[KERNEL32]: Implement CreateJobSet

[KERNEL32]: Acquire SE_INCREASE_WORKING_SET_PRIVILEGE in SetInformationJobObject if needed.
[KERNEL32]: Only do conversion of Process Priority Class in SetInformationJobObject if the limit flags request it.
[KERNEL32]: Add missing size checks in QueryInformationJobObject.
[KERNEL32]: Use RtlEncode/DecodePointer to protect the top level exception handler pointer, as done on NT 5.2+
[KERNEL32]: Fix IsBadRead/WritePtr to use the correct page size from the CSRSS shared section.
[KERNEL32]: Fix IsBad(String)Read/WritePtr loops
[KERNEL32]: SetErrorMode now handles SEM_NOALIGNMENTFAULTEXCEPT.
[KERNEL32]: Set/GetErrorMode do not set LastError on failure.
[KERNEL32]: RaiseException can simply use memcpy instead of copying argument by argument.
[KERNEL32]: Minor formatting changes.

svn path=/trunk/; revision=54291
This commit is contained in:
Alex Ionescu 2011-11-05 01:19:52 +00:00
parent c0f989c66a
commit d30964b0fb
7 changed files with 313 additions and 273 deletions

View file

@ -13,8 +13,6 @@
#define NDEBUG
#include <debug.h>
/* TYPES **********************************************************************/
/* FUNCTIONS ******************************************************************/
/*

View file

@ -209,6 +209,9 @@ DllMain(HANDLE hDll,
switch (dwReason)
{
case DLL_PROCESS_ATTACH:
/* Set no filter intially */
GlobalTopLevelExceptionFilter = RtlEncodePointer(NULL);
/* Don't bother us for each thread */
LdrDisableThreadCalloutsForDll((PVOID)hDll);

View file

@ -11,12 +11,13 @@
* Created 01/11/98
*/
/* INCLUDES *******************************************************************/
#include <k32.h>
#define NDEBUG
#include <debug.h>
/* FUNCTIONS ******************************************************************/
/*

View file

@ -10,14 +10,13 @@
* Created 01/11/98
*/
/* INCLUDES *******************************************************************/
#include <k32.h>
#define NDEBUG
#include <debug.h>
LPTOP_LEVEL_EXCEPTION_FILTER GlobalTopLevelExceptionFilter = NULL;
DWORD g_dwLastErrorToBreakOn;
/*
* Private helper function to lookup the module name from a given address.
* The address can point to anywhere within the module.
@ -69,63 +68,6 @@ _dump_context(PCONTEXT pc)
#endif
}
static LONG
BasepCheckForReadOnlyResource(IN PVOID Ptr)
{
PVOID Data;
ULONG Size, OldProtect;
MEMORY_BASIC_INFORMATION mbi;
NTSTATUS Status;
LONG Ret = EXCEPTION_CONTINUE_SEARCH;
/* Check if it was an attempt to write to a read-only image section! */
Status = NtQueryVirtualMemory(NtCurrentProcess(),
Ptr,
MemoryBasicInformation,
&mbi,
sizeof(mbi),
NULL);
if (NT_SUCCESS(Status) &&
mbi.Protect == PAGE_READONLY && mbi.Type == MEM_IMAGE)
{
/* Attempt to treat it as a resource section. We need to
use SEH here because we don't know if it's actually a
resource mapping */
_SEH2_TRY
{
Data = RtlImageDirectoryEntryToData(mbi.AllocationBase,
TRUE,
IMAGE_DIRECTORY_ENTRY_RESOURCE,
&Size);
if (Data != NULL &&
(ULONG_PTR)Ptr >= (ULONG_PTR)Data &&
(ULONG_PTR)Ptr < (ULONG_PTR)Data + Size)
{
/* The user tried to write into the resources. Make the page
writable... */
Size = 1;
Status = NtProtectVirtualMemory(NtCurrentProcess(),
&Ptr,
&Size,
PAGE_READWRITE,
&OldProtect);
if (NT_SUCCESS(Status))
{
Ret = EXCEPTION_CONTINUE_EXECUTION;
}
}
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
}
_SEH2_END;
}
return Ret;
}
static VOID
PrintStackTrace(struct _EXCEPTION_POINTERS *ExceptionInfo)
{
@ -188,6 +130,70 @@ PrintStackTrace(struct _EXCEPTION_POINTERS *ExceptionInfo)
#endif
}
/* GLOBALS ********************************************************************/
LPTOP_LEVEL_EXCEPTION_FILTER GlobalTopLevelExceptionFilter;
DWORD g_dwLastErrorToBreakOn;
/* FUNCTIONS ******************************************************************/
LONG
WINAPI
BasepCheckForReadOnlyResource(IN PVOID Ptr)
{
PVOID Data;
ULONG Size, OldProtect;
MEMORY_BASIC_INFORMATION mbi;
NTSTATUS Status;
LONG Ret = EXCEPTION_CONTINUE_SEARCH;
/* Check if it was an attempt to write to a read-only image section! */
Status = NtQueryVirtualMemory(NtCurrentProcess(),
Ptr,
MemoryBasicInformation,
&mbi,
sizeof(mbi),
NULL);
if (NT_SUCCESS(Status) &&
mbi.Protect == PAGE_READONLY && mbi.Type == MEM_IMAGE)
{
/* Attempt to treat it as a resource section. We need to
use SEH here because we don't know if it's actually a
resource mapping */
_SEH2_TRY
{
Data = RtlImageDirectoryEntryToData(mbi.AllocationBase,
TRUE,
IMAGE_DIRECTORY_ENTRY_RESOURCE,
&Size);
if (Data != NULL &&
(ULONG_PTR)Ptr >= (ULONG_PTR)Data &&
(ULONG_PTR)Ptr < (ULONG_PTR)Data + Size)
{
/* The user tried to write into the resources. Make the page
writable... */
Size = 1;
Status = NtProtectVirtualMemory(NtCurrentProcess(),
&Ptr,
&Size,
PAGE_READWRITE,
&OldProtect);
if (NT_SUCCESS(Status))
{
Ret = EXCEPTION_CONTINUE_EXECUTION;
}
}
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
}
_SEH2_END;
}
return Ret;
}
UINT
WINAPI
GetErrorMode(VOID)
@ -272,9 +278,11 @@ UnhandledExceptionFilter(struct _EXCEPTION_POINTERS *ExceptionInfo)
return EXCEPTION_CONTINUE_SEARCH;
}
if (GlobalTopLevelExceptionFilter)
LPTOP_LEVEL_EXCEPTION_FILTER RealFilter;
RealFilter = RtlDecodePointer(GlobalTopLevelExceptionFilter);
if (RealFilter)
{
LONG ret = GlobalTopLevelExceptionFilter(ExceptionInfo);
LONG ret = RealFilter(ExceptionInfo);
if (ret != EXCEPTION_CONTINUE_SEARCH)
return ret;
}
@ -351,20 +359,14 @@ RaiseException(IN DWORD dwExceptionCode,
nNumberOfArguments = EXCEPTION_MAXIMUM_PARAMETERS;
}
/* Set the count of parameters */
/* Set the count of parameters and copy them */
ExceptionRecord.NumberParameters = nNumberOfArguments;
/* Loop each parameter */
for (nNumberOfArguments = 0;
(nNumberOfArguments < ExceptionRecord.NumberParameters);
nNumberOfArguments ++)
{
/* Copy the exception information */
ExceptionRecord.ExceptionInformation[nNumberOfArguments] =
*lpArguments++;
}
RtlCopyMemory(ExceptionRecord.ExceptionInformation,
lpArguments,
nNumberOfArguments * sizeof(ULONG));
}
/* Better handling of Delphi Exceptions... a ReactOS Hack */
if (dwExceptionCode == 0xeedface || dwExceptionCode == 0xeedfade)
{
DPRINT1("Delphi Exception at address: %p\n", ExceptionRecord.ExceptionInformation[0]);
@ -413,12 +415,14 @@ SetErrorMode(IN UINT uMode)
NewMode |= SEM_FAILCRITICALERRORS;
}
/* Always keep no alignment faults if they were set */
NewMode |= (PrevErrMode & SEM_NOALIGNMENTFAULTEXCEPT);
/* Set the new mode */
Status = NtSetInformationProcess(NtCurrentProcess(),
ProcessDefaultHardErrorMode,
(PVOID)&NewMode,
sizeof(NewMode));
if(!NT_SUCCESS(Status)) BaseSetLastNTError(Status);
/* Return the previous mode */
return PrevErrMode;
@ -429,11 +433,14 @@ SetErrorMode(IN UINT uMode)
*/
LPTOP_LEVEL_EXCEPTION_FILTER
WINAPI
SetUnhandledExceptionFilter(
IN LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter)
SetUnhandledExceptionFilter(IN LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter)
{
return InterlockedExchangePointer(&GlobalTopLevelExceptionFilter,
lpTopLevelExceptionFilter);
PVOID EncodedPointer, NewPointer;
EncodedPointer = RtlEncodePointer(lpTopLevelExceptionFilter);
NewPointer = InterlockedExchangePointer(&GlobalTopLevelExceptionFilter,
EncodedPointer);
return RtlDecodePointer(EncodedPointer);
}
/*
@ -444,7 +451,7 @@ WINAPI
IsBadReadPtr(IN LPCVOID lp,
IN UINT_PTR ucb)
{
//ULONG PageSize;
ULONG PageSize;
BOOLEAN Result = FALSE;
volatile CHAR *Current;
PCHAR Last;
@ -454,25 +461,31 @@ IsBadReadPtr(IN LPCVOID lp,
if (!lp) return TRUE;
/* Get the page size */
//PageSize = BaseStaticServerData->SysInfo.PageSize;
PageSize = BaseStaticServerData->SysInfo.PageSize;
/* Calculate the last page */
/* Calculate start and end */
Current = (volatile CHAR*)lp;
Last = (PCHAR)((ULONG_PTR)lp + ucb - 1);
/* Another quick failure case */
if ((ULONG_PTR)Last < (ULONG_PTR)lp) return TRUE;
if (Last < Current) return TRUE;
/* Enter SEH */
_SEH2_TRY
{
/* Do an initial probe */
*Current;
/* Align the addresses */
Current = (volatile CHAR *)ROUND_DOWN(Current, PageSize);
Last = (PCHAR)ROUND_DOWN(Last, PageSize);
/* Probe the entire range */
Current = (volatile CHAR*)lp;
Last = (PCHAR)(PAGE_ROUND_DOWN(Last));
do
while (Current != Last)
{
Current += PageSize;
*Current;
Current = (volatile CHAR*)(PAGE_ROUND_DOWN(Current) + PAGE_SIZE);
} while (Current <= Last);
}
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
@ -513,10 +526,10 @@ IsBadCodePtr(FARPROC lpfn)
*/
BOOL
NTAPI
IsBadWritePtr(LPVOID lp,
UINT_PTR ucb)
IsBadWritePtr(IN LPVOID lp,
IN UINT_PTR ucb)
{
//ULONG PageSize;
ULONG PageSize;
BOOLEAN Result = FALSE;
volatile CHAR *Current;
PCHAR Last;
@ -526,25 +539,31 @@ IsBadWritePtr(LPVOID lp,
if (!lp) return TRUE;
/* Get the page size */
//PageSize = BaseStaticServerData->SysInfo.PageSize;
PageSize = BaseStaticServerData->SysInfo.PageSize;
/* Calculate the last page */
/* Calculate start and end */
Current = (volatile CHAR*)lp;
Last = (PCHAR)((ULONG_PTR)lp + ucb - 1);
/* Another quick failure case */
if ((ULONG_PTR)Last < (ULONG_PTR)lp) return TRUE;
if (Last < Current) return TRUE;
/* Enter SEH */
_SEH2_TRY
{
/* Do an initial probe */
*Current = *Current;
/* Align the addresses */
Current = (volatile CHAR *)ROUND_DOWN(Current, PageSize);
Last = (PCHAR)ROUND_DOWN(Last, PageSize);
/* Probe the entire range */
Current = (volatile CHAR*)lp;
Last = (PCHAR)(PAGE_ROUND_DOWN(Last));
do
while (Current != Last)
{
Current += PageSize;
*Current = *Current;
Current = (volatile CHAR*)(PAGE_ROUND_DOWN(Current) + PAGE_SIZE);
} while (Current <= Last);
}
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
@ -562,8 +581,8 @@ IsBadWritePtr(LPVOID lp,
*/
BOOL
NTAPI
IsBadHugeWritePtr(LPVOID lp,
UINT_PTR ucb)
IsBadHugeWritePtr(IN LPVOID lp,
IN UINT_PTR ucb)
{
/* Implementation is the same on 32-bit */
return IsBadWritePtr(lp, ucb);
@ -575,7 +594,7 @@ IsBadHugeWritePtr(LPVOID lp,
BOOL
NTAPI
IsBadStringPtrW(IN LPCWSTR lpsz,
UINT_PTR ucchMax)
IN UINT_PTR ucchMax)
{
BOOLEAN Result = FALSE;
volatile WCHAR *Current;
@ -586,20 +605,16 @@ IsBadStringPtrW(IN LPCWSTR lpsz,
if (!ucchMax) return FALSE;
if (!lpsz) return TRUE;
/* Calculate the last page */
/* Calculate start and end */
Current = (volatile WCHAR*)lpsz;
Last = (PWCHAR)((ULONG_PTR)lpsz + (ucchMax * 2) - 2);
/* Enter SEH */
_SEH2_TRY
{
/* Probe the entire range */
Current = (volatile WCHAR*)lpsz;
Last = (PWCHAR)(PAGE_ROUND_DOWN(Last));
do
{
Char = *Current;
Current++;
} while (Char && (Current != Last + 1));
Char = *Current++;
while ((Char) && (Current != Last)) Char = *Current++;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
@ -618,7 +633,7 @@ IsBadStringPtrW(IN LPCWSTR lpsz,
BOOL
NTAPI
IsBadStringPtrA(IN LPCSTR lpsz,
UINT_PTR ucchMax)
IN UINT_PTR ucchMax)
{
BOOLEAN Result = FALSE;
volatile CHAR *Current;
@ -629,20 +644,16 @@ IsBadStringPtrA(IN LPCSTR lpsz,
if (!ucchMax) return FALSE;
if (!lpsz) return TRUE;
/* Calculate the last page */
/* Calculate start and end */
Current = (volatile CHAR*)lpsz;
Last = (PCHAR)((ULONG_PTR)lpsz + ucchMax - 1);
/* Enter SEH */
_SEH2_TRY
{
/* Probe the entire range */
Current = (volatile CHAR*)lpsz;
Last = (PCHAR)(PAGE_ROUND_DOWN(Last));
do
{
Char = *Current;
Current++;
} while (Char && (Current != Last + 1));
Char = *Current++;
while ((Char) && (Current != Last)) Char = *Current++;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{

View file

@ -9,14 +9,14 @@
* Created 9/23/2004
*/
/* INCLUDES ****************************************************************/
/* INCLUDES *******************************************************************/
#include <k32.h>
#define NDEBUG
#include <debug.h>
/* FUNCTIONS ****************************************************************/
/* FUNCTIONS ******************************************************************/
/*
* @implemented
@ -47,9 +47,9 @@ CreateJobObjectW(IN LPSECURITY_ATTRIBUTES lpJobAttributes,
*/
HANDLE
WINAPI
OpenJobObjectW(DWORD dwDesiredAccess,
BOOL bInheritHandle,
LPCWSTR lpName)
OpenJobObjectW(IN DWORD dwDesiredAccess,
IN BOOL bInheritHandle,
IN LPCWSTR lpName)
{
/* Open the NT object */
OpenNtObjectFromWin32Api(JobObject, dwDesiredAccess, bInheritHandle, lpName);
@ -61,23 +61,22 @@ OpenJobObjectW(DWORD dwDesiredAccess,
*/
HANDLE
WINAPI
OpenJobObjectA(DWORD dwDesiredAccess,
BOOL bInheritHandle,
LPCSTR lpName)
OpenJobObjectA(IN DWORD dwDesiredAccess,
IN BOOL bInheritHandle,
IN LPCSTR lpName)
{
/* Call the W(ide) function */
ConvertOpenWin32AnsiObjectApiToUnicodeApi(JobObject, dwDesiredAccess, bInheritHandle, lpName);
}
/*
* @implemented
*/
BOOL
WINAPI
IsProcessInJob(HANDLE ProcessHandle,
HANDLE JobHandle,
PBOOL Result)
IsProcessInJob(IN HANDLE ProcessHandle,
IN HANDLE JobHandle,
OUT PBOOL Result)
{
NTSTATUS Status;
@ -92,14 +91,13 @@ IsProcessInJob(HANDLE ProcessHandle,
return FALSE;
}
/*
* @implemented
*/
BOOL
WINAPI
AssignProcessToJobObject(HANDLE hJob,
HANDLE hProcess)
AssignProcessToJobObject(IN HANDLE hJob,
IN HANDLE hProcess)
{
NTSTATUS Status;
@ -113,81 +111,92 @@ AssignProcessToJobObject(HANDLE hJob,
return TRUE;
}
/*
* @implemented
*/
BOOL
WINAPI
QueryInformationJobObject(HANDLE hJob,
JOBOBJECTINFOCLASS JobObjectInformationClass,
LPVOID lpJobObjectInformation,
DWORD cbJobObjectInformationLength,
LPDWORD lpReturnLength)
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 == JobObjectBasicLimitInformation)
{
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,
lpJobObjectInformation,
cbJobObjectInformationLength,
JobInfo,
ExpectedSize,
lpReturnLength);
if (NT_SUCCESS(Status))
{
PJOBOBJECT_BASIC_LIMIT_INFORMATION BasicInfo;
if (JobInfo != &LocalInfo) return TRUE;
switch (JobObjectInformationClass)
switch (LocalInfo.BasicLimitInformation.PriorityClass)
{
case JobObjectBasicLimitInformation:
BasicInfo = (PJOBOBJECT_BASIC_LIMIT_INFORMATION)lpJobObjectInformation;
case PROCESS_PRIORITY_CLASS_IDLE:
LocalInfo.BasicLimitInformation.PriorityClass =
IDLE_PRIORITY_CLASS;
break;
case JobObjectExtendedLimitInformation:
BasicInfo = &((PJOBOBJECT_EXTENDED_LIMIT_INFORMATION)lpJobObjectInformation)->BasicLimitInformation;
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:
BasicInfo = NULL;
LocalInfo.BasicLimitInformation.PriorityClass =
NORMAL_PRIORITY_CLASS;
break;
}
if (BasicInfo != NULL)
{
/* we need to convert the process priority classes in the
JOBOBJECT_BASIC_LIMIT_INFORMATION structure the same way as
GetPriorityClass() converts it! */
switch (BasicInfo->PriorityClass)
{
case PROCESS_PRIORITY_CLASS_IDLE:
BasicInfo->PriorityClass = IDLE_PRIORITY_CLASS;
break;
case PROCESS_PRIORITY_CLASS_BELOW_NORMAL:
BasicInfo->PriorityClass = BELOW_NORMAL_PRIORITY_CLASS;
break;
case PROCESS_PRIORITY_CLASS_NORMAL:
BasicInfo->PriorityClass = NORMAL_PRIORITY_CLASS;
break;
case PROCESS_PRIORITY_CLASS_ABOVE_NORMAL:
BasicInfo->PriorityClass = ABOVE_NORMAL_PRIORITY_CLASS;
break;
case PROCESS_PRIORITY_CLASS_HIGH:
BasicInfo->PriorityClass = HIGH_PRIORITY_CLASS;
break;
case PROCESS_PRIORITY_CLASS_REALTIME:
BasicInfo->PriorityClass = REALTIME_PRIORITY_CLASS;
break;
default:
BasicInfo->PriorityClass = NORMAL_PRIORITY_CLASS;
break;
}
}
RtlCopyMemory(lpJobObjectInformation, &LocalInfo, ExpectedSize);
return TRUE;
}
@ -195,112 +204,119 @@ QueryInformationJobObject(HANDLE hJob,
return FALSE;
}
/*
* @implemented
*/
BOOL
WINAPI
SetInformationJobObject(HANDLE hJob,
JOBOBJECTINFOCLASS JobObjectInformationClass,
LPVOID lpJobObjectInformation,
DWORD cbJobObjectInformationLength)
SetInformationJobObject(IN HANDLE hJob,
IN JOBOBJECTINFOCLASS JobObjectInformationClass,
IN LPVOID lpJobObjectInformation,
IN DWORD cbJobObjectInformationLength)
{
JOBOBJECT_EXTENDED_LIMIT_INFORMATION ExtendedLimitInfo;
PJOBOBJECT_BASIC_LIMIT_INFORMATION BasicInfo;
PVOID ObjectInfo;
NTSTATUS Status;
PVOID JobInfo;
JOBOBJECT_EXTENDED_LIMIT_INFORMATION LocalInfo;
ULONG ExpectedSize;
PVOID State = NULL;
ULONG Privilege = SE_INC_BASE_PRIORITY_PRIVILEGE;
switch (JobObjectInformationClass)
if (JobObjectInformationClass == JobObjectBasicLimitInformation)
{
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;
ExpectedSize = sizeof(JOBOBJECT_BASIC_LIMIT_INFORMATION);
JobInfo = &LocalInfo;
}
else if (JobObjectInformationClass == JobObjectBasicLimitInformation)
{
ExpectedSize = sizeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION);
JobInfo = &LocalInfo;
}
else
{
ExpectedSize = cbJobObjectInformationLength;
JobInfo = lpJobObjectInformation;
}
if (BasicInfo != NULL)
if (cbJobObjectInformationLength != ExpectedSize)
{
/* 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)
BaseSetLastNTError(STATUS_INFO_LENGTH_MISMATCH);
return FALSE;
}
if (JobInfo == &LocalInfo)
{
RtlCopyMemory(&LocalInfo, lpJobObjectInformation, ExpectedSize);
if (LocalInfo.BasicLimitInformation.LimitFlags &
JOB_OBJECT_LIMIT_PRIORITY_CLASS)
{
case IDLE_PRIORITY_CLASS:
BasicInfo->PriorityClass = PROCESS_PRIORITY_CLASS_IDLE;
break;
switch (LocalInfo.BasicLimitInformation.PriorityClass)
{
case IDLE_PRIORITY_CLASS:
LocalInfo.BasicLimitInformation.PriorityClass =
PROCESS_PRIORITY_CLASS_IDLE;
break;
case BELOW_NORMAL_PRIORITY_CLASS:
BasicInfo->PriorityClass = PROCESS_PRIORITY_CLASS_BELOW_NORMAL;
break;
case BELOW_NORMAL_PRIORITY_CLASS:
LocalInfo.BasicLimitInformation.PriorityClass =
PROCESS_PRIORITY_CLASS_BELOW_NORMAL;
break;
case NORMAL_PRIORITY_CLASS:
BasicInfo->PriorityClass = PROCESS_PRIORITY_CLASS_NORMAL;
break;
case NORMAL_PRIORITY_CLASS:
LocalInfo.BasicLimitInformation.PriorityClass =
PROCESS_PRIORITY_CLASS_NORMAL;
break;
case ABOVE_NORMAL_PRIORITY_CLASS:
BasicInfo->PriorityClass = PROCESS_PRIORITY_CLASS_ABOVE_NORMAL;
break;
case ABOVE_NORMAL_PRIORITY_CLASS:
LocalInfo.BasicLimitInformation.PriorityClass =
PROCESS_PRIORITY_CLASS_ABOVE_NORMAL;
break;
case HIGH_PRIORITY_CLASS:
BasicInfo->PriorityClass = PROCESS_PRIORITY_CLASS_HIGH;
break;
case HIGH_PRIORITY_CLASS:
LocalInfo.BasicLimitInformation.PriorityClass =
PROCESS_PRIORITY_CLASS_HIGH;
break;
case REALTIME_PRIORITY_CLASS:
BasicInfo->PriorityClass = PROCESS_PRIORITY_CLASS_REALTIME;
break;
case REALTIME_PRIORITY_CLASS:
LocalInfo.BasicLimitInformation.PriorityClass =
PROCESS_PRIORITY_CLASS_REALTIME;
break;
default:
BasicInfo->PriorityClass = PROCESS_PRIORITY_CLASS_NORMAL;
break;
default:
LocalInfo.BasicLimitInformation.PriorityClass =
PROCESS_PRIORITY_CLASS_NORMAL;
break;
}
}
if (LocalInfo.BasicLimitInformation.LimitFlags &
JOB_OBJECT_LIMIT_WORKINGSET)
{
Status = RtlAcquirePrivilege(&Privilege, TRUE, FALSE, &State);
}
}
Status = NtSetInformationJobObject(hJob,
JobObjectInformationClass,
ObjectInfo,
cbJobObjectInformationLength);
if (!NT_SUCCESS(Status))
JobInfo,
ExpectedSize);
if (NT_SUCCESS(Status))
{
BaseSetLastNTError(Status);
return FALSE;
if (State != NULL) RtlReleasePrivilege(State);
return TRUE;
}
return TRUE;
BaseSetLastNTError(Status);
return FALSE;
}
/*
* @implemented
*/
BOOL
WINAPI
TerminateJobObject(HANDLE hJob,
UINT uExitCode)
TerminateJobObject(IN HANDLE hJob,
IN UINT uExitCode)
{
NTSTATUS Status;
@ -315,17 +331,24 @@ TerminateJobObject(HANDLE hJob,
}
/*
* @unimplemented
* @implemented
*/
BOOL
WINAPI
CreateJobSet (
ULONG NumJob,
PJOB_SET_ARRAY UserJobSet,
ULONG Flags)
CreateJobSet(IN ULONG NumJob,
IN PJOB_SET_ARRAY UserJobSet,
IN ULONG Flags)
{
STUB;
return 0;
NTSTATUS Status;
Status = NtCreateJobSet(NumJob, UserJobSet, Flags);
if (!NT_SUCCESS(Status))
{
BaseSetLastNTError(Status);
return FALSE;
}
return TRUE;
}
/* EOF */

View file

@ -49,12 +49,14 @@ static
LONG BaseExceptionFilter(EXCEPTION_POINTERS *ExceptionInfo)
{
LONG ExceptionDisposition = EXCEPTION_EXECUTE_HANDLER;
LPTOP_LEVEL_EXCEPTION_FILTER RealFilter;
RealFilter = RtlDecodePointer(GlobalTopLevelExceptionFilter);
if (GlobalTopLevelExceptionFilter != NULL)
if (RealFilter != NULL)
{
_SEH2_TRY
{
ExceptionDisposition = GlobalTopLevelExceptionFilter(ExceptionInfo);
ExceptionDisposition = RealFilter(ExceptionInfo);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
@ -62,7 +64,7 @@ LONG BaseExceptionFilter(EXCEPTION_POINTERS *ExceptionInfo)
_SEH2_END;
}
if ((ExceptionDisposition == EXCEPTION_CONTINUE_SEARCH || ExceptionDisposition == EXCEPTION_EXECUTE_HANDLER) &&
GlobalTopLevelExceptionFilter != UnhandledExceptionFilter)
RealFilter != UnhandledExceptionFilter)
{
ExceptionDisposition = UnhandledExceptionFilter(ExceptionInfo);
}

View file

@ -29,12 +29,14 @@ static
LONG BaseThreadExceptionFilter(EXCEPTION_POINTERS * ExceptionInfo)
{
LONG ExceptionDisposition = EXCEPTION_EXECUTE_HANDLER;
if (GlobalTopLevelExceptionFilter != NULL)
LPTOP_LEVEL_EXCEPTION_FILTER RealFilter;
RealFilter = RtlDecodePointer(GlobalTopLevelExceptionFilter);
if (RealFilter != NULL)
{
_SEH2_TRY
{
ExceptionDisposition = GlobalTopLevelExceptionFilter(ExceptionInfo);
ExceptionDisposition = RealFilter(ExceptionInfo);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{