mirror of
https://github.com/reactos/reactos.git
synced 2024-08-18 01:18:56 +00:00
355 lines
9 KiB
C
355 lines
9 KiB
C
/*
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
* PROJECT: ReactOS system libraries
|
|
* FILE: dll/win32/kernel32/client/job.c
|
|
* PURPOSE: Job functions
|
|
* PROGRAMMER: Thomas Weidenmueller <w3seek@reactos.com>
|
|
* UPDATE HISTORY:
|
|
* Created 9/23/2004
|
|
*/
|
|
|
|
/* INCLUDES *******************************************************************/
|
|
|
|
#include <k32.h>
|
|
#include <winspool.h>
|
|
|
|
#define NDEBUG
|
|
#include <debug.h>
|
|
|
|
/* FUNCTIONS ******************************************************************/
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
HANDLE
|
|
WINAPI
|
|
CreateJobObjectA(IN LPSECURITY_ATTRIBUTES lpJobAttributes,
|
|
IN LPCSTR lpName)
|
|
{
|
|
/* Call the W(ide) function */
|
|
ConvertWin32AnsiObjectApiToUnicodeApi(JobObject, lpName, lpJobAttributes);
|
|
}
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
HANDLE
|
|
WINAPI
|
|
CreateJobObjectW(IN LPSECURITY_ATTRIBUTES lpJobAttributes,
|
|
IN LPCWSTR lpName)
|
|
{
|
|
/* Create the NT object */
|
|
CreateNtObjectFromWin32Api(JobObject, JobObject, JOB_OBJECT_ALL_ACCESS, lpJobAttributes, lpName);
|
|
}
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
HANDLE
|
|
WINAPI
|
|
OpenJobObjectW(IN DWORD dwDesiredAccess,
|
|
IN BOOL bInheritHandle,
|
|
IN LPCWSTR lpName)
|
|
{
|
|
/* Open the NT object */
|
|
OpenNtObjectFromWin32Api(JobObject, dwDesiredAccess, bInheritHandle, lpName);
|
|
}
|
|
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
HANDLE
|
|
WINAPI
|
|
OpenJobObjectA(IN DWORD dwDesiredAccess,
|
|
IN BOOL bInheritHandle,
|
|
IN LPCSTR lpName)
|
|
{
|
|
/* Call the W(ide) function */
|
|
ConvertOpenWin32AnsiObjectApiToUnicodeApi(JobObject, dwDesiredAccess, bInheritHandle, lpName);
|
|
}
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
BOOL
|
|
WINAPI
|
|
IsProcessInJob(IN HANDLE ProcessHandle,
|
|
IN HANDLE JobHandle,
|
|
OUT PBOOL Result)
|
|
{
|
|
NTSTATUS Status;
|
|
|
|
Status = NtIsProcessInJob(ProcessHandle, JobHandle);
|
|
if (NT_SUCCESS(Status))
|
|
{
|
|
*Result = (Status == STATUS_PROCESS_IN_JOB);
|
|
return TRUE;
|
|
}
|
|
|
|
BaseSetLastNTError(Status);
|
|
return FALSE;
|
|
}
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
BOOL
|
|
WINAPI
|
|
AssignProcessToJobObject(IN HANDLE hJob,
|
|
IN HANDLE hProcess)
|
|
{
|
|
NTSTATUS Status;
|
|
|
|
Status = NtAssignProcessToJobObject(hJob, hProcess);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
BaseSetLastNTError(Status);
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
BOOL
|
|
WINAPI
|
|
QueryInformationJobObject(IN HANDLE hJob,
|
|
IN JOBOBJECTINFOCLASS JobObjectInformationClass,
|
|
IN LPVOID lpJobObjectInformation,
|
|
IN DWORD cbJobObjectInformationLength,
|
|
OUT LPDWORD lpReturnLength)
|
|
{
|
|
NTSTATUS Status;
|
|
PVOID JobInfo;
|
|
JOBOBJECT_EXTENDED_LIMIT_INFORMATION LocalInfo;
|
|
ULONG ExpectedSize;
|
|
|
|
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;
|
|
}
|
|
|
|
Status = NtQueryInformationJobObject(hJob,
|
|
JobObjectInformationClass,
|
|
JobInfo,
|
|
ExpectedSize,
|
|
lpReturnLength);
|
|
if (NT_SUCCESS(Status))
|
|
{
|
|
if (JobInfo != &LocalInfo) return TRUE;
|
|
|
|
switch (LocalInfo.BasicLimitInformation.PriorityClass)
|
|
{
|
|
case PROCESS_PRIORITY_CLASS_IDLE:
|
|
LocalInfo.BasicLimitInformation.PriorityClass =
|
|
IDLE_PRIORITY_CLASS;
|
|
break;
|
|
|
|
case PROCESS_PRIORITY_CLASS_BELOW_NORMAL:
|
|
LocalInfo.BasicLimitInformation.PriorityClass =
|
|
BELOW_NORMAL_PRIORITY_CLASS;
|
|
break;
|
|
|
|
case PROCESS_PRIORITY_CLASS_NORMAL:
|
|
LocalInfo.BasicLimitInformation.PriorityClass =
|
|
NORMAL_PRIORITY_CLASS;
|
|
break;
|
|
|
|
case PROCESS_PRIORITY_CLASS_ABOVE_NORMAL:
|
|
LocalInfo.BasicLimitInformation.PriorityClass =
|
|
ABOVE_NORMAL_PRIORITY_CLASS;
|
|
break;
|
|
|
|
case PROCESS_PRIORITY_CLASS_HIGH:
|
|
LocalInfo.BasicLimitInformation.PriorityClass =
|
|
HIGH_PRIORITY_CLASS;
|
|
break;
|
|
|
|
case PROCESS_PRIORITY_CLASS_REALTIME:
|
|
LocalInfo.BasicLimitInformation.PriorityClass =
|
|
REALTIME_PRIORITY_CLASS;
|
|
break;
|
|
|
|
default:
|
|
LocalInfo.BasicLimitInformation.PriorityClass =
|
|
NORMAL_PRIORITY_CLASS;
|
|
break;
|
|
}
|
|
|
|
RtlCopyMemory(lpJobObjectInformation, &LocalInfo, ExpectedSize);
|
|
return TRUE;
|
|
}
|
|
|
|
BaseSetLastNTError(Status);
|
|
return FALSE;
|
|
}
|
|
|
|
/*
|
|
* @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;
|
|
}
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
BOOL
|
|
WINAPI
|
|
TerminateJobObject(IN HANDLE hJob,
|
|
IN UINT uExitCode)
|
|
{
|
|
NTSTATUS Status;
|
|
|
|
Status = NtTerminateJobObject(hJob, uExitCode);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
BaseSetLastNTError(Status);
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
BOOL
|
|
WINAPI
|
|
CreateJobSet(IN ULONG NumJob,
|
|
IN PJOB_SET_ARRAY UserJobSet,
|
|
IN ULONG Flags)
|
|
{
|
|
NTSTATUS Status;
|
|
|
|
Status = NtCreateJobSet(NumJob, UserJobSet, Flags);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
BaseSetLastNTError(Status);
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/* EOF */
|