2017-03-19 00:11:31 +00:00
|
|
|
/*
|
|
|
|
* PROJECT: ReactOS AT utility
|
|
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
|
|
* FILE: base/applications/cmdutils/at/at.c
|
|
|
|
* PURPOSE: ReactOS AT utility
|
|
|
|
* PROGRAMMERS: Eric Kohl <eric.kohl@reactos.org>
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
|
|
|
|
#include <windef.h>
|
|
|
|
#include <winbase.h>
|
|
|
|
#include <winuser.h>
|
|
|
|
#include <wincon.h>
|
|
|
|
#include <winnls.h>
|
|
|
|
#include <lm.h>
|
|
|
|
|
|
|
|
#include <conutils.h>
|
|
|
|
|
|
|
|
#include "resource.h"
|
|
|
|
|
2017-03-21 20:32:54 +00:00
|
|
|
|
|
|
|
PWSTR pszDaysOfWeekArray[7] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL};
|
|
|
|
|
|
|
|
|
|
|
|
static
|
|
|
|
VOID
|
|
|
|
FreeDaysOfWeekArray(VOID)
|
|
|
|
{
|
|
|
|
INT i;
|
|
|
|
|
|
|
|
for (i = 0; i < 7; i++)
|
|
|
|
{
|
|
|
|
if (pszDaysOfWeekArray[i] != NULL)
|
|
|
|
HeapFree(GetProcessHeap(), 0, pszDaysOfWeekArray[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static
|
|
|
|
BOOL
|
|
|
|
InitDaysOfWeekArray(VOID)
|
|
|
|
{
|
|
|
|
INT i, nLength;
|
|
|
|
|
|
|
|
for (i = 0; i < 7; i++)
|
|
|
|
{
|
|
|
|
nLength = GetLocaleInfo(LOCALE_USER_DEFAULT,
|
|
|
|
LOCALE_SABBREVDAYNAME1 + i,
|
|
|
|
NULL,
|
|
|
|
0);
|
|
|
|
|
|
|
|
pszDaysOfWeekArray[i] = HeapAlloc(GetProcessHeap(),
|
|
|
|
HEAP_ZERO_MEMORY,
|
|
|
|
nLength * sizeof(WCHAR));
|
|
|
|
if (pszDaysOfWeekArray[i] == NULL)
|
|
|
|
{
|
|
|
|
FreeDaysOfWeekArray();
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
GetLocaleInfo(LOCALE_USER_DEFAULT,
|
|
|
|
LOCALE_SABBREVDAYNAME1 + i,
|
|
|
|
pszDaysOfWeekArray[i],
|
|
|
|
nLength);
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2017-03-19 00:11:31 +00:00
|
|
|
|
|
|
|
static
|
|
|
|
BOOL
|
|
|
|
ParseTime(
|
|
|
|
PWSTR pszTime,
|
|
|
|
PULONG pulJobHour,
|
|
|
|
PULONG pulJobMinute)
|
|
|
|
{
|
2017-04-14 15:54:08 +00:00
|
|
|
WCHAR szHour[3], szMinute[3], szAmPm[5];
|
2017-03-19 00:11:31 +00:00
|
|
|
PWSTR startPtr, endPtr;
|
|
|
|
ULONG ulHour = 0, ulMinute = 0;
|
2017-04-14 15:54:08 +00:00
|
|
|
INT nLength;
|
|
|
|
|
|
|
|
if (pszTime == NULL)
|
|
|
|
return FALSE;
|
2017-03-19 00:11:31 +00:00
|
|
|
|
|
|
|
startPtr = pszTime;
|
2017-04-14 15:54:08 +00:00
|
|
|
|
|
|
|
/* Extract the hour string */
|
|
|
|
nLength = 0;
|
|
|
|
while (*startPtr != L'\0' && iswdigit(*startPtr))
|
|
|
|
{
|
|
|
|
if (nLength >= 2)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
szHour[nLength] = *startPtr;
|
|
|
|
nLength++;
|
|
|
|
|
|
|
|
startPtr++;
|
|
|
|
}
|
|
|
|
szHour[nLength] = L'\0';
|
|
|
|
|
|
|
|
/* Check for a valid time separator */
|
|
|
|
if (*startPtr != L':')
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
/* Skip the time separator */
|
|
|
|
startPtr++;
|
|
|
|
|
|
|
|
/* Extract the minute string */
|
|
|
|
nLength = 0;
|
|
|
|
while (*startPtr != L'\0' && iswdigit(*startPtr))
|
|
|
|
{
|
|
|
|
if (nLength >= 2)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
szMinute[nLength] = *startPtr;
|
|
|
|
nLength++;
|
|
|
|
|
|
|
|
startPtr++;
|
|
|
|
}
|
|
|
|
szMinute[nLength] = L'\0';
|
|
|
|
|
|
|
|
/* Extract the optional AM/PM indicator string */
|
|
|
|
nLength = 0;
|
|
|
|
while (*startPtr != L'\0')
|
2017-03-19 00:11:31 +00:00
|
|
|
{
|
2017-04-14 15:54:08 +00:00
|
|
|
if (nLength >= 4)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
if (!iswspace(*startPtr))
|
2017-03-19 00:11:31 +00:00
|
|
|
{
|
2017-04-14 15:54:08 +00:00
|
|
|
szAmPm[nLength] = *startPtr;
|
|
|
|
nLength++;
|
|
|
|
}
|
2017-03-19 00:11:31 +00:00
|
|
|
|
2017-04-14 15:54:08 +00:00
|
|
|
startPtr++;
|
|
|
|
}
|
|
|
|
szAmPm[nLength] = L'\0';
|
|
|
|
|
|
|
|
/* Convert the hour string */
|
|
|
|
ulHour = wcstoul(szHour, &endPtr, 10);
|
|
|
|
if (ulHour == 0 && *endPtr != UNICODE_NULL)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
/* Convert the minute string */
|
|
|
|
ulMinute = wcstoul(szMinute, &endPtr, 10);
|
|
|
|
if (ulMinute == 0 && *endPtr != UNICODE_NULL)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
/* Check for valid AM/PM indicator */
|
|
|
|
if (wcslen(szAmPm) > 0 &&
|
|
|
|
_wcsicmp(szAmPm, L"a") != 0 &&
|
|
|
|
_wcsicmp(szAmPm, L"am") != 0 &&
|
|
|
|
_wcsicmp(szAmPm, L"p") != 0 &&
|
|
|
|
_wcsicmp(szAmPm, L"pm") != 0)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
/* Check for the valid minute range [0-59] */
|
|
|
|
if (ulMinute > 59)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
if (wcslen(szAmPm) > 0)
|
|
|
|
{
|
|
|
|
/* 12 hour time format */
|
2017-03-19 00:11:31 +00:00
|
|
|
|
2017-04-14 15:54:08 +00:00
|
|
|
/* Check for the valid hour range [1-12] */
|
|
|
|
if (ulHour == 0 || ulHour > 12)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
/* Convert 12 hour format to 24 hour format */
|
|
|
|
if (_wcsicmp(szAmPm, L"a") == 0 ||
|
|
|
|
_wcsicmp(szAmPm, L"am") == 0)
|
|
|
|
{
|
|
|
|
if (ulHour == 12)
|
|
|
|
ulHour = 0;
|
2017-03-19 00:11:31 +00:00
|
|
|
}
|
2017-04-14 15:54:08 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
if (ulHour >= 1 && ulHour <= 11)
|
|
|
|
ulHour += 12;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* 24 hour time format */
|
|
|
|
|
|
|
|
/* Check for the valid hour range [0-23] */
|
|
|
|
if (ulHour > 23)
|
|
|
|
return FALSE;
|
2017-03-19 00:11:31 +00:00
|
|
|
}
|
|
|
|
|
2017-04-14 15:54:08 +00:00
|
|
|
if (pulJobHour != NULL)
|
|
|
|
*pulJobHour = ulHour;
|
|
|
|
|
|
|
|
if (pulJobMinute != NULL)
|
|
|
|
*pulJobMinute = ulMinute;
|
|
|
|
|
|
|
|
return TRUE;
|
2017-03-19 00:11:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static
|
|
|
|
BOOL
|
|
|
|
ParseId(
|
|
|
|
PWSTR pszId,
|
|
|
|
PULONG pulId)
|
|
|
|
{
|
|
|
|
PWSTR startPtr, endPtr;
|
|
|
|
ULONG ulId = 0;
|
|
|
|
BOOL bResult = FALSE;
|
|
|
|
|
|
|
|
startPtr = pszId;
|
|
|
|
endPtr = NULL;
|
|
|
|
ulId = wcstoul(startPtr, &endPtr, 10);
|
|
|
|
if (endPtr != NULL && *endPtr == UNICODE_NULL)
|
|
|
|
{
|
|
|
|
bResult = TRUE;
|
|
|
|
|
|
|
|
if (pulId != NULL)
|
|
|
|
*pulId = ulId;
|
|
|
|
}
|
|
|
|
|
|
|
|
return bResult;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-03-19 17:15:59 +00:00
|
|
|
static
|
|
|
|
BOOL
|
|
|
|
ParseDaysOfMonth(
|
|
|
|
PWSTR pszBuffer,
|
|
|
|
PULONG pulDaysOfMonth)
|
|
|
|
{
|
|
|
|
PWSTR startPtr, endPtr;
|
|
|
|
ULONG ulValue;
|
|
|
|
|
|
|
|
if (wcslen(pszBuffer) == 0)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
startPtr = pszBuffer;
|
|
|
|
endPtr = NULL;
|
|
|
|
for (;;)
|
|
|
|
{
|
|
|
|
ulValue = wcstoul(startPtr, &endPtr, 10);
|
2017-03-20 22:55:08 +00:00
|
|
|
if (ulValue == 0)
|
|
|
|
return FALSE;
|
2017-03-19 17:15:59 +00:00
|
|
|
|
|
|
|
if (ulValue > 0 && ulValue <= 31)
|
|
|
|
*pulDaysOfMonth |= (1 << (ulValue - 1));
|
|
|
|
|
|
|
|
if (endPtr != NULL && *endPtr == UNICODE_NULL)
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
startPtr = endPtr + 1;
|
|
|
|
endPtr = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static
|
|
|
|
BOOL
|
|
|
|
ParseDaysOfWeek(
|
|
|
|
PWSTR pszBuffer,
|
|
|
|
PUCHAR pucDaysOfWeek)
|
|
|
|
{
|
|
|
|
PWSTR startPtr, endPtr;
|
2017-03-20 22:55:08 +00:00
|
|
|
INT nLength, i;
|
2017-03-19 17:15:59 +00:00
|
|
|
|
|
|
|
if (wcslen(pszBuffer) == 0)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
startPtr = pszBuffer;
|
|
|
|
endPtr = NULL;
|
|
|
|
for (;;)
|
|
|
|
{
|
|
|
|
endPtr = wcschr(startPtr, L',');
|
2017-03-20 22:55:08 +00:00
|
|
|
if (endPtr == NULL)
|
|
|
|
nLength = wcslen(startPtr);
|
|
|
|
else
|
|
|
|
nLength = (INT)((ULONG_PTR)endPtr - (ULONG_PTR)startPtr) / sizeof(WCHAR);
|
2017-03-19 17:15:59 +00:00
|
|
|
|
2017-03-20 22:55:08 +00:00
|
|
|
for (i = 0; i < 7; i++)
|
|
|
|
{
|
|
|
|
if (nLength == wcslen(pszDaysOfWeekArray[i]) &&
|
|
|
|
_wcsnicmp(startPtr, pszDaysOfWeekArray[i], nLength) == 0)
|
|
|
|
{
|
|
|
|
*pucDaysOfWeek |= (1 << i);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2017-03-19 17:15:59 +00:00
|
|
|
|
|
|
|
if (endPtr == NULL)
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
startPtr = endPtr + 1;
|
|
|
|
endPtr = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-03-19 00:11:31 +00:00
|
|
|
static
|
|
|
|
VOID
|
|
|
|
PrintErrorMessage(
|
|
|
|
DWORD dwError)
|
|
|
|
{
|
|
|
|
PWSTR pszBuffer = NULL;
|
|
|
|
|
|
|
|
FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
|
|
|
|
NULL,
|
|
|
|
dwError,
|
|
|
|
0,
|
|
|
|
(PWSTR)&pszBuffer,
|
|
|
|
0,
|
|
|
|
NULL);
|
|
|
|
|
2017-03-20 22:55:08 +00:00
|
|
|
ConPrintf(StdErr, L"%s\n", pszBuffer);
|
2017-03-19 00:11:31 +00:00
|
|
|
LocalFree(pszBuffer);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static
|
|
|
|
VOID
|
|
|
|
PrintHorizontalLine(VOID)
|
|
|
|
{
|
2017-03-20 22:55:08 +00:00
|
|
|
WCHAR szBuffer[80];
|
|
|
|
INT i;
|
2017-03-19 00:11:31 +00:00
|
|
|
|
2017-03-20 22:55:08 +00:00
|
|
|
for (i = 0; i < 79; i++)
|
|
|
|
szBuffer[i] = L'-';
|
|
|
|
szBuffer[79] = UNICODE_NULL;
|
2017-03-19 00:11:31 +00:00
|
|
|
|
2017-03-20 22:55:08 +00:00
|
|
|
ConPrintf(StdOut, L"%s\n", szBuffer);
|
2017-03-19 00:11:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-03-22 21:59:06 +00:00
|
|
|
static
|
|
|
|
BOOL
|
|
|
|
Confirm(VOID)
|
|
|
|
{
|
|
|
|
HINSTANCE hInstance;
|
|
|
|
WCHAR szYesBuffer[8];
|
|
|
|
WCHAR szNoBuffer[8];
|
|
|
|
WCHAR szInput[80];
|
|
|
|
DWORD dwOldMode;
|
|
|
|
DWORD dwRead = 0;
|
|
|
|
BOOL ret = FALSE;
|
|
|
|
HANDLE hFile;
|
|
|
|
|
|
|
|
hInstance = GetModuleHandleW(NULL);
|
|
|
|
LoadStringW(hInstance, IDS_CONFIRM_YES, szYesBuffer, _countof(szYesBuffer));
|
|
|
|
LoadStringW(hInstance, IDS_CONFIRM_NO, szNoBuffer, _countof(szNoBuffer));
|
|
|
|
|
|
|
|
ZeroMemory(szInput, sizeof(szInput));
|
|
|
|
|
|
|
|
hFile = GetStdHandle(STD_INPUT_HANDLE);
|
|
|
|
GetConsoleMode(hFile, &dwOldMode);
|
|
|
|
|
|
|
|
SetConsoleMode(hFile, ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT);
|
|
|
|
|
|
|
|
for (;;)
|
|
|
|
{
|
|
|
|
ConResPrintf(StdOut, IDS_CONFIRM_QUESTION);
|
|
|
|
|
|
|
|
ReadConsoleW(hFile, szInput, _countof(szInput), &dwRead, NULL);
|
|
|
|
|
|
|
|
szInput[0] = towupper(szInput[0]);
|
|
|
|
if (szInput[0] == szYesBuffer[0])
|
|
|
|
{
|
|
|
|
ret = TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
else if (szInput[0] == 13 || szInput[0] == szNoBuffer[0])
|
|
|
|
{
|
|
|
|
ret = FALSE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
ConResPrintf(StdOut, IDS_CONFIRM_INVALID);
|
|
|
|
}
|
|
|
|
|
|
|
|
SetConsoleMode(hFile, dwOldMode);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-03-19 00:11:31 +00:00
|
|
|
static
|
|
|
|
DWORD_PTR
|
|
|
|
GetTimeAsJobTime(VOID)
|
|
|
|
{
|
|
|
|
SYSTEMTIME Time;
|
|
|
|
DWORD_PTR JobTime;
|
|
|
|
|
|
|
|
GetLocalTime(&Time);
|
|
|
|
|
|
|
|
JobTime = (DWORD_PTR)Time.wHour * 3600000 +
|
|
|
|
(DWORD_PTR)Time.wMinute * 60000;
|
|
|
|
|
|
|
|
return JobTime;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-03-19 17:15:59 +00:00
|
|
|
static
|
|
|
|
ULONG
|
|
|
|
GetCurrentDayOfMonth(VOID)
|
|
|
|
{
|
|
|
|
SYSTEMTIME Time;
|
|
|
|
|
|
|
|
GetLocalTime(&Time);
|
|
|
|
|
|
|
|
return 1UL << (Time.wDay - 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-03-19 00:11:31 +00:00
|
|
|
static
|
|
|
|
VOID
|
|
|
|
JobTimeToTimeString(
|
|
|
|
PWSTR pszBuffer,
|
|
|
|
INT cchBuffer,
|
|
|
|
WORD wHour,
|
|
|
|
WORD wMinute)
|
|
|
|
{
|
|
|
|
SYSTEMTIME Time = {0, 0, 0, 0, 0, 0, 0, 0};
|
|
|
|
|
|
|
|
Time.wHour = wHour;
|
|
|
|
Time.wMinute = wMinute;
|
|
|
|
|
|
|
|
GetTimeFormat(LOCALE_USER_DEFAULT,
|
|
|
|
TIME_NOSECONDS,
|
|
|
|
&Time,
|
|
|
|
NULL,
|
|
|
|
pszBuffer,
|
|
|
|
cchBuffer);
|
|
|
|
}
|
|
|
|
|
2017-03-19 17:15:59 +00:00
|
|
|
|
2017-03-19 00:11:31 +00:00
|
|
|
static
|
|
|
|
INT
|
|
|
|
PrintJobDetails(
|
|
|
|
PWSTR pszComputerName,
|
|
|
|
ULONG ulJobId)
|
|
|
|
{
|
2017-03-19 17:15:59 +00:00
|
|
|
PAT_INFO pBuffer = NULL;
|
2017-03-19 00:11:31 +00:00
|
|
|
DWORD_PTR CurrentTime;
|
|
|
|
WCHAR szStatusBuffer[16];
|
2017-03-19 17:15:59 +00:00
|
|
|
WCHAR szScheduleBuffer[60];
|
2017-03-19 00:11:31 +00:00
|
|
|
WCHAR szTimeBuffer[16];
|
|
|
|
WCHAR szInteractiveBuffer[16];
|
2017-03-19 17:15:59 +00:00
|
|
|
WCHAR szDateBuffer[8];
|
|
|
|
INT i, nDateLength, nScheduleLength;
|
2017-03-19 00:11:31 +00:00
|
|
|
HINSTANCE hInstance;
|
|
|
|
NET_API_STATUS Status;
|
|
|
|
|
|
|
|
Status = NetScheduleJobGetInfo(pszComputerName,
|
|
|
|
ulJobId,
|
|
|
|
(PBYTE *)&pBuffer);
|
|
|
|
if (Status != NERR_Success)
|
|
|
|
{
|
|
|
|
PrintErrorMessage(Status);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2017-03-19 17:15:59 +00:00
|
|
|
hInstance = GetModuleHandle(NULL);
|
|
|
|
|
2017-03-19 00:11:31 +00:00
|
|
|
if (pBuffer->Flags & JOB_EXEC_ERROR)
|
2017-03-19 17:15:59 +00:00
|
|
|
LoadStringW(hInstance, IDS_ERROR, szStatusBuffer, _countof(szStatusBuffer));
|
2017-03-19 00:11:31 +00:00
|
|
|
else
|
2017-03-19 17:15:59 +00:00
|
|
|
LoadStringW(hInstance, IDS_OK, szStatusBuffer, _countof(szStatusBuffer));
|
2017-03-19 00:11:31 +00:00
|
|
|
|
|
|
|
if (pBuffer->DaysOfMonth != 0)
|
|
|
|
{
|
2017-03-19 17:15:59 +00:00
|
|
|
if (pBuffer->Flags & JOB_RUN_PERIODICALLY)
|
|
|
|
LoadStringW(hInstance, IDS_EVERY, szScheduleBuffer, _countof(szScheduleBuffer));
|
|
|
|
else
|
|
|
|
LoadStringW(hInstance, IDS_NEXT, szScheduleBuffer, _countof(szScheduleBuffer));
|
|
|
|
|
|
|
|
nScheduleLength = wcslen(szScheduleBuffer);
|
|
|
|
for (i = 0; i < 31; i++)
|
|
|
|
{
|
|
|
|
if (pBuffer->DaysOfMonth & (1 << i))
|
|
|
|
{
|
|
|
|
swprintf(szDateBuffer, L" %d", i + 1);
|
|
|
|
nDateLength = wcslen(szDateBuffer);
|
|
|
|
if (nScheduleLength + nDateLength <= 55)
|
|
|
|
{
|
|
|
|
wcscat(szScheduleBuffer, szDateBuffer);
|
|
|
|
nScheduleLength += nDateLength;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
wcscat(szScheduleBuffer, L"...");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-03-19 00:11:31 +00:00
|
|
|
}
|
|
|
|
else if (pBuffer->DaysOfWeek != 0)
|
|
|
|
{
|
2017-03-19 17:15:59 +00:00
|
|
|
if (pBuffer->Flags & JOB_RUN_PERIODICALLY)
|
|
|
|
LoadStringW(hInstance, IDS_EVERY, szScheduleBuffer, _countof(szScheduleBuffer));
|
|
|
|
else
|
|
|
|
LoadStringW(hInstance, IDS_NEXT, szScheduleBuffer, _countof(szScheduleBuffer));
|
|
|
|
|
|
|
|
nScheduleLength = wcslen(szScheduleBuffer);
|
|
|
|
for (i = 0; i < 7; i++)
|
|
|
|
{
|
|
|
|
if (pBuffer->DaysOfWeek & (1 << i))
|
|
|
|
{
|
2017-03-20 22:55:08 +00:00
|
|
|
swprintf(szDateBuffer, L" %s", pszDaysOfWeekArray[i]);
|
|
|
|
nDateLength = wcslen(szDateBuffer);
|
|
|
|
if (nScheduleLength + nDateLength <= 55)
|
|
|
|
{
|
|
|
|
wcscat(szScheduleBuffer, szDateBuffer);
|
|
|
|
nScheduleLength += nDateLength;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
wcscat(szScheduleBuffer, L"...");
|
|
|
|
break;
|
|
|
|
}
|
2017-03-19 17:15:59 +00:00
|
|
|
}
|
|
|
|
}
|
2017-03-19 00:11:31 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
CurrentTime = GetTimeAsJobTime();
|
|
|
|
if (CurrentTime > pBuffer->JobTime)
|
2017-03-19 17:15:59 +00:00
|
|
|
LoadStringW(hInstance, IDS_TOMORROW, szScheduleBuffer, _countof(szScheduleBuffer));
|
2017-03-19 00:11:31 +00:00
|
|
|
else
|
2017-03-19 17:15:59 +00:00
|
|
|
LoadStringW(hInstance, IDS_TODAY, szScheduleBuffer, _countof(szScheduleBuffer));
|
2017-03-19 00:11:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
JobTimeToTimeString(szTimeBuffer,
|
2017-03-19 17:15:59 +00:00
|
|
|
_countof(szTimeBuffer),
|
2017-03-19 00:11:31 +00:00
|
|
|
(WORD)(pBuffer->JobTime / 3600000),
|
|
|
|
(WORD)((pBuffer->JobTime % 3600000) / 60000));
|
|
|
|
|
|
|
|
if (pBuffer->Flags & JOB_NONINTERACTIVE)
|
2017-03-19 17:15:59 +00:00
|
|
|
LoadStringW(hInstance, IDS_NO, szInteractiveBuffer, _countof(szInteractiveBuffer));
|
2017-03-19 00:11:31 +00:00
|
|
|
else
|
2017-03-19 17:15:59 +00:00
|
|
|
LoadStringW(hInstance, IDS_YES, szInteractiveBuffer, _countof(szInteractiveBuffer));
|
2017-03-19 00:11:31 +00:00
|
|
|
|
|
|
|
ConResPrintf(StdOut, IDS_TASKID, ulJobId);
|
|
|
|
ConResPrintf(StdOut, IDS_STATUS, szStatusBuffer);
|
2017-03-19 17:15:59 +00:00
|
|
|
ConResPrintf(StdOut, IDS_SCHEDULE, szScheduleBuffer);
|
2017-03-19 00:11:31 +00:00
|
|
|
ConResPrintf(StdOut, IDS_TIME, szTimeBuffer);
|
|
|
|
ConResPrintf(StdOut, IDS_INTERACTIVE, szInteractiveBuffer);
|
|
|
|
ConResPrintf(StdOut, IDS_COMMAND, pBuffer->Command);
|
|
|
|
|
|
|
|
NetApiBufferFree(pBuffer);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static
|
|
|
|
INT
|
|
|
|
PrintAllJobs(
|
|
|
|
PWSTR pszComputerName)
|
|
|
|
{
|
|
|
|
PAT_ENUM pBuffer = NULL;
|
|
|
|
DWORD dwRead = 0, dwTotal = 0;
|
|
|
|
DWORD dwResume = 0, i;
|
|
|
|
DWORD_PTR CurrentTime;
|
|
|
|
NET_API_STATUS Status;
|
|
|
|
|
2017-03-19 17:15:59 +00:00
|
|
|
WCHAR szScheduleBuffer[32];
|
2017-03-19 00:11:31 +00:00
|
|
|
WCHAR szTimeBuffer[16];
|
2017-03-19 17:15:59 +00:00
|
|
|
WCHAR szDateBuffer[8];
|
2017-03-19 00:11:31 +00:00
|
|
|
HINSTANCE hInstance;
|
2017-03-19 17:15:59 +00:00
|
|
|
INT j, nDateLength, nScheduleLength;
|
2017-03-19 00:11:31 +00:00
|
|
|
|
|
|
|
Status = NetScheduleJobEnum(pszComputerName,
|
|
|
|
(PBYTE *)&pBuffer,
|
|
|
|
MAX_PREFERRED_LENGTH,
|
|
|
|
&dwRead,
|
|
|
|
&dwTotal,
|
|
|
|
&dwResume);
|
|
|
|
if (Status != NERR_Success)
|
|
|
|
{
|
|
|
|
PrintErrorMessage(Status);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (dwTotal == 0)
|
|
|
|
{
|
|
|
|
ConResPrintf(StdOut, IDS_NO_ENTRIES);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
ConResPrintf(StdOut, IDS_JOBS_LIST);
|
|
|
|
PrintHorizontalLine();
|
|
|
|
|
|
|
|
hInstance = GetModuleHandle(NULL);
|
|
|
|
|
|
|
|
for (i = 0; i < dwRead; i++)
|
|
|
|
{
|
|
|
|
if (pBuffer[i].DaysOfMonth != 0)
|
|
|
|
{
|
2017-03-19 17:15:59 +00:00
|
|
|
if (pBuffer[i].Flags & JOB_RUN_PERIODICALLY)
|
|
|
|
LoadStringW(hInstance, IDS_EVERY, szScheduleBuffer, _countof(szScheduleBuffer));
|
|
|
|
else
|
|
|
|
LoadStringW(hInstance, IDS_NEXT, szScheduleBuffer, _countof(szScheduleBuffer));
|
|
|
|
|
|
|
|
nScheduleLength = wcslen(szScheduleBuffer);
|
|
|
|
for (j = 0; j < 31; j++)
|
|
|
|
{
|
|
|
|
if (pBuffer[i].DaysOfMonth & (1 << j))
|
|
|
|
{
|
|
|
|
swprintf(szDateBuffer, L" %d", j + 1);
|
|
|
|
nDateLength = wcslen(szDateBuffer);
|
|
|
|
if (nScheduleLength + nDateLength <= 19)
|
|
|
|
{
|
|
|
|
wcscat(szScheduleBuffer, szDateBuffer);
|
|
|
|
nScheduleLength += nDateLength;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
wcscat(szScheduleBuffer, L"...");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-03-19 00:11:31 +00:00
|
|
|
}
|
|
|
|
else if (pBuffer[i].DaysOfWeek != 0)
|
|
|
|
{
|
2017-03-19 17:15:59 +00:00
|
|
|
if (pBuffer[i].Flags & JOB_RUN_PERIODICALLY)
|
|
|
|
LoadStringW(hInstance, IDS_EVERY, szScheduleBuffer, _countof(szScheduleBuffer));
|
|
|
|
else
|
|
|
|
LoadStringW(hInstance, IDS_NEXT, szScheduleBuffer, _countof(szScheduleBuffer));
|
|
|
|
|
|
|
|
nScheduleLength = wcslen(szScheduleBuffer);
|
|
|
|
for (j = 0; j < 7; j++)
|
|
|
|
{
|
|
|
|
if (pBuffer[i].DaysOfWeek & (1 << j))
|
|
|
|
{
|
2017-03-20 22:55:08 +00:00
|
|
|
swprintf(szDateBuffer, L" %s", pszDaysOfWeekArray[j]);
|
2017-03-19 17:15:59 +00:00
|
|
|
nDateLength = wcslen(szDateBuffer);
|
2017-03-20 22:55:08 +00:00
|
|
|
if (nScheduleLength + nDateLength <= 55)
|
2017-03-19 17:15:59 +00:00
|
|
|
{
|
|
|
|
wcscat(szScheduleBuffer, szDateBuffer);
|
|
|
|
nScheduleLength += nDateLength;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
wcscat(szScheduleBuffer, L"...");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-03-19 00:11:31 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
CurrentTime = GetTimeAsJobTime();
|
|
|
|
if (CurrentTime > pBuffer[i].JobTime)
|
2017-03-19 17:15:59 +00:00
|
|
|
LoadStringW(hInstance, IDS_TOMORROW, szScheduleBuffer, _countof(szScheduleBuffer));
|
2017-03-19 00:11:31 +00:00
|
|
|
else
|
2017-03-19 17:15:59 +00:00
|
|
|
LoadStringW(hInstance, IDS_TODAY, szScheduleBuffer, _countof(szScheduleBuffer));
|
2017-03-19 00:11:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
JobTimeToTimeString(szTimeBuffer,
|
2017-03-19 17:15:59 +00:00
|
|
|
_countof(szTimeBuffer),
|
2017-03-19 00:11:31 +00:00
|
|
|
(WORD)(pBuffer[i].JobTime / 3600000),
|
|
|
|
(WORD)((pBuffer[i].JobTime % 3600000) / 60000));
|
|
|
|
|
|
|
|
ConPrintf(StdOut,
|
2017-03-20 22:55:08 +00:00
|
|
|
L" %6lu %-21s %-11s %s\n",
|
2017-03-19 00:11:31 +00:00
|
|
|
pBuffer[i].JobId,
|
2017-03-19 17:15:59 +00:00
|
|
|
szScheduleBuffer,
|
2017-03-19 00:11:31 +00:00
|
|
|
szTimeBuffer,
|
|
|
|
pBuffer[i].Command);
|
|
|
|
}
|
|
|
|
|
|
|
|
NetApiBufferFree(pBuffer);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static
|
|
|
|
INT
|
|
|
|
AddJob(
|
|
|
|
PWSTR pszComputerName,
|
|
|
|
ULONG ulJobHour,
|
|
|
|
ULONG ulJobMinute,
|
2017-03-19 17:15:59 +00:00
|
|
|
ULONG ulDaysOfMonth,
|
|
|
|
UCHAR ucDaysOfWeek,
|
2017-03-19 00:11:31 +00:00
|
|
|
BOOL bInteractiveJob,
|
2017-03-19 17:15:59 +00:00
|
|
|
BOOL bPeriodicJob,
|
2017-03-19 00:11:31 +00:00
|
|
|
PWSTR pszCommand)
|
|
|
|
{
|
|
|
|
AT_INFO InfoBuffer;
|
|
|
|
ULONG ulJobId = 0;
|
|
|
|
NET_API_STATUS Status;
|
|
|
|
|
|
|
|
InfoBuffer.JobTime = (DWORD_PTR)ulJobHour * 3600000 +
|
|
|
|
(DWORD_PTR)ulJobMinute * 60000;
|
2017-03-19 17:15:59 +00:00
|
|
|
InfoBuffer.DaysOfMonth = ulDaysOfMonth;
|
|
|
|
InfoBuffer.DaysOfWeek = ucDaysOfWeek;
|
|
|
|
InfoBuffer.Flags = (bInteractiveJob ? 0 : JOB_NONINTERACTIVE) |
|
|
|
|
(bPeriodicJob ? JOB_RUN_PERIODICALLY : 0);
|
2017-03-19 00:11:31 +00:00
|
|
|
InfoBuffer.Command = pszCommand;
|
|
|
|
|
|
|
|
Status = NetScheduleJobAdd(pszComputerName,
|
|
|
|
(PBYTE)&InfoBuffer,
|
|
|
|
&ulJobId);
|
|
|
|
if (Status != NERR_Success)
|
|
|
|
{
|
|
|
|
PrintErrorMessage(Status);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
ConResPrintf(StdOut, IDS_NEW_JOB, ulJobId);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static
|
|
|
|
INT
|
|
|
|
DeleteJob(
|
|
|
|
PWSTR pszComputerName,
|
|
|
|
ULONG ulJobId,
|
|
|
|
BOOL bForceDelete)
|
|
|
|
{
|
|
|
|
NET_API_STATUS Status;
|
|
|
|
|
|
|
|
if (ulJobId == (ULONG)-1 && bForceDelete == FALSE)
|
|
|
|
{
|
2017-03-22 21:59:06 +00:00
|
|
|
ConResPrintf(StdOut, IDS_DELETE_ALL);
|
|
|
|
if (!Confirm())
|
|
|
|
return 0;
|
2017-03-19 00:11:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Status = NetScheduleJobDel(pszComputerName,
|
|
|
|
(ulJobId == (ULONG)-1) ? 0 : ulJobId,
|
|
|
|
(ulJobId == (ULONG)-1) ? -1 : ulJobId);
|
|
|
|
if (Status != NERR_Success)
|
|
|
|
{
|
|
|
|
PrintErrorMessage(Status);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int wmain(int argc, WCHAR **argv)
|
|
|
|
{
|
|
|
|
PWSTR pszComputerName = NULL;
|
|
|
|
PWSTR pszCommand = NULL;
|
|
|
|
ULONG ulJobId = (ULONG)-1;
|
|
|
|
ULONG ulJobHour = (ULONG)-1;
|
|
|
|
ULONG ulJobMinute = (ULONG)-1;
|
|
|
|
BOOL bDeleteJob = FALSE, bForceDelete = FALSE;
|
2017-03-19 17:15:59 +00:00
|
|
|
BOOL bInteractiveJob = FALSE, bPeriodicJob = FALSE;
|
2017-03-19 00:11:31 +00:00
|
|
|
BOOL bPrintUsage = FALSE;
|
2017-03-19 17:15:59 +00:00
|
|
|
ULONG ulDaysOfMonth = 0;
|
|
|
|
UCHAR ucDaysOfWeek = 0;
|
2017-03-19 00:11:31 +00:00
|
|
|
INT nResult = 0;
|
|
|
|
INT i, minIdx;
|
|
|
|
|
|
|
|
/* Initialize the Console Standard Streams */
|
|
|
|
ConInitStdStreams();
|
|
|
|
|
2017-03-21 20:32:54 +00:00
|
|
|
if (!InitDaysOfWeekArray())
|
|
|
|
return 1;
|
|
|
|
|
2017-03-19 00:11:31 +00:00
|
|
|
/* Parse the computer name */
|
|
|
|
i = 1;
|
|
|
|
minIdx = 1;
|
|
|
|
if (i < argc &&
|
|
|
|
argv[i][0] == L'\\' &&
|
|
|
|
argv[i][1] == L'\\')
|
|
|
|
{
|
|
|
|
pszComputerName = argv[i];
|
|
|
|
i++;
|
|
|
|
minIdx++;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Parse the time or job id */
|
|
|
|
if (i < argc && argv[i][0] != L'/')
|
|
|
|
{
|
|
|
|
if (ParseTime(argv[i], &ulJobHour, &ulJobMinute))
|
|
|
|
{
|
|
|
|
i++;
|
|
|
|
minIdx++;
|
|
|
|
}
|
|
|
|
else if (ParseId(argv[i], &ulJobId))
|
|
|
|
{
|
|
|
|
i++;
|
|
|
|
minIdx++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Parse the options */
|
|
|
|
for (; i < argc; i++)
|
|
|
|
{
|
|
|
|
if (argv[i][0] == L'/')
|
|
|
|
{
|
|
|
|
if (_wcsicmp(argv[i], L"/?") == 0)
|
|
|
|
{
|
|
|
|
bPrintUsage = TRUE;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
else if (_wcsicmp(argv[i], L"/delete") == 0)
|
|
|
|
{
|
|
|
|
bDeleteJob = TRUE;
|
|
|
|
}
|
|
|
|
else if (_wcsicmp(argv[i], L"/yes") == 0)
|
|
|
|
{
|
|
|
|
bForceDelete = TRUE;
|
|
|
|
}
|
|
|
|
else if (_wcsicmp(argv[i], L"/interactive") == 0)
|
|
|
|
{
|
|
|
|
bInteractiveJob = TRUE;
|
|
|
|
}
|
|
|
|
else if (_wcsnicmp(argv[i], L"/every:", 7) == 0)
|
|
|
|
{
|
2017-03-19 17:15:59 +00:00
|
|
|
bPeriodicJob = TRUE;
|
|
|
|
if (ParseDaysOfMonth(&(argv[i][7]), &ulDaysOfMonth) == FALSE)
|
|
|
|
{
|
|
|
|
if (ParseDaysOfWeek(&(argv[i][7]), &ucDaysOfWeek) == FALSE)
|
|
|
|
{
|
|
|
|
ulDaysOfMonth = GetCurrentDayOfMonth();
|
|
|
|
}
|
|
|
|
}
|
2017-03-19 00:11:31 +00:00
|
|
|
}
|
|
|
|
else if (_wcsnicmp(argv[i], L"/next:", 6) == 0)
|
|
|
|
{
|
2017-03-19 17:15:59 +00:00
|
|
|
bPeriodicJob = FALSE;
|
|
|
|
if (ParseDaysOfMonth(&(argv[i][6]), &ulDaysOfMonth) == FALSE)
|
|
|
|
{
|
|
|
|
if (ParseDaysOfWeek(&(argv[i][6]), &ucDaysOfWeek) == FALSE)
|
|
|
|
{
|
|
|
|
ulDaysOfMonth = GetCurrentDayOfMonth();
|
|
|
|
}
|
|
|
|
}
|
2017-03-19 00:11:31 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
bPrintUsage = TRUE;
|
|
|
|
nResult = 1;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Parse the command */
|
|
|
|
if (argc > minIdx && argv[argc - 1][0] != L'/')
|
|
|
|
{
|
|
|
|
pszCommand = argv[argc - 1];
|
|
|
|
}
|
|
|
|
|
|
|
|
if (bDeleteJob == TRUE)
|
|
|
|
{
|
|
|
|
/* Check for invalid options or arguments */
|
|
|
|
if (bInteractiveJob == TRUE ||
|
|
|
|
ulJobHour != (ULONG)-1 ||
|
|
|
|
ulJobMinute != (ULONG)-1 ||
|
2017-03-19 17:15:59 +00:00
|
|
|
ulDaysOfMonth != 0 ||
|
|
|
|
ucDaysOfWeek != 0 ||
|
2017-03-19 00:11:31 +00:00
|
|
|
pszCommand != NULL)
|
|
|
|
{
|
|
|
|
bPrintUsage = TRUE;
|
|
|
|
nResult = 1;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
2017-03-19 17:15:59 +00:00
|
|
|
nResult = DeleteJob(pszComputerName,
|
|
|
|
ulJobId,
|
|
|
|
bForceDelete);
|
2017-03-19 00:11:31 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (ulJobHour != (ULONG)-1 && ulJobMinute != (ULONG)-1)
|
|
|
|
{
|
|
|
|
/* Check for invalid options or arguments */
|
2017-03-19 17:15:59 +00:00
|
|
|
if (bForceDelete == TRUE ||
|
|
|
|
pszCommand == NULL)
|
2017-03-19 00:11:31 +00:00
|
|
|
{
|
|
|
|
bPrintUsage = TRUE;
|
|
|
|
nResult = 1;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
nResult = AddJob(pszComputerName,
|
|
|
|
ulJobHour,
|
|
|
|
ulJobMinute,
|
2017-03-19 17:15:59 +00:00
|
|
|
ulDaysOfMonth,
|
|
|
|
ucDaysOfWeek,
|
2017-03-19 00:11:31 +00:00
|
|
|
bInteractiveJob,
|
2017-03-19 17:15:59 +00:00
|
|
|
bPeriodicJob,
|
2017-03-19 00:11:31 +00:00
|
|
|
pszCommand);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Check for invalid options or arguments */
|
2017-03-19 17:15:59 +00:00
|
|
|
if (bForceDelete == TRUE ||
|
|
|
|
bInteractiveJob == TRUE ||
|
|
|
|
ulDaysOfMonth != 0 ||
|
|
|
|
ucDaysOfWeek != 0 ||
|
|
|
|
pszCommand != NULL)
|
2017-03-19 00:11:31 +00:00
|
|
|
{
|
|
|
|
bPrintUsage = TRUE;
|
|
|
|
nResult = 1;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ulJobId == (ULONG)-1)
|
|
|
|
{
|
|
|
|
nResult = PrintAllJobs(pszComputerName);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-03-19 17:15:59 +00:00
|
|
|
nResult = PrintJobDetails(pszComputerName,
|
|
|
|
ulJobId);
|
2017-03-19 00:11:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
done:
|
2017-03-21 20:32:54 +00:00
|
|
|
FreeDaysOfWeekArray();
|
|
|
|
|
2017-03-19 00:11:31 +00:00
|
|
|
if (bPrintUsage == TRUE)
|
|
|
|
ConResPuts(StdOut, IDS_USAGE);
|
|
|
|
|
|
|
|
return nResult;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* EOF */
|