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.

881 lines
25 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. DWORD dwCSFlags = 0;
  204. #define TIMERQCS_INITIALIZED 0x00000001
  205. #define DEVICETABLECS_INITIALIZED 0x00000002
  206. #define ACCOUNTINGSESSIONCS_INITIALIZED 0x00000004
  207. #define MEDIATABLECS_INITIALIZED 0x00000008
  208. ZeroMemory( &gblDDMConfigInfo, sizeof( gblDDMConfigInfo ) );
  209. gblDDMConfigInfo.fRasSrvrInitialized = FALSE;
  210. gblDDMConfigInfo.hIpHlpApi = NULL;
  211. gblDDMConfigInfo.lpfnAllocateAndGetIfTableFromStack = NULL;
  212. gblDDMConfigInfo.lpfnAllocateAndGetIpAddrTableFromStack = NULL;
  213. gblDDMConfigInfo.dwNumRouterManagers = DimInfo->dwNumRouterManagers;
  214. gblRouterManagers = DimInfo->pRouterManagers;
  215. gblpInterfaceTable = DimInfo->pInterfaceTable;
  216. gblDDMConfigInfo.pServiceStatus = DimInfo->pServiceStatus;
  217. gblDDMConfigInfo.dwTraceId = DimInfo->dwTraceId;
  218. gblDDMConfigInfo.hLogEvents = DimInfo->hLogEvents;
  219. gblphEventDDMServiceState = DimInfo->phEventDDMServiceState;
  220. gblphEventDDMTerminated = DimInfo->phEventDDMTerminated;
  221. gblDDMConfigInfo.lpdwNumThreadsRunning = DimInfo->lpdwNumThreadsRunning;
  222. gblDDMConfigInfo.lpfnIfObjectRemove = DimInfo->lpfnIfObjectRemove;
  223. gblDDMConfigInfo.lpfnIfObjectGetPointer = DimInfo->lpfnIfObjectGetPointer;
  224. gblDDMConfigInfo.lpfnIfObjectInsertInTable =
  225. DimInfo->lpfnIfObjectInsertInTable;
  226. gblDDMConfigInfo.lpfnIfObjectAllocateAndInit =
  227. DimInfo->lpfnIfObjectAllocateAndInit;
  228. gblDDMConfigInfo.lpfnIfObjectGetPointerByName =
  229. DimInfo->lpfnIfObjectGetPointerByName;
  230. gblDDMConfigInfo.lpfnIfObjectWANDeviceInstalled =
  231. DimInfo->lpfnIfObjectWANDeviceInstalled;
  232. gblDDMConfigInfo.lpfnRouterIdentityObjectUpdate =
  233. DimInfo->lpfnRouterIdentityObjectUpdate;
  234. gblDDMConfigInfo.fRasmanReferenced = FALSE;
  235. DimInfo->fWANDeviceInstalled = FALSE;
  236. try
  237. {
  238. (VOID) TimerQInitialize();
  239. dwCSFlags |= TIMERQCS_INITIALIZED;
  240. InitializeCriticalSection(
  241. &(gblDeviceTable.CriticalSection) );
  242. dwCSFlags |= DEVICETABLECS_INITIALIZED;
  243. InitializeCriticalSection( &(gblMediaTable.CriticalSection) );
  244. dwCSFlags |= MEDIATABLECS_INITIALIZED;
  245. InitializeCriticalSection(
  246. &(gblDDMConfigInfo.CSAccountingSessionId) );
  247. dwCSFlags |= ACCOUNTINGSESSIONCS_INITIALIZED;
  248. }
  249. except (EXCEPTION_EXECUTE_HANDLER)
  250. {
  251. dwRetCode = GetExceptionCode();
  252. if(dwCSFlags & TIMERQCS_INITIALIZED)
  253. {
  254. TimerQDelete();
  255. }
  256. if(dwCSFlags & DEVICETABLECS_INITIALIZED)
  257. {
  258. DeleteCriticalSection(
  259. &gblDeviceTable.CriticalSection);
  260. }
  261. if(dwCSFlags & MEDIATABLECS_INITIALIZED)
  262. {
  263. DeleteCriticalSection(
  264. &gblMediaTable.CriticalSection);
  265. }
  266. return dwRetCode;
  267. }
  268. do
  269. {
  270. //
  271. // Create DDM private heap
  272. //
  273. gblDDMConfigInfo.hHeap = HeapCreate( 0, DDM_HEAP_INITIAL_SIZE,
  274. DDM_HEAP_MAX_SIZE );
  275. if ( gblDDMConfigInfo.hHeap == NULL )
  276. {
  277. dwRetCode = GetLastError();
  278. break;
  279. }
  280. //
  281. // Allocate and initialize the media object table.
  282. //
  283. if ( ( dwRetCode = MediaObjInitializeTable() ) != NO_ERROR )
  284. {
  285. DDMLogError(ROUTERLOG_NOT_ENOUGH_MEMORY, 0, NULL, dwRetCode );
  286. break;
  287. }
  288. //
  289. // initialize the rasman module
  290. //
  291. if ( ( dwRetCode = RasInitialize() ) != NO_ERROR )
  292. {
  293. //
  294. // can't start rasman
  295. //
  296. DDMLogErrorString( ROUTERLOG_RASMAN_NOT_AVAILABLE,
  297. 0, NULL, dwRetCode, 0 );
  298. break;
  299. }
  300. //
  301. // Increase rasman's reference count since we are in the same process
  302. // this does not happen automatically
  303. //
  304. if ( dwRetCode = RasReferenceRasman( TRUE ) )
  305. {
  306. //
  307. // can't start rasman
  308. //
  309. DDMLogErrorString( ROUTERLOG_RASMAN_NOT_AVAILABLE,
  310. 0, NULL, dwRetCode, 0 );
  311. break;
  312. }
  313. gblDDMConfigInfo.fRasmanReferenced = TRUE;
  314. //
  315. // Check if there is any security agent on the network. If there is,
  316. // we check with it if we can start up or not.
  317. //
  318. /*
  319. if ( SecurityCheck() )
  320. {
  321. dwRetCode = ERROR_SERVICE_DISABLED;
  322. break;
  323. }
  324. */
  325. if ( ( dwRetCode = GetRouterPhoneBook() ) != NO_ERROR )
  326. {
  327. break;
  328. }
  329. if ( ( dwRetCode = LoadStrings() ) != NO_ERROR )
  330. {
  331. break;
  332. }
  333. //
  334. // get handle to the supervisor parameters key
  335. //
  336. if ( dwRetCode = RegOpenKey( HKEY_LOCAL_MACHINE,
  337. DDM_PARAMETERS_KEY_PATH,
  338. &(gblDDMConfigInfo.hkeyParameters) ))
  339. {
  340. WCHAR * pwChar = DDM_PARAMETERS_KEY_PATH;
  341. DDMLogError( ROUTERLOG_CANT_OPEN_REGKEY, 1, &pwChar, dwRetCode);
  342. break;
  343. }
  344. if ( dwRetCode = RegOpenKey( HKEY_LOCAL_MACHINE,
  345. DDM_ACCOUNTING_KEY_PATH,
  346. &(gblDDMConfigInfo.hkeyAccounting) ))
  347. {
  348. WCHAR * pwChar = DDM_ACCOUNTING_KEY_PATH;
  349. DDMLogError( ROUTERLOG_CANT_OPEN_REGKEY, 1, &pwChar, dwRetCode);
  350. break;
  351. }
  352. if ( dwRetCode = RegOpenKey( HKEY_LOCAL_MACHINE,
  353. DDM_AUTHENTICATION_KEY_PATH,
  354. &(gblDDMConfigInfo.hkeyAuthentication) ))
  355. {
  356. WCHAR * pwChar = DDM_AUTHENTICATION_KEY_PATH;
  357. DDMLogError( ROUTERLOG_CANT_OPEN_REGKEY, 1, &pwChar, dwRetCode);
  358. break;
  359. }
  360. if ( ( dwRetCode = LoadDDMParameters( gblDDMConfigInfo.hkeyParameters,
  361. &fIpAllowed) )
  362. != NO_ERROR )
  363. {
  364. //
  365. // error loading parameters
  366. //
  367. break;
  368. }
  369. //
  370. // Load the secuirity module if there is one.
  371. //
  372. if ( ( dwRetCode = LoadSecurityModule() ) != NO_ERROR )
  373. {
  374. //
  375. // error loading security dll
  376. //
  377. break;
  378. }
  379. //
  380. // Load the third party admin module if there is one
  381. //
  382. if ( ( dwRetCode = LoadAdminModule() ) != NO_ERROR )
  383. {
  384. //
  385. // error loading admin module dll
  386. //
  387. break;
  388. }
  389. //
  390. // This call allocates memory for all enumed devices with dialin
  391. // capability, opens each device and updates the port handle and
  392. // the port name in the DCB.
  393. //
  394. if ((dwRetCode = RmInit(&(DimInfo->fWANDeviceInstalled))) != NO_ERROR)
  395. {
  396. break;
  397. }
  398. //
  399. // Allocate the supervisor events array, 2 per device bucket since there
  400. // are 2 rasman events per device, state change and frame received.
  401. //
  402. gblSupervisorEvents = (HANDLE *)LOCAL_ALLOC( LPTR,
  403. (NUM_DDM_EVENTS + (gblDeviceTable.NumDeviceBuckets * 3))
  404. * sizeof( HANDLE ) );
  405. if ( gblSupervisorEvents == (HANDLE *)NULL )
  406. {
  407. dwRetCode = GetLastError();
  408. DDMLogError(ROUTERLOG_NOT_ENOUGH_MEMORY, 0, NULL, dwRetCode );
  409. break;
  410. }
  411. //
  412. // Create the DDM Events
  413. //
  414. for ( dwIndex = 0;
  415. dwIndex < (NUM_DDM_EVENTS+(gblDeviceTable.NumDeviceBuckets * 3));
  416. dwIndex ++ )
  417. {
  418. switch( dwIndex )
  419. {
  420. case DDM_EVENT_SVC:
  421. gblSupervisorEvents[dwIndex]=*gblphEventDDMServiceState;
  422. gblEventHandlerTable[dwIndex].EventHandler = SvcEventHandler;
  423. break;
  424. case DDM_EVENT_SVC_TERMINATED:
  425. gblSupervisorEvents[dwIndex]=*gblphEventDDMTerminated;
  426. break;
  427. case DDM_EVENT_TIMER:
  428. gblSupervisorEvents[dwIndex]=CreateWaitableTimer( NULL,
  429. FALSE,
  430. NULL );
  431. gblEventHandlerTable[dwIndex].EventHandler = TimerHandler;
  432. break;
  433. case DDM_EVENT_SECURITY_DLL:
  434. gblSupervisorEvents[dwIndex]=CreateEvent(NULL,FALSE,FALSE,NULL);
  435. gblEventHandlerTable[dwIndex].EventHandler =
  436. SecurityDllEventHandler;
  437. break;
  438. case DDM_EVENT_PPP:
  439. gblSupervisorEvents[dwIndex]=CreateEvent(NULL,FALSE,FALSE,NULL);
  440. gblEventHandlerTable[dwIndex].EventHandler = PppEventHandler;
  441. break;
  442. case DDM_EVENT_CHANGE_NOTIFICATION:
  443. case DDM_EVENT_CHANGE_NOTIFICATION1:
  444. case DDM_EVENT_CHANGE_NOTIFICATION2:
  445. gblSupervisorEvents[dwIndex]=CreateEvent(NULL,FALSE,FALSE,NULL);
  446. gblEventHandlerTable[dwIndex].EventHandler =
  447. ChangeNotificationEventHandler;
  448. break;
  449. default:
  450. //
  451. // RasMan events
  452. //
  453. gblSupervisorEvents[dwIndex]=CreateEvent(NULL,FALSE,FALSE,NULL);
  454. break;
  455. }
  456. if ( gblSupervisorEvents[dwIndex] == NULL )
  457. {
  458. dwRetCode = GetLastError();
  459. break;
  460. }
  461. }
  462. //
  463. // Initialize the Message Mechanism
  464. //
  465. InitializeMessageQs( gblSupervisorEvents[DDM_EVENT_SECURITY_DLL],
  466. gblSupervisorEvents[DDM_EVENT_PPP] );
  467. //
  468. // Register the device hEvents with RasMan
  469. //
  470. dwRetCode = DeviceObjIterator(DeviceObjRequestNotification,TRUE,NULL);
  471. if ( dwRetCode != NO_ERROR )
  472. {
  473. break;
  474. }
  475. if ( fIpAllowed )
  476. {
  477. //
  478. // GetLocalNASIpAddress tries to load iphlpapi.dll. iphlpapi.dll
  479. // tries to load dhcpcsvc.dll. The latter fails unless TCP/IP is
  480. // installed and a popup appears.
  481. //
  482. dwLocalIpAddress = GetLocalNASIpAddress();
  483. }
  484. //
  485. // Load the configured authentication provider
  486. //
  487. dwRetCode = LoadAndInitAuthOrAcctProvider(
  488. TRUE,
  489. dwLocalIpAddress,
  490. NULL,
  491. &lpfnRasAuthProviderAuthenticateUser,
  492. &lpfnRasAuthProviderFreeAttributes,
  493. &lpfnRasAuthConfigChangeNotification,
  494. NULL,
  495. NULL,
  496. NULL,
  497. NULL,
  498. NULL );
  499. if ( dwRetCode != NO_ERROR )
  500. {
  501. DDMLogErrorString( ROUTERLOG_AUTHPROVIDER_FAILED_INIT,
  502. 0, NULL, dwRetCode, 0);
  503. break;
  504. }
  505. gblDDMConfigInfo.lpfnRasAuthConfigChangeNotification = (DWORD(*)(DWORD))
  506. lpfnRasAuthConfigChangeNotification;
  507. //
  508. // Load the configured accounting provider
  509. //
  510. dwRetCode = LoadAndInitAuthOrAcctProvider(
  511. FALSE,
  512. dwLocalIpAddress,
  513. &(gblDDMConfigInfo.dwAccountingSessionId),
  514. NULL,
  515. NULL,
  516. NULL,
  517. &lpfnRasAcctProviderStartAccounting,
  518. &lpfnRasAcctProviderInterimAccounting,
  519. &lpfnRasAcctProviderStopAccounting,
  520. &lpfnRasAcctProviderFreeAttributes,
  521. &lpfnRasAcctConfigChangeNotification );
  522. if ( dwRetCode != NO_ERROR )
  523. {
  524. DDMLogErrorString( ROUTERLOG_ACCTPROVIDER_FAILED_INIT,
  525. 0, NULL, dwRetCode, 0);
  526. break;
  527. }
  528. gblDDMConfigInfo.lpfnRasAcctConfigChangeNotification = (DWORD(*)(DWORD))
  529. lpfnRasAcctConfigChangeNotification;
  530. //
  531. // Initialize PPP RASIPHLP DLL
  532. //
  533. if ( fIpAllowed )
  534. {
  535. DWORD i;
  536. BOOL bCalled = FALSE;
  537. for (i=0; i<gblDDMConfigInfo.NumAdminDlls; i++)
  538. {
  539. PADMIN_DLL_CALLBACKS AdminDllCallbacks = &gblDDMConfigInfo.AdminDllCallbacks[i];
  540. if (AdminDllCallbacks[i].lpfnMprAdminGetIpAddressForUser!=NULL)
  541. {
  542. dwRetCode = RasSrvrInitialize(
  543. AdminDllCallbacks[i].lpfnMprAdminGetIpAddressForUser,
  544. AdminDllCallbacks[i].lpfnMprAdminReleaseIpAddress );
  545. bCalled = TRUE;
  546. break;
  547. }
  548. }
  549. if (!bCalled)
  550. {
  551. dwRetCode = RasSrvrInitialize(NULL, NULL);
  552. }
  553. if ( dwRetCode != NO_ERROR )
  554. {
  555. DDMLogErrorString( ROUTERLOG_CANT_INITIALIZE_IP_SERVER,
  556. 0, NULL, dwRetCode, 0 );
  557. break;
  558. }
  559. gblDDMConfigInfo.fRasSrvrInitialized = TRUE;
  560. }
  561. //
  562. // Start the timer
  563. //
  564. {
  565. LARGE_INTEGER DueTime;
  566. DueTime.QuadPart = Int32x32To64((LONG)1000, -10000);
  567. if ( !SetWaitableTimer( gblSupervisorEvents[DDM_EVENT_TIMER],
  568. &DueTime, 1000, NULL, NULL, FALSE) )
  569. {
  570. dwRetCode = GetLastError();
  571. break;
  572. }
  573. }
  574. //
  575. // Initialize PPP engine DLL
  576. //
  577. dwRetCode = PppDdmInit(
  578. SendPppMessageToDDM,
  579. gblDDMConfigInfo.dwServerFlags,
  580. gblDDMConfigInfo.dwLoggingLevel,
  581. dwLocalIpAddress,
  582. gblDDMConfigInfo.fFlags&DDM_USING_RADIUS_AUTHENTICATION,
  583. lpfnRasAuthProviderAuthenticateUser,
  584. lpfnRasAuthProviderFreeAttributes,
  585. lpfnRasAcctProviderStartAccounting,
  586. lpfnRasAcctProviderInterimAccounting,
  587. lpfnRasAcctProviderStopAccounting,
  588. lpfnRasAcctProviderFreeAttributes,
  589. (LPVOID)GetNextAccountingSessionId );
  590. if ( dwRetCode != NO_ERROR )
  591. {
  592. DDMLogErrorString(ROUTERLOG_PPP_INIT_FAILED, 0, NULL, dwRetCode, 0);
  593. break;
  594. }
  595. //
  596. // Create the Event dispatcher thread
  597. //
  598. if ( ( hEventDispatcher = CreateThread( NULL, 0, EventDispatcher,
  599. NULL, 0, &ThreadId)) == 0 )
  600. {
  601. //
  602. // cannot create event dispatcher thread
  603. //
  604. dwRetCode = GetLastError();
  605. break;
  606. }
  607. //
  608. // Register for plug and play notifications with RASMAN
  609. //
  610. dwRetCode = RasRegisterPnPHandler( (PAPCFUNC) DdmDevicePnpHandler,
  611. hEventDispatcher,
  612. TRUE);
  613. if ( dwRetCode != NO_ERROR )
  614. {
  615. break;
  616. }
  617. //
  618. // Initialize notification event list
  619. //
  620. InitializeListHead( &(gblDDMConfigInfo.NotificationEventListHead) );
  621. //
  622. // Initialize the array of Analog/Digital Ip Addresses.
  623. //
  624. dwRetCode = AddressPoolInit();
  625. if( dwRetCode != NO_ERROR )
  626. {
  627. break;
  628. }
  629. gblDDMConfigInfo.dwIndex = 0;
  630. /*
  631. TimerQInsert( NULL,
  632. gblDDMConfigInfo.dwAnnouncePresenceTimer,
  633. AnnouncePresenceHandler );
  634. */
  635. //
  636. // Send notification to the connections folder that ddm
  637. // has started.
  638. //
  639. {
  640. RASEVENT RasEvent;
  641. ZeroMemory((PBYTE) &RasEvent, sizeof(RASEVENT));
  642. RasEvent.Type = SERVICE_EVENT;
  643. RasEvent.Event = RAS_SERVICE_STARTED;
  644. RasEvent.Service = REMOTEACCESS;
  645. (void) RasSendNotification(&RasEvent);
  646. }
  647. return( NO_ERROR );
  648. } while ( FALSE );
  649. //
  650. // We call DDMCleanUp before setting the gblphEventDDMTerminated because
  651. // otherwise the DIM dll will be unloaded while DDMCleanUp is being
  652. // executed
  653. //
  654. DDMCleanUp();
  655. //
  656. // Will terminate the event dispatcher thread if it started
  657. // and will notify DIM that the service is terminated.
  658. //
  659. if(NULL != gblphEventDDMTerminated)
  660. {
  661. SetEvent( *gblphEventDDMTerminated );
  662. }
  663. gblphEventDDMTerminated = NULL;
  664. return( dwRetCode );
  665. }
  666. //***
  667. //
  668. // Function: SvcEventHandler
  669. //
  670. // Descrption: Invoked following the event signaled by the handler registered
  671. // with the service controller. Replaces old service state with
  672. // the new state and calls the appropriate handler.
  673. //
  674. //***
  675. VOID
  676. SvcEventHandler(
  677. VOID
  678. )
  679. {
  680. EnterCriticalSection( &(gblDeviceTable.CriticalSection) );
  681. switch ( gblDDMConfigInfo.pServiceStatus->dwCurrentState )
  682. {
  683. case SERVICE_RUNNING:
  684. DDMServiceResume();
  685. break;
  686. case SERVICE_PAUSED:
  687. DDMServicePause();
  688. break;
  689. case SERVICE_STOP_PENDING:
  690. DDMServiceTerminate();
  691. break;
  692. default:
  693. RTASSERT(FALSE);
  694. }
  695. LeaveCriticalSection( &(gblDeviceTable.CriticalSection) );
  696. }