Jacek Caban : gdi32: Initialize GdiSharedHandleTable in PEB.

Alexandre Julliard julliard at winehq.org
Thu Jul 1 15:53:49 CDT 2021


Module: wine
Branch: master
Commit: e82332f2b24b16d4c320a8bd924ed90bab5ded3a
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=e82332f2b24b16d4c320a8bd924ed90bab5ded3a

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Wed Jun 30 17:38:00 2021 +0200

gdi32: Initialize GdiSharedHandleTable in PEB.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Huw Davies <huw at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/gdi32/gdiobj.c       | 16 ++++++++++++
 dlls/gdi32/tests/gdiobj.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 77 insertions(+), 1 deletion(-)

diff --git a/dlls/gdi32/gdiobj.c b/dlls/gdi32/gdiobj.c
index d0c1f0c8230..b0fad2660ee 100644
--- a/dlls/gdi32/gdiobj.c
+++ b/dlls/gdi32/gdiobj.c
@@ -598,6 +598,21 @@ static HFONT create_scaled_font( const LOGFONTW *deffont )
     return CreateFontIndirectW( &lf );
 }
 
+static void set_gdi_shared(void)
+{
+#ifndef _WIN64
+    if (NtCurrentTeb()->GdiBatchCount)
+    {
+        TEB64 *teb64 = (TEB64 *)(UINT_PTR)NtCurrentTeb()->GdiBatchCount;
+        PEB64 *peb64 = (PEB64 *)(UINT_PTR)teb64->Peb;
+        peb64->GdiSharedHandleTable = (UINT_PTR)&gdi_shared;
+        return;
+    }
+#endif
+    /* NOTE: Windows uses 32-bit for 32-bit kernel */
+    NtCurrentTeb()->Peb->GdiSharedHandleTable = &gdi_shared;
+}
+
 /***********************************************************************
  *           DllMain
  *
@@ -612,6 +627,7 @@ BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved )
 
     gdi32_module = inst;
     DisableThreadLibraryCalls( inst );
+    set_gdi_shared();
     font_init();
 
     /* create stock objects */
diff --git a/dlls/gdi32/tests/gdiobj.c b/dlls/gdi32/tests/gdiobj.c
index 8f3d01c27df..80c8b284c62 100644
--- a/dlls/gdi32/tests/gdiobj.c
+++ b/dlls/gdi32/tests/gdiobj.c
@@ -24,11 +24,14 @@
 
 #include "windef.h"
 #include "winbase.h"
-#include "wingdi.h"
+#include "ntgdi.h"
 #include "winuser.h"
+#include "winternl.h"
 
 #include "wine/test.h"
 
+static BOOL is_wow64;
+
 static void test_gdi_objects(void)
 {
     BYTE buff[256];
@@ -362,11 +365,68 @@ static void test_handles_on_win64(void)
     }
 }
 
+static GDI_SHARED_MEMORY *get_gdi_shared(void)
+{
+#ifndef _WIN64
+    if (NtCurrentTeb()->GdiBatchCount)
+    {
+        TEB64 *teb64 = (TEB64 *)(UINT_PTR)NtCurrentTeb()->GdiBatchCount;
+        PEB64 *peb64 = (PEB64 *)(UINT_PTR)teb64->Peb;
+        return (GDI_SHARED_MEMORY *)(UINT_PTR)peb64->GdiSharedHandleTable;
+    }
+#endif
+    return (GDI_SHARED_MEMORY *)NtCurrentTeb()->Peb->GdiSharedHandleTable;
+}
+
+static void test_shared_handle_table(void)
+{
+    GDI_SHARED_MEMORY *gdi_shared;
+    GDI_HANDLE_ENTRY *entry;
+    unsigned int handle;
+    HRGN hrgn;
+
+    if (sizeof(void *) == 4 && !is_wow64)
+    {
+        skip("Skipping shared memory tests on 32-bit Windows\n");
+        return;
+    }
+    gdi_shared = get_gdi_shared();
+
+    hrgn = CreateRectRgn(10, 10, 20, 20);
+    ok(hrgn != 0, "CreateRectRgn failed\n");
+
+    handle = (UINT_PTR)hrgn;
+    entry = &gdi_shared->Handles[handle & 0xffff];
+    ok(entry->Unique == handle >> 16, "Unique = %x, expected %x\n",
+       entry->Unique, handle >> 16);
+    todo_wine
+    ok(entry->Type == 4, "Type = %x\n", entry->Type);
+    ok(entry->Object, "Object = NULL\n");
+    todo_wine
+    ok(entry->Owner.ProcessId == GetCurrentProcessId(), "ProcessId = %x, expected %x\n",
+       entry->Owner.ProcessId, GetCurrentProcessId());
+    ok(entry->Owner.Count == 0, "Count = %u\n", entry->Owner.Count);
+
+    DeleteObject(hrgn);
+    ok(entry->Unique == handle >> 16, "Unique = %x, expected %x\n",
+       entry->Unique, handle >> 16);
+    todo_wine
+    ok(entry->Type == 4, "Type = %x\n", entry->Type);
+    ok(entry->Object, "Object = NULL\n");
+    todo_wine
+    ok(entry->Owner.ProcessId == GetCurrentProcessId(), "ProcessId = %x, expected %x\n",
+       entry->Owner.ProcessId, GetCurrentProcessId());
+    ok(entry->Owner.Count == 0, "Count = %u\n", entry->Owner.Count);
+}
+
 START_TEST(gdiobj)
 {
+    if (!IsWow64Process( GetCurrentProcess(), &is_wow64 )) is_wow64 = FALSE;
+
     test_gdi_objects();
     test_thread_objects();
     test_GetCurrentObject();
     test_region();
     test_handles_on_win64();
+    test_shared_handle_table();
 }




More information about the wine-cvs mailing list