Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

4167 lines
122 KiB

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