diff --git a/modules/rostests/apitests/shell32/ExtractIconEx.cpp b/modules/rostests/apitests/shell32/ExtractIconEx.cpp index e32f3ac34d2..244081199f3 100644 --- a/modules/rostests/apitests/shell32/ExtractIconEx.cpp +++ b/modules/rostests/apitests/shell32/ExtractIconEx.cpp @@ -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 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, 0, NULL, NULL, IconTests[i].nIcons); - ok(nReturnedIcons == IconTests[i].nIcons, "ExtractIconExW(%u): Expected %u icons, got %u\n", i, IconTests[i].nIcons, nReturnedIcons); + 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) + { + 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 index 00000000000..587992b6eea Binary files /dev/null and b/modules/rostests/apitests/shell32/ROS.ico differ diff --git a/modules/rostests/apitests/shell32/resource.rc b/modules/rostests/apitests/shell32/resource.rc index f57af647e3d..177ef5b3f03 100644 --- a/modules/rostests/apitests/shell32/resource.rc +++ b/modules/rostests/apitests/shell32/resource.rc @@ -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 index 00000000000..2c32fdf0022 Binary files /dev/null and b/modules/rostests/apitests/shell32/sysicon.ico differ