ReactOS 0.4.16-dev-980-g00983aa
PrivateExtractIcons.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS api tests
3 * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory
4 * PURPOSE: Test for PrivateExtractIcons
5 * PROGRAMMER: Hermes Belusca-Maito
6 * Doug Lyons <douglyons@douglyons.com>
7 */
8
9#include "precomp.h"
10#include <stdio.h>
11#include <versionhelpers.h>
12
14{
15 ICONINFO info = { 0 };
16
17 if (!hIco || !GetIconInfo(hIco, &info))
18 return FALSE;
19
20 DeleteObject(info.hbmMask);
21 if (info.hbmColor)
22 DeleteObject(info.hbmColor);
23 return TRUE;
24}
25
27{
29
30 return (Attribute != INVALID_FILE_ATTRIBUTES &&
31 !(Attribute & FILE_ATTRIBUTE_DIRECTORY));
32}
33
35{
36 FILE *fout;
37 HGLOBAL hData;
38 HRSRC hRes;
39 PVOID pResLock;
40 UINT iSize;
41
43 {
44 /* We should only be using %temp% paths, so deleting here should be OK */
45 printf("Deleting '%S' that already exists.\n", FileName);
47 }
48
50 if (hRes == NULL)
51 {
52 skip("Could not locate resource (%d). Exiting now\n", i);
53 return FALSE;
54 }
55
56 iSize = SizeofResource(NULL, hRes);
57
58 hData = LoadResource(NULL, hRes);
59 if (hData == NULL)
60 {
61 skip("Could not load resource (%d). Exiting now\n", i);
62 return FALSE;
63 }
64
65 // Lock the resource into global memory.
66 pResLock = LockResource(hData);
67 if (pResLock == NULL)
68 {
69 skip("Could not lock resource (%d). Exiting now\n", i);
70 return FALSE;
71 }
72
73 fout = _wfopen(FileName, L"wb");
74 fwrite(pResLock, iSize, 1, fout);
75 fclose(fout);
76 return TRUE;
77}
78
79static struct
80{
82 UINT cIcons; // Return value of the first icon group extracted (should be 1 if no error)
83 UINT cTotalIcons; // Return value of total icon groups in file
84 BOOL bhIconValid; // Whether or not the returned icon handle is not NULL.
85} IconTests[] =
86{
87 /* Executables with just one icon group */
88 {L"notepad.exe", 1, 1, TRUE},
89 {L"%SystemRoot%\\System32\\cmd.exe", 1, 1, TRUE},
90
91 /* Executable without icon groups */
92 {L"%SystemRoot%\\System32\\autochk.exe", 0, 0, FALSE},
93
94 /* Existing file (shell32 has 233 icon groups in ReactOS only) */
95 {L"%SystemRoot%\\System32\\shell32.dll", 1, 233, TRUE},
96
97 /* Non-existing files */
98 {L"%SystemRoot%\\non-existent-file.sdf", 0xFFFFFFFF, 0, FALSE},
99
100 /* Executable with 18 icon groups */
101 {L"%SystemRoot%\\explorer.exe", 1, 18, TRUE},
102
103 /* Icon group file containing 6 icons */
104 {L"%temp%\\sysicon.ico", 1, 1, TRUE},
105
106 /* Icon group file containing one PNG icon and one normal icon */
107 {L"%temp%\\ROS.ico", 1, 1, TRUE},
108
109 /* Executable file with bad 'Icon Group' but good 'Icons'.
110 * Windows explorer shows the program's icon correctly in WinXP/Win2K3
111 * but Windows 7 shows only a default icon. This is analogous
112 * to EXE's generated by older Watcom C/C++ versions. */
113 {L"%temp%\\cpimg2e.exe", 1, 1, TRUE},
115
116static struct
117{
120} IconFiles[] =
121{
122 {L"%temp%\\ROS.ico", IDR_ICONS_PNG},
123 {L"%temp%\\sysicon.ico", IDR_ICONS_NORMAL},
124 {L"%temp%\\cpimg2e.exe", IDR_EXE_NORMAL}
126
127void TestPairExtraction(void);
128
130{
131 HICON ahIcon;
132 UINT i, aIconId, cIcons, cIcoTotal;
133 WCHAR PathBuffer[MAX_PATH];
134 UINT Shell32WinIcoCount = IsWindowsVistaOrGreater() ? 326 : 239; /* 239 on W2K3SP2, 326 on Win10 */
135
136 /* Extract icons */
137 for (i = 0; i < _countof(IconFiles); ++i)
138 {
139 ExpandEnvironmentStringsW(IconFiles[i].FileName, PathBuffer, _countof(PathBuffer));
140
141 if (!ResourceToFile(IconFiles[i].ResourceId, PathBuffer))
142 goto Cleanup;
143 }
144
146
147 for (i = 0; i < _countof(IconTests); ++i)
148 {
149 /* Get total number of icon groups in file.
150 * None of the hard numbers in the function matter since we have
151 * two NULLs for the Icon Handle and Count to be set. */
152 cIcoTotal = PrivateExtractIconsW(IconTests[i].FilePath, 0, 16, 16, NULL, NULL, 0, 0);
153 ok((i == 3 ?
154 cIcoTotal > 232 && cIcoTotal <= Shell32WinIcoCount : /* shell32 case: ROS has 233, Windows has >= 239 icon groups. */
155 cIcoTotal == IconTests[i].cTotalIcons),
156 "PrivateExtractIconsW(%u): "
157 "got %u, expected %u\n", i, cIcoTotal, IconTests[i].cTotalIcons);
158
159 /* Always test extraction of the FIRST icon (index 0) */
160 ahIcon = (HICON)UlongToHandle(0xdeadbeef);
161 aIconId = 0xdeadbeef;
162 cIcons = PrivateExtractIconsW(IconTests[i].FilePath, 0, 16, 16, &ahIcon, &aIconId, 1, 0);
163 ok(cIcons == IconTests[i].cIcons, "PrivateExtractIconsW(%u): got %u, expected %u\n", i, cIcons, IconTests[i].cIcons);
164 ok(ahIcon != (HICON)UlongToHandle(0xdeadbeef), "PrivateExtractIconsW(%u): icon not set\n", i);
165 ok((IconTests[i].bhIconValid && ahIcon) || (!IconTests[i].bhIconValid && !ahIcon),
166 "PrivateExtractIconsW(%u): icon expected to be %s, but got 0x%p\n",
167 i, IconTests[i].bhIconValid ? "valid" : "not valid", ahIcon);
168 if (cIcons == 0xFFFFFFFF)
169 {
170 ok(aIconId == 0xdeadbeef,
171 "PrivateExtractIconsW(%u): id should not be set to 0x%x\n",
172 i, aIconId);
173 }
174 else
175 {
176 ok(aIconId != 0xdeadbeef, "PrivateExtractIconsW(%u): id not set\n", i);
177 }
178 if (ahIcon && ahIcon != (HICON)UlongToHandle(0xdeadbeef))
179 DestroyIcon(ahIcon);
180 }
181
182Cleanup:
183 for (i = 0; i < _countof(IconFiles); ++i)
184 {
185 ExpandEnvironmentStringsW(IconFiles[i].FileName, PathBuffer, _countof(PathBuffer));
186 DeleteFileW(PathBuffer);
187 }
188}
189
190static const struct tagPAIRSTESTS
191{
193 BYTE UseHigh; // Extract a pair (high and low word sizes)
199} g_pairs[] =
200{
201 { 0, 0, 0, 1, 1, 1, 1 },
202 { 0, 0, 1, 0, 0, 0, 0 },
203 { 0, 1, 0, 1, 2, 1, 2 },
204 { 0, 1, 1, 0, 0, 0, 0 },
205 { 1, 0, 0, 1, 1, 1, 1 },
206 { 1, 0, 1, 1, 1, 1, 1 },
207 { 1, 1, 0, 1, 2, 1, 2 },
208 { 1, 1, 1, 2, 2, 0, 0 },
209 { 2, 0, 0, 1, 1, 1, 1 },
210 { 2, 0, 1, 2, 2, 2, 2 },
211 { 2, 1, 0, 1, 2, 1, 2 },
212 { 2, 1, 1, 2, 2, 2, 2 }, // This is the only way to extract a pair from a PE on NT6!
213 { 3, 0, 0, 1, 1, 1, 1 },
214 { 3, 0, 1, 3, 3, 3, 3 },
215 { 3, 1, 0, 1, 2, 1, 2 },
216 { 3, 1, 1, 4, 4, 0, 0 },
217 { 4, 0, 0, 1, 1, 1, 1 },
218 { 4, 0, 1, 4, 4, 4, 4 },
219 { 4, 1, 0, 1, 2, 1, 2 },
220 { 4, 1, 1, 4, 4, 4, 4 }
222
224{
225 const HICON hInvalidIcon = (HICON)(INT_PTR)-2;
226 const BOOL IsNT6 = IsWindowsVistaOrGreater();
227 for (UINT i = 0; i < _countof(g_pairs); ++i)
228 {
229 UINT j, Count, ExpectedCount;
230 int RetVal, ExpectedRet;
231 UINT IcoSize = MAKELONG(32, g_pairs[i].UseHigh ? 16 : 0);
232 PCWSTR pszPath = g_pairs[i].Library ? L"%SystemRoot%\\system32\\shell32.dll" : L"%temp%\\sysicon.ico";
233 HICON hIcons[8];
234 for (j = 0; j < _countof(hIcons); ++j)
235 hIcons[j] = hInvalidIcon;
236
237 RetVal = PrivateExtractIconsW(pszPath, 0, IcoSize, IcoSize, hIcons, NULL, g_pairs[i].InCount, 0);
238 for (j = 0, Count = 0; j < _countof(hIcons); ++j)
239 {
240 if (hIcons[j] != hInvalidIcon && IsValidIcon(hIcons[j]))
241 {
242 DestroyIcon(hIcons[j]);
243 ++Count;
244 }
245 }
246
247 ExpectedRet = !IsNT6 ? g_pairs[i].ReturnNT5 : g_pairs[i].ReturnNT6;
248 ExpectedCount = !IsNT6 ? g_pairs[i].CountNT5 : g_pairs[i].CountNT6;
249 ok(RetVal == ExpectedRet, "Test %u: RetVal must be %d but got %d\n", i, ExpectedRet, RetVal);
250 ok(Count == ExpectedCount, "Test %u: Count must be %u but got %u\n", i, ExpectedCount, Count);
251 }
252}
BOOL bhIconValid
static const struct tagPAIRSTESTS g_pairs[]
UINT cTotalIcons
BOOL IsValidIcon(HICON hIco)
INT ResourceId
PCWSTR FilePath
static struct @1641 IconFiles[]
BOOL ResourceToFile(INT i, PCWSTR FileName)
static struct @1640 IconTests[]
PCWSTR FileName
BOOL FileExists(PCWSTR FileName)
void TestPairExtraction(void)
UINT cIcons
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
#define START_TEST(x)
Definition: atltest.h:75
#define UlongToHandle(ul)
Definition: basetsd.h:97
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define MAX_PATH
Definition: compat.h:34
DWORD WINAPI ExpandEnvironmentStringsW(IN LPCWSTR lpSrc, IN LPWSTR lpDst, IN DWORD nSize)
Definition: environ.c:519
BOOL WINAPI DeleteFileW(IN LPCWSTR lpFileName)
Definition: delete.c:39
DWORD WINAPI GetFileAttributesW(LPCWSTR lpFileName)
Definition: fileinfo.c:652
HRSRC WINAPI FindResourceW(HINSTANCE hModule, LPCWSTR name, LPCWSTR type)
Definition: res.c:176
DWORD WINAPI SizeofResource(HINSTANCE hModule, HRSRC hRsrc)
Definition: res.c:568
LPVOID WINAPI LockResource(HGLOBAL handle)
Definition: res.c:550
HGLOBAL WINAPI LoadResource(HINSTANCE hModule, HRSRC hRsrc)
Definition: res.c:532
static const WCHAR Cleanup[]
Definition: register.c:80
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
#define printf
Definition: freeldr.h:97
pKey DeleteObject()
GLsizei GLuint * groups
Definition: glext.h:11113
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
_Check_return_ _CRTIMP FILE *__cdecl _wfopen(_In_z_ const wchar_t *_Filename, _In_z_ const wchar_t *_Mode)
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
_Check_return_opt_ _CRTIMP size_t __cdecl fwrite(_In_reads_bytes_(_Size *_Count) const void *_Str, _In_ size_t _Size, _In_ size_t _Count, _Inout_ FILE *_File)
#define IDR_ICONS_NORMAL
Definition: resource.h:5
#define IDR_ICONS_PNG
Definition: resource.h:4
#define IDR_EXE_NORMAL
Definition: resource.h:6
static HICON
Definition: imagelist.c:80
unsigned int UINT
Definition: ndis.h:50
int Count
Definition: noreturn.cpp:7
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
#define L(x)
Definition: ntvdm.h:50
#define RT_RCDATA
Definition: pedump.c:372
#define _countof(array)
Definition: sndvol32.h:70
int32_t INT_PTR
Definition: typedefs.h:64
const uint16_t * PCWSTR
Definition: typedefs.h:57
int32_t INT
Definition: typedefs.h:58
#define MAKELONG(a, b)
Definition: typedefs.h:249
VERSIONHELPERAPI IsWindowsVistaOrGreater()
#define INVALID_FILE_ATTRIBUTES
Definition: vfdcmd.c:23
BOOL WINAPI GetIconInfo(_In_ HICON, _Out_ PICONINFO)
Definition: cursoricon.c:2382
UINT WINAPI PrivateExtractIconsW(_In_reads_(MAX_PATH) LPCWSTR szFileName, _In_ int nIconIndex, _In_ int cxIcon, _In_ int cyIcon, _Out_writes_opt_(nIcons) HICON *phicon, _Out_writes_opt_(nIcons) UINT *piconid, _In_ UINT nIcons, _In_ UINT flags)
#define PrivateExtractIcons
Definition: winuser.h:5854
#define MAKEINTRESOURCEW(i)
Definition: winuser.h:582
BOOL WINAPI DestroyIcon(_In_ HICON)
Definition: cursoricon.c:2390
__wchar_t WCHAR
Definition: xmlstorage.h:180
unsigned char BYTE
Definition: xxhash.c:193