[PATCH] [NtDll/Kernel32]: moved GetThreadSelectorEntry to ntdll
Eric Pouech
eric.pouech at wanadoo.fr
Fri May 26 05:10:57 CDT 2006
- implemented NtQueryInformationThread's ThreadDescriptorTableEntry
information class
- used it to implement the kernel32's equivalent (GetThreadSelectorEntry)
A+
---
dlls/kernel/selector.c | 66 +++++++-----------------------------------------
dlls/ntdll/thread.c | 62 ++++++++++++++++++++++++++++++++++++++++++++-
include/winternl.h | 6 ++++
3 files changed, 77 insertions(+), 57 deletions(-)
diff --git a/dlls/kernel/selector.c b/dlls/kernel/selector.c
index 7cd159c..86d150c 100644
--- a/dlls/kernel/selector.c
+++ b/dlls/kernel/selector.c
@@ -573,67 +573,21 @@ __ASM_GLOBAL_FUNC( UnMapSLFixArray, "ret
/***********************************************************************
* GetThreadSelectorEntry (KERNEL32.@)
*/
-BOOL WINAPI GetThreadSelectorEntry( HANDLE hthread, DWORD sel, LPLDT_ENTRY ldtent)
+BOOL WINAPI GetThreadSelectorEntry( HANDLE hthread, DWORD sel, LPLDT_ENTRY ldtent )
{
-#ifdef __i386__
- BOOL ret;
+ THREAD_DESCRIPTOR_INFORMATION tdi;
+ NTSTATUS status;
- if (!(sel & 4)) /* GDT selector */
+ tdi.Selector = sel;
+ status = NtQueryInformationThread( hthread, ThreadDescriptorTableEntry,
+ &tdi, sizeof(tdi), NULL);
+ if (status)
{
- sel &= ~3; /* ignore RPL */
- if (!sel) /* null selector */
- {
- memset( ldtent, 0, sizeof(*ldtent) );
- return TRUE;
- }
- ldtent->BaseLow = 0;
- ldtent->HighWord.Bits.BaseMid = 0;
- ldtent->HighWord.Bits.BaseHi = 0;
- ldtent->LimitLow = 0xffff;
- ldtent->HighWord.Bits.LimitHi = 0xf;
- ldtent->HighWord.Bits.Dpl = 3;
- ldtent->HighWord.Bits.Sys = 0;
- ldtent->HighWord.Bits.Pres = 1;
- ldtent->HighWord.Bits.Granularity = 1;
- ldtent->HighWord.Bits.Default_Big = 1;
- ldtent->HighWord.Bits.Type = 0x12;
- /* it has to be one of the system GDT selectors */
- if (sel == (wine_get_ds() & ~3)) return TRUE;
- if (sel == (wine_get_ss() & ~3)) return TRUE;
- if (sel == (wine_get_cs() & ~3))
- {
- ldtent->HighWord.Bits.Type |= 8; /* code segment */
- return TRUE;
- }
- SetLastError( ERROR_NOACCESS );
+ SetLastError( RtlNtStatusToDosError(status) );
return FALSE;
}
-
- SERVER_START_REQ( get_selector_entry )
- {
- req->handle = hthread;
- req->entry = sel >> __AHSHIFT;
- if ((ret = !wine_server_call_err( req )))
- {
- if (!(reply->flags & WINE_LDT_FLAGS_ALLOCATED))
- {
- SetLastError( ERROR_MR_MID_NOT_FOUND ); /* sic */
- ret = FALSE;
- }
- else
- {
- wine_ldt_set_base( ldtent, (void *)reply->base );
- wine_ldt_set_limit( ldtent, reply->limit );
- wine_ldt_set_flags( ldtent, reply->flags );
- }
- }
- }
- SERVER_END_REQ;
- return ret;
-#else
- SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
- return FALSE;
-#endif
+ *ldtent = tdi.Entry;
+ return TRUE;
}
diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c
index 5d25096..b2d0c55 100644
--- a/dlls/ntdll/thread.c
+++ b/dlls/ntdll/thread.c
@@ -1073,11 +1073,71 @@ NTSTATUS WINAPI NtQueryInformationThread
}
}
return status;
+ case ThreadDescriptorTableEntry:
+ {
+#ifdef __i386__
+ THREAD_DESCRIPTOR_INFORMATION* tdi = data;
+ if (length < sizeof(*tdi))
+ status = STATUS_INFO_LENGTH_MISMATCH;
+ else if (!(tdi->Selector & 4)) /* GDT selector */
+ {
+ unsigned sel = tdi->Selector & ~3; /* ignore RPL */
+ status = STATUS_SUCCESS;
+ if (!sel) /* null selector */
+ memset( &tdi->Entry, 0, sizeof(tdi->Entry) );
+ else
+ {
+ tdi->Entry.BaseLow = 0;
+ tdi->Entry.HighWord.Bits.BaseMid = 0;
+ tdi->Entry.HighWord.Bits.BaseHi = 0;
+ tdi->Entry.LimitLow = 0xffff;
+ tdi->Entry.HighWord.Bits.LimitHi = 0xf;
+ tdi->Entry.HighWord.Bits.Dpl = 3;
+ tdi->Entry.HighWord.Bits.Sys = 0;
+ tdi->Entry.HighWord.Bits.Pres = 1;
+ tdi->Entry.HighWord.Bits.Granularity = 1;
+ tdi->Entry.HighWord.Bits.Default_Big = 1;
+ tdi->Entry.HighWord.Bits.Type = 0x12;
+ /* it has to be one of the system GDT selectors */
+ if (sel != (wine_get_ds() & ~3) && sel != (wine_get_ss() & ~3))
+ {
+ if (sel == (wine_get_cs() & ~3))
+ tdi->Entry.HighWord.Bits.Type |= 8; /* code segment */
+ else status = STATUS_ACCESS_DENIED;
+ }
+ }
+ }
+ else
+ {
+ SERVER_START_REQ( get_selector_entry )
+ {
+ req->handle = handle;
+ req->entry = tdi->Selector >> 3;
+ status = wine_server_call( req );
+ if (!status)
+ {
+ if (!(reply->flags & WINE_LDT_FLAGS_ALLOCATED))
+ status = STATUS_INVALID_LDT_OFFSET;
+ else
+ {
+ wine_ldt_set_base ( &tdi->Entry, (void *)reply->base );
+ wine_ldt_set_limit( &tdi->Entry, reply->limit );
+ wine_ldt_set_flags( &tdi->Entry, reply->flags );
+ }
+ }
+ }
+ SERVER_END_REQ;
+ }
+#else
+ status = STATUS_NOT_IMPLEMENTED;
+#endif
+ if (status == STATUS_SUCCESS && ret_len) *ret_len = sizeof(*tdi);
+ return status;
+ }
case ThreadPriority:
case ThreadBasePriority:
case ThreadAffinityMask:
case ThreadImpersonationToken:
- case ThreadDescriptorTableEntry:
case ThreadEnableAlignmentFaultFixup:
case ThreadEventPair_Reusable:
case ThreadQuerySetWin32StartAddress:
diff --git a/include/winternl.h b/include/winternl.h
index d90d5ea..da3505a 100644
--- a/include/winternl.h
+++ b/include/winternl.h
@@ -728,6 +728,12 @@ typedef struct _THREAD_BASIC_INFORMATION
LONG BasePriority;
} THREAD_BASIC_INFORMATION, *PTHREAD_BASIC_INFORMATION;
+typedef struct _THREAD_DESCRIPTOR_INFORMATION
+{
+ DWORD Selector;
+ LDT_ENTRY Entry;
+} THREAD_DESCRIPTOR_INFORMATION, *PTHREAD_DESCRIPTOR_INFORMATION;
+
typedef struct _KERNEL_USER_TIMES {
LARGE_INTEGER CreateTime;
LARGE_INTEGER ExitTime;
More information about the wine-patches
mailing list