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.

2877 lines
72 KiB

  1. /////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1997-2000 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // ClusNode.cpp
  7. //
  8. // Description:
  9. // Implementation of the node classes for the MSCLUS automation classes.
  10. //
  11. // Author:
  12. // Charles Stacy Harris (stacyh) 28-Feb-1997
  13. // Galen Barbee (galenb) July 1998
  14. //
  15. // Revision History:
  16. // July 1998 GalenB Maaaaaajjjjjjjjjoooooorrrr clean up
  17. //
  18. // Notes:
  19. //
  20. /////////////////////////////////////////////////////////////////////////////
  21. #include "stdafx.h"
  22. #include "ClusterObject.h"
  23. #include "property.h"
  24. #include "clusres.h"
  25. #include "clusresg.h"
  26. #include "clusneti.h"
  27. #include "clusnode.h"
  28. /////////////////////////////////////////////////////////////////////////////
  29. // Global variables
  30. /////////////////////////////////////////////////////////////////////////////
  31. static const IID * iidCClusNode[] =
  32. {
  33. &IID_ISClusNode
  34. };
  35. static const IID * iidCClusNodes[] =
  36. {
  37. &IID_ISClusNodes
  38. };
  39. static const IID * iidCClusResGroupPreferredOwnerNodes[] =
  40. {
  41. &IID_ISClusResGroupPreferredOwnerNodes
  42. };
  43. static const IID * iidCClusResPossibleOwnerNodes[] =
  44. {
  45. &IID_ISClusResPossibleOwnerNodes
  46. };
  47. static const IID * iidCClusResTypePossibleOwnerNodes[] =
  48. {
  49. &IID_ISClusResTypePossibleOwnerNodes
  50. };
  51. //*************************************************************************//
  52. /////////////////////////////////////////////////////////////////////////////
  53. // CClusNode class
  54. /////////////////////////////////////////////////////////////////////////////
  55. /////////////////////////////////////////////////////////////////////////////
  56. //++
  57. //
  58. // CClusNode::CClusNode
  59. //
  60. // Description:
  61. // Constructor.
  62. //
  63. // Arguments:
  64. // None.
  65. //
  66. // Return Value:
  67. // None.
  68. //
  69. //--
  70. /////////////////////////////////////////////////////////////////////////////
  71. CClusNode::CClusNode( void )
  72. {
  73. m_hNode = NULL;
  74. m_pClusRefObject = NULL;
  75. m_pResourceGroups = NULL;
  76. m_pCommonProperties = NULL;
  77. m_pPrivateProperties = NULL;
  78. m_pCommonROProperties = NULL;
  79. m_pPrivateROProperties = NULL;
  80. m_pNetInterfaces = NULL;
  81. m_piids = (const IID *) iidCClusNode;
  82. m_piidsSize = ARRAYSIZE( iidCClusNode );
  83. } //*** CClusNode::CClusNode()
  84. /////////////////////////////////////////////////////////////////////////////
  85. //++
  86. //
  87. // CClusNode::~CClusNode
  88. //
  89. // Description:
  90. // Destructor.
  91. //
  92. // Arguments:
  93. // None.
  94. //
  95. // Return Value:
  96. // None.
  97. //
  98. //--
  99. /////////////////////////////////////////////////////////////////////////////
  100. CClusNode::~CClusNode( void )
  101. {
  102. if ( m_hNode != NULL )
  103. {
  104. ::CloseClusterNode( m_hNode );
  105. m_hNode = NULL;
  106. } // if:
  107. if ( m_pResourceGroups != NULL )
  108. {
  109. m_pResourceGroups->Release();
  110. m_pResourceGroups = NULL;
  111. } // if:
  112. if ( m_pCommonProperties != NULL )
  113. {
  114. m_pCommonProperties->Release();
  115. m_pCommonProperties = NULL;
  116. } // if: release the property collection
  117. if ( m_pPrivateProperties != NULL )
  118. {
  119. m_pPrivateProperties->Release();
  120. m_pPrivateProperties = NULL;
  121. } // if: release the property collection
  122. if ( m_pCommonROProperties != NULL )
  123. {
  124. m_pCommonROProperties->Release();
  125. m_pCommonROProperties = NULL;
  126. } // if: release the property collection
  127. if ( m_pPrivateROProperties != NULL )
  128. {
  129. m_pPrivateROProperties->Release();
  130. m_pPrivateROProperties = NULL;
  131. } // if: release the property collection
  132. if ( m_pNetInterfaces != NULL )
  133. {
  134. m_pNetInterfaces->Release();
  135. m_pNetInterfaces = NULL;
  136. } // if:
  137. if ( m_pClusRefObject != NULL )
  138. {
  139. m_pClusRefObject->Release();
  140. m_pClusRefObject = NULL;
  141. } // if:
  142. } //*** CClusNode::~CClusNode()
  143. /////////////////////////////////////////////////////////////////////////////
  144. //++
  145. //
  146. // CClusNode::Open
  147. //
  148. // Description:
  149. // Retrieve this object's (Node) data from the cluster.
  150. //
  151. // Arguments:
  152. // pClusRefObject [IN] - Wraps the cluster handle.
  153. // bstrNodeName [IN] - The name of the node to open.
  154. //
  155. // Return Value:
  156. // S_OK if successful, E_POINTER, or other Win32 error as HRESULT.
  157. //
  158. //--
  159. /////////////////////////////////////////////////////////////////////////////
  160. HRESULT CClusNode::Open(
  161. IN ISClusRefObject * pClusRefObject,
  162. IN BSTR bstrNodeName
  163. )
  164. {
  165. ASSERT( pClusRefObject != NULL );
  166. ASSERT( bstrNodeName != NULL);
  167. HRESULT _hr = E_POINTER;
  168. if ( ( pClusRefObject != NULL ) && ( bstrNodeName != NULL ) )
  169. {
  170. m_pClusRefObject = pClusRefObject;
  171. m_pClusRefObject->AddRef();
  172. HCLUSTER hCluster = NULL;
  173. _hr = m_pClusRefObject->get_Handle( (ULONG_PTR *) &hCluster );
  174. if ( SUCCEEDED( _hr ) )
  175. {
  176. m_hNode = ::OpenClusterNode( hCluster, bstrNodeName );
  177. if ( m_hNode == 0 )
  178. {
  179. DWORD _sc = GetLastError();
  180. _hr = HRESULT_FROM_WIN32( _sc );
  181. } // if: the node failed to open
  182. else
  183. {
  184. m_bstrNodeName = bstrNodeName;
  185. _hr = S_OK;
  186. } // else: we opened the node
  187. } // if: we have a cluster handle
  188. } // if: non NULL args
  189. return _hr;
  190. } //*** CClusNode::Open()
  191. /////////////////////////////////////////////////////////////////////////////
  192. //++
  193. //
  194. // CClusNode::GetProperties
  195. //
  196. // Description:
  197. // Creates a property collection for this object type (Node).
  198. //
  199. // Arguments:
  200. // ppProperties [OUT] - Catches the newly created collection.
  201. // bPrivate [IN] - Are these private properties? Or Common?
  202. // bReadOnly [IN] - Are these read only properties?
  203. //
  204. // Return Value:
  205. // S_OK if successful, or other HRESULT error.
  206. //
  207. //--
  208. /////////////////////////////////////////////////////////////////////////////
  209. HRESULT CClusNode::GetProperties(
  210. ISClusProperties ** ppProperties,
  211. BOOL bPrivate,
  212. BOOL bReadOnly
  213. )
  214. {
  215. //ASSERT( ppProperties != NULL );
  216. HRESULT _hr = E_POINTER;
  217. if ( ppProperties != NULL )
  218. {
  219. CComObject< CClusProperties > * pProperties = NULL;
  220. *ppProperties = NULL;
  221. _hr = CComObject< CClusProperties >::CreateInstance( &pProperties );
  222. if ( SUCCEEDED( _hr ) )
  223. {
  224. CSmartPtr< CComObject< CClusProperties > > ptrProperties( pProperties );
  225. _hr = ptrProperties->Create( this, bPrivate, bReadOnly );
  226. if ( SUCCEEDED( _hr ) )
  227. {
  228. _hr = ptrProperties->Refresh();
  229. if ( SUCCEEDED( _hr ) )
  230. {
  231. _hr = ptrProperties->QueryInterface( IID_ISClusProperties, (void **) ppProperties );
  232. if ( SUCCEEDED( _hr ) )
  233. {
  234. ptrProperties->AddRef();
  235. if ( bPrivate )
  236. {
  237. if ( bReadOnly )
  238. {
  239. m_pPrivateROProperties = ptrProperties;
  240. }
  241. else
  242. {
  243. m_pPrivateProperties = ptrProperties;
  244. }
  245. }
  246. else
  247. {
  248. if ( bReadOnly )
  249. {
  250. m_pCommonROProperties = ptrProperties;
  251. }
  252. else
  253. {
  254. m_pCommonProperties = ptrProperties;
  255. }
  256. }
  257. }
  258. }
  259. }
  260. }
  261. } // if: non NULL args
  262. return _hr;
  263. } //*** CClusNode::GetProperties()
  264. /////////////////////////////////////////////////////////////////////////////
  265. //++
  266. //
  267. // CClusNode::get_Handle
  268. //
  269. // Description:
  270. // Get the native handle for this object (Node).
  271. //
  272. // Arguments:
  273. // phandle [OUT] - Catches the handle.
  274. //
  275. // Return Value:
  276. // S_OK if successful, or E_POINTER.
  277. //
  278. //--
  279. /////////////////////////////////////////////////////////////////////////////
  280. STDMETHODIMP CClusNode::get_Handle( OUT ULONG_PTR * phandle )
  281. {
  282. //ASSERT( phandle != NULL );
  283. ASSERT( m_hNode != NULL );
  284. HRESULT _hr = E_POINTER;
  285. if ( phandle != NULL )
  286. {
  287. if ( m_hNode != NULL )
  288. {
  289. *phandle = (ULONG_PTR) m_hNode;
  290. _hr = S_OK;
  291. } // if: node handle not NULL
  292. } // if: argument no NULL
  293. return _hr;
  294. } //*** CClusNode::get_Handle()
  295. /////////////////////////////////////////////////////////////////////////////
  296. //++
  297. //
  298. // CClusNode::Close
  299. //
  300. // Description:
  301. // Close this object (Node).
  302. //
  303. // Arguments:
  304. // None.
  305. //
  306. // Return Value:
  307. // S_OK if successful, or other Win32 error as HRESULT.
  308. //
  309. //--
  310. /////////////////////////////////////////////////////////////////////////////
  311. HRESULT CClusNode::Close( void )
  312. {
  313. HRESULT _hr = S_FALSE;
  314. if ( m_hNode != NULL )
  315. {
  316. if ( ::CloseClusterNode( m_hNode ) )
  317. {
  318. m_hNode = NULL;
  319. _hr = S_OK;
  320. }
  321. else
  322. {
  323. DWORD _sc = GetLastError();
  324. _hr = HRESULT_FROM_WIN32( _sc );
  325. }
  326. }
  327. return _hr;
  328. } //*** CClusNode::Close()
  329. /////////////////////////////////////////////////////////////////////////////
  330. //++
  331. //
  332. // CClusNode::get_Name
  333. //
  334. // Description:
  335. // Return the name of this object (Node).
  336. //
  337. // Arguments:
  338. // pbstrNodeName [OUT] - Catches the name of this object.
  339. //
  340. // Return Value:
  341. // S_OK if successful, E_POINTER, or other HRESULT error.
  342. //
  343. //--
  344. /////////////////////////////////////////////////////////////////////////////
  345. STDMETHODIMP CClusNode::get_Name( BSTR * pbstrNodeName )
  346. {
  347. //ASSERT( pbstrNodeName != NULL );
  348. HRESULT _hr = E_POINTER;
  349. if ( pbstrNodeName != NULL )
  350. {
  351. *pbstrNodeName = m_bstrNodeName.Copy();
  352. _hr = S_OK;
  353. }
  354. return _hr;
  355. } //*** CClusNode::get_Name()
  356. /////////////////////////////////////////////////////////////////////////////
  357. //++
  358. //
  359. // CClusNode::get_NodeID
  360. //
  361. // Description:
  362. // Get the ID of this node.
  363. //
  364. // Arguments:
  365. // pbstrNodeID [OUT] - Catches the node id.
  366. //
  367. // Return Value:
  368. // S_OK if successful, E_POINTER, or other Win32 error as HRESULT.
  369. //
  370. //--
  371. /////////////////////////////////////////////////////////////////////////////
  372. STDMETHODIMP CClusNode::get_NodeID( OUT BSTR * pbstrNodeID )
  373. {
  374. //ASSERT( pbstrNodeID != NULL );
  375. HRESULT _hr = E_POINTER;
  376. if ( pbstrNodeID != NULL )
  377. {
  378. LPWSTR pwszNodeID;
  379. DWORD dwRet = ERROR_SUCCESS;
  380. dwRet = ::WrapGetClusterNodeId( m_hNode, &pwszNodeID );
  381. if ( dwRet == ERROR_SUCCESS )
  382. {
  383. *pbstrNodeID = ::SysAllocString( pwszNodeID );
  384. if ( *pbstrNodeID == NULL )
  385. {
  386. _hr = E_OUTOFMEMORY;
  387. }
  388. ::LocalFree( pwszNodeID );
  389. } // if: got node ID...
  390. _hr = HRESULT_FROM_WIN32( dwRet );
  391. }
  392. return _hr;
  393. } //*** CClusNode::get_NodeID()
  394. /////////////////////////////////////////////////////////////////////////////
  395. //++
  396. //
  397. // CClusNode::get_State
  398. //
  399. // Description:
  400. // Get the current state of the cluster node. Up/down/paused, etc.
  401. //
  402. // Arguments:
  403. // pState [OUT] - Catches the node state.
  404. //
  405. // Return Value:
  406. // S_OK if successful, E_POINTER, or other Win32 error as HRESULT.
  407. //
  408. //--
  409. /////////////////////////////////////////////////////////////////////////////
  410. STDMETHODIMP CClusNode::get_State( OUT CLUSTER_NODE_STATE * pState )
  411. {
  412. //ASSERT( pState != NULL );
  413. HRESULT _hr = E_POINTER;
  414. if ( pState != NULL )
  415. {
  416. CLUSTER_NODE_STATE cns;
  417. cns = ::GetClusterNodeState( m_hNode );
  418. if ( cns == ClusterNodeStateUnknown )
  419. {
  420. DWORD _sc = GetLastError();
  421. _hr = HRESULT_FROM_WIN32( _sc );
  422. }
  423. else
  424. {
  425. *pState = cns;
  426. _hr = S_OK;
  427. }
  428. }
  429. return _hr;
  430. } //*** CClusNode::get_State()
  431. /////////////////////////////////////////////////////////////////////////////
  432. //++
  433. //
  434. // CClusNode::Pause
  435. //
  436. // Description:
  437. // Pause this cluster node.
  438. //
  439. // Arguments:
  440. // None.
  441. //
  442. // Return Value:
  443. // S_OK if successful, E_POINTER, or other Win32 error as HRESULT.
  444. //
  445. //--
  446. /////////////////////////////////////////////////////////////////////////////
  447. STDMETHODIMP CClusNode::Pause( void )
  448. {
  449. HRESULT _hr = E_POINTER;
  450. if ( m_hNode != NULL )
  451. {
  452. DWORD _sc = ::PauseClusterNode( m_hNode );
  453. _hr = HRESULT_FROM_WIN32( _sc );
  454. }
  455. return _hr;
  456. } //*** CClusNode::Pause()
  457. /////////////////////////////////////////////////////////////////////////////
  458. //++
  459. //
  460. // CClusNode::Resume
  461. //
  462. // Description:
  463. // Resume this paused cluster node.
  464. //
  465. // Arguments:
  466. // None.
  467. //
  468. // Return Value:
  469. // S_OK if successful, E_POINTER, or other Win32 error as HRESULT.
  470. //
  471. //--
  472. /////////////////////////////////////////////////////////////////////////////
  473. STDMETHODIMP CClusNode::Resume( void )
  474. {
  475. HRESULT _hr = E_POINTER;
  476. if ( m_hNode != NULL )
  477. {
  478. DWORD _sc = ::ResumeClusterNode( m_hNode );
  479. _hr = HRESULT_FROM_WIN32( _sc );
  480. }
  481. return _hr;
  482. } //*** CClusNode::Resume()
  483. /////////////////////////////////////////////////////////////////////////////
  484. //++
  485. //
  486. // CClusNode::Evict
  487. //
  488. // Description:
  489. // Evict this node from the cluster.
  490. //
  491. // Arguments:
  492. // None.
  493. //
  494. // Return Value:
  495. // S_OK if successful, E_POINTER, or other Win32 error as HRESULT.
  496. //
  497. //--
  498. /////////////////////////////////////////////////////////////////////////////
  499. STDMETHODIMP CClusNode::Evict( void )
  500. {
  501. HRESULT _hr = E_POINTER;
  502. if ( m_hNode != NULL )
  503. {
  504. DWORD _sc = ::EvictClusterNode( m_hNode );
  505. _hr = HRESULT_FROM_WIN32( _sc );
  506. }
  507. return _hr;
  508. } //*** CClusNode::Evict()
  509. /////////////////////////////////////////////////////////////////////////////
  510. //++
  511. //
  512. // CClusNode::get_ResourceGroups
  513. //
  514. // Description:
  515. // Get the collection of groups that are active on this node.
  516. //
  517. // Arguments:
  518. // ppResourceGroups [OUT] - Catches the collection of groups.
  519. //
  520. // Return Value:
  521. // S_OK if successful, E_POINTER, or other Win32 error as HRESULT.
  522. //
  523. //--
  524. /////////////////////////////////////////////////////////////////////////////
  525. STDMETHODIMP CClusNode::get_ResourceGroups(
  526. OUT ISClusResGroups ** ppResourceGroups
  527. )
  528. {
  529. return ::HrCreateResourceCollection< CClusResGroups, ISClusResGroups, CComBSTR >(
  530. &m_pResourceGroups,
  531. m_bstrNodeName,
  532. ppResourceGroups,
  533. IID_ISClusResGroups,
  534. m_pClusRefObject
  535. );
  536. } //*** CClusNode::get_ResourceGroups()
  537. /////////////////////////////////////////////////////////////////////////////
  538. //++
  539. //
  540. // CClusNode::get_CommonProperties
  541. //
  542. // Description:
  543. // Get this object's (Node) common properties collection.
  544. //
  545. // Arguments:
  546. // ppProperties [OUT] - Catches the properties collection.
  547. //
  548. // Return Value:
  549. // S_OK if successful, or other HRESULT error.
  550. //
  551. //--
  552. /////////////////////////////////////////////////////////////////////////////
  553. STDMETHODIMP CClusNode::get_CommonProperties(
  554. OUT ISClusProperties ** ppProperties
  555. )
  556. {
  557. //ASSERT( ppProperties != NULL );
  558. HRESULT _hr = E_POINTER;
  559. if ( ppProperties != NULL )
  560. {
  561. if ( m_pCommonProperties )
  562. {
  563. _hr = m_pCommonProperties->QueryInterface( IID_ISClusProperties, (void **) ppProperties );
  564. }
  565. else
  566. {
  567. _hr = GetProperties( ppProperties, FALSE, FALSE );
  568. }
  569. }
  570. return _hr;
  571. } //*** CClusNode::get_CommonProperties()
  572. /////////////////////////////////////////////////////////////////////////////
  573. //++
  574. //
  575. // CClusNode::get_PrivateProperties
  576. //
  577. // Description:
  578. // Get this object's (Node) private properties collection.
  579. //
  580. // Arguments:
  581. // ppProperties [OUT] - Catches the properties collection.
  582. //
  583. // Return Value:
  584. // S_OK if successful, or other HRESULT error.
  585. //
  586. //--
  587. /////////////////////////////////////////////////////////////////////////////
  588. STDMETHODIMP CClusNode::get_PrivateProperties(
  589. OUT ISClusProperties ** ppProperties
  590. )
  591. {
  592. //ASSERT( ppProperties != NULL );
  593. HRESULT _hr = E_POINTER;
  594. if ( ppProperties != NULL )
  595. {
  596. if ( m_pPrivateProperties )
  597. {
  598. _hr = m_pPrivateProperties->QueryInterface( IID_ISClusProperties, (void **) ppProperties );
  599. }
  600. else
  601. {
  602. _hr = GetProperties( ppProperties, TRUE, FALSE );
  603. }
  604. }
  605. return _hr;
  606. } //*** CClusNode::get_PrivateProperties()
  607. /////////////////////////////////////////////////////////////////////////////
  608. //++
  609. //
  610. // CClusNode::get_CommonROProperties
  611. //
  612. // Description:
  613. // Get this object's (Node) common read only properties collection.
  614. //
  615. // Arguments:
  616. // ppProperties [OUT] - Catches the properties collection.
  617. //
  618. // Return Value:
  619. // S_OK if successful, or other HRESULT error.
  620. //
  621. //--
  622. /////////////////////////////////////////////////////////////////////////////
  623. STDMETHODIMP CClusNode::get_CommonROProperties(
  624. OUT ISClusProperties ** ppProperties
  625. )
  626. {
  627. //ASSERT( ppProperties != NULL );
  628. HRESULT _hr = E_POINTER;
  629. if ( ppProperties != NULL )
  630. {
  631. if ( m_pCommonROProperties )
  632. {
  633. _hr = m_pCommonROProperties->QueryInterface( IID_ISClusProperties, (void **) ppProperties );
  634. }
  635. else
  636. {
  637. _hr = GetProperties( ppProperties, FALSE, TRUE );
  638. }
  639. }
  640. return _hr;
  641. } //*** CClusNode::get_CommonROProperties()
  642. /////////////////////////////////////////////////////////////////////////////
  643. //++
  644. //
  645. // CClusNode::get_PrivateROProperties
  646. //
  647. // Description:
  648. // Get this object's (Node) private read only properties collection.
  649. //
  650. // Arguments:
  651. // ppProperties [OUT] - Catches the properties collection.
  652. //
  653. // Return Value:
  654. // S_OK if successful, or other HRESULT error.
  655. //
  656. //--
  657. /////////////////////////////////////////////////////////////////////////////
  658. STDMETHODIMP CClusNode::get_PrivateROProperties(
  659. OUT ISClusProperties ** ppProperties
  660. )
  661. {
  662. //ASSERT( ppProperties != NULL );
  663. HRESULT _hr = E_POINTER;
  664. if ( ppProperties != NULL )
  665. {
  666. if ( m_pPrivateROProperties )
  667. {
  668. _hr = m_pPrivateROProperties->QueryInterface( IID_ISClusProperties, (void **) ppProperties );
  669. }
  670. else
  671. {
  672. _hr = GetProperties( ppProperties, TRUE, TRUE );
  673. }
  674. }
  675. return _hr;
  676. } //*** CClusNode::get_PrivateROProperties()
  677. /////////////////////////////////////////////////////////////////////////////
  678. //++
  679. //
  680. // CClusNode::get_NetInterfaces
  681. //
  682. // Description:
  683. // Get this object's (Node) network interfaces collection.
  684. //
  685. // Arguments:
  686. // ppNetInterfaces [OUT] - Catches the network interfaces collection.
  687. //
  688. // Return Value:
  689. // S_OK if successful, E_POINTER, or other HRESULT error.
  690. //
  691. //--
  692. /////////////////////////////////////////////////////////////////////////////
  693. STDMETHODIMP CClusNode::get_NetInterfaces(
  694. OUT ISClusNodeNetInterfaces ** ppNetInterfaces
  695. )
  696. {
  697. return ::HrCreateResourceCollection< CClusNodeNetInterfaces, ISClusNodeNetInterfaces, HNODE >(
  698. &m_pNetInterfaces,
  699. m_hNode,
  700. ppNetInterfaces,
  701. IID_ISClusNodeNetInterfaces,
  702. m_pClusRefObject
  703. );
  704. } //*** CClusNode::get_NetInterfaces()
  705. /////////////////////////////////////////////////////////////////////////////
  706. //++
  707. //
  708. // CClusNode::get_Cluster
  709. //
  710. // Description:
  711. // Returns the parent cluster of this node.
  712. //
  713. // Arguments:
  714. // ppCluster [OUT] - Catches the cluster parent.
  715. //
  716. // Return Value:
  717. // S_OK if successful, E_POINTER, or other Win32 error as HRESULT.
  718. //
  719. //--
  720. /////////////////////////////////////////////////////////////////////////////
  721. STDMETHODIMP CClusNode::get_Cluster( OUT ISCluster ** ppCluster )
  722. {
  723. return ::HrGetCluster( ppCluster, m_pClusRefObject );
  724. } //*** CClusNode::get_Cluster()
  725. /////////////////////////////////////////////////////////////////////////////
  726. //++
  727. //
  728. // CClusNode::HrLoadProperties
  729. //
  730. // Description:
  731. // This virtual function does the actual load of the property list from
  732. // the cluster.
  733. //
  734. // Arguments:
  735. // rcplPropList [IN OUT] - The property list to load.
  736. // bReadOnly [IN] - Load the read only properties?
  737. // bPrivate [IN] - Load the common or the private properties?
  738. //
  739. // Return Value:
  740. // S_OK if successful, or other Win32 error as HRESULT error.
  741. //
  742. //--
  743. /////////////////////////////////////////////////////////////////////////////
  744. HRESULT CClusNode::HrLoadProperties(
  745. IN OUT CClusPropList & rcplPropList,
  746. IN BOOL bReadOnly,
  747. IN BOOL bPrivate
  748. )
  749. {
  750. HRESULT _hr = S_FALSE;
  751. DWORD _dwControlCode = 0;
  752. DWORD _sc = ERROR_SUCCESS;
  753. if ( bReadOnly )
  754. {
  755. _dwControlCode = bPrivate
  756. ? CLUSCTL_NODE_GET_RO_PRIVATE_PROPERTIES
  757. : CLUSCTL_NODE_GET_RO_COMMON_PROPERTIES;
  758. }
  759. else
  760. {
  761. _dwControlCode = bPrivate
  762. ? CLUSCTL_NODE_GET_PRIVATE_PROPERTIES
  763. : CLUSCTL_NODE_GET_COMMON_PROPERTIES;
  764. }
  765. _sc = rcplPropList.ScGetNodeProperties( m_hNode, _dwControlCode );
  766. _hr = HRESULT_FROM_WIN32( _sc );
  767. return _hr;
  768. } //*** CClusNode::HrLoadProperties()
  769. /////////////////////////////////////////////////////////////////////////////
  770. //++
  771. //
  772. // CClusNode::ScWriteProperties
  773. //
  774. // Description:
  775. // This virtual function does the actual saving of the property list to
  776. // the cluster.
  777. //
  778. // Arguments:
  779. // rcplPropList [IN] - The property list to save.
  780. // bPrivate [IN] - Save the common or the private properties?
  781. //
  782. // Return Value:
  783. // ERROR_SUCCESS if successful, or other Win32 error if not.
  784. //
  785. //--
  786. /////////////////////////////////////////////////////////////////////////////
  787. DWORD CClusNode::ScWriteProperties(
  788. const CClusPropList & rcplPropList,
  789. BOOL bPrivate
  790. )
  791. {
  792. DWORD dwControlCode = bPrivate ? CLUSCTL_NODE_SET_PRIVATE_PROPERTIES : CLUSCTL_NODE_SET_COMMON_PROPERTIES;
  793. DWORD nBytesReturned = 0;
  794. DWORD _sc = ERROR_SUCCESS;
  795. _sc = ClusterNodeControl(
  796. m_hNode,
  797. NULL,
  798. dwControlCode,
  799. rcplPropList,
  800. rcplPropList.CbBufferSize(),
  801. 0,
  802. 0,
  803. &nBytesReturned
  804. );
  805. return _sc;
  806. } //*** CClusNode::ScWriteProperties()
  807. //*************************************************************************//
  808. /////////////////////////////////////////////////////////////////////////////
  809. // CNodes class
  810. /////////////////////////////////////////////////////////////////////////////
  811. /////////////////////////////////////////////////////////////////////////////
  812. //++
  813. //
  814. // CNodes::CNodes
  815. //
  816. // Description:
  817. // Constructor. This class implements functionality common to all node
  818. // collections.
  819. //
  820. // Arguments:
  821. // None.
  822. //
  823. // Return Value:
  824. // None.
  825. //
  826. //--
  827. /////////////////////////////////////////////////////////////////////////////
  828. CNodes::CNodes( void )
  829. {
  830. m_pClusRefObject = NULL;
  831. } //*** CNodes::CNodes()
  832. /////////////////////////////////////////////////////////////////////////////
  833. //++
  834. //
  835. // CNodes::~CNodes
  836. //
  837. // Description:
  838. // Desctructor.
  839. //
  840. // Arguments:
  841. // None.
  842. //
  843. // Return Value:
  844. // None.
  845. //
  846. //--
  847. /////////////////////////////////////////////////////////////////////////////
  848. CNodes::~CNodes( void )
  849. {
  850. Clear();
  851. if ( m_pClusRefObject != NULL )
  852. {
  853. m_pClusRefObject->Release();
  854. m_pClusRefObject = NULL;
  855. } // if:
  856. } //*** CNodes::~CNodes()
  857. /////////////////////////////////////////////////////////////////////////////
  858. //++
  859. //
  860. // CNodes::Create
  861. //
  862. // Description:
  863. // Finish creating the object by doing things that cannot be done in
  864. // a light weight constructor.
  865. //
  866. // Arguments:
  867. // pClusRefObject [IN] - Wraps the cluster handle.
  868. //
  869. // Return Value:
  870. // S_OK if successful or E_POINTER if not.
  871. //
  872. //--
  873. /////////////////////////////////////////////////////////////////////////////
  874. HRESULT CNodes::Create( IN ISClusRefObject * pClusRefObject )
  875. {
  876. ASSERT( pClusRefObject != NULL );
  877. HRESULT _hr = E_POINTER;
  878. if ( pClusRefObject != NULL )
  879. {
  880. m_pClusRefObject = pClusRefObject;
  881. m_pClusRefObject->AddRef();
  882. _hr = S_OK;
  883. }
  884. return _hr;
  885. } //*** CNodes::Create()
  886. /////////////////////////////////////////////////////////////////////////////
  887. //++
  888. //
  889. // CNodes::Clear
  890. //
  891. // Description:
  892. // Release the objects in the vector and clean up the vector.
  893. //
  894. // Arguments:
  895. // None.
  896. //
  897. // Return Value:
  898. // None.
  899. //
  900. //--
  901. /////////////////////////////////////////////////////////////////////////////
  902. void CNodes::Clear( void )
  903. {
  904. ::ReleaseAndEmptyCollection< NodeList, CComObject< CClusNode > >( m_Nodes );
  905. } //*** CNodes::Clear()
  906. /////////////////////////////////////////////////////////////////////////////
  907. //++
  908. //
  909. // CNodes::FindItem
  910. //
  911. // Description:
  912. // Find the passed in node in the vector and return its index.
  913. //
  914. // Arguments:
  915. // pwszNodeName [IN] - The node to find.
  916. // pnIndex [OUT] - Catches the node's index.
  917. //
  918. // Return Value:
  919. // S_OK if successful, E_POINTER, or E_INVALIDARG.
  920. //
  921. //--
  922. /////////////////////////////////////////////////////////////////////////////
  923. HRESULT CNodes::FindItem(
  924. IN LPWSTR pwszNodeName,
  925. OUT UINT * pnIndex
  926. )
  927. {
  928. //ASSERT( pwszNodeName != NULL );
  929. //ASSERT( pnIndex != NULL );
  930. HRESULT _hr = E_POINTER;
  931. if ( ( pwszNodeName != NULL ) && ( pnIndex != NULL ) )
  932. {
  933. _hr = E_INVALIDARG;
  934. if ( ! m_Nodes.empty() )
  935. {
  936. CComObject< CClusNode > * pNode = NULL;
  937. NodeList::iterator first = m_Nodes.begin();
  938. NodeList::iterator last = m_Nodes.end();
  939. UINT _iIndex;
  940. for ( _iIndex = 0; first != last; first++, _iIndex++ )
  941. {
  942. pNode = *first;
  943. if ( pNode && ( lstrcmpi( pwszNodeName, pNode->Name() ) == 0 ) )
  944. {
  945. *pnIndex = _iIndex;
  946. _hr = S_OK;
  947. break;
  948. }
  949. }
  950. } // if:
  951. }
  952. return _hr;
  953. } //*** CNodes::FindItem( pwszNodeName )
  954. /////////////////////////////////////////////////////////////////////////////
  955. //++
  956. //
  957. // CNodes::FindItem
  958. //
  959. // Description:
  960. // Find the passed in node in the vector and return its index.
  961. //
  962. // Arguments:
  963. // pClusterNode [IN] - The node to find.
  964. // pnIndex [OUT] - Catches the node's index.
  965. //
  966. // Return Value:
  967. // S_OK if successful, E_POINTER, or E_INVALIDARG.
  968. //
  969. //--
  970. /////////////////////////////////////////////////////////////////////////////
  971. HRESULT CNodes::FindItem(
  972. IN ISClusNode * pClusterNode,
  973. OUT UINT * pnIndex
  974. )
  975. {
  976. //ASSERT( pClusterNode != NULL );
  977. //ASSERT( pnIndex != NULL );
  978. HRESULT _hr = E_POINTER;
  979. if ( ( pClusterNode != NULL ) && ( pnIndex != NULL ) )
  980. {
  981. CComBSTR bstrName;
  982. _hr = pClusterNode->get_Name( &bstrName );
  983. if ( SUCCEEDED( _hr ) )
  984. {
  985. _hr = FindItem( bstrName, pnIndex );
  986. }
  987. }
  988. return _hr;
  989. } //*** CNodes::FindItem( pClusterNode )
  990. /////////////////////////////////////////////////////////////////////////////
  991. //++
  992. //
  993. // CNodes::GetIndex
  994. //
  995. // Description:
  996. // Convert the passed in variant index into the real index in the
  997. // collection.
  998. //
  999. // Arguments:
  1000. // varIndex [IN] - The index to convert.
  1001. // pnIndex [OUT] - Catches the index.
  1002. //
  1003. // Return Value:
  1004. // S_OK if successful, E_POINTER, or E_INVALIDARG.
  1005. //
  1006. //--
  1007. /////////////////////////////////////////////////////////////////////////////
  1008. HRESULT CNodes::GetIndex(
  1009. IN VARIANT varIndex,
  1010. OUT UINT * pnIndex
  1011. )
  1012. {
  1013. //ASSERT( pnIndex != NULL );
  1014. HRESULT _hr = E_POINTER;
  1015. if ( pnIndex != NULL )
  1016. {
  1017. UINT nIndex = 0;
  1018. CComVariant v;
  1019. *pnIndex = 0;
  1020. v.Copy( &varIndex );
  1021. // Check to see if the index is a number.
  1022. _hr = v.ChangeType( VT_I4 );
  1023. if ( SUCCEEDED( _hr ) )
  1024. {
  1025. nIndex = v.lVal;
  1026. nIndex--; // Adjust index to be 0 relative instead of 1 relative
  1027. }
  1028. else
  1029. {
  1030. // Check to see if the index is a string.
  1031. _hr = v.ChangeType( VT_BSTR );
  1032. if ( SUCCEEDED( _hr ) )
  1033. {
  1034. // Search for the string.
  1035. _hr = FindItem( v.bstrVal, &nIndex );
  1036. }
  1037. }
  1038. // We found an index, now check the range.
  1039. if ( SUCCEEDED( _hr ) )
  1040. {
  1041. if ( nIndex < m_Nodes.size() )
  1042. {
  1043. *pnIndex = nIndex;
  1044. }
  1045. else
  1046. {
  1047. _hr = E_INVALIDARG;
  1048. }
  1049. }
  1050. }
  1051. return _hr;
  1052. } //*** CNodes::GetIndex()
  1053. /////////////////////////////////////////////////////////////////////////////
  1054. //++
  1055. //
  1056. // CNodes::GetItem
  1057. //
  1058. // Description:
  1059. // Return the item (Node) by name.
  1060. //
  1061. // Arguments:
  1062. // pwszNodeName [IN] - The name of the item requested.
  1063. // ppClusterNode [OUT] - Catches the item.
  1064. //
  1065. // Return Value:
  1066. // S_OK if successful, E_POINTER, or E_INVALIDARG.
  1067. //
  1068. //--
  1069. /////////////////////////////////////////////////////////////////////////////
  1070. HRESULT CNodes::GetItem(
  1071. IN LPWSTR pwszNodeName,
  1072. OUT ISClusNode ** ppClusterNode
  1073. )
  1074. {
  1075. //ASSERT( pwszNodeName != NULL );
  1076. //ASSERT( ppClusterNode != NULL );
  1077. HRESULT _hr = E_POINTER;
  1078. if ( ( pwszNodeName != NULL ) && ( ppClusterNode != NULL ) )
  1079. {
  1080. CComObject< CClusNode > * pNode = NULL;
  1081. NodeList::iterator first = m_Nodes.begin();
  1082. NodeList::iterator last = m_Nodes.end();
  1083. _hr = E_INVALIDARG;
  1084. for ( ; first != last; first++ )
  1085. {
  1086. pNode = *first;
  1087. if ( pNode && ( lstrcmpi( pwszNodeName, pNode->Name() ) == 0 ) )
  1088. {
  1089. _hr = pNode->QueryInterface( IID_ISClusNode, (void **) ppClusterNode );
  1090. break;
  1091. }
  1092. }
  1093. }
  1094. return _hr;
  1095. } //*** CNodes::GetItem()
  1096. /////////////////////////////////////////////////////////////////////////////
  1097. //++
  1098. //
  1099. // CNodes::GetItem
  1100. //
  1101. // Description:
  1102. // Return the item (Node) by index.
  1103. //
  1104. // Arguments:
  1105. // nIndex [IN] - The name of the item requested.
  1106. // ppClusterNode [OUT] - Catches the item.
  1107. //
  1108. // Return Value:
  1109. // S_OK if successful, E_POINTER, or E_INVALIDARG.
  1110. //
  1111. //--
  1112. /////////////////////////////////////////////////////////////////////////////
  1113. HRESULT CNodes::GetItem( IN UINT nIndex, OUT ISClusNode ** ppClusterNode )
  1114. {
  1115. //ASSERT( ppClusterNode != NULL );
  1116. HRESULT _hr = E_POINTER;
  1117. if ( ppClusterNode != NULL )
  1118. {
  1119. //
  1120. // Automation collections are 1-relative for languages like VB.
  1121. // We are 0-relative internally.
  1122. //
  1123. if ( ( --nIndex ) < m_Nodes.size() )
  1124. {
  1125. CComObject< CClusNode > * pNode = m_Nodes[ nIndex ];
  1126. _hr = pNode->QueryInterface( IID_ISClusNode, (void **) ppClusterNode );
  1127. }
  1128. else
  1129. {
  1130. _hr = E_INVALIDARG;
  1131. }
  1132. }
  1133. return _hr;
  1134. } //*** CNodes::GetItem()
  1135. /////////////////////////////////////////////////////////////////////////////
  1136. //++
  1137. //
  1138. // CNodes::GetNodeItem
  1139. //
  1140. // Description:
  1141. // Return the object (Node) at the passed in index.
  1142. //
  1143. // Arguments:
  1144. // varIndex [IN] - Contains the index requested.
  1145. // ppClusterNode [OUT] - Catches the item.
  1146. //
  1147. // Return Value:
  1148. // S_OK if successful, E_POINTER, or E_INVALIDARG.
  1149. //
  1150. //--
  1151. /////////////////////////////////////////////////////////////////////////////
  1152. HRESULT CNodes::GetNodeItem(
  1153. IN VARIANT varIndex,
  1154. OUT ISClusNode ** ppClusterNode
  1155. )
  1156. {
  1157. //ASSERT( ppClusterNode != NULL );
  1158. HRESULT _hr = E_POINTER;
  1159. if ( ppClusterNode != NULL )
  1160. {
  1161. CComObject<CClusNode> * pNode = NULL;
  1162. UINT nIndex = 0;
  1163. *ppClusterNode = NULL;
  1164. _hr = GetIndex( varIndex, &nIndex );
  1165. if ( SUCCEEDED( _hr ) )
  1166. {
  1167. pNode = m_Nodes[ nIndex ];
  1168. _hr = pNode->QueryInterface( IID_ISClusNode, (void **) ppClusterNode );
  1169. }
  1170. }
  1171. return _hr;
  1172. } //*** CNodes::GetNodeItem()
  1173. /////////////////////////////////////////////////////////////////////////////
  1174. //++
  1175. //
  1176. // CNodes::InsertAt
  1177. //
  1178. // Description:
  1179. // Insert the passed in node into the node list.
  1180. //
  1181. // Arguments:
  1182. // pClusNode [IN] - The node to add.
  1183. // pos [IN] - The position to insert the node at.
  1184. //
  1185. // Return Value:
  1186. // E_POINTER, E_INVALIDARG, or S_OK if successful.
  1187. //
  1188. //--
  1189. /////////////////////////////////////////////////////////////////////////////
  1190. HRESULT CNodes::InsertAt(
  1191. CComObject< CClusNode > * pClusNode,
  1192. size_t pos
  1193. )
  1194. {
  1195. //ASSERT( pClusNode != NULL );
  1196. HRESULT _hr = E_POINTER;
  1197. if ( pClusNode != NULL )
  1198. {
  1199. if ( pos < m_Nodes.size() )
  1200. {
  1201. NodeList::iterator first = m_Nodes.begin();
  1202. NodeList::iterator last = m_Nodes.end();
  1203. size_t _iIndex;
  1204. for ( _iIndex = 0; ( _iIndex < pos ) && ( first != last ); _iIndex++, first++ )
  1205. {
  1206. } // for:
  1207. m_Nodes.insert( first, pClusNode );
  1208. pClusNode->AddRef();
  1209. _hr = S_OK;
  1210. }
  1211. else
  1212. {
  1213. _hr = E_INVALIDARG;
  1214. }
  1215. }
  1216. return _hr;
  1217. } //*** CNodes::InsertAt()
  1218. /////////////////////////////////////////////////////////////////////////////
  1219. //++
  1220. //
  1221. // CNodes::RemoveAt
  1222. //
  1223. // Description:
  1224. // Remove the object from the vector at the passed in position.
  1225. //
  1226. // Arguments:
  1227. // pos [IN] - the position of the object to remove.
  1228. //
  1229. // Return Value:
  1230. // S_OK if successful, or E_INVALIDARG if the position is out of range.
  1231. //
  1232. //--
  1233. /////////////////////////////////////////////////////////////////////////////
  1234. HRESULT CNodes::RemoveAt( size_t pos )
  1235. {
  1236. CComObject<CClusNode> * pNode = NULL;
  1237. NodeList::iterator first = m_Nodes.begin();
  1238. NodeList::const_iterator last = m_Nodes.end();
  1239. HRESULT _hr = E_INVALIDARG;
  1240. size_t _iIndex;
  1241. for ( _iIndex = 0; ( _iIndex < pos ) && ( first != last ); _iIndex++, first++ )
  1242. {
  1243. } // for:
  1244. if ( first != last )
  1245. {
  1246. pNode = *first;
  1247. if ( pNode )
  1248. {
  1249. pNode->Release();
  1250. }
  1251. m_Nodes.erase( first );
  1252. _hr = S_OK;
  1253. }
  1254. return _hr;
  1255. } //*** CNodes::RemoveAt()
  1256. //*************************************************************************//
  1257. /////////////////////////////////////////////////////////////////////////////
  1258. // CClusNodes class
  1259. /////////////////////////////////////////////////////////////////////////////
  1260. /////////////////////////////////////////////////////////////////////////////
  1261. //++
  1262. //
  1263. // CClusNodes::CClusNodes
  1264. //
  1265. // Description:
  1266. // Constructor.
  1267. //
  1268. // Arguments:
  1269. // None.
  1270. //
  1271. // Return Value:
  1272. // None.
  1273. //
  1274. //--
  1275. /////////////////////////////////////////////////////////////////////////////
  1276. CClusNodes::CClusNodes( void )
  1277. {
  1278. m_piids = (const IID *) iidCClusNodes;
  1279. m_piidsSize = ARRAYSIZE( iidCClusNodes );
  1280. } //*** CClusNodes::CClusNodes()
  1281. /////////////////////////////////////////////////////////////////////////////
  1282. //++
  1283. //
  1284. // CClusNodes::~CClusNodes
  1285. //
  1286. // Description:
  1287. // destructor.
  1288. //
  1289. // Arguments:
  1290. // None.
  1291. //
  1292. // Return Value:
  1293. // None.
  1294. //
  1295. //--
  1296. /////////////////////////////////////////////////////////////////////////////
  1297. CClusNodes::~CClusNodes( void )
  1298. {
  1299. Clear();
  1300. } //*** CClusNodes::~CClusNodes()
  1301. /////////////////////////////////////////////////////////////////////////////
  1302. //++
  1303. //
  1304. // CClusNodes::get_Count
  1305. //
  1306. // Description:
  1307. // Return the count of objects (Nodes) in the collection.
  1308. //
  1309. // Arguments:
  1310. // plCount [OUT] - Catches the count.
  1311. //
  1312. // Return Value:
  1313. // S_OK if successful, or E_POINTER.
  1314. //
  1315. //--
  1316. /////////////////////////////////////////////////////////////////////////////
  1317. STDMETHODIMP CClusNodes::get_Count( OUT long * plCount )
  1318. {
  1319. //ASSERT( plCount != NULL );
  1320. HRESULT _hr = E_POINTER;
  1321. if ( plCount != NULL )
  1322. {
  1323. *plCount = m_Nodes.size();
  1324. _hr = S_OK;
  1325. }
  1326. return _hr;
  1327. } //*** CClusNodes::get_Count()
  1328. /////////////////////////////////////////////////////////////////////////////
  1329. //++
  1330. //
  1331. // CClusNodes::get_Item
  1332. //
  1333. // Description:
  1334. // Return the object (Node) at the passed in index.
  1335. //
  1336. // Arguments:
  1337. // varIndex [IN] - Contains the index requested.
  1338. // ppClusterNode [OUT] - Catches the item.
  1339. //
  1340. // Return Value:
  1341. // S_OK if successful, E_POINTER, or E_INVALIDARG.
  1342. //
  1343. //--
  1344. /////////////////////////////////////////////////////////////////////////////
  1345. STDMETHODIMP CClusNodes::get_Item(
  1346. IN VARIANT varIndex,
  1347. OUT ISClusNode ** ppClusterNode
  1348. )
  1349. {
  1350. //ASSERT( ppClusterNode != NULL );
  1351. HRESULT _hr = E_POINTER;
  1352. if ( ppClusterNode != NULL )
  1353. {
  1354. _hr = GetNodeItem(varIndex, ppClusterNode);
  1355. } // if: args are not NULL
  1356. return _hr;
  1357. } //*** CClusNodes::get_Item()
  1358. /////////////////////////////////////////////////////////////////////////////
  1359. //++
  1360. //
  1361. // CClusNodes::get__NewEnum
  1362. //
  1363. // Description:
  1364. // Create and return a new enumeration for this collection.
  1365. //
  1366. // Arguments:
  1367. // ppunk [OUT] - Catches the new enumeration.
  1368. //
  1369. // Return Value:
  1370. // S_OK if successful, E_POINTER, or other HRESULT error.
  1371. //
  1372. //--
  1373. /////////////////////////////////////////////////////////////////////////////
  1374. STDMETHODIMP CClusNodes::get__NewEnum( IUnknown ** ppunk )
  1375. {
  1376. return ::HrNewIDispatchEnum< NodeList, CComObject< CClusNode > >( ppunk, m_Nodes );
  1377. } //*** CClusNodes::get__NewEnum()
  1378. /////////////////////////////////////////////////////////////////////////////
  1379. //++
  1380. //
  1381. // CClusNodes::Refresh
  1382. //
  1383. // Description:
  1384. // Load the collection from the cluster database.
  1385. //
  1386. // Arguments:
  1387. // None.
  1388. //
  1389. // Return Value:
  1390. // S_OK if successful, E_POINTER, or Win32 error as HRESULT.
  1391. //
  1392. //--
  1393. /////////////////////////////////////////////////////////////////////////////
  1394. STDMETHODIMP CClusNodes::Refresh( void )
  1395. {
  1396. HCLUSENUM hEnum = NULL;
  1397. HCLUSTER hCluster = NULL;
  1398. DWORD _sc = ERROR_SUCCESS;
  1399. HRESULT _hr = S_OK;
  1400. _hr = m_pClusRefObject->get_Handle( (ULONG_PTR *) &hCluster );
  1401. if ( SUCCEEDED( _hr ) )
  1402. {
  1403. hEnum = ::ClusterOpenEnum( hCluster, CLUSTER_ENUM_NODE );
  1404. if ( hEnum != NULL )
  1405. {
  1406. int _nIndex = 0;
  1407. DWORD dwType;
  1408. LPWSTR pszName = NULL;
  1409. CComObject< CClusNode > * pNode = NULL;
  1410. Clear();
  1411. for( _nIndex = 0, _hr = S_OK; SUCCEEDED( _hr ); _nIndex++ )
  1412. {
  1413. _sc = ::WrapClusterEnum( hEnum, _nIndex, &dwType, &pszName );
  1414. if ( _sc == ERROR_NO_MORE_ITEMS )
  1415. {
  1416. _hr = S_OK;
  1417. break;
  1418. }
  1419. else if ( _sc == ERROR_SUCCESS )
  1420. {
  1421. _hr = CComObject< CClusNode >::CreateInstance( &pNode );
  1422. if ( SUCCEEDED( _hr ) )
  1423. {
  1424. CSmartPtr< ISClusRefObject > ptrRefObject( m_pClusRefObject );
  1425. CSmartPtr< CComObject< CClusNode > > ptrNode( pNode );
  1426. _hr = ptrNode->Open( ptrRefObject, pszName );
  1427. if ( SUCCEEDED( _hr ) )
  1428. {
  1429. ptrNode->AddRef();
  1430. m_Nodes.insert( m_Nodes.end(), ptrNode );
  1431. }
  1432. }
  1433. ::LocalFree( pszName );
  1434. pszName = NULL;
  1435. }
  1436. else
  1437. {
  1438. _hr = HRESULT_FROM_WIN32( _sc );
  1439. }
  1440. }
  1441. ::ClusterCloseEnum( hEnum );
  1442. }
  1443. else
  1444. {
  1445. _sc = GetLastError();
  1446. _hr = HRESULT_FROM_WIN32( _sc );
  1447. }
  1448. }
  1449. return _hr;
  1450. } //*** CClusNodes::Refresh()
  1451. //*************************************************************************//
  1452. /////////////////////////////////////////////////////////////////////////////
  1453. // CClusResGroupPreferredOwnerNodes class
  1454. /////////////////////////////////////////////////////////////////////////////
  1455. /////////////////////////////////////////////////////////////////////////////
  1456. //++
  1457. //
  1458. // CClusResGroupPreferredOwnerNodes::CClusResGroupPreferredOwnerNodes
  1459. //
  1460. // Description:
  1461. // Constructor.
  1462. //
  1463. // Arguments:
  1464. // None.
  1465. //
  1466. // Return Value:
  1467. // None.
  1468. //
  1469. //--
  1470. /////////////////////////////////////////////////////////////////////////////
  1471. CClusResGroupPreferredOwnerNodes::CClusResGroupPreferredOwnerNodes( void )
  1472. {
  1473. m_bModified = FALSE;
  1474. m_piids = (const IID *) iidCClusResGroupPreferredOwnerNodes;
  1475. m_piidsSize = ARRAYSIZE( iidCClusResGroupPreferredOwnerNodes );
  1476. } //*** CClusResGroupPreferredOwnerNodes::CClusResGroupPreferredOwnerNodes()
  1477. /////////////////////////////////////////////////////////////////////////////
  1478. //++
  1479. //
  1480. // CClusResGroupPreferredOwnerNodes::~CClusResGroupPreferredOwnerNodes
  1481. //
  1482. // Description:
  1483. // destructor.
  1484. //
  1485. // Arguments:
  1486. // None.
  1487. //
  1488. // Return Value:
  1489. // None.
  1490. //
  1491. //--
  1492. /////////////////////////////////////////////////////////////////////////////
  1493. CClusResGroupPreferredOwnerNodes::~CClusResGroupPreferredOwnerNodes( void )
  1494. {
  1495. Clear();
  1496. } //*** CClusResGroupPreferredOwnerNodes::~CClusResGroupPreferredOwnerNodes()
  1497. /////////////////////////////////////////////////////////////////////////////
  1498. //++
  1499. //
  1500. // CClusResGroupPreferredOwnerNodes::Create
  1501. //
  1502. // Description:
  1503. // Finish creating the object by doing things that cannot be done in
  1504. // a light weight constructor.
  1505. //
  1506. // Arguments:
  1507. // pClusRefObject [IN] - Wraps the cluster handle.
  1508. // hGroup [IN] - Group the collection belongs to.
  1509. //
  1510. // Return Value:
  1511. // S_OK if successful or E_POINTER if not.
  1512. //
  1513. //--
  1514. /////////////////////////////////////////////////////////////////////////////
  1515. HRESULT CClusResGroupPreferredOwnerNodes::Create(
  1516. IN ISClusRefObject * pClusRefObject,
  1517. IN HGROUP hGroup
  1518. )
  1519. {
  1520. HRESULT _hr = E_POINTER;
  1521. _hr = CNodes::Create( pClusRefObject );
  1522. if ( SUCCEEDED( _hr ) )
  1523. {
  1524. m_hGroup = hGroup;
  1525. } // if:
  1526. return _hr;
  1527. } //*** CClusResGroupPreferredOwnerNodes::Create()
  1528. /////////////////////////////////////////////////////////////////////////////
  1529. //++
  1530. //
  1531. // CClusResGroupPreferredOwnerNodes::get_Count
  1532. //
  1533. // Description:
  1534. // Return the count of objects (Nodes) in the collection.
  1535. //
  1536. // Arguments:
  1537. // plCount [OUT] - Catches the count.
  1538. //
  1539. // Return Value:
  1540. // S_OK if successful, or E_POINTER.
  1541. //
  1542. //--
  1543. /////////////////////////////////////////////////////////////////////////////
  1544. STDMETHODIMP CClusResGroupPreferredOwnerNodes::get_Count(
  1545. OUT long * plCount
  1546. )
  1547. {
  1548. //ASSERT( plCount != NULL );
  1549. HRESULT _hr = E_POINTER;
  1550. if ( plCount != NULL )
  1551. {
  1552. *plCount = m_Nodes.size();
  1553. _hr = S_OK;
  1554. }
  1555. return _hr;
  1556. } //*** CClusResGroupPreferredOwnerNodes::get_Count()
  1557. /////////////////////////////////////////////////////////////////////////////
  1558. //++
  1559. //
  1560. // CClusResGroupPreferredOwnerNodes::get_Item
  1561. //
  1562. // Description:
  1563. // Return the object (Node) at the passed in index.
  1564. //
  1565. // Arguments:
  1566. // varIndex [IN] - Contains the index requested.
  1567. // ppClusterNode [OUT] - Catches the item.
  1568. //
  1569. // Return Value:
  1570. // S_OK if successful, E_POINTER, or E_INVALIDARG.
  1571. //
  1572. //--
  1573. /////////////////////////////////////////////////////////////////////////////
  1574. STDMETHODIMP CClusResGroupPreferredOwnerNodes::get_Item(
  1575. IN VARIANT varIndex,
  1576. OUT ISClusNode ** ppClusterNode
  1577. )
  1578. {
  1579. //ASSERT( ppClusterNode != NULL );
  1580. HRESULT _hr = E_POINTER;
  1581. if ( ppClusterNode != NULL )
  1582. {
  1583. _hr = GetNodeItem( varIndex, ppClusterNode );
  1584. }
  1585. return _hr;
  1586. } //*** CClusResGroupPreferredOwnerNodes::get_Item()
  1587. /////////////////////////////////////////////////////////////////////////////
  1588. //++
  1589. //
  1590. // CClusResGroupPreferredOwnerNodes::get__NewEnum
  1591. //
  1592. // Description:
  1593. // Create and return a new enumeration for this collection.
  1594. //
  1595. // Arguments:
  1596. // ppunk [OUT] - Catches the new enumeration.
  1597. //
  1598. // Return Value:
  1599. // S_OK if successful, E_POINTER, or other HRESULT error.
  1600. //
  1601. //--
  1602. /////////////////////////////////////////////////////////////////////////////
  1603. STDMETHODIMP CClusResGroupPreferredOwnerNodes::get__NewEnum(
  1604. IUnknown ** ppunk
  1605. )
  1606. {
  1607. return ::HrNewIDispatchEnum< NodeList, CComObject< CClusNode > >( ppunk, m_Nodes );
  1608. } //*** CClusResGroupPreferredOwnerNodes::get__NewEnum()
  1609. /////////////////////////////////////////////////////////////////////////////
  1610. //++
  1611. //
  1612. // CClusResGroupPreferredOwnerNodes::Refresh
  1613. //
  1614. // Description:
  1615. // Loads the resource group preferred owner node collection from the
  1616. // cluster.
  1617. //
  1618. // Arguments:
  1619. // None.
  1620. //
  1621. // Return Value:
  1622. // S_OK if successful, or other HRESULT error.
  1623. //
  1624. //--
  1625. /////////////////////////////////////////////////////////////////////////////
  1626. STDMETHODIMP CClusResGroupPreferredOwnerNodes::Refresh( void )
  1627. {
  1628. HRESULT _hr = S_OK;
  1629. HGROUPENUM hEnum = NULL;
  1630. DWORD _sc = ERROR_SUCCESS;
  1631. hEnum = ::ClusterGroupOpenEnum( m_hGroup, CLUSTER_GROUP_ENUM_NODES );
  1632. if ( hEnum != NULL )
  1633. {
  1634. int _nIndex = 0;
  1635. DWORD dwType = 0;
  1636. LPWSTR pszName = NULL;
  1637. CComObject< CClusNode > * pNode = NULL;
  1638. Clear();
  1639. m_bModified = FALSE;
  1640. for( _nIndex = 0, _hr = S_OK; SUCCEEDED( _hr ); _nIndex++ )
  1641. {
  1642. _sc = WrapClusterGroupEnum( hEnum, _nIndex, &dwType, &pszName );
  1643. if ( _sc == ERROR_NO_MORE_ITEMS )
  1644. {
  1645. _hr = S_OK;
  1646. break;
  1647. }
  1648. else if ( _sc == ERROR_SUCCESS )
  1649. {
  1650. _hr = CComObject< CClusNode >::CreateInstance( &pNode );
  1651. if ( SUCCEEDED( _hr ) )
  1652. {
  1653. CSmartPtr< ISClusRefObject > ptrRefObject( m_pClusRefObject );
  1654. CSmartPtr< CComObject< CClusNode > > ptrNode( pNode );
  1655. _hr = ptrNode->Open( ptrRefObject, pszName );
  1656. if ( SUCCEEDED( _hr ) )
  1657. {
  1658. ptrNode->AddRef();
  1659. m_Nodes.insert( m_Nodes.end(), ptrNode );
  1660. }
  1661. }
  1662. ::LocalFree( pszName );
  1663. pszName = NULL;
  1664. }
  1665. else
  1666. {
  1667. _hr = HRESULT_FROM_WIN32( _sc );
  1668. }
  1669. }
  1670. ::ClusterGroupCloseEnum( hEnum );
  1671. }
  1672. else
  1673. {
  1674. _sc = GetLastError();
  1675. _hr = HRESULT_FROM_WIN32( _sc );
  1676. }
  1677. return _hr;
  1678. } //*** CClusResGroupPreferredOwnerNodes::Refresh()
  1679. /////////////////////////////////////////////////////////////////////////////
  1680. //++
  1681. //
  1682. // CClusResGroupPreferredOwnerNodes::InsertItem
  1683. //
  1684. // Description:
  1685. // Insert the node into the groups preferred owners list.
  1686. //
  1687. // Arguments:
  1688. // pNode [IN] - Node to add to the preferred owners list.
  1689. // nPosition [IN] - Where in the list to insert the node.
  1690. //
  1691. // Return Value:
  1692. // S_OK if successful, or other HRESULT error.
  1693. //
  1694. //--
  1695. /////////////////////////////////////////////////////////////////////////////
  1696. STDMETHODIMP CClusResGroupPreferredOwnerNodes::InsertItem(
  1697. IN ISClusNode * pNode,
  1698. IN long nPosition
  1699. )
  1700. {
  1701. //ASSERT( pNode != NULL );
  1702. HRESULT _hr = E_POINTER;
  1703. if ( pNode != NULL )
  1704. {
  1705. UINT _nIndex = 0;
  1706. _hr = FindItem( pNode, &_nIndex );
  1707. if ( FAILED( _hr ) )
  1708. {
  1709. _hr = E_INVALIDARG;
  1710. if ( nPosition > 0 )
  1711. {
  1712. SSIZE_T pos = (SSIZE_T) nPosition - 1; // convert to zero base
  1713. if ( pos >= 0 )
  1714. {
  1715. CComObject< CClusNode > * _pNode = NULL;
  1716. _hr = pNode->QueryInterface( IID_CClusNode, (void **) &_pNode );
  1717. if ( SUCCEEDED( _hr ) )
  1718. {
  1719. if ( ( m_Nodes.empty() ) || ( pos == 0 ) )
  1720. {
  1721. _pNode->AddRef();
  1722. m_Nodes.insert( m_Nodes.begin(), _pNode );
  1723. } // if: list is empty or the insert index is zero then insert at the beginning
  1724. else if ( pos >= m_Nodes.size() )
  1725. {
  1726. _pNode->AddRef();
  1727. m_Nodes.insert( m_Nodes.end(), _pNode );
  1728. } // else if: pos equals the end, append
  1729. else
  1730. {
  1731. _hr = InsertAt( _pNode, pos );
  1732. } // else: try to insert it where is belongs
  1733. m_bModified = TRUE;
  1734. pNode->Release();
  1735. } // if:
  1736. } // if: index is greater than zero
  1737. } // if: nPosition must be greater than zero!
  1738. } // if: node was not already in the collection
  1739. else
  1740. {
  1741. _hr = E_INVALIDARG;
  1742. } // else: node was already in the collectoin
  1743. }
  1744. return _hr;
  1745. } //*** CClusResGroupPreferredOwnerNodes::InsertItem()
  1746. /////////////////////////////////////////////////////////////////////////////
  1747. //++
  1748. //
  1749. // CClusResGroupPreferredOwnerNodes::AddItem
  1750. //
  1751. // Description:
  1752. // Add the node into the groups preferred owners list.
  1753. //
  1754. // Arguments:
  1755. // pNode [IN] - Node to add to the preferred owners list.
  1756. //
  1757. // Return Value:
  1758. // S_OK if successful, or other HRESULT error.
  1759. //
  1760. //--
  1761. /////////////////////////////////////////////////////////////////////////////
  1762. STDMETHODIMP CClusResGroupPreferredOwnerNodes::AddItem(
  1763. IN ISClusNode * pNode
  1764. )
  1765. {
  1766. //ASSERT( pNode != NULL );
  1767. HRESULT _hr = E_POINTER;
  1768. if ( pNode != NULL )
  1769. {
  1770. UINT _nIndex = 0;
  1771. _hr = FindItem( pNode, &_nIndex );
  1772. if ( FAILED( _hr ) )
  1773. {
  1774. CComObject< CClusNode > * _pNode = NULL;
  1775. _hr = pNode->QueryInterface( IID_CClusNode, (void **) &_pNode );
  1776. if ( SUCCEEDED( _hr ) )
  1777. {
  1778. m_Nodes.insert( m_Nodes.end(), _pNode );
  1779. m_bModified = TRUE;
  1780. } // if:
  1781. } // if: node was not found in the collection already
  1782. else
  1783. {
  1784. _hr = E_INVALIDARG;
  1785. } // esle: node was found
  1786. }
  1787. return _hr;
  1788. } //*** CClusResGroupPreferredOwnerNodes::AddItem()
  1789. /////////////////////////////////////////////////////////////////////////////
  1790. //++
  1791. //
  1792. // CClusResGroupPreferredOwnerNodes::RemoveItem
  1793. //
  1794. // Description:
  1795. // Remove the item at the passed in index.
  1796. //
  1797. // Arguments:
  1798. // varIndex [IN] - The index of the item to remove.
  1799. //
  1800. // Return Value:
  1801. // S_OK if successful, E_POINTER, or E_INVALIDARG.
  1802. //
  1803. //--
  1804. /////////////////////////////////////////////////////////////////////////////
  1805. STDMETHODIMP CClusResGroupPreferredOwnerNodes::RemoveItem(
  1806. IN VARIANT varIndex
  1807. )
  1808. {
  1809. HRESULT _hr = S_OK;
  1810. UINT _nIndex = 0;
  1811. _hr = GetIndex( varIndex, &_nIndex );
  1812. if ( SUCCEEDED( _hr ) )
  1813. {
  1814. _hr = RemoveAt( _nIndex );
  1815. if ( SUCCEEDED( _hr ) )
  1816. {
  1817. m_bModified = TRUE;
  1818. } // if:
  1819. } // if:
  1820. return _hr;
  1821. } //*** CClusResGroupPreferredOwnerNodes::RemoveItem()
  1822. /////////////////////////////////////////////////////////////////////////////
  1823. //++
  1824. //
  1825. // CClusResGroupPreferredOwnerNodes::get_Modified
  1826. //
  1827. // Description:
  1828. // Has this collection been modified?
  1829. //
  1830. // Arguments:
  1831. // pvarModified [OUT] - Catches the modified state.
  1832. //
  1833. // Return Value:
  1834. // S_OK if successful, or E_POINTER.
  1835. //
  1836. //--
  1837. /////////////////////////////////////////////////////////////////////////////
  1838. STDMETHODIMP CClusResGroupPreferredOwnerNodes::get_Modified(
  1839. OUT VARIANT * pvarModified
  1840. )
  1841. {
  1842. //ASSERT( pvarModified != NULL );
  1843. HRESULT _hr = E_POINTER;
  1844. if ( pvarModified != NULL )
  1845. {
  1846. pvarModified->vt = VT_BOOL;
  1847. if ( m_bModified )
  1848. {
  1849. pvarModified->boolVal = VARIANT_TRUE;
  1850. } // if: the collection has been modified.
  1851. else
  1852. {
  1853. pvarModified->boolVal = VARIANT_FALSE;
  1854. } // else: the collection has not been modified.
  1855. _hr = S_OK;
  1856. }
  1857. return _hr;
  1858. } //*** CClusResGroupPreferredOwnerNodes::get_Modified()
  1859. /////////////////////////////////////////////////////////////////////////////
  1860. //++
  1861. //
  1862. // CClusResGroupPreferredOwnerNodes::SaveChanges
  1863. //
  1864. // Description:
  1865. // Saves the changes to this collection of preferred owner nodes to
  1866. // the cluster database.
  1867. //
  1868. // Arguments:
  1869. // None.
  1870. //
  1871. // Return Value:
  1872. // S_OK if successful, or other HRESULT error.
  1873. //
  1874. //--
  1875. /////////////////////////////////////////////////////////////////////////////
  1876. STDMETHODIMP CClusResGroupPreferredOwnerNodes::SaveChanges( void )
  1877. {
  1878. HRESULT _hr = S_OK;
  1879. if ( m_bModified )
  1880. {
  1881. size_t _cNodes;
  1882. HNODE * _phNodes = NULL;
  1883. _cNodes = m_Nodes.size();
  1884. _phNodes = new HNODE [ _cNodes ];
  1885. if ( _phNodes != NULL )
  1886. {
  1887. NodeList::const_iterator _itCurrent = m_Nodes.begin();
  1888. NodeList::const_iterator _itLast = m_Nodes.end();
  1889. size_t _iIndex;
  1890. DWORD _sc = ERROR_SUCCESS;
  1891. CComObject< CClusNode > * _pOwnerNode = NULL;
  1892. ZeroMemory( _phNodes, _cNodes * sizeof( HNODE ) );
  1893. for ( _iIndex = 0; _itCurrent != _itLast; _itCurrent++, _iIndex++ )
  1894. {
  1895. _pOwnerNode = *_itCurrent;
  1896. _phNodes[ _iIndex ] = _pOwnerNode->RhNode();
  1897. } // for:
  1898. _sc = ::SetClusterGroupNodeList( m_hGroup, _cNodes, _phNodes );
  1899. _hr = HRESULT_FROM_WIN32( _sc );
  1900. if ( SUCCEEDED( _hr ) )
  1901. {
  1902. m_bModified = FALSE;
  1903. } // if:
  1904. delete [] _phNodes;
  1905. }
  1906. else
  1907. {
  1908. _hr = E_OUTOFMEMORY;
  1909. }
  1910. }
  1911. return _hr;
  1912. } //*** CClusResGroupPreferredOwnerNodes::SaveChanges()
  1913. //*************************************************************************//
  1914. /////////////////////////////////////////////////////////////////////////////
  1915. // CClusResPossibleOwnerNodes class
  1916. /////////////////////////////////////////////////////////////////////////////
  1917. /////////////////////////////////////////////////////////////////////////////
  1918. //++
  1919. //
  1920. // CClusResPossibleOwnerNodes::CClusResPossibleOwnerNodes
  1921. //
  1922. // Description:
  1923. // Constructor.
  1924. //
  1925. // Arguments:
  1926. // None.
  1927. //
  1928. // Return Value:
  1929. // None.
  1930. //
  1931. //--
  1932. /////////////////////////////////////////////////////////////////////////////
  1933. CClusResPossibleOwnerNodes::CClusResPossibleOwnerNodes( void )
  1934. {
  1935. m_piids = (const IID *) iidCClusResPossibleOwnerNodes;
  1936. m_piidsSize = ARRAYSIZE( iidCClusResPossibleOwnerNodes );
  1937. } //*** CClusResPossibleOwnerNodes::CClusResPossibleOwnerNodes()
  1938. /////////////////////////////////////////////////////////////////////////////
  1939. //++
  1940. //
  1941. // CClusResPossibleOwnerNodes::~CClusResPossibleOwnerNodes
  1942. //
  1943. // Description:
  1944. // destructor.
  1945. //
  1946. // Arguments:
  1947. // None.
  1948. //
  1949. // Return Value:
  1950. // None.
  1951. //
  1952. //--
  1953. /////////////////////////////////////////////////////////////////////////////
  1954. CClusResPossibleOwnerNodes::~CClusResPossibleOwnerNodes( void )
  1955. {
  1956. Clear();
  1957. } //*** CClusResPossibleOwnerNodes::~CClusResPossibleOwnerNodes()
  1958. /////////////////////////////////////////////////////////////////////////////
  1959. //++
  1960. //
  1961. // CClusResPossibleOwnerNodes::Create
  1962. //
  1963. // Description:
  1964. // Finish creating the object by doing things that cannot be done in
  1965. // a light weight constructor.
  1966. //
  1967. // Arguments:
  1968. // pClusRefObject [IN] - Wraps the cluster handle.
  1969. // hResource [IN] - Resource the collection belongs to.
  1970. //
  1971. // Return Value:
  1972. // S_OK if successful or E_POINTER if not.
  1973. //
  1974. //--
  1975. /////////////////////////////////////////////////////////////////////////////
  1976. HRESULT CClusResPossibleOwnerNodes::Create(
  1977. IN ISClusRefObject * pClusRefObject,
  1978. IN HRESOURCE hResource
  1979. )
  1980. {
  1981. HRESULT _hr = E_POINTER;
  1982. _hr = CNodes::Create( pClusRefObject );
  1983. if ( SUCCEEDED( _hr ) )
  1984. {
  1985. m_hResource = hResource;
  1986. } // if:
  1987. return _hr;
  1988. } //*** CClusResPossibleOwnerNodes::Create()
  1989. /////////////////////////////////////////////////////////////////////////////
  1990. //++
  1991. //
  1992. // CClusResPossibleOwnerNodes::get_Count
  1993. //
  1994. // Description:
  1995. // Return the count of objects (Nodes) in the collection.
  1996. //
  1997. // Arguments:
  1998. // plCount [OUT] - Catches the count.
  1999. //
  2000. // Return Value:
  2001. // S_OK if successful, or E_POINTER.
  2002. //
  2003. //--
  2004. /////////////////////////////////////////////////////////////////////////////
  2005. STDMETHODIMP CClusResPossibleOwnerNodes::get_Count( OUT long * plCount )
  2006. {
  2007. //ASSERT( plCount != NULL );
  2008. HRESULT _hr = E_POINTER;
  2009. if ( plCount != NULL )
  2010. {
  2011. *plCount = m_Nodes.size();
  2012. _hr = S_OK;
  2013. }
  2014. return _hr;
  2015. } //*** CClusResPossibleOwnerNodes::get_Count()
  2016. /////////////////////////////////////////////////////////////////////////////
  2017. //++
  2018. //
  2019. // CClusResPossibleOwnerNodes::get_Item
  2020. //
  2021. // Description:
  2022. // Return the object (Node) at the passed in index.
  2023. //
  2024. // Arguments:
  2025. // varIndex [IN] - Contains the index requested.
  2026. // ppClusterNode [OUT] - Catches the item.
  2027. //
  2028. // Return Value:
  2029. // S_OK if successful, E_POINTER, or E_INVALIDARG.
  2030. //
  2031. //--
  2032. /////////////////////////////////////////////////////////////////////////////
  2033. STDMETHODIMP CClusResPossibleOwnerNodes::get_Item(
  2034. IN VARIANT varIndex,
  2035. OUT ISClusNode ** ppClusterNode
  2036. )
  2037. {
  2038. //ASSERT( ppClusterNode != NULL );
  2039. HRESULT _hr = E_POINTER;
  2040. if ( ppClusterNode != NULL )
  2041. {
  2042. _hr = GetNodeItem( varIndex, ppClusterNode );
  2043. }
  2044. return _hr;
  2045. } //*** CClusResPossibleOwnerNodes::get_Item()
  2046. /////////////////////////////////////////////////////////////////////////////
  2047. //++
  2048. //
  2049. // CClusResPossibleOwnerNodes::get__NewEnum
  2050. //
  2051. // Description:
  2052. // Create and return a new enumeration for this collection.
  2053. //
  2054. // Arguments:
  2055. // ppunk [OUT] - Catches the new enumeration.
  2056. //
  2057. // Return Value:
  2058. // S_OK if successful, E_POINTER, or other HRESULT error.
  2059. //
  2060. //--
  2061. /////////////////////////////////////////////////////////////////////////////
  2062. STDMETHODIMP CClusResPossibleOwnerNodes::get__NewEnum( IUnknown ** ppunk )
  2063. {
  2064. return ::HrNewIDispatchEnum< NodeList, CComObject< CClusNode > >( ppunk, m_Nodes );
  2065. } //*** CClusResPossibleOwnerNodes::get__NewEnum()
  2066. /////////////////////////////////////////////////////////////////////////////
  2067. //++
  2068. //
  2069. // CClusResPossibleOwnerNodes::Refresh
  2070. //
  2071. // Description:
  2072. // Load the collection from the cluster database.
  2073. //
  2074. // Arguments:
  2075. // None.
  2076. //
  2077. // Return Value:
  2078. // S_OK if successful, E_POINTER, or Win32 error as HRESULT.
  2079. //
  2080. //--
  2081. /////////////////////////////////////////////////////////////////////////////
  2082. STDMETHODIMP CClusResPossibleOwnerNodes::Refresh( void )
  2083. {
  2084. HRESULT _hr = S_OK;
  2085. HRESENUM hEnum = NULL;
  2086. DWORD _sc = ERROR_SUCCESS;
  2087. hEnum = ::ClusterResourceOpenEnum( m_hResource, CLUSTER_RESOURCE_ENUM_NODES );
  2088. if ( hEnum != NULL )
  2089. {
  2090. int _nIndex = 0;
  2091. DWORD dwType;
  2092. LPWSTR pszName = NULL;
  2093. CComObject< CClusNode > * pNode = NULL;
  2094. Clear();
  2095. m_bModified = FALSE;
  2096. for( _nIndex = 0, _hr = S_OK; SUCCEEDED( _hr ); _nIndex++ )
  2097. {
  2098. _sc = ::WrapClusterResourceEnum( hEnum, _nIndex, &dwType, &pszName );
  2099. if ( _sc == ERROR_NO_MORE_ITEMS )
  2100. {
  2101. _hr = S_OK;
  2102. break;
  2103. }
  2104. else if ( _sc == ERROR_SUCCESS )
  2105. {
  2106. _hr = CComObject< CClusNode >::CreateInstance( &pNode );
  2107. if ( SUCCEEDED( _hr ) )
  2108. {
  2109. CSmartPtr< ISClusRefObject > ptrRefObject( m_pClusRefObject );
  2110. CSmartPtr< CComObject< CClusNode > > ptrNode( pNode );
  2111. _hr = ptrNode->Open( ptrRefObject, pszName );
  2112. if ( SUCCEEDED( _hr ) )
  2113. {
  2114. ptrNode->AddRef();
  2115. m_Nodes.insert( m_Nodes.end(), ptrNode );
  2116. }
  2117. }
  2118. ::LocalFree( pszName );
  2119. pszName = NULL;
  2120. }
  2121. else
  2122. {
  2123. _hr = HRESULT_FROM_WIN32( _sc );
  2124. }
  2125. }
  2126. ::ClusterResourceCloseEnum( hEnum );
  2127. }
  2128. else
  2129. {
  2130. _sc = GetLastError();
  2131. _hr = HRESULT_FROM_WIN32( _sc );
  2132. }
  2133. return _hr;
  2134. } //*** CClusResPossibleOwnerNodes::Refresh()
  2135. /////////////////////////////////////////////////////////////////////////////
  2136. //++
  2137. //
  2138. // CClusResPossibleOwnerNodes::AddItem
  2139. //
  2140. // Description:
  2141. // Add the passed in node to this resource's list of possible owners.
  2142. //
  2143. // Arguments:
  2144. // pNode [IN] - The node to add to the list.
  2145. //
  2146. // Return Value:
  2147. // S_OK if successful, E_POINTER, or other HRESULT error.
  2148. //
  2149. //--
  2150. /////////////////////////////////////////////////////////////////////////////
  2151. STDMETHODIMP CClusResPossibleOwnerNodes::AddItem( ISClusNode * pNode )
  2152. {
  2153. //ASSERT( pNode != NULL );
  2154. HRESULT _hr = E_POINTER;
  2155. if ( pNode != NULL )
  2156. {
  2157. // Fail if duplicate
  2158. UINT _nIndex = 0;
  2159. _hr = FindItem( pNode, &_nIndex );
  2160. if ( SUCCEEDED( _hr ) )
  2161. {
  2162. _hr = E_INVALIDARG;
  2163. }
  2164. else
  2165. {
  2166. CComObject< CClusNode > * _pNode = NULL;
  2167. _hr = pNode->QueryInterface( IID_CClusNode, (void **) &_pNode );
  2168. if ( SUCCEEDED( _hr ) )
  2169. {
  2170. DWORD _sc = ERROR_SUCCESS;
  2171. _sc = ::AddClusterResourceNode( m_hResource, _pNode->RhNode() );
  2172. if ( _sc == ERROR_SUCCESS )
  2173. {
  2174. _pNode->AddRef();
  2175. m_Nodes.insert( m_Nodes.end(), _pNode );
  2176. m_bModified = TRUE;
  2177. } // if:
  2178. _hr = HRESULT_FROM_WIN32( _sc );
  2179. pNode->Release();
  2180. } // if:
  2181. }
  2182. }
  2183. return _hr;
  2184. } //*** CClusResPossibleOwnerNodes::AddItem()
  2185. /////////////////////////////////////////////////////////////////////////////
  2186. //++
  2187. //
  2188. // CClusResPossibleOwnerNodes::RemoveItem
  2189. //
  2190. // Description:
  2191. // Remove the node at the passed in index from this resource's list of
  2192. // possible owners.
  2193. //
  2194. // Arguments:
  2195. // varIndex [IN] - holds the index of the node to remove.
  2196. //
  2197. // Return Value:
  2198. // S_OK if successful, or other HRESULT error.
  2199. //
  2200. //--
  2201. /////////////////////////////////////////////////////////////////////////////
  2202. STDMETHODIMP CClusResPossibleOwnerNodes::RemoveItem( VARIANT varIndex )
  2203. {
  2204. HRESULT _hr = S_OK;
  2205. UINT _nIndex = 0;
  2206. _hr = GetIndex( varIndex, &_nIndex );
  2207. if ( SUCCEEDED( _hr ) )
  2208. {
  2209. CComObject< CClusNode> * _pNode = m_Nodes[ _nIndex ];
  2210. DWORD _sc = ERROR_SUCCESS;
  2211. _sc = ::RemoveClusterResourceNode( m_hResource, _pNode->RhNode() );
  2212. _hr = HRESULT_FROM_WIN32( _sc );
  2213. if ( SUCCEEDED( _hr ) )
  2214. {
  2215. RemoveAt( _nIndex );
  2216. m_bModified = TRUE;
  2217. } // if:
  2218. } // if:
  2219. return _hr;
  2220. } //*** CClusResPossibleOwnerNodes::RemoveItem()
  2221. /////////////////////////////////////////////////////////////////////////////
  2222. //++
  2223. //
  2224. // CClusResPossibleOwnerNodes::get_Modified
  2225. //
  2226. // Description:
  2227. // Has this collection been modified?
  2228. //
  2229. // Arguments:
  2230. // pvarModified [OUT] - Catches the modified state.
  2231. //
  2232. // Return Value:
  2233. // S_OK if successful, or E_POINTER.
  2234. //
  2235. //--
  2236. /////////////////////////////////////////////////////////////////////////////
  2237. STDMETHODIMP CClusResPossibleOwnerNodes::get_Modified(
  2238. OUT VARIANT * pvarModified
  2239. )
  2240. {
  2241. //ASSERT( pvarModified != NULL );
  2242. HRESULT _hr = E_POINTER;
  2243. if ( pvarModified != NULL )
  2244. {
  2245. pvarModified->vt = VT_BOOL;
  2246. if ( m_bModified )
  2247. {
  2248. pvarModified->boolVal = VARIANT_TRUE;
  2249. } // if: the collection has been modified.
  2250. else
  2251. {
  2252. pvarModified->boolVal = VARIANT_FALSE;
  2253. } // else: the collection has not been modified.
  2254. _hr = S_OK;
  2255. }
  2256. return _hr;
  2257. } //*** CClusResPossibleOwnerNodes::get_Modified()
  2258. //*************************************************************************//
  2259. /////////////////////////////////////////////////////////////////////////////
  2260. // CClusResTypePossibleOwnerNodes class
  2261. /////////////////////////////////////////////////////////////////////////////
  2262. #if CLUSAPI_VERSION >= 0x0500
  2263. /////////////////////////////////////////////////////////////////////////////
  2264. //++
  2265. //
  2266. // CClusResTypePossibleOwnerNodes::CClusResTypePossibleOwnerNodes
  2267. //
  2268. // Description:
  2269. // Constructor.
  2270. //
  2271. // Arguments:
  2272. // None.
  2273. //
  2274. // Return Value:
  2275. // None.
  2276. //
  2277. //--
  2278. /////////////////////////////////////////////////////////////////////////////
  2279. CClusResTypePossibleOwnerNodes::CClusResTypePossibleOwnerNodes( void )
  2280. {
  2281. m_piids = (const IID *) iidCClusResTypePossibleOwnerNodes;
  2282. m_piidsSize = ARRAYSIZE( iidCClusResTypePossibleOwnerNodes );
  2283. } //*** CClusResTypePossibleOwnerNodes::CClusResTypePossibleOwnerNodes()
  2284. /////////////////////////////////////////////////////////////////////////////
  2285. //++
  2286. //
  2287. // CClusResTypePossibleOwnerNodes::~CClusResTypePossibleOwnerNodes
  2288. //
  2289. // Description:
  2290. // destructor.
  2291. //
  2292. // Arguments:
  2293. // None.
  2294. //
  2295. // Return Value:
  2296. // None.
  2297. //
  2298. //--
  2299. /////////////////////////////////////////////////////////////////////////////
  2300. CClusResTypePossibleOwnerNodes::~CClusResTypePossibleOwnerNodes( void )
  2301. {
  2302. Clear();
  2303. } //*** CClusResTypePossibleOwnerNodes::~CClusResTypePossibleOwnerNodes()
  2304. /////////////////////////////////////////////////////////////////////////////
  2305. //++
  2306. //
  2307. // CClusResTypePossibleOwnerNodes::Create
  2308. //
  2309. // Description:
  2310. // Finish creating the object by doing things that cannot be done in
  2311. // a light weight constructor.
  2312. //
  2313. // Arguments:
  2314. // pClusRefObject [IN] - Wraps the cluster handle.
  2315. // bstrResTypeName [IN] - Resource type name the collection belongs to.
  2316. //
  2317. // Return Value:
  2318. // S_OK if successful or E_POINTER if not.
  2319. //
  2320. //--
  2321. /////////////////////////////////////////////////////////////////////////////
  2322. HRESULT CClusResTypePossibleOwnerNodes::Create(
  2323. IN ISClusRefObject * pClusRefObject,
  2324. IN BSTR bstrResTypeName
  2325. )
  2326. {
  2327. HRESULT _hr = E_POINTER;
  2328. _hr = CNodes::Create( pClusRefObject );
  2329. if ( SUCCEEDED( _hr ) )
  2330. {
  2331. m_bstrResTypeName = bstrResTypeName;
  2332. } // if:
  2333. return _hr;
  2334. } //*** CClusResTypePossibleOwnerNodes::Create()
  2335. /////////////////////////////////////////////////////////////////////////////
  2336. //++
  2337. //
  2338. // CClusResTypePossibleOwnerNodes::get_Count
  2339. //
  2340. // Description:
  2341. // Return the count of objects (Nodes) in the collection.
  2342. //
  2343. // Arguments:
  2344. // plCount [OUT] - Catches the count.
  2345. //
  2346. // Return Value:
  2347. // S_OK if successful, or E_POINTER.
  2348. //
  2349. //--
  2350. /////////////////////////////////////////////////////////////////////////////
  2351. STDMETHODIMP CClusResTypePossibleOwnerNodes::get_Count( OUT long * plCount )
  2352. {
  2353. //ASSERT( plCount != NULL );
  2354. HRESULT _hr = E_POINTER;
  2355. if ( plCount != NULL )
  2356. {
  2357. *plCount = m_Nodes.size();
  2358. _hr = S_OK;
  2359. }
  2360. return _hr;
  2361. } //*** CClusResTypePossibleOwnerNodes::get_Count()
  2362. /////////////////////////////////////////////////////////////////////////////
  2363. //++
  2364. //
  2365. // CClusResTypePossibleOwnerNodes::get_Item
  2366. //
  2367. // Description:
  2368. // Return the object (Node) at the passed in index.
  2369. //
  2370. // Arguments:
  2371. // varIndex [IN] - Contains the index requested.
  2372. // ppClusterNode [OUT] - Catches the item.
  2373. //
  2374. // Return Value:
  2375. // S_OK if successful, E_POINTER, or E_INVALIDARG.
  2376. //
  2377. //--
  2378. /////////////////////////////////////////////////////////////////////////////
  2379. STDMETHODIMP CClusResTypePossibleOwnerNodes::get_Item(
  2380. IN VARIANT varIndex,
  2381. OUT ISClusNode ** ppClusterNode
  2382. )
  2383. {
  2384. //ASSERT( ppClusterNode != NULL );
  2385. HRESULT _hr = E_POINTER;
  2386. if ( ppClusterNode != NULL )
  2387. {
  2388. _hr = GetNodeItem( varIndex, ppClusterNode );
  2389. }
  2390. return _hr;
  2391. } //*** CClusResTypePossibleOwnerNodes::get_Item()
  2392. /////////////////////////////////////////////////////////////////////////////
  2393. //++
  2394. //
  2395. // CClusResTypePossibleOwnerNodes::get__NewEnum
  2396. //
  2397. // Description:
  2398. // Create and return a new enumeration for this collection.
  2399. //
  2400. // Arguments:
  2401. // ppunk [OUT] - Catches the new enumeration.
  2402. //
  2403. // Return Value:
  2404. // S_OK if successful, E_POINTER, or other HRESULT error.
  2405. //
  2406. //--
  2407. /////////////////////////////////////////////////////////////////////////////
  2408. STDMETHODIMP CClusResTypePossibleOwnerNodes::get__NewEnum(
  2409. OUT IUnknown ** ppunk
  2410. )
  2411. {
  2412. return ::HrNewIDispatchEnum< NodeList, CComObject< CClusNode > >( ppunk, m_Nodes );
  2413. } //*** CClusResTypePossibleOwnerNodes::get__NewEnum()
  2414. /////////////////////////////////////////////////////////////////////////////
  2415. //++
  2416. //
  2417. // CClusResTypePossibleOwnerNodes::Refresh
  2418. //
  2419. // Description:
  2420. // Load the resource type possible owner nodes collection from the
  2421. // cluster.
  2422. //
  2423. // Arguments:
  2424. // None.
  2425. //
  2426. // Return Value:
  2427. // S_OK if successful, or Win32 error ad HRESULT.
  2428. //
  2429. //--
  2430. /////////////////////////////////////////////////////////////////////////////
  2431. STDMETHODIMP CClusResTypePossibleOwnerNodes::Refresh( void )
  2432. {
  2433. HRESULT _hr = S_OK;
  2434. HRESTYPEENUM hEnum = NULL;
  2435. DWORD _sc = ERROR_SUCCESS;
  2436. HCLUSTER hCluster = NULL;
  2437. _hr = m_pClusRefObject->get_Handle( (ULONG_PTR *) &hCluster );
  2438. if ( SUCCEEDED( _hr ) )
  2439. {
  2440. hEnum = ::ClusterResourceTypeOpenEnum( hCluster, m_bstrResTypeName, CLUSTER_RESOURCE_TYPE_ENUM_NODES );
  2441. if ( hEnum != NULL )
  2442. {
  2443. int _nIndex = 0;
  2444. DWORD dwType;
  2445. LPWSTR pszName = NULL;
  2446. CComObject< CClusNode > * pNode = NULL;
  2447. Clear();
  2448. for ( _nIndex = 0, _hr = S_OK; SUCCEEDED( _hr ); _nIndex++ )
  2449. {
  2450. _sc = ::WrapClusterResourceTypeEnum( hEnum, _nIndex, &dwType, &pszName );
  2451. if ( _sc == ERROR_NO_MORE_ITEMS )
  2452. {
  2453. _hr = S_OK;
  2454. break;
  2455. }
  2456. else if ( _sc == ERROR_SUCCESS )
  2457. {
  2458. _hr = CComObject< CClusNode >::CreateInstance( &pNode );
  2459. if ( SUCCEEDED( _hr ) )
  2460. {
  2461. CSmartPtr< ISClusRefObject > ptrRefObject( m_pClusRefObject );
  2462. CSmartPtr< CComObject< CClusNode > > ptrNode( pNode );
  2463. _hr = ptrNode->Open( ptrRefObject, pszName );
  2464. if ( SUCCEEDED( _hr ) )
  2465. {
  2466. ptrNode->AddRef();
  2467. m_Nodes.insert( m_Nodes.end(), ptrNode );
  2468. }
  2469. }
  2470. ::LocalFree( pszName );
  2471. pszName = NULL;
  2472. } // else if: no error
  2473. else
  2474. {
  2475. _hr = HRESULT_FROM_WIN32( _sc );
  2476. } // else: error from WrapClusterResourceTypeEnum
  2477. } // for: repeat until error
  2478. ::ClusterResourceTypeCloseEnum( hEnum );
  2479. }
  2480. else
  2481. {
  2482. _sc = GetLastError();
  2483. _hr = HRESULT_FROM_WIN32( _sc );
  2484. }
  2485. } // if: we have a cluster handle
  2486. return _hr;
  2487. } //*** CClusResTypePossibleOwnerNodes::Refresh()
  2488. #endif // CLUSAPI_VERSION >= 0x0500