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.

1693 lines
46 KiB

  1. /////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1997-2002 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // Cluster.cpp
  7. //
  8. // Description:
  9. // Implementation of the cluster and application classes and other
  10. // support classes for the MSCLUS automation classes.
  11. //
  12. // Author:
  13. // Charles Stacy Harris (stacyh) 28-Feb-1997
  14. // Galen Barbee (galenb) July 1998
  15. //
  16. // Revision History:
  17. // July 1998 GalenB Maaaaaajjjjjjjjjoooooorrrr clean up
  18. //
  19. // Notes:
  20. //
  21. /////////////////////////////////////////////////////////////////////////////
  22. #include "stdafx.h"
  23. #include "ClusterObject.h"
  24. #include "property.h"
  25. #include "ClusRes.h"
  26. #include "ClusNeti.h"
  27. #include "ClusResg.h"
  28. #include "ClusRest.h"
  29. #include "ClusNode.h"
  30. #include "ClusNetw.h"
  31. #include "ClusApp.h"
  32. #include "version.h"
  33. #include "cluster.h"
  34. /////////////////////////////////////////////////////////////////////////////
  35. // Global variables
  36. /////////////////////////////////////////////////////////////////////////////
  37. static const IID * iidCClusRefObject[] =
  38. {
  39. &IID_ISClusRefObject
  40. };
  41. static const IID * iidCCluster[] =
  42. {
  43. &IID_ISCluster
  44. };
  45. //*************************************************************************//
  46. /////////////////////////////////////////////////////////////////////////////
  47. // CClusRefObject class
  48. /////////////////////////////////////////////////////////////////////////////
  49. /////////////////////////////////////////////////////////////////////////////
  50. //++
  51. //
  52. // CClusRefObject::CClusRefObject
  53. //
  54. // Description:
  55. // Constructor.
  56. //
  57. // Arguments:
  58. // None.
  59. //
  60. // Return Value:
  61. // None.
  62. //
  63. //--
  64. /////////////////////////////////////////////////////////////////////////////
  65. CClusRefObject::CClusRefObject( void )
  66. {
  67. m_hCluster = NULL;
  68. m_piids = (const IID *) iidCClusRefObject;
  69. m_piidsSize = ARRAYSIZE( iidCClusRefObject );
  70. } //*** CClusRefObject::CClusRefObject( void )
  71. /////////////////////////////////////////////////////////////////////////////
  72. //++
  73. //
  74. // CClusRefObject::~CClusRefObject
  75. //
  76. // Description:
  77. // Destructor.
  78. //
  79. // Arguments:
  80. // None.
  81. //
  82. // Return Value:
  83. // None.
  84. //
  85. //--
  86. /////////////////////////////////////////////////////////////////////////////
  87. CClusRefObject::~CClusRefObject( void )
  88. {
  89. if ( m_hCluster != NULL )
  90. {
  91. ::CloseCluster( m_hCluster );
  92. m_hCluster = NULL;
  93. }
  94. } //*** CClusRefObject::~CClusRefObject()
  95. /////////////////////////////////////////////////////////////////////////////
  96. //++
  97. //
  98. // CCluster::ClusRefObject
  99. //
  100. // Description:
  101. // Copy constructor -- sort of.
  102. //
  103. // Arguments:
  104. // pClusRefObject [IN] - Cluster handle wrapper to hold copy.
  105. //
  106. // Return Value:
  107. // None.
  108. //
  109. //--
  110. /////////////////////////////////////////////////////////////////////////////
  111. void CCluster::ClusRefObject( IN ISClusRefObject * pClusRefObject )
  112. {
  113. ASSERT( pClusRefObject != NULL );
  114. if ( pClusRefObject != NULL )
  115. {
  116. if ( m_pClusRefObject != NULL )
  117. {
  118. m_pClusRefObject->Release();
  119. m_pClusRefObject = NULL;
  120. } // if:
  121. m_pClusRefObject = pClusRefObject;
  122. m_pClusRefObject->AddRef();
  123. } // if: args are not NULL
  124. } //*** CCluster::ClusRefObject( pClusRefObject )
  125. /////////////////////////////////////////////////////////////////////////////
  126. //++
  127. //
  128. // CCluster::Hcluster
  129. //
  130. // Description:
  131. // Changes the raw cluster handle that this class holds onto.
  132. //
  133. // Arguments:
  134. // hCluster [IN] - The new cluster handle.
  135. //
  136. // Return Value:
  137. // None.
  138. //
  139. //--
  140. /////////////////////////////////////////////////////////////////////////////
  141. void CCluster::Hcluster( IN HCLUSTER hCluster )
  142. {
  143. ASSERT( hCluster != NULL );
  144. if ( hCluster != NULL )
  145. {
  146. if ( m_hCluster != NULL )
  147. {
  148. ::CloseCluster( m_hCluster );
  149. m_hCluster = NULL;
  150. } // if:
  151. m_hCluster = hCluster;
  152. } // if:
  153. } //*** CCluster::Hcluster()
  154. /////////////////////////////////////////////////////////////////////////////
  155. //++
  156. //
  157. // CClusRefObject::get_Handle
  158. //
  159. // Description:
  160. // Returns the raw cluster handle.
  161. //
  162. // Arguments:
  163. // phandle [OUT] - Catches the cluster handle.
  164. //
  165. // Return Value:
  166. // S_OK if successful, or E_POINTER.
  167. //
  168. //--
  169. /////////////////////////////////////////////////////////////////////////////
  170. STDMETHODIMP CClusRefObject::get_Handle( OUT ULONG_PTR * phandle )
  171. {
  172. //ASSERT( phandle != NULL );
  173. HRESULT _hr = E_POINTER;
  174. if ( phandle != NULL )
  175. {
  176. _hr = E_HANDLE;
  177. if ( m_hCluster != NULL )
  178. {
  179. *phandle = (ULONG_PTR) m_hCluster;
  180. _hr = S_OK;
  181. } // if: cluster handle is not NULL
  182. } // if: args are not NULL
  183. return _hr;
  184. } //*** CClusRefObject::get_Handle()
  185. //*************************************************************************//
  186. /////////////////////////////////////////////////////////////////////////////
  187. // CCluster class
  188. /////////////////////////////////////////////////////////////////////////////
  189. /////////////////////////////////////////////////////////////////////////////
  190. //++
  191. //
  192. // CCluster::CCluster
  193. //
  194. // Description:
  195. // Constructor.
  196. //
  197. // Arguments:
  198. // None.
  199. //
  200. // Return Value:
  201. // None.
  202. //
  203. //--
  204. /////////////////////////////////////////////////////////////////////////////
  205. CCluster::CCluster( void )
  206. {
  207. // Initializing all data members.
  208. m_hCluster = NULL;
  209. m_pClusterNodes = NULL;
  210. m_pClusterResourceGroups = NULL;
  211. m_pClusterResources = NULL;
  212. m_pResourceTypes = NULL;
  213. m_pNetworks = NULL;
  214. m_pNetInterfaces = NULL;
  215. m_pClusRefObject = NULL;
  216. m_nQuorumLogSize = -1;
  217. m_pCommonProperties = NULL;
  218. m_pPrivateProperties = NULL;
  219. m_pCommonROProperties = NULL;
  220. m_pPrivateROProperties = NULL;
  221. m_pParentApplication = NULL;
  222. m_piids = (const IID *) iidCCluster;
  223. m_piidsSize = ARRAYSIZE( iidCCluster );
  224. } //*** CCluster::CCluster()
  225. /////////////////////////////////////////////////////////////////////////////
  226. //++
  227. //
  228. // CCluster::~CCluster
  229. //
  230. // Description:
  231. // Destructor.
  232. //
  233. // Arguments:
  234. // None.
  235. //
  236. // Return Value:
  237. // None.
  238. //
  239. //--
  240. /////////////////////////////////////////////////////////////////////////////
  241. CCluster::~CCluster( void )
  242. {
  243. Clear();
  244. } //*** CCluster::~CCluster()
  245. /////////////////////////////////////////////////////////////////////////////
  246. //++
  247. //
  248. // CCluster::Clear
  249. //
  250. // Description:
  251. // Clean out all of the collections we are hanging onto.
  252. //
  253. // Arguments:
  254. // None.
  255. //
  256. // Return Value:
  257. // None.
  258. //
  259. //--
  260. /////////////////////////////////////////////////////////////////////////////
  261. void CCluster::Clear( void )
  262. {
  263. if ( m_pParentApplication != NULL )
  264. {
  265. m_pParentApplication->Release();
  266. m_pParentApplication = NULL;
  267. }
  268. if ( m_pClusterNodes != NULL )
  269. {
  270. m_pClusterNodes->Release();
  271. m_pClusterNodes = NULL;
  272. }
  273. if ( m_pClusterResourceGroups != NULL )
  274. {
  275. m_pClusterResourceGroups->Release();
  276. m_pClusterResourceGroups = NULL;
  277. }
  278. if ( m_pClusterResources != NULL )
  279. {
  280. m_pClusterResources->Release();
  281. m_pClusterResources = NULL;
  282. }
  283. if ( m_pResourceTypes != NULL )
  284. {
  285. m_pResourceTypes->Release();
  286. m_pResourceTypes = NULL;
  287. }
  288. if ( m_pNetworks != NULL )
  289. {
  290. m_pNetworks->Release();
  291. m_pNetworks = NULL;
  292. }
  293. if ( m_pNetInterfaces != NULL )
  294. {
  295. m_pNetInterfaces->Release();
  296. m_pNetInterfaces = NULL;
  297. }
  298. if ( m_pCommonProperties != NULL )
  299. {
  300. m_pCommonProperties->Release();
  301. m_pCommonProperties = NULL;
  302. } // if: release the property collection
  303. if ( m_pPrivateProperties != NULL )
  304. {
  305. m_pPrivateProperties->Release();
  306. m_pPrivateProperties = NULL;
  307. } // if: release the property collection
  308. if ( m_pCommonROProperties != NULL )
  309. {
  310. m_pCommonROProperties->Release();
  311. m_pCommonROProperties = NULL;
  312. } // if: release the property collection
  313. if ( m_pPrivateROProperties != NULL )
  314. {
  315. m_pPrivateROProperties->Release();
  316. m_pPrivateROProperties = NULL;
  317. } // if: release the property collection
  318. if ( m_pClusRefObject != NULL )
  319. {
  320. m_pClusRefObject->Release();
  321. m_pClusRefObject = NULL;
  322. }
  323. m_hCluster = NULL;
  324. } //*** CCluster::Clear()
  325. /////////////////////////////////////////////////////////////////////////////
  326. //++
  327. //
  328. // CCluster::Create
  329. //
  330. // Description:
  331. // Complete heavy weight construction.
  332. //
  333. // Arguments:
  334. // pParentApplication [IN] - The parent ClusApplication object.
  335. //
  336. // Return Value:
  337. // S_OK if successful, E_POINTER, or other HRESULT error.
  338. //
  339. //--
  340. /////////////////////////////////////////////////////////////////////////////
  341. STDMETHODIMP CCluster::Create( IN CClusApplication * pParentApplication )
  342. {
  343. //ASSERT( pParentApplication != NULL );
  344. HRESULT _hr = E_POINTER;
  345. if ( pParentApplication != NULL )
  346. {
  347. _hr = pParentApplication->_InternalQueryInterface( IID_ISClusApplication, (void **) &m_pParentApplication );
  348. } // if: args are not NULL
  349. return _hr;
  350. } //*** CCluster::Create()
  351. /////////////////////////////////////////////////////////////////////////////
  352. //++
  353. //
  354. // CCluster::Open
  355. //
  356. // Description:
  357. // Open the cluster whose name is in bstrClusterName.
  358. //
  359. // Arguments:
  360. // bstrCluserName [IN] - Cluster name.
  361. //
  362. // Return Value:
  363. // S_OK if successful, or E_POINTER if the cluster is already open.
  364. // Win32 errors passed back as HRESULT.
  365. //
  366. //--
  367. /////////////////////////////////////////////////////////////////////////////
  368. STDMETHODIMP CCluster::Open( IN BSTR bstrClusterName )
  369. {
  370. //ASSERT( bstrClusterName != NULL );
  371. //ASSERT( m_hCluster == NULL );
  372. HRESULT _hr = E_POINTER;
  373. if ( bstrClusterName != NULL )
  374. {
  375. _hr = E_HANDLE;
  376. if ( m_hCluster == NULL )
  377. {
  378. _hr = S_OK;
  379. m_hCluster = ::OpenCluster( bstrClusterName );
  380. if ( m_hCluster == NULL )
  381. {
  382. DWORD _sc = GetLastError();
  383. _hr = HRESULT_FROM_WIN32( _sc );
  384. } // if: was the cluster opened?
  385. else
  386. {
  387. CComObject< CClusRefObject > * pCClusRefObject = NULL;
  388. _hr = CComObject< CClusRefObject >::CreateInstance( &pCClusRefObject );
  389. if ( SUCCEEDED( _hr ) )
  390. {
  391. CSmartPtr< CComObject< CClusRefObject > > ptrRefObject( pCClusRefObject );
  392. ptrRefObject->SetClusHandle( m_hCluster );
  393. _hr = pCClusRefObject->QueryInterface( IID_ISClusRefObject, (void **) &m_pClusRefObject );
  394. } // if: CreateInstance OK.
  395. } // else: the cluster was opened
  396. } // if: is there already a cluster open?
  397. } // if: bstrClusterName != NULL
  398. return _hr;
  399. } //*** CCluster::Open()
  400. /////////////////////////////////////////////////////////////////////////////
  401. //++
  402. //
  403. // CCluster::get_Handle
  404. //
  405. // Description:
  406. // Return the cluster handle.
  407. //
  408. // Arguments:
  409. // phandle [OUT] - Catches the cluster handle.
  410. //
  411. // Return Value:
  412. // S_OK if successful, or E_POINTER if not.
  413. //
  414. //--
  415. /////////////////////////////////////////////////////////////////////////////
  416. STDMETHODIMP CCluster::get_Handle( OUT ULONG_PTR * phandle )
  417. {
  418. //ASSERT( phandle != NULL );
  419. HRESULT _hr = E_POINTER;
  420. if ( phandle != NULL )
  421. {
  422. _hr = E_HANDLE;
  423. if ( m_hCluster != NULL )
  424. {
  425. *phandle = (ULONG_PTR) m_hCluster;
  426. _hr = S_OK;
  427. } // if: cluster handle is not NULL
  428. } // if: args are not NULL
  429. return _hr;
  430. } //*** CCluster::get_Handle()
  431. /////////////////////////////////////////////////////////////////////////////
  432. //++
  433. //
  434. // CCluster::Close
  435. //
  436. // Description:
  437. // Close the cluster.
  438. //
  439. // Arguments:
  440. // None.
  441. //
  442. // Return Value:
  443. // S_OK.
  444. //
  445. //--
  446. /////////////////////////////////////////////////////////////////////////////
  447. STDMETHODIMP CCluster::Close( void )
  448. {
  449. if ( m_hCluster != NULL )
  450. {
  451. //
  452. // If the Cluster Handle will be closed only when the
  453. // reference count on the RefObj becomes 0. But the
  454. // Cluster Object will be initialized and is reusable.
  455. //
  456. Clear();
  457. }
  458. return S_OK;
  459. } //*** CCluster::Close()
  460. /////////////////////////////////////////////////////////////////////////////
  461. //++
  462. //
  463. // CCluster::put_Name
  464. //
  465. // Description:
  466. // Change the name of this object (Cluster).
  467. //
  468. // Arguments:
  469. // bstrClusterName [IN] - The new name.
  470. //
  471. // Return Value:
  472. // S_OK if successful, E_POINTER, or other Win32 error as HRESULT.
  473. //
  474. //--
  475. /////////////////////////////////////////////////////////////////////////////
  476. STDMETHODIMP CCluster::put_Name( IN BSTR bstrClusterName )
  477. {
  478. //ASSERT( bstrClusterName != NULL );
  479. //ASSERT( pvarStatusCode != NULL );
  480. //ASSERT( bstrClusterName[ 0 ] != '\0' );
  481. ASSERT( m_hCluster != NULL );
  482. HRESULT _hr = E_POINTER;
  483. if ( ( bstrClusterName != NULL ) && ( bstrClusterName[ 0 ] != '\0' ) )
  484. {
  485. _hr = E_HANDLE;
  486. if ( m_hCluster != NULL )
  487. {
  488. DWORD _sc = ::SetClusterName( m_hCluster, bstrClusterName );
  489. //
  490. // Convert status, it's not an error, into error success since we
  491. // don't want an exception to be thrown when the client is a scripting
  492. // client.
  493. //
  494. if ( _sc == ERROR_RESOURCE_PROPERTIES_STORED )
  495. {
  496. _sc = ERROR_SUCCESS;
  497. }
  498. _hr = HRESULT_FROM_WIN32( _sc );
  499. }
  500. } // if: args are not NULL and the new name is not empty
  501. return _hr;
  502. } //*** CCluster::put_Name()
  503. /////////////////////////////////////////////////////////////////////////////
  504. //++
  505. //
  506. // CCluster::get_Name
  507. //
  508. // Description:
  509. // Return the name of this object (Cluster).
  510. //
  511. // Arguments:
  512. // pbstrClusterName [OUT] - Catches the name of this object.
  513. //
  514. // Return Value:
  515. // S_OK if successful, E_POINTER, or other HRESULT error.
  516. //
  517. //--
  518. /////////////////////////////////////////////////////////////////////////////
  519. STDMETHODIMP CCluster::get_Name( OUT BSTR * pbstrClusterName )
  520. {
  521. //ASSERT( pbstrClusterName != NULL );
  522. HRESULT _hr = E_POINTER;
  523. if ( pbstrClusterName != NULL )
  524. {
  525. if ( m_hCluster != NULL )
  526. {
  527. CLUSTERVERSIONINFO clusinfo;
  528. LPWSTR pwszName = NULL;
  529. DWORD _sc;
  530. clusinfo.dwVersionInfoSize = sizeof( clusinfo );
  531. _sc = WrapGetClusterInformation( m_hCluster, &pwszName, &clusinfo );
  532. if ( _sc == ERROR_SUCCESS )
  533. {
  534. *pbstrClusterName = SysAllocString( pwszName );
  535. if ( *pbstrClusterName == NULL )
  536. {
  537. _hr = E_OUTOFMEMORY;
  538. }
  539. ::LocalFree( pwszName );
  540. pwszName = NULL;
  541. }
  542. _hr = HRESULT_FROM_WIN32( _sc );
  543. }
  544. }
  545. return _hr;
  546. } //*** CCluster::get_Name()
  547. /////////////////////////////////////////////////////////////////////////////
  548. //++
  549. //
  550. // CCluster::get_Version
  551. //
  552. // Description:
  553. // Return the version info for this cluster.
  554. //
  555. // Arguments:
  556. // ppClusVersion [OUT] - Catches the ClusVersion object.
  557. //
  558. // Return Value:
  559. // S_OK if successful, E_POINTER, or Win32 error as HRESULT.
  560. //
  561. //--
  562. /////////////////////////////////////////////////////////////////////////////
  563. STDMETHODIMP CCluster::get_Version( OUT ISClusVersion ** ppClusVersion )
  564. {
  565. //ASSERT( ppClusVersion != NULL );
  566. ASSERT( m_hCluster != NULL );
  567. HRESULT _hr = E_POINTER;
  568. if ( ppClusVersion != NULL )
  569. {
  570. _hr = E_HANDLE;
  571. if ( m_hCluster != NULL )
  572. {
  573. CComObject< CClusVersion > * pClusVersion = NULL;
  574. *ppClusVersion = NULL;
  575. _hr = CComObject< CClusVersion >::CreateInstance( &pClusVersion );
  576. if ( SUCCEEDED( _hr ) )
  577. {
  578. CSmartPtr< ISClusRefObject > ptrRefObject( m_pClusRefObject );
  579. CSmartPtr< CComObject< CClusVersion > > ptrClusVersion( pClusVersion );
  580. _hr = ptrClusVersion->Create( ptrRefObject );
  581. if ( SUCCEEDED( _hr ) )
  582. {
  583. _hr = ptrClusVersion->QueryInterface( IID_ISClusVersion, (void **) ppClusVersion );
  584. } // if: ClusVersion object created
  585. } // if: ClusVersion object allocated
  586. } // if: cluster handle is not NULL
  587. } // if: args are not NULL
  588. return _hr;
  589. } //*** CCluster::GetVersion()
  590. /////////////////////////////////////////////////////////////////////////////
  591. //++
  592. //
  593. // CCluster::put_QuorumResource
  594. //
  595. // Description:
  596. // Change the quorum resource.
  597. //
  598. // Arguments:
  599. // pResource [IN] - The new quorum resource.
  600. //
  601. // Return Value:
  602. // S_OK if successful, E_POINTER, or Win32 error as HRESULT.
  603. //
  604. //--
  605. /////////////////////////////////////////////////////////////////////////////
  606. STDMETHODIMP CCluster::put_QuorumResource( IN ISClusResource * pResource )
  607. {
  608. //ASSERT( pResource != NULL );
  609. HRESULT _hr = E_POINTER;
  610. if ( pResource != NULL )
  611. {
  612. _hr = E_HANDLE;
  613. if ( m_hCluster != NULL )
  614. {
  615. _hr = pResource->BecomeQuorumResource( m_bstrQuorumPath, m_nQuorumLogSize );
  616. } // if: the cluster handle is not NULL
  617. } // if: args are not NULL
  618. return _hr;
  619. } //*** CCluster::put_QuorumResource()
  620. /////////////////////////////////////////////////////////////////////////////
  621. //++
  622. //
  623. // CCluster::get_QuorumResource
  624. //
  625. // Description:
  626. // Returns the quorum resource.
  627. //
  628. // Arguments:
  629. // ppResource [IN] - Catches the quorum resource.
  630. //
  631. // Return Value:
  632. // S_OK if successful, E_POINTER, or Win32 error as HRESULT.
  633. //
  634. //--
  635. /////////////////////////////////////////////////////////////////////////////
  636. STDMETHODIMP CCluster::get_QuorumResource( ISClusResource ** ppResource )
  637. {
  638. //ASSERT( ppResource != NULL );
  639. HRESULT _hr = E_POINTER;
  640. if ( ppResource != NULL )
  641. {
  642. _hr = E_HANDLE;
  643. if ( m_hCluster != NULL )
  644. {
  645. LPWSTR lpszResourceName = NULL;
  646. LPWSTR lpszDeviceName = NULL;
  647. DWORD dwLogSize = 0;
  648. DWORD _sc;
  649. _sc = ::WrapGetClusterQuorumResource( m_hCluster, &lpszResourceName, &lpszDeviceName, &dwLogSize );
  650. if ( _sc == ERROR_SUCCESS )
  651. {
  652. BSTR bstr = NULL;
  653. bstr = SysAllocString( lpszResourceName );
  654. if ( bstr == NULL )
  655. {
  656. _hr = E_OUTOFMEMORY;
  657. }
  658. else
  659. {
  660. _hr = OpenResource( bstr, ppResource );
  661. if ( SUCCEEDED( _hr ) )
  662. {
  663. if ( lpszResourceName != NULL )
  664. {
  665. ::LocalFree( lpszResourceName );
  666. }
  667. if ( lpszDeviceName != NULL )
  668. {
  669. m_bstrQuorumPath = lpszDeviceName;
  670. ::LocalFree( lpszDeviceName );
  671. }
  672. m_nQuorumLogSize = dwLogSize;
  673. }
  674. SysFreeString( bstr );
  675. } // else:
  676. }
  677. else
  678. {
  679. _hr = HRESULT_FROM_WIN32( _sc );
  680. }
  681. }
  682. }
  683. return _hr;
  684. } //*** CCluster::get_QuorumResource()
  685. /////////////////////////////////////////////////////////////////////////////
  686. //++
  687. //
  688. // CCluster::HrGetQuorumInfo
  689. //
  690. // Description:
  691. // Retrieves the current quorum info and stores it in member vars.
  692. //
  693. // Arguments:
  694. // None.
  695. //
  696. // Return Value:
  697. // S_OK if successful, or Win32 error as HRESULT if not.
  698. //
  699. //--
  700. /////////////////////////////////////////////////////////////////////////////
  701. STDMETHODIMP CCluster::HrGetQuorumInfo( void )
  702. {
  703. LPWSTR lpszResourceName = NULL;
  704. LPWSTR lpszDeviceName = NULL;
  705. DWORD dwLogSize = 0;
  706. DWORD _sc = NO_ERROR;
  707. HRESULT _hr = E_HANDLE;
  708. if ( m_hCluster != NULL )
  709. {
  710. _sc = ::WrapGetClusterQuorumResource( m_hCluster, &lpszResourceName, &lpszDeviceName, &dwLogSize );
  711. _hr = HRESULT_FROM_WIN32( _sc );
  712. if ( SUCCEEDED( _hr ) )
  713. {
  714. if ( lpszResourceName != NULL )
  715. {
  716. m_bstrQuorumResourceName = lpszResourceName;
  717. ::LocalFree( lpszResourceName );
  718. }
  719. if ( lpszDeviceName != NULL )
  720. {
  721. m_bstrQuorumPath = lpszDeviceName;
  722. ::LocalFree( lpszDeviceName );
  723. }
  724. m_nQuorumLogSize = dwLogSize;
  725. } // if: WrapGetClusterQuorumResource() succeeded
  726. } // if: cluster handle is not NULL
  727. return _hr;
  728. } //*** CCluster::HrGetQuorumInfo()
  729. /////////////////////////////////////////////////////////////////////////////
  730. //++
  731. //
  732. // CCluster::get_QuorumLogSize
  733. //
  734. // Description:
  735. // Returns the current quorum log size.
  736. //
  737. // Arguments:
  738. // pnQuorumLogSize [OUT] - Catches the log file size.
  739. //
  740. // Return Value:
  741. // S_OK if successful, E_POINTER, or Win32 error as HRESULT if not.
  742. //
  743. //--
  744. /////////////////////////////////////////////////////////////////////////////
  745. STDMETHODIMP CCluster::get_QuorumLogSize( OUT long * pnQuorumLogSize )
  746. {
  747. //ASSERT( pnQuorumLogSize != NULL );
  748. HRESULT _hr = E_POINTER;
  749. if ( pnQuorumLogSize != NULL )
  750. {
  751. _hr = E_HANDLE;
  752. if ( m_hCluster != NULL )
  753. {
  754. _hr = HrGetQuorumInfo();
  755. if ( SUCCEEDED( _hr ) )
  756. {
  757. *pnQuorumLogSize = m_nQuorumLogSize;
  758. }
  759. }
  760. }
  761. return _hr;
  762. } //*** CCluster::get_QuorumLogSize()
  763. /////////////////////////////////////////////////////////////////////////////
  764. //++
  765. //
  766. // CCluster::put_QuorumLogSize
  767. //
  768. // Description:
  769. // Set the current quorum log size.
  770. //
  771. // Arguments:
  772. // nQuorumLogSize [IN] - The new log file size.
  773. //
  774. // Return Value:
  775. // S_OK if successful, E_POINTER, or Win32 error as HRESULT if not.
  776. //
  777. //--
  778. /////////////////////////////////////////////////////////////////////////////
  779. STDMETHODIMP CCluster::put_QuorumLogSize( IN long nQuoromLogSize )
  780. {
  781. //ASSERT( nQuoromLogSize > 0 );
  782. HRESULT _hr = E_INVALIDARG;
  783. if ( nQuoromLogSize > 0 )
  784. {
  785. _hr = E_HANDLE;
  786. if ( m_hCluster != NULL )
  787. {
  788. _hr = HrGetQuorumInfo();
  789. if ( SUCCEEDED( _hr ) )
  790. {
  791. DWORD _sc = NO_ERROR;
  792. HRESOURCE hResource = NULL;
  793. hResource = ::OpenClusterResource( m_hCluster, m_bstrQuorumResourceName );
  794. if ( hResource != NULL )
  795. {
  796. m_nQuorumLogSize = nQuoromLogSize;
  797. _sc = ::SetClusterQuorumResource( hResource, m_bstrQuorumPath, m_nQuorumLogSize );
  798. _hr = HRESULT_FROM_WIN32( _sc );
  799. ::CloseClusterResource( hResource );
  800. }
  801. else
  802. {
  803. _sc = GetLastError();
  804. _hr = HRESULT_FROM_WIN32( _sc );
  805. }
  806. }
  807. }
  808. }
  809. return _hr;
  810. } //*** CCluster::put_QuorumLogSize()
  811. /////////////////////////////////////////////////////////////////////////////
  812. //++
  813. //
  814. // CCluster::get_QuorumPath
  815. //
  816. // Description:
  817. // Returns the current quorum log path.
  818. //
  819. // Arguments:
  820. // ppPath [OUT] - Catches the device path.
  821. //
  822. // Return Value:
  823. // S_OK if successful, E_POINTER, or Win32 error as HRESULT if not.
  824. //
  825. //--
  826. /////////////////////////////////////////////////////////////////////////////
  827. STDMETHODIMP CCluster::get_QuorumPath( OUT BSTR * ppPath )
  828. {
  829. //ASSERT( ppPath != NULL );
  830. HRESULT _hr = E_POINTER;
  831. if ( ppPath != NULL )
  832. {
  833. _hr = E_HANDLE;
  834. if ( m_hCluster != NULL )
  835. {
  836. _hr = HrGetQuorumInfo();
  837. if ( SUCCEEDED( _hr ) )
  838. {
  839. *ppPath = m_bstrQuorumPath.Copy();
  840. }
  841. }
  842. }
  843. return _hr;
  844. } //*** CCluster::get_QuorumPath()
  845. /////////////////////////////////////////////////////////////////////////////
  846. //++
  847. //
  848. // CCluster::put_QuorumPath
  849. //
  850. // Description:
  851. // Change the current quorum log path.
  852. //
  853. // Arguments:
  854. // pPath [IN] - The new device path.
  855. //
  856. // Return Value:
  857. // S_OK if successful, E_POINTER, or Win32 error as HRESULT if not.
  858. //
  859. //--
  860. /////////////////////////////////////////////////////////////////////////////
  861. STDMETHODIMP CCluster::put_QuorumPath( IN BSTR pPath )
  862. {
  863. //ASSERT( pPath != NULL );
  864. HRESULT _hr = E_POINTER;
  865. if ( pPath != NULL )
  866. {
  867. _hr = E_HANDLE;
  868. if ( m_hCluster != NULL )
  869. {
  870. _hr = HrGetQuorumInfo();
  871. if ( SUCCEEDED( _hr ) )
  872. {
  873. DWORD _sc = NO_ERROR;
  874. HRESOURCE hResource = NULL;
  875. hResource = ::OpenClusterResource( m_hCluster, m_bstrQuorumResourceName );
  876. if ( hResource != NULL )
  877. {
  878. m_bstrQuorumPath = pPath;
  879. _sc = ::SetClusterQuorumResource( hResource, m_bstrQuorumPath, m_nQuorumLogSize );
  880. _hr = HRESULT_FROM_WIN32( _sc );
  881. ::CloseClusterResource( hResource );
  882. }
  883. else
  884. {
  885. _sc = GetLastError();
  886. _hr = HRESULT_FROM_WIN32( _sc );
  887. }
  888. }
  889. }
  890. }
  891. return _hr;
  892. } //*** CCluster::put_QuorumPath()
  893. /////////////////////////////////////////////////////////////////////////////
  894. //++
  895. //
  896. // CCluster::get_Nodes
  897. //
  898. // Description:
  899. // Returns the collection of nodes for this cluster.
  900. //
  901. // Arguments:
  902. // ppClusterNodes [OUT] - Catches the collection.
  903. //
  904. // Return Value:
  905. // S_OK if successful, E_POINTER, or Win32 error as HRESULT if not.
  906. //
  907. //--
  908. /////////////////////////////////////////////////////////////////////////////
  909. STDMETHODIMP CCluster::get_Nodes( OUT ISClusNodes ** ppClusterNodes )
  910. {
  911. return ::HrCreateResourceCollection< CClusNodes, ISClusNodes, HNODE >(
  912. ppClusterNodes,
  913. IID_ISClusNodes,
  914. m_pClusRefObject
  915. );
  916. } //*** CCluster::get_Nodes()
  917. /////////////////////////////////////////////////////////////////////////////
  918. //++
  919. //
  920. // CCluster::get_ResourceGroups
  921. //
  922. // Description:
  923. // Returns the collection of resource groups for this cluster.
  924. //
  925. // Arguments:
  926. // ppClusterResourceGroups [OUT] - Catches the collection.
  927. //
  928. // Return Value:
  929. // S_OK if successful, E_POINTER, or Win32 error as HRESULT if not.
  930. //
  931. //--
  932. /////////////////////////////////////////////////////////////////////////////
  933. STDMETHODIMP CCluster::get_ResourceGroups(
  934. OUT ISClusResGroups ** ppClusterResourceGroups
  935. )
  936. {
  937. return ::HrCreateResourceCollection< CClusResGroups, ISClusResGroups, HRESOURCE >(
  938. ppClusterResourceGroups,
  939. IID_ISClusResGroups,
  940. m_pClusRefObject
  941. );
  942. } //*** CCluster::get_ResourceGroups()
  943. /////////////////////////////////////////////////////////////////////////////
  944. //++
  945. //
  946. // CCluster::get_Resources
  947. //
  948. // Description:
  949. // Returns the collection of resources for this cluster.
  950. //
  951. // Arguments:
  952. // ppClusterResources [OUT] - Catches the collection.
  953. //
  954. // Return Value:
  955. // S_OK if successful, E_POINTER, or Win32 error as HRESULT if not.
  956. //
  957. //--
  958. /////////////////////////////////////////////////////////////////////////////
  959. STDMETHODIMP CCluster::get_Resources(
  960. OUT ISClusResources ** ppClusterResources
  961. )
  962. {
  963. return ::HrCreateResourceCollection< CClusResources, ISClusResources, HRESOURCE >(
  964. &m_pClusterResources,
  965. ppClusterResources,
  966. IID_ISClusResources,
  967. m_pClusRefObject
  968. );
  969. } //*** CCluster::get_Resources()
  970. /////////////////////////////////////////////////////////////////////////////
  971. //++
  972. //
  973. // CCluster::OpenResource
  974. //
  975. // Description:
  976. // Create and open a new resource.
  977. //
  978. // Arguments:
  979. // bstrResourceName [IN] - The name of the resource to open.
  980. // ppClusterResource [OUT] - Catches the new resource.
  981. //
  982. // Return Value:
  983. // S_OK if successful, E_POINTER, or Win32 error as HRESULT if not.
  984. //
  985. //--
  986. /////////////////////////////////////////////////////////////////////////////
  987. STDMETHODIMP CCluster::OpenResource(
  988. IN BSTR bstrResourceName,
  989. OUT ISClusResource ** ppClusterResource
  990. )
  991. {
  992. //ASSERT( bstrResourceName != NULL );
  993. //ASSERT( ppClusterResource != NULL );
  994. ASSERT( m_hCluster != NULL );
  995. HRESULT _hr = E_POINTER;
  996. if ( ( bstrResourceName != NULL ) && ( ppClusterResource != NULL ) )
  997. {
  998. _hr = E_HANDLE;
  999. if ( m_hCluster != NULL )
  1000. {
  1001. CComObject< CClusResource > * pClusterResource = NULL;
  1002. *ppClusterResource = NULL;
  1003. _hr = CComObject< CClusResource >::CreateInstance( &pClusterResource );
  1004. if ( SUCCEEDED( _hr ) )
  1005. {
  1006. CSmartPtr< ISClusRefObject > ptrRefObject( m_pClusRefObject );
  1007. CSmartPtr< CComObject< CClusResource > > ptrClusterResource( pClusterResource );
  1008. _hr = ptrClusterResource->Open( ptrRefObject, bstrResourceName );
  1009. if ( SUCCEEDED( _hr ) )
  1010. {
  1011. _hr = ptrClusterResource->QueryInterface( IID_ISClusResource, (void **) ppClusterResource );
  1012. }
  1013. }
  1014. }
  1015. }
  1016. return _hr;
  1017. } //*** CCluster::OpenResource()
  1018. /////////////////////////////////////////////////////////////////////////////
  1019. //++
  1020. //
  1021. // CCluster::get_ResourceTypes
  1022. //
  1023. // Description:
  1024. // Returns the collection of resource types for this cluster.
  1025. //
  1026. // Arguments:
  1027. // ppResourceTypes [OUT] - Catches the collection.
  1028. //
  1029. // Return Value:
  1030. // S_OK if successful, E_POINTER, or Win32 error as HRESULT if not.
  1031. //
  1032. //--
  1033. /////////////////////////////////////////////////////////////////////////////
  1034. STDMETHODIMP CCluster::get_ResourceTypes(
  1035. OUT ISClusResTypes ** ppResourceTypes
  1036. )
  1037. {
  1038. return ::HrCreateResourceCollection< CClusResTypes, ISClusResTypes, CComBSTR >(
  1039. &m_pResourceTypes,
  1040. ppResourceTypes,
  1041. IID_ISClusResTypes,
  1042. m_pClusRefObject
  1043. );
  1044. } //*** CCluster::get_ResourceTypes()
  1045. /////////////////////////////////////////////////////////////////////////////
  1046. //++
  1047. //
  1048. // CCluster::get_Networks
  1049. //
  1050. // Description:
  1051. // Returns the collection of networks for this cluster.
  1052. //
  1053. // Arguments:
  1054. // ppNetworks [OUT] - Catches the collection.
  1055. //
  1056. // Return Value:
  1057. // S_OK if successful, E_POINTER, or Win32 error as HRESULT if not.
  1058. //
  1059. //--
  1060. /////////////////////////////////////////////////////////////////////////////
  1061. STDMETHODIMP CCluster::get_Networks( OUT ISClusNetworks ** ppNetworks )
  1062. {
  1063. return ::HrCreateResourceCollection< CClusNetworks, ISClusNetworks, HNETWORK >(
  1064. &m_pNetworks,
  1065. ppNetworks,
  1066. IID_ISClusNetworks,
  1067. m_pClusRefObject
  1068. );
  1069. } //*** CCluster::get_Networks()
  1070. /////////////////////////////////////////////////////////////////////////////
  1071. //++
  1072. //
  1073. // CCluster::get_NetInterfaces
  1074. //
  1075. // Description:
  1076. // Returns the collection of netinterfaces for this cluster.
  1077. //
  1078. // Arguments:
  1079. // ppNetInterfaces [OUT] - Catches the collection.
  1080. //
  1081. // Return Value:
  1082. // S_OK if successful, E_POINTER, or Win32 error as HRESULT if not.
  1083. //
  1084. //--
  1085. /////////////////////////////////////////////////////////////////////////////
  1086. STDMETHODIMP CCluster::get_NetInterfaces(
  1087. OUT ISClusNetInterfaces ** ppNetInterfaces
  1088. )
  1089. {
  1090. return ::HrCreateResourceCollection< CClusNetInterfaces, ISClusNetInterfaces, HNETINTERFACE >(
  1091. &m_pNetInterfaces,
  1092. ppNetInterfaces,
  1093. IID_ISClusNetInterfaces,
  1094. m_pClusRefObject
  1095. );
  1096. } //*** CCluster::get_NetInterfaces()
  1097. /////////////////////////////////////////////////////////////////////////////
  1098. //++
  1099. //
  1100. // CCluster::GetProperties
  1101. //
  1102. // Description:
  1103. // Creates a property collection for this object type (Cluster).
  1104. //
  1105. // Arguments:
  1106. // ppProperties [OUT] - Catches the newly created collection.
  1107. // bPrivate [IN] - Are these private properties? Or Common?
  1108. // bReadOnly [IN] - Are these read only properties?
  1109. //
  1110. // Return Value:
  1111. // S_OK if successful, or other HRESULT error.
  1112. //
  1113. //--
  1114. /////////////////////////////////////////////////////////////////////////////
  1115. HRESULT CCluster::GetProperties(
  1116. ISClusProperties ** ppProperties,
  1117. BOOL bPrivate,
  1118. BOOL bReadOnly
  1119. )
  1120. {
  1121. //ASSERT( ppProperties != NULL );
  1122. HRESULT _hr = E_POINTER;
  1123. if ( ppProperties != NULL )
  1124. {
  1125. *ppProperties = NULL;
  1126. CComObject< CClusProperties > * pProperties = NULL;
  1127. _hr = CComObject< CClusProperties >::CreateInstance( &pProperties );
  1128. if ( SUCCEEDED( _hr ) )
  1129. {
  1130. CSmartPtr< CComObject< CClusProperties > > ptrProperties( pProperties );
  1131. _hr = ptrProperties->Create( this, bPrivate, bReadOnly );
  1132. if ( SUCCEEDED( _hr ) )
  1133. {
  1134. _hr = ptrProperties->Refresh();
  1135. if ( SUCCEEDED( _hr ) )
  1136. {
  1137. _hr = ptrProperties->QueryInterface( IID_ISClusProperties, (void **) ppProperties );
  1138. if ( SUCCEEDED( _hr ) )
  1139. {
  1140. ptrProperties->AddRef();
  1141. if ( bPrivate )
  1142. {
  1143. if ( bReadOnly )
  1144. {
  1145. m_pPrivateROProperties = pProperties;
  1146. }
  1147. else
  1148. {
  1149. m_pPrivateProperties = pProperties;
  1150. }
  1151. }
  1152. else
  1153. {
  1154. if ( bReadOnly )
  1155. {
  1156. m_pCommonROProperties = pProperties;
  1157. }
  1158. else
  1159. {
  1160. m_pCommonProperties = pProperties;
  1161. }
  1162. }
  1163. }
  1164. }
  1165. }
  1166. }
  1167. }
  1168. return _hr;
  1169. } //*** CCluster::GetProperties()
  1170. /////////////////////////////////////////////////////////////////////////////
  1171. //++
  1172. //
  1173. // CCluster::HrLoadProperties
  1174. //
  1175. // Description:
  1176. // This virtual function does the actual load of the property list from
  1177. // the cluster.
  1178. //
  1179. // Arguments:
  1180. // rcplPropList [IN OUT] - The property list to load.
  1181. // bReadOnly [IN] - Load the read only properties?
  1182. // bPrivate [IN] - Load the common or the private properties?
  1183. //
  1184. // Return Value:
  1185. // S_OK if successful, or other HRESULT error.
  1186. //
  1187. //--
  1188. /////////////////////////////////////////////////////////////////////////////
  1189. HRESULT CCluster::HrLoadProperties(
  1190. IN OUT CClusPropList & rcplPropList,
  1191. IN BOOL bReadOnly,
  1192. IN BOOL bPrivate
  1193. )
  1194. {
  1195. HRESULT _hr = E_INVALIDARG;
  1196. #if CLUSAPI_VERSION >= 0x0500
  1197. DWORD _dwControlCode = 0;
  1198. DWORD _sc = NO_ERROR;
  1199. _hr = E_HANDLE;
  1200. if ( m_hCluster != NULL )
  1201. {
  1202. if ( bReadOnly )
  1203. {
  1204. _dwControlCode = bPrivate
  1205. ? CLUSCTL_CLUSTER_GET_RO_PRIVATE_PROPERTIES
  1206. : CLUSCTL_CLUSTER_GET_RO_COMMON_PROPERTIES;
  1207. }
  1208. else
  1209. {
  1210. _dwControlCode = bPrivate
  1211. ? CLUSCTL_CLUSTER_GET_PRIVATE_PROPERTIES
  1212. : CLUSCTL_CLUSTER_GET_COMMON_PROPERTIES;
  1213. }
  1214. _sc = rcplPropList.ScGetClusterProperties( m_hCluster, _dwControlCode );
  1215. _hr = HRESULT_FROM_WIN32( _sc );
  1216. } // if: cluster handle is not NULL
  1217. #else
  1218. _hr = E_NOTIMPL;
  1219. #endif // CLUSAPI_VERSION >= 0x0500
  1220. return _hr;
  1221. } //*** CCluster::HrLoadProperties()
  1222. /////////////////////////////////////////////////////////////////////////////
  1223. //++
  1224. //
  1225. // CCluster::ScWriteProperties
  1226. //
  1227. // Description:
  1228. // This virtual function does the actual saving of the property list to
  1229. // the cluster.
  1230. //
  1231. // Arguments:
  1232. // rcplPropList [IN] - The property list to save.
  1233. // bPrivate [IN] - Save the common or the private properties?
  1234. //
  1235. // Return Value:
  1236. // ERROR_SUCCESS if successful, or other Win32 error if not.
  1237. //
  1238. //--
  1239. /////////////////////////////////////////////////////////////////////////////
  1240. DWORD CCluster::ScWriteProperties(
  1241. const CClusPropList & rcplPropList,
  1242. BOOL bPrivate
  1243. )
  1244. {
  1245. //ASSERT( bPrivate == FALSE );
  1246. DWORD _sc = ERROR_INVALID_HANDLE;
  1247. #if CLUSAPI_VERSION >= 0x0500
  1248. if ( m_hCluster != NULL )
  1249. {
  1250. DWORD nBytesReturned = 0;
  1251. DWORD _dwControlCode = bPrivate
  1252. ? CLUSCTL_CLUSTER_SET_PRIVATE_PROPERTIES
  1253. : CLUSCTL_CLUSTER_SET_COMMON_PROPERTIES;
  1254. _sc = ClusterControl(
  1255. m_hCluster,
  1256. NULL,
  1257. _dwControlCode,
  1258. rcplPropList,
  1259. rcplPropList.CbBufferSize(),
  1260. 0,
  1261. 0,
  1262. &nBytesReturned
  1263. );
  1264. } // if: cluster handle is not NULL
  1265. #else
  1266. _sc = ERROR_CALL_NOT_IMPLEMENTED;
  1267. #endif // CLUSAPI_VERSION >= 0x0500
  1268. return _sc;
  1269. } //*** CCluster::ScWriteProperties()
  1270. /////////////////////////////////////////////////////////////////////////////
  1271. //++
  1272. //
  1273. // CCluster::get_CommonProperties
  1274. //
  1275. // Description:
  1276. // Get this object's (Cluster) common properties collection.
  1277. //
  1278. // Arguments:
  1279. // ppProperties [OUT] - Catches the properties collection.
  1280. //
  1281. // Return Value:
  1282. // S_OK if successful, or other HRESULT error.
  1283. //
  1284. //--
  1285. /////////////////////////////////////////////////////////////////////////////
  1286. STDMETHODIMP CCluster::get_CommonProperties(
  1287. OUT ISClusProperties ** ppProperties
  1288. )
  1289. {
  1290. //ASSERT( ppProperties != NULL );
  1291. HRESULT _hr = E_POINTER;
  1292. if ( ppProperties != NULL )
  1293. {
  1294. if ( m_pCommonProperties != NULL )
  1295. {
  1296. _hr = m_pCommonProperties->QueryInterface( IID_ISClusProperties, (void **) ppProperties );
  1297. }
  1298. else
  1299. {
  1300. _hr = GetProperties( ppProperties, FALSE, FALSE );
  1301. }
  1302. }
  1303. return _hr;
  1304. } //*** CCluster::get_CommonProperties()
  1305. /////////////////////////////////////////////////////////////////////////////
  1306. //++
  1307. //
  1308. // CCluster::get_PrivateProperties
  1309. //
  1310. // Description:
  1311. // Get this object's (Cluster) private properties collection.
  1312. //
  1313. // Arguments:
  1314. // ppProperties [OUT] - Catches the properties collection.
  1315. //
  1316. // Return Value:
  1317. // S_OK if successful, or other HRESULT error.
  1318. //
  1319. //--
  1320. /////////////////////////////////////////////////////////////////////////////
  1321. STDMETHODIMP CCluster::get_PrivateProperties(
  1322. OUT ISClusProperties ** ppProperties
  1323. )
  1324. {
  1325. //ASSERT( ppProperties != NULL );
  1326. HRESULT _hr = E_POINTER;
  1327. if ( ppProperties != NULL )
  1328. {
  1329. if ( m_pPrivateProperties != NULL )
  1330. {
  1331. _hr = m_pPrivateProperties->QueryInterface( IID_ISClusProperties, (void **) ppProperties );
  1332. }
  1333. else
  1334. {
  1335. _hr = GetProperties( ppProperties, TRUE, FALSE );
  1336. }
  1337. }
  1338. return _hr;
  1339. } //*** CCluster::get_PrivateProperties()
  1340. /////////////////////////////////////////////////////////////////////////////
  1341. //++
  1342. //
  1343. // CCluster::get_CommonROProperties
  1344. //
  1345. // Description:
  1346. // Get this object's (Cluster) common read only properties collection.
  1347. //
  1348. // Arguments:
  1349. // ppProperties [OUT] - Catches the properties collection.
  1350. //
  1351. // Return Value:
  1352. // S_OK if successful, or other HRESULT error.
  1353. //
  1354. /////////////////////////////////////////////////////////////////////////////
  1355. STDMETHODIMP CCluster::get_CommonROProperties(
  1356. OUT ISClusProperties ** ppProperties
  1357. )
  1358. {
  1359. //ASSERT( ppProperties != NULL );
  1360. HRESULT _hr = E_POINTER;
  1361. if ( ppProperties != NULL )
  1362. {
  1363. if ( m_pCommonROProperties != NULL )
  1364. {
  1365. _hr = m_pCommonROProperties->QueryInterface( IID_ISClusProperties, (void **) ppProperties );
  1366. }
  1367. else
  1368. {
  1369. _hr = GetProperties( ppProperties, FALSE, TRUE );
  1370. }
  1371. }
  1372. return _hr;
  1373. } //*** CCluster::get_CommonROProperties()
  1374. /////////////////////////////////////////////////////////////////////////////
  1375. //++
  1376. //
  1377. // CCluster::get_PrivateROProperties
  1378. //
  1379. // Description:
  1380. // Get this object's (Cluster) private read only properties collection.
  1381. //
  1382. // Arguments:
  1383. // ppProperties [OUT] - Catches the properties collection.
  1384. //
  1385. // Return Value:
  1386. // S_OK if successful, or other HRESULT error.
  1387. //
  1388. //--
  1389. /////////////////////////////////////////////////////////////////////////////
  1390. STDMETHODIMP CCluster::get_PrivateROProperties(
  1391. OUT ISClusProperties ** ppProperties
  1392. )
  1393. {
  1394. //ASSERT( ppProperties != NULL );
  1395. HRESULT _hr = E_POINTER;
  1396. if ( ppProperties != NULL )
  1397. {
  1398. if ( m_pPrivateROProperties != NULL )
  1399. {
  1400. _hr = m_pPrivateROProperties->QueryInterface( IID_ISClusProperties, (void **) ppProperties );
  1401. }
  1402. else
  1403. {
  1404. _hr = GetProperties( ppProperties, TRUE, TRUE );
  1405. }
  1406. }
  1407. return _hr;
  1408. } //*** CCluster::get_PrivateROProperties()
  1409. /*
  1410. /////////////////////////////////////////////////////////////////////////////
  1411. //++
  1412. //
  1413. // CCluster::get_Parent
  1414. //
  1415. // Description:
  1416. // Returns the parent of the cluster object. This is an automation
  1417. // thing and the parent could be NULL.
  1418. //
  1419. // Arguments:
  1420. // ppParent [OUT] - Catches the parent.
  1421. //
  1422. // Return Value:
  1423. // S_OK if successful, or other HRESULT error.
  1424. //
  1425. //--
  1426. /////////////////////////////////////////////////////////////////////////////
  1427. STDMETHODIMP CCluster::get_Parent( OUT IDispatch ** ppParent )
  1428. {
  1429. //ASSERT( ppParent != NULL );
  1430. HRESULT _hr = E_POINTER;
  1431. if ( ppParent != NULL )
  1432. {
  1433. if ( m_pParentApplication != NULL )
  1434. {
  1435. _hr = m_pParentApplication->QueryInterface( IID_IDispatch, (void **) ppParent );
  1436. }
  1437. else
  1438. {
  1439. _hr = _InternalQueryInterface( IID_IDispatch, (void **) ppParent );
  1440. }
  1441. }
  1442. return _hr;
  1443. } //*** CCluster::get_Parent()
  1444. /////////////////////////////////////////////////////////////////////////////
  1445. //++
  1446. //
  1447. // CCluster::get_Application
  1448. //
  1449. // Description:
  1450. // Get the parent application for this cluster object. This is an
  1451. // automation thing and it could be NULL.
  1452. //
  1453. // Arguments:
  1454. // ppParentApplication [OUT] - Catches the parent app object.
  1455. //
  1456. // Return Value:
  1457. // S_OK if successful, or other HRESULT error.
  1458. //
  1459. //--
  1460. /////////////////////////////////////////////////////////////////////////////
  1461. STDMETHODIMP CCluster::get_Application(
  1462. OUT ISClusApplication ** ppParentApplication
  1463. )
  1464. {
  1465. //ASSERT( ppParentApplication != NULL );
  1466. HRESULT _hr = E_POINTER;
  1467. if ( ppParentApplication != NULL )
  1468. {
  1469. if ( m_pParentApplication != NULL )
  1470. {
  1471. _hr = m_pParentApplication->QueryInterface( IID_IDispatch, (void **) ppParentApplication );
  1472. }
  1473. }
  1474. return _hr;
  1475. } //*** CCluster::get_Application()
  1476. */