mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 01:24:38 +00:00
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:
parent
3f694e507f
commit
10f230ae0a
9 changed files with 371 additions and 282 deletions
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue