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.

2183 lines
44 KiB

  1. /*++
  2. Copyright (c) 1999-2001 Microsoft Corporation
  3. Module Name:
  4. regfig.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. // Table for quick lookup of DWORD\BOOL reg values
  15. //
  16. // DCR: read directly to config BLOB with regID indexes
  17. // you can't screw that up
  18. //
  19. #define DWORD_PTR_ARRAY_END ((PDWORD) (DWORD_PTR)(-1))
  20. PDWORD RegDwordPtrArray[] =
  21. {
  22. // basic -- not DWORDs
  23. NULL,
  24. NULL,
  25. NULL,
  26. NULL,
  27. NULL,
  28. NULL,
  29. NULL,
  30. NULL,
  31. NULL,
  32. NULL,
  33. // query
  34. (PDWORD) &g_QueryAdapterName,
  35. (PDWORD) &g_UseNameDevolution,
  36. (PDWORD) &g_PrioritizeRecordData,
  37. (PDWORD) &g_AllowUnqualifiedQuery,
  38. (PDWORD) &g_AppendToMultiLabelName,
  39. (PDWORD) &g_ScreenBadTlds,
  40. (PDWORD) &g_ScreenUnreachableServers,
  41. (PDWORD) &g_FilterClusterIp,
  42. (PDWORD) &g_WaitForNameErrorOnAll,
  43. (PDWORD) &g_UseEdns,
  44. // update
  45. (PDWORD) &g_RegistrationEnabled,
  46. (PDWORD) &g_RegisterPrimaryName,
  47. (PDWORD) &g_RegisterAdapterName,
  48. (PDWORD) &g_RegisterReverseLookup,
  49. (PDWORD) &g_RegisterWanAdapters,
  50. (PDWORD) &g_RegistrationOverwritesInConflict,
  51. (PDWORD) &g_RegistrationTtl,
  52. (PDWORD) &g_RegistrationRefreshInterval,
  53. (PDWORD) &g_RegistrationMaxAddressCount,
  54. (PDWORD) &g_UpdateSecurityLevel,
  55. (PDWORD) &g_UpdateZoneExcludeFile,
  56. (PDWORD) &g_UpdateTopLevelDomains,
  57. // backcompat
  58. NULL,
  59. NULL,
  60. NULL,
  61. NULL,
  62. NULL,
  63. NULL,
  64. NULL,
  65. NULL,
  66. NULL,
  67. NULL,
  68. // micellaneous
  69. NULL, //g_InNTSetupMode, // not in standard location
  70. (PDWORD) &g_DnsTestMode,
  71. NULL, // remote resolver not a DWORD
  72. // resolver
  73. (PDWORD) &g_MaxCacheSize,
  74. (PDWORD) &g_MaxCacheTtl,
  75. (PDWORD) &g_MaxNegativeCacheTtl,
  76. (PDWORD) &g_AdapterTimeoutLimit,
  77. (PDWORD) &g_ServerPriorityTimeLimit,
  78. (PDWORD) &g_MaxCachedSockets,
  79. // multicast resolver
  80. (PDWORD) &g_UseMulticast,
  81. (PDWORD) &g_MulticastOnNameError,
  82. (PDWORD) &g_UseDotLocalDomain,
  83. (PDWORD) &g_ListenOnMulticast,
  84. // termination
  85. DWORD_PTR_ARRAY_END
  86. };
  87. //
  88. // Array indicating which registry values
  89. // were read versus defaulted
  90. //
  91. DWORD RegValueWasReadArray[ RegIdValueCount ];
  92. //
  93. // Check for empty reg value (string)
  94. //
  95. // DCR: consider more detailed white space check
  96. //
  97. #define IS_EMPTY_STRING(psz) (*(psz)==0)
  98. //
  99. // General registry\config utils
  100. //
  101. VOID
  102. PrintConfigGlobals(
  103. IN PSTR pszHeader
  104. )
  105. /*++
  106. Routine Description:
  107. Print config globals.
  108. Arguments:
  109. pszHeader -- header to print with
  110. Return Value:
  111. ERROR_SUCCESS if successful.
  112. ErrorCode on failure.
  113. --*/
  114. {
  115. DWORD propId;
  116. //
  117. // print each property
  118. //
  119. DnsDbg_Lock();
  120. DnsDbg_Printf(
  121. "%s\n",
  122. pszHeader ? pszHeader : "Registry Globals:" );
  123. propId = 0;
  124. for( propId=0; propId<=RegIdValueMax; propId++ )
  125. {
  126. PDWORD pdword = RegDwordPtrArray[propId];
  127. // separators
  128. if ( propId == RegIdQueryAdapterName )
  129. {
  130. DnsDbg_Printf( "\t-- Query:\n" );
  131. }
  132. else if ( propId == RegIdRegistrationEnabled )
  133. {
  134. DnsDbg_Printf( "\t-- Update:\n" );
  135. }
  136. else if ( propId == RegIdSetupMode )
  137. {
  138. DnsDbg_Printf( "\t-- Miscellaneous:\n" );
  139. }
  140. else if ( propId == RegIdMaxCacheSize )
  141. {
  142. DnsDbg_Printf( "\t-- Resolver\n" );
  143. }
  144. // NULL indicates not DWORD or not standard
  145. if ( !pdword )
  146. {
  147. continue;
  148. }
  149. // terminate on bogus ptr
  150. if ( pdword == DWORD_PTR_ARRAY_END )
  151. {
  152. ASSERT( FALSE );
  153. break;
  154. }
  155. DnsDbg_Printf(
  156. "\t%-36S= %8d (read=%d)\n",
  157. REGPROP_NAME( propId ),
  158. * pdword,
  159. RegValueWasReadArray[ propId ] );
  160. }
  161. DnsDbg_Printf(
  162. "\t-- Random:\n"
  163. "\tIsDnsServer = %d\n"
  164. "\tInNTSetupMode = %d\n"
  165. "\tDnsTestMode = %08x\n\n",
  166. g_IsDnsServer,
  167. g_InNTSetupMode,
  168. g_DnsTestMode
  169. );
  170. DnsDbg_Unlock();
  171. }
  172. DNS_STATUS
  173. Reg_ReadGlobalsEx(
  174. IN DWORD dwFlag,
  175. IN PVOID pRegSession OPTIONAL
  176. )
  177. /*++
  178. Routine Description:
  179. Read globals from registry.
  180. Arguments:
  181. dwFlag -- flag indicating read level
  182. //
  183. // DCR: reg read flag unimplemented
  184. //
  185. // note: should have option to NOT read some registry
  186. // values for case when cache off, then could
  187. // skip useless cache info when building local
  188. // networkinfo blob
  189. //
  190. pRegSession -- ptr to existing registry session
  191. Return Value:
  192. ERROR_SUCCESS if successful.
  193. ErrorCode on failure.
  194. --*/
  195. {
  196. DWORD propId;
  197. REG_SESSION regSession;
  198. PREG_SESSION psession;
  199. DNS_STATUS status;
  200. DNSDBG( TRACE, (
  201. "Dns_ReadRegistryGlobals( %08x, %p )\n",
  202. dwFlag,
  203. pRegSession ));
  204. //
  205. // basic registry init
  206. // - includes system global
  207. //
  208. Reg_Init();
  209. //
  210. // code validity check
  211. // property table should have entry for every reg value plus an
  212. // extra one for the terminator
  213. //
  214. #if DBG
  215. DNS_ASSERT( (RegIdValueCount+1)*sizeof(PDWORD) ==
  216. sizeof(RegDwordPtrArray) );
  217. #endif
  218. //
  219. // open registry session -- if not passed in
  220. //
  221. psession = (PREG_SESSION) pRegSession;
  222. if ( !psession )
  223. {
  224. psession = &regSession;
  225. status = Reg_OpenSession( psession, 0, 0 );
  226. if ( status != ERROR_SUCCESS )
  227. {
  228. return( status );
  229. }
  230. }
  231. //
  232. // clear "value was read" array
  233. //
  234. RtlZeroMemory(
  235. RegValueWasReadArray,
  236. sizeof( RegValueWasReadArray ) );
  237. //
  238. // MS DNS?
  239. //
  240. g_IsDnsServer = Reg_IsMicrosoftDnsServer();
  241. //
  242. // remote resolver?
  243. // - not currently enabled
  244. //
  245. //g_pwsRemoteResolver = DnsGetResolverAddress();
  246. g_pwsRemoteResolver = NULL;
  247. //
  248. // read\set each DWORD\BOOL registry value
  249. //
  250. propId = 0;
  251. for( propId=0; propId<=RegIdValueMax; propId++ )
  252. {
  253. PDWORD pdword = RegDwordPtrArray[propId];
  254. // NULL indicates not DWORD or not standard
  255. if ( !pdword )
  256. {
  257. continue;
  258. }
  259. // terminate on bogus ptr
  260. if ( pdword == DWORD_PTR_ARRAY_END )
  261. {
  262. ASSERT( FALSE );
  263. break;
  264. }
  265. status = Reg_GetDword(
  266. psession, // reg session
  267. NULL, // no key
  268. NULL, // standard location
  269. propId, // index is property id
  270. pdword );
  271. // set fRead flag if value found in registry
  272. if ( status == ERROR_SUCCESS )
  273. {
  274. RegValueWasReadArray[propId] = TRUE;
  275. }
  276. }
  277. //
  278. // registration refresh defaults are different for DC
  279. //
  280. if ( !RegValueWasReadArray[ RegIdRegistrationRefreshInterval ] )
  281. {
  282. if ( g_IsDomainController )
  283. {
  284. g_RegistrationRefreshInterval = REGDEF_REGISTRATION_REFRESH_INTERVAL_DC;
  285. }
  286. ELSE_ASSERT( g_RegistrationRefreshInterval == REGDEF_REGISTRATION_REFRESH_INTERVAL );
  287. }
  288. //
  289. // non-standard registry values
  290. // - setup mode
  291. //
  292. Reg_GetDword(
  293. psession,
  294. NULL, // no key
  295. REGKEY_SETUP_MODE_LOCATION,
  296. RegIdSetupMode,
  297. (PDWORD) &g_InNTSetupMode );
  298. //
  299. // DCR: flip in policy globals and do single read here
  300. // or since they are only relevant to adapter
  301. // list and registration, keep separate
  302. //
  303. // fundamentally the question is how separate is the
  304. // adapter list read from other globals?
  305. //
  306. // close local session registry handles
  307. if ( psession == &regSession )
  308. {
  309. Reg_CloseSession( psession );
  310. }
  311. IF_DNSDBG( INIT )
  312. {
  313. PrintConfigGlobals( "Read Registry Globals" );
  314. }
  315. return( ERROR_SUCCESS );
  316. }
  317. DNS_STATUS
  318. Reg_RefreshUpdateConfig(
  319. VOID
  320. )
  321. /*++
  322. Routine Description:
  323. Read\refresh update config.
  324. This routine encapsulates getting all update config info
  325. current before any update operation.
  326. Arguments:
  327. None
  328. Return Value:
  329. ERROR_SUCCESS if successful.
  330. Error code on failure.
  331. --*/
  332. {
  333. //
  334. // read all global DWORDs if haven't been read "recently"
  335. //
  336. // note: adapter specific stuff is read building network config;
  337. // here were are just insuring that we have top level globals
  338. // current; specifically test was blocked because the
  339. // update TLD flag was not being reread
  340. //
  341. // DCR: when have change\notify this should just tie into
  342. // global config read
  343. //
  344. return Reg_ReadGlobalsEx( 0, NULL );
  345. }
  346. //
  347. // Special DNS property routines
  348. //
  349. DNS_STATUS
  350. Reg_ReadPrimaryDomainName(
  351. IN PREG_SESSION pRegSession, OPTIONAL
  352. IN HKEY hRegKey, OPTIONAL
  353. OUT PSTR * ppPrimaryDomainName
  354. )
  355. /*++
  356. Routine Description:
  357. Read primary domain name.
  358. Arguments:
  359. pRegSession -- ptr to registry session, OPTIONAL
  360. hRegKey -- handle to open regkey OPTIONAL (currently unimplemented)
  361. ppPrimaryDomainName -- addr to recv ptr to PDN
  362. Return Value:
  363. ERROR_SUCCESS if successful.
  364. Error code on failure.
  365. --*/
  366. {
  367. DNS_STATUS status;
  368. REG_SESSION session;
  369. PREG_SESSION psession = NULL;
  370. LPSTR pdomainName = NULL;
  371. DNSDBG( TRACE, ( "Reg_ReadPrimaryDomainName()\n" ));
  372. ASSERT( !hRegKey );
  373. //
  374. // open reg handle if not open
  375. //
  376. // note: worth doing here, because if we default the open
  377. // in the calls below, we will make unnecessary reg calls
  378. // -- won't be able to screen for policy existence
  379. // so policy PDN name will be looked for in TCPIP
  380. // -- the second call for the TCPIP domain name, will also
  381. // check in the policy area (if exists)
  382. //
  383. psession = pRegSession;
  384. if ( !psession )
  385. {
  386. psession = &session;
  387. status = Reg_OpenSession(
  388. psession,
  389. 0, // standard level
  390. 0 // no specific value, open both
  391. );
  392. if ( status != ERROR_SUCCESS )
  393. {
  394. goto Done;
  395. }
  396. }
  397. //
  398. // try policy
  399. // - no policy pickup for DCs
  400. // - first try new WindowsNT policy
  401. // - if not found, try policy used in Win2K
  402. //
  403. if ( !g_IsDomainController )
  404. {
  405. HKEY holdPolicyKey = NULL;
  406. HKEY hkeyPolicy = psession->hPolicy;
  407. if ( hkeyPolicy )
  408. {
  409. status = Reg_GetValue(
  410. NULL, // don't send whole session
  411. hkeyPolicy, // use explicit policy key
  412. RegIdPrimaryDomainName,
  413. REGTYPE_DNS_NAME,
  414. (PBYTE *) &pdomainName
  415. );
  416. if ( pdomainName )
  417. {
  418. goto Found;
  419. }
  420. }
  421. //
  422. // not found in new, open old policy
  423. //
  424. status = RegOpenKeyExW(
  425. HKEY_LOCAL_MACHINE,
  426. DNS_POLICY_WIN2K_KEY,
  427. 0,
  428. KEY_QUERY_VALUE,
  429. & holdPolicyKey );
  430. if ( holdPolicyKey )
  431. {
  432. status = Reg_GetValue(
  433. NULL, // don't send whole session
  434. holdPolicyKey, // use explicit policy key
  435. RegIdPrimaryDnsSuffix,
  436. REGTYPE_DNS_NAME,
  437. (PBYTE *) &pdomainName
  438. );
  439. RegCloseKey( holdPolicyKey );
  440. if ( pdomainName )
  441. {
  442. goto Found;
  443. }
  444. }
  445. }
  446. //
  447. // no policy name
  448. // - try DNS client
  449. // - try standard TCPIP location
  450. // note under TCPIP it's "Domain"
  451. //
  452. #ifdef DNSCLIENTKEY
  453. if ( psession->hClient )
  454. {
  455. status = Reg_GetValue(
  456. NULL, // don't send whole session
  457. psession->hClient, // send client key explicitly
  458. RegIdPrimaryDomainName,
  459. REGTYPE_DNS_NAME,
  460. (PBYTE *) &pdomainName );
  461. if ( pdomainName )
  462. {
  463. goto Found;
  464. }
  465. }
  466. #endif
  467. status = Reg_GetValue(
  468. NULL, // don't send whole session
  469. psession->hTcpip, // send TCPIP key explicitly
  470. RegIdDomainName,
  471. REGTYPE_DNS_NAME,
  472. (PBYTE *) &pdomainName );
  473. Found:
  474. // dump name if empty\useless
  475. if ( pdomainName &&
  476. ( strlen( pdomainName ) == 0 ) )
  477. {
  478. FREE_HEAP( pdomainName );
  479. pdomainName = NULL;
  480. }
  481. Done:
  482. DNSDBG( TRACE, ( "Read PDN = %s\n", pdomainName ));
  483. // set domain name OUT param
  484. *ppPrimaryDomainName = pdomainName;
  485. // cleanup any regkey's opened
  486. if ( psession == &session )
  487. {
  488. Reg_CloseSession( psession );
  489. }
  490. return( status );
  491. }
  492. BOOL
  493. Reg_IsMicrosoftDnsServer(
  494. VOID
  495. )
  496. /*++
  497. Routine Description:
  498. Read registry to determine if MS DNS server.
  499. Arguments:
  500. None
  501. Return Value:
  502. ERROR_SUCCESS if successful.
  503. Error code on failure.
  504. --*/
  505. {
  506. DWORD status = NO_ERROR;
  507. HKEY hkey = NULL;
  508. //
  509. // open services key to determine whether the DNS server is installed.
  510. //
  511. // DCR: read DNS server only once
  512. // - however need some sort of callback so we can pick this up
  513. // after install
  514. //
  515. status = RegOpenKeyExW(
  516. HKEY_LOCAL_MACHINE,
  517. DNS_SERVER_KEY,
  518. 0,
  519. KEY_QUERY_VALUE,
  520. &hkey );
  521. if ( status != ERROR_SUCCESS )
  522. {
  523. return FALSE;
  524. }
  525. RegCloseKey( hkey );
  526. return TRUE;
  527. }
  528. //
  529. // Reg info read.
  530. // These are read routines for info beyond flat globals.
  531. //
  532. // Three types of info:
  533. // - global
  534. // - adapter specific
  535. // - update
  536. //
  537. DNS_STATUS
  538. Reg_ReadGlobalInfo(
  539. IN PREG_SESSION pRegSession,
  540. OUT PREG_GLOBAL_INFO pRegInfo
  541. )
  542. /*++
  543. Routine Description:
  544. Read DNS registry info, not read in flat read.
  545. This covers all the allocated stuff, plus policy
  546. stuff for adapter info.
  547. -- primary domain name
  548. -- adapter policy
  549. - domain name
  550. - DNS servers
  551. - flag overrides
  552. Arguments:
  553. pRegSession -- registry session
  554. pRegInfo -- blob to hold reg info
  555. Return Value:
  556. ERROR_SUCCESS if successful.
  557. Error code on failure.
  558. --*/
  559. {
  560. DNS_STATUS status;
  561. REG_SESSION regSession;
  562. PREG_SESSION pregSession = pRegSession;
  563. HKEY hkeyPolicy = NULL;
  564. DNSDBG( TRACE, (
  565. "Dns_ReadRegInfo( %p, %p )\n",
  566. pRegSession,
  567. pRegInfo ));
  568. //
  569. // clear reg info blob
  570. //
  571. RtlZeroMemory(
  572. pRegInfo,
  573. sizeof( *pRegInfo ) );
  574. //
  575. // open the registry
  576. //
  577. if ( !pregSession )
  578. {
  579. pregSession = &regSession;
  580. status = Reg_OpenSession(
  581. pregSession,
  582. 0,
  583. 0 );
  584. if ( status != ERROR_SUCCESS )
  585. {
  586. return( status );
  587. }
  588. }
  589. //
  590. // if not read force registry read
  591. //
  592. status = Reg_ReadGlobalsEx(
  593. 0, // no flag, read it all
  594. pregSession
  595. );
  596. //
  597. // primary domain name
  598. //
  599. Reg_ReadPrimaryDomainName(
  600. pregSession,
  601. NULL, // no specific key
  602. & pRegInfo->pszPrimaryDomainName
  603. );
  604. //
  605. // host name
  606. //
  607. Reg_GetValue(
  608. pregSession,
  609. NULL, // no key
  610. RegIdHostName,
  611. REGTYPE_DNS_NAME,
  612. & pRegInfo->pszHostName
  613. );
  614. //
  615. // pick up required registry values from globals
  616. //
  617. pRegInfo->fUseNameDevolution = g_UseNameDevolution;
  618. pRegInfo->fUseMulticast = g_UseMulticast;
  619. pRegInfo->fUseMulticastOnNameError = g_MulticastOnNameError;
  620. pRegInfo->fUseDotLocalDomain = g_UseDotLocalDomain;
  621. //
  622. // policy overrides for adapter info
  623. // - enable adapter registration
  624. // - DNS servers
  625. // - domain name
  626. //
  627. // note, we need both value and found\not-found flag
  628. // as value overrides only when it exists
  629. //
  630. hkeyPolicy = pregSession->hPolicy;
  631. if ( !hkeyPolicy )
  632. {
  633. goto Done;
  634. }
  635. //
  636. // policy for register adapter name?
  637. //
  638. status = Reg_GetDword(
  639. NULL, // no session
  640. hkeyPolicy, // policy
  641. NULL, // no adapter
  642. RegIdRegisterAdapterName,
  643. & pRegInfo->fRegisterAdapterName
  644. );
  645. if ( status == ERROR_SUCCESS )
  646. {
  647. pRegInfo->fPolicyRegisterAdapterName = TRUE;
  648. }
  649. //
  650. // policy for adapter domain name?
  651. //
  652. status = Reg_GetValue(
  653. NULL, // no session
  654. hkeyPolicy,
  655. RegIdAdapterDomainName,
  656. REGTYPE_DNS_NAME,
  657. (PBYTE *) &pRegInfo->pszAdapterDomainName
  658. );
  659. //
  660. // policy for adapter DNS server lists
  661. //
  662. status = Reg_GetIpArray(
  663. NULL, // no session
  664. hkeyPolicy,
  665. NULL, // no adapter
  666. RegIdDnsServers,
  667. REG_SZ,
  668. &pRegInfo->pDnsServerArray
  669. );
  670. Done:
  671. // if opened session -- close
  672. if ( pregSession && !pRegSession )
  673. {
  674. Reg_CloseSession( pregSession );
  675. }
  676. DNSDBG( TRACE, (
  677. "Leave Reg_ReadGlobalInfo()\n"
  678. "\tPDN = %s\n"
  679. "\tPolicy:\n"
  680. "\t\tRegister Adapter = %d\n"
  681. "\t\tAdapterName = %s\n"
  682. "\t\tDNS servers = %p\n",
  683. pRegInfo->pszPrimaryDomainName,
  684. pRegInfo->fRegisterAdapterName,
  685. pRegInfo->pszAdapterDomainName,
  686. pRegInfo->pDnsServerArray
  687. ));
  688. return ERROR_SUCCESS;
  689. }
  690. VOID
  691. Reg_FreeGlobalInfo(
  692. IN OUT PREG_GLOBAL_INFO pRegInfo,
  693. IN BOOL fFreeBlob
  694. )
  695. /*++
  696. Routine Description:
  697. Free registry adapter policy info blob.
  698. Arguments:
  699. pRegInfo -- adapter policy blob to free
  700. fFreeBlob -- flag to free blob itself
  701. FALSE -- just free allocated data fields
  702. TRUE -- also free blob itself
  703. Return Value:
  704. ERROR_SUCCESS if successful.
  705. Error code on failure.
  706. --*/
  707. {
  708. DNSDBG( TRACE, (
  709. "Reg_FreeGlobalInfo( %p )\n",
  710. pRegInfo ));
  711. // allow sloppy cleanup
  712. if ( !pRegInfo )
  713. {
  714. return;
  715. }
  716. //
  717. // free data
  718. // - primary DNS name
  719. // - policy adapter name
  720. // - policy DNS server list
  721. //
  722. if ( pRegInfo->pszPrimaryDomainName )
  723. {
  724. FREE_HEAP( pRegInfo->pszPrimaryDomainName );
  725. }
  726. if ( pRegInfo->pszHostName )
  727. {
  728. FREE_HEAP( pRegInfo->pszHostName );
  729. }
  730. if ( pRegInfo->pszAdapterDomainName )
  731. {
  732. FREE_HEAP( pRegInfo->pszAdapterDomainName );
  733. }
  734. if ( pRegInfo->pDnsServerArray )
  735. {
  736. FREE_HEAP( pRegInfo->pDnsServerArray );
  737. }
  738. // free blob itself
  739. if ( fFreeBlob )
  740. {
  741. FREE_HEAP( pRegInfo );
  742. }
  743. }
  744. DNS_STATUS
  745. Reg_ReadAdapterInfo(
  746. IN PSTR pszAdapterName,
  747. IN PREG_SESSION pRegSession,
  748. IN PREG_GLOBAL_INFO pRegInfo,
  749. OUT PREG_ADAPTER_INFO pBlob
  750. )
  751. /*++
  752. Routine Description:
  753. Read adapter registry info.
  754. Arguments:
  755. pszAdapterName -- adapter name (registry name)
  756. pRegSession -- registry session
  757. pRegInfo -- registry global info
  758. pBlob -- adapter info blob to fill in
  759. Return Value:
  760. ERROR_SUCCESS if successful.
  761. Error code on failure.
  762. --*/
  763. {
  764. DNS_STATUS status;
  765. HKEY hkeyAdapter = NULL;
  766. PSTR padapterDomainName = NULL;
  767. CHAR adapterParamKey[ MAX_PATH ];
  768. DNSDBG( TRACE, (
  769. "ReadRegAdapterInfo( %s, %p, %p, %p )\n",
  770. pszAdapterName,
  771. pRegSession,
  772. pRegInfo,
  773. pBlob ));
  774. //
  775. // clear adapter blob
  776. //
  777. RtlZeroMemory(
  778. pBlob,
  779. sizeof(*pBlob) );
  780. //
  781. // bail if no adapter
  782. //
  783. // note: this check\bail is only in place to allow call to
  784. // Reg_ReadUpdateInfo() to be made in asyncreg.c without
  785. // specifying an adapter; this allows us to make the call
  786. // before the adapter check and therefore skip a separate
  787. // registry op to get current g_IsDnsServer global;
  788. // no actual use will be made of REG_ADAPTER_INFO blob
  789. if ( !pszAdapterName )
  790. {
  791. return ERROR_SUCCESS;
  792. }
  793. //
  794. // open adapter key for read
  795. //
  796. strcpy( adapterParamKey, TCPIP_INTERFACES_KEY_A );
  797. strcat( adapterParamKey, pszAdapterName );
  798. status = RegOpenKeyExA(
  799. HKEY_LOCAL_MACHINE,
  800. adapterParamKey,
  801. 0,
  802. KEY_READ,
  803. &hkeyAdapter );
  804. if ( status != NO_ERROR )
  805. {
  806. return( status );
  807. }
  808. //
  809. // query with adapter name
  810. // - OFF global overrides
  811. //
  812. pBlob->fQueryAdapterName = g_QueryAdapterName;
  813. if ( g_QueryAdapterName )
  814. {
  815. Reg_GetDword(
  816. NULL, // no session,
  817. hkeyAdapter, // explicit key
  818. NULL, // no adapter name
  819. RegIdQueryAdapterName,
  820. & pBlob->fQueryAdapterName );
  821. }
  822. //
  823. // check if adapter IPs get registered
  824. // - OFF global overrides
  825. //
  826. pBlob->fRegistrationEnabled = g_RegistrationEnabled;
  827. if ( g_RegistrationEnabled )
  828. {
  829. Reg_GetDword(
  830. NULL, // no session,
  831. hkeyAdapter, // explicit key
  832. NULL, // no adapter name
  833. RegIdRegistrationEnabled,
  834. & pBlob->fRegistrationEnabled );
  835. }
  836. //
  837. // adapter name registration
  838. // - policy may override
  839. // - OFF global overrides
  840. // - then adapter
  841. //
  842. if ( pRegInfo->fPolicyRegisterAdapterName )
  843. {
  844. pBlob->fRegisterAdapterName = pRegInfo->fRegisterAdapterName;
  845. }
  846. else
  847. {
  848. pBlob->fRegisterAdapterName = g_RegisterAdapterName;
  849. if ( g_RegisterAdapterName )
  850. {
  851. Reg_GetDword(
  852. NULL, // no open session,
  853. hkeyAdapter, // open key
  854. NULL, // no adapter name
  855. RegIdRegisterAdapterName,
  856. & pBlob->fRegisterAdapterName );
  857. }
  858. }
  859. //
  860. // max addresses to register
  861. //
  862. // DCR: RegistrationAddrCount -- adapter or global sets high\low?
  863. //
  864. if ( pBlob->fRegistrationEnabled )
  865. {
  866. Reg_GetDword(
  867. NULL, // no session,
  868. hkeyAdapter, // explicit key
  869. NULL, // no adapter name
  870. RegIdRegistrationMaxAddressCount,
  871. & pBlob->RegistrationMaxAddressCount );
  872. #if 0
  873. if ( g_RegistrationMaxAddressCount >
  874. pBlob->RegistrationMaxAddressCount )
  875. {
  876. pBlob->RegistrationMaxAddressCount = g_RegistrationMaxAddressCount;
  877. }
  878. #endif
  879. }
  880. //
  881. // get adapter name
  882. // - policy may override AND
  883. // allow policy to override with NULL string to kill domain name
  884. //
  885. if ( pRegInfo->pszAdapterDomainName )
  886. {
  887. if ( IS_EMPTY_STRING( pRegInfo->pszAdapterDomainName ) )
  888. {
  889. padapterDomainName = NULL;
  890. }
  891. else
  892. {
  893. padapterDomainName = DnsCreateStringCopy(
  894. pRegInfo->pszAdapterDomainName,
  895. 0 );
  896. }
  897. }
  898. else
  899. {
  900. //
  901. // static domain name set on adapter?
  902. //
  903. status = Reg_GetValueEx(
  904. NULL, // no session
  905. hkeyAdapter,
  906. NULL, // no adapter name
  907. RegIdStaticDomainName,
  908. REGTYPE_DNS_NAME,
  909. DNSREG_FLAG_DUMP_EMPTY, // dump empty string
  910. (PBYTE *) &padapterDomainName
  911. );
  912. if ( status != ERROR_SUCCESS )
  913. {
  914. DNS_ASSERT( padapterDomainName == NULL );
  915. padapterDomainName = NULL;
  916. }
  917. //
  918. // if no static name, use DHCP name
  919. //
  920. if ( ! padapterDomainName )
  921. {
  922. status = Reg_GetValueEx(
  923. NULL, // no session
  924. hkeyAdapter,
  925. NULL, // no adapter
  926. RegIdDhcpDomainName,
  927. REGTYPE_DNS_NAME,
  928. DNSREG_FLAG_DUMP_EMPTY, // dump if empty string
  929. (PBYTE *) &padapterDomainName );
  930. if ( status != ERROR_SUCCESS )
  931. {
  932. DNS_ASSERT( padapterDomainName == NULL );
  933. padapterDomainName = NULL;
  934. }
  935. }
  936. }
  937. //
  938. // set adapter name in info blob
  939. //
  940. pBlob->pszAdapterDomainName = padapterDomainName;
  941. //
  942. // cleanup
  943. //
  944. if ( hkeyAdapter )
  945. {
  946. RegCloseKey( hkeyAdapter );
  947. }
  948. DNSDBG( TRACE, (
  949. "Leave Dns_ReadRegAdapterInfo()\n"
  950. "\tDomainName = %s\n"
  951. "\tQueryAdapterName = %d\n"
  952. "\tRegistrationEnabled = %d\n"
  953. "\tRegisterAdapterName = %d\n"
  954. "\tRegisterAddrCount = %d\n",
  955. pBlob->pszAdapterDomainName,
  956. pBlob->fQueryAdapterName,
  957. pBlob->fRegistrationEnabled,
  958. pBlob->fRegisterAdapterName,
  959. pBlob->RegistrationMaxAddressCount
  960. ));
  961. return ERROR_SUCCESS;
  962. }
  963. VOID
  964. Reg_FreeAdapterInfo(
  965. IN OUT PREG_ADAPTER_INFO pRegAdapterInfo,
  966. IN BOOL fFreeBlob
  967. )
  968. /*++
  969. Routine Description:
  970. Free registry adapter info blob.
  971. Arguments:
  972. pRegAdapterInfo -- adapter registry info blob to free
  973. fFreeBlob -- flag to free blob itself
  974. FALSE -- just free allocated data fields
  975. TRUE -- also free blob itself
  976. Return Value:
  977. ERROR_SUCCESS if successful.
  978. Error code on failure.
  979. --*/
  980. {
  981. DNSDBG( TRACE, (
  982. "FreeRegAdapterInfo( %p )\n",
  983. pRegAdapterInfo ));
  984. //
  985. // free data
  986. // - adapter domain name
  987. //
  988. if ( pRegAdapterInfo->pszAdapterDomainName )
  989. {
  990. FREE_HEAP( pRegAdapterInfo->pszAdapterDomainName );
  991. pRegAdapterInfo->pszAdapterDomainName = NULL;
  992. }
  993. // free blob itself
  994. if ( fFreeBlob )
  995. {
  996. FREE_HEAP( pRegAdapterInfo );
  997. }
  998. }
  999. DNS_STATUS
  1000. Reg_ReadUpdateInfo(
  1001. IN PSTR pszAdapterName,
  1002. OUT PREG_UPDATE_INFO pUpdateInfo
  1003. )
  1004. /*++
  1005. Routine Description:
  1006. Read update info.
  1007. //
  1008. // DCR: shouldn't need this routine, just get NETINFO
  1009. // this blob is just mix of global stuff and
  1010. // mostly adapter stuff
  1011. // even if want in single blob for update routines --
  1012. // ok, but not ideal --
  1013. // should be getting blob from resolver and reformatting
  1014. // info;
  1015. // reg read should happen just once producing network
  1016. // info in resolver
  1017. //
  1018. Arguments:
  1019. pszAdapterName -- adapter name
  1020. pUpdateInfo -- blob to hold reg info
  1021. Return Value:
  1022. ERROR_SUCCESS if successful.
  1023. Error code on failure.
  1024. --*/
  1025. {
  1026. DNS_STATUS status;
  1027. REG_SESSION regSession;
  1028. PREG_SESSION pregSession;
  1029. REG_GLOBAL_INFO regInfo;
  1030. REG_ADAPTER_INFO regAdapterInfo;
  1031. BOOL freadRegInfo = FALSE;
  1032. BOOL freadRegAdapterInfo = FALSE;
  1033. DNSDBG( TRACE, (
  1034. "Dns_ReadUpdateInfo( %s, %p )\n",
  1035. pszAdapterName,
  1036. pUpdateInfo ));
  1037. //
  1038. // clear update info blob
  1039. //
  1040. RtlZeroMemory(
  1041. pUpdateInfo,
  1042. sizeof( *pUpdateInfo ) );
  1043. //
  1044. // open the registry
  1045. //
  1046. pregSession = &regSession;
  1047. status = Reg_OpenSession(
  1048. pregSession,
  1049. 0,
  1050. 0 );
  1051. if ( status != ERROR_SUCCESS )
  1052. {
  1053. return( status );
  1054. }
  1055. //
  1056. // read registry
  1057. // - global DWORDs
  1058. // - global info
  1059. // - adapter specific info
  1060. //
  1061. // DCR_PERF: global read should be RPC
  1062. // DCR_REG: fix this with reg read
  1063. // have flag for IN caching resolver process (skip RPC)
  1064. // have cookie for last read
  1065. //
  1066. #if 0
  1067. // Reg_ReadGlobalInfo() calls Reg_ReadGlobalsEx()
  1068. status = Reg_ReadGlobalsEx(
  1069. 0, // no flag, update variables desired
  1070. pregSession
  1071. );
  1072. #endif
  1073. status = Reg_ReadGlobalInfo(
  1074. pregSession,
  1075. & regInfo );
  1076. if ( status != ERROR_SUCCESS )
  1077. {
  1078. goto Done;
  1079. }
  1080. freadRegInfo = TRUE;
  1081. status = Reg_ReadAdapterInfo(
  1082. pszAdapterName,
  1083. pregSession,
  1084. & regInfo,
  1085. & regAdapterInfo );
  1086. if ( status != ERROR_SUCCESS )
  1087. {
  1088. goto Done;
  1089. }
  1090. freadRegAdapterInfo = TRUE;
  1091. //
  1092. // alternate computer name
  1093. //
  1094. Reg_GetValue(
  1095. pregSession,
  1096. NULL, // no key
  1097. RegIdAlternateNames,
  1098. REGTYPE_ALTERNATE_NAMES,
  1099. & pUpdateInfo->pmszAlternateNames
  1100. );
  1101. //
  1102. // set update results
  1103. // - PDN always needed
  1104. // - adapter domain if policy override
  1105. // - DNS servers if policy override
  1106. //
  1107. // note, in all cases we don't realloc, we steal the
  1108. // info and NULL it out so not freed on cleanup
  1109. //
  1110. pUpdateInfo->pszPrimaryDomainName = regInfo.pszPrimaryDomainName;
  1111. regInfo.pszPrimaryDomainName = NULL;
  1112. pUpdateInfo->pszAdapterDomainName = regInfo.pszAdapterDomainName;
  1113. regInfo.pszAdapterDomainName = NULL;
  1114. pUpdateInfo->pDnsServerArray = regInfo.pDnsServerArray;
  1115. regInfo.pDnsServerArray = NULL;
  1116. pUpdateInfo->pDnsServerIp6Array = regInfo.pDnsServerIp6Array;
  1117. regInfo.pDnsServerIp6Array = NULL;
  1118. // update flags
  1119. pUpdateInfo->fRegistrationEnabled = regAdapterInfo.fRegistrationEnabled;
  1120. pUpdateInfo->fRegisterAdapterName = regAdapterInfo.fRegisterAdapterName;
  1121. pUpdateInfo->RegistrationMaxAddressCount =
  1122. regAdapterInfo.RegistrationMaxAddressCount;
  1123. Done:
  1124. //
  1125. // cleanup
  1126. //
  1127. if ( pregSession )
  1128. {
  1129. Reg_CloseSession( pregSession );
  1130. }
  1131. // don't free blobs -- they're on stack
  1132. if ( freadRegInfo )
  1133. {
  1134. Reg_FreeGlobalInfo( &regInfo, FALSE );
  1135. }
  1136. if ( freadRegAdapterInfo )
  1137. {
  1138. Reg_FreeAdapterInfo( &regAdapterInfo, FALSE );
  1139. }
  1140. DNSDBG( TRACE, (
  1141. "Leave Dns_ReadUpdateInfo()\n"
  1142. "\tPDN = %s\n"
  1143. "\tAlternateNames = %s\n"
  1144. "\tAdapterName = %s\n"
  1145. "\tDNS servers = %p\n"
  1146. "\tDNS servers IP6 = %p\n"
  1147. "\tRegister = %d\n"
  1148. "\tRegisterAdapterName = %d\n"
  1149. "\tRegisterAddrCount = %d\n",
  1150. pUpdateInfo->pszPrimaryDomainName,
  1151. pUpdateInfo->pmszAlternateNames,
  1152. pUpdateInfo->pszAdapterDomainName,
  1153. pUpdateInfo->pDnsServerArray,
  1154. pUpdateInfo->pDnsServerIp6Array,
  1155. pUpdateInfo->fRegistrationEnabled,
  1156. pUpdateInfo->fRegisterAdapterName,
  1157. pUpdateInfo->RegistrationMaxAddressCount
  1158. ));
  1159. return ERROR_SUCCESS;
  1160. }
  1161. VOID
  1162. Reg_FreeUpdateInfo(
  1163. IN OUT PREG_UPDATE_INFO pUpdateInfo,
  1164. IN BOOL fFreeBlob
  1165. )
  1166. /*++
  1167. Routine Description:
  1168. Free registry update info blob.
  1169. Arguments:
  1170. pUpdateInfo -- update registry info blob to free
  1171. fFreeBlob -- flag to free blob itself
  1172. FALSE -- just free allocated data fields
  1173. TRUE -- also free blob itself
  1174. Return Value:
  1175. ERROR_SUCCESS if successful.
  1176. Error code on failure.
  1177. --*/
  1178. {
  1179. DNSDBG( TRACE, (
  1180. "FreeRegUpdateInfo( %p )\n",
  1181. pUpdateInfo ));
  1182. //
  1183. // free data
  1184. // - PDN
  1185. // - adapter domain name
  1186. // - DNS server lists
  1187. //
  1188. if ( pUpdateInfo->pszPrimaryDomainName )
  1189. {
  1190. FREE_HEAP( pUpdateInfo->pszPrimaryDomainName );
  1191. }
  1192. if ( pUpdateInfo->pmszAlternateNames )
  1193. {
  1194. FREE_HEAP( pUpdateInfo->pmszAlternateNames );
  1195. }
  1196. if ( pUpdateInfo->pszAdapterDomainName )
  1197. {
  1198. FREE_HEAP( pUpdateInfo->pszAdapterDomainName );
  1199. }
  1200. if ( pUpdateInfo->pDnsServerArray )
  1201. {
  1202. FREE_HEAP( pUpdateInfo->pDnsServerArray );
  1203. }
  1204. if ( pUpdateInfo->pDnsServerIp6Array )
  1205. {
  1206. FREE_HEAP( pUpdateInfo->pDnsServerIp6Array );
  1207. }
  1208. // free blob itself
  1209. if ( fFreeBlob )
  1210. {
  1211. FREE_HEAP( pUpdateInfo );
  1212. }
  1213. }
  1214. //
  1215. // Special
  1216. //
  1217. DNS_STATUS
  1218. Reg_WriteLoopbackDnsServerList(
  1219. IN PSTR pszAdapterName,
  1220. IN PREG_SESSION pRegSession
  1221. )
  1222. /*++
  1223. Routine Description:
  1224. Write loopback IP as DNS server list.
  1225. Arguments:
  1226. pszAdapterName -- adapter name (registry name)
  1227. pRegSession -- registry session
  1228. Return Value:
  1229. ERROR_SUCCESS if successful.
  1230. Error code on failure.
  1231. --*/
  1232. {
  1233. DNS_STATUS status;
  1234. HKEY hkeyAdapter = NULL;
  1235. CHAR adapterParamKey[ MAX_PATH ];
  1236. CHAR nameServerString[ IP4_ADDRESS_STRING_LENGTH+1 ];
  1237. DNSDBG( TRACE, (
  1238. "WriteLookupbackDnsServerList( %s )\n",
  1239. pszAdapterName ));
  1240. //
  1241. // open adapter key for write
  1242. //
  1243. strcpy( adapterParamKey, TCPIP_INTERFACES_KEY_A );
  1244. strcat( adapterParamKey, pszAdapterName );
  1245. status = RegOpenKeyExA(
  1246. HKEY_LOCAL_MACHINE,
  1247. adapterParamKey,
  1248. 0,
  1249. KEY_READ | KEY_WRITE,
  1250. & hkeyAdapter );
  1251. if ( status != NO_ERROR )
  1252. {
  1253. return( status );
  1254. }
  1255. //
  1256. // write loopback address
  1257. //
  1258. strcpy( nameServerString, "127.0.0.1" );
  1259. status = RegSetValueExA(
  1260. hkeyAdapter,
  1261. STATIC_NAME_SERVER_VALUE_A,
  1262. 0,
  1263. REGTYPE_DNS_SERVER,
  1264. (PBYTE) nameServerString,
  1265. (strlen(nameServerString)+1) * sizeof(CHAR) );
  1266. RegCloseKey( hkeyAdapter );
  1267. return( status );
  1268. }
  1269. //
  1270. // PDN Query
  1271. //
  1272. PSTR
  1273. WINAPI
  1274. Reg_GetPrimaryDomainName(
  1275. IN DNS_CHARSET CharSet
  1276. )
  1277. /*++
  1278. Routine Description:
  1279. Get primary domain name (PDN).
  1280. Arguments:
  1281. CharSet -- desired char set.
  1282. Return Value:
  1283. Ptr to primary domain name in desired charset.
  1284. --*/
  1285. {
  1286. DNS_STATUS status;
  1287. PSTR pnameWire = NULL;
  1288. PSTR pnameReturn;
  1289. status = Reg_ReadPrimaryDomainName(
  1290. NULL, // no session
  1291. NULL, // no regkey
  1292. &pnameWire );
  1293. if ( !pnameWire )
  1294. {
  1295. SetLastError( status );
  1296. return NULL;
  1297. }
  1298. //
  1299. // convert to desired char set
  1300. //
  1301. if ( CharSet == DnsCharSetWire )
  1302. {
  1303. return pnameWire;
  1304. }
  1305. else
  1306. {
  1307. pnameReturn = Dns_NameCopyAllocate(
  1308. pnameWire,
  1309. 0,
  1310. DnsCharSetWire,
  1311. CharSet );
  1312. FREE_HEAP( pnameWire );
  1313. return pnameReturn;
  1314. }
  1315. }
  1316. //
  1317. // Hostname query
  1318. //
  1319. PSTR
  1320. WINAPI
  1321. Reg_GetHostName(
  1322. IN DNS_CHARSET CharSet
  1323. )
  1324. /*++
  1325. Routine Description:
  1326. Get host name.
  1327. Arguments:
  1328. CharSet -- desired char set.
  1329. Return Value:
  1330. Ptr to host name in desired charset.
  1331. --*/
  1332. {
  1333. PSTR pnameWire = NULL;
  1334. PSTR pnameReturn;
  1335. DNS_STATUS status;
  1336. //
  1337. // get hostname from registry
  1338. //
  1339. status = Reg_GetValue(
  1340. NULL, // no session
  1341. NULL, // no key
  1342. RegIdHostName,
  1343. REGTYPE_DNS_NAME,
  1344. (PBYTE *) &pnameWire
  1345. );
  1346. if ( !pnameWire )
  1347. {
  1348. SetLastError( status );
  1349. return NULL;
  1350. }
  1351. //
  1352. // convert to desired char set
  1353. //
  1354. if ( CharSet == DnsCharSetWire )
  1355. {
  1356. return pnameWire;
  1357. }
  1358. else
  1359. {
  1360. pnameReturn = Dns_NameCopyAllocate(
  1361. pnameWire,
  1362. 0,
  1363. DnsCharSetWire,
  1364. CharSet );
  1365. FREE_HEAP( pnameWire );
  1366. return pnameReturn;
  1367. }
  1368. }
  1369. PSTR
  1370. WINAPI
  1371. Reg_GetFullHostName(
  1372. IN DNS_CHARSET CharSet
  1373. )
  1374. /*++
  1375. Routine Description:
  1376. Get full host name.
  1377. Arguments:
  1378. CharSet -- desired char set.
  1379. Return Value:
  1380. Ptr to full host name in desired charset.
  1381. --*/
  1382. {
  1383. PSTR pnameWire = NULL;
  1384. PSTR pdomainWire = NULL;
  1385. PSTR presult = NULL;
  1386. DNS_STATUS status;
  1387. CHAR nameBuffer[ DNS_MAX_NAME_BUFFER_LENGTH+4 ];
  1388. //
  1389. // get hostname from registry
  1390. //
  1391. status = Reg_GetValue(
  1392. NULL, // no session
  1393. NULL, // no key
  1394. RegIdHostName,
  1395. REGTYPE_DNS_NAME,
  1396. (PBYTE *) &pnameWire
  1397. );
  1398. if ( !pnameWire )
  1399. {
  1400. SetLastError( status );
  1401. return NULL;
  1402. }
  1403. //
  1404. // get domain name from registry
  1405. //
  1406. status = Reg_ReadPrimaryDomainName(
  1407. NULL, // no session
  1408. NULL, // no regkey
  1409. &pdomainWire );
  1410. if ( !pdomainWire )
  1411. {
  1412. SetLastError( status );
  1413. return NULL;
  1414. }
  1415. //
  1416. // create appended name
  1417. // - wire format is narrow
  1418. //
  1419. // allocate result in desired char set
  1420. //
  1421. if ( Dns_NameAppend_A(
  1422. nameBuffer,
  1423. DNS_MAX_NAME_BUFFER_LENGTH,
  1424. pnameWire,
  1425. pdomainWire ) )
  1426. {
  1427. presult = Dns_NameCopyAllocate(
  1428. nameBuffer,
  1429. 0,
  1430. DnsCharSetWire,
  1431. CharSet );
  1432. }
  1433. //
  1434. // free registry allocations
  1435. //
  1436. FREE_HEAP( pnameWire );
  1437. FREE_HEAP( pdomainWire );
  1438. return presult;
  1439. }
  1440. //
  1441. // DWORD Get\Set
  1442. //
  1443. DWORD
  1444. Reg_ReadDwordValueFromGlobal(
  1445. IN DWORD PropId
  1446. )
  1447. /*++
  1448. Routine Description:
  1449. Read DWORD from global.
  1450. This is direct access to global through RegId,
  1451. rather than by name.
  1452. Arguments:
  1453. PropId -- property ID of desired value
  1454. Return Value:
  1455. ERROR_SUCCESS if successful.
  1456. ErrorCode on failure.
  1457. --*/
  1458. {
  1459. PDWORD pdword;
  1460. //
  1461. // validate PropId -- within DWORD array
  1462. //
  1463. if ( PropId > RegIdValueMax )
  1464. {
  1465. DNS_ASSERT( FALSE );
  1466. return( 0 );
  1467. }
  1468. //
  1469. // get DWORD ptr and read value (if exists)
  1470. //
  1471. pdword = RegDwordPtrArray[ PropId ];
  1472. if ( !pdword )
  1473. {
  1474. DNS_ASSERT( FALSE );
  1475. return( 0 );
  1476. }
  1477. return( *pdword );
  1478. }
  1479. DWORD
  1480. Reg_ReadDwordProperty(
  1481. IN DNS_REGID RegId,
  1482. IN PWSTR pwsAdapterName OPTIONAL
  1483. )
  1484. /*++
  1485. Routine Description:
  1486. Read through to registry for DWORD\BOOL value.
  1487. Simplified interface for DWORD reads.
  1488. Arguments:
  1489. RegId -- registry ID of value
  1490. pwsAdapterName -- adapter name if adapter specific registration
  1491. value is desired
  1492. Return Value:
  1493. Value for global -- from registry or defaulted
  1494. --*/
  1495. {
  1496. DWORD value;
  1497. //
  1498. // read value
  1499. //
  1500. Reg_GetDword(
  1501. NULL, // no session
  1502. NULL, // no key given
  1503. pwsAdapterName,
  1504. RegId,
  1505. & value );
  1506. return( value );
  1507. }
  1508. DNS_STATUS
  1509. WINAPI
  1510. Reg_SetDwordPropertyAndAlertCache(
  1511. IN PWSTR pwsKey,
  1512. IN DWORD RegId,
  1513. IN DWORD dwValue
  1514. )
  1515. /*++
  1516. Routine Description:
  1517. Write DWORD property -- cause cache to reload config.
  1518. Arguments:
  1519. pwsRey -- key or adapater name to set
  1520. RegId -- reg id
  1521. dwValue -- value to set
  1522. Return Value:
  1523. None.
  1524. --*/
  1525. {
  1526. DNS_STATUS status;
  1527. // set value
  1528. status = Reg_SetDwordValue(
  1529. NULL, // reserved
  1530. NULL, // no open key
  1531. pwsKey,
  1532. RegId,
  1533. dwValue );
  1534. //
  1535. // if reg write successful
  1536. // - poke cache
  1537. // - mark any local netinfo dirty
  1538. //
  1539. if ( status == NO_ERROR )
  1540. {
  1541. DnsNotifyResolverEx(
  1542. POKE_OP_UPDATE_NETINFO,
  1543. 0,
  1544. POKE_COOKIE_UPDATE_NETINFO,
  1545. NULL );
  1546. NetInfo_MarkDirty();
  1547. }
  1548. return status;
  1549. }
  1550. //
  1551. // Environment variable configuration
  1552. //
  1553. BOOL
  1554. Reg_ReadDwordEnvar(
  1555. IN DWORD Id,
  1556. OUT PENVAR_DWORD_INFO pEnvar
  1557. )
  1558. /*++
  1559. Routine Description:
  1560. Read DWORD environment variable.
  1561. Note: this function read environment variables that allow
  1562. per process control of registry configurable params.
  1563. The environment variable is assumed to be the same
  1564. as the regkey with Dns prepended ( Dns<regvalue name> ).
  1565. Ex. FilterClusterIp controlled with envar DnsFilterClusterIp.
  1566. Arguments:
  1567. Id -- registry ID (registry.h) of environment value to read
  1568. pEnvar -- ptr to blob to hold results
  1569. Return Value:
  1570. ERROR_SUCCESS if successful.
  1571. ErrorCode on failure.
  1572. --*/
  1573. {
  1574. DWORD count;
  1575. PWSTR pnameBuffer;
  1576. PWSTR pvarBuffer;
  1577. BOOL found = FALSE;
  1578. DNSDBG( TRACE, (
  1579. "Dns_ReadDwordEnvar( %d, %p )\n",
  1580. Id,
  1581. pEnvar ));
  1582. if ( Id > RegIdValueMax )
  1583. {
  1584. DNS_ASSERT( FALSE );
  1585. return FALSE;
  1586. }
  1587. //
  1588. // init struct (for not found)
  1589. //
  1590. pEnvar->Id = Id;
  1591. pEnvar->Value = 0;
  1592. //
  1593. // prepend "Dns" to reg value name to create environment var name
  1594. //
  1595. pnameBuffer = (PWSTR) ALLOCATE_HEAP( 2 * (sizeof(WCHAR) * MAX_PATH) );
  1596. if ( !pnameBuffer )
  1597. {
  1598. return FALSE;
  1599. }
  1600. pvarBuffer = pnameBuffer + MAX_PATH;
  1601. wcscpy( pnameBuffer, L"Dns" );
  1602. wcscpy( &pnameBuffer[3], REGPROP_NAME(Id) );
  1603. //
  1604. // lookup
  1605. //
  1606. // note: no handling of values greater than MAX_PATH
  1607. // assuming busted string
  1608. //
  1609. // DCR: could add base discrimination (scan for non-digit)
  1610. // or try decimal first
  1611. //
  1612. DNSDBG( TRACE, (
  1613. "Dns_ReadDwordEnvar() looking up %S.\n",
  1614. pnameBuffer ));
  1615. count = GetEnvironmentVariableW(
  1616. pnameBuffer,
  1617. pvarBuffer,
  1618. MAX_PATH );
  1619. if ( count && count < MAX_PATH )
  1620. {
  1621. pEnvar->Value = wcstoul( pvarBuffer, NULL, 10 );
  1622. found = TRUE;
  1623. }
  1624. pEnvar->fFound = found;
  1625. FREE_HEAP( pnameBuffer );
  1626. return found;
  1627. }
  1628. #if 0
  1629. //
  1630. // Remote resolver not currently supported
  1631. //
  1632. PWSTR
  1633. Reg_GetResolverAddress(
  1634. VOID
  1635. )
  1636. /*++
  1637. Routine Description:
  1638. Get address (string form) of remote resolver.
  1639. Arguments:
  1640. None
  1641. Return Value:
  1642. Ptr to string of remote resolver name.
  1643. --*/
  1644. {
  1645. PWSTR pnameResolver = NULL;
  1646. Reg_GetValueEx(
  1647. NULL, // no session
  1648. NULL, // no key
  1649. NULL, // no adapter
  1650. RegIdRemoteResolver,
  1651. REGTYPE_DNS_NAME,
  1652. DNSREG_FLAG_GET_UNICODE | DNSREG_FLAG_DUMP_EMPTY,
  1653. (PBYTE *) &pnameResolver
  1654. );
  1655. return pnameResolver;
  1656. }
  1657. #endif
  1658. //
  1659. // End regfig.c
  1660. //