kernel: allocate global memory with execute permission

Mikolaj Zalewski mikolaj at zalewski.pl
Mon Aug 13 13:01:43 CDT 2007


This is needed for Win16 programs as we allocate e.g. memory for NE code 
segments with GlobalAlloc. This patch doesn't yet allow to run Win16 
programs as we have some code in the UMB of the DOS memory area - I'll 
need to see how that's done on Windows.
-------------- next part --------------
>From 6894bc89e448521fe07fbbe19f09a46f1c545468 Mon Sep 17 00:00:00 2001
From: Mikolaj Zalewski <mikolajz at mikolajz.smo.corp.google.com>
Date: Mon, 13 Aug 2007 10:55:08 -0700
Subject: [PATCH] kernel: allocate global memory with execute permission
---
 dlls/kernel32/global16.c         |   37 ++++++++++++++++++++++++++-----------
 dlls/kernel32/kernel16_private.h |    3 +++
 dlls/kernel32/kernel_main.c      |    3 +++
 3 files changed, 32 insertions(+), 11 deletions(-)

diff --git a/dlls/kernel32/global16.c b/dlls/kernel32/global16.c
index b17c610..2890601 100644
--- a/dlls/kernel32/global16.c
+++ b/dlls/kernel32/global16.c
@@ -66,6 +66,8 @@ #define GA_DISCARDABLE  0x08
 #define GA_IPCSHARE     0x10  /* same as GMEM_DDESHARE */
 #define GA_DOSMEM       0x20
 
+static HANDLE hWin16GlobalsHeap;
+
 /* Arena array (FIXME) */
 static GLOBALARENA *pGlobalArena;
 static int globalArenaSize;
@@ -94,6 +96,21 @@ static inline UINT      DOSMEM_ResizeBlo
 }
 
 /***********************************************************************
+ *           GLOBAL16_Init
+ *
+ * Initializes the Win16 global heap. Called from DllMain
+ */
+void GLOBAL16_Init()
+{
+    /* we create global memory block with execute permission. The access can be limited
+     * for 16-bit code on selector level */
+    hWin16GlobalsHeap = HeapCreate(HEAP_CREATE_ENABLE_EXECUTE, 0, 0);
+    if (hWin16GlobalsHeap == NULL)
+	ERR("Allocating Win16 global heap failed!\n");
+}
+
+
+/***********************************************************************
  *           GLOBAL_GetArena
  *
  * Return the arena for a given selector, growing the arena array if needed.
@@ -235,7 +252,7 @@ HGLOBAL16 GLOBAL_Alloc( UINT16 flags, DW
     size = (size + 0x1f) & ~0x1f;
 
     /* Allocate the linear memory */
-    ptr = HeapAlloc( GetProcessHeap(), 0, size );
+    ptr = HeapAlloc( hWin16GlobalsHeap, 0, size );
       /* FIXME: free discardable blocks and try again? */
     if (!ptr) return 0;
 
@@ -244,7 +261,7 @@ HGLOBAL16 GLOBAL_Alloc( UINT16 flags, DW
     handle = GLOBAL_CreateBlock( flags, ptr, size, hOwner, selflags );
     if (!handle)
     {
-        HeapFree( GetProcessHeap(), 0, ptr );
+        HeapFree( hWin16GlobalsHeap, 0, ptr );
         return 0;
     }
 
@@ -315,7 +332,7 @@ HGLOBAL16 WINAPI GlobalReAlloc16(
         if (pArena->flags & GA_DOSMEM)
             DOSMEM_FreeBlock( (void *)pArena->base );
         else
-            HeapFree( GetProcessHeap(), 0, (void *)pArena->base );
+            HeapFree( hWin16GlobalsHeap, 0, (void *)pArena->base );
         pArena->base = 0;
 
         /* Note: we rely on the fact that SELECTOR_ReallocBlock won't
@@ -374,13 +391,11 @@ HGLOBAL16 WINAPI GlobalReAlloc16(
          */
 
 	if (ptr)
-            newptr = HeapReAlloc( GetProcessHeap(),
+            newptr = HeapReAlloc( hWin16GlobalsHeap,
 		(pArena->pageLockCount > 0) ? HEAP_REALLOC_IN_PLACE_ONLY : 0, 
                               ptr, size );
 	else
-            newptr = HeapAlloc( GetProcessHeap(),
-		(pArena->pageLockCount > 0) ? HEAP_REALLOC_IN_PLACE_ONLY : 0, 
-                              size );
+            newptr = HeapAlloc( hWin16GlobalsHeap, 0, size );
 
     }
 
@@ -392,7 +407,7 @@ HGLOBAL16 WINAPI GlobalReAlloc16(
             if (pArena->flags & GA_DOSMEM)
                 DOSMEM_FreeBlock( (void *)pArena->base );
             else
-                HeapFree( GetProcessHeap(), 0, ptr );
+                HeapFree( hWin16GlobalsHeap, 0, ptr );
             SELECTOR_FreeBlock( sel );
             memset( pArena, 0, sizeof(GLOBALARENA) );
         }
@@ -408,7 +423,7 @@ HGLOBAL16 WINAPI GlobalReAlloc16(
         if (pArena->flags & GA_DOSMEM)
             DOSMEM_FreeBlock( (void *)pArena->base );
         else
-            HeapFree( GetProcessHeap(), 0, ptr );
+            HeapFree( hWin16GlobalsHeap, 0, ptr );
         memset( pArena, 0, sizeof(GLOBALARENA) );
         return 0;
     }
@@ -419,7 +434,7 @@ HGLOBAL16 WINAPI GlobalReAlloc16(
         if (pArena->flags & GA_DOSMEM)
             DOSMEM_FreeBlock( (void *)pArena->base );
         else
-            HeapFree( GetProcessHeap(), 0, ptr );
+            HeapFree( hWin16GlobalsHeap, 0, ptr );
         SELECTOR_FreeBlock( sel );
         return 0;
     }
@@ -463,7 +478,7 @@ HGLOBAL16 WINAPI GlobalFree16(
 
     TRACE("%04x\n", handle );
     if (!GLOBAL_FreeBlock( handle )) return handle;  /* failed */
-    HeapFree( GetProcessHeap(), 0, ptr );
+    HeapFree( hWin16GlobalsHeap, 0, ptr );
     return 0;
 }
 
diff --git a/dlls/kernel32/kernel16_private.h b/dlls/kernel32/kernel16_private.h
index 0c59bbd..bab6c79 100644
--- a/dlls/kernel32/kernel16_private.h
+++ b/dlls/kernel32/kernel16_private.h
@@ -188,6 +188,9 @@ static inline void stack16_pop( int size
     NtCurrentTeb()->WOW32Reserved = (char *)NtCurrentTeb()->WOW32Reserved + size;
 }
 
+/* global16.c */
+extern void GLOBAL16_Init();
+
 /* ne_module.c */
 extern NE_MODULE *NE_GetPtr( HMODULE16 hModule );
 extern WORD NE_GetOrdinal( HMODULE16 hModule, const char *name );
diff --git a/dlls/kernel32/kernel_main.c b/dlls/kernel32/kernel_main.c
index 846f787..8aeb43f 100644
--- a/dlls/kernel32/kernel_main.c
+++ b/dlls/kernel32/kernel_main.c
@@ -123,6 +123,9 @@ static BOOL process_attach( HMODULE modu
 
     NtQuerySystemInformation( SystemTimeOfDayInformation, &ti, sizeof(ti), NULL );
     server_start_time = ti.liKeBootTime.QuadPart;
+    
+    /* Initialize Win16 global heap */
+    GLOBAL16_Init();
 
     /* Setup registry locale information */
     LOCALE_InitRegistry();
-- 
1.4.1



More information about the wine-patches mailing list