[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:
Alex Ionescu 2011-12-18 04:27:20 +00:00
parent 48b3130f83
commit 58e95a8607
5 changed files with 659 additions and 141 deletions

View file

@ -222,6 +222,12 @@ Author:
#define STA_ADDRESS_SPACE_OWNER_BIT 0x4
#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
//
@ -762,6 +768,11 @@ typedef struct _PROCESS_PRIORITY_CLASS
UCHAR PriorityClass;
} PROCESS_PRIORITY_CLASS, *PPROCESS_PRIORITY_CLASS;
typedef struct _PROCESS_FOREGROUND_BACKGROUND
{
BOOLEAN Foreground;
} PROCESS_FOREGROUND_BACKGROUND, *PPROCESS_FOREGROUND_BACKGROUND;
//
// Thread Information Structures for NtQueryProcessInformation
//

View file

@ -269,6 +269,34 @@ KeSetDisableBoostThread(
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
NTAPI
KeBalanceSetManager(IN PVOID Context);

View file

@ -260,6 +260,90 @@ KeSetQuantumProcess(IN PKPROCESS Process,
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
NTAPI
KeSetPriorityAndQuantumProcess(IN PKPROCESS Process,

View file

@ -224,6 +224,53 @@ KeAlertThread(IN PKTHREAD Thread,
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
NTAPI
KeForceResumeThread(IN PKTHREAD Thread)

View file

@ -14,6 +14,9 @@
#define NDEBUG
#include <debug.h>
/* FIXME: From winbase.h... what to do? */
#define SEM_NOALIGNMENTFAULTEXCEPT 0x04
/* Include Information Class Tables */
#include "internal/ps_i.h"
@ -247,6 +250,7 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
_SEH2_TRY
{
/* FIXME: Call KeQueryValuesProcess */
IoCounters->ReadOperationCount = Process->ReadOperationCount.QuadPart;
IoCounters->ReadTransferCount = Process->ReadTransferCount.QuadPart;
IoCounters->WriteOperationCount = Process->WriteOperationCount.QuadPart;
@ -292,11 +296,12 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
_SEH2_TRY
{
/* Copy time information from EPROCESS/KPROCESS */
/* FIXME: Call KeQueryRuntimeProcess */
ProcessTime->CreateTime = Process->CreateTime;
ProcessTime->UserTime.QuadPart = Process->Pcb.UserTime *
100000LL;
KeMaximumIncrement;
ProcessTime->KernelTime.QuadPart = Process->Pcb.KernelTime *
100000LL;
KeMaximumIncrement;
ProcessTime->ExitTime = Process->ExitTime;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
@ -349,27 +354,6 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
ObDereferenceObject(Process);
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:
/* Set the return length*/
@ -435,50 +419,7 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
_SEH2_TRY
{
/* Write back the Session ID */
SessionInfo->SessionId = Process->Session;
}
_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
SessionInfo->SessionId = Process->Session; //MmGetSessionId(Process);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
@ -494,15 +435,17 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
/* Virtual Memory Statistics */
case ProcessVmCounters:
/* Set the return length */
Length = sizeof(VM_COUNTERS);
if (ProcessInformationLength != Length)
/* Validate the input length */
if ((ProcessInformationLength != sizeof(VM_COUNTERS)) &&
(ProcessInformationLength != sizeof(VM_COUNTERS_EX)))
{
Status = STATUS_INFO_LENGTH_MISMATCH;
break;
}
/* Set the return length */
Length = ProcessInformationLength;
/* Reference the process */
Status = ObReferenceObjectByHandle(ProcessHandle,
PROCESS_QUERY_INFORMATION,
@ -525,9 +468,9 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
VmCounters->QuotaPagedPoolUsage = Process->QuotaUsage[0];
VmCounters->QuotaPeakNonPagedPoolUsage = Process->QuotaPeak[1];
VmCounters->QuotaNonPagedPoolUsage = Process->QuotaUsage[1];
VmCounters->PagefileUsage = Process->QuotaUsage[2];
VmCounters->PeakPagefileUsage = Process->QuotaPeak[2];
VmCounters->PagefileUsage = Process->QuotaUsage[2] << PAGE_SHIFT;
VmCounters->PeakPagefileUsage = Process->QuotaPeak[2] << PAGE_SHIFT;
//VmCounters->PrivateUsage = Process->CommitCharge << PAGE_SHIFT;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
@ -582,7 +525,7 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
/* Priority Boosting status */
case ProcessPriorityBoost:
/* Set the return length*/
/* Set the return length */
Length = sizeof(ULONG);
if (ProcessInformationLength != Length)
@ -621,12 +564,20 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
/* DOS Device Map */
case ProcessDeviceMap:
/* Set the return length*/
/* Set the return length */
Length = sizeof(PROCESS_DEVICEMAP_INFORMATION);
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;
}
@ -751,6 +702,42 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
ObDereferenceObject(Process);
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:
/* Set the return length*/
@ -831,20 +818,52 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
}
_SEH2_END;
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 ProcessBasePriority:
case ProcessRaisePriority:
case ProcessExceptionPort:
case ProcessAccessToken:
case ProcessLdtSize:
case ProcessIoPortHandlers:
case ProcessUserModeIOPL:
case ProcessEnableAlignmentFaultFixup:
case ProcessAffinityMask:
case ProcessForegroundInformation:
case ProcessWorkingSetWatch:
DPRINT1("WS Watch Not implemented: %lx\n", ProcessInformationClass);
Status = STATUS_NOT_IMPLEMENTED;
break;
case ProcessPooledUsageAndLimits:
DPRINT1("Pool limits Not implemented: %lx\n", ProcessInformationClass);
Status = STATUS_NOT_IMPLEMENTED;
break;
/* Not supported by Server 2003 */
default:
DPRINT1("Unsupported or unimplemented: %lx\n", ProcessInformationClass);
DPRINT1("Unsupported info class: %lx\n", ProcessInformationClass);
Status = STATUS_INVALID_INFO_CLASS;
}
@ -882,8 +901,14 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
HANDLE TokenHandle = NULL;
PROCESS_SESSION_INFORMATION SessionInfo = {0};
PROCESS_PRIORITY_CLASS PriorityClass = {0};
PROCESS_FOREGROUND_BACKGROUND Foreground = {0};
PVOID ExceptionPort;
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();
/* Verify Information Class validity */
@ -946,6 +971,14 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
}
_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 */
Status = ObReferenceObjectByHandle(PortHandle,
0,
@ -1008,16 +1041,29 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
/* Enter SEH for direct buffer read */
_SEH2_TRY
{
/* Update the current mode abd return the previous one */
InterlockedExchange((LONG*)&Process->DefaultHardErrorProcessing,
*(PLONG)ProcessInformation);
DefaultHardErrorMode = *(PULONG)ProcessInformation;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
/* Get exception code */
Status = _SEH2_GetExceptionCode();
_SEH2_YIELD(break);
}
_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;
/* Session ID */
@ -1119,7 +1165,12 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
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 */
if (Process->Job)
@ -1132,75 +1183,150 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
/* Set process priority mode (foreground or background) */
PsSetProcessPriorityByClass(Process,
!PriorityClass.Foreground ? PsProcessPriorityBackground :
PsProcessPriorityForeground);
PriorityClass.Foreground ?
PsProcessPriorityForeground :
PsProcessPriorityBackground);
Status = STATUS_SUCCESS;
break;
case ProcessQuotaLimits:
case ProcessForegroundInformation:
/* Check buffer length */
if (ProcessInformationLength != sizeof(QUOTA_LIMITS))
if (ProcessInformationLength != sizeof(PROCESS_FOREGROUND_BACKGROUND))
{
Status = STATUS_INFO_LENGTH_MISMATCH;
break;
}
DPRINT1("Not implemented: ProcessQuotaLimits\n");
Status = STATUS_NOT_IMPLEMENTED;
break;
/* Enter SEH for capture */
_SEH2_TRY
{
/* 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:
/* Check buffer length */
/* Validate input length */
if (ProcessInformationLength != sizeof(KPRIORITY))
{
Status = STATUS_INFO_LENGTH_MISMATCH;
break;
}
DPRINT1("Not implemented: ProcessBasePriority\n");
Status = STATUS_NOT_IMPLEMENTED;
/* Enter SEH for direct buffer read */
_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;
case ProcessRaisePriority:
/* Check buffer length */
/* Validate input length */
if (ProcessInformationLength != sizeof(ULONG))
{
Status = STATUS_INFO_LENGTH_MISMATCH;
break;
}
DPRINT1("Not implemented: ProcessRaisePriority\n");
Status = STATUS_NOT_IMPLEMENTED;
break;
case ProcessWx86Information:
/* Check buffer length */
if (ProcessInformationLength != sizeof(HANDLE))
/* Enter SEH for direct buffer read */
_SEH2_TRY
{
Status = STATUS_INFO_LENGTH_MISMATCH;
break;
Boost = *(PULONG)ProcessInformation;
}
DPRINT1("Not implemented: ProcessWx86Information\n");
Status = STATUS_NOT_IMPLEMENTED;
break;
case ProcessDebugPort:
/* Check buffer length */
if (ProcessInformationLength != sizeof(HANDLE))
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = STATUS_INFO_LENGTH_MISMATCH;
break;
/* Get exception code */
Break = 0;
Status = _SEH2_GetExceptionCode();
_SEH2_YIELD(break);
}
_SEH2_END;
DPRINT1("Not implemented: ProcessDebugPort\n");
Status = STATUS_NOT_IMPLEMENTED;
/* Make sure the process isn't dying */
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;
case ProcessBreakOnTermination:
@ -1244,28 +1370,249 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
}
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 */
case ProcessLdtInformation:
case ProcessLdtSize:
case ProcessIoPortHandlers:
case ProcessWorkingSetWatch:
case ProcessUserModeIOPL:
case ProcessEnableAlignmentFaultFixup:
case ProcessAffinityMask:
DPRINT1("Not implemented: %lx\n", ProcessInformationClass);
case ProcessWx86Information:
DPRINT1("VDM/16-bit Request not implemented: %lx\n", ProcessInformationClass);
Status = STATUS_NOT_IMPLEMENTED;
break;
case ProcessQuotaLimits:
DPRINT1("Quota Limits not implemented\n");
Status = STATUS_NOT_IMPLEMENTED;
break;
/* Supposedly these are invalid...!? verify! */
case ProcessBasicInformation:
case ProcessIoCounters:
case ProcessTimes:
case ProcessPooledUsageAndLimits:
case ProcessHandleCount:
case ProcessWow64Information:
case ProcessWorkingSetWatch:
DPRINT1("WS watch not implemented\n");
Status = STATUS_NOT_IMPLEMENTED;
break;
case ProcessDeviceMap:
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:
DPRINT1("Unsupported or unimplemented: %lx\n", ProcessInformationClass);
DPRINT1("Invalid Server 2003 Info Class: %lx\n", ProcessInformationClass);
Status = STATUS_INVALID_INFO_CLASS;
}
@ -1434,6 +1781,7 @@ NtSetInformationThread(IN HANDLE ThreadHandle,
{
/* Get the exception code */
Status = _SEH2_GetExceptionCode();
_SEH2_YIELD(break);
}
_SEH2_END;