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.

3977 lines
109 KiB

  1. /////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1997-2000 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // ClusRes.cpp
  7. //
  8. // Description:
  9. // Implementation of the resource 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 "clusrest.h"
  27. #include "clusneti.h"
  28. #include "clusnode.h"
  29. /////////////////////////////////////////////////////////////////////////////
  30. // Global variables
  31. /////////////////////////////////////////////////////////////////////////////
  32. static const IID * iidCClusResource[] =
  33. {
  34. &IID_ISClusResource
  35. };
  36. static const IID * iidCClusResources[] =
  37. {
  38. &IID_ISClusResources
  39. };
  40. static const IID * iidCClusResDependencies[] =
  41. {
  42. &IID_ISClusResDependencies
  43. };
  44. static const IID * iidCClusResDependents[] =
  45. {
  46. &IID_ISClusResDependents
  47. };
  48. static const IID * iidCClusResGroupResources[] =
  49. {
  50. &IID_ISClusResGroupResources
  51. };
  52. static const IID * iidCClusResTypeResources[] =
  53. {
  54. &IID_ISClusResTypeResources
  55. };
  56. //*************************************************************************//
  57. /////////////////////////////////////////////////////////////////////////////
  58. // CClusResource class
  59. /////////////////////////////////////////////////////////////////////////////
  60. /////////////////////////////////////////////////////////////////////////////
  61. //++
  62. //
  63. // CClusResource::CClusResource
  64. //
  65. // Description:
  66. // Constructor.
  67. //
  68. // Arguments:
  69. // None.
  70. //
  71. // Return Value:
  72. // None.
  73. //
  74. //--
  75. /////////////////////////////////////////////////////////////////////////////
  76. CClusResource::CClusResource( void )
  77. {
  78. m_hResource = NULL;
  79. m_pClusRefObject = NULL;
  80. m_pCommonProperties = NULL;
  81. m_pPrivateProperties = NULL;
  82. m_pCommonROProperties = NULL;
  83. m_pPrivateROProperties = NULL;
  84. m_piids = (const IID *) iidCClusResource;
  85. m_piidsSize = ARRAYSIZE( iidCClusResource );
  86. } //*** CClusResource::CClusResource()
  87. /////////////////////////////////////////////////////////////////////////////
  88. //++
  89. //
  90. // CClusResource::~CClusResource
  91. //
  92. // Description:
  93. // Destructor.
  94. //
  95. // Arguments:
  96. // None.
  97. //
  98. // Return Value:
  99. // None.
  100. //
  101. //--
  102. /////////////////////////////////////////////////////////////////////////////
  103. CClusResource::~CClusResource( void )
  104. {
  105. if ( m_hResource != NULL )
  106. {
  107. ::CloseClusterResource( m_hResource );
  108. m_hResource = NULL;
  109. } // if:
  110. if ( m_pCommonProperties != NULL )
  111. {
  112. m_pCommonProperties->Release();
  113. m_pCommonProperties = NULL;
  114. } // if: release the property collection
  115. if ( m_pPrivateProperties != NULL )
  116. {
  117. m_pPrivateProperties->Release();
  118. m_pPrivateProperties = NULL;
  119. } // if: release the property collection
  120. if ( m_pCommonROProperties != NULL )
  121. {
  122. m_pCommonROProperties->Release();
  123. m_pCommonROProperties = NULL;
  124. } // if: release the property collection
  125. if ( m_pPrivateROProperties != NULL )
  126. {
  127. m_pPrivateROProperties->Release();
  128. m_pPrivateROProperties = NULL;
  129. } // if: release the property collection
  130. if ( m_pClusRefObject != NULL )
  131. {
  132. m_pClusRefObject->Release();
  133. m_pClusRefObject = NULL;
  134. } // if: release the property collection
  135. } //*** CClusResource::~CClusResource()
  136. /////////////////////////////////////////////////////////////////////////////
  137. //++
  138. //
  139. // CClusResource::Create
  140. //
  141. // Description:
  142. // Finish creating the object.
  143. //
  144. // Arguments:
  145. // pClusRefObject [IN] - Wraps the cluster handle.
  146. // hGroup [IN] - Group to create the resource in.
  147. // bstrResourceName [IN] - Name of the new resource.
  148. // bstrResourceType [IN] - The type of resource to create.
  149. // dwFlags [IN] - Creatation flags, separate resmon, etc.
  150. //
  151. // Return Value:
  152. // S_OK if successful, E_POINTER, or other HRESULT error.
  153. //
  154. //--
  155. /////////////////////////////////////////////////////////////////////////////
  156. HRESULT CClusResource::Create(
  157. IN ISClusRefObject * pClusRefObject,
  158. IN HGROUP hGroup,
  159. IN BSTR bstrResourceName,
  160. IN BSTR bstrResourceType,
  161. IN long dwFlags
  162. )
  163. {
  164. ASSERT( pClusRefObject != NULL );
  165. ASSERT( bstrResourceName != NULL );
  166. ASSERT( bstrResourceType != NULL );
  167. HRESULT _hr = E_POINTER;
  168. if ( ( pClusRefObject != NULL ) &&
  169. ( bstrResourceName != NULL ) &&
  170. ( bstrResourceType != NULL ) )
  171. {
  172. m_pClusRefObject = pClusRefObject;
  173. m_pClusRefObject->AddRef();
  174. m_hResource = ::CreateClusterResource( hGroup, bstrResourceName, bstrResourceType, dwFlags );
  175. if ( m_hResource == NULL )
  176. {
  177. DWORD _sc = GetLastError();
  178. _hr = HRESULT_FROM_WIN32( _sc );
  179. }
  180. else
  181. {
  182. m_bstrResourceName = bstrResourceName;
  183. _hr= S_OK;
  184. }
  185. }
  186. return _hr;
  187. } //*** CClusResource::Create()
  188. /////////////////////////////////////////////////////////////////////////////
  189. //++
  190. //
  191. // CClusResource::Open
  192. //
  193. // Description:
  194. // Open a handle to the resource object on the cluster.
  195. //
  196. // Arguments:
  197. // pClusRefObject [IN] - Wraps the cluster handle.
  198. // bstrResourceName [IN] - Name of the resource to open.
  199. //
  200. // Return Value:
  201. // S_OK if successful, E_POINTER, or other Win32 error as HRESULT.
  202. //
  203. //--
  204. /////////////////////////////////////////////////////////////////////////////
  205. HRESULT CClusResource::Open(
  206. IN ISClusRefObject * pClusRefObject,
  207. IN BSTR bstrResourceName
  208. )
  209. {
  210. ASSERT( pClusRefObject != NULL );
  211. ASSERT( bstrResourceName != NULL );
  212. HRESULT _hr = E_POINTER;
  213. if ( ( pClusRefObject != NULL ) && ( bstrResourceName != NULL ) )
  214. {
  215. m_pClusRefObject = pClusRefObject;
  216. m_pClusRefObject->AddRef();
  217. HCLUSTER hCluster;
  218. _hr = m_pClusRefObject->get_Handle( (ULONG_PTR *) &hCluster );
  219. if ( SUCCEEDED( _hr ) )
  220. {
  221. m_hResource = OpenClusterResource( hCluster, bstrResourceName );
  222. if ( m_hResource == NULL )
  223. {
  224. DWORD _sc = GetLastError();
  225. _hr = HRESULT_FROM_WIN32( _sc );
  226. }
  227. else
  228. {
  229. m_bstrResourceName = bstrResourceName;
  230. _hr = S_OK;
  231. }
  232. }
  233. }
  234. return _hr;
  235. } //*** CClusResource::Open()
  236. /////////////////////////////////////////////////////////////////////////////
  237. //++
  238. //
  239. // CClusResource::GetProperties
  240. //
  241. // Description:
  242. // Creates a property collection for this object type (Resource).
  243. //
  244. // Arguments:
  245. // ppProperties [OUT] - Catches the newly created collection.
  246. // bPrivate [IN] - Are these private properties? Or Common?
  247. // bReadOnly [IN] - Are these read only properties?
  248. //
  249. // Return Value:
  250. // S_OK if successful, or other HRESULT error.
  251. //
  252. //--
  253. /////////////////////////////////////////////////////////////////////////////
  254. HRESULT CClusResource::GetProperties(
  255. ISClusProperties ** ppProperties,
  256. BOOL bPrivate,
  257. BOOL bReadOnly
  258. )
  259. {
  260. //ASSERT( ppProperties != NULL );
  261. HRESULT _hr = E_POINTER;
  262. if ( ppProperties != NULL )
  263. {
  264. CComObject< CClusProperties > * pProperties = NULL;
  265. *ppProperties = NULL;
  266. _hr = CComObject< CClusProperties >::CreateInstance( &pProperties );
  267. if ( SUCCEEDED( _hr ) )
  268. {
  269. CSmartPtr< CComObject< CClusProperties > > ptrProperties( pProperties );
  270. _hr = ptrProperties->Create( this, bPrivate, bReadOnly );
  271. if ( SUCCEEDED( _hr ) )
  272. {
  273. _hr = ptrProperties->Refresh();
  274. if ( SUCCEEDED( _hr ) )
  275. {
  276. _hr = ptrProperties->QueryInterface( IID_ISClusProperties, (void **) ppProperties );
  277. if ( SUCCEEDED( _hr ) )
  278. {
  279. ptrProperties->AddRef();
  280. if ( bPrivate )
  281. {
  282. if ( bReadOnly )
  283. {
  284. m_pPrivateROProperties = ptrProperties;
  285. }
  286. else
  287. {
  288. m_pPrivateProperties = ptrProperties;
  289. }
  290. }
  291. else
  292. {
  293. if ( bReadOnly )
  294. {
  295. m_pCommonROProperties = ptrProperties;
  296. }
  297. else
  298. {
  299. m_pCommonProperties = ptrProperties;
  300. }
  301. }
  302. }
  303. }
  304. }
  305. }
  306. }
  307. return _hr;
  308. } //*** CClusResource::GetProperties()
  309. /////////////////////////////////////////////////////////////////////////////
  310. //++
  311. //
  312. // CClusResource::get_Handle
  313. //
  314. // Description:
  315. // Return the handle to this object (Resource).
  316. //
  317. // Arguments:
  318. // phandle [OUT] - Catches the handle.
  319. //
  320. // Return Value:
  321. // S_OK if successful, or E_POINTER if not.
  322. //
  323. //--
  324. /////////////////////////////////////////////////////////////////////////////
  325. STDMETHODIMP CClusResource::get_Handle(
  326. OUT ULONG_PTR * phandle
  327. )
  328. {
  329. //ASSERT( phandle != NULL );
  330. HRESULT _hr = E_POINTER;
  331. if ( phandle != NULL )
  332. {
  333. *phandle = (ULONG_PTR) m_hResource;
  334. _hr = S_OK;
  335. }
  336. return _hr;
  337. } //*** CClusResource::get_Handle()
  338. /////////////////////////////////////////////////////////////////////////////
  339. //++
  340. //
  341. // CClusResource::Close
  342. //
  343. // Description:
  344. // Close the handle to the cluster object (Resource).
  345. //
  346. // Arguments:
  347. // None.
  348. //
  349. // Return Value:
  350. // S_OK if successful, E_POINTER, or other Win32 error as HRESULT.
  351. //
  352. //--
  353. /////////////////////////////////////////////////////////////////////////////
  354. STDMETHODIMP CClusResource::Close( void )
  355. {
  356. HRESULT _hr = E_POINTER;
  357. if ( m_hResource != NULL )
  358. {
  359. if ( CloseClusterResource( m_hResource ) )
  360. {
  361. m_hResource = NULL;
  362. _hr = S_OK;
  363. }
  364. else
  365. {
  366. DWORD _sc = GetLastError();
  367. _hr = HRESULT_FROM_WIN32( _sc );
  368. }
  369. }
  370. return _hr;
  371. } //*** CClusResource::Close()
  372. /////////////////////////////////////////////////////////////////////////////
  373. //++
  374. //
  375. // CClusResource::put_Name
  376. //
  377. // Description:
  378. // Change the name of this object (Resource).
  379. //
  380. // Arguments:
  381. // bstrResourceName [IN] - The new name.
  382. //
  383. // Return Value:
  384. // S_OK if successful, E_POINTER, or other Win32 error as HRESULT.
  385. //
  386. //--
  387. /////////////////////////////////////////////////////////////////////////////
  388. STDMETHODIMP CClusResource::put_Name( IN BSTR bstrResourceName )
  389. {
  390. //ASSERT( bstrResourceName != NULL );
  391. HRESULT _hr = E_POINTER;
  392. if ( bstrResourceName != NULL )
  393. {
  394. DWORD _sc = ERROR_SUCCESS;
  395. _sc = ::SetClusterResourceName( m_hResource, bstrResourceName );
  396. if ( _sc == ERROR_SUCCESS )
  397. {
  398. m_bstrResourceName = bstrResourceName;
  399. }
  400. _hr = HRESULT_FROM_WIN32( _sc );
  401. }
  402. return _hr;
  403. } //*** CClusResource::put_Name()
  404. /////////////////////////////////////////////////////////////////////////////
  405. //++
  406. //
  407. // CClusResource::get_Name
  408. //
  409. // Description:
  410. // Return the name of this object (Resource).
  411. //
  412. // Arguments:
  413. // pbstrResourceName [OUT] - Catches the name of this object.
  414. //
  415. // Return Value:
  416. // S_OK if successful, E_POINTER, or other HRESULT error.
  417. //
  418. //--
  419. /////////////////////////////////////////////////////////////////////////////
  420. STDMETHODIMP CClusResource::get_Name( OUT BSTR * pbstrResourceName )
  421. {
  422. //ASSERT( pbstrResourceName != NULL );
  423. HRESULT _hr = E_POINTER;
  424. if ( pbstrResourceName != NULL )
  425. {
  426. *pbstrResourceName = m_bstrResourceName.Copy();
  427. _hr = S_OK;
  428. }
  429. return _hr;
  430. } //*** CClusResource::get_Name()
  431. /////////////////////////////////////////////////////////////////////////////
  432. //++
  433. //
  434. // CClusResource::get_State
  435. //
  436. // Description:
  437. // Returs the current state of this object (Resource).
  438. //
  439. // Arguments:
  440. // pcrsState [OUT] - Catches the resource's state.
  441. //
  442. // Return Value:
  443. // S_OK if successful, E_POINTER, or other Win32 error as HRESULT.
  444. //
  445. //--
  446. /////////////////////////////////////////////////////////////////////////////
  447. STDMETHODIMP CClusResource::get_State(
  448. OUT CLUSTER_RESOURCE_STATE * pcrsState
  449. )
  450. {
  451. //ASSERT( pcrsState != NULL );
  452. HRESULT _hr = E_POINTER;
  453. if ( pcrsState != NULL )
  454. {
  455. CLUSTER_RESOURCE_STATE crsState = ::WrapGetClusterResourceState( m_hResource, NULL, NULL );
  456. if ( crsState == ClusterResourceStateUnknown )
  457. {
  458. DWORD _sc = GetLastError();
  459. _hr = HRESULT_FROM_WIN32( _sc );
  460. }
  461. else
  462. {
  463. *pcrsState = crsState;
  464. _hr = S_OK;
  465. }
  466. }
  467. return _hr;
  468. } //*** CClusResource::get_State()
  469. /////////////////////////////////////////////////////////////////////////////
  470. //++
  471. //
  472. // CClusResource::get_CoreFlag
  473. //
  474. // Description:
  475. // Returns this object's (Resource) core flags.
  476. //
  477. // Arguments:
  478. // pFlags [OUT] - Catches the flags.
  479. //
  480. // Return Value:
  481. // S_OK if successful, E_POINTER, or other Win32 error as HRESULT.
  482. //
  483. //--
  484. /////////////////////////////////////////////////////////////////////////////
  485. STDMETHODIMP CClusResource::get_CoreFlag(
  486. OUT CLUS_FLAGS * pFlags
  487. )
  488. {
  489. //ASSERT( pFlags != NULL );
  490. HRESULT _hr = E_POINTER;
  491. if ( pFlags != NULL )
  492. {
  493. DWORD _sc = ERROR_SUCCESS;
  494. DWORD dwData;
  495. DWORD cbData;
  496. _sc = ::ClusterResourceControl(
  497. m_hResource,
  498. NULL,
  499. CLUSCTL_RESOURCE_GET_FLAGS,
  500. NULL,
  501. 0,
  502. &dwData,
  503. sizeof( dwData ),
  504. &cbData
  505. );
  506. if ( _sc != ERROR_SUCCESS )
  507. {
  508. _hr = HRESULT_FROM_WIN32( _sc );
  509. }
  510. else
  511. {
  512. *pFlags = (CLUS_FLAGS) dwData;
  513. _hr = S_OK;
  514. }
  515. }
  516. return _hr;
  517. } //*** CClusResource::get_CoreFlag()
  518. /////////////////////////////////////////////////////////////////////////////
  519. //++
  520. //
  521. // CClusResource::BecomeQuorumResource
  522. //
  523. // Description:
  524. // Make this resource (Physical Disk) the quorum resource.
  525. //
  526. // Arguments:
  527. // bstrDevicePath [IN] - Path to the quorum device.
  528. // lMaxLogSize [IN] - Maximun quorum log file size.
  529. //
  530. // Return Value:
  531. // S_OK if successful, E_POINTER, or other Win32 error as HRESULT.
  532. //
  533. //--
  534. /////////////////////////////////////////////////////////////////////////////
  535. STDMETHODIMP CClusResource::BecomeQuorumResource(
  536. IN BSTR bstrDevicePath,
  537. IN long lMaxLogSize
  538. )
  539. {
  540. //ASSERT( bstrDevicePath != NULL );
  541. HRESULT _hr = E_POINTER;
  542. if ( bstrDevicePath != NULL )
  543. {
  544. if ( m_hResource != NULL )
  545. {
  546. DWORD _sc = ERROR_SUCCESS;
  547. _sc = ::SetClusterQuorumResource( m_hResource, bstrDevicePath, lMaxLogSize );
  548. _hr = HRESULT_FROM_WIN32( _sc );
  549. }
  550. }
  551. return _hr;
  552. } //*** CClusResource::BecomeQuorumResource()
  553. /////////////////////////////////////////////////////////////////////////////
  554. //++
  555. //
  556. // CClusResource::Delete
  557. //
  558. // Description:
  559. // Removes this object (Resource) from the cluster.
  560. //
  561. // Arguments:
  562. // None.
  563. //
  564. // Return Value:
  565. // S_OK if successful, or other Win32 error as HRESULT.
  566. //
  567. //--
  568. /////////////////////////////////////////////////////////////////////////////
  569. STDMETHODIMP CClusResource::Delete( void )
  570. {
  571. DWORD _sc = ERROR_INVALID_HANDLE;
  572. if ( m_hResource != NULL )
  573. {
  574. _sc = ::DeleteClusterResource( m_hResource );
  575. if ( _sc == ERROR_SUCCESS )
  576. {
  577. m_hResource = NULL;
  578. }
  579. }
  580. return HRESULT_FROM_WIN32( _sc );
  581. } //*** CClusResource::Delete()
  582. /////////////////////////////////////////////////////////////////////////////
  583. //++
  584. //
  585. // CClusResource::Fail
  586. //
  587. // Description:
  588. // Initiate a failure in this resource.
  589. //
  590. // Arguments:
  591. // None.
  592. //
  593. // Return Value:
  594. // S_OK if successful, E_POINTER, or other Win32 error as HRESULT.
  595. //
  596. //--
  597. /////////////////////////////////////////////////////////////////////////////
  598. STDMETHODIMP CClusResource::Fail( void )
  599. {
  600. HRESULT _hr = E_POINTER;
  601. if ( m_hResource != NULL )
  602. {
  603. DWORD _sc = ERROR_SUCCESS;
  604. _sc = ::FailClusterResource( m_hResource );
  605. _hr = HRESULT_FROM_WIN32( _sc );
  606. }
  607. return _hr;
  608. } //*** CClusResource::Fail()
  609. /////////////////////////////////////////////////////////////////////////////
  610. //++
  611. //
  612. // CClusResource::Online
  613. //
  614. // Description:
  615. // Bring this resource online.
  616. //
  617. // Arguments:
  618. // nTimeut [IN] - How long in seconds to wait for the resource
  619. // to come online.
  620. // pvarPending [OUT] - Catches the pending state. True if the
  621. // resource was not online when the timeout
  622. // expired.
  623. //
  624. // Return Value:
  625. // S_OK if successful, E_POINTER, or other Win32 error as HRESULT.
  626. //
  627. //--
  628. /////////////////////////////////////////////////////////////////////////////
  629. STDMETHODIMP CClusResource::Online(
  630. IN long nTimeout,
  631. OUT VARIANT * pvarPending
  632. )
  633. {
  634. //ASSERT( pvarPending != NULL );
  635. HRESULT _hr = E_POINTER;
  636. if ( pvarPending != NULL )
  637. {
  638. pvarPending->vt = VT_BOOL;
  639. pvarPending->boolVal = VARIANT_FALSE;
  640. if ( m_hResource != NULL )
  641. {
  642. HCLUSTER hCluster = NULL;
  643. _hr = m_pClusRefObject->get_Handle( (ULONG_PTR *) &hCluster );
  644. if ( SUCCEEDED( _hr ) )
  645. {
  646. BOOL bPending = FALSE;
  647. _hr = ::HrWrapOnlineClusterResource( hCluster, m_hResource, nTimeout, (long *) &bPending );
  648. if ( SUCCEEDED( _hr ) )
  649. {
  650. if ( bPending )
  651. {
  652. pvarPending->boolVal = VARIANT_TRUE;
  653. } // if: pending?
  654. } // if: online resource succeeded
  655. } // if: do we have a cluster handle?
  656. } // if: do we have an open resource?
  657. } // if: args not NULL
  658. return _hr;
  659. } //*** CClusResource::Online()
  660. /////////////////////////////////////////////////////////////////////////////
  661. //++
  662. //
  663. // CClusResource::Offline
  664. //
  665. // Description:
  666. // Take this resource offline.
  667. //
  668. // Arguments:
  669. // nTimeut [IN] - How long in seconds to wait for the resource
  670. // to go offline.
  671. // pvarPending [OUT] - Catches the pending state. True if the
  672. // resource was not offline when the timeout
  673. // expired.
  674. //
  675. //
  676. // Return Value:
  677. // S_OK if successful, E_POINTER, or other Win32 error as HRESULT.
  678. //
  679. //--
  680. /////////////////////////////////////////////////////////////////////////////
  681. STDMETHODIMP CClusResource::Offline(
  682. IN long nTimeout,
  683. OUT VARIANT * pvarPending
  684. )
  685. {
  686. //ASSERT( pvarPending != NULL );
  687. HRESULT _hr = E_POINTER;
  688. if ( pvarPending != NULL )
  689. {
  690. pvarPending->vt = VT_BOOL;
  691. pvarPending->boolVal = VARIANT_FALSE;
  692. if ( m_hResource != NULL )
  693. {
  694. HCLUSTER hCluster = NULL;
  695. _hr = m_pClusRefObject->get_Handle( (ULONG_PTR *) &hCluster );
  696. if ( SUCCEEDED( _hr ) )
  697. {
  698. BOOL bPending = FALSE;
  699. _hr = ::HrWrapOfflineClusterResource( hCluster, m_hResource, nTimeout, (long *) &bPending );
  700. if ( SUCCEEDED( _hr ) )
  701. {
  702. if ( bPending )
  703. {
  704. pvarPending->boolVal = VARIANT_TRUE;
  705. } // if: pending?
  706. } // if: offline resource succeeded
  707. } // if: do we have a cluster handle?
  708. } // if: do we have an open resource?
  709. } // if: args not NULL
  710. return _hr;
  711. } //*** CClusResource::Offline()
  712. /////////////////////////////////////////////////////////////////////////////
  713. //++
  714. //
  715. // CClusResource::ChangeResourceGroup
  716. //
  717. // Description:
  718. // Move this resource into the passed in group.
  719. //
  720. // Arguments:
  721. // pResourceGroup [IN] - the group to move to.
  722. //
  723. // Return Value:
  724. // S_OK if successful, or other HRESULT error.
  725. //
  726. //--
  727. /////////////////////////////////////////////////////////////////////////////
  728. STDMETHODIMP CClusResource::ChangeResourceGroup(
  729. IN ISClusResGroup * pResourceGroup
  730. )
  731. {
  732. //ASSERT( pResourceGroup != NULL );
  733. HRESULT _hr = E_POINTER;
  734. if ( pResourceGroup != NULL )
  735. {
  736. HGROUP hGroup = 0;
  737. _hr = pResourceGroup->get_Handle( (ULONG_PTR *) &hGroup );
  738. if ( SUCCEEDED( _hr ) )
  739. {
  740. DWORD _sc = ::ChangeClusterResourceGroup( m_hResource, hGroup );
  741. _hr = HRESULT_FROM_WIN32( _sc );
  742. }
  743. }
  744. return _hr;
  745. } //*** CClusResource::ChangeResourceGroup()
  746. /////////////////////////////////////////////////////////////////////////////
  747. //++
  748. //
  749. // CClusResource::AddResourceNode
  750. //
  751. // Description:
  752. // Add the passed in node to this resources list of possible owners.
  753. //
  754. // Arguments:
  755. // pNode [IN] - the node to add to the possible owners.
  756. //
  757. // Return Value:
  758. // S_OK if successful, or other HRESULT error.
  759. //
  760. //--
  761. /////////////////////////////////////////////////////////////////////////////
  762. STDMETHODIMP CClusResource::AddResourceNode( IN ISClusNode * pNode )
  763. {
  764. //ASSERT( pNode != NULL );
  765. HRESULT _hr = E_POINTER;
  766. if ( pNode != NULL )
  767. {
  768. HNODE hNode = 0;
  769. _hr = pNode->get_Handle( (ULONG_PTR *) &hNode );
  770. if ( SUCCEEDED( _hr ) )
  771. {
  772. DWORD _sc = ::AddClusterResourceNode( m_hResource, hNode );
  773. _hr = HRESULT_FROM_WIN32( _sc );
  774. }
  775. }
  776. return _hr;
  777. } //*** CClusResource::AddResourceNode()
  778. /////////////////////////////////////////////////////////////////////////////
  779. //++
  780. //
  781. // CClusResource::RemoveResourceNode
  782. //
  783. // Description:
  784. // remove the passed in node from this resources list of possible owners.
  785. //
  786. // Arguments:
  787. // pNode [IN] - the node to remove from the possible owners.
  788. //
  789. // Return Value:
  790. // S_OK if successful, or other HRESULT error.
  791. //
  792. //--
  793. /////////////////////////////////////////////////////////////////////////////
  794. STDMETHODIMP CClusResource::RemoveResourceNode( IN ISClusNode * pNode )
  795. {
  796. //ASSERT( pNode != NULL );
  797. HRESULT _hr = E_POINTER;
  798. if ( pNode != NULL )
  799. {
  800. HNODE hNode = 0;
  801. _hr = pNode->get_Handle( (ULONG_PTR *) &hNode );
  802. if ( SUCCEEDED( _hr ) )
  803. {
  804. DWORD _sc = ::RemoveClusterResourceNode( m_hResource, hNode );
  805. _hr = HRESULT_FROM_WIN32( _sc );
  806. }
  807. }
  808. return _hr;
  809. } //*** CClusResource::RemoveResourceNode()
  810. /////////////////////////////////////////////////////////////////////////////
  811. //++
  812. //
  813. // CClusResource::CanResourceBeDependent
  814. //
  815. // Description:
  816. // Determines if this resource can be dependent upon the passed in
  817. // resource.
  818. //
  819. // Arguments:
  820. // pResource [in] - The resource upon which this resource may
  821. // depend.
  822. // pvarDependent [OUT] - catches whether or not this resource can become
  823. // dependent.
  824. //
  825. // Return Value:
  826. // S_OK if successful, or other HRESULT error.
  827. //
  828. //--
  829. /////////////////////////////////////////////////////////////////////////////
  830. STDMETHODIMP CClusResource::CanResourceBeDependent(
  831. IN ISClusResource * pResource,
  832. OUT VARIANT * pvarDependent
  833. )
  834. {
  835. //ASSERT( pResource != NULL );
  836. //ASSERT( pvarDependent != NULL );
  837. HRESULT _hr = E_POINTER;
  838. if ( ( pvarDependent != NULL ) && ( pResource != NULL ) )
  839. {
  840. HRESOURCE hResourceDep = NULL;
  841. _hr = pResource->get_Handle( (ULONG_PTR *) &hResourceDep );
  842. if ( SUCCEEDED( _hr ) )
  843. {
  844. BOOL bDependent = FALSE;
  845. bDependent = ::CanResourceBeDependent( m_hResource, hResourceDep );
  846. pvarDependent->vt = VT_BOOL;
  847. if ( bDependent )
  848. {
  849. pvarDependent->boolVal = VARIANT_TRUE;
  850. } // if: can the passed in resource be dependent?
  851. else
  852. {
  853. pvarDependent->boolVal = VARIANT_FALSE;
  854. } // else: no it cannot...
  855. }
  856. }
  857. return _hr;
  858. } //*** CClusResource::CanResourceBeDependent()
  859. /////////////////////////////////////////////////////////////////////////////
  860. //++
  861. //
  862. // CClusResource::get_PossibleOwnerNodes
  863. //
  864. // Description:
  865. // Returns the possible owner nodes collection for this resource.
  866. //
  867. // Arguments:
  868. // ppOwnerNodes [OUT] - Catches the collection.
  869. //
  870. // Return Value:
  871. // S_OK if successful, E_POINTER, or other Win32 error as HRESULT.
  872. //
  873. //--
  874. /////////////////////////////////////////////////////////////////////////////
  875. STDMETHODIMP CClusResource::get_PossibleOwnerNodes(
  876. OUT ISClusResPossibleOwnerNodes ** ppOwnerNodes
  877. )
  878. {
  879. //ASSERT( ppOwnerNodes != NULL );
  880. HRESULT _hr = E_POINTER;
  881. if ( ppOwnerNodes != NULL )
  882. {
  883. CComObject< CClusResPossibleOwnerNodes > * pClusterNodes = NULL;
  884. *ppOwnerNodes = NULL;
  885. _hr = CComObject< CClusResPossibleOwnerNodes >::CreateInstance( &pClusterNodes );
  886. if ( SUCCEEDED( _hr ) )
  887. {
  888. CSmartPtr< ISClusRefObject > ptrRefObject( m_pClusRefObject );
  889. CSmartPtr< CComObject< CClusResPossibleOwnerNodes > > ptrClusterNodes( pClusterNodes );
  890. _hr = ptrClusterNodes->Create( ptrRefObject, m_hResource );
  891. if ( SUCCEEDED( _hr ) )
  892. {
  893. _hr = ptrClusterNodes->Refresh();
  894. if ( SUCCEEDED( _hr ) )
  895. {
  896. _hr = ptrClusterNodes->QueryInterface( IID_ISClusResPossibleOwnerNodes, (void **) ppOwnerNodes );
  897. }
  898. }
  899. }
  900. }
  901. return _hr;
  902. } //*** CClusResource::get_PossibleOwnerNodes()
  903. /////////////////////////////////////////////////////////////////////////////
  904. //++
  905. //
  906. // CClusResource::get_Dependencies
  907. //
  908. // Description:
  909. // Get the collection of this resources dependency resources.
  910. //
  911. // Arguments:
  912. // ppResources [OUT] - Catches the collection of dependencies.
  913. //
  914. // Return Value:
  915. // S_OK if successful, E_POINTER, or other Win32 error as HRESULT.
  916. //
  917. //--
  918. /////////////////////////////////////////////////////////////////////////////
  919. STDMETHODIMP CClusResource::get_Dependencies(
  920. OUT ISClusResDependencies ** ppResources
  921. )
  922. {
  923. //ASSERT( ppResources != NULL );
  924. HRESULT _hr = E_POINTER;
  925. if ( ppResources != NULL )
  926. {
  927. CComObject< CClusResDependencies > * pResources = NULL;
  928. *ppResources = NULL;
  929. _hr = CComObject< CClusResDependencies >::CreateInstance( &pResources );
  930. if ( SUCCEEDED( _hr ) )
  931. {
  932. CSmartPtr< ISClusRefObject > ptrRefObject( m_pClusRefObject );
  933. CSmartPtr< CComObject< CClusResDependencies > > ptrResources( pResources );
  934. _hr = ptrResources->Create( ptrRefObject, m_hResource );
  935. if ( SUCCEEDED( _hr ) )
  936. {
  937. _hr = ptrResources->Refresh();
  938. if ( SUCCEEDED( _hr ) )
  939. {
  940. _hr = ptrResources->QueryInterface( IID_ISClusResDependencies, (void **) ppResources );
  941. }
  942. }
  943. }
  944. }
  945. return _hr;
  946. } //*** CClusResource::get_Dependencies()
  947. /////////////////////////////////////////////////////////////////////////////
  948. //++
  949. //
  950. // CClusResource::get_Dependents
  951. //
  952. // Description:
  953. // Get the collection of this resources dependent resources.
  954. //
  955. // Arguments:
  956. // ppResources [OUT] - Catches the collection of dependents.
  957. //
  958. // Return Value:
  959. // S_OK if successful, E_POINTER, or other Win32 error as HRESULT.
  960. //
  961. //--
  962. /////////////////////////////////////////////////////////////////////////////
  963. STDMETHODIMP CClusResource::get_Dependents(
  964. OUT ISClusResDependents ** ppResources
  965. )
  966. {
  967. //ASSERT( ppResources != NULL );
  968. HRESULT _hr = E_POINTER;
  969. if ( ppResources != NULL )
  970. {
  971. CComObject< CClusResDependents > * pResources = NULL;
  972. *ppResources = NULL;
  973. _hr = CComObject< CClusResDependents >::CreateInstance( &pResources );
  974. if ( SUCCEEDED( _hr ) )
  975. {
  976. CSmartPtr< ISClusRefObject > ptrRefObject( m_pClusRefObject );
  977. CSmartPtr< CComObject< CClusResDependents > > ptrResources( pResources );
  978. _hr = ptrResources->Create( ptrRefObject, m_hResource );
  979. if ( SUCCEEDED( _hr ) )
  980. {
  981. _hr = ptrResources->Refresh();
  982. if ( SUCCEEDED( _hr ) )
  983. {
  984. _hr = ptrResources->QueryInterface( IID_ISClusResDependents, (void **) ppResources );
  985. }
  986. }
  987. }
  988. }
  989. return _hr;
  990. } //*** CClusResource::get_Dependents()
  991. /////////////////////////////////////////////////////////////////////////////
  992. //++
  993. //
  994. // CClusResource::get_CommonProperties
  995. //
  996. // Description:
  997. // Get this object's (Resource) common properties collection.
  998. //
  999. // Arguments:
  1000. // ppProperties [OUT] - Catches the properties collection.
  1001. //
  1002. // Return Value:
  1003. // S_OK if successful, E_POINTER, or other Win32 error as HRESULT.
  1004. //
  1005. //--
  1006. /////////////////////////////////////////////////////////////////////////////
  1007. STDMETHODIMP CClusResource::get_CommonProperties(
  1008. OUT ISClusProperties ** ppProperties
  1009. )
  1010. {
  1011. //ASSERT( ppProperties != NULL );
  1012. HRESULT _hr = E_POINTER;
  1013. if ( ppProperties != NULL )
  1014. {
  1015. if ( m_pCommonProperties )
  1016. {
  1017. _hr = m_pCommonProperties->QueryInterface( IID_ISClusProperties, (void **) ppProperties );
  1018. }
  1019. else
  1020. {
  1021. _hr = GetProperties( ppProperties, FALSE, FALSE );
  1022. }
  1023. }
  1024. return _hr;
  1025. } //*** CClusResource::get_CommonProperties()
  1026. /////////////////////////////////////////////////////////////////////////////
  1027. //++
  1028. //
  1029. // CClusResource::get_PrivateProperties
  1030. //
  1031. // Description:
  1032. // Get this object's (Resource) private properties collection.
  1033. //
  1034. // Arguments:
  1035. // ppProperties [OUT] - Catches the properties collection.
  1036. //
  1037. // Return Value:
  1038. // S_OK if successful, E_POINTER, or other Win32 error as HRESULT.
  1039. //
  1040. //--
  1041. /////////////////////////////////////////////////////////////////////////////
  1042. STDMETHODIMP CClusResource::get_PrivateProperties(
  1043. OUT ISClusProperties ** ppProperties
  1044. )
  1045. {
  1046. //ASSERT( ppProperties != NULL );
  1047. HRESULT _hr = E_POINTER;
  1048. if ( ppProperties != NULL )
  1049. {
  1050. if ( m_pPrivateProperties )
  1051. {
  1052. _hr = m_pPrivateProperties->QueryInterface( IID_ISClusProperties, (void **) ppProperties );
  1053. }
  1054. else
  1055. {
  1056. _hr = GetProperties( ppProperties, TRUE, FALSE );
  1057. }
  1058. }
  1059. return _hr;
  1060. } //*** CClusResource::get_PrivateProperties()
  1061. /////////////////////////////////////////////////////////////////////////////
  1062. //++
  1063. //
  1064. // CClusResource::get_CommonROProperties
  1065. //
  1066. // Description:
  1067. // Get this object's (Resource) common read only properties collection.
  1068. //
  1069. // Arguments:
  1070. // ppProperties [OUT] - Catches the properties collection.
  1071. //
  1072. // Return Value:
  1073. // S_OK if successful, E_POINTER, or other Win32 error as HRESULT.
  1074. //
  1075. //--
  1076. /////////////////////////////////////////////////////////////////////////////
  1077. STDMETHODIMP CClusResource::get_CommonROProperties(
  1078. OUT ISClusProperties ** ppProperties
  1079. )
  1080. {
  1081. //ASSERT( ppProperties != NULL );
  1082. HRESULT _hr = E_POINTER;
  1083. if ( ppProperties != NULL )
  1084. {
  1085. if ( m_pCommonROProperties )
  1086. {
  1087. _hr = m_pCommonROProperties->QueryInterface( IID_ISClusProperties, (void **) ppProperties );
  1088. }
  1089. else
  1090. {
  1091. _hr = GetProperties( ppProperties, FALSE, TRUE );
  1092. }
  1093. }
  1094. return _hr;
  1095. } //*** CClusResource::get_CommonROProperties()
  1096. /////////////////////////////////////////////////////////////////////////////
  1097. //++
  1098. //
  1099. // CClusResource::get_PrivateROProperties
  1100. //
  1101. // Description:
  1102. // Get this object's (Resource) private read only properties collection.
  1103. //
  1104. // Arguments:
  1105. // ppProperties [OUT] - Catches the properties collection.
  1106. //
  1107. // Return Value:
  1108. // S_OK if successful, E_POINTER, or other Win32 error as HRESULT.
  1109. //
  1110. //--
  1111. /////////////////////////////////////////////////////////////////////////////
  1112. STDMETHODIMP CClusResource::get_PrivateROProperties(
  1113. OUT ISClusProperties ** ppProperties
  1114. )
  1115. {
  1116. //ASSERT( ppProperties != NULL );
  1117. HRESULT _hr = E_POINTER;
  1118. if ( ppProperties != NULL )
  1119. {
  1120. if ( m_pPrivateROProperties )
  1121. {
  1122. _hr = m_pPrivateROProperties->QueryInterface( IID_ISClusProperties, (void **) ppProperties );
  1123. }
  1124. else
  1125. {
  1126. _hr = GetProperties( ppProperties, TRUE, TRUE );
  1127. }
  1128. }
  1129. return _hr;
  1130. } //*** CClusResource::get_PrivateROProperties()
  1131. /////////////////////////////////////////////////////////////////////////////
  1132. //++
  1133. //
  1134. // CClusResource::get_Group
  1135. //
  1136. // Description:
  1137. // Get this resource's owning group.
  1138. //
  1139. // Arguments:
  1140. // ppGroup [OUT] - Catches the owning group.
  1141. //
  1142. // Return Value:
  1143. // S_OK if successful, E_POINTER, or other Win32 error as HRESULT.
  1144. //
  1145. //--
  1146. /////////////////////////////////////////////////////////////////////////////
  1147. STDMETHODIMP CClusResource::get_Group( OUT ISClusResGroup ** ppGroup )
  1148. {
  1149. //ASSERT( ppGroup != NULL );
  1150. HRESULT _hr = E_POINTER;
  1151. if ( ppGroup != NULL )
  1152. {
  1153. LPWSTR pwszGroupName = NULL;
  1154. CLUSTER_RESOURCE_STATE cState = ClusterResourceStateUnknown;
  1155. cState = ::WrapGetClusterResourceState( m_hResource, NULL, &pwszGroupName );
  1156. if ( cState != ClusterResourceStateUnknown )
  1157. {
  1158. CComObject< CClusResGroup > * pGroup = NULL;
  1159. _hr = CComObject< CClusResGroup >::CreateInstance( &pGroup );
  1160. if ( SUCCEEDED( _hr ) )
  1161. {
  1162. CSmartPtr< ISClusRefObject > ptrRefObject( m_pClusRefObject );
  1163. CSmartPtr< CComObject< CClusResGroup > > ptrGroup( pGroup );
  1164. _hr = ptrGroup->Open( ptrRefObject, pwszGroupName );
  1165. if ( SUCCEEDED( _hr ) )
  1166. {
  1167. _hr = ptrGroup->QueryInterface( IID_ISClusResGroup, (void **) ppGroup);
  1168. }
  1169. }
  1170. ::LocalFree( pwszGroupName );
  1171. pwszGroupName = NULL;
  1172. }
  1173. else
  1174. {
  1175. DWORD _sc = GetLastError();
  1176. _hr = HRESULT_FROM_WIN32( _sc );
  1177. }
  1178. }
  1179. return _hr;
  1180. } //*** CClusResource::get_Group()
  1181. /////////////////////////////////////////////////////////////////////////////
  1182. //++
  1183. //
  1184. // CClusResource::get_OwnerNode
  1185. //
  1186. // Description:
  1187. // Returns this resource's owning node.
  1188. //
  1189. // Arguments:
  1190. // ppNode [OUT] - Catches the owning node.
  1191. //
  1192. // Return Value:
  1193. // S_OK if successful, E_POINTER, or other Win32 error as HRESULT.
  1194. //
  1195. //--
  1196. /////////////////////////////////////////////////////////////////////////////
  1197. STDMETHODIMP CClusResource::get_OwnerNode( OUT ISClusNode ** ppNode )
  1198. {
  1199. //ASSERT( ppNode != NULL );
  1200. HRESULT _hr = E_POINTER;
  1201. if ( ppNode != NULL )
  1202. {
  1203. LPWSTR pwszNodeName = NULL;
  1204. CLUSTER_RESOURCE_STATE cState = ClusterResourceStateUnknown;
  1205. cState = ::WrapGetClusterResourceState( m_hResource, &pwszNodeName, NULL );
  1206. if ( cState != ClusterResourceStateUnknown )
  1207. {
  1208. CComObject< CClusNode > * pNode = NULL;
  1209. _hr = CComObject< CClusNode >::CreateInstance( &pNode );
  1210. if ( SUCCEEDED( _hr ) )
  1211. {
  1212. CSmartPtr< ISClusRefObject > ptrRefObject( m_pClusRefObject );
  1213. CSmartPtr< CComObject< CClusNode > > ptrNode( pNode );
  1214. _hr = ptrNode->Open( ptrRefObject, pwszNodeName );
  1215. if ( SUCCEEDED( _hr ) )
  1216. {
  1217. _hr = ptrNode->QueryInterface( IID_ISClusNode, (void **) ppNode);
  1218. }
  1219. }
  1220. ::LocalFree( pwszNodeName );
  1221. pwszNodeName = NULL;
  1222. }
  1223. else
  1224. {
  1225. DWORD _sc = GetLastError();
  1226. _hr = HRESULT_FROM_WIN32( _sc );
  1227. }
  1228. }
  1229. return _hr;
  1230. } //*** CClusResource::get_OwnerNode()
  1231. /////////////////////////////////////////////////////////////////////////////
  1232. //++
  1233. //
  1234. // CClusResource::get_Cluster
  1235. //
  1236. // Description:
  1237. // Returns the cluster where this resource resides.
  1238. //
  1239. // Arguments:
  1240. // ppCluster [OUT] - Catches the cluster.
  1241. //
  1242. // Return Value:
  1243. // S_OK if successful, E_POINTER, or other Win32 error as HRESULT.
  1244. //
  1245. //--
  1246. /////////////////////////////////////////////////////////////////////////////
  1247. STDMETHODIMP CClusResource::get_Cluster( OUT ISCluster ** ppCluster )
  1248. {
  1249. return ::HrGetCluster( ppCluster, m_pClusRefObject );
  1250. } //*** CClusResource::get_Cluster()
  1251. /////////////////////////////////////////////////////////////////////////////
  1252. //++
  1253. //
  1254. // CClusResource::HrLoadProperties
  1255. //
  1256. // Description:
  1257. // This virtual function does the actual load of the property list from
  1258. // the cluster.
  1259. //
  1260. // Arguments:
  1261. // rcplPropList [IN OUT] - The property list to load.
  1262. // bReadOnly [IN] - Load the read only properties?
  1263. // bPrivate [IN] - Load the common or the private properties?
  1264. //
  1265. // Return Value:
  1266. // S_OK if successful, or other HRESULT error.
  1267. //
  1268. //--
  1269. /////////////////////////////////////////////////////////////////////////////
  1270. HRESULT CClusResource::HrLoadProperties(
  1271. IN OUT CClusPropList & rcplPropList,
  1272. IN BOOL bReadOnly,
  1273. IN BOOL bPrivate
  1274. )
  1275. {
  1276. HRESULT _hr = S_FALSE;
  1277. DWORD _dwControlCode = 0;
  1278. DWORD _sc = ERROR_SUCCESS;
  1279. if ( bReadOnly )
  1280. {
  1281. _dwControlCode = bPrivate ?
  1282. CLUSCTL_RESOURCE_GET_RO_PRIVATE_PROPERTIES :
  1283. CLUSCTL_RESOURCE_GET_RO_COMMON_PROPERTIES;
  1284. }
  1285. else
  1286. {
  1287. _dwControlCode = bPrivate
  1288. ? CLUSCTL_RESOURCE_GET_PRIVATE_PROPERTIES
  1289. : CLUSCTL_RESOURCE_GET_COMMON_PROPERTIES;
  1290. }
  1291. _sc = rcplPropList.ScGetResourceProperties( m_hResource, _dwControlCode );
  1292. _hr = HRESULT_FROM_WIN32( _sc );
  1293. return _hr;
  1294. } //*** CClusResource::HrLoadProperties()
  1295. /////////////////////////////////////////////////////////////////////////////
  1296. //++
  1297. //
  1298. // CClusResource::ScWriteProperties
  1299. //
  1300. // Description:
  1301. // This virtual function does the actual saving of the property list to
  1302. // the cluster.
  1303. //
  1304. // Arguments:
  1305. // rcplPropList [IN] - The property list to save.
  1306. // bPrivate [IN] - Save the common or the private properties?
  1307. //
  1308. // Return Value:
  1309. // ERROR_SUCCESS if successful, or other Win32 error if not.
  1310. //
  1311. //--
  1312. /////////////////////////////////////////////////////////////////////////////
  1313. DWORD CClusResource::ScWriteProperties(
  1314. const CClusPropList & rcplPropList,
  1315. BOOL bPrivate
  1316. )
  1317. {
  1318. DWORD dwControlCode = bPrivate ? CLUSCTL_RESOURCE_SET_PRIVATE_PROPERTIES : CLUSCTL_RESOURCE_SET_COMMON_PROPERTIES;
  1319. DWORD nBytesReturned = 0;
  1320. DWORD _sc = ERROR_SUCCESS;
  1321. _sc = ClusterResourceControl(
  1322. m_hResource,
  1323. NULL,
  1324. dwControlCode,
  1325. rcplPropList,
  1326. rcplPropList.CbBufferSize(),
  1327. 0,
  1328. 0,
  1329. &nBytesReturned
  1330. );
  1331. return _sc;
  1332. } //*** CClusResource::ScWriteProperties()
  1333. /////////////////////////////////////////////////////////////////////////////
  1334. //++
  1335. //
  1336. // CClusResource::get_ClassInfo
  1337. //
  1338. // Description:
  1339. // Returns the class info for this resource.
  1340. //
  1341. // Arguments:
  1342. // prcClassInfo [OUT] - Catches the class info.
  1343. //
  1344. // Return Value:
  1345. // S_OK if successful, E_POINTER, or other Win32 error as HRESULT.
  1346. //
  1347. //--
  1348. /////////////////////////////////////////////////////////////////////////////
  1349. STDMETHODIMP CClusResource::get_ClassInfo(
  1350. OUT CLUSTER_RESOURCE_CLASS * prcClassInfo
  1351. )
  1352. {
  1353. ASSERT( prcClassInfo != NULL );
  1354. HRESULT _hr = E_POINTER;
  1355. if ( prcClassInfo != NULL )
  1356. {
  1357. if ( m_hResource != NULL )
  1358. {
  1359. CLUS_RESOURCE_CLASS_INFO ClassInfo;
  1360. DWORD _sc = ERROR_SUCCESS;
  1361. DWORD cbData;
  1362. _sc = ::ClusterResourceControl(
  1363. m_hResource,
  1364. NULL,
  1365. CLUSCTL_RESOURCE_GET_CLASS_INFO,
  1366. NULL,
  1367. 0,
  1368. &ClassInfo,
  1369. sizeof( CLUS_RESOURCE_CLASS_INFO ),
  1370. &cbData
  1371. );
  1372. _hr = HRESULT_FROM_WIN32( _sc );
  1373. if ( SUCCEEDED( _hr ) )
  1374. {
  1375. *prcClassInfo = ClassInfo.rc;
  1376. } // if:
  1377. } // if:
  1378. } // if:
  1379. return _hr;
  1380. } //*** CClusResource::get_ClassInfo
  1381. /////////////////////////////////////////////////////////////////////////////
  1382. //++
  1383. //
  1384. // CClusResource::get_Disk
  1385. //
  1386. // Description:
  1387. // Request the disk information for this physical disk resource.
  1388. //
  1389. // Arguments:
  1390. // ppDisk [OUT] - catches the disk information.
  1391. //
  1392. // Return Value:
  1393. // S_OK if successful, or other HRESULT error.
  1394. //
  1395. //--
  1396. /////////////////////////////////////////////////////////////////////////////
  1397. STDMETHODIMP CClusResource::get_Disk(
  1398. OUT ISClusDisk ** ppDisk
  1399. )
  1400. {
  1401. // ASSERT( ppDisk != NULL );
  1402. HRESULT _hr = E_POINTER;
  1403. if ( ppDisk != NULL )
  1404. {
  1405. if ( m_hResource != NULL )
  1406. {
  1407. CComObject< CClusDisk > * pDisk = NULL;
  1408. _hr = CComObject< CClusDisk >::CreateInstance( &pDisk );
  1409. if ( SUCCEEDED( _hr ) )
  1410. {
  1411. CSmartPtr< CComObject< CClusDisk > > ptrDisk( pDisk );
  1412. _hr = ptrDisk->Create( m_hResource );
  1413. if ( SUCCEEDED( _hr ) )
  1414. {
  1415. _hr = ptrDisk->QueryInterface( IID_ISClusDisk, (void **) ppDisk);
  1416. } // if:
  1417. } // if:
  1418. } // if:
  1419. } // if:
  1420. return _hr;
  1421. } //*** CClusResource::get_Disk
  1422. /////////////////////////////////////////////////////////////////////////////
  1423. //++
  1424. //
  1425. // CClusResource::get_RegistryKeys
  1426. //
  1427. // Description:
  1428. // Get the collection of registry keys.
  1429. //
  1430. // Arguments:
  1431. // ppRegistryKeys [OUT] - catches the registry keys collection.
  1432. //
  1433. // Return Value:
  1434. // S_OK if successful, or other HRESULT error.
  1435. //
  1436. //--
  1437. /////////////////////////////////////////////////////////////////////////////
  1438. STDMETHODIMP CClusResource::get_RegistryKeys(
  1439. OUT ISClusRegistryKeys ** ppRegistryKeys
  1440. )
  1441. {
  1442. return ::HrCreateResourceCollection< CClusResourceRegistryKeys, ISClusRegistryKeys, HRESOURCE >(
  1443. m_hResource,
  1444. ppRegistryKeys,
  1445. IID_ISClusRegistryKeys
  1446. );
  1447. } //*** CClusResource::get_RegistryKeys()
  1448. /////////////////////////////////////////////////////////////////////////////
  1449. //++
  1450. //
  1451. // CClusResource::get_CryptoKeys
  1452. //
  1453. // Description:
  1454. // Get the collection of crypto keys.
  1455. //
  1456. // Arguments:
  1457. // ppCryptoKeys [OUT] - catches the crypto keys collection.
  1458. //
  1459. // Return Value:
  1460. // S_OK if successful, or other HRESULT error.
  1461. //
  1462. //--
  1463. /////////////////////////////////////////////////////////////////////////////
  1464. STDMETHODIMP CClusResource::get_CryptoKeys(
  1465. OUT ISClusCryptoKeys ** ppCryptoKeys
  1466. )
  1467. {
  1468. #if CLUSAPI_VERSION >= 0x0500
  1469. return ::HrCreateResourceCollection< CClusResourceCryptoKeys, ISClusCryptoKeys, HRESOURCE >(
  1470. m_hResource,
  1471. ppCryptoKeys,
  1472. IID_ISClusCryptoKeys
  1473. );
  1474. #else
  1475. return E_NOTIMPL;
  1476. #endif // CLUSAPI_VERSION >= 0x0500
  1477. } //*** CClusResource::get_CryptoKeys()
  1478. /////////////////////////////////////////////////////////////////////////////
  1479. //++
  1480. //
  1481. // CClusResource::get_TypeName
  1482. //
  1483. // Description:
  1484. // Get the resource type name of this resource.
  1485. //
  1486. // Arguments:
  1487. // pbstrTypeName [OUT] - Catches the resource type name.
  1488. //
  1489. // Return Value:
  1490. // S_OK if successful, or other HRESULT error.
  1491. //
  1492. //--
  1493. /////////////////////////////////////////////////////////////////////////////
  1494. STDMETHODIMP CClusResource::get_TypeName( OUT BSTR * pbstrTypeName )
  1495. {
  1496. //ASSERT( pbstrTypeName != NULL );
  1497. HRESULT _hr = E_POINTER;
  1498. if ( pbstrTypeName != NULL )
  1499. {
  1500. LPWSTR _psz;
  1501. DWORD _sc;
  1502. _sc = ScGetResourceTypeName( &_psz );
  1503. _hr = HRESULT_FROM_WIN32( _sc );
  1504. if ( SUCCEEDED( _hr ) )
  1505. {
  1506. *pbstrTypeName = ::SysAllocString( _psz );
  1507. if ( *pbstrTypeName == NULL )
  1508. {
  1509. _hr = E_OUTOFMEMORY;
  1510. }
  1511. ::LocalFree( _psz );
  1512. } // if:
  1513. } // if: arg is not NULL
  1514. return _hr;
  1515. } //*** CClusResource::get_TypeName()
  1516. /////////////////////////////////////////////////////////////////////////////
  1517. //++
  1518. //
  1519. // CClusResource::get_Type
  1520. //
  1521. // Description:
  1522. // Get the resource type object for this resource.
  1523. //
  1524. // Arguments:
  1525. // ppResourceType [OUT] - Catches the resource type object.
  1526. //
  1527. // Return Value:
  1528. // S_OK if successful, or other HRESULT error.
  1529. //
  1530. //--
  1531. /////////////////////////////////////////////////////////////////////////////
  1532. STDMETHODIMP CClusResource::get_Type( OUT ISClusResType ** ppResourceType )
  1533. {
  1534. //ASSERT( ppResourceType != NULL );
  1535. HRESULT _hr = E_POINTER;
  1536. if ( ppResourceType != NULL )
  1537. {
  1538. LPWSTR _psz;
  1539. DWORD _sc;
  1540. _sc = ScGetResourceTypeName( &_psz );
  1541. _hr = HRESULT_FROM_WIN32( _sc );
  1542. if ( SUCCEEDED( _hr ) )
  1543. {
  1544. CComObject< CClusResType > * pResourceType = NULL;
  1545. _hr = CComObject< CClusResType >::CreateInstance( &pResourceType );
  1546. if ( SUCCEEDED( _hr ) )
  1547. {
  1548. CSmartPtr< ISClusRefObject > ptrRefObject( m_pClusRefObject );
  1549. CSmartPtr< CComObject< CClusResType > > ptrResourceType( pResourceType );
  1550. _hr = ptrResourceType->Open( ptrRefObject, _psz );
  1551. if ( SUCCEEDED( _hr ) )
  1552. {
  1553. _hr = ptrResourceType->QueryInterface( IID_ISClusResType, (void **) ppResourceType );
  1554. } // if: the resource type could be opened
  1555. } // if: CreateInstance OK
  1556. ::LocalFree( _psz );
  1557. } // if: we got the resource type name for this resource
  1558. } // if: arg is not NULL
  1559. return _hr;
  1560. } //*** CClusResource::get_Type()
  1561. /////////////////////////////////////////////////////////////////////////////
  1562. //++
  1563. //
  1564. // CClusResource::ScGetResourceTypeName
  1565. //
  1566. // Description:
  1567. // Get the resource type name for this resource.
  1568. //
  1569. // Arguments:
  1570. // ppwszResourceTypeName [OUT] - Catches the resource type name.
  1571. //
  1572. // Return Value:
  1573. // ERROR_SUCCESS if successful, or other Win32 error.
  1574. //
  1575. //--
  1576. /////////////////////////////////////////////////////////////////////////////
  1577. DWORD CClusResource::ScGetResourceTypeName(
  1578. OUT LPWSTR * ppwszResourceTypeName
  1579. )
  1580. {
  1581. ASSERT( ppwszResourceTypeName != NULL );
  1582. LPWSTR _psz = NULL;
  1583. DWORD _cb = 512;
  1584. DWORD _sc = ERROR_SUCCESS;
  1585. _psz = (LPWSTR) ::LocalAlloc( LMEM_ZEROINIT, _cb );
  1586. if ( _psz != NULL )
  1587. {
  1588. DWORD _cbData = 0;
  1589. _sc = ::ClusterResourceControl(
  1590. m_hResource,
  1591. NULL,
  1592. CLUSCTL_RESOURCE_GET_RESOURCE_TYPE,
  1593. NULL,
  1594. 0,
  1595. _psz,
  1596. _cb,
  1597. &_cbData
  1598. );
  1599. if ( _sc == ERROR_MORE_DATA )
  1600. {
  1601. ::LocalFree( _psz );
  1602. _psz = NULL;
  1603. _cb = _cbData;
  1604. _psz = (LPWSTR) ::LocalAlloc( LMEM_ZEROINIT, _cb );
  1605. if ( _psz != NULL )
  1606. {
  1607. DWORD _cbData = 0;
  1608. _sc = ::ClusterResourceControl(
  1609. m_hResource,
  1610. NULL,
  1611. CLUSCTL_RESOURCE_GET_RESOURCE_TYPE,
  1612. NULL,
  1613. 0,
  1614. _psz,
  1615. _cb,
  1616. &_cbData
  1617. );
  1618. } // if: alloc ok
  1619. else
  1620. {
  1621. _sc = ::GetLastError();
  1622. } // else: if alloc failed
  1623. } // if: buffer not big enough...
  1624. if ( _sc == ERROR_SUCCESS )
  1625. {
  1626. *ppwszResourceTypeName = _psz;
  1627. } // if:
  1628. } // if: alloc ok
  1629. else
  1630. {
  1631. _sc = ::GetLastError();
  1632. } // else: if alloc failed
  1633. return _sc;
  1634. } //*** CClusResource::ScGetResourceTypeName()
  1635. //*************************************************************************//
  1636. /////////////////////////////////////////////////////////////////////////////
  1637. // CResources class
  1638. /////////////////////////////////////////////////////////////////////////////
  1639. /////////////////////////////////////////////////////////////////////////////
  1640. //++
  1641. //
  1642. // CResources::CResources
  1643. //
  1644. // Description:
  1645. // Constructor.
  1646. //
  1647. // Arguments:
  1648. // None.
  1649. //
  1650. // Return Value:
  1651. // None.
  1652. //
  1653. //--
  1654. /////////////////////////////////////////////////////////////////////////////
  1655. CResources::CResources( void )
  1656. {
  1657. m_pClusRefObject = NULL;
  1658. } //*** CResources::CResources()
  1659. /////////////////////////////////////////////////////////////////////////////
  1660. //++
  1661. //
  1662. // CResources::~CResources
  1663. //
  1664. // Description:
  1665. // Destructor.
  1666. //
  1667. // Arguments:
  1668. // None.
  1669. //
  1670. // Return Value:
  1671. // None.
  1672. //
  1673. //--
  1674. /////////////////////////////////////////////////////////////////////////////
  1675. CResources::~CResources( void )
  1676. {
  1677. Clear();
  1678. if ( m_pClusRefObject != NULL )
  1679. {
  1680. m_pClusRefObject->Release();
  1681. m_pClusRefObject = NULL;
  1682. } // if:
  1683. } //*** CResources::~CResources()
  1684. /////////////////////////////////////////////////////////////////////////////
  1685. //++
  1686. //
  1687. // CResources::Create
  1688. //
  1689. // Description:
  1690. // Finish creating the object by doing things that cannot be done in
  1691. // a light weight constructor.
  1692. //
  1693. // Arguments:
  1694. // pClusRefObject [IN] - Wraps the cluster handle.
  1695. //
  1696. // Return Value:
  1697. // S_OK if successful or E_POINTER if not.
  1698. //
  1699. //--
  1700. /////////////////////////////////////////////////////////////////////////////
  1701. HRESULT CResources::Create(
  1702. IN ISClusRefObject * pClusRefObject
  1703. )
  1704. {
  1705. ASSERT( pClusRefObject != NULL );
  1706. HRESULT _hr = E_POINTER;
  1707. if ( pClusRefObject != NULL )
  1708. {
  1709. m_pClusRefObject = pClusRefObject;
  1710. m_pClusRefObject->AddRef();
  1711. _hr = S_OK;
  1712. }
  1713. return _hr;
  1714. } //*** CResources::Create()
  1715. /////////////////////////////////////////////////////////////////////////////
  1716. //++
  1717. //
  1718. // CResources::Clear
  1719. //
  1720. // Description:
  1721. // Release the objects in the vector and clean up the vector.
  1722. //
  1723. // Arguments:
  1724. // None.
  1725. //
  1726. // Return Value:
  1727. // None.
  1728. //
  1729. //--
  1730. /////////////////////////////////////////////////////////////////////////////
  1731. void CResources::Clear( void )
  1732. {
  1733. ::ReleaseAndEmptyCollection< ResourceList, CComObject< CClusResource > >( m_Resources );
  1734. } //*** CResources::Clear()
  1735. /////////////////////////////////////////////////////////////////////////////
  1736. //++
  1737. //
  1738. // CResources::FindItem
  1739. //
  1740. // Description:
  1741. // Find the passed in resource in the vector and return its index.
  1742. //
  1743. // Arguments:
  1744. // pszResourceName [IN] - The item to find.
  1745. // pnIndex [OUT] - Catches the node's index.
  1746. //
  1747. // Return Value:
  1748. // S_OK if successful, E_POINTER, or E_INVALIDARG.
  1749. //
  1750. //--
  1751. /////////////////////////////////////////////////////////////////////////////
  1752. HRESULT CResources::FindItem(
  1753. IN LPWSTR pszResourceName,
  1754. OUT UINT * pnIndex
  1755. )
  1756. {
  1757. //ASSERT( pnIndex != NULL );
  1758. HRESULT _hr = E_POINTER;
  1759. if ( pnIndex != NULL )
  1760. {
  1761. CComObject< CClusResource > * _pResource = NULL;
  1762. size_t _cMax = m_Resources.size();
  1763. size_t _index;
  1764. _hr = E_INVALIDARG;
  1765. for( _index = 0; _index < _cMax; _index++ )
  1766. {
  1767. _pResource = m_Resources[ _index ];
  1768. if ( ( _pResource != NULL ) &&
  1769. ( lstrcmpi( pszResourceName, _pResource->Name() ) == 0 ) )
  1770. {
  1771. *pnIndex = _index;
  1772. _hr = S_OK;
  1773. break;
  1774. }
  1775. }
  1776. }
  1777. return _hr;
  1778. } //*** CResources::FindItem( pszResourceName )
  1779. /////////////////////////////////////////////////////////////////////////////
  1780. //++
  1781. //
  1782. // CResources::FindItem
  1783. //
  1784. // Description:
  1785. // Find the passed in resource in the vector and return its index.
  1786. //
  1787. // Arguments:
  1788. // pResource [IN] - The item to find.
  1789. // pnIndex [OUT] - Catches the node's index.
  1790. //
  1791. // Return Value:
  1792. // S_OK if successful, E_POINTER, or E_INVALIDARG.
  1793. //
  1794. //--
  1795. /////////////////////////////////////////////////////////////////////////////
  1796. HRESULT CResources::FindItem(
  1797. IN ISClusResource * pResource,
  1798. OUT UINT * pnIndex
  1799. )
  1800. {
  1801. //ASSERT( pResource != NULL );
  1802. //ASSERT( pnIndex != NULL );
  1803. HRESULT _hr = E_POINTER;
  1804. if ( ( pResource != NULL ) && ( pnIndex != NULL ) )
  1805. {
  1806. CComBSTR bstrName;
  1807. _hr = pResource->get_Name( &bstrName );
  1808. if ( SUCCEEDED( _hr ) )
  1809. {
  1810. _hr = FindItem( bstrName, pnIndex );
  1811. }
  1812. }
  1813. return _hr;
  1814. } //*** CResources::FindItem( pResource )
  1815. /////////////////////////////////////////////////////////////////////////////
  1816. //++
  1817. //
  1818. // CResources::GetIndex
  1819. //
  1820. // Description:
  1821. // Convert the passed in variant index into the real index in the
  1822. // collection.
  1823. //
  1824. // Arguments:
  1825. // varIndex [IN] - The index to convert.
  1826. // pnIndex [OUT] - Catches the index.
  1827. //
  1828. // Return Value:
  1829. // S_OK if successful, E_POINTER, or E_INVALIDARG.
  1830. //
  1831. //--
  1832. /////////////////////////////////////////////////////////////////////////////
  1833. HRESULT CResources::GetIndex(
  1834. IN VARIANT varIndex,
  1835. OUT UINT * pnIndex
  1836. )
  1837. {
  1838. //ASSERT( pnIndex != NULL );
  1839. HRESULT _hr = E_POINTER;
  1840. if ( pnIndex != NULL )
  1841. {
  1842. CComVariant v;
  1843. UINT nIndex = 0;
  1844. *pnIndex = 0;
  1845. v.Copy( &varIndex );
  1846. //
  1847. // Check to see if the index is a number.
  1848. //
  1849. _hr = v.ChangeType( VT_I4 );
  1850. if ( SUCCEEDED( _hr ) )
  1851. {
  1852. nIndex = v.lVal;
  1853. nIndex--; // Adjust index to be 0 relative instead of 1 relative
  1854. }
  1855. else
  1856. {
  1857. //
  1858. // Check to see if the index is a string.
  1859. //
  1860. _hr = v.ChangeType( VT_BSTR );
  1861. if ( SUCCEEDED( _hr ) )
  1862. {
  1863. _hr = FindItem( v.bstrVal, &nIndex );
  1864. }
  1865. }
  1866. if ( SUCCEEDED( _hr ) )
  1867. {
  1868. if ( nIndex < m_Resources.size() )
  1869. {
  1870. *pnIndex = nIndex;
  1871. }
  1872. else
  1873. {
  1874. _hr = E_INVALIDARG;
  1875. }
  1876. }
  1877. }
  1878. return _hr;
  1879. } //*** CResources::GetIndex()
  1880. /////////////////////////////////////////////////////////////////////////////
  1881. //++
  1882. //
  1883. // CResources::GetResourceItem
  1884. //
  1885. // Description:
  1886. // Return the object (Resource) at the passed in index.
  1887. //
  1888. // Arguments:
  1889. // varIndex [IN] - Contains the index requested.
  1890. // ppResource [OUT] - Catches the item.
  1891. //
  1892. // Return Value:
  1893. // S_OK if successful, E_POINTER, or E_INVALIDARG.
  1894. //
  1895. //--
  1896. /////////////////////////////////////////////////////////////////////////////
  1897. HRESULT CResources::GetResourceItem(
  1898. IN VARIANT varIndex,
  1899. OUT ISClusResource ** ppResource
  1900. )
  1901. {
  1902. //ASSERT( ppResource != NULL );
  1903. HRESULT _hr = E_POINTER;
  1904. if ( ppResource != NULL )
  1905. {
  1906. CComObject< CClusResource > * pResource = NULL;
  1907. UINT nIndex = 0;
  1908. *ppResource = NULL ;
  1909. _hr = GetIndex( varIndex, &nIndex );
  1910. if ( SUCCEEDED( _hr ) )
  1911. {
  1912. pResource = m_Resources[ nIndex ];
  1913. _hr = pResource->QueryInterface( IID_ISClusResource, (void **) ppResource );
  1914. }
  1915. }
  1916. return _hr;
  1917. } //*** CResources::GetResourceItem()
  1918. /////////////////////////////////////////////////////////////////////////////
  1919. //++
  1920. //
  1921. // CResources::RemoveAt
  1922. //
  1923. // Description:
  1924. // Remove the item at the passed in index from the collection.
  1925. //
  1926. // Arguments:
  1927. // pos [IN] - Index to remove.
  1928. //
  1929. // Return Value:
  1930. // S_OK if successful, or E_INVALIDARG.
  1931. //
  1932. //--
  1933. /////////////////////////////////////////////////////////////////////////////
  1934. HRESULT CResources::RemoveAt( IN size_t pos )
  1935. {
  1936. CComObject<CClusResource> * pResource = NULL;
  1937. ResourceList::iterator first = m_Resources.begin();
  1938. ResourceList::iterator last = m_Resources.end();
  1939. HRESULT _hr = E_INVALIDARG;
  1940. for ( size_t t = 0; ( t < pos ) && ( first != last ); t++, first++ );
  1941. if ( first != last )
  1942. {
  1943. pResource = *first;
  1944. if ( pResource )
  1945. {
  1946. pResource->Release();
  1947. }
  1948. m_Resources.erase( first );
  1949. _hr = S_OK;
  1950. }
  1951. return _hr;
  1952. } //*** CResources::RemoveAt()
  1953. /////////////////////////////////////////////////////////////////////////////
  1954. //++
  1955. //
  1956. // CResources::DeleteItem
  1957. //
  1958. // Description:
  1959. // Delete the resource at the passed in index from the collection and
  1960. // the cluster.
  1961. //
  1962. // Arguments:
  1963. // varIndex [IN] - Contains the index of the resource to delete.
  1964. //
  1965. // Return Value:
  1966. // S_OK if successful, E_POINTER, or Win32 as HRESULT error.
  1967. //
  1968. //--
  1969. /////////////////////////////////////////////////////////////////////////////
  1970. HRESULT CResources::DeleteItem( IN VARIANT varIndex )
  1971. {
  1972. HRESULT _hr = S_FALSE;
  1973. UINT nIndex = 0;
  1974. _hr = GetIndex( varIndex, &nIndex );
  1975. if ( SUCCEEDED( _hr ) )
  1976. {
  1977. ISClusResource * pClusterResource = (ISClusResource *) m_Resources[ nIndex ];
  1978. _hr = pClusterResource->Delete();
  1979. if ( SUCCEEDED( _hr ) )
  1980. {
  1981. _hr = RemoveAt( nIndex );
  1982. }
  1983. }
  1984. return _hr;
  1985. } //*** CResources::DeleteItem()
  1986. //*************************************************************************//
  1987. /////////////////////////////////////////////////////////////////////////////
  1988. // CClusResources class
  1989. /////////////////////////////////////////////////////////////////////////////
  1990. /////////////////////////////////////////////////////////////////////////////
  1991. //++
  1992. //
  1993. // CClusResources::CClusResources
  1994. //
  1995. // Description:
  1996. // Constructor.
  1997. //
  1998. // Arguments:
  1999. // None.
  2000. //
  2001. // Return Value:
  2002. // None.
  2003. //
  2004. //--
  2005. /////////////////////////////////////////////////////////////////////////////
  2006. CClusResources::CClusResources( void )
  2007. {
  2008. m_piids = (const IID *) iidCClusResources;
  2009. m_piidsSize = ARRAYSIZE( iidCClusResources );
  2010. } //*** CClusResources::CClusResources()
  2011. /////////////////////////////////////////////////////////////////////////////
  2012. //++
  2013. //
  2014. // CClusResources::~CClusResources
  2015. //
  2016. // Description:
  2017. // Destructor.
  2018. //
  2019. // Arguments:
  2020. // None.
  2021. //
  2022. // Return Value:
  2023. // None.
  2024. //
  2025. //--
  2026. /////////////////////////////////////////////////////////////////////////////
  2027. CClusResources::~CClusResources( void )
  2028. {
  2029. CResources::Clear();
  2030. } //*** CClusResources::~CClusResources()
  2031. /////////////////////////////////////////////////////////////////////////////
  2032. //++
  2033. //
  2034. // CClusResources::get_Count
  2035. //
  2036. // Description:
  2037. // Return the count of objects (Resource) in the collection.
  2038. //
  2039. // Arguments:
  2040. // plCount [OUT] - Catches the count.
  2041. //
  2042. // Return Value:
  2043. // S_OK if successful, or E_POINTER.
  2044. //
  2045. //--
  2046. /////////////////////////////////////////////////////////////////////////////
  2047. STDMETHODIMP CClusResources::get_Count( OUT long * plCount )
  2048. {
  2049. //ASSERT( plCount != NULL );
  2050. HRESULT _hr = E_POINTER;
  2051. if ( plCount != NULL )
  2052. {
  2053. *plCount = m_Resources.size();
  2054. _hr = S_OK;
  2055. }
  2056. return _hr;
  2057. } //*** CClusResources::get_Count()
  2058. /////////////////////////////////////////////////////////////////////////////
  2059. //++
  2060. //
  2061. // CClusResources::get__NewEnum
  2062. //
  2063. // Description:
  2064. // Create and return a new enumeration for this collection.
  2065. //
  2066. // Arguments:
  2067. // ppunk [OUT] - Catches the new enumeration.
  2068. //
  2069. // Return Value:
  2070. // S_OK if successful, E_POINTER, or other HRESULT error.
  2071. //
  2072. //--
  2073. /////////////////////////////////////////////////////////////////////////////
  2074. STDMETHODIMP CClusResources::get__NewEnum( OUT IUnknown ** ppunk )
  2075. {
  2076. return ::HrNewIDispatchEnum< ResourceList, CComObject< CClusResource > >( ppunk, m_Resources );
  2077. } //*** CClusResources::get__NewEnum()
  2078. /////////////////////////////////////////////////////////////////////////////
  2079. //++
  2080. //
  2081. // CClusResources::CreateItem
  2082. //
  2083. // Description:
  2084. // Create a new item and add it to the collection.
  2085. //
  2086. // Arguments:
  2087. // bstrResourceName [IN] - The name of the resource to create.
  2088. // bstrResourceType [IN] - The type of the resource to create.
  2089. // bstrGroupName [IN] - The group to create it in.
  2090. // dwFlags [IN] - Resource monitor flag.
  2091. // ppClusterResource [OUT] - Catches the new resource.
  2092. //
  2093. // Return Value:
  2094. // S_OK if successful, E_POINTER, or Win32 as HRESULT error.
  2095. //
  2096. //--
  2097. /////////////////////////////////////////////////////////////////////////////
  2098. STDMETHODIMP CClusResources::CreateItem(
  2099. IN BSTR bstrResourceName,
  2100. IN BSTR bstrResourceType,
  2101. IN BSTR bstrGroupName,
  2102. IN CLUSTER_RESOURCE_CREATE_FLAGS dwFlags,
  2103. IN ISClusResource ** ppClusterResource
  2104. )
  2105. {
  2106. //ASSERT( bstrResourceName != NULL );
  2107. //ASSERT( bstrResourceType != NULL );
  2108. //ASSERT( bstrGroupName != NULL );
  2109. //ASSERT( ppClusterResource != NULL );
  2110. HRESULT _hr = E_POINTER;
  2111. if ( ( ppClusterResource != NULL ) &&
  2112. ( bstrResourceName != NULL ) &&
  2113. ( bstrResourceType != NULL ) &&
  2114. ( bstrGroupName != NULL ) )
  2115. {
  2116. *ppClusterResource = NULL;
  2117. //
  2118. // Fail if no valid cluster handle.
  2119. //
  2120. if ( m_pClusRefObject != NULL )
  2121. {
  2122. UINT nIndex;
  2123. _hr = FindItem( bstrResourceName, &nIndex );
  2124. if ( FAILED( _hr ) ) // don't allow duplicates
  2125. {
  2126. HCLUSTER hCluster = NULL;
  2127. HGROUP hGroup = NULL;
  2128. _hr = m_pClusRefObject->get_Handle( (ULONG_PTR *) &hCluster );
  2129. if ( SUCCEEDED( _hr ) )
  2130. {
  2131. hGroup = OpenClusterGroup( hCluster, bstrGroupName );
  2132. if ( hGroup != NULL )
  2133. {
  2134. CComObject< CClusResource > * pClusterResource = NULL;
  2135. _hr = CComObject< CClusResource >::CreateInstance( &pClusterResource );
  2136. if ( SUCCEEDED( _hr ) )
  2137. {
  2138. CSmartPtr< ISClusRefObject > ptrRefObject( m_pClusRefObject );
  2139. CSmartPtr< CComObject< CClusResource > > ptrResource( pClusterResource );
  2140. _hr = ptrResource->Create( ptrRefObject, hGroup, bstrResourceName, bstrResourceType, dwFlags );
  2141. if ( SUCCEEDED( _hr ) )
  2142. {
  2143. _hr = ptrResource->QueryInterface( IID_ISClusResource, (void **) ppClusterResource );
  2144. if ( SUCCEEDED( _hr ) )
  2145. {
  2146. ptrResource->AddRef();
  2147. m_Resources.insert( m_Resources.end(), ptrResource );
  2148. }
  2149. }
  2150. }
  2151. ::CloseClusterGroup( hGroup );
  2152. }
  2153. else
  2154. {
  2155. DWORD _sc = 0;
  2156. _sc = GetLastError();
  2157. _hr = HRESULT_FROM_WIN32( _sc );
  2158. }
  2159. }
  2160. }
  2161. else
  2162. {
  2163. CComObject<CClusResource> * pClusterResource = NULL;
  2164. pClusterResource = m_Resources[ nIndex ];
  2165. _hr = pClusterResource->QueryInterface( IID_ISClusResource, (void **) ppClusterResource );
  2166. }
  2167. }
  2168. }
  2169. return _hr;
  2170. } //*** CClusResources::CreateItem()
  2171. /////////////////////////////////////////////////////////////////////////////
  2172. //++
  2173. //
  2174. // CClusResources::DeleteItem
  2175. //
  2176. // Description:
  2177. // Delete the resource at the passed in index from the collection and
  2178. // the cluster.
  2179. //
  2180. // Arguments:
  2181. // varIndex [IN] - Contains the index of the resource to delete.
  2182. //
  2183. // Return Value:
  2184. // S_OK if successful, E_POINTER, or Win32 as HRESULT error.
  2185. //
  2186. //--
  2187. /////////////////////////////////////////////////////////////////////////////
  2188. STDMETHODIMP CClusResources::DeleteItem( IN VARIANT varIndex )
  2189. {
  2190. return CResources::DeleteItem( varIndex );
  2191. } //*** CClusResources::DeleteItem()
  2192. /////////////////////////////////////////////////////////////////////////////
  2193. //++
  2194. //
  2195. // CClusResources::Refresh
  2196. //
  2197. // Description:
  2198. // Load the collection from the cluster database.
  2199. //
  2200. // Arguments:
  2201. // None.
  2202. //
  2203. // Return Value:
  2204. // S_OK if successful, E_POINTER, or Win32 error as HRESULT.
  2205. //
  2206. //--
  2207. /////////////////////////////////////////////////////////////////////////////
  2208. STDMETHODIMP CClusResources::Refresh( void )
  2209. {
  2210. HRESULT _hr = E_POINTER;
  2211. HCLUSENUM _hEnum = NULL;
  2212. DWORD _sc = ERROR_SUCCESS;
  2213. if ( m_pClusRefObject != NULL )
  2214. {
  2215. HCLUSTER hCluster = NULL;
  2216. _hr = m_pClusRefObject->get_Handle( (ULONG_PTR *) &hCluster );
  2217. if ( SUCCEEDED( _hr ) )
  2218. {
  2219. _hEnum = ::ClusterOpenEnum( hCluster, CLUSTER_ENUM_RESOURCE );
  2220. if ( _hEnum != NULL )
  2221. {
  2222. int _nIndex = 0;
  2223. DWORD dwType;
  2224. LPWSTR pszName = NULL;
  2225. CComObject< CClusResource > * pClusterResource = NULL;
  2226. CResources::Clear();
  2227. for( _nIndex = 0, _hr = S_OK; SUCCEEDED( _hr ); _nIndex++ )
  2228. {
  2229. _sc = ::WrapClusterEnum( _hEnum, _nIndex, &dwType, &pszName );
  2230. if ( _sc == ERROR_NO_MORE_ITEMS )
  2231. {
  2232. _hr = S_OK;
  2233. break;
  2234. }
  2235. else if ( _sc == ERROR_SUCCESS )
  2236. {
  2237. _hr = CComObject< CClusResource >::CreateInstance( &pClusterResource );
  2238. if ( SUCCEEDED( _hr ) )
  2239. {
  2240. CSmartPtr< ISClusRefObject > ptrRefObject( m_pClusRefObject );
  2241. CSmartPtr< CComObject< CClusResource > > ptrResource( pClusterResource );
  2242. _hr = ptrResource->Open( ptrRefObject, pszName );
  2243. if ( SUCCEEDED( _hr ) )
  2244. {
  2245. ptrResource->AddRef();
  2246. m_Resources.insert( m_Resources.end(), ptrResource );
  2247. }
  2248. }
  2249. ::LocalFree( pszName );
  2250. pszName = NULL;
  2251. }
  2252. else
  2253. {
  2254. _hr = HRESULT_FROM_WIN32( _sc );
  2255. }
  2256. }
  2257. ::ClusterCloseEnum( _hEnum );
  2258. }
  2259. else
  2260. {
  2261. _sc = GetLastError();
  2262. _hr = HRESULT_FROM_WIN32( _sc );
  2263. }
  2264. }
  2265. }
  2266. return _hr;
  2267. } //*** CClusResources::Refresh()
  2268. /////////////////////////////////////////////////////////////////////////////
  2269. //++
  2270. //
  2271. // CClusResources::get_Item
  2272. //
  2273. // Description:
  2274. // Return the object (Resource) at the passed in index.
  2275. //
  2276. // Arguments:
  2277. // varIndex [IN] - Contains the index requested.
  2278. // ppResource [OUT] - Catches the item.
  2279. //
  2280. // Return Value:
  2281. // S_OK if successful, E_POINTER, or E_INVALIDARG.
  2282. //
  2283. //--
  2284. /////////////////////////////////////////////////////////////////////////////
  2285. HRESULT CClusResources::get_Item(
  2286. IN VARIANT varIndex,
  2287. OUT ISClusResource ** ppResource
  2288. )
  2289. {
  2290. return GetResourceItem( varIndex, ppResource );
  2291. } //*** CClusResources::get_Item()
  2292. //*************************************************************************//
  2293. /////////////////////////////////////////////////////////////////////////////
  2294. // CClusResDepends class
  2295. /////////////////////////////////////////////////////////////////////////////
  2296. /////////////////////////////////////////////////////////////////////////////
  2297. //++
  2298. //
  2299. // CClusResDepends::CClusResDepends
  2300. //
  2301. // Description:
  2302. // Constructor.
  2303. //
  2304. // Arguments:
  2305. // None.
  2306. //
  2307. // Return Value:
  2308. // None.
  2309. //
  2310. //--
  2311. /////////////////////////////////////////////////////////////////////////////
  2312. CClusResDepends::CClusResDepends( void )
  2313. {
  2314. m_hResource = NULL;
  2315. } //*** CClusResDepends::CClusResDepends()
  2316. /////////////////////////////////////////////////////////////////////////////
  2317. //++
  2318. //
  2319. // CClusResDepends::~CClusResDepends
  2320. //
  2321. // Description:
  2322. // Destructor.
  2323. //
  2324. // Arguments:
  2325. // None.
  2326. //
  2327. // Return Value:
  2328. // None.
  2329. //
  2330. //--
  2331. /////////////////////////////////////////////////////////////////////////////
  2332. CClusResDepends::~CClusResDepends( void )
  2333. {
  2334. Clear();
  2335. } //*** CClusResDepends::~CClusResDepends()
  2336. /////////////////////////////////////////////////////////////////////////////
  2337. //++
  2338. //
  2339. // CClusResDepends::get_Count
  2340. //
  2341. // Description:
  2342. // Return the count of objects (Resource) in the collection.
  2343. //
  2344. // Arguments:
  2345. // plCount [OUT] - Catches the count.
  2346. //
  2347. // Return Value:
  2348. // S_OK if successful, or E_POINTER.
  2349. //
  2350. //--
  2351. /////////////////////////////////////////////////////////////////////////////
  2352. STDMETHODIMP CClusResDepends::get_Count( OUT long * plCount )
  2353. {
  2354. //ASSERT( plCount != NULL );
  2355. HRESULT _hr = E_POINTER;
  2356. if ( plCount != NULL )
  2357. {
  2358. *plCount = m_Resources.size();
  2359. _hr = S_OK;
  2360. }
  2361. return _hr;
  2362. } //*** CClusResDepends::get_Count()
  2363. /////////////////////////////////////////////////////////////////////////////
  2364. //++
  2365. //
  2366. // CClusResDepends::Create
  2367. //
  2368. // Description:
  2369. // Finish creating the object by doing things that cannot be done in
  2370. // a light weight constructor.
  2371. //
  2372. // Arguments:
  2373. // pClusRefObject [IN] - Wraps the cluster handle.
  2374. // hResource [IN] - The resource this collection belongs to.
  2375. //
  2376. // Return Value:
  2377. // S_OK if successful or E_POINTER if not.
  2378. //
  2379. //--
  2380. /////////////////////////////////////////////////////////////////////////////
  2381. HRESULT CClusResDepends::Create(
  2382. IN ISClusRefObject * pClusRefObject,
  2383. IN HRESOURCE hResource
  2384. )
  2385. {
  2386. HRESULT _hr = E_POINTER;
  2387. _hr = CResources::Create( pClusRefObject );
  2388. if ( SUCCEEDED( _hr ) )
  2389. {
  2390. m_hResource = hResource;
  2391. } // if:
  2392. return _hr;
  2393. } //*** CClusResDepends::Create()
  2394. /////////////////////////////////////////////////////////////////////////////
  2395. //++
  2396. //
  2397. // CClusResDepends::get__NewEnum
  2398. //
  2399. // Description:
  2400. // Create and return a new enumeration for this collection.
  2401. //
  2402. // Arguments:
  2403. // ppunk [OUT] - Catches the new enumeration.
  2404. //
  2405. // Return Value:
  2406. // S_OK if successful, E_POINTER, or other HRESULT error.
  2407. //
  2408. //--
  2409. /////////////////////////////////////////////////////////////////////////////
  2410. STDMETHODIMP CClusResDepends::get__NewEnum( OUT IUnknown ** ppunk )
  2411. {
  2412. return ::HrNewIDispatchEnum< ResourceList, CComObject< CClusResource > >( ppunk, m_Resources );
  2413. } //*** CClusResDepends::get__NewEnum()
  2414. /////////////////////////////////////////////////////////////////////////////
  2415. //++
  2416. //
  2417. // CClusResDepends::DeleteItem
  2418. //
  2419. // Description:
  2420. // Delete the resource at the passed in index from the collection and
  2421. // the cluster.
  2422. //
  2423. // Arguments:
  2424. // varIndex [IN] - Contains the index of the resource to delete.
  2425. //
  2426. // Return Value:
  2427. // S_OK if successful, E_POINTER, or Win32 as HRESULT error.
  2428. //
  2429. //--
  2430. /////////////////////////////////////////////////////////////////////////////
  2431. STDMETHODIMP CClusResDepends::DeleteItem( IN VARIANT varIndex )
  2432. {
  2433. return CResources::DeleteItem( varIndex );
  2434. } //*** CClusResDepends::DeleteItem()
  2435. /////////////////////////////////////////////////////////////////////////////
  2436. //++
  2437. //
  2438. // CClusResDepends::get_Item
  2439. //
  2440. // Description:
  2441. // Return the object (Resource) at the passed in index.
  2442. //
  2443. // Arguments:
  2444. // varIndex [IN] - Contains the index requested.
  2445. // ppResource [OUT] - Catches the item.
  2446. //
  2447. // Return Value:
  2448. // S_OK if successful, E_POINTER, or E_INVALIDARG.
  2449. //
  2450. //--
  2451. /////////////////////////////////////////////////////////////////////////////
  2452. STDMETHODIMP CClusResDepends::get_Item(
  2453. IN VARIANT varIndex,
  2454. OUT ISClusResource ** ppResource
  2455. )
  2456. {
  2457. return GetResourceItem( varIndex, ppResource );
  2458. } //*** CClusResDepends::get_Item()
  2459. /////////////////////////////////////////////////////////////////////////////
  2460. //++
  2461. //
  2462. // CClusResDepends::HrRefresh
  2463. //
  2464. // Description:
  2465. // Load the collection from the cluster database.
  2466. //
  2467. // Arguments:
  2468. // cre [IN] - Type of enumeration to perform.
  2469. //
  2470. // Return Value:
  2471. // S_OK if successful, E_POINTER, or Win32 error as HRESULT.
  2472. //
  2473. //--
  2474. /////////////////////////////////////////////////////////////////////////////
  2475. HRESULT CClusResDepends::HrRefresh( IN CLUSTER_RESOURCE_ENUM cre )
  2476. {
  2477. HRESENUM _hEnum = NULL;
  2478. HRESULT _hr = S_OK;
  2479. DWORD _sc = ERROR_SUCCESS;
  2480. _hEnum = ::ClusterResourceOpenEnum( m_hResource, cre );
  2481. if ( _hEnum != NULL )
  2482. {
  2483. int _nIndex = 0;
  2484. DWORD dwType;
  2485. LPWSTR pszName = NULL;
  2486. CComObject< CClusResource > * pClusterResource = NULL;
  2487. Clear();
  2488. for( _nIndex = 0, _hr = S_OK; SUCCEEDED( _hr ); _nIndex++ )
  2489. {
  2490. _sc = ::WrapClusterResourceEnum( _hEnum, _nIndex, &dwType, &pszName );
  2491. if ( _sc == ERROR_NO_MORE_ITEMS )
  2492. {
  2493. _hr = S_OK;
  2494. break;
  2495. }
  2496. else if ( _sc == ERROR_SUCCESS )
  2497. {
  2498. _hr = CComObject< CClusResource >::CreateInstance( &pClusterResource );
  2499. if ( SUCCEEDED( _hr ) )
  2500. {
  2501. CSmartPtr< ISClusRefObject > ptrRefObject( m_pClusRefObject );
  2502. CSmartPtr< CComObject< CClusResource > > ptrResource( pClusterResource );
  2503. _hr = ptrResource->Open( ptrRefObject, pszName );
  2504. if ( SUCCEEDED( _hr ) )
  2505. {
  2506. ptrResource->AddRef();
  2507. m_Resources.insert( m_Resources.end(), ptrResource );
  2508. }
  2509. }
  2510. ::LocalFree( pszName );
  2511. pszName = NULL;
  2512. }
  2513. else
  2514. {
  2515. _hr = HRESULT_FROM_WIN32( _sc );
  2516. }
  2517. }
  2518. ::ClusterResourceCloseEnum( _hEnum );
  2519. }
  2520. else
  2521. {
  2522. _sc = GetLastError();
  2523. _hr = HRESULT_FROM_WIN32( _sc );
  2524. }
  2525. return _hr;
  2526. } //*** CClusResDepends::HrRefresh()
  2527. /////////////////////////////////////////////////////////////////////////////
  2528. //++
  2529. //
  2530. // CClusResDepends::CreateItem
  2531. //
  2532. // Description:
  2533. // Create a new item and add it to the collection.
  2534. //
  2535. // Arguments:
  2536. // bstrResourceName [IN] - The name of the resource to create.
  2537. // bstrResourceType [IN] - The type of the resource to create.
  2538. // dwFlags [IN] - Resource monitor flag.
  2539. // ppClusterResource [OUT] - Catches the new resource.
  2540. //
  2541. // Return Value:
  2542. // S_OK if successful, E_POINTER, or Win32 as HRESULT error.
  2543. //
  2544. //--
  2545. /////////////////////////////////////////////////////////////////////////////
  2546. STDMETHODIMP CClusResDepends::CreateItem(
  2547. IN BSTR bstrResourceName,
  2548. IN BSTR bstrResourceType,
  2549. IN CLUSTER_RESOURCE_CREATE_FLAGS dwFlags,
  2550. OUT ISClusResource ** ppClusterResource
  2551. )
  2552. {
  2553. //ASSERT( bstrResourceName != NULL );
  2554. //ASSERT( bstrResourceType != NULL );
  2555. //ASSERT( ppClusterResource != NULL );
  2556. ASSERT( m_pClusRefObject != NULL );
  2557. HRESULT _hr = E_POINTER;
  2558. if ( ( ppClusterResource != NULL ) &&
  2559. ( bstrResourceName != NULL ) &&
  2560. ( bstrResourceType != NULL ) )
  2561. {
  2562. DWORD _sc = ERROR_SUCCESS;
  2563. *ppClusterResource = NULL;
  2564. if ( m_pClusRefObject != NULL )
  2565. {
  2566. UINT _nIndex;
  2567. _hr = FindItem( bstrResourceName, &_nIndex );
  2568. if ( FAILED( _hr ) )
  2569. {
  2570. HCLUSTER hCluster = NULL;
  2571. HGROUP hGroup = NULL;
  2572. _hr = m_pClusRefObject->get_Handle( (ULONG_PTR *) &hCluster );
  2573. if ( SUCCEEDED( _hr ) )
  2574. {
  2575. LPWSTR pwszGroupName = NULL;
  2576. CLUSTER_RESOURCE_STATE cState = ClusterResourceStateUnknown;
  2577. cState = WrapGetClusterResourceState( m_hResource, NULL, &pwszGroupName );
  2578. if ( cState != ClusterResourceStateUnknown )
  2579. {
  2580. hGroup = ::OpenClusterGroup( hCluster, pwszGroupName );
  2581. if ( hGroup != NULL )
  2582. {
  2583. CComObject< CClusResource > * pClusterResource = NULL;
  2584. _hr = CComObject< CClusResource >::CreateInstance( &pClusterResource );
  2585. if ( SUCCEEDED( _hr ) )
  2586. {
  2587. CSmartPtr< ISClusRefObject > ptrRefObject( m_pClusRefObject );
  2588. CSmartPtr< CComObject< CClusResource > > ptrResource( pClusterResource );
  2589. _hr = ptrResource->Create( ptrRefObject, hGroup, bstrResourceName, bstrResourceType, dwFlags );
  2590. if ( SUCCEEDED( _hr ) )
  2591. {
  2592. HRESOURCE hDependsRes = NULL;
  2593. _hr = ptrResource->get_Handle( (ULONG_PTR *) &hDependsRes );
  2594. if ( SUCCEEDED( _hr ) )
  2595. {
  2596. _sc = ScAddDependency( m_hResource, hDependsRes );
  2597. if ( _sc == ERROR_SUCCESS )
  2598. {
  2599. _hr = ptrResource->QueryInterface( IID_ISClusResource, (void **) ppClusterResource );
  2600. if ( SUCCEEDED( _hr ) )
  2601. {
  2602. ptrResource->AddRef();
  2603. m_Resources.insert( m_Resources.end(), ptrResource );
  2604. }
  2605. }
  2606. else
  2607. {
  2608. _hr = HRESULT_FROM_WIN32( _sc );
  2609. }
  2610. }
  2611. }
  2612. }
  2613. ::CloseClusterGroup( hGroup );
  2614. }
  2615. else
  2616. {
  2617. _sc = GetLastError();
  2618. _hr = HRESULT_FROM_WIN32( _sc );
  2619. }
  2620. ::LocalFree( pwszGroupName );
  2621. pwszGroupName = NULL;
  2622. } // if: WrapGetClusterResourceState
  2623. else
  2624. {
  2625. DWORD _sc = GetLastError();
  2626. _hr = HRESULT_FROM_WIN32( _sc );
  2627. }
  2628. }
  2629. }
  2630. else
  2631. {
  2632. CComObject< CClusResource > * pClusterResource = NULL;
  2633. pClusterResource = m_Resources[ _nIndex ];
  2634. _hr = pClusterResource->QueryInterface( IID_ISClusResource, (void **) ppClusterResource );
  2635. }
  2636. }
  2637. }
  2638. return _hr;
  2639. } //*** CClusResDepends::CreateItem()
  2640. /////////////////////////////////////////////////////////////////////////////
  2641. //++
  2642. //
  2643. // CClusResDepends::AddItem
  2644. //
  2645. // Description:
  2646. // Make this resource dependent upon the passed in resource.
  2647. //
  2648. // Arguments:
  2649. // pResouce [IN] - Resource to add to the dependencies list.
  2650. //
  2651. // Return Value:
  2652. // S_OK if successful, or other HRESULT error.
  2653. //
  2654. //--
  2655. /////////////////////////////////////////////////////////////////////////////
  2656. STDMETHODIMP CClusResDepends::AddItem( IN ISClusResource * pResource )
  2657. {
  2658. //ASSERT( pResource != NULL );
  2659. HRESULT _hr = E_POINTER;
  2660. if ( pResource != NULL )
  2661. {
  2662. // Fail if duplicate
  2663. UINT _nIndex = 0;
  2664. _hr = FindItem( pResource, &_nIndex );
  2665. if ( FAILED( _hr ) )
  2666. {
  2667. HRESOURCE hResourceDep = NULL;
  2668. CComObject< CClusResource > * pClusterResource = NULL;
  2669. _hr = pResource->get_Handle( (ULONG_PTR *) &hResourceDep );
  2670. if ( SUCCEEDED( _hr ) )
  2671. {
  2672. DWORD _sc = ScAddDependency( m_hResource, hResourceDep );
  2673. _hr = HRESULT_FROM_WIN32( _sc );
  2674. if ( SUCCEEDED( _hr ) )
  2675. {
  2676. CComObject< CClusResource > * _pResource = NULL;
  2677. _hr = pResource->QueryInterface( IID_CClusResource, (void **) &_pResource );
  2678. if ( SUCCEEDED( _hr ) )
  2679. {
  2680. _pResource->AddRef();
  2681. m_Resources.insert( m_Resources.end(), _pResource );
  2682. pResource->Release();
  2683. } // if:
  2684. }
  2685. }
  2686. }
  2687. else
  2688. {
  2689. _hr = E_INVALIDARG;
  2690. }
  2691. }
  2692. return _hr;
  2693. } //*** CClusResDepends::AddItem()
  2694. /////////////////////////////////////////////////////////////////////////////
  2695. //++
  2696. //
  2697. // CClusResDepends::RemoveItem
  2698. //
  2699. // Description:
  2700. // Remove the dependency on the resource at the passed in index.
  2701. //
  2702. // Arguments:
  2703. // varIndex [IN] - The index of the item whose dependency should
  2704. // be removed.
  2705. //
  2706. // Return Value:
  2707. // S_OK if successful, or other Win32 error as HRESULT if not.
  2708. //
  2709. //--
  2710. /////////////////////////////////////////////////////////////////////////////
  2711. STDMETHODIMP CClusResDepends::RemoveItem( IN VARIANT varIndex )
  2712. {
  2713. HRESULT _hr = S_OK;
  2714. UINT _nIndex = 0;
  2715. _hr = GetIndex( varIndex, &_nIndex );
  2716. if ( SUCCEEDED( _hr ) )
  2717. {
  2718. ISClusResource * pClusterResource = (ISClusResource *) m_Resources[ _nIndex ];
  2719. HRESOURCE hResourceDep = NULL;
  2720. _hr = pClusterResource->get_Handle( (ULONG_PTR *) &hResourceDep );
  2721. if ( SUCCEEDED( _hr ) )
  2722. {
  2723. DWORD _sc = ScRemoveDependency( m_hResource, hResourceDep );
  2724. _hr = HRESULT_FROM_WIN32( _sc );
  2725. if ( SUCCEEDED( _hr ) )
  2726. {
  2727. _hr = RemoveAt( _nIndex );
  2728. }
  2729. }
  2730. }
  2731. return _hr;
  2732. } //*** CClusResDepends::RemoveItem()
  2733. //*************************************************************************//
  2734. /////////////////////////////////////////////////////////////////////////////
  2735. // CClusResDependencies class
  2736. /////////////////////////////////////////////////////////////////////////////
  2737. /////////////////////////////////////////////////////////////////////////////
  2738. //++
  2739. //
  2740. // CClusResDependencies::CClusResDependencies
  2741. //
  2742. // Description:
  2743. // Constructor.
  2744. //
  2745. // Arguments:
  2746. // None.
  2747. //
  2748. // Return Value:
  2749. // None.
  2750. //
  2751. //--
  2752. /////////////////////////////////////////////////////////////////////////////
  2753. CClusResDependencies::CClusResDependencies( void )
  2754. {
  2755. m_piids = (const IID *) iidCClusResDependencies;
  2756. m_piidsSize = ARRAYSIZE( iidCClusResDependencies );
  2757. } //*** CClusResDependencies::CClusResDependencies()
  2758. //*************************************************************************//
  2759. /////////////////////////////////////////////////////////////////////////////
  2760. // CClusResDependents class
  2761. /////////////////////////////////////////////////////////////////////////////
  2762. /////////////////////////////////////////////////////////////////////////////
  2763. //++
  2764. //
  2765. // CClusResDependents::CClusResDependents
  2766. //
  2767. // Description:
  2768. // Constructor.
  2769. //
  2770. // Arguments:
  2771. // None.
  2772. //
  2773. // Return Value:
  2774. // None.
  2775. //
  2776. //--
  2777. /////////////////////////////////////////////////////////////////////////////
  2778. CClusResDependents::CClusResDependents( void )
  2779. {
  2780. m_piids = (const IID *) iidCClusResDependents;
  2781. m_piidsSize = ARRAYSIZE( iidCClusResDependents );
  2782. } //*** CClusResDependents::CClusResDependents()
  2783. //*************************************************************************//
  2784. /////////////////////////////////////////////////////////////////////////////
  2785. // CClusResGroupResources class
  2786. /////////////////////////////////////////////////////////////////////////////
  2787. /////////////////////////////////////////////////////////////////////////////
  2788. //++
  2789. //
  2790. // CClusResGroupResources::CClusResGroupResources
  2791. //
  2792. // Description:
  2793. // Constructor.
  2794. //
  2795. // Arguments:
  2796. // None.
  2797. //
  2798. // Return Value:
  2799. // None.
  2800. //
  2801. //--
  2802. /////////////////////////////////////////////////////////////////////////////
  2803. CClusResGroupResources::CClusResGroupResources( void )
  2804. {
  2805. m_piids = (const IID *) iidCClusResGroupResources;
  2806. m_piidsSize = ARRAYSIZE( iidCClusResGroupResources );
  2807. } //*** CClusResGroupResources::CClusResGroupResources()
  2808. /////////////////////////////////////////////////////////////////////////////
  2809. //++
  2810. //
  2811. // CClusResGroupResources::~CClusResGroupResources
  2812. //
  2813. // Description:
  2814. // Destructor.
  2815. //
  2816. // Arguments:
  2817. // None.
  2818. //
  2819. // Return Value:
  2820. // None.
  2821. //
  2822. //--
  2823. /////////////////////////////////////////////////////////////////////////////
  2824. CClusResGroupResources::~CClusResGroupResources( void )
  2825. {
  2826. Clear();
  2827. } //*** CClusResGroupResources::~CClusResGroupResources()
  2828. /////////////////////////////////////////////////////////////////////////////
  2829. //++
  2830. //
  2831. // CClusResGroupResources::get_Count
  2832. //
  2833. // Description:
  2834. // Return the count of objects (Resource) in the collection.
  2835. //
  2836. // Arguments:
  2837. // plCount [OUT] - Catches the count.
  2838. //
  2839. // Return Value:
  2840. // S_OK if successful, or E_POINTER.
  2841. //
  2842. //--
  2843. /////////////////////////////////////////////////////////////////////////////
  2844. STDMETHODIMP CClusResGroupResources::get_Count( OUT long * plCount )
  2845. {
  2846. //ASSERT( plCount != NULL );
  2847. HRESULT _hr = E_POINTER;
  2848. if ( plCount != NULL )
  2849. {
  2850. *plCount = m_Resources.size();
  2851. _hr = S_OK;
  2852. }
  2853. return _hr;
  2854. } //*** CClusResGroupResources::get_Count()
  2855. /////////////////////////////////////////////////////////////////////////////
  2856. //++
  2857. //
  2858. // CClusResGroupResources::Create
  2859. //
  2860. // Description:
  2861. // Finish creating the object by doing things that cannot be done in
  2862. // a light weight constructor.
  2863. //
  2864. // Arguments:
  2865. // pClusRefObject [IN] - Wraps the cluster handle.
  2866. // hGroup [IN] - The group this collection belongs to.
  2867. //
  2868. // Return Value:
  2869. // S_OK if successful or E_POINTER if not.
  2870. //
  2871. //--
  2872. /////////////////////////////////////////////////////////////////////////////
  2873. HRESULT CClusResGroupResources::Create(
  2874. IN ISClusRefObject * pClusRefObject,
  2875. IN HGROUP hGroup
  2876. )
  2877. {
  2878. HRESULT _hr = E_POINTER;
  2879. _hr = CResources::Create( pClusRefObject );
  2880. if ( SUCCEEDED( _hr ) )
  2881. {
  2882. m_hGroup = hGroup;
  2883. } // if:
  2884. return _hr;
  2885. } //*** CClusResGroupResources::Create()
  2886. /////////////////////////////////////////////////////////////////////////////
  2887. //++
  2888. //
  2889. // CClusResGroupResources::get__NewEnum
  2890. //
  2891. // Description:
  2892. // Create and return a new enumeration for this collection.
  2893. //
  2894. // Arguments:
  2895. // ppunk [OUT] - Catches the new enumeration.
  2896. //
  2897. // Return Value:
  2898. // S_OK if successful, E_POINTER, or other HRESULT error.
  2899. //
  2900. //--
  2901. /////////////////////////////////////////////////////////////////////////////
  2902. STDMETHODIMP CClusResGroupResources::get__NewEnum( OUT IUnknown ** ppunk )
  2903. {
  2904. return ::HrNewIDispatchEnum< ResourceList, CComObject< CClusResource > >( ppunk, m_Resources );
  2905. } //*** CClusResGroupResources::get__NewEnum()
  2906. /////////////////////////////////////////////////////////////////////////////
  2907. //++
  2908. //
  2909. // CClusResGroupResources::CreateItem
  2910. //
  2911. // Description:
  2912. // Create a new item and add it to the collection.
  2913. //
  2914. // Arguments:
  2915. // bstrResourceName [IN] - The name of the resource to create.
  2916. // bstrResourceType [IN] - The type of the resource to create.
  2917. // dwFlags [IN] - Resource monitor flag.
  2918. // ppClusterResource [OUT] - Catches the new resource.
  2919. //
  2920. // Return Value:
  2921. // S_OK if successful, E_POINTER, or Win32 as HRESULT error.
  2922. //
  2923. //--
  2924. /////////////////////////////////////////////////////////////////////////////
  2925. STDMETHODIMP CClusResGroupResources::CreateItem(
  2926. IN BSTR bstrResourceName,
  2927. IN BSTR bstrResourceType,
  2928. IN CLUSTER_RESOURCE_CREATE_FLAGS dwFlags,
  2929. OUT ISClusResource ** ppClusterResource
  2930. )
  2931. {
  2932. //ASSERT( bstrResourceName != NULL );
  2933. //ASSERT( bstrResourceType != NULL );
  2934. //ASSERT( ppClusterResource != NULL );
  2935. HRESULT _hr = E_POINTER;
  2936. if ( ( bstrResourceName != NULL ) &&
  2937. ( bstrResourceType != NULL ) &&
  2938. ( ppClusterResource != NULL ) )
  2939. {
  2940. *ppClusterResource = NULL;
  2941. if ( m_pClusRefObject != NULL )
  2942. {
  2943. UINT _nIndex = 0;
  2944. _hr = FindItem( bstrResourceName, &_nIndex );
  2945. if ( FAILED( _hr ) )
  2946. {
  2947. HCLUSTER hCluster = NULL;
  2948. CComObject< CClusResource > * pClusterResource = NULL;
  2949. _hr = m_pClusRefObject->get_Handle( (ULONG_PTR *) &hCluster );
  2950. if ( SUCCEEDED( _hr ) )
  2951. {
  2952. _hr = CComObject< CClusResource >::CreateInstance( &pClusterResource );
  2953. if ( SUCCEEDED( _hr ) )
  2954. {
  2955. CSmartPtr< ISClusRefObject > ptrRefObject( m_pClusRefObject );
  2956. CSmartPtr< CComObject< CClusResource > > ptrResource( pClusterResource );
  2957. _hr = ptrResource->Create( ptrRefObject, m_hGroup, bstrResourceName, bstrResourceType, dwFlags );
  2958. if ( SUCCEEDED( _hr ) )
  2959. {
  2960. _hr = ptrResource->QueryInterface( IID_ISClusResource, (void **) ppClusterResource );
  2961. if ( SUCCEEDED( _hr ) )
  2962. {
  2963. ptrResource->AddRef();
  2964. m_Resources.insert( m_Resources.end(), ptrResource );
  2965. }
  2966. }
  2967. }
  2968. }
  2969. }
  2970. else
  2971. {
  2972. CComObject< CClusResource > * pClusterResource = NULL;
  2973. pClusterResource = m_Resources[ _nIndex ];
  2974. _hr = pClusterResource->QueryInterface( IID_ISClusResource, (void **) ppClusterResource );
  2975. }
  2976. }
  2977. }
  2978. return _hr;
  2979. } //*** CClusResGroupResources::CreateItem()
  2980. /////////////////////////////////////////////////////////////////////////////
  2981. //++
  2982. //
  2983. // CClusResGroupResources::DeleteItem
  2984. //
  2985. // Description:
  2986. // Delete the resource at the passed in index from the collection and
  2987. // the cluster.
  2988. //
  2989. // Arguments:
  2990. // varIndex [IN] - Contains the index of the resource to delete.
  2991. //
  2992. // Return Value:
  2993. // S_OK if successful, E_POINTER, or Win32 as HRESULT error.
  2994. //
  2995. //--
  2996. /////////////////////////////////////////////////////////////////////////////
  2997. STDMETHODIMP CClusResGroupResources::DeleteItem( VARIANT varIndex )
  2998. {
  2999. return CResources::DeleteItem( varIndex );
  3000. } //*** CClusResGroupResources::DeleteItem()
  3001. /////////////////////////////////////////////////////////////////////////////
  3002. //++
  3003. //
  3004. // CClusResGroupResources::Refresh
  3005. //
  3006. // Description:
  3007. // Load the collection from the cluster database.
  3008. //
  3009. // Arguments:
  3010. // None.
  3011. //
  3012. // Return Value:
  3013. // S_OK if successful, E_POINTER, or Win32 error as HRESULT.
  3014. //
  3015. //--
  3016. /////////////////////////////////////////////////////////////////////////////
  3017. STDMETHODIMP CClusResGroupResources::Refresh( void )
  3018. {
  3019. HGROUPENUM hEnum = NULL;
  3020. DWORD _sc = ERROR_SUCCESS;
  3021. HRESULT _hr = S_OK;
  3022. hEnum = ::ClusterGroupOpenEnum( m_hGroup, CLUSTER_GROUP_ENUM_CONTAINS );
  3023. if ( hEnum != NULL )
  3024. {
  3025. int _nIndex = 0;
  3026. DWORD dwType;
  3027. LPWSTR pszName = NULL;
  3028. CComObject< CClusResource > * pClusterResource = NULL;
  3029. Clear();
  3030. for( _nIndex = 0, _hr = S_OK; SUCCEEDED( _hr ); _nIndex++ )
  3031. {
  3032. _sc = ::WrapClusterGroupEnum( hEnum, _nIndex, &dwType, &pszName );
  3033. if ( _sc == ERROR_NO_MORE_ITEMS )
  3034. {
  3035. _hr = S_OK;
  3036. break;
  3037. }
  3038. else if ( _sc == ERROR_SUCCESS )
  3039. {
  3040. _hr = CComObject< CClusResource >::CreateInstance( &pClusterResource );
  3041. if ( SUCCEEDED( _hr ) )
  3042. {
  3043. CSmartPtr< ISClusRefObject > ptrRefObject( m_pClusRefObject );
  3044. CSmartPtr< CComObject< CClusResource > > ptrResource( pClusterResource );
  3045. _hr = ptrResource->Open( ptrRefObject, pszName );
  3046. if ( SUCCEEDED( _hr ) )
  3047. {
  3048. ptrResource->AddRef();
  3049. m_Resources.insert( m_Resources.end(), ptrResource );
  3050. }
  3051. }
  3052. ::LocalFree( pszName );
  3053. pszName = NULL;
  3054. }
  3055. else
  3056. {
  3057. _hr = HRESULT_FROM_WIN32( _sc );
  3058. }
  3059. }
  3060. ::ClusterGroupCloseEnum( hEnum );
  3061. }
  3062. else
  3063. {
  3064. _sc = GetLastError();
  3065. _hr = HRESULT_FROM_WIN32( _sc );
  3066. }
  3067. return _hr;
  3068. } //*** CClusResGroupResources::Refresh()
  3069. /////////////////////////////////////////////////////////////////////////////
  3070. //++
  3071. //
  3072. // CClusResGroupResources::get_Item
  3073. //
  3074. // Description:
  3075. // Return the object (Resource) at the passed in index.
  3076. //
  3077. // Arguments:
  3078. // varIndex [IN] - Contains the index requested.
  3079. // ppResource [OUT] - Catches the item.
  3080. //
  3081. // Return Value:
  3082. // S_OK if successful, E_POINTER, or E_INVALIDARG.
  3083. //
  3084. //--
  3085. /////////////////////////////////////////////////////////////////////////////
  3086. STDMETHODIMP CClusResGroupResources::get_Item(
  3087. IN VARIANT varIndex,
  3088. OUT ISClusResource ** ppResource
  3089. )
  3090. {
  3091. return GetResourceItem( varIndex, ppResource );
  3092. } //*** CClusResGroupResources::get_Item()
  3093. //*************************************************************************//
  3094. /////////////////////////////////////////////////////////////////////////////
  3095. // CClusResTypeResources class
  3096. /////////////////////////////////////////////////////////////////////////////
  3097. /////////////////////////////////////////////////////////////////////////////
  3098. //++
  3099. //
  3100. // CClusResTypeResources::CClusResTypeResources
  3101. //
  3102. // Description:
  3103. // Constructor.
  3104. //
  3105. // Arguments:
  3106. // None.
  3107. //
  3108. // Return Value:
  3109. // None.
  3110. //
  3111. //--
  3112. /////////////////////////////////////////////////////////////////////////////
  3113. CClusResTypeResources::CClusResTypeResources( void )
  3114. {
  3115. m_piids = (const IID *) iidCClusResTypeResources;
  3116. m_piidsSize = ARRAYSIZE( iidCClusResTypeResources );
  3117. } //*** CClusResTypeResources::CClusResTypeResources()
  3118. /////////////////////////////////////////////////////////////////////////////
  3119. //++
  3120. //
  3121. // CClusResTypeResources::~CClusResTypeResources
  3122. //
  3123. // Description:
  3124. // Destructor.
  3125. //
  3126. // Arguments:
  3127. // None.
  3128. //
  3129. // Return Value:
  3130. // None.
  3131. //
  3132. //--
  3133. /////////////////////////////////////////////////////////////////////////////
  3134. CClusResTypeResources::~CClusResTypeResources( void )
  3135. {
  3136. Clear();
  3137. } //*** CClusResTypeResources::~CClusResTypeResources()
  3138. /////////////////////////////////////////////////////////////////////////////
  3139. //++
  3140. //
  3141. // CClusResTypeResources::get_Count
  3142. //
  3143. // Description:
  3144. // Return the count of objects (Resource) in the collection.
  3145. //
  3146. // Arguments:
  3147. // plCount [OUT] - Catches the count.
  3148. //
  3149. // Return Value:
  3150. // S_OK if successful, or E_POINTER.
  3151. //
  3152. //--
  3153. /////////////////////////////////////////////////////////////////////////////
  3154. STDMETHODIMP CClusResTypeResources::get_Count( OUT long * plCount )
  3155. {
  3156. //ASSERT( plCount != NULL );
  3157. HRESULT _hr = E_POINTER;
  3158. if ( plCount != NULL )
  3159. {
  3160. *plCount = m_Resources.size();
  3161. _hr = S_OK;
  3162. }
  3163. return _hr;
  3164. } //*** CClusResTypeResources::get_Count()
  3165. /////////////////////////////////////////////////////////////////////////////
  3166. //++
  3167. //
  3168. // CClusResTypeResources::Create
  3169. //
  3170. // Description:
  3171. // Finish creating the object by doing things that cannot be done in
  3172. // a light weight constructor.
  3173. //
  3174. // Arguments:
  3175. // pClusRefObject [IN] - Wraps the cluster handle.
  3176. // bstrResTypeName [IN] - The name of the resource type this collection
  3177. // belongs to.
  3178. //
  3179. // Return Value:
  3180. // S_OK if successful or E_POINTER if not.
  3181. //
  3182. //--
  3183. /////////////////////////////////////////////////////////////////////////////
  3184. HRESULT CClusResTypeResources::Create(
  3185. IN ISClusRefObject * pClusRefObject,
  3186. IN BSTR bstrResTypeName
  3187. )
  3188. {
  3189. HRESULT _hr = E_POINTER;
  3190. _hr = CResources::Create( pClusRefObject );
  3191. if ( SUCCEEDED( _hr ) )
  3192. {
  3193. m_bstrResourceTypeName = bstrResTypeName;
  3194. } // if:
  3195. return _hr;
  3196. } //*** CClusResTypeResources::Create()
  3197. /////////////////////////////////////////////////////////////////////////////
  3198. //++
  3199. //
  3200. // CClusResTypeResources::get__NewEnum
  3201. //
  3202. // Description:
  3203. // Create and return a new enumeration for this collection.
  3204. //
  3205. // Arguments:
  3206. // ppunk [OUT] - Catches the new enumeration.
  3207. //
  3208. // Return Value:
  3209. // S_OK if successful, E_POINTER, or other HRESULT error.
  3210. //
  3211. //--
  3212. /////////////////////////////////////////////////////////////////////////////
  3213. STDMETHODIMP CClusResTypeResources::get__NewEnum( OUT IUnknown ** ppunk )
  3214. {
  3215. return ::HrNewIDispatchEnum< ResourceList, CComObject< CClusResource > >( ppunk, m_Resources );
  3216. } //*** CClusResTypeResources::get__NewEnum()
  3217. /////////////////////////////////////////////////////////////////////////////
  3218. //++
  3219. //
  3220. // CClusResTypeResources::CreateItem
  3221. //
  3222. // Description:
  3223. // Create a new item and add it to the collection.
  3224. //
  3225. // Arguments:
  3226. // bstrResourceName [IN] - The name of the resource to create.
  3227. // bstrGroupName [IN] - The group to create it in.
  3228. // dwFlags [IN] - Resource monitor flag.
  3229. // ppClusterResource [OUT] - Catches the new resource.
  3230. //
  3231. // Return Value:
  3232. // S_OK if successful, E_POINTER, or Win32 as HRESULT error.
  3233. //
  3234. //--
  3235. /////////////////////////////////////////////////////////////////////////////
  3236. STDMETHODIMP CClusResTypeResources::CreateItem(
  3237. IN BSTR bstrResourceName,
  3238. IN BSTR bstrGroupName,
  3239. IN CLUSTER_RESOURCE_CREATE_FLAGS dwFlags,
  3240. OUT ISClusResource ** ppClusterResource
  3241. )
  3242. {
  3243. //ASSERT( bstrResourceName != NULL );
  3244. //ASSERT( bstrGroupName != NULL );
  3245. //ASSERT( ppClusterResource != NULL );
  3246. HRESULT _hr = E_POINTER;
  3247. if ( ( bstrResourceName != NULL ) &&
  3248. ( bstrGroupName != NULL ) &&
  3249. ( ppClusterResource != NULL ) )
  3250. {
  3251. *ppClusterResource = NULL;
  3252. // Fail if no valid cluster handle.
  3253. if ( m_pClusRefObject != NULL )
  3254. {
  3255. UINT _nIndex;
  3256. _hr = FindItem( bstrResourceName, &_nIndex );
  3257. if ( FAILED( _hr ) ) // duplicates are not allowed
  3258. {
  3259. HCLUSTER hCluster = NULL;
  3260. HGROUP hGroup = NULL;
  3261. CComObject< CClusResource > * pClusterResource = NULL;
  3262. _hr = m_pClusRefObject->get_Handle( (ULONG_PTR *) &hCluster );
  3263. if ( SUCCEEDED( _hr ) )
  3264. {
  3265. hGroup = OpenClusterGroup( hCluster, bstrGroupName );
  3266. if ( hGroup != NULL )
  3267. {
  3268. _hr = CComObject< CClusResource >::CreateInstance( &pClusterResource );
  3269. if ( SUCCEEDED( _hr ) )
  3270. {
  3271. CSmartPtr< ISClusRefObject > ptrRefObject( m_pClusRefObject );
  3272. CSmartPtr< CComObject< CClusResource > > ptrResource( pClusterResource );
  3273. _hr = ptrResource->Create( ptrRefObject, hGroup, bstrResourceName, m_bstrResourceTypeName, dwFlags );
  3274. if ( SUCCEEDED( _hr ) )
  3275. {
  3276. _hr = ptrResource->QueryInterface( IID_ISClusResource, (void **) ppClusterResource );
  3277. if ( SUCCEEDED( _hr ) )
  3278. {
  3279. ptrResource->AddRef();
  3280. m_Resources.insert( m_Resources.end(), ptrResource );
  3281. } // if: QI ok
  3282. } // if: Create ok
  3283. } // if: CreateInstance ok
  3284. CloseClusterGroup( hGroup );
  3285. } // if: OpenClusterGroup ok
  3286. else
  3287. {
  3288. DWORD _sc = GetLastError();
  3289. _hr = HRESULT_FROM_WIN32( _sc );
  3290. }
  3291. } // if: get_Handle ok
  3292. } // if: FindIndex failed. No duplicate entries
  3293. else
  3294. {
  3295. CComObject<CClusResource> * pClusterResource = NULL;
  3296. pClusterResource = m_Resources[ _nIndex ];
  3297. _hr = pClusterResource->QueryInterface( IID_ISClusResource, (void **) ppClusterResource );
  3298. } // else: found a duplicate
  3299. } // if: m_pClusRefObject is not NULL
  3300. } // if: any NULL argument pointers
  3301. return _hr;
  3302. } //*** CClusResTypeResources::CreateItem()
  3303. /////////////////////////////////////////////////////////////////////////////
  3304. //++
  3305. //
  3306. // CClusResTypeResources::DeleteItem
  3307. //
  3308. // Description:
  3309. // Delete the resource at the passed in index from the collection and
  3310. // the cluster.
  3311. //
  3312. // Arguments:
  3313. // varIndex [IN] - Contains the index of the resource to delete.
  3314. //
  3315. // Return Value:
  3316. // S_OK if successful, E_POINTER, or Win32 as HRESULT error.
  3317. //
  3318. //--
  3319. /////////////////////////////////////////////////////////////////////////////
  3320. STDMETHODIMP CClusResTypeResources::DeleteItem( IN VARIANT varIndex )
  3321. {
  3322. return CResources::DeleteItem( varIndex );
  3323. } //*** CClusResTypeResources::DeleteItem()
  3324. /////////////////////////////////////////////////////////////////////////////
  3325. //++
  3326. //
  3327. // CClusResTypeResources::Refresh
  3328. //
  3329. // Description:
  3330. // Load the collection from the cluster database.
  3331. //
  3332. // Arguments:
  3333. // None.
  3334. //
  3335. // Return Value:
  3336. // S_OK if successful, E_POINTER, or Win32 error as HRESULT.
  3337. //
  3338. //--
  3339. /////////////////////////////////////////////////////////////////////////////
  3340. STDMETHODIMP CClusResTypeResources::Refresh( void )
  3341. {
  3342. DWORD _sc = ERROR_SUCCESS;
  3343. HRESULT _hr = E_POINTER;
  3344. HCLUSTER hCluster = NULL;
  3345. if ( m_pClusRefObject != NULL )
  3346. {
  3347. HCLUSENUM hEnum = NULL;
  3348. _hr = m_pClusRefObject->get_Handle( (ULONG_PTR *) &hCluster );
  3349. if ( SUCCEEDED( _hr ) )
  3350. {
  3351. hEnum = ::ClusterOpenEnum( hCluster, CLUSTER_ENUM_RESOURCE );
  3352. if ( hEnum != NULL )
  3353. {
  3354. int _nIndex = 0;
  3355. DWORD dwType = 0;
  3356. LPWSTR pszName = NULL;
  3357. HRESOURCE hResource = NULL;
  3358. WCHAR strResType[1024];
  3359. DWORD dwData = 0;
  3360. CComObject< CClusResource > * pClusterResource = NULL;
  3361. Clear();
  3362. for( _nIndex = 0, _hr = S_OK; SUCCEEDED( _hr ); _nIndex++ )
  3363. {
  3364. _sc = ::WrapClusterEnum( hEnum, _nIndex, &dwType, &pszName );
  3365. if ( _sc == ERROR_NO_MORE_ITEMS )
  3366. {
  3367. _hr = S_OK;
  3368. break;
  3369. }
  3370. else if ( _sc == ERROR_SUCCESS )
  3371. {
  3372. _hr = CComObject< CClusResource >::CreateInstance( &pClusterResource );
  3373. if ( SUCCEEDED( _hr ) )
  3374. {
  3375. CSmartPtr< ISClusRefObject > ptrRefObject( m_pClusRefObject );
  3376. CSmartPtr< CComObject< CClusResource > > ptrResource( pClusterResource );
  3377. _hr = ptrResource->Open( ptrRefObject, pszName );
  3378. if ( SUCCEEDED( _hr ) )
  3379. {
  3380. _hr = ptrResource->get_Handle( (ULONG_PTR *) &hResource );
  3381. if ( SUCCEEDED( _hr ) )
  3382. {
  3383. _sc = ClusterResourceControl(
  3384. hResource,
  3385. NULL,
  3386. CLUSCTL_RESOURCE_GET_RESOURCE_TYPE,
  3387. NULL,
  3388. 0,
  3389. strResType,
  3390. sizeof( strResType ),
  3391. &dwData
  3392. );
  3393. if ( _sc == ERROR_SUCCESS )
  3394. {
  3395. if ( lstrcmpi( strResType, m_bstrResourceTypeName ) == 0 )
  3396. {
  3397. ptrResource->AddRef();
  3398. m_Resources.insert( m_Resources.end(), ptrResource );
  3399. }
  3400. }
  3401. else
  3402. {
  3403. _hr = HRESULT_FROM_WIN32( _sc );
  3404. }
  3405. }
  3406. }
  3407. }
  3408. ::LocalFree( pszName );
  3409. pszName = NULL;
  3410. }
  3411. else
  3412. {
  3413. _hr = HRESULT_FROM_WIN32( _sc );
  3414. }
  3415. }
  3416. ::ClusterCloseEnum( hEnum );
  3417. }
  3418. else
  3419. {
  3420. _sc = GetLastError();
  3421. _hr = HRESULT_FROM_WIN32( _sc );
  3422. }
  3423. }
  3424. }
  3425. return _hr;
  3426. } //*** CClusResTypeResources::Refresh()
  3427. /////////////////////////////////////////////////////////////////////////////
  3428. //++
  3429. //
  3430. // CClusResTypeResources::get_Item
  3431. //
  3432. // Description:
  3433. // Return the object (Resource) at the passed in index.
  3434. //
  3435. // Arguments:
  3436. // varIndex [IN] - Contains the index requested.
  3437. // ppResource [OUT] - Catches the item.
  3438. //
  3439. // Return Value:
  3440. // S_OK if successful, E_POINTER, or E_INVALIDARG.
  3441. //
  3442. //--
  3443. /////////////////////////////////////////////////////////////////////////////
  3444. STDMETHODIMP CClusResTypeResources::get_Item(
  3445. IN VARIANT varIndex,
  3446. OUT ISClusResource ** ppResource
  3447. )
  3448. {
  3449. return GetResourceItem( varIndex, ppResource );
  3450. } //*** CClusResTypeResources::get_Item()