dsound: Don't specify period size for the IAudioClient.
[wine/multimedia.git] / programs / ipconfig / ipconfig.c
blob37e709931e7507a35ea9316bef22af877eb459a9
1 /*
2 * IP configuration utility
4 * Copyright 2008 Andrew Riedi
5 * Copyright 2010 Andrew Nguyen
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include <winsock2.h>
23 #include <windows.h>
24 #include <iphlpapi.h>
25 #include <wine/unicode.h>
27 #include "ipconfig.h"
29 static int ipconfig_vprintfW(const WCHAR *msg, va_list va_args)
31 int wlen;
32 DWORD count, ret;
33 WCHAR msg_buffer[8192];
35 wlen = vsprintfW(msg_buffer, msg, va_args);
37 ret = WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), msg_buffer, wlen, &count, NULL);
38 if (!ret)
40 DWORD len;
41 char *msgA;
43 /* On Windows WriteConsoleW() fails if the output is redirected. So fall
44 * back to WriteFile(), assuming the console encoding is still the right
45 * one in that case.
47 len = WideCharToMultiByte(GetConsoleOutputCP(), 0, msg_buffer, wlen,
48 NULL, 0, NULL, NULL);
49 msgA = HeapAlloc(GetProcessHeap(), 0, len);
50 if (!msgA)
51 return 0;
53 WideCharToMultiByte(GetConsoleOutputCP(), 0, msg_buffer, wlen, msgA, len,
54 NULL, NULL);
55 WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), msgA, len, &count, FALSE);
56 HeapFree(GetProcessHeap(), 0, msgA);
59 return count;
62 static int ipconfig_printfW(const WCHAR *msg, ...)
64 va_list va_args;
65 int len;
67 va_start(va_args, msg);
68 len = ipconfig_vprintfW(msg, va_args);
69 va_end(va_args);
71 return len;
74 static int ipconfig_message_printfW(int msg, ...)
76 va_list va_args;
77 WCHAR msg_buffer[8192];
78 int len;
80 LoadStringW(GetModuleHandleW(NULL), msg, msg_buffer,
81 sizeof(msg_buffer)/sizeof(WCHAR));
83 va_start(va_args, msg);
84 len = ipconfig_vprintfW(msg_buffer, va_args);
85 va_end(va_args);
87 return len;
90 static int ipconfig_message(int msg)
92 static const WCHAR formatW[] = {'%','s',0};
93 WCHAR msg_buffer[8192];
95 LoadStringW(GetModuleHandleW(NULL), msg, msg_buffer,
96 sizeof(msg_buffer)/sizeof(WCHAR));
98 return ipconfig_printfW(formatW, msg_buffer);
101 static const WCHAR *iftype_to_string(DWORD type)
103 static WCHAR msg_buffer[50];
105 int msg;
107 switch (type)
109 case IF_TYPE_ETHERNET_CSMACD:
110 /* The loopback adapter appears as an Ethernet device. */
111 case IF_TYPE_SOFTWARE_LOOPBACK:
112 msg = STRING_ETHERNET;
113 break;
114 default:
115 msg = STRING_UNKNOWN;
118 LoadStringW(GetModuleHandleW(NULL), msg, msg_buffer,
119 sizeof(msg_buffer)/sizeof(WCHAR));
121 return msg_buffer;
124 static void print_field(int msg, const WCHAR *value)
126 static const WCHAR formatW[] = {' ',' ',' ',' ','%','s',':',' ','%','s','\n',0};
128 WCHAR field[] = {'.',' ','.',' ','.',' ','.',' ','.',' ','.',' ','.',' ','.',' ','.',
129 ' ','.',' ','.',' ','.',' ','.',' ','.',' ','.',' ','.',' ','.',' ',0};
130 WCHAR name_buffer[sizeof(field)/sizeof(WCHAR)];
132 LoadStringW(GetModuleHandleW(NULL), msg, name_buffer, sizeof(name_buffer)/sizeof(WCHAR));
133 memcpy(field, name_buffer, sizeof(WCHAR) * min(strlenW(name_buffer), sizeof(field)/sizeof(WCHAR) - 1));
135 ipconfig_printfW(formatW, field, value);
138 static void print_value(const WCHAR *value)
140 static const WCHAR formatW[] = {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',
141 ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',
142 ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',
143 ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',
144 '%','s','\n',0};
146 ipconfig_printfW(formatW, value);
149 static BOOL socket_address_to_string(WCHAR *buf, DWORD len, SOCKET_ADDRESS *addr)
151 return WSAAddressToStringW(addr->lpSockaddr,
152 addr->iSockaddrLength, NULL,
153 buf, &len) == 0;
156 static void print_basic_information(void)
158 IP_ADAPTER_ADDRESSES *adapters;
159 ULONG out = 0;
161 if (GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_ALL_GATEWAYS,
162 NULL, NULL, &out) == ERROR_BUFFER_OVERFLOW)
164 adapters = HeapAlloc(GetProcessHeap(), 0, out);
165 if (!adapters)
166 exit(1);
168 if (GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_ALL_GATEWAYS,
169 NULL, adapters, &out) == ERROR_SUCCESS)
171 IP_ADAPTER_ADDRESSES *p;
173 for (p = adapters; p; p = p->Next)
175 static const WCHAR newlineW[] = {'\n',0};
176 static const WCHAR emptyW[] = {0};
178 IP_ADAPTER_UNICAST_ADDRESS *addr;
179 IP_ADAPTER_GATEWAY_ADDRESS_LH *gateway;
180 WCHAR addr_buf[54];
182 ipconfig_message_printfW(STRING_ADAPTER_FRIENDLY, iftype_to_string(p->IfType), p->FriendlyName);
183 ipconfig_printfW(newlineW);
184 print_field(STRING_CONN_DNS_SUFFIX, p->DnsSuffix);
186 for (addr = p->FirstUnicastAddress; addr; addr = addr->Next)
188 if (socket_address_to_string(addr_buf, sizeof(addr_buf)/sizeof(WCHAR), &addr->Address))
189 print_field(STRING_IP_ADDRESS, addr_buf);
190 /* FIXME: Output corresponding subnet mask. */
193 if (p->FirstGatewayAddress)
195 if (socket_address_to_string(addr_buf, sizeof(addr_buf)/sizeof(WCHAR), &p->FirstGatewayAddress->Address))
196 print_field(STRING_DEFAULT_GATEWAY, addr_buf);
198 for (gateway = p->FirstGatewayAddress->Next; gateway; gateway = gateway->Next)
200 if (socket_address_to_string(addr_buf, sizeof(addr_buf)/sizeof(WCHAR), &gateway->Address))
201 print_value(addr_buf);
204 else
205 print_field(STRING_DEFAULT_GATEWAY, emptyW);
207 ipconfig_printfW(newlineW);
211 HeapFree(GetProcessHeap(), 0, adapters);
215 static const WCHAR *nodetype_to_string(DWORD type)
217 static WCHAR msg_buffer[50];
219 int msg;
221 switch (type)
223 case BROADCAST_NODETYPE:
224 msg = STRING_BROADCAST;
225 break;
226 case PEER_TO_PEER_NODETYPE:
227 msg = STRING_PEER_TO_PEER;
228 break;
229 case MIXED_NODETYPE:
230 msg = STRING_MIXED;
231 break;
232 case HYBRID_NODETYPE:
233 msg = STRING_HYBRID;
234 break;
235 default:
236 msg = STRING_UNKNOWN;
239 LoadStringW(GetModuleHandleW(NULL), msg, msg_buffer,
240 sizeof(msg_buffer)/sizeof(WCHAR));
242 return msg_buffer;
245 static WCHAR *physaddr_to_string(WCHAR *buf, BYTE *addr, DWORD len)
247 static const WCHAR fmtW[] = {'%','0','2','X','-',0};
248 static const WCHAR fmt2W[] = {'%','0','2','X',0};
250 if (!len)
251 *buf = '\0';
252 else
254 WCHAR *p = buf;
255 DWORD i;
257 for (i = 0; i < len - 1; i++)
259 sprintfW(p, fmtW, addr[i]);
260 p += 3;
262 sprintfW(p, fmt2W, addr[i]);
265 return buf;
268 static const WCHAR *boolean_to_string(int value)
270 static WCHAR msg_buffer[15];
272 LoadStringW(GetModuleHandleW(NULL), value ? STRING_YES : STRING_NO,
273 msg_buffer, sizeof(msg_buffer)/sizeof(WCHAR));
275 return msg_buffer;
278 static void print_full_information(void)
280 static const WCHAR newlineW[] = {'\n',0};
281 static const WCHAR emptyW[] = {0};
283 FIXED_INFO *info;
284 IP_ADAPTER_ADDRESSES *adapters;
285 ULONG out = 0;
287 if (GetNetworkParams(NULL, &out) == ERROR_BUFFER_OVERFLOW)
289 info = HeapAlloc(GetProcessHeap(), 0, out);
290 if (!info)
291 exit(1);
293 if (GetNetworkParams(info, &out) == ERROR_SUCCESS)
295 WCHAR hostnameW[MAX_HOSTNAME_LEN + 4];
297 MultiByteToWideChar(CP_ACP, 0, info->HostName, -1, hostnameW, sizeof(hostnameW)/sizeof(hostnameW[0]));
298 print_field(STRING_HOSTNAME, hostnameW);
300 /* FIXME: Output primary DNS suffix. */
302 print_field(STRING_NODE_TYPE, nodetype_to_string(info->NodeType));
303 print_field(STRING_IP_ROUTING, boolean_to_string(info->EnableRouting));
305 /* FIXME: Output WINS proxy status and DNS suffix search list. */
307 ipconfig_printfW(newlineW);
310 HeapFree(GetProcessHeap(), 0, info);
313 if (GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_ALL_GATEWAYS,
314 NULL, NULL, &out) == ERROR_BUFFER_OVERFLOW)
316 adapters = HeapAlloc(GetProcessHeap(), 0, out);
317 if (!adapters)
318 exit(1);
320 if (GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_ALL_GATEWAYS,
321 NULL, adapters, &out) == ERROR_SUCCESS)
323 IP_ADAPTER_ADDRESSES *p;
325 for (p = adapters; p; p = p->Next)
327 IP_ADAPTER_UNICAST_ADDRESS *addr;
328 WCHAR physaddr_buf[3 * MAX_ADAPTER_ADDRESS_LENGTH];
329 IP_ADAPTER_GATEWAY_ADDRESS_LH *gateway;
330 WCHAR addr_buf[54];
332 ipconfig_message_printfW(STRING_ADAPTER_FRIENDLY, iftype_to_string(p->IfType), p->FriendlyName);
333 ipconfig_printfW(newlineW);
334 print_field(STRING_CONN_DNS_SUFFIX, p->DnsSuffix);
335 print_field(STRING_DESCRIPTION, p->Description);
336 print_field(STRING_PHYS_ADDR, physaddr_to_string(physaddr_buf, p->PhysicalAddress, p->PhysicalAddressLength));
337 print_field(STRING_DHCP_ENABLED, boolean_to_string(p->Flags & IP_ADAPTER_DHCP_ENABLED));
339 /* FIXME: Output autoconfiguration status. */
341 for (addr = p->FirstUnicastAddress; addr; addr = addr->Next)
343 if (socket_address_to_string(addr_buf, sizeof(addr_buf)/sizeof(WCHAR), &addr->Address))
344 print_field(STRING_IP_ADDRESS, addr_buf);
345 /* FIXME: Output corresponding subnet mask. */
348 if (p->FirstGatewayAddress)
350 if (socket_address_to_string(addr_buf, sizeof(addr_buf)/sizeof(WCHAR), &p->FirstGatewayAddress->Address))
351 print_field(STRING_DEFAULT_GATEWAY, addr_buf);
353 for (gateway = p->FirstGatewayAddress->Next; gateway; gateway = gateway->Next)
355 if (socket_address_to_string(addr_buf, sizeof(addr_buf)/sizeof(WCHAR), &gateway->Address))
356 print_value(addr_buf);
359 else
360 print_field(STRING_DEFAULT_GATEWAY, emptyW);
362 ipconfig_printfW(newlineW);
366 HeapFree(GetProcessHeap(), 0, adapters);
370 int wmain(int argc, WCHAR *argv[])
372 static const WCHAR slashHelp[] = {'/','?',0};
373 static const WCHAR slashAll[] = {'/','a','l','l',0};
375 WSADATA data;
377 if (WSAStartup(MAKEWORD(2, 2), &data))
378 return 1;
380 if (argc > 1)
382 if (!strcmpW(slashHelp, argv[1]))
384 ipconfig_message(STRING_USAGE);
385 WSACleanup();
386 return 1;
388 else if (!strcmpiW(slashAll, argv[1]))
390 if (argv[2])
392 ipconfig_message(STRING_INVALID_CMDLINE);
393 ipconfig_message(STRING_USAGE);
394 WSACleanup();
395 return 1;
398 print_full_information();
400 else
402 ipconfig_message(STRING_INVALID_CMDLINE);
403 ipconfig_message(STRING_USAGE);
404 WSACleanup();
405 return 1;
408 else
409 print_basic_information();
411 WSACleanup();
412 return 0;