When populating the imagelists cache with icons of different sizes, it can happen that only some icon sizes actually succeed the extraction, with others failing with a NULL handle. This is especially true with some broken "executable packers" where for example, a 32x32 icon loads okay, but a 16x16 fails. Even when PrivateExtractIconsW succeeds, the returned handle can still be NULL, leading to the ImageLists becoming out of sync.
This fixes a regression, because at some point, we stopped failing if one icon failed to extract, so when SIC_IconAppend called ImageList_AddIcon with a NULL icon handle, it would go out of sync.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45696 Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/shell32/iconcache.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/dlls/shell32/iconcache.c b/dlls/shell32/iconcache.c index 6107e0c..44422ab 100644 --- a/dlls/shell32/iconcache.c +++ b/dlls/shell32/iconcache.c @@ -364,13 +364,14 @@ static INT SIC_LoadIcon (const WCHAR *sourcefile, INT index, DWORD flags) HICON hshortcuts[ARRAY_SIZE(hicons)] = { 0 }; unsigned int i; SIZE size; - int ret; + INT ret = -1;
for (i = 0; i < ARRAY_SIZE(hicons); i++) { get_imagelist_icon_size( i, &size ); if (!PrivateExtractIconsW( sourcefile, index, size.cx, size.cy, &hicons[i], 0, 1, 0 )) WARN("Failed to load icon %d from %s.\n", index, debugstr_w(sourcefile)); + if (!hicons[i]) goto fail; }
if (flags & GIL_FORSHORTCUT) @@ -403,6 +404,8 @@ static INT SIC_LoadIcon (const WCHAR *sourcefile, INT index, DWORD flags) }
ret = SIC_IconAppend( sourcefile, index, hicons, flags ); + +fail: for (i = 0; i < ARRAY_SIZE(hicons); i++) DestroyIcon(hicons[i]); return ret;