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.

552 lines
15 KiB

  1. //
  2. // tscapp.cpp
  3. //
  4. // Implementation of CTscApp
  5. // Ts Client Shell app logic
  6. //
  7. // Copyright(C) Microsoft Corporation 2000
  8. // Author: Nadim Abdo (nadima)
  9. //
  10. //
  11. #include "stdafx.h"
  12. #define TRC_GROUP TRC_GROUP_UI
  13. #define TRC_FILE "tscapp.cpp"
  14. #include <atrcapi.h>
  15. #include "tscapp.h"
  16. #include "tscsetting.h"
  17. #include "rdpfstore.h"
  18. #include "rmigrate.h"
  19. #include "sh.h"
  20. CTscApp::CTscApp()
  21. {
  22. DC_BEGIN_FN("CTscApp");
  23. _pWnd = NULL;
  24. _pShellUtil = NULL;
  25. _pTscSet = NULL;
  26. _fAutoSaveSettings = FALSE;
  27. DC_END_FN();
  28. }
  29. CTscApp::~CTscApp()
  30. {
  31. DC_BEGIN_FN("~CTscApp");
  32. delete _pWnd;
  33. delete _pShellUtil;
  34. delete _pTscSet;
  35. DC_END_FN();
  36. }
  37. //
  38. // StartShell called to startup the app
  39. //
  40. //
  41. BOOL CTscApp::StartShell(HINSTANCE hInstance,
  42. HINSTANCE hPrevInstance,
  43. LPTSTR lpszCmdLine)
  44. {
  45. DWORD dwErr;
  46. DC_BEGIN_FN("StartShell");
  47. _hInst = hInstance;
  48. TRC_ASSERT(!_pWnd,
  49. (TB,_T("Calling StartShell while container wnd is up")));
  50. //
  51. // Create the container window
  52. //
  53. _pShellUtil = new CSH();
  54. if(_pShellUtil)
  55. {
  56. if(!_pShellUtil->SH_Init( hInstance))
  57. {
  58. TRC_ERR((TB,_T("SH_Init failed")));
  59. return FALSE;
  60. }
  61. dwErr = _pShellUtil->SH_ParseCmdParam( lpszCmdLine);
  62. if (SH_PARSECMD_OK != dwErr) {
  63. TRC_ERR((TB,_T("SH_ParseCmdParam failed on: %s code: 0x%x"),lpszCmdLine, dwErr));
  64. //
  65. // Invalid connection file specified
  66. //
  67. if (SH_PARSECMD_ERR_INVALID_CONNECTION_PARAM == dwErr) {
  68. _pShellUtil->SH_DisplayErrorBox(NULL,
  69. UI_IDS_ERR_INVALID_CONNECTION_FILE,
  70. _pShellUtil->GetRegSession()
  71. );
  72. }
  73. //
  74. // Parse failure is fatal
  75. //
  76. return FALSE;
  77. }
  78. #ifndef OS_WINCE
  79. if(_pShellUtil->SH_GetCmdMigrate())
  80. {
  81. //Only do a migrate and then quit
  82. CTscRegMigrate mig;
  83. TCHAR szPath[MAX_PATH];
  84. if(_pShellUtil->SH_GetRemoteDesktopFolderPath(szPath,
  85. SIZECHAR(szPath)))
  86. {
  87. if(!mig.MigrateAll(szPath))
  88. {
  89. TRC_ERR((TB,_T("MigrateAll failed to dir:%s"),szPath));
  90. }
  91. //Want to quit the app
  92. return FALSE;
  93. }
  94. else
  95. {
  96. TRC_ERR((TB,_T("SH_GetRemoteDesktopFolderPath failed")));
  97. return FALSE;
  98. }
  99. }
  100. #endif
  101. if(!InitSettings(hInstance))
  102. {
  103. TRC_ERR((TB,_T("InitSettings returned FALSE")));
  104. return FALSE;
  105. }
  106. _pWnd = new CContainerWnd();
  107. if(_pWnd)
  108. {
  109. if (_pWnd->Init( hInstance, _pTscSet, _pShellUtil))
  110. {
  111. return TRUE;
  112. }
  113. else
  114. {
  115. TRC_ERR((TB,_T("Error: pWnd->Init returned FALSE. Exiting\n")));
  116. return FALSE;
  117. }
  118. }
  119. else
  120. {
  121. TRC_ERR((TB,_T("Could not new CContainerWnd")));
  122. return FALSE;
  123. }
  124. }
  125. else
  126. {
  127. TRC_ERR((TB,_T("Could not new CSH")));
  128. return FALSE;
  129. }
  130. DC_END_FN();
  131. }
  132. HWND CTscApp::GetTscDialogHandle()
  133. {
  134. DC_BEGIN_FN("GetTscDialogHandle");
  135. HWND hwndDlg = NULL;
  136. if(_pWnd)
  137. {
  138. hwndDlg = _pWnd->GetConnectDialogHandle();
  139. }
  140. DC_END_FN();
  141. return hwndDlg;
  142. }
  143. //
  144. // Setup the settings structures
  145. // Based on command line options
  146. //
  147. // This involves figuring out where to load settings from
  148. // and then doing it. E.g
  149. // Load from file
  150. // Load from registry
  151. // Load from internal defaults
  152. //
  153. BOOL CTscApp::InitSettings(HINSTANCE hInstance)
  154. {
  155. CRdpFileStore rdpf;
  156. LPTSTR szFileName = NULL;
  157. TCHAR szDefaultFile[MAX_PATH];
  158. BOOL fLoadedSettings = FALSE;
  159. DC_BEGIN_FN("InitSettings");
  160. _pTscSet = new CTscSettings();
  161. if(!_pTscSet)
  162. {
  163. TRC_ERR((TB,_T("Could not new CTscSettings")));
  164. return FALSE;
  165. }
  166. if(_pShellUtil->SH_GetCmdFileForEdit() ||
  167. _pShellUtil->SH_GetCmdFileForConnect())
  168. {
  169. szFileName = _pShellUtil->SH_GetCmdLnFileName();
  170. if(!_pShellUtil->SH_FileExists(szFileName))
  171. {
  172. TCHAR errFileNotFound[MAX_PATH];
  173. TCHAR szAppName[MAX_PATH];
  174. if(LoadString(hInstance,
  175. UI_IDS_APP_NAME,
  176. szAppName,
  177. SIZECHAR(szAppName)))
  178. {
  179. if (LoadString(hInstance,
  180. UI_IDS_ERR_FILEDOESNOTEXIST,
  181. errFileNotFound,
  182. SIZECHAR(errFileNotFound)) != 0)
  183. {
  184. TCHAR errFormatedFileNotFound[MAX_PATH*3];
  185. _stprintf(errFormatedFileNotFound, errFileNotFound,
  186. szFileName);
  187. MessageBox(NULL, errFormatedFileNotFound, szAppName,
  188. MB_ICONERROR | MB_OK);
  189. return FALSE;
  190. }
  191. }
  192. return FALSE;
  193. }
  194. }
  195. else if(_pShellUtil->GetRegSessionSpecified())
  196. {
  197. // Automigrate the specified registry
  198. // session directly to an in-memory settings store
  199. _fAutoSaveSettings = FALSE;
  200. rdpf.SetToNullStore();
  201. CTscRegMigrate mig;
  202. TRC_NRM((TB,_T("Automigrating session %s"),
  203. _pShellUtil->GetRegSession()));
  204. if(mig.MigrateSession( _pShellUtil->GetRegSession(),
  205. &rdpf))
  206. {
  207. TRC_NRM((TB,_T("Success automigrating reg setting")));
  208. HRESULT hr = _pTscSet->LoadFromStore(&rdpf);
  209. if(FAILED(hr))
  210. {
  211. _pShellUtil->SH_DisplayErrorBox(NULL,
  212. UI_IDS_ERR_INITDEFAULT,
  213. szFileName);
  214. return FALSE;
  215. }
  216. _pShellUtil->SetAutoConnect( TRUE );
  217. fLoadedSettings = TRUE;
  218. }
  219. else
  220. {
  221. //Something bad happened
  222. //could not automigrate..indicate failure
  223. //and use NULL store
  224. fLoadedSettings = FALSE;
  225. }
  226. }
  227. else
  228. {
  229. //No files specified or registry sessions specified
  230. //Try to use the default.rdp file (create if necessary)
  231. if(!_pShellUtil->SH_GetPathToDefaultFile(
  232. szDefaultFile,
  233. SIZECHAR(szDefaultFile)))
  234. {
  235. TRC_ERR((TB,_T("SH_GetPathToDefaultFile failed")));
  236. //
  237. // Display error message to user
  238. //
  239. _pShellUtil->SH_DisplayErrorBox(NULL,
  240. UI_IDS_ERR_GETPATH_TO_DEFAULT_FILE);
  241. return FALSE;
  242. }
  243. szFileName = szDefaultFile;
  244. if(!_pShellUtil->SH_FileExists(szFileName))
  245. {
  246. //
  247. // File doesn't exist so create the Remote Desktops
  248. // directory to ensure the file can be created
  249. //
  250. if(!CreateRDdir())
  251. {
  252. TRC_ERR((TB,_T("Couldn't create RD dir. Not using %s"),
  253. szFileName));
  254. szFileName = NULL;
  255. }
  256. //
  257. // Now create a hidden default file
  258. //
  259. if (szFileName)
  260. {
  261. if (!CSH::SH_CreateHiddenFile(szFileName))
  262. {
  263. TRC_ERR((TB,_T("Unable to create and hide file %s"),
  264. szFileName));
  265. szFileName = NULL;
  266. }
  267. }
  268. }
  269. //
  270. // Auto Save on exit if we're using the default
  271. // connection file (Default.rdp)
  272. //
  273. _fAutoSaveSettings = szFileName ? TRUE : FALSE;
  274. }
  275. if(szFileName)
  276. {
  277. //
  278. //We're loading the settings from a file
  279. //this is the common case.
  280. //
  281. if(rdpf.OpenStore(szFileName))
  282. {
  283. HRESULT hr = _pTscSet->LoadFromStore(&rdpf);
  284. if(SUCCEEDED(hr))
  285. {
  286. fLoadedSettings = TRUE;
  287. }
  288. else
  289. {
  290. TRC_ERR((TB,_T("LoadFromStore failed")));
  291. _pShellUtil->SH_DisplayErrorBox(NULL,
  292. UI_IDS_ERR_LOAD,
  293. szFileName);
  294. // We can load NULL file even if you can't load the file
  295. }
  296. rdpf.CloseStore();
  297. }
  298. else
  299. {
  300. TRC_ERR((TB,_T("OpenStore (%s) failed"),szFileName));
  301. _pShellUtil->SH_DisplayErrorBox(NULL,UI_IDS_ERR_OPEN_FILE,
  302. szFileName);
  303. // We can load NULL file even if you can't open the file
  304. }
  305. }
  306. if(!fLoadedSettings)
  307. {
  308. TRC_ERR((TB,_T("Couldn't load settings, using NULL STORE")));
  309. //Some bad thing happened and we can't get a file to load
  310. //from (not even the default file). So load from an empty
  311. //store, this will initialize everything to defaults
  312. if(rdpf.SetToNullStore())
  313. {
  314. HRESULT hr = _pTscSet->LoadFromStore(&rdpf);
  315. if(FAILED(hr))
  316. {
  317. _pShellUtil->SH_DisplayErrorBox(NULL,
  318. UI_IDS_ERR_INITDEFAULT,
  319. szFileName);
  320. return FALSE;
  321. }
  322. }
  323. else
  324. {
  325. TRC_ERR((TB,_T("SetToNullStore Failed")));
  326. return FALSE;
  327. }
  328. }
  329. //Keep track of the filename
  330. if(szFileName)
  331. {
  332. _pTscSet->SetFileName(szFileName);
  333. }
  334. //
  335. // Override loaded settings with cmd line settings
  336. //
  337. _pShellUtil->SH_ApplyCmdLineSettings(_pTscSet, NULL);
  338. DC_END_FN();
  339. return TRUE;
  340. }
  341. BOOL CTscApp::EndShell()
  342. {
  343. DC_BEGIN_FN("EndShell");
  344. BOOL fRet = FALSE;
  345. if(!_pTscSet || !_pShellUtil)
  346. {
  347. return FALSE;
  348. }
  349. #ifndef OS_WINCE
  350. _pShellUtil->SH_Cleanup();
  351. #endif
  352. //
  353. // Only autosave if
  354. // the last connection was successful
  355. //
  356. if(_fAutoSaveSettings &&
  357. _pWnd &&
  358. _pWnd->GetConnectionSuccessFlag())
  359. {
  360. //
  361. // AutoSave the tscsettings
  362. // (only if the current file is still Default.rdp)
  363. //
  364. TCHAR szDefaultFile[MAX_PATH];
  365. if(!_pShellUtil->SH_GetPathToDefaultFile(
  366. szDefaultFile,
  367. SIZECHAR(szDefaultFile)))
  368. {
  369. TRC_ERR((TB,_T("SH_GetPathToDefaultFile failed")));
  370. return FALSE;
  371. }
  372. if(!_tcscmp(szDefaultFile, _pTscSet->GetFileName()))
  373. {
  374. CRdpFileStore rdpf;
  375. if(rdpf.OpenStore(szDefaultFile))
  376. {
  377. HRESULT hr = E_FAIL;
  378. hr = _pTscSet->SaveToStore(&rdpf);
  379. if(SUCCEEDED(hr))
  380. {
  381. if(rdpf.CommitStore())
  382. {
  383. //Save last filename
  384. _pTscSet->SetFileName(szDefaultFile);
  385. fRet = TRUE;
  386. }
  387. else
  388. {
  389. TRC_ERR((TB,_T("Unable to CommitStore settings")));
  390. }
  391. }
  392. else
  393. {
  394. TRC_ERR((TB,_T("Unable to save settings to store %d, %s"),
  395. hr, szDefaultFile));
  396. }
  397. rdpf.CloseStore();
  398. if(!fRet)
  399. {
  400. _pShellUtil->SH_DisplayErrorBox(NULL,
  401. UI_IDS_ERR_SAVE,
  402. szDefaultFile);
  403. }
  404. return fRet;
  405. }
  406. else
  407. {
  408. TRC_ERR((TB,_T("Unable to OpenStore for save %s"), szDefaultFile));
  409. _pShellUtil->SH_DisplayErrorBox(NULL,UI_IDS_ERR_OPEN_FILE,
  410. szDefaultFile);
  411. return FALSE;
  412. }
  413. }
  414. else
  415. {
  416. //Not a failure, but nothing to do
  417. TRC_NRM((TB,_T("Current file is no longer default, don't autosave")));
  418. return TRUE;
  419. }
  420. }
  421. else
  422. {
  423. return TRUE;
  424. }
  425. DC_END_FN();
  426. }
  427. //
  428. // Creates the Remote Desktops dir (if needed)
  429. // pops UI on failure
  430. //
  431. // Returns:
  432. // TRUE on success
  433. //
  434. //
  435. BOOL CTscApp::CreateRDdir()
  436. {
  437. DC_BEGIN_FN("CreateRDdir");
  438. //
  439. // Make sure the directory exists so that the file
  440. // can be created by the OpenStore
  441. //
  442. TCHAR szDir[MAX_PATH];
  443. if(_pShellUtil->SH_GetRemoteDesktopFolderPath(szDir,
  444. SIZECHAR(szDir)))
  445. {
  446. if(_pShellUtil->SH_CreateDirectory(szDir))
  447. {
  448. return TRUE;
  449. }
  450. else
  451. {
  452. TRC_ERR((TB,_T("SH_CreateDirectory failed %s:%d"),
  453. szDir, GetLastError()));
  454. //
  455. // Display error message to user
  456. //
  457. #ifndef OS_WINCE
  458. TCHAR szMyDocsFolderName[MAX_PATH];
  459. if(_pShellUtil->SH_GetMyDocumentsDisplayName(
  460. szMyDocsFolderName,
  461. SIZECHAR(szMyDocsFolderName)))
  462. {
  463. TCHAR errCantCreateRDFolder[MAX_PATH];
  464. TCHAR szAppName[MAX_PATH];
  465. if(LoadString(_hInst,
  466. UI_IDS_APP_NAME,
  467. szAppName,
  468. SIZECHAR(szAppName)))
  469. {
  470. if (LoadString(_hInst,
  471. UI_IDS_ERR_CREATE_REMDESKS_FOLDER,
  472. errCantCreateRDFolder,
  473. SIZECHAR(errCantCreateRDFolder)))
  474. {
  475. TCHAR errFmtCantCreateRDFolder[MAX_PATH*3];
  476. _stprintf(errFmtCantCreateRDFolder,
  477. errCantCreateRDFolder,
  478. szMyDocsFolderName,
  479. szDir);
  480. MessageBox(NULL, errFmtCantCreateRDFolder,
  481. szAppName,
  482. MB_ICONERROR | MB_OK);
  483. }
  484. }
  485. }
  486. #endif
  487. //
  488. // This is an error but we'll handle it anyway
  489. // by loading defaults from a null store
  490. //
  491. return FALSE;
  492. }
  493. }
  494. else
  495. {
  496. //Guess we can't load from a file after all
  497. return FALSE;
  498. }
  499. DC_END_FN();
  500. }