18ec05f5fSBișoc George /*
28ec05f5fSBișoc George * PROJECT: ReactOS API Tests
38ec05f5fSBișoc George * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
48ec05f5fSBișoc George * PURPOSE: Tests for ExtractIconEx routine
5b00ecdcaSGeorge Bișoc * COPYRIGHT: Copyright 2019 George Bișoc (george.bisoc@reactos.org)
6*c8fc8264SDoug Lyons * Copyright 2023 Doug Lyons (douglyons@douglyons.com)
78ec05f5fSBișoc George */
88ec05f5fSBișoc George
98ec05f5fSBișoc George #include "shelltest.h"
10*c8fc8264SDoug Lyons #include <stdio.h>
118ec05f5fSBișoc George
128ec05f5fSBișoc George typedef struct
138ec05f5fSBișoc George {
148ec05f5fSBișoc George PCWSTR pszFilePath;
158ec05f5fSBișoc George UINT nIcons;
168ec05f5fSBișoc George } EXTRACTICONTESTS;
178ec05f5fSBișoc George
FileExists(LPCSTR FileName)18*c8fc8264SDoug Lyons BOOL FileExists(LPCSTR FileName)
19*c8fc8264SDoug Lyons {
20*c8fc8264SDoug Lyons FILE *fp = NULL;
21*c8fc8264SDoug Lyons bool exists = FALSE;
22*c8fc8264SDoug Lyons
23*c8fc8264SDoug Lyons fp = fopen(FileName, "r");
24*c8fc8264SDoug Lyons if (fp != NULL)
25*c8fc8264SDoug Lyons {
26*c8fc8264SDoug Lyons exists = TRUE;
27*c8fc8264SDoug Lyons fclose(fp);
28*c8fc8264SDoug Lyons }
29*c8fc8264SDoug Lyons return exists;
30*c8fc8264SDoug Lyons }
31*c8fc8264SDoug Lyons
ResourceToFile(INT i,LPCSTR FileName)32*c8fc8264SDoug Lyons BOOL ResourceToFile(INT i, LPCSTR FileName)
33*c8fc8264SDoug Lyons {
34*c8fc8264SDoug Lyons FILE *fout;
35*c8fc8264SDoug Lyons HGLOBAL hData;
36*c8fc8264SDoug Lyons HRSRC hRes;
37*c8fc8264SDoug Lyons LPVOID lpResLock;
38*c8fc8264SDoug Lyons UINT iSize;
39*c8fc8264SDoug Lyons
40*c8fc8264SDoug Lyons if (FileExists(FileName))
41*c8fc8264SDoug Lyons {
42*c8fc8264SDoug Lyons skip("'%s' already exists. Exiting now\n", FileName);
43*c8fc8264SDoug Lyons return FALSE;
44*c8fc8264SDoug Lyons }
45*c8fc8264SDoug Lyons
46*c8fc8264SDoug Lyons hRes = FindResourceW(NULL, MAKEINTRESOURCEW(i), MAKEINTRESOURCEW(RT_RCDATA));
47*c8fc8264SDoug Lyons if (hRes == NULL)
48*c8fc8264SDoug Lyons {
49*c8fc8264SDoug Lyons skip("Could not locate resource (%d). Exiting now\n", i);
50*c8fc8264SDoug Lyons return FALSE;
51*c8fc8264SDoug Lyons }
52*c8fc8264SDoug Lyons
53*c8fc8264SDoug Lyons iSize = SizeofResource(NULL, hRes);
54*c8fc8264SDoug Lyons
55*c8fc8264SDoug Lyons hData = LoadResource(NULL, hRes);
56*c8fc8264SDoug Lyons if (hData == NULL)
57*c8fc8264SDoug Lyons {
58*c8fc8264SDoug Lyons skip("Could not load resource (%d). Exiting now\n", i);
59*c8fc8264SDoug Lyons return FALSE;
60*c8fc8264SDoug Lyons }
61*c8fc8264SDoug Lyons
62*c8fc8264SDoug Lyons // Lock the resource into global memory.
63*c8fc8264SDoug Lyons lpResLock = LockResource(hData);
64*c8fc8264SDoug Lyons if (lpResLock == NULL)
65*c8fc8264SDoug Lyons {
66*c8fc8264SDoug Lyons skip("Could not lock resource (%d). Exiting now\n", i);
67*c8fc8264SDoug Lyons return FALSE;
68*c8fc8264SDoug Lyons }
69*c8fc8264SDoug Lyons
70*c8fc8264SDoug Lyons fout = fopen(FileName, "wb");
71*c8fc8264SDoug Lyons fwrite(lpResLock, iSize, 1, fout);
72*c8fc8264SDoug Lyons fclose(fout);
73*c8fc8264SDoug Lyons return TRUE;
74*c8fc8264SDoug Lyons }
75*c8fc8264SDoug Lyons
768ec05f5fSBișoc George EXTRACTICONTESTS IconTests[] =
778ec05f5fSBișoc George {
788ec05f5fSBișoc George /* Executable file with icon */
798ec05f5fSBișoc George {L"%SystemRoot%\\System32\\cmd.exe", 1},
808ec05f5fSBișoc George
818ec05f5fSBișoc George /* Executable file without icon */
828ec05f5fSBișoc George {L"%SystemRoot%\\System32\\autochk.exe", 0},
838ec05f5fSBișoc George
848ec05f5fSBișoc George /* Non-existing files */
85*c8fc8264SDoug Lyons {L"%SystemRoot%\\non-existent-file.sdf", 0},
86*c8fc8264SDoug Lyons
87*c8fc8264SDoug Lyons /* Multiple icons in the same EXE file (18 icons) */
88*c8fc8264SDoug Lyons {L"%SystemRoot%\\explorer.exe", 18},
89*c8fc8264SDoug Lyons
90*c8fc8264SDoug Lyons /* Multiple icons in the same ICO file (6 icons)
91*c8fc8264SDoug Lyons * Per MS: If the file is an .ico file, the return value is 1. */
92*c8fc8264SDoug Lyons {L"sysicon.ico", 1},
93*c8fc8264SDoug Lyons
94*c8fc8264SDoug Lyons /* ICO file with both normal and PNG icons */
95*c8fc8264SDoug Lyons {L"ROS.ico", 0}
968ec05f5fSBișoc George };
978ec05f5fSBișoc George
START_TEST(ExtractIconEx)988ec05f5fSBișoc George START_TEST(ExtractIconEx)
998ec05f5fSBișoc George {
100*c8fc8264SDoug Lyons UINT i, nReturnedIcons, nExtractedIcons;
101*c8fc8264SDoug Lyons CHAR FileName[2][13] = { "ROS.ico", "sysicon.ico" };
1028ec05f5fSBișoc George
103*c8fc8264SDoug Lyons if (!ResourceToFile(2, FileName[0]))
104*c8fc8264SDoug Lyons return;
105*c8fc8264SDoug Lyons if (!ResourceToFile(3, FileName[1]))
106*c8fc8264SDoug Lyons return;
107*c8fc8264SDoug Lyons
108*c8fc8264SDoug Lyons /* Check count of icons returned */
1098ec05f5fSBișoc George for (i = 0; i < _countof(IconTests); ++i)
1108ec05f5fSBișoc George {
111*c8fc8264SDoug Lyons nReturnedIcons = ExtractIconExW(IconTests[i].pszFilePath, -1, NULL, NULL, 0);
112*c8fc8264SDoug Lyons ok(nReturnedIcons == IconTests[i].nIcons, "ExtractIconExW(%u): Expects %u icons, got %u\n", i, IconTests[i].nIcons, nReturnedIcons);
1138ec05f5fSBișoc George }
114*c8fc8264SDoug Lyons
115*c8fc8264SDoug Lyons /* Check if the 0th icon can be extracted successfully */
116*c8fc8264SDoug Lyons for (i = 0; i < _countof(IconTests); ++i)
117*c8fc8264SDoug Lyons {
118*c8fc8264SDoug Lyons nExtractedIcons = ExtractIconExW(IconTests[i].pszFilePath, 0, NULL, NULL, 1);
119*c8fc8264SDoug Lyons ok(nExtractedIcons == IconTests[i].nIcons, "ExtractIconExW(%u): Expects %u icons, got %u\n", i, IconTests[i].nIcons, nExtractedIcons);
120*c8fc8264SDoug Lyons }
121*c8fc8264SDoug Lyons
122*c8fc8264SDoug Lyons DeleteFileA(FileName[0]);
123*c8fc8264SDoug Lyons DeleteFileA(FileName[1]);
1248ec05f5fSBișoc George }
125