mirror of
https://github.com/reactos/reactos.git
synced 2024-09-28 21:44:31 +00:00
- 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. svn path=/trunk/; revision=43827
This commit is contained in:
parent
7590cdb16d
commit
bec72fa6a7
|
@ -651,28 +651,32 @@ SetThreadPriorityBoost(IN HANDLE hThread,
|
|||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOL WINAPI
|
||||
BOOL
|
||||
WINAPI
|
||||
GetThreadSelectorEntry(IN HANDLE hThread,
|
||||
IN DWORD dwSelector,
|
||||
OUT LPLDT_ENTRY lpSelectorEntry)
|
||||
IN DWORD dwSelector,
|
||||
OUT LPLDT_ENTRY lpSelectorEntry)
|
||||
{
|
||||
DESCRIPTOR_TABLE_ENTRY DescriptionTableEntry;
|
||||
NTSTATUS Status;
|
||||
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;
|
||||
}
|
||||
/* 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;
|
||||
}
|
||||
|
||||
*lpSelectorEntry = DescriptionTableEntry.Descriptor;
|
||||
return TRUE;
|
||||
/* Success, return the selector */
|
||||
*lpSelectorEntry = DescriptionTableEntry.Descriptor;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -66,6 +66,11 @@ Author:
|
|||
#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
|
||||
//
|
||||
|
|
|
@ -88,6 +88,14 @@ KiThreadStartup(PKSYSTEM_ROUTINE SystemRoutine,
|
|||
KTRAP_FRAME TrapFrame);
|
||||
#endif
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
Ke386GetGdtEntryThread(
|
||||
IN PKTHREAD Thread,
|
||||
IN ULONG Offset,
|
||||
IN PKGDTENTRY Descriptor
|
||||
);
|
||||
|
||||
#endif
|
||||
#endif /* __NTOSKRNL_INCLUDE_INTERNAL_I386_KE_H */
|
||||
|
||||
|
|
|
@ -300,8 +300,9 @@ PspDestroyQuotaBlock(
|
|||
IN PEPROCESS Process
|
||||
);
|
||||
|
||||
#if defined(_X86_)
|
||||
//
|
||||
// VDM Support
|
||||
// VDM and LDT Support
|
||||
//
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
|
@ -315,6 +316,16 @@ PspDeleteVdmObjects(
|
|||
IN PEPROCESS Process
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
PspQueryDescriptorThread(
|
||||
IN PETHREAD Thread,
|
||||
IN PVOID ThreadInformation,
|
||||
IN ULONG ThreadInformationLength,
|
||||
OUT PULONG ReturnLength OPTIONAL
|
||||
);
|
||||
#endif
|
||||
|
||||
//
|
||||
// Job Routines
|
||||
//
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
* PURPOSE: LDT managment
|
||||
*
|
||||
* PROGRAMMERS: David Welch (welch@cwcom.net)
|
||||
* Stefan Ginsberg (stefan.ginsberg@reactos.org)
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
@ -20,6 +21,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,
|
||||
PVOID Base)
|
||||
|
|
|
@ -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">
|
||||
|
|
105
reactos/ntoskrnl/ps/i386/psldt.c
Normal file
105
reactos/ntoskrnl/ps/i386/psldt.c
Normal file
|
@ -0,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;
|
||||
}
|
|
@ -270,9 +270,11 @@ PspDeleteProcess(IN PVOID ObjectBody)
|
|||
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)
|
||||
|
|
|
@ -70,22 +70,6 @@ KPRIORITY PspPriorityTable[PROCESS_PRIORITY_CLASS_ABOVE_NORMAL + 1] =
|
|||
|
||||
/* PRIVATE FUNCTIONS *********************************************************/
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
PspDeleteLdt(PEPROCESS Process)
|
||||
{
|
||||
/* FIXME */
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
PspDeleteVdmObjects(PEPROCESS Process)
|
||||
{
|
||||
/* FIXME */
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
PETHREAD
|
||||
NTAPI
|
||||
PsGetNextProcessThread(IN PEPROCESS Process,
|
||||
|
|
|
@ -1819,9 +1819,19 @@ NtQueryInformationThread(IN HANDLE ThreadHandle,
|
|||
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:
|
||||
|
|
Loading…
Reference in a new issue