From e15aadd58a15f0c5d0fdc6c352de374ebb9cc52b Mon Sep 17 00:00:00 2001
From: Alexandre Julliard <julliard@winehq.org>
Date: Tue, 13 May 2003 00:49:49 +0000
Subject: [PATCH] Allocate/free the 16-bit thread stack in the kernel dll init
 routine.

---
 dlls/kernel/kernel_main.c | 34 ++++++++++++++++++++++++++++++++++
 scheduler/sysdeps.c       |  1 -
 scheduler/thread.c        | 21 +++++----------------
 3 files changed, 39 insertions(+), 17 deletions(-)

diff --git a/dlls/kernel/kernel_main.c b/dlls/kernel/kernel_main.c
index 442d059befe..aa7296b6375 100644
--- a/dlls/kernel/kernel_main.c
+++ b/dlls/kernel/kernel_main.c
@@ -38,6 +38,8 @@
 #include "miscemu.h"
 #include "module.h"
 #include "task.h"
+#include "thread.h"
+#include "stackframe.h"
 #include "wincon.h"
 #include "console_private.h"
 
@@ -64,6 +66,31 @@ static void ldt_unlock(void)
     LeaveCriticalSection( &ldt_section );
 }
 
+
+/***********************************************************************
+ *           KERNEL thread initialisation routine
+ */
+static void thread_attach(void)
+{
+    /* allocate the 16-bit stack (FIXME: should be done lazily) */
+    HGLOBAL16 hstack = K32WOWGlobalAlloc16( GMEM_FIXED, 0x10000 );
+    NtCurrentTeb()->stack_sel = GlobalHandleToSel16( hstack );
+    NtCurrentTeb()->cur_stack = MAKESEGPTR( NtCurrentTeb()->stack_sel,
+                                            0x10000 - sizeof(STACK16FRAME) );
+}
+
+
+/***********************************************************************
+ *           KERNEL thread finalisation routine
+ */
+static void thread_detach(void)
+{
+    /* free the 16-bit stack */
+    K32WOWGlobalFree16( NtCurrentTeb()->stack_sel );
+    NtCurrentTeb()->cur_stack = 0;
+}
+
+
 /***********************************************************************
  *           KERNEL process initialisation routine
  */
@@ -144,6 +171,7 @@ static BOOL process_attach(void)
     if (main_create_flags & CREATE_NEW_PROCESS_GROUP)
         SetConsoleCtrlHandler(NULL, TRUE);
 
+    thread_attach();
     return TRUE;
 }
 
@@ -156,6 +184,12 @@ BOOL WINAPI MAIN_KernelInit( HINSTANCE hinst, DWORD reason, LPVOID reserved )
     {
     case DLL_PROCESS_ATTACH:
         return process_attach();
+    case DLL_THREAD_ATTACH:
+        thread_attach();
+        break;
+    case DLL_THREAD_DETACH:
+        thread_detach();
+        break;
     case DLL_PROCESS_DETACH:
         WriteOutProfiles16();
         break;
diff --git a/scheduler/sysdeps.c b/scheduler/sysdeps.c
index eb2a4bc4934..933b24ca366 100644
--- a/scheduler/sysdeps.c
+++ b/scheduler/sysdeps.c
@@ -293,7 +293,6 @@ void SYSDEPS_ExitThread( int status )
     struct thread_cleanup_info info;
     MEMORY_BASIC_INFORMATION meminfo;
 
-    wine_ldt_free_entries( teb->stack_sel, 1 );
     VirtualQuery( teb->stack_top, &meminfo, sizeof(meminfo) );
     info.stack_base = meminfo.AllocationBase;
     info.stack_size = meminfo.RegionSize + ((char *)teb->stack_top - (char *)meminfo.AllocationBase);
diff --git a/scheduler/thread.c b/scheduler/thread.c
index 6d5ad887ba2..87e312eeb01 100644
--- a/scheduler/thread.c
+++ b/scheduler/thread.c
@@ -120,7 +120,6 @@ static void THREAD_FreeTEB( TEB *teb )
 {
     TRACE("(%p) called\n", teb );
     /* Free the associated memory */
-    wine_ldt_free_entries( teb->stack_sel, 1 );
     wine_ldt_free_fs( teb->teb_sel );
     VirtualFree( teb->stack_base, 0, MEM_RELEASE );
 }
@@ -163,14 +162,12 @@ TEB *THREAD_InitStack( TEB *teb, DWORD stack_size )
      * 1 page              NOACCESS guard page
      * 1 page              PAGE_GUARD guard page
      * stack_size          normal stack
-     * 64Kb                16-bit stack (optional)
      * 1 page              TEB (except for initial thread)
      * 1 page              debug info (except for initial thread)
      */
 
     stack_size = (stack_size + (page_size - 1)) & ~(page_size - 1);
     total_size = stack_size + SIGNAL_STACK_SIZE + 3 * page_size;
-    total_size += 0x10000; /* 16-bit stack */
     if (!teb) total_size += 2 * page_size;
 
     if (!(base = VirtualAlloc( NULL, total_size, MEM_COMMIT, PAGE_EXECUTE_READWRITE )))
@@ -179,7 +176,11 @@ TEB *THREAD_InitStack( TEB *teb, DWORD stack_size )
     if (!teb)
     {
         teb = (TEB *)((char *)base + total_size - 2 * page_size);
-        if (!THREAD_InitTEB( teb )) goto error;
+        if (!THREAD_InitTEB( teb ))
+        {
+            VirtualFree( base, 0, MEM_RELEASE );
+            return NULL;
+        }
         teb->debug_info = (char *)teb + page_size;
     }
 
@@ -194,19 +195,7 @@ TEB *THREAD_InitStack( TEB *teb, DWORD stack_size )
     VirtualProtect( (char *)teb->signal_stack + SIGNAL_STACK_SIZE, 1, PAGE_NOACCESS, &old_prot );
     VirtualProtect( (char *)teb->signal_stack + SIGNAL_STACK_SIZE + page_size, 1,
                     PAGE_EXECUTE_READWRITE | PAGE_GUARD, &old_prot );
-
-    /* Allocate the 16-bit stack selector */
-
-    teb->stack_sel = SELECTOR_AllocBlock( teb->stack_top, 0x10000, WINE_LDT_FLAGS_DATA );
-    if (!teb->stack_sel) goto error;
-    teb->cur_stack = MAKESEGPTR( teb->stack_sel, 0x10000 - sizeof(STACK16FRAME) );
-
     return teb;
-
-error:
-    wine_ldt_free_fs( teb->teb_sel );
-    VirtualFree( base, 0, MEM_RELEASE );
-    return NULL;
 }
 
 
-- 
GitLab