diff --git "a/win32ss/gdi/gdi32/objects/bitmap.c" "b/win32ss/gdi/gdi32/objects/bitmap.c" index b029d4ad2df..4f8d20d0db3 100644 --- "a/win32ss/gdi/gdi32/objects/bitmap.c" +++ "b/win32ss/gdi/gdi32/objects/bitmap.c" @@ -667,6 +667,9 @@ SetDIBitsToDevice( BOOL Hit = FALSE; PVOID pvSafeBits = (PVOID) Bits; + #define aligned(Address, Count) \ + (((ULONG_PTR)(void *)(Address)) % (Count) == 0) + if (!ScanLines || !lpbmi || !Bits) return 0; @@ -677,6 +680,46 @@ SetDIBitsToDevice( if (!pConvertedInfo) return 0; + if (!aligned(Bits, 4) && (ScanLines > Height)) + { + return 0; + } + + /* Below code modeled after Wine's nulldrv_SetDIBitsToDevice */ + if (StartScan <= YSrc + abs(pConvertedInfo->bmiHeader.biHeight)) + { + UINT src_y = 0; + BOOL top_down; + UINT bmiHeight = 0; + + top_down = (pConvertedInfo->bmiHeader.biHeight < 0); + bmiHeight = abs(pConvertedInfo->bmiHeader.biHeight); + + if ((pConvertedInfo->bmiHeader.biCompression == BI_RLE8) || + (pConvertedInfo->bmiHeader.biCompression == BI_RLE4)) + { + StartScan = 0; + ScanLines = bmiHeight; + } + else + { + if (StartScan >= bmiHeight) return 0; + if (!top_down && ScanLines > bmiHeight - StartScan) ScanLines = bmiHeight - StartScan; + src_y = StartScan + ScanLines - (YSrc + Height); + if (src_y > 0) // True + { + if (!top_down) + { + /* get rid of unnecessary lines */ + if (src_y >= ScanLines) return 0; + ScanLines -= src_y; // 8 - 1 + } + else if (src_y >= ScanLines) return ScanLines; + } + LinesCopied = ScanLines; + } + } + HANDLE_METADC(INT, SetDIBitsToDevice, 0,