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.

3611 lines
90 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 2000-2002 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // CEnumPhysicalDisks.cpp
  7. //
  8. // Description:
  9. // This file contains the definition of the CEnumPhysicalDisks
  10. // class.
  11. //
  12. // The class CEnumPhysicalDisks is the enumeration of cluster
  13. // storage devices. It implements the IEnumClusCfgManagedResources
  14. // interface.
  15. //
  16. // Maintained By:
  17. // Galen Barbee (GalenB) 23-FEB-2000
  18. //
  19. //////////////////////////////////////////////////////////////////////////////
  20. //////////////////////////////////////////////////////////////////////////////
  21. // Include Files
  22. //////////////////////////////////////////////////////////////////////////////
  23. #include "Pch.h"
  24. //#include <setupapi.h>
  25. //#include <winioctl.h>
  26. #include "CEnumPhysicalDisks.h"
  27. #include "CPhysicalDisk.h"
  28. #include "CIndexedDisk.h"
  29. #include <PropList.h>
  30. #include <InsertionSort.h>
  31. //////////////////////////////////////////////////////////////////////////////
  32. // Constant Definitions
  33. //////////////////////////////////////////////////////////////////////////////
  34. DEFINE_THISCLASS( "CEnumPhysicalDisks" );
  35. //*************************************************************************//
  36. /////////////////////////////////////////////////////////////////////////////
  37. // CEnumPhysicalDisks class
  38. /////////////////////////////////////////////////////////////////////////////
  39. //////////////////////////////////////////////////////////////////////////////
  40. //++
  41. //
  42. // CEnumPhysicalDisks::S_HrCreateInstance
  43. //
  44. // Description:
  45. // Create a CEnumPhysicalDisks instance.
  46. //
  47. // Arguments:
  48. // None.
  49. //
  50. // Return Values:
  51. // S_OK
  52. // Success.
  53. //
  54. // E_POINTER
  55. // The passed in ppunk is NULL.
  56. //
  57. // other HRESULTs
  58. // Object creation failed.
  59. //
  60. //--
  61. //////////////////////////////////////////////////////////////////////////////
  62. HRESULT
  63. CEnumPhysicalDisks::S_HrCreateInstance( IUnknown ** ppunkOut )
  64. {
  65. TraceFunc( "" );
  66. HRESULT hr = S_OK;
  67. CEnumPhysicalDisks * pepd = NULL;
  68. if ( ppunkOut == NULL )
  69. {
  70. hr = THR( E_POINTER );
  71. goto Cleanup;
  72. } // if:
  73. pepd = new CEnumPhysicalDisks();
  74. if ( pepd == NULL )
  75. {
  76. hr = THR( E_OUTOFMEMORY );
  77. goto Cleanup;
  78. } // if: error allocating object
  79. hr = THR( pepd->HrInit() );
  80. if ( FAILED( hr ) )
  81. {
  82. goto Cleanup;
  83. } // if: HrInit() failed
  84. hr = THR( pepd->TypeSafeQI( IUnknown, ppunkOut ) );
  85. if ( FAILED( hr ) )
  86. {
  87. goto Cleanup;
  88. } // if: QI failed
  89. Cleanup:
  90. if ( FAILED( hr ) )
  91. {
  92. LogMsg( L"[SRV] CEnumPhysicalDisks::S_HrCreateInstance() failed. (hr = %#08x)", hr );
  93. } // if:
  94. if ( pepd != NULL )
  95. {
  96. pepd->Release();
  97. } // if:
  98. HRETURN( hr );
  99. } //*** CEnumPhysicalDisks::S_HrCreateInstance
  100. //////////////////////////////////////////////////////////////////////////////
  101. //++
  102. //
  103. // IUnknown *
  104. // CEnumPhysicalDisks::S_RegisterCatIDSupport
  105. //
  106. // Description:
  107. // Registers/unregisters this class with the categories that it belongs
  108. // to.
  109. //
  110. // Arguments:
  111. // IN ICatRegister * picrIn
  112. // Used to register/unregister our CATID support.
  113. //
  114. // IN BOOL fCreateIn
  115. // When true we are registering the server. When false we are
  116. // un-registering the server.
  117. //
  118. // Return Values:
  119. // S_OK
  120. // Success.
  121. //
  122. // E_INVALIDARG
  123. // The passed in ICatRgister pointer was NULL.
  124. //
  125. // other HRESULTs
  126. // Registration/Unregistration failed.
  127. //
  128. //--
  129. //////////////////////////////////////////////////////////////////////////////
  130. HRESULT
  131. CEnumPhysicalDisks::S_RegisterCatIDSupport(
  132. ICatRegister * picrIn,
  133. BOOL fCreateIn
  134. )
  135. {
  136. TraceFunc( "" );
  137. HRESULT hr = S_OK;
  138. CATID rgCatIds[ 1 ];
  139. if ( picrIn == NULL )
  140. {
  141. hr = THR( E_INVALIDARG );
  142. goto Cleanup;
  143. } // if:
  144. rgCatIds[ 0 ] = CATID_EnumClusCfgManagedResources;
  145. if ( fCreateIn )
  146. {
  147. hr = THR( picrIn->RegisterClassImplCategories( CLSID_EnumPhysicalDisks, 1, rgCatIds ) );
  148. } // if:
  149. Cleanup:
  150. HRETURN( hr );
  151. } //*** CEnumPhysicalDisks::S_RegisterCatIDSupport
  152. //////////////////////////////////////////////////////////////////////////////
  153. //++
  154. //
  155. // CEnumPhysicalDisks::CEnumPhysicalDisks
  156. //
  157. // Description:
  158. // Constructor of the CEnumPhysicalDisks class. This initializes
  159. // the m_cRef variable to 1 instead of 0 to account of possible
  160. // QueryInterface failure in DllGetClassObject.
  161. //
  162. // Arguments:
  163. // None.
  164. //
  165. // Return Value:
  166. // None.
  167. //
  168. // Remarks:
  169. // None.
  170. //
  171. //--
  172. //////////////////////////////////////////////////////////////////////////////
  173. CEnumPhysicalDisks::CEnumPhysicalDisks( void )
  174. : m_cRef( 1 )
  175. , m_lcid( LOCALE_NEUTRAL )
  176. , m_fLoadedDevices( false )
  177. {
  178. TraceFunc( "" );
  179. // Increment the count of components in memory so the DLL hosting this
  180. // object cannot be unloaded.
  181. InterlockedIncrement( &g_cObjects );
  182. Assert( m_picccCallback == NULL );
  183. Assert( m_pIWbemServices == NULL );
  184. Assert( m_prgDisks == NULL );
  185. Assert( m_idxNext == 0 );
  186. Assert( m_idxEnumNext == 0 );
  187. Assert( m_bstrNodeName == NULL );
  188. Assert( m_bstrBootDevice == NULL );
  189. Assert( m_bstrSystemDevice == NULL );
  190. Assert( m_bstrBootLogicalDisk == NULL );
  191. Assert( m_bstrSystemLogicalDisk == NULL );
  192. Assert( m_bstrSystemWMIDeviceID == NULL );
  193. Assert( m_cDiskCount == 0 );
  194. Assert( m_bstrCrashDumpLogicalDisk == NULL );
  195. TraceFuncExit();
  196. } //*** CEnumPhysicalDisks::CEnumPhysicalDisks
  197. //////////////////////////////////////////////////////////////////////////////
  198. //++
  199. //
  200. // CEnumPhysicalDisks::~CEnumPhysicalDisks
  201. //
  202. // Description:
  203. // Desstructor of the CEnumPhysicalDisks class.
  204. //
  205. // Arguments:
  206. // None.
  207. //
  208. // Return Value:
  209. // None.
  210. //
  211. // Remarks:
  212. // None.
  213. //
  214. //--
  215. //////////////////////////////////////////////////////////////////////////////
  216. CEnumPhysicalDisks::~CEnumPhysicalDisks( void )
  217. {
  218. TraceFunc( "" );
  219. ULONG idx;
  220. if ( m_pIWbemServices != NULL )
  221. {
  222. m_pIWbemServices->Release();
  223. } // if:
  224. if ( m_picccCallback != NULL )
  225. {
  226. m_picccCallback->Release();
  227. } // if:
  228. for ( idx = 0; idx < m_idxNext; idx++ )
  229. {
  230. if ( (*m_prgDisks)[ idx ] != NULL )
  231. {
  232. ((*m_prgDisks)[ idx ])->Release();
  233. } // end if:
  234. } // for:
  235. TraceFree( m_prgDisks );
  236. TraceSysFreeString( m_bstrNodeName );
  237. TraceSysFreeString( m_bstrBootDevice );
  238. TraceSysFreeString( m_bstrSystemDevice );
  239. TraceSysFreeString( m_bstrBootLogicalDisk );
  240. TraceSysFreeString( m_bstrSystemLogicalDisk );
  241. TraceSysFreeString( m_bstrSystemWMIDeviceID );
  242. TraceSysFreeString( m_bstrCrashDumpLogicalDisk );
  243. // There's going to be one less component in memory. Decrement component count.
  244. InterlockedDecrement( &g_cObjects );
  245. TraceFuncExit();
  246. } //*** CEnumPhysicalDisks::~CEnumPhysicalDisks
  247. //*************************************************************************//
  248. /////////////////////////////////////////////////////////////////////////////
  249. // CEnumPhysicalDisks -- IUnknown interface.
  250. /////////////////////////////////////////////////////////////////////////////
  251. //////////////////////////////////////////////////////////////////////////////
  252. //++
  253. //
  254. // CEnumPhysicalDisks::AddRef
  255. //
  256. // Description:
  257. // Increment the reference count of this object by one.
  258. //
  259. // Arguments:
  260. // None.
  261. //
  262. // Return Value:
  263. // The new reference count.
  264. //
  265. // Remarks:
  266. // None.
  267. //
  268. //--
  269. //////////////////////////////////////////////////////////////////////////////
  270. STDMETHODIMP_( ULONG )
  271. CEnumPhysicalDisks::AddRef( void )
  272. {
  273. TraceFunc( "[IUnknown]" );
  274. InterlockedIncrement( & m_cRef );
  275. CRETURN( m_cRef );
  276. } //*** CEnumPhysicalDisks::AddRef
  277. //////////////////////////////////////////////////////////////////////////////
  278. //++
  279. //
  280. // CEnumPhysicalDisks::Release
  281. //
  282. // Description:
  283. // Decrement the reference count of this object by one.
  284. //
  285. // Arguments:
  286. // None.
  287. //
  288. // Return Value:
  289. // The new reference count.
  290. //
  291. // Remarks:
  292. // None.
  293. //
  294. //--
  295. //////////////////////////////////////////////////////////////////////////////
  296. STDMETHODIMP_( ULONG )
  297. CEnumPhysicalDisks::Release( void )
  298. {
  299. TraceFunc( "[IUnknown]" );
  300. LONG cRef;
  301. cRef = InterlockedDecrement( &m_cRef );
  302. if ( cRef == 0 )
  303. {
  304. TraceDo( delete this );
  305. } // if: reference count equal to zero
  306. CRETURN( cRef );
  307. } //*** CEnumPhysicalDisks::Release
  308. //////////////////////////////////////////////////////////////////////////////
  309. //++
  310. //
  311. // CEnumPhysicalDisks::QueryInterface
  312. //
  313. // Description:
  314. // Query this object for the passed in interface.
  315. //
  316. // Arguments:
  317. // riidIn
  318. // Id of interface requested.
  319. //
  320. // ppvOut
  321. // Pointer to the requested interface.
  322. //
  323. // Return Value:
  324. // S_OK
  325. // If the interface is available on this object.
  326. //
  327. // E_NOINTERFACE
  328. // If the interface is not available.
  329. //
  330. // E_POINTER
  331. // ppvOut was NULL.
  332. //
  333. // Remarks:
  334. // None.
  335. //
  336. //--
  337. //////////////////////////////////////////////////////////////////////////////
  338. STDMETHODIMP
  339. CEnumPhysicalDisks::QueryInterface(
  340. REFIID riidIn
  341. , void ** ppvOut
  342. )
  343. {
  344. TraceQIFunc( riidIn, ppvOut );
  345. HRESULT hr = S_OK;
  346. //
  347. // Validate arguments.
  348. //
  349. Assert( ppvOut != NULL );
  350. if ( ppvOut == NULL )
  351. {
  352. hr = THR( E_POINTER );
  353. goto Cleanup;
  354. }
  355. //
  356. // Handle known interfaces.
  357. //
  358. if ( IsEqualIID( riidIn, IID_IUnknown ) )
  359. {
  360. *ppvOut = static_cast< IEnumClusCfgManagedResources * >( this );
  361. } // if: IUnknown
  362. else if ( IsEqualIID( riidIn, IID_IEnumClusCfgManagedResources ) )
  363. {
  364. *ppvOut = TraceInterface( __THISCLASS__, IEnumClusCfgManagedResources, this, 0 );
  365. } // else if: IEnumClusCfgManagedResources
  366. else if ( IsEqualIID( riidIn, IID_IClusCfgWbemServices ) )
  367. {
  368. *ppvOut = TraceInterface( __THISCLASS__, IClusCfgWbemServices, this, 0 );
  369. } // else if: IClusCfgWbemServices
  370. else if ( IsEqualIID( riidIn, IID_IClusCfgInitialize ) )
  371. {
  372. *ppvOut = TraceInterface( __THISCLASS__, IClusCfgInitialize, this, 0 );
  373. } // else if: IClusCfgInitialize
  374. else
  375. {
  376. *ppvOut = NULL;
  377. hr = E_NOINTERFACE;
  378. }
  379. //
  380. // Add a reference to the interface if successful.
  381. //
  382. if ( SUCCEEDED( hr ) )
  383. {
  384. ((IUnknown *) *ppvOut)->AddRef();
  385. } // if: success
  386. Cleanup:
  387. QIRETURN_IGNORESTDMARSHALLING( hr, riidIn );
  388. } //*** CEnumPhysicalDisks::QueryInterface
  389. //*************************************************************************//
  390. /////////////////////////////////////////////////////////////////////////////
  391. // CEnumPhysicalDisks -- IClusCfgWbemServices interface.
  392. /////////////////////////////////////////////////////////////////////////////
  393. //////////////////////////////////////////////////////////////////////////////
  394. //++
  395. //
  396. // CEnumPhysicalDisks::SetWbemServices
  397. //
  398. // Description:
  399. // Set the WBEM services provider.
  400. //
  401. // Arguments:
  402. // IN IWbemServices pIWbemServicesIn
  403. //
  404. // Return Value:
  405. // S_OK
  406. // Success
  407. //
  408. // E_POINTER
  409. // The pIWbemServicesIn param is NULL.
  410. //
  411. // Remarks:
  412. // None.
  413. //
  414. //--
  415. //////////////////////////////////////////////////////////////////////////////
  416. STDMETHODIMP
  417. CEnumPhysicalDisks::SetWbemServices( IWbemServices * pIWbemServicesIn )
  418. {
  419. TraceFunc( "[IClusCfgWbemServices]" );
  420. HRESULT hr = S_OK;
  421. if ( pIWbemServicesIn == NULL )
  422. {
  423. hr = THR( E_POINTER );
  424. STATUS_REPORT_REF( TASKID_Major_Find_Devices, TASKID_Minor_SetWbemServices_Enum_PhysDisk, IDS_ERROR_NULL_POINTER, IDS_ERROR_NULL_POINTER_REF, hr );
  425. goto Cleanup;
  426. } // if:
  427. m_pIWbemServices = pIWbemServicesIn;
  428. m_pIWbemServices->AddRef();
  429. hr = THR( HrGetSystemDevice( &m_bstrSystemDevice ) );
  430. if ( FAILED( hr ) )
  431. {
  432. goto Cleanup;
  433. } // if:
  434. hr = THR( HrConvertDeviceVolumeToLogicalDisk( m_bstrSystemDevice, &m_bstrSystemLogicalDisk ) );
  435. if ( HRESULT_CODE( hr ) == ERROR_INVALID_FUNCTION )
  436. {
  437. //
  438. // system volume is an EFI volume on IA64 and won't have a logical disk.
  439. //
  440. hr = THR( HrConvertDeviceVolumeToWMIDeviceID( m_bstrSystemDevice, &m_bstrSystemWMIDeviceID ) );
  441. Assert( m_bstrSystemLogicalDisk == NULL );
  442. Assert( m_bstrSystemWMIDeviceID != NULL );
  443. } // if:
  444. if ( FAILED( hr ) )
  445. {
  446. goto Cleanup;
  447. } // if:
  448. hr = THR( HrGetBootLogicalDisk( &m_bstrBootLogicalDisk ) );
  449. if ( FAILED( hr ) )
  450. {
  451. goto Cleanup;
  452. } // if:
  453. hr = STHR( HrIsLogicalDiskNTFS( m_bstrBootLogicalDisk ) );
  454. if ( hr == S_FALSE )
  455. {
  456. STATUS_REPORT_REF(
  457. TASKID_Major_Find_Devices
  458. , TASKID_Minor_Boot_Partition_Not_NTFS
  459. , IDS_WARN_BOOT_PARTITION_NOT_NTFS
  460. , IDS_WARN_BOOT_PARTITION_NOT_NTFS_REF
  461. , hr
  462. );
  463. hr = S_OK;
  464. } // if:
  465. hr = THR( HrGetCrashDumpLogicalDisk( &m_bstrCrashDumpLogicalDisk ) );
  466. if ( FAILED( hr ) )
  467. {
  468. goto Cleanup;
  469. } // if:
  470. Cleanup:
  471. HRETURN( hr );
  472. } //*** CEnumPhysicalDisks::SetWbemServices
  473. //*************************************************************************//
  474. /////////////////////////////////////////////////////////////////////////////
  475. // CEnumPhysicalDisks -- IClusCfgInitialize interface.
  476. /////////////////////////////////////////////////////////////////////////////
  477. //////////////////////////////////////////////////////////////////////////////
  478. //++
  479. //
  480. // CEnumPhysicalDisks::Initialize
  481. //
  482. // Description:
  483. // Initialize this component.
  484. //
  485. // Arguments:
  486. // punkCallbackIn
  487. // lcidIn
  488. //
  489. // Return Value:
  490. // S_OK - Success.
  491. // E_INVALIDARG - Required input argument not specified.
  492. // Other HRESULTs.
  493. //
  494. //--
  495. //////////////////////////////////////////////////////////////////////////////
  496. STDMETHODIMP
  497. CEnumPhysicalDisks::Initialize(
  498. IUnknown * punkCallbackIn
  499. , LCID lcidIn
  500. )
  501. {
  502. TraceFunc( "[IClusCfgInitialize]" );
  503. Assert( m_picccCallback == NULL );
  504. HRESULT hr = S_OK;
  505. m_lcid = lcidIn;
  506. if ( punkCallbackIn == NULL )
  507. {
  508. hr = THR( E_INVALIDARG );
  509. goto Cleanup;
  510. } // if:
  511. hr = THR( punkCallbackIn->TypeSafeQI( IClusCfgCallback, &m_picccCallback ) );
  512. if ( FAILED( hr ) )
  513. {
  514. goto Cleanup;
  515. } // if:
  516. hr = THR( HrGetComputerName(
  517. ComputerNameDnsHostname
  518. , &m_bstrNodeName
  519. , TRUE // fBestEffortIn
  520. ) );
  521. if ( FAILED( hr ) )
  522. {
  523. goto Cleanup;
  524. } // if:
  525. Cleanup:
  526. HRETURN( hr );
  527. } //*** CEnumPhysicalDisks::Initialize
  528. //*************************************************************************//
  529. /////////////////////////////////////////////////////////////////////////////
  530. // CEnumPhysicalDisks -- IEnumClusCfgManagedResources interface.
  531. /////////////////////////////////////////////////////////////////////////////
  532. //////////////////////////////////////////////////////////////////////////////
  533. //++
  534. //
  535. // CEnumPhysicalDisks::Next
  536. //
  537. // Description:
  538. //
  539. // Arguments:
  540. //
  541. // Return Value:
  542. //
  543. // Remarks:
  544. // None.
  545. //
  546. //--
  547. //////////////////////////////////////////////////////////////////////////////
  548. STDMETHODIMP
  549. CEnumPhysicalDisks::Next(
  550. ULONG cNumberRequestedIn,
  551. IClusCfgManagedResourceInfo ** rgpManagedResourceInfoOut,
  552. ULONG * pcNumberFetchedOut
  553. )
  554. {
  555. TraceFunc( "[IEnumClusCfgManagedResources]" );
  556. HRESULT hr = S_FALSE;
  557. ULONG cFetched = 0;
  558. IClusCfgManagedResourceInfo * pccsdi;
  559. IUnknown * punk;
  560. ULONG ulStop;
  561. if ( rgpManagedResourceInfoOut == NULL )
  562. {
  563. hr = THR( E_POINTER );
  564. STATUS_REPORT_REF( TASKID_Major_Find_Devices, TASKID_Minor_Next_Enum_PhysDisk, IDS_ERROR_NULL_POINTER, IDS_ERROR_NULL_POINTER_REF, hr );
  565. goto Cleanup;
  566. } // if:
  567. if ( !m_fLoadedDevices )
  568. {
  569. hr = THR( HrLoadEnum() );
  570. if ( FAILED( hr ) )
  571. {
  572. goto Cleanup;
  573. } // if:
  574. } // if:
  575. ulStop = min( cNumberRequestedIn, ( m_idxNext - m_idxEnumNext ) );
  576. for ( hr = S_OK; ( cFetched < ulStop ) && ( m_idxEnumNext < m_idxNext ); m_idxEnumNext++ )
  577. {
  578. punk = (*m_prgDisks)[ m_idxEnumNext ];
  579. if ( punk != NULL )
  580. {
  581. hr = THR( punk->TypeSafeQI( IClusCfgManagedResourceInfo, &pccsdi ) );
  582. if ( FAILED( hr ) )
  583. {
  584. break;
  585. } // if:
  586. rgpManagedResourceInfoOut[ cFetched++ ] = pccsdi;
  587. } // if:
  588. } // for:
  589. if ( FAILED( hr ) )
  590. {
  591. m_idxEnumNext -= cFetched;
  592. while ( cFetched != 0 )
  593. {
  594. (rgpManagedResourceInfoOut[ --cFetched ])->Release();
  595. } // for:
  596. goto Cleanup;
  597. } // if:
  598. if ( cFetched < cNumberRequestedIn )
  599. {
  600. hr = S_FALSE;
  601. } // if:
  602. Cleanup:
  603. if ( pcNumberFetchedOut != NULL )
  604. {
  605. *pcNumberFetchedOut = cFetched;
  606. } // if:
  607. HRETURN( hr );
  608. } //*** CEnumPhysicalDisks::Next
  609. //////////////////////////////////////////////////////////////////////////////
  610. //++
  611. //
  612. // CEnumPhysicalDisks::Skip
  613. //
  614. // Description:
  615. //
  616. // Arguments:
  617. //
  618. // Return Value:
  619. //
  620. // Remarks:
  621. // None.
  622. //
  623. //--
  624. //////////////////////////////////////////////////////////////////////////////
  625. STDMETHODIMP
  626. CEnumPhysicalDisks::Skip( ULONG cNumberToSkipIn )
  627. {
  628. TraceFunc( "[IEnumClusCfgManagedResources]" );
  629. HRESULT hr = S_OK;
  630. m_idxEnumNext += cNumberToSkipIn;
  631. if ( m_idxEnumNext >= m_idxNext )
  632. {
  633. m_idxEnumNext = m_idxNext;
  634. hr = STHR( S_FALSE );
  635. } // if:
  636. HRETURN( hr );
  637. } //*** CEnumPhysicalDisks::Skip
  638. //////////////////////////////////////////////////////////////////////////////
  639. //++
  640. //
  641. // CEnumPhysicalDisks::Reset
  642. //
  643. // Description:
  644. //
  645. // Arguments:
  646. //
  647. // Return Value:
  648. //
  649. // Remarks:
  650. // None.
  651. //
  652. //--
  653. //////////////////////////////////////////////////////////////////////////////
  654. STDMETHODIMP
  655. CEnumPhysicalDisks::Reset( void )
  656. {
  657. TraceFunc( "[IEnumClusCfgManagedResources]" );
  658. m_idxEnumNext = 0;
  659. HRETURN( S_OK );
  660. } //*** CEnumPhysicalDisks::Reset
  661. //////////////////////////////////////////////////////////////////////////////
  662. //++
  663. //
  664. // CEnumPhysicalDisks::Clone
  665. //
  666. // Description:
  667. //
  668. // Arguments:
  669. //
  670. // Return Value:
  671. //
  672. // Remarks:
  673. // None.
  674. //
  675. //--
  676. //////////////////////////////////////////////////////////////////////////////
  677. STDMETHODIMP
  678. CEnumPhysicalDisks::Clone(
  679. IEnumClusCfgManagedResources ** ppEnumClusCfgStorageDevicesOut
  680. )
  681. {
  682. TraceFunc( "[IEnumClusCfgManagedResources]" );
  683. HRESULT hr = S_OK;
  684. if ( ppEnumClusCfgStorageDevicesOut == NULL )
  685. {
  686. hr = THR( E_POINTER );
  687. STATUS_REPORT_REF( TASKID_Major_Find_Devices, TASKID_Minor_Clone_Enum_PhysDisk, IDS_ERROR_NULL_POINTER, IDS_ERROR_NULL_POINTER_REF, hr );
  688. goto Cleanup;
  689. } // if:
  690. hr = THR( E_NOTIMPL );
  691. Cleanup:
  692. HRETURN( hr );
  693. } //*** CEnumPhysicalDisks::Clone
  694. //////////////////////////////////////////////////////////////////////////////
  695. //++
  696. //
  697. // CEnumPhysicalDisks::Count
  698. //
  699. // Description:
  700. // Return the count of items in the Enum.
  701. //
  702. // Arguments:
  703. //
  704. // Return Value:
  705. //
  706. // Remarks:
  707. // None.
  708. //
  709. //--
  710. //////////////////////////////////////////////////////////////////////////////
  711. STDMETHODIMP
  712. CEnumPhysicalDisks::Count( DWORD * pnCountOut )
  713. {
  714. TraceFunc( "[IEnumClusCfgManagedResources]" );
  715. HRESULT hr = S_OK;
  716. if ( pnCountOut == NULL )
  717. {
  718. hr = THR( E_POINTER );
  719. goto Cleanup;
  720. } // if:
  721. if ( !m_fLoadedDevices )
  722. {
  723. hr = THR( HrLoadEnum() );
  724. if ( FAILED( hr ) )
  725. {
  726. goto Cleanup;
  727. } // if:
  728. } // if:
  729. *pnCountOut = m_cDiskCount;
  730. Cleanup:
  731. HRETURN( hr );
  732. } //*** CEnumPhysicalDisks::Count
  733. //*************************************************************************//
  734. /////////////////////////////////////////////////////////////////////////////
  735. // CEnumPhysicalDisks class -- Private Methods.
  736. /////////////////////////////////////////////////////////////////////////////
  737. //////////////////////////////////////////////////////////////////////////////
  738. //++
  739. //
  740. // CEnumPhysicalDisks::HrInit
  741. //
  742. // Description:
  743. // Initialize this component.
  744. //
  745. // Arguments:
  746. // None.
  747. //
  748. // Return Value:
  749. //
  750. //
  751. // Remarks:
  752. // None.
  753. //
  754. //--
  755. //////////////////////////////////////////////////////////////////////////////
  756. HRESULT
  757. CEnumPhysicalDisks::HrInit( void )
  758. {
  759. TraceFunc( "" );
  760. HRESULT hr = S_OK;
  761. // IUnknown
  762. Assert( m_cRef == 1 );
  763. HRETURN( hr );
  764. } //*** CEnumPhysicalDisks::HrInit
  765. /////////////////////////////////////////////////////////////////////////////
  766. //++
  767. //
  768. // CEnumPhysicalDisks::HrGetDisks
  769. //
  770. // Description:
  771. //
  772. // Arguments:
  773. //
  774. //
  775. // Return Value:
  776. //
  777. //
  778. // Remarks:
  779. // None.
  780. //
  781. //--
  782. //////////////////////////////////////////////////////////////////////////////
  783. HRESULT
  784. CEnumPhysicalDisks::HrGetDisks( void )
  785. {
  786. TraceFunc( "" );
  787. HRESULT hr = S_FALSE;
  788. BSTR bstrClass;
  789. IEnumWbemClassObject * pDisks = NULL;
  790. ULONG ulReturned;
  791. IWbemClassObject * pDisk = NULL;
  792. bstrClass = TraceSysAllocString( L"Win32_DiskDrive" );
  793. if ( bstrClass == NULL )
  794. {
  795. hr = THR( E_OUTOFMEMORY );
  796. STATUS_REPORT_REF( TASKID_Major_Find_Devices, TASKID_Minor_HrGetDisks, IDS_ERROR_OUTOFMEMORY, IDS_ERROR_OUTOFMEMORY_REF, hr );
  797. goto Cleanup;
  798. } // if:
  799. hr = THR( m_pIWbemServices->CreateInstanceEnum( bstrClass, WBEM_FLAG_SHALLOW, NULL, &pDisks ) );
  800. if ( FAILED( hr ) )
  801. {
  802. STATUS_REPORT_REF(
  803. TASKID_Major_Find_Devices
  804. , TASKID_Minor_WMI_Phys_Disks_Qry_Failed
  805. , IDS_ERROR_WMI_PHYS_DISKS_QRY_FAILED
  806. , IDS_ERROR_WMI_PHYS_DISKS_QRY_FAILED_REF
  807. , hr
  808. );
  809. goto Cleanup;
  810. } // if:
  811. for ( ; ; )
  812. {
  813. hr = pDisks->Next( WBEM_INFINITE, 1, &pDisk, &ulReturned );
  814. if ( ( hr == S_OK ) && ( ulReturned == 1 ) )
  815. {
  816. hr = STHR( HrLogDiskInfo( pDisk ) );
  817. if ( FAILED( hr ) )
  818. {
  819. goto Cleanup;
  820. } // if:
  821. hr = STHR( IsDiskSCSI( pDisk ) );
  822. if ( FAILED( hr ) )
  823. {
  824. goto Cleanup;
  825. } // if:
  826. if ( hr == S_OK )
  827. {
  828. hr = STHR( HrCreateAndAddDiskToArray( pDisk ) );
  829. if ( FAILED( hr ) )
  830. {
  831. goto Cleanup;
  832. } // if:
  833. } // if:
  834. pDisk->Release();
  835. pDisk = NULL;
  836. } // if:
  837. else if ( ( hr == S_FALSE ) && ( ulReturned == 0 ) )
  838. {
  839. hr = S_OK;
  840. break;
  841. } // else if:
  842. else
  843. {
  844. STATUS_REPORT_STRING_REF(
  845. TASKID_Major_Find_Devices
  846. , TASKID_Minor_WQL_Disk_Qry_Next_Failed
  847. , IDS_ERROR_WQL_QRY_NEXT_FAILED
  848. , bstrClass
  849. , IDS_ERROR_WQL_QRY_NEXT_FAILED_REF
  850. , hr
  851. );
  852. goto Cleanup;
  853. } // else:
  854. } // for:
  855. m_idxEnumNext = 0;
  856. m_fLoadedDevices = TRUE;
  857. goto Cleanup;
  858. Cleanup:
  859. if ( pDisk != NULL )
  860. {
  861. pDisk->Release();
  862. } // if:
  863. if ( pDisks != NULL )
  864. {
  865. pDisks->Release();
  866. } // if:
  867. TraceSysFreeString( bstrClass );
  868. HRETURN( hr );
  869. } //*** CEnumPhysicalDisks::HrGetDisks
  870. /////////////////////////////////////////////////////////////////////////////
  871. //++
  872. //
  873. // CEnumPhysicalDisks::HrCreateAndAddDiskToArray
  874. //
  875. // Description:
  876. // Create a IClusCfgStorageDevice object and add the passed in disk to
  877. // the array of punks that holds the disks.
  878. //
  879. // Arguments:
  880. //
  881. //
  882. // Return Value:
  883. // S_OK
  884. // Success
  885. //
  886. // E_OUTOFMEMORY
  887. // Couldn't allocate memeory.
  888. //
  889. // Remarks:
  890. // None.
  891. //
  892. //--
  893. //////////////////////////////////////////////////////////////////////////////
  894. HRESULT
  895. CEnumPhysicalDisks::HrCreateAndAddDiskToArray( IWbemClassObject * pDiskIn )
  896. {
  897. TraceFunc( "" );
  898. HRESULT hr = S_FALSE;
  899. IUnknown * punk = NULL;
  900. IClusCfgSetWbemObject * piccswo = NULL;
  901. bool fRetainObject = true;
  902. hr = THR( CPhysicalDisk::S_HrCreateInstance( &punk ) );
  903. if ( FAILED( hr ) )
  904. {
  905. goto Exit;
  906. } // if:
  907. punk = TraceInterface( L"CPhysicalDisk", IUnknown, punk, 1 );
  908. hr = THR( HrSetInitialize( punk, m_picccCallback, m_lcid ) );
  909. if ( FAILED( hr ) )
  910. {
  911. goto Cleanup;
  912. } // if:
  913. hr = THR( HrSetWbemServices( punk, m_pIWbemServices ) );
  914. if ( FAILED( hr ) )
  915. {
  916. goto Cleanup;
  917. } // if:
  918. hr = THR( punk->TypeSafeQI( IClusCfgSetWbemObject, &piccswo ) );
  919. if ( FAILED( hr ) )
  920. {
  921. goto Cleanup;
  922. } // if:
  923. hr = STHR( piccswo->SetWbemObject( pDiskIn, &fRetainObject ) );
  924. if ( FAILED( hr ) )
  925. {
  926. goto Cleanup;
  927. } // if:
  928. if ( fRetainObject )
  929. {
  930. hr = THR( HrAddDiskToArray( punk ) );
  931. } // if:
  932. Cleanup:
  933. if ( piccswo != NULL )
  934. {
  935. piccswo->Release();
  936. } // if:
  937. punk->Release();
  938. Exit:
  939. HRETURN( hr );
  940. } //*** CEnumPhysicalDisks::HrCreateAndAddDiskToArray
  941. /////////////////////////////////////////////////////////////////////////////
  942. //++
  943. //
  944. // CEnumPhysicalDisks::HrPruneSystemDisks
  945. //
  946. // Description:
  947. // Prune all system disks from the list. System disks are disks that
  948. // are booted, are running the OS, or have page files.
  949. //
  950. // Arguments:
  951. //
  952. //
  953. // Return Value:
  954. // S_OK
  955. // Success
  956. //
  957. // E_OUTOFMEMORY
  958. // Couldn't allocate memeory.
  959. //
  960. // Remarks:
  961. //
  962. //--
  963. //////////////////////////////////////////////////////////////////////////////
  964. HRESULT
  965. CEnumPhysicalDisks::HrPruneSystemDisks( void )
  966. {
  967. TraceFunc( "" );
  968. Assert( m_bstrSystemLogicalDisk != NULL );
  969. Assert( m_bstrBootLogicalDisk != NULL );
  970. HRESULT hr = S_OK;
  971. ULONG idx;
  972. ULONG ulSCSIBus;
  973. ULONG ulSCSIPort;
  974. IClusCfgPhysicalDiskProperties * piccpdp = NULL;
  975. IUnknown * punk;
  976. ULONG cRemoved = 0;
  977. ULONG cTemp = 0;
  978. bool fSystemAndBootTheSame;
  979. bool fPruneBus = false;
  980. fSystemAndBootTheSame = ( m_bstrSystemLogicalDisk != NULL )
  981. ? ( m_bstrBootLogicalDisk[ 0 ] == m_bstrSystemLogicalDisk[ 0 ] )
  982. : false;
  983. hr = STHR( HrIsSystemBusManaged() );
  984. if ( FAILED( hr ) )
  985. {
  986. goto Cleanup;
  987. } // if:
  988. //
  989. // If the system bus is not managed then we need to prune the disks on those buses
  990. // that contain system, boot, and pagefile disks.
  991. //
  992. if ( hr == S_FALSE )
  993. {
  994. fPruneBus = true;
  995. } // if:
  996. //
  997. // Prune the disks on the system buses. If the system disks are IDE they won't
  998. // be in the list.
  999. //
  1000. //
  1001. // Find the boot disk(s). Could be a volume with more than one physical disk.
  1002. //
  1003. for ( ; ; )
  1004. {
  1005. hr = STHR( HrFindDiskWithLogicalDisk( m_bstrBootLogicalDisk[ 0 ], &idx ) );
  1006. if ( FAILED( hr ) )
  1007. {
  1008. goto Cleanup;
  1009. } // if:
  1010. if ( hr == S_OK )
  1011. {
  1012. //
  1013. // Should we prune the whole bus, or just the boot disk itself?
  1014. //
  1015. if ( fPruneBus )
  1016. {
  1017. hr = THR( HrGetSCSIInfo( idx, &ulSCSIBus, &ulSCSIPort ) );
  1018. if ( FAILED( hr ) )
  1019. {
  1020. goto Cleanup;
  1021. } // if:
  1022. STATUS_REPORT( TASKID_Major_Find_Devices, TASKID_Minor_Pruning_Boot_Disk_Bus, IDS_INFO_PRUNING_BOOTDISK_BUS, hr );
  1023. hr = THR( HrPruneDisks(
  1024. ulSCSIBus
  1025. , ulSCSIPort
  1026. , &TASKID_Minor_Pruning_Boot_Disk_Bus
  1027. , IDS_INFO_BOOTDISK_PRUNED
  1028. , IDS_INFO_BOOTDISK_PRUNED_REF
  1029. , &cTemp
  1030. ) );
  1031. if ( FAILED( hr ) )
  1032. {
  1033. goto Cleanup;
  1034. } // if:
  1035. cRemoved += cTemp;
  1036. } // if:
  1037. else
  1038. {
  1039. RemoveDiskFromArray( idx );
  1040. cRemoved++;
  1041. } // else:
  1042. continue;
  1043. } // if:
  1044. break;
  1045. } // for:
  1046. //
  1047. // Prune the system disk bus if it is not the same as the boot disk bus.
  1048. //
  1049. if ( !fSystemAndBootTheSame )
  1050. {
  1051. if ( m_bstrSystemLogicalDisk != NULL )
  1052. {
  1053. Assert( m_bstrSystemWMIDeviceID == NULL );
  1054. hr = STHR( HrFindDiskWithLogicalDisk( m_bstrSystemLogicalDisk[ 0 ], &idx ) );
  1055. } // if:
  1056. else
  1057. {
  1058. Assert( m_bstrSystemLogicalDisk == NULL );
  1059. hr = STHR( HrFindDiskWithWMIDeviceID( m_bstrSystemWMIDeviceID, &idx ) );
  1060. } // else:
  1061. if ( FAILED( hr ) )
  1062. {
  1063. goto Cleanup;
  1064. } // if:
  1065. if ( hr == S_OK )
  1066. {
  1067. //
  1068. // Should we prune the whole bus, or just the system disk itself?
  1069. //
  1070. if ( fPruneBus )
  1071. {
  1072. hr = THR( HrGetSCSIInfo( idx, &ulSCSIBus, &ulSCSIPort ) );
  1073. if ( FAILED( hr ) )
  1074. {
  1075. goto Cleanup;
  1076. } // if:
  1077. STATUS_REPORT( TASKID_Major_Find_Devices, TASKID_Minor_Pruning_System_Disk_Bus, IDS_INFO_PRUNING_SYSTEMDISK_BUS, hr );
  1078. hr = THR( HrPruneDisks(
  1079. ulSCSIBus
  1080. , ulSCSIPort
  1081. , &TASKID_Minor_Pruning_System_Disk_Bus
  1082. , IDS_INFO_SYSTEMDISK_PRUNED
  1083. , IDS_INFO_SYSTEMDISK_PRUNED_REF
  1084. , &cTemp
  1085. ) );
  1086. if ( FAILED( hr ) )
  1087. {
  1088. goto Cleanup;
  1089. } // if:
  1090. cRemoved += cTemp;
  1091. } // if:
  1092. else
  1093. {
  1094. RemoveDiskFromArray( idx );
  1095. cRemoved++;
  1096. } // else:
  1097. } // if:
  1098. } // if:
  1099. //
  1100. // Now prune the busses that have page file disks on them.
  1101. //
  1102. hr = THR( HrPrunePageFileDiskBussess( fPruneBus, &cTemp ) );
  1103. if ( FAILED( hr ) )
  1104. {
  1105. goto Cleanup;
  1106. } // if:
  1107. cRemoved += cTemp;
  1108. //
  1109. // Now prune the bus that has a crash dump file disk.
  1110. //
  1111. hr = THR( HrPruneCrashDumpBus( fPruneBus, &cTemp ) );
  1112. if ( FAILED( hr ) )
  1113. {
  1114. goto Cleanup;
  1115. } // if:
  1116. cRemoved += cTemp;
  1117. //
  1118. // Now prune the off any remaining dynamic disks.
  1119. //
  1120. hr = THR( HrPruneDynamicDisks( &cTemp ) );
  1121. if ( FAILED( hr ) )
  1122. {
  1123. goto Cleanup;
  1124. } // if:
  1125. cRemoved += cTemp;
  1126. //
  1127. // Now prune the off any remaining GPT disks.
  1128. //
  1129. hr = THR( HrPruneGPTDisks( &cTemp ) );
  1130. if ( FAILED( hr ) )
  1131. {
  1132. goto Cleanup;
  1133. } // if:
  1134. cRemoved += cTemp;
  1135. //
  1136. // Last ditch effort to properly set the managed state of the remaining disks.
  1137. //
  1138. for ( idx = 0; ( cRemoved < m_idxNext ) && ( idx < m_idxNext ); idx++ )
  1139. {
  1140. punk = (*m_prgDisks)[ idx ]; // don't ref
  1141. if ( punk != NULL )
  1142. {
  1143. hr = THR( punk->TypeSafeQI( IClusCfgPhysicalDiskProperties, &piccpdp ) );
  1144. if ( FAILED( hr ) )
  1145. {
  1146. LOG_STATUS_REPORT( L"Could not query for the IClusCfgPhysicalDiskProperties interface.", hr );
  1147. goto Cleanup;
  1148. } // if:
  1149. //
  1150. // Give the disk a chance to figure out for itself if it should be managed.
  1151. //
  1152. hr = STHR( piccpdp->CanBeManaged() );
  1153. if ( FAILED( hr ) )
  1154. {
  1155. goto Cleanup;
  1156. } // if:
  1157. piccpdp->Release();
  1158. piccpdp = NULL;
  1159. } // if:
  1160. } // for:
  1161. //
  1162. // Minor optimization. If we removed all of the elements reset the enum next to 0.
  1163. //
  1164. if ( cRemoved == m_idxNext )
  1165. {
  1166. m_idxNext = 0;
  1167. } // if:
  1168. hr = S_OK;
  1169. Cleanup:
  1170. if ( piccpdp != NULL )
  1171. {
  1172. piccpdp->Release();
  1173. } // if:
  1174. HRETURN( hr );
  1175. } //*** CEnumPhysicalDisks::HrPruneSystemDisks
  1176. /////////////////////////////////////////////////////////////////////////////
  1177. //++
  1178. //
  1179. // CEnumPhysicalDisks::IsDiskSCSI
  1180. //
  1181. // Description:
  1182. //
  1183. // Arguments:
  1184. //
  1185. //
  1186. // Return Value:
  1187. // S_OK
  1188. // Disk is SCSI.
  1189. //
  1190. // S_FALSE
  1191. // Disk is not SCSI.
  1192. //
  1193. // E_OUTOFMEMORY
  1194. // Couldn't allocate memeory.
  1195. //
  1196. // Remarks:
  1197. //
  1198. //--
  1199. //////////////////////////////////////////////////////////////////////////////
  1200. HRESULT
  1201. CEnumPhysicalDisks::IsDiskSCSI( IWbemClassObject * pDiskIn )
  1202. {
  1203. TraceFunc( "" );
  1204. Assert( pDiskIn != NULL );
  1205. HRESULT hr;
  1206. VARIANT var;
  1207. VariantInit( &var );
  1208. hr = THR( HrGetWMIProperty( pDiskIn, L"InterfaceType", VT_BSTR, &var ) );
  1209. if ( SUCCEEDED( hr ) )
  1210. {
  1211. if ( ( NStringCchCompareCase( L"SCSI", RTL_NUMBER_OF( L"SCSI" ), var.bstrVal, SysStringLen( var.bstrVal ) + 1 ) == 0 ) )
  1212. {
  1213. hr = S_OK;
  1214. } // if:
  1215. else
  1216. {
  1217. hr = S_FALSE;
  1218. } // else:
  1219. } // if:
  1220. VariantClear( &var );
  1221. HRETURN( hr );
  1222. } //*** CEnumPhysicalDisks::IsDiskSCSI
  1223. /////////////////////////////////////////////////////////////////////////////
  1224. //++
  1225. //
  1226. // CEnumPhysicalDisks:HrAddDiskToArray
  1227. //
  1228. // Description:
  1229. // Add the passed in disk to the array of punks that holds the disks.
  1230. //
  1231. // Arguments:
  1232. //
  1233. //
  1234. // Return Value:
  1235. // S_OK
  1236. // Success
  1237. //
  1238. // E_OUTOFMEMORY
  1239. // Couldn't allocate memeory.
  1240. //
  1241. // Remarks:
  1242. // None.
  1243. //
  1244. //--
  1245. //////////////////////////////////////////////////////////////////////////////
  1246. HRESULT
  1247. CEnumPhysicalDisks::HrAddDiskToArray( IUnknown * punkIn )
  1248. {
  1249. TraceFunc( "" );
  1250. Assert( punkIn != NULL );
  1251. HRESULT hr = S_OK;
  1252. IUnknown * ((*prgpunks)[]) = NULL;
  1253. prgpunks = (IUnknown *((*)[])) TraceReAlloc( m_prgDisks, sizeof( IUnknown * ) * ( m_idxNext + 1 ), HEAP_ZERO_MEMORY );
  1254. if ( prgpunks == NULL )
  1255. {
  1256. hr = THR( E_OUTOFMEMORY );
  1257. STATUS_REPORT_REF( TASKID_Major_Find_Devices, TASKID_Minor_HrAddDiskToArray, IDS_ERROR_OUTOFMEMORY, IDS_ERROR_OUTOFMEMORY_REF, hr );
  1258. goto Cleanup;
  1259. } // if:
  1260. m_prgDisks = prgpunks;
  1261. (*m_prgDisks)[ m_idxNext++ ] = punkIn;
  1262. punkIn->AddRef();
  1263. m_cDiskCount += 1;
  1264. Cleanup:
  1265. HRETURN( hr );
  1266. } //*** CEnumPhysicalDisks::HrAddDiskToArray
  1267. /////////////////////////////////////////////////////////////////////////////
  1268. //++
  1269. //
  1270. // CEnumPhysicalDisks:HrFixupDisks
  1271. //
  1272. // Description:
  1273. // Tweak the disks to better reflect how they are managed by this node.
  1274. //
  1275. // Arguments:
  1276. // None.
  1277. //
  1278. // Return Value:
  1279. // S_OK
  1280. // Success.
  1281. //
  1282. // Win32 Error
  1283. // something failed.
  1284. //
  1285. // Remarks:
  1286. // None.
  1287. //
  1288. //--
  1289. //////////////////////////////////////////////////////////////////////////////
  1290. HRESULT
  1291. CEnumPhysicalDisks::HrFixupDisks( void )
  1292. {
  1293. TraceFunc( "" );
  1294. HRESULT hr = S_OK;
  1295. BSTR bstrLocalNetBIOSName = NULL;
  1296. //
  1297. // Get netbios name for clusapi calls.
  1298. //
  1299. hr = THR( HrGetComputerName( ComputerNameNetBIOS, &bstrLocalNetBIOSName, TRUE ) );
  1300. if ( FAILED( hr ) )
  1301. {
  1302. goto Cleanup;
  1303. } // if:
  1304. //
  1305. // If the cluster service is running then load any physical disk
  1306. // resources that we own.
  1307. //
  1308. hr = STHR( HrIsClusterServiceRunning() );
  1309. if ( hr == S_OK )
  1310. {
  1311. hr = THR( HrEnumNodeResources( bstrLocalNetBIOSName ) );
  1312. }
  1313. else if ( hr == S_FALSE )
  1314. {
  1315. hr = S_OK;
  1316. } // else:
  1317. Cleanup:
  1318. TraceSysFreeString( bstrLocalNetBIOSName );
  1319. HRETURN( hr );
  1320. } //*** CEnumPhysicalDisks::HrFixupDisks
  1321. /////////////////////////////////////////////////////////////////////////////
  1322. //++
  1323. //
  1324. // CEnumPhysicalDisks:HrNodeResourceCallback
  1325. //
  1326. // Description:
  1327. // Called by CClusterUtils::HrEnumNodeResources() when it finds a
  1328. // resource for this node.
  1329. //
  1330. // Arguments:
  1331. //
  1332. //
  1333. // Return Value:
  1334. // S_OK
  1335. // Success.
  1336. //
  1337. // Win32 Error
  1338. // something failed.
  1339. //
  1340. // Remarks:
  1341. // None.
  1342. //
  1343. //--
  1344. //////////////////////////////////////////////////////////////////////////////
  1345. HRESULT
  1346. CEnumPhysicalDisks::HrNodeResourceCallback(
  1347. HCLUSTER hClusterIn,
  1348. HRESOURCE hResourceIn
  1349. )
  1350. {
  1351. TraceFunc( "" );
  1352. HRESULT hr = S_OK;
  1353. CLUS_SCSI_ADDRESS csa;
  1354. DWORD dwSignature;
  1355. BOOL fIsQuorum;
  1356. BSTR bstrResourceName = NULL;
  1357. hr = STHR( HrIsResourceOfType( hResourceIn, L"Physical Disk" ) );
  1358. if ( FAILED( hr ) )
  1359. {
  1360. goto Cleanup;
  1361. } // if:
  1362. //
  1363. // If this resource is not a physical disk then we simply want to
  1364. // skip it.
  1365. //
  1366. if ( hr == S_FALSE )
  1367. {
  1368. goto Cleanup;
  1369. } // if:
  1370. hr = STHR( HrIsCoreResource( hResourceIn ) );
  1371. if ( FAILED( hr ) )
  1372. {
  1373. goto Cleanup;
  1374. } // if:
  1375. fIsQuorum = ( hr == S_OK );
  1376. hr = THR( HrGetClusterDiskInfo( hClusterIn, hResourceIn, &csa, &dwSignature ) );
  1377. if ( FAILED( hr ) )
  1378. {
  1379. goto Cleanup;
  1380. } // if:
  1381. hr = THR( HrGetClusterProperties( hResourceIn, &bstrResourceName ) );
  1382. if ( FAILED( hr ) )
  1383. {
  1384. goto Cleanup;
  1385. } // if:
  1386. hr = THR( HrSetThisDiskToBeManaged( csa.TargetId, csa.Lun, fIsQuorum, bstrResourceName, dwSignature ) );
  1387. if ( FAILED( hr ) )
  1388. {
  1389. goto Cleanup;
  1390. } // if:
  1391. Cleanup:
  1392. TraceSysFreeString( bstrResourceName );
  1393. HRETURN( hr );
  1394. } //*** CEnumPhysicalDisks::HrNodeResourceCallback
  1395. /////////////////////////////////////////////////////////////////////////////
  1396. //++
  1397. //
  1398. // CEnumPhysicalDisks:HrGetClusterDiskInfo
  1399. //
  1400. // Description:
  1401. //
  1402. //
  1403. // Arguments:
  1404. //
  1405. //
  1406. // Return Value:
  1407. // S_OK
  1408. // Success.
  1409. //
  1410. // Win32 Error
  1411. // something failed.
  1412. //
  1413. // Remarks:
  1414. // None.
  1415. //
  1416. //--
  1417. //////////////////////////////////////////////////////////////////////////////
  1418. HRESULT
  1419. CEnumPhysicalDisks::HrGetClusterDiskInfo(
  1420. HCLUSTER hClusterIn,
  1421. HRESOURCE hResourceIn,
  1422. CLUS_SCSI_ADDRESS * pcsaOut,
  1423. DWORD * pdwSignatureOut
  1424. )
  1425. {
  1426. TraceFunc( "" );
  1427. HRESULT hr = S_OK;
  1428. DWORD sc;
  1429. CClusPropValueList cpvl;
  1430. CLUSPROP_BUFFER_HELPER cbhValue = { NULL };
  1431. sc = TW32( cpvl.ScGetResourceValueList( hResourceIn, CLUSCTL_RESOURCE_STORAGE_GET_DISK_INFO ) );
  1432. if ( sc != ERROR_SUCCESS )
  1433. {
  1434. hr = HRESULT_FROM_WIN32( sc );
  1435. goto Cleanup;
  1436. } // if:
  1437. sc = TW32( cpvl.ScMoveToFirstValue() );
  1438. if ( sc != ERROR_SUCCESS )
  1439. {
  1440. hr = HRESULT_FROM_WIN32( sc );
  1441. goto Cleanup;
  1442. } // if:
  1443. for ( ; ; )
  1444. {
  1445. cbhValue = cpvl;
  1446. switch ( cbhValue.pSyntax->dw )
  1447. {
  1448. case CLUSPROP_SYNTAX_PARTITION_INFO :
  1449. {
  1450. break;
  1451. } // case: CLUSPROP_SYNTAX_PARTITION_INFO
  1452. case CLUSPROP_SYNTAX_DISK_SIGNATURE :
  1453. {
  1454. *pdwSignatureOut = cbhValue.pDiskSignatureValue->dw;
  1455. break;
  1456. } // case: CLUSPROP_SYNTAX_DISK_SIGNATURE
  1457. case CLUSPROP_SYNTAX_SCSI_ADDRESS :
  1458. {
  1459. pcsaOut->dw = cbhValue.pScsiAddressValue->dw;
  1460. break;
  1461. } // case: CLUSPROP_SYNTAXscSI_ADDRESS
  1462. case CLUSPROP_SYNTAX_DISK_NUMBER :
  1463. {
  1464. break;
  1465. } // case: CLUSPROP_SYNTAX_DISK_NUMBER
  1466. } // switch:
  1467. sc = cpvl.ScMoveToNextValue();
  1468. if ( sc == ERROR_SUCCESS )
  1469. {
  1470. continue;
  1471. } // if:
  1472. if ( sc == ERROR_NO_MORE_ITEMS )
  1473. {
  1474. break;
  1475. } // if: error occurred moving to the next value
  1476. hr = HRESULT_FROM_WIN32( TW32( sc ) );
  1477. goto Cleanup;
  1478. } // for:
  1479. Cleanup:
  1480. HRETURN( hr );
  1481. } //*** CEnumPhysicalDisks::HrGetClusterDiskInfo
  1482. /////////////////////////////////////////////////////////////////////////////
  1483. //++
  1484. //
  1485. // CEnumPhysicalDisks:HrSetThisDiskToBeManaged
  1486. //
  1487. // Description:
  1488. //
  1489. //
  1490. // Arguments:
  1491. //
  1492. //
  1493. // Return Value:
  1494. // S_OK
  1495. // Success.
  1496. //
  1497. // Win32 Error
  1498. // something failed.
  1499. //
  1500. // Remarks:
  1501. // None.
  1502. //
  1503. //--
  1504. //////////////////////////////////////////////////////////////////////////////
  1505. HRESULT
  1506. CEnumPhysicalDisks::HrSetThisDiskToBeManaged(
  1507. ULONG ulSCSITidIn
  1508. , ULONG ulSCSILunIn
  1509. , BOOL fIsQuorumIn
  1510. , BSTR bstrResourceNameIn
  1511. , DWORD dwSignatureIn
  1512. )
  1513. {
  1514. TraceFunc( "" );
  1515. HRESULT hr = S_OK;
  1516. ULONG idx;
  1517. IUnknown * punk = NULL;
  1518. IClusCfgManagedResourceInfo * piccmri = NULL;
  1519. WCHAR sz[ 64 ];
  1520. BSTR bstrUID = NULL;
  1521. DWORD dwSignature;
  1522. IClusCfgPhysicalDiskProperties * piccpdp = NULL;
  1523. hr = THR( StringCchPrintfW( sz, ARRAYSIZE( sz ), L"SCSI Tid %ld, SCSI Lun %ld", ulSCSITidIn, ulSCSILunIn ) );
  1524. if ( FAILED( hr ) )
  1525. {
  1526. goto Cleanup;
  1527. } // if:
  1528. //
  1529. // Find the disk that has the passes in TID and Lun and set it
  1530. // to be managed.
  1531. //
  1532. for ( idx = 0; idx < m_idxNext; idx++ )
  1533. {
  1534. punk = (*m_prgDisks)[ idx ]; // don't ref
  1535. if ( punk != NULL )
  1536. {
  1537. hr = THR( punk->TypeSafeQI( IClusCfgManagedResourceInfo, &piccmri ) );
  1538. if ( FAILED( hr ) )
  1539. {
  1540. goto Cleanup;
  1541. } // if:
  1542. hr = THR( piccmri->GetUID( &bstrUID ) );
  1543. if ( FAILED( hr ) )
  1544. {
  1545. goto Cleanup;
  1546. } // if:
  1547. TraceMemoryAddBSTR( bstrUID );
  1548. if ( NStringCchCompareNoCase( bstrUID, SysStringLen( bstrUID ) + 1, sz, RTL_NUMBER_OF( sz ) ) == 0 )
  1549. {
  1550. hr = THR( piccmri->TypeSafeQI( IClusCfgPhysicalDiskProperties, &piccpdp ) );
  1551. if ( FAILED( hr ) )
  1552. {
  1553. goto Cleanup;
  1554. } // if:
  1555. hr = THR( piccpdp->HrGetSignature( &dwSignature ) );
  1556. if ( FAILED( hr ) )
  1557. {
  1558. goto Cleanup;
  1559. } // if:
  1560. hr = THR( piccpdp->HrSetFriendlyName( bstrResourceNameIn ) );
  1561. if ( FAILED( hr ) )
  1562. {
  1563. goto Cleanup;
  1564. } // if:
  1565. piccpdp->Release();
  1566. piccpdp = NULL;
  1567. //
  1568. // May want to do more with this later...
  1569. //
  1570. Assert( dwSignatureIn == dwSignature );
  1571. hr = THR( piccmri->SetManaged( TRUE ) );
  1572. if ( FAILED( hr ) )
  1573. {
  1574. goto Cleanup;
  1575. } // if:
  1576. hr = THR( piccmri->SetQuorumResource( fIsQuorumIn ) );
  1577. if ( FAILED( hr ) )
  1578. {
  1579. goto Cleanup;
  1580. } // if:
  1581. break;
  1582. } // if:
  1583. TraceSysFreeString( bstrUID );
  1584. bstrUID = NULL;
  1585. piccmri->Release();
  1586. piccmri = NULL;
  1587. } // if:
  1588. } // for:
  1589. Cleanup:
  1590. if ( piccpdp != NULL )
  1591. {
  1592. piccpdp->Release();
  1593. } // if:
  1594. if ( piccmri != NULL )
  1595. {
  1596. piccmri->Release();
  1597. } // if:
  1598. TraceSysFreeString( bstrUID );
  1599. HRETURN( hr );
  1600. } //*** CEnumPhysicalDisks::HrSetThisDiskToBeManaged
  1601. /////////////////////////////////////////////////////////////////////////////
  1602. //++
  1603. //
  1604. // CEnumPhysicalDisks:HrFindDiskWithLogicalDisk
  1605. //
  1606. // Description:
  1607. // Find the disk with the passed in logical disk ID.
  1608. //
  1609. // Arguments:
  1610. // None.
  1611. //
  1612. // Return Value:
  1613. // S_OK
  1614. // Success. Found the disk.
  1615. //
  1616. // S_FALSE
  1617. // Success. Did not find the disk.
  1618. //
  1619. // Win32 Error
  1620. // something failed.
  1621. //
  1622. // Remarks:
  1623. // None.
  1624. //
  1625. //--
  1626. //////////////////////////////////////////////////////////////////////////////
  1627. HRESULT
  1628. CEnumPhysicalDisks::HrFindDiskWithLogicalDisk(
  1629. WCHAR cLogicalDiskIn,
  1630. ULONG * pidxDiskOut
  1631. )
  1632. {
  1633. TraceFunc( "" );
  1634. Assert( pidxDiskOut != NULL );
  1635. HRESULT hr = S_OK;
  1636. IClusCfgPhysicalDiskProperties * piccpdp = NULL;
  1637. ULONG idx;
  1638. bool fFoundIt = false;
  1639. IUnknown * punk;
  1640. for ( idx = 0; idx < m_idxNext; idx++ )
  1641. {
  1642. punk = (*m_prgDisks)[ idx ]; // don't ref
  1643. if ( punk != NULL )
  1644. {
  1645. hr = THR( punk->TypeSafeQI( IClusCfgPhysicalDiskProperties, &piccpdp ) );
  1646. if ( FAILED( hr ) )
  1647. {
  1648. goto Cleanup;
  1649. } // if:
  1650. hr = STHR( piccpdp->IsThisLogicalDisk( cLogicalDiskIn ) );
  1651. if ( FAILED( hr ) )
  1652. {
  1653. goto Cleanup;
  1654. } // if:
  1655. if ( hr == S_OK )
  1656. {
  1657. fFoundIt = true;
  1658. break;
  1659. } // if:
  1660. piccpdp->Release();
  1661. piccpdp = NULL;
  1662. } // if:
  1663. } // for:
  1664. if ( !fFoundIt )
  1665. {
  1666. hr = S_FALSE;
  1667. } // if:
  1668. if ( pidxDiskOut != NULL )
  1669. {
  1670. *pidxDiskOut = idx;
  1671. } // if:
  1672. Cleanup:
  1673. if ( piccpdp != NULL )
  1674. {
  1675. piccpdp->Release();
  1676. } // if:
  1677. HRETURN( hr );
  1678. } //*** CEnumPhysicalDisks::HrFindDiskWithLogicalDisk
  1679. /////////////////////////////////////////////////////////////////////////////
  1680. //++
  1681. //
  1682. // CEnumPhysicalDisks:HrGetSCSIInfo
  1683. //
  1684. // Description:
  1685. // Get the SCSI info for the disk at the passed in index.
  1686. //
  1687. // Arguments:
  1688. // None.
  1689. //
  1690. // Return Value:
  1691. // S_OK
  1692. // Success.
  1693. //
  1694. // Win32 Error
  1695. // something failed.
  1696. //
  1697. // Remarks:
  1698. // None.
  1699. //
  1700. //--
  1701. //////////////////////////////////////////////////////////////////////////////
  1702. HRESULT
  1703. CEnumPhysicalDisks::HrGetSCSIInfo(
  1704. ULONG idxDiskIn,
  1705. ULONG * pulSCSIBusOut,
  1706. ULONG * pulSCSIPortOut
  1707. )
  1708. {
  1709. TraceFunc( "" );
  1710. Assert( pulSCSIBusOut != NULL );
  1711. Assert( pulSCSIPortOut != NULL );
  1712. HRESULT hr = S_OK;
  1713. IClusCfgPhysicalDiskProperties * piccpdp = NULL;
  1714. hr = THR( ((*m_prgDisks)[ idxDiskIn ])->TypeSafeQI( IClusCfgPhysicalDiskProperties, &piccpdp ) );
  1715. if ( FAILED( hr ) )
  1716. {
  1717. goto Cleanup;
  1718. } // if:
  1719. hr = THR( piccpdp->HrGetSCSIBus( pulSCSIBusOut ) );
  1720. if ( FAILED( hr ) )
  1721. {
  1722. goto Cleanup;
  1723. } // if:
  1724. hr = THR( piccpdp->HrGetSCSIPort( pulSCSIPortOut ) );
  1725. Cleanup:
  1726. if ( piccpdp != NULL )
  1727. {
  1728. piccpdp->Release();
  1729. } // if:
  1730. HRETURN( hr );
  1731. } //*** CEnumPhysicalDisks::HrGetSCSIInfo
  1732. /////////////////////////////////////////////////////////////////////////////
  1733. //++
  1734. //
  1735. // CEnumPhysicalDisks:HrPruneDisks
  1736. //
  1737. // Description:
  1738. // Get the SCSI info for the disk at the passed in index.
  1739. //
  1740. // Arguments:
  1741. // None.
  1742. //
  1743. // Return Value:
  1744. // S_OK
  1745. // Success.
  1746. //
  1747. // Win32 Error
  1748. // something failed.
  1749. //
  1750. // Remarks:
  1751. // None.
  1752. //
  1753. //--
  1754. //////////////////////////////////////////////////////////////////////////////
  1755. HRESULT
  1756. CEnumPhysicalDisks::HrPruneDisks(
  1757. ULONG ulSCSIBusIn
  1758. , ULONG ulSCSIPortIn
  1759. , const GUID * pcguidMajorIdIn
  1760. , int nMsgIdIn
  1761. , int nRefIdIn
  1762. , ULONG * pulRemovedOut
  1763. )
  1764. {
  1765. TraceFunc( "" );
  1766. Assert( pulRemovedOut != NULL );
  1767. HRESULT hr = S_OK;
  1768. IClusCfgPhysicalDiskProperties * piccpdp = NULL;
  1769. ULONG idx;
  1770. IUnknown * punk;
  1771. ULONG ulSCSIBus;
  1772. ULONG ulSCSIPort;
  1773. ULONG cRemoved = 0;
  1774. for ( idx = 0; idx < m_idxNext; idx++ )
  1775. {
  1776. punk = (*m_prgDisks)[ idx ]; // don't ref
  1777. if ( punk != NULL )
  1778. {
  1779. hr = THR( punk->TypeSafeQI( IClusCfgPhysicalDiskProperties, &piccpdp ) );
  1780. if ( FAILED( hr ) )
  1781. {
  1782. goto Cleanup;
  1783. } // if:
  1784. hr = THR( piccpdp->HrGetSCSIBus( &ulSCSIBus ) );
  1785. if ( FAILED( hr ) )
  1786. {
  1787. goto Cleanup;
  1788. } // if:
  1789. hr = THR( piccpdp->HrGetSCSIPort( &ulSCSIPort ) );
  1790. if ( FAILED( hr ) )
  1791. {
  1792. goto Cleanup;
  1793. } // if:
  1794. if ( ( ulSCSIBusIn == ulSCSIBus ) && ( ulSCSIPortIn == ulSCSIPort ) )
  1795. {
  1796. BSTR bstr = NULL;
  1797. IClusCfgManagedResourceInfo * piccmri = NULL;
  1798. HRESULT hrTemp;
  1799. CLSID clsidMinorId;
  1800. hrTemp = THR( CoCreateGuid( &clsidMinorId ) );
  1801. if ( FAILED( hrTemp ) )
  1802. {
  1803. LogMsg( L"[SRV] Could not create a guid for a pruning disk minor task ID" );
  1804. clsidMinorId = IID_NULL;
  1805. } // if:
  1806. LogPrunedDisk( punk, ulSCSIBusIn, ulSCSIPortIn );
  1807. THR( ((*m_prgDisks)[ idx ])->TypeSafeQI( IClusCfgManagedResourceInfo, &piccmri ) );
  1808. THR( piccmri->GetName( &bstr ) );
  1809. if ( piccmri != NULL )
  1810. {
  1811. piccmri->Release();
  1812. } // if:
  1813. TraceMemoryAddBSTR( bstr );
  1814. STATUS_REPORT_STRING_REF( *pcguidMajorIdIn, clsidMinorId, nMsgIdIn, bstr != NULL ? bstr : L"????", nRefIdIn, hr );
  1815. RemoveDiskFromArray( idx );
  1816. cRemoved++;
  1817. TraceSysFreeString( bstr );
  1818. } // if:
  1819. piccpdp->Release();
  1820. piccpdp = NULL;
  1821. } // if:
  1822. } // for:
  1823. if ( pulRemovedOut != NULL )
  1824. {
  1825. *pulRemovedOut = cRemoved;
  1826. } // if:
  1827. Cleanup:
  1828. if ( piccpdp != NULL )
  1829. {
  1830. piccpdp->Release();
  1831. } // if:
  1832. HRETURN( hr );
  1833. } //*** CEnumPhysicalDisks::HrPruneDisks
  1834. /////////////////////////////////////////////////////////////////////////////
  1835. //++
  1836. //
  1837. // CEnumPhysicalDisks:LogPrunedDisk
  1838. //
  1839. // Description:
  1840. // Get the SCSI info for the disk at the passed in index.
  1841. //
  1842. // Arguments:
  1843. // None.
  1844. //
  1845. // Return Value:
  1846. // S_OK
  1847. // Success.
  1848. //
  1849. // Win32 Error
  1850. // something failed.
  1851. //
  1852. // Remarks:
  1853. // None.
  1854. //
  1855. //--
  1856. //////////////////////////////////////////////////////////////////////////////
  1857. void
  1858. CEnumPhysicalDisks::LogPrunedDisk(
  1859. IUnknown * punkIn,
  1860. ULONG ulSCSIBusIn,
  1861. ULONG ulSCSIPortIn
  1862. )
  1863. {
  1864. TraceFunc( "" );
  1865. Assert( punkIn != NULL );
  1866. HRESULT hr = S_OK;
  1867. IClusCfgManagedResourceInfo * piccmri = NULL;
  1868. IClusCfgPhysicalDiskProperties * piccpdp = NULL;
  1869. BSTR bstrName = NULL;
  1870. BSTR bstrUID = NULL;
  1871. BSTR bstr = NULL;
  1872. hr = THR( punkIn->TypeSafeQI( IClusCfgManagedResourceInfo, &piccmri ) );
  1873. if ( SUCCEEDED( hr ) )
  1874. {
  1875. hr = THR( piccmri->GetUID( &bstrUID ) );
  1876. piccmri->Release();
  1877. } // if:
  1878. if ( FAILED( hr ) )
  1879. {
  1880. bstrUID = TraceSysAllocString( L"<Unknown>" );
  1881. } // if:
  1882. else
  1883. {
  1884. TraceMemoryAddBSTR( bstrUID );
  1885. } // else:
  1886. hr = THR( punkIn->TypeSafeQI( IClusCfgPhysicalDiskProperties, &piccpdp ) );
  1887. if ( SUCCEEDED( hr ) )
  1888. {
  1889. hr = THR( piccpdp->HrGetDeviceID( &bstrName ) );
  1890. piccpdp->Release();
  1891. } // if:
  1892. if ( FAILED( hr ) )
  1893. {
  1894. bstrName = TraceSysAllocString( L"<Unknown>" );
  1895. } // if:
  1896. hr = THR( HrFormatStringIntoBSTR(
  1897. L"Pruning SCSI disk '%1!ws!', on Bus '%2!d!' and Port '%3!d!'; at '%4!ws!'"
  1898. , &bstr
  1899. , bstrName
  1900. , ulSCSIBusIn
  1901. , ulSCSIPortIn
  1902. , bstrUID
  1903. ) );
  1904. if ( FAILED( hr ) )
  1905. {
  1906. goto Cleanup;
  1907. } // if:
  1908. LOG_STATUS_REPORT( bstr, hr );
  1909. Cleanup:
  1910. TraceSysFreeString( bstrName );
  1911. TraceSysFreeString( bstrUID );
  1912. TraceSysFreeString( bstr );
  1913. TraceFuncExit();
  1914. } //*** CEnumPhysicalDisks::LogPrunedDisk
  1915. /////////////////////////////////////////////////////////////////////////////
  1916. //++
  1917. //
  1918. // CEnumPhysicalDisks:HrIsLogicalDiskNTFS
  1919. //
  1920. // Description:
  1921. // Is the passed in logical disk NTFS?
  1922. //
  1923. // Arguments:
  1924. // bstrLogicalDiskIn
  1925. //
  1926. // Return Value:
  1927. // S_OK
  1928. // The disk is NTFS.
  1929. //
  1930. // S_FALSE
  1931. // The disk is not NTFS.
  1932. //
  1933. // Win32 Error
  1934. // something failed.
  1935. //
  1936. // Remarks:
  1937. // None.
  1938. //
  1939. //--
  1940. //////////////////////////////////////////////////////////////////////////////
  1941. HRESULT
  1942. CEnumPhysicalDisks::HrIsLogicalDiskNTFS( BSTR bstrLogicalDiskIn )
  1943. {
  1944. TraceFunc1( "bstrLogicalDiskIn = '%ls'", bstrLogicalDiskIn == NULL ? L"<null>" : bstrLogicalDiskIn );
  1945. Assert( bstrLogicalDiskIn != NULL );
  1946. HRESULT hr = S_OK;
  1947. IWbemClassObject * pLogicalDisk = NULL;
  1948. BSTR bstrPath = NULL;
  1949. WCHAR sz[ 64 ];
  1950. VARIANT var;
  1951. size_t cch;
  1952. VariantInit( &var );
  1953. cch = wcslen( bstrLogicalDiskIn );
  1954. if ( cch > 3 )
  1955. {
  1956. hr = THR( E_INVALIDARG );
  1957. STATUS_REPORT_REF( TASKID_Major_Find_Devices, TASKID_Minor_HrIsLogicalDiskNTFS_InvalidArg, IDS_ERROR_INVALIDARG, IDS_ERROR_INVALIDARG_REF, hr );
  1958. goto Cleanup;
  1959. } // if:
  1960. //
  1961. // truncate off any trailing \'s
  1962. //
  1963. if ( bstrLogicalDiskIn[ cch - 1 ] == L'\\' )
  1964. {
  1965. bstrLogicalDiskIn[ cch - 1 ] = '\0';
  1966. } // if:
  1967. //
  1968. // If we have just the logical disk without the trailing colon...
  1969. //
  1970. if ( wcslen( bstrLogicalDiskIn ) == 1 )
  1971. {
  1972. hr = THR( StringCchPrintfW( sz, ARRAYSIZE( sz ), L"Win32_LogicalDisk.DeviceID=\"%ws:\"", bstrLogicalDiskIn ) );
  1973. } // if:
  1974. else
  1975. {
  1976. hr = THR( StringCchPrintfW( sz, ARRAYSIZE( sz ), L"Win32_LogicalDisk.DeviceID=\"%ws\"", bstrLogicalDiskIn ) );
  1977. } // else:
  1978. if ( FAILED( hr ) )
  1979. {
  1980. goto Cleanup;
  1981. } // if:
  1982. bstrPath = TraceSysAllocString( sz );
  1983. if ( bstrPath == NULL )
  1984. {
  1985. hr = THR( E_OUTOFMEMORY );
  1986. STATUS_REPORT_REF( TASKID_Major_Find_Devices, TASKID_Minor_HrIsLogicalDiskNTFS, IDS_ERROR_OUTOFMEMORY, IDS_ERROR_OUTOFMEMORY_REF, hr );
  1987. } // if:
  1988. hr = THR( m_pIWbemServices->GetObject( bstrPath, WBEM_FLAG_RETURN_WBEM_COMPLETE, NULL, &pLogicalDisk, NULL ) );
  1989. if ( FAILED( hr ) )
  1990. {
  1991. STATUS_REPORT_STRING_REF(
  1992. TASKID_Major_Find_Devices
  1993. , TASKID_Minor_WMI_Get_LogicalDisk_Failed
  1994. , IDS_ERROR_WMI_GET_LOGICALDISK_FAILED
  1995. , bstrLogicalDiskIn
  1996. , IDS_ERROR_WMI_GET_LOGICALDISK_FAILED_REF
  1997. , hr
  1998. );
  1999. goto Cleanup;
  2000. } // if:
  2001. hr = THR( HrGetWMIProperty( pLogicalDisk, L"FileSystem", VT_BSTR, &var ) );
  2002. if (FAILED( hr ) )
  2003. {
  2004. goto Cleanup;
  2005. } // if:
  2006. CharUpper( var.bstrVal );
  2007. if ( NStringCchCompareCase( var.bstrVal, SysStringLen( var.bstrVal ) + 1, L"NTFS", RTL_NUMBER_OF( L"NTFS" ) ) != 0 )
  2008. {
  2009. hr = S_FALSE;
  2010. } // if:
  2011. Cleanup:
  2012. if ( pLogicalDisk != NULL )
  2013. {
  2014. pLogicalDisk->Release();
  2015. } // if:
  2016. VariantClear( &var );
  2017. TraceSysFreeString( bstrPath );
  2018. HRETURN( hr );
  2019. } //*** CEnumPhysicalDisks::HrIsLogicalDiskNTFS
  2020. /////////////////////////////////////////////////////////////////////////////
  2021. //++
  2022. //
  2023. // CEnumPhysicalDisks:HrLogDiskInfo
  2024. //
  2025. // Description:
  2026. // Write the info about this disk into the log.
  2027. //
  2028. // Arguments:
  2029. // pDiskIn
  2030. //
  2031. // Return Value:
  2032. // S_OK
  2033. //
  2034. // Win32 Error
  2035. // something failed.
  2036. //
  2037. // Remarks:
  2038. // None.
  2039. //
  2040. //--
  2041. //////////////////////////////////////////////////////////////////////////////
  2042. HRESULT
  2043. CEnumPhysicalDisks::HrLogDiskInfo( IWbemClassObject * pDiskIn )
  2044. {
  2045. TraceFunc( "" );
  2046. Assert( pDiskIn != NULL );
  2047. HRESULT hr = S_OK;
  2048. VARIANT varDeviceID;
  2049. VARIANT varSCSIBus;
  2050. VARIANT varSCSIPort;
  2051. VARIANT varSCSILun;
  2052. VARIANT varSCSITid;
  2053. BSTR bstr = NULL;
  2054. VariantInit( &varDeviceID );
  2055. VariantInit( &varSCSIBus );
  2056. VariantInit( &varSCSIPort );
  2057. VariantInit( &varSCSILun );
  2058. VariantInit( &varSCSITid );
  2059. hr = THR( HrGetWMIProperty( pDiskIn, L"DeviceID", VT_BSTR, &varDeviceID ) );
  2060. if ( FAILED( hr ) )
  2061. {
  2062. goto Cleanup;
  2063. } // if:
  2064. hr = STHR( IsDiskSCSI( pDiskIn ) );
  2065. if ( FAILED( hr ) )
  2066. {
  2067. goto Cleanup;
  2068. } // if:
  2069. //
  2070. // Disk is SCSI...
  2071. //
  2072. if ( hr == S_OK )
  2073. {
  2074. hr = THR( HrGetWMIProperty( pDiskIn, L"SCSIBus", VT_I4, &varSCSIBus ) );
  2075. if ( FAILED( hr ) )
  2076. {
  2077. goto Cleanup;
  2078. } // if:
  2079. hr = THR( HrGetWMIProperty( pDiskIn, L"SCSITargetId", VT_I4, &varSCSITid ) );
  2080. if ( FAILED( hr ) )
  2081. {
  2082. goto Cleanup;
  2083. } // if:
  2084. hr = THR( HrGetWMIProperty( pDiskIn, L"SCSILogicalUnit", VT_I4, &varSCSILun ) );
  2085. if ( FAILED( hr ) )
  2086. {
  2087. goto Cleanup;
  2088. } // if:
  2089. hr = THR( HrGetWMIProperty( pDiskIn, L"SCSIPort", VT_I4, &varSCSIPort ) );
  2090. if ( FAILED( hr ) )
  2091. {
  2092. goto Cleanup;
  2093. } // if:
  2094. hr = THR( HrFormatStringIntoBSTR(
  2095. L"Found SCSI disk '%1!ws!' on Bus '%2!d!' and Port '%3!d!'; at TID '%4!d!' and LUN '%5!d!'"
  2096. , &bstr
  2097. , varDeviceID.bstrVal
  2098. , varSCSIBus.iVal
  2099. , varSCSIPort.iVal
  2100. , varSCSITid.iVal
  2101. , varSCSILun.iVal
  2102. ) );
  2103. if ( FAILED( hr ) )
  2104. {
  2105. goto Cleanup;
  2106. } // if:
  2107. LOG_STATUS_REPORT( bstr, hr );
  2108. } // if:
  2109. else
  2110. {
  2111. HRESULT hrTemp;
  2112. CLSID clsidMinorId;
  2113. hrTemp = THR( CoCreateGuid( &clsidMinorId ) );
  2114. if ( FAILED( hrTemp ) )
  2115. {
  2116. LogMsg( L"[SRV] Could not create a guid for a non-scsi disk minor task ID" );
  2117. clsidMinorId = IID_NULL;
  2118. } // if:
  2119. //
  2120. // Reset hr to S_OK since we don't want a yellow bang in the UI. Finding non-scsi disks is expected
  2121. // and should cause as little concern as possible.
  2122. //
  2123. hr = S_OK;
  2124. STATUS_REPORT_REF( TASKID_Major_Find_Devices, TASKID_Minor_Non_SCSI_Disks, IDS_INFO_NON_SCSI_DISKS, IDS_INFO_NON_SCSI_DISKS_REF, hr );
  2125. STATUS_REPORT_STRING_REF( TASKID_Minor_Non_SCSI_Disks, clsidMinorId, IDS_ERROR_FOUND_NON_SCSI_DISK, varDeviceID.bstrVal, IDS_ERROR_FOUND_NON_SCSI_DISK_REF, hr );
  2126. } // else:
  2127. Cleanup:
  2128. VariantClear( &varDeviceID );
  2129. VariantClear( &varSCSIBus );
  2130. VariantClear( &varSCSIPort );
  2131. VariantClear( &varSCSILun );
  2132. VariantClear( &varSCSITid );
  2133. TraceSysFreeString( bstr );
  2134. HRETURN( hr );
  2135. } //*** CEnumPhysicalDisks::HrLogDiskInfo
  2136. /////////////////////////////////////////////////////////////////////////////
  2137. //++
  2138. //
  2139. // CEnumPhysicalDisks:HrFindDiskWithWMIDeviceID
  2140. //
  2141. // Description:
  2142. // Find the disk with the passed in WMI device ID.
  2143. //
  2144. // Arguments:
  2145. // None.
  2146. //
  2147. // Return Value:
  2148. // S_OK
  2149. // Success. Found the disk.
  2150. //
  2151. // S_FALSE
  2152. // Success. Did not find the disk.
  2153. //
  2154. // Win32 Error
  2155. // something failed.
  2156. //
  2157. // Remarks:
  2158. // None.
  2159. //
  2160. //--
  2161. //////////////////////////////////////////////////////////////////////////////
  2162. HRESULT
  2163. CEnumPhysicalDisks::HrFindDiskWithWMIDeviceID(
  2164. BSTR bstrWMIDeviceIDIn,
  2165. ULONG * pidxDiskOut
  2166. )
  2167. {
  2168. TraceFunc( "" );
  2169. Assert( pidxDiskOut != NULL );
  2170. HRESULT hr = S_OK;
  2171. IClusCfgPhysicalDiskProperties * piccpdp = NULL;
  2172. ULONG idx;
  2173. bool fFoundIt = false;
  2174. IUnknown * punk;
  2175. BSTR bstrDeviceID = NULL;
  2176. for ( idx = 0; idx < m_idxNext; idx++ )
  2177. {
  2178. punk = (*m_prgDisks)[ idx ]; // don't ref
  2179. if ( punk != NULL )
  2180. {
  2181. hr = THR( punk->TypeSafeQI( IClusCfgPhysicalDiskProperties, &piccpdp ) );
  2182. if ( FAILED( hr ) )
  2183. {
  2184. goto Cleanup;
  2185. } // if:
  2186. hr = STHR( piccpdp->HrGetDeviceID( &bstrDeviceID ) );
  2187. if ( FAILED( hr ) )
  2188. {
  2189. goto Cleanup;
  2190. } // if:
  2191. if ( NBSTRCompareCase( bstrWMIDeviceIDIn, bstrDeviceID ) == 0 )
  2192. {
  2193. fFoundIt = true;
  2194. break;
  2195. } // if:
  2196. piccpdp->Release();
  2197. piccpdp = NULL;
  2198. TraceSysFreeString( bstrDeviceID );
  2199. bstrDeviceID = NULL;
  2200. } // if:
  2201. } // for:
  2202. if ( !fFoundIt )
  2203. {
  2204. hr = S_FALSE;
  2205. } // if:
  2206. if ( pidxDiskOut != NULL )
  2207. {
  2208. *pidxDiskOut = idx;
  2209. } // if:
  2210. Cleanup:
  2211. if ( piccpdp != NULL )
  2212. {
  2213. piccpdp->Release();
  2214. } // if:
  2215. TraceSysFreeString( bstrDeviceID );
  2216. HRETURN( hr );
  2217. } //*** CEnumPhysicalDisks::HrFindDiskWithWMIDeviceID
  2218. /////////////////////////////////////////////////////////////////////////////
  2219. //++
  2220. //
  2221. // CEnumPhysicalDisks:HrIsSystemBusManaged
  2222. //
  2223. // Description:
  2224. // Is the system bus managed by the cluster service?
  2225. //
  2226. // Arguments:
  2227. // None.
  2228. //
  2229. // Return Value:
  2230. // S_OK
  2231. // Success. The system bus is managed.
  2232. //
  2233. // S_FALSE
  2234. // Success. The system bus is not managed.
  2235. //
  2236. // Win32 Error
  2237. // something failed.
  2238. //
  2239. // Remarks:
  2240. // None.
  2241. //
  2242. //--
  2243. //////////////////////////////////////////////////////////////////////////////
  2244. HRESULT
  2245. CEnumPhysicalDisks::HrIsSystemBusManaged( void )
  2246. {
  2247. TraceFunc( "" );
  2248. HRESULT hr = S_FALSE;
  2249. DWORD sc;
  2250. HKEY hKey = NULL;
  2251. DWORD dwData;
  2252. DWORD cbData = sizeof( dwData );
  2253. DWORD dwType;
  2254. sc = RegOpenKeyEx( HKEY_LOCAL_MACHINE, L"SYSTEM\\CURRENTCONTROLSET\\SERVICES\\ClusSvc\\Parameters", 0, KEY_READ, &hKey );
  2255. if ( sc == ERROR_FILE_NOT_FOUND )
  2256. {
  2257. goto Cleanup; // not yet a cluster node. Return S_FALSE.
  2258. } // if:
  2259. if ( sc != ERROR_SUCCESS )
  2260. {
  2261. hr = HRESULT_FROM_WIN32( TW32( sc ) );
  2262. LogMsg( L"[SRV] RegOpenKeyEx() failed. (hr = %#08x)", hr );
  2263. goto Cleanup;
  2264. } // if:
  2265. sc = RegQueryValueEx( hKey, L"ManageDisksOnSystemBuses", NULL, &dwType, (LPBYTE) &dwData, &cbData );
  2266. if ( sc == ERROR_FILE_NOT_FOUND )
  2267. {
  2268. goto Cleanup; // value not found. Return S_FALSE.
  2269. } // if:
  2270. if ( sc != ERROR_SUCCESS )
  2271. {
  2272. hr = HRESULT_FROM_WIN32( TW32( sc ) );
  2273. LogMsg( L"[SRV] RegQueryValueEx() failed. (hr = %#08x)", hr );
  2274. goto Cleanup;
  2275. } // if:
  2276. if (dwType != REG_DWORD)
  2277. {
  2278. hr = HRESULT_FROM_WIN32( TW32(ERROR_DATATYPE_MISMATCH) );
  2279. LogMsg( L"[SRV] RegQueryValueEx() invalid data type %d.", dwType );
  2280. }
  2281. else if ( dwData > 0)
  2282. {
  2283. hr = S_OK;
  2284. } // if:
  2285. Cleanup:
  2286. if ( hKey != NULL )
  2287. {
  2288. RegCloseKey( hKey );
  2289. } // if:
  2290. HRETURN( hr );
  2291. } //*** CEnumPhysicalDisks::HrIsSystemBusManaged
  2292. /////////////////////////////////////////////////////////////////////////////
  2293. //++
  2294. //
  2295. // CEnumPhysicalDisks:HrGetClusterProperties
  2296. //
  2297. // Description:
  2298. // Return the asked for cluster properties.
  2299. //
  2300. // Arguments:
  2301. //
  2302. //
  2303. // Return Value:
  2304. // S_OK
  2305. // Success.
  2306. //
  2307. // Win32 Error
  2308. // something failed.
  2309. //
  2310. // Remarks:
  2311. // None.
  2312. //
  2313. //--
  2314. //////////////////////////////////////////////////////////////////////////////
  2315. HRESULT
  2316. CEnumPhysicalDisks::HrGetClusterProperties(
  2317. HRESOURCE hResourceIn
  2318. , BSTR * pbstrResourceNameOut
  2319. )
  2320. {
  2321. TraceFunc( "" );
  2322. Assert( hResourceIn != NULL );
  2323. Assert( pbstrResourceNameOut != NULL );
  2324. HRESULT hr = S_OK;
  2325. DWORD sc;
  2326. DWORD cbBuffer;
  2327. WCHAR * pwszBuffer = NULL;
  2328. cbBuffer = 0;
  2329. sc = TW32( ClusterResourceControl(
  2330. hResourceIn,
  2331. NULL,
  2332. CLUSCTL_RESOURCE_GET_NAME,
  2333. NULL,
  2334. NULL,
  2335. NULL,
  2336. cbBuffer,
  2337. &cbBuffer
  2338. ) );
  2339. if ( sc != ERROR_SUCCESS )
  2340. {
  2341. hr = HRESULT_FROM_WIN32( sc );
  2342. goto Cleanup;
  2343. }
  2344. // cbBuffer contains the byte count, not the char count.
  2345. pwszBuffer = new WCHAR[(cbBuffer/sizeof(WCHAR))+1];
  2346. if ( pwszBuffer == NULL )
  2347. {
  2348. hr = THR( ERROR_OUTOFMEMORY );
  2349. goto Cleanup;
  2350. }
  2351. sc = ClusterResourceControl(
  2352. hResourceIn,
  2353. NULL,
  2354. CLUSCTL_RESOURCE_GET_NAME,
  2355. NULL,
  2356. NULL,
  2357. pwszBuffer,
  2358. cbBuffer,
  2359. &cbBuffer
  2360. );
  2361. if ( sc != ERROR_SUCCESS )
  2362. {
  2363. hr = HRESULT_FROM_WIN32( TW32( sc ) );
  2364. goto Cleanup;
  2365. }
  2366. if ( wcslen( pwszBuffer ) == 0 )
  2367. {
  2368. LOG_STATUS_REPORT( L"The Name of a physical disk resource was empty!", hr );
  2369. }
  2370. *pbstrResourceNameOut = TraceSysAllocString( pwszBuffer );
  2371. hr = S_OK;
  2372. Cleanup:
  2373. delete [] pwszBuffer;
  2374. HRETURN( hr );
  2375. } //*** CEnumPhysicalDisks::HrGetClusterProperties
  2376. /////////////////////////////////////////////////////////////////////////////
  2377. //++
  2378. //
  2379. // CEnumPhysicalDisks::RemoveDiskFromArray
  2380. //
  2381. // Description:
  2382. // Release the disk at the specified index in the array and decrease the disk count.
  2383. //
  2384. // Arguments:
  2385. // idxDiskIn - the index of the disk to remove; must be less than the array size.
  2386. //
  2387. // Return Value:
  2388. // None.
  2389. //
  2390. // Remarks:
  2391. // None.
  2392. //
  2393. //--
  2394. //////////////////////////////////////////////////////////////////////////////
  2395. void
  2396. CEnumPhysicalDisks::RemoveDiskFromArray( ULONG idxDiskIn )
  2397. {
  2398. TraceFunc( "" );
  2399. Assert( idxDiskIn < m_idxNext );
  2400. ((*m_prgDisks)[ idxDiskIn ])->Release();
  2401. (*m_prgDisks)[ idxDiskIn ] = NULL;
  2402. m_cDiskCount -= 1;
  2403. TraceFuncExit();
  2404. } //*** CEnumPhysicalDisks::RemoveDiskFromArray
  2405. /////////////////////////////////////////////////////////////////////////////
  2406. //++
  2407. //
  2408. // CEnumPhysicalDisks::HrLoadEnum
  2409. //
  2410. // Description:
  2411. // Load the enum and filter out any devices that don't belong.
  2412. //
  2413. // Arguments:
  2414. // None.
  2415. //
  2416. // Return Value:
  2417. // S_OK
  2418. // Success.
  2419. //
  2420. // Other HRESULT errors.
  2421. //
  2422. // Remarks:
  2423. // None.
  2424. //
  2425. //--
  2426. //////////////////////////////////////////////////////////////////////////////
  2427. HRESULT
  2428. CEnumPhysicalDisks::HrLoadEnum( void )
  2429. {
  2430. TraceFunc( "" );
  2431. HRESULT hr = S_OK;
  2432. hr = THR( HrGetDisks() );
  2433. if ( FAILED( hr ) )
  2434. {
  2435. goto Cleanup;
  2436. } // if:
  2437. hr = THR( HrPruneSystemDisks() );
  2438. if ( FAILED( hr ) )
  2439. {
  2440. goto Cleanup;
  2441. } // if:
  2442. hr = THR( HrSortDisksByIndex() );
  2443. if ( FAILED( hr ) )
  2444. {
  2445. goto Cleanup;
  2446. } // if:
  2447. hr = STHR( HrIsNodeClustered() );
  2448. if ( FAILED( hr ) )
  2449. {
  2450. goto Cleanup;
  2451. } // if:
  2452. if ( hr == S_OK )
  2453. {
  2454. hr = THR( HrFixupDisks() );
  2455. if ( FAILED( hr ) )
  2456. {
  2457. goto Cleanup;
  2458. } // if:
  2459. } // if:
  2460. hr = S_OK; // could have been S_FALSE
  2461. Cleanup:
  2462. HRETURN( hr );
  2463. } //*** CEnumPhysicalDisks::HrLoadEnum
  2464. /////////////////////////////////////////////////////////////////////////////
  2465. //++
  2466. //
  2467. // CEnumPhysicalDisks::HrSortDisksByIndex
  2468. //
  2469. // Description:
  2470. // Sort a (possibly sparse) array of pointers to disk objects by their
  2471. // WMI "Index" property.
  2472. //
  2473. // Arguments:
  2474. // ppunkDisksIn -- a pointer to an array of (possibly null)
  2475. // IUnknown pointers to objects that implement the
  2476. // IClusCfgPhysicalDiskProperties interface.
  2477. //
  2478. // cArraySizeIn -- the total number of pointers in the array,
  2479. // including nulls
  2480. //
  2481. // Return Value:
  2482. // None.
  2483. //
  2484. // Remarks:
  2485. // None.
  2486. //
  2487. //--
  2488. //////////////////////////////////////////////////////////////////////////////
  2489. HRESULT
  2490. CEnumPhysicalDisks::HrSortDisksByIndex( void )
  2491. {
  2492. TraceFunc( "" );
  2493. HRESULT hr = S_OK;
  2494. CIndexedDisk * prgIndexedDisks = NULL;
  2495. size_t idxCurrentDisk = 0;
  2496. size_t idxSortedDisk = 0;
  2497. size_t cDisks = 0;
  2498. // Count the number of non-null pointers in the array
  2499. for ( idxCurrentDisk = 0; idxCurrentDisk < m_idxNext; ++idxCurrentDisk )
  2500. {
  2501. if ( (*m_prgDisks)[ idxCurrentDisk ] != NULL )
  2502. {
  2503. cDisks += 1;
  2504. } // if:
  2505. } // for:
  2506. if ( cDisks < 2 ) // no sorting to do; also avoid calling new[] with zero array size
  2507. {
  2508. goto Cleanup;
  2509. } // if:
  2510. // Make a compact array of indexed disks
  2511. prgIndexedDisks = new CIndexedDisk[ cDisks ];
  2512. if ( prgIndexedDisks == NULL )
  2513. {
  2514. hr = THR( E_OUTOFMEMORY );
  2515. goto Cleanup;
  2516. } // if:
  2517. // Initialize the array of indexed disks
  2518. for ( idxCurrentDisk = 0; idxCurrentDisk < m_idxNext; ++idxCurrentDisk )
  2519. {
  2520. if ( (*m_prgDisks)[ idxCurrentDisk ] != NULL )
  2521. {
  2522. hr = THR( prgIndexedDisks[ idxSortedDisk ].HrInit( (*m_prgDisks)[ idxCurrentDisk ] ) );
  2523. if ( FAILED( hr ) )
  2524. {
  2525. goto Cleanup;
  2526. } // if:
  2527. idxSortedDisk += 1;
  2528. } // if current disk pointer in original array is not null
  2529. } // for each disk pointer in the original array
  2530. InsertionSort( prgIndexedDisks, cDisks, CIndexedDiskLessThan() );
  2531. // Copy the sorted pointers back into the original array, padding extra space with nulls
  2532. for ( idxCurrentDisk = 0; idxCurrentDisk < m_idxNext; ++idxCurrentDisk)
  2533. {
  2534. if ( idxCurrentDisk < cDisks)
  2535. {
  2536. (*m_prgDisks)[ idxCurrentDisk ] = prgIndexedDisks[ idxCurrentDisk ].punkDisk;
  2537. } // if:
  2538. else
  2539. {
  2540. (*m_prgDisks)[ idxCurrentDisk ] = NULL;
  2541. } // else:
  2542. } // for each slot in the original array
  2543. Cleanup:
  2544. delete [] prgIndexedDisks;
  2545. HRETURN( hr );
  2546. } //*** CEnumPhysicalDisks::HrSortDisksByIndex
  2547. /////////////////////////////////////////////////////////////////////////////
  2548. //++
  2549. //
  2550. // CEnumPhysicalDisks::HrPrunePageFileDiskBussess
  2551. //
  2552. // Description:
  2553. // Prune from the list of disks those that have pagefiles on them and
  2554. // the other disks on those same SCSI busses.
  2555. //
  2556. // Arguments:
  2557. // fPruneBusIn
  2558. //
  2559. // pcPrunedInout
  2560. //
  2561. // Return Value:
  2562. // S_OK
  2563. // Success.
  2564. //
  2565. //--
  2566. //////////////////////////////////////////////////////////////////////////////
  2567. HRESULT
  2568. CEnumPhysicalDisks::HrPrunePageFileDiskBussess(
  2569. BOOL fPruneBusIn
  2570. , ULONG * pcPrunedInout
  2571. )
  2572. {
  2573. TraceFunc( "" );
  2574. Assert( pcPrunedInout != NULL );
  2575. HRESULT hr = S_OK;
  2576. WCHAR szPageFileDisks[ 26 ];
  2577. int cPageFileDisks = 0;
  2578. int idxPageFileDisk;
  2579. ULONG ulSCSIBus;
  2580. ULONG ulSCSIPort;
  2581. ULONG idx;
  2582. ULONG cPruned = 0;
  2583. //
  2584. // Prune the bus with disks that have paging files.
  2585. //
  2586. hr = THR( HrGetPageFileLogicalDisks( m_picccCallback, m_pIWbemServices, szPageFileDisks, &cPageFileDisks ) );
  2587. if ( FAILED( hr ) )
  2588. {
  2589. goto Cleanup;
  2590. } // if:
  2591. if ( cPageFileDisks > 0 )
  2592. {
  2593. for ( idxPageFileDisk = 0; idxPageFileDisk < cPageFileDisks; idxPageFileDisk++ )
  2594. {
  2595. hr = STHR( HrFindDiskWithLogicalDisk( szPageFileDisks[ idxPageFileDisk ], &idx ) );
  2596. if ( FAILED( hr ) )
  2597. {
  2598. goto Cleanup;
  2599. } // if:
  2600. if ( hr == S_OK )
  2601. {
  2602. //
  2603. // Should we prune the whole bus, or just the system disk itself?
  2604. //
  2605. if ( fPruneBusIn )
  2606. {
  2607. hr = THR( HrGetSCSIInfo( idx, &ulSCSIBus, &ulSCSIPort ) );
  2608. if ( FAILED( hr ) )
  2609. {
  2610. goto Cleanup;
  2611. } // if:
  2612. STATUS_REPORT( TASKID_Major_Find_Devices, TASKID_Minor_Pruning_PageFile_Disk_Bus, IDS_INFO_PRUNING_PAGEFILEDISK_BUS, hr );
  2613. hr = THR( HrPruneDisks(
  2614. ulSCSIBus
  2615. , ulSCSIPort
  2616. , &TASKID_Minor_Pruning_PageFile_Disk_Bus
  2617. , IDS_INFO_PAGEFILEDISK_PRUNED
  2618. , IDS_INFO_PAGEFILEDISK_PRUNED_REF
  2619. , &cPruned
  2620. ) );
  2621. if ( FAILED( hr ) )
  2622. {
  2623. goto Cleanup;
  2624. } // if:
  2625. } // if:
  2626. else
  2627. {
  2628. RemoveDiskFromArray( idx );
  2629. cPruned++;
  2630. } // else:
  2631. } // if:
  2632. } // for:
  2633. } // if:
  2634. *pcPrunedInout = cPruned;
  2635. hr = S_OK;
  2636. Cleanup:
  2637. HRETURN( hr );
  2638. } //*** CEnumPhysicalDisks::HrPrunePageFileDiskBussess
  2639. /////////////////////////////////////////////////////////////////////////////
  2640. //++
  2641. //
  2642. // CEnumPhysicalDisks::HrPruneCrashDumpBus
  2643. //
  2644. // Description:
  2645. // Prune from the list of disks those that have pagefiles on them and
  2646. // the other disks on those same SCSI busses.
  2647. //
  2648. // Arguments:
  2649. // fPruneBusIn
  2650. //
  2651. // pcPrunedInout
  2652. //
  2653. // Return Value:
  2654. // S_OK
  2655. // Success.
  2656. //
  2657. //--
  2658. //////////////////////////////////////////////////////////////////////////////
  2659. HRESULT
  2660. CEnumPhysicalDisks::HrPruneCrashDumpBus(
  2661. BOOL fPruneBusIn
  2662. , ULONG * pcPrunedInout
  2663. )
  2664. {
  2665. TraceFunc( "" );
  2666. Assert( pcPrunedInout != NULL );
  2667. Assert( m_bstrCrashDumpLogicalDisk != NULL );
  2668. HRESULT hr = S_OK;
  2669. ULONG ulSCSIBus;
  2670. ULONG ulSCSIPort;
  2671. ULONG idx;
  2672. ULONG cPruned = 0;
  2673. //
  2674. // Prune the bus with disks that have paging files.
  2675. //
  2676. hr = STHR( HrFindDiskWithLogicalDisk( m_bstrCrashDumpLogicalDisk[ 0 ], &idx ) );
  2677. if ( FAILED( hr ) )
  2678. {
  2679. goto Cleanup;
  2680. } // if:
  2681. if ( hr == S_OK )
  2682. {
  2683. //
  2684. // Should we prune the whole bus, or just the system disk itself?
  2685. //
  2686. if ( fPruneBusIn )
  2687. {
  2688. hr = THR( HrGetSCSIInfo( idx, &ulSCSIBus, &ulSCSIPort ) );
  2689. if ( FAILED( hr ) )
  2690. {
  2691. goto Cleanup;
  2692. } // if:
  2693. STATUS_REPORT( TASKID_Major_Find_Devices, TASKID_Minor_Pruning_CrashDump_Disk_Bus, IDS_INFO_PRUNING_CRASHDUMP_BUS, hr );
  2694. hr = THR( HrPruneDisks(
  2695. ulSCSIBus
  2696. , ulSCSIPort
  2697. , &TASKID_Minor_Pruning_CrashDump_Disk_Bus
  2698. , IDS_INFO_CRASHDUMPDISK_PRUNED
  2699. , IDS_INFO_CRASHDUMPDISK_PRUNED_REF
  2700. , &cPruned
  2701. ) );
  2702. if ( FAILED( hr ) )
  2703. {
  2704. goto Cleanup;
  2705. } // if:
  2706. } // if:
  2707. else
  2708. {
  2709. RemoveDiskFromArray( idx );
  2710. cPruned++;
  2711. } // else:
  2712. } // if:
  2713. *pcPrunedInout = cPruned;
  2714. hr = S_OK;
  2715. Cleanup:
  2716. HRETURN( hr );
  2717. } //*** CEnumPhysicalDisks::HrPruneCrashDumpBus
  2718. /////////////////////////////////////////////////////////////////////////////
  2719. //++
  2720. //
  2721. // CEnumPhysicalDisks::HrPruneDynamicDisks
  2722. //
  2723. // Description:
  2724. // Prune from the list of disks those that have dynamic partitions
  2725. // on them.
  2726. //
  2727. // Arguments:
  2728. // pcPrunedInout
  2729. //
  2730. // Return Value:
  2731. // S_OK
  2732. // Success.
  2733. //
  2734. //--
  2735. //////////////////////////////////////////////////////////////////////////////
  2736. HRESULT
  2737. CEnumPhysicalDisks::HrPruneDynamicDisks(
  2738. ULONG * pcPrunedInout
  2739. )
  2740. {
  2741. TraceFunc( "" );
  2742. Assert( pcPrunedInout != NULL );
  2743. HRESULT hr = S_OK;
  2744. ULONG idx;
  2745. ULONG cPruned = 0;
  2746. IClusCfgPhysicalDiskProperties * piccpdp = NULL;
  2747. HRESULT hrTemp;
  2748. CLSID clsidMinorId;
  2749. BSTR bstrDiskName = NULL;
  2750. BSTR bstrDeviceName = NULL;
  2751. for ( idx = 0; idx < m_idxNext; idx++ )
  2752. {
  2753. if ( (*m_prgDisks)[ idx ] != NULL )
  2754. {
  2755. hr = THR( ((*m_prgDisks)[ idx ])->TypeSafeQI( IClusCfgPhysicalDiskProperties, &piccpdp ) );
  2756. if ( FAILED( hr ) )
  2757. {
  2758. goto Cleanup;
  2759. } // if:
  2760. hr = piccpdp->HrIsDynamicDisk();
  2761. if ( FAILED( hr ) )
  2762. {
  2763. goto Cleanup;
  2764. } // if:
  2765. if ( hr == S_OK )
  2766. {
  2767. ((*m_prgDisks)[ idx ])->Release();
  2768. (*m_prgDisks)[ idx ] = NULL;
  2769. cPruned++;
  2770. hrTemp = THR( piccpdp->HrGetDiskNames( &bstrDiskName, &bstrDeviceName ) );
  2771. if ( FAILED( hrTemp ) )
  2772. {
  2773. LOG_STATUS_REPORT( L"Could not get the name of the disk", hrTemp );
  2774. bstrDiskName = NULL;
  2775. bstrDeviceName = NULL;
  2776. } // if:
  2777. hrTemp = THR( CoCreateGuid( &clsidMinorId ) );
  2778. if ( FAILED( hrTemp ) )
  2779. {
  2780. LOG_STATUS_REPORT( L"Could not create a guid for a dynamic disk minor task ID", hrTemp );
  2781. clsidMinorId = IID_NULL;
  2782. } // if:
  2783. STATUS_REPORT_REF( TASKID_Major_Find_Devices, TASKID_Minor_Non_SCSI_Disks, IDS_INFO_NON_SCSI_DISKS, IDS_INFO_NON_SCSI_DISKS_REF, hr );
  2784. STATUS_REPORT_STRING2_REF(
  2785. TASKID_Minor_Non_SCSI_Disks
  2786. , clsidMinorId
  2787. , IDS_ERROR_LDM_DISK
  2788. , bstrDeviceName != NULL ? bstrDeviceName : L"<unknown>"
  2789. , bstrDiskName != NULL ? bstrDiskName : L"<unknown>"
  2790. , IDS_ERROR_LDM_DISK_REF
  2791. , hr
  2792. );
  2793. } // if:
  2794. piccpdp->Release();
  2795. piccpdp = NULL;
  2796. TraceSysFreeString( bstrDiskName );
  2797. bstrDiskName = NULL;
  2798. TraceSysFreeString( bstrDeviceName );
  2799. bstrDeviceName = NULL;
  2800. } // end if:
  2801. } // for:
  2802. *pcPrunedInout = cPruned;
  2803. hr = S_OK;
  2804. Cleanup:
  2805. if ( piccpdp != NULL )
  2806. {
  2807. piccpdp->Release();
  2808. } // if:
  2809. TraceSysFreeString( bstrDiskName );
  2810. TraceSysFreeString( bstrDeviceName );
  2811. HRETURN( hr );
  2812. } //*** CEnumPhysicalDisks::HrPruneDynamicDisks
  2813. /////////////////////////////////////////////////////////////////////////////
  2814. //++
  2815. //
  2816. // CEnumPhysicalDisks::HrPruneGPTDisks
  2817. //
  2818. // Description:
  2819. // Prune from the list of disks those that have GPT partitions
  2820. // on them.
  2821. //
  2822. // Arguments:
  2823. // pcPrunedInout
  2824. //
  2825. // Return Value:
  2826. // S_OK
  2827. // Success.
  2828. //
  2829. //--
  2830. //////////////////////////////////////////////////////////////////////////////
  2831. HRESULT
  2832. CEnumPhysicalDisks::HrPruneGPTDisks(
  2833. ULONG * pcPrunedInout
  2834. )
  2835. {
  2836. TraceFunc( "" );
  2837. Assert( pcPrunedInout != NULL );
  2838. HRESULT hr = S_OK;
  2839. ULONG idx;
  2840. ULONG cPruned = 0;
  2841. IClusCfgPhysicalDiskProperties * piccpdp = NULL;
  2842. HRESULT hrTemp;
  2843. CLSID clsidMinorId;
  2844. BSTR bstrDiskName = NULL;
  2845. BSTR bstrDeviceName = NULL;
  2846. for ( idx = 0; idx < m_idxNext; idx++ )
  2847. {
  2848. if ( (*m_prgDisks)[ idx ] != NULL )
  2849. {
  2850. hr = THR( ((*m_prgDisks)[ idx ])->TypeSafeQI( IClusCfgPhysicalDiskProperties, &piccpdp ) );
  2851. if ( FAILED( hr ) )
  2852. {
  2853. goto Cleanup;
  2854. } // if:
  2855. hr = piccpdp->HrIsGPTDisk();
  2856. if ( FAILED( hr ) )
  2857. {
  2858. goto Cleanup;
  2859. } // if:
  2860. if ( hr == S_OK )
  2861. {
  2862. ((*m_prgDisks)[ idx ])->Release();
  2863. (*m_prgDisks)[ idx ] = NULL;
  2864. cPruned++;
  2865. hrTemp = THR( piccpdp->HrGetDiskNames( &bstrDiskName, &bstrDeviceName ) );
  2866. if ( FAILED( hrTemp ) )
  2867. {
  2868. LOG_STATUS_REPORT( L"Could not get the name of the disk", hrTemp );
  2869. bstrDiskName = NULL;
  2870. bstrDeviceName = NULL;
  2871. } // if:
  2872. hrTemp = THR( CoCreateGuid( &clsidMinorId ) );
  2873. if ( FAILED( hrTemp ) )
  2874. {
  2875. LOG_STATUS_REPORT( L"Could not create a guid for a dynamic disk minor task ID", hrTemp );
  2876. clsidMinorId = IID_NULL;
  2877. } // if:
  2878. STATUS_REPORT_REF( TASKID_Major_Find_Devices, TASKID_Minor_Non_SCSI_Disks, IDS_INFO_NON_SCSI_DISKS, IDS_INFO_NON_SCSI_DISKS_REF, hr );
  2879. STATUS_REPORT_STRING2_REF(
  2880. TASKID_Minor_Non_SCSI_Disks
  2881. , clsidMinorId
  2882. , IDS_INFO_GPT_DISK
  2883. , bstrDeviceName != NULL ? bstrDeviceName : L"<unknown>"
  2884. , bstrDiskName != NULL ? bstrDiskName : L"<unknown>"
  2885. , IDS_ERROR_LDM_DISK_REF
  2886. , hr
  2887. );
  2888. } // if:
  2889. piccpdp->Release();
  2890. piccpdp = NULL;
  2891. TraceSysFreeString( bstrDiskName );
  2892. bstrDiskName = NULL;
  2893. TraceSysFreeString( bstrDeviceName );
  2894. bstrDeviceName = NULL;
  2895. } // end if:
  2896. } // for:
  2897. *pcPrunedInout = cPruned;
  2898. hr = S_OK;
  2899. Cleanup:
  2900. if ( piccpdp != NULL )
  2901. {
  2902. piccpdp->Release();
  2903. } // if:
  2904. TraceSysFreeString( bstrDiskName );
  2905. TraceSysFreeString( bstrDeviceName );
  2906. HRETURN( hr );
  2907. } //*** CEnumPhysicalDisks::HrPruneGPTDisks
  2908. /*
  2909. /////////////////////////////////////////////////////////////////////////////
  2910. //++
  2911. //
  2912. // CEnumPhysicalDisks::HrGetDisks
  2913. //
  2914. // Description:
  2915. //
  2916. // Arguments:
  2917. //
  2918. //
  2919. // Return Value:
  2920. //
  2921. //
  2922. // Remarks:
  2923. // None.
  2924. //
  2925. //--
  2926. //////////////////////////////////////////////////////////////////////////////
  2927. HRESULT
  2928. CEnumPhysicalDisks::HrGetDisks(
  2929. void
  2930. )
  2931. {
  2932. TraceFunc( "" );
  2933. HRESULT hr = S_OK;
  2934. DWORD sc;
  2935. HDEVINFO hdiSet = INVALID_HANDLE_VALUE;
  2936. SP_DEVINFO_DATA didData;
  2937. SP_INTERFACE_DEVICE_DATA iddData;
  2938. GUID guidClass = GUID_DEVINTERFACE_DISK;
  2939. DWORD idx = 0;
  2940. BOOL fRet = TRUE;
  2941. PSP_INTERFACE_DEVICE_DETAIL_DATA pidddDetailData = NULL;
  2942. DWORD cbDetailData = 512L;
  2943. DWORD cbRequired = 0L;
  2944. ZeroMemory ( &didData, sizeof( didData ) );
  2945. didData.cbSize = sizeof( didData );
  2946. ZeroMemory ( &iddData, sizeof( iddData ) );
  2947. iddData.cbSize = sizeof( iddData );
  2948. //
  2949. // get device list
  2950. //
  2951. hdiSet = SetupDiGetClassDevs( &guidClass, NULL, NULL, DIGCF_INTERFACEDEVICE );
  2952. if ( hdiSet == INVALID_HANDLE_VALUE )
  2953. {
  2954. sc = TW32( GetLastError() );
  2955. hr = HRESULT_FROM_WIN32( sc );
  2956. goto Cleanup;
  2957. } // if:
  2958. //
  2959. // Do initial allocations.
  2960. //
  2961. pidddDetailData = (PSP_INTERFACE_DEVICE_DETAIL_DATA) TraceAlloc( 0, cbDetailData );
  2962. if ( pidddDetailData == NULL )
  2963. {
  2964. hr = THR( E_OUTOFMEMORY );
  2965. goto Cleanup;
  2966. } // if:
  2967. pidddDetailData->cbSize = sizeof( SP_INTERFACE_DEVICE_DETAIL_DATA );
  2968. //
  2969. // enumerate list
  2970. //
  2971. for ( ; ; )
  2972. {
  2973. fRet = SetupDiEnumDeviceInterfaces( hdiSet, NULL, &guidClass, idx, &iddData );
  2974. if ( fRet == FALSE )
  2975. {
  2976. sc = GetLastError();
  2977. if ( sc == ERROR_NO_MORE_ITEMS )
  2978. {
  2979. hr = S_OK;
  2980. break;
  2981. } // if:
  2982. TW32( sc );
  2983. hr = HRESULT_FROM_WIN32( sc );
  2984. goto Cleanup;
  2985. } // if:
  2986. for ( ; ; )
  2987. {
  2988. fRet = SetupDiGetDeviceInterfaceDetail( hdiSet, &iddData, pidddDetailData, cbDetailData, &cbRequired, &didData );
  2989. if ( fRet == FALSE )
  2990. {
  2991. sc = GetLastError();
  2992. if ( sc == ERROR_INSUFFICIENT_BUFFER )
  2993. {
  2994. cbDetailData = cbRequired;
  2995. TraceFree( pidddDetailData );
  2996. pidddDetailData = NULL;
  2997. pidddDetailData = (PSP_INTERFACE_DEVICE_DETAIL_DATA) TraceAlloc( 0, cbDetailData );
  2998. if ( pidddDetailData == NULL )
  2999. {
  3000. hr = THR( E_OUTOFMEMORY );
  3001. goto Cleanup;
  3002. } // if:
  3003. pidddDetailData->cbSize = sizeof( SP_INTERFACE_DEVICE_DETAIL_DATA );
  3004. continue;
  3005. } // if:
  3006. TW32( sc );
  3007. hr = HRESULT_FROM_WIN32( sc );
  3008. goto Cleanup;
  3009. } // if:
  3010. else
  3011. {
  3012. break;
  3013. } // else:
  3014. } // for:
  3015. idx++;
  3016. } // for:
  3017. Cleanup:
  3018. TraceFree( pidddDetailData );
  3019. if ( hdiSet != INVALID_HANDLE_VALUE )
  3020. {
  3021. SetupDiDestroyDeviceInfoList( hdiSet );
  3022. } // if:
  3023. HRETURN( hr );
  3024. } //*** CEnumPhysicalDisks::HrGetDisks
  3025. */