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.

1186 lines
23 KiB

  1. /*++
  2. Copyright (c) 1998, Microsoft Corporation
  3. Module Name:
  4. rmdhcp.c
  5. Abstract:
  6. This module contains routines for the DHCP 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 DhcpComponentReference;
  15. PCHAR DhcpDomainName = NULL;
  16. PIP_AUTO_DHCP_GLOBAL_INFO DhcpGlobalInfo;
  17. CRITICAL_SECTION DhcpGlobalInfoLock;
  18. HANDLE DhcpNotificationEvent;
  19. ULONG DhcpProtocolStopped = 0;
  20. const MPR_ROUTING_CHARACTERISTICS DhcpRoutingCharacteristics =
  21. {
  22. MS_ROUTER_VERSION,
  23. MS_IP_DHCP_ALLOCATOR,
  24. RF_ROUTING|RF_ADD_ALL_INTERFACES,
  25. DhcpRmStartProtocol,
  26. DhcpRmStartComplete,
  27. DhcpRmStopProtocol,
  28. DhcpRmGetGlobalInfo,
  29. DhcpRmSetGlobalInfo,
  30. NULL,
  31. NULL,
  32. DhcpRmAddInterface,
  33. DhcpRmDeleteInterface,
  34. DhcpRmInterfaceStatus,
  35. DhcpRmGetInterfaceInfo,
  36. DhcpRmSetInterfaceInfo,
  37. DhcpRmGetEventMessage,
  38. NULL,
  39. NULL,
  40. NULL,
  41. NULL,
  42. NULL,
  43. DhcpRmMibCreate,
  44. DhcpRmMibDelete,
  45. DhcpRmMibGet,
  46. DhcpRmMibSet,
  47. DhcpRmMibGetFirst,
  48. DhcpRmMibGetNext,
  49. NULL,
  50. NULL
  51. };
  52. IP_AUTO_DHCP_STATISTICS DhcpStatistics;
  53. SUPPORT_FUNCTIONS DhcpSupportFunctions;
  54. extern "C"
  55. LPSTR WINAPI
  56. DnsGetPrimaryDomainName_A(
  57. VOID
  58. );
  59. VOID
  60. DhcpCleanupModule(
  61. VOID
  62. )
  63. /*++
  64. Routine Description:
  65. This routine is invoked to cleanup the DHCP module.
  66. Arguments:
  67. none.
  68. Return Value:
  69. none.
  70. Environment:
  71. Invoked from within a 'DllMain' routine on 'DLL_PROCESS_DETACH'.
  72. --*/
  73. {
  74. DeleteCriticalSection(&DhcpGlobalInfoLock);
  75. DhcpShutdownInterfaceManagement();
  76. DeleteComponentReference(&DhcpComponentReference);
  77. } // DhcpCleanupModule
  78. VOID
  79. DhcpCleanupProtocol(
  80. VOID
  81. )
  82. /*++
  83. Routine Description:
  84. This routine is invoked to cleanup the DHCP protocol-component
  85. after a 'StopProtocol'. It runs when the last reference to the
  86. DHCP component is released. (See 'COMPREF.H').
  87. Arguments:
  88. none.
  89. Return Value:
  90. none.
  91. Environment:
  92. Invoked from within an arbitrary context with no locks held.
  93. --*/
  94. {
  95. PROFILE("DhcpCleanupProtocol");
  96. #if 1
  97. if (DhcpDomainName) {
  98. DnsFree(DhcpDomainName, DnsFreeFlat);
  99. DhcpDomainName = NULL;
  100. }
  101. #else
  102. if (DhcpDomainName) {
  103. NH_FREE(DhcpDomainName);
  104. DhcpDomainName = NULL;
  105. }
  106. #endif
  107. if (DhcpGlobalInfo) { NH_FREE(DhcpGlobalInfo); DhcpGlobalInfo = NULL; }
  108. InterlockedExchange(reinterpret_cast<LPLONG>(&DhcpProtocolStopped), 1);
  109. SetEvent(DhcpNotificationEvent);
  110. ResetComponentReference(&DhcpComponentReference);
  111. NhStopEventLog();
  112. } // DhcpCleanupProtocol
  113. BOOLEAN
  114. DhcpInitializeModule(
  115. VOID
  116. )
  117. /*++
  118. Routine Description:
  119. This routine is invoked to initialize the DHCP module.
  120. Arguments:
  121. none.
  122. Return Value:
  123. BOOLEAN - TRUE if initialization succeeded, FALSE otherwise
  124. Environment:
  125. Invoked in the context of a 'DllMain' routine on 'DLL_PROCESS_ATTACH'.
  126. --*/
  127. {
  128. if (InitializeComponentReference(
  129. &DhcpComponentReference, DhcpCleanupProtocol
  130. )) {
  131. return FALSE;
  132. } else if (DhcpInitializeInterfaceManagement()) {
  133. DeleteComponentReference(&DhcpComponentReference);
  134. return FALSE;
  135. } else {
  136. __try {
  137. InitializeCriticalSection(&DhcpGlobalInfoLock);
  138. } __except(EXCEPTION_EXECUTE_HANDLER) {
  139. DeleteComponentReference(&DhcpComponentReference);
  140. return FALSE;
  141. }
  142. }
  143. return TRUE;
  144. } // DhcpInitializeModule
  145. ULONG
  146. APIENTRY
  147. DhcpRmStartProtocol(
  148. HANDLE NotificationEvent,
  149. PSUPPORT_FUNCTIONS SupportFunctions,
  150. PVOID GlobalInfo,
  151. ULONG StructureVersion,
  152. ULONG StructureSize,
  153. ULONG StructureCount
  154. )
  155. /*++
  156. Routine Description:
  157. This routine is invoked to indicate the component's operation should begin.
  158. Arguments:
  159. NotificationEvent - event on which we notify the router-manager
  160. about asynchronous occurrences
  161. SupportFunctions - functions for initiating router-related operations
  162. GlobalInfo - configuration for the component
  163. Return Value:
  164. ULONG - Win32 status code.
  165. Environment:
  166. The routine runs in the context of an IP router-manager thread.
  167. --*/
  168. {
  169. ULONG Error = NO_ERROR;
  170. ULONG Size;
  171. PROFILE("DhcpRmStartProtocol");
  172. REFERENCE_DHCP_OR_RETURN(ERROR_CAN_NOT_COMPLETE);
  173. if (!GlobalInfo) { DEREFERENCE_DHCP_AND_RETURN(ERROR_INVALID_PARAMETER); }
  174. NhStartEventLog();
  175. do {
  176. //
  177. // Create a copy of the global configuration
  178. //
  179. Size =
  180. sizeof(*DhcpGlobalInfo) +
  181. ((PIP_AUTO_DHCP_GLOBAL_INFO)GlobalInfo)->ExclusionCount *
  182. sizeof(ULONG);
  183. DhcpGlobalInfo =
  184. reinterpret_cast<PIP_AUTO_DHCP_GLOBAL_INFO>(NH_ALLOCATE(Size));
  185. if (!DhcpGlobalInfo) {
  186. NhTrace(
  187. TRACE_FLAG_INIT,
  188. "DhcpRmStartProtocol: cannot allocate global info"
  189. );
  190. NhErrorLog(
  191. IP_AUTO_DHCP_LOG_ALLOCATION_FAILED,
  192. 0,
  193. "%d",
  194. Size
  195. );
  196. Error = ERROR_NOT_ENOUGH_MEMORY;
  197. break;
  198. }
  199. CopyMemory(DhcpGlobalInfo, GlobalInfo, Size);
  200. //
  201. // Save the notification event
  202. //
  203. DhcpNotificationEvent = NotificationEvent;
  204. //
  205. // Save the support functions
  206. //
  207. if (!SupportFunctions) {
  208. ZeroMemory(&DhcpSupportFunctions, sizeof(DhcpSupportFunctions));
  209. }
  210. else {
  211. CopyMemory(
  212. &DhcpSupportFunctions,
  213. SupportFunctions,
  214. sizeof(*SupportFunctions)
  215. );
  216. }
  217. InterlockedExchange(reinterpret_cast<LPLONG>(&DhcpProtocolStopped), 0);
  218. } while (FALSE);
  219. if (NO_ERROR != Error) {
  220. NhStopEventLog();
  221. }
  222. DEREFERENCE_DHCP_AND_RETURN(Error);
  223. } // DhcpRmStartProtocol
  224. ULONG
  225. APIENTRY
  226. DhcpRmStartComplete(
  227. VOID
  228. )
  229. /*++
  230. Routine Description:
  231. This routine is invoked when the router has finished adding the initial
  232. configuration
  233. Arguments:
  234. none.
  235. Return Value:
  236. ULONG - Win32 status code
  237. Environment:
  238. The routine runs in the context of an IP router-manager thread.
  239. --*/
  240. {
  241. return NO_ERROR;
  242. } // DhcpRmStartComplete
  243. ULONG
  244. APIENTRY
  245. DhcpRmStopProtocol(
  246. VOID
  247. )
  248. /*++
  249. Routine Description:
  250. This routine is invoked to stop the protocol.
  251. Arguments:
  252. none.
  253. Return Value:
  254. ULONG - Win32 status code
  255. Environment:
  256. The routine runs in the context of an IP router-manager thread.
  257. --*/
  258. {
  259. PROFILE("DhcpStopProtocol");
  260. //
  261. // Reference the module to make sure it's running
  262. //
  263. REFERENCE_DHCP_OR_RETURN(ERROR_CAN_NOT_COMPLETE);
  264. //
  265. // Drop the initial reference to cause a cleanup
  266. //
  267. ReleaseInitialComponentReference(&DhcpComponentReference);
  268. return DEREFERENCE_DHCP() ? NO_ERROR : ERROR_PROTOCOL_STOP_PENDING;
  269. } // DhcpRmStopProtocol
  270. ULONG
  271. APIENTRY
  272. DhcpRmAddInterface(
  273. PWCHAR Name,
  274. ULONG Index,
  275. NET_INTERFACE_TYPE Type,
  276. ULONG MediaType,
  277. USHORT AccessType,
  278. USHORT ConnectionType,
  279. PVOID InterfaceInfo,
  280. ULONG StructureVersion,
  281. ULONG StructureSize,
  282. ULONG StructureCount
  283. )
  284. /*++
  285. Routine Description:
  286. This routine is invoked to add an interface to the component.
  287. Arguments:
  288. Name - the name of the interface (unused)
  289. Index - the index of the interface
  290. Type - the type of the interface
  291. InterfaceInfo - the configuration information for the interface
  292. Return Value:
  293. ULONG - Win32 status code.
  294. Environment:
  295. The routine runs in the context of an IP router-manager thread.
  296. --*/
  297. {
  298. ULONG Error;
  299. PROFILE("DhcpRmAddInterface");
  300. if (Type != PERMANENT) { return NO_ERROR; }
  301. REFERENCE_DHCP_OR_RETURN(ERROR_CAN_NOT_COMPLETE);
  302. Error =
  303. DhcpCreateInterface(
  304. Index,
  305. Type,
  306. (PIP_AUTO_DHCP_INTERFACE_INFO)InterfaceInfo,
  307. NULL
  308. );
  309. DEREFERENCE_DHCP_AND_RETURN(Error);
  310. } // DhcpRmAddInterface
  311. ULONG
  312. APIENTRY
  313. DhcpRmDeleteInterface(
  314. ULONG Index
  315. )
  316. /*++
  317. Routine Description:
  318. This routine is invoked to delete an interface from the component.
  319. Arguments:
  320. Index - the index of the interface
  321. Return Value:
  322. ULONG - Win32 status code
  323. Environment:
  324. The routine runs in the context of an IP router-manager thread.
  325. --*/
  326. {
  327. ULONG Error;
  328. PROFILE("DhcpRmDeleteInterface");
  329. REFERENCE_DHCP_OR_RETURN(ERROR_CAN_NOT_COMPLETE);
  330. Error =
  331. DhcpDeleteInterface(
  332. Index
  333. );
  334. DEREFERENCE_DHCP_AND_RETURN(Error);
  335. } // DhcpRmDeleteInterface
  336. ULONG
  337. APIENTRY
  338. DhcpRmGetEventMessage(
  339. OUT ROUTING_PROTOCOL_EVENTS* Event,
  340. OUT MESSAGE* Result
  341. )
  342. /*++
  343. Routine Description:
  344. This routine is invoked to retrieve an event message from the component.
  345. The only event message we generate is the 'ROUTER_STOPPED' message.
  346. Arguments:
  347. Event - receives the generated event
  348. Result - receives the associated result
  349. Return Value:
  350. ULONG - Win32 status code.
  351. --*/
  352. {
  353. PROFILE("DhcpRmGetEventMessage");
  354. if (InterlockedExchange(reinterpret_cast<LPLONG>(&DhcpProtocolStopped), 0)) {
  355. *Event = ROUTER_STOPPED;
  356. return NO_ERROR;
  357. }
  358. return ERROR_NO_MORE_ITEMS;
  359. } // DhcpRmGetEventMessage
  360. ULONG
  361. APIENTRY
  362. DhcpRmGetInterfaceInfo(
  363. ULONG Index,
  364. PVOID InterfaceInfo,
  365. IN OUT PULONG InterfaceInfoSize,
  366. IN OUT PULONG StructureVersion,
  367. IN OUT PULONG StructureSize,
  368. IN OUT PULONG StructureCount
  369. )
  370. /*++
  371. Routine Description:
  372. This routine is invoked to retrieve the component's per-interface
  373. configuration.
  374. Arguments:
  375. Index - the index of the interface to be queried
  376. InterfaceInfo - receives the query results
  377. InterfaceInfoSize - receives the amount of data retrieved
  378. Return Value:
  379. ULONG - Win32 status code.
  380. --*/
  381. {
  382. ULONG Error;
  383. PROFILE("DhcpRmGetInterfaceInfo");
  384. REFERENCE_DHCP_OR_RETURN(ERROR_CAN_NOT_COMPLETE);
  385. Error =
  386. DhcpQueryInterface(
  387. Index,
  388. (PIP_AUTO_DHCP_INTERFACE_INFO)InterfaceInfo,
  389. InterfaceInfoSize
  390. );
  391. *StructureSize = *InterfaceInfoSize;
  392. if (StructureCount) {*StructureCount = 1;}
  393. DEREFERENCE_DHCP_AND_RETURN(Error);
  394. } // DhcpRmGetInterfaceInfo
  395. ULONG
  396. APIENTRY
  397. DhcpRmSetInterfaceInfo(
  398. ULONG Index,
  399. PVOID InterfaceInfo,
  400. ULONG StructureVersion,
  401. ULONG StructureSize,
  402. ULONG StructureCount
  403. )
  404. /*++
  405. Routine Description:
  406. This routine is invoked to change the component's per-interface
  407. configuration.
  408. Arguments:
  409. Index - the index of the interface to be updated
  410. InterfaceInfo - supplies the new configuration
  411. Return Value:
  412. ULONG - Win32 status code.
  413. --*/
  414. {
  415. ULONG Error;
  416. PROFILE("DhcpRmSetInterfaceInfo");
  417. REFERENCE_DHCP_OR_RETURN(ERROR_CAN_NOT_COMPLETE);
  418. Error =
  419. DhcpConfigureInterface(
  420. Index,
  421. (PIP_AUTO_DHCP_INTERFACE_INFO)InterfaceInfo
  422. );
  423. DEREFERENCE_DHCP_AND_RETURN(Error);
  424. } // DhcpRmSetInterfaceInfo
  425. ULONG
  426. APIENTRY
  427. DhcpRmInterfaceStatus(
  428. ULONG Index,
  429. BOOL InterfaceActive,
  430. ULONG StatusType,
  431. PVOID StatusInfo
  432. )
  433. /*++
  434. Routine Description:
  435. This routine is invoked to bind/unbind, enable/disable an interface
  436. Arguments:
  437. Index - the interface to be bound
  438. InterfaceActive - whether the interface is active
  439. StatusType - type of status being changed (bind or enabled)
  440. StatusInfo - Info pertaining to the state being changed
  441. Return Value:
  442. ULONG - Win32 Status code
  443. Environment:
  444. The routine runs in the context of an IP router-manager thread.
  445. --*/
  446. {
  447. ULONG Error = NO_ERROR;
  448. switch(StatusType) {
  449. case RIS_INTERFACE_ADDRESS_CHANGE: {
  450. PIP_ADAPTER_BINDING_INFO BindInfo =
  451. (PIP_ADAPTER_BINDING_INFO)StatusInfo;
  452. if (BindInfo->AddressCount) {
  453. Error = DhcpRmBindInterface(Index, StatusInfo);
  454. } else {
  455. Error = DhcpRmUnbindInterface(Index);
  456. }
  457. break;
  458. }
  459. case RIS_INTERFACE_ENABLED: {
  460. Error = DhcpRmEnableInterface(Index);
  461. break;
  462. }
  463. case RIS_INTERFACE_DISABLED: {
  464. Error = DhcpRmDisableInterface(Index);
  465. break;
  466. }
  467. }
  468. return Error;
  469. } // DhcpRmInterfaceStatus
  470. ULONG
  471. DhcpRmBindInterface(
  472. ULONG Index,
  473. PVOID BindingInfo
  474. )
  475. /*++
  476. Routine Description:
  477. This routine is invoked to bind an interface to its IP address(es).
  478. Arguments:
  479. Index - the interface to be bound
  480. BindingInfo - the addressing information
  481. Return Value:
  482. ULONG - Win32 status code.
  483. Environment:
  484. The routine runs in the context of an IP router-manager thread.
  485. --*/
  486. {
  487. PCHAR DomainName;
  488. ULONG Error;
  489. NTSTATUS status;
  490. PROFILE("DhcpRmBindInterface");
  491. REFERENCE_DHCP_OR_RETURN(ERROR_CAN_NOT_COMPLETE);
  492. Error =
  493. DhcpBindInterface(
  494. Index,
  495. (PIP_ADAPTER_BINDING_INFO)BindingInfo
  496. );
  497. //
  498. // Re-read the domain name in case it changed
  499. //
  500. EnterCriticalSection(&DhcpGlobalInfoLock);
  501. #if 1
  502. DomainName = DnsGetPrimaryDomainName_A();
  503. if (DomainName) {
  504. if (DhcpDomainName && lstrcmpiA(DomainName, DhcpDomainName) == 0) {
  505. DnsFree(DomainName, DnsFreeFlat);
  506. } else {
  507. if (DhcpDomainName) { DnsFree(DhcpDomainName, DnsFreeFlat); }
  508. DhcpDomainName = DomainName;
  509. }
  510. }
  511. #else
  512. status = NhQueryDomainName(&DomainName);
  513. if (NT_SUCCESS(status)) {
  514. if (DhcpDomainName && lstrcmpiA(DomainName, DhcpDomainName) == 0) {
  515. NH_FREE(DomainName);
  516. } else {
  517. NH_FREE(DhcpDomainName);
  518. if (DhcpDomainName) { NH_FREE(DhcpDomainName); }
  519. DhcpDomainName = DomainName;
  520. }
  521. }
  522. #endif
  523. LeaveCriticalSection(&DhcpGlobalInfoLock);
  524. DEREFERENCE_DHCP_AND_RETURN(Error);
  525. } // DhcpRmBindInterface
  526. ULONG
  527. DhcpRmUnbindInterface(
  528. ULONG Index
  529. )
  530. /*++
  531. Routine Description:
  532. This routine is invoked to unbind an interface from its IP address(es).
  533. Arguments:
  534. Index - the interface to be unbound
  535. Return Value:
  536. ULONG - Win32 status code.
  537. Environment:
  538. The routine runs in the context of an IP router-manager thread.
  539. --*/
  540. {
  541. ULONG Error;
  542. PROFILE("DhcpRmUnbindInterface");
  543. REFERENCE_DHCP_OR_RETURN(ERROR_CAN_NOT_COMPLETE);
  544. Error =
  545. DhcpUnbindInterface(
  546. Index
  547. );
  548. DEREFERENCE_DHCP_AND_RETURN(Error);
  549. } // DhcpRmUnbindInterface
  550. ULONG
  551. DhcpRmEnableInterface(
  552. ULONG Index
  553. )
  554. /*++
  555. Routine Description:
  556. This routine is invoked to enable operation on an interface.
  557. Arguments:
  558. Index - the interface to be enabled.
  559. Return Value:
  560. ULONG - Win32 status code.
  561. Environment:
  562. The routine runs in the context of an IP router-manager thread.
  563. --*/
  564. {
  565. ULONG Error;
  566. PROFILE("DhcpRmEnableInterface");
  567. REFERENCE_DHCP_OR_RETURN(ERROR_CAN_NOT_COMPLETE);
  568. Error =
  569. DhcpEnableInterface(
  570. Index
  571. );
  572. DEREFERENCE_DHCP_AND_RETURN(Error);
  573. } // DhcpRmEnableInterface
  574. ULONG
  575. DhcpRmDisableInterface(
  576. ULONG Index
  577. )
  578. /*++
  579. Routine Description:
  580. This routine is invoked to disable operation on an interface.
  581. Arguments:
  582. Index - the interface to be disabled.
  583. Return Value:
  584. ULONG - Win32 status code.
  585. Environment:
  586. The routine runs in the context of an IP router-manager thread.
  587. --*/
  588. {
  589. ULONG Error;
  590. PROFILE("DhcpRmDisableInterface");
  591. REFERENCE_DHCP_OR_RETURN(ERROR_CAN_NOT_COMPLETE);
  592. Error =
  593. DhcpDisableInterface(
  594. Index
  595. );
  596. DEREFERENCE_DHCP_AND_RETURN(Error);
  597. } // DhcpRmDisableInterface
  598. ULONG
  599. APIENTRY
  600. DhcpRmGetGlobalInfo(
  601. PVOID GlobalInfo,
  602. IN OUT PULONG GlobalInfoSize,
  603. PULONG StructureVersion,
  604. IN OUT PULONG StructureSize,
  605. IN OUT PULONG StructureCount
  606. )
  607. /*++
  608. Routine Description:
  609. This routine is invoked to retrieve the configuration for the component.
  610. Arguments:
  611. GlobalInfo - receives the configuration
  612. GlobalInfoSize - receives the size of the configuration
  613. Return Value:
  614. ULONG - Win32 status code
  615. Environment:
  616. The routine runs in the context of an IP router-manager thread.
  617. --*/
  618. {
  619. ULONG Size;
  620. PROFILE("DhcpRmGetGlobalInfo");
  621. REFERENCE_DHCP_OR_RETURN(ERROR_CAN_NOT_COMPLETE);
  622. if (!GlobalInfoSize || (*GlobalInfoSize && !GlobalInfo)) {
  623. DEREFERENCE_DHCP_AND_RETURN(ERROR_INVALID_PARAMETER);
  624. }
  625. EnterCriticalSection(&DhcpGlobalInfoLock);
  626. Size =
  627. sizeof(*DhcpGlobalInfo) +
  628. DhcpGlobalInfo->ExclusionCount * sizeof(ULONG);
  629. if (*GlobalInfoSize < Size) {
  630. LeaveCriticalSection(&DhcpGlobalInfoLock);
  631. *StructureSize = *GlobalInfoSize = Size;
  632. if (StructureCount) {*StructureCount = 1;}
  633. DEREFERENCE_DHCP_AND_RETURN(ERROR_INSUFFICIENT_BUFFER);
  634. }
  635. CopyMemory(GlobalInfo, DhcpGlobalInfo, Size);
  636. LeaveCriticalSection(&DhcpGlobalInfoLock);
  637. *StructureSize = *GlobalInfoSize = Size;
  638. if (StructureCount) {*StructureCount = 1;}
  639. DEREFERENCE_DHCP_AND_RETURN(NO_ERROR);
  640. } // DhcpRmGetGlobalInfo
  641. ULONG
  642. APIENTRY
  643. DhcpRmSetGlobalInfo(
  644. PVOID GlobalInfo,
  645. ULONG StructureVersion,
  646. ULONG StructureSize,
  647. ULONG StructureCount
  648. )
  649. /*++
  650. Routine Description:
  651. This routine is invoked to change the configuration for the component.
  652. Arguments:
  653. GlobalInfo - the new configuration
  654. Return Value:
  655. ULONG - Win32 status code
  656. Environment:
  657. The routine runs in the context of an IP router-manager thread.
  658. --*/
  659. {
  660. PIP_AUTO_DHCP_GLOBAL_INFO NewInfo;
  661. ULONG NewScope;
  662. ULONG OldScope;
  663. ULONG Size;
  664. PROFILE("DhcpRmSetGlobalInfo");
  665. REFERENCE_DHCP_OR_RETURN(ERROR_CAN_NOT_COMPLETE);
  666. if (!GlobalInfo) { DEREFERENCE_DHCP_AND_RETURN(ERROR_INVALID_PARAMETER); }
  667. Size =
  668. sizeof(*DhcpGlobalInfo) +
  669. ((PIP_AUTO_DHCP_GLOBAL_INFO)GlobalInfo)->ExclusionCount * sizeof(ULONG);
  670. NewInfo = reinterpret_cast<PIP_AUTO_DHCP_GLOBAL_INFO>(NH_ALLOCATE(Size));
  671. if (!NewInfo) {
  672. NhTrace(
  673. TRACE_FLAG_INIT,
  674. "DhcpRmSetGlobalInfo: error reallocating global info"
  675. );
  676. NhErrorLog(
  677. IP_AUTO_DHCP_LOG_ALLOCATION_FAILED,
  678. 0,
  679. "%d",
  680. Size
  681. );
  682. DEREFERENCE_DHCP_AND_RETURN(ERROR_NOT_ENOUGH_MEMORY);
  683. }
  684. CopyMemory(NewInfo, GlobalInfo, Size);
  685. EnterCriticalSection(&DhcpGlobalInfoLock);
  686. OldScope = DhcpGlobalInfo->ScopeNetwork & DhcpGlobalInfo->ScopeMask;
  687. NH_FREE(DhcpGlobalInfo);
  688. DhcpGlobalInfo = NewInfo;
  689. NewScope = DhcpGlobalInfo->ScopeNetwork & DhcpGlobalInfo->ScopeMask;
  690. LeaveCriticalSection(&DhcpGlobalInfoLock);
  691. if (OldScope != NewScope) {
  692. DhcpReactivateEveryInterface();
  693. }
  694. DEREFERENCE_DHCP_AND_RETURN(NO_ERROR);
  695. } // DhcpRmSetGlobalInfo
  696. ULONG
  697. APIENTRY
  698. DhcpRmMibCreate(
  699. ULONG InputDataSize,
  700. PVOID InputData
  701. )
  702. {
  703. return ERROR_NOT_SUPPORTED;
  704. }
  705. ULONG
  706. APIENTRY
  707. DhcpRmMibDelete(
  708. ULONG InputDataSize,
  709. PVOID InputData
  710. )
  711. {
  712. return ERROR_NOT_SUPPORTED;
  713. }
  714. ULONG
  715. APIENTRY
  716. DhcpRmMibGet(
  717. ULONG InputDataSize,
  718. PVOID InputData,
  719. OUT PULONG OutputDataSize,
  720. OUT PVOID OutputData
  721. )
  722. /*++
  723. Routine Description:
  724. The DHCP allocator only exposes one item to the MIB; its statistics.
  725. Arguments:
  726. InputDataSize - the MIB query data size
  727. InputData - specifies the MIB object to be retrieved
  728. OutputDataSize - the MIB response data size
  729. OutputData - receives the MIB object retrieved
  730. Return Value:
  731. ULONG - Win32 status code.
  732. --*/
  733. {
  734. ULONG Error;
  735. PIP_AUTO_DHCP_MIB_QUERY Oidp;
  736. PROFILE("DhcpRmMibGet");
  737. REFERENCE_DHCP_OR_RETURN(ERROR_CAN_NOT_COMPLETE);
  738. if (InputDataSize < sizeof(*Oidp) || !InputData|| !OutputDataSize) {
  739. Error = ERROR_INVALID_PARAMETER;
  740. }
  741. else {
  742. Oidp = (PIP_AUTO_DHCP_MIB_QUERY)InputData;
  743. switch(Oidp->Oid) {
  744. case IP_AUTO_DHCP_STATISTICS_OID: {
  745. if (*OutputDataSize < sizeof(*Oidp) + sizeof(DhcpStatistics)) {
  746. *OutputDataSize = sizeof(*Oidp) + sizeof(DhcpStatistics);
  747. Error = ERROR_INSUFFICIENT_BUFFER;
  748. }
  749. else if (!OutputData) {
  750. Error = ERROR_INVALID_PARAMETER;
  751. }
  752. else {
  753. *OutputDataSize = sizeof(*Oidp) + sizeof(DhcpStatistics);
  754. Oidp = (PIP_AUTO_DHCP_MIB_QUERY)OutputData;
  755. Oidp->Oid = IP_AUTO_DHCP_STATISTICS_OID;
  756. CopyMemory(
  757. Oidp->Data,
  758. &DhcpStatistics,
  759. sizeof(DhcpStatistics)
  760. );
  761. Error = NO_ERROR;
  762. }
  763. break;
  764. }
  765. default: {
  766. NhTrace(
  767. TRACE_FLAG_DHCP,
  768. "DhcpRmMibGet: oid %d invalid",
  769. Oidp->Oid
  770. );
  771. Error = ERROR_INVALID_PARAMETER;
  772. break;
  773. }
  774. }
  775. }
  776. DEREFERENCE_DHCP_AND_RETURN(Error);
  777. }
  778. ULONG
  779. APIENTRY
  780. DhcpRmMibSet(
  781. ULONG InputDataSize,
  782. PVOID InputData
  783. )
  784. {
  785. return ERROR_NOT_SUPPORTED;
  786. }
  787. ULONG
  788. APIENTRY
  789. DhcpRmMibGetFirst(
  790. ULONG InputDataSize,
  791. PVOID InputData,
  792. OUT PULONG OutputDataSize,
  793. OUT PVOID OutputData
  794. )
  795. {
  796. return ERROR_NOT_SUPPORTED;
  797. }
  798. ULONG
  799. APIENTRY
  800. DhcpRmMibGetNext(
  801. ULONG InputDataSize,
  802. PVOID InputData,
  803. OUT PULONG OutputDataSize,
  804. OUT PVOID OutputData
  805. )
  806. {
  807. return ERROR_NOT_SUPPORTED;
  808. }