ReactOS  0.4.15-dev-1200-gc3b3fcd
job.c File Reference
#include "precomp.h"
Include dependency graph for job.c:

Go to the source code of this file.

Classes

struct  _SCHEDULE
 

Typedefs

typedef struct _SCHEDULE SCHEDULE
 
typedef struct _SCHEDULE PSCHEDULE
 

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (schedsvc)
 
DWORD GetNextJobTimeout (VOID)
 
static VOID ReScheduleJob (PJOB pJob)
 
VOID RunNextJob (VOID)
 
static VOID GetJobName (HKEY hJobsKey, PWSTR pszJobName)
 
LONG SaveJob (_In_ PJOB pJob)
 
LONG DeleteJob (_In_ PJOB pJob)
 
LONG LoadJobs (VOID)
 
static WORD DaysOfMonth (WORD wMonth, WORD wYear)
 
VOID CalculateNextStartTime (_In_ PJOB pJob)
 
VOID InsertJobIntoStartList (_In_ PLIST_ENTRY StartListHead, _In_ PJOB pJob)
 
VOID DumpStartList (_In_ PLIST_ENTRY StartListHead)
 

Variables

DWORD dwNextJobId = 0
 
DWORD dwJobCount = 0
 
LIST_ENTRY JobListHead
 
RTL_RESOURCE JobListLock
 
LIST_ENTRY StartListHead
 
RTL_RESOURCE StartListLock
 
static WORD wDaysArray [13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
 

Typedef Documentation

◆ PSCHEDULE

◆ SCHEDULE

Function Documentation

◆ CalculateNextStartTime()

VOID CalculateNextStartTime ( _In_ PJOB  pJob)

Definition at line 468 of file job.c.

470 {
471  SYSTEMTIME CurrentSystemTime, StartSystemTime;
472  FILETIME StartFileTime;
473  WORD wDaysOffset, wTempOffset, i, wJobDayOfWeek, wJobDayOfMonth;
474  DWORD_PTR CurrentTimeMs;
475  BOOL bDaysOffsetValid;
476 
477  TRACE("CalculateNextStartTime(%p)\n", pJob);
478  TRACE("JobTime: %lu\n", pJob->JobTime);
479  TRACE("DaysOfWeek: 0x%x\n", pJob->DaysOfWeek);
480  TRACE("DaysOfMonth: 0x%x\n", pJob->DaysOfMonth);
481 
482  GetLocalTime(&CurrentSystemTime);
483 
484  CurrentTimeMs = (DWORD_PTR)CurrentSystemTime.wHour * 3600000 +
485  (DWORD_PTR)CurrentSystemTime.wMinute * 60000;
486 
487  bDaysOffsetValid = FALSE;
488  wDaysOffset = 0;
489  if ((pJob->DaysOfWeek == 0) && (pJob->DaysOfMonth == 0))
490  {
491  if (CurrentTimeMs >= pJob->JobTime)
492  {
493  TRACE("Tomorrow!\n");
494  wDaysOffset = 1;
495  }
496 
497  bDaysOffsetValid = TRUE;
498  }
499  else
500  {
501  if (pJob->DaysOfWeek != 0)
502  {
503  TRACE("DaysOfWeek!\n");
504  for (i = 0; i < 7; i++)
505  {
506  if (pJob->DaysOfWeek & (1 << i))
507  {
508  /* Adjust the range */
509  wJobDayOfWeek = (i + 1) % 7;
510  TRACE("wJobDayOfWeek: %hu\n", wJobDayOfWeek);
511  TRACE("CurrentSystemTime.wDayOfWeek: %hu\n", CurrentSystemTime.wDayOfWeek);
512 
513  /* Calculate the days offset */
514  if ((CurrentSystemTime.wDayOfWeek > wJobDayOfWeek ) ||
515  ((CurrentSystemTime.wDayOfWeek == wJobDayOfWeek) && (CurrentTimeMs >= pJob->JobTime)))
516  {
517  wTempOffset = 7 - CurrentSystemTime.wDayOfWeek + wJobDayOfWeek;
518  TRACE("wTempOffset: %hu\n", wTempOffset);
519  }
520  else
521  {
522  wTempOffset = wJobDayOfWeek - CurrentSystemTime.wDayOfWeek;
523  TRACE("wTempOffset: %hu\n", wTempOffset);
524  }
525 
526  /* Use the smallest offset */
527  if (bDaysOffsetValid == FALSE)
528  {
529  wDaysOffset = wTempOffset;
530  bDaysOffsetValid = TRUE;
531  }
532  else
533  {
534  if (wTempOffset < wDaysOffset)
535  wDaysOffset = wTempOffset;
536  }
537  }
538  }
539  }
540 
541  if (pJob->DaysOfMonth != 0)
542  {
543  FIXME("Support DaysOfMonth!\n");
544  for (i = 0; i < 31; i++)
545  {
546  if (pJob->DaysOfMonth & (1 << i))
547  {
548  /* Adjust the range */
549  wJobDayOfMonth = i + 1;
550  FIXME("wJobDayOfMonth: %hu\n", wJobDayOfMonth);
551  FIXME("CurrentSystemTime.wDay: %hu\n", CurrentSystemTime.wDay);
552 
553  if ((CurrentSystemTime.wDay > wJobDayOfMonth) ||
554  ((CurrentSystemTime.wDay == wJobDayOfMonth) && (CurrentTimeMs >= pJob->JobTime)))
555  {
556  wTempOffset = DaysOfMonth(CurrentSystemTime.wMonth, CurrentSystemTime.wYear) -
557  CurrentSystemTime.wDay + wJobDayOfMonth;
558  FIXME("wTempOffset: %hu\n", wTempOffset);
559  }
560  else
561  {
562  wTempOffset = wJobDayOfMonth - CurrentSystemTime.wDay;
563  FIXME("wTempOffset: %hu\n", wTempOffset);
564  }
565 
566  /* Use the smallest offset */
567  if (bDaysOffsetValid == FALSE)
568  {
569  wDaysOffset = wTempOffset;
570  bDaysOffsetValid = TRUE;
571  }
572  else
573  {
574  if (wTempOffset < wDaysOffset)
575  wDaysOffset = wTempOffset;
576  }
577  }
578  }
579  }
580  }
581 
582  TRACE("wDaysOffset: %hu\n", wDaysOffset);
583 
584  CopyMemory(&StartSystemTime, &CurrentSystemTime, sizeof(SYSTEMTIME));
585 
586  StartSystemTime.wMilliseconds = 0;
587  StartSystemTime.wSecond = 0;
588  StartSystemTime.wHour = (WORD)(pJob->JobTime / 3600000);
589  StartSystemTime.wMinute = (WORD)((pJob->JobTime % 3600000) / 60000);
590 
591  SystemTimeToFileTime(&StartSystemTime, &StartFileTime);
592 
593  pJob->StartTime.u.LowPart = StartFileTime.dwLowDateTime;
594  pJob->StartTime.u.HighPart = StartFileTime.dwHighDateTime;
595  if (bDaysOffsetValid && wDaysOffset != 0)
596  {
597  pJob->StartTime.QuadPart += ((ULONGLONG)wDaysOffset * 24 * 60 * 60 * 10000);
598  }
599 }
#define DWORD_PTR
Definition: treelist.c:76
WORD wMonth
Definition: winbase.h:884
#define TRUE
Definition: types.h:120
WORD wDayOfWeek
Definition: winbase.h:885
DWORD dwHighDateTime
Definition: mapidefs.h:66
WORD wYear
Definition: winbase.h:883
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
#define FIXME(fmt,...)
Definition: debug.h:111
WORD wMinute
Definition: winbase.h:888
VOID WINAPI GetLocalTime(OUT LPSYSTEMTIME lpSystemTime)
Definition: time.c:286
#define TRACE(s)
Definition: solgame.cpp:4
uint64_t ULONGLONG
Definition: typedefs.h:67
#define CopyMemory
Definition: winbase.h:1646
unsigned short WORD
Definition: ntddk_ex.h:93
WORD wSecond
Definition: winbase.h:889
WORD wMilliseconds
Definition: winbase.h:890
uint32_t DWORD_PTR
Definition: typedefs.h:65
WORD wDay
Definition: winbase.h:886
BOOL WINAPI SystemTimeToFileTime(IN CONST SYSTEMTIME *lpSystemTime, OUT LPFILETIME lpFileTime)
Definition: time.c:158
WORD wHour
Definition: winbase.h:887
static WORD DaysOfMonth(WORD wMonth, WORD wYear)
Definition: job.c:456
DWORD dwLowDateTime
Definition: mapidefs.h:65

Referenced by LoadJobs(), NetrJobAdd(), and ReScheduleJob().

◆ DaysOfMonth()

static WORD DaysOfMonth ( WORD  wMonth,
WORD  wYear 
)
static

Definition at line 456 of file job.c.

459 {
460  if (wMonth == 2 && wYear % 4 == 0 && wYear % 400 != 0)
461  return 29;
462 
463  return wDaysArray[wMonth];
464 }
static WORD wDaysArray[13]
Definition: job.c:35

Referenced by CalculateNextStartTime(), and PrintAllJobs().

◆ DeleteJob()

LONG DeleteJob ( _In_ PJOB  pJob)

Definition at line 283 of file job.c.

285 {
286  HKEY hJobsKey = NULL;
287  LONG lError;
288 
289  TRACE("DeleteJob()\n");
290 
292  L"System\\CurrentControlSet\\Services\\Schedule\\Jobs",
293  0,
294  NULL,
296  KEY_WRITE,
297  NULL,
298  &hJobsKey,
299  NULL);
300  if (lError != ERROR_SUCCESS)
301  goto done;
302 
303  lError = RegDeleteKey(hJobsKey,
304  pJob->Name);
305  if (lError != ERROR_SUCCESS)
306  goto done;
307 
308 done:
309  if (hJobsKey != NULL)
310  RegCloseKey(hJobsKey);
311 
312  return lError;
313 }
#define ERROR_SUCCESS
Definition: deptool.c:10
LONG WINAPI RegCreateKeyExW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey, _In_ DWORD Reserved, _In_opt_ LPWSTR lpClass, _In_ DWORD dwOptions, _In_ REGSAM samDesired, _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes, _Out_ PHKEY phkResult, _Out_opt_ LPDWORD lpdwDisposition)
Definition: reg.c:1091
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
long LONG
Definition: pedump.c:60
smooth NULL
Definition: ftsmooth.c:416
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
#define KEY_WRITE
Definition: nt_native.h:1031
#define TRACE(s)
Definition: solgame.cpp:4
static const WCHAR L[]
Definition: oid.c:1250
#define RegDeleteKey
Definition: winreg.h:502
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12

Referenced by ReScheduleJob().

◆ DumpStartList()

VOID DumpStartList ( _In_ PLIST_ENTRY  StartListHead)

Definition at line 654 of file job.c.

656 {
657  PLIST_ENTRY CurrentEntry;
658  PJOB CurrentJob;
659 
660  CurrentEntry = StartListHead->Flink;
661  while (CurrentEntry != StartListHead)
662  {
663  CurrentJob = CONTAINING_RECORD(CurrentEntry, JOB, StartEntry);
664 
665  TRACE("%3lu: %016I64x\n", CurrentJob->JobId, CurrentJob->StartTime.QuadPart);
666 
667  CurrentEntry = CurrentEntry->Flink;
668  }
669 }
DWORD JobId
Definition: precomp.h:39
ULARGE_INTEGER StartTime
Definition: precomp.h:36
LIST_ENTRY StartListHead
Definition: job.c:32
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define TRACE(s)
Definition: solgame.cpp:4
Definition: typedefs.h:119
Definition: precomp.h:31

Referenced by LoadJobs(), NetrJobAdd(), NetrJobDel(), and ReScheduleJob().

◆ GetJobName()

static VOID GetJobName ( HKEY  hJobsKey,
PWSTR  pszJobName 
)
static

Definition at line 178 of file job.c.

181 {
182  WCHAR szNameBuffer[JOB_NAME_LENGTH];
183  FILETIME SystemTime;
184  ULONG ulSeed, ulValue;
185  HKEY hKey;
186  LONG lError;
187 
188  GetSystemTimeAsFileTime(&SystemTime);
189  ulSeed = SystemTime.dwLowDateTime;
190  for (;;)
191  {
192  ulValue = RtlRandomEx(&ulSeed);
193  swprintf(szNameBuffer, L"%08lx", ulValue);
194 
195  hKey = NULL;
196  lError = RegOpenKeyEx(hJobsKey,
197  szNameBuffer,
198  0,
199  KEY_READ,
200  &hKey);
201  if (lError != ERROR_SUCCESS)
202  {
203  wcscpy(pszJobName, szNameBuffer);
204  return;
205  }
206 
207  RegCloseKey(hKey);
208  }
209 }
VOID WINAPI GetSystemTimeAsFileTime(OUT PFILETIME lpFileTime)
Definition: time.c:128
#define ERROR_SUCCESS
Definition: deptool.c:10
#define KEY_READ
Definition: nt_native.h:1023
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
long LONG
Definition: pedump.c:60
smooth NULL
Definition: ftsmooth.c:416
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define swprintf(buf, format,...)
Definition: sprintf.c:56
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
static const WCHAR L[]
Definition: oid.c:1250
NTSYSAPI ULONG NTAPI RtlRandomEx(PULONG Seed)
#define RegOpenKeyEx
Definition: winreg.h:520
#define JOB_NAME_LENGTH
Definition: precomp.h:23
unsigned int ULONG
Definition: retypes.h:1
DWORD dwLowDateTime
Definition: mapidefs.h:65

Referenced by SaveJob().

◆ GetNextJobTimeout()

DWORD GetNextJobTimeout ( VOID  )

Definition at line 41 of file job.c.

42 {
43  FILETIME FileTime;
44  SYSTEMTIME SystemTime;
45  ULARGE_INTEGER CurrentTime, Timeout;
46  PJOB pNextJob;
47 
49  {
50  TRACE("No job in list! Wait until next update.\n");
51  return INFINITE;
52  }
53 
54  pNextJob = CONTAINING_RECORD((&StartListHead)->Flink, JOB, StartEntry);
55 
56  FileTime.dwLowDateTime = pNextJob->StartTime.u.LowPart;
57  FileTime.dwHighDateTime = pNextJob->StartTime.u.HighPart;
58  FileTimeToSystemTime(&FileTime, &SystemTime);
59 
60  TRACE("Start next job (%lu) at %02hu:%02hu %02hu.%02hu.%hu\n",
61  pNextJob->JobId, SystemTime.wHour, SystemTime.wMinute,
62  SystemTime.wDay, SystemTime.wMonth, SystemTime.wYear);
63 
64  GetLocalTime(&SystemTime);
65  SystemTimeToFileTime(&SystemTime, &FileTime);
66 
67  CurrentTime.u.LowPart = FileTime.dwLowDateTime;
68  CurrentTime.u.HighPart = FileTime.dwHighDateTime;
69 
70  if (CurrentTime.QuadPart >= pNextJob->StartTime.QuadPart)
71  {
72  TRACE("Next event has already gone by!\n");
73  return 0;
74  }
75 
76  Timeout.QuadPart = (pNextJob->StartTime.QuadPart - CurrentTime.QuadPart) / 10000;
77  if (Timeout.u.HighPart != 0)
78  {
79  TRACE("Event happens too far in the future!\n");
80  return INFINITE;
81  }
82 
83  TRACE("Timeout: %lu\n", Timeout.u.LowPart);
84  return Timeout.u.LowPart;
85 }
DWORD JobId
Definition: precomp.h:39
ULARGE_INTEGER StartTime
Definition: precomp.h:36
WORD wMonth
Definition: winbase.h:884
LIST_ENTRY StartListHead
Definition: job.c:32
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
struct _ULARGE_INTEGER::@3873 u
DWORD dwHighDateTime
Definition: mapidefs.h:66
WORD wYear
Definition: winbase.h:883
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
WORD wMinute
Definition: winbase.h:888
VOID WINAPI GetLocalTime(OUT LPSYSTEMTIME lpSystemTime)
Definition: time.c:286
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
#define TRACE(s)
Definition: solgame.cpp:4
BOOL WINAPI FileTimeToSystemTime(IN CONST FILETIME *lpFileTime, OUT LPSYSTEMTIME lpSystemTime)
Definition: time.c:188
WORD wDay
Definition: winbase.h:886
BOOL WINAPI SystemTimeToFileTime(IN CONST SYSTEMTIME *lpSystemTime, OUT LPFILETIME lpFileTime)
Definition: time.c:158
static ULONG Timeout
Definition: ping.c:61
WORD wHour
Definition: winbase.h:887
#define INFINITE
Definition: serial.h:102
Definition: precomp.h:31
DWORD dwLowDateTime
Definition: mapidefs.h:65

Referenced by SchedServiceMain().

◆ InsertJobIntoStartList()

VOID InsertJobIntoStartList ( _In_ PLIST_ENTRY  StartListHead,
_In_ PJOB  pJob 
)

Definition at line 603 of file job.c.

606 {
607  PLIST_ENTRY CurrentEntry, PreviousEntry;
608  PJOB CurrentJob;
609 
611  {
612  InsertHeadList(StartListHead, &pJob->StartEntry);
613  return;
614  }
615 
616  CurrentEntry = StartListHead->Flink;
617  while (CurrentEntry != StartListHead)
618  {
619  CurrentJob = CONTAINING_RECORD(CurrentEntry, JOB, StartEntry);
620 
621  if ((CurrentEntry == StartListHead->Flink) &&
622  (pJob->StartTime.QuadPart < CurrentJob->StartTime.QuadPart))
623  {
624  /* Insert before the first entry */
625  InsertHeadList(StartListHead, &pJob->StartEntry);
626  return;
627  }
628 
629  if (pJob->StartTime.QuadPart < CurrentJob->StartTime.QuadPart)
630  {
631  /* Insert between the previous and the current entry */
632  PreviousEntry = CurrentEntry->Blink;
633  pJob->StartEntry.Blink = PreviousEntry;
634  pJob->StartEntry.Flink = CurrentEntry;
635  PreviousEntry->Flink = &pJob->StartEntry;
636  CurrentEntry->Blink = &pJob->StartEntry;
637  return;
638  }
639 
640  if ((CurrentEntry->Flink == StartListHead) &&
641  (pJob->StartTime.QuadPart >= CurrentJob->StartTime.QuadPart))
642  {
643  /* Insert after the last entry */
644  InsertTailList(StartListHead, &pJob->StartEntry);
645  return;
646  }
647 
648  CurrentEntry = CurrentEntry->Flink;
649  }
650 }
ULARGE_INTEGER StartTime
Definition: precomp.h:36
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PLIST_ENTRY Entry)
Definition: rtlfuncs.h:201
#define InsertTailList(ListHead, Entry)
LIST_ENTRY StartListHead
Definition: job.c:32
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
Definition: typedefs.h:119
Definition: precomp.h:31

Referenced by LoadJobs(), NetrJobAdd(), and ReScheduleJob().

◆ LoadJobs()

LONG LoadJobs ( VOID  )

Definition at line 317 of file job.c.

318 {
319  SCHEDULE Schedule;
320  WCHAR szNameBuffer[JOB_NAME_LENGTH];
321  DWORD dwNameLength, dwIndex, dwSize;
322  HKEY hJobsKey = NULL, hJobKey = NULL;
323  PJOB pJob = NULL;
324  LONG lError;
325 
326  TRACE("LoadJobs()\n");
327 
329  L"System\\CurrentControlSet\\Services\\Schedule\\Jobs",
330  0,
331  NULL,
333  KEY_READ,
334  NULL,
335  &hJobsKey,
336  NULL);
337  if (lError != ERROR_SUCCESS)
338  goto done;
339 
340  for (dwIndex = 0; dwIndex < 1000; dwIndex++)
341  {
342  dwNameLength = JOB_NAME_LENGTH;
343  lError = RegEnumKeyEx(hJobsKey,
344  dwIndex,
345  szNameBuffer,
346  &dwNameLength,
347  NULL,
348  NULL,
349  NULL,
350  NULL);
351  if (lError != ERROR_SUCCESS)
352  {
353  lError = ERROR_SUCCESS;
354  break;
355  }
356 
357  TRACE("KeyName: %S\n", szNameBuffer);
358 
359  lError = RegOpenKeyEx(hJobsKey,
360  szNameBuffer,
361  0,
362  KEY_READ,
363  &hJobKey);
364  if (lError != ERROR_SUCCESS)
365  break;
366 
367  dwSize = sizeof(SCHEDULE);
368  lError = RegQueryValueEx(hJobKey,
369  L"Schedule",
370  NULL,
371  NULL,
372  (PBYTE)&Schedule,
373  &dwSize);
374  if (lError == ERROR_SUCCESS)
375  {
376  dwSize = 0;
377  RegQueryValueEx(hJobKey,
378  L"Command",
379  NULL,
380  NULL,
381  NULL,
382  &dwSize);
383  if (dwSize != 0)
384  {
385  /* Allocate a new job object */
386  pJob = HeapAlloc(GetProcessHeap(),
388  sizeof(JOB) + dwSize - sizeof(WCHAR));
389  if (pJob == NULL)
390  {
391  lError = ERROR_OUTOFMEMORY;
392  break;
393  }
394 
395  lError = RegQueryValueEx(hJobKey,
396  L"Command",
397  NULL,
398  NULL,
399  (PBYTE)pJob->Command,
400  &dwSize);
401  if (lError != ERROR_SUCCESS)
402  break;
403 
404  wcscpy(pJob->Name, szNameBuffer);
405  pJob->JobTime = Schedule.JobTime;
406  pJob->DaysOfMonth = Schedule.DaysOfMonth;
407  pJob->DaysOfWeek = Schedule.DaysOfWeek;
408  pJob->Flags = Schedule.Flags;
409 
410  /* Acquire the job list lock exclusively */
412 
413  /* Assign a new job ID */
414  pJob->JobId = dwNextJobId++;
415  dwJobCount++;
416 
417  /* Append the new job to the job list */
419 
420  /* Calculate the next start time */
422 
423  /* Insert the job into the start list */
425 #if 0
427 #endif
428 
429  /* Release the job list lock */
431 
432  pJob = NULL;
433  }
434  }
435 
436  RegCloseKey(hJobKey);
437  hJobKey = NULL;
438  }
439 
440 done:
441  if (pJob != NULL)
442  HeapFree(GetProcessHeap(), 0, pJob);
443 
444  if (hJobKey != NULL)
445  RegCloseKey(hJobKey);
446 
447  if (hJobsKey != NULL)
448  RegCloseKey(hJobsKey);
449 
450  return lError;
451 }
#define RegQueryValueEx
Definition: winreg.h:524
LIST_ENTRY JobEntry
Definition: precomp.h:33
RTL_RESOURCE JobListLock
Definition: job.c:30
DWORD JobId
Definition: precomp.h:39
#define ERROR_SUCCESS
Definition: deptool.c:10
VOID InsertJobIntoStartList(_In_ PLIST_ENTRY StartListHead, _In_ PJOB pJob)
Definition: job.c:603
#define KEY_READ
Definition: nt_native.h:1023
#define TRUE
Definition: types.h:120
UCHAR DaysOfWeek
Definition: job.c:22
WCHAR Name[JOB_NAME_LENGTH]
Definition: precomp.h:37
#define InsertTailList(ListHead, Entry)
LIST_ENTRY StartListHead
Definition: job.c:32
WCHAR Command[1]
Definition: precomp.h:44
NTSYSAPI VOID NTAPI RtlReleaseResource(_In_ PRTL_RESOURCE Resource)
LIST_ENTRY JobListHead
Definition: job.c:29
LONG WINAPI RegCreateKeyExW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey, _In_ DWORD Reserved, _In_opt_ LPWSTR lpClass, _In_ DWORD dwOptions, _In_ REGSAM samDesired, _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes, _Out_ PHKEY phkResult, _Out_opt_ LPDWORD lpdwDisposition)
Definition: reg.c:1091
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
UCHAR Flags
Definition: precomp.h:43
long LONG
Definition: pedump.c:60
smooth NULL
Definition: ftsmooth.c:416
DWORD_PTR JobTime
Definition: precomp.h:40
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
UCHAR DaysOfWeek
Definition: precomp.h:42
#define TRACE(s)
Definition: solgame.cpp:4
#define GetProcessHeap()
Definition: compat.h:595
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
__wchar_t WCHAR
Definition: xmlstorage.h:180
struct _SCHEDULE SCHEDULE
unsigned long DWORD
Definition: ntddk_ex.h:95
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
static const WCHAR L[]
Definition: oid.c:1250
#define RegEnumKeyEx
Definition: winreg.h:510
UCHAR Flags
Definition: job.c:23
#define RegOpenKeyEx
Definition: winreg.h:520
DWORD JobTime
Definition: job.c:20
#define JOB_NAME_LENGTH
Definition: precomp.h:23
DWORD dwJobCount
Definition: job.c:28
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
Definition: job.c:18
VOID DumpStartList(_In_ PLIST_ENTRY StartListHead)
Definition: job.c:654
DWORD DaysOfMonth
Definition: precomp.h:41
DWORD dwNextJobId
Definition: job.c:27
VOID CalculateNextStartTime(_In_ PJOB pJob)
Definition: job.c:468
DWORD DaysOfMonth
Definition: job.c:21
BYTE * PBYTE
Definition: pedump.c:66
Definition: precomp.h:31
#define HeapFree(x, y, z)
Definition: compat.h:594
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:54
#define ERROR_OUTOFMEMORY
Definition: deptool.c:13
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
NTSYSAPI BOOLEAN NTAPI RtlAcquireResourceExclusive(_In_ PRTL_RESOURCE Resource, _In_ BOOLEAN Wait)

Referenced by ServiceInit().

◆ ReScheduleJob()

static VOID ReScheduleJob ( PJOB  pJob)
static

Definition at line 90 of file job.c.

92 {
93  /* Remove the job from the start list */
95 
96  /* Non-periodical job, remove it */
97  if ((pJob->Flags & JOB_RUN_PERIODICALLY) == 0)
98  {
99  /* Remove the job from the registry */
100  DeleteJob(pJob);
101 
102  /* Remove the job from the job list */
103  RemoveEntryList(&pJob->JobEntry);
104  dwJobCount--;
105 
106  /* Free the job object */
107  HeapFree(GetProcessHeap(), 0, pJob);
108  return;
109  }
110 
111  /* Calculate the next start time */
113 
114  /* Insert the job into the start list again */
116 #if 0
118 #endif
119 }
LIST_ENTRY JobEntry
Definition: precomp.h:33
VOID InsertJobIntoStartList(_In_ PLIST_ENTRY StartListHead, _In_ PJOB pJob)
Definition: job.c:603
LIST_ENTRY StartListHead
Definition: job.c:32
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
UCHAR Flags
Definition: precomp.h:43
#define GetProcessHeap()
Definition: compat.h:595
LIST_ENTRY StartEntry
Definition: precomp.h:35
DWORD dwJobCount
Definition: job.c:28
LONG DeleteJob(_In_ PJOB pJob)
Definition: job.c:283
#define JOB_RUN_PERIODICALLY
Definition: lmat.h:7
VOID DumpStartList(_In_ PLIST_ENTRY StartListHead)
Definition: job.c:654
VOID CalculateNextStartTime(_In_ PJOB pJob)
Definition: job.c:468
#define HeapFree(x, y, z)
Definition: compat.h:594

Referenced by RunNextJob().

◆ RunNextJob()

VOID RunNextJob ( VOID  )

Definition at line 123 of file job.c.

124 {
125  PROCESS_INFORMATION ProcessInformation;
126  STARTUPINFOW StartupInfo;
127  BOOL bRet;
128  PJOB pNextJob;
129 
131  {
132  ERR("No job in list!\n");
133  return;
134  }
135 
136  pNextJob = CONTAINING_RECORD((&StartListHead)->Flink, JOB, StartEntry);
137 
138  TRACE("Run job %ld: %S\n", pNextJob->JobId, pNextJob->Command);
139 
140  ZeroMemory(&StartupInfo, sizeof(StartupInfo));
141  StartupInfo.cb = sizeof(StartupInfo);
142  StartupInfo.lpTitle = pNextJob->Command;
143  StartupInfo.dwFlags = STARTF_USESHOWWINDOW;
144  StartupInfo.wShowWindow = SW_SHOWDEFAULT;
145 
146  if ((pNextJob->Flags & JOB_NONINTERACTIVE) == 0)
147  {
148  StartupInfo.dwFlags |= STARTF_INHERITDESKTOP;
149  StartupInfo.lpDesktop = L"WinSta0\\Default";
150  }
151 
152  bRet = CreateProcessW(NULL,
153  pNextJob->Command,
154  NULL,
155  NULL,
156  FALSE,
158  NULL,
159  NULL,
160  &StartupInfo,
161  &ProcessInformation);
162  if (bRet == FALSE)
163  {
164  ERR("CreateProcessW() failed (Error %lu)\n", GetLastError());
165  }
166  else
167  {
168  CloseHandle(ProcessInformation.hThread);
169  CloseHandle(ProcessInformation.hProcess);
170  }
171 
172  ReScheduleJob(pNextJob);
173 }
DWORD JobId
Definition: precomp.h:39
#define SW_SHOWDEFAULT
Definition: winuser.h:774
#define CloseHandle
Definition: compat.h:598
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1044
#define ZeroMemory
Definition: winbase.h:1648
LIST_ENTRY StartListHead
Definition: job.c:32
WCHAR Command[1]
Definition: precomp.h:44
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
UCHAR Flags
Definition: precomp.h:43
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
LPWSTR lpDesktop
Definition: winbase.h:832
#define STARTF_INHERITDESKTOP
Definition: undocuser.h:162
smooth NULL
Definition: ftsmooth.c:416
LPWSTR lpTitle
Definition: winbase.h:833
#define STARTF_USESHOWWINDOW
Definition: winbase.h:472
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessW(LPCWSTR lpApplicationName, LPWSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation)
Definition: proc.c:4595
#define TRACE(s)
Definition: solgame.cpp:4
#define CREATE_NEW_CONSOLE
Definition: winbase.h:180
DWORD cb
Definition: winbase.h:830
#define JOB_NONINTERACTIVE
Definition: lmat.h:11
static VOID ReScheduleJob(PJOB pJob)
Definition: job.c:90
static const WCHAR L[]
Definition: oid.c:1250
WORD wShowWindow
Definition: winbase.h:842
#define ERR(fmt,...)
Definition: debug.h:110
DWORD dwFlags
Definition: winbase.h:841
Definition: precomp.h:31

Referenced by SchedServiceMain().

◆ SaveJob()

LONG SaveJob ( _In_ PJOB  pJob)

Definition at line 213 of file job.c.

215 {
216  SCHEDULE Schedule;
217  HKEY hJobsKey = NULL, hJobKey = NULL;
218  LONG lError;
219 
220  TRACE("SaveJob()\n");
221 
223  L"System\\CurrentControlSet\\Services\\Schedule\\Jobs",
224  0,
225  NULL,
227  KEY_WRITE,
228  NULL,
229  &hJobsKey,
230  NULL);
231  if (lError != ERROR_SUCCESS)
232  goto done;
233 
234  GetJobName(hJobsKey, pJob->Name);
235 
236  lError = RegCreateKeyExW(hJobsKey,
237  pJob->Name,
238  0,
239  NULL,
241  KEY_WRITE,
242  NULL,
243  &hJobKey,
244  NULL);
245  if (lError != ERROR_SUCCESS)
246  goto done;
247 
248  Schedule.JobTime = pJob->JobTime;
249  Schedule.DaysOfMonth = pJob->DaysOfMonth;
250  Schedule.DaysOfWeek = pJob->DaysOfWeek;
251  Schedule.Flags = pJob->Flags;
252 
253  lError = RegSetValueEx(hJobKey,
254  L"Schedule",
255  0,
256  REG_BINARY,
257  (PBYTE)&Schedule,
258  sizeof(Schedule));
259  if (lError != ERROR_SUCCESS)
260  goto done;
261 
262  lError = RegSetValueEx(hJobKey,
263  L"Command",
264  0,
265  REG_SZ,
266  (PBYTE)pJob->Command,
267  (wcslen(pJob->Command) + 1) * sizeof(WCHAR));
268  if (lError != ERROR_SUCCESS)
269  goto done;
270 
271 done:
272  if (hJobKey != NULL)
273  RegCloseKey(hJobKey);
274 
275  if (hJobsKey != NULL)
276  RegCloseKey(hJobsKey);
277 
278  return lError;
279 }
#define ERROR_SUCCESS
Definition: deptool.c:10
#define REG_BINARY
Definition: nt_native.h:1496
static VOID GetJobName(HKEY hJobsKey, PWSTR pszJobName)
Definition: job.c:178
UCHAR DaysOfWeek
Definition: job.c:22
LONG WINAPI RegCreateKeyExW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey, _In_ DWORD Reserved, _In_opt_ LPWSTR lpClass, _In_ DWORD dwOptions, _In_ REGSAM samDesired, _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes, _Out_ PHKEY phkResult, _Out_opt_ LPDWORD lpdwDisposition)
Definition: reg.c:1091
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
long LONG
Definition: pedump.c:60
smooth NULL
Definition: ftsmooth.c:416
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
#define KEY_WRITE
Definition: nt_native.h:1031
#define TRACE(s)
Definition: solgame.cpp:4
__wchar_t WCHAR
Definition: xmlstorage.h:180
static const WCHAR L[]
Definition: oid.c:1250
UCHAR Flags
Definition: job.c:23
DWORD JobTime
Definition: job.c:20
Definition: job.c:18
DWORD DaysOfMonth
Definition: job.c:21
BYTE * PBYTE
Definition: pedump.c:66
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define RegSetValueEx
Definition: winreg.h:533
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define REG_SZ
Definition: layer.c:22

Referenced by NetrJobAdd().

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( schedsvc  )

Variable Documentation

◆ dwJobCount

DWORD dwJobCount = 0

Definition at line 28 of file job.c.

Referenced by LoadJobs(), NetrJobAdd(), NetrJobDel(), NetrJobEnum(), and ReScheduleJob().

◆ dwNextJobId

DWORD dwNextJobId = 0

Definition at line 27 of file job.c.

Referenced by LoadJobs(), and NetrJobAdd().

◆ JobListHead

LIST_ENTRY JobListHead

Definition at line 29 of file job.c.

Referenced by LoadJobs(), NetrJobAdd(), NetrJobDel(), NetrJobEnum(), NetrJobGetInfo(), and ServiceInit().

◆ JobListLock

RTL_RESOURCE JobListLock

◆ StartListHead

◆ StartListLock

RTL_RESOURCE StartListLock

Definition at line 33 of file job.c.

Referenced by ServiceInit().

◆ wDaysArray

WORD wDaysArray[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
static

Definition at line 35 of file job.c.

Referenced by DaysOfMonth().