From 29795a2d72337259bc87f77422c24e73f5fea545 Mon Sep 17 00:00:00 2001 From: Katayama Hirofumi MZ Date: Sun, 27 Jan 2019 15:51:33 +0900 Subject: [PATCH] [WIN32SS][NTGDI] Improve UnsafeGetBitmapBits and NtGdiGetBitmapBits (#1308) CORE-15657 --- win32ss/gdi/ntgdi/bitmaps.c | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/win32ss/gdi/ntgdi/bitmaps.c b/win32ss/gdi/ntgdi/bitmaps.c index c0c587482a8..e003640e9ee 100644 --- a/win32ss/gdi/ntgdi/bitmaps.c +++ b/win32ss/gdi/ntgdi/bitmaps.c @@ -496,7 +496,7 @@ NtGdiGetBitmapDimension( } -VOID +LONG FASTCALL UnsafeGetBitmapBits( PSURFACE psurf, @@ -505,10 +505,10 @@ UnsafeGetBitmapBits( { PUCHAR pjDst, pjSrc; LONG lDeltaDst, lDeltaSrc; - ULONG nWidth, nHeight, cBitsPixel; + ULONG Y, iSrc, iDst, cbSrc, cbDst, nWidth, nHeight, cBitsPixel; nWidth = psurf->SurfObj.sizlBitmap.cx; - nHeight = psurf->SurfObj.sizlBitmap.cy; + nHeight = labs(psurf->SurfObj.sizlBitmap.cy); cBitsPixel = BitsPerFormat(psurf->SurfObj.iBitmapFormat); /* Get pointers */ @@ -516,14 +516,33 @@ UnsafeGetBitmapBits( pjDst = pvBits; lDeltaSrc = psurf->SurfObj.lDelta; lDeltaDst = WIDTH_BYTES_ALIGN16(nWidth, cBitsPixel); + NT_ASSERT(labs(lDeltaSrc) >= lDeltaDst); - while (nHeight--) + cbSrc = nHeight * labs(lDeltaSrc); + cbDst = nHeight * lDeltaDst; + Bytes = min(Bytes, cbDst); + + iSrc = iDst = 0; + for (Y = 0; Y < nHeight; Y++) { + if (iSrc + labs(lDeltaSrc) > cbSrc || iDst + lDeltaDst > Bytes) + { + LONG lDelta = min(cbSrc - iSrc, Bytes - iDst); + NT_ASSERT(lDelta >= 0); + RtlCopyMemory(pjDst, pjSrc, lDelta); + iDst += lDelta; + break; + } + /* Copy one line */ RtlCopyMemory(pjDst, pjSrc, lDeltaDst); pjSrc += lDeltaSrc; pjDst += lDeltaDst; + iSrc += labs(lDeltaSrc); + iDst += lDeltaDst; } + + return iDst; } LONG @@ -570,8 +589,7 @@ NtGdiGetBitmapBits( _SEH2_TRY { ProbeForWrite(pUnsafeBits, cjBuffer, 1); - UnsafeGetBitmapBits(psurf, cjBuffer, pUnsafeBits); - ret = cjBuffer; + ret = UnsafeGetBitmapBits(psurf, cjBuffer, pUnsafeBits); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {