Created
May 30, 2015 15:39
-
-
Save peryaudo/e7a60890439ef3faa863 to your computer and use it in GitHub Desktop.
Implement NtQueryInformationJobObject and NtSetInformationJobObject to ReactOS
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Index: include/ndk/pstypes.h | |
| =================================================================== | |
| --- include/ndk/pstypes.h (revision 67961) | |
| +++ include/ndk/pstypes.h (working copy) | |
| @@ -826,6 +826,77 @@ | |
| #ifndef NTOS_MODE_USER | |
| // | |
| +// Job Information Structures for NtQueryInformationJobObject | |
| +// | |
| +typedef struct _JOBOBJECT_BASIC_ACCOUNTING_INFORMATION { | |
| + LARGE_INTEGER TotalUserTime; | |
| + LARGE_INTEGER TotalKernelTime; | |
| + LARGE_INTEGER ThisPeriodTotalUserTime; | |
| + LARGE_INTEGER ThisPeriodTotalKernelTime; | |
| + ULONG TotalPageFaultCount; | |
| + ULONG TotalProcesses; | |
| + ULONG ActiveProcesses; | |
| + ULONG TotalTerminatedProcesses; | |
| +} JOBOBJECT_BASIC_ACCOUNTING_INFORMATION,*PJOBOBJECT_BASIC_ACCOUNTING_INFORMATION; | |
| + | |
| +typedef struct _JOBOBJECT_BASIC_LIMIT_INFORMATION { | |
| + LARGE_INTEGER PerProcessUserTimeLimit; | |
| + LARGE_INTEGER PerJobUserTimeLimit; | |
| + ULONG LimitFlags; | |
| + SIZE_T MinimumWorkingSetSize; | |
| + SIZE_T MaximumWorkingSetSize; | |
| + ULONG ActiveProcessLimit; | |
| + ULONG_PTR Affinity; | |
| + ULONG PriorityClass; | |
| + ULONG SchedulingClass; | |
| +} JOBOBJECT_BASIC_LIMIT_INFORMATION,*PJOBOBJECT_BASIC_LIMIT_INFORMATION; | |
| + | |
| +typedef struct _JOBOBJECT_BASIC_PROCESS_ID_LIST { | |
| + ULONG NumberOfAssignedProcesses; | |
| + ULONG NumberOfProcessIdsInList; | |
| + ULONG_PTR ProcessIdList[1]; | |
| +} JOBOBJECT_BASIC_PROCESS_ID_LIST, *PJOBOBJECT_BASIC_PROCESS_ID_LIST; | |
| + | |
| +typedef struct _JOBOBJECT_BASIC_UI_RESTRICTIONS { | |
| + ULONG UIRestrictionsClass; | |
| +} JOBOBJECT_BASIC_UI_RESTRICTIONS,*PJOBOBJECT_BASIC_UI_RESTRICTIONS; | |
| + | |
| +typedef struct _JOBOBJECT_SECURITY_LIMIT_INFORMATION { | |
| + ULONG SecurityLimitFlags; | |
| + HANDLE JobToken; | |
| + PTOKEN_GROUPS SidsToDisable; | |
| + PTOKEN_PRIVILEGES PrivilegesToDelete; | |
| + PTOKEN_GROUPS RestrictedSids; | |
| +} JOBOBJECT_SECURITY_LIMIT_INFORMATION,*PJOBOBJECT_SECURITY_LIMIT_INFORMATION; | |
| + | |
| +typedef struct _JOBOBJECT_END_OF_JOB_TIME_INFORMATION { | |
| + ULONG EndOfJobTimeAction; | |
| +} JOBOBJECT_END_OF_JOB_TIME_INFORMATION,*PJOBOBJECT_END_OF_JOB_TIME_INFORMATION; | |
| + | |
| +typedef struct _JOBOBJECT_ASSOCIATE_COMPLETION_PORT { | |
| + PVOID CompletionKey; | |
| + HANDLE CompletionPort; | |
| +} JOBOBJECT_ASSOCIATE_COMPLETION_PORT,*PJOBOBJECT_ASSOCIATE_COMPLETION_PORT; | |
| + | |
| +typedef struct _JOBOBJECT_BASIC_AND_IO_ACCOUNTING_INFORMATION { | |
| + JOBOBJECT_BASIC_ACCOUNTING_INFORMATION BasicInfo; | |
| + IO_COUNTERS IoInfo; | |
| +} JOBOBJECT_BASIC_AND_IO_ACCOUNTING_INFORMATION,*PJOBOBJECT_BASIC_AND_IO_ACCOUNTING_INFORMATION; | |
| + | |
| +typedef struct _JOBOBJECT_EXTENDED_LIMIT_INFORMATION { | |
| + JOBOBJECT_BASIC_LIMIT_INFORMATION BasicLimitInformation; | |
| + IO_COUNTERS IoInfo; | |
| + SIZE_T ProcessMemoryLimit; | |
| + SIZE_T JobMemoryLimit; | |
| + SIZE_T PeakProcessMemoryUsed; | |
| + SIZE_T PeakJobMemoryUsed; | |
| +} JOBOBJECT_EXTENDED_LIMIT_INFORMATION,*PJOBOBJECT_EXTENDED_LIMIT_INFORMATION; | |
| + | |
| +typedef struct _JOBOBJECT_JOBSET_INFORMATION { | |
| + ULONG MemberLevel; | |
| +} JOBOBJECT_JOBSET_INFORMATION,*PJOBOBJECT_JOBSET_INFORMATION; | |
| + | |
| +// | |
| // Job Set Array | |
| // | |
| typedef struct _JOB_SET_ARRAY | |
| Index: ntoskrnl/ps/job.c | |
| =================================================================== | |
| --- ntoskrnl/ps/job.c (revision 67961) | |
| +++ ntoskrnl/ps/job.c (working copy) | |
| @@ -443,7 +443,6 @@ | |
| return Status; | |
| } | |
| - | |
| /* | |
| * @unimplemented | |
| */ | |
| @@ -456,11 +455,398 @@ | |
| ULONG JobInformationLength, | |
| PULONG ReturnLength ) | |
| { | |
| - UNIMPLEMENTED; | |
| - return STATUS_NOT_IMPLEMENTED; | |
| + KPROCESSOR_MODE PreviousMode; | |
| + NTSTATUS Status = STATUS_SUCCESS; | |
| + PEJOB Job; | |
| + ULONG Length = 0; | |
| + PLIST_ENTRY Next; | |
| + ULONG i = 0; | |
| + PEPROCESS Process; | |
| + | |
| + PJOBOBJECT_BASIC_ACCOUNTING_INFORMATION BasicAccountingInfo = | |
| + (PJOBOBJECT_BASIC_ACCOUNTING_INFORMATION)JobInformation; | |
| + PJOBOBJECT_BASIC_LIMIT_INFORMATION BasicLimitInfo = | |
| + (PJOBOBJECT_BASIC_LIMIT_INFORMATION)JobInformation; | |
| + PJOBOBJECT_BASIC_PROCESS_ID_LIST BasicProcessIdList = | |
| + (PJOBOBJECT_BASIC_PROCESS_ID_LIST)JobInformation; | |
| + PJOBOBJECT_BASIC_UI_RESTRICTIONS BasicUIRestrictions = | |
| + (PJOBOBJECT_BASIC_UI_RESTRICTIONS)JobInformation; | |
| + PJOBOBJECT_SECURITY_LIMIT_INFORMATION SecurityLimitInfo = | |
| + (PJOBOBJECT_SECURITY_LIMIT_INFORMATION)JobInformation; | |
| + PJOBOBJECT_END_OF_JOB_TIME_INFORMATION EndOfJobTimeInfo = | |
| + (PJOBOBJECT_END_OF_JOB_TIME_INFORMATION)JobInformation; | |
| + PJOBOBJECT_ASSOCIATE_COMPLETION_PORT AssociateCompletionPort = | |
| + (PJOBOBJECT_ASSOCIATE_COMPLETION_PORT)JobInformation; | |
| + PJOBOBJECT_BASIC_AND_IO_ACCOUNTING_INFORMATION BasicAndIoAccountingInfo = | |
| + (PJOBOBJECT_BASIC_AND_IO_ACCOUNTING_INFORMATION)JobInformation; | |
| + PJOBOBJECT_EXTENDED_LIMIT_INFORMATION ExtendedLimitInfo = | |
| + (PJOBOBJECT_EXTENDED_LIMIT_INFORMATION)JobInformation; | |
| + PJOBOBJECT_JOBSET_INFORMATION JobSetInfo = | |
| + (PJOBOBJECT_JOBSET_INFORMATION)JobInformation; | |
| + | |
| + PAGED_CODE(); | |
| + | |
| + PreviousMode = ExGetPreviousMode(); | |
| + | |
| + if (JobHandle == NULL) | |
| + { | |
| + Process = PsGetCurrentProcess(); | |
| + Job = Process->Job; | |
| + /* FIXME: lock properly */ | |
| + } else { | |
| + Status = ObReferenceObjectByHandle(JobHandle, | |
| + JOB_OBJECT_QUERY, | |
| + PsJobType, | |
| + PreviousMode, | |
| + (PVOID*)&Job, | |
| + NULL); | |
| + if (!NT_SUCCESS(Status)) | |
| + { | |
| + return Status; | |
| + } | |
| + } | |
| + | |
| + ExAcquireResourceSharedLite(&Job->JobLock, TRUE); | |
| + | |
| + switch (JobInformationClass) | |
| + { | |
| + case JobObjectBasicAccountingInformation: | |
| + | |
| + /* Set return length */ | |
| + Length = sizeof(JOBOBJECT_BASIC_ACCOUNTING_INFORMATION); | |
| + if (JobInformationLength != Length) | |
| + { | |
| + Status = STATUS_INFO_LENGTH_MISMATCH; | |
| + break; | |
| + } | |
| + | |
| + /* Protect writes with SEH */ | |
| + _SEH2_TRY | |
| + { | |
| + /* Write all the information from the EJOB */ | |
| + BasicAccountingInfo->TotalUserTime = Job->TotalUserTime; | |
| + BasicAccountingInfo->TotalKernelTime = Job->TotalKernelTime; | |
| + BasicAccountingInfo->ThisPeriodTotalUserTime = Job->ThisPeriodTotalUserTime; | |
| + BasicAccountingInfo->ThisPeriodTotalKernelTime = Job->ThisPeriodTotalKernelTime; | |
| + BasicAccountingInfo->TotalPageFaultCount = Job->TotalPageFaultCount; | |
| + BasicAccountingInfo->TotalProcesses = Job->TotalProcesses; | |
| + BasicAccountingInfo->ActiveProcesses = Job->ActiveProcesses; | |
| + BasicAccountingInfo->TotalTerminatedProcesses = Job->TotalTerminatedProcesses; | |
| + } | |
| + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) | |
| + { | |
| + /* Get exception code */ | |
| + Status = _SEH2_GetExceptionCode(); | |
| + } | |
| + _SEH2_END; | |
| + | |
| + break; | |
| + | |
| + case JobObjectBasicLimitInformation: | |
| + | |
| + /* Set return length */ | |
| + Length = sizeof(JOBOBJECT_BASIC_LIMIT_INFORMATION); | |
| + if (JobInformationLength != Length) | |
| + { | |
| + Status = STATUS_INFO_LENGTH_MISMATCH; | |
| + break; | |
| + } | |
| + | |
| + /* Protect writes with SEH */ | |
| + _SEH2_TRY | |
| + { | |
| + /* Write all the information from the EJOB */ | |
| + BasicLimitInfo->PerProcessUserTimeLimit = Job->PerProcessUserTimeLimit; | |
| + BasicLimitInfo->PerJobUserTimeLimit = Job->PerJobUserTimeLimit; | |
| + BasicLimitInfo->LimitFlags = Job->LimitFlags; | |
| + BasicLimitInfo->MinimumWorkingSetSize = Job->MinimumWorkingSetSize; | |
| + BasicLimitInfo->MaximumWorkingSetSize = Job->MaximumWorkingSetSize; | |
| + BasicLimitInfo->ActiveProcessLimit = Job->ActiveProcessLimit; | |
| + BasicLimitInfo->Affinity = Job->Affinity; | |
| + BasicLimitInfo->PriorityClass = Job->PriorityClass; | |
| + BasicLimitInfo->SchedulingClass = Job->SchedulingClass; | |
| + } | |
| + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) | |
| + { | |
| + /* Get exception code */ | |
| + Status = _SEH2_GetExceptionCode(); | |
| + } | |
| + _SEH2_END; | |
| + | |
| + break; | |
| + | |
| + case JobObjectBasicProcessIdList: | |
| + | |
| + Length = sizeof(ULONG) * 2; | |
| + | |
| + if (JobInformationLength < Length) | |
| + { | |
| + Status = STATUS_INFO_LENGTH_MISMATCH; | |
| + break; | |
| + } | |
| + | |
| + /* Protect writes with SEH */ | |
| + _SEH2_TRY | |
| + { | |
| + /* Write all the information from the EJOB */ | |
| + | |
| + BasicProcessIdList->NumberOfAssignedProcesses = 0; | |
| + BasicProcessIdList->NumberOfProcessIdsInList = 0; | |
| + | |
| + /* Loop the processes */ | |
| + for (Next = Job->ProcessListHead.Flink, i = 0; | |
| + Next != &Job->ProcessListHead; | |
| + Next = Next->Flink, i++) | |
| + { | |
| + Process = CONTAINING_RECORD(Next, EPROCESS, JobLinks); | |
| + | |
| + if (Length + sizeof(ULONG_PTR) <= JobInformationLength) | |
| + { | |
| + /* FIXME: Is it correct? */ | |
| + BasicProcessIdList->ProcessIdList[i] = (ULONG_PTR)Process->UniqueProcessId; | |
| + } | |
| + } | |
| + | |
| + } | |
| + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) | |
| + { | |
| + /* Get exception code */ | |
| + Status = _SEH2_GetExceptionCode(); | |
| + } | |
| + _SEH2_END; | |
| + | |
| + break; | |
| + | |
| + case JobObjectBasicUIRestrictions: | |
| + | |
| + /* Set return length */ | |
| + Length = sizeof(JOBOBJECT_BASIC_UI_RESTRICTIONS); | |
| + if (JobInformationLength != Length) | |
| + { | |
| + Status = STATUS_INFO_LENGTH_MISMATCH; | |
| + break; | |
| + } | |
| + | |
| + /* Protect writes with SEH */ | |
| + _SEH2_TRY | |
| + { | |
| + /* Write all the information from the EJOB */ | |
| + BasicUIRestrictions->UIRestrictionsClass = Job->UIRestrictionsClass; | |
| + } | |
| + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) | |
| + { | |
| + /* Get exception code */ | |
| + Status = _SEH2_GetExceptionCode(); | |
| + } | |
| + _SEH2_END; | |
| + | |
| + break; | |
| + | |
| + case JobObjectSecurityLimitInformation: | |
| + | |
| + /* Set return length */ | |
| + Length = sizeof(JOBOBJECT_SECURITY_LIMIT_INFORMATION); | |
| + if (JobInformationLength != Length) | |
| + { | |
| + Status = STATUS_INFO_LENGTH_MISMATCH; | |
| + break; | |
| + } | |
| + | |
| + /* Protect writes with SEH */ | |
| + _SEH2_TRY | |
| + { | |
| + /* Write all the information from the EJOB */ | |
| + SecurityLimitInfo->SecurityLimitFlags = Job->SecurityLimitFlags; | |
| + SecurityLimitInfo->JobToken = Job->Token; | |
| + /* FIXME: Is it correct? */ | |
| + SecurityLimitInfo->SidsToDisable = NULL; | |
| + SecurityLimitInfo->PrivilegesToDelete = NULL; | |
| + SecurityLimitInfo->RestrictedSids = NULL; | |
| + } | |
| + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) | |
| + { | |
| + /* Get exception code */ | |
| + Status = _SEH2_GetExceptionCode(); | |
| + } | |
| + _SEH2_END; | |
| + | |
| + break; | |
| + | |
| + case JobObjectEndOfJobTimeInformation: | |
| + | |
| + /* Set return length */ | |
| + Length = sizeof(JOBOBJECT_END_OF_JOB_TIME_INFORMATION); | |
| + if (JobInformationLength != Length) | |
| + { | |
| + Status = STATUS_INFO_LENGTH_MISMATCH; | |
| + break; | |
| + } | |
| + | |
| + /* Protect writes with SEH */ | |
| + _SEH2_TRY | |
| + { | |
| + /* Write all the information from the EJOB */ | |
| + EndOfJobTimeInfo->EndOfJobTimeAction = Job->EndOfJobTimeAction; | |
| + } | |
| + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) | |
| + { | |
| + /* Get exception code */ | |
| + Status = _SEH2_GetExceptionCode(); | |
| + } | |
| + _SEH2_END; | |
| + | |
| + break; | |
| + | |
| + case JobObjectAssociateCompletionPortInformation: | |
| + | |
| + /* Set return length */ | |
| + Length = sizeof(JOBOBJECT_ASSOCIATE_COMPLETION_PORT); | |
| + if (JobInformationLength != Length) | |
| + { | |
| + Status = STATUS_INFO_LENGTH_MISMATCH; | |
| + break; | |
| + } | |
| + | |
| + /* Protect writes with SEH */ | |
| + _SEH2_TRY | |
| + { | |
| + /* Write all the information from the EJOB */ | |
| + AssociateCompletionPort->CompletionKey = Job->CompletionKey; | |
| + AssociateCompletionPort->CompletionPort = Job->CompletionPort; | |
| + } | |
| + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) | |
| + { | |
| + /* Get exception code */ | |
| + Status = _SEH2_GetExceptionCode(); | |
| + } | |
| + _SEH2_END; | |
| + | |
| + break; | |
| + | |
| + case JobObjectBasicAndIoAccountingInformation: | |
| + | |
| + /* Set return length */ | |
| + Length = sizeof(JOBOBJECT_BASIC_AND_IO_ACCOUNTING_INFORMATION); | |
| + if (JobInformationLength != Length) | |
| + { | |
| + Status = STATUS_INFO_LENGTH_MISMATCH; | |
| + break; | |
| + } | |
| + | |
| + /* Protect writes with SEH */ | |
| + _SEH2_TRY | |
| + { | |
| + /* Write all the information from the EJOB */ | |
| + BasicAndIoAccountingInfo->BasicInfo.TotalUserTime = Job->TotalUserTime; | |
| + BasicAndIoAccountingInfo->BasicInfo.TotalKernelTime = Job->TotalKernelTime; | |
| + BasicAndIoAccountingInfo->BasicInfo.ThisPeriodTotalUserTime = Job->ThisPeriodTotalUserTime; | |
| + BasicAndIoAccountingInfo->BasicInfo.ThisPeriodTotalKernelTime = Job->ThisPeriodTotalKernelTime; | |
| + BasicAndIoAccountingInfo->BasicInfo.TotalPageFaultCount = Job->TotalPageFaultCount; | |
| + BasicAndIoAccountingInfo->BasicInfo.TotalProcesses = Job->TotalProcesses; | |
| + BasicAndIoAccountingInfo->BasicInfo.ActiveProcesses = Job->ActiveProcesses; | |
| + BasicAndIoAccountingInfo->BasicInfo.TotalTerminatedProcesses = Job->TotalTerminatedProcesses; | |
| + BasicAndIoAccountingInfo->IoInfo = Job->IoInfo; | |
| + } | |
| + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) | |
| + { | |
| + /* Get exception code */ | |
| + Status = _SEH2_GetExceptionCode(); | |
| + } | |
| + _SEH2_END; | |
| + | |
| + break; | |
| + | |
| + case JobObjectExtendedLimitInformation: | |
| + | |
| + /* Set return length */ | |
| + Length = sizeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION); | |
| + if (JobInformationLength != Length) | |
| + { | |
| + Status = STATUS_INFO_LENGTH_MISMATCH; | |
| + break; | |
| + } | |
| + | |
| + /* Protect writes with SEH */ | |
| + _SEH2_TRY | |
| + { | |
| + /* Write all the information from the EJOB */ | |
| + ExtendedLimitInfo->BasicLimitInformation.PerProcessUserTimeLimit = Job->PerProcessUserTimeLimit; | |
| + ExtendedLimitInfo->BasicLimitInformation.PerJobUserTimeLimit = Job->PerJobUserTimeLimit; | |
| + ExtendedLimitInfo->BasicLimitInformation.LimitFlags = Job->LimitFlags; | |
| + ExtendedLimitInfo->BasicLimitInformation.MinimumWorkingSetSize = Job->MinimumWorkingSetSize; | |
| + ExtendedLimitInfo->BasicLimitInformation.MaximumWorkingSetSize = Job->MaximumWorkingSetSize; | |
| + ExtendedLimitInfo->BasicLimitInformation.ActiveProcessLimit = Job->ActiveProcessLimit; | |
| + ExtendedLimitInfo->BasicLimitInformation.Affinity = Job->Affinity; | |
| + ExtendedLimitInfo->BasicLimitInformation.PriorityClass = Job->PriorityClass; | |
| + ExtendedLimitInfo->BasicLimitInformation.SchedulingClass = Job->SchedulingClass; | |
| + ExtendedLimitInfo->IoInfo = Job->IoInfo; | |
| + ExtendedLimitInfo->ProcessMemoryLimit = Job->ProcessMemoryLimit; | |
| + ExtendedLimitInfo->JobMemoryLimit = Job->JobMemoryLimit; | |
| + ExtendedLimitInfo->PeakProcessMemoryUsed = Job->PeakProcessMemoryUsed; | |
| + ExtendedLimitInfo->PeakJobMemoryUsed = Job->PeakJobMemoryUsed; | |
| + } | |
| + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) | |
| + { | |
| + /* Get exception code */ | |
| + Status = _SEH2_GetExceptionCode(); | |
| + } | |
| + _SEH2_END; | |
| + | |
| + break; | |
| + | |
| + case JobObjectJobSetInformation: | |
| + | |
| + /* Set return length */ | |
| + Length = sizeof(JOBOBJECT_JOBSET_INFORMATION); | |
| + if (JobInformationLength != Length) | |
| + { | |
| + Status = STATUS_INFO_LENGTH_MISMATCH; | |
| + break; | |
| + } | |
| + | |
| + /* Protect writes with SEH */ | |
| + _SEH2_TRY | |
| + { | |
| + /* Write all the information from the EJOB */ | |
| + JobSetInfo->MemberLevel = Job->MemberLevel; | |
| + } | |
| + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) | |
| + { | |
| + /* Get exception code */ | |
| + Status = _SEH2_GetExceptionCode(); | |
| + } | |
| + _SEH2_END; | |
| + | |
| + break; | |
| + | |
| + default: | |
| + Status = STATUS_NOT_IMPLEMENTED; | |
| + break; | |
| + } | |
| + | |
| + ExReleaseResourceLite(&Job->JobLock); | |
| + | |
| + if (JobHandle != NULL) | |
| + { | |
| + ObDereferenceObject(Job); | |
| + } | |
| + | |
| + /* Protect write with SEH */ | |
| + _SEH2_TRY | |
| + { | |
| + /* Check if caller wanted return length */ | |
| + if ((ReturnLength) && (Length)) *ReturnLength = Length; | |
| + } | |
| + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) | |
| + { | |
| + /* Get exception code */ | |
| + Status = _SEH2_GetExceptionCode(); | |
| + } | |
| + _SEH2_END; | |
| + | |
| + return Status; | |
| } | |
| - | |
| /* | |
| * @unimplemented | |
| */ | |
| @@ -472,8 +858,250 @@ | |
| PVOID JobInformation, | |
| ULONG JobInformationLength) | |
| { | |
| - UNIMPLEMENTED; | |
| - return STATUS_NOT_IMPLEMENTED; | |
| + KPROCESSOR_MODE PreviousMode; | |
| + NTSTATUS Status = STATUS_SUCCESS; | |
| + PEJOB Job; | |
| + PEPROCESS Process; | |
| + | |
| + PJOBOBJECT_BASIC_LIMIT_INFORMATION BasicLimitInfo = | |
| + (PJOBOBJECT_BASIC_LIMIT_INFORMATION)JobInformation; | |
| + PJOBOBJECT_BASIC_UI_RESTRICTIONS BasicUIRestrictions = | |
| + (PJOBOBJECT_BASIC_UI_RESTRICTIONS)JobInformation; | |
| + PJOBOBJECT_SECURITY_LIMIT_INFORMATION SecurityLimitInfo = | |
| + (PJOBOBJECT_SECURITY_LIMIT_INFORMATION)JobInformation; | |
| + PJOBOBJECT_END_OF_JOB_TIME_INFORMATION EndOfJobTimeInfo = | |
| + (PJOBOBJECT_END_OF_JOB_TIME_INFORMATION)JobInformation; | |
| + PJOBOBJECT_ASSOCIATE_COMPLETION_PORT AssociateCompletionPort = | |
| + (PJOBOBJECT_ASSOCIATE_COMPLETION_PORT)JobInformation; | |
| + PJOBOBJECT_EXTENDED_LIMIT_INFORMATION ExtendedLimitInfo = | |
| + (PJOBOBJECT_EXTENDED_LIMIT_INFORMATION)JobInformation; | |
| + PJOBOBJECT_JOBSET_INFORMATION JobSetInfo = | |
| + (PJOBOBJECT_JOBSET_INFORMATION)JobInformation; | |
| + | |
| + PAGED_CODE(); | |
| + | |
| + PreviousMode = ExGetPreviousMode(); | |
| + | |
| + if (JobHandle == NULL) | |
| + { | |
| + Process = PsGetCurrentProcess(); | |
| + Job = Process->Job; | |
| + /* FIXME: lock properly */ | |
| + } else { | |
| + Status = ObReferenceObjectByHandle(JobHandle, | |
| + JOB_OBJECT_QUERY, | |
| + PsJobType, | |
| + PreviousMode, | |
| + (PVOID*)&Job, | |
| + NULL); | |
| + if (!NT_SUCCESS(Status)) | |
| + { | |
| + return Status; | |
| + } | |
| + } | |
| + | |
| + ExAcquireResourceSharedLite(&Job->JobLock, TRUE); | |
| + | |
| + switch (JobInformationClass) | |
| + { | |
| + case JobObjectBasicLimitInformation: | |
| + | |
| + /* Check buffer length */ | |
| + if (JobInformationLength != sizeof(JOBOBJECT_BASIC_LIMIT_INFORMATION)) | |
| + { | |
| + Status = STATUS_INFO_LENGTH_MISMATCH; | |
| + break; | |
| + } | |
| + | |
| + /* Protect reads with SEH */ | |
| + _SEH2_TRY | |
| + { | |
| + Job->PerProcessUserTimeLimit = BasicLimitInfo->PerProcessUserTimeLimit; | |
| + Job->PerJobUserTimeLimit = BasicLimitInfo->PerJobUserTimeLimit; | |
| + Job->LimitFlags = BasicLimitInfo->LimitFlags; | |
| + Job->MinimumWorkingSetSize = BasicLimitInfo->MinimumWorkingSetSize; | |
| + Job->MaximumWorkingSetSize = BasicLimitInfo->MaximumWorkingSetSize; | |
| + Job->ActiveProcessLimit = BasicLimitInfo->ActiveProcessLimit; | |
| + Job->Affinity = BasicLimitInfo->Affinity; | |
| + Job->PriorityClass = BasicLimitInfo->PriorityClass; | |
| + Job->SchedulingClass = BasicLimitInfo->SchedulingClass; | |
| + } | |
| + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) | |
| + { | |
| + /* Get exception code */ | |
| + Status = _SEH2_GetExceptionCode(); | |
| + } | |
| + _SEH2_END; | |
| + | |
| + break; | |
| + | |
| + case JobObjectBasicUIRestrictions: | |
| + | |
| + /* Check buffer length */ | |
| + if (JobInformationLength != sizeof(JOBOBJECT_BASIC_UI_RESTRICTIONS)) | |
| + { | |
| + Status = STATUS_INFO_LENGTH_MISMATCH; | |
| + break; | |
| + } | |
| + | |
| + /* Protect reads with SEH */ | |
| + _SEH2_TRY | |
| + { | |
| + Job->UIRestrictionsClass = BasicUIRestrictions->UIRestrictionsClass; | |
| + } | |
| + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) | |
| + { | |
| + /* Get exception code */ | |
| + Status = _SEH2_GetExceptionCode(); | |
| + } | |
| + _SEH2_END; | |
| + | |
| + break; | |
| + | |
| + case JobObjectSecurityLimitInformation: | |
| + | |
| + /* Check buffer length */ | |
| + if (JobInformationLength != sizeof(JOBOBJECT_SECURITY_LIMIT_INFORMATION)) | |
| + { | |
| + Status = STATUS_INFO_LENGTH_MISMATCH; | |
| + break; | |
| + } | |
| + | |
| + /* Protect reads with SEH */ | |
| + _SEH2_TRY | |
| + { | |
| + Job->SecurityLimitFlags = SecurityLimitInfo->SecurityLimitFlags; | |
| + Job->Token = SecurityLimitInfo->JobToken; | |
| + /* FIXME: SidsToDisable, PrivilegesToDelete, RestrictedSids */ | |
| + } | |
| + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) | |
| + { | |
| + /* Get exception code */ | |
| + Status = _SEH2_GetExceptionCode(); | |
| + } | |
| + _SEH2_END; | |
| + | |
| + break; | |
| + | |
| + case JobObjectEndOfJobTimeInformation: | |
| + | |
| + /* Check buffer length */ | |
| + if (JobInformationLength != sizeof(JOBOBJECT_END_OF_JOB_TIME_INFORMATION)) | |
| + { | |
| + Status = STATUS_INFO_LENGTH_MISMATCH; | |
| + break; | |
| + } | |
| + | |
| + /* Protect reads with SEH */ | |
| + _SEH2_TRY | |
| + { | |
| + Job->EndOfJobTimeAction = EndOfJobTimeInfo->EndOfJobTimeAction; | |
| + } | |
| + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) | |
| + { | |
| + /* Get exception code */ | |
| + Status = _SEH2_GetExceptionCode(); | |
| + } | |
| + _SEH2_END; | |
| + | |
| + break; | |
| + | |
| + case JobObjectAssociateCompletionPortInformation: | |
| + | |
| + /* Check buffer length */ | |
| + if (JobInformationLength != sizeof(JOBOBJECT_ASSOCIATE_COMPLETION_PORT)) | |
| + { | |
| + Status = STATUS_INFO_LENGTH_MISMATCH; | |
| + break; | |
| + } | |
| + | |
| + /* Protect reads with SEH */ | |
| + _SEH2_TRY | |
| + { | |
| + Job->CompletionKey = AssociateCompletionPort->CompletionKey; | |
| + Job->CompletionPort = AssociateCompletionPort->CompletionPort; | |
| + } | |
| + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) | |
| + { | |
| + /* Get exception code */ | |
| + Status = _SEH2_GetExceptionCode(); | |
| + } | |
| + _SEH2_END; | |
| + | |
| + break; | |
| + | |
| + case JobObjectExtendedLimitInformation: | |
| + | |
| + /* Check buffer length */ | |
| + if (JobInformationLength != sizeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION)) | |
| + { | |
| + Status = STATUS_INFO_LENGTH_MISMATCH; | |
| + break; | |
| + } | |
| + | |
| + /* Protect reads with SEH */ | |
| + _SEH2_TRY | |
| + { | |
| + Job->PerProcessUserTimeLimit = ExtendedLimitInfo->BasicLimitInformation.PerProcessUserTimeLimit; | |
| + Job->PerJobUserTimeLimit = ExtendedLimitInfo->BasicLimitInformation.PerJobUserTimeLimit; | |
| + Job->LimitFlags = ExtendedLimitInfo->BasicLimitInformation.LimitFlags; | |
| + Job->MinimumWorkingSetSize = ExtendedLimitInfo->BasicLimitInformation.MinimumWorkingSetSize; | |
| + Job->MaximumWorkingSetSize = ExtendedLimitInfo->BasicLimitInformation.MaximumWorkingSetSize; | |
| + Job->ActiveProcessLimit = ExtendedLimitInfo->BasicLimitInformation.ActiveProcessLimit; | |
| + Job->Affinity = ExtendedLimitInfo->BasicLimitInformation.Affinity; | |
| + Job->PriorityClass = ExtendedLimitInfo->BasicLimitInformation.PriorityClass; | |
| + Job->SchedulingClass = ExtendedLimitInfo->BasicLimitInformation.SchedulingClass; | |
| + Job->IoInfo = ExtendedLimitInfo->IoInfo; | |
| + Job->ProcessMemoryLimit = ExtendedLimitInfo->ProcessMemoryLimit; | |
| + Job->JobMemoryLimit = ExtendedLimitInfo->JobMemoryLimit; | |
| + Job->PeakProcessMemoryUsed = ExtendedLimitInfo->PeakProcessMemoryUsed; | |
| + Job->PeakJobMemoryUsed = ExtendedLimitInfo->PeakJobMemoryUsed; | |
| + } | |
| + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) | |
| + { | |
| + /* Get exception code */ | |
| + Status = _SEH2_GetExceptionCode(); | |
| + } | |
| + _SEH2_END; | |
| + | |
| + break; | |
| + | |
| + case JobObjectJobSetInformation: | |
| + | |
| + /* Check buffer length */ | |
| + if (JobInformationLength != sizeof(JOBOBJECT_JOBSET_INFORMATION)) | |
| + { | |
| + Status = STATUS_INFO_LENGTH_MISMATCH; | |
| + break; | |
| + } | |
| + | |
| + /* Protect reads with SEH */ | |
| + _SEH2_TRY | |
| + { | |
| + Job->MemberLevel = JobSetInfo->MemberLevel; | |
| + } | |
| + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) | |
| + { | |
| + /* Get exception code */ | |
| + Status = _SEH2_GetExceptionCode(); | |
| + } | |
| + _SEH2_END; | |
| + | |
| + break; | |
| + | |
| + default: | |
| + Status = STATUS_NOT_IMPLEMENTED; | |
| + break; | |
| + } | |
| + | |
| + ExReleaseResourceLite(&Job->JobLock); | |
| + | |
| + if (JobHandle != NULL) | |
| + { | |
| + ObDereferenceObject(Job); | |
| + } | |
| + | |
| + return Status; | |
| } | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment