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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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(a)cwcom.net)
+ * Stefan Ginsberg (stefan.ginsberg(a)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.…
==============================================================================
--- 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?r…
==============================================================================
--- 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(a)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=438…
==============================================================================
--- 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=…
==============================================================================
--- 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=43…
==============================================================================
--- 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: