Author: sginsberg Date: Thu Oct 29 11:04:15 2009 New Revision: 43827
URL: http://svn.reactos.org/svn/reactos?rev=43827&view=rev Log: - Implement the ThreadDescriptorTableEntry case for NtQueryInformationThread. This is required for the GetThreadSelectorEntry routine used by user mode debuggers. - #if out some x86-only LDT code from PS and move it to psldt.c.
Added: trunk/reactos/ntoskrnl/ps/i386/psldt.c (with props) Modified: trunk/reactos/dll/win32/kernel32/thread/thread.c trunk/reactos/include/ndk/i386/ketypes.h trunk/reactos/ntoskrnl/include/internal/i386/ke.h trunk/reactos/ntoskrnl/include/internal/ps.h trunk/reactos/ntoskrnl/ke/i386/ldt.c trunk/reactos/ntoskrnl/ntoskrnl-generic.rbuild trunk/reactos/ntoskrnl/ps/kill.c trunk/reactos/ntoskrnl/ps/process.c trunk/reactos/ntoskrnl/ps/query.c
Modified: trunk/reactos/dll/win32/kernel32/thread/thread.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/thread/t... ============================================================================== --- trunk/reactos/dll/win32/kernel32/thread/thread.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/kernel32/thread/thread.c [iso-8859-1] Thu Oct 29 11:04:15 2009 @@ -651,28 +651,32 @@ /* * @implemented */ -BOOL WINAPI +BOOL +WINAPI GetThreadSelectorEntry(IN HANDLE hThread, - IN DWORD dwSelector, - OUT LPLDT_ENTRY lpSelectorEntry) -{ - DESCRIPTOR_TABLE_ENTRY DescriptionTableEntry; - NTSTATUS Status; - - DescriptionTableEntry.Selector = dwSelector; - Status = NtQueryInformationThread(hThread, - ThreadDescriptorTableEntry, - &DescriptionTableEntry, - sizeof(DESCRIPTOR_TABLE_ENTRY), - NULL); - if(!NT_SUCCESS(Status)) - { - SetLastErrorByStatus(Status); - return FALSE; - } - - *lpSelectorEntry = DescriptionTableEntry.Descriptor; - return TRUE; + IN DWORD dwSelector, + OUT LPLDT_ENTRY lpSelectorEntry) +{ + DESCRIPTOR_TABLE_ENTRY DescriptionTableEntry; + NTSTATUS Status; + + /* Set the selector and do the query */ + DescriptionTableEntry.Selector = dwSelector; + Status = NtQueryInformationThread(hThread, + ThreadDescriptorTableEntry, + &DescriptionTableEntry, + sizeof(DESCRIPTOR_TABLE_ENTRY), + NULL); + if (!NT_SUCCESS(Status)) + { + /* Fail */ + SetLastErrorByStatus(Status); + return FALSE; + } + + /* Success, return the selector */ + *lpSelectorEntry = DescriptionTableEntry.Descriptor; + return TRUE; }
/*
Modified: trunk/reactos/include/ndk/i386/ketypes.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/ndk/i386/ketypes.h?... ============================================================================== --- trunk/reactos/include/ndk/i386/ketypes.h [iso-8859-1] (original) +++ trunk/reactos/include/ndk/i386/ketypes.h [iso-8859-1] Thu Oct 29 11:04:15 2009 @@ -65,6 +65,11 @@ #define KGDT_LDT 0x48 #define KGDT_DF_TSS 0x50 #define KGDT_NMI_TSS 0x58 + +// +// Define the number of GDTs that can be queried by user mode +// +#define KGDT_NUMBER 10
// // CR4
Modified: trunk/reactos/ntoskrnl/include/internal/i386/ke.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/i... ============================================================================== --- trunk/reactos/ntoskrnl/include/internal/i386/ke.h [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/include/internal/i386/ke.h [iso-8859-1] Thu Oct 29 11:04:15 2009 @@ -88,6 +88,14 @@ KTRAP_FRAME TrapFrame); #endif
+NTSTATUS +NTAPI +Ke386GetGdtEntryThread( + IN PKTHREAD Thread, + IN ULONG Offset, + IN PKGDTENTRY Descriptor +); + #endif #endif /* __NTOSKRNL_INCLUDE_INTERNAL_I386_KE_H */
Modified: trunk/reactos/ntoskrnl/include/internal/ps.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/p... ============================================================================== --- trunk/reactos/ntoskrnl/include/internal/ps.h [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/include/internal/ps.h [iso-8859-1] Thu Oct 29 11:04:15 2009 @@ -300,8 +300,9 @@ IN PEPROCESS Process );
-// -// VDM Support +#if defined(_X86_) +// +// VDM and LDT Support // NTSTATUS NTAPI @@ -314,6 +315,16 @@ PspDeleteVdmObjects( IN PEPROCESS Process ); + +NTSTATUS +NTAPI +PspQueryDescriptorThread( + IN PETHREAD Thread, + IN PVOID ThreadInformation, + IN ULONG ThreadInformationLength, + OUT PULONG ReturnLength OPTIONAL +); +#endif
// // Job Routines
Modified: trunk/reactos/ntoskrnl/ke/i386/ldt.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/ldt.c?rev=... ============================================================================== --- trunk/reactos/ntoskrnl/ke/i386/ldt.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/ke/i386/ldt.c [iso-8859-1] Thu Oct 29 11:04:15 2009 @@ -5,6 +5,7 @@ * PURPOSE: LDT managment * * PROGRAMMERS: David Welch (welch@cwcom.net) + * Stefan Ginsberg (stefan.ginsberg@reactos.org) */
/* INCLUDES *****************************************************************/ @@ -19,6 +20,55 @@ static KSPIN_LOCK GdtLock;
/* FUNCTIONS *****************************************************************/ + +NTSTATUS +NTAPI +Ke386GetGdtEntryThread(IN PKTHREAD Thread, + IN ULONG Offset, + IN PKGDTENTRY Descriptor) +{ + /* Make sure the offset is inside the allowed range */ + if (!((Offset) < (KGDT_NUMBER * sizeof(KGDTENTRY)))) + { + /* It isn't, fail */ + return STATUS_ACCESS_VIOLATION; + } + + /* Check if this is the LDT selector */ + if (Offset == KGDT_LDT) + { + /* Get it from the thread's process */ + RtlCopyMemory(Descriptor, + &Thread->Process->LdtDescriptor, + sizeof(KGDTENTRY)); + } + else + { + /* Get the descriptor entry from the GDT */ + RtlCopyMemory(Descriptor, + (PCHAR)((PKIPCR)KeGetPcr()->GDT) + Offset, + sizeof(KGDTENTRY)); + + /* Check if this is the TEB selector */ + if (Offset == KGDT_R3_TEB) + { + /* + * Make sure we set the correct base for this thread. This is per + * process and is set in the GDT on context switch, so it might not + * be correct for the thread specified. + */ + Descriptor->BaseLow = + (USHORT)((ULONG_PTR)(Thread->Teb) & 0xFFFF); + Descriptor->HighWord.Bytes.BaseMid = + (UCHAR)((ULONG_PTR)(Thread->Teb) >> 16); + Descriptor->HighWord.Bytes.BaseHi = + (UCHAR)((ULONG_PTR)(Thread->Teb) >> 24); + } + } + + /* Success */ + return STATUS_SUCCESS; +}
VOID KeSetBaseGdtSelector(ULONG Entry,
Modified: trunk/reactos/ntoskrnl/ntoskrnl-generic.rbuild URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ntoskrnl-generic.r... ============================================================================== --- trunk/reactos/ntoskrnl/ntoskrnl-generic.rbuild [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/ntoskrnl-generic.rbuild [iso-8859-1] Thu Oct 29 11:04:15 2009 @@ -444,6 +444,7 @@ <if property="ARCH" value="i386"> <directory name="i386"> <file>psctx.c</file> + <file>psldt.c</file> </directory> </if> <if property="ARCH" value="arm">
Added: trunk/reactos/ntoskrnl/ps/i386/psldt.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ps/i386/psldt.c?re... ============================================================================== --- trunk/reactos/ntoskrnl/ps/i386/psldt.c (added) +++ trunk/reactos/ntoskrnl/ps/i386/psldt.c [iso-8859-1] Thu Oct 29 11:04:15 2009 @@ -1,0 +1,105 @@ +/* + * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory + * FILE: ntoskrnl/ps/i386/psldt.c + * PURPOSE: LDT support for x86 + * PROGRAMMERS: Stefan Ginsberg (stefan.ginsberg@reactos.org) + */ + +/* INCLUDES ******************************************************************/ + +#include <ntoskrnl.h> +#define NDEBUG +#include <debug.h> + +/* FUNCTIONS *****************************************************************/ + +NTSTATUS +NTAPI +PspDeleteLdt(PEPROCESS Process) +{ + /* FIXME */ + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +PspDeleteVdmObjects(PEPROCESS Process) +{ + /* FIXME */ + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +PspQueryDescriptorThread(IN PETHREAD Thread, + IN PVOID ThreadInformation, + IN ULONG ThreadInformationLength, + OUT PULONG ReturnLength OPTIONAL) +{ + DESCRIPTOR_TABLE_ENTRY DescriptorEntry; + LDT_ENTRY Descriptor; + NTSTATUS Status; + PAGED_CODE(); + + /* Verify the size */ + if (ThreadInformationLength != sizeof(DESCRIPTOR_TABLE_ENTRY)) + { + /* Fail */ + return STATUS_INFO_LENGTH_MISMATCH; + } + + /* Enter SEH for the copy */ + _SEH2_TRY + { + /* Get the descriptor */ + RtlCopyMemory(&DescriptorEntry, + ThreadInformation, + sizeof(DESCRIPTOR_TABLE_ENTRY)); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Return the exception code */ + _SEH2_YIELD(return _SEH2_GetExceptionCode()); + } + _SEH2_END; + + /* Check if this is a GDT selector */ + if (!(DescriptorEntry.Selector & 0x4)) + { + /* Get the GDT entry */ + Status = Ke386GetGdtEntryThread(&Thread->Tcb, + DescriptorEntry.Selector & 0xFFFFFFF8, + (PKGDTENTRY)&Descriptor); + if (!NT_SUCCESS(Status)) return Status; + + /* Enter SEH for the copy */ + _SEH2_TRY + { + /* Copy the GDT entry to caller */ + RtlCopyMemory(&((PDESCRIPTOR_TABLE_ENTRY)ThreadInformation)-> + Descriptor, + &Descriptor, + sizeof(LDT_ENTRY)); + if (ReturnLength) *ReturnLength = sizeof(LDT_ENTRY); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Return the exception code */ + _SEH2_YIELD(return _SEH2_GetExceptionCode()); + } + _SEH2_END; + + /* Success */ + Status = STATUS_SUCCESS; + } + else + { + /* This is only supported for VDM, which we don't implement */ + ASSERT(Thread->ThreadsProcess->LdtInformation == NULL); + Status = STATUS_NO_LDT; + } + + /* Return status to caller */ + return Status; +}
Propchange: trunk/reactos/ntoskrnl/ps/i386/psldt.c ------------------------------------------------------------------------------ svn:eol-style = native
Modified: trunk/reactos/ntoskrnl/ps/kill.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ps/kill.c?rev=4382... ============================================================================== --- trunk/reactos/ntoskrnl/ps/kill.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/ps/kill.c [iso-8859-1] Thu Oct 29 11:04:15 2009 @@ -270,9 +270,11 @@ Process->SectionObject = NULL; }
- /* Clean LDT and VDM_OBJECTS */ +#if defined(_X86_) + /* Clean Ldt and Vdm objects */ PspDeleteLdt(Process); PspDeleteVdmObjects(Process); +#endif
/* Delete the Object Table */ if (Process->ObjectTable)
Modified: trunk/reactos/ntoskrnl/ps/process.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ps/process.c?rev=4... ============================================================================== --- trunk/reactos/ntoskrnl/ps/process.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/ps/process.c [iso-8859-1] Thu Oct 29 11:04:15 2009 @@ -69,22 +69,6 @@ };
/* PRIVATE FUNCTIONS *********************************************************/ - -NTSTATUS -NTAPI -PspDeleteLdt(PEPROCESS Process) -{ - /* FIXME */ - return STATUS_SUCCESS; -} - -NTSTATUS -NTAPI -PspDeleteVdmObjects(PEPROCESS Process) -{ - /* FIXME */ - return STATUS_SUCCESS; -}
PETHREAD NTAPI
Modified: trunk/reactos/ntoskrnl/ps/query.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ps/query.c?rev=438... ============================================================================== --- trunk/reactos/ntoskrnl/ps/query.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/ps/query.c [iso-8859-1] Thu Oct 29 11:04:15 2009 @@ -1819,9 +1819,19 @@ KeLowerIrql(OldIrql); break;
+ /* LDT and GDT information */ case ThreadDescriptorTableEntry: - DPRINT1("NtQueryInformationThread(): case ThreadDescriptorTableEntry not implemented!\n"); + +#if defined(_X86_) + /* Call the worker routine */ + Status = PspQueryDescriptorThread(Thread, + ThreadInformation, + ThreadInformationLength, + ReturnLength); +#else + /* Only implemented on x86 */ Status = STATUS_NOT_IMPLEMENTED; +#endif break;
case ThreadPriorityBoost: