Jacek Caban : wow64win: Handle bitmaps and pens in wow64_NtGdiExtGetObjectW.

Alexandre Julliard julliard at winehq.org
Sat Aug 13 14:19:16 CDT 2022


Module: wine
Branch: master
Commit: c3c82bd96a399c90f548639ce8f879a4b0c5c601
URL:    https://gitlab.winehq.org/wine/wine/-/commit/c3c82bd96a399c90f548639ce8f879a4b0c5c601

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Fri Aug 12 15:17:24 2022 +0200

wow64win: Handle bitmaps and pens in wow64_NtGdiExtGetObjectW.

---

 dlls/wow64win/gdi.c | 115 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 114 insertions(+), 1 deletion(-)

diff --git a/dlls/wow64win/gdi.c b/dlls/wow64win/gdi.c
index 4d98a1b9b13..f13ed3da1f0 100644
--- a/dlls/wow64win/gdi.c
+++ b/dlls/wow64win/gdi.c
@@ -27,6 +27,35 @@
 #include "ntgdi.h"
 #include "wow64win_private.h"
 
+typedef struct
+{
+    INT   bmType;
+    INT   bmWidth;
+    INT   bmHeight;
+    INT   bmWidthBytes;
+    WORD  bmPlanes;
+    WORD  bmBitsPixel;
+    ULONG bmBits;
+} BITMAP32;
+
+typedef struct
+{
+    DWORD    elpPenStyle;
+    DWORD    elpWidth;
+    UINT     elpBrushStyle;
+    COLORREF elpColor;
+    ULONG    elpHatch;
+    DWORD    elpNumEntries;
+    DWORD    elpStyleEntry[1];
+} EXTLOGPEN32;
+
+
+static DWORD gdi_handle_type( HGDIOBJ obj )
+{
+    unsigned int handle = HandleToUlong( obj );
+    return handle & NTGDI_HANDLE_TYPE_MASK;
+}
+
 NTSTATUS WINAPI wow64_NtGdiAddFontMemResourceEx( UINT *args )
 {
     void *ptr = get_ptr( &args );
@@ -334,7 +363,91 @@ NTSTATUS WINAPI wow64_NtGdiExtGetObjectW( UINT *args )
     INT count = get_ulong( &args );
     void *buffer = get_ptr( &args );
 
-    return NtGdiExtGetObjectW( handle, count, buffer );
+    switch (gdi_handle_type( handle ))
+    {
+    case NTGDI_OBJ_BITMAP:
+        {
+            BITMAP32 *bitmap32 = buffer;
+            struct
+            {
+                BITMAP32 dsBm;
+                BITMAPINFOHEADER dsBmih;
+                DWORD  dsBitfields[3];
+                ULONG  dshSection;
+                DWORD  dsOffset;
+            } *dib32 = buffer;
+            DIBSECTION dib;
+            int ret;
+
+            if (buffer)
+            {
+                if (count < sizeof(*bitmap32)) return 0;
+                count = count < sizeof(*dib32) ? sizeof(BITMAP) : sizeof(DIBSECTION);
+            }
+
+            if (!(ret = NtGdiExtGetObjectW( handle, count, buffer ? &dib : NULL ))) return 0;
+
+            if (bitmap32)
+            {
+                bitmap32->bmType = dib.dsBm.bmType;
+                bitmap32->bmWidth = dib.dsBm.bmWidth;
+                bitmap32->bmHeight = dib.dsBm.bmHeight;
+                bitmap32->bmWidthBytes = dib.dsBm.bmWidthBytes;
+                bitmap32->bmPlanes = dib.dsBm.bmPlanes;
+                bitmap32->bmBitsPixel = dib.dsBm.bmBitsPixel;
+                bitmap32->bmBits = PtrToUlong( dib.dsBm.bmBits );
+            }
+            if (ret != sizeof(dib)) return sizeof(*bitmap32);
+
+            if (dib32)
+            {
+                dib32->dsBmih = dib.dsBmih;
+                dib32->dsBitfields[0] = dib.dsBitfields[0];
+                dib32->dsBitfields[1] = dib.dsBitfields[1];
+                dib32->dsBitfields[2] = dib.dsBitfields[2];
+                dib32->dshSection = HandleToUlong( dib.dshSection );
+                dib32->dsOffset = dib.dsOffset;
+            }
+            return sizeof(*dib32);
+        }
+
+    case NTGDI_OBJ_PEN:
+    case NTGDI_OBJ_EXTPEN:
+        {
+            EXTLOGPEN32 *pen32 = buffer;
+            EXTLOGPEN *pen = NULL;
+
+            if (count == sizeof(LOGPEN) || (buffer && !HIWORD( buffer )))
+                return NtGdiExtGetObjectW( handle, count, buffer );
+
+            if (pen32 && count && !(pen = Wow64AllocateTemp( count + sizeof(ULONG) ))) return 0;
+            count = NtGdiExtGetObjectW( handle, count + sizeof(ULONG), pen );
+
+            if (count == sizeof(LOGPEN))
+            {
+                if (buffer) memcpy( buffer, pen, count );
+            }
+            else if (count)
+            {
+                if (pen32)
+                {
+                    pen32->elpPenStyle = pen->elpPenStyle;
+                    pen32->elpWidth = pen->elpWidth;
+                    pen32->elpBrushStyle = pen->elpBrushStyle;
+                    pen32->elpColor = pen->elpColor;
+                    pen32->elpHatch = pen->elpHatch;
+                    pen32->elpNumEntries = pen->elpNumEntries;
+                }
+                count -= FIELD_OFFSET( EXTLOGPEN, elpStyleEntry );
+                if (count && pen32) memcpy( pen32->elpStyleEntry, pen->elpStyleEntry, count );
+                count += FIELD_OFFSET( EXTLOGPEN32, elpStyleEntry );
+            }
+            return count;
+        }
+
+    default:
+        return NtGdiExtGetObjectW( handle, count, buffer );
+    }
 }
 
 NTSTATUS WINAPI wow64_NtGdiFlattenPath( UINT *args )




More information about the wine-cvs mailing list