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.

1196 lines
27 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 2000-2002 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // CEnumLocalQuorum.cpp
  7. //
  8. // Description:
  9. // This file contains the definition of the CEnumLocalQuorum
  10. // class.
  11. //
  12. // The class CEnumLocalQuorum is the enumeration of cluster
  13. // local quorum devices. It implements the IEnumClusCfgManagedResources
  14. // interface.
  15. //
  16. // Maintained By:
  17. // Galen Barbee (GalenB) 18-DEC-2000
  18. //
  19. //////////////////////////////////////////////////////////////////////////////
  20. //////////////////////////////////////////////////////////////////////////////
  21. // Include Files
  22. //////////////////////////////////////////////////////////////////////////////
  23. #include "Pch.h"
  24. #include <PropList.h>
  25. #include "CEnumLocalQuorum.h"
  26. #include "CLocalQuorum.h"
  27. //////////////////////////////////////////////////////////////////////////////
  28. // Constant Definitions
  29. //////////////////////////////////////////////////////////////////////////////
  30. DEFINE_THISCLASS( "CEnumLocalQuorum" );
  31. //*************************************************************************//
  32. /////////////////////////////////////////////////////////////////////////////
  33. // CEnumLocalQuorum class
  34. /////////////////////////////////////////////////////////////////////////////
  35. //////////////////////////////////////////////////////////////////////////////
  36. //++
  37. //
  38. // CEnumLocalQuorum::S_HrCreateInstance
  39. //
  40. // Description:
  41. // Create a CEnumLocalQuorum instance.
  42. //
  43. // Arguments:
  44. // None.
  45. //
  46. // Return Values:
  47. // S_OK
  48. // Success.
  49. //
  50. // E_POINTER
  51. // The passed in ppunk is NULL.
  52. //
  53. // other HRESULTs
  54. // Object creation failed.
  55. //
  56. //--
  57. //////////////////////////////////////////////////////////////////////////////
  58. HRESULT
  59. CEnumLocalQuorum::S_HrCreateInstance( IUnknown ** ppunkOut )
  60. {
  61. TraceFunc( "" );
  62. HRESULT hr = S_OK;
  63. CEnumLocalQuorum * pelq = NULL;
  64. if ( ppunkOut == NULL )
  65. {
  66. hr = THR( E_POINTER );
  67. goto Cleanup;
  68. } // if:
  69. pelq = new CEnumLocalQuorum();
  70. if ( pelq == NULL )
  71. {
  72. hr = THR( E_OUTOFMEMORY );
  73. goto Cleanup;
  74. } // if: error allocating object
  75. hr = THR( pelq->HrInit() );
  76. if ( FAILED( hr ) )
  77. {
  78. goto Cleanup;
  79. } // if: HrInit() failed
  80. hr = THR( pelq->TypeSafeQI( IUnknown, ppunkOut ) );
  81. if ( FAILED( hr ) )
  82. {
  83. goto Cleanup;
  84. } // if: QI failed
  85. Cleanup:
  86. if ( FAILED( hr ) )
  87. {
  88. LogMsg( L"[SRV] CEnumLocalQuorum::S_HrCreateInstance() failed. (hr = %#08x)", hr );
  89. } // if:
  90. if ( pelq != NULL )
  91. {
  92. pelq->Release();
  93. } // if:
  94. HRETURN( hr );
  95. } //*** CEnumLocalQuorum::S_HrCreateInstance
  96. //////////////////////////////////////////////////////////////////////////////
  97. //++
  98. //
  99. // IUnknown *
  100. // CEnumLocalQuorum::S_RegisterCatIDSupport
  101. //
  102. // Description:
  103. // Registers/unregisters this class with the categories that it belongs
  104. // to.
  105. //
  106. // Arguments:
  107. // IN ICatRegister * picrIn
  108. // Used to register/unregister our CATID support.
  109. //
  110. // IN BOOL fCreateIn
  111. // When true we are registering the server. When false we are
  112. // un-registering the server.
  113. //
  114. // Return Values:
  115. // S_OK
  116. // Success.
  117. //
  118. // E_INVALIDARG
  119. // The passed in ICatRgister pointer was NULL.
  120. //
  121. // other HRESULTs
  122. // Registration/Unregistration failed.
  123. //
  124. //--
  125. //////////////////////////////////////////////////////////////////////////////
  126. HRESULT
  127. CEnumLocalQuorum::S_RegisterCatIDSupport(
  128. ICatRegister * picrIn,
  129. BOOL fCreateIn
  130. )
  131. {
  132. TraceFunc( "" );
  133. HRESULT hr = S_OK;
  134. CATID rgCatIds[ 1 ];
  135. if ( picrIn == NULL )
  136. {
  137. hr = THR( E_INVALIDARG );
  138. goto Cleanup;
  139. } // if:
  140. rgCatIds[ 0 ] = CATID_EnumClusCfgManagedResources;
  141. if ( fCreateIn )
  142. {
  143. hr = THR( picrIn->RegisterClassImplCategories( CLSID_EnumLocalQuorum, 1, rgCatIds ) );
  144. } // if:
  145. Cleanup:
  146. HRETURN( hr );
  147. } //*** CEnumLocalQuorum::S_RegisterCatIDSupport
  148. /////////////////////////////////////////////////////////////////////////////
  149. //++
  150. //
  151. // CEnumLocalQuorum:HrNodeResourceCallback
  152. //
  153. // Description:
  154. // Called by CClusterUtils::HrEnumNodeResources when it finds a
  155. // resource for this node.
  156. //
  157. // Arguments:
  158. //
  159. //
  160. // Return Value:
  161. // S_OK
  162. // Success.
  163. //
  164. // Win32 Error
  165. // something failed.
  166. //
  167. // Remarks:
  168. // None.
  169. //
  170. //--
  171. //////////////////////////////////////////////////////////////////////////////
  172. HRESULT
  173. CEnumLocalQuorum::HrNodeResourceCallback(
  174. HCLUSTER hClusterIn,
  175. HRESOURCE hResourceIn
  176. )
  177. {
  178. TraceFunc( "" );
  179. HRESULT hr = S_OK;
  180. DWORD sc;
  181. CClusPropList cplPriv;
  182. CClusPropList cplCommonRO;
  183. CLUSPROP_BUFFER_HELPER cpbh;
  184. BOOL fIsQuorum;
  185. IUnknown * punk = NULL;
  186. IClusCfgManagedResourceInfo * pcccmri = NULL;
  187. IClusCfgVerifyQuorum * piccvq = NULL;
  188. hr = STHR( HrIsResourceOfType( hResourceIn, L"Local Quorum" ) );
  189. if ( FAILED( hr ) )
  190. {
  191. goto Cleanup;
  192. } // if:
  193. //
  194. // If this resource is not a local quorum then we simply want to
  195. // skip it.
  196. //
  197. if ( hr == S_FALSE )
  198. {
  199. goto Cleanup;
  200. } // if:
  201. hr = STHR( HrIsCoreResource( hResourceIn ) );
  202. if ( FAILED( hr ) )
  203. {
  204. goto Cleanup;
  205. } // if:
  206. fIsQuorum = ( hr == S_OK );
  207. LOG_STATUS_REPORT_STRING( L"This node owns a local quorum resource. It '%1!ws!' the quorum.", fIsQuorum ? L"is" : L"is not", hr );
  208. hr = THR( CLocalQuorum::S_HrCreateInstance( &punk ) );
  209. if ( FAILED( hr ) )
  210. {
  211. goto Cleanup;
  212. } // if:
  213. hr = THR( HrSetInitialize( punk, m_picccCallback, m_lcid ) );
  214. if ( FAILED( hr ) )
  215. {
  216. goto Cleanup;
  217. } // if:
  218. hr = THR( punk->TypeSafeQI( IClusCfgManagedResourceInfo, &pcccmri ) );
  219. if ( FAILED( hr ) )
  220. {
  221. goto Cleanup;
  222. } // if:
  223. //
  224. // If a local quorum resource is found, ie we get here, then the
  225. // local quorum resource exists and needs to be managed by befault
  226. // by the cluster.
  227. //
  228. hr = THR( pcccmri->SetManagedByDefault( TRUE ) );
  229. if ( FAILED( hr ) )
  230. {
  231. goto Cleanup;
  232. } // if:
  233. //
  234. // If a local quorum resource is found, ie we get here, then the
  235. // local quorum resource exists and is in the cluster.
  236. //
  237. hr = THR( pcccmri->SetManaged( TRUE ) );
  238. if ( FAILED( hr ) )
  239. {
  240. goto Cleanup;
  241. } // if:
  242. hr = THR( pcccmri->SetQuorumResource( fIsQuorum ) );
  243. if ( FAILED( hr ) )
  244. {
  245. goto Cleanup;
  246. } // if:
  247. hr = THR( pcccmri->TypeSafeQI( IClusCfgVerifyQuorum, &piccvq ) );
  248. if ( FAILED( hr ) )
  249. {
  250. goto Cleanup;
  251. } // if:
  252. // Find out if the Debug flag is set....
  253. sc = TW32( cplPriv.ScGetResourceProperties( hResourceIn, CLUSCTL_RESOURCE_GET_PRIVATE_PROPERTIES ) );
  254. if ( sc != ERROR_SUCCESS )
  255. {
  256. goto MakeHr;
  257. } // if:
  258. sc = cplPriv.ScMoveToPropertyByName( L"Debug" );
  259. if ( sc == ERROR_NO_MORE_ITEMS )
  260. {
  261. hr = THR( piccvq->SetMultiNodeCapable( false ) );
  262. if ( FAILED( hr ) )
  263. {
  264. goto Cleanup;
  265. } // if:
  266. } // if:
  267. else if ( sc == ERROR_SUCCESS )
  268. {
  269. cpbh = cplPriv.CbhCurrentValue();
  270. Assert( cpbh.pSyntax->dw == CLUSPROP_SYNTAX_LIST_VALUE_DWORD );
  271. hr = THR( piccvq->SetMultiNodeCapable( !( cpbh.pDwordValue->dw == 0 ) ) );
  272. if ( FAILED( hr ) )
  273. {
  274. goto Cleanup;
  275. } // if:
  276. } // else if:
  277. else
  278. {
  279. TW32( sc );
  280. goto MakeHr;
  281. } // else:
  282. // get the name of this resource.
  283. sc = TW32( cplCommonRO.ScGetResourceProperties( hResourceIn, CLUSCTL_RESOURCE_GET_RO_COMMON_PROPERTIES ) );
  284. if ( sc != ERROR_SUCCESS )
  285. {
  286. goto MakeHr;
  287. } // if:
  288. sc = cplCommonRO.ScMoveToPropertyByName( L"Name" );
  289. if ( sc == ERROR_SUCCESS )
  290. {
  291. cpbh = cplCommonRO.CbhCurrentValue();
  292. Assert( cpbh.pSyntax->dw == CLUSPROP_SYNTAX_LIST_VALUE_SZ );
  293. hr = THR( pcccmri->SetName( cpbh.pStringValue->sz ) );
  294. if ( FAILED( hr ) )
  295. {
  296. goto Cleanup;
  297. } // if:
  298. } // if:
  299. else
  300. {
  301. TW32( sc );
  302. goto MakeHr;
  303. } // else:
  304. hr = THR( HrAddResourceToArray( punk ) );
  305. goto Cleanup;
  306. MakeHr:
  307. hr = HRESULT_FROM_WIN32( sc );
  308. Cleanup:
  309. if ( piccvq != NULL )
  310. {
  311. piccvq->Release();
  312. } // if:
  313. if ( pcccmri != NULL )
  314. {
  315. pcccmri->Release();
  316. } // if:
  317. if ( punk != NULL )
  318. {
  319. punk->Release();
  320. } // if:
  321. HRETURN( hr );
  322. } //*** CEnumLocalQuorum::HrNodeResourceCallback
  323. //*************************************************************************//
  324. /////////////////////////////////////////////////////////////////////////////
  325. // CEnumLocalQuorum class -- Private Methods.
  326. /////////////////////////////////////////////////////////////////////////////
  327. //////////////////////////////////////////////////////////////////////////////
  328. //++
  329. //
  330. // CEnumLocalQuorum::CEnumLocalQuorum
  331. //
  332. // Description:
  333. // Constructor of the CEnumLocalQuorum class. This initializes
  334. // the m_cRef variable to 1 instead of 0 to account of possible
  335. // QueryInterface failure in DllGetClassObject.
  336. //
  337. // Arguments:
  338. // None.
  339. //
  340. // Return Value:
  341. // None.
  342. //
  343. // Remarks:
  344. // None.
  345. //
  346. //--
  347. //////////////////////////////////////////////////////////////////////////////
  348. CEnumLocalQuorum::CEnumLocalQuorum( void )
  349. : m_cRef( 1 )
  350. , m_lcid( LOCALE_NEUTRAL )
  351. {
  352. TraceFunc( "" );
  353. // Increment the count of components in memory so the DLL hosting this
  354. // object cannot be unloaded.
  355. InterlockedIncrement( &g_cObjects );
  356. Assert( m_picccCallback == NULL );
  357. Assert( m_prgQuorums == NULL );
  358. Assert( m_idxNext == 0 );
  359. Assert( m_idxEnumNext == 0 );
  360. Assert( m_bstrNodeName == NULL );
  361. Assert( !m_fEnumLoaded );
  362. Assert( m_cQuorumCount == 0 );
  363. TraceFuncExit();
  364. } //*** CEnumLocalQuorum::CEnumLocalQuorum
  365. //////////////////////////////////////////////////////////////////////////////
  366. //++
  367. //
  368. // CEnumLocalQuorum::~CEnumLocalQuorum
  369. //
  370. // Description:
  371. // Desstructor of the CEnumLocalQuorum class.
  372. //
  373. // Arguments:
  374. // None.
  375. //
  376. // Return Value:
  377. // None.
  378. //
  379. // Remarks:
  380. // None.
  381. //
  382. //--
  383. //////////////////////////////////////////////////////////////////////////////
  384. CEnumLocalQuorum::~CEnumLocalQuorum( void )
  385. {
  386. TraceFunc( "" );
  387. ULONG idx;
  388. if ( m_picccCallback != NULL )
  389. {
  390. m_picccCallback->Release();
  391. } // if:
  392. for ( idx = 0; idx < m_idxNext; idx++ )
  393. {
  394. if ( (*m_prgQuorums)[ idx ] != NULL )
  395. {
  396. ((*m_prgQuorums)[ idx ])->Release();
  397. } // end if:
  398. } // for:
  399. TraceFree( m_prgQuorums );
  400. TraceSysFreeString( m_bstrNodeName );
  401. // There's going to be one less component in memory. Decrement component count.
  402. InterlockedDecrement( &g_cObjects );
  403. TraceFuncExit();
  404. } //*** CEnumLocalQuorum::~CEnumLocalQuorum
  405. //////////////////////////////////////////////////////////////////////////////
  406. //++
  407. //
  408. // CEnumLocalQuorum::HrInit
  409. //
  410. // Description:
  411. // Initialize this component.
  412. //
  413. // Arguments:
  414. // None.
  415. //
  416. // Return Value:
  417. //
  418. //
  419. // Remarks:
  420. // None.
  421. //
  422. //--
  423. //////////////////////////////////////////////////////////////////////////////
  424. HRESULT
  425. CEnumLocalQuorum::HrInit( void )
  426. {
  427. TraceFunc( "" );
  428. // IUnknown
  429. Assert( m_cRef == 1 );
  430. HRETURN( S_OK );
  431. } //*** CEnumLocalQuorum::HrInit
  432. //////////////////////////////////////////////////////////////////////////////
  433. //++
  434. //
  435. // CEnumLocalQuorum::HrLoadResources
  436. //
  437. // Description:
  438. // Initialize this component.
  439. //
  440. // Arguments:
  441. // None.
  442. //
  443. // Return Value:
  444. //
  445. //
  446. // Remarks:
  447. // None.
  448. //
  449. //--
  450. //////////////////////////////////////////////////////////////////////////////
  451. HRESULT
  452. CEnumLocalQuorum::HrLoadResources( void )
  453. {
  454. TraceFunc( "" );
  455. HRESULT hr = S_OK;
  456. BSTR bstrLocalNetBIOSName = NULL;
  457. //
  458. // Get netbios name for clusapi calls.
  459. //
  460. hr = THR( HrGetComputerName( ComputerNameNetBIOS, &bstrLocalNetBIOSName, TRUE ) );
  461. if ( FAILED( hr ) )
  462. {
  463. goto Cleanup;
  464. } // if:
  465. //
  466. // If the cluster service is running then load any local quorum
  467. // resources that we own.
  468. //
  469. hr = STHR( HrIsClusterServiceRunning() );
  470. if ( hr == S_OK )
  471. {
  472. hr = THR( HrEnumNodeResources( bstrLocalNetBIOSName ) );
  473. if ( FAILED( hr ) )
  474. {
  475. goto Cleanup;
  476. } // if:
  477. //
  478. // If this node doesn't own an instance of this resource then we need
  479. // to create a dummy resource for MiddleTier analysis.
  480. //
  481. if ( m_idxNext == 0 )
  482. {
  483. LogMsg( L"[SRV] This node does not own a Local Quorum resource. Creating a dummy resource." );
  484. hr = THR( HrCreateDummyObject() );
  485. } // if:
  486. } // if:
  487. else if ( hr == S_FALSE )
  488. {
  489. //
  490. // If cluster service isn't running then we need to create a dummy resource
  491. // for MiddleTier analysis and for EvictCleanup.
  492. //
  493. LogMsg( L"[SRV] The cluster service is not running. Creating a dummy Local Quorum resource." );
  494. hr = THR( HrCreateDummyObject() );
  495. } // else if:
  496. Cleanup:
  497. TraceSysFreeString( bstrLocalNetBIOSName );
  498. HRETURN( hr );
  499. } //*** CEnumLocalQuorum::HrLoadResources
  500. /////////////////////////////////////////////////////////////////////////////
  501. //++
  502. //
  503. // CEnumLocalQuorum:HrAddResourceToArray
  504. //
  505. // Description:
  506. // Add the passed in local quorum to the array of punks that holds the
  507. // list of local quorums.
  508. //
  509. // Arguments:
  510. //
  511. //
  512. // Return Value:
  513. // S_OK
  514. // Success
  515. //
  516. // E_OUTOFMEMORY
  517. // Couldn't allocate memeory.
  518. //
  519. // Remarks:
  520. // None.
  521. //
  522. //--
  523. //////////////////////////////////////////////////////////////////////////////
  524. HRESULT
  525. CEnumLocalQuorum::HrAddResourceToArray( IUnknown * punkIn )
  526. {
  527. TraceFunc( "" );
  528. Assert( punkIn != NULL );
  529. HRESULT hr = S_OK;
  530. IUnknown * ((*prgpunks)[]) = NULL;
  531. prgpunks = (IUnknown *((*)[])) TraceReAlloc( m_prgQuorums, sizeof( IUnknown * ) * ( m_idxNext + 1 ), HEAP_ZERO_MEMORY );
  532. if ( prgpunks == NULL )
  533. {
  534. hr = THR( E_OUTOFMEMORY );
  535. STATUS_REPORT_REF( TASKID_Major_Find_Devices, TASKID_Minor_HrAddResourceToArray, IDS_ERROR_OUTOFMEMORY, IDS_ERROR_OUTOFMEMORY_REF, hr );
  536. goto Cleanup;
  537. } // if:
  538. m_prgQuorums = prgpunks;
  539. (*m_prgQuorums)[ m_idxNext++ ] = punkIn;
  540. punkIn->AddRef();
  541. m_cQuorumCount += 1;
  542. Cleanup:
  543. HRETURN( hr );
  544. } //*** CEnumLocalQuorum::HrAddResourceToArray
  545. //////////////////////////////////////////////////////////////////////////////
  546. //++
  547. //
  548. // CEnumLocalQuorum::HrCreateDummyObject
  549. //
  550. // Description:
  551. // Create a dummy object so the MiddleTier will be happy.
  552. //
  553. // Arguments:
  554. // None.
  555. //
  556. // Return Value:
  557. //
  558. // Remarks:
  559. // None.
  560. //
  561. //--
  562. //////////////////////////////////////////////////////////////////////////////
  563. HRESULT
  564. CEnumLocalQuorum::HrCreateDummyObject( void )
  565. {
  566. TraceFunc( "" );
  567. HRESULT hr = S_OK;
  568. IUnknown * punk = NULL;
  569. hr = THR( CLocalQuorum::S_HrCreateInstance( &punk ) );
  570. if ( FAILED( hr ) )
  571. {
  572. goto Cleanup;
  573. } // if:
  574. hr = THR( HrSetInitialize( punk, m_picccCallback, m_lcid ) );
  575. if ( FAILED( hr ) )
  576. {
  577. goto Cleanup;
  578. } // if:
  579. hr = THR( HrAddResourceToArray( punk ) );
  580. Cleanup:
  581. if ( punk != NULL )
  582. {
  583. punk->Release();
  584. } // if:
  585. HRETURN( hr );
  586. } //*** CEnumLocalQuorum::HrCreateDummyObject
  587. //*************************************************************************//
  588. /////////////////////////////////////////////////////////////////////////////
  589. // CEnumLocalQuorum -- IUknkown interface.
  590. /////////////////////////////////////////////////////////////////////////////
  591. //////////////////////////////////////////////////////////////////////////////
  592. //++
  593. //
  594. // CEnumLocalQuorum::AddRef
  595. //
  596. // Description:
  597. // Increment the reference count of this object by one.
  598. //
  599. // Arguments:
  600. // None.
  601. //
  602. // Return Value:
  603. // The new reference count.
  604. //
  605. // Remarks:
  606. // None.
  607. //
  608. //--
  609. //////////////////////////////////////////////////////////////////////////////
  610. STDMETHODIMP_( ULONG )
  611. CEnumLocalQuorum::AddRef( void )
  612. {
  613. TraceFunc( "[IUnknown]" );
  614. InterlockedIncrement( &m_cRef );
  615. CRETURN( m_cRef );
  616. } //*** CEnumLocalQuorum::AddRef
  617. //////////////////////////////////////////////////////////////////////////////
  618. //++
  619. //
  620. // CEnumLocalQuorum::Release
  621. //
  622. // Description:
  623. // Decrement the reference count of this object by one.
  624. //
  625. // Arguments:
  626. // None.
  627. //
  628. // Return Value:
  629. // The new reference count.
  630. //
  631. // Remarks:
  632. // None.
  633. //
  634. //--
  635. //////////////////////////////////////////////////////////////////////////////
  636. STDMETHODIMP_( ULONG )
  637. CEnumLocalQuorum::Release( void )
  638. {
  639. TraceFunc( "[IUnknown]" );
  640. LONG cRef;
  641. cRef = InterlockedDecrement( &m_cRef );
  642. if ( cRef == 0 )
  643. {
  644. TraceDo( delete this );
  645. } // if: reference count equal to zero
  646. CRETURN( cRef );
  647. } //*** CEnumLocalQuorum::Release
  648. //////////////////////////////////////////////////////////////////////////////
  649. //++
  650. //
  651. // CEnumLocalQuorum::QueryInterface
  652. //
  653. // Description:
  654. // Query this object for the passed in interface.
  655. //
  656. // Arguments:
  657. // riidIn
  658. // Id of interface requested.
  659. //
  660. // ppvOut
  661. // Pointer to the requested interface.
  662. //
  663. // Return Value:
  664. // S_OK
  665. // If the interface is available on this object.
  666. //
  667. // E_NOINTERFACE
  668. // If the interface is not available.
  669. //
  670. // E_POINTER
  671. // ppvOut was NULL.
  672. //
  673. // Remarks:
  674. // None.
  675. //
  676. //--
  677. //////////////////////////////////////////////////////////////////////////////
  678. STDMETHODIMP
  679. CEnumLocalQuorum::QueryInterface(
  680. REFIID riidIn
  681. , void ** ppvOut
  682. )
  683. {
  684. TraceQIFunc( riidIn, ppvOut );
  685. HRESULT hr = S_OK;
  686. //
  687. // Validate arguments.
  688. //
  689. Assert( ppvOut != NULL );
  690. if ( ppvOut == NULL )
  691. {
  692. hr = THR( E_POINTER );
  693. goto Cleanup;
  694. }
  695. //
  696. // Handle known interfaces.
  697. //
  698. if ( IsEqualIID( riidIn, IID_IUnknown ) )
  699. {
  700. *ppvOut = static_cast< IEnumClusCfgManagedResources * >( this );
  701. } // if: IUnknown
  702. else if ( IsEqualIID( riidIn, IID_IEnumClusCfgManagedResources ) )
  703. {
  704. *ppvOut = TraceInterface( __THISCLASS__, IEnumClusCfgManagedResources, this, 0 );
  705. } // else if: IEnumClusCfgManagedResources
  706. else if ( IsEqualIID( riidIn, IID_IClusCfgInitialize ) )
  707. {
  708. *ppvOut = TraceInterface( __THISCLASS__, IClusCfgInitialize, this, 0 );
  709. } // else if: IClusCfgInitialize
  710. else
  711. {
  712. *ppvOut = NULL;
  713. hr = E_NOINTERFACE;
  714. }
  715. //
  716. // Add a reference to the interface if successful.
  717. //
  718. if ( SUCCEEDED( hr ) )
  719. {
  720. ((IUnknown *) *ppvOut)->AddRef();
  721. } // if: success
  722. Cleanup:
  723. QIRETURN_IGNORESTDMARSHALLING1( hr, riidIn, IID_IClusCfgWbemServices );
  724. } //*** CEnumLocalQuorum::QueryInterface
  725. //*************************************************************************//
  726. /////////////////////////////////////////////////////////////////////////////
  727. // CEnumLocalQuorum -- IClusCfgInitialize interface.
  728. /////////////////////////////////////////////////////////////////////////////
  729. //////////////////////////////////////////////////////////////////////////////
  730. //++
  731. //
  732. // CEnumLocalQuorum::Initialize
  733. //
  734. // Description:
  735. // Initialize this component.
  736. //
  737. // Arguments:
  738. // punkCallbackIn
  739. // lcidIn
  740. //
  741. // Return Value:
  742. // S_OK - Success.
  743. // E_INVALIDARG - Required input argument not specified.
  744. // Other HRESULTs.
  745. //
  746. //--
  747. //////////////////////////////////////////////////////////////////////////////
  748. STDMETHODIMP
  749. CEnumLocalQuorum::Initialize(
  750. IUnknown * punkCallbackIn
  751. , LCID lcidIn
  752. )
  753. {
  754. TraceFunc( "[IClusCfgInitialize]" );
  755. Assert( m_picccCallback == NULL );
  756. HRESULT hr = S_OK;
  757. m_lcid = lcidIn;
  758. if ( punkCallbackIn == NULL )
  759. {
  760. hr = THR( E_INVALIDARG );
  761. goto Cleanup;
  762. } // if:
  763. hr = THR( punkCallbackIn->TypeSafeQI( IClusCfgCallback, &m_picccCallback ) );
  764. if ( FAILED( hr ) )
  765. {
  766. goto Cleanup;
  767. } // if:
  768. hr = THR( HrGetComputerName(
  769. ComputerNameDnsHostname
  770. , &m_bstrNodeName
  771. , TRUE // fBestEffortIn
  772. ) );
  773. if ( FAILED( hr ) )
  774. {
  775. goto Cleanup;
  776. } // if:
  777. Cleanup:
  778. HRETURN( hr );
  779. } //*** CEnumLocalQuorum::Initialize
  780. //*************************************************************************//
  781. /////////////////////////////////////////////////////////////////////////////
  782. // CEnumLocalQuorum -- IEnumClusCfgManagedResources interface.
  783. /////////////////////////////////////////////////////////////////////////////
  784. //////////////////////////////////////////////////////////////////////////////
  785. //++
  786. //
  787. // CEnumLocalQuorum::Next
  788. //
  789. // Description:
  790. //
  791. // Arguments:
  792. //
  793. // Return Value:
  794. //
  795. // Remarks:
  796. // None.
  797. //
  798. //--
  799. //////////////////////////////////////////////////////////////////////////////
  800. STDMETHODIMP
  801. CEnumLocalQuorum::Next(
  802. ULONG cNumberRequestedIn,
  803. IClusCfgManagedResourceInfo ** rgpManagedResourceInfoOut,
  804. ULONG * pcNumberFetchedOut
  805. )
  806. {
  807. TraceFunc( "[IEnumClusCfgManagedResources]" );
  808. HRESULT hr = S_FALSE;
  809. ULONG cFetched = 0;
  810. IClusCfgManagedResourceInfo * pccsdi;
  811. IUnknown * punk;
  812. ULONG ulStop;
  813. if ( rgpManagedResourceInfoOut == NULL )
  814. {
  815. hr = THR( E_POINTER );
  816. STATUS_REPORT_REF( TASKID_Major_Find_Devices, TASKID_Minor_Next_Enum_LocalQuorum, IDS_ERROR_NULL_POINTER, IDS_ERROR_NULL_POINTER_REF, hr );
  817. goto Cleanup;
  818. } // if:
  819. if ( !m_fEnumLoaded )
  820. {
  821. hr = STHR( HrLoadResources() );
  822. if ( FAILED( hr ) )
  823. {
  824. goto Cleanup;
  825. } // if:
  826. m_fEnumLoaded = true;
  827. } // if:
  828. ulStop = min( cNumberRequestedIn, ( m_idxNext - m_idxEnumNext ) );
  829. for ( hr = S_OK; ( cFetched < ulStop ) && ( m_idxEnumNext < m_idxNext ); m_idxEnumNext++ )
  830. {
  831. punk = (*m_prgQuorums)[ m_idxEnumNext ];
  832. if ( punk != NULL )
  833. {
  834. hr = THR( punk->TypeSafeQI( IClusCfgManagedResourceInfo, &pccsdi ) );
  835. if ( FAILED( hr ) )
  836. {
  837. break;
  838. } // if:
  839. rgpManagedResourceInfoOut[ cFetched++ ] = pccsdi;
  840. } // if:
  841. } // for:
  842. if ( FAILED( hr ) )
  843. {
  844. m_idxEnumNext -= cFetched;
  845. while ( cFetched != 0 )
  846. {
  847. (rgpManagedResourceInfoOut[ --cFetched ])->Release();
  848. } // for:
  849. goto Cleanup;
  850. } // if:
  851. if ( cFetched < cNumberRequestedIn )
  852. {
  853. hr = S_FALSE;
  854. } // if:
  855. Cleanup:
  856. if ( pcNumberFetchedOut != NULL )
  857. {
  858. *pcNumberFetchedOut = cFetched;
  859. } // if:
  860. HRETURN( hr );
  861. } //*** CEnumLocalQuorum::Next
  862. //////////////////////////////////////////////////////////////////////////////
  863. //++
  864. //
  865. // CEnumLocalQuorum::Skip
  866. //
  867. // Description:
  868. //
  869. // Arguments:
  870. //
  871. // Return Value:
  872. //
  873. // Remarks:
  874. // None.
  875. //
  876. //--
  877. //////////////////////////////////////////////////////////////////////////////
  878. STDMETHODIMP
  879. CEnumLocalQuorum::Skip( ULONG cNumberToSkipIn )
  880. {
  881. TraceFunc( "[IEnumClusCfgManagedResources]" );
  882. HRESULT hr = S_OK;
  883. m_idxEnumNext += cNumberToSkipIn;
  884. if ( m_idxEnumNext >= m_idxNext )
  885. {
  886. m_idxEnumNext = m_idxNext;
  887. hr = STHR( S_FALSE );
  888. } // if:
  889. HRETURN( hr );
  890. } //*** CEnumLocalQuorum::Skip
  891. //////////////////////////////////////////////////////////////////////////////
  892. //++
  893. //
  894. // CEnumLocalQuorum::Reset
  895. //
  896. // Description:
  897. //
  898. // Arguments:
  899. //
  900. // Return Value:
  901. //
  902. // Remarks:
  903. // None.
  904. //
  905. //--
  906. //////////////////////////////////////////////////////////////////////////////
  907. STDMETHODIMP
  908. CEnumLocalQuorum::Reset( void )
  909. {
  910. TraceFunc( "[IEnumClusCfgManagedResources]" );
  911. m_idxEnumNext = 0;
  912. HRETURN( S_OK );
  913. } //*** CEnumLocalQuorum::Reset
  914. //////////////////////////////////////////////////////////////////////////////
  915. //++
  916. //
  917. // CEnumLocalQuorum::Clone
  918. //
  919. // Description:
  920. //
  921. // Arguments:
  922. //
  923. // Return Value:
  924. //
  925. // Remarks:
  926. // None.
  927. //
  928. //--
  929. //////////////////////////////////////////////////////////////////////////////
  930. STDMETHODIMP
  931. CEnumLocalQuorum::Clone(
  932. IEnumClusCfgManagedResources ** ppEnumClusCfgStorageDevicesOut
  933. )
  934. {
  935. TraceFunc( "[IEnumClusCfgManagedResources]" );
  936. HRESULT hr = S_OK;
  937. if ( ppEnumClusCfgStorageDevicesOut == NULL )
  938. {
  939. hr = THR( E_POINTER );
  940. STATUS_REPORT_REF( TASKID_Major_Find_Devices, TASKID_Minor_Clone_Enum_LocalQuorum, IDS_ERROR_NULL_POINTER, IDS_ERROR_NULL_POINTER_REF, hr );
  941. goto Cleanup;
  942. } // if:
  943. hr = THR( E_NOTIMPL );
  944. Cleanup:
  945. HRETURN( hr );
  946. } //*** CEnumLocalQuorum::Clone
  947. //////////////////////////////////////////////////////////////////////////////
  948. //++
  949. //
  950. // CEnumLocalQuorum::Count
  951. //
  952. // Description:
  953. //
  954. // Arguments:
  955. //
  956. // Return Value:
  957. //
  958. // Remarks:
  959. // None.
  960. //
  961. //--
  962. //////////////////////////////////////////////////////////////////////////////
  963. STDMETHODIMP
  964. CEnumLocalQuorum::Count( DWORD * pnCountOut )
  965. {
  966. TraceFunc( "[IEnumClusCfgManagedResources]" );
  967. HRESULT hr = S_OK;
  968. if ( pnCountOut == NULL )
  969. {
  970. hr = THR( E_POINTER );
  971. goto Cleanup;
  972. } // if:
  973. if ( !m_fEnumLoaded )
  974. {
  975. hr = STHR( HrLoadResources() );
  976. if ( FAILED( hr ) )
  977. {
  978. goto Cleanup;
  979. } // if:
  980. m_fEnumLoaded = true;
  981. } // if:
  982. *pnCountOut = m_cQuorumCount;
  983. Cleanup:
  984. HRETURN( hr );
  985. } //*** CEnumLocalQuorum::Count