Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2045 lines
48 KiB

  1. /////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1997-1999 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // ClusResG.cpp
  7. //
  8. // Description:
  9. // Implementation of the resource group classes for the MSCLUS
  10. // 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 "clusresg.h"
  27. #include "clusneti.h"
  28. #include "clusnode.h"
  29. /////////////////////////////////////////////////////////////////////////////
  30. // Global variables
  31. /////////////////////////////////////////////////////////////////////////////
  32. static const IID * iidCClusResGroup[] =
  33. {
  34. &IID_ISClusResGroup
  35. };
  36. static const IID * iidCClusResGroups[] =
  37. {
  38. &IID_ISClusResGroups
  39. };
  40. //*************************************************************************//
  41. /////////////////////////////////////////////////////////////////////////////
  42. // CClusResGroup class
  43. /////////////////////////////////////////////////////////////////////////////
  44. /////////////////////////////////////////////////////////////////////////////
  45. //++
  46. //
  47. // CClusResGroup::CClusResGroup
  48. //
  49. // Description:
  50. // Constructor.
  51. //
  52. // Arguments:
  53. // None.
  54. //
  55. // Return Value:
  56. // None.
  57. //
  58. //--
  59. /////////////////////////////////////////////////////////////////////////////
  60. CClusResGroup::CClusResGroup( void )
  61. {
  62. m_hGroup = NULL;
  63. m_pClusRefObject = NULL;
  64. m_pClusterResources = NULL;
  65. m_pPreferredOwnerNodes = NULL;
  66. m_pCommonProperties = NULL;
  67. m_pPrivateProperties = NULL;
  68. m_pCommonROProperties = NULL;
  69. m_pPrivateROProperties = NULL;
  70. m_piids = (const IID *) iidCClusResGroup;
  71. m_piidsSize = ARRAYSIZE( iidCClusResGroup );
  72. } //*** CClusResGroup::CClusResGroup()
  73. /////////////////////////////////////////////////////////////////////////////
  74. //++
  75. //
  76. // CClusResGroup::~CClusResGroup
  77. //
  78. // Description:
  79. // Destructor.
  80. //
  81. // Arguments:
  82. // None.
  83. //
  84. // Return Value:
  85. // None.
  86. //
  87. //--
  88. /////////////////////////////////////////////////////////////////////////////
  89. CClusResGroup::~CClusResGroup( void )
  90. {
  91. if ( m_hGroup != NULL )
  92. {
  93. CloseClusterGroup( m_hGroup );
  94. m_hGroup = 0;
  95. }
  96. if ( m_pClusterResources != NULL )
  97. {
  98. m_pClusterResources->Release();
  99. m_pClusterResources = NULL;
  100. }
  101. if ( m_pPreferredOwnerNodes != NULL )
  102. {
  103. m_pPreferredOwnerNodes->Release();
  104. m_pPreferredOwnerNodes = NULL;
  105. }
  106. if ( m_pCommonProperties != NULL )
  107. {
  108. m_pCommonProperties->Release();
  109. m_pCommonProperties = NULL;
  110. } // if: release the property collection
  111. if ( m_pPrivateProperties != NULL )
  112. {
  113. m_pPrivateProperties->Release();
  114. m_pPrivateProperties = NULL;
  115. } // if: release the property collection
  116. if ( m_pCommonROProperties != NULL )
  117. {
  118. m_pCommonROProperties->Release();
  119. m_pCommonROProperties = NULL;
  120. } // if: release the property collection
  121. if ( m_pPrivateROProperties != NULL )
  122. {
  123. m_pPrivateROProperties->Release();
  124. m_pPrivateROProperties = NULL;
  125. } // if: release the property collection
  126. if ( m_pClusRefObject != NULL )
  127. {
  128. m_pClusRefObject->Release();
  129. m_pClusRefObject = NULL;
  130. }
  131. } //*** CClusResGroup::~CClusResGroup()
  132. /////////////////////////////////////////////////////////////////////////////
  133. //++
  134. //
  135. // CClusResGroup::Create
  136. //
  137. // Description:
  138. // Finish the heavy weight construction.
  139. //
  140. // Arguments:
  141. // pClusRefObject [IN] - Wraps the cluster handle.
  142. // bstrGroupName [IN] - The name of this group.
  143. //
  144. // Return Value:
  145. // S_OK if successful, E_POINTER, or Win32 error as HRESULT.
  146. //
  147. //--
  148. /////////////////////////////////////////////////////////////////////////////
  149. HRESULT CClusResGroup::Create(
  150. IN ISClusRefObject * pClusRefObject,
  151. IN BSTR bstrGroupName
  152. )
  153. {
  154. ASSERT( pClusRefObject != NULL );
  155. ASSERT( bstrGroupName != NULL );
  156. HRESULT _hr = E_POINTER;
  157. if ( ( pClusRefObject != NULL ) && ( bstrGroupName != NULL ) )
  158. {
  159. m_pClusRefObject = pClusRefObject;
  160. m_pClusRefObject->AddRef();
  161. HCLUSTER _hCluster = 0;
  162. _hr = m_pClusRefObject->get_Handle((ULONG_PTR *) &_hCluster);
  163. if ( SUCCEEDED( _hr ) )
  164. {
  165. m_hGroup = ::CreateClusterGroup( _hCluster, bstrGroupName );
  166. if ( m_hGroup == 0 )
  167. {
  168. DWORD _sc = GetLastError();
  169. _hr = HRESULT_FROM_WIN32( _sc );
  170. }
  171. else
  172. {
  173. m_bstrGroupName = bstrGroupName;
  174. _hr = S_OK;
  175. }
  176. }
  177. }
  178. return _hr;
  179. } //*** CClusResGroup::Create()
  180. /////////////////////////////////////////////////////////////////////////////
  181. //++
  182. //
  183. // CClusResGroup::Open
  184. //
  185. // Description:
  186. // Open the passed group on the cluster.
  187. //
  188. // Arguments:
  189. // pClusRefObject [IN] - Wraps the cluster handle.
  190. // bstrGroupName [IN] - The name of this group.
  191. //
  192. // Return Value:
  193. // S_OK if successful, E_POINTER, or Win32 error as HRESULT.
  194. //
  195. //--
  196. /////////////////////////////////////////////////////////////////////////////
  197. HRESULT CClusResGroup::Open(
  198. IN ISClusRefObject * pClusRefObject,
  199. IN BSTR bstrGroupName
  200. )
  201. {
  202. ASSERT( pClusRefObject != NULL );
  203. ASSERT( bstrGroupName != NULL );
  204. HRESULT _hr = E_POINTER;
  205. if ( ( pClusRefObject != NULL ) && ( bstrGroupName != NULL ) )
  206. {
  207. m_pClusRefObject = pClusRefObject;
  208. m_pClusRefObject->AddRef();
  209. HCLUSTER _hCluster = NULL;
  210. _hr = m_pClusRefObject->get_Handle( (ULONG_PTR *) &_hCluster );
  211. if ( SUCCEEDED( _hr ) )
  212. {
  213. m_hGroup = ::OpenClusterGroup( _hCluster, bstrGroupName );
  214. if ( m_hGroup == NULL )
  215. {
  216. DWORD _sc = GetLastError();
  217. _hr = HRESULT_FROM_WIN32( _sc );
  218. }
  219. else
  220. {
  221. m_bstrGroupName = bstrGroupName;
  222. _hr = S_OK;
  223. }
  224. }
  225. }
  226. return _hr;
  227. } //*** CClusResGroup::Open()
  228. /////////////////////////////////////////////////////////////////////////////
  229. //++
  230. //
  231. // CClusResGroup::GetProperties
  232. //
  233. // Description:
  234. // Creates a property collection for this object type (Resource Group).
  235. //
  236. // Arguments:
  237. // ppProperties [OUT] - Catches the newly created collection.
  238. // bPrivate [IN] - Are these private properties? Or Common?
  239. // bReadOnly [IN] - Are these read only properties?
  240. //
  241. // Return Value:
  242. // S_OK if successful, or other HRESULT error.
  243. //
  244. //--
  245. /////////////////////////////////////////////////////////////////////////////
  246. HRESULT CClusResGroup::GetProperties(
  247. ISClusProperties ** ppProperties,
  248. BOOL bPrivate,
  249. BOOL bReadOnly
  250. )
  251. {
  252. //ASSERT( ppProperties != NULL );
  253. HRESULT _hr = E_POINTER;
  254. if ( ppProperties != NULL )
  255. {
  256. CComObject<CClusProperties> * pProperties = NULL;
  257. *ppProperties = NULL;
  258. _hr = CComObject< CClusProperties >::CreateInstance( &pProperties );
  259. if ( SUCCEEDED( _hr ) )
  260. {
  261. CSmartPtr< CComObject< CClusProperties > > ptrProperties( pProperties );
  262. _hr = ptrProperties->Create( this, bPrivate, bReadOnly );
  263. if ( SUCCEEDED( _hr ) )
  264. {
  265. _hr = ptrProperties->Refresh();
  266. if ( SUCCEEDED( _hr ) )
  267. {
  268. _hr = ptrProperties->QueryInterface( IID_ISClusProperties, (void **) ppProperties );
  269. if ( SUCCEEDED( _hr ) )
  270. {
  271. ptrProperties->AddRef();
  272. if ( bPrivate )
  273. {
  274. if ( bReadOnly )
  275. {
  276. m_pPrivateROProperties = pProperties;
  277. }
  278. else
  279. {
  280. m_pPrivateProperties = pProperties;
  281. }
  282. }
  283. else
  284. {
  285. if ( bReadOnly )
  286. {
  287. m_pCommonROProperties = pProperties;
  288. }
  289. else
  290. {
  291. m_pCommonProperties = pProperties;
  292. }
  293. }
  294. }
  295. }
  296. }
  297. }
  298. }
  299. return _hr;
  300. } //*** CClusResGroup::GetProperties()
  301. /////////////////////////////////////////////////////////////////////////////
  302. //++
  303. //
  304. // CClusResGroup::get_Handle
  305. //
  306. // Description:
  307. // Returns the handle to this object (Group).
  308. //
  309. // Arguments:
  310. // phandle [OUT] - Catches the handle.
  311. //
  312. // Return Value:
  313. // S_OK if successful, or E_POINTER if not.
  314. //
  315. //--
  316. /////////////////////////////////////////////////////////////////////////////
  317. STDMETHODIMP CClusResGroup::get_Handle( OUT ULONG_PTR * phandle )
  318. {
  319. //ASSERT( phandle != NULL );
  320. HRESULT _hr = E_POINTER;
  321. if ( phandle != NULL )
  322. {
  323. *phandle = (ULONG_PTR)m_hGroup;
  324. _hr = S_OK;
  325. }
  326. return _hr;
  327. } //*** CClusResGroup::get_Handle()
  328. /////////////////////////////////////////////////////////////////////////////
  329. //++
  330. //
  331. // CClusResGroup::Close
  332. //
  333. // Description:
  334. // Close the handle to the cluster object (Group).
  335. //
  336. // Arguments:
  337. // None.
  338. //
  339. // Return Value:
  340. // S_OK if successful, or Win32 error as HRESULT if not.
  341. //
  342. //--
  343. /////////////////////////////////////////////////////////////////////////////
  344. STDMETHODIMP CClusResGroup::Close( void )
  345. {
  346. DWORD _sc = ::CloseClusterGroup( m_hGroup );
  347. if ( m_pClusRefObject )
  348. {
  349. m_pClusRefObject->Release();
  350. m_pClusRefObject = NULL;
  351. }
  352. m_hGroup = NULL;
  353. return HRESULT_FROM_WIN32( _sc );
  354. } //*** CClusResGroup::Close()
  355. /////////////////////////////////////////////////////////////////////////////
  356. //++
  357. //
  358. // CClusResGroup::put_Name
  359. //
  360. // Description:
  361. // Change the name of this object (Group).
  362. //
  363. // Arguments:
  364. // bstrGroupName [IN] - The new name.
  365. //
  366. // Return Value:
  367. // S_OK if successful, E_POINTER, or Win32 error as HRESULT if not.
  368. //
  369. //--
  370. /////////////////////////////////////////////////////////////////////////////
  371. STDMETHODIMP CClusResGroup::put_Name( IN BSTR bstrGroupName )
  372. {
  373. //ASSERT( bstrGroupName != NULL );
  374. HRESULT _hr = E_POINTER;
  375. if ( bstrGroupName != NULL )
  376. {
  377. DWORD _sc = ::SetClusterGroupName( m_hGroup, bstrGroupName );
  378. if ( _sc == ERROR_SUCCESS )
  379. {
  380. m_bstrGroupName = bstrGroupName;
  381. }
  382. _hr = HRESULT_FROM_WIN32( _sc );
  383. }
  384. return _hr;
  385. } //*** CClusResGroup::put_Name()
  386. /////////////////////////////////////////////////////////////////////////////
  387. //++
  388. //
  389. // CClusResGroup::get_Name
  390. //
  391. // Description:
  392. // Return the name of this object (Resource Group).
  393. //
  394. // Arguments:
  395. // pbstrGroupName [OUT] - Catches the name of this object.
  396. //
  397. // Return Value:
  398. // S_OK if successful, or E_POINTER if not.
  399. //
  400. //--
  401. /////////////////////////////////////////////////////////////////////////////
  402. STDMETHODIMP CClusResGroup::get_Name( OUT BSTR * pbstrGroupName )
  403. {
  404. //ASSERT( pbstrGroupName != NULL );
  405. HRESULT _hr = E_POINTER;
  406. if ( pbstrGroupName != NULL )
  407. {
  408. *pbstrGroupName = m_bstrGroupName.Copy();
  409. _hr = S_OK;
  410. }
  411. return _hr;
  412. } //*** CClusResGroup::get_Name()
  413. /////////////////////////////////////////////////////////////////////////////
  414. //++
  415. //
  416. // CClusResGroup::get_State
  417. //
  418. // Description:
  419. // Returns the current cluster group state for this group.
  420. //
  421. // Arguments:
  422. // pcgsState [OUT] - Catches the cluster group state.
  423. //
  424. // Return Value:
  425. // S_OK if successful, E_POINTER, or Win32 error as HRESULT if not.
  426. //
  427. //--
  428. /////////////////////////////////////////////////////////////////////////////
  429. STDMETHODIMP CClusResGroup::get_State( OUT CLUSTER_GROUP_STATE * pcgsState )
  430. {
  431. //ASSERT( pcgsState != NULL );
  432. HRESULT _hr = E_POINTER;
  433. if ( pcgsState != NULL )
  434. {
  435. CLUSTER_GROUP_STATE _cgsState = ::WrapGetClusterGroupState( m_hGroup, NULL );
  436. if ( _cgsState == ClusterGroupStateUnknown )
  437. {
  438. DWORD _sc = GetLastError();
  439. _hr = HRESULT_FROM_WIN32( _sc );
  440. }
  441. else
  442. {
  443. *pcgsState = _cgsState;
  444. _hr = S_OK;
  445. }
  446. }
  447. return _hr;
  448. } //*** CClusResGroup::get_State()
  449. /////////////////////////////////////////////////////////////////////////////
  450. //++
  451. //
  452. // CClusResGroup::get_OwnerNode
  453. //
  454. // Description:
  455. // Returns the owner node for this group. The owner node is the node
  456. // where the group is currently online.
  457. //
  458. // Arguments:
  459. // ppOwnerNode [OUT[ - Catches the owner node interface.
  460. //
  461. // Return Value:
  462. // S_OK if successful, E_POINTER, or Win32 error as HRESULT if not.
  463. //
  464. //--
  465. /////////////////////////////////////////////////////////////////////////////
  466. STDMETHODIMP CClusResGroup::get_OwnerNode( OUT ISClusNode ** ppOwnerNode )
  467. {
  468. //ASSERT( ppOwnerNode != NULL );
  469. HRESULT _hr = E_POINTER;
  470. if ( ppOwnerNode != NULL )
  471. {
  472. DWORD _sc = 0;
  473. PWCHAR pwszNodeName = NULL;
  474. CLUSTER_GROUP_STATE cgs = ClusterGroupStateUnknown;
  475. cgs = WrapGetClusterGroupState( m_hGroup, &pwszNodeName );
  476. if ( cgs != ClusterGroupStateUnknown )
  477. {
  478. CComObject<CClusNode> * pNode = NULL;
  479. *ppOwnerNode = NULL;
  480. _hr = CComObject<CClusNode>::CreateInstance( &pNode );
  481. if ( SUCCEEDED( _hr ) )
  482. {
  483. CSmartPtr< ISClusRefObject > ptrRefObject( m_pClusRefObject );
  484. pNode->AddRef();
  485. _hr = pNode->Open( ptrRefObject, pwszNodeName );
  486. if ( SUCCEEDED( _hr ) )
  487. {
  488. _hr = pNode->QueryInterface( IID_ISClusNode, (void **) ppOwnerNode );
  489. }
  490. pNode->Release();
  491. }
  492. ::LocalFree( pwszNodeName );
  493. }
  494. else
  495. {
  496. _sc = GetLastError();
  497. _hr = HRESULT_FROM_WIN32( _sc );
  498. }
  499. }
  500. return _hr;
  501. } //*** CClusResGroup::get_OwnerNode()
  502. /////////////////////////////////////////////////////////////////////////////
  503. //++
  504. //
  505. // CClusResGroup::get_Resources
  506. //
  507. // Description:
  508. // Returns the collection of resources that belong to this group.
  509. //
  510. // Arguments:
  511. // ppClusterGroupResources [OUT] - Catches the collection.
  512. //
  513. // Return Value:
  514. // S_OK if successful, E_POINTER, or other HRESULT error if not.
  515. //
  516. //--
  517. /////////////////////////////////////////////////////////////////////////////
  518. STDMETHODIMP CClusResGroup::get_Resources(
  519. OUT ISClusResGroupResources ** ppClusterGroupResources
  520. )
  521. {
  522. return ::HrCreateResourceCollection< CClusResGroupResources, ISClusResGroupResources, HGROUP >(
  523. &m_pClusterResources,
  524. m_hGroup,
  525. ppClusterGroupResources,
  526. IID_ISClusResGroupResources,
  527. m_pClusRefObject
  528. );
  529. } //*** CClusResGroup::get_Resources()
  530. /////////////////////////////////////////////////////////////////////////////
  531. //++
  532. //
  533. // CClusResGroup::get_PreferredOwnerNodes
  534. //
  535. // Description:
  536. // Returns the collection of preferred owner nodes for this group.
  537. //
  538. // Arguments:
  539. // ppOwnerNodes [OUT] - Catches the collection.
  540. //
  541. // Return Value:
  542. // S_OK if successful, E_POINTER, or other HRESULT error if not.
  543. //
  544. //--
  545. /////////////////////////////////////////////////////////////////////////////
  546. STDMETHODIMP CClusResGroup::get_PreferredOwnerNodes(
  547. ISClusResGroupPreferredOwnerNodes ** ppOwnerNodes
  548. )
  549. {
  550. return ::HrCreateResourceCollection< CClusResGroupPreferredOwnerNodes, ISClusResGroupPreferredOwnerNodes, HGROUP >(
  551. &m_pPreferredOwnerNodes,
  552. m_hGroup,
  553. ppOwnerNodes,
  554. IID_ISClusResGroupPreferredOwnerNodes,
  555. m_pClusRefObject
  556. );
  557. } //*** CClusResGroup::get_PreferredOwnerNodes()
  558. /////////////////////////////////////////////////////////////////////////////
  559. //++
  560. //
  561. // CClusResGroup::Delete
  562. //
  563. // Description:
  564. // Removes this object (Resource Group) from the cluster.
  565. //
  566. // Arguments:
  567. // None.
  568. //
  569. // Return Value:
  570. // S_OK if successful, or other HRESULT error.
  571. //
  572. //--
  573. /////////////////////////////////////////////////////////////////////////////
  574. STDMETHODIMP CClusResGroup::Delete( void )
  575. {
  576. DWORD _sc = ERROR_INVALID_HANDLE;
  577. if ( m_hGroup != NULL )
  578. {
  579. _sc = DeleteClusterGroup( m_hGroup );
  580. if ( _sc == ERROR_SUCCESS )
  581. {
  582. m_hGroup = NULL;
  583. }
  584. }
  585. return HRESULT_FROM_WIN32( _sc );
  586. } //*** CClusResGroup::Delete()
  587. /////////////////////////////////////////////////////////////////////////////
  588. //++
  589. //
  590. // CClusResGroup::Online
  591. //
  592. // Description:
  593. // Bring this group online on the passed in node, or on to the node
  594. // it is currently offline if no node is specified.
  595. //
  596. // Arguments:
  597. // varTimeout [IN] - How long in seconds to wait for the group to
  598. // come online.
  599. // varNode [IN] - Node to bring the group online.
  600. // pvarPending [OUT] - Catches the pending state. True if we timed
  601. // out before the group came completely online.
  602. //
  603. // Return Value:
  604. // S_OK if successful, or other Win32 error as HRESULT.
  605. //
  606. //--
  607. /////////////////////////////////////////////////////////////////////////////
  608. STDMETHODIMP CClusResGroup::Online(
  609. IN VARIANT varTimeout,
  610. IN VARIANT varNode,
  611. OUT VARIANT * pvarPending
  612. )
  613. {
  614. //ASSERT( pNode != NULL );
  615. //ASSERT( pvarPending != NULL );
  616. HRESULT _hr = E_POINTER;
  617. if ( pvarPending != NULL )
  618. {
  619. _hr = ::VariantChangeTypeEx( &varTimeout, &varTimeout, LOCALE_SYSTEM_DEFAULT, 0, VT_I4 );
  620. if ( SUCCEEDED( _hr ) )
  621. {
  622. HNODE _hNode = NULL;
  623. HCLUSTER _hCluster = NULL;
  624. CComObject< CClusNode > * _pcnNode = NULL;
  625. ISClusNode * _piscNode = NULL;
  626. pvarPending->vt = VT_BOOL;
  627. pvarPending->boolVal = VARIANT_FALSE;
  628. _hr = m_pClusRefObject->get_Handle( (ULONG_PTR *) &_hCluster );
  629. if ( SUCCEEDED( _hr ) )
  630. {
  631. if ( varNode.vt == ( VT_VARIANT | VT_BYREF ) )
  632. {
  633. if ( varNode.pvarVal != NULL )
  634. {
  635. IDispatch * _pidNode = varNode.pvarVal->pdispVal;
  636. _hr = _pidNode->QueryInterface( IID_ISClusNode, (void **) &_piscNode );
  637. if ( SUCCEEDED( _hr ) )
  638. {
  639. _hr = _piscNode->get_Handle( (ULONG_PTR *) &_hNode );
  640. _piscNode->Release();
  641. } // if: did we get the ISClusNode interface?
  642. } // if: we have a variant value pointer
  643. } // if: was the option parameter present?
  644. else if ( varNode.vt == VT_DISPATCH )
  645. {
  646. IDispatch * _pidNode = varNode.pdispVal;
  647. _hr = _pidNode->QueryInterface( IID_ISClusNode, (void **) &_piscNode );
  648. if ( SUCCEEDED( _hr ) )
  649. {
  650. _hr = _piscNode->get_Handle( (ULONG_PTR *) &_hNode );
  651. _piscNode->Release();
  652. } // if: did we get the ISClusNode interface?
  653. } // else if: we have a dispatch variant
  654. else if ( varNode.vt == VT_BSTR )
  655. {
  656. _hr = CComObject< CClusNode >::CreateInstance( &_pcnNode );
  657. if ( SUCCEEDED( _hr ) )
  658. {
  659. _pcnNode->AddRef();
  660. _hr = _pcnNode->Open( m_pClusRefObject, ( varNode.vt & VT_BYREF) ? (*varNode.pbstrVal) : varNode.bstrVal );
  661. if ( SUCCEEDED( _hr ) )
  662. {
  663. _hr = _pcnNode->get_Handle( (ULONG_PTR *) &_hNode );
  664. } // if:
  665. } // if:
  666. } // else if: we have a string variant
  667. else if ( varNode.vt == VT_EMPTY )
  668. {
  669. _hNode = NULL;
  670. } // else if: it is empty
  671. else if ( ( varNode.vt == VT_ERROR ) && ( varNode.scode == DISP_E_PARAMNOTFOUND ) )
  672. {
  673. _hNode = NULL;
  674. } // else if: the optional parameter was not specified
  675. else
  676. {
  677. _hr = ::VariantChangeTypeEx( &varNode, &varNode, LOCALE_SYSTEM_DEFAULT, 0, VT_I4 );
  678. if ( SUCCEEDED( _hr ) )
  679. {
  680. if ( varNode.lVal != 0 )
  681. {
  682. _hr = E_INVALIDARG;
  683. } // if: this is not zero then we cannot accept this parameter format. If varNode.lVal was zero then we could assume it was a NULL arg...
  684. } // if: coerce to a long
  685. } // else: the node variant could be invalid -- check for a zero, and if found treat it like a NULL...
  686. if ( SUCCEEDED( _hr ) )
  687. {
  688. BOOL bPending = FALSE;
  689. _hr = ::HrWrapOnlineClusterGroup(
  690. _hCluster,
  691. m_hGroup,
  692. _hNode,
  693. varTimeout.lVal,
  694. (long *) &bPending
  695. );
  696. if ( SUCCEEDED( _hr ) )
  697. {
  698. if ( bPending )
  699. {
  700. pvarPending->boolVal = VARIANT_TRUE;
  701. } // if: pending?
  702. } // if: online succeeded
  703. } // if: we have a node handle
  704. } // if: get_Handle() -- cluster handle
  705. if ( _pcnNode != NULL )
  706. {
  707. _pcnNode->Release();
  708. } // if: did we create a node?
  709. } // if: wasn't the right type
  710. } //if: pvarPending != NULL
  711. return _hr;
  712. } //*** CClusResGroup::Online()
  713. /////////////////////////////////////////////////////////////////////////////
  714. //++
  715. //
  716. // CClusResGroup::Move
  717. //
  718. // Description:
  719. // Move this group to the passed in node, or to the best available node
  720. // if no node was passed, and restore its online state.
  721. //
  722. // Arguments:
  723. // varTimeout [IN] - How long in seconds to wait for the group to
  724. // come move and complete stat restoration.
  725. // varNode [IN] - Node to move the group to.
  726. // pvarPending [OUT] - Catches the pending state. True if we timed
  727. // out before the group came completely online.
  728. //
  729. // Return Value:
  730. // S_OK if successful, or other Win32 error as HRESULT.
  731. //
  732. //--
  733. /////////////////////////////////////////////////////////////////////////////
  734. STDMETHODIMP CClusResGroup::Move(
  735. IN VARIANT varTimeout,
  736. IN VARIANT varNode,
  737. OUT VARIANT * pvarPending
  738. )
  739. {
  740. //ASSERT( pNode != NULL );
  741. //ASSERT( pvarPending != NULL );
  742. HRESULT _hr = E_POINTER;
  743. if ( pvarPending != NULL )
  744. {
  745. _hr = ::VariantChangeTypeEx( &varTimeout, &varTimeout, LOCALE_SYSTEM_DEFAULT, 0, VT_I4 );
  746. if ( SUCCEEDED( _hr ) )
  747. {
  748. HNODE _hNode = NULL;
  749. HCLUSTER _hCluster = NULL;
  750. CComObject< CClusNode > * _pcnNode = NULL;
  751. ISClusNode * _piscNode = NULL;
  752. pvarPending->vt = VT_BOOL;
  753. pvarPending->boolVal = VARIANT_FALSE;
  754. _hr = m_pClusRefObject->get_Handle( (ULONG_PTR *) &_hCluster );
  755. if ( SUCCEEDED( _hr ) )
  756. {
  757. if ( varNode.vt == ( VT_VARIANT | VT_BYREF ) )
  758. {
  759. if ( varNode.pvarVal != NULL )
  760. {
  761. IDispatch * _pidNode = varNode.pvarVal->pdispVal;
  762. _hr = _pidNode->QueryInterface( IID_ISClusNode, (void **) &_piscNode );
  763. if ( SUCCEEDED( _hr ) )
  764. {
  765. _hr = _piscNode->get_Handle( (ULONG_PTR *) &_hNode );
  766. _piscNode->Release();
  767. } // if: did we get the ISClusNode interface?
  768. } // if: we have a variant value pointer
  769. } // if: was the option parameter present?
  770. else if ( varNode.vt == VT_DISPATCH )
  771. {
  772. IDispatch * _pidNode = varNode.pdispVal;
  773. _hr = _pidNode->QueryInterface( IID_ISClusNode, (void **) &_piscNode );
  774. if ( SUCCEEDED( _hr ) )
  775. {
  776. _hr = _piscNode->get_Handle( (ULONG_PTR *) &_hNode );
  777. _piscNode->Release();
  778. } // if: did we get the ISClusNode interface?
  779. } // else if: we have a dispatch variant
  780. else if ( varNode.vt == VT_BSTR )
  781. {
  782. _hr = CComObject< CClusNode >::CreateInstance( &_pcnNode );
  783. if ( SUCCEEDED( _hr ) )
  784. {
  785. _pcnNode->AddRef();
  786. _hr = _pcnNode->Open( m_pClusRefObject, ( varNode.vt & VT_BYREF) ? (*varNode.pbstrVal) : varNode.bstrVal );
  787. if ( SUCCEEDED( _hr ) )
  788. {
  789. _hr = _pcnNode->get_Handle( (ULONG_PTR *) &_hNode );
  790. } // if:
  791. } // if:
  792. } // else if: we have a string variant
  793. else if ( varNode.vt == VT_EMPTY )
  794. {
  795. _hNode = NULL;
  796. } // else if: it is empty
  797. else if ( ( varNode.vt == VT_ERROR ) && ( varNode.scode == DISP_E_PARAMNOTFOUND ) )
  798. {
  799. _hNode = NULL;
  800. } // else if: the optional parameter was not specified
  801. else
  802. {
  803. _hr = ::VariantChangeTypeEx( &varNode, &varNode, LOCALE_SYSTEM_DEFAULT, 0, VT_I4 );
  804. if ( SUCCEEDED( _hr ) )
  805. {
  806. if ( varNode.lVal != 0 )
  807. {
  808. _hr = E_INVALIDARG;
  809. } // if: this is not zero then we cannot accept this parameter format. If varNode.lVal was zero then we could assume it was a NULL arg...
  810. } // if: coerce to a long
  811. } // else: the node variant could be invalid -- check for a zero, and if found treat it like a NULL...
  812. if ( SUCCEEDED( _hr ) )
  813. {
  814. BOOL bPending = FALSE;
  815. _hr = ::HrWrapMoveClusterGroup(
  816. _hCluster,
  817. m_hGroup,
  818. _hNode,
  819. varTimeout.lVal,
  820. (long *) &bPending
  821. );
  822. if ( SUCCEEDED( _hr ) )
  823. {
  824. if ( bPending )
  825. {
  826. pvarPending->boolVal = VARIANT_TRUE;
  827. } // if: pending?
  828. } // if: Move group succeeded
  829. } // if: we have all handles
  830. } // if: get_Handle() -- cluster handle
  831. if ( _pcnNode != NULL )
  832. {
  833. _pcnNode->Release();
  834. } // if: did we create a node?
  835. } // if: wasn't the right type
  836. } //if: pvarPending != NULL
  837. return _hr;
  838. } //*** CClusResGroup::Move()
  839. /////////////////////////////////////////////////////////////////////////////
  840. //++
  841. //
  842. // CClusResGroup::Offline
  843. //
  844. // Description:
  845. // Take the group offline.
  846. //
  847. // Arguments:
  848. // varTimeout [IN] - How long in seconds to wait for the group to
  849. // go offline.
  850. // pvarPending [OUT] - Catches the pending state. True if we timed
  851. // out before the group came completely online.
  852. //
  853. // Return Value:
  854. // S_OK if successful, or other Win32 error as HRESULT.
  855. //
  856. //--
  857. /////////////////////////////////////////////////////////////////////////////
  858. STDMETHODIMP CClusResGroup::Offline(
  859. IN VARIANT varTimeout,
  860. OUT VARIANT * pvarPending
  861. )
  862. {
  863. //ASSERT( nTimeout >= 0 );
  864. //ASSERT( pvarPending != NULL );
  865. HRESULT _hr = E_POINTER;
  866. if ( pvarPending != NULL )
  867. {
  868. _hr = ::VariantChangeTypeEx( &varTimeout, &varTimeout, LOCALE_SYSTEM_DEFAULT, 0, VT_I4 );
  869. if ( SUCCEEDED( _hr ) )
  870. {
  871. HCLUSTER _hCluster;
  872. pvarPending->vt = VT_BOOL;
  873. pvarPending->boolVal = VARIANT_FALSE;
  874. _hr = m_pClusRefObject->get_Handle( (ULONG_PTR *) &_hCluster );
  875. if ( SUCCEEDED( _hr ) )
  876. {
  877. BOOL bPending = FALSE;
  878. _hr = ::HrWrapOfflineClusterGroup( _hCluster, m_hGroup, varTimeout.lVal, (long *) &bPending );
  879. if ( SUCCEEDED( _hr ) )
  880. {
  881. if ( bPending )
  882. {
  883. pvarPending->boolVal = VARIANT_TRUE;
  884. } // if: pending?
  885. } // if: offline group succeeded
  886. } // if: get_Handle() -- cluster handle
  887. } // if: wasn't the right type
  888. } //if: pvarPending != NULL
  889. return _hr;
  890. } //*** CClusResGroup::Offline()
  891. /////////////////////////////////////////////////////////////////////////////
  892. //++
  893. //
  894. // CClusResGroup::get_CommonProperties
  895. //
  896. // Description:
  897. // Get this object's (Resource Group) common properties collection.
  898. //
  899. // Arguments:
  900. // ppProperties [OUT] - Catches the properties collection.
  901. //
  902. // Return Value:
  903. // S_OK if successful, or other HRESULT error.
  904. //
  905. //--
  906. /////////////////////////////////////////////////////////////////////////////
  907. STDMETHODIMP CClusResGroup::get_CommonProperties(
  908. OUT ISClusProperties ** ppProperties
  909. )
  910. {
  911. //ASSERT( ppProperties != NULL );
  912. HRESULT _hr = E_POINTER;
  913. if ( ppProperties != NULL )
  914. {
  915. if ( m_pCommonProperties )
  916. {
  917. _hr = m_pCommonProperties->QueryInterface( IID_ISClusProperties, (void **) ppProperties );
  918. }
  919. else
  920. {
  921. _hr = GetProperties( ppProperties, FALSE, FALSE );
  922. }
  923. }
  924. return _hr;
  925. } //*** CClusResGroup::get_CommonProperties()
  926. /////////////////////////////////////////////////////////////////////////////
  927. //++
  928. //
  929. // CClusResGroup::get_PrivateProperties
  930. //
  931. // Description:
  932. // Get this object's (Resource Group) private properties collection.
  933. //
  934. // Arguments:
  935. // ppProperties [OUT] - Catches the properties collection.
  936. //
  937. // Return Value:
  938. // S_OK if successful, or other HRESULT error.
  939. //
  940. //--
  941. /////////////////////////////////////////////////////////////////////////////
  942. STDMETHODIMP CClusResGroup::get_PrivateProperties(
  943. OUT ISClusProperties ** ppProperties
  944. )
  945. {
  946. //ASSERT( ppProperties != NULL );
  947. HRESULT _hr = E_POINTER;
  948. if ( ppProperties != NULL )
  949. {
  950. if ( m_pPrivateProperties )
  951. {
  952. _hr = m_pPrivateProperties->QueryInterface( IID_ISClusProperties, (void **) ppProperties );
  953. }
  954. else
  955. {
  956. _hr = GetProperties( ppProperties, TRUE, FALSE );
  957. }
  958. }
  959. return _hr;
  960. } //*** CClusResGroup::get_PrivateProperties()
  961. /////////////////////////////////////////////////////////////////////////////
  962. //++
  963. //
  964. // CClusResGroup::get_CommonROProperties
  965. //
  966. // Description:
  967. // Get this object's (Resource Group) common read only properties collection.
  968. //
  969. // Arguments:
  970. // ppProperties [OUT] - Catches the properties collection.
  971. //
  972. // Return Value:
  973. // S_OK if successful, or other HRESULT error.
  974. //
  975. //--
  976. /////////////////////////////////////////////////////////////////////////////
  977. STDMETHODIMP CClusResGroup::get_CommonROProperties(
  978. OUT ISClusProperties ** ppProperties
  979. )
  980. {
  981. //ASSERT( ppProperties != NULL );
  982. HRESULT _hr = E_POINTER;
  983. if ( ppProperties != NULL )
  984. {
  985. if ( m_pCommonROProperties )
  986. {
  987. _hr = m_pCommonROProperties->QueryInterface( IID_ISClusProperties, (void **) ppProperties );
  988. }
  989. else
  990. {
  991. _hr = GetProperties( ppProperties, FALSE, TRUE );
  992. }
  993. }
  994. return _hr;
  995. } //*** CClusResGroup::get_CommonROProperties()
  996. /////////////////////////////////////////////////////////////////////////////
  997. //++
  998. //
  999. // CClusResGroup::get_PrivateROProperties
  1000. //
  1001. // Description:
  1002. // Get this object's (Resource Group) private read only properties collection.
  1003. //
  1004. // Arguments:
  1005. // ppProperties [OUT] - Catches the properties collection.
  1006. //
  1007. // Return Value:
  1008. // S_OK if successful, or other HRESULT error.
  1009. //
  1010. //--
  1011. /////////////////////////////////////////////////////////////////////////////
  1012. STDMETHODIMP CClusResGroup::get_PrivateROProperties(
  1013. OUT ISClusProperties ** ppProperties
  1014. )
  1015. {
  1016. //ASSERT( ppProperties != NULL );
  1017. HRESULT _hr = E_POINTER;
  1018. if ( ppProperties != NULL )
  1019. {
  1020. if ( m_pPrivateROProperties )
  1021. {
  1022. _hr = m_pPrivateROProperties->QueryInterface( IID_ISClusProperties, (void **) ppProperties );
  1023. }
  1024. else
  1025. {
  1026. _hr = GetProperties( ppProperties, TRUE, TRUE );
  1027. }
  1028. }
  1029. return _hr;
  1030. } //*** CClusResGroup::get_PrivateROProperties()
  1031. /////////////////////////////////////////////////////////////////////////////
  1032. //++
  1033. //
  1034. // CClusResGroup::get_Cluster
  1035. //
  1036. // Description:
  1037. // Returns the cluster object for the cluster where this group lives.
  1038. //
  1039. // Arguments:
  1040. // ppCluster [OUT] - Catches the cluster object.
  1041. //
  1042. // Return Value:
  1043. // S_OK if successful, E_POINTER, or other HRESULT error.
  1044. //
  1045. //--
  1046. /////////////////////////////////////////////////////////////////////////////
  1047. STDMETHODIMP CClusResGroup::get_Cluster( OUT ISCluster ** ppCluster )
  1048. {
  1049. return ::HrGetCluster( ppCluster, m_pClusRefObject );
  1050. } //*** CClusResGroup::get_Cluster()
  1051. /////////////////////////////////////////////////////////////////////////////
  1052. //++
  1053. //
  1054. // CClusResGroup::HrLoadProperties
  1055. //
  1056. // Description:
  1057. // This virtual function does the actual load of the property list from
  1058. // the cluster.
  1059. //
  1060. // Arguments:
  1061. // rcplPropList [IN OUT] - The property list to load.
  1062. // bReadOnly [IN] - Load the read only properties?
  1063. // bPrivate [IN] - Load the common or the private properties?
  1064. //
  1065. // Return Value:
  1066. // S_OK if successful, or other HRESULT error.
  1067. //
  1068. //--
  1069. /////////////////////////////////////////////////////////////////////////////
  1070. HRESULT CClusResGroup::HrLoadProperties(
  1071. IN OUT CClusPropList & rcplPropList,
  1072. IN BOOL bReadOnly,
  1073. IN BOOL bPrivate
  1074. )
  1075. {
  1076. HRESULT _hr = S_FALSE;
  1077. DWORD _dwControlCode = 0;
  1078. DWORD _sc = ERROR_SUCCESS;
  1079. if ( bReadOnly )
  1080. {
  1081. _dwControlCode = bPrivate
  1082. ? CLUSCTL_GROUP_GET_RO_PRIVATE_PROPERTIES
  1083. : CLUSCTL_GROUP_GET_RO_COMMON_PROPERTIES;
  1084. }
  1085. else
  1086. {
  1087. _dwControlCode = bPrivate
  1088. ? CLUSCTL_GROUP_GET_PRIVATE_PROPERTIES
  1089. : CLUSCTL_GROUP_GET_COMMON_PROPERTIES;
  1090. }
  1091. _sc = rcplPropList.ScGetGroupProperties( m_hGroup, _dwControlCode );
  1092. _hr = HRESULT_FROM_WIN32( _sc );
  1093. return _hr;
  1094. } //*** CClusResGroup::HrLoadProperties()
  1095. /////////////////////////////////////////////////////////////////////////////
  1096. //++
  1097. //
  1098. // CClusResGroup::ScWriteProperties
  1099. //
  1100. // Description:
  1101. // This virtual function does the actual saving of the property list to
  1102. // the cluster.
  1103. //
  1104. // Arguments:
  1105. // rcplPropList [IN] - The property list to save.
  1106. // bPrivate [IN] - Save the common or the private properties?
  1107. //
  1108. // Return Value:
  1109. // S_OK if successful, or other Win32 error as HRESULT error.
  1110. //
  1111. //--
  1112. /////////////////////////////////////////////////////////////////////////////
  1113. DWORD CClusResGroup::ScWriteProperties(
  1114. const CClusPropList & rcplPropList,
  1115. BOOL bPrivate
  1116. )
  1117. {
  1118. DWORD dwControlCode = bPrivate ? CLUSCTL_GROUP_SET_PRIVATE_PROPERTIES : CLUSCTL_GROUP_SET_COMMON_PROPERTIES;
  1119. DWORD nBytesReturned = 0;
  1120. DWORD _sc = ERROR_SUCCESS;
  1121. _sc = ClusterGroupControl(
  1122. m_hGroup,
  1123. NULL,
  1124. dwControlCode,
  1125. rcplPropList,
  1126. rcplPropList.CbBufferSize(),
  1127. 0,
  1128. 0,
  1129. &nBytesReturned
  1130. );
  1131. return _sc;
  1132. } //*** CClusResGroup::ScWriteProperties()
  1133. //*************************************************************************//
  1134. /////////////////////////////////////////////////////////////////////////////
  1135. // CClusResGroups class
  1136. /////////////////////////////////////////////////////////////////////////////
  1137. /////////////////////////////////////////////////////////////////////////////
  1138. //++
  1139. //
  1140. // CClusResGroups::CClusResGroups
  1141. //
  1142. // Description:
  1143. // Constructor.
  1144. //
  1145. // Arguments:
  1146. // None.
  1147. //
  1148. // Return Value:
  1149. // None.
  1150. //
  1151. //--
  1152. /////////////////////////////////////////////////////////////////////////////
  1153. CClusResGroups::CClusResGroups( void )
  1154. {
  1155. m_pClusRefObject = NULL;
  1156. m_piids = (const IID *) iidCClusResGroups;
  1157. m_piidsSize = ARRAYSIZE( iidCClusResGroups );
  1158. } //*** CClusResGroups::CClusResGroups()
  1159. /////////////////////////////////////////////////////////////////////////////
  1160. //++
  1161. //
  1162. // CClusResGroups::~CClusResGroups
  1163. //
  1164. // Description:
  1165. // Destructor.
  1166. //
  1167. // Arguments:
  1168. // None.
  1169. //
  1170. // Return Value:
  1171. // None.
  1172. //
  1173. //--
  1174. /////////////////////////////////////////////////////////////////////////////
  1175. CClusResGroups::~CClusResGroups( void )
  1176. {
  1177. Clear();
  1178. if ( m_pClusRefObject != NULL )
  1179. {
  1180. m_pClusRefObject->Release();
  1181. m_pClusRefObject = NULL;
  1182. }
  1183. } //*** CClusResGroups::~CClusResGroups()
  1184. /////////////////////////////////////////////////////////////////////////////
  1185. //++
  1186. //
  1187. // CClusResGroups::Create
  1188. //
  1189. // Description:
  1190. // Finish the heavy weight construction.
  1191. //
  1192. // Arguments:
  1193. // pClusRefObject [IN] - Wraps the cluster handle.
  1194. // pwszNodeName [IN] - Optional node name. If this argument
  1195. // is supplied then this is a collection of
  1196. // groups that are owned by that node.
  1197. //
  1198. // Return Value:
  1199. // S_OK if successful, or E_POINTER if not.
  1200. //
  1201. //--
  1202. /////////////////////////////////////////////////////////////////////////////
  1203. HRESULT CClusResGroups::Create(
  1204. IN ISClusRefObject * pClusRefObject,
  1205. IN LPCWSTR pwszNodeName
  1206. )
  1207. {
  1208. ASSERT( pClusRefObject != NULL );
  1209. //ASSERT( pwszNodeName != NULL );
  1210. HRESULT _hr = E_POINTER;
  1211. if ( ( pClusRefObject != NULL ) /*&& ( pwszNodeName != NULL )*/ )
  1212. {
  1213. m_pClusRefObject= pClusRefObject;
  1214. m_pClusRefObject->AddRef();
  1215. m_bstrNodeName = pwszNodeName;
  1216. _hr = S_OK;
  1217. }
  1218. return _hr;
  1219. } //*** CClusResGroups::Create()
  1220. /////////////////////////////////////////////////////////////////////////////
  1221. //++
  1222. //
  1223. // CClusResGroups::FindItem
  1224. //
  1225. // Description:
  1226. // Find the passed in group in the collection.
  1227. //
  1228. // Arguments:
  1229. // pszGroupName [IN] - The name of the group to find.
  1230. // pnIndex [OUT] - Catches the index of the group.
  1231. //
  1232. // Return Value:
  1233. // S_OK if successful, E_POINTER, or E_INVALIDARG if the group was
  1234. // not found.
  1235. //
  1236. //--
  1237. /////////////////////////////////////////////////////////////////////////////
  1238. HRESULT CClusResGroups::FindItem(
  1239. IN LPWSTR pszGroupName,
  1240. OUT ULONG * pnIndex
  1241. )
  1242. {
  1243. //ASSERT( pszGroupName != NULL );
  1244. //ASSERT( pnIndex != NULL );
  1245. HRESULT _hr = E_POINTER;
  1246. if ( ( pszGroupName != NULL ) && ( pnIndex != NULL ) )
  1247. {
  1248. CComObject<CClusResGroup> * pGroup = NULL;
  1249. int nMax = m_ResourceGroups.size();
  1250. _hr = E_INVALIDARG;
  1251. for( int i = 0; i < nMax; i++ )
  1252. {
  1253. pGroup = m_ResourceGroups[ i ];
  1254. if ( pGroup && ( lstrcmpi( pszGroupName, pGroup->Name() ) == 0 ) )
  1255. {
  1256. *pnIndex = i;
  1257. _hr = S_OK;
  1258. break;
  1259. }
  1260. }
  1261. }
  1262. return _hr;
  1263. } //*** CClusResGroups::FindItem()
  1264. /////////////////////////////////////////////////////////////////////////////
  1265. //++
  1266. //
  1267. // CClusResGroups::FindItem
  1268. //
  1269. // Description:
  1270. // Find the passed in group in the collection.
  1271. //
  1272. // Arguments:
  1273. // pResourceGroup [IN] - The group to find.
  1274. // pnIndex [OUT] - Catches the index of the group.
  1275. //
  1276. // Return Value:
  1277. // S_OK if successful, E_POINTER, or E_INVALIDARG is the group was
  1278. // not found.
  1279. //--
  1280. /////////////////////////////////////////////////////////////////////////////
  1281. HRESULT CClusResGroups::FindItem(
  1282. IN ISClusResGroup * pResourceGroup,
  1283. OUT ULONG * pnIndex
  1284. )
  1285. {
  1286. //ASSERT( pResourceGroup != NULL );
  1287. //ASSERT( pnIndex != NULL );
  1288. HRESULT _hr = E_POINTER;
  1289. if ( ( pResourceGroup != NULL ) && ( pnIndex != NULL ) )
  1290. {
  1291. CComBSTR _bstrName;
  1292. _hr = pResourceGroup->get_Name( &_bstrName );
  1293. if ( SUCCEEDED( _hr ) )
  1294. {
  1295. _hr = FindItem( _bstrName, pnIndex );
  1296. }
  1297. }
  1298. return _hr;
  1299. } //*** CClusResGroups::FindItem()
  1300. /////////////////////////////////////////////////////////////////////////////
  1301. //++
  1302. //
  1303. // CClusResGroups::GetIndex
  1304. //
  1305. // Description:
  1306. // Get the index from the passed in variant.
  1307. //
  1308. // Arguments:
  1309. // varIndex [IN] - Hold the index. This is a one based number,
  1310. // or the name of the group as a string.
  1311. // pnIndex [OUT] - Catches the zero based index in the collection.
  1312. //
  1313. // Return Value:
  1314. // S_OK if successful, E_POINTER, or E_INVALIDARG if the index is out
  1315. // of range.
  1316. //
  1317. //--
  1318. /////////////////////////////////////////////////////////////////////////////
  1319. HRESULT CClusResGroups::GetIndex(
  1320. IN VARIANT varIndex,
  1321. OUT ULONG * pnIndex
  1322. )
  1323. {
  1324. //ASSERT( pnIndex != NULL );
  1325. HRESULT _hr = E_POINTER;
  1326. if ( pnIndex != NULL )
  1327. {
  1328. CComVariant v;
  1329. ULONG nIndex = 0;
  1330. *pnIndex = 0;
  1331. v.Copy( &varIndex );
  1332. // Check to see if the index is a number.
  1333. _hr = v.ChangeType( VT_I4 );
  1334. if ( SUCCEEDED( _hr ) )
  1335. {
  1336. nIndex = v.lVal;
  1337. nIndex--; // Adjust index to be 0 relative instead of 1 relative
  1338. }
  1339. else
  1340. {
  1341. // Check to see if the index is a string.
  1342. _hr = v.ChangeType( VT_BSTR );
  1343. if ( SUCCEEDED( _hr ) )
  1344. {
  1345. // Search for the string.
  1346. _hr = FindItem( v.bstrVal, &nIndex );
  1347. }
  1348. }
  1349. // We found an index, now check the range.
  1350. if ( SUCCEEDED( _hr ) )
  1351. {
  1352. if ( nIndex < m_ResourceGroups.size() )
  1353. {
  1354. *pnIndex = nIndex;
  1355. }
  1356. else
  1357. {
  1358. _hr = E_INVALIDARG;
  1359. }
  1360. }
  1361. }
  1362. return _hr;
  1363. } //*** CClusResGroups::GetIndex()
  1364. /////////////////////////////////////////////////////////////////////////////
  1365. //++
  1366. //
  1367. // CClusResGroups::RemoveAt
  1368. //
  1369. // Description:
  1370. // Remove the object (Group) at the passed in index/position from the
  1371. // collection.
  1372. //
  1373. // Arguments:
  1374. // nPos [IN] - Index of the object to remove.
  1375. //
  1376. // Return Value:
  1377. // S_OK if successful, or E_INVALIDARG is the index is out of range.
  1378. //
  1379. //--
  1380. /////////////////////////////////////////////////////////////////////////////
  1381. HRESULT CClusResGroups::RemoveAt( IN size_t pos )
  1382. {
  1383. CComObject<CClusResGroup> * pResourceGroup = NULL;
  1384. ResourceGroupList::iterator first = m_ResourceGroups.begin();
  1385. ResourceGroupList::iterator last = m_ResourceGroups.end();
  1386. HRESULT _hr = E_INVALIDARG;
  1387. for ( size_t t = 0; ( t < pos ) && ( first != last ); t++, first++ );
  1388. if ( first != last )
  1389. {
  1390. pResourceGroup = *first;
  1391. if ( pResourceGroup )
  1392. {
  1393. pResourceGroup->Release();
  1394. }
  1395. m_ResourceGroups.erase( first );
  1396. _hr = S_OK;
  1397. }
  1398. return _hr;
  1399. } //*** CClusResGroups::RemoveAt()
  1400. /////////////////////////////////////////////////////////////////////////////
  1401. //++
  1402. //
  1403. // CClusResGroups::get_Count
  1404. //
  1405. // Description:
  1406. // Returns the count of elements (Groups) in the collection.
  1407. //
  1408. // Arguments:
  1409. // plCount [OUT] - Catches the count.
  1410. //
  1411. // Return Value:
  1412. // S_OK if successful, or E_POINTER if not.
  1413. //
  1414. //--
  1415. /////////////////////////////////////////////////////////////////////////////
  1416. STDMETHODIMP CClusResGroups::get_Count( OUT long * plCount )
  1417. {
  1418. //ASSERT( plCount != NULL );
  1419. HRESULT _hr = E_POINTER;
  1420. if ( plCount != NULL )
  1421. {
  1422. *plCount = m_ResourceGroups.size();
  1423. _hr = S_OK;
  1424. }
  1425. return _hr;
  1426. } //*** CClusResGroups::get_Count()
  1427. /////////////////////////////////////////////////////////////////////////////
  1428. //++
  1429. //
  1430. // CClusResGroups::Clear
  1431. //
  1432. // Description:
  1433. // Clean out the vector of ClusResGroup objects.
  1434. //
  1435. // Arguments:
  1436. // None.
  1437. //
  1438. // Return Value:
  1439. // None.
  1440. //
  1441. //--
  1442. /////////////////////////////////////////////////////////////////////////////
  1443. void CClusResGroups::Clear( void )
  1444. {
  1445. ::ReleaseAndEmptyCollection< ResourceGroupList, CComObject< CClusResGroup > >( m_ResourceGroups );
  1446. } //*** CClusResGroups::Clear()
  1447. /////////////////////////////////////////////////////////////////////////////
  1448. //++
  1449. //
  1450. // CClusResGroups::get_Item
  1451. //
  1452. // Description:
  1453. // Returns the object (Group) at the passed in index.
  1454. //
  1455. // Arguments:
  1456. // varIndex [IN] - Hold the index. This is a one based number, or
  1457. // a string that is the name of the group to get.
  1458. // ppProperty [OUT] - Catches the property.
  1459. //
  1460. // Return Value:
  1461. // S_OK if successful, E_POINTER, or E_INVALIDARG if the index is out
  1462. // of range, or other HRESULT error.
  1463. //
  1464. //--
  1465. /////////////////////////////////////////////////////////////////////////////
  1466. STDMETHODIMP CClusResGroups::get_Item(
  1467. IN VARIANT varIndex,
  1468. OUT ISClusResGroup ** ppResourceGroup
  1469. )
  1470. {
  1471. //ASSERT( ppResourceGroup != NULL );
  1472. HRESULT _hr = E_POINTER;
  1473. if ( ppResourceGroup != NULL )
  1474. {
  1475. CComObject<CClusResGroup> * pGroup = NULL;
  1476. // Zero the out param
  1477. *ppResourceGroup = NULL;
  1478. ULONG nIndex = 0;
  1479. _hr = GetIndex( varIndex, &nIndex );
  1480. if ( SUCCEEDED( _hr ) )
  1481. {
  1482. pGroup = m_ResourceGroups[ nIndex ];
  1483. _hr = pGroup->QueryInterface( IID_ISClusResGroup, (void **) ppResourceGroup );
  1484. }
  1485. }
  1486. return _hr;
  1487. } //*** CClusResGroups::get_Item()
  1488. /////////////////////////////////////////////////////////////////////////////
  1489. //++
  1490. //
  1491. // CClusResGroups::get__NewEnum
  1492. //
  1493. // Description:
  1494. // Create and return a new enumeration for this collection.
  1495. //
  1496. // Arguments:
  1497. // ppunk [OUT] - Catches the new enumeration.
  1498. //
  1499. // Return Value:
  1500. // S_OK if successful, E_POINTER, or other HRESULT error.
  1501. //
  1502. //--
  1503. /////////////////////////////////////////////////////////////////////////////
  1504. STDMETHODIMP CClusResGroups::get__NewEnum(
  1505. IUnknown ** ppunk
  1506. )
  1507. {
  1508. return ::HrNewIDispatchEnum< ResourceGroupList, CComObject< CClusResGroup > >( ppunk, m_ResourceGroups );
  1509. } //*** CClusResGroups::get__NewEnum()
  1510. /////////////////////////////////////////////////////////////////////////////
  1511. //++
  1512. //
  1513. // CClusResGroups::CreateItem
  1514. //
  1515. // Description:
  1516. // Create a new object (Group) and add it to the collection.
  1517. //
  1518. // Arguments:
  1519. // bstrResourceGroupName [IN] - The name of the new group.
  1520. // ppResourceGroup [OUT] - Catches the new object.
  1521. //
  1522. // Return Value:
  1523. // S_OK if successful, E_POINTER, or Win32 error as HRESULT.
  1524. //
  1525. //--
  1526. /////////////////////////////////////////////////////////////////////////////
  1527. STDMETHODIMP CClusResGroups::CreateItem(
  1528. IN BSTR bstrResourceGroupName,
  1529. OUT ISClusResGroup ** ppResourceGroup
  1530. )
  1531. {
  1532. //ASSERT( bstrResourceGroupName != NULL );
  1533. //ASSERT( ppResourceGroup != NULL );
  1534. HRESULT _hr = E_POINTER;
  1535. if ( ( bstrResourceGroupName != NULL ) && ( ppResourceGroup != NULL ) )
  1536. {
  1537. ULONG nIndex;
  1538. *ppResourceGroup = NULL;
  1539. _hr = FindItem( bstrResourceGroupName, &nIndex );
  1540. if ( FAILED( _hr ) )
  1541. {
  1542. CComObject< CClusResGroup > * pResourceGroup = NULL;
  1543. _hr = CComObject< CClusResGroup >::CreateInstance( &pResourceGroup );
  1544. if ( SUCCEEDED( _hr ) )
  1545. {
  1546. CSmartPtr< ISClusRefObject > ptrRefObject( m_pClusRefObject );
  1547. CSmartPtr< CComObject< CClusResGroup > > ptrGroup( pResourceGroup );
  1548. _hr = ptrGroup->Create( ptrRefObject, bstrResourceGroupName );
  1549. if ( SUCCEEDED( _hr ) )
  1550. {
  1551. _hr = ptrGroup->QueryInterface( IID_ISClusResGroup, (void **) ppResourceGroup );
  1552. if ( SUCCEEDED( _hr ) )
  1553. {
  1554. ptrGroup->AddRef();
  1555. m_ResourceGroups.insert( m_ResourceGroups.end(), ptrGroup );
  1556. }
  1557. }
  1558. }
  1559. } // if: group already exists
  1560. else
  1561. {
  1562. CComObject< CClusResGroup > * pResourceGroup = NULL;
  1563. pResourceGroup = m_ResourceGroups[ nIndex ];
  1564. _hr = pResourceGroup->QueryInterface( IID_ISClusResGroup, (void **) ppResourceGroup );
  1565. }
  1566. }
  1567. return _hr;
  1568. } //*** CClusResGroups::CreateItem()
  1569. /////////////////////////////////////////////////////////////////////////////
  1570. //++
  1571. //
  1572. // CClusResGroups::DeleteItem
  1573. //
  1574. // Description:
  1575. // Deletes the object (group) at the passed in index.
  1576. //
  1577. // Arguments:
  1578. // varIndex [IN] - The index of the object to delete.
  1579. //
  1580. // Return Value:
  1581. // S_OK if successful, E_INVALIDARG, or Win32 error as HRESULT.
  1582. //
  1583. //--
  1584. /////////////////////////////////////////////////////////////////////////////
  1585. STDMETHODIMP CClusResGroups::DeleteItem( IN VARIANT varIndex )
  1586. {
  1587. HRESULT _hr = S_OK;
  1588. ULONG nIndex = 0;
  1589. _hr = GetIndex( varIndex, &nIndex );
  1590. if ( SUCCEEDED( _hr ) )
  1591. {
  1592. ISClusResGroup * pResourceGroup = (ISClusResGroup *) m_ResourceGroups[ nIndex ];
  1593. // Delete the resource group.
  1594. _hr = pResourceGroup->Delete();
  1595. if ( SUCCEEDED( _hr ) )
  1596. {
  1597. RemoveAt( nIndex );
  1598. }
  1599. }
  1600. return _hr;
  1601. } //*** CClusResGroups::DeleteItem()
  1602. /////////////////////////////////////////////////////////////////////////////
  1603. //++
  1604. //
  1605. // CClusResGroups::Refresh
  1606. //
  1607. // Description:
  1608. // Load the collection from the cluster.
  1609. //
  1610. // Arguments:
  1611. // None.
  1612. //
  1613. // Return Value:
  1614. // S_OK is successful, or Win32 error as HRESULT if not.
  1615. //
  1616. //--
  1617. /////////////////////////////////////////////////////////////////////////////
  1618. STDMETHODIMP CClusResGroups::Refresh( void )
  1619. {
  1620. Clear();
  1621. if ( m_pClusRefObject == NULL )
  1622. {
  1623. return E_POINTER;
  1624. } // if: we have a cluster handle wrapper
  1625. if ( m_bstrNodeName == (BSTR) NULL )
  1626. {
  1627. return RefreshCluster();
  1628. } // if: this collection is for a cluster
  1629. else
  1630. {
  1631. return RefreshNode();
  1632. } // else: this collection is for a node
  1633. } //*** CClusResGroups::Refresh()
  1634. /////////////////////////////////////////////////////////////////////////////
  1635. //++
  1636. //
  1637. // CClusResGroups::RefreshCluster
  1638. //
  1639. // Description:
  1640. // Load all of the groups in the cluster into this collection.
  1641. //
  1642. // Arguments:
  1643. // None.
  1644. //
  1645. // Return Value:
  1646. // S_OK is successful, or Win32 error as HRESULT if not.
  1647. //
  1648. //--
  1649. /////////////////////////////////////////////////////////////////////////////
  1650. HRESULT CClusResGroups::RefreshCluster( void )
  1651. {
  1652. HCLUSTER _hCluster = NULL;
  1653. HRESULT _hr;
  1654. _hr = m_pClusRefObject->get_Handle( (ULONG_PTR *) &_hCluster );
  1655. if ( SUCCEEDED( _hr ) )
  1656. {
  1657. HCLUSENUM hEnum = NULL;
  1658. DWORD _sc = ERROR_SUCCESS;
  1659. hEnum = ::ClusterOpenEnum( _hCluster, CLUSTER_ENUM_GROUP );
  1660. if ( hEnum != NULL )
  1661. {
  1662. DWORD dwType;
  1663. LPWSTR pwszName = NULL;
  1664. CComObject< CClusResGroup > * pResourceGroup = NULL;
  1665. int nIndex;
  1666. for( nIndex = 0, _hr = S_OK; SUCCEEDED( _hr ); nIndex++ )
  1667. {
  1668. _sc = ::WrapClusterEnum( hEnum, nIndex, &dwType, &pwszName );
  1669. if ( _sc == ERROR_NO_MORE_ITEMS)
  1670. {
  1671. _hr = S_OK;
  1672. break;
  1673. }
  1674. else if ( _sc == ERROR_SUCCESS )
  1675. {
  1676. _hr = CComObject< CClusResGroup >::CreateInstance( &pResourceGroup );
  1677. if ( SUCCEEDED( _hr ) )
  1678. {
  1679. CSmartPtr< ISClusRefObject > ptrRefObject( m_pClusRefObject );
  1680. CSmartPtr< CComObject< CClusResGroup > > ptrGroup( pResourceGroup );
  1681. _hr = ptrGroup->Open( ptrRefObject, pwszName );
  1682. if ( SUCCEEDED( _hr ) )
  1683. {
  1684. ptrGroup->AddRef();
  1685. m_ResourceGroups.insert( m_ResourceGroups.end(), ptrGroup );
  1686. }
  1687. }
  1688. ::LocalFree( pwszName );
  1689. pwszName = NULL;
  1690. }
  1691. else
  1692. {
  1693. _hr = HRESULT_FROM_WIN32( _sc );
  1694. }
  1695. } // end for
  1696. ::ClusterCloseEnum( hEnum ) ;
  1697. }
  1698. else
  1699. {
  1700. _sc = GetLastError();
  1701. _hr = HRESULT_FROM_WIN32( _sc );
  1702. }
  1703. }
  1704. return _hr;
  1705. } //*** CClusResGroups::RefreshCluster()
  1706. /////////////////////////////////////////////////////////////////////////////
  1707. //++
  1708. //
  1709. // CClusResGroups::RefreshNode
  1710. //
  1711. // Description:
  1712. // Load all of the groups owned by the node at m_bstrNodeName.
  1713. //
  1714. // Arguments:
  1715. // None.
  1716. //
  1717. // Return Value:
  1718. // S_OK is successful, or Win32 error as HRESULT if not.
  1719. //
  1720. //--
  1721. /////////////////////////////////////////////////////////////////////////////
  1722. HRESULT CClusResGroups::RefreshNode( void )
  1723. {
  1724. HCLUSTER _hCluster = NULL;
  1725. HRESULT _hr;
  1726. _hr = m_pClusRefObject->get_Handle( (ULONG_PTR *) &_hCluster );
  1727. if ( SUCCEEDED( _hr ) )
  1728. {
  1729. HCLUSENUM hEnum = NULL;
  1730. DWORD _sc = ERROR_SUCCESS;
  1731. hEnum = ::ClusterOpenEnum( _hCluster, CLUSTER_ENUM_GROUP );
  1732. if ( hEnum != NULL )
  1733. {
  1734. DWORD dwType;
  1735. LPWSTR pwszName = NULL;
  1736. LPWSTR pwszNodeName = NULL;
  1737. CComObject< CClusResGroup > * pResourceGroup = NULL;
  1738. CLUSTER_GROUP_STATE cgs = ClusterGroupStateUnknown;
  1739. int _nIndex;
  1740. for( _nIndex = 0, _hr = S_OK; SUCCEEDED( _hr ); _nIndex++ )
  1741. {
  1742. _sc = ::WrapClusterEnum( hEnum, _nIndex, &dwType, &pwszName );
  1743. if ( _sc == ERROR_NO_MORE_ITEMS )
  1744. {
  1745. _hr = S_OK;
  1746. break;
  1747. }
  1748. else if ( _sc == ERROR_SUCCESS )
  1749. {
  1750. _hr = CComObject< CClusResGroup >::CreateInstance( &pResourceGroup );
  1751. if ( SUCCEEDED( _hr ) )
  1752. {
  1753. CSmartPtr< ISClusRefObject > ptrRefObject( m_pClusRefObject );
  1754. CSmartPtr< CComObject< CClusResGroup > > ptrGroup( pResourceGroup );
  1755. _hr = ptrGroup->Open( ptrRefObject, pwszName );
  1756. if ( SUCCEEDED( _hr ) )
  1757. {
  1758. cgs = WrapGetClusterGroupState( ptrGroup->Hgroup(), &pwszNodeName );
  1759. if ( cgs != ClusterGroupStateUnknown )
  1760. {
  1761. if ( lstrcmpi( m_bstrNodeName, pwszNodeName ) == 0 )
  1762. {
  1763. ptrGroup->AddRef();
  1764. m_ResourceGroups.insert( m_ResourceGroups.end(), ptrGroup );
  1765. }
  1766. ::LocalFree( pwszNodeName );
  1767. pwszNodeName = NULL;
  1768. }
  1769. }
  1770. }
  1771. ::LocalFree( pwszName );
  1772. pwszName = NULL;
  1773. }
  1774. else
  1775. {
  1776. _hr = HRESULT_FROM_WIN32( _sc );
  1777. }
  1778. } // for:
  1779. ::ClusterCloseEnum( hEnum );
  1780. }
  1781. else
  1782. {
  1783. _sc = GetLastError();
  1784. _hr = HRESULT_FROM_WIN32( _sc );
  1785. }
  1786. }
  1787. return _hr;
  1788. } //*** CClusResGroups::RefreshNode()