Reactos
1/*
2 * Unit test suite for version functions
3 *
4 * Copyright 2006 Robert Shearman
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21#include "ntstatus.h"
22#define WIN32_NO_STATUS
23#include "wine/test.h"
24#include "winbase.h"
25#include "winternl.h"
26#include "appmodel.h"
27
28static BOOL (WINAPI * pGetProductInfo)(DWORD, DWORD, DWORD, DWORD, DWORD *);
29static UINT (WINAPI * pEnumSystemFirmwareTables)(DWORD, void *, DWORD);
30static UINT (WINAPI * pGetSystemFirmwareTable)(DWORD, DWORD, void *, DWORD);
31static LONG (WINAPI * pPackageIdFromFullName)(const WCHAR *, UINT32, UINT32 *, BYTE *);
32static NTSTATUS (WINAPI * pNtQuerySystemInformation)(SYSTEM_INFORMATION_CLASS, void *, ULONG, ULONG *);
33static NTSTATUS (WINAPI * pRtlGetVersion)(RTL_OSVERSIONINFOEXW *);
34
35#define GET_PROC(func) \
36 p##func = (void *)GetProcAddress(hmod, #func);
37
38/* Firmware table providers */
39#define ACPI 0x41435049
40#define FIRM 0x4649524D
41#define RSMB 0x52534D42
42
43static void init_function_pointers(void)
44{
45 HMODULE hmod;
46
47 hmod = GetModuleHandleA("kernel32.dll");
48
49 GET_PROC(GetProductInfo);
50 GET_PROC(EnumSystemFirmwareTables);
51 GET_PROC(GetSystemFirmwareTable);
52 GET_PROC(PackageIdFromFullName);
53
54 hmod = GetModuleHandleA("ntdll.dll");
55
56 GET_PROC(NtQuerySystemInformation);
57 GET_PROC(RtlGetVersion);
58}
59
60static void test_GetProductInfo(void)
61{
62 DWORD product;
63 DWORD res;
64 DWORD table[] = {9,8,7,6,
65 7,0,0,0,
66 6,2,0,0,
67 6,1,2,0,
68 6,1,1,0,
69 6,1,0,2,
70 6,1,0,0,
71 6,0,3,0,
72 6,0,2,0,
73 6,0,1,5,
74 6,0,1,0,
75 6,0,0,0,
76 5,3,0,0,
77 5,2,0,0,
78 5,1,0,0,
79 5,0,0,0,
80 0};
81
82 DWORD *entry = table;
83
84#if defined(__REACTOS__) && DLL_EXPORT_VERSION >= 0x600
85 /* FIXME: GetProductInfo is a STUB on ReactOS */
86 if (is_reactos() || !pGetProductInfo)
87#else
88 if (!pGetProductInfo)
89#endif
90 {
91 /* Not present before Vista */
92 win_skip("GetProductInfo() not available\n");
93 return;
94 }
95
96 while (*entry)
97 {
98 /* SetLastError() / GetLastError(): value is untouched */
99 product = 0xdeadbeef;
100 SetLastError(0xdeadbeef);
101 res = pGetProductInfo(entry[0], entry[1], entry[2], entry[3], &product);
102
103 if (entry[0] >= 6)
104 ok(res && (product > PRODUCT_UNDEFINED) && (product <= PRODUCT_ENTERPRISE_S_N_EVALUATION),
105 "got %ld and 0x%lx (expected TRUE and a valid PRODUCT_* value)\n", res, product);
106 else
107 ok(!res && !product && (GetLastError() == 0xdeadbeef),
108 "got %ld and 0x%lx with 0x%lx (expected FALSE and PRODUCT_UNDEFINED with LastError untouched)\n",
109 res, product, GetLastError());
110
111 entry+= 4;
112 }
113
114 /* NULL pointer is not a problem */
115 SetLastError(0xdeadbeef);
116 res = pGetProductInfo(6, 1, 0, 0, NULL);
117 ok( (!res) && (GetLastError() == 0xdeadbeef),
118 "got %ld with 0x%lx (expected FALSE with LastError untouched\n", res, GetLastError());
119}
120
121static void test_GetVersionEx(void)
122{
123 OSVERSIONINFOA infoA;
124 OSVERSIONINFOEXA infoExA;
125 BOOL ret;
126
127 if (0)
128 {
129 /* Silently crashes on XP */
130 GetVersionExA(NULL);
131 }
132
133 SetLastError(0xdeadbeef);
134 memset(&infoA,0,sizeof infoA);
135 ret = GetVersionExA(&infoA);
136 ok(!ret, "Expected GetVersionExA to fail\n");
137 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER ||
138 GetLastError() == 0xdeadbeef /* Win9x */,
139 "Expected ERROR_INSUFFICIENT_BUFFER or 0xdeadbeef (Win9x), got %ld\n",
140 GetLastError());
141
142 SetLastError(0xdeadbeef);
143 infoA.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA) / 2;
144 ret = GetVersionExA(&infoA);
145 ok(!ret, "Expected GetVersionExA to fail\n");
146 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER ||
147 GetLastError() == 0xdeadbeef /* Win9x */,
148 "Expected ERROR_INSUFFICIENT_BUFFER or 0xdeadbeef (Win9x), got %ld\n",
149 GetLastError());
150
151 SetLastError(0xdeadbeef);
152 infoA.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA) * 2;
153 ret = GetVersionExA(&infoA);
154 ok(!ret, "Expected GetVersionExA to fail\n");
155 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER ||
156 GetLastError() == 0xdeadbeef /* Win9x */,
157 "Expected ERROR_INSUFFICIENT_BUFFER or 0xdeadbeef (Win9x), got %ld\n",
158 GetLastError());
159
160 SetLastError(0xdeadbeef);
161 infoA.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
162 ret = GetVersionExA(&infoA);
163 ok(ret, "Expected GetVersionExA to succeed\n");
164 ok(GetLastError() == 0xdeadbeef,
165 "Expected 0xdeadbeef, got %ld\n", GetLastError());
166
167 SetLastError(0xdeadbeef);
168 infoExA.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA);
169 ret = GetVersionExA((OSVERSIONINFOA *)&infoExA);
170 ok(ret, "GetVersionExA failed.\n");
171
172 if (!infoExA.wServicePackMajor && !infoExA.wServicePackMinor)
173 ok(!infoExA.szCSDVersion[0], "got '%s'\n", infoExA.szCSDVersion);
174}
175
176static void test_VerifyVersionInfo(void)
177{
178 enum srcversion_mode
179 {
180 SRCVERSION_ZERO = 0,
181 SRCVERSION_CURRENT = 1,
182 SRCVERSION_INC_MINOR = 2,
183 SRCVERSION_INC_SP_MINOR = 3,
184 SRCVERSION_INC_SP_MAJOR = 4,
185 SRCVERSION_DEC_SP_MAJOR = 5,
186 SRCVERSION_DEC_MAJOR = 6,
187 SRCVERSION_INC_BUILD = 7,
188 SRCVERSION_REQUIRES_SP = 0x1000,
189 };
190
191 struct verify_version_test
192 {
193 DWORD verifymask; /* Type mask for VerifyVersionInfo() */
194 DWORD srcinfo; /* The way current version info is modified. */
195 DWORD err; /* Error code on failure, 0 on success. */
196
197 DWORD typemask1;
198 DWORD condition1;
199 DWORD typemask2;
200 DWORD condition2;
201 DWORD typemask3;
202 DWORD condition3;
203 DWORD typemask4;
204 DWORD condition4;
205 } verify_version_tests[] =
206 {
207 {
208 VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
209 SRCVERSION_INC_MINOR,
210 0,
211
212 VER_MAJORVERSION, VER_EQUAL,
213 VER_MINORVERSION, VER_LESS,
214 },
215 {
216 VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
217 SRCVERSION_INC_MINOR,
218 ERROR_OLD_WIN_VERSION,
219
220 VER_MAJORVERSION, VER_GREATER_EQUAL,
221 VER_MINORVERSION, VER_LESS,
222 },
223 {
224 VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
225 SRCVERSION_CURRENT,
226 0,
227
228 VER_MAJORVERSION, VER_GREATER_EQUAL,
229 VER_MINORVERSION, VER_LESS,
230 },
231 {
232 VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
233 SRCVERSION_CURRENT,
234 0,
235
236 VER_MAJORVERSION, VER_GREATER_EQUAL,
237 VER_MINORVERSION, VER_AND,
238 },
239 {
240 VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
241 SRCVERSION_INC_MINOR,
242 0,
243
244 VER_MAJORVERSION, VER_LESS_EQUAL,
245 VER_MINORVERSION, VER_LESS,
246 },
247 {
248 VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
249 SRCVERSION_INC_MINOR,
250 ERROR_OLD_WIN_VERSION,
251
252 VER_MAJORVERSION, VER_AND,
253 VER_MINORVERSION, VER_LESS,
254 },
255 {
256 VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
257 SRCVERSION_INC_MINOR,
258 ERROR_OLD_WIN_VERSION,
259
260 VER_MAJORVERSION, VER_OR,
261 VER_MINORVERSION, VER_LESS,
262 },
263 {
264 VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
265 SRCVERSION_INC_SP_MINOR,
266 ERROR_OLD_WIN_VERSION,
267
268 VER_MINORVERSION, VER_EQUAL,
269 VER_SERVICEPACKMINOR, VER_LESS,
270 },
271 {
272 VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
273 SRCVERSION_INC_SP_MINOR,
274 ERROR_OLD_WIN_VERSION,
275
276 VER_MAJORVERSION, VER_EQUAL,
277 VER_SERVICEPACKMINOR, VER_LESS,
278 },
279 {
280 VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
281 SRCVERSION_INC_SP_MAJOR,
282 ERROR_OLD_WIN_VERSION,
283
284 VER_MAJORVERSION, VER_EQUAL,
285 VER_SERVICEPACKMAJOR, VER_EQUAL,
286 },
287 {
288 VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
289 SRCVERSION_INC_SP_MINOR,
290 0,
291
292 VER_SERVICEPACKMAJOR, VER_EQUAL,
293 VER_SERVICEPACKMINOR, VER_LESS,
294 },
295 {
296 VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
297 SRCVERSION_INC_SP_MINOR,
298 ERROR_OLD_WIN_VERSION,
299
300 VER_SERVICEPACKMAJOR, VER_EQUAL,
301 VER_SERVICEPACKMINOR, VER_LESS,
302 },
303 {
304 VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
305 SRCVERSION_INC_SP_MINOR,
306 0,
307
308 VER_MINORVERSION, VER_EQUAL,
309 VER_SERVICEPACKMAJOR, VER_EQUAL,
310 VER_SERVICEPACKMINOR, VER_LESS,
311 },
312 {
313 VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
314 SRCVERSION_INC_SP_MINOR,
315 ERROR_OLD_WIN_VERSION,
316
317 VER_MINORVERSION, VER_EQUAL,
318 VER_SERVICEPACKMAJOR, VER_EQUAL,
319 VER_SERVICEPACKMINOR, VER_LESS,
320 },
321 {
322 VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
323 SRCVERSION_INC_SP_MINOR,
324 0,
325
326 VER_MAJORVERSION, VER_EQUAL,
327 VER_MINORVERSION, VER_EQUAL,
328 VER_SERVICEPACKMAJOR, VER_EQUAL,
329 VER_SERVICEPACKMINOR, VER_LESS,
330 },
331 {
332 VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
333 SRCVERSION_INC_SP_MINOR,
334 ERROR_OLD_WIN_VERSION,
335
336 VER_MAJORVERSION, VER_EQUAL,
337 VER_MINORVERSION, VER_GREATER_EQUAL,
338 VER_SERVICEPACKMAJOR, VER_EQUAL,
339 VER_SERVICEPACKMINOR, VER_LESS,
340 },
341 {
342 VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
343 SRCVERSION_INC_SP_MAJOR,
344 0,
345
346 VER_MAJORVERSION, VER_LESS_EQUAL,
347 VER_SERVICEPACKMAJOR, VER_GREATER,
348 },
349 {
350 VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
351 SRCVERSION_INC_SP_MAJOR,
352 ERROR_OLD_WIN_VERSION,
353
354 VER_MAJORVERSION, VER_EQUAL,
355 VER_SERVICEPACKMAJOR, VER_LESS,
356 },
357 {
358 VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
359 SRCVERSION_INC_SP_MAJOR,
360 ERROR_OLD_WIN_VERSION,
361
362 VER_MINORVERSION, VER_EQUAL,
363 VER_SERVICEPACKMAJOR, VER_LESS,
364 },
365 {
366 VER_MAJORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
367 SRCVERSION_INC_SP_MAJOR,
368 0,
369
370 VER_MAJORVERSION, VER_EQUAL,
371 VER_SERVICEPACKMAJOR, VER_LESS,
372 },
373 {
374 VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
375 SRCVERSION_INC_SP_MAJOR,
376 ERROR_OLD_WIN_VERSION,
377
378 VER_MAJORVERSION, VER_EQUAL,
379 VER_SERVICEPACKMAJOR, VER_LESS,
380 },
381 {
382 VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
383 SRCVERSION_INC_SP_MAJOR,
384 0,
385
386 VER_MAJORVERSION, VER_EQUAL,
387 VER_MINORVERSION, VER_EQUAL,
388 VER_SERVICEPACKMAJOR, VER_LESS,
389 },
390 {
391 VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
392 SRCVERSION_INC_SP_MAJOR,
393 ERROR_OLD_WIN_VERSION,
394
395 VER_MAJORVERSION, VER_GREATER_EQUAL,
396 VER_SERVICEPACKMAJOR, VER_LESS,
397 },
398 {
399 VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
400 SRCVERSION_DEC_MAJOR,
401 0,
402
403 VER_MAJORVERSION, VER_GREATER_EQUAL,
404 VER_SERVICEPACKMAJOR, VER_LESS,
405 },
406 {
407 VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
408 SRCVERSION_CURRENT,
409 0,
410
411 VER_MAJORVERSION, VER_GREATER_EQUAL,
412 VER_SERVICEPACKMAJOR, VER_LESS,
413 },
414 {
415 VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
416 SRCVERSION_INC_SP_MAJOR,
417 ERROR_OLD_WIN_VERSION,
418
419 VER_MAJORVERSION, VER_GREATER_EQUAL,
420 VER_MINORVERSION, VER_EQUAL,
421 VER_SERVICEPACKMAJOR, VER_LESS,
422 },
423 {
424 VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
425 SRCVERSION_INC_SP_MAJOR,
426 ERROR_OLD_WIN_VERSION,
427
428 VER_MAJORVERSION, VER_GREATER_EQUAL,
429 VER_MINORVERSION, VER_GREATER_EQUAL,
430 VER_SERVICEPACKMAJOR, VER_LESS_EQUAL,
431 },
432 {
433 VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
434 SRCVERSION_INC_SP_MAJOR,
435 ERROR_OLD_WIN_VERSION,
436
437 VER_MAJORVERSION, VER_GREATER_EQUAL,
438 VER_SERVICEPACKMAJOR, VER_AND,
439 },
440 {
441 VER_MAJORVERSION | VER_MINORVERSION,
442 SRCVERSION_ZERO,
443 0,
444
445 VER_MAJORVERSION, VER_GREATER_EQUAL,
446 },
447 {
448 VER_MAJORVERSION | VER_MINORVERSION | VER_BUILDNUMBER,
449 SRCVERSION_ZERO,
450 ERROR_OLD_WIN_VERSION,
451
452 VER_MAJORVERSION, VER_GREATER_EQUAL,
453 },
454 {
455 VER_SUITENAME,
456 SRCVERSION_ZERO,
457 0,
458
459 VER_SUITENAME, VER_AND,
460 },
461 {
462 VER_SUITENAME,
463 SRCVERSION_ZERO,
464 0,
465
466 VER_SUITENAME, VER_OR,
467 },
468 {
469 VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
470 SRCVERSION_INC_SP_MINOR,
471 ERROR_OLD_WIN_VERSION,
472
473 VER_MINORVERSION, VER_GREATER_EQUAL,
474 },
475 {
476 VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
477 SRCVERSION_INC_SP_MAJOR,
478 0,
479
480 VER_MINORVERSION, VER_LESS,
481 },
482 {
483 VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
484 SRCVERSION_INC_SP_MAJOR,
485 0,
486
487 VER_MINORVERSION, VER_LESS_EQUAL,
488 },
489 {
490 VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
491 SRCVERSION_INC_SP_MAJOR,
492 ERROR_OLD_WIN_VERSION,
493
494 VER_MINORVERSION, VER_EQUAL,
495 },
496 {
497 VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
498 SRCVERSION_INC_SP_MAJOR,
499 ERROR_OLD_WIN_VERSION,
500
501 VER_MINORVERSION, VER_GREATER_EQUAL,
502 },
503 {
504 VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
505 SRCVERSION_INC_MINOR,
506 ERROR_OLD_WIN_VERSION,
507
508 VER_MINORVERSION, VER_GREATER_EQUAL,
509 },
510 {
511 VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
512 SRCVERSION_INC_MINOR,
513 ERROR_OLD_WIN_VERSION,
514
515 VER_MINORVERSION, VER_GREATER_EQUAL,
516 },
517 {
518 VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
519 SRCVERSION_CURRENT,
520 0,
521
522 VER_MINORVERSION, VER_GREATER_EQUAL,
523 },
524 {
525 VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
526 SRCVERSION_INC_BUILD,
527 ERROR_OLD_WIN_VERSION,
528
529 VER_MINORVERSION, VER_GREATER_EQUAL,
530 },
531 {
532 VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
533 SRCVERSION_INC_BUILD,
534 0,
535
536 VER_MINORVERSION, VER_GREATER_EQUAL,
537 },
538 {
539 VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
540 SRCVERSION_DEC_SP_MAJOR | SRCVERSION_REQUIRES_SP,
541 0,
542
543 VER_MINORVERSION, VER_GREATER,
544 },
545 {
546 VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
547 SRCVERSION_DEC_SP_MAJOR | SRCVERSION_REQUIRES_SP,
548 0,
549
550 VER_MINORVERSION, VER_GREATER_EQUAL,
551 },
552 {
553 VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
554 SRCVERSION_DEC_SP_MAJOR | SRCVERSION_REQUIRES_SP,
555 ERROR_OLD_WIN_VERSION,
556
557 VER_MAJORVERSION, VER_EQUAL,
558 VER_SERVICEPACKMAJOR, VER_GREATER,
559 },
560 {
561 VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
562 SRCVERSION_DEC_SP_MAJOR | SRCVERSION_REQUIRES_SP,
563 0,
564
565 VER_MAJORVERSION, VER_GREATER_EQUAL,
566 VER_MINORVERSION, VER_EQUAL,
567 VER_SERVICEPACKMAJOR, VER_GREATER,
568 },
569 {
570 VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
571 SRCVERSION_DEC_SP_MAJOR | SRCVERSION_REQUIRES_SP,
572 0,
573
574 VER_MAJORVERSION, VER_GREATER_EQUAL,
575 VER_MINORVERSION, VER_LESS_EQUAL,
576 VER_SERVICEPACKMAJOR, VER_GREATER,
577 },
578 {
579 VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
580 SRCVERSION_DEC_SP_MAJOR | SRCVERSION_REQUIRES_SP,
581 0,
582
583 VER_MAJORVERSION, VER_GREATER_EQUAL,
584 VER_MINORVERSION, VER_AND,
585 VER_SERVICEPACKMAJOR, VER_GREATER,
586 },
587 {
588 VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
589 SRCVERSION_DEC_SP_MAJOR | SRCVERSION_REQUIRES_SP,
590 ERROR_OLD_WIN_VERSION,
591
592 VER_SERVICEPACKMAJOR, VER_GREATER,
593 VER_SERVICEPACKMINOR, VER_EQUAL,
594 },
595 };
596
597 OSVERSIONINFOEXA info;
598 DWORD servicepack;
599 unsigned int i;
600 BOOL ret;
601
602 /* Before we start doing some tests we should check what the version of
603 * the ServicePack is. Tests on a box with no ServicePack will fail otherwise.
604 */
605 info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA);
606 GetVersionExA((OSVERSIONINFOA *)&info);
607 servicepack = info.wServicePackMajor;
608 if (servicepack == 0)
609 skip("There is no ServicePack on this system. Some tests will be skipped.\n");
610
611 /* Win8.1+ returns Win8 version in GetVersionEx when there's no app manifest targeting 8.1 */
612 if (info.dwMajorVersion == 6 && info.dwMinorVersion == 2)
613 {
614 RTL_OSVERSIONINFOEXW rtlinfo;
615 rtlinfo.dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOEXW);
616 ok(!pRtlGetVersion(&rtlinfo), "RtlGetVersion failed\n");
617
618 if (rtlinfo.dwMajorVersion != 6 || rtlinfo.dwMinorVersion != 2)
619 {
620 skip("GetVersionEx and VerifyVersionInfo are faking values\n");
621 return;
622 }
623 }
624
625 for (i = 0; i < ARRAY_SIZE(verify_version_tests); i++)
626 {
627 struct verify_version_test *test = &verify_version_tests[i];
628 DWORD srcinfo = test->srcinfo;
629 ULONGLONG mask;
630
631 if (servicepack == 0 && srcinfo & SRCVERSION_REQUIRES_SP)
632 continue;
633 srcinfo &= ~SRCVERSION_REQUIRES_SP;
634
635 info.dwOSVersionInfoSize = sizeof(info);
636 GetVersionExA((OSVERSIONINFOA *)&info);
637
638 switch (srcinfo)
639 {
640 case SRCVERSION_ZERO:
641 memset(&info, 0, sizeof(info));
642 break;
643 case SRCVERSION_INC_MINOR:
644 info.dwMinorVersion++;
645 break;
646 case SRCVERSION_INC_SP_MINOR:
647 info.wServicePackMinor++;
648 break;
649 case SRCVERSION_INC_SP_MAJOR:
650 info.wServicePackMajor++;
651 break;
652 case SRCVERSION_DEC_SP_MAJOR:
653 info.wServicePackMajor--;
654 break;
655 case SRCVERSION_DEC_MAJOR:
656 info.dwMajorVersion--;
657 break;
658 case SRCVERSION_INC_BUILD:
659 info.dwBuildNumber++;
660 break;
661 default:
662 ;
663 }
664
665 mask = VerSetConditionMask(0, test->typemask1, test->condition1);
666 if (test->typemask2)
667 mask = VerSetConditionMask(mask, test->typemask2, test->condition2);
668 if (test->typemask3)
669 mask = VerSetConditionMask(mask, test->typemask3, test->condition3);
670 if (test->typemask4)
671 mask = VerSetConditionMask(mask, test->typemask4, test->condition4);
672
673 SetLastError(0xdeadbeef);
674 ret = VerifyVersionInfoA(&info, test->verifymask, mask);
675 ok(test->err ? !ret : ret, "%u: unexpected return value %d.\n", i, ret);
676 if (!ret)
677 ok(GetLastError() == test->err, "%u: unexpected error code %ld, expected %ld.\n", i, GetLastError(), test->err);
678 }
679
680 /* test handling of version numbers */
681 /* v3.10 is always less than v4.x even
682 * if the minor version is tested */
683 info.dwMajorVersion = 3;
684 info.dwMinorVersion = 10;
685 ret = VerifyVersionInfoA(&info, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
686 VerSetConditionMask(VerSetConditionMask(0, VER_MINORVERSION, VER_GREATER_EQUAL),
687 VER_MAJORVERSION, VER_GREATER_EQUAL));
688 ok(ret, "VerifyVersionInfoA failed with error %ld\n", GetLastError());
689
690 info.dwMinorVersion = 0;
691 info.wServicePackMajor = 10;
692 ret = VerifyVersionInfoA(&info, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
693 VerSetConditionMask(VerSetConditionMask(0, VER_MINORVERSION, VER_GREATER_EQUAL),
694 VER_MAJORVERSION, VER_GREATER_EQUAL));
695 ok(ret, "VerifyVersionInfoA failed with error %ld\n", GetLastError());
696
697 info.wServicePackMajor = 0;
698 info.wServicePackMinor = 10;
699 ret = VerifyVersionInfoA(&info, VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
700 VerSetConditionMask(VerSetConditionMask(0, VER_MINORVERSION, VER_GREATER_EQUAL),
701 VER_MAJORVERSION, VER_GREATER_EQUAL));
702 ok(ret, "VerifyVersionInfoA failed with error %ld\n", GetLastError());
703
704 /* test bad dwOSVersionInfoSize */
705 info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA);
706 GetVersionExA((OSVERSIONINFOA *)&info);
707 info.dwOSVersionInfoSize = 0;
708 ret = VerifyVersionInfoA(&info, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
709 VerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL));
710 ok(ret, "VerifyVersionInfoA failed with error %ld\n", GetLastError());
711}
712
713static void test_SystemFirmwareTable(void)
714{
715 static const ULONG min_sfti_len = FIELD_OFFSET(SYSTEM_FIRMWARE_TABLE_INFORMATION, TableBuffer);
716 ULONG expected_len;
717 UINT len;
718 NTSTATUS status;
719 SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti;
720 UCHAR *smbios_table;
721
722 if (!pGetSystemFirmwareTable || !pEnumSystemFirmwareTables)
723 {
724 win_skip("SystemFirmwareTable functions not available\n");
725 return;
726 }
727
728 sfti = HeapAlloc(GetProcessHeap(), 0, sizeof(*sfti));
729 ok(!!sfti, "Failed to allocate memory\n");
730 sfti->ProviderSignature = RSMB;
731 sfti->Action = SystemFirmwareTable_Get;
732 sfti->TableID = 0;
733 status = pNtQuerySystemInformation(SystemFirmwareTableInformation, sfti, min_sfti_len, &expected_len);
734 if (expected_len == 0) /* xp, 2003 */
735 {
736 win_skip("SystemFirmwareTableInformation is not available\n");
737 HeapFree(GetProcessHeap(), 0, sfti);
738 return;
739 }
740#ifdef __REACTOS__
741 ok( status == STATUS_BUFFER_TOO_SMALL || broken(status == STATUS_INVALID_DEVICE_REQUEST) /* Vista x64 ROS testbot */, "NtQuerySystemInformation failed %lx\n", status );
742#else
743 ok( status == STATUS_BUFFER_TOO_SMALL, "NtQuerySystemInformation failed %lx\n", status );
744#endif
745 sfti = HeapReAlloc(GetProcessHeap(), 0, sfti, expected_len);
746 status = pNtQuerySystemInformation(SystemFirmwareTableInformation, sfti, expected_len, &expected_len);
747#ifdef __REACTOS__
748 ok( !status || broken(status == STATUS_INVALID_DEVICE_REQUEST) /* Vista x64 ROS testbot */, "NtQuerySystemInformation failed %lx\n", status );
749#else
750 ok( !status, "NtQuerySystemInformation failed %lx\n", status );
751#endif
752
753 expected_len -= min_sfti_len;
754 ok( sfti->TableBufferLength == expected_len, "wrong len %lu/%lx\n",
755 sfti->TableBufferLength, expected_len );
756 len = pGetSystemFirmwareTable(RSMB, 0, NULL, 0);
757 ok(len == expected_len, "Expected length %lu, got %u\n", expected_len, len);
758
759 smbios_table = HeapAlloc(GetProcessHeap(), 0, expected_len);
760 len = pGetSystemFirmwareTable(RSMB, 0, smbios_table, expected_len);
761 ok(len == expected_len, "Expected length %lu, got %u\n", expected_len, len);
762 ok(len == 0 || !memcmp(smbios_table, sfti->TableBuffer, 6),
763 "Expected prologue %02x %02x %02x %02x %02x %02x, got %02x %02x %02x %02x %02x %02x\n",
764 sfti->TableBuffer[0], sfti->TableBuffer[1], sfti->TableBuffer[2],
765 sfti->TableBuffer[3], sfti->TableBuffer[4], sfti->TableBuffer[5],
766 smbios_table[0], smbios_table[1], smbios_table[2],
767 smbios_table[3], smbios_table[4], smbios_table[5]);
768 HeapFree(GetProcessHeap(), 0, smbios_table);
769
770 sfti->Action = SystemFirmwareTable_Enumerate;
771 status = pNtQuerySystemInformation(SystemFirmwareTableInformation, sfti, min_sfti_len, &expected_len);
772 ok( status == STATUS_BUFFER_TOO_SMALL, "NtQuerySystemInformation failed %lx\n", status );
773 sfti = HeapReAlloc(GetProcessHeap(), 0, sfti, expected_len);
774 status = pNtQuerySystemInformation(SystemFirmwareTableInformation, sfti, expected_len, &expected_len);
775 ok( !status, "NtQuerySystemInformation failed %lx\n", status );
776 ok( expected_len == min_sfti_len + sizeof(UINT), "wrong len %lu\n", expected_len );
777 ok( sfti->TableBufferLength == sizeof(UINT), "wrong len %lu\n", sfti->TableBufferLength );
778 ok( *(UINT *)sfti->TableBuffer == 0, "wrong table id %x\n", *(UINT *)sfti->TableBuffer );
779
780 len = pEnumSystemFirmwareTables( RSMB, NULL, 0 );
781 ok( len == sizeof(UINT), "wrong len %u\n", len );
782 smbios_table = malloc( len );
783 len = pEnumSystemFirmwareTables( RSMB, smbios_table, len );
784 ok( len == sizeof(UINT), "wrong len %u\n", len );
785 ok( *(UINT *)smbios_table == 0, "wrong table id %x\n", *(UINT *)smbios_table );
786 free( smbios_table );
787
788 HeapFree(GetProcessHeap(), 0, sfti);
789}
790
791static const struct
792{
793 UINT32 code;
794 const WCHAR *name;
795 BOOL broken;
796}
797arch_data[] =
798{
799 {PROCESSOR_ARCHITECTURE_INTEL, L"X86"},
800 {PROCESSOR_ARCHITECTURE_ARM, L"Arm"},
801 {PROCESSOR_ARCHITECTURE_AMD64, L"X64"},
802 {PROCESSOR_ARCHITECTURE_NEUTRAL, L"Neutral"},
803 {PROCESSOR_ARCHITECTURE_ARM64, L"Arm64", TRUE /* Before Win10. */},
804 {PROCESSOR_ARCHITECTURE_UNKNOWN, L"Unknown", TRUE /* Before Win10 1709. */},
805};
806
807static const WCHAR *arch_string_from_code(UINT32 arch)
808{
809 unsigned int i;
810
811 for (i = 0; i < ARRAY_SIZE(arch_data); ++i)
812 if (arch_data[i].code == arch)
813 return arch_data[i].name;
814
815 return NULL;
816}
817
818static unsigned int get_package_str_size(const WCHAR *str)
819{
820 return str ? (lstrlenW(str) + 1) * sizeof(*str) : 0;
821}
822
823static unsigned int get_package_id_size(const PACKAGE_ID *id)
824{
825 return sizeof(*id) + get_package_str_size(id->name)
826 + get_package_str_size(id->resourceId) + 14 * sizeof(WCHAR);
827}
828
829static void packagefullname_from_packageid(WCHAR *buffer, size_t count, const PACKAGE_ID *id)
830{
831 swprintf(buffer, count, L"%s_%u.%u.%u.%u_%s_%s_%s", id->name, id->version.Major,
832 id->version.Minor, id->version.Build, id->version.Revision,
833 arch_string_from_code(id->processorArchitecture), id->resourceId,
834 id->publisherId);
835}
836
837static void test_PackageIdFromFullName(void)
838{
839 static const PACKAGE_ID test_package_id =
840 {
841 0, PROCESSOR_ARCHITECTURE_INTEL,
842 {{.Major = 1, .Minor = 2, .Build = 3, .Revision = 4}},
843 (WCHAR *)L"TestPackage", NULL,
844 (WCHAR *)L"TestResourceId", (WCHAR *)L"0abcdefghjkme"
845 };
846 UINT32 size, expected_size;
847 PACKAGE_ID test_id;
848 WCHAR fullname[512];
849 BYTE id_buffer[512];
850 unsigned int i;
851 PACKAGE_ID *id;
852 LONG ret;
853
854 if (!pPackageIdFromFullName)
855 {
856 win_skip("PackageIdFromFullName not available.\n");
857 return;
858 }
859#ifdef __REACTOS__
860 if (GetNTVersion() < _WIN32_WINNT_WIN10) {
861 skip("test_PackageIdFromFullName() broken on Win8.1 and older\n");
862 return;
863 }
864#endif
865
866 packagefullname_from_packageid(fullname, ARRAY_SIZE(fullname), &test_package_id);
867
868 id = (PACKAGE_ID *)id_buffer;
869
870 memset(id_buffer, 0xcc, sizeof(id_buffer));
871 expected_size = get_package_id_size(&test_package_id);
872 size = sizeof(id_buffer);
873 ret = pPackageIdFromFullName(fullname, 0, &size, id_buffer);
874 ok(ret == ERROR_SUCCESS, "Got unexpected ret %lu.\n", ret);
875 ok(size == expected_size, "Got unexpected length %u, expected %u.\n", size, expected_size);
876 ok(!lstrcmpW(id->name, test_package_id.name), "Got unexpected name %s.\n", debugstr_w(id->name));
877 ok(!lstrcmpW(id->resourceId, test_package_id.resourceId), "Got unexpected resourceId %s.\n",
878 debugstr_w(id->resourceId));
879 ok(!lstrcmpW(id->publisherId, test_package_id.publisherId), "Got unexpected publisherId %s.\n",
880 debugstr_w(id->publisherId));
881 ok(!id->publisher, "Got unexpected publisher %s.\n", debugstr_w(id->publisher));
882 ok(id->processorArchitecture == PROCESSOR_ARCHITECTURE_INTEL, "Got unexpected processorArchitecture %u.\n",
883 id->processorArchitecture);
884 ok(id->version.Version == 0x0001000200030004, "Got unexpected Version %s.\n",
885 wine_dbgstr_longlong(id->version.Version));
886 ok((BYTE *)id->name == id_buffer + sizeof(*id), "Got unexpected name %p, buffer %p.\n", id->name, id_buffer);
887 ok((BYTE *)id->resourceId == (BYTE *)id->name + (lstrlenW(id->name) + 1) * 2,
888 "Got unexpected resourceId %p, buffer %p.\n", id->resourceId, id_buffer);
889 ok((BYTE *)id->publisherId == (BYTE *)id->resourceId + (lstrlenW(id->resourceId) + 1) * 2,
890 "Got unexpected publisherId %p, buffer %p.\n", id->resourceId, id_buffer);
891
892 ret = pPackageIdFromFullName(fullname, 0, NULL, id_buffer);
893 ok(ret == ERROR_INVALID_PARAMETER, "Got unexpected ret %ld.\n", ret);
894
895 size = sizeof(id_buffer);
896 ret = pPackageIdFromFullName(NULL, 0, &size, id_buffer);
897 ok(ret == ERROR_INVALID_PARAMETER, "Got unexpected ret %ld.\n", ret);
898 ok(size == sizeof(id_buffer), "Got unexpected size %u.\n", size);
899
900 size = sizeof(id_buffer);
901 ret = pPackageIdFromFullName(fullname, 0, &size, NULL);
902 ok(ret == ERROR_INVALID_PARAMETER, "Got unexpected ret %ld.\n", ret);
903 ok(size == sizeof(id_buffer), "Got unexpected size %u.\n", size);
904
905 size = expected_size - 1;
906 ret = pPackageIdFromFullName(fullname, 0, &size, NULL);
907 ok(ret == ERROR_INVALID_PARAMETER, "Got unexpected ret %ld.\n", ret);
908 ok(size == expected_size - 1, "Got unexpected size %u.\n", size);
909
910 size = expected_size - 1;
911 ret = pPackageIdFromFullName(fullname, 0, &size, id_buffer);
912 ok(ret == ERROR_INSUFFICIENT_BUFFER, "Got unexpected ret %ld.\n", ret);
913 ok(size == expected_size, "Got unexpected size %u.\n", size);
914
915 size = 0;
916 ret = pPackageIdFromFullName(fullname, 0, &size, NULL);
917 ok(ret == ERROR_INSUFFICIENT_BUFFER, "Got unexpected ret %ld.\n", ret);
918 ok(size == expected_size, "Got unexpected size %u.\n", size);
919
920 for (i = 0; i < ARRAY_SIZE(arch_data); ++i)
921 {
922 test_id = test_package_id;
923 test_id.processorArchitecture = arch_data[i].code;
924 packagefullname_from_packageid(fullname, ARRAY_SIZE(fullname), &test_id);
925 size = expected_size;
926 ret = pPackageIdFromFullName(fullname, 0, &size, id_buffer);
927 ok(ret == ERROR_SUCCESS || broken(arch_data[i].broken && ret == ERROR_INVALID_PARAMETER),
928 "Got unexpected ret %lu.\n", ret);
929 if (ret != ERROR_SUCCESS)
930 continue;
931 ok(size == expected_size, "Got unexpected length %u, expected %u.\n", size, expected_size);
932 ok(id->processorArchitecture == arch_data[i].code, "Got unexpected processorArchitecture %u, arch %S.\n",
933 id->processorArchitecture, arch_data[i].name);
934 }
935
936 size = sizeof(id_buffer);
937 ret = pPackageIdFromFullName(L"TestPackage_1.2.3.4_X86_TestResourceId_0abcdefghjkme", 0, &size, id_buffer);
938 ok(ret == ERROR_SUCCESS, "Got unexpected ret %lu.\n", ret);
939
940 size = sizeof(id_buffer);
941 ret = pPackageIdFromFullName(L"TestPackage_1.2.3.4_X86_TestResourceId_abcdefghjkme", 0, &size, id_buffer);
942 ok(ret == ERROR_INVALID_PARAMETER, "Got unexpected ret %lu.\n", ret);
943
944 size = sizeof(id_buffer);
945 ret = pPackageIdFromFullName(L"TestPackage_1.2.3.4_X86_TestResourceId_0abcdefghjkmee", 0, &size, id_buffer);
946 ok(ret == ERROR_INVALID_PARAMETER, "Got unexpected ret %lu.\n", ret);
947
948 size = sizeof(id_buffer);
949 ret = pPackageIdFromFullName(L"TestPackage_1.2.3_X86_TestResourceId_0abcdefghjkme", 0, &size, id_buffer);
950 ok(ret == ERROR_INVALID_PARAMETER, "Got unexpected ret %lu.\n", ret);
951
952 size = sizeof(id_buffer);
953 ret = pPackageIdFromFullName(L"TestPackage_1.2.3.4_X86_TestResourceId_0abcdefghjkme_", 0, &size, id_buffer);
954 ok(ret == ERROR_INVALID_PARAMETER, "Got unexpected ret %lu.\n", ret);
955
956 size = sizeof(id_buffer);
957 ret = pPackageIdFromFullName(L"TestPackage_1.2.3.4_X86__0abcdefghjkme", 0, &size, id_buffer);
958 ok(ret == ERROR_SUCCESS, "Got unexpected ret %lu.\n", ret);
959 ok(!lstrcmpW(id->resourceId, L""), "Got unexpected resourceId %s.\n", debugstr_w(id->resourceId));
960
961 size = sizeof(id_buffer);
962 ret = pPackageIdFromFullName(L"TestPackage_1.2.3.4_X86_0abcdefghjkme", 0, &size, id_buffer);
963 ok(ret == ERROR_INVALID_PARAMETER, "Got unexpected ret %lu.\n", ret);
964}
965
966#define TEST_VERSION_WIN7 1
967#define TEST_VERSION_WIN8 2
968#define TEST_VERSION_WIN8_1 4
969#define TEST_VERSION_WIN10 8
970
971static const struct
972{
973 unsigned int pe_version_major, pe_version_minor;
974 unsigned int manifest_versions;
975 unsigned int expected_major, expected_minor;
976}
977test_pe_os_version_tests[] =
978{
979 { 4, 0, 0, 6, 2},
980 { 4, 0, TEST_VERSION_WIN10, 10, 0},
981 { 6, 3, TEST_VERSION_WIN8, 6, 2},
982 {10, 0, 0, 10, 0},
983 { 6, 3, 0, 6, 3},
984 { 6, 4, 0, 6, 3},
985 { 9, 0, 0, 6, 3},
986 {11, 0, 0, 10, 0},
987 {10, 0,
988 TEST_VERSION_WIN7 | TEST_VERSION_WIN8 | TEST_VERSION_WIN8_1,
989 6, 3},
990};
991
992static void test_pe_os_version_child(unsigned int test)
993{
994 OSVERSIONINFOEXA info;
995 BOOL ret;
996
997 info.dwOSVersionInfoSize = sizeof(info);
998 ret = GetVersionExA((OSVERSIONINFOA *)&info);
999 ok(ret, "Got unexpected ret %#x, GetLastError() %lu.\n", ret, GetLastError());
1000 ok(info.dwMajorVersion == test_pe_os_version_tests[test].expected_major,
1001 "Test %u, expected major version %u, got %lu.\n", test, test_pe_os_version_tests[test].expected_major,
1002 info.dwMajorVersion);
1003 ok(info.dwMinorVersion == test_pe_os_version_tests[test].expected_minor,
1004 "Test %u, expected minor version %u, got %lu.\n", test, test_pe_os_version_tests[test].expected_minor,
1005 info.dwMinorVersion);
1006}
1007
1008static void test_pe_os_version(void)
1009{
1010 static const char manifest_header[] =
1011 "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"
1012 "<assembly manifestVersion=\"1.0\" xmlns=\"urn:schemas-microsoft-com:asm.v1\""
1013 " xmlns:asmv3=\"urn:schemas-microsoft-com:asm.v3\">\n"
1014 "\t<compatibility xmlns=\"urn:schemas-microsoft-com:compatibility.v1\">\n"
1015 "\t\t<application>\n";
1016 static const char manifest_footer[] =
1017 "\t\t</application>\n"
1018 "\t</compatibility>\n"
1019 "</assembly>\n";
1020 static const char *version_guids[] =
1021 {
1022 "{35138b9a-5d96-4fbd-8e2d-a2440225f93a}",
1023 "{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}",
1024 "{1f676c76-80e1-4239-95bb-83d0f6d0da78}",
1025 "{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}",
1026 };
1027 LONG hdr_offset, offset_major, offset_minor;
1028 char str[MAX_PATH], tmp_exe_name[9];
1029 RTL_OSVERSIONINFOEXW rtlinfo;
1030 STARTUPINFOA si = { 0 };
1031 PROCESS_INFORMATION pi;
1032 DWORD result, code;
1033 unsigned int i, j;
1034 HANDLE file;
1035 char **argv;
1036 DWORD size;
1037 BOOL ret;
1038
1039 winetest_get_mainargs( &argv );
1040
1041 if (!pRtlGetVersion)
1042 {
1043 win_skip("RtlGetVersion is not supported, skipping tests.\n");
1044 return;
1045 }
1046
1047 rtlinfo.dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOEXW);
1048 ok(!pRtlGetVersion(&rtlinfo), "RtlGetVersion failed.\n");
1049 if (rtlinfo.dwMajorVersion < 10)
1050 {
1051 skip("Too old Windows version %lu.%lu, skipping tests.\n", rtlinfo.dwMajorVersion, rtlinfo.dwMinorVersion);
1052 return;
1053 }
1054
1055 file = CreateFileA(argv[0], GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
1056 ok(file != INVALID_HANDLE_VALUE, "CreateFile failed, GetLastError() %lu.\n", GetLastError());
1057 SetFilePointer(file, 0x3c, NULL, FILE_BEGIN);
1058 ReadFile(file, &hdr_offset, sizeof(hdr_offset), &size, NULL);
1059 CloseHandle(file);
1060
1061 offset_major = hdr_offset + FIELD_OFFSET(IMAGE_NT_HEADERS, OptionalHeader)
1062 + FIELD_OFFSET(IMAGE_OPTIONAL_HEADER, MajorOperatingSystemVersion);
1063 offset_minor = hdr_offset + FIELD_OFFSET(IMAGE_NT_HEADERS, OptionalHeader)
1064 + FIELD_OFFSET(IMAGE_OPTIONAL_HEADER, MinorOperatingSystemVersion);
1065
1066 si.cb = sizeof(si);
1067
1068 for (i = 0; i < ARRAY_SIZE(test_pe_os_version_tests); ++i)
1069 {
1070 sprintf(tmp_exe_name, "tmp%u.exe", i);
1071 ret = CopyFileA(argv[0], tmp_exe_name, FALSE);
1072 ok(ret, "Got unexpected ret %#x, GetLastError() %lu.\n", ret, GetLastError());
1073
1074 file = CreateFileA(tmp_exe_name, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
1075 ok(file != INVALID_HANDLE_VALUE, "CreateFile failed, GetLastError() %lu.\n", GetLastError());
1076
1077 SetFilePointer(file, offset_major, NULL, FILE_BEGIN);
1078 WriteFile(file, &test_pe_os_version_tests[i].pe_version_major,
1079 sizeof(test_pe_os_version_tests[i].pe_version_major), &size, NULL);
1080 SetFilePointer(file, offset_minor, NULL, FILE_BEGIN);
1081 WriteFile(file, &test_pe_os_version_tests[i].pe_version_minor,
1082 sizeof(test_pe_os_version_tests[i].pe_version_minor), &size, NULL);
1083
1084 CloseHandle(file);
1085
1086 sprintf(str, "%s.manifest", tmp_exe_name);
1087 file = CreateFileA(str, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
1088 ok(file != INVALID_HANDLE_VALUE, "CreateFile failed, GetLastError() %lu.\n", GetLastError());
1089
1090 WriteFile(file, manifest_header, strlen(manifest_header), &size, NULL);
1091 for (j = 0; j < ARRAY_SIZE(version_guids); ++j)
1092 {
1093 if (test_pe_os_version_tests[i].manifest_versions & (1 << j))
1094 {
1095 sprintf(str, "\t\t\t<supportedOS Id=\"%s\"/>\n", version_guids[j]);
1096 WriteFile(file, str, strlen(str), &size, NULL);
1097 }
1098 }
1099 WriteFile(file, manifest_footer, strlen(manifest_footer), &size, NULL);
1100
1101 CloseHandle(file);
1102
1103 sprintf(str, "%s version pe_os_version %u", tmp_exe_name, i);
1104
1105 ret = CreateProcessA(NULL, str, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
1106 ok(ret, "Got unexpected ret %#x, GetLastError() %lu.\n", ret, GetLastError());
1107 CloseHandle(pi.hThread);
1108 result = WaitForSingleObject(pi.hProcess, 10000);
1109 ok(result == WAIT_OBJECT_0, "Got unexpected result %#lx.\n", result);
1110
1111 ret = GetExitCodeProcess(pi.hProcess, &code);
1112 ok(ret, "Got unexpected ret %#x, GetLastError() %lu.\n", ret, GetLastError());
1113 ok(!code, "Test %u failed.\n", i);
1114
1115 CloseHandle(pi.hProcess);
1116
1117 DeleteFileA(tmp_exe_name);
1118 sprintf(str, "%s.manifest", tmp_exe_name);
1119 DeleteFileA(str);
1120 }
1121}
1122
1123START_TEST(version)
1124{
1125 char **argv;
1126 int argc;
1127
1128 argc = winetest_get_mainargs( &argv );
1129
1130 init_function_pointers();
1131
1132 if (argc >= 4)
1133 {
1134 if (!strcmp(argv[2], "pe_os_version"))
1135 {
1136 unsigned int test;
1137
1138 test = atoi(argv[3]);
1139 test_pe_os_version_child(test);
1140 }
1141 return;
1142 }
1143
1144 test_GetProductInfo();
1145 test_GetVersionEx();
1146 test_VerifyVersionInfo();
1147 test_pe_os_version();
1148 test_SystemFirmwareTable();
1149 test_PackageIdFromFullName();
1150}