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.

465 lines
14 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // TASKS.CPP / Tuneup
  4. //
  5. // Microsoft Confidential
  6. // Copyright (c) Microsoft Corporation 1998
  7. // All rights reserved
  8. //
  9. // 7/98 - Jason Cohen (JCOHEN)
  10. //
  11. //////////////////////////////////////////////////////////////////////////////
  12. // Internal include file(s).
  13. //
  14. #include "main.h"
  15. #include "scm.h"
  16. // Internal defince value(s).
  17. //
  18. #define TUNEUP_TASK_CI 0x00000001
  19. #define SERVICE_CISVC _T("CISVC")
  20. // Internal data structure(s).
  21. //
  22. typedef struct _DEFTASKS
  23. {
  24. INT nPageID; // Resource ID for the dialog used in the wizard page.
  25. LPTSTR lpAppName; // File name of the task to schedule.
  26. LPTSTR lpParameters; // Parameters for the application.
  27. LPTSTR lpSetParam; // Command line to execute for the settings button.
  28. DWORD dwFlags; // Default flags to use for the job.
  29. DWORD dwOptions; // Default tuneup options for the task.
  30. INT nSchedule; // The task schedule.
  31. INT nTitle; // Resource ID for the title of the wizard page.
  32. INT nSubTitle; // Resource ID for the subtitle of the wizard.
  33. INT nDescription; // Resource ID for the description on the wizard page.
  34. INT nJobName; // Resource ID for the string used for the job name of the task.
  35. INT nJobComment; // Resource ID for the string used for the job comment of the task.
  36. INT nYesAction; // Resource ID for the string used in the Yes option button. Only for IDD_TASKS pages.
  37. INT nNoAction; // Resource ID for the string used in the No option button. Only for IDD_TASKS pages.
  38. INT nSummary; // Resource ID for the string used in on the summary page.
  39. DWORD nSpecial; // Special identifier for tasks that require specific code.
  40. } DEFTASKS, *PDEFTASKS, *LPDEFTASKS;
  41. // Internal function prtotype(s).
  42. //
  43. static BOOL CALLBACK ThirdPartyAddOn(HKEY, LPTSTR, LPARAM);
  44. static LPTASKDATA AllocateTaskData(LPTASKDATA *);
  45. //
  46. // External function(s).
  47. //
  48. LPTASKDATA CreateTasks(VOID)
  49. {
  50. LPDEFTASKS lpDefTask;
  51. LPTASKDATA lpCurrent,
  52. lpHead = NULL;
  53. BOOL bAdd;
  54. TCHAR szPathBuffer[MAX_PATH];
  55. // This is how we now what the default tasks are. You can simply
  56. // add any tasks to this list that you want.
  57. //
  58. DEFTASKS DefaultTasks[] =
  59. {
  60. //{ IDD_TASK, _T("SMTIDY.EXE"), _T(""), _T(""), DEFAULT_TASK_FLAG2, 0, TASK_MONTHLY, IDS_TITLE_SMTIDY, IDS_SUBTITLE_SMTIDY, IDS_DESC_SMTIDY, IDS_TASK_SMTIDY, IDS_CMT_SMTIDY, IDS_TEXT_SMTIDY},
  61. { IDD_TASK, _T("SCANDISK.EXE"), _T("/sagerun:0"), _T("/sageset:0"), DEFAULT_TASK_FLAG, 0, TASK_WEEKLY, IDS_TITLE_CHKDSK, IDS_SUBTITLE_CHKDSK, IDS_DESC_CHKDSK, IDS_TASK_CHKDSK, IDS_CMT_CHKDSK, IDS_YES_CHKDSK, IDS_NO_CHKDSK, IDS_SUM_CHKDSK, 0},
  62. { IDD_CLEANUP, _T("CLEANMGR.EXE"), _T("/sagerun:0"), _T("/sageset:0"), DEFAULT_TASK_FLAG2, TASK_NOIDLE, TASK_MONTHLY, IDS_TITLE_CLEANUP, IDS_SUBTITLE_CLEANUP, IDS_DESC_CLEANUP, IDS_TASK_CLEANUP, IDS_CMT_CLEANUP, 0, 0, IDS_SUM_CLEANUP, 0},
  63. { IDD_TASK, _T("TUNEUP.EXE"), _T("/service:cisvc"), NULL, DEFAULT_TASK_FLAG, 0, TASK_ONCE, IDS_TITLE_CIDAEMON, IDS_SUBTITLE_CIDAEMON, IDS_DESC_CIDAEMON, IDS_TASK_CIDAEMON, IDS_CMT_CIDAEMON, IDS_YES_CIDAEMON, IDS_NO_CIDAEMON, IDS_SUM_CIDAEMON, TUNEUP_TASK_CI},
  64. //{ IDD_TASK, _T("NTBACKUP.EXE"), _T(""), _T(""), DEFAULT_TASK_FLAG, 0, TASK_MONTHLY, IDS_TITLE_BACKUP, IDS_SUBTITLE_BACKUP, IDS_TASK_BACKUP, IDS_CMT_BACKUP, IDS_TEXT_BACKUP},
  65. { 0, NULL, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // The first field of the last item must be zero.
  66. };
  67. // Loop through all the default tasks.
  68. //
  69. for (lpDefTask = DefaultTasks; lpDefTask->nPageID != 0; lpDefTask++)
  70. {
  71. // First make sure we need this page in case there is a condition where we
  72. // shouldn't display it (just for content indexing now).
  73. //
  74. switch (lpDefTask->nSpecial)
  75. {
  76. case TUNEUP_TASK_CI:
  77. bAdd = (IsUserAdmin() && !ServiceRunning(SERVICE_CISVC));
  78. break;
  79. default:
  80. bAdd = TRUE;
  81. }
  82. // Allocate the memory for this task's data structure.
  83. //
  84. if ( bAdd && (lpCurrent = AllocateTaskData(&lpHead)) )
  85. {
  86. //
  87. // Now we need to setup all the settings we need
  88. // to create this task's job in Task Scheduler.
  89. //
  90. // These structure items must be filled in:
  91. // lpFullPathName, lpParameters, lpSetParam,
  92. // lpJobName, lpComment, nSchedule, dwFlags,
  93. // dwOptions.
  94. //
  95. // Get the full path and app name (lpFullPathName). The default path for all the
  96. // default tasks is the system32 directory.
  97. //
  98. if ( GetSystemDirectory(szPathBuffer, sizeof(szPathBuffer)) )
  99. {
  100. lstrcat(szPathBuffer, _T("\\"));
  101. lstrcat(szPathBuffer, lpDefTask->lpAppName);
  102. if ( lpCurrent->lpFullPathName = (LPTSTR) MALLOC(sizeof(TCHAR) * (lstrlen(szPathBuffer) + 1)) )
  103. lstrcpy(lpCurrent->lpFullPathName, szPathBuffer);
  104. }
  105. // Get the app name (lpParameters) from the default task structure.
  106. //
  107. if ( lpCurrent->lpParameters = (LPTSTR) MALLOC(sizeof(TCHAR) * (lstrlen(lpDefTask->lpParameters) + 1)) )
  108. lstrcpy(lpCurrent->lpParameters, lpDefTask->lpParameters);
  109. // Get the settings button parameters. We leave the settings name to null because
  110. // the default tasks use the same exe as the task, just with different command line parameters.
  111. //
  112. if ( ( lpDefTask->lpSetParam ) &&
  113. ( lpCurrent->lpSetParam = (LPTSTR) MALLOC(sizeof(TCHAR) * (lstrlen(lpDefTask->lpSetParam) + 1)) ) )
  114. lstrcpy(lpCurrent->lpSetParam, lpDefTask->lpSetParam);
  115. // Get the job name (lpJobName) from the string table.
  116. //
  117. lpCurrent->lpJobName = AllocateString(NULL, lpDefTask->nJobName);
  118. // Get the name of the job comment (lpComment) from the string table.
  119. //
  120. lpCurrent->lpComment = AllocateString(NULL, lpDefTask->nJobComment);
  121. // Set the schedule for this job (nSchedule).
  122. //
  123. lpCurrent->nSchedule = lpDefTask->nSchedule;
  124. // Set the default flags for this job (dwFlags).
  125. //
  126. lpCurrent->dwFlags = lpDefTask->dwFlags;
  127. // Set the default tuneup options for this job (dwOptions).
  128. //
  129. lpCurrent->dwOptions = lpDefTask->dwOptions;
  130. //
  131. // Now we are going to setup all the data to create
  132. // this task's wizard page in Tuneup. All the task
  133. // structure items for the wizard must be filled in.
  134. //
  135. // Get the resource ID for the dialog.
  136. //
  137. lpCurrent->nPageID = lpDefTask->nPageID;
  138. // Get the other strings needed by the wizard.
  139. //
  140. lpCurrent->lpTitle = AllocateString(NULL, lpDefTask->nTitle);
  141. lpCurrent->lpSubTitle = AllocateString(NULL, lpDefTask->nSubTitle);
  142. lpCurrent->lpDescription = AllocateString(NULL, lpDefTask->nDescription);
  143. lpCurrent->lpYesAction = AllocateString(NULL, lpDefTask->nYesAction);
  144. lpCurrent->lpNoAction = AllocateString(NULL, lpDefTask->nNoAction);
  145. lpCurrent->lpSummary = AllocateString(NULL, lpDefTask->nSummary);
  146. }
  147. }
  148. // Now loop through all the third-party tasks.
  149. //
  150. RegEnumKeys(HKLM, g_szRegKeyAddOns, ThirdPartyAddOn, (LPARAM) &lpHead, FALSE);
  151. // Return the head of this list.
  152. //
  153. return lpHead;
  154. }
  155. VOID FreeTasks(LPTASKDATA lpTask)
  156. {
  157. // Don't free NULL data (this is the last item).
  158. //
  159. if ( lpTask != NULL )
  160. {
  161. // First free the next guy in the list.
  162. //
  163. FreeTasks(lpTask->lpNext);
  164. // Free all the job data. The FREE macro
  165. // will make sure that it isn't freeing NULL.
  166. //
  167. FREE(lpTask->lpFullPathName);
  168. FREE(lpTask->lpParameters);
  169. FREE(lpTask->lpSetName);
  170. FREE(lpTask->lpSetParam);
  171. FREE(lpTask->lpJobName);
  172. FREE(lpTask->lpComment);
  173. // Free all the wizard data.
  174. //
  175. FREE(lpTask->lpTitle);
  176. FREE(lpTask->lpSubTitle);
  177. FREE(lpTask->lpDescription);
  178. FREE(lpTask->lpYesAction);
  179. FREE(lpTask->lpNoAction);
  180. FREE(lpTask->lpSummary);
  181. // Now finally free the actuall task item.
  182. //
  183. FREE(lpTask);
  184. }
  185. }
  186. DWORD TasksScheduled(LPTASKDATA lpTasks)
  187. {
  188. DWORD dwFound = 0;
  189. while ( lpTasks )
  190. {
  191. if ( !(g_dwFlags & TUNEUP_CUSTOM) || (lpTasks->dwOptions & TASK_SCHEDULED) )
  192. dwFound++;
  193. lpTasks = lpTasks->lpNext;
  194. }
  195. return dwFound;
  196. }
  197. static BOOL CALLBACK ThirdPartyAddOn(HKEY hKey, LPTSTR lpKey, LPARAM lParam)
  198. {
  199. LPTASKDATA lpCurrent;
  200. LPTSTR lpBuffer,
  201. lpString;
  202. // Allocate the memory for this task's data structure.
  203. //
  204. if ( lpCurrent = AllocateTaskData((LPTASKDATA *) lParam) )
  205. {
  206. //
  207. // Now we need to setup all the settings we need
  208. // to create this task's job in Task Scheduler.
  209. //
  210. // These structure items must be filled in:
  211. // lpFullPathName, lpParameters, lpSetParam,
  212. // lpJobName, lpComment, nSchedule, dwFlags,
  213. // dwOptions.
  214. //
  215. // Get the full path and app name (lpFullPathName).
  216. //
  217. lpCurrent->lpFullPathName = RegGetString(hKey, NULL, g_szRegValProgram);
  218. // Get the app name (lpParameters) from the registry.
  219. //
  220. lpCurrent->lpParameters = RegGetString(hKey, NULL, g_szRegValProgParam);
  221. // Get the settings button exe and parameters.
  222. //
  223. lpCurrent->lpSetName = RegGetString(hKey, NULL, g_szRegValSettings);
  224. lpCurrent->lpSetParam = RegGetString(hKey, NULL, g_szRegValSetParam);
  225. // Get the job name (lpJobName) from the registry.
  226. //
  227. lpCurrent->lpJobName = RegGetString(hKey, NULL, g_szRegValJobName);
  228. // Get the name of the job comment (lpComment) from the registry.
  229. //
  230. lpCurrent->lpComment = RegGetString(hKey, NULL, g_szRegValComment);
  231. // Set the schedule for this job (nSchedule).
  232. //
  233. if ( lpBuffer = RegGetString(hKey, NULL, g_szRegValSchedule) )
  234. {
  235. lpCurrent->nSchedule = *lpBuffer - _T('0');
  236. FREE(lpBuffer);
  237. }
  238. // Set the default flags for this job (dwFlags).
  239. //
  240. lpCurrent->dwFlags = DEFAULT_TASK_FLAG;
  241. //
  242. // Now we are going to setup all the data to create
  243. // this task's wizard page in Tuneup. All the task
  244. // structure items for the wizard must be filled in.
  245. //
  246. // Set the resource ID for the dialog.
  247. //
  248. lpCurrent->nPageID = IDD_TASK;
  249. // Get the other strings needed by the wizard.
  250. //
  251. lpCurrent->lpTitle = RegGetString(hKey, NULL, g_szRegValTitle);
  252. lpCurrent->lpSubTitle = RegGetString(hKey, NULL, g_szRegValSubtitle);
  253. lpCurrent->lpDescription = RegGetString(hKey, NULL, g_szRegValDescription);
  254. lpCurrent->lpSummary = RegGetString(hKey, NULL, g_szRegValSummary);
  255. // Get and hold the action text in case we need it.
  256. //
  257. lpString = RegGetString(hKey, NULL, REG_VAL_ACTION);
  258. // Get the yes action option text for the wizard page.
  259. //
  260. if ( (lpCurrent->lpYesAction = RegGetString(hKey, NULL, g_szRegValYesAction)) == NULL )
  261. {
  262. // Since the no specific registry key wasn't there, we can create the
  263. // string from the action text and the '&Yes, ' prefix.
  264. //
  265. if ( lpString && (lpBuffer = AllocateString(NULL, IDS_YES)) )
  266. {
  267. if ( lpCurrent->lpYesAction = (LPTSTR) MALLOC(sizeof(TCHAR) * (lstrlen(lpString) + lstrlen(lpBuffer) + 1)) )
  268. wsprintf(lpCurrent->lpYesAction, _T("%s%s"), lpBuffer, lpString);
  269. FREE(lpBuffer);
  270. }
  271. }
  272. // Get the no action option text for the wizard page.
  273. //
  274. if ( (lpCurrent->lpNoAction = RegGetString(hKey, NULL, g_szRegValNoAction)) == NULL )
  275. {
  276. // Since the no specific registry key wasn't there, we can create the
  277. // string from the action text and the 'No, &don't ' prefix.
  278. //
  279. if ( lpString && (lpBuffer = AllocateString(NULL, IDS_NO)) )
  280. {
  281. if ( lpCurrent->lpNoAction = (LPTSTR) MALLOC(sizeof(TCHAR) * (lstrlen(lpString) + lstrlen(lpBuffer) + 1)) )
  282. wsprintf(lpCurrent->lpNoAction, _T("%s%s"), lpBuffer, lpString);
  283. FREE(lpBuffer);
  284. }
  285. }
  286. // Free the action text if we allocated it (FREE macro checks for us).
  287. //
  288. FREE(lpString);
  289. // Now lets make sure there is enough info for this item. If not we
  290. // need to free it so we don't display the page.
  291. //
  292. if ( ( lpCurrent->lpFullPathName == NULL ) ||
  293. ( !(EXIST(lpCurrent->lpFullPathName)) ) ||
  294. ( lpCurrent->nSchedule < TASK_ONCE ) ||
  295. ( lpCurrent->nSchedule > TASK_YEARLY ) ||
  296. ( lpCurrent->lpJobName == NULL) ||
  297. ( lpCurrent->lpTitle == NULL ) ||
  298. ( lpCurrent->lpYesAction == NULL ) ||
  299. ( lpCurrent->lpNoAction == NULL ) )
  300. {
  301. // Passing in NULL to this function will cause it to
  302. // free the last item allocated.
  303. //
  304. AllocateTaskData(NULL);
  305. }
  306. }
  307. // Always return true so the enum will continue.
  308. //
  309. return TRUE;
  310. }
  311. static LPTASKDATA AllocateTaskData(LPTASKDATA * lpHead)
  312. {
  313. // The current pointer needs to be static so that we can setup
  314. // the the next and back pointers after allocating the next
  315. // task data item.
  316. //
  317. static LPTASKDATA lpCurrent = NULL;
  318. LPTASKDATA lpBuffer = NULL;
  319. // lpHead can not be NULL. If it is, then we want to free
  320. // the last page allocated (used so if we decide that the third
  321. // party program doesn't have enough info in the registry for
  322. // us to use it, we can remove it).
  323. //
  324. if ( lpHead == NULL )
  325. {
  326. // Make sure there is a last item to free.
  327. //
  328. if ( lpCurrent )
  329. {
  330. // Record the current lpCurrent pointer so we can free
  331. // it later.
  332. //
  333. lpBuffer = lpCurrent;
  334. // Back up the lpCurrent pointer to the previous item
  335. // and Null out its next pointer so that it doesn't
  336. // think that this item still exists.
  337. //
  338. lpCurrent = lpCurrent->lpBack;
  339. lpCurrent->lpNext = NULL;
  340. // Now free the orphaned last item.
  341. //
  342. FreeTasks(lpBuffer);
  343. }
  344. return NULL;
  345. }
  346. // Allocate the memory for this task's data structure.
  347. //
  348. if ( lpBuffer = (LPTASKDATA) MALLOC(sizeof(TASKDATA)) )
  349. {
  350. //
  351. // We need to setup the next and back pointers
  352. // for the doubly linked list.
  353. //
  354. // Record the new pointer in the next of the pervious (current)
  355. // data.
  356. //
  357. if ( *lpHead && lpCurrent )
  358. {
  359. lpCurrent->lpNext = lpBuffer;
  360. lpBuffer->lpBack = lpCurrent;
  361. }
  362. // Or the head if this is the first item.
  363. //
  364. else
  365. *lpHead = lpBuffer;
  366. // Then set the current pointer to the new buffer.
  367. //
  368. lpCurrent = lpBuffer;
  369. }
  370. return lpBuffer;
  371. }
  372. BOOL InitGenericTask(HWND hDlg)
  373. {
  374. // Setup the "Yes" and "No" option string.
  375. //
  376. SetDlgItemText(hDlg, IDC_YES, g_CurrentTask->lpYesAction);
  377. SetDlgItemText(hDlg, IDC_DENY, g_CurrentTask->lpNoAction);
  378. // We can free these now, because we don't need them anymore.
  379. // The FREE macro also sets the pointer to NULL so we don't free
  380. // it again when we close the program.
  381. //
  382. FREE(g_CurrentTask->lpYesAction);
  383. FREE(g_CurrentTask->lpNoAction);
  384. // Disable the settings button if there is nothing for it to do.
  385. //
  386. if ( ( g_CurrentTask->lpSetName == NULL ) &&
  387. ( g_CurrentTask->lpSetParam == NULL) )
  388. EnableWindow(GetDlgItem(hDlg, IDC_SETTING), FALSE);
  389. // Always return false.
  390. //
  391. return FALSE;
  392. }