diff --git a/win32ss/user/user32/include/user32.h b/win32ss/user/user32/include/user32.h index 2615fb61549..0eb01deeb71 100644 --- a/win32ss/user/user32/include/user32.h +++ b/win32ss/user/user32/include/user32.h @@ -72,4 +72,36 @@ typedef struct _PATRECT HBRUSH hBrush; } PATRECT, * PPATRECT; +#include "pshpack1.h" + +typedef struct { + BYTE bWidth; + BYTE bHeight; + BYTE bColorCount; + BYTE bReserved; + WORD xHotspot; + WORD yHotspot; + DWORD dwDIBSize; + DWORD dwDIBOffset; +} CURSORICONFILEDIRENTRY; + +typedef struct +{ + WORD idReserved; + WORD idType; + WORD idCount; + CURSORICONFILEDIRENTRY idEntries[1]; +} CURSORICONFILEDIR; + +#include "poppack.h" + +const CURSORICONFILEDIRENTRY* +get_best_icon_file_entry( + _In_ const CURSORICONFILEDIR* dir, + _In_ DWORD dwFileSize, + _In_ int cxDesired, + _In_ int cyDesired, + _In_ BOOL bIcon, + _In_ DWORD fuLoad); + #endif /* _USER32_PCH_ */ diff --git a/win32ss/user/user32/misc/exticon.c b/win32ss/user/user32/misc/exticon.c index ba2bd6d6b2c..a2afd5d98d0 100644 --- a/win32ss/user/user32/misc/exticon.c +++ b/win32ss/user/user32/misc/exticon.c @@ -438,36 +438,47 @@ static UINT ICO_ExtractIconExW( { DWORD dataOffset; LPBYTE imageData; - POINT hotSpot; - LPICONIMAGE entry; - - dataOffset = get_best_icon_file_offset(peimage, fsizel, cx[index], cy[index], sig == 1, flags, sig == 1 ? NULL : &hotSpot); - - if (dataOffset) + const CURSORICONFILEDIR *dir; + const CURSORICONFILEDIRENTRY *entry; + LPBITMAPINFOHEADER pbi; + + dir = (const CURSORICONFILEDIR*)peimage; + entry = get_best_icon_file_entry(dir, fsizel, cx[index], cy[index], sig == 1, flags); + dataOffset = entry->dwDIBOffset; + if (entry && entry->dwDIBSize && dataOffset) { HICON icon; WORD *cursorData = NULL; + DWORD image_size, index; + dataOffset = entry->dwDIBOffset; imageData = peimage + dataOffset; - entry = (LPICONIMAGE)(imageData); + pbi = (LPBITMAPINFOHEADER)imageData; + if (pbi->biSizeImage) + image_size = pbi->biSizeImage; + else + image_size = entry->dwDIBSize; if(sig == 2) { /* we need to prepend the bitmap data with hot spots for CreateIconFromResourceEx */ - cursorData = HeapAlloc(GetProcessHeap(), 0, entry->icHeader.biSizeImage + 2 * sizeof(WORD)); + cursorData = HeapAlloc(GetProcessHeap(), 0, image_size + 2 * sizeof(WORD)); if(!cursorData) continue; - cursorData[0] = hotSpot.x; - cursorData[1] = hotSpot.y; + cursorData[0] = entry->xHotspot; + cursorData[1] = entry->yHotspot; - memcpy(cursorData + 2, imageData, entry->icHeader.biSizeImage); + memcpy(cursorData + 2, imageData, image_size); imageData = (LPBYTE)cursorData; + image_size += 2 * sizeof(WORD); } - icon = CreateIconFromResourceEx(imageData, entry->icHeader.biSizeImage, sig == 1, 0x00030000, cx[index], cy[index], flags); + /* Now imageData is a RT_ICON or RT_CURSOR */ + icon = CreateIconFromResourceEx(imageData, image_size, sig == 1, 0x00030000, cx[index], cy[index], flags); + ASSERT(icon != NULL); HeapFree(GetProcessHeap(), 0, cursorData); diff --git a/win32ss/user/user32/windows/cursoricon.c b/win32ss/user/user32/windows/cursoricon.c index 6299c839006..95d78b6f093 100644 --- a/win32ss/user/user32/windows/cursoricon.c +++ b/win32ss/user/user32/windows/cursoricon.c @@ -440,29 +440,6 @@ done: return alpha; } -#include "pshpack1.h" - -typedef struct { - BYTE bWidth; - BYTE bHeight; - BYTE bColorCount; - BYTE bReserved; - WORD xHotspot; - WORD yHotspot; - DWORD dwDIBSize; - DWORD dwDIBOffset; -} CURSORICONFILEDIRENTRY; - -typedef struct -{ - WORD idReserved; - WORD idType; - WORD idCount; - CURSORICONFILEDIRENTRY idEntries[1]; -} CURSORICONFILEDIR; - -#include "poppack.h" - const CURSORICONFILEDIRENTRY* get_best_icon_file_entry( _In_ const CURSORICONFILEDIR* dir, @@ -470,8 +447,7 @@ get_best_icon_file_entry( _In_ int cxDesired, _In_ int cyDesired, _In_ BOOL bIcon, - _In_ DWORD fuLoad -) + _In_ DWORD fuLoad) { CURSORICONDIR* fakeDir; CURSORICONDIRENTRY* fakeEntry; @@ -536,7 +512,7 @@ get_best_icon_file_entry( } /* Now call LookupIconIdFromResourceEx */ - i = LookupIconIdFromDirectoryEx((PBYTE)fakeDir, bIcon, cxDesired, cyDesired, fuLoad & LR_MONOCHROME); + i = LookupIconIdFromDirectoryEx((PBYTE)fakeDir, bIcon, cxDesired, cyDesired, fuLoad); /* We don't need this anymore */ HeapFree(GetProcessHeap(), 0, fakeDir); if(i == 0) @@ -2518,7 +2494,10 @@ HICON WINAPI CreateIconFromResourceEx( hIcon = NtUserxCreateEmptyCurObject(isAnimated); if (!hIcon) + { + ERR("!hIcon\n"); goto end_error; + } if(!NtUserSetCursorIconData(hIcon, NULL, NULL, &cursorData)) {