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 */ 355