windows-nt/Source/XPSP1/NT/base/fs/utils/tuneup/tasks.cpp

466 lines
14 KiB
C++
Raw Normal View History

2020-09-26 03:20:57 -05:00
//////////////////////////////////////////////////////////////////////////////
//
// 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;
}