diff --git a/reactos/include/ddk/zwtypes.h b/reactos/include/ddk/zwtypes.h index 327a9a36a4a..90f4396238c 100644 --- a/reactos/include/ddk/zwtypes.h +++ b/reactos/include/ddk/zwtypes.h @@ -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 diff --git a/reactos/ntoskrnl/include/internal/ps.h b/reactos/ntoskrnl/include/internal/ps.h index 32bee26503c..b976bd636da 100644 --- a/reactos/ntoskrnl/include/internal/ps.h +++ b/reactos/ntoskrnl/include/internal/ps.h @@ -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) diff --git a/reactos/ntoskrnl/ke/kthread.c b/reactos/ntoskrnl/ke/kthread.c index 27c78fd4f31..57303a38a0f 100644 --- a/reactos/ntoskrnl/ke/kthread.c +++ b/reactos/ntoskrnl/ke/kthread.c @@ -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 diff --git a/reactos/ntoskrnl/mm/virtual.c b/reactos/ntoskrnl/mm/virtual.c index b750e90f65a..7bc8b5991de 100644 --- a/reactos/ntoskrnl/mm/virtual.c +++ b/reactos/ntoskrnl/mm/virtual.c @@ -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)); } } diff --git a/reactos/ntoskrnl/ps/create.c b/reactos/ntoskrnl/ps/create.c index e1dce2f8b4b..609ccd07640 100644 --- a/reactos/ntoskrnl/ps/create.c +++ b/reactos/ntoskrnl/ps/create.c @@ -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); } diff --git a/reactos/ntoskrnl/ps/process.c b/reactos/ntoskrnl/ps/process.c index 99b5b8b55ce..f36a36a11b9 100644 --- a/reactos/ntoskrnl/ps/process.c +++ b/reactos/ntoskrnl/ps/process.c @@ -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: diff --git a/reactos/ntoskrnl/ps/suspend.c b/reactos/ntoskrnl/ps/suspend.c index 90252c2fb62..803b70322a6 100644 --- a/reactos/ntoskrnl/ps/suspend.c +++ b/reactos/ntoskrnl/ps/suspend.c @@ -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 -/* 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; +} + + + + + diff --git a/reactos/ntoskrnl/ps/thread.c b/reactos/ntoskrnl/ps/thread.c index b20ad5b4425..8b6f7ab0584 100644 --- a/reactos/ntoskrnl/ps/thread.c +++ b/reactos/ntoskrnl/ps/thread.c @@ -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, diff --git a/reactos/ntoskrnl/ps/tinfo.c b/reactos/ntoskrnl/ps/tinfo.c index 0320dde39b3..bb4391dd210 100644 --- a/reactos/ntoskrnl/ps/tinfo.c +++ b/reactos/ntoskrnl/ps/tinfo.c @@ -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; }