- Merge from trunk up to r45543
[reactos.git] / dll / win32 / kernel32 / process / job.c
1 /* $Id$
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS system libraries
5 * FILE: lib/kernel32/process/job.c
6 * PURPOSE: Job functions
7 * PROGRAMMER: Thomas Weidenmueller <w3seek@reactos.com>
8 * UPDATE HISTORY:
9 * Created 9/23/2004
10 */
11
12 /* INCLUDES ****************************************************************/
13
14 #include <k32.h>
15
16 #define NDEBUG
17 #include <debug.h>
18
19 /* FUNCTIONS ****************************************************************/
20
21
22 /*
23 * @implemented
24 */
25 HANDLE
26 WINAPI
27 CreateJobObjectA(LPSECURITY_ATTRIBUTES lpJobAttributes,
28 LPCSTR lpName)
29 {
30 HANDLE hJob;
31 ANSI_STRING AnsiName;
32 UNICODE_STRING UnicodeName;
33
34 if (lpName != NULL)
35 {
36 NTSTATUS Status;
37
38 RtlInitAnsiString(&AnsiName, lpName);
39 Status = RtlAnsiStringToUnicodeString(&UnicodeName, &AnsiName, TRUE);
40 if (!NT_SUCCESS(Status))
41 {
42 SetLastErrorByStatus(Status);
43 return FALSE;
44 }
45 }
46
47 hJob = CreateJobObjectW(lpJobAttributes,
48 ((lpName != NULL) ? UnicodeName.Buffer : NULL));
49
50 if (lpName != NULL)
51 {
52 RtlFreeUnicodeString(&UnicodeName);
53 }
54
55 return hJob;
56 }
57
58
59 /*
60 * @implemented
61 */
62 HANDLE
63 WINAPI
64 CreateJobObjectW(LPSECURITY_ATTRIBUTES lpJobAttributes,
65 LPCWSTR lpName)
66 {
67 UNICODE_STRING JobName;
68 OBJECT_ATTRIBUTES ObjectAttributes;
69 ULONG Attributes = 0;
70 PVOID SecurityDescriptor;
71 HANDLE hJob;
72 NTSTATUS Status;
73
74 if (lpName != NULL)
75 {
76 RtlInitUnicodeString(&JobName, lpName);
77 }
78
79 if (lpJobAttributes != NULL)
80 {
81 if (lpJobAttributes->bInheritHandle)
82 {
83 Attributes |= OBJ_INHERIT;
84 }
85
86 SecurityDescriptor = lpJobAttributes->lpSecurityDescriptor;
87 }
88 else
89 {
90 SecurityDescriptor = NULL;
91 }
92
93 InitializeObjectAttributes(&ObjectAttributes,
94 ((lpName != NULL) ? &JobName : NULL),
95 Attributes,
96 NULL,
97 SecurityDescriptor);
98
99 Status = NtCreateJobObject(&hJob,
100 JOB_OBJECT_ALL_ACCESS,
101 &ObjectAttributes);
102 if (!NT_SUCCESS(Status))
103 {
104 SetLastErrorByStatus(Status);
105 return NULL;
106 }
107
108 return hJob;
109 }
110
111
112 /*
113 * @implemented
114 */
115 HANDLE
116 WINAPI
117 OpenJobObjectW(DWORD dwDesiredAccess,
118 BOOL bInheritHandle,
119 LPCWSTR lpName)
120 {
121 OBJECT_ATTRIBUTES ObjectAttributes;
122 UNICODE_STRING JobName;
123 HANDLE hJob;
124 NTSTATUS Status;
125
126 if (lpName == NULL)
127 {
128 SetLastError(ERROR_INVALID_PARAMETER);
129 return NULL;
130 }
131
132 RtlInitUnicodeString(&JobName, lpName);
133
134 InitializeObjectAttributes(&ObjectAttributes,
135 &JobName,
136 (bInheritHandle ? OBJ_INHERIT : 0),
137 NULL,
138 NULL);
139
140 Status = NtOpenJobObject(&hJob,
141 dwDesiredAccess,
142 &ObjectAttributes);
143 if (!NT_SUCCESS(Status))
144 {
145 SetLastErrorByStatus(Status);
146 return NULL;
147 }
148
149 return hJob;
150 }
151
152
153 /*
154 * @implemented
155 */
156 HANDLE
157 WINAPI
158 OpenJobObjectA(DWORD dwDesiredAccess,
159 BOOL bInheritHandle,
160 LPCSTR lpName)
161 {
162 ANSI_STRING AnsiName;
163 UNICODE_STRING UnicodeName;
164 HANDLE hJob;
165 NTSTATUS Status;
166
167 if (lpName == NULL)
168 {
169 SetLastError(ERROR_INVALID_PARAMETER);
170 return NULL;
171 }
172
173 RtlInitAnsiString(&AnsiName, lpName);
174 Status = RtlAnsiStringToUnicodeString(&UnicodeName, &AnsiName, TRUE);
175 if (!NT_SUCCESS(Status))
176 {
177 SetLastErrorByStatus(Status);
178 return FALSE;
179 }
180
181 hJob = OpenJobObjectW(dwDesiredAccess,
182 bInheritHandle,
183 UnicodeName.Buffer);
184
185 RtlFreeUnicodeString(&UnicodeName);
186 return hJob;
187 }
188
189
190 /*
191 * @implemented
192 */
193 BOOL
194 WINAPI
195 IsProcessInJob(HANDLE ProcessHandle,
196 HANDLE JobHandle,
197 PBOOL Result)
198 {
199 NTSTATUS Status;
200
201 Status = NtIsProcessInJob(ProcessHandle, JobHandle);
202 if (NT_SUCCESS(Status))
203 {
204 *Result = (Status == STATUS_PROCESS_IN_JOB);
205 return TRUE;
206 }
207
208 SetLastErrorByStatus(Status);
209 return FALSE;
210 }
211
212
213 /*
214 * @implemented
215 */
216 BOOL
217 WINAPI
218 AssignProcessToJobObject(HANDLE hJob,
219 HANDLE hProcess)
220 {
221 NTSTATUS Status;
222
223 Status = NtAssignProcessToJobObject(hJob, hProcess);
224 if (!NT_SUCCESS(Status))
225 {
226 SetLastErrorByStatus(Status);
227 return FALSE;
228 }
229
230 return TRUE;
231 }
232
233
234 /*
235 * @implemented
236 */
237 BOOL
238 WINAPI
239 QueryInformationJobObject(HANDLE hJob,
240 JOBOBJECTINFOCLASS JobObjectInformationClass,
241 LPVOID lpJobObjectInformation,
242 DWORD cbJobObjectInformationLength,
243 LPDWORD lpReturnLength)
244 {
245 NTSTATUS Status;
246
247 Status = NtQueryInformationJobObject(hJob,
248 JobObjectInformationClass,
249 lpJobObjectInformation,
250 cbJobObjectInformationLength,
251 lpReturnLength);
252 if (NT_SUCCESS(Status))
253 {
254 PJOBOBJECT_BASIC_LIMIT_INFORMATION BasicInfo;
255
256 switch (JobObjectInformationClass)
257 {
258 case JobObjectBasicLimitInformation:
259 BasicInfo = (PJOBOBJECT_BASIC_LIMIT_INFORMATION)lpJobObjectInformation;
260 break;
261
262 case JobObjectExtendedLimitInformation:
263 BasicInfo = &((PJOBOBJECT_EXTENDED_LIMIT_INFORMATION)lpJobObjectInformation)->BasicLimitInformation;
264 break;
265
266 default:
267 BasicInfo = NULL;
268 break;
269 }
270
271 if (BasicInfo != NULL)
272 {
273 /* we need to convert the process priority classes in the
274 JOBOBJECT_BASIC_LIMIT_INFORMATION structure the same way as
275 GetPriorityClass() converts it! */
276 switch (BasicInfo->PriorityClass)
277 {
278 case PROCESS_PRIORITY_CLASS_IDLE:
279 BasicInfo->PriorityClass = IDLE_PRIORITY_CLASS;
280 break;
281
282 case PROCESS_PRIORITY_CLASS_BELOW_NORMAL:
283 BasicInfo->PriorityClass = BELOW_NORMAL_PRIORITY_CLASS;
284 break;
285
286 case PROCESS_PRIORITY_CLASS_NORMAL:
287 BasicInfo->PriorityClass = NORMAL_PRIORITY_CLASS;
288 break;
289
290 case PROCESS_PRIORITY_CLASS_ABOVE_NORMAL:
291 BasicInfo->PriorityClass = ABOVE_NORMAL_PRIORITY_CLASS;
292 break;
293
294 case PROCESS_PRIORITY_CLASS_HIGH:
295 BasicInfo->PriorityClass = HIGH_PRIORITY_CLASS;
296 break;
297
298 case PROCESS_PRIORITY_CLASS_REALTIME:
299 BasicInfo->PriorityClass = REALTIME_PRIORITY_CLASS;
300 break;
301
302 default:
303 BasicInfo->PriorityClass = NORMAL_PRIORITY_CLASS;
304 break;
305 }
306 }
307
308 return TRUE;
309 }
310
311 SetLastErrorByStatus(Status);
312 return FALSE;
313 }
314
315
316 /*
317 * @implemented
318 */
319 BOOL
320 WINAPI
321 SetInformationJobObject(HANDLE hJob,
322 JOBOBJECTINFOCLASS JobObjectInformationClass,
323 LPVOID lpJobObjectInformation,
324 DWORD cbJobObjectInformationLength)
325 {
326 JOBOBJECT_EXTENDED_LIMIT_INFORMATION ExtendedLimitInfo;
327 PJOBOBJECT_BASIC_LIMIT_INFORMATION BasicInfo;
328 PVOID ObjectInfo;
329 NTSTATUS Status;
330
331 switch (JobObjectInformationClass)
332 {
333 case JobObjectBasicLimitInformation:
334 if (cbJobObjectInformationLength != sizeof(JOBOBJECT_BASIC_LIMIT_INFORMATION))
335 {
336 SetLastError(ERROR_BAD_LENGTH);
337 return FALSE;
338 }
339
340 ObjectInfo = &ExtendedLimitInfo.BasicLimitInformation;
341 BasicInfo = (PJOBOBJECT_BASIC_LIMIT_INFORMATION)ObjectInfo;
342 RtlCopyMemory(ObjectInfo, lpJobObjectInformation, cbJobObjectInformationLength);
343 break;
344
345 case JobObjectExtendedLimitInformation:
346 if (cbJobObjectInformationLength != sizeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION))
347 {
348 SetLastError(ERROR_BAD_LENGTH);
349 return FALSE;
350 }
351
352 ObjectInfo = &ExtendedLimitInfo;
353 BasicInfo = &ExtendedLimitInfo.BasicLimitInformation;
354 RtlCopyMemory(ObjectInfo, lpJobObjectInformation, cbJobObjectInformationLength);
355 break;
356
357 default:
358 ObjectInfo = lpJobObjectInformation;
359 BasicInfo = NULL;
360 break;
361 }
362
363 if (BasicInfo != NULL)
364 {
365 /* we need to convert the process priority classes in the
366 JOBOBJECT_BASIC_LIMIT_INFORMATION structure the same way as
367 SetPriorityClass() converts it! */
368 switch(BasicInfo->PriorityClass)
369 {
370 case IDLE_PRIORITY_CLASS:
371 BasicInfo->PriorityClass = PROCESS_PRIORITY_CLASS_IDLE;
372 break;
373
374 case BELOW_NORMAL_PRIORITY_CLASS:
375 BasicInfo->PriorityClass = PROCESS_PRIORITY_CLASS_BELOW_NORMAL;
376 break;
377
378 case NORMAL_PRIORITY_CLASS:
379 BasicInfo->PriorityClass = PROCESS_PRIORITY_CLASS_NORMAL;
380 break;
381
382 case ABOVE_NORMAL_PRIORITY_CLASS:
383 BasicInfo->PriorityClass = PROCESS_PRIORITY_CLASS_ABOVE_NORMAL;
384 break;
385
386 case HIGH_PRIORITY_CLASS:
387 BasicInfo->PriorityClass = PROCESS_PRIORITY_CLASS_HIGH;
388 break;
389
390 case REALTIME_PRIORITY_CLASS:
391 BasicInfo->PriorityClass = PROCESS_PRIORITY_CLASS_REALTIME;
392 break;
393
394 default:
395 BasicInfo->PriorityClass = PROCESS_PRIORITY_CLASS_NORMAL;
396 break;
397 }
398 }
399
400 Status = NtSetInformationJobObject(hJob,
401 JobObjectInformationClass,
402 ObjectInfo,
403 cbJobObjectInformationLength);
404 if (!NT_SUCCESS(Status))
405 {
406 SetLastErrorByStatus(Status);
407 return FALSE;
408 }
409
410 return TRUE;
411 }
412
413
414 /*
415 * @implemented
416 */
417 BOOL
418 WINAPI
419 TerminateJobObject(HANDLE hJob,
420 UINT uExitCode)
421 {
422 NTSTATUS Status;
423
424 Status = NtTerminateJobObject(hJob, uExitCode);
425 if (!NT_SUCCESS(Status))
426 {
427 SetLastErrorByStatus(Status);
428 return FALSE;
429 }
430
431 return TRUE;
432 }
433
434 /* EOF */