From: Jacek Caban jacek@codeweavers.com
--- 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 )