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.

1012 lines
26 KiB

  1. //____________________________________________________________________________
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1995 - 1996.
  5. //
  6. // File: settings.cxx
  7. //
  8. // Contents:
  9. //
  10. // Classes:
  11. //
  12. // Functions:
  13. //
  14. // Notes: For the first release of the scheduling agent, all security
  15. // operations are disabled under Win95, even Win95 to NT.
  16. //
  17. // History: 3/4/1996 RaviR Created
  18. //
  19. //____________________________________________________________________________
  20. #include "..\pch\headers.hxx"
  21. #pragma hdrstop
  22. #include <mstask.h>
  23. #include "..\inc\common.hxx"
  24. #include "..\folderui\dbg.h"
  25. #include "..\folderui\macros.h"
  26. #include "..\folderui\util.hxx"
  27. #include "..\inc\network.hxx"
  28. #include "..\inc\dll.hxx"
  29. #include "dlg.hxx"
  30. #include "rc.h"
  31. #include "defines.h"
  32. #include "uiutil.hxx"
  33. #include "helpids.h"
  34. #include "schedui.hxx"
  35. #include "misc.hxx"
  36. //
  37. // (Control id, help id) list for context sensitivity help.
  38. //
  39. ULONG s_aSettingsPageHelpIds[] =
  40. {
  41. chk_start_on_idle, Hchk_start_on_idle,
  42. chk_stop_if_not_idle, Hchk_stop_if_not_idle,
  43. chk_dont_start_if_on_batteries, Hchk_dont_start_if_on_batteries,
  44. chk_kill_if_going_on_batteries, Hchk_kill_if_going_on_batteries,
  45. chk_delete_when_done, Hchk_delete_when_done,
  46. chk_stop_after, Hchk_stop_after,
  47. txt_stop_after_hr, Htxt_stop_after_hr,
  48. spin_stop_after_hr, Hspin_stop_after_hr,
  49. txt_stop_after_min, Htxt_stop_after_min,
  50. spin_stop_after_min, Hspin_stop_after_min,
  51. txt_idle_min, Htxt_idle_min,
  52. spin_idle_min, Hspin_idle_min,
  53. lbl_idle_deadline1, Hlbl_idle_deadline,
  54. lbl_idle_deadline2, Hlbl_idle_deadline,
  55. txt_idle_deadline, Htxt_idle_deadline,
  56. spin_idle_deadline, Hspin_idle_deadline,
  57. lbl_min, Hlbl_settings_min,
  58. lbl_hours, Hlbl_settings_hours,
  59. grp_idle_time, Hgrp_idle_time,
  60. txt_idle_minutes, Htxt_idle_minutes,
  61. grp_task_completed, Hgrp_task_completed,
  62. grp_power_management, Hgrp_power_management,
  63. btn_new, Hbtn_new,
  64. btn_delete, Hbtn_delete,
  65. chk_system_required, Hchk_system_required,
  66. 0,0
  67. };
  68. extern "C" TCHAR szMstaskHelp[];
  69. //
  70. // extern
  71. //
  72. extern HINSTANCE g_hInstance;
  73. //
  74. // All task flags included in this define will be modified when the page
  75. // values are persisted in the _OnApply method.
  76. //
  77. // If we're running on NT and targeting NT, the controls for some of these
  78. // flags will be initialized to the job's values and hidden.
  79. //
  80. #define TASK_FLAGS_IN_SETTINGS_PAGE (TASK_FLAG_START_ONLY_IF_IDLE | \
  81. TASK_FLAG_KILL_ON_IDLE_END | \
  82. TASK_FLAG_DONT_START_IF_ON_BATTERIES | \
  83. TASK_FLAG_KILL_IF_GOING_ON_BATTERIES | \
  84. TASK_FLAG_SYSTEM_REQUIRED | \
  85. TASK_FLAG_DELETE_WHEN_DONE)
  86. //____________________________________________________________________________
  87. //____________________________________________________________________________
  88. //________________ ______________________________________
  89. //________________ class CSettingsPage ______________________________________
  90. //________________ ______________________________________
  91. //____________________________________________________________________________
  92. //____________________________________________________________________________
  93. class CSettingsPage : public CPropPage
  94. {
  95. public:
  96. CSettingsPage(ITask * pIJob,
  97. LPTSTR ptszTaskPath,
  98. BOOL fPersistChanges);
  99. ~CSettingsPage();
  100. private:
  101. virtual LRESULT _OnInitDialog(LPARAM lParam);
  102. virtual LRESULT _OnCommand(int id, HWND hwndCtl, UINT codeNotify);
  103. virtual LRESULT _OnApply();
  104. virtual LRESULT _OnPSMQuerySibling(WPARAM wParam, LPARAM lParam);
  105. virtual LRESULT _OnPSNSetActive(LPARAM lParam);
  106. virtual LRESULT _OnPSNKillActive(LPARAM lParam);
  107. virtual LRESULT _OnHelp(HANDLE hRequesting, UINT uiHelpCommand);
  108. void _ReadIdleSettings();
  109. void _ErrorDialog(int idsErr, LONG error = 0, UINT idsHelpHint = 0)
  110. { SchedUIErrorDialog(Hwnd(), idsErr, error, idsHelpHint); }
  111. void _DisableUI(void);
  112. BOOL _PerformSanityChk();
  113. ITask * m_pIJob;
  114. DWORD m_dwFlags;
  115. DWORD m_dwMaxRunTime;
  116. WORD m_wIdleWait;
  117. WORD m_wIdleDeadline;
  118. //
  119. // Should we save on Apply or OK.
  120. //
  121. BOOL m_fPersistChanges;
  122. }; // class CSettingsPage
  123. inline
  124. CSettingsPage::CSettingsPage(
  125. ITask * pIJob,
  126. LPTSTR ptszTaskPath,
  127. BOOL fPersistChanges)
  128. :
  129. m_pIJob(pIJob),
  130. m_fPersistChanges(fPersistChanges),
  131. m_dwFlags(0),
  132. m_dwMaxRunTime(0),
  133. m_wIdleWait(0),
  134. m_wIdleDeadline(0),
  135. CPropPage(MAKEINTRESOURCE(settings_page), ptszTaskPath)
  136. {
  137. TRACE(CSettingsPage, CSettingsPage);
  138. Win4Assert(m_pIJob != NULL);
  139. pIJob->AddRef();
  140. }
  141. inline
  142. CSettingsPage::~CSettingsPage()
  143. {
  144. TRACE(CSettingsPage, ~CSettingsPage);
  145. if (m_pIJob != NULL)
  146. {
  147. m_pIJob->Release();
  148. }
  149. }
  150. LRESULT
  151. CSettingsPage::_OnHelp(
  152. HANDLE hRequesting,
  153. UINT uiHelpCommand)
  154. {
  155. WinHelp((HWND)hRequesting,
  156. szMstaskHelp,
  157. uiHelpCommand,
  158. (DWORD_PTR)(LPSTR)s_aSettingsPageHelpIds);
  159. return TRUE;
  160. }
  161. LRESULT
  162. CSettingsPage::_OnInitDialog(
  163. LPARAM lParam)
  164. {
  165. TRACE(CSettingsPage, _OnInitDialog);
  166. HRESULT hr = S_OK;
  167. ITask * pIJob = m_pIJob;
  168. Spin_SetRange(m_hPage, spin_idle_min, 1, MAX_IDLE_MINUTES);
  169. Edit_LimitText(_hCtrl(txt_idle_min), MAX_IDLE_DIGITS);
  170. Spin_SetRange(m_hPage, spin_idle_deadline, 0, MAX_IDLE_MINUTES);
  171. Edit_LimitText(_hCtrl(txt_idle_deadline), MAX_IDLE_DIGITS);
  172. Spin_SetRange(m_hPage, spin_stop_after_hr, 0, MAX_MAXRUNTIME_HOURS);
  173. Edit_LimitText(_hCtrl(txt_stop_after_hr), MAX_MAXRUNTIME_DIGITS);
  174. Spin_SetRange(m_hPage, spin_stop_after_min, 0, 59);
  175. Edit_LimitText(_hCtrl(txt_stop_after_min), 2);
  176. do
  177. {
  178. //
  179. // Set job flags
  180. //
  181. hr = pIJob->GetFlags(&m_dwFlags);
  182. CHECK_HRESULT(hr);
  183. BREAK_ON_FAIL(hr);
  184. CheckDlgButton(m_hPage, chk_start_on_idle,
  185. (m_dwFlags & TASK_FLAG_START_ONLY_IF_IDLE));
  186. CheckDlgButton(m_hPage, chk_stop_if_not_idle,
  187. (m_dwFlags & TASK_FLAG_KILL_ON_IDLE_END));
  188. CheckDlgButton(m_hPage, chk_dont_start_if_on_batteries,
  189. (m_dwFlags & TASK_FLAG_DONT_START_IF_ON_BATTERIES));
  190. CheckDlgButton(m_hPage, chk_kill_if_going_on_batteries,
  191. (m_dwFlags & TASK_FLAG_KILL_IF_GOING_ON_BATTERIES));
  192. CheckDlgButton(m_hPage, chk_system_required,
  193. (m_dwFlags & TASK_FLAG_SYSTEM_REQUIRED));
  194. CheckDlgButton(m_hPage, chk_delete_when_done,
  195. (m_dwFlags & TASK_FLAG_DELETE_WHEN_DONE));
  196. //
  197. // Not all machines have resume timers, which are used to support the
  198. // TASK_FLAG_SYSTEM_REQUIRED flag. If the target machine doesn't
  199. // have resume timers, hide the control.
  200. //
  201. if (!SupportsSystemRequired())
  202. {
  203. RECT rcSysReq;
  204. RECT rcGroup;
  205. LONG cy;
  206. //
  207. // Get the distance in pixels from the top of the system required
  208. // checkbox to the bottom of the group window.
  209. //
  210. // Reduce the height of the groupbox by this amount.
  211. //
  212. GetWindowRect(_hCtrl(chk_system_required), &rcSysReq);
  213. GetWindowRect(_hCtrl(grp_power_management), &rcGroup);
  214. cy = rcGroup.bottom - rcSysReq.top + 1;
  215. //
  216. // Hide the checkbox and resize the group window
  217. //
  218. ShowWindow(_hCtrl(chk_system_required), SW_HIDE);
  219. SetWindowPos(_hCtrl(grp_power_management),
  220. NULL,
  221. 0,0,
  222. rcGroup.right - rcGroup.left + 1,
  223. rcGroup.bottom - rcGroup.top - cy + 1,
  224. SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
  225. }
  226. //
  227. // Init idle controls
  228. //
  229. hr = m_pIJob->GetIdleWait(&m_wIdleWait, &m_wIdleDeadline);
  230. CHECK_HRESULT(hr);
  231. BREAK_ON_FAIL(hr);
  232. if (m_wIdleWait > MAX_IDLE_MINUTES)
  233. {
  234. m_wIdleWait = MAX_IDLE_MINUTES;
  235. }
  236. if (m_wIdleDeadline > MAX_IDLE_MINUTES)
  237. {
  238. m_wIdleDeadline = MAX_IDLE_MINUTES;
  239. }
  240. if (m_dwFlags & TASK_FLAG_START_ONLY_IF_IDLE)
  241. {
  242. Spin_Enable(m_hPage, spin_idle_min, m_wIdleWait);
  243. Spin_Enable(m_hPage, spin_idle_deadline, m_wIdleDeadline);
  244. Spin_SetPos(m_hPage, spin_idle_min, m_wIdleWait);
  245. Spin_SetPos(m_hPage, spin_idle_deadline, m_wIdleDeadline);
  246. }
  247. else
  248. {
  249. m_wIdleWait = SCH_DEFAULT_IDLE_TIME;
  250. m_wIdleDeadline = SCH_DEFAULT_IDLE_DEADLINE;
  251. Spin_Disable(m_hPage, spin_idle_min);
  252. Spin_Disable(m_hPage, spin_idle_deadline);
  253. }
  254. //
  255. // Set max run time
  256. //
  257. hr = pIJob->GetMaxRunTime(&m_dwMaxRunTime);
  258. CHECK_HRESULT(hr);
  259. BREAK_ON_FAIL(hr);
  260. if (m_dwMaxRunTime != (DWORD)-1)
  261. {
  262. CheckDlgButton(m_hPage, chk_stop_after, BST_CHECKED);
  263. //
  264. // Convert to minutes from milliseconds. If the value is larger
  265. // than the UI supports, reduce it.
  266. //
  267. m_dwMaxRunTime /= 60000;
  268. if (m_dwMaxRunTime > (MAX_MAXRUNTIME_HOURS * 60 + 59))
  269. {
  270. m_dwMaxRunTime = MAX_MAXRUNTIME_HOURS * 60 + 59;
  271. }
  272. WORD wHours = (WORD) (m_dwMaxRunTime / 60);
  273. WORD wMins = (WORD) (m_dwMaxRunTime % 60);
  274. Spin_SetPos(m_hPage, spin_stop_after_hr, wHours);
  275. Spin_SetPos(m_hPage, spin_stop_after_min, wMins);
  276. }
  277. else
  278. {
  279. CheckDlgButton(m_hPage, chk_stop_after, BST_UNCHECKED);
  280. Spin_Disable(m_hPage, spin_stop_after_hr);
  281. Spin_Disable(m_hPage, spin_stop_after_min);
  282. }
  283. } while (0);
  284. if (m_dwFlags & JOB_I_FLAG_NET_SCHEDULE)
  285. _DisableUI();
  286. if (FAILED(hr))
  287. {
  288. if (hr == E_OUTOFMEMORY)
  289. {
  290. _ErrorDialog(IERR_OUT_OF_MEMORY);
  291. }
  292. else
  293. {
  294. _ErrorDialog(IERR_SETTINGS_PAGE_INIT, hr);
  295. }
  296. EnableWindow(Hwnd(), FALSE);
  297. return FALSE;
  298. }
  299. m_fDirty = FALSE;
  300. return TRUE;
  301. }
  302. //+--------------------------------------------------------------------------
  303. //
  304. // Member: CSettingsPage::_DisableUI
  305. //
  306. // Synopsis: Disable UI so the user can only view the settings
  307. //
  308. // History: 2001-11-13 ShBrown Created
  309. //
  310. //---------------------------------------------------------------------------
  311. void
  312. CSettingsPage::_DisableUI(void)
  313. {
  314. HWND hwnd;
  315. if (hwnd = _hCtrl(chk_delete_when_done)) EnableWindow(hwnd, FALSE);
  316. if (hwnd = _hCtrl(chk_stop_after)) EnableWindow(hwnd, FALSE);
  317. if (hwnd = _hCtrl(txt_stop_after_hr)) EnableWindow(hwnd, FALSE);
  318. if (hwnd = _hCtrl(spin_stop_after_hr)) EnableWindow(hwnd, FALSE);
  319. if (hwnd = _hCtrl(txt_stop_after_min)) EnableWindow(hwnd, FALSE);
  320. if (hwnd = _hCtrl(spin_stop_after_min)) EnableWindow(hwnd, FALSE);
  321. if (hwnd = _hCtrl(chk_start_on_idle)) EnableWindow(hwnd, FALSE);
  322. if (hwnd = _hCtrl(txt_idle_min)) EnableWindow(hwnd, FALSE);
  323. if (hwnd = _hCtrl(spin_idle_min)) EnableWindow(hwnd, FALSE);
  324. if (hwnd = _hCtrl(txt_idle_deadline)) EnableWindow(hwnd, FALSE);
  325. if (hwnd = _hCtrl(spin_idle_deadline)) EnableWindow(hwnd, FALSE);
  326. if (hwnd = _hCtrl(chk_stop_if_not_idle)) EnableWindow(hwnd, FALSE);
  327. if (hwnd = _hCtrl(chk_dont_start_if_on_batteries)) EnableWindow(hwnd, FALSE);
  328. if (hwnd = _hCtrl(chk_kill_if_going_on_batteries)) EnableWindow(hwnd, FALSE);
  329. if (hwnd = _hCtrl(chk_system_required)) EnableWindow(hwnd, FALSE);
  330. }
  331. LRESULT
  332. CSettingsPage::_OnCommand(
  333. int id,
  334. HWND hwndCtl,
  335. UINT codeNotify)
  336. {
  337. TRACE(CSettingsPage, _OnCommand);
  338. switch (id)
  339. {
  340. case chk_stop_after:
  341. if (codeNotify != BN_CLICKED)
  342. {
  343. return TRUE;
  344. }
  345. if (IsDlgButtonChecked(m_hPage, chk_stop_after) == BST_CHECKED)
  346. {
  347. Spin_Enable(m_hPage,
  348. spin_stop_after_hr,
  349. DEFAULT_MAXRUNTIME_HOURS);
  350. Spin_Enable(m_hPage,
  351. spin_stop_after_min,
  352. DEFAULT_MAXRUNTIME_MINUTES);
  353. }
  354. else
  355. {
  356. Spin_Disable(m_hPage, spin_stop_after_hr);
  357. Spin_Disable(m_hPage, spin_stop_after_min);
  358. }
  359. break;
  360. case chk_start_on_idle:
  361. if (codeNotify != BN_CLICKED)
  362. {
  363. return TRUE;
  364. }
  365. if (IsDlgButtonChecked(m_hPage, chk_start_on_idle) == BST_CHECKED)
  366. {
  367. Spin_Enable(m_hPage, spin_idle_min, m_wIdleWait);
  368. Spin_Enable(m_hPage, spin_idle_deadline, m_wIdleDeadline);
  369. }
  370. else
  371. {
  372. Spin_Disable(m_hPage, spin_idle_min);
  373. Spin_Disable(m_hPage, spin_idle_deadline);
  374. }
  375. break;
  376. case txt_idle_min:
  377. case txt_idle_deadline:
  378. case txt_stop_after_hr:
  379. case txt_stop_after_min:
  380. if (codeNotify != EN_CHANGE)
  381. {
  382. return TRUE;
  383. }
  384. break;
  385. // case spin_stop_after_hr:
  386. // case spin_stop_after_min:
  387. // break;
  388. case chk_stop_if_not_idle:
  389. case chk_dont_start_if_on_batteries:
  390. case chk_kill_if_going_on_batteries:
  391. case chk_delete_when_done:
  392. case chk_system_required:
  393. if (codeNotify != BN_CLICKED)
  394. {
  395. return TRUE;
  396. }
  397. break;
  398. default:
  399. return FALSE;
  400. }
  401. _EnableApplyButton();
  402. return TRUE;
  403. }
  404. //+--------------------------------------------------------------------------
  405. //
  406. // Member: CSettingsPage::_ReadIdleSettings
  407. //
  408. // Synopsis: Move the idle settings from the edit controls to the member
  409. // variables, setting them on the job if they have been
  410. // updated.
  411. //
  412. // History: 07-17-1997 DavidMun Created
  413. //
  414. //---------------------------------------------------------------------------
  415. void
  416. CSettingsPage::_ReadIdleSettings()
  417. {
  418. ULONG ulSpinPos;
  419. WORD wIdleWait;
  420. WORD wIdleDeadline;
  421. //
  422. // If idle wait isn't turned on, the controls don't have meaningful
  423. // values.
  424. //
  425. if (IsDlgButtonChecked(m_hPage, chk_start_on_idle) != BST_CHECKED)
  426. {
  427. return;
  428. }
  429. ulSpinPos = Spin_GetPos(m_hPage, spin_idle_min);
  430. if (HIWORD(ulSpinPos))
  431. {
  432. wIdleWait = SCH_DEFAULT_IDLE_TIME;
  433. }
  434. else
  435. {
  436. wIdleWait = LOWORD(ulSpinPos);
  437. }
  438. ulSpinPos = Spin_GetPos(m_hPage, spin_idle_deadline);
  439. if (HIWORD(ulSpinPos))
  440. {
  441. wIdleDeadline = SCH_DEFAULT_IDLE_DEADLINE;
  442. }
  443. else
  444. {
  445. wIdleDeadline = LOWORD(ulSpinPos);
  446. }
  447. if (m_wIdleWait != wIdleWait || m_wIdleDeadline != wIdleDeadline)
  448. {
  449. HRESULT hr;
  450. hr = m_pIJob->SetIdleWait(wIdleWait, wIdleDeadline);
  451. CHECK_HRESULT(hr);
  452. if (SUCCEEDED(hr))
  453. {
  454. m_wIdleWait = wIdleWait;
  455. m_wIdleDeadline = wIdleDeadline;
  456. }
  457. }
  458. }
  459. BOOL
  460. CSettingsPage::_PerformSanityChk(void)
  461. {
  462. ULONG ul;
  463. if (IsDlgButtonChecked(m_hPage, chk_stop_after) == BST_CHECKED)
  464. {
  465. ul = GetDlgItemInt(Hwnd(), txt_stop_after_hr, NULL, FALSE);
  466. if (!ul)
  467. {
  468. ul = GetDlgItemInt(Hwnd(), txt_stop_after_min, NULL, FALSE);
  469. if (!ul)
  470. {
  471. Spin_SetPos(Hwnd(), spin_stop_after_min, 1);
  472. _ErrorDialog(IERR_MAXRUNTIME);
  473. return FALSE;
  474. }
  475. }
  476. }
  477. return TRUE;
  478. }
  479. LRESULT
  480. CSettingsPage::_OnPSNKillActive(
  481. LPARAM lParam)
  482. {
  483. TRACE(CSettingsPage, _OnPSNKillActive);
  484. if (_PerformSanityChk() == FALSE)
  485. {
  486. // Returns TRUE to prevent the page from losing the activation
  487. SetWindowLongPtr(m_hPage, DWLP_MSGRESULT, TRUE);
  488. return TRUE;
  489. }
  490. //
  491. // Make sure Schedule page is synchronized with IdleWait changes.
  492. //
  493. _ReadIdleSettings();
  494. return CPropPage::_OnPSNKillActive(lParam);
  495. }
  496. LRESULT
  497. CSettingsPage::_OnPSNSetActive(LPARAM lParam)
  498. {
  499. m_fInInit = TRUE;
  500. //
  501. // Make sure IdleWait is synchronized with Schedule page changes.
  502. //
  503. WORD wDummy;
  504. HRESULT hr = m_pIJob->GetIdleWait(&m_wIdleWait, &wDummy);
  505. if (SUCCEEDED(hr) &&
  506. IsDlgButtonChecked(m_hPage, chk_start_on_idle) == BST_CHECKED)
  507. {
  508. Spin_SetPos(m_hPage, spin_idle_min, m_wIdleWait);
  509. }
  510. m_fInInit = FALSE;
  511. return CPropPage::_OnPSNSetActive(lParam);
  512. }
  513. LRESULT
  514. CSettingsPage::_OnApply(void)
  515. {
  516. TRACE(CSettingsPage, _OnApply);
  517. //DbxDisplay("CSettingsPage::_OnApply");
  518. if (m_fDirty == FALSE)
  519. {
  520. return TRUE;
  521. }
  522. if (_PerformSanityChk() == FALSE)
  523. {
  524. SetWindowLongPtr(Hwnd(), DWLP_MSGRESULT, FALSE);
  525. return FALSE;
  526. }
  527. HRESULT hr = S_OK;
  528. ITask * pIJob = m_pIJob;
  529. DWORD dwFlags = 0;
  530. do
  531. {
  532. if (IsDlgButtonChecked(m_hPage, chk_start_on_idle) == BST_CHECKED)
  533. {
  534. dwFlags |= TASK_FLAG_START_ONLY_IF_IDLE;
  535. }
  536. if (IsDlgButtonChecked(m_hPage, chk_stop_if_not_idle) == BST_CHECKED)
  537. {
  538. dwFlags |= TASK_FLAG_KILL_ON_IDLE_END;
  539. }
  540. if (IsDlgButtonChecked(m_hPage, chk_dont_start_if_on_batteries)
  541. == BST_CHECKED)
  542. {
  543. dwFlags |= TASK_FLAG_DONT_START_IF_ON_BATTERIES;
  544. }
  545. if (IsDlgButtonChecked(m_hPage, chk_kill_if_going_on_batteries) ==
  546. BST_CHECKED)
  547. {
  548. dwFlags |= TASK_FLAG_KILL_IF_GOING_ON_BATTERIES;
  549. }
  550. if (IsDlgButtonChecked(m_hPage, chk_system_required) ==
  551. BST_CHECKED)
  552. {
  553. dwFlags |= TASK_FLAG_SYSTEM_REQUIRED;
  554. }
  555. if (IsDlgButtonChecked(m_hPage, chk_delete_when_done) == BST_CHECKED)
  556. {
  557. dwFlags |= TASK_FLAG_DELETE_WHEN_DONE;
  558. }
  559. if ((m_dwFlags & TASK_FLAGS_IN_SETTINGS_PAGE) != dwFlags)
  560. {
  561. hr = pIJob->GetFlags(&m_dwFlags);
  562. CHECK_HRESULT(hr);
  563. BREAK_ON_FAIL(hr);
  564. dwFlags |= (m_dwFlags & ~TASK_FLAGS_IN_SETTINGS_PAGE);
  565. hr = pIJob->SetFlags(dwFlags);
  566. CHECK_HRESULT(hr);
  567. BREAK_ON_FAIL(hr);
  568. m_dwFlags = dwFlags;
  569. }
  570. _ReadIdleSettings();
  571. DWORD dwMins = (DWORD)-1;
  572. if (IsDlgButtonChecked(m_hPage, chk_stop_after) == BST_CHECKED)
  573. {
  574. ULONG ulSpinPos = Spin_GetPos(m_hPage, spin_stop_after_hr);
  575. if (HIWORD(ulSpinPos))
  576. {
  577. dwMins = DEFAULT_MAXRUNTIME_HOURS * 60;
  578. }
  579. else
  580. {
  581. dwMins = LOWORD(ulSpinPos) * 60;
  582. }
  583. ulSpinPos = Spin_GetPos(m_hPage, spin_stop_after_min);
  584. if (HIWORD(ulSpinPos))
  585. {
  586. dwMins += DEFAULT_MAXRUNTIME_MINUTES;
  587. }
  588. else
  589. {
  590. dwMins += LOWORD(ulSpinPos);
  591. }
  592. }
  593. Win4Assert(dwMins != 0);
  594. if (m_dwMaxRunTime != dwMins)
  595. {
  596. // Max run time is in milliseconds
  597. hr = pIJob->SetMaxRunTime(
  598. ((dwMins == (DWORD)-1) ? (DWORD)-1 : (dwMins * 60000)));
  599. CHECK_HRESULT(hr);
  600. BREAK_ON_FAIL(hr);
  601. m_dwMaxRunTime = dwMins;
  602. }
  603. //
  604. // reset dirty flag
  605. //
  606. m_fDirty = FALSE;
  607. //
  608. // If evrything went well see if the other pages are ready to
  609. // save the job to storage.
  610. //
  611. if ((m_fPersistChanges == TRUE) &&
  612. (PropSheet_QuerySiblings(GetParent(Hwnd()),
  613. QUERY_READY_TO_BE_SAVED, 0))
  614. == 0)
  615. {
  616. //
  617. // Save the job file to storage.
  618. //
  619. // First, fetch general page task, application dirty status flags.
  620. // Default to not dirty if the general page isn't present.
  621. //
  622. BOOL fTaskApplicationChange = FALSE;
  623. PropSheet_QuerySiblings(GetParent(Hwnd()),
  624. QUERY_TASK_APPLICATION_DIRTY_STATUS,
  625. (LPARAM)&fTaskApplicationChange);
  626. BOOL fTaskAccountChange = FALSE;
  627. PropSheet_QuerySiblings(GetParent(Hwnd()),
  628. QUERY_TASK_ACCOUNT_INFO_DIRTY_STATUS,
  629. (LPARAM)&fTaskAccountChange);
  630. BOOL fSuppressAccountInfoRequest = FALSE;
  631. PropSheet_QuerySiblings(GetParent(Hwnd()),
  632. QUERY_SUPPRESS_ACCOUNT_INFO_REQUEST_FLAG,
  633. (LPARAM)&fSuppressAccountInfoRequest);
  634. hr = JFSaveJob(Hwnd(),
  635. pIJob,
  636. this->GetPlatformId() == VER_PLATFORM_WIN32_NT &&
  637. this->IsTaskInTasksFolder(),
  638. fTaskAccountChange,
  639. fTaskApplicationChange,
  640. fSuppressAccountInfoRequest);
  641. CHECK_HRESULT(hr);
  642. BREAK_ON_FAIL(hr);
  643. PropSheet_QuerySiblings(GetParent(Hwnd()),
  644. RESET_TASK_APPLICATION_DIRTY_STATUS, 0);
  645. PropSheet_QuerySiblings(GetParent(Hwnd()),
  646. RESET_TASK_ACCOUNT_INFO_DIRTY_STATUS, 0);
  647. PropSheet_QuerySiblings(GetParent(Hwnd()),
  648. RESET_SUPPRESS_ACCOUNT_INFO_REQUEST_FLAG, 0);
  649. //
  650. // Instruct the general page to refresh account information.
  651. //
  652. PropSheet_QuerySiblings(GetParent(Hwnd()),
  653. TASK_ACCOUNT_CHANGE_NOTIFY, 0);
  654. }
  655. } while (0);
  656. if (FAILED(hr))
  657. {
  658. if (hr == E_OUTOFMEMORY)
  659. {
  660. _ErrorDialog(IERR_OUT_OF_MEMORY);
  661. }
  662. else if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))
  663. {
  664. _ErrorDialog(IERR_FILE_NOT_FOUND);
  665. }
  666. else if (hr == HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED))
  667. {
  668. _ErrorDialog(IERR_ACCESS_DENIED);
  669. }
  670. else
  671. {
  672. _ErrorDialog(IERR_INTERNAL_ERROR, hr);
  673. }
  674. }
  675. return TRUE;
  676. }
  677. LRESULT
  678. CSettingsPage::_OnPSMQuerySibling(
  679. WPARAM wParam,
  680. LPARAM lParam)
  681. {
  682. int iRet = 0;
  683. switch (wParam)
  684. {
  685. case QUERY_READY_TO_BE_SAVED:
  686. iRet = (int)m_fDirty;
  687. break;
  688. }
  689. SetWindowLongPtr(Hwnd(), DWLP_MSGRESULT, iRet);
  690. return iRet;
  691. }
  692. HRESULT
  693. GetSettingsPage(
  694. ITask * pIJob,
  695. LPTSTR ptszTaskPath,
  696. BOOL fPersistChanges,
  697. HPROPSHEETPAGE * phpage)
  698. {
  699. Win4Assert(pIJob != NULL);
  700. Win4Assert(phpage != NULL);
  701. LPTSTR ptszPath = NULL;
  702. HRESULT hr = S_OK;
  703. WORD cTriggers = 0;
  704. do
  705. {
  706. //
  707. // Get the job name.
  708. //
  709. if (ptszTaskPath != NULL)
  710. {
  711. //
  712. // Use passed-in path
  713. //
  714. ptszPath = ptszTaskPath;
  715. }
  716. else
  717. {
  718. //
  719. // Obtain the job path from the interfaces.
  720. //
  721. hr = GetJobPath(pIJob, &ptszPath);
  722. BREAK_ON_FAIL(hr);
  723. }
  724. hr = pIJob->GetTriggerCount(&cTriggers);
  725. if (FAILED(hr))
  726. {
  727. CHECK_HRESULT(hr);
  728. break;
  729. }
  730. CSettingsPage * pPage = new CSettingsPage(
  731. pIJob,
  732. ptszPath,
  733. fPersistChanges);
  734. if (pPage == NULL)
  735. {
  736. hr = E_OUTOFMEMORY;
  737. CHECK_HRESULT(hr);
  738. break;
  739. }
  740. HPROPSHEETPAGE hpage = CreatePropertySheetPage(&pPage->m_psp);
  741. if (hpage == NULL)
  742. {
  743. delete pPage;
  744. hr = E_OUTOFMEMORY;
  745. CHECK_HRESULT(hr);
  746. break;
  747. }
  748. *phpage = hpage;
  749. } while (0);
  750. //
  751. // If we made a copy of pIJob's path string, free it.
  752. //
  753. if (ptszPath != ptszTaskPath)
  754. {
  755. delete [] ptszPath;
  756. }
  757. return hr;
  758. }
  759. HRESULT
  760. AddSettingsPage(
  761. PROPSHEETHEADER &psh,
  762. ITask * pIJob)
  763. {
  764. HPROPSHEETPAGE hpage = NULL;
  765. HRESULT hr = GetSettingsPage(pIJob, NULL, TRUE, &hpage);
  766. if (SUCCEEDED(hr))
  767. {
  768. psh.phpage[psh.nPages++] = hpage;
  769. }
  770. return hr;
  771. }
  772. HRESULT
  773. AddSettingsPage(
  774. LPFNADDPROPSHEETPAGE lpfnAddPage,
  775. LPARAM cookie,
  776. ITask * pIJob)
  777. {
  778. HPROPSHEETPAGE hpage = NULL;
  779. HRESULT hr = GetSettingsPage(pIJob, NULL, TRUE, &hpage);
  780. CHECK_HRESULT(hr);
  781. if (SUCCEEDED(hr))
  782. {
  783. if (!lpfnAddPage(hpage, cookie))
  784. {
  785. DestroyPropertySheetPage(hpage);
  786. hr = E_FAIL;
  787. CHECK_HRESULT(hr);
  788. }
  789. }
  790. return hr;
  791. }