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