[SCHEDSVC] Fix the job start time calculation for given days of week.

This commit is contained in:
Eric Kohl 2020-05-31 15:48:07 +02:00
parent cb99761bc1
commit d70c64bde0

View file

@ -449,81 +449,102 @@ done:
} }
static
WORD
DaysOfMonth(
WORD wMonth,
WORD wYear)
{
WORD wDaysArray[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
if (wMonth == 2 && wYear % 4 == 0 && wYear % 400 != 0)
return 29;
return wDaysArray[wMonth];
}
VOID VOID
CalculateNextStartTime( CalculateNextStartTime(
_In_ PJOB pJob) _In_ PJOB pJob)
{ {
SYSTEMTIME StartTime; SYSTEMTIME CurrentSystemTime, StartSystemTime;
FILETIME FileTime; FILETIME StartFileTime;
DWORD_PTR Now; WORD wDaysOffset, wTempOffset, i, wJobDayOfWeek;
DWORD_PTR CurrentTimeMs;
BOOL bDaysOffsetValid;
TRACE("CalculateNextStartTime(%p)\n", pJob); TRACE("CalculateNextStartTime(%p)\n", pJob);
TRACE("JobTime: %lu\n", pJob->JobTime);
TRACE("DaysOfWeek: 0x%x\n", pJob->DaysOfWeek);
TRACE("DaysOfMonth: 0x%x\n", pJob->DaysOfMonth);
GetLocalTime(&StartTime); GetLocalTime(&CurrentSystemTime);
Now = (DWORD_PTR)StartTime.wHour * 3600000 + CurrentTimeMs = (DWORD_PTR)CurrentSystemTime.wHour * 3600000 +
(DWORD_PTR)StartTime.wMinute * 60000; (DWORD_PTR)CurrentSystemTime.wMinute * 60000;
StartTime.wMilliseconds = 0; CopyMemory(&StartSystemTime, &CurrentSystemTime, sizeof(SYSTEMTIME));
StartTime.wSecond = 0;
StartTime.wHour = (WORD)(pJob->JobTime / 3600000);
StartTime.wMinute = (WORD)((pJob->JobTime % 3600000) / 60000);
if (pJob->DaysOfMonth != 0) StartSystemTime.wMilliseconds = 0;
StartSystemTime.wSecond = 0;
StartSystemTime.wHour = (WORD)(pJob->JobTime / 3600000);
StartSystemTime.wMinute = (WORD)((pJob->JobTime % 3600000) / 60000);
bDaysOffsetValid = FALSE;
wDaysOffset = 0;
if ((pJob->DaysOfWeek == 0) && (pJob->DaysOfMonth == 0))
{ {
FIXME("Support DaysOfMonth!\n"); if (CurrentTimeMs >= pJob->JobTime)
} {
else if (pJob->DaysOfWeek != 0) TRACE("Tomorrow!\n");
{ wDaysOffset = 1;
FIXME("Support DaysOfWeek!\n"); }
bDaysOffsetValid = TRUE;
} }
else else
{ {
/* Start the job tomorrow */ if (pJob->DaysOfWeek != 0)
if (Now > pJob->JobTime)
{ {
if (StartTime.wDay + 1 > DaysOfMonth(StartTime.wMonth, StartTime.wYear)) TRACE("DaysOfWeek!\n");
for (i = 0; i < 7; i++)
{ {
if (StartTime.wMonth == 12) if (pJob->DaysOfWeek & (1 << i))
{ {
StartTime.wDay = 1; /* Adjust the ranges */
StartTime.wMonth = 1; wJobDayOfWeek = (i + 1) % 7;
StartTime.wYear++; TRACE("wJobDayOfWeek: %hu\n", wJobDayOfWeek);
} TRACE("CurrentSystemTime.wDayOfWeek: %hu\n", CurrentSystemTime.wDayOfWeek);
else
{ /* Calculate the days offset */
StartTime.wDay = 1; if ((CurrentSystemTime.wDayOfWeek > wJobDayOfWeek ) ||
StartTime.wMonth++; ((CurrentSystemTime.wDayOfWeek == wJobDayOfWeek) && (CurrentTimeMs >= pJob->JobTime)))
{
wTempOffset = 7 - CurrentSystemTime.wDayOfWeek + wJobDayOfWeek;
TRACE("wTempOffset: %hu\n", wTempOffset);
}
else
{
wTempOffset = wJobDayOfWeek - CurrentSystemTime.wDayOfWeek;
TRACE("wTempOffset: %hu\n", wTempOffset);
}
/* Use the smallest offset */
if (bDaysOffsetValid == FALSE)
{
wDaysOffset = wTempOffset;
bDaysOffsetValid = TRUE;
}
else
{
if (wTempOffset < wDaysOffset)
wDaysOffset = wTempOffset;
}
} }
} }
else }
{
StartTime.wDay++; if (pJob->DaysOfMonth != 0)
} {
FIXME("Support DaysOfMonth!\n");
} }
} }
TRACE("Next start: %02hu:%02hu %02hu.%02hu.%hu\n", StartTime.wHour, TRACE("wDaysOffset: %hu\n", wDaysOffset);
StartTime.wMinute, StartTime.wDay, StartTime.wMonth, StartTime.wYear);
SystemTimeToFileTime(&StartTime, &FileTime); SystemTimeToFileTime(&StartSystemTime, &StartFileTime);
pJob->StartTime.u.LowPart = FileTime.dwLowDateTime; pJob->StartTime.u.LowPart = StartFileTime.dwLowDateTime;
pJob->StartTime.u.HighPart = FileTime.dwHighDateTime; pJob->StartTime.u.HighPart = StartFileTime.dwHighDateTime;
if (bDaysOffsetValid && wDaysOffset != 0)
{
pJob->StartTime.QuadPart += ((ULONGLONG)wDaysOffset * 24 * 60 * 60 * 10000);
}
} }