ReactOS 0.4.16-dev-197-g92996da
VerQueryValue.c
Go to the documentation of this file.
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 <timo.kreuzer@reactos.org>
6 */
7
8#include "precomp.h"
9
10typedef struct
11{
15 WCHAR szKey[16]; // L"VS_VERSION_INFO"
18
20 {
24 WCHAR szKey[15]; // L"StringFileInfo"
25
27 {
31 WCHAR szKey[9]; // L"000004B"
32
34 {
38 WCHAR szKey[12]; // L"CompanyName"
40 WCHAR Value[16]; // L"ReactOS Project"
41 } CompanyName;
42
44 {
48 WCHAR szKey[9]; // L"Comments"
49 } Comments;
50
52 {
56 WCHAR szKey[10]; // L"Comments2"
58 } Comments2;
59
61 {
65 WCHAR szKey[7]; // L"FooBar"
66 WCHAR Value[4]; // L"Bar"
67 } FooBar;
68
69 } StringTable;
70 } StringFileInfo;
72
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
145void
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
194void
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
237void
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
298{
302}
void Test_VerQueryValueA(void)
void Test_StaticVersionInfo(void)
void Test_VerQueryValueW(void)
static const TEST_VERSIONINFO g_VersionInfo
Definition: VerQueryValue.c:73
#define ok_eq_wstr(value, expected)
Definition: apitest.h:84
#define ok_eq_int(value, expected)
Definition: apitest.h:60
#define ok(value,...)
Definition: atltest.h:57
#define START_TEST(x)
Definition: atltest.h:75
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#define NULL
Definition: types.h:112
struct tagVS_FIXEDFILEINFO VS_FIXEDFILEINFO
DWORD WINAPI GetFileVersionInfoSizeA(LPCSTR filename, LPDWORD handle)
Definition: version.c:619
BOOL WINAPI VerQueryValueA(LPCVOID pBlock, LPCSTR lpSubBlock, LPVOID *lplpBuffer, PUINT puLen)
Definition: version.c:1001
BOOL WINAPI GetFileVersionInfoW(LPCWSTR filename, DWORD handle, DWORD datasize, LPVOID data)
Definition: version.c:845
BOOL WINAPI GetFileVersionInfoA(LPCSTR filename, DWORD handle, DWORD datasize, LPVOID data)
Definition: version.c:853
BOOL WINAPI VerQueryValueW(LPCVOID pBlock, LPCWSTR lpSubBlock, LPVOID *lplpBuffer, PUINT puLen)
Definition: version.c:1057
DWORD WINAPI GetFileVersionInfoSizeW(LPCWSTR filename, LPDWORD handle)
Definition: version.c:611
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
GLuint64EXT * result
Definition: glext.h:11304
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
int _swprintf(wchar_t *buffer, const wchar_t *format,...)
#define sprintf(buf, format,...)
Definition: sprintf.c:55
unsigned int UINT
Definition: ndis.h:50
#define L(x)
Definition: ntvdm.h:50
unsigned short USHORT
Definition: pedump.c:61
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
#define memset(x, y, z)
Definition: compat.h:39
VS_FIXEDFILEINFO Value
Definition: VerQueryValue.c:17
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define VFT2_UNKNOWN
Definition: verrsrc.h:84
#define VS_FFI_SIGNATURE
Definition: verrsrc.h:37
#define VS_FFI_STRUCVERSION
Definition: verrsrc.h:38
#define VOS__WINDOWS32
Definition: verrsrc.h:64
#define VFT_APP
Definition: verrsrc.h:75
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413
_In_ ULONG _In_opt_ PVOID pvData
Definition: winddi.h:3749
#define VerQueryValue
Definition: winver.h:56
__wchar_t WCHAR
Definition: xmlstorage.h:180
char CHAR
Definition: xmlstorage.h:175