[IPCONFIG] Indentation and coding style fixes. No code changes!
[reactos.git] / base / applications / network / ipconfig / ipconfig.c
1 /*
2 * PROJECT: ReactOS ipconfig utility
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: base/applications/network/ipconfig/ipconfig.c
5 * PURPOSE: Display IP info for net adapters
6 * PROGRAMMERS: Copyright 2005 - 2006 Ged Murphy (gedmurphy@gmail.com)
7 */
8 /*
9 * TODO:
10 * fix renew / release
11 * implement flushdns, registerdns, displaydns, showclassid, setclassid
12 * allow globbing on adapter names
13 */
14
15 #include <stdarg.h>
16 #include <windef.h>
17 #include <winbase.h>
18 #include <winuser.h>
19 #include <winreg.h>
20 #include <stdio.h>
21 #include <tchar.h>
22 #include <time.h>
23 #include <iphlpapi.h>
24
25 #include "resource.h"
26
27 #define GUID_LEN 40
28
29 HINSTANCE hInstance;
30 HANDLE ProcessHeap;
31
32 int LoadStringAndOem(HINSTANCE hInst,
33 UINT uID,
34 LPTSTR szNode,
35 int byteSize)
36 {
37 TCHAR *szTmp;
38 int res;
39
40 szTmp = (LPTSTR)HeapAlloc(ProcessHeap, 0, byteSize);
41 if (szTmp == NULL)
42 {
43 return 0;
44 }
45
46 res = LoadString(hInst, uID, szTmp, byteSize);
47 CharToOem(szTmp, szNode);
48 HeapFree(ProcessHeap, 0, szTmp);
49 return res;
50 }
51
52 LPTSTR GetNodeTypeName(UINT NodeType)
53 {
54 static TCHAR szNode[14];
55
56 switch (NodeType)
57 {
58 case 1:
59 if (!LoadStringAndOem(hInstance, IDS_BCAST, szNode, sizeof(szNode)))
60 return NULL;
61 break;
62
63 case 2:
64 if (!LoadStringAndOem(hInstance, IDS_P2P, szNode, sizeof(szNode)))
65 return NULL;
66 break;
67
68 case 4:
69 if (!LoadStringAndOem(hInstance, IDS_MIXED, szNode, sizeof(szNode)))
70 return NULL;
71 break;
72
73 case 8:
74 if (!LoadStringAndOem(hInstance, IDS_HYBRID, szNode, sizeof(szNode)))
75 return NULL;
76 break;
77
78 default :
79 if (!LoadStringAndOem(hInstance, IDS_UNKNOWN, szNode, sizeof(szNode)))
80 return NULL;
81 break;
82 }
83
84 return szNode;
85 }
86
87
88 LPTSTR GetInterfaceTypeName(UINT InterfaceType)
89 {
90 static TCHAR szIntType[25];
91
92 switch (InterfaceType)
93 {
94 case MIB_IF_TYPE_OTHER:
95 if (!LoadStringAndOem(hInstance, IDS_OTHER, szIntType, sizeof(szIntType)))
96 return NULL;
97 break;
98
99 case MIB_IF_TYPE_ETHERNET:
100 if (!LoadStringAndOem(hInstance, IDS_ETH, szIntType, sizeof(szIntType)))
101 return NULL;
102 break;
103
104 case MIB_IF_TYPE_TOKENRING:
105 if (!LoadStringAndOem(hInstance, IDS_TOKEN, szIntType, sizeof(szIntType)))
106 return NULL;
107 break;
108
109 case MIB_IF_TYPE_FDDI:
110 if (!LoadStringAndOem(hInstance, IDS_FDDI, szIntType, sizeof(szIntType)))
111 return NULL;
112 break;
113
114 case MIB_IF_TYPE_PPP:
115 if (!LoadStringAndOem(hInstance, IDS_PPP, szIntType, sizeof(szIntType)))
116 return NULL;
117 break;
118
119 case MIB_IF_TYPE_LOOPBACK:
120 if (!LoadStringAndOem(hInstance, IDS_LOOP, szIntType, sizeof(szIntType)))
121 return NULL;
122 break;
123
124 case MIB_IF_TYPE_SLIP:
125 if (!LoadStringAndOem(hInstance, IDS_SLIP, szIntType, sizeof(szIntType)))
126 return NULL;
127 break;
128
129 default:
130 if (!LoadStringAndOem(hInstance, IDS_UNKNOWN, szIntType, sizeof(szIntType)))
131 return NULL;
132 break;
133 }
134
135 return szIntType;
136 }
137
138
139 /* print MAC address */
140 PTCHAR PrintMacAddr(PBYTE Mac)
141 {
142 static TCHAR MacAddr[20];
143
144 _stprintf(MacAddr, _T("%02x-%02x-%02x-%02x-%02x-%02x"),
145 Mac[0], Mac[1], Mac[2], Mac[3], Mac[4], Mac[5]);
146
147 return MacAddr;
148 }
149
150
151 VOID DoFormatMessage(LONG ErrorCode)
152 {
153 LPVOID lpMsgBuf;
154 //DWORD ErrorCode;
155
156 if (ErrorCode == 0)
157 ErrorCode = GetLastError();
158
159 if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
160 FORMAT_MESSAGE_FROM_SYSTEM |
161 FORMAT_MESSAGE_IGNORE_INSERTS,
162 NULL,
163 ErrorCode,
164 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */
165 (LPTSTR) &lpMsgBuf,
166 0,
167 NULL))
168 {
169 _tprintf(_T("%s"), (LPTSTR)lpMsgBuf);
170 LocalFree(lpMsgBuf);
171 }
172 }
173
174
175 LPTSTR GetConnectionType(LPTSTR lpClass)
176 {
177 HKEY hKey = NULL;
178 LPTSTR ConType = NULL;
179 LPTSTR ConTypeTmp = NULL;
180 TCHAR Path[256];
181 LPTSTR PrePath = _T("SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\");
182 LPTSTR PostPath = _T("\\Connection");
183 DWORD PathSize;
184 DWORD dwType;
185 DWORD dwDataSize;
186
187 /* don't overflow the buffer */
188 PathSize = lstrlen(PrePath) + lstrlen(lpClass) + lstrlen(PostPath) + 1;
189 if (PathSize >= 255)
190 return NULL;
191
192 wsprintf(Path, _T("%s%s%s"), PrePath, lpClass, PostPath);
193
194 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
195 Path,
196 0,
197 KEY_READ,
198 &hKey) == ERROR_SUCCESS)
199 {
200 if (RegQueryValueEx(hKey,
201 _T("Name"),
202 NULL,
203 &dwType,
204 NULL,
205 &dwDataSize) == ERROR_SUCCESS)
206 {
207 ConTypeTmp = (LPTSTR)HeapAlloc(ProcessHeap,
208 0,
209 dwDataSize);
210
211 if (ConTypeTmp == NULL)
212 return NULL;
213
214 ConType = (LPTSTR)HeapAlloc(ProcessHeap,
215 0,
216 dwDataSize);
217
218 if (ConType == NULL)
219 {
220 HeapFree(ProcessHeap, 0, ConTypeTmp);
221 return NULL;
222 }
223
224 if (RegQueryValueEx(hKey,
225 _T("Name"),
226 NULL,
227 &dwType,
228 (PBYTE)ConTypeTmp,
229 &dwDataSize) != ERROR_SUCCESS)
230 {
231 HeapFree(ProcessHeap,
232 0,
233 ConType);
234
235 ConType = NULL;
236 }
237
238 if (ConType)
239 CharToOem(ConTypeTmp, ConType);
240 HeapFree(ProcessHeap, 0, ConTypeTmp);
241 }
242 }
243
244 if (hKey != NULL)
245 RegCloseKey(hKey);
246
247 return ConType;
248 }
249
250
251 LPTSTR GetConnectionDescription(LPTSTR lpClass)
252 {
253 HKEY hBaseKey = NULL;
254 HKEY hClassKey = NULL;
255 LPTSTR lpKeyClass = NULL;
256 LPTSTR lpConDesc = NULL;
257 LPTSTR lpPath = NULL;
258 TCHAR szPrePath[] = _T("SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}\\");
259 DWORD dwType;
260 DWORD dwDataSize;
261 INT i;
262
263 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
264 szPrePath,
265 0,
266 KEY_READ,
267 &hBaseKey) != ERROR_SUCCESS)
268 {
269 return NULL;
270 }
271
272 for (i = 0; ; i++)
273 {
274 DWORD PathSize;
275 LONG Status;
276 TCHAR szName[10];
277 DWORD NameLen = 9;
278
279 if ((Status = RegEnumKeyEx(hBaseKey,
280 i,
281 szName,
282 &NameLen,
283 NULL,
284 NULL,
285 NULL,
286 NULL)) != ERROR_SUCCESS)
287 {
288 if (Status == ERROR_NO_MORE_ITEMS)
289 {
290 DoFormatMessage(Status);
291 lpConDesc = NULL;
292 goto CLEANUP;
293 }
294 else
295 continue;
296 }
297
298 PathSize = lstrlen(szPrePath) + lstrlen(szName) + 1;
299 lpPath = (LPTSTR)HeapAlloc(ProcessHeap,
300 0,
301 PathSize * sizeof(TCHAR));
302 if (lpPath == NULL)
303 goto CLEANUP;
304
305 wsprintf(lpPath, _T("%s%s"), szPrePath, szName);
306
307 //MessageBox(NULL, lpPath, NULL, 0);
308
309 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
310 lpPath,
311 0,
312 KEY_READ,
313 &hClassKey) != ERROR_SUCCESS)
314 {
315 goto CLEANUP;
316 }
317
318 HeapFree(ProcessHeap, 0, lpPath);
319 lpPath = NULL;
320
321 if (RegQueryValueEx(hClassKey,
322 _T("NetCfgInstanceId"),
323 NULL,
324 &dwType,
325 NULL,
326 &dwDataSize) == ERROR_SUCCESS)
327 {
328 lpKeyClass = (LPTSTR)HeapAlloc(ProcessHeap,
329 0,
330 dwDataSize);
331 if (lpKeyClass == NULL)
332 goto CLEANUP;
333
334 if (RegQueryValueEx(hClassKey,
335 _T("NetCfgInstanceId"),
336 NULL,
337 &dwType,
338 (PBYTE)lpKeyClass,
339 &dwDataSize) != ERROR_SUCCESS)
340 {
341 HeapFree(ProcessHeap, 0, lpKeyClass);
342 lpKeyClass = NULL;
343 continue;
344 }
345 }
346 else
347 continue;
348
349 if (!lstrcmp(lpClass, lpKeyClass))
350 {
351 HeapFree(ProcessHeap, 0, lpKeyClass);
352 lpKeyClass = NULL;
353
354 if (RegQueryValueEx(hClassKey,
355 _T("DriverDesc"),
356 NULL,
357 &dwType,
358 NULL,
359 &dwDataSize) == ERROR_SUCCESS)
360 {
361 lpConDesc = (LPTSTR)HeapAlloc(ProcessHeap,
362 0,
363 dwDataSize);
364 if (lpConDesc == NULL)
365 goto CLEANUP;
366
367 if (RegQueryValueEx(hClassKey,
368 _T("DriverDesc"),
369 NULL,
370 &dwType,
371 (PBYTE)lpConDesc,
372 &dwDataSize) != ERROR_SUCCESS)
373 {
374 HeapFree(ProcessHeap, 0, lpConDesc);
375 lpConDesc = NULL;
376 goto CLEANUP;
377 }
378 }
379 else
380 {
381 lpConDesc = NULL;
382 }
383
384 break;
385 }
386 }
387
388 CLEANUP:
389 if (hBaseKey != NULL)
390 RegCloseKey(hBaseKey);
391 if (hClassKey != NULL)
392 RegCloseKey(hClassKey);
393 if (lpPath != NULL)
394 HeapFree(ProcessHeap, 0, lpPath);
395 if (lpKeyClass != NULL)
396 HeapFree(ProcessHeap, 0, lpKeyClass);
397
398 return lpConDesc;
399 }
400
401
402 VOID ShowInfo(BOOL bAll)
403 {
404 MIB_IFROW mibEntry;
405 PIP_ADAPTER_INFO pAdapterInfo = NULL;
406 PIP_ADAPTER_INFO pAdapter = NULL;
407 ULONG adaptOutBufLen = 0;
408 PFIXED_INFO pFixedInfo = NULL;
409 ULONG netOutBufLen = 0;
410 ULONG ret = 0;
411
412 /* call GetAdaptersInfo to obtain the adapter info */
413 ret = GetAdaptersInfo(pAdapterInfo, &adaptOutBufLen);
414 if (ret == ERROR_BUFFER_OVERFLOW)
415 {
416 pAdapterInfo = (IP_ADAPTER_INFO *)HeapAlloc(ProcessHeap, 0, adaptOutBufLen);
417 if (pAdapterInfo == NULL)
418 return;
419
420 ret = GetAdaptersInfo(pAdapterInfo, &adaptOutBufLen);
421 if (ret != NO_ERROR)
422 {
423 DoFormatMessage(0);
424 HeapFree(ProcessHeap, 0, pAdapterInfo);
425 return;
426 }
427 }
428 else
429 {
430 if (ret != ERROR_NO_DATA)
431 {
432 DoFormatMessage(0);
433 return;
434 }
435 }
436
437 /* call GetNetworkParams to obtain the network info */
438 if (GetNetworkParams(pFixedInfo, &netOutBufLen) == ERROR_BUFFER_OVERFLOW)
439 {
440 pFixedInfo = (FIXED_INFO *)HeapAlloc(ProcessHeap, 0, netOutBufLen);
441 if (pFixedInfo == NULL)
442 {
443 if (pAdapterInfo)
444 HeapFree(ProcessHeap, 0, pAdapterInfo);
445 return;
446 }
447 if (GetNetworkParams(pFixedInfo, &netOutBufLen) != NO_ERROR)
448 {
449 DoFormatMessage(0);
450 if (pAdapterInfo)
451 HeapFree(ProcessHeap, 0, pAdapterInfo);
452 HeapFree(ProcessHeap, 0, pFixedInfo);
453 return;
454 }
455 }
456 else
457 {
458 if (pAdapterInfo)
459 HeapFree(ProcessHeap, 0, pAdapterInfo);
460 DoFormatMessage(0);
461 return;
462 }
463
464 pAdapter = pAdapterInfo;
465
466 _tprintf(_T("\nReactOS IP Configuration\n\n"));
467 if (bAll)
468 {
469 _tprintf(_T("\tHost Name . . . . . . . . . . . . : %s\n"), pFixedInfo->HostName);
470 _tprintf(_T("\tPrimary DNS Suffix. . . . . . . . : \n"));
471 _tprintf(_T("\tNode Type . . . . . . . . . . . . : %s\n"), GetNodeTypeName(pFixedInfo->NodeType));
472 if (pFixedInfo->EnableRouting)
473 _tprintf(_T("\tIP Routing Enabled. . . . . . . . : Yes\n"));
474 else
475 _tprintf(_T("\tIP Routing Enabled. . . . . . . . : No\n"));
476 if (pAdapter && pAdapter->HaveWins)
477 _tprintf(_T("\tWINS Proxy enabled. . . . . . . . : Yes\n"));
478 else
479 _tprintf(_T("\tWINS Proxy enabled. . . . . . . . : No\n"));
480 _tprintf(_T("\tDNS Suffix Search List. . . . . . : %s\n"), pFixedInfo->DomainName);
481 }
482
483 while (pAdapter)
484 {
485 LPTSTR IntType, myConType;
486 BOOLEAN bConnected = TRUE;
487
488 mibEntry.dwIndex = pAdapter->Index;
489 GetIfEntry(&mibEntry);
490
491 IntType = GetInterfaceTypeName(pAdapter->Type);
492 myConType = GetConnectionType(pAdapter->AdapterName);
493
494 _tprintf(_T("\n%s %s: \n\n"), IntType , myConType);
495
496 if (myConType != NULL) HeapFree(ProcessHeap, 0, myConType);
497
498 /* check if the adapter is connected to the media */
499 if (mibEntry.dwOperStatus != MIB_IF_OPER_STATUS_CONNECTED && mibEntry.dwOperStatus != MIB_IF_OPER_STATUS_OPERATIONAL)
500 {
501 bConnected = FALSE;
502 _tprintf(_T("\tMedia State . . . . . . . . . . . : Media disconnected\n"));
503 }
504 else
505 {
506 _tprintf(_T("\tConnection-specific DNS Suffix. . : %s\n"), pFixedInfo->DomainName);
507 }
508
509 if (bAll)
510 {
511 LPTSTR lpDesc = GetConnectionDescription(pAdapter->AdapterName);
512 _tprintf(_T("\tDescription . . . . . . . . . . . : %s\n"), lpDesc);
513 HeapFree(ProcessHeap, 0, lpDesc);
514 _tprintf(_T("\tPhysical Address. . . . . . . . . : %s\n"), PrintMacAddr(pAdapter->Address));
515 if (bConnected)
516 {
517 if (pAdapter->DhcpEnabled)
518 _tprintf(_T("\tDHCP Enabled. . . . . . . . . . . : Yes\n"));
519 else
520 _tprintf(_T("\tDHCP Enabled. . . . . . . . . . . : No\n"));
521 _tprintf(_T("\tAutoconfiguration Enabled . . . . : \n"));
522 }
523 }
524
525 if (!bConnected)
526 {
527 pAdapter = pAdapter->Next;
528 continue;
529 }
530
531 _tprintf(_T("\tIP Address. . . . . . . . . . . . : %s\n"), pAdapter->IpAddressList.IpAddress.String);
532 _tprintf(_T("\tSubnet Mask . . . . . . . . . . . : %s\n"), pAdapter->IpAddressList.IpMask.String);
533 if (pAdapter->GatewayList.IpAddress.String[0] != '0')
534 _tprintf(_T("\tDefault Gateway . . . . . . . . . : %s\n"), pAdapter->GatewayList.IpAddress.String);
535 else
536 _tprintf(_T("\tDefault Gateway . . . . . . . . . :\n"));
537
538 if (bAll)
539 {
540 PIP_ADDR_STRING pIPAddr;
541
542 if (pAdapter->DhcpEnabled)
543 _tprintf(_T("\tDHCP Server . . . . . . . . . . . : %s\n"), pAdapter->DhcpServer.IpAddress.String);
544
545 _tprintf(_T("\tDNS Servers . . . . . . . . . . . : "));
546 _tprintf(_T("%s\n"), pFixedInfo->DnsServerList.IpAddress.String);
547 pIPAddr = pFixedInfo->DnsServerList.Next;
548 while (pIPAddr)
549 {
550 _tprintf(_T("\t\t\t\t\t %s\n"), pIPAddr ->IpAddress.String );
551 pIPAddr = pIPAddr->Next;
552 }
553
554 if (pAdapter->HaveWins)
555 {
556 _tprintf(_T("\tPrimary WINS Server . . . . . . . : %s\n"), pAdapter->PrimaryWinsServer.IpAddress.String);
557 _tprintf(_T("\tSecondary WINS Server . . . . . . : %s\n"), pAdapter->SecondaryWinsServer.IpAddress.String);
558 }
559
560 if (pAdapter->DhcpEnabled && _tcscmp(pAdapter->DhcpServer.IpAddress.String, _T("255.255.255.255")))
561 {
562 _tprintf(_T("\tLease Obtained. . . . . . . . . . : %s"), _tasctime(localtime(&pAdapter->LeaseObtained)));
563 _tprintf(_T("\tLease Expires . . . . . . . . . . : %s"), _tasctime(localtime(&pAdapter->LeaseExpires)));
564 }
565 }
566 _tprintf(_T("\n"));
567
568 pAdapter = pAdapter->Next;
569
570 }
571
572 HeapFree(ProcessHeap, 0, pFixedInfo);
573 if (pAdapterInfo)
574 HeapFree(ProcessHeap, 0, pAdapterInfo);
575 }
576
577 VOID Release(LPTSTR Index)
578 {
579 IP_ADAPTER_INDEX_MAP AdapterInfo;
580 DWORD ret;
581 DWORD i;
582
583 /* if interface is not given, query GetInterfaceInfo */
584 if (Index == NULL)
585 {
586 PIP_INTERFACE_INFO pInfo = NULL;
587 ULONG ulOutBufLen = 0;
588
589 if (GetInterfaceInfo(pInfo, &ulOutBufLen) == ERROR_INSUFFICIENT_BUFFER)
590 {
591 pInfo = (IP_INTERFACE_INFO *)HeapAlloc(ProcessHeap, 0, ulOutBufLen);
592 if (pInfo == NULL)
593 return;
594
595 if (GetInterfaceInfo(pInfo, &ulOutBufLen) == NO_ERROR )
596 {
597 for (i = 0; i < pInfo->NumAdapters; i++)
598 {
599 CopyMemory(&AdapterInfo, &pInfo->Adapter[i], sizeof(IP_ADAPTER_INDEX_MAP));
600 _tprintf(_T("name - %ls\n"), pInfo->Adapter[i].Name);
601
602 /* Call IpReleaseAddress to release the IP address on the specified adapter. */
603 if ((ret = IpReleaseAddress(&AdapterInfo)) != NO_ERROR)
604 {
605 _tprintf(_T("\nAn error occured while releasing interface %ls : \n"), AdapterInfo.Name);
606 DoFormatMessage(ret);
607 }
608 }
609
610 HeapFree(ProcessHeap, 0, pInfo);
611 }
612 else
613 {
614 DoFormatMessage(0);
615 HeapFree(ProcessHeap, 0, pInfo);
616 return;
617 }
618 }
619 else
620 {
621 DoFormatMessage(0);
622 return;
623 }
624 }
625 else
626 {
627 ;
628 /* FIXME:
629 * we need to be able to release connections by name with support for globbing
630 * i.e. ipconfig /release Eth* will release all cards starting with Eth...
631 * ipconfig /release *con* will release all cards with 'con' in their name
632 */
633 }
634 }
635
636
637
638
639 VOID Renew(LPTSTR Index)
640 {
641 IP_ADAPTER_INDEX_MAP AdapterInfo;
642 DWORD i;
643
644 /* if interface is not given, query GetInterfaceInfo */
645 if (Index == NULL)
646 {
647 PIP_INTERFACE_INFO pInfo;
648 ULONG ulOutBufLen = 0;
649
650 pInfo = (IP_INTERFACE_INFO *)HeapAlloc(ProcessHeap, 0, sizeof(IP_INTERFACE_INFO));
651 if (pInfo == NULL)
652 {
653 _tprintf(_T("memory allocation error"));
654 return;
655 }
656
657 /* Make an initial call to GetInterfaceInfo to get
658 * the necessary size into the ulOutBufLen variable */
659 if (GetInterfaceInfo(pInfo, &ulOutBufLen) == ERROR_INSUFFICIENT_BUFFER)
660 {
661 HeapFree(ProcessHeap, 0, pInfo);
662 pInfo = (IP_INTERFACE_INFO *)HeapAlloc(ProcessHeap, 0, ulOutBufLen);
663 if (pInfo == NULL)
664 {
665 _tprintf(_T("memory allocation error"));
666 return;
667 }
668 }
669
670 /* Make a second call to GetInterfaceInfo to get the actual data we want */
671 if (GetInterfaceInfo(pInfo, &ulOutBufLen) == NO_ERROR)
672 {
673 for (i = 0; i < pInfo->NumAdapters; i++)
674 {
675 CopyMemory(&AdapterInfo, &pInfo->Adapter[i], sizeof(IP_ADAPTER_INDEX_MAP));
676 _tprintf(_T("name - %ls\n"), pInfo->Adapter[i].Name);
677
678 /* Call IpRenewAddress to renew the IP address on the specified adapter. */
679 if (IpRenewAddress(&AdapterInfo) != NO_ERROR)
680 {
681 _tprintf(_T("\nAn error occured while renew interface %s : "), _T("*name*"));
682 DoFormatMessage(0);
683 }
684 }
685 }
686 else
687 {
688 _tprintf(_T("\nGetInterfaceInfo failed : "));
689 DoFormatMessage(0);
690 }
691
692 HeapFree(ProcessHeap, 0, pInfo);
693 }
694 else
695 {
696 ;
697 /* FIXME:
698 * we need to be able to renew connections by name with support for globbing
699 * i.e. ipconfig /renew Eth* will renew all cards starting with Eth...
700 * ipconfig /renew *con* will renew all cards with 'con' in their name
701 */
702 }
703 }
704
705
706
707 VOID Usage(VOID)
708 {
709 HRSRC hRes;
710 LPTSTR lpUsage;
711 DWORD Size;
712
713 LPTSTR lpName = (LPTSTR)MAKEINTRESOURCE((IDS_USAGE >> 4) + 1);
714
715 hRes = FindResource(hInstance,
716 lpName,
717 RT_STRING);
718 if (hRes != NULL)
719 {
720 if ((Size = SizeofResource(hInstance,
721 hRes)))
722 {
723 lpUsage = (LPTSTR)HeapAlloc(ProcessHeap,
724 0,
725 Size);
726 if (lpUsage == NULL)
727 return;
728
729 if (LoadStringAndOem(hInstance,
730 IDS_USAGE,
731 lpUsage,
732 Size))
733 {
734 _tprintf(_T("%s"), lpUsage);
735 }
736
737 HeapFree(ProcessHeap, 0, lpUsage);
738 }
739 }
740
741
742 }
743
744 int main(int argc, char *argv[])
745 {
746 BOOL DoUsage=FALSE;
747 BOOL DoAll=FALSE;
748 BOOL DoRelease=FALSE;
749 BOOL DoRenew=FALSE;
750 BOOL DoFlushdns=FALSE;
751 BOOL DoRegisterdns=FALSE;
752 BOOL DoDisplaydns=FALSE;
753 BOOL DoShowclassid=FALSE;
754 BOOL DoSetclassid=FALSE;
755
756 hInstance = GetModuleHandle(NULL);
757 ProcessHeap = GetProcessHeap();
758
759 /* Parse command line for options we have been given. */
760 if ((argc > 1) && (argv[1][0]=='/' || argv[1][0]=='-'))
761 {
762 if (!_tcsicmp(&argv[1][1], _T("?")))
763 {
764 DoUsage = TRUE;
765 }
766 else if (!_tcsnicmp(&argv[1][1], _T("ALL"), _tcslen(&argv[1][1])))
767 {
768 DoAll = TRUE;
769 }
770 else if (!_tcsnicmp(&argv[1][1], _T("RELEASE"), _tcslen(&argv[1][1])))
771 {
772 DoRelease = TRUE;
773 }
774 else if (!_tcsnicmp(&argv[1][1], _T("RENEW"), _tcslen(&argv[1][1])))
775 {
776 DoRenew = TRUE;
777 }
778 else if (!_tcsnicmp(&argv[1][1], _T("FLUSHDNS"), _tcslen(&argv[1][1])))
779 {
780 DoFlushdns = TRUE;
781 }
782 else if (!_tcsnicmp(&argv[1][1], _T("FLUSHREGISTERDNS"), _tcslen(&argv[1][1])))
783 {
784 DoRegisterdns = TRUE;
785 }
786 else if (!_tcsnicmp(&argv[1][1], _T("DISPLAYDNS"), _tcslen(&argv[1][1])))
787 {
788 DoDisplaydns = TRUE;
789 }
790 else if (!_tcsnicmp(&argv[1][1], _T("SHOWCLASSID"), _tcslen(&argv[1][1])))
791 {
792 DoShowclassid = TRUE;
793 }
794 else if (!_tcsnicmp(&argv[1][1], _T("SETCLASSID"), _tcslen(&argv[1][1])))
795 {
796 DoSetclassid = TRUE;
797 }
798 }
799
800 switch (argc)
801 {
802 case 1: /* Default behaviour if no options are given*/
803 ShowInfo(FALSE);
804 break;
805 case 2: /* Process all the options that take no parameters */
806 if (DoUsage)
807 Usage();
808 else if (DoAll)
809 ShowInfo(TRUE);
810 else if (DoRelease)
811 Release(NULL);
812 else if (DoRenew)
813 Renew(NULL);
814 else if (DoFlushdns)
815 _tprintf(_T("\nSorry /flushdns is not implemented yet\n"));
816 else if (DoRegisterdns)
817 _tprintf(_T("\nSorry /registerdns is not implemented yet\n"));
818 else if (DoDisplaydns)
819 _tprintf(_T("\nSorry /displaydns is not implemented yet\n"));
820 else
821 Usage();
822 break;
823 case 3: /* Process all the options that can have 1 parameter */
824 if (DoRelease)
825 _tprintf(_T("\nSorry /release [adapter] is not implemented yet\n"));
826 //Release(argv[2]);
827 else if (DoRenew)
828 _tprintf(_T("\nSorry /renew [adapter] is not implemented yet\n"));
829 else if (DoShowclassid)
830 _tprintf(_T("\nSorry /showclassid adapter is not implemented yet\n"));
831 else if (DoSetclassid)
832 _tprintf(_T("\nSorry /setclassid adapter is not implemented yet\n"));
833 else
834 Usage();
835 break;
836 case 4: /* Process all the options that can have 2 parameters */
837 if (DoSetclassid)
838 _tprintf(_T("\nSorry /setclassid adapter [classid]is not implemented yet\n"));
839 else
840 Usage();
841 break;
842 default:
843 Usage();
844 }
845
846 return 0;
847 }