466 lines
14 KiB
C++
466 lines
14 KiB
C++
|
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// TASKS.CPP / Tuneup
|
||
|
//
|
||
|
// Microsoft Confidential
|
||
|
// Copyright (c) Microsoft Corporation 1998
|
||
|
// All rights reserved
|
||
|
//
|
||
|
// 7/98 - Jason Cohen (JCOHEN)
|
||
|
//
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
|
||
|
// Internal include file(s).
|
||
|
//
|
||
|
#include "main.h"
|
||
|
#include "scm.h"
|
||
|
|
||
|
|
||
|
// Internal defince value(s).
|
||
|
//
|
||
|
#define TUNEUP_TASK_CI 0x00000001
|
||
|
#define SERVICE_CISVC _T("CISVC")
|
||
|
|
||
|
|
||
|
// Internal data structure(s).
|
||
|
//
|
||
|
typedef struct _DEFTASKS
|
||
|
{
|
||
|
INT nPageID; // Resource ID for the dialog used in the wizard page.
|
||
|
LPTSTR lpAppName; // File name of the task to schedule.
|
||
|
LPTSTR lpParameters; // Parameters for the application.
|
||
|
LPTSTR lpSetParam; // Command line to execute for the settings button.
|
||
|
DWORD dwFlags; // Default flags to use for the job.
|
||
|
DWORD dwOptions; // Default tuneup options for the task.
|
||
|
INT nSchedule; // The task schedule.
|
||
|
INT nTitle; // Resource ID for the title of the wizard page.
|
||
|
INT nSubTitle; // Resource ID for the subtitle of the wizard.
|
||
|
INT nDescription; // Resource ID for the description on the wizard page.
|
||
|
INT nJobName; // Resource ID for the string used for the job name of the task.
|
||
|
INT nJobComment; // Resource ID for the string used for the job comment of the task.
|
||
|
INT nYesAction; // Resource ID for the string used in the Yes option button. Only for IDD_TASKS pages.
|
||
|
INT nNoAction; // Resource ID for the string used in the No option button. Only for IDD_TASKS pages.
|
||
|
INT nSummary; // Resource ID for the string used in on the summary page.
|
||
|
DWORD nSpecial; // Special identifier for tasks that require specific code.
|
||
|
} DEFTASKS, *PDEFTASKS, *LPDEFTASKS;
|
||
|
|
||
|
|
||
|
// Internal function prtotype(s).
|
||
|
//
|
||
|
static BOOL CALLBACK ThirdPartyAddOn(HKEY, LPTSTR, LPARAM);
|
||
|
static LPTASKDATA AllocateTaskData(LPTASKDATA *);
|
||
|
|
||
|
|
||
|
|
||
|
//
|
||
|
// External function(s).
|
||
|
//
|
||
|
|
||
|
|
||
|
LPTASKDATA CreateTasks(VOID)
|
||
|
{
|
||
|
LPDEFTASKS lpDefTask;
|
||
|
LPTASKDATA lpCurrent,
|
||
|
lpHead = NULL;
|
||
|
BOOL bAdd;
|
||
|
TCHAR szPathBuffer[MAX_PATH];
|
||
|
|
||
|
// This is how we now what the default tasks are. You can simply
|
||
|
// add any tasks to this list that you want.
|
||
|
//
|
||
|
DEFTASKS DefaultTasks[] =
|
||
|
{
|
||
|
//{ 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},
|
||
|
{ 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},
|
||
|
{ 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},
|
||
|
{ 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},
|
||
|
//{ 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},
|
||
|
{ 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.
|
||
|
};
|
||
|
|
||
|
// Loop through all the default tasks.
|
||
|
//
|
||
|
for (lpDefTask = DefaultTasks; lpDefTask->nPageID != 0; lpDefTask++)
|
||
|
{
|
||
|
// First make sure we need this page in case there is a condition where we
|
||
|
// shouldn't display it (just for content indexing now).
|
||
|
//
|
||
|
switch (lpDefTask->nSpecial)
|
||
|
{
|
||
|
case TUNEUP_TASK_CI:
|
||
|
bAdd = (IsUserAdmin() && !ServiceRunning(SERVICE_CISVC));
|
||
|
break;
|
||
|
default:
|
||
|
bAdd = TRUE;
|
||
|
}
|
||
|
|
||
|
// Allocate the memory for this task's data structure.
|
||
|
//
|
||
|
if ( bAdd && (lpCurrent = AllocateTaskData(&lpHead)) )
|
||
|
{
|
||
|
//
|
||
|
// Now we need to setup all the settings we need
|
||
|
// to create this task's job in Task Scheduler.
|
||
|
//
|
||
|
// These structure items must be filled in:
|
||
|
// lpFullPathName, lpParameters, lpSetParam,
|
||
|
// lpJobName, lpComment, nSchedule, dwFlags,
|
||
|
// dwOptions.
|
||
|
//
|
||
|
|
||
|
// Get the full path and app name (lpFullPathName). The default path for all the
|
||
|
// default tasks is the system32 directory.
|
||
|
//
|
||
|
if ( GetSystemDirectory(szPathBuffer, sizeof(szPathBuffer)) )
|
||
|
{
|
||
|
lstrcat(szPathBuffer, _T("\\"));
|
||
|
lstrcat(szPathBuffer, lpDefTask->lpAppName);
|
||
|
if ( lpCurrent->lpFullPathName = (LPTSTR) MALLOC(sizeof(TCHAR) * (lstrlen(szPathBuffer) + 1)) )
|
||
|
lstrcpy(lpCurrent->lpFullPathName, szPathBuffer);
|
||
|
}
|
||
|
|
||
|
// Get the app name (lpParameters) from the default task structure.
|
||
|
//
|
||
|
if ( lpCurrent->lpParameters = (LPTSTR) MALLOC(sizeof(TCHAR) * (lstrlen(lpDefTask->lpParameters) + 1)) )
|
||
|
lstrcpy(lpCurrent->lpParameters, lpDefTask->lpParameters);
|
||
|
|
||
|
|
||
|
// Get the settings button parameters. We leave the settings name to null because
|
||
|
// the default tasks use the same exe as the task, just with different command line parameters.
|
||
|
//
|
||
|
if ( ( lpDefTask->lpSetParam ) &&
|
||
|
( lpCurrent->lpSetParam = (LPTSTR) MALLOC(sizeof(TCHAR) * (lstrlen(lpDefTask->lpSetParam) + 1)) ) )
|
||
|
lstrcpy(lpCurrent->lpSetParam, lpDefTask->lpSetParam);
|
||
|
|
||
|
// Get the job name (lpJobName) from the string table.
|
||
|
//
|
||
|
lpCurrent->lpJobName = AllocateString(NULL, lpDefTask->nJobName);
|
||
|
|
||
|
// Get the name of the job comment (lpComment) from the string table.
|
||
|
//
|
||
|
lpCurrent->lpComment = AllocateString(NULL, lpDefTask->nJobComment);
|
||
|
|
||
|
// Set the schedule for this job (nSchedule).
|
||
|
//
|
||
|
lpCurrent->nSchedule = lpDefTask->nSchedule;
|
||
|
|
||
|
// Set the default flags for this job (dwFlags).
|
||
|
//
|
||
|
lpCurrent->dwFlags = lpDefTask->dwFlags;
|
||
|
|
||
|
// Set the default tuneup options for this job (dwOptions).
|
||
|
//
|
||
|
lpCurrent->dwOptions = lpDefTask->dwOptions;
|
||
|
|
||
|
|
||
|
//
|
||
|
// Now we are going to setup all the data to create
|
||
|
// this task's wizard page in Tuneup. All the task
|
||
|
// structure items for the wizard must be filled in.
|
||
|
//
|
||
|
|
||
|
// Get the resource ID for the dialog.
|
||
|
//
|
||
|
lpCurrent->nPageID = lpDefTask->nPageID;
|
||
|
|
||
|
// Get the other strings needed by the wizard.
|
||
|
//
|
||
|
lpCurrent->lpTitle = AllocateString(NULL, lpDefTask->nTitle);
|
||
|
lpCurrent->lpSubTitle = AllocateString(NULL, lpDefTask->nSubTitle);
|
||
|
lpCurrent->lpDescription = AllocateString(NULL, lpDefTask->nDescription);
|
||
|
lpCurrent->lpYesAction = AllocateString(NULL, lpDefTask->nYesAction);
|
||
|
lpCurrent->lpNoAction = AllocateString(NULL, lpDefTask->nNoAction);
|
||
|
lpCurrent->lpSummary = AllocateString(NULL, lpDefTask->nSummary);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Now loop through all the third-party tasks.
|
||
|
//
|
||
|
RegEnumKeys(HKLM, g_szRegKeyAddOns, ThirdPartyAddOn, (LPARAM) &lpHead, FALSE);
|
||
|
|
||
|
// Return the head of this list.
|
||
|
//
|
||
|
return lpHead;
|
||
|
}
|
||
|
|
||
|
|
||
|
VOID FreeTasks(LPTASKDATA lpTask)
|
||
|
{
|
||
|
// Don't free NULL data (this is the last item).
|
||
|
//
|
||
|
if ( lpTask != NULL )
|
||
|
{
|
||
|
// First free the next guy in the list.
|
||
|
//
|
||
|
FreeTasks(lpTask->lpNext);
|
||
|
|
||
|
// Free all the job data. The FREE macro
|
||
|
// will make sure that it isn't freeing NULL.
|
||
|
//
|
||
|
FREE(lpTask->lpFullPathName);
|
||
|
FREE(lpTask->lpParameters);
|
||
|
FREE(lpTask->lpSetName);
|
||
|
FREE(lpTask->lpSetParam);
|
||
|
FREE(lpTask->lpJobName);
|
||
|
FREE(lpTask->lpComment);
|
||
|
|
||
|
// Free all the wizard data.
|
||
|
//
|
||
|
FREE(lpTask->lpTitle);
|
||
|
FREE(lpTask->lpSubTitle);
|
||
|
FREE(lpTask->lpDescription);
|
||
|
FREE(lpTask->lpYesAction);
|
||
|
FREE(lpTask->lpNoAction);
|
||
|
FREE(lpTask->lpSummary);
|
||
|
|
||
|
// Now finally free the actuall task item.
|
||
|
//
|
||
|
FREE(lpTask);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
DWORD TasksScheduled(LPTASKDATA lpTasks)
|
||
|
{
|
||
|
DWORD dwFound = 0;
|
||
|
|
||
|
while ( lpTasks )
|
||
|
{
|
||
|
if ( !(g_dwFlags & TUNEUP_CUSTOM) || (lpTasks->dwOptions & TASK_SCHEDULED) )
|
||
|
dwFound++;
|
||
|
lpTasks = lpTasks->lpNext;
|
||
|
}
|
||
|
|
||
|
return dwFound;
|
||
|
}
|
||
|
|
||
|
|
||
|
static BOOL CALLBACK ThirdPartyAddOn(HKEY hKey, LPTSTR lpKey, LPARAM lParam)
|
||
|
{
|
||
|
LPTASKDATA lpCurrent;
|
||
|
LPTSTR lpBuffer,
|
||
|
lpString;
|
||
|
|
||
|
// Allocate the memory for this task's data structure.
|
||
|
//
|
||
|
if ( lpCurrent = AllocateTaskData((LPTASKDATA *) lParam) )
|
||
|
{
|
||
|
//
|
||
|
// Now we need to setup all the settings we need
|
||
|
// to create this task's job in Task Scheduler.
|
||
|
//
|
||
|
// These structure items must be filled in:
|
||
|
// lpFullPathName, lpParameters, lpSetParam,
|
||
|
// lpJobName, lpComment, nSchedule, dwFlags,
|
||
|
// dwOptions.
|
||
|
//
|
||
|
|
||
|
// Get the full path and app name (lpFullPathName).
|
||
|
//
|
||
|
lpCurrent->lpFullPathName = RegGetString(hKey, NULL, g_szRegValProgram);
|
||
|
|
||
|
// Get the app name (lpParameters) from the registry.
|
||
|
//
|
||
|
lpCurrent->lpParameters = RegGetString(hKey, NULL, g_szRegValProgParam);
|
||
|
|
||
|
// Get the settings button exe and parameters.
|
||
|
//
|
||
|
lpCurrent->lpSetName = RegGetString(hKey, NULL, g_szRegValSettings);
|
||
|
lpCurrent->lpSetParam = RegGetString(hKey, NULL, g_szRegValSetParam);
|
||
|
|
||
|
// Get the job name (lpJobName) from the registry.
|
||
|
//
|
||
|
lpCurrent->lpJobName = RegGetString(hKey, NULL, g_szRegValJobName);
|
||
|
|
||
|
// Get the name of the job comment (lpComment) from the registry.
|
||
|
//
|
||
|
lpCurrent->lpComment = RegGetString(hKey, NULL, g_szRegValComment);
|
||
|
|
||
|
// Set the schedule for this job (nSchedule).
|
||
|
//
|
||
|
if ( lpBuffer = RegGetString(hKey, NULL, g_szRegValSchedule) )
|
||
|
{
|
||
|
lpCurrent->nSchedule = *lpBuffer - _T('0');
|
||
|
FREE(lpBuffer);
|
||
|
}
|
||
|
|
||
|
// Set the default flags for this job (dwFlags).
|
||
|
//
|
||
|
lpCurrent->dwFlags = DEFAULT_TASK_FLAG;
|
||
|
|
||
|
//
|
||
|
// Now we are going to setup all the data to create
|
||
|
// this task's wizard page in Tuneup. All the task
|
||
|
// structure items for the wizard must be filled in.
|
||
|
//
|
||
|
|
||
|
// Set the resource ID for the dialog.
|
||
|
//
|
||
|
lpCurrent->nPageID = IDD_TASK;
|
||
|
|
||
|
// Get the other strings needed by the wizard.
|
||
|
//
|
||
|
lpCurrent->lpTitle = RegGetString(hKey, NULL, g_szRegValTitle);
|
||
|
lpCurrent->lpSubTitle = RegGetString(hKey, NULL, g_szRegValSubtitle);
|
||
|
lpCurrent->lpDescription = RegGetString(hKey, NULL, g_szRegValDescription);
|
||
|
lpCurrent->lpSummary = RegGetString(hKey, NULL, g_szRegValSummary);
|
||
|
|
||
|
// Get and hold the action text in case we need it.
|
||
|
//
|
||
|
lpString = RegGetString(hKey, NULL, REG_VAL_ACTION);
|
||
|
|
||
|
// Get the yes action option text for the wizard page.
|
||
|
//
|
||
|
if ( (lpCurrent->lpYesAction = RegGetString(hKey, NULL, g_szRegValYesAction)) == NULL )
|
||
|
{
|
||
|
// Since the no specific registry key wasn't there, we can create the
|
||
|
// string from the action text and the '&Yes, ' prefix.
|
||
|
//
|
||
|
if ( lpString && (lpBuffer = AllocateString(NULL, IDS_YES)) )
|
||
|
{
|
||
|
if ( lpCurrent->lpYesAction = (LPTSTR) MALLOC(sizeof(TCHAR) * (lstrlen(lpString) + lstrlen(lpBuffer) + 1)) )
|
||
|
wsprintf(lpCurrent->lpYesAction, _T("%s%s"), lpBuffer, lpString);
|
||
|
FREE(lpBuffer);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Get the no action option text for the wizard page.
|
||
|
//
|
||
|
if ( (lpCurrent->lpNoAction = RegGetString(hKey, NULL, g_szRegValNoAction)) == NULL )
|
||
|
{
|
||
|
// Since the no specific registry key wasn't there, we can create the
|
||
|
// string from the action text and the 'No, &don't ' prefix.
|
||
|
//
|
||
|
if ( lpString && (lpBuffer = AllocateString(NULL, IDS_NO)) )
|
||
|
{
|
||
|
if ( lpCurrent->lpNoAction = (LPTSTR) MALLOC(sizeof(TCHAR) * (lstrlen(lpString) + lstrlen(lpBuffer) + 1)) )
|
||
|
wsprintf(lpCurrent->lpNoAction, _T("%s%s"), lpBuffer, lpString);
|
||
|
FREE(lpBuffer);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Free the action text if we allocated it (FREE macro checks for us).
|
||
|
//
|
||
|
FREE(lpString);
|
||
|
|
||
|
// Now lets make sure there is enough info for this item. If not we
|
||
|
// need to free it so we don't display the page.
|
||
|
//
|
||
|
if ( ( lpCurrent->lpFullPathName == NULL ) ||
|
||
|
( !(EXIST(lpCurrent->lpFullPathName)) ) ||
|
||
|
( lpCurrent->nSchedule < TASK_ONCE ) ||
|
||
|
( lpCurrent->nSchedule > TASK_YEARLY ) ||
|
||
|
( lpCurrent->lpJobName == NULL) ||
|
||
|
( lpCurrent->lpTitle == NULL ) ||
|
||
|
( lpCurrent->lpYesAction == NULL ) ||
|
||
|
( lpCurrent->lpNoAction == NULL ) )
|
||
|
{
|
||
|
// Passing in NULL to this function will cause it to
|
||
|
// free the last item allocated.
|
||
|
//
|
||
|
AllocateTaskData(NULL);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Always return true so the enum will continue.
|
||
|
//
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
static LPTASKDATA AllocateTaskData(LPTASKDATA * lpHead)
|
||
|
{
|
||
|
// The current pointer needs to be static so that we can setup
|
||
|
// the the next and back pointers after allocating the next
|
||
|
// task data item.
|
||
|
//
|
||
|
static LPTASKDATA lpCurrent = NULL;
|
||
|
LPTASKDATA lpBuffer = NULL;
|
||
|
|
||
|
// lpHead can not be NULL. If it is, then we want to free
|
||
|
// the last page allocated (used so if we decide that the third
|
||
|
// party program doesn't have enough info in the registry for
|
||
|
// us to use it, we can remove it).
|
||
|
//
|
||
|
if ( lpHead == NULL )
|
||
|
{
|
||
|
// Make sure there is a last item to free.
|
||
|
//
|
||
|
if ( lpCurrent )
|
||
|
{
|
||
|
// Record the current lpCurrent pointer so we can free
|
||
|
// it later.
|
||
|
//
|
||
|
lpBuffer = lpCurrent;
|
||
|
|
||
|
// Back up the lpCurrent pointer to the previous item
|
||
|
// and Null out its next pointer so that it doesn't
|
||
|
// think that this item still exists.
|
||
|
//
|
||
|
lpCurrent = lpCurrent->lpBack;
|
||
|
lpCurrent->lpNext = NULL;
|
||
|
|
||
|
// Now free the orphaned last item.
|
||
|
//
|
||
|
FreeTasks(lpBuffer);
|
||
|
}
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
// Allocate the memory for this task's data structure.
|
||
|
//
|
||
|
if ( lpBuffer = (LPTASKDATA) MALLOC(sizeof(TASKDATA)) )
|
||
|
{
|
||
|
//
|
||
|
// We need to setup the next and back pointers
|
||
|
// for the doubly linked list.
|
||
|
//
|
||
|
|
||
|
// Record the new pointer in the next of the pervious (current)
|
||
|
// data.
|
||
|
//
|
||
|
if ( *lpHead && lpCurrent )
|
||
|
{
|
||
|
lpCurrent->lpNext = lpBuffer;
|
||
|
lpBuffer->lpBack = lpCurrent;
|
||
|
}
|
||
|
// Or the head if this is the first item.
|
||
|
//
|
||
|
else
|
||
|
*lpHead = lpBuffer;
|
||
|
|
||
|
// Then set the current pointer to the new buffer.
|
||
|
//
|
||
|
lpCurrent = lpBuffer;
|
||
|
}
|
||
|
|
||
|
return lpBuffer;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL InitGenericTask(HWND hDlg)
|
||
|
{
|
||
|
// Setup the "Yes" and "No" option string.
|
||
|
//
|
||
|
SetDlgItemText(hDlg, IDC_YES, g_CurrentTask->lpYesAction);
|
||
|
SetDlgItemText(hDlg, IDC_DENY, g_CurrentTask->lpNoAction);
|
||
|
|
||
|
// We can free these now, because we don't need them anymore.
|
||
|
// The FREE macro also sets the pointer to NULL so we don't free
|
||
|
// it again when we close the program.
|
||
|
//
|
||
|
FREE(g_CurrentTask->lpYesAction);
|
||
|
FREE(g_CurrentTask->lpNoAction);
|
||
|
|
||
|
// Disable the settings button if there is nothing for it to do.
|
||
|
//
|
||
|
if ( ( g_CurrentTask->lpSetName == NULL ) &&
|
||
|
( g_CurrentTask->lpSetParam == NULL) )
|
||
|
EnableWindow(GetDlgItem(hDlg, IDC_SETTING), FALSE);
|
||
|
|
||
|
// Always return false.
|
||
|
//
|
||
|
return FALSE;
|
||
|
}
|