mirror of
https://github.com/reactos/reactos.git
synced 2024-08-07 19:58:21 +00:00
[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:
parent
c0f989c66a
commit
d30964b0fb
|
@ -13,8 +13,6 @@
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
/* TYPES **********************************************************************/
|
|
||||||
|
|
||||||
/* FUNCTIONS ******************************************************************/
|
/* FUNCTIONS ******************************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -209,6 +209,9 @@ DllMain(HANDLE hDll,
|
||||||
switch (dwReason)
|
switch (dwReason)
|
||||||
{
|
{
|
||||||
case DLL_PROCESS_ATTACH:
|
case DLL_PROCESS_ATTACH:
|
||||||
|
|
||||||
|
/* Set no filter intially */
|
||||||
|
GlobalTopLevelExceptionFilter = RtlEncodePointer(NULL);
|
||||||
|
|
||||||
/* Don't bother us for each thread */
|
/* Don't bother us for each thread */
|
||||||
LdrDisableThreadCalloutsForDll((PVOID)hDll);
|
LdrDisableThreadCalloutsForDll((PVOID)hDll);
|
||||||
|
|
|
@ -11,12 +11,13 @@
|
||||||
* Created 01/11/98
|
* Created 01/11/98
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* INCLUDES *******************************************************************/
|
||||||
|
|
||||||
#include <k32.h>
|
#include <k32.h>
|
||||||
|
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
|
|
||||||
/* FUNCTIONS ******************************************************************/
|
/* FUNCTIONS ******************************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -10,14 +10,13 @@
|
||||||
* Created 01/11/98
|
* Created 01/11/98
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* INCLUDES *******************************************************************/
|
||||||
|
|
||||||
#include <k32.h>
|
#include <k32.h>
|
||||||
|
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
LPTOP_LEVEL_EXCEPTION_FILTER GlobalTopLevelExceptionFilter = NULL;
|
|
||||||
DWORD g_dwLastErrorToBreakOn;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Private helper function to lookup the module name from a given address.
|
* Private helper function to lookup the module name from a given address.
|
||||||
* The address can point to anywhere within the module.
|
* The address can point to anywhere within the module.
|
||||||
|
@ -69,63 +68,6 @@ _dump_context(PCONTEXT pc)
|
||||||
#endif
|
#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
|
static VOID
|
||||||
PrintStackTrace(struct _EXCEPTION_POINTERS *ExceptionInfo)
|
PrintStackTrace(struct _EXCEPTION_POINTERS *ExceptionInfo)
|
||||||
{
|
{
|
||||||
|
@ -188,6 +130,70 @@ PrintStackTrace(struct _EXCEPTION_POINTERS *ExceptionInfo)
|
||||||
#endif
|
#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
|
UINT
|
||||||
WINAPI
|
WINAPI
|
||||||
GetErrorMode(VOID)
|
GetErrorMode(VOID)
|
||||||
|
@ -272,9 +278,11 @@ UnhandledExceptionFilter(struct _EXCEPTION_POINTERS *ExceptionInfo)
|
||||||
return EXCEPTION_CONTINUE_SEARCH;
|
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)
|
if (ret != EXCEPTION_CONTINUE_SEARCH)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -351,20 +359,14 @@ RaiseException(IN DWORD dwExceptionCode,
|
||||||
nNumberOfArguments = EXCEPTION_MAXIMUM_PARAMETERS;
|
nNumberOfArguments = EXCEPTION_MAXIMUM_PARAMETERS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the count of parameters */
|
/* Set the count of parameters and copy them */
|
||||||
ExceptionRecord.NumberParameters = nNumberOfArguments;
|
ExceptionRecord.NumberParameters = nNumberOfArguments;
|
||||||
|
RtlCopyMemory(ExceptionRecord.ExceptionInformation,
|
||||||
/* Loop each parameter */
|
lpArguments,
|
||||||
for (nNumberOfArguments = 0;
|
nNumberOfArguments * sizeof(ULONG));
|
||||||
(nNumberOfArguments < ExceptionRecord.NumberParameters);
|
|
||||||
nNumberOfArguments ++)
|
|
||||||
{
|
|
||||||
/* Copy the exception information */
|
|
||||||
ExceptionRecord.ExceptionInformation[nNumberOfArguments] =
|
|
||||||
*lpArguments++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Better handling of Delphi Exceptions... a ReactOS Hack */
|
||||||
if (dwExceptionCode == 0xeedface || dwExceptionCode == 0xeedfade)
|
if (dwExceptionCode == 0xeedface || dwExceptionCode == 0xeedfade)
|
||||||
{
|
{
|
||||||
DPRINT1("Delphi Exception at address: %p\n", ExceptionRecord.ExceptionInformation[0]);
|
DPRINT1("Delphi Exception at address: %p\n", ExceptionRecord.ExceptionInformation[0]);
|
||||||
|
@ -413,12 +415,14 @@ SetErrorMode(IN UINT uMode)
|
||||||
NewMode |= SEM_FAILCRITICALERRORS;
|
NewMode |= SEM_FAILCRITICALERRORS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Always keep no alignment faults if they were set */
|
||||||
|
NewMode |= (PrevErrMode & SEM_NOALIGNMENTFAULTEXCEPT);
|
||||||
|
|
||||||
/* Set the new mode */
|
/* Set the new mode */
|
||||||
Status = NtSetInformationProcess(NtCurrentProcess(),
|
Status = NtSetInformationProcess(NtCurrentProcess(),
|
||||||
ProcessDefaultHardErrorMode,
|
ProcessDefaultHardErrorMode,
|
||||||
(PVOID)&NewMode,
|
(PVOID)&NewMode,
|
||||||
sizeof(NewMode));
|
sizeof(NewMode));
|
||||||
if(!NT_SUCCESS(Status)) BaseSetLastNTError(Status);
|
|
||||||
|
|
||||||
/* Return the previous mode */
|
/* Return the previous mode */
|
||||||
return PrevErrMode;
|
return PrevErrMode;
|
||||||
|
@ -429,11 +433,14 @@ SetErrorMode(IN UINT uMode)
|
||||||
*/
|
*/
|
||||||
LPTOP_LEVEL_EXCEPTION_FILTER
|
LPTOP_LEVEL_EXCEPTION_FILTER
|
||||||
WINAPI
|
WINAPI
|
||||||
SetUnhandledExceptionFilter(
|
SetUnhandledExceptionFilter(IN LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter)
|
||||||
IN LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter)
|
|
||||||
{
|
{
|
||||||
return InterlockedExchangePointer(&GlobalTopLevelExceptionFilter,
|
PVOID EncodedPointer, NewPointer;
|
||||||
lpTopLevelExceptionFilter);
|
|
||||||
|
EncodedPointer = RtlEncodePointer(lpTopLevelExceptionFilter);
|
||||||
|
NewPointer = InterlockedExchangePointer(&GlobalTopLevelExceptionFilter,
|
||||||
|
EncodedPointer);
|
||||||
|
return RtlDecodePointer(EncodedPointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -444,7 +451,7 @@ WINAPI
|
||||||
IsBadReadPtr(IN LPCVOID lp,
|
IsBadReadPtr(IN LPCVOID lp,
|
||||||
IN UINT_PTR ucb)
|
IN UINT_PTR ucb)
|
||||||
{
|
{
|
||||||
//ULONG PageSize;
|
ULONG PageSize;
|
||||||
BOOLEAN Result = FALSE;
|
BOOLEAN Result = FALSE;
|
||||||
volatile CHAR *Current;
|
volatile CHAR *Current;
|
||||||
PCHAR Last;
|
PCHAR Last;
|
||||||
|
@ -454,25 +461,31 @@ IsBadReadPtr(IN LPCVOID lp,
|
||||||
if (!lp) return TRUE;
|
if (!lp) return TRUE;
|
||||||
|
|
||||||
/* Get the page size */
|
/* 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);
|
Last = (PCHAR)((ULONG_PTR)lp + ucb - 1);
|
||||||
|
|
||||||
/* Another quick failure case */
|
/* Another quick failure case */
|
||||||
if ((ULONG_PTR)Last < (ULONG_PTR)lp) return TRUE;
|
if (Last < Current) return TRUE;
|
||||||
|
|
||||||
/* Enter SEH */
|
/* Enter SEH */
|
||||||
_SEH2_TRY
|
_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 */
|
/* Probe the entire range */
|
||||||
Current = (volatile CHAR*)lp;
|
while (Current != Last)
|
||||||
Last = (PCHAR)(PAGE_ROUND_DOWN(Last));
|
|
||||||
do
|
|
||||||
{
|
{
|
||||||
|
Current += PageSize;
|
||||||
*Current;
|
*Current;
|
||||||
Current = (volatile CHAR*)(PAGE_ROUND_DOWN(Current) + PAGE_SIZE);
|
}
|
||||||
} while (Current <= Last);
|
|
||||||
}
|
}
|
||||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
{
|
{
|
||||||
|
@ -513,10 +526,10 @@ IsBadCodePtr(FARPROC lpfn)
|
||||||
*/
|
*/
|
||||||
BOOL
|
BOOL
|
||||||
NTAPI
|
NTAPI
|
||||||
IsBadWritePtr(LPVOID lp,
|
IsBadWritePtr(IN LPVOID lp,
|
||||||
UINT_PTR ucb)
|
IN UINT_PTR ucb)
|
||||||
{
|
{
|
||||||
//ULONG PageSize;
|
ULONG PageSize;
|
||||||
BOOLEAN Result = FALSE;
|
BOOLEAN Result = FALSE;
|
||||||
volatile CHAR *Current;
|
volatile CHAR *Current;
|
||||||
PCHAR Last;
|
PCHAR Last;
|
||||||
|
@ -526,25 +539,31 @@ IsBadWritePtr(LPVOID lp,
|
||||||
if (!lp) return TRUE;
|
if (!lp) return TRUE;
|
||||||
|
|
||||||
/* Get the page size */
|
/* 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);
|
Last = (PCHAR)((ULONG_PTR)lp + ucb - 1);
|
||||||
|
|
||||||
/* Another quick failure case */
|
/* Another quick failure case */
|
||||||
if ((ULONG_PTR)Last < (ULONG_PTR)lp) return TRUE;
|
if (Last < Current) return TRUE;
|
||||||
|
|
||||||
/* Enter SEH */
|
/* Enter SEH */
|
||||||
_SEH2_TRY
|
_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 */
|
/* Probe the entire range */
|
||||||
Current = (volatile CHAR*)lp;
|
while (Current != Last)
|
||||||
Last = (PCHAR)(PAGE_ROUND_DOWN(Last));
|
|
||||||
do
|
|
||||||
{
|
{
|
||||||
|
Current += PageSize;
|
||||||
*Current = *Current;
|
*Current = *Current;
|
||||||
Current = (volatile CHAR*)(PAGE_ROUND_DOWN(Current) + PAGE_SIZE);
|
}
|
||||||
} while (Current <= Last);
|
|
||||||
}
|
}
|
||||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
{
|
{
|
||||||
|
@ -562,8 +581,8 @@ IsBadWritePtr(LPVOID lp,
|
||||||
*/
|
*/
|
||||||
BOOL
|
BOOL
|
||||||
NTAPI
|
NTAPI
|
||||||
IsBadHugeWritePtr(LPVOID lp,
|
IsBadHugeWritePtr(IN LPVOID lp,
|
||||||
UINT_PTR ucb)
|
IN UINT_PTR ucb)
|
||||||
{
|
{
|
||||||
/* Implementation is the same on 32-bit */
|
/* Implementation is the same on 32-bit */
|
||||||
return IsBadWritePtr(lp, ucb);
|
return IsBadWritePtr(lp, ucb);
|
||||||
|
@ -575,7 +594,7 @@ IsBadHugeWritePtr(LPVOID lp,
|
||||||
BOOL
|
BOOL
|
||||||
NTAPI
|
NTAPI
|
||||||
IsBadStringPtrW(IN LPCWSTR lpsz,
|
IsBadStringPtrW(IN LPCWSTR lpsz,
|
||||||
UINT_PTR ucchMax)
|
IN UINT_PTR ucchMax)
|
||||||
{
|
{
|
||||||
BOOLEAN Result = FALSE;
|
BOOLEAN Result = FALSE;
|
||||||
volatile WCHAR *Current;
|
volatile WCHAR *Current;
|
||||||
|
@ -586,20 +605,16 @@ IsBadStringPtrW(IN LPCWSTR lpsz,
|
||||||
if (!ucchMax) return FALSE;
|
if (!ucchMax) return FALSE;
|
||||||
if (!lpsz) return TRUE;
|
if (!lpsz) return TRUE;
|
||||||
|
|
||||||
/* Calculate the last page */
|
/* Calculate start and end */
|
||||||
|
Current = (volatile WCHAR*)lpsz;
|
||||||
Last = (PWCHAR)((ULONG_PTR)lpsz + (ucchMax * 2) - 2);
|
Last = (PWCHAR)((ULONG_PTR)lpsz + (ucchMax * 2) - 2);
|
||||||
|
|
||||||
/* Enter SEH */
|
/* Enter SEH */
|
||||||
_SEH2_TRY
|
_SEH2_TRY
|
||||||
{
|
{
|
||||||
/* Probe the entire range */
|
/* Probe the entire range */
|
||||||
Current = (volatile WCHAR*)lpsz;
|
Char = *Current++;
|
||||||
Last = (PWCHAR)(PAGE_ROUND_DOWN(Last));
|
while ((Char) && (Current != Last)) Char = *Current++;
|
||||||
do
|
|
||||||
{
|
|
||||||
Char = *Current;
|
|
||||||
Current++;
|
|
||||||
} while (Char && (Current != Last + 1));
|
|
||||||
}
|
}
|
||||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
{
|
{
|
||||||
|
@ -618,7 +633,7 @@ IsBadStringPtrW(IN LPCWSTR lpsz,
|
||||||
BOOL
|
BOOL
|
||||||
NTAPI
|
NTAPI
|
||||||
IsBadStringPtrA(IN LPCSTR lpsz,
|
IsBadStringPtrA(IN LPCSTR lpsz,
|
||||||
UINT_PTR ucchMax)
|
IN UINT_PTR ucchMax)
|
||||||
{
|
{
|
||||||
BOOLEAN Result = FALSE;
|
BOOLEAN Result = FALSE;
|
||||||
volatile CHAR *Current;
|
volatile CHAR *Current;
|
||||||
|
@ -629,20 +644,16 @@ IsBadStringPtrA(IN LPCSTR lpsz,
|
||||||
if (!ucchMax) return FALSE;
|
if (!ucchMax) return FALSE;
|
||||||
if (!lpsz) return TRUE;
|
if (!lpsz) return TRUE;
|
||||||
|
|
||||||
/* Calculate the last page */
|
/* Calculate start and end */
|
||||||
|
Current = (volatile CHAR*)lpsz;
|
||||||
Last = (PCHAR)((ULONG_PTR)lpsz + ucchMax - 1);
|
Last = (PCHAR)((ULONG_PTR)lpsz + ucchMax - 1);
|
||||||
|
|
||||||
/* Enter SEH */
|
/* Enter SEH */
|
||||||
_SEH2_TRY
|
_SEH2_TRY
|
||||||
{
|
{
|
||||||
/* Probe the entire range */
|
/* Probe the entire range */
|
||||||
Current = (volatile CHAR*)lpsz;
|
Char = *Current++;
|
||||||
Last = (PCHAR)(PAGE_ROUND_DOWN(Last));
|
while ((Char) && (Current != Last)) Char = *Current++;
|
||||||
do
|
|
||||||
{
|
|
||||||
Char = *Current;
|
|
||||||
Current++;
|
|
||||||
} while (Char && (Current != Last + 1));
|
|
||||||
}
|
}
|
||||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
{
|
{
|
||||||
|
|
|
@ -9,14 +9,14 @@
|
||||||
* Created 9/23/2004
|
* Created 9/23/2004
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* INCLUDES ****************************************************************/
|
/* INCLUDES *******************************************************************/
|
||||||
|
|
||||||
#include <k32.h>
|
#include <k32.h>
|
||||||
|
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
/* FUNCTIONS ****************************************************************/
|
/* FUNCTIONS ******************************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @implemented
|
* @implemented
|
||||||
|
@ -47,9 +47,9 @@ CreateJobObjectW(IN LPSECURITY_ATTRIBUTES lpJobAttributes,
|
||||||
*/
|
*/
|
||||||
HANDLE
|
HANDLE
|
||||||
WINAPI
|
WINAPI
|
||||||
OpenJobObjectW(DWORD dwDesiredAccess,
|
OpenJobObjectW(IN DWORD dwDesiredAccess,
|
||||||
BOOL bInheritHandle,
|
IN BOOL bInheritHandle,
|
||||||
LPCWSTR lpName)
|
IN LPCWSTR lpName)
|
||||||
{
|
{
|
||||||
/* Open the NT object */
|
/* Open the NT object */
|
||||||
OpenNtObjectFromWin32Api(JobObject, dwDesiredAccess, bInheritHandle, lpName);
|
OpenNtObjectFromWin32Api(JobObject, dwDesiredAccess, bInheritHandle, lpName);
|
||||||
|
@ -61,23 +61,22 @@ OpenJobObjectW(DWORD dwDesiredAccess,
|
||||||
*/
|
*/
|
||||||
HANDLE
|
HANDLE
|
||||||
WINAPI
|
WINAPI
|
||||||
OpenJobObjectA(DWORD dwDesiredAccess,
|
OpenJobObjectA(IN DWORD dwDesiredAccess,
|
||||||
BOOL bInheritHandle,
|
IN BOOL bInheritHandle,
|
||||||
LPCSTR lpName)
|
IN LPCSTR lpName)
|
||||||
{
|
{
|
||||||
/* Call the W(ide) function */
|
/* Call the W(ide) function */
|
||||||
ConvertOpenWin32AnsiObjectApiToUnicodeApi(JobObject, dwDesiredAccess, bInheritHandle, lpName);
|
ConvertOpenWin32AnsiObjectApiToUnicodeApi(JobObject, dwDesiredAccess, bInheritHandle, lpName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
BOOL
|
BOOL
|
||||||
WINAPI
|
WINAPI
|
||||||
IsProcessInJob(HANDLE ProcessHandle,
|
IsProcessInJob(IN HANDLE ProcessHandle,
|
||||||
HANDLE JobHandle,
|
IN HANDLE JobHandle,
|
||||||
PBOOL Result)
|
OUT PBOOL Result)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
@ -92,14 +91,13 @@ IsProcessInJob(HANDLE ProcessHandle,
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
BOOL
|
BOOL
|
||||||
WINAPI
|
WINAPI
|
||||||
AssignProcessToJobObject(HANDLE hJob,
|
AssignProcessToJobObject(IN HANDLE hJob,
|
||||||
HANDLE hProcess)
|
IN HANDLE hProcess)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
@ -113,81 +111,92 @@ AssignProcessToJobObject(HANDLE hJob,
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
BOOL
|
BOOL
|
||||||
WINAPI
|
WINAPI
|
||||||
QueryInformationJobObject(HANDLE hJob,
|
QueryInformationJobObject(IN HANDLE hJob,
|
||||||
JOBOBJECTINFOCLASS JobObjectInformationClass,
|
IN JOBOBJECTINFOCLASS JobObjectInformationClass,
|
||||||
LPVOID lpJobObjectInformation,
|
IN LPVOID lpJobObjectInformation,
|
||||||
DWORD cbJobObjectInformationLength,
|
IN DWORD cbJobObjectInformationLength,
|
||||||
LPDWORD lpReturnLength)
|
OUT LPDWORD lpReturnLength)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
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,
|
Status = NtQueryInformationJobObject(hJob,
|
||||||
JobObjectInformationClass,
|
JobObjectInformationClass,
|
||||||
lpJobObjectInformation,
|
JobInfo,
|
||||||
cbJobObjectInformationLength,
|
ExpectedSize,
|
||||||
lpReturnLength);
|
lpReturnLength);
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
PJOBOBJECT_BASIC_LIMIT_INFORMATION BasicInfo;
|
if (JobInfo != &LocalInfo) return TRUE;
|
||||||
|
|
||||||
switch (JobObjectInformationClass)
|
switch (LocalInfo.BasicLimitInformation.PriorityClass)
|
||||||
{
|
{
|
||||||
case JobObjectBasicLimitInformation:
|
case PROCESS_PRIORITY_CLASS_IDLE:
|
||||||
BasicInfo = (PJOBOBJECT_BASIC_LIMIT_INFORMATION)lpJobObjectInformation;
|
LocalInfo.BasicLimitInformation.PriorityClass =
|
||||||
|
IDLE_PRIORITY_CLASS;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case JobObjectExtendedLimitInformation:
|
case PROCESS_PRIORITY_CLASS_BELOW_NORMAL:
|
||||||
BasicInfo = &((PJOBOBJECT_EXTENDED_LIMIT_INFORMATION)lpJobObjectInformation)->BasicLimitInformation;
|
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;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
BasicInfo = NULL;
|
LocalInfo.BasicLimitInformation.PriorityClass =
|
||||||
|
NORMAL_PRIORITY_CLASS;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BasicInfo != NULL)
|
RtlCopyMemory(lpJobObjectInformation, &LocalInfo, ExpectedSize);
|
||||||
{
|
|
||||||
/* 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,112 +204,119 @@ QueryInformationJobObject(HANDLE hJob,
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
BOOL
|
BOOL
|
||||||
WINAPI
|
WINAPI
|
||||||
SetInformationJobObject(HANDLE hJob,
|
SetInformationJobObject(IN HANDLE hJob,
|
||||||
JOBOBJECTINFOCLASS JobObjectInformationClass,
|
IN JOBOBJECTINFOCLASS JobObjectInformationClass,
|
||||||
LPVOID lpJobObjectInformation,
|
IN LPVOID lpJobObjectInformation,
|
||||||
DWORD cbJobObjectInformationLength)
|
IN DWORD cbJobObjectInformationLength)
|
||||||
{
|
{
|
||||||
JOBOBJECT_EXTENDED_LIMIT_INFORMATION ExtendedLimitInfo;
|
|
||||||
PJOBOBJECT_BASIC_LIMIT_INFORMATION BasicInfo;
|
|
||||||
PVOID ObjectInfo;
|
|
||||||
NTSTATUS Status;
|
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:
|
ExpectedSize = sizeof(JOBOBJECT_BASIC_LIMIT_INFORMATION);
|
||||||
if (cbJobObjectInformationLength != sizeof(JOBOBJECT_BASIC_LIMIT_INFORMATION))
|
JobInfo = &LocalInfo;
|
||||||
{
|
}
|
||||||
SetLastError(ERROR_BAD_LENGTH);
|
else if (JobObjectInformationClass == JobObjectBasicLimitInformation)
|
||||||
return FALSE;
|
{
|
||||||
}
|
ExpectedSize = sizeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION);
|
||||||
|
JobInfo = &LocalInfo;
|
||||||
ObjectInfo = &ExtendedLimitInfo.BasicLimitInformation;
|
}
|
||||||
BasicInfo = (PJOBOBJECT_BASIC_LIMIT_INFORMATION)ObjectInfo;
|
else
|
||||||
RtlCopyMemory(ObjectInfo, lpJobObjectInformation, cbJobObjectInformationLength);
|
{
|
||||||
break;
|
ExpectedSize = cbJobObjectInformationLength;
|
||||||
|
JobInfo = lpJobObjectInformation;
|
||||||
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)
|
if (cbJobObjectInformationLength != ExpectedSize)
|
||||||
{
|
{
|
||||||
/* we need to convert the process priority classes in the
|
BaseSetLastNTError(STATUS_INFO_LENGTH_MISMATCH);
|
||||||
JOBOBJECT_BASIC_LIMIT_INFORMATION structure the same way as
|
return FALSE;
|
||||||
SetPriorityClass() converts it! */
|
}
|
||||||
switch(BasicInfo->PriorityClass)
|
|
||||||
|
if (JobInfo == &LocalInfo)
|
||||||
|
{
|
||||||
|
RtlCopyMemory(&LocalInfo, lpJobObjectInformation, ExpectedSize);
|
||||||
|
|
||||||
|
if (LocalInfo.BasicLimitInformation.LimitFlags &
|
||||||
|
JOB_OBJECT_LIMIT_PRIORITY_CLASS)
|
||||||
{
|
{
|
||||||
case IDLE_PRIORITY_CLASS:
|
switch (LocalInfo.BasicLimitInformation.PriorityClass)
|
||||||
BasicInfo->PriorityClass = PROCESS_PRIORITY_CLASS_IDLE;
|
{
|
||||||
break;
|
case IDLE_PRIORITY_CLASS:
|
||||||
|
LocalInfo.BasicLimitInformation.PriorityClass =
|
||||||
|
PROCESS_PRIORITY_CLASS_IDLE;
|
||||||
|
break;
|
||||||
|
|
||||||
case BELOW_NORMAL_PRIORITY_CLASS:
|
case BELOW_NORMAL_PRIORITY_CLASS:
|
||||||
BasicInfo->PriorityClass = PROCESS_PRIORITY_CLASS_BELOW_NORMAL;
|
LocalInfo.BasicLimitInformation.PriorityClass =
|
||||||
break;
|
PROCESS_PRIORITY_CLASS_BELOW_NORMAL;
|
||||||
|
break;
|
||||||
|
|
||||||
case NORMAL_PRIORITY_CLASS:
|
case NORMAL_PRIORITY_CLASS:
|
||||||
BasicInfo->PriorityClass = PROCESS_PRIORITY_CLASS_NORMAL;
|
LocalInfo.BasicLimitInformation.PriorityClass =
|
||||||
break;
|
PROCESS_PRIORITY_CLASS_NORMAL;
|
||||||
|
break;
|
||||||
|
|
||||||
case ABOVE_NORMAL_PRIORITY_CLASS:
|
case ABOVE_NORMAL_PRIORITY_CLASS:
|
||||||
BasicInfo->PriorityClass = PROCESS_PRIORITY_CLASS_ABOVE_NORMAL;
|
LocalInfo.BasicLimitInformation.PriorityClass =
|
||||||
break;
|
PROCESS_PRIORITY_CLASS_ABOVE_NORMAL;
|
||||||
|
break;
|
||||||
|
|
||||||
case HIGH_PRIORITY_CLASS:
|
case HIGH_PRIORITY_CLASS:
|
||||||
BasicInfo->PriorityClass = PROCESS_PRIORITY_CLASS_HIGH;
|
LocalInfo.BasicLimitInformation.PriorityClass =
|
||||||
break;
|
PROCESS_PRIORITY_CLASS_HIGH;
|
||||||
|
break;
|
||||||
|
|
||||||
case REALTIME_PRIORITY_CLASS:
|
case REALTIME_PRIORITY_CLASS:
|
||||||
BasicInfo->PriorityClass = PROCESS_PRIORITY_CLASS_REALTIME;
|
LocalInfo.BasicLimitInformation.PriorityClass =
|
||||||
break;
|
PROCESS_PRIORITY_CLASS_REALTIME;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
BasicInfo->PriorityClass = PROCESS_PRIORITY_CLASS_NORMAL;
|
LocalInfo.BasicLimitInformation.PriorityClass =
|
||||||
break;
|
PROCESS_PRIORITY_CLASS_NORMAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LocalInfo.BasicLimitInformation.LimitFlags &
|
||||||
|
JOB_OBJECT_LIMIT_WORKINGSET)
|
||||||
|
{
|
||||||
|
Status = RtlAcquirePrivilege(&Privilege, TRUE, FALSE, &State);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = NtSetInformationJobObject(hJob,
|
Status = NtSetInformationJobObject(hJob,
|
||||||
JobObjectInformationClass,
|
JobObjectInformationClass,
|
||||||
ObjectInfo,
|
JobInfo,
|
||||||
cbJobObjectInformationLength);
|
ExpectedSize);
|
||||||
if (!NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
BaseSetLastNTError(Status);
|
if (State != NULL) RtlReleasePrivilege(State);
|
||||||
return FALSE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
BaseSetLastNTError(Status);
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
BOOL
|
BOOL
|
||||||
WINAPI
|
WINAPI
|
||||||
TerminateJobObject(HANDLE hJob,
|
TerminateJobObject(IN HANDLE hJob,
|
||||||
UINT uExitCode)
|
IN UINT uExitCode)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
@ -315,17 +331,24 @@ TerminateJobObject(HANDLE hJob,
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @unimplemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
BOOL
|
BOOL
|
||||||
WINAPI
|
WINAPI
|
||||||
CreateJobSet (
|
CreateJobSet(IN ULONG NumJob,
|
||||||
ULONG NumJob,
|
IN PJOB_SET_ARRAY UserJobSet,
|
||||||
PJOB_SET_ARRAY UserJobSet,
|
IN ULONG Flags)
|
||||||
ULONG Flags)
|
|
||||||
{
|
{
|
||||||
STUB;
|
NTSTATUS Status;
|
||||||
return 0;
|
|
||||||
|
Status = NtCreateJobSet(NumJob, UserJobSet, Flags);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
BaseSetLastNTError(Status);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -49,12 +49,14 @@ static
|
||||||
LONG BaseExceptionFilter(EXCEPTION_POINTERS *ExceptionInfo)
|
LONG BaseExceptionFilter(EXCEPTION_POINTERS *ExceptionInfo)
|
||||||
{
|
{
|
||||||
LONG ExceptionDisposition = EXCEPTION_EXECUTE_HANDLER;
|
LONG ExceptionDisposition = EXCEPTION_EXECUTE_HANDLER;
|
||||||
|
LPTOP_LEVEL_EXCEPTION_FILTER RealFilter;
|
||||||
|
RealFilter = RtlDecodePointer(GlobalTopLevelExceptionFilter);
|
||||||
|
|
||||||
if (GlobalTopLevelExceptionFilter != NULL)
|
if (RealFilter != NULL)
|
||||||
{
|
{
|
||||||
_SEH2_TRY
|
_SEH2_TRY
|
||||||
{
|
{
|
||||||
ExceptionDisposition = GlobalTopLevelExceptionFilter(ExceptionInfo);
|
ExceptionDisposition = RealFilter(ExceptionInfo);
|
||||||
}
|
}
|
||||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
{
|
{
|
||||||
|
@ -62,7 +64,7 @@ LONG BaseExceptionFilter(EXCEPTION_POINTERS *ExceptionInfo)
|
||||||
_SEH2_END;
|
_SEH2_END;
|
||||||
}
|
}
|
||||||
if ((ExceptionDisposition == EXCEPTION_CONTINUE_SEARCH || ExceptionDisposition == EXCEPTION_EXECUTE_HANDLER) &&
|
if ((ExceptionDisposition == EXCEPTION_CONTINUE_SEARCH || ExceptionDisposition == EXCEPTION_EXECUTE_HANDLER) &&
|
||||||
GlobalTopLevelExceptionFilter != UnhandledExceptionFilter)
|
RealFilter != UnhandledExceptionFilter)
|
||||||
{
|
{
|
||||||
ExceptionDisposition = UnhandledExceptionFilter(ExceptionInfo);
|
ExceptionDisposition = UnhandledExceptionFilter(ExceptionInfo);
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,12 +29,14 @@ static
|
||||||
LONG BaseThreadExceptionFilter(EXCEPTION_POINTERS * ExceptionInfo)
|
LONG BaseThreadExceptionFilter(EXCEPTION_POINTERS * ExceptionInfo)
|
||||||
{
|
{
|
||||||
LONG ExceptionDisposition = EXCEPTION_EXECUTE_HANDLER;
|
LONG ExceptionDisposition = EXCEPTION_EXECUTE_HANDLER;
|
||||||
|
LPTOP_LEVEL_EXCEPTION_FILTER RealFilter;
|
||||||
if (GlobalTopLevelExceptionFilter != NULL)
|
RealFilter = RtlDecodePointer(GlobalTopLevelExceptionFilter);
|
||||||
|
|
||||||
|
if (RealFilter != NULL)
|
||||||
{
|
{
|
||||||
_SEH2_TRY
|
_SEH2_TRY
|
||||||
{
|
{
|
||||||
ExceptionDisposition = GlobalTopLevelExceptionFilter(ExceptionInfo);
|
ExceptionDisposition = RealFilter(ExceptionInfo);
|
||||||
}
|
}
|
||||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue