Skip to content

Commit 8c2b8c8

Browse files
committed
[VERSION_APITEST] Add tests for VerQueryValue(A/W)
1 parent eafa7c6 commit 8c2b8c8

File tree

5 files changed

+354
-0
lines changed

5 files changed

+354
-0
lines changed

modules/rostests/apitests/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ add_subdirectory(user32_dynamic)
5656
add_subdirectory(userenv)
5757
add_subdirectory(utildll)
5858
add_subdirectory(uxtheme)
59+
add_subdirectory(version)
5960
if(NOT CMAKE_BUILD_TYPE STREQUAL "Release")
6061
add_subdirectory(win32u)
6162
add_subdirectory(win32nt)
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
2+
list(APPEND SOURCE
3+
VerQueryValue.c
4+
precomp.h)
5+
6+
list(APPEND PCH_SKIP_SOURCE
7+
testlist.c)
8+
9+
add_executable(version_apitest
10+
${SOURCE}
11+
${PCH_SKIP_SOURCE})
12+
13+
target_link_libraries(version_apitest wine uuid ${PSEH_LIB})
14+
set_module_type(version_apitest win32cui)
15+
add_importlibs(version_apitest version msvcrt kernel32 ntdll)
16+
add_pch(version_apitest precomp.h "${PCH_SKIP_SOURCE}")
17+
18+
add_rostests_file(TARGET version_apitest)
Lines changed: 302 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,302 @@
1+
/*
2+
* PROJECT: ReactOS API Tests
3+
* LICENSE: MIT (https://spdx.org/licenses/MIT)
4+
* PURPOSE: Tests for VerQueryValue[A/W]
5+
* COPYRIGHT: Copyright 2024 Timo Kreuzer <[email protected]>
6+
*/
7+
8+
#include "precomp.h"
9+
10+
typedef struct
11+
{
12+
WORD wLength;
13+
WORD wValueLength;
14+
WORD wType;
15+
WCHAR szKey[16]; // L"VS_VERSION_INFO"
16+
WORD Padding1;
17+
VS_FIXEDFILEINFO Value;
18+
19+
struct _StringFileInfo
20+
{
21+
WORD wLength;
22+
WORD wValueLength;
23+
WORD wType;
24+
WCHAR szKey[15]; // L"StringFileInfo"
25+
26+
struct _StringTable
27+
{
28+
WORD wLength;
29+
WORD wValueLength;
30+
WORD wType;
31+
WCHAR szKey[9]; // L"000004B"
32+
33+
struct _String_CompanyName
34+
{
35+
WORD wLength;
36+
WORD wValueLength;
37+
WORD wType;
38+
WCHAR szKey[12]; // L"CompanyName"
39+
WORD Padding1;
40+
WCHAR Value[16]; // L"ReactOS Project"
41+
} CompanyName;
42+
43+
struct _String_Comments
44+
{
45+
WORD wLength;
46+
WORD wValueLength; // 0
47+
WORD wType;
48+
WCHAR szKey[9]; // L"Comments"
49+
} Comments;
50+
51+
struct _String_Comments2
52+
{
53+
WORD wLength;
54+
WORD wValueLength; // 0
55+
WORD wType;
56+
WCHAR szKey[10]; // L"Comments2"
57+
WORD Padding;
58+
} Comments2;
59+
60+
struct _String_FooBar
61+
{
62+
WORD wLength;
63+
WORD wValueLength;
64+
WORD wType;
65+
WCHAR szKey[7]; // L"FooBar"
66+
WCHAR Value[4]; // L"Bar"
67+
} FooBar;
68+
69+
} StringTable;
70+
} StringFileInfo;
71+
} TEST_VERSIONINFO;
72+
73+
static const TEST_VERSIONINFO g_VersionInfo =
74+
{
75+
.wLength = 298, // Header: 40, Value: 54, StringFileInfo: 204
76+
.wValueLength = sizeof(VS_FIXEDFILEINFO),
77+
.wType = 0,
78+
.szKey = L"VS_VERSION_INFO",
79+
.Padding1 = 0,
80+
.Value =
81+
{
82+
.dwSignature = VS_FFI_SIGNATURE,
83+
.dwStrucVersion = VS_FFI_STRUCVERSION,
84+
.dwFileVersionMS = 0x00050002,
85+
.dwFileVersionLS = 0x0ECE0000,
86+
.dwProductVersionMS = 0x00050002,
87+
.dwProductVersionLS = 0x0ECE0000,
88+
.dwFileFlagsMask = 0x00000002,
89+
.dwFileFlags = 0x00000000,
90+
.dwFileOS = VOS__WINDOWS32,
91+
.dwFileType = VFT_APP,
92+
.dwFileSubtype = VFT2_UNKNOWN,
93+
.dwFileDateMS = 0x00020074,
94+
.dwFileDateLS = 0x00000000,
95+
},
96+
.StringFileInfo =
97+
{
98+
.wLength = 204, // Header: 36, StringTable: 168
99+
.wValueLength = 0,
100+
.wType = 1,
101+
.szKey = L"StringFileInfo",
102+
.StringTable =
103+
{
104+
.wLength = 168, //Header: 24, Children: 144
105+
.wValueLength = 0,
106+
.wType = 1,
107+
.szKey = L"000004B0",
108+
109+
.CompanyName =
110+
{
111+
.wLength = 64,
112+
.wValueLength = 16,
113+
.wType = 1,
114+
.szKey = L"CompanyName",
115+
.Padding1 = 0,
116+
.Value = L"ReactOS Project",
117+
},
118+
.Comments =
119+
{
120+
.wLength = 24,
121+
.wValueLength = 0,
122+
.wType = 1,
123+
.szKey = L"Comments",
124+
},
125+
.Comments2 =
126+
{
127+
.wLength = 28,
128+
.wValueLength = 0,
129+
.wType = 1,
130+
.szKey = L"Comments2",
131+
.Padding = 0xCC,
132+
},
133+
.FooBar =
134+
{
135+
.wLength = 28,
136+
.wValueLength = 4,
137+
.wType = 1,
138+
.szKey = L"FooBar",
139+
.Value = L"Bar",
140+
},
141+
},
142+
},
143+
};
144+
145+
void
146+
Test_VerQueryValueA(void)
147+
{
148+
DWORD dwVersionInfoSizeW, dwVersionInfoSizeA;
149+
PVOID pvVersionInfoA, pvData = NULL;
150+
CHAR szSubBlock[256];
151+
USHORT uLanguage, uCodePage;
152+
UINT cbLen;
153+
BOOL result;
154+
155+
/* Get the size for the unicode version info */
156+
dwVersionInfoSizeW = GetFileVersionInfoSizeW(L"kernel32.dll", NULL);
157+
ok(dwVersionInfoSizeW > 0, "GetFileVersionInfoSizeW failed\n");
158+
159+
/* Get the size for the ANSI version info */
160+
dwVersionInfoSizeA = GetFileVersionInfoSizeA("kernel32.dll", NULL);
161+
ok(dwVersionInfoSizeA > 0, "GetFileVersionInfoSizeA failed\n");
162+
ok(dwVersionInfoSizeA == dwVersionInfoSizeW, "Unexpected size\n");
163+
164+
/* Get the ANSI version info from kernel32 */
165+
pvVersionInfoA = malloc(dwVersionInfoSizeA);
166+
memset(pvVersionInfoA, 0xCC, dwVersionInfoSizeA);
167+
result = GetFileVersionInfoA("kernel32.dll", 0, dwVersionInfoSizeA, pvVersionInfoA);
168+
ok(result, "GetFileVersionInfoA failed\n");
169+
170+
/* Query available translations */
171+
result = VerQueryValueA(pvVersionInfoA,
172+
"\\VarFileInfo\\Translation",
173+
&pvData,
174+
&cbLen);
175+
ok(result, "VerQueryValueA failed\n");
176+
ok(cbLen >= 4, "Unexpected value\n");
177+
ok((cbLen & 0x3) == 0, "Unexpected value\n");
178+
uLanguage = ((USHORT*)pvData)[0];
179+
uCodePage = ((USHORT*)pvData)[1];
180+
181+
/* Query sublock */
182+
sprintf(szSubBlock, "\\StringFileInfo\\%04X%04X\\CompanyName", uLanguage, uCodePage);
183+
result = VerQueryValueA(pvVersionInfoA,
184+
szSubBlock,
185+
&pvData,
186+
&cbLen);
187+
ok(result, "VerQueryValueA failed\n");
188+
ok(cbLen >= 2, "Unexpected value\n");
189+
ok((cbLen & 0x1) == 0, "Unexpected value\n");
190+
191+
free(pvVersionInfoA);
192+
}
193+
194+
void
195+
Test_VerQueryValueW(void)
196+
{
197+
DWORD dwVersionInfoSizeW;
198+
PVOID pvVersionInfoW, pvData = NULL;
199+
WCHAR szSubBlock[256];
200+
USHORT uLanguage, uCodePage;
201+
UINT cbLen;
202+
BOOL result;
203+
204+
/* Get the size for the unicode version info */
205+
dwVersionInfoSizeW = GetFileVersionInfoSizeW(L"kernel32.dll", NULL);
206+
ok(dwVersionInfoSizeW > 0, "GetFileVersionInfoSizeW failed\n");
207+
208+
/* Get the unicode version info from kernel32 */
209+
pvVersionInfoW = malloc(dwVersionInfoSizeW);
210+
result = GetFileVersionInfoW(L"kernel32.dll", 0, dwVersionInfoSizeW, pvVersionInfoW);
211+
ok(result, "GetFileVersionInfoW failed\n");
212+
213+
/* Query available translations */
214+
result = VerQueryValueW(pvVersionInfoW,
215+
L"\\VarFileInfo\\Translation",
216+
&pvData,
217+
&cbLen);
218+
ok(result, "VerQueryValueA failed\n");
219+
ok(cbLen >= 4, "Unexpected value\n");
220+
ok((cbLen & 0x3) == 0, "Unexpected value\n");
221+
uLanguage = ((USHORT*)pvData)[0];
222+
uCodePage = ((USHORT*)pvData)[1];
223+
224+
/* Query sublock */
225+
_swprintf(szSubBlock, L"\\StringFileInfo\\%04X%04X\\CompanyName", uLanguage, uCodePage);
226+
result = VerQueryValueW(pvVersionInfoW,
227+
szSubBlock,
228+
&pvData,
229+
&cbLen);
230+
ok(result, "VerQueryValueA failed\n");
231+
ok(cbLen >= 2, "Unexpected value\n");
232+
ok((cbLen & 0x1) == 0, "Unexpected value\n");
233+
234+
free(pvVersionInfoW);
235+
}
236+
237+
void
238+
Test_StaticVersionInfo(void)
239+
{
240+
PVOID pVersionInfo;
241+
PVOID pvData = NULL;
242+
SIZE_T ExpectedOffset;
243+
UINT cbLen;
244+
BOOL result;
245+
246+
/* Make a copy of the version info. Windows actually writes to it!
247+
We make the buffer twice as big to account for the ANSI copy,
248+
even if we don't use it. */
249+
pVersionInfo = malloc(2 * sizeof(g_VersionInfo));
250+
memset(pVersionInfo, 0, 2 * sizeof(g_VersionInfo));
251+
memcpy(pVersionInfo, &g_VersionInfo, sizeof(g_VersionInfo));
252+
253+
/* Test a special static version */
254+
result = VerQueryValueW(pVersionInfo,
255+
L"\\StringFileInfo\\000004B0\\CompanyName",
256+
&pvData,
257+
&cbLen);
258+
ok(result, "VerQueryValueW failed\n");
259+
ok_eq_int(cbLen, 16);
260+
ok_eq_wstr((WCHAR*)pvData, L"ReactOS Project");
261+
ExpectedOffset = FIELD_OFFSET(TEST_VERSIONINFO, StringFileInfo.StringTable.CompanyName.Value);
262+
ok(pvData == (PVOID)((ULONG_PTR)pVersionInfo + ExpectedOffset), "Unexpected offset\n");
263+
264+
result = VerQueryValueW(pVersionInfo,
265+
L"\\StringFileInfo\\000004B0\\Comments",
266+
&pvData,
267+
&cbLen);
268+
ok(result, "VerQueryValueW failed\n");
269+
ok_eq_int(cbLen, 0);
270+
ok_eq_wstr((WCHAR*)pvData, L"");
271+
ExpectedOffset = FIELD_OFFSET(TEST_VERSIONINFO, StringFileInfo.StringTable.Comments.szKey[8]);
272+
ok(pvData == (PVOID)((ULONG_PTR)pVersionInfo + ExpectedOffset), "Unexpected offset\n");
273+
274+
result = VerQueryValueW(pVersionInfo,
275+
L"\\StringFileInfo\\000004B0\\Comments2",
276+
&pvData,
277+
&cbLen);
278+
ok(result, "VerQueryValueW failed\n");
279+
ok_eq_int(cbLen, 0);
280+
ok_eq_wstr((WCHAR*)pvData, L"");
281+
ExpectedOffset = FIELD_OFFSET(TEST_VERSIONINFO, StringFileInfo.StringTable.Comments2.szKey[9]);
282+
ok(pvData == (PVOID)((ULONG_PTR)pVersionInfo + ExpectedOffset), "Unexpected offset\n");
283+
284+
result = VerQueryValueW(pVersionInfo,
285+
L"\\StringFileInfo\\000004B0\\FooBar",
286+
&pvData,
287+
&cbLen);
288+
ok(result, "VerQueryValueW failed\n");
289+
ok_eq_int(cbLen, 4);
290+
ok(wcscmp((WCHAR*)pvData, L"Bar") == 0, "Bar\n");
291+
ExpectedOffset = FIELD_OFFSET(TEST_VERSIONINFO, StringFileInfo.StringTable.FooBar.Value);
292+
ok(pvData == (PVOID)((ULONG_PTR)pVersionInfo + ExpectedOffset), "Unexpected offset\n");
293+
294+
free(pVersionInfo);
295+
}
296+
297+
START_TEST(VerQueryValue)
298+
{
299+
Test_VerQueryValueA();
300+
Test_VerQueryValueW();
301+
Test_StaticVersionInfo();
302+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#pragma once
2+
3+
#include <stdio.h>
4+
5+
#define WIN32_NO_STATUS
6+
#define _INC_WINDOWS
7+
#define COM_NO_WINDOWS_H
8+
9+
#include <apitest.h>
10+
#include <apitest_guard.h>
11+
#include <ndk/ntndk.h>
12+
#include <strsafe.h>
13+
#include <pseh/pseh2.h>
14+
#include <verrsrc.h>
15+
#include <winver.h>
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/*
2+
* PROJECT: ReactOS API Tests
3+
* LICENSE: MIT (https://spdx.org/licenses/MIT)
4+
* PURPOSE: Tests for version.dll
5+
* COPYRIGHT: Copyright 2024 Timo Kreuzer <[email protected]>
6+
*/
7+
8+
#define STANDALONE
9+
#include <apitest.h>
10+
11+
extern void func_VerQueryValue(void);
12+
13+
const struct test winetest_testlist[] =
14+
{
15+
{ "VerQueryValue", func_VerQueryValue },
16+
17+
{ 0, 0 }
18+
};

0 commit comments

Comments
 (0)