mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 07:42:59 +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 ProcessImageFileName 22
|
||||||
#define MaxProcessInfoClass 23
|
#define MaxProcessInfoClass 23
|
||||||
|
|
||||||
// thread query / set information class
|
/*
|
||||||
|
* thread query / set information class
|
||||||
|
*/
|
||||||
#define ThreadBasicInformation 0
|
#define ThreadBasicInformation 0
|
||||||
#define ThreadTimes 1
|
#define ThreadTimes 1
|
||||||
#define ThreadPriority 2
|
#define ThreadPriority 2
|
||||||
|
@ -71,7 +73,10 @@ extern ULONG IMPORTED NtBuildNumber;
|
||||||
#define ThreadAmILastThread 12
|
#define ThreadAmILastThread 12
|
||||||
#define ThreadIdealProcessor 13
|
#define ThreadIdealProcessor 13
|
||||||
#define ThreadPriorityBoost 14
|
#define ThreadPriorityBoost 14
|
||||||
#define MaxThreadInfoClass 15
|
#define ThreadSetTlsArrayAddress 15
|
||||||
|
#define ThreadIsIoPending 16
|
||||||
|
#define ThreadHideFromDebugger 17
|
||||||
|
#define MaxThreadInfoClass 17
|
||||||
|
|
||||||
// object handle information
|
// object handle information
|
||||||
|
|
||||||
|
@ -864,9 +869,10 @@ typedef struct _THREAD_BASIC_INFORMATION
|
||||||
{
|
{
|
||||||
NTSTATUS ExitStatus;
|
NTSTATUS ExitStatus;
|
||||||
PVOID TebBaseAddress;
|
PVOID TebBaseAddress;
|
||||||
|
CLIENT_ID ClientId;
|
||||||
KAFFINITY AffinityMask;
|
KAFFINITY AffinityMask;
|
||||||
|
KPRIORITY Priority;
|
||||||
KPRIORITY BasePriority;
|
KPRIORITY BasePriority;
|
||||||
ULONG UniqueThreadId;
|
|
||||||
} THREAD_BASIC_INFORMATION, *PTHREAD_BASIC_INFORMATION;
|
} THREAD_BASIC_INFORMATION, *PTHREAD_BASIC_INFORMATION;
|
||||||
|
|
||||||
// object information
|
// object information
|
||||||
|
|
|
@ -396,15 +396,8 @@ PACCESS_TOKEN PsReferenceEffectiveToken(PETHREAD Thread,
|
||||||
NTSTATUS PsOpenTokenOfProcess(HANDLE ProcessHandle,
|
NTSTATUS PsOpenTokenOfProcess(HANDLE ProcessHandle,
|
||||||
PACCESS_TOKEN* Token);
|
PACCESS_TOKEN* Token);
|
||||||
|
|
||||||
ULONG PsFreezeThread(PETHREAD Thread,
|
NTSTATUS PsSuspendThread(PETHREAD Thread, PULONG PreviousCount);
|
||||||
PNTSTATUS WaitStatus,
|
NTSTATUS PsResumeThread(PETHREAD Thread, PULONG PreviousCount);
|
||||||
UCHAR Alertable,
|
|
||||||
ULONG WaitMode);
|
|
||||||
ULONG PsUnfreezeThread(PETHREAD Thread,
|
|
||||||
PNTSTATUS WaitStatus);
|
|
||||||
|
|
||||||
ULONG PsSuspendThread(PETHREAD Thread);
|
|
||||||
ULONG PsResumeThread(PETHREAD Thread);
|
|
||||||
|
|
||||||
|
|
||||||
#define THREAD_STATE_INVALID (0)
|
#define THREAD_STATE_INVALID (0)
|
||||||
|
|
|
@ -77,7 +77,7 @@ KeInitializeThread(PKPROCESS Process, PKTHREAD Thread, BOOLEAN First)
|
||||||
Thread->Teb = NULL;
|
Thread->Teb = NULL;
|
||||||
Thread->TlsArray = NULL;
|
Thread->TlsArray = NULL;
|
||||||
Thread->DebugActive = 0;
|
Thread->DebugActive = 0;
|
||||||
Thread->State = THREAD_STATE_SUSPENDED;
|
Thread->State = THREAD_STATE_BLOCKED;
|
||||||
Thread->Alerted[0] = 0;
|
Thread->Alerted[0] = 0;
|
||||||
Thread->Alerted[1] = 0;
|
Thread->Alerted[1] = 0;
|
||||||
Thread->Iopl = 0;
|
Thread->Iopl = 0;
|
||||||
|
@ -146,7 +146,7 @@ KeInitializeThread(PKPROCESS Process, PKTHREAD Thread, BOOLEAN First)
|
||||||
Thread->ThreadListEntry.Flink = NULL;
|
Thread->ThreadListEntry.Flink = NULL;
|
||||||
Thread->ThreadListEntry.Blink = NULL;
|
Thread->ThreadListEntry.Blink = NULL;
|
||||||
Thread->FreezeCount = 0;
|
Thread->FreezeCount = 0;
|
||||||
Thread->SuspendCount = 1;
|
Thread->SuspendCount = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize ReactOS specific members
|
* 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
|
* COPYRIGHT: See COPYING in the top directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -995,16 +995,18 @@ NtFreeVirtualMemory(IN HANDLE ProcessHandle,
|
||||||
|
|
||||||
for (i=0; i<=(MemoryArea->Length/PAGESIZE); i++)
|
for (i=0; i<=(MemoryArea->Length/PAGESIZE); i++)
|
||||||
{
|
{
|
||||||
LARGE_INTEGER PhysicalAddr;
|
ULONG PhysicalAddr;
|
||||||
|
|
||||||
PhysicalAddr = MmGetPhysicalAddress(MemoryArea->BaseAddress +
|
PhysicalAddr =
|
||||||
|
MmGetPhysicalAddressForProcess(Process,
|
||||||
|
MemoryArea->BaseAddress +
|
||||||
(i*PAGESIZE));
|
(i*PAGESIZE));
|
||||||
if (PhysicalAddr.u.LowPart != 0)
|
if (PhysicalAddr != 0)
|
||||||
{
|
{
|
||||||
MmRemovePageFromWorkingSet(AddressSpace->Process,
|
MmRemovePageFromWorkingSet(AddressSpace->Process,
|
||||||
MemoryArea->BaseAddress +
|
MemoryArea->BaseAddress +
|
||||||
(i*PAGESIZE));
|
(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
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -512,7 +512,8 @@ static NTSTATUS PsCreateTeb (HANDLE ProcessHandle,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS STDCALL NtCreateThread (PHANDLE ThreadHandle,
|
NTSTATUS STDCALL
|
||||||
|
NtCreateThread (PHANDLE ThreadHandle,
|
||||||
ACCESS_MASK DesiredAccess,
|
ACCESS_MASK DesiredAccess,
|
||||||
POBJECT_ATTRIBUTES ObjectAttributes,
|
POBJECT_ATTRIBUTES ObjectAttributes,
|
||||||
HANDLE ProcessHandle,
|
HANDLE ProcessHandle,
|
||||||
|
@ -601,17 +602,18 @@ NTSTATUS STDCALL NtCreateThread (PHANDLE ThreadHandle,
|
||||||
if (!CreateSuspended)
|
if (!CreateSuspended)
|
||||||
{
|
{
|
||||||
DPRINT("Not creating suspended\n");
|
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);
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS STDCALL PsCreateSystemThread(PHANDLE ThreadHandle,
|
NTSTATUS STDCALL
|
||||||
|
PsCreateSystemThread(PHANDLE ThreadHandle,
|
||||||
ACCESS_MASK DesiredAccess,
|
ACCESS_MASK DesiredAccess,
|
||||||
POBJECT_ATTRIBUTES ObjectAttributes,
|
POBJECT_ATTRIBUTES ObjectAttributes,
|
||||||
HANDLE ProcessHandle,
|
HANDLE ProcessHandle,
|
||||||
|
@ -660,7 +662,7 @@ NTSTATUS STDCALL PsCreateSystemThread(PHANDLE ThreadHandle,
|
||||||
*ClientId=Thread->Cid;
|
*ClientId=Thread->Cid;
|
||||||
}
|
}
|
||||||
|
|
||||||
PsResumeThread(Thread);
|
PsUnblockThread(Thread, NULL);
|
||||||
|
|
||||||
return(STATUS_SUCCESS);
|
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
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -315,7 +315,8 @@ PEPROCESS STDCALL IoGetCurrentProcess(VOID)
|
||||||
return(PsGetCurrentProcess());
|
return(PsGetCurrentProcess());
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS STDCALL NtCreateProcess (OUT PHANDLE ProcessHandle,
|
NTSTATUS STDCALL
|
||||||
|
NtCreateProcess (OUT PHANDLE ProcessHandle,
|
||||||
IN ACCESS_MASK DesiredAccess,
|
IN ACCESS_MASK DesiredAccess,
|
||||||
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
|
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
|
||||||
IN HANDLE ParentProcessHandle,
|
IN HANDLE ParentProcessHandle,
|
||||||
|
|
|
@ -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
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -19,36 +19,12 @@
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <internal/debug.h>
|
#include <internal/debug.h>
|
||||||
|
|
||||||
/* GLOBALS *******************************************************************/
|
/* NOTES **********************************************************************
|
||||||
|
*
|
||||||
extern KSPIN_LOCK PiThreadListLock;
|
*/
|
||||||
VOID PsInsertIntoThreadList(KPRIORITY Priority, PETHREAD Thread);
|
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* 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
|
VOID
|
||||||
PiSuspendThreadRundownRoutine(PKAPC Apc)
|
PiSuspendThreadRundownRoutine(PKAPC Apc)
|
||||||
{
|
{
|
||||||
|
@ -62,8 +38,7 @@ PiSuspendThreadKernelRoutine(PKAPC Apc,
|
||||||
PVOID* SystemArgument1,
|
PVOID* SystemArgument1,
|
||||||
PVOID* SystemArguemnt2)
|
PVOID* SystemArguemnt2)
|
||||||
{
|
{
|
||||||
InterlockedIncrement(&PsGetCurrentThread()->Tcb.SuspendThread);
|
KeWaitForSingleObject(&PsGetCurrentThread()->Tcb.SuspendSemaphore,
|
||||||
KeWaitForSingleObject((PVOID)&PsGetCurrentThread()->SuspendSemaphore,
|
|
||||||
0,
|
0,
|
||||||
UserMode,
|
UserMode,
|
||||||
TRUE,
|
TRUE,
|
||||||
|
@ -72,21 +47,45 @@ PiSuspendThreadKernelRoutine(PKAPC Apc,
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
PsSuspendThread(PETHREAD Thread, PULONG SuspendCount)
|
PsResumeThread(PETHREAD Thread, PULONG SuspendCount)
|
||||||
|
{
|
||||||
|
KeReleaseSemaphore(&Thread->Tcb.SuspendSemaphore, IO_NO_INCREMENT, 1, FALSE);
|
||||||
|
return(STATUS_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
PsSuspendThread(PETHREAD Thread, PULONG PreviousSuspendCount)
|
||||||
{
|
{
|
||||||
PKAPC Apc;
|
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));
|
Apc = ExAllocatePool(NonPagedPool, sizeof(KAPC));
|
||||||
if (Apc == NULL)
|
if (Apc == NULL)
|
||||||
{
|
{
|
||||||
return(STATUS_NO_MORE_MEMORY);
|
return(STATUS_NO_MEMORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
*SuspendCount = Thread->Tcb.SuspendCount;
|
|
||||||
|
|
||||||
KeInitializeApc(Apc,
|
KeInitializeApc(Apc,
|
||||||
&Thread->Tcb,
|
&Thread->Tcb,
|
||||||
NULL,
|
0,
|
||||||
PiSuspendThreadKernelRoutine,
|
PiSuspendThreadKernelRoutine,
|
||||||
PiSuspendThreadRundownRoutine,
|
PiSuspendThreadRundownRoutine,
|
||||||
NULL,
|
NULL,
|
||||||
|
@ -98,33 +97,89 @@ PsSuspendThread(PETHREAD Thread, PULONG SuspendCount)
|
||||||
0);
|
0);
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#if 1
|
NTSTATUS STDCALL
|
||||||
ULONG
|
NtResumeThread (IN HANDLE ThreadHandle,
|
||||||
PsSuspendThread(PETHREAD Thread)
|
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;
|
PETHREAD Thread;
|
||||||
ULONG PreviousSuspendCount;
|
NTSTATUS Status;
|
||||||
|
ULONG Count;
|
||||||
|
|
||||||
KeAcquireSpinLock(&PiThreadListLock, &oldIrql);
|
Status = ObReferenceObjectByHandle(ThreadHandle,
|
||||||
|
THREAD_SUSPEND_RESUME,
|
||||||
PreviousSuspendCount = Thread->Tcb.SuspendCount;
|
PsThreadType,
|
||||||
if (Thread->Tcb.SuspendCount < MAXIMUM_SUSPEND_COUNT)
|
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");
|
*SuspendCount = Count;
|
||||||
KeBugCheck(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Thread->Tcb.State = THREAD_STATE_SUSPENDED;
|
ObDereferenceObject((PVOID)Thread);
|
||||||
|
|
||||||
KeReleaseSpinLock(&PiThreadListLock, oldIrql);
|
return STATUS_SUCCESS;
|
||||||
|
|
||||||
return PreviousSuspendCount;
|
|
||||||
}
|
}
|
||||||
#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
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -386,91 +386,6 @@ NtOpenThread(OUT PHANDLE ThreadHandle,
|
||||||
UNIMPLEMENTED;
|
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
|
NTSTATUS STDCALL
|
||||||
NtCallbackReturn (PVOID Result,
|
NtCallbackReturn (PVOID Result,
|
||||||
ULONG ResultLength,
|
ULONG ResultLength,
|
||||||
|
|
|
@ -17,14 +17,14 @@
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
NTSTATUS STDCALL NtSetInformationThread(HANDLE ThreadHandle,
|
NTSTATUS STDCALL
|
||||||
|
NtSetInformationThread(HANDLE ThreadHandle,
|
||||||
THREADINFOCLASS ThreadInformationClass,
|
THREADINFOCLASS ThreadInformationClass,
|
||||||
PVOID ThreadInformation,
|
PVOID ThreadInformation,
|
||||||
ULONG ThreadInformationLength)
|
ULONG ThreadInformationLength)
|
||||||
{
|
{
|
||||||
PETHREAD Thread;
|
PETHREAD Thread;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PTHREAD_BASIC_INFORMATION ThreadBasicInformationP;
|
|
||||||
|
|
||||||
Status = ObReferenceObjectByHandle(ThreadHandle,
|
Status = ObReferenceObjectByHandle(ThreadHandle,
|
||||||
THREAD_SET_INFORMATION,
|
THREAD_SET_INFORMATION,
|
||||||
|
@ -40,28 +40,24 @@ NTSTATUS STDCALL NtSetInformationThread(HANDLE ThreadHandle,
|
||||||
switch (ThreadInformationClass)
|
switch (ThreadInformationClass)
|
||||||
{
|
{
|
||||||
case ThreadBasicInformation:
|
case ThreadBasicInformation:
|
||||||
ThreadBasicInformationP =
|
/* Can only be queried */
|
||||||
(PTHREAD_BASIC_INFORMATION) ThreadInformation;
|
Status = STATUS_INVALID_INFO_CLASS;
|
||||||
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;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ThreadTimes:
|
case ThreadTimes:
|
||||||
|
/* Can only be queried */
|
||||||
|
Status = STATUS_INVALID_INFO_CLASS;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ThreadPriority:
|
case ThreadPriority:
|
||||||
{
|
{
|
||||||
KPRIORITY Priority;
|
KPRIORITY Priority;
|
||||||
|
|
||||||
|
if (ThreadInformationLength != sizeof(KPRIORITY))
|
||||||
|
{
|
||||||
|
Status = STATUS_INFO_LENGTH_MISMATCH;
|
||||||
|
break;
|
||||||
|
}
|
||||||
Priority = *(KPRIORITY*)ThreadInformation;
|
Priority = *(KPRIORITY*)ThreadInformation;
|
||||||
if (Priority < LOW_PRIORITY || Priority >= MAXIMUM_PRIORITY)
|
if (Priority < LOW_PRIORITY || Priority >= MAXIMUM_PRIORITY)
|
||||||
{
|
{
|
||||||
|
@ -74,37 +70,79 @@ NTSTATUS STDCALL NtSetInformationThread(HANDLE ThreadHandle,
|
||||||
}
|
}
|
||||||
|
|
||||||
case ThreadBasePriority:
|
case ThreadBasePriority:
|
||||||
|
Status = STATUS_NOT_IMPLEMENTED;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ThreadAffinityMask:
|
case ThreadAffinityMask:
|
||||||
|
Status = STATUS_NOT_IMPLEMENTED;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ThreadImpersonationToken:
|
case ThreadImpersonationToken:
|
||||||
Status = PsAssignImpersonationToken(Thread,
|
{
|
||||||
*((PHANDLE)ThreadInformation));
|
HANDLE TokenHandle;
|
||||||
|
|
||||||
|
if (ThreadInformationLength != sizeof(HANDLE))
|
||||||
|
{
|
||||||
|
Status = STATUS_INFO_LENGTH_MISMATCH;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
TokenHandle = *((PHANDLE)ThreadInformation);
|
||||||
|
Status = PsAssignImpersonationToken(Thread, TokenHandle);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case ThreadDescriptorTableEntry:
|
case ThreadDescriptorTableEntry:
|
||||||
UNIMPLEMENTED;
|
/* Can only be queried */
|
||||||
|
Status = STATUS_INVALID_INFO_CLASS;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ThreadEventPair:
|
case ThreadEventPair:
|
||||||
UNIMPLEMENTED;
|
Status = STATUS_NOT_IMPLEMENTED;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ThreadQuerySetWin32StartAddress:
|
case ThreadQuerySetWin32StartAddress:
|
||||||
|
if (ThreadInformationLength != sizeof(ULONG))
|
||||||
|
{
|
||||||
|
Status = STATUS_INFO_LENGTH_MISMATCH;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Thread->u2.Win32StartAddress = (PVOID)*((PULONG)ThreadInformation);
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ThreadZeroTlsCell:
|
case ThreadZeroTlsCell:
|
||||||
|
Status = STATUS_NOT_IMPLEMENTED;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ThreadPerformanceCount:
|
case ThreadPerformanceCount:
|
||||||
|
/* Can only be queried */
|
||||||
|
Status = STATUS_INVALID_INFO_CLASS;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ThreadAmILastThread:
|
case ThreadAmILastThread:
|
||||||
|
/* Can only be queried */
|
||||||
|
Status = STATUS_INVALID_INFO_CLASS;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ThreadIdealProcessor:
|
||||||
|
Status = STATUS_NOT_IMPLEMENTED;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ThreadPriorityBoost:
|
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;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -116,8 +154,7 @@ NTSTATUS STDCALL NtSetInformationThread(HANDLE ThreadHandle,
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS STDCALL
|
NTSTATUS STDCALL
|
||||||
NtQueryInformationThread (
|
NtQueryInformationThread (IN HANDLE ThreadHandle,
|
||||||
IN HANDLE ThreadHandle,
|
|
||||||
IN THREADINFOCLASS ThreadInformationClass,
|
IN THREADINFOCLASS ThreadInformationClass,
|
||||||
OUT PVOID ThreadInformation,
|
OUT PVOID ThreadInformation,
|
||||||
IN ULONG ThreadInformationLength,
|
IN ULONG ThreadInformationLength,
|
||||||
|
@ -140,59 +177,140 @@ NtQueryInformationThread (
|
||||||
switch (ThreadInformationClass)
|
switch (ThreadInformationClass)
|
||||||
{
|
{
|
||||||
case ThreadBasicInformation:
|
case ThreadBasicInformation:
|
||||||
|
{
|
||||||
|
PTHREAD_BASIC_INFORMATION TBI;
|
||||||
|
|
||||||
|
TBI = (PTHREAD_BASIC_INFORMATION)ThreadInformation;
|
||||||
|
|
||||||
|
if (ThreadInformationLength != sizeof(THREAD_BASIC_INFORMATION))
|
||||||
|
{
|
||||||
|
Status = STATUS_INFO_LENGTH_MISMATCH;
|
||||||
break;
|
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:
|
case ThreadTimes:
|
||||||
|
Status = STATUS_NOT_IMPLEMENTED;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ThreadPriority:
|
case ThreadPriority:
|
||||||
|
/* Can be set only */
|
||||||
|
Status = STATUS_INVALID_INFO_CLASS;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ThreadBasePriority:
|
case ThreadBasePriority:
|
||||||
|
/* Can be set only */
|
||||||
|
Status = STATUS_INVALID_INFO_CLASS;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ThreadAffinityMask:
|
case ThreadAffinityMask:
|
||||||
|
/* Can be set only */
|
||||||
|
Status = STATUS_INVALID_INFO_CLASS;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ThreadImpersonationToken:
|
case ThreadImpersonationToken:
|
||||||
|
/* Can be set only */
|
||||||
|
Status = STATUS_INVALID_INFO_CLASS;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ThreadDescriptorTableEntry:
|
case ThreadDescriptorTableEntry:
|
||||||
UNIMPLEMENTED;
|
/* Nebbett says nothing about this */
|
||||||
|
Status = STATUS_NOT_IMPLEMENTED;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ThreadEnableAlignmentFaultFixup:
|
||||||
|
/* Can be set only */
|
||||||
|
Status = STATUS_INVALID_INFO_CLASS;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ThreadEventPair:
|
case ThreadEventPair:
|
||||||
UNIMPLEMENTED;
|
/* Can be set only */
|
||||||
|
Status = STATUS_INVALID_INFO_CLASS;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ThreadQuerySetWin32StartAddress:
|
case ThreadQuerySetWin32StartAddress:
|
||||||
|
if (ThreadInformationLength != sizeof(PVOID))
|
||||||
|
{
|
||||||
|
Status = STATUS_INFO_LENGTH_MISMATCH;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
*((PVOID*)ThreadInformation) = Thread->u2.Win32StartAddress;
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ThreadZeroTlsCell:
|
case ThreadZeroTlsCell:
|
||||||
|
/* Can only be set */
|
||||||
|
Status = STATUS_INVALID_INFO_CLASS;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ThreadPerformanceCount:
|
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;
|
break;
|
||||||
|
|
||||||
case ThreadAmILastThread:
|
case ThreadAmILastThread:
|
||||||
{
|
{
|
||||||
BOOLEAN *LastThread;
|
if (ThreadInformationLength != sizeof(BOOLEAN))
|
||||||
PLIST_ENTRY Entry;
|
{
|
||||||
|
Status = STATUS_INFO_LENGTH_MISMATCH;
|
||||||
LastThread = (PBOOLEAN) ThreadInformation;
|
break;
|
||||||
Entry = &(Thread->ThreadsProcess->ThreadListHead);
|
|
||||||
*LastThread = (Entry->Flink->Flink == Entry)?TRUE:FALSE;
|
|
||||||
}
|
}
|
||||||
|
if (Thread->ThreadsProcess->ThreadListHead.Flink->Flink ==
|
||||||
|
&Thread->ThreadsProcess->ThreadListHead)
|
||||||
|
{
|
||||||
|
*((PBOOLEAN)ThreadInformation) = TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*((PBOOLEAN)ThreadInformation) = FALSE;
|
||||||
|
}
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case ThreadIdealProcessor:
|
||||||
|
/* Can only be set */
|
||||||
|
Status = STATUS_INFO_LENGTH_MISMATCH;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ThreadPriorityBoost:
|
case ThreadPriorityBoost:
|
||||||
|
Status = STATUS_NOT_IMPLEMENTED;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ThreadSetTlsArrayAddress:
|
||||||
|
/* Can only be set */
|
||||||
|
Status = STATUS_INVALID_INFO_CLASS;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ThreadIsIoPending:
|
||||||
|
Status = STATUS_NOT_IMPLEMENTED;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ThreadHideFromDebugger:
|
||||||
|
/* Can only be set */
|
||||||
|
Status = STATUS_INVALID_INFO_CLASS;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Status = STATUS_UNSUCCESSFUL;
|
Status = STATUS_INVALID_INFO_CLASS;
|
||||||
}
|
}
|
||||||
ObDereferenceObject(Thread);
|
ObDereferenceObject(Thread);
|
||||||
return Status;
|
return(Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID KeSetPreviousMode(ULONG Mode)
|
VOID KeSetPreviousMode(ULONG Mode)
|
||||||
|
@ -203,15 +321,12 @@ VOID KeSetPreviousMode(ULONG Mode)
|
||||||
ULONG STDCALL
|
ULONG STDCALL
|
||||||
KeGetPreviousMode (VOID)
|
KeGetPreviousMode (VOID)
|
||||||
{
|
{
|
||||||
/* CurrentThread is in ntoskrnl/ps/thread.c */
|
|
||||||
return (ULONG)PsGetCurrentThread()->Tcb.PreviousMode;
|
return (ULONG)PsGetCurrentThread()->Tcb.PreviousMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ULONG STDCALL
|
ULONG STDCALL
|
||||||
ExGetPreviousMode (VOID)
|
ExGetPreviousMode (VOID)
|
||||||
{
|
{
|
||||||
/* CurrentThread is in ntoskrnl/ps/thread.c */
|
|
||||||
return (ULONG)PsGetCurrentThread()->Tcb.PreviousMode;
|
return (ULONG)PsGetCurrentThread()->Tcb.PreviousMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue