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

1451 lines
33 KiB

  1. /////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1997-2000 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // ClusResT.cpp
  7. //
  8. // Description:
  9. // Implementation of the resource type classes for the MSCLUS
  10. // automation classes.
  11. //
  12. // Author:
  13. // Charles Stacy Harris (stacyh) 28-Feb-1997
  14. // Galen Barbee (galenb) July 1998
  15. //
  16. // Revision History:
  17. // July 1998 GalenB Maaaaaajjjjjjjjjoooooorrrr clean up
  18. //
  19. // Notes:
  20. //
  21. /////////////////////////////////////////////////////////////////////////////
  22. #include "stdafx.h"
  23. #include "ClusterObject.h"
  24. #include "property.h"
  25. #include "clusres.h"
  26. #include "clusresg.h"
  27. #include "clusneti.h"
  28. #include "clusnode.h"
  29. #include "clusrest.h"
  30. /////////////////////////////////////////////////////////////////////////////
  31. // Global variables
  32. /////////////////////////////////////////////////////////////////////////////
  33. static const IID * iidCClusResourceType[] =
  34. {
  35. &IID_ISClusResType
  36. };
  37. static const IID * iidCClusResourceTypes[] =
  38. {
  39. &IID_ISClusResTypes
  40. };
  41. //*************************************************************************//
  42. /////////////////////////////////////////////////////////////////////////////
  43. // CClusResType class
  44. /////////////////////////////////////////////////////////////////////////////
  45. /////////////////////////////////////////////////////////////////////////////
  46. //++
  47. //
  48. // CClusResType::CClusResType
  49. //
  50. // Description:
  51. // Constructor.
  52. //
  53. // Arguments:
  54. // None.
  55. //
  56. // Return Value:
  57. // None.
  58. //
  59. //--
  60. /////////////////////////////////////////////////////////////////////////////
  61. CClusResType::CClusResType( void )
  62. {
  63. m_pClusRefObject = NULL;
  64. m_pCommonProperties = NULL;
  65. m_pPrivateProperties = NULL;
  66. m_pCommonROProperties = NULL;
  67. m_pPrivateROProperties = NULL;
  68. m_pClusterResTypeResources = NULL;
  69. m_piids = (const IID *) iidCClusResourceType;
  70. m_piidsSize = ARRAYSIZE( iidCClusResourceType );
  71. } //*** CClusResType::CClusResType()
  72. /////////////////////////////////////////////////////////////////////////////
  73. //++
  74. //
  75. // CClusResType::~CClusResType
  76. //
  77. // Description:
  78. // Destructor.
  79. //
  80. // Arguments:
  81. // None.
  82. //
  83. // Return Value:
  84. // None.
  85. //
  86. //--
  87. /////////////////////////////////////////////////////////////////////////////
  88. CClusResType::~CClusResType( void )
  89. {
  90. if ( m_pCommonProperties != NULL )
  91. {
  92. m_pCommonProperties->Release();
  93. m_pCommonProperties = NULL;
  94. } // if: release the property collection
  95. if ( m_pPrivateProperties != NULL )
  96. {
  97. m_pPrivateProperties->Release();
  98. m_pPrivateProperties = NULL;
  99. } // if: release the property collection
  100. if ( m_pCommonROProperties != NULL )
  101. {
  102. m_pCommonROProperties->Release();
  103. m_pCommonROProperties = NULL;
  104. } // if: release the property collection
  105. if ( m_pPrivateROProperties != NULL )
  106. {
  107. m_pPrivateROProperties->Release();
  108. m_pPrivateROProperties = NULL;
  109. } // if: release the property collection
  110. if ( m_pClusterResTypeResources != NULL )
  111. {
  112. m_pClusterResTypeResources->Release();
  113. m_pClusterResTypeResources = NULL;
  114. }
  115. if ( m_pClusRefObject != NULL )
  116. {
  117. m_pClusRefObject->Release();
  118. m_pClusRefObject = NULL;
  119. }
  120. } //*** CClusResType::~CClusResType()
  121. /////////////////////////////////////////////////////////////////////////////
  122. //++
  123. //
  124. // CClusResType::GetProperties
  125. //
  126. // Description:
  127. // Creates a property collection for this object type (Resource Type).
  128. //
  129. // Arguments:
  130. // ppProperties [OUT] - Catches the newly created collection.
  131. // bPrivate [IN] - Are these private properties? Or Common?
  132. // bReadOnly [IN] - Are these read only properties?
  133. //
  134. // Return Value:
  135. // S_OK if successful, or other HRESULT error.
  136. //
  137. //--
  138. /////////////////////////////////////////////////////////////////////////////
  139. HRESULT CClusResType::GetProperties(
  140. OUT ISClusProperties ** ppProperties,
  141. IN BOOL bPrivate,
  142. IN BOOL bReadOnly
  143. )
  144. {
  145. //ASSERT( ppProperties != NULL );
  146. HRESULT _hr = E_POINTER;
  147. if ( ppProperties != NULL )
  148. {
  149. *ppProperties = NULL;
  150. CComObject< CClusProperties > * pProperties = NULL;
  151. _hr = CComObject< CClusProperties >::CreateInstance( &pProperties );
  152. if ( SUCCEEDED( _hr ) )
  153. {
  154. CSmartPtr< CComObject< CClusProperties > > ptrProperties( pProperties );
  155. _hr = ptrProperties->Create( this, bPrivate, bReadOnly );
  156. if ( SUCCEEDED( _hr ) )
  157. {
  158. _hr = ptrProperties->Refresh();
  159. if ( SUCCEEDED( _hr ) )
  160. {
  161. _hr = ptrProperties->QueryInterface( IID_ISClusProperties, (void **) ppProperties );
  162. if ( SUCCEEDED( _hr ) )
  163. {
  164. ptrProperties->AddRef();
  165. if ( bPrivate )
  166. {
  167. if ( bReadOnly )
  168. {
  169. m_pPrivateROProperties = pProperties;
  170. }
  171. else
  172. {
  173. m_pPrivateProperties = pProperties;
  174. }
  175. }
  176. else
  177. {
  178. if ( bReadOnly )
  179. {
  180. m_pCommonROProperties = pProperties;
  181. }
  182. else
  183. {
  184. m_pCommonProperties = pProperties;
  185. }
  186. }
  187. }
  188. }
  189. }
  190. }
  191. }
  192. return _hr;
  193. } //*** CClusResType::GetProperties()
  194. /////////////////////////////////////////////////////////////////////////////
  195. //++
  196. //
  197. // CClusResType::Create
  198. //
  199. // Description:
  200. // Create a new Resource Type and add it to the cluster.
  201. //
  202. // Arguments:
  203. // pClusRefObject [IN] - Cluster handle wrapper.
  204. // bstrResourceTypeName [IN] - Name of the new resource type.
  205. // bstrDisplayName [IN] - Resource type display name.
  206. // bstrResourceTypeDll [IN] - Resource type implementation dll.
  207. // dwLooksAlivePollInterval [IN] - Looks alive poll interval.
  208. // dwIsAlivePollInterval [IN] - Is alive poll interval.
  209. //
  210. // Return Value:
  211. // S_OK if successful, or Win32 error wrapped in HRESULT.
  212. //
  213. //--
  214. /////////////////////////////////////////////////////////////////////////////
  215. HRESULT CClusResType::Create(
  216. IN ISClusRefObject * pClusRefObject,
  217. IN BSTR bstrResourceTypeName,
  218. IN BSTR bstrDisplayName,
  219. IN BSTR bstrResourceTypeDll,
  220. IN long dwLooksAlivePollInterval,
  221. IN long dwIsAlivePollInterval
  222. )
  223. {
  224. ASSERT( pClusRefObject != NULL );
  225. ASSERT( bstrResourceTypeName != NULL );
  226. ASSERT( bstrDisplayName != NULL );
  227. ASSERT( bstrResourceTypeDll != NULL );
  228. HRESULT _hr = E_POINTER;
  229. if ( ( pClusRefObject != NULL ) &&
  230. ( pClusRefObject != NULL ) &&
  231. ( bstrResourceTypeName != NULL ) &&
  232. ( bstrDisplayName != NULL ) )
  233. {
  234. DWORD _sc = 0;
  235. HCLUSTER hCluster = NULL;
  236. m_pClusRefObject= pClusRefObject;
  237. m_pClusRefObject->AddRef();
  238. _hr = m_pClusRefObject->get_Handle( (ULONG_PTR *) &hCluster);
  239. if ( SUCCEEDED( _hr ) )
  240. {
  241. _sc = CreateClusterResourceType(
  242. hCluster,
  243. bstrResourceTypeName,
  244. bstrDisplayName,
  245. bstrResourceTypeDll,
  246. dwLooksAlivePollInterval,
  247. dwIsAlivePollInterval
  248. );
  249. if ( _sc == ERROR_SUCCESS )
  250. {
  251. m_bstrResourceTypeName = bstrResourceTypeName ;
  252. }
  253. _hr = HRESULT_FROM_WIN32( _sc );
  254. }
  255. }
  256. return _hr;
  257. } //*** CClusResType::Create()
  258. /////////////////////////////////////////////////////////////////////////////
  259. //++
  260. //
  261. // CClusResType::Open
  262. //
  263. // Description:
  264. // Create a resource type object from an existing object in the cluster.
  265. //
  266. // Arguments:
  267. // pClusRefObject [IN] - Cluster handle wrapper.
  268. // bstrResourceTypeName [IN] - Name of the resource type to open.
  269. //
  270. // Return Value:
  271. // S_OK if successful, or other HRESULT error.
  272. //
  273. //--
  274. /////////////////////////////////////////////////////////////////////////////
  275. HRESULT CClusResType::Open(
  276. IN ISClusRefObject * pClusRefObject,
  277. IN BSTR bstrResourceTypeName
  278. )
  279. {
  280. ASSERT( pClusRefObject != NULL );
  281. //ASSERT( bstrResourceTypeName != NULL );
  282. HRESULT _hr = E_POINTER;
  283. if ( ( pClusRefObject != NULL ) && ( bstrResourceTypeName != NULL ) )
  284. {
  285. m_pClusRefObject = pClusRefObject;
  286. m_pClusRefObject->AddRef();
  287. m_bstrResourceTypeName = bstrResourceTypeName;
  288. return S_OK;
  289. }
  290. return _hr;
  291. } //*** CClusResType::Open()
  292. /////////////////////////////////////////////////////////////////////////////
  293. //++
  294. //
  295. // CClusResType::get_Name
  296. //
  297. // Description:
  298. // Return the name of this object (Resource Type).
  299. //
  300. // Arguments:
  301. // pbstrTypeName [OUT] - Catches the name of this object.
  302. //
  303. // Return Value:
  304. // S_OK if successful, E_POINTER, or other HRESULT error.
  305. //
  306. //--
  307. /////////////////////////////////////////////////////////////////////////////
  308. STDMETHODIMP CClusResType::get_Name( OUT BSTR * pbstrTypeName )
  309. {
  310. //ASSERT( pbstrTypeName != NULL );
  311. HRESULT _hr = E_POINTER;
  312. if ( pbstrTypeName != NULL )
  313. {
  314. *pbstrTypeName = m_bstrResourceTypeName.Copy();
  315. _hr = S_OK;
  316. }
  317. return _hr;
  318. } //*** CClusResType::get_Name()
  319. /////////////////////////////////////////////////////////////////////////////
  320. //++
  321. //
  322. // CClusResType::Delete
  323. //
  324. // Description:
  325. // Removes this object (Resource Type) from the cluster.
  326. //
  327. // Arguments:
  328. // None.
  329. //
  330. // Return Value:
  331. // S_OK if successful, E_POINTER, or other HRESULT error.
  332. //
  333. //--
  334. /////////////////////////////////////////////////////////////////////////////
  335. STDMETHODIMP CClusResType::Delete( void )
  336. {
  337. ASSERT( m_bstrResourceTypeName != NULL );
  338. HRESULT _hr = E_POINTER;
  339. if ( m_bstrResourceTypeName != NULL )
  340. {
  341. HCLUSTER hCluster = NULL;
  342. _hr = m_pClusRefObject->get_Handle( (ULONG_PTR *) &hCluster );
  343. if ( SUCCEEDED( _hr ) )
  344. {
  345. DWORD _sc = DeleteClusterResourceType( hCluster, m_bstrResourceTypeName );
  346. _hr = HRESULT_FROM_WIN32( _sc );
  347. }
  348. }
  349. return _hr;
  350. } //*** CClusResType::Delete()
  351. /////////////////////////////////////////////////////////////////////////////
  352. //++
  353. //
  354. // CClusResType::get_CommonProperties
  355. //
  356. // Description:
  357. // Get this object's (Resource Type) common properties collection.
  358. //
  359. // Arguments:
  360. // ppProperties [OUT] - Catches the properties collection.
  361. //
  362. // Return Value:
  363. // S_OK if successful, or other HRESULT error.
  364. //
  365. //--
  366. /////////////////////////////////////////////////////////////////////////////
  367. STDMETHODIMP CClusResType::get_CommonProperties(
  368. OUT ISClusProperties ** ppProperties
  369. )
  370. {
  371. //ASSERT( ppProperties != NULL );
  372. HRESULT _hr = E_POINTER;
  373. if ( ppProperties != NULL )
  374. {
  375. if ( m_pCommonProperties != NULL )
  376. {
  377. _hr = m_pCommonProperties->QueryInterface( IID_ISClusProperties, (void **) ppProperties );
  378. }
  379. else
  380. {
  381. _hr = GetProperties( ppProperties, FALSE, FALSE );
  382. }
  383. }
  384. return _hr;
  385. } //*** CClusResType::get_CommonProperties()
  386. /////////////////////////////////////////////////////////////////////////////
  387. //++
  388. //
  389. // CClusResType::get_PrivateProperties
  390. //
  391. // Description:
  392. // Get this object's (Resource Type) private properties collection.
  393. //
  394. // Arguments:
  395. // ppProperties [OUT] - Catches the properties collection.
  396. //
  397. // Return Value:
  398. // S_OK if successful, or other HRESULT error.
  399. //
  400. //--
  401. /////////////////////////////////////////////////////////////////////////////
  402. STDMETHODIMP CClusResType::get_PrivateProperties(
  403. OUT ISClusProperties ** ppProperties
  404. )
  405. {
  406. //ASSERT( ppProperties != NULL );
  407. HRESULT _hr = E_POINTER;
  408. if ( ppProperties != NULL )
  409. {
  410. if ( m_pPrivateProperties != NULL )
  411. {
  412. _hr = m_pPrivateProperties->QueryInterface( IID_ISClusProperties, (void **) ppProperties );
  413. }
  414. else
  415. {
  416. _hr = GetProperties( ppProperties, TRUE, FALSE );
  417. }
  418. }
  419. return _hr;
  420. } //*** CClusResType::get_PrivateProperties()
  421. /////////////////////////////////////////////////////////////////////////////
  422. //++
  423. //
  424. // CClusResType::get_CommonROProperties
  425. //
  426. // Description:
  427. // Get this object's (Resource Type) common read only properties collection.
  428. //
  429. // Arguments:
  430. // ppProperties [OUT] - Catches the properties collection.
  431. //
  432. // Return Value:
  433. // S_OK if successful, or other HRESULT error.
  434. //
  435. //--
  436. /////////////////////////////////////////////////////////////////////////////
  437. STDMETHODIMP CClusResType::get_CommonROProperties(
  438. OUT ISClusProperties ** ppProperties
  439. )
  440. {
  441. //ASSERT( ppProperties != NULL );
  442. HRESULT _hr = E_POINTER;
  443. if ( ppProperties != NULL )
  444. {
  445. if ( m_pCommonROProperties != NULL )
  446. {
  447. _hr = m_pCommonROProperties->QueryInterface( IID_ISClusProperties, (void **) ppProperties );
  448. }
  449. else
  450. {
  451. _hr = GetProperties( ppProperties, FALSE, TRUE );
  452. }
  453. }
  454. return _hr;
  455. } //*** CClusResType::get_CommonROProperties()
  456. /////////////////////////////////////////////////////////////////////////////
  457. //++
  458. //
  459. // CClusResType::get_PrivateROProperties
  460. //
  461. // Description:
  462. // Get this object's (Resource Type) private readonly properties collection.
  463. //
  464. // Arguments:
  465. // ppProperties [OUT] - Catches the properties collection.
  466. //
  467. // Return Value:
  468. // S_OK if successful, or other HRESULT error.
  469. //
  470. //--
  471. /////////////////////////////////////////////////////////////////////////////
  472. STDMETHODIMP CClusResType::get_PrivateROProperties(
  473. OUT ISClusProperties ** ppProperties
  474. )
  475. {
  476. //ASSERT( ppProperties != NULL );
  477. HRESULT _hr = E_POINTER;
  478. if ( ppProperties != NULL )
  479. {
  480. if ( m_pPrivateROProperties != NULL )
  481. {
  482. _hr = m_pPrivateROProperties->QueryInterface( IID_ISClusProperties, (void **) ppProperties );
  483. }
  484. else
  485. {
  486. _hr = GetProperties( ppProperties, TRUE, TRUE );
  487. }
  488. }
  489. return _hr;
  490. } //*** CClusResType::get_PrivateROProperties()
  491. /////////////////////////////////////////////////////////////////////////////
  492. //++
  493. //
  494. // CClusResType::get_Cluster
  495. //
  496. // Description:
  497. //
  498. //
  499. // Arguments:
  500. //
  501. //
  502. // Return Value:
  503. // S_OK if successful, or other HRESULT error.
  504. //
  505. //--
  506. /////////////////////////////////////////////////////////////////////////////
  507. STDMETHODIMP CClusResType::get_Cluster(
  508. ISCluster ** ppCluster
  509. )
  510. {
  511. return ::HrGetCluster( ppCluster, m_pClusRefObject );
  512. } //*** CClusResType::get_Cluster()
  513. /////////////////////////////////////////////////////////////////////////////
  514. //++
  515. //
  516. // CClusResType::HrLoadProperties
  517. //
  518. // Description:
  519. // This virtual function does the actual load of the property list from
  520. // the cluster.
  521. //
  522. // Arguments:
  523. // rcplPropList [IN OUT] - The property list to load.
  524. // bReadOnly [IN] - Load the read only properties?
  525. // bPrivate [IN] - Load the common or the private properties?
  526. //
  527. // Return Value:
  528. // S_OK if successful, or other HRESULT error.
  529. //
  530. //--
  531. /////////////////////////////////////////////////////////////////////////////
  532. HRESULT CClusResType::HrLoadProperties(
  533. IN OUT CClusPropList & rcplPropList,
  534. IN BOOL bReadOnly,
  535. IN BOOL bPrivate
  536. )
  537. {
  538. ASSERT( m_pClusRefObject != NULL );
  539. HRESULT _hr = E_POINTER;
  540. if ( m_pClusRefObject != NULL )
  541. {
  542. HCLUSTER hCluster = NULL;
  543. _hr = m_pClusRefObject->get_Handle( (ULONG_PTR *) &hCluster );
  544. if ( SUCCEEDED( _hr ) )
  545. {
  546. DWORD _dwControlCode = 0;
  547. DWORD _sc = ERROR_SUCCESS;
  548. if ( bReadOnly )
  549. {
  550. _dwControlCode = bPrivate
  551. ? CLUSCTL_RESOURCE_TYPE_GET_RO_PRIVATE_PROPERTIES
  552. : CLUSCTL_RESOURCE_TYPE_GET_RO_COMMON_PROPERTIES;
  553. }
  554. else
  555. {
  556. _dwControlCode = bPrivate
  557. ? CLUSCTL_RESOURCE_TYPE_GET_PRIVATE_PROPERTIES
  558. : CLUSCTL_RESOURCE_TYPE_GET_COMMON_PROPERTIES;
  559. }
  560. _sc = rcplPropList.ScGetResourceTypeProperties( hCluster, m_bstrResourceTypeName, _dwControlCode );
  561. _hr = HRESULT_FROM_WIN32( _sc );
  562. } // if:
  563. } // if:
  564. return _hr;
  565. } //*** CClusResType::HrLoadProperties()
  566. /////////////////////////////////////////////////////////////////////////////
  567. //++
  568. //
  569. // CClusResType::ScWriteProperties
  570. //
  571. // Description:
  572. // This virtual function does the actual saving of the property list to
  573. // the cluster.
  574. //
  575. // Arguments:
  576. // rcplPropList [IN] - The property list to save.
  577. // bPrivate [IN] - Save the common or the private properties?
  578. //
  579. // Return Value:
  580. // ERROR_SUCCESS if successful, or other Win32 error if not.
  581. //
  582. //--
  583. /////////////////////////////////////////////////////////////////////////////
  584. DWORD CClusResType::ScWriteProperties(
  585. const CClusPropList & rcplPropList,
  586. BOOL bPrivate
  587. )
  588. {
  589. ASSERT( m_pClusRefObject != NULL );
  590. DWORD _sc = ERROR_BAD_ARGUMENTS;
  591. if ( m_pClusRefObject != NULL )
  592. {
  593. HCLUSTER hCluster = NULL;
  594. if ( S_OK == m_pClusRefObject->get_Handle( (ULONG_PTR *) &hCluster ) )
  595. {
  596. DWORD dwControlCode = bPrivate
  597. ? CLUSCTL_RESOURCE_TYPE_SET_PRIVATE_PROPERTIES
  598. : CLUSCTL_RESOURCE_TYPE_SET_COMMON_PROPERTIES;
  599. DWORD nBytesReturned = 0;
  600. _sc = ClusterResourceTypeControl(
  601. hCluster,
  602. m_bstrResourceTypeName,
  603. NULL,
  604. dwControlCode,
  605. rcplPropList,
  606. rcplPropList.CbBufferSize(),
  607. 0,
  608. 0,
  609. &nBytesReturned
  610. );
  611. } // if:
  612. } // if:
  613. return _sc;
  614. } //*** CClusResType::ScWriteProperties()
  615. /////////////////////////////////////////////////////////////////////////////
  616. //++
  617. //
  618. // CClusResType::get_Resources
  619. //
  620. // Description:
  621. // Create a collection of the resources of this type.
  622. //
  623. // Arguments:
  624. // ppClusterResTypeResources [OUT] - Catches the collection.
  625. //
  626. // Return Value:
  627. // S_OK if successful, E_POINTER, or Win32 error as HRESULT.
  628. //
  629. //--
  630. /////////////////////////////////////////////////////////////////////////////
  631. STDMETHODIMP CClusResType::get_Resources(
  632. OUT ISClusResTypeResources ** ppClusterResTypeResources
  633. )
  634. {
  635. return ::HrCreateResourceCollection< CClusResTypeResources, ISClusResTypeResources, CComBSTR >(
  636. &m_pClusterResTypeResources,
  637. m_bstrResourceTypeName,
  638. ppClusterResTypeResources,
  639. IID_ISClusResTypeResources,
  640. m_pClusRefObject
  641. );
  642. } //*** CClusResType::get_Resources()
  643. /////////////////////////////////////////////////////////////////////////////
  644. //++
  645. //
  646. // CClusResType::get_PossibleOwnerNodes
  647. //
  648. // Description:
  649. // Create a collection of possible owner nodes for this resource type.
  650. //
  651. // Arguments:
  652. // ppOwnerNodes [OUT] - Catches the collection.
  653. //
  654. // Return Value:
  655. // S_OK if successful, E_POINTER, or Win32 error as HRESULT.
  656. //
  657. //--
  658. /////////////////////////////////////////////////////////////////////////////
  659. STDMETHODIMP CClusResType::get_PossibleOwnerNodes(
  660. ISClusResTypePossibleOwnerNodes ** ppOwnerNodes
  661. )
  662. {
  663. //
  664. // KB: Can't use one of the template functions here! There is an internal compiler error(C1001).
  665. // I am assuming that the type names are too long. Very sad for 1999 ;-)
  666. //
  667. //ASSERT( ppOwnerNodes != NULL );
  668. HRESULT _hr = E_POINTER;
  669. #if CLUSAPI_VERSION >= 0x0500
  670. if ( ppOwnerNodes != NULL )
  671. {
  672. CComObject< CClusResTypePossibleOwnerNodes > * pClusterNodes = NULL;
  673. *ppOwnerNodes = NULL;
  674. _hr = CComObject< CClusResTypePossibleOwnerNodes >::CreateInstance( &pClusterNodes );
  675. if ( SUCCEEDED( _hr ) )
  676. {
  677. CSmartPtr< ISClusRefObject > ptrRefObject( m_pClusRefObject );
  678. CSmartPtr< CComObject< CClusResTypePossibleOwnerNodes > > ptrClusterNodes( pClusterNodes );
  679. _hr = ptrClusterNodes->Create( ptrRefObject, m_bstrResourceTypeName );
  680. if ( SUCCEEDED( _hr ) )
  681. {
  682. _hr = ptrClusterNodes->Refresh();
  683. if ( SUCCEEDED( _hr ) )
  684. {
  685. _hr = ptrClusterNodes->QueryInterface( IID_ISClusResTypePossibleOwnerNodes, (void **) ppOwnerNodes );
  686. }
  687. }
  688. }
  689. }
  690. #else
  691. _hr = E_NOTIMPL;
  692. #endif // CLUSAPI_VERSION >= 0x0500
  693. return _hr;
  694. } //*** CClusResType::get_PossibleOwnerNodes()
  695. /////////////////////////////////////////////////////////////////////////////
  696. //++
  697. //
  698. // CClusResType::get_AvailableDisks
  699. //
  700. // Description:
  701. // Get the collection of available disks.
  702. //
  703. // Arguments:
  704. // ppAvailableDisk [OUT] - catches the available disks collection.
  705. //
  706. // Return Value:
  707. // S_OK if successful, E_POINTER, or Win32 error as HRESULT.
  708. //
  709. //--
  710. /////////////////////////////////////////////////////////////////////////////
  711. STDMETHODIMP CClusResType::get_AvailableDisks(
  712. OUT ISClusDisks ** ppAvailableDisks
  713. )
  714. {
  715. return ::HrCreateResourceCollection< CClusDisks, ISClusDisks, CComBSTR >(
  716. ppAvailableDisks,
  717. m_bstrResourceTypeName,
  718. IID_ISClusDisks,
  719. m_pClusRefObject
  720. );
  721. } //*** CClusResType::get_AvailableDisks()
  722. //*************************************************************************//
  723. /////////////////////////////////////////////////////////////////////////////
  724. // CClusResTypes class
  725. /////////////////////////////////////////////////////////////////////////////
  726. /////////////////////////////////////////////////////////////////////////////
  727. //++
  728. //
  729. // CClusResTypes::CClusResTypes
  730. //
  731. // Description:
  732. // Constructor.
  733. //
  734. // Arguments:
  735. // None.
  736. //
  737. // Return Value:
  738. // None.
  739. //
  740. //--
  741. /////////////////////////////////////////////////////////////////////////////
  742. CClusResTypes::CClusResTypes( void )
  743. {
  744. m_pClusRefObject = NULL;
  745. m_piids = (const IID *) iidCClusResourceTypes;
  746. m_piidsSize = ARRAYSIZE( iidCClusResourceTypes );
  747. } //*** CClusResTypes::CClusResTypes()
  748. /////////////////////////////////////////////////////////////////////////////
  749. //++
  750. //
  751. // CClusResTypes::~CClusResTypes
  752. //
  753. // Description:
  754. // Destructor.
  755. //
  756. // Arguments:
  757. // None.
  758. //
  759. // Return Value:
  760. // None.
  761. //
  762. //--
  763. /////////////////////////////////////////////////////////////////////////////
  764. CClusResTypes::~CClusResTypes( void )
  765. {
  766. Clear();
  767. if ( m_pClusRefObject != NULL )
  768. {
  769. m_pClusRefObject->Release();
  770. m_pClusRefObject = NULL;
  771. }
  772. } //*** CClusResTypes::~CClusResTypes()
  773. /////////////////////////////////////////////////////////////////////////////
  774. //++
  775. //
  776. // CClusResTypes::Create
  777. //
  778. // Description:
  779. // Finish the heavy weight construction.
  780. //
  781. // Arguments:
  782. // pClusRefObject [IN] - Wraps the cluster handle.
  783. //
  784. // Return Value:
  785. // S_OK if successful, or E_POINTER if not.
  786. //
  787. //--
  788. /////////////////////////////////////////////////////////////////////////////
  789. HRESULT CClusResTypes::Create( IN ISClusRefObject * pClusRefObject )
  790. {
  791. ASSERT( pClusRefObject != NULL );
  792. HRESULT _hr = E_POINTER;
  793. if ( pClusRefObject != NULL )
  794. {
  795. m_pClusRefObject = pClusRefObject;
  796. m_pClusRefObject->AddRef();
  797. _hr = S_OK;
  798. } // if: args are not NULL
  799. return _hr;
  800. } //*** CClusResTypes::Create()
  801. /////////////////////////////////////////////////////////////////////////////
  802. //++
  803. //
  804. // CClusResTypes::get_Count
  805. //
  806. // Description:
  807. // Returns the count of elements (ResTypes) in the collection.
  808. //
  809. // Arguments:
  810. // plCount [OUT] - Catches the count.
  811. //
  812. // Return Value:
  813. // S_OK if successful, or E_POINTER if not.
  814. //
  815. //--
  816. /////////////////////////////////////////////////////////////////////////////
  817. STDMETHODIMP CClusResTypes::get_Count( OUT long * plCount )
  818. {
  819. //ASSERT( plCount != NULL );
  820. HRESULT _hr = E_POINTER;
  821. if ( plCount != NULL )
  822. {
  823. *plCount = m_ResourceTypes.size();
  824. _hr = S_OK;
  825. }
  826. return _hr;
  827. } //*** CClusResTypes::get_Count()
  828. /////////////////////////////////////////////////////////////////////////////
  829. //++
  830. //
  831. // CClusResTypes::Clear
  832. //
  833. // Description:
  834. // Clean out the vector of ClusResGroup objects.
  835. //
  836. // Arguments:
  837. // None.
  838. //
  839. // Return Value:
  840. // None.
  841. //
  842. //--
  843. /////////////////////////////////////////////////////////////////////////////
  844. void CClusResTypes::Clear( void )
  845. {
  846. ::ReleaseAndEmptyCollection< ResourceTypeList, CComObject< CClusResType > >( m_ResourceTypes );
  847. } //*** CClusResTypes::Clear()
  848. /////////////////////////////////////////////////////////////////////////////
  849. //++
  850. //
  851. // CClusResTypes::FindItem
  852. //
  853. // Description:
  854. // Find the passed in resource type in the collection.
  855. //
  856. // Arguments:
  857. // pszResourceTypeName [IN] - The name of the resource type to find.
  858. // pnIndex [OUT] - Catches the index of the group.
  859. //
  860. // Return Value:
  861. // S_OK if successful, E_POINTER, or E_INVALIDARG if the resource type
  862. // was not found.
  863. //
  864. //--
  865. /////////////////////////////////////////////////////////////////////////////
  866. HRESULT CClusResTypes::FindItem(
  867. IN LPWSTR pszResourceTypeName,
  868. OUT UINT * pnIndex
  869. )
  870. {
  871. //ASSERT( pszResourceTypeName != NULL );
  872. //ASSERT( pnIndex != NULL );
  873. HRESULT _hr = E_POINTER;
  874. if ( ( pszResourceTypeName != NULL ) && ( pnIndex != NULL ) )
  875. {
  876. CComObject<CClusResType> * pResourceType = NULL;
  877. int nMax = m_ResourceTypes.size();
  878. _hr = E_INVALIDARG;
  879. for( int i = 0; i < nMax; i++ )
  880. {
  881. pResourceType = m_ResourceTypes[i];
  882. if ( pResourceType && ( lstrcmpi( pszResourceTypeName, pResourceType->Name() ) == 0 ) )
  883. {
  884. *pnIndex = i;
  885. _hr = S_OK;
  886. break;
  887. }
  888. }
  889. }
  890. return _hr;
  891. } //*** CClusResTypes::FindItem( pszResourceTypeName )
  892. /////////////////////////////////////////////////////////////////////////////
  893. //++
  894. //
  895. // CClusResTypes::FindItem
  896. //
  897. // Description:
  898. // Find the passed in resource type in the collection.
  899. //
  900. // Arguments:
  901. // pszResourceTypeName [IN] - The name of the resource type to find.
  902. // pnIndex [OUT] - Catches the index of the group.
  903. //
  904. // Return Value:
  905. // S_OK if successful, E_POINTER, or E_INVALIDARG if the resource type
  906. // was not found.
  907. //
  908. //--
  909. /////////////////////////////////////////////////////////////////////////////
  910. HRESULT CClusResTypes::FindItem(
  911. IN ISClusResType * pResourceType,
  912. OUT UINT * pnIndex
  913. )
  914. {
  915. //ASSERT( pResourceType != NULL );
  916. //ASSERT( pnIndex != NULL );
  917. HRESULT _hr = E_POINTER;
  918. if ( ( pResourceType != NULL ) && ( pnIndex != NULL ) )
  919. {
  920. CComBSTR bstrName;
  921. _hr = pResourceType->get_Name( &bstrName );
  922. if ( SUCCEEDED( _hr ) )
  923. {
  924. _hr = FindItem( bstrName, pnIndex );
  925. }
  926. }
  927. return _hr;
  928. } //*** CClusResTypes::FindItem( pResourceType )
  929. /////////////////////////////////////////////////////////////////////////////
  930. //++
  931. //
  932. // CClusResTypes::RemoveAt
  933. //
  934. // Description:
  935. // Remove the object (ResType) at the passed in index/position from the
  936. // collection.
  937. //
  938. // Arguments:
  939. // nPos [IN] - Index of the object to remove.
  940. //
  941. // Return Value:
  942. // S_OK if successful, or E_INVALIDARG is the index is out of range.
  943. //
  944. //--
  945. /////////////////////////////////////////////////////////////////////////////
  946. HRESULT CClusResTypes::RemoveAt( IN size_t pos )
  947. {
  948. CComObject<CClusResType> * pResourceType = NULL;
  949. ResourceTypeList::iterator first = m_ResourceTypes.begin();
  950. ResourceTypeList::iterator last = m_ResourceTypes.end();
  951. HRESULT _hr = E_INVALIDARG;
  952. for ( size_t t = 0; ( t < pos ) && ( first != last ); t++, first++ );
  953. if ( first != last )
  954. {
  955. pResourceType = *first;
  956. if ( pResourceType )
  957. {
  958. pResourceType->Release();
  959. }
  960. m_ResourceTypes.erase( first );
  961. _hr = S_OK;
  962. }
  963. return _hr;
  964. } //*** CClusResTypes::RemoveAt()
  965. /////////////////////////////////////////////////////////////////////////////
  966. //++
  967. //
  968. // CClusResTypes::GetIndex
  969. //
  970. // Description:
  971. // Convert the passed in variant index into the real index in the
  972. // collection.
  973. //
  974. // Arguments:
  975. // varIndex [IN] - The index to convert.
  976. // pnIndex [OUT] - Catches the index.
  977. //
  978. // Return Value:
  979. // S_OK if successful, E_POINTER, or E_INVALIDARG.
  980. //
  981. //--
  982. /////////////////////////////////////////////////////////////////////////////
  983. HRESULT CClusResTypes::GetIndex(
  984. IN VARIANT varIndex,
  985. OUT UINT * pnIndex
  986. )
  987. {
  988. //ASSERT( pnIndex != NULL );
  989. HRESULT _hr = E_POINTER;
  990. if ( pnIndex != NULL )
  991. {
  992. CComVariant v;
  993. UINT nIndex = 0;
  994. *pnIndex = 0;
  995. v.Copy( &varIndex );
  996. // Check to see if the index is a number.
  997. _hr = v.ChangeType( VT_I4 );
  998. if ( SUCCEEDED( _hr ) )
  999. {
  1000. nIndex = v.lVal;
  1001. nIndex--; // Adjust index to be 0 relative instead of 1 relative
  1002. }
  1003. else
  1004. {
  1005. // Check to see if the index is a string.
  1006. _hr = v.ChangeType( VT_BSTR );
  1007. if ( SUCCEEDED( _hr ) )
  1008. {
  1009. // Search for the string.
  1010. _hr = FindItem( v.bstrVal, &nIndex );
  1011. }
  1012. }
  1013. // We found an index, now check the range.
  1014. if ( SUCCEEDED( _hr ) )
  1015. {
  1016. if ( nIndex < m_ResourceTypes.size() )
  1017. {
  1018. *pnIndex = nIndex;
  1019. }
  1020. else
  1021. {
  1022. _hr = E_INVALIDARG;
  1023. }
  1024. }
  1025. }
  1026. return _hr;
  1027. } //*** CClusResTypes::GetIndex()
  1028. /////////////////////////////////////////////////////////////////////////////
  1029. //++
  1030. //
  1031. // CClusResTypes::get_Item
  1032. //
  1033. // Description:
  1034. // Returns the object (Group) at the passed in index.
  1035. //
  1036. // Arguments:
  1037. // varIndex [IN] - Hold the index. This is a one based number, or
  1038. // a string that is the name of the group to get.
  1039. // ppResourceType [OUT] - Catches the resource type object.
  1040. //
  1041. // Return Value:
  1042. // S_OK if successful, E_POINTER, or E_INVALIDARG if the index is out
  1043. // of range, or other HRESULT error.
  1044. //
  1045. //--
  1046. /////////////////////////////////////////////////////////////////////////////
  1047. STDMETHODIMP CClusResTypes::get_Item(
  1048. IN VARIANT varIndex,
  1049. OUT ISClusResType ** ppResourceType
  1050. )
  1051. {
  1052. //ASSERT( ppResourceType != NULL );
  1053. HRESULT _hr = E_POINTER;
  1054. if ( ppResourceType != NULL )
  1055. {
  1056. CComObject<CClusResType> * pResourceType = NULL;
  1057. UINT nIndex = 0;
  1058. *ppResourceType = NULL;
  1059. _hr = GetIndex( varIndex, &nIndex );
  1060. if ( SUCCEEDED( _hr ) )
  1061. {
  1062. pResourceType = m_ResourceTypes[ nIndex ];
  1063. _hr = pResourceType->QueryInterface( IID_ISClusResType, (void **) ppResourceType );
  1064. }
  1065. }
  1066. return _hr;
  1067. } //*** CClusResTypes::get_Item()
  1068. /////////////////////////////////////////////////////////////////////////////
  1069. //++
  1070. //
  1071. // CClusResTypes::get__NewEnum
  1072. //
  1073. // Description:
  1074. // Create and return a new enumeration for this collection.
  1075. //
  1076. // Arguments:
  1077. // ppunk [OUT] - Catches the new enumeration.
  1078. //
  1079. // Return Value:
  1080. // S_OK if successful, E_POINTER, or other HRESULT error.
  1081. //
  1082. //--
  1083. /////////////////////////////////////////////////////////////////////////////
  1084. STDMETHODIMP CClusResTypes::get__NewEnum( OUT IUnknown ** ppunk )
  1085. {
  1086. return ::HrNewIDispatchEnum< ResourceTypeList, CComObject< CClusResType > >( ppunk, m_ResourceTypes );
  1087. } //*** CClusResTypes::get__NewEnum()
  1088. /////////////////////////////////////////////////////////////////////////////
  1089. //++
  1090. //
  1091. // CClusResTypes::CreateItem
  1092. //
  1093. // Description:
  1094. // Create a new object (ResType) and add it to the collection.
  1095. //
  1096. // Arguments:
  1097. // bstrResourceGroupName [IN] - The name of the new group.
  1098. // ppResourceGroup [OUT] - Catches the new object.
  1099. //
  1100. // Return Value:
  1101. // S_OK if successful, E_POINTER, or Win32 error as HRESULT.
  1102. //
  1103. //--
  1104. /////////////////////////////////////////////////////////////////////////////
  1105. STDMETHODIMP CClusResTypes::CreateItem(
  1106. BSTR bstrResTypeName,
  1107. BSTR bstrDisplayName,
  1108. BSTR bstrResTypeDll,
  1109. long nLooksAliveInterval,
  1110. long nIsAliveInterval,
  1111. ISClusResType ** ppResourceType
  1112. )
  1113. {
  1114. //ASSERT( bstrResTypeName != NULL );
  1115. //ASSERT( bstrDisplayName != NULL );
  1116. //ASSERT( bstrResTypeDll != NULL );
  1117. //ASSERT( ppResourceType != NULL );
  1118. HRESULT _hr = E_POINTER;
  1119. if ( ( bstrResTypeName != NULL ) &&
  1120. ( bstrDisplayName != NULL ) &&
  1121. ( bstrResTypeDll != NULL ) &&
  1122. ( ppResourceType != NULL ) )
  1123. {
  1124. UINT nIndex;
  1125. *ppResourceType = NULL;
  1126. _hr = FindItem( bstrResTypeName, &nIndex );
  1127. if ( FAILED( _hr ) )
  1128. {
  1129. CComObject<CClusResType> * pClusterResourceType = NULL;
  1130. _hr = CComObject< CClusResType >::CreateInstance( &pClusterResourceType );
  1131. if ( SUCCEEDED( _hr ) )
  1132. {
  1133. CSmartPtr< ISClusRefObject > ptrRefObject( m_pClusRefObject );
  1134. CSmartPtr< CComObject< CClusResType > > ptrResourceType( pClusterResourceType );
  1135. _hr = ptrResourceType->Create( ptrRefObject, bstrResTypeName, bstrDisplayName, bstrResTypeDll, nLooksAliveInterval, nIsAliveInterval );
  1136. if ( SUCCEEDED( _hr ) )
  1137. {
  1138. _hr = ptrResourceType->QueryInterface( IID_ISClusResType, (void **) ppResourceType );
  1139. if ( SUCCEEDED( _hr ) )
  1140. {
  1141. ptrResourceType->AddRef();
  1142. m_ResourceTypes.insert( m_ResourceTypes.end(), ptrResourceType );
  1143. }
  1144. }
  1145. }
  1146. }
  1147. else
  1148. {
  1149. CComObject<CClusResType> * pClusterResourceType = NULL;
  1150. pClusterResourceType = m_ResourceTypes[ nIndex ];
  1151. _hr = pClusterResourceType->QueryInterface( IID_ISClusResType, (void **) ppResourceType );
  1152. }
  1153. }
  1154. return _hr;
  1155. } //*** CClusResTypes::CreateItem()
  1156. /////////////////////////////////////////////////////////////////////////////
  1157. //++
  1158. //
  1159. // CClusResTypes::DeleteItem
  1160. //
  1161. // Description:
  1162. // Deletes the object (ResType) at the passed in index.
  1163. //
  1164. // Arguments:
  1165. // varIndex [IN] - The index of the object to delete.
  1166. //
  1167. // Return Value:
  1168. // S_OK if successful, E_INVALIDARG, or Win32 error as HRESULT.
  1169. //
  1170. //--
  1171. /////////////////////////////////////////////////////////////////////////////
  1172. STDMETHODIMP CClusResTypes::DeleteItem( VARIANT varIndex )
  1173. {
  1174. HRESULT _hr = S_OK;
  1175. UINT nIndex = 0;
  1176. _hr = GetIndex( varIndex, &nIndex );
  1177. if ( SUCCEEDED( _hr ) )
  1178. {
  1179. ISClusResType * pResourceType = (ISClusResType *) m_ResourceTypes[ nIndex ];
  1180. // delete the resource type
  1181. _hr = pResourceType->Delete();
  1182. if ( SUCCEEDED( _hr ) )
  1183. {
  1184. RemoveAt( nIndex );
  1185. } // if: the restype was deleted from the cluster
  1186. } // if: we have a valid index
  1187. return _hr;
  1188. } //*** CClusResTypes::DeleteItem()
  1189. /////////////////////////////////////////////////////////////////////////////
  1190. //++
  1191. //
  1192. // CClusResTypes::Refresh
  1193. //
  1194. // Description:
  1195. // Load the collection from the cluster.
  1196. //
  1197. // Arguments:
  1198. // None.
  1199. //
  1200. // Return Value:
  1201. // S_OK is successful, or Win32 error as HRESULT if not.
  1202. //
  1203. //--
  1204. /////////////////////////////////////////////////////////////////////////////
  1205. STDMETHODIMP CClusResTypes::Refresh( void )
  1206. {
  1207. HCLUSTER hCluster = NULL;
  1208. HRESULT _hr;
  1209. _hr = m_pClusRefObject->get_Handle( (ULONG_PTR *) &hCluster );
  1210. if ( SUCCEEDED( _hr ) )
  1211. {
  1212. HCLUSENUM hEnum = NULL;
  1213. DWORD _sc = ERROR_SUCCESS;
  1214. hEnum = ::ClusterOpenEnum( hCluster, CLUSTER_ENUM_RESTYPE );
  1215. if ( hEnum != NULL )
  1216. {
  1217. int _nIndex = 0;
  1218. DWORD dwType = 0;
  1219. LPWSTR pwszName = NULL;
  1220. CComObject< CClusResType > * pClusterResourceType = NULL;
  1221. Clear();
  1222. for( _nIndex = 0, _hr = S_OK; SUCCEEDED( _hr ); _nIndex++ )
  1223. {
  1224. _sc = ::WrapClusterEnum( hEnum, _nIndex, &dwType, &pwszName );
  1225. if ( _sc == ERROR_NO_MORE_ITEMS )
  1226. {
  1227. _hr = S_OK;
  1228. break;
  1229. }
  1230. else if ( _sc == ERROR_SUCCESS )
  1231. {
  1232. _hr = CComObject< CClusResType >::CreateInstance( &pClusterResourceType );
  1233. if ( SUCCEEDED( _hr ) )
  1234. {
  1235. CSmartPtr< ISClusRefObject > ptrRefObject( m_pClusRefObject );
  1236. CSmartPtr< CComObject< CClusResType > > ptrType( pClusterResourceType );
  1237. _hr = ptrType->Open( ptrRefObject, pwszName );
  1238. if ( SUCCEEDED( _hr ) )
  1239. {
  1240. ptrType->AddRef();
  1241. m_ResourceTypes.insert( m_ResourceTypes.end(), ptrType );
  1242. }
  1243. }
  1244. ::LocalFree( pwszName );
  1245. pwszName = NULL;
  1246. }
  1247. else
  1248. {
  1249. _hr = HRESULT_FROM_WIN32( _sc );
  1250. }
  1251. } // for:
  1252. ::ClusterCloseEnum( hEnum );
  1253. }
  1254. else
  1255. {
  1256. _sc = GetLastError();
  1257. _hr = HRESULT_FROM_WIN32( _sc );
  1258. }
  1259. }
  1260. return _hr;
  1261. } //*** CClusResTypes::Refresh()