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.

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