Index: win32ss/gdi/eng/bitblt.c =================================================================== --- win32ss/gdi/eng/bitblt.c (revision 66366) +++ win32ss/gdi/eng/bitblt.c (working copy) @@ -1078,6 +1078,7 @@ psoDest->iBitmapFormat, 0, 0, + 0, NULL); if (psurfTemp == NULL) { Index: win32ss/gdi/eng/surface.c =================================================================== --- win32ss/gdi/eng/surface.c (revision 66366) +++ win32ss/gdi/eng/surface.c (working copy) @@ -120,6 +120,7 @@ _In_ ULONG iFormat, _In_ ULONG fjBitmap, _In_opt_ ULONG cjWidth, + _In_opt_ ULONG cjBufSize, _In_opt_ PVOID pvBits) { ULONG cBitsPixel, cjBits, cjObject; @@ -127,7 +128,8 @@ SURFOBJ *pso; PVOID pvSection; - ASSERT(!pvBits || (iType == STYPE_BITMAP)); + NT_ASSERT(!pvBits || (iType == STYPE_BITMAP)); + NT_ASSERT((iFormat <= BMF_32BPP) || (cjBufSize != 0)); /* Verify format */ if ((iFormat < BMF_1BPP) || (iFormat > BMF_PNG)) @@ -151,9 +153,36 @@ cjWidth = WIDTH_BYTES_ALIGN32(cx, cBitsPixel); } - /* Calculate the bitmap size in bytes */ - cjBits = cjWidth * cy; + /* Is this an uncompressed format? */ + if (iFormat <= BMF_32BPP) + { + /* Calculate the correct bitmap size in bytes */ + if (!NT_SUCCESS(RtlULongMult(cjWidth, cy, &cjBits))) + { + DPRINT1("Overflow calculating size: cjWidth %lu, cy %lu\n", + cjWidth, cy); + return NULL; + } + /* Did we get a buffer and size? */ + if ((pvBits != NULL) && (cjBufSize != 0)) + { + /* Make sure the buffer is large enough */ + if (cjBufSize < cjBits) + { + DPRINT1("Buffer is too small, required: %lu, got %lu\n", + cjBits, cjBits); + return NULL; + } + } + } + else + { + /* Compressed format, use the provided size */ + NT_ASSERT(cjBufSize != 0); + cjBits = cjBufSize; + } + /* Check if we need an extra large object */ if ((iType == STYPE_BITMAP) && (pvBits == NULL) && !(fjBitmap & BMF_USERMEM) && !(fjBitmap & BMF_KMSECTION)) @@ -168,9 +197,10 @@ } /* Check for arithmetic overflow */ - if ((cjBits < cjWidth) || (cjObject < sizeof(SURFACE))) + if (cjObject < sizeof(SURFACE)) { /* Fail! */ + DPRINT1("Overflow calculating cjObject: cjBits %lu\n", cjBits); return NULL; } @@ -289,6 +319,7 @@ iFormat, fl, lWidth, + 0, pvBits); if (!psurf) { @@ -327,6 +358,7 @@ iFormat, 0, 0, + 0, NULL); if (!psurf) { @@ -365,6 +397,7 @@ iFormat, 0, 0, + 0, NULL); if (!psurf) { Index: win32ss/gdi/eng/surface.h =================================================================== --- win32ss/gdi/eng/surface.h (revision 66366) +++ win32ss/gdi/eng/surface.h (working copy) @@ -123,6 +123,7 @@ _In_ ULONG iFormat, _In_ ULONG fjBitmap, _In_opt_ ULONG cjWidth, + _In_opt_ ULONG cjBits, _In_opt_ PVOID pvBits); FORCEINLINE Index: win32ss/gdi/ntgdi/bitblt.c =================================================================== --- win32ss/gdi/ntgdi/bitblt.c (revision 66366) +++ win32ss/gdi/ntgdi/bitblt.c (working copy) @@ -1453,6 +1453,7 @@ BMF_32BPP, 0, 0, + 0, &ulRGBColor); if (psurfDest) { Index: win32ss/gdi/ntgdi/bitmaps.c =================================================================== --- win32ss/gdi/ntgdi/bitmaps.c (revision 66366) +++ win32ss/gdi/ntgdi/bitmaps.c (working copy) @@ -72,6 +72,7 @@ pvCompressedBits = pvBits; pvBits = NULL; iFormat = (iFormat == BMF_4RLE) ? BMF_4BPP : BMF_8BPP; + cjSizeImage = 0; } /* Allocate a surface */ @@ -81,6 +82,7 @@ iFormat, fjBitmap, cjWidthBytes, + cjSizeImage, pvBits); if (!psurf) { @@ -176,6 +178,7 @@ iFormat, 0, 0, + 0, NULL); if (!psurf) { Index: win32ss/gdi/ntgdi/dibobj.c =================================================================== --- win32ss/gdi/ntgdi/dibobj.c (revision 66366) +++ win32ss/gdi/ntgdi/dibobj.c (working copy) @@ -1090,7 +1090,7 @@ _SEH2_TRY { /* Copy the data back */ - cjMaxInfo = min(cjMaxInfo, DIB_BitmapInfoSize(pbmi, (WORD)iUsage)); + cjMaxInfo = min(cjMaxInfo, (UINT)DIB_BitmapInfoSize(pbmi, (WORD)iUsage)); ProbeForWrite(pbmiUser, cjMaxInfo, 1); RtlCopyMemory(pbmiUser, pbmi, cjMaxInfo); } Index: win32ss/pch.h =================================================================== --- win32ss/pch.h (revision 66366) +++ win32ss/pch.h (working copy) @@ -26,6 +26,7 @@ #include #include #include +#include #include /* Win32 headers */