mirror of
https://github.com/reactos/reactos.git
synced 2024-06-30 01:42:30 +00:00
[NTOSKRNL]: An old patch that implements most of the Query/Set classes for processes, and cleans up those that aren't yet implemented. Adds support for KeBoostPriorityThread, KeSetDisableBoostProcess, KeSetAutoAlignmentProcess, KeSetAffinityProcess and the scheduling impact of these APIs. Also fixes some bugs in existing classes.
svn path=/trunk/; revision=54681
This commit is contained in:
parent
48b3130f83
commit
58e95a8607
|
@ -222,6 +222,12 @@ Author:
|
||||||
#define STA_ADDRESS_SPACE_OWNER_BIT 0x4
|
#define STA_ADDRESS_SPACE_OWNER_BIT 0x4
|
||||||
#define STA_OWNS_WORKING_SET_BITS 0x1F8
|
#define STA_OWNS_WORKING_SET_BITS 0x1F8
|
||||||
|
|
||||||
|
//
|
||||||
|
// Kernel Process flags (maybe in ketypes.h?)
|
||||||
|
//
|
||||||
|
#define KPSF_AUTO_ALIGNMENT_BIT 0
|
||||||
|
#define KPSF_DISABLE_BOOST_BIT 1
|
||||||
|
|
||||||
//
|
//
|
||||||
// Process Flags
|
// Process Flags
|
||||||
//
|
//
|
||||||
|
@ -762,6 +768,11 @@ typedef struct _PROCESS_PRIORITY_CLASS
|
||||||
UCHAR PriorityClass;
|
UCHAR PriorityClass;
|
||||||
} PROCESS_PRIORITY_CLASS, *PPROCESS_PRIORITY_CLASS;
|
} PROCESS_PRIORITY_CLASS, *PPROCESS_PRIORITY_CLASS;
|
||||||
|
|
||||||
|
typedef struct _PROCESS_FOREGROUND_BACKGROUND
|
||||||
|
{
|
||||||
|
BOOLEAN Foreground;
|
||||||
|
} PROCESS_FOREGROUND_BACKGROUND, *PPROCESS_FOREGROUND_BACKGROUND;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Thread Information Structures for NtQueryProcessInformation
|
// Thread Information Structures for NtQueryProcessInformation
|
||||||
//
|
//
|
||||||
|
|
|
@ -269,6 +269,34 @@ KeSetDisableBoostThread(
|
||||||
IN BOOLEAN Disable
|
IN BOOLEAN Disable
|
||||||
);
|
);
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
KeSetDisableBoostProcess(
|
||||||
|
IN PKPROCESS Process,
|
||||||
|
IN BOOLEAN Disable
|
||||||
|
);
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
KeSetAutoAlignmentProcess(
|
||||||
|
IN PKPROCESS Process,
|
||||||
|
IN BOOLEAN Enable
|
||||||
|
);
|
||||||
|
|
||||||
|
KAFFINITY
|
||||||
|
NTAPI
|
||||||
|
KeSetAffinityProcess(
|
||||||
|
IN PKPROCESS Process,
|
||||||
|
IN KAFFINITY Affinity
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
KeBoostPriorityThread(
|
||||||
|
IN PKTHREAD Thread,
|
||||||
|
IN KPRIORITY Increment
|
||||||
|
);
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
KeBalanceSetManager(IN PVOID Context);
|
KeBalanceSetManager(IN PVOID Context);
|
||||||
|
|
|
@ -260,6 +260,90 @@ KeSetQuantumProcess(IN PKPROCESS Process,
|
||||||
KiReleaseProcessLock(&ProcessLock);
|
KiReleaseProcessLock(&ProcessLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KAFFINITY
|
||||||
|
NTAPI
|
||||||
|
KeSetAffinityProcess(IN PKPROCESS Process,
|
||||||
|
IN KAFFINITY Affinity)
|
||||||
|
{
|
||||||
|
|
||||||
|
KLOCK_QUEUE_HANDLE ProcessLock;
|
||||||
|
PLIST_ENTRY NextEntry, ListHead;
|
||||||
|
KAFFINITY OldAffinity;
|
||||||
|
PKTHREAD Thread;
|
||||||
|
ASSERT_PROCESS(Process);
|
||||||
|
ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
|
||||||
|
ASSERT((Affinity & KeActiveProcessors) != 0);
|
||||||
|
|
||||||
|
/* Lock the process */
|
||||||
|
KiAcquireProcessLock(Process, &ProcessLock);
|
||||||
|
|
||||||
|
/* Acquire the dispatcher lock */
|
||||||
|
KiAcquireDispatcherLockAtDpcLevel();
|
||||||
|
|
||||||
|
/* Capture old affinity and update it */
|
||||||
|
OldAffinity = Process->Affinity;
|
||||||
|
Process->Affinity = Affinity;
|
||||||
|
|
||||||
|
/* Loop all child threads */
|
||||||
|
ListHead = &Process->ThreadListHead;
|
||||||
|
NextEntry = ListHead->Flink;
|
||||||
|
while (ListHead != NextEntry)
|
||||||
|
{
|
||||||
|
/* Get the thread */
|
||||||
|
Thread = CONTAINING_RECORD(NextEntry, KTHREAD, ThreadListEntry);
|
||||||
|
|
||||||
|
/* Set affinity on it */
|
||||||
|
KiSetAffinityThread(Thread, Affinity);
|
||||||
|
NextEntry = NextEntry->Flink;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Release Dispatcher Database */
|
||||||
|
KiReleaseDispatcherLockFromDpcLevel();
|
||||||
|
|
||||||
|
/* Release the process lock */
|
||||||
|
KiReleaseProcessLockFromDpcLevel(&ProcessLock);
|
||||||
|
KiExitDispatcher(ProcessLock.OldIrql);
|
||||||
|
|
||||||
|
/* Return previous affinity */
|
||||||
|
return OldAffinity;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
KeSetAutoAlignmentProcess(IN PKPROCESS Process,
|
||||||
|
IN BOOLEAN Enable)
|
||||||
|
{
|
||||||
|
/* Set or reset the bit depending on what the enable flag says */
|
||||||
|
if (Enable)
|
||||||
|
{
|
||||||
|
return InterlockedBitTestAndSet(&Process->ProcessFlags,
|
||||||
|
KPSF_AUTO_ALIGNMENT_BIT);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return InterlockedBitTestAndReset(&Process->ProcessFlags,
|
||||||
|
KPSF_AUTO_ALIGNMENT_BIT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
KeSetDisableBoostProcess(IN PKPROCESS Process,
|
||||||
|
IN BOOLEAN Disable)
|
||||||
|
{
|
||||||
|
/* Set or reset the bit depending on what the disable flag says */
|
||||||
|
if (Disable)
|
||||||
|
{
|
||||||
|
return InterlockedBitTestAndSet(&Process->ProcessFlags,
|
||||||
|
KPSF_DISABLE_BOOST_BIT);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return InterlockedBitTestAndReset(&Process->ProcessFlags,
|
||||||
|
KPSF_DISABLE_BOOST_BIT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
KPRIORITY
|
KPRIORITY
|
||||||
NTAPI
|
NTAPI
|
||||||
KeSetPriorityAndQuantumProcess(IN PKPROCESS Process,
|
KeSetPriorityAndQuantumProcess(IN PKPROCESS Process,
|
||||||
|
|
|
@ -224,6 +224,53 @@ KeAlertThread(IN PKTHREAD Thread,
|
||||||
return PreviousState;
|
return PreviousState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
KeBoostPriorityThread(IN PKTHREAD Thread,
|
||||||
|
IN KPRIORITY Increment)
|
||||||
|
{
|
||||||
|
KIRQL OldIrql;
|
||||||
|
KPRIORITY Priority;
|
||||||
|
ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
|
||||||
|
|
||||||
|
/* Lock the Dispatcher Database */
|
||||||
|
OldIrql = KiAcquireDispatcherLock();
|
||||||
|
|
||||||
|
/* Only threads in the dynamic range get boosts */
|
||||||
|
if (Thread->Priority < LOW_REALTIME_PRIORITY)
|
||||||
|
{
|
||||||
|
/* Lock the thread */
|
||||||
|
KiAcquireThreadLock(Thread);
|
||||||
|
|
||||||
|
/* Check again, and make sure there's not already a boost */
|
||||||
|
if ((Thread->Priority < LOW_REALTIME_PRIORITY) &&
|
||||||
|
!(Thread->PriorityDecrement))
|
||||||
|
{
|
||||||
|
/* Compute the new priority and see if it's higher */
|
||||||
|
Priority = Thread->BasePriority + Increment;
|
||||||
|
if (Priority > Thread->Priority)
|
||||||
|
{
|
||||||
|
if (Priority >= LOW_REALTIME_PRIORITY)
|
||||||
|
{
|
||||||
|
Priority = LOW_REALTIME_PRIORITY - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reset the quantum */
|
||||||
|
Thread->Quantum = Thread->QuantumReset;
|
||||||
|
|
||||||
|
/* Set the new Priority */
|
||||||
|
KiSetPriorityThread(Thread, Priority);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Release thread lock */
|
||||||
|
KiReleaseThreadLock(Thread);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Release the dispatcher lokc */
|
||||||
|
KiReleaseDispatcherLock(OldIrql);
|
||||||
|
}
|
||||||
|
|
||||||
ULONG
|
ULONG
|
||||||
NTAPI
|
NTAPI
|
||||||
KeForceResumeThread(IN PKTHREAD Thread)
|
KeForceResumeThread(IN PKTHREAD Thread)
|
||||||
|
|
|
@ -14,6 +14,9 @@
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
|
/* FIXME: From winbase.h... what to do? */
|
||||||
|
#define SEM_NOALIGNMENTFAULTEXCEPT 0x04
|
||||||
|
|
||||||
/* Include Information Class Tables */
|
/* Include Information Class Tables */
|
||||||
#include "internal/ps_i.h"
|
#include "internal/ps_i.h"
|
||||||
|
|
||||||
|
@ -247,6 +250,7 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
|
||||||
|
|
||||||
_SEH2_TRY
|
_SEH2_TRY
|
||||||
{
|
{
|
||||||
|
/* FIXME: Call KeQueryValuesProcess */
|
||||||
IoCounters->ReadOperationCount = Process->ReadOperationCount.QuadPart;
|
IoCounters->ReadOperationCount = Process->ReadOperationCount.QuadPart;
|
||||||
IoCounters->ReadTransferCount = Process->ReadTransferCount.QuadPart;
|
IoCounters->ReadTransferCount = Process->ReadTransferCount.QuadPart;
|
||||||
IoCounters->WriteOperationCount = Process->WriteOperationCount.QuadPart;
|
IoCounters->WriteOperationCount = Process->WriteOperationCount.QuadPart;
|
||||||
|
@ -292,11 +296,12 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
|
||||||
_SEH2_TRY
|
_SEH2_TRY
|
||||||
{
|
{
|
||||||
/* Copy time information from EPROCESS/KPROCESS */
|
/* Copy time information from EPROCESS/KPROCESS */
|
||||||
|
/* FIXME: Call KeQueryRuntimeProcess */
|
||||||
ProcessTime->CreateTime = Process->CreateTime;
|
ProcessTime->CreateTime = Process->CreateTime;
|
||||||
ProcessTime->UserTime.QuadPart = Process->Pcb.UserTime *
|
ProcessTime->UserTime.QuadPart = Process->Pcb.UserTime *
|
||||||
100000LL;
|
KeMaximumIncrement;
|
||||||
ProcessTime->KernelTime.QuadPart = Process->Pcb.KernelTime *
|
ProcessTime->KernelTime.QuadPart = Process->Pcb.KernelTime *
|
||||||
100000LL;
|
KeMaximumIncrement;
|
||||||
ProcessTime->ExitTime = Process->ExitTime;
|
ProcessTime->ExitTime = Process->ExitTime;
|
||||||
}
|
}
|
||||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
@ -349,27 +354,6 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
|
||||||
ObDereferenceObject(Process);
|
ObDereferenceObject(Process);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* LDT, WS and VDM Information: not implemented */
|
|
||||||
case ProcessLdtInformation:
|
|
||||||
case ProcessWorkingSetWatch:
|
|
||||||
case ProcessWx86Information:
|
|
||||||
|
|
||||||
/* Reference the process */
|
|
||||||
Status = ObReferenceObjectByHandle(ProcessHandle,
|
|
||||||
PROCESS_QUERY_INFORMATION,
|
|
||||||
PsProcessType,
|
|
||||||
PreviousMode,
|
|
||||||
(PVOID*)&Process,
|
|
||||||
NULL);
|
|
||||||
if (!NT_SUCCESS(Status)) break;
|
|
||||||
|
|
||||||
DPRINT1("Not implemented: %lx\n", ProcessInformationClass);
|
|
||||||
|
|
||||||
/* Dereference the process */
|
|
||||||
ObDereferenceObject(Process);
|
|
||||||
Status = STATUS_NOT_IMPLEMENTED;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ProcessHandleCount:
|
case ProcessHandleCount:
|
||||||
|
|
||||||
/* Set the return length*/
|
/* Set the return length*/
|
||||||
|
@ -435,50 +419,7 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
|
||||||
_SEH2_TRY
|
_SEH2_TRY
|
||||||
{
|
{
|
||||||
/* Write back the Session ID */
|
/* Write back the Session ID */
|
||||||
SessionInfo->SessionId = Process->Session;
|
SessionInfo->SessionId = Process->Session; //MmGetSessionId(Process);
|
||||||
}
|
|
||||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
|
||||||
{
|
|
||||||
/* Get the exception code */
|
|
||||||
Status = _SEH2_GetExceptionCode();
|
|
||||||
}
|
|
||||||
_SEH2_END;
|
|
||||||
|
|
||||||
/* Dereference the process */
|
|
||||||
ObDereferenceObject(Process);
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* WOW64: Not implemented */
|
|
||||||
case ProcessWow64Information:
|
|
||||||
|
|
||||||
/* Set the return length */
|
|
||||||
Length = sizeof(ULONG_PTR);
|
|
||||||
|
|
||||||
if (ProcessInformationLength != Length)
|
|
||||||
{
|
|
||||||
Status = STATUS_INFO_LENGTH_MISMATCH;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Reference the process */
|
|
||||||
Status = ObReferenceObjectByHandle(ProcessHandle,
|
|
||||||
PROCESS_QUERY_INFORMATION,
|
|
||||||
PsProcessType,
|
|
||||||
PreviousMode,
|
|
||||||
(PVOID*)&Process,
|
|
||||||
NULL);
|
|
||||||
if (!NT_SUCCESS(Status)) break;
|
|
||||||
|
|
||||||
/* Protect write in SEH */
|
|
||||||
_SEH2_TRY
|
|
||||||
{
|
|
||||||
#ifdef _WIN64
|
|
||||||
DPRINT1("Not implemented: ProcessWow64Information\n");
|
|
||||||
Status = STATUS_NOT_IMPLEMENTED;
|
|
||||||
#else
|
|
||||||
/* Wow64 not present */
|
|
||||||
*(PULONG_PTR)ProcessInformation = 0;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
{
|
{
|
||||||
|
@ -494,15 +435,17 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
|
||||||
/* Virtual Memory Statistics */
|
/* Virtual Memory Statistics */
|
||||||
case ProcessVmCounters:
|
case ProcessVmCounters:
|
||||||
|
|
||||||
/* Set the return length */
|
/* Validate the input length */
|
||||||
Length = sizeof(VM_COUNTERS);
|
if ((ProcessInformationLength != sizeof(VM_COUNTERS)) &&
|
||||||
|
(ProcessInformationLength != sizeof(VM_COUNTERS_EX)))
|
||||||
if (ProcessInformationLength != Length)
|
|
||||||
{
|
{
|
||||||
Status = STATUS_INFO_LENGTH_MISMATCH;
|
Status = STATUS_INFO_LENGTH_MISMATCH;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Set the return length */
|
||||||
|
Length = ProcessInformationLength;
|
||||||
|
|
||||||
/* Reference the process */
|
/* Reference the process */
|
||||||
Status = ObReferenceObjectByHandle(ProcessHandle,
|
Status = ObReferenceObjectByHandle(ProcessHandle,
|
||||||
PROCESS_QUERY_INFORMATION,
|
PROCESS_QUERY_INFORMATION,
|
||||||
|
@ -525,9 +468,9 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
|
||||||
VmCounters->QuotaPagedPoolUsage = Process->QuotaUsage[0];
|
VmCounters->QuotaPagedPoolUsage = Process->QuotaUsage[0];
|
||||||
VmCounters->QuotaPeakNonPagedPoolUsage = Process->QuotaPeak[1];
|
VmCounters->QuotaPeakNonPagedPoolUsage = Process->QuotaPeak[1];
|
||||||
VmCounters->QuotaNonPagedPoolUsage = Process->QuotaUsage[1];
|
VmCounters->QuotaNonPagedPoolUsage = Process->QuotaUsage[1];
|
||||||
VmCounters->PagefileUsage = Process->QuotaUsage[2];
|
VmCounters->PagefileUsage = Process->QuotaUsage[2] << PAGE_SHIFT;
|
||||||
VmCounters->PeakPagefileUsage = Process->QuotaPeak[2];
|
VmCounters->PeakPagefileUsage = Process->QuotaPeak[2] << PAGE_SHIFT;
|
||||||
|
//VmCounters->PrivateUsage = Process->CommitCharge << PAGE_SHIFT;
|
||||||
}
|
}
|
||||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
{
|
{
|
||||||
|
@ -582,7 +525,7 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
|
||||||
/* Priority Boosting status */
|
/* Priority Boosting status */
|
||||||
case ProcessPriorityBoost:
|
case ProcessPriorityBoost:
|
||||||
|
|
||||||
/* Set the return length*/
|
/* Set the return length */
|
||||||
Length = sizeof(ULONG);
|
Length = sizeof(ULONG);
|
||||||
|
|
||||||
if (ProcessInformationLength != Length)
|
if (ProcessInformationLength != Length)
|
||||||
|
@ -621,12 +564,20 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
|
||||||
/* DOS Device Map */
|
/* DOS Device Map */
|
||||||
case ProcessDeviceMap:
|
case ProcessDeviceMap:
|
||||||
|
|
||||||
/* Set the return length*/
|
/* Set the return length */
|
||||||
Length = sizeof(PROCESS_DEVICEMAP_INFORMATION);
|
Length = sizeof(PROCESS_DEVICEMAP_INFORMATION);
|
||||||
|
|
||||||
if (ProcessInformationLength != Length)
|
if (ProcessInformationLength != Length)
|
||||||
{
|
{
|
||||||
Status = STATUS_INFO_LENGTH_MISMATCH;
|
if (ProcessInformationLength == sizeof(PROCESS_DEVICEMAP_INFORMATION_EX))
|
||||||
|
{
|
||||||
|
DPRINT1("PROCESS_DEVICEMAP_INFORMATION_EX not supported!\n");
|
||||||
|
Status = STATUS_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Status = STATUS_INFO_LENGTH_MISMATCH;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -751,6 +702,42 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
|
||||||
ObDereferenceObject(Process);
|
ObDereferenceObject(Process);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ProcessDebugFlags:
|
||||||
|
|
||||||
|
/* Set the return length*/
|
||||||
|
Length = sizeof(ULONG);
|
||||||
|
if (ProcessInformationLength != Length)
|
||||||
|
{
|
||||||
|
Status = STATUS_INFO_LENGTH_MISMATCH;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reference the process */
|
||||||
|
Status = ObReferenceObjectByHandle(ProcessHandle,
|
||||||
|
PROCESS_QUERY_INFORMATION,
|
||||||
|
PsProcessType,
|
||||||
|
PreviousMode,
|
||||||
|
(PVOID*)&Process,
|
||||||
|
NULL);
|
||||||
|
if (!NT_SUCCESS(Status)) break;
|
||||||
|
|
||||||
|
/* Enter SEH for writing back data */
|
||||||
|
_SEH2_TRY
|
||||||
|
{
|
||||||
|
/* Return the debug flag state */
|
||||||
|
*(PULONG)ProcessInformation = Process->NoDebugInherit ? 0 : 1;
|
||||||
|
}
|
||||||
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
/* Get the exception code */
|
||||||
|
Status = _SEH2_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH2_END;
|
||||||
|
|
||||||
|
/* Dereference the process */
|
||||||
|
ObDereferenceObject(Process);
|
||||||
|
break;
|
||||||
|
|
||||||
case ProcessBreakOnTermination:
|
case ProcessBreakOnTermination:
|
||||||
|
|
||||||
/* Set the return length*/
|
/* Set the return length*/
|
||||||
|
@ -831,20 +818,52 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
|
||||||
}
|
}
|
||||||
_SEH2_END;
|
_SEH2_END;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ProcessImageInformation:
|
||||||
|
DPRINT1("Image Information Query Not implemented: %lx\n", ProcessInformationClass);
|
||||||
|
Status = STATUS_NOT_IMPLEMENTED;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ProcessDebugObjectHandle:
|
||||||
|
DPRINT1("Debug Object Query Not implemented: %lx\n", ProcessInformationClass);
|
||||||
|
Status = STATUS_NOT_IMPLEMENTED;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ProcessHandleTracing:
|
||||||
|
DPRINT1("Handle tracing Not implemented: %lx\n", ProcessInformationClass);
|
||||||
|
Status = STATUS_NOT_IMPLEMENTED;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ProcessLUIDDeviceMapsEnabled:
|
||||||
|
DPRINT1("LUID Device Maps Not implemented: %lx\n", ProcessInformationClass);
|
||||||
|
Status = STATUS_NOT_IMPLEMENTED;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ProcessExecuteFlags:
|
||||||
|
DPRINT1("No execute Not implemented: %lx\n", ProcessInformationClass);
|
||||||
|
Status = STATUS_NOT_IMPLEMENTED;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ProcessWow64Information:
|
||||||
|
case ProcessLdtInformation:
|
||||||
|
case ProcessWx86Information:
|
||||||
|
DPRINT1("VDM/16-bit implemented: %lx\n", ProcessInformationClass);
|
||||||
|
Status = STATUS_NOT_IMPLEMENTED;
|
||||||
|
break;
|
||||||
|
|
||||||
/* Not yet implemented, or unknown */
|
case ProcessWorkingSetWatch:
|
||||||
case ProcessBasePriority:
|
DPRINT1("WS Watch Not implemented: %lx\n", ProcessInformationClass);
|
||||||
case ProcessRaisePriority:
|
Status = STATUS_NOT_IMPLEMENTED;
|
||||||
case ProcessExceptionPort:
|
break;
|
||||||
case ProcessAccessToken:
|
|
||||||
case ProcessLdtSize:
|
case ProcessPooledUsageAndLimits:
|
||||||
case ProcessIoPortHandlers:
|
DPRINT1("Pool limits Not implemented: %lx\n", ProcessInformationClass);
|
||||||
case ProcessUserModeIOPL:
|
Status = STATUS_NOT_IMPLEMENTED;
|
||||||
case ProcessEnableAlignmentFaultFixup:
|
break;
|
||||||
case ProcessAffinityMask:
|
|
||||||
case ProcessForegroundInformation:
|
/* Not supported by Server 2003 */
|
||||||
default:
|
default:
|
||||||
DPRINT1("Unsupported or unimplemented: %lx\n", ProcessInformationClass);
|
DPRINT1("Unsupported info class: %lx\n", ProcessInformationClass);
|
||||||
Status = STATUS_INVALID_INFO_CLASS;
|
Status = STATUS_INVALID_INFO_CLASS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -882,8 +901,14 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
|
||||||
HANDLE TokenHandle = NULL;
|
HANDLE TokenHandle = NULL;
|
||||||
PROCESS_SESSION_INFORMATION SessionInfo = {0};
|
PROCESS_SESSION_INFORMATION SessionInfo = {0};
|
||||||
PROCESS_PRIORITY_CLASS PriorityClass = {0};
|
PROCESS_PRIORITY_CLASS PriorityClass = {0};
|
||||||
|
PROCESS_FOREGROUND_BACKGROUND Foreground = {0};
|
||||||
PVOID ExceptionPort;
|
PVOID ExceptionPort;
|
||||||
ULONG Break;
|
ULONG Break;
|
||||||
|
KAFFINITY ValidAffinity, Affinity = 0;
|
||||||
|
ULONG DefaultHardErrorMode = 0, BasePriority = 0, MemoryPriority = 0;
|
||||||
|
ULONG DisableBoost = 0, DebugFlags = 0, EnableFixup = 0, Boost = 0;
|
||||||
|
PLIST_ENTRY Next;
|
||||||
|
PETHREAD Thread;
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
/* Verify Information Class validity */
|
/* Verify Information Class validity */
|
||||||
|
@ -946,6 +971,14 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
|
||||||
}
|
}
|
||||||
_SEH2_END;
|
_SEH2_END;
|
||||||
|
|
||||||
|
/* Setting the error port requires the SeTcbPrivilege */
|
||||||
|
if (!SeSinglePrivilegeCheck(SeTcbPrivilege, PreviousMode))
|
||||||
|
{
|
||||||
|
/* Can't set the session ID, bail out. */
|
||||||
|
Status = STATUS_PRIVILEGE_NOT_HELD;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* Get the LPC Port */
|
/* Get the LPC Port */
|
||||||
Status = ObReferenceObjectByHandle(PortHandle,
|
Status = ObReferenceObjectByHandle(PortHandle,
|
||||||
0,
|
0,
|
||||||
|
@ -1008,16 +1041,29 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
|
||||||
/* Enter SEH for direct buffer read */
|
/* Enter SEH for direct buffer read */
|
||||||
_SEH2_TRY
|
_SEH2_TRY
|
||||||
{
|
{
|
||||||
/* Update the current mode abd return the previous one */
|
DefaultHardErrorMode = *(PULONG)ProcessInformation;
|
||||||
InterlockedExchange((LONG*)&Process->DefaultHardErrorProcessing,
|
|
||||||
*(PLONG)ProcessInformation);
|
|
||||||
}
|
}
|
||||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
{
|
{
|
||||||
/* Get exception code */
|
/* Get exception code */
|
||||||
Status = _SEH2_GetExceptionCode();
|
Status = _SEH2_GetExceptionCode();
|
||||||
|
_SEH2_YIELD(break);
|
||||||
}
|
}
|
||||||
_SEH2_END;
|
_SEH2_END;
|
||||||
|
|
||||||
|
/* Set the mode */
|
||||||
|
Process->DefaultHardErrorProcessing = DefaultHardErrorMode;
|
||||||
|
|
||||||
|
/* Call Ke for the update */
|
||||||
|
if (DefaultHardErrorMode & SEM_NOALIGNMENTFAULTEXCEPT)
|
||||||
|
{
|
||||||
|
KeSetAutoAlignmentProcess(&Process->Pcb, TRUE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
KeSetAutoAlignmentProcess(&Process->Pcb, FALSE);
|
||||||
|
}
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Session ID */
|
/* Session ID */
|
||||||
|
@ -1119,7 +1165,12 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: Check privileges */
|
if ((PriorityClass.PriorityClass != Process->PriorityClass) &&
|
||||||
|
(PriorityClass.PriorityClass == PROCESS_PRIORITY_CLASS_REALTIME))
|
||||||
|
{
|
||||||
|
/* TODO: Check privileges */
|
||||||
|
DPRINT1("Should check privilege\n");
|
||||||
|
}
|
||||||
|
|
||||||
/* Check if we have a job */
|
/* Check if we have a job */
|
||||||
if (Process->Job)
|
if (Process->Job)
|
||||||
|
@ -1132,75 +1183,150 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
|
||||||
|
|
||||||
/* Set process priority mode (foreground or background) */
|
/* Set process priority mode (foreground or background) */
|
||||||
PsSetProcessPriorityByClass(Process,
|
PsSetProcessPriorityByClass(Process,
|
||||||
!PriorityClass.Foreground ? PsProcessPriorityBackground :
|
PriorityClass.Foreground ?
|
||||||
PsProcessPriorityForeground);
|
PsProcessPriorityForeground :
|
||||||
|
PsProcessPriorityBackground);
|
||||||
Status = STATUS_SUCCESS;
|
Status = STATUS_SUCCESS;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ProcessQuotaLimits:
|
case ProcessForegroundInformation:
|
||||||
|
|
||||||
/* Check buffer length */
|
/* Check buffer length */
|
||||||
if (ProcessInformationLength != sizeof(QUOTA_LIMITS))
|
if (ProcessInformationLength != sizeof(PROCESS_FOREGROUND_BACKGROUND))
|
||||||
{
|
{
|
||||||
Status = STATUS_INFO_LENGTH_MISMATCH;
|
Status = STATUS_INFO_LENGTH_MISMATCH;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINT1("Not implemented: ProcessQuotaLimits\n");
|
/* Enter SEH for capture */
|
||||||
Status = STATUS_NOT_IMPLEMENTED;
|
_SEH2_TRY
|
||||||
break;
|
{
|
||||||
|
/* Capture the caller's buffer */
|
||||||
|
Foreground = *(PPROCESS_FOREGROUND_BACKGROUND)ProcessInformation;
|
||||||
|
}
|
||||||
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
/* Return the exception code */
|
||||||
|
Status = _SEH2_GetExceptionCode();
|
||||||
|
_SEH2_YIELD(break);
|
||||||
|
}
|
||||||
|
_SEH2_END;
|
||||||
|
|
||||||
|
/* Set process priority mode (foreground or background) */
|
||||||
|
PsSetProcessPriorityByClass(Process,
|
||||||
|
Foreground.Foreground ?
|
||||||
|
PsProcessPriorityForeground :
|
||||||
|
PsProcessPriorityBackground);
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
break;
|
||||||
|
|
||||||
case ProcessBasePriority:
|
case ProcessBasePriority:
|
||||||
|
|
||||||
/* Check buffer length */
|
/* Validate input length */
|
||||||
if (ProcessInformationLength != sizeof(KPRIORITY))
|
if (ProcessInformationLength != sizeof(KPRIORITY))
|
||||||
{
|
{
|
||||||
Status = STATUS_INFO_LENGTH_MISMATCH;
|
Status = STATUS_INFO_LENGTH_MISMATCH;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINT1("Not implemented: ProcessBasePriority\n");
|
/* Enter SEH for direct buffer read */
|
||||||
Status = STATUS_NOT_IMPLEMENTED;
|
_SEH2_TRY
|
||||||
|
{
|
||||||
|
BasePriority = *(PULONG)ProcessInformation;
|
||||||
|
}
|
||||||
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
/* Get exception code */
|
||||||
|
Break = 0;
|
||||||
|
Status = _SEH2_GetExceptionCode();
|
||||||
|
_SEH2_YIELD(break);
|
||||||
|
}
|
||||||
|
_SEH2_END;
|
||||||
|
|
||||||
|
/* Extract the memory priority out of there */
|
||||||
|
if (BasePriority & 0x80000000)
|
||||||
|
{
|
||||||
|
MemoryPriority = MEMORY_PRIORITY_FOREGROUND;
|
||||||
|
BasePriority &= ~0x80000000;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MemoryPriority = MEMORY_PRIORITY_BACKGROUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Validate the number */
|
||||||
|
if ((BasePriority > HIGH_PRIORITY) || (BasePriority <= LOW_PRIORITY))
|
||||||
|
{
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if the new base is higher */
|
||||||
|
if (BasePriority > Process->Pcb.BasePriority)
|
||||||
|
{
|
||||||
|
DPRINT1("Should check privilege\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Call Ke */
|
||||||
|
KeSetPriorityAndQuantumProcess(&Process->Pcb, BasePriority, 0);
|
||||||
|
|
||||||
|
/* Now set the memory priority */
|
||||||
|
MmSetMemoryPriorityProcess(Process, MemoryPriority);
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ProcessRaisePriority:
|
case ProcessRaisePriority:
|
||||||
|
|
||||||
/* Check buffer length */
|
/* Validate input length */
|
||||||
if (ProcessInformationLength != sizeof(ULONG))
|
if (ProcessInformationLength != sizeof(ULONG))
|
||||||
{
|
{
|
||||||
Status = STATUS_INFO_LENGTH_MISMATCH;
|
Status = STATUS_INFO_LENGTH_MISMATCH;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINT1("Not implemented: ProcessRaisePriority\n");
|
/* Enter SEH for direct buffer read */
|
||||||
Status = STATUS_NOT_IMPLEMENTED;
|
_SEH2_TRY
|
||||||
break;
|
|
||||||
|
|
||||||
case ProcessWx86Information:
|
|
||||||
|
|
||||||
/* Check buffer length */
|
|
||||||
if (ProcessInformationLength != sizeof(HANDLE))
|
|
||||||
{
|
{
|
||||||
Status = STATUS_INFO_LENGTH_MISMATCH;
|
Boost = *(PULONG)ProcessInformation;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
DPRINT1("Not implemented: ProcessWx86Information\n");
|
|
||||||
Status = STATUS_NOT_IMPLEMENTED;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ProcessDebugPort:
|
|
||||||
|
|
||||||
/* Check buffer length */
|
|
||||||
if (ProcessInformationLength != sizeof(HANDLE))
|
|
||||||
{
|
{
|
||||||
Status = STATUS_INFO_LENGTH_MISMATCH;
|
/* Get exception code */
|
||||||
break;
|
Break = 0;
|
||||||
|
Status = _SEH2_GetExceptionCode();
|
||||||
|
_SEH2_YIELD(break);
|
||||||
}
|
}
|
||||||
|
_SEH2_END;
|
||||||
|
|
||||||
DPRINT1("Not implemented: ProcessDebugPort\n");
|
/* Make sure the process isn't dying */
|
||||||
Status = STATUS_NOT_IMPLEMENTED;
|
if (ExAcquireRundownProtection(&Process->RundownProtect))
|
||||||
|
{
|
||||||
|
/* Lock it */
|
||||||
|
KeEnterCriticalRegion();
|
||||||
|
ExAcquirePushLockShared(&Process->ProcessLock);
|
||||||
|
|
||||||
|
/* Loop the threads */
|
||||||
|
for (Next = Process->ThreadListHead.Flink;
|
||||||
|
Next != &Process->ThreadListHead;
|
||||||
|
Next = Next->Flink)
|
||||||
|
{
|
||||||
|
/* Call Ke for the thread */
|
||||||
|
Thread = CONTAINING_RECORD(Next, ETHREAD, ThreadListEntry);
|
||||||
|
KeBoostPriorityThread(&Thread->Tcb, Boost);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Release the lock and rundown */
|
||||||
|
ExReleasePushLockShared(&Process->ProcessLock);
|
||||||
|
KeLeaveCriticalRegion();
|
||||||
|
ExReleaseRundownProtection(&Process->RundownProtect);
|
||||||
|
|
||||||
|
/* Set success code */
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Avoid race conditions */
|
||||||
|
Status = STATUS_PROCESS_IS_TERMINATING;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ProcessBreakOnTermination:
|
case ProcessBreakOnTermination:
|
||||||
|
@ -1244,28 +1370,249 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ProcessAffinityMask:
|
||||||
|
|
||||||
|
/* Check buffer length */
|
||||||
|
if (ProcessInformationLength != sizeof(KAFFINITY))
|
||||||
|
{
|
||||||
|
Status = STATUS_INFO_LENGTH_MISMATCH;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Enter SEH for direct buffer read */
|
||||||
|
_SEH2_TRY
|
||||||
|
{
|
||||||
|
Affinity = *(PKAFFINITY)ProcessInformation;
|
||||||
|
}
|
||||||
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
/* Get exception code */
|
||||||
|
Break = 0;
|
||||||
|
Status = _SEH2_GetExceptionCode();
|
||||||
|
_SEH2_YIELD(break);
|
||||||
|
}
|
||||||
|
_SEH2_END;
|
||||||
|
|
||||||
|
/* Make sure it's valid for the CPUs present */
|
||||||
|
ValidAffinity = Affinity & KeActiveProcessors;
|
||||||
|
if (!Affinity || (ValidAffinity != Affinity))
|
||||||
|
{
|
||||||
|
Status = STATUS_INVALID_PARAMETER;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if it's within job affinity limits */
|
||||||
|
if (Process->Job)
|
||||||
|
{
|
||||||
|
/* Not yet implemented */
|
||||||
|
UNIMPLEMENTED;
|
||||||
|
Status = STATUS_NOT_IMPLEMENTED;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make sure the process isn't dying */
|
||||||
|
if (ExAcquireRundownProtection(&Process->RundownProtect))
|
||||||
|
{
|
||||||
|
/* Lock it */
|
||||||
|
KeEnterCriticalRegion();
|
||||||
|
ExAcquirePushLockShared(&Process->ProcessLock);
|
||||||
|
|
||||||
|
/* Call Ke to do the work */
|
||||||
|
KeSetAffinityProcess(&Process->Pcb, ValidAffinity);
|
||||||
|
|
||||||
|
/* Release the lock and rundown */
|
||||||
|
ExReleasePushLockShared(&Process->ProcessLock);
|
||||||
|
KeLeaveCriticalRegion();
|
||||||
|
ExReleaseRundownProtection(&Process->RundownProtect);
|
||||||
|
|
||||||
|
/* Set success code */
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Avoid race conditions */
|
||||||
|
Status = STATUS_PROCESS_IS_TERMINATING;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Priority Boosting status */
|
||||||
|
case ProcessPriorityBoost:
|
||||||
|
|
||||||
|
/* Validate input length */
|
||||||
|
if (ProcessInformationLength != sizeof(ULONG))
|
||||||
|
{
|
||||||
|
Status = STATUS_INFO_LENGTH_MISMATCH;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Enter SEH for direct buffer read */
|
||||||
|
_SEH2_TRY
|
||||||
|
{
|
||||||
|
DisableBoost = *(PULONG)ProcessInformation;
|
||||||
|
}
|
||||||
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
/* Get exception code */
|
||||||
|
Break = 0;
|
||||||
|
Status = _SEH2_GetExceptionCode();
|
||||||
|
_SEH2_YIELD(break);
|
||||||
|
}
|
||||||
|
_SEH2_END;
|
||||||
|
|
||||||
|
/* Make sure the process isn't dying */
|
||||||
|
if (ExAcquireRundownProtection(&Process->RundownProtect))
|
||||||
|
{
|
||||||
|
/* Lock it */
|
||||||
|
KeEnterCriticalRegion();
|
||||||
|
ExAcquirePushLockShared(&Process->ProcessLock);
|
||||||
|
|
||||||
|
/* Call Ke to do the work */
|
||||||
|
KeSetDisableBoostProcess(&Process->Pcb, DisableBoost);
|
||||||
|
|
||||||
|
/* Loop the threads too */
|
||||||
|
for (Next = Process->ThreadListHead.Flink;
|
||||||
|
Next != &Process->ThreadListHead;
|
||||||
|
Next = Next->Flink)
|
||||||
|
{
|
||||||
|
/* Call Ke for the thread */
|
||||||
|
Thread = CONTAINING_RECORD(Next, ETHREAD, ThreadListEntry);
|
||||||
|
KeSetDisableBoostThread(&Thread->Tcb, DisableBoost);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Release the lock and rundown */
|
||||||
|
ExReleasePushLockShared(&Process->ProcessLock);
|
||||||
|
KeLeaveCriticalRegion();
|
||||||
|
ExReleaseRundownProtection(&Process->RundownProtect);
|
||||||
|
|
||||||
|
/* Set success code */
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Avoid race conditions */
|
||||||
|
Status = STATUS_PROCESS_IS_TERMINATING;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ProcessDebugFlags:
|
||||||
|
|
||||||
|
/* Check buffer length */
|
||||||
|
if (ProcessInformationLength != sizeof(ULONG))
|
||||||
|
{
|
||||||
|
Status = STATUS_INFO_LENGTH_MISMATCH;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Enter SEH for direct buffer read */
|
||||||
|
_SEH2_TRY
|
||||||
|
{
|
||||||
|
DebugFlags = *(PULONG)ProcessInformation;
|
||||||
|
}
|
||||||
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
/* Get exception code */
|
||||||
|
Status = _SEH2_GetExceptionCode();
|
||||||
|
_SEH2_YIELD(break);
|
||||||
|
}
|
||||||
|
_SEH2_END;
|
||||||
|
|
||||||
|
/* Set the mode */
|
||||||
|
if (DebugFlags & ~1)
|
||||||
|
{
|
||||||
|
Status = STATUS_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (DebugFlags & 1)
|
||||||
|
{
|
||||||
|
PspClearProcessFlag(Process, PSF_NO_DEBUG_INHERIT_BIT);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PspSetProcessFlag(Process, PSF_NO_DEBUG_INHERIT_BIT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Done */
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ProcessEnableAlignmentFaultFixup:
|
||||||
|
|
||||||
|
/* Check buffer length */
|
||||||
|
if (ProcessInformationLength != sizeof(ULONG))
|
||||||
|
{
|
||||||
|
Status = STATUS_INFO_LENGTH_MISMATCH;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Enter SEH for direct buffer read */
|
||||||
|
_SEH2_TRY
|
||||||
|
{
|
||||||
|
EnableFixup = *(PULONG)ProcessInformation;
|
||||||
|
}
|
||||||
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
/* Get exception code */
|
||||||
|
Status = _SEH2_GetExceptionCode();
|
||||||
|
_SEH2_YIELD(break);
|
||||||
|
}
|
||||||
|
_SEH2_END;
|
||||||
|
|
||||||
|
/* Set the mode */
|
||||||
|
if (EnableFixup)
|
||||||
|
{
|
||||||
|
Process->DefaultHardErrorProcessing |= SEM_NOALIGNMENTFAULTEXCEPT;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Process->DefaultHardErrorProcessing &= ~SEM_NOALIGNMENTFAULTEXCEPT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Call Ke for the update */
|
||||||
|
KeSetAutoAlignmentProcess(&Process->Pcb, FALSE);
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
break;
|
||||||
|
|
||||||
/* We currently don't implement any of these */
|
/* We currently don't implement any of these */
|
||||||
case ProcessLdtInformation:
|
case ProcessLdtInformation:
|
||||||
case ProcessLdtSize:
|
case ProcessLdtSize:
|
||||||
case ProcessIoPortHandlers:
|
case ProcessIoPortHandlers:
|
||||||
case ProcessWorkingSetWatch:
|
|
||||||
case ProcessUserModeIOPL:
|
case ProcessUserModeIOPL:
|
||||||
case ProcessEnableAlignmentFaultFixup:
|
case ProcessWx86Information:
|
||||||
case ProcessAffinityMask:
|
DPRINT1("VDM/16-bit Request not implemented: %lx\n", ProcessInformationClass);
|
||||||
DPRINT1("Not implemented: %lx\n", ProcessInformationClass);
|
Status = STATUS_NOT_IMPLEMENTED;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ProcessQuotaLimits:
|
||||||
|
DPRINT1("Quota Limits not implemented\n");
|
||||||
Status = STATUS_NOT_IMPLEMENTED;
|
Status = STATUS_NOT_IMPLEMENTED;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Supposedly these are invalid...!? verify! */
|
case ProcessWorkingSetWatch:
|
||||||
case ProcessBasicInformation:
|
DPRINT1("WS watch not implemented\n");
|
||||||
case ProcessIoCounters:
|
Status = STATUS_NOT_IMPLEMENTED;
|
||||||
case ProcessTimes:
|
break;
|
||||||
case ProcessPooledUsageAndLimits:
|
|
||||||
case ProcessHandleCount:
|
case ProcessDeviceMap:
|
||||||
case ProcessWow64Information:
|
DPRINT1("Device map not implemented\n");
|
||||||
|
Status = STATUS_NOT_IMPLEMENTED;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ProcessHandleTracing:
|
||||||
|
DPRINT1("Handle tracing not implemented\n");
|
||||||
|
Status = STATUS_NOT_IMPLEMENTED;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ProcessExecuteFlags:
|
||||||
|
DPRINT1("No execute support not implemented\n");
|
||||||
|
Status = STATUS_NOT_IMPLEMENTED;
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Anything else is invalid */
|
||||||
default:
|
default:
|
||||||
DPRINT1("Unsupported or unimplemented: %lx\n", ProcessInformationClass);
|
DPRINT1("Invalid Server 2003 Info Class: %lx\n", ProcessInformationClass);
|
||||||
Status = STATUS_INVALID_INFO_CLASS;
|
Status = STATUS_INVALID_INFO_CLASS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1434,6 +1781,7 @@ NtSetInformationThread(IN HANDLE ThreadHandle,
|
||||||
{
|
{
|
||||||
/* Get the exception code */
|
/* Get the exception code */
|
||||||
Status = _SEH2_GetExceptionCode();
|
Status = _SEH2_GetExceptionCode();
|
||||||
|
_SEH2_YIELD(break);
|
||||||
}
|
}
|
||||||
_SEH2_END;
|
_SEH2_END;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue