Jacek Caban : gdi32: Use NtGdiCreateClientObj for enhmetafile objects.

Alexandre Julliard julliard at winehq.org
Fri Jul 9 16:45:34 CDT 2021


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Fri Jul  9 15:28:51 2021 +0200

gdi32: Use NtGdiCreateClientObj for enhmetafile objects.

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/enhmetafile.c    | 49 +++++++++++++++++++++++++++++++++------------
 dlls/gdi32/tests/metafile.c | 10 +++++++++
 2 files changed, 46 insertions(+), 13 deletions(-)

diff --git a/dlls/gdi32/enhmetafile.c b/dlls/gdi32/enhmetafile.c
index 75db4cb24fb..1053a2ea104 100644
--- a/dlls/gdi32/enhmetafile.c
+++ b/dlls/gdi32/enhmetafile.c
@@ -41,13 +41,23 @@
 #include "winnls.h"
 #include "winerror.h"
 #include "ntgdi_private.h"
+#include "gdi_private.h"
 #include "wine/debug.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(enhmetafile);
 
+
+static CRITICAL_SECTION enhmetafile_cs;
+static CRITICAL_SECTION_DEBUG critsect_debug =
+{
+    0, 0, &enhmetafile_cs,
+    { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
+      0, 0, { (DWORD_PTR)(__FILE__ ": enhmetafile_cs") }
+};
+static CRITICAL_SECTION enhmetafile_cs = { &critsect_debug, -1, 0, 0, 0, 0 };
+
 typedef struct
 {
-    struct gdi_obj_header obj;
     ENHMETAHEADER        *emh;
     BOOL                  on_disk;   /* true if metafile is on disk */
 } ENHMETAFILEOBJ;
@@ -277,7 +287,9 @@ HENHMETAFILE EMF_Create_HENHMETAFILE(ENHMETAHEADER *emh, DWORD filesize, BOOL on
     metaObj->emh = emh;
     metaObj->on_disk = on_disk;
 
-    if (!(hmf = alloc_gdi_handle( &metaObj->obj, NTGDI_OBJ_ENHMETAFILE, NULL )))
+    if ((hmf = NtGdiCreateClientObj( NTGDI_OBJ_ENHMETAFILE )))
+        set_gdi_client_ptr( hmf, metaObj );
+    else
         HeapFree( GetProcessHeap(), 0, metaObj );
     return hmf;
 }
@@ -287,15 +299,23 @@ HENHMETAFILE EMF_Create_HENHMETAFILE(ENHMETAHEADER *emh, DWORD filesize, BOOL on
  */
 static BOOL EMF_Delete_HENHMETAFILE( HENHMETAFILE hmf )
 {
-    ENHMETAFILEOBJ *metaObj = free_gdi_handle( hmf );
+    ENHMETAFILEOBJ *metafile;
 
-    if(!metaObj) return FALSE;
+    EnterCriticalSection( &enhmetafile_cs );
+    if (!(metafile = get_gdi_client_ptr( hmf, NTGDI_OBJ_ENHMETAFILE )) ||
+        !NtGdiDeleteClientObj( hmf ))
+    {
+        LeaveCriticalSection( &enhmetafile_cs );
+        SetLastError( ERROR_INVALID_HANDLE );
+        return FALSE;
+    }
 
-    if(metaObj->on_disk)
-        UnmapViewOfFile( metaObj->emh );
+    if (metafile->on_disk)
+        UnmapViewOfFile( metafile->emh );
     else
-        HeapFree( GetProcessHeap(), 0, metaObj->emh );
-    HeapFree( GetProcessHeap(), 0, metaObj );
+        HeapFree( GetProcessHeap(), 0, metafile->emh );
+    HeapFree( GetProcessHeap(), 0, metafile );
+    LeaveCriticalSection( &enhmetafile_cs );
     return TRUE;
 }
 
@@ -307,13 +327,16 @@ static BOOL EMF_Delete_HENHMETAFILE( HENHMETAFILE hmf )
 static ENHMETAHEADER *EMF_GetEnhMetaHeader( HENHMETAFILE hmf )
 {
     ENHMETAHEADER *ret = NULL;
-    ENHMETAFILEOBJ *metaObj = GDI_GetObjPtr( hmf, NTGDI_OBJ_ENHMETAFILE );
-    TRACE("hmf %p -> enhmetaObj %p\n", hmf, metaObj);
-    if (metaObj)
+    ENHMETAFILEOBJ *metafile;
+
+    EnterCriticalSection( &enhmetafile_cs );
+    if ((metafile = get_gdi_client_ptr( hmf, NTGDI_OBJ_ENHMETAFILE )))
     {
-        ret = metaObj->emh;
-        GDI_ReleaseObj( hmf );
+        TRACE( "hmf %p -> enhmetafile %p\n", hmf, metafile );
+        ret = metafile->emh;
     }
+    else SetLastError( ERROR_INVALID_HANDLE );
+    LeaveCriticalSection( &enhmetafile_cs );
     return ret;
 }
 
diff --git a/dlls/gdi32/tests/metafile.c b/dlls/gdi32/tests/metafile.c
index 10c99304c74..574ccc3d98f 100644
--- a/dlls/gdi32/tests/metafile.c
+++ b/dlls/gdi32/tests/metafile.c
@@ -3137,6 +3137,16 @@ static void test_enhmetafile_file(void)
 
     ret = DeleteFileA(mf_name);
     ok(ret, "Could not delete file: %u\n", GetLastError());
+
+    SetLastError(0xdeadbeef);
+    ret = DeleteEnhMetaFile(ULongToHandle(0xdeadbeef));
+    ok(!ret, "DeleteEnhMetaFile succeeded\n");
+    ok(GetLastError() == ERROR_INVALID_HANDLE, "GetLastError() = %u\n", GetLastError());
+
+    SetLastError(0xdeadbeef);
+    size = GetEnhMetaFileBits(ULongToHandle(0xdeadbeef), 0, NULL);
+    ok(!size, "GetEnhMetaFileBitsEx returned %u\n", size);
+    ok(GetLastError() == ERROR_INVALID_HANDLE, "GetLastError() = %u\n", GetLastError());
 }
 
 static void test_CopyMetaFile(void)




More information about the wine-cvs mailing list