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.

593 lines
12 KiB

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