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.

692 lines
17 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1999-2002 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // ServiceMgr.cpp
  7. //
  8. // Description:
  9. // Service Manager implementation.
  10. //
  11. // Documentation:
  12. // Yes.
  13. //
  14. // Maintained By:
  15. // Galen Barbee (GalenB) 22-NOV-1999
  16. //
  17. //////////////////////////////////////////////////////////////////////////////
  18. #include "Pch.h"
  19. // #include "ServiceMgr.h" - already included in DLL.H
  20. DEFINE_THISCLASS("CServiceManager")
  21. #define CServiceManager CServiceManager
  22. #define LPTHISCLASS CServiceManager *
  23. //****************************************************************************
  24. //
  25. // Protected Global
  26. //
  27. //****************************************************************************
  28. IServiceProvider * g_pspServiceManager = NULL;
  29. //****************************************************************************
  30. //
  31. // Class Static Variables
  32. //
  33. //****************************************************************************
  34. CRITICAL_SECTION CServiceManager::sm_cs;
  35. //****************************************************************************
  36. //
  37. // Constructor / Destructor
  38. //
  39. //****************************************************************************
  40. //////////////////////////////////////////////////////////////////////////////
  41. //
  42. // HRESULT
  43. // CServiceManager::S_HrCreateInstance(
  44. // IUnknown ** ppunkOut
  45. // )
  46. //
  47. //////////////////////////////////////////////////////////////////////////////
  48. HRESULT
  49. CServiceManager::S_HrCreateInstance(
  50. IUnknown ** ppunkOut
  51. )
  52. {
  53. TraceFunc( "" );
  54. HRESULT hr = S_OK;
  55. LPTHISCLASS pthis = NULL;
  56. EnterCriticalSection( &sm_cs );
  57. Assert( ppunkOut != NULL );
  58. if ( ppunkOut == NULL )
  59. {
  60. hr = THR( E_POINTER );
  61. goto Cleanup;
  62. } // if:
  63. if ( g_pspServiceManager != NULL )
  64. {
  65. hr = THR( g_pspServiceManager->TypeSafeQI( IUnknown, ppunkOut ) );
  66. goto Cleanup;
  67. } // if: assign new service manager
  68. pthis = new CServiceManager();
  69. if ( pthis == NULL )
  70. {
  71. hr = THR( E_OUTOFMEMORY );
  72. goto Cleanup;
  73. } // if:
  74. //
  75. // Can't hold CS in Init.
  76. //
  77. LeaveCriticalSection( &sm_cs );
  78. hr = THR( pthis->HrInit() );
  79. EnterCriticalSection( &sm_cs );
  80. if ( FAILED( hr ) )
  81. {
  82. goto Cleanup;
  83. } // if:
  84. Assert( g_pspServiceManager == NULL );
  85. // No REF - or we'll never die!
  86. g_pspServiceManager = static_cast< IServiceProvider * >( pthis );
  87. TraceMoveToMemoryList( g_pspServiceManager, g_GlobalMemoryList );
  88. hr = THR( g_pspServiceManager->TypeSafeQI( IUnknown, ppunkOut ) );
  89. if ( FAILED( hr ) )
  90. {
  91. goto Cleanup;
  92. }
  93. Cleanup:
  94. if ( pthis != NULL )
  95. {
  96. pthis->Release();
  97. } // if:
  98. LeaveCriticalSection( &sm_cs );
  99. HRETURN( hr );
  100. } //*** CServiceManager::S_HrCreateInstance
  101. //////////////////////////////////////////////////////////////////////////////
  102. //++
  103. //
  104. // HRESULT
  105. // CServiceManager::S_HrGetManagerPointer( IServiceProvider ** ppspOut )
  106. //
  107. //--
  108. //////////////////////////////////////////////////////////////////////////////
  109. HRESULT
  110. CServiceManager::S_HrGetManagerPointer( IServiceProvider ** ppspOut )
  111. {
  112. TraceFunc( "ppspOut" );
  113. HRESULT hr = HRESULT_FROM_WIN32( ERROR_PROCESS_ABORTED );
  114. EnterCriticalSection( &sm_cs );
  115. if ( g_pspServiceManager != NULL )
  116. {
  117. g_pspServiceManager->AddRef();
  118. *ppspOut = g_pspServiceManager;
  119. hr = S_OK;
  120. } // if: valid service manager
  121. else
  122. {
  123. //
  124. // KB 18-JUN-2001 DavidP
  125. // Don't wrap this with THR because it is expected to return
  126. // E_POINTER on the very first call.
  127. //
  128. hr = E_POINTER;
  129. } // else: no pointer
  130. LeaveCriticalSection( &sm_cs );
  131. HRETURN ( hr );
  132. } //*** CServiceManager::S_HrGetManagerPointer
  133. //////////////////////////////////////////////////////////////////////////////
  134. //++
  135. //
  136. // CServiceManager::S_HrProcessInitialize
  137. //
  138. // Description:
  139. // Do process initialization by intializing the critical section.
  140. //
  141. // Return Value:
  142. // S_OK
  143. //
  144. // Remarks:
  145. // This function is called from DllMain() when DLL_PROCESS_ATTACH
  146. // is sent. This function is needed because we need a known point
  147. // to create a critical section that synchronizes the creation and
  148. // deletion of this object. Given this object's life cycle and
  149. // static creator function it is possible to have a race when this
  150. // object is destrying itself with the static creator function.
  151. //
  152. //--
  153. //////////////////////////////////////////////////////////////////////////////
  154. HRESULT
  155. CServiceManager::S_HrProcessInitialize( void )
  156. {
  157. TraceFunc( "" );
  158. HRESULT hr = S_OK;
  159. if ( InitializeCriticalSectionAndSpinCount( &sm_cs, RECOMMENDED_SPIN_COUNT ) == 0 )
  160. {
  161. DWORD scLastError = TW32( GetLastError() );
  162. hr = HRESULT_FROM_WIN32( scLastError );
  163. }
  164. HRETURN( hr );
  165. } //*** CServiceManager::S_HrProcessInitialize
  166. //////////////////////////////////////////////////////////////////////////////
  167. //++
  168. //
  169. // CServiceManager::S_HrProcessUninitialize
  170. //
  171. // Description:
  172. // Do process uninitialization by deleting the critical section.
  173. //
  174. // Return Value:
  175. // S_OK
  176. //
  177. // Remarks:
  178. // Delete the critical section that sychronizes the creation and
  179. // deletion code.
  180. //
  181. //--
  182. //////////////////////////////////////////////////////////////////////////////
  183. HRESULT
  184. CServiceManager::S_HrProcessUninitialize( void )
  185. {
  186. TraceFunc( "" );
  187. HRESULT hr = S_OK;
  188. DeleteCriticalSection( &sm_cs );
  189. HRETURN( hr );
  190. } //*** CServiceManager::S_HrProcessUninitialize
  191. //////////////////////////////////////////////////////////////////////////////
  192. //
  193. // CServiceManager::CServiceManager
  194. //
  195. //////////////////////////////////////////////////////////////////////////////
  196. CServiceManager::CServiceManager( void )
  197. : m_cRef( 1 )
  198. {
  199. TraceFunc( "" );
  200. InterlockedIncrement( &g_cObjects );
  201. TraceFuncExit();
  202. } //*** CServiceManager::CServiceManager
  203. //////////////////////////////////////////////////////////////////////////////
  204. //
  205. // HRESULT
  206. // CServiceManager::HrInit
  207. //
  208. //////////////////////////////////////////////////////////////////////////////
  209. HRESULT
  210. CServiceManager::HrInit( void )
  211. {
  212. TraceFunc( "" );
  213. HRESULT hr;
  214. ITaskManager * ptm = NULL;
  215. IDoTask * pdt = NULL;
  216. IObjectManager * pom = NULL;
  217. INotificationManager * pnm = NULL;
  218. IConnectionManager * pcm = NULL;
  219. ILogManager * plm = NULL;
  220. // IUnknown
  221. Assert( m_cRef == 1 );
  222. // IServiceProvider
  223. Assert( m_dwLogManagerCookie == 0 );
  224. Assert( m_dwConnectionManagerCookie == 0 );
  225. Assert( m_dwNotificationManagerCookie == 0 );
  226. Assert( m_dwObjectManagerCookie == 0 );
  227. Assert( m_dwTaskManagerCookie == 0 );
  228. Assert( m_pgit == NULL );
  229. // IServiceProvider stuff
  230. hr = THR( HrCoCreateInternalInstance( CLSID_ObjectManager, NULL, CLSCTX_INPROC_SERVER, TypeSafeParams( IObjectManager, &pom ) ) );
  231. if ( FAILED( hr ) )
  232. {
  233. goto Cleanup;
  234. }
  235. hr = THR( HrCoCreateInternalInstance( CLSID_TaskManager, NULL, CLSCTX_INPROC_SERVER, TypeSafeParams( ITaskManager, &ptm ) ) );
  236. if ( FAILED( hr ) )
  237. {
  238. goto Cleanup;
  239. }
  240. hr = THR( HrCoCreateInternalInstance( CLSID_NotificationManager, NULL, CLSCTX_INPROC_SERVER, TypeSafeParams( INotificationManager, &pnm ) ) );
  241. if ( FAILED( hr ) )
  242. {
  243. goto Cleanup;
  244. }
  245. hr = THR( HrCoCreateInternalInstance( CLSID_ClusterConnectionManager, NULL, CLSCTX_INPROC_SERVER, TypeSafeParams( IConnectionManager, &pcm ) ) );
  246. if ( FAILED( hr ) )
  247. {
  248. goto Cleanup;
  249. }
  250. hr = THR( HrCoCreateInternalInstance( CLSID_LogManager, NULL, CLSCTX_INPROC_SERVER, TypeSafeParams( ILogManager, &plm ) ) );
  251. if ( FAILED( hr ) )
  252. {
  253. goto Cleanup;
  254. }
  255. //
  256. // Store the interfaces in the GIT.
  257. //
  258. hr = THR( CoCreateInstance(
  259. CLSID_StdGlobalInterfaceTable
  260. , NULL
  261. , CLSCTX_INPROC_SERVER
  262. , IID_IGlobalInterfaceTable
  263. , reinterpret_cast< void ** >( &m_pgit )
  264. ) );
  265. if ( FAILED( hr ) )
  266. {
  267. goto Cleanup;
  268. }
  269. hr = THR( m_pgit->RegisterInterfaceInGlobal( pom, IID_IObjectManager, &m_dwObjectManagerCookie ) );
  270. if ( FAILED( hr ) )
  271. {
  272. goto Cleanup;
  273. }
  274. hr = THR( m_pgit->RegisterInterfaceInGlobal( ptm, IID_ITaskManager, &m_dwTaskManagerCookie ) );
  275. if ( FAILED( hr ) )
  276. {
  277. goto Cleanup;
  278. }
  279. hr = THR( m_pgit->RegisterInterfaceInGlobal( pnm, IID_INotificationManager, &m_dwNotificationManagerCookie ) );
  280. if ( FAILED( hr ) )
  281. {
  282. goto Cleanup;
  283. }
  284. hr = THR( m_pgit->RegisterInterfaceInGlobal( pcm, IID_IConnectionManager, &m_dwConnectionManagerCookie ) );
  285. if ( FAILED( hr ) )
  286. {
  287. goto Cleanup;
  288. }
  289. hr = THR( m_pgit->RegisterInterfaceInGlobal( plm, IID_ILogManager, &m_dwLogManagerCookie ) );
  290. if ( FAILED( hr ) )
  291. {
  292. goto Cleanup;
  293. }
  294. Cleanup:
  295. if ( pom != NULL )
  296. {
  297. pom->Release();
  298. } // if:
  299. if ( pnm != NULL )
  300. {
  301. pnm->Release();
  302. } // if:
  303. if ( pcm != NULL )
  304. {
  305. pcm->Release();
  306. } // if:
  307. if ( plm != NULL )
  308. {
  309. plm->Release();
  310. } // if:
  311. if ( ptm != NULL )
  312. {
  313. ptm->Release();
  314. } // if:
  315. if ( pdt != NULL )
  316. {
  317. pdt->Release();
  318. } // if:
  319. HRETURN( hr );
  320. } //*** CServiceManager::HrInit
  321. //////////////////////////////////////////////////////////////////////////////
  322. //
  323. // CServiceManager::~CServiceManager
  324. //
  325. //////////////////////////////////////////////////////////////////////////////
  326. CServiceManager::~CServiceManager( void )
  327. {
  328. TraceFunc( "" );
  329. EnterCriticalSection( &sm_cs );
  330. if ( g_pspServiceManager == static_cast< IServiceProvider * >( this ) )
  331. {
  332. TraceMoveFromMemoryList( g_pspServiceManager, g_GlobalMemoryList );
  333. g_pspServiceManager = NULL;
  334. } // if: its our pointer
  335. if ( m_pgit != NULL )
  336. {
  337. if ( m_dwLogManagerCookie != 0 )
  338. {
  339. THR( m_pgit->RevokeInterfaceFromGlobal( m_dwLogManagerCookie ) );
  340. } // if:
  341. if ( m_dwConnectionManagerCookie != 0 )
  342. {
  343. THR( m_pgit->RevokeInterfaceFromGlobal( m_dwConnectionManagerCookie ) );
  344. } // if:
  345. if ( m_dwNotificationManagerCookie != 0 )
  346. {
  347. THR( m_pgit->RevokeInterfaceFromGlobal( m_dwNotificationManagerCookie ) );
  348. } // if:
  349. if ( m_dwObjectManagerCookie != 0 )
  350. {
  351. THR( m_pgit->RevokeInterfaceFromGlobal( m_dwObjectManagerCookie ) );
  352. } // if:
  353. if ( m_dwTaskManagerCookie != 0 )
  354. {
  355. THR( m_pgit->RevokeInterfaceFromGlobal( m_dwTaskManagerCookie ) );
  356. } // if:
  357. m_pgit->Release();
  358. } // if:
  359. InterlockedDecrement( &g_cObjects );
  360. LeaveCriticalSection( &sm_cs );
  361. TraceFuncExit();
  362. } //*** CServiceManager::~CServiceManager
  363. //****************************************************************************
  364. //
  365. // IUnknown
  366. //
  367. //****************************************************************************
  368. //////////////////////////////////////////////////////////////////////////////
  369. //++
  370. //
  371. // CServiceManager::QueryInterface
  372. //
  373. // Description:
  374. // Query this object for the passed in interface.
  375. //
  376. // Arguments:
  377. // riidIn
  378. // Id of interface requested.
  379. //
  380. // ppvOut
  381. // Pointer to the requested interface.
  382. //
  383. // Return Value:
  384. // S_OK
  385. // If the interface is available on this object.
  386. //
  387. // E_NOINTERFACE
  388. // If the interface is not available.
  389. //
  390. // E_POINTER
  391. // ppvOut was NULL.
  392. //
  393. // Remarks:
  394. // None.
  395. //
  396. //--
  397. //////////////////////////////////////////////////////////////////////////////
  398. STDMETHODIMP
  399. CServiceManager::QueryInterface(
  400. REFIID riidIn
  401. , LPVOID * ppvOut
  402. )
  403. {
  404. TraceQIFunc( riidIn, ppvOut );
  405. HRESULT hr = S_OK;
  406. //
  407. // Validate arguments.
  408. //
  409. Assert( ppvOut != NULL );
  410. if ( ppvOut == NULL )
  411. {
  412. hr = THR( E_POINTER );
  413. goto Cleanup;
  414. }
  415. //
  416. // Handle known interfaces.
  417. //
  418. if ( IsEqualIID( riidIn, IID_IUnknown ) )
  419. {
  420. *ppvOut = static_cast< LPUNKNOWN >( this );
  421. } // if: IUnknown
  422. else if ( IsEqualIID( riidIn, IID_IServiceProvider ) )
  423. {
  424. *ppvOut = TraceInterface( __THISCLASS__, IServiceProvider, this, 0 );
  425. } // else if: IQueryService
  426. else
  427. {
  428. *ppvOut = NULL;
  429. hr = E_NOINTERFACE;
  430. }
  431. //
  432. // Add a reference to the interface if successful.
  433. //
  434. if ( SUCCEEDED( hr ) )
  435. {
  436. ((IUnknown *) *ppvOut)->AddRef();
  437. } // if: success
  438. Cleanup:
  439. QIRETURN_IGNORESTDMARSHALLING( hr, riidIn );
  440. } //*** CServiceManager::QueryInterface
  441. //////////////////////////////////////////////////////////////////////////////
  442. //
  443. // STDMETHODIMP_( ULONG )
  444. // CServiceManager::AddRef
  445. //
  446. //////////////////////////////////////////////////////////////////////////////
  447. STDMETHODIMP_( ULONG )
  448. CServiceManager::AddRef( void )
  449. {
  450. TraceFunc( "[IUnknown]" );
  451. InterlockedIncrement( &m_cRef );
  452. CRETURN( m_cRef );
  453. } //*** CServiceManager::AddRef
  454. //////////////////////////////////////////////////////////////////////////////
  455. //++
  456. //
  457. // STDMETHODIMP_( ULONG )
  458. // CServiceManager::Release
  459. //
  460. //--
  461. //////////////////////////////////////////////////////////////////////////////
  462. STDMETHODIMP_( ULONG )
  463. CServiceManager::Release( void )
  464. {
  465. TraceFunc( "[IUnknown]" );
  466. LONG cRef;
  467. cRef = InterlockedDecrement( &m_cRef );
  468. if ( cRef == 0 )
  469. {
  470. TraceDo( delete this );
  471. }
  472. CRETURN( cRef );
  473. } //*** CServiceManager::Release
  474. //****************************************************************************
  475. //
  476. // IServiceProvider
  477. //
  478. //****************************************************************************
  479. //////////////////////////////////////////////////////////////////////////////
  480. //++
  481. //
  482. // STDMETHODIMP
  483. // CServiceManager::QueryService(
  484. // REFCLSID rclsidIn
  485. // , REFIID riidInIn
  486. // , void ** ppvOutOut
  487. // )
  488. //
  489. //--
  490. //////////////////////////////////////////////////////////////////////////////
  491. STDMETHODIMP
  492. CServiceManager::QueryService(
  493. REFCLSID rclsidIn
  494. , REFIID riidIn
  495. , void ** ppvOut
  496. )
  497. {
  498. TraceFunc( "[IServiceProvider]" );
  499. HRESULT hr = CLASS_E_CLASSNOTAVAILABLE;
  500. if ( m_pgit != NULL )
  501. {
  502. if ( IsEqualIID( rclsidIn, CLSID_ObjectManager ) )
  503. {
  504. IObjectManager * pom;
  505. hr = THR( m_pgit->GetInterfaceFromGlobal( m_dwObjectManagerCookie, TypeSafeParams( IObjectManager, &pom ) ) );
  506. if ( FAILED( hr ) )
  507. goto Cleanup;
  508. hr = THR( pom->QueryInterface( riidIn, ppvOut ) );
  509. pom->Release();
  510. // fall thru
  511. }
  512. else if ( IsEqualIID( rclsidIn, CLSID_TaskManager ) )
  513. {
  514. ITaskManager * ptm;
  515. hr = THR( m_pgit->GetInterfaceFromGlobal( m_dwTaskManagerCookie, TypeSafeParams( ITaskManager, &ptm ) ) );
  516. if ( FAILED( hr ) )
  517. goto Cleanup;
  518. hr = THR( ptm->QueryInterface( riidIn, ppvOut ) );
  519. ptm->Release();
  520. // fall thru
  521. }
  522. else if ( IsEqualIID( rclsidIn, CLSID_NotificationManager ) )
  523. {
  524. INotificationManager * pnm;
  525. hr = THR( m_pgit->GetInterfaceFromGlobal( m_dwNotificationManagerCookie, TypeSafeParams( INotificationManager, &pnm ) ) );
  526. if ( FAILED( hr ) )
  527. goto Cleanup;
  528. hr = THR( pnm->QueryInterface( riidIn, ppvOut ) );
  529. pnm->Release();
  530. // fall thru
  531. }
  532. else if ( IsEqualIID( rclsidIn, CLSID_ClusterConnectionManager ) )
  533. {
  534. IConnectionManager * pcm;
  535. hr = THR( m_pgit->GetInterfaceFromGlobal( m_dwConnectionManagerCookie, TypeSafeParams( IConnectionManager, &pcm ) ) );
  536. if ( FAILED( hr ) )
  537. goto Cleanup;
  538. hr = THR( pcm->QueryInterface( riidIn, ppvOut ) );
  539. pcm->Release();
  540. // fall thru
  541. }
  542. else if ( IsEqualIID( rclsidIn, CLSID_LogManager ) )
  543. {
  544. ILogManager * plm;
  545. hr = THR( m_pgit->GetInterfaceFromGlobal( m_dwLogManagerCookie, TypeSafeParams( ILogManager, &plm ) ) );
  546. if ( FAILED( hr ) )
  547. goto Cleanup;
  548. hr = THR( plm->QueryInterface( riidIn, ppvOut ) );
  549. plm->Release();
  550. // fall thru
  551. }
  552. } // if: GIT pointer not NULL
  553. Cleanup:
  554. HRETURN( hr );
  555. } //*** CServiceManager::QueryService
  556. //****************************************************************************
  557. //
  558. // Private Methods
  559. //
  560. //****************************************************************************