[PATCH] shell32: Resize from the first available icon to fill missing icon sizes.
Gabriel Ivăncescu
gabrielopcode at gmail.com
Fri Mar 19 09:07:51 CDT 2021
The issue is not in PrivateExtractIconsW: it fails on Windows on such
malformed executables as well (see bug report).
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45696
Signed-off-by: Gabriel Ivăncescu <gabrielopcode at gmail.com>
---
dlls/shell32/iconcache.c | 27 +++++++++++++++++++++++++--
1 file changed, 25 insertions(+), 2 deletions(-)
diff --git a/dlls/shell32/iconcache.c b/dlls/shell32/iconcache.c
index d1be540..265cb87 100644
--- a/dlls/shell32/iconcache.c
+++ b/dlls/shell32/iconcache.c
@@ -362,6 +362,7 @@ static INT SIC_LoadIcon (const WCHAR *sourcefile, INT index, DWORD flags)
{
HICON hicons[ARRAY_SIZE(shell_imagelists)] = { 0 };
HICON hshortcuts[ARRAY_SIZE(hicons)] = { 0 };
+ HICON first_icon = NULL;
unsigned int i;
SIZE size;
INT ret = -1;
@@ -369,8 +370,30 @@ static INT SIC_LoadIcon (const WCHAR *sourcefile, INT index, DWORD flags)
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));
+ PrivateExtractIconsW( sourcefile, index, size.cx, size.cy, &hicons[i], 0, 1, 0 );
+ if (!hicons[i])
+ WARN("Failed to load icon %d (%dx%d) from %s.\n", index, size.cx, size.cy, debugstr_w(sourcefile));
+ else if (!first_icon)
+ first_icon = hicons[i];
+ }
+
+ if (!first_icon)
+ {
+ WARN("No valid icon of any size was able to be loaded.\n");
+ return ret;
+ }
+
+ /* It is possible that PrivateExtractIconsW fails for some sizes, if the executable
+ is malformed (packed, obfuscated, etc), and does fail only on certain sizes even
+ on Windows. Create the missing sizes by resizing from the first available icon. */
+ for (i = 0; i < ARRAY_SIZE(hicons); i++)
+ {
+ if (hicons[i]) continue;
+
+ /* If this fails, we have to abort to prevent the image lists from
+ becoming out of sync and completely screwing the icons up */
+ get_imagelist_icon_size(i, &size);
+ hicons[i] = CopyImage(first_icon, IMAGE_ICON, size.cx, size.cy, 0);
if (!hicons[i]) goto fail;
}
--
2.30.0
More information about the wine-devel
mailing list