ReactOS  0.4.15-dev-4914-g2220e56
job.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: See COPYING in the top level directory
3  * PROJECT: ReactOS Services
4  * FILE: base/services/schedsvc/job.c
5  * PURPOSE: Scheduling service
6  * PROGRAMMER: Eric Kohl <eric.kohl@reactos.org>
7  */
8 
9 /* INCLUDES *****************************************************************/
10 
11 #include "precomp.h"
12 
14 
15 
16 /* GLOBALS ******************************************************************/
17 
18 typedef struct _SCHEDULE
19 {
26 
31 
36 
37 
38 static WORD wDaysArray[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
39 
40 
41 /* FUNCTIONS *****************************************************************/
42 
43 VOID
45 {
46  PLIST_ENTRY CurrentEntry;
48  PJOB CurrentJob;
49 
51  CurrentEntry = JobListHead.Flink;
52  while (CurrentEntry != &JobListHead)
53  {
54  CurrentJob = CONTAINING_RECORD(CurrentEntry, JOB, JobEntry);
55 
57  {
58  CopyMemory(&NextJobStartTime, &CurrentJob->StartTime, sizeof(FILETIME));
60  }
61  else
62  {
63  if (CompareFileTime(&NextJobStartTime, &CurrentJob->StartTime) > 0)
64  CopyMemory(&NextJobStartTime, &CurrentJob->StartTime, sizeof(FILETIME));
65  }
66 
67  CurrentEntry = CurrentEntry->Flink;
68  }
69 
71  {
72  TRACE("No valid job!\n");
73  return;
74  }
75 
77 
78  SetWaitableTimer(hTimer,
80  0,
81  NULL,
82  NULL,
83  TRUE);
84 }
85 
86 #if 0
87 static
88 VOID
89 ReScheduleJob(
90  PJOB pJob)
91 {
92  /* Remove the job from the start list */
93  RemoveEntryList(&pJob->StartEntry);
94 
95  /* Non-periodical job, remove it */
96  if ((pJob->Flags & JOB_RUN_PERIODICALLY) == 0)
97  {
98  /* Remove the job from the registry */
99  DeleteJob(pJob);
100 
101  /* Remove the job from the job list */
102  RemoveEntryList(&pJob->JobEntry);
103  dwJobCount--;
104 
105  /* Free the job object */
106  HeapFree(GetProcessHeap(), 0, pJob);
107  return;
108  }
109 
110  /* Calculate the next start time */
112 
113  /* Insert the job into the start list again */
115 #if 0
117 #endif
118 }
119 #endif
120 
121 VOID
123 {
124  PROCESS_INFORMATION ProcessInformation;
125  STARTUPINFOW StartupInfo;
126  PLIST_ENTRY CurrentEntry;
127  PJOB CurrentJob;
128  BOOL bRet;
129 
130  CurrentEntry = JobListHead.Flink;
131  while (CurrentEntry != &JobListHead)
132  {
133  CurrentJob = CONTAINING_RECORD(CurrentEntry, JOB, JobEntry);
134 
135  if (CompareFileTime(&NextJobStartTime, &CurrentJob->StartTime) == 0)
136  {
137  TRACE("Run job %ld: %S\n", CurrentJob->JobId, CurrentJob->Command);
138 
139  ZeroMemory(&StartupInfo, sizeof(StartupInfo));
140  StartupInfo.cb = sizeof(StartupInfo);
141  StartupInfo.lpTitle = CurrentJob->Command;
142  StartupInfo.dwFlags = STARTF_USESHOWWINDOW;
143  StartupInfo.wShowWindow = SW_SHOWDEFAULT;
144 
145  if ((CurrentJob->Flags & JOB_NONINTERACTIVE) == 0)
146  {
147  StartupInfo.dwFlags |= STARTF_INHERITDESKTOP;
148  StartupInfo.lpDesktop = L"WinSta0\\Default";
149  }
150 
151  bRet = CreateProcessW(NULL,
152  CurrentJob->Command,
153  NULL,
154  NULL,
155  FALSE,
157  NULL,
158  NULL,
159  &StartupInfo,
160  &ProcessInformation);
161  if (bRet == FALSE)
162  {
163  ERR("CreateProcessW() failed (Error %lu)\n", GetLastError());
164  }
165  else
166  {
167  CloseHandle(ProcessInformation.hThread);
168  CloseHandle(ProcessInformation.hProcess);
169  }
170  }
171 
172  CurrentEntry = CurrentEntry->Flink;
173  }
174 }
175 
176 
177 static
178 VOID
180  HKEY hJobsKey,
181  PWSTR pszJobName)
182 {
183  WCHAR szNameBuffer[JOB_NAME_LENGTH];
184  FILETIME SystemTime;
185  ULONG ulSeed, ulValue;
186  HKEY hKey;
187  LONG lError;
188 
189  GetSystemTimeAsFileTime(&SystemTime);
190  ulSeed = SystemTime.dwLowDateTime;
191  for (;;)
192  {
193  ulValue = RtlRandomEx(&ulSeed);
194  swprintf(szNameBuffer, L"%08lx", ulValue);
195 
196  hKey = NULL;
197  lError = RegOpenKeyEx(hJobsKey,
198  szNameBuffer,
199  0,
200  KEY_READ,
201  &hKey);
202  if (lError != ERROR_SUCCESS)
203  {
204  wcscpy(pszJobName, szNameBuffer);
205  return;
206  }
207 
208  RegCloseKey(hKey);
209  }
210 }
211 
212 
213 LONG
215  _In_ PJOB pJob)
216 {
217  SCHEDULE Schedule;
218  HKEY hJobsKey = NULL, hJobKey = NULL;
219  LONG lError;
220 
221  TRACE("SaveJob()\n");
222 
224  L"System\\CurrentControlSet\\Services\\Schedule\\Jobs",
225  0,
226  NULL,
228  KEY_WRITE,
229  NULL,
230  &hJobsKey,
231  NULL);
232  if (lError != ERROR_SUCCESS)
233  goto done;
234 
235  GetJobName(hJobsKey, pJob->Name);
236 
237  lError = RegCreateKeyExW(hJobsKey,
238  pJob->Name,
239  0,
240  NULL,
242  KEY_WRITE,
243  NULL,
244  &hJobKey,
245  NULL);
246  if (lError != ERROR_SUCCESS)
247  goto done;
248 
249  Schedule.JobTime = pJob->JobTime;
250  Schedule.DaysOfMonth = pJob->DaysOfMonth;
251  Schedule.DaysOfWeek = pJob->DaysOfWeek;
252  Schedule.Flags = pJob->Flags;
253 
254  lError = RegSetValueEx(hJobKey,
255  L"Schedule",
256  0,
257  REG_BINARY,
258  (PBYTE)&Schedule,
259  sizeof(Schedule));
260  if (lError != ERROR_SUCCESS)
261  goto done;
262 
263  lError = RegSetValueEx(hJobKey,
264  L"Command",
265  0,
266  REG_SZ,
267  (PBYTE)pJob->Command,
268  (wcslen(pJob->Command) + 1) * sizeof(WCHAR));
269  if (lError != ERROR_SUCCESS)
270  goto done;
271 
272 done:
273  if (hJobKey != NULL)
274  RegCloseKey(hJobKey);
275 
276  if (hJobsKey != NULL)
277  RegCloseKey(hJobsKey);
278 
279  return lError;
280 }
281 
282 
283 LONG
285  _In_ PJOB pJob)
286 {
287  HKEY hJobsKey = NULL;
288  LONG lError;
289 
290  TRACE("DeleteJob()\n");
291 
293  L"System\\CurrentControlSet\\Services\\Schedule\\Jobs",
294  0,
295  NULL,
297  KEY_WRITE,
298  NULL,
299  &hJobsKey,
300  NULL);
301  if (lError != ERROR_SUCCESS)
302  goto done;
303 
304  lError = RegDeleteKey(hJobsKey,
305  pJob->Name);
306  if (lError != ERROR_SUCCESS)
307  goto done;
308 
309 done:
310  if (hJobsKey != NULL)
311  RegCloseKey(hJobsKey);
312 
313  return lError;
314 }
315 
316 
317 LONG
319 {
320  SCHEDULE Schedule;
321  WCHAR szNameBuffer[JOB_NAME_LENGTH];
322  DWORD dwNameLength, dwIndex, dwSize;
323  HKEY hJobsKey = NULL, hJobKey = NULL;
324  PJOB pJob = NULL;
325  LONG lError;
326 
327  TRACE("LoadJobs()\n");
328 
330  L"System\\CurrentControlSet\\Services\\Schedule\\Jobs",
331  0,
332  NULL,
334  KEY_READ,
335  NULL,
336  &hJobsKey,
337  NULL);
338  if (lError != ERROR_SUCCESS)
339  goto done;
340 
341  for (dwIndex = 0; dwIndex < 1000; dwIndex++)
342  {
343  dwNameLength = JOB_NAME_LENGTH;
344  lError = RegEnumKeyEx(hJobsKey,
345  dwIndex,
346  szNameBuffer,
347  &dwNameLength,
348  NULL,
349  NULL,
350  NULL,
351  NULL);
352  if (lError != ERROR_SUCCESS)
353  {
354  lError = ERROR_SUCCESS;
355  break;
356  }
357 
358  TRACE("KeyName: %S\n", szNameBuffer);
359 
360  lError = RegOpenKeyEx(hJobsKey,
361  szNameBuffer,
362  0,
363  KEY_READ,
364  &hJobKey);
365  if (lError != ERROR_SUCCESS)
366  break;
367 
368  dwSize = sizeof(SCHEDULE);
369  lError = RegQueryValueEx(hJobKey,
370  L"Schedule",
371  NULL,
372  NULL,
373  (PBYTE)&Schedule,
374  &dwSize);
375  if (lError == ERROR_SUCCESS)
376  {
377  dwSize = 0;
378  RegQueryValueEx(hJobKey,
379  L"Command",
380  NULL,
381  NULL,
382  NULL,
383  &dwSize);
384  if (dwSize != 0)
385  {
386  /* Allocate a new job object */
387  pJob = HeapAlloc(GetProcessHeap(),
389  sizeof(JOB) + dwSize - sizeof(WCHAR));
390  if (pJob == NULL)
391  {
392  lError = ERROR_OUTOFMEMORY;
393  break;
394  }
395 
396  lError = RegQueryValueEx(hJobKey,
397  L"Command",
398  NULL,
399  NULL,
400  (PBYTE)pJob->Command,
401  &dwSize);
402  if (lError != ERROR_SUCCESS)
403  break;
404 
405  wcscpy(pJob->Name, szNameBuffer);
406  pJob->JobTime = Schedule.JobTime;
407  pJob->DaysOfMonth = Schedule.DaysOfMonth;
408  pJob->DaysOfWeek = Schedule.DaysOfWeek;
409  pJob->Flags = Schedule.Flags;
410 
411  /* Acquire the job list lock exclusively */
413 
414  /* Assign a new job ID */
415  pJob->JobId = dwNextJobId++;
416  dwJobCount++;
417 
418  /* Append the new job to the job list */
420 
421  /* Calculate the next start time */
423 
424 #if 0
426 #endif
427 
428  /* Release the job list lock */
430 
431  pJob = NULL;
432  }
433  }
434 
435  RegCloseKey(hJobKey);
436  hJobKey = NULL;
437  }
438 
439 done:
440  if (pJob != NULL)
441  HeapFree(GetProcessHeap(), 0, pJob);
442 
443  if (hJobKey != NULL)
444  RegCloseKey(hJobKey);
445 
446  if (hJobsKey != NULL)
447  RegCloseKey(hJobsKey);
448 
449  return lError;
450 }
451 
452 
453 static
454 WORD
456  WORD wMonth,
457  WORD wYear)
458 {
459  if (wMonth == 2 && wYear % 4 == 0 && wYear % 400 != 0)
460  return 29;
461 
462  return wDaysArray[wMonth];
463 }
464 
465 
466 VOID
468  _In_ PJOB pJob)
469 {
470  SYSTEMTIME CurrentSystemTime, StartSystemTime;
471  FILETIME StartFileTime;
472  WORD wDaysOffset, wTempOffset, i, wJobDayOfWeek, wJobDayOfMonth;
473  DWORD_PTR CurrentTimeMs;
474  BOOL bDaysOffsetValid;
475  ULARGE_INTEGER LocalStartTime;
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  LocalStartTime.u.LowPart = StartFileTime.dwLowDateTime;
594  LocalStartTime.u.HighPart = StartFileTime.dwHighDateTime;
595  if (bDaysOffsetValid && wDaysOffset != 0)
596  {
597  LocalStartTime.QuadPart += ((ULONGLONG)wDaysOffset * 24 * 60 * 60 * 10000);
598  }
599 
600  pJob->StartTime.dwLowDateTime = LocalStartTime.u.LowPart;
601  pJob->StartTime.dwHighDateTime = LocalStartTime.u.HighPart;
602 }
603 
604 #if 0
605 VOID
608 {
609  PLIST_ENTRY CurrentEntry;
610  PJOB CurrentJob;
611 
612  CurrentEntry = JobListHead->Flink;
613  while (CurrentEntry != &JobListHead)
614  {
615  CurrentJob = CONTAINING_RECORD(CurrentEntry, JOB, StartEntry);
616 
617  TRACE("%3lu: %016I64x\n", CurrentJob->JobId, CurrentJob->StartTime.QuadPart);
618 
619  CurrentEntry = CurrentEntry->Flink;
620  }
621 }
622 #endif
623 /* EOF */
#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:38
#define SW_SHOWDEFAULT
Definition: winuser.h:774
static WORD wDaysArray[13]
Definition: job.c:38
VOID WINAPI GetSystemTimeAsFileTime(OUT PFILETIME lpFileTime)
Definition: time.c:128
#define CloseHandle
Definition: compat.h:598
VOID RunCurrentJobs(VOID)
Definition: job.c:122
#define ERROR_SUCCESS
Definition: deptool.c:10
#define DWORD_PTR
Definition: treelist.c:76
WORD wMonth
Definition: winbase.h:903
struct _ULARGE_INTEGER::@3916 u
#define REG_BINARY
Definition: nt_native.h:1496
#define KEY_READ
Definition: nt_native.h:1023
#define TRUE
Definition: types.h:120
uint16_t * PWSTR
Definition: typedefs.h:56
static VOID GetJobName(HKEY hJobsKey, PWSTR pszJobName)
Definition: job.c:179
WORD wDayOfWeek
Definition: winbase.h:904
UCHAR DaysOfWeek
Definition: job.c:22
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1040
#define ZeroMemory
Definition: winbase.h:1667
WCHAR Name[JOB_NAME_LENGTH]
Definition: precomp.h:36
struct _SCHEDULE PSCHEDULE
#define InsertTailList(ListHead, Entry)
LIST_ENTRY StartListHead
Definition: job.c:32
VOID DumpStartList(_In_ PLIST_ENTRY StartListHead)
WCHAR Command[1]
Definition: precomp.h:43
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
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
BOOL WINAPI LocalFileTimeToFileTime(IN CONST FILETIME *lpLocalFileTime, OUT LPFILETIME lpFileTime)
Definition: time.c:253
DWORD dwHighDateTime
Definition: mapidefs.h:66
WORD wYear
Definition: winbase.h:902
#define L(x)
Definition: ntvdm.h:50
UCHAR Flags
Definition: precomp.h:42
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
#define FIXME(fmt,...)
Definition: debug.h:111
LPWSTR lpDesktop
Definition: winbase.h:851
#define STARTF_INHERITDESKTOP
Definition: undocuser.h:163
LONG SaveJob(_In_ PJOB pJob)
Definition: job.c:214
WORD wMinute
Definition: winbase.h:907
LPWSTR lpTitle
Definition: winbase.h:852
#define _In_
Definition: ms_sal.h:308
VOID WINAPI GetLocalTime(OUT LPSYSTEMTIME lpSystemTime)
Definition: time.c:286
#define STARTF_USESHOWWINDOW
Definition: winbase.h:488
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
DWORD_PTR JobTime
Definition: precomp.h:39
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:4594
BOOL bValidNextJobStartTime
Definition: job.c:35
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
#define KEY_WRITE
Definition: nt_native.h:1031
UCHAR DaysOfWeek
Definition: precomp.h:41
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define TRACE(s)
Definition: solgame.cpp:4
#define CREATE_NEW_CONSOLE
Definition: winbase.h:180
LONG WINAPI CompareFileTime(IN CONST FILETIME *lpFileTime1, IN CONST FILETIME *lpFileTime2)
Definition: time.c:106
#define GetProcessHeap()
Definition: compat.h:595
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
DWORD cb
Definition: winbase.h:849
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define JOB_NONINTERACTIVE
Definition: lmat.h:11
WINE_DEFAULT_DEBUG_CHANNEL(schedsvc)
uint64_t ULONGLONG
Definition: typedefs.h:67
WORD Reserved
Definition: job.c:24
struct _SCHEDULE SCHEDULE
#define CopyMemory
Definition: winbase.h:1665
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned long DWORD
Definition: ntddk_ex.h:95
WORD wSecond
Definition: winbase.h:908
WORD wMilliseconds
Definition: winbase.h:909
RTL_RESOURCE StartListLock
Definition: job.c:33
unsigned char UCHAR
Definition: xmlstorage.h:181
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
FILETIME StartTime
Definition: precomp.h:35
WORD wShowWindow
Definition: winbase.h:861
VOID GetNextJobTimeout(HANDLE hTimer)
Definition: job.c:44
Definition: typedefs.h:119
int _cdecl swprintf(const WCHAR *,...)
uint32_t DWORD_PTR
Definition: typedefs.h:65
#define RegEnumKeyEx
Definition: winreg.h:510
NTSYSAPI ULONG NTAPI RtlRandomEx(PULONG Seed)
#define ERR(fmt,...)
Definition: debug.h:110
UCHAR Flags
Definition: job.c:23
WORD wDay
Definition: winbase.h:905
VOID InsertJobIntoStartList(_In_ PLIST_ENTRY StartListHead, _In_ PJOB pJob)
#define RegOpenKeyEx
Definition: winreg.h:520
BOOL WINAPI SystemTimeToFileTime(IN CONST SYSTEMTIME *lpSystemTime, OUT LPFILETIME lpFileTime)
Definition: time.c:158
DWORD JobTime
Definition: job.c:20
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
FxAutoRegKey hKey
WORD wHour
Definition: winbase.h:906
#define JOB_NAME_LENGTH
Definition: precomp.h:23
DWORD dwJobCount
Definition: job.c:28
#define NULL
Definition: types.h:112
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
#define RegDeleteKey
Definition: winreg.h:502
LONG DeleteJob(_In_ PJOB pJob)
Definition: job.c:284
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
_In_ WDFTIMER _In_ LONGLONG DueTime
Definition: wdftimer.h:187
Definition: job.c:18
LONG LoadJobs(VOID)
Definition: job.c:318
#define JOB_RUN_PERIODICALLY
Definition: lmat.h:7
unsigned int ULONG
Definition: retypes.h:1
DWORD DaysOfMonth
Definition: precomp.h:40
DWORD dwFlags
Definition: winbase.h:860
DWORD dwNextJobId
Definition: job.c:27
static WORD DaysOfMonth(WORD wMonth, WORD wYear)
Definition: job.c:455
VOID CalculateNextStartTime(_In_ PJOB pJob)
Definition: job.c:467
BOOL WINAPI SetWaitableTimer(IN HANDLE hTimer, IN const LARGE_INTEGER *pDueTime, IN LONG lPeriod, IN PTIMERAPCROUTINE pfnCompletionRoutine OPTIONAL, IN OPTIONAL LPVOID lpArgToCompletionRoutine, IN BOOL fResume)
Definition: synch.c:382
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
#define RegCloseKey(hKey)
Definition: registry.h:47
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:56
#define RegSetValueEx
Definition: winreg.h:533
DWORD dwLowDateTime
Definition: mapidefs.h:65
FILETIME NextJobStartTime
Definition: job.c:34
#define ERROR_OUTOFMEMORY
Definition: deptool.c:13
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define REG_SZ
Definition: layer.c:22
NTSYSAPI BOOLEAN NTAPI RtlAcquireResourceExclusive(_In_ PRTL_RESOURCE Resource, _In_ BOOLEAN Wait)