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.

592 lines
18 KiB

  1. //
  2. // propgeneral.cpp: general property sheet dialog proc
  3. // This is Tab A
  4. //
  5. // Copyright (C) Microsoft Corporation 2000
  6. // (nadima)
  7. //
  8. #include "stdafx.h"
  9. #define TRC_GROUP TRC_GROUP_UI
  10. #define TRC_FILE "propgeneral"
  11. #include <atrcapi.h>
  12. #include "propgeneral.h"
  13. #include "sh.h"
  14. #include "browsedlg.h"
  15. #include "rdpfstore.h"
  16. #define DUMMY_PASSWORD_TEXT TEXT("*||||||||@")
  17. CPropGeneral* CPropGeneral::_pPropGeneralInstance = NULL;
  18. //
  19. // Controls that need to be disabled/enabled
  20. // during connection (for progress animation)
  21. //
  22. CTL_ENABLE connectingDisableCtlsPGeneral[] = {
  23. {IDC_GENERAL_COMBO_SERVERS, FALSE},
  24. {IDC_GENERAL_EDIT_USERNAME, FALSE},
  25. {IDC_GENERAL_EDIT_PASSWORD, FALSE},
  26. {IDC_STATIC_PASSWORD, FALSE},
  27. {IDC_GENERAL_EDIT_DOMAIN, FALSE},
  28. {IDC_GENERAL_CHECK_SAVE_PASSWORD, FALSE},
  29. {IDC_BUTTON_SAVE, FALSE},
  30. {IDC_BUTTON_OPEN, FALSE}};
  31. const UINT numConnectingDisableCtlsPGeneral =
  32. sizeof(connectingDisableCtlsPGeneral)/
  33. sizeof(connectingDisableCtlsPGeneral[0]);
  34. CPropGeneral::CPropGeneral(HINSTANCE hInstance, CTscSettings* pTscSet, CSH* pSh) :
  35. _pSh(pSh)
  36. {
  37. DC_BEGIN_FN("CPropGeneral");
  38. _hInstance = hInstance;
  39. CPropGeneral::_pPropGeneralInstance = this;
  40. _pTscSet = pTscSet;
  41. TRC_ASSERT(_pTscSet, (TB,_T("_pTscSet is null")));
  42. TRC_ASSERT(_pSh, (TB,_T("_pSh is null")));
  43. LoadGeneralPgStrings();
  44. DC_END_FN();
  45. }
  46. CPropGeneral::~CPropGeneral()
  47. {
  48. CPropGeneral::_pPropGeneralInstance = NULL;
  49. }
  50. INT_PTR CALLBACK CPropGeneral::StaticPropPgGeneralDialogProc(HWND hwndDlg,
  51. UINT uMsg,
  52. WPARAM wParam,
  53. LPARAM lParam)
  54. {
  55. //
  56. // Delegate to appropriate instance (only works for single instance dialogs)
  57. //
  58. DC_BEGIN_FN("StaticDialogBoxProc");
  59. DCINT retVal = 0;
  60. TRC_ASSERT(_pPropGeneralInstance,
  61. (TB, _T("Logon dlg has NULL static inst ptr\n")));
  62. retVal = _pPropGeneralInstance->PropPgGeneralDialogProc( hwndDlg, uMsg,
  63. wParam, lParam);
  64. DC_END_FN();
  65. return retVal;
  66. }
  67. INT_PTR CALLBACK CPropGeneral::PropPgGeneralDialogProc (
  68. HWND hwndDlg, UINT uMsg,
  69. WPARAM wParam, LPARAM lParam)
  70. {
  71. DC_BEGIN_FN("PropPgGeneralDialogProc");
  72. switch(uMsg)
  73. {
  74. case WM_INITDIALOG:
  75. {
  76. //
  77. // Position the dialog within the tab
  78. //
  79. SetWindowPos( hwndDlg, HWND_TOP,
  80. _rcTabDispayArea.left, _rcTabDispayArea.top,
  81. _rcTabDispayArea.right - _rcTabDispayArea.left,
  82. _rcTabDispayArea.bottom - _rcTabDispayArea.top,
  83. 0);
  84. //
  85. // Setup username edit box
  86. //
  87. SetDlgItemText(hwndDlg, IDC_GENERAL_EDIT_USERNAME,
  88. (PDCTCHAR) _pTscSet->GetLogonUserName());
  89. //
  90. // Setup the server combo box
  91. //
  92. HWND hwndSrvCombo = GetDlgItem(hwndDlg,IDC_GENERAL_COMBO_SERVERS);
  93. CSH::InitServerAutoCmplCombo( _pTscSet, hwndSrvCombo);
  94. //
  95. // Update server combo edit field
  96. //
  97. SetDlgItemText(hwndDlg, IDC_GENERAL_COMBO_SERVERS,
  98. _pTscSet->GetFlatConnectString());
  99. //Domain
  100. SendDlgItemMessage(hwndDlg,
  101. IDC_GENERAL_EDIT_DOMAIN,
  102. EM_LIMITTEXT,
  103. SH_MAX_DOMAIN_LENGTH-1,
  104. 0);
  105. SetDlgItemText(hwndDlg, IDC_GENERAL_EDIT_DOMAIN,
  106. _pTscSet->GetDomain());
  107. //password
  108. SendDlgItemMessage(hwndDlg,
  109. IDC_GENERAL_EDIT_PASSWORD,
  110. EM_LIMITTEXT,
  111. SH_MAX_PASSWORD_LENGTH-1,
  112. 0);
  113. #ifdef OS_WINCE
  114. SendDlgItemMessage(hwndDlg,
  115. IDC_GENERAL_COMBO_SERVERS,
  116. EM_LIMITTEXT,
  117. SH_MAX_ADDRESS_LENGTH-1,
  118. 0);
  119. SendDlgItemMessage(hwndDlg,
  120. IDC_GENERAL_EDIT_USERNAME,
  121. EM_LIMITTEXT,
  122. SH_MAX_USERNAME_LENGTH-1,
  123. 0);
  124. #endif
  125. //
  126. // We're using an encrypted password directly from
  127. // the tscsettings, fill in the edit well with dummy
  128. // characters. This is to avoid having to fill
  129. // with the real password which can give a length
  130. // indication.
  131. //
  132. // Have to be carefull though, if the user changed
  133. // or added a password then we have a clear text
  134. // password present.
  135. //
  136. BOOL bPrevPassEdited = _pTscSet->GetUIPasswordEdited();
  137. if (_pTscSet->GetPasswordProvided() &&
  138. !_pTscSet->GetUIPasswordEdited())
  139. {
  140. SetDlgItemText(hwndDlg, IDC_GENERAL_EDIT_PASSWORD,
  141. DUMMY_PASSWORD_TEXT);
  142. }
  143. else
  144. {
  145. HRESULT hr;
  146. TCHAR szClearPass[TSC_MAX_PASSLENGTH_TCHARS];
  147. memset(szClearPass, 0, sizeof(szClearPass));
  148. hr = _pTscSet->GetClearTextPass(szClearPass,
  149. sizeof(szClearPass));
  150. if (SUCCEEDED(hr))
  151. {
  152. SetDlgItemText(hwndDlg, IDC_GENERAL_EDIT_PASSWORD,
  153. szClearPass);
  154. }
  155. else
  156. {
  157. SetDlgItemText(hwndDlg, IDC_GENERAL_EDIT_PASSWORD,
  158. _T(""));
  159. }
  160. // Wipe stack copy.
  161. SecureZeroMemory( szClearPass, sizeof(szClearPass));
  162. }
  163. _pTscSet->SetUIPasswordEdited(bPrevPassEdited);
  164. if (_pSh->IsCryptoAPIPresent())
  165. {
  166. CheckDlgButton(hwndDlg, IDC_GENERAL_CHECK_SAVE_PASSWORD,
  167. (_pTscSet->GetSavePassword() ? BST_CHECKED : BST_UNCHECKED));
  168. }
  169. else
  170. {
  171. CheckDlgButton(hwndDlg, IDC_GENERAL_CHECK_SAVE_PASSWORD,
  172. BST_UNCHECKED);
  173. //
  174. // Disable the save password checkbox if no crypto api (e.g 9x)
  175. //
  176. EnableWindow(GetDlgItem(hwndDlg,
  177. IDC_GENERAL_CHECK_SAVE_PASSWORD),
  178. FALSE);
  179. }
  180. OnChangeUserName( hwndDlg);
  181. _pSh->SH_ThemeDialogWindow(hwndDlg, ETDT_ENABLETAB);
  182. return TRUE;
  183. }
  184. break; //WM_INITDIALOG
  185. case WM_SAVEPROPSHEET: //Intentional fallthru
  186. case WM_DESTROY:
  187. {
  188. //
  189. // Save fields for when page reactivates
  190. //
  191. DlgToSettings(hwndDlg);
  192. }
  193. break; //WM_DESTROY
  194. case WM_TSC_ENABLECONTROLS:
  195. {
  196. //
  197. // wParam is TRUE to enable controls,
  198. // FALSE to disable them
  199. //
  200. CSH::EnableControls( hwndDlg,
  201. connectingDisableCtlsPGeneral,
  202. numConnectingDisableCtlsPGeneral,
  203. wParam ? TRUE : FALSE);
  204. }
  205. break;
  206. //
  207. // On return to connection UI
  208. // (e.g after a disconnection)
  209. //
  210. case WM_TSC_RETURNTOCONUI:
  211. {
  212. //
  213. // Reset the server combo to force it to repaint
  214. // this is a minor hack to fix the ComboBoxEx
  215. // which doesn't want to repaint itself on return
  216. // to the dialog.
  217. //
  218. HWND hwndSrvCombo = GetDlgItem(hwndDlg, IDC_GENERAL_COMBO_SERVERS);
  219. SetWindowText( hwndSrvCombo, _pTscSet->GetFlatConnectString());
  220. }
  221. break;
  222. case WM_COMMAND:
  223. {
  224. switch(DC_GET_WM_COMMAND_ID(wParam))
  225. {
  226. case IDC_GENERAL_COMBO_SERVERS:
  227. {
  228. //
  229. // Bring up the brwse for servers dlg
  230. // if the user chose the last item in the combo
  231. //
  232. if(HIWORD(wParam) == CBN_SELCHANGE)
  233. {
  234. CSH::HandleServerComboChange(
  235. (HWND)lParam,
  236. hwndDlg,
  237. _hInstance,
  238. (LPTSTR)_pTscSet->GetFlatConnectString()
  239. );
  240. }
  241. }
  242. break;
  243. case IDC_BUTTON_OPEN:
  244. {
  245. OnLoad(hwndDlg);
  246. }
  247. break;
  248. case IDC_BUTTON_SAVE:
  249. {
  250. OnSave(hwndDlg);
  251. }
  252. break;
  253. case IDC_GENERAL_EDIT_USERNAME:
  254. {
  255. if(HIWORD(wParam) == EN_CHANGE)
  256. {
  257. OnChangeUserName(hwndDlg);
  258. }
  259. }
  260. break;
  261. case IDC_GENERAL_EDIT_PASSWORD:
  262. {
  263. if(HIWORD(wParam) == EN_CHANGE)
  264. {
  265. _pTscSet->SetUIPasswordEdited(TRUE);
  266. }
  267. }
  268. break;
  269. }
  270. }
  271. break; //WM_COMMAND
  272. }
  273. DC_END_FN();
  274. return 0;
  275. }
  276. BOOL CPropGeneral::LoadGeneralPgStrings()
  277. {
  278. DC_BEGIN_FN("LoadGeneralPgStrings");
  279. memset(_szFileTypeDescription, 0, sizeof(_szFileTypeDescription));
  280. if(!LoadString(_hInstance,
  281. UI_IDS_REMOTE_DESKTOP_FILES,
  282. _szFileTypeDescription,
  283. SIZECHAR(_szFileTypeDescription)))
  284. {
  285. TRC_ERR((TB, _T("Failed to load UI_IDS_REMOTE_DESKTOP_FILES")));
  286. return FALSE;
  287. }
  288. DC_END_FN();
  289. return TRUE;
  290. }
  291. //
  292. // OnSave event handler
  293. // returns bool indiciating error
  294. //
  295. BOOL CPropGeneral::OnSave(HWND hwndDlg)
  296. {
  297. DC_BEGIN_FN("OnSave");
  298. //
  299. // Bring up the save as dialog
  300. // and if necessary, save the file
  301. //
  302. TCHAR szPath[MAX_PATH];
  303. OPENFILENAME ofn;
  304. int cchLen = 0;
  305. memset(&ofn, 0, sizeof(ofn));
  306. _tcsncpy(szPath, _pTscSet->GetFileName(), SIZECHAR(szPath)-1);
  307. szPath[SIZECHAR(szPath)-1] = 0;
  308. #ifdef OS_WINCE
  309. ofn.lStructSize = sizeof( ofn );
  310. #else
  311. ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400;
  312. #endif
  313. ofn.hwndOwner = hwndDlg;
  314. ofn.hInstance = _hInstance;
  315. ofn.lpstrFile = szPath;
  316. ofn.nMaxFile = SIZECHAR(szPath);
  317. ofn.lpstrFilter = _szFileTypeDescription;
  318. ofn.lpstrDefExt = RDP_FILE_EXTENSION_NODOT;
  319. ofn.Flags = OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY;
  320. BOOL fRet = FALSE;
  321. if(GetSaveFileName(&ofn))
  322. {
  323. cchLen = _tcslen(szPath);
  324. if(cchLen >= MAX_PATH - SIZECHAR(RDP_FILE_EXTENSION))
  325. {
  326. //
  327. // If the path entered is too long, the common dlg
  328. // will not truncate and not append the .RDP extension
  329. // we don't want that so check and make the user
  330. // enter a shorter path
  331. //
  332. LPTSTR sz = szPath + cchLen - SIZECHAR(RDP_FILE_EXTENSION);
  333. if(_tcsicmp(sz, RDP_FILE_EXTENSION))
  334. {
  335. _pSh->SH_DisplayErrorBox(NULL,
  336. UI_IDS_PATHTOLONG,
  337. szPath);
  338. return FALSE;
  339. }
  340. }
  341. DlgToSettings(hwndDlg);
  342. CRdpFileStore rdpf;
  343. if(rdpf.OpenStore(szPath))
  344. {
  345. HRESULT hr = E_FAIL;
  346. hr = _pTscSet->SaveToStore(&rdpf);
  347. if(SUCCEEDED(hr))
  348. {
  349. if(rdpf.CommitStore())
  350. {
  351. //Save last filename
  352. _pTscSet->SetFileName(szPath);
  353. fRet = TRUE;
  354. }
  355. else
  356. {
  357. TRC_ERR((TB,_T("Unable to CommitStore settings")));
  358. }
  359. }
  360. else
  361. {
  362. TRC_ERR((TB,_T("Unable to save settings to store %d, %s"),
  363. hr, szPath));
  364. }
  365. if(!fRet)
  366. {
  367. _pSh->SH_DisplayErrorBox(NULL,
  368. UI_IDS_ERR_SAVE,
  369. szPath);
  370. }
  371. rdpf.CloseStore();
  372. return fRet;
  373. }
  374. else
  375. {
  376. TRC_ERR((TB,_T("Unable to OpenStore for save %s"), szPath));
  377. _pSh->SH_DisplayErrorBox(NULL,
  378. UI_IDS_ERR_OPEN_FILE,
  379. szPath);
  380. return FALSE;
  381. }
  382. }
  383. else
  384. {
  385. //User canceled out, this is not a failure
  386. return TRUE;
  387. }
  388. DC_END_FN();
  389. }
  390. BOOL CPropGeneral::OnLoad(HWND hwndDlg)
  391. {
  392. DC_BEGIN_FN("OnLoad");
  393. //
  394. // Bring up the Open dialog
  395. // and if necessary, save the file
  396. //
  397. TCHAR szPath[MAX_PATH];
  398. OPENFILENAME ofn;
  399. memset(&ofn, 0, sizeof(ofn));
  400. _tcsncpy(szPath, _pTscSet->GetFileName(), SIZECHAR(szPath)-1);
  401. szPath[SIZECHAR(szPath)-1] = 0;
  402. #ifdef OS_WINCE
  403. ofn.lStructSize = sizeof( ofn );
  404. #else
  405. ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400;
  406. #endif
  407. ofn.hwndOwner = hwndDlg;
  408. ofn.hInstance = _hInstance;
  409. ofn.lpstrFile = szPath;
  410. ofn.nMaxFile = SIZECHAR(szPath);
  411. ofn.lpstrFilter = _szFileTypeDescription;
  412. ofn.lpstrDefExt = TEXT("RDP");
  413. ofn.Flags = OFN_OVERWRITEPROMPT | OFN_FILEMUSTEXIST;
  414. BOOL fRet = FALSE;
  415. if(GetOpenFileName(&ofn))
  416. {
  417. CRdpFileStore rdpf;
  418. if(rdpf.OpenStore(szPath))
  419. {
  420. HRESULT hr = E_FAIL;
  421. hr = _pTscSet->LoadFromStore(&rdpf);
  422. if(SUCCEEDED(hr))
  423. {
  424. //Save last filename
  425. _pTscSet->SetFileName(szPath);
  426. //Need to trigger an update of the current dialog
  427. SendMessage(hwndDlg, WM_INITDIALOG, 0, 0);
  428. fRet = TRUE;
  429. }
  430. else
  431. {
  432. TRC_ERR((TB,_T("Unable LoadFromStore %d, %s"), hr, szPath));
  433. _pSh->SH_DisplayErrorBox(NULL,
  434. UI_IDS_ERR_LOAD,
  435. szPath);
  436. }
  437. rdpf.CloseStore();
  438. return fRet;
  439. }
  440. else
  441. {
  442. TRC_ERR((TB,_T("Unable to OpenStore for load %s"), szPath));
  443. _pSh->SH_DisplayErrorBox(NULL,
  444. UI_IDS_ERR_OPEN_FILE,
  445. szPath);
  446. return FALSE;
  447. }
  448. }
  449. else
  450. {
  451. //User canceled out, this is not a failure
  452. return TRUE;
  453. }
  454. DC_END_FN();
  455. }
  456. //
  457. // Behave like winlogon for UPN
  458. // Disable the Domain field if the user has entered an '@'
  459. //
  460. //
  461. BOOL CPropGeneral::OnChangeUserName(HWND hwndDlg)
  462. {
  463. DC_BEGIN_FN("OnChangeUserName");
  464. TCHAR szUserName[SH_MAX_USERNAME_LENGTH];
  465. GetDlgItemText( hwndDlg, IDC_GENERAL_EDIT_USERNAME,
  466. szUserName, SIZECHAR(szUserName));
  467. BOOL fDisableDomain = FALSE;
  468. if(!_tcsstr(szUserName, TEXT("@")))
  469. {
  470. fDisableDomain = TRUE;
  471. }
  472. EnableWindow(GetDlgItem(hwndDlg, IDC_GENERAL_EDIT_DOMAIN),
  473. fDisableDomain);
  474. DC_END_FN();
  475. return TRUE;
  476. }
  477. void CPropGeneral::DlgToSettings(HWND hwndDlg)
  478. {
  479. TCHAR szServer[SH_MAX_ADDRESS_LENGTH];
  480. TCHAR szDomain[SH_MAX_DOMAIN_LENGTH];
  481. TCHAR szUserName[SH_MAX_USERNAME_LENGTH];
  482. BOOL fSavePassword;
  483. GetDlgItemText( hwndDlg, IDC_GENERAL_EDIT_USERNAME,
  484. szUserName, SIZECHAR(szUserName));
  485. _pTscSet->SetLogonUserName(szUserName);
  486. GetDlgItemText( hwndDlg, IDC_GENERAL_COMBO_SERVERS,
  487. szServer, SIZECHAR(szServer));
  488. _pTscSet->SetConnectString(szServer);
  489. //
  490. // Pickup the password
  491. //
  492. if (_pTscSet->GetUIPasswordEdited())
  493. {
  494. TCHAR szClearPass[MAX_PATH];
  495. GetDlgItemText(hwndDlg, IDC_GENERAL_EDIT_PASSWORD,
  496. szClearPass, SIZECHAR(szClearPass));
  497. _pTscSet->SetClearTextPass(szClearPass);
  498. // Wipe stack copy.
  499. SecureZeroMemory(szClearPass, sizeof(szClearPass));
  500. }
  501. fSavePassword = IsDlgButtonChecked(hwndDlg,
  502. IDC_GENERAL_CHECK_SAVE_PASSWORD);
  503. _pTscSet->SetSavePassword(fSavePassword);
  504. GetDlgItemText(hwndDlg, IDC_GENERAL_EDIT_DOMAIN,
  505. szDomain, SIZECHAR(szDomain));
  506. _pTscSet->SetDomain(szDomain);
  507. }