xref: /reactos/dll/win32/kernel32/client/job.c (revision 18a9993d)
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