Leaked source code of windows server 2003
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.
 
 
 
 
 
 

997 lines
23 KiB

//////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2000-2002 Microsoft Corporation
//
// Module Name:
// ClusDomainPage.cpp
//
// Maintained By:
// David Potter (DavidP) 31-JAN-2001
// Geoffrey Pease (GPease) 12-MAY-2000
//
//////////////////////////////////////////////////////////////////////////////
#include "Pch.h"
#include "ClusDomainPage.h"
#include "WizardUtils.h"
DEFINE_THISCLASS("CClusDomainPage");
//////////////////////////////////////////////////////////////////////////////
//++
//
// CClusDomainPage::CClusDomainPage
//
// Description:
// Constructor.
//
// Arguments:
// pccwIn - CClusCfgWizard
// ecamCreateAddModeIn - Creating cluster or adding nodes to cluster
// idsDescIn - Resource ID for the domain description string.
//
// Return Values:
// None.
//
// Remarks:
//
//--
//////////////////////////////////////////////////////////////////////////////
CClusDomainPage::CClusDomainPage(
CClusCfgWizard * pccwIn,
ECreateAddMode ecamCreateAddModeIn,
UINT idsDescIn
)
: m_pccw( pccwIn )
{
TraceFunc( "" );
Assert( pccwIn != NULL );
Assert( idsDescIn != 0 );
// m_hwnd
m_pccw->AddRef();
m_ecamCreateAddMode = ecamCreateAddModeIn;
m_idsDesc = idsDescIn;
if ( ( ecamCreateAddModeIn == camADDING )
&& ( m_pccw->FHasClusterName() )
&& ( !m_pccw->FDefaultedClusterDomain() ) )
{
//
// Don't show the cluster name/domain page if we are joining
// and the cluster name has been filled in by the caller.
//
m_fDisplayPage = FALSE;
}
else
{
m_fDisplayPage = TRUE;
}
m_cRef = 0;
m_ptgd = NULL;
TraceFuncExit();
} //*** CClusDomainPage::CClusDomainPage
//////////////////////////////////////////////////////////////////////////////
//++
//
// CClusDomainPage::~CClusDomainPage
//
// Description:
// Destructor.
//
// Arguments:
// None.
//
// Return Values:
// None.
//
// Remarks:
//
//--
//////////////////////////////////////////////////////////////////////////////
CClusDomainPage::~CClusDomainPage( void )
{
TraceFunc( "" );
if ( m_pccw != NULL )
{
m_pccw->Release();
}
if ( m_ptgd != NULL )
{
// Make sure we don't get called anymore.
THR( m_ptgd->SetCallback( NULL ) );
m_ptgd->Release();
}
Assert( m_cRef == 0 );
TraceFuncExit();
} //*** CClusDomainPage::~CClusDomainPage
//////////////////////////////////////////////////////////////////////////////
//++
//
// CClusDomainPage::OnInitDialog
//
// Description:
// Handle the WM_INITDIALOG window message.
//
// Arguments:
// None.
//
// Return Values:
// FALSE - Didn't set the focus.
//
// Remarks:
//
//--
//////////////////////////////////////////////////////////////////////////////
LRESULT
CClusDomainPage::OnInitDialog( void )
{
TraceFunc( "" );
HRESULT hr;
LRESULT lr = FALSE; // didn't set focus
BSTR bstrClusterName = NULL;
BSTR bstrClusterLabel = NULL;
BSTR bstrDomain = NULL;
BSTR bstrDomainDesc = NULL;
PCWSTR pwcszLabelToUse = NULL;
BSTR bstrNodeName = NULL;
IUnknown * punkTask = NULL;
//
// (jfranco, bugs #373331 and #480246) Limit cluster name length to max( MAX_CLUSTERNAME_LENGTH, INET_ADDRSTRLEN - 1 )
// Use INET_ADDRSTRLEN - 1 because INET_ADDRSTRLEN seems to include terminating null.
// According to MSDN, EM_(SET)LIMITTEXT does not return a value, so ignore what SendDlgItemMessage returns.
//
SendDlgItemMessage( m_hwnd, IDC_CLUSDOMAIN_E_CLUSTERNAME, EM_SETLIMITTEXT, max( MAX_CLUSTERNAME_LENGTH, INET_ADDRSTRLEN - 1 ), 0 );
//
// (jfranco, bug #462673) Limit cluster domain length to ADJUSTED_DNS_MAX_NAME_LENGTH
// According to MSDN, the return value of CB_LIMITTEXT is always true, so ignore what SendDlgItemMessage returns
//
SendDlgItemMessage( m_hwnd, IDC_CLUSDOMAIN_CB_DOMAIN, CB_LIMITTEXT, ADJUSTED_DNS_MAX_NAME_LENGTH, 0 );
//
// Kick off the GetDomains task.
//
hr = THR( m_pccw->HrCreateTask( TASK_GetDomains, &punkTask ) );
if ( FAILED( hr ) )
{
goto Cleanup;
}
//TraceMoveFromMemoryList( punkTask, g_GlobalMemoryList );
hr = THR( punkTask->TypeSafeQI( ITaskGetDomains, &m_ptgd ) );
if ( FAILED( hr ) )
{
goto Cleanup;
}
hr = THR( m_ptgd->SetCallback( static_cast< ITaskGetDomainsCallback * >( this ) ) );
if ( FAILED( hr ) )
{
goto Cleanup;
}
hr = THR( m_pccw->HrSubmitTask( m_ptgd ) );
if ( FAILED( hr ) )
{
goto Cleanup;
}
//
// If a cluster name has already been specified, set it to the page.
//
hr = STHR( m_pccw->get_ClusterName( &bstrClusterName ) );
if ( FAILED( hr ) )
{
goto Cleanup;
}
else if ( bstrClusterName != NULL )
{
TraceMemoryAddBSTR( bstrClusterName );
hr = STHR( HrIsValidFQN( bstrClusterName, true ) );
if ( FAILED( hr ) )
{
goto Cleanup;
}
else if ( hr == S_OK )
{
hr = THR( HrExtractPrefixFromFQN( bstrClusterName, &bstrClusterLabel ) );
if ( FAILED( hr ) )
{
goto Cleanup;
}
pwcszLabelToUse = bstrClusterLabel;
}
else
{
pwcszLabelToUse = bstrClusterName;
}
SetDlgItemText( m_hwnd, IDC_CLUSDOMAIN_E_CLUSTERNAME, pwcszLabelToUse );
if ( !m_pccw->FDefaultedClusterDomain() )
{
hr = STHR( m_pccw->HrGetClusterDomain( &bstrDomain ) );
if ( FAILED( hr ) )
{
goto Cleanup;
}
}
} // if: cluster name specified already
else
{
size_t cNodes = 0;
hr = THR( m_pccw->HrGetNodeCount( &cNodes ) );
if ( FAILED( hr ) )
{
goto Cleanup;
}
// If a node FQN has been specified, use its domain.
if ( cNodes > 0 )
{
hr = THR( m_pccw->HrGetNodeName( 0, &bstrNodeName ) );
if ( FAILED( hr ) )
{
goto Cleanup;
}
hr = STHR( HrIsValidFQN( bstrNodeName, true ) );
if ( FAILED( hr ) )
{
goto Cleanup;
}
else if ( hr == S_OK )
{
size_t idxDomain = 0;
hr = THR( HrFindDomainInFQN( bstrNodeName, &idxDomain ) );
if ( FAILED( hr ) )
{
goto Cleanup;
}
bstrDomain = TraceSysAllocString( ( bstrNodeName + idxDomain ) );
if ( bstrDomain == NULL )
{
hr = THR( E_OUTOFMEMORY );
goto Cleanup;
}
}
} // if the wizard already has some nodes.
if ( bstrDomain == NULL )
{
//
// Get the domain of the local computer.
//
hr = THR( HrGetComputerName(
ComputerNameDnsDomain
, &bstrDomain
, FALSE // fBestEffortIn
) );
if ( FAILED( hr ) )
{
goto Cleanup;
}
} // cNodes == 0 or node name is not fully qualified
} // else: don't have a cluster name
SetDlgItemText( m_hwnd, IDC_CLUSDOMAIN_CB_DOMAIN, ( bstrDomain == NULL? L"": bstrDomain ) );
//
// Set the text of the domain description control.
//
hr = HrLoadStringIntoBSTR( g_hInstance, m_idsDesc, &bstrDomainDesc );
if ( FAILED( hr ) )
{
goto Cleanup;
}
SetDlgItemText( m_hwnd, IDC_CLUSDOMAIN_S_DOMAIN_DESC, bstrDomainDesc );
Cleanup:
TraceSysFreeString( bstrClusterLabel );
TraceSysFreeString( bstrClusterName );
TraceSysFreeString( bstrDomainDesc );
TraceSysFreeString( bstrDomain );
TraceSysFreeString( bstrNodeName );
if ( punkTask != NULL )
{
punkTask->Release();
}
RETURN( lr );
} //*** CClusDomainPage::OnInitDialog
//////////////////////////////////////////////////////////////////////////////
//++
//
// CClusDomainPage::OnNotifySetActive
//
// Description:
//
// Arguments:
// None.
//
// Return Values:
// TRUE
//
// Remarks:
//
//--
//////////////////////////////////////////////////////////////////////////////
LRESULT
CClusDomainPage::OnNotifySetActive( void )
{
TraceFunc( "" );
LRESULT lr = TRUE;
if ( m_fDisplayPage )
{
lr = OnUpdateWizardButtons();
}
else
{
SetWindowLongPtr( m_hwnd, DWLP_MSGRESULT, -1 );
}
RETURN( lr );
} //*** CClusDomainPage::OnNotifySetActive
//////////////////////////////////////////////////////////////////////////////
//++
//
// CClusDomainPage::OnNotifyWizNext
//
// Description:
//
// Arguments:
// None.
//
// Return Values:
// TRUE
//
// Remarks:
//
//--
//////////////////////////////////////////////////////////////////////////////
LRESULT
CClusDomainPage::OnNotifyWizNext( void )
{
TraceFunc( "" );
HRESULT hr = S_OK;
LRESULT lr = TRUE;
BSTR bstrDomainName = NULL;
BSTR bstrClusterNameLabel = NULL;
BSTR bstrClusterFQN = NULL;
int idcFocus = 0;
PFN_LABEL_VALIDATOR pfnLabelValidator = ( m_ecamCreateAddMode == camCREATING? HrValidateClusterNameLabel: HrValidateFQNPrefix );
EFQNErrorOrigin efeo = feoSYSTEM;
// Get the cluster domain.
hr = THR( HrGetTrimmedText( GetDlgItem( m_hwnd, IDC_CLUSDOMAIN_CB_DOMAIN ), &bstrDomainName ) );
if ( hr != S_OK )
{
// Next is supposed to be disabled when control is empty.
goto Error;
}
// Get the cluster hostname label.
hr = THR( HrGetTrimmedText( GetDlgItem( m_hwnd, IDC_CLUSDOMAIN_E_CLUSTERNAME ), &bstrClusterNameLabel ) );
if ( hr != S_OK )
{
// Next is supposed to be disabled when control is empty.
goto Error;
}
// Weed out IP addresses when creating.
if ( m_ecamCreateAddMode == camCREATING )
{
hr = STHR( HrIsValidIPAddress( bstrClusterNameLabel ) );
if ( hr == S_OK )
{
MessageBoxFromStrings(
m_hwnd
, IDS_ERR_VALIDATING_NAME_TITLE
, IDS_ERR_CLUSTER_CREATE_IP_TEXT
, MB_OK | MB_ICONSTOP
);
goto Error;
}
else if ( FAILED( hr ) )
{
goto Error;
}
}
// Make the cluster FQN.
hr = THR( HrCreateFQN( m_hwnd, bstrClusterNameLabel, bstrDomainName, pfnLabelValidator, &bstrClusterFQN, &efeo ) );
if ( FAILED( hr ) )
{
if ( efeo == feoLABEL )
{
idcFocus = IDC_CLUSDOMAIN_E_CLUSTERNAME;
}
else if ( efeo == feoDOMAIN )
{
idcFocus = IDC_CLUSDOMAIN_CB_DOMAIN;
}
goto Error;
}
hr = STHR( m_pccw->HrSetClusterName( bstrClusterFQN, true ) );
if ( FAILED( hr ) )
{
THR( HrMessageBoxWithStatus(
m_hwnd
, IDS_ERR_CLUSTER_RENAME_TITLE
, IDS_ERR_CLUSTER_RENAME_TEXT
, hr
, 0
, MB_OK | MB_ICONSTOP
, NULL
) );
goto Error;
}
Cleanup:
TraceSysFreeString( bstrClusterFQN );
TraceSysFreeString( bstrDomainName );
TraceSysFreeString( bstrClusterNameLabel );
RETURN( lr );
Error:
if ( idcFocus != 0 )
{
SetFocus( GetDlgItem( m_hwnd, idcFocus ) );
}
// Don't go to the next page.
SetWindowLongPtr( m_hwnd, DWLP_MSGRESULT, -1 );
goto Cleanup;
} //*** CClusDomainPage::OnNotifyWizNext
//////////////////////////////////////////////////////////////////////////////
//++
//
// CClusDomainPage::OnNotifyQueryCancel
//
// Description:
//
// Arguments:
// None.
//
// Return Values:
// TRUE
//
// Remarks:
//
//--
//////////////////////////////////////////////////////////////////////////////
LRESULT
CClusDomainPage::OnNotifyQueryCancel( void )
{
TraceFunc( "" );
LRESULT lr = TRUE;
int iRet;
iRet = MessageBoxFromStrings( m_hwnd,
IDS_QUERY_CANCEL_TITLE,
IDS_QUERY_CANCEL_TEXT,
MB_YESNO
);
if ( iRet == IDNO )
{
SetWindowLongPtr( m_hwnd, DWLP_MSGRESULT, -1 );
}
RETURN( lr );
} //*** OnNotifyQueryCancel
//////////////////////////////////////////////////////////////////////////////
//++
//
// CClusDomainPage::OnNotify
//
// Description:
//
// Arguments:
// idCtrlIn
// pnmhdrIn
//
// Return Values:
// TRUE
// Other LRESULT values.
//
// Remarks:
//
//--
//////////////////////////////////////////////////////////////////////////////
LRESULT
CClusDomainPage::OnNotify(
WPARAM idCtrlIn,
LPNMHDR pnmhdrIn
)
{
TraceFunc( "" );
LRESULT lr = TRUE;
SetWindowLongPtr( m_hwnd, DWLP_MSGRESULT, 0 );
switch ( pnmhdrIn->code )
{
case PSN_SETACTIVE:
lr = OnNotifySetActive();
break;
case PSN_WIZNEXT:
lr = OnNotifyWizNext();
break;
case PSN_WIZBACK:
//
// Disable the wizard buttons.
//
PropSheet_SetWizButtons( GetParent( m_hwnd ), 0 );
break;
case PSN_QUERYCANCEL:
lr = OnNotifyQueryCancel();
break;
} // switch: notification code
RETURN( lr );
} //*** CClusDomainPage::OnNotify
//////////////////////////////////////////////////////////////////////////////
//++
//
// CClusDomainPage::OnCommand
//
// Description:
//
// Arguments:
// idNotificationIn
// idControlIn
// hwndSenderIn
//
// Return Values:
// TRUE
// FALSE
//
// Remarks:
//
//--
//////////////////////////////////////////////////////////////////////////////
LRESULT
CClusDomainPage::OnCommand(
UINT idNotificationIn,
UINT idControlIn,
HWND hwndSenderIn
)
{
TraceFunc( "" );
LRESULT lr = FALSE;
switch ( idControlIn )
{
case IDC_CLUSDOMAIN_E_CLUSTERNAME:
if ( idNotificationIn == EN_CHANGE )
{
lr = OnUpdateWizardButtons();
}
break;
case IDC_CLUSDOMAIN_CB_DOMAIN:
if ( ( idNotificationIn == CBN_EDITCHANGE ) || ( idNotificationIn == CBN_SELENDOK ) )
{
// KB: jfranco 24-oct-2001 bug 481636
// Need to update wizard buttons, but only after combo box has a chance to update itself.
if ( PostMessage( m_hwnd, WM_CCW_UPDATEBUTTONS, 0, 0 ) == 0 )
{
TW32( GetLastError() );
}
lr = TRUE;
}
break;
} // switch: control ID
RETURN( lr );
} //*** CClusDomainPage::OnCommand
//////////////////////////////////////////////////////////////////////////////
//++
//
// CClusDomainPage::OnUpdateWizardButtons
//
// Description:
//
// Arguments:
// None.
//
// Return Values:
// TRUE
//
// Remarks:
//
//--
//////////////////////////////////////////////////////////////////////////////
LRESULT
CClusDomainPage::OnUpdateWizardButtons( void )
{
TraceFunc( "" );
LRESULT lr = TRUE;
HRESULT hrName = S_OK;
HRESULT hrDomain = S_OK;
BSTR bstrName = NULL;
BSTR bstrDomain = NULL;
DWORD mEnabledButtons = PSWIZB_BACK;
hrName = STHR( HrGetTrimmedText( GetDlgItem( m_hwnd, IDC_CLUSDOMAIN_E_CLUSTERNAME ), &bstrName ) );
hrDomain = STHR( HrGetTrimmedText( GetDlgItem( m_hwnd, IDC_CLUSDOMAIN_CB_DOMAIN ), &bstrDomain ) );
if ( ( hrName == S_OK ) && ( hrDomain == S_OK ) )
{
mEnabledButtons |= PSWIZB_NEXT;
}
PropSheet_SetWizButtons( GetParent( m_hwnd ), mEnabledButtons );
TraceSysFreeString( bstrName );
TraceSysFreeString( bstrDomain );
RETURN( lr );
} //*** CClusDomainPage::OnUpdateWizardButtons
//////////////////////////////////////////////////////////////////////////////
//++
//
// static
// CALLBACK
// CClusDomainPage::S_DlgProc
//
// Description:
// Dialog proc for this page.
//
// Arguments:
// hDlgIn
// MsgIn
// wParam
// lParam
//
// Return Values:
// FALSE
// Other LRESULT values.
//
// Remarks:
//
//--
//////////////////////////////////////////////////////////////////////////////
INT_PTR
CALLBACK
CClusDomainPage::S_DlgProc(
HWND hDlgIn,
UINT MsgIn,
WPARAM wParam,
LPARAM lParam
)
{
// Don't do TraceFunc because every mouse movement
// will cause this function to be called.
WndMsg( hDlgIn, MsgIn, wParam, lParam );
LRESULT lr = FALSE;
CClusDomainPage * pPage = reinterpret_cast< CClusDomainPage *> ( GetWindowLongPtr( hDlgIn, GWLP_USERDATA ) );
if ( MsgIn == WM_INITDIALOG )
{
PROPSHEETPAGE * ppage = reinterpret_cast< PROPSHEETPAGE * >( lParam );
SetWindowLongPtr( hDlgIn, GWLP_USERDATA, (LPARAM) ppage->lParam );
pPage = reinterpret_cast< CClusDomainPage * >( ppage->lParam );
pPage->m_hwnd = hDlgIn;
}
if ( pPage != NULL )
{
Assert( hDlgIn == pPage->m_hwnd );
switch( MsgIn )
{
case WM_INITDIALOG:
lr = pPage->OnInitDialog();
break;
case WM_NOTIFY:
lr = pPage->OnNotify( wParam, reinterpret_cast< LPNMHDR >( lParam ) );
break;
case WM_COMMAND:
lr= pPage->OnCommand( HIWORD( wParam ), LOWORD( wParam ), (HWND) lParam );
break;
case WM_CCW_UPDATEBUTTONS:
lr = pPage->OnUpdateWizardButtons();
break;
// no default clause needed
} // switch: message
} // if: there is a page associated with the window
return lr;
} //*** CClusDomainPage::S_DlgProc
// ************************************************************************
//
// IUnknown
//
// ************************************************************************
//////////////////////////////////////////////////////////////////////////////
//++
//
// CClusDomainPage::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:
// This QI implementation does not use the interface tracing macros due
// to problems with CITracker's marshalling support.
//
//--
//////////////////////////////////////////////////////////////////////////////
STDMETHODIMP
CClusDomainPage::QueryInterface(
REFIID riidIn
, LPVOID * ppvOut
)
{
TraceFunc( "" );
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_ITaskGetDomainsCallback ) )
{
*ppvOut = static_cast< ITaskGetDomainsCallback * >( this );
} // else if: ITaskGetDomainsCallback
else
{
*ppvOut = NULL;
hr = E_NOINTERFACE;
} // else
//
// Add a reference to the interface if successful.
//
if ( SUCCEEDED( hr ) )
{
((IUnknown *) *ppvOut)->AddRef();
} // if: success
Cleanup:
HRETURN( hr );
} //*** CClusDomainPage::QueryInterface
//////////////////////////////////////////////////////////////////////////////
//++
//
// CClusDomainPage::AddRef
//
// Description:
//
// Arguments:
// None.
//
// Return Values:
// New reference count.
//
// Remarks:
//
//--
//////////////////////////////////////////////////////////////////////////////
STDMETHODIMP_( ULONG )
CClusDomainPage::AddRef( void )
{
TraceFunc( "[IUnknown]" );
InterlockedIncrement( &m_cRef );
CRETURN( m_cRef );
} //*** CClusDomainPage::AddRef
//////////////////////////////////////////////////////////////////////////////
//++
//
// CClusDomainPage::Release
//
// Description:
//
// Arguments:
// None.
//
// Return Values:
// New reference count.
//
// Remarks:
//
//--
//////////////////////////////////////////////////////////////////////////////
STDMETHODIMP_( ULONG )
CClusDomainPage::Release( void )
{
TraceFunc( "[IUnknown]" );
LONG cRef;
cRef = InterlockedDecrement( &m_cRef );
if ( cRef == 0 )
{
// do nothing -- COM interface does not control object lifetime
}
CRETURN( cRef );
} //*** CClusDomainPage::Release
//****************************************************************************
//
// ITaskGetDomainsCallback
//
//****************************************************************************
//////////////////////////////////////////////////////////////////////////////
//++
//
// [ITaskGetDomainsCallback]
// CClusDomainPage::ReceiveDomainResult
//
// Description:
//
// Arguments:
// hrIn
//
// Return Values:
// S_OK
// Other HRESULT values.
//
// Remarks:
//
//--
//////////////////////////////////////////////////////////////////////////////
STDMETHODIMP
CClusDomainPage::ReceiveDomainResult(
HRESULT hrIn
)
{
TraceFunc( "[ITaskGetDomainsCallback]" );
HRESULT hr;
hr = THR( m_ptgd->SetCallback( NULL ) );
HRETURN( hr );
} //*** CClusDomainPage::ReceiveResult
//////////////////////////////////////////////////////////////////////////////
//++
//
// [ITaskGetDomainsCallback]
// CClusDomainPage::ReceiveDomainName
//
// Description:
//
// Arguments:
// bstrDomainIn
//
// Remarks:
//
//--
//////////////////////////////////////////////////////////////////////////////
STDMETHODIMP
CClusDomainPage::ReceiveDomainName(
LPCWSTR pcszDomainIn
)
{
TraceFunc( "[ITaskGetDomainsCallback]" );
HRESULT hr = S_OK;
ComboBox_AddString( GetDlgItem( m_hwnd, IDC_CLUSDOMAIN_CB_DOMAIN ), pcszDomainIn );
HRETURN( hr );
} //*** CClusDomainPage::ReceiveName