gdi32: Do not allow to create too large device dependent bitmaps like Windows does.
This commit is contained in:
parent
4111ea931c
commit
d5456de058
|
@ -136,79 +136,71 @@ HBITMAP WINAPI CreateCompatibleBitmap( HDC hdc, INT width, INT height)
|
||||||
|
|
||||||
TRACE("(%p,%d,%d) =\n", hdc, width, height);
|
TRACE("(%p,%d,%d) =\n", hdc, width, height);
|
||||||
|
|
||||||
if ((width >= 0x10000) || (height >= 0x10000))
|
if (!(dc = DC_GetDCPtr(hdc))) return 0;
|
||||||
{
|
|
||||||
FIXME("got bad width %d or height %d, please look for reason\n",
|
|
||||||
width, height);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!(dc = DC_GetDCPtr(hdc))) return 0;
|
|
||||||
|
|
||||||
if (GDIMAGIC( dc->header.wMagic ) != MEMORY_DC_MAGIC)
|
if (GDIMAGIC( dc->header.wMagic ) != MEMORY_DC_MAGIC)
|
||||||
|
{
|
||||||
|
hbmpRet = CreateBitmap(width, height,
|
||||||
|
GetDeviceCaps(hdc, PLANES),
|
||||||
|
GetDeviceCaps(hdc, BITSPIXEL),
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
else /* Memory DC */
|
||||||
|
{
|
||||||
|
BITMAPOBJ *bmp = GDI_GetObjPtr( dc->hBitmap, BITMAP_MAGIC );
|
||||||
|
|
||||||
|
if (!bmp->dib)
|
||||||
{
|
{
|
||||||
|
/* A device-dependent bitmap is selected in the DC */
|
||||||
hbmpRet = CreateBitmap(width, height,
|
hbmpRet = CreateBitmap(width, height,
|
||||||
GetDeviceCaps(hdc, PLANES),
|
bmp->bitmap.bmPlanes,
|
||||||
GetDeviceCaps(hdc, BITSPIXEL),
|
bmp->bitmap.bmBitsPixel,
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
else /* Memory DC */
|
else
|
||||||
{
|
{
|
||||||
BITMAPOBJ *bmp = GDI_GetObjPtr( dc->hBitmap, BITMAP_MAGIC );
|
/* A DIB section is selected in the DC */
|
||||||
|
BITMAPINFO *bi;
|
||||||
|
void *bits;
|
||||||
|
|
||||||
if (!bmp->dib)
|
/* Allocate memory for a BITMAPINFOHEADER structure and a
|
||||||
|
color table. The maximum number of colors in a color table
|
||||||
|
is 256 which corresponds to a bitmap with depth 8.
|
||||||
|
Bitmaps with higher depths don't have color tables. */
|
||||||
|
bi = HeapAlloc(GetProcessHeap(), 0, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
|
||||||
|
|
||||||
|
if (bi)
|
||||||
{
|
{
|
||||||
/* A device-dependent bitmap is selected in the DC */
|
bi->bmiHeader.biSize = sizeof(bi->bmiHeader);
|
||||||
hbmpRet = CreateBitmap(width, height,
|
bi->bmiHeader.biWidth = width;
|
||||||
bmp->bitmap.bmPlanes,
|
bi->bmiHeader.biHeight = height;
|
||||||
bmp->bitmap.bmBitsPixel,
|
bi->bmiHeader.biPlanes = bmp->dib->dsBmih.biPlanes;
|
||||||
NULL);
|
bi->bmiHeader.biBitCount = bmp->dib->dsBmih.biBitCount;
|
||||||
}
|
bi->bmiHeader.biCompression = bmp->dib->dsBmih.biCompression;
|
||||||
else
|
bi->bmiHeader.biSizeImage = 0;
|
||||||
{
|
bi->bmiHeader.biXPelsPerMeter = bmp->dib->dsBmih.biXPelsPerMeter;
|
||||||
/* A DIB section is selected in the DC */
|
bi->bmiHeader.biYPelsPerMeter = bmp->dib->dsBmih.biYPelsPerMeter;
|
||||||
BITMAPINFO *bi;
|
bi->bmiHeader.biClrUsed = bmp->dib->dsBmih.biClrUsed;
|
||||||
void *bits;
|
bi->bmiHeader.biClrImportant = bmp->dib->dsBmih.biClrImportant;
|
||||||
|
|
||||||
/* Allocate memory for a BITMAPINFOHEADER structure and a
|
if (bi->bmiHeader.biCompression == BI_BITFIELDS)
|
||||||
color table. The maximum number of colors in a color table
|
|
||||||
is 256 which corresponds to a bitmap with depth 8.
|
|
||||||
Bitmaps with higher depths don't have color tables. */
|
|
||||||
bi = HeapAlloc(GetProcessHeap(), 0, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
|
|
||||||
|
|
||||||
if (bi)
|
|
||||||
{
|
{
|
||||||
bi->bmiHeader.biSize = sizeof(bi->bmiHeader);
|
/* Copy the color masks */
|
||||||
bi->bmiHeader.biWidth = width;
|
CopyMemory(bi->bmiColors, bmp->dib->dsBitfields, 3 * sizeof(DWORD));
|
||||||
bi->bmiHeader.biHeight = height;
|
|
||||||
bi->bmiHeader.biPlanes = bmp->dib->dsBmih.biPlanes;
|
|
||||||
bi->bmiHeader.biBitCount = bmp->dib->dsBmih.biBitCount;
|
|
||||||
bi->bmiHeader.biCompression = bmp->dib->dsBmih.biCompression;
|
|
||||||
bi->bmiHeader.biSizeImage = 0;
|
|
||||||
bi->bmiHeader.biXPelsPerMeter = bmp->dib->dsBmih.biXPelsPerMeter;
|
|
||||||
bi->bmiHeader.biYPelsPerMeter = bmp->dib->dsBmih.biYPelsPerMeter;
|
|
||||||
bi->bmiHeader.biClrUsed = bmp->dib->dsBmih.biClrUsed;
|
|
||||||
bi->bmiHeader.biClrImportant = bmp->dib->dsBmih.biClrImportant;
|
|
||||||
|
|
||||||
if (bi->bmiHeader.biCompression == BI_BITFIELDS)
|
|
||||||
{
|
|
||||||
/* Copy the color masks */
|
|
||||||
CopyMemory(bi->bmiColors, bmp->dib->dsBitfields, 3 * sizeof(DWORD));
|
|
||||||
}
|
|
||||||
else if (bi->bmiHeader.biBitCount <= 8)
|
|
||||||
{
|
|
||||||
/* Copy the color table */
|
|
||||||
GetDIBColorTable(hdc, 0, 256, bi->bmiColors);
|
|
||||||
}
|
|
||||||
|
|
||||||
hbmpRet = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
|
|
||||||
HeapFree(GetProcessHeap(), 0, bi);
|
|
||||||
}
|
}
|
||||||
|
else if (bi->bmiHeader.biBitCount <= 8)
|
||||||
|
{
|
||||||
|
/* Copy the color table */
|
||||||
|
GetDIBColorTable(hdc, 0, 256, bi->bmiColors);
|
||||||
|
}
|
||||||
|
|
||||||
|
hbmpRet = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
|
||||||
|
HeapFree(GetProcessHeap(), 0, bi);
|
||||||
}
|
}
|
||||||
GDI_ReleaseObj(dc->hBitmap);
|
|
||||||
}
|
}
|
||||||
DC_ReleaseDCPtr( dc );
|
GDI_ReleaseObj(dc->hBitmap);
|
||||||
}
|
}
|
||||||
|
DC_ReleaseDCPtr( dc );
|
||||||
|
|
||||||
TRACE("\t\t%p\n", hbmpRet);
|
TRACE("\t\t%p\n", hbmpRet);
|
||||||
return hbmpRet;
|
return hbmpRet;
|
||||||
|
@ -242,6 +234,12 @@ HBITMAP WINAPI CreateBitmapIndirect( const BITMAP *bmp )
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (bmp->bmWidth > 0x7ffffff || bmp->bmHeight > 0x7ffffff)
|
||||||
|
{
|
||||||
|
SetLastError( ERROR_INVALID_PARAMETER );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
bm = *bmp;
|
bm = *bmp;
|
||||||
|
|
||||||
if (!bm.bmWidth || !bm.bmHeight)
|
if (!bm.bmWidth || !bm.bmHeight)
|
||||||
|
@ -278,6 +276,12 @@ HBITMAP WINAPI CreateBitmapIndirect( const BITMAP *bmp )
|
||||||
|
|
||||||
/* Windows ignores the provided bm.bmWidthBytes */
|
/* Windows ignores the provided bm.bmWidthBytes */
|
||||||
bm.bmWidthBytes = BITMAP_GetWidthBytes( bm.bmWidth, bm.bmBitsPixel );
|
bm.bmWidthBytes = BITMAP_GetWidthBytes( bm.bmWidth, bm.bmBitsPixel );
|
||||||
|
/* XP doesn't allow to create bitmaps larger than 128 Mb */
|
||||||
|
if (bm.bmHeight * bm.bmWidthBytes > 128 * 1024 * 1024)
|
||||||
|
{
|
||||||
|
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Create the BITMAPOBJ */
|
/* Create the BITMAPOBJ */
|
||||||
bmpobj = GDI_AllocObject( sizeof(BITMAPOBJ), BITMAP_MAGIC,
|
bmpobj = GDI_AllocObject( sizeof(BITMAPOBJ), BITMAP_MAGIC,
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
#include "windef.h"
|
#include "windef.h"
|
||||||
#include "winbase.h"
|
#include "winbase.h"
|
||||||
|
#include "winerror.h"
|
||||||
#include "wingdi.h"
|
#include "wingdi.h"
|
||||||
#include "winuser.h"
|
#include "winuser.h"
|
||||||
#include "mmsystem.h"
|
#include "mmsystem.h"
|
||||||
|
@ -966,6 +967,23 @@ static void test_bitmap(void)
|
||||||
hdc = CreateCompatibleDC(0);
|
hdc = CreateCompatibleDC(0);
|
||||||
assert(hdc != 0);
|
assert(hdc != 0);
|
||||||
|
|
||||||
|
SetLastError(0xdeadbeef);
|
||||||
|
hbmp = CreateBitmap(0x7ffffff, 1, 1, 1, NULL);
|
||||||
|
ok(hbmp != 0, "CreateBitmap should not fail\n");
|
||||||
|
DeleteObject(hbmp);
|
||||||
|
|
||||||
|
SetLastError(0xdeadbeef);
|
||||||
|
hbmp = CreateBitmap(0x7ffffff, 9, 1, 1, NULL);
|
||||||
|
ok(!hbmp, "CreateBitmap should fail\n");
|
||||||
|
ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY,
|
||||||
|
"expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
|
||||||
|
|
||||||
|
SetLastError(0xdeadbeef);
|
||||||
|
hbmp = CreateBitmap(0x7ffffff + 1, 1, 1, 1, NULL);
|
||||||
|
ok(!hbmp, "CreateBitmap should fail\n");
|
||||||
|
ok(GetLastError() == ERROR_INVALID_PARAMETER,
|
||||||
|
"expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
|
||||||
|
|
||||||
hbmp = CreateBitmap(15, 15, 1, 1, NULL);
|
hbmp = CreateBitmap(15, 15, 1, 1, NULL);
|
||||||
assert(hbmp != NULL);
|
assert(hbmp != NULL);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue