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.

1722 lines
33 KiB

  1. /*++
  2. Copyright (c) 2002-2002 Microsoft Corporation
  3. Module Name:
  4. netinfo.c
  5. Abstract:
  6. Domain Name System (DNS) API
  7. Public DNS network info routines.
  8. Author:
  9. Jim Gilroy (jamesg) April 2002
  10. Revision History:
  11. --*/
  12. #include "local.h"
  13. //
  14. // Private protos
  15. //
  16. PDNS_SEARCH_LIST
  17. DnsSearchList_CreateFromPrivate(
  18. IN PDNS_NETINFO pNetInfo,
  19. IN DNS_CHARSET CharSet
  20. );
  21. //
  22. // Character set for old DNS_NETWORK_INFORMATION
  23. //
  24. // DCR: netdiag should move to new routine and unicode
  25. //
  26. #define NICHARSET DnsCharSetUtf8
  27. //
  28. // Routines for the old public structures:
  29. // DNS_NETWORK_INFORMATION
  30. // DNS_SEARCH_INFORMATION
  31. // DNS_ADAPTER_INFORMATION
  32. //
  33. //
  34. // Adapter Information
  35. //
  36. VOID
  37. DnsAdapterInformation_Free(
  38. IN OUT PDNS_ADAPTER_INFORMATION pAdapter
  39. )
  40. /*++
  41. Routine Description:
  42. Free public adapter info struct.
  43. Arguments:
  44. pAdapter -- adapter info to free
  45. Return Value:
  46. None
  47. --*/
  48. {
  49. if ( pAdapter )
  50. {
  51. FREE_HEAP( pAdapter->pszAdapterGuidName );
  52. FREE_HEAP( pAdapter->pszDomain );
  53. FREE_HEAP( pAdapter->pIPAddresses );
  54. FREE_HEAP( pAdapter->pIPSubnetMasks );
  55. FREE_HEAP( pAdapter );
  56. }
  57. }
  58. PDNS_ADAPTER_INFORMATION
  59. DnsAdapterInformation_CreateFromPrivate(
  60. IN PDNS_ADAPTER pAdapter
  61. )
  62. /*++
  63. Routine Description:
  64. Create public DNS adapter info.
  65. Arguments:
  66. pAdapter -- private adapter info.
  67. Return Value:
  68. None.
  69. --*/
  70. {
  71. PDNS_ADAPTER_INFORMATION pnew = NULL;
  72. PDNS_ADDR_ARRAY pserverArray;
  73. DWORD iter;
  74. DWORD count = 0;
  75. PWSTR pnameIn;
  76. PSTR pname;
  77. DWORD serverCount;
  78. //
  79. // validate and unpack
  80. //
  81. if ( ! pAdapter )
  82. {
  83. return NULL;
  84. }
  85. pserverArray = pAdapter->pDnsAddrs;
  86. serverCount = 0;
  87. if ( pserverArray )
  88. {
  89. serverCount = pserverArray->AddrCount;
  90. }
  91. //
  92. // alloc
  93. //
  94. pnew = (PDNS_ADAPTER_INFORMATION) ALLOCATE_HEAP_ZERO(
  95. sizeof(DNS_ADAPTER_INFORMATION) -
  96. sizeof(DNS_SERVER_INFORMATION) +
  97. ( sizeof(DNS_SERVER_INFORMATION) * serverCount )
  98. );
  99. if ( !pnew )
  100. {
  101. return NULL;
  102. }
  103. //
  104. // copy flags and names
  105. //
  106. pnew->InfoFlags = pAdapter->InfoFlags;
  107. pnameIn = pAdapter->pszAdapterGuidName;
  108. if ( pnameIn )
  109. {
  110. pname = Dns_NameCopyAllocate(
  111. (PSTR) pnameIn,
  112. 0,
  113. DnsCharSetUnicode,
  114. NICHARSET );
  115. if ( !pname )
  116. {
  117. goto Failed;
  118. }
  119. pnew->pszAdapterGuidName = pname;
  120. }
  121. pnameIn = pAdapter->pszAdapterDomain;
  122. if ( pnameIn )
  123. {
  124. pname = Dns_NameCopyAllocate(
  125. (PSTR) pnameIn,
  126. 0,
  127. DnsCharSetUnicode,
  128. NICHARSET );
  129. if ( !pname )
  130. {
  131. goto Failed;
  132. }
  133. pnew->pszDomain = pname;
  134. }
  135. // address info
  136. pnew->pIPAddresses = DnsAddrArray_CreateIp4Array( pAdapter->pLocalAddrs );
  137. pnew->pIPSubnetMasks = NULL;
  138. //
  139. // server info
  140. //
  141. for ( iter=0; iter < serverCount; iter++ )
  142. {
  143. PDNS_ADDR pserver = &pserverArray->AddrArray[iter];
  144. if ( DnsAddr_IsIp4( pserver ) )
  145. {
  146. pnew->aipServers[iter].ipAddress = DnsAddr_GetIp4( pserver );
  147. pnew->aipServers[iter].Priority = pserver->Priority;
  148. count++;
  149. }
  150. }
  151. pnew->cServerCount = count;
  152. return pnew;
  153. Failed:
  154. DnsAdapterInformation_Free( pnew );
  155. return NULL;
  156. }
  157. //
  158. // Search List
  159. //
  160. VOID
  161. DnsSearchInformation_Free(
  162. IN PDNS_SEARCH_INFORMATION pSearchInfo
  163. )
  164. /*++
  165. Routine Description:
  166. Free public search list struct.
  167. Arguments:
  168. pSearchInfo -- search list to free
  169. Return Value:
  170. None
  171. --*/
  172. {
  173. DWORD iter;
  174. if ( pSearchInfo )
  175. {
  176. FREE_HEAP( pSearchInfo->pszPrimaryDomainName );
  177. for ( iter=0; iter < pSearchInfo->cNameCount; iter++ )
  178. {
  179. FREE_HEAP( pSearchInfo->aSearchListNames[iter] );
  180. }
  181. FREE_HEAP( pSearchInfo );
  182. }
  183. }
  184. #if 0
  185. PDNS_SEARCH_INFORMATION
  186. DnsSearchInformation_CreateFromPrivate(
  187. IN PSEARCH_LIST pSearchList
  188. )
  189. /*++
  190. Routine Description:
  191. Create public search list from private.
  192. Arguments:
  193. pSearchList -- private search list
  194. Return Value:
  195. Ptr to new search list, if successful.
  196. NULL on error.
  197. --*/
  198. {
  199. PDNS_SEARCH_INFORMATION pnew;
  200. DWORD iter;
  201. DWORD nameCount;
  202. PWSTR pname;
  203. PSTR pnewName;
  204. if ( !pSearchList )
  205. {
  206. return NULL;
  207. }
  208. nameCount = pSearchList->NameCount;
  209. //
  210. // alloc
  211. //
  212. pnew = (PDNS_SEARCH_INFORMATION) ALLOCATE_HEAP_ZERO(
  213. sizeof( DNS_SEARCH_INFORMATION ) -
  214. sizeof(PSTR) +
  215. ( sizeof(PSTR) * nameCount ) );
  216. if ( !pnew )
  217. {
  218. return NULL;
  219. }
  220. //
  221. // copy name
  222. //
  223. pname = pSearchList->pszDomainOrZoneName;
  224. if ( pname )
  225. {
  226. pnewName = Dns_NameCopyAllocate(
  227. (PSTR) pname,
  228. 0,
  229. DnsCharSetUnicode,
  230. NICHARSET );
  231. if ( !pnewName )
  232. {
  233. goto Failed;
  234. }
  235. pnew->pszPrimaryDomainName = pnewName;
  236. }
  237. //
  238. // copy search names
  239. //
  240. for ( iter=0; iter < nameCount; iter++ )
  241. {
  242. pname = pSearchList->SearchNameArray[iter].pszName;
  243. if ( pname )
  244. {
  245. pnewName = Dns_NameCopyAllocate(
  246. (PSTR) pname,
  247. 0,
  248. DnsCharSetUnicode,
  249. NICHARSET );
  250. if ( !pnewName )
  251. {
  252. goto Failed;
  253. }
  254. pnew->aSearchListNames[iter] = pnewName;
  255. pnew->cNameCount++;
  256. }
  257. }
  258. return pnew;
  259. Failed:
  260. DnsSearchInformation_Free( pnew );
  261. return NULL;
  262. }
  263. #endif
  264. PDNS_SEARCH_INFORMATION
  265. DnsSearchInformation_CreateFromPrivate(
  266. IN PDNS_NETINFO pNetInfo
  267. )
  268. /*++
  269. Routine Description:
  270. Create public search list from private.
  271. Arguments:
  272. pNetInfo -- private netinfo
  273. Return Value:
  274. Ptr to new search list, if successful.
  275. NULL on error.
  276. --*/
  277. {
  278. //
  279. // call new function -- specifying ANSI char set
  280. //
  281. // DCR: note this assumes mapping with DNS_SEARCH_LIST
  282. // note UTF8 -- so this only relevant to netdiag and ipconfig
  283. //
  284. return (PDNS_SEARCH_INFORMATION)
  285. DnsSearchList_CreateFromPrivate(
  286. pNetInfo,
  287. NICHARSET
  288. );
  289. }
  290. PDNS_SEARCH_INFORMATION
  291. DnsSearchInformation_Get(
  292. VOID
  293. )
  294. /*++
  295. Routine Description:
  296. Get search list info.
  297. Arguments:
  298. None
  299. Return Value:
  300. Ptr to search list.
  301. NULL on error.
  302. --*/
  303. {
  304. PDNS_NETINFO pnetInfo = GetNetworkInfo();
  305. PDNS_SEARCH_INFORMATION pnew;
  306. DNSDBG( TRACE, ( "DnsSearchInformation_Get()\n" ));
  307. if ( !pnetInfo )
  308. {
  309. return NULL;
  310. }
  311. pnew = DnsSearchInformation_CreateFromPrivate( pnetInfo );
  312. NetInfo_Free( pnetInfo );
  313. return pnew;
  314. }
  315. //
  316. // Network Information
  317. //
  318. VOID
  319. DnsNetworkInformation_Free(
  320. IN OUT PDNS_NETWORK_INFORMATION pNetInfo
  321. )
  322. /*++
  323. Routine Description:
  324. Free network info blob.
  325. Arguments:
  326. pNetInfo -- blob to free
  327. Return Value:
  328. None
  329. --*/
  330. {
  331. DWORD iter;
  332. DNSDBG( TRACE, ( "DnsNetworkInformation_Free()\n" ));
  333. if ( pNetInfo )
  334. {
  335. DnsSearchInformation_Free( pNetInfo->pSearchInformation );
  336. for ( iter = 0; iter < pNetInfo->cAdapterCount; iter++ )
  337. {
  338. DnsAdapterInformation_Free( pNetInfo->aAdapterInfoList[iter] );
  339. }
  340. FREE_HEAP( pNetInfo );
  341. }
  342. }
  343. PDNS_NETWORK_INFORMATION
  344. DnsNetworkInformation_CreateFromPrivate(
  345. IN PDNS_NETINFO pNetInfo,
  346. IN BOOL fSearchList
  347. )
  348. /*++
  349. Routine Description:
  350. Create public DNS_NETWORK_INFORMATION from private DNS_NETINFO.
  351. Arguments:
  352. pNetInfo -- private blob
  353. fSearchList -- TRUE to force search list; FALSE otherwise
  354. Return Value:
  355. Ptr to new network info, if successful.
  356. Null on error -- allocation failure.
  357. --*/
  358. {
  359. PDNS_NETWORK_INFORMATION pnew = NULL;
  360. PSEARCH_LIST psearchList;
  361. DWORD iter;
  362. DNSDBG( TRACE, ( "DnsNetworkInformation_CreateFromPrivate()\n" ));
  363. if ( !pNetInfo )
  364. {
  365. return NULL;
  366. }
  367. //
  368. // alloc
  369. //
  370. pnew = (PDNS_NETWORK_INFORMATION)
  371. ALLOCATE_HEAP_ZERO(
  372. sizeof( DNS_NETWORK_INFORMATION) -
  373. sizeof( PDNS_ADAPTER_INFORMATION) +
  374. ( sizeof(PDNS_ADAPTER_INFORMATION) * pNetInfo->AdapterCount )
  375. );
  376. if ( !pnew )
  377. {
  378. goto Failed;
  379. }
  380. //
  381. // no search list if neither name or count
  382. //
  383. if ( fSearchList )
  384. {
  385. PDNS_SEARCH_INFORMATION psearch;
  386. psearch = DnsSearchInformation_CreateFromPrivate( pNetInfo );
  387. if ( !psearch )
  388. {
  389. goto Failed;
  390. }
  391. pnew->pSearchInformation = psearch;
  392. }
  393. //
  394. // copy adapter blobs
  395. //
  396. for ( iter = 0; iter < pNetInfo->AdapterCount; iter++ )
  397. {
  398. PDNS_ADAPTER_INFORMATION padapter;
  399. padapter = DnsAdapterInformation_CreateFromPrivate(
  400. & pNetInfo->AdapterArray[iter] );
  401. if ( !padapter )
  402. {
  403. goto Failed;
  404. }
  405. pnew->aAdapterInfoList[iter] = padapter;
  406. pnew->cAdapterCount++;
  407. }
  408. return pnew;
  409. Failed:
  410. DnsNetworkInformation_Free( pnew );
  411. return NULL;
  412. }
  413. PDNS_NETWORK_INFORMATION
  414. DnsNetworkInformation_Get(
  415. VOID
  416. )
  417. /*++
  418. Routine Description:
  419. Get DNS network info.
  420. Arguments:
  421. None.
  422. Return Value:
  423. Ptr to DNS network info, if successful.
  424. NULL on error.
  425. --*/
  426. {
  427. PDNS_NETWORK_INFORMATION pnew = NULL;
  428. PDNS_NETINFO pnetInfo;
  429. DNSDBG( TRACE, ( "DnsNetworkInformation_Get()\n" ));
  430. // grab current network info
  431. pnetInfo = GetNetworkInfo();
  432. if ( !pnetInfo )
  433. {
  434. return NULL;
  435. }
  436. // copy to public structure
  437. pnew = DnsNetworkInformation_CreateFromPrivate(
  438. pnetInfo,
  439. TRUE // include search list
  440. );
  441. NetInfo_Free( pnetInfo );
  442. return pnew;
  443. }
  444. //
  445. // Netdiag public network info routines
  446. //
  447. DNS_STATUS
  448. DnsNetworkInformation_CreateFromFAZ(
  449. IN PCSTR pszName,
  450. IN DWORD dwFlags,
  451. IN PIP4_ARRAY pIp4Servers,
  452. OUT PDNS_NETWORK_INFORMATION * ppNetworkInformation
  453. )
  454. /*++
  455. Routine Description:
  456. Get network info blob result from FAZ
  457. EXPORTED function. (Used in netdiag.exe)
  458. Arguments:
  459. Return Value:
  460. --*/
  461. {
  462. PDNS_NETWORK_INFORMATION pnew = NULL;
  463. PDNS_ADDR_ARRAY parray = NULL;
  464. PDNS_NETINFO pnetInfo = NULL;
  465. PWSTR pname = NULL;
  466. DNS_STATUS status;
  467. DNSDBG( TRACE, (
  468. "DnsNetworkInformation_CreateFromFAZ()\n"
  469. "\tpszName = %s\n"
  470. "\tFlags = %08x\n"
  471. "\tpIp4Servers = %p\n"
  472. "\tppResults = %p\n",
  473. pszName,
  474. dwFlags,
  475. pIp4Servers,
  476. ppNetworkInformation
  477. ));
  478. // convert to DNS_ADDR_ARRAY
  479. if ( pIp4Servers )
  480. {
  481. parray = DnsAddrArray_CreateFromIp4Array( pIp4Servers );
  482. if ( !parray )
  483. {
  484. status = DNS_ERROR_NO_MEMORY;
  485. goto Done;
  486. }
  487. }
  488. // convert name to unicode
  489. // DCR: remove when netdiag unicode
  490. pname = Dns_StringCopyAllocate(
  491. (PCHAR) pszName,
  492. 0, // null terminated
  493. NICHARSET,
  494. DnsCharSetUnicode
  495. );
  496. // FAZ
  497. status = Faz_Private(
  498. (PWSTR) pname,
  499. dwFlags,
  500. parray,
  501. & pnetInfo );
  502. if ( status != ERROR_SUCCESS )
  503. {
  504. goto Done;
  505. }
  506. // convert FAZ results to DNS_NETWORK_INFORMATION
  507. pnew = DnsNetworkInformation_CreateFromPrivate(
  508. pnetInfo,
  509. TRUE // include search list
  510. );
  511. if ( !pnew )
  512. {
  513. status = DNS_ERROR_NO_MEMORY;
  514. }
  515. else if ( !pnew->pSearchInformation ||
  516. !pnew->pSearchInformation->pszPrimaryDomainName ||
  517. pnew->cAdapterCount != 1 ||
  518. !pnew->aAdapterInfoList[0] )
  519. {
  520. DNS_ASSERT( FALSE );
  521. DnsNetworkInformation_Free( pnew );
  522. pnew = NULL;
  523. status = DNS_ERROR_NO_MEMORY;
  524. }
  525. Done:
  526. *ppNetworkInformation = pnew;
  527. NetInfo_Free( pnetInfo );
  528. DnsAddrArray_Free( parray );
  529. Dns_Free( pname );
  530. DNSDBG( TRACE, (
  531. "Leave DnsNetworkInformation_CreateFromFAZ()\n"
  532. "\tstatus = %d\n"
  533. "\tpNetInfo = %p\n",
  534. status,
  535. pnew ));
  536. return status;
  537. }
  538. //
  539. // Routines for the new public structures:
  540. // DNS_SEARCH_LIST
  541. // DNS_NETWORK_INFO
  542. // DNS_ADAPTER_INFO
  543. //
  544. //
  545. // Adapter Info
  546. //
  547. VOID
  548. DnsAdapterInfo_Free(
  549. IN OUT PDNS_ADAPTER_INFO pAdapter,
  550. IN BOOL fFreeAdapter
  551. )
  552. /*++
  553. Routine Description:
  554. Free public adapter info struct.
  555. Arguments:
  556. pAdapter -- adapter info to free
  557. Return Value:
  558. None
  559. --*/
  560. {
  561. if ( pAdapter )
  562. {
  563. FREE_HEAP( pAdapter->pszAdapterGuidName );
  564. FREE_HEAP( pAdapter->pszAdapterDomain );
  565. DnsAddrArray_Free( pAdapter->pIpAddrs );
  566. DnsAddrArray_Free( pAdapter->pDnsAddrs );
  567. if ( fFreeAdapter )
  568. {
  569. FREE_HEAP( pAdapter );
  570. }
  571. else
  572. {
  573. RtlZeroMemory( pAdapter, sizeof(*pAdapter) );
  574. }
  575. }
  576. }
  577. BOOL
  578. DnsAdapterInfo_CopyFromPrivate(
  579. IN PDNS_ADAPTER_INFO pCopy,
  580. IN PDNS_ADAPTER pAdapter,
  581. IN DNS_CHARSET CharSet
  582. )
  583. /*++
  584. Routine Description:
  585. Create public DNS adapter info.
  586. Arguments:
  587. pAdapter -- private adapter info.
  588. CharSet -- desired char set
  589. Return Value:
  590. None.
  591. --*/
  592. {
  593. DWORD iter;
  594. DWORD count = 0;
  595. PWSTR pnameIn;
  596. PWSTR pname;
  597. DWORD serverCount;
  598. PDNS_ADDR_ARRAY parray;
  599. //
  600. // validate and clear
  601. //
  602. if ( !pAdapter || !pCopy )
  603. {
  604. return FALSE;
  605. }
  606. RtlZeroMemory(
  607. pCopy,
  608. sizeof( *pCopy ) );
  609. //
  610. // copy flags and names
  611. //
  612. pCopy->Flags = pAdapter->InfoFlags;
  613. pnameIn = pAdapter->pszAdapterGuidName;
  614. if ( pnameIn )
  615. {
  616. pname = (PWSTR) Dns_NameCopyAllocate(
  617. (PSTR) pnameIn,
  618. 0,
  619. DnsCharSetUnicode,
  620. CharSet );
  621. if ( !pname )
  622. {
  623. goto Failed;
  624. }
  625. pCopy->pszAdapterGuidName = pname;
  626. }
  627. pnameIn = pAdapter->pszAdapterDomain;
  628. if ( pnameIn )
  629. {
  630. pname = (PWSTR) Dns_NameCopyAllocate(
  631. (PSTR) pnameIn,
  632. 0,
  633. DnsCharSetUnicode,
  634. CharSet );
  635. if ( !pname )
  636. {
  637. goto Failed;
  638. }
  639. pCopy->pszAdapterDomain = pname;
  640. }
  641. //
  642. // address info
  643. //
  644. parray = DnsAddrArray_CreateCopy( pAdapter->pLocalAddrs );
  645. if ( !parray && pAdapter->pLocalAddrs )
  646. {
  647. goto Failed;
  648. }
  649. pCopy->pIpAddrs = parray;
  650. //
  651. // server info
  652. //
  653. parray = DnsAddrArray_CreateCopy( pAdapter->pDnsAddrs );
  654. if ( !parray && pAdapter->pDnsAddrs )
  655. {
  656. goto Failed;
  657. }
  658. pCopy->pDnsAddrs = parray;
  659. return TRUE;
  660. Failed:
  661. DnsAdapterInfo_Free(
  662. pCopy,
  663. FALSE // don't free struct
  664. );
  665. return FALSE;
  666. }
  667. PDNS_ADAPTER_INFO
  668. DnsAdapterInfo_CreateFromPrivate(
  669. IN PDNS_ADAPTER pAdapter,
  670. IN DNS_CHARSET CharSet
  671. )
  672. /*++
  673. Routine Description:
  674. Create public DNS adapter info.
  675. Arguments:
  676. pAdapter -- private adapter info.
  677. CharSet -- desired char set
  678. Return Value:
  679. None.
  680. --*/
  681. {
  682. PDNS_ADAPTER_INFO pnew = NULL;
  683. //
  684. // validate and unpack
  685. //
  686. if ( ! pAdapter )
  687. {
  688. return NULL;
  689. }
  690. //
  691. // alloc
  692. //
  693. pnew = (PDNS_ADAPTER_INFO) ALLOCATE_HEAP_ZERO( sizeof(DNS_ADAPTER_INFO) );
  694. if ( !pnew )
  695. {
  696. return NULL;
  697. }
  698. //
  699. // copy adapter info
  700. //
  701. if ( !DnsAdapterInfo_CopyFromPrivate(
  702. pnew,
  703. pAdapter,
  704. CharSet ) )
  705. {
  706. goto Failed;
  707. }
  708. return pnew;
  709. Failed:
  710. DnsAdapterInfo_Free( pnew, TRUE );
  711. return NULL;
  712. }
  713. //
  714. // Search List
  715. //
  716. VOID
  717. DnsSearchList_Free(
  718. IN PDNS_SEARCH_LIST pSearchList
  719. )
  720. /*++
  721. Routine Description:
  722. Free public search list struct.
  723. Arguments:
  724. pSearchList -- search list to free
  725. Return Value:
  726. None
  727. --*/
  728. {
  729. DWORD iter;
  730. if ( pSearchList )
  731. {
  732. FREE_HEAP( pSearchList->pszPrimaryDomainName );
  733. for ( iter=0; iter < pSearchList->NameCount; iter++ )
  734. {
  735. FREE_HEAP( pSearchList->SearchNameArray[iter] );
  736. }
  737. FREE_HEAP( pSearchList );
  738. }
  739. }
  740. BOOL
  741. dnsSearchList_AddName(
  742. IN OUT PDNS_SEARCH_LIST pSearchList,
  743. IN DWORD MaxCount,
  744. IN PWSTR pName,
  745. IN DNS_CHARSET CharSet,
  746. IN BOOL fDupCheck
  747. )
  748. /*++
  749. Routine Description:
  750. Add name to search list.
  751. Private util for building search list.
  752. Arguments:
  753. pSearchList -- new search list
  754. MaxCount -- OPTIONAL count of max entries in list;
  755. if zero assume adequate space
  756. pName -- name to add
  757. CharSet -- desired char set
  758. fDupCheck -- check if duplicate
  759. Return Value:
  760. TRUE if successful or space constraint.
  761. FALSE only on allocation failure.
  762. NULL on error.
  763. --*/
  764. {
  765. PWSTR pnewName;
  766. DWORD nameCount;
  767. //
  768. // validity test
  769. //
  770. // note, failing ONLY on memory allocation failure
  771. // as that's the ONLY failure that results in failed build
  772. //
  773. nameCount = pSearchList->NameCount;
  774. if ( !pName ||
  775. ( MaxCount!=0 && MaxCount<=nameCount ) )
  776. {
  777. return TRUE;
  778. }
  779. //
  780. // copy into desired char set
  781. // - then place in search list
  782. //
  783. pnewName = Dns_NameCopyAllocate(
  784. (PSTR) pName,
  785. 0,
  786. DnsCharSetUnicode,
  787. CharSet );
  788. if ( !pnewName )
  789. {
  790. return FALSE;
  791. }
  792. //
  793. // duplicate check
  794. //
  795. if ( fDupCheck )
  796. {
  797. DWORD iter;
  798. for ( iter=0; iter < nameCount; iter++ )
  799. {
  800. if ( Dns_NameComparePrivate(
  801. (PCSTR) pnewName,
  802. (PCSTR) pSearchList->SearchNameArray[iter],
  803. CharSet ) )
  804. {
  805. FREE_HEAP( pnewName );
  806. return TRUE;
  807. }
  808. }
  809. }
  810. //
  811. // put new name in list
  812. //
  813. pSearchList->SearchNameArray[nameCount] = pnewName;
  814. pSearchList->NameCount = ++nameCount;
  815. return TRUE;
  816. }
  817. PDNS_SEARCH_LIST
  818. DnsSearchList_CreateFromPrivate(
  819. IN PDNS_NETINFO pNetInfo,
  820. IN DNS_CHARSET CharSet
  821. )
  822. /*++
  823. Routine Description:
  824. Create public search list from private.
  825. Arguments:
  826. pSearchList -- private search list
  827. CharSet -- desired char set
  828. Return Value:
  829. Ptr to new search list, if successful.
  830. NULL on error.
  831. --*/
  832. {
  833. PDNS_SEARCH_LIST pnew = NULL;
  834. DWORD iter;
  835. DWORD nameCount;
  836. PWSTR pname;
  837. PWSTR pdn = pNetInfo->pszDomainName;
  838. PSEARCH_LIST psearch = NULL;
  839. DNSDBG( TRACE, (
  840. "DnsSearchList_CreateFromPrivate( %p, %d )\n",
  841. pNetInfo,
  842. CharSet ));
  843. //
  844. // count names
  845. // - real search list -- done
  846. // - dummy list -- must add in adapter names
  847. //
  848. nameCount = MAX_SEARCH_LIST_ENTRIES;
  849. if ( !(pNetInfo->InfoFlags & NINFO_FLAG_DUMMY_SEARCH_LIST) &&
  850. (psearch = pNetInfo->pSearchList) )
  851. {
  852. nameCount = psearch->NameCount;
  853. }
  854. //
  855. // alloc
  856. //
  857. pnew = (PDNS_SEARCH_LIST) ALLOCATE_HEAP_ZERO(
  858. sizeof( DNS_SEARCH_LIST ) -
  859. sizeof(PSTR) +
  860. ( sizeof(PSTR) * nameCount ) );
  861. if ( !pnew )
  862. {
  863. return NULL;
  864. }
  865. //
  866. // copy existing search list
  867. //
  868. if ( psearch )
  869. {
  870. #if 0
  871. // primary\zone name
  872. // note: this is used only for update netinfo
  873. // only current public customer is netdiag.exe
  874. pname = psearch->pszDomainName;
  875. if ( pname )
  876. {
  877. pnewName = Dns_NameCopyAllocate(
  878. (PSTR) pName,
  879. 0,
  880. DnsCharSetUnicode,
  881. CharSet );
  882. if ( !pnewName )
  883. {
  884. goto Failed;
  885. }
  886. pnew->pszPrimaryDomainName = pnewName;
  887. }
  888. #endif
  889. for ( iter=0; iter < nameCount; iter++ )
  890. {
  891. if ( !dnsSearchList_AddName(
  892. pnew,
  893. 0, // adequate space
  894. psearch->SearchNameArray[iter].pszName,
  895. CharSet,
  896. FALSE // no duplicate check
  897. ) )
  898. {
  899. goto Failed;
  900. }
  901. }
  902. }
  903. //
  904. // otherwise build search list
  905. //
  906. else
  907. {
  908. PDNS_ADAPTER padapter;
  909. //
  910. // use PDN in first search list slot
  911. //
  912. if ( pdn )
  913. {
  914. if ( !dnsSearchList_AddName(
  915. pnew,
  916. 0, // adequate space
  917. pdn,
  918. CharSet,
  919. FALSE // no duplicate check
  920. ) )
  921. {
  922. goto Failed;
  923. }
  924. }
  925. //
  926. // add adapter domain names
  927. //
  928. // note: currently presence of adapter name signals it's
  929. // use in queries
  930. //
  931. NetInfo_AdapterLoopStart( pNetInfo );
  932. while ( padapter = NetInfo_GetNextAdapter( pNetInfo ) )
  933. {
  934. pname = padapter->pszAdapterDomain;
  935. if ( pname )
  936. {
  937. if ( !dnsSearchList_AddName(
  938. pnew,
  939. nameCount,
  940. pname,
  941. CharSet,
  942. TRUE // duplicate check
  943. ) )
  944. {
  945. goto Failed;
  946. }
  947. }
  948. }
  949. //
  950. // add devolved primary name
  951. // - must have following label
  952. // do NOT include TLDs in search list
  953. //
  954. if ( pdn && g_UseNameDevolution )
  955. {
  956. PWSTR pnext;
  957. pname = Dns_GetDomainNameW( pdn );
  958. while ( pname &&
  959. (pnext = Dns_GetDomainNameW(pname)) )
  960. {
  961. if ( !dnsSearchList_AddName(
  962. pnew,
  963. nameCount,
  964. pname,
  965. CharSet,
  966. FALSE // no duplicate check
  967. ) )
  968. {
  969. goto Failed;
  970. }
  971. pname = pnext;
  972. }
  973. }
  974. }
  975. //
  976. // copy PDN
  977. //
  978. // currently required
  979. // - netdiag references it (as zone for update check)
  980. // - ipconfig may use it, not sure
  981. //
  982. if ( pdn )
  983. {
  984. pname = Dns_NameCopyAllocate(
  985. (PSTR) pdn,
  986. 0,
  987. DnsCharSetUnicode,
  988. CharSet );
  989. if ( !pname )
  990. {
  991. goto Failed;
  992. }
  993. pnew->pszPrimaryDomainName = pname;
  994. }
  995. return pnew;
  996. Failed:
  997. DnsSearchList_Free( pnew );
  998. return NULL;
  999. }
  1000. PDNS_SEARCH_LIST
  1001. DnsSearchList_Get(
  1002. IN DNS_CHARSET CharSet
  1003. )
  1004. /*++
  1005. Routine Description:
  1006. Get search list info.
  1007. Arguments:
  1008. CharSet -- desired char set
  1009. Return Value:
  1010. Ptr to search list.
  1011. NULL on error.
  1012. --*/
  1013. {
  1014. PDNS_NETINFO pnetInfo = GetNetworkInfo();
  1015. PDNS_SEARCH_LIST pnew;
  1016. if ( !pnetInfo )
  1017. {
  1018. return NULL;
  1019. }
  1020. pnew = DnsSearchList_CreateFromPrivate(
  1021. pnetInfo,
  1022. CharSet );
  1023. NetInfo_Free( pnetInfo );
  1024. return pnew;
  1025. }
  1026. //
  1027. // Network Info
  1028. //
  1029. VOID
  1030. DnsNetworkInfo_Free(
  1031. IN OUT PDNS_NETWORK_INFO pNetInfo
  1032. )
  1033. /*++
  1034. Routine Description:
  1035. Free network info blob.
  1036. Arguments:
  1037. pNetInfo -- blob to free
  1038. Return Value:
  1039. None
  1040. --*/
  1041. {
  1042. DWORD iter;
  1043. if ( pNetInfo )
  1044. {
  1045. DnsSearchList_Free( pNetInfo->pSearchList );
  1046. FREE_HEAP( pNetInfo->pszPrimaryDomainName );
  1047. FREE_HEAP( pNetInfo->pszHostName );
  1048. for ( iter = 0; iter < pNetInfo->AdapterCount; iter++ )
  1049. {
  1050. DnsAdapterInfo_Free(
  1051. & pNetInfo->AdapterArray[iter],
  1052. FALSE // don't free structure
  1053. );
  1054. }
  1055. FREE_HEAP( pNetInfo );
  1056. }
  1057. }
  1058. PDNS_NETWORK_INFO
  1059. DnsNetworkInfo_CreateFromPrivate(
  1060. IN PDNS_NETINFO pNetInfo,
  1061. IN DNS_CHARSET CharSet,
  1062. IN BOOL fSearchList
  1063. )
  1064. /*++
  1065. Routine Description:
  1066. Create public DNS_NETWORK_INFO from private DNS_NETINFO.
  1067. Arguments:
  1068. pNetInfo -- private blob
  1069. CharSet -- char set of results
  1070. fSearchList -- TRUE to include search list; FALSE otherwise
  1071. Return Value:
  1072. Ptr to new network info, if successful.
  1073. Null on error -- allocation failure.
  1074. --*/
  1075. {
  1076. PDNS_NETWORK_INFO pnew = NULL;
  1077. PSEARCH_LIST psearchList;
  1078. DWORD iter;
  1079. PSTR pnewName;
  1080. PWSTR pname;
  1081. if ( !pNetInfo )
  1082. {
  1083. return NULL;
  1084. }
  1085. //
  1086. // alloc
  1087. //
  1088. pnew = (PDNS_NETWORK_INFO)
  1089. ALLOCATE_HEAP_ZERO(
  1090. sizeof( DNS_NETWORK_INFO ) -
  1091. sizeof( DNS_ADAPTER_INFO ) +
  1092. ( sizeof(DNS_ADAPTER_INFO) * pNetInfo->AdapterCount )
  1093. );
  1094. if ( !pnew )
  1095. {
  1096. goto Failed;
  1097. }
  1098. //
  1099. // hostname and PDN
  1100. //
  1101. pname = pNetInfo->pszHostName;
  1102. if ( pname )
  1103. {
  1104. pnewName = Dns_NameCopyAllocate(
  1105. (PSTR) pname,
  1106. 0,
  1107. DnsCharSetUnicode,
  1108. CharSet );
  1109. if ( !pnewName )
  1110. {
  1111. goto Failed;
  1112. }
  1113. pnew->pszHostName = (PWSTR) pnewName;
  1114. }
  1115. pname = pNetInfo->pszDomainName;
  1116. if ( pname )
  1117. {
  1118. pnewName = Dns_NameCopyAllocate(
  1119. (PSTR) pname,
  1120. 0,
  1121. DnsCharSetUnicode,
  1122. CharSet );
  1123. if ( !pnewName )
  1124. {
  1125. goto Failed;
  1126. }
  1127. pnew->pszPrimaryDomainName = (PWSTR) pnewName;
  1128. }
  1129. //
  1130. // search list
  1131. //
  1132. if ( fSearchList )
  1133. {
  1134. PDNS_SEARCH_LIST psearch;
  1135. psearch = DnsSearchList_CreateFromPrivate(
  1136. pNetInfo,
  1137. CharSet );
  1138. if ( !psearch )
  1139. {
  1140. goto Failed;
  1141. }
  1142. pnew->pSearchList = psearch;
  1143. }
  1144. //
  1145. // copy adapter blobs
  1146. //
  1147. for ( iter = 0; iter < pNetInfo->AdapterCount; iter++ )
  1148. {
  1149. if ( ! DnsAdapterInfo_CopyFromPrivate(
  1150. & pnew->AdapterArray[iter],
  1151. & pNetInfo->AdapterArray[iter],
  1152. CharSet ) )
  1153. {
  1154. goto Failed;
  1155. }
  1156. pnew->AdapterCount++;
  1157. }
  1158. return pnew;
  1159. Failed:
  1160. DnsNetworkInfo_Free( pnew );
  1161. return NULL;
  1162. }
  1163. PDNS_NETWORK_INFO
  1164. DnsNetworkInfo_Get(
  1165. IN DNS_CHARSET CharSet
  1166. )
  1167. /*++
  1168. Routine Description:
  1169. Get DNS network info.
  1170. Arguments:
  1171. None.
  1172. Return Value:
  1173. Ptr to DNS network info, if successful.
  1174. NULL on error.
  1175. --*/
  1176. {
  1177. PDNS_NETWORK_INFO pnew = NULL;
  1178. PDNS_NETINFO pnetInfo;
  1179. // grab current network info
  1180. pnetInfo = GetNetworkInfo();
  1181. if ( !pnetInfo )
  1182. {
  1183. return NULL;
  1184. }
  1185. // copy to public structure
  1186. pnew = DnsNetworkInfo_CreateFromPrivate(
  1187. pnetInfo,
  1188. CharSet,
  1189. TRUE // include search list
  1190. );
  1191. NetInfo_Free( pnetInfo );
  1192. return pnew;
  1193. }
  1194. //
  1195. // Netdiag public network info routines
  1196. //
  1197. #if 1
  1198. //
  1199. // This routine can be brought in when netdiag can be brought
  1200. // onto new structures.
  1201. // Currently netdiag uses the old structure DNS_NETWORK_INFORMATION
  1202. // and uses the routine above.
  1203. //
  1204. DNS_STATUS
  1205. DnsNetworkInfo_CreateFromFAZ(
  1206. //IN PCWSTR pszName,
  1207. IN PCSTR pszName,
  1208. IN DWORD dwFlags,
  1209. IN PIP4_ARRAY pIp4Servers,
  1210. IN DNS_CHARSET CharSet,
  1211. OUT PDNS_NETWORK_INFOA * ppNetworkInfo
  1212. )
  1213. /*++
  1214. Routine Description:
  1215. Get network info blob result from FAZ
  1216. EXPORTED function. (Used in netdiag.exe)
  1217. Arguments:
  1218. Return Value:
  1219. --*/
  1220. {
  1221. DNS_STATUS status;
  1222. PDNS_ADDR_ARRAY parray = NULL;
  1223. PDNS_NETINFO pnetInfo = NULL;
  1224. PDNS_NETWORK_INFO pnew = NULL;
  1225. PWSTR pname = NULL;
  1226. PWSTR pnameAlloc = NULL;
  1227. DNSDBG( TRACE, (
  1228. "DnsNetworkInfo_CreateFromFAZ( %s )\n", pszName ));
  1229. // convert to DNS_ADDR_ARRAY
  1230. if ( pIp4Servers )
  1231. {
  1232. parray = DnsAddrArray_CreateFromIp4Array( pIp4Servers );
  1233. if ( !parray )
  1234. {
  1235. status = DNS_ERROR_NO_MEMORY;
  1236. goto Done;
  1237. }
  1238. }
  1239. // convert name to unicode
  1240. // DCR: remove when netdiag unicode
  1241. pname = (PWSTR) pszName;
  1242. if ( CharSet != DnsCharSetUnicode )
  1243. {
  1244. pname = Dns_StringCopyAllocate(
  1245. (PCHAR) pszName,
  1246. 0, // null terminated
  1247. CharSet,
  1248. DnsCharSetUnicode
  1249. );
  1250. pnameAlloc = pname;
  1251. }
  1252. // FAZ
  1253. status = Faz_Private(
  1254. (PWSTR) pname,
  1255. dwFlags,
  1256. parray,
  1257. & pnetInfo );
  1258. if ( status != ERROR_SUCCESS )
  1259. {
  1260. goto Done;
  1261. }
  1262. // convert FAZ results to DNS_NETWORK_INFO
  1263. pnew = DnsNetworkInfo_CreateFromPrivate(
  1264. pnetInfo,
  1265. CharSet,
  1266. FALSE // no search list built
  1267. );
  1268. if ( !pnew )
  1269. {
  1270. status = DNS_ERROR_NO_MEMORY;
  1271. }
  1272. else if ( !pnew->pszPrimaryDomainName ||
  1273. pnew->AdapterCount != 1 ||
  1274. !pnew->AdapterArray[0].pszAdapterDomain )
  1275. {
  1276. DNS_ASSERT( FALSE );
  1277. DnsNetworkInfo_Free( pnew );
  1278. pnew = NULL;
  1279. status = DNS_ERROR_NO_MEMORY;
  1280. }
  1281. Done:
  1282. // DCR: remove cast once netdiag is in unicode
  1283. *ppNetworkInfo = (PDNS_NETWORK_INFOA) pnew;
  1284. NetInfo_Free( pnetInfo );
  1285. DnsAddrArray_Free( parray );
  1286. Dns_Free( pnameAlloc );
  1287. return status;
  1288. }
  1289. #endif
  1290. //
  1291. // End netpub.c
  1292. //