Reactos
at master 1150 lines 42 kB view raw
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}