1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: dll/win32/kernel32/client/job.c
5 * PURPOSE: Job functions
6 * PROGRAMMER: Thomas Weidenmueller <w3seek@reactos.com>
7 * UPDATE HISTORY:
8 * Created 9/23/2004
9 */
10
11 /* INCLUDES *******************************************************************/
12
13 #include <k32.h>
14 #include <winspool.h>
15
16 #define NDEBUG
17 #include <debug.h>
18
19 /* FUNCTIONS ******************************************************************/
20
21 /*
22 * @implemented
23 */
24 HANDLE
25 WINAPI
CreateJobObjectA(IN LPSECURITY_ATTRIBUTES lpJobAttributes,IN LPCSTR lpName)26 CreateJobObjectA(IN LPSECURITY_ATTRIBUTES lpJobAttributes,
27 IN LPCSTR lpName)
28 {
29 /* Call the W(ide) function */
30 ConvertWin32AnsiObjectApiToUnicodeApi(JobObject, lpName, lpJobAttributes);
31 }
32
33 /*
34 * @implemented
35 */
36 HANDLE
37 WINAPI
CreateJobObjectW(IN LPSECURITY_ATTRIBUTES lpJobAttributes,IN LPCWSTR lpName)38 CreateJobObjectW(IN LPSECURITY_ATTRIBUTES lpJobAttributes,
39 IN LPCWSTR lpName)
40 {
41 /* Create the NT object */
42 CreateNtObjectFromWin32Api(JobObject, JobObject, JOB_OBJECT_ALL_ACCESS, lpJobAttributes, lpName);
43 }
44
45 /*
46 * @implemented
47 */
48 HANDLE
49 WINAPI
OpenJobObjectW(IN DWORD dwDesiredAccess,IN BOOL bInheritHandle,IN LPCWSTR lpName)50 OpenJobObjectW(IN DWORD dwDesiredAccess,
51 IN BOOL bInheritHandle,
52 IN LPCWSTR lpName)
53 {
54 /* Open the NT object */
55 OpenNtObjectFromWin32Api(JobObject, dwDesiredAccess, bInheritHandle, lpName);
56 }
57
58
59 /*
60 * @implemented
61 */
62 HANDLE
63 WINAPI
OpenJobObjectA(IN DWORD dwDesiredAccess,IN BOOL bInheritHandle,IN LPCSTR lpName)64 OpenJobObjectA(IN DWORD dwDesiredAccess,
65 IN BOOL bInheritHandle,
66 IN LPCSTR lpName)
67 {
68 /* Call the W(ide) function */
69 ConvertOpenWin32AnsiObjectApiToUnicodeApi(JobObject, dwDesiredAccess, bInheritHandle, lpName);
70 }
71
72 /*
73 * @implemented
74 */
75 BOOL
76 WINAPI
IsProcessInJob(IN HANDLE ProcessHandle,IN HANDLE JobHandle,OUT PBOOL Result)77 IsProcessInJob(IN HANDLE ProcessHandle,
78 IN HANDLE JobHandle,
79 OUT PBOOL Result)
80 {
81 NTSTATUS Status;
82
83 Status = NtIsProcessInJob(ProcessHandle, JobHandle);
84 if (NT_SUCCESS(Status))
85 {
86 *Result = (Status == STATUS_PROCESS_IN_JOB);
87 return TRUE;
88 }
89
90 BaseSetLastNTError(Status);
91 return FALSE;
92 }
93
94 /*
95 * @implemented
96 */
97 BOOL
98 WINAPI
AssignProcessToJobObject(IN HANDLE hJob,IN HANDLE hProcess)99 AssignProcessToJobObject(IN HANDLE hJob,
100 IN HANDLE hProcess)
101 {
102 NTSTATUS Status;
103
104 Status = NtAssignProcessToJobObject(hJob, hProcess);
105 if (!NT_SUCCESS(Status))
106 {
107 BaseSetLastNTError(Status);
108 return FALSE;
109 }
110
111 return TRUE;
112 }
113
114 /*
115 * @implemented
116 */
117 BOOL
118 WINAPI
QueryInformationJobObject(IN HANDLE hJob,IN JOBOBJECTINFOCLASS JobObjectInformationClass,IN LPVOID lpJobObjectInformation,IN DWORD cbJobObjectInformationLength,OUT LPDWORD lpReturnLength)119 QueryInformationJobObject(IN HANDLE hJob,
120 IN JOBOBJECTINFOCLASS JobObjectInformationClass,
121 IN LPVOID lpJobObjectInformation,
122 IN DWORD cbJobObjectInformationLength,
123 OUT LPDWORD lpReturnLength)
124 {
125 NTSTATUS Status;
126 PVOID JobInfo;
127 JOBOBJECT_EXTENDED_LIMIT_INFORMATION LocalInfo;
128 ULONG ExpectedSize;
129
130 if (JobObjectInformationClass == JobObjectBasicLimitInformation)
131 {
132 ExpectedSize = sizeof(JOBOBJECT_BASIC_LIMIT_INFORMATION);
133 JobInfo = &LocalInfo;
134 }
135 else if (JobObjectInformationClass == JobObjectExtendedLimitInformation)
136 {
137 ExpectedSize = sizeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION);
138 JobInfo = &LocalInfo;
139 }
140 else
141 {
142 ExpectedSize = cbJobObjectInformationLength;
143 JobInfo = lpJobObjectInformation;
144 }
145
146 if (cbJobObjectInformationLength != ExpectedSize)
147 {
148 BaseSetLastNTError(STATUS_INFO_LENGTH_MISMATCH);
149 return FALSE;
150 }
151
152 Status = NtQueryInformationJobObject(hJob,
153 JobObjectInformationClass,
154 JobInfo,
155 ExpectedSize,
156 lpReturnLength);
157 if (NT_SUCCESS(Status))
158 {
159 if (JobInfo != &LocalInfo) return TRUE;
160
161 switch (LocalInfo.BasicLimitInformation.PriorityClass)
162 {
163 case PROCESS_PRIORITY_CLASS_IDLE:
164 LocalInfo.BasicLimitInformation.PriorityClass =
165 IDLE_PRIORITY_CLASS;
166 break;
167
168 case PROCESS_PRIORITY_CLASS_BELOW_NORMAL:
169 LocalInfo.BasicLimitInformation.PriorityClass =
170 BELOW_NORMAL_PRIORITY_CLASS;
171 break;
172
173 case PROCESS_PRIORITY_CLASS_NORMAL:
174 LocalInfo.BasicLimitInformation.PriorityClass =
175 NORMAL_PRIORITY_CLASS;
176 break;
177
178 case PROCESS_PRIORITY_CLASS_ABOVE_NORMAL:
179 LocalInfo.BasicLimitInformation.PriorityClass =
180 ABOVE_NORMAL_PRIORITY_CLASS;
181 break;
182
183 case PROCESS_PRIORITY_CLASS_HIGH:
184 LocalInfo.BasicLimitInformation.PriorityClass =
185 HIGH_PRIORITY_CLASS;
186 break;
187
188 case PROCESS_PRIORITY_CLASS_REALTIME:
189 LocalInfo.BasicLimitInformation.PriorityClass =
190 REALTIME_PRIORITY_CLASS;
191 break;
192
193 default:
194 LocalInfo.BasicLimitInformation.PriorityClass =
195 NORMAL_PRIORITY_CLASS;
196 break;
197 }
198
199 RtlCopyMemory(lpJobObjectInformation, &LocalInfo, ExpectedSize);
200 return TRUE;
201 }
202
203 BaseSetLastNTError(Status);
204 return FALSE;
205 }
206
207 /*
208 * @implemented
209 */
210 BOOL
211 WINAPI
SetInformationJobObject(IN HANDLE hJob,IN JOBOBJECTINFOCLASS JobObjectInformationClass,IN LPVOID lpJobObjectInformation,IN DWORD cbJobObjectInformationLength)212 SetInformationJobObject(IN HANDLE hJob,
213 IN JOBOBJECTINFOCLASS JobObjectInformationClass,
214 IN LPVOID lpJobObjectInformation,
215 IN DWORD cbJobObjectInformationLength)
216 {
217 NTSTATUS Status;
218 PVOID JobInfo;
219 JOBOBJECT_EXTENDED_LIMIT_INFORMATION LocalInfo;
220 ULONG ExpectedSize;
221 PVOID State = NULL;
222 ULONG Privilege = SE_INC_BASE_PRIORITY_PRIVILEGE;
223
224 if (JobObjectInformationClass == JobObjectBasicLimitInformation)
225 {
226 ExpectedSize = sizeof(JOBOBJECT_BASIC_LIMIT_INFORMATION);
227 JobInfo = &LocalInfo;
228 }
229 else if (JobObjectInformationClass == JobObjectExtendedLimitInformation)
230 {
231 ExpectedSize = sizeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION);
232 JobInfo = &LocalInfo;
233 }
234 else
235 {
236 ExpectedSize = cbJobObjectInformationLength;
237 JobInfo = lpJobObjectInformation;
238 }
239
240 if (cbJobObjectInformationLength != ExpectedSize)
241 {
242 BaseSetLastNTError(STATUS_INFO_LENGTH_MISMATCH);
243 return FALSE;
244 }
245
246 if (JobInfo == &LocalInfo)
247 {
248 RtlCopyMemory(&LocalInfo, lpJobObjectInformation, ExpectedSize);
249
250 if (LocalInfo.BasicLimitInformation.LimitFlags &
251 JOB_OBJECT_LIMIT_PRIORITY_CLASS)
252 {
253 switch (LocalInfo.BasicLimitInformation.PriorityClass)
254 {
255 case IDLE_PRIORITY_CLASS:
256 LocalInfo.BasicLimitInformation.PriorityClass =
257 PROCESS_PRIORITY_CLASS_IDLE;
258 break;
259
260 case BELOW_NORMAL_PRIORITY_CLASS:
261 LocalInfo.BasicLimitInformation.PriorityClass =
262 PROCESS_PRIORITY_CLASS_BELOW_NORMAL;
263 break;
264
265 case NORMAL_PRIORITY_CLASS:
266 LocalInfo.BasicLimitInformation.PriorityClass =
267 PROCESS_PRIORITY_CLASS_NORMAL;
268 break;
269
270 case ABOVE_NORMAL_PRIORITY_CLASS:
271 LocalInfo.BasicLimitInformation.PriorityClass =
272 PROCESS_PRIORITY_CLASS_ABOVE_NORMAL;
273 break;
274
275 case HIGH_PRIORITY_CLASS:
276 LocalInfo.BasicLimitInformation.PriorityClass =
277 PROCESS_PRIORITY_CLASS_HIGH;
278 break;
279
280 case REALTIME_PRIORITY_CLASS:
281 LocalInfo.BasicLimitInformation.PriorityClass =
282 PROCESS_PRIORITY_CLASS_REALTIME;
283 break;
284
285 default:
286 LocalInfo.BasicLimitInformation.PriorityClass =
287 PROCESS_PRIORITY_CLASS_NORMAL;
288 break;
289 }
290 }
291
292 if (LocalInfo.BasicLimitInformation.LimitFlags &
293 JOB_OBJECT_LIMIT_WORKINGSET)
294 {
295 Status = RtlAcquirePrivilege(&Privilege, 1, 0, &State);
296 }
297 }
298
299 Status = NtSetInformationJobObject(hJob,
300 JobObjectInformationClass,
301 JobInfo,
302 ExpectedSize);
303 if (NT_SUCCESS(Status))
304 {
305 if (State != NULL) RtlReleasePrivilege(State);
306 return TRUE;
307 }
308
309 BaseSetLastNTError(Status);
310 return FALSE;
311 }
312
313 /*
314 * @implemented
315 */
316 BOOL
317 WINAPI
TerminateJobObject(IN HANDLE hJob,IN UINT uExitCode)318 TerminateJobObject(IN HANDLE hJob,
319 IN UINT uExitCode)
320 {
321 NTSTATUS Status;
322
323 Status = NtTerminateJobObject(hJob, uExitCode);
324 if (!NT_SUCCESS(Status))
325 {
326 BaseSetLastNTError(Status);
327 return FALSE;
328 }
329
330 return TRUE;
331 }
332
333 /*
334 * @implemented
335 */
336 BOOL
337 WINAPI
CreateJobSet(IN ULONG NumJob,IN PJOB_SET_ARRAY UserJobSet,IN ULONG Flags)338 CreateJobSet(IN ULONG NumJob,
339 IN PJOB_SET_ARRAY UserJobSet,
340 IN ULONG Flags)
341 {
342 NTSTATUS Status;
343
344 Status = NtCreateJobSet(NumJob, UserJobSet, Flags);
345 if (!NT_SUCCESS(Status))
346 {
347 BaseSetLastNTError(Status);
348 return FALSE;
349 }
350
351 return TRUE;
352 }
353
354 /* EOF */
355