[RAPPS] Validate DisplayIcon value and support icon index (#5664)
authorWhindmar Saksit <whindsaks@proton.me>
Mon, 20 Nov 2023 16:41:31 +0000 (17:41 +0100)
committerStanislav Motylkov <x86corez@gmail.com>
Mon, 20 Nov 2023 17:50:42 +0000 (20:50 +0300)
- If the DisplayIcon value points to an invalid path, ExtractIconW()
  can return 1! ExtractIconExW() does not have this problem nor the -1 issue.
  Reference: https://devblogs.microsoft.com/oldnewthing/20050526-07/?p=35533
- Use the icon index from PathParseIconLocationW().

Addendum to c6c7fc1. CORE-19317

Test to reproduce:

```
@echo off
reg add HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Ex1 /v DisplayName /d "Ex1 Normal" /f
reg add HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Ex1 /v DisplayIcon /d "%windir%\explorer.exe" /f
reg add HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Ex1 /v UninstallString /d "calc.exe" /f
reg add HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Ex2 /v DisplayName /d "Ex2 Bad icon path" /f
reg add HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Ex2 /v DisplayIcon /d "%windir%\DoesNotExist.exe" /f
reg add HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Ex2 /v UninstallString /d "calc.exe" /f
reg add HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Ex3 /v DisplayName /d "Ex3 Resource index" /f
reg add HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Ex3 /v DisplayIcon /d "%windir%\explorer.exe,4" /f
reg add HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Ex3 /v UninstallString /d "calc.exe" /f
start appwiz.cpl
```

base/applications/rapps/appview.cpp

index 004e162..a34e9cd 100644 (file)
@@ -1289,14 +1289,13 @@ CAppsListView::AddApplication(CAppInfo *AppInfo, BOOL InitialCheckState)
         /* Load icon from registry */
         HICON hIcon = NULL;
         CStringW szIconPath;
+        int IconIndex;
         if (AppInfo->RetrieveIcon(szIconPath))
         {
-            PathParseIconLocationW((LPWSTR)szIconPath.GetString());
+            IconIndex = PathParseIconLocationW(szIconPath.GetBuffer());
+            szIconPath.ReleaseBuffer();
 
-            /* Load only the 1st icon from the application executable,
-             * because all apps provide the executables which have the main icon
-             * as 1st in the index , so we don't need other icons here */
-            hIcon = ExtractIconW(hInst, szIconPath.GetString(), 0);
+            ExtractIconExW(szIconPath.GetString(), IconIndex, &hIcon, NULL, 1);
         }
 
         /* Use the default icon if none were found in the file, or if it is not supported (returned 1) */
@@ -1306,7 +1305,7 @@ CAppsListView::AddApplication(CAppInfo *AppInfo, BOOL InitialCheckState)
             hIcon = LoadIconW(hInst, MAKEINTRESOURCEW(IDI_MAIN));
         }
 
-        int IconIndex = ImageList_AddIcon(m_hImageListView, hIcon);
+        IconIndex = ImageList_AddIcon(m_hImageListView, hIcon);
         DestroyIcon(hIcon);
 
         int Index = AddItem(ItemCount, IconIndex, AppInfo->szDisplayName, (LPARAM)AppInfo);