[NTOS:IO]
[reactos.git] / reactos / 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 #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 {
38 TCHAR *szTmp;
39 int res;
40
41 szTmp = (LPTSTR)HeapAlloc(ProcessHeap, 0, byteSize);
42 if (szTmp == NULL)
43 {
44 return 0;
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 ConType = (LPTSTR)HeapAlloc(ProcessHeap,
212 0,
213 dwDataSize);
214 if (ConType && ConTypeTmp)
215 {
216 if(RegQueryValueEx(hKey,
217 _T("Name"),
218 NULL,
219 &dwType,
220 (PBYTE)ConTypeTmp,
221 &dwDataSize) != ERROR_SUCCESS)
222 {
223 HeapFree(ProcessHeap,
224 0,
225 ConType);
226
227 HeapFree(ProcessHeap,
228 0,
229 ConTypeTmp);
230
231 ConType = NULL;
232 }
233
234 if (ConType) CharToOem(ConTypeTmp, ConType);
235 }
236 }
237 }
238
239 if (hKey != NULL)
240 RegCloseKey(hKey);
241
242 return ConType;
243 }
244
245
246 LPTSTR GetConnectionDescription(LPTSTR lpClass)
247 {
248 HKEY hBaseKey = NULL;
249 HKEY hClassKey = NULL;
250 LPTSTR lpKeyClass = NULL;
251 LPTSTR lpConDesc = NULL;
252 LPTSTR lpPath = NULL;
253 TCHAR szPrePath[] = _T("SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}\\");
254 DWORD dwType;
255 DWORD dwDataSize;
256 INT i;
257
258 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
259 szPrePath,
260 0,
261 KEY_READ,
262 &hBaseKey) != ERROR_SUCCESS)
263 {
264 return NULL;
265 }
266
267 for (i=0; ; i++)
268 {
269 DWORD PathSize;
270 LONG Status;
271 TCHAR szName[10];
272 DWORD NameLen = 9;
273
274 if ((Status = RegEnumKeyEx(hBaseKey,
275 i,
276 szName,
277 &NameLen,
278 NULL,
279 NULL,
280 NULL,
281 NULL)) != ERROR_SUCCESS)
282 {
283 if (Status == ERROR_NO_MORE_ITEMS)
284 {
285 DoFormatMessage(Status);
286 lpConDesc = NULL;
287 goto CLEANUP;
288 }
289 else
290 continue;
291 }
292
293 PathSize = lstrlen(szPrePath) + lstrlen(szName) + 1;
294 lpPath = (LPTSTR)HeapAlloc(ProcessHeap,
295 0,
296 PathSize * sizeof(TCHAR));
297 if (lpPath == NULL)
298 goto CLEANUP;
299
300 wsprintf(lpPath, _T("%s%s"), szPrePath, szName);
301
302 //MessageBox(NULL, lpPath, NULL, 0);
303
304 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
305 lpPath,
306 0,
307 KEY_READ,
308 &hClassKey) != ERROR_SUCCESS)
309 {
310 goto CLEANUP;
311 }
312
313 HeapFree(ProcessHeap, 0, lpPath);
314 lpPath = NULL;
315
316 if(RegQueryValueEx(hClassKey,
317 _T("NetCfgInstanceId"),
318 NULL,
319 &dwType,
320 NULL,
321 &dwDataSize) == ERROR_SUCCESS)
322 {
323 lpKeyClass = (LPTSTR)HeapAlloc(ProcessHeap,
324 0,
325 dwDataSize);
326 if (lpKeyClass == NULL)
327 goto CLEANUP;
328
329 if(RegQueryValueEx(hClassKey,
330 _T("NetCfgInstanceId"),
331 NULL,
332 &dwType,
333 (PBYTE)lpKeyClass,
334 &dwDataSize) != ERROR_SUCCESS)
335 {
336 lpKeyClass = NULL;
337 HeapFree(ProcessHeap, 0, lpKeyClass);
338 continue;
339 }
340 }
341 else
342 continue;
343
344 if (!lstrcmp(lpClass, lpKeyClass))
345 {
346 HeapFree(ProcessHeap, 0, lpKeyClass);
347 lpKeyClass = NULL;
348
349 if(RegQueryValueEx(hClassKey,
350 _T("DriverDesc"),
351 NULL,
352 &dwType,
353 NULL,
354 &dwDataSize) == ERROR_SUCCESS)
355 {
356 lpConDesc = (LPTSTR)HeapAlloc(ProcessHeap,
357 0,
358 dwDataSize);
359 if (lpConDesc == NULL)
360 goto CLEANUP;
361
362 if(RegQueryValueEx(hClassKey,
363 _T("DriverDesc"),
364 NULL,
365 &dwType,
366 (PBYTE)lpConDesc,
367 &dwDataSize) != ERROR_SUCCESS)
368 {
369 lpConDesc = NULL;
370 goto CLEANUP;
371 }
372 }
373 else
374 lpConDesc = NULL;
375
376 break;
377 }
378 }
379
380 CLEANUP:
381 if (hBaseKey != NULL)
382 RegCloseKey(hBaseKey);
383 if (hClassKey != NULL)
384 RegCloseKey(hClassKey);
385 if (lpConDesc != NULL)
386 HeapFree(ProcessHeap, 0, lpPath);
387 if (lpConDesc != NULL)
388 HeapFree(ProcessHeap, 0, lpKeyClass);
389
390 return lpConDesc;
391 }
392
393
394 VOID ShowInfo(BOOL bAll)
395 {
396 MIB_IFROW mibEntry;
397 PIP_ADAPTER_INFO pAdapterInfo = NULL;
398 PIP_ADAPTER_INFO pAdapter = NULL;
399 ULONG adaptOutBufLen = 0;
400 PFIXED_INFO pFixedInfo = NULL;
401 ULONG netOutBufLen = 0;
402 ULONG ret = 0;
403
404 /* call GetAdaptersInfo to obtain the adapter info */
405 ret = GetAdaptersInfo(pAdapterInfo, &adaptOutBufLen);
406 if (ret == ERROR_BUFFER_OVERFLOW)
407 {
408 pAdapterInfo = (IP_ADAPTER_INFO *)HeapAlloc(ProcessHeap, 0, adaptOutBufLen);
409 if (pAdapterInfo == NULL)
410 return;
411
412 ret = GetAdaptersInfo(pAdapterInfo, &adaptOutBufLen);
413 if (ret != NO_ERROR)
414 {
415 DoFormatMessage(0);
416 HeapFree(ProcessHeap, 0, pAdapterInfo);
417 return;
418 }
419 }
420 else
421 {
422 if( ERROR_NO_DATA != ret )
423 {
424 DoFormatMessage(0);
425 return;
426 }
427 }
428
429 /* call GetNetworkParams to obtain the network info */
430 if(GetNetworkParams(pFixedInfo, &netOutBufLen) == ERROR_BUFFER_OVERFLOW)
431 {
432 pFixedInfo = (FIXED_INFO *)HeapAlloc(ProcessHeap, 0, netOutBufLen);
433 if (pFixedInfo == NULL)
434 {
435 if (pAdapterInfo)
436 HeapFree(ProcessHeap, 0, pAdapterInfo);
437 return;
438 }
439 if (GetNetworkParams(pFixedInfo, &netOutBufLen) != NO_ERROR)
440 {
441 DoFormatMessage(0);
442 if (pAdapterInfo)
443 HeapFree(ProcessHeap, 0, pAdapterInfo);
444 HeapFree(ProcessHeap, 0, pFixedInfo);
445 return;
446 }
447 }
448 else
449 {
450 if (pAdapterInfo)
451 HeapFree(ProcessHeap, 0, pAdapterInfo);
452 DoFormatMessage(0);
453 return;
454 }
455
456 pAdapter = pAdapterInfo;
457
458 _tprintf(_T("\nReactOS IP Configuration\n\n"));
459 if (bAll)
460 {
461 _tprintf(_T("\tHost Name . . . . . . . . . . . . : %s\n"), pFixedInfo->HostName);
462 _tprintf(_T("\tPrimary DNS Suffix. . . . . . . . : \n"));
463 _tprintf(_T("\tNode Type . . . . . . . . . . . . : %s\n"), GetNodeTypeName(pFixedInfo->NodeType));
464 if (pFixedInfo->EnableRouting)
465 _tprintf(_T("\tIP Routing Enabled. . . . . . . . : Yes\n"));
466 else
467 _tprintf(_T("\tIP Routing Enabled. . . . . . . . : No\n"));
468 if (pAdapter && pAdapter->HaveWins)
469 _tprintf(_T("\tWINS Proxy enabled. . . . . . . . : Yes\n"));
470 else
471 _tprintf(_T("\tWINS Proxy enabled. . . . . . . . : No\n"));
472 _tprintf(_T("\tDNS Suffix Search List. . . . . . : %s\n"), pFixedInfo->DomainName);
473 }
474
475 while (pAdapter)
476 {
477 LPTSTR IntType, myConType;
478
479 mibEntry.dwIndex = pAdapter->Index;
480 GetIfEntry(&mibEntry);
481
482 IntType = GetInterfaceTypeName(pAdapter->Type);
483 myConType = GetConnectionType(pAdapter->AdapterName);
484
485 _tprintf(_T("\n%s %s: \n\n"), IntType , myConType);
486
487 if (myConType != NULL) HeapFree(ProcessHeap, 0, myConType);
488
489 /* check if the adapter is connected to the media */
490 if (mibEntry.dwOperStatus != MIB_IF_OPER_STATUS_CONNECTED && mibEntry.dwOperStatus != MIB_IF_OPER_STATUS_OPERATIONAL)
491 {
492 _tprintf(_T("\tMedia State . . . . . . . . . . . : Media disconnected\n"));
493 pAdapter = pAdapter->Next;
494 continue;
495 }
496
497 _tprintf(_T("\tConnection-specific DNS Suffix. . : %s\n"), pFixedInfo->DomainName);
498
499 if (bAll)
500 {
501 LPTSTR lpDesc = GetConnectionDescription(pAdapter->AdapterName);
502 _tprintf(_T("\tDescription . . . . . . . . . . . : %s\n"), lpDesc);
503 HeapFree(ProcessHeap, 0, lpDesc);
504 _tprintf(_T("\tPhysical Address. . . . . . . . . : %s\n"), PrintMacAddr(pAdapter->Address));
505 if (pAdapter->DhcpEnabled)
506 _tprintf(_T("\tDHCP Enabled. . . . . . . . . . . : Yes\n"));
507 else
508 _tprintf(_T("\tDHCP Enabled. . . . . . . . . . . : No\n"));
509 _tprintf(_T("\tAutoconfiguration Enabled . . . . : \n"));
510 }
511
512 _tprintf(_T("\tIP Address. . . . . . . . . . . . : %s\n"), pAdapter->IpAddressList.IpAddress.String);
513 _tprintf(_T("\tSubnet Mask . . . . . . . . . . . : %s\n"), pAdapter->IpAddressList.IpMask.String);
514 if (pAdapter->GatewayList.IpAddress.String[0] != '0')
515 _tprintf(_T("\tDefault Gateway . . . . . . . . . : %s\n"), pAdapter->GatewayList.IpAddress.String);
516 else
517 _tprintf(_T("\tDefault Gateway . . . . . . . . . :\n"));
518
519 if (bAll)
520 {
521 PIP_ADDR_STRING pIPAddr;
522
523 if (pAdapter->DhcpEnabled)
524 _tprintf(_T("\tDHCP Server . . . . . . . . . . . : %s\n"), pAdapter->DhcpServer.IpAddress.String);
525
526 _tprintf(_T("\tDNS Servers . . . . . . . . . . . : "));
527 _tprintf(_T("%s\n"), pFixedInfo->DnsServerList.IpAddress.String);
528 pIPAddr = pFixedInfo->DnsServerList.Next;
529 while (pIPAddr)
530 {
531 _tprintf(_T("\t\t\t\t\t %s\n"), pIPAddr ->IpAddress.String );
532 pIPAddr = pIPAddr->Next;
533 }
534
535 if (pAdapter->HaveWins)
536 {
537 _tprintf(_T("\tPrimary WINS Server . . . . . . . : %s\n"), pAdapter->PrimaryWinsServer.IpAddress.String);
538 _tprintf(_T("\tSecondard WINS Server . . . . . . : %s\n"), pAdapter->SecondaryWinsServer.IpAddress.String);
539 }
540
541 if (pAdapter->DhcpEnabled)
542 {
543 _tprintf(_T("\tLease Obtained. . . . . . . . . . : %s"), _tasctime(localtime(&pAdapter->LeaseObtained)));
544 _tprintf(_T("\tLease Expires . . . . . . . . . . : %s"), _tasctime(localtime(&pAdapter->LeaseExpires)));
545 }
546 }
547 _tprintf(_T("\n"));
548
549 pAdapter = pAdapter->Next;
550
551 }
552
553 HeapFree(ProcessHeap, 0, pFixedInfo);
554 if (pAdapterInfo)
555 HeapFree(ProcessHeap, 0, pAdapterInfo);
556 }
557
558 VOID Release(LPTSTR Index)
559 {
560 IP_ADAPTER_INDEX_MAP AdapterInfo;
561 DWORD ret;
562 DWORD i;
563
564 /* if interface is not given, query GetInterfaceInfo */
565 if (Index == NULL)
566 {
567 PIP_INTERFACE_INFO pInfo = NULL;
568 ULONG ulOutBufLen = 0;
569
570 if (GetInterfaceInfo(pInfo, &ulOutBufLen) == ERROR_INSUFFICIENT_BUFFER)
571 {
572 pInfo = (IP_INTERFACE_INFO *)HeapAlloc(ProcessHeap, 0, ulOutBufLen);
573 if (pInfo == NULL)
574 return;
575
576 if (GetInterfaceInfo(pInfo, &ulOutBufLen) == NO_ERROR )
577 {
578 for (i = 0; i < pInfo->NumAdapters; i++)
579 {
580 CopyMemory(&AdapterInfo, &pInfo->Adapter[i], sizeof(IP_ADAPTER_INDEX_MAP));
581 _tprintf(_T("name - %S\n"), pInfo->Adapter[i].Name);
582
583 /* Call IpReleaseAddress to release the IP address on the specified adapter. */
584 if ((ret = IpReleaseAddress(&AdapterInfo)) != NO_ERROR)
585 {
586 _tprintf(_T("\nAn error occured while releasing interface %S : \n"), AdapterInfo.Name);
587 DoFormatMessage(ret);
588 }
589 }
590
591 HeapFree(ProcessHeap, 0, pInfo);
592 }
593 else
594 {
595 DoFormatMessage(0);
596 HeapFree(ProcessHeap, 0, pInfo);
597 return;
598 }
599 }
600 else
601 {
602 DoFormatMessage(0);
603 return;
604 }
605 }
606 else
607 {
608 ;
609 /* FIXME:
610 * we need to be able to release connections by name with support for globbing
611 * i.e. ipconfig /release Eth* will release all cards starting with Eth...
612 * ipconfig /release *con* will release all cards with 'con' in their name
613 */
614 }
615 }
616
617
618
619
620 VOID Renew(LPTSTR Index)
621 {
622 IP_ADAPTER_INDEX_MAP AdapterInfo;
623 DWORD i;
624
625 /* if interface is not given, query GetInterfaceInfo */
626 if (Index == NULL)
627 {
628 PIP_INTERFACE_INFO pInfo;
629 ULONG ulOutBufLen = 0;
630
631 pInfo = (IP_INTERFACE_INFO *)HeapAlloc(ProcessHeap, 0, sizeof(IP_INTERFACE_INFO));
632 if (pInfo == NULL)
633 {
634 _tprintf(_T("memory allocation error"));
635 return;
636 }
637
638 /* Make an initial call to GetInterfaceInfo to get
639 * the necessary size into the ulOutBufLen variable */
640 if ( GetInterfaceInfo(pInfo, &ulOutBufLen) == ERROR_INSUFFICIENT_BUFFER)
641 {
642 HeapFree(ProcessHeap, 0, pInfo);
643 pInfo = (IP_INTERFACE_INFO *)HeapAlloc(ProcessHeap, 0, ulOutBufLen);
644 if (pInfo == NULL)
645 {
646 _tprintf(_T("memory allocation error"));
647 return;
648 }
649 }
650
651 /* Make a second call to GetInterfaceInfo to get the actual data we want */
652 if (GetInterfaceInfo(pInfo, &ulOutBufLen) == NO_ERROR )
653 {
654 for (i = 0; i < pInfo->NumAdapters; i++)
655 {
656 CopyMemory(&AdapterInfo, &pInfo->Adapter[i], sizeof(IP_ADAPTER_INDEX_MAP));
657 _tprintf(_T("name - %S\n"), pInfo->Adapter[i].Name);
658
659
660 /* Call IpRenewAddress to renew the IP address on the specified adapter. */
661 if (IpRenewAddress(&AdapterInfo) != NO_ERROR)
662 {
663 _tprintf(_T("\nAn error occured while renew interface %s : "), _T("*name*"));
664 DoFormatMessage(0);
665 }
666 }
667 }
668 else
669 {
670 _tprintf(_T("\nGetInterfaceInfo failed : "));
671 DoFormatMessage(0);
672 }
673
674 HeapFree(ProcessHeap, 0, pInfo);
675 }
676 else
677 {
678 ;
679 /* FIXME:
680 * we need to be able to renew connections by name with support for globbing
681 * i.e. ipconfig /renew Eth* will renew all cards starting with Eth...
682 * ipconfig /renew *con* will renew all cards with 'con' in their name
683 */
684 }
685 }
686
687
688
689 VOID Usage(VOID)
690 {
691 HRSRC hRes;
692 LPTSTR lpUsage;
693 DWORD Size;
694
695 LPTSTR lpName = (LPTSTR)MAKEINTRESOURCE((IDS_USAGE >> 4) + 1);
696
697 hRes = FindResource(hInstance,
698 lpName,
699 RT_STRING);
700 if (hRes != NULL)
701 {
702 if ((Size = SizeofResource(hInstance,
703 hRes)))
704 {
705 lpUsage = (LPTSTR)HeapAlloc(ProcessHeap,
706 0,
707 Size);
708 if (lpUsage == NULL)
709 return;
710
711 if (LoadStringAndOem(hInstance,
712 IDS_USAGE,
713 lpUsage,
714 Size))
715 {
716 _tprintf(_T("%s"), lpUsage);
717 }
718 }
719 }
720
721
722 }
723
724 int main(int argc, char *argv[])
725 {
726 BOOL DoUsage=FALSE;
727 BOOL DoAll=FALSE;
728 BOOL DoRelease=FALSE;
729 BOOL DoRenew=FALSE;
730 BOOL DoFlushdns=FALSE;
731 BOOL DoRegisterdns=FALSE;
732 BOOL DoDisplaydns=FALSE;
733 BOOL DoShowclassid=FALSE;
734 BOOL DoSetclassid=FALSE;
735
736 hInstance = GetModuleHandle(NULL);
737 ProcessHeap = GetProcessHeap();
738
739 /* Parse command line for options we have been given. */
740 if ( (argc > 1)&&(argv[1][0]=='/' || argv[1][0]=='-') )
741 {
742 if( !_tcsicmp( &argv[1][1], _T("?") ))
743 {
744 DoUsage = TRUE;
745 }
746 else if( !_tcsnicmp( &argv[1][1], _T("ALL"), _tcslen(&argv[1][1]) ))
747 {
748 DoAll = TRUE;
749 }
750 else if( !_tcsnicmp( &argv[1][1], _T("RELEASE"), _tcslen(&argv[1][1]) ))
751 {
752 DoRelease = TRUE;
753 }
754 else if( ! _tcsnicmp( &argv[1][1], _T("RENEW"), _tcslen(&argv[1][1]) ))
755 {
756 DoRenew = TRUE;
757 }
758 else if( ! _tcsnicmp( &argv[1][1], _T("FLUSHDNS"), _tcslen(&argv[1][1]) ))
759 {
760 DoFlushdns = TRUE;
761 }
762 else if( ! _tcsnicmp( &argv[1][1], _T("FLUSHREGISTERDNS"), _tcslen(&argv[1][1]) ))
763 {
764 DoRegisterdns = TRUE;
765 }
766 else if( ! _tcsnicmp( &argv[1][1], _T("DISPLAYDNS"), _tcslen(&argv[1][1]) ))
767 {
768 DoDisplaydns = TRUE;
769 }
770 else if( ! _tcsnicmp( &argv[1][1], _T("SHOWCLASSID"), _tcslen(&argv[1][1]) ))
771 {
772 DoShowclassid = TRUE;
773 }
774 else if( ! _tcsnicmp( &argv[1][1], _T("SETCLASSID"), _tcslen(&argv[1][1]) ))
775 {
776 DoSetclassid = TRUE;
777 }
778 }
779
780 switch (argc)
781 {
782 case 1: /* Default behaviour if no options are given*/
783 ShowInfo(FALSE);
784 break;
785 case 2: /* Process all the options that take no parameters */
786 if (DoUsage)
787 Usage();
788 else if (DoAll)
789 ShowInfo(TRUE);
790 else if (DoRelease)
791 Release(NULL);
792 else if (DoRenew)
793 Renew(NULL);
794 else if (DoFlushdns)
795 _tprintf(_T("\nSorry /flushdns is not implemented yet\n"));
796 else if (DoRegisterdns)
797 _tprintf(_T("\nSorry /registerdns is not implemented yet\n"));
798 else if (DoDisplaydns)
799 _tprintf(_T("\nSorry /displaydns is not implemented yet\n"));
800 else
801 Usage();
802 break;
803 case 3: /* Process all the options that can have 1 parameter */
804 if (DoRelease)
805 _tprintf(_T("\nSorry /release [adapter] is not implemented yet\n"));
806 //Release(argv[2]);
807 else if (DoRenew)
808 _tprintf(_T("\nSorry /renew [adapter] is not implemented yet\n"));
809 else if (DoShowclassid)
810 _tprintf(_T("\nSorry /showclassid adapter is not implemented yet\n"));
811 else if (DoSetclassid)
812 _tprintf(_T("\nSorry /setclassid adapter is not implemented yet\n"));
813 else
814 Usage();
815 break;
816 case 4: /* Process all the options that can have 2 parameters */
817 if (DoSetclassid)
818 _tprintf(_T("\nSorry /setclassid adapter [classid]is not implemented yet\n"));
819 else
820 Usage();
821 break;
822 default:
823 Usage();
824 }
825
826 return 0;
827 }