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