https://git.reactos.org/?p=reactos.git;a=commitdiff;h=75c67f9b515117b730a84…
commit 75c67f9b515117b730a84800b7c0b5bf65ed192c
Author: Doug Lyons <douglyons(a)douglyons.com>
AuthorDate: Mon Nov 27 11:02:08 2023 -0600
Commit: GitHub <noreply(a)github.com>
CommitDate: Mon Nov 27 17:02:08 2023 +0000
[USER32] Fix F1'97 Demo icon not showing in explorer (#5268)
Fixes the F1'97 Demo program (a racing game) not showing an icon in explorer.
This fixes a very special kind of icons which are embedded into the
executable by ancient Watcom C/C++ compilers.
Windows XP/2k3sp2 can show that icon.
Windows Vista/7 cannot show that icon.
Due to the different behavior of the various Windows versions, we
also added a testcase for our bots to protect that functionality in the future,
we committed that test by 0.4.15-dev-7076-g c00d41d91c181746563e689d3390228f703053f5 (#6020)
JIRA issue: CORE-10726
---
win32ss/user/user32/misc/exticon.c | 69 ++++++++++++++++++++++++++++++++++++++
1 file changed, 69 insertions(+)
diff --git a/win32ss/user/user32/misc/exticon.c b/win32ss/user/user32/misc/exticon.c
index 2afd6e6d975..fec6103b2bb 100644
--- a/win32ss/user/user32/misc/exticon.c
+++ b/win32ss/user/user32/misc/exticon.c
@@ -743,9 +743,78 @@ static UINT ICO_ExtractIconExW(
xresdir = find_entry_by_id(iconresdir, LOWORD(pIconId[i]), rootresdir);
if( !xresdir )
{
+#ifdef __REACTOS__
+ /* XP/2K3 can decode icons this way. Vista/7 cannot. This handles
+ * damaged Resources in 'Icon Group' by falling back to 'Icon' resources.
+ * Older Watcom C/C++ compilers can generate such a case */
+ const IMAGE_RESOURCE_DIRECTORY *resdir;
+ WARN("icon entry %d not found\n", LOWORD(pIconId[i]));
+
+ /* Try to get an icon by walking the files Resource Section */
+ if (iconresdir->NumberOfIdEntries > 0)
+ {
+ xresent = (const IMAGE_RESOURCE_DIRECTORY_ENTRY*)
+ (ULONG_PTR)(iconresdir + 1);
+ }
+ else
+ {
+ RetPtr[i] = 0;
+ continue;
+ }
+
+ /* Get the Resource Directory */
+ resdir = (const IMAGE_RESOURCE_DIRECTORY *)
+ ((const char *)rootresdir + xresent->OffsetToDirectory);
+
+ if (resdir->NumberOfIdEntries > 0) // Do we have entries
+ {
+ xresent = (const IMAGE_RESOURCE_DIRECTORY_ENTRY*)
+ (ULONG_PTR)(resdir + 1);
+ }
+ else
+ {
+ RetPtr[i] = 0;
+ continue;
+ }
+
+ /* Retrieve the data entry and find its address */
+ igdataent = (const IMAGE_RESOURCE_DATA_ENTRY*)
+ ((const char *)rootresdir + xresent->OffsetToData);
+ idata = RtlImageRvaToVa(RtlImageNtHeader((HMODULE)peimage),
+ (HMODULE)peimage, igdataent->OffsetToData, NULL);
+ if (!idata)
+ {
+ RetPtr[i] = 0;
+ continue;
+ }
+
+ /* Check to see if this looks like an icon bitmap */
+ if (idata[0] == sizeof(BITMAPINFOHEADER))
+ {
+ BITMAPINFOHEADER bmih;
+ RtlCopyMemory(&bmih, idata, sizeof(BITMAPINFOHEADER));
+ /* Do the Width and Height look correct for an icon */
+ if ((bmih.biWidth * 2) == bmih.biHeight)
+ {
+ RetPtr[0] = CreateIconFromResourceEx(idata, igdataent->Size,
+ TRUE, 0x00030000, cx1, cy1, flags);
+ if (cx2 && cy2)
+ RetPtr[1] = CreateIconFromResourceEx(idata, idataent->Size,
+ TRUE, 0x00030000, cx2, cy2, flags);
+ ret = 1; // Set number of icons found
+ goto end; // Success so Exit
+ }
+ }
+ else
+ {
+ RetPtr[i] = 0;
+ continue;
+ }
+#else
WARN("icon entry %d not found\n", LOWORD(pIconId[i]));
RetPtr[i]=0;
continue;
+#endif
}
xresdir = find_entry_default(xresdir, rootresdir);
idataent = (const IMAGE_RESOURCE_DATA_ENTRY*)xresdir;