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.

761 lines
13 KiB

  1. /*++
  2. Copyright (c) 1996-2000 Microsoft Corporation
  3. Module Name:
  4. dnsapi.c
  5. Abstract:
  6. Domain Name System (DNS) API
  7. Dnsapi.dll infrastructure (init, shutdown, etc)
  8. Routines to access DNS resolver
  9. Author:
  10. GlennC 22-Jan-1997
  11. Revision History:
  12. Jim Gilroy (jamesg) March 2000 cleanup
  13. --*/
  14. #include "local.h"
  15. #include <lmcons.h>
  16. #define DNS_NET_FAILURE_CACHE_TIME 30 // Seconds
  17. //
  18. // Global Definitions
  19. //
  20. //
  21. // Globals
  22. //
  23. CRITICAL_SECTION g_RegistrationListCS;
  24. CRITICAL_SECTION g_RegistrationThreadCS;
  25. CRITICAL_SECTION g_QueueCS;
  26. CRITICAL_SECTION g_NetFailureCS;
  27. DWORD g_NetFailureTime;
  28. DNS_STATUS g_NetFailureStatus;
  29. IP_ADDRESS g_LastDNSServerUpdated = 0;
  30. //
  31. // Local Function Prototypes
  32. //
  33. BOOL
  34. DnsInitialize(
  35. VOID
  36. );
  37. VOID
  38. DnsCleanup(
  39. VOID
  40. );
  41. VOID
  42. ClearDnsCacheEntry_A (
  43. IN LPSTR,
  44. IN WORD );
  45. VOID
  46. ClearDnsCacheEntry_W (
  47. IN LPWSTR,
  48. IN WORD );
  49. VOID
  50. FreeRpcIpAddressList(
  51. IN PDNS_IP_ADDR_LIST );
  52. //
  53. // System public Network Information
  54. //
  55. // The dnsapi.dll interface is in config.c
  56. //
  57. PDNS_NETWORK_INFORMATION
  58. CreateNetworkInformation(
  59. IN DWORD cAdapterCount
  60. )
  61. /*++
  62. Routine Description:
  63. None.
  64. Arguments:
  65. None.
  66. Return Value:
  67. None.
  68. --*/
  69. {
  70. PDNS_NETWORK_INFORMATION pNetworkInfo = NULL;
  71. DWORD dwAdapterListBufLen = sizeof( DNS_NETWORK_INFORMATION ) -
  72. sizeof( PDNS_ADAPTER_INFORMATION ) +
  73. ( sizeof( PDNS_ADAPTER_INFORMATION ) *
  74. cAdapterCount );
  75. pNetworkInfo = (PDNS_NETWORK_INFORMATION) ALLOCATE_HEAP_ZERO(
  76. dwAdapterListBufLen );
  77. return pNetworkInfo;
  78. }
  79. PDNS_SEARCH_INFORMATION
  80. CreateSearchInformation(
  81. IN DWORD cNameCount,
  82. IN LPSTR pszName
  83. )
  84. {
  85. PDNS_SEARCH_INFORMATION pSearchInfo = NULL;
  86. DWORD dwSearchInfoBufLen = sizeof( DNS_SEARCH_INFORMATION ) -
  87. sizeof( LPSTR ) +
  88. ( sizeof( LPSTR ) *
  89. cNameCount );
  90. if ( ( cNameCount == 0 ) && ( ! pszName ) )
  91. {
  92. return NULL;
  93. }
  94. pSearchInfo =
  95. (PDNS_SEARCH_INFORMATION) ALLOCATE_HEAP_ZERO( dwSearchInfoBufLen );
  96. if ( ! pSearchInfo )
  97. {
  98. return NULL;
  99. }
  100. if ( pszName )
  101. {
  102. pSearchInfo->pszPrimaryDomainName = Dns_NameCopyAllocate(
  103. pszName,
  104. 0,
  105. DnsCharSetUtf8,
  106. DnsCharSetUtf8 );
  107. if ( ! pSearchInfo->pszPrimaryDomainName )
  108. {
  109. FREE_HEAP( pSearchInfo );
  110. return NULL;
  111. }
  112. }
  113. return pSearchInfo;
  114. }
  115. PDNS_SEARCH_INFORMATION
  116. CreateSearchInformationCopyFromList(
  117. IN PSEARCH_LIST pSearchList
  118. )
  119. /*++
  120. Routine Description:
  121. None.
  122. Arguments:
  123. None.
  124. Return Value:
  125. None.
  126. --*/
  127. {
  128. PDNS_SEARCH_INFORMATION pSearchInformation;
  129. DWORD iter;
  130. if ( ! pSearchList )
  131. {
  132. return NULL;
  133. }
  134. pSearchInformation = CreateSearchInformation(
  135. pSearchList->NameCount,
  136. pSearchList->pszDomainOrZoneName );
  137. if ( ! pSearchInformation )
  138. {
  139. return NULL;
  140. }
  141. for ( iter = 0; iter < pSearchList->NameCount; iter++ )
  142. {
  143. if ( pSearchList->SearchNameArray[iter].pszName )
  144. {
  145. pSearchInformation->aSearchListNames[iter] =
  146. Dns_NameCopyAllocate(
  147. pSearchList->SearchNameArray[iter].pszName,
  148. 0,
  149. DnsCharSetUtf8,
  150. DnsCharSetUtf8 );
  151. }
  152. if ( pSearchInformation->aSearchListNames[iter] )
  153. {
  154. pSearchInformation->cNameCount++;
  155. }
  156. }
  157. return pSearchInformation;
  158. }
  159. PDNS_ADAPTER_INFORMATION
  160. CreateAdapterInformation(
  161. IN DWORD cServerCount,
  162. IN DWORD dwFlags,
  163. IN LPSTR pszDomain,
  164. IN LPSTR pszGuidName
  165. )
  166. /*++
  167. Routine Description:
  168. None.
  169. Arguments:
  170. None.
  171. Return Value:
  172. None.
  173. --*/
  174. {
  175. PDNS_ADAPTER_INFORMATION pAdapter = NULL;
  176. DWORD dwAdapterInfoBufLen = sizeof( DNS_ADAPTER_INFORMATION ) -
  177. sizeof( DNS_SERVER_INFORMATION ) +
  178. ( sizeof( DNS_SERVER_INFORMATION ) *
  179. cServerCount );
  180. pAdapter = (PDNS_ADAPTER_INFORMATION)
  181. ALLOCATE_HEAP_ZERO( dwAdapterInfoBufLen );
  182. if ( ! pAdapter )
  183. {
  184. return NULL;
  185. }
  186. pAdapter->InfoFlags = dwFlags;
  187. pAdapter->cServerCount = 0;
  188. if ( pszDomain )
  189. {
  190. pAdapter->pszDomain = Dns_NameCopyAllocate(
  191. pszDomain,
  192. 0,
  193. DnsCharSetUtf8,
  194. DnsCharSetUtf8 );
  195. }
  196. if ( pszGuidName )
  197. {
  198. pAdapter->pszAdapterGuidName = Dns_NameCopyAllocate(
  199. pszGuidName,
  200. 0,
  201. DnsCharSetUtf8,
  202. DnsCharSetUtf8 );
  203. }
  204. return pAdapter;
  205. }
  206. PDNS_ADAPTER_INFORMATION
  207. CreateAdapterInformationCopyFromList(
  208. IN PDNS_ADAPTER pAdapter
  209. )
  210. /*++
  211. Routine Description:
  212. None.
  213. Arguments:
  214. None.
  215. Return Value:
  216. None.
  217. --*/
  218. {
  219. PDNS_ADAPTER_INFORMATION pAdapterInformation;
  220. DWORD iter;
  221. if ( ! pAdapter )
  222. {
  223. return NULL;
  224. }
  225. pAdapterInformation = CreateAdapterInformation(
  226. pAdapter->ServerCount,
  227. pAdapter->InfoFlags,
  228. pAdapter->pszAdapterDomain,
  229. pAdapter->pszAdapterGuidName );
  230. if ( ! pAdapterInformation )
  231. {
  232. return NULL;
  233. }
  234. pAdapterInformation->pIPAddresses =
  235. Dns_CreateIpArrayCopy( pAdapter->pAdapterIPAddresses );
  236. pAdapterInformation->pIPSubnetMasks =
  237. Dns_CreateIpArrayCopy( pAdapter->pAdapterIPSubnetMasks );
  238. for ( iter = 0; iter < pAdapter->ServerCount; iter++ )
  239. {
  240. pAdapterInformation->aipServers[iter].ipAddress =
  241. pAdapter->ServerArray[iter].IpAddress;
  242. pAdapterInformation->aipServers[iter].Priority =
  243. pAdapter->ServerArray[iter].Priority;
  244. }
  245. pAdapterInformation->cServerCount = pAdapter->ServerCount;
  246. return pAdapterInformation ;
  247. }
  248. PDNS_NETWORK_INFORMATION
  249. WINAPI
  250. GetNetworkInformation(
  251. VOID )
  252. /*++
  253. Routine Description:
  254. None.
  255. Arguments:
  256. None.
  257. Return Value:
  258. None.
  259. --*/
  260. {
  261. PDNS_NETINFO pNetInfo = GetNetworkInfo();
  262. DWORD iter;
  263. PDNS_NETWORK_INFORMATION pNetworkInformation = NULL;
  264. if ( !pNetInfo )
  265. {
  266. return NULL;
  267. }
  268. //
  269. // create Network Information of desired size
  270. // then copy entire structure
  271. //
  272. pNetworkInformation = CreateNetworkInformation( pNetInfo->AdapterCount );
  273. if ( ! pNetworkInformation )
  274. {
  275. goto Done;
  276. }
  277. pNetworkInformation->pSearchInformation =
  278. CreateSearchInformationCopyFromList( pNetInfo->pSearchList );
  279. for ( iter = 0; iter < pNetInfo->AdapterCount; iter++ )
  280. {
  281. pNetworkInformation->aAdapterInfoList[iter] =
  282. CreateAdapterInformationCopyFromList( pNetInfo->AdapterArray[iter] );
  283. if ( pNetworkInformation->aAdapterInfoList[iter] )
  284. {
  285. pNetworkInformation->cAdapterCount += 1;
  286. }
  287. }
  288. Done:
  289. NetInfo_Free( pNetInfo );
  290. return pNetworkInformation;
  291. }
  292. PDNS_SEARCH_INFORMATION
  293. WINAPI
  294. GetSearchInformation(
  295. VOID )
  296. /*++
  297. Routine Description:
  298. None.
  299. Arguments:
  300. None.
  301. Return Value:
  302. None.
  303. --*/
  304. {
  305. PDNS_NETINFO pNetInfo = GetNetworkInfo();
  306. PDNS_SEARCH_INFORMATION pSearchInformation = NULL;
  307. if ( !pNetInfo )
  308. {
  309. return NULL;
  310. }
  311. pSearchInformation = CreateSearchInformationCopyFromList(
  312. pNetInfo->pSearchList );
  313. NetInfo_Free( pNetInfo );
  314. return pSearchInformation;
  315. }
  316. VOID
  317. WINAPI
  318. FreeAdapterInformation(
  319. IN PDNS_ADAPTER_INFORMATION pAdapterInformation
  320. )
  321. /*++
  322. Routine Description:
  323. None.
  324. Arguments:
  325. None.
  326. Return Value:
  327. None.
  328. --*/
  329. {
  330. if ( pAdapterInformation )
  331. {
  332. if ( pAdapterInformation->pszAdapterGuidName )
  333. {
  334. FREE_HEAP( pAdapterInformation->pszAdapterGuidName );
  335. }
  336. if ( pAdapterInformation->pszDomain )
  337. {
  338. FREE_HEAP( pAdapterInformation->pszDomain );
  339. }
  340. if ( pAdapterInformation->pIPAddresses )
  341. {
  342. FREE_HEAP( pAdapterInformation->pIPAddresses );
  343. }
  344. if ( pAdapterInformation->pIPSubnetMasks )
  345. {
  346. FREE_HEAP( pAdapterInformation->pIPSubnetMasks );
  347. }
  348. FREE_HEAP( pAdapterInformation );
  349. }
  350. }
  351. VOID
  352. WINAPI
  353. FreeSearchInformation(
  354. IN PDNS_SEARCH_INFORMATION pSearchInformation
  355. )
  356. /*++
  357. Routine Description:
  358. None.
  359. Arguments:
  360. None.
  361. Return Value:
  362. None.
  363. --*/
  364. {
  365. DWORD iter;
  366. if ( pSearchInformation )
  367. {
  368. if ( pSearchInformation->pszPrimaryDomainName )
  369. {
  370. FREE_HEAP( pSearchInformation->pszPrimaryDomainName );
  371. }
  372. for ( iter = 0; iter < pSearchInformation->cNameCount; iter++ )
  373. {
  374. if ( pSearchInformation->aSearchListNames[iter] )
  375. {
  376. FREE_HEAP( pSearchInformation->aSearchListNames[iter] );
  377. }
  378. }
  379. FREE_HEAP( pSearchInformation );
  380. }
  381. }
  382. VOID
  383. WINAPI
  384. FreeNetworkInformation(
  385. IN PDNS_NETWORK_INFORMATION pNetworkInformation
  386. )
  387. /*++
  388. Routine Description:
  389. None.
  390. Arguments:
  391. None.
  392. Return Value:
  393. None.
  394. --*/
  395. {
  396. DWORD iter;
  397. if ( pNetworkInformation )
  398. {
  399. FreeSearchInformation( pNetworkInformation->pSearchInformation );
  400. for ( iter = 0; iter < pNetworkInformation->cAdapterCount; iter++ )
  401. {
  402. FreeAdapterInformation( pNetworkInformation ->
  403. aAdapterInfoList[iter] );
  404. }
  405. FREE_HEAP( pNetworkInformation );
  406. }
  407. }
  408. //
  409. // Net failure caching
  410. //
  411. BOOL
  412. IsKnownNetFailure(
  413. VOID
  414. )
  415. /*++
  416. Routine Description:
  417. None.
  418. Arguments:
  419. None.
  420. Return Value:
  421. None.
  422. --*/
  423. {
  424. BOOL flag = FALSE;
  425. DNSDBG( TRACE, ( "IsKnownNetFailure()\n" ));
  426. EnterCriticalSection( &g_NetFailureCS );
  427. if ( g_NetFailureStatus )
  428. {
  429. if ( g_NetFailureTime < Dns_GetCurrentTimeInSeconds() )
  430. {
  431. g_NetFailureTime = 0;
  432. g_NetFailureStatus = ERROR_SUCCESS;
  433. flag = FALSE;
  434. }
  435. else
  436. {
  437. SetLastError( g_NetFailureStatus );
  438. flag = TRUE;
  439. }
  440. }
  441. LeaveCriticalSection( &g_NetFailureCS );
  442. return flag;
  443. }
  444. VOID
  445. SetKnownNetFailure(
  446. IN DNS_STATUS Status
  447. )
  448. /*++
  449. Routine Description:
  450. None.
  451. Arguments:
  452. None.
  453. Return Value:
  454. None.
  455. --*/
  456. {
  457. DNSDBG( TRACE, ( "SetKnownNetFailure()\n" ));
  458. EnterCriticalSection( &g_NetFailureCS );
  459. g_NetFailureTime = Dns_GetCurrentTimeInSeconds() +
  460. DNS_NET_FAILURE_CACHE_TIME;
  461. g_NetFailureStatus = Status;
  462. LeaveCriticalSection( &g_NetFailureCS );
  463. }
  464. BOOL
  465. WINAPI
  466. DnsGetCacheDataTable(
  467. OUT PDNS_CACHE_TABLE * ppTable
  468. )
  469. /*++
  470. Routine Description:
  471. Get cache data table.
  472. Arguments:
  473. ppTable -- address to receive ptr to cache data table
  474. Return Value:
  475. ERROR_SUCCES if successful.
  476. Error code on failure.
  477. --*/
  478. {
  479. DNS_STATUS status = ERROR_SUCCESS;
  480. DWORD rpcStatus = ERROR_SUCCESS;
  481. PDNS_RPC_CACHE_TABLE pcacheTable = NULL;
  482. DNSDBG( TRACE, ( "DnsGetCacheDataTable()\n" ));
  483. if ( ! ppTable )
  484. {
  485. return FALSE;
  486. }
  487. #if DNSBUILDOLD
  488. if ( g_IsWin9X )
  489. {
  490. return FALSE;
  491. }
  492. #endif
  493. RpcTryExcept
  494. {
  495. status = CRrReadCache( NULL, &pcacheTable );
  496. }
  497. RpcExcept( DNS_RPC_EXCEPTION_FILTER )
  498. {
  499. status = RpcExceptionCode();
  500. }
  501. RpcEndExcept
  502. // set out param
  503. *ppTable = (PDNS_CACHE_TABLE) pcacheTable;
  504. #if DBG
  505. if ( status != ERROR_SUCCESS )
  506. {
  507. DNSDBG( RPC, (
  508. "DnsGetCacheDataTable() status = %d\n",
  509. status ));
  510. }
  511. #endif
  512. return( pcacheTable && status == ERROR_SUCCESS );
  513. }
  514. BOOL
  515. IsLocalIpAddress(
  516. IN IP_ADDRESS IpAddress
  517. )
  518. //
  519. // DCR_FIX: this has no customers other than debug code in update.c
  520. //
  521. // If wanted this API it should be remoteable -- we could avoid alloc
  522. // and include IP6
  523. //
  524. {
  525. BOOL bfound = FALSE;
  526. PIP_ARRAY ipList = Dns_GetLocalIpAddressArray();
  527. DWORD iter;
  528. if ( !ipList )
  529. {
  530. return bfound;
  531. }
  532. //
  533. // check if IpAddress is in local list
  534. //
  535. for ( iter = 0; iter < ipList->AddrCount; iter++ )
  536. {
  537. if ( IpAddress == ipList->AddrArray[iter] )
  538. {
  539. bfound = TRUE;
  540. }
  541. }
  542. FREE_HEAP( ipList );
  543. return bfound;
  544. }
  545. //
  546. // End dnsapi.c
  547. //