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.
1072 lines
36 KiB
1072 lines
36 KiB
|
|
/******************************************************************************
|
|
|
|
Copyright(c) Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
delete.cpp
|
|
|
|
Abstract:
|
|
|
|
This module deletes the task(s) present in the system
|
|
|
|
Author:
|
|
|
|
Hari 10-Sep-2000
|
|
|
|
Revision History:
|
|
|
|
Hari 10-Sep-2000 : Created it
|
|
G.Surender Reddy 25-Sep-2000 : Modified it [added error checking]
|
|
G.Surender Reddy 31-Oct-2000 : Modified it
|
|
[Moved strings to resource file]
|
|
G.Surender Reddy 18-Nov-2000 : Modified it
|
|
[Modified usage help to be displayed]
|
|
G.Surender Reddy 15-Dec-2000 : Modified it
|
|
[Removed getch() fn.& used Console API
|
|
to read characters]
|
|
G.Surender Reddy 22-Dec-2000 : Modified it
|
|
[Rewrote the DisplayDeleteUsage() fn.]
|
|
G.Surender Reddy 08-Jan-2001 : Modified it
|
|
[Deleted the unused variables.]
|
|
|
|
******************************************************************************/
|
|
|
|
|
|
//common header files needed for this file
|
|
#include "pch.h"
|
|
#include "CommonHeaderFiles.h"
|
|
|
|
|
|
// Function declaration for the Usage function.
|
|
VOID DisplayDeleteUsage();
|
|
DWORD ConfirmDelete( LPCTSTR szTaskName , PBOOL pbFalg );
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
Routine Description:
|
|
|
|
This routine deletes a specified scheduled task(s)
|
|
|
|
Arguments:
|
|
|
|
[ in ] argc : Number of command line arguments
|
|
[ in ] argv : Array containing command line arguments
|
|
|
|
Return Value :
|
|
A DWORD value indicating EXIT_SUCCESS on success else
|
|
EXIT_FAILURE on failure
|
|
|
|
*****************************************************************************/
|
|
|
|
DWORD
|
|
DeleteScheduledTask(
|
|
IN DWORD argc,
|
|
IN LPCTSTR argv[]
|
|
)
|
|
{
|
|
// Variables used to find whether Delete main option, Usage option
|
|
// or the force option is specified or not
|
|
BOOL bDelete = FALSE;
|
|
BOOL bUsage = FALSE;
|
|
BOOL bForce = FALSE;
|
|
|
|
// Set the TaskSchduler object as NULL
|
|
ITaskScheduler *pITaskScheduler = NULL;
|
|
|
|
// Return value
|
|
HRESULT hr = S_OK;
|
|
|
|
// Initialising the variables that are passed to TCMDPARSER structure
|
|
LPWSTR szServer = NULL;
|
|
WCHAR szTaskName[ MAX_JOB_LEN ] = L"\0";
|
|
LPWSTR szUser = NULL;
|
|
LPWSTR szPassword = NULL;
|
|
|
|
// For each task in all the tasks.
|
|
WCHAR szEachTaskName[ MAX_JOB_LEN ];
|
|
BOOL bWrongValue = FALSE;
|
|
|
|
// Task name or the job name which is to be deleted
|
|
WCHAR wszJobName[MAX_JOB_LEN] ;
|
|
|
|
// Dynamic Array contaning array of jobs
|
|
TARRAY arrJobs = NULL;
|
|
|
|
// Loop Variable.
|
|
DWORD dwJobCount = 0;
|
|
//buffer for displaying error message
|
|
WCHAR szMessage[2 * MAX_STRING_LENGTH] = L"\0";
|
|
BOOL bNeedPassword = FALSE;
|
|
BOOL bResult = FALSE;
|
|
BOOL bCloseConnection = TRUE;
|
|
BOOL bFlag = FALSE;
|
|
|
|
TCMDPARSER2 cmdDeleteOptions[MAX_DELETE_OPTIONS];
|
|
BOOL bReturn = FALSE;
|
|
DWORD dwPolicy = 0;
|
|
|
|
// /delete sub-options
|
|
const WCHAR szDeleteOpt[] = L"delete";
|
|
const WCHAR szDeleteHelpOpt[] = L"?";
|
|
const WCHAR szDeleteServerOpt[] = L"s";
|
|
const WCHAR szDeleteUserOpt[] = L"u";
|
|
const WCHAR szDeletePwdOpt[] = L"p";
|
|
const WCHAR szDeleteTaskNameOpt[] = L"tn";
|
|
const WCHAR szDeleteForceOpt[] = L"f";
|
|
|
|
// set all the fields to 0
|
|
SecureZeroMemory( cmdDeleteOptions, sizeof( TCMDPARSER2 ) * MAX_DELETE_OPTIONS );
|
|
|
|
//
|
|
// fill the commandline parser
|
|
//
|
|
|
|
// /delete option
|
|
StringCopyA( cmdDeleteOptions[ OI_DELETE_OPTION ].szSignature, "PARSER2\0", 8 );
|
|
cmdDeleteOptions[ OI_DELETE_OPTION ].dwType = CP_TYPE_BOOLEAN;
|
|
cmdDeleteOptions[ OI_DELETE_OPTION ].pwszOptions = szDeleteOpt;
|
|
cmdDeleteOptions[ OI_DELETE_OPTION ].dwCount = 1;
|
|
cmdDeleteOptions[ OI_DELETE_OPTION ].dwFlags = 0;
|
|
cmdDeleteOptions[ OI_DELETE_OPTION ].pValue = &bDelete;
|
|
|
|
// /? option
|
|
StringCopyA( cmdDeleteOptions[ OI_DELETE_USAGE ].szSignature, "PARSER2\0", 8 );
|
|
cmdDeleteOptions[ OI_DELETE_USAGE ].dwType = CP_TYPE_BOOLEAN;
|
|
cmdDeleteOptions[ OI_DELETE_USAGE ].pwszOptions = szDeleteHelpOpt;
|
|
cmdDeleteOptions[ OI_DELETE_USAGE ].dwCount = 1;
|
|
cmdDeleteOptions[ OI_DELETE_USAGE ].dwFlags = CP2_USAGE;
|
|
cmdDeleteOptions[ OI_DELETE_USAGE ].pValue = &bUsage;
|
|
|
|
// /s option
|
|
StringCopyA( cmdDeleteOptions[ OI_DELETE_SERVER ].szSignature, "PARSER2\0", 8 );
|
|
cmdDeleteOptions[ OI_DELETE_SERVER ].dwType = CP_TYPE_TEXT;
|
|
cmdDeleteOptions[ OI_DELETE_SERVER ].pwszOptions = szDeleteServerOpt;
|
|
cmdDeleteOptions[ OI_DELETE_SERVER ].dwCount = 1;
|
|
cmdDeleteOptions[ OI_DELETE_SERVER ].dwFlags = CP2_ALLOCMEMORY| CP2_VALUE_TRIMINPUT|CP2_VALUE_NONULL ;
|
|
|
|
// /u option
|
|
StringCopyA( cmdDeleteOptions[ OI_DELETE_USERNAME ].szSignature, "PARSER2\0", 8 );
|
|
cmdDeleteOptions[ OI_DELETE_USERNAME ].dwType = CP_TYPE_TEXT;
|
|
cmdDeleteOptions[ OI_DELETE_USERNAME ].pwszOptions = szDeleteUserOpt;
|
|
cmdDeleteOptions[ OI_DELETE_USERNAME ].dwCount = 1;
|
|
cmdDeleteOptions[ OI_DELETE_USERNAME ].dwFlags = CP2_ALLOCMEMORY| CP2_VALUE_TRIMINPUT|CP2_VALUE_NONULL ;
|
|
|
|
// /p option
|
|
StringCopyA( cmdDeleteOptions[ OI_DELETE_PASSWORD ].szSignature, "PARSER2\0", 8 );
|
|
cmdDeleteOptions[ OI_DELETE_PASSWORD ].dwType = CP_TYPE_TEXT;
|
|
cmdDeleteOptions[ OI_DELETE_PASSWORD ].pwszOptions = szDeletePwdOpt;
|
|
cmdDeleteOptions[ OI_DELETE_PASSWORD ].dwCount = 1;
|
|
cmdDeleteOptions[ OI_DELETE_PASSWORD ].dwActuals = 0;
|
|
cmdDeleteOptions[ OI_DELETE_PASSWORD ].dwFlags = CP2_ALLOCMEMORY | CP2_VALUE_OPTIONAL;
|
|
|
|
// /tn option
|
|
StringCopyA( cmdDeleteOptions[ OI_DELETE_TASKNAME ].szSignature, "PARSER2\0", 8 );
|
|
cmdDeleteOptions[ OI_DELETE_TASKNAME ].dwType = CP_TYPE_TEXT;
|
|
cmdDeleteOptions[ OI_DELETE_TASKNAME ].pwszOptions = szDeleteTaskNameOpt;
|
|
cmdDeleteOptions[ OI_DELETE_TASKNAME ].dwCount = 1;
|
|
cmdDeleteOptions[ OI_DELETE_TASKNAME ].dwFlags = CP2_MANDATORY;
|
|
cmdDeleteOptions[ OI_DELETE_TASKNAME ].pValue = szTaskName;
|
|
cmdDeleteOptions[ OI_DELETE_TASKNAME ].dwLength = MAX_JOB_LEN;
|
|
|
|
|
|
// /f option
|
|
StringCopyA( cmdDeleteOptions[ OI_DELETE_FORCE ].szSignature, "PARSER2\0", 8 );
|
|
cmdDeleteOptions[ OI_DELETE_FORCE ].dwType = CP_TYPE_BOOLEAN;
|
|
cmdDeleteOptions[ OI_DELETE_FORCE ].pwszOptions = szDeleteForceOpt;
|
|
cmdDeleteOptions[ OI_DELETE_FORCE ].dwCount = 1;
|
|
cmdDeleteOptions[ OI_DELETE_FORCE ].pValue = &bForce;
|
|
|
|
|
|
//parse command line arguments
|
|
bReturn = DoParseParam2( argc, argv, 0, SIZE_OF_ARRAY(cmdDeleteOptions), cmdDeleteOptions, 0);
|
|
if( FALSE == bReturn) // Invalid commandline
|
|
{
|
|
//display an error message
|
|
ShowLastErrorEx ( stderr, SLE_TYPE_ERROR | SLE_INTERNAL );
|
|
ReleaseGlobals();
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
|
|
// get the buffer pointers allocated by command line parser
|
|
szServer = (LPWSTR)cmdDeleteOptions[ OI_CREATE_SERVER ].pValue;
|
|
szUser = (LPWSTR)cmdDeleteOptions[ OI_CREATE_USERNAME ].pValue;
|
|
szPassword = (LPWSTR)cmdDeleteOptions[ OI_CREATE_PASSWORD ].pValue;
|
|
|
|
|
|
if ( (argc > 3) && (bUsage == TRUE) )
|
|
{
|
|
ShowMessage ( stderr, GetResString (IDS_ERROR_DELETEPARAM) );
|
|
FreeMemory((LPVOID*) &szServer);
|
|
FreeMemory((LPVOID*) &szUser);
|
|
FreeMemory((LPVOID*) &szPassword);
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
// Displaying delete usage if user specified -? with -delete option
|
|
if( bUsage == TRUE )
|
|
{
|
|
DisplayDeleteUsage();
|
|
FreeMemory((LPVOID*) &szServer);
|
|
FreeMemory((LPVOID*) &szUser);
|
|
FreeMemory((LPVOID*) &szPassword);
|
|
return EXIT_SUCCESS;
|
|
}
|
|
|
|
// check for invalid user name
|
|
if( ( cmdDeleteOptions[OI_DELETE_SERVER].dwActuals == 0 ) && ( cmdDeleteOptions[OI_DELETE_USERNAME].dwActuals == 1 ) )
|
|
{
|
|
ShowMessage(stderr, GetResString(IDS_DELETE_USER_BUT_NOMACHINE));
|
|
FreeMemory((LPVOID*) &szServer);
|
|
FreeMemory((LPVOID*) &szUser);
|
|
FreeMemory((LPVOID*) &szPassword);
|
|
return RETVAL_FAIL;
|
|
}
|
|
|
|
|
|
// check whether username is specified or not along with the password
|
|
if ( cmdDeleteOptions[ OI_DELETE_USERNAME ].dwActuals == 0 && cmdDeleteOptions[OI_DELETE_PASSWORD].dwActuals == 1 )
|
|
{
|
|
// invalid syntax
|
|
ShowMessage(stderr, GetResString(IDS_DPASSWORD_BUT_NOUSERNAME));
|
|
FreeMemory((LPVOID*) &szServer);
|
|
FreeMemory((LPVOID*) &szUser);
|
|
FreeMemory((LPVOID*) &szPassword);
|
|
return RETVAL_FAIL;
|
|
}
|
|
|
|
// check for the length of the taskname
|
|
if( ( StringLength( szTaskName, 0 ) > MAX_JOB_LEN ) )
|
|
{
|
|
ShowMessage(stderr,GetResString(IDS_INVALID_TASKLENGTH));
|
|
FreeMemory((LPVOID*) &szServer);
|
|
FreeMemory((LPVOID*) &szUser);
|
|
FreeMemory((LPVOID*) &szPassword);
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
|
|
// check whether the password (-p) specified in the command line or not
|
|
// and also check whether '*' or empty is given for -p or not
|
|
// check whether the password (-p) specified in the command line or not
|
|
// and also check whether '*' or empty is given for -p or not
|
|
// check the remote connectivity information
|
|
if ( szServer != NULL )
|
|
{
|
|
//
|
|
// if -u is not specified, we need to allocate memory
|
|
// in order to be able to retrive the current user name
|
|
//
|
|
// case 1: -p is not at all specified
|
|
// as the value for this switch is optional, we have to rely
|
|
// on the dwActuals to determine whether the switch is specified or not
|
|
// in this case utility needs to try to connect first and if it fails
|
|
// then prompt for the password -- in fact, we need not check for this
|
|
// condition explicitly except for noting that we need to prompt for the
|
|
// password
|
|
//
|
|
// case 2: -p is specified
|
|
// but we need to check whether the value is specified or not
|
|
// in this case user wants the utility to prompt for the password
|
|
// before trying to connect
|
|
//
|
|
// case 3: -p * is specified
|
|
|
|
// user name
|
|
if ( szUser == NULL )
|
|
{
|
|
szUser = (LPWSTR) AllocateMemory( MAX_STRING_LENGTH * sizeof( WCHAR ) );
|
|
if ( szUser == NULL )
|
|
{
|
|
SaveLastError();
|
|
return RETVAL_FAIL;
|
|
}
|
|
}
|
|
|
|
// password
|
|
if ( szPassword == NULL )
|
|
{
|
|
bNeedPassword = TRUE;
|
|
szPassword = (LPWSTR)AllocateMemory( MAX_STRING_LENGTH * sizeof( WCHAR ) );
|
|
if ( szPassword == NULL )
|
|
{
|
|
SaveLastError();
|
|
return RETVAL_FAIL;
|
|
}
|
|
}
|
|
|
|
// case 1
|
|
if ( cmdDeleteOptions[ OI_DELETE_PASSWORD ].dwActuals == 0 )
|
|
{
|
|
// we need not do anything special here
|
|
}
|
|
|
|
// case 2
|
|
else if ( cmdDeleteOptions[ OI_DELETE_PASSWORD ].pValue == NULL )
|
|
{
|
|
StringCopy( szPassword, L"*", GetBufferSize(szPassword)/sizeof(WCHAR));
|
|
}
|
|
|
|
// case 3
|
|
else if ( StringCompareEx( szPassword, L"*", TRUE, 0 ) == 0 )
|
|
{
|
|
if ( ReallocateMemory( (LPVOID*)&szPassword,
|
|
MAX_STRING_LENGTH * sizeof( WCHAR ) ) == FALSE )
|
|
{
|
|
SaveLastError();
|
|
return RETVAL_FAIL;
|
|
}
|
|
|
|
// ...
|
|
bNeedPassword = TRUE;
|
|
}
|
|
}
|
|
|
|
|
|
if( ( IsLocalSystem( szServer ) == FALSE ) || ( cmdDeleteOptions[OI_DELETE_USERNAME].dwActuals == 1 ) )
|
|
{
|
|
bFlag = TRUE;
|
|
// Establish the connection on a remote machine
|
|
bResult = EstablishConnection(szServer,szUser,GetBufferSize(szUser)/sizeof(WCHAR),szPassword,GetBufferSize(szPassword)/sizeof(WCHAR), bNeedPassword );
|
|
if (bResult == FALSE)
|
|
{
|
|
ShowLastErrorEx ( stderr, SLE_TYPE_ERROR | SLE_INTERNAL );
|
|
FreeMemory((LPVOID*) &szServer);
|
|
FreeMemory((LPVOID*) &szUser);
|
|
FreeMemory((LPVOID*) &szPassword);
|
|
return EXIT_FAILURE ;
|
|
}
|
|
else
|
|
{
|
|
// though the connection is successfull, some conflict might have occured
|
|
switch( GetLastError() )
|
|
{
|
|
case I_NO_CLOSE_CONNECTION:
|
|
bCloseConnection = FALSE;
|
|
break;
|
|
|
|
// for mismatched credentials
|
|
case E_LOCAL_CREDENTIALS:
|
|
case ERROR_SESSION_CREDENTIAL_CONFLICT:
|
|
{
|
|
bCloseConnection = FALSE;
|
|
ShowMessage( stderr, GetResString(IDS_ERROR_STRING) );
|
|
ShowMessage( stderr, GetReason());
|
|
FreeMemory((LPVOID*) &szServer);
|
|
FreeMemory((LPVOID*) &szUser);
|
|
FreeMemory((LPVOID*) &szPassword);
|
|
return EXIT_FAILURE;
|
|
}
|
|
default :
|
|
bCloseConnection = TRUE;
|
|
}
|
|
}
|
|
|
|
//release memory for password
|
|
FreeMemory((LPVOID*) &szPassword);
|
|
}
|
|
|
|
// Get the task Scheduler object for the machine.
|
|
pITaskScheduler = GetTaskScheduler( szServer );
|
|
|
|
// If the Task Scheduler is not defined then give the error message.
|
|
if ( pITaskScheduler == NULL )
|
|
{
|
|
// close the connection that was established by the utility
|
|
if ( (TRUE == bFlag) && (bCloseConnection == TRUE) )
|
|
{
|
|
CloseConnection( szServer );
|
|
}
|
|
|
|
Cleanup(pITaskScheduler);
|
|
FreeMemory((LPVOID*) &szServer);
|
|
FreeMemory((LPVOID*) &szUser);
|
|
FreeMemory((LPVOID*) &szPassword);
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
//for holding values of parameters in FormatMessage()
|
|
WCHAR* szValues[1] = {szTaskName};
|
|
|
|
// Validate the Given Task and get as TARRAY in case of taskname
|
|
// as *.
|
|
arrJobs = ValidateAndGetTasks( pITaskScheduler, szTaskName);
|
|
if( arrJobs == NULL )
|
|
{
|
|
if(StringCompare(szTaskName, ASTERIX, TRUE, 0) == 0)
|
|
{
|
|
ShowMessage(stdout,GetResString(IDS_TASKNAME_NOTASKS));
|
|
// close the connection that was established by the utility
|
|
if ( (TRUE == bFlag) && (bCloseConnection == TRUE) )
|
|
{
|
|
CloseConnection( szServer );
|
|
}
|
|
|
|
Cleanup(pITaskScheduler);
|
|
FreeMemory((LPVOID*) &szServer);
|
|
FreeMemory((LPVOID*) &szUser);
|
|
FreeMemory((LPVOID*) &szPassword);
|
|
return EXIT_SUCCESS;
|
|
}
|
|
else
|
|
{
|
|
StringCchPrintf( szMessage , SIZE_OF_ARRAY(szMessage) , GetResString(IDS_TASKNAME_NOTEXIST), _X( szTaskName ));
|
|
ShowMessage(stderr, szMessage );
|
|
}
|
|
|
|
// close the connection that was established by the utility
|
|
if ( (TRUE == bFlag) && (bCloseConnection == TRUE) )
|
|
{
|
|
CloseConnection( szServer );
|
|
}
|
|
|
|
Cleanup(pITaskScheduler);
|
|
FreeMemory((LPVOID*) &szServer);
|
|
FreeMemory((LPVOID*) &szUser);
|
|
FreeMemory((LPVOID*) &szPassword);
|
|
return EXIT_FAILURE;
|
|
|
|
}
|
|
|
|
// check whether the group policy prevented user from deleting tasks or not.
|
|
if ( FALSE == GetGroupPolicy( szServer, szUser, TS_KEYPOLICY_DENY_DELETE , &dwPolicy ) )
|
|
{
|
|
// close the connection that was established by the utility
|
|
if ( (TRUE == bFlag) && (bCloseConnection == TRUE) )
|
|
{
|
|
CloseConnection( szServer );
|
|
}
|
|
|
|
Cleanup(pITaskScheduler);
|
|
FreeMemory((LPVOID*) &szServer);
|
|
FreeMemory((LPVOID*) &szUser);
|
|
FreeMemory((LPVOID*) &szPassword);
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
if ( dwPolicy > 0 )
|
|
{
|
|
ShowMessage ( stdout, GetResString (IDS_PREVENT_DELETE));
|
|
// close the connection that was established by the utility
|
|
if ( (TRUE == bFlag) && (bCloseConnection == TRUE) )
|
|
{
|
|
CloseConnection( szServer );
|
|
}
|
|
|
|
Cleanup(pITaskScheduler);
|
|
FreeMemory((LPVOID*) &szServer);
|
|
FreeMemory((LPVOID*) &szUser);
|
|
FreeMemory((LPVOID*) &szPassword);
|
|
return EXIT_SUCCESS;
|
|
}
|
|
|
|
// Confirm whether delete operation is to be perfromed
|
|
if( !bForce && ConfirmDelete( szTaskName , &bWrongValue ) )
|
|
{
|
|
// close the connection that was established by the utility
|
|
if ( (TRUE == bFlag) && (bCloseConnection == TRUE) )
|
|
{
|
|
CloseConnection( szServer );
|
|
}
|
|
|
|
Cleanup(pITaskScheduler);
|
|
FreeMemory((LPVOID*) &szServer);
|
|
FreeMemory((LPVOID*) &szUser);
|
|
FreeMemory((LPVOID*) &szPassword);
|
|
if ( bWrongValue == TRUE )
|
|
{
|
|
return EXIT_FAILURE;
|
|
}
|
|
else
|
|
{
|
|
return EXIT_SUCCESS;
|
|
}
|
|
}
|
|
|
|
// Loop through all the Jobs.
|
|
for( dwJobCount = 0; dwJobCount < DynArrayGetCount(arrJobs); dwJobCount++ )
|
|
{
|
|
// Get Each TaskName in the Array.
|
|
StringCopy (szEachTaskName, DynArrayItemAsString( arrJobs, dwJobCount ), SIZE_OF_ARRAY(szEachTaskName) );
|
|
|
|
StringCopy ( wszJobName, szEachTaskName , SIZE_OF_ARRAY(wszJobName));
|
|
|
|
// Parse the Task so that .job is removed.
|
|
if ( ParseTaskName( szEachTaskName ) )
|
|
{
|
|
Cleanup(pITaskScheduler);
|
|
FreeMemory((LPVOID*) &szServer);
|
|
FreeMemory((LPVOID*) &szUser);
|
|
FreeMemory((LPVOID*) &szPassword);
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
// Calling the delete method of ITaskScheduler interface
|
|
hr = pITaskScheduler->Delete(wszJobName);
|
|
szValues[0] = (WCHAR*) szEachTaskName;
|
|
// Based on the return value
|
|
switch (hr)
|
|
{
|
|
case S_OK:
|
|
|
|
StringCchPrintf ( szMessage, SIZE_OF_ARRAY(szMessage), GetResString(IDS_SUCCESS_DELETED), _X(szEachTaskName));
|
|
ShowMessage ( stdout, _X(szMessage));
|
|
|
|
break;
|
|
case E_INVALIDARG:
|
|
ShowMessage(stderr,GetResString(IDS_INVALID_ARG));
|
|
|
|
// close the connection that was established by the utility
|
|
if ( (TRUE == bFlag) && (bCloseConnection == TRUE) )
|
|
{
|
|
CloseConnection( szServer );
|
|
}
|
|
|
|
Cleanup(pITaskScheduler);
|
|
FreeMemory((LPVOID*) &szServer);
|
|
FreeMemory((LPVOID*) &szUser);
|
|
FreeMemory((LPVOID*) &szPassword);
|
|
return EXIT_FAILURE;
|
|
case E_OUTOFMEMORY:
|
|
ShowMessage(stderr,GetResString(IDS_NO_MEMORY));
|
|
|
|
// close the connection that was established by the utility
|
|
if ( (TRUE == bFlag) && (bCloseConnection == TRUE) )
|
|
{
|
|
CloseConnection( szServer );
|
|
}
|
|
|
|
Cleanup(pITaskScheduler);
|
|
FreeMemory((LPVOID*) &szServer);
|
|
FreeMemory((LPVOID*) &szUser);
|
|
FreeMemory((LPVOID*) &szPassword);
|
|
return EXIT_FAILURE;
|
|
default:
|
|
SetLastError ((DWORD) hr);
|
|
ShowLastErrorEx ( stderr, SLE_TYPE_ERROR | SLE_SYSTEM );
|
|
|
|
// close the connection that was established by the utility
|
|
if ( (TRUE == bFlag) && (bCloseConnection == TRUE) )
|
|
{
|
|
CloseConnection( szServer );
|
|
}
|
|
|
|
Cleanup(pITaskScheduler);
|
|
FreeMemory((LPVOID*) &szServer);
|
|
FreeMemory((LPVOID*) &szUser);
|
|
FreeMemory((LPVOID*) &szPassword);
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
}
|
|
|
|
// close the connection that was established by the utility
|
|
if ( (TRUE == bFlag) && (bCloseConnection == TRUE) )
|
|
{
|
|
CloseConnection( szServer );
|
|
}
|
|
|
|
Cleanup(pITaskScheduler);
|
|
FreeMemory((LPVOID*) &szServer);
|
|
FreeMemory((LPVOID*) &szUser);
|
|
FreeMemory((LPVOID*) &szPassword);
|
|
return EXIT_SUCCESS;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
|
|
Routine Description:
|
|
|
|
This routine displays the usage of -delete option
|
|
|
|
Arguments:
|
|
None
|
|
|
|
Return Value :
|
|
VOID
|
|
******************************************************************************/
|
|
|
|
VOID
|
|
DisplayDeleteUsage()
|
|
{
|
|
// Displaying delete usage
|
|
DisplayUsage( IDS_DEL_HLP1, IDS_DEL_HLP23);
|
|
}
|
|
|
|
/******************************************************************************
|
|
Routine Description:
|
|
|
|
This function validates whether the tasks to be deleted are present
|
|
in system & are valid.
|
|
|
|
Arguments:
|
|
|
|
[ in ] pITaskScheduler : Pointer to the ITaskScheduler Interface
|
|
|
|
[ in ] szTaskName : Array containing Task name
|
|
|
|
Return Value :
|
|
Array of type TARRAY containing tasks
|
|
******************************************************************************/
|
|
|
|
TARRAY
|
|
ValidateAndGetTasks(
|
|
IN ITaskScheduler *pITaskScheduler,
|
|
IN LPCTSTR szTaskName
|
|
)
|
|
{
|
|
// Dynamic Array of Jobs
|
|
TARRAY arrJobs = NULL;
|
|
|
|
// Enumerating WorkItems
|
|
IEnumWorkItems *pIEnum = NULL;
|
|
|
|
if( (pITaskScheduler == NULL ) || ( szTaskName == NULL ) )
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
// Create a Dynamic Array
|
|
arrJobs = CreateDynamicArray();
|
|
if (NULL == arrJobs)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
// Enumerate the Work Items
|
|
HRESULT hr = pITaskScheduler->Enum(&pIEnum);
|
|
if( FAILED( hr) )
|
|
{
|
|
if( pIEnum )
|
|
pIEnum->Release();
|
|
DestroyDynamicArray(&arrJobs);
|
|
return NULL;
|
|
}
|
|
|
|
// Names and Tasks fetches.
|
|
LPWSTR *lpwszNames = NULL;
|
|
DWORD dwFetchedTasks = 0;
|
|
DWORD dwTasks = 0;
|
|
ITask *pITask = NULL;//ITask interface
|
|
|
|
// Task found or not
|
|
BOOL blnFound = FALSE;
|
|
// array containing the Actual Taskname .
|
|
WCHAR szActualTask[MAX_STRING_LENGTH] = L"\0";
|
|
WCHAR szTmpTaskName[MAX_STRING_LENGTH] = L"\0";
|
|
|
|
// Enumerate all the Work Items
|
|
while (SUCCEEDED(pIEnum->Next(TASKS_TO_RETRIEVE,
|
|
&lpwszNames,
|
|
&dwFetchedTasks))
|
|
&& (dwFetchedTasks != 0))
|
|
{
|
|
dwTasks = dwFetchedTasks - 1;
|
|
|
|
// returns an pITask inteface for szEachTaskName
|
|
hr = pITaskScheduler->Activate(lpwszNames[dwTasks],IID_ITask,
|
|
(IUnknown**) &pITask);
|
|
|
|
//case 1:
|
|
// check whether the specified scheduled task is created under
|
|
// some other user. If so, ignore the respective task and
|
|
// continue to retrieve other tasks in the system.
|
|
// If the taskname created under some other user return value
|
|
// of above API must 0x80070005.
|
|
|
|
//case 2:
|
|
// check whether the respective .job file in %windir%\tasks\***.job is corrupted
|
|
//or not. if corrupted, the above function fails and return the value
|
|
// SCHED_E_UNKNOWN_OBJECT_VERSION. Eventhough, corrupted tasks would not shown in
|
|
// UI..tasks would still exists in database..can remove specific/all task names
|
|
// in task sheduler database.
|
|
if (hr == 0x80070005 || hr == 0x8007000D || hr == SCHED_E_UNKNOWN_OBJECT_VERSION || hr == E_INVALIDARG )
|
|
{
|
|
// continue to retrieve other tasks
|
|
continue;
|
|
}
|
|
|
|
if ( FAILED(hr))
|
|
{
|
|
|
|
CoTaskMemFree(lpwszNames[dwFetchedTasks]);
|
|
|
|
if( pIEnum )
|
|
{
|
|
pIEnum->Release();
|
|
}
|
|
|
|
DestroyDynamicArray(&arrJobs);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
// If the Task Name is * then get parse the tokens
|
|
// and append the jobs.
|
|
if(StringCompare( szTaskName , ASTERIX, TRUE, 0) == 0 )
|
|
{
|
|
|
|
StringCopy(szActualTask, lpwszNames[--dwFetchedTasks], SIZE_OF_ARRAY(szActualTask));
|
|
|
|
StringCopy ( szTmpTaskName, szActualTask , SIZE_OF_ARRAY(szTmpTaskName));
|
|
|
|
// Parse the Task so that .job is removed.
|
|
if ( ParseTaskName( szTmpTaskName ) )
|
|
{
|
|
CoTaskMemFree(lpwszNames[dwFetchedTasks]);
|
|
|
|
if( pIEnum )
|
|
{
|
|
pIEnum->Release();
|
|
}
|
|
|
|
DestroyDynamicArray(&arrJobs);
|
|
|
|
return NULL;
|
|
}
|
|
|
|
// Append the task in the job array
|
|
DynArrayAppendString( arrJobs, szActualTask, StringLength( szActualTask, 0 ) );
|
|
|
|
// Set the found flag as True.
|
|
blnFound = TRUE;
|
|
|
|
// Free the Named Task Memory.
|
|
CoTaskMemFree(lpwszNames[dwFetchedTasks]);
|
|
}
|
|
else
|
|
{
|
|
|
|
StringCopy( szActualTask, lpwszNames[--dwFetchedTasks], SIZE_OF_ARRAY(szActualTask));
|
|
|
|
StringCopy ( szTmpTaskName, szActualTask, SIZE_OF_ARRAY(szTmpTaskName) );
|
|
|
|
// Parse the TaskName to remove the .job extension.
|
|
if ( ParseTaskName( szTmpTaskName ) )
|
|
{
|
|
CoTaskMemFree(lpwszNames[dwFetchedTasks]);
|
|
|
|
if( pIEnum )
|
|
{
|
|
pIEnum->Release();
|
|
}
|
|
|
|
DestroyDynamicArray(&arrJobs);
|
|
|
|
return NULL;
|
|
}
|
|
|
|
// If the given Task matches with the TaskName present then form
|
|
// the TARRAY with this task and return.
|
|
if( StringCompare( szTmpTaskName, szTaskName, TRUE, 0 ) == 0 )
|
|
{
|
|
CoTaskMemFree(lpwszNames[dwFetchedTasks]);
|
|
DynArrayAppendString( arrJobs, szActualTask,
|
|
StringLength( szActualTask, 0 ) );
|
|
|
|
if( pIEnum )
|
|
pIEnum->Release();
|
|
return arrJobs;
|
|
}
|
|
}
|
|
}
|
|
|
|
CoTaskMemFree(lpwszNames);
|
|
|
|
if( pIEnum )
|
|
pIEnum->Release();
|
|
|
|
if( !blnFound )
|
|
{
|
|
DestroyDynamicArray(&arrJobs);
|
|
return NULL;
|
|
}
|
|
|
|
// return the TARRAY object.
|
|
return arrJobs;
|
|
}
|
|
|
|
|
|
DWORD
|
|
ConfirmDelete(
|
|
IN LPCTSTR szTaskName ,
|
|
OUT PBOOL pbFalg
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
|
|
This function confirms from the user really to delete the task(s).
|
|
|
|
Arguments:
|
|
|
|
[ in ] szTaskName : Array containing Task name
|
|
[ out ] pbFalg : Boolean flag to check whether wrong information entered
|
|
in the console or not.
|
|
Return Value :
|
|
EXIT_SUCCESS on success else EXIT_FAILURE
|
|
|
|
--*/
|
|
|
|
{
|
|
// sub-local variables
|
|
DWORD dwCharsRead = 0;
|
|
DWORD dwPrevConsoleMode = 0;
|
|
HANDLE hInputConsole = NULL;
|
|
BOOL bIndirectionInput = FALSE;
|
|
CHAR chAnsi = '\0';
|
|
CHAR szAnsiBuf[ 10 ] = "\0";
|
|
WCHAR chTmp = L'\0';
|
|
WCHAR wch = L'\0';
|
|
DWORD dwCharsWritten = 0;
|
|
WCHAR szBuffer[MAX_RES_STRING];
|
|
TCHAR szBackup[MAX_RES_STRING];
|
|
TCHAR szTmpBuf[MAX_RES_STRING];
|
|
WCHAR szMessage [2 * MAX_STRING_LENGTH];
|
|
DWORD dwIndex = 0 ;
|
|
BOOL bNoBreak = TRUE;
|
|
|
|
//intialize the variables
|
|
SecureZeroMemory ( szBuffer, SIZE_OF_ARRAY(szBuffer));
|
|
SecureZeroMemory ( szTmpBuf, SIZE_OF_ARRAY(szTmpBuf));
|
|
SecureZeroMemory ( szBackup, SIZE_OF_ARRAY(szBackup));
|
|
SecureZeroMemory ( szMessage, SIZE_OF_ARRAY(szMessage));
|
|
|
|
if ( szTaskName == NULL )
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
// Get the handle for the standard input
|
|
hInputConsole = GetStdHandle( STD_INPUT_HANDLE );
|
|
if ( hInputConsole == INVALID_HANDLE_VALUE )
|
|
{
|
|
SaveLastError();
|
|
// could not get the handle so return failure
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
MessageBeep(MB_ICONEXCLAMATION);
|
|
|
|
// Check for the input redirect
|
|
if( ( hInputConsole != (HANDLE)0x0000000F ) &&
|
|
( hInputConsole != (HANDLE)0x00000003 ) &&
|
|
( hInputConsole != INVALID_HANDLE_VALUE ) )
|
|
{
|
|
bIndirectionInput = TRUE;
|
|
}
|
|
|
|
// if there is no redirection
|
|
if ( bIndirectionInput == FALSE )
|
|
{
|
|
// Get the current input mode of the input buffer
|
|
if ( FALSE == GetConsoleMode( hInputConsole, &dwPrevConsoleMode ))
|
|
{
|
|
SaveLastError();
|
|
// could not set the mode, return failure
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
// Set the mode such that the control keys are processed by the system
|
|
if ( FALSE == SetConsoleMode( hInputConsole, ENABLE_PROCESSED_INPUT ) )
|
|
{
|
|
SaveLastError();
|
|
// could not set the mode, return failure
|
|
return EXIT_FAILURE;
|
|
}
|
|
}
|
|
|
|
|
|
// Print the warning message.accoring to the taskname
|
|
if( StringCompare( szTaskName , ASTERIX, TRUE, 0 ) == 0 )
|
|
{
|
|
ShowMessage(stdout, GetResString(IDS_WARN_DELETEALL));
|
|
}
|
|
else
|
|
{
|
|
StringCchPrintf ( szMessage, SIZE_OF_ARRAY(szMessage), GetResString(IDS_WARN_DELETE), _X(szTaskName));
|
|
ShowMessage ( stdout, _X(szMessage));
|
|
|
|
}
|
|
|
|
|
|
// redirect the data into the console
|
|
if ( bIndirectionInput == TRUE )
|
|
{
|
|
do {
|
|
//read the contents of file
|
|
if ( ReadFile(hInputConsole, &chAnsi, 1, &dwCharsRead, NULL) == FALSE )
|
|
{
|
|
SaveLastError();
|
|
// could not get the handle so return failure
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
// check if number of characters read were zero.. or
|
|
// any carriage return pressed..
|
|
if ( dwCharsRead == 0 || chTmp == CARRIAGE_RETURN || chTmp == L'\n' || chTmp == L'\t' )
|
|
{
|
|
bNoBreak = FALSE;
|
|
// exit from the loop
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
// convert the ANSI character into UNICODE character
|
|
szAnsiBuf[ 0 ] = chAnsi;
|
|
dwCharsRead = SIZE_OF_ARRAY( szBuffer );
|
|
GetAsUnicodeString2( szAnsiBuf, szBuffer, &dwCharsRead );
|
|
chTmp = szBuffer[ 0 ];
|
|
}
|
|
|
|
// write the contents to the console
|
|
if ( FALSE == WriteFile ( GetStdHandle( STD_OUTPUT_HANDLE ), &chTmp, 1, &dwCharsRead, NULL ) )
|
|
{
|
|
SaveLastError();
|
|
// could not get the handle so return failure
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
// copy the character
|
|
wch = chTmp;
|
|
|
|
StringCchPrintf ( szBackup, SIZE_OF_ARRAY(szBackup), L"%c" , wch );
|
|
|
|
// increment the index
|
|
dwIndex++;
|
|
|
|
} while (TRUE == bNoBreak);
|
|
|
|
}
|
|
else
|
|
{
|
|
do {
|
|
// Get the Character and loop accordingly.
|
|
if ( ReadConsole( hInputConsole, &chTmp, 1, &dwCharsRead, NULL ) == FALSE )
|
|
{
|
|
SaveLastError();
|
|
|
|
// Set the original console settings
|
|
if ( FALSE == SetConsoleMode( hInputConsole, dwPrevConsoleMode ) )
|
|
{
|
|
SaveLastError();
|
|
}
|
|
// return failure
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
// check if number of chars read were zero..if so, continue...
|
|
if ( dwCharsRead == 0 )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// check if any carriage return pressed...
|
|
if ( chTmp == CARRIAGE_RETURN )
|
|
{
|
|
bNoBreak = FALSE;
|
|
// exit from the loop
|
|
break;
|
|
}
|
|
|
|
wch = chTmp;
|
|
|
|
if ( wch != BACK_SPACE )
|
|
{
|
|
StringCchPrintf ( szTmpBuf, SIZE_OF_ARRAY(szTmpBuf), L"%c" , wch );
|
|
StringConcat ( szBackup, szTmpBuf , SIZE_OF_ARRAY(szBackup));
|
|
}
|
|
|
|
// Check id back space is hit
|
|
if ( wch == BACK_SPACE )
|
|
{
|
|
if ( dwIndex != 0 )
|
|
{
|
|
//
|
|
// Remove a asterix from the console
|
|
|
|
// move the cursor one character back
|
|
StringCchPrintf( szBuffer, SIZE_OF_ARRAY(szBuffer), L"%c" , BACK_SPACE );
|
|
if ( FALSE == WriteConsole( GetStdHandle( STD_OUTPUT_HANDLE ), szBuffer, 1,
|
|
&dwCharsWritten, NULL ) )
|
|
{
|
|
SaveLastError();
|
|
// return failure
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
|
|
// replace the existing character with space
|
|
StringCchPrintf( szBuffer, SIZE_OF_ARRAY(szBuffer), L"%c" , BLANK_CHAR );
|
|
if ( FALSE == WriteConsole( GetStdHandle( STD_OUTPUT_HANDLE ), szBuffer, 1,
|
|
&dwCharsWritten, NULL ))
|
|
{
|
|
SaveLastError();
|
|
// return failure
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
// now set the cursor at back position
|
|
StringCchPrintf( szBuffer, SIZE_OF_ARRAY(szBuffer), L"%c" , BACK_SPACE );
|
|
if ( FALSE == WriteConsole( GetStdHandle( STD_OUTPUT_HANDLE ), szBuffer, 1,
|
|
&dwCharsWritten, NULL ))
|
|
{
|
|
SaveLastError();
|
|
// return failure
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
szBackup [StringLength(szBackup, 0) - 1] = L'\0';
|
|
// decrement the index
|
|
dwIndex--;
|
|
}
|
|
|
|
// process the next character
|
|
continue;
|
|
}
|
|
|
|
// write the contents onto console
|
|
if ( FALSE == WriteFile ( GetStdHandle( STD_OUTPUT_HANDLE ), &wch, 1, &dwCharsRead, NULL ) )
|
|
{
|
|
SaveLastError();
|
|
// return failure
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
// increment the index value
|
|
dwIndex++;
|
|
|
|
} while (TRUE == bNoBreak);
|
|
|
|
}
|
|
|
|
ShowMessage(stdout, _T("\n") );
|
|
|
|
//StringCchPrintf( szBuffer, SIZE_OF_ARRAY(szBuffer), L"%c" , ch );
|
|
|
|
if( (1 == dwIndex) && StringCompare ( szBackup, GetResString(IDS_UPPER_YES), TRUE, 0 ) == 0 ) {
|
|
//Set the original console settings
|
|
SetConsoleMode( hInputConsole, dwPrevConsoleMode );
|
|
return EXIT_SUCCESS;
|
|
}
|
|
else if( (1 == dwIndex) && StringCompare ( szBackup, GetResString(IDS_UPPER_NO), TRUE, 0 ) == 0 )
|
|
{
|
|
// display a message as .. operation has been cancelled...
|
|
ShowMessage ( stdout, GetResString (IDS_OPERATION_CANCELLED ) );
|
|
SetConsoleMode( hInputConsole, dwPrevConsoleMode );
|
|
return EXIT_FAILURE;
|
|
}
|
|
else
|
|
{
|
|
ShowMessage(stderr, GetResString( IDS_WRONG_INPUT_DELETE ));
|
|
SetConsoleMode( hInputConsole, dwPrevConsoleMode );
|
|
*pbFalg = TRUE;
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
//not returning anything as control never comes here...
|
|
}
|
|
|