midimap: Handle MIDI running status.
[wine.git] / programs / ipconfig / ipconfig.c
blobb787947885d92e04e337f5d38ccac4fe8365f108
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 #define NONAMELESSUNION
24 #include <stdio.h>
25 #include <winsock2.h>
26 #include <windows.h>
27 #include <iphlpapi.h>
29 #include "ipconfig.h"
31 static int ipconfig_vprintfW(const WCHAR *msg, va_list va_args)
33 int wlen;
34 DWORD count;
35 WCHAR msg_buffer[8192];
37 wlen = FormatMessageW(FORMAT_MESSAGE_FROM_STRING, msg, 0, 0, msg_buffer,
38 ARRAY_SIZE(msg_buffer), &va_args);
40 if (!WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), msg_buffer, wlen, &count, NULL))
42 DWORD len;
43 char *msgA;
45 /* On Windows WriteConsoleW() fails if the output is redirected. So fall
46 * back to WriteFile() with OEM code page.
48 len = WideCharToMultiByte(GetOEMCP(), 0, msg_buffer, wlen,
49 NULL, 0, NULL, NULL);
50 msgA = HeapAlloc(GetProcessHeap(), 0, len);
51 if (!msgA)
52 return 0;
54 WideCharToMultiByte(GetOEMCP(), 0, msg_buffer, wlen, msgA, len, NULL, NULL);
55 WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), msgA, len, &count, FALSE);
56 HeapFree(GetProcessHeap(), 0, msgA);
59 return count;
62 static int WINAPIV 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 WINAPIV 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, ARRAY_SIZE(msg_buffer));
82 va_start(va_args, msg);
83 len = ipconfig_vprintfW(msg_buffer, va_args);
84 va_end(va_args);
86 return len;
89 static int ipconfig_message(int msg)
91 WCHAR msg_buffer[8192];
93 LoadStringW(GetModuleHandleW(NULL), msg, msg_buffer, ARRAY_SIZE(msg_buffer));
95 return ipconfig_printfW(L"%1", msg_buffer);
98 static const WCHAR *iftype_to_string(DWORD type)
100 static WCHAR msg_buffer[50];
102 int msg;
104 switch (type)
106 case IF_TYPE_ETHERNET_CSMACD:
107 /* The loopback adapter appears as an Ethernet device. */
108 case IF_TYPE_SOFTWARE_LOOPBACK:
109 msg = STRING_ETHERNET;
110 break;
111 default:
112 msg = STRING_UNKNOWN;
115 LoadStringW(GetModuleHandleW(NULL), msg, msg_buffer, ARRAY_SIZE(msg_buffer));
117 return msg_buffer;
120 static void print_field(int msg, const WCHAR *value)
122 WCHAR field[] = L". . . . . . . . . . . . . . . . . ";
123 WCHAR name_buffer[ARRAY_SIZE(field)];
125 LoadStringW(GetModuleHandleW(NULL), msg, name_buffer, ARRAY_SIZE(name_buffer));
126 memcpy(field, name_buffer, sizeof(WCHAR) * min(lstrlenW(name_buffer), ARRAY_SIZE(field) - 1));
128 ipconfig_printfW(L" %1: %2\n", field, value);
131 static void print_value(const WCHAR *value)
133 ipconfig_printfW(L" %1\n", value);
136 static BOOL socket_address_to_string(WCHAR *buf, DWORD len, SOCKET_ADDRESS *addr)
138 return WSAAddressToStringW(addr->lpSockaddr,
139 addr->iSockaddrLength, NULL,
140 buf, &len) == 0;
143 static void print_basic_information(void)
145 IP_ADAPTER_ADDRESSES *adapters;
146 ULONG out = 0;
148 if (GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_ALL_GATEWAYS,
149 NULL, NULL, &out) == ERROR_BUFFER_OVERFLOW)
151 adapters = HeapAlloc(GetProcessHeap(), 0, out);
152 if (!adapters)
153 exit(1);
155 if (GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_ALL_GATEWAYS,
156 NULL, adapters, &out) == ERROR_SUCCESS)
158 IP_ADAPTER_ADDRESSES *p;
160 for (p = adapters; p; p = p->Next)
162 IP_ADAPTER_UNICAST_ADDRESS *addr;
163 IP_ADAPTER_GATEWAY_ADDRESS_LH *gateway;
164 WCHAR addr_buf[54];
166 ipconfig_message_printfW(STRING_ADAPTER_FRIENDLY, iftype_to_string(p->IfType), p->FriendlyName);
167 ipconfig_printfW(L"\n");
168 print_field(STRING_CONN_DNS_SUFFIX, p->DnsSuffix);
170 for (addr = p->FirstUnicastAddress; addr; addr = addr->Next)
172 if (addr->Address.lpSockaddr->sa_family == AF_INET &&
173 socket_address_to_string(addr_buf, ARRAY_SIZE(addr_buf), &addr->Address))
174 print_field(STRING_IP_ADDRESS, addr_buf);
175 else if (addr->Address.lpSockaddr->sa_family == AF_INET6 &&
176 socket_address_to_string(addr_buf, ARRAY_SIZE(addr_buf), &addr->Address))
177 print_field(STRING_IP6_ADDRESS, addr_buf);
178 /* FIXME: Output corresponding subnet mask. */
181 if (p->FirstGatewayAddress)
183 if (socket_address_to_string(addr_buf, ARRAY_SIZE(addr_buf), &p->FirstGatewayAddress->Address))
184 print_field(STRING_DEFAULT_GATEWAY, addr_buf);
186 for (gateway = p->FirstGatewayAddress->Next; gateway; gateway = gateway->Next)
188 if (socket_address_to_string(addr_buf, ARRAY_SIZE(addr_buf), &gateway->Address))
189 print_value(addr_buf);
192 else
193 print_field(STRING_DEFAULT_GATEWAY, L"");
195 ipconfig_printfW(L"\n");
199 HeapFree(GetProcessHeap(), 0, adapters);
203 static const WCHAR *nodetype_to_string(DWORD type)
205 static WCHAR msg_buffer[50];
207 int msg;
209 switch (type)
211 case BROADCAST_NODETYPE:
212 msg = STRING_BROADCAST;
213 break;
214 case PEER_TO_PEER_NODETYPE:
215 msg = STRING_PEER_TO_PEER;
216 break;
217 case MIXED_NODETYPE:
218 msg = STRING_MIXED;
219 break;
220 case HYBRID_NODETYPE:
221 msg = STRING_HYBRID;
222 break;
223 default:
224 msg = STRING_UNKNOWN;
227 LoadStringW(GetModuleHandleW(NULL), msg, msg_buffer, ARRAY_SIZE(msg_buffer));
229 return msg_buffer;
232 static WCHAR *physaddr_to_string(WCHAR *buf, BYTE *addr, DWORD len)
234 if (!len)
235 *buf = '\0';
236 else
238 WCHAR *p = buf;
239 DWORD i;
241 for (i = 0; i < len - 1; i++)
243 swprintf(p, 4, L"%02X-", addr[i]);
244 p += 3;
246 swprintf(p, 3, L"%02X", addr[i]);
249 return buf;
252 static const WCHAR *boolean_to_string(int value)
254 static WCHAR msg_buffer[15];
256 LoadStringW(GetModuleHandleW(NULL), value ? STRING_YES : STRING_NO,
257 msg_buffer, ARRAY_SIZE(msg_buffer));
259 return msg_buffer;
262 static void print_full_information(void)
264 FIXED_INFO *info;
265 IP_ADAPTER_ADDRESSES *adapters;
266 ULONG out = 0;
268 if (GetNetworkParams(NULL, &out) == ERROR_BUFFER_OVERFLOW)
270 info = HeapAlloc(GetProcessHeap(), 0, out);
271 if (!info)
272 exit(1);
274 if (GetNetworkParams(info, &out) == ERROR_SUCCESS)
276 WCHAR hostnameW[MAX_HOSTNAME_LEN + 4];
277 WCHAR dnssuffixW[MAX_DOMAIN_NAME_LEN + 4];
279 MultiByteToWideChar(CP_ACP, 0, info->HostName, -1, hostnameW, ARRAY_SIZE(hostnameW));
280 print_field(STRING_HOSTNAME, hostnameW);
282 MultiByteToWideChar(CP_ACP, 0, info->DomainName, -1, dnssuffixW, ARRAY_SIZE(dnssuffixW));
283 print_field(STRING_PRIMARY_DNS_SUFFIX, dnssuffixW);
285 print_field(STRING_NODE_TYPE, nodetype_to_string(info->NodeType));
286 print_field(STRING_IP_ROUTING, boolean_to_string(info->EnableRouting));
288 /* FIXME: Output WINS proxy status and DNS suffix search list. */
290 ipconfig_printfW(L"\n");
293 HeapFree(GetProcessHeap(), 0, info);
296 if (GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_ALL_GATEWAYS,
297 NULL, NULL, &out) == ERROR_BUFFER_OVERFLOW)
299 adapters = HeapAlloc(GetProcessHeap(), 0, out);
300 if (!adapters)
301 exit(1);
303 if (GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_ALL_GATEWAYS,
304 NULL, adapters, &out) == ERROR_SUCCESS)
306 IP_ADAPTER_ADDRESSES *p;
308 for (p = adapters; p; p = p->Next)
310 IP_ADAPTER_UNICAST_ADDRESS *addr;
311 WCHAR physaddr_buf[3 * MAX_ADAPTER_ADDRESS_LENGTH];
312 IP_ADAPTER_GATEWAY_ADDRESS_LH *gateway;
313 WCHAR addr_buf[54];
315 ipconfig_message_printfW(STRING_ADAPTER_FRIENDLY, iftype_to_string(p->IfType), p->FriendlyName);
316 ipconfig_printfW(L"\n");
317 print_field(STRING_CONN_DNS_SUFFIX, p->DnsSuffix);
318 print_field(STRING_DESCRIPTION, p->Description);
319 print_field(STRING_PHYS_ADDR, physaddr_to_string(physaddr_buf, p->PhysicalAddress, p->PhysicalAddressLength));
320 print_field(STRING_DHCP_ENABLED, boolean_to_string(p->u1.Flags & IP_ADAPTER_DHCP_ENABLED));
322 /* FIXME: Output autoconfiguration status. */
324 for (addr = p->FirstUnicastAddress; addr; addr = addr->Next)
326 if (addr->Address.lpSockaddr->sa_family == AF_INET &&
327 socket_address_to_string(addr_buf, ARRAY_SIZE(addr_buf), &addr->Address))
328 print_field(STRING_IP_ADDRESS, addr_buf);
329 else if (addr->Address.lpSockaddr->sa_family == AF_INET6 &&
330 socket_address_to_string(addr_buf, ARRAY_SIZE(addr_buf), &addr->Address))
331 print_field(STRING_IP6_ADDRESS, addr_buf);
332 /* FIXME: Output corresponding subnet mask. */
335 if (p->FirstGatewayAddress)
337 if (socket_address_to_string(addr_buf, ARRAY_SIZE(addr_buf), &p->FirstGatewayAddress->Address))
338 print_field(STRING_DEFAULT_GATEWAY, addr_buf);
340 for (gateway = p->FirstGatewayAddress->Next; gateway; gateway = gateway->Next)
342 if (socket_address_to_string(addr_buf, ARRAY_SIZE(addr_buf), &gateway->Address))
343 print_value(addr_buf);
346 else
347 print_field(STRING_DEFAULT_GATEWAY, L"");
349 ipconfig_printfW(L"\n");
353 HeapFree(GetProcessHeap(), 0, adapters);
357 int __cdecl wmain(int argc, WCHAR *argv[])
359 WSADATA data;
361 if (WSAStartup(MAKEWORD(2, 2), &data))
362 return 1;
364 if (argc > 1)
366 if (!lstrcmpW(L"/?", argv[1]))
368 ipconfig_message(STRING_USAGE);
369 WSACleanup();
370 return 1;
372 else if (!wcsicmp(L"/all", argv[1]))
374 if (argv[2])
376 ipconfig_message(STRING_INVALID_CMDLINE);
377 ipconfig_message(STRING_USAGE);
378 WSACleanup();
379 return 1;
382 print_full_information();
384 else
386 ipconfig_message(STRING_INVALID_CMDLINE);
387 ipconfig_message(STRING_USAGE);
388 WSACleanup();
389 return 1;
392 else
393 print_basic_information();
395 WSACleanup();
396 return 0;