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.
 
 
 
 
 
 

1984 lines
49 KiB

//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1994 - 1996.
//
// File: commands.cxx
//
// Contents: Implementation of command-line switches.
//
// History: 01-03-96 DavidMun Created
//
//----------------------------------------------------------------------------
#include <headers.hxx>
#pragma hdrstop
#include "jt.hxx"
#include "..\..\inc\defines.hxx"
#define MAX_TRIGGER_STRING 160
#define DEFAULT_FETCH_COUNT 2
#define MSTASK_DLL TEXT("MSTASK.DLL")
typedef HRESULT (WINAPI * PSETNSACCOUNTINFO)(LPCWSTR, LPCWSTR, LPCWSTR);
typedef HRESULT (WINAPI * PGETNSACCOUNTINFO)(LPCWSTR, DWORD, LPWSTR);
//+---------------------------------------------------------------------------
//
// Function: Abort
//
// Synopsis: Parse and execute the abort job command.
//
// Arguments: [ppwsz] - command line
// [fJob] - TRUE=>operate on job, FALSE=>operate on queue
//
// Returns: S_OK - command executed
// E_* - error logged
//
// Modifies: *[ppwsz]
//
// History: 01-05-96 DavidMun Created
//
//----------------------------------------------------------------------------
HRESULT Abort(WCHAR **ppwsz, BOOL fJob)
{
HRESULT hr = S_OK;
if (fJob)
{
g_Log.Write(LOG_TRACE, "Aborting job");
hr = g_pJob->Terminate();
if (FAILED(hr))
{
g_Log.Write(LOG_FAIL, "ITask::Terminate hr=%#010x", hr);
}
}
else
{
g_Log.Write(LOG_TRACE, "Aborting Queue");
#ifdef NOT_YET
hr = g_pJobQueue->Terminate();
if (FAILED(hr))
{
g_Log.Write(LOG_FAIL, "ITaskQueue::Terminate hr=%#010x", hr);
}
#endif // NOT_YET
hr = E_NOTIMPL;
}
return hr;
}
//+---------------------------------------------------------------------------
//
// Function: ConvertSage
//
// Synopsis: Execute the convert sage tasks to jobs command, but only
// if this binary was built for and is running on Win9x.
//
// Returns: Built for or runnong on NT - S_OK
// Otherwise - result of ConvertSageTasksToJobs()
//
// History: 03-25-96 DavidMun Created
//
//----------------------------------------------------------------------------
HRESULT ConvertSage()
{
HRESULT hr = S_OK;
#ifdef _CHICAGO_
OSVERSIONINFO VersionInfo = { sizeof OSVERSIONINFO };
GetVersionEx(&VersionInfo);
if (VersionInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
{
hr = ConvertSageTasksToJobs();
}
else
{
g_Log.Write(
LOG_WARN,
"This command cannot be executed when running under Windows NT.");
}
#else
g_Log.Write(
LOG_WARN,
"This version of JT was built for NT and cannot execute this command.");
#endif // !_CHICAGO_
return hr;
}
//+---------------------------------------------------------------------------
//
// Function: SetNSAccountInfo
//
// Synopsis:
//
// Returns:
//
// History:
//
//----------------------------------------------------------------------------
HRESULT SetNSAccountInfo(WCHAR ** ppwsz)
{
#define SET_NS_ACCOUNT_INFO "SetNetScheduleAccountInformation"
HRESULT hr = S_OK;
#ifndef _CHICAGO_
OSVERSIONINFO VersionInfo = { sizeof OSVERSIONINFO };
GetVersionEx(&VersionInfo);
if (VersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT)
{
WCHAR wszAccount[MAX_USERNAME + 1];
WCHAR wszPassword[MAX_PASSWORD + 1];
hr = Expect(TKN_STRING, ppwsz, L"Account name");
if (FAILED(hr))
{
return hr;
}
wcsncpy(wszAccount, g_wszLastStringToken,
min(wcslen(g_wszLastStringToken) + 1, MAX_USERNAME));
hr = Expect(TKN_STRING, ppwsz, L"Account password");
if (FAILED(hr))
{
return hr;
}
wcsncpy(wszPassword, g_wszLastStringToken,
min(wcslen(g_wszLastStringToken) + 1, MAX_PASSWORD));
PSETNSACCOUNTINFO pSetNSAccountInfo;
HMODULE hMod = LoadLibrary(MSTASK_DLL);
if (hMod == NULL)
{
hr = HRESULT_FROM_WIN32(GetLastError());
g_Log.Write(LOG_FAIL, "LoadLibrary hr=%#010x", hr);
return hr;
}
else
{
pSetNSAccountInfo = (PSETNSACCOUNTINFO)GetProcAddress(
hMod,
SET_NS_ACCOUNT_INFO);
if (pSetNSAccountInfo == NULL)
{
FreeLibrary(hMod);
hr = HRESULT_FROM_WIN32(GetLastError());
g_Log.Write(LOG_FAIL, "GetProcAddress hr=%#010x", hr);
return hr;
}
}
hr = pSetNSAccountInfo(
NULL,
lstrcmpiW(wszAccount, L"NULL") == 0 ? NULL : wszAccount,
wszPassword);
if (FAILED(hr))
{
g_Log.Write(LOG_FAIL,
"SetNetScheduleAccountInformation hr=%#010x", hr);
}
FreeLibrary(hMod);
}
else
{
g_Log.Write(
LOG_WARN,
"This command cannot be executed when running under Windows 95.");
}
#else
g_Log.Write(
LOG_WARN,
"This version of JT was built for Win95 and cannot execute this command.");
#endif // !_CHICAGO_
return hr;
}
//+---------------------------------------------------------------------------
//
// Function: PrintNSAccountInfo
//
// Synopsis:
//
// Returns:
//
// History:
//
//----------------------------------------------------------------------------
HRESULT PrintNSAccountInfo(void)
{
#define GET_NS_ACCOUNT_INFO "GetNetScheduleAccountInformation"
HRESULT hr = S_OK;
#ifndef _CHICAGO_
OSVERSIONINFO VersionInfo = { sizeof OSVERSIONINFO };
GetVersionEx(&VersionInfo);
if (VersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT)
{
PGETNSACCOUNTINFO pGetNSAccountInfo;
HMODULE hMod = LoadLibrary(MSTASK_DLL);
if (hMod == NULL)
{
hr = HRESULT_FROM_WIN32(GetLastError());
g_Log.Write(LOG_FAIL, "LoadLibrary hr=%#010x", hr);
return hr;
}
else
{
pGetNSAccountInfo = (PGETNSACCOUNTINFO)GetProcAddress(
hMod,
GET_NS_ACCOUNT_INFO);
if (pGetNSAccountInfo == NULL)
{
FreeLibrary(hMod);
hr = HRESULT_FROM_WIN32(GetLastError());
g_Log.Write(LOG_FAIL, "GetProcAddress hr=%#010x", hr);
return hr;
}
}
WCHAR wszAccount[MAX_USERNAME + 1];
DWORD ccAccount = MAX_USERNAME + 1;
hr = pGetNSAccountInfo(NULL, ccAccount, wszAccount);
if (SUCCEEDED(hr))
{
if (hr == S_FALSE)
{
g_Log.Write(LOG_TRACE, "NetSchedule account not specified");
}
else
{
g_Log.Write(LOG_TRACE,
"NetSchedule account name = '%S'", wszAccount);
}
}
else
{
g_Log.Write(LOG_FAIL,
"GetNetScheduleAccountInformation hr=%#010x", hr);
}
FreeLibrary(hMod);
}
else
{
g_Log.Write(
LOG_WARN,
"This command cannot be executed when running under Windows 95.");
}
#else
g_Log.Write(
LOG_WARN,
"This version of JT was built for Win95 and cannot execute this command.");
#endif // !_CHICAGO_
return hr;
}
//+---------------------------------------------------------------------------
//
// Function: CreateTrigger
//
// Synopsis: Parse and execute the create trigger command.
//
// Arguments: [ppwsz] - command line
//
// Returns: S_OK - created trigger
// E_* - error logged
//
// History: 01-04-96 DavidMun Created
//
//----------------------------------------------------------------------------
HRESULT CreateTrigger(WCHAR **ppwsz, BOOL fJob)
{
HRESULT hr = S_OK;
CTrigProp TriggerProps;
USHORT usTrigger;
SpIJobTrigger spTrigger;
do
{
hr = TriggerProps.Parse(ppwsz);
BREAK_ON_FAILURE(hr);
//
// Ask job or queue to create trigger
//
if (fJob)
{
hr = g_pJob->CreateTrigger(&usTrigger, &spTrigger);
LOG_AND_BREAK_ON_FAIL(hr, "ITask::CreateTrigger");
}
else
{
#ifdef NOT_YET
hr = g_pJobQueue->CreateTrigger(&usTrigger, &spTrigger);
LOG_AND_BREAK_ON_FAIL(hr, "ITaskQueue::CreateTrigger");
#endif // NOT_YET
hr = E_NOTIMPL;
}
g_Log.Write(LOG_TRACE, "Created trigger %u", usTrigger);
//
// Now set the trigger's properties to the values we parsed already
//
hr = TriggerProps.SetActual(spTrigger);
}
while (0);
return hr;
}
//+---------------------------------------------------------------------------
//
// Function: DeleteTrigger
//
// Synopsis: Parse and execute the delete trigger command.
//
// Arguments: [ppwsz] - command line
//
// Returns: S_OK - trigger deleted
// E_* - error logged
//
// Modifies: *[ppwsz]
//
// History: 01-05-96 DavidMun Created
//
//----------------------------------------------------------------------------
HRESULT DeleteTrigger(WCHAR **ppwsz, BOOL fJob)
{
HRESULT hr = S_OK;
USHORT usTrigger = 0;
do
{
if (PeekToken(ppwsz) == TKN_NUMBER)
{
GetToken(ppwsz);
usTrigger = (SHORT) g_ulLastNumberToken;
}
g_Log.Write(LOG_TRACE, "Deleting trigger %u", usTrigger);
if (fJob)
{
hr = g_pJob->DeleteTrigger(usTrigger);
LOG_AND_BREAK_ON_FAIL(hr, "ITask::DeleteTrigger");
}
else
{
#ifdef NOT_YET
hr = g_pJobQueue->DeleteTrigger(usTrigger);
LOG_AND_BREAK_ON_FAIL(hr, "ITaskQueue::DeleteTrigger");
#endif // NOT_YET
hr = E_NOTIMPL;
}
}
while (0);
return hr;
}
//+---------------------------------------------------------------------------
//
// Function: EditJob
//
// Synopsis: Invoke the edit job command
//
// Arguments: [ppwsz] - command line
// [fJob] - TRUE=>edit g_pJob, FALSE=>edit a job in g_pJobQueue
//
// Returns: S_OK - UI invoked
// E_* - error logged
//
// History: 01-11-96 DavidMun Created
// 06-28-96 DavidMun Support individual prop pages
//
//----------------------------------------------------------------------------
HRESULT EditJob(WCHAR **ppwsz, BOOL fJob)
{
HRESULT hr = S_OK;
SpIJob spJob;
ITask *pJob; // Do not Release this
SpIUnknown spunkJob;
SpIProvideTaskPage spProvideTaskPage;
TOKEN tkn;
ULONG ulType = 0;
BOOL fPersist = TRUE;
PROPSHEETHEADER psh;
HPROPSHEETPAGE hPage;
LONG lResult;
ZeroMemory(&psh, sizeof(psh));
do
{
if (fJob)
{
pJob = g_pJob;
}
else
{
#ifdef NOT_YET
hr = Expect(TKN_STRING, ppwsz, L"job name");
BREAK_ON_FAILURE(hr);
hr = g_pJobQueue->GetTask(
g_wszLastStringToken,
IID_IUnknown,
&spunkJob);
LOG_AND_BREAK_ON_FAIL(hr, "ITaskQueue::GetTask");
hr = spunkJob->QueryInterface(IID_ITask, (VOID**)(ITask**)&spJob);
LOG_AND_BREAK_ON_FAIL(hr, "QI for ITask");
pJob = spJob;
#endif // NOT_YET
hr = E_NOTIMPL;
}
//
// See if the optional property sheet page argument has been
// specified. If so, retrieve and open just that page, otherwise use
// the EditJob method to open all the pages.
//
tkn = PeekToken(ppwsz);
if (tkn == TKN_NUMBER)
{
GetToken(ppwsz);
ulType = g_ulLastNumberToken;
//
// Now see if the optional value for fPersistChanges was
// provided.
//
tkn = PeekToken(ppwsz);
if (tkn == TKN_STRING)
{
GetToken(ppwsz);
fPersist = g_wszLastStringToken[0] == L't' ||
g_wszLastStringToken[0] == L'T';
}
//
// Get the interface that has the method that returns a page.
// Then retrieve the page the user asked for.
//
hr = pJob->QueryInterface(
IID_IProvideTaskPage,
(VOID**)(IProvideTaskPage**)&spProvideTaskPage);
LOG_AND_BREAK_ON_FAIL(hr, "QI for IProvideTaskPage");
g_Log.Write(
LOG_TRACE,
"Opening page %u, changes will%s be persisted",
ulType,
fPersist ? "" : " not");
hr = spProvideTaskPage->GetPage((TASKPAGE)ulType, fPersist, &hPage);
LOG_AND_BREAK_ON_FAIL(hr, "IProvideTaskPage::GetPage");
//
// Now that we have the page, display it in its very own
// property sheet.
//
psh.dwSize = sizeof(PROPSHEETHEADER);
psh.dwFlags = PSH_DEFAULT;
psh.hwndParent = NULL;
psh.hInstance = NULL;
psh.pszCaption = TEXT("jt job object");
psh.phpage = &hPage;
psh.nPages = 1;
lResult = PropertySheet(&psh);
if (lResult == -1)
{
g_Log.Write(LOG_FAIL, "PropertySheet (%u)", GetLastError());
hr = HRESULT_FROM_WIN32(GetLastError());
}
}
else
{
hr = pJob->EditWorkItem(NULL, TRUE);
LOG_AND_BREAK_ON_FAIL(hr, "ITask::EditWorkItem");
}
}
while (0);
return hr;
}
//+---------------------------------------------------------------------------
//
// Function: EnumClone
//
// Synopsis: Invoke the IEnumJobs::Clone command
//
// Arguments: [ppwsz] - command line
//
// Returns: S_OK - a slot has been filled with cloned enumerator
// E_INVALIDARG - bad slot number
//
// Modifies: g_apEnumJobs
//
// History: 01-30-96 DavidMun Created
//
//----------------------------------------------------------------------------
HRESULT EnumClone(WCHAR **ppwsz)
{
HRESULT hr = S_OK;
ULONG idxDestSlot;
ULONG idxSourceSlot;
do
{
hr = GetAndPrepareEnumeratorSlot(ppwsz, &idxDestSlot);
BREAK_ON_FAILURE(hr);
hr = GetEnumeratorSlot(ppwsz, &idxSourceSlot);
BREAK_ON_FAILURE(hr);
hr = VerifySlotFilled(idxSourceSlot);
BREAK_ON_FAILURE(hr);
g_Log.Write(
LOG_TRACE,
"Cloning enumerator in slot %u into slot %u",
idxSourceSlot,
idxDestSlot);
hr = g_apEnumJobs[idxSourceSlot]->Clone(&g_apEnumJobs[idxDestSlot]);
if (FAILED(hr))
{
g_Log.Write(
LOG_FAIL,
"IEnumJobs::Clone hr=%#010x",
hr);
}
}
while (0);
return hr;
}
//+---------------------------------------------------------------------------
//
// Function: EnumNext
//
// Synopsis: Invoke the IEnumJobs::Next command
//
// Arguments: [ppwsz] - command line
//
// Returns: S_OK - Next performed successfully
// E_INVALIDARG - bad slot number
//
// History: 01-30-96 DavidMun Created
//
//----------------------------------------------------------------------------
HRESULT EnumNext(WCHAR **ppwsz)
{
HRESULT hr = S_OK;
ULONG idxSlot;
LPWSTR *ppwszFetched;
LPWSTR *ppwszCur;
ULONG cFetched;
ULONG i;
do
{
hr = GetEnumeratorSlot(ppwsz, &idxSlot);
BREAK_ON_FAILURE(hr);
hr = VerifySlotFilled(idxSlot);
BREAK_ON_FAILURE(hr);
hr = Expect(TKN_NUMBER, ppwsz, L"number of items to enumerate");
BREAK_ON_FAILURE(hr);
g_Log.Write(
LOG_TRACE,
"Enumerating next %u items using enumerator in slot %u",
g_ulLastNumberToken,
idxSlot);
hr = g_apEnumJobs[idxSlot]->Next(g_ulLastNumberToken, &ppwszFetched, &cFetched);
LOG_AND_BREAK_ON_FAIL(hr, "IEnumJobs::Next");
if (hr == S_FALSE)
{
g_Log.Write(LOG_INFO, "IEnumJobs::Next returned S_FALSE");
}
if (cFetched != g_ulLastNumberToken)
{
g_Log.Write(
LOG_INFO,
"IEnumJobs::Next fetched only %u jobs",
cFetched);
}
for (i = 0, ppwszCur = ppwszFetched; i < cFetched; i++, ppwszCur++)
{
g_Log.Write(LOG_TEXT, "%u: %S", idxSlot, *ppwszCur);
CoTaskMemFree(*ppwszCur);
}
CoTaskMemFree(ppwszFetched);
}
while (0);
return hr;
}
//+---------------------------------------------------------------------------
//
// Function: EnumReset
//
// Synopsis: Invoke the IEnumJobs::Reset command
//
// Arguments: [ppwsz] - command line
//
// Returns: S_OK - Reset performed successfully
// E_INVALIDARG - bad slot number
//
// History: 01-30-96 DavidMun Created
//
//----------------------------------------------------------------------------
HRESULT EnumReset(WCHAR **ppwsz)
{
HRESULT hr = S_OK;
ULONG idxSlot;
do
{
hr = GetEnumeratorSlot(ppwsz, &idxSlot);
BREAK_ON_FAILURE(hr);
hr = VerifySlotFilled(idxSlot);
BREAK_ON_FAILURE(hr);
g_Log.Write(LOG_TRACE, "Resetting enumerator in slot %u", idxSlot);
hr = g_apEnumJobs[idxSlot]->Reset();
LOG_AND_BREAK_ON_FAIL(hr, "IEnumJobs::Reset");
}
while (0);
return hr;
}
//+---------------------------------------------------------------------------
//
// Function: EnumSkip
//
// Synopsis: Invoke the IEnumJobs::Skip command
//
// Arguments: [ppwsz] - command line
//
// Returns: S_OK - Skip performed successfully
// E_INVALIDARG - bad slot number
//
// History: 01-30-96 DavidMun Created
//
//----------------------------------------------------------------------------
HRESULT EnumSkip(WCHAR **ppwsz)
{
HRESULT hr = S_OK;
ULONG idxSlot;
do
{
hr = GetEnumeratorSlot(ppwsz, &idxSlot);
BREAK_ON_FAILURE(hr);
hr = VerifySlotFilled(idxSlot);
BREAK_ON_FAILURE(hr);
hr = Expect(TKN_NUMBER, ppwsz, L"number of items to skip");
BREAK_ON_FAILURE(hr);
g_Log.Write(
LOG_TRACE,
"Skipping next %u items using enumerator in slot %u",
g_ulLastNumberToken,
idxSlot);
hr = g_apEnumJobs[idxSlot]->Skip(g_ulLastNumberToken);
LOG_AND_BREAK_ON_FAIL(hr, "IEnumJobs::Skip");
if (hr == S_FALSE)
{
g_Log.Write(LOG_INFO, "IEnumJobs::Skip returned S_FALSE");
}
}
while (0);
return hr;
}
//+---------------------------------------------------------------------------
//
// Function: Load
//
// Synopsis: Load the job or queue file specified on the command line
// into the global job or queue object.
//
// Arguments: [ppwsz] - command line.
// [szJobOrQueue] - "Job" or "Queue"
// [fJob] - TRUE=>use global job, FALSE=>use global queue
//
// Returns: S_OK - job or queue loaded
// E_* - error logged
//
// History: 01-10-96 DavidMun Created
//
//----------------------------------------------------------------------------
HRESULT Load(WCHAR **ppwsz, CHAR *szJobOrQueue, BOOL fJob)
{
HRESULT hr = S_OK;
SpIPersistFile spPersistFile;
do
{
hr = GetFilename(ppwsz, L"file to load");
BREAK_ON_FAILURE(hr);
g_Log.Write(
LOG_TRACE,
"Loading %s %S",
szJobOrQueue,
g_wszLastStringToken);
if (fJob)
{
g_pJob->QueryInterface(
IID_IPersistFile,
(VOID**)(IPersistFile**)&spPersistFile);
LOG_AND_BREAK_ON_FAIL(hr, "ITask::QI(IPersistFile)");
}
else
{
g_pJobQueue->QueryInterface(
IID_IPersistFile,
(VOID**)(IPersistFile**)&spPersistFile);
LOG_AND_BREAK_ON_FAIL(hr, "ITaskQueue::QI(IPersistFile)");
}
DWORD ulTicks = GetTickCount();
hr = spPersistFile->Load(
g_wszLastStringToken,
STGM_READWRITE | STGM_SHARE_EXCLUSIVE);
ulTicks = GetTickCount() - ulTicks;
g_Log.Write(LOG_PERF, "Load took %lu ms", ulTicks);
LOG_AND_BREAK_ON_FAIL(hr, "IPersistFile::Load");
}
while (0);
return hr;
}
//+---------------------------------------------------------------------------
//
// Function: PrintAll
//
// Synopsis: Print all properties of global job or queue.
//
// Arguments: [ppwsz] - command line
// [fJob] - TRUE=>use global job, FALSE=>use global queue
//
// Returns: S_OK - command executed
// E_* - error logged
//
// Modifies: *[ppwsz]
//
// History: 01-10-96 DavidMun Created
//
//----------------------------------------------------------------------------
HRESULT PrintAll(WCHAR **ppwsz, BOOL fJob)
{
HRESULT hr = S_OK;
do
{
if (!fJob)
{
g_Log.Write(LOG_ERROR, "this command is not yet implemented");
break;
}
else
{
hr = DumpJob(g_pJob);
BREAK_ON_FAILURE(hr);
hr = DumpJobTriggers(g_pJob);
}
}
while (0);
return hr;
}
//+---------------------------------------------------------------------------
//
// Function: PrintRunTimes
//
// Synopsis: Parse and execute the print job run times command
//
// Arguments: [ppwsz] - command line
// [fJob] - TRUE=>use global job, FALSE=>use global queue
//
// Returns: S_OK - command executed
// E_* - error logged
//
// Modifies: *[ppwsz]
//
// History: 01-05-96 DavidMun Created
//
//----------------------------------------------------------------------------
HRESULT PrintRunTimes(WCHAR **ppwsz, BOOL fJob)
{
HRESULT hr = S_OK;
TOKEN tkn;
USHORT cRuns = 0;
SYSTEMTIME stNow;
LPSYSTEMTIME pstRuns = NULL;
USHORT i;
do
{
tkn = PeekToken(ppwsz);
if (tkn == TKN_NUMBER)
{
GetToken(ppwsz);
cRuns = (USHORT) g_ulLastNumberToken;
}
GetLocalTime(&stNow);
//
// If the optional number of runs was not specified or was 0,
// print remaining runs for today only.
//
if (cRuns == 0)
{
SYSTEMTIME stEnd;
stEnd = stNow;
stEnd.wHour = 23;
stEnd.wMinute = 59;
if (fJob)
{
hr = g_pJob->GetRunTimes(&stNow, &stEnd, &cRuns, &pstRuns);
LOG_AND_BREAK_ON_FAIL(hr, "ITask::GetRunTimes");
}
else
{
#ifdef NOT_YET
hr = g_pJobQueue->GetRunTimes(&stNow, &stEnd, &cRuns, &pstRuns);
LOG_AND_BREAK_ON_FAIL(hr, "ITaskQueue::GetRunTimes");
#endif // NOT_YET
hr = E_NOTIMPL;
}
if (cRuns == 0)
{
g_Log.Write(LOG_TEXT, "No runs are scheduled for today.");
break;
}
g_Log.Write(LOG_TEXT, "The remaining %u run", cRuns);
g_Log.Write(LOG_TEXT, "times for today:");
g_Log.Write(LOG_TEXT, "--------------------");
}
else
{
//
// cRuns > 0. Get at most the next cRuns run times.
//
if (fJob)
{
hr = g_pJob->GetRunTimes(&stNow, NULL, &cRuns, &pstRuns);
LOG_AND_BREAK_ON_FAIL(hr, "ITask::GetRunTimes");
}
else
{
#ifdef NOT_YET
hr = g_pJobQueue->GetRunTimes(&stNow, NULL, &cRuns, &pstRuns);
LOG_AND_BREAK_ON_FAIL(hr, "ITask::GetRunTimes");
#endif // NOT_YET
hr = E_NOTIMPL;
}
if (cRuns == 0)
{
g_Log.Write(LOG_TEXT, "No runs are scheduled. hr = %#lx", hr);
break;
}
g_Log.Write(LOG_TEXT, "ITask::GetRunTimes succeeded, hr = %#lx", hr);
g_Log.Write(LOG_TEXT, "The next %u run times:", cRuns);
g_Log.Write(LOG_TEXT, "----------------------");
}
for (i = 0; i < cRuns; i++)
{
g_Log.Write(
LOG_TEXT,
"%02d/%02d/%d at %02d:%02d:%02d",
pstRuns[i].wMonth,
pstRuns[i].wDay,
pstRuns[i].wYear,
pstRuns[i].wHour,
pstRuns[i].wMinute,
pstRuns[i].wSecond);
}
}
while (0);
CoTaskMemFree(pstRuns);
return hr;
}
//+---------------------------------------------------------------------------
//
// Function: PrintTrigger
//
// Synopsis: Print one or more trigger's properties
//
// Arguments: [ppwsz] - command line
// [fJob] - TRUE=>use g_pJob, FALSE=>use g_pJobQueue
//
// Returns: S_OK - trigger(s) printed
// E_* - error logged
//
// History: 01-10-96 DavidMun Created
//
//----------------------------------------------------------------------------
HRESULT PrintTrigger(WCHAR **ppwsz, BOOL fJob)
{
HRESULT hr = S_OK;
USHORT usTrigger = 0;
BOOL fPrintAll = FALSE;
SpIJobTrigger spTrigger;
do
{
if (PeekToken(ppwsz) == TKN_NUMBER)
{
GetToken(ppwsz);
usTrigger = (USHORT) g_ulLastNumberToken;
}
else
{
fPrintAll = TRUE;
}
if (fPrintAll)
{
hr = DumpTriggers(fJob);
}
else
{
hr = DumpTrigger(fJob, usTrigger);
}
}
while (0);
return hr;
}
//+---------------------------------------------------------------------------
//
// Function: PrintTriggerStrings
//
// Synopsis: Parse and execute the command to print one or all trigger
// strings for a job.
//
// Arguments: [ppwsz] - command line
// [fJob] - TRUE=>use g_pJob, FALSE=>use g_pJobQueue
//
// Returns: S_OK - string(s) printed
// E_* - error logged
//
// Modifies: *[ppwsz]
//
// History: 01-05-96 DavidMun Created
//
//----------------------------------------------------------------------------
HRESULT PrintTriggerStrings(WCHAR **ppwsz, CHAR *szJobOrQueue, BOOL fJob)
{
HRESULT hr = S_OK;
TOKEN tkn;
BOOL fAllTriggers = TRUE;
USHORT usTrigger;
USHORT cTriggers;
SHORT i;
WCHAR * pwszTriggerString;
do
{
tkn = PeekToken(ppwsz);
if (tkn == TKN_NUMBER)
{
GetToken(ppwsz);
fAllTriggers = FALSE;
usTrigger = (USHORT) g_ulLastNumberToken;
}
if (fJob)
{
hr = g_pJob->GetTriggerCount(&cTriggers);
LOG_AND_BREAK_ON_FAIL(hr, "ITask::GetTriggerCount");
}
else
{
#ifdef NOT_YET
hr = g_pJobQueue->GetTriggerCount(&cTriggers);
LOG_AND_BREAK_ON_FAIL(hr, "ITaskQueue::GetTriggerCount");
#endif // NOT_YET
hr = E_NOTIMPL;
}
if (!cTriggers)
{
g_Log.Write(LOG_TEXT, "There are no triggers on the %s", szJobOrQueue);
break;
}
if (fAllTriggers)
{
g_Log.Write(LOG_TEXT, "All %u triggers on %s:", cTriggers, szJobOrQueue);
g_Log.Write(LOG_TEXT, "Index Value");
g_Log.Write(LOG_TEXT, "----- -----------------------------------------------------");
for (i = 0; i < cTriggers; i++)
{
if (fJob)
{
hr = g_pJob->GetTriggerString(i, &pwszTriggerString);
LOG_AND_BREAK_ON_FAIL(hr, "ITask::GetTriggerString");
}
else
{
#ifdef NOT_YET
hr = g_pJobQueue->GetTriggerString(i, &pwszTriggerString);
LOG_AND_BREAK_ON_FAIL(hr, "ITask::GetTriggerString");
#endif // NOT_YET
hr = E_NOTIMPL;
}
g_Log.Write(LOG_TEXT, "% 5d %S", i, pwszTriggerString);
CoTaskMemFree(pwszTriggerString);
if (i < cTriggers - 1)
{
g_Log.Write(LOG_TEXT, "");
}
}
}
else
{
g_Log.Write(LOG_TEXT, "Trigger %u:", usTrigger);
if (fJob)
{
hr = g_pJob->GetTriggerString(usTrigger,
&pwszTriggerString);
LOG_AND_BREAK_ON_FAIL(hr, "ITask::GetTriggerString");
}
else
{
#ifdef NOT_YET
hr = g_pJobQueue->GetTriggerString(usTrigger,
&pwszTriggerString);
LOG_AND_BREAK_ON_FAIL(hr, "ITaskQueue::GetTriggerString");
#endif // NOT_YET
hr = E_NOTIMPL;
}
g_Log.Write(LOG_TEXT, "%S", pwszTriggerString);
CoTaskMemFree(pwszTriggerString);
}
}
while (0);
return hr;
}
//+---------------------------------------------------------------------------
//
// Function: Run
//
// Synopsis: Run job or queue object.
//
// Arguments: [fJob] - TRUE=>use g_pJob, FALSE=>use g_pJobQueue
//
// Returns: Result of ITask[Queue]::Run
//
// History: 01-11-96 DavidMun Created
//
//----------------------------------------------------------------------------
HRESULT Run(BOOL fJob)
{
HRESULT hr = S_OK;
if (fJob)
{
g_Log.Write(LOG_TRACE, "Running job");
hr = g_pJob->Run();
if (FAILED(hr))
{
g_Log.Write(LOG_FAIL, "ITask::Run hr=%#010x", hr);
}
}
else
{
#ifdef NOT_YET
g_Log.Write(LOG_TRACE, "Running queue");
hr = g_pJobQueue->Run();
if (FAILED(hr))
{
g_Log.Write(LOG_FAIL, "ITaskQueue::Run hr=%#010x", hr);
}
#endif // NOT_YET
hr = E_NOTIMPL;
}
return hr;
}
//+---------------------------------------------------------------------------
//
// Function: Save
//
// Synopsis: Persist the global job or queue to the file specified in
// the command line
//
// Arguments: [ppwsz] - command line.
// [szJobOrQueue] - "Job" or "Queue"
// [fJob] - TRUE=>use global job, FALSE=>use global queue
//
// Returns: S_OK - job or queue persisted
// E_* - error logged
//
// History: 01-10-96 DavidMun Created
//
//----------------------------------------------------------------------------
HRESULT Save(WCHAR **ppwsz, CHAR *szJobOrQueue, BOOL fJob)
{
HRESULT hr = S_OK;
TOKEN tkn;
WCHAR *pwszFilename = NULL;
SpIPersistFile spPersistFile;
do
{
tkn = PeekToken(ppwsz);
if (tkn == TKN_STRING)
{
hr = GetFilename(ppwsz, L"filename for save");
BREAK_ON_FAILURE(hr);
pwszFilename = g_wszLastStringToken;
g_Log.Write(LOG_TRACE, "Saving %s to %S", szJobOrQueue, g_wszLastStringToken);
}
else
{
g_Log.Write(LOG_TRACE, "Saving %s", szJobOrQueue);
}
if (fJob)
{
g_pJob->QueryInterface(
IID_IPersistFile,
(VOID**)(IPersistFile**)&spPersistFile);
LOG_AND_BREAK_ON_FAIL(hr, "ITask::QI(IPersistFile)");
}
else
{
g_pJobQueue->QueryInterface(
IID_IPersistFile,
(VOID**)(IPersistFile**)&spPersistFile);
LOG_AND_BREAK_ON_FAIL(hr, "ITaskQueue::QI(IPersistFile)");
}
DWORD ulTicks = GetTickCount();
hr = spPersistFile->Save(pwszFilename, TRUE);
ulTicks = GetTickCount() - ulTicks;
g_Log.Write(LOG_PERF, "Save took %lu ms", ulTicks);
LOG_AND_BREAK_ON_FAIL(hr, "IPersistFile::Save");
}
while (0);
return hr;
}
//+---------------------------------------------------------------------------
//
// Function: SchedActivate
//
// Synopsis: Perform activate job/queue command.
//
// Arguments: [ppwsz] - commandline.
//
// Returns: S_OK - activated job or queue
// E_* - error logged
//
// History: 01-11-96 DavidMun Created
//
// Notes: This is the command-line front end to the utility routine
// Activate. That routine is also called by other routines;
// see SchedEnum.
//
//----------------------------------------------------------------------------
HRESULT SchedActivate(WCHAR **ppwsz)
{
HRESULT hr = S_OK;
BOOL fJob;
do
{
hr = Expect(TKN_STRING, ppwsz, L"job or queue filename");
BREAK_ON_FAILURE(hr);
hr = Activate(g_wszLastStringToken, &g_pJob, &g_pJobQueue, &fJob);
}
while (0);
return hr;
}
//+---------------------------------------------------------------------------
//
// Function: SchedAddJob
//
// Synopsis: Perform add job command.
//
// Arguments: [ppwsz] - commandline.
//
// Returns: S_OK - added job
// E_* - error logged
//
// History: 01-11-96 DavidMun Created
//
//----------------------------------------------------------------------------
HRESULT SchedAddJob(WCHAR **ppwsz)
{
HRESULT hr = S_OK;
do
{
//
// Note this filename may be a path relative to the job folder, so we
// don't want to expand it to a full path name by calling GetFilename.
// Just read it as a string instead.
//
hr = Expect(TKN_STRING, ppwsz, L"job filename");
BREAK_ON_FAILURE(hr);
g_Log.Write(LOG_TRACE, "Adding job '%S'", g_wszLastStringToken);
hr = g_pJobScheduler->AddWorkItem(g_wszLastStringToken, g_pJob);
LOG_AND_BREAK_ON_FAIL(hr, "ITaskScheduler::AddWorkItemn");
}
while (0);
return hr;
}
//+---------------------------------------------------------------------------
//
// Function: SchedCreateEnum
//
// Synopsis: Create a new jobs folder enumerator in the slot specified
// by command line
//
// Arguments: [ppwsz] - command line
//
// Returns: S_OK - new enumerator created
// E_INVALIDARG - command line has bad slot number
// E_* - from ITaskScheduler::EnumJobs
//
// Modifies: g_apEnumJobs
//
// History: 01-30-96 DavidMun Created
//
//----------------------------------------------------------------------------
HRESULT SchedCreateEnum(WCHAR **ppwsz)
{
HRESULT hr = S_OK;
ULONG idxSlot;
do
{
hr = GetAndPrepareEnumeratorSlot(ppwsz, &idxSlot);
BREAK_ON_FAILURE(hr);
g_Log.Write(LOG_TRACE, "Creating new enumerator in slot %u", idxSlot);
hr = g_pJobScheduler->Enum(&g_apEnumJobs[idxSlot]);
LOG_AND_BREAK_ON_FAIL(hr, "ITaskScheduler::Enum");
}
while (0);
return hr;
}
//+---------------------------------------------------------------------------
//
// Function: SchedDelete
//
// Synopsis: Perform delete job/queue command.
//
// Arguments: [ppwsz] - commandline.
//
// Returns: S_OK - deleted job or queue
// E_* - error logged
//
// History: 01-11-96 DavidMun Created
//
//----------------------------------------------------------------------------
HRESULT SchedDelete(WCHAR **ppwsz)
{
HRESULT hr = S_OK;
do
{
hr = Expect(TKN_STRING, ppwsz, L"job or queue filename to delete");
BREAK_ON_FAILURE(hr);
g_Log.Write(LOG_TRACE, "Deleting '%S'", g_wszLastStringToken);
hr = g_pJobScheduler->Delete(g_wszLastStringToken);
LOG_AND_BREAK_ON_FAIL(hr, "ITaskScheduler::Delete");
}
while (0);
return hr;
}
//+---------------------------------------------------------------------------
//
// Function: SchedEnum
//
// Synopsis: Perform enumerate jobs/queues command.
//
// Arguments: [ppwsz] - commandline.
//
// Returns: S_OK - job/queue names enumerated
// E_* - error logged
//
// History: 01-12-96 DavidMun Created
//
//----------------------------------------------------------------------------
HRESULT SchedEnum(WCHAR **ppwsz)
{
HRESULT hr = S_OK;
SpIEnumJobs spEnum;
TOKEN tkn;
ULONG i;
ULONG cToFetch = DEFAULT_FETCH_COUNT;
ULONG cFetched;
BOOL fPrint = FALSE;
do
{
g_Log.Write(LOG_TRACE, "Enumerating jobs and queues");
tkn = PeekToken(ppwsz);
while (tkn == TKN_NUMBER || tkn == TKN_STRING)
{
GetToken(ppwsz);
if (tkn == TKN_NUMBER)
{
cToFetch = g_ulLastNumberToken;
}
else
{
if (towupper(g_wszLastStringToken[0]) == L'P')
{
fPrint = TRUE;
}
}
tkn = PeekToken(ppwsz);
}
hr = g_pJobScheduler->Enum(&spEnum);
LOG_AND_BREAK_ON_FAIL(hr, "ITaskScheduler::Enum");
do
{
LPWSTR *ppwszFetched;
LPWSTR *ppwszCur;
hr = spEnum->Next(cToFetch, &ppwszFetched, &cFetched);
LOG_AND_BREAK_ON_FAIL(hr, "IEnumJobs::Next");
for (i = 0, ppwszCur = ppwszFetched; i < cFetched; i++, ppwszCur++)
{
if (fPrint)
{
SpIJob spJob;
SpIUnknown spQueue;
BOOL fJob;
hr = Activate(*ppwszCur, &spJob, &spQueue, &fJob);
if (SUCCEEDED(hr))
{
if (fJob)
{
DumpJob(spJob);
DumpJobTriggers(spJob);
}
else
{
// BUGBUG call DumpQueue here
g_Log.Write(
LOG_WARN,
"Ignoring %S: DumpQueue not implemented",
*ppwszCur);
}
}
g_Log.Write(LOG_TEXT, "");
g_Log.Write(LOG_TEXT, "");
}
else
{
g_Log.Write(LOG_TEXT, " %S", *ppwszCur);
}
CoTaskMemFree(*ppwszCur);
}
CoTaskMemFree(ppwszFetched);
} while (cFetched);
}
while (0);
return hr;
}
//+---------------------------------------------------------------------------
//
// Function: GetCredentials
//
// Synopsis: Retrieve the account name associated with the job's
// credentials.
//
// Returns: Result of GetTargetComputer call.
//
// History: 06-04-96 DavidMun Created
//
//----------------------------------------------------------------------------
HRESULT GetCredentials(void)
{
HRESULT hr;
LPWSTR pwszAccount;
if (g_pJob == NULL)
{
g_Log.Write(
LOG_FAIL,
"A job object must be specified to get account information.");
return(E_FAIL);
}
hr = g_pJob->GetAccountInformation(&pwszAccount);
if (FAILED(hr))
{
g_Log.Write(LOG_FAIL,
"ITaskScheduler::GetAccountInformation hr=%#010x", hr);
}
else
{
g_Log.Write(LOG_TRACE, "Credential account name = '%S'", pwszAccount);
CoTaskMemFree(pwszAccount);
}
return(hr);
}
//+---------------------------------------------------------------------------
//
// Function: SchedGetMachine
//
// Synopsis: Perform Get Machine command (print target computer).
//
// Returns: Result of GetTargetComputer call.
//
// History: 06-04-96 DavidMun Created
//
//----------------------------------------------------------------------------
HRESULT SchedGetMachine()
{
HRESULT hr;
LPWSTR pwszComputer;
hr = g_pJobScheduler->GetTargetComputer(&pwszComputer);
if (FAILED(hr))
{
g_Log.Write(LOG_FAIL, "ITaskScheduler::GetTargetComputer hr=%#010x", hr);
}
else
{
g_Log.Write(LOG_TRACE, "TargetComputer = '%S'", pwszComputer);
CoTaskMemFree(pwszComputer);
}
return hr;
}
//+---------------------------------------------------------------------------
//
// Function: SchedIsJobOrQueue
//
// Synopsis: Call the ITaskScheduler::IsJob and IsQueue commands on the
// specified filename and report the results.
//
// Arguments: [ppwsz] - commandline.
//
// Returns: S_OK - methods called
// E_* - invalid commandline
//
// History: 03-11-96 DavidMun Created
//
// Notes: Don't consider errors returned by the IsJob and IsQueue
// methods as errors in calling this routine. That would
// halt a script that purposely gives them bad paths.
//
//----------------------------------------------------------------------------
HRESULT SchedIsJobOrQueue(WCHAR **ppwsz)
{
HRESULT hr = S_OK;
do
{
hr = Expect(TKN_STRING, ppwsz, L"filename to test");
BREAK_ON_FAILURE(hr);
hr = g_pJobScheduler->IsOfType(g_wszLastStringToken, IID_ITask);
g_Log.Write(
LOG_TRACE,
"ITaskScheduler::IsOfType(%S) returned %#010x",
g_wszLastStringToken,
hr);
#ifdef NOT_YET
hr = g_pJobScheduler->IsQueue(g_wszLastStringToken);
g_Log.Write(
LOG_TRACE,
"ITaskScheduler::IsQueue(%S) returned %#010x",
g_wszLastStringToken,
hr);
#endif
hr = S_OK;
}
while (0);
return hr;
}
//+---------------------------------------------------------------------------
//
// Function: SchedNewJob
//
// Synopsis: Perform new job command.
//
// Arguments: [ppwsz] - commandline.
//
// Returns: S_OK - created new job
// E_* - error logged
//
// History: 01-11-96 DavidMun Created
//
//----------------------------------------------------------------------------
HRESULT SchedNewJob(WCHAR **ppwsz)
{
HRESULT hr = S_OK;
SpIJob spNewJob;
do
{
hr = Expect(TKN_STRING, ppwsz, L"job filename");
BREAK_ON_FAILURE(hr);
g_Log.Write(LOG_TRACE, "Creating new job '%S'", g_wszLastStringToken);
DWORD ulTicks = GetTickCount();
hr = g_pJobScheduler->NewWorkItem(
g_wszLastStringToken,
CLSID_CTask,
IID_ITask,
(IUnknown**)(ITask**)&spNewJob);
ulTicks = GetTickCount() - ulTicks;
g_Log.Write(LOG_PERF, "NewWorkItem call took %lu ms", ulTicks);
LOG_AND_BREAK_ON_FAIL(hr, "ITaskScheduler::NewWorkItem");
//
// Replace the global job object with the new one.
//
g_pJob->Release();
spNewJob.Transfer(&g_pJob);
}
while (0);
return hr;
}
//+---------------------------------------------------------------------------
//
// Function: SetCredentials
//
// Synopsis: Call SetAccountInformation to set the job credentials.
//
// Arguments: [ppwsz] - command line.
//
// Returns: Result of calling ITaskScheduler::SetAccountInformation
//
// History: 06-22-96 MarkBl Created
// 07-22-96 DavidMun Method now takes just two arguments
//
//----------------------------------------------------------------------------
HRESULT SetCredentials(WCHAR **ppwsz)
{
WCHAR wszAccountNew[MAX_USERNAME + 1]; //see sched\inc\defines.hxx
WCHAR wszPasswordNew[MAX_PASSWORD + 1];
HRESULT hr;
TOKEN tkn;
ZeroMemory(wszAccountNew, sizeof(wszAccountNew));
ZeroMemory(wszPasswordNew, sizeof(wszPasswordNew));
do
{
hr = Expect(TKN_STRING, ppwsz, L"new account name");
BREAK_ON_FAILURE(hr);
wcsncpy(wszAccountNew,
g_wszLastStringToken,
min(wcslen(g_wszLastStringToken) + 1, MAX_USERNAME));
wszAccountNew[MAX_USERNAME] = L'\0';
hr = Expect(TKN_STRING, ppwsz, L"new account password");
BREAK_ON_FAILURE(hr);
wcsncpy(wszPasswordNew,
g_wszLastStringToken,
min(wcslen(g_wszLastStringToken) + 1, MAX_PASSWORD));
wszPasswordNew[MAX_PASSWORD] = L'\0';
g_Log.Write(LOG_TRACE, "Setting account information");
hr = g_pJob->SetAccountInformation(wszAccountNew,
wcscmp(wszPasswordNew, L"NULL") ? wszPasswordNew :
NULL);
if (FAILED(hr))
{
g_Log.Write(
LOG_FAIL,
"ITaskScheduler::SetAccountInformation hr=%#010x",
hr);
}
} while (0);
return hr;
}
//+---------------------------------------------------------------------------
//
// Function: SchedSetMachine
//
// Synopsis: Call SetTargetComputer with computer name (NULL if not
// specified on command line).
//
// Arguments: [ppwsz] - command line.
//
// Returns: Result of calling ITaskScheduler::SetTargetComputer
//
// History: 06-04-96 DavidMun Created
//
//----------------------------------------------------------------------------
HRESULT SchedSetMachine(WCHAR **ppwsz)
{
HRESULT hr;
TOKEN tkn;
LPWSTR pwszComputer = NULL;
tkn = PeekToken(ppwsz);
if (tkn == TKN_STRING)
{
GetToken(ppwsz);
pwszComputer = g_wszLastStringToken;
}
g_Log.Write(LOG_TRACE, "Setting target computer to '%S'", pwszComputer);
hr = g_pJobScheduler->SetTargetComputer(pwszComputer);
if (FAILED(hr))
{
g_Log.Write(
LOG_FAIL,
"ITaskScheduler::SetTargetComputer hr=%#010x",
hr);
}
return hr;
}
//+---------------------------------------------------------------------------
//
// Function: SetJob
//
// Synopsis: Set one or more properties on the global job.
//
// Arguments: [ppwsz] - command line.
//
// Returns: S_OK - job properties set
// E_* - error logged
//
// History: 01-10-96 DavidMun Created
//
//----------------------------------------------------------------------------
HRESULT SetJob(WCHAR **ppwsz)
{
HRESULT hr = S_OK;
CJobProp JobProperties;
do
{
g_Log.Write(LOG_TRACE, "Setting job's properties");
hr = JobProperties.Parse(ppwsz);
BREAK_ON_FAILURE(hr);
//
// Set the job's properties to the values we just parsed
//
hr = JobProperties.SetActual(g_pJob);
}
while (0);
return hr;
}
//+---------------------------------------------------------------------------
//
// Function: SetTrigger
//
// Synopsis: Parse and execute the set trigger command.
//
// Arguments: [ppwsz] - command line
//
// Returns: S_OK - trigger modified
// E_* - error logged
//
// Modifies: *[ppwsz]
//
// History: 01-05-96 DavidMun Created
//
//----------------------------------------------------------------------------
HRESULT SetTrigger(WCHAR **ppwsz, BOOL fJob)
{
HRESULT hr = S_OK;
CTrigProp TriggerProps;
SHORT usTrigger = 0;
SpIJobTrigger spTrigger;
do
{
if (PeekToken(ppwsz) == TKN_NUMBER)
{
GetToken(ppwsz);
usTrigger = (SHORT) g_ulLastNumberToken;
}
g_Log.Write(
LOG_TRACE,
"Setting properties on trigger %u",
usTrigger);
hr = TriggerProps.Parse(ppwsz);
BREAK_ON_FAILURE(hr);
if (fJob)
{
hr = g_pJob->GetTrigger(usTrigger, &spTrigger);
LOG_AND_BREAK_ON_FAIL(hr, "ITask::GetTrigger");
}
else
{
#ifdef NOT_YET
hr = g_pJobQueue->GetTrigger(usTrigger, &spTrigger);
LOG_AND_BREAK_ON_FAIL(hr, "ITaskQueue::GetTrigger");
#endif // NOT_YET
hr = E_NOTIMPL;
}
hr = TriggerProps.SetActual(spTrigger);
}
while (0);
return hr;
}