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 } 848