Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1218 lines
28 KiB

  1. /*++
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. ipconfig.c
  5. Abstract:
  6. updated clean version of ipconfig.
  7. --*/
  8. #include <precomp.h>
  9. #include <shellapi.h>
  10. #include <dhcpcapi.h>
  11. #include <locale.h>
  12. #include <dnslib.h>
  13. int InitLogger(const char *fname);
  14. void DoneLogger(void);
  15. DWORD
  16. WriteOutput(
  17. IN HANDLE hOut,
  18. IN LPWSTR String
  19. )
  20. {
  21. DWORD Error = NO_ERROR, Unused;
  22. INT StringLen;
  23. StringLen = wcslen(String);
  24. if( GetFileType(hOut) == FILE_TYPE_CHAR )
  25. {
  26. if (StringLen < 0)
  27. {
  28. Error = ERROR_NOT_ENOUGH_MEMORY;
  29. }
  30. else
  31. {
  32. while (StringLen > 0)
  33. {
  34. if (!WriteConsoleW(hOut, String, min(StringLen, 1024), &Unused, 0 ))
  35. {
  36. Error = GetLastError();
  37. break;
  38. }
  39. String += 1024;
  40. StringLen -= 1024;
  41. }
  42. }
  43. if( ERROR_INVALID_HANDLE != Error ) return Error;
  44. }
  45. //
  46. // If it is not a console, this is good enough
  47. //
  48. printf("%ws", String );
  49. return NO_ERROR;
  50. }
  51. BOOL
  52. StringIsSame(
  53. IN LPWSTR Str1,
  54. IN LPWSTR Str2
  55. )
  56. {
  57. return CSTR_EQUAL == CompareString(
  58. LOCALE_USER_DEFAULT, NORM_IGNORECASE |
  59. NORM_IGNOREKANATYPE | NORM_IGNOREWIDTH,
  60. Str1, -1, Str2, -2 );
  61. }
  62. DWORD
  63. ParseCommandLine(
  64. IN OUT PCMD_ARGS Args,
  65. IN OUT LPWSTR *Argv,
  66. IN DWORD Argc,
  67. OUT LPWSTR *AdapterName,
  68. OUT LPWSTR *ClassId
  69. )
  70. {
  71. Argc --; Argv ++;
  72. if( Argc == 0 ) return NO_ERROR;
  73. if( **Argv != L'/' && **Argv != L'-' ) {
  74. return ERROR_INVALID_DATA;
  75. }
  76. (*Argv)++;
  77. if( StringIsSame(Args->Debug, *Argv) ) {
  78. LocalFree( Args->Debug );
  79. Args->Debug = NULL;
  80. Argv ++;
  81. Argc --;
  82. if( **Argv != L'/' && **Argv != L'-' ) {
  83. return ERROR_INVALID_DATA;
  84. }
  85. (*Argv)++;
  86. }
  87. if( Argc == 0 ) return NO_ERROR;
  88. if( Argc >= 2 ) (*AdapterName) = Argv[1];
  89. if( Argc == 3 ) (*ClassId) = Argv[2];
  90. if( **Argv == L'?' ) {
  91. return ERROR_INVALID_COMMAND_LINE;
  92. }
  93. if( StringIsSame(Args->All, *Argv) ) {
  94. if( Argc != 1 ) return ERROR_INVALID_DATA;
  95. LocalFree( Args->All );
  96. Args->All = NULL;
  97. return NO_ERROR;
  98. }
  99. if( StringIsSame(Args->FlushDns, *Argv) ) {
  100. if( Argc != 1 ) return ERROR_INVALID_DATA;
  101. LocalFree( Args->FlushDns );
  102. Args->FlushDns = NULL;
  103. return NO_ERROR;
  104. }
  105. if( StringIsSame(Args->Register, *Argv) ) {
  106. if( Argc != 1 ) return ERROR_INVALID_DATA;
  107. LocalFree( Args->Register );
  108. Args->Register = NULL;
  109. return NO_ERROR;
  110. }
  111. if( StringIsSame(Args->DisplayDns, *Argv) ) {
  112. if( Argc != 1 ) return ERROR_INVALID_DATA;
  113. LocalFree( Args->DisplayDns );
  114. Args->DisplayDns = NULL;
  115. return NO_ERROR;
  116. }
  117. if( StringIsSame(Args->Renew, *Argv) ) {
  118. if( Argc > 2 ) return ERROR_INVALID_DATA;
  119. LocalFree( Args->Renew );
  120. Args->Renew = NULL;
  121. return NO_ERROR;
  122. }
  123. if( StringIsSame(Args->Release, *Argv) ) {
  124. if( Argc > 2 ) return ERROR_INVALID_DATA;
  125. LocalFree( Args->Release );
  126. Args->Release = NULL;
  127. return NO_ERROR;
  128. }
  129. if( StringIsSame(Args->ShowClassId, *Argv) ) {
  130. if( Argc != 2 ) return ERROR_INVALID_DATA;
  131. LocalFree( Args->ShowClassId );
  132. Args->ShowClassId = NULL;
  133. return NO_ERROR;
  134. }
  135. if( StringIsSame(Args->SetClassId, *Argv) ) {
  136. if( Argc != 3 && Argc != 2 ) return ERROR_INVALID_DATA;
  137. LocalFree( Args->SetClassId );
  138. Args->SetClassId = NULL;
  139. return NO_ERROR;
  140. }
  141. return ERROR_INVALID_DATA;
  142. }
  143. BOOL
  144. StringMatch(
  145. IN LPWSTR Str1,
  146. IN LPWSTR Str2,
  147. IN BOOL fCase
  148. )
  149. {
  150. switch( *Str1 ){
  151. case L'\0' : return ! *Str2 ;
  152. case L'*' : return StringMatch( Str1+1, Str2, fCase ) || *Str2 && StringMatch( Str1, Str2+1, fCase );
  153. case L'?' : return *Str2 && StringMatch( Str1+1, Str2+1, fCase );
  154. default : return (fCase ? *Str1 == *Str2 : toupper(*Str1) == toupper(*Str2)) && StringMatch( Str1+1, Str2+1, fCase );
  155. }
  156. }
  157. BOOL
  158. InterfaceMatch(
  159. IN PINTERFACE_NETWORK_INFO IfInfo,
  160. IN LPWSTR AdapterName
  161. )
  162. {
  163. if( NULL == AdapterName ) return TRUE;
  164. if( IfInfo->ConnectionName != NULL ) {
  165. return StringMatch( AdapterName, IfInfo->ConnectionName, FALSE );
  166. }
  167. return FALSE;
  168. }
  169. DWORD
  170. DoRenew(
  171. IN LPWSTR Buffer,
  172. IN ULONG BufSize,
  173. IN PNETWORK_INFO NetInfo,
  174. IN LPWSTR AdapterName
  175. )
  176. {
  177. DWORD i, FindCount, Error, LastError;
  178. PINTERFACE_NETWORK_INFO IfInfo;
  179. BOOL fSucceeded;
  180. fSucceeded = FALSE;
  181. FindCount = 0;
  182. LastError = ERROR_INTERNAL_ERROR;
  183. for( i = 0; i < NetInfo->nInterfaces; i ++ ) {
  184. IfInfo = NetInfo->IfInfo[i];
  185. if( !InterfaceMatch(IfInfo, AdapterName) ) continue;
  186. FindCount ++;
  187. if( !IfInfo->EnableDhcp || 0 == IfInfo->nIpAddresses ) {
  188. if( NULL != AdapterName ) {
  189. DumpMessage(
  190. Buffer, BufSize, MSG_OPERATION_ON_NONDHCP,
  191. IfInfo->ConnectionName );
  192. } else FindCount --;
  193. } else if( IfInfo->MediaDisconnected ) {
  194. DumpMessage(
  195. Buffer, BufSize, MSG_MEDIA_SENSE,
  196. IfInfo->ConnectionName );
  197. } else {
  198. Error = DhcpAcquireParameters(IfInfo->DeviceGuidName);
  199. if( NO_ERROR == Error ) {
  200. fSucceeded = TRUE;
  201. } else if (ERROR_SEM_TIMEOUT == Error) {
  202. LastError = Error;
  203. DumpMessage(
  204. Buffer, BufSize, MSG_RENEW_FAILED_UNREACHABLE_DHCP,
  205. IfInfo->ConnectionName );
  206. } else {
  207. LastError = Error;
  208. DumpMessageError(
  209. Buffer, BufSize, MSG_RENEW_FAILED, Error,
  210. IfInfo->ConnectionName );
  211. }
  212. }
  213. }
  214. if( fSucceeded ) return NO_ERROR;
  215. if( FindCount == 0 ) {
  216. DumpMessage( Buffer, BufSize, MSG_NO_MATCH );
  217. }
  218. return LastError;
  219. }
  220. DWORD
  221. DoRelease(
  222. IN LPWSTR Buffer,
  223. IN ULONG BufSize,
  224. IN PNETWORK_INFO NetInfo,
  225. IN LPWSTR AdapterName
  226. )
  227. {
  228. DWORD i, FindCount, Error, LastError;
  229. PINTERFACE_NETWORK_INFO IfInfo;
  230. BOOL fSucceeded;
  231. fSucceeded = FALSE;
  232. FindCount = 0;
  233. LastError = ERROR_INTERNAL_ERROR;
  234. for( i = 0; i < NetInfo->nInterfaces; i ++ ) {
  235. IfInfo = NetInfo->IfInfo[i];
  236. if( !InterfaceMatch(IfInfo, AdapterName) ) continue;
  237. FindCount ++;
  238. if( !IfInfo->EnableDhcp || 0 == IfInfo->nIpAddresses ) {
  239. if( NULL != AdapterName ) {
  240. DumpMessage(
  241. Buffer, BufSize, MSG_OPERATION_ON_NONDHCP,
  242. IfInfo->ConnectionName );
  243. } else FindCount --;
  244. } else if( IfInfo->MediaDisconnected ) {
  245. DumpMessage(
  246. Buffer, BufSize, MSG_MEDIA_SENSE,
  247. IfInfo->ConnectionName );
  248. } else if( IfInfo->IpAddress[0] == INADDR_ANY ) {
  249. DumpMessage(
  250. Buffer, BufSize, MSG_ZERO_ADDRESS,
  251. IfInfo->ConnectionName );
  252. } else {
  253. Error = DhcpReleaseParameters(IfInfo->DeviceGuidName);
  254. if( NO_ERROR == Error ) {
  255. fSucceeded = TRUE;
  256. } else {
  257. LastError = Error;
  258. DumpMessageError(
  259. Buffer, BufSize, MSG_RELEASE_FAILED, Error,
  260. IfInfo->ConnectionName );
  261. }
  262. }
  263. }
  264. if( fSucceeded ) return NO_ERROR;
  265. if( FindCount == 0 ) {
  266. DumpMessage( Buffer, BufSize, MSG_NO_MATCH );
  267. }
  268. return LastError;
  269. }
  270. DWORD
  271. DoFlushDns(
  272. IN LPWSTR Buffer,
  273. IN ULONG BufSize,
  274. IN PNETWORK_INFO NetInfo
  275. )
  276. {
  277. DWORD Error;
  278. UNREFERENCED_PARAMETER( NetInfo);
  279. Error = DnsFlushResolverCache();
  280. if( FALSE == Error ) {
  281. Error = ERROR_FUNCTION_FAILED;
  282. DumpMessageError(
  283. Buffer, BufSize, MSG_FLUSHDNS_FAILED, Error, NULL );
  284. } else {
  285. DumpMessage(
  286. Buffer, BufSize, MSG_FLUSHDNS_SUCCEEDED );
  287. }
  288. return Error;
  289. }
  290. extern DWORD DhcpStaticRefreshParams(IN LPWSTR Adapter);
  291. DWORD
  292. DoRegisterDns(
  293. IN LPWSTR Buffer,
  294. IN ULONG BufSize,
  295. IN PNETWORK_INFO NetInfo
  296. )
  297. {
  298. DWORD Error;
  299. extern DWORD RegisterIPv6Dns(VOID);
  300. //
  301. // Since IPv6 call is asynchronous, no error doesn't necessarily
  302. // mean the success of DNS registration. So ignore it.
  303. //
  304. Error = RegisterIPv6Dns();
  305. Error = DhcpStaticRefreshParams(NULL);
  306. if( NO_ERROR != Error ) {
  307. DumpMessageError(
  308. Buffer, BufSize, MSG_REGISTERDNS_FAILED, Error, NULL );
  309. } else {
  310. DumpMessage(
  311. Buffer, BufSize, MSG_REGISTERDNS_SUCCEEDED );
  312. }
  313. UNREFERENCED_PARAMETER( NetInfo );
  314. return Error;
  315. }
  316. VOID
  317. PrintARecord (
  318. IN OUT LPWSTR Buffer,
  319. IN ULONG BufSize,
  320. IN PDNS_RECORD DnsRecord
  321. )
  322. {
  323. WCHAR IpAddr[20];
  324. swprintf(
  325. IpAddr,
  326. L"%d.%d.%d.%d",
  327. ((BYTE *) &DnsRecord->Data.A.IpAddress)[0],
  328. ((BYTE *) &DnsRecord->Data.A.IpAddress)[1],
  329. ((BYTE *) &DnsRecord->Data.A.IpAddress)[2],
  330. ((BYTE *) &DnsRecord->Data.A.IpAddress)[3] );
  331. DumpMessage( Buffer, BufSize, MSG_DNS_A_RECORD, IpAddr );
  332. }
  333. VOID
  334. PrintSOARecord (
  335. IN OUT LPWSTR Buffer,
  336. IN ULONG BufSize,
  337. IN PDNS_RECORD DnsRecord
  338. )
  339. {
  340. WCHAR SerialNo[20], Refresh[20], Retry[20];
  341. WCHAR Expire[20], Ttl[20];
  342. swprintf( SerialNo, L"%d", DnsRecord->Data.SOA.dwSerialNo );
  343. swprintf( Refresh, L"%d", DnsRecord->Data.SOA.dwRefresh );
  344. swprintf( Retry, L"%d", DnsRecord->Data.SOA.dwRetry );
  345. swprintf( Expire, L"%d", DnsRecord->Data.SOA.dwExpire );
  346. swprintf( Ttl, L"%d", DnsRecord->Data.SOA.dwDefaultTtl );
  347. DumpMessage(
  348. Buffer, BufSize, MSG_DNS_SOA_RECORD,
  349. DnsRecord->Data.SOA.pNamePrimaryServer,
  350. DnsRecord->Data.SOA.pNameAdministrator,
  351. SerialNo,
  352. Refresh,
  353. Retry,
  354. Expire,
  355. Ttl );
  356. }
  357. VOID
  358. PrintPTRRecord (
  359. IN ULONG MsgId,
  360. IN OUT LPWSTR Buffer,
  361. IN ULONG BufSize,
  362. IN PDNS_RECORD DnsRecord
  363. )
  364. {
  365. DumpMessage(
  366. Buffer,
  367. BufSize,
  368. MsgId,
  369. DnsRecord->Data.PTR.pNameHost );
  370. }
  371. VOID
  372. PrintMXRecord (
  373. IN OUT LPWSTR Buffer,
  374. IN ULONG BufSize,
  375. IN PDNS_RECORD DnsRecord
  376. )
  377. {
  378. WCHAR Pref[20], Pad[20];
  379. swprintf( Pref, L"%d", DnsRecord->Data.MX.wPreference );
  380. swprintf( Pad, L"%d", DnsRecord->Data.MX.Pad );
  381. DumpMessage(
  382. Buffer,
  383. BufSize,
  384. MSG_DNS_MX_RECORD,
  385. DnsRecord->Data.MX.pNameExchange,
  386. Pref,
  387. Pad );
  388. }
  389. VOID
  390. PrintAAAARecord(
  391. IN OUT PWSTR Buffer,
  392. IN ULONG BufSize,
  393. IN PDNS_RECORD DnsRecord
  394. )
  395. {
  396. WCHAR stringIp6[IP6_ADDRESS_STRING_BUFFER_LENGTH];
  397. Dns_Ip6AddressToString_W(
  398. stringIp6,
  399. & DnsRecord->Data.AAAA.Ip6Address );
  400. DumpMessage(
  401. Buffer,
  402. BufSize,
  403. MSG_DNS_AAAA_RECORD,
  404. stringIp6 );
  405. }
  406. VOID
  407. PrintSRVRecord (
  408. IN OUT LPWSTR Buffer,
  409. IN ULONG BufSize,
  410. IN PDNS_RECORD DnsRecord
  411. )
  412. {
  413. WCHAR Priority[20], Weight[20], Port[20];
  414. swprintf( Priority, L"%d", DnsRecord->Data.SRV.wPriority );
  415. swprintf( Weight, L"%d", DnsRecord->Data.SRV.wWeight );
  416. swprintf( Port, L"%d", DnsRecord->Data.SRV.wPort );
  417. DumpMessage(
  418. Buffer,
  419. BufSize,
  420. MSG_DNS_SRV_RECORD,
  421. DnsRecord->Data.SRV.pNameTarget,
  422. Priority,
  423. Weight,
  424. Port );
  425. }
  426. VOID
  427. PrintATMARecord (
  428. IN OUT LPWSTR Buffer,
  429. IN ULONG BufSize,
  430. IN PDNS_RECORD DnsRecord
  431. )
  432. {
  433. WCHAR Type[20], Address[300];
  434. swprintf( Type, L"%d", DnsRecord->Data.ATMA.AddressType );
  435. if ( DnsRecord->Data.ATMA.Address &&
  436. DnsRecord->Data.ATMA.AddressType == DNS_ATMA_FORMAT_E164 ) {
  437. swprintf(
  438. Address,
  439. L"%S",
  440. DnsRecord->Data.ATMA.Address );
  441. } else {
  442. DWORD iter;
  443. for ( iter = 0; iter < DnsRecord->wDataLength; iter++ ) {
  444. swprintf(
  445. &Address[iter*2],
  446. L"%02x",
  447. DnsRecord->Data.ATMA.Address[iter]
  448. );
  449. }
  450. }
  451. DumpMessage(
  452. Buffer, BufSize, MSG_DNS_ATMA_RECORD, Type, Address );
  453. }
  454. VOID
  455. PrintDnsRecord(
  456. IN OUT LPWSTR Buffer,
  457. IN ULONG BufSize,
  458. IN PDNS_RECORD DnsRecord
  459. )
  460. {
  461. WCHAR Type[20], Ttl[20], DataLen[20];
  462. DWORD MsgId;
  463. if ( ! DnsRecord ) return;
  464. swprintf( Type, L"%d", DnsRecord->wType );
  465. swprintf( Ttl, L"%d", DnsRecord->dwTtl );
  466. swprintf( DataLen, L"%d", DnsRecord->wDataLength );
  467. DumpMessage(
  468. Buffer, BufSize, MSG_DNS_RECORD_HEADER,
  469. DnsRecord->pName, (LPWSTR)Type, (LPWSTR)Ttl,
  470. (LPWSTR)DataLen );
  471. if ( DnsRecord->Flags.S.Section == DNSREC_QUESTION ) {
  472. MsgId = MSG_DNS_QUESTION_SECTION;
  473. } else if ( DnsRecord->Flags.S.Section == DNSREC_ANSWER ) {
  474. MsgId = MSG_DNS_ANSWER_SECTION;
  475. } else if ( DnsRecord->Flags.S.Section == DNSREC_AUTHORITY ) {
  476. MsgId = MSG_DNS_AUTHORITY_SECTION;
  477. } else {
  478. MsgId = MSG_DNS_ADDITIONAL_SECTION;
  479. }
  480. DumpMessage( Buffer, BufSize, MsgId );
  481. switch( DnsRecord->wType )
  482. {
  483. case DNS_TYPE_A :
  484. PrintARecord( Buffer, BufSize, DnsRecord );
  485. break;
  486. case DNS_TYPE_SOA :
  487. PrintSOARecord( Buffer, BufSize, DnsRecord );
  488. break;
  489. case DNS_TYPE_PTR :
  490. PrintPTRRecord(
  491. MSG_DNS_PTR_RECORD, Buffer, BufSize, DnsRecord );
  492. break;
  493. case DNS_TYPE_NS :
  494. PrintPTRRecord(
  495. MSG_DNS_NS_RECORD, Buffer, BufSize, DnsRecord );
  496. break;
  497. case DNS_TYPE_CNAME :
  498. PrintPTRRecord(
  499. MSG_DNS_CNAME_RECORD, Buffer, BufSize, DnsRecord );
  500. break;
  501. case DNS_TYPE_MX :
  502. PrintMXRecord( Buffer, BufSize, DnsRecord );
  503. break;
  504. case DNS_TYPE_AAAA :
  505. PrintAAAARecord( Buffer, BufSize, DnsRecord );
  506. break;
  507. case DNS_TYPE_SRV :
  508. PrintSRVRecord( Buffer, BufSize, DnsRecord );
  509. break;
  510. case DNS_TYPE_ATMA :
  511. PrintATMARecord( Buffer, BufSize, DnsRecord );
  512. break;
  513. default :
  514. break;
  515. }
  516. }
  517. VOID
  518. PrintDnsRecords(
  519. IN OUT LPWSTR Buffer,
  520. IN ULONG BufSize,
  521. IN PDNS_RECORD DnsRecord
  522. )
  523. {
  524. PDNS_RECORD Tmp = DnsRecord;
  525. while( Tmp ) {
  526. PrintDnsRecord( Buffer, BufSize, Tmp );
  527. Tmp = Tmp->pNext;
  528. }
  529. }
  530. BOOL
  531. GetDnsCachedData(
  532. IN OUT LPWSTR Buffer,
  533. IN ULONG BufSize,
  534. IN LPWSTR Name,
  535. IN WORD Type
  536. )
  537. {
  538. PDNS_RECORD DnsRecord = NULL;
  539. DNS_STATUS DnsStatus;
  540. DnsStatus = DnsQuery_W(
  541. Name,
  542. Type,
  543. DNS_QUERY_CACHE_ONLY,
  544. NULL,
  545. & DnsRecord,
  546. NULL );
  547. if ( DnsStatus != NO_ERROR ) {
  548. if ( DnsStatus == DNS_INFO_NO_RECORDS ) {
  549. WCHAR wsTypeName[ 20 ];
  550. Dns_WriteStringForType_W(
  551. wsTypeName,
  552. Type );
  553. DumpMessage(
  554. Buffer,
  555. BufSize,
  556. MSG_DNS_ERR_NO_RECORDS,
  557. Name,
  558. wsTypeName );
  559. } else if ( DnsStatus == DNS_ERROR_RCODE_NAME_ERROR ) {
  560. DumpMessage(
  561. Buffer, BufSize, MSG_DNS_ERR_NAME_ERROR, Name );
  562. } else if ( DnsStatus == DNS_ERROR_RECORD_DOES_NOT_EXIST ) {
  563. //
  564. // Don't print?
  565. //
  566. } else {
  567. DumpMessage(
  568. Buffer, BufSize, MSG_DNS_ERR_UNABLE_TO_DISPLAY,
  569. Name );
  570. }
  571. return FALSE;
  572. }
  573. if ( DnsRecord ) {
  574. DumpMessage(
  575. Buffer, BufSize, MSG_DNS_RECORD_PREAMBLE, Name );
  576. PrintDnsRecords( Buffer, BufSize, DnsRecord );
  577. DnsRecordListFree( DnsRecord, TRUE );
  578. }
  579. return TRUE;
  580. }
  581. VOID
  582. DisplayDnsCacheData(
  583. IN OUT LPWSTR Buffer,
  584. IN ULONG BufSize
  585. )
  586. {
  587. PDNS_CACHE_TABLE pDNSCacheTable = NULL;
  588. PDNS_CACHE_TABLE pTempDNSCacheTable = NULL;
  589. if( !DnsGetCacheDataTable( &pDNSCacheTable ) ) {
  590. DumpMessage(
  591. Buffer, BufSize, MSG_DISPLAYDNS_FAILED );
  592. return;
  593. }
  594. pTempDNSCacheTable = pDNSCacheTable;
  595. while( pTempDNSCacheTable ) {
  596. PDNS_CACHE_TABLE pNext = pTempDNSCacheTable->pNext;
  597. if( pTempDNSCacheTable->Type1 != DNS_TYPE_ZERO ) {
  598. GetDnsCachedData(
  599. Buffer, BufSize, pTempDNSCacheTable->Name,
  600. pTempDNSCacheTable->Type1 );
  601. }
  602. if( pTempDNSCacheTable->Type2 != DNS_TYPE_ZERO ) {
  603. GetDnsCachedData(
  604. Buffer, BufSize, pTempDNSCacheTable->Name,
  605. pTempDNSCacheTable->Type2 );
  606. }
  607. if( pTempDNSCacheTable->Type3 != DNS_TYPE_ZERO ) {
  608. GetDnsCachedData(
  609. Buffer, BufSize, pTempDNSCacheTable->Name,
  610. pTempDNSCacheTable->Type3 );
  611. }
  612. if( pTempDNSCacheTable->Name ) {
  613. LocalFree( pTempDNSCacheTable->Name );
  614. }
  615. LocalFree( pTempDNSCacheTable );
  616. pTempDNSCacheTable = pNext;
  617. }
  618. }
  619. DWORD
  620. DoDisplayDns(
  621. IN LPWSTR Buffer,
  622. IN ULONG BufSize,
  623. IN PNETWORK_INFO NetInfo
  624. )
  625. {
  626. UNREFERENCED_PARAMETER( NetInfo);
  627. DisplayDnsCacheData( Buffer, BufSize );
  628. return NO_ERROR;
  629. }
  630. DWORD
  631. DoShowClassId(
  632. IN LPWSTR Buffer,
  633. IN ULONG BufSize,
  634. IN PNETWORK_INFO NetInfo,
  635. IN LPWSTR AdapterName
  636. )
  637. {
  638. DWORD i, Error, Size, nClassesPrinted;
  639. PINTERFACE_NETWORK_INFO IfInfo;
  640. DHCP_CLASS_INFO *pClasses;
  641. IfInfo = NULL;
  642. for( i = 0; i < NetInfo->nInterfaces; i ++ ) {
  643. IfInfo = NetInfo->IfInfo[i];
  644. if( !InterfaceMatch(IfInfo, AdapterName) ) continue;
  645. if( !IfInfo->DeviceGuidName ) continue;
  646. break;
  647. }
  648. if( i == NetInfo->nInterfaces ) {
  649. DumpMessage(
  650. Buffer, BufSize, MSG_NO_MATCH );
  651. return ERROR_NOT_FOUND;
  652. }
  653. do {
  654. Size = 0; pClasses = NULL;
  655. Error = DhcpEnumClasses(
  656. 0, IfInfo->DeviceGuidName, &Size, pClasses
  657. );
  658. if( ERROR_MORE_DATA != Error ) {
  659. if( NO_ERROR == Error ) {
  660. DumpMessage(
  661. Buffer, BufSize, MSG_NO_CLASSES,
  662. IfInfo->ConnectionName );
  663. }
  664. break;
  665. }
  666. pClasses = LocalAlloc(LMEM_FIXED, Size);
  667. if( NULL == pClasses ) {
  668. Error = ERROR_NOT_ENOUGH_MEMORY;
  669. break;
  670. }
  671. Error = DhcpEnumClasses(
  672. 0, IfInfo->DeviceGuidName, &Size, pClasses
  673. );
  674. if( NO_ERROR != Error ) {
  675. LocalFree(pClasses);
  676. break;
  677. }
  678. nClassesPrinted = Size;
  679. if( nClassesPrinted ) {
  680. DumpMessage(
  681. Buffer, BufSize, MSG_CLASSES_LIST_HEADER,
  682. IfInfo->ConnectionName );
  683. for( i = 0; i < nClassesPrinted ; i ++ ) {
  684. DumpMessage(
  685. Buffer, BufSize, MSG_CLASSID,
  686. pClasses[i].ClassName, pClasses[i].ClassDescr );
  687. }
  688. } else {
  689. DumpMessage(
  690. Buffer, BufSize, MSG_NO_CLASSES,
  691. IfInfo->ConnectionName );
  692. }
  693. LocalFree(pClasses);
  694. } while ( 0 );
  695. if( NO_ERROR != Error ) {
  696. DumpMessage(
  697. Buffer, BufSize, MSG_CLASSID_FAILED, Error,
  698. IfInfo->ConnectionName );
  699. }
  700. return Error;
  701. }
  702. DWORD
  703. DoSetClassId(
  704. IN LPWSTR Buffer,
  705. IN ULONG BufSize,
  706. IN PNETWORK_INFO NetInfo,
  707. IN LPWSTR AdapterName,
  708. IN LPWSTR ClassId
  709. )
  710. {
  711. DWORD i, Error;
  712. PINTERFACE_NETWORK_INFO IfInfo;
  713. HKEY hKey;
  714. DHCP_PNP_CHANGE Changes;
  715. IfInfo = NULL;
  716. for( i = 0; i < NetInfo->nInterfaces; i ++ ) {
  717. IfInfo = NetInfo->IfInfo[i];
  718. if( !InterfaceMatch(IfInfo, AdapterName) ) continue;
  719. if( !IfInfo->DeviceGuidName ) continue;
  720. break;
  721. }
  722. if( i == NetInfo->nInterfaces ) {
  723. DumpMessage(
  724. Buffer, BufSize, MSG_NO_MATCH );
  725. return ERROR_NOT_FOUND;
  726. }
  727. Error = OpenRegKey(
  728. IfInfo->DeviceGuidName, OpenTcpipKey, OpenKeyForWrite,
  729. &hKey );
  730. if( NO_ERROR != Error ) {
  731. DumpErrorMessage(
  732. Buffer, BufSize, InterfaceOpenTcpipKeyReadFailure,
  733. Error );
  734. return Error;
  735. }
  736. if( NULL == ClassId ) ClassId = (LPWSTR)L"";
  737. RegSetValueExW(
  738. hKey, (LPWSTR) L"DhcpClassId", 0, REG_SZ,
  739. (LPBYTE)ClassId, sizeof(WCHAR)*(1+wcslen(ClassId)) );
  740. RegCloseKey( hKey );
  741. ZeroMemory(&Changes, sizeof(Changes));
  742. Changes.ClassIdChanged = TRUE;
  743. Error = DhcpHandlePnPEvent(
  744. 0, DHCP_CALLER_TCPUI, IfInfo->DeviceGuidName, &Changes,
  745. NULL );
  746. if( NO_ERROR != Error ) {
  747. DumpMessageError(
  748. Buffer, BufSize, MSG_SETCLASSID_FAILED, Error,
  749. IfInfo->ConnectionName );
  750. } else {
  751. DumpMessage(
  752. Buffer, BufSize, MSG_SETCLASSID_SUCCEEDED,
  753. IfInfo->ConnectionName );
  754. }
  755. return Error;
  756. }
  757. void _cdecl main(void)
  758. {
  759. WCHAR TmpBuffer[8000];
  760. WCHAR *Buffer;
  761. DWORD LocalError, Error, InternalError, BufSize = 512;
  762. PNETWORK_INFO NetInfo;
  763. LPWSTR *Argv, CommandLine, AdapterName, ClassId;
  764. int Argc;
  765. CMD_ARGS Args;
  766. BOOL fVerbose;
  767. BOOL fDebug;
  768. BOOL fDisplay;
  769. UNREFERENCED_PARAMETER(InternalError);
  770. UNREFERENCED_PARAMETER(NetInfo);
  771. //
  772. // bug 211927: set the locale to the system default
  773. //
  774. setlocale ( LC_ALL, "" );
  775. InitLogger("ipconfig.log");
  776. CommandLine = GetCommandLineW();
  777. if( NULL == CommandLine ) {
  778. DbgPrint("GetCommandLineW: 0x%x\n", GetLastError());
  779. DoneLogger();
  780. exit(1);
  781. }
  782. Argv = CommandLineToArgvW(CommandLine, &Argc );
  783. if( NULL == Argv ) {
  784. DbgPrint("CommandLineToArgvW: 0x%x\n", GetLastError());
  785. DoneLogger();
  786. exit(1);
  787. }
  788. Error = GetCommandArgConstants( &Args );
  789. if( NO_ERROR != Error ) {
  790. DbgPrint("GetCommandArgConstants: 0x%lx\n", Error );
  791. DoneLogger();
  792. exit(1);
  793. }
  794. AdapterName = NULL; ClassId = NULL;
  795. //
  796. // The ParseCommandLine routine NULLs out the field in Args
  797. // that was supplied by teh user... i.e ipconfig /renew would
  798. // cause Args.Renew to be NULL on return
  799. //
  800. Error = ParseCommandLine(
  801. &Args, Argv, Argc, &AdapterName, &ClassId );
  802. if( ERROR_INVALID_COMMAND_LINE == Error ) {
  803. WriteOutput( GetStdHandle( STD_OUTPUT_HANDLE), Args.Usage );
  804. DoneLogger();
  805. exit(1);
  806. }
  807. if( NO_ERROR != Error ) {
  808. WriteOutput( GetStdHandle( STD_OUTPUT_HANDLE), Args.UsageErr );
  809. WriteOutput( GetStdHandle( STD_OUTPUT_HANDLE), Args.Usage );
  810. DoneLogger();
  811. exit(1);
  812. }
  813. fVerbose = (Args.All == NULL);
  814. fDebug = (Args.Debug == NULL);
  815. fDisplay = FALSE;
  816. NetInfo = NULL;
  817. Error = GetNetworkInformation(
  818. &NetInfo, &InternalError );
  819. //
  820. // Calculate how much space it would take to display a full display..
  821. //
  822. do {
  823. Buffer = LocalAlloc( LPTR, sizeof(WCHAR)*BufSize );
  824. if( Buffer == NULL ) break;
  825. LocalError = FormatNetworkInfo(
  826. Buffer, BufSize, NetInfo,
  827. Error,InternalError,TRUE,fDebug);
  828. LocalFree(Buffer);
  829. BufSize *= 2;
  830. } while( NO_ERROR != LocalError );
  831. if( NULL != Buffer ) {
  832. Buffer = LocalAlloc( LPTR, sizeof(WCHAR)*BufSize );
  833. }
  834. if( NULL == Buffer ) {
  835. Buffer = (LPWSTR)TmpBuffer;
  836. BufSize = sizeof(TmpBuffer)/sizeof(WCHAR);
  837. Error = ERROR_NOT_ENOUGH_MEMORY;
  838. }
  839. DumpMessage(
  840. Buffer, BufSize, MSG_TITLE );
  841. if( NO_ERROR != Error || Args.All == NULL ) {
  842. fDisplay = TRUE;
  843. } else if( Args.Renew == NULL ) {
  844. //
  845. // Attempt to renew
  846. //
  847. Error = DoRenew( Buffer, BufSize, NetInfo, AdapterName);
  848. fDisplay = (NO_ERROR == Error);
  849. if( fDisplay ) {
  850. FreeNetworkInfo( NetInfo );
  851. Error = GetNetworkInformation(
  852. &NetInfo, &InternalError );
  853. }
  854. } else if( Args.Release == NULL ) {
  855. //
  856. // Attempt to renew
  857. //
  858. Error = DoRelease( Buffer, BufSize, NetInfo, AdapterName);
  859. fDisplay = (NO_ERROR == Error);
  860. if( fDisplay ) {
  861. FreeNetworkInfo( NetInfo );
  862. Error = GetNetworkInformation(
  863. &NetInfo, &InternalError );
  864. }
  865. } else if( Args.FlushDns == NULL ) {
  866. DoFlushDns( Buffer, BufSize, NetInfo );
  867. } else if( Args.Register == NULL ) {
  868. DoRegisterDns( Buffer, BufSize, NetInfo );
  869. } else if( Args.DisplayDns == NULL ) {
  870. DoDisplayDns( Buffer, BufSize, NetInfo );
  871. } else if( Args.ShowClassId == NULL ) {
  872. DoShowClassId( Buffer, BufSize, NetInfo, AdapterName );
  873. } else if( Args.SetClassId == NULL ) {
  874. DoSetClassId( Buffer, BufSize, NetInfo, AdapterName, ClassId );
  875. } else {
  876. fDisplay = TRUE;
  877. }
  878. if( fDisplay ) {
  879. FormatNetworkInfo(
  880. Buffer, BufSize, NetInfo,
  881. Error, InternalError, fVerbose, fDebug );
  882. }
  883. Error = WriteOutput( GetStdHandle( STD_OUTPUT_HANDLE), Buffer );
  884. if (Error != NO_ERROR)
  885. {
  886. Buffer[0] = L'\0';
  887. DumpMessage(Buffer, BufSize, MSG_TITLE );
  888. DumpErrorMessage(Buffer, BufSize, NoSpecificError, Error);
  889. WriteOutput( GetStdHandle( STD_OUTPUT_HANDLE ), Buffer );
  890. }
  891. FreeNetworkInfo(NetInfo);
  892. GlobalFree( Argv );
  893. LocalFree( Args.All );
  894. LocalFree( Args.Renew );
  895. LocalFree( Args.Release );
  896. LocalFree( Args.FlushDns );
  897. LocalFree( Args.Register );
  898. LocalFree( Args.DisplayDns );
  899. LocalFree( Args.ShowClassId );
  900. LocalFree( Args.SetClassId );
  901. LocalFree( Args.Debug );
  902. LocalFree( Args.Usage );
  903. DoneLogger();
  904. exit(0);
  905. }
  906. DWORD
  907. RegisterIPv6Dns(VOID)
  908. {
  909. DWORD dwErr = NO_ERROR;
  910. SC_HANDLE hcm = NULL;
  911. SC_HANDLE hSvc = NULL;
  912. SERVICE_STATUS status = {0};
  913. #define SERVICE_CONTROL_6TO4_REGISER_DNS 128
  914. do
  915. {
  916. hcm = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
  917. if (NULL == hcm)
  918. {
  919. dwErr = GetLastError();
  920. IPCFG_TRACE(IPCFG_TRACE_TCPIP, ("OpenSCManager returns 0x%lx (%d)\n", dwErr, dwErr));
  921. break;
  922. }
  923. hSvc = OpenService(hcm, L"6to4", SERVICE_USER_DEFINED_CONTROL);
  924. if (NULL == hSvc)
  925. {
  926. dwErr = GetLastError();
  927. IPCFG_TRACE(IPCFG_TRACE_TCPIP, ("OpenService returns 0x%lx (%d)\n", dwErr, dwErr));
  928. break;
  929. }
  930. if (!ControlService(hSvc, SERVICE_CONTROL_6TO4_REGISER_DNS, &status))
  931. {
  932. dwErr = GetLastError();
  933. IPCFG_TRACE(IPCFG_TRACE_TCPIP, ("ControlService returns 0x%lx (%d)\n", dwErr, dwErr));
  934. break;
  935. }
  936. } while (FALSE);
  937. if (hSvc)
  938. {
  939. CloseServiceHandle(hSvc);
  940. }
  941. if (hcm)
  942. {
  943. CloseServiceHandle(hcm);
  944. }
  945. IPCFG_TRACE(IPCFG_TRACE_TCPIP, ("RegisterIPv6Dns returns 0x%lx (%d)\n", dwErr, dwErr));
  946. return dwErr;
  947. }
  948. #ifdef __IPCFG_ENABLE_LOG__
  949. DWORD dwTraceFlag = 0xffffffffU;
  950. static FILE *hLogger = NULL;
  951. int
  952. InitLogger(const char *fname)
  953. {
  954. if (hLogger) {
  955. fclose(hLogger);
  956. }
  957. hLogger = fopen(fname, "w+");
  958. return (hLogger == NULL)? (-1): 0;
  959. }
  960. void
  961. DoneLogger(void)
  962. {
  963. if (hLogger) {
  964. fclose(hLogger);
  965. hLogger = NULL;
  966. }
  967. }
  968. int
  969. TraceFunc(const char* fmt, ...)
  970. {
  971. va_list ap;
  972. if (hLogger != NULL) {
  973. va_start(ap, fmt);
  974. vfprintf(hLogger, fmt, ap);
  975. va_end(ap);
  976. }
  977. return 0;
  978. }
  979. #else
  980. int InitLogger(const char *fname)
  981. {
  982. UNREFERENCED_PARAMETER(fname);
  983. return 0;
  984. }
  985. void DoneLogger(void) {}
  986. int TraceFunc(const char* fmt, ...)
  987. {
  988. UNREFERENCED_PARAMETER(fmt);
  989. return 0;
  990. }
  991. #endif