[PATCH updated] kernel32: Bug 8241 Mask out obsolete flags in GlobalAlloc

Peter Hedlund peter at peterandlinda.com
Wed May 27 12:35:23 CDT 2009


Changelog:
    - Mask out obsolete flags in GlobalAlloc()
    - Test that passes on wine and Windows XP.

Hello,

The attached patch masks out obsolete flags in GlobalAlloc() in a safe way as 
discussed in http://bugs.winehq.org/show_bug.cgi?id=8241.

This will allow programs erroneously setting such flags to run. Examples 
discussed in the bug report include GraphPad Prism 3, 4, and 5.

This updated patch includes a test that passes on both wine and Windows XP.

Thanks,
Peter Hedlund

-------------- next part --------------
From 3c487cba5a38eac673d8c51bb51329f347bb33c0 Mon Sep 17 00:00:00 2001
From: Peter Hedlund <peter at peterandlinda.com>
Date: Wed, 27 May 2009 10:27:56 -0700
Subject: Mask out obsolete flags in GlobalAlloc()
 With test that passes on wine and WinXP.

Resolves bug 8241.
---
 dlls/kernel32/heap.c       |    3 ++
 dlls/kernel32/tests/heap.c |   51 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 54 insertions(+), 0 deletions(-)

diff --git a/dlls/kernel32/heap.c b/dlls/kernel32/heap.c
index c08fb51..c78c762 100644
--- a/dlls/kernel32/heap.c
+++ b/dlls/kernel32/heap.c
@@ -375,6 +375,9 @@ HGLOBAL WINAPI GlobalAlloc(
       pintern = HeapAlloc(GetProcessHeap(), 0, sizeof(GLOBAL32_INTERN));
       if (pintern)
       {
+          /* Mask out obsolete flags */
+          flags &= ~(GMEM_LOWER | GMEM_NOCOMPACT | GMEM_NOT_BANKED | GMEM_NOTIFY);
+
           pintern->Magic = MAGIC_GLOBAL_USED;
           pintern->Flags = flags >> 8;
           pintern->LockCount = 0;
diff --git a/dlls/kernel32/tests/heap.c b/dlls/kernel32/tests/heap.c
index 39517cc..e51dcc6 100644
--- a/dlls/kernel32/tests/heap.c
+++ b/dlls/kernel32/tests/heap.c
@@ -28,6 +28,25 @@
 
 #define MAGIC_DEAD 0xdeadbeef
 
+typedef struct _TEST_OBSOLETE_FLAGS {
+    UINT flags;
+    UINT globalflags;
+} TEST_OBSOLETE_FLAGS;
+
+static TEST_OBSOLETE_FLAGS TEST_APPLY[] = {
+    {GMEM_FIXED | GMEM_NOTIFY, 0},
+    {GMEM_FIXED | GMEM_DISCARDABLE, 0},
+    {GMEM_MOVEABLE | GMEM_NOTIFY, 0},
+    {GMEM_MOVEABLE | GMEM_SHARE, GMEM_SHARE},
+    {GMEM_MOVEABLE | GMEM_DDESHARE, GMEM_DDESHARE},
+    {GMEM_MOVEABLE | GMEM_NOT_BANKED, 0},
+    {GMEM_MOVEABLE | GMEM_NODISCARD, 0},
+    {GMEM_MOVEABLE | GMEM_DISCARDABLE, GMEM_DISCARDABLE},
+    {GMEM_MOVEABLE | GMEM_DDESHARE | GMEM_DISCARDABLE | GMEM_LOWER | GMEM_NOCOMPACT | GMEM_NODISCARD |
+    GMEM_NOT_BANKED | GMEM_NOTIFY | GMEM_SHARE, GMEM_DDESHARE | GMEM_DISCARDABLE | GMEM_SHARE},
+};
+
+
 static SIZE_T resize_9x(SIZE_T size)
 {
     DWORD dwSizeAligned = (size + 3) & ~3;
@@ -362,9 +381,41 @@ static void test_heap(void)
     GlobalFree(gbl);
 }
 
+static void test_obsolete_flags()
+{
+    unsigned int i;
+    HGLOBAL gbl;
+    UINT resultflags;
+   
+    UINT (WINAPI *pGlobalFlags)(HGLOBAL);
+ 
+    pGlobalFlags = (void *) GetProcAddress(GetModuleHandleA("kernel32"), "GlobalFlags");
+
+    if (!pGlobalFlags)
+    {
+        win_skip("GlobalFlags is not available\n");
+        return; 
+    }
+
+    for (i = 0; i < sizeof(TEST_APPLY)/sizeof(TEST_APPLY[0]); i++) 
+    {
+        gbl = GlobalAlloc(TEST_APPLY[i].flags, 4);
+        ok(gbl != NULL, "GlobalAlloc failed\n");
+   
+        SetLastError(MAGIC_DEAD);
+        resultflags = pGlobalFlags(gbl);
+
+        ok( resultflags == TEST_APPLY[i].globalflags, "expected 0x%08x, but returned 0x%08x with %d \n",
+            TEST_APPLY[i].globalflags, resultflags, GetLastError() );
+
+        GlobalFree(gbl);
+    }
+}
+
 START_TEST(heap)
 {
     test_heap();
+    test_obsolete_flags();
 
     /* Test both short and very long blocks */
     test_sized_HeapAlloc(1);
-- 
1.6.2.2



More information about the wine-patches mailing list