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