|
|
/******************************************************************************
Copyright(c) Microsoft Corporation
Module Name:
run.cpp
Abstract:
This module runs the schedule task present in the system
Author:
Venu Gopal Choudary 12-Mar-2001
Revision History:
Venu Gopal Choudary 12-Mar-2001 : Created it
******************************************************************************/
//common header files needed for this file
#include "pch.h"
#include "CommonHeaderFiles.h"
// Function declaration for the Usage function.
VOID DisplayRunUsage();
/*****************************************************************************
Routine Description:
This routine runs the 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 RunScheduledTask( IN DWORD argc, IN LPCTSTR argv[] ) { // Variables used to find whether Run option, Usage option
// are specified or not
BOOL bRun = FALSE; BOOL bUsage = FALSE; DWORD dwPolicy = 0;
// 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;
// Dynamic Array contaning array of jobs
TARRAY arrJobs = NULL;
//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; DWORD dwCheck = 0;
TCMDPARSER2 cmdRunOptions[MAX_RUN_OPTIONS]; BOOL bReturn = FALSE;
// /run sub-options
const WCHAR szRunOpt[] = L"run"; const WCHAR szRunHelpOpt[] = L"?"; const WCHAR szRunServerOpt[] = L"s"; const WCHAR szRunUserOpt[] = L"u"; const WCHAR szRunPwdOpt[] = L"p"; const WCHAR szRunTaskNameOpt[] = L"tn";
// set all the fields to 0
SecureZeroMemory( cmdRunOptions, sizeof( TCMDPARSER2 ) * MAX_RUN_OPTIONS );
//
// fill the commandline parser
//
// /delete option
StringCopyA( cmdRunOptions[ OI_RUN_OPTION ].szSignature, "PARSER2\0", 8 ); cmdRunOptions[ OI_RUN_OPTION ].dwType = CP_TYPE_BOOLEAN; cmdRunOptions[ OI_RUN_OPTION ].pwszOptions = szRunOpt; cmdRunOptions[ OI_RUN_OPTION ].dwCount = 1; cmdRunOptions[ OI_RUN_OPTION ].dwFlags = 0; cmdRunOptions[ OI_RUN_OPTION ].pValue = &bRun;
// /? option
StringCopyA( cmdRunOptions[ OI_RUN_USAGE ].szSignature, "PARSER2\0", 8 ); cmdRunOptions[ OI_RUN_USAGE ].dwType = CP_TYPE_BOOLEAN; cmdRunOptions[ OI_RUN_USAGE ].pwszOptions = szRunHelpOpt; cmdRunOptions[ OI_RUN_USAGE ].dwCount = 1; cmdRunOptions[ OI_RUN_USAGE ].dwFlags = CP2_USAGE; cmdRunOptions[ OI_RUN_USAGE ].pValue = &bUsage;
// /s option
StringCopyA( cmdRunOptions[ OI_RUN_SERVER ].szSignature, "PARSER2\0", 8 ); cmdRunOptions[ OI_RUN_SERVER ].dwType = CP_TYPE_TEXT; cmdRunOptions[ OI_RUN_SERVER ].pwszOptions = szRunServerOpt; cmdRunOptions[ OI_RUN_SERVER ].dwCount = 1; cmdRunOptions[ OI_RUN_SERVER ].dwFlags = CP2_ALLOCMEMORY| CP2_VALUE_TRIMINPUT|CP2_VALUE_NONULL ;
// /u option
StringCopyA( cmdRunOptions[ OI_RUN_USERNAME ].szSignature, "PARSER2\0", 8 ); cmdRunOptions[ OI_RUN_USERNAME ].dwType = CP_TYPE_TEXT; cmdRunOptions[ OI_RUN_USERNAME ].pwszOptions = szRunUserOpt; cmdRunOptions[ OI_RUN_USERNAME ].dwCount = 1; cmdRunOptions[ OI_RUN_USERNAME ].dwFlags = CP2_ALLOCMEMORY| CP2_VALUE_TRIMINPUT|CP2_VALUE_NONULL ;
// /p option
StringCopyA( cmdRunOptions[ OI_RUN_PASSWORD ].szSignature, "PARSER2\0", 8 ); cmdRunOptions[ OI_RUN_PASSWORD ].dwType = CP_TYPE_TEXT; cmdRunOptions[ OI_RUN_PASSWORD ].pwszOptions = szRunPwdOpt; cmdRunOptions[ OI_RUN_PASSWORD ].dwCount = 1; cmdRunOptions[ OI_RUN_PASSWORD ].dwFlags = CP2_ALLOCMEMORY | CP2_VALUE_OPTIONAL;
// /tn option
StringCopyA( cmdRunOptions[ OI_RUN_TASKNAME ].szSignature, "PARSER2\0", 8 ); cmdRunOptions[ OI_RUN_TASKNAME ].dwType = CP_TYPE_TEXT; cmdRunOptions[ OI_RUN_TASKNAME ].pwszOptions = szRunTaskNameOpt; cmdRunOptions[ OI_RUN_TASKNAME ].dwCount = 1; cmdRunOptions[ OI_RUN_TASKNAME ].dwFlags = CP2_MANDATORY; cmdRunOptions[ OI_RUN_TASKNAME ].pValue = szTaskName; cmdRunOptions[ OI_RUN_TASKNAME ].dwLength = MAX_JOB_LEN;
//parse command line arguments
bReturn = DoParseParam2( argc, argv, 0, SIZE_OF_ARRAY(cmdRunOptions), cmdRunOptions, 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)cmdRunOptions[ OI_RUN_SERVER ].pValue; szUser = (LPWSTR)cmdRunOptions[ OI_RUN_USERNAME ].pValue; szPassword = (LPWSTR)cmdRunOptions[ OI_RUN_PASSWORD ].pValue;
if ( (argc > 3) && (bUsage == TRUE) ) { ShowMessage ( stderr, GetResString (IDS_ERROR_RUNPARAM) ); FreeMemory((LPVOID*) &szServer); FreeMemory((LPVOID*) &szUser); FreeMemory((LPVOID*) &szPassword); return EXIT_FAILURE; }
// Displaying run usage if user specified -? with -run option
if( bUsage == TRUE ) { DisplayRunUsage(); FreeMemory((LPVOID*) &szServer); FreeMemory((LPVOID*) &szUser); FreeMemory((LPVOID*) &szPassword); return EXIT_SUCCESS; }
// check for invalid user name
if( ( cmdRunOptions[OI_RUN_SERVER].dwActuals == 0 ) && ( cmdRunOptions[OI_RUN_USERNAME].dwActuals == 1 ) ) { ShowMessage(stderr, GetResString(IDS_RUN_USER_BUT_NOMACHINE)); FreeMemory((LPVOID*) &szServer); FreeMemory((LPVOID*) &szUser); FreeMemory((LPVOID*) &szPassword); return RETVAL_FAIL; }
// check whether -ru is specified or not
if ( cmdRunOptions[ OI_RUN_USERNAME ].dwActuals == 0 && cmdRunOptions[ OI_RUN_PASSWORD ].dwActuals == 1 ) { // invalid syntax
ShowMessage(stderr, GetResString(IDS_RPASSWORD_BUT_NOUSERNAME)); FreeMemory((LPVOID*) &szServer); FreeMemory((LPVOID*) &szUser); FreeMemory((LPVOID*) &szPassword); return RETVAL_FAIL; }
// check for the length of taskname
if( ( StringLength( szTaskName, 0 ) > MAX_JOB_LEN ) ) { ShowMessage(stderr, GetResString( IDS_INVALID_TASKLENGTH )); FreeMemory((LPVOID*) &szServer); FreeMemory((LPVOID*) &szUser); FreeMemory((LPVOID*) &szPassword); return RETVAL_FAIL; }
//for holding values of parameters in FormatMessage()
WCHAR* szValues[1] = {NULL};
// 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 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(); FreeMemory((LPVOID*) &szServer); FreeMemory((LPVOID*) &szUser); FreeMemory((LPVOID*) &szPassword);
return RETVAL_FAIL; } }
// password
if ( szPassword == NULL ) { bNeedPassword = TRUE; szPassword = (LPWSTR)AllocateMemory( MAX_STRING_LENGTH * sizeof( WCHAR ) ); if ( szPassword == NULL ) { SaveLastError(); FreeMemory((LPVOID*) &szServer); FreeMemory((LPVOID*) &szUser); FreeMemory((LPVOID*) &szPassword);
return RETVAL_FAIL; } }
// case 1
if ( cmdRunOptions[ OI_RUN_PASSWORD ].dwActuals == 0 ) { // we need not do anything special here
}
// case 2
else if ( cmdRunOptions[ OI_RUN_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(); FreeMemory((LPVOID*) &szServer); FreeMemory((LPVOID*) &szUser); FreeMemory((LPVOID*) &szPassword);
return RETVAL_FAIL; }
// ...
bNeedPassword = TRUE; } }
if( ( IsLocalSystem( szServer ) == FALSE ) || ( cmdRunOptions[OI_RUN_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; case E_LOCAL_CREDENTIALS: case ERROR_SESSION_CREDENTIAL_CONFLICT: { bCloseConnection = FALSE; ShowLastErrorEx ( stderr, SLE_TYPE_ERROR | SLE_INTERNAL ); 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; }
//check whether service is running or not
if ((FALSE == CheckServiceStatus ( szServer , &dwCheck, TRUE)) && (0 != dwCheck) && ( GetLastError () != ERROR_ACCESS_DENIED)) { // 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 ( 1 == dwCheck ) { ShowMessage ( stderr, GetResString (IDS_NOT_START_SERVICE)); return EXIT_FAILURE; } else if (2 == dwCheck ) { return EXIT_FAILURE; } else if (3 == dwCheck ) { return EXIT_SUCCESS; } }
// Validate the Given Task and get as TARRAY in case of taskname
arrJobs = ValidateAndGetTasks( pITaskScheduler, szTaskName); if( arrJobs == NULL ) { StringCchPrintf( szMessage , SIZE_OF_ARRAY(szMessage), GetResString(IDS_TASKNAME_NOTEXIST), _X( szTaskName )); ShowMessage(stderr, szMessage );
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 running or not.
if ( FALSE == GetGroupPolicy( szServer, szUser, TS_KEYPOLICY_DENY_EXECUTION, &dwPolicy ) ) { 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_RUN)); if ( (TRUE == bFlag) && (bCloseConnection == TRUE) ) { CloseConnection( szServer ); }
Cleanup(pITaskScheduler); FreeMemory((LPVOID*) &szServer); FreeMemory((LPVOID*) &szUser); FreeMemory((LPVOID*) &szPassword); return EXIT_SUCCESS; }
IPersistFile *pIPF = NULL; ITask *pITask = NULL;
StringConcat ( szTaskName, JOB, SIZE_OF_ARRAY(szTaskName) );
// returns an pITask inteface for szTaskName
hr = pITaskScheduler->Activate(szTaskName,IID_ITask, (IUnknown**) &pITask);
if (FAILED(hr)) { SetLastError ((DWORD) hr); ShowLastErrorEx ( stderr, SLE_TYPE_ERROR | SLE_SYSTEM );
if( pIPF ) pIPF->Release();
if( pITask ) pITask->Release();
if ( (TRUE == bFlag) && (bCloseConnection == TRUE) ) { CloseConnection( szServer ); }
Cleanup(pITaskScheduler); FreeMemory((LPVOID*) &szServer); FreeMemory((LPVOID*) &szUser); FreeMemory((LPVOID*) &szPassword);
return EXIT_FAILURE; }
WCHAR szTaskProperty[MAX_STRING_LENGTH] = L"\0";
// get the status code
hr = GetStatusCode(pITask,szTaskProperty); if (FAILED(hr)) { SetLastError ((DWORD) hr); ShowLastErrorEx ( stderr, SLE_TYPE_ERROR | SLE_SYSTEM );
if( pIPF ) pIPF->Release();
if( pITask ) pITask->Release();
if ( (TRUE == bFlag) && (bCloseConnection == TRUE) ) { CloseConnection( szServer ); }
Cleanup(pITaskScheduler); FreeMemory((LPVOID*) &szServer); FreeMemory((LPVOID*) &szUser); FreeMemory((LPVOID*) &szPassword); return EXIT_FAILURE;
}
// remove the .job extension from the taskname
if ( ParseTaskName( szTaskName ) ) { if( pIPF ) pIPF->Release();
if( pITask ) pITask->Release();
if ( (TRUE == bFlag) && (bCloseConnection == TRUE) ) { CloseConnection( szServer ); }
Cleanup(pITaskScheduler); FreeMemory((LPVOID*) &szServer); FreeMemory((LPVOID*) &szUser); FreeMemory((LPVOID*) &szPassword); return EXIT_FAILURE; }
// check whether the task already been running or not
if ( (StringCompare(szTaskProperty , GetResString(IDS_STATUS_RUNNING), TRUE, 0) == 0 )) { szValues[0] = (WCHAR*) (szTaskName);
StringCchPrintf ( szMessage, SIZE_OF_ARRAY(szMessage), GetResString(IDS_RUNNING_ALREADY), _X(szTaskName)); ShowMessage(stdout, _X(szMessage));
if( pIPF ) pIPF->Release();
if( pITask ) pITask->Release();
if ( (TRUE == bFlag) && (bCloseConnection == TRUE) ) { CloseConnection( szServer ); }
Cleanup(pITaskScheduler); FreeMemory((LPVOID*) &szServer); FreeMemory((LPVOID*) &szUser); FreeMemory((LPVOID*) &szPassword); return EXIT_SUCCESS; }
// run the scheduled task immediately
hr = pITask->Run();
if ( FAILED(hr) ) { SetLastError ((DWORD) hr); ShowLastErrorEx ( stderr, SLE_TYPE_ERROR | SLE_SYSTEM );
if( pIPF ) pIPF->Release();
if( pITask ) pITask->Release();
if ( (TRUE == bFlag) && (bCloseConnection == TRUE) ) { CloseConnection( szServer ); }
Cleanup(pITaskScheduler); FreeMemory((LPVOID*) &szServer); FreeMemory((LPVOID*) &szUser); FreeMemory((LPVOID*) &szPassword); return EXIT_FAILURE; }
szValues[0] = (WCHAR*) (szTaskName);
StringCchPrintf ( szMessage, SIZE_OF_ARRAY(szMessage), GetResString(IDS_RUN_SUCCESSFUL), _X(szTaskName)); ShowMessage ( stdout, _X(szMessage));
if( pIPF ) pIPF->Release();
if( pITask ) pITask->Release();
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 -run option
Arguments: None
Return Value : VOID ******************************************************************************/
VOID DisplayRunUsage() { // Displaying run option usage
DisplayUsage( IDS_RUN_HLP1, IDS_RUN_HLP17 ); }
|