beebc4ff15815d1a5ffc74f5ae337106cb392b54
[reactos.git] / reactos / base / services / schedsvc / job.c
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
13 WINE_DEFAULT_DEBUG_CHANNEL(schedsvc);
14
15
16 /* GLOBALS ******************************************************************/
17
18 typedef struct _SCHEDULE
19 {
20 DWORD JobTime;
21 DWORD DaysOfMonth;
22 UCHAR DaysOfWeek;
23 UCHAR Flags;
24 WORD Reserved;
25 } SCHEDULE, PSCHEDULE;
26
27 DWORD dwNextJobId = 0;
28 DWORD dwJobCount = 0;
29 LIST_ENTRY JobListHead;
30 RTL_RESOURCE JobListLock;
31
32 LIST_ENTRY StartListHead;
33 RTL_RESOURCE StartListLock;
34
35
36 /* FUNCTIONS *****************************************************************/
37
38 static
39 VOID
40 GetJobName(
41 HKEY hJobsKey,
42 PWSTR pszJobName)
43 {
44 WCHAR szNameBuffer[9];
45 FILETIME SystemTime;
46 ULONG ulSeed, ulValue;
47 HKEY hKey;
48 LONG lError;
49
50 GetSystemTimeAsFileTime(&SystemTime);
51 ulSeed = SystemTime.dwLowDateTime;
52 for (;;)
53 {
54 ulValue = RtlRandomEx(&ulSeed);
55 swprintf(szNameBuffer, L"%08lx", ulValue);
56
57 hKey = NULL;
58 lError = RegOpenKeyEx(hJobsKey,
59 szNameBuffer,
60 0,
61 KEY_READ,
62 &hKey);
63 if (lError != ERROR_SUCCESS)
64 {
65 wcscpy(pszJobName, szNameBuffer);
66 return;
67 }
68
69 RegCloseKey(hKey);
70 }
71 }
72
73
74 LONG
75 SaveJob(
76 _In_ PJOB pJob)
77 {
78 SCHEDULE Schedule;
79 HKEY hJobsKey = NULL, hJobKey = NULL;
80 LONG lError;
81
82 TRACE("SaveJob()\n");
83
84 lError = RegCreateKeyExW(HKEY_LOCAL_MACHINE,
85 L"System\\CurrentControlSet\\Services\\Schedule\\Jobs",
86 0,
87 NULL,
88 REG_OPTION_NON_VOLATILE,
89 KEY_WRITE,
90 NULL,
91 &hJobsKey,
92 NULL);
93 if (lError != ERROR_SUCCESS)
94 goto done;
95
96 GetJobName(hJobsKey, pJob->Name);
97
98 lError = RegCreateKeyExW(hJobsKey,
99 pJob->Name,
100 0,
101 NULL,
102 REG_OPTION_NON_VOLATILE,
103 KEY_WRITE,
104 NULL,
105 &hJobKey,
106 NULL);
107 if (lError != ERROR_SUCCESS)
108 goto done;
109
110 Schedule.JobTime = pJob->JobTime;
111 Schedule.DaysOfMonth = pJob->DaysOfMonth;
112 Schedule.DaysOfWeek = pJob->DaysOfWeek;
113 Schedule.Flags = pJob->Flags;
114
115 lError = RegSetValueEx(hJobKey,
116 L"Schedule",
117 0,
118 REG_BINARY,
119 (PBYTE)&Schedule,
120 sizeof(Schedule));
121 if (lError != ERROR_SUCCESS)
122 goto done;
123
124 lError = RegSetValueEx(hJobKey,
125 L"Command",
126 0,
127 REG_SZ,
128 (PBYTE)pJob->Command,
129 (wcslen(pJob->Command) + 1) * sizeof(WCHAR));
130 if (lError != ERROR_SUCCESS)
131 goto done;
132
133 done:
134 if (hJobKey != NULL)
135 RegCloseKey(hJobKey);
136
137 if (hJobsKey != NULL)
138 RegCloseKey(hJobsKey);
139
140 return lError;
141 }
142
143
144 LONG
145 DeleteJob(
146 _In_ PJOB pJob)
147 {
148 HKEY hJobsKey = NULL;
149 LONG lError;
150
151 TRACE("DeleteJob()\n");
152
153 lError = RegCreateKeyExW(HKEY_LOCAL_MACHINE,
154 L"System\\CurrentControlSet\\Services\\Schedule\\Jobs",
155 0,
156 NULL,
157 REG_OPTION_NON_VOLATILE,
158 KEY_WRITE,
159 NULL,
160 &hJobsKey,
161 NULL);
162 if (lError != ERROR_SUCCESS)
163 goto done;
164
165 lError = RegDeleteKey(hJobsKey,
166 pJob->Name);
167 if (lError != ERROR_SUCCESS)
168 goto done;
169
170 done:
171 if (hJobsKey != NULL)
172 RegCloseKey(hJobsKey);
173
174 return lError;
175 }
176
177
178 LONG
179 LoadJobs(VOID)
180 {
181 SCHEDULE Schedule;
182 WCHAR szNameBuffer[32];
183 DWORD dwNameLength, dwIndex, dwSize;
184 HKEY hJobsKey = NULL, hJobKey = NULL;
185 PJOB pJob = NULL;
186 LONG lError;
187
188 TRACE("LoadJobs()\n");
189
190 lError = RegCreateKeyExW(HKEY_LOCAL_MACHINE,
191 L"System\\CurrentControlSet\\Services\\Schedule\\Jobs",
192 0,
193 NULL,
194 REG_OPTION_NON_VOLATILE,
195 KEY_READ,
196 NULL,
197 &hJobsKey,
198 NULL);
199 if (lError != ERROR_SUCCESS)
200 goto done;
201
202 for (dwIndex = 0; dwIndex < 1000; dwIndex++)
203 {
204 dwNameLength = 32;
205 lError = RegEnumKeyEx(hJobsKey,
206 dwIndex,
207 szNameBuffer,
208 &dwNameLength,
209 NULL,
210 NULL,
211 NULL,
212 NULL);
213 if (lError != ERROR_SUCCESS)
214 {
215 lError = ERROR_SUCCESS;
216 break;
217 }
218
219 TRACE("KeyName: %S\n", szNameBuffer);
220
221 lError = RegOpenKeyEx(hJobsKey,
222 szNameBuffer,
223 0,
224 KEY_READ,
225 &hJobKey);
226 if (lError != ERROR_SUCCESS)
227 break;
228
229 dwSize = sizeof(SCHEDULE);
230 lError = RegQueryValueEx(hJobKey,
231 L"Schedule",
232 NULL,
233 NULL,
234 (PBYTE)&Schedule,
235 &dwSize);
236 if (lError == ERROR_SUCCESS)
237 {
238 dwSize = 0;
239 RegQueryValueEx(hJobKey,
240 L"Command",
241 NULL,
242 NULL,
243 NULL,
244 &dwSize);
245 if (dwSize != 0)
246 {
247 /* Allocate a new job object */
248 pJob = HeapAlloc(GetProcessHeap(),
249 HEAP_ZERO_MEMORY,
250 sizeof(JOB) + dwSize - sizeof(WCHAR));
251 if (pJob == NULL)
252 {
253 lError = ERROR_OUTOFMEMORY;
254 break;
255 }
256
257 lError = RegQueryValueEx(hJobKey,
258 L"Command",
259 NULL,
260 NULL,
261 (PBYTE)pJob->Command,
262 &dwSize);
263 if (lError != ERROR_SUCCESS)
264 break;
265
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;
271
272 /* Acquire the job list lock exclusively */
273 RtlAcquireResourceExclusive(&JobListLock, TRUE);
274
275 /* Assign a new job ID */
276 pJob->JobId = dwNextJobId++;
277 dwJobCount++;
278
279 /* Append the new job to the job list */
280 InsertTailList(&JobListHead, &pJob->JobEntry);
281
282 /* Release the job list lock */
283 RtlReleaseResource(&JobListLock);
284
285 // Calculate start time
286
287 // Insert job into the start list
288
289 // Update the start timer
290
291 pJob = NULL;
292 }
293 }
294
295 RegCloseKey(hJobKey);
296 hJobKey = NULL;
297 }
298
299 done:
300 if (pJob != NULL)
301 HeapFree(GetProcessHeap(), 0, pJob);
302
303 if (hJobKey != NULL)
304 RegCloseKey(hJobKey);
305
306 if (hJobsKey != NULL)
307 RegCloseKey(hJobsKey);
308
309 return lError;
310 }
311
312
313 #if 0
314 VOID
315 CalculateNextStartTime(PJOB pJob)
316 {
317 SYSTEMTIME Time;
318 DWORD_PTR JobTime;
319 WORD wDay;
320 BOOL bToday = FALSE;
321
322 GetLocalTime(&Time);
323
324 Now = (DWORD_PTR)Time.wHour * 3600000 +
325 (DWORD_PTR)Time.wMinute * 60000;
326 if (pJob->JobTime > Now)
327 bToday = TRUE;
328
329 if (pJob->DaysOfMonth != 0)
330 {
331 wDay = 0;
332 for (i = Time.wDay - 1; i < 32; i++)
333 {
334 if (pJob->DaysOfMonth && (1 << i))
335 {
336 wDay = i;
337 break;
338 }
339 }
340 ERR("Next day this month: %hu\n", wDay);
341 }
342 else if (pJob->DaysOfWeek != 0)
343 {
344
345 }
346 }
347 #endif