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>
12 /* INCLUDES ****************************************************************/
19 /* FUNCTIONS ****************************************************************/
27 CreateJobObjectA(LPSECURITY_ATTRIBUTES lpJobAttributes
,
32 UNICODE_STRING UnicodeName
;
38 RtlInitAnsiString(&AnsiName
, lpName
);
39 Status
= RtlAnsiStringToUnicodeString(&UnicodeName
, &AnsiName
, TRUE
);
40 if(!NT_SUCCESS(Status
))
42 SetLastErrorByStatus(Status
);
47 hJob
= CreateJobObjectW(lpJobAttributes
,
48 ((lpName
!= NULL
) ? UnicodeName
.Buffer
: NULL
));
52 RtlFreeUnicodeString(&UnicodeName
);
63 CreateJobObjectW(LPSECURITY_ATTRIBUTES lpJobAttributes
,
66 UNICODE_STRING JobName
;
67 OBJECT_ATTRIBUTES ObjectAttributes
;
69 PVOID SecurityDescriptor
;
75 RtlInitUnicodeString(&JobName
, lpName
);
78 if(lpJobAttributes
!= NULL
)
80 if(lpJobAttributes
->bInheritHandle
)
82 Attributes
|= OBJ_INHERIT
;
84 SecurityDescriptor
= lpJobAttributes
->lpSecurityDescriptor
;
88 SecurityDescriptor
= NULL
;
91 InitializeObjectAttributes(&ObjectAttributes
,
92 ((lpName
!= NULL
) ? &JobName
: NULL
),
97 Status
= NtCreateJobObject(&hJob
,
98 JOB_OBJECT_ALL_ACCESS
,
100 if(!NT_SUCCESS(Status
))
102 SetLastErrorByStatus(Status
);
115 OpenJobObjectW(DWORD dwDesiredAccess
,
119 OBJECT_ATTRIBUTES ObjectAttributes
;
120 UNICODE_STRING JobName
;
126 SetLastError(ERROR_INVALID_PARAMETER
);
130 RtlInitUnicodeString(&JobName
, lpName
);
132 InitializeObjectAttributes(&ObjectAttributes
,
134 (bInheritHandle
? OBJ_INHERIT
: 0),
138 Status
= NtOpenJobObject(&hJob
,
142 if(!NT_SUCCESS(Status
))
144 SetLastErrorByStatus(Status
);
157 OpenJobObjectA(DWORD dwDesiredAccess
,
161 ANSI_STRING AnsiName
;
162 UNICODE_STRING UnicodeName
;
168 SetLastError(ERROR_INVALID_PARAMETER
);
172 RtlInitAnsiString(&AnsiName
, lpName
);
173 Status
= RtlAnsiStringToUnicodeString(&UnicodeName
, &AnsiName
, TRUE
);
174 if(!NT_SUCCESS(Status
))
176 SetLastErrorByStatus(Status
);
180 hJob
= OpenJobObjectW(dwDesiredAccess
,
184 RtlFreeUnicodeString(&UnicodeName
);
194 IsProcessInJob(HANDLE ProcessHandle
,
200 Status
= NtIsProcessInJob(ProcessHandle
, JobHandle
);
201 if(NT_SUCCESS(Status
))
203 *Result
= (Status
== STATUS_PROCESS_IN_JOB
);
207 SetLastErrorByStatus(Status
);
217 AssignProcessToJobObject(HANDLE hJob
,
222 Status
= NtAssignProcessToJobObject(hJob
, hProcess
);
223 if(!NT_SUCCESS(Status
))
225 SetLastErrorByStatus(Status
);
237 QueryInformationJobObject(HANDLE hJob
,
238 JOBOBJECTINFOCLASS JobObjectInformationClass
,
239 LPVOID lpJobObjectInformation
,
240 DWORD cbJobObjectInformationLength
,
241 LPDWORD lpReturnLength
)
245 Status
= NtQueryInformationJobObject(hJob
,
246 JobObjectInformationClass
,
247 lpJobObjectInformation
,
248 cbJobObjectInformationLength
,
250 if(NT_SUCCESS(Status
))
252 PJOBOBJECT_BASIC_LIMIT_INFORMATION BasicInfo
;
253 switch(JobObjectInformationClass
)
255 case JobObjectBasicLimitInformation
:
256 BasicInfo
= (PJOBOBJECT_BASIC_LIMIT_INFORMATION
)lpJobObjectInformation
;
258 case JobObjectExtendedLimitInformation
:
259 BasicInfo
= &((PJOBOBJECT_EXTENDED_LIMIT_INFORMATION
)lpJobObjectInformation
)->BasicLimitInformation
;
267 if(BasicInfo
!= NULL
)
269 /* we need to convert the process priority classes in the
270 JOBOBJECT_BASIC_LIMIT_INFORMATION structure the same way as
271 GetPriorityClass() converts it! */
272 switch(BasicInfo
->PriorityClass
)
274 case PROCESS_PRIORITY_CLASS_IDLE
:
275 BasicInfo
->PriorityClass
= IDLE_PRIORITY_CLASS
;
277 case PROCESS_PRIORITY_CLASS_BELOW_NORMAL
:
278 BasicInfo
->PriorityClass
= BELOW_NORMAL_PRIORITY_CLASS
;
280 case PROCESS_PRIORITY_CLASS_NORMAL
:
281 BasicInfo
->PriorityClass
= NORMAL_PRIORITY_CLASS
;
283 case PROCESS_PRIORITY_CLASS_ABOVE_NORMAL
:
284 BasicInfo
->PriorityClass
= ABOVE_NORMAL_PRIORITY_CLASS
;
286 case PROCESS_PRIORITY_CLASS_HIGH
:
287 BasicInfo
->PriorityClass
= HIGH_PRIORITY_CLASS
;
289 case PROCESS_PRIORITY_CLASS_REALTIME
:
290 BasicInfo
->PriorityClass
= REALTIME_PRIORITY_CLASS
;
293 BasicInfo
->PriorityClass
= NORMAL_PRIORITY_CLASS
;
301 SetLastErrorByStatus(Status
);
311 SetInformationJobObject(HANDLE hJob
,
312 JOBOBJECTINFOCLASS JobObjectInformationClass
,
313 LPVOID lpJobObjectInformation
,
314 DWORD cbJobObjectInformationLength
)
316 JOBOBJECT_EXTENDED_LIMIT_INFORMATION ExtendedLimitInfo
;
317 PJOBOBJECT_BASIC_LIMIT_INFORMATION BasicInfo
;
321 switch(JobObjectInformationClass
)
323 case JobObjectBasicLimitInformation
:
324 if(cbJobObjectInformationLength
!= sizeof(JOBOBJECT_BASIC_LIMIT_INFORMATION
))
326 SetLastError(ERROR_BAD_LENGTH
);
329 ObjectInfo
= &ExtendedLimitInfo
.BasicLimitInformation
;
330 BasicInfo
= (PJOBOBJECT_BASIC_LIMIT_INFORMATION
)ObjectInfo
;
331 RtlCopyMemory(ObjectInfo
, lpJobObjectInformation
, cbJobObjectInformationLength
);
334 case JobObjectExtendedLimitInformation
:
335 if(cbJobObjectInformationLength
!= sizeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION
))
337 SetLastError(ERROR_BAD_LENGTH
);
340 ObjectInfo
= &ExtendedLimitInfo
;
341 BasicInfo
= &ExtendedLimitInfo
.BasicLimitInformation
;
342 RtlCopyMemory(ObjectInfo
, lpJobObjectInformation
, cbJobObjectInformationLength
);
346 ObjectInfo
= lpJobObjectInformation
;
351 if(BasicInfo
!= NULL
)
353 /* we need to convert the process priority classes in the
354 JOBOBJECT_BASIC_LIMIT_INFORMATION structure the same way as
355 SetPriorityClass() converts it! */
356 switch(BasicInfo
->PriorityClass
)
358 case IDLE_PRIORITY_CLASS
:
359 BasicInfo
->PriorityClass
= PROCESS_PRIORITY_CLASS_IDLE
;
361 case BELOW_NORMAL_PRIORITY_CLASS
:
362 BasicInfo
->PriorityClass
= PROCESS_PRIORITY_CLASS_BELOW_NORMAL
;
364 case NORMAL_PRIORITY_CLASS
:
365 BasicInfo
->PriorityClass
= PROCESS_PRIORITY_CLASS_NORMAL
;
367 case ABOVE_NORMAL_PRIORITY_CLASS
:
368 BasicInfo
->PriorityClass
= PROCESS_PRIORITY_CLASS_ABOVE_NORMAL
;
370 case HIGH_PRIORITY_CLASS
:
371 BasicInfo
->PriorityClass
= PROCESS_PRIORITY_CLASS_HIGH
;
373 case REALTIME_PRIORITY_CLASS
:
374 BasicInfo
->PriorityClass
= PROCESS_PRIORITY_CLASS_REALTIME
;
377 BasicInfo
->PriorityClass
= PROCESS_PRIORITY_CLASS_NORMAL
;
382 Status
= NtSetInformationJobObject(hJob
,
383 JobObjectInformationClass
,
385 cbJobObjectInformationLength
);
386 if(!NT_SUCCESS(Status
))
388 SetLastErrorByStatus(Status
);
401 TerminateJobObject(HANDLE hJob
,
406 Status
= NtTerminateJobObject(hJob
, uExitCode
);
407 if(!NT_SUCCESS(Status
))
409 SetLastErrorByStatus(Status
);