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.

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