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.
592 lines
18 KiB
592 lines
18 KiB
//
|
|
// propgeneral.cpp: general property sheet dialog proc
|
|
// This is Tab A
|
|
//
|
|
// Copyright (C) Microsoft Corporation 2000
|
|
// (nadima)
|
|
//
|
|
|
|
#include "stdafx.h"
|
|
|
|
|
|
#define TRC_GROUP TRC_GROUP_UI
|
|
#define TRC_FILE "propgeneral"
|
|
#include <atrcapi.h>
|
|
|
|
#include "propgeneral.h"
|
|
#include "sh.h"
|
|
|
|
#include "browsedlg.h"
|
|
#include "rdpfstore.h"
|
|
|
|
#define DUMMY_PASSWORD_TEXT TEXT("*||||||||@")
|
|
|
|
CPropGeneral* CPropGeneral::_pPropGeneralInstance = NULL;
|
|
|
|
|
|
//
|
|
// Controls that need to be disabled/enabled
|
|
// during connection (for progress animation)
|
|
//
|
|
CTL_ENABLE connectingDisableCtlsPGeneral[] = {
|
|
{IDC_GENERAL_COMBO_SERVERS, FALSE},
|
|
{IDC_GENERAL_EDIT_USERNAME, FALSE},
|
|
{IDC_GENERAL_EDIT_PASSWORD, FALSE},
|
|
{IDC_STATIC_PASSWORD, FALSE},
|
|
{IDC_GENERAL_EDIT_DOMAIN, FALSE},
|
|
{IDC_GENERAL_CHECK_SAVE_PASSWORD, FALSE},
|
|
{IDC_BUTTON_SAVE, FALSE},
|
|
{IDC_BUTTON_OPEN, FALSE}};
|
|
|
|
const UINT numConnectingDisableCtlsPGeneral =
|
|
sizeof(connectingDisableCtlsPGeneral)/
|
|
sizeof(connectingDisableCtlsPGeneral[0]);
|
|
|
|
|
|
CPropGeneral::CPropGeneral(HINSTANCE hInstance, CTscSettings* pTscSet, CSH* pSh) :
|
|
_pSh(pSh)
|
|
{
|
|
DC_BEGIN_FN("CPropGeneral");
|
|
_hInstance = hInstance;
|
|
CPropGeneral::_pPropGeneralInstance = this;
|
|
|
|
_pTscSet = pTscSet;
|
|
TRC_ASSERT(_pTscSet, (TB,_T("_pTscSet is null")));
|
|
TRC_ASSERT(_pSh, (TB,_T("_pSh is null")));
|
|
|
|
LoadGeneralPgStrings();
|
|
|
|
DC_END_FN();
|
|
}
|
|
|
|
CPropGeneral::~CPropGeneral()
|
|
{
|
|
CPropGeneral::_pPropGeneralInstance = NULL;
|
|
}
|
|
|
|
INT_PTR CALLBACK CPropGeneral::StaticPropPgGeneralDialogProc(HWND hwndDlg,
|
|
UINT uMsg,
|
|
WPARAM wParam,
|
|
LPARAM lParam)
|
|
{
|
|
//
|
|
// Delegate to appropriate instance (only works for single instance dialogs)
|
|
//
|
|
DC_BEGIN_FN("StaticDialogBoxProc");
|
|
DCINT retVal = 0;
|
|
|
|
TRC_ASSERT(_pPropGeneralInstance,
|
|
(TB, _T("Logon dlg has NULL static inst ptr\n")));
|
|
retVal = _pPropGeneralInstance->PropPgGeneralDialogProc( hwndDlg, uMsg,
|
|
wParam, lParam);
|
|
|
|
DC_END_FN();
|
|
return retVal;
|
|
}
|
|
|
|
|
|
INT_PTR CALLBACK CPropGeneral::PropPgGeneralDialogProc (
|
|
HWND hwndDlg, UINT uMsg,
|
|
WPARAM wParam, LPARAM lParam)
|
|
{
|
|
DC_BEGIN_FN("PropPgGeneralDialogProc");
|
|
|
|
switch(uMsg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
{
|
|
//
|
|
// Position the dialog within the tab
|
|
//
|
|
SetWindowPos( hwndDlg, HWND_TOP,
|
|
_rcTabDispayArea.left, _rcTabDispayArea.top,
|
|
_rcTabDispayArea.right - _rcTabDispayArea.left,
|
|
_rcTabDispayArea.bottom - _rcTabDispayArea.top,
|
|
0);
|
|
|
|
//
|
|
// Setup username edit box
|
|
//
|
|
SetDlgItemText(hwndDlg, IDC_GENERAL_EDIT_USERNAME,
|
|
(PDCTCHAR) _pTscSet->GetLogonUserName());
|
|
|
|
//
|
|
// Setup the server combo box
|
|
//
|
|
HWND hwndSrvCombo = GetDlgItem(hwndDlg,IDC_GENERAL_COMBO_SERVERS);
|
|
CSH::InitServerAutoCmplCombo( _pTscSet, hwndSrvCombo);
|
|
|
|
//
|
|
// Update server combo edit field
|
|
//
|
|
SetDlgItemText(hwndDlg, IDC_GENERAL_COMBO_SERVERS,
|
|
_pTscSet->GetFlatConnectString());
|
|
|
|
//Domain
|
|
SendDlgItemMessage(hwndDlg,
|
|
IDC_GENERAL_EDIT_DOMAIN,
|
|
EM_LIMITTEXT,
|
|
SH_MAX_DOMAIN_LENGTH-1,
|
|
0);
|
|
SetDlgItemText(hwndDlg, IDC_GENERAL_EDIT_DOMAIN,
|
|
_pTscSet->GetDomain());
|
|
|
|
//password
|
|
SendDlgItemMessage(hwndDlg,
|
|
IDC_GENERAL_EDIT_PASSWORD,
|
|
EM_LIMITTEXT,
|
|
SH_MAX_PASSWORD_LENGTH-1,
|
|
0);
|
|
|
|
#ifdef OS_WINCE
|
|
SendDlgItemMessage(hwndDlg,
|
|
IDC_GENERAL_COMBO_SERVERS,
|
|
EM_LIMITTEXT,
|
|
SH_MAX_ADDRESS_LENGTH-1,
|
|
0);
|
|
|
|
SendDlgItemMessage(hwndDlg,
|
|
IDC_GENERAL_EDIT_USERNAME,
|
|
EM_LIMITTEXT,
|
|
SH_MAX_USERNAME_LENGTH-1,
|
|
0);
|
|
#endif
|
|
|
|
//
|
|
// We're using an encrypted password directly from
|
|
// the tscsettings, fill in the edit well with dummy
|
|
// characters. This is to avoid having to fill
|
|
// with the real password which can give a length
|
|
// indication.
|
|
//
|
|
// Have to be carefull though, if the user changed
|
|
// or added a password then we have a clear text
|
|
// password present.
|
|
//
|
|
|
|
BOOL bPrevPassEdited = _pTscSet->GetUIPasswordEdited();
|
|
if (_pTscSet->GetPasswordProvided() &&
|
|
!_pTscSet->GetUIPasswordEdited())
|
|
{
|
|
SetDlgItemText(hwndDlg, IDC_GENERAL_EDIT_PASSWORD,
|
|
DUMMY_PASSWORD_TEXT);
|
|
}
|
|
else
|
|
{
|
|
HRESULT hr;
|
|
TCHAR szClearPass[TSC_MAX_PASSLENGTH_TCHARS];
|
|
memset(szClearPass, 0, sizeof(szClearPass));
|
|
hr = _pTscSet->GetClearTextPass(szClearPass,
|
|
sizeof(szClearPass));
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
SetDlgItemText(hwndDlg, IDC_GENERAL_EDIT_PASSWORD,
|
|
szClearPass);
|
|
}
|
|
else
|
|
{
|
|
SetDlgItemText(hwndDlg, IDC_GENERAL_EDIT_PASSWORD,
|
|
_T(""));
|
|
}
|
|
|
|
// Wipe stack copy.
|
|
SecureZeroMemory( szClearPass, sizeof(szClearPass));
|
|
}
|
|
_pTscSet->SetUIPasswordEdited(bPrevPassEdited);
|
|
|
|
if (_pSh->IsCryptoAPIPresent())
|
|
{
|
|
CheckDlgButton(hwndDlg, IDC_GENERAL_CHECK_SAVE_PASSWORD,
|
|
(_pTscSet->GetSavePassword() ? BST_CHECKED : BST_UNCHECKED));
|
|
}
|
|
else
|
|
{
|
|
CheckDlgButton(hwndDlg, IDC_GENERAL_CHECK_SAVE_PASSWORD,
|
|
BST_UNCHECKED);
|
|
//
|
|
// Disable the save password checkbox if no crypto api (e.g 9x)
|
|
//
|
|
EnableWindow(GetDlgItem(hwndDlg,
|
|
IDC_GENERAL_CHECK_SAVE_PASSWORD),
|
|
FALSE);
|
|
}
|
|
|
|
OnChangeUserName( hwndDlg);
|
|
|
|
_pSh->SH_ThemeDialogWindow(hwndDlg, ETDT_ENABLETAB);
|
|
return TRUE;
|
|
}
|
|
break; //WM_INITDIALOG
|
|
|
|
case WM_SAVEPROPSHEET: //Intentional fallthru
|
|
case WM_DESTROY:
|
|
{
|
|
|
|
//
|
|
// Save fields for when page reactivates
|
|
//
|
|
DlgToSettings(hwndDlg);
|
|
}
|
|
break; //WM_DESTROY
|
|
|
|
case WM_TSC_ENABLECONTROLS:
|
|
{
|
|
//
|
|
// wParam is TRUE to enable controls,
|
|
// FALSE to disable them
|
|
//
|
|
CSH::EnableControls( hwndDlg,
|
|
connectingDisableCtlsPGeneral,
|
|
numConnectingDisableCtlsPGeneral,
|
|
wParam ? TRUE : FALSE);
|
|
}
|
|
break;
|
|
|
|
//
|
|
// On return to connection UI
|
|
// (e.g after a disconnection)
|
|
//
|
|
case WM_TSC_RETURNTOCONUI:
|
|
{
|
|
//
|
|
// Reset the server combo to force it to repaint
|
|
// this is a minor hack to fix the ComboBoxEx
|
|
// which doesn't want to repaint itself on return
|
|
// to the dialog.
|
|
//
|
|
HWND hwndSrvCombo = GetDlgItem(hwndDlg, IDC_GENERAL_COMBO_SERVERS);
|
|
SetWindowText( hwndSrvCombo, _pTscSet->GetFlatConnectString());
|
|
}
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
{
|
|
switch(DC_GET_WM_COMMAND_ID(wParam))
|
|
{
|
|
case IDC_GENERAL_COMBO_SERVERS:
|
|
{
|
|
//
|
|
// Bring up the brwse for servers dlg
|
|
// if the user chose the last item in the combo
|
|
//
|
|
if(HIWORD(wParam) == CBN_SELCHANGE)
|
|
{
|
|
CSH::HandleServerComboChange(
|
|
(HWND)lParam,
|
|
hwndDlg,
|
|
_hInstance,
|
|
(LPTSTR)_pTscSet->GetFlatConnectString()
|
|
);
|
|
}
|
|
|
|
}
|
|
break;
|
|
|
|
case IDC_BUTTON_OPEN:
|
|
{
|
|
OnLoad(hwndDlg);
|
|
}
|
|
break;
|
|
|
|
case IDC_BUTTON_SAVE:
|
|
{
|
|
OnSave(hwndDlg);
|
|
}
|
|
break;
|
|
|
|
case IDC_GENERAL_EDIT_USERNAME:
|
|
{
|
|
if(HIWORD(wParam) == EN_CHANGE)
|
|
{
|
|
OnChangeUserName(hwndDlg);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case IDC_GENERAL_EDIT_PASSWORD:
|
|
{
|
|
if(HIWORD(wParam) == EN_CHANGE)
|
|
{
|
|
_pTscSet->SetUIPasswordEdited(TRUE);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break; //WM_COMMAND
|
|
|
|
}
|
|
|
|
DC_END_FN();
|
|
return 0;
|
|
}
|
|
|
|
BOOL CPropGeneral::LoadGeneralPgStrings()
|
|
{
|
|
DC_BEGIN_FN("LoadGeneralPgStrings");
|
|
|
|
memset(_szFileTypeDescription, 0, sizeof(_szFileTypeDescription));
|
|
if(!LoadString(_hInstance,
|
|
UI_IDS_REMOTE_DESKTOP_FILES,
|
|
_szFileTypeDescription,
|
|
SIZECHAR(_szFileTypeDescription)))
|
|
{
|
|
TRC_ERR((TB, _T("Failed to load UI_IDS_REMOTE_DESKTOP_FILES")));
|
|
return FALSE;
|
|
}
|
|
|
|
DC_END_FN();
|
|
return TRUE;
|
|
}
|
|
|
|
//
|
|
// OnSave event handler
|
|
// returns bool indiciating error
|
|
//
|
|
BOOL CPropGeneral::OnSave(HWND hwndDlg)
|
|
{
|
|
DC_BEGIN_FN("OnSave");
|
|
|
|
//
|
|
// Bring up the save as dialog
|
|
// and if necessary, save the file
|
|
//
|
|
|
|
TCHAR szPath[MAX_PATH];
|
|
OPENFILENAME ofn;
|
|
int cchLen = 0;
|
|
memset(&ofn, 0, sizeof(ofn));
|
|
|
|
_tcsncpy(szPath, _pTscSet->GetFileName(), SIZECHAR(szPath)-1);
|
|
szPath[SIZECHAR(szPath)-1] = 0;
|
|
|
|
#ifdef OS_WINCE
|
|
ofn.lStructSize = sizeof( ofn );
|
|
#else
|
|
ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400;
|
|
#endif
|
|
|
|
ofn.hwndOwner = hwndDlg;
|
|
ofn.hInstance = _hInstance;
|
|
ofn.lpstrFile = szPath;
|
|
ofn.nMaxFile = SIZECHAR(szPath);
|
|
ofn.lpstrFilter = _szFileTypeDescription;
|
|
ofn.lpstrDefExt = RDP_FILE_EXTENSION_NODOT;
|
|
ofn.Flags = OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY;
|
|
|
|
BOOL fRet = FALSE;
|
|
if(GetSaveFileName(&ofn))
|
|
{
|
|
cchLen = _tcslen(szPath);
|
|
if(cchLen >= MAX_PATH - SIZECHAR(RDP_FILE_EXTENSION))
|
|
{
|
|
//
|
|
// If the path entered is too long, the common dlg
|
|
// will not truncate and not append the .RDP extension
|
|
// we don't want that so check and make the user
|
|
// enter a shorter path
|
|
//
|
|
LPTSTR sz = szPath + cchLen - SIZECHAR(RDP_FILE_EXTENSION);
|
|
if(_tcsicmp(sz, RDP_FILE_EXTENSION))
|
|
{
|
|
_pSh->SH_DisplayErrorBox(NULL,
|
|
UI_IDS_PATHTOLONG,
|
|
szPath);
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
DlgToSettings(hwndDlg);
|
|
|
|
CRdpFileStore rdpf;
|
|
if(rdpf.OpenStore(szPath))
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
hr = _pTscSet->SaveToStore(&rdpf);
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
if(rdpf.CommitStore())
|
|
{
|
|
//Save last filename
|
|
_pTscSet->SetFileName(szPath);
|
|
fRet = TRUE;
|
|
}
|
|
else
|
|
{
|
|
TRC_ERR((TB,_T("Unable to CommitStore settings")));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
TRC_ERR((TB,_T("Unable to save settings to store %d, %s"),
|
|
hr, szPath));
|
|
}
|
|
if(!fRet)
|
|
{
|
|
_pSh->SH_DisplayErrorBox(NULL,
|
|
UI_IDS_ERR_SAVE,
|
|
szPath);
|
|
}
|
|
|
|
rdpf.CloseStore();
|
|
return fRet;
|
|
}
|
|
else
|
|
{
|
|
TRC_ERR((TB,_T("Unable to OpenStore for save %s"), szPath));
|
|
_pSh->SH_DisplayErrorBox(NULL,
|
|
UI_IDS_ERR_OPEN_FILE,
|
|
szPath);
|
|
return FALSE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//User canceled out, this is not a failure
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
DC_END_FN();
|
|
}
|
|
|
|
BOOL CPropGeneral::OnLoad(HWND hwndDlg)
|
|
{
|
|
DC_BEGIN_FN("OnLoad");
|
|
|
|
//
|
|
// Bring up the Open dialog
|
|
// and if necessary, save the file
|
|
//
|
|
|
|
TCHAR szPath[MAX_PATH];
|
|
OPENFILENAME ofn;
|
|
memset(&ofn, 0, sizeof(ofn));
|
|
|
|
_tcsncpy(szPath, _pTscSet->GetFileName(), SIZECHAR(szPath)-1);
|
|
szPath[SIZECHAR(szPath)-1] = 0;
|
|
|
|
#ifdef OS_WINCE
|
|
ofn.lStructSize = sizeof( ofn );
|
|
#else
|
|
ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400;
|
|
#endif
|
|
|
|
ofn.hwndOwner = hwndDlg;
|
|
ofn.hInstance = _hInstance;
|
|
ofn.lpstrFile = szPath;
|
|
ofn.nMaxFile = SIZECHAR(szPath);
|
|
ofn.lpstrFilter = _szFileTypeDescription;
|
|
ofn.lpstrDefExt = TEXT("RDP");
|
|
ofn.Flags = OFN_OVERWRITEPROMPT | OFN_FILEMUSTEXIST;
|
|
|
|
BOOL fRet = FALSE;
|
|
if(GetOpenFileName(&ofn))
|
|
{
|
|
CRdpFileStore rdpf;
|
|
if(rdpf.OpenStore(szPath))
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
hr = _pTscSet->LoadFromStore(&rdpf);
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
//Save last filename
|
|
_pTscSet->SetFileName(szPath);
|
|
|
|
//Need to trigger an update of the current dialog
|
|
SendMessage(hwndDlg, WM_INITDIALOG, 0, 0);
|
|
fRet = TRUE;
|
|
}
|
|
else
|
|
{
|
|
TRC_ERR((TB,_T("Unable LoadFromStore %d, %s"), hr, szPath));
|
|
_pSh->SH_DisplayErrorBox(NULL,
|
|
UI_IDS_ERR_LOAD,
|
|
szPath);
|
|
}
|
|
|
|
rdpf.CloseStore();
|
|
return fRet;
|
|
}
|
|
else
|
|
{
|
|
TRC_ERR((TB,_T("Unable to OpenStore for load %s"), szPath));
|
|
_pSh->SH_DisplayErrorBox(NULL,
|
|
UI_IDS_ERR_OPEN_FILE,
|
|
szPath);
|
|
return FALSE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//User canceled out, this is not a failure
|
|
return TRUE;
|
|
}
|
|
|
|
DC_END_FN();
|
|
}
|
|
|
|
//
|
|
// Behave like winlogon for UPN
|
|
// Disable the Domain field if the user has entered an '@'
|
|
//
|
|
//
|
|
BOOL CPropGeneral::OnChangeUserName(HWND hwndDlg)
|
|
{
|
|
DC_BEGIN_FN("OnChangeUserName");
|
|
|
|
TCHAR szUserName[SH_MAX_USERNAME_LENGTH];
|
|
GetDlgItemText( hwndDlg, IDC_GENERAL_EDIT_USERNAME,
|
|
szUserName, SIZECHAR(szUserName));
|
|
|
|
BOOL fDisableDomain = FALSE;
|
|
if(!_tcsstr(szUserName, TEXT("@")))
|
|
{
|
|
fDisableDomain = TRUE;
|
|
}
|
|
EnableWindow(GetDlgItem(hwndDlg, IDC_GENERAL_EDIT_DOMAIN),
|
|
fDisableDomain);
|
|
|
|
DC_END_FN();
|
|
return TRUE;
|
|
}
|
|
|
|
void CPropGeneral::DlgToSettings(HWND hwndDlg)
|
|
{
|
|
TCHAR szServer[SH_MAX_ADDRESS_LENGTH];
|
|
TCHAR szDomain[SH_MAX_DOMAIN_LENGTH];
|
|
TCHAR szUserName[SH_MAX_USERNAME_LENGTH];
|
|
BOOL fSavePassword;
|
|
|
|
GetDlgItemText( hwndDlg, IDC_GENERAL_EDIT_USERNAME,
|
|
szUserName, SIZECHAR(szUserName));
|
|
_pTscSet->SetLogonUserName(szUserName);
|
|
|
|
GetDlgItemText( hwndDlg, IDC_GENERAL_COMBO_SERVERS,
|
|
szServer, SIZECHAR(szServer));
|
|
_pTscSet->SetConnectString(szServer);
|
|
|
|
|
|
//
|
|
// Pickup the password
|
|
//
|
|
if (_pTscSet->GetUIPasswordEdited())
|
|
{
|
|
TCHAR szClearPass[MAX_PATH];
|
|
GetDlgItemText(hwndDlg, IDC_GENERAL_EDIT_PASSWORD,
|
|
szClearPass, SIZECHAR(szClearPass));
|
|
_pTscSet->SetClearTextPass(szClearPass);
|
|
|
|
// Wipe stack copy.
|
|
SecureZeroMemory(szClearPass, sizeof(szClearPass));
|
|
}
|
|
|
|
fSavePassword = IsDlgButtonChecked(hwndDlg,
|
|
IDC_GENERAL_CHECK_SAVE_PASSWORD);
|
|
_pTscSet->SetSavePassword(fSavePassword);
|
|
|
|
GetDlgItemText(hwndDlg, IDC_GENERAL_EDIT_DOMAIN,
|
|
szDomain, SIZECHAR(szDomain));
|
|
_pTscSet->SetDomain(szDomain);
|
|
}
|
|
|