ieframe: Moved dialog resources to ieframe.
[wine/testsucceed.git] / programs / ipconfig / ipconfig.c
blob14974ae836952e6c3eddc3a2e950ebddc4046eef
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 len = WideCharToMultiByte(GetConsoleOutputCP(), 0, msg_buffer, wlen,
44 NULL, 0, NULL, NULL);
45 msgA = HeapAlloc(GetProcessHeap(), 0, len);
46 if (!msgA)
47 return 0;
49 WideCharToMultiByte(GetConsoleOutputCP(), 0, msg_buffer, wlen, msgA, len,
50 NULL, NULL);
51 WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), msgA, len, &count, FALSE);
52 HeapFree(GetProcessHeap(), 0, msgA);
55 return count;
58 static int ipconfig_printfW(const WCHAR *msg, ...)
60 va_list va_args;
61 int len;
63 va_start(va_args, msg);
64 len = ipconfig_vprintfW(msg, va_args);
65 va_end(va_args);
67 return len;
70 static int ipconfig_message_printfW(int msg, ...)
72 va_list va_args;
73 WCHAR msg_buffer[8192];
74 int len;
76 LoadStringW(GetModuleHandleW(NULL), msg, msg_buffer,
77 sizeof(msg_buffer)/sizeof(WCHAR));
79 va_start(va_args, msg);
80 len = ipconfig_vprintfW(msg_buffer, va_args);
81 va_end(va_args);
83 return len;
86 static int ipconfig_message(int msg)
88 static const WCHAR formatW[] = {'%','s',0};
89 WCHAR msg_buffer[8192];
91 LoadStringW(GetModuleHandleW(NULL), msg, msg_buffer,
92 sizeof(msg_buffer)/sizeof(WCHAR));
94 return ipconfig_printfW(formatW, msg_buffer);
97 static const WCHAR *iftype_to_string(DWORD type)
99 static WCHAR msg_buffer[50];
101 int msg;
103 switch (type)
105 case IF_TYPE_ETHERNET_CSMACD:
106 /* The loopback adapter appears as an Ethernet device. */
107 case IF_TYPE_SOFTWARE_LOOPBACK:
108 msg = STRING_ETHERNET;
109 break;
110 default:
111 msg = STRING_UNKNOWN;
114 LoadStringW(GetModuleHandleW(NULL), msg, msg_buffer,
115 sizeof(msg_buffer)/sizeof(WCHAR));
117 return msg_buffer;
120 static void print_field(int msg, const WCHAR *value)
122 static const WCHAR formatW[] = {' ',' ',' ',' ','%','s',':',' ','%','s','\n',0};
124 WCHAR field[] = {'.',' ','.',' ','.',' ','.',' ','.',' ','.',' ','.',' ','.',' ','.',
125 ' ','.',' ','.',' ','.',' ','.',' ','.',' ','.',' ','.',' ','.',' ',0};
126 WCHAR name_buffer[sizeof(field)/sizeof(WCHAR)];
128 LoadStringW(GetModuleHandleW(NULL), msg, name_buffer, sizeof(name_buffer)/sizeof(WCHAR));
129 memcpy(field, name_buffer, sizeof(WCHAR) * min(strlenW(name_buffer), sizeof(field)/sizeof(WCHAR) - 1));
131 ipconfig_printfW(formatW, field, value);
134 static void print_value(const WCHAR *value)
136 static const WCHAR formatW[] = {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',
137 ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',
138 ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',
139 ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',
140 '%','s','\n',0};
142 ipconfig_printfW(formatW, value);
145 static BOOL socket_address_to_string(WCHAR *buf, DWORD len, SOCKET_ADDRESS *addr)
147 return WSAAddressToStringW(addr->lpSockaddr,
148 addr->iSockaddrLength, NULL,
149 buf, &len) == 0;
152 static void print_basic_information(void)
154 IP_ADAPTER_ADDRESSES *adapters;
155 ULONG out = 0;
157 if (GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_ALL_GATEWAYS,
158 NULL, NULL, &out) == ERROR_BUFFER_OVERFLOW)
160 adapters = HeapAlloc(GetProcessHeap(), 0, out);
161 if (!adapters)
162 exit(1);
164 if (GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_ALL_GATEWAYS,
165 NULL, adapters, &out) == ERROR_SUCCESS)
167 IP_ADAPTER_ADDRESSES *p;
169 for (p = adapters; p; p = p->Next)
171 static const WCHAR newlineW[] = {'\n',0};
172 static const WCHAR emptyW[] = {0};
174 IP_ADAPTER_UNICAST_ADDRESS *addr;
175 IP_ADAPTER_GATEWAY_ADDRESS_LH *gateway;
176 WCHAR addr_buf[54];
178 ipconfig_message_printfW(STRING_ADAPTER_FRIENDLY, iftype_to_string(p->IfType), p->FriendlyName);
179 ipconfig_printfW(newlineW);
180 print_field(STRING_CONN_DNS_SUFFIX, p->DnsSuffix);
182 for (addr = p->FirstUnicastAddress; addr; addr = addr->Next)
184 if (socket_address_to_string(addr_buf, sizeof(addr_buf)/sizeof(WCHAR), &addr->Address))
185 print_field(STRING_IP_ADDRESS, addr_buf);
186 /* FIXME: Output corresponding subnet mask. */
189 if (p->FirstGatewayAddress)
191 if (socket_address_to_string(addr_buf, sizeof(addr_buf)/sizeof(WCHAR), &p->FirstGatewayAddress->Address))
192 print_field(STRING_DEFAULT_GATEWAY, addr_buf);
194 for (gateway = p->FirstGatewayAddress->Next; gateway; gateway = gateway->Next)
196 if (socket_address_to_string(addr_buf, sizeof(addr_buf)/sizeof(WCHAR), &gateway->Address))
197 print_value(addr_buf);
200 else
201 print_field(STRING_DEFAULT_GATEWAY, emptyW);
203 ipconfig_printfW(newlineW);
207 HeapFree(GetProcessHeap(), 0, adapters);
211 static const WCHAR *nodetype_to_string(DWORD type)
213 static WCHAR msg_buffer[50];
215 int msg;
217 switch (type)
219 case BROADCAST_NODETYPE:
220 msg = STRING_BROADCAST;
221 break;
222 case PEER_TO_PEER_NODETYPE:
223 msg = STRING_PEER_TO_PEER;
224 break;
225 case MIXED_NODETYPE:
226 msg = STRING_MIXED;
227 break;
228 case HYBRID_NODETYPE:
229 msg = STRING_HYBRID;
230 break;
231 default:
232 msg = STRING_UNKNOWN;
235 LoadStringW(GetModuleHandleW(NULL), msg, msg_buffer,
236 sizeof(msg_buffer)/sizeof(WCHAR));
238 return msg_buffer;
241 static WCHAR *physaddr_to_string(WCHAR *buf, BYTE *addr, DWORD len)
243 static const WCHAR fmtW[] = {'%','0','2','X','-',0};
244 static const WCHAR fmt2W[] = {'%','0','2','X',0};
246 if (!len)
247 *buf = '\0';
248 else
250 WCHAR *p = buf;
251 DWORD i;
253 for (i = 0; i < len - 1; i++)
255 sprintfW(p, fmtW, addr[i]);
256 p += 3;
258 sprintfW(p, fmt2W, addr[i]);
261 return buf;
264 static const WCHAR *boolean_to_string(int value)
266 static WCHAR msg_buffer[15];
268 LoadStringW(GetModuleHandleW(NULL), value ? STRING_YES : STRING_NO,
269 msg_buffer, sizeof(msg_buffer)/sizeof(WCHAR));
271 return msg_buffer;
274 static void print_full_information(void)
276 static const WCHAR newlineW[] = {'\n',0};
277 static const WCHAR emptyW[] = {0};
279 FIXED_INFO *info;
280 IP_ADAPTER_ADDRESSES *adapters;
281 ULONG out = 0;
283 if (GetNetworkParams(NULL, &out) == ERROR_BUFFER_OVERFLOW)
285 info = HeapAlloc(GetProcessHeap(), 0, out);
286 if (!info)
287 exit(1);
289 if (GetNetworkParams(info, &out) == ERROR_SUCCESS)
291 WCHAR hostnameW[MAX_HOSTNAME_LEN + 4];
293 MultiByteToWideChar(CP_ACP, 0, info->HostName, -1, hostnameW, sizeof(hostnameW)/sizeof(hostnameW[0]));
294 print_field(STRING_HOSTNAME, hostnameW);
296 /* FIXME: Output primary DNS suffix. */
298 print_field(STRING_NODE_TYPE, nodetype_to_string(info->NodeType));
299 print_field(STRING_IP_ROUTING, boolean_to_string(info->EnableRouting));
301 /* FIXME: Output WINS proxy status and DNS suffix search list. */
303 ipconfig_printfW(newlineW);
306 HeapFree(GetProcessHeap(), 0, info);
309 if (GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_ALL_GATEWAYS,
310 NULL, NULL, &out) == ERROR_BUFFER_OVERFLOW)
312 adapters = HeapAlloc(GetProcessHeap(), 0, out);
313 if (!adapters)
314 exit(1);
316 if (GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_ALL_GATEWAYS,
317 NULL, adapters, &out) == ERROR_SUCCESS)
319 IP_ADAPTER_ADDRESSES *p;
321 for (p = adapters; p; p = p->Next)
323 IP_ADAPTER_UNICAST_ADDRESS *addr;
324 WCHAR physaddr_buf[3 * MAX_ADAPTER_ADDRESS_LENGTH];
325 IP_ADAPTER_GATEWAY_ADDRESS_LH *gateway;
326 WCHAR addr_buf[54];
328 ipconfig_message_printfW(STRING_ADAPTER_FRIENDLY, iftype_to_string(p->IfType), p->FriendlyName);
329 ipconfig_printfW(newlineW);
330 print_field(STRING_CONN_DNS_SUFFIX, p->DnsSuffix);
331 print_field(STRING_DESCRIPTION, p->Description);
332 print_field(STRING_PHYS_ADDR, physaddr_to_string(physaddr_buf, p->PhysicalAddress, p->PhysicalAddressLength));
333 print_field(STRING_DHCP_ENABLED, boolean_to_string(p->Flags & IP_ADAPTER_DHCP_ENABLED));
335 /* FIXME: Output autoconfiguration status. */
337 for (addr = p->FirstUnicastAddress; addr; addr = addr->Next)
339 if (socket_address_to_string(addr_buf, sizeof(addr_buf)/sizeof(WCHAR), &addr->Address))
340 print_field(STRING_IP_ADDRESS, addr_buf);
341 /* FIXME: Output corresponding subnet mask. */
344 if (p->FirstGatewayAddress)
346 if (socket_address_to_string(addr_buf, sizeof(addr_buf)/sizeof(WCHAR), &p->FirstGatewayAddress->Address))
347 print_field(STRING_DEFAULT_GATEWAY, addr_buf);
349 for (gateway = p->FirstGatewayAddress->Next; gateway; gateway = gateway->Next)
351 if (socket_address_to_string(addr_buf, sizeof(addr_buf)/sizeof(WCHAR), &gateway->Address))
352 print_value(addr_buf);
355 else
356 print_field(STRING_DEFAULT_GATEWAY, emptyW);
358 ipconfig_printfW(newlineW);
362 HeapFree(GetProcessHeap(), 0, adapters);
366 int wmain(int argc, WCHAR *argv[])
368 static const WCHAR slashHelp[] = {'/','?',0};
369 static const WCHAR slashAll[] = {'/','a','l','l',0};
371 WSADATA data;
373 if (WSAStartup(MAKEWORD(2, 2), &data))
374 return 1;
376 if (argc > 1)
378 if (!strcmpW(slashHelp, argv[1]))
380 ipconfig_message(STRING_USAGE);
381 WSACleanup();
382 return 1;
384 else if (!strcmpiW(slashAll, argv[1]))
386 if (argv[2])
388 ipconfig_message(STRING_INVALID_CMDLINE);
389 ipconfig_message(STRING_USAGE);
390 WSACleanup();
391 return 1;
394 print_full_information();
396 else
398 ipconfig_message(STRING_INVALID_CMDLINE);
399 ipconfig_message(STRING_USAGE);
400 WSACleanup();
401 return 1;
404 else
405 print_basic_information();
407 WSACleanup();
408 return 0;