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