You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1917 lines
48 KiB
1917 lines
48 KiB
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Copyright (c) 2000-2002 Microsoft Corporation
|
|
//
|
|
// Module Name:
|
|
// CEnumClusCfgManagedResources.cpp
|
|
//
|
|
// Description:
|
|
// This file contains the definition of the CEnumClusCfgManagedResources
|
|
// class.
|
|
//
|
|
// The class CEnumClusCfgManagedResources is the enumeration of cluster
|
|
// managed devices. It implements the IEnumClusCfgManagedResources
|
|
// interface.
|
|
//
|
|
// Maintained By:
|
|
// Galen Barbee (GalenB) 23-FEB-2000
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// Include Files
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
#include "Pch.h"
|
|
#include "CEnumClusCfgManagedResources.h"
|
|
#include "CEnumUnknownQuorum.h"
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// Constant Definitions
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
DEFINE_THISCLASS( "CEnumClusCfgManagedResources" );
|
|
|
|
|
|
//*************************************************************************//
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CEnumClusCfgManagedResources class
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CEnumClusCfgManagedResources::S_HrCreateInstance
|
|
//
|
|
// Description:
|
|
// Create a CEnumClusCfgManagedResources instance.
|
|
//
|
|
// Arguments:
|
|
// None.
|
|
//
|
|
// Return Values:
|
|
// Pointer to CEnumClusCfgManagedResources instance.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
HRESULT
|
|
CEnumClusCfgManagedResources::S_HrCreateInstance( IUnknown ** ppunkOut )
|
|
{
|
|
TraceFunc( "" );
|
|
|
|
HRESULT hr = S_OK;
|
|
CEnumClusCfgManagedResources * peccmr = NULL;
|
|
|
|
if ( ppunkOut == NULL )
|
|
{
|
|
hr = THR( E_POINTER );
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
peccmr = new CEnumClusCfgManagedResources();
|
|
if ( peccmr == NULL )
|
|
{
|
|
hr = THR( E_OUTOFMEMORY );
|
|
goto Cleanup;
|
|
} // if: error allocating object
|
|
|
|
hr = THR( peccmr->HrInit() );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
} // if: HrInit() failed
|
|
|
|
hr = THR( peccmr->TypeSafeQI( IUnknown, ppunkOut ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
} // if: QI failed
|
|
|
|
Cleanup:
|
|
|
|
if ( FAILED( hr ) )
|
|
{
|
|
LogMsg( L"[SRV] CEnumClusCfgManagedResources::S_HrCreateInstance() failed. (hr = %#08x)", hr );
|
|
} // if:
|
|
|
|
if ( peccmr != NULL )
|
|
{
|
|
peccmr->Release();
|
|
} // if:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CEnumClusCfgManagedResources::S_HrCreateInstance
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CEnumClusCfgManagedResources::CEnumClusCfgManagedResources
|
|
//
|
|
// Description:
|
|
// Constructor of the CEnumClusCfgManagedResources 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.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
CEnumClusCfgManagedResources::CEnumClusCfgManagedResources( void )
|
|
: m_cRef( 1 )
|
|
, m_lcid( LOCALE_NEUTRAL )
|
|
{
|
|
TraceFunc( "" );
|
|
|
|
Assert( m_idxNextEnum == 0 );
|
|
Assert( m_idxCurrentEnum == 0 );
|
|
Assert( m_picccCallback == NULL );
|
|
Assert( m_pIWbemServices == NULL );
|
|
Assert( m_prgEnums == NULL );
|
|
Assert( m_cTotalResources == 0);
|
|
Assert( !m_fLoadedDevices );
|
|
Assert( m_bstrNodeName == NULL );
|
|
|
|
// Increment the count of components in memory so the DLL hosting this
|
|
// object cannot be unloaded.
|
|
InterlockedIncrement( &g_cObjects );
|
|
|
|
TraceFuncExit();
|
|
|
|
} //*** CEnumClusCfgManagedResources::CEnumClusCfgManagedResources
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CEnumClusCfgManagedResources::~CEnumClusCfgManagedResources
|
|
//
|
|
// Description:
|
|
// Desstructor of the CEnumClusCfgManagedResources class.
|
|
//
|
|
// Arguments:
|
|
// None.
|
|
//
|
|
// Return Value:
|
|
// None.
|
|
//
|
|
// Remarks:
|
|
// None.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
CEnumClusCfgManagedResources::~CEnumClusCfgManagedResources( 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_idxNextEnum; idx++ )
|
|
{
|
|
Assert( (m_prgEnums[ idx ]).punk != NULL );
|
|
|
|
(m_prgEnums[ idx ]).punk->Release();
|
|
TraceSysFreeString( (m_prgEnums[ idx ]).bstrComponentName );
|
|
} // for: each enum in the array...
|
|
|
|
TraceFree( m_prgEnums );
|
|
|
|
TraceSysFreeString( m_bstrNodeName );
|
|
|
|
// There's going to be one less component in memory. Decrement component count.
|
|
InterlockedDecrement( &g_cObjects );
|
|
|
|
TraceFuncExit();
|
|
|
|
} //*** CEnumClusCfgManagedResources::~CEnumClusCfgManagedResources
|
|
|
|
|
|
//*************************************************************************//
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CEnumClusCfgManagedResources -- IUknkown interface.
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CEnumClusCfgManagedResources::AddRef
|
|
//
|
|
// Description:
|
|
// Increment the reference count of this object by one.
|
|
//
|
|
// Arguments:
|
|
// None.
|
|
//
|
|
// Return Value:
|
|
// The new reference count.
|
|
//
|
|
// Remarks:
|
|
// None.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP_( ULONG )
|
|
CEnumClusCfgManagedResources::AddRef( void )
|
|
{
|
|
TraceFunc( "[IUnknown]" );
|
|
|
|
InterlockedIncrement( &m_cRef );
|
|
|
|
CRETURN( m_cRef );
|
|
|
|
} //*** CEnumClusCfgManagedResources::AddRef
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CEnumClusCfgManagedResources::Release
|
|
//
|
|
// Description:
|
|
// Decrement the reference count of this object by one.
|
|
//
|
|
// Arguments:
|
|
// None.
|
|
//
|
|
// Return Value:
|
|
// The new reference count.
|
|
//
|
|
// Remarks:
|
|
// None.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP_( ULONG )
|
|
CEnumClusCfgManagedResources::Release( void )
|
|
{
|
|
TraceFunc( "[IUnknown]" );
|
|
|
|
LONG cRef;
|
|
|
|
cRef = InterlockedDecrement( &m_cRef );
|
|
if ( cRef == 0 )
|
|
{
|
|
TraceDo( delete this );
|
|
} // if: reference count equal to zero
|
|
|
|
CRETURN( cRef );
|
|
|
|
} //*** CEnumClusCfgManagedResources::Release
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CEnumClusCfgManagedResources::QueryInterface
|
|
//
|
|
// Description:
|
|
// Query this object for the passed in interface.
|
|
//
|
|
// Arguments:
|
|
// riidIn
|
|
// Id of interface requested.
|
|
//
|
|
// ppvOut
|
|
// Pointer to the requested interface.
|
|
//
|
|
// Return Value:
|
|
// S_OK
|
|
// If the interface is available on this object.
|
|
//
|
|
// E_NOINTERFACE
|
|
// If the interface is not available.
|
|
//
|
|
// E_POINTER
|
|
// ppvOut was NULL.
|
|
//
|
|
// Remarks:
|
|
// None.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CEnumClusCfgManagedResources::QueryInterface(
|
|
REFIID riidIn
|
|
, void ** ppvOut
|
|
)
|
|
{
|
|
TraceQIFunc( riidIn, ppvOut );
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
//
|
|
// Validate arguments.
|
|
//
|
|
|
|
Assert( ppvOut != NULL );
|
|
if ( ppvOut == NULL )
|
|
{
|
|
hr = THR( E_POINTER );
|
|
goto Cleanup;
|
|
}
|
|
|
|
//
|
|
// Handle known interfaces.
|
|
//
|
|
|
|
if ( IsEqualIID( riidIn, IID_IUnknown ) )
|
|
{
|
|
*ppvOut = static_cast< IEnumClusCfgManagedResources * >( this );
|
|
} // if: IUnknown
|
|
else if ( IsEqualIID( riidIn, IID_IEnumClusCfgManagedResources ) )
|
|
{
|
|
*ppvOut = TraceInterface( __THISCLASS__, IEnumClusCfgManagedResources, this, 0 );
|
|
} // else if: IEnumClusCfgManagedResources
|
|
else if ( IsEqualIID( riidIn, IID_IClusCfgWbemServices ) )
|
|
{
|
|
*ppvOut = TraceInterface( __THISCLASS__, IClusCfgWbemServices, this, 0 );
|
|
} // else if: IClusCfgWbemServices
|
|
else if ( IsEqualIID( riidIn, IID_IClusCfgInitialize ) )
|
|
{
|
|
*ppvOut = TraceInterface( __THISCLASS__, IClusCfgInitialize, this, 0 );
|
|
} // else if: IClusCfgInitialize
|
|
else
|
|
{
|
|
*ppvOut = NULL;
|
|
hr = E_NOINTERFACE;
|
|
}
|
|
|
|
//
|
|
// Add a reference to the interface if successful.
|
|
//
|
|
|
|
if ( SUCCEEDED( hr ) )
|
|
{
|
|
((IUnknown *) *ppvOut)->AddRef();
|
|
} // if: success
|
|
|
|
Cleanup:
|
|
|
|
QIRETURN_IGNORESTDMARSHALLING( hr, riidIn );
|
|
|
|
} //*** CEnumClusCfgManagedResources::QueryInterface
|
|
|
|
|
|
//*************************************************************************//
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CEnumClusCfgManagedResources -- IClusCfgWbemServices interface.
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CEnumClusCfgManagedResources::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
|
|
CEnumClusCfgManagedResources::SetWbemServices( IWbemServices * pIWbemServicesIn )
|
|
{
|
|
TraceFunc( "[IClusCfgWbemServices]" );
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
if ( pIWbemServicesIn == NULL )
|
|
{
|
|
hr = THR( E_POINTER );
|
|
STATUS_REPORT_REF( TASKID_Major_Find_Devices, TASKID_Minor_SetWbemServices_Enum_Resources, IDS_ERROR_NULL_POINTER, IDS_ERROR_NULL_POINTER_REF, hr );
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
m_pIWbemServices = pIWbemServicesIn;
|
|
m_pIWbemServices->AddRef();
|
|
|
|
Cleanup:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CEnumClusCfgManagedResources::SetWbemServices
|
|
|
|
|
|
//*************************************************************************//
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CEnumClusCfgManagedResources -- IClusCfgInitialize interface.
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CEnumClusCfgManagedResources::Initialize
|
|
//
|
|
// Description:
|
|
// Initialize this component.
|
|
//
|
|
// Arguments:
|
|
// IN IUknown * punkCallbackIn
|
|
//
|
|
// IN LCID lcidIn
|
|
//
|
|
// Return Value:
|
|
// S_OK
|
|
// Success
|
|
//
|
|
// Remarks:
|
|
// None.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CEnumClusCfgManagedResources::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 ) );
|
|
|
|
Cleanup:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CEnumClusCfgManagedResources::Initialize
|
|
|
|
|
|
//*************************************************************************//
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CEnumClusCfgManagedResources -- IEnumClusCfgManagedResources interface.
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CEnumClusCfgManagedResources::Next
|
|
//
|
|
// Description:
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Return Value:
|
|
//
|
|
// Remarks:
|
|
// None.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CEnumClusCfgManagedResources::Next(
|
|
ULONG cNumberRequestedIn
|
|
, IClusCfgManagedResourceInfo ** rgpManagedResourceInfoOut
|
|
, ULONG * pcNumberFetchedOut
|
|
)
|
|
{
|
|
TraceFunc( "[IEnumClusCfgManagedResources]" );
|
|
Assert( rgpManagedResourceInfoOut != NULL );
|
|
Assert( ( cNumberRequestedIn <= 1 ) || ( pcNumberFetchedOut != NULL ) );
|
|
|
|
HRESULT hr;
|
|
ULONG cFetched = 0;
|
|
|
|
if ( rgpManagedResourceInfoOut == NULL )
|
|
{
|
|
hr = THR( E_POINTER );
|
|
STATUS_REPORT_REF( TASKID_Major_Find_Devices, TASKID_Minor_Next_Enum_Resources, IDS_ERROR_NULL_POINTER, IDS_ERROR_NULL_POINTER_REF, hr );
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
//
|
|
// pcNumberFetchedOut can only be NULL when the number requested is 1.
|
|
//
|
|
|
|
if ( ( pcNumberFetchedOut == NULL )
|
|
&& ( cNumberRequestedIn > 1 ) )
|
|
{
|
|
hr = THR( E_INVALIDARG );
|
|
STATUS_REPORT_REF( TASKID_Major_Find_Devices, TASKID_Minor_Next_Enum_Resources, IDS_ERROR_NULL_POINTER, IDS_ERROR_NULL_POINTER_REF, hr );
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
if ( m_fLoadedDevices == FALSE )
|
|
{
|
|
hr = THR( HrLoadEnum() );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
} // if:
|
|
} // if:
|
|
|
|
hr = STHR( HrDoNext( cNumberRequestedIn, rgpManagedResourceInfoOut, &cFetched ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
//
|
|
// Do they want the out count?
|
|
//
|
|
|
|
if ( pcNumberFetchedOut != NULL )
|
|
{
|
|
*pcNumberFetchedOut = cFetched;
|
|
} // if:
|
|
|
|
Cleanup:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CEnumClusCfgManagedResources::Next
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CEnumClusCfgManagedResources::Skip
|
|
//
|
|
// Description:
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Return Value:
|
|
//
|
|
// Remarks:
|
|
// None.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CEnumClusCfgManagedResources::Skip( ULONG cNumberToSkipIn )
|
|
{
|
|
TraceFunc( "[IEnumClusCfgManagedResources]" );
|
|
|
|
HRESULT hr = S_FALSE;
|
|
|
|
if ( cNumberToSkipIn > 0 )
|
|
{
|
|
hr = STHR( HrDoSkip( cNumberToSkipIn ) );
|
|
} // if:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CEnumClusCfgManagedResources::Skip
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CEnumClusCfgManagedResources::Reset
|
|
//
|
|
// Description:
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Return Value:
|
|
//
|
|
// Remarks:
|
|
// None.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CEnumClusCfgManagedResources::Reset( void )
|
|
{
|
|
TraceFunc( "[IEnumClusCfgManagedResources]" );
|
|
|
|
HRESULT hr;
|
|
|
|
hr = STHR( HrDoReset() );
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CEnumClusCfgManagedResources::Reset
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CEnumClusCfgManagedResources::Clone
|
|
//
|
|
// Description:
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Return Value:
|
|
//
|
|
// Remarks:
|
|
// None.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CEnumClusCfgManagedResources::Clone(
|
|
IEnumClusCfgManagedResources ** ppEnumClusCfgManagedResourcesOut
|
|
)
|
|
{
|
|
TraceFunc( "[IEnumClusCfgManagedResources]" );
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
if ( ppEnumClusCfgManagedResourcesOut == NULL )
|
|
{
|
|
hr = THR( E_POINTER );
|
|
STATUS_REPORT_REF( TASKID_Major_Find_Devices, TASKID_Minor_Clone_Enum_Resources, IDS_ERROR_NULL_POINTER, IDS_ERROR_NULL_POINTER_REF, hr );
|
|
goto Cleanup;
|
|
} // else:
|
|
|
|
hr = THR( HrDoClone( ppEnumClusCfgManagedResourcesOut ) );
|
|
|
|
Cleanup:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CEnumClusCfgManagedResources::Clone
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CEnumClusCfgManagedResources::Count
|
|
//
|
|
// Description:
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Return Value:
|
|
//
|
|
// Remarks:
|
|
// None.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CEnumClusCfgManagedResources::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_cTotalResources;
|
|
|
|
Cleanup:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CEnumClusCfgManagedResources::Count
|
|
|
|
|
|
//*************************************************************************//
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CEnumClusCfgManagedResources class -- Private Methods.
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CEnumClusCfgManagedResources::HrInit
|
|
//
|
|
// Description:
|
|
// Initialize this component.
|
|
//
|
|
// Arguments:
|
|
// None.
|
|
//
|
|
// Return Value:
|
|
// S_OK - Success.
|
|
// Other HRESULTs.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
HRESULT
|
|
CEnumClusCfgManagedResources::HrInit( void )
|
|
{
|
|
TraceFunc( "" );
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
// IUnknown
|
|
Assert( m_cRef == 1 );
|
|
|
|
hr = THR( HrGetComputerName(
|
|
ComputerNameDnsHostname
|
|
, &m_bstrNodeName
|
|
, TRUE // fBestEffortIn
|
|
) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
Cleanup:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CEnumClusCfgManagedResources::HrInit
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CEnumClusCfgManagedResources::HrLoadEnum
|
|
//
|
|
// Description:
|
|
// Load this enumerator.
|
|
//
|
|
// Arguments:
|
|
// None.
|
|
//
|
|
// Return Value:
|
|
//
|
|
//
|
|
// Remarks:
|
|
// None.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
HRESULT
|
|
CEnumClusCfgManagedResources::HrLoadEnum( void )
|
|
{
|
|
TraceFunc( "" );
|
|
Assert( m_prgEnums == NULL );
|
|
|
|
HRESULT hr = S_OK;
|
|
IUnknown * punk = NULL;
|
|
ICatInformation * pici = NULL;
|
|
CATID rgCatIds[ 1 ];
|
|
IEnumCLSID * pieclsids = NULL;
|
|
IEnumClusCfgManagedResources * pieccmr = NULL;
|
|
CLSID clsid;
|
|
ULONG cFetched;
|
|
WCHAR szGUID[ 64 ];
|
|
int cch;
|
|
BSTR bstrComponentName = NULL;
|
|
|
|
rgCatIds[ 0 ] = CATID_EnumClusCfgManagedResources;
|
|
|
|
hr = THR( CoCreateInstance( CLSID_StdComponentCategoriesMgr, NULL, CLSCTX_INPROC_SERVER, IID_ICatInformation, (void **) &pici ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
|
|
hr = THR( pici->EnumClassesOfCategories( 1, rgCatIds, 0, NULL, &pieclsids ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
for ( ; ; )
|
|
{
|
|
|
|
//
|
|
// Cleanup.
|
|
//
|
|
|
|
if ( punk != NULL )
|
|
{
|
|
punk->Release();
|
|
punk = NULL;
|
|
} // if:
|
|
|
|
TraceSysFreeString( bstrComponentName );
|
|
bstrComponentName = NULL;
|
|
|
|
hr = STHR( pieclsids->Next( 1, &clsid, &cFetched ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
//
|
|
// When hr is S_FALSE and the count is 0 then the enum is really
|
|
// at the end.
|
|
//
|
|
|
|
if ( ( hr == S_FALSE ) && ( cFetched == 0 ) )
|
|
{
|
|
hr = S_OK;
|
|
break;
|
|
} // if:
|
|
|
|
//
|
|
// Create a GUID string for logging purposes...
|
|
//
|
|
|
|
cch = StringFromGUID2( clsid, szGUID, RTL_NUMBER_OF( szGUID ) );
|
|
Assert( cch > 0 ); // 64 chars should always hold a guid!
|
|
|
|
//
|
|
// Get the best name we have available for the COM component. If for
|
|
// any reason we cannot get the name then make one up and continue.
|
|
//
|
|
|
|
hr = THR( HrGetDefaultComponentNameFromRegistry( &clsid, &bstrComponentName ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
bstrComponentName = TraceSysAllocString( L"<Unknown> component" );
|
|
if ( bstrComponentName == NULL )
|
|
{
|
|
hr = THR( E_OUTOFMEMORY );
|
|
goto Cleanup;
|
|
} // if:
|
|
} // if:
|
|
|
|
//
|
|
// If we cannot create the component then log the error and continue. We should load as many components as we can.
|
|
//
|
|
|
|
hr = THR( HrCoCreateInternalInstance( clsid, NULL, CLSCTX_SERVER, IID_IEnumClusCfgManagedResources, (void **) &pieccmr ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
LOG_STATUS_REPORT_STRING_MINOR2( TASKID_Minor_MREnum_Cannot_Create_Component, L"Could not create component %1!ws! %2!ws!.", bstrComponentName, szGUID, hr );
|
|
hr = S_OK;
|
|
continue;
|
|
} // if:
|
|
|
|
//
|
|
// If we cannot QI the component then log the error and continue. We should load as many components as we can.
|
|
//
|
|
|
|
hr = THR( pieccmr->TypeSafeQI( IUnknown, &punk ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
LOG_STATUS_REPORT_STRING_MINOR2( TASKID_Minor_MREnum_Cannot_QI_Component_For_Punk, L"Could not QI for IUnknown on component %1!ws! %2!ws!.", bstrComponentName, szGUID, hr );
|
|
hr = S_OK;
|
|
continue;
|
|
} // if:
|
|
|
|
punk = TraceInterface( L"IEnumClusCfgManagedResources", IUnknown, punk, 1 );
|
|
|
|
pieccmr->Release();
|
|
pieccmr = NULL;
|
|
|
|
//
|
|
// If this fails then simply skip it and move on...
|
|
//
|
|
|
|
hr = HrInitializeAndSaveEnum( punk, &clsid, bstrComponentName );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
LOG_STATUS_REPORT_STRING_MINOR2( TASKID_Minor_MREnum_Cannot_Save_Provider, L"Could not save enumerator component %1!ws! %2!ws!.", bstrComponentName, szGUID, hr );
|
|
hr = S_OK;
|
|
continue;
|
|
} // if:
|
|
|
|
if ( hr == S_OK )
|
|
{
|
|
m_fLoadedDevices = TRUE; // there is at least one provider loaded.
|
|
} // if:
|
|
} // for: each CLSID that implements our CATID...
|
|
|
|
hr = STHR( HrLoadUnknownQuorumProvider() );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
Cleanup:
|
|
|
|
if ( pieclsids != NULL )
|
|
{
|
|
pieclsids->Release();
|
|
} // if:
|
|
|
|
if ( pici != NULL )
|
|
{
|
|
pici->Release();
|
|
} // if:
|
|
|
|
if ( pieccmr != NULL )
|
|
{
|
|
pieccmr->Release();
|
|
} // if:
|
|
|
|
if ( punk != NULL )
|
|
{
|
|
punk->Release();
|
|
} // if:
|
|
|
|
TraceSysFreeString( bstrComponentName );
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CEnumClusCfgManagedResources::HrLoadEnum
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CEnumClusCfgManagedResources::HrDoNext
|
|
//
|
|
// Description:
|
|
// Gets the required number of elements from the contained physical disk
|
|
// and optional 3rd party device enumerations.
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Return Value:
|
|
//
|
|
// Remarks:
|
|
// None.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
HRESULT
|
|
CEnumClusCfgManagedResources::HrDoNext(
|
|
ULONG cNumberRequestedIn
|
|
, IClusCfgManagedResourceInfo ** rgpManagedResourceInfoOut
|
|
, ULONG * pcNumberFetchedOut
|
|
)
|
|
{
|
|
TraceFunc( "" );
|
|
Assert( rgpManagedResourceInfoOut != NULL );
|
|
Assert( pcNumberFetchedOut != NULL );
|
|
Assert( m_prgEnums != NULL );
|
|
|
|
HRESULT hr = S_FALSE;
|
|
IEnumClusCfgManagedResources * peccsd = NULL;
|
|
ULONG cRequested = cNumberRequestedIn;
|
|
ULONG cFetched = 0;
|
|
ULONG cTotal = 0;
|
|
IClusCfgManagedResourceInfo ** ppccmriTemp = rgpManagedResourceInfoOut;
|
|
int cch;
|
|
WCHAR szGUID[ 64 ];
|
|
|
|
//
|
|
// Call each enumerator in the list trying to get the number of requested
|
|
// items. Note that we may call the same enumerator more than once in
|
|
// this loop. The second call is to ensure that we are really at the
|
|
// end of the enumerator.
|
|
//
|
|
|
|
LOG_STATUS_REPORT_STRING3( L"[SRV] Enumerating resources. Total Requested:%1!d!; Current enum index:%2!d!; Total Enums:%3!d!.", cNumberRequestedIn, m_idxCurrentEnum, m_idxNextEnum, hr );
|
|
|
|
while ( m_idxCurrentEnum < m_idxNextEnum )
|
|
{
|
|
//
|
|
// Cleanup.
|
|
//
|
|
|
|
if ( peccsd != NULL )
|
|
{
|
|
peccsd->Release();
|
|
peccsd = NULL;
|
|
} // if:
|
|
|
|
cch = StringFromGUID2( (m_prgEnums[ m_idxCurrentEnum ]).clsid, szGUID, RTL_NUMBER_OF( szGUID ) );
|
|
Assert( cch > 0 ); // 64 chars should always hold a guid!
|
|
|
|
Assert( (m_prgEnums[ m_idxCurrentEnum ]).punk != NULL );
|
|
hr = THR( (m_prgEnums[ m_idxCurrentEnum ]).punk->TypeSafeQI( IEnumClusCfgManagedResources, &peccsd ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
HRESULT hrTemp;
|
|
|
|
//
|
|
// Convert this into a warning in the UI...
|
|
//
|
|
|
|
hrTemp = MAKE_HRESULT( SEVERITY_SUCCESS, HRESULT_FACILITY( hr ), HRESULT_CODE( hr ) );
|
|
|
|
//
|
|
// If we cannot QI for the enum then move on to the next one.
|
|
//
|
|
|
|
STATUS_REPORT_STRING2_REF(
|
|
TASKID_Major_Find_Devices
|
|
, TASKID_Minor_Enum_Enum_QI_Failed
|
|
, IDS_WARNING_SKIPPING_ENUM
|
|
, (m_prgEnums[ m_idxCurrentEnum ]).bstrComponentName
|
|
, szGUID
|
|
, IDS_WARNING_SKIPPING_ENUM
|
|
, hrTemp
|
|
);
|
|
|
|
m_idxCurrentEnum++;
|
|
continue;
|
|
} // if:
|
|
|
|
hr = STHR( peccsd->Next( cRequested, ppccmriTemp, &cFetched ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
HRESULT hrTemp;
|
|
|
|
//
|
|
// Convert this into a warning in the UI...
|
|
//
|
|
|
|
hrTemp = MAKE_HRESULT( SEVERITY_SUCCESS, HRESULT_FACILITY( hr ), HRESULT_CODE( hr ) );
|
|
|
|
//
|
|
// If this enumerator fails for anyreason then we should skip it
|
|
// and move on to the next one.
|
|
//
|
|
|
|
STATUS_REPORT_STRING2_REF(
|
|
TASKID_Major_Find_Devices
|
|
, TASKID_Minor_Enum_Enum_Next_Failed
|
|
, IDS_WARNING_SKIPPING_ENUM
|
|
, (m_prgEnums[ m_idxCurrentEnum ]).bstrComponentName
|
|
, szGUID
|
|
, IDS_WARNING_SKIPPING_ENUM
|
|
, hrTemp
|
|
);
|
|
|
|
m_idxCurrentEnum++;
|
|
continue;
|
|
} // if:
|
|
else if ( hr == S_OK )
|
|
{
|
|
cTotal += cFetched;
|
|
|
|
//
|
|
// We can only return S_OK if the number of elements returned is equal to
|
|
// the number of elements requested. If the number request is greater than
|
|
// the number returned then we must return S_FALSE.
|
|
//
|
|
|
|
Assert( cNumberRequestedIn == cTotal );
|
|
*pcNumberFetchedOut = cTotal;
|
|
break;
|
|
} // else if: hr == S_OK
|
|
else if ( hr == S_FALSE )
|
|
{
|
|
//
|
|
// The only time that we can be certain that an enumerator is
|
|
// empty is to get S_FALSE and no elements returned. Now that
|
|
// the current enumerator empty move up to the next one in the
|
|
// list.
|
|
//
|
|
|
|
if ( cFetched == 0 )
|
|
{
|
|
m_idxCurrentEnum++;
|
|
continue;
|
|
} // if:
|
|
|
|
//
|
|
// Update the totals...
|
|
//
|
|
|
|
cTotal += cFetched;
|
|
*pcNumberFetchedOut = cTotal;
|
|
cRequested -= cFetched;
|
|
|
|
//
|
|
// If we got some items and still got S_FALSE then we have to
|
|
// retry the current enumerator.
|
|
//
|
|
|
|
if ( cRequested > 0 )
|
|
{
|
|
ppccmriTemp += cFetched;
|
|
continue;
|
|
} // if: Safety check... Ensure that we still need more elements...
|
|
else
|
|
{
|
|
//
|
|
// We should not have decremented requested items below zero!
|
|
//
|
|
|
|
hr = S_FALSE;
|
|
LOG_STATUS_REPORT_MINOR( TASKID_Minor_MREnum_Negative_Item_Count, L"The managed resources enumerator tried to return more items than asked for.", hr );
|
|
goto Cleanup;
|
|
} // else: Should not get here...
|
|
} // if: hr == S_FALSE
|
|
else
|
|
{
|
|
//
|
|
// Should not get here as we are in an unknown state...
|
|
//
|
|
|
|
LOG_STATUS_REPORT_MINOR( TASKID_Minor_MREnum_Unknown_State, L"The managed resources enumerator encountered an unknown state.", hr );
|
|
goto Cleanup;
|
|
} // else: unexpected hresult...
|
|
} // while: more enumerators in the list
|
|
|
|
//
|
|
// If we haven't honored the complete request then we must return
|
|
// S_FALSE;
|
|
//
|
|
|
|
if ( *pcNumberFetchedOut < cNumberRequestedIn )
|
|
{
|
|
hr = S_FALSE;
|
|
} // if:
|
|
|
|
Cleanup:
|
|
|
|
if ( peccsd != NULL )
|
|
{
|
|
peccsd->Release();
|
|
} // if:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CEnumClusCfgManagedResources::HrDoNext
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CEnumClusCfgManagedResources::HrDoSkip
|
|
//
|
|
// Description:
|
|
// Skips the required number of elements in the contained physical disk
|
|
// and optional 3rd party device enumerations.
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Return Value:
|
|
//
|
|
// Remarks:
|
|
// None.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
HRESULT
|
|
CEnumClusCfgManagedResources::HrDoSkip(
|
|
ULONG cNumberToSkipIn
|
|
)
|
|
{
|
|
TraceFunc( "" );
|
|
Assert( m_prgEnums != NULL );
|
|
|
|
HRESULT hr = S_FALSE;
|
|
IEnumClusCfgManagedResources * peccsd = NULL;
|
|
ULONG cSkipped = 0;
|
|
|
|
for ( ; m_idxCurrentEnum < m_idxNextEnum; )
|
|
{
|
|
hr = THR( (m_prgEnums[ m_idxCurrentEnum ]).punk->TypeSafeQI( IEnumClusCfgManagedResources, &peccsd ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
do
|
|
{
|
|
hr = STHR( peccsd->Skip( 1 ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
if ( hr == S_FALSE )
|
|
{
|
|
m_idxCurrentEnum++;
|
|
break;
|
|
} // if:
|
|
}
|
|
while( cNumberToSkipIn >= (++cSkipped) );
|
|
|
|
peccsd->Release();
|
|
peccsd = NULL;
|
|
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
if ( cNumberToSkipIn == cSkipped )
|
|
{
|
|
break;
|
|
} // if:
|
|
} // for:
|
|
|
|
Cleanup:
|
|
|
|
if ( peccsd != NULL )
|
|
{
|
|
peccsd->Release();
|
|
} // if:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CEnumClusCfgManagedResources::HrDoSkip
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CEnumClusCfgManagedResources::HrDoReset
|
|
//
|
|
// Description:
|
|
// Resets the elements in the contained physical disk and optional 3rd
|
|
// party device enumerations.
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Return Value:
|
|
//
|
|
// Remarks:
|
|
// None.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
HRESULT
|
|
CEnumClusCfgManagedResources::HrDoReset( void )
|
|
{
|
|
TraceFunc( "" );
|
|
|
|
HRESULT hr = S_FALSE;
|
|
IEnumClusCfgManagedResources * peccsd;
|
|
ULONG idx;
|
|
|
|
m_idxCurrentEnum = 0;
|
|
|
|
for ( idx = m_idxCurrentEnum; idx < m_idxNextEnum; idx++ )
|
|
{
|
|
Assert( m_prgEnums != NULL );
|
|
|
|
hr = THR( (m_prgEnums[ idx ]).punk->TypeSafeQI( IEnumClusCfgManagedResources, &peccsd ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
break;
|
|
} // if:
|
|
|
|
hr = STHR( peccsd->Reset() );
|
|
peccsd->Release();
|
|
|
|
if ( FAILED( hr ) )
|
|
{
|
|
break;
|
|
} // if:
|
|
} // for:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CEnumClusCfgManagedResources::HrDoReset
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CEnumClusCfgManagedResources::HrDoClone
|
|
//
|
|
// Description:
|
|
// Clones the elements in the contained physical disk and optional 3rd
|
|
// party device enumerations.
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Return Value:
|
|
//
|
|
// Remarks:
|
|
// None.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
HRESULT
|
|
CEnumClusCfgManagedResources::HrDoClone(
|
|
IEnumClusCfgManagedResources ** ppEnumClusCfgManagedResourcesOut
|
|
)
|
|
{
|
|
TraceFunc( "" );
|
|
|
|
HRESULT hr = THR( E_NOTIMPL );
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CEnumClusCfgManagedResources::HrDoClone
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CEnumClusCfgManagedResources:HrAddToEnumsArray
|
|
//
|
|
// Description:
|
|
// Add the passed in punk to the array of punks that holds the enums.
|
|
//
|
|
// Arguments:
|
|
//
|
|
//
|
|
// Return Value:
|
|
// S_OK
|
|
// Success
|
|
//
|
|
// E_OUTOFMEMORY
|
|
// Couldn't allocate memeory.
|
|
//
|
|
// Remarks:
|
|
// None.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
HRESULT
|
|
CEnumClusCfgManagedResources::HrAddToEnumsArray(
|
|
IUnknown * punkIn
|
|
, CLSID * pclsidIn
|
|
, BSTR bstrComponentNameIn
|
|
)
|
|
{
|
|
TraceFunc( "" );
|
|
Assert( punkIn != NULL );
|
|
Assert( pclsidIn != NULL );
|
|
Assert( bstrComponentNameIn != NULL );
|
|
|
|
HRESULT hr = S_OK;
|
|
SEnumInfo * prgEnums = NULL;
|
|
IEnumClusCfgManagedResources * pieccmr = NULL;
|
|
DWORD nAmountToAdd = 0;
|
|
|
|
hr = punkIn->TypeSafeQI( IEnumClusCfgManagedResources, &pieccmr );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
hr = pieccmr->Count( &nAmountToAdd );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
WCHAR szGUID[ 64 ];
|
|
int cch;
|
|
HRESULT hrTemp;
|
|
|
|
//
|
|
// Convert this into a warning in the UI...
|
|
//
|
|
|
|
hrTemp = MAKE_HRESULT( SEVERITY_SUCCESS, HRESULT_FACILITY( hr ), HRESULT_CODE( hr ) );
|
|
|
|
cch = StringFromGUID2( *pclsidIn, szGUID, RTL_NUMBER_OF( szGUID ) );
|
|
Assert( cch > 0 ); // 64 chars should always hold a guid!
|
|
|
|
STATUS_REPORT_STRING2_REF(
|
|
TASKID_Major_Find_Devices
|
|
, TASKID_Minor_Enum_Enum_Count_Failed
|
|
, IDS_WARNING_SKIPPING_ENUM
|
|
, bstrComponentNameIn
|
|
, szGUID
|
|
, IDS_WARNING_SKIPPING_ENUM
|
|
, hrTemp
|
|
);
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
prgEnums = (SEnumInfo *) TraceReAlloc( m_prgEnums, sizeof( SEnumInfo ) * ( m_idxNextEnum + 1 ), HEAP_ZERO_MEMORY );
|
|
if ( prgEnums == NULL )
|
|
{
|
|
hr = THR( E_OUTOFMEMORY );
|
|
STATUS_REPORT_REF( TASKID_Major_Find_Devices, TASKID_Minor_HrAddToEnumsArray, IDS_ERROR_OUTOFMEMORY, IDS_ERROR_OUTOFMEMORY_REF, hr );
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
m_prgEnums = prgEnums;
|
|
|
|
//
|
|
// Fill in the newly allocated struct.
|
|
//
|
|
|
|
(m_prgEnums[ m_idxNextEnum ]).punk = punkIn;
|
|
(m_prgEnums[ m_idxNextEnum ]).punk->AddRef();
|
|
|
|
CopyMemory( &((m_prgEnums[ m_idxNextEnum ]).clsid), pclsidIn, sizeof( ( m_prgEnums[ m_idxNextEnum ]).clsid ) );
|
|
|
|
//
|
|
// Capture the component name. We don't really care if this fails.
|
|
// Simply show the popup for anyone who may be watching and continue on.
|
|
//
|
|
|
|
(m_prgEnums[ m_idxNextEnum ]).bstrComponentName = TraceSysAllocString( bstrComponentNameIn );
|
|
if ( (m_prgEnums[ m_idxNextEnum ]).bstrComponentName == NULL )
|
|
{
|
|
THR( E_OUTOFMEMORY );
|
|
} // if:
|
|
|
|
//
|
|
// Increment the enum index pointer.
|
|
//
|
|
|
|
m_idxNextEnum++;
|
|
|
|
m_cTotalResources += nAmountToAdd;
|
|
|
|
Cleanup:
|
|
|
|
if ( pieccmr != NULL )
|
|
{
|
|
pieccmr->Release();
|
|
}
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CEnumClusCfgManagedResources::HrAddToEnumsArray
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CEnumClusCfgManagedResources:HrLoadUnknownQuorumProvider
|
|
//
|
|
// Description:
|
|
// Since we cannot resonable expect every 3rd party quorum vender
|
|
// to write a "provider" for their device for this setup wizard
|
|
// we need a proxy to represent that quorum device. The "unknown"
|
|
// is just such a proxy.
|
|
//
|
|
// Arguments:
|
|
// None.
|
|
//
|
|
// Return Value:
|
|
// S_OK
|
|
// Success
|
|
//
|
|
// E_OUTOFMEMORY
|
|
// Couldn't allocate memeory.
|
|
//
|
|
// Remarks:
|
|
// If this node is clustered and we do not find a device that is
|
|
// already the quorum then we need to make the "unknown" quorum
|
|
// the quorum device.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
HRESULT
|
|
CEnumClusCfgManagedResources::HrLoadUnknownQuorumProvider( void )
|
|
{
|
|
TraceFunc( "" );
|
|
|
|
HRESULT hr = S_OK;
|
|
IUnknown * punk = NULL;
|
|
BOOL fNeedQuorum = FALSE;
|
|
BOOL fQuormIsOwnedByThisNode = FALSE;
|
|
BSTR bstrQuorumResourceName = NULL;
|
|
BSTR bstrComponentName = NULL;
|
|
|
|
hr = STHR( HrIsClusterServiceRunning() );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
if ( hr == S_OK )
|
|
{
|
|
hr = STHR( HrIsThereAQuorumDevice() );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
if ( hr == S_FALSE )
|
|
{
|
|
fNeedQuorum = TRUE;
|
|
} // if:
|
|
|
|
hr = THR( HrGetQuorumResourceName( &bstrQuorumResourceName, &fQuormIsOwnedByThisNode ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
} // if:
|
|
} // if:
|
|
|
|
//
|
|
// If there was not already a quorum, and if this node owns the quorum resource
|
|
// then we need the unknown quorum proxy to be set as default to the quorum device.
|
|
//
|
|
// If we are not running on a cluster node then both are false and the unknown
|
|
// quorum proxy will not be set by default to be the quorum.
|
|
//
|
|
|
|
hr = THR( CEnumUnknownQuorum::S_HrCreateInstance( bstrQuorumResourceName, ( fNeedQuorum && fQuormIsOwnedByThisNode ), &punk ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
hr = THR( HrLoadStringIntoBSTR( g_hInstance, IDS_ENUM_UNKNOWN_QUORUM_COMPONENT_NAME, &bstrComponentName ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
hr = THR( HrInitializeAndSaveEnum( punk, const_cast< CLSID * >( &CLSID_EnumUnknownQuorum ), bstrComponentName ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
Cleanup:
|
|
|
|
if ( punk != NULL )
|
|
{
|
|
punk->Release();
|
|
} // if:
|
|
|
|
TraceSysFreeString( bstrQuorumResourceName );
|
|
TraceSysFreeString( bstrComponentName );
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CEnumClusCfgManagedResources::HrLoadUnknownQuorumProvider
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CEnumClusCfgManagedResources:HrIsClusterServiceRunning
|
|
//
|
|
// Description:
|
|
// Is this node a member of a cluster and is the serice running?
|
|
//
|
|
// Arguments:
|
|
// None.
|
|
//
|
|
// Return Value:
|
|
// S_OK
|
|
// The node is clustered and the serivce is running.
|
|
//
|
|
// S_FALSE
|
|
// The node is not clustered, or the serivce is not running.
|
|
//
|
|
// Win32 Error
|
|
// something failed.
|
|
//
|
|
// Remarks:
|
|
// None.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
HRESULT
|
|
CEnumClusCfgManagedResources::HrIsClusterServiceRunning( void )
|
|
{
|
|
TraceFunc( "" );
|
|
|
|
HRESULT hr = S_FALSE;
|
|
DWORD sc;
|
|
DWORD dwClusterState;
|
|
|
|
//
|
|
// Get the cluster state of the node.
|
|
// Ignore the case where the service does not exist so that
|
|
// EvictCleanup can do its job.
|
|
//
|
|
|
|
sc = GetNodeClusterState( NULL, &dwClusterState );
|
|
if ( ( sc != ERROR_SUCCESS ) && ( sc != ERROR_SERVICE_DOES_NOT_EXIST ) )
|
|
{
|
|
hr = HRESULT_FROM_WIN32( TW32( sc ) );
|
|
goto Cleanup;
|
|
} // if : GetClusterState() failed
|
|
|
|
if ( dwClusterState == ClusterStateRunning )
|
|
{
|
|
hr = S_OK;
|
|
} // if:
|
|
|
|
Cleanup:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CEnumClusCfgManagedResources::HrIsClusterServiceRunning
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CEnumClusCfgManagedResources:HrIsThereAQuorumDevice
|
|
//
|
|
// Description:
|
|
// Is there a quorum device in an enum somewhere?
|
|
//
|
|
// Arguments:
|
|
// None.
|
|
//
|
|
// Return Value:
|
|
// S_OK
|
|
// There is a quorum device.
|
|
//
|
|
// S_FALSE
|
|
// There is not a quorum device.
|
|
//
|
|
// Win32 Error
|
|
// something failed.
|
|
//
|
|
// Remarks:
|
|
// None.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
HRESULT
|
|
CEnumClusCfgManagedResources::HrIsThereAQuorumDevice( void )
|
|
{
|
|
TraceFunc( "" );
|
|
Assert( m_idxCurrentEnum == 0 );
|
|
|
|
HRESULT hr = S_OK;
|
|
IClusCfgManagedResourceInfo * piccmri = NULL;
|
|
DWORD cFetched;
|
|
bool fFoundQuorum = false;
|
|
|
|
for ( ; ; )
|
|
{
|
|
hr = STHR( Next( 1, &piccmri, &cFetched ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
if ( ( hr == S_FALSE ) && ( cFetched == 0 ) )
|
|
{
|
|
hr = S_OK;
|
|
break;
|
|
} // if:
|
|
|
|
hr = STHR( piccmri->IsQuorumResource() );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
if ( hr == S_OK )
|
|
{
|
|
fFoundQuorum = true;
|
|
break;
|
|
} // if:
|
|
|
|
piccmri->Release();
|
|
piccmri = NULL;
|
|
} // for:
|
|
|
|
hr = THR( Reset() );
|
|
|
|
Cleanup:
|
|
|
|
if ( piccmri != NULL )
|
|
{
|
|
piccmri->Release();
|
|
} // if:
|
|
|
|
if ( SUCCEEDED( hr ) )
|
|
{
|
|
if ( fFoundQuorum )
|
|
{
|
|
hr = S_OK;
|
|
} // if:
|
|
else
|
|
{
|
|
hr = S_FALSE;
|
|
} // else:
|
|
} // if:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CEnumClusCfgManagedResources::HrIsThereAQuorumDevice
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CEnumClusCfgManagedResources:HrInitializeAndSaveEnum
|
|
//
|
|
// Description:
|
|
// Initialize the passed in enum and add it to the array of enums.
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Return Value:
|
|
// S_OK
|
|
// Success.
|
|
//
|
|
// S_FALSE
|
|
// The provider was not saved.
|
|
//
|
|
// Win32 Error
|
|
// something failed.
|
|
//
|
|
// Remarks:
|
|
// None.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
HRESULT
|
|
CEnumClusCfgManagedResources::HrInitializeAndSaveEnum(
|
|
IUnknown * punkIn
|
|
, CLSID * pclsidIn
|
|
, BSTR bstrComponentNameIn
|
|
)
|
|
{
|
|
TraceFunc( "" );
|
|
Assert( punkIn != NULL );
|
|
Assert( pclsidIn != NULL );
|
|
Assert( bstrComponentNameIn != NULL );
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
//
|
|
// KB: 13-JUN-2000 GalenB
|
|
//
|
|
// If S_FALSE is returned don't add this to the array. S_FALSE
|
|
// indicates that this enumerator should not be run now.
|
|
//
|
|
|
|
hr = STHR( HrSetInitialize( punkIn, m_picccCallback, m_lcid ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
if ( hr == S_FALSE )
|
|
{
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
hr = HrSetWbemServices( punkIn, m_pIWbemServices );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
hr = THR( HrAddToEnumsArray( punkIn, pclsidIn, bstrComponentNameIn ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
Cleanup:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CEnumClusCfgManagedResources::HrInitializeAndSaveEnum
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CEnumClusCfgManagedResources:HrGetQuorumResourceName
|
|
//
|
|
// Description:
|
|
// Get the quorum resource name and return whether or not this node
|
|
// owns the quorum.
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Return Value:
|
|
// S_OK
|
|
// Success.
|
|
//
|
|
// Win32 Error
|
|
// something failed.
|
|
//
|
|
// Remarks:
|
|
// None.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
HRESULT
|
|
CEnumClusCfgManagedResources::HrGetQuorumResourceName(
|
|
BSTR * pbstrQuorumResourceNameOut
|
|
, BOOL * pfQuormIsOwnedByThisNodeOut
|
|
)
|
|
{
|
|
TraceFunc( "" );
|
|
Assert( pbstrQuorumResourceNameOut != NULL );
|
|
Assert( pfQuormIsOwnedByThisNodeOut != NULL );
|
|
|
|
HRESULT hr = S_OK;
|
|
DWORD sc;
|
|
HCLUSTER hCluster = NULL;
|
|
BSTR bstrQuorumResourceName = NULL;
|
|
BSTR bstrNodeName = NULL;
|
|
HRESOURCE hQuorumResource = NULL;
|
|
BSTR bstrLocalNetBIOSName = NULL;
|
|
|
|
//
|
|
// Get netbios name for clusapi calls.
|
|
//
|
|
|
|
hr = THR( HrGetComputerName( ComputerNameNetBIOS, &bstrLocalNetBIOSName, TRUE ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
hCluster = OpenCluster( NULL );
|
|
if ( hCluster == NULL )
|
|
{
|
|
sc = TW32( GetLastError() );
|
|
hr = HRESULT_FROM_WIN32( sc );
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
hr = THR( HrGetClusterQuorumResource( hCluster, &bstrQuorumResourceName, NULL, NULL ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
hQuorumResource = OpenClusterResource( hCluster, bstrQuorumResourceName );
|
|
if ( hQuorumResource == NULL )
|
|
{
|
|
sc = TW32( GetLastError() );
|
|
hr = HRESULT_FROM_WIN32( sc );
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
hr = THR( HrGetClusterResourceState( hQuorumResource, &bstrNodeName, NULL, NULL ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
//
|
|
// Give ownership away.
|
|
//
|
|
|
|
Assert( bstrQuorumResourceName != NULL );
|
|
*pbstrQuorumResourceNameOut = bstrQuorumResourceName;
|
|
bstrQuorumResourceName = NULL;
|
|
|
|
*pfQuormIsOwnedByThisNodeOut = ( NBSTRCompareNoCase( bstrLocalNetBIOSName, bstrNodeName ) == 0 );
|
|
|
|
Cleanup:
|
|
|
|
if ( hQuorumResource != NULL )
|
|
{
|
|
CloseClusterResource( hQuorumResource );
|
|
} // if:
|
|
|
|
if ( hCluster != NULL )
|
|
{
|
|
CloseCluster( hCluster );
|
|
} // if:
|
|
|
|
TraceSysFreeString( bstrQuorumResourceName );
|
|
TraceSysFreeString( bstrLocalNetBIOSName );
|
|
TraceSysFreeString( bstrNodeName );
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CEnumClusCfgManagedResources::HrGetQuorumResourceName
|