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.

890 lines
19 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1999-2002 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // EnumCPICCCB.cpp
  7. //
  8. // Description:
  9. // IClusCfgCallback Connection Point Enumerator implementation.
  10. //
  11. // Maintained By:
  12. // David Potter (DavidP) 14-JUN-2001
  13. // Geoffrey Pease (GPease) 10-NOV-2000
  14. //
  15. //////////////////////////////////////////////////////////////////////////////
  16. #include "Pch.h"
  17. #include "EnumCPICCCB.h"
  18. DEFINE_THISCLASS("CEnumCPICCCB")
  19. #define PUNK_BUFFER_GROW_SIZE 10
  20. //*************************************************************************//
  21. /////////////////////////////////////////////////////////////////////////////
  22. // CEnumCPICCCB class
  23. /////////////////////////////////////////////////////////////////////////////
  24. //////////////////////////////////////////////////////////////////////////////
  25. //++
  26. //
  27. // CEnumCPICCCB::S_HrCreateInstance
  28. //
  29. // Description:
  30. // Create a CEnumCPICCCB instance.
  31. //
  32. // Arguments:
  33. // None.
  34. //
  35. // Return Values:
  36. // S_OK
  37. // Success.
  38. //
  39. // E_POINTER
  40. // The passed in ppunk is NULL.
  41. //
  42. // other HRESULTs
  43. // Object creation failed.
  44. //
  45. //--
  46. //////////////////////////////////////////////////////////////////////////////
  47. HRESULT
  48. CEnumCPICCCB::S_HrCreateInstance(
  49. IUnknown ** ppunkOut
  50. )
  51. {
  52. TraceFunc( "" );
  53. HRESULT hr = S_OK;
  54. CEnumCPICCCB * pcc = NULL;
  55. Assert( ppunkOut != NULL );
  56. if ( ppunkOut == NULL )
  57. {
  58. hr = THR( E_POINTER );
  59. goto Cleanup;
  60. } // if:
  61. pcc = new CEnumCPICCCB();
  62. if ( pcc == NULL )
  63. {
  64. hr = THR( E_OUTOFMEMORY );
  65. goto Cleanup;
  66. } // if:
  67. hr = THR( pcc->HrInit() ); // fIsCloneIn = FALSE
  68. if ( FAILED( hr ) )
  69. {
  70. goto Cleanup;
  71. } // if:
  72. hr = THR( pcc->TypeSafeQI( IUnknown, ppunkOut ) );
  73. if ( FAILED( hr ) )
  74. {
  75. goto Cleanup;
  76. } // if:
  77. Cleanup:
  78. if ( pcc != NULL )
  79. {
  80. pcc->Release();
  81. } // if:
  82. HRETURN( hr );
  83. } //*** CEnumCPICCCB::S_HrCreateInstance
  84. //////////////////////////////////////////////////////////////////////////////
  85. //++
  86. //
  87. // CEnumCPICCCB::CEnumCPICCCB
  88. //
  89. // Description:
  90. // Default constructor.
  91. //
  92. // Arguments:
  93. // None.
  94. //
  95. // Return Values:
  96. // None.
  97. //
  98. //--
  99. //////////////////////////////////////////////////////////////////////////////
  100. CEnumCPICCCB::CEnumCPICCCB( void )
  101. : m_cRef( 1 )
  102. {
  103. TraceFunc( "" );
  104. InterlockedIncrement( &g_cObjects );
  105. TraceFuncExit();
  106. } //*** CEnumCPICCCB::CEnumCPICCCB
  107. //////////////////////////////////////////////////////////////////////////////
  108. //++
  109. //
  110. // CEnumCPICCCB::~CEnumCPICCCB
  111. //
  112. // Description:
  113. // Default destructor.
  114. //
  115. // Arguments:
  116. // None.
  117. //
  118. // Return Values:
  119. // None.
  120. //
  121. //--
  122. //////////////////////////////////////////////////////////////////////////////
  123. CEnumCPICCCB::~CEnumCPICCCB( void )
  124. {
  125. TraceFunc( "" );
  126. IUnknown * punk = NULL;
  127. if ( m_pList != NULL )
  128. {
  129. while ( m_cAlloced != 0 )
  130. {
  131. m_cAlloced --;
  132. punk = m_pList[ m_cAlloced ];
  133. AssertMsg( m_fIsClone || punk == NULL, "Someone didn't Unadvise before releasing the last Reference." );
  134. if ( punk != NULL )
  135. {
  136. punk->Release();
  137. }
  138. } // while: m_cAlloced
  139. TraceFree( m_pList );
  140. } // while:
  141. InterlockedDecrement( &g_cObjects );
  142. TraceFuncExit();
  143. } //*** CEnumCPICCCB::~CEnumCPICCCB
  144. //*************************************************************************//
  145. /////////////////////////////////////////////////////////////////////////////
  146. // CEnumCPICCCB -- IUnknown interface.
  147. /////////////////////////////////////////////////////////////////////////////
  148. //////////////////////////////////////////////////////////////////////////////
  149. //++
  150. //
  151. // CEnumCPICCCB::AddRef
  152. //
  153. // Description:
  154. // Increment the reference count of this object by one.
  155. //
  156. // Arguments:
  157. // None.
  158. //
  159. // Return Value:
  160. // The new reference count.
  161. //
  162. // Remarks:
  163. // None.
  164. //
  165. //--
  166. //////////////////////////////////////////////////////////////////////////////
  167. STDMETHODIMP_(ULONG)
  168. CEnumCPICCCB::AddRef( void )
  169. {
  170. TraceFunc( "[IUnknown]" );
  171. InterlockedIncrement( &m_cRef );
  172. CRETURN( m_cRef );
  173. } //*** CEnumCPICCCB::AddRef
  174. //////////////////////////////////////////////////////////////////////////////
  175. //++
  176. //
  177. // CTaskCancelCleanup::Release
  178. //
  179. // Description:
  180. // Decrement the reference count of this object by one.
  181. //
  182. // Arguments:
  183. // None.
  184. //
  185. // Return Value:
  186. // The new reference count.
  187. //
  188. // Remarks:
  189. // None.
  190. //
  191. //--
  192. //////////////////////////////////////////////////////////////////////////////
  193. STDMETHODIMP_(ULONG)
  194. CEnumCPICCCB::Release( void )
  195. {
  196. TraceFunc( "[IUnknown]" );
  197. LONG cRef;
  198. cRef = InterlockedDecrement( &m_cRef );
  199. if ( cRef == 0 )
  200. {
  201. TraceDo( delete this );
  202. }
  203. CRETURN( cRef );
  204. } //*** CEnumCPICCCB::Release
  205. //////////////////////////////////////////////////////////////////////////////
  206. //++
  207. //
  208. // CEnumCPICCCB::QueryInterface
  209. //
  210. // Description:
  211. // Query this object for the passed in interface.
  212. //
  213. // Arguments:
  214. // riidIn
  215. // Id of interface requested.
  216. //
  217. // ppvOut
  218. // Pointer to the requested interface.
  219. //
  220. // Return Value:
  221. // S_OK
  222. // If the interface is available on this object.
  223. //
  224. // E_NOINTERFACE
  225. // If the interface is not available.
  226. //
  227. // E_POINTER
  228. // ppvOut was NULL.
  229. //
  230. // Remarks:
  231. // None.
  232. //
  233. //--
  234. //////////////////////////////////////////////////////////////////////////////
  235. STDMETHODIMP
  236. CEnumCPICCCB::QueryInterface(
  237. REFIID riidIn
  238. , LPVOID * ppvOut
  239. )
  240. {
  241. TraceQIFunc( riidIn, ppvOut );
  242. HRESULT hr = S_OK;
  243. //
  244. // Validate arguments.
  245. //
  246. Assert( ppvOut != NULL );
  247. if ( ppvOut == NULL )
  248. {
  249. hr = THR( E_POINTER );
  250. goto Cleanup;
  251. }
  252. //
  253. // Handle known interfaces.
  254. //
  255. if ( IsEqualIID( riidIn, IID_IUnknown ) )
  256. {
  257. *ppvOut = static_cast< IEnumConnections * >( this );
  258. } // if: IUnknown
  259. else if ( IsEqualIID( riidIn, IID_IEnumConnections ) )
  260. {
  261. *ppvOut = TraceInterface( __THISCLASS__, IEnumConnections, this, 0 );
  262. } // else if: IEnumConnections
  263. else
  264. {
  265. *ppvOut = NULL;
  266. hr = E_NOINTERFACE;
  267. } // else
  268. //
  269. // Add a reference to the interface if successful.
  270. //
  271. if ( SUCCEEDED( hr ) )
  272. {
  273. ((IUnknown *) *ppvOut)->AddRef();
  274. } // if: success
  275. Cleanup:
  276. QIRETURN_IGNORESTDMARSHALLING( hr, riidIn );
  277. } //*** CEnumCPICCCB::QueryInterface
  278. //*************************************************************************//
  279. /////////////////////////////////////////////////////////////////////////////
  280. // CEnumCPICCCB -- IEnumConnectionPoints interface.
  281. /////////////////////////////////////////////////////////////////////////////
  282. //////////////////////////////////////////////////////////////////////////////
  283. //++
  284. //
  285. // CEnumCPICCCB::Next
  286. //
  287. // Description:
  288. // Enumerator Next method.
  289. //
  290. // Arguments:
  291. // cConnectionsIn
  292. // How many items requested. Also tells us how bing rgcd.
  293. //
  294. // rgcdOut
  295. // Array that gets the data.
  296. //
  297. // pcFetchedOut
  298. // How many did we place in the array.
  299. //
  300. // Return Values:
  301. // S_OK
  302. // Success.
  303. //
  304. // S_FALSE
  305. // cConnectionsIn > *pcFetchedOut. Did not return as many items
  306. // as the caller asked for.
  307. //
  308. // Other HRESULT errors.
  309. //
  310. //--
  311. //////////////////////////////////////////////////////////////////////////////
  312. STDMETHODIMP
  313. CEnumCPICCCB::Next(
  314. ULONG cConnectionsIn,
  315. LPCONNECTDATA rgcd,
  316. ULONG *pcFetchedOut
  317. )
  318. {
  319. TraceFunc( "[IEnumConnectionPoints]" );
  320. ULONG cIter;
  321. HRESULT hr = S_FALSE;
  322. if ( pcFetchedOut != NULL )
  323. {
  324. *pcFetchedOut = 0;
  325. } // if:
  326. for( cIter = 0
  327. ; ( cIter < cConnectionsIn ) && ( m_cIter < m_cCurrent )
  328. ; m_cIter++
  329. )
  330. {
  331. IUnknown * punk = m_pList[ m_cIter ];
  332. if ( punk != NULL )
  333. {
  334. hr = THR( punk->TypeSafeQI( IUnknown, &rgcd[ cIter ].pUnk ) );
  335. if ( FAILED( hr ) )
  336. goto Error;
  337. rgcd[ cIter ].pUnk = TraceInterface( L"EnumCPICCCB!IUnknown", IUnknown, rgcd[ cIter ].pUnk, 1 );
  338. rgcd[ cIter ].dwCookie = m_cIter + 1;
  339. cIter ++;
  340. } // if:
  341. } // for: cIter
  342. if ( cIter != cConnectionsIn )
  343. {
  344. hr = S_FALSE;
  345. } // if:
  346. else
  347. {
  348. hr = S_OK;
  349. } // else:
  350. if ( pcFetchedOut != NULL )
  351. {
  352. *pcFetchedOut = cIter;
  353. } // if:
  354. Cleanup:
  355. HRETURN( hr );
  356. Error:
  357. while ( cIter != 0 )
  358. {
  359. cIter --;
  360. rgcd[ cIter ].pUnk->Release();
  361. } // while:
  362. goto Cleanup;
  363. } //*** CEnumCPICCCB::Next
  364. //////////////////////////////////////////////////////////////////////////////
  365. //++
  366. //
  367. // CEnumCPICCCB::Skip
  368. //
  369. // Description:
  370. // Enumerator Skip method.
  371. //
  372. // Arguments:
  373. // cConnectionsIn
  374. // Number of items to skip.
  375. //
  376. // Return Values:
  377. // S_OK
  378. // Success.
  379. //
  380. // S_FALSE
  381. // The number to skip put us at the end of the list.
  382. //
  383. // Other HRESULT errors.
  384. //
  385. //--
  386. //////////////////////////////////////////////////////////////////////////////
  387. STDMETHODIMP
  388. CEnumCPICCCB::Skip(
  389. ULONG cConnectionsIn
  390. )
  391. {
  392. TraceFunc( "[IEnumConnectionPoints]" );
  393. HRESULT hr = S_OK;
  394. m_cIter += cConnectionsIn;
  395. if ( m_cIter >= m_cCurrent )
  396. {
  397. m_cIter = m_cCurrent;
  398. hr = S_FALSE;
  399. } // if:
  400. HRETURN( hr );
  401. } //*** CEnumCPICCCB::Skip
  402. //////////////////////////////////////////////////////////////////////////////
  403. //++
  404. //
  405. // CEnumCPICCCB::Reset
  406. //
  407. // Description:
  408. // Enumerator Reset method.
  409. //
  410. // Arguments:
  411. // None.
  412. //
  413. // Return Values:
  414. // S_OK
  415. // Success.
  416. //
  417. //--
  418. //////////////////////////////////////////////////////////////////////////////
  419. STDMETHODIMP
  420. CEnumCPICCCB::Reset( void )
  421. {
  422. TraceFunc( "[IEnumConnectionPoints]" );
  423. HRESULT hr = S_OK;
  424. m_cIter = 0;
  425. HRETURN( hr );
  426. } //*** CEnumCPICCCB::Reset
  427. //////////////////////////////////////////////////////////////////////////////
  428. //++
  429. //
  430. // CEnumCPICCCB::Clone
  431. //
  432. // Description:
  433. // Enumerator Clone method.
  434. //
  435. // Arguments:
  436. // ppEnumOut
  437. // The new enumerator that we are cloning ourselves into.
  438. //
  439. // Return Values:
  440. // S_OK
  441. // Success.
  442. //
  443. // Other HRESULT errors.
  444. //
  445. //--
  446. //////////////////////////////////////////////////////////////////////////////
  447. STDMETHODIMP
  448. CEnumCPICCCB::Clone(
  449. IEnumConnections **ppEnumOut
  450. )
  451. {
  452. TraceFunc( "[IEnumConnectionPoints]" );
  453. HRESULT hr;
  454. CEnumCPICCCB * pecp = new CEnumCPICCCB();
  455. if ( pecp == NULL )
  456. {
  457. hr = THR( E_OUTOFMEMORY );
  458. goto Cleanup;
  459. } // if:
  460. hr = THR( pecp->HrInit( TRUE ) ); // fIsCloneIn = TRUE
  461. if ( FAILED( hr ) )
  462. {
  463. goto Cleanup;
  464. } // if:
  465. hr = THR( pecp->HrCopy( this ) );
  466. if ( FAILED( hr ) )
  467. {
  468. goto Cleanup;
  469. } // if:
  470. hr = THR( pecp->TypeSafeQI( IEnumConnections, ppEnumOut ) );
  471. if ( FAILED( hr ) )
  472. {
  473. goto Cleanup;
  474. } // if:
  475. *ppEnumOut = TraceInterface( L"EnumCPICCCB!IEnumConnections", IEnumConnections, *ppEnumOut, 1 );
  476. pecp->Release();
  477. pecp = NULL;
  478. Cleanup:
  479. if ( pecp != NULL )
  480. {
  481. delete pecp;
  482. } // if:
  483. HRETURN( hr );
  484. } //*** CEnumCPICCCB::Clone
  485. //*************************************************************************//
  486. /////////////////////////////////////////////////////////////////////////////
  487. // CEnumCPINotifyUI -- Public methods.
  488. /////////////////////////////////////////////////////////////////////////////
  489. //////////////////////////////////////////////////////////////////////////////
  490. //++
  491. //
  492. // CEnumCPICCCB::HrAddConnection
  493. //
  494. // Description:
  495. // Add a connection point container to our list of clients.
  496. //
  497. // Arguments:
  498. // punkIn
  499. // The new client object.
  500. //
  501. // pdwCookieOut
  502. // Cookie used to find this client object in our list.
  503. //
  504. // Return Values:
  505. // S_OK
  506. // Success.
  507. //
  508. // Other HRESULT errors.
  509. //
  510. //--
  511. //////////////////////////////////////////////////////////////////////////////
  512. HRESULT
  513. CEnumCPICCCB::HrAddConnection(
  514. IUnknown * punkIn,
  515. DWORD * pdwCookieOut
  516. )
  517. {
  518. TraceFunc( "" );
  519. HRESULT hr = S_FALSE;
  520. ULONG cIter;
  521. if ( pdwCookieOut == NULL )
  522. {
  523. hr = THR( E_POINTER );
  524. goto Cleanup;
  525. }
  526. //
  527. // See if there is an openning in the currently allocated list.
  528. //
  529. for ( cIter = 0; cIter < m_cCurrent; cIter ++ )
  530. {
  531. if ( m_pList[ cIter ] == NULL )
  532. {
  533. //
  534. // Found an openning... try to use it.
  535. //
  536. hr = THR( punkIn->TypeSafeQI( IUnknown, &m_pList[ cIter ] ) );
  537. m_pList[ cIter ] = TraceInterface( L"CEnumCPICCCB!IUnknown", IUnknown, m_pList[ cIter ], 1 );
  538. *pdwCookieOut = cIter + 1;
  539. // Doesn't matter if it succeeded or fail, exit.
  540. goto Cleanup;
  541. }
  542. }
  543. if ( m_cCurrent == m_cAlloced )
  544. {
  545. IUnknown ** pNewList;
  546. //
  547. // Try making some more space.
  548. //
  549. pNewList = (IUnknown **) TraceAlloc( HEAP_ZERO_MEMORY, ( m_cAlloced + PUNK_BUFFER_GROW_SIZE ) * sizeof( IUnknown * ) );
  550. if ( pNewList == NULL )
  551. {
  552. hr = THR( E_OUTOFMEMORY );
  553. goto Cleanup;
  554. }
  555. CopyMemory( pNewList, m_pList, m_cCurrent * sizeof( IUnknown * ) );
  556. TraceFree( m_pList );
  557. m_pList = pNewList;
  558. m_cAlloced += PUNK_BUFFER_GROW_SIZE;
  559. }
  560. //
  561. // Add it to the list.
  562. //
  563. hr = THR( punkIn->TypeSafeQI( IUnknown, &m_pList[ m_cCurrent ] ) );
  564. if ( FAILED( hr ) )
  565. {
  566. goto Cleanup;
  567. }
  568. m_pList[ m_cCurrent ] = TraceInterface( L"CEnumCPICCCB!IUnknown", IUnknown, m_pList[ m_cCurrent ], 1 );
  569. m_cCurrent ++;
  570. *pdwCookieOut = m_cCurrent; // starts at ONE, not ZERO
  571. Cleanup:
  572. HRETURN( hr );
  573. } //*** CEnumCPICCCB::HrAddConnection
  574. //////////////////////////////////////////////////////////////////////////////
  575. //++
  576. //
  577. // CEnumCPICCCB::HrRemoveConnection
  578. //
  579. // Description:
  580. // Remove the client identified by the passed in cookie from the list.
  581. //
  582. // Arguments:
  583. // dwCookieIn
  584. // The cookie of the client that is to be removed from the list.
  585. //
  586. // Return Values:
  587. // S_OK
  588. // Success.
  589. //
  590. // Other HRESULT errors.
  591. //
  592. //--
  593. //////////////////////////////////////////////////////////////////////////////
  594. HRESULT
  595. CEnumCPICCCB::HrRemoveConnection(
  596. DWORD dwCookieIn
  597. )
  598. {
  599. TraceFunc( "" );
  600. HRESULT hr;
  601. if ( dwCookieIn == 0 || dwCookieIn > m_cCurrent )
  602. {
  603. hr = THR( E_INVALIDARG );
  604. goto Cleanup;
  605. } // if:
  606. if ( m_pList[ dwCookieIn - 1 ] == NULL )
  607. {
  608. hr = THR( E_INVALIDARG );
  609. goto Cleanup;
  610. } // if:
  611. m_pList[ dwCookieIn - 1 ]->Release();
  612. m_pList[ dwCookieIn - 1 ] = NULL;
  613. hr = S_OK;
  614. Cleanup:
  615. HRETURN( hr );
  616. } //*** CEnumCPICCCB::HrRemoveConnection
  617. //*************************************************************************//
  618. /////////////////////////////////////////////////////////////////////////////
  619. // CEnumCPICCCB -- Private methods.
  620. /////////////////////////////////////////////////////////////////////////////
  621. //////////////////////////////////////////////////////////////////////////////
  622. //++
  623. //
  624. // CEnumCPICCCB::HrInt
  625. //
  626. // Description:
  627. // Do any initialization that may fail here.
  628. //
  629. // Arguments:
  630. // fIsCloneIn
  631. // Is this instance a clone?
  632. //
  633. // Return Values:
  634. // S_OK
  635. // Success.
  636. //
  637. // Other HRESULT errors.
  638. //
  639. //--
  640. //////////////////////////////////////////////////////////////////////////////
  641. HRESULT
  642. CEnumCPICCCB::HrInit(
  643. BOOL fIsCloneIn // = FALSE
  644. )
  645. {
  646. TraceFunc( "" );
  647. // IUnknown stuff
  648. Assert( m_cRef == 1 );
  649. // IEnumConnectionPoints
  650. Assert( m_cAlloced == 0 );
  651. Assert( m_cCurrent == 0 );
  652. Assert( m_cIter == 0 );
  653. Assert( m_pList == NULL );
  654. Assert( m_fIsClone == FALSE );
  655. m_fIsClone = fIsCloneIn;
  656. // INotifyUI
  657. HRETURN( S_OK );
  658. } //*** CEnumCPICCCB::HrInit
  659. //////////////////////////////////////////////////////////////////////////////
  660. //++
  661. //
  662. // CEnumCPICCCB::HrCopy
  663. //
  664. // Description:
  665. // Copy from the passed in enumerator.
  666. //
  667. // Arguments:
  668. // pecpIn
  669. // The source that we are to copy from.
  670. //
  671. // Return Values:
  672. // S_OK
  673. // Success.
  674. //
  675. // Other HRESULT errors.
  676. //
  677. //--
  678. //////////////////////////////////////////////////////////////////////////////
  679. HRESULT
  680. CEnumCPICCCB::HrCopy(
  681. CEnumCPICCCB * pecpIn
  682. )
  683. {
  684. TraceFunc( "" );
  685. HRESULT hr = S_FALSE;
  686. ULONG cIter;
  687. Assert( m_cAlloced == 0 );
  688. Assert( m_cCurrent == 0 );
  689. Assert( m_pList == 0 );
  690. m_pList = (IUnknown**) TraceAlloc( HEAP_ZERO_MEMORY, pecpIn->m_cCurrent * sizeof( IUnknown * ) );
  691. if ( m_pList == NULL )
  692. {
  693. hr = THR( E_OUTOFMEMORY );
  694. goto Cleanup;
  695. } // if:
  696. m_cCurrent = m_cAlloced = pecpIn->m_cCurrent;
  697. m_cIter = 0;
  698. for ( cIter = 0; cIter < pecpIn->m_cCurrent; cIter ++ )
  699. {
  700. //
  701. // Does the source have a pointer at the current index? If it does then "copy" it,
  702. // otherwise NULL out that index in our copy...
  703. //
  704. if ( pecpIn->m_pList[ cIter ] != NULL )
  705. {
  706. hr = THR( pecpIn->m_pList[ cIter ]->TypeSafeQI( IUnknown, &m_pList[ cIter ] ) );
  707. if ( FAILED( hr ) )
  708. {
  709. goto Cleanup;
  710. } // if:
  711. m_pList[ cIter ] = TraceInterface( L"EnumCPICCCB!IUnknown", IUnknown, m_pList[ cIter ], 1 );
  712. } // if:
  713. else
  714. {
  715. m_pList[ cIter ] = NULL;
  716. } // else:
  717. } // for:
  718. hr = S_OK;
  719. Cleanup:
  720. HRETURN( hr );
  721. } //*** CEnumCPICCCB::HrCopy