Fixed bug in NtFreeVirtualMemory reported by Philip Susi

Added all thread information classes
Began work on fixing suspend/resume

svn path=/trunk/; revision=1554
This commit is contained in:
David Welch 2001-01-21 14:54:30 +00:00
parent 3f694e507f
commit 10f230ae0a
9 changed files with 371 additions and 282 deletions

View file

@ -55,7 +55,9 @@ extern ULONG IMPORTED NtBuildNumber;
#define ProcessImageFileName 22
#define MaxProcessInfoClass 23
// thread query / set information class
/*
* thread query / set information class
*/
#define ThreadBasicInformation 0
#define ThreadTimes 1
#define ThreadPriority 2
@ -71,7 +73,10 @@ extern ULONG IMPORTED NtBuildNumber;
#define ThreadAmILastThread 12
#define ThreadIdealProcessor 13
#define ThreadPriorityBoost 14
#define MaxThreadInfoClass 15
#define ThreadSetTlsArrayAddress 15
#define ThreadIsIoPending 16
#define ThreadHideFromDebugger 17
#define MaxThreadInfoClass 17
// object handle information
@ -862,11 +867,12 @@ typedef KERNEL_USER_TIMES *PKERNEL_USER_TIMES;
typedef struct _THREAD_BASIC_INFORMATION
{
NTSTATUS ExitStatus;
PVOID TebBaseAddress;
KAFFINITY AffinityMask;
KPRIORITY BasePriority;
ULONG UniqueThreadId;
NTSTATUS ExitStatus;
PVOID TebBaseAddress;
CLIENT_ID ClientId;
KAFFINITY AffinityMask;
KPRIORITY Priority;
KPRIORITY BasePriority;
} THREAD_BASIC_INFORMATION, *PTHREAD_BASIC_INFORMATION;
// object information

View file

@ -396,15 +396,8 @@ PACCESS_TOKEN PsReferenceEffectiveToken(PETHREAD Thread,
NTSTATUS PsOpenTokenOfProcess(HANDLE ProcessHandle,
PACCESS_TOKEN* Token);
ULONG PsFreezeThread(PETHREAD Thread,
PNTSTATUS WaitStatus,
UCHAR Alertable,
ULONG WaitMode);
ULONG PsUnfreezeThread(PETHREAD Thread,
PNTSTATUS WaitStatus);
ULONG PsSuspendThread(PETHREAD Thread);
ULONG PsResumeThread(PETHREAD Thread);
NTSTATUS PsSuspendThread(PETHREAD Thread, PULONG PreviousCount);
NTSTATUS PsResumeThread(PETHREAD Thread, PULONG PreviousCount);
#define THREAD_STATE_INVALID (0)

View file

@ -77,7 +77,7 @@ KeInitializeThread(PKPROCESS Process, PKTHREAD Thread, BOOLEAN First)
Thread->Teb = NULL;
Thread->TlsArray = NULL;
Thread->DebugActive = 0;
Thread->State = THREAD_STATE_SUSPENDED;
Thread->State = THREAD_STATE_BLOCKED;
Thread->Alerted[0] = 0;
Thread->Alerted[1] = 0;
Thread->Iopl = 0;
@ -146,7 +146,7 @@ KeInitializeThread(PKPROCESS Process, PKTHREAD Thread, BOOLEAN First)
Thread->ThreadListEntry.Flink = NULL;
Thread->ThreadListEntry.Blink = NULL;
Thread->FreezeCount = 0;
Thread->SuspendCount = 1;
Thread->SuspendCount = 0;
/*
* Initialize ReactOS specific members

View file

@ -1,4 +1,4 @@
/* $Id: virtual.c,v 1.36 2001/01/08 02:14:06 dwelch Exp $
/* $Id: virtual.c,v 1.37 2001/01/21 14:54:29 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top directory
* PROJECT: ReactOS kernel
@ -995,16 +995,18 @@ NtFreeVirtualMemory(IN HANDLE ProcessHandle,
for (i=0; i<=(MemoryArea->Length/PAGESIZE); i++)
{
LARGE_INTEGER PhysicalAddr;
ULONG PhysicalAddr;
PhysicalAddr = MmGetPhysicalAddress(MemoryArea->BaseAddress +
(i*PAGESIZE));
if (PhysicalAddr.u.LowPart != 0)
PhysicalAddr =
MmGetPhysicalAddressForProcess(Process,
MemoryArea->BaseAddress +
(i*PAGESIZE));
if (PhysicalAddr != 0)
{
MmRemovePageFromWorkingSet(AddressSpace->Process,
MemoryArea->BaseAddress +
(i*PAGESIZE));
MmDereferencePage((PVOID)(ULONG)(PhysicalAddr.u.LowPart));
MmDereferencePage((PVOID)(ULONG)(PhysicalAddr));
}
}

View file

@ -1,4 +1,4 @@
/* $Id: create.c,v 1.28 2001/01/19 15:09:01 dwelch Exp $
/* $Id: create.c,v 1.29 2001/01/21 14:54:29 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -512,14 +512,15 @@ static NTSTATUS PsCreateTeb (HANDLE ProcessHandle,
}
NTSTATUS STDCALL NtCreateThread (PHANDLE ThreadHandle,
ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes,
HANDLE ProcessHandle,
PCLIENT_ID Client,
PCONTEXT ThreadContext,
PINITIAL_TEB InitialTeb,
BOOLEAN CreateSuspended)
NTSTATUS STDCALL
NtCreateThread (PHANDLE ThreadHandle,
ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes,
HANDLE ProcessHandle,
PCLIENT_ID Client,
PCONTEXT ThreadContext,
PINITIAL_TEB InitialTeb,
BOOLEAN CreateSuspended)
{
PETHREAD Thread;
PNT_TEB TebBase;
@ -601,23 +602,24 @@ NTSTATUS STDCALL NtCreateThread (PHANDLE ThreadHandle,
if (!CreateSuspended)
{
DPRINT("Not creating suspended\n");
PsResumeThread(Thread);
PsUnblockThread(Thread, NULL);
}
else
{
KeBugCheck(0);
}
DPRINT("Thread %x\n", Thread);
DPRINT("ObGetReferenceCount(Thread) %d ObGetHandleCount(Thread) %x\n",
ObGetReferenceCount(Thread), ObGetHandleCount(Thread));
DPRINT("Finished PsCreateThread()\n");
return(STATUS_SUCCESS);
}
NTSTATUS STDCALL PsCreateSystemThread(PHANDLE ThreadHandle,
ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes,
HANDLE ProcessHandle,
PCLIENT_ID ClientId,
PKSTART_ROUTINE StartRoutine,
PVOID StartContext)
NTSTATUS STDCALL
PsCreateSystemThread(PHANDLE ThreadHandle,
ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes,
HANDLE ProcessHandle,
PCLIENT_ID ClientId,
PKSTART_ROUTINE StartRoutine,
PVOID StartContext)
/*
* FUNCTION: Creates a thread which executes in kernel mode
* ARGUMENTS:
@ -660,7 +662,7 @@ NTSTATUS STDCALL PsCreateSystemThread(PHANDLE ThreadHandle,
*ClientId=Thread->Cid;
}
PsResumeThread(Thread);
PsUnblockThread(Thread, NULL);
return(STATUS_SUCCESS);
}

View file

@ -1,4 +1,4 @@
/* $Id: process.c,v 1.54 2000/10/22 16:36:53 ekohl Exp $
/* $Id: process.c,v 1.55 2001/01/21 14:54:29 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -315,14 +315,15 @@ PEPROCESS STDCALL IoGetCurrentProcess(VOID)
return(PsGetCurrentProcess());
}
NTSTATUS STDCALL NtCreateProcess (OUT PHANDLE ProcessHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
IN HANDLE ParentProcessHandle,
IN BOOLEAN InheritObjectTable,
IN HANDLE SectionHandle OPTIONAL,
IN HANDLE DebugPortHandle OPTIONAL,
IN HANDLE ExceptionPortHandle OPTIONAL)
NTSTATUS STDCALL
NtCreateProcess (OUT PHANDLE ProcessHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
IN HANDLE ParentProcessHandle,
IN BOOLEAN InheritObjectTable,
IN HANDLE SectionHandle OPTIONAL,
IN HANDLE DebugPortHandle OPTIONAL,
IN HANDLE ExceptionPortHandle OPTIONAL)
/*
* FUNCTION: Creates a process.
* ARGUMENTS:

View file

@ -1,4 +1,4 @@
/* $Id: suspend.c,v 1.1 2001/01/19 15:09:01 dwelch Exp $
/* $Id: suspend.c,v 1.2 2001/01/21 14:54:30 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -19,36 +19,12 @@
#define NDEBUG
#include <internal/debug.h>
/* GLOBALS *******************************************************************/
extern KSPIN_LOCK PiThreadListLock;
VOID PsInsertIntoThreadList(KPRIORITY Priority, PETHREAD Thread);
/* NOTES **********************************************************************
*
*/
/* FUNCTIONS *****************************************************************/
#if 1
ULONG PsResumeThread(PETHREAD Thread)
{
KIRQL oldIrql;
ULONG SuspendCount;
KeAcquireSpinLock(&PiThreadListLock, &oldIrql);
if (Thread->Tcb.SuspendCount > 0)
{
Thread->Tcb.SuspendCount--;
SuspendCount = Thread->Tcb.SuspendCount;
Thread->Tcb.State = THREAD_STATE_RUNNABLE;
PsInsertIntoThreadList(Thread->Tcb.Priority, Thread);
}
KeReleaseSpinLock(&PiThreadListLock, oldIrql);
return SuspendCount;
}
#endif
#if 0
VOID
PiSuspendThreadRundownRoutine(PKAPC Apc)
{
@ -62,8 +38,7 @@ PiSuspendThreadKernelRoutine(PKAPC Apc,
PVOID* SystemArgument1,
PVOID* SystemArguemnt2)
{
InterlockedIncrement(&PsGetCurrentThread()->Tcb.SuspendThread);
KeWaitForSingleObject((PVOID)&PsGetCurrentThread()->SuspendSemaphore,
KeWaitForSingleObject(&PsGetCurrentThread()->Tcb.SuspendSemaphore,
0,
UserMode,
TRUE,
@ -71,22 +46,46 @@ PiSuspendThreadKernelRoutine(PKAPC Apc,
ExFreePool(Apc);
}
NTSTATUS
PsResumeThread(PETHREAD Thread, PULONG SuspendCount)
{
KeReleaseSemaphore(&Thread->Tcb.SuspendSemaphore, IO_NO_INCREMENT, 1, FALSE);
return(STATUS_SUCCESS);
}
NTSTATUS
PsSuspendThread(PETHREAD Thread, PULONG SuspendCount)
PsSuspendThread(PETHREAD Thread, PULONG PreviousSuspendCount)
{
PKAPC Apc;
NTSTATUS Status;
/*
* If we are suspending ourselves then we can cut out the work in
* sending an APC
*/
if (Thread == PsGetCurrentThread())
{
Status = KeWaitForSingleObject(&Thread->Tcb.SuspendSemaphore,
0,
UserMode,
FALSE,
NULL);
if (!NT_SUCCESS(Status))
{
return(Status);
}
return(Status);
}
Apc = ExAllocatePool(NonPagedPool, sizeof(KAPC));
if (Apc == NULL)
{
return(STATUS_NO_MORE_MEMORY);
return(STATUS_NO_MEMORY);
}
*SuspendCount = Thread->Tcb.SuspendCount;
KeInitializeApc(Apc,
&Thread->Tcb,
NULL,
0,
PiSuspendThreadKernelRoutine,
PiSuspendThreadRundownRoutine,
NULL,
@ -98,33 +97,89 @@ PsSuspendThread(PETHREAD Thread, PULONG SuspendCount)
0);
return(STATUS_SUCCESS);
}
#endif
#if 1
ULONG
PsSuspendThread(PETHREAD Thread)
NTSTATUS STDCALL
NtResumeThread (IN HANDLE ThreadHandle,
IN PULONG SuspendCount)
/*
* FUNCTION: Decrements a thread's resume count
* ARGUMENTS:
* ThreadHandle = Handle to the thread that should be resumed
* ResumeCount = The resulting resume count.
* RETURNS: Status
*/
{
KIRQL oldIrql;
ULONG PreviousSuspendCount;
PETHREAD Thread;
NTSTATUS Status;
ULONG Count;
KeAcquireSpinLock(&PiThreadListLock, &oldIrql);
PreviousSuspendCount = Thread->Tcb.SuspendCount;
if (Thread->Tcb.SuspendCount < MAXIMUM_SUSPEND_COUNT)
Status = ObReferenceObjectByHandle(ThreadHandle,
THREAD_SUSPEND_RESUME,
PsThreadType,
UserMode,
(PVOID*)&Thread,
NULL);
if (!NT_SUCCESS(Status))
{
Thread->Tcb.SuspendCount++;
return(Status);
}
if (PsGetCurrentThread() == Thread)
Status = PsResumeThread(Thread, &Count);
if (SuspendCount != NULL)
{
DbgPrint("Cannot suspend self\n");
KeBugCheck(0);
*SuspendCount = Count;
}
Thread->Tcb.State = THREAD_STATE_SUSPENDED;
ObDereferenceObject((PVOID)Thread);
KeReleaseSpinLock(&PiThreadListLock, oldIrql);
return PreviousSuspendCount;
return STATUS_SUCCESS;
}
#endif
NTSTATUS STDCALL
NtSuspendThread (IN HANDLE ThreadHandle,
IN PULONG PreviousSuspendCount)
/*
* FUNCTION: Increments a thread's suspend count
* ARGUMENTS:
* ThreadHandle = Handle to the thread that should be resumed
* PreviousSuspendCount = The resulting/previous suspend count.
* REMARK:
* A thread will be suspended if its suspend count is greater than 0.
* This procedure maps to the win32 SuspendThread function. (
* documentation about the the suspend count can be found here aswell )
* The suspend count is not increased if it is greater than
* MAXIMUM_SUSPEND_COUNT.
* RETURNS: Status
*/
{
PETHREAD Thread;
NTSTATUS Status;
ULONG Count;
Status = ObReferenceObjectByHandle(ThreadHandle,
THREAD_SUSPEND_RESUME,
PsThreadType,
UserMode,
(PVOID*)&Thread,
NULL);
if (!NT_SUCCESS(Status))
{
return(Status);
}
Status = PsSuspendThread(Thread, &Count);
if (PreviousSuspendCount != NULL)
{
*PreviousSuspendCount = Count;
}
ObDereferenceObject((PVOID)Thread);
return STATUS_SUCCESS;
}

View file

@ -1,4 +1,4 @@
/* $Id: thread.c,v 1.66 2001/01/19 15:09:01 dwelch Exp $
/* $Id: thread.c,v 1.67 2001/01/21 14:54:30 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -386,91 +386,6 @@ NtOpenThread(OUT PHANDLE ThreadHandle,
UNIMPLEMENTED;
}
NTSTATUS STDCALL
NtResumeThread (IN HANDLE ThreadHandle,
IN PULONG SuspendCount)
/*
* FUNCTION: Decrements a thread's resume count
* ARGUMENTS:
* ThreadHandle = Handle to the thread that should be resumed
* ResumeCount = The resulting resume count.
* REMARK:
* A thread is resumed if its suspend count is 0. This procedure maps to
* the win32 ResumeThread function. ( documentation about the the suspend
* count can be found here aswell )
* RETURNS: Status
*/
{
PETHREAD Thread;
NTSTATUS Status;
ULONG Count;
Status = ObReferenceObjectByHandle(ThreadHandle,
THREAD_SUSPEND_RESUME,
PsThreadType,
UserMode,
(PVOID*)&Thread,
NULL);
if (!NT_SUCCESS(Status))
{
return(Status);
}
Count = PsResumeThread(Thread);
if (SuspendCount != NULL)
{
*SuspendCount = Count;
}
ObDereferenceObject((PVOID)Thread);
return STATUS_SUCCESS;
}
NTSTATUS STDCALL
NtSuspendThread (IN HANDLE ThreadHandle,
IN PULONG PreviousSuspendCount)
/*
* FUNCTION: Increments a thread's suspend count
* ARGUMENTS:
* ThreadHandle = Handle to the thread that should be resumed
* PreviousSuspendCount = The resulting/previous suspend count.
* REMARK:
* A thread will be suspended if its suspend count is greater than 0.
* This procedure maps to the win32 SuspendThread function. (
* documentation about the the suspend count can be found here aswell )
* The suspend count is not increased if it is greater than
* MAXIMUM_SUSPEND_COUNT.
* RETURNS: Status
*/
{
PETHREAD Thread;
NTSTATUS Status;
ULONG Count;
Status = ObReferenceObjectByHandle(ThreadHandle,
THREAD_SUSPEND_RESUME,
PsThreadType,
UserMode,
(PVOID*)&Thread,
NULL);
if (!NT_SUCCESS(Status))
{
return(Status);
}
Count = PsSuspendThread(Thread);
if (PreviousSuspendCount != NULL)
{
*PreviousSuspendCount = Count;
}
ObDereferenceObject((PVOID)Thread);
return STATUS_SUCCESS;
}
NTSTATUS STDCALL
NtCallbackReturn (PVOID Result,
ULONG ResultLength,

View file

@ -17,14 +17,14 @@
/* FUNCTIONS *****************************************************************/
NTSTATUS STDCALL NtSetInformationThread(HANDLE ThreadHandle,
THREADINFOCLASS ThreadInformationClass,
PVOID ThreadInformation,
ULONG ThreadInformationLength)
NTSTATUS STDCALL
NtSetInformationThread(HANDLE ThreadHandle,
THREADINFOCLASS ThreadInformationClass,
PVOID ThreadInformation,
ULONG ThreadInformationLength)
{
PETHREAD Thread;
NTSTATUS Status;
PTHREAD_BASIC_INFORMATION ThreadBasicInformationP;
Status = ObReferenceObjectByHandle(ThreadHandle,
THREAD_SET_INFORMATION,
@ -40,73 +40,111 @@ NTSTATUS STDCALL NtSetInformationThread(HANDLE ThreadHandle,
switch (ThreadInformationClass)
{
case ThreadBasicInformation:
ThreadBasicInformationP =
(PTHREAD_BASIC_INFORMATION) ThreadInformation;
ThreadBasicInformationP->ExitStatus =
Thread->ExitStatus;
ThreadBasicInformationP->TebBaseAddress =
Thread->Tcb.Teb;
ThreadBasicInformationP->AffinityMask =
Thread->Tcb.Affinity;
ThreadBasicInformationP->BasePriority =
Thread->Tcb.BasePriority;
ThreadBasicInformationP->UniqueThreadId =
(ULONG) Thread->Cid.UniqueThread;
Status = STATUS_SUCCESS;
/* Can only be queried */
Status = STATUS_INVALID_INFO_CLASS;
break;
case ThreadTimes:
/* Can only be queried */
Status = STATUS_INVALID_INFO_CLASS;
break;
case ThreadPriority:
{
KPRIORITY Priority;
Priority = *(KPRIORITY*)ThreadInformation;
if (Priority < LOW_PRIORITY || Priority >= MAXIMUM_PRIORITY)
{
Status = STATUS_INVALID_PARAMETER;
break;
}
KeSetPriorityThread(&Thread->Tcb, Priority);
Status = STATUS_SUCCESS;
break;
KPRIORITY Priority;
if (ThreadInformationLength != sizeof(KPRIORITY))
{
Status = STATUS_INFO_LENGTH_MISMATCH;
break;
}
Priority = *(KPRIORITY*)ThreadInformation;
if (Priority < LOW_PRIORITY || Priority >= MAXIMUM_PRIORITY)
{
Status = STATUS_INVALID_PARAMETER;
break;
}
KeSetPriorityThread(&Thread->Tcb, Priority);
Status = STATUS_SUCCESS;
break;
}
case ThreadBasePriority:
Status = STATUS_NOT_IMPLEMENTED;
break;
case ThreadAffinityMask:
Status = STATUS_NOT_IMPLEMENTED;
break;
case ThreadImpersonationToken:
Status = PsAssignImpersonationToken(Thread,
*((PHANDLE)ThreadInformation));
break;
{
HANDLE TokenHandle;
if (ThreadInformationLength != sizeof(HANDLE))
{
Status = STATUS_INFO_LENGTH_MISMATCH;
break;
}
TokenHandle = *((PHANDLE)ThreadInformation);
Status = PsAssignImpersonationToken(Thread, TokenHandle);
break;
}
case ThreadDescriptorTableEntry:
UNIMPLEMENTED;
/* Can only be queried */
Status = STATUS_INVALID_INFO_CLASS;
break;
case ThreadEventPair:
UNIMPLEMENTED;
Status = STATUS_NOT_IMPLEMENTED;
break;
case ThreadQuerySetWin32StartAddress:
if (ThreadInformationLength != sizeof(ULONG))
{
Status = STATUS_INFO_LENGTH_MISMATCH;
break;
}
Thread->u2.Win32StartAddress = (PVOID)*((PULONG)ThreadInformation);
Status = STATUS_SUCCESS;
break;
case ThreadZeroTlsCell:
Status = STATUS_NOT_IMPLEMENTED;
break;
case ThreadPerformanceCount:
/* Can only be queried */
Status = STATUS_INVALID_INFO_CLASS;
break;
case ThreadAmILastThread:
/* Can only be queried */
Status = STATUS_INVALID_INFO_CLASS;
break;
case ThreadPriorityBoost:
break;
case ThreadIdealProcessor:
Status = STATUS_NOT_IMPLEMENTED;
break;
case ThreadPriorityBoost:
Status = STATUS_NOT_IMPLEMENTED;
break;
case ThreadSetTlsArrayAddress:
Status = STATUS_NOT_IMPLEMENTED;
break;
case ThreadIsIoPending:
/* Can only be queried */
Status = STATUS_INVALID_INFO_CLASS;
break;
case ThreadHideFromDebugger:
Status = STATUS_NOT_IMPLEMENTED;
break;
default:
Status = STATUS_UNSUCCESSFUL;
}
@ -116,12 +154,11 @@ NTSTATUS STDCALL NtSetInformationThread(HANDLE ThreadHandle,
NTSTATUS STDCALL
NtQueryInformationThread (
IN HANDLE ThreadHandle,
IN THREADINFOCLASS ThreadInformationClass,
OUT PVOID ThreadInformation,
IN ULONG ThreadInformationLength,
OUT PULONG ReturnLength)
NtQueryInformationThread (IN HANDLE ThreadHandle,
IN THREADINFOCLASS ThreadInformationClass,
OUT PVOID ThreadInformation,
IN ULONG ThreadInformationLength,
OUT PULONG ReturnLength)
{
PETHREAD Thread;
NTSTATUS Status;
@ -139,60 +176,141 @@ NtQueryInformationThread (
switch (ThreadInformationClass)
{
case ThreadBasicInformation:
break;
case ThreadBasicInformation:
{
PTHREAD_BASIC_INFORMATION TBI;
TBI = (PTHREAD_BASIC_INFORMATION)ThreadInformation;
if (ThreadInformationLength != sizeof(THREAD_BASIC_INFORMATION))
{
Status = STATUS_INFO_LENGTH_MISMATCH;
break;
}
TBI->ExitStatus = Thread->ExitStatus;
TBI->TebBaseAddress = Thread->Tcb.Teb;
TBI->ClientId = Thread->Cid;
TBI->AffinityMask = Thread->Tcb.Affinity;
TBI->Priority = Thread->Tcb.Priority;
TBI->BasePriority = Thread->Tcb.BasePriority;
Status = STATUS_SUCCESS;
break;
}
case ThreadTimes:
Status = STATUS_NOT_IMPLEMENTED;
break;
case ThreadPriority:
/* Can be set only */
Status = STATUS_INVALID_INFO_CLASS;
break;
case ThreadBasePriority:
/* Can be set only */
Status = STATUS_INVALID_INFO_CLASS;
break;
case ThreadAffinityMask:
/* Can be set only */
Status = STATUS_INVALID_INFO_CLASS;
break;
case ThreadTimes:
break;
case ThreadImpersonationToken:
/* Can be set only */
Status = STATUS_INVALID_INFO_CLASS;
break;
case ThreadDescriptorTableEntry:
/* Nebbett says nothing about this */
Status = STATUS_NOT_IMPLEMENTED;
break;
case ThreadPriority:
break;
case ThreadEnableAlignmentFaultFixup:
/* Can be set only */
Status = STATUS_INVALID_INFO_CLASS;
break;
case ThreadEventPair:
/* Can be set only */
Status = STATUS_INVALID_INFO_CLASS;
break;
case ThreadBasePriority:
break;
case ThreadQuerySetWin32StartAddress:
if (ThreadInformationLength != sizeof(PVOID))
{
Status = STATUS_INFO_LENGTH_MISMATCH;
break;
}
*((PVOID*)ThreadInformation) = Thread->u2.Win32StartAddress;
Status = STATUS_SUCCESS;
break;
case ThreadAffinityMask:
break;
case ThreadZeroTlsCell:
/* Can only be set */
Status = STATUS_INVALID_INFO_CLASS;
break;
case ThreadImpersonationToken:
break;
case ThreadPerformanceCount:
/* Nebbett says this class is always zero */
if (ThreadInformationLength != sizeof(LARGE_INTEGER))
{
Status = STATUS_INFO_LENGTH_MISMATCH;
break;
}
((PLARGE_INTEGER)ThreadInformation)->QuadPart = 0;
Status = STATUS_SUCCESS;
break;
case ThreadDescriptorTableEntry:
UNIMPLEMENTED;
break;
case ThreadAmILastThread:
{
if (ThreadInformationLength != sizeof(BOOLEAN))
{
Status = STATUS_INFO_LENGTH_MISMATCH;
break;
}
if (Thread->ThreadsProcess->ThreadListHead.Flink->Flink ==
&Thread->ThreadsProcess->ThreadListHead)
{
*((PBOOLEAN)ThreadInformation) = TRUE;
}
else
{
*((PBOOLEAN)ThreadInformation) = FALSE;
}
Status = STATUS_SUCCESS;
break;
}
case ThreadEventPair:
UNIMPLEMENTED;
break;
case ThreadIdealProcessor:
/* Can only be set */
Status = STATUS_INFO_LENGTH_MISMATCH;
break;
case ThreadQuerySetWin32StartAddress:
break;
case ThreadPriorityBoost:
Status = STATUS_NOT_IMPLEMENTED;
break;
case ThreadZeroTlsCell:
break;
case ThreadSetTlsArrayAddress:
/* Can only be set */
Status = STATUS_INVALID_INFO_CLASS;
break;
case ThreadPerformanceCount:
break;
case ThreadAmILastThread:
{
BOOLEAN *LastThread;
PLIST_ENTRY Entry;
LastThread = (PBOOLEAN) ThreadInformation;
Entry = &(Thread->ThreadsProcess->ThreadListHead);
*LastThread = (Entry->Flink->Flink == Entry)?TRUE:FALSE;
}
break;
case ThreadPriorityBoost:
break;
case ThreadIsIoPending:
Status = STATUS_NOT_IMPLEMENTED;
break;
case ThreadHideFromDebugger:
/* Can only be set */
Status = STATUS_INVALID_INFO_CLASS;
break;
default:
Status = STATUS_UNSUCCESSFUL;
Status = STATUS_INVALID_INFO_CLASS;
}
ObDereferenceObject(Thread);
return Status;
return(Status);
}
VOID KeSetPreviousMode(ULONG Mode)
@ -203,15 +321,12 @@ VOID KeSetPreviousMode(ULONG Mode)
ULONG STDCALL
KeGetPreviousMode (VOID)
{
/* CurrentThread is in ntoskrnl/ps/thread.c */
return (ULONG)PsGetCurrentThread()->Tcb.PreviousMode;
}
ULONG STDCALL
ExGetPreviousMode (VOID)
{
/* CurrentThread is in ntoskrnl/ps/thread.c */
return (ULONG)PsGetCurrentThread()->Tcb.PreviousMode;
}