/* * Checks if the privilege for Real-Time Priority is there * Beware about this function behavior: * - In case Keep is set to FALSE, then the function will only check * whether real time is allowed and won't grant the privilege. In that case * it will return TRUE if allowed, FALSE otherwise. Not a state! * It means you don't have to release privilege when calling with FALSE. */ PVOID WINAPI BasepIsRealtimeAllowed(IN BOOLEAN Keep) { ULONG Privilege = SE_INC_BASE_PRIORITY_PRIVILEGE; PVOID State; NTSTATUS Status; Status = RtlAcquirePrivilege(&Privilege, 1, 0, &State); if (!NT_SUCCESS(Status)) return NULL; if (!Keep) { RtlReleasePrivilege(State); State = (PVOID)TRUE; } return State; }
/* * @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; }