////////////////////////////////////////////////////////////////////////////// // // 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" 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