2808 lines
64 KiB
C++
2808 lines
64 KiB
C++
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// 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 <PropList.h>
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// 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"<Unknown>" );
|
|
} // 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"<Unknown>" );
|
|
} // 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"<null>" : 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
|