[KERNEL32] implement CreateSemaphoreExW/A and adjust macroses for it
[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: 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
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
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
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
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
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
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
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
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
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
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 */