diff --git a/dlls/gdi32/bitmap.c b/dlls/gdi32/bitmap.c index c16793d82b..0ae5b20052 100644 --- a/dlls/gdi32/bitmap.c +++ b/dlls/gdi32/bitmap.c @@ -145,6 +145,8 @@ HBITMAP WINAPI CreateBitmapIndirect( const BITMAP *bmp ) BITMAP bm; BITMAPOBJ *bmpobj; HBITMAP hbitmap; + INT dib_stride; + SIZE_T size; if (!bmp || bmp->bmType) { @@ -194,10 +196,13 @@ HBITMAP WINAPI CreateBitmapIndirect( const BITMAP *bmp ) /* Windows ignores the provided bm.bmWidthBytes */ bm.bmWidthBytes = get_bitmap_stride( bm.bmWidth, bm.bmBitsPixel ); - /* XP doesn't allow creating bitmaps larger than 128 MB */ - if (bm.bmHeight > 128 * 1024 * 1024 / bm.bmWidthBytes) + + dib_stride = get_dib_stride( bm.bmWidth, bm.bmBitsPixel ); + size = dib_stride * bm.bmHeight; + /* Check for overflow (dib_stride itself must be ok because of the constraint on bm.bmWidth above). */ + if (dib_stride != size / bm.bmHeight) { - SetLastError( ERROR_NOT_ENOUGH_MEMORY ); + SetLastError( ERROR_INVALID_PARAMETER ); return 0; } @@ -209,10 +214,17 @@ HBITMAP WINAPI CreateBitmapIndirect( const BITMAP *bmp ) } bmpobj->dib.dsBm = bm; - bmpobj->dib.dsBm.bmBits = NULL; + bmpobj->dib.dsBm.bmBits = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, size ); + if (!bmpobj->dib.dsBm.bmBits) + { + HeapFree( GetProcessHeap(), 0, bmpobj ); + SetLastError( ERROR_NOT_ENOUGH_MEMORY ); + return 0; + } if (!(hbitmap = alloc_gdi_handle( bmpobj, OBJ_BITMAP, &bitmap_funcs ))) { + HeapFree( GetProcessHeap(), 0, bmpobj->dib.dsBm.bmBits ); HeapFree( GetProcessHeap(), 0, bmpobj ); return 0; } diff --git a/dlls/gdi32/dibdrv/dc.c b/dlls/gdi32/dibdrv/dc.c index aee305fda8..2447093921 100644 --- a/dlls/gdi32/dibdrv/dc.c +++ b/dlls/gdi32/dibdrv/dc.c @@ -168,13 +168,6 @@ BOOL init_dib_info_from_bitmapobj(dib_info *dib, BITMAPOBJ *bmp) BITMAPINFO info; get_ddb_bitmapinfo( bmp, &info ); - if (!bmp->dib.dsBm.bmBits) - { - int width_bytes = get_dib_stride( bmp->dib.dsBm.bmWidth, bmp->dib.dsBm.bmBitsPixel ); - bmp->dib.dsBm.bmBits = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, - bmp->dib.dsBm.bmHeight * width_bytes ); - if (!bmp->dib.dsBm.bmBits) return FALSE; - } init_dib_info_from_bitmapinfo( dib, &info, bmp->dib.dsBm.bmBits ); } else init_dib_info( dib, &bmp->dib.dsBmih, bmp->dib.dsBm.bmWidthBytes,