[SHELL32_APITESTS] Add ROS.ico test file. Improve shell32:ExtractIconEx tests (#5169)
authorDoug Lyons <douglyons@douglyons.com>
Thu, 30 Mar 2023 11:31:13 +0000 (06:31 -0500)
committerGitHub <noreply@github.com>
Thu, 30 Mar 2023 11:31:13 +0000 (13:31 +0200)
Improve shell32:ExtractIconEx tests by updating it and adding more test files and 1 new icon file.

JIRA issue: ROSTESTS-381

Add new ROS.ico file which has both a normal icon and a PNG one.
Update testing to test for count of icons in file and separately extract the 0th one.
Add tests for sysicon.ico, explorer.exe and the new ROS.ico files.

modules/rostests/apitests/shell32/ExtractIconEx.cpp
modules/rostests/apitests/shell32/ROS.ico [new file with mode: 0644]
modules/rostests/apitests/shell32/resource.rc
modules/rostests/apitests/shell32/sysicon.ico [new file with mode: 0644]

index e32f3ac..2440811 100644 (file)
@@ -3,9 +3,11 @@
  * LICENSE:     GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
  * PURPOSE:     Tests for ExtractIconEx routine
  * COPYRIGHT:   Copyright 2019 George BiČ™oc (george.bisoc@reactos.org)
+ *              Copyright 2023 Doug Lyons (douglyons@douglyons.com)
  */
 
 #include "shelltest.h"
+#include <stdio.h>
 
 typedef struct
 {
@@ -13,6 +15,64 @@ typedef struct
     UINT nIcons;
 } EXTRACTICONTESTS;
 
+BOOL FileExists(LPCSTR FileName)
+{
+    FILE *fp = NULL;
+    bool exists = FALSE;
+
+    fp = fopen(FileName, "r");
+    if (fp != NULL)
+    {
+        exists = TRUE;
+        fclose(fp);
+    }
+    return exists;
+}
+
+BOOL ResourceToFile(INT i, LPCSTR FileName)
+{
+    FILE *fout;
+    HGLOBAL hData;
+    HRSRC hRes;
+    LPVOID lpResLock;
+    UINT iSize;
+
+    if (FileExists(FileName))
+    {
+        skip("'%s' already exists. Exiting now\n", FileName);
+        return FALSE;
+    }
+
+    hRes = FindResourceW(NULL, MAKEINTRESOURCEW(i), MAKEINTRESOURCEW(RT_RCDATA));
+    if (hRes == NULL)
+    {
+        skip("Could not locate resource (%d). Exiting now\n", i);
+        return FALSE;
+    }
+
+    iSize = SizeofResource(NULL, hRes);
+
+    hData = LoadResource(NULL, hRes);
+    if (hData == NULL)
+    {
+        skip("Could not load resource (%d). Exiting now\n", i);
+        return FALSE;
+    }
+
+    // Lock the resource into global memory.
+    lpResLock = LockResource(hData);
+    if (lpResLock == NULL)
+    {
+        skip("Could not lock resource (%d). Exiting now\n", i);
+        return FALSE;
+    }
+
+    fout = fopen(FileName, "wb");
+    fwrite(lpResLock, iSize, 1, fout);
+    fclose(fout);
+    return TRUE;
+}
+
 EXTRACTICONTESTS IconTests[] =
 {
     /* Executable file with icon */
@@ -22,16 +82,43 @@ EXTRACTICONTESTS IconTests[] =
     {L"%SystemRoot%\\System32\\autochk.exe", 0},
 
     /* Non-existing files */
-    {L"%SystemRoot%\\non-existent-file.sdf", 0}
+    {L"%SystemRoot%\\non-existent-file.sdf", 0},
+
+    /* Multiple icons in the same EXE file (18 icons) */
+    {L"%SystemRoot%\\explorer.exe", 18},
+
+    /* Multiple icons in the same ICO file (6 icons)
+     * Per MS: If the file is an .ico file, the return value is 1. */
+    {L"sysicon.ico", 1},
+
+    /* ICO file with both normal and PNG icons */
+    {L"ROS.ico", 0}
 };
 
 START_TEST(ExtractIconEx)
 {
-    UINT i, nReturnedIcons;
+    UINT i, nReturnedIcons, nExtractedIcons;
+    CHAR FileName[2][13] = { "ROS.ico", "sysicon.ico" };
+
+    if (!ResourceToFile(2, FileName[0]))
+        return;
+    if (!ResourceToFile(3, FileName[1]))
+        return;
+
+    /* Check count of icons returned */
+    for (i = 0; i < _countof(IconTests); ++i)
+    {
+        nReturnedIcons = ExtractIconExW(IconTests[i].pszFilePath, -1, NULL, NULL, 0);
+        ok(nReturnedIcons == IconTests[i].nIcons, "ExtractIconExW(%u): Expects %u icons, got %u\n", i, IconTests[i].nIcons, nReturnedIcons);
+    }
 
+    /* Check if the 0th icon can be extracted successfully */
     for (i = 0; i < _countof(IconTests); ++i)
     {
-        nReturnedIcons = ExtractIconExW(IconTests[i].pszFilePath, 0, NULL, NULL, IconTests[i].nIcons);
-        ok(nReturnedIcons == IconTests[i].nIcons, "ExtractIconExW(%u): Expected %u icons, got %u\n", i, IconTests[i].nIcons, nReturnedIcons);
+        nExtractedIcons = ExtractIconExW(IconTests[i].pszFilePath, 0, NULL, NULL, 1);
+        ok(nExtractedIcons == IconTests[i].nIcons, "ExtractIconExW(%u): Expects %u icons, got %u\n", i, IconTests[i].nIcons, nExtractedIcons);
     }
+
+    DeleteFileA(FileName[0]);
+    DeleteFileA(FileName[1]);
 }
diff --git a/modules/rostests/apitests/shell32/ROS.ico b/modules/rostests/apitests/shell32/ROS.ico
new file mode 100644 (file)
index 0000000..587992b
Binary files /dev/null and b/modules/rostests/apitests/shell32/ROS.ico differ
index f57af64..177ef5b 100644 (file)
@@ -5,6 +5,8 @@
 LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
 
 1 ICON "1.ico"
+2 RCDATA "ROS.ico"
+3 RCDATA "sysicon.ico"
 
 SHLIMIT DIALOG 0, 0, 122, 84
 CAPTION "SHLIMIT"
diff --git a/modules/rostests/apitests/shell32/sysicon.ico b/modules/rostests/apitests/shell32/sysicon.ico
new file mode 100644 (file)
index 0000000..2c32fdf
Binary files /dev/null and b/modules/rostests/apitests/shell32/sysicon.ico differ