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.

835 lines
23 KiB

  1. /********************************************************************/
  2. /** Copyright(c) 1995 Microsoft Corporation. **/
  3. /********************************************************************/
  4. //***
  5. //
  6. // Filename: svchand.c
  7. //
  8. // Description: This module contains procedures to handle DDM service state
  9. // changes and startup initialization.
  10. //
  11. // History: May 11,1995 NarenG Created original version.
  12. //
  13. #define _ALLOCATE_DDM_GLOBALS_
  14. #include "ddm.h"
  15. #include "objects.h"
  16. #include "handlers.h"
  17. #include "rasmanif.h"
  18. #include "util.h"
  19. #include <ddmif.h>
  20. #include <ddmparms.h>
  21. #include "timer.h"
  22. #include "rassrvr.h"
  23. DWORD
  24. EventDispatcher(
  25. IN LPVOID arg
  26. );
  27. //***
  28. //
  29. // Function: DDMServiceStopComplete
  30. //
  31. // Descr: called by each device which has closed. Checks if all devices
  32. // are closed and if true signals the event dispatcher to
  33. // exit the "forever" loop and return.
  34. //
  35. //***
  36. VOID
  37. DDMServiceStopComplete(
  38. VOID
  39. )
  40. {
  41. //
  42. // check if all devices have been stopped
  43. //
  44. if ( DeviceObjIterator( DeviceObjIsClosed, TRUE, NULL ) != NO_ERROR )
  45. {
  46. DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
  47. "ServiceStopComplete:there are device pending close");
  48. //
  49. // there are still unclosed devices
  50. //
  51. return;
  52. }
  53. //
  54. //*** All Devices Are Closed at the Supervisor Level ***
  55. //
  56. DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
  57. "ServiceStopComplete: ALL devices closed");
  58. //
  59. // Notify connections that the service has stopped.
  60. //
  61. {
  62. RASEVENT RasEvent;
  63. ZeroMemory((PBYTE) &RasEvent, sizeof(RASEVENT));
  64. RasEvent.Type = SERVICE_EVENT;
  65. RasEvent.Event = RAS_SERVICE_STOPPED;
  66. RasEvent.Service = REMOTEACCESS;
  67. (void) RasSendNotification(&RasEvent);
  68. }
  69. //
  70. // notify the DIM that DDM has terminated. This will also cause the
  71. // event dispatcher and timer threads to die.
  72. //
  73. SetEvent( gblSupervisorEvents[DDM_EVENT_SVC_TERMINATED] );
  74. }
  75. //***
  76. //
  77. // Function: DDMServiceTerminate
  78. //
  79. // Descr: deallocates all resources and closes all dialin devices
  80. //
  81. //***
  82. VOID
  83. DDMServiceTerminate(
  84. VOID
  85. )
  86. {
  87. //
  88. // Disconnect all connected DDM interfaces
  89. //
  90. IfObjectDisconnectInterfaces();
  91. //
  92. // Wait for all disconenct notificaions to be processed
  93. //
  94. Sleep( 2000L );
  95. DeviceObjIterator( DeviceObjStartClosing, FALSE, NULL );
  96. //
  97. // UnRegister the notifier form rasman
  98. //
  99. (void) RasRegisterPnPHandler( (PAPCFUNC) DdmDevicePnpHandler,
  100. NULL,
  101. FALSE);
  102. //
  103. // check if all devices are closed and terminate if true
  104. //
  105. DDMServiceStopComplete();
  106. }
  107. //***
  108. //
  109. // Function: DDMServicePause
  110. //
  111. // Descr: disables listening on any active listenning ports. Sets
  112. // service global state to RAS_SERVICE_PAUSED. No new listen
  113. // will be posted when a client terminates.
  114. //
  115. //***
  116. VOID
  117. DDMServicePause(
  118. VOID
  119. )
  120. {
  121. WORD i;
  122. PDEVICE_OBJECT pDeviceObj;
  123. DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,"SvServicePause: Entered");
  124. //
  125. // Close all active listenning ports
  126. //
  127. DeviceObjIterator( DeviceObjCloseListening, FALSE, NULL );
  128. //
  129. // Notify all interfaces that they are not reachable
  130. //
  131. IfObjectNotifyAllOfReachabilityChange( FALSE, INTERFACE_SERVICE_IS_PAUSED );
  132. }
  133. //***
  134. //
  135. // Function: DDMServiceResume
  136. //
  137. // Descr: resumes listening on all ports.
  138. //
  139. //***
  140. VOID
  141. DDMServiceResume(
  142. VOID
  143. )
  144. {
  145. WORD i;
  146. PDEVICE_OBJECT pDeviceObj;
  147. DDM_PRINT(gblDDMConfigInfo.dwTraceId,TRACE_FSM,"SvServiceResume: Entered");
  148. //
  149. // resume listening on all closed devices
  150. //
  151. DeviceObjIterator( DeviceObjResumeListening, FALSE, NULL );
  152. //
  153. // Notify all interfaces that they are reachable now.
  154. //
  155. IfObjectNotifyAllOfReachabilityChange( TRUE, INTERFACE_SERVICE_IS_PAUSED );
  156. }
  157. //***
  158. //
  159. // Function: DDMServiceInitialize
  160. //
  161. // Descrption: It does init work as follows:
  162. // Loads the configuration parameters
  163. // Loads the security module if there is one.
  164. // Creates the event flags
  165. // Initializes the message DLL
  166. // Opens all dialin devices
  167. // Initializes the DCBs
  168. // Initializes the authentication DLL
  169. // Posts listen on all opened dialin devices
  170. //
  171. // NOTE: Also changing the working set size for this process
  172. // will change it for all the services in this process.
  173. // Is this OK?
  174. // What do we do about the security check call?
  175. //
  176. // Returns: NO_ERROR - Sucess
  177. // non-zero - Failure
  178. //
  179. //***
  180. DWORD
  181. DDMServiceInitialize(
  182. IN DIM_INFO * DimInfo
  183. )
  184. {
  185. DWORD dwIndex;
  186. DWORD ThreadId;
  187. QUOTA_LIMITS ql;
  188. NTSTATUS ntStatus = STATUS_SUCCESS;
  189. DWORD dwRetCode = NO_ERROR;
  190. HANDLE hEventDispatcher = NULL;
  191. DEVICE_OBJECT * pDeviceObj = NULL;
  192. HPORT * phPorts = NULL;
  193. BOOL fIpAllowed = FALSE;
  194. LPVOID lpfnRasAuthProviderFreeAttributes = NULL;
  195. LPVOID lpfnRasAuthProviderAuthenticateUser = NULL;
  196. LPVOID lpfnRasAuthConfigChangeNotification = NULL;
  197. LPVOID lpfnRasAcctProviderStartAccounting = NULL;
  198. LPVOID lpfnRasAcctProviderInterimAccounting = NULL;
  199. LPVOID lpfnRasAcctProviderStopAccounting = NULL;
  200. LPVOID lpfnRasAcctProviderFreeAttributes = NULL;
  201. LPVOID lpfnRasAcctConfigChangeNotification = NULL;
  202. DWORD dwLocalIpAddress = 0;
  203. ZeroMemory( &gblDDMConfigInfo, sizeof( gblDDMConfigInfo ) );
  204. gblDDMConfigInfo.fRasSrvrInitialized = FALSE;
  205. gblDDMConfigInfo.hIpHlpApi = NULL;
  206. gblDDMConfigInfo.lpfnAllocateAndGetIfTableFromStack = NULL;
  207. gblDDMConfigInfo.lpfnAllocateAndGetIpAddrTableFromStack = NULL;
  208. gblDDMConfigInfo.dwNumRouterManagers = DimInfo->dwNumRouterManagers;
  209. gblRouterManagers = DimInfo->pRouterManagers;
  210. gblpInterfaceTable = DimInfo->pInterfaceTable;
  211. gblDDMConfigInfo.pServiceStatus = DimInfo->pServiceStatus;
  212. gblDDMConfigInfo.dwTraceId = DimInfo->dwTraceId;
  213. gblDDMConfigInfo.hLogEvents = DimInfo->hLogEvents;
  214. gblphEventDDMServiceState = DimInfo->phEventDDMServiceState;
  215. gblphEventDDMTerminated = DimInfo->phEventDDMTerminated;
  216. gblDDMConfigInfo.lpdwNumThreadsRunning = DimInfo->lpdwNumThreadsRunning;
  217. gblDDMConfigInfo.lpfnIfObjectRemove = DimInfo->lpfnIfObjectRemove;
  218. gblDDMConfigInfo.lpfnIfObjectGetPointer = DimInfo->lpfnIfObjectGetPointer;
  219. gblDDMConfigInfo.lpfnIfObjectInsertInTable =
  220. DimInfo->lpfnIfObjectInsertInTable;
  221. gblDDMConfigInfo.lpfnIfObjectAllocateAndInit =
  222. DimInfo->lpfnIfObjectAllocateAndInit;
  223. gblDDMConfigInfo.lpfnIfObjectGetPointerByName =
  224. DimInfo->lpfnIfObjectGetPointerByName;
  225. gblDDMConfigInfo.lpfnIfObjectWANDeviceInstalled =
  226. DimInfo->lpfnIfObjectWANDeviceInstalled;
  227. gblDDMConfigInfo.lpfnRouterIdentityObjectUpdate =
  228. DimInfo->lpfnRouterIdentityObjectUpdate;
  229. gblDDMConfigInfo.fRasmanReferenced = FALSE;
  230. DimInfo->fWANDeviceInstalled = FALSE;
  231. //
  232. // Create DDM private heap
  233. //
  234. gblDDMConfigInfo.hHeap = HeapCreate( 0, DDM_HEAP_INITIAL_SIZE,
  235. DDM_HEAP_MAX_SIZE );
  236. if ( gblDDMConfigInfo.hHeap == NULL )
  237. {
  238. return( GetLastError() );
  239. }
  240. InitializeCriticalSection( &(gblDeviceTable.CriticalSection) );
  241. do
  242. {
  243. //
  244. // initialize the rasman module
  245. //
  246. if ( ( dwRetCode = RasInitialize() ) != NO_ERROR )
  247. {
  248. //
  249. // can't start rasman
  250. //
  251. DDMLogErrorString( ROUTERLOG_RASMAN_NOT_AVAILABLE,
  252. 0, NULL, dwRetCode, 0 );
  253. break;
  254. }
  255. //
  256. // Increase rasman's reference count since we are in the same process
  257. // this does not happen automatically
  258. //
  259. if ( dwRetCode = RasReferenceRasman( TRUE ) )
  260. {
  261. //
  262. // can't start rasman
  263. //
  264. DDMLogErrorString( ROUTERLOG_RASMAN_NOT_AVAILABLE,
  265. 0, NULL, dwRetCode, 0 );
  266. break;
  267. }
  268. gblDDMConfigInfo.fRasmanReferenced = TRUE;
  269. //
  270. // Check if there is any security agent on the network. If there is,
  271. // we check with it if we can start up or not.
  272. //
  273. /*
  274. if ( SecurityCheck() )
  275. {
  276. dwRetCode = ERROR_SERVICE_DISABLED;
  277. break;
  278. }
  279. */
  280. if ( ( dwRetCode = GetRouterPhoneBook() ) != NO_ERROR )
  281. {
  282. break;
  283. }
  284. if ( ( dwRetCode = LoadStrings() ) != NO_ERROR )
  285. {
  286. break;
  287. }
  288. //
  289. // get handle to the supervisor parameters key
  290. //
  291. if ( dwRetCode = RegOpenKey( HKEY_LOCAL_MACHINE,
  292. DDM_PARAMETERS_KEY_PATH,
  293. &(gblDDMConfigInfo.hkeyParameters) ))
  294. {
  295. WCHAR * pwChar = DDM_PARAMETERS_KEY_PATH;
  296. DDMLogError( ROUTERLOG_CANT_OPEN_REGKEY, 1, &pwChar, dwRetCode);
  297. break;
  298. }
  299. if ( dwRetCode = RegOpenKey( HKEY_LOCAL_MACHINE,
  300. DDM_ACCOUNTING_KEY_PATH,
  301. &(gblDDMConfigInfo.hkeyAccounting) ))
  302. {
  303. WCHAR * pwChar = DDM_ACCOUNTING_KEY_PATH;
  304. DDMLogError( ROUTERLOG_CANT_OPEN_REGKEY, 1, &pwChar, dwRetCode);
  305. break;
  306. }
  307. if ( dwRetCode = RegOpenKey( HKEY_LOCAL_MACHINE,
  308. DDM_AUTHENTICATION_KEY_PATH,
  309. &(gblDDMConfigInfo.hkeyAuthentication) ))
  310. {
  311. WCHAR * pwChar = DDM_AUTHENTICATION_KEY_PATH;
  312. DDMLogError( ROUTERLOG_CANT_OPEN_REGKEY, 1, &pwChar, dwRetCode);
  313. break;
  314. }
  315. if ( ( dwRetCode = LoadDDMParameters( gblDDMConfigInfo.hkeyParameters,
  316. &fIpAllowed) )
  317. != NO_ERROR )
  318. {
  319. //
  320. // error loading parameters
  321. //
  322. break;
  323. }
  324. //
  325. // Load the secuirity module if there is one.
  326. //
  327. if ( ( dwRetCode = LoadSecurityModule() ) != NO_ERROR )
  328. {
  329. //
  330. // error loading security dll
  331. //
  332. break;
  333. }
  334. //
  335. // Load the third party admin module if there is one
  336. //
  337. if ( ( dwRetCode = LoadAdminModule() ) != NO_ERROR )
  338. {
  339. //
  340. // error loading admin module dll
  341. //
  342. break;
  343. }
  344. //
  345. // Initialize and allocate the media object table
  346. //
  347. if ( ( dwRetCode = MediaObjInitializeTable() ) != NO_ERROR )
  348. {
  349. DDMLogError(ROUTERLOG_NOT_ENOUGH_MEMORY, 0, NULL, dwRetCode );
  350. break;
  351. }
  352. //
  353. // This call allocates memory for all enumed devices with dialin
  354. // capability, opens each device and updates the port handle and
  355. // the port name in the DCB.
  356. //
  357. if ((dwRetCode = RmInit(&(DimInfo->fWANDeviceInstalled))) != NO_ERROR)
  358. {
  359. break;
  360. }
  361. //
  362. // Allocate the supervisor events array, 2 per device bucket since there
  363. // are 2 rasman events per device, state change and frame received.
  364. //
  365. gblSupervisorEvents = (HANDLE *)LOCAL_ALLOC( LPTR,
  366. (NUM_DDM_EVENTS + (gblDeviceTable.NumDeviceBuckets * 3))
  367. * sizeof( HANDLE ) );
  368. if ( gblSupervisorEvents == (HANDLE *)NULL )
  369. {
  370. dwRetCode = GetLastError();
  371. DDMLogError(ROUTERLOG_NOT_ENOUGH_MEMORY, 0, NULL, dwRetCode );
  372. break;
  373. }
  374. //
  375. // Create the DDM Events
  376. //
  377. for ( dwIndex = 0;
  378. dwIndex < (NUM_DDM_EVENTS+(gblDeviceTable.NumDeviceBuckets * 3));
  379. dwIndex ++ )
  380. {
  381. switch( dwIndex )
  382. {
  383. case DDM_EVENT_SVC:
  384. gblSupervisorEvents[dwIndex]=*gblphEventDDMServiceState;
  385. gblEventHandlerTable[dwIndex].EventHandler = SvcEventHandler;
  386. break;
  387. case DDM_EVENT_SVC_TERMINATED:
  388. gblSupervisorEvents[dwIndex]=*gblphEventDDMTerminated;
  389. break;
  390. case DDM_EVENT_TIMER:
  391. gblSupervisorEvents[dwIndex]=CreateWaitableTimer( NULL,
  392. FALSE,
  393. NULL );
  394. gblEventHandlerTable[dwIndex].EventHandler = TimerHandler;
  395. break;
  396. case DDM_EVENT_SECURITY_DLL:
  397. gblSupervisorEvents[dwIndex]=CreateEvent(NULL,FALSE,FALSE,NULL);
  398. gblEventHandlerTable[dwIndex].EventHandler =
  399. SecurityDllEventHandler;
  400. break;
  401. case DDM_EVENT_PPP:
  402. gblSupervisorEvents[dwIndex]=CreateEvent(NULL,FALSE,FALSE,NULL);
  403. gblEventHandlerTable[dwIndex].EventHandler = PppEventHandler;
  404. break;
  405. case DDM_EVENT_CHANGE_NOTIFICATION:
  406. case DDM_EVENT_CHANGE_NOTIFICATION1:
  407. case DDM_EVENT_CHANGE_NOTIFICATION2:
  408. gblSupervisorEvents[dwIndex]=CreateEvent(NULL,FALSE,FALSE,NULL);
  409. gblEventHandlerTable[dwIndex].EventHandler =
  410. ChangeNotificationEventHandler;
  411. break;
  412. default:
  413. //
  414. // RasMan events
  415. //
  416. gblSupervisorEvents[dwIndex]=CreateEvent(NULL,FALSE,FALSE,NULL);
  417. break;
  418. }
  419. if ( gblSupervisorEvents[dwIndex] == NULL )
  420. {
  421. dwRetCode = GetLastError();
  422. break;
  423. }
  424. }
  425. //
  426. // Initialize the Message Mechanism
  427. //
  428. InitializeMessageQs( gblSupervisorEvents[DDM_EVENT_SECURITY_DLL],
  429. gblSupervisorEvents[DDM_EVENT_PPP] );
  430. //
  431. // Register the device hEvents with RasMan
  432. //
  433. dwRetCode = DeviceObjIterator(DeviceObjRequestNotification,TRUE,NULL);
  434. if ( dwRetCode != NO_ERROR )
  435. {
  436. break;
  437. }
  438. if ( fIpAllowed )
  439. {
  440. //
  441. // GetLocalNASIpAddress tries to load iphlpapi.dll. iphlpapi.dll
  442. // tries to load dhcpcsvc.dll. The latter fails unless TCP/IP is
  443. // installed and a popup appears.
  444. //
  445. dwLocalIpAddress = GetLocalNASIpAddress();
  446. }
  447. //
  448. // Load the configured authentication provider
  449. //
  450. dwRetCode = LoadAndInitAuthOrAcctProvider(
  451. TRUE,
  452. dwLocalIpAddress,
  453. NULL,
  454. &lpfnRasAuthProviderAuthenticateUser,
  455. &lpfnRasAuthProviderFreeAttributes,
  456. &lpfnRasAuthConfigChangeNotification,
  457. NULL,
  458. NULL,
  459. NULL,
  460. NULL,
  461. NULL );
  462. if ( dwRetCode != NO_ERROR )
  463. {
  464. DDMLogErrorString( ROUTERLOG_AUTHPROVIDER_FAILED_INIT,
  465. 0, NULL, dwRetCode, 0);
  466. break;
  467. }
  468. gblDDMConfigInfo.lpfnRasAuthConfigChangeNotification = (DWORD(*)(DWORD))
  469. lpfnRasAuthConfigChangeNotification;
  470. //
  471. // Load the configured accounting provider
  472. //
  473. dwRetCode = LoadAndInitAuthOrAcctProvider(
  474. FALSE,
  475. dwLocalIpAddress,
  476. &(gblDDMConfigInfo.dwAccountingSessionId),
  477. NULL,
  478. NULL,
  479. NULL,
  480. &lpfnRasAcctProviderStartAccounting,
  481. &lpfnRasAcctProviderInterimAccounting,
  482. &lpfnRasAcctProviderStopAccounting,
  483. &lpfnRasAcctProviderFreeAttributes,
  484. &lpfnRasAcctConfigChangeNotification );
  485. if ( dwRetCode != NO_ERROR )
  486. {
  487. DDMLogErrorString( ROUTERLOG_ACCTPROVIDER_FAILED_INIT,
  488. 0, NULL, dwRetCode, 0);
  489. break;
  490. }
  491. gblDDMConfigInfo.lpfnRasAcctConfigChangeNotification = (DWORD(*)(DWORD))
  492. lpfnRasAcctConfigChangeNotification;
  493. InitializeCriticalSection( &(gblDDMConfigInfo.CSAccountingSessionId) );
  494. //
  495. // Initialize PPP RASIPHLP DLL
  496. //
  497. if ( fIpAllowed )
  498. {
  499. dwRetCode = RasSrvrInitialize(
  500. gblDDMConfigInfo.lpfnMprAdminGetIpAddressForUser,
  501. gblDDMConfigInfo.lpfnMprAdminReleaseIpAddress );
  502. if ( dwRetCode != NO_ERROR )
  503. {
  504. DDMLogErrorString( ROUTERLOG_CANT_INITIALIZE_IP_SERVER,
  505. 0, NULL, dwRetCode, 0 );
  506. break;
  507. }
  508. gblDDMConfigInfo.fRasSrvrInitialized = TRUE;
  509. }
  510. //
  511. // Init Timer Q
  512. //
  513. if ( ( dwRetCode = TimerQInitialize() ) != NO_ERROR )
  514. {
  515. break;
  516. }
  517. //
  518. // Start the timer
  519. //
  520. {
  521. LARGE_INTEGER DueTime;
  522. DueTime.QuadPart = Int32x32To64((LONG)1000, -10000);
  523. if ( !SetWaitableTimer( gblSupervisorEvents[DDM_EVENT_TIMER],
  524. &DueTime, 1000, NULL, NULL, FALSE) )
  525. {
  526. dwRetCode = GetLastError();
  527. break;
  528. }
  529. }
  530. //
  531. // Initialize PPP engine DLL
  532. //
  533. dwRetCode = PppDdmInit(
  534. SendPppMessageToDDM,
  535. gblDDMConfigInfo.dwServerFlags,
  536. gblDDMConfigInfo.dwLoggingLevel,
  537. dwLocalIpAddress,
  538. gblDDMConfigInfo.fFlags&DDM_USING_RADIUS_AUTHENTICATION,
  539. lpfnRasAuthProviderAuthenticateUser,
  540. lpfnRasAuthProviderFreeAttributes,
  541. lpfnRasAcctProviderStartAccounting,
  542. lpfnRasAcctProviderInterimAccounting,
  543. lpfnRasAcctProviderStopAccounting,
  544. lpfnRasAcctProviderFreeAttributes,
  545. (LPVOID)GetNextAccountingSessionId );
  546. if ( dwRetCode != NO_ERROR )
  547. {
  548. DDMLogErrorString(ROUTERLOG_PPP_INIT_FAILED, 0, NULL, dwRetCode, 0);
  549. break;
  550. }
  551. //
  552. // Create the Event dispatcher thread
  553. //
  554. if ( ( hEventDispatcher = CreateThread( NULL, 0, EventDispatcher,
  555. NULL, 0, &ThreadId)) == 0 )
  556. {
  557. //
  558. // cannot create event dispatcher thread
  559. //
  560. dwRetCode = GetLastError();
  561. break;
  562. }
  563. //
  564. // Register for plug and play notifications with RASMAN
  565. //
  566. dwRetCode = RasRegisterPnPHandler( (PAPCFUNC) DdmDevicePnpHandler,
  567. hEventDispatcher,
  568. TRUE);
  569. if ( dwRetCode != NO_ERROR )
  570. {
  571. break;
  572. }
  573. //
  574. // Initialize notification event list
  575. //
  576. InitializeListHead( &(gblDDMConfigInfo.NotificationEventListHead) );
  577. //
  578. // Initialize the array of Analog/Digital Ip Addresses.
  579. //
  580. dwRetCode = AddressPoolInit();
  581. if( dwRetCode != NO_ERROR )
  582. {
  583. break;
  584. }
  585. if(gblDDMConfigInfo.dwServerFlags & PPPCFG_AudioAccelerator)
  586. {
  587. //
  588. // Call rasman to initialize rasaudio. Ignore the error
  589. // - rasman will event log and clean up if required.
  590. //
  591. (void) RasEnableRasAudio(NULL,TRUE);
  592. }
  593. gblDDMConfigInfo.dwIndex = 0;
  594. /*
  595. TimerQInsert( NULL,
  596. gblDDMConfigInfo.dwAnnouncePresenceTimer,
  597. AnnouncePresenceHandler );
  598. */
  599. //
  600. // Send notification to the connections folder that ddm
  601. // has started.
  602. //
  603. {
  604. RASEVENT RasEvent;
  605. ZeroMemory((PBYTE) &RasEvent, sizeof(RASEVENT));
  606. RasEvent.Type = SERVICE_EVENT;
  607. RasEvent.Event = RAS_SERVICE_STARTED;
  608. RasEvent.Service = REMOTEACCESS;
  609. (void) RasSendNotification(&RasEvent);
  610. }
  611. return( NO_ERROR );
  612. } while ( FALSE );
  613. //
  614. // We call DDMCleanUp before setting the gblphEventDDMTerminated because
  615. // otherwise the DIM dll will be unloaded while DDMCleanUp is being
  616. // executed
  617. //
  618. DDMCleanUp();
  619. //
  620. // Will terminate the event dispatcher thread if it started
  621. // and will notify DIM that the service is terminated.
  622. //
  623. if(NULL != gblphEventDDMTerminated)
  624. {
  625. SetEvent( *gblphEventDDMTerminated );
  626. }
  627. gblphEventDDMTerminated = NULL;
  628. return( dwRetCode );
  629. }
  630. //***
  631. //
  632. // Function: SvcEventHandler
  633. //
  634. // Descrption: Invoked following the event signaled by the handler registered
  635. // with the service controller. Replaces old service state with
  636. // the new state and calls the appropriate handler.
  637. //
  638. //***
  639. VOID
  640. SvcEventHandler(
  641. VOID
  642. )
  643. {
  644. EnterCriticalSection( &(gblDeviceTable.CriticalSection) );
  645. switch ( gblDDMConfigInfo.pServiceStatus->dwCurrentState )
  646. {
  647. case SERVICE_RUNNING:
  648. DDMServiceResume();
  649. break;
  650. case SERVICE_PAUSED:
  651. DDMServicePause();
  652. break;
  653. case SERVICE_STOP_PENDING:
  654. DDMServiceTerminate();
  655. break;
  656. default:
  657. RTASSERT(FALSE);
  658. }
  659. LeaveCriticalSection( &(gblDeviceTable.CriticalSection) );
  660. }