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.

537 lines
14 KiB

  1. //+--------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1994 - 1996.
  5. //
  6. // File: complete.cxx
  7. //
  8. // Contents: Task wizard completion (final) property page implementation.
  9. //
  10. // Classes: CCompletionPage
  11. //
  12. // History: 4-28-1997 DavidMun Created
  13. //
  14. //---------------------------------------------------------------------------
  15. #include "..\pch\headers.hxx"
  16. #pragma hdrstop
  17. #include "myheaders.hxx"
  18. //+--------------------------------------------------------------------------
  19. //
  20. // Member: CCompletionPage::CCompletionPage
  21. //
  22. // Synopsis: ctor
  23. //
  24. // Arguments: [ptszFolderPath] - full path to tasks folder with dummy
  25. // filename appended
  26. // [phPSP] - filled with prop page handle
  27. //
  28. // History: 4-28-1997 DavidMun Created
  29. //
  30. //---------------------------------------------------------------------------
  31. CCompletionPage::CCompletionPage(
  32. CTaskWizard *pParent,
  33. LPTSTR ptszFolderPath,
  34. HPROPSHEETPAGE *phPSP):
  35. CWizPage(MAKEINTRESOURCE(IDD_COMPLETION), ptszFolderPath)
  36. {
  37. TRACE_CONSTRUCTOR(CCompletionPage);
  38. _pParent = pParent;
  39. _hIcon = NULL;
  40. _pJob = NULL;
  41. #ifdef WIZARD97
  42. m_psp.dwFlags |= PSP_HIDEHEADER;
  43. #endif // WIZARD97
  44. *phPSP = CreatePropertySheetPage(&m_psp);
  45. if (!*phPSP)
  46. {
  47. DEBUG_OUT_LASTERROR;
  48. }
  49. }
  50. //+--------------------------------------------------------------------------
  51. //
  52. // Member: CCompletionPage::~CCompletionPage
  53. //
  54. // Synopsis: dtor
  55. //
  56. // History: 4-28-1997 DavidMun Created
  57. //
  58. //---------------------------------------------------------------------------
  59. CCompletionPage::~CCompletionPage()
  60. {
  61. TRACE_DESTRUCTOR(CCompletionPage);
  62. if (_pJob)
  63. {
  64. _pJob->Release();
  65. }
  66. if (_hIcon)
  67. {
  68. VERIFY(DestroyIcon(_hIcon));
  69. }
  70. }
  71. //===========================================================================
  72. //
  73. // CWizPage overrides
  74. //
  75. //===========================================================================
  76. //+--------------------------------------------------------------------------
  77. //
  78. // Member: CCompletionPage::_OnInitDialog
  79. //
  80. // Synopsis: Perform initialization that should only occur once.
  81. //
  82. // Arguments: [lParam] - LPPROPSHEETPAGE used to create this page
  83. //
  84. // Returns: TRUE (let windows set focus)
  85. //
  86. // History: 5-20-1997 DavidMun Created
  87. // 4-14-1998 CameronE Added Policy Support
  88. //
  89. //---------------------------------------------------------------------------
  90. LRESULT
  91. CCompletionPage::_OnInitDialog(
  92. LPARAM lParam)
  93. {
  94. TRACE_METHOD(CCompletionPage, _OnInitDialog);
  95. //
  96. // Policy Support - remove "open advanced" checkbox if
  97. // we find a registry key for that policy
  98. //
  99. if (RegReadPolicyKey(TS_KEYPOLICY_DISABLE_ADVANCED))
  100. {
  101. DEBUG_OUT((DEB_ITRACE, "Policy DISABLE_ADVANCED active to remove checkbox\n"));
  102. EnableWindow(_hCtrl(complete_advanced_ckbox), FALSE);
  103. ShowWindow(_hCtrl(complete_advanced_ckbox), SW_HIDE);
  104. }
  105. return TRUE;
  106. }
  107. //+--------------------------------------------------------------------------
  108. //
  109. // Member: CCompletionPage::_OnPSNSetActive
  110. //
  111. // Synopsis: Create a task object (in-memory only) and update the
  112. // summary information on this page.
  113. //
  114. // Arguments: [lParam] - LPNMHDR (unused)
  115. //
  116. // Returns: TRUE
  117. //
  118. // History: 5-20-1997 DavidMun Created
  119. //
  120. //---------------------------------------------------------------------------
  121. LRESULT
  122. CCompletionPage::_OnPSNSetActive(
  123. LPARAM lParam)
  124. {
  125. TRACE_METHOD(CCompletionPage, _OnPSNSetActive);
  126. HRESULT hr = S_OK;
  127. LPWSTR pwszTrigger = NULL;
  128. do
  129. {
  130. //
  131. // Update the summary info to reflect the user's latest
  132. // choices.
  133. //
  134. CSelectProgramPage *pSelProg = GetSelectProgramPage(_pParent);
  135. CSelectTriggerPage *pSelTrig = GetSelectTriggerPage(_pParent);
  136. HICON hIcon;
  137. hIcon = pSelProg->GetSelectedAppIcon();
  138. SendDlgItemMessage(Hwnd(),
  139. complete_task_icon,
  140. STM_SETICON,
  141. (WPARAM) hIcon,
  142. 0L);
  143. if (_hIcon)
  144. {
  145. VERIFY(DestroyIcon(_hIcon));
  146. }
  147. _hIcon = hIcon;
  148. Static_SetText(_hCtrl(complete_taskname_lbl), pSelTrig->GetTaskName());
  149. Static_SetText(_hCtrl(complete_trigger_lbl), TEXT(""));
  150. //
  151. // Create the task object so we can ask it for its trigger string.
  152. // The object won't be persisted until the user hits the Finish
  153. // button.
  154. //
  155. hr = _UpdateTaskObject();
  156. if (FAILED(hr))
  157. {
  158. _SetWizButtons(PSWIZB_BACK | PSWIZB_DISABLEDFINISH);
  159. break;
  160. }
  161. //
  162. // _pJob is now valid, so enable the finish button.
  163. //
  164. _SetWizButtons(PSWIZB_BACK | PSWIZB_FINISH);
  165. //
  166. // Put the trigger string in the ui so the user can see a
  167. // description of when the task will run.
  168. //
  169. hr = _pJob->GetTriggerString(0, &pwszTrigger);
  170. if (FAILED(hr))
  171. {
  172. DEBUG_OUT_HRESULT(hr);
  173. break;
  174. }
  175. Static_SetText(_hCtrl(complete_trigger_lbl), pwszTrigger);
  176. } while (0);
  177. CoTaskMemFree(pwszTrigger);
  178. return CPropPage::_OnPSNSetActive(lParam);
  179. }
  180. //+--------------------------------------------------------------------------
  181. //
  182. // Member: CCompletionPage::_OnWizBack
  183. //
  184. // Synopsis: Set the current page to the one that should precede this.
  185. //
  186. // Returns: -1
  187. //
  188. // History: 5-20-1997 DavidMun Created
  189. //
  190. //---------------------------------------------------------------------------
  191. LRESULT
  192. CCompletionPage::_OnWizBack()
  193. {
  194. TRACE_METHOD(CCompletionPage, _OnWizBack);
  195. SetWindowLongPtr(Hwnd(), DWLP_MSGRESULT, IDD_PASSWORD);
  196. return -1;
  197. }
  198. //+--------------------------------------------------------------------------
  199. //
  200. // Member: CCompletionPage::_OnWizFinish
  201. //
  202. // Synopsis: Persist the task object.
  203. //
  204. // Returns: 0
  205. //
  206. // History: 5-20-1997 DavidMun Created
  207. //
  208. //---------------------------------------------------------------------------
  209. LRESULT
  210. CCompletionPage::_OnWizFinish()
  211. {
  212. TRACE_METHOD(CCompletionPage, _OnWizFinish);
  213. HRESULT hr = S_OK;
  214. LPCTSTR ptszJob = NULL;
  215. CSelectTriggerPage *pSelTrig = GetSelectTriggerPage(_pParent);
  216. CPasswordPage *pPasswdPage = GetPasswordPage(_pParent);
  217. BOOL fSaveSucceeded = FALSE;
  218. do
  219. {
  220. if (!_pJob)
  221. {
  222. hr = E_OUTOFMEMORY;
  223. break;
  224. }
  225. //
  226. // Persist the new job object.
  227. //
  228. ptszJob = pSelTrig->GetJobObjectFullPath();
  229. CWaitCursor HourGlass;
  230. if (FileExists((LPTSTR)ptszJob, MAX_PATH + 1))
  231. {
  232. if (!DeleteFile(ptszJob))
  233. {
  234. //
  235. // Complain but leave hr alone so we don't pop up a second
  236. // error
  237. //
  238. DEBUG_OUT_LASTERROR;
  239. SchedUIErrorDialog(Hwnd(),
  240. IDS_CANT_DELETE_EXISTING,
  241. (LPTSTR) pSelTrig->GetTaskName());
  242. break;
  243. }
  244. }
  245. hr = _pJob->Save(ptszJob, TRUE);
  246. BREAK_ON_FAIL_HRESULT(hr);
  247. fSaveSucceeded = TRUE;
  248. //
  249. // set the account information. Caller must ensure service is running.
  250. //
  251. //
  252. // Translate input account prior to saving, then save it
  253. //
  254. DWORD cchAccount = MAX_USERNAME + 1;
  255. WCHAR wszAccount[MAX_USERNAME + 1] = L"";
  256. LPWSTR pwszPassword = (LPWSTR) pPasswdPage->GetPassword();
  257. hr = TranslateAccount(TRANSLATE_FOR_INTERNAL, pPasswdPage->GetAccountName(), wszAccount, cchAccount, &pwszPassword);
  258. if (SUCCEEDED(hr))
  259. {
  260. hr = _pJob->SetAccountInformation(wszAccount, pwszPassword);
  261. }
  262. BREAK_ON_FAIL_HRESULT(hr);
  263. hr = _pJob->Save(NULL, FALSE);
  264. BREAK_ON_FAIL_HRESULT(hr);
  265. } while (0);
  266. //
  267. // Don't leave account name & password in memory
  268. //
  269. pPasswdPage->ZeroCredentials();
  270. //
  271. // If advanced checkbox is checked, indicate to DoTaskWizard. Also,
  272. // give it a reference to the job object so it can do any terminal
  273. // processing necessary (e.g., displaying the property pages).
  274. //
  275. if (fSaveSucceeded)
  276. {
  277. BOOL fAdvanced = IsDlgButtonChecked(Hwnd(), complete_advanced_ckbox);
  278. _pParent->SetAdvancedMode(fAdvanced);
  279. _pJob->AddRef();
  280. _pParent->SetTaskObject(_pJob);
  281. _pParent->SetJobObjectPath(ptszJob);
  282. }
  283. //
  284. // Notify the user if anything went wrong.
  285. //
  286. if (FAILED(hr))
  287. {
  288. if (fSaveSucceeded)
  289. {
  290. SchedUIErrorDialog(Hwnd(), IDS_WIZFINISH_NONFATAL, hr);
  291. }
  292. else
  293. {
  294. SchedUIErrorDialog(Hwnd(), IDS_WIZFINISH_FATAL, hr);
  295. }
  296. }
  297. return 0;
  298. }
  299. //+--------------------------------------------------------------------------
  300. //
  301. // Member: CCompletionPage::_UpdateTaskObject
  302. //
  303. // Synopsis: Create a task object in memory that matches all the
  304. // settings the user made on previous pages.
  305. //
  306. // Returns: HRESULT
  307. //
  308. // History: 5-20-1997 DavidMun Created
  309. //
  310. // Notes: If a task object already exists, it is freed and replaced
  311. // with a new one.
  312. //
  313. // The task object is not persisted until the user hits the
  314. // finish button.
  315. //
  316. //---------------------------------------------------------------------------
  317. HRESULT
  318. CCompletionPage::_UpdateTaskObject()
  319. {
  320. TRACE_METHOD(CCompletionPage, _CreateTaskObject);
  321. HRESULT hr = S_OK;
  322. ITaskTrigger *pTrigger = NULL;
  323. CSelectTriggerPage *pSelTrig = GetSelectTriggerPage(_pParent);
  324. CSelectProgramPage *pSelProg = GetSelectProgramPage(_pParent);
  325. do
  326. {
  327. //
  328. // If there's already a task object, get rid of it. This would
  329. // be the case if the user got to the finish page, then hit
  330. // the back button.
  331. //
  332. if (_pJob)
  333. {
  334. _pJob->Release();
  335. _pJob = NULL;
  336. }
  337. //
  338. // Create the task object
  339. //
  340. _pJob = CJob::Create();
  341. if (_pJob == NULL)
  342. {
  343. hr = E_OUTOFMEMORY;
  344. DEBUG_OUT_HRESULT(hr);
  345. break;
  346. }
  347. //
  348. // Add default flags
  349. //
  350. DWORD dwAddFlags = TASK_FLAG_DONT_START_IF_ON_BATTERIES |
  351. TASK_FLAG_KILL_IF_GOING_ON_BATTERIES;
  352. hr = _pJob->SetFlags(dwAddFlags);
  353. BREAK_ON_FAIL_HRESULT(hr);
  354. //
  355. // Fill in the trigger struct
  356. //
  357. TASK_TRIGGER Trigger;
  358. SecureZeroMemory(&Trigger, sizeof(Trigger));
  359. Trigger.cbTriggerSize = sizeof(Trigger);
  360. CTriggerPage *pTriggerPage = pSelTrig->GetSelectedTriggerPage();
  361. if (pTriggerPage)
  362. {
  363. pTriggerPage->FillInTrigger(&Trigger);
  364. }
  365. else
  366. {
  367. ULONG idTrigger = pSelTrig->GetSelectedTriggerType();
  368. switch (idTrigger)
  369. {
  370. case seltrig_startup_rb:
  371. Trigger.TriggerType = TASK_EVENT_TRIGGER_AT_SYSTEMSTART;
  372. break;
  373. case seltrig_logon_rb:
  374. Trigger.TriggerType = TASK_EVENT_TRIGGER_AT_LOGON;
  375. break;
  376. default:
  377. DEBUG_ASSERT(FALSE);
  378. hr = E_UNEXPECTED;
  379. break;
  380. }
  381. BREAK_ON_FAIL_HRESULT(hr);
  382. SYSTEMTIME stStart;
  383. GetSystemTime(&stStart);
  384. Trigger.wBeginYear = stStart.wYear;
  385. Trigger.wBeginMonth = stStart.wMonth;
  386. Trigger.wBeginDay = stStart.wDay;
  387. }
  388. //
  389. // Create a trigger object and init it with the struct
  390. //
  391. WORD iTrigger = (WORD)-1;
  392. hr = _pJob->CreateTrigger(&iTrigger, &pTrigger);
  393. BREAK_ON_FAIL_HRESULT(hr);
  394. DEBUG_ASSERT(iTrigger == 0);
  395. hr = pTrigger->SetTrigger(&Trigger);
  396. BREAK_ON_FAIL_HRESULT(hr);
  397. //
  398. // Set the application name
  399. //
  400. TCHAR tszExeFullPath[MAX_PATH + 1];
  401. pSelProg->GetExeFullPath(tszExeFullPath, ARRAYLEN(tszExeFullPath));
  402. hr = _pJob->SetApplicationName(tszExeFullPath);
  403. BREAK_ON_FAIL_HRESULT(hr);
  404. //
  405. // Set the arguments
  406. //
  407. hr = _pJob->SetParameters(pSelProg->GetArgs());
  408. BREAK_ON_FAIL_HRESULT(hr);
  409. //
  410. // Set the working directory
  411. //
  412. TCHAR tszWorkingDir[MAX_PATH + 1];
  413. pSelProg->GetExeDir(tszWorkingDir, ARRAYLEN(tszWorkingDir));
  414. hr = _pJob->SetWorkingDirectory(tszWorkingDir);
  415. BREAK_ON_FAIL_HRESULT(hr);
  416. } while (0);
  417. if (pTrigger)
  418. {
  419. pTrigger->Release();
  420. }
  421. return hr;
  422. }