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.
3856 lines
94 KiB
3856 lines
94 KiB
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Copyright (c) 1999-2002 Microsoft Corporation
|
|
//
|
|
// Module Name:
|
|
// ClusCfg.cpp
|
|
//
|
|
// Description:
|
|
// Implementation of CClusCfgWizard class.
|
|
//
|
|
// Maintained By:
|
|
// David Potter (DavidP) 14-MAR-2001
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// Include Files
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "Pch.h"
|
|
#include "TaskTreeView.h"
|
|
#include "AnalyzePage.h"
|
|
#include "ClusDomainPage.h"
|
|
#include "CommitPage.h"
|
|
#include "CompletionPage.h"
|
|
#include "CSAccountPage.h"
|
|
#include "IPAddressPage.h"
|
|
#include "SelNodePage.h"
|
|
#include "SelNodesPage.h"
|
|
#include "WelcomePage.h"
|
|
#include "SummaryPage.h"
|
|
#include <initguid.h>
|
|
|
|
|
|
//****************************************************************************
|
|
//
|
|
// CClusCfgWizard
|
|
//
|
|
//****************************************************************************
|
|
|
|
DEFINE_THISCLASS( "CClusCfgWizard" )
|
|
|
|
// {AAA8DA17-62C8-40f6-BEC1-3F0326B73388}
|
|
DEFINE_GUID( CLSID_CancelCleanupTaskCompletionCookieType,
|
|
0xaaa8da17, 0x62c8, 0x40f6, 0xbe, 0xc1, 0x3f, 0x3, 0x26, 0xb7, 0x33, 0x88 );
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgWizard::S_HrCreateInstance
|
|
//
|
|
// Description:
|
|
// Create a CClusCfgWizard instance.
|
|
//
|
|
// Arguments:
|
|
// ppccwOut
|
|
//
|
|
// Return Values:
|
|
// S_OK - Operation completed successfully.
|
|
// E_OUTOFMEMORY - Error allocating memory.
|
|
// Other HRESULTs.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
HRESULT
|
|
CClusCfgWizard::S_HrCreateInstance(
|
|
CClusCfgWizard ** ppccwOut
|
|
)
|
|
{
|
|
TraceFunc( "" );
|
|
|
|
HRESULT hr = S_OK;
|
|
CClusCfgWizard * pccw = NULL;
|
|
|
|
Assert( ppccwOut != NULL );
|
|
if ( ppccwOut == NULL )
|
|
{
|
|
hr = THR( E_POINTER );
|
|
goto Cleanup;
|
|
}
|
|
*ppccwOut = NULL;
|
|
|
|
pccw = new CClusCfgWizard();
|
|
if ( pccw == NULL )
|
|
{
|
|
hr = THR( E_OUTOFMEMORY );
|
|
goto Cleanup;
|
|
}
|
|
|
|
hr = THR( pccw->HrInit() );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
|
|
*ppccwOut = pccw;
|
|
pccw = NULL;
|
|
|
|
|
|
Cleanup:
|
|
|
|
if ( pccw != NULL )
|
|
{
|
|
pccw->Release();
|
|
}
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgWizard::S_HrCreateInstance
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgWizard::CClusCfgWizard
|
|
//
|
|
// Description:
|
|
// Default constructor.
|
|
//
|
|
// Arguments:
|
|
// None.
|
|
//
|
|
// Return Values:
|
|
// None.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
CClusCfgWizard::CClusCfgWizard( void )
|
|
: m_cRef( 1 )
|
|
, m_pccc( NULL )
|
|
, m_psp( NULL )
|
|
, m_pcpc( NULL )
|
|
, m_pom( NULL )
|
|
, m_ptm( NULL )
|
|
, m_bstrClusterDomain( NULL )
|
|
, m_fDefaultedDomain( TRUE )
|
|
, m_dwCookieNotify( 0 )
|
|
, m_hCancelCleanupEvent( NULL )
|
|
{
|
|
TraceFunc( "" );
|
|
|
|
TraceFuncExit();
|
|
|
|
} //*** CClusCfgWizard::CClusCfgWizard
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgWizard::~CClusCfgWizard
|
|
//
|
|
// Description:
|
|
// Destructor.
|
|
//
|
|
// Arguments:
|
|
// None.
|
|
//
|
|
// Return Values:
|
|
// None.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
CClusCfgWizard::~CClusCfgWizard( void )
|
|
{
|
|
TraceFunc( "" );
|
|
|
|
TraceSysFreeString( m_bstrNetworkName );
|
|
TraceSysFreeString( m_bstrClusterDomain );
|
|
|
|
if ( m_psp != NULL )
|
|
{
|
|
m_psp->Release();
|
|
} // if:
|
|
|
|
if ( m_pcpc != NULL )
|
|
{
|
|
m_pcpc->Release();
|
|
} // if:
|
|
|
|
if ( m_ptm != NULL )
|
|
{
|
|
m_ptm->Release();
|
|
} // if:
|
|
|
|
if ( m_pom != NULL )
|
|
{
|
|
m_pom->Release();
|
|
} // if:
|
|
|
|
if ( m_pccc != NULL )
|
|
{
|
|
m_pccc->Release();
|
|
} // if:
|
|
|
|
if ( m_hRichEdit != NULL )
|
|
{
|
|
FreeLibrary( m_hRichEdit );
|
|
} // if:
|
|
|
|
if ( m_hCancelCleanupEvent != NULL )
|
|
{
|
|
CloseHandle( m_hCancelCleanupEvent );
|
|
} // if:
|
|
|
|
TraceFuncExit();
|
|
|
|
} // ~CClusCfgWizard
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgWizard::HrInit
|
|
//
|
|
// Description:
|
|
// Initialize a CClusCfgWizard instance.
|
|
//
|
|
// Arguments:
|
|
// None.
|
|
//
|
|
// Return Values:
|
|
// S_OK - Operation completed successfully.
|
|
// Other HRESULTs.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
HRESULT
|
|
CClusCfgWizard::HrInit( void )
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
TraceFunc( "" );
|
|
|
|
INITCOMMONCONTROLSEX icex;
|
|
BOOL bRet;
|
|
// EConfigurationSettings ecsConfigType = csFullConfig;
|
|
|
|
// IUnknown
|
|
Assert( m_cRef == 1 );
|
|
|
|
Assert( m_ulIPAddress == 0 );
|
|
Assert( m_ulIPSubnet == 0 );
|
|
Assert( m_bstrNetworkName == NULL );
|
|
Assert( m_psp == NULL );
|
|
Assert( m_pcpc == NULL );
|
|
Assert( m_pom == NULL );
|
|
Assert( m_ptm == NULL );
|
|
Assert( m_pccc == NULL );
|
|
Assert( m_cookieCompletion == 0 );
|
|
Assert( m_fMinimalConfig == FALSE );
|
|
|
|
icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
|
|
icex.dwICC = ICC_INTERNET_CLASSES
|
|
| ICC_PROGRESS_CLASS
|
|
| ICC_TREEVIEW_CLASSES
|
|
| ICC_LISTVIEW_CLASSES;
|
|
bRet = InitCommonControlsEx( &icex );
|
|
Assert( bRet != FALSE );
|
|
|
|
hr = THR( CoCreateInstance(
|
|
CLSID_ServiceManager
|
|
, NULL
|
|
, CLSCTX_INPROC_SERVER
|
|
, IID_IServiceProvider
|
|
, reinterpret_cast< void ** >( &m_psp )
|
|
) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
|
|
hr = THR( m_psp->TypeSafeQS( CLSID_ObjectManager, IObjectManager, &m_pom ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
|
|
hr = THR( m_psp->TypeSafeQS( CLSID_TaskManager, ITaskManager, &m_ptm ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
|
|
hr = THR( m_psp->TypeSafeQS( CLSID_NotificationManager, IConnectionPointContainer, &m_pcpc ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
|
|
hr = THR( HrCoCreateInternalInstance(
|
|
CLSID_ClusCfgCredentials
|
|
, NULL
|
|
, CLSCTX_INPROC_SERVER
|
|
, IID_IClusCfgCredentials
|
|
, reinterpret_cast< void ** >( &m_pccc )
|
|
) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
|
|
//
|
|
// Initialize the RichEdit controls.
|
|
//
|
|
|
|
m_hRichEdit = LoadLibrary( L"RichEd32.Dll" );
|
|
if ( m_hRichEdit == NULL )
|
|
{
|
|
hr = HRESULT_FROM_WIN32( TW32( GetLastError() ) );
|
|
goto Cleanup;
|
|
}
|
|
|
|
m_hCancelCleanupEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
|
|
if ( m_hCancelCleanupEvent == NULL )
|
|
{
|
|
hr = HRESULT_FROM_WIN32( TW32( GetLastError() ) );
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
// STHR( HrReadSettings( &ecsConfigType ) );
|
|
|
|
// m_fMinimalConfig = ( ecsConfigType == csMinConfig );
|
|
|
|
Cleanup:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgWizard::HrInit
|
|
|
|
|
|
//****************************************************************************
|
|
//
|
|
// IUnknown
|
|
//
|
|
//****************************************************************************
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgWizard::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
|
|
CClusCfgWizard::QueryInterface(
|
|
REFIID riidIn
|
|
, PVOID * 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< IUnknown * >( this );
|
|
} // if: IUnknown
|
|
else if ( IsEqualIID( riidIn, IID_INotifyUI ) )
|
|
{
|
|
*ppvOut = TraceInterface( __THISCLASS__, INotifyUI, this, 0 );
|
|
} // else if: INotifyUI
|
|
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 );
|
|
|
|
} //*** CClusCfgWizard::QueryInterface
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgWizard::AddRef
|
|
//
|
|
// Description:
|
|
// Add a reference to this instance.
|
|
//
|
|
// Arguments:
|
|
// None.
|
|
//
|
|
// Return Values:
|
|
// New reference count.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP_( ULONG )
|
|
CClusCfgWizard::AddRef( void )
|
|
{
|
|
TraceFunc( "[IUnknown]" );
|
|
|
|
InterlockedIncrement( &m_cRef );
|
|
|
|
CRETURN( m_cRef );
|
|
|
|
} //*** CClusCfgWizard::AddRef
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgWizard::Release
|
|
//
|
|
// Description:
|
|
// Release a reference to this instance. If it is the last reference
|
|
// the object instance will be deallocated.
|
|
//
|
|
// Arguments:
|
|
// None.
|
|
//
|
|
// Return Values:
|
|
// New reference count.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP_( ULONG )
|
|
CClusCfgWizard::Release( void )
|
|
{
|
|
TraceFunc( "[IUnknown]" );
|
|
|
|
LONG cRef;
|
|
|
|
cRef = InterlockedDecrement( &m_cRef );
|
|
|
|
if ( cRef == 0 )
|
|
{
|
|
delete this;
|
|
}
|
|
|
|
CRETURN( cRef );
|
|
|
|
} //*** CClusCfgWizard::Release
|
|
|
|
|
|
//****************************************************************************
|
|
//
|
|
// IClusCfgWizard
|
|
//
|
|
//****************************************************************************
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgWizard::CreateCluster
|
|
//
|
|
// Description:
|
|
//
|
|
// Arguments:
|
|
// ParentWnd
|
|
// pfDone
|
|
//
|
|
// Return Values:
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CClusCfgWizard::CreateCluster(
|
|
HWND lParentWndIn,
|
|
BOOL * pfDoneOut
|
|
)
|
|
{
|
|
TraceFunc( "[IClusCfgWizard]" );
|
|
|
|
HPROPSHEETPAGE rPages[ 9 ];
|
|
PROPSHEETHEADER pshead;
|
|
BOOL fSuccess;
|
|
INT_PTR ipStatus;
|
|
HRESULT hr = S_OK;
|
|
ILogManager * plm = NULL;
|
|
TraceFlow1( "[Clcfgsrv] - CClusCfgWizard::CreateCluster - Thread id %d", GetCurrentThreadId() );
|
|
|
|
CWelcomePage dlgWelcomePage( this, camCREATING );
|
|
CClusDomainPage dlgClusDomainPage( this, camCREATING, IDS_DOMAIN_DESC_CREATE );
|
|
CSelNodePage dlgSelNodePage( this );
|
|
CAnalyzePage dlgAnalyzePage( this, camCREATING );
|
|
CIPAddressPage dlgIPAddressPage( this, camCREATING, &m_ulIPAddress, &m_ulIPSubnet, &m_bstrNetworkName );
|
|
CCSAccountPage dlgCSAccountPage( this, camCREATING, m_pccc );
|
|
CSummaryPage dlgSummaryPage( this, camCREATING, IDS_SUMMARY_NEXT_CREATE );
|
|
CCommitPage dlgCommitPage( this, camCREATING );
|
|
CCompletionPage dlgCompletionPage( IDS_COMPLETION_TITLE_CREATE, IDS_COMPLETION_DESC_CREATE );
|
|
|
|
//
|
|
// TODO: gpease 14-MAY-2000
|
|
// Do we really need this?
|
|
//
|
|
if ( pfDoneOut == NULL )
|
|
{
|
|
hr = THR( E_POINTER );
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
//
|
|
// Start the logger.
|
|
//
|
|
hr = THR( m_psp->TypeSafeQS( CLSID_LogManager,
|
|
ILogManager,
|
|
&plm
|
|
) );
|
|
if ( FAILED( hr ) )
|
|
goto Cleanup;
|
|
|
|
hr = THR( plm->StartLogging() );
|
|
if ( FAILED( hr ) )
|
|
goto Cleanup;
|
|
|
|
//
|
|
// Register to get UI notification (if needed)
|
|
//
|
|
|
|
if ( m_dwCookieNotify == 0 )
|
|
{
|
|
hr = THR( HrAdvise( IID_INotifyUI, static_cast< INotifyUI * >( this ), &m_dwCookieNotify ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
} // if:
|
|
} // if:
|
|
|
|
//
|
|
// Create the Wizard.
|
|
//
|
|
ZeroMemory( &pshead, sizeof( pshead ) );
|
|
pshead.dwSize = sizeof( pshead );
|
|
pshead.dwFlags = PSH_WIZARD97 | PSH_WATERMARK | PSH_HEADER;
|
|
pshead.hInstance = g_hInstance;
|
|
pshead.pszCaption = MAKEINTRESOURCE( IDS_TITLE_FORM );
|
|
pshead.phpage = rPages;
|
|
pshead.pszbmWatermark = MAKEINTRESOURCE( IDB_WATERMARK );
|
|
pshead.pszbmHeader = MAKEINTRESOURCE( IDB_BANNER );
|
|
pshead.hwndParent = lParentWndIn;
|
|
|
|
THR( HrAddWizardPage( &pshead, IDD_WELCOME_CREATE, CWelcomePage::S_DlgProc, 0, 0, (LPARAM) &dlgWelcomePage ) );
|
|
THR( HrAddWizardPage( &pshead, IDD_CLUSDOMAIN, CClusDomainPage::S_DlgProc, IDS_TCLUSTER, IDS_STCLUSTER_CREATE, (LPARAM) &dlgClusDomainPage ) );
|
|
THR( HrAddWizardPage( &pshead, IDD_SELNODE, CSelNodePage::S_DlgProc, IDS_TSELNODE, IDS_STSELNODE, (LPARAM) &dlgSelNodePage ) );
|
|
THR( HrAddWizardPage( &pshead, IDD_ANALYZE, CAnalyzePage::S_DlgProc, IDS_TANALYZE, IDS_STANALYZE, (LPARAM) &dlgAnalyzePage ) );
|
|
THR( HrAddWizardPage( &pshead, IDD_IPADDRESS, CIPAddressPage::S_DlgProc, IDS_TIPADDRESS, IDS_STIPADDRESS, (LPARAM) &dlgIPAddressPage ) );
|
|
THR( HrAddWizardPage( &pshead, IDD_CSACCOUNT, CCSAccountPage::S_DlgProc, IDS_TCSACCOUNT, IDS_STCSACCOUNT, (LPARAM) &dlgCSAccountPage ) );
|
|
THR( HrAddWizardPage( &pshead, IDD_SUMMARY, CSummaryPage::S_DlgProc, IDS_TSUMMARY, IDS_STSUMMARY_CREATE, (LPARAM) &dlgSummaryPage ) );
|
|
THR( HrAddWizardPage( &pshead, IDD_COMMIT, CCommitPage::S_DlgProc, IDS_TCOMMIT_CREATE, IDS_STCOMMIT, (LPARAM) &dlgCommitPage ) );
|
|
THR( HrAddWizardPage( &pshead, IDD_COMPLETION, CCompletionPage::S_DlgProc, 0, 0, (LPARAM) &dlgCompletionPage ) );
|
|
|
|
AssertMsg( pshead.nPages == ARRAYSIZE( rPages ), "Not enough or too many PROPSHEETPAGEs." );
|
|
|
|
ipStatus = PropertySheet( &pshead );
|
|
if ( ipStatus == -1 )
|
|
{
|
|
TW32( GetLastError() );
|
|
}
|
|
fSuccess = ipStatus != NULL;
|
|
if ( pfDoneOut != NULL )
|
|
{
|
|
*pfDoneOut = fSuccess;
|
|
}
|
|
|
|
Cleanup:
|
|
|
|
if ( plm != NULL )
|
|
{
|
|
THR( plm->StopLogging() );
|
|
plm->Release();
|
|
} // if:
|
|
|
|
if ( m_dwCookieNotify != 0 )
|
|
{
|
|
THR( HrUnadvise( IID_INotifyUI, m_dwCookieNotify ) );
|
|
m_dwCookieNotify = 0;
|
|
} // if:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgWizard::CreateCluster
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgWizard::AddClusterNodes
|
|
//
|
|
// Description:
|
|
// Launch the Cluster Wizard in Add Cluster Nodes mode.
|
|
//
|
|
// Parameters
|
|
// ParentWnd - Handle to the parent window (default NULL).
|
|
// If not NULL, the wizard will be positionned
|
|
// in the center of this window.
|
|
// Done - return TRUE if committed, FALSE if cancelled.
|
|
//
|
|
// Return Values:
|
|
// S_OK - The call succeeded.
|
|
// other HRESULTs - The call failed.
|
|
// E_POINTER
|
|
// E_OUTOFMEMORY
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CClusCfgWizard::AddClusterNodes(
|
|
HWND lParentWndIn,
|
|
BOOL * pfDoneOut
|
|
)
|
|
{
|
|
TraceFunc( "[IClusCfgWizard]" );
|
|
|
|
HPROPSHEETPAGE rPages[ 8 ];
|
|
PROPSHEETHEADER pshead;
|
|
|
|
BOOL fSuccess;
|
|
INT_PTR ipStatus;
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
ILogManager * plm = NULL;
|
|
|
|
CWelcomePage dlgWelcomePage( this, camADDING );
|
|
CClusDomainPage dlgClusDomainPage( this, camADDING, IDS_DOMAIN_DESC_ADD );
|
|
CSelNodesPage dlgSelNodesPage( this );
|
|
CAnalyzePage dlgAnalyzePage( this, camADDING );
|
|
CCSAccountPage dlgCSAccountPage( this, camADDING, m_pccc );
|
|
CSummaryPage dlgSummaryPage( this, camADDING, IDS_SUMMARY_NEXT_ADD );
|
|
CCommitPage dlgCommitPage( this, camADDING );
|
|
CCompletionPage dlgCompletionPage( IDS_COMPLETION_TITLE_ADD, IDS_COMPLETION_DESC_ADD );
|
|
|
|
//
|
|
// TODO: gpease 12-JUL-2000
|
|
// Do we really need this? Or can we have the script implement an event
|
|
// sink that we signal?
|
|
//
|
|
if ( pfDoneOut == NULL )
|
|
{
|
|
hr = THR( E_POINTER );
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
//
|
|
// Start the logger.
|
|
//
|
|
hr = THR( m_psp->TypeSafeQS( CLSID_LogManager,
|
|
ILogManager,
|
|
&plm
|
|
) );
|
|
if ( FAILED( hr ) )
|
|
goto Cleanup;
|
|
|
|
hr = THR( plm->StartLogging() );
|
|
if ( FAILED( hr ) )
|
|
goto Cleanup;
|
|
|
|
//
|
|
// Register to get UI notification (if needed)
|
|
//
|
|
|
|
if ( m_dwCookieNotify == 0 )
|
|
{
|
|
hr = THR( HrAdvise( IID_INotifyUI, static_cast< INotifyUI * >( this ), &m_dwCookieNotify ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
} // if:
|
|
} // if:
|
|
|
|
//
|
|
// Create the Wizard.
|
|
//
|
|
ZeroMemory( &pshead, sizeof(pshead) );
|
|
pshead.dwSize = sizeof(pshead);
|
|
pshead.dwFlags = PSH_WIZARD97 | PSH_WATERMARK | PSH_HEADER;
|
|
pshead.hInstance = g_hInstance;
|
|
pshead.pszCaption = MAKEINTRESOURCE( IDS_TITLE_JOIN );
|
|
pshead.phpage = rPages;
|
|
pshead.pszbmWatermark = MAKEINTRESOURCE( IDB_WATERMARK );
|
|
pshead.pszbmHeader = MAKEINTRESOURCE( IDB_BANNER );
|
|
pshead.hwndParent = lParentWndIn;
|
|
|
|
THR( HrAddWizardPage( &pshead, IDD_WELCOME_ADD, CWelcomePage::S_DlgProc, 0, 0, (LPARAM) &dlgWelcomePage ) );
|
|
THR( HrAddWizardPage( &pshead, IDD_CLUSDOMAIN, CClusDomainPage::S_DlgProc, IDS_TCLUSTER, IDS_STCLUSTER_ADD, (LPARAM) &dlgClusDomainPage ) );
|
|
THR( HrAddWizardPage( &pshead, IDD_SELNODES, CSelNodesPage::S_DlgProc, IDS_TSELNODES, IDS_STSELNODES, (LPARAM) &dlgSelNodesPage ) );
|
|
THR( HrAddWizardPage( &pshead, IDD_ANALYZE, CAnalyzePage::S_DlgProc, IDS_TANALYZE, IDS_STANALYZE, (LPARAM) &dlgAnalyzePage ) );
|
|
THR( HrAddWizardPage( &pshead, IDD_CSACCOUNT, CCSAccountPage::S_DlgProc, IDS_TCSACCOUNT, IDS_STCSACCOUNT, (LPARAM) &dlgCSAccountPage ) );
|
|
THR( HrAddWizardPage( &pshead, IDD_SUMMARY, CSummaryPage::S_DlgProc, IDS_TSUMMARY, IDS_STSUMMARY_ADD, (LPARAM) &dlgSummaryPage ) );
|
|
THR( HrAddWizardPage( &pshead, IDD_COMMIT, CCommitPage::S_DlgProc, IDS_TCOMMIT_ADD, IDS_STCOMMIT, (LPARAM) &dlgCommitPage ) );
|
|
THR( HrAddWizardPage( &pshead, IDD_COMPLETION, CCompletionPage::S_DlgProc, 0, 0, (LPARAM) &dlgCompletionPage ) );
|
|
|
|
AssertMsg( pshead.nPages == ARRAYSIZE( rPages ), "Not enough or too many PROPSHEETPAGEs." );
|
|
|
|
ipStatus = PropertySheet( &pshead );
|
|
fSuccess = ipStatus != NULL;
|
|
if ( pfDoneOut != NULL )
|
|
{
|
|
*pfDoneOut = fSuccess;
|
|
}
|
|
|
|
Cleanup:
|
|
|
|
if ( plm != NULL )
|
|
{
|
|
THR( plm->StopLogging() );
|
|
plm->Release();
|
|
} // if:
|
|
|
|
if ( m_dwCookieNotify != 0 )
|
|
{
|
|
THR( HrUnadvise( IID_INotifyUI, m_dwCookieNotify ) );
|
|
m_dwCookieNotify = 0;
|
|
} // if:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgWizard::AddClusterNodes
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgWizard::get_ClusterName
|
|
//
|
|
// Description:
|
|
//
|
|
// Arguments:
|
|
// pbstrNameOut
|
|
//
|
|
// Return Values:
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CClusCfgWizard::get_ClusterName(
|
|
BSTR * pbstrNameOut
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
TraceFunc( "[IClusCfgWizard]" );
|
|
|
|
if ( pbstrNameOut == NULL )
|
|
{
|
|
hr = THR( E_POINTER );
|
|
goto Cleanup;
|
|
}
|
|
|
|
if ( m_ncCluster.bstrName == NULL )
|
|
{
|
|
hr = S_FALSE;
|
|
*pbstrNameOut = NULL;
|
|
goto Cleanup;
|
|
}
|
|
|
|
// Return either an IP address or an FQDN.
|
|
hr = STHR( HrIsValidFQN( m_ncCluster.bstrName, true ) );
|
|
if ( hr == S_OK ) // Name is fully-qualified.
|
|
{
|
|
HRESULT hrFQIPTest = STHR( HrFQNIsFQIP( m_ncCluster.bstrName ) );
|
|
if ( hrFQIPTest == S_OK ) // Name is an FQIP.
|
|
{
|
|
// If the name is an FQIP, return just the IP address.
|
|
hr = HrExtractPrefixFromFQN( m_ncCluster.bstrName, pbstrNameOut );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
TraceMemoryDelete( *pbstrNameOut, false ); // Prevent false reports of memory leaks.
|
|
} // If name is FQIP.
|
|
else if ( hrFQIPTest == S_FALSE ) // Name is an FQDN.
|
|
{
|
|
// Otherwise, the name is an FQDN, so return the whole thing.
|
|
*pbstrNameOut = SysAllocString( m_ncCluster.bstrName );
|
|
if ( *pbstrNameOut == NULL )
|
|
{
|
|
hr = THR( E_OUTOFMEMORY );
|
|
goto Cleanup;
|
|
}
|
|
} // If name is FQDN.
|
|
else if ( FAILED( hrFQIPTest ) )
|
|
{
|
|
hr = hrFQIPTest;
|
|
goto Cleanup;
|
|
}
|
|
} // If name is fully-qualified.
|
|
else if ( hr == S_FALSE ) // Name is not fully-qualified.
|
|
{
|
|
HRESULT hrIPTest = STHR( HrIsValidIPAddress( m_ncCluster.bstrName ) );
|
|
if ( hrIPTest == S_OK )
|
|
{
|
|
// If the name is an IP address, return it.
|
|
*pbstrNameOut = SysAllocString( m_ncCluster.bstrName );
|
|
if ( *pbstrNameOut == NULL )
|
|
{
|
|
hr = THR( E_OUTOFMEMORY );
|
|
goto Cleanup;
|
|
}
|
|
} // If name is an IP address.
|
|
else if ( hrIPTest == S_FALSE ) // Name is hostname label.
|
|
{
|
|
// Otherwise, append the cluster domain and return the result.
|
|
hr = THR( HrMakeFQN( m_ncCluster.bstrName, m_bstrClusterDomain, true, pbstrNameOut ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
TraceMemoryDelete( *pbstrNameOut, false ); // Prevent false reports of memory leaks.
|
|
} // If name is hostname label.
|
|
else if ( FAILED( hrIPTest ) )
|
|
{
|
|
hr = hrIPTest;
|
|
goto Cleanup;
|
|
}
|
|
} // If name is not fully-qualified.
|
|
else if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
|
|
Cleanup:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgWizard::get_ClusterName
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgWizard::put_ClusterName
|
|
//
|
|
// Description:
|
|
//
|
|
// Arguments:
|
|
// bstrNameIn
|
|
//
|
|
// Return Values:
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CClusCfgWizard::put_ClusterName(
|
|
BSTR bstrNameIn
|
|
)
|
|
{
|
|
TraceFunc1( "[IClusCfgWizard] bstrNameIn = %'ls'", bstrNameIn == NULL ? L"<null>" : bstrNameIn );
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
if ( bstrNameIn == NULL )
|
|
{
|
|
hr = THR( E_INVALIDARG );
|
|
goto Cleanup;
|
|
}
|
|
|
|
hr = THR( HrSetClusterName( bstrNameIn, true ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
|
|
Cleanup:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgWizard::put_ClusterName
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgWizard::get_ServiceAccountUserName
|
|
//
|
|
// Description:
|
|
//
|
|
// Arguments:
|
|
// pbstrNameOut
|
|
//
|
|
// Return Values:
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CClusCfgWizard::get_ServiceAccountUserName(
|
|
BSTR * pbstrNameOut
|
|
)
|
|
{
|
|
TraceFunc( "[IClusCfgWizard]" );
|
|
|
|
HRESULT hr = S_OK;
|
|
BSTR bstrDomain = NULL;
|
|
|
|
if ( pbstrNameOut == NULL )
|
|
{
|
|
hr = THR( E_POINTER );
|
|
goto Cleanup;
|
|
}
|
|
|
|
hr = THR( m_pccc->GetIdentity( pbstrNameOut, &bstrDomain ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
|
|
if ( SysStringLen( *pbstrNameOut ) == 0 )
|
|
{
|
|
hr = S_FALSE;
|
|
}
|
|
|
|
Cleanup:
|
|
|
|
SysFreeString( bstrDomain );
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgWizard::get_ServiceAccountUserName
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgWizard::put_ServiceAccountUserName
|
|
//
|
|
// Description:
|
|
//
|
|
// Arguments:
|
|
// bstrNameIn
|
|
//
|
|
// Return Values:
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CClusCfgWizard::put_ServiceAccountUserName(
|
|
BSTR bstrNameIn
|
|
)
|
|
{
|
|
TraceFunc1( "[IClusCfgWizard] bstrNameIn = '%ls'", bstrNameIn == NULL ? L"<null>" : bstrNameIn );
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
hr = THR( m_pccc->SetCredentials( bstrNameIn, NULL, NULL ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
|
|
Cleanup:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgWizard::put_ServiceAccountUserName
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgWizard::put_ServiceAccountPassword
|
|
//
|
|
// Description:
|
|
//
|
|
// Arguments:
|
|
// bstrPasswordIn
|
|
//
|
|
// Return Values:
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CClusCfgWizard::put_ServiceAccountPassword(
|
|
BSTR bstrPasswordIn
|
|
)
|
|
{
|
|
TraceFunc( "[IClusCfgWizard]" );
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
hr = THR( m_pccc->SetCredentials( NULL, NULL, bstrPasswordIn ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
|
|
Cleanup:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgWizard::put_ServiceAccountPassword
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgWizard::get_ServiceAccountDomainName
|
|
//
|
|
// Description:
|
|
//
|
|
// Arguments:
|
|
// pbstrDomainOut
|
|
//
|
|
// Return Values:
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CClusCfgWizard::get_ServiceAccountDomainName(
|
|
BSTR * pbstrDomainOut
|
|
)
|
|
{
|
|
TraceFunc( "[IClusCfgWizard]" );
|
|
|
|
HRESULT hr = S_OK;
|
|
BSTR bstrName = NULL;
|
|
|
|
if ( pbstrDomainOut == NULL )
|
|
{
|
|
hr = THR( E_POINTER );
|
|
goto Cleanup;
|
|
}
|
|
|
|
hr = THR( m_pccc->GetIdentity( &bstrName, pbstrDomainOut ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
|
|
if ( SysStringLen( *pbstrDomainOut ) == 0 )
|
|
{
|
|
hr = S_FALSE;
|
|
}
|
|
|
|
Cleanup:
|
|
|
|
SysFreeString( bstrName );
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgWizard::get_ServiceAccountDomainName
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgWizard::put_ServiceAccountDomainName
|
|
//
|
|
// Description:
|
|
//
|
|
// Arguments:
|
|
// bstrDomainIn
|
|
//
|
|
// Return Values:
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CClusCfgWizard::put_ServiceAccountDomainName(
|
|
BSTR bstrDomainIn
|
|
)
|
|
{
|
|
TraceFunc1( "[IClusCfgWizard] bstrDomainIn = '%ls'", bstrDomainIn == NULL ? L"<null>" : bstrDomainIn );
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
hr = THR( m_pccc->SetCredentials( NULL, bstrDomainIn, NULL ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
|
|
Cleanup:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgWizard::put_ServiceAccountDomainName
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgWizard::get_ClusterIPAddress
|
|
//
|
|
// Description:
|
|
//
|
|
// Arguments:
|
|
// pbstrIPAddressOut
|
|
//
|
|
// Return Values:
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CClusCfgWizard::get_ClusterIPAddress(
|
|
BSTR * pbstrIPAddressOut
|
|
)
|
|
{
|
|
TraceFunc( "[IClusCfgWizard]" );
|
|
|
|
HRESULT hr = S_OK;
|
|
DWORD dwStatus;
|
|
LPWSTR pwszIPAddress = NULL;
|
|
|
|
if ( pbstrIPAddressOut == NULL )
|
|
{
|
|
hr = THR( E_POINTER );
|
|
goto Cleanup;
|
|
}
|
|
|
|
if ( m_ulIPAddress == 0 )
|
|
{
|
|
hr = S_FALSE;
|
|
*pbstrIPAddressOut = NULL;
|
|
goto Cleanup;
|
|
}
|
|
|
|
dwStatus = TW32( ClRtlTcpipAddressToString( m_ulIPAddress, &pwszIPAddress ) );
|
|
if ( dwStatus != ERROR_SUCCESS )
|
|
{
|
|
hr = HRESULT_FROM_WIN32( dwStatus );
|
|
goto Cleanup;
|
|
}
|
|
|
|
*pbstrIPAddressOut = SysAllocString( pwszIPAddress );
|
|
if ( *pbstrIPAddressOut == NULL )
|
|
{
|
|
hr = THR( E_OUTOFMEMORY );
|
|
goto Cleanup;
|
|
}
|
|
|
|
Cleanup:
|
|
|
|
if ( pwszIPAddress != NULL )
|
|
{
|
|
LocalFree( pwszIPAddress );
|
|
}
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgWizard::get_ClusterIPAddress
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgWizard::put_ClusterIPAddress
|
|
//
|
|
// Description:
|
|
//
|
|
// Arguments:
|
|
// bstrIPAddressIn
|
|
//
|
|
// Return Values:
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CClusCfgWizard::put_ClusterIPAddress(
|
|
BSTR bstrIPAddressIn
|
|
)
|
|
{
|
|
TraceFunc1( "[IClusCfgWizard] bstrIPAddressIn = '%ls'", bstrIPAddressIn == NULL ? L"<null>" : bstrIPAddressIn );
|
|
|
|
HRESULT hr = S_OK;
|
|
DWORD dwStatus;
|
|
|
|
if ( bstrIPAddressIn == NULL )
|
|
{
|
|
hr = THR( E_INVALIDARG );
|
|
goto Cleanup;
|
|
}
|
|
|
|
dwStatus = TW32( ClRtlTcpipStringToAddress( bstrIPAddressIn, &m_ulIPAddress ) );
|
|
if ( dwStatus != ERROR_SUCCESS )
|
|
{
|
|
hr = HRESULT_FROM_WIN32( dwStatus );
|
|
goto Cleanup;
|
|
}
|
|
|
|
Cleanup:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgWizard::put_ClusterIPAddress
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgWizard::get_ClusterIPSubnet
|
|
//
|
|
// Description:
|
|
//
|
|
// Arguments:
|
|
// pbstrIPSubnetOut
|
|
//
|
|
// Return Values:
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CClusCfgWizard::get_ClusterIPSubnet(
|
|
BSTR * pbstrIPSubnetOut
|
|
)
|
|
{
|
|
TraceFunc( "[IClusCfgWizard]" );
|
|
|
|
HRESULT hr = S_OK;
|
|
DWORD dwStatus = ERROR_SUCCESS;
|
|
LPWSTR pwszIPSubnet = NULL;
|
|
|
|
if ( pbstrIPSubnetOut == NULL )
|
|
{
|
|
hr = THR( E_POINTER );
|
|
goto Cleanup;
|
|
}
|
|
*pbstrIPSubnetOut = NULL;
|
|
|
|
if ( m_ulIPSubnet == 0 )
|
|
{
|
|
hr = S_FALSE;
|
|
goto Cleanup;
|
|
}
|
|
|
|
dwStatus = TW32( ClRtlTcpipAddressToString( m_ulIPSubnet, &pwszIPSubnet ) );
|
|
if ( dwStatus != ERROR_SUCCESS )
|
|
{
|
|
hr = HRESULT_FROM_WIN32( dwStatus );
|
|
goto Cleanup;
|
|
}
|
|
|
|
*pbstrIPSubnetOut = SysAllocString( pwszIPSubnet );
|
|
if ( *pbstrIPSubnetOut == NULL )
|
|
{
|
|
hr = THR( E_OUTOFMEMORY );
|
|
goto Cleanup;
|
|
}
|
|
|
|
Cleanup:
|
|
|
|
if ( pwszIPSubnet != NULL )
|
|
{
|
|
LocalFree( pwszIPSubnet );
|
|
}
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgWizard::get_ClusterIPSubnet
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgWizard::put_ClusterIPSubnet
|
|
//
|
|
// Description:
|
|
//
|
|
// Arguments:
|
|
// bstrSubnetMaskIn
|
|
//
|
|
// Return Values:
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CClusCfgWizard::put_ClusterIPSubnet(
|
|
BSTR bstrIPSubnetIn
|
|
)
|
|
{
|
|
TraceFunc1( "[IClusCfgWizard] bstrIPSubnetIn = '%ls'", bstrIPSubnetIn );
|
|
|
|
HRESULT hr = S_OK;
|
|
DWORD dwStatus;
|
|
|
|
if ( bstrIPSubnetIn == NULL )
|
|
{
|
|
hr = THR( E_INVALIDARG );
|
|
goto Cleanup;
|
|
}
|
|
|
|
dwStatus = TW32( ClRtlTcpipStringToAddress( bstrIPSubnetIn, &m_ulIPSubnet ) );
|
|
if ( dwStatus != ERROR_SUCCESS )
|
|
{
|
|
hr = HRESULT_FROM_WIN32( dwStatus );
|
|
goto Cleanup;
|
|
}
|
|
|
|
Cleanup:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgWizard::put_ClusterIPSubnet
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgWizard::get_ClusterIPAddressNetwork
|
|
//
|
|
// Description:
|
|
//
|
|
// Arguments:
|
|
// pbstrNetworkNameOut
|
|
//
|
|
// Return Values:
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CClusCfgWizard::get_ClusterIPAddressNetwork(
|
|
BSTR * pbstrNetworkNameOut
|
|
)
|
|
{
|
|
TraceFunc( "[IClusCfgWizard]" );
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
if ( pbstrNetworkNameOut == NULL )
|
|
{
|
|
hr = THR( E_POINTER );
|
|
goto Cleanup;
|
|
}
|
|
*pbstrNetworkNameOut = NULL;
|
|
|
|
if ( m_bstrNetworkName == NULL )
|
|
{
|
|
hr = S_FALSE;
|
|
goto Cleanup;
|
|
}
|
|
|
|
*pbstrNetworkNameOut = SysAllocString( m_bstrNetworkName );
|
|
if ( *pbstrNetworkNameOut == NULL )
|
|
{
|
|
hr = THR( E_OUTOFMEMORY );
|
|
goto Cleanup;
|
|
}
|
|
|
|
Cleanup:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgWizard::get_ClusterIPAddressNetwork
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgWizard::put_ClusterIPAddressNetwork
|
|
//
|
|
// Description:
|
|
//
|
|
// Arguments:
|
|
// bstrNetworkNameIn
|
|
//
|
|
// Return Values:
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CClusCfgWizard::put_ClusterIPAddressNetwork(
|
|
BSTR bstrNetworkNameIn
|
|
)
|
|
{
|
|
TraceFunc1( "[IClusCfgWizard] bstrNetworkNameIn = '%ls'", bstrNetworkNameIn == NULL ? L"<null>" : bstrNetworkNameIn );
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
BSTR bstrNewNetworkName;
|
|
|
|
if ( bstrNetworkNameIn == NULL )
|
|
{
|
|
hr = THR( E_INVALIDARG );
|
|
goto Cleanup;
|
|
}
|
|
|
|
bstrNewNetworkName = TraceSysAllocString( bstrNetworkNameIn );
|
|
if ( bstrNewNetworkName == NULL )
|
|
{
|
|
hr = THR( E_OUTOFMEMORY );
|
|
goto Cleanup;
|
|
}
|
|
|
|
if ( m_bstrNetworkName != NULL )
|
|
{
|
|
TraceSysFreeString( m_bstrNetworkName );
|
|
}
|
|
|
|
m_bstrNetworkName = bstrNewNetworkName;
|
|
|
|
Cleanup:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgWizard::put_ClusterIPAddressNetwork
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgWizard::get_MinimumConfiguration
|
|
//
|
|
// Description:
|
|
//
|
|
// Arguments:
|
|
// pfMinimumConfigurationOut
|
|
//
|
|
// Return Values:
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CClusCfgWizard::get_MinimumConfiguration(
|
|
BOOL * pfMinimumConfigurationOut
|
|
)
|
|
{
|
|
TraceFunc( "" );
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
if ( pfMinimumConfigurationOut == NULL )
|
|
{
|
|
hr = THR( E_POINTER );
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
*pfMinimumConfigurationOut = m_fMinimalConfig;
|
|
|
|
Cleanup:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgWizard::get_MinimumConfiguration
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgWizard::put_MinimumConfiguration
|
|
//
|
|
// Description:
|
|
//
|
|
// Arguments:
|
|
// fMinimumConfigurationIn
|
|
//
|
|
// Return Values:
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CClusCfgWizard::put_MinimumConfiguration(
|
|
BOOL fMinimumConfigurationIn
|
|
)
|
|
{
|
|
TraceFunc1( "[IClusCfgWizard] fMinimalConfigurationIn = '%ls'", fMinimumConfigurationIn ? L"TRUE" : L"FALSE" );
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
m_fMinimalConfig = fMinimumConfigurationIn;
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgWizard::put_MinimumConfiguration
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgWizard::AddComputer
|
|
//
|
|
// Description:
|
|
//
|
|
// Arguments:
|
|
// bstrNameIn
|
|
//
|
|
// Return Values:
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CClusCfgWizard::AddComputer(
|
|
BSTR bstrNameIn
|
|
)
|
|
{
|
|
TraceFunc1( "[IClusCfgWizard] pcszNameIn = '%ls'", bstrNameIn == NULL ? L"<null>" : bstrNameIn );
|
|
|
|
HRESULT hr = S_OK;
|
|
if ( bstrNameIn == NULL )
|
|
{
|
|
hr = THR( E_POINTER );
|
|
goto Cleanup;
|
|
}
|
|
|
|
hr = THR( HrAddNode( bstrNameIn, true ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
|
|
Cleanup:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgWizard::AddComputer
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgWizard::RemoveComputer
|
|
//
|
|
// Description:
|
|
//
|
|
// Arguments:
|
|
// pcszNameIn
|
|
//
|
|
// Return Values:
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CClusCfgWizard::RemoveComputer(
|
|
BSTR bstrNameIn
|
|
)
|
|
{
|
|
TraceFunc1( "[IClusCfgWizard] pcszNameIn = '%ls'", bstrNameIn == NULL ? L"<null>" : bstrNameIn );
|
|
|
|
HRESULT hr = S_FALSE;
|
|
|
|
NamedCookieArray::Iterator itNode = m_ncaNodes.ItBegin();
|
|
|
|
if ( bstrNameIn == NULL )
|
|
{
|
|
hr = THR( E_POINTER );
|
|
goto Cleanup;
|
|
}
|
|
|
|
// Look for a node that has the same name.
|
|
while ( ( itNode != m_ncaNodes.ItEnd() ) && ( NBSTRCompareNoCase( ( *itNode ).bstrName, bstrNameIn ) != 0 ) )
|
|
{
|
|
++itNode;
|
|
}
|
|
|
|
// If a node with the same name exists, remove it.
|
|
if ( itNode != m_ncaNodes.ItEnd() )
|
|
{
|
|
if ( ( *itNode ).FHasCookie() )
|
|
{
|
|
THR( m_pom->RemoveObject( ( *itNode ).ocObject ) );
|
|
}
|
|
hr = THR( m_ncaNodes.HrRemove( itNode ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
}
|
|
else // No node has the same name.
|
|
{
|
|
hr = S_FALSE;
|
|
}
|
|
|
|
Cleanup:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgWizard::RemoveComputer
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgWizard::ClearComputerList
|
|
//
|
|
// Description:
|
|
//
|
|
// Arguments:
|
|
// None.
|
|
//
|
|
// Return Values:
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CClusCfgWizard::ClearComputerList( void )
|
|
{
|
|
TraceFunc( "[IClusCfgWizard]" );
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
hr = THR( HrReleaseNodeObjects() );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
|
|
m_ncaNodes.Clear();
|
|
|
|
Cleanup:
|
|
|
|
HRETURN( hr );
|
|
} //*** CClusCfgWizard::ClearComputerList
|
|
|
|
|
|
|
|
//****************************************************************************
|
|
//
|
|
// Private
|
|
//
|
|
//****************************************************************************
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgWizard::HrAddWizardPage
|
|
//
|
|
// Description:
|
|
// Fills in the PROPSHEETPAGE structure, create the page and adds it to
|
|
// the wizard's PROPSHEETHEADER.
|
|
//
|
|
// Arguments:
|
|
// ppshInout
|
|
// LPPROPSHEETHEADER structure to add page to.
|
|
//
|
|
// idTemplateIn
|
|
// The dialog template ID of the page.
|
|
//
|
|
// pfnDlgProcIn
|
|
// The dialog proc for the page.
|
|
//
|
|
// idCaptionIn
|
|
// The page's caption.
|
|
//
|
|
// idTitleIn
|
|
// The page's title.
|
|
//
|
|
// idSubtitleIn
|
|
// The page's sub-title.
|
|
//
|
|
// lParam
|
|
// The lParam to be put into the PROPSHEETPAGE stucture's lParam.
|
|
//
|
|
// Return Values:
|
|
// S_OK
|
|
// The call succeeded.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
HRESULT
|
|
CClusCfgWizard::HrAddWizardPage(
|
|
LPPROPSHEETHEADER ppshInout,
|
|
UINT idTemplateIn,
|
|
DLGPROC pfnDlgProcIn,
|
|
UINT idTitleIn,
|
|
UINT idSubtitleIn,
|
|
LPARAM lParam
|
|
)
|
|
{
|
|
TraceFunc( "" );
|
|
|
|
PROPSHEETPAGE psp;
|
|
|
|
TCHAR szTitle[ 256 ];
|
|
TCHAR szSubTitle[ 256 ];
|
|
|
|
ZeroMemory( &psp, sizeof(psp) );
|
|
|
|
psp.dwSize = sizeof(psp);
|
|
psp.dwFlags = PSP_USETITLE;
|
|
psp.pszTitle = ppshInout->pszCaption;
|
|
psp.hInstance = ppshInout->hInstance;
|
|
psp.pszTemplate = MAKEINTRESOURCE( idTemplateIn );
|
|
psp.pfnDlgProc = pfnDlgProcIn;
|
|
psp.lParam = lParam;
|
|
|
|
if ( ( idTemplateIn == IDD_WELCOME_CREATE )
|
|
|| ( idTemplateIn == IDD_WELCOME_ADD )
|
|
|| ( idTemplateIn == IDD_COMPLETION )
|
|
)
|
|
{
|
|
psp.dwFlags |= PSP_HIDEHEADER;
|
|
}
|
|
else
|
|
{
|
|
if ( idTitleIn != 0 )
|
|
{
|
|
DWORD dw;
|
|
dw = LoadString( g_hInstance, idTitleIn, szTitle, ARRAYSIZE(szTitle) );
|
|
Assert( dw );
|
|
psp.pszHeaderTitle = szTitle;
|
|
psp.dwFlags |= PSP_USEHEADERTITLE;
|
|
}
|
|
else
|
|
{
|
|
psp.pszHeaderTitle = NULL;
|
|
}
|
|
|
|
if ( idSubtitleIn != 0 )
|
|
{
|
|
DWORD dw;
|
|
dw = LoadString( g_hInstance, idSubtitleIn, szSubTitle, ARRAYSIZE(szSubTitle) );
|
|
Assert( dw );
|
|
psp.pszHeaderSubTitle = szSubTitle;
|
|
psp.dwFlags |= PSP_USEHEADERSUBTITLE;
|
|
}
|
|
else
|
|
{
|
|
psp.pszHeaderSubTitle = NULL;
|
|
}
|
|
}
|
|
|
|
ppshInout->phpage[ ppshInout->nPages ] = CreatePropertySheetPage( &psp );
|
|
Assert( ppshInout->phpage[ ppshInout->nPages ] != NULL );
|
|
if ( ppshInout->phpage[ ppshInout->nPages ] != NULL )
|
|
{
|
|
ppshInout->nPages++;
|
|
}
|
|
|
|
HRETURN( S_OK );
|
|
|
|
} //*** CClusCfgWizard::HrAddWizardPage
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgWizard::HrIsCompatibleNodeDomain
|
|
//
|
|
// Description:
|
|
// Determine whether the domain of a node being added to the cluster
|
|
// matches that already established for the cluster.
|
|
//
|
|
// Arguments:
|
|
// pcwszDomainIn - The domain of the proposed node.
|
|
//
|
|
// Return Values:
|
|
// S_OK
|
|
// Either the domain matches, or the cluster is empty.
|
|
//
|
|
// S_FALSE
|
|
// The domain does not match the cluster's.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CClusCfgWizard::HrIsCompatibleNodeDomain(
|
|
LPCWSTR pcwszDomainIn
|
|
)
|
|
{
|
|
TraceFunc( "" );
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
if ( ( m_bstrClusterDomain != NULL ) && ( ClRtlStrICmp( pcwszDomainIn, m_bstrClusterDomain ) != 0 ) )
|
|
{
|
|
hr = S_FALSE;
|
|
}
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgWizard::HrIsCompatibleNodeDomain
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// HrLaunchCleanupTask
|
|
//
|
|
// Description:
|
|
// When the wizard has been canceled after analysis has completed
|
|
// the cancel cleanup task needs to be run to ensure that all
|
|
// cleanup has occured.
|
|
//
|
|
// Arguments:
|
|
// None.
|
|
//
|
|
// Return Values:
|
|
// S_OK
|
|
// Success
|
|
//
|
|
// HRESULT errors
|
|
//
|
|
// Remarks:
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
HRESULT
|
|
CClusCfgWizard::HrLaunchCleanupTask( void )
|
|
{
|
|
TraceFunc( "" );
|
|
Assert( m_cookieCompletion == 0 );
|
|
|
|
HRESULT hr = S_OK;
|
|
IUnknown * punk = NULL;
|
|
ITaskCancelCleanup * ptcc = NULL;
|
|
OBJECTCOOKIE cookieCluster;
|
|
ULONG ulCurrent;
|
|
DWORD sc;
|
|
|
|
hr = HrGetCompletionCookie( CLSID_CancelCleanupTaskCompletionCookieType, &m_cookieCompletion );
|
|
if ( hr == E_PENDING )
|
|
{
|
|
// no-op.
|
|
} // if:
|
|
else if ( FAILED( hr ) )
|
|
{
|
|
THR( hr );
|
|
goto Cleanup;
|
|
} // else if:
|
|
|
|
hr = THR( HrCreateTask( TASK_CancelCleanup, &punk ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
hr = THR( punk->TypeSafeQI( ITaskCancelCleanup, &ptcc ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
hr = THR( HrGetClusterCookie( &cookieCluster ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
hr = THR( ptcc->SetCompletionCookie( m_cookieCompletion ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
hr = THR( HrSubmitTask( ptcc ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
//
|
|
// Wait for task to complete.
|
|
//
|
|
|
|
for ( ulCurrent = 0, sc = WAIT_OBJECT_0 + 1
|
|
; ( sc != WAIT_OBJECT_0 )
|
|
; ulCurrent++
|
|
)
|
|
{
|
|
MSG msg;
|
|
|
|
while( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
|
|
{
|
|
TranslateMessage( &msg );
|
|
DispatchMessage( &msg );
|
|
} // while:
|
|
|
|
sc = MsgWaitForMultipleObjectsEx(
|
|
1
|
|
, &m_hCancelCleanupEvent
|
|
, INFINITE
|
|
, QS_ALLEVENTS | QS_ALLINPUT | QS_ALLPOSTMESSAGE
|
|
, 0
|
|
);
|
|
} // while: sc == WAIT_OBJECT_0
|
|
|
|
Cleanup:
|
|
|
|
if ( m_cookieCompletion != 0 )
|
|
{
|
|
THR( HrReleaseCompletionObject( m_cookieCompletion ) );
|
|
m_cookieCompletion = 0;
|
|
} // if:
|
|
|
|
if ( ptcc != NULL )
|
|
{
|
|
ptcc->Release();
|
|
} // if:
|
|
|
|
if ( punk != NULL )
|
|
{
|
|
punk->Release();
|
|
} // if:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgWizard::HrLaunchCleanupTask
|
|
|
|
|
|
//****************************************************************************
|
|
//
|
|
// Non-COM public methods: cluster access
|
|
//
|
|
//****************************************************************************
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgWizard::HrSetClusterName
|
|
//
|
|
// Description:
|
|
// Sets the cluster name, overwriting any current name.
|
|
//
|
|
// Arguments:
|
|
// pwcszClusterNameIn - The new cluster name.
|
|
// fAcceptNonRFCCharsIn - Allow the name to contain non-RFC chars.
|
|
//
|
|
// Return Values:
|
|
// S_OK
|
|
// Changing the cluster name succeeded.
|
|
//
|
|
// S_FALSE
|
|
// The cluster already has this name.
|
|
//
|
|
// Other errors
|
|
// Something went wrong, and the cluster's name hasn't changed.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CClusCfgWizard::HrSetClusterName(
|
|
LPCWSTR pwcszClusterNameIn
|
|
, bool fAcceptNonRFCCharsIn
|
|
)
|
|
{
|
|
TraceFunc( "" );
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
BSTR bstrClusterFQN = NULL;
|
|
BSTR bstrClusterDisplay = NULL;
|
|
BSTR bstrClusterDomain = NULL;
|
|
|
|
Assert( pwcszClusterNameIn != NULL );
|
|
if ( pwcszClusterNameIn == NULL )
|
|
{
|
|
hr = THR( E_POINTER );
|
|
goto Cleanup;
|
|
}
|
|
|
|
//
|
|
// Determine whether the caller is providing a fully-qualified name,
|
|
// and remember the result, so that the cluster name and domain page knows
|
|
// whether to obtain the domain from the user.
|
|
//
|
|
hr = STHR( HrIsValidFQN( pwcszClusterNameIn, true ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
|
|
m_fDefaultedDomain = ( hr == S_FALSE );
|
|
|
|
// Make corresponding FQName.
|
|
hr = THR( HrMakeFQN(
|
|
pwcszClusterNameIn
|
|
, NULL // Default to local machine's domain.
|
|
, fAcceptNonRFCCharsIn
|
|
, &bstrClusterFQN
|
|
) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
|
|
// Get domain name from FQName.
|
|
{
|
|
size_t idxClusterDomain = 0;
|
|
hr = THR( HrFindDomainInFQN( bstrClusterFQN, &idxClusterDomain ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
|
|
bstrClusterDomain = TraceSysAllocString( ( bstrClusterFQN + idxClusterDomain ) );
|
|
if ( bstrClusterDomain == NULL )
|
|
{
|
|
hr = THR( E_OUTOFMEMORY );
|
|
goto Cleanup;
|
|
}
|
|
}
|
|
|
|
// If bstrClusterFQN is an FQIP,
|
|
hr = STHR( HrFQNIsFQIP( bstrClusterFQN ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
else if ( hr == S_OK ) // set display name to IP address;
|
|
{
|
|
hr = THR( HrExtractPrefixFromFQN( bstrClusterFQN, &bstrClusterDisplay ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
}
|
|
else // otherwise, set display name to pwcszClusterNameIn.
|
|
{
|
|
hr = S_OK;
|
|
bstrClusterDisplay = TraceSysAllocString( pwcszClusterNameIn );
|
|
if ( bstrClusterDisplay == NULL )
|
|
{
|
|
hr = THR( E_OUTOFMEMORY );
|
|
goto Cleanup;
|
|
}
|
|
}
|
|
|
|
// If already have a cluster name,
|
|
if ( FHasClusterName() )
|
|
{
|
|
// if names are equal, bail out with S_FALSE;
|
|
if ( ( NBSTRCompareNoCase( m_ncCluster.bstrName, bstrClusterDisplay ) == 0 )
|
|
&& ( NBSTRCompareNoCase( m_bstrClusterDomain, bstrClusterDomain ) == 0 ) )
|
|
{
|
|
hr = S_FALSE;
|
|
goto Cleanup;
|
|
}
|
|
else // otherwise, dump current cluster.
|
|
{
|
|
hr = THR( HrReleaseClusterObject() );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
|
|
m_ncCluster.Erase();
|
|
TraceSysFreeString( m_bstrClusterDomain );
|
|
m_bstrClusterDomain = NULL;
|
|
}
|
|
}
|
|
|
|
// Set cluster names.
|
|
m_bstrClusterDomain = bstrClusterDomain;
|
|
bstrClusterDomain = NULL;
|
|
m_ncCluster.bstrName = bstrClusterDisplay;
|
|
bstrClusterDisplay = NULL;
|
|
|
|
Cleanup:
|
|
|
|
TraceSysFreeString( bstrClusterFQN );
|
|
TraceSysFreeString( bstrClusterDisplay );
|
|
TraceSysFreeString( bstrClusterDomain );
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgWizard::HrSetClusterName
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgWizard::HrGetClusterDomain
|
|
//
|
|
// Description:
|
|
// Retrieve the cluster's domain.
|
|
//
|
|
// Arguments:
|
|
// pbstrDomainOut - The cluster's domain.
|
|
//
|
|
// Return Values:
|
|
// S_OK
|
|
// *pbstrDomainOut is a BSTR containing the cluster's domain; the
|
|
// caller needs to free it with TraceSysFreeString.
|
|
//
|
|
// S_FALSE
|
|
// Same as S_OK, except that the cluster's domain was not specified
|
|
// by the caller who set it, and so it defaulted to the local machine's.
|
|
//
|
|
// E_POINTER
|
|
// pbstrDomainOut was null.
|
|
//
|
|
// HRESULT_FROM_WIN32( ERROR_INVALID_DOMAINNAME )
|
|
// The cluster's name and domain are not yet defined.
|
|
//
|
|
// Other failures are possible.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CClusCfgWizard::HrGetClusterDomain(
|
|
BSTR* pbstrDomainOut
|
|
)
|
|
{
|
|
TraceFunc( "" );
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
Assert( pbstrDomainOut != NULL );
|
|
if ( pbstrDomainOut == NULL )
|
|
{
|
|
hr = THR( E_POINTER );
|
|
goto Cleanup;
|
|
}
|
|
*pbstrDomainOut = NULL;
|
|
|
|
if ( !FHasClusterName() )
|
|
{
|
|
hr = HRESULT_FROM_WIN32( TW32( ERROR_INVALID_DOMAINNAME ) );
|
|
goto Cleanup;
|
|
}
|
|
|
|
*pbstrDomainOut = TraceSysAllocString( m_bstrClusterDomain );
|
|
if ( *pbstrDomainOut == NULL )
|
|
{
|
|
hr = THR( E_OUTOFMEMORY );
|
|
goto Cleanup;
|
|
}
|
|
|
|
hr = ( m_fDefaultedDomain? S_FALSE: S_OK );
|
|
|
|
Cleanup:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgWizard::HrGetClusterDomain
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgWizard::HrGetClusterObject
|
|
//
|
|
// Description:
|
|
// Retrieve the CClusCfgServer object representing the cluster,
|
|
// creating it if necessary.
|
|
//
|
|
// Arguments:
|
|
// ppClusterOut
|
|
// A pointer to the CClusCfgServer object; can be null if the
|
|
// caller wants just to ensure the object exists.
|
|
//
|
|
// Return Values:
|
|
// S_OK
|
|
// The cluster object exists; if ppClusterOut is not null,
|
|
// *ppClusterOut points to the object and the caller must
|
|
// release it.
|
|
//
|
|
// E_PENDING
|
|
// The cluster object has not been initialized,
|
|
// and *ppClusterOut is null.
|
|
//
|
|
// HRESULT_FROM_WIN32( ERROR_INVALID_ACCOUNT_NAME )
|
|
// The cluster's name has not yet been set.
|
|
//
|
|
// Other failures are possible.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CClusCfgWizard::HrGetClusterObject(
|
|
IClusCfgClusterInfo ** ppClusterOut
|
|
)
|
|
{
|
|
TraceFunc( "" );
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
if ( ppClusterOut != NULL )
|
|
{
|
|
*ppClusterOut = NULL;
|
|
}
|
|
|
|
if ( !m_ncCluster.FHasObject() )
|
|
{
|
|
if ( !m_ncCluster.FHasCookie() )
|
|
{
|
|
hr = STHR( HrGetClusterCookie( NULL ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
}
|
|
|
|
hr = THR( m_pom->GetObject( DFGUID_ClusterConfigurationInfo, m_ncCluster.ocObject, &m_ncCluster.punkObject ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
} // m_ncCluster currently has no object pointer.
|
|
|
|
if ( ppClusterOut != NULL )
|
|
{
|
|
hr = THR( m_ncCluster.punkObject->QueryInterface( IID_IClusCfgClusterInfo, reinterpret_cast< void ** >( ppClusterOut ) ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
}
|
|
|
|
Cleanup:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgWizard::HrGetClusterObject
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgWizard::HrGetClusterCookie
|
|
//
|
|
// Description:
|
|
// Retrieve the ObjectManager cookie corresponding to the cluster,
|
|
// creating it if necessary.
|
|
//
|
|
// Arguments:
|
|
// pocClusterOut
|
|
// A pointer to the ObjectManager cookie; can be null if the
|
|
// caller wants just to ensure the cookie exists.
|
|
//
|
|
// Return Values:
|
|
// S_OK
|
|
// The cookie exists; if pocClusterOut is not null,
|
|
// *pocClusterOut holds the value of the cookie.
|
|
//
|
|
// S_FALSE
|
|
// Same as S_OK except that the corresponding object is known not
|
|
// to be initialized.
|
|
//
|
|
// HRESULT_FROM_WIN32( ERROR_INVALID_ACCOUNT_NAME )
|
|
// The cluster's name has not yet been set.
|
|
//
|
|
// Other failures are possible.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CClusCfgWizard::HrGetClusterCookie(
|
|
OBJECTCOOKIE * pocClusterOut
|
|
)
|
|
{
|
|
TraceFunc( "" );
|
|
|
|
HRESULT hr = S_OK;
|
|
BSTR bstrClusterFQN = NULL;
|
|
|
|
// Clear *pocClusterOut in case of failure.
|
|
if ( pocClusterOut != NULL )
|
|
{
|
|
*pocClusterOut = 0;
|
|
}
|
|
|
|
Assert( FHasClusterName() );
|
|
if ( !FHasClusterName() )
|
|
{
|
|
hr = HRESULT_FROM_WIN32( TW32( ERROR_INVALID_ACCOUNT_NAME ) );
|
|
goto Cleanup;
|
|
}
|
|
|
|
// Get the cookie from the object manager if necessary.
|
|
if ( !m_ncCluster.FHasCookie() )
|
|
{
|
|
// Make FQName for cluster.
|
|
hr = THR( HrMakeFQN( m_ncCluster.bstrName, m_bstrClusterDomain, true, &bstrClusterFQN ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
|
|
hr = m_pom->FindObject(
|
|
CLSID_ClusterConfigurationType
|
|
, 0
|
|
, bstrClusterFQN
|
|
, DFGUID_ClusterConfigurationInfo
|
|
, &m_ncCluster.ocObject
|
|
, &m_ncCluster.punkObject
|
|
);
|
|
if ( hr == E_PENDING )
|
|
{
|
|
hr = S_FALSE;
|
|
}
|
|
else if ( FAILED( hr ) )
|
|
{
|
|
THR( hr );
|
|
goto Cleanup;
|
|
}
|
|
} // m_ncCluster currently has no cookie.
|
|
|
|
// Set the cookie if the caller wants it.
|
|
if ( pocClusterOut != NULL )
|
|
{
|
|
*pocClusterOut = m_ncCluster.ocObject;
|
|
}
|
|
|
|
Cleanup:
|
|
TraceSysFreeString( bstrClusterFQN );
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgWizard::HrGetClusterCookie
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgWizard::HrGetClusterChild
|
|
//
|
|
// Description:
|
|
// Retrieve an object which the ObjectManager regards as a child of
|
|
// the cluster.
|
|
//
|
|
// Arguments:
|
|
// rclsidChildIn - The child's class.
|
|
// rguidFormatIn - The child's "data format."
|
|
// ppunkChildOut - A pointer to the child object.
|
|
//
|
|
// Return Values:
|
|
// S_OK
|
|
// The call succeeded and *ppunkChildOut points to a valid object,
|
|
// which the caller must release.
|
|
//
|
|
// Failure
|
|
// *ppunkChildOut is null.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CClusCfgWizard::HrGetClusterChild(
|
|
REFCLSID rclsidChildIn
|
|
, REFGUID rguidFormatIn
|
|
, IUnknown ** ppunkChildOut
|
|
)
|
|
{
|
|
TraceFunc( "" );
|
|
|
|
HRESULT hr = S_OK;
|
|
OBJECTCOOKIE ocChild = 0;
|
|
|
|
Assert( ppunkChildOut != NULL );
|
|
if ( ppunkChildOut == NULL )
|
|
{
|
|
hr = THR( E_POINTER );
|
|
goto Cleanup;
|
|
}
|
|
*ppunkChildOut = NULL;
|
|
|
|
if ( !m_ncCluster.FHasCookie() )
|
|
{
|
|
hr = STHR( HrGetClusterCookie( NULL ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
}
|
|
|
|
hr = THR( m_pom->FindObject(
|
|
rclsidChildIn
|
|
, m_ncCluster.ocObject
|
|
, NULL
|
|
, rguidFormatIn
|
|
, &ocChild
|
|
, ppunkChildOut
|
|
) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
|
|
Cleanup:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgWizard::HrGetClusterChild
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgWizard::HrReleaseClusterObject
|
|
//
|
|
// Description:
|
|
// Discard the cluster object (if one exists) and all nodes, and
|
|
// ask the object manager to do the same, but preserve the cluster's
|
|
// name (as well as the node names).
|
|
//
|
|
// Arguments:
|
|
// None.
|
|
//
|
|
// Return Values:
|
|
// S_OK
|
|
// Failure
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CClusCfgWizard::HrReleaseClusterObject( void )
|
|
{
|
|
TraceFunc( "" );
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
if ( m_ncCluster.FHasCookie() )
|
|
{
|
|
hr = THR( HrReleaseNodeObjects() );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
|
|
hr = THR( m_pom->RemoveObject( m_ncCluster.ocObject ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
|
|
m_ncCluster.ocObject = 0;
|
|
m_ncCluster.ReleaseObject();
|
|
} // If: cluster cookie exists.
|
|
|
|
Cleanup:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgWizard::HrReleaseClusterObject
|
|
|
|
|
|
//****************************************************************************
|
|
//
|
|
// Non-COM public methods: node access
|
|
//
|
|
//****************************************************************************
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgWizard::HrAddNode
|
|
//
|
|
// Description:
|
|
// Add a node for the wizard to include in its action.
|
|
//
|
|
// Arguments:
|
|
// pwcszNodeNameIn
|
|
// The node's name; can be anything accepted as the first
|
|
// argument to HrMakeFQN.
|
|
//
|
|
// fAcceptNonRFCCharsIn
|
|
// Allow the node name to contain non-RFC characters.
|
|
//
|
|
// Return Values:
|
|
// S_OK
|
|
// The name is valid and the corresponding machine will be
|
|
// included in the wizard's action.
|
|
//
|
|
// S_FALSE
|
|
// The node is already in the wizard's list.
|
|
//
|
|
// HRESULT_FROM_WIN32( ERROR_CURRENT_DOMAIN_NOT_ALLOWED )
|
|
// The node's domain conflicts either with the cluster's or with
|
|
// that of other nodes in the cluster.
|
|
//
|
|
// Other failures
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CClusCfgWizard::HrAddNode(
|
|
LPCWSTR pwcszNodeNameIn
|
|
, bool fAcceptNonRFCCharsIn
|
|
)
|
|
{
|
|
TraceFunc( "" );
|
|
|
|
HRESULT hr = S_OK;
|
|
BSTR bstrNodeFQN = NULL;
|
|
BSTR bstrNodeDisplay = NULL;
|
|
|
|
NamedCookieArray::Iterator it = m_ncaNodes.ItBegin();
|
|
|
|
Assert( pwcszNodeNameIn != NULL );
|
|
if ( pwcszNodeNameIn == NULL )
|
|
{
|
|
hr = THR( E_POINTER );
|
|
goto Cleanup;
|
|
}
|
|
|
|
// Make corresponding FQName, using cluster domain (or local machine's) as default.
|
|
hr = THR( HrMakeFQN( pwcszNodeNameIn, m_bstrClusterDomain, fAcceptNonRFCCharsIn, &bstrNodeFQN ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
|
|
// If bstrNodeFQN is an FQIP,
|
|
hr = STHR( HrFQNIsFQIP( bstrNodeFQN ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
else if ( hr == S_OK ) // set display name to IP address;
|
|
{
|
|
hr = THR( HrExtractPrefixFromFQN( bstrNodeFQN, &bstrNodeDisplay ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
}
|
|
else // otherwise, set display name to pwcszNodeNameIn.
|
|
{
|
|
bstrNodeDisplay = TraceSysAllocString( pwcszNodeNameIn );
|
|
if ( bstrNodeDisplay == NULL )
|
|
{
|
|
hr = THR( E_OUTOFMEMORY );
|
|
goto Cleanup;
|
|
}
|
|
}
|
|
|
|
// If name already exists, bail out with S_FALSE;
|
|
while ( it != m_ncaNodes.ItEnd() )
|
|
{
|
|
if ( NBSTRCompareNoCase( ( *it ).bstrName, bstrNodeDisplay ) == 0 )
|
|
{
|
|
hr = S_FALSE;
|
|
goto Cleanup;
|
|
}
|
|
++it;
|
|
} // For each node currently in the list.
|
|
|
|
// Add to node list.
|
|
{
|
|
SNamedCookie ncNewNode;
|
|
|
|
ncNewNode.bstrName = bstrNodeDisplay;
|
|
bstrNodeDisplay = NULL;
|
|
|
|
hr = THR( m_ncaNodes.HrPushBack( ncNewNode ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
}
|
|
|
|
Cleanup:
|
|
|
|
TraceSysFreeString( bstrNodeFQN );
|
|
TraceSysFreeString( bstrNodeDisplay );
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgWizard::HrAddNode
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgWizard::HrGetNodeCount
|
|
//
|
|
// Description:
|
|
// Retrieve the number of nodes currently in the wizard's list.
|
|
//
|
|
// Arguments:
|
|
// pcNodesOut - The node count.
|
|
//
|
|
// Return Values:
|
|
// S_OK
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CClusCfgWizard::HrGetNodeCount(
|
|
size_t* pcNodesOut
|
|
)
|
|
{
|
|
TraceFunc( "" );
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
Assert( pcNodesOut != NULL );
|
|
if ( pcNodesOut == NULL )
|
|
{
|
|
hr = THR( E_POINTER );
|
|
goto Cleanup;
|
|
}
|
|
|
|
*pcNodesOut = m_ncaNodes.Count();
|
|
|
|
Cleanup:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgWizard::HrGetNodeCount
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgWizard::HrGetNodeObject
|
|
//
|
|
// Description:
|
|
// Retrieve the CClusCfgServer object representing a node in the
|
|
// list, creating it if necessary.
|
|
//
|
|
// Arguments:
|
|
// idxNodeIn
|
|
// The zero-based index of the node in the list.
|
|
//
|
|
// ppNodeOut
|
|
// A pointer to the CClusCfgServer object; can be null if the
|
|
// caller wants just to ensure the object exists.
|
|
//
|
|
// Return Values:
|
|
// S_OK
|
|
// The node object exists; if ppNodeOut is not null,
|
|
// *ppNodeOut points to the object and the caller must
|
|
// release it.
|
|
//
|
|
// E_PENDING
|
|
// The node object has not been initialized,
|
|
// and *ppNodeOut is null.
|
|
//
|
|
// Other failures are possible.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CClusCfgWizard::HrGetNodeObject(
|
|
size_t idxNodeIn
|
|
, IClusCfgNodeInfo ** ppNodeOut
|
|
)
|
|
{
|
|
TraceFunc( "" );
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
// Clear *ppNodeOut in case of failure.
|
|
if ( ppNodeOut != NULL )
|
|
{
|
|
*ppNodeOut = NULL;
|
|
}
|
|
|
|
// Make sure index is within bounds.
|
|
Assert( idxNodeIn < m_ncaNodes.Count() );
|
|
if ( idxNodeIn >= m_ncaNodes.Count() )
|
|
{
|
|
hr = THR( E_INVALIDARG );
|
|
goto Cleanup;
|
|
}
|
|
|
|
// Obtain the object from the object manager if necessary.
|
|
if ( !m_ncaNodes[ idxNodeIn ].FHasObject() )
|
|
{
|
|
hr = STHR( HrGetNodeCookie( idxNodeIn, NULL ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
|
|
hr = THR( m_pom->GetObject(
|
|
DFGUID_NodeInformation
|
|
, m_ncaNodes[ idxNodeIn ].ocObject
|
|
, &m_ncaNodes[ idxNodeIn ].punkObject
|
|
) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
} // If: need to obtain object from object manager.
|
|
|
|
// QI for the interface if the caller wants it.
|
|
if ( ppNodeOut != NULL )
|
|
{
|
|
hr = THR( m_ncaNodes[ idxNodeIn ].punkObject->QueryInterface(
|
|
IID_IClusCfgNodeInfo
|
|
, reinterpret_cast< void** >( ppNodeOut )
|
|
) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
}
|
|
|
|
Cleanup:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgWizard::HrGetNodeObject
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgWizard::HrGetNodeCookie
|
|
//
|
|
// Description:
|
|
// Retrieve the ObjectManager cookie corresponding to the node,
|
|
// creating it if necessary.
|
|
//
|
|
// Arguments:
|
|
// idxNodeIn
|
|
// The zero-based index of the node in the list.
|
|
//
|
|
// pocNodeOut
|
|
// A pointer to the ObjectManager cookie; can be null if the
|
|
// caller wants just to ensure the cookie exists.
|
|
//
|
|
// Return Values:
|
|
// S_OK
|
|
// The cookie exists; if pocNodeOut is not null,
|
|
// *pocNodeOut holds the value of the cookie.
|
|
//
|
|
// S_FALSE
|
|
// Same as S_OK except that the corresponding object is known not
|
|
// to be initialized.
|
|
//
|
|
// Other failures are possible.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CClusCfgWizard::HrGetNodeCookie(
|
|
size_t idxNodeIn
|
|
, OBJECTCOOKIE * pocNodeOut
|
|
)
|
|
{
|
|
TraceFunc( "" );
|
|
|
|
HRESULT hr = S_OK;
|
|
BSTR bstrNodeFQN = NULL;
|
|
|
|
// Clear *pocNodeOut in case of failure.
|
|
if ( pocNodeOut != NULL )
|
|
{
|
|
*pocNodeOut = 0;
|
|
}
|
|
|
|
// Make sure index is within bounds.
|
|
Assert( idxNodeIn < m_ncaNodes.Count() );
|
|
if ( idxNodeIn >= m_ncaNodes.Count() )
|
|
{
|
|
hr = THR( E_INVALIDARG );
|
|
goto Cleanup;
|
|
}
|
|
|
|
// Get the cookie from the object manager if necessary.
|
|
if ( !m_ncaNodes[ idxNodeIn ].FHasCookie() )
|
|
{
|
|
hr = STHR( HrGetClusterCookie( NULL ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
|
|
hr = THR( HrMakeFQN( m_ncaNodes[ idxNodeIn ].bstrName, m_bstrClusterDomain, true, &bstrNodeFQN ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
|
|
hr = m_pom->FindObject(
|
|
CLSID_NodeType
|
|
, m_ncCluster.ocObject
|
|
, bstrNodeFQN
|
|
, DFGUID_NodeInformation
|
|
, &m_ncaNodes[ idxNodeIn ].ocObject
|
|
, &m_ncaNodes[ idxNodeIn ].punkObject
|
|
);
|
|
if ( hr == E_PENDING )
|
|
{
|
|
hr = S_FALSE;
|
|
}
|
|
else if ( FAILED( hr ) )
|
|
{
|
|
THR( hr );
|
|
goto Cleanup;
|
|
}
|
|
} // If: node doesn't already have a cookie.
|
|
|
|
// Set the cookie if the caller wants it.
|
|
if ( pocNodeOut != NULL )
|
|
{
|
|
*pocNodeOut = m_ncaNodes[ idxNodeIn ].ocObject;
|
|
}
|
|
|
|
Cleanup:
|
|
|
|
TraceSysFreeString( bstrNodeFQN );
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgWizard::HrGetNodeCookie
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgWizard::HrGetNodeName
|
|
//
|
|
// Description:
|
|
// Retrieve the node's name.
|
|
//
|
|
// Arguments:
|
|
// idxNodeIn - The zero-based index of the node in the list.
|
|
// pbstrNodeNameOut - The node's name.
|
|
//
|
|
// Return Values:
|
|
// S_OK
|
|
// *pbstrNodeNameOut is a BSTR containing the node's name; the
|
|
// caller needs to free it with TraceSysFreeString.
|
|
//
|
|
// E_POINTER
|
|
// pbstrNodeNameOut was null.
|
|
//
|
|
// E_INVALIDARG
|
|
// The index was out of range for the current set of nodes.
|
|
//
|
|
// Other failures are possible.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CClusCfgWizard::HrGetNodeName(
|
|
size_t idxNodeIn
|
|
, BSTR * pbstrNodeNameOut
|
|
)
|
|
{
|
|
TraceFunc( "" );
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
// Check out-parameter and set to null in case of failure.
|
|
Assert( pbstrNodeNameOut != NULL );
|
|
if ( pbstrNodeNameOut == NULL )
|
|
{
|
|
hr = THR( E_POINTER );
|
|
goto Cleanup;
|
|
}
|
|
*pbstrNodeNameOut = NULL;
|
|
|
|
// Make sure index is within bounds.
|
|
Assert( idxNodeIn < m_ncaNodes.Count() );
|
|
if ( idxNodeIn >= m_ncaNodes.Count() )
|
|
{
|
|
hr = THR( E_INVALIDARG );
|
|
goto Cleanup;
|
|
}
|
|
|
|
*pbstrNodeNameOut = TraceSysAllocString( m_ncaNodes[ idxNodeIn ].bstrName );
|
|
if ( *pbstrNodeNameOut == NULL )
|
|
{
|
|
hr = THR( E_OUTOFMEMORY );
|
|
goto Cleanup;
|
|
}
|
|
|
|
Cleanup:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgWizard::HrGetNodeName
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgWizard::HrGetNodeChild
|
|
//
|
|
// Description:
|
|
// Retrieve an object which the ObjectManager regards as a child of
|
|
// the node.
|
|
//
|
|
// Arguments:
|
|
// idxNodeIn - The zero-based index of the node in the list.
|
|
// rclsidChildIn - The child's class.
|
|
// rguidFormatIn - The child's "data format."
|
|
// ppunkChildOut - A pointer to the child object.
|
|
//
|
|
// Return Values:
|
|
// S_OK
|
|
// The call succeeded and *ppunkChildOut points to a valid object,
|
|
// which the caller must release.
|
|
//
|
|
// Failure
|
|
// *ppunkChildOut is null.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CClusCfgWizard::HrGetNodeChild(
|
|
size_t idxNodeIn
|
|
, REFCLSID rclsidChildIn
|
|
, REFGUID rguidFormatIn
|
|
, IUnknown ** ppunkChildOut
|
|
)
|
|
{
|
|
TraceFunc( "" );
|
|
|
|
HRESULT hr = S_OK;
|
|
OBJECTCOOKIE ocChild = 0;
|
|
|
|
// Check out-parameter and set to null in case of failure.
|
|
Assert( ppunkChildOut != NULL );
|
|
if ( ppunkChildOut == NULL )
|
|
{
|
|
hr = THR( E_POINTER );
|
|
goto Cleanup;
|
|
}
|
|
*ppunkChildOut = NULL;
|
|
|
|
// Make sure index is within bounds.
|
|
Assert( idxNodeIn < m_ncaNodes.Count() );
|
|
if ( idxNodeIn >= m_ncaNodes.Count() )
|
|
{
|
|
hr = THR( E_INVALIDARG );
|
|
goto Cleanup;
|
|
}
|
|
|
|
// Get the node's cookie if necessary.
|
|
if ( !m_ncaNodes[ idxNodeIn ].FHasCookie() )
|
|
{
|
|
hr = STHR( HrGetNodeCookie( idxNodeIn, NULL ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
}
|
|
|
|
// Ask the object manager for the child object.
|
|
hr = THR( m_pom->FindObject(
|
|
rclsidChildIn
|
|
, m_ncaNodes[ idxNodeIn ].ocObject
|
|
, NULL
|
|
, rguidFormatIn
|
|
, &ocChild
|
|
, ppunkChildOut
|
|
) );
|
|
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
|
|
Cleanup:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgWizard::HrGetNodeChild
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgWizard::HrReleaseNodeObjects
|
|
//
|
|
// Description:
|
|
// Discard all node objects, and ask the object manager to do
|
|
// the same, but preserve the list of names.
|
|
//
|
|
// Arguments:
|
|
// None.
|
|
//
|
|
// Return Values:
|
|
// S_OK
|
|
// Failure
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CClusCfgWizard::HrReleaseNodeObjects( void )
|
|
{
|
|
TraceFunc( "" );
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
for ( NamedCookieArray::Iterator it = m_ncaNodes.ItBegin(); it != m_ncaNodes.ItEnd(); ++it)
|
|
{
|
|
if ( ( *it ).FHasCookie() )
|
|
{
|
|
hr = THR( m_pom->RemoveObject( ( *it ).ocObject ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
( *it ).ocObject = 0;
|
|
|
|
( *it ).ReleaseObject();
|
|
}
|
|
} // For each node in the list.
|
|
|
|
Cleanup:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgWizard::HrReleaseNodeObjects
|
|
|
|
|
|
//****************************************************************************
|
|
//
|
|
// Non-COM public methods: task access
|
|
//
|
|
//****************************************************************************
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgWizard::HrCreateTask
|
|
//
|
|
// Description:
|
|
// Get a new task from the task manager.
|
|
//
|
|
// Arguments:
|
|
// rguidTaskIn - The type of task.
|
|
// ppunkOut - A pointer to the new task.
|
|
//
|
|
// Return Values:
|
|
// S_OK
|
|
// Failure
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CClusCfgWizard::HrCreateTask(
|
|
REFGUID rguidTaskIn
|
|
, IUnknown ** ppunkOut
|
|
)
|
|
{
|
|
TraceFunc( "" );
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
hr = THR( m_ptm->CreateTask( rguidTaskIn, ppunkOut ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
|
|
Cleanup:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgWizard::HrCreateTask
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgWizard::HrSubmitTask
|
|
//
|
|
// Description:
|
|
// Submit a task to the task manager.
|
|
//
|
|
// Arguments:
|
|
// pTaskIn - A pointer to the task to submit.
|
|
//
|
|
// Return Values:
|
|
// S_OK
|
|
// Failure
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CClusCfgWizard::HrSubmitTask(
|
|
IDoTask * pTaskIn
|
|
)
|
|
{
|
|
TraceFunc( "" );
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
hr = THR( m_ptm->SubmitTask( pTaskIn ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
|
|
Cleanup:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgWizard::HrSubmitTask
|
|
|
|
|
|
//****************************************************************************
|
|
//
|
|
// Non-COM public methods: completion task access
|
|
//
|
|
//****************************************************************************
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgWizard::HrGetCompletionCookie
|
|
//
|
|
// Description:
|
|
// Get an object manager cookie for referring to a completion task.
|
|
//
|
|
// Arguments:
|
|
// rguidTaskIn - The type of completion task.
|
|
// pocTaskOut - The task's cookie.
|
|
//
|
|
// Return Values:
|
|
// S_OK
|
|
// E_PENDING - An expected value; the task is not yet complete.
|
|
// Other failures.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CClusCfgWizard::HrGetCompletionCookie(
|
|
REFGUID rguidTaskIn
|
|
, OBJECTCOOKIE * pocTaskOut
|
|
)
|
|
{
|
|
TraceFunc( "" );
|
|
|
|
HRESULT hr = S_OK;
|
|
IUnknown* punk = NULL;
|
|
|
|
hr = m_pom->FindObject(
|
|
rguidTaskIn
|
|
, NULL
|
|
, m_ncCluster.bstrName
|
|
, IID_NULL
|
|
, pocTaskOut
|
|
, &punk // dummy
|
|
);
|
|
if ( FAILED( hr ) && ( hr != E_PENDING ) )
|
|
{
|
|
THR( hr );
|
|
goto Cleanup;
|
|
}
|
|
|
|
Cleanup:
|
|
|
|
if ( punk != NULL )
|
|
{
|
|
punk->Release();
|
|
}
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgWizard::HrGetCompletionCookie
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgWizard::HrGetCompletionStatus
|
|
//
|
|
// Description:
|
|
// Get the status of a completion task.
|
|
//
|
|
// Arguments:
|
|
// ocTaskIn
|
|
// The task's cookie, obtained from HrGetCompletionCookie.
|
|
//
|
|
// phrStatusOut
|
|
// The task's current status.
|
|
//
|
|
// Return Values:
|
|
// S_OK
|
|
// Failure
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CClusCfgWizard::HrGetCompletionStatus(
|
|
OBJECTCOOKIE ocTaskIn
|
|
, HRESULT * phrStatusOut
|
|
)
|
|
{
|
|
TraceFunc( "" );
|
|
|
|
HRESULT hr = S_OK;
|
|
IStandardInfo* psi = NULL;
|
|
IUnknown* punk = NULL;
|
|
|
|
hr = THR( m_pom->GetObject( DFGUID_StandardInfo, ocTaskIn, &punk ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
|
|
hr = THR( punk->TypeSafeQI( IStandardInfo, &psi ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
|
|
hr = THR( psi->GetStatus( phrStatusOut ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
|
|
Cleanup:
|
|
|
|
if ( punk != NULL )
|
|
{
|
|
punk->Release();
|
|
}
|
|
|
|
if ( psi != NULL )
|
|
{
|
|
psi->Release();
|
|
}
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgWizard::HrGetCompletionStatus
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgWizard::HrReleaseCompletionObject
|
|
//
|
|
// Description:
|
|
// Release a completion task that's no longer needed.
|
|
//
|
|
// Arguments:
|
|
// ocTaskIn
|
|
// The task's cookie, obtained from HrGetCompletionCookie.
|
|
//
|
|
// Return Values:
|
|
// S_OK
|
|
// Failure
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CClusCfgWizard::HrReleaseCompletionObject(
|
|
OBJECTCOOKIE ocTaskIn
|
|
)
|
|
{
|
|
TraceFunc( "" );
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
hr = THR( m_pom->RemoveObject( ocTaskIn ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
|
|
Cleanup:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgWizard::HrReleaseCompletionObject
|
|
|
|
|
|
|
|
//****************************************************************************
|
|
//
|
|
// Non-COM public methods: connection point access
|
|
//
|
|
//****************************************************************************
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgWizard::HrAdvise
|
|
//
|
|
// Description:
|
|
// Hook up an event sink to receive notifications from the middle tier.
|
|
//
|
|
// Arguments:
|
|
// riidConnectionIn - The type of event sink.
|
|
// punkConnectionIn - The event sink instance to connect.
|
|
// pdwCookieOut - The cookie to use for disconnecting.
|
|
//
|
|
// Return Values:
|
|
// S_OK
|
|
// Failure
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CClusCfgWizard::HrAdvise(
|
|
REFIID riidConnectionIn
|
|
, IUnknown * punkConnectionIn
|
|
, DWORD * pdwCookieOut
|
|
)
|
|
{
|
|
TraceFunc( "" );
|
|
|
|
HRESULT hr = S_OK;
|
|
IConnectionPoint * pConnection = NULL;
|
|
|
|
hr = THR( m_pcpc->FindConnectionPoint( riidConnectionIn, &pConnection ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
|
|
hr = THR( pConnection->Advise( punkConnectionIn, pdwCookieOut ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
|
|
Cleanup:
|
|
|
|
if ( pConnection != NULL )
|
|
{
|
|
pConnection->Release();
|
|
}
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgWizard::HrAdvise
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgWizard::HrUnadvise
|
|
//
|
|
// Description:
|
|
// Disconnect an event sink from the middle tier.
|
|
//
|
|
// Arguments:
|
|
// riidConnectionIn - The type of event sink.
|
|
// dwCookieIn - The event sink's cookie from HrAdvise.
|
|
//
|
|
// Return Values:
|
|
// S_OK
|
|
// Failure
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CClusCfgWizard::HrUnadvise(
|
|
REFIID riidConnectionIn
|
|
, DWORD dwCookieIn
|
|
)
|
|
{
|
|
TraceFunc( "" );
|
|
|
|
HRESULT hr = S_OK;
|
|
IConnectionPoint * pConnection = NULL;
|
|
|
|
hr = THR( m_pcpc->FindConnectionPoint( riidConnectionIn, &pConnection ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
|
|
hr = THR( pConnection->Unadvise( dwCookieIn ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
|
|
Cleanup:
|
|
|
|
if ( pConnection != NULL )
|
|
{
|
|
pConnection->Release();
|
|
}
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgWizard::HrUnadvise
|
|
|
|
|
|
//****************************************************************************
|
|
//
|
|
// Non-COM public methods: miscellaneous
|
|
//
|
|
//****************************************************************************
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgWizard::HrCreateMiddleTierObjects
|
|
//
|
|
// Description:
|
|
//
|
|
// Arguments:
|
|
// None.
|
|
//
|
|
// Return Values:
|
|
// S_OK
|
|
// Failure
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CClusCfgWizard::HrCreateMiddleTierObjects()
|
|
{
|
|
TraceFunc( "" );
|
|
|
|
HRESULT hr = S_OK;
|
|
size_t idxNode = 0;
|
|
|
|
hr = STHR( HrGetClusterCookie( NULL ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
|
|
for ( idxNode = 0; idxNode < m_ncaNodes.Count(); ++idxNode )
|
|
{
|
|
hr = STHR( HrGetNodeCookie( idxNode, NULL ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
}
|
|
|
|
hr = S_OK;
|
|
|
|
Cleanup:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgWizard::HrCreateMiddleTierObjects
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgWizard::FHasClusterName
|
|
//
|
|
// Description:
|
|
//
|
|
// Arguments:
|
|
// None.
|
|
//
|
|
// Return Values:
|
|
// S_OK
|
|
// Failure
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
BOOL
|
|
CClusCfgWizard::FHasClusterName() const
|
|
{
|
|
TraceFunc( "" );
|
|
|
|
RETURN( m_ncCluster.FHasName() );
|
|
|
|
} //*** CClusCfgWizard::FHasClusterName
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgWizard::FDefaultedClusterDomain
|
|
//
|
|
// Description:
|
|
//
|
|
// Arguments:
|
|
// None.
|
|
//
|
|
// Return Values:
|
|
// S_OK
|
|
// Failure
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
BOOL
|
|
CClusCfgWizard::FDefaultedClusterDomain() const
|
|
{
|
|
TraceFunc( "" );
|
|
|
|
RETURN( m_fDefaultedDomain );
|
|
|
|
} //*** CClusCfgWizard::FHasClusterName
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgWizard::HrFilterNodesWithBadDomains
|
|
//
|
|
// Description:
|
|
//
|
|
// Arguments:
|
|
// None.
|
|
//
|
|
// Return Values:
|
|
// S_OK
|
|
// Failure
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CClusCfgWizard::HrFilterNodesWithBadDomains( BSTR* pbstrBadNodesOut )
|
|
{
|
|
TraceFunc( "" );
|
|
|
|
HRESULT hr = S_OK;
|
|
BSTR bstrCurrentList = NULL;
|
|
|
|
NamedCookieArray ncaUnfilteredNodes;
|
|
|
|
Assert( pbstrBadNodesOut != NULL );
|
|
if ( pbstrBadNodesOut == NULL )
|
|
{
|
|
hr = THR( E_POINTER );
|
|
goto Cleanup;
|
|
}
|
|
*pbstrBadNodesOut = NULL;
|
|
|
|
ncaUnfilteredNodes.Swap( m_ncaNodes );
|
|
|
|
for ( NamedCookieArray::Iterator it = ncaUnfilteredNodes.ItBegin(); it != ncaUnfilteredNodes.ItEnd(); ++it )
|
|
{
|
|
bool fDomainValid = true;
|
|
|
|
hr = STHR( HrIsValidFQN( ( *it ).bstrName, true ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
else if ( hr == S_OK )
|
|
{
|
|
size_t idxNodeDomain = 0;
|
|
hr = THR( HrFindDomainInFQN( ( *it ).bstrName, &idxNodeDomain ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
|
|
hr = STHR( HrIsCompatibleNodeDomain( ( *it ).bstrName + idxNodeDomain ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
fDomainValid = ( hr == S_OK );
|
|
|
|
if ( fDomainValid )
|
|
{
|
|
// KB: 18-Oct-2001 jfranco bug #477514
|
|
// The wizard's supposed to show node domains to the user only when they're invalid,
|
|
// so remove the domain from the node name.
|
|
|
|
BSTR bstrShortName = NULL;
|
|
hr = THR( HrExtractPrefixFromFQN( ( *it ).bstrName, &bstrShortName ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
|
|
TraceSysFreeString( ( *it ).bstrName );
|
|
( *it ).bstrName = bstrShortName;
|
|
}
|
|
} // if: node name has a domain
|
|
|
|
if ( fDomainValid ) // Domain is okay, so put into filtered array.
|
|
{
|
|
hr = THR( m_ncaNodes.HrPushBack( ( *it ) ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
}
|
|
else // Domain doesn't match; add to bad list.
|
|
{
|
|
if ( *pbstrBadNodesOut == NULL ) // First name in bad list.
|
|
{
|
|
*pbstrBadNodesOut = TraceSysAllocString( ( *it ).bstrName );
|
|
if ( *pbstrBadNodesOut == NULL )
|
|
{
|
|
hr = THR( E_OUTOFMEMORY );
|
|
goto Cleanup;
|
|
}
|
|
}
|
|
else // Append another name to non-empty bad list.
|
|
{
|
|
TraceSysFreeString( bstrCurrentList );
|
|
bstrCurrentList = *pbstrBadNodesOut;
|
|
*pbstrBadNodesOut = NULL;
|
|
hr = THR( HrFormatStringIntoBSTR(
|
|
L"%1!ws!; %2!ws!"
|
|
, pbstrBadNodesOut
|
|
, bstrCurrentList
|
|
, ( *it ).bstrName
|
|
) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
} // else: append name to bad list
|
|
} // else: mismatched domain
|
|
} // for: each unfiltered node
|
|
|
|
|
|
Cleanup:
|
|
|
|
TraceSysFreeString( bstrCurrentList );
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgWizard::HrFilterNodesWithBadDomains
|
|
|
|
/*
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgWizard::HrReadSettings
|
|
//
|
|
// Description:
|
|
// Read the saved settings from the registry. If there are no saved
|
|
// setting then we want to do a full configuration.
|
|
//
|
|
// Arguments:
|
|
// pecsSettingOut
|
|
// What is the saved setting?
|
|
//
|
|
// pfValuePresentOut
|
|
// Was the value present in the registry?
|
|
//
|
|
// Return Values:
|
|
// S_OK
|
|
// Success
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
HRESULT
|
|
CClusCfgWizard::HrReadSettings(
|
|
EConfigurationSettings * pecsSettingOut
|
|
, BOOL * pfValuePresentOut // = NULL
|
|
)
|
|
{
|
|
TraceFunc( "" );
|
|
Assert( pecsSettingOut != NULL );
|
|
|
|
HRESULT hr = S_OK;
|
|
DWORD sc;
|
|
HKEY hKey = NULL;
|
|
DWORD dwType;
|
|
DWORD dwData;
|
|
DWORD cbData = sizeof( dwData );
|
|
|
|
//
|
|
// Default to doing a full config.
|
|
//
|
|
|
|
*pecsSettingOut = csFullConfig;
|
|
|
|
//
|
|
// Default to the value not being present.
|
|
//
|
|
|
|
if ( pfValuePresentOut != NULL )
|
|
{
|
|
*pfValuePresentOut = FALSE;
|
|
} // if:
|
|
|
|
sc = RegOpenKeyExW( HKEY_CURRENT_USER, USER_REGISTRY_SETTINGS_KEY, 0, KEY_READ, &hKey );
|
|
if ( sc == ERROR_FILE_NOT_FOUND )
|
|
{
|
|
hr = S_FALSE;
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
//
|
|
// If we fail for any other reason log it and leave.
|
|
//
|
|
|
|
if ( sc != ERROR_SUCCESS )
|
|
{
|
|
LogMsg( L"[WIZ] RegOpenKeyEx() for %ws failed. (hr = %#08x)", USER_REGISTRY_SETTINGS_KEY, HRESULT_FROM_WIN32( TW32( sc ) ) );
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
//
|
|
// Now that the key is open we need to read the value.
|
|
//
|
|
|
|
sc = RegQueryValueExW( hKey, CONFIGURATION_TYPE, NULL, &dwType, (LPBYTE) &dwData, &cbData );
|
|
if ( sc == ERROR_FILE_NOT_FOUND )
|
|
{
|
|
//
|
|
// It's okay if the value is not found.
|
|
//
|
|
|
|
goto Cleanup;
|
|
} // if:
|
|
else if ( sc == ERROR_SUCCESS )
|
|
{
|
|
Assert( dwType == REG_DWORD )
|
|
|
|
//
|
|
// The value was present. Tell the caller if they cared to ask...
|
|
//
|
|
|
|
if ( pfValuePresentOut != NULL )
|
|
{
|
|
*pfValuePresentOut = TRUE;
|
|
} // if:
|
|
|
|
//
|
|
// If there was a stored value then we need to return it to the caller.
|
|
//
|
|
|
|
*pecsSettingOut = (EConfigurationSettings) dwData;
|
|
} // else if:
|
|
else
|
|
{
|
|
TW32( sc );
|
|
hr = HRESULT_FROM_WIN32( sc );
|
|
goto Cleanup;
|
|
} // else:
|
|
|
|
Cleanup:
|
|
|
|
if ( hKey != NULL )
|
|
{
|
|
RegCloseKey( hKey );
|
|
} // if:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgWizard::HrReadSettings
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgWizard::HrWriteSettings
|
|
//
|
|
// Description:
|
|
// Write the settings into the registry.
|
|
//
|
|
// Arguments:
|
|
// ecsSettingIn
|
|
// The setting to write.
|
|
//
|
|
// fDeleteValueIn
|
|
// Should the value be deleted and therefore stop being the default
|
|
// setting.
|
|
//
|
|
// Return Values:
|
|
// S_OK
|
|
// Success
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
HRESULT
|
|
CClusCfgWizard::HrWriteSettings(
|
|
EConfigurationSettings ecsSettingIn
|
|
, BOOL fDeleteValueIn // = FALSE
|
|
)
|
|
{
|
|
TraceFunc( "" );
|
|
|
|
HRESULT hr = S_OK;
|
|
DWORD sc;
|
|
HKEY hKey = NULL;
|
|
|
|
sc = RegCreateKeyExW( HKEY_CURRENT_USER, USER_REGISTRY_SETTINGS_KEY, NULL, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, NULL );
|
|
if ( sc != ERROR_SUCCESS )
|
|
{
|
|
hr = HRESULT_FROM_WIN32( TW32( sc ) );
|
|
LogMsg( L"[WIZ] RegCreateKeyExW() for %ws failed. (hr = %#08x)", USER_REGISTRY_SETTINGS_KEY, hr );
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
//
|
|
// Only save the data if we are not going to delete the value from the registry.
|
|
//
|
|
|
|
if ( fDeleteValueIn == FALSE )
|
|
{
|
|
//
|
|
// Now that the key is open we need to write the value.
|
|
//
|
|
|
|
sc = RegSetValueExW( hKey, CONFIGURATION_TYPE, NULL, REG_DWORD, (LPBYTE) &ecsSettingIn, sizeof( ecsSettingIn ) );
|
|
if ( sc != ERROR_SUCCESS )
|
|
{
|
|
hr = HRESULT_FROM_WIN32( TW32( sc ) );
|
|
goto Cleanup;
|
|
} // if:
|
|
} // if:
|
|
else
|
|
{
|
|
sc = RegDeleteValueW( hKey, CONFIGURATION_TYPE );
|
|
if ( ( sc != ERROR_SUCCESS ) && ( sc != ERROR_FILE_NOT_FOUND ) )
|
|
{
|
|
TW32( sc );
|
|
hr = HRESULT_FROM_WIN32( sc );
|
|
goto Cleanup;
|
|
} // if:
|
|
} // else:
|
|
|
|
Cleanup:
|
|
|
|
if ( hKey != NULL )
|
|
{
|
|
RegCloseKey( hKey );
|
|
} // if:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgWizard::HrWriteSettings
|
|
*/
|
|
|
|
//****************************************************************************
|
|
//
|
|
// INotifyUI
|
|
//
|
|
//****************************************************************************
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusCfgWizard::ObjectChanged
|
|
//
|
|
// Description:
|
|
//
|
|
// Arguments:
|
|
// cookieIn
|
|
//
|
|
// Return Values:
|
|
// S_OK
|
|
// Failure
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CClusCfgWizard::ObjectChanged(
|
|
OBJECTCOOKIE cookieIn
|
|
)
|
|
{
|
|
TraceFunc( "[INotifyUI]" );
|
|
|
|
HRESULT hr = S_OK;
|
|
HRESULT hrResult;
|
|
BOOL fSuccess;
|
|
|
|
if ( cookieIn == m_cookieCompletion )
|
|
{
|
|
THR( HrGetCompletionStatus( m_cookieCompletion, &hrResult ) );
|
|
|
|
fSuccess = SetEvent( m_hCancelCleanupEvent );
|
|
if ( fSuccess == FALSE )
|
|
{
|
|
hr = HRESULT_FROM_WIN32( TW32( GetLastError() ) );
|
|
} // if:
|
|
} // if:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CClusCfgWizard::ObjectChanged
|