Module: wine Branch: master Commit: e33bdb87493ce2a55ec5e2a0884074d0ca7e26ea URL: https://source.winehq.org/git/wine.git/?a=commit;h=e33bdb87493ce2a55ec5e2a08...
Author: Jacek Caban jacek@codeweavers.com Date: Fri Jul 9 15:28:51 2021 +0200
gdi32: Use NtGdiCreateClientObj for enhmetafile objects.
Signed-off-by: Jacek Caban jacek@codeweavers.com Signed-off-by: Huw Davies huw@codeweavers.com Signed-off-by: Alexandre Julliard julliard@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)