ReactOS  0.4.12-dev-57-g7050ac4
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 
34 
35 
36 /* FUNCTIONS *****************************************************************/
37 
38 DWORD
40 {
41  FILETIME FileTime;
42  SYSTEMTIME SystemTime;
43  ULARGE_INTEGER CurrentTime, Timeout;
44  PJOB pNextJob;
45 
46  if (IsListEmpty(&StartListHead))
47  {
48  TRACE("No job in list! Wait until next update.\n");
49  return INFINITE;
50  }
51 
52  pNextJob = CONTAINING_RECORD((&StartListHead)->Flink, JOB, StartEntry);
53 
54  FileTime.dwLowDateTime = pNextJob->StartTime.u.LowPart;
55  FileTime.dwHighDateTime = pNextJob->StartTime.u.HighPart;
56  FileTimeToSystemTime(&FileTime, &SystemTime);
57 
58  TRACE("Start next job (%lu) at %02hu:%02hu %02hu.%02hu.%hu\n",
59  pNextJob->JobId, SystemTime.wHour, SystemTime.wMinute,
60  SystemTime.wDay, SystemTime.wMonth, SystemTime.wYear);
61 
62  GetLocalTime(&SystemTime);
63  SystemTimeToFileTime(&SystemTime, &FileTime);
64 
65  CurrentTime.u.LowPart = FileTime.dwLowDateTime;
66  CurrentTime.u.HighPart = FileTime.dwHighDateTime;
67 
68  if (CurrentTime.QuadPart >= pNextJob->StartTime.QuadPart)
69  {
70  TRACE("Next event has already gone by!\n");
71  return 0;
72  }
73 
74  Timeout.QuadPart = (pNextJob->StartTime.QuadPart - CurrentTime.QuadPart) / 10000;
75  if (Timeout.u.HighPart != 0)
76  {
77  TRACE("Event happens too far in the future!\n");
78  return INFINITE;
79  }
80 
81  TRACE("Timeout: %lu\n", Timeout.u.LowPart);
82  return Timeout.u.LowPart;
83 }
84 
85 
86 static
87 VOID
89  PJOB pJob)
90 {
91  /* Remove the job from the start list */
93 
94  /* Non-periodical job, remove it */
95  if ((pJob->Flags & JOB_RUN_PERIODICALLY) == 0)
96  {
97  /* Remove the job from the registry */
98  DeleteJob(pJob);
99 
100  /* Remove the job from the job list */
101  RemoveEntryList(&pJob->JobEntry);
102  dwJobCount--;
103 
104  /* Free the job object */
105  HeapFree(GetProcessHeap(), 0, pJob);
106  return;
107  }
108 
109  /* Calculate the next start time */
111 
112  /* Insert the job into the start list again */
113  InsertJobIntoStartList(&StartListHead, pJob);
114 #if 0
115  DumpStartList(&StartListHead);
116 #endif
117 }
118 
119 
120 VOID
122 {
123  PROCESS_INFORMATION ProcessInformation;
124  STARTUPINFOW StartupInfo;
125  BOOL bRet;
126  PJOB pNextJob;
127 
128  if (IsListEmpty(&StartListHead))
129  {
130  ERR("No job in list!\n");
131  return;
132  }
133 
134  pNextJob = CONTAINING_RECORD((&StartListHead)->Flink, JOB, StartEntry);
135 
136  TRACE("Run job %ld: %S\n", pNextJob->JobId, pNextJob->Command);
137 
138  ZeroMemory(&StartupInfo, sizeof(StartupInfo));
139  StartupInfo.cb = sizeof(StartupInfo);
140  StartupInfo.lpTitle = pNextJob->Command;
141  StartupInfo.dwFlags = STARTF_USESHOWWINDOW;
142  StartupInfo.wShowWindow = SW_SHOWDEFAULT;
143 
144  if ((pNextJob->Flags & JOB_NONINTERACTIVE) == 0)
145  {
146  StartupInfo.dwFlags |= STARTF_INHERITDESKTOP;
147  StartupInfo.lpDesktop = L"WinSta0\\Default";
148  }
149 
150  bRet = CreateProcessW(NULL,
151  pNextJob->Command,
152  NULL,
153  NULL,
154  FALSE,
156  NULL,
157  NULL,
158  &StartupInfo,
159  &ProcessInformation);
160  if (bRet == FALSE)
161  {
162  ERR("CreateProcessW() failed (Error %lu)\n", GetLastError());
163  }
164  else
165  {
166  CloseHandle(ProcessInformation.hThread);
167  CloseHandle(ProcessInformation.hProcess);
168  }
169 
170  ReScheduleJob(pNextJob);
171 }
172 
173 
174 static
175 VOID
177  HKEY hJobsKey,
178  PWSTR pszJobName)
179 {
180  WCHAR szNameBuffer[JOB_NAME_LENGTH];
181  FILETIME SystemTime;
182  ULONG ulSeed, ulValue;
183  HKEY hKey;
184  LONG lError;
185 
186  GetSystemTimeAsFileTime(&SystemTime);
187  ulSeed = SystemTime.dwLowDateTime;
188  for (;;)
189  {
190  ulValue = RtlRandomEx(&ulSeed);
191  swprintf(szNameBuffer, L"%08lx", ulValue);
192 
193  hKey = NULL;
194  lError = RegOpenKeyEx(hJobsKey,
195  szNameBuffer,
196  0,
197  KEY_READ,
198  &hKey);
199  if (lError != ERROR_SUCCESS)
200  {
201  wcscpy(pszJobName, szNameBuffer);
202  return;
203  }
204 
205  RegCloseKey(hKey);
206  }
207 }
208 
209 
210 LONG
212  _In_ PJOB pJob)
213 {
214  SCHEDULE Schedule;
215  HKEY hJobsKey = NULL, hJobKey = NULL;
216  LONG lError;
217 
218  TRACE("SaveJob()\n");
219 
221  L"System\\CurrentControlSet\\Services\\Schedule\\Jobs",
222  0,
223  NULL,
225  KEY_WRITE,
226  NULL,
227  &hJobsKey,
228  NULL);
229  if (lError != ERROR_SUCCESS)
230  goto done;
231 
232  GetJobName(hJobsKey, pJob->Name);
233 
234  lError = RegCreateKeyExW(hJobsKey,
235  pJob->Name,
236  0,
237  NULL,
239  KEY_WRITE,
240  NULL,
241  &hJobKey,
242  NULL);
243  if (lError != ERROR_SUCCESS)
244  goto done;
245 
246  Schedule.JobTime = pJob->JobTime;
247  Schedule.DaysOfMonth = pJob->DaysOfMonth;
248  Schedule.DaysOfWeek = pJob->DaysOfWeek;
249  Schedule.Flags = pJob->Flags;
250 
251  lError = RegSetValueEx(hJobKey,
252  L"Schedule",
253  0,
254  REG_BINARY,
255  (PBYTE)&Schedule,
256  sizeof(Schedule));
257  if (lError != ERROR_SUCCESS)
258  goto done;
259 
260  lError = RegSetValueEx(hJobKey,
261  L"Command",
262  0,
263  REG_SZ,
264  (PBYTE)pJob->Command,
265  (wcslen(pJob->Command) + 1) * sizeof(WCHAR));
266  if (lError != ERROR_SUCCESS)
267  goto done;
268 
269 done:
270  if (hJobKey != NULL)
271  RegCloseKey(hJobKey);
272 
273  if (hJobsKey != NULL)
274  RegCloseKey(hJobsKey);
275 
276  return lError;
277 }
278 
279 
280 LONG
282  _In_ PJOB pJob)
283 {
284  HKEY hJobsKey = NULL;
285  LONG lError;
286 
287  TRACE("DeleteJob()\n");
288 
290  L"System\\CurrentControlSet\\Services\\Schedule\\Jobs",
291  0,
292  NULL,
294  KEY_WRITE,
295  NULL,
296  &hJobsKey,
297  NULL);
298  if (lError != ERROR_SUCCESS)
299  goto done;
300 
301  lError = RegDeleteKey(hJobsKey,
302  pJob->Name);
303  if (lError != ERROR_SUCCESS)
304  goto done;
305 
306 done:
307  if (hJobsKey != NULL)
308  RegCloseKey(hJobsKey);
309 
310  return lError;
311 }
312 
313 
314 LONG
316 {
317  SCHEDULE Schedule;
318  WCHAR szNameBuffer[JOB_NAME_LENGTH];
319  DWORD dwNameLength, dwIndex, dwSize;
320  HKEY hJobsKey = NULL, hJobKey = NULL;
321  PJOB pJob = NULL;
322  LONG lError;
323 
324  TRACE("LoadJobs()\n");
325 
327  L"System\\CurrentControlSet\\Services\\Schedule\\Jobs",
328  0,
329  NULL,
331  KEY_READ,
332  NULL,
333  &hJobsKey,
334  NULL);
335  if (lError != ERROR_SUCCESS)
336  goto done;
337 
338  for (dwIndex = 0; dwIndex < 1000; dwIndex++)
339  {
340  dwNameLength = JOB_NAME_LENGTH;
341  lError = RegEnumKeyEx(hJobsKey,
342  dwIndex,
343  szNameBuffer,
344  &dwNameLength,
345  NULL,
346  NULL,
347  NULL,
348  NULL);
349  if (lError != ERROR_SUCCESS)
350  {
351  lError = ERROR_SUCCESS;
352  break;
353  }
354 
355  TRACE("KeyName: %S\n", szNameBuffer);
356 
357  lError = RegOpenKeyEx(hJobsKey,
358  szNameBuffer,
359  0,
360  KEY_READ,
361  &hJobKey);
362  if (lError != ERROR_SUCCESS)
363  break;
364 
365  dwSize = sizeof(SCHEDULE);
366  lError = RegQueryValueEx(hJobKey,
367  L"Schedule",
368  NULL,
369  NULL,
370  (PBYTE)&Schedule,
371  &dwSize);
372  if (lError == ERROR_SUCCESS)
373  {
374  dwSize = 0;
375  RegQueryValueEx(hJobKey,
376  L"Command",
377  NULL,
378  NULL,
379  NULL,
380  &dwSize);
381  if (dwSize != 0)
382  {
383  /* Allocate a new job object */
384  pJob = HeapAlloc(GetProcessHeap(),
386  sizeof(JOB) + dwSize - sizeof(WCHAR));
387  if (pJob == NULL)
388  {
389  lError = ERROR_OUTOFMEMORY;
390  break;
391  }
392 
393  lError = RegQueryValueEx(hJobKey,
394  L"Command",
395  NULL,
396  NULL,
397  (PBYTE)pJob->Command,
398  &dwSize);
399  if (lError != ERROR_SUCCESS)
400  break;
401 
402  wcscpy(pJob->Name, szNameBuffer);
403  pJob->JobTime = Schedule.JobTime;
404  pJob->DaysOfMonth = Schedule.DaysOfMonth;
405  pJob->DaysOfWeek = Schedule.DaysOfWeek;
406  pJob->Flags = Schedule.Flags;
407 
408  /* Acquire the job list lock exclusively */
409  RtlAcquireResourceExclusive(&JobListLock, TRUE);
410 
411  /* Assign a new job ID */
412  pJob->JobId = dwNextJobId++;
413  dwJobCount++;
414 
415  /* Append the new job to the job list */
416  InsertTailList(&JobListHead, &pJob->JobEntry);
417 
418  /* Calculate the next start time */
420 
421  /* Insert the job into the start list */
422  InsertJobIntoStartList(&StartListHead, pJob);
423 #if 0
424  DumpStartList(&StartListHead);
425 #endif
426 
427  /* Release the job list lock */
428  RtlReleaseResource(&JobListLock);
429 
430  pJob = NULL;
431  }
432  }
433 
434  RegCloseKey(hJobKey);
435  hJobKey = NULL;
436  }
437 
438 done:
439  if (pJob != NULL)
440  HeapFree(GetProcessHeap(), 0, pJob);
441 
442  if (hJobKey != NULL)
443  RegCloseKey(hJobKey);
444 
445  if (hJobsKey != NULL)
446  RegCloseKey(hJobsKey);
447 
448  return lError;
449 }
450 
451 
452 static
453 WORD
455  WORD wMonth,
456  WORD wYear)
457 {
458  WORD wDaysArray[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
459 
460  if (wMonth == 2 && wYear % 4 == 0 && wYear % 400 != 0)
461  return 29;
462 
463  return wDaysArray[wMonth];
464 }
465 
466 
467 VOID
469  _In_ PJOB pJob)
470 {
472  FILETIME FileTime;
473  DWORD_PTR Now;
474 
475  TRACE("CalculateNextStartTime(%p)\n", pJob);
476 
477  GetLocalTime(&StartTime);
478 
479  Now = (DWORD_PTR)StartTime.wHour * 3600000 +
480  (DWORD_PTR)StartTime.wMinute * 60000;
481 
482  StartTime.wMilliseconds = 0;
483  StartTime.wSecond = 0;
484  StartTime.wHour = (WORD)(pJob->JobTime / 3600000);
485  StartTime.wMinute = (WORD)((pJob->JobTime % 3600000) / 60000);
486 
487  if (pJob->DaysOfMonth != 0)
488  {
489  FIXME("Support DaysOfMonth!\n");
490  }
491  else if (pJob->DaysOfWeek != 0)
492  {
493  FIXME("Support DaysOfWeek!\n");
494  }
495  else
496  {
497  /* Start the job tomorrow */
498  if (Now > pJob->JobTime)
499  {
500  if (StartTime.wDay + 1 > DaysOfMonth(StartTime.wMonth, StartTime.wYear))
501  {
502  if (StartTime.wMonth == 12)
503  {
504  StartTime.wDay = 1;
505  StartTime.wMonth = 1;
506  StartTime.wYear++;
507  }
508  else
509  {
510  StartTime.wDay = 1;
511  StartTime.wMonth++;
512  }
513  }
514  else
515  {
516  StartTime.wDay++;
517  }
518  }
519  }
520 
521  TRACE("Next start: %02hu:%02hu %02hu.%02hu.%hu\n", StartTime.wHour,
522  StartTime.wMinute, StartTime.wDay, StartTime.wMonth, StartTime.wYear);
523 
524  SystemTimeToFileTime(&StartTime, &FileTime);
525  pJob->StartTime.u.LowPart = FileTime.dwLowDateTime;
526  pJob->StartTime.u.HighPart = FileTime.dwHighDateTime;
527 }
528 
529 
530 VOID
532  _In_ PLIST_ENTRY StartListHead,
533  _In_ PJOB pJob)
534 {
535  PLIST_ENTRY CurrentEntry, PreviousEntry;
536  PJOB CurrentJob;
537 
538  if (IsListEmpty(StartListHead))
539  {
540  InsertHeadList(StartListHead, &pJob->StartEntry);
541  return;
542  }
543 
544  CurrentEntry = StartListHead->Flink;
545  while (CurrentEntry != StartListHead)
546  {
547  CurrentJob = CONTAINING_RECORD(CurrentEntry, JOB, StartEntry);
548 
549  if ((CurrentEntry == StartListHead->Flink) &&
550  (pJob->StartTime.QuadPart < CurrentJob->StartTime.QuadPart))
551  {
552  /* Insert before the first entry */
553  InsertHeadList(StartListHead, &pJob->StartEntry);
554  return;
555  }
556 
557  if (pJob->StartTime.QuadPart < CurrentJob->StartTime.QuadPart)
558  {
559  /* Insert between the previous and the current entry */
560  PreviousEntry = CurrentEntry->Blink;
561  pJob->StartEntry.Blink = PreviousEntry;
562  pJob->StartEntry.Flink = CurrentEntry;
563  PreviousEntry->Flink = &pJob->StartEntry;
564  CurrentEntry->Blink = &pJob->StartEntry;
565  return;
566  }
567 
568  if ((CurrentEntry->Flink == StartListHead) &&
569  (pJob->StartTime.QuadPart >= CurrentJob->StartTime.QuadPart))
570  {
571  /* Insert after the last entry */
572  InsertTailList(StartListHead, &pJob->StartEntry);
573  return;
574  }
575 
576  CurrentEntry = CurrentEntry->Flink;
577  }
578 }
579 
580 
581 VOID
583  _In_ PLIST_ENTRY StartListHead)
584 {
585  PLIST_ENTRY CurrentEntry;
586  PJOB CurrentJob;
587 
588  CurrentEntry = StartListHead->Flink;
589  while (CurrentEntry != StartListHead)
590  {
591  CurrentJob = CONTAINING_RECORD(CurrentEntry, JOB, StartEntry);
592 
593  TRACE("%3lu: %016I64x\n", CurrentJob->JobId, CurrentJob->StartTime.QuadPart);
594 
595  CurrentEntry = CurrentEntry->Flink;
596  }
597 }
598 
599 /* 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:39
#define SW_SHOWDEFAULT
Definition: winuser.h:774
VOID WINAPI GetSystemTimeAsFileTime(OUT PFILETIME lpFileTime)
Definition: time.c:128
#define TRUE
Definition: types.h:120
#define CloseHandle
Definition: compat.h:398
ULARGE_INTEGER StartTime
Definition: precomp.h:36
#define ERROR_SUCCESS
Definition: deptool.c:10
#define DWORD_PTR
Definition: treelist.c:76
WORD wMonth
Definition: winbase.h:871
VOID RunNextJob(VOID)
Definition: job.c:121
#define REG_BINARY
Definition: nt_native.h:1496
VOID InsertJobIntoStartList(_In_ PLIST_ENTRY StartListHead, _In_ PJOB pJob)
Definition: job.c:531
#define KEY_READ
Definition: nt_native.h:1023
__wchar_t WCHAR
Definition: xmlstorage.h:180
uint16_t * PWSTR
Definition: typedefs.h:54
struct _LIST_ENTRY * Blink
Definition: typedefs.h:120
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PLIST_ENTRY Entry)
Definition: rtlfuncs.h:201
static VOID GetJobName(HKEY hJobsKey, PWSTR pszJobName)
Definition: job.c:176
UCHAR DaysOfWeek
Definition: job.c:22
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
#define ZeroMemory
Definition: winbase.h:1635
WCHAR Name[JOB_NAME_LENGTH]
Definition: precomp.h:37
struct _SCHEDULE PSCHEDULE
#define InsertTailList(ListHead, Entry)
LIST_ENTRY StartListHead
Definition: job.c:32
static LARGE_INTEGER StartTime
Definition: sys_arch.c:18
WCHAR Command[1]
Definition: precomp.h:44
NTSYSAPI VOID NTAPI RtlReleaseResource(_In_ PRTL_RESOURCE Resource)
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
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:1094
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
DWORD dwHighDateTime
Definition: mapidefs.h:66
WORD wYear
Definition: winbase.h:870
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
UCHAR Flags
Definition: precomp.h:43
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
long LONG
Definition: pedump.c:60
#define FIXME(fmt,...)
Definition: debug.h:110
LPWSTR lpDesktop
Definition: winbase.h:819
#define STARTF_INHERITDESKTOP
Definition: undocuser.h:162
LONG SaveJob(_In_ PJOB pJob)
Definition: job.c:211
WORD wMinute
Definition: winbase.h:875
smooth NULL
Definition: ftsmooth.c:416
LPWSTR lpTitle
Definition: winbase.h:820
DWORD GetNextJobTimeout(VOID)
Definition: job.c:39
VOID WINAPI GetLocalTime(OUT LPSYSTEMTIME lpSystemTime)
Definition: time.c:276
#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
DWORD_PTR JobTime
Definition: precomp.h:40
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:4623
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
#define KEY_WRITE
Definition: nt_native.h:1031
struct _ULARGE_INTEGER::@3737 u
UCHAR DaysOfWeek
Definition: precomp.h:42
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
#define TRACE(s)
Definition: solgame.cpp:4
BOOL WINAPI FileTimeToSystemTime(IN CONST FILETIME *lpFileTime, OUT LPSYSTEMTIME lpSystemTime)
Definition: time.c:178
unsigned int BOOL
Definition: ntddk_ex.h:94
#define CREATE_NEW_CONSOLE
Definition: winbase.h:180
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
DWORD cb
Definition: winbase.h:817
#define JOB_NONINTERACTIVE
Definition: lmat.h:11
WINE_DEFAULT_DEBUG_CHANNEL(schedsvc)
WORD Reserved
Definition: job.c:24
struct _SCHEDULE SCHEDULE
#define swprintf(buf, format,...)
Definition: sprintf.c:56
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned long DWORD
Definition: ntddk_ex.h:95
static VOID ReScheduleJob(PJOB pJob)
Definition: job.c:88
WORD wSecond
Definition: winbase.h:876
WORD wMilliseconds
Definition: winbase.h:877
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)
static const WCHAR L[]
Definition: oid.c:1087
struct tm * Now
Definition: output.c:19
WORD wShowWindow
Definition: winbase.h:829
Definition: typedefs.h:117
uint32_t DWORD_PTR
Definition: typedefs.h:63
#define RegEnumKeyEx
Definition: winreg.h:510
NTSYSAPI ULONG NTAPI RtlRandomEx(PULONG Seed)
LIST_ENTRY StartEntry
Definition: precomp.h:35
#define ERR(fmt,...)
Definition: debug.h:109
#define _In_
Definition: no_sal2.h:204
UCHAR Flags
Definition: job.c:23
WORD wDay
Definition: winbase.h:873
#define RegOpenKeyEx
Definition: winreg.h:520
BOOL WINAPI SystemTimeToFileTime(IN CONST SYSTEMTIME *lpSystemTime, OUT LPFILETIME lpFileTime)
Definition: time.c:148
DWORD JobTime
Definition: job.c:20
static ULONG Timeout
Definition: ping.c:61
WORD wHour
Definition: winbase.h:874
#define JOB_NAME_LENGTH
Definition: precomp.h:23
DWORD dwJobCount
Definition: job.c:28
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
#define RegDeleteKey
Definition: winreg.h:502
LONG DeleteJob(_In_ PJOB pJob)
Definition: job.c:281
Definition: job.c:18
LONG LoadJobs(VOID)
Definition: job.c:315
#define JOB_RUN_PERIODICALLY
Definition: lmat.h:7
VOID DumpStartList(_In_ PLIST_ENTRY StartListHead)
Definition: job.c:582
unsigned int ULONG
Definition: retypes.h:1
DWORD DaysOfMonth
Definition: precomp.h:41
DWORD dwFlags
Definition: winbase.h:828
DWORD dwNextJobId
Definition: job.c:27
VOID CalculateNextStartTime(_In_ PJOB pJob)
Definition: job.c:468
#define INFINITE
Definition: serial.h:102
DWORD DaysOfMonth
Definition: job.c:21
BYTE * PBYTE
Definition: pedump.c:66
Definition: precomp.h:31
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define HeapFree(x, y, z)
Definition: compat.h:394
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:54
#define RegSetValueEx
Definition: winreg.h:533
DWORD dwLowDateTime
Definition: mapidefs.h:65
#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)