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>
9 /* INCLUDES *****************************************************************/
13 WINE_DEFAULT_DEBUG_CHANNEL(schedsvc
);
16 /* GLOBALS ******************************************************************/
18 typedef struct _SCHEDULE
25 } SCHEDULE
, PSCHEDULE
;
27 DWORD dwNextJobId
= 0;
29 LIST_ENTRY JobListHead
;
30 RTL_RESOURCE JobListLock
;
32 LIST_ENTRY StartListHead
;
33 RTL_RESOURCE StartListLock
;
36 /* FUNCTIONS *****************************************************************/
44 WCHAR szNameBuffer
[9];
46 ULONG ulSeed
, ulValue
;
50 GetSystemTimeAsFileTime(&SystemTime
);
51 ulSeed
= SystemTime
.dwLowDateTime
;
54 ulValue
= RtlRandomEx(&ulSeed
);
55 swprintf(szNameBuffer
, L
"%08lx", ulValue
);
58 lError
= RegOpenKeyEx(hJobsKey
,
63 if (lError
!= ERROR_SUCCESS
)
65 wcscpy(pszJobName
, szNameBuffer
);
79 HKEY hJobsKey
= NULL
, hJobKey
= NULL
;
84 lError
= RegCreateKeyExW(HKEY_LOCAL_MACHINE
,
85 L
"System\\CurrentControlSet\\Services\\Schedule\\Jobs",
88 REG_OPTION_NON_VOLATILE
,
93 if (lError
!= ERROR_SUCCESS
)
96 GetJobName(hJobsKey
, pJob
->Name
);
98 lError
= RegCreateKeyExW(hJobsKey
,
102 REG_OPTION_NON_VOLATILE
,
107 if (lError
!= ERROR_SUCCESS
)
110 Schedule
.JobTime
= pJob
->JobTime
;
111 Schedule
.DaysOfMonth
= pJob
->DaysOfMonth
;
112 Schedule
.DaysOfWeek
= pJob
->DaysOfWeek
;
113 Schedule
.Flags
= pJob
->Flags
;
115 lError
= RegSetValueEx(hJobKey
,
121 if (lError
!= ERROR_SUCCESS
)
124 lError
= RegSetValueEx(hJobKey
,
128 (PBYTE
)pJob
->Command
,
129 (wcslen(pJob
->Command
) + 1) * sizeof(WCHAR
));
130 if (lError
!= ERROR_SUCCESS
)
135 RegCloseKey(hJobKey
);
137 if (hJobsKey
!= NULL
)
138 RegCloseKey(hJobsKey
);
148 HKEY hJobsKey
= NULL
;
151 TRACE("DeleteJob()\n");
153 lError
= RegCreateKeyExW(HKEY_LOCAL_MACHINE
,
154 L
"System\\CurrentControlSet\\Services\\Schedule\\Jobs",
157 REG_OPTION_NON_VOLATILE
,
162 if (lError
!= ERROR_SUCCESS
)
165 lError
= RegDeleteKey(hJobsKey
,
167 if (lError
!= ERROR_SUCCESS
)
171 if (hJobsKey
!= NULL
)
172 RegCloseKey(hJobsKey
);
182 WCHAR szNameBuffer
[32];
183 DWORD dwNameLength
, dwIndex
, dwSize
;
184 HKEY hJobsKey
= NULL
, hJobKey
= NULL
;
188 TRACE("LoadJobs()\n");
190 lError
= RegCreateKeyExW(HKEY_LOCAL_MACHINE
,
191 L
"System\\CurrentControlSet\\Services\\Schedule\\Jobs",
194 REG_OPTION_NON_VOLATILE
,
199 if (lError
!= ERROR_SUCCESS
)
202 for (dwIndex
= 0; dwIndex
< 1000; dwIndex
++)
205 lError
= RegEnumKeyEx(hJobsKey
,
213 if (lError
!= ERROR_SUCCESS
)
215 lError
= ERROR_SUCCESS
;
219 TRACE("KeyName: %S\n", szNameBuffer
);
221 lError
= RegOpenKeyEx(hJobsKey
,
226 if (lError
!= ERROR_SUCCESS
)
229 dwSize
= sizeof(SCHEDULE
);
230 lError
= RegQueryValueEx(hJobKey
,
236 if (lError
== ERROR_SUCCESS
)
239 RegQueryValueEx(hJobKey
,
247 /* Allocate a new job object */
248 pJob
= HeapAlloc(GetProcessHeap(),
250 sizeof(JOB
) + dwSize
- sizeof(WCHAR
));
253 lError
= ERROR_OUTOFMEMORY
;
257 lError
= RegQueryValueEx(hJobKey
,
261 (PBYTE
)pJob
->Command
,
263 if (lError
!= ERROR_SUCCESS
)
266 wcscpy(pJob
->Name
, szNameBuffer
);
267 pJob
->JobTime
= Schedule
.JobTime
;
268 pJob
->DaysOfMonth
= Schedule
.DaysOfMonth
;
269 pJob
->DaysOfWeek
= Schedule
.DaysOfWeek
;
270 pJob
->Flags
= Schedule
.Flags
;
272 /* Acquire the job list lock exclusively */
273 RtlAcquireResourceExclusive(&JobListLock
, TRUE
);
275 /* Assign a new job ID */
276 pJob
->JobId
= dwNextJobId
++;
279 /* Append the new job to the job list */
280 InsertTailList(&JobListHead
, &pJob
->JobEntry
);
282 /* Release the job list lock */
283 RtlReleaseResource(&JobListLock
);
285 // Calculate start time
287 // Insert job into the start list
289 // Update the start timer
295 RegCloseKey(hJobKey
);
301 HeapFree(GetProcessHeap(), 0, pJob
);
304 RegCloseKey(hJobKey
);
306 if (hJobsKey
!= NULL
)
307 RegCloseKey(hJobsKey
);
315 CalculateNextStartTime(PJOB pJob
)
324 Now
= (DWORD_PTR
)Time
.wHour
* 3600000 +
325 (DWORD_PTR
)Time
.wMinute
* 60000;
326 if (pJob
->JobTime
> Now
)
329 if (pJob
->DaysOfMonth
!= 0)
332 for (i
= Time
.wDay
- 1; i
< 32; i
++)
334 if (pJob
->DaysOfMonth
&& (1 << i
))
340 ERR("Next day this month: %hu\n", wDay
);
342 else if (pJob
->DaysOfWeek
!= 0)