diff --git "a/modules/rostests/apitests/shell32/ExtractIconEx.cpp" "b/modules/rostests/apitests/shell32/ExtractIconEx.cpp" index e32f3ac34d2..a83d0a19ef3 100644 --- "a/modules/rostests/apitests/shell32/ExtractIconEx.cpp" +++ "b/modules/rostests/apitests/shell32/ExtractIconEx.cpp" @@ -3,9 +3,12 @@ * 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 +#include typedef struct { @@ -13,6 +16,50 @@ typedef struct UINT nIcons; } EXTRACTICONTESTS; +BOOL ResourceToFile(INT i, LPCSTR FileName) +{ + FILE *fout; + HGLOBAL hData; + HRSRC hRes; + LPVOID lpResLock; + UINT iSize; + + if (access(FileName, F_OK) == 0) + { + 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 +69,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 index 0000000000000000000000000000000000000000..587992b6eea0dc7af0f6f519ecc6d172bca513c3 GIT binary patch literal 10526 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 literal 0 HcmV?d00001