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.

639 lines
14 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1999-2001 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // ConnPointEnum.cpp
  7. //
  8. // Description:
  9. // Connection Point Enumerator implementation.
  10. //
  11. // Maintained By:
  12. // David Potter (DavidP) 14-JUN-2001
  13. // Geoffrey Pease (GPease) 04-AUG-2000
  14. //
  15. //////////////////////////////////////////////////////////////////////////////
  16. #include "Pch.h"
  17. #include "ConnPointEnum.h"
  18. DEFINE_THISCLASS("CConnPointEnum")
  19. // ************************************************************************
  20. //
  21. // Constructor / Destructor
  22. //
  23. // ************************************************************************
  24. //////////////////////////////////////////////////////////////////////////////
  25. //++
  26. //
  27. // HRESULT
  28. // CConnPointEnum::S_HrCreateInstance(
  29. // IUnknown ** ppunkOut
  30. // )
  31. //
  32. //--
  33. //////////////////////////////////////////////////////////////////////////////
  34. HRESULT
  35. CConnPointEnum::S_HrCreateInstance(
  36. IUnknown ** ppunkOut
  37. )
  38. {
  39. TraceFunc( "" );
  40. HRESULT hr = S_OK;
  41. CConnPointEnum * pcc = NULL;
  42. Assert( ppunkOut != NULL );
  43. if ( ppunkOut == NULL )
  44. {
  45. hr = THR( E_POINTER );
  46. goto Cleanup;
  47. }
  48. pcc = new CConnPointEnum();
  49. if ( pcc == NULL )
  50. {
  51. hr = THR( E_OUTOFMEMORY );
  52. goto Cleanup;
  53. }
  54. hr = THR( pcc->HrInit() );
  55. if ( FAILED( hr ) )
  56. {
  57. goto Cleanup;
  58. }
  59. hr = THR( pcc->TypeSafeQI( IUnknown, ppunkOut ) );
  60. if ( FAILED( hr ) )
  61. {
  62. goto Cleanup;
  63. }
  64. Cleanup:
  65. if ( pcc != NULL )
  66. {
  67. pcc->Release();
  68. }
  69. HRETURN( hr );
  70. } //*** CConnPointEnum::S_HrCreateInstance
  71. //////////////////////////////////////////////////////////////////////////////
  72. //++
  73. //
  74. // STDMETHODIMP
  75. // CConnPointEnum::CConnPointEnum
  76. //
  77. //--
  78. //////////////////////////////////////////////////////////////////////////////
  79. CConnPointEnum::CConnPointEnum( void )
  80. : m_cRef( 1 )
  81. {
  82. TraceFunc( "" );
  83. InterlockedIncrement( &g_cObjects );
  84. TraceFuncExit();
  85. } //*** CConnPointEnum::CConnPointEnum
  86. //////////////////////////////////////////////////////////////////////////////
  87. //++
  88. //
  89. // STDMETHODIMP
  90. // CConnPointEnum::HrInit
  91. //
  92. //--
  93. //////////////////////////////////////////////////////////////////////////////
  94. STDMETHODIMP
  95. CConnPointEnum::HrInit( void )
  96. {
  97. TraceFunc( "" );
  98. // IUnknown stuff
  99. Assert( m_cRef == 1 );
  100. // IConnectionPoint
  101. Assert( m_pCPList == NULL );
  102. HRETURN( S_OK );
  103. } //*** CConnPointEnum::HrInit
  104. //////////////////////////////////////////////////////////////////////////////
  105. //++
  106. //
  107. // CConnPointEnum::~CConnPointEnum
  108. //
  109. //--
  110. //////////////////////////////////////////////////////////////////////////////
  111. CConnPointEnum::~CConnPointEnum( void )
  112. {
  113. TraceFunc( "" );
  114. while ( m_pCPList != NULL )
  115. {
  116. SCPEntry * pentry;
  117. pentry = m_pCPList;
  118. m_pCPList = m_pCPList->pNext;
  119. if ( pentry->punk != NULL )
  120. {
  121. pentry->punk->Release();
  122. }
  123. TraceFree( pentry );
  124. }
  125. InterlockedDecrement( &g_cObjects );
  126. TraceFuncExit();
  127. } //*** CConnPointEnum::~CConnPointEnum
  128. // ************************************************************************
  129. //
  130. // IUnknown
  131. //
  132. // ************************************************************************
  133. //////////////////////////////////////////////////////////////////////////////
  134. //++
  135. //
  136. // CConnPointEnum::QueryInterface
  137. //
  138. // Description:
  139. // Query this object for the passed in interface.
  140. //
  141. // Arguments:
  142. // riidIn
  143. // Id of interface requested.
  144. //
  145. // ppvOut
  146. // Pointer to the requested interface.
  147. //
  148. // Return Value:
  149. // S_OK
  150. // If the interface is available on this object.
  151. //
  152. // E_NOINTERFACE
  153. // If the interface is not available.
  154. //
  155. // E_POINTER
  156. // ppvOut was NULL.
  157. //
  158. // Remarks:
  159. // None.
  160. //
  161. //--
  162. //////////////////////////////////////////////////////////////////////////////
  163. STDMETHODIMP
  164. CConnPointEnum::QueryInterface(
  165. REFIID riidIn
  166. , LPVOID * ppvOut
  167. )
  168. {
  169. TraceQIFunc( riidIn, ppvOut );
  170. HRESULT hr = S_OK;
  171. //
  172. // Validate arguments.
  173. //
  174. Assert( ppvOut != NULL );
  175. if ( ppvOut == NULL )
  176. {
  177. hr = THR( E_POINTER );
  178. goto Cleanup;
  179. }
  180. //
  181. // Handle known interfaces.
  182. //
  183. if ( IsEqualIID( riidIn, IID_IUnknown ) )
  184. {
  185. *ppvOut = static_cast< IEnumConnectionPoints * >( this );
  186. } // if: IUnknown
  187. else if ( IsEqualIID( riidIn, IID_IEnumConnectionPoints ) )
  188. {
  189. *ppvOut = TraceInterface( __THISCLASS__, IEnumConnectionPoints, this, 0 );
  190. } // else if: IEnumConnectionPoints
  191. else
  192. {
  193. *ppvOut = NULL;
  194. hr = E_NOINTERFACE;
  195. } // else
  196. //
  197. // Add a reference to the interface if successful.
  198. //
  199. if ( SUCCEEDED( hr ) )
  200. {
  201. ((IUnknown *) *ppvOut)->AddRef();
  202. } // if: success
  203. Cleanup:
  204. QIRETURN_IGNORESTDMARSHALLING( hr, riidIn );
  205. } //*** CConnPointEnum::QueryInterface
  206. //////////////////////////////////////////////////////////////////////////////
  207. //++
  208. //
  209. // STDMETHODIMP_( ULONG )
  210. // CConnPointEnum::AddRef
  211. //
  212. //--
  213. //////////////////////////////////////////////////////////////////////////////
  214. STDMETHODIMP_( ULONG )
  215. CConnPointEnum::AddRef( void )
  216. {
  217. TraceFunc( "[IUnknown]" );
  218. InterlockedIncrement( &m_cRef );
  219. CRETURN( m_cRef );
  220. } //*** CConnPointEnum::AddRef
  221. //////////////////////////////////////////////////////////////////////////////
  222. //++
  223. //
  224. // STDMETHODIMP_( ULONG )
  225. // CConnPointEnum::Release
  226. //
  227. //--
  228. //////////////////////////////////////////////////////////////////////////////
  229. STDMETHODIMP_( ULONG )
  230. CConnPointEnum::Release( void )
  231. {
  232. TraceFunc( "[IUnknown]" );
  233. LONG cRef;
  234. cRef = InterlockedDecrement( &m_cRef );
  235. if ( cRef == 0 )
  236. {
  237. TraceDo( delete this );
  238. }
  239. CRETURN( cRef );
  240. } //*** CConnPointEnum::Release
  241. //****************************************************************************
  242. //
  243. // IEnumConnectionPoints
  244. //
  245. //****************************************************************************
  246. //////////////////////////////////////////////////////////////////////////////
  247. //++
  248. //
  249. // STDMETHODIMP
  250. // CConnPointEnum::Next(
  251. // ULONG cConnectionsIn,
  252. // LPCONNECTIONPOINT * ppCPOut,
  253. // ULONG * pcFetchedOut
  254. // )
  255. //
  256. //--
  257. //////////////////////////////////////////////////////////////////////////////
  258. STDMETHODIMP
  259. CConnPointEnum::Next(
  260. ULONG cConnectionsIn,
  261. LPCONNECTIONPOINT * ppCPOut,
  262. ULONG * pcFetchedOut
  263. )
  264. {
  265. TraceFunc( "[IEnumConnectionPoints]" );
  266. HRESULT hr = S_FALSE;
  267. ULONG celt;
  268. if ( pcFetchedOut != NULL )
  269. {
  270. *pcFetchedOut = 0;
  271. }
  272. if ( m_pIter != NULL )
  273. {
  274. for( celt = 0; celt < cConnectionsIn; )
  275. {
  276. hr = THR( m_pIter->punk->TypeSafeQI( IConnectionPoint, &ppCPOut[ celt ] ) );
  277. if ( FAILED( hr ) )
  278. goto Error;
  279. ppCPOut[ celt ] = TraceInterface( L"ConnPointEnum!IConnectionPoint", IConnectionPoint, ppCPOut[ celt ], 1 );
  280. celt ++;
  281. m_pIter = m_pIter->pNext;
  282. if( m_pIter == NULL )
  283. break;
  284. }
  285. }
  286. else
  287. {
  288. celt = 0;
  289. }
  290. if ( celt != cConnectionsIn )
  291. {
  292. hr = S_FALSE;
  293. }
  294. else
  295. {
  296. hr = S_OK;
  297. }
  298. if ( pcFetchedOut != NULL )
  299. {
  300. *pcFetchedOut = celt;
  301. }
  302. Cleanup:
  303. HRETURN( hr );
  304. Error:
  305. while ( celt > 0 )
  306. {
  307. celt --;
  308. ppCPOut[ celt ]->Release();
  309. }
  310. goto Cleanup;
  311. } //*** CConnPointEnum::Next
  312. //////////////////////////////////////////////////////////////////////////////
  313. //++
  314. //
  315. // STDMETHODIMP
  316. // CConnPointEnum::Skip(
  317. // ULONG cConnectionsIn
  318. // )
  319. //
  320. //--
  321. //////////////////////////////////////////////////////////////////////////////
  322. STDMETHODIMP
  323. CConnPointEnum::Skip(
  324. ULONG cConnectionsIn
  325. )
  326. {
  327. TraceFunc( "[IEnumConnectionPoints]" );
  328. HRESULT hr = S_FALSE;
  329. ULONG celt;
  330. if ( m_pIter != NULL )
  331. {
  332. for ( celt = 0; celt < cConnectionsIn; celt ++ )
  333. {
  334. m_pIter = m_pIter->pNext;
  335. if ( m_pIter == NULL )
  336. break;
  337. }
  338. }
  339. if ( m_pIter == NULL )
  340. {
  341. hr = S_FALSE;
  342. }
  343. else
  344. {
  345. hr = S_OK;
  346. }
  347. HRETURN( hr );
  348. } //*** CConnPointEnum::Skip
  349. //////////////////////////////////////////////////////////////////////////////
  350. //++
  351. //
  352. // STDMETHODIMP
  353. // CConnPointEnum::Reset( void )
  354. //
  355. //--
  356. //////////////////////////////////////////////////////////////////////////////
  357. STDMETHODIMP
  358. CConnPointEnum::Reset( void )
  359. {
  360. TraceFunc( "[IEnumConnectionPoints]" );
  361. HRESULT hr = S_OK;
  362. m_pIter = m_pCPList;
  363. HRETURN( hr );
  364. } //*** CConnPointEnum::Reset
  365. //////////////////////////////////////////////////////////////////////////////
  366. //++
  367. //
  368. // STDMETHODIMP
  369. // CConnPointEnum::Clone(
  370. // IEnumConnectionPoints ** ppEnum
  371. // )
  372. //
  373. //--
  374. //////////////////////////////////////////////////////////////////////////////
  375. STDMETHODIMP
  376. CConnPointEnum::Clone(
  377. IEnumConnectionPoints ** ppEnum
  378. )
  379. {
  380. TraceFunc( "[IEnumConnectionPoints]" );
  381. HRESULT hr;
  382. CConnPointEnum * pcpenum = new CConnPointEnum();
  383. if ( pcpenum == NULL )
  384. {
  385. hr = THR( E_OUTOFMEMORY );
  386. goto Cleanup;
  387. }
  388. hr = THR( pcpenum->HrInit() );
  389. if ( FAILED( hr ) )
  390. {
  391. goto Cleanup;
  392. }
  393. hr = THR( pcpenum->HrCopy( this ) );
  394. if ( FAILED( hr ) )
  395. {
  396. goto Cleanup;
  397. }
  398. hr = THR( pcpenum->TypeSafeQI( IEnumConnectionPoints, ppEnum ) );
  399. if ( FAILED( hr ) )
  400. {
  401. goto Cleanup;
  402. }
  403. *ppEnum = TraceInterface( L"ConnPointEnum!IEnumConnectionPoints", IEnumConnectionPoints, *ppEnum, 1 );
  404. //
  405. // Release our ref and make sure we don't free it on the way out.
  406. //
  407. pcpenum->Release();
  408. pcpenum = NULL;
  409. Cleanup:
  410. if ( pcpenum != NULL )
  411. {
  412. delete pcpenum;
  413. }
  414. HRETURN( hr );
  415. } //*** CConnPointEnum::Clone
  416. //****************************************************************************
  417. //
  418. // Private
  419. //
  420. //****************************************************************************
  421. //////////////////////////////////////////////////////////////////////////////
  422. //++
  423. //
  424. // HRESULT
  425. // CConnPointEnum::HrCopy(
  426. // CConnPointEnum * pECPIn
  427. // )
  428. //
  429. //--
  430. //////////////////////////////////////////////////////////////////////////////
  431. HRESULT
  432. CConnPointEnum::HrCopy(
  433. CConnPointEnum * pECPIn
  434. )
  435. {
  436. TraceFunc1( "pECPIn = %p", pECPIn );
  437. HRESULT hr = S_OK;
  438. SCPEntry * pentry;
  439. Assert( m_pCPList == NULL );
  440. for( pentry = pECPIn->m_pCPList; pentry != NULL; pentry = pentry->pNext )
  441. {
  442. SCPEntry * pentryNew = (SCPEntry *) TraceAlloc( 0, sizeof(SCPEntry) );
  443. if ( pentryNew == NULL )
  444. {
  445. hr = THR( E_OUTOFMEMORY );
  446. goto Cleanup;
  447. }
  448. pentryNew->iid = pentry->iid;
  449. hr = THR( pentry->punk->TypeSafeQI( IUnknown, &pentryNew->punk ) );
  450. if ( FAILED( hr ) )
  451. {
  452. goto Cleanup;
  453. }
  454. pentryNew->punk = TraceInterface( L"ConnPointEnum!IUnknown", IUnknown, pentryNew->punk, 1 );
  455. pentryNew->pNext = m_pCPList;
  456. m_pCPList = pentryNew;
  457. }
  458. m_pIter = m_pCPList;
  459. Cleanup:
  460. HRETURN( hr );
  461. } //*** CConnPointEnum::CConnPointEnum
  462. //////////////////////////////////////////////////////////////////////////////
  463. //++
  464. //
  465. // HRESULT
  466. // CConnPointEnum::HrAddConnection(
  467. // REFIID riidIn,
  468. // IUnknown * punkIn
  469. // )
  470. //
  471. //--
  472. //////////////////////////////////////////////////////////////////////////////
  473. HRESULT
  474. CConnPointEnum::HrAddConnection(
  475. REFIID riidIn
  476. , IUnknown * punkIn
  477. )
  478. {
  479. TraceFunc( "" );
  480. HRESULT hr = S_FALSE;
  481. SCPEntry * pentry;
  482. //
  483. // Check to see if the interface is already registered.
  484. //
  485. for ( pentry = m_pCPList; pentry != NULL; pentry = pentry->pNext )
  486. {
  487. if ( pentry->iid == riidIn )
  488. {
  489. hr = THR( CO_E_OBJISREG );
  490. goto Cleanup;
  491. }
  492. } // for: pentry
  493. //
  494. // Not registered; add it.
  495. //
  496. pentry = (SCPEntry *) TraceAlloc( 0, sizeof( SCPEntry ) );
  497. if ( pentry == NULL )
  498. {
  499. hr = THR( E_OUTOFMEMORY );
  500. goto Cleanup;
  501. } // if:
  502. hr = THR( punkIn->TypeSafeQI( IUnknown, &pentry->punk ) );
  503. Assert( hr == S_OK );
  504. if ( FAILED( hr ) )
  505. {
  506. TraceFree( pentry );
  507. goto Cleanup;
  508. } // if:
  509. pentry->punk = TraceInterface( L"ConnPointEnum!IUnknown", IUnknown, pentry->punk, 1 );
  510. pentry->iid = riidIn;
  511. pentry->pNext = m_pCPList;
  512. m_pCPList = pentry;
  513. m_pIter = m_pCPList;
  514. LogMsg( L"[CConnPointEnum::HrAddConnection] punk %#08x added to the connection point enumerator. (hr=%#08x)", punkIn, hr );
  515. Cleanup:
  516. HRETURN( hr );
  517. } //*** CConnPointEnum::HrAddConnection