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.

565 lines
12 KiB

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