[PATCH 25/27] [Kernel32]: ActCtx: storage of activation context on stack

Eric Pouech eric.pouech at wanadoo.fr
Sat Apr 28 07:23:22 CDT 2007




A+
---

 dlls/kernel32/actctx.c  |   80 ++++++++++++++++++++++++++++++++---------------
 include/thread.h        |    3 +-
 tools/winebuild/relay.c |    2 +
 3 files changed, 58 insertions(+), 27 deletions(-)

diff --git a/dlls/kernel32/actctx.c b/dlls/kernel32/actctx.c
index aac9da2..1070f08 100644
--- a/dlls/kernel32/actctx.c
+++ b/dlls/kernel32/actctx.c
@@ -30,6 +30,7 @@ #include "winbase.h"
 #include "winerror.h"
 #include "winnls.h"
 #include "winuser.h"
+#include "thread.h"
 #include "winternl.h"
 #include "wine/debug.h"
 #include "wine/unicode.h"
@@ -49,7 +50,6 @@ #define ACTCTX_FLAGS_ALL (\
  ACTCTX_FLAG_HMODULE_VALID )
 
 #define ACTCTX_FAKE_HANDLE ((HANDLE) 0xf00baa)
-#define ACTCTX_FAKE_COOKIE ((ULONG_PTR) 0xf00bad)
 
 #define ACTCTX_MAGIC       0xC07E3E11
 
@@ -1647,26 +1647,37 @@ static struct actctx* check_actctx(HANDL
     }
 }
 
+struct actctx_list
+{
+    struct actctx_list* prev;
+    HANDLE              hActCtx;
+};
+
 /***********************************************************************
  * ActivateActCtx (KERNEL32.@)
  *
  * Activate an activation context.
  */
-BOOL WINAPI ActivateActCtx(HANDLE hActCtx, ULONG_PTR *ulCookie)
+BOOL WINAPI ActivateActCtx(HANDLE hActCtx, ULONG_PTR* ulCookie)
 {
-  static BOOL reported = FALSE;
+    struct _TEB*        teb;
+    struct actctx_list* top;
 
-  if (reported)
     TRACE("%p %p\n", hActCtx, ulCookie);
-  else
-  {
-    FIXME("%p %p\n", hActCtx, ulCookie);
-    reported = TRUE;
-  }
 
-  if (ulCookie)
-    *ulCookie = ACTCTX_FAKE_COOKIE;
-  return TRUE;
+    if (!check_actctx(hActCtx)) return FALSE;
+
+    top = HeapAlloc(GetProcessHeap(), 0, sizeof(*top));
+    if (!top) return FALSE;
+    teb = NtCurrentTeb();
+
+    top->prev = teb->ActCtxList;
+    top->hActCtx = hActCtx;
+    teb->ActCtxList = top;
+    *ulCookie = (ULONG_PTR)top;
+    AddRefActCtx(hActCtx);
+
+    return TRUE;
 }
 
 /***********************************************************************
@@ -1676,19 +1687,29 @@ BOOL WINAPI ActivateActCtx(HANDLE hActCt
  */
 BOOL WINAPI DeactivateActCtx(DWORD dwFlags, ULONG_PTR ulCookie)
 {
-  static BOOL reported = FALSE;
+    struct _TEB*        teb;
+    struct actctx_list**curr;
 
-  if (reported)
-    TRACE("%08x %08lx\n", dwFlags, ulCookie);
-  else
-  {
-    FIXME("%08x %08lx\n", dwFlags, ulCookie);
-    reported = TRUE;
-  }
+    TRACE("%x %lx\n", dwFlags, ulCookie);
 
-  if (ulCookie != ACTCTX_FAKE_COOKIE)
+    teb = NtCurrentTeb();
+    for (curr = (struct actctx_list**)&teb->ActCtxList; *curr; curr = &(*curr)->prev)
+    {
+        if ((ULONG_PTR)*curr != ulCookie) continue;
+        if (dwFlags == DEACTIVATE_ACTCTX_FLAG_FORCE_EARLY_DEACTIVATION ||
+            *curr == teb->ActCtxList)
+        {
+            struct actctx_list* tmp = *curr;
+            ReleaseActCtx((*curr)->hActCtx);
+            *curr = (*curr)->prev;
+            HeapFree(GetProcessHeap(), 0, tmp);
+            return TRUE;
+        }
+        RaiseException(STATUS_SXS_EARLY_DEACTIVATION, 0, 0, NULL);
+        return FALSE;
+    }
+    RaiseException(STATUS_SXS_INVALID_DEACTIVATION, 0, 0, NULL);
     return FALSE;
-  return TRUE;
 }
 
 /***********************************************************************
@@ -1698,9 +1719,18 @@ BOOL WINAPI DeactivateActCtx(DWORD dwFla
  */
 BOOL WINAPI GetCurrentActCtx(HANDLE* phActCtx)
 {
-  FIXME("%p\n", phActCtx);
-  *phActCtx = ACTCTX_FAKE_HANDLE;
-  return TRUE;
+    struct _TEB*        teb;
+
+    TRACE("%p\n", phActCtx);
+
+    teb = NtCurrentTeb();
+    if (teb->ActCtxList)
+    {
+        *phActCtx = ((struct actctx_list*)teb->ActCtxList)->hActCtx;
+        AddRefActCtx(*phActCtx);
+    }
+    else *phActCtx = NULL;
+    return TRUE;
 }
 
 /***********************************************************************
diff --git a/include/thread.h b/include/thread.h
index 68d7ae2..a60db9e 100644
--- a/include/thread.h
+++ b/include/thread.h
@@ -49,7 +49,8 @@ typedef struct _TEB
     PVOID        SystemReserved1[54];          /* 0cc */
     PVOID        Spare1;                       /* 1a4 */
     LONG         ExceptionCode;                /* 1a8 */
-    BYTE         SpareBytes1[40];              /* 1ac */
+    VOID*        ActCtxList;                   /* 1ac list of Activation Contexts */
+    BYTE         SpareBytes1[36];              /* 1b0 */
     PVOID        SystemReserved2[10];          /* 1d4 */
 
     /* The following are Wine-specific fields (NT: GdiTebBatch) */
diff --git a/tools/winebuild/relay.c b/tools/winebuild/relay.c
index b75c9c5..75b2b9a 100644
--- a/tools/winebuild/relay.c
+++ b/tools/winebuild/relay.c
@@ -48,7 +48,7 @@ #define STACK32OFFSET(reg)  STRUCTOFFSET
 #define STACKOFFSET 0xc0  /* STRUCTOFFSET(TEB,WOW32Reserved) */
 
 /* fix this if the ntdll_thread_regs structure is changed */
-#define GS_OFFSET  0x1b0  /* STRUCTOFFSET(TEB,SpareBytes1) + STRUCTOFFSET(ntdll_thread_regs,gs) */
+#define GS_OFFSET  0x1b4  /* STRUCTOFFSET(TEB,SpareBytes1) + STRUCTOFFSET(ntdll_thread_regs,gs) */
 
 static void function_header( const char *name )
 {




More information about the wine-patches mailing list