From: Katayama Hirofumi MZ Date: Tue, 25 Jan 2022 11:41:00 +0000 (+0900) Subject: [USER32] Follow-up of #4262 (a47590c) (#4312) X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=0360abb796ef81e3fa03fa0c9dea8881bdb88a80;ds=sidebyside [USER32] Follow-up of #4262 (a47590c) (#4312) Display icons/cursors correctly without hungup. CORE-16287 --- diff --git a/win32ss/user/user32/misc/exticon.c b/win32ss/user/user32/misc/exticon.c index d4143054dc7..70e7d447a2b 100644 --- a/win32ss/user/user32/misc/exticon.c +++ b/win32ss/user/user32/misc/exticon.c @@ -508,12 +508,29 @@ static UINT ICO_ExtractIconExW( HICON icon; WORD *cursorData = NULL; #ifdef __REACTOS__ - BITMAPINFOHEADER bmih; + BITMAPINFOHEADER bi; + DWORD cbColorTable = 0, cbTotal; #endif imageData = peimage + dataOffset; #ifdef __REACTOS__ - memcpy(&bmih, imageData, sizeof(BITMAPINFOHEADER)); + /* Calculate the size of color table */ + CopyMemory(&bi, imageData, sizeof(BITMAPCOREHEADER)); + if (bi.biBitCount <= 8) + { + if (bi.biSize >= sizeof(BITMAPINFOHEADER)) + { + CopyMemory(&bi, imageData, sizeof(BITMAPINFOHEADER)); + if (bi.biClrUsed) + cbColorTable = bi.biClrUsed * sizeof(RGBQUAD); + else + cbColorTable = (1 << bi.biBitCount) * sizeof(RGBQUAD); + } + else if (bi.biSize == sizeof(BITMAPCOREHEADER)) + { + cbColorTable = (1 << bi.biBitCount) * sizeof(RGBTRIPLE); + } + } #else entry = (LPICONIMAGE)(imageData); #endif @@ -521,18 +538,23 @@ static UINT ICO_ExtractIconExW( if(sig == 2) { #ifdef __REACTOS__ - /* biSizeImage is the size of the raw bitmap data. - * A dummy 0 can be given for BI_RGB bitmaps. - * https://en.wikipedia.org/wiki/BMP_file_format */ - if ((bmih.biCompression == BI_RGB) && (bmih.biSizeImage == 0)) - { - bmih.biSizeImage = ((bmih.biWidth * bmih.biBitCount + 31) / 32) * 4 * - (bmih.biHeight / 2); - } + /* biSizeImage is the size of the raw bitmap data. + * A dummy 0 can be given for BI_RGB bitmaps. + * https://en.wikipedia.org/wiki/BMP_file_format */ + if (bi.biSizeImage == 0 || bi.biSize == sizeof(BITMAPCOREHEADER)) + { + /* Calculate image size */ +#define WIDTHBYTES(width, bits) (((width) * (bits) + 31) / 32 * 4) + bi.biSizeImage = WIDTHBYTES(bi.biWidth, bi.biBitCount) * (bi.biHeight / 2); + bi.biSizeImage += WIDTHBYTES(bi.biWidth, 1) * (bi.biHeight / 2); +#undef WIDTHBYTES + } + /* Calculate total size */ + cbTotal = bi.biSize + cbColorTable + bi.biSizeImage; #endif /* we need to prepend the bitmap data with hot spots for CreateIconFromResourceEx */ #ifdef __REACTOS__ - cursorData = HeapAlloc(GetProcessHeap(), 0, bmih.biSizeImage + 2 * sizeof(WORD)); + cursorData = HeapAlloc(GetProcessHeap(), 0, 2 * sizeof(WORD) + cbTotal); #else cursorData = HeapAlloc(GetProcessHeap(), 0, entry->icHeader.biSizeImage + 2 * sizeof(WORD)); #endif @@ -544,7 +566,7 @@ static UINT ICO_ExtractIconExW( cursorData[1] = hotSpot.y; #ifdef __REACTOS__ - memcpy(cursorData + 2, imageData, bmih.biSizeImage); + CopyMemory(cursorData + 2, imageData, cbTotal); #else memcpy(cursorData + 2, imageData, entry->icHeader.biSizeImage); #endif @@ -553,7 +575,7 @@ static UINT ICO_ExtractIconExW( } #ifdef __REACTOS__ - icon = CreateIconFromResourceEx(imageData, bmih.biSizeImage, sig == 1, 0x00030000, cx[index], cy[index], flags); + icon = CreateIconFromResourceEx(imageData, cbTotal, sig == 1, 0x00030000, cx[index], cy[index], flags); #else icon = CreateIconFromResourceEx(imageData, entry->icHeader.biSizeImage, sig == 1, 0x00030000, cx[index], cy[index], flags); #endif