[USER32] Follow-up of #4262 (a47590c) (#4312)
authorKatayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
Tue, 25 Jan 2022 11:41:00 +0000 (20:41 +0900)
committerGitHub <noreply@github.com>
Tue, 25 Jan 2022 11:41:00 +0000 (20:41 +0900)
Display icons/cursors correctly without hungup. CORE-16287

win32ss/user/user32/misc/exticon.c

index d414305..70e7d44 100644 (file)
@@ -508,12 +508,29 @@ static UINT ICO_ExtractIconExW(
                     HICON icon;
                     WORD *cursorData = NULL;
 #ifdef __REACTOS__
                     HICON icon;
                     WORD *cursorData = NULL;
 #ifdef __REACTOS__
-                    BITMAPINFOHEADER bmih;
+                    BITMAPINFOHEADER bi;
+                    DWORD cbColorTable = 0, cbTotal;
 #endif
 
                     imageData = peimage + dataOffset;
 #ifdef __REACTOS__
 #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
 #else
                     entry = (LPICONIMAGE)(imageData);
 #endif
@@ -521,18 +538,23 @@ static UINT ICO_ExtractIconExW(
                     if(sig == 2)
                     {
 #ifdef __REACTOS__
                     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__
 #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
 #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__
                         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
 #else
                         memcpy(cursorData + 2, imageData, entry->icHeader.biSizeImage);
 #endif
@@ -553,7 +575,7 @@ static UINT ICO_ExtractIconExW(
                     }
 
 #ifdef __REACTOS__
                     }
 
 #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
 #else
                     icon = CreateIconFromResourceEx(imageData, entry->icHeader.biSizeImage, sig == 1, 0x00030000, cx[index], cy[index], flags);
 #endif