Leaked source code of windows server 2003
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.

1223 lines
30 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. DnsFree( pTempDNSCacheTable->Name, DnsFreeFlat );
  613. DnsFree( pTempDNSCacheTable, DnsFreeFlat );
  614. pTempDNSCacheTable = pNext;
  615. }
  616. }
  617. DWORD
  618. DoDisplayDns(
  619. IN LPWSTR Buffer,
  620. IN ULONG BufSize,
  621. IN PNETWORK_INFO NetInfo
  622. )
  623. {
  624. UNREFERENCED_PARAMETER( NetInfo);
  625. DisplayDnsCacheData( Buffer, BufSize );
  626. return NO_ERROR;
  627. }
  628. DWORD
  629. DoShowClassId(
  630. IN LPWSTR Buffer,
  631. IN ULONG BufSize,
  632. IN PNETWORK_INFO NetInfo,
  633. IN LPWSTR AdapterName
  634. )
  635. {
  636. DWORD i, Error, Size, nClassesPrinted;
  637. PINTERFACE_NETWORK_INFO IfInfo;
  638. DHCP_CLASS_INFO *pClasses;
  639. IfInfo = NULL;
  640. for( i = 0; i < NetInfo->nInterfaces; i ++ ) {
  641. IfInfo = NetInfo->IfInfo[i];
  642. if( !InterfaceMatch(IfInfo, AdapterName) ) continue;
  643. if( !IfInfo->DeviceGuidName ) continue;
  644. break;
  645. }
  646. if( i == NetInfo->nInterfaces ) {
  647. DumpMessage(
  648. Buffer, BufSize, MSG_NO_MATCH );
  649. return ERROR_NOT_FOUND;
  650. }
  651. do {
  652. Size = 0; pClasses = NULL;
  653. Error = DhcpEnumClasses(
  654. 0, IfInfo->DeviceGuidName, &Size, pClasses
  655. );
  656. if( ERROR_MORE_DATA != Error ) {
  657. if( NO_ERROR == Error ) {
  658. DumpMessage(
  659. Buffer, BufSize, MSG_NO_CLASSES,
  660. IfInfo->ConnectionName );
  661. } else {
  662. IPCFG_TRACE(IPCFG_TRACE_TCPIP, ("1. DhcpEnumClasses returns %d\n", Error));
  663. }
  664. break;
  665. }
  666. IPCFG_TRACE(IPCFG_TRACE_TCPIP, ("DhcpEnumClasses asks for %d bytes\n", Size));
  667. pClasses = LocalAlloc(LMEM_FIXED, Size);
  668. if( NULL == pClasses ) {
  669. Error = ERROR_NOT_ENOUGH_MEMORY;
  670. break;
  671. }
  672. Error = DhcpEnumClasses(
  673. 0, IfInfo->DeviceGuidName, &Size, pClasses
  674. );
  675. if( NO_ERROR != Error ) {
  676. IPCFG_TRACE(IPCFG_TRACE_TCPIP, ("2. DhcpEnumClasses returns %d\n", Error));
  677. LocalFree(pClasses);
  678. break;
  679. }
  680. nClassesPrinted = Size;
  681. if( nClassesPrinted ) {
  682. DumpMessage(
  683. Buffer, BufSize, MSG_CLASSES_LIST_HEADER,
  684. IfInfo->ConnectionName );
  685. for( i = 0; i < nClassesPrinted ; i ++ ) {
  686. IPCFG_TRACE(IPCFG_TRACE_TCPIP, ("%d. Class %ws Descr %ws\n",
  687. i + 1,
  688. pClasses[i].ClassName,
  689. pClasses[i].ClassDescr
  690. ));
  691. DumpMessage(
  692. Buffer, BufSize, MSG_CLASSID,
  693. pClasses[i].ClassName, pClasses[i].ClassDescr );
  694. }
  695. } else {
  696. DumpMessage(
  697. Buffer, BufSize, MSG_NO_CLASSES,
  698. IfInfo->ConnectionName );
  699. }
  700. LocalFree(pClasses);
  701. } while ( 0 );
  702. if( NO_ERROR != Error ) {
  703. DumpMessageError(
  704. Buffer, BufSize, MSG_CLASSID_FAILED, Error,
  705. IfInfo->ConnectionName );
  706. }
  707. return Error;
  708. }
  709. DWORD
  710. DoSetClassId(
  711. IN LPWSTR Buffer,
  712. IN ULONG BufSize,
  713. IN PNETWORK_INFO NetInfo,
  714. IN LPWSTR AdapterName,
  715. IN LPWSTR ClassId
  716. )
  717. {
  718. DWORD i, Error;
  719. PINTERFACE_NETWORK_INFO IfInfo;
  720. HKEY hKey;
  721. DHCP_PNP_CHANGE Changes;
  722. IfInfo = NULL;
  723. for( i = 0; i < NetInfo->nInterfaces; i ++ ) {
  724. IfInfo = NetInfo->IfInfo[i];
  725. if( !InterfaceMatch(IfInfo, AdapterName) ) continue;
  726. if( !IfInfo->DeviceGuidName ) continue;
  727. break;
  728. }
  729. if( i == NetInfo->nInterfaces ) {
  730. DumpMessage(
  731. Buffer, BufSize, MSG_NO_MATCH );
  732. return ERROR_NOT_FOUND;
  733. }
  734. Error = OpenRegKey(
  735. IfInfo->DeviceGuidName, OpenTcpipKey, OpenKeyForWrite,
  736. &hKey );
  737. if( NO_ERROR != Error ) {
  738. DumpErrorMessage(
  739. Buffer, BufSize, InterfaceOpenTcpipKeyReadFailure,
  740. Error );
  741. return Error;
  742. }
  743. if( NULL == ClassId ) ClassId = (LPWSTR)L"";
  744. RegSetValueExW(
  745. hKey, (LPWSTR) L"DhcpClassId", 0, REG_SZ,
  746. (LPBYTE)ClassId, sizeof(WCHAR)*(1+wcslen(ClassId)) );
  747. RegCloseKey( hKey );
  748. ZeroMemory(&Changes, sizeof(Changes));
  749. Changes.ClassIdChanged = TRUE;
  750. Error = DhcpHandlePnPEvent(
  751. 0, DHCP_CALLER_TCPUI, IfInfo->DeviceGuidName, &Changes,
  752. NULL );
  753. if( NO_ERROR != Error ) {
  754. DumpMessageError(
  755. Buffer, BufSize, MSG_SETCLASSID_FAILED, Error,
  756. IfInfo->ConnectionName );
  757. } else {
  758. DumpMessage(
  759. Buffer, BufSize, MSG_SETCLASSID_SUCCEEDED,
  760. IfInfo->ConnectionName );
  761. }
  762. return Error;
  763. }
  764. void _cdecl main(void)
  765. {
  766. WCHAR TmpBuffer[8000];
  767. WCHAR *Buffer;
  768. DWORD LocalError, Error, InternalError, BufSize = 512;
  769. PNETWORK_INFO NetInfo;
  770. LPWSTR *Argv, CommandLine, AdapterName, ClassId;
  771. int Argc;
  772. CMD_ARGS Args;
  773. BOOL fVerbose;
  774. BOOL fDebug;
  775. BOOL fDisplay;
  776. UNREFERENCED_PARAMETER(InternalError);
  777. UNREFERENCED_PARAMETER(NetInfo);
  778. //
  779. // bug 211927: set the locale to the system default
  780. //
  781. setlocale ( LC_ALL, "" );
  782. InitLogger("ipconfig.log");
  783. CommandLine = GetCommandLineW();
  784. if( NULL == CommandLine ) {
  785. DbgPrint("GetCommandLineW: 0x%x\n", GetLastError());
  786. DoneLogger();
  787. exit(1);
  788. }
  789. Argv = CommandLineToArgvW(CommandLine, &Argc );
  790. if( NULL == Argv ) {
  791. DbgPrint("CommandLineToArgvW: 0x%x\n", GetLastError());
  792. DoneLogger();
  793. exit(1);
  794. }
  795. Error = GetCommandArgConstants( &Args );
  796. if( NO_ERROR != Error ) {
  797. DbgPrint("GetCommandArgConstants: 0x%lx\n", Error );
  798. DoneLogger();
  799. exit(1);
  800. }
  801. AdapterName = NULL; ClassId = NULL;
  802. //
  803. // The ParseCommandLine routine NULLs out the field in Args
  804. // that was supplied by teh user... i.e ipconfig /renew would
  805. // cause Args.Renew to be NULL on return
  806. //
  807. Error = ParseCommandLine(
  808. &Args, Argv, Argc, &AdapterName, &ClassId );
  809. if( ERROR_INVALID_COMMAND_LINE == Error ) {
  810. WriteOutput( GetStdHandle( STD_OUTPUT_HANDLE), Args.Usage );
  811. DoneLogger();
  812. exit(1);
  813. }
  814. if( NO_ERROR != Error ) {
  815. WriteOutput( GetStdHandle( STD_OUTPUT_HANDLE), Args.UsageErr );
  816. WriteOutput( GetStdHandle( STD_OUTPUT_HANDLE), Args.Usage );
  817. DoneLogger();
  818. exit(1);
  819. }
  820. fVerbose = (Args.All == NULL);
  821. fDebug = (Args.Debug == NULL);
  822. fDisplay = FALSE;
  823. NetInfo = NULL;
  824. Error = GetNetworkInformation(
  825. &NetInfo, &InternalError );
  826. //
  827. // Calculate how much space it would take to display a full display..
  828. //
  829. do {
  830. Buffer = LocalAlloc( LPTR, sizeof(WCHAR)*BufSize );
  831. if( Buffer == NULL ) break;
  832. LocalError = FormatNetworkInfo(
  833. Buffer, BufSize, NetInfo,
  834. Error,InternalError,TRUE,fDebug);
  835. LocalFree(Buffer);
  836. BufSize *= 2;
  837. } while( NO_ERROR != LocalError );
  838. if( NULL != Buffer ) {
  839. Buffer = LocalAlloc( LPTR, sizeof(WCHAR)*BufSize );
  840. }
  841. if( NULL == Buffer ) {
  842. Buffer = (LPWSTR)TmpBuffer;
  843. BufSize = sizeof(TmpBuffer)/sizeof(WCHAR);
  844. Error = ERROR_NOT_ENOUGH_MEMORY;
  845. }
  846. DumpMessage(
  847. Buffer, BufSize, MSG_TITLE );
  848. if( NO_ERROR != Error || Args.All == NULL ) {
  849. fDisplay = TRUE;
  850. } else if( Args.Renew == NULL ) {
  851. //
  852. // Attempt to renew
  853. //
  854. Error = DoRenew( Buffer, BufSize, NetInfo, AdapterName);
  855. fDisplay = (NO_ERROR == Error);
  856. if( fDisplay ) {
  857. FreeNetworkInfo( NetInfo );
  858. Error = GetNetworkInformation(
  859. &NetInfo, &InternalError );
  860. }
  861. } else if( Args.Release == NULL ) {
  862. //
  863. // Attempt to renew
  864. //
  865. Error = DoRelease( Buffer, BufSize, NetInfo, AdapterName);
  866. fDisplay = (NO_ERROR == Error);
  867. if( fDisplay ) {
  868. FreeNetworkInfo( NetInfo );
  869. Error = GetNetworkInformation(
  870. &NetInfo, &InternalError );
  871. }
  872. } else if( Args.FlushDns == NULL ) {
  873. DoFlushDns( Buffer, BufSize, NetInfo );
  874. } else if( Args.Register == NULL ) {
  875. DoRegisterDns( Buffer, BufSize, NetInfo );
  876. } else if( Args.DisplayDns == NULL ) {
  877. DoDisplayDns( Buffer, BufSize, NetInfo );
  878. } else if( Args.ShowClassId == NULL ) {
  879. DoShowClassId( Buffer, BufSize, NetInfo, AdapterName );
  880. } else if( Args.SetClassId == NULL ) {
  881. DoSetClassId( Buffer, BufSize, NetInfo, AdapterName, ClassId );
  882. } else {
  883. fDisplay = TRUE;
  884. }
  885. if( fDisplay ) {
  886. FormatNetworkInfo(
  887. Buffer, BufSize, NetInfo,
  888. Error, InternalError, fVerbose, fDebug );
  889. }
  890. Error = WriteOutput( GetStdHandle( STD_OUTPUT_HANDLE), Buffer );
  891. if (Error != NO_ERROR)
  892. {
  893. Buffer[0] = L'\0';
  894. DumpMessage(Buffer, BufSize, MSG_TITLE );
  895. DumpErrorMessage(Buffer, BufSize, NoSpecificError, Error);
  896. WriteOutput( GetStdHandle( STD_OUTPUT_HANDLE ), Buffer );
  897. }
  898. FreeNetworkInfo(NetInfo);
  899. GlobalFree( Argv );
  900. LocalFree( Args.All );
  901. LocalFree( Args.Renew );
  902. LocalFree( Args.Release );
  903. LocalFree( Args.FlushDns );
  904. LocalFree( Args.Register );
  905. LocalFree( Args.DisplayDns );
  906. LocalFree( Args.ShowClassId );
  907. LocalFree( Args.SetClassId );
  908. LocalFree( Args.Debug );
  909. LocalFree( Args.Usage );
  910. DoneLogger();
  911. exit(0);
  912. }
  913. DWORD
  914. RegisterIPv6Dns(VOID)
  915. {
  916. DWORD dwErr = NO_ERROR;
  917. SC_HANDLE hcm = NULL;
  918. SC_HANDLE hSvc = NULL;
  919. SERVICE_STATUS status = {0};
  920. #define SERVICE_CONTROL_6TO4_REGISER_DNS 128
  921. do
  922. {
  923. hcm = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
  924. if (NULL == hcm)
  925. {
  926. dwErr = GetLastError();
  927. IPCFG_TRACE(IPCFG_TRACE_TCPIP, ("OpenSCManager returns 0x%lx (%d)\n", dwErr, dwErr));
  928. break;
  929. }
  930. hSvc = OpenService(hcm, L"6to4", SERVICE_USER_DEFINED_CONTROL);
  931. if (NULL == hSvc)
  932. {
  933. dwErr = GetLastError();
  934. IPCFG_TRACE(IPCFG_TRACE_TCPIP, ("OpenService returns 0x%lx (%d)\n", dwErr, dwErr));
  935. break;
  936. }
  937. if (!ControlService(hSvc, SERVICE_CONTROL_6TO4_REGISER_DNS, &status))
  938. {
  939. dwErr = GetLastError();
  940. IPCFG_TRACE(IPCFG_TRACE_TCPIP, ("ControlService returns 0x%lx (%d)\n", dwErr, dwErr));
  941. break;
  942. }
  943. } while (FALSE);
  944. if (hSvc)
  945. {
  946. CloseServiceHandle(hSvc);
  947. }
  948. if (hcm)
  949. {
  950. CloseServiceHandle(hcm);
  951. }
  952. IPCFG_TRACE(IPCFG_TRACE_TCPIP, ("RegisterIPv6Dns returns 0x%lx (%d)\n", dwErr, dwErr));
  953. return dwErr;
  954. }
  955. #ifdef __IPCFG_ENABLE_LOG__
  956. DWORD dwTraceFlag = 0xffffffffU;
  957. static FILE *hLogger = NULL;
  958. int
  959. InitLogger(const char *fname)
  960. {
  961. if (hLogger) {
  962. fclose(hLogger);
  963. }
  964. hLogger = fopen(fname, "w+");
  965. return (hLogger == NULL)? (-1): 0;
  966. }
  967. void
  968. DoneLogger(void)
  969. {
  970. if (hLogger) {
  971. fclose(hLogger);
  972. hLogger = NULL;
  973. }
  974. }
  975. int
  976. TraceFunc(const char* fmt, ...)
  977. {
  978. va_list ap;
  979. if (hLogger != NULL) {
  980. va_start(ap, fmt);
  981. vfprintf(hLogger, fmt, ap);
  982. va_end(ap);
  983. }
  984. return 0;
  985. }
  986. #else
  987. int InitLogger(const char *fname)
  988. {
  989. UNREFERENCED_PARAMETER(fname);
  990. return 0;
  991. }
  992. void DoneLogger(void) {}
  993. int TraceFunc(const char* fmt, ...)
  994. {
  995. UNREFERENCED_PARAMETER(fmt);
  996. return 0;
  997. }
  998. #endif