diff --git a/win32ss/gdi/gdi32/objects/bitmap.c b/win32ss/gdi/gdi32/objects/bitmap.c index 438521f69e9..ce906612094 100644 --- a/win32ss/gdi/gdi32/objects/bitmap.c +++ b/win32ss/gdi/gdi32/objects/bitmap.c @@ -666,6 +666,7 @@ SetDIBitsToDevice( UINT cjBmpScanSize = 0; BOOL Hit = FALSE; PVOID pvSafeBits = (PVOID) Bits; + UINT NewScanLines; if (!ScanLines || !lpbmi || !Bits) return 0; @@ -742,14 +743,35 @@ SetDIBitsToDevice( { Hit = TRUE; } - _SEH2_END + _SEH2_END; + + /* The caller might be sending "just enough" data. Setting ScanLines as Height */ + NewScanLines = ScanLines; + if (ScanLines != Height) + { + NewScanLines = Height; + cjBmpScanSize = DIB_BitmapMaxBitsSize((LPBITMAPINFO) lpbmi, Height); + } if (Hit) { // We don't die, we continue on with a allocated safe pointer to kernel // space..... - DPRINT1("SetDIBitsToDevice fail to read BitMapInfo: %p or Bits: %p & Size: %u\n", - pConvertedInfo, Bits, cjBmpScanSize); + + DPRINT1("SetDIBitsToDevice fail to read BitMapInfo: %p or Bits: %p & Size: %u Height: %u ScanLines: %u.\n", + pConvertedInfo, Bits, cjBmpScanSize, Height, ScanLines); + Hit = FALSE; + _SEH2_TRY + { + RtlCopyMemory(pvSafeBits, Bits, cjBmpScanSize); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + Hit = TRUE; + } + _SEH2_END; + if (Hit) + DPRINT("SetDIBitsToDevice second fail.\n"); } DPRINT("SetDIBitsToDevice Allocate Bits %u!!!\n", cjBmpScanSize); } @@ -767,7 +789,7 @@ SetDIBitsToDevice( pConvertedInfo->bmiHeader.biCompression == BI_PNG )) )*/ { LinesCopied = NtGdiSetDIBitsToDeviceInternal(hdc, XDest, YDest, Width, Height, XSrc, YSrc, - StartScan, ScanLines, (LPBYTE) pvSafeBits, (LPBITMAPINFO) pConvertedInfo, ColorUse, + StartScan, NewScanLines, (LPBYTE) pvSafeBits, (LPBITMAPINFO) pConvertedInfo, ColorUse, cjBmpScanSize, ConvertedInfoSize, TRUE, NULL); @@ -778,6 +800,10 @@ Exit: if (lpbmi != pConvertedInfo) RtlFreeHeap(RtlGetProcessHeap(), 0, pConvertedInfo); + if ((ScanLines != Height) && (LinesCopied != 0)) + { + LinesCopied = ScanLines; + } return LinesCopied; }