https://git.reactos.org/?p=reactos.git;a=commitdiff;h=75c67f9b515117b730a84800b7c0b5bf65ed192c

commit 75c67f9b515117b730a84800b7c0b5bf65ed192c
Author:     Doug Lyons <[email protected]>
AuthorDate: Mon Nov 27 11:02:08 2023 -0600
Commit:     GitHub <[email protected]>
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;

Reply via email to