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.

1048 lines
27 KiB

  1. /////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1999-2002 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // ClusDisk.cpp
  7. //
  8. // Description:
  9. // Implementation of the cluster disk class for the MSCLUS
  10. // automation classes.
  11. //
  12. // Author:
  13. // Galen Barbee (galenb) 11-Feb-1999
  14. //
  15. // Revision History:
  16. //
  17. // Notes:
  18. //
  19. /////////////////////////////////////////////////////////////////////////////
  20. #include "stdafx.h"
  21. #if CLUSAPI_VERSION >= 0x0500
  22. #include <PropList.h>
  23. #else
  24. #include "PropList.h"
  25. #endif // CLUSAPI_VERSION >= 0x0500
  26. #include "ClusDisk.h"
  27. /////////////////////////////////////////////////////////////////////////////
  28. // Global variables
  29. /////////////////////////////////////////////////////////////////////////////
  30. static const IID * iidCClusDisk[] =
  31. {
  32. &IID_ISClusDisk
  33. };
  34. static const IID * iidCClusDisks[] =
  35. {
  36. &IID_ISClusDisks
  37. };
  38. static const IID * iidCClusScsiAddress[] =
  39. {
  40. &IID_ISClusScsiAddress
  41. };
  42. //*************************************************************************//
  43. /////////////////////////////////////////////////////////////////////////////
  44. // CClusDisk class
  45. /////////////////////////////////////////////////////////////////////////////
  46. /////////////////////////////////////////////////////////////////////////////
  47. //++
  48. //
  49. // CClusDisk::CClusDisk
  50. //
  51. // Description:
  52. // Constructor.
  53. //
  54. // Arguments:
  55. // None.
  56. //
  57. // Return Value:
  58. // None.
  59. //
  60. //--
  61. /////////////////////////////////////////////////////////////////////////////
  62. CClusDisk::CClusDisk( void )
  63. {
  64. m_pPartitions = NULL;
  65. m_dwSignature = 0;
  66. m_dwDiskNumber = 0;
  67. m_piids = (const IID *) iidCClusDisk;
  68. m_piidsSize = ARRAYSIZE( iidCClusDisk );
  69. } //*** CClusDisk::CClusDisk()
  70. /////////////////////////////////////////////////////////////////////////////
  71. //++
  72. //
  73. // CClusDisk::~CClusDisk
  74. //
  75. // Description:
  76. // Destructor.
  77. //
  78. // Arguments:
  79. // None.
  80. //
  81. // Return Value:
  82. // None.
  83. //
  84. //--
  85. /////////////////////////////////////////////////////////////////////////////
  86. CClusDisk::~CClusDisk( void )
  87. {
  88. if ( m_pPartitions != NULL )
  89. {
  90. m_pPartitions->Release();
  91. } // if:
  92. } //*** CClusDisk::~CClusDisk()
  93. /////////////////////////////////////////////////////////////////////////////
  94. //++
  95. //
  96. // CClusDisk::Create
  97. //
  98. // Description:
  99. // Finish creating this object. This method get the value list from
  100. // the passed in physical disk resource handle.
  101. //
  102. // Arguments:
  103. // hResource [IN] - Handle to the physical disk resource.
  104. //
  105. // Return Value:
  106. // S_OK if successful, or Win32 error wrapped in HRESULT.
  107. //
  108. //--
  109. /////////////////////////////////////////////////////////////////////////////
  110. HRESULT CClusDisk::Create( IN HRESOURCE hResource )
  111. {
  112. HRESULT _hr = E_POINTER;
  113. DWORD _sc = ERROR_SUCCESS;
  114. CClusPropValueList _cpvl;
  115. _sc = _cpvl.ScGetResourceValueList( hResource, CLUSCTL_RESOURCE_STORAGE_GET_DISK_INFO );
  116. _hr = HRESULT_FROM_WIN32( _sc );
  117. if ( SUCCEEDED( _hr ) )
  118. {
  119. _sc = _cpvl.ScMoveToFirstValue();
  120. _hr = HRESULT_FROM_WIN32( _sc );
  121. if ( SUCCEEDED( _hr ) )
  122. {
  123. CLUSPROP_BUFFER_HELPER _cbhValue = { NULL };
  124. CComObject< CClusPartitions > * pPartitions = NULL;
  125. if ( m_pPartitions != NULL )
  126. {
  127. m_pPartitions->Release();
  128. m_pPartitions = NULL;
  129. } // if: clean up any old partitions collection
  130. _hr = CComObject< CClusPartitions >::CreateInstance( &pPartitions );
  131. if ( SUCCEEDED( _hr ) )
  132. {
  133. CSmartPtr< CComObject< CClusPartitions > > ptrPartitions( pPartitions );
  134. m_pPartitions = ptrPartitions;
  135. ptrPartitions->AddRef();
  136. do
  137. {
  138. _cbhValue = _cpvl;
  139. switch ( _cbhValue.pSyntax->dw )
  140. {
  141. case CLUSPROP_SYNTAX_PARTITION_INFO :
  142. {
  143. _hr = ptrPartitions->HrCreateItem( _cbhValue.pPartitionInfoValue );
  144. break;
  145. } // case: CLUSPROP_SYNTAX_PARTITION_INFO
  146. case CLUSPROP_SYNTAX_DISK_SIGNATURE :
  147. {
  148. m_dwSignature = _cbhValue.pDiskSignatureValue->dw;
  149. break;
  150. } // case: CLUSPROP_SYNTAX_DISK_SIGNATURE
  151. case CLUSPROP_SYNTAX_SCSI_ADDRESS :
  152. {
  153. m_csaScsiAddress.dw = _cbhValue.pScsiAddressValue->dw;
  154. break;
  155. } // case: CLUSPROP_SYNTAX_SCSI_ADDRESS
  156. case CLUSPROP_SYNTAX_DISK_NUMBER :
  157. {
  158. m_dwDiskNumber = _cbhValue.pDiskNumberValue->dw;
  159. break;
  160. } // case: CLUSPROP_SYNTAX_DISK_NUMBER
  161. } // switch:
  162. //
  163. // Move to the next value.
  164. //
  165. _sc = _cpvl.ScMoveToNextValue();
  166. if ( _sc == ERROR_NO_MORE_ITEMS )
  167. {
  168. _hr = S_OK;
  169. break;
  170. } // if: error occurred moving to the next value
  171. _hr = HRESULT_FROM_WIN32( _sc );
  172. } while ( SUCCEEDED( _hr ) ); // do-while: there are no errors
  173. } // if: created the partition collection
  174. } // if: move to first value ok
  175. } // if: get the value list ok
  176. return _hr;
  177. } //*** CClusDisk::Create()
  178. /////////////////////////////////////////////////////////////////////////////
  179. //++
  180. //
  181. // CClusDisk::HrCreate
  182. //
  183. // Description:
  184. // Finish creating this object. This method parses a passed in value
  185. // list to get the values for the physical disk object.
  186. //
  187. // Arguments:
  188. // rcpvl [IN OUT] - Value list to parse.
  189. // pbEndFound [OUT] - Did find the end of the value list?
  190. //
  191. // Return Value:
  192. // S_OK, or Win32 error code wrapped in an HRESULT.
  193. //
  194. //--
  195. /////////////////////////////////////////////////////////////////////////////
  196. HRESULT CClusDisk::HrCreate(
  197. IN OUT CClusPropValueList & rcpvl,
  198. OUT BOOL * pbEndFound
  199. )
  200. {
  201. DWORD _sc = ERROR_SUCCESS;
  202. CLUSPROP_BUFFER_HELPER _cbhValue = { NULL };
  203. CComObject< CClusPartitions > * pPartitions = NULL;
  204. HRESULT _hr = S_FALSE;
  205. if ( m_pPartitions != NULL )
  206. {
  207. m_pPartitions->Release();
  208. m_pPartitions = NULL;
  209. } // if: clean up any old partitions collection
  210. _hr = CComObject< CClusPartitions >::CreateInstance( &pPartitions );
  211. if ( SUCCEEDED( _hr ) )
  212. {
  213. CSmartPtr< CComObject< CClusPartitions > > ptrPartitions( pPartitions );
  214. m_pPartitions = ptrPartitions;
  215. ptrPartitions->AddRef();
  216. _cbhValue = rcpvl;
  217. do
  218. {
  219. switch ( _cbhValue.pSyntax->dw )
  220. {
  221. case CLUSPROP_SYNTAX_DISK_SIGNATURE :
  222. {
  223. m_dwSignature = _cbhValue.pDiskSignatureValue->dw;
  224. break;
  225. } // case: CLUSPROP_SYNTAX_DISK_SIGNATURE
  226. case CLUSPROP_SYNTAX_PARTITION_INFO :
  227. {
  228. _hr = ptrPartitions->HrCreateItem( _cbhValue.pPartitionInfoValue );
  229. break;
  230. } // case: CLUSPROP_SYNTAX_PARTITION_INFO
  231. case CLUSPROP_SYNTAX_SCSI_ADDRESS :
  232. {
  233. m_csaScsiAddress.dw = _cbhValue.pScsiAddressValue->dw;
  234. break;
  235. } // case: CLUSPROP_SYNTAX_SCSI_ADDRESS
  236. case CLUSPROP_SYNTAX_DISK_NUMBER :
  237. {
  238. m_dwDiskNumber = _cbhValue.pDiskNumberValue->dw;
  239. break;
  240. } // case: CLUSPROP_SYNTAX_DISK_NUMBER
  241. } // switch:
  242. //
  243. // Move to the next value.
  244. //
  245. _sc = rcpvl.ScMoveToNextValue();
  246. if ( _sc == ERROR_NO_MORE_ITEMS )
  247. {
  248. _hr = S_OK;
  249. *pbEndFound = TRUE;
  250. break;
  251. } // if: error occurred moving to the next value
  252. _cbhValue = rcpvl;
  253. if ( _cbhValue.pSyntax->dw == CLUSPROP_SYNTAX_DISK_SIGNATURE )
  254. {
  255. _hr = HRESULT_FROM_WIN32( _sc );
  256. break;
  257. } // if: exit if another signature is found before the end of the list is seen
  258. _hr = HRESULT_FROM_WIN32( _sc );
  259. } while ( SUCCEEDED( _hr ) ); // do-while: there are no errors
  260. } // if: the patitions collection can be created
  261. return _hr;
  262. } //*** CClusDisk::HrCreate()
  263. /////////////////////////////////////////////////////////////////////////////
  264. //++
  265. //
  266. // CClusDisk::get_Signature
  267. //
  268. // Description:
  269. // Get the disk signature.
  270. //
  271. // Arguments:
  272. // plSignature [OUT] - catches the signature.
  273. //
  274. // Return Value:
  275. // S_OK if successful, or E_POINTER
  276. //
  277. //--
  278. /////////////////////////////////////////////////////////////////////////////
  279. STDMETHODIMP CClusDisk::get_Signature( OUT long * plSignature )
  280. {
  281. //ASSERT( plSignature != NULL );
  282. HRESULT _hr = E_POINTER;
  283. if ( plSignature != NULL )
  284. {
  285. *plSignature = static_cast< long >( m_dwSignature );
  286. _hr = S_OK;
  287. }
  288. return _hr;
  289. } //*** CClusDisk::get_Signature()
  290. /////////////////////////////////////////////////////////////////////////////
  291. //++
  292. //
  293. // CClusDisk::get_ScsiAddress
  294. //
  295. // Description:
  296. // Get the disk's SCSI address.
  297. //
  298. // Arguments:
  299. // ppScsiAddress [OUT] - catches the SCSI address..
  300. //
  301. // Return Value:
  302. // S_OK if successful, or E_POINTER
  303. //
  304. //--
  305. /////////////////////////////////////////////////////////////////////////////
  306. STDMETHODIMP CClusDisk::get_ScsiAddress(
  307. OUT ISClusScsiAddress ** ppScsiAddress
  308. )
  309. {
  310. //ASSERT( ppScsiAddress != NULL );
  311. HRESULT _hr = E_POINTER;
  312. if ( ppScsiAddress != NULL )
  313. {
  314. CComObject< CClusScsiAddress > * _pScsiAddress = NULL;
  315. _hr = CComObject< CClusScsiAddress >::CreateInstance( &_pScsiAddress );
  316. if ( SUCCEEDED( _hr ) )
  317. {
  318. CSmartPtr< CComObject< CClusScsiAddress > > _ptrScsiAddress( _pScsiAddress );
  319. _hr = _ptrScsiAddress->Create( m_csaScsiAddress );
  320. if ( SUCCEEDED( _hr ) )
  321. {
  322. _hr = _ptrScsiAddress->QueryInterface( IID_ISClusScsiAddress, (void **) ppScsiAddress );
  323. } // if:
  324. } // if:
  325. } // if:
  326. return _hr;
  327. } //*** CClusDisk::get_ScsiAddress()
  328. /////////////////////////////////////////////////////////////////////////////
  329. //++
  330. //
  331. // CClusDisk::get_DiskNumber
  332. //
  333. // Description:
  334. // Get the disk number.
  335. //
  336. // Arguments:
  337. // plDiskNumber [OUT] - catches the disk number.
  338. //
  339. // Return Value:
  340. // S_OK if successful, or E_POINTER
  341. //
  342. //--
  343. /////////////////////////////////////////////////////////////////////////////
  344. STDMETHODIMP CClusDisk::get_DiskNumber( OUT long * plDiskNumber )
  345. {
  346. //ASSERT( plDiskNumber != NULL );
  347. HRESULT _hr = E_POINTER;
  348. if ( plDiskNumber != NULL )
  349. {
  350. *plDiskNumber = static_cast< long >( m_dwDiskNumber );
  351. _hr = S_OK;
  352. }
  353. return _hr;
  354. } //*** CClusDisk::get_DiskNumber()
  355. /////////////////////////////////////////////////////////////////////////////
  356. //++
  357. //
  358. // CClusDisk::get_Partitions
  359. //
  360. // Description:
  361. // Get the disk partitions.
  362. //
  363. // Arguments:
  364. // ppPartitions [OUT] - catches the partitions collection.
  365. //
  366. // Return Value:
  367. // S_OK if successful, or E_POINTER
  368. //
  369. //--
  370. /////////////////////////////////////////////////////////////////////////////
  371. STDMETHODIMP CClusDisk::get_Partitions( OUT ISClusPartitions ** ppPartitions )
  372. {
  373. //ASSERT( ppPartitions != NULL );
  374. ASSERT( m_pPartitions != NULL );
  375. HRESULT _hr = E_POINTER;
  376. if ( ppPartitions != NULL )
  377. {
  378. if ( ppPartitions != NULL )
  379. {
  380. _hr = m_pPartitions->QueryInterface( IID_ISClusPartitions, (void **) ppPartitions );
  381. } // if:
  382. } // if:
  383. return _hr;
  384. } //*** CClusDisk::get_Partitions()
  385. //*************************************************************************//
  386. /////////////////////////////////////////////////////////////////////////////
  387. // CClusDisks class
  388. /////////////////////////////////////////////////////////////////////////////
  389. /////////////////////////////////////////////////////////////////////////////
  390. //++
  391. //
  392. // CClusDisks::CClusDisks
  393. //
  394. // Description:
  395. // Constructor.
  396. //
  397. // Arguments:
  398. // None.
  399. //
  400. // Return Value:
  401. // None.
  402. //
  403. //--
  404. /////////////////////////////////////////////////////////////////////////////
  405. CClusDisks::CClusDisks( void )
  406. {
  407. m_pClusRefObject = NULL;
  408. m_piids = (const IID *) iidCClusDisks;
  409. m_piidsSize = ARRAYSIZE( iidCClusDisks );
  410. } //*** CClusDisks::CClusDisks()
  411. /////////////////////////////////////////////////////////////////////////////
  412. //++
  413. //
  414. // CClusDisks::~CClusDisks
  415. //
  416. // Description:
  417. // Destructor.
  418. //
  419. // Arguments:
  420. // None.
  421. //
  422. // Return Value:
  423. // None.
  424. //
  425. //--
  426. /////////////////////////////////////////////////////////////////////////////
  427. CClusDisks::~CClusDisks( void )
  428. {
  429. Clear();
  430. if ( m_pClusRefObject != NULL )
  431. {
  432. m_pClusRefObject->Release();
  433. m_pClusRefObject = NULL;
  434. } // if: do we have a pointer to the cluster handle wrapper?
  435. } //*** CClusDisks::~CClusDisks()
  436. /////////////////////////////////////////////////////////////////////////////
  437. //++
  438. //
  439. // CClusDisks::Create
  440. //
  441. // Description:
  442. // Complete the heavy weight construction,
  443. //
  444. // Arguments:
  445. // rpvl [IN] - Property value list.
  446. //
  447. // Return Value:
  448. // E_NOTIMPL
  449. //
  450. //--
  451. /////////////////////////////////////////////////////////////////////////////
  452. HRESULT CClusDisks::Create( IN const CClusPropValueList &rpvl )
  453. {
  454. HRESULT _hr = E_NOTIMPL;
  455. return _hr;
  456. } //*** CClusDisks::Create()
  457. /////////////////////////////////////////////////////////////////////////////
  458. //++
  459. //
  460. // CClusDisks::GetIndex
  461. //
  462. // Description:
  463. // Convert the passed in 1 based index into a 0 based index.
  464. //
  465. // Arguments:
  466. // varIndex [IN] - holds the 1 based index.
  467. // pnIndex [OUT] - catches the 0 based index.
  468. //
  469. // Return Value:
  470. // S_OK if successful, E_POINTER, or E_INVALIDARG if out of range.
  471. //
  472. //--
  473. /////////////////////////////////////////////////////////////////////////////
  474. HRESULT CClusDisks::GetIndex( IN VARIANT varIndex, OUT UINT * pnIndex )
  475. {
  476. //ASSERT( pnIndex != NULL );
  477. HRESULT _hr = E_POINTER;
  478. if ( pnIndex != NULL )
  479. {
  480. CComVariant v;
  481. UINT nIndex = 0;
  482. *pnIndex = 0;
  483. v.Copy( &varIndex );
  484. // Check to see if the index is a number.
  485. _hr = v.ChangeType( VT_I4 );
  486. if ( SUCCEEDED( _hr ) )
  487. {
  488. nIndex = v.lVal;
  489. nIndex--; // Adjust index to be 0 relative instead of 1 relative
  490. if ( nIndex < m_dvDisks.size() )
  491. {
  492. *pnIndex = nIndex;
  493. }
  494. else
  495. {
  496. _hr = E_INVALIDARG;
  497. }
  498. }
  499. }
  500. return _hr;
  501. } //*** CClusDisks::GetIndex()
  502. /////////////////////////////////////////////////////////////////////////////
  503. //++
  504. //
  505. // CClusDisks::get_Count
  506. //
  507. // Description:
  508. // Get the count of objects in the collection.
  509. //
  510. // Arguments:
  511. // plCount [OUT] - Catches the count.
  512. //
  513. // Return Value:
  514. // S_OK if successful or E_POINTER.
  515. //
  516. //--
  517. /////////////////////////////////////////////////////////////////////////////
  518. STDMETHODIMP CClusDisks::get_Count( OUT long * plCount )
  519. {
  520. //ASSERT( plCount != NULL );
  521. HRESULT _hr = E_POINTER;
  522. if ( plCount != NULL )
  523. {
  524. *plCount = m_dvDisks.size();
  525. _hr = S_OK;
  526. }
  527. return _hr;
  528. } //*** CClusDisks::get_Count()
  529. /////////////////////////////////////////////////////////////////////////////
  530. //++
  531. //
  532. // CClusDisks::Clear
  533. //
  534. // Description:
  535. // Empty the vector of disks.
  536. //
  537. // Arguments:
  538. // None.
  539. //
  540. // Return Value:
  541. // None.
  542. //
  543. //--
  544. /////////////////////////////////////////////////////////////////////////////
  545. void CClusDisks::Clear( void )
  546. {
  547. ::ReleaseAndEmptyCollection< DiskVector, CComObject< CClusDisk > >( m_dvDisks );
  548. } //*** CClusDisks::Clear()
  549. /////////////////////////////////////////////////////////////////////////////
  550. //++
  551. //
  552. // CClusDisks::get_Item
  553. //
  554. // Description:
  555. // Get the item (disk) at the passed in index.
  556. //
  557. // Arguments:
  558. // varIndex [IN] - Contains the index requested.
  559. // ppbstrRegistryKey [OUT] - Catches the key.
  560. //
  561. // Return Value:
  562. // S_OK if successful, E_POINTER, or other HRESULT error.
  563. //
  564. //--
  565. /////////////////////////////////////////////////////////////////////////////
  566. STDMETHODIMP CClusDisks::get_Item(
  567. IN VARIANT varIndex,
  568. OUT ISClusDisk ** ppDisk
  569. )
  570. {
  571. //ASSERT( ppDisk != NULL );
  572. HRESULT _hr = E_POINTER;
  573. if ( ppDisk != NULL )
  574. {
  575. CComObject< CClusDisk > * pDisk = NULL;
  576. // Zero the out param
  577. *ppDisk = NULL;
  578. UINT nIndex = 0;
  579. _hr = GetIndex( varIndex, &nIndex );
  580. if ( SUCCEEDED( _hr ) )
  581. {
  582. pDisk = m_dvDisks[ nIndex ];
  583. _hr = pDisk->QueryInterface( IID_ISClusDisk, (void **) ppDisk );
  584. }
  585. }
  586. return _hr;
  587. } //*** CClusDisks::get_Item()
  588. /////////////////////////////////////////////////////////////////////////////
  589. //++
  590. //
  591. // CClusDisks::get__NewEnum
  592. //
  593. // Description:
  594. // Create and return a new enumeration for this collection.
  595. //
  596. // Arguments:
  597. // ppunk [OUT] - Catches the new enumeration.
  598. //
  599. // Return Value:
  600. // S_OK if successful, E_POINTER, or other HRESULT error.
  601. //
  602. //--
  603. /////////////////////////////////////////////////////////////////////////////
  604. STDMETHODIMP CClusDisks::get__NewEnum( OUT IUnknown ** ppunk )
  605. {
  606. return ::HrNewIDispatchEnum< DiskVector, CComObject< CClusDisk > >( ppunk, m_dvDisks );
  607. } //*** CClusDisks::get__NewEnum()
  608. /////////////////////////////////////////////////////////////////////////////
  609. //++
  610. //
  611. // CClusDisks::Create
  612. //
  613. // Description:
  614. // Finish creating the object by doing things that cannot be done in
  615. // a light weight constructor.
  616. //
  617. // Arguments:
  618. // pClusRefObject [IN] - Wraps the cluster handle.
  619. // bstrResTypeName [IN] - The resource type this collection is for.
  620. //
  621. // Return Value:
  622. // S_OK if successful, or E_POINTER if not.
  623. //
  624. //--
  625. /////////////////////////////////////////////////////////////////////////////
  626. HRESULT CClusDisks::Create(
  627. IN ISClusRefObject * pClusRefObject,
  628. IN BSTR bstrResTypeName
  629. )
  630. {
  631. ASSERT( pClusRefObject != NULL );
  632. HRESULT _hr = E_POINTER;
  633. if ( pClusRefObject != NULL )
  634. {
  635. m_pClusRefObject = pClusRefObject;
  636. m_pClusRefObject->AddRef();
  637. m_bstrResTypeName = bstrResTypeName;
  638. _hr = S_OK;
  639. }
  640. return _hr;
  641. } //*** CClusDisks::Create()
  642. /////////////////////////////////////////////////////////////////////////////
  643. //++
  644. //
  645. // CClusDisks::Refresh
  646. //
  647. // Description:
  648. // Load the collection from the cluster database.
  649. //
  650. // Arguments:
  651. // None.
  652. //
  653. // Return Value:
  654. // S_OK if successful, or Win32 error as HRESULT if not.
  655. //
  656. //--
  657. /////////////////////////////////////////////////////////////////////////////
  658. STDMETHODIMP CClusDisks::Refresh( void )
  659. {
  660. HRESULT _hr = S_OK;
  661. DWORD _sc = ERROR_SUCCESS;
  662. HCLUSTER _hCluster = NULL;
  663. BOOL _bEndFound = FALSE;
  664. _hr = m_pClusRefObject->get_Handle( (ULONG_PTR *) &_hCluster );
  665. if ( SUCCEEDED( _hr ) )
  666. {
  667. CClusPropValueList _cpvl;
  668. _sc = _cpvl.ScGetResourceTypeValueList(
  669. _hCluster,
  670. m_bstrResTypeName,
  671. CLUSCTL_RESOURCE_TYPE_STORAGE_GET_AVAILABLE_DISKS
  672. );
  673. _hr = HRESULT_FROM_WIN32( _sc );
  674. if ( SUCCEEDED( _hr ) )
  675. {
  676. Clear();
  677. _sc = _cpvl.ScMoveToFirstValue();
  678. _hr = HRESULT_FROM_WIN32( _sc );
  679. if ( SUCCEEDED( _hr ) )
  680. {
  681. CLUSPROP_BUFFER_HELPER _cbhValue = { NULL };
  682. do
  683. {
  684. _cbhValue = _cpvl;
  685. if ( _cbhValue.pSyntax->dw == CLUSPROP_SYNTAX_DISK_SIGNATURE )
  686. {
  687. _hr = HrCreateDisk( _cpvl, &_bEndFound );
  688. } // if: value list MUST start with signature!
  689. } while ( ! _bEndFound ); // do-while: there are values in the list
  690. } // if: we moved to the first value
  691. } // if: the value list of available disks was retrieved
  692. } // if: we have a cluster handle
  693. return _hr;
  694. } //*** CClusDisks::Refresh()
  695. /////////////////////////////////////////////////////////////////////////////
  696. //++
  697. //
  698. // CClusDisks::HrCreateDisk
  699. //
  700. // Description:
  701. // Create a CClusDisk object from the passed in value list and add it
  702. // to the collection. This method assumes that the value list's curent
  703. // value is the disk signature.
  704. //
  705. // Arguments:
  706. // rcpvl [IN OUT] - The value list to parse.
  707. // pbEndFound [IN] - Catches the end of list state.
  708. //
  709. // Return Value:
  710. // S_OK, if successful, Win32 error code wrapped in an HRESULT.
  711. //
  712. //--
  713. /////////////////////////////////////////////////////////////////////////////
  714. HRESULT CClusDisks::HrCreateDisk(
  715. IN OUT CClusPropValueList & rcpvl,
  716. OUT BOOL * pbEndFound
  717. )
  718. {
  719. CComObject< CClusDisk > * _pDisk = NULL;
  720. HRESULT _hr = S_FALSE;
  721. _hr = CComObject< CClusDisk >::CreateInstance( &_pDisk );
  722. if ( SUCCEEDED( _hr ) )
  723. {
  724. CSmartPtr< CComObject< CClusDisk > > _ptrDisk( _pDisk );
  725. _hr = _ptrDisk->HrCreate( rcpvl, pbEndFound );
  726. if ( SUCCEEDED( _hr ) )
  727. {
  728. m_dvDisks.insert( m_dvDisks.end(), _pDisk );
  729. _ptrDisk->AddRef();
  730. } // if:
  731. } // if:
  732. return _hr;
  733. } //*** CClusDisks::HrCreateDisk()
  734. //*************************************************************************//
  735. /////////////////////////////////////////////////////////////////////////////
  736. // CClusScsiAddress class
  737. /////////////////////////////////////////////////////////////////////////////
  738. /////////////////////////////////////////////////////////////////////////////
  739. //++
  740. //
  741. // CClusScsiAddress::CClusScsiAddress
  742. //
  743. // Description:
  744. // Constructor.
  745. //
  746. // Arguments:
  747. // None.
  748. //
  749. // Return Value:
  750. // None.
  751. //
  752. //--
  753. /////////////////////////////////////////////////////////////////////////////
  754. CClusScsiAddress::CClusScsiAddress( void )
  755. {
  756. m_piids = (const IID *) iidCClusScsiAddress;
  757. m_piidsSize = ARRAYSIZE( iidCClusScsiAddress );
  758. } //*** CClusScsiAddress::CClusScsiAddress()
  759. /////////////////////////////////////////////////////////////////////////////
  760. //++
  761. //
  762. // CClusScsiAddress::Create
  763. //
  764. // Description:
  765. // Finish creating this object.
  766. //
  767. // Arguments:
  768. // pcpi [IN] - points to the CLUS_PARTITION_INFO struct.
  769. //
  770. // Return Value:
  771. // S_OK if successful, or E_POINTER
  772. //
  773. //--
  774. /////////////////////////////////////////////////////////////////////////////
  775. HRESULT CClusScsiAddress::Create( IN const CLUS_SCSI_ADDRESS & rcsa )
  776. {
  777. m_csa = rcsa;
  778. return S_OK;
  779. } //*** CClusScsiAddress::Create()
  780. /////////////////////////////////////////////////////////////////////////////
  781. //++
  782. //
  783. // CClusScsiAddress::get_PortNumber
  784. //
  785. // Description:
  786. // Get the disk's port number.
  787. //
  788. // Arguments:
  789. // pvarPortNumber [OUT] - catches the port number.
  790. //
  791. // Return Value:
  792. // S_OK if successful, or E_POINTER
  793. //
  794. //--
  795. /////////////////////////////////////////////////////////////////////////////
  796. STDMETHODIMP CClusScsiAddress::get_PortNumber( OUT VARIANT * pvarPortNumber )
  797. {
  798. //ASSERT( pvarPortNumber != NULL );
  799. HRESULT _hr = E_POINTER;
  800. if ( pvarPortNumber != NULL )
  801. {
  802. pvarPortNumber->bVal = m_csa.PortNumber;
  803. pvarPortNumber->vt = VT_UI1;
  804. _hr = S_OK;
  805. }
  806. return _hr;
  807. } //*** CClusScsiAddress::get_PortNumber()
  808. /////////////////////////////////////////////////////////////////////////////
  809. //++
  810. //
  811. // CClusScsiAddress::get_PathId
  812. //
  813. // Description:
  814. // Get the disk's path id.
  815. //
  816. // Arguments:
  817. // pvarPathId [OUT] - catches the path id.
  818. //
  819. // Return Value:
  820. // S_OK if successful, or E_POINTER
  821. //
  822. //--
  823. /////////////////////////////////////////////////////////////////////////////
  824. STDMETHODIMP CClusScsiAddress::get_PathId( OUT VARIANT * pvarPathId )
  825. {
  826. //ASSERT( pvarPathId != NULL );
  827. HRESULT _hr = E_POINTER;
  828. if ( pvarPathId != NULL )
  829. {
  830. pvarPathId->bVal = m_csa.PathId;
  831. pvarPathId->vt = VT_UI1;
  832. _hr = S_OK;
  833. }
  834. return _hr;
  835. } //*** CClusScsiAddress::get_PathId()
  836. /////////////////////////////////////////////////////////////////////////////
  837. //++
  838. //
  839. // CClusScsiAddress::get_TargetId
  840. //
  841. // Description:
  842. // Get the disk's target id.
  843. //
  844. // Arguments:
  845. // pvarTargetId [OUT] - catches the target id.
  846. //
  847. // Return Value:
  848. // S_OK if successful, or E_POINTER
  849. //
  850. //--
  851. /////////////////////////////////////////////////////////////////////////////
  852. STDMETHODIMP CClusScsiAddress::get_TargetId( OUT VARIANT * pvarTargetId )
  853. {
  854. //ASSERT( pvarTargetId != NULL );
  855. HRESULT _hr = E_POINTER;
  856. if ( pvarTargetId != NULL )
  857. {
  858. pvarTargetId->bVal = m_csa.TargetId;
  859. pvarTargetId->vt = VT_UI1;
  860. _hr = S_OK;
  861. }
  862. return _hr;
  863. } //*** CClusScsiAddress::get_TargetId()
  864. /////////////////////////////////////////////////////////////////////////////
  865. //++
  866. //
  867. // CClusScsiAddress::get_Lun
  868. //
  869. // Description:
  870. // Get the disk's Lun.
  871. //
  872. // Arguments:
  873. // pvarLun [OUT] - catches the Lun.
  874. //
  875. // Return Value:
  876. // S_OK if successful, or E_POINTER
  877. //
  878. //--
  879. /////////////////////////////////////////////////////////////////////////////
  880. STDMETHODIMP CClusScsiAddress::get_Lun( OUT VARIANT * pvarLun )
  881. {
  882. //ASSERT( pvarLun != NULL );
  883. HRESULT _hr = E_POINTER;
  884. if ( pvarLun != NULL )
  885. {
  886. pvarLun->bVal = m_csa.Lun;
  887. pvarLun->vt = VT_UI1;
  888. _hr = S_OK;
  889. }
  890. return _hr;
  891. } //*** CClusScsiAddress::get_Lun()