Source code of Windows XP (NT5)
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.

844 lines
22 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // SCHEDWIZ.CPP / Tuneup
  4. //
  5. // Microsoft Confidential
  6. // Copyright (c) Microsoft Corporation 1998
  7. // All rights reserved
  8. //
  9. // Functions for the summary wizard page.
  10. //
  11. // 8/98 - Jason Cohen (JCOHEN)
  12. //
  13. //////////////////////////////////////////////////////////////////////////////
  14. //
  15. // Internal include file(s).
  16. //
  17. #include <windows.h>
  18. #include <prsht.h>
  19. #include "schedwiz.h"
  20. #include "main.h"
  21. //#include "resource.h"
  22. //#include "mstask.h"
  23. #include <io.h>
  24. //#include <oleguid.h>
  25. //
  26. // Internal defined value(s).
  27. //
  28. #define TASK_BIMONTH_ODD (TASK_JANUARY | TASK_MARCH | TASK_MAY | TASK_JULY | TASK_SEPTEMBER | TASK_NOVEMBER)
  29. #define TASK_BIMONTH_EVEN (TASK_FEBRUARY | TASK_APRIL | TASK_JUNE | TASK_AUGUST | TASK_OCTOBER | TASK_DECEMBER)
  30. #define TASK_QUARTER_1 (TASK_JANUARY | TASK_MAY | TASK_SEPTEMBER)
  31. #define TASK_QUARTER_2 (TASK_FEBRUARY | TASK_JUNE | TASK_OCTOBER)
  32. #define TASK_QUARTER_3 (TASK_MARCH | TASK_JULY | TASK_NOVEMBER)
  33. #define TASK_QUARTER_4 (TASK_APRIL | TASK_AUGUST | TASK_DECEMBER)
  34. #define TASK_WHOLE_YEAR (TASK_BIMONTH_ODD | TASK_BIMONTH_EVEN)
  35. //
  36. // Internal defined macro(s).
  37. //
  38. #define E_JOB_FAIL(x) (x == E_OUTOFMEMORY ? IDS_OUTOFMEMORY : IDS_JOB_CREATE_FAIL)
  39. //
  40. // Internal global variable(s).
  41. //
  42. ITaskScheduler *g_psa = NULL;
  43. //
  44. // Inernal function prototype(s).
  45. //
  46. static VOID InitJobTime(TASK_TRIGGER *, INT, INT);
  47. static BOOL GetJobFileName(LPTSTR, LPTSTR);
  48. static VOID IncDate(LPWORD, LPWORD, LPWORD, INT);
  49. static BOOL DeleteOrgJobFile(LPTSTR);
  50. static INT WeekDayToNum(INT);
  51. static VOID taskSetNextDay(TASK_TRIGGER *);
  52. static BOOL IsScheduledTasks(LPTASKDATA);
  53. static BOOL GetTaskTrigger(ITask *, TASK_TRIGGER *);
  54. //
  55. // External function(s).
  56. //
  57. BOOL InitJobs(LPTASKDATA lpGlobalTasks)
  58. {
  59. ITaskTrigger *pTrigger = NULL;
  60. WORD wTrigger;
  61. HRESULT hResult;
  62. BOOL bErr = FALSE;
  63. LPTASKDATA lpTask;
  64. #ifdef _UNICODE
  65. LPWSTR lpwBuffer;
  66. #else // _UNICODE
  67. WCHAR szwBuffer[256];
  68. LPWSTR lpwBuffer = szwBuffer;
  69. #endif // _UNICODE
  70. // Initialize the COM library.
  71. //
  72. if ( ( (hResult = CoInitialize(NULL)) != S_OK ) && (hResult == S_FALSE) )
  73. return FALSE;
  74. // Initialize ISchedulingAgent.
  75. //
  76. if ( CoCreateInstance(CLSID_CSchedulingAgent, NULL, CLSCTX_INPROC_SERVER, IID_ISchedulingAgent, (void **) &g_psa) != S_OK )
  77. return FALSE;
  78. for (lpTask = lpGlobalTasks; lpTask && !bErr; lpTask = lpTask->lpNext)
  79. {
  80. // Load the task (.job) with ITaskScheduler::Activate().
  81. //
  82. ANSIWCHAR(lpwBuffer, lpTask->lpJobName, sizeof(szwBuffer));
  83. if ( (hResult = g_psa->Activate((LPCWSTR) lpwBuffer, IID_ITask, (IUnknown**) &lpTask->pTask)) == E_OUTOFMEMORY )
  84. bErr = ErrMsg(NULL, IDS_OUTOFMEMORY);
  85. else
  86. {
  87. // We should search for a task with the same app name if the
  88. // above activate call failed.
  89. //
  90. if ( hResult == S_OK )
  91. {
  92. // Get the existing flags for the job with IScheduledWorkItem::GetFlags().
  93. //
  94. if ( (hResult = lpTask->pTask->GetFlags(&lpTask->dwFlags)) == S_OK )
  95. {
  96. // Setup our internal flags for the task.
  97. //
  98. if ( lpTask->dwFlags & TASK_FLAG_DISABLED )
  99. lpTask->dwOptions &= ~TASK_SCHEDULED;
  100. else
  101. lpTask->dwOptions |= TASK_SCHEDULED;
  102. // IScheduledWorkItem::GetTrigger().
  103. //
  104. // TODO: why do we need this data saved.
  105. //
  106. if ( (hResult = lpTask->pTask->GetTrigger((WORD) 0, &pTrigger)) == S_OK )
  107. {
  108. pTrigger->GetTrigger(&lpTask->Trigger);
  109. pTrigger->Release();
  110. }
  111. }
  112. }
  113. // If we didn't load the entire task successfully, we should
  114. // delete any that is there and create a new one.
  115. //
  116. if (hResult != S_OK)
  117. {
  118. // Delete existing (maybe corrupted) job file.
  119. //
  120. if ( !DeleteOrgJobFile(lpTask->lpJobName) )
  121. bErr = ErrMsg(NULL, IDS_DEL_FILE);
  122. else
  123. {
  124. ANSIWCHAR(lpwBuffer, lpTask->lpJobName, sizeof(szwBuffer));
  125. hResult = g_psa->NewWorkItem((LPCWSTR) lpwBuffer, CLSID_CTask, IID_ITask, (IUnknown**) &lpTask->pTask);
  126. if ( (hResult != S_OK) || (lpTask->pTask == NULL) )
  127. bErr = ErrMsg(NULL, E_JOB_FAIL(hResult));
  128. else
  129. {
  130. // Make sure Tuneup knows this is a new task and is
  131. // scheduled by default.
  132. //
  133. lpTask->dwOptions |= TASK_NEW;
  134. lpTask->dwOptions |= TASK_SCHEDULED;
  135. // Set the application name to the full path name of the task.
  136. //
  137. ANSIWCHAR(lpwBuffer, lpTask->lpFullPathName, sizeof(szwBuffer));
  138. lpTask->pTask->SetApplicationName((LPCWSTR) lpwBuffer);
  139. // Set the working directory for the task (always empty string).
  140. //
  141. lpTask->pTask->SetWorkingDirectory((LPCWSTR) L"");
  142. // Set the parameters for the task (not required).
  143. //
  144. if ( lpTask->lpParameters )
  145. {
  146. ANSIWCHAR(lpwBuffer, lpTask->lpParameters, sizeof(szwBuffer));
  147. lpTask->pTask->SetParameters(lpwBuffer);
  148. }
  149. // Set the comment for the task (not required).
  150. //
  151. if ( lpTask->lpComment )
  152. {
  153. ANSIWCHAR(lpwBuffer, lpTask->lpComment, sizeof(szwBuffer));
  154. lpTask->pTask->SetComment(lpwBuffer);
  155. }
  156. // Set the default flags for the task.
  157. //
  158. lpTask->pTask->SetFlags(lpTask->dwFlags);
  159. // For some reason we do this for all tasks
  160. // but cleanup.
  161. //
  162. if ( !( lpTask->dwOptions & TASK_NOIDLE ) )
  163. lpTask->pTask->SetIdleWait(10, 999);
  164. // Create trigger item.
  165. //
  166. if ( (hResult = lpTask->pTask->CreateTrigger(&wTrigger, &pTrigger)) != S_OK)
  167. bErr = ErrMsg(NULL, E_JOB_FAIL(hResult));
  168. else
  169. {
  170. InitJobTime(&lpTask->Trigger, lpTask->nSchedule, g_nTimeScheme);
  171. pTrigger->SetTrigger(&lpTask->Trigger);
  172. pTrigger->Release();
  173. }
  174. }
  175. }
  176. }
  177. }
  178. }
  179. if (bErr)
  180. ReleaseJobs(lpGlobalTasks, FALSE);
  181. return bErr;
  182. }
  183. VOID ReleaseJobs(LPTASKDATA lpGlobalTasks, BOOL bFinish)
  184. {
  185. ITaskTrigger *pTrigger;
  186. IPersistFile *pPersistFile;
  187. LPTASKDATA lpTask;
  188. for (lpTask = lpGlobalTasks; lpTask; lpTask = lpTask->lpNext)
  189. {
  190. // Check to see if used in initialization fail handler
  191. // or the item is not needed.
  192. //
  193. if ( lpTask->pTask != (ITask*) NULL )
  194. {
  195. if ( ( lpTask->dwOptions & TASK_NEW ) && !bFinish )
  196. {
  197. // The .job is newly created, and user choose Cancel.
  198. //
  199. DeleteOrgJobFile(lpTask->lpJobName);
  200. }
  201. else
  202. {
  203. // Even if the item is not scheduled, we still save it, because we
  204. // use the Enable/Disable flag in the .job to keep the Yes/No state.
  205. //
  206. if (bFinish)
  207. {
  208. // Take care the flag only, since the Task_Trigger is
  209. // auto saved in Schedule property page.
  210. //
  211. if ( !(g_dwFlags & TUNEUP_CUSTOM) || (lpTask->dwOptions & TASK_SCHEDULED) )
  212. lpTask->dwFlags &= ~TASK_FLAG_DISABLED;
  213. else
  214. lpTask->dwFlags |= TASK_FLAG_DISABLED;
  215. }
  216. else
  217. {
  218. // User canceled so restore Task_Trigger.
  219. //
  220. if ( lpTask->pTask->GetTrigger((WORD) 0, &pTrigger) == S_OK )
  221. {
  222. pTrigger->SetTrigger(&lpTask->Trigger);
  223. pTrigger->Release();
  224. }
  225. }
  226. // Set or restore flags.
  227. //
  228. lpTask->pTask->SetFlags(lpTask->dwFlags);
  229. // Save the file, release the interfaces.
  230. //
  231. if ( lpTask->pTask->QueryInterface(IID_IPersistFile, (VOID **) &pPersistFile) == S_OK )
  232. {
  233. pPersistFile->Save((LPCOLESTR) NULL, TRUE);
  234. pPersistFile->Release();
  235. }
  236. lpTask->pTask->Release();
  237. /* BUGBUG: I don't understand why this is here!
  238. // Rename the old task.
  239. //
  240. if ( ItemData[i].lpOldTaskName )
  241. {
  242. if ( bSave )
  243. {
  244. TCHAR szSrc[MAX_PATH],
  245. szTgt[MAX_PATH],
  246. *ptr;
  247. //GetJobFileName(i, szTgt); // get filename for delete or hide
  248. DeleteFile(szTgt);
  249. lstrcpy(szSrc, szTgt);
  250. if ( ptr = strrchr(szSrc, '\\') )
  251. lstrcpy(ptr+1, ItemData[i].lpOldTaskName);
  252. MoveFile(szSrc, szTgt);
  253. }
  254. }
  255. */
  256. }
  257. }
  258. }
  259. // Release ISchedulingAgent.
  260. //
  261. g_psa->Release();
  262. // Close the OLE COM library.
  263. //
  264. CoUninitialize();
  265. }
  266. //////////////////////////////////////////////////////////////////////////////
  267. //
  268. // EXTERNAL:
  269. // JobReschedule()
  270. // - Reschedules a particular job.
  271. //
  272. // ENTRY:
  273. // hDlg - Parent dialog for property sheet.
  274. //
  275. // EXIT:
  276. // BOOL
  277. //
  278. //////////////////////////////////////////////////////////////////////////////
  279. BOOL JobReschedule(HWND hDlg, ITask * pJob)
  280. {
  281. HPROPSHEETPAGE hpsp[1];
  282. PROPSHEETHEADER psh;
  283. TASK_TRIGGER OldTrigger,
  284. NewTrigger;
  285. IProvideTaskPage *pProvideTaskPage;
  286. LPTSTR lpCaption;
  287. if ( pJob->QueryInterface(IID_IProvideTaskPage, (VOID**) &pProvideTaskPage) != S_OK )
  288. return FALSE;
  289. // We need the Schedule page only.
  290. //
  291. if ( pProvideTaskPage->GetPage(TASKPAGE_SCHEDULE, TRUE, &(hpsp[0])) != S_OK )
  292. return FALSE;
  293. // Get the caption string.
  294. //
  295. lpCaption = AllocateString(NULL, IDS_RESCHED);
  296. // Setup the property page header.
  297. //
  298. psh.dwSize = sizeof(PROPSHEETHEADER);
  299. psh.dwFlags = PSH_DEFAULT | PSH_NOAPPLYNOW;
  300. psh.hwndParent = hDlg;
  301. psh.nPages = 1;
  302. psh.nStartPage = 0;
  303. psh.phpage = (HPROPSHEETPAGE *) hpsp;
  304. psh.pszCaption = lpCaption;
  305. // Keep original trigger.
  306. //
  307. GetTaskTrigger(pJob, &OldTrigger);
  308. // Display the property sheet page.
  309. //
  310. PropertySheet(&psh);
  311. // Release the page and other resources.
  312. //
  313. FREE(lpCaption);
  314. pProvideTaskPage->Release();
  315. // Get the new trigger, compare it to see whether it's changed.
  316. //
  317. GetTaskTrigger(pJob, &NewTrigger);
  318. // If the new time and the old time don't compare, then
  319. // we must change the time scheme to custom.
  320. //
  321. if ( memcmp((const void *) &OldTrigger, (const void *) &NewTrigger, sizeof(TASK_TRIGGER)) == 0 )
  322. return FALSE;
  323. return TRUE;
  324. }
  325. LPTSTR GetTaskTriggerText(ITask * pTask)
  326. {
  327. LPWSTR lpwBuffer;
  328. LPTSTR lpReturn = NULL;
  329. #ifdef _UNICODE
  330. LPTSTR lpBuffer;
  331. #else // _UNICODE
  332. TCHAR szBuffer[256];
  333. LPTSTR lpBuffer = szBuffer;
  334. #endif // _UNICODE
  335. if ( pTask->GetTriggerString((WORD) 0, (LPWSTR *) &lpwBuffer) == S_OK )
  336. {
  337. // Convert the string if _UNICODE is not defined and set the
  338. // window to the new text.
  339. //
  340. WCHARANSI(lpBuffer, lpwBuffer, sizeof(szBuffer));
  341. if ( lpReturn = (LPTSTR) MALLOC(sizeof(TCHAR) * (lstrlen(lpBuffer) + 1)) )
  342. lstrcpy(lpReturn, lpBuffer);
  343. // Free the string returned from IScheduledWorkitem::GetTriggerString().
  344. //
  345. CoTaskMemFree(lpwBuffer);
  346. }
  347. return lpReturn;
  348. }
  349. LPTSTR GetNextRunTimeText(ITask * pTask, DWORD dwFlags)
  350. {
  351. TCHAR szTime[128],
  352. szDate[128];
  353. LPTSTR lpReturn = NULL;
  354. SYSTEMTIME stm;
  355. // If it's disabled, we can't get run time string.
  356. // JobRelease will clear it if the user cancels.
  357. //
  358. if ( dwFlags & TASK_FLAG_DISABLED )
  359. {
  360. dwFlags &= ~TASK_FLAG_DISABLED;
  361. pTask->SetFlags(dwFlags);
  362. }
  363. pTask->GetNextRunTime(&stm);
  364. if ( ( GetTimeFormat(GetUserDefaultLCID(), TIME_NOSECONDS, &stm, NULL, (LPTSTR) szTime, sizeof(szTime) / sizeof(TCHAR)) ) &&
  365. ( GetDateFormat(GetUserDefaultLCID(), DATE_LONGDATE, &stm, NULL, (LPTSTR) szDate, sizeof(szDate) / sizeof(TCHAR)) ) &&
  366. ( lpReturn = (LPTSTR) MALLOC(sizeof(TCHAR) * (lstrlen(szTime) + lstrlen(szDate) + 3)) ) )
  367. {
  368. wsprintf(lpReturn, _T("%s, %s"), szTime, szDate);
  369. }
  370. return lpReturn;
  371. }
  372. VOID SetTimeScheme(INT nTimeScheme)
  373. {
  374. ITaskTrigger *pTrigger;
  375. TASK_TRIGGER SchemeTrigger;
  376. LPTASKDATA lpTask;
  377. // Reset the static values in InitJobTime() since
  378. // we are resetting all the job times.
  379. //
  380. InitJobTime(NULL, 0, 0);
  381. // Go through all the tasks and update the task trigger for
  382. // the new time scheme.
  383. //
  384. for (lpTask = g_Tasks; lpTask; lpTask = lpTask->lpNext)
  385. {
  386. // Get the ITaskTrigger interface so we can set the task trigger.
  387. //
  388. if (lpTask->pTask->GetTrigger((WORD) 0, &pTrigger) == S_OK)
  389. {
  390. // Get the new task trigger for this job.
  391. //
  392. InitJobTime(&SchemeTrigger, lpTask->nSchedule, nTimeScheme);
  393. // Save the new task trigger to the job.
  394. //
  395. pTrigger->SetTrigger(&SchemeTrigger);
  396. // Release the ITaskTrigger interface.
  397. //
  398. pTrigger->Release();
  399. }
  400. }
  401. }
  402. static VOID InitJobTime(TASK_TRIGGER *pTrigger, INT nSchedule, INT nTimeScheme)
  403. {
  404. SYSTEMTIME stNow;
  405. static INT nMonthDay = 0, // Used to stagger monthly items.
  406. nWeekDay = 1, // Used to staggar weekly items.
  407. nOnceDay = 1; // Used to staggar once items.
  408. INT nDays[] = { TASK_SUNDAY, TASK_MONDAY, TASK_TUESDAY, TASK_WEDNESDAY, TASK_THURSDAY, TASK_FRIDAY, TASK_SATURDAY };
  409. INT nMonths[] = { TASK_JANUARY, TASK_FEBRUARY, TASK_MARCH, TASK_APRIL, TASK_MAY, TASK_JUNE, TASK_JULY, TASK_AUGUST, TASK_SEPTEMBER, TASK_OCTOBER, TASK_NOVEMBER, TASK_DECEMBER };
  410. INT nQuarters[] = { TASK_QUARTER_1, TASK_QUARTER_2, TASK_QUARTER_3, TASK_QUARTER_4 };
  411. // If NULL is passed in for pTrigger, we should reset the
  412. // initial values used for scheduling the tasks.
  413. //
  414. if ( pTrigger == NULL )
  415. {
  416. // Reset the static values.
  417. //
  418. nMonthDay = 0;
  419. nWeekDay = 1;
  420. nOnceDay = 1;
  421. return;
  422. }
  423. // Init the default trigger structure values.
  424. //
  425. ZeroMemory(pTrigger, sizeof(TASK_TRIGGER));
  426. pTrigger->cbTriggerSize = sizeof(TASK_TRIGGER);
  427. pTrigger->MinutesDuration = 999;
  428. // Set the trigger to activate today.
  429. //
  430. GetLocalTime(&stNow);
  431. pTrigger->wBeginMonth = stNow.wMonth;
  432. pTrigger->wBeginDay = stNow.wDay;
  433. pTrigger->wBeginYear = stNow.wYear;
  434. // Set the start hour and minute based on the time scheme.
  435. //
  436. switch (nTimeScheme)
  437. {
  438. case IDC_NIGHT:
  439. pTrigger->wStartHour = 0;
  440. pTrigger->wStartMinute = 0;
  441. break;
  442. case IDC_DAY:
  443. pTrigger->wStartHour = 12;
  444. pTrigger->wStartMinute = 00;
  445. break;
  446. case IDC_EVENING:
  447. pTrigger->wStartHour = 20;
  448. pTrigger->wStartMinute = 0;
  449. break;
  450. }
  451. // Set the schedule (once, daily, weekly, monthly, bimonthly, quarterly, or yearly).
  452. // The day of the week or month is incrimented each time so that once, weekly and
  453. // monthly tasks aren't scheduled for the same days.
  454. //
  455. switch (nSchedule)
  456. {
  457. case TASK_ONCE:
  458. pTrigger->TriggerType = TASK_TIME_TRIGGER_ONCE;
  459. IncDate(&(pTrigger->wBeginMonth), &(pTrigger->wBeginDay), &(pTrigger->wBeginYear), nOnceDay++);
  460. pTrigger->wStartHour += 2;
  461. break;
  462. case TASK_DAILY:
  463. pTrigger->TriggerType = TASK_TIME_TRIGGER_DAILY;
  464. pTrigger->Type.Daily.DaysInterval = 1;
  465. break;
  466. case TASK_WEEKLY:
  467. pTrigger->TriggerType = TASK_TIME_TRIGGER_WEEKLY;
  468. pTrigger->Type.Weekly.rgfDaysOfTheWeek = (USHORT)nDays[(((stNow.wDayOfWeek + nWeekDay++) % 7) + 7) % 7];
  469. pTrigger->Type.Weekly.WeeksInterval = 1;
  470. pTrigger->wStartMinute += 30;
  471. break;
  472. case TASK_MONTHLY:
  473. case TASK_BIMONTHLY:
  474. case TASK_QUARTLY:
  475. case TASK_YEARLY:
  476. pTrigger->TriggerType = TASK_TIME_TRIGGER_MONTHLYDATE;
  477. pTrigger->Type.MonthlyDate.rgfDays = (nMonthDay++ % 28) + 1;
  478. pTrigger->wStartHour++;
  479. switch (nSchedule)
  480. {
  481. case TASK_MONTHLY:
  482. pTrigger->Type.MonthlyDate.rgfMonths = TASK_WHOLE_YEAR;
  483. break;
  484. case TASK_BIMONTHLY:
  485. pTrigger->Type.MonthlyDate.rgfMonths = ((stNow.wMonth % 2) ? TASK_BIMONTH_EVEN : TASK_BIMONTH_ODD);
  486. break;
  487. case TASK_QUARTLY:
  488. pTrigger->Type.MonthlyDate.rgfMonths = (USHORT)nQuarters[(((stNow.wMonth + 1) % 4) + 4) % 4];
  489. break;
  490. case TASK_YEARLY:
  491. pTrigger->Type.MonthlyDate.rgfMonths = (USHORT)nMonths[(((stNow.wMonth + 1) % 12) + 12) % 12];
  492. break;
  493. }
  494. break;
  495. }
  496. }
  497. static VOID IncDate(LPWORD lpwMonth, LPWORD lpwDay, LPWORD lpwYear, INT iDays)
  498. {
  499. SYSTEMTIME SysTime;
  500. FILETIME FileTime;
  501. LARGE_INTEGER LargeInt;
  502. BOOL bTwoDigit;
  503. // Setup the system structure.
  504. //
  505. ZeroMemory(&SysTime, sizeof(SYSTEMTIME));
  506. SysTime.wMonth = *lpwMonth;
  507. SysTime.wDay = *lpwDay;
  508. SysTime.wYear = *lpwYear;
  509. // Support two digit dates.
  510. //
  511. if ( bTwoDigit = ( SysTime.wYear < 100 ) )
  512. {
  513. if ( SysTime.wYear >= 80 )
  514. SysTime.wYear += 1900;
  515. else
  516. SysTime.wYear += 2000;
  517. }
  518. // Convert it to file time.
  519. //
  520. SystemTimeToFileTime(&SysTime, &FileTime);
  521. // Copy it to a large integer so we can add or subtract days.
  522. //
  523. memcpy(&LargeInt, &FileTime, sizeof(LARGE_INTEGER));
  524. // Add or subtract the days in nanoseconds.
  525. //
  526. LargeInt.QuadPart += iDays * Int32x32To64(24 * 60 * 60, 1000 * 10000);
  527. // Copy it back to the filetime structure.
  528. //
  529. memcpy(&FileTime, &LargeInt, sizeof(LARGE_INTEGER));
  530. // Convert it back to a systime structure.
  531. //
  532. FileTimeToSystemTime(&FileTime, &SysTime);
  533. // Return supported two digit dates.
  534. //
  535. if ( bTwoDigit )
  536. {
  537. if ( SysTime.wYear <= 2000 )
  538. SysTime.wYear -= 1900;
  539. else
  540. SysTime.wYear -= 2000;
  541. }
  542. // Return the new date.
  543. //
  544. *lpwMonth = SysTime.wMonth;
  545. *lpwDay = SysTime.wDay;
  546. *lpwYear = SysTime.wYear;
  547. }
  548. //////////////////////////////////////////////////////////////////////////////
  549. //
  550. // INTERNAL:
  551. // GetJobFileName()
  552. // This routine returns the full path and file name to the job file
  553. // specified by the job name passed in.
  554. //
  555. // ENTRY:
  556. // LPTSTR lpJobName
  557. // This is the name of the job (as it appears in Task Scheduler) passed in.
  558. //
  559. // LPTSTR lpJobFileName
  560. // This is the buffer that receives the full path and file name of the job
  561. // (%WINDIR%\Tasks\lpJobName.JOB). Should be atleast MAX_PATH.
  562. //
  563. //
  564. // EXIT:
  565. // BOOL
  566. // TRUE - Successfully retrieved all the information and filled in the buffer.
  567. // FALSE - Something failed.
  568. //
  569. //////////////////////////////////////////////////////////////////////////////
  570. static BOOL GetJobFileName(LPTSTR lpJobName, LPTSTR lpJobFileName)
  571. {
  572. TCHAR szWindowsDir[MAX_PATH];
  573. LPTSTR lpTaskDir,
  574. lpJobExt;
  575. DWORD dwLength;
  576. // Get the windows directory.
  577. //
  578. if ( GetWindowsDirectory(szWindowsDir, sizeof(szWindowsDir)) == 0 )
  579. return FALSE;
  580. // Get rid of the backslash if windows is in the root of a drive.
  581. //
  582. if ( (dwLength = lstrlen(szWindowsDir)) == 3 )
  583. szWindowsDir[dwLength - 1] = _T('\0');
  584. // Get the task dir from the string resource.
  585. //
  586. if ( (lpTaskDir = AllocateString(NULL, IDS_TASKDIR)) == NULL )
  587. return FALSE;
  588. // Get the job extension from the string resource.
  589. //
  590. if ( (lpJobExt = AllocateString(NULL, IDS_JOBEXT)) == NULL )
  591. {
  592. FREE(lpTaskDir);
  593. return FALSE;
  594. }
  595. // Create the job name with all the data we have.
  596. //
  597. wsprintf(lpJobFileName, _T("%s%s\\%s%s"), szWindowsDir, lpTaskDir, lpJobName, lpJobExt);
  598. FREE(lpJobExt);
  599. FREE(lpTaskDir);
  600. return TRUE;
  601. }
  602. /*
  603. void ConcatNextRunTime(LPSTR szOrgText, int nItem)
  604. {
  605. int nLen;
  606. SYSTEMTIME stm;
  607. char szTemp[128];
  608. DWORD dwFlags;
  609. lstrcat(szOrgText, "\n");
  610. // get next run time string
  611. dwFlags = ItemData[nItem].dwFlags;
  612. dwFlags &= ~TASK_FLAG_DISABLED; // if it's disabled, we can't get run time string
  613. pTask[nItem]->SetFlags(dwFlags); // JobRelease will clear it if Cancel finally
  614. pTask[nItem]->GetNextRunTime(&stm);
  615. if (GetTimeFormat(GetUserDefaultLCID(), TIME_NOSECONDS, &stm, NULL,
  616. (LPTSTR)szTemp, 128)) {
  617. lstrcat(szTemp, ", ");
  618. nLen = lstrlen(szTemp);
  619. if (GetDateFormat(GetUserDefaultLCID(), DATE_LONGDATE, &stm, NULL,
  620. (LPTSTR)szTemp + nLen, 126-nLen))
  621. lstrcat(szOrgText, szTemp);
  622. }
  623. }
  624. static void taskSetNextDay(TASK_TRIGGER *pTaskTrigger)
  625. {
  626. if (pTaskTrigger->wBeginMonth == 2 && pTaskTrigger->wBeginDay >= 28)
  627. { pTaskTrigger->wBeginMonth++, pTaskTrigger->wBeginDay = 1; }
  628. else if (pTaskTrigger->wBeginDay < 30)
  629. pTaskTrigger->wBeginDay++;
  630. else if (pTaskTrigger->wBeginMonth == 4 || pTaskTrigger->wBeginMonth == 6 ||
  631. pTaskTrigger->wBeginMonth == 9 || pTaskTrigger->wBeginMonth == 11)
  632. { pTaskTrigger->wBeginMonth++, pTaskTrigger->wBeginDay = 1; }
  633. else if (pTaskTrigger->wBeginDay < 31)
  634. pTaskTrigger->wBeginDay++;
  635. else if (pTaskTrigger->wBeginMonth == 12)
  636. { pTaskTrigger->wBeginYear++, pTaskTrigger->wBeginMonth = pTaskTrigger->wBeginDay = 1; }
  637. else
  638. { pTaskTrigger->wBeginMonth++, pTaskTrigger->wBeginDay = 1; }
  639. }
  640. */
  641. //////////////////////////////////////////////////////////////////////////////
  642. //
  643. // INTERNAL:
  644. // DeleteOrgJobFile()
  645. // This routine deletes the job (if it exists) with the job name passed in.
  646. //
  647. // ENTRY:
  648. // LPTSTR lpJobName -
  649. // This is the name of the job (as it appears in Task Scheduler) passed in.
  650. //
  651. // EXIT:
  652. // BOOL
  653. // TRUE - Either the file was successfully deleted or it didn't exist.
  654. // FALSE - Something failed.
  655. //
  656. //////////////////////////////////////////////////////////////////////////////
  657. static BOOL DeleteOrgJobFile(LPTSTR lpJobName)
  658. {
  659. TCHAR szJobFileName[MAX_PATH];
  660. DWORD dwAttr;
  661. // First get the full path and file name of
  662. // the job file.
  663. //
  664. if ( !GetJobFileName(lpJobName, szJobFileName) )
  665. return FALSE;
  666. // If it doesn't exit, return TRUE.
  667. //
  668. if ( !(EXIST(szJobFileName)) )
  669. return TRUE;
  670. // Make sure the file isn't read only.
  671. //
  672. if ( (dwAttr = GetFileAttributes(szJobFileName)) & _A_RDONLY )
  673. {
  674. dwAttr &= ~_A_RDONLY;
  675. SetFileAttributes(szJobFileName, dwAttr);
  676. }
  677. // Return the success or failure of DeleteFile().
  678. //
  679. return DeleteFile(szJobFileName);
  680. }
  681. /*
  682. int GetTimeScheme()
  683. {
  684. int i, nTimeScheme;
  685. ITaskTrigger *pTrigger = NULL;
  686. TASK_TRIGGER TaskTrigger, SchemeTrigger[ITEM_NUM];
  687. if (g_bEnableDefaultScheme == FALSE)
  688. return g_nTimeScheme;
  689. // check scheme by scheme
  690. for (nTimeScheme = IDC_NIGHT; nTimeScheme <= IDC_EVENING; nTimeScheme++) {
  691. for (i = TASK_FIRST; i <= TASK_LAST; i++) {
  692. if (!ItemData[i].bNeeded)
  693. continue;
  694. //InitJobTime(i, nTimeScheme, &SchemeTrigger[i]);
  695. }
  696. for (i = TASK_FIRST; i <= TASK_LAST; i++) {
  697. if (!ItemData[i].bNeeded)
  698. continue;
  699. if (!GetTaskTrigger(pTask[i], &TaskTrigger))
  700. break;
  701. if (memcmp((const void*)&TaskTrigger, (const void*)&SchemeTrigger[i], sizeof(TASK_TRIGGER)))
  702. break;
  703. }
  704. if (i == (TASK_LAST + 1)) // all the item match this scheme setting
  705. return nTimeScheme;
  706. }
  707. return IDC_CUSTOM;
  708. }
  709. */
  710. static BOOL GetTaskTrigger(ITask *pJob, TASK_TRIGGER *pTaskTrigger)
  711. {
  712. ITaskTrigger *pTrigger = NULL;
  713. if (pJob->GetTrigger((WORD)0, &pTrigger) != S_OK)
  714. return FALSE;
  715. ZeroMemory(pTaskTrigger, sizeof(TASK_TRIGGER));
  716. pTrigger->GetTrigger(pTaskTrigger);
  717. pTrigger->Release();
  718. return TRUE;
  719. }