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.
2166 lines
53 KiB
2166 lines
53 KiB
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Copyright (c) 2000-2002 Microsoft Corporation
|
|
//
|
|
// Module Name:
|
|
// CClusCfgClusterInfo.cpp
|
|
//
|
|
// Description:
|
|
// This file contains the definition of the CClusCfgClusterInfo
|
|
// class.
|
|
//
|
|
// The class CClusCfgClusterInfo is the representation of a
|
|
// cluster. It implements the IClusCfgClusterInfo interface.
|
|
//
|
|
// Maintained By:
|
|
// Galen Barbee (GalenB) 22-FEB-2000
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// Include Files
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
#include "Pch.h"
|
|
#include <PropList.h>
|
|
#include <ClusRtl.h>
|
|
#include <windns.h>
|
|
#include <commctrl.h>
|
|
#include <ClusCfgPrivate.h>
|
|
#include <ClusterUtils.h>
|
|
|
|
#include "CClusCfgClusterInfo.h"
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// Constant Definitions
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
DEFINE_THISCLASS( "CClusCfgClusterInfo" );
|
|
|
|
|
|
//*************************************************************************//
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CClusCfgClusterInfo class
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgClusterInfo::S_HrCreateInstance
|
|
//
|
|
// Description:
|
|
// Create a CClusCfgClusterInfo instance.
|
|
//
|
|
// Arguments:
|
|
// None.
|
|
//
|
|
// Return Values:
|
|
// S_OK
|
|
// Success.
|
|
//
|
|
// E_POINTER
|
|
// A passed in argument is NULL.
|
|
//
|
|
// E_OUTOFMEMORY
|
|
// Out of memory.
|
|
//
|
|
// Other HRESULT error.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
HRESULT
|
|
CClusCfgClusterInfo::S_HrCreateInstance(
|
|
IUnknown ** ppunkOut
|
|
)
|
|
{
|
|
TraceFunc( "" );
|
|
|
|
HRESULT hr = S_OK;
|
|
CClusCfgClusterInfo * pccci = NULL;
|
|
|
|
if ( ppunkOut == NULL )
|
|
{
|
|
hr = THR( E_POINTER );
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
pccci = new CClusCfgClusterInfo();
|
|
if ( pccci == NULL )
|
|
{
|
|
hr = THR( E_OUTOFMEMORY );
|
|
goto Cleanup;
|
|
} // if: error allocating object
|
|
|
|
hr = THR( pccci->HrInit() );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
} // if: HrInit() failed
|
|
|
|
hr = THR( pccci->TypeSafeQI( IUnknown, ppunkOut ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
} // if: QI failed
|
|
|
|
Cleanup:
|
|
|
|
if ( pccci != NULL )
|
|
{
|
|
pccci->Release();
|
|
} // if:
|
|
|
|
if ( FAILED( hr ) )
|
|
{
|
|
LogMsg( L"[SRV] CClusCfgClusterInfo::S_HrCreateInstance() failed. (hr = %#08x)", hr );
|
|
} // if:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgClusterInfo::S_HrCreateInstance
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgClusterInfo::CClusCfgClusterInfo
|
|
//
|
|
// Description:
|
|
// Constructor of the CClusCfgClusterInfo 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.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
CClusCfgClusterInfo::CClusCfgClusterInfo( void )
|
|
: m_cRef( 1 )
|
|
, m_lcid( LOCALE_NEUTRAL )
|
|
{
|
|
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_bstrName == NULL );
|
|
Assert( m_piccniNetwork == NULL );
|
|
Assert( m_ulIPDottedQuad == 0 );
|
|
Assert( m_ulSubnetDottedQuad == 0 );
|
|
Assert( m_punkServiceAccountCredentials == NULL );
|
|
Assert( m_pIWbemServices == NULL );
|
|
Assert( m_ecmCommitChangesMode == cmUNKNOWN );
|
|
Assert( m_bstrBindingString == NULL );
|
|
|
|
TraceFuncExit();
|
|
|
|
} //*** CClusCfgClusterInfo::CClusCfgClusterInfo
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgClusterInfo::~CClusCfgClusterInfo
|
|
//
|
|
// Description:
|
|
// Desstructor of the CClusCfgClusterInfo class.
|
|
//
|
|
// Arguments:
|
|
// None.
|
|
//
|
|
// Return Value:
|
|
// None.
|
|
//
|
|
// Remarks:
|
|
// None.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
CClusCfgClusterInfo::~CClusCfgClusterInfo( void )
|
|
{
|
|
TraceFunc( "" );
|
|
|
|
if ( m_picccCallback != NULL )
|
|
{
|
|
m_picccCallback->Release();
|
|
} // if:
|
|
|
|
if ( m_piccniNetwork != NULL )
|
|
{
|
|
m_piccniNetwork->Release();
|
|
} // if:
|
|
|
|
if ( m_punkServiceAccountCredentials != NULL )
|
|
{
|
|
m_punkServiceAccountCredentials->Release();
|
|
} // if:
|
|
|
|
if ( m_pIWbemServices != NULL )
|
|
{
|
|
m_pIWbemServices->Release();
|
|
} // if:
|
|
|
|
TraceSysFreeString( m_bstrName );
|
|
TraceSysFreeString( m_bstrBindingString );
|
|
|
|
// There's going to be one less component in memory. Decrement component count.
|
|
InterlockedDecrement( &g_cObjects );
|
|
|
|
TraceFuncExit();
|
|
|
|
} //*** CClusCfgClusterInfo::~CClusCfgClusterInfo
|
|
|
|
|
|
//*************************************************************************//
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CClusCfgClusterInfo -- IUknkown interface.
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgClusterInfo::AddRef
|
|
//
|
|
// Description:
|
|
// Increment the reference count of this object by one.
|
|
//
|
|
// Arguments:
|
|
// None.
|
|
//
|
|
// Return Value:
|
|
// The new reference count.
|
|
//
|
|
// Remarks:
|
|
// None.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP_( ULONG )
|
|
CClusCfgClusterInfo::AddRef( void )
|
|
{
|
|
TraceFunc( "[IUnknown]" );
|
|
|
|
InterlockedIncrement( & m_cRef );
|
|
|
|
CRETURN( m_cRef );
|
|
|
|
} //*** CClusCfgClusterInfo::AddRef
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgClusterInfo::Release
|
|
//
|
|
// Description:
|
|
// Decrement the reference count of this object by one.
|
|
//
|
|
// Arguments:
|
|
// None.
|
|
//
|
|
// Return Value:
|
|
// The new reference count.
|
|
//
|
|
// Remarks:
|
|
// None.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP_( ULONG )
|
|
CClusCfgClusterInfo::Release( void )
|
|
{
|
|
TraceFunc( "[IUnknown]" );
|
|
|
|
LONG cRef;
|
|
|
|
cRef = InterlockedDecrement( &m_cRef );
|
|
if ( cRef == 0 )
|
|
{
|
|
TraceDo( delete this );
|
|
} // if: reference count equal to zero
|
|
|
|
CRETURN( cRef );
|
|
|
|
} //*** CClusCfgClusterInfo::Release
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgClusterInfo::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
|
|
CClusCfgClusterInfo::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< IClusCfgClusterInfo * >( this );
|
|
} // if: IUnknown
|
|
else if ( IsEqualIID( riidIn, IID_IClusCfgClusterInfo ) )
|
|
{
|
|
*ppvOut = TraceInterface( __THISCLASS__, IClusCfgClusterInfo, this, 0 );
|
|
} // else if: IClusCfgClusterInfo
|
|
else if ( IsEqualIID( riidIn, IID_IClusCfgInitialize ) )
|
|
{
|
|
*ppvOut = TraceInterface( __THISCLASS__, IClusCfgInitialize, this, 0 );
|
|
} // else if: IClusCfgInitialize
|
|
else if ( IsEqualIID( riidIn, IID_IClusCfgSetClusterNodeInfo ) )
|
|
{
|
|
*ppvOut = TraceInterface( __THISCLASS__, IClusCfgSetClusterNodeInfo, this, 0 );
|
|
} // else if: IClusCfgSetClusterNodeInfo
|
|
else if ( IsEqualIID( riidIn, IID_IClusCfgWbemServices ) )
|
|
{
|
|
*ppvOut = TraceInterface( __THISCLASS__, IClusCfgWbemServices, this, 0 );
|
|
} // else if: IClusCfgWbemServices
|
|
else if ( IsEqualIID( riidIn, IID_IClusCfgClusterInfoEx ) )
|
|
{
|
|
*ppvOut = TraceInterface( __THISCLASS__, IClusCfgClusterInfoEx, this, 0 );
|
|
} // else if: IClusCfgClusterInfoEx
|
|
else
|
|
{
|
|
*ppvOut = NULL;
|
|
hr = E_NOINTERFACE;
|
|
} // else:
|
|
|
|
//
|
|
// Add a reference to the interface if successful.
|
|
//
|
|
|
|
if ( SUCCEEDED( hr ) )
|
|
{
|
|
((IUnknown *) *ppvOut)->AddRef();
|
|
} // if: success
|
|
|
|
Cleanup:
|
|
|
|
QIRETURN_IGNORESTDMARSHALLING( hr, riidIn );
|
|
|
|
} //*** CClusCfgClusterInfo::QueryInterface
|
|
|
|
|
|
//*************************************************************************//
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CClusCfgClusterInfo -- IClusCfgWbemServices interface.
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgClusterInfo::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
|
|
CClusCfgClusterInfo::SetWbemServices(
|
|
IWbemServices * pIWbemServicesIn
|
|
)
|
|
{
|
|
TraceFunc( "[IClusCfgWbemServices]" );
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
if ( pIWbemServicesIn == NULL )
|
|
{
|
|
hr = THR( E_POINTER );
|
|
STATUS_REPORT_REF( TASKID_Major_Establish_Connection, TASKID_Minor_SetWbemServices_Cluster, IDS_ERROR_NULL_POINTER, IDS_ERROR_NULL_POINTER_REF, hr );
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
m_pIWbemServices = pIWbemServicesIn;
|
|
m_pIWbemServices->AddRef();
|
|
|
|
Cleanup:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgClusterInfo::SetWbemServices
|
|
|
|
|
|
//*************************************************************************//
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CClusCfgClusterInfo -- IClusCfgInitialze interface.
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgClusterInfo::Initialize
|
|
//
|
|
// Description:
|
|
// Initialize this component.
|
|
//
|
|
// Arguments:
|
|
// IN IUknown * punkCallbackIn
|
|
//
|
|
// IN LCID lcidIn
|
|
//
|
|
// Return Value:
|
|
// S_OK
|
|
// Success
|
|
//
|
|
// Remarks:
|
|
// None.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CClusCfgClusterInfo::Initialize(
|
|
IUnknown * punkCallbackIn,
|
|
LCID lcidIn
|
|
)
|
|
{
|
|
TraceFunc( "[IClusCfgInitialize]" );
|
|
|
|
HRESULT hr = S_OK;
|
|
HRESULT hrTemp = S_OK;
|
|
HCLUSTER hCluster = NULL;
|
|
DWORD sc;
|
|
DWORD dwState;
|
|
BSTR bstrDomain = NULL;
|
|
BSTR bstrClusterName = NULL;
|
|
size_t cchName;
|
|
size_t cchClusterName;
|
|
size_t cchDomain;
|
|
|
|
m_lcid = lcidIn;
|
|
|
|
Assert( m_picccCallback == NULL );
|
|
|
|
if ( punkCallbackIn == NULL )
|
|
{
|
|
hr = THR( E_POINTER );
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
hr = THR( punkCallbackIn->TypeSafeQI( IClusCfgCallback, &m_picccCallback ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
if ( m_fIsClusterNode )
|
|
{
|
|
//
|
|
// 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, &dwState );
|
|
if ( sc == ERROR_SERVICE_DOES_NOT_EXIST )
|
|
{
|
|
LOG_STATUS_REPORT( L"CClusCfgClusterInfo::Initialize() GetNodeClusterState() determined that the cluster service does not exist.", hr );
|
|
}
|
|
else if ( sc != ERROR_SUCCESS )
|
|
{
|
|
hr = HRESULT_FROM_WIN32( TW32( sc ) );
|
|
LOG_STATUS_REPORT( L"CClusCfgClusterInfo::Initialize() GetNodeClusterState() failed.", hr );
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
Assert( ( dwState == ClusterStateRunning ) || ( dwState == ClusterStateNotRunning ) );
|
|
|
|
if ( dwState == ClusterStateNotRunning )
|
|
{
|
|
//
|
|
// Set hrTemp to S_FALSE so a warning is shown in the UI.
|
|
//
|
|
hrTemp = S_FALSE;
|
|
STATUS_REPORT_REF( TASKID_Major_Establish_Connection, TASKID_Minor_Node_Down, IDS_ERROR_NODE_DOWN, IDS_ERROR_NODE_DOWN_REF, hrTemp );
|
|
LogMsg( L"[SRV] The cluster service is down on this node." );
|
|
|
|
//
|
|
// Set hrTemp to HR_S_RPC_S_CLUSTER_NODE_DOWN so we can return this later.
|
|
//
|
|
hrTemp = HR_S_RPC_S_CLUSTER_NODE_DOWN;
|
|
goto ClusterNodeDown;
|
|
} // if:
|
|
|
|
hCluster = OpenCluster( NULL );
|
|
if ( hCluster == NULL )
|
|
{
|
|
sc = TW32( GetLastError() );
|
|
hr = HRESULT_FROM_WIN32( sc );
|
|
LOG_STATUS_REPORT( L"CClusCfgClusterInfo::Initialize() OpenCluster() failed.", hr );
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
hr = THR( HrGetClusterInformation( hCluster, &bstrClusterName, NULL ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
hr = THR( HrGetComputerName(
|
|
ComputerNamePhysicalDnsDomain
|
|
, &bstrDomain
|
|
, FALSE // fBestEffortIn
|
|
) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
cchClusterName = wcslen( bstrClusterName );
|
|
cchDomain = wcslen( bstrDomain );
|
|
|
|
cchName = cchClusterName + cchDomain + 2; // '.' + UNICODE_NULL
|
|
|
|
TraceSysFreeString( m_bstrName );
|
|
m_bstrName = TraceSysAllocStringLen( NULL, (UINT) cchName );
|
|
if ( m_bstrName == NULL )
|
|
{
|
|
hr = THR( E_OUTOFMEMORY );
|
|
STATUS_REPORT_REF( TASKID_Major_Establish_Connection, TASKID_Minor_Initialize, IDS_ERROR_OUTOFMEMORY, IDS_ERROR_OUTOFMEMORY_REF, hr );
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
hr = THR( StringCchCopyW( m_bstrName, cchName, bstrClusterName ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
hr = THR( StringCchCatW( m_bstrName, cchName, L"." ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
hr = THR( StringCchCatW( m_bstrName, cchName, bstrDomain ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
hr = THR( HrLoadNetworkInfo( hCluster ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
ClusterNodeDown:
|
|
|
|
hr = STHR( HrLoadCredentials() );
|
|
if ( SUCCEEDED( hr ) )
|
|
{
|
|
//
|
|
// If successful then use hrTemp since it may contain a more important status code.
|
|
//
|
|
hr = hrTemp;
|
|
LogMsg( L"[SRV] CClusCfgClusterInfo::Initialize() returning (hr=%#08x)", hr );
|
|
} // if:
|
|
} // if:
|
|
|
|
Cleanup:
|
|
|
|
TraceSysFreeString( bstrDomain );
|
|
TraceSysFreeString( bstrClusterName );
|
|
|
|
if ( hCluster != NULL )
|
|
{
|
|
CloseCluster( hCluster );
|
|
} // if:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgClusterInfo::Initialize
|
|
|
|
|
|
//*************************************************************************//
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CClusCfgClusterInfo -- IClusCfgClusterInfo interface.
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgClusterInfo::GetCommitMode
|
|
//
|
|
// Description:
|
|
// Get the mode of processing for this node when commit changes is
|
|
// called.
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Return Value:
|
|
// S_OK
|
|
// Success.
|
|
//
|
|
// E_POINTER
|
|
// pecmCurrentModeOut is NULL.
|
|
//
|
|
// Other Win32 error as HRESULT if a failure occurs.
|
|
//
|
|
// Remarks:
|
|
// None.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CClusCfgClusterInfo::GetCommitMode(
|
|
ECommitMode * pecmCurrentModeOut
|
|
)
|
|
{
|
|
TraceFunc( "[IClusCfgClusterInfo]" );
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
if ( pecmCurrentModeOut == NULL )
|
|
{
|
|
hr = THR( E_POINTER );
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
*pecmCurrentModeOut = m_ecmCommitChangesMode;
|
|
|
|
Cleanup:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgClusterInfo::GetCommitMode
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgClusterInfo::SetCommitMode
|
|
//
|
|
// Description:
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Return Value:
|
|
//
|
|
// Remarks:
|
|
// None.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CClusCfgClusterInfo::SetCommitMode(
|
|
ECommitMode ecmCurrentModeIn
|
|
)
|
|
{
|
|
TraceFunc( "[IClusCfgClusterInfo]" );
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
m_ecmCommitChangesMode = ecmCurrentModeIn;
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgClusterInfo::SetCommitMode
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgClusterInfo::GetName
|
|
//
|
|
// Description:
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Return Value:
|
|
//
|
|
// Remarks:
|
|
// None.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CClusCfgClusterInfo::GetName(
|
|
BSTR * pbstrNameOut
|
|
)
|
|
{
|
|
TraceFunc( "[IClusCfgClusterInfo]" );
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
if ( pbstrNameOut == NULL )
|
|
{
|
|
hr = THR( E_POINTER );
|
|
STATUS_REPORT_REF( TASKID_Major_Find_Devices, TASKID_Minor_ClusterInfo_GetName_Pointer, IDS_ERROR_NULL_POINTER, IDS_ERROR_NULL_POINTER_REF, hr );
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
if ( m_bstrName == NULL )
|
|
{
|
|
hr = HRESULT_FROM_WIN32( TW32( ERROR_NOT_FOUND ) );
|
|
STATUS_REPORT_REF(
|
|
TASKID_Major_Find_Devices
|
|
, TASKID_Minor_Get_Cluster_Name
|
|
, IDS_ERROR_CLUSTER_NAME_NOT_FOUND
|
|
, IDS_ERROR_CLUSTER_NAME_NOT_FOUND_REF
|
|
, hr
|
|
);
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
*pbstrNameOut = SysAllocString( m_bstrName );
|
|
if ( *pbstrNameOut == NULL )
|
|
{
|
|
hr = THR( E_OUTOFMEMORY );
|
|
STATUS_REPORT_REF( TASKID_Major_Find_Devices, TASKID_Minor_GetName_Memory, IDS_ERROR_OUTOFMEMORY, IDS_ERROR_OUTOFMEMORY_REF, hr );
|
|
} // if:
|
|
|
|
Cleanup:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgClusterInfo::GetName
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgClusterInfo::SetName
|
|
//
|
|
// Description:
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Return Value:
|
|
//
|
|
// Remarks:
|
|
// None.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CClusCfgClusterInfo::SetName(
|
|
LPCWSTR pcszNameIn
|
|
)
|
|
{
|
|
TraceFunc1( "[IClusCfgClusterInfo] pcszNameIn = '%ls'", pcszNameIn == NULL ? L"<null>" : pcszNameIn );
|
|
|
|
HRESULT hr;
|
|
|
|
if ( pcszNameIn == NULL )
|
|
{
|
|
hr = THR( E_INVALIDARG );
|
|
goto Cleanup;
|
|
}
|
|
|
|
TraceSysFreeString( m_bstrName );
|
|
m_bstrName = NULL;
|
|
|
|
m_bstrName = TraceSysAllocString( pcszNameIn );
|
|
if ( m_bstrName == NULL )
|
|
{
|
|
hr = THR( E_OUTOFMEMORY );
|
|
STATUS_REPORT_REF( TASKID_Major_Find_Devices, TASKID_Minor_SetName_Cluster, IDS_ERROR_OUTOFMEMORY, IDS_ERROR_OUTOFMEMORY_REF, hr );
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
hr = S_OK;
|
|
|
|
Cleanup:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgClusterInfo::SetName
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgClusterInfo::GetIPAddress
|
|
//
|
|
// Description:
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Return Value:
|
|
//
|
|
// Remarks:
|
|
// None.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CClusCfgClusterInfo::GetIPAddress(
|
|
ULONG * pulDottedQuadOut
|
|
)
|
|
{
|
|
TraceFunc( "[IClusCfgClusterInfo]" );
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
if ( pulDottedQuadOut == NULL )
|
|
{
|
|
hr = THR( E_POINTER );
|
|
STATUS_REPORT_REF( TASKID_Major_Find_Devices, TASKID_Minor_GetIPAddress, IDS_ERROR_NULL_POINTER, IDS_ERROR_NULL_POINTER_REF, hr );
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
if ( m_ulIPDottedQuad == 0 )
|
|
{
|
|
hr = HRESULT_FROM_WIN32( TW32( ERROR_NOT_FOUND ) );
|
|
STATUS_REPORT_REF(
|
|
TASKID_Major_Find_Devices
|
|
, TASKID_Minor_Get_Cluster_IP_Address
|
|
, IDS_ERROR_CLUSTER_IP_ADDRESS_NOT_FOUND
|
|
, IDS_ERROR_CLUSTER_IP_ADDRESS_NOT_FOUND_REF
|
|
, hr
|
|
);
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
*pulDottedQuadOut = m_ulIPDottedQuad;
|
|
|
|
Cleanup:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgClusterInfo::GetIPAddress
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgClusterInfo::SetIPAddress
|
|
//
|
|
// Description:
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Return Value:
|
|
//
|
|
// Remarks:
|
|
// None.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CClusCfgClusterInfo::SetIPAddress(
|
|
ULONG ulDottedQuadIn
|
|
)
|
|
{
|
|
TraceFunc( "[IClusCfgClusterInfo]" );
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
m_ulIPDottedQuad = ulDottedQuadIn;
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgClusterInfo::SetIPAddress
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgClusterInfo::GetSubnetMask
|
|
//
|
|
// Description:
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Return Value:
|
|
//
|
|
// Remarks:
|
|
// None.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CClusCfgClusterInfo::GetSubnetMask(
|
|
ULONG * pulDottedQuadOut
|
|
)
|
|
{
|
|
TraceFunc( "[IClusCfgClusterInfo]" );
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
if ( pulDottedQuadOut == NULL )
|
|
{
|
|
hr = THR( E_POINTER );
|
|
STATUS_REPORT_REF( TASKID_Major_Find_Devices, TASKID_Minor_ClusterInfo_GetSubnetMask, IDS_ERROR_NULL_POINTER, IDS_ERROR_NULL_POINTER_REF, hr );
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
if ( m_ulSubnetDottedQuad == 0 )
|
|
{
|
|
hr = HRESULT_FROM_WIN32( TW32( ERROR_NOT_FOUND ) );
|
|
STATUS_REPORT_REF(
|
|
TASKID_Major_Find_Devices
|
|
, TASKID_Minor_Get_Cluster_IP_Subnet
|
|
, IDS_ERROR_CLUSTER_IP_SUBNET_NOT_FOUND
|
|
, IDS_ERROR_CLUSTER_IP_SUBNET_NOT_FOUND_REF
|
|
, hr
|
|
);
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
*pulDottedQuadOut = m_ulSubnetDottedQuad;
|
|
|
|
Cleanup:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgClusterInfo::GetSubnetMask
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgClusterInfo::SetSubnetMask
|
|
//
|
|
// Description:
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Return Value:
|
|
//
|
|
// Remarks:
|
|
// None.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CClusCfgClusterInfo::SetSubnetMask(
|
|
ULONG ulDottedQuadIn
|
|
)
|
|
{
|
|
TraceFunc( "[IClusCfgClusterInfo]" );
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
m_ulSubnetDottedQuad = ulDottedQuadIn;
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgClusterInfo::SetSubnetMask
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgClusterInfo::GetNetworkInfo
|
|
//
|
|
// Description:
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Return Value:
|
|
//
|
|
// Remarks:
|
|
// None.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CClusCfgClusterInfo::GetNetworkInfo(
|
|
IClusCfgNetworkInfo ** ppiccniOut
|
|
)
|
|
{
|
|
TraceFunc( "[IClusCfgClusterInfo]" );
|
|
Assert( m_piccniNetwork != NULL );
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
if ( ppiccniOut == NULL )
|
|
{
|
|
hr = THR( E_POINTER );
|
|
STATUS_REPORT_REF( TASKID_Major_Find_Devices, TASKID_Minor_GetNetworkInfo, IDS_ERROR_NULL_POINTER, IDS_ERROR_NULL_POINTER_REF, hr );
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
if ( m_piccniNetwork == NULL )
|
|
{
|
|
hr = HRESULT_FROM_WIN32( TW32( ERROR_NOT_FOUND ) );
|
|
STATUS_REPORT_REF(
|
|
TASKID_Major_Find_Devices
|
|
, TASKID_Minor_Get_Cluster_Networks
|
|
, IDS_ERROR_CLUSTER_NETWORKS_NOT_FOUND
|
|
, IDS_ERROR_CLUSTER_NETWORKS_NOT_FOUND_REF
|
|
, hr
|
|
);
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
*ppiccniOut = TraceInterface( L"CClusCfgNetworkInfo", IClusCfgNetworkInfo, m_piccniNetwork, 0 );
|
|
(*ppiccniOut)->AddRef();
|
|
|
|
Cleanup:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgClusterInfo::GetNetworkInfo
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgClusterInfo::SetNetworkInfo
|
|
//
|
|
// Description:
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Return Value:
|
|
//
|
|
// Remarks:
|
|
// None.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CClusCfgClusterInfo::SetNetworkInfo(
|
|
IClusCfgNetworkInfo * piccniIn
|
|
)
|
|
{
|
|
TraceFunc( "[IClusCfgClusterInfo]" );
|
|
Assert( piccniIn != NULL );
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
if ( piccniIn == NULL )
|
|
{
|
|
hr = THR( E_INVALIDARG );
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
if ( m_piccniNetwork != NULL )
|
|
{
|
|
m_piccniNetwork->Release();
|
|
} // if:
|
|
|
|
m_piccniNetwork = piccniIn;
|
|
m_piccniNetwork->AddRef();
|
|
|
|
Cleanup:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgClusterInfo::SetNetworkInfo
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgClusterInfo::GetClusterServiceAccountCredentials
|
|
//
|
|
// Description:
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Return Value:
|
|
//
|
|
// Remarks:
|
|
// None.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CClusCfgClusterInfo::GetClusterServiceAccountCredentials(
|
|
IClusCfgCredentials ** ppicccCredentialsOut
|
|
)
|
|
{
|
|
TraceFunc( "[IClusCfgClusterInfo]" );
|
|
|
|
HRESULT hr;
|
|
|
|
if ( ppicccCredentialsOut == NULL )
|
|
{
|
|
hr = THR( E_POINTER );
|
|
STATUS_REPORT_REF( TASKID_Major_Find_Devices, TASKID_Minor_GetClusterServiceAccountCredentials, IDS_ERROR_NULL_POINTER, IDS_ERROR_NULL_POINTER_REF, hr );
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
if ( m_punkServiceAccountCredentials != NULL )
|
|
{
|
|
hr = S_OK;
|
|
LOG_STATUS_REPORT( L"CClusCfgClusterInfo::GetClusterServiceAccountCredentials() skipping object creation.", hr );
|
|
goto SkipCreate;
|
|
} // if:
|
|
|
|
hr = THR( HrCoCreateInternalInstance(
|
|
CLSID_ClusCfgCredentials
|
|
, NULL
|
|
, CLSCTX_INPROC_SERVER
|
|
, IID_IUnknown
|
|
, reinterpret_cast< void ** >( &m_punkServiceAccountCredentials )
|
|
) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
m_punkServiceAccountCredentials = TraceInterface( L"CClusCfgCredentials", IUnknown, m_punkServiceAccountCredentials, 1 );
|
|
|
|
hr = THR( HrSetInitialize( m_punkServiceAccountCredentials, m_picccCallback, m_lcid ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
hr = THR( HrSetWbemServices( m_punkServiceAccountCredentials, NULL ) );
|
|
|
|
SkipCreate:
|
|
|
|
if ( SUCCEEDED( hr ) )
|
|
{
|
|
Assert( m_punkServiceAccountCredentials != NULL );
|
|
hr = THR( m_punkServiceAccountCredentials->TypeSafeQI( IClusCfgCredentials, ppicccCredentialsOut ) );
|
|
} // if:
|
|
|
|
Cleanup:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgClusterInfo::GetClusterServiceAccountCredentials
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgClusterInfo::GetBindingString
|
|
//
|
|
// Description:
|
|
// Get the binding string for this cluster.
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Return Value:
|
|
//
|
|
// Remarks:
|
|
// None.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CClusCfgClusterInfo::GetBindingString(
|
|
BSTR * pbstrBindingStringOut
|
|
)
|
|
{
|
|
TraceFunc( "[IClusCfgClusterInfo]" );
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
if ( pbstrBindingStringOut == NULL )
|
|
{
|
|
hr = THR( E_POINTER );
|
|
STATUS_REPORT_REF( TASKID_Major_Find_Devices, TASKID_Minor_ClusterInfo_GetBindingString_Pointer, IDS_ERROR_NULL_POINTER, IDS_ERROR_NULL_POINTER_REF, hr );
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
if ( m_bstrBindingString == NULL )
|
|
{
|
|
hr = S_FALSE;
|
|
LOG_STATUS_REPORT_MINOR(
|
|
TASKID_Minor_GetBindingString_Binding_String_NULL
|
|
, L"The cluster binding string is empty. If we are adding nodes then this is not correct!"
|
|
, hr );
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
*pbstrBindingStringOut = SysAllocString( m_bstrBindingString );
|
|
if ( *pbstrBindingStringOut == NULL )
|
|
{
|
|
hr = THR( E_OUTOFMEMORY );
|
|
STATUS_REPORT_REF( TASKID_Major_Find_Devices, TASKID_Minor_GetBindingString_Memory, IDS_ERROR_OUTOFMEMORY, IDS_ERROR_OUTOFMEMORY_REF, hr );
|
|
} // if:
|
|
|
|
Cleanup:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgClusterInfo::GetBindingString
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgClusterInfo::SetBindingString
|
|
//
|
|
// Description:
|
|
// Set the binding string of this cluster.
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Return Value:
|
|
//
|
|
// Remarks:
|
|
// None.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CClusCfgClusterInfo::SetBindingString(
|
|
LPCWSTR pcszBindingStringIn
|
|
)
|
|
{
|
|
TraceFunc1( "[IClusCfgClusterInfo] pcszBindingStringIn = '%ls'", pcszBindingStringIn == NULL ? L"<null>" : pcszBindingStringIn );
|
|
|
|
HRESULT hr = S_OK;
|
|
BSTR bstr = NULL;
|
|
|
|
//
|
|
// When creating a cluster there is no cluster binding string. Therefore it is reasonable
|
|
// to accept a NULL string as the passed in parameter.
|
|
//
|
|
if ( pcszBindingStringIn == NULL )
|
|
{
|
|
hr = S_FALSE;
|
|
TraceSysFreeString( m_bstrBindingString );
|
|
m_bstrBindingString = NULL;
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
bstr = TraceSysAllocString( pcszBindingStringIn );
|
|
if ( bstr == NULL )
|
|
{
|
|
hr = THR( E_OUTOFMEMORY );
|
|
STATUS_REPORT_REF( TASKID_Major_Find_Devices, TASKID_Minor_SetBindingString_Cluster, IDS_ERROR_OUTOFMEMORY, IDS_ERROR_OUTOFMEMORY_REF, hr );
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
TraceSysFreeString( m_bstrBindingString );
|
|
m_bstrBindingString = bstr;
|
|
|
|
Cleanup:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgClusterInfo::SetBindingString
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgClusterInfo::GetMaxNodeCount
|
|
//
|
|
// Description:
|
|
// Get the maximum number of nodes supported in this cluster.
|
|
//
|
|
// Arguments:
|
|
// pcMaxNodesOut
|
|
//
|
|
// Return Value:
|
|
// S_OK
|
|
// Success;
|
|
//
|
|
// E_POINTER
|
|
// pcMaxNodesOut is NULL.
|
|
//
|
|
// Other HRESULT errors.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CClusCfgClusterInfo::GetMaxNodeCount(
|
|
DWORD * pcMaxNodesOut
|
|
)
|
|
{
|
|
TraceFunc( "[IClusCfgClusterInfo]" );
|
|
|
|
HRETURN( STHR( HrGetMaxNodeCount( pcMaxNodesOut ) ) );
|
|
|
|
} //*** CClusCfgClusterInfo::GetMaxNodeCount
|
|
|
|
|
|
//*************************************************************************//
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CClusCfgClusterInfo class -- IClusCfgSetClusterNodeInfo Interfaces.
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgClusterInfo::SetClusterNodeInfo
|
|
//
|
|
// Description:
|
|
// Suck some info off of the passed in node info object.
|
|
//
|
|
// Arguments:
|
|
// None.
|
|
//
|
|
// Return Value:
|
|
//
|
|
//
|
|
// Remarks:
|
|
// None.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CClusCfgClusterInfo::SetClusterNodeInfo(
|
|
IClusCfgNodeInfo * pNodeInfoIn
|
|
)
|
|
{
|
|
TraceFunc( "[IClusCfgClusterInfo]" );
|
|
Assert( pNodeInfoIn != NULL );
|
|
|
|
HRESULT hr = S_FALSE;
|
|
|
|
if ( pNodeInfoIn == NULL )
|
|
{
|
|
hr = THR( E_INVALIDARG );
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
hr = STHR( pNodeInfoIn->IsMemberOfCluster() );
|
|
if ( hr == S_OK )
|
|
{
|
|
m_fIsClusterNode = true;
|
|
} // if:
|
|
else if ( hr == S_FALSE )
|
|
{
|
|
m_fIsClusterNode = false;
|
|
hr = S_OK;
|
|
} // else if:
|
|
|
|
Cleanup:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgClusterInfo::SetClusterNodeInfo
|
|
|
|
|
|
//*************************************************************************//
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CClusCfgClusterInfo class -- IClusCfgClusterInfoEx Interfaces.
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgClusterInfo::CheckJoiningNodeVersion
|
|
//
|
|
// Description:
|
|
// Check a joining node's version information against that of the cluster.
|
|
//
|
|
// Arguments:
|
|
// dwNodeHighestVersionIn
|
|
// dwNodeLowestVersionIn
|
|
//
|
|
// Return Value:
|
|
// S_OK
|
|
// The joining node is compatible.
|
|
//
|
|
// HRESULT_FROM_WIN32( ERROR_CLUSTER_INCOMPATIBLE_VERSIONS )
|
|
// The joining node is NOT compatible.
|
|
//
|
|
// Other HRESULT errors.
|
|
//
|
|
// Remarks:
|
|
//
|
|
// Get and verify the sponsor version
|
|
//
|
|
//
|
|
// From Whistler onwards, CsRpcGetJoinVersionData() will return a failure code in its last parameter
|
|
// if the version of this node is not compatible with the sponsor version. Prior to this, the last
|
|
// parameter always contained a success value and the cluster versions had to be compared subsequent to this
|
|
// call. This will, however, still have to be done as long as interoperability with Win2K
|
|
// is a requirement, since Win2K sponsors do not return an error in the last parameter.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CClusCfgClusterInfo::CheckJoiningNodeVersion(
|
|
DWORD dwNodeHighestVersionIn
|
|
, DWORD dwNodeLowestVersionIn
|
|
)
|
|
{
|
|
TraceFunc( "[IClusCfgClusterInfoEx]" );
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
hr = THR( HrCheckJoiningNodeVersion(
|
|
NULL
|
|
, dwNodeHighestVersionIn
|
|
, dwNodeLowestVersionIn
|
|
, m_picccCallback
|
|
) );
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgClusterInfo::CheckJoiningNodeVersion
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgClusterInfo::GetNodeNames
|
|
//
|
|
// Description:
|
|
// Retrieve the names of the nodes currently in the cluster.
|
|
//
|
|
// Parameters:
|
|
// pnCountOut
|
|
// On success, *pnCountOut returns the number of nodes in the cluster.
|
|
//
|
|
// prgbstrNodeNamesOut
|
|
// On success, an array of BSTRs containing the node names.
|
|
// The caller must free each BSTR with SysFreeString, and free
|
|
// the array with CoTaskMemFree.
|
|
//
|
|
// Return Values:
|
|
// S_OK
|
|
// The out parameters contain valid information and the caller
|
|
// must free the array and the BSTRs it contains.
|
|
//
|
|
// E_OUTOFMEMORY, and other failures are possible.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CClusCfgClusterInfo::GetNodeNames(
|
|
long * pnCountOut
|
|
, BSTR ** prgbstrNodeNamesOut
|
|
)
|
|
{
|
|
TraceFunc( "[IClusCfgClusterInfoEx]" );
|
|
|
|
HRESULT hr = S_OK;
|
|
HCLUSTER hCluster = NULL;
|
|
|
|
hCluster = OpenCluster( NULL );
|
|
if ( hCluster == NULL )
|
|
{
|
|
DWORD scLastError = TW32( GetLastError() );
|
|
hr = HRESULT_FROM_WIN32( scLastError );
|
|
goto Cleanup;
|
|
} // if
|
|
|
|
hr = THR( HrGetNodeNames(
|
|
hCluster
|
|
, pnCountOut
|
|
, prgbstrNodeNamesOut
|
|
) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
Cleanup:
|
|
|
|
if ( hCluster != NULL )
|
|
{
|
|
CloseCluster( hCluster );
|
|
} // if
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgClusterInfo::GetNodeNames
|
|
|
|
|
|
|
|
//*************************************************************************//
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CClusCfgClusterInfo class -- Private Methods.
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgClusterInfo::HrInit
|
|
//
|
|
// Description:
|
|
// Initialize this component.
|
|
//
|
|
// Arguments:
|
|
// None.
|
|
//
|
|
// Return Value:
|
|
//
|
|
//
|
|
// Remarks:
|
|
// None.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
HRESULT
|
|
CClusCfgClusterInfo::HrInit( void )
|
|
{
|
|
TraceFunc( "" );
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
// IUnknown
|
|
Assert( m_cRef == 1 );
|
|
|
|
m_bstrName = TraceSysAllocString( L"\0" );
|
|
if ( m_bstrName == NULL )
|
|
{
|
|
hr = THR( E_OUTOFMEMORY );
|
|
STATUS_REPORT_REF( TASKID_Major_Find_Devices, TASKID_Minor_HrInit, IDS_ERROR_OUTOFMEMORY, IDS_ERROR_OUTOFMEMORY_REF, hr );
|
|
} // if:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgClusterInfo::HrInit
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgClusterInfo::HrLoadNetworkInfo
|
|
//
|
|
// Description:
|
|
// Load the cluster network info...
|
|
//
|
|
// Arguments:
|
|
//
|
|
//
|
|
// Return Value:
|
|
//
|
|
//
|
|
// Remarks:
|
|
// None.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
HRESULT
|
|
CClusCfgClusterInfo::HrLoadNetworkInfo(
|
|
HCLUSTER hClusterIn
|
|
)
|
|
{
|
|
TraceFunc( "" );
|
|
Assert( hClusterIn != NULL );
|
|
|
|
HRESULT hr = S_OK;
|
|
DWORD sc;
|
|
HRESOURCE hIPAddress = NULL;
|
|
|
|
sc = TW32( ResUtilGetCoreClusterResources( hClusterIn, NULL, &hIPAddress, NULL ) );
|
|
if ( sc != ERROR_SUCCESS )
|
|
{
|
|
hr = HRESULT_FROM_WIN32( sc );
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
Assert( hIPAddress != NULL );
|
|
|
|
hr = THR( HrGetIPAddressInfo( hIPAddress ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
Cleanup:
|
|
|
|
LOG_STATUS_REPORT_MINOR( TASKID_Minor_Server_LoadNetwork_Info, L"LoadNetworkInfo() completed.", hr );
|
|
|
|
if ( hIPAddress != NULL )
|
|
{
|
|
CloseClusterResource( hIPAddress );
|
|
} // if:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgClusterInfo::HrLoadNetworkInfo
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgClusterInfo::HrGetIPAddressInfo
|
|
//
|
|
// Description:
|
|
//
|
|
//
|
|
// Arguments:
|
|
//
|
|
//
|
|
// Return Value:
|
|
//
|
|
//
|
|
// Remarks:
|
|
// None.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
HRESULT
|
|
CClusCfgClusterInfo::HrGetIPAddressInfo(
|
|
HCLUSTER hClusterIn,
|
|
HRESOURCE hResIn
|
|
)
|
|
{
|
|
TraceFunc( "" );
|
|
Assert( hClusterIn != NULL );
|
|
Assert( hResIn != NULL );
|
|
|
|
HRESULT hr = S_FALSE;
|
|
DWORD sc;
|
|
HRESENUM hEnum = NULL;
|
|
DWORD idx;
|
|
WCHAR * psz = NULL;
|
|
DWORD cchpsz = 33;
|
|
DWORD dwType;
|
|
HRESOURCE hRes = NULL;
|
|
|
|
hEnum = ClusterResourceOpenEnum( hResIn, CLUSTER_RESOURCE_ENUM_DEPENDS );
|
|
if ( hEnum == NULL )
|
|
{
|
|
sc = TW32( GetLastError() );
|
|
hr = HRESULT_FROM_WIN32( sc );
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
psz = new WCHAR [ cchpsz ];
|
|
if ( psz == NULL )
|
|
{
|
|
goto OutOfMemory;
|
|
} // if:
|
|
|
|
for ( idx = 0; ; )
|
|
{
|
|
sc = TW32( ClusterResourceEnum( hEnum, idx, &dwType, psz, &cchpsz ) );
|
|
if ( sc == ERROR_NO_MORE_ITEMS )
|
|
{
|
|
break;
|
|
} // if:
|
|
|
|
if ( sc == ERROR_MORE_DATA )
|
|
{
|
|
delete [] psz;
|
|
psz = NULL;
|
|
|
|
cchpsz++;
|
|
|
|
psz = new WCHAR [ cchpsz ];
|
|
if ( psz == NULL )
|
|
{
|
|
goto OutOfMemory;
|
|
} // if:
|
|
|
|
continue;
|
|
} // if:
|
|
|
|
if ( sc == ERROR_SUCCESS )
|
|
{
|
|
hRes = OpenClusterResource( hClusterIn, psz );
|
|
if ( hRes == NULL )
|
|
{
|
|
sc = TW32( GetLastError() );
|
|
hr = HRESULT_FROM_WIN32( sc );
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
hr = STHR( HrIsResourceOfType( hRes, L"IP Address" ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
if ( hr == S_OK )
|
|
{
|
|
hr = THR( HrGetIPAddressInfo( hRes ) ); // not recursive!
|
|
break;
|
|
} // if:
|
|
|
|
CloseClusterResource( hRes );
|
|
hRes = NULL;
|
|
|
|
idx++;
|
|
continue;
|
|
} // if:
|
|
|
|
hr = THR( HRESULT_FROM_WIN32( sc ) ); // must be an error!
|
|
goto Cleanup;
|
|
} // for:
|
|
|
|
goto Cleanup;
|
|
|
|
OutOfMemory:
|
|
|
|
hr = THR( E_OUTOFMEMORY );
|
|
STATUS_REPORT_REF( TASKID_Major_Find_Devices, TASKID_Minor_HrGetIPAddressInfo, IDS_ERROR_OUTOFMEMORY, IDS_ERROR_OUTOFMEMORY_REF, hr );
|
|
|
|
Cleanup:
|
|
|
|
LOG_STATUS_REPORT_MINOR( TASKID_Minor_Server_Get_ClusterIPAddress_Info_2, L"GetIPAddressInfo() completed.", hr );
|
|
|
|
delete [] psz;
|
|
|
|
if ( hRes != NULL )
|
|
{
|
|
CloseClusterResource( hRes );
|
|
} // if:
|
|
|
|
if ( hEnum != NULL )
|
|
{
|
|
ClusterResourceCloseEnum( hEnum );
|
|
} // if:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgClusterInfo::HrGetIPAddressInfo
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgClusterInfo::HrGetIPAddressInfo
|
|
//
|
|
// Description:
|
|
//
|
|
//
|
|
// Arguments:
|
|
//
|
|
//
|
|
// Return Value:
|
|
//
|
|
//
|
|
// Remarks:
|
|
// None.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
HRESULT
|
|
CClusCfgClusterInfo::HrGetIPAddressInfo(
|
|
HRESOURCE hResIn
|
|
)
|
|
{
|
|
TraceFunc( "" );
|
|
Assert( hResIn != NULL );
|
|
|
|
HRESULT hr = S_OK;
|
|
DWORD sc;
|
|
ULONG ulNetwork;
|
|
WCHAR * psz = NULL;
|
|
BSTR bstrNetworkName = NULL;
|
|
|
|
hr = THR( ::HrGetIPAddressInfo( hResIn, &m_ulIPDottedQuad, &m_ulSubnetDottedQuad, &bstrNetworkName ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
LOG_STATUS_REPORT_MINOR( TASKID_Minor_Server_Get_IPAddressResource_Info, L"Could not get the IP address info.", hr );
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
sc = TW32( ClRtlTcpipAddressToString( m_ulIPDottedQuad, &psz ) ); // KB: Allocates to psz using LocalAlloc().
|
|
if ( sc != ERROR_SUCCESS )
|
|
{
|
|
hr = HRESULT_FROM_WIN32( sc );
|
|
LOG_STATUS_REPORT_MINOR( TASKID_Minor_Server_Convert_ClusterIPAddress_To_String, L"Could not convert the Cluster IP address to a string.", hr );
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
m_bstrBindingString = TraceSysAllocString( psz );
|
|
if ( m_bstrBindingString == NULL )
|
|
{
|
|
hr = THR( E_OUTOFMEMORY );
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
LocalFree( psz );
|
|
psz = NULL;
|
|
|
|
LOG_STATUS_REPORT_STRING( L"Cluster binding string is '%1!ws!'.", m_bstrBindingString, hr );
|
|
|
|
ulNetwork = m_ulIPDottedQuad & m_ulSubnetDottedQuad;
|
|
|
|
sc = TW32( ClRtlTcpipAddressToString( ulNetwork, &psz ) ); // KB: Allocates to psz using LocalAlloc().
|
|
if ( sc != ERROR_SUCCESS )
|
|
{
|
|
hr = HRESULT_FROM_WIN32( sc );
|
|
LOG_STATUS_REPORT_MINOR( TASKID_Minor_Server_Convert_Network_To_String, L"Could not convert the network address to a string.", hr );
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
hr = THR( HrFindNetworkInfo( bstrNetworkName, psz ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
LOG_STATUS_REPORT_STRING_MINOR2( TASKID_Minor_Server_Find_Network, L"Could not find network %1!ws! with address %2!ws!.", bstrNetworkName, psz, hr );
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
Cleanup:
|
|
|
|
LOG_STATUS_REPORT_MINOR( TASKID_Minor_Server_Get_ClusterIPAddress_Info, L"GetIPAddressInfo() completed.", hr );
|
|
|
|
LocalFree( psz ); // KB: Don't use TraceFree() here! PREFAST may complain but their complaint is bogus.
|
|
|
|
TraceSysFreeString( bstrNetworkName );
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgClusterInfo::HrGetIPAddressInfo
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgClusterInfo::HrFindNetworkInfo
|
|
//
|
|
// Description:
|
|
//
|
|
//
|
|
// Arguments:
|
|
//
|
|
//
|
|
// Return Value:
|
|
//
|
|
//
|
|
// Remarks:
|
|
// None.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
HRESULT
|
|
CClusCfgClusterInfo::HrFindNetworkInfo(
|
|
const WCHAR * pszNetworkNameIn,
|
|
const WCHAR * pszNetworkIn
|
|
)
|
|
{
|
|
TraceFunc( "" );
|
|
Assert( pszNetworkNameIn != NULL );
|
|
Assert( pszNetworkIn != NULL );
|
|
|
|
HRESULT hr;
|
|
IUnknown * punk = NULL;
|
|
IEnumClusCfgNetworks * pieccn = NULL;
|
|
ULONG cFetched;
|
|
IClusCfgNetworkInfo * piccni = NULL;
|
|
BSTR bstrNetworkName = NULL;
|
|
BSTR bstrNetwork = NULL;
|
|
|
|
hr = THR( HrCreateNetworksEnum( m_picccCallback, m_lcid, m_pIWbemServices, &punk ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
hr = THR( punk->TypeSafeQI( IEnumClusCfgNetworks, &pieccn ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
for ( ; ; )
|
|
{
|
|
hr = pieccn->Next( 1, &piccni, &cFetched );
|
|
if ( ( hr == S_OK ) && ( cFetched == 1 ) )
|
|
{
|
|
hr = THR( piccni->GetName( &bstrNetworkName ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
TraceMemoryAddBSTR( bstrNetworkName );
|
|
|
|
hr = THR( piccni->GetUID( &bstrNetwork ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
TraceMemoryAddBSTR( bstrNetwork );
|
|
|
|
if ( ( wcscmp( pszNetworkNameIn, bstrNetworkName ) == 0 ) && ( ClRtlStrICmp( pszNetworkIn, bstrNetwork ) == 0 ) )
|
|
{
|
|
if ( m_piccniNetwork != NULL )
|
|
{
|
|
m_piccniNetwork->Release();
|
|
m_piccniNetwork = NULL;
|
|
} // if:
|
|
|
|
m_piccniNetwork = piccni;
|
|
m_piccniNetwork->AddRef();
|
|
|
|
break;
|
|
} // if:
|
|
|
|
piccni->Release();
|
|
piccni = NULL;
|
|
|
|
TraceSysFreeString( bstrNetworkName );
|
|
bstrNetworkName = NULL;
|
|
|
|
TraceSysFreeString( bstrNetwork );
|
|
bstrNetwork = NULL;
|
|
} // if:
|
|
else if ( ( hr == S_FALSE ) && ( cFetched == 0 ) )
|
|
{
|
|
hr = S_OK;
|
|
break;
|
|
} // else if:
|
|
else
|
|
{
|
|
goto Cleanup;
|
|
} // else:
|
|
} // for:
|
|
|
|
//
|
|
// If we didn't find the cluster network in the WMI list of networks then we have a problem.
|
|
//
|
|
|
|
Assert( m_piccniNetwork != NULL );
|
|
if ( m_piccniNetwork == NULL )
|
|
{
|
|
hr = THR( ERROR_NETWORK_NOT_AVAILABLE );
|
|
STATUS_REPORT_STRING_REF(
|
|
TASKID_Major_Find_Devices
|
|
, TASKID_Minor_Cluster_Network_Not_Found
|
|
, IDS_ERROR_CLUSTER_NETWORK_NOT_FOUND
|
|
, pszNetworkIn
|
|
, IDS_ERROR_CLUSTER_NETWORK_NOT_FOUND_REF
|
|
, hr
|
|
);
|
|
} // if:
|
|
|
|
Cleanup:
|
|
|
|
if ( piccni != NULL )
|
|
{
|
|
piccni->Release();
|
|
} // if:
|
|
|
|
if ( pieccn != NULL )
|
|
{
|
|
pieccn->Release();
|
|
} // if:
|
|
|
|
if ( punk != NULL )
|
|
{
|
|
punk->Release();
|
|
} // if:
|
|
|
|
TraceSysFreeString( bstrNetworkName );
|
|
TraceSysFreeString( bstrNetwork );
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgClusterInfo::HrFindNetworkInfo
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgClusterInfo::HrLoadCredentials
|
|
//
|
|
// Description:
|
|
//
|
|
//
|
|
// Arguments:
|
|
// None.
|
|
//
|
|
// Return Value:
|
|
// S_OK - Operation completed successfully.
|
|
// S_FALSE - Nothing was done (cluster service doesn't exist).
|
|
// Other HRESULTs.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
HRESULT
|
|
CClusCfgClusterInfo::HrLoadCredentials( void )
|
|
{
|
|
TraceFunc( "" );
|
|
|
|
HRESULT hr = S_OK;
|
|
SC_HANDLE schSCM = NULL;
|
|
SC_HANDLE schClusSvc = NULL;
|
|
DWORD sc;
|
|
DWORD cbRequired;
|
|
QUERY_SERVICE_CONFIG * pqsc = NULL;
|
|
DWORD cbqsc = 128;
|
|
IClusCfgCredentials * piccc = NULL;
|
|
IClusCfgSetCredentials * piccsc = NULL;
|
|
|
|
schSCM = OpenSCManager( NULL, NULL, GENERIC_READ );
|
|
if ( schSCM == NULL )
|
|
{
|
|
sc = TW32( GetLastError() );
|
|
goto Win32Error;
|
|
} // if:
|
|
|
|
schClusSvc = OpenService( schSCM, L"ClusSvc", GENERIC_READ );
|
|
if ( schClusSvc == NULL )
|
|
{
|
|
sc = GetLastError();
|
|
if ( sc == ERROR_SERVICE_DOES_NOT_EXIST )
|
|
{
|
|
hr = S_FALSE;
|
|
LogMsg( "[SRV] CClusCfgClusterInfo::HrLoadCredentials() - The cluster service does not exist." );
|
|
goto Cleanup;
|
|
}
|
|
|
|
TW32( sc );
|
|
goto Win32Error;
|
|
} // if:
|
|
|
|
for ( ; ; )
|
|
{
|
|
pqsc = (QUERY_SERVICE_CONFIG *) TraceAlloc( 0, cbqsc );
|
|
if ( pqsc == NULL )
|
|
{
|
|
hr = THR( E_OUTOFMEMORY );
|
|
STATUS_REPORT_REF( TASKID_Major_Find_Devices, TASKID_Minor_HrLoadCredentials, IDS_ERROR_OUTOFMEMORY, IDS_ERROR_OUTOFMEMORY_REF, hr );
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
if ( !QueryServiceConfig( schClusSvc, pqsc, cbqsc, &cbRequired ) )
|
|
{
|
|
sc = GetLastError();
|
|
if ( sc == ERROR_INSUFFICIENT_BUFFER )
|
|
{
|
|
TraceFree( pqsc );
|
|
pqsc = NULL;
|
|
cbqsc = cbRequired;
|
|
continue;
|
|
} // if:
|
|
else
|
|
{
|
|
TW32( sc );
|
|
goto Win32Error;
|
|
} // else:
|
|
} // if:
|
|
else
|
|
{
|
|
break;
|
|
} // else:
|
|
} // for:
|
|
|
|
Assert( m_punkServiceAccountCredentials == NULL );
|
|
|
|
hr = THR( GetClusterServiceAccountCredentials( &piccc ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
hr = THR( piccc->TypeSafeQI( IClusCfgSetCredentials, &piccsc ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
hr = THR( piccsc->SetDomainCredentials( pqsc->lpServiceStartName ) );
|
|
|
|
goto Cleanup;
|
|
|
|
Win32Error:
|
|
|
|
hr = HRESULT_FROM_WIN32( sc );
|
|
|
|
Cleanup:
|
|
|
|
if ( schClusSvc != NULL )
|
|
{
|
|
CloseServiceHandle( schClusSvc );
|
|
} // if:
|
|
|
|
if ( schSCM != NULL )
|
|
{
|
|
CloseServiceHandle( schSCM );
|
|
} // if:
|
|
|
|
if ( pqsc != NULL )
|
|
{
|
|
TraceFree( pqsc );
|
|
} // if:
|
|
|
|
if ( piccc != NULL )
|
|
{
|
|
piccc->Release();
|
|
} // if:
|
|
|
|
if ( piccsc != NULL )
|
|
{
|
|
piccsc->Release();
|
|
} // if:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgClusterInfo::HrLoadCredentials
|