ReactOS  0.4.15-dev-1150-g593bcce
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 static WORD wDaysArray[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
36 
37 
38 /* FUNCTIONS *****************************************************************/
39 
40 DWORD
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 }
86 
87 
88 static
89 VOID
91  PJOB pJob)
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 }
120 
121 
122 VOID
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 }
174 
175 
176 static
177 VOID
179  HKEY hJobsKey,
180  PWSTR pszJobName)
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 }
210 
211 
212 LONG
214  _In_ PJOB pJob)
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 }
280 
281 
282 LONG
284  _In_ PJOB pJob)
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 }
314 
315 
316 LONG
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 }
452 
453 
454 static
455 WORD
457  WORD wMonth,
458  WORD wYear)
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 {
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 }
600 
601 
602 VOID
605  _In_ PJOB pJob)
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 }
651 
652 
653 VOID
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 }
670 
671 /* 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
static WORD wDaysArray[13]
Definition: job.c:35
VOID WINAPI GetSystemTimeAsFileTime(OUT PFILETIME lpFileTime)
Definition: time.c:128
#define CloseHandle
Definition: compat.h:487
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:884
VOID RunNextJob(VOID)
Definition: job.c:123
#define REG_BINARY
Definition: nt_native.h:1496
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
uint16_t * PWSTR
Definition: typedefs.h:56
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
static VOID GetJobName(HKEY hJobsKey, PWSTR pszJobName)
Definition: job.c:178
WORD wDayOfWeek
Definition: winbase.h:885
UCHAR DaysOfWeek
Definition: job.c:22
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1044
#define ZeroMemory
Definition: winbase.h:1648
WCHAR Name[JOB_NAME_LENGTH]
Definition: precomp.h:37
struct _SCHEDULE PSCHEDULE
#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)
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
LIST_ENTRY JobListHead
Definition: job.c:29
struct _ULARGE_INTEGER::@3873 u
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
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
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
UCHAR Flags
Definition: precomp.h:43
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:832
#define STARTF_INHERITDESKTOP
Definition: undocuser.h:162
LONG SaveJob(_In_ PJOB pJob)
Definition: job.c:213
WORD wMinute
Definition: winbase.h:888
smooth NULL
Definition: ftsmooth.c:416
LPWSTR lpTitle
Definition: winbase.h:833
DWORD GetNextJobTimeout(VOID)
Definition: job.c:41
VOID WINAPI GetLocalTime(OUT LPSYSTEMTIME lpSystemTime)
Definition: time.c:286
#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:4595
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
#define KEY_WRITE
Definition: nt_native.h:1031
UCHAR DaysOfWeek
Definition: precomp.h:42
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define TRACE(s)
Definition: solgame.cpp:4
BOOL WINAPI FileTimeToSystemTime(IN CONST FILETIME *lpFileTime, OUT LPSYSTEMTIME lpSystemTime)
Definition: time.c:188
#define CREATE_NEW_CONSOLE
Definition: winbase.h:180
#define GetProcessHeap()
Definition: compat.h:484
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
DWORD cb
Definition: winbase.h:830
__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 swprintf(buf, format,...)
Definition: sprintf.c:56
#define CopyMemory
Definition: winbase.h:1646
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned long DWORD
Definition: ntddk_ex.h:95
static VOID ReScheduleJob(PJOB pJob)
Definition: job.c:90
WORD wSecond
Definition: winbase.h:889
WORD wMilliseconds
Definition: winbase.h:890
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:1250
WORD wShowWindow
Definition: winbase.h:842
Definition: typedefs.h:119
uint32_t DWORD_PTR
Definition: typedefs.h:65
#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:110
#define _In_
Definition: no_sal2.h:204
UCHAR Flags
Definition: job.c:23
WORD wDay
Definition: winbase.h:886
#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
static ULONG Timeout
Definition: ping.c:61
WORD wHour
Definition: winbase.h:887
#define JOB_NAME_LENGTH
Definition: precomp.h:23
DWORD dwJobCount
Definition: job.c:28
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
#define RegDeleteKey
Definition: winreg.h:502
LONG DeleteJob(_In_ PJOB pJob)
Definition: job.c:283
Definition: job.c:18
LONG LoadJobs(VOID)
Definition: job.c:317
#define JOB_RUN_PERIODICALLY
Definition: lmat.h:7
VOID DumpStartList(_In_ PLIST_ENTRY StartListHead)
Definition: job.c:654
unsigned int ULONG
Definition: retypes.h:1
DWORD DaysOfMonth
Definition: precomp.h:41
DWORD dwFlags
Definition: winbase.h:841
DWORD dwNextJobId
Definition: job.c:27
static WORD DaysOfMonth(WORD wMonth, WORD wYear)
Definition: job.c:456
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:483
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)