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