////////////////////////////////////////////////////////////////////////////// // // Copyright (c) 2000-2002 Microsoft Corporation // // Module Name: // CSAccountPage.cpp // // Maintained By: // David Potter (DavidP) 22-MAR-2001 // Geoffrey Pease (GPease) 12-MAY-2000 // ////////////////////////////////////////////////////////////////////////////// #include "Pch.h" #include "CSAccountPage.h" #include "WizardUtils.h" DEFINE_THISCLASS("CCSAccountPage"); ////////////////////////////////////////////////////////////////////////////// //++ // // CCSAccountPage::CCSAccountPage( // CClusCfgWizard * pccwIn, // ECreateAddMode ecamCreateAddModeIn, // BSTR * pbstrUsernameIn, // BSTR * pbstrPasswordIn, // BSTR * pbstrDomainIn, // BSTR * pbstrClusterNameIn // ) // //-- ////////////////////////////////////////////////////////////////////////////// CCSAccountPage::CCSAccountPage( CClusCfgWizard * pccwIn, ECreateAddMode ecamCreateAddModeIn, IClusCfgCredentials * pcccIn ) : m_pccw( pccwIn ) , m_pccc( pcccIn ) { TraceFunc( "" ); // m_hwnd Assert( pccwIn != NULL ); m_pccw->AddRef(); Assert( pcccIn != NULL ); m_pccc->AddRef(); m_ecamCreateAddMode = ecamCreateAddModeIn; m_cRef = 0; m_ptgd = NULL; TraceFuncExit(); } //*** CCSAccountPage::CCSAccountPage ////////////////////////////////////////////////////////////////////////////// //++ // // CCSAccountPage::~CCSAccountPage( void ) // //-- ////////////////////////////////////////////////////////////////////////////// CCSAccountPage::~CCSAccountPage( void ) { TraceFunc( "" ); if ( m_pccw != NULL ) { m_pccw->Release(); } if ( m_pccc != NULL ) { m_pccc->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(); } //*** CCSAccountPage::~CCSAccountPage ////////////////////////////////////////////////////////////////////////////// //++ // // CCSAccountPage::OnInitDialog // // Description: // Handle the WM_INITDIALOG message. // // Arguments: // None. // // Return Values: // FALSE // //-- ////////////////////////////////////////////////////////////////////////////// LRESULT CCSAccountPage::OnInitDialog( void ) { TraceFunc( "" ); HRESULT hr; BSTR bstrUser = NULL; BSTR bstrDomain = NULL; BSTR bstrPassword = NULL; IUnknown * punkTask = NULL; LRESULT lr = FALSE; // // (jfranco, bug #477671) Limit user name length to ADJUSTED_DNS_MAX_NAME_LENGTH // according to msdn, EM_(SET)LIMITTEXT does not return a value, so ignore what SendDlgItemMessage returns // SendDlgItemMessage( m_hwnd, IDC_CSACCOUNT_E_USERNAME, EM_SETLIMITTEXT, ADJUSTED_DNS_MAX_NAME_LENGTH, 0 ); // // (jfranco, bug #462673) Limit 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_CSACCOUNT_CB_DOMAIN, CB_LIMITTEXT, ADJUSTED_DNS_MAX_NAME_LENGTH, 0 ); // // Create the task to get the domains. // hr = THR( m_pccw->HrCreateTask( TASK_GetDomains, &punkTask ) ); if ( FAILED( hr ) ) { goto Cleanup; } 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; } // // Default to the script supplied information. // hr = THR( m_pccc->GetCredentials( &bstrUser, &bstrDomain, &bstrPassword ) ); if ( FAILED( hr ) ) { goto Cleanup; } SetDlgItemText( m_hwnd, IDC_CSACCOUNT_E_USERNAME, bstrUser ); SetDlgItemText( m_hwnd, IDC_CSACCOUNT_E_PASSWORD, bstrPassword ); SecureZeroMemory( bstrPassword, SysStringLen( bstrPassword ) * sizeof( *bstrPassword ) ); if ( SysStringLen( bstrDomain ) > 0 ) { SetDlgItemText( m_hwnd, IDC_CSACCOUNT_CB_DOMAIN, bstrDomain ); TraceMemoryAddBSTR( bstrDomain ); } else { // // Use the cluster's domain. // hr = THR( m_pccw->HrGetClusterDomain( &bstrDomain ) ); if ( FAILED( hr ) ) { goto Cleanup; } SetDlgItemText( m_hwnd, IDC_CSACCOUNT_CB_DOMAIN, bstrDomain ); } Cleanup: OnUpdateWizardButtons(); // Ignore return value because OnUpdateWizardButtons always returns true, but we want OnInitDialog to return false. if ( punkTask != NULL ) { punkTask->Release(); } SysFreeString( bstrUser ); TraceSysFreeString( bstrDomain ); SysFreeString( bstrPassword ); RETURN( lr ); } //*** CCSAccountPage::OnInitDialog ////////////////////////////////////////////////////////////////////////////// //++ // // LRESULT // CCSAccountPage::OnCommand( // UINT idNotificationIn, // UINT idControlIn, // HWND hwndSenderIn // ) // //-- ////////////////////////////////////////////////////////////////////////////// LRESULT CCSAccountPage::OnCommand( UINT idNotificationIn, UINT idControlIn, HWND hwndSenderIn ) { TraceFunc( "" ); LRESULT lr = FALSE; switch ( idControlIn ) { case IDC_CSACCOUNT_E_PASSWORD: case IDC_CSACCOUNT_E_USERNAME: if ( idNotificationIn == EN_CHANGE ) { lr = OnUpdateWizardButtons(); } break; case IDC_CSACCOUNT_CB_DOMAIN: if ( ( idNotificationIn == CBN_EDITCHANGE ) || ( idNotificationIn == CBN_SELENDOK ) ) { if ( PostMessage( m_hwnd, WM_CCW_UPDATEBUTTONS, 0, 0 ) == 0 ) { TW32( GetLastError() ); } lr = TRUE; } break; } RETURN( lr ); } //*** CCSAccountPage::OnCommand ////////////////////////////////////////////////////////////////////////////// //++ // // LRESULT // CCSAccountPage::OnUpdateWizardButtons( void ) // //-- ////////////////////////////////////////////////////////////////////////////// LRESULT CCSAccountPage::OnUpdateWizardButtons( void ) { TraceFunc( "" ); LRESULT lr = TRUE; HRESULT hr = S_OK; BSTR bstrName = NULL; BSTR bstrDomain = NULL; DWORD mEnabledButtons = PSWIZB_BACK; HWND hwndUser = GetDlgItem( m_hwnd, IDC_CSACCOUNT_E_USERNAME ); HWND hwndDomain = GetDlgItem( m_hwnd, IDC_CSACCOUNT_CB_DOMAIN ); BOOL fUserIsDNSName = FALSE; // // Password could be blank so don't count on it! // hr = STHR( HrGetPrincipalName( hwndUser, hwndDomain, &bstrName, &bstrDomain, &fUserIsDNSName ) ); if ( hr == S_OK ) { mEnabledButtons |= PSWIZB_NEXT; } PropSheet_SetWizButtons( GetParent( m_hwnd ), mEnabledButtons ); EnableWindow( hwndDomain, !fUserIsDNSName ); TraceSysFreeString( bstrName ); TraceSysFreeString( bstrDomain ); RETURN( lr ); } //*** CCSAccountPage::OnUpdateWizardButtons ////////////////////////////////////////////////////////////////////////////// //++ // // LRESULT // CCSAccountPage::OnNotifyQueryCancel( void ) // //-- ////////////////////////////////////////////////////////////////////////////// LRESULT CCSAccountPage::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 ); } // if: else { THR( m_pccw->HrLaunchCleanupTask() ); } // else: RETURN( lr ); } //*** CCSAccountPage::OnNotifyQueryCancel ////////////////////////////////////////////////////////////////////////////// //++ // // LRESULT // CCSAccountPage::OnNotifySetActive( void ) // //-- ////////////////////////////////////////////////////////////////////////////// LRESULT CCSAccountPage::OnNotifySetActive( void ) { TraceFunc( "" ); HRESULT hr; LRESULT lr = TRUE; IClusCfgClusterInfo * pccci = NULL; IClusCfgCredentials * piccc = NULL; BSTR bstrUsername = NULL; BSTR bstrDomain = NULL; if ( m_ecamCreateAddMode == camADDING ) { // // See if the cluster configuration information has something // different. // hr = THR( m_pccw->HrGetClusterObject( &pccci ) ); if ( FAILED( hr ) ) { goto Cleanup; } hr = THR( pccci->GetClusterServiceAccountCredentials( &piccc ) ); if ( FAILED( hr ) ) { goto Cleanup; } hr = THR( piccc->GetIdentity( &bstrUsername, &bstrDomain ) ); if ( FAILED( hr ) ) { goto Cleanup; } TraceMemoryAddBSTR( bstrUsername ); TraceMemoryAddBSTR( bstrDomain ); SetDlgItemText( m_hwnd, IDC_CSACCOUNT_E_USERNAME, bstrUsername ); SetDlgItemText( m_hwnd, IDC_CSACCOUNT_CB_DOMAIN, bstrDomain ); // // Disable the username and domain windows. // EnableWindow( GetDlgItem( m_hwnd, IDC_CSACCOUNT_E_USERNAME ), FALSE ); EnableWindow( GetDlgItem( m_hwnd, IDC_CSACCOUNT_CB_DOMAIN ), FALSE ); } Cleanup: lr = OnUpdateWizardButtons(); if ( piccc != NULL ) { piccc->Release(); } if ( pccci != NULL ) { pccci->Release(); } TraceSysFreeString( bstrUsername ); TraceSysFreeString( bstrDomain ); RETURN( lr ); } //*** CCSAccountPage::OnNotifySetActive ////////////////////////////////////////////////////////////////////////////// //++ // // LRESULT // CCSAccountPage::OnNotifyWizNext( void ) // //-- ////////////////////////////////////////////////////////////////////////////// LRESULT CCSAccountPage::OnNotifyWizNext( void ) { TraceFunc( "" ); HRESULT hr; HWND hwnd; DWORD dwLen; BSTR bstrUsername = NULL; BSTR bstrPassword = NULL; BSTR bstrDomain = NULL; LRESULT lr = TRUE; IClusCfgClusterInfo * pccci = NULL; IClusCfgCredentials * piccc = NULL; // // Get the user and domain names from the UI. // hr = THR( HrGetPrincipalName( GetDlgItem( m_hwnd, IDC_CSACCOUNT_E_USERNAME ) , GetDlgItem( m_hwnd, IDC_CSACCOUNT_CB_DOMAIN ) , &bstrUsername , &bstrDomain ) ); if ( hr != S_OK ) { goto Error; } // // Get the password from the UI. // hwnd = GetDlgItem( m_hwnd, IDC_CSACCOUNT_E_PASSWORD ); Assert( hwnd != NULL ); dwLen = GetWindowTextLength( hwnd ); bstrPassword = TraceSysAllocStringLen( NULL, dwLen ); if ( bstrPassword == NULL ) { goto OutOfMemory; } GetWindowText( hwnd, bstrPassword, dwLen + 1 ); THR( m_pccc->SetCredentials( bstrUsername, bstrDomain, bstrPassword ) ); SecureZeroMemory( bstrPassword, SysStringLen( bstrPassword ) * sizeof( *bstrPassword ) ); if ( FAILED( hr ) ) { goto Cleanup; } // // Get the cluster configuration info. // hr = THR( m_pccw->HrGetClusterObject( &pccci ) ); if ( FAILED( hr ) ) { goto Cleanup; } // // Set the cluster service account credentials... // hr = THR( pccci->GetClusterServiceAccountCredentials( &piccc ) ); if ( FAILED( hr ) ) { goto Error; } hr = THR( m_pccc->AssignTo( piccc ) ); if ( FAILED( hr ) ) { goto Error; } Cleanup: TraceSysFreeString( bstrUsername ); TraceSysFreeString( bstrPassword ); TraceSysFreeString( bstrDomain ); if ( piccc != NULL ) { piccc->Release(); } if ( pccci != NULL ) { pccci->Release(); } RETURN( lr ); Error: SetWindowLongPtr( m_hwnd, DWLP_MSGRESULT, -1 ); goto Cleanup; OutOfMemory: goto Error; } //*** CCSAccountPage::OnNotifyWizNext ////////////////////////////////////////////////////////////////////////////// //++ // // LRESULT // CCSAccountPage::OnNotify( // WPARAM idCtrlIn, // LPNMHDR pnmhdrIn // ) // //-- ////////////////////////////////////////////////////////////////////////////// LRESULT CCSAccountPage::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_QUERYCANCEL: lr = OnNotifyQueryCancel(); break; } RETURN( lr ); } //*** CCSAccountPage::OnNotify ////////////////////////////////////////////////////////////////////////////// //++ // // INT_PTR // CALLBACK // CCSAccountPage::S_DlgProc( // HWND hDlgIn, // UINT MsgIn, // WPARAM wParam, // LPARAM lParam // ) // //-- ////////////////////////////////////////////////////////////////////////////// INT_PTR CALLBACK CCSAccountPage::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; CCSAccountPage * pPage = reinterpret_cast< CCSAccountPage *> ( GetWindowLongPtr( hDlgIn, GWLP_USERDATA ) ); if ( MsgIn == WM_INITDIALOG ) { PROPSHEETPAGE * ppage = reinterpret_cast< PROPSHEETPAGE * >( lParam ); SetWindowLongPtr( hDlgIn, GWLP_USERDATA, (LPARAM) ppage->lParam ); pPage = reinterpret_cast< CCSAccountPage * >( 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 } } return lr; } //*** CCSAccountPage::S_DlgProc // ************************************************************************ // // IUnknown // // ************************************************************************ ////////////////////////////////////////////////////////////////////////////// //++ // // CCSAccountPage::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 CCSAccountPage::QueryInterface( REFIID riidIn , void ** ppvOut ) { TraceQIFunc( riidIn, ppvOut ); HRESULT hr = S_OK; // // Validate arguments. // Assert( ppvOut != NULL ); if ( ppvOut == NULL ) { hr = THR( E_POINTER ); goto Cleanup; } // // Handle known interfaces. // if ( IsEqualIID( riidIn, IID_IUnknown ) ) { *ppvOut = static_cast< ITaskGetDomainsCallback * >( this ); } // if: IUnknown else if ( IsEqualIID( riidIn, IID_ITaskGetDomainsCallback ) ) { *ppvOut = TraceInterface( __THISCLASS__, ITaskGetDomainsCallback, this, 0 ); } // 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: QIRETURN_IGNORESTDMARSHALLING( hr, riidIn ); } //*** CCSAccountPage::QueryInterface ////////////////////////////////////////////////////////////////////////////// //++ // // STDMETHODIMP_( ULONG ) // CCSAccountPage::AddRef // //-- ////////////////////////////////////////////////////////////////////////////// STDMETHODIMP_( ULONG ) CCSAccountPage::AddRef( void ) { TraceFunc( "[IUnknown]" ); InterlockedIncrement( &m_cRef ); CRETURN( m_cRef ); } //*** CCSAccountPage::AddRef ////////////////////////////////////////////////////////////////////////////// //++ // // STDMETHODIMP_( ULONG ) // CCSAccountPage::Release // //-- ////////////////////////////////////////////////////////////////////////////// STDMETHODIMP_( ULONG ) CCSAccountPage::Release( void ) { TraceFunc( "[IUnknown]" ); LONG cRef; cRef = InterlockedDecrement( &m_cRef ); if ( cRef == 0 ) { // do nothing -- COM interface does not control object lifetime } CRETURN( cRef ); } //*** CCSAccountPage::Release //**************************************************************************** // // ITaskGetDomainsCallback // //**************************************************************************** ////////////////////////////////////////////////////////////////////////////// //++ // // STDMETHODIMP // CCSAccountPage::ReceiveDomainResult( // HRESULT hrIn // ) // //-- ////////////////////////////////////////////////////////////////////////////// STDMETHODIMP CCSAccountPage::ReceiveDomainResult( HRESULT hrIn ) { TraceFunc( "[ITaskGetDomainsCallback]" ); HRESULT hr; hr = THR( m_ptgd->SetCallback( NULL ) ); HRETURN( hr ); } //*** CCSAccountPage::ReceiveResult ////////////////////////////////////////////////////////////////////////////// //++ // // STDMETHODIMP // CCSAccountPage::ReceiveDomainName( // LPCWSTR pcszDomainIn // ) // //-- ////////////////////////////////////////////////////////////////////////////// STDMETHODIMP CCSAccountPage::ReceiveDomainName( LPCWSTR pcszDomainIn ) { TraceFunc( "[ITaskGetDomainsCallback]" ); HRESULT hr = S_OK; ComboBox_AddString( GetDlgItem( m_hwnd, IDC_CSACCOUNT_CB_DOMAIN ), pcszDomainIn ); HRETURN( hr ); } //*** CCSAccountPage::ReceiveName