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.

546 lines
12 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1999-2000 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // NotificationMgr.cpp
  7. //
  8. // Description:
  9. // Notification Manager implementation.
  10. //
  11. // Documentation:
  12. // Yes.
  13. //
  14. // Maintained By:
  15. // Geoffrey Pease (GPease) 22-NOV-1999
  16. //
  17. //////////////////////////////////////////////////////////////////////////////
  18. #include "Pch.h"
  19. #include "ConnPointEnum.h"
  20. #include "NotificationManager.h"
  21. #include "CPINotifyUI.h"
  22. #include "CPIClusCfgCallback.h"
  23. DEFINE_THISCLASS("CNotificationManager")
  24. // ************************************************************************
  25. //
  26. // Constructor / Destructor
  27. //
  28. // ************************************************************************
  29. //////////////////////////////////////////////////////////////////////////////
  30. //
  31. // HRESULT
  32. // CNotificationManager::S_HrCreateInstance(
  33. // IUnknown ** ppunkOut
  34. // )
  35. //
  36. //////////////////////////////////////////////////////////////////////////////
  37. HRESULT
  38. CNotificationManager::S_HrCreateInstance(
  39. IUnknown ** ppunkOut
  40. )
  41. {
  42. TraceFunc( "" );
  43. HRESULT hr = S_OK;
  44. IServiceProvider * psp = NULL;
  45. CNotificationManager * pnm = NULL;
  46. Assert( ppunkOut != NULL );
  47. if ( ppunkOut == NULL )
  48. {
  49. hr = THR( E_POINTER );
  50. goto Cleanup;
  51. }
  52. // Don't wrap - this can fail with E_POINTER.
  53. hr = CServiceManager::S_HrGetManagerPointer( &psp );
  54. if ( hr == E_POINTER )
  55. {
  56. //
  57. // This happens when the Service Manager is first started.
  58. //
  59. pnm = new CNotificationManager();
  60. if ( pnm == NULL )
  61. {
  62. hr = THR( E_OUTOFMEMORY );
  63. goto Cleanup;
  64. }
  65. hr = THR( pnm->HrInit() );
  66. if ( FAILED( hr ) )
  67. {
  68. goto Cleanup;
  69. }
  70. hr = THR( pnm->TypeSafeQI( IUnknown, ppunkOut ) );
  71. if ( FAILED( hr ) )
  72. {
  73. goto Cleanup;
  74. }
  75. } // if: service manager doesn't exist
  76. else if ( FAILED( hr ) )
  77. {
  78. THR( hr );
  79. goto Cleanup;
  80. }
  81. else
  82. {
  83. hr = THR( psp->TypeSafeQS( CLSID_NotificationManager, IUnknown, ppunkOut ) );
  84. psp->Release();
  85. } // else: service manager exists
  86. Cleanup:
  87. if ( pnm != NULL )
  88. {
  89. pnm->Release();
  90. }
  91. HRETURN( hr );
  92. } //*** CNotificationManager::S_HrCreateInstance
  93. //////////////////////////////////////////////////////////////////////////////
  94. //++
  95. //
  96. // CNotificationManager::CNotificationManager
  97. //
  98. // Description:
  99. // Default constructor.
  100. //
  101. // Arguments:
  102. // None.
  103. //
  104. // Return Values:
  105. // None.
  106. //
  107. //--
  108. //////////////////////////////////////////////////////////////////////////////
  109. CNotificationManager::CNotificationManager( void )
  110. : m_cRef( 1 )
  111. {
  112. TraceFunc( "" );
  113. InterlockedIncrement( &g_cObjects );
  114. TraceFuncExit();
  115. } //*** CNotificationManager::CNotificationManager
  116. //////////////////////////////////////////////////////////////////////////////
  117. //
  118. // STDMETHODIMP
  119. // CNotificationManager::HrInit
  120. //
  121. //////////////////////////////////////////////////////////////////////////////
  122. STDMETHODIMP
  123. CNotificationManager::HrInit( void )
  124. {
  125. TraceFunc( "" );
  126. HRESULT hr = S_OK;
  127. IUnknown * punk = NULL;
  128. // IUnknown stuff
  129. Assert( m_cRef == 1 );
  130. // IConnectionPointContainer
  131. Assert( m_penumcp == NULL );
  132. m_penumcp = new CConnPointEnum();
  133. if ( m_penumcp == NULL )
  134. {
  135. hr = THR( E_OUTOFMEMORY );
  136. goto Cleanup;
  137. }
  138. hr = THR( m_penumcp->HrInit() );
  139. if ( FAILED( hr ) )
  140. {
  141. goto Cleanup;
  142. }
  143. hr = THR( CCPINotifyUI::S_HrCreateInstance( &punk ) );
  144. if ( FAILED( hr ) )
  145. {
  146. goto Cleanup;
  147. }
  148. hr = THR( m_penumcp->HrAddConnection( IID_INotifyUI, punk ) );
  149. if ( FAILED( hr ) )
  150. {
  151. goto Cleanup;
  152. }
  153. punk->Release();
  154. punk = NULL;
  155. hr = THR( CCPIClusCfgCallback::S_HrCreateInstance( &punk ) );
  156. if ( FAILED( hr ) )
  157. {
  158. goto Cleanup;
  159. }
  160. hr = THR( m_penumcp->HrAddConnection( IID_IClusCfgCallback, punk ) );
  161. if ( FAILED( hr ) )
  162. {
  163. goto Cleanup;
  164. }
  165. hr = THR( m_csInstanceGuard.HrInitialized() );
  166. if ( FAILED( hr ) )
  167. {
  168. goto Cleanup;
  169. }
  170. Cleanup:
  171. if ( punk != NULL )
  172. {
  173. punk->Release();
  174. }
  175. HRETURN( hr );
  176. } //*** CNotificationManager::HrInit
  177. //////////////////////////////////////////////////////////////////////////////
  178. //
  179. // CNotificationManager::~CNotificationManager
  180. //
  181. //////////////////////////////////////////////////////////////////////////////
  182. CNotificationManager::~CNotificationManager( void )
  183. {
  184. TraceFunc( "" );
  185. if ( m_penumcp != NULL )
  186. {
  187. m_penumcp->Release();
  188. }
  189. InterlockedDecrement( &g_cObjects );
  190. TraceFuncExit();
  191. } //*** CNotificationManager::~CNotificationManager
  192. // ************************************************************************
  193. //
  194. // IUnknown
  195. //
  196. // ************************************************************************
  197. //////////////////////////////////////////////////////////////////////////////
  198. //++
  199. //
  200. // CNotificationManager::QueryInterface
  201. //
  202. // Description:
  203. // Query this object for the passed in interface.
  204. //
  205. // Arguments:
  206. // riidIn
  207. // Id of interface requested.
  208. //
  209. // ppvOut
  210. // Pointer to the requested interface.
  211. //
  212. // Return Value:
  213. // S_OK
  214. // If the interface is available on this object.
  215. //
  216. // E_NOINTERFACE
  217. // If the interface is not available.
  218. //
  219. // E_POINTER
  220. // ppvOut was NULL.
  221. //
  222. // Remarks:
  223. // None.
  224. //
  225. //--
  226. //////////////////////////////////////////////////////////////////////////////
  227. STDMETHODIMP
  228. CNotificationManager::QueryInterface(
  229. REFIID riidIn
  230. , LPVOID * ppvOut
  231. )
  232. {
  233. TraceQIFunc( riidIn, ppvOut );
  234. HRESULT hr = S_OK;
  235. //
  236. // Validate arguments.
  237. //
  238. Assert( ppvOut != NULL );
  239. if ( ppvOut == NULL )
  240. {
  241. hr = THR( E_POINTER );
  242. goto Cleanup;
  243. }
  244. //
  245. // Handle known interfaces.
  246. //
  247. if ( IsEqualIID( riidIn, IID_IUnknown ) )
  248. {
  249. *ppvOut = static_cast< INotificationManager * >( this );
  250. } // if: IUnknown
  251. else if ( IsEqualIID( riidIn, IID_INotificationManager ) )
  252. {
  253. *ppvOut = TraceInterface( __THISCLASS__, INotificationManager, this, 0 );
  254. } // else if: INotificationManager
  255. else if ( IsEqualIID( riidIn, IID_IConnectionPointContainer ) )
  256. {
  257. *ppvOut = TraceInterface( __THISCLASS__, IConnectionPointContainer, this, 0 );
  258. } // else if: IConnectionPointContainer
  259. else
  260. {
  261. *ppvOut = NULL;
  262. hr = E_NOINTERFACE;
  263. }
  264. //
  265. // Add a reference to the interface if successful.
  266. //
  267. if ( SUCCEEDED( hr ) )
  268. {
  269. ((IUnknown *) *ppvOut)->AddRef();
  270. } // if: success
  271. Cleanup:
  272. QIRETURN_IGNORESTDMARSHALLING( hr, riidIn );
  273. } //*** CNotificationManager::QueryInterface
  274. //////////////////////////////////////////////////////////////////////////////
  275. //
  276. // STDMETHODIMP_(ULONG)
  277. // CNotificationManager::AddRef
  278. //
  279. //////////////////////////////////////////////////////////////////////////////
  280. STDMETHODIMP_(ULONG)
  281. CNotificationManager::AddRef( void )
  282. {
  283. TraceFunc( "[IUnknown]" );
  284. InterlockedIncrement( &m_cRef );
  285. CRETURN( m_cRef );
  286. } //*** CNotificationManager::AddRef
  287. //////////////////////////////////////////////////////////////////////////////
  288. //
  289. // STDMETHODIMP_(ULONG)
  290. // CNotificationManager::Release
  291. //
  292. //////////////////////////////////////////////////////////////////////////////
  293. STDMETHODIMP_(ULONG)
  294. CNotificationManager::Release( void )
  295. {
  296. TraceFunc( "[IUnknown]" );
  297. LONG cRef;
  298. cRef = InterlockedDecrement( &m_cRef );
  299. if ( cRef == 0 )
  300. {
  301. TraceDo( delete this );
  302. }
  303. CRETURN( cRef );
  304. } //*** CNotificationManager::Release
  305. // ************************************************************************
  306. //
  307. // INotificationManager
  308. //
  309. // ************************************************************************
  310. //////////////////////////////////////////////////////////////////////////////
  311. //
  312. // STDMETHODIMP
  313. // CNotificationManager::AddConnectionPoint(
  314. // REFIID riidIn,
  315. // IConnectionPoint * pcpIn
  316. // )
  317. //
  318. //////////////////////////////////////////////////////////////////////////////
  319. STDMETHODIMP
  320. CNotificationManager::AddConnectionPoint(
  321. REFIID riidIn,
  322. IConnectionPoint * pcpIn
  323. )
  324. {
  325. TraceFunc( "[INotificationManager]" );
  326. HRESULT hr;
  327. m_csInstanceGuard.Enter();
  328. hr = THR( m_penumcp->HrAddConnection( riidIn, pcpIn ) );
  329. m_csInstanceGuard.Leave();
  330. HRETURN( hr );
  331. } //*** CNotificationManager::AddConnectionPoint
  332. // ************************************************************************
  333. //
  334. // IConnectionPointContainer
  335. //
  336. // ************************************************************************
  337. //////////////////////////////////////////////////////////////////////////////
  338. //
  339. // STDMETHODIMP
  340. // CNotificationManager::EnumConnectionPoints(
  341. // IEnumConnectionPoints **ppEnumOut
  342. // )
  343. //
  344. // Return values:
  345. // On success the result of m_penumcp->Clone()
  346. // E_POINTER - null m_penumcp pointer
  347. // E_INVALIDARG - ppEnumOut is NULL
  348. //
  349. //
  350. //////////////////////////////////////////////////////////////////////////////
  351. STDMETHODIMP
  352. CNotificationManager::EnumConnectionPoints(
  353. IEnumConnectionPoints **ppEnumOut
  354. )
  355. {
  356. TraceFunc( "[IConnectionPointContainer]" );
  357. HRESULT hr = S_OK;
  358. m_csInstanceGuard.Enter();
  359. if ( ( ppEnumOut == NULL ) || ( m_penumcp == NULL ) )
  360. {
  361. hr = THR( E_POINTER );
  362. goto Cleanup;
  363. }
  364. hr = THR( m_penumcp->Clone( ppEnumOut ) );
  365. Cleanup:
  366. m_csInstanceGuard.Leave();
  367. HRETURN( hr );
  368. } //*** CNotificationManager::EnumConnectionPoints
  369. //////////////////////////////////////////////////////////////////////////////
  370. //
  371. // STDMETHODIMP
  372. // CNotificationManager::FindConnectionPoint(
  373. // REFIID riidIn,
  374. // IConnectionPoint **ppCPOut
  375. // )
  376. //
  377. //////////////////////////////////////////////////////////////////////////////
  378. STDMETHODIMP
  379. CNotificationManager::FindConnectionPoint(
  380. REFIID riidIn,
  381. IConnectionPoint ** ppCPOut
  382. )
  383. {
  384. TraceFunc( "[IConnectionPointContainer]" );
  385. IID iid;
  386. HRESULT hr = S_FALSE;
  387. IConnectionPoint * pcp = NULL;
  388. m_csInstanceGuard.Enter();
  389. if ( ppCPOut == NULL )
  390. {
  391. hr = THR( E_POINTER );
  392. goto Cleanup;
  393. }
  394. hr = THR( m_penumcp->Reset() );
  395. if ( FAILED( hr ) )
  396. {
  397. goto Cleanup;
  398. }
  399. for ( ; ; ) // ever
  400. {
  401. if ( pcp != NULL )
  402. {
  403. pcp->Release();
  404. pcp = NULL;
  405. }
  406. hr = STHR( m_penumcp->Next( 1, &pcp, NULL ) );
  407. if ( FAILED( hr ) )
  408. {
  409. goto Cleanup;
  410. }
  411. if ( hr == S_FALSE )
  412. {
  413. hr = THR( CONNECT_E_NOCONNECTION );
  414. break; // exit condition
  415. }
  416. hr = THR( pcp->GetConnectionInterface( &iid ) );
  417. if ( FAILED( hr ) )
  418. {
  419. continue; // ignore it
  420. }
  421. if ( iid != riidIn )
  422. {
  423. continue; // not the right interface
  424. }
  425. //
  426. // Found it. Give up ownership and exit loop.
  427. //
  428. *ppCPOut = pcp;
  429. pcp = NULL;
  430. hr = S_OK;
  431. break;
  432. } // forever
  433. Cleanup:
  434. if ( pcp != NULL )
  435. {
  436. pcp->Release();
  437. }
  438. m_csInstanceGuard.Leave();
  439. HRETURN( hr );
  440. } //*** CNotificationManager::FindConnectionPoint