[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