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.

1613 lines
31 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. rmALG.cpp
  5. Abstract:
  6. This module contains routines for the ALG Manager module's
  7. interface to the IP router-manager. (See ROUTPROT.H for details).
  8. Author:
  9. JPDup 10-Nov-2000
  10. Revision History:
  11. Savasg 22-Aug-2001 Added RRAS Support
  12. --*/
  13. #include "precomp.h"
  14. #pragma hdrstop
  15. #include <ipnatapi.h>
  16. #include <initguid.h>
  17. #include <atlbase.h>
  18. extern CComModule _Module;
  19. #include <atlcom.h>
  20. #include "Alg_private.h"
  21. #include "NatPrivateAPI_Imp.h"
  22. #include <MyTrace.h>
  23. MYTRACE_ENABLE
  24. //
  25. // Globals
  26. //
  27. COMPONENT_REFERENCE AlgComponentReference;
  28. PIP_ALG_GLOBAL_INFO AlgGlobalInfo = NULL;
  29. CRITICAL_SECTION AlgGlobalInfoLock;
  30. HANDLE AlgNotificationEvent;
  31. HANDLE AlgTimerQueueHandle = NULL;
  32. HANDLE AlgPortReservationHandle = NULL;
  33. HANDLE AlgTranslatorHandle = NULL;
  34. ULONG AlgProtocolStopped = 0;
  35. IP_ALG_STATISTICS AlgStatistics;
  36. SUPPORT_FUNCTIONS AlgSupportFunctions;
  37. //
  38. // GIT cookie for the IHNetCfgMgr instance
  39. //
  40. DWORD AlgGITcookie = 0;
  41. IGlobalInterfaceTable* AlgGITp = NULL;
  42. const MPR_ROUTING_CHARACTERISTICS AlgRoutingCharacteristics =
  43. {
  44. MS_ROUTER_VERSION,
  45. MS_IP_ALG,
  46. RF_ROUTING|RF_ADD_ALL_INTERFACES,
  47. AlgRmStartProtocol,
  48. AlgRmStartComplete,
  49. AlgRmStopProtocol,
  50. AlgRmGetGlobalInfo,
  51. AlgRmSetGlobalInfo,
  52. NULL,
  53. NULL,
  54. AlgRmAddInterface,
  55. AlgRmDeleteInterface,
  56. AlgRmInterfaceStatus,
  57. AlgRmGetInterfaceInfo,
  58. AlgRmSetInterfaceInfo,
  59. AlgRmGetEventMessage,
  60. NULL,
  61. NULL,
  62. NULL,
  63. NULL,
  64. NULL,
  65. AlgRmMibCreate,
  66. AlgRmMibDelete,
  67. AlgRmMibGet,
  68. AlgRmMibSet,
  69. AlgRmMibGetFirst,
  70. AlgRmMibGetNext,
  71. NULL,
  72. NULL
  73. };
  74. //
  75. //
  76. //
  77. HRESULT
  78. GetAlgControllerInterface(
  79. IAlgController** ppAlgController
  80. )
  81. /*++
  82. Routine Description:
  83. This routine obtains a pointer to the home networking configuration
  84. manager.
  85. Arguments:
  86. ppAlgController - receives the IAlgController pointer. The caller must release this pointer.
  87. Return Value:
  88. standard HRESULT
  89. Environment:
  90. COM must be initialized on the calling thread
  91. --*/
  92. {
  93. HRESULT hr = S_OK;
  94. if ( NULL == AlgGITp )
  95. {
  96. IAlgController* pIAlgController;
  97. //
  98. // Create the global interface table
  99. //
  100. hr = CoCreateInstance(
  101. CLSID_StdGlobalInterfaceTable,
  102. NULL,
  103. CLSCTX_INPROC_SERVER,
  104. IID_PPV_ARG(IGlobalInterfaceTable, &AlgGITp)
  105. );
  106. if ( SUCCEEDED(hr) )
  107. {
  108. //
  109. // Create the ALG Interface (ALG.exe will start as a service by COM)
  110. //
  111. hr = CoCreateInstance(
  112. CLSID_AlgController,
  113. NULL,
  114. CLSCTX_LOCAL_SERVER,
  115. IID_PPV_ARG(IAlgController, &pIAlgController)
  116. );
  117. if ( FAILED(hr) )
  118. {
  119. NhTrace(
  120. TRACE_FLAG_INIT,
  121. "GetAlgControllerInterface: Unable to create pIAlgController (0x%08x)",
  122. hr
  123. );
  124. }
  125. }
  126. else
  127. {
  128. NhTrace(
  129. TRACE_FLAG_INIT,
  130. "GetAlgControllerInterface: Unable to create GIT (0x%08x)",
  131. hr
  132. );
  133. }
  134. if (SUCCEEDED(hr))
  135. {
  136. //
  137. // Store the CfgMgr pointer in the GIT
  138. //
  139. hr = AlgGITp->RegisterInterfaceInGlobal(
  140. pIAlgController,
  141. IID_IAlgController,
  142. &AlgGITcookie
  143. );
  144. pIAlgController->Release();
  145. if ( FAILED(hr) )
  146. {
  147. NhTrace(
  148. TRACE_FLAG_INIT,
  149. "GetAlgControllerInterface: Unable to register pIAlgController (0x%08x)",
  150. hr
  151. );
  152. }
  153. }
  154. }
  155. if ( SUCCEEDED(hr) )
  156. {
  157. hr = AlgGITp->GetInterfaceFromGlobal(
  158. AlgGITcookie,
  159. IID_PPV_ARG(IAlgController, ppAlgController)
  160. );
  161. }
  162. return hr;
  163. } // GetAlgControllerInterface
  164. //
  165. //
  166. //
  167. void
  168. FreeAlgControllerInterface()
  169. {
  170. //
  171. // Free up HNetCfgMgr pointers
  172. //
  173. if ( !AlgGITp )
  174. return; // nothing to free
  175. //
  176. // Make sure COM is initialized
  177. //
  178. HRESULT hr;
  179. COMINIT_BEGIN;
  180. if ( SUCCEEDED(hr) )
  181. {
  182. //
  183. // Release the ALG.exe private interface from the GIT
  184. //
  185. AlgGITp->RevokeInterfaceFromGlobal(AlgGITcookie);
  186. AlgGITcookie = 0;
  187. //
  188. // Release the GIT
  189. //
  190. AlgGITp->Release();
  191. AlgGITp = NULL;
  192. }
  193. COMINIT_END;
  194. }
  195. VOID
  196. AlgCleanupModule(
  197. VOID
  198. )
  199. /*++
  200. Routine Description:
  201. This routine is invoked to cleanup the ALG transparent proxy module.
  202. Arguments:
  203. none.
  204. Return Value:
  205. none.
  206. Environment:
  207. Invoked from within a 'DllMain' routine on 'DLL_PROCESS_DETACH'.
  208. --*/
  209. {
  210. AlgShutdownInterfaceManagement();
  211. DeleteCriticalSection(&AlgGlobalInfoLock);
  212. DeleteComponentReference(&AlgComponentReference);
  213. } // AlgCleanupModule
  214. VOID
  215. AlgCleanupProtocol(
  216. VOID
  217. )
  218. /*++
  219. Routine Description:
  220. This routine is invoked to cleanup the ALG transparent proxy
  221. protocol-component after a 'StopProtocol'. It runs when the last reference
  222. to the component is released. (See 'COMPREF.H').
  223. Arguments:
  224. none.
  225. Return Value:
  226. none.
  227. Environment:
  228. Invoked from within an arbitrary context with no locks held.
  229. --*/
  230. {
  231. PROFILE("AlgCleanupProtocol");
  232. if (AlgGlobalInfo) { NH_FREE(AlgGlobalInfo); AlgGlobalInfo = NULL; }
  233. if (AlgTimerQueueHandle) {
  234. DeleteTimerQueueEx(AlgTimerQueueHandle, INVALID_HANDLE_VALUE);
  235. AlgTimerQueueHandle = NULL;
  236. }
  237. if (AlgPortReservationHandle) {
  238. NatShutdownPortReservation(AlgPortReservationHandle);
  239. AlgPortReservationHandle = NULL;
  240. }
  241. if (AlgTranslatorHandle) {
  242. NatShutdownTranslator(AlgTranslatorHandle); AlgTranslatorHandle = NULL;
  243. }
  244. InterlockedExchange(reinterpret_cast<LPLONG>(&AlgProtocolStopped), 1);
  245. SetEvent(AlgNotificationEvent);
  246. ResetComponentReference(&AlgComponentReference);
  247. //
  248. // Free the GIT and AlgController interface
  249. //
  250. FreeAlgControllerInterface();
  251. NhStopEventLog();
  252. } // AlgCleanupProtocol
  253. BOOLEAN
  254. AlgInitializeModule(
  255. VOID
  256. )
  257. /*++
  258. Routine Description:
  259. This routine is invoked to initialize the FnP module.
  260. Arguments:
  261. none.
  262. Return Value:
  263. BOOLEAN - TRUE if initialization succeeded, FALSE otherwise
  264. Environment:
  265. Invoked in the context of a 'DllMain' routine on 'DLL_PROCESS_ATTACH'.
  266. --*/
  267. {
  268. if (InitializeComponentReference(
  269. &AlgComponentReference, AlgCleanupProtocol
  270. ))
  271. {
  272. return FALSE;
  273. }
  274. __try
  275. {
  276. InitializeCriticalSection(&AlgGlobalInfoLock);
  277. }
  278. __except(EXCEPTION_EXECUTE_HANDLER)
  279. {
  280. DeleteComponentReference(&AlgComponentReference);
  281. return FALSE;
  282. }
  283. if ( AlgInitializeInterfaceManagement() )
  284. {
  285. DeleteCriticalSection( &AlgGlobalInfoLock );
  286. DeleteComponentReference( &AlgComponentReference );
  287. return FALSE;
  288. }
  289. return TRUE;
  290. } // AlgInitializeModule
  291. //
  292. // Get ALG COM Interface to Start the ALG and give call back Interface
  293. //
  294. HRESULT
  295. Initialise_ALG()
  296. {
  297. HRESULT hr;
  298. COMINIT_BEGIN;
  299. if ( FAILED(hr) )
  300. return hr;
  301. //
  302. // Get COM to load the ALG.exe
  303. // The ALG will be launch using a LOCAL_SERVICE priviledge
  304. // See the RunAs entry under the AppID of the ALG.exe
  305. //
  306. IAlgController* pIAlgController=NULL;
  307. hr = GetAlgControllerInterface(&pIAlgController);
  308. if ( SUCCEEDED(hr) )
  309. {
  310. //
  311. // We create our Private COM interface to the NAT api
  312. //
  313. CComObject<CNat>* pComponentNat;
  314. hr = CComObject<CNat>::CreateInstance(&pComponentNat);
  315. if ( SUCCEEDED(hr) )
  316. {
  317. pComponentNat->AddRef();
  318. //
  319. // Make sure we pass a INat interface
  320. //
  321. INat* pINat=NULL;
  322. hr = pComponentNat->QueryInterface(IID_INat, (void**)&pINat);
  323. if ( SUCCEEDED(hr) )
  324. {
  325. //
  326. // Let the ALG manager start the loading of all the ALG modules
  327. //
  328. hr = pIAlgController->Start(pINat);
  329. if ( FAILED(hr) )
  330. {
  331. NhTrace(
  332. TRACE_FLAG_INIT,
  333. "Initialise_ALG: Error (0x%08x) on pIAlgController->Start(pINat)",
  334. hr
  335. );
  336. }
  337. //
  338. // ALG manager will have AddRef this INat so we can release
  339. //
  340. pINat->Release();
  341. }
  342. pComponentNat->Release();
  343. }
  344. }
  345. else
  346. {
  347. NhTrace(
  348. TRACE_FLAG_INIT,
  349. "Initialise_ALG: Error (0x%08x) Getting the IAlgController interface",
  350. hr
  351. );
  352. return hr;
  353. }
  354. if ( pIAlgController )
  355. pIAlgController->Release();
  356. COMINIT_END;
  357. return S_OK;
  358. }
  359. ULONG
  360. APIENTRY
  361. AlgRmStartProtocol(
  362. HANDLE NotificationEvent,
  363. PSUPPORT_FUNCTIONS SupportFunctions,
  364. PVOID GlobalInfo,
  365. ULONG StructureVersion,
  366. ULONG StructureSize,
  367. ULONG StructureCount
  368. )
  369. /*++
  370. Routine Description:
  371. This routine is invoked to indicate the component's operation should begin.
  372. Arguments:
  373. NotificationEvent - event on which we notify the router-manager
  374. about asynchronous occurrences
  375. SupportFunctions - functions for initiating router-related operations
  376. GlobalInfo - configuration for the component
  377. Return Value:
  378. ULONG - Win32 status code.
  379. Environment:
  380. The routine runs in the context of an IP router-manager thread.
  381. --*/
  382. {
  383. MYTRACE_START(L"rmALG");
  384. MYTRACE_ENTER("AlgRmStartProtocol");
  385. PROFILE("AlgRmStartProtocol");
  386. ULONG Error = NO_ERROR;
  387. ULONG Size;
  388. REFERENCE_ALG_OR_RETURN(ERROR_CAN_NOT_COMPLETE);
  389. if (!GlobalInfo) { DEREFERENCE_ALG_AND_RETURN(ERROR_INVALID_PARAMETER); }
  390. NhStartEventLog();
  391. do {
  392. //
  393. // Copy the global configuration
  394. //
  395. EnterCriticalSection(&AlgGlobalInfoLock);
  396. Size = sizeof(*AlgGlobalInfo);
  397. AlgGlobalInfo =
  398. reinterpret_cast<PIP_ALG_GLOBAL_INFO>(NH_ALLOCATE(Size));
  399. if (!AlgGlobalInfo) {
  400. LeaveCriticalSection(&AlgGlobalInfoLock);
  401. NhTrace(
  402. TRACE_FLAG_INIT,
  403. "AlgRmStartProtocol: cannot allocate global info"
  404. );
  405. NhErrorLog(
  406. IP_ALG_LOG_ALLOCATION_FAILED,
  407. 0,
  408. "%d",
  409. Size
  410. );
  411. Error = ERROR_NOT_ENOUGH_MEMORY;
  412. break;
  413. }
  414. CopyMemory(AlgGlobalInfo, GlobalInfo, Size);
  415. //
  416. // Save the notification event
  417. //
  418. AlgNotificationEvent = NotificationEvent;
  419. //
  420. // Save the support functions
  421. //
  422. if (!SupportFunctions) {
  423. ZeroMemory(&AlgSupportFunctions, sizeof(AlgSupportFunctions));
  424. } else {
  425. CopyMemory(
  426. &AlgSupportFunctions,
  427. SupportFunctions,
  428. sizeof(*SupportFunctions)
  429. );
  430. }
  431. //
  432. // Obtain a handle to the kernel-mode translation module.
  433. //
  434. Error = NatInitializeTranslator(&AlgTranslatorHandle);
  435. if (Error) {
  436. NhTrace(
  437. TRACE_FLAG_INIT,
  438. "AlgRmStartProtocol: error %d initializing translator",
  439. Error
  440. );
  441. break;
  442. }
  443. //
  444. // Obtain a port-reservation handle
  445. //
  446. Error = NatInitializePortReservation(
  447. ALG_PORT_RESERVATION_BLOCK_SIZE,
  448. &AlgPortReservationHandle
  449. );
  450. if (Error)
  451. {
  452. NhTrace(
  453. TRACE_FLAG_INIT,
  454. "AlgRmStartProtocol: error %d initializing port-reservation",
  455. Error
  456. );
  457. break;
  458. }
  459. AlgTimerQueueHandle = CreateTimerQueue();
  460. if (AlgTimerQueueHandle == NULL) {
  461. Error = GetLastError();
  462. NhTrace(
  463. TRACE_FLAG_INIT,
  464. "AlgRmStartProtocol: error %d initializing timer queue",
  465. Error
  466. );
  467. break;
  468. }
  469. //
  470. // Start the ALG.exe
  471. //
  472. Initialise_ALG();
  473. LeaveCriticalSection(&AlgGlobalInfoLock);
  474. InterlockedExchange(reinterpret_cast<LPLONG>(&AlgProtocolStopped), 0);
  475. } while (FALSE);
  476. if (NO_ERROR != Error) {
  477. NhStopEventLog();
  478. }
  479. DEREFERENCE_ALG_AND_RETURN(Error);
  480. } // AlgRmStartProtocol
  481. ULONG
  482. APIENTRY
  483. AlgRmStartComplete(
  484. VOID
  485. )
  486. /*++
  487. Routine Description:
  488. This routine is invoked when the router has finished adding the initial
  489. configuration.
  490. Arguments:
  491. none.
  492. Return Value:
  493. ULONG - Win32 status code
  494. Environment:
  495. The routine runs in the context of an IP router-manager thread.
  496. --*/
  497. {
  498. return NO_ERROR;
  499. } // AlgRmStartComplete
  500. ULONG
  501. APIENTRY
  502. AlgRmStopProtocol(
  503. VOID
  504. )
  505. /*++
  506. Routine Description:
  507. This routine is invoked to stop the protocol.
  508. Arguments:
  509. none.
  510. Return Value:
  511. ULONG - Win32 status code
  512. Environment:
  513. The routine runs in the context of an IP router-manager thread.
  514. --*/
  515. {
  516. MYTRACE_ENTER("AlgRmStopProtocol");
  517. PROFILE("AlgRmStopProtocol");
  518. //
  519. // Reference the module to make sure it's running
  520. //
  521. REFERENCE_ALG_OR_RETURN(ERROR_CAN_NOT_COMPLETE);
  522. //
  523. // Stop all ALG
  524. //
  525. HRESULT hr;
  526. COMINIT_BEGIN;
  527. if ( SUCCEEDED(hr) )
  528. {
  529. IAlgController* pIAlgController=NULL;
  530. hr = GetAlgControllerInterface(&pIAlgController);
  531. if ( SUCCEEDED(hr) )
  532. {
  533. hr = pIAlgController->Stop();
  534. if ( FAILED(hr) )
  535. {
  536. NhTrace(
  537. TRACE_FLAG_INIT,
  538. "AlgRmStopProtocol: Error (0x%08x) returned from pIalgController->Stop()",
  539. hr
  540. );
  541. }
  542. ULONG nRef = pIAlgController->Release();
  543. //
  544. // We are done with the ALG
  545. // Free the GIT and AlgController interface
  546. //
  547. FreeAlgControllerInterface();
  548. }
  549. }
  550. COMINIT_END;
  551. //
  552. // Drop the initial reference to cause a cleanup
  553. //
  554. ReleaseInitialComponentReference(&AlgComponentReference);
  555. MYTRACE_STOP;
  556. return DEREFERENCE_ALG() ? NO_ERROR : ERROR_PROTOCOL_STOP_PENDING;
  557. } // AlgRmStopProtocol
  558. ULONG
  559. APIENTRY
  560. AlgRmAddInterface(
  561. PWCHAR Name,
  562. ULONG Index,
  563. NET_INTERFACE_TYPE Type,
  564. ULONG MediaType,
  565. USHORT AccessType,
  566. USHORT ConnectionType,
  567. PVOID InterfaceInfo,
  568. ULONG StructureVersion,
  569. ULONG StructureSize,
  570. ULONG StructureCount
  571. )
  572. /*++
  573. Routine Description:
  574. This routine is invoked to add an interface to the component.
  575. Arguments:
  576. Name - the name of the interface (unused)
  577. Index - the index of the interface
  578. Type - the type of the interface
  579. InterfaceInfo - the configuration information for the interface
  580. Return Value:
  581. ULONG - Win32 status code.
  582. Environment:
  583. The routine runs in the context of an IP router-manager thread.
  584. --*/
  585. {
  586. PROFILE("AlgRmAddInterface");
  587. REFERENCE_ALG_OR_RETURN(ERROR_CAN_NOT_COMPLETE);
  588. ULONG Error = NO_ERROR;
  589. //
  590. // Also notify the ALG.exe manager
  591. //
  592. HRESULT hr = S_OK;
  593. Error = AlgCreateInterface(Index,
  594. Type,
  595. (PIP_ALG_INTERFACE_INFO) InterfaceInfo,
  596. NULL);
  597. DEREFERENCE_ALG_AND_RETURN(Error);
  598. } // AlgRmAddInterface
  599. ULONG
  600. APIENTRY
  601. AlgRmDeleteInterface(
  602. ULONG Index
  603. )
  604. /*++
  605. Routine Description:
  606. This routine is invoked to delete an interface from the component.
  607. Arguments:
  608. Index - the index of the interface
  609. Return Value:
  610. ULONG - Win32 status code
  611. Environment:
  612. The routine runs in the context of an IP router-manager thread.
  613. --*/
  614. {
  615. ULONG Error = S_OK;
  616. PROFILE("AlgRmDeleteInterface");
  617. REFERENCE_ALG_OR_RETURN(ERROR_CAN_NOT_COMPLETE);
  618. Error = AlgDeleteInterface(Index);
  619. DEREFERENCE_ALG_AND_RETURN(Error);
  620. } // AlgRmDeleteInterface
  621. ULONG
  622. APIENTRY
  623. AlgRmInterfaceStatus(
  624. ULONG Index,
  625. BOOL InterfaceActive,
  626. ULONG StatusType,
  627. PVOID StatusInfo
  628. )
  629. /*++
  630. Routine Description:
  631. This routine is invoked to bind/unbind, enable/disable an interface
  632. Arguments:
  633. Index - the interface to be bound
  634. InterfaceActive - whether the interface is active
  635. StatusType - type of status being changed (bind or enabled)
  636. StatusInfo - Info pertaining to the state being changed
  637. Return Value:
  638. ULONG - Win32 Status code
  639. Environment:
  640. The routine runs in the context of an IP router-manager thread.
  641. --*/
  642. {
  643. ULONG Error = NO_ERROR;
  644. switch(StatusType) {
  645. case RIS_INTERFACE_ADDRESS_CHANGE: {
  646. PIP_ADAPTER_BINDING_INFO BindInfo =
  647. (PIP_ADAPTER_BINDING_INFO)StatusInfo;
  648. if (BindInfo->AddressCount) {
  649. Error = AlgRmBindInterface(Index, StatusInfo);
  650. } else {
  651. Error = AlgRmUnbindInterface(Index);
  652. }
  653. break;
  654. }
  655. case RIS_INTERFACE_ENABLED: {
  656. Error = AlgRmEnableInterface(Index);
  657. break;
  658. }
  659. case RIS_INTERFACE_DISABLED: {
  660. Error = AlgRmDisableInterface(Index);
  661. break;
  662. }
  663. }
  664. return Error;
  665. } // AlgRmInterfaceStatus
  666. ULONG
  667. AlgRmBindInterface(
  668. ULONG Index,
  669. PVOID BindingInfo
  670. )
  671. /*++
  672. Routine Description:
  673. This routine is invoked to bind an interface to its IP address(es).
  674. Arguments:
  675. Index - the interface to be bound
  676. BindingInfo - the addressing information
  677. Return Value:
  678. ULONG - Win32 status code.
  679. Environment:
  680. The routine runs in the context of an IP router-manager thread.
  681. --*/
  682. {
  683. ULONG Error = NO_ERROR;
  684. PROFILE("AlgRmBindInterface");
  685. REFERENCE_ALG_OR_RETURN(ERROR_CAN_NOT_COMPLETE);
  686. Error = AlgBindInterface(Index, (PIP_ADAPTER_BINDING_INFO)BindingInfo);
  687. DEREFERENCE_ALG_AND_RETURN(Error);
  688. } // AlgRmBindInterface
  689. ULONG
  690. AlgRmUnbindInterface(
  691. ULONG Index
  692. )
  693. /*++
  694. Routine Description:
  695. This routine is invoked to unbind an interface from its IP address(es).
  696. Arguments:
  697. Index - the interface to be unbound
  698. Return Value:
  699. ULONG - Win32 status code.
  700. Environment:
  701. The routine runs in the context of an IP router-manager thread.
  702. --*/
  703. {
  704. ULONG Error = NO_ERROR;
  705. PROFILE("AlgRmUnbindInterface");
  706. REFERENCE_ALG_OR_RETURN(ERROR_CAN_NOT_COMPLETE);
  707. Error = AlgUnbindInterface( Index );
  708. DEREFERENCE_ALG_AND_RETURN(Error);
  709. } // AlgRmUnbindInterface
  710. ULONG
  711. AlgRmEnableInterface(
  712. ULONG Index
  713. )
  714. /*++
  715. Routine Description:
  716. This routine is invoked to enable operation on an interface.
  717. Arguments:
  718. Index - the interface to be enabled.
  719. Return Value:
  720. ULONG - Win32 status code.
  721. Environment:
  722. The routine runs in the context of an IP router-manager thread.
  723. --*/
  724. {
  725. ULONG Error = NO_ERROR;
  726. PROFILE("AlgRmEnableInterface");
  727. REFERENCE_ALG_OR_RETURN(ERROR_CAN_NOT_COMPLETE);
  728. Error = AlgEnableInterface( Index );
  729. DEREFERENCE_ALG_AND_RETURN(Error);
  730. } // AlgRmEnableInterface
  731. ULONG
  732. AlgRmDisableInterface(
  733. ULONG Index
  734. )
  735. /*++
  736. Routine Description:
  737. This routine is invoked to disable operation on an interface.
  738. Arguments:
  739. Index - the interface to be disabled.
  740. Return Value:
  741. ULONG - Win32 status code.
  742. Environment:
  743. The routine runs in the context of an IP router-manager thread.
  744. --*/
  745. {
  746. ULONG Error = NO_ERROR;
  747. PROFILE("AlgRmDisableInterface");
  748. REFERENCE_ALG_OR_RETURN(ERROR_CAN_NOT_COMPLETE);
  749. Error = AlgDisableInterface( Index );
  750. DEREFERENCE_ALG_AND_RETURN(Error);
  751. } // AlgRmDisableInterface
  752. ULONG
  753. APIENTRY
  754. AlgRmGetGlobalInfo(
  755. PVOID GlobalInfo,
  756. IN OUT PULONG GlobalInfoSize,
  757. IN OUT PULONG StructureVersion,
  758. IN OUT PULONG StructureSize,
  759. IN OUT PULONG StructureCount
  760. )
  761. /*++
  762. Routine Description:
  763. This routine is invoked to retrieve the configuration for the component.
  764. Arguments:
  765. GlobalInfo - receives the configuration
  766. GlobalInfoSize - receives the size of the configuration
  767. Return Value:
  768. ULONG - Win32 status code
  769. Environment:
  770. The routine runs in the context of an IP router-manager thread.
  771. --*/
  772. {
  773. ULONG Size;
  774. PROFILE("AlgRmGetGlobalInfo");
  775. REFERENCE_ALG_OR_RETURN(ERROR_CAN_NOT_COMPLETE);
  776. if (!GlobalInfoSize || (*GlobalInfoSize && !GlobalInfo)) {
  777. DEREFERENCE_ALG_AND_RETURN(ERROR_INVALID_PARAMETER);
  778. }
  779. EnterCriticalSection(&AlgGlobalInfoLock);
  780. Size = sizeof(*AlgGlobalInfo);
  781. if (*GlobalInfoSize < Size) {
  782. LeaveCriticalSection(&AlgGlobalInfoLock);
  783. *StructureSize = *GlobalInfoSize = Size;
  784. if (StructureCount) {*StructureCount = 1;}
  785. DEREFERENCE_ALG_AND_RETURN(ERROR_INSUFFICIENT_BUFFER);
  786. }
  787. CopyMemory(GlobalInfo, AlgGlobalInfo, Size);
  788. LeaveCriticalSection(&AlgGlobalInfoLock);
  789. *StructureSize = *GlobalInfoSize = Size;
  790. if (StructureCount) {*StructureCount = 1;}
  791. DEREFERENCE_ALG_AND_RETURN(NO_ERROR);
  792. } // AlgRmGetGlobalInfo
  793. ULONG
  794. APIENTRY
  795. AlgRmSetGlobalInfo(
  796. PVOID GlobalInfo,
  797. ULONG StructureVersion,
  798. ULONG StructureSize,
  799. ULONG StructureCount
  800. )
  801. /*++
  802. Routine Description:
  803. This routine is invoked to change the configuration for the component.
  804. Arguments:
  805. GlobalInfo - the new configuration
  806. Return Value:
  807. ULONG - Win32 status code
  808. Environment:
  809. The routine runs in the context of an IP router-manager thread.
  810. --*/
  811. {
  812. ULONG OldFlags;
  813. ULONG NewFlags;
  814. PIP_ALG_GLOBAL_INFO NewInfo;
  815. ULONG Size;
  816. PROFILE("AlgRmSetGlobalInfo");
  817. REFERENCE_ALG_OR_RETURN(ERROR_CAN_NOT_COMPLETE);
  818. if (!GlobalInfo) { DEREFERENCE_ALG_AND_RETURN(ERROR_INVALID_PARAMETER); }
  819. Size = sizeof(*AlgGlobalInfo);
  820. NewInfo = reinterpret_cast<PIP_ALG_GLOBAL_INFO>(NH_ALLOCATE(Size));
  821. if (!NewInfo) {
  822. NhTrace(
  823. TRACE_FLAG_INIT,
  824. "AlgRmSetGlobalInfo: error reallocating global info"
  825. );
  826. NhErrorLog(
  827. IP_ALG_LOG_ALLOCATION_FAILED,
  828. 0,
  829. "%d",
  830. Size
  831. );
  832. DEREFERENCE_ALG_AND_RETURN(ERROR_NOT_ENOUGH_MEMORY);
  833. }
  834. CopyMemory(NewInfo, GlobalInfo, Size);
  835. EnterCriticalSection(&AlgGlobalInfoLock);
  836. OldFlags = AlgGlobalInfo->Flags;
  837. NH_FREE(AlgGlobalInfo);
  838. AlgGlobalInfo = NewInfo;
  839. NewFlags = AlgGlobalInfo->Flags;
  840. LeaveCriticalSection(&AlgGlobalInfoLock);
  841. DEREFERENCE_ALG_AND_RETURN(NO_ERROR);
  842. } // AlgRmSetGlobalInfo
  843. ULONG
  844. AlgRmPortMappingChanged(
  845. ULONG Index,
  846. UCHAR Protocol,
  847. USHORT Port
  848. )
  849. /*++
  850. Routine Description:
  851. This routine is invoked when a port mapping has changed for
  852. an interface.
  853. Arguments:
  854. Index - the index of the interface on which the port mapping
  855. changed.
  856. Protcol - the IP protocol for the port mapping
  857. Port - the port for the port mapping
  858. Return Value:
  859. ULONG - Win32 status code
  860. Environment:
  861. This method must be called by a COM-initialized thread.
  862. --*/
  863. {
  864. ULONG Error = NO_ERROR;
  865. HRESULT hr;
  866. IAlgController* pIAlgController;
  867. PROFILE("AlgRmPortMappingChanged");
  868. REFERENCE_ALG_OR_RETURN(ERROR_CAN_NOT_COMPLETE);
  869. hr = GetAlgControllerInterface(&pIAlgController);
  870. if (SUCCEEDED(hr))
  871. {
  872. hr = pIAlgController->Adapter_PortMappingChanged(
  873. Index,
  874. Protocol,
  875. Port
  876. );
  877. pIAlgController->Release();
  878. }
  879. if (FAILED(hr))
  880. {
  881. Error = ERROR_CAN_NOT_COMPLETE;
  882. }
  883. DEREFERENCE_ALG_AND_RETURN(Error);
  884. } // AlgRmPortMappingChanged
  885. //
  886. // Added for RRAS support
  887. //
  888. ULONG
  889. APIENTRY
  890. AlgRmGetEventMessage(
  891. OUT ROUTING_PROTOCOL_EVENTS* Event,
  892. OUT MESSAGE* Result
  893. )
  894. /*++
  895. Routine Description:
  896. This routine is invoked to retrieve an event message from the component.
  897. The only event message we generate is the 'ROUTER_STOPPED' message.
  898. Arguments:
  899. Event - receives the generated event
  900. Result - receives the associated result
  901. Return Value:
  902. ULONG - Win32 status code.
  903. --*/
  904. {
  905. if (InterlockedExchange((LPLONG)&AlgProtocolStopped, 0))
  906. {
  907. if ( NULL != Event )
  908. *Event = ROUTER_STOPPED;
  909. return NO_ERROR;
  910. }
  911. return ERROR_NO_MORE_ITEMS;
  912. } // AlgRmGetEventMessage
  913. ULONG
  914. APIENTRY
  915. AlgRmGetInterfaceInfo(
  916. ULONG Index,
  917. PVOID InterfaceInfo,
  918. IN OUT PULONG InterfaceInfoSize,
  919. IN OUT PULONG StructureVersion,
  920. IN OUT PULONG StructureSize,
  921. IN OUT PULONG StructureCount
  922. )
  923. /*++
  924. Routine Description:
  925. This routine is invoked to retrieve the component's per-interface
  926. configuration.
  927. Arguments:
  928. Index - the index of the interface to be queried
  929. InterfaceInfo - receives the query results
  930. InterfaceInfoSize - receives the amount of data retrieved
  931. Return Value:
  932. ULONG - Win32 status code.
  933. --*/
  934. {
  935. ULONG Error;
  936. REFERENCE_ALG_OR_RETURN(ERROR_CAN_NOT_COMPLETE);
  937. Error = AlgQueryInterface(Index,
  938. (PIP_ALG_INTERFACE_INFO)InterfaceInfo,
  939. InterfaceInfoSize);
  940. *StructureSize = *InterfaceInfoSize;
  941. if (StructureCount)
  942. {
  943. *StructureCount = 1;
  944. }
  945. DEREFERENCE_ALG_AND_RETURN(Error);
  946. } // AlgRmGetInterfaceInfo
  947. ULONG
  948. APIENTRY
  949. AlgRmSetInterfaceInfo(
  950. ULONG Index,
  951. PVOID InterfaceInfo,
  952. ULONG StructureVersion,
  953. ULONG StructureSize,
  954. ULONG StructureCount
  955. )
  956. /*++
  957. Routine Description:
  958. This routine is invoked to change the component's per-interface
  959. configuration.
  960. Arguments:
  961. Index - the index of the interface to be updated
  962. InterfaceInfo - supplies the new configuration
  963. Return Value:
  964. ULONG - Win32 status code.
  965. --*/
  966. {
  967. ULONG Error;
  968. REFERENCE_ALG_OR_RETURN(ERROR_CAN_NOT_COMPLETE);
  969. Error = AlgConfigureInterface(Index,
  970. (PIP_ALG_INTERFACE_INFO)InterfaceInfo);
  971. DEREFERENCE_ALG_AND_RETURN(Error);
  972. } // AlgRmSetInterfaceInfo
  973. ULONG
  974. APIENTRY
  975. AlgRmMibCreate(
  976. ULONG InputDataSize,
  977. PVOID InputData
  978. )
  979. {
  980. return ERROR_NOT_SUPPORTED;
  981. }
  982. ULONG
  983. APIENTRY
  984. AlgRmMibDelete(
  985. ULONG InputDataSize,
  986. PVOID InputData
  987. )
  988. {
  989. return ERROR_NOT_SUPPORTED;
  990. }
  991. ULONG
  992. APIENTRY
  993. AlgRmMibGet(
  994. ULONG InputDataSize,
  995. PVOID InputData,
  996. OUT PULONG OutputDataSize,
  997. OUT PVOID OutputData
  998. )
  999. /*++
  1000. Routine Description:
  1001. The transparent proxy only exposes one item to the MIB; its statistics.
  1002. Arguments:
  1003. InputDataSize - the MIB query data size
  1004. InputData - specifies the MIB object to be retrieved
  1005. OutputDataSize - the MIB response data size
  1006. OutputData - receives the MIB object retrieved
  1007. Return Value:
  1008. ULONG - Win32 status code.
  1009. --*/
  1010. {
  1011. ULONG Error;
  1012. PIP_ALG_MIB_QUERY Oidp;
  1013. REFERENCE_ALG_OR_RETURN(ERROR_CAN_NOT_COMPLETE);
  1014. if (InputDataSize < sizeof(*Oidp) || !OutputDataSize)
  1015. {
  1016. Error = ERROR_INVALID_PARAMETER;
  1017. }
  1018. else
  1019. {
  1020. Oidp = (PIP_ALG_MIB_QUERY)InputData;
  1021. switch (Oidp->Oid)
  1022. {
  1023. case IP_ALG_STATISTICS_OID:
  1024. {
  1025. if (*OutputDataSize < sizeof(*Oidp) + sizeof(AlgStatistics))
  1026. {
  1027. *OutputDataSize = sizeof(*Oidp) + sizeof(AlgStatistics);
  1028. Error = ERROR_INSUFFICIENT_BUFFER;
  1029. }
  1030. else
  1031. {
  1032. *OutputDataSize = sizeof(*Oidp) + sizeof(AlgStatistics);
  1033. Oidp = (PIP_ALG_MIB_QUERY)OutputData;
  1034. Oidp->Oid = IP_ALG_STATISTICS_OID;
  1035. CopyMemory(Oidp->Data,
  1036. &AlgStatistics,
  1037. sizeof(AlgStatistics));
  1038. Error = NO_ERROR;
  1039. }
  1040. break;
  1041. }
  1042. default:
  1043. {
  1044. NhTrace(TRACE_FLAG_ALG,
  1045. "AlgRmMibGet: oid %d invalid",
  1046. Oidp->Oid);
  1047. Error = ERROR_INVALID_PARAMETER;
  1048. break;
  1049. }
  1050. }
  1051. }
  1052. DEREFERENCE_ALG_AND_RETURN(Error);
  1053. }
  1054. ULONG
  1055. APIENTRY
  1056. AlgRmMibSet(
  1057. ULONG InputDataSize,
  1058. PVOID InputData
  1059. )
  1060. {
  1061. return ERROR_NOT_SUPPORTED;
  1062. }
  1063. ULONG
  1064. APIENTRY
  1065. AlgRmMibGetFirst(
  1066. ULONG InputDataSize,
  1067. PVOID InputData,
  1068. OUT PULONG OutputDataSize,
  1069. OUT PVOID OutputData
  1070. )
  1071. {
  1072. return ERROR_NOT_SUPPORTED;
  1073. }
  1074. ULONG
  1075. APIENTRY
  1076. AlgRmMibGetNext(
  1077. ULONG InputDataSize,
  1078. PVOID InputData,
  1079. OUT PULONG OutputDataSize,
  1080. OUT PVOID OutputData
  1081. )
  1082. {
  1083. return ERROR_NOT_SUPPORTED;
  1084. }