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.

1343 lines
25 KiB

  1. /*++
  2. Copyright (c) 1998, Microsoft Corporation
  3. Module Name:
  4. rmdns.c
  5. Abstract:
  6. This module contains routines for the DNS allocator module's interface
  7. to the IP router-manager. (See ROUTPROT.H for details).
  8. Author:
  9. Abolade Gbadegesin (aboladeg) 4-Mar-1998
  10. Revision History:
  11. --*/
  12. #include "precomp.h"
  13. #pragma hdrstop
  14. COMPONENT_REFERENCE DnsComponentReference;
  15. PIP_DNS_PROXY_GLOBAL_INFO DnsGlobalInfo = NULL;
  16. CRITICAL_SECTION DnsGlobalInfoLock;
  17. SOCKET DnsGlobalSocket = INVALID_SOCKET;
  18. HANDLE DnsNotificationEvent;
  19. ULONG DnsProtocolStopped = 0;
  20. const MPR_ROUTING_CHARACTERISTICS DnsRoutingCharacteristics =
  21. {
  22. MS_ROUTER_VERSION,
  23. MS_IP_DNS_PROXY,
  24. RF_ROUTING|RF_ADD_ALL_INTERFACES,
  25. DnsRmStartProtocol,
  26. DnsRmStartComplete,
  27. DnsRmStopProtocol,
  28. DnsRmGetGlobalInfo,
  29. DnsRmSetGlobalInfo,
  30. NULL,
  31. NULL,
  32. DnsRmAddInterface,
  33. DnsRmDeleteInterface,
  34. DnsRmInterfaceStatus,
  35. DnsRmGetInterfaceInfo,
  36. DnsRmSetInterfaceInfo,
  37. DnsRmGetEventMessage,
  38. NULL,
  39. NULL,
  40. NULL,
  41. NULL,
  42. NULL,
  43. DnsRmMibCreate,
  44. DnsRmMibDelete,
  45. DnsRmMibGet,
  46. DnsRmMibSet,
  47. DnsRmMibGetFirst,
  48. DnsRmMibGetNext,
  49. NULL,
  50. NULL
  51. };
  52. IP_DNS_PROXY_STATISTICS DnsStatistics;
  53. SUPPORT_FUNCTIONS DnsSupportFunctions;
  54. VOID
  55. DnsCleanupModule(
  56. VOID
  57. )
  58. /*++
  59. Routine Description:
  60. This routine is invoked to cleanup the DNS module.
  61. Arguments:
  62. none.
  63. Return Value:
  64. none.
  65. Environment:
  66. Invoked from within a 'DllMain' routine on 'DLL_PROCESS_DETACH'.
  67. --*/
  68. {
  69. DnsShutdownInterfaceManagement();
  70. DnsShutdownTableManagement();
  71. DnsShutdownFileManagement();
  72. DeleteCriticalSection(&DnsGlobalInfoLock);
  73. DeleteComponentReference(&DnsComponentReference);
  74. } // DnsCleanupModule
  75. VOID
  76. DnsCleanupProtocol(
  77. VOID
  78. )
  79. /*++
  80. Routine Description:
  81. This routine is invoked to cleanup the DNS protocol-component
  82. after a 'StopProtocol'. It runs when the last reference to the
  83. DHCP component is released. (See 'COMPREF.H').
  84. Arguments:
  85. none.
  86. Return Value:
  87. none.
  88. Environment:
  89. Invoked from within an arbitrary context with no locks held.
  90. --*/
  91. {
  92. DNS_PROXY_TYPE Type;
  93. PROFILE("DnsCleanupProtocol");
  94. if (DnsServerList[DnsProxyDns]) {
  95. NH_FREE(DnsServerList[DnsProxyDns]);
  96. DnsServerList[DnsProxyDns] = NULL;
  97. }
  98. if (DnsServerList[DnsProxyWins]) {
  99. NH_FREE(DnsServerList[DnsProxyWins]);
  100. DnsServerList[DnsProxyWins] = NULL;
  101. }
  102. if (DnsICSDomainSuffix)
  103. {
  104. NH_FREE(DnsICSDomainSuffix);
  105. DnsICSDomainSuffix = NULL;
  106. }
  107. if (DnsGlobalInfo) { NH_FREE(DnsGlobalInfo); DnsGlobalInfo = NULL; }
  108. InterlockedExchange(reinterpret_cast<LPLONG>(&DnsProtocolStopped), 1);
  109. SetEvent(DnsNotificationEvent);
  110. ResetComponentReference(&DnsComponentReference);
  111. } // DnsCleanupProtocol
  112. BOOLEAN
  113. DnsInitializeModule(
  114. VOID
  115. )
  116. /*++
  117. Routine Description:
  118. This routine is invoked to initialize the DNS module.
  119. Arguments:
  120. none.
  121. Return Value:
  122. BOOLEAN - TRUE if initialization succeeded, FALSE otherwise
  123. Environment:
  124. Invoked in the context of a 'DllMain' routine on 'DLL_PROCESS_ATTACH'.
  125. --*/
  126. {
  127. if (InitializeComponentReference(
  128. &DnsComponentReference, DnsCleanupProtocol
  129. )) {
  130. return FALSE;
  131. }
  132. __try {
  133. InitializeCriticalSection(&DnsGlobalInfoLock);
  134. }
  135. __except(EXCEPTION_EXECUTE_HANDLER) {
  136. DeleteComponentReference(&DnsComponentReference);
  137. return FALSE;
  138. }
  139. if (DnsInitializeFileManagement()) {
  140. DeleteCriticalSection(&DnsGlobalInfoLock);
  141. DeleteComponentReference(&DnsComponentReference);
  142. return FALSE;
  143. }
  144. if (DnsInitializeTableManagement()) {
  145. DnsShutdownFileManagement();
  146. DeleteCriticalSection(&DnsGlobalInfoLock);
  147. DeleteComponentReference(&DnsComponentReference);
  148. return FALSE;
  149. }
  150. if (DnsInitializeInterfaceManagement()) {
  151. DnsShutdownTableManagement();
  152. DnsShutdownFileManagement();
  153. DeleteCriticalSection(&DnsGlobalInfoLock);
  154. DeleteComponentReference(&DnsComponentReference);
  155. return FALSE;
  156. }
  157. return TRUE;
  158. } // DnsInitializeModule
  159. BOOLEAN
  160. DnsIsDnsEnabled(
  161. VOID
  162. )
  163. /*++
  164. Routine Description:
  165. This routine is invoked to determine whether the DNS proxy is enabled.
  166. It checks the global info which, if found, indicates that the protocol
  167. is enabled.
  168. Note that the global info critical section is always initialized in the
  169. 'DllMain' routine, which is why this routine works if the DNS proxy
  170. is not even installed.
  171. Arguments:
  172. none.
  173. Return Value:
  174. BOOLEAN - TRUE if DNS proxy is enabled, FALSE otherwise.
  175. Environment:
  176. Invoked from an arbitrary context.
  177. --*/
  178. {
  179. PROFILE("DnsIsDnsEnabled");
  180. if (!REFERENCE_DNS()) { return FALSE; }
  181. EnterCriticalSection(&DnsGlobalInfoLock);
  182. if (!DnsGlobalInfo ||
  183. !(DnsGlobalInfo->Flags & IP_DNS_PROXY_FLAG_ENABLE_DNS)) {
  184. LeaveCriticalSection(&DnsGlobalInfoLock);
  185. DEREFERENCE_DNS_AND_RETURN(FALSE);
  186. }
  187. LeaveCriticalSection(&DnsGlobalInfoLock);
  188. DEREFERENCE_DNS_AND_RETURN(TRUE);
  189. } // DnsIsDnsEnabled
  190. BOOLEAN
  191. DnsIsWinsEnabled(
  192. VOID
  193. )
  194. /*++
  195. Routine Description:
  196. This routine is invoked to determine whether the WINS proxy is enabled.
  197. It checks the global info which, if found, indicates that the protocol
  198. is enabled.
  199. Note that the global info critical section is always initialized in the
  200. 'DllMain' routine, which is why this routine works if the DNS proxy
  201. is not even installed.
  202. Arguments:
  203. none.
  204. Return Value:
  205. BOOLEAN - TRUE if WINS proxy is enabled, FALSE otherwise.
  206. Environment:
  207. Invoked from an arbitrary context.
  208. --*/
  209. {
  210. PROFILE("DnsIsWinsEnabled");
  211. return FALSE;
  212. } // DnsIsWinsEnabled
  213. ULONG
  214. APIENTRY
  215. DnsRmStartProtocol(
  216. HANDLE NotificationEvent,
  217. PSUPPORT_FUNCTIONS SupportFunctions,
  218. PVOID GlobalInfo,
  219. ULONG StructureVersion,
  220. ULONG StructureSize,
  221. ULONG StructureCount
  222. )
  223. /*++
  224. Routine Description:
  225. This routine is invoked to indicate the component's operation should begin.
  226. Arguments:
  227. NotificationEvent - event on which we notify the router-manager
  228. about asynchronous occurrences
  229. SupportFunctions - functions for initiating router-related operations
  230. GlobalInfo - configuration for the component
  231. Return Value:
  232. ULONG - Win32 status code.
  233. Environment:
  234. The routine runs in the context of an IP router-manager thread.
  235. --*/
  236. {
  237. ULONG Error = NO_ERROR;
  238. SOCKET GlobalSocket;
  239. ULONG Size;
  240. NTSTATUS status;
  241. PROFILE("DnsRmStartProtocol");
  242. REFERENCE_DNS_OR_RETURN(ERROR_CAN_NOT_COMPLETE);
  243. if (!GlobalInfo) { DEREFERENCE_DNS_AND_RETURN(ERROR_INVALID_PARAMETER); }
  244. do {
  245. //
  246. // Copy the global configuration
  247. //
  248. EnterCriticalSection(&DnsGlobalInfoLock);
  249. Size = sizeof(*DnsGlobalInfo);
  250. DnsGlobalInfo =
  251. reinterpret_cast<PIP_DNS_PROXY_GLOBAL_INFO>(NH_ALLOCATE(Size));
  252. if (!DnsGlobalInfo) {
  253. LeaveCriticalSection(&DnsGlobalInfoLock);
  254. NhTrace(
  255. TRACE_FLAG_INIT,
  256. "DnsRmStartProtocol: cannot allocate global info"
  257. );
  258. NhErrorLog(
  259. IP_DNS_PROXY_LOG_ALLOCATION_FAILED,
  260. 0,
  261. "%d",
  262. Size
  263. );
  264. Error = ERROR_NOT_ENOUGH_MEMORY;
  265. break;
  266. }
  267. CopyMemory(DnsGlobalInfo, GlobalInfo, Size);
  268. //
  269. // Save the notification event
  270. //
  271. DnsNotificationEvent = NotificationEvent;
  272. //
  273. // Save the support functions
  274. //
  275. if (!SupportFunctions) {
  276. ZeroMemory(&DnsSupportFunctions, sizeof(DnsSupportFunctions));
  277. }
  278. else {
  279. CopyMemory(
  280. &DnsSupportFunctions,
  281. SupportFunctions,
  282. sizeof(*SupportFunctions)
  283. );
  284. }
  285. //
  286. // Query for ICS domain suffix string
  287. //
  288. DnsQueryICSDomainSuffix();
  289. //
  290. // Build the server list
  291. //
  292. DnsQueryServerList();
  293. //
  294. // Create the global query-socket
  295. //
  296. Error = NhCreateDatagramSocket(0, 0, &GlobalSocket);
  297. if (Error == NO_ERROR) {
  298. InterlockedExchangePointer(
  299. (PVOID*)&DnsGlobalSocket,
  300. (PVOID)GlobalSocket
  301. );
  302. }
  303. else {
  304. NhTrace(
  305. TRACE_FLAG_DNS,
  306. "DnsRmStartProtocol: error %d creating global socket", Error
  307. );
  308. Error = NO_ERROR;
  309. }
  310. LeaveCriticalSection(&DnsGlobalInfoLock);
  311. //
  312. // load entries from the hosts.ics file (if present)
  313. //
  314. LoadHostsIcsFile(TRUE);
  315. InterlockedExchange(reinterpret_cast<LPLONG>(&DnsProtocolStopped), 0);
  316. } while (FALSE);
  317. DEREFERENCE_DNS_AND_RETURN(Error);
  318. } // DnsRmStartProtocol
  319. ULONG
  320. APIENTRY
  321. DnsRmStartComplete(
  322. VOID
  323. )
  324. /*++
  325. Routine Description:
  326. This routine is invoked when the router has finished adding the initial
  327. configuration
  328. Arguments:
  329. none.
  330. Return Value:
  331. ULONG - Win32 status code
  332. Environment:
  333. The routine runs in the context of an IP router-manager thread.
  334. --*/
  335. {
  336. return NO_ERROR;
  337. } // DnsRmStartComplete
  338. ULONG
  339. APIENTRY
  340. DnsRmStopProtocol(
  341. VOID
  342. )
  343. /*++
  344. Routine Description:
  345. This routine is invoked to stop the protocol.
  346. Arguments:
  347. none.
  348. Return Value:
  349. ULONG - Win32 status code
  350. Environment:
  351. The routine runs in the context of an IP router-manager thread.
  352. --*/
  353. {
  354. SOCKET GlobalSocket;
  355. PROFILE("DnsRmStopProtocol");
  356. //
  357. // Reference the module to make sure it's running
  358. //
  359. REFERENCE_DNS_OR_RETURN(ERROR_CAN_NOT_COMPLETE);
  360. //
  361. // Save any entries present in our tables
  362. //
  363. SaveHostsIcsFile(TRUE);
  364. //
  365. // Empty the dns tables to save memory space
  366. //
  367. DnsEmptyTables();
  368. EnterCriticalSection(&DnsGlobalInfoLock);
  369. if (DnsNotifyChangeKeyWaitHandle) {
  370. RtlDeregisterWait(DnsNotifyChangeKeyWaitHandle);
  371. DnsNotifyChangeKeyWaitHandle = NULL;
  372. }
  373. if (DnsNotifyChangeKeyEvent) {
  374. NtClose(DnsNotifyChangeKeyEvent);
  375. DnsNotifyChangeKeyEvent = NULL;
  376. DnsNotifyChangeKeyCallbackRoutine(NULL, FALSE);
  377. }
  378. if (DnsTcpipInterfacesKey) {
  379. NtClose(DnsTcpipInterfacesKey);
  380. DnsTcpipInterfacesKey = NULL;
  381. }
  382. if (DnsNotifyChangeAddressWaitHandle) {
  383. RtlDeregisterWait(DnsNotifyChangeAddressWaitHandle);
  384. DnsNotifyChangeAddressWaitHandle = NULL;
  385. }
  386. if (DnsNotifyChangeAddressEvent) {
  387. NtClose(DnsNotifyChangeAddressEvent);
  388. DnsNotifyChangeAddressEvent = NULL;
  389. DnsNotifyChangeAddressCallbackRoutine(NULL, FALSE);
  390. }
  391. //
  392. // ICSDomain
  393. //
  394. if (DnsNotifyChangeKeyICSDomainWaitHandle) {
  395. RtlDeregisterWait(DnsNotifyChangeKeyICSDomainWaitHandle);
  396. DnsNotifyChangeKeyICSDomainWaitHandle = NULL;
  397. }
  398. if (DnsNotifyChangeKeyICSDomainEvent) {
  399. NtClose(DnsNotifyChangeKeyICSDomainEvent);
  400. DnsNotifyChangeKeyICSDomainEvent = NULL;
  401. DnsNotifyChangeKeyICSDomainCallbackRoutine(NULL, FALSE);
  402. }
  403. if (DnsTcpipParametersKey) {
  404. NtClose(DnsTcpipParametersKey);
  405. DnsTcpipParametersKey = NULL;
  406. }
  407. LeaveCriticalSection(&DnsGlobalInfoLock);
  408. GlobalSocket =
  409. (SOCKET)InterlockedExchangePointer(
  410. (PVOID*)&DnsGlobalSocket,
  411. (PVOID)INVALID_SOCKET
  412. );
  413. NhDeleteDatagramSocket(GlobalSocket);
  414. //
  415. // Drop the initial reference to cause a cleanup
  416. //
  417. ReleaseInitialComponentReference(&DnsComponentReference);
  418. return DEREFERENCE_DNS() ? NO_ERROR : ERROR_PROTOCOL_STOP_PENDING;
  419. } // DnsRmStopProtocol
  420. ULONG
  421. APIENTRY
  422. DnsRmAddInterface(
  423. PWCHAR Name,
  424. ULONG Index,
  425. NET_INTERFACE_TYPE Type,
  426. ULONG MediaType,
  427. USHORT AccessType,
  428. USHORT ConnectionType,
  429. PVOID InterfaceInfo,
  430. ULONG StructureVersion,
  431. ULONG StructureSize,
  432. ULONG StructureCount
  433. )
  434. /*++
  435. Routine Description:
  436. This routine is invoked to add an interface to the component.
  437. Arguments:
  438. Name - the name of the interface (unused)
  439. Index - the index of the interface
  440. Type - the type of the interface
  441. InterfaceInfo - the configuration information for the interface
  442. Return Value:
  443. ULONG - Win32 status code.
  444. Environment:
  445. The routine runs in the context of an IP router-manager thread.
  446. --*/
  447. {
  448. ULONG Error;
  449. PROFILE("DnsRmAddInterface");
  450. REFERENCE_DNS_OR_RETURN(ERROR_CAN_NOT_COMPLETE);
  451. Error =
  452. DnsCreateInterface(
  453. Index,
  454. Type,
  455. (PIP_DNS_PROXY_INTERFACE_INFO)InterfaceInfo,
  456. NULL
  457. );
  458. DEREFERENCE_DNS_AND_RETURN(Error);
  459. } // DnsRmAddInterface
  460. ULONG
  461. APIENTRY
  462. DnsRmDeleteInterface(
  463. ULONG Index
  464. )
  465. /*++
  466. Routine Description:
  467. This routine is invoked to delete an interface from the component.
  468. Arguments:
  469. Index - the index of the interface
  470. Return Value:
  471. ULONG - Win32 status code
  472. Environment:
  473. The routine runs in the context of an IP router-manager thread.
  474. --*/
  475. {
  476. ULONG Error;
  477. PROFILE("DnsRmDeleteInterface");
  478. REFERENCE_DNS_OR_RETURN(ERROR_CAN_NOT_COMPLETE);
  479. Error =
  480. DnsDeleteInterface(
  481. Index
  482. );
  483. DEREFERENCE_DNS_AND_RETURN(Error);
  484. } // DnsRmDeleteInterface
  485. ULONG
  486. APIENTRY
  487. DnsRmGetEventMessage(
  488. OUT ROUTING_PROTOCOL_EVENTS* Event,
  489. OUT MESSAGE* Result
  490. )
  491. /*++
  492. Routine Description:
  493. This routine is invoked to retrieve an event message from the component.
  494. The only event message we generate is the 'ROUTER_STOPPED' message.
  495. Arguments:
  496. Event - receives the generated event
  497. Result - receives the associated result
  498. Return Value:
  499. ULONG - Win32 status code.
  500. --*/
  501. {
  502. PROFILE("DnsRmGetEventMessage");
  503. if (InterlockedExchange(reinterpret_cast<LPLONG>(&DnsProtocolStopped), 0)) {
  504. *Event = ROUTER_STOPPED;
  505. return NO_ERROR;
  506. }
  507. return ERROR_NO_MORE_ITEMS;
  508. } // DnsRmGetEventMessage
  509. ULONG
  510. APIENTRY
  511. DnsRmGetInterfaceInfo(
  512. ULONG Index,
  513. PVOID InterfaceInfo,
  514. IN OUT PULONG InterfaceInfoSize,
  515. IN OUT PULONG StructureVersion,
  516. IN OUT PULONG StructureSize,
  517. IN OUT PULONG StructureCount
  518. )
  519. /*++
  520. Routine Description:
  521. This routine is invoked to retrieve the component's per-interface
  522. configuration.
  523. Arguments:
  524. Index - the index of the interface to be queried
  525. InterfaceInfo - receives the query results
  526. InterfaceInfoSize - receives the amount of data retrieved
  527. Return Value:
  528. ULONG - Win32 status code.
  529. --*/
  530. {
  531. ULONG Error;
  532. PROFILE("DnsRmGetInterfaceInfo");
  533. REFERENCE_DNS_OR_RETURN(ERROR_CAN_NOT_COMPLETE);
  534. Error =
  535. DnsQueryInterface(
  536. Index,
  537. (PIP_DNS_PROXY_INTERFACE_INFO)InterfaceInfo,
  538. InterfaceInfoSize
  539. );
  540. *StructureSize = *InterfaceInfoSize;
  541. if (StructureCount) {*StructureCount = 1;}
  542. DEREFERENCE_DNS_AND_RETURN(Error);
  543. } // DnsRmGetInterfaceInfo
  544. ULONG
  545. APIENTRY
  546. DnsRmSetInterfaceInfo(
  547. ULONG Index,
  548. PVOID InterfaceInfo,
  549. ULONG StructureVersion,
  550. ULONG StructureSize,
  551. ULONG StructureCount
  552. )
  553. /*++
  554. Routine Description:
  555. This routine is invoked to change the component's per-interface
  556. configuration.
  557. Arguments:
  558. Index - the index of the interface to be updated
  559. InterfaceInfo - supplies the new configuration
  560. Return Value:
  561. ULONG - Win32 status code.
  562. --*/
  563. {
  564. ULONG Error;
  565. PROFILE("DnsRmSetInterfaceInfo");
  566. REFERENCE_DNS_OR_RETURN(ERROR_CAN_NOT_COMPLETE);
  567. Error =
  568. DnsConfigureInterface(
  569. Index,
  570. (PIP_DNS_PROXY_INTERFACE_INFO)InterfaceInfo
  571. );
  572. DEREFERENCE_DNS_AND_RETURN(Error);
  573. } // DnsRmSetInterfaceInfo
  574. ULONG
  575. APIENTRY
  576. DnsRmInterfaceStatus(
  577. ULONG Index,
  578. BOOL InterfaceActive,
  579. ULONG StatusType,
  580. PVOID StatusInfo
  581. )
  582. /*++
  583. Routine Description:
  584. This routine is invoked to bind/unbind, enable/disable an interface
  585. Arguments:
  586. Index - the interface to be bound
  587. InterfaceActive - whether the interface is active
  588. StatusType - type of status being changed (bind or enabled)
  589. StatusInfo - Info pertaining to the state being changed
  590. Return Value:
  591. ULONG - Win32 Status code
  592. Environment:
  593. The routine runs in the context of an IP router-manager thread.
  594. --*/
  595. {
  596. ULONG Error = NO_ERROR;
  597. switch(StatusType) {
  598. case RIS_INTERFACE_ADDRESS_CHANGE: {
  599. PIP_ADAPTER_BINDING_INFO BindInfo =
  600. (PIP_ADAPTER_BINDING_INFO)StatusInfo;
  601. if (BindInfo->AddressCount) {
  602. Error = DnsRmBindInterface(Index, StatusInfo);
  603. } else {
  604. Error = DnsRmUnbindInterface(Index);
  605. }
  606. break;
  607. }
  608. case RIS_INTERFACE_ENABLED: {
  609. Error = DnsRmEnableInterface(Index);
  610. break;
  611. }
  612. case RIS_INTERFACE_DISABLED: {
  613. Error = DnsRmDisableInterface(Index);
  614. break;
  615. }
  616. }
  617. return Error;
  618. } // DnsRmInterfaceStatus
  619. ULONG
  620. DnsRmBindInterface(
  621. ULONG Index,
  622. PVOID BindingInfo
  623. )
  624. /*++
  625. Routine Description:
  626. This routine is invoked to bind an interface to its IP address(es).
  627. Arguments:
  628. Index - the interface to be bound
  629. BindingInfo - the addressing information
  630. Return Value:
  631. ULONG - Win32 status code.
  632. Environment:
  633. The routine runs in the context of an IP router-manager thread.
  634. --*/
  635. {
  636. ULONG Error;
  637. PROFILE("DnsRmBindInterface");
  638. REFERENCE_DNS_OR_RETURN(ERROR_CAN_NOT_COMPLETE);
  639. Error =
  640. DnsBindInterface(
  641. Index,
  642. (PIP_ADAPTER_BINDING_INFO)BindingInfo
  643. );
  644. DEREFERENCE_DNS_AND_RETURN(Error);
  645. } // DnsRmBindInterface
  646. ULONG
  647. DnsRmUnbindInterface(
  648. ULONG Index
  649. )
  650. /*++
  651. Routine Description:
  652. This routine is invoked to unbind an interface from its IP address(es).
  653. Arguments:
  654. Index - the interface to be unbound
  655. Return Value:
  656. ULONG - Win32 status code.
  657. Environment:
  658. The routine runs in the context of an IP router-manager thread.
  659. --*/
  660. {
  661. ULONG Error;
  662. PROFILE("DnsRmUnbindInterface");
  663. REFERENCE_DNS_OR_RETURN(ERROR_CAN_NOT_COMPLETE);
  664. Error =
  665. DnsUnbindInterface(
  666. Index
  667. );
  668. DEREFERENCE_DNS_AND_RETURN(Error);
  669. } // DnsRmUnbindInterface
  670. ULONG
  671. DnsRmEnableInterface(
  672. ULONG Index
  673. )
  674. /*++
  675. Routine Description:
  676. This routine is invoked to enable operation on an interface.
  677. Arguments:
  678. Index - the interface to be enabled.
  679. Return Value:
  680. ULONG - Win32 status code.
  681. Environment:
  682. The routine runs in the context of an IP router-manager thread.
  683. --*/
  684. {
  685. ULONG Error;
  686. PROFILE("DnsRmEnableInterface");
  687. REFERENCE_DNS_OR_RETURN(ERROR_CAN_NOT_COMPLETE);
  688. Error =
  689. DnsEnableInterface(
  690. Index
  691. );
  692. DEREFERENCE_DNS_AND_RETURN(Error);
  693. } // DnsRmEnableInterface
  694. ULONG
  695. DnsRmDisableInterface(
  696. ULONG Index
  697. )
  698. /*++
  699. Routine Description:
  700. This routine is invoked to disable operation on an interface.
  701. Arguments:
  702. Index - the interface to be disabled.
  703. Return Value:
  704. ULONG - Win32 status code.
  705. Environment:
  706. The routine runs in the context of an IP router-manager thread.
  707. --*/
  708. {
  709. ULONG Error;
  710. PROFILE("DnsRmDisableInterface");
  711. REFERENCE_DNS_OR_RETURN(ERROR_CAN_NOT_COMPLETE);
  712. Error =
  713. DnsDisableInterface(
  714. Index
  715. );
  716. DEREFERENCE_DNS_AND_RETURN(Error);
  717. } // DnsRmDisableInterface
  718. ULONG
  719. APIENTRY
  720. DnsRmGetGlobalInfo(
  721. PVOID GlobalInfo,
  722. IN OUT PULONG GlobalInfoSize,
  723. IN OUT PULONG StructureVersion,
  724. IN OUT PULONG StructureSize,
  725. IN OUT PULONG StructureCount
  726. )
  727. /*++
  728. Routine Description:
  729. This routine is invoked to retrieve the configuration for the component.
  730. Arguments:
  731. GlobalInfo - receives the configuration
  732. GlobalInfoSize - receives the size of the configuration
  733. Return Value:
  734. ULONG - Win32 status code
  735. Environment:
  736. The routine runs in the context of an IP router-manager thread.
  737. --*/
  738. {
  739. ULONG Size;
  740. PROFILE("DnsRmGetGlobalInfo");
  741. REFERENCE_DNS_OR_RETURN(ERROR_CAN_NOT_COMPLETE);
  742. if (!GlobalInfoSize || (*GlobalInfoSize && !GlobalInfo)) {
  743. DEREFERENCE_DNS_AND_RETURN(ERROR_INVALID_PARAMETER);
  744. }
  745. EnterCriticalSection(&DnsGlobalInfoLock);
  746. Size = sizeof(*DnsGlobalInfo);
  747. if (*GlobalInfoSize < Size) {
  748. LeaveCriticalSection(&DnsGlobalInfoLock);
  749. *StructureSize = *GlobalInfoSize = Size;
  750. if (StructureCount) {*StructureCount = 1;}
  751. DEREFERENCE_DNS_AND_RETURN(ERROR_INSUFFICIENT_BUFFER);
  752. }
  753. CopyMemory(GlobalInfo, DnsGlobalInfo, Size);
  754. LeaveCriticalSection(&DnsGlobalInfoLock);
  755. *StructureSize = *GlobalInfoSize = Size;
  756. if (StructureCount) {*StructureCount = 1;}
  757. DEREFERENCE_DNS_AND_RETURN(NO_ERROR);
  758. } // DnsRmGetGlobalInfo
  759. ULONG
  760. APIENTRY
  761. DnsRmSetGlobalInfo(
  762. PVOID GlobalInfo,
  763. ULONG StructureVersion,
  764. ULONG StructureSize,
  765. ULONG StructureCount
  766. )
  767. /*++
  768. Routine Description:
  769. This routine is invoked to change the configuration for the component.
  770. Arguments:
  771. GlobalInfo - the new configuration
  772. Return Value:
  773. ULONG - Win32 status code
  774. Environment:
  775. The routine runs in the context of an IP router-manager thread.
  776. --*/
  777. {
  778. ULONG OldFlags;
  779. ULONG NewFlags;
  780. PIP_DNS_PROXY_GLOBAL_INFO NewInfo;
  781. ULONG Size;
  782. PROFILE("DnsRmSetGlobalInfo");
  783. REFERENCE_DNS_OR_RETURN(ERROR_CAN_NOT_COMPLETE);
  784. if (!GlobalInfo) { DEREFERENCE_DNS_AND_RETURN(ERROR_INVALID_PARAMETER); }
  785. Size = sizeof(*DnsGlobalInfo);
  786. NewInfo = reinterpret_cast<PIP_DNS_PROXY_GLOBAL_INFO>(NH_ALLOCATE(Size));
  787. if (!NewInfo) {
  788. NhTrace(
  789. TRACE_FLAG_INIT,
  790. "DnsRmSetGlobalInfo: error reallocating global info"
  791. );
  792. NhErrorLog(
  793. IP_DNS_PROXY_LOG_ALLOCATION_FAILED,
  794. 0,
  795. "%d",
  796. Size
  797. );
  798. DEREFERENCE_DNS_AND_RETURN(ERROR_NOT_ENOUGH_MEMORY);
  799. }
  800. CopyMemory(NewInfo, GlobalInfo, Size);
  801. EnterCriticalSection(&DnsGlobalInfoLock);
  802. OldFlags = DnsGlobalInfo->Flags;
  803. NH_FREE(DnsGlobalInfo);
  804. DnsGlobalInfo = NewInfo;
  805. NewFlags = DnsGlobalInfo->Flags;
  806. LeaveCriticalSection(&DnsGlobalInfoLock);
  807. //
  808. // See if the enabled state of either DNS or WINS proxy changed.
  809. // If so, we need to deactivate and reactivate all interfaces
  810. //
  811. if ((NewFlags & IP_DNS_PROXY_FLAG_ENABLE_DNS)
  812. != (OldFlags & IP_DNS_PROXY_FLAG_ENABLE_DNS)) {
  813. DnsReactivateEveryInterface();
  814. }
  815. DEREFERENCE_DNS_AND_RETURN(NO_ERROR);
  816. } // DnsRmSetGlobalInfo
  817. ULONG
  818. APIENTRY
  819. DnsRmMibCreate(
  820. ULONG InputDataSize,
  821. PVOID InputData
  822. )
  823. {
  824. return ERROR_NOT_SUPPORTED;
  825. }
  826. ULONG
  827. APIENTRY
  828. DnsRmMibDelete(
  829. ULONG InputDataSize,
  830. PVOID InputData
  831. )
  832. {
  833. return ERROR_NOT_SUPPORTED;
  834. }
  835. ULONG
  836. APIENTRY
  837. DnsRmMibGet(
  838. ULONG InputDataSize,
  839. PVOID InputData,
  840. OUT PULONG OutputDataSize,
  841. OUT PVOID OutputData
  842. )
  843. /*++
  844. Routine Description:
  845. The DNS proxy only exposes one item to the MIB; its statistics.
  846. Arguments:
  847. InputDataSize - the MIB query data size
  848. InputData - specifies the MIB object to be retrieved
  849. OutputDataSize - the MIB response data size
  850. OutputData - receives the MIB object retrieved
  851. Return Value:
  852. ULONG - Win32 status code.
  853. --*/
  854. {
  855. ULONG Error;
  856. PIP_DNS_PROXY_MIB_QUERY Oidp;
  857. PROFILE("DnsRmMibGet");
  858. REFERENCE_DNS_OR_RETURN(ERROR_CAN_NOT_COMPLETE);
  859. if (InputDataSize < sizeof(*Oidp) || !OutputDataSize) {
  860. Error = ERROR_INVALID_PARAMETER;
  861. }
  862. else {
  863. Oidp = (PIP_DNS_PROXY_MIB_QUERY)InputData;
  864. switch(Oidp->Oid) {
  865. case IP_DNS_PROXY_STATISTICS_OID: {
  866. if (*OutputDataSize < sizeof(*Oidp) + sizeof(DnsStatistics)) {
  867. *OutputDataSize = sizeof(*Oidp) + sizeof(DnsStatistics);
  868. Error = ERROR_INSUFFICIENT_BUFFER;
  869. }
  870. else {
  871. *OutputDataSize = sizeof(*Oidp) + sizeof(DnsStatistics);
  872. Oidp = (PIP_DNS_PROXY_MIB_QUERY)OutputData;
  873. Oidp->Oid = IP_DNS_PROXY_STATISTICS_OID;
  874. CopyMemory(
  875. Oidp->Data,
  876. &DnsStatistics,
  877. sizeof(DnsStatistics)
  878. );
  879. Error = NO_ERROR;
  880. }
  881. break;
  882. }
  883. default: {
  884. NhTrace(
  885. TRACE_FLAG_DNS,
  886. "DnsRmMibGet: oid %d invalid",
  887. Oidp->Oid
  888. );
  889. Error = ERROR_INVALID_PARAMETER;
  890. break;
  891. }
  892. }
  893. }
  894. DEREFERENCE_DNS_AND_RETURN(Error);
  895. }
  896. ULONG
  897. APIENTRY
  898. DnsRmMibSet(
  899. ULONG InputDataSize,
  900. PVOID InputData
  901. )
  902. {
  903. return ERROR_NOT_SUPPORTED;
  904. }
  905. ULONG
  906. APIENTRY
  907. DnsRmMibGetFirst(
  908. ULONG InputDataSize,
  909. PVOID InputData,
  910. OUT PULONG OutputDataSize,
  911. OUT PVOID OutputData
  912. )
  913. {
  914. return ERROR_NOT_SUPPORTED;
  915. }
  916. ULONG
  917. APIENTRY
  918. DnsRmMibGetNext(
  919. ULONG InputDataSize,
  920. PVOID InputData,
  921. OUT PULONG OutputDataSize,
  922. OUT PVOID OutputData
  923. )
  924. {
  925. return ERROR_NOT_SUPPORTED;
  926. }