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.

4425 lines
104 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 2000-2002 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // CPhysicalDisk.cpp
  7. //
  8. // Description:
  9. // This file contains the definition of the CPhysicalDisk
  10. // class.
  11. //
  12. // The class CPhysicalDisk represents a cluster manageable
  13. // device. It implements the IClusCfgManagedResourceInfo interface.
  14. //
  15. // Maintained By:
  16. // Galen Barbee (GalenB) 23-FEB-2000
  17. //
  18. //////////////////////////////////////////////////////////////////////////////
  19. //////////////////////////////////////////////////////////////////////////////
  20. // Include Files
  21. //////////////////////////////////////////////////////////////////////////////
  22. #include "Pch.h"
  23. #include "CPhysicalDisk.h"
  24. #include "CClusCfgPartitionInfo.h"
  25. #include <devioctl.h>
  26. #include <ntddvol.h>
  27. #include <ntddstor.h>
  28. #include <ntddscsi.h>
  29. #define _NTSCSI_USER_MODE_
  30. #include <scsi.h>
  31. #undef _NTSCSI_USER_MODE_
  32. //////////////////////////////////////////////////////////////////////////////
  33. // Constant Definitions
  34. //////////////////////////////////////////////////////////////////////////////
  35. DEFINE_THISCLASS( "CPhysicalDisk" );
  36. //*************************************************************************//
  37. /////////////////////////////////////////////////////////////////////////////
  38. // CPhysicalDisk class
  39. /////////////////////////////////////////////////////////////////////////////
  40. //////////////////////////////////////////////////////////////////////////////
  41. //++
  42. //
  43. // CPhysicalDisk::S_HrCreateInstance
  44. //
  45. // Description:
  46. // Create a CPhysicalDisk instance.
  47. //
  48. // Arguments:
  49. // None.
  50. //
  51. // Return Values:
  52. // Pointer to CPhysicalDisk instance.
  53. //
  54. //--
  55. //////////////////////////////////////////////////////////////////////////////
  56. HRESULT
  57. CPhysicalDisk::S_HrCreateInstance( IUnknown ** ppunkOut )
  58. {
  59. TraceFunc( "" );
  60. HRESULT hr = S_OK;
  61. CPhysicalDisk * ppd = NULL;
  62. if ( ppunkOut == NULL )
  63. {
  64. hr = THR( E_POINTER );
  65. goto Cleanup;
  66. } // if:
  67. ppd = new CPhysicalDisk();
  68. if ( ppd == NULL )
  69. {
  70. hr = THR( E_OUTOFMEMORY );
  71. goto Cleanup;
  72. } // if: error allocating object
  73. hr = THR( ppd->HrInit() );
  74. if ( FAILED( hr ) )
  75. {
  76. goto Cleanup;
  77. } // if: HrInit() failed
  78. hr = THR( ppd->TypeSafeQI( IUnknown, ppunkOut ) );
  79. if ( FAILED( hr ) )
  80. {
  81. goto Cleanup;
  82. } // if: QI failed
  83. Cleanup:
  84. if ( FAILED( hr ) )
  85. {
  86. LogMsg( L"[SRV] CPhysicalDisk::S_HrCreateInstance() failed. (hr = %#08x)", hr );
  87. } // if:
  88. if ( ppd != NULL )
  89. {
  90. ppd->Release();
  91. } // if:
  92. HRETURN( hr );
  93. } //*** CPhysicalDisk::S_HrCreateInstance
  94. //////////////////////////////////////////////////////////////////////////////
  95. //++
  96. //
  97. // CPhysicalDisk::CPhysicalDisk
  98. //
  99. // Description:
  100. // Constructor of the CPhysicalDisk class. This initializes
  101. // the m_cRef variable to 1 instead of 0 to account of possible
  102. // QueryInterface failure in DllGetClassObject.
  103. //
  104. // Arguments:
  105. // None.
  106. //
  107. // Return Value:
  108. // None.
  109. //
  110. // Remarks:
  111. // None.
  112. //
  113. //--
  114. //////////////////////////////////////////////////////////////////////////////
  115. CPhysicalDisk::CPhysicalDisk( void )
  116. : m_cRef( 1 )
  117. {
  118. TraceFunc( "" );
  119. // Increment the count of components in memory so the DLL hosting this
  120. // object cannot be unloaded.
  121. InterlockedIncrement( &g_cObjects );
  122. Assert( m_pIWbemServices == NULL );
  123. Assert( m_bstrName == NULL );
  124. Assert( m_bstrDeviceID == NULL );
  125. Assert( m_bstrDescription == NULL );
  126. Assert( m_idxNextPartition == 0 );
  127. Assert( m_ulSCSIBus == 0 );
  128. Assert( m_ulSCSITid == 0 );
  129. Assert( m_ulSCSIPort == 0 );
  130. Assert( m_ulSCSILun == 0 );
  131. Assert( m_idxEnumPartitionNext == 0 );
  132. Assert( m_prgPartitions == NULL );
  133. Assert( m_lcid == 0 );
  134. Assert( m_picccCallback == NULL );
  135. Assert( m_dwSignature == 0 );
  136. Assert( m_bstrFriendlyName == NULL );
  137. // Assert( m_bstrFirmwareSerialNumber == NULL );
  138. Assert( m_fIsManaged == FALSE );
  139. Assert( m_fIsManagedByDefault == FALSE );
  140. Assert( m_cPartitions == 0 );
  141. Assert( m_idxDevice == 0 );
  142. Assert( m_fIsDynamicDisk == FALSE );
  143. Assert( m_fIsGPTDisk == FALSE );
  144. TraceFuncExit();
  145. } //*** CPhysicalDisk::CPhysicalDisk
  146. //////////////////////////////////////////////////////////////////////////////
  147. //++
  148. //
  149. // CPhysicalDisk::~CPhysicalDisk
  150. //
  151. // Description:
  152. // Desstructor of the CPhysicalDisk class.
  153. //
  154. // Arguments:
  155. // None.
  156. //
  157. // Return Value:
  158. // None.
  159. //
  160. // Remarks:
  161. // None.
  162. //
  163. //--
  164. //////////////////////////////////////////////////////////////////////////////
  165. CPhysicalDisk::~CPhysicalDisk( void )
  166. {
  167. TraceFunc( "" );
  168. ULONG idx;
  169. TraceSysFreeString( m_bstrName );
  170. TraceSysFreeString( m_bstrDeviceID );
  171. TraceSysFreeString( m_bstrDescription );
  172. TraceSysFreeString( m_bstrFriendlyName );
  173. // TraceSysFreeString( m_bstrFirmwareSerialNumber );
  174. for ( idx = 0; idx < m_idxNextPartition; idx++ )
  175. {
  176. ((*m_prgPartitions)[ idx ])->Release();
  177. } // for:
  178. TraceFree( m_prgPartitions );
  179. if ( m_pIWbemServices != NULL )
  180. {
  181. m_pIWbemServices->Release();
  182. } // if:
  183. if ( m_picccCallback != NULL )
  184. {
  185. m_picccCallback->Release();
  186. } // if:
  187. // There's going to be one less component in memory. Decrement component count.
  188. InterlockedDecrement( &g_cObjects );
  189. TraceFuncExit();
  190. } //*** CPhysicalDisk::~CPhysicalDisk
  191. //*************************************************************************//
  192. /////////////////////////////////////////////////////////////////////////////
  193. // CPhysicalDisk -- IUknkown interface.
  194. /////////////////////////////////////////////////////////////////////////////
  195. //////////////////////////////////////////////////////////////////////////////
  196. //++
  197. //
  198. // CPhysicalDisk::AddRef
  199. //
  200. // Description:
  201. // Increment the reference count of this object by one.
  202. //
  203. // Arguments:
  204. // None.
  205. //
  206. // Return Value:
  207. // The new reference count.
  208. //
  209. // Remarks:
  210. // None.
  211. //
  212. //--
  213. //////////////////////////////////////////////////////////////////////////////
  214. STDMETHODIMP_( ULONG )
  215. CPhysicalDisk::AddRef( void )
  216. {
  217. TraceFunc( "[IUnknown]" );
  218. InterlockedIncrement( & m_cRef );
  219. CRETURN( m_cRef );
  220. } //*** CPhysicalDisk::AddRef
  221. //////////////////////////////////////////////////////////////////////////////
  222. //++
  223. //
  224. // CPhysicalDisk::Release
  225. //
  226. // Description:
  227. // Decrement the reference count of this object by one.
  228. //
  229. // Arguments:
  230. // None.
  231. //
  232. // Return Value:
  233. // The new reference count.
  234. //
  235. // Remarks:
  236. // None.
  237. //
  238. //--
  239. //////////////////////////////////////////////////////////////////////////////
  240. STDMETHODIMP_( ULONG )
  241. CPhysicalDisk::Release( void )
  242. {
  243. TraceFunc( "[IUnknown]" );
  244. LONG cRef;
  245. cRef = InterlockedDecrement( &m_cRef );
  246. if ( cRef == 0 )
  247. {
  248. TraceDo( delete this );
  249. } // if: reference count equal to zero
  250. CRETURN( cRef );
  251. } //*** CPhysicalDisk::Release
  252. //////////////////////////////////////////////////////////////////////////////
  253. //++
  254. //
  255. // CPhysicalDisk::QueryInterface
  256. //
  257. // Description:
  258. // Query this object for the passed in interface.
  259. //
  260. // Arguments:
  261. // riidIn
  262. // Id of interface requested.
  263. //
  264. // ppvOut
  265. // Pointer to the requested interface.
  266. //
  267. // Return Value:
  268. // S_OK
  269. // If the interface is available on this object.
  270. //
  271. // E_NOINTERFACE
  272. // If the interface is not available.
  273. //
  274. // E_POINTER
  275. // ppvOut was NULL.
  276. //
  277. // Remarks:
  278. // None.
  279. //
  280. //--
  281. //////////////////////////////////////////////////////////////////////////////
  282. STDMETHODIMP
  283. CPhysicalDisk::QueryInterface(
  284. REFIID riidIn
  285. , void ** ppvOut
  286. )
  287. {
  288. TraceQIFunc( riidIn, ppvOut );
  289. HRESULT hr = S_OK;
  290. //
  291. // Validate arguments.
  292. //
  293. Assert( ppvOut != NULL );
  294. if ( ppvOut == NULL )
  295. {
  296. hr = THR( E_POINTER );
  297. goto Cleanup;
  298. }
  299. //
  300. // Handle known interfaces.
  301. //
  302. if ( IsEqualIID( riidIn, IID_IUnknown ) )
  303. {
  304. *ppvOut = static_cast< IClusCfgManagedResourceInfo * >( this );
  305. } // if: IUnknown
  306. else if ( IsEqualIID( riidIn, IID_IClusCfgManagedResourceInfo ) )
  307. {
  308. *ppvOut = TraceInterface( __THISCLASS__, IClusCfgManagedResourceInfo, this, 0 );
  309. } // else if: IClusCfgManagedResourceInfo
  310. else if ( IsEqualIID( riidIn, IID_IClusCfgWbemServices ) )
  311. {
  312. *ppvOut = TraceInterface( __THISCLASS__, IClusCfgWbemServices, this, 0 );
  313. } // else if: IClusCfgWbemServices
  314. else if ( IsEqualIID( riidIn, IID_IClusCfgSetWbemObject ) )
  315. {
  316. *ppvOut = TraceInterface( __THISCLASS__, IClusCfgSetWbemObject, this, 0 );
  317. } // else if: IClusCfgSetWbemObject
  318. else if ( IsEqualIID( riidIn, IID_IEnumClusCfgPartitions ) )
  319. {
  320. *ppvOut = TraceInterface( __THISCLASS__, IEnumClusCfgPartitions, this, 0 );
  321. } // else if: IEnumClusCfgPartitions
  322. else if ( IsEqualIID( riidIn, IID_IClusCfgPhysicalDiskProperties ) )
  323. {
  324. *ppvOut = TraceInterface( __THISCLASS__, IClusCfgPhysicalDiskProperties, this, 0 );
  325. } // else if: IClusCfgPhysicalDiskProperties
  326. else if ( IsEqualIID( riidIn, IID_IClusCfgInitialize ) )
  327. {
  328. *ppvOut = TraceInterface( __THISCLASS__, IClusCfgInitialize, this, 0 );
  329. } // else if: IClusCfgInitialize
  330. else if ( IsEqualIID( riidIn, IID_IClusCfgManagedResourceCfg ) )
  331. {
  332. *ppvOut = TraceInterface( __THISCLASS__, IClusCfgManagedResourceCfg, this, 0 );
  333. } // else if: IClusCfgManagedResourceCfg
  334. else if ( IsEqualIID( riidIn, IID_IClusCfgVerifyQuorum ) )
  335. {
  336. *ppvOut = TraceInterface( __THISCLASS__, IClusCfgVerifyQuorum, this, 0 );
  337. } // else if: IClusCfgVerifyQuorum
  338. else
  339. {
  340. *ppvOut = NULL;
  341. hr = E_NOINTERFACE;
  342. }
  343. //
  344. // Add a reference to the interface if successful.
  345. //
  346. if ( SUCCEEDED( hr ) )
  347. {
  348. ((IUnknown *) *ppvOut)->AddRef();
  349. } // if: success
  350. Cleanup:
  351. QIRETURN_IGNORESTDMARSHALLING1(
  352. hr
  353. , riidIn
  354. , IID_IClusCfgManagedResourceData
  355. );
  356. } //*** CPhysicalDisk::QueryInterface
  357. //*************************************************************************//
  358. /////////////////////////////////////////////////////////////////////////////
  359. // CPhysicalDisk -- IClusCfgWbemServices interface.
  360. /////////////////////////////////////////////////////////////////////////////
  361. //////////////////////////////////////////////////////////////////////////////
  362. //++
  363. //
  364. // CPhysicalDisk::SetWbemServices
  365. //
  366. // Description:
  367. // Set the WBEM services provider.
  368. //
  369. // Arguments:
  370. // IN IWbemServices pIWbemServicesIn
  371. //
  372. // Return Value:
  373. // S_OK
  374. // Success
  375. //
  376. // E_POINTER
  377. // The pIWbemServicesIn param is NULL.
  378. //
  379. // Remarks:
  380. // None.
  381. //
  382. //--
  383. //////////////////////////////////////////////////////////////////////////////
  384. STDMETHODIMP
  385. CPhysicalDisk::SetWbemServices( IWbemServices * pIWbemServicesIn )
  386. {
  387. TraceFunc( "[IClusCfgWbemServices]" );
  388. HRESULT hr = S_OK;
  389. if ( pIWbemServicesIn == NULL )
  390. {
  391. hr = THR( E_POINTER );
  392. STATUS_REPORT( TASKID_Major_Find_Devices, TASKID_Minor_SetWbemServices_PhysDisk, IDS_ERROR_NULL_POINTER, hr );
  393. goto Cleanup;
  394. } // if:
  395. m_pIWbemServices = pIWbemServicesIn;
  396. m_pIWbemServices->AddRef();
  397. Cleanup:
  398. HRETURN( hr );
  399. } //*** CPhysicalDisk::SetWbemServices
  400. //*************************************************************************//
  401. /////////////////////////////////////////////////////////////////////////////
  402. // CPhysicalDisk -- IClusCfgInitialize interface.
  403. /////////////////////////////////////////////////////////////////////////////
  404. //////////////////////////////////////////////////////////////////////////////
  405. //++
  406. //
  407. // CPhysicalDisk::Initialize
  408. //
  409. // Description:
  410. // Initialize this component.
  411. //
  412. // Arguments:
  413. // IN IUknown * punkCallbackIn
  414. //
  415. // IN LCID lcidIn
  416. //
  417. // Return Value:
  418. // S_OK
  419. // Success
  420. //
  421. // Remarks:
  422. // None.
  423. //
  424. //--
  425. //////////////////////////////////////////////////////////////////////////////
  426. STDMETHODIMP
  427. CPhysicalDisk::Initialize(
  428. IUnknown * punkCallbackIn,
  429. LCID lcidIn
  430. )
  431. {
  432. TraceFunc( "[IClusCfgInitialize]" );
  433. Assert( m_picccCallback == NULL );
  434. HRESULT hr = S_OK;
  435. m_lcid = lcidIn;
  436. if ( punkCallbackIn == NULL )
  437. {
  438. hr = THR( E_POINTER );
  439. goto Cleanup;
  440. } // if:
  441. hr = THR( punkCallbackIn->TypeSafeQI( IClusCfgCallback, &m_picccCallback ) );
  442. Cleanup:
  443. HRETURN( hr );
  444. } //*** CPhysicalDisk::Initialize
  445. //*************************************************************************//
  446. /////////////////////////////////////////////////////////////////////////////
  447. // CPhysicalDisk -- IEnumClusCfgPartitions interface.
  448. /////////////////////////////////////////////////////////////////////////////
  449. //////////////////////////////////////////////////////////////////////////////
  450. //++
  451. //
  452. // CPhysicalDisk::Next
  453. //
  454. // Description:
  455. //
  456. //
  457. // Arguments:
  458. //
  459. // Return Value:
  460. // S_OK
  461. // Success
  462. //
  463. // E_POINTER
  464. // The rgpPartitionInfoOut param is NULL.
  465. //
  466. // Remarks:
  467. // None.
  468. //
  469. //--
  470. //////////////////////////////////////////////////////////////////////////////
  471. STDMETHODIMP
  472. CPhysicalDisk::Next(
  473. ULONG cNumberRequestedIn,
  474. IClusCfgPartitionInfo ** rgpPartitionInfoOut,
  475. ULONG * pcNumberFetchedOut
  476. )
  477. {
  478. TraceFunc( "[IEnumClusCfgPartitions]" );
  479. HRESULT hr = S_FALSE;
  480. ULONG cFetched = 0;
  481. ULONG idx;
  482. IClusCfgPartitionInfo * piccpi = NULL;
  483. if ( rgpPartitionInfoOut == NULL )
  484. {
  485. hr = THR( E_POINTER );
  486. STATUS_REPORT_REF( TASKID_Major_Find_Devices, TASKID_Minor_Next_PhysDisk, IDS_ERROR_NULL_POINTER, IDS_ERROR_NULL_POINTER_REF, hr );
  487. goto Cleanup;
  488. } // if:
  489. if ( pcNumberFetchedOut != NULL )
  490. {
  491. *pcNumberFetchedOut = 0;
  492. } // if:
  493. if ( m_prgPartitions == NULL )
  494. {
  495. LOG_STATUS_REPORT_MINOR( TASKID_Minor_PhysDisk_No_Partitions, L"A physical disk does not have a partitions enumerator", hr );
  496. goto Cleanup;
  497. } // if:
  498. cFetched = min( cNumberRequestedIn, ( m_idxNextPartition - m_idxEnumPartitionNext ) );
  499. for ( idx = 0; idx < cFetched; idx++, m_idxEnumPartitionNext++ )
  500. {
  501. hr = THR( ((*m_prgPartitions)[ m_idxEnumPartitionNext ])->TypeSafeQI( IClusCfgPartitionInfo, &piccpi ) );
  502. if ( FAILED( hr ) )
  503. {
  504. LOG_STATUS_REPORT( L"CPhysicalDisk::Next() could not query for IClusCfgPartitionInfo.", hr );
  505. break;
  506. } // if:
  507. rgpPartitionInfoOut[ idx ] = piccpi;
  508. } // for:
  509. if ( FAILED( hr ) )
  510. {
  511. ULONG idxStop = idx;
  512. m_idxEnumPartitionNext -= idx;
  513. for ( idx = 0; idx < idxStop; idx++ )
  514. {
  515. (rgpPartitionInfoOut[ idx ])->Release();
  516. } // for:
  517. cFetched = 0;
  518. goto Cleanup;
  519. } // if:
  520. if ( pcNumberFetchedOut != NULL )
  521. {
  522. *pcNumberFetchedOut = cFetched;
  523. } // if:
  524. if ( cFetched < cNumberRequestedIn )
  525. {
  526. hr = S_FALSE;
  527. } // if:
  528. Cleanup:
  529. HRETURN( hr );
  530. } //*** CPhysicalDisk::Next
  531. //////////////////////////////////////////////////////////////////////////////
  532. //++
  533. //
  534. // CPhysicalDisk::Skip
  535. //
  536. // Description:
  537. //
  538. //
  539. // Arguments:
  540. //
  541. // Return Value:
  542. // S_OK
  543. // Success
  544. //
  545. // Remarks:
  546. // None.
  547. //
  548. //--
  549. //////////////////////////////////////////////////////////////////////////////
  550. STDMETHODIMP
  551. CPhysicalDisk::Skip( ULONG cNumberToSkipIn )
  552. {
  553. TraceFunc( "[IEnumClusCfgPartitions]" );
  554. HRESULT hr = S_OK;
  555. m_idxEnumPartitionNext += cNumberToSkipIn;
  556. if ( m_idxEnumPartitionNext > m_idxNextPartition )
  557. {
  558. m_idxEnumPartitionNext = m_idxNextPartition;
  559. hr = S_FALSE;
  560. } // if:
  561. HRETURN( hr );
  562. } //*** CPhysicalDisk::Skip
  563. //////////////////////////////////////////////////////////////////////////////
  564. //++
  565. //
  566. // CPhysicalDisk::Reset
  567. //
  568. // Description:
  569. //
  570. //
  571. // Arguments:
  572. //
  573. // Return Value:
  574. // S_OK
  575. // Success
  576. //
  577. // Remarks:
  578. // None.
  579. //
  580. //--
  581. //////////////////////////////////////////////////////////////////////////////
  582. STDMETHODIMP
  583. CPhysicalDisk::Reset( void )
  584. {
  585. TraceFunc( "[IEnumClusCfgPartitions]" );
  586. HRESULT hr = S_OK;
  587. m_idxEnumPartitionNext = 0;
  588. HRETURN( hr );
  589. } //*** CPhysicalDisk::Reset
  590. //////////////////////////////////////////////////////////////////////////////
  591. //++
  592. //
  593. // CPhysicalDisk::Clone
  594. //
  595. // Description:
  596. //
  597. //
  598. // Arguments:
  599. //
  600. // Return Value:
  601. // S_OK
  602. // Success
  603. //
  604. // E_POINTER
  605. // The ppEnumClusCfgPartitionsOut param is NULL.
  606. //
  607. // Remarks:
  608. // None.
  609. //
  610. //--
  611. //////////////////////////////////////////////////////////////////////////////
  612. STDMETHODIMP
  613. CPhysicalDisk::Clone( IEnumClusCfgPartitions ** ppEnumClusCfgPartitionsOut )
  614. {
  615. TraceFunc( "[IEnumClusCfgPartitions]" );
  616. HRESULT hr = S_OK;
  617. if ( ppEnumClusCfgPartitionsOut == NULL )
  618. {
  619. hr = THR( E_POINTER );
  620. STATUS_REPORT_REF( TASKID_Major_Find_Devices, TASKID_Minor_Clone_PhysDisk, IDS_ERROR_NULL_POINTER, IDS_ERROR_NULL_POINTER_REF, hr );
  621. goto Cleanup;
  622. } // if:
  623. hr = THR( E_NOTIMPL );
  624. Cleanup:
  625. HRETURN( hr );
  626. } //*** CPhysicalDisk::Clone
  627. //////////////////////////////////////////////////////////////////////////////
  628. //++
  629. //
  630. // CPhysicalDisk::Count
  631. //
  632. // Description:
  633. //
  634. //
  635. // Arguments:
  636. //
  637. // Return Value:
  638. // S_OK
  639. // Success
  640. //
  641. // E_POINTER
  642. // The pnCountOut param is NULL.
  643. //
  644. // Remarks:
  645. // None.
  646. //
  647. //--
  648. //////////////////////////////////////////////////////////////////////////////
  649. STDMETHODIMP
  650. CPhysicalDisk::Count( DWORD * pnCountOut )
  651. {
  652. TraceFunc( "[IEnumClusCfgPartitions]" );
  653. HRESULT hr = THR( S_OK );
  654. if ( pnCountOut == NULL )
  655. {
  656. hr = THR( E_POINTER );
  657. goto Cleanup;
  658. } // if:
  659. *pnCountOut = m_cPartitions;
  660. Cleanup:
  661. HRETURN( hr );
  662. } //*** CPhysicalDisk::Count
  663. //*************************************************************************//
  664. /////////////////////////////////////////////////////////////////////////////
  665. // CPhysicalDisk -- IClusCfgSetWbemObject interface.
  666. /////////////////////////////////////////////////////////////////////////////
  667. //////////////////////////////////////////////////////////////////////////////
  668. //++
  669. //
  670. // CPhysicalDisk::SetWbemObject
  671. //
  672. // Description:
  673. // Set the disk information information provider.
  674. //
  675. // Arguments:
  676. //
  677. // Return Value:
  678. // S_OK
  679. // Success
  680. //
  681. // Remarks:
  682. // None.
  683. //
  684. //--
  685. //////////////////////////////////////////////////////////////////////////////
  686. STDMETHODIMP
  687. CPhysicalDisk::SetWbemObject(
  688. IWbemClassObject * pDiskIn
  689. , bool * pfRetainObjectOut
  690. )
  691. {
  692. TraceFunc( "[IClusCfgSetWbemObject]" );
  693. Assert( pDiskIn != NULL );
  694. Assert( pfRetainObjectOut != NULL );
  695. HRESULT hr = S_FALSE;
  696. VARIANT var;
  697. CLSID clsidMinorId;
  698. m_fIsQuorumCapable = TRUE;
  699. m_fIsQuorumResourceMultiNodeCapable = TRUE;
  700. VariantInit( &var );
  701. hr = THR( HrGetWMIProperty( pDiskIn, L"Name", VT_BSTR, &var ) );
  702. if ( FAILED( hr ) )
  703. {
  704. goto Cleanup;
  705. } // if:
  706. hr = STHR( HrCreateFriendlyName( var.bstrVal ) );
  707. if ( FAILED( hr ) )
  708. {
  709. goto Cleanup;
  710. } // if:
  711. VariantClear( &var );
  712. hr = THR( HrGetWMIProperty( pDiskIn, L"DeviceID", VT_BSTR, &var ) );
  713. if ( FAILED( hr ) )
  714. {
  715. goto Cleanup;
  716. } // if:
  717. m_bstrDeviceID = TraceSysAllocString( var.bstrVal );
  718. if (m_bstrDeviceID == NULL )
  719. {
  720. goto OutOfMemory;
  721. } // if:
  722. VariantClear( &var );
  723. hr = THR( HrGetWMIProperty( pDiskIn, L"Description", VT_BSTR, &var ) );
  724. if ( FAILED( hr ) )
  725. {
  726. goto Cleanup;
  727. } // if:
  728. m_bstrDescription = TraceSysAllocString( var.bstrVal );
  729. if ( m_bstrDescription == NULL )
  730. {
  731. goto OutOfMemory;
  732. } // if:
  733. VariantClear( &var );
  734. hr = THR( HrGetWMIProperty( pDiskIn, L"SCSIBus", VT_I4, &var ) );
  735. if ( FAILED( hr ) )
  736. {
  737. goto Cleanup;
  738. } // if:
  739. m_ulSCSIBus = var.lVal;
  740. VariantClear( &var );
  741. hr = THR( HrGetWMIProperty( pDiskIn, L"SCSITargetId", VT_I4, &var ) );
  742. if ( FAILED( hr ) )
  743. {
  744. goto Cleanup;
  745. } // if:
  746. m_ulSCSITid = var.lVal;
  747. VariantClear( &var );
  748. hr = THR( HrGetWMIProperty( pDiskIn, L"SCSIPort", VT_I4, &var ) );
  749. if ( FAILED( hr ) )
  750. {
  751. goto Cleanup;
  752. } // if:
  753. m_ulSCSIPort = var.lVal;
  754. VariantClear( &var );
  755. hr = THR( HrGetWMIProperty( pDiskIn, L"SCSILogicalUnit", VT_I4, &var ) );
  756. if ( FAILED( hr ) )
  757. {
  758. goto Cleanup;
  759. } // if:
  760. m_ulSCSILun = var.lVal;
  761. VariantClear( &var );
  762. hr = THR( HrGetWMIProperty( pDiskIn, L"Index", VT_I4, &var ) );
  763. if ( FAILED( hr ) )
  764. {
  765. goto Cleanup;
  766. } // if:
  767. m_idxDevice = var.lVal;
  768. VariantClear( &var );
  769. hr = HrGetWMIProperty( pDiskIn, L"Signature", VT_I4, &var );
  770. if ( hr == WBEM_E_NOT_FOUND )
  771. {
  772. //
  773. // If the signature is not found then log it and let everything continue.
  774. //
  775. LOG_STATUS_REPORT_STRING( L"Physical disk %1!ws! does not have a signature property.", m_bstrName, hr );
  776. var.lVal = 0L;
  777. hr = S_OK;
  778. } // if:
  779. if ( FAILED( hr ) )
  780. {
  781. THR( hr );
  782. goto Cleanup;
  783. } // if:
  784. //
  785. // Did we actually get a value? Could be VT_NULL to indicate that it is empty.
  786. // We only want VT_I4 values...
  787. //
  788. if ( var.vt == VT_I4 )
  789. {
  790. m_dwSignature = (DWORD) var.lVal;
  791. } // else if:
  792. LOG_STATUS_REPORT_STRING2( L"Physical disk %1!ws! has signature %2!x!.", m_bstrName, m_dwSignature, hr );
  793. if ( FAILED( hr ) )
  794. {
  795. STATUS_REPORT_REF(
  796. TASKID_Major_Find_Devices
  797. , TASKID_Minor_PhysDisk_Signature
  798. , IDS_ERROR_PHYSDISK_SIGNATURE
  799. , IDS_ERROR_PHYSDISK_SIGNATURE_REF
  800. , hr
  801. );
  802. THR( hr );
  803. goto Cleanup;
  804. } // if:
  805. VariantClear( &var );
  806. hr = STHR( HrGetPartitionInfo( pDiskIn, pfRetainObjectOut ) );
  807. if ( FAILED( hr ) )
  808. {
  809. goto Cleanup;
  810. } // if:
  811. //
  812. // KB: 28-JUL-2000 GalenB
  813. //
  814. // HrGetPartitionInfo() returns S_FALSE when it cannot get the partition info for a disk.
  815. // This is usually caused by the disk already being under ClusDisk control. This is not
  816. // and error, it just means we cannot query the partition or logical drive info.
  817. //
  818. if ( hr == S_OK )
  819. {
  820. hr = STHR( HrCreateFriendlyName() );
  821. if ( FAILED( hr ) )
  822. {
  823. goto Cleanup;
  824. } // if:
  825. //
  826. // Since we have partition info we also have a signature and need to see if this
  827. // disk is cluster capable.
  828. hr = STHR( HrIsClusterCapable() );
  829. if ( FAILED( hr ) )
  830. {
  831. goto Cleanup;
  832. } // if:
  833. //
  834. // If the disk is not cluster capable then we don't want the enumerator
  835. // to keep it.
  836. //
  837. if ( hr == S_FALSE )
  838. {
  839. HRESULT hrTemp;
  840. STATUS_REPORT( TASKID_Major_Find_Devices, TASKID_Minor_PhysDisk_Cluster_Capable, IDS_INFO_PHYSDISK_CLUSTER_CAPABLE, hr );
  841. hrTemp = THR( CoCreateGuid( &clsidMinorId ) );
  842. if ( FAILED( hrTemp ) )
  843. {
  844. LOG_STATUS_REPORT( L"Could not create a guid for a not cluster capable disk minor task ID", hrTemp );
  845. clsidMinorId = IID_NULL;
  846. } // if:
  847. *pfRetainObjectOut = false;
  848. STATUS_REPORT_STRING_REF(
  849. TASKID_Minor_PhysDisk_Cluster_Capable
  850. , clsidMinorId
  851. , IDS_INFO_PHYSDISK_NOT_CLUSTER_CAPABLE
  852. , m_bstrFriendlyName
  853. , IDS_INFO_PHYSDISK_NOT_CLUSTER_CAPABLE_REF
  854. , hr
  855. );
  856. LOG_STATUS_REPORT_STRING( L"The '%1!ws!' physical disk is not cluster capable", m_bstrFriendlyName, hr );
  857. } // if:
  858. /* else
  859. {
  860. hr = THR( HrProcessMountPoints() );
  861. if ( FAILED( hr ) )
  862. {
  863. goto Cleanup;
  864. } // if:
  865. } // else:
  866. */
  867. } // if:
  868. //
  869. // TODO: 15-MAR-2001 GalenB
  870. //
  871. // Need to check this error code when this feature is complete!
  872. //
  873. //hr = THR( HrGetDiskFirmwareSerialNumber() );
  874. //THR( HrGetDiskFirmwareVitalData() );
  875. goto Cleanup;
  876. OutOfMemory:
  877. hr = THR( E_OUTOFMEMORY );
  878. STATUS_REPORT( TASKID_Major_Find_Devices, TASKID_Minor_SetWbemObject_PhysDisk, IDS_ERROR_OUTOFMEMORY, hr );
  879. Cleanup:
  880. VariantClear( &var );
  881. HRETURN( hr );
  882. } //*** CPhysicalDisk::SetWbemObject
  883. //*************************************************************************//
  884. /////////////////////////////////////////////////////////////////////////////
  885. // CPhysicalDisk -- IClusCfgManagedResourceInfo interface.
  886. /////////////////////////////////////////////////////////////////////////////
  887. //////////////////////////////////////////////////////////////////////////////
  888. //++
  889. //
  890. // CPhysicalDisk::GetUID
  891. //
  892. // Description:
  893. //
  894. // Arguments:
  895. // pbstrUIDOut
  896. //
  897. // Return Value:
  898. //
  899. // Remarks:
  900. // None.
  901. //
  902. //--
  903. //////////////////////////////////////////////////////////////////////////////
  904. STDMETHODIMP
  905. CPhysicalDisk::GetUID( BSTR * pbstrUIDOut )
  906. {
  907. TraceFunc( "[IClusCfgManagedResourceInfo]" );
  908. HRESULT hr = S_OK;
  909. WCHAR sz[ 256 ];
  910. if ( pbstrUIDOut == NULL )
  911. {
  912. hr = THR( E_POINTER );
  913. STATUS_REPORT_REF( TASKID_Major_Find_Devices, TASKID_Minor_PhysDisk_GetUID_Pointer, IDS_ERROR_NULL_POINTER, IDS_ERROR_NULL_POINTER_REF, hr );
  914. goto Cleanup;
  915. } // if:
  916. hr = THR( StringCchPrintfW( sz, ARRAYSIZE( sz ), L"SCSI Tid %ld, SCSI Lun %ld", m_ulSCSITid, m_ulSCSILun ) );
  917. if ( FAILED( hr ) )
  918. {
  919. goto Cleanup;
  920. } // if:
  921. *pbstrUIDOut = SysAllocString( sz );
  922. if ( *pbstrUIDOut == NULL )
  923. {
  924. hr = THR( E_OUTOFMEMORY );
  925. STATUS_REPORT( TASKID_Major_Find_Devices, TASKID_Minor_PhysDisk_GetUID_Memory, IDS_ERROR_OUTOFMEMORY, hr );
  926. } // if:
  927. Cleanup:
  928. HRETURN( hr );
  929. } //*** CPhysicalDisk::GetUID
  930. //////////////////////////////////////////////////////////////////////////////
  931. //++
  932. //
  933. // CPhysicalDisk::GetName
  934. //
  935. // Description:
  936. //
  937. // Arguments:
  938. //
  939. // Return Value:
  940. //
  941. // Remarks:
  942. // None.
  943. //
  944. //--
  945. //////////////////////////////////////////////////////////////////////////////
  946. STDMETHODIMP
  947. CPhysicalDisk::GetName( BSTR * pbstrNameOut )
  948. {
  949. TraceFunc( "[IClusCfgManagedResourceInfo]" );
  950. HRESULT hr = S_OK;
  951. if ( pbstrNameOut == NULL )
  952. {
  953. hr = THR( E_POINTER );
  954. STATUS_REPORT_REF( TASKID_Major_Find_Devices, TASKID_Minor_GetName_Pointer, IDS_ERROR_NULL_POINTER, IDS_ERROR_NULL_POINTER_REF, hr );
  955. goto Cleanup;
  956. } // if:
  957. //
  958. // Prefer the "friendly" name over the WMI name -- if we have it...
  959. //
  960. if ( m_bstrFriendlyName != NULL )
  961. {
  962. *pbstrNameOut = SysAllocString( m_bstrFriendlyName );
  963. } // if:
  964. else
  965. {
  966. LOG_STATUS_REPORT_STRING( L"There is not a \"friendly name\" for the physical disk \"%1!ws!\".", m_bstrName, hr );
  967. *pbstrNameOut = SysAllocString( m_bstrName );
  968. } // else:
  969. if (*pbstrNameOut == NULL )
  970. {
  971. hr = THR( E_OUTOFMEMORY );
  972. STATUS_REPORT( TASKID_Major_Find_Devices, TASKID_Minor_GetName_Memory, IDS_ERROR_OUTOFMEMORY, hr );
  973. } // if:
  974. Cleanup:
  975. HRETURN( hr );
  976. } //*** CPhysicalDisk::GetName
  977. //////////////////////////////////////////////////////////////////////////////
  978. //++
  979. //
  980. // CPhysicalDisk::SetName
  981. //
  982. // Description:
  983. //
  984. // Arguments:
  985. //
  986. // Return Value:
  987. //
  988. // Remarks:
  989. // None.
  990. //
  991. //--
  992. //////////////////////////////////////////////////////////////////////////////
  993. STDMETHODIMP
  994. CPhysicalDisk::SetName( LPCWSTR pcszNameIn )
  995. {
  996. TraceFunc1( "[IClusCfgManagedResourceInfo] pcszNameIn = '%ws'", pcszNameIn == NULL ? L"<null>" : pcszNameIn );
  997. HRESULT hr = S_OK;
  998. BSTR bstr = NULL;
  999. if ( pcszNameIn == NULL )
  1000. {
  1001. hr = THR( E_INVALIDARG );
  1002. goto Cleanup;
  1003. } // if:
  1004. bstr = TraceSysAllocString( pcszNameIn );
  1005. if ( bstr == NULL )
  1006. {
  1007. hr = THR( E_OUTOFMEMORY );
  1008. STATUS_REPORT( TASKID_Major_Find_Devices, TASKID_Minor_SetName_PhysDisk, IDS_ERROR_OUTOFMEMORY, hr );
  1009. goto Cleanup;
  1010. } // if:
  1011. TraceSysFreeString( m_bstrName );
  1012. m_bstrName = bstr;
  1013. //
  1014. // Since we got asked from the outside to set a new name, this should actually be reflected in
  1015. // the friendly name, too, since that, ultimately, gets preference over the real name
  1016. //
  1017. hr = HrSetFriendlyName( pcszNameIn );
  1018. Cleanup:
  1019. HRETURN( hr );
  1020. } //*** CPhysicalDisk::SetName
  1021. //////////////////////////////////////////////////////////////////////////////
  1022. //++
  1023. //
  1024. // CPhysicalDisk::IsManaged
  1025. //
  1026. // Description:
  1027. //
  1028. // Arguments:
  1029. //
  1030. // Return Value:
  1031. // S_OK
  1032. // The device is managed.
  1033. //
  1034. // S_FALSE
  1035. // The device is not managed.
  1036. //
  1037. // Win32 error as HRESULT when an error occurs.
  1038. //
  1039. // Remarks:
  1040. // None.
  1041. //
  1042. //--
  1043. //////////////////////////////////////////////////////////////////////////////
  1044. STDMETHODIMP
  1045. CPhysicalDisk::IsManaged( void )
  1046. {
  1047. TraceFunc( "[IClusCfgManagedResourceInfo]" );
  1048. HRESULT hr = S_FALSE;
  1049. if ( m_fIsManaged )
  1050. {
  1051. hr = S_OK;
  1052. } // if:
  1053. HRETURN( hr );
  1054. } //*** CPhysicalDisk::IsManaged
  1055. //////////////////////////////////////////////////////////////////////////////
  1056. //++
  1057. //
  1058. // CPhysicalDisk::SetManaged
  1059. //
  1060. // Description:
  1061. //
  1062. // Arguments:
  1063. // fIsManagedIn
  1064. //
  1065. // Return Value:
  1066. //
  1067. // Remarks:
  1068. // None.
  1069. //
  1070. //--
  1071. //////////////////////////////////////////////////////////////////////////////
  1072. STDMETHODIMP
  1073. CPhysicalDisk::SetManaged(
  1074. BOOL fIsManagedIn
  1075. )
  1076. {
  1077. TraceFunc( "[IClusCfgManagedResourceInfo]" );
  1078. HRESULT hr = S_OK;
  1079. m_fIsManaged = fIsManagedIn;
  1080. LOG_STATUS_REPORT_STRING2(
  1081. L"Physical disk '%1!ws!' '%2!ws!"
  1082. , ( m_bstrFriendlyName != NULL ) ? m_bstrFriendlyName : m_bstrName
  1083. , m_fIsManaged ? L"is managed" : L"is not managed"
  1084. , hr
  1085. );
  1086. HRETURN( hr );
  1087. } //*** CPhysicalDisk::SetManaged
  1088. //////////////////////////////////////////////////////////////////////////////
  1089. //++
  1090. //
  1091. // CPhysicalDisk::IsQuorumResource
  1092. //
  1093. // Description:
  1094. //
  1095. // Arguments:
  1096. //
  1097. // Return Value:
  1098. // S_OK
  1099. // The device is the quorum device.
  1100. //
  1101. // S_FALSE
  1102. // The device is not the quorum device.
  1103. //
  1104. // Win32 error as HRESULT when an error occurs.
  1105. //
  1106. // Remarks:
  1107. // None.
  1108. //
  1109. //--
  1110. //////////////////////////////////////////////////////////////////////////////
  1111. STDMETHODIMP
  1112. CPhysicalDisk::IsQuorumResource( void )
  1113. {
  1114. TraceFunc( "[IClusCfgManagedResourceInfo]" );
  1115. HRESULT hr = S_FALSE;
  1116. if ( m_fIsQuorumResource )
  1117. {
  1118. hr = S_OK;
  1119. } // if:
  1120. LOG_STATUS_REPORT_STRING2(
  1121. L"Physical disk '%1!ws!' '%2!ws!' the quorum device."
  1122. , ( m_bstrFriendlyName != NULL ) ? m_bstrFriendlyName : m_bstrDeviceID
  1123. , m_fIsQuorumResource ? L"is" : L"is not"
  1124. , hr
  1125. );
  1126. HRETURN( hr );
  1127. } //*** CPhysicalDisk::IsQuorumResource
  1128. //////////////////////////////////////////////////////////////////////////////
  1129. //++
  1130. //
  1131. // CPhysicalDisk::SetQuorumResource
  1132. //
  1133. // Description:
  1134. //
  1135. // Arguments:
  1136. //
  1137. // Return Value:
  1138. //
  1139. // Remarks:
  1140. // None.
  1141. //
  1142. //--
  1143. //////////////////////////////////////////////////////////////////////////////
  1144. STDMETHODIMP
  1145. CPhysicalDisk::SetQuorumResource( BOOL fIsQuorumResourceIn )
  1146. {
  1147. TraceFunc( "[IClusCfgManagedResourceInfo]" );
  1148. HRESULT hr = S_OK;
  1149. //
  1150. // Since no accurate determination can be made about a disk's quorum capability
  1151. // when the node that it's on does not hold the SCSI reservation and have access
  1152. // to the media we must blindly accept the input given...
  1153. //
  1154. /*
  1155. //
  1156. // If we are not quorum capable then we should not allow ourself to be
  1157. // made the quorum resource.
  1158. //
  1159. if ( ( fIsQuorumResourceIn ) && ( m_fIsQuorumCapable == FALSE ) )
  1160. {
  1161. hr = HRESULT_FROM_WIN32( ERROR_NOT_QUORUM_CAPABLE );
  1162. goto Cleanup;
  1163. } // if:
  1164. */
  1165. m_fIsQuorumResource = fIsQuorumResourceIn;
  1166. LOG_STATUS_REPORT_STRING2(
  1167. L"Setting physical disk '%1!ws!' '%2!ws!' the quorum device."
  1168. , ( m_bstrFriendlyName != NULL ) ? m_bstrFriendlyName : m_bstrDeviceID
  1169. , m_fIsQuorumResource ? L"to be" : L"to not be"
  1170. , hr
  1171. );
  1172. //Cleanup:
  1173. HRETURN( hr );
  1174. } //*** CPhysicalDisk::SetQuorumResource
  1175. //////////////////////////////////////////////////////////////////////////////
  1176. //++
  1177. //
  1178. // CPhysicalDisk::IsQuorumCapable
  1179. //
  1180. // Description:
  1181. //
  1182. // Arguments:
  1183. //
  1184. // Return Value:
  1185. // S_OK
  1186. // The device is a quorum capable device.
  1187. //
  1188. // S_FALSE
  1189. // The device is not a quorum capable device.
  1190. //
  1191. // Win32 error as HRESULT when an error occurs.
  1192. //
  1193. // Remarks:
  1194. // None.
  1195. //
  1196. //--
  1197. //////////////////////////////////////////////////////////////////////////////
  1198. STDMETHODIMP
  1199. CPhysicalDisk::IsQuorumCapable( void )
  1200. {
  1201. TraceFunc( "[IClusCfgManagedResourceInfo]" );
  1202. HRESULT hr = S_FALSE;
  1203. if ( m_fIsQuorumCapable )
  1204. {
  1205. hr = S_OK;
  1206. } // if:
  1207. HRETURN( hr );
  1208. } //*** CPhysicalDisk::IsQuorumCapable
  1209. //////////////////////////////////////////////////////////////////////////
  1210. //
  1211. // CPhysicalDisk::SetQuorumCapable
  1212. //
  1213. // Description:
  1214. // Call this to set whether the resource is capable to be the quorum
  1215. // resource or not.
  1216. //
  1217. // Parameter:
  1218. // fIsQuorumCapableIn - If TRUE, the resource will be marked as quorum capable.
  1219. //
  1220. // Return Values:
  1221. // S_OK
  1222. // Call succeeded.
  1223. //
  1224. //////////////////////////////////////////////////////////////////////////
  1225. STDMETHODIMP
  1226. CPhysicalDisk::SetQuorumCapable(
  1227. BOOL fIsQuorumCapableIn
  1228. )
  1229. {
  1230. TraceFunc( "[IClusCfgManagedResourceInfo]" );
  1231. HRESULT hr = S_OK;
  1232. m_fIsQuorumCapable = fIsQuorumCapableIn;
  1233. HRETURN( hr );
  1234. } //*** CPhysicalDisk::SetQuorumCapable
  1235. //////////////////////////////////////////////////////////////////////////////
  1236. //++
  1237. //
  1238. // CPhysicalDisk::GetDriveLetterMappings
  1239. //
  1240. // Description:
  1241. //
  1242. // Arguments:
  1243. //
  1244. // Return Value:
  1245. //
  1246. // Remarks:
  1247. // None.
  1248. //
  1249. //--
  1250. //////////////////////////////////////////////////////////////////////////////
  1251. STDMETHODIMP
  1252. CPhysicalDisk::GetDriveLetterMappings(
  1253. SDriveLetterMapping * pdlmDriveLetterMappingOut
  1254. )
  1255. {
  1256. TraceFunc( "[IClusCfgManagedResourceInfo]" );
  1257. HRESULT hr = S_FALSE;
  1258. IClusCfgPartitionInfo * piccpi = NULL;
  1259. ULONG idx;
  1260. if ( pdlmDriveLetterMappingOut == NULL )
  1261. {
  1262. hr = THR( E_POINTER );
  1263. STATUS_REPORT_REF( TASKID_Major_Find_Devices, TASKID_Minor_GetDriveLetterMappings_PhysDisk, IDS_ERROR_NULL_POINTER, IDS_ERROR_NULL_POINTER_REF, hr );
  1264. goto Cleanup;
  1265. } // if:
  1266. for ( idx = 0; idx < m_idxNextPartition; idx++ )
  1267. {
  1268. hr = ( ((*m_prgPartitions)[ idx ])->TypeSafeQI( IClusCfgPartitionInfo, &piccpi ) );
  1269. if ( FAILED( hr ) )
  1270. {
  1271. goto Cleanup;
  1272. } // if:
  1273. hr = STHR( piccpi->GetDriveLetterMappings( pdlmDriveLetterMappingOut ) );
  1274. if ( FAILED( hr ) )
  1275. {
  1276. goto Cleanup;
  1277. } // if:
  1278. piccpi->Release();
  1279. piccpi = NULL;
  1280. } // for:
  1281. Cleanup:
  1282. if ( piccpi != NULL )
  1283. {
  1284. piccpi->Release();
  1285. } // if:
  1286. HRETURN( hr );
  1287. } //*** CPhysicalDisk::GetDriveLetterMappings
  1288. //////////////////////////////////////////////////////////////////////////////
  1289. //++
  1290. //
  1291. // CPhysicalDisk::SetDriveLetterMappings
  1292. //
  1293. // Description:
  1294. //
  1295. // Arguments:
  1296. //
  1297. // Return Value:
  1298. //
  1299. // Remarks:
  1300. // None.
  1301. //
  1302. //--
  1303. //////////////////////////////////////////////////////////////////////////////
  1304. STDMETHODIMP
  1305. CPhysicalDisk::SetDriveLetterMappings(
  1306. SDriveLetterMapping dlmDriveLetterMappingIn
  1307. )
  1308. {
  1309. TraceFunc( "[IClusCfgManagedResourceInfo]" );
  1310. HRESULT hr = THR( E_NOTIMPL );
  1311. HRETURN( hr );
  1312. } //*** CPhysicalDisk::SetDriveLetterMappings
  1313. //////////////////////////////////////////////////////////////////////////////
  1314. //++
  1315. //
  1316. // CPhysicalDisk::IsManagedByDefault
  1317. //
  1318. // Description:
  1319. // Should this resource be managed by the cluster by default?
  1320. //
  1321. // Arguments:
  1322. // None.
  1323. //
  1324. // Return Value:
  1325. // S_OK
  1326. // The device is managed by default.
  1327. //
  1328. // S_FALSE
  1329. // The device is not managed by default.
  1330. //
  1331. // Win32 error as HRESULT when an error occurs.
  1332. //
  1333. // Remarks:
  1334. // None.
  1335. //
  1336. //--
  1337. //////////////////////////////////////////////////////////////////////////////
  1338. STDMETHODIMP
  1339. CPhysicalDisk::IsManagedByDefault( void )
  1340. {
  1341. TraceFunc( "[IClusCfgManagedResourceInfo]" );
  1342. HRESULT hr = S_FALSE;
  1343. if ( m_fIsManagedByDefault )
  1344. {
  1345. hr = S_OK;
  1346. } // if:
  1347. HRETURN( hr );
  1348. } //*** CPhysicalDisk::IsManagedByDefault
  1349. //////////////////////////////////////////////////////////////////////////////
  1350. //++
  1351. //
  1352. // CPhysicalDisk::SetManagedByDefault
  1353. //
  1354. // Description:
  1355. //
  1356. // Arguments:
  1357. // fIsManagedByDefaultIn
  1358. //
  1359. // Return Value:
  1360. //
  1361. // Remarks:
  1362. // None.
  1363. //
  1364. //--
  1365. //////////////////////////////////////////////////////////////////////////////
  1366. STDMETHODIMP
  1367. CPhysicalDisk::SetManagedByDefault(
  1368. BOOL fIsManagedByDefaultIn
  1369. )
  1370. {
  1371. TraceFunc( "[IClusCfgManagedResourceInfo]" );
  1372. HRESULT hr = S_OK;
  1373. m_fIsManagedByDefault = fIsManagedByDefaultIn;
  1374. LOG_STATUS_REPORT_STRING2(
  1375. L"Physical disk '%1!ws!' '%2!ws!"
  1376. , ( m_bstrFriendlyName != NULL ) ? m_bstrFriendlyName : m_bstrName
  1377. , fIsManagedByDefaultIn ? L"is manageable" : L"is not manageable"
  1378. , hr
  1379. );
  1380. HRETURN( hr );
  1381. } //*** CPhysicalDisk::SetManagedByDefault
  1382. //*************************************************************************//
  1383. /////////////////////////////////////////////////////////////////////////////
  1384. // CPhysicalDisk class -- IClusCfgPhysicalDiskProperties Interface.
  1385. /////////////////////////////////////////////////////////////////////////////
  1386. //////////////////////////////////////////////////////////////////////////////
  1387. //++
  1388. //
  1389. // CPhysicalDisk::IsThisLogicalDisk
  1390. //
  1391. // Description:
  1392. //
  1393. // Arguments:
  1394. // None.
  1395. //
  1396. // Return Value:
  1397. //
  1398. //
  1399. // Remarks:
  1400. // None.
  1401. //
  1402. //--
  1403. //////////////////////////////////////////////////////////////////////////////
  1404. STDMETHODIMP
  1405. CPhysicalDisk::IsThisLogicalDisk( WCHAR cLogicalDiskIn )
  1406. {
  1407. TraceFunc( "[IClusCfgPhysicalDiskProperties]" );
  1408. HRESULT hr = S_FALSE;
  1409. ULONG idx;
  1410. IClusCfgPartitionProperties * piccpp = NULL;
  1411. for ( idx = 0; idx < m_idxNextPartition; idx++ )
  1412. {
  1413. hr = ( ((*m_prgPartitions)[ idx ])->TypeSafeQI( IClusCfgPartitionProperties, &piccpp ) );
  1414. if ( FAILED( hr ) )
  1415. {
  1416. goto Cleanup;
  1417. } // if:
  1418. hr = STHR( piccpp->IsThisLogicalDisk( cLogicalDiskIn ) );
  1419. if ( FAILED( hr ) )
  1420. {
  1421. goto Cleanup;
  1422. } // if:
  1423. if ( hr == S_OK )
  1424. {
  1425. break;
  1426. } // if:
  1427. piccpp->Release();
  1428. piccpp = NULL;
  1429. } // for:
  1430. Cleanup:
  1431. if ( piccpp != NULL )
  1432. {
  1433. piccpp->Release();
  1434. } // if:
  1435. HRETURN( hr );
  1436. } //*** CPhysicalDisk::IsThisLogicalDisk
  1437. //////////////////////////////////////////////////////////////////////////////
  1438. //++
  1439. //
  1440. // CPhysicalDisk::HrGetSCSIBus
  1441. //
  1442. // Description:
  1443. //
  1444. // Arguments:
  1445. // None.
  1446. //
  1447. // Return Value:
  1448. //
  1449. //
  1450. // Remarks:
  1451. // None.
  1452. //
  1453. //--
  1454. //////////////////////////////////////////////////////////////////////////////
  1455. STDMETHODIMP
  1456. CPhysicalDisk::HrGetSCSIBus( ULONG * pulSCSIBusOut )
  1457. {
  1458. TraceFunc( "[IClusCfgPhysicalDiskProperties]" );
  1459. HRESULT hr = S_OK;
  1460. if ( pulSCSIBusOut == NULL )
  1461. {
  1462. hr = THR( E_POINTER );
  1463. STATUS_REPORT_REF( TASKID_Major_Find_Devices, TASKID_Minor_HrGetSCSIBus, IDS_ERROR_NULL_POINTER, IDS_ERROR_NULL_POINTER_REF, hr );
  1464. goto Cleanup;
  1465. } // if:
  1466. *pulSCSIBusOut = m_ulSCSIBus;
  1467. Cleanup:
  1468. HRETURN( hr );
  1469. } //*** CPhysicalDisk::HrGetSCSIBus
  1470. //////////////////////////////////////////////////////////////////////////////
  1471. //++
  1472. //
  1473. // CPhysicalDisk::HrGetSCSIPort
  1474. //
  1475. // Description:
  1476. //
  1477. // Arguments:
  1478. // None.
  1479. //
  1480. // Return Value:
  1481. //
  1482. //
  1483. // Remarks:
  1484. // None.
  1485. //
  1486. //--
  1487. //////////////////////////////////////////////////////////////////////////////
  1488. STDMETHODIMP
  1489. CPhysicalDisk::HrGetSCSIPort( ULONG * pulSCSIPortOut )
  1490. {
  1491. TraceFunc( "[IClusCfgPhysicalDiskProperties]" );
  1492. HRESULT hr = S_OK;
  1493. if ( pulSCSIPortOut == NULL )
  1494. {
  1495. hr = THR( E_POINTER );
  1496. STATUS_REPORT_REF( TASKID_Major_Find_Devices, TASKID_Minor_HrGetSCSIPort, IDS_ERROR_NULL_POINTER, IDS_ERROR_NULL_POINTER_REF, hr );
  1497. goto Cleanup;
  1498. } // if:
  1499. *pulSCSIPortOut = m_ulSCSIPort;
  1500. Cleanup:
  1501. HRETURN( hr );
  1502. } //*** CPhysicalDisk::HrGetSCSIPort
  1503. //////////////////////////////////////////////////////////////////////////////
  1504. //++
  1505. //
  1506. // CPhysicalDisk::HrGetDeviceID
  1507. //
  1508. // Description:
  1509. //
  1510. // Arguments:
  1511. // None.
  1512. //
  1513. // Return Value:
  1514. //
  1515. //
  1516. // Remarks:
  1517. // None.
  1518. //
  1519. //--
  1520. //////////////////////////////////////////////////////////////////////////////
  1521. STDMETHODIMP
  1522. CPhysicalDisk::HrGetDeviceID( BSTR * pbstrDeviceIDOut )
  1523. {
  1524. TraceFunc( "" );
  1525. Assert( m_bstrDeviceID != NULL );
  1526. HRESULT hr = S_OK;
  1527. if ( pbstrDeviceIDOut == NULL )
  1528. {
  1529. hr = THR( E_POINTER );
  1530. STATUS_REPORT_REF( TASKID_Major_Find_Devices, TASKID_Minor_HrGetDeviceID_Pointer, IDS_ERROR_NULL_POINTER, IDS_ERROR_NULL_POINTER_REF, hr );
  1531. goto Cleanup;
  1532. } // if:
  1533. *pbstrDeviceIDOut = TraceSysAllocString( m_bstrDeviceID );
  1534. if ( *pbstrDeviceIDOut == NULL )
  1535. {
  1536. hr = THR( E_OUTOFMEMORY );
  1537. STATUS_REPORT_REF( TASKID_Major_Find_Devices, TASKID_Minor_HrGetDeviceID_Memory, IDS_ERROR_OUTOFMEMORY, IDS_ERROR_OUTOFMEMORY_REF, hr );
  1538. } // if:
  1539. Cleanup:
  1540. HRETURN( hr );
  1541. } //*** CPhysicalDisk::HrGetDeviceID
  1542. //////////////////////////////////////////////////////////////////////////////
  1543. //++
  1544. //
  1545. // CPhysicalDisk::HrGetSignature
  1546. //
  1547. // Description:
  1548. //
  1549. // Arguments:
  1550. // None.
  1551. //
  1552. // Return Value:
  1553. //
  1554. //
  1555. // Remarks:
  1556. // None.
  1557. //
  1558. //--
  1559. //////////////////////////////////////////////////////////////////////////////
  1560. STDMETHODIMP
  1561. CPhysicalDisk::HrGetSignature( DWORD * pdwSignatureOut )
  1562. {
  1563. TraceFunc( "" );
  1564. Assert( m_dwSignature != 0 );
  1565. HRESULT hr = S_OK;
  1566. if ( pdwSignatureOut == NULL )
  1567. {
  1568. hr = THR( E_POINTER );
  1569. STATUS_REPORT_REF( TASKID_Major_Find_Devices, TASKID_Minor_HrGetSignature_Pointer, IDS_ERROR_NULL_POINTER, IDS_ERROR_NULL_POINTER_REF, hr );
  1570. goto Cleanup;
  1571. } // if:
  1572. *pdwSignatureOut = m_dwSignature;
  1573. Cleanup:
  1574. HRETURN( hr );
  1575. } //*** CPhysicalDisk::HrGetSignature
  1576. //////////////////////////////////////////////////////////////////////////////
  1577. //++
  1578. //
  1579. // CPhysicalDisk::HrSetFriendlyName
  1580. //
  1581. // Description:
  1582. //
  1583. // Arguments:
  1584. //
  1585. // Return Value:
  1586. //
  1587. // Remarks:
  1588. // None.
  1589. //
  1590. //--
  1591. //////////////////////////////////////////////////////////////////////////////
  1592. STDMETHODIMP
  1593. CPhysicalDisk::HrSetFriendlyName( LPCWSTR pcszFriendlyNameIn )
  1594. {
  1595. TraceFunc1( "[IClusCfgManagedResourceInfo] pcszFriendlyNameIn = '%ws'", pcszFriendlyNameIn == NULL ? L"<null>" : pcszFriendlyNameIn );
  1596. HRESULT hr = S_OK;
  1597. BSTR bstr = NULL;
  1598. if ( pcszFriendlyNameIn == NULL )
  1599. {
  1600. hr = THR( E_INVALIDARG );
  1601. goto Cleanup;
  1602. } // if:
  1603. bstr = TraceSysAllocString( pcszFriendlyNameIn );
  1604. if ( bstr == NULL )
  1605. {
  1606. hr = THR( E_OUTOFMEMORY );
  1607. STATUS_REPORT( TASKID_Major_Find_Devices, TASKID_Minor_HrSetFriendlyName_PhysDisk, IDS_ERROR_OUTOFMEMORY, hr );
  1608. goto Cleanup;
  1609. } // if:
  1610. TraceSysFreeString( m_bstrFriendlyName );
  1611. m_bstrFriendlyName = bstr;
  1612. LOG_STATUS_REPORT_STRING( L"Setting physical disk friendly name to \"%1!ws!\".", m_bstrFriendlyName, hr );
  1613. Cleanup:
  1614. HRETURN( hr );
  1615. } //*** CPhysicalDisk::HrSetFriendlyName
  1616. //////////////////////////////////////////////////////////////////////////////
  1617. //++
  1618. //
  1619. // CPhysicalDisk::HrGetDeviceIndex
  1620. //
  1621. // Description:
  1622. //
  1623. // Arguments:
  1624. //
  1625. // Return Value:
  1626. //
  1627. // Remarks:
  1628. // None.
  1629. //
  1630. //--
  1631. //////////////////////////////////////////////////////////////////////////////
  1632. STDMETHODIMP
  1633. CPhysicalDisk::HrGetDeviceIndex( DWORD * pidxDeviceOut )
  1634. {
  1635. TraceFunc( "" );
  1636. HRESULT hr = S_OK;
  1637. if ( pidxDeviceOut == NULL )
  1638. {
  1639. hr = THR( E_POINTER );
  1640. goto Cleanup;
  1641. } // if:
  1642. *pidxDeviceOut = m_idxDevice;
  1643. Cleanup:
  1644. HRETURN( hr );
  1645. } //*** CPhysicalDisk::HrGetDeviceIndex
  1646. //////////////////////////////////////////////////////////////////////////////
  1647. //++
  1648. //
  1649. // CPhysicalDisk::CanBeManaged
  1650. //
  1651. // Description:
  1652. //
  1653. // Arguments:
  1654. //
  1655. // Return Value:
  1656. // S_OK
  1657. // The device is managed.
  1658. //
  1659. // S_FALSE
  1660. // The device is not managed.
  1661. //
  1662. // Win32 error as HRESULT when an error occurs.
  1663. //
  1664. // Remarks:
  1665. // None.
  1666. //
  1667. //--
  1668. //////////////////////////////////////////////////////////////////////////////
  1669. STDMETHODIMP
  1670. CPhysicalDisk::CanBeManaged( void )
  1671. {
  1672. TraceFunc( "[IClusCfgPhysicalDiskProperties]" );
  1673. HRESULT hr = S_OK;
  1674. ULONG idx;
  1675. IClusCfgPartitionProperties * piccpp = NULL;
  1676. //
  1677. // Turn off the manageable state because this disk may already be managed by
  1678. // another node, or it may be RAW.
  1679. //
  1680. m_fIsManagedByDefault = FALSE;
  1681. //
  1682. // A disk must have at least one NTFS partition in order to be a quorum
  1683. // resource.
  1684. //
  1685. m_fIsQuorumCapable = FALSE;
  1686. m_fIsQuorumResourceMultiNodeCapable = FALSE;
  1687. //
  1688. // If this disk has no partitions then it may already be managed by
  1689. // another node, or it may be RAW.
  1690. //
  1691. if ( m_idxNextPartition == 0 )
  1692. {
  1693. hr = S_FALSE;
  1694. goto Cleanup;
  1695. } // if:
  1696. //
  1697. // Enum the partitions and set the quorum capable flag if an NTFS
  1698. // partition is found.
  1699. //
  1700. for ( idx = 0; idx < m_idxNextPartition; idx++ )
  1701. {
  1702. hr = ( ((*m_prgPartitions)[ idx ])->TypeSafeQI( IClusCfgPartitionProperties, &piccpp ) );
  1703. if ( FAILED( hr ) )
  1704. {
  1705. goto Cleanup;
  1706. } // if:
  1707. hr = STHR( piccpp->IsNTFS() );
  1708. if ( hr == S_OK )
  1709. {
  1710. m_fIsQuorumCapable = TRUE;
  1711. m_fIsQuorumResourceMultiNodeCapable = TRUE;
  1712. m_fIsManagedByDefault = TRUE;
  1713. break;
  1714. } // if:
  1715. piccpp->Release();
  1716. piccpp = NULL;
  1717. } // for:
  1718. Cleanup:
  1719. LOG_STATUS_REPORT_STRING2(
  1720. L"Physical disk '%1!ws!' %2!ws! quorum capable."
  1721. , ( ( m_bstrFriendlyName != NULL ) ? m_bstrFriendlyName : m_bstrName )
  1722. , ( ( m_fIsQuorumCapable == TRUE ) ? L"is" : L"is NOT" )
  1723. , hr
  1724. );
  1725. if ( FAILED( hr ) )
  1726. {
  1727. LOG_STATUS_REPORT( L"CPhysicalDisk::CanBeManaged failed.", hr );
  1728. } // if:
  1729. if ( piccpp != NULL )
  1730. {
  1731. piccpp->Release();
  1732. } // if:
  1733. HRETURN( hr );
  1734. } //*** CPhysicalDisk::CanBeManaged
  1735. //////////////////////////////////////////////////////////////////////////////
  1736. //++
  1737. //
  1738. // CPhysicalDisk::HrIsDynamicDisk
  1739. //
  1740. // Description:
  1741. // Is this disk a "dynamic" disk? Dynamic disks are those disks that
  1742. // contain LDM partitions.
  1743. //
  1744. // Arguments:
  1745. // None.
  1746. //
  1747. // Return Value:
  1748. // S_OK
  1749. // This is a dynamic disk.
  1750. //
  1751. // S_FALSE
  1752. // This is not a dynamic disk.
  1753. //
  1754. //--
  1755. //////////////////////////////////////////////////////////////////////////////
  1756. STDMETHODIMP
  1757. CPhysicalDisk::HrIsDynamicDisk( void )
  1758. {
  1759. TraceFunc( "" );
  1760. HRESULT hr = S_OK;
  1761. if ( m_fIsDynamicDisk == FALSE )
  1762. {
  1763. hr = S_FALSE;
  1764. } // if:
  1765. HRETURN( hr );
  1766. } //*** CPhysicalDisk::HrIsDynamicDisk
  1767. //////////////////////////////////////////////////////////////////////////////
  1768. //++
  1769. //
  1770. // CPhysicalDisk::HrIsGPTDisk
  1771. //
  1772. // Description:
  1773. // Is this disk a "GPT" disk? GPT disks are those disks that
  1774. // contain GPT partitions.
  1775. //
  1776. // Arguments:
  1777. // None.
  1778. //
  1779. // Return Value:
  1780. // S_OK
  1781. // This is a GPT disk.
  1782. //
  1783. // S_FALSE
  1784. // This is not a GPT disk.
  1785. //
  1786. //--
  1787. //////////////////////////////////////////////////////////////////////////////
  1788. STDMETHODIMP
  1789. CPhysicalDisk::HrIsGPTDisk( void )
  1790. {
  1791. TraceFunc( "" );
  1792. HRESULT hr = S_OK;
  1793. if ( m_fIsGPTDisk == FALSE )
  1794. {
  1795. hr = S_FALSE;
  1796. } // if:
  1797. HRETURN( hr );
  1798. } //*** CPhysicalDisk::HrIsGPTDisk
  1799. //////////////////////////////////////////////////////////////////////////////
  1800. //++
  1801. //
  1802. // CPhysicalDisk::HrGetDiskNames
  1803. //
  1804. // Description:
  1805. // Get the names of this disk, both its friendly and device names.
  1806. //
  1807. // Arguments:
  1808. // pbstrDiskNameOut
  1809. //
  1810. // pbstrDeviceNameOut
  1811. //
  1812. // Return Value:
  1813. // S_OK
  1814. // Success;
  1815. //
  1816. // E_OUTOFMEMORY
  1817. //
  1818. // E_POINTER
  1819. //
  1820. //--
  1821. //////////////////////////////////////////////////////////////////////////////
  1822. STDMETHODIMP
  1823. CPhysicalDisk::HrGetDiskNames(
  1824. BSTR * pbstrDiskNameOut
  1825. , BSTR * pbstrDeviceNameOut
  1826. )
  1827. {
  1828. TraceFunc( "" );
  1829. Assert( m_bstrName != NULL );
  1830. Assert( m_bstrFriendlyName != NULL );
  1831. Assert( pbstrDiskNameOut != NULL );
  1832. Assert( pbstrDeviceNameOut != NULL );
  1833. HRESULT hr = S_OK;
  1834. BSTR bstr = NULL;
  1835. if ( ( pbstrDiskNameOut == NULL ) || ( pbstrDeviceNameOut == NULL ) )
  1836. {
  1837. hr = THR( E_POINTER );
  1838. goto Cleanup;
  1839. } // if:
  1840. bstr = TraceSysAllocString( m_bstrFriendlyName );
  1841. if ( bstr == NULL )
  1842. {
  1843. hr = THR( E_OUTOFMEMORY );
  1844. goto Cleanup;
  1845. } // if:
  1846. *pbstrDiskNameOut = bstr;
  1847. bstr = NULL;
  1848. bstr = TraceSysAllocString( m_bstrName );
  1849. if ( bstr == NULL )
  1850. {
  1851. hr = THR( E_OUTOFMEMORY );
  1852. goto Cleanup;
  1853. } // if:
  1854. *pbstrDeviceNameOut = bstr;
  1855. bstr = NULL;
  1856. Cleanup:
  1857. TraceSysFreeString( bstr );
  1858. HRETURN( hr );
  1859. } //*** CPhysicalDisk::HrGetDiskNames
  1860. //*************************************************************************//
  1861. /////////////////////////////////////////////////////////////////////////////
  1862. // CPhysicalDisk class -- IClusCfgManagedResourceCfg
  1863. /////////////////////////////////////////////////////////////////////////////
  1864. //////////////////////////////////////////////////////////////////////////////
  1865. //++
  1866. //
  1867. // CPhysicalDisk::PreCreate
  1868. //
  1869. // Description:
  1870. //
  1871. // Arguments:
  1872. //
  1873. // Return Value:
  1874. // S_OK
  1875. // Success
  1876. //
  1877. // Win32 error as HRESULT when an error occurs.
  1878. //
  1879. // Remarks:
  1880. // None.
  1881. //
  1882. //--
  1883. //////////////////////////////////////////////////////////////////////////////
  1884. STDMETHODIMP
  1885. CPhysicalDisk::PreCreate( IUnknown * punkServicesIn )
  1886. {
  1887. TraceFunc( "[IClusCfgManagedResourceCfg]" );
  1888. HRESULT hr = S_OK;
  1889. IClusCfgResourcePreCreate * pccrpc = NULL;
  1890. BSTR bstr = m_bstrFriendlyName != NULL ? m_bstrFriendlyName : m_bstrName;
  1891. hr = THR( punkServicesIn->TypeSafeQI( IClusCfgResourcePreCreate, &pccrpc ) );
  1892. if ( FAILED( hr ) )
  1893. {
  1894. goto Cleanup;
  1895. } // if:
  1896. hr = THR( pccrpc->SetType( (LPCLSID) &RESTYPE_PhysicalDisk ) );
  1897. if ( FAILED( hr ) )
  1898. {
  1899. goto Cleanup;
  1900. } // if:
  1901. hr = THR( pccrpc->SetClassType( (LPCLSID) &RESCLASSTYPE_StorageDevice ) );
  1902. if ( FAILED( hr ) )
  1903. {
  1904. goto Cleanup;
  1905. } // if:
  1906. #if 0 // test code only
  1907. hr = THR( pccrpc->SetDependency( (LPCLSID) &IID_NULL, dfSHARED ) );
  1908. if ( FAILED( hr ) )
  1909. {
  1910. goto Cleanup;
  1911. } // if:
  1912. #endif // test code only
  1913. Cleanup:
  1914. STATUS_REPORT_STRING( TASKID_Major_Configure_Resources, TASKID_Minor_PhysDisk_PreCreate, IDS_INFO_PHYSDISK_PRECREATE, bstr, hr );
  1915. if ( pccrpc != NULL )
  1916. {
  1917. pccrpc->Release();
  1918. } // if:
  1919. HRETURN( hr );
  1920. } //*** CPhysicalDisk::PreCreate
  1921. //////////////////////////////////////////////////////////////////////////////
  1922. //++
  1923. //
  1924. // CPhysicalDisk::Create
  1925. //
  1926. // Description:
  1927. //
  1928. // Arguments:
  1929. //
  1930. // Return Value:
  1931. // S_OK
  1932. // Success
  1933. //
  1934. // Win32 error as HRESULT when an error occurs.
  1935. //
  1936. // Remarks:
  1937. // None.
  1938. //
  1939. //--
  1940. //////////////////////////////////////////////////////////////////////////////
  1941. STDMETHODIMP
  1942. CPhysicalDisk::Create( IUnknown * punkServicesIn )
  1943. {
  1944. TraceFunc( "[IClusCfgManagedResourceCfg]" );
  1945. HRESULT hr = S_OK;
  1946. IClusCfgResourceCreate * pccrc = NULL;
  1947. BSTR * pbstr = m_bstrFriendlyName != NULL ? &m_bstrFriendlyName : &m_bstrName;
  1948. hr = THR( punkServicesIn->TypeSafeQI( IClusCfgResourceCreate, &pccrc ) );
  1949. if ( FAILED( hr ) )
  1950. {
  1951. goto Cleanup;
  1952. } // if:
  1953. if ( m_dwSignature != 0 )
  1954. {
  1955. LOG_STATUS_REPORT_STRING2( L"Setting signature to \"%1!u!\" on resource \"%2!ws!\".", m_dwSignature, *pbstr, hr );
  1956. hr = THR( pccrc->SetPropertyDWORD( L"Signature", m_dwSignature ) );
  1957. if ( FAILED( hr ) )
  1958. {
  1959. goto Cleanup;
  1960. } // if:
  1961. } // if:
  1962. Cleanup:
  1963. STATUS_REPORT_STRING( TASKID_Major_Configure_Resources, TASKID_Minor_PhysDisk_Create, IDS_INFO_PHYSDISK_CREATE, *pbstr, hr );
  1964. if ( pccrc != NULL )
  1965. {
  1966. pccrc->Release();
  1967. } // if:
  1968. HRETURN( hr );
  1969. } //*** CPhysicalDisk::Create
  1970. //////////////////////////////////////////////////////////////////////////////
  1971. //++
  1972. //
  1973. // CPhysicalDisk::PostCreate
  1974. //
  1975. // Description:
  1976. //
  1977. // Arguments:
  1978. //
  1979. // Return Value:
  1980. // S_OK
  1981. // Success
  1982. //
  1983. // Win32 error as HRESULT when an error occurs.
  1984. //
  1985. // Remarks:
  1986. // None.
  1987. //
  1988. //--
  1989. //////////////////////////////////////////////////////////////////////////////
  1990. STDMETHODIMP
  1991. CPhysicalDisk::PostCreate( IUnknown * punkServicesIn )
  1992. {
  1993. TraceFunc( "[IClusCfgManagedResourceCfg]" );
  1994. HRETURN( S_OK );
  1995. } //*** CPhysicalDisk::PostCreate
  1996. //////////////////////////////////////////////////////////////////////////////
  1997. //++
  1998. //
  1999. // CPhysicalDisk::Evict
  2000. //
  2001. // Description:
  2002. //
  2003. // Arguments:
  2004. //
  2005. // Return Value:
  2006. // S_OK
  2007. // Success
  2008. //
  2009. // Win32 error as HRESULT when an error occurs.
  2010. //
  2011. // Remarks:
  2012. // None.
  2013. //
  2014. //--
  2015. //////////////////////////////////////////////////////////////////////////////
  2016. STDMETHODIMP
  2017. CPhysicalDisk::Evict( IUnknown * punkServicesIn )
  2018. {
  2019. TraceFunc( "[IClusCfgManagedResourceCfg]" );
  2020. HRETURN( S_OK );
  2021. } //*** CPhysicalDisk::Evict
  2022. //*************************************************************************//
  2023. /////////////////////////////////////////////////////////////////////////////
  2024. // CPhysicalDisk class -- Private Methods.
  2025. /////////////////////////////////////////////////////////////////////////////
  2026. //////////////////////////////////////////////////////////////////////////////
  2027. //++
  2028. //
  2029. // CPhysicalDisk::HrInit
  2030. //
  2031. // Description:
  2032. // Initialize this component.
  2033. //
  2034. // Arguments:
  2035. // None.
  2036. //
  2037. // Return Value:
  2038. //
  2039. //
  2040. // Remarks:
  2041. // None.
  2042. //
  2043. //--
  2044. //////////////////////////////////////////////////////////////////////////////
  2045. HRESULT
  2046. CPhysicalDisk::HrInit( void )
  2047. {
  2048. TraceFunc( "" );
  2049. HRESULT hr = S_OK;
  2050. // IUnknown
  2051. Assert( m_cRef == 1 );
  2052. HRETURN( hr );
  2053. } //*** CPhysicalDisk::HrInit
  2054. //////////////////////////////////////////////////////////////////////////////
  2055. //++
  2056. //
  2057. // CPhysicalDisk::HrGetPartitionInfo
  2058. //
  2059. // Description:
  2060. // Gather the partition information.
  2061. //
  2062. // Arguments:
  2063. // None.
  2064. //
  2065. // Return Value:
  2066. //
  2067. //
  2068. // Remarks:
  2069. // None.
  2070. //
  2071. //--
  2072. //////////////////////////////////////////////////////////////////////////////
  2073. HRESULT
  2074. CPhysicalDisk::HrGetPartitionInfo(
  2075. IWbemClassObject * pDiskIn
  2076. , bool * pfRetainObjectOut
  2077. )
  2078. {
  2079. TraceFunc( "" );
  2080. Assert( pDiskIn != NULL );
  2081. Assert( pfRetainObjectOut != NULL );
  2082. HRESULT hr;
  2083. VARIANT var;
  2084. VARIANT varDiskName;
  2085. WCHAR szBuf[ 256 ];
  2086. IEnumWbemClassObject * pPartitions = NULL;
  2087. IWbemClassObject * pPartition = NULL;
  2088. ULONG ulReturned;
  2089. BSTR bstrQuery = NULL;
  2090. BSTR bstrWQL = NULL;
  2091. DWORD cPartitions;
  2092. bstrWQL = TraceSysAllocString( L"WQL" );
  2093. if ( bstrWQL == NULL )
  2094. {
  2095. hr = THR( E_OUTOFMEMORY );
  2096. STATUS_REPORT( TASKID_Major_Find_Devices, TASKID_Minor_HrGetPartitionInfo, IDS_ERROR_OUTOFMEMORY, hr );
  2097. goto Cleanup;
  2098. } // if:
  2099. VariantInit( &var );
  2100. VariantInit( &varDiskName );
  2101. //
  2102. // Need to enum the partition(s) of this disk to determine if it is booted
  2103. // bootable.
  2104. //
  2105. hr = THR( HrGetWMIProperty( pDiskIn, L"DeviceID", VT_BSTR, &var ) );
  2106. if ( FAILED( hr ) )
  2107. {
  2108. goto Cleanup;
  2109. } // if:
  2110. hr = THR( StringCchPrintfW(
  2111. szBuf
  2112. , ARRAYSIZE( szBuf )
  2113. , L"Associators of {Win32_DiskDrive.DeviceID='%ws'} where AssocClass=Win32_DiskDriveToDiskPartition"
  2114. , var.bstrVal
  2115. ) );
  2116. if ( FAILED( hr ) )
  2117. {
  2118. goto Cleanup;
  2119. } // if:
  2120. bstrQuery = TraceSysAllocString( szBuf );
  2121. if ( bstrQuery == NULL )
  2122. {
  2123. hr = THR( E_OUTOFMEMORY );
  2124. STATUS_REPORT( TASKID_Major_Find_Devices, TASKID_Minor_HrGetPartitionInfo, IDS_ERROR_OUTOFMEMORY, hr );
  2125. goto Cleanup;
  2126. } // if:
  2127. hr = THR( m_pIWbemServices->ExecQuery( bstrWQL, bstrQuery, WBEM_FLAG_FORWARD_ONLY, NULL, &pPartitions ) );
  2128. if ( FAILED( hr ) )
  2129. {
  2130. STATUS_REPORT_STRING_REF(
  2131. TASKID_Major_Find_Devices
  2132. , TASKID_Minor_WMI_DiskDrivePartitions_Qry_Failed
  2133. , IDS_ERROR_WMI_DISKDRIVEPARTITIONS_QRY_FAILED
  2134. , var.bstrVal
  2135. , IDS_ERROR_WMI_DISKDRIVEPARTITIONS_QRY_FAILED_REF
  2136. , hr
  2137. );
  2138. goto Cleanup;
  2139. } // if:
  2140. for ( cPartitions = 0; ; cPartitions++ )
  2141. {
  2142. hr = STHR( pPartitions->Next( WBEM_INFINITE, 1, &pPartition, &ulReturned ) );
  2143. if ( ( hr == S_OK ) && ( ulReturned == 1 ) )
  2144. {
  2145. hr = STHR( HrIsPartitionLDM( pPartition ) );
  2146. if ( FAILED( hr ) )
  2147. {
  2148. goto Cleanup;
  2149. } // if:
  2150. //
  2151. // If the partition is logical disk manager (LDM) then we cannot accept this disk therefore cannot manage it.
  2152. //
  2153. if ( hr == S_OK )
  2154. {
  2155. m_fIsDynamicDisk = TRUE;
  2156. } // if:
  2157. hr = STHR( HrIsPartitionGPT( pPartition ) );
  2158. if ( FAILED( hr ) )
  2159. {
  2160. goto Cleanup;
  2161. } // if:
  2162. if ( hr == S_OK )
  2163. {
  2164. m_fIsGPTDisk = TRUE;
  2165. } // if:
  2166. hr = THR( HrCreatePartitionInfo( pPartition ) );
  2167. if ( FAILED( hr ) )
  2168. {
  2169. goto Cleanup;
  2170. } // if:
  2171. pPartition->Release();
  2172. pPartition = NULL;
  2173. } // if:
  2174. else if ( ( hr == S_FALSE ) && ( ulReturned == 0 ) )
  2175. {
  2176. break;
  2177. } // else if:
  2178. else
  2179. {
  2180. STATUS_REPORT_STRING_REF(
  2181. TASKID_Major_Find_Devices
  2182. , TASKID_Minor_WQL_Partition_Qry_Next_Failed
  2183. , IDS_ERROR_WQL_QRY_NEXT_FAILED
  2184. , bstrQuery
  2185. , IDS_ERROR_WQL_QRY_NEXT_FAILED_REF
  2186. , hr
  2187. );
  2188. goto Cleanup;
  2189. } // else:
  2190. } // for:
  2191. //
  2192. // The enumerator can be empty because we cannot read the partition info from
  2193. // clustered disks. If the enumerator was empty retain the S_FALSE, otherwise
  2194. // return S_OK if count is greater than 0.
  2195. //
  2196. if ( cPartitions > 0 )
  2197. {
  2198. hr = S_OK;
  2199. } // if:
  2200. else
  2201. {
  2202. LOG_STATUS_REPORT_STRING( L"The physical disk '%1!ws!' does not have any partitions and will not be managed", var.bstrVal, hr );
  2203. m_fIsManagedByDefault = FALSE;
  2204. } // else:
  2205. Cleanup:
  2206. VariantClear( &var );
  2207. VariantClear( &varDiskName );
  2208. TraceSysFreeString( bstrQuery );
  2209. TraceSysFreeString( bstrWQL );
  2210. if ( pPartition != NULL )
  2211. {
  2212. pPartition->Release();
  2213. } // if:
  2214. if ( pPartitions != NULL )
  2215. {
  2216. pPartitions->Release();
  2217. } // if:
  2218. HRETURN( hr );
  2219. } //*** CPhysicalDisk::HrGetPartitionInfo
  2220. /////////////////////////////////////////////////////////////////////////////
  2221. //++
  2222. //
  2223. // CPhysicalDisk:HrAddPartitionToArray
  2224. //
  2225. // Description:
  2226. // Add the passed in partition to the array of punks that holds the
  2227. // partitions.
  2228. //
  2229. // Arguments:
  2230. //
  2231. //
  2232. // Return Value:
  2233. // S_OK
  2234. // Success
  2235. //
  2236. // E_OUTOFMEMORY
  2237. // Couldn't allocate memeory.
  2238. //
  2239. // Remarks:
  2240. // None.
  2241. //
  2242. //--
  2243. //////////////////////////////////////////////////////////////////////////////
  2244. HRESULT
  2245. CPhysicalDisk::HrAddPartitionToArray( IUnknown * punkIn )
  2246. {
  2247. TraceFunc( "" );
  2248. HRESULT hr = S_OK;
  2249. IUnknown * ((*prgpunks)[]) = NULL;
  2250. prgpunks = (IUnknown *((*)[])) TraceReAlloc( m_prgPartitions, sizeof( IUnknown * ) * ( m_idxNextPartition + 1 ), HEAP_ZERO_MEMORY );
  2251. if ( prgpunks == NULL )
  2252. {
  2253. hr = THR( E_OUTOFMEMORY );
  2254. STATUS_REPORT( TASKID_Major_Find_Devices, TASKID_Minor_HrAddPartitionToArray, IDS_ERROR_OUTOFMEMORY, hr );
  2255. goto Cleanup;
  2256. } // if:
  2257. m_prgPartitions = prgpunks;
  2258. (*m_prgPartitions)[ m_idxNextPartition++ ] = punkIn;
  2259. punkIn->AddRef();
  2260. m_cPartitions += 1;
  2261. Cleanup:
  2262. HRETURN( hr );
  2263. } //*** CPhysicalDisk::HrAddPartitionToArray
  2264. /////////////////////////////////////////////////////////////////////////////
  2265. //++
  2266. //
  2267. // CPhysicalDisk:HrCreatePartitionInfo
  2268. //
  2269. // Description:
  2270. // Create a partition info from the passes in WMI partition.
  2271. //
  2272. // Arguments:
  2273. //
  2274. //
  2275. // Return Value:
  2276. // S_OK
  2277. // Success
  2278. //
  2279. // S_FALSE
  2280. // The file system was not NTFS.
  2281. //
  2282. // E_OUTOFMEMORY
  2283. // Couldn't allocate memeory.
  2284. //
  2285. // Remarks:
  2286. // None.
  2287. //
  2288. //--
  2289. //////////////////////////////////////////////////////////////////////////////
  2290. HRESULT
  2291. CPhysicalDisk::HrCreatePartitionInfo( IWbemClassObject * pPartitionIn )
  2292. {
  2293. TraceFunc( "" );
  2294. Assert( m_bstrDeviceID != NULL );
  2295. HRESULT hr = S_OK;
  2296. IUnknown * punk = NULL;
  2297. IClusCfgSetWbemObject * piccswo = NULL;
  2298. bool fRetainObject = true;
  2299. hr = THR( CClusCfgPartitionInfo::S_HrCreateInstance( &punk, m_bstrDeviceID ) );
  2300. if ( FAILED( hr ) )
  2301. {
  2302. goto Cleanup;
  2303. } // if:
  2304. punk = TraceInterface( L"CClusCfgPartitionInfo", IUnknown, punk, 1 );
  2305. hr = THR( HrSetInitialize( punk, m_picccCallback, m_lcid ) );
  2306. if ( FAILED( hr ) )
  2307. {
  2308. goto Cleanup;
  2309. } // if:
  2310. hr = THR( HrSetWbemServices( punk, m_pIWbemServices ) );
  2311. if ( FAILED( hr ) )
  2312. {
  2313. goto Cleanup;
  2314. } // if:
  2315. hr = THR( punk->TypeSafeQI( IClusCfgSetWbemObject, &piccswo ) );
  2316. if ( FAILED( hr ) )
  2317. {
  2318. goto Cleanup;
  2319. } // if:
  2320. hr = THR( piccswo->SetWbemObject( pPartitionIn, &fRetainObject ) );
  2321. if ( FAILED( hr ) )
  2322. {
  2323. goto Cleanup;
  2324. } // if:
  2325. if ( fRetainObject )
  2326. {
  2327. hr = THR( HrAddPartitionToArray( punk ) );
  2328. } // if:
  2329. Cleanup:
  2330. if ( piccswo != NULL )
  2331. {
  2332. piccswo->Release();
  2333. } // if:
  2334. if ( punk != NULL )
  2335. {
  2336. punk->Release();
  2337. } // if:
  2338. HRETURN( hr );
  2339. } //*** CPhysicalDisk::HrCreatePartitionInfo
  2340. /////////////////////////////////////////////////////////////////////////////
  2341. //++
  2342. //
  2343. // CPhysicalDisk:HrCreateFriendlyName
  2344. //
  2345. // Description:
  2346. // Create a cluster friendly name.
  2347. //
  2348. // Arguments:
  2349. //
  2350. //
  2351. // Return Value:
  2352. // S_OK
  2353. // Success
  2354. //
  2355. // S_FALSE
  2356. // Success, but a friendly name could not be created.
  2357. //
  2358. // E_OUTOFMEMORY
  2359. // Couldn't allocate memeory.
  2360. //
  2361. // Remarks:
  2362. // None.
  2363. //
  2364. //--
  2365. //////////////////////////////////////////////////////////////////////////////
  2366. HRESULT
  2367. CPhysicalDisk::HrCreateFriendlyName( void )
  2368. {
  2369. TraceFunc( "" );
  2370. HRESULT hr = S_FALSE;
  2371. WCHAR * psz = NULL;
  2372. WCHAR * pszTmp = NULL;
  2373. DWORD cch;
  2374. DWORD idx;
  2375. IClusCfgPartitionProperties * piccpp = NULL;
  2376. BSTR bstrName = NULL;
  2377. bool fFoundLogicalDisk = false;
  2378. BSTR bstr = NULL;
  2379. BSTR bstrDisk = NULL;
  2380. if ( m_idxNextPartition == 0 )
  2381. {
  2382. goto Cleanup;
  2383. } // if:
  2384. hr = THR( HrLoadStringIntoBSTR( g_hInstance, IDS_DISK, &bstrDisk ) );
  2385. if ( FAILED( hr ) )
  2386. {
  2387. goto Cleanup;
  2388. } // if:
  2389. cch = (UINT) wcslen( bstrDisk ) + 1;
  2390. psz = new WCHAR[ cch ];
  2391. if ( psz == NULL )
  2392. {
  2393. goto OutOfMemory;
  2394. } // if:
  2395. hr = THR( StringCchCopyW( psz, cch, bstrDisk ) );
  2396. if ( FAILED( hr ) )
  2397. {
  2398. goto Cleanup;
  2399. } // if:
  2400. for ( idx = 0; idx < m_idxNextPartition; idx++ )
  2401. {
  2402. hr = THR( ((*m_prgPartitions)[ idx ])->TypeSafeQI( IClusCfgPartitionProperties, &piccpp ) );
  2403. if ( FAILED( hr ) )
  2404. {
  2405. goto Cleanup;
  2406. } // if:
  2407. hr = STHR( piccpp->GetFriendlyName( &bstrName ) );
  2408. if ( FAILED( hr ) )
  2409. {
  2410. goto Cleanup;
  2411. } // if:
  2412. if ( hr == S_FALSE )
  2413. {
  2414. continue;
  2415. } // if:
  2416. fFoundLogicalDisk = true;
  2417. cch += (UINT) wcslen( bstrName ) + 1;
  2418. pszTmp = new WCHAR[ cch ];
  2419. if ( pszTmp == NULL )
  2420. {
  2421. goto OutOfMemory;
  2422. } // if:
  2423. hr = THR( StringCchCopyW( pszTmp, cch, psz ) );
  2424. if ( FAILED( hr ) )
  2425. {
  2426. goto Cleanup;
  2427. } // if:
  2428. delete [] psz;
  2429. psz = pszTmp;
  2430. pszTmp = NULL;
  2431. hr = THR( StringCchCatW( psz, cch, bstrName ) );
  2432. if ( FAILED( hr ) )
  2433. {
  2434. goto Cleanup;
  2435. } // if:
  2436. TraceSysFreeString( bstrName );
  2437. bstrName = NULL;
  2438. piccpp->Release();
  2439. piccpp = NULL;
  2440. } // for:
  2441. //
  2442. // KB: 31-JUL-2000
  2443. //
  2444. // If we didn't find any logical disk IDs then we don't want
  2445. // to touch m_bstrFriendlyName.
  2446. //
  2447. if ( !fFoundLogicalDisk )
  2448. {
  2449. hr = S_OK; // ensure that that the caller doesn't fail since this is not a fatal error...
  2450. goto Cleanup;
  2451. } // if:
  2452. bstr = TraceSysAllocString( psz );
  2453. if ( bstr == NULL )
  2454. {
  2455. goto OutOfMemory;
  2456. } // if:
  2457. TraceSysFreeString( m_bstrFriendlyName );
  2458. m_bstrFriendlyName = bstr;
  2459. bstr = NULL;
  2460. goto Cleanup;
  2461. OutOfMemory:
  2462. hr = THR( E_OUTOFMEMORY );
  2463. STATUS_REPORT( TASKID_Major_Find_Devices, TASKID_Minor_HrCreateFriendlyName_VOID, IDS_ERROR_OUTOFMEMORY, hr );
  2464. Cleanup:
  2465. if ( piccpp != NULL )
  2466. {
  2467. piccpp->Release();
  2468. } // if:
  2469. delete [] psz;
  2470. delete [] pszTmp;
  2471. TraceSysFreeString( bstrName );
  2472. TraceSysFreeString( bstrDisk );
  2473. TraceSysFreeString( bstr );
  2474. HRETURN( hr );
  2475. } //*** CPhysicalDisk::HrCreateFriendlyName
  2476. /////////////////////////////////////////////////////////////////////////////
  2477. //++
  2478. //
  2479. // CPhysicalDisk:HrCreateFriendlyName
  2480. //
  2481. // Description:
  2482. // Convert the WMI disk name into a more freindly version.
  2483. // Create a cluster friendly name.
  2484. //
  2485. // Arguments:
  2486. //
  2487. //
  2488. // Return Value:
  2489. // S_OK
  2490. // Success
  2491. //
  2492. // E_OUTOFMEMORY
  2493. // Couldn't allocate memeory.
  2494. //
  2495. // Remarks:
  2496. // None.
  2497. //
  2498. //--
  2499. //////////////////////////////////////////////////////////////////////////////
  2500. HRESULT
  2501. CPhysicalDisk::HrCreateFriendlyName( BSTR bstrNameIn )
  2502. {
  2503. TraceFunc1( "bstrNameIn = '%ws'", bstrNameIn == NULL ? L"<null>" : bstrNameIn );
  2504. HRESULT hr = S_OK;
  2505. WCHAR * psz = NULL;
  2506. BSTR bstr = NULL;
  2507. //
  2508. // KB: 27-JUN-2000 GalenB
  2509. //
  2510. // Disk names in WMI start with "\\.\". As a better and easy
  2511. // friendly name I am just going to trim these leading chars
  2512. // off.
  2513. //
  2514. psz = bstrNameIn + wcslen( L"\\\\.\\" );
  2515. bstr = TraceSysAllocString( psz );
  2516. if ( bstr == NULL )
  2517. {
  2518. hr = THR( E_OUTOFMEMORY );
  2519. STATUS_REPORT( TASKID_Major_Find_Devices, TASKID_Minor_HrCreateFriendlyName_BSTR, IDS_ERROR_OUTOFMEMORY, hr );
  2520. goto Cleanup;
  2521. } // if:
  2522. TraceSysFreeString( m_bstrName );
  2523. m_bstrName = bstr;
  2524. Cleanup:
  2525. HRETURN( hr );
  2526. } //*** CPhysicalDisk::HrCreateFriendlyName
  2527. /////////////////////////////////////////////////////////////////////////////
  2528. //++
  2529. //
  2530. // CPhysicalDisk:HrIsPartitionGPT
  2531. //
  2532. // Description:
  2533. // Is the passed in partition a GPT partition.
  2534. //
  2535. // Arguments:
  2536. //
  2537. //
  2538. // Return Value:
  2539. // S_OK
  2540. // The partition is a GPT partition.
  2541. //
  2542. // S_FALSE
  2543. // The partition is not GPT.
  2544. //
  2545. // E_OUTOFMEMORY
  2546. // Couldn't allocate memeory.
  2547. //
  2548. // Remarks:
  2549. // If the type property of a Win32_DiskPartition starts with "GPT"
  2550. // then the whole spindle has GPT partitions.
  2551. //
  2552. //--
  2553. //////////////////////////////////////////////////////////////////////////////
  2554. HRESULT
  2555. CPhysicalDisk::HrIsPartitionGPT( IWbemClassObject * pPartitionIn )
  2556. {
  2557. TraceFunc( "" );
  2558. HRESULT hr = S_OK;
  2559. VARIANT var;
  2560. WCHAR szData[ 4 ];
  2561. BSTR bstrGPT = NULL;
  2562. VariantInit( &var );
  2563. hr = THR( HrLoadStringIntoBSTR( g_hInstance, IDS_GPT, &bstrGPT ) );
  2564. if ( FAILED( hr ) )
  2565. {
  2566. goto Cleanup;
  2567. } // if:
  2568. hr = THR( HrGetWMIProperty( pPartitionIn, L"Type", VT_BSTR, &var ) );
  2569. if ( FAILED( hr ) )
  2570. {
  2571. goto Cleanup;
  2572. } // if:
  2573. //
  2574. // Get the fist three characters. When the spindle has GPT partitions then
  2575. // these characters will be "GPT". I am unsure if this will be localized?
  2576. //
  2577. hr = THR( StringCchCopyNW( szData, ARRAYSIZE( szData ), var.bstrVal, 3 ) );
  2578. if ( FAILED( hr ) )
  2579. {
  2580. goto Cleanup;
  2581. } // if:
  2582. CharUpper( szData );
  2583. if ( NStringCchCompareCase( szData, ARRAYSIZE( szData ), bstrGPT, SysStringLen( bstrGPT ) + 1 ) != 0 )
  2584. {
  2585. hr = S_FALSE;
  2586. } // if:
  2587. Cleanup:
  2588. VariantClear( &var );
  2589. TraceSysFreeString( bstrGPT );
  2590. HRETURN( hr );
  2591. } //*** CPhysicalDisk::HrIsPartitionGPT
  2592. /////////////////////////////////////////////////////////////////////////////
  2593. //++
  2594. //
  2595. // CPhysicalDisk:HrIsPartitionLDM
  2596. //
  2597. // Description:
  2598. // Is the passed in partition an LDM partition.
  2599. //
  2600. // Arguments:
  2601. //
  2602. //
  2603. // Return Value:
  2604. // S_OK
  2605. // The partition is an LDM partition.
  2606. //
  2607. // S_FALSE
  2608. // The partition is not LDM.
  2609. //
  2610. // E_OUTOFMEMORY
  2611. // Couldn't allocate memeory.
  2612. //
  2613. // Remarks:
  2614. // If the type property of a Win32_DiskPartition is "logical disk
  2615. // manager" then this disk is an LDM disk.
  2616. //
  2617. //--
  2618. //////////////////////////////////////////////////////////////////////////////
  2619. HRESULT
  2620. CPhysicalDisk::HrIsPartitionLDM( IWbemClassObject * pPartitionIn )
  2621. {
  2622. TraceFunc( "" );
  2623. HRESULT hr = S_OK;
  2624. VARIANT var;
  2625. BSTR bstrLDM = NULL;
  2626. VariantInit( &var );
  2627. hr = THR( HrLoadStringIntoBSTR( g_hInstance, IDS_LDM, &bstrLDM ) );
  2628. if ( FAILED( hr ) )
  2629. {
  2630. goto Cleanup;
  2631. } // if:
  2632. hr = THR( HrGetWMIProperty( pPartitionIn, L"Type", VT_BSTR, &var ) );
  2633. if ( FAILED( hr ) )
  2634. {
  2635. goto Cleanup;
  2636. } // if:
  2637. CharUpper( var.bstrVal );
  2638. if ( NBSTRCompareCase( var.bstrVal, bstrLDM ) != 0 )
  2639. {
  2640. hr = S_FALSE;
  2641. } // if:
  2642. Cleanup:
  2643. VariantClear( &var );
  2644. TraceSysFreeString( bstrLDM );
  2645. HRETURN( hr );
  2646. } //*** CPhysicalDisk::HrIsPartitionLDM
  2647. /*
  2648. /////////////////////////////////////////////////////////////////////////////
  2649. //++
  2650. //
  2651. // CPhysicalDisk:HrGetDiskFirmwareSerialNumber
  2652. //
  2653. // Description:
  2654. // Get the disk firmware serial number.
  2655. //
  2656. // Arguments:
  2657. // None.
  2658. //
  2659. // Return Value:
  2660. // S_OK
  2661. // Success.
  2662. //
  2663. // S_FALSE
  2664. // There wasn't a firmware serial number.
  2665. //
  2666. // E_OUTOFMEMORY
  2667. // Couldn't allocate memeory.
  2668. //
  2669. // Remarks:
  2670. //
  2671. //--
  2672. //////////////////////////////////////////////////////////////////////////////
  2673. HRESULT
  2674. CPhysicalDisk::HrGetDiskFirmwareSerialNumber( void )
  2675. {
  2676. TraceFunc( "" );
  2677. HRESULT hr = S_OK;
  2678. HANDLE hVolume = NULL;
  2679. DWORD dwSize;
  2680. DWORD sc;
  2681. STORAGE_PROPERTY_QUERY spq;
  2682. BOOL fRet;
  2683. PSTORAGE_DEVICE_DESCRIPTOR pddBuffer = NULL;
  2684. DWORD cbBuffer;
  2685. PCHAR psz = NULL;
  2686. //
  2687. // get handle to disk
  2688. //
  2689. hVolume = CreateFileW(
  2690. m_bstrDeviceID
  2691. , GENERIC_READ
  2692. , FILE_SHARE_READ
  2693. , NULL
  2694. , OPEN_EXISTING
  2695. , FILE_ATTRIBUTE_NORMAL
  2696. , NULL
  2697. );
  2698. if ( hVolume == INVALID_HANDLE_VALUE )
  2699. {
  2700. sc = TW32( GetLastError() );
  2701. hr = HRESULT_FROM_WIN32( sc );
  2702. goto Cleanup;
  2703. } // if:
  2704. cbBuffer = sizeof( STORAGE_DEVICE_DESCRIPTOR ) + 2048;
  2705. pddBuffer = ( PSTORAGE_DEVICE_DESCRIPTOR ) TraceAlloc( 0, cbBuffer );
  2706. if ( pddBuffer == NULL )
  2707. {
  2708. goto OutOfMemory;
  2709. } // if:
  2710. ZeroMemory( pddBuffer, cbBuffer );
  2711. ZeroMemory( &spq, sizeof( spq ) );
  2712. spq.PropertyId = StorageDeviceProperty;
  2713. spq.QueryType = PropertyStandardQuery;
  2714. //
  2715. // issue storage class ioctl to get the disk's firmware serial number.
  2716. //
  2717. fRet = DeviceIoControl(
  2718. hVolume
  2719. , IOCTL_STORAGE_QUERY_PROPERTY
  2720. , &spq
  2721. , sizeof( spq )
  2722. , pddBuffer
  2723. , cbBuffer
  2724. , &dwSize
  2725. , NULL
  2726. );
  2727. if ( !fRet )
  2728. {
  2729. sc = TW32( GetLastError() );
  2730. hr = HRESULT_FROM_WIN32( sc );
  2731. goto Cleanup;
  2732. } // if:
  2733. if ( dwSize > 0 )
  2734. {
  2735. //
  2736. // Ensure that there is a serial number offset and that it is within the buffer extents.
  2737. //
  2738. if ( ( pddBuffer->SerialNumberOffset == 0 ) || ( pddBuffer->SerialNumberOffset > pddBuffer->Size ) )
  2739. {
  2740. LOG_STATUS_REPORT_STRING( L"The disk '%1!ws!' does not have a firmware serial number.", m_bstrDeviceID, hr );
  2741. hr = S_FALSE;
  2742. goto Cleanup;
  2743. } // if:
  2744. //
  2745. // Serial number string is a zero terminated ASCII string.
  2746. //
  2747. // The header ntddstor.h says the for devices with no serial number,
  2748. // the offset will be zero. This doesn't seem to be TRUE.
  2749. //
  2750. // For devices with no serial number, it looks like a string with a single
  2751. // null character '\0' is returned.
  2752. //
  2753. psz = (PCHAR) pddBuffer + (DWORD) pddBuffer->SerialNumberOffset;
  2754. hr = THR( HrAnsiStringToBSTR( psz, &m_bstrFirmwareSerialNumber ) );
  2755. if ( FAILED( hr ) )
  2756. {
  2757. goto Cleanup;
  2758. } // if:
  2759. LOG_STATUS_REPORT_STRING3(
  2760. L"Disk '%1!ws!' has firmware serial number '%2!ws!' at offset '%3!#08x!'."
  2761. , m_bstrDeviceID
  2762. , m_bstrFirmwareSerialNumber
  2763. , pddBuffer->SerialNumberOffset
  2764. , hr
  2765. );
  2766. } // if:
  2767. goto Cleanup;
  2768. OutOfMemory:
  2769. hr = THR( E_OUTOFMEMORY );
  2770. LOG_STATUS_REPORT( L"HrGetDiskFirmwareSerialNumber() is out of memory.", hr );
  2771. Cleanup:
  2772. if ( hVolume != NULL )
  2773. {
  2774. CloseHandle( hVolume );
  2775. } // if:
  2776. TraceFree( pddBuffer );
  2777. HRETURN( hr );
  2778. } //*** CPhysicalDisk::HrGetDiskFirmwareSerialNumber
  2779. /////////////////////////////////////////////////////////////////////////////
  2780. //++
  2781. //
  2782. // CPhysicalDisk:HrGetDiskFirmwareVitalData
  2783. //
  2784. // Description:
  2785. // Get the disk firmware vital data.
  2786. //
  2787. // Arguments:
  2788. // None.
  2789. //
  2790. // Return Value:
  2791. // S_OK
  2792. // Success.
  2793. //
  2794. // S_FALSE
  2795. // There wasn't a firmware serial number.
  2796. //
  2797. // E_OUTOFMEMORY
  2798. // Couldn't allocate memeory.
  2799. //
  2800. // Remarks:
  2801. //
  2802. //--
  2803. //////////////////////////////////////////////////////////////////////////////
  2804. HRESULT
  2805. CPhysicalDisk::HrGetDiskFirmwareVitalData( void )
  2806. {
  2807. TraceFunc( "" );
  2808. HRESULT hr = S_OK;
  2809. HANDLE hVolume = NULL;
  2810. DWORD dwSize;
  2811. DWORD sc;
  2812. STORAGE_PROPERTY_QUERY spq;
  2813. BOOL fRet;
  2814. PSTORAGE_DEVICE_ID_DESCRIPTOR psdidBuffer = NULL;
  2815. DWORD cbBuffer;
  2816. //
  2817. // get handle to disk
  2818. //
  2819. hVolume = CreateFileW(
  2820. m_bstrDeviceID
  2821. , GENERIC_READ
  2822. , FILE_SHARE_READ
  2823. , NULL
  2824. , OPEN_EXISTING
  2825. , FILE_ATTRIBUTE_NORMAL
  2826. , NULL
  2827. );
  2828. if ( hVolume == INVALID_HANDLE_VALUE )
  2829. {
  2830. sc = TW32( GetLastError() );
  2831. hr = HRESULT_FROM_WIN32( sc );
  2832. goto Cleanup;
  2833. } // if:
  2834. cbBuffer = sizeof( STORAGE_DEVICE_ID_DESCRIPTOR ) + 2048;
  2835. psdidBuffer = (PSTORAGE_DEVICE_ID_DESCRIPTOR) TraceAlloc( 0, cbBuffer );
  2836. if ( psdidBuffer == NULL )
  2837. {
  2838. goto OutOfMemory;
  2839. } // if:
  2840. ZeroMemory( psdidBuffer, cbBuffer );
  2841. ZeroMemory( &spq, sizeof( spq ) );
  2842. spq.PropertyId = StorageDeviceIdProperty;
  2843. spq.QueryType = PropertyStandardQuery;
  2844. //
  2845. // issue storage class ioctl to get the disk's firmware vital data
  2846. //
  2847. fRet = DeviceIoControl(
  2848. hVolume
  2849. , IOCTL_STORAGE_QUERY_PROPERTY
  2850. , &spq
  2851. , sizeof( spq )
  2852. , psdidBuffer
  2853. , cbBuffer
  2854. , &dwSize
  2855. , NULL
  2856. );
  2857. if ( !fRet )
  2858. {
  2859. sc = TW32( GetLastError() );
  2860. hr = HRESULT_FROM_WIN32( sc );
  2861. goto Cleanup;
  2862. } // if:
  2863. if ( dwSize > 0 )
  2864. {
  2865. } // if:
  2866. goto Cleanup;
  2867. OutOfMemory:
  2868. hr = THR( E_OUTOFMEMORY );
  2869. LOG_STATUS_REPORT( L"HrGetDiskFirmwareVitalData() is out of memory.", hr );
  2870. Cleanup:
  2871. if ( hVolume != NULL )
  2872. {
  2873. CloseHandle( hVolume );
  2874. } // if:
  2875. TraceFree( psdidBuffer );
  2876. HRETURN( hr );
  2877. } //*** CPhysicalDisk::HrGetDiskFirmwareVitalData
  2878. */
  2879. /////////////////////////////////////////////////////////////////////////////
  2880. //++
  2881. //
  2882. // CPhysicalDisk:HrIsClusterCapable
  2883. //
  2884. // Description:
  2885. // Is this disk cluster capable?
  2886. //
  2887. // Arguments:
  2888. // None.
  2889. //
  2890. // Return Value:
  2891. // S_OK
  2892. // The disk is cluster capable.
  2893. //
  2894. // S_FALSE
  2895. // The disk is not cluster capable.
  2896. //
  2897. // E_OUTOFMEMORY
  2898. // Couldn't allocate memeory.
  2899. //
  2900. // Remarks:
  2901. //
  2902. //--
  2903. //////////////////////////////////////////////////////////////////////////////
  2904. HRESULT
  2905. CPhysicalDisk::HrIsClusterCapable( void )
  2906. {
  2907. TraceFunc( "" );
  2908. HRESULT hr = S_OK;
  2909. HANDLE hSCSIPort = INVALID_HANDLE_VALUE;
  2910. DWORD dwSize;
  2911. DWORD sc;
  2912. BOOL fRet;
  2913. WCHAR szSCSIPort[ 32 ];
  2914. SRB_IO_CONTROL srb;
  2915. hr = THR( StringCchPrintfW( szSCSIPort, ARRAYSIZE( szSCSIPort ), L"\\\\.\\Scsi%d:", m_ulSCSIPort ) );
  2916. if ( FAILED( hr ) )
  2917. {
  2918. goto Cleanup;
  2919. } // if:
  2920. //
  2921. // get handle to disk
  2922. //
  2923. hSCSIPort = CreateFileW(
  2924. szSCSIPort
  2925. , GENERIC_READ | GENERIC_WRITE
  2926. , FILE_SHARE_READ | FILE_SHARE_WRITE
  2927. , NULL
  2928. , OPEN_EXISTING
  2929. , FILE_ATTRIBUTE_NORMAL
  2930. , NULL
  2931. );
  2932. if ( hSCSIPort == INVALID_HANDLE_VALUE )
  2933. {
  2934. sc = TW32( GetLastError() );
  2935. hr = HRESULT_FROM_WIN32( sc );
  2936. LOG_STATUS_REPORT_STRING( L"Failed to open device %1!ws!.", szSCSIPort, hr );
  2937. goto Cleanup;
  2938. } // if:
  2939. #define CLUSDISK_SRB_SIGNATURE "CLUSDISK"
  2940. ZeroMemory( &srb, sizeof( srb ) );
  2941. srb.HeaderLength = sizeof( srb );
  2942. Assert( sizeof( srb.Signature ) <= sizeof( CLUSDISK_SRB_SIGNATURE ) );
  2943. CopyMemory( srb.Signature, CLUSDISK_SRB_SIGNATURE, sizeof( srb.Signature ) );
  2944. srb.ControlCode = IOCTL_SCSI_MINIPORT_NOT_QUORUM_CAPABLE;
  2945. //
  2946. // issue mini port ioctl to determine whether the disk is cluster capable
  2947. //
  2948. fRet = DeviceIoControl(
  2949. hSCSIPort
  2950. , IOCTL_SCSI_MINIPORT
  2951. , &srb
  2952. , sizeof( srb )
  2953. , NULL
  2954. , 0
  2955. , &dwSize
  2956. , NULL
  2957. );
  2958. //
  2959. // If the call succeeds then the disk is "not cluster capable". If the call
  2960. // fails then the disk is "not not cluster capable" and that means that it
  2961. // is cluster capable.
  2962. //
  2963. if ( fRet )
  2964. {
  2965. hr = S_FALSE;
  2966. } // if:
  2967. else
  2968. {
  2969. hr = S_OK;
  2970. } // else:
  2971. LogMsg( L"[SRV] The disks on SCSI port %d are%ws cluster capable.", m_ulSCSIPort, ( hr == S_FALSE ? L" not" : L"" ) );
  2972. Cleanup:
  2973. if ( FAILED( hr ) )
  2974. {
  2975. CLSID clsidMinorId;
  2976. HRESULT hrTemp;
  2977. hrTemp = THR( CoCreateGuid( &clsidMinorId ) );
  2978. if ( FAILED( hrTemp ) )
  2979. {
  2980. LOG_STATUS_REPORT( L"Could not create a guid for a not cluster capable disk minor task ID", hrTemp );
  2981. clsidMinorId = IID_NULL;
  2982. } // if:
  2983. STATUS_REPORT_STRING2_REF(
  2984. TASKID_Minor_PhysDisk_Cluster_Capable
  2985. , clsidMinorId
  2986. , IDS_ERROR_PHYSDISK_CLUSTER_CAPABLE
  2987. , m_bstrFriendlyName
  2988. , m_ulSCSIPort
  2989. , IDS_ERROR_PHYSDISK_CLUSTER_CAPABLE_REF
  2990. , hr
  2991. );
  2992. } // if:
  2993. if ( hSCSIPort != INVALID_HANDLE_VALUE )
  2994. {
  2995. CloseHandle( hSCSIPort );
  2996. } // if:
  2997. HRETURN( hr );
  2998. } //*** CPhysicalDisk::HrIsClusterCapable
  2999. /*
  3000. /////////////////////////////////////////////////////////////////////////////
  3001. //++
  3002. //
  3003. // CPhysicalDisk:HrProcessMountPoints
  3004. //
  3005. // Description:
  3006. // if any of the partitions on this spindle have reparse points then
  3007. // the mounted volumes are found and enumerated.
  3008. //
  3009. // Arguments:
  3010. // None.
  3011. //
  3012. // Return Value:
  3013. // S_OK
  3014. // Success.
  3015. //
  3016. // HRESULT errors.
  3017. //
  3018. // Remarks:
  3019. //
  3020. //--
  3021. //////////////////////////////////////////////////////////////////////////////
  3022. HRESULT
  3023. CPhysicalDisk::HrProcessMountPoints(
  3024. void
  3025. )
  3026. {
  3027. TraceFunc( "" );
  3028. HRESULT hr = S_OK;
  3029. ULONG idxOuter;
  3030. ULONG idxInner;
  3031. IClusCfgPartitionInfo * piccpi = NULL;
  3032. SDriveLetterMapping sdlm;
  3033. DWORD dwFlags;
  3034. WCHAR szRootPath[] = L"A:\\";
  3035. BSTR bstrFileSystem = NULL;
  3036. for ( idxOuter = 0; idxOuter < m_idxNextPartition; idxOuter++ )
  3037. {
  3038. hr = THR( ((*m_prgPartitions)[ idxOuter ])->TypeSafeQI( IClusCfgPartitionInfo, &piccpi ) );
  3039. if ( FAILED( hr ) )
  3040. {
  3041. LOG_STATUS_REPORT( L"CPhysicalDisk::HrHasReparsePoints() could not query for IClusCfgPartitionInfo.", hr );
  3042. goto Cleanup;
  3043. } // if:
  3044. InitDriveLetterMappings( &sdlm );
  3045. hr = THR( piccpi->GetDriveLetterMappings( &sdlm ) );
  3046. if ( FAILED( hr ) )
  3047. {
  3048. goto Cleanup;
  3049. } // if:
  3050. if ( hr == S_OK )
  3051. {
  3052. for ( idxInner = 0; idxInner < 26; idxInner++)
  3053. {
  3054. if ( sdlm.dluDrives[ idxInner ] != dluUNUSED )
  3055. {
  3056. szRootPath[ 0 ] = L'A' + (WCHAR) idxInner;
  3057. hr = THR( HrGetVolumeInformation( szRootPath, &dwFlags, &bstrFileSystem ) );
  3058. if ( FAILED( hr ) )
  3059. {
  3060. goto Cleanup;
  3061. } // if:
  3062. //
  3063. // If this spindle has reparse points then we need to return S_OK.
  3064. //
  3065. if ( dwFlags & FILE_SUPPORTS_REPARSE_POINTS )
  3066. {
  3067. hr = THR( HrEnumMountPoints( szRootPath ) );
  3068. if ( FAILED( hr ) )
  3069. {
  3070. goto Cleanup;
  3071. } // if:
  3072. } // if:
  3073. TraceSysFreeString( bstrFileSystem );
  3074. bstrFileSystem = NULL;
  3075. } // if:
  3076. } // for:
  3077. } // if:
  3078. piccpi->Release();
  3079. piccpi = NULL;
  3080. } // for:
  3081. Cleanup:
  3082. if ( piccpi != NULL )
  3083. {
  3084. piccpi->Release();
  3085. } // if:
  3086. TraceSysFreeString( bstrFileSystem );
  3087. HRETURN( hr );
  3088. } //*** CPhysicalDisk::HrProcessMountPoints
  3089. /////////////////////////////////////////////////////////////////////////////
  3090. //++
  3091. //
  3092. // CPhysicalDisk:HrEnumMountPoints
  3093. //
  3094. // Description:
  3095. // Enumerate the mounted volumes of the passed in root path.
  3096. //
  3097. // Arguments:
  3098. // pcszRootPathIn
  3099. //
  3100. // Return Value:
  3101. // S_OK
  3102. // Success.
  3103. //
  3104. // HRESULT errors.
  3105. //
  3106. // Remarks:
  3107. //
  3108. //--
  3109. //////////////////////////////////////////////////////////////////////////////
  3110. HRESULT
  3111. CPhysicalDisk::HrEnumMountPoints(
  3112. const WCHAR * pcszRootPathIn
  3113. )
  3114. {
  3115. TraceFunc( "" );
  3116. Assert( pcszRootPathIn != NULL );
  3117. HRESULT hr = S_OK;
  3118. HANDLE hEnum = NULL;
  3119. BOOL fRet;
  3120. WCHAR * psz = NULL;
  3121. DWORD cch = 512;
  3122. DWORD sc;
  3123. int cTemp;
  3124. psz = new WCHAR[ cch ];
  3125. if ( psz == NULL )
  3126. {
  3127. hr = THR( E_OUTOFMEMORY );
  3128. goto Cleanup;
  3129. } // if:
  3130. for ( cTemp = 0; cTemp < 3; cTemp++ )
  3131. {
  3132. hEnum = FindFirstVolumeMountPointW( pcszRootPathIn, psz, cch );
  3133. if ( hEnum == INVALID_HANDLE_VALUE )
  3134. {
  3135. sc = GetLastError();
  3136. if ( sc == ERROR_NO_MORE_FILES )
  3137. {
  3138. hr = S_FALSE;
  3139. goto Cleanup;
  3140. } // if:
  3141. else if ( sc == ERROR_BAD_LENGTH )
  3142. {
  3143. //
  3144. // Grow the buffer and try again.
  3145. //
  3146. cch += 512;
  3147. delete [] psz;
  3148. psz = new WCHAR[ cch ];
  3149. if ( psz == NULL )
  3150. {
  3151. hr = THR( E_OUTOFMEMORY );
  3152. goto Cleanup;
  3153. } // if:
  3154. continue;
  3155. } // else if:
  3156. else
  3157. {
  3158. hr = HRESULT_FROM_WIN32( TW32( sc ) );
  3159. goto Cleanup;
  3160. } // else:
  3161. } // if:
  3162. else
  3163. {
  3164. sc = ERROR_SUCCESS;
  3165. break;
  3166. } // else:
  3167. } // for:
  3168. if ( hEnum == INVALID_HANDLE_VALUE )
  3169. {
  3170. hr = HRESULT_FROM_WIN32( TW32( GetLastError() ) );
  3171. goto Cleanup;
  3172. } // if:
  3173. //
  3174. // psz has the first mounted volume
  3175. //
  3176. hr = STHR( HrProcessMountedVolume( pcszRootPathIn, psz ) );
  3177. if ( FAILED( hr ) )
  3178. {
  3179. goto Cleanup;
  3180. } // if:
  3181. //
  3182. // Now find any remaining mount points.
  3183. //
  3184. for ( ; ; )
  3185. {
  3186. fRet = FindNextVolumeMountPointW( hEnum, psz, cch );
  3187. if ( fRet == FALSE )
  3188. {
  3189. sc = GetLastError();
  3190. if ( sc == ERROR_NO_MORE_FILES )
  3191. {
  3192. hr = S_OK;
  3193. break;
  3194. } // if:
  3195. else if ( sc == ERROR_BAD_LENGTH )
  3196. {
  3197. //
  3198. // Grow the buffer and try again.
  3199. //
  3200. cch += 512;
  3201. delete [] psz;
  3202. psz = new WCHAR[ cch ];
  3203. if ( psz == NULL )
  3204. {
  3205. hr = THR( E_OUTOFMEMORY );
  3206. goto Cleanup;
  3207. } // if:
  3208. continue;
  3209. } // else if:
  3210. else
  3211. {
  3212. TW32( sc );
  3213. hr = HRESULT_FROM_WIN32( sc );
  3214. goto Cleanup;
  3215. } // else:
  3216. } // if:
  3217. else
  3218. {
  3219. hr = STHR( HrProcessMountedVolume( pcszRootPathIn, psz ) );
  3220. if ( FAILED( hr ) )
  3221. {
  3222. goto Cleanup;
  3223. } // if:
  3224. } // else:
  3225. } // for:
  3226. Cleanup:
  3227. if ( hEnum != INVALID_HANDLE_VALUE )
  3228. {
  3229. FindVolumeMountPointClose( hEnum );
  3230. } // if:
  3231. delete [] psz;
  3232. HRETURN( hr );
  3233. } //*** CPhysicalDisk::HrEnumMountPoints
  3234. /////////////////////////////////////////////////////////////////////////////
  3235. //++
  3236. //
  3237. // CPhysicalDisk:InitDriveLetterMappings
  3238. //
  3239. // Description:
  3240. // Initialize the drive letter mappings array.
  3241. //
  3242. // Arguments:
  3243. // pdlmDriveLetterMappingOut
  3244. //
  3245. // Return Value:
  3246. // None.
  3247. //
  3248. // Remarks:
  3249. //
  3250. //--
  3251. //////////////////////////////////////////////////////////////////////////////
  3252. void
  3253. CPhysicalDisk::InitDriveLetterMappings(
  3254. SDriveLetterMapping * pdlmDriveLetterMappingOut
  3255. )
  3256. {
  3257. TraceFunc( "" );
  3258. Assert( pdlmDriveLetterMappingOut != NULL );
  3259. ULONG idx;
  3260. for ( idx = 0 ; idx < 26 ; idx++ )
  3261. {
  3262. pdlmDriveLetterMappingOut->dluDrives[ idx ] = dluUNUSED;
  3263. } // for:
  3264. TraceFuncExit();
  3265. } // *** CPhysicalDisk::InitDriveLetterMappings
  3266. /////////////////////////////////////////////////////////////////////////////
  3267. //++
  3268. //
  3269. // CPhysicalDisk:HrProcessMountedVolume
  3270. //
  3271. // Description:
  3272. // Process the mounted volume by finding each spindle that makes up
  3273. // the mount point volume and convert it into a WMI device ID.
  3274. //
  3275. // Arguments:
  3276. // pcszRootPathIn
  3277. //
  3278. // pcszMountPointIn
  3279. //
  3280. // Return Value:
  3281. // S_OK
  3282. // Success.
  3283. //
  3284. // S_FALSE
  3285. // The mounted volume was not a physical disk.
  3286. //
  3287. // HRESULT errors.
  3288. //
  3289. // Remarks:
  3290. //
  3291. //--
  3292. //////////////////////////////////////////////////////////////////////////////
  3293. HRESULT
  3294. CPhysicalDisk::HrProcessMountedVolume(
  3295. const WCHAR * pcszRootPathIn
  3296. , const WCHAR * pcszMountPointIn
  3297. )
  3298. {
  3299. TraceFunc( "" );
  3300. Assert( pcszRootPathIn != NULL );
  3301. Assert( pcszMountPointIn != NULL );
  3302. HRESULT hr = S_OK;
  3303. BOOL fRet;
  3304. WCHAR * pszPath = NULL;
  3305. DWORD cchPath;
  3306. WCHAR * psz = NULL;
  3307. DWORD cch = 512;
  3308. int cTemp;
  3309. DWORD sc = ERROR_SUCCESS;
  3310. BSTR bstr = NULL;
  3311. UINT uDriveType;
  3312. HANDLE hVolume = NULL;
  3313. PVOLUME_DISK_EXTENTS pvde = NULL;
  3314. DWORD cbvde;
  3315. DWORD dwSize;
  3316. WCHAR sz[ 32 ];
  3317. DWORD idx;
  3318. BSTR bstrFileSystem = NULL;
  3319. BOOL fIsNTFS;
  3320. cchPath = wcslen( pcszRootPathIn ) + wcslen( pcszMountPointIn ) + 1;
  3321. pszPath = new WCHAR[ cchPath ];
  3322. if ( pszPath == NULL )
  3323. {
  3324. hr = THR( E_OUTOFMEMORY );
  3325. goto Cleanup;
  3326. } // if:
  3327. hr = THR( StringCchCopyW( pszPath, cchPath, pcszRootPathIn ) );
  3328. if ( FAILED( hr ) )
  3329. {
  3330. goto Cleanup;
  3331. } // if:
  3332. hr = THR( StringCchCopyW( pszPath, cchPath, pcszMountPointIn ) );
  3333. if ( FAILED( hr ) )
  3334. {
  3335. goto Cleanup;
  3336. } // if:
  3337. psz = new WCHAR[ cch ];
  3338. if ( psz == NULL )
  3339. {
  3340. hr = THR( E_OUTOFMEMORY );
  3341. goto Cleanup;
  3342. } // if:
  3343. for ( cTemp = 0, fRet = FALSE; cTemp < 3; cTemp++ )
  3344. {
  3345. fRet = GetVolumeNameForVolumeMountPoint( pszPath, psz, cch );
  3346. if ( fRet == FALSE )
  3347. {
  3348. sc = GetLastError();
  3349. if ( sc == ERROR_BAD_LENGTH )
  3350. {
  3351. //
  3352. // Grow the buffer and try again.
  3353. //
  3354. cch += 512;
  3355. delete [] psz;
  3356. psz = new WCHAR[ cch ];
  3357. if ( psz == NULL )
  3358. {
  3359. hr = THR( E_OUTOFMEMORY );
  3360. goto Cleanup;
  3361. } // if:
  3362. continue;
  3363. } // if:
  3364. else
  3365. {
  3366. hr = HRESULT_FROM_WIN32( TW32( sc ) );
  3367. goto Cleanup;
  3368. } // else:
  3369. } // if:
  3370. else
  3371. {
  3372. sc = ERROR_SUCCESS;
  3373. break;
  3374. } // else:
  3375. } // for:
  3376. if ( fRet == FALSE )
  3377. {
  3378. hr = HRESULT_FROM_WIN32( TW32( GetLastError() ) );
  3379. goto Cleanup;
  3380. } // if:
  3381. //
  3382. // Now psz has the "guid volume name" for the volume that is mounted.
  3383. //
  3384. //
  3385. // Now we need to ensure that the mounted volume is a fixed disk.
  3386. //
  3387. uDriveType = GetDriveType( psz );
  3388. if ( uDriveType != DRIVE_FIXED )
  3389. {
  3390. hr = S_FALSE;
  3391. goto Cleanup;
  3392. } // if:
  3393. hr = THR( HrGetVolumeInformation( psz, NULL, &bstrFileSystem ) );
  3394. if ( FAILED( hr ) )
  3395. {
  3396. goto Cleanup;
  3397. } // if:
  3398. //
  3399. // We don't care about volumes that are not using NTFS.
  3400. //
  3401. fIsNTFS = ( NStringCchCompareCase( bstrFileSystem, SysStringLen( bstrFileSystem ) + 1, L"NTFS", RTL_NUMBER_OF( L"NTFS" ) ) == 0 );
  3402. if ( fIsNTFS == FALSE )
  3403. {
  3404. hr = S_FALSE;
  3405. goto Cleanup;
  3406. } // if:
  3407. //
  3408. // Trim off the trailing \ so we can open the device and poke it with
  3409. // an IOCTL.
  3410. //
  3411. psz[ wcslen( psz ) - 1 ] = L'\0';
  3412. //
  3413. // Get and handle to the device.
  3414. //
  3415. hVolume = CreateFileW(
  3416. psz
  3417. , GENERIC_READ
  3418. , FILE_SHARE_READ
  3419. , NULL
  3420. , OPEN_EXISTING
  3421. , FILE_ATTRIBUTE_NORMAL
  3422. , NULL
  3423. );
  3424. if ( hVolume == INVALID_HANDLE_VALUE )
  3425. {
  3426. sc = TW32( GetLastError() );
  3427. hr = HRESULT_FROM_WIN32( sc );
  3428. goto Cleanup;
  3429. } // if:
  3430. cbvde = sizeof( VOLUME_DISK_EXTENTS );
  3431. pvde = (PVOLUME_DISK_EXTENTS) TraceAlloc( 0, cbvde );
  3432. if ( pvde == NULL )
  3433. {
  3434. hr = THR( E_OUTOFMEMORY );
  3435. goto Cleanup;
  3436. } // if:
  3437. for ( cTemp = 0; cTemp < 3; cTemp++ )
  3438. {
  3439. fRet = DeviceIoControl(
  3440. hVolume
  3441. , IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS
  3442. , NULL
  3443. , 0
  3444. , pvde
  3445. , cbvde
  3446. , &dwSize
  3447. , NULL
  3448. );
  3449. if ( fRet == FALSE )
  3450. {
  3451. sc = GetLastError();
  3452. if ( sc == ERROR_MORE_DATA )
  3453. {
  3454. PVOLUME_DISK_EXTENTS pvdeTemp = NULL;
  3455. cbvde = sizeof( VOLUME_DISK_EXTENTS ) + ( sizeof( DISK_EXTENT ) * pvde->NumberOfDiskExtents );
  3456. pvdeTemp = (PVOLUME_DISK_EXTENTS) TraceReAlloc( pvde, cbvde, HEAP_ZERO_MEMORY );
  3457. if ( pvdeTemp == NULL )
  3458. {
  3459. hr = THR( E_OUTOFMEMORY );
  3460. goto Cleanup;
  3461. } // if:
  3462. pvde = pvdeTemp;
  3463. continue;
  3464. } // if:
  3465. else
  3466. {
  3467. TW32( sc );
  3468. hr = HRESULT_FROM_WIN32( sc );
  3469. goto Cleanup;
  3470. } // else:
  3471. } // if:
  3472. else
  3473. {
  3474. sc = ERROR_SUCCESS;
  3475. break;
  3476. } // else:
  3477. } // for:
  3478. if ( sc != ERROR_SUCCESS )
  3479. {
  3480. hr = HRESULT_FROM_WIN32( TW32( sc ) );
  3481. goto Cleanup;
  3482. } // if:
  3483. //
  3484. // Now we have the disk number(s) of the mounted disk and we can convert that to
  3485. // a WMI device ID.
  3486. //
  3487. for ( idx = 0; idx < pvde->NumberOfDiskExtents; idx++ )
  3488. {
  3489. hr = THR( StringCchPrintfW( sz, ARRAYSIZE( sz ), g_szPhysicalDriveFormat, pvde->Extents[ idx ].DiskNumber ) );
  3490. if ( FAILED( hr ) )
  3491. {
  3492. goto Cleanup;
  3493. } // if:
  3494. hr = THR( HrProcessSpindle( sz ) );
  3495. if ( FAILED( hr ) )
  3496. {
  3497. goto Cleanup;
  3498. } // if:
  3499. } // for:
  3500. Cleanup:
  3501. if ( hVolume != NULL )
  3502. {
  3503. CloseHandle( hVolume );
  3504. } // if:
  3505. TraceFree( pvde );
  3506. TraceSysFreeString( bstr );
  3507. TraceSysFreeString( bstrFileSystem );
  3508. delete [] psz;
  3509. delete [] pszPath;
  3510. HRETURN( hr );
  3511. } // *** CPhysicalDisk::HrProcessMountedVolume
  3512. /////////////////////////////////////////////////////////////////////////////
  3513. //++
  3514. //
  3515. // CPhysicalDisk:HrProcessSpindle
  3516. //
  3517. // Description:
  3518. // Process the mounted volume spindle by creating a CPhysicalDisk
  3519. // object and adding it to the physical disks enumerator.
  3520. //
  3521. // Arguments:
  3522. // pcszDeviceIDIn
  3523. //
  3524. // Return Value:
  3525. // S_OK
  3526. // Success.
  3527. //
  3528. // HRESULT errors.
  3529. //
  3530. // Remarks:
  3531. //
  3532. //--
  3533. //////////////////////////////////////////////////////////////////////////////
  3534. HRESULT
  3535. CPhysicalDisk::HrProcessSpindle(
  3536. const WCHAR * pcszDeviceIDIn
  3537. )
  3538. {
  3539. Assert( pcszDeviceIDIn != NULL );
  3540. TraceFunc( "" );
  3541. HRESULT hr = S_OK;
  3542. Cleanup:
  3543. HRETURN( hr );
  3544. } // *** CPhysicalDisk::HrProcessSpindle
  3545. */
  3546. //*************************************************************************//
  3547. /////////////////////////////////////////////////////////////////////////////
  3548. // CPhysicalDisk class -- IClusCfgVerifyQuorum interface.
  3549. /////////////////////////////////////////////////////////////////////////////
  3550. //////////////////////////////////////////////////////////////////////////////
  3551. //++
  3552. //
  3553. // CPhysicalDisk::PrepareToHostQuorumResource
  3554. //
  3555. // Description:
  3556. // Do any configuration necessary in preparation for this node hosting
  3557. // the quorum.
  3558. //
  3559. // Arguments:
  3560. // None.
  3561. //
  3562. // Return Value:
  3563. // S_OK
  3564. // Success
  3565. //
  3566. // Win32 error as HRESULT when an error occurs.
  3567. //
  3568. //--
  3569. //////////////////////////////////////////////////////////////////////////////
  3570. STDMETHODIMP
  3571. CPhysicalDisk::PrepareToHostQuorumResource( void )
  3572. {
  3573. TraceFunc( "[IClusCfgVerifyQuorum]" );
  3574. HRETURN( S_OK );
  3575. } //*** CPhysicalDisk::PrepareToHostQuorumResource
  3576. //////////////////////////////////////////////////////////////////////////////
  3577. //++
  3578. //
  3579. // CPhysicalDisk::Cleanup
  3580. //
  3581. // Description:
  3582. // Do any necessay cleanup from the PrepareToHostQuorumResource()
  3583. // method.
  3584. //
  3585. // If the cleanup method is anything other than successful completion
  3586. // then the anything created above in PrepareToHostQuorumResource()
  3587. // needs to be cleaned up.
  3588. //
  3589. // Arguments:
  3590. // cccrReasonIn
  3591. //
  3592. // Return Value:
  3593. // S_OK
  3594. // Success
  3595. //
  3596. // Win32 error as HRESULT when an error occurs.
  3597. //
  3598. //--
  3599. //////////////////////////////////////////////////////////////////////////////
  3600. STDMETHODIMP
  3601. CPhysicalDisk::Cleanup(
  3602. EClusCfgCleanupReason cccrReasonIn
  3603. )
  3604. {
  3605. TraceFunc( "[IClusCfgVerifyQuorum]" );
  3606. HRETURN( S_OK );
  3607. } //*** CPhysicalDisk::Cleanup
  3608. //////////////////////////////////////////////////////////////////////////////
  3609. //++
  3610. //
  3611. // CPhysicalDisk::IsMultiNodeCapable
  3612. //
  3613. // Description:
  3614. //
  3615. // Arguments:
  3616. //
  3617. // Return Value:
  3618. // S_OK
  3619. // The quorumable device allows join.
  3620. //
  3621. // S_FALSE
  3622. // The device does not allow join.
  3623. //
  3624. // Win32 error as HRESULT when an error occurs.
  3625. //
  3626. // Remarks:
  3627. // None.
  3628. //
  3629. //--
  3630. //////////////////////////////////////////////////////////////////////////////
  3631. STDMETHODIMP
  3632. CPhysicalDisk::IsMultiNodeCapable( void )
  3633. {
  3634. TraceFunc( "[IClusCfgVerifyQuorum]" );
  3635. HRESULT hr = S_FALSE;
  3636. if ( m_fIsQuorumResourceMultiNodeCapable )
  3637. {
  3638. hr = S_OK;
  3639. } // if:
  3640. HRETURN( hr );
  3641. } //*** CPhysicalDisk::IsMultiNodeCapable
  3642. //////////////////////////////////////////////////////////////////////////////
  3643. //++
  3644. //
  3645. // CPhysicalDisk::SetMultiNodeCapable
  3646. //
  3647. // Description:
  3648. //
  3649. // Arguments:
  3650. //
  3651. // Return Value:
  3652. // S_OK
  3653. // The quorumable device allows join.
  3654. //
  3655. // S_FALSE
  3656. // The device does not allow join.
  3657. //
  3658. // Win32 error as HRESULT when an error occurs.
  3659. //
  3660. // Remarks:
  3661. // This function should never be called
  3662. //
  3663. //--
  3664. //////////////////////////////////////////////////////////////////////////////
  3665. STDMETHODIMP
  3666. CPhysicalDisk::SetMultiNodeCapable(
  3667. BOOL fMultiNodeCapableIn
  3668. )
  3669. {
  3670. TraceFunc( "[IClusCfgVerifyQuorum]" );
  3671. HRETURN( S_FALSE );
  3672. } //*** CPhysicalDisk::SetMultiNodeCapable