////////////////////////////////////////////////////////////////////////////// // // Copyright (c) 2000-2001 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. // // Documentation: // // Header File: // CEnumPhysicalDisks.h // // Maintained By: // Galen Barbee (GalenB) 23-FEB-2000 // ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // Include Files ////////////////////////////////////////////////////////////////////////////// #include "pch.h" #include "CEnumPhysicalDisks.h" #include "CPhysicalDisk.h" #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; CEnumPhysicalDisks * pccpd = NULL; if ( ppunkOut == NULL ) { hr = THR( E_POINTER ); goto Cleanup; } // if: pccpd = new CEnumPhysicalDisks(); if ( pccpd == NULL ) { hr = THR( E_OUTOFMEMORY ); goto Cleanup; } // if: error allocating object hr = THR( pccpd->HrInit() ); if ( FAILED( hr ) ) { goto Cleanup; } // if: HrInit() failed hr = THR( pccpd->TypeSafeQI( IUnknown, ppunkOut ) ); Cleanup: if ( FAILED( hr ) ) { LogMsg( L"[SRV] CEnumPhysicalDisks::S_HrCreateInstance() failed. (hr = %#08x)", hr ); } // if: if ( pccpd != NULL ) { pccpd->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 ); 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 ); // There's going to be one less component in memory. Decrement component count. InterlockedDecrement( &g_cObjects ); TraceFuncExit(); } //*** CEnumPhysicalDisks::~CEnumPhysicalDisks //*************************************************************************// ///////////////////////////////////////////////////////////////////////////// // CEnumPhysicalDisks -- IUnknown interface. ///////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// //++ // // STDMETHODIMP_( ULONG ) // CEnumPhysicalDisks:: [IUNKNOWN] 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 ); RETURN( m_cRef ); } //*** CEnumPhysicalDisks::AddRef ////////////////////////////////////////////////////////////////////////////// //++ // // STDMETHODIMP_( ULONG ) // CEnumPhysicalDisks:: [IUNKNOWN] 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 RETURN( cRef ); } //*** CEnumPhysicalDisks::Release ////////////////////////////////////////////////////////////////////////////// //++ // // CEnumPhysicalDisks:: [INKNOWN] QueryInterface // // Description: // Query this object for the passed in interface. // // Arguments: // IN REFIID riid, // Id of interface requested. // // OUT void ** ppv // 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. // // Remarks: // None. // //-- ////////////////////////////////////////////////////////////////////////////// STDMETHODIMP CEnumPhysicalDisks::QueryInterface( REFIID riid, void ** ppv ) { TraceQIFunc( riid, ppv ); HRESULT hr = E_NOINTERFACE; if ( IsEqualIID( riid, IID_IUnknown ) ) { *ppv = static_cast< IEnumClusCfgManagedResources * >( this ); hr = S_OK; } // if: IUnknown else if ( IsEqualIID( riid, IID_IEnumClusCfgManagedResources ) ) { *ppv = TraceInterface( __THISCLASS__, IEnumClusCfgManagedResources, this, 0 ); hr = S_OK; } // else if: else if ( IsEqualIID( riid, IID_IClusCfgWbemServices ) ) { *ppv = TraceInterface( __THISCLASS__, IClusCfgWbemServices, this, 0 ); hr = S_OK; } // else if: else if ( IsEqualIID( riid, IID_IClusCfgInitialize ) ) { *ppv = TraceInterface( __THISCLASS__, IClusCfgInitialize, this, 0 ); hr = S_OK; } // else if: if ( SUCCEEDED( hr ) ) { ((IUnknown *) *ppv)->AddRef( ); } // if: success QIRETURN_IGNORESTDMARSHALLING( hr, riid ); } //*** 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( TASKID_Major_Find_Devices, TASKID_Minor_SetWbemServices_Enum_PhysDisk, IDS_ERROR_NULL_POINTER, 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 ) ); // // system volume is an EFI volume on IA64 and won't have a logical disk. // if ( HRESULT_CODE( hr ) == ERROR_INVALID_FUNCTION ) { 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( TASKID_Major_Find_Devices, TASKID_Minor_Boot_Partition_Not_NTFS, IDS_WARNING_BOOT_PARTITION_NOT_NTFS, hr ); hr = S_OK; } // if: Cleanup: HRETURN( hr ); } //*** CEnumPhysicalDisks::SetWbemServices //*************************************************************************// ///////////////////////////////////////////////////////////////////////////// // CEnumPhysicalDisks -- IClusCfgInitialize interface. ///////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// //++ // // CEnumPhysicalDisks::Initialize // // Description: // Initialize this component. // // Arguments: // IN IUknown * punkCallbackIn // // IN LCID lcidIn // // Return Value: // S_OK // Success // // Remarks: // None. // //-- ////////////////////////////////////////////////////////////////////////////// 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_POINTER ); goto Cleanup; } // if: hr = THR( punkCallbackIn->TypeSafeQI( IClusCfgCallback, &m_picccCallback ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: hr = THR( HrGetComputerName( ComputerNameNetBIOS, &m_bstrNodeName ) ); 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( TASKID_Major_Find_Devices, TASKID_Minor_Next_Enum_PhysDisk, IDS_ERROR_NULL_POINTER, 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( TASKID_Major_Find_Devices, TASKID_Minor_Clone_Enum_PhysDisk, IDS_ERROR_NULL_POINTER, 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; 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 ) { goto OutOfMemory; } // if: hr = THR( m_pIWbemServices->CreateInstanceEnum( bstrClass, WBEM_FLAG_SHALLOW, NULL, &pDisks ) ); if ( FAILED( hr ) ) { STATUS_REPORT( TASKID_Major_Find_Devices, TASKID_Minor_WMI_Phys_Disks_Qry_Failed, IDS_ERROR_WMI_PHYS_DISKS_QRY_FAILED, 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( TASKID_Major_Find_Devices, TASKID_Minor_WQL_Disk_Qry_Next_Failed, IDS_ERROR_WQL_QRY_NEXT_FAILED, bstrClass, hr ); goto Cleanup; } // else: } // for: m_idxEnumNext = 0; m_fLoadedDevices = TRUE; goto Cleanup; OutOfMemory: hr = THR( E_OUTOFMEMORY ); STATUS_REPORT( TASKID_Major_Find_Devices, TASKID_Minor_HrGetDisks, IDS_ERROR_OUTOFMEMORY, hr ); 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( "" ); HRESULT hr = S_OK; ULONG idx; ULONG ulSCSIBus; ULONG ulSCSIPort; IClusCfgPhysicalDiskProperties * piccpdp = NULL; IUnknown * punk; ULONG cRemoved = 0; ULONG cTemp = 0; bool fSystemAndBootTheSame = ( m_bstrSystemLogicalDisk != NULL ) ? ( m_bstrBootLogicalDisk[ 0 ] == m_bstrSystemLogicalDisk[ 0 ] ) : false; WCHAR szPageFileDisks[ 26 ]; int cPageFileDisks = 0; int idxPageFileDisk; bool fPruneBus = 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 // 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, &cTemp, IDS_INFO_BOOTDISK_PRUNED ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: cRemoved += cTemp; } // if: else { RemoveDiskFromArray( idx ); cRemoved++; } // else: } // if: // // 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, &cTemp, IDS_INFO_SYSTEMDISK_PRUNED ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: cRemoved += cTemp; } // if: else { RemoveDiskFromArray( idx ); cRemoved++; } // else: } // if: } // if: // // 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 ( fPruneBus ) { 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, &cTemp, IDS_INFO_PAGEFILEDISK_PRUNED ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: cRemoved += cTemp; } // if: else { RemoveDiskFromArray( idx ); cRemoved++; } // else: } // if: } // for: } // if: // // 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 ( ( wcscmp( L"SCSI", var.bstrVal ) == 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( TASKID_Major_Find_Devices, TASKID_Minor_HrAddDiskToArray, IDS_ERROR_OUTOFMEMORY, 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; ULONG idx; IUnknown * punk = NULL; IClusCfgManagedResourceInfo * piccmri = NULL; // // KB: 14-JUN-2000 GalenB // // Clear the managed bit on all remaing disks. These bits will be turned // back on for the disks this node owns. That happens in // HrNodeResourceCallback(). // // // BUGBUG: 02-MAY-2001 GalenB // // Hmmm... Maybe clearing the managed state from all disks is a mistake. What if we // have new disks that are not already in the cluster for this clustered node? // 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->SetManaged( false ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: piccmri->Release(); piccmri = NULL; } // if: } // for: hr = THR( HrEnumNodeResources( m_bstrNodeName ) ); Cleanup: if ( piccmri != NULL ) { piccmri->Release(); } // if: 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 ) ); 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 ) { goto MakeHr; } // if: sc = TW32( cpvl.ScMoveToFirstValue() ); if ( sc != ERROR_SUCCESS ) { goto MakeHr; } // 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 TW32( sc ); goto MakeHr; } // for: goto Cleanup; MakeHr: hr = HRESULT_FROM_WIN32( sc ); 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; _snwprintf( sz, ARRAYSIZE( sz ), L"SCSI Tid %ld, SCSI Lun %ld", ulSCSITidIn, ulSCSILunIn ); // // KB: 15-JUN-2000 GalenB // // 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 ( _wcsicmp( bstrUID, 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->SetQuorumedDevice( 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 , ULONG * pulRemovedOut , int nMsgId ) { 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; 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( TASKID_Major_Find_Devices, TASKID_Minor_Pruned_Disk_From_Bus, nMsgId, bstr != NULL ? bstr : L"????", 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( TASKID_Major_Find_Devices, TASKID_Minor_HrIsLogicalDiskNTFS_InvalidArg, IDS_ERROR_INVALIDARG, hr ); goto Cleanup; } // if: // // truncate off any trailing \'s // if ( bstrLogicalDiskIn[ cch - 1 ] == L'\\' ) { bstrLogicalDiskIn[ cch - 1 ] = '\0'; } // if: // // If we got just the logical disk without the trailing colon... // if ( wcslen( bstrLogicalDiskIn ) == 1 ) { _snwprintf( sz, ARRAYSIZE( sz ), L"Win32_LogicalDisk.DeviceID=\"%s:\"", bstrLogicalDiskIn ); } // if: else { _snwprintf( sz, ARRAYSIZE( sz ), L"Win32_LogicalDisk.DeviceID=\"%s\"", bstrLogicalDiskIn ); } // else: bstrPath = TraceSysAllocString( sz ); if ( bstrPath == NULL ) { hr = THR( E_OUTOFMEMORY ); STATUS_REPORT( TASKID_Major_Find_Devices, TASKID_Minor_HrIsLogicalDiskNTFS, IDS_ERROR_OUTOFMEMORY, hr ); } // if: hr = THR( m_pIWbemServices->GetObject( bstrPath, WBEM_FLAG_RETURN_WBEM_COMPLETE, NULL, &pLogicalDisk, NULL ) ); if ( FAILED( hr ) ) { STATUS_REPORT_STRING( TASKID_Major_Find_Devices, TASKID_Minor_WMI_Get_LogicalDisk_Failed, IDS_ERROR_WMI_GET_LOGICALDISK_FAILED, bstrLogicalDiskIn, hr ); goto Cleanup; } // if: hr = THR( HrGetWMIProperty( pLogicalDisk, L"FileSystem", VT_BSTR, &var ) ); if (FAILED( hr ) ) { goto Cleanup; } // if: CharUpper( var.bstrVal ); if ( wcscmp( var.bstrVal, 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 { STATUS_REPORT_STRING( TASKID_Major_Find_Devices, TASKID_Minor_Found_Non_SCSI_Disk, IDS_ERROR_FOUND_NON_SCSI_DISK, varDeviceID.bstrVal, 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 ( wcscmp( 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 ); 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 ) { TW32( sc ); LogMsg( L"[SRV] RegOpenKeyEx() failed. (hr = %#08x)", hr ); goto Win32Error; } // if: sc = RegQueryValueEx( hKey, L"ManageDisksOnSystemBuses", NULL, NULL, (LPBYTE) &dwData, &cbData ); if ( sc == ERROR_FILE_NOT_FOUND ) { goto Cleanup; // value not found. Return S_FALSE. } // if: if ( sc != ERROR_SUCCESS ) { TW32( sc ); LogMsg( L"[SRV] RegQueryValueEx() failed. (hr = %#08x)", hr ); goto Win32Error; } // if: if ( dwData > 0 ) { hr = S_OK; } // if: goto Cleanup; Win32Error: hr = HRESULT_FROM_WIN32( sc ); 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( pbstrResourceNameOut != NULL ); HRESULT hr = S_OK; CClusPropList cpl; CLUSPROP_BUFFER_HELPER cpbh; DWORD sc; sc = TW32( cpl.ScGetResourceProperties( hResourceIn, CLUSCTL_RESOURCE_GET_RO_COMMON_PROPERTIES ) ); if ( sc != ERROR_SUCCESS ) { goto MakeHr; } // if: sc = TW32( cpl.ScMoveToPropertyByName( L"Name" ) ); if ( sc != ERROR_SUCCESS ) { goto MakeHr; } // if: cpbh = cpl.CbhCurrentValue(); Assert( cpbh.pSyntax->dw == CLUSPROP_SYNTAX_LIST_VALUE_SZ ); if ( ( cpbh.pStringValue->sz != NULL ) && ( wcscmp( cpbh.pStringValue->sz, L"" ) != 0 ) ) { *pbstrResourceNameOut = TraceSysAllocString( cpbh.pStringValue->sz ); if ( *pbstrResourceNameOut == NULL ) { hr = THR( E_OUTOFMEMORY ); goto Cleanup; } // if: } // if: else { hr = THR( E_UNEXPECTED ); LOG_STATUS_REPORT( L"The name of a physical disk resource was empty!", hr ); } // else: goto Cleanup; MakeHr: hr = HRESULT_FROM_WIN32( sc ); Cleanup: 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 = 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 ); } //*** CEnumPysicalDisks::HrLoadEnum