Author: jgardou Date: Wed Oct 10 23:05:38 2012 New Revision: 57535 URL: http://svn.reactos.org/svn/reactos?rev=57535&view=rev Log: [GDI32] - Assume that the provided buffer size is maximal in GetDIBits [WIN32K] - Probe buffer before writing to it - Fail DIB Section creation if palette creation failed
Modified: trunk/reactos/win32ss/gdi/gdi32/objects/bitmap.c trunk/reactos/win32ss/gdi/ntgdi/dibobj.c Modified: trunk/reactos/win32ss/gdi/gdi32/objects/bitmap.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/gdi32/objects/bitmap.c?rev=57535&r1=57534&r2=57535&view=diff ============================================================================== --- trunk/reactos/win32ss/gdi/gdi32/objects/bitmap.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/gdi/gdi32/objects/bitmap.c [iso-8859-1] Wed Oct 10 23:05:38 2012 @@ -13,7 +13,7 @@ * 11/16/1999 (RJJ) lifted from wine */ -INT FASTCALL DIB_BitmapInfoSize(const BITMAPINFO * info, WORD coloruse) +INT FASTCALL DIB_BitmapInfoSize(const BITMAPINFO * info, WORD coloruse, BOOL max) { unsigned int colors, size, masks = 0; @@ -26,7 +26,7 @@ } else /* assume BITMAPINFOHEADER */ { - colors = info->bmiHeader.biClrUsed; + colors = max ? 1 << info->bmiHeader.biBitCount : info->bmiHeader.biClrUsed; if (colors > 256) colors = 256; if (!colors && (info->bmiHeader.biBitCount <= 8)) colors = 1 << info->bmiHeader.biBitCount; @@ -409,7 +409,8 @@ } cjBmpScanSize = DIB_BitmapMaxBitsSize(lpbmi, cScanLines); - cjInfoSize = DIB_BitmapInfoSize(lpbmi, uUsage); + /* Caller must provide maximum size possible */ + cjInfoSize = DIB_BitmapInfoSize(lpbmi, uUsage, TRUE); if ( lpvBits ) { Modified: trunk/reactos/win32ss/gdi/ntgdi/dibobj.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/ntgdi/dibobj.c?rev=57535&r1=57534&r2=57535&view=diff ============================================================================== --- trunk/reactos/win32ss/gdi/ntgdi/dibobj.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/gdi/ntgdi/dibobj.c [iso-8859-1] Wed Oct 10 23:05:38 2012 @@ -1038,7 +1038,7 @@ _SEH2_TRY { /* Probe and copy the BITMAPINFO */ - ProbeForWrite(pbmiUser, cjMaxInfo, 1); + ProbeForRead(pbmiUser, cjMaxInfo, 1); RtlCopyMemory(pbmi, pbmiUser, cjMaxInfo); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) @@ -1082,7 +1082,8 @@ /* Use SEH to copy back to user mode */ _SEH2_TRY { - /* Buffer is already probed, copy the data back */ + /* Copy the data back */ + ProbeForWrite(pbmiUser, cjMaxInfo, 1); RtlCopyMemory(pbmiUser, pbmi, cjMaxInfo); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) @@ -1551,7 +1552,7 @@ HBITMAP res = 0; SURFACE *bmp = NULL; void *mapBits = NULL; - PPALETTE ppalDIB; + PPALETTE ppalDIB = NULL; // Fill BITMAP32 structure with DIB data CONST BITMAPINFOHEADER *bi = &bmi->bmiHeader; @@ -1685,15 +1686,10 @@ /* Create a palette for the DIB */ ppalDIB = CreateDIBPalette(bmi, dc, usage); - if (ppalDIB) - { - SURFACE_vSetPalette(bmp, ppalDIB); - PALETTE_ShareUnlockPalette(ppalDIB); - } // Clean up in case of errors cleanup: - if (!res || !bmp || !bm.bmBits) + if (!res || !bmp || !bm.bmBits || !ppalDIB) { DPRINT("Got an error res=%p, bmp=%p, bm.bmBits=%p\n", res, bmp, bm.bmBits); if (bm.bmBits) @@ -1709,17 +1705,28 @@ } if (bmp) + { + SURFACE_ShareUnlockSurface(bmp); bmp = NULL; + } if (res) { GreDeleteObject(res); res = 0; } + + if(ppalDIB) + { + PALETTE_ShareUnlockPalette(ppalDIB); + } } if (bmp) { + /* If we're here, everything went fine */ + SURFACE_vSetPalette(bmp, ppalDIB); + PALETTE_ShareUnlockPalette(ppalDIB); SURFACE_ShareUnlockSurface(bmp); }