////////////////////////////////////////////////////////////////////////////// // // Copyright (c) 2000-2002 Microsoft Corporation // // Module Name: // CEnumPhysicalDisks.cpp // // Description: // This file contains the definition of the CEnumPhysicalDisks // class. // // The class CEnumPhysicalDisks is the enumeration of cluster // storage devices. It implements the IEnumClusCfgManagedResources // interface. // // Maintained By: // Galen Barbee (GalenB) 23-FEB-2000 // ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // Include Files ////////////////////////////////////////////////////////////////////////////// #include "Pch.h" //#include //#include #include "CEnumPhysicalDisks.h" #include "CPhysicalDisk.h" #include "CIndexedDisk.h" #include #include ////////////////////////////////////////////////////////////////////////////// // Constant Definitions ////////////////////////////////////////////////////////////////////////////// DEFINE_THISCLASS( "CEnumPhysicalDisks" ); //*************************************************************************// ///////////////////////////////////////////////////////////////////////////// // CEnumPhysicalDisks class ///////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// //++ // // CEnumPhysicalDisks::S_HrCreateInstance // // Description: // Create a CEnumPhysicalDisks instance. // // Arguments: // None. // // Return Values: // S_OK // Success. // // E_POINTER // The passed in ppunk is NULL. // // other HRESULTs // Object creation failed. // //-- ////////////////////////////////////////////////////////////////////////////// HRESULT CEnumPhysicalDisks::S_HrCreateInstance( IUnknown ** ppunkOut ) { TraceFunc( "" ); HRESULT hr = S_OK; CEnumPhysicalDisks * pepd = NULL; if ( ppunkOut == NULL ) { hr = THR( E_POINTER ); goto Cleanup; } // if: pepd = new CEnumPhysicalDisks(); if ( pepd == NULL ) { hr = THR( E_OUTOFMEMORY ); goto Cleanup; } // if: error allocating object hr = THR( pepd->HrInit() ); if ( FAILED( hr ) ) { goto Cleanup; } // if: HrInit() failed hr = THR( pepd->TypeSafeQI( IUnknown, ppunkOut ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: QI failed Cleanup: if ( FAILED( hr ) ) { LogMsg( L"[SRV] CEnumPhysicalDisks::S_HrCreateInstance() failed. (hr = %#08x)", hr ); } // if: if ( pepd != NULL ) { pepd->Release(); } // if: HRETURN( hr ); } //*** CEnumPhysicalDisks::S_HrCreateInstance ////////////////////////////////////////////////////////////////////////////// //++ // // IUnknown * // CEnumPhysicalDisks::S_RegisterCatIDSupport // // Description: // Registers/unregisters this class with the categories that it belongs // to. // // Arguments: // IN ICatRegister * picrIn // Used to register/unregister our CATID support. // // IN BOOL fCreateIn // When true we are registering the server. When false we are // un-registering the server. // // Return Values: // S_OK // Success. // // E_INVALIDARG // The passed in ICatRgister pointer was NULL. // // other HRESULTs // Registration/Unregistration failed. // //-- ////////////////////////////////////////////////////////////////////////////// HRESULT CEnumPhysicalDisks::S_RegisterCatIDSupport( ICatRegister * picrIn, BOOL fCreateIn ) { TraceFunc( "" ); HRESULT hr = S_OK; CATID rgCatIds[ 1 ]; if ( picrIn == NULL ) { hr = THR( E_INVALIDARG ); goto Cleanup; } // if: rgCatIds[ 0 ] = CATID_EnumClusCfgManagedResources; if ( fCreateIn ) { hr = THR( picrIn->RegisterClassImplCategories( CLSID_EnumPhysicalDisks, 1, rgCatIds ) ); } // if: Cleanup: HRETURN( hr ); } //*** CEnumPhysicalDisks::S_RegisterCatIDSupport ////////////////////////////////////////////////////////////////////////////// //++ // // CEnumPhysicalDisks::CEnumPhysicalDisks // // Description: // Constructor of the CEnumPhysicalDisks class. This initializes // the m_cRef variable to 1 instead of 0 to account of possible // QueryInterface failure in DllGetClassObject. // // Arguments: // None. // // Return Value: // None. // // Remarks: // None. // //-- ////////////////////////////////////////////////////////////////////////////// CEnumPhysicalDisks::CEnumPhysicalDisks( void ) : m_cRef( 1 ) , m_lcid( LOCALE_NEUTRAL ) , m_fLoadedDevices( false ) { TraceFunc( "" ); // Increment the count of components in memory so the DLL hosting this // object cannot be unloaded. InterlockedIncrement( &g_cObjects ); Assert( m_picccCallback == NULL ); Assert( m_pIWbemServices == NULL ); Assert( m_prgDisks == NULL ); Assert( m_idxNext == 0 ); Assert( m_idxEnumNext == 0 ); Assert( m_bstrNodeName == NULL ); Assert( m_bstrBootDevice == NULL ); Assert( m_bstrSystemDevice == NULL ); Assert( m_bstrBootLogicalDisk == NULL ); Assert( m_bstrSystemLogicalDisk == NULL ); Assert( m_bstrSystemWMIDeviceID == NULL ); Assert( m_cDiskCount == 0 ); Assert( m_bstrCrashDumpLogicalDisk == NULL ); TraceFuncExit(); } //*** CEnumPhysicalDisks::CEnumPhysicalDisks ////////////////////////////////////////////////////////////////////////////// //++ // // CEnumPhysicalDisks::~CEnumPhysicalDisks // // Description: // Desstructor of the CEnumPhysicalDisks class. // // Arguments: // None. // // Return Value: // None. // // Remarks: // None. // //-- ////////////////////////////////////////////////////////////////////////////// CEnumPhysicalDisks::~CEnumPhysicalDisks( void ) { TraceFunc( "" ); ULONG idx; if ( m_pIWbemServices != NULL ) { m_pIWbemServices->Release(); } // if: if ( m_picccCallback != NULL ) { m_picccCallback->Release(); } // if: for ( idx = 0; idx < m_idxNext; idx++ ) { if ( (*m_prgDisks)[ idx ] != NULL ) { ((*m_prgDisks)[ idx ])->Release(); } // end if: } // for: TraceFree( m_prgDisks ); TraceSysFreeString( m_bstrNodeName ); TraceSysFreeString( m_bstrBootDevice ); TraceSysFreeString( m_bstrSystemDevice ); TraceSysFreeString( m_bstrBootLogicalDisk ); TraceSysFreeString( m_bstrSystemLogicalDisk ); TraceSysFreeString( m_bstrSystemWMIDeviceID ); TraceSysFreeString( m_bstrCrashDumpLogicalDisk ); // There's going to be one less component in memory. Decrement component count. InterlockedDecrement( &g_cObjects ); TraceFuncExit(); } //*** CEnumPhysicalDisks::~CEnumPhysicalDisks //*************************************************************************// ///////////////////////////////////////////////////////////////////////////// // CEnumPhysicalDisks -- IUnknown interface. ///////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// //++ // // CEnumPhysicalDisks::AddRef // // Description: // Increment the reference count of this object by one. // // Arguments: // None. // // Return Value: // The new reference count. // // Remarks: // None. // //-- ////////////////////////////////////////////////////////////////////////////// STDMETHODIMP_( ULONG ) CEnumPhysicalDisks::AddRef( void ) { TraceFunc( "[IUnknown]" ); InterlockedIncrement( & m_cRef ); CRETURN( m_cRef ); } //*** CEnumPhysicalDisks::AddRef ////////////////////////////////////////////////////////////////////////////// //++ // // CEnumPhysicalDisks::Release // // Description: // Decrement the reference count of this object by one. // // Arguments: // None. // // Return Value: // The new reference count. // // Remarks: // None. // //-- ////////////////////////////////////////////////////////////////////////////// STDMETHODIMP_( ULONG ) CEnumPhysicalDisks::Release( void ) { TraceFunc( "[IUnknown]" ); LONG cRef; cRef = InterlockedDecrement( &m_cRef ); if ( cRef == 0 ) { TraceDo( delete this ); } // if: reference count equal to zero CRETURN( cRef ); } //*** CEnumPhysicalDisks::Release ////////////////////////////////////////////////////////////////////////////// //++ // // CEnumPhysicalDisks::QueryInterface // // Description: // Query this object for the passed in interface. // // Arguments: // riidIn // Id of interface requested. // // ppvOut // Pointer to the requested interface. // // Return Value: // S_OK // If the interface is available on this object. // // E_NOINTERFACE // If the interface is not available. // // E_POINTER // ppvOut was NULL. // // Remarks: // None. // //-- ////////////////////////////////////////////////////////////////////////////// STDMETHODIMP CEnumPhysicalDisks::QueryInterface( REFIID riidIn , void ** ppvOut ) { TraceQIFunc( riidIn, ppvOut ); HRESULT hr = S_OK; // // Validate arguments. // Assert( ppvOut != NULL ); if ( ppvOut == NULL ) { hr = THR( E_POINTER ); goto Cleanup; } // // Handle known interfaces. // if ( IsEqualIID( riidIn, IID_IUnknown ) ) { *ppvOut = static_cast< IEnumClusCfgManagedResources * >( this ); } // if: IUnknown else if ( IsEqualIID( riidIn, IID_IEnumClusCfgManagedResources ) ) { *ppvOut = TraceInterface( __THISCLASS__, IEnumClusCfgManagedResources, this, 0 ); } // else if: IEnumClusCfgManagedResources else if ( IsEqualIID( riidIn, IID_IClusCfgWbemServices ) ) { *ppvOut = TraceInterface( __THISCLASS__, IClusCfgWbemServices, this, 0 ); } // else if: IClusCfgWbemServices else if ( IsEqualIID( riidIn, IID_IClusCfgInitialize ) ) { *ppvOut = TraceInterface( __THISCLASS__, IClusCfgInitialize, this, 0 ); } // else if: IClusCfgInitialize else { *ppvOut = NULL; hr = E_NOINTERFACE; } // // Add a reference to the interface if successful. // if ( SUCCEEDED( hr ) ) { ((IUnknown *) *ppvOut)->AddRef(); } // if: success Cleanup: QIRETURN_IGNORESTDMARSHALLING( hr, riidIn ); } //*** CEnumPhysicalDisks::QueryInterface //*************************************************************************// ///////////////////////////////////////////////////////////////////////////// // CEnumPhysicalDisks -- IClusCfgWbemServices interface. ///////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// //++ // // CEnumPhysicalDisks::SetWbemServices // // Description: // Set the WBEM services provider. // // Arguments: // IN IWbemServices pIWbemServicesIn // // Return Value: // S_OK // Success // // E_POINTER // The pIWbemServicesIn param is NULL. // // Remarks: // None. // //-- ////////////////////////////////////////////////////////////////////////////// STDMETHODIMP CEnumPhysicalDisks::SetWbemServices( IWbemServices * pIWbemServicesIn ) { TraceFunc( "[IClusCfgWbemServices]" ); HRESULT hr = S_OK; if ( pIWbemServicesIn == NULL ) { hr = THR( E_POINTER ); STATUS_REPORT_REF( TASKID_Major_Find_Devices, TASKID_Minor_SetWbemServices_Enum_PhysDisk, IDS_ERROR_NULL_POINTER, IDS_ERROR_NULL_POINTER_REF, hr ); goto Cleanup; } // if: m_pIWbemServices = pIWbemServicesIn; m_pIWbemServices->AddRef(); hr = THR( HrGetSystemDevice( &m_bstrSystemDevice ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: hr = THR( HrConvertDeviceVolumeToLogicalDisk( m_bstrSystemDevice, &m_bstrSystemLogicalDisk ) ); if ( HRESULT_CODE( hr ) == ERROR_INVALID_FUNCTION ) { // // system volume is an EFI volume on IA64 and won't have a logical disk. // hr = THR( HrConvertDeviceVolumeToWMIDeviceID( m_bstrSystemDevice, &m_bstrSystemWMIDeviceID ) ); Assert( m_bstrSystemLogicalDisk == NULL ); Assert( m_bstrSystemWMIDeviceID != NULL ); } // if: if ( FAILED( hr ) ) { goto Cleanup; } // if: hr = THR( HrGetBootLogicalDisk( &m_bstrBootLogicalDisk ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: hr = STHR( HrIsLogicalDiskNTFS( m_bstrBootLogicalDisk ) ); if ( hr == S_FALSE ) { STATUS_REPORT_REF( TASKID_Major_Find_Devices , TASKID_Minor_Boot_Partition_Not_NTFS , IDS_WARN_BOOT_PARTITION_NOT_NTFS , IDS_WARN_BOOT_PARTITION_NOT_NTFS_REF , hr ); hr = S_OK; } // if: hr = THR( HrGetCrashDumpLogicalDisk( &m_bstrCrashDumpLogicalDisk ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: Cleanup: HRETURN( hr ); } //*** CEnumPhysicalDisks::SetWbemServices //*************************************************************************// ///////////////////////////////////////////////////////////////////////////// // CEnumPhysicalDisks -- IClusCfgInitialize interface. ///////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// //++ // // CEnumPhysicalDisks::Initialize // // Description: // Initialize this component. // // Arguments: // punkCallbackIn // lcidIn // // Return Value: // S_OK - Success. // E_INVALIDARG - Required input argument not specified. // Other HRESULTs. // //-- ////////////////////////////////////////////////////////////////////////////// STDMETHODIMP CEnumPhysicalDisks::Initialize( IUnknown * punkCallbackIn , LCID lcidIn ) { TraceFunc( "[IClusCfgInitialize]" ); Assert( m_picccCallback == NULL ); HRESULT hr = S_OK; m_lcid = lcidIn; if ( punkCallbackIn == NULL ) { hr = THR( E_INVALIDARG ); goto Cleanup; } // if: hr = THR( punkCallbackIn->TypeSafeQI( IClusCfgCallback, &m_picccCallback ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: hr = THR( HrGetComputerName( ComputerNameDnsHostname , &m_bstrNodeName , TRUE // fBestEffortIn ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: Cleanup: HRETURN( hr ); } //*** CEnumPhysicalDisks::Initialize //*************************************************************************// ///////////////////////////////////////////////////////////////////////////// // CEnumPhysicalDisks -- IEnumClusCfgManagedResources interface. ///////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// //++ // // CEnumPhysicalDisks::Next // // Description: // // Arguments: // // Return Value: // // Remarks: // None. // //-- ////////////////////////////////////////////////////////////////////////////// STDMETHODIMP CEnumPhysicalDisks::Next( ULONG cNumberRequestedIn, IClusCfgManagedResourceInfo ** rgpManagedResourceInfoOut, ULONG * pcNumberFetchedOut ) { TraceFunc( "[IEnumClusCfgManagedResources]" ); HRESULT hr = S_FALSE; ULONG cFetched = 0; IClusCfgManagedResourceInfo * pccsdi; IUnknown * punk; ULONG ulStop; if ( rgpManagedResourceInfoOut == NULL ) { hr = THR( E_POINTER ); STATUS_REPORT_REF( TASKID_Major_Find_Devices, TASKID_Minor_Next_Enum_PhysDisk, IDS_ERROR_NULL_POINTER, IDS_ERROR_NULL_POINTER_REF, hr ); goto Cleanup; } // if: if ( !m_fLoadedDevices ) { hr = THR( HrLoadEnum() ); if ( FAILED( hr ) ) { goto Cleanup; } // if: } // if: ulStop = min( cNumberRequestedIn, ( m_idxNext - m_idxEnumNext ) ); for ( hr = S_OK; ( cFetched < ulStop ) && ( m_idxEnumNext < m_idxNext ); m_idxEnumNext++ ) { punk = (*m_prgDisks)[ m_idxEnumNext ]; if ( punk != NULL ) { hr = THR( punk->TypeSafeQI( IClusCfgManagedResourceInfo, &pccsdi ) ); if ( FAILED( hr ) ) { break; } // if: rgpManagedResourceInfoOut[ cFetched++ ] = pccsdi; } // if: } // for: if ( FAILED( hr ) ) { m_idxEnumNext -= cFetched; while ( cFetched != 0 ) { (rgpManagedResourceInfoOut[ --cFetched ])->Release(); } // for: goto Cleanup; } // if: if ( cFetched < cNumberRequestedIn ) { hr = S_FALSE; } // if: Cleanup: if ( pcNumberFetchedOut != NULL ) { *pcNumberFetchedOut = cFetched; } // if: HRETURN( hr ); } //*** CEnumPhysicalDisks::Next ////////////////////////////////////////////////////////////////////////////// //++ // // CEnumPhysicalDisks::Skip // // Description: // // Arguments: // // Return Value: // // Remarks: // None. // //-- ////////////////////////////////////////////////////////////////////////////// STDMETHODIMP CEnumPhysicalDisks::Skip( ULONG cNumberToSkipIn ) { TraceFunc( "[IEnumClusCfgManagedResources]" ); HRESULT hr = S_OK; m_idxEnumNext += cNumberToSkipIn; if ( m_idxEnumNext >= m_idxNext ) { m_idxEnumNext = m_idxNext; hr = STHR( S_FALSE ); } // if: HRETURN( hr ); } //*** CEnumPhysicalDisks::Skip ////////////////////////////////////////////////////////////////////////////// //++ // // CEnumPhysicalDisks::Reset // // Description: // // Arguments: // // Return Value: // // Remarks: // None. // //-- ////////////////////////////////////////////////////////////////////////////// STDMETHODIMP CEnumPhysicalDisks::Reset( void ) { TraceFunc( "[IEnumClusCfgManagedResources]" ); m_idxEnumNext = 0; HRETURN( S_OK ); } //*** CEnumPhysicalDisks::Reset ////////////////////////////////////////////////////////////////////////////// //++ // // CEnumPhysicalDisks::Clone // // Description: // // Arguments: // // Return Value: // // Remarks: // None. // //-- ////////////////////////////////////////////////////////////////////////////// STDMETHODIMP CEnumPhysicalDisks::Clone( IEnumClusCfgManagedResources ** ppEnumClusCfgStorageDevicesOut ) { TraceFunc( "[IEnumClusCfgManagedResources]" ); HRESULT hr = S_OK; if ( ppEnumClusCfgStorageDevicesOut == NULL ) { hr = THR( E_POINTER ); STATUS_REPORT_REF( TASKID_Major_Find_Devices, TASKID_Minor_Clone_Enum_PhysDisk, IDS_ERROR_NULL_POINTER, IDS_ERROR_NULL_POINTER_REF, hr ); goto Cleanup; } // if: hr = THR( E_NOTIMPL ); Cleanup: HRETURN( hr ); } //*** CEnumPhysicalDisks::Clone ////////////////////////////////////////////////////////////////////////////// //++ // // CEnumPhysicalDisks::Count // // Description: // Return the count of items in the Enum. // // Arguments: // // Return Value: // // Remarks: // None. // //-- ////////////////////////////////////////////////////////////////////////////// STDMETHODIMP CEnumPhysicalDisks::Count( DWORD * pnCountOut ) { TraceFunc( "[IEnumClusCfgManagedResources]" ); HRESULT hr = S_OK; if ( pnCountOut == NULL ) { hr = THR( E_POINTER ); goto Cleanup; } // if: if ( !m_fLoadedDevices ) { hr = THR( HrLoadEnum() ); if ( FAILED( hr ) ) { goto Cleanup; } // if: } // if: *pnCountOut = m_cDiskCount; Cleanup: HRETURN( hr ); } //*** CEnumPhysicalDisks::Count //*************************************************************************// ///////////////////////////////////////////////////////////////////////////// // CEnumPhysicalDisks class -- Private Methods. ///////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// //++ // // CEnumPhysicalDisks::HrInit // // Description: // Initialize this component. // // Arguments: // None. // // Return Value: // // // Remarks: // None. // //-- ////////////////////////////////////////////////////////////////////////////// HRESULT CEnumPhysicalDisks::HrInit( void ) { TraceFunc( "" ); HRESULT hr = S_OK; // IUnknown Assert( m_cRef == 1 ); HRETURN( hr ); } //*** CEnumPhysicalDisks::HrInit ///////////////////////////////////////////////////////////////////////////// //++ // // CEnumPhysicalDisks::HrGetDisks // // Description: // // Arguments: // // // Return Value: // // // Remarks: // None. // //-- ////////////////////////////////////////////////////////////////////////////// HRESULT CEnumPhysicalDisks::HrGetDisks( void ) { TraceFunc( "" ); HRESULT hr = S_FALSE; BSTR bstrClass; IEnumWbemClassObject * pDisks = NULL; ULONG ulReturned; IWbemClassObject * pDisk = NULL; bstrClass = TraceSysAllocString( L"Win32_DiskDrive" ); if ( bstrClass == NULL ) { hr = THR( E_OUTOFMEMORY ); STATUS_REPORT_REF( TASKID_Major_Find_Devices, TASKID_Minor_HrGetDisks, IDS_ERROR_OUTOFMEMORY, IDS_ERROR_OUTOFMEMORY_REF, hr ); goto Cleanup; } // if: hr = THR( m_pIWbemServices->CreateInstanceEnum( bstrClass, WBEM_FLAG_SHALLOW, NULL, &pDisks ) ); if ( FAILED( hr ) ) { STATUS_REPORT_REF( TASKID_Major_Find_Devices , TASKID_Minor_WMI_Phys_Disks_Qry_Failed , IDS_ERROR_WMI_PHYS_DISKS_QRY_FAILED , IDS_ERROR_WMI_PHYS_DISKS_QRY_FAILED_REF , hr ); goto Cleanup; } // if: for ( ; ; ) { hr = pDisks->Next( WBEM_INFINITE, 1, &pDisk, &ulReturned ); if ( ( hr == S_OK ) && ( ulReturned == 1 ) ) { hr = STHR( HrLogDiskInfo( pDisk ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: hr = STHR( IsDiskSCSI( pDisk ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: if ( hr == S_OK ) { hr = STHR( HrCreateAndAddDiskToArray( pDisk ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: } // if: pDisk->Release(); pDisk = NULL; } // if: else if ( ( hr == S_FALSE ) && ( ulReturned == 0 ) ) { hr = S_OK; break; } // else if: else { STATUS_REPORT_STRING_REF( TASKID_Major_Find_Devices , TASKID_Minor_WQL_Disk_Qry_Next_Failed , IDS_ERROR_WQL_QRY_NEXT_FAILED , bstrClass , IDS_ERROR_WQL_QRY_NEXT_FAILED_REF , hr ); goto Cleanup; } // else: } // for: m_idxEnumNext = 0; m_fLoadedDevices = TRUE; goto Cleanup; Cleanup: if ( pDisk != NULL ) { pDisk->Release(); } // if: if ( pDisks != NULL ) { pDisks->Release(); } // if: TraceSysFreeString( bstrClass ); HRETURN( hr ); } //*** CEnumPhysicalDisks::HrGetDisks ///////////////////////////////////////////////////////////////////////////// //++ // // CEnumPhysicalDisks::HrCreateAndAddDiskToArray // // Description: // Create a IClusCfgStorageDevice object and add the passed in disk to // the array of punks that holds the disks. // // Arguments: // // // Return Value: // S_OK // Success // // E_OUTOFMEMORY // Couldn't allocate memeory. // // Remarks: // None. // //-- ////////////////////////////////////////////////////////////////////////////// HRESULT CEnumPhysicalDisks::HrCreateAndAddDiskToArray( IWbemClassObject * pDiskIn ) { TraceFunc( "" ); HRESULT hr = S_FALSE; IUnknown * punk = NULL; IClusCfgSetWbemObject * piccswo = NULL; bool fRetainObject = true; hr = THR( CPhysicalDisk::S_HrCreateInstance( &punk ) ); if ( FAILED( hr ) ) { goto Exit; } // if: punk = TraceInterface( L"CPhysicalDisk", IUnknown, punk, 1 ); hr = THR( HrSetInitialize( punk, m_picccCallback, m_lcid ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: hr = THR( HrSetWbemServices( punk, m_pIWbemServices ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: hr = THR( punk->TypeSafeQI( IClusCfgSetWbemObject, &piccswo ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: hr = STHR( piccswo->SetWbemObject( pDiskIn, &fRetainObject ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: if ( fRetainObject ) { hr = THR( HrAddDiskToArray( punk ) ); } // if: Cleanup: if ( piccswo != NULL ) { piccswo->Release(); } // if: punk->Release(); Exit: HRETURN( hr ); } //*** CEnumPhysicalDisks::HrCreateAndAddDiskToArray ///////////////////////////////////////////////////////////////////////////// //++ // // CEnumPhysicalDisks::HrPruneSystemDisks // // Description: // Prune all system disks from the list. System disks are disks that // are booted, are running the OS, or have page files. // // Arguments: // // // Return Value: // S_OK // Success // // E_OUTOFMEMORY // Couldn't allocate memeory. // // Remarks: // //-- ////////////////////////////////////////////////////////////////////////////// HRESULT CEnumPhysicalDisks::HrPruneSystemDisks( void ) { TraceFunc( "" ); Assert( m_bstrSystemLogicalDisk != NULL ); Assert( m_bstrBootLogicalDisk != NULL ); HRESULT hr = S_OK; ULONG idx; ULONG ulSCSIBus; ULONG ulSCSIPort; IClusCfgPhysicalDiskProperties * piccpdp = NULL; IUnknown * punk; ULONG cRemoved = 0; ULONG cTemp = 0; bool fSystemAndBootTheSame; bool fPruneBus = false; fSystemAndBootTheSame = ( m_bstrSystemLogicalDisk != NULL ) ? ( m_bstrBootLogicalDisk[ 0 ] == m_bstrSystemLogicalDisk[ 0 ] ) : false; hr = STHR( HrIsSystemBusManaged() ); if ( FAILED( hr ) ) { goto Cleanup; } // if: // // If the system bus is not managed then we need to prune the disks on those buses // that contain system, boot, and pagefile disks. // if ( hr == S_FALSE ) { fPruneBus = true; } // if: // // Prune the disks on the system buses. If the system disks are IDE they won't // be in the list. // // // Find the boot disk(s). Could be a volume with more than one physical disk. // for ( ; ; ) { hr = STHR( HrFindDiskWithLogicalDisk( m_bstrBootLogicalDisk[ 0 ], &idx ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: if ( hr == S_OK ) { // // Should we prune the whole bus, or just the boot disk itself? // if ( fPruneBus ) { hr = THR( HrGetSCSIInfo( idx, &ulSCSIBus, &ulSCSIPort ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: STATUS_REPORT( TASKID_Major_Find_Devices, TASKID_Minor_Pruning_Boot_Disk_Bus, IDS_INFO_PRUNING_BOOTDISK_BUS, hr ); hr = THR( HrPruneDisks( ulSCSIBus , ulSCSIPort , &TASKID_Minor_Pruning_Boot_Disk_Bus , IDS_INFO_BOOTDISK_PRUNED , IDS_INFO_BOOTDISK_PRUNED_REF , &cTemp ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: cRemoved += cTemp; } // if: else { RemoveDiskFromArray( idx ); cRemoved++; } // else: continue; } // if: break; } // for: // // Prune the system disk bus if it is not the same as the boot disk bus. // if ( !fSystemAndBootTheSame ) { if ( m_bstrSystemLogicalDisk != NULL ) { Assert( m_bstrSystemWMIDeviceID == NULL ); hr = STHR( HrFindDiskWithLogicalDisk( m_bstrSystemLogicalDisk[ 0 ], &idx ) ); } // if: else { Assert( m_bstrSystemLogicalDisk == NULL ); hr = STHR( HrFindDiskWithWMIDeviceID( m_bstrSystemWMIDeviceID, &idx ) ); } // else: if ( FAILED( hr ) ) { goto Cleanup; } // if: if ( hr == S_OK ) { // // Should we prune the whole bus, or just the system disk itself? // if ( fPruneBus ) { hr = THR( HrGetSCSIInfo( idx, &ulSCSIBus, &ulSCSIPort ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: STATUS_REPORT( TASKID_Major_Find_Devices, TASKID_Minor_Pruning_System_Disk_Bus, IDS_INFO_PRUNING_SYSTEMDISK_BUS, hr ); hr = THR( HrPruneDisks( ulSCSIBus , ulSCSIPort , &TASKID_Minor_Pruning_System_Disk_Bus , IDS_INFO_SYSTEMDISK_PRUNED , IDS_INFO_SYSTEMDISK_PRUNED_REF , &cTemp ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: cRemoved += cTemp; } // if: else { RemoveDiskFromArray( idx ); cRemoved++; } // else: } // if: } // if: // // Now prune the busses that have page file disks on them. // hr = THR( HrPrunePageFileDiskBussess( fPruneBus, &cTemp ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: cRemoved += cTemp; // // Now prune the bus that has a crash dump file disk. // hr = THR( HrPruneCrashDumpBus( fPruneBus, &cTemp ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: cRemoved += cTemp; // // Now prune the off any remaining dynamic disks. // hr = THR( HrPruneDynamicDisks( &cTemp ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: cRemoved += cTemp; // // Now prune the off any remaining GPT disks. // hr = THR( HrPruneGPTDisks( &cTemp ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: cRemoved += cTemp; // // Last ditch effort to properly set the managed state of the remaining disks. // for ( idx = 0; ( cRemoved < m_idxNext ) && ( idx < m_idxNext ); idx++ ) { punk = (*m_prgDisks)[ idx ]; // don't ref if ( punk != NULL ) { hr = THR( punk->TypeSafeQI( IClusCfgPhysicalDiskProperties, &piccpdp ) ); if ( FAILED( hr ) ) { LOG_STATUS_REPORT( L"Could not query for the IClusCfgPhysicalDiskProperties interface.", hr ); goto Cleanup; } // if: // // Give the disk a chance to figure out for itself if it should be managed. // hr = STHR( piccpdp->CanBeManaged() ); if ( FAILED( hr ) ) { goto Cleanup; } // if: piccpdp->Release(); piccpdp = NULL; } // if: } // for: // // Minor optimization. If we removed all of the elements reset the enum next to 0. // if ( cRemoved == m_idxNext ) { m_idxNext = 0; } // if: hr = S_OK; Cleanup: if ( piccpdp != NULL ) { piccpdp->Release(); } // if: HRETURN( hr ); } //*** CEnumPhysicalDisks::HrPruneSystemDisks ///////////////////////////////////////////////////////////////////////////// //++ // // CEnumPhysicalDisks::IsDiskSCSI // // Description: // // Arguments: // // // Return Value: // S_OK // Disk is SCSI. // // S_FALSE // Disk is not SCSI. // // E_OUTOFMEMORY // Couldn't allocate memeory. // // Remarks: // //-- ////////////////////////////////////////////////////////////////////////////// HRESULT CEnumPhysicalDisks::IsDiskSCSI( IWbemClassObject * pDiskIn ) { TraceFunc( "" ); Assert( pDiskIn != NULL ); HRESULT hr; VARIANT var; VariantInit( &var ); hr = THR( HrGetWMIProperty( pDiskIn, L"InterfaceType", VT_BSTR, &var ) ); if ( SUCCEEDED( hr ) ) { if ( ( NStringCchCompareCase( L"SCSI", RTL_NUMBER_OF( L"SCSI" ), var.bstrVal, SysStringLen( var.bstrVal ) + 1 ) == 0 ) ) { hr = S_OK; } // if: else { hr = S_FALSE; } // else: } // if: VariantClear( &var ); HRETURN( hr ); } //*** CEnumPhysicalDisks::IsDiskSCSI ///////////////////////////////////////////////////////////////////////////// //++ // // CEnumPhysicalDisks:HrAddDiskToArray // // Description: // Add the passed in disk to the array of punks that holds the disks. // // Arguments: // // // Return Value: // S_OK // Success // // E_OUTOFMEMORY // Couldn't allocate memeory. // // Remarks: // None. // //-- ////////////////////////////////////////////////////////////////////////////// HRESULT CEnumPhysicalDisks::HrAddDiskToArray( IUnknown * punkIn ) { TraceFunc( "" ); Assert( punkIn != NULL ); HRESULT hr = S_OK; IUnknown * ((*prgpunks)[]) = NULL; prgpunks = (IUnknown *((*)[])) TraceReAlloc( m_prgDisks, sizeof( IUnknown * ) * ( m_idxNext + 1 ), HEAP_ZERO_MEMORY ); if ( prgpunks == NULL ) { hr = THR( E_OUTOFMEMORY ); STATUS_REPORT_REF( TASKID_Major_Find_Devices, TASKID_Minor_HrAddDiskToArray, IDS_ERROR_OUTOFMEMORY, IDS_ERROR_OUTOFMEMORY_REF, hr ); goto Cleanup; } // if: m_prgDisks = prgpunks; (*m_prgDisks)[ m_idxNext++ ] = punkIn; punkIn->AddRef(); m_cDiskCount += 1; Cleanup: HRETURN( hr ); } //*** CEnumPhysicalDisks::HrAddDiskToArray ///////////////////////////////////////////////////////////////////////////// //++ // // CEnumPhysicalDisks:HrFixupDisks // // Description: // Tweak the disks to better reflect how they are managed by this node. // // Arguments: // None. // // Return Value: // S_OK // Success. // // Win32 Error // something failed. // // Remarks: // None. // //-- ////////////////////////////////////////////////////////////////////////////// HRESULT CEnumPhysicalDisks::HrFixupDisks( void ) { TraceFunc( "" ); HRESULT hr = S_OK; BSTR bstrLocalNetBIOSName = NULL; // // Get netbios name for clusapi calls. // hr = THR( HrGetComputerName( ComputerNameNetBIOS, &bstrLocalNetBIOSName, TRUE ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: // // If the cluster service is running then load any physical disk // resources that we own. // hr = STHR( HrIsClusterServiceRunning() ); if ( hr == S_OK ) { hr = THR( HrEnumNodeResources( bstrLocalNetBIOSName ) ); } else if ( hr == S_FALSE ) { hr = S_OK; } // else: Cleanup: TraceSysFreeString( bstrLocalNetBIOSName ); HRETURN( hr ); } //*** CEnumPhysicalDisks::HrFixupDisks ///////////////////////////////////////////////////////////////////////////// //++ // // CEnumPhysicalDisks:HrNodeResourceCallback // // Description: // Called by CClusterUtils::HrEnumNodeResources() when it finds a // resource for this node. // // Arguments: // // // Return Value: // S_OK // Success. // // Win32 Error // something failed. // // Remarks: // None. // //-- ////////////////////////////////////////////////////////////////////////////// HRESULT CEnumPhysicalDisks::HrNodeResourceCallback( HCLUSTER hClusterIn, HRESOURCE hResourceIn ) { TraceFunc( "" ); HRESULT hr = S_OK; CLUS_SCSI_ADDRESS csa; DWORD dwSignature; BOOL fIsQuorum; BSTR bstrResourceName = NULL; hr = STHR( HrIsResourceOfType( hResourceIn, L"Physical Disk" ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: // // If this resource is not a physical disk then we simply want to // skip it. // if ( hr == S_FALSE ) { goto Cleanup; } // if: hr = STHR( HrIsCoreResource( hResourceIn ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: fIsQuorum = ( hr == S_OK ); hr = THR( HrGetClusterDiskInfo( hClusterIn, hResourceIn, &csa, &dwSignature ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: hr = THR( HrGetClusterProperties( hResourceIn, &bstrResourceName ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: hr = THR( HrSetThisDiskToBeManaged( csa.TargetId, csa.Lun, fIsQuorum, bstrResourceName, dwSignature ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: Cleanup: TraceSysFreeString( bstrResourceName ); HRETURN( hr ); } //*** CEnumPhysicalDisks::HrNodeResourceCallback ///////////////////////////////////////////////////////////////////////////// //++ // // CEnumPhysicalDisks:HrGetClusterDiskInfo // // Description: // // // Arguments: // // // Return Value: // S_OK // Success. // // Win32 Error // something failed. // // Remarks: // None. // //-- ////////////////////////////////////////////////////////////////////////////// HRESULT CEnumPhysicalDisks::HrGetClusterDiskInfo( HCLUSTER hClusterIn, HRESOURCE hResourceIn, CLUS_SCSI_ADDRESS * pcsaOut, DWORD * pdwSignatureOut ) { TraceFunc( "" ); HRESULT hr = S_OK; DWORD sc; CClusPropValueList cpvl; CLUSPROP_BUFFER_HELPER cbhValue = { NULL }; sc = TW32( cpvl.ScGetResourceValueList( hResourceIn, CLUSCTL_RESOURCE_STORAGE_GET_DISK_INFO ) ); if ( sc != ERROR_SUCCESS ) { hr = HRESULT_FROM_WIN32( sc ); goto Cleanup; } // if: sc = TW32( cpvl.ScMoveToFirstValue() ); if ( sc != ERROR_SUCCESS ) { hr = HRESULT_FROM_WIN32( sc ); goto Cleanup; } // if: for ( ; ; ) { cbhValue = cpvl; switch ( cbhValue.pSyntax->dw ) { case CLUSPROP_SYNTAX_PARTITION_INFO : { break; } // case: CLUSPROP_SYNTAX_PARTITION_INFO case CLUSPROP_SYNTAX_DISK_SIGNATURE : { *pdwSignatureOut = cbhValue.pDiskSignatureValue->dw; break; } // case: CLUSPROP_SYNTAX_DISK_SIGNATURE case CLUSPROP_SYNTAX_SCSI_ADDRESS : { pcsaOut->dw = cbhValue.pScsiAddressValue->dw; break; } // case: CLUSPROP_SYNTAXscSI_ADDRESS case CLUSPROP_SYNTAX_DISK_NUMBER : { break; } // case: CLUSPROP_SYNTAX_DISK_NUMBER } // switch: sc = cpvl.ScMoveToNextValue(); if ( sc == ERROR_SUCCESS ) { continue; } // if: if ( sc == ERROR_NO_MORE_ITEMS ) { break; } // if: error occurred moving to the next value hr = HRESULT_FROM_WIN32( TW32( sc ) ); goto Cleanup; } // for: Cleanup: HRETURN( hr ); } //*** CEnumPhysicalDisks::HrGetClusterDiskInfo ///////////////////////////////////////////////////////////////////////////// //++ // // CEnumPhysicalDisks:HrSetThisDiskToBeManaged // // Description: // // // Arguments: // // // Return Value: // S_OK // Success. // // Win32 Error // something failed. // // Remarks: // None. // //-- ////////////////////////////////////////////////////////////////////////////// HRESULT CEnumPhysicalDisks::HrSetThisDiskToBeManaged( ULONG ulSCSITidIn , ULONG ulSCSILunIn , BOOL fIsQuorumIn , BSTR bstrResourceNameIn , DWORD dwSignatureIn ) { TraceFunc( "" ); HRESULT hr = S_OK; ULONG idx; IUnknown * punk = NULL; IClusCfgManagedResourceInfo * piccmri = NULL; WCHAR sz[ 64 ]; BSTR bstrUID = NULL; DWORD dwSignature; IClusCfgPhysicalDiskProperties * piccpdp = NULL; hr = THR( StringCchPrintfW( sz, ARRAYSIZE( sz ), L"SCSI Tid %ld, SCSI Lun %ld", ulSCSITidIn, ulSCSILunIn ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: // // Find the disk that has the passes in TID and Lun and set it // to be managed. // for ( idx = 0; idx < m_idxNext; idx++ ) { punk = (*m_prgDisks)[ idx ]; // don't ref if ( punk != NULL ) { hr = THR( punk->TypeSafeQI( IClusCfgManagedResourceInfo, &piccmri ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: hr = THR( piccmri->GetUID( &bstrUID ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: TraceMemoryAddBSTR( bstrUID ); if ( NStringCchCompareNoCase( bstrUID, SysStringLen( bstrUID ) + 1, sz, RTL_NUMBER_OF( sz ) ) == 0 ) { hr = THR( piccmri->TypeSafeQI( IClusCfgPhysicalDiskProperties, &piccpdp ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: hr = THR( piccpdp->HrGetSignature( &dwSignature ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: hr = THR( piccpdp->HrSetFriendlyName( bstrResourceNameIn ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: piccpdp->Release(); piccpdp = NULL; // // May want to do more with this later... // Assert( dwSignatureIn == dwSignature ); hr = THR( piccmri->SetManaged( TRUE ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: hr = THR( piccmri->SetQuorumResource( fIsQuorumIn ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: break; } // if: TraceSysFreeString( bstrUID ); bstrUID = NULL; piccmri->Release(); piccmri = NULL; } // if: } // for: Cleanup: if ( piccpdp != NULL ) { piccpdp->Release(); } // if: if ( piccmri != NULL ) { piccmri->Release(); } // if: TraceSysFreeString( bstrUID ); HRETURN( hr ); } //*** CEnumPhysicalDisks::HrSetThisDiskToBeManaged ///////////////////////////////////////////////////////////////////////////// //++ // // CEnumPhysicalDisks:HrFindDiskWithLogicalDisk // // Description: // Find the disk with the passed in logical disk ID. // // Arguments: // None. // // Return Value: // S_OK // Success. Found the disk. // // S_FALSE // Success. Did not find the disk. // // Win32 Error // something failed. // // Remarks: // None. // //-- ////////////////////////////////////////////////////////////////////////////// HRESULT CEnumPhysicalDisks::HrFindDiskWithLogicalDisk( WCHAR cLogicalDiskIn, ULONG * pidxDiskOut ) { TraceFunc( "" ); Assert( pidxDiskOut != NULL ); HRESULT hr = S_OK; IClusCfgPhysicalDiskProperties * piccpdp = NULL; ULONG idx; bool fFoundIt = false; IUnknown * punk; for ( idx = 0; idx < m_idxNext; idx++ ) { punk = (*m_prgDisks)[ idx ]; // don't ref if ( punk != NULL ) { hr = THR( punk->TypeSafeQI( IClusCfgPhysicalDiskProperties, &piccpdp ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: hr = STHR( piccpdp->IsThisLogicalDisk( cLogicalDiskIn ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: if ( hr == S_OK ) { fFoundIt = true; break; } // if: piccpdp->Release(); piccpdp = NULL; } // if: } // for: if ( !fFoundIt ) { hr = S_FALSE; } // if: if ( pidxDiskOut != NULL ) { *pidxDiskOut = idx; } // if: Cleanup: if ( piccpdp != NULL ) { piccpdp->Release(); } // if: HRETURN( hr ); } //*** CEnumPhysicalDisks::HrFindDiskWithLogicalDisk ///////////////////////////////////////////////////////////////////////////// //++ // // CEnumPhysicalDisks:HrGetSCSIInfo // // Description: // Get the SCSI info for the disk at the passed in index. // // Arguments: // None. // // Return Value: // S_OK // Success. // // Win32 Error // something failed. // // Remarks: // None. // //-- ////////////////////////////////////////////////////////////////////////////// HRESULT CEnumPhysicalDisks::HrGetSCSIInfo( ULONG idxDiskIn, ULONG * pulSCSIBusOut, ULONG * pulSCSIPortOut ) { TraceFunc( "" ); Assert( pulSCSIBusOut != NULL ); Assert( pulSCSIPortOut != NULL ); HRESULT hr = S_OK; IClusCfgPhysicalDiskProperties * piccpdp = NULL; hr = THR( ((*m_prgDisks)[ idxDiskIn ])->TypeSafeQI( IClusCfgPhysicalDiskProperties, &piccpdp ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: hr = THR( piccpdp->HrGetSCSIBus( pulSCSIBusOut ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: hr = THR( piccpdp->HrGetSCSIPort( pulSCSIPortOut ) ); Cleanup: if ( piccpdp != NULL ) { piccpdp->Release(); } // if: HRETURN( hr ); } //*** CEnumPhysicalDisks::HrGetSCSIInfo ///////////////////////////////////////////////////////////////////////////// //++ // // CEnumPhysicalDisks:HrPruneDisks // // Description: // Get the SCSI info for the disk at the passed in index. // // Arguments: // None. // // Return Value: // S_OK // Success. // // Win32 Error // something failed. // // Remarks: // None. // //-- ////////////////////////////////////////////////////////////////////////////// HRESULT CEnumPhysicalDisks::HrPruneDisks( ULONG ulSCSIBusIn , ULONG ulSCSIPortIn , const GUID * pcguidMajorIdIn , int nMsgIdIn , int nRefIdIn , ULONG * pulRemovedOut ) { TraceFunc( "" ); Assert( pulRemovedOut != NULL ); HRESULT hr = S_OK; IClusCfgPhysicalDiskProperties * piccpdp = NULL; ULONG idx; IUnknown * punk; ULONG ulSCSIBus; ULONG ulSCSIPort; ULONG cRemoved = 0; for ( idx = 0; idx < m_idxNext; idx++ ) { punk = (*m_prgDisks)[ idx ]; // don't ref if ( punk != NULL ) { hr = THR( punk->TypeSafeQI( IClusCfgPhysicalDiskProperties, &piccpdp ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: hr = THR( piccpdp->HrGetSCSIBus( &ulSCSIBus ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: hr = THR( piccpdp->HrGetSCSIPort( &ulSCSIPort ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: if ( ( ulSCSIBusIn == ulSCSIBus ) && ( ulSCSIPortIn == ulSCSIPort ) ) { BSTR bstr = NULL; IClusCfgManagedResourceInfo * piccmri = NULL; HRESULT hrTemp; CLSID clsidMinorId; hrTemp = THR( CoCreateGuid( &clsidMinorId ) ); if ( FAILED( hrTemp ) ) { LogMsg( L"[SRV] Could not create a guid for a pruning disk minor task ID" ); clsidMinorId = IID_NULL; } // if: LogPrunedDisk( punk, ulSCSIBusIn, ulSCSIPortIn ); THR( ((*m_prgDisks)[ idx ])->TypeSafeQI( IClusCfgManagedResourceInfo, &piccmri ) ); THR( piccmri->GetName( &bstr ) ); if ( piccmri != NULL ) { piccmri->Release(); } // if: TraceMemoryAddBSTR( bstr ); STATUS_REPORT_STRING_REF( *pcguidMajorIdIn, clsidMinorId, nMsgIdIn, bstr != NULL ? bstr : L"????", nRefIdIn, hr ); RemoveDiskFromArray( idx ); cRemoved++; TraceSysFreeString( bstr ); } // if: piccpdp->Release(); piccpdp = NULL; } // if: } // for: if ( pulRemovedOut != NULL ) { *pulRemovedOut = cRemoved; } // if: Cleanup: if ( piccpdp != NULL ) { piccpdp->Release(); } // if: HRETURN( hr ); } //*** CEnumPhysicalDisks::HrPruneDisks ///////////////////////////////////////////////////////////////////////////// //++ // // CEnumPhysicalDisks:LogPrunedDisk // // Description: // Get the SCSI info for the disk at the passed in index. // // Arguments: // None. // // Return Value: // S_OK // Success. // // Win32 Error // something failed. // // Remarks: // None. // //-- ////////////////////////////////////////////////////////////////////////////// void CEnumPhysicalDisks::LogPrunedDisk( IUnknown * punkIn, ULONG ulSCSIBusIn, ULONG ulSCSIPortIn ) { TraceFunc( "" ); Assert( punkIn != NULL ); HRESULT hr = S_OK; IClusCfgManagedResourceInfo * piccmri = NULL; IClusCfgPhysicalDiskProperties * piccpdp = NULL; BSTR bstrName = NULL; BSTR bstrUID = NULL; BSTR bstr = NULL; hr = THR( punkIn->TypeSafeQI( IClusCfgManagedResourceInfo, &piccmri ) ); if ( SUCCEEDED( hr ) ) { hr = THR( piccmri->GetUID( &bstrUID ) ); piccmri->Release(); } // if: if ( FAILED( hr ) ) { bstrUID = TraceSysAllocString( L"" ); } // if: else { TraceMemoryAddBSTR( bstrUID ); } // else: hr = THR( punkIn->TypeSafeQI( IClusCfgPhysicalDiskProperties, &piccpdp ) ); if ( SUCCEEDED( hr ) ) { hr = THR( piccpdp->HrGetDeviceID( &bstrName ) ); piccpdp->Release(); } // if: if ( FAILED( hr ) ) { bstrName = TraceSysAllocString( L"" ); } // if: hr = THR( HrFormatStringIntoBSTR( L"Pruning SCSI disk '%1!ws!', on Bus '%2!d!' and Port '%3!d!'; at '%4!ws!'" , &bstr , bstrName , ulSCSIBusIn , ulSCSIPortIn , bstrUID ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: LOG_STATUS_REPORT( bstr, hr ); Cleanup: TraceSysFreeString( bstrName ); TraceSysFreeString( bstrUID ); TraceSysFreeString( bstr ); TraceFuncExit(); } //*** CEnumPhysicalDisks::LogPrunedDisk ///////////////////////////////////////////////////////////////////////////// //++ // // CEnumPhysicalDisks:HrIsLogicalDiskNTFS // // Description: // Is the passed in logical disk NTFS? // // Arguments: // bstrLogicalDiskIn // // Return Value: // S_OK // The disk is NTFS. // // S_FALSE // The disk is not NTFS. // // Win32 Error // something failed. // // Remarks: // None. // //-- ////////////////////////////////////////////////////////////////////////////// HRESULT CEnumPhysicalDisks::HrIsLogicalDiskNTFS( BSTR bstrLogicalDiskIn ) { TraceFunc1( "bstrLogicalDiskIn = '%ls'", bstrLogicalDiskIn == NULL ? L"" : bstrLogicalDiskIn ); Assert( bstrLogicalDiskIn != NULL ); HRESULT hr = S_OK; IWbemClassObject * pLogicalDisk = NULL; BSTR bstrPath = NULL; WCHAR sz[ 64 ]; VARIANT var; size_t cch; VariantInit( &var ); cch = wcslen( bstrLogicalDiskIn ); if ( cch > 3 ) { hr = THR( E_INVALIDARG ); STATUS_REPORT_REF( TASKID_Major_Find_Devices, TASKID_Minor_HrIsLogicalDiskNTFS_InvalidArg, IDS_ERROR_INVALIDARG, IDS_ERROR_INVALIDARG_REF, hr ); goto Cleanup; } // if: // // truncate off any trailing \'s // if ( bstrLogicalDiskIn[ cch - 1 ] == L'\\' ) { bstrLogicalDiskIn[ cch - 1 ] = '\0'; } // if: // // If we have just the logical disk without the trailing colon... // if ( wcslen( bstrLogicalDiskIn ) == 1 ) { hr = THR( StringCchPrintfW( sz, ARRAYSIZE( sz ), L"Win32_LogicalDisk.DeviceID=\"%ws:\"", bstrLogicalDiskIn ) ); } // if: else { hr = THR( StringCchPrintfW( sz, ARRAYSIZE( sz ), L"Win32_LogicalDisk.DeviceID=\"%ws\"", bstrLogicalDiskIn ) ); } // else: if ( FAILED( hr ) ) { goto Cleanup; } // if: bstrPath = TraceSysAllocString( sz ); if ( bstrPath == NULL ) { hr = THR( E_OUTOFMEMORY ); STATUS_REPORT_REF( TASKID_Major_Find_Devices, TASKID_Minor_HrIsLogicalDiskNTFS, IDS_ERROR_OUTOFMEMORY, IDS_ERROR_OUTOFMEMORY_REF, hr ); } // if: hr = THR( m_pIWbemServices->GetObject( bstrPath, WBEM_FLAG_RETURN_WBEM_COMPLETE, NULL, &pLogicalDisk, NULL ) ); if ( FAILED( hr ) ) { STATUS_REPORT_STRING_REF( TASKID_Major_Find_Devices , TASKID_Minor_WMI_Get_LogicalDisk_Failed , IDS_ERROR_WMI_GET_LOGICALDISK_FAILED , bstrLogicalDiskIn , IDS_ERROR_WMI_GET_LOGICALDISK_FAILED_REF , hr ); goto Cleanup; } // if: hr = THR( HrGetWMIProperty( pLogicalDisk, L"FileSystem", VT_BSTR, &var ) ); if (FAILED( hr ) ) { goto Cleanup; } // if: CharUpper( var.bstrVal ); if ( NStringCchCompareCase( var.bstrVal, SysStringLen( var.bstrVal ) + 1, L"NTFS", RTL_NUMBER_OF( L"NTFS" ) ) != 0 ) { hr = S_FALSE; } // if: Cleanup: if ( pLogicalDisk != NULL ) { pLogicalDisk->Release(); } // if: VariantClear( &var ); TraceSysFreeString( bstrPath ); HRETURN( hr ); } //*** CEnumPhysicalDisks::HrIsLogicalDiskNTFS ///////////////////////////////////////////////////////////////////////////// //++ // // CEnumPhysicalDisks:HrLogDiskInfo // // Description: // Write the info about this disk into the log. // // Arguments: // pDiskIn // // Return Value: // S_OK // // Win32 Error // something failed. // // Remarks: // None. // //-- ////////////////////////////////////////////////////////////////////////////// HRESULT CEnumPhysicalDisks::HrLogDiskInfo( IWbemClassObject * pDiskIn ) { TraceFunc( "" ); Assert( pDiskIn != NULL ); HRESULT hr = S_OK; VARIANT varDeviceID; VARIANT varSCSIBus; VARIANT varSCSIPort; VARIANT varSCSILun; VARIANT varSCSITid; BSTR bstr = NULL; VariantInit( &varDeviceID ); VariantInit( &varSCSIBus ); VariantInit( &varSCSIPort ); VariantInit( &varSCSILun ); VariantInit( &varSCSITid ); hr = THR( HrGetWMIProperty( pDiskIn, L"DeviceID", VT_BSTR, &varDeviceID ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: hr = STHR( IsDiskSCSI( pDiskIn ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: // // Disk is SCSI... // if ( hr == S_OK ) { hr = THR( HrGetWMIProperty( pDiskIn, L"SCSIBus", VT_I4, &varSCSIBus ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: hr = THR( HrGetWMIProperty( pDiskIn, L"SCSITargetId", VT_I4, &varSCSITid ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: hr = THR( HrGetWMIProperty( pDiskIn, L"SCSILogicalUnit", VT_I4, &varSCSILun ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: hr = THR( HrGetWMIProperty( pDiskIn, L"SCSIPort", VT_I4, &varSCSIPort ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: hr = THR( HrFormatStringIntoBSTR( L"Found SCSI disk '%1!ws!' on Bus '%2!d!' and Port '%3!d!'; at TID '%4!d!' and LUN '%5!d!'" , &bstr , varDeviceID.bstrVal , varSCSIBus.iVal , varSCSIPort.iVal , varSCSITid.iVal , varSCSILun.iVal ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: LOG_STATUS_REPORT( bstr, hr ); } // if: else { HRESULT hrTemp; CLSID clsidMinorId; hrTemp = THR( CoCreateGuid( &clsidMinorId ) ); if ( FAILED( hrTemp ) ) { LogMsg( L"[SRV] Could not create a guid for a non-scsi disk minor task ID" ); clsidMinorId = IID_NULL; } // if: // // Reset hr to S_OK since we don't want a yellow bang in the UI. Finding non-scsi disks is expected // and should cause as little concern as possible. // hr = S_OK; STATUS_REPORT_REF( TASKID_Major_Find_Devices, TASKID_Minor_Non_SCSI_Disks, IDS_INFO_NON_SCSI_DISKS, IDS_INFO_NON_SCSI_DISKS_REF, hr ); 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 ); } // else: Cleanup: VariantClear( &varDeviceID ); VariantClear( &varSCSIBus ); VariantClear( &varSCSIPort ); VariantClear( &varSCSILun ); VariantClear( &varSCSITid ); TraceSysFreeString( bstr ); HRETURN( hr ); } //*** CEnumPhysicalDisks::HrLogDiskInfo ///////////////////////////////////////////////////////////////////////////// //++ // // CEnumPhysicalDisks:HrFindDiskWithWMIDeviceID // // Description: // Find the disk with the passed in WMI device ID. // // Arguments: // None. // // Return Value: // S_OK // Success. Found the disk. // // S_FALSE // Success. Did not find the disk. // // Win32 Error // something failed. // // Remarks: // None. // //-- ////////////////////////////////////////////////////////////////////////////// HRESULT CEnumPhysicalDisks::HrFindDiskWithWMIDeviceID( BSTR bstrWMIDeviceIDIn, ULONG * pidxDiskOut ) { TraceFunc( "" ); Assert( pidxDiskOut != NULL ); HRESULT hr = S_OK; IClusCfgPhysicalDiskProperties * piccpdp = NULL; ULONG idx; bool fFoundIt = false; IUnknown * punk; BSTR bstrDeviceID = NULL; for ( idx = 0; idx < m_idxNext; idx++ ) { punk = (*m_prgDisks)[ idx ]; // don't ref if ( punk != NULL ) { hr = THR( punk->TypeSafeQI( IClusCfgPhysicalDiskProperties, &piccpdp ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: hr = STHR( piccpdp->HrGetDeviceID( &bstrDeviceID ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: if ( NBSTRCompareCase( bstrWMIDeviceIDIn, bstrDeviceID ) == 0 ) { fFoundIt = true; break; } // if: piccpdp->Release(); piccpdp = NULL; TraceSysFreeString( bstrDeviceID ); bstrDeviceID = NULL; } // if: } // for: if ( !fFoundIt ) { hr = S_FALSE; } // if: if ( pidxDiskOut != NULL ) { *pidxDiskOut = idx; } // if: Cleanup: if ( piccpdp != NULL ) { piccpdp->Release(); } // if: TraceSysFreeString( bstrDeviceID ); HRETURN( hr ); } //*** CEnumPhysicalDisks::HrFindDiskWithWMIDeviceID ///////////////////////////////////////////////////////////////////////////// //++ // // CEnumPhysicalDisks:HrIsSystemBusManaged // // Description: // Is the system bus managed by the cluster service? // // Arguments: // None. // // Return Value: // S_OK // Success. The system bus is managed. // // S_FALSE // Success. The system bus is not managed. // // Win32 Error // something failed. // // Remarks: // None. // //-- ////////////////////////////////////////////////////////////////////////////// HRESULT CEnumPhysicalDisks::HrIsSystemBusManaged( void ) { TraceFunc( "" ); HRESULT hr = S_FALSE; DWORD sc; HKEY hKey = NULL; DWORD dwData; DWORD cbData = sizeof( dwData ); DWORD dwType; sc = RegOpenKeyEx( HKEY_LOCAL_MACHINE, L"SYSTEM\\CURRENTCONTROLSET\\SERVICES\\ClusSvc\\Parameters", 0, KEY_READ, &hKey ); if ( sc == ERROR_FILE_NOT_FOUND ) { goto Cleanup; // not yet a cluster node. Return S_FALSE. } // if: if ( sc != ERROR_SUCCESS ) { hr = HRESULT_FROM_WIN32( TW32( sc ) ); LogMsg( L"[SRV] RegOpenKeyEx() failed. (hr = %#08x)", hr ); goto Cleanup; } // if: sc = RegQueryValueEx( hKey, L"ManageDisksOnSystemBuses", NULL, &dwType, (LPBYTE) &dwData, &cbData ); if ( sc == ERROR_FILE_NOT_FOUND ) { goto Cleanup; // value not found. Return S_FALSE. } // if: if ( sc != ERROR_SUCCESS ) { hr = HRESULT_FROM_WIN32( TW32( sc ) ); LogMsg( L"[SRV] RegQueryValueEx() failed. (hr = %#08x)", hr ); goto Cleanup; } // if: if (dwType != REG_DWORD) { hr = HRESULT_FROM_WIN32( TW32(ERROR_DATATYPE_MISMATCH) ); LogMsg( L"[SRV] RegQueryValueEx() invalid data type %d.", dwType ); } else if ( dwData > 0) { hr = S_OK; } // if: Cleanup: if ( hKey != NULL ) { RegCloseKey( hKey ); } // if: HRETURN( hr ); } //*** CEnumPhysicalDisks::HrIsSystemBusManaged ///////////////////////////////////////////////////////////////////////////// //++ // // CEnumPhysicalDisks:HrGetClusterProperties // // Description: // Return the asked for cluster properties. // // Arguments: // // // Return Value: // S_OK // Success. // // Win32 Error // something failed. // // Remarks: // None. // //-- ////////////////////////////////////////////////////////////////////////////// HRESULT CEnumPhysicalDisks::HrGetClusterProperties( HRESOURCE hResourceIn , BSTR * pbstrResourceNameOut ) { TraceFunc( "" ); Assert( hResourceIn != NULL ); Assert( pbstrResourceNameOut != NULL ); HRESULT hr = S_OK; DWORD sc; DWORD cbBuffer; WCHAR * pwszBuffer = NULL; cbBuffer = 0; sc = TW32( ClusterResourceControl( hResourceIn, NULL, CLUSCTL_RESOURCE_GET_NAME, NULL, NULL, NULL, cbBuffer, &cbBuffer ) ); if ( sc != ERROR_SUCCESS ) { hr = HRESULT_FROM_WIN32( sc ); goto Cleanup; } // cbBuffer contains the byte count, not the char count. pwszBuffer = new WCHAR[(cbBuffer/sizeof(WCHAR))+1]; if ( pwszBuffer == NULL ) { hr = THR( ERROR_OUTOFMEMORY ); goto Cleanup; } sc = ClusterResourceControl( hResourceIn, NULL, CLUSCTL_RESOURCE_GET_NAME, NULL, NULL, pwszBuffer, cbBuffer, &cbBuffer ); if ( sc != ERROR_SUCCESS ) { hr = HRESULT_FROM_WIN32( TW32( sc ) ); goto Cleanup; } if ( wcslen( pwszBuffer ) == 0 ) { LOG_STATUS_REPORT( L"The Name of a physical disk resource was empty!", hr ); } *pbstrResourceNameOut = TraceSysAllocString( pwszBuffer ); hr = S_OK; Cleanup: delete [] pwszBuffer; HRETURN( hr ); } //*** CEnumPhysicalDisks::HrGetClusterProperties ///////////////////////////////////////////////////////////////////////////// //++ // // CEnumPhysicalDisks::RemoveDiskFromArray // // Description: // Release the disk at the specified index in the array and decrease the disk count. // // Arguments: // idxDiskIn - the index of the disk to remove; must be less than the array size. // // Return Value: // None. // // Remarks: // None. // //-- ////////////////////////////////////////////////////////////////////////////// void CEnumPhysicalDisks::RemoveDiskFromArray( ULONG idxDiskIn ) { TraceFunc( "" ); Assert( idxDiskIn < m_idxNext ); ((*m_prgDisks)[ idxDiskIn ])->Release(); (*m_prgDisks)[ idxDiskIn ] = NULL; m_cDiskCount -= 1; TraceFuncExit(); } //*** CEnumPhysicalDisks::RemoveDiskFromArray ///////////////////////////////////////////////////////////////////////////// //++ // // CEnumPhysicalDisks::HrLoadEnum // // Description: // Load the enum and filter out any devices that don't belong. // // Arguments: // None. // // Return Value: // S_OK // Success. // // Other HRESULT errors. // // Remarks: // None. // //-- ////////////////////////////////////////////////////////////////////////////// HRESULT CEnumPhysicalDisks::HrLoadEnum( void ) { TraceFunc( "" ); HRESULT hr = S_OK; hr = THR( HrGetDisks() ); if ( FAILED( hr ) ) { goto Cleanup; } // if: hr = THR( HrPruneSystemDisks() ); if ( FAILED( hr ) ) { goto Cleanup; } // if: hr = THR( HrSortDisksByIndex() ); if ( FAILED( hr ) ) { goto Cleanup; } // if: hr = STHR( HrIsNodeClustered() ); if ( FAILED( hr ) ) { goto Cleanup; } // if: if ( hr == S_OK ) { hr = THR( HrFixupDisks() ); if ( FAILED( hr ) ) { goto Cleanup; } // if: } // if: hr = S_OK; // could have been S_FALSE Cleanup: HRETURN( hr ); } //*** CEnumPhysicalDisks::HrLoadEnum ///////////////////////////////////////////////////////////////////////////// //++ // // CEnumPhysicalDisks::HrSortDisksByIndex // // Description: // Sort a (possibly sparse) array of pointers to disk objects by their // WMI "Index" property. // // Arguments: // ppunkDisksIn -- a pointer to an array of (possibly null) // IUnknown pointers to objects that implement the // IClusCfgPhysicalDiskProperties interface. // // cArraySizeIn -- the total number of pointers in the array, // including nulls // // Return Value: // None. // // Remarks: // None. // //-- ////////////////////////////////////////////////////////////////////////////// HRESULT CEnumPhysicalDisks::HrSortDisksByIndex( void ) { TraceFunc( "" ); HRESULT hr = S_OK; CIndexedDisk * prgIndexedDisks = NULL; size_t idxCurrentDisk = 0; size_t idxSortedDisk = 0; size_t cDisks = 0; // Count the number of non-null pointers in the array for ( idxCurrentDisk = 0; idxCurrentDisk < m_idxNext; ++idxCurrentDisk ) { if ( (*m_prgDisks)[ idxCurrentDisk ] != NULL ) { cDisks += 1; } // if: } // for: if ( cDisks < 2 ) // no sorting to do; also avoid calling new[] with zero array size { goto Cleanup; } // if: // Make a compact array of indexed disks prgIndexedDisks = new CIndexedDisk[ cDisks ]; if ( prgIndexedDisks == NULL ) { hr = THR( E_OUTOFMEMORY ); goto Cleanup; } // if: // Initialize the array of indexed disks for ( idxCurrentDisk = 0; idxCurrentDisk < m_idxNext; ++idxCurrentDisk ) { if ( (*m_prgDisks)[ idxCurrentDisk ] != NULL ) { hr = THR( prgIndexedDisks[ idxSortedDisk ].HrInit( (*m_prgDisks)[ idxCurrentDisk ] ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: idxSortedDisk += 1; } // if current disk pointer in original array is not null } // for each disk pointer in the original array InsertionSort( prgIndexedDisks, cDisks, CIndexedDiskLessThan() ); // Copy the sorted pointers back into the original array, padding extra space with nulls for ( idxCurrentDisk = 0; idxCurrentDisk < m_idxNext; ++idxCurrentDisk) { if ( idxCurrentDisk < cDisks) { (*m_prgDisks)[ idxCurrentDisk ] = prgIndexedDisks[ idxCurrentDisk ].punkDisk; } // if: else { (*m_prgDisks)[ idxCurrentDisk ] = NULL; } // else: } // for each slot in the original array Cleanup: delete [] prgIndexedDisks; HRETURN( hr ); } //*** CEnumPhysicalDisks::HrSortDisksByIndex ///////////////////////////////////////////////////////////////////////////// //++ // // CEnumPhysicalDisks::HrPrunePageFileDiskBussess // // Description: // Prune from the list of disks those that have pagefiles on them and // the other disks on those same SCSI busses. // // Arguments: // fPruneBusIn // // pcPrunedInout // // Return Value: // S_OK // Success. // //-- ////////////////////////////////////////////////////////////////////////////// HRESULT CEnumPhysicalDisks::HrPrunePageFileDiskBussess( BOOL fPruneBusIn , ULONG * pcPrunedInout ) { TraceFunc( "" ); Assert( pcPrunedInout != NULL ); HRESULT hr = S_OK; WCHAR szPageFileDisks[ 26 ]; int cPageFileDisks = 0; int idxPageFileDisk; ULONG ulSCSIBus; ULONG ulSCSIPort; ULONG idx; ULONG cPruned = 0; // // Prune the bus with disks that have paging files. // hr = THR( HrGetPageFileLogicalDisks( m_picccCallback, m_pIWbemServices, szPageFileDisks, &cPageFileDisks ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: if ( cPageFileDisks > 0 ) { for ( idxPageFileDisk = 0; idxPageFileDisk < cPageFileDisks; idxPageFileDisk++ ) { hr = STHR( HrFindDiskWithLogicalDisk( szPageFileDisks[ idxPageFileDisk ], &idx ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: if ( hr == S_OK ) { // // Should we prune the whole bus, or just the system disk itself? // if ( fPruneBusIn ) { hr = THR( HrGetSCSIInfo( idx, &ulSCSIBus, &ulSCSIPort ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: STATUS_REPORT( TASKID_Major_Find_Devices, TASKID_Minor_Pruning_PageFile_Disk_Bus, IDS_INFO_PRUNING_PAGEFILEDISK_BUS, hr ); hr = THR( HrPruneDisks( ulSCSIBus , ulSCSIPort , &TASKID_Minor_Pruning_PageFile_Disk_Bus , IDS_INFO_PAGEFILEDISK_PRUNED , IDS_INFO_PAGEFILEDISK_PRUNED_REF , &cPruned ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: } // if: else { RemoveDiskFromArray( idx ); cPruned++; } // else: } // if: } // for: } // if: *pcPrunedInout = cPruned; hr = S_OK; Cleanup: HRETURN( hr ); } //*** CEnumPhysicalDisks::HrPrunePageFileDiskBussess ///////////////////////////////////////////////////////////////////////////// //++ // // CEnumPhysicalDisks::HrPruneCrashDumpBus // // Description: // Prune from the list of disks those that have pagefiles on them and // the other disks on those same SCSI busses. // // Arguments: // fPruneBusIn // // pcPrunedInout // // Return Value: // S_OK // Success. // //-- ////////////////////////////////////////////////////////////////////////////// HRESULT CEnumPhysicalDisks::HrPruneCrashDumpBus( BOOL fPruneBusIn , ULONG * pcPrunedInout ) { TraceFunc( "" ); Assert( pcPrunedInout != NULL ); Assert( m_bstrCrashDumpLogicalDisk != NULL ); HRESULT hr = S_OK; ULONG ulSCSIBus; ULONG ulSCSIPort; ULONG idx; ULONG cPruned = 0; // // Prune the bus with disks that have paging files. // hr = STHR( HrFindDiskWithLogicalDisk( m_bstrCrashDumpLogicalDisk[ 0 ], &idx ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: if ( hr == S_OK ) { // // Should we prune the whole bus, or just the system disk itself? // if ( fPruneBusIn ) { hr = THR( HrGetSCSIInfo( idx, &ulSCSIBus, &ulSCSIPort ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: STATUS_REPORT( TASKID_Major_Find_Devices, TASKID_Minor_Pruning_CrashDump_Disk_Bus, IDS_INFO_PRUNING_CRASHDUMP_BUS, hr ); hr = THR( HrPruneDisks( ulSCSIBus , ulSCSIPort , &TASKID_Minor_Pruning_CrashDump_Disk_Bus , IDS_INFO_CRASHDUMPDISK_PRUNED , IDS_INFO_CRASHDUMPDISK_PRUNED_REF , &cPruned ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: } // if: else { RemoveDiskFromArray( idx ); cPruned++; } // else: } // if: *pcPrunedInout = cPruned; hr = S_OK; Cleanup: HRETURN( hr ); } //*** CEnumPhysicalDisks::HrPruneCrashDumpBus ///////////////////////////////////////////////////////////////////////////// //++ // // CEnumPhysicalDisks::HrPruneDynamicDisks // // Description: // Prune from the list of disks those that have dynamic partitions // on them. // // Arguments: // pcPrunedInout // // Return Value: // S_OK // Success. // //-- ////////////////////////////////////////////////////////////////////////////// HRESULT CEnumPhysicalDisks::HrPruneDynamicDisks( ULONG * pcPrunedInout ) { TraceFunc( "" ); Assert( pcPrunedInout != NULL ); HRESULT hr = S_OK; ULONG idx; ULONG cPruned = 0; IClusCfgPhysicalDiskProperties * piccpdp = NULL; HRESULT hrTemp; CLSID clsidMinorId; BSTR bstrDiskName = NULL; BSTR bstrDeviceName = NULL; for ( idx = 0; idx < m_idxNext; idx++ ) { if ( (*m_prgDisks)[ idx ] != NULL ) { hr = THR( ((*m_prgDisks)[ idx ])->TypeSafeQI( IClusCfgPhysicalDiskProperties, &piccpdp ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: hr = piccpdp->HrIsDynamicDisk(); if ( FAILED( hr ) ) { goto Cleanup; } // if: if ( hr == S_OK ) { ((*m_prgDisks)[ idx ])->Release(); (*m_prgDisks)[ idx ] = NULL; cPruned++; hrTemp = THR( piccpdp->HrGetDiskNames( &bstrDiskName, &bstrDeviceName ) ); if ( FAILED( hrTemp ) ) { LOG_STATUS_REPORT( L"Could not get the name of the disk", hrTemp ); bstrDiskName = NULL; bstrDeviceName = NULL; } // if: hrTemp = THR( CoCreateGuid( &clsidMinorId ) ); if ( FAILED( hrTemp ) ) { LOG_STATUS_REPORT( L"Could not create a guid for a dynamic disk minor task ID", hrTemp ); clsidMinorId = IID_NULL; } // if: STATUS_REPORT_REF( TASKID_Major_Find_Devices, TASKID_Minor_Non_SCSI_Disks, IDS_INFO_NON_SCSI_DISKS, IDS_INFO_NON_SCSI_DISKS_REF, hr ); STATUS_REPORT_STRING2_REF( TASKID_Minor_Non_SCSI_Disks , clsidMinorId , IDS_ERROR_LDM_DISK , bstrDeviceName != NULL ? bstrDeviceName : L"" , bstrDiskName != NULL ? bstrDiskName : L"" , IDS_ERROR_LDM_DISK_REF , hr ); } // if: piccpdp->Release(); piccpdp = NULL; TraceSysFreeString( bstrDiskName ); bstrDiskName = NULL; TraceSysFreeString( bstrDeviceName ); bstrDeviceName = NULL; } // end if: } // for: *pcPrunedInout = cPruned; hr = S_OK; Cleanup: if ( piccpdp != NULL ) { piccpdp->Release(); } // if: TraceSysFreeString( bstrDiskName ); TraceSysFreeString( bstrDeviceName ); HRETURN( hr ); } //*** CEnumPhysicalDisks::HrPruneDynamicDisks ///////////////////////////////////////////////////////////////////////////// //++ // // CEnumPhysicalDisks::HrPruneGPTDisks // // Description: // Prune from the list of disks those that have GPT partitions // on them. // // Arguments: // pcPrunedInout // // Return Value: // S_OK // Success. // //-- ////////////////////////////////////////////////////////////////////////////// HRESULT CEnumPhysicalDisks::HrPruneGPTDisks( ULONG * pcPrunedInout ) { TraceFunc( "" ); Assert( pcPrunedInout != NULL ); HRESULT hr = S_OK; ULONG idx; ULONG cPruned = 0; IClusCfgPhysicalDiskProperties * piccpdp = NULL; HRESULT hrTemp; CLSID clsidMinorId; BSTR bstrDiskName = NULL; BSTR bstrDeviceName = NULL; for ( idx = 0; idx < m_idxNext; idx++ ) { if ( (*m_prgDisks)[ idx ] != NULL ) { hr = THR( ((*m_prgDisks)[ idx ])->TypeSafeQI( IClusCfgPhysicalDiskProperties, &piccpdp ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: hr = piccpdp->HrIsGPTDisk(); if ( FAILED( hr ) ) { goto Cleanup; } // if: if ( hr == S_OK ) { ((*m_prgDisks)[ idx ])->Release(); (*m_prgDisks)[ idx ] = NULL; cPruned++; hrTemp = THR( piccpdp->HrGetDiskNames( &bstrDiskName, &bstrDeviceName ) ); if ( FAILED( hrTemp ) ) { LOG_STATUS_REPORT( L"Could not get the name of the disk", hrTemp ); bstrDiskName = NULL; bstrDeviceName = NULL; } // if: hrTemp = THR( CoCreateGuid( &clsidMinorId ) ); if ( FAILED( hrTemp ) ) { LOG_STATUS_REPORT( L"Could not create a guid for a dynamic disk minor task ID", hrTemp ); clsidMinorId = IID_NULL; } // if: STATUS_REPORT_REF( TASKID_Major_Find_Devices, TASKID_Minor_Non_SCSI_Disks, IDS_INFO_NON_SCSI_DISKS, IDS_INFO_NON_SCSI_DISKS_REF, hr ); STATUS_REPORT_STRING2_REF( TASKID_Minor_Non_SCSI_Disks , clsidMinorId , IDS_INFO_GPT_DISK , bstrDeviceName != NULL ? bstrDeviceName : L"" , bstrDiskName != NULL ? bstrDiskName : L"" , IDS_ERROR_LDM_DISK_REF , hr ); } // if: piccpdp->Release(); piccpdp = NULL; TraceSysFreeString( bstrDiskName ); bstrDiskName = NULL; TraceSysFreeString( bstrDeviceName ); bstrDeviceName = NULL; } // end if: } // for: *pcPrunedInout = cPruned; hr = S_OK; Cleanup: if ( piccpdp != NULL ) { piccpdp->Release(); } // if: TraceSysFreeString( bstrDiskName ); TraceSysFreeString( bstrDeviceName ); HRETURN( hr ); } //*** CEnumPhysicalDisks::HrPruneGPTDisks /* ///////////////////////////////////////////////////////////////////////////// //++ // // CEnumPhysicalDisks::HrGetDisks // // Description: // // Arguments: // // // Return Value: // // // Remarks: // None. // //-- ////////////////////////////////////////////////////////////////////////////// HRESULT CEnumPhysicalDisks::HrGetDisks( void ) { TraceFunc( "" ); HRESULT hr = S_OK; DWORD sc; HDEVINFO hdiSet = INVALID_HANDLE_VALUE; SP_DEVINFO_DATA didData; SP_INTERFACE_DEVICE_DATA iddData; GUID guidClass = GUID_DEVINTERFACE_DISK; DWORD idx = 0; BOOL fRet = TRUE; PSP_INTERFACE_DEVICE_DETAIL_DATA pidddDetailData = NULL; DWORD cbDetailData = 512L; DWORD cbRequired = 0L; ZeroMemory ( &didData, sizeof( didData ) ); didData.cbSize = sizeof( didData ); ZeroMemory ( &iddData, sizeof( iddData ) ); iddData.cbSize = sizeof( iddData ); // // get device list // hdiSet = SetupDiGetClassDevs( &guidClass, NULL, NULL, DIGCF_INTERFACEDEVICE ); if ( hdiSet == INVALID_HANDLE_VALUE ) { sc = TW32( GetLastError() ); hr = HRESULT_FROM_WIN32( sc ); goto Cleanup; } // if: // // Do initial allocations. // pidddDetailData = (PSP_INTERFACE_DEVICE_DETAIL_DATA) TraceAlloc( 0, cbDetailData ); if ( pidddDetailData == NULL ) { hr = THR( E_OUTOFMEMORY ); goto Cleanup; } // if: pidddDetailData->cbSize = sizeof( SP_INTERFACE_DEVICE_DETAIL_DATA ); // // enumerate list // for ( ; ; ) { fRet = SetupDiEnumDeviceInterfaces( hdiSet, NULL, &guidClass, idx, &iddData ); if ( fRet == FALSE ) { sc = GetLastError(); if ( sc == ERROR_NO_MORE_ITEMS ) { hr = S_OK; break; } // if: TW32( sc ); hr = HRESULT_FROM_WIN32( sc ); goto Cleanup; } // if: for ( ; ; ) { fRet = SetupDiGetDeviceInterfaceDetail( hdiSet, &iddData, pidddDetailData, cbDetailData, &cbRequired, &didData ); if ( fRet == FALSE ) { sc = GetLastError(); if ( sc == ERROR_INSUFFICIENT_BUFFER ) { cbDetailData = cbRequired; TraceFree( pidddDetailData ); pidddDetailData = NULL; pidddDetailData = (PSP_INTERFACE_DEVICE_DETAIL_DATA) TraceAlloc( 0, cbDetailData ); if ( pidddDetailData == NULL ) { hr = THR( E_OUTOFMEMORY ); goto Cleanup; } // if: pidddDetailData->cbSize = sizeof( SP_INTERFACE_DEVICE_DETAIL_DATA ); continue; } // if: TW32( sc ); hr = HRESULT_FROM_WIN32( sc ); goto Cleanup; } // if: else { break; } // else: } // for: idx++; } // for: Cleanup: TraceFree( pidddDetailData ); if ( hdiSet != INVALID_HANDLE_VALUE ) { SetupDiDestroyDeviceInfoList( hdiSet ); } // if: HRETURN( hr ); } //*** CEnumPhysicalDisks::HrGetDisks */