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.

1466 lines
32 KiB

  1. /*++
  2. Copyright (c) 1999-2002 Microsoft Corporation
  3. Module Name:
  4. config.c
  5. Abstract:
  6. Domain Name System (DNS) API
  7. Configuration routines.
  8. Author:
  9. Jim Gilroy (jamesg) September 1999
  10. Revision History:
  11. --*/
  12. #include "local.h"
  13. //
  14. // Config mapping table.
  15. //
  16. // Maps config IDs into corresponding registry lookups.
  17. //
  18. typedef struct _ConfigMapping
  19. {
  20. DWORD ConfigId;
  21. DWORD RegId;
  22. BOOLEAN fAdapterAllowed;
  23. BOOLEAN fAdapterRequired;
  24. BYTE CharSet;
  25. //BYTE Reserved;
  26. }
  27. CONFIG_MAPPING, *PCONFIG_MAPPING;
  28. //
  29. // Mapping table
  30. //
  31. CONFIG_MAPPING ConfigMappingArray[] =
  32. {
  33. // In Win2K
  34. DnsConfigPrimaryDomainName_W,
  35. RegIdPrimaryDomainName,
  36. 0,
  37. 0,
  38. DnsCharSetUnicode,
  39. DnsConfigPrimaryDomainName_A,
  40. RegIdPrimaryDomainName,
  41. 0,
  42. 0,
  43. DnsCharSetAnsi,
  44. DnsConfigPrimaryDomainName_UTF8,
  45. RegIdPrimaryDomainName,
  46. 0,
  47. 0,
  48. DnsCharSetUtf8,
  49. // Not available
  50. DnsConfigAdapterDomainName_W,
  51. RegIdAdapterDomainName,
  52. 1,
  53. 1,
  54. DnsCharSetUnicode,
  55. DnsConfigAdapterDomainName_A,
  56. RegIdAdapterDomainName,
  57. 1,
  58. 1,
  59. DnsCharSetAnsi,
  60. DnsConfigAdapterDomainName_UTF8,
  61. RegIdAdapterDomainName,
  62. 1,
  63. 1,
  64. DnsCharSetUtf8,
  65. // In Win2K
  66. DnsConfigDnsServerList,
  67. RegIdDnsServers,
  68. 1, // adapter allowed
  69. 0, // not required
  70. 0,
  71. // Not available
  72. DnsConfigSearchList,
  73. RegIdSearchList,
  74. 0, // adapter allowed
  75. 0, // not required
  76. 0,
  77. DnsConfigAdapterInfo,
  78. 0, // no reg mapping
  79. 0, // adapter allowed
  80. 0, // not required
  81. 0,
  82. // In Win2K
  83. DnsConfigPrimaryHostNameRegistrationEnabled,
  84. RegIdRegisterPrimaryName,
  85. 1, // adapter allowed
  86. 0, // not required
  87. 0,
  88. DnsConfigAdapterHostNameRegistrationEnabled,
  89. RegIdRegisterAdapterName,
  90. 1, // adapter allowed
  91. 0, // adapter note required
  92. 0,
  93. DnsConfigAddressRegistrationMaxCount,
  94. RegIdRegistrationMaxAddressCount,
  95. 1, // adapter allowed
  96. 0, // not required
  97. 0,
  98. // In WindowsXP
  99. DnsConfigHostName_W,
  100. RegIdHostName,
  101. 0,
  102. 0,
  103. DnsCharSetUnicode,
  104. DnsConfigHostName_A,
  105. RegIdHostName,
  106. 0,
  107. 0,
  108. DnsCharSetAnsi,
  109. DnsConfigHostName_UTF8,
  110. RegIdHostName,
  111. 0,
  112. 0,
  113. DnsCharSetUtf8,
  114. // In WindowsXP
  115. //
  116. // System Public -- Windows XP
  117. //
  118. DnsConfigRegistrationEnabled,
  119. RegIdRegistrationEnabled,
  120. 1, // adapter allowed
  121. 0, // not required
  122. 0,
  123. DnsConfigWaitForNameErrorOnAll,
  124. RegIdWaitForNameErrorOnAll,
  125. 0, // no adapter
  126. 0, // not required
  127. 0,
  128. // These exist in system-public space but are
  129. // not DWORDs and table is never used for them
  130. //
  131. // DnsConfigNetworkInformation:
  132. // DnsConfigSearchInformation:
  133. // DnsConfigNetInfo:
  134. };
  135. #define LAST_CONFIG_MAPPED (DnsConfigHostName_UTF8)
  136. #define CONFIG_TABLE_LENGTH (sizeof(ConfigMappingArray) / sizeof(CONFIG_MAPPING))
  137. PCONFIG_MAPPING
  138. GetConfigToRegistryMapping(
  139. IN DNS_CONFIG_TYPE ConfigId,
  140. IN PCWSTR pwsAdapterName,
  141. IN BOOL fCheckAdapter
  142. )
  143. /*++
  144. Routine Description:
  145. Get registry enum type for config enum type.
  146. Purpose of this is to do mapping -- thus hiding internal
  147. registry implemenation -- AND to do check on whether
  148. adapter info is allowed or required for the config type.
  149. Arguments:
  150. ConfigId -- config type
  151. pwsAdapterName -- adapter name
  152. Return Value:
  153. Ptr to config to registry mapping -- if found.
  154. --*/
  155. {
  156. DWORD iter = 0;
  157. PCONFIG_MAPPING pfig;
  158. //
  159. // find config
  160. //
  161. // note, using loop through config IDs; this allows
  162. // use to have gap in config table allowing private
  163. // ids well separated from public id space
  164. //
  165. while ( iter < CONFIG_TABLE_LENGTH )
  166. {
  167. pfig = & ConfigMappingArray[ iter ];
  168. if ( pfig->ConfigId != (DWORD)ConfigId )
  169. {
  170. iter++;
  171. continue;
  172. }
  173. goto Found;
  174. }
  175. goto Invalid;
  176. Found:
  177. //
  178. // verify adapter info is appropriate to config type
  179. //
  180. if ( fCheckAdapter )
  181. {
  182. if ( pwsAdapterName )
  183. {
  184. if ( !pfig->fAdapterAllowed )
  185. {
  186. goto Invalid;
  187. }
  188. }
  189. else
  190. {
  191. if ( pfig->fAdapterRequired )
  192. {
  193. goto Invalid;
  194. }
  195. }
  196. }
  197. return pfig;
  198. Invalid:
  199. DNS_ASSERT( FALSE );
  200. SetLastError( ERROR_INVALID_PARAMETER );
  201. return NULL;
  202. }
  203. DNS_STATUS
  204. LookupDwordConfigValue(
  205. OUT PDWORD pResult,
  206. IN DNS_CONFIG_TYPE ConfigId,
  207. IN PWSTR pwsAdapter
  208. )
  209. /*++
  210. Routine Description:
  211. Get registry enum type for config enum type.
  212. Purpose of this is to do mapping -- thus hiding internal
  213. registry implemenation -- AND to do check on whether
  214. adapter info is allowed or required for the config type.
  215. Arguments:
  216. pResult -- address to recv DWORD result
  217. ConfigId -- config type
  218. pwsAdapter -- adapter name
  219. Return Value:
  220. ERROR_SUCCESS on successful read.
  221. ErrorCode on failure.
  222. --*/
  223. {
  224. PCONFIG_MAPPING pfig;
  225. DNS_STATUS status;
  226. //
  227. // verify config is known and mapped
  228. //
  229. pfig = GetConfigToRegistryMapping(
  230. ConfigId,
  231. pwsAdapter,
  232. TRUE // check adapter validity
  233. );
  234. if ( !pfig )
  235. {
  236. return ERROR_INVALID_PARAMETER;
  237. }
  238. //
  239. // lookup in registry
  240. //
  241. status = Reg_GetDword(
  242. NULL, // no session
  243. NULL, // no key given
  244. pwsAdapter,
  245. pfig->RegId, // reg id for config type
  246. pResult );
  247. #if DBG
  248. if ( status != NO_ERROR )
  249. {
  250. if ( status == ERROR_FILE_NOT_FOUND )
  251. {
  252. DNSDBG( REGISTRY, (
  253. "Reg_GetDword() defaulted for config lookup!\n"
  254. "\tConfigId = %d\n"
  255. "\tRedId = %d\n"
  256. "\tpwsAdapter = %S\n"
  257. "\tValue = %d\n",
  258. ConfigId,
  259. pfig->RegId,
  260. pwsAdapter,
  261. *pResult ));
  262. }
  263. else
  264. {
  265. DNSDBG( ANY, (
  266. "Reg_GetDword() failed for config lookup!\n"
  267. "\tstatus = %d\n"
  268. "\tConfigId = %d\n"
  269. "\tRedId = %d\n"
  270. "\tpwsAdapter = %S\n",
  271. status,
  272. ConfigId,
  273. pfig->RegId,
  274. pwsAdapter ));
  275. ASSERT( status == NO_ERROR );
  276. }
  277. }
  278. #endif
  279. return( status );
  280. }
  281. //
  282. // Public Configuration API
  283. //
  284. DNS_STATUS
  285. DnsQueryConfig(
  286. IN DNS_CONFIG_TYPE ConfigId,
  287. IN DWORD Flag,
  288. IN PWSTR pwsAdapterName,
  289. IN PVOID pReserved,
  290. OUT PVOID pBuffer,
  291. IN OUT PDWORD pBufferLength
  292. )
  293. /*++
  294. Routine Description:
  295. Get DNS configuration info.
  296. Arguments:
  297. ConfigId -- type of config info desired
  298. Flag -- flags to query
  299. pAdapterName -- name of adapter; NULL if no specific adapter
  300. pReserved -- reserved parameter, should be NULL
  301. pBuffer -- buffer to receive config info
  302. pBufferLength -- addr of DWORD containing buffer length; on return
  303. contains length
  304. Return Value:
  305. ERROR_SUCCESS -- if query successful
  306. ERROR_MORE_DATA -- if not enough space in buffer
  307. --*/
  308. {
  309. DNS_STATUS status = ERROR_SUCCESS;
  310. DWORD bufLength = 0;
  311. DWORD resultLength = 0;
  312. PBYTE presult;
  313. PBYTE pallocResult = NULL;
  314. BOOL boolData;
  315. DWORD dwordData;
  316. DNSDBG( TRACE, (
  317. "DnsQueryConfig()\n"
  318. "\tconfig = %d\n"
  319. "\tconfig = %08x\n"
  320. "\tflag = %08x\n"
  321. "\tadapter = %S\n"
  322. "\tpBuffer = %p\n",
  323. ConfigId,
  324. ConfigId,
  325. Flag,
  326. pwsAdapterName,
  327. pBuffer
  328. ));
  329. //
  330. // check out param setup
  331. //
  332. if ( !pBufferLength )
  333. {
  334. return ERROR_INVALID_PARAMETER;
  335. }
  336. if ( pBuffer )
  337. {
  338. bufLength = *pBufferLength;
  339. }
  340. //
  341. // find specific configuration data requested
  342. //
  343. switch( ConfigId )
  344. {
  345. case DnsConfigPrimaryDomainName_W:
  346. presult = (PBYTE) Reg_GetPrimaryDomainName( DnsCharSetUnicode );
  347. goto WideString;
  348. case DnsConfigPrimaryDomainName_A:
  349. presult = (PBYTE) Reg_GetPrimaryDomainName( DnsCharSetAnsi );
  350. goto NarrowString;
  351. case DnsConfigPrimaryDomainName_UTF8:
  352. presult = (PBYTE) Reg_GetPrimaryDomainName( DnsCharSetUtf8 );
  353. goto NarrowString;
  354. case DnsConfigDnsServerList:
  355. presult = (PBYTE) Config_GetDnsServerListIp4(
  356. pwsAdapterName,
  357. TRUE // force registry read
  358. );
  359. if ( !presult )
  360. {
  361. status = GetLastError();
  362. if ( status == NO_ERROR )
  363. {
  364. DNS_ASSERT( FALSE );
  365. status = DNS_ERROR_NO_DNS_SERVERS;
  366. }
  367. goto Done;
  368. }
  369. pallocResult = presult;
  370. resultLength = Dns_SizeofIpArray( (PIP4_ARRAY)presult );
  371. goto Process;
  372. case DnsConfigDnsServers:
  373. case DnsConfigDnsServersIp4:
  374. case DnsConfigDnsServersIp6:
  375. {
  376. DWORD family = 0;
  377. if ( ConfigId == DnsConfigDnsServersIp4 )
  378. {
  379. family = AF_INET;
  380. }
  381. else if ( ConfigId == DnsConfigDnsServersIp6 )
  382. {
  383. family = AF_INET6;
  384. }
  385. presult = (PBYTE) Config_GetDnsServerList(
  386. pwsAdapterName,
  387. family, // desired address family
  388. TRUE // force registry read
  389. );
  390. if ( !presult )
  391. {
  392. status = GetLastError();
  393. if ( status == NO_ERROR )
  394. {
  395. DNS_ASSERT( FALSE );
  396. status = DNS_ERROR_NO_DNS_SERVERS;
  397. }
  398. goto Done;
  399. }
  400. pallocResult = presult;
  401. resultLength = DnsAddrArray_Sizeof( (PDNS_ADDR_ARRAY)presult );
  402. goto Process;
  403. }
  404. case DnsConfigPrimaryHostNameRegistrationEnabled:
  405. case DnsConfigAdapterHostNameRegistrationEnabled:
  406. case DnsConfigAddressRegistrationMaxCount:
  407. goto Dword;
  408. //case DnsConfigAdapterDomainName:
  409. //case DnsConfigAdapterInfo:
  410. //case DnsConfigSearchList:
  411. case DnsConfigHostName_W:
  412. presult = (PBYTE) Reg_GetHostName( DnsCharSetUnicode );
  413. goto WideString;
  414. case DnsConfigHostName_A:
  415. presult = (PBYTE) Reg_GetHostName( DnsCharSetAnsi );
  416. goto NarrowString;
  417. case DnsConfigHostName_UTF8:
  418. presult = (PBYTE) Reg_GetHostName( DnsCharSetUtf8 );
  419. goto NarrowString;
  420. case DnsConfigFullHostName_W:
  421. presult = (PBYTE) Reg_GetFullHostName( DnsCharSetUnicode );
  422. goto WideString;
  423. case DnsConfigFullHostName_A:
  424. presult = (PBYTE) Reg_GetFullHostName( DnsCharSetAnsi );
  425. goto NarrowString;
  426. case DnsConfigFullHostName_UTF8:
  427. presult = (PBYTE) Reg_GetFullHostName( DnsCharSetUtf8 );
  428. goto NarrowString;
  429. default:
  430. return ERROR_INVALID_PARAMETER;
  431. }
  432. //
  433. // setup return info for common types
  434. //
  435. // this just avoids code duplication above
  436. //
  437. Dword:
  438. status = LookupDwordConfigValue(
  439. & dwordData,
  440. ConfigId,
  441. pwsAdapterName );
  442. if ( status != NO_ERROR )
  443. {
  444. goto Done;
  445. }
  446. presult = (PBYTE) &dwordData;
  447. resultLength = sizeof(DWORD);
  448. goto Process;
  449. NarrowString:
  450. if ( !presult )
  451. {
  452. status = DNS_ERROR_NO_MEMORY;
  453. goto Done;
  454. }
  455. pallocResult = presult;
  456. resultLength = strlen( (PSTR)presult ) + 1;
  457. goto Process;
  458. WideString:
  459. if ( !presult )
  460. {
  461. status = DNS_ERROR_NO_MEMORY;
  462. goto Done;
  463. }
  464. pallocResult = presult;
  465. resultLength = (wcslen( (PWSTR)presult ) + 1) * sizeof(WCHAR);
  466. goto Process;
  467. Process:
  468. //
  469. // return results -- three basic programs
  470. // - no buffer => only return length required
  471. // - allocate => return allocated result
  472. // - supplied buffer => copy result into buffer
  473. //
  474. // note, this section only handles simple flag datablobs to aVOID
  475. // duplicating code for specific config types above;
  476. // when we add config types that require nested pointers, they must
  477. // roll their own return-results code and jump to Done
  478. //
  479. //
  480. // no buffer
  481. // - no-op, length is set below
  482. if ( !pBuffer )
  483. {
  484. }
  485. //
  486. // allocated result
  487. // - return buffer gets ptr
  488. // - allocate copy of result if not allocated
  489. //
  490. else if ( Flag & DNS_CONFIG_FLAG_ALLOC )
  491. {
  492. PBYTE pheap;
  493. if ( bufLength < sizeof(PVOID) )
  494. {
  495. resultLength = sizeof(PVOID);
  496. status = ERROR_MORE_DATA;
  497. goto Done;
  498. }
  499. // create local alloc buffer
  500. pheap = LocalAlloc( 0, resultLength );
  501. if ( !pheap )
  502. {
  503. status = DNS_ERROR_NO_MEMORY;
  504. goto Done;
  505. }
  506. RtlCopyMemory(
  507. pheap,
  508. presult,
  509. resultLength );
  510. // return ptr to allocated result
  511. * (PVOID*) pBuffer = pheap;
  512. }
  513. //
  514. // allocated result -- but dnsapi alloc
  515. //
  516. else if ( Flag & DNS_CONFIG_FLAG_DNSAPI_ALLOC )
  517. {
  518. if ( bufLength < sizeof(PVOID) )
  519. {
  520. resultLength = sizeof(PVOID);
  521. status = ERROR_MORE_DATA;
  522. goto Done;
  523. }
  524. // if result not allocated, alloc and copy it
  525. if ( ! pallocResult )
  526. {
  527. pallocResult = ALLOCATE_HEAP( resultLength );
  528. if ( !pallocResult )
  529. {
  530. status = DNS_ERROR_NO_MEMORY;
  531. goto Done;
  532. }
  533. RtlCopyMemory(
  534. pallocResult,
  535. presult,
  536. resultLength );
  537. }
  538. // return ptr to allocated result
  539. * (PVOID*) pBuffer = pallocResult;
  540. // clear pallocResult, so not freed in generic cleanup
  541. pallocResult = NULL;
  542. }
  543. //
  544. // copy result to caller buffer
  545. //
  546. else
  547. {
  548. if ( bufLength < resultLength )
  549. {
  550. status = ERROR_MORE_DATA;
  551. goto Done;
  552. }
  553. RtlCopyMemory(
  554. pBuffer,
  555. presult,
  556. resultLength );
  557. }
  558. Done:
  559. //
  560. // set result length
  561. // cleanup any allocated (but not returned) data
  562. //
  563. *pBufferLength = resultLength;
  564. if ( pallocResult )
  565. {
  566. FREE_HEAP( pallocResult );
  567. }
  568. return( status );
  569. }
  570. //
  571. // System Public Configuration API
  572. //
  573. PVOID
  574. WINAPI
  575. DnsQueryConfigAllocEx(
  576. IN DNS_CONFIG_TYPE ConfigId,
  577. IN PWSTR pwsAdapterName,
  578. IN BOOL fLocalAlloc
  579. )
  580. /*++
  581. Routine Description:
  582. Get DNS configuration info.
  583. Allocate DNS configuration info.
  584. This is the cover API both handling the system public API
  585. DnsQueryConfigAlloc() below and the backward compatible
  586. macros for the old hostname and PDN alloc routines (see dnsapi.h)
  587. Arguments:
  588. ConfigId -- type of config info desired
  589. pAdapterName -- name of adapter; NULL if no specific adapter
  590. fLocalAlloc -- allocate with LocalAlloc
  591. Return Value:
  592. ERROR_SUCCESS -- if query successful
  593. ERROR_MORE_DATA -- if not enough space in buffer
  594. --*/
  595. {
  596. DNS_STATUS status = ERROR_SUCCESS;
  597. DWORD bufLength = sizeof(PVOID);
  598. PBYTE presult = NULL;
  599. DNSDBG( TRACE, (
  600. "DnsQueryConfigAllocEx()\n"
  601. "\tconfig = %d\n"
  602. "\tconfig = %08x\n"
  603. "\tadapter = %S\n"
  604. "\tflocal = %d\n",
  605. ConfigId,
  606. ConfigId,
  607. pwsAdapterName,
  608. fLocalAlloc
  609. ));
  610. //
  611. // DCR: flags on config reading (resolver, cached, etc.)
  612. //
  613. //
  614. // SDK-public types
  615. //
  616. if ( ConfigId < DnsConfigSystemBase )
  617. {
  618. //
  619. // DCR: could screen here for alloc types
  620. //
  621. // DnsConfigPrimaryDomainName_W:
  622. // DnsConfigPrimaryDomainName_A:
  623. // DnsConfigPrimaryDomainName_UTF8:
  624. // DnsConfigHostname_W:
  625. // DnsConfigHostname_A:
  626. // DnsConfigHostname_UTF8:
  627. // DnsConfigDnsServerList:
  628. //
  629. status = DnsQueryConfig(
  630. ConfigId,
  631. fLocalAlloc
  632. ? DNS_CONFIG_FLAG_LOCAL_ALLOC
  633. : DNS_CONFIG_FLAG_DNSAPI_ALLOC,
  634. pwsAdapterName,
  635. NULL, // reserved
  636. & presult,
  637. & bufLength );
  638. if ( status != NO_ERROR )
  639. {
  640. SetLastError( status );
  641. return NULL;
  642. }
  643. return presult;
  644. }
  645. //
  646. // System public types
  647. //
  648. if ( fLocalAlloc )
  649. {
  650. goto Invalid;
  651. }
  652. switch ( ConfigId )
  653. {
  654. // old public config blobs
  655. case DnsConfigNetworkInformation:
  656. return DnsNetworkInformation_Get();
  657. case DnsConfigSearchInformation:
  658. return DnsSearchInformation_Get();
  659. // new public config blobs
  660. case DnsConfigNetworkInfoA:
  661. return DnsNetworkInfo_Get( DnsCharSetAnsi );
  662. case DnsConfigSearchListA:
  663. return DnsSearchList_Get( DnsCharSetAnsi );
  664. case DnsConfigNetworkInfoW:
  665. return DnsNetworkInfo_Get( DnsCharSetUnicode );
  666. case DnsConfigSearchListW:
  667. return DnsSearchList_Get( DnsCharSetUnicode );
  668. case DnsConfigDwordGlobals:
  669. //
  670. // DCR: flags on config reading (resolver, cached, etc.)
  671. //
  672. //
  673. // get globals
  674. // not forcing registry read
  675. // using from resolver if found
  676. // then current (if netinfo blob cached)
  677. //
  678. // note, that whatever we return, even if from resolver, is
  679. // (becomes) the current set for dnsapi.dll
  680. //
  681. return Config_GetDwordGlobals(
  682. ( NIFLAG_READ_RESOLVER_FIRST | NIFLAG_READ_PROCESS_CACHE ),
  683. 0 // default cache timeout
  684. );
  685. #if 0
  686. case DnsConfigNetInfo:
  687. return NetInfo_Get(
  688. TRUE, // force
  689. TRUE // include IP addresses
  690. );
  691. #endif
  692. case DnsConfigIp4AddressArray:
  693. // this called by gethostname( NULL ) => myhostent()
  694. // - so handle cluster based on environment varaible
  695. return NetInfo_GetLocalAddrArrayIp4(
  696. pwsAdapterName,
  697. DNS_CONFIG_FLAG_ADDR_PUBLIC |
  698. DNS_CONFIG_FLAG_ADDR_PRIVATE |
  699. DNS_CONFIG_FLAG_READ_CLUSTER_ENVAR,
  700. FALSE // no force, accept from resolver
  701. );
  702. case DnsConfigLocalAddrsIp6:
  703. case DnsConfigLocalAddrsIp4:
  704. case DnsConfigLocalAddrs:
  705. {
  706. DWORD family = 0;
  707. if ( ConfigId == DnsConfigLocalAddrsIp6 )
  708. {
  709. family = AF_INET6;
  710. }
  711. else if ( ConfigId == DnsConfigLocalAddrsIp4 )
  712. {
  713. family = AF_INET;
  714. }
  715. return NetInfo_GetLocalAddrArray(
  716. NULL, // no existing netinfo
  717. pwsAdapterName,
  718. family, // address family
  719. DNS_CONFIG_FLAG_ADDR_ALL, // all addrs
  720. TRUE // force rebuild
  721. );
  722. }
  723. // unknown falls through to invalid
  724. }
  725. Invalid:
  726. DNS_ASSERT( FALSE );
  727. SetLastError( ERROR_INVALID_PARAMETER );
  728. return( NULL );
  729. }
  730. //
  731. // DWORD system-public config
  732. //
  733. DWORD
  734. DnsQueryConfigDword(
  735. IN DNS_CONFIG_TYPE ConfigId,
  736. IN PWSTR pwsAdapter
  737. )
  738. /*++
  739. Routine Description:
  740. Get DNS DWORD configuration value.
  741. This is system public routine.
  742. Arguments:
  743. ConfigId -- type of config info desired
  744. pwsAdapter -- name of adapter; NULL if no specific adapter
  745. Return Value:
  746. DWORD config value.
  747. Zero if no such config.
  748. --*/
  749. {
  750. DNS_STATUS status;
  751. DWORD value = 0;
  752. DNSDBG( TRACE, (
  753. "DnsQueryConfigDword()\n"
  754. "\tconfig = %d\n"
  755. "\tadapter = %S\n",
  756. ConfigId,
  757. pwsAdapter
  758. ));
  759. status = LookupDwordConfigValue(
  760. & value,
  761. ConfigId,
  762. pwsAdapter );
  763. #if DBG
  764. if ( status != NO_ERROR &&
  765. status != ERROR_FILE_NOT_FOUND )
  766. {
  767. DNSDBG( ANY, (
  768. "LookupDwordConfigValue() failed for config lookup!\n"
  769. "\tstatus = %d\n"
  770. "\tConfigId = %d\n"
  771. "\tpwsAdapter = %S\n",
  772. status,
  773. ConfigId,
  774. pwsAdapter ));
  775. DNS_ASSERT( status == NO_ERROR );
  776. }
  777. #endif
  778. DNSDBG( TRACE, (
  779. "Leave DnsQueryConfigDword() => %08x (%d)\n"
  780. "\tconfig = %d\n"
  781. "\tadapter = %S\n",
  782. value,
  783. value,
  784. ConfigId,
  785. pwsAdapter
  786. ));
  787. return( value );
  788. }
  789. DNS_STATUS
  790. DnsSetConfigDword(
  791. IN DNS_CONFIG_TYPE ConfigId,
  792. IN PWSTR pwsAdapter,
  793. IN DWORD NewValue
  794. )
  795. /*++
  796. Routine Description:
  797. Set DNS DWORD configuration value.
  798. This is system public routine.
  799. Arguments:
  800. ConfigId -- type of config info desired
  801. pwsAdapter -- name of adapter; NULL if no specific adapter
  802. NewValue -- new value for parameter
  803. Return Value:
  804. DWORD config value.
  805. Zero if no such config.
  806. --*/
  807. {
  808. PCONFIG_MAPPING pfig;
  809. DNSDBG( TRACE, (
  810. "DnsSetConfigDword()\n"
  811. "\tconfig = %d\n"
  812. "\tadapter = %S\n"
  813. "\tvalue = %d (%08x)\n",
  814. ConfigId,
  815. pwsAdapter,
  816. NewValue, NewValue
  817. ));
  818. //
  819. // verify config is known and mapped
  820. //
  821. pfig = GetConfigToRegistryMapping(
  822. ConfigId,
  823. pwsAdapter,
  824. TRUE // check adapter validity
  825. );
  826. if ( !pfig )
  827. {
  828. return ERROR_INVALID_PARAMETER;
  829. }
  830. //
  831. // set in registry
  832. //
  833. return Reg_SetDwordPropertyAndAlertCache(
  834. pwsAdapter, // adapter name key (if any)
  835. pfig->RegId,
  836. NewValue );
  837. }
  838. //
  839. // Config data free
  840. //
  841. VOID
  842. WINAPI
  843. DnsFreeConfigStructure(
  844. IN OUT PVOID pData,
  845. IN DNS_CONFIG_TYPE ConfigId
  846. )
  847. /*++
  848. Routine Description:
  849. Free config data
  850. This routine simply handles the mapping between config IDs
  851. and the free type.
  852. Arguments:
  853. pData -- data to free
  854. ConfigId -- config id
  855. Return Value:
  856. None
  857. --*/
  858. {
  859. DNS_FREE_TYPE freeType = DnsFreeFlat;
  860. DNSDBG( TRACE, (
  861. "DnsFreeConfigStructure( %p, %d )\n",
  862. pData,
  863. ConfigId ));
  864. //
  865. // find any unflat config types
  866. //
  867. // note: currently all config types that are not flat
  868. // are system-public only and the config ID is also
  869. // the free type (for convenience); if we start
  870. // exposing some of these bringing them into the low
  871. // space, then this will change
  872. //
  873. // unfortunately these types can NOT be identical because
  874. // the space conflicts in shipped Win2K (FreeType==1 is
  875. // record list)
  876. //
  877. if ( ConfigId > DnsConfigSystemBase &&
  878. (
  879. ConfigId == DnsConfigNetworkInfoW ||
  880. ConfigId == DnsConfigSearchListW ||
  881. ConfigId == DnsConfigAdapterInfoW ||
  882. ConfigId == DnsConfigNetworkInfoA ||
  883. ConfigId == DnsConfigSearchListA ||
  884. ConfigId == DnsConfigAdapterInfoA ||
  885. // ConfigId == DnsConfigNetInfo ||
  886. ConfigId == DnsConfigNetworkInformation ||
  887. ConfigId == DnsConfigSearchInformation ||
  888. ConfigId == DnsConfigAdapterInformation
  889. ) )
  890. {
  891. freeType = (DNS_FREE_TYPE) ConfigId;
  892. }
  893. DnsFree(
  894. pData,
  895. freeType );
  896. }
  897. //
  898. // Config routines for specific types
  899. //
  900. PADDR_ARRAY
  901. Config_GetDnsServerList(
  902. IN PWSTR pwsAdapterName,
  903. IN DWORD AddrFamily,
  904. IN BOOL fForce
  905. )
  906. /*++
  907. Routine Description:
  908. Get DNS server list as IP array.
  909. Arguments:
  910. fForce -- force reread from registry
  911. Return Value:
  912. ERROR_SUCCESS if successful.
  913. Error code on failure.
  914. --*/
  915. {
  916. PDNS_NETINFO pnetInfo = NULL;
  917. PADDR_ARRAY parray = NULL;
  918. DNS_STATUS status = NO_ERROR;
  919. DNSDBG( TRACE, (
  920. "Config_GetDnsServerList()\n"
  921. "\tadapter = %S\n"
  922. "\tfamily = %d\n"
  923. "\tforce = %d\n",
  924. pwsAdapterName,
  925. AddrFamily,
  926. fForce
  927. ));
  928. //
  929. // get network info to make list from
  930. // - don't need IP address lists
  931. //
  932. // DCR: force reread for DNS servers unnecessary once notify on it
  933. //
  934. pnetInfo = NetInfo_Get(
  935. NIFLAG_FORCE_REGISTRY_READ,
  936. 0
  937. );
  938. if ( !pnetInfo )
  939. {
  940. status = DNS_ERROR_NO_DNS_SERVERS;
  941. goto Done;
  942. }
  943. //
  944. // convert network info to IP4_ARRAY
  945. //
  946. parray = NetInfo_ConvertToAddrArray(
  947. pnetInfo,
  948. pwsAdapterName,
  949. AddrFamily );
  950. if ( !parray )
  951. {
  952. status = GetLastError();
  953. goto Done;
  954. }
  955. // if no servers read, return
  956. if ( parray->AddrCount == 0 )
  957. {
  958. DNS_PRINT((
  959. "Dns_GetDnsServerList() failed: no DNS servers found\n"
  960. "\tstatus = %d\n" ));
  961. status = DNS_ERROR_NO_DNS_SERVERS;
  962. goto Done;
  963. }
  964. IF_DNSDBG( NETINFO )
  965. {
  966. DNS_PRINT(( "Leaving Config_GetDnsServerList()\n" ));
  967. DnsDbg_DnsAddrArray(
  968. "DNS server list",
  969. "server",
  970. parray );
  971. }
  972. Done:
  973. NetInfo_Free( pnetInfo );
  974. if ( status != NO_ERROR )
  975. {
  976. FREE_HEAP( parray );
  977. parray = NULL;
  978. SetLastError( status );
  979. }
  980. return( parray );
  981. }
  982. PIP4_ARRAY
  983. Config_GetDnsServerListIp4(
  984. IN PWSTR pwsAdapterName,
  985. IN BOOL fForce
  986. )
  987. /*++
  988. Routine Description:
  989. Get DNS server list as IP array.
  990. Arguments:
  991. fForce -- force reread from registry
  992. Return Value:
  993. ERROR_SUCCESS if successful.
  994. Error code on failure.
  995. --*/
  996. {
  997. PADDR_ARRAY parray;
  998. PIP4_ARRAY parray4 = NULL;
  999. DNS_STATUS status = NO_ERROR;
  1000. DNSDBG( TRACE, ( "Config_GetDnsServerListIp4()\n" ));
  1001. //
  1002. // get DNS server list
  1003. //
  1004. parray = Config_GetDnsServerList(
  1005. pwsAdapterName,
  1006. AF_INET,
  1007. fForce );
  1008. if ( !parray )
  1009. {
  1010. goto Done;
  1011. }
  1012. //
  1013. // convert array to IP4 array
  1014. //
  1015. parray4 = DnsAddrArray_CreateIp4Array( parray );
  1016. if ( !parray4 )
  1017. {
  1018. status = DNS_ERROR_NO_MEMORY;
  1019. goto Done;
  1020. }
  1021. DNS_ASSERT( parray4->AddrCount > 0 );
  1022. IF_DNSDBG( NETINFO )
  1023. {
  1024. DnsDbg_Ip4Array(
  1025. "DNS server list",
  1026. "server",
  1027. parray4 );
  1028. }
  1029. Done:
  1030. DnsAddrArray_Free( parray );
  1031. if ( status != NO_ERROR )
  1032. {
  1033. SetLastError( status );
  1034. }
  1035. return( parray4 );
  1036. }
  1037. PDNS_GLOBALS_BLOB
  1038. Config_GetDwordGlobals(
  1039. IN DWORD Flag,
  1040. IN DWORD AcceptLocalCacheTime OPTIONAL
  1041. )
  1042. /*++
  1043. Routine Description:
  1044. Read DNS network info from registry.
  1045. This is in process, limited caching version.
  1046. Note, this is macro'd as GetNetworkInfo() with parameters
  1047. NetInfo_Get( FALSE, TRUE ) throughout dnsapi code.
  1048. Arguments:
  1049. Flag -- flag; read order and IP
  1050. NIFLAG_GET_LOCAL_ADDRS
  1051. NIFLAG_FORCE_REGISTRY_READ
  1052. NIFLAG_READ_RESOLVER_FIRST
  1053. NIFLAG_READ_RESOLVER
  1054. NIFLAG_READ_PROCESS_CACHE
  1055. AcceptLocalCacheTime -- acceptable cache time on in process copy
  1056. Return Value:
  1057. ERROR_SUCCESS if successful.
  1058. Error code on failure.
  1059. --*/
  1060. {
  1061. DNS_STATUS status = ERROR_SUCCESS;
  1062. PDNS_NETINFO pnetInfo = NULL;
  1063. PDNS_GLOBALS_BLOB pblob = NULL;
  1064. DNSDBG( TRACE, (
  1065. "Config_GetDwordGlobals( %08x %08x)\n",
  1066. Flag,
  1067. AcceptLocalCacheTime ));
  1068. //
  1069. // read info -- from resolver or locally
  1070. // reading netinfo will force update of globals
  1071. //
  1072. // DCR: extra work being done here;
  1073. // if UpdateNetworkInfo() fails to contact resolver
  1074. // or if resolver not trusted, can get away with simple
  1075. // reg read, don't need entire network info deal
  1076. //
  1077. pnetInfo = NetInfo_Get(
  1078. Flag,
  1079. AcceptLocalCacheTime );
  1080. //
  1081. // global info now up to date
  1082. //
  1083. // note, that whatever we return, even if from resolver, is
  1084. // (becomes) the current set for dnsapi.dll
  1085. //
  1086. // DCR: copy outside of API?
  1087. //
  1088. pblob = ALLOCATE_HEAP( sizeof(*pblob) );
  1089. if ( pblob )
  1090. {
  1091. RtlCopyMemory(
  1092. pblob,
  1093. & DnsGlobals,
  1094. sizeof(DnsGlobals) );
  1095. }
  1096. //
  1097. // cleanup netinfo
  1098. //
  1099. NetInfo_Free( pnetInfo );
  1100. return pblob;
  1101. }
  1102. //
  1103. // End config.c
  1104. //