/* * @implemented */ BOOL WINAPI SetInformationJobObject(HANDLE hJob, JOBOBJECTINFOCLASS JobObjectInformationClass, LPVOID lpJobObjectInformation, DWORD cbJobObjectInformationLength) { JOBOBJECT_EXTENDED_LIMIT_INFORMATION ExtendedLimitInfo; PJOBOBJECT_BASIC_LIMIT_INFORMATION BasicInfo; PVOID ObjectInfo; NTSTATUS Status; switch (JobObjectInformationClass) { case JobObjectBasicLimitInformation: if (cbJobObjectInformationLength != sizeof(JOBOBJECT_BASIC_LIMIT_INFORMATION)) { SetLastError(ERROR_BAD_LENGTH); return FALSE; } ObjectInfo = &ExtendedLimitInfo.BasicLimitInformation; BasicInfo = (PJOBOBJECT_BASIC_LIMIT_INFORMATION)ObjectInfo; RtlCopyMemory(ObjectInfo, lpJobObjectInformation, cbJobObjectInformationLength); break; case JobObjectExtendedLimitInformation: if (cbJobObjectInformationLength != sizeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION)) { SetLastError(ERROR_BAD_LENGTH); return FALSE; } ObjectInfo = &ExtendedLimitInfo; BasicInfo = &ExtendedLimitInfo.BasicLimitInformation; RtlCopyMemory(ObjectInfo, lpJobObjectInformation, cbJobObjectInformationLength); break; default: ObjectInfo = lpJobObjectInformation; BasicInfo = NULL; break; } if (BasicInfo != NULL) { /* we need to convert the process priority classes in the JOBOBJECT_BASIC_LIMIT_INFORMATION structure the same way as SetPriorityClass() converts it! */ switch(BasicInfo->PriorityClass) { case IDLE_PRIORITY_CLASS: BasicInfo->PriorityClass = PROCESS_PRIORITY_CLASS_IDLE; break; case BELOW_NORMAL_PRIORITY_CLASS: BasicInfo->PriorityClass = PROCESS_PRIORITY_CLASS_BELOW_NORMAL; break; case NORMAL_PRIORITY_CLASS: BasicInfo->PriorityClass = PROCESS_PRIORITY_CLASS_NORMAL; break; case ABOVE_NORMAL_PRIORITY_CLASS: BasicInfo->PriorityClass = PROCESS_PRIORITY_CLASS_ABOVE_NORMAL; break; case HIGH_PRIORITY_CLASS: BasicInfo->PriorityClass = PROCESS_PRIORITY_CLASS_HIGH; break; case REALTIME_PRIORITY_CLASS: BasicInfo->PriorityClass = PROCESS_PRIORITY_CLASS_REALTIME; break; default: BasicInfo->PriorityClass = PROCESS_PRIORITY_CLASS_NORMAL; break; } } Status = NtSetInformationJobObject(hJob, JobObjectInformationClass, ObjectInfo, cbJobObjectInformationLength); if (!NT_SUCCESS(Status)) { BaseSetLastNTError(Status); return FALSE; } return TRUE; }
/* * @implemented */ BOOL WINAPI SetInformationJobObject(IN HANDLE hJob, IN JOBOBJECTINFOCLASS JobObjectInformationClass, IN LPVOID lpJobObjectInformation, IN DWORD cbJobObjectInformationLength) { NTSTATUS Status; PVOID JobInfo; JOBOBJECT_EXTENDED_LIMIT_INFORMATION LocalInfo; ULONG ExpectedSize; PVOID State = NULL; ULONG Privilege = SE_INC_BASE_PRIORITY_PRIVILEGE; if (JobObjectInformationClass == JobObjectBasicLimitInformation) { ExpectedSize = sizeof(JOBOBJECT_BASIC_LIMIT_INFORMATION); JobInfo = &LocalInfo; } else if (JobObjectInformationClass == JobObjectExtendedLimitInformation) { ExpectedSize = sizeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION); JobInfo = &LocalInfo; } else { ExpectedSize = cbJobObjectInformationLength; JobInfo = lpJobObjectInformation; } if (cbJobObjectInformationLength != ExpectedSize) { BaseSetLastNTError(STATUS_INFO_LENGTH_MISMATCH); return FALSE; } if (JobInfo == &LocalInfo) { RtlCopyMemory(&LocalInfo, lpJobObjectInformation, ExpectedSize); if (LocalInfo.BasicLimitInformation.LimitFlags & JOB_OBJECT_LIMIT_PRIORITY_CLASS) { switch (LocalInfo.BasicLimitInformation.PriorityClass) { case IDLE_PRIORITY_CLASS: LocalInfo.BasicLimitInformation.PriorityClass = PROCESS_PRIORITY_CLASS_IDLE; break; case BELOW_NORMAL_PRIORITY_CLASS: LocalInfo.BasicLimitInformation.PriorityClass = PROCESS_PRIORITY_CLASS_BELOW_NORMAL; break; case NORMAL_PRIORITY_CLASS: LocalInfo.BasicLimitInformation.PriorityClass = PROCESS_PRIORITY_CLASS_NORMAL; break; case ABOVE_NORMAL_PRIORITY_CLASS: LocalInfo.BasicLimitInformation.PriorityClass = PROCESS_PRIORITY_CLASS_ABOVE_NORMAL; break; case HIGH_PRIORITY_CLASS: LocalInfo.BasicLimitInformation.PriorityClass = PROCESS_PRIORITY_CLASS_HIGH; break; case REALTIME_PRIORITY_CLASS: LocalInfo.BasicLimitInformation.PriorityClass = PROCESS_PRIORITY_CLASS_REALTIME; break; default: LocalInfo.BasicLimitInformation.PriorityClass = PROCESS_PRIORITY_CLASS_NORMAL; break; } } if (LocalInfo.BasicLimitInformation.LimitFlags & JOB_OBJECT_LIMIT_WORKINGSET) { Status = RtlAcquirePrivilege(&Privilege, 1, 0, &State); } } Status = NtSetInformationJobObject(hJob, JobObjectInformationClass, JobInfo, ExpectedSize); if (NT_SUCCESS(Status)) { if (State != NULL) RtlReleasePrivilege(State); return TRUE; } BaseSetLastNTError(Status); return FALSE; }