1 /* 2 * PROJECT: ReactOS API Tests 3 * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory 4 * PURPOSE: Test for NtMapViewOfSection 5 * PROGRAMMERS: Timo Kreuzer 6 * Thomas Faber 7 */ 8 9 #include "precomp.h" 10 11 void 12 Test_PageFileSection(void) 13 { 14 NTSTATUS Status; 15 HANDLE SectionHandle; 16 LARGE_INTEGER MaximumSize, SectionOffset; 17 PVOID BaseAddress, BaseAddress2; 18 SIZE_T ViewSize; 19 ULONG OldProtect; 20 21 /* Create a page file backed section with SEC_COMMIT */ 22 MaximumSize.QuadPart = 0x20000; 23 Status = NtCreateSection(&SectionHandle, 24 SECTION_ALL_ACCESS, 25 NULL, 26 &MaximumSize, 27 PAGE_READWRITE, 28 SEC_COMMIT, 29 NULL); 30 ok_ntstatus(Status, STATUS_SUCCESS); 31 if (!NT_SUCCESS(Status)) 32 return; 33 34 /* Try to map a page at an address that is not 64k aligned */ 35 BaseAddress = (PVOID)0x30001000; 36 SectionOffset.QuadPart = 0; 37 ViewSize = 0x1000; 38 Status = NtMapViewOfSection(SectionHandle, 39 NtCurrentProcess(), 40 &BaseAddress, 41 0, 42 0, 43 &SectionOffset, 44 &ViewSize, 45 ViewShare, 46 0, 47 PAGE_READWRITE); 48 ok_ntstatus(Status, STATUS_MAPPED_ALIGNMENT); 49 50 /* Try to map a page with execute rights */ 51 BaseAddress = (PVOID)0x30000000; 52 SectionOffset.QuadPart = 0; 53 ViewSize = 0x1000; 54 Status = NtMapViewOfSection(SectionHandle, 55 NtCurrentProcess(), 56 &BaseAddress, 57 0, 58 0, 59 &SectionOffset, 60 &ViewSize, 61 ViewShare, 62 0, 63 PAGE_EXECUTE_READWRITE); 64 ok_ntstatus(Status, STATUS_SECTION_PROTECTION); 65 66 /* Try to map 2 pages with MEM_COMMIT */ 67 BaseAddress = (PVOID)0x30000000; 68 SectionOffset.QuadPart = 0; 69 ViewSize = 0x2000; 70 Status = NtMapViewOfSection(SectionHandle, 71 NtCurrentProcess(), 72 &BaseAddress, 73 0, 74 PAGE_SIZE, 75 &SectionOffset, 76 &ViewSize, 77 ViewShare, 78 MEM_COMMIT, 79 PAGE_READWRITE); 80 ok_ntstatus(Status, STATUS_INVALID_PARAMETER_9); 81 82 /* Try to map 1 page, with free base address and zero bits compatible with 64k granularity */ 83 BaseAddress = NULL; 84 SectionOffset.QuadPart = 0; 85 ViewSize = 0x1000; 86 Status = NtMapViewOfSection(SectionHandle, 87 NtCurrentProcess(), 88 &BaseAddress, 89 10, 90 0, 91 &SectionOffset, 92 &ViewSize, 93 ViewShare, 94 0, 95 PAGE_READWRITE); 96 ok_ntstatus(Status, STATUS_SUCCESS); 97 Status = NtUnmapViewOfSection(NtCurrentProcess(), BaseAddress); 98 ok_ntstatus(Status, STATUS_SUCCESS); 99 100 { 101 ULONG_PTR gran = 64 * 1024; 102 ULONG_PTR ZeroBits = 11; 103 104 ok_hex(gran, 0x10000); 105 gran <<= ZeroBits; 106 ok_hex(gran, 0x8000000); 107 gran >>= ZeroBits; 108 ok_hex(gran, 0x10000); 109 110 ok_hex((gran << ZeroBits) >> ZeroBits, gran); 111 112 } 113 114 /* Try to map 1 page, with free base address and zero bits incompatible with 64k granularity */ 115 BaseAddress = NULL; 116 SectionOffset.QuadPart = 0; 117 ViewSize = 0x1000; 118 Status = NtMapViewOfSection(SectionHandle, 119 NtCurrentProcess(), 120 &BaseAddress, 121 11, 122 0, 123 &SectionOffset, 124 &ViewSize, 125 ViewShare, 126 0, 127 PAGE_READWRITE); 128 ok_ntstatus(Status, STATUS_NO_MEMORY); 129 130 /* Try to map 1 page, with base address and zero bits being compatible */ 131 BaseAddress = (PVOID)0x30000000; 132 SectionOffset.QuadPart = 0; 133 ViewSize = 0x1000; 134 Status = NtMapViewOfSection(SectionHandle, 135 NtCurrentProcess(), 136 &BaseAddress, 137 2, 138 0, 139 &SectionOffset, 140 &ViewSize, 141 ViewShare, 142 0, 143 PAGE_READWRITE); 144 ok_ntstatus(Status, STATUS_SUCCESS); 145 Status = NtUnmapViewOfSection(NtCurrentProcess(), BaseAddress); 146 ok_ntstatus(Status, STATUS_SUCCESS); 147 148 /* Try to map 1 page, with base address and zero bits being incompatible */ 149 BaseAddress = (PVOID)0x30000000; 150 SectionOffset.QuadPart = 0; 151 ViewSize = 0x1000; 152 Status = NtMapViewOfSection(SectionHandle, 153 NtCurrentProcess(), 154 &BaseAddress, 155 3, 156 0, 157 &SectionOffset, 158 &ViewSize, 159 ViewShare, 160 0, 161 PAGE_READWRITE); 162 ok_ntstatus(Status, STATUS_INVALID_PARAMETER_4); 163 164 /* Map 2 pages, without MEM_COMMIT */ 165 BaseAddress = (PVOID)0x30000000; 166 SectionOffset.QuadPart = 0; 167 ViewSize = 0x2000; 168 Status = NtMapViewOfSection(SectionHandle, 169 NtCurrentProcess(), 170 &BaseAddress, 171 0, 172 0, 173 &SectionOffset, 174 &ViewSize, 175 ViewShare, 176 0, 177 PAGE_READWRITE); 178 ok_ntstatus(Status, STATUS_SUCCESS); 179 180 /* We must be able to access the memory */ 181 _SEH2_TRY 182 { 183 *(PULONG)BaseAddress = 1; 184 } 185 _SEH2_EXCEPT(1) 186 { 187 ok(FALSE, "Got an exception\n"); 188 } 189 _SEH2_END; 190 191 /* Commit a page in the section */ 192 BaseAddress = (PVOID)0x30000000; 193 ViewSize = 0x1000; 194 Status = NtAllocateVirtualMemory(NtCurrentProcess(), 195 &BaseAddress, 196 0, 197 &ViewSize, 198 MEM_COMMIT, 199 PAGE_READWRITE); 200 ok_ntstatus(Status, STATUS_SUCCESS); 201 202 /* Try to decommit a page in the section */ 203 Status = NtFreeVirtualMemory(NtCurrentProcess(), 204 &BaseAddress, 205 &ViewSize, 206 MEM_DECOMMIT); 207 ok_ntstatus(Status, STATUS_UNABLE_TO_DELETE_SECTION); 208 209 /* Try to commit a range larger than the section */ 210 BaseAddress = (PVOID)0x30000000; 211 ViewSize = 0x3000; 212 Status = NtAllocateVirtualMemory(NtCurrentProcess(), 213 &BaseAddress, 214 0, 215 &ViewSize, 216 MEM_COMMIT, 217 PAGE_READWRITE); 218 ok_ntstatus(Status, STATUS_CONFLICTING_ADDRESSES); 219 220 /* Try to commit a page after the section */ 221 BaseAddress = (PVOID)0x30002000; 222 ViewSize = 0x1000; 223 Status = NtAllocateVirtualMemory(NtCurrentProcess(), 224 &BaseAddress, 225 0, 226 &ViewSize, 227 MEM_COMMIT, 228 PAGE_READWRITE); 229 ok_ntstatus(Status, STATUS_CONFLICTING_ADDRESSES); 230 231 /* Try to allocate a page after the section */ 232 BaseAddress = (PVOID)0x30002000; 233 ViewSize = 0x1000; 234 Status = NtAllocateVirtualMemory(NtCurrentProcess(), 235 &BaseAddress, 236 0, 237 &ViewSize, 238 MEM_RESERVE | MEM_COMMIT, 239 PAGE_READWRITE); 240 ok_ntstatus(Status, STATUS_CONFLICTING_ADDRESSES); 241 242 /* Need to go to next 64k boundary */ 243 BaseAddress = (PVOID)0x30010000; 244 ViewSize = 0x1000; 245 Status = NtAllocateVirtualMemory(NtCurrentProcess(), 246 &BaseAddress, 247 0, 248 &ViewSize, 249 MEM_RESERVE | MEM_COMMIT, 250 PAGE_READWRITE); 251 ok_ntstatus(Status, STATUS_SUCCESS); 252 if (!NT_SUCCESS(Status)) 253 return; 254 255 /* Free the allocation */ 256 BaseAddress = (PVOID)0x30010000; 257 ViewSize = 0x1000; 258 Status = NtFreeVirtualMemory(NtCurrentProcess(), 259 &BaseAddress, 260 &ViewSize, 261 MEM_RELEASE); 262 ok(NT_SUCCESS(Status), "NtFreeVirtualMemory failed with Status %lx\n", Status); 263 264 /* Try to release the section mapping with NtFreeVirtualMemory */ 265 BaseAddress = (PVOID)0x30000000; 266 ViewSize = 0x1000; 267 Status = NtFreeVirtualMemory(NtCurrentProcess(), 268 &BaseAddress, 269 &ViewSize, 270 MEM_RELEASE); 271 ok_ntstatus(Status, STATUS_UNABLE_TO_DELETE_SECTION); 272 273 /* Commit a page in the section */ 274 BaseAddress = (PVOID)0x30001000; 275 ViewSize = 0x1000; 276 Status = NtAllocateVirtualMemory(NtCurrentProcess(), 277 &BaseAddress, 278 0, 279 &ViewSize, 280 MEM_COMMIT, 281 PAGE_READWRITE); 282 ok_ntstatus(Status, STATUS_SUCCESS); 283 284 /* Try to decommit the page */ 285 BaseAddress = (PVOID)0x30001000; 286 ViewSize = 0x1000; 287 Status = NtFreeVirtualMemory(NtCurrentProcess(), 288 &BaseAddress, 289 &ViewSize, 290 MEM_DECOMMIT); 291 ok_ntstatus(Status, STATUS_UNABLE_TO_DELETE_SECTION); 292 293 BaseAddress = UlongToPtr(0x40000000); 294 SectionOffset.QuadPart = 0; 295 ViewSize = 0x1000; 296 Status = NtMapViewOfSection(SectionHandle, 297 NtCurrentProcess(), 298 &BaseAddress, 299 0, 300 0, 301 &SectionOffset, 302 &ViewSize, 303 ViewShare, 304 0, 305 PAGE_READWRITE); 306 ok_ntstatus(Status, STATUS_SUCCESS); 307 if (!NT_SUCCESS(Status)) 308 return; 309 310 ok(BaseAddress == UlongToPtr(0x40000000), "Invalid BaseAddress: %p\n", BaseAddress); 311 312 BaseAddress = (PVOID)0x40080000; 313 SectionOffset.QuadPart = 0x10000; 314 ViewSize = 0x1000; 315 Status = NtMapViewOfSection(SectionHandle, 316 NtCurrentProcess(), 317 &BaseAddress, 318 0, 319 0, 320 &SectionOffset, 321 &ViewSize, 322 ViewShare, 323 0, 324 PAGE_READWRITE); 325 ok_ntstatus(Status, STATUS_SUCCESS); 326 327 ok(BaseAddress == (PVOID)0x40080000, "Invalid BaseAddress: %p\n", BaseAddress); 328 329 /* Commit a page in the section */ 330 BaseAddress = (PVOID)0x40000000; 331 Status = NtAllocateVirtualMemory(NtCurrentProcess(), 332 &BaseAddress, 333 0, 334 &ViewSize, 335 MEM_COMMIT, 336 PAGE_READWRITE); 337 ok_ntstatus(Status, STATUS_SUCCESS); 338 339 /* Close the mapping */ 340 Status = NtUnmapViewOfSection(NtCurrentProcess(), BaseAddress); 341 ok_ntstatus(Status, STATUS_SUCCESS); 342 BaseAddress = (PVOID)0x30000000; 343 Status = NtUnmapViewOfSection(NtCurrentProcess(), BaseAddress); 344 ok_ntstatus(Status, STATUS_SUCCESS); 345 Status = NtClose(SectionHandle); 346 ok_ntstatus(Status, STATUS_SUCCESS); 347 348 /* Create a page file backed section, but only reserved */ 349 MaximumSize.QuadPart = 0x20000; 350 Status = NtCreateSection(&SectionHandle, 351 SECTION_ALL_ACCESS, 352 NULL, 353 &MaximumSize, 354 PAGE_READWRITE, 355 SEC_RESERVE, 356 NULL); 357 ok_ntstatus(Status, STATUS_SUCCESS); 358 359 /* Try to map 1 page, passing MEM_RESERVE */ 360 BaseAddress = NULL; 361 SectionOffset.QuadPart = 0; 362 ViewSize = PAGE_SIZE; 363 Status = NtMapViewOfSection(SectionHandle, 364 NtCurrentProcess(), 365 &BaseAddress, 366 0, 367 PAGE_SIZE, 368 &SectionOffset, 369 &ViewSize, 370 ViewShare, 371 MEM_RESERVE, 372 PAGE_READWRITE); 373 ok_ntstatus(Status, STATUS_INVALID_PARAMETER_9); 374 375 /* Try to map 1 page using MEM_COMMIT */ 376 BaseAddress = NULL; 377 SectionOffset.QuadPart = 0; 378 ViewSize = PAGE_SIZE; 379 Status = NtMapViewOfSection(SectionHandle, 380 NtCurrentProcess(), 381 &BaseAddress, 382 0, 383 PAGE_SIZE, 384 &SectionOffset, 385 &ViewSize, 386 ViewShare, 387 MEM_COMMIT, 388 PAGE_READWRITE); 389 ok_ntstatus(Status, STATUS_INVALID_PARAMETER_9); 390 391 /* Map 2 pages, but commit 1 */ 392 BaseAddress = NULL; 393 SectionOffset.QuadPart = 0; 394 ViewSize = 2 * PAGE_SIZE; 395 Status = NtMapViewOfSection(SectionHandle, 396 NtCurrentProcess(), 397 &BaseAddress, 398 0, 399 PAGE_SIZE, 400 &SectionOffset, 401 &ViewSize, 402 ViewShare, 403 0, 404 PAGE_READWRITE); 405 ok_ntstatus(Status, STATUS_SUCCESS); 406 407 /* We must be able to access the 1st page */ 408 Status = STATUS_SUCCESS; 409 _SEH2_TRY 410 { 411 *(PUCHAR)BaseAddress = 1; 412 } 413 _SEH2_EXCEPT(1) 414 { 415 Status = _SEH2_GetExceptionCode(); 416 } 417 _SEH2_END; 418 ok_ntstatus(Status, STATUS_SUCCESS); 419 420 /* We must not be able to access the 2nd page */ 421 Status = STATUS_SUCCESS; 422 _SEH2_TRY 423 { 424 *((PUCHAR)BaseAddress + PAGE_SIZE) = 1; 425 } 426 _SEH2_EXCEPT(1) 427 { 428 Status = _SEH2_GetExceptionCode(); 429 } 430 _SEH2_END; 431 ok_ntstatus(Status, STATUS_ACCESS_VIOLATION); 432 433 /* Map the 2 pages again into a different memory location */ 434 BaseAddress2 = NULL; 435 Status = NtMapViewOfSection(SectionHandle, 436 NtCurrentProcess(), 437 &BaseAddress2, 438 0, 439 0, 440 &SectionOffset, 441 &ViewSize, 442 ViewShare, 443 0, 444 PAGE_READWRITE); 445 ok_ntstatus(Status, STATUS_SUCCESS); 446 447 /* Commit a the 2nd page in the 2nd memory location */ 448 BaseAddress2 = (PUCHAR)BaseAddress2 + PAGE_SIZE; 449 ViewSize = PAGE_SIZE; 450 Status = NtAllocateVirtualMemory(NtCurrentProcess(), 451 &BaseAddress2, 452 0, 453 &ViewSize, 454 MEM_COMMIT, 455 PAGE_READONLY); 456 ok_ntstatus(Status, STATUS_SUCCESS); 457 458 /* Try to commit again (the already committed page) */ 459 Status = NtAllocateVirtualMemory(NtCurrentProcess(), 460 &BaseAddress2, 461 0, 462 &ViewSize, 463 MEM_COMMIT, 464 PAGE_READONLY); 465 ok_ntstatus(Status, STATUS_SUCCESS); 466 467 /* We must be able to access the memory in the 2nd page of the 1st memory location */ 468 Status = STATUS_SUCCESS; 469 _SEH2_TRY 470 { 471 *((PUCHAR)BaseAddress + PAGE_SIZE) = 2; 472 } 473 _SEH2_EXCEPT(1) 474 { 475 Status = _SEH2_GetExceptionCode(); 476 } 477 _SEH2_END; 478 ok_ntstatus(Status, STATUS_SUCCESS); 479 480 ok(*(PULONG)BaseAddress2 == 2, "Value in memory was wrong\n"); 481 482 /* Close the mapping */ 483 Status = NtUnmapViewOfSection(NtCurrentProcess(), BaseAddress); 484 ok_ntstatus(Status, STATUS_SUCCESS); 485 Status = NtUnmapViewOfSection(NtCurrentProcess(), (PUCHAR)BaseAddress2 - PAGE_SIZE); 486 ok_ntstatus(Status, STATUS_SUCCESS); 487 Status = NtClose(SectionHandle); 488 ok_ntstatus(Status, STATUS_SUCCESS); 489 490 /* Try to create a 512 GB page file backed section with committed pages */ 491 MaximumSize.QuadPart = 0x8000000000; 492 Status = NtCreateSection(&SectionHandle, 493 SECTION_ALL_ACCESS, 494 NULL, 495 &MaximumSize, 496 PAGE_READWRITE, 497 SEC_COMMIT, 498 NULL); 499 ok_ntstatus(Status, STATUS_COMMITMENT_LIMIT); 500 501 /* Try to create a huge page file backed section with PAGE_NOACCESS protection */ 502 MaximumSize.QuadPart = 0x8000000000; 503 Status = NtCreateSection(&SectionHandle, 504 SECTION_ALL_ACCESS, 505 NULL, 506 &MaximumSize, 507 PAGE_NOACCESS, 508 SEC_COMMIT, 509 NULL); 510 ok_ntstatus(Status, STATUS_INVALID_PAGE_PROTECTION); 511 512 /* Try to create a very huge page file backed section, but only reserved */ 513 MaximumSize.QuadPart = 0x80000000000; 514 Status = NtCreateSection(&SectionHandle, 515 SECTION_ALL_ACCESS, 516 NULL, 517 &MaximumSize, 518 PAGE_READWRITE, 519 SEC_RESERVE, 520 NULL); 521 #ifdef _WIN64 522 ok_ntstatus(Status, STATUS_INSUFFICIENT_RESOURCES); 523 #else 524 /* WoW64 returns STATUS_INSUFFICIENT_RESOURCES */ 525 ok((Status == STATUS_INSUFFICIENT_RESOURCES) || (Status == STATUS_SECTION_TOO_BIG), 526 "got wrong Status: 0x%lx\n", Status); 527 #endif 528 529 /* Try to create a even huger page file backed section, but only reserved */ 530 MaximumSize.QuadPart = 0x800000000000; 531 Status = NtCreateSection(&SectionHandle, 532 SECTION_ALL_ACCESS, 533 NULL, 534 &MaximumSize, 535 PAGE_READWRITE, 536 SEC_RESERVE, 537 NULL); 538 ok_ntstatus(Status, STATUS_SECTION_TOO_BIG); 539 540 /* Create a 8 GB page file backed section, but only reserved */ 541 MaximumSize.QuadPart = 0x200000000; 542 Status = NtCreateSection(&SectionHandle, 543 SECTION_ALL_ACCESS, 544 NULL, 545 &MaximumSize, 546 PAGE_READWRITE, 547 SEC_RESERVE, 548 NULL); 549 ok_ntstatus(Status, STATUS_SUCCESS); 550 551 /* Pass a too large region size */ 552 BaseAddress = NULL; 553 SectionOffset.QuadPart = 0; 554 ViewSize = MAXULONG_PTR; 555 Status = NtMapViewOfSection(SectionHandle, 556 NtCurrentProcess(), 557 &BaseAddress, 558 0, 559 0, 560 &SectionOffset, 561 &ViewSize, 562 ViewShare, 563 0, 564 PAGE_READWRITE); 565 #ifdef _WIN64 566 ok_ntstatus(Status, STATUS_INVALID_PARAMETER_3); 567 #else 568 /* WoW64 returns STATUS_INVALID_PARAMETER_4 */ 569 ok((Status == STATUS_INVALID_PARAMETER_4) || (Status == STATUS_INVALID_PARAMETER_3), 570 "got wrong Status: 0x%lx\n", Status); 571 #endif 572 573 /* Pass 0 region size */ 574 BaseAddress = NULL; 575 SectionOffset.QuadPart = 0; 576 ViewSize = 0; 577 Status = NtMapViewOfSection(SectionHandle, 578 NtCurrentProcess(), 579 &BaseAddress, 580 0, 581 0, 582 &SectionOffset, 583 &ViewSize, 584 ViewShare, 585 0, 586 PAGE_READWRITE); 587 #ifdef _WIN64 588 ok_ntstatus(Status, STATUS_SUCCESS); 589 ok(ViewSize == 0x200000000, "wrong ViewSize: 0x%Ix\n", ViewSize); 590 #else 591 /* WoW64 returns STATUS_NO_MEMORY */ 592 ok((Status == STATUS_NO_MEMORY) || (Status == STATUS_INVALID_VIEW_SIZE), 593 "got wrong Status: 0x%lx\n", Status); 594 ok(ViewSize == 0, "wrong ViewSize: 0x%Ix\n", ViewSize); 595 #endif 596 597 /* Map with PAGE_NOACCESS */ 598 BaseAddress = NULL; 599 SectionOffset.QuadPart = 0; 600 ViewSize = 0x20000000; 601 Status = NtMapViewOfSection(SectionHandle, 602 NtCurrentProcess(), 603 &BaseAddress, 604 0, 605 0, 606 &SectionOffset, 607 &ViewSize, 608 ViewShare, 609 0, 610 PAGE_NOACCESS); 611 ok_ntstatus(Status, STATUS_SUCCESS); 612 613 /* Try to change protection to read/write */ 614 ViewSize = 0x1000; 615 OldProtect = -1; 616 BaseAddress2 = BaseAddress; 617 Status = NtProtectVirtualMemory(NtCurrentProcess(), &BaseAddress2, &ViewSize, PAGE_READWRITE, &OldProtect); 618 ok_ntstatus(Status, STATUS_SECTION_PROTECTION); 619 // Windows 2003 returns bogus 620 //ok(OldProtect == PAGE_READWRITE, "Wrong protection returned: %u\n", OldProtect); 621 622 /* Test read access */ 623 Status = STATUS_SUCCESS; 624 _SEH2_TRY 625 { 626 (void)(*(volatile char*)BaseAddress2); 627 } 628 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 629 { 630 Status = _SEH2_GetExceptionCode(); 631 } 632 _SEH2_END; 633 ok_ntstatus(Status, STATUS_ACCESS_VIOLATION); 634 635 /* Try to change protection to read/write */ 636 ViewSize = 0x1000; 637 OldProtect = -1; 638 BaseAddress2 = BaseAddress; 639 Status = NtProtectVirtualMemory(NtCurrentProcess(), &BaseAddress2, &ViewSize, PAGE_READWRITE, &OldProtect); 640 ok_ntstatus(Status, STATUS_SECTION_PROTECTION); 641 #ifdef _WIN64 642 ok(OldProtect == 0, "Wrong protection returned: 0x%lx\n", OldProtect); 643 #else 644 // Windows 2003 returns bogus 645 #endif 646 647 /* Try to change protection to readonly */ 648 ViewSize = 0x1000; 649 OldProtect = -1; 650 BaseAddress2 = BaseAddress; 651 Status = NtProtectVirtualMemory(NtCurrentProcess(), &BaseAddress2, &ViewSize, PAGE_READONLY, &OldProtect); 652 ok_ntstatus(Status, STATUS_SECTION_PROTECTION); 653 #ifdef _WIN64 654 //ok(OldProtect == 0, "Wrong protection returned: 0x%lx\n", OldProtect); 655 #else 656 // Windows 2003 returns bogus 657 #endif 658 659 /* Commit a page */ 660 ViewSize = 0x1000; 661 BaseAddress2 = BaseAddress; 662 Status = NtAllocateVirtualMemory(NtCurrentProcess(), &BaseAddress2, 0, &ViewSize, MEM_COMMIT, PAGE_READONLY); 663 ok_ntstatus(Status, STATUS_SUCCESS); 664 ok(BaseAddress2 == BaseAddress, "Invalid base address: %p\n", BaseAddress2); 665 666 /* Commit the page again */ 667 ViewSize = 0x1000; 668 BaseAddress2 = BaseAddress; 669 Status = NtAllocateVirtualMemory(NtCurrentProcess(), &BaseAddress2, 0, &ViewSize, MEM_COMMIT, PAGE_READONLY); 670 ok_ntstatus(Status, STATUS_SUCCESS); 671 ok(BaseAddress2 == BaseAddress, "Invalid base address: %p\n", BaseAddress2); 672 673 /* Test read access */ 674 Status = STATUS_SUCCESS; 675 _SEH2_TRY 676 { 677 (void)(*(volatile char*)BaseAddress2); 678 } 679 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 680 { 681 Status = _SEH2_GetExceptionCode(); 682 } 683 _SEH2_END; 684 ok_ntstatus(Status, STATUS_SUCCESS); 685 686 /* Test write access */ 687 Status = STATUS_SUCCESS; 688 _SEH2_TRY 689 { 690 *(char*)BaseAddress2 = 1; 691 } 692 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 693 { 694 Status = _SEH2_GetExceptionCode(); 695 } 696 _SEH2_END; 697 ok_ntstatus(Status, STATUS_ACCESS_VIOLATION); 698 699 /* Update protection to PAGE_READWRITE */ 700 ViewSize = 0x1000; 701 BaseAddress2 = BaseAddress; 702 Status = NtAllocateVirtualMemory(NtCurrentProcess(), &BaseAddress2, 0, &ViewSize, MEM_COMMIT, PAGE_READWRITE); 703 ok_ntstatus(Status, STATUS_SUCCESS); 704 705 /* Test write access */ 706 Status = STATUS_SUCCESS; 707 _SEH2_TRY 708 { 709 *(char*)BaseAddress2 = 1; 710 } 711 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 712 { 713 Status = _SEH2_GetExceptionCode(); 714 } 715 _SEH2_END; 716 ok_ntstatus(Status, STATUS_SUCCESS); 717 718 /* Update protection to PAGE_EXECUTE_READWRITE (1 page) */ 719 ViewSize = 0x1000; 720 BaseAddress2 = BaseAddress; 721 Status = NtAllocateVirtualMemory(NtCurrentProcess(), &BaseAddress2, 0, &ViewSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE); 722 ok_ntstatus(Status, STATUS_SUCCESS); 723 724 Status = NtUnmapViewOfSection(NtCurrentProcess(), BaseAddress); 725 ok_ntstatus(Status, STATUS_SUCCESS); 726 Status = NtClose(SectionHandle); 727 ok_ntstatus(Status, STATUS_SUCCESS); 728 } 729 730 void 731 Test_ImageSection(void) 732 { 733 UNICODE_STRING FileName; 734 NTSTATUS Status; 735 OBJECT_ATTRIBUTES FileObjectAttributes; 736 IO_STATUS_BLOCK IoStatusBlock; 737 WCHAR TestDllPath[MAX_PATH]; 738 HANDLE FileHandle, DataSectionHandle, ImageSectionHandle; 739 PVOID DataBase, ImageBase; 740 SIZE_T ViewSize; 741 742 GetModuleFileNameW(NULL, TestDllPath, RTL_NUMBER_OF(TestDllPath)); 743 wcsrchr(TestDllPath, L'\\')[1] = UNICODE_NULL; 744 StringCbCatW(TestDllPath, sizeof(TestDllPath), L"testdata\\test.dll"); 745 if (!RtlDosPathNameToNtPathName_U(TestDllPath, 746 &FileName, 747 NULL, 748 NULL)) 749 { 750 ok(0, "RtlDosPathNameToNtPathName_U failed\n"); 751 return; 752 } 753 754 InitializeObjectAttributes(&FileObjectAttributes, 755 &FileName, 756 0, 757 NULL, 758 NULL); 759 760 Status = NtOpenFile(&FileHandle, 761 GENERIC_READ|GENERIC_WRITE|SYNCHRONIZE, 762 &FileObjectAttributes, 763 &IoStatusBlock, 764 FILE_SHARE_READ, 765 FILE_SYNCHRONOUS_IO_NONALERT); 766 ok_ntstatus(Status, STATUS_SUCCESS); 767 if (!NT_SUCCESS(Status)) 768 { 769 skip("Failed to open file %s\n", wine_dbgstr_wn(FileName.Buffer, FileName.Length / sizeof(WCHAR))); 770 return; 771 } 772 773 /* Create a data section with write access */ 774 Status = NtCreateSection(&DataSectionHandle, 775 SECTION_ALL_ACCESS, // DesiredAccess 776 NULL, // ObjectAttributes 777 NULL, // MaximumSize 778 PAGE_READWRITE, // SectionPageProtection 779 SEC_COMMIT, // AllocationAttributes 780 FileHandle); 781 ok_ntstatus(Status, STATUS_SUCCESS); 782 if (!NT_SUCCESS(Status)) 783 { 784 skip("Failed to create data section\n"); 785 NtClose(FileHandle); 786 return; 787 } 788 789 /* Map the data section as flat mapping */ 790 DataBase = NULL; 791 ViewSize = 0; 792 Status = NtMapViewOfSection(DataSectionHandle, 793 NtCurrentProcess(), 794 &DataBase, 795 0, 796 0, 797 NULL, 798 &ViewSize, 799 ViewShare, 800 0, 801 PAGE_READWRITE); 802 ok_ntstatus(Status, STATUS_SUCCESS); 803 //ok(ViewSize == 0x3f95cc48, "ViewSize wrong: 0x%lx\n"); 804 if (!NT_SUCCESS(Status)) 805 { 806 skip("Failed to map view of data section\n"); 807 NtClose(DataSectionHandle); 808 NtClose(FileHandle); 809 return; 810 } 811 812 /* Check the original data */ 813 ok(*(ULONG*)DataBase == 0x00905a4d, "Header not ok\n"); 814 815 /* Modify the PE header (but do not flush!) */ 816 *(ULONG*)DataBase = 0xdeadbabe; 817 ok(*(ULONG*)DataBase == 0xdeadbabe, "Header not ok\n"); 818 819 /* Modify data in the .data section (but do not flush!) */ 820 ok(*(ULONG*)((PUCHAR)DataBase + 0x800) == 0x12345678, 821 "Data in .data section invalid: 0x%lx!\n", *(ULONG*)((PUCHAR)DataBase + 0x800)); 822 *(ULONG*)((PUCHAR)DataBase + 0x800) = 0x87654321; 823 824 /* Now try to create an image section (should fail) */ 825 Status = NtCreateSection(&ImageSectionHandle, 826 SECTION_ALL_ACCESS, // DesiredAccess 827 NULL, // ObjectAttributes 828 NULL, // MaximumSize 829 PAGE_READWRITE, // SectionPageProtection 830 SEC_IMAGE, // AllocationAttributes 831 FileHandle); 832 ok_ntstatus(Status, STATUS_INVALID_IMAGE_NOT_MZ); 833 if (NT_SUCCESS(Status)) NtClose(ImageSectionHandle); 834 835 /* Restore the original header */ 836 *(ULONG*)DataBase = 0x00905a4d; 837 838 /* Modify data in the .data section (but do not flush!) */ 839 ok_hex(*(ULONG*)((PUCHAR)DataBase + 0x800), 0x87654321); 840 *(ULONG*)((PUCHAR)DataBase + 0x800) = 0xdeadbabe; 841 842 /* Try to create an image section again */ 843 Status = NtCreateSection(&ImageSectionHandle, 844 SECTION_ALL_ACCESS, // DesiredAccess 845 NULL, // ObjectAttributes 846 NULL, // MaximumSize 847 PAGE_READWRITE, // SectionPageProtection 848 SEC_IMAGE, // AllocationAttributes 849 FileHandle); 850 ok_ntstatus(Status, STATUS_SUCCESS); 851 if (!NT_SUCCESS(Status)) 852 { 853 skip("Failed to create image section\n"); 854 NtClose(DataSectionHandle); 855 NtClose(FileHandle); 856 return; 857 } 858 859 /* Map the image section */ 860 ImageBase = NULL; 861 ViewSize = 0; 862 Status = NtMapViewOfSection(ImageSectionHandle, 863 NtCurrentProcess(), 864 &ImageBase, 865 0, // ZeroBits 866 0, // CommitSize 867 NULL, // SectionOffset 868 &ViewSize, 869 ViewShare, 870 0, // AllocationType 871 PAGE_READONLY); 872 #ifdef _M_IX86 873 ok_ntstatus(Status, STATUS_SUCCESS); 874 #else 875 ok_ntstatus(Status, STATUS_IMAGE_MACHINE_TYPE_MISMATCH); 876 #endif 877 if (!NT_SUCCESS(Status)) 878 { 879 skip("Failed to map view of image section\n"); 880 NtClose(ImageSectionHandle); 881 NtClose(DataSectionHandle); 882 NtClose(FileHandle); 883 return; 884 } 885 886 /* Check the header */ 887 ok(*(ULONG*)DataBase == 0x00905a4d, "Header not ok\n"); 888 ok(*(ULONG*)ImageBase == 0x00905a4d, "Header not ok\n"); 889 890 /* Check the data section. Either of these can be present! */ 891 ok((*(ULONG*)((PUCHAR)ImageBase + 0x80000) == 0x87654321) || 892 (*(ULONG*)((PUCHAR)ImageBase + 0x80000) == 0x12345678), 893 "Wrong value in data section: 0x%lx!\n", *(ULONG*)((PUCHAR)ImageBase + 0x80000)); 894 895 /* Now modify the data again */ 896 *(ULONG*)DataBase = 0xdeadbabe; 897 *(ULONG*)((PUCHAR)DataBase + 0x800) = 0xf00dada; 898 899 /* Check the data */ 900 ok(*(ULONG*)DataBase == 0xdeadbabe, "Header not ok\n"); 901 ok(*(ULONG*)ImageBase == 0x00905a4d, "Data should not be synced!\n"); 902 ok((*(ULONG*)((PUCHAR)ImageBase + 0x80000) == 0x87654321) || 903 (*(ULONG*)((PUCHAR)ImageBase + 0x80000) == 0x12345678), 904 "Wrong value in data section: 0x%lx!\n", *(ULONG*)((PUCHAR)ImageBase + 0x80000)); 905 906 /* Flush the view */ 907 ViewSize = 0x1000; 908 Status = NtFlushVirtualMemory(NtCurrentProcess(), 909 &DataBase, 910 &ViewSize, 911 &IoStatusBlock); 912 ok_ntstatus(Status, STATUS_SUCCESS); 913 914 /* Check the data again */ 915 ok(*(ULONG*)ImageBase == 0x00905a4d, "Data should not be synced!\n"); 916 ok((*(ULONG*)((PUCHAR)ImageBase + 0x80000) == 0x87654321) || 917 (*(ULONG*)((PUCHAR)ImageBase + 0x80000) == 0x12345678), 918 "Wrong value in data section: 0x%lx!\n", *(ULONG*)((PUCHAR)ImageBase + 0x80000)); 919 920 /* Restore the original header */ 921 *(ULONG*)DataBase = 0x00905a4d; 922 ok(*(ULONG*)DataBase == 0x00905a4d, "Header not ok\n"); 923 924 /* Close the image mapping */ 925 NtUnmapViewOfSection(NtCurrentProcess(), ImageBase); 926 NtClose(ImageSectionHandle); 927 928 /* Create an image section again */ 929 Status = NtCreateSection(&ImageSectionHandle, 930 SECTION_ALL_ACCESS, // DesiredAccess 931 NULL, // ObjectAttributes 932 NULL, // MaximumSize 933 PAGE_READWRITE, // SectionPageProtection 934 SEC_IMAGE, // AllocationAttributes 935 FileHandle); 936 ok_ntstatus(Status, STATUS_SUCCESS); 937 if (!NT_SUCCESS(Status)) 938 { 939 skip("Failed to create image section\n"); 940 NtClose(DataSectionHandle); 941 NtClose(FileHandle); 942 return; 943 } 944 945 /* Map the image section again */ 946 ImageBase = NULL; 947 ViewSize = 0; 948 Status = NtMapViewOfSection(ImageSectionHandle, 949 NtCurrentProcess(), 950 &ImageBase, 951 0, 952 0, 953 NULL, 954 &ViewSize, 955 ViewShare, 956 0, 957 PAGE_READONLY); 958 #ifdef _M_IX86 959 ok_ntstatus(Status, STATUS_SUCCESS); 960 #else 961 ok_ntstatus(Status, STATUS_IMAGE_MACHINE_TYPE_MISMATCH); 962 #endif 963 if (!NT_SUCCESS(Status)) 964 { 965 skip("Failed to map view of image section\n"); 966 NtClose(ImageSectionHandle); 967 NtClose(DataSectionHandle); 968 NtClose(FileHandle); 969 return; 970 } 971 972 // This one doesn't always work, needs investigation 973 /* Check the .data section again */ 974 //ok(*(ULONG*)((PUCHAR)ImageBase + 0x80000) == 0xf00dada, 975 // "Data should be synced: 0x%lx!\n", *(ULONG*)((PUCHAR)ImageBase + 0x80000)); 976 977 /* Restore the original data */ 978 *(ULONG*)((PUCHAR)DataBase + 0x800) = 0x12345678; 979 980 /* Close the data mapping */ 981 NtUnmapViewOfSection(NtCurrentProcess(), DataBase); 982 983 NtClose(DataSectionHandle); 984 985 /* Try to allocate memory inside the image mapping */ 986 DataBase = (PUCHAR)ImageBase + 0x20000; 987 ViewSize = 0x1000; 988 Status = NtAllocateVirtualMemory(NtCurrentProcess(), &DataBase, 0, &ViewSize, MEM_RESERVE, PAGE_NOACCESS); 989 ok_ntstatus(Status, STATUS_CONFLICTING_ADDRESSES); 990 991 /* Cleanup */ 992 NtClose(FileHandle); 993 NtClose(ImageSectionHandle); 994 NtUnmapViewOfSection(NtCurrentProcess(), ImageBase); 995 } 996 997 void 998 Test_ImageSection2(void) 999 { 1000 UNICODE_STRING FileName; 1001 NTSTATUS Status; 1002 OBJECT_ATTRIBUTES FileObjectAttributes; 1003 IO_STATUS_BLOCK IoStatusBlock; 1004 HANDLE FileHandle, ImageSectionHandle; 1005 PVOID ImageBase, BaseAddress; 1006 SIZE_T ViewSize; 1007 LARGE_INTEGER MaximumSize, SectionOffset; 1008 1009 if (!RtlDosPathNameToNtPathName_U(L"testdata\\nvoglv32.dll", 1010 &FileName, 1011 NULL, 1012 NULL)) 1013 { 1014 ok(0, "RtlDosPathNameToNtPathName_U failed\n"); 1015 return; 1016 } 1017 1018 InitializeObjectAttributes(&FileObjectAttributes, 1019 &FileName, 1020 0, 1021 NULL, 1022 NULL); 1023 1024 Status = NtOpenFile(&FileHandle, 1025 GENERIC_READ|GENERIC_WRITE|SYNCHRONIZE, 1026 &FileObjectAttributes, 1027 &IoStatusBlock, 1028 FILE_SHARE_READ, 1029 FILE_SYNCHRONOUS_IO_NONALERT); 1030 ok_ntstatus(Status, STATUS_SUCCESS); 1031 printf("Opened file with handle %p\n", FileHandle); 1032 1033 /* Create a data section with write access */ 1034 MaximumSize.QuadPart = 0x20000; 1035 Status = NtCreateSection(&ImageSectionHandle, 1036 SECTION_ALL_ACCESS, // DesiredAccess 1037 NULL, // ObjectAttributes 1038 &MaximumSize, // MaximumSize 1039 PAGE_READWRITE, // SectionPageProtection 1040 SEC_IMAGE, // AllocationAttributes 1041 FileHandle); 1042 ok_ntstatus(Status, STATUS_SUCCESS); 1043 1044 printf("Created image section with handle %p\n", ImageSectionHandle); 1045 //system("PAUSE"); 1046 1047 /* Map the image section */ 1048 ImageBase = NULL; 1049 ViewSize = 0x0000; 1050 SectionOffset.QuadPart = 0x00000; 1051 Status = NtMapViewOfSection(ImageSectionHandle, 1052 NtCurrentProcess(), 1053 &ImageBase, 1054 0, 1055 0, 1056 &SectionOffset, 1057 &ViewSize, 1058 ViewShare, 1059 0, 1060 PAGE_READWRITE); 1061 ok_ntstatus(Status, STATUS_SUCCESS); 1062 1063 printf("Mapped image section at %p, value in text section: %lx\n", 1064 ImageBase, *((ULONG*)((PCHAR)ImageBase + 0x1196))); 1065 system("PAUSE"); 1066 1067 /* Try to allocate a page after the section */ 1068 BaseAddress = (PUCHAR)ImageBase + 0x10000; 1069 ViewSize = 0x1000; 1070 Status = NtAllocateVirtualMemory(NtCurrentProcess(), 1071 &BaseAddress, 1072 0, 1073 &ViewSize, 1074 MEM_RESERVE | MEM_COMMIT, 1075 PAGE_READWRITE); 1076 printf("allocation status: %lx\n", Status); 1077 system("PAUSE"); 1078 1079 } 1080 1081 // doesn't work with WoW64! 1082 void 1083 Test_BasedSection(void) 1084 { 1085 NTSTATUS Status; 1086 HANDLE SectionHandle1, SectionHandle2; 1087 LARGE_INTEGER MaximumSize, SectionOffset; 1088 PVOID BaseAddress1, BaseAddress2; 1089 SIZE_T ViewSize; 1090 1091 /* Create a based section with SEC_COMMIT */ 1092 MaximumSize.QuadPart = 0x1000; 1093 Status = NtCreateSection(&SectionHandle1, 1094 SECTION_ALL_ACCESS, 1095 NULL, 1096 &MaximumSize, 1097 PAGE_READWRITE, 1098 SEC_COMMIT | SEC_BASED, 1099 NULL); 1100 ok_ntstatus(Status, STATUS_SUCCESS); 1101 1102 /* Map the 1st section */ 1103 BaseAddress1 = NULL; 1104 SectionOffset.QuadPart = 0; 1105 ViewSize = 0; 1106 Status = NtMapViewOfSection(SectionHandle1, 1107 NtCurrentProcess(), 1108 &BaseAddress1, 1109 0, 1110 0, 1111 &SectionOffset, 1112 &ViewSize, 1113 ViewShare, 1114 0, 1115 PAGE_READWRITE); 1116 #if 0 // WOW64? 1117 ok_ntstatus(Status, STATUS_CONFLICTING_ADDRESSES); 1118 #else 1119 ok_ntstatus(Status, STATUS_SUCCESS); 1120 #endif 1121 1122 /* Create a 2nd based section with SEC_COMMIT */ 1123 MaximumSize.QuadPart = 0x1000; 1124 Status = NtCreateSection(&SectionHandle2, 1125 SECTION_ALL_ACCESS, 1126 NULL, 1127 &MaximumSize, 1128 PAGE_READWRITE, 1129 SEC_COMMIT | SEC_BASED, 1130 NULL); 1131 ok_ntstatus(Status, STATUS_SUCCESS);// 1132 1133 /* Map the 2nd section */ 1134 BaseAddress2 = NULL; 1135 SectionOffset.QuadPart = 0; 1136 ViewSize = 0; 1137 Status = NtMapViewOfSection(SectionHandle2, 1138 NtCurrentProcess(), 1139 &BaseAddress2, 1140 0, 1141 0, 1142 &SectionOffset, 1143 &ViewSize, 1144 ViewShare, 1145 0, 1146 PAGE_READWRITE); 1147 #if 0 // WOW64? 1148 ok_ntstatus(Status, STATUS_CONFLICTING_ADDRESSES); 1149 #else 1150 ok_ntstatus(Status, STATUS_SUCCESS); 1151 ok((ULONG_PTR)BaseAddress2 < (ULONG_PTR)BaseAddress1, 1152 "Invalid addresses: BaseAddress1=%p, BaseAddress2=%p\n", BaseAddress1, BaseAddress2); 1153 ok(((ULONG_PTR)BaseAddress1 - (ULONG_PTR)BaseAddress2) == 0x10000, 1154 "Invalid addresses: BaseAddress1=%p, BaseAddress2=%p\n", BaseAddress1, BaseAddress2); 1155 #endif 1156 } 1157 1158 #define BYTES4(x) x, x, x, x 1159 #define BYTES8(x) BYTES4(x), BYTES4(x) 1160 #define BYTES16(x) BYTES8(x), BYTES8(x) 1161 #define BYTES32(x) BYTES16(x), BYTES16(x) 1162 #define BYTES64(x) BYTES32(x), BYTES32(x) 1163 #define BYTES128(x) BYTES64(x), BYTES64(x) 1164 #define BYTES256(x) BYTES128(x), BYTES128(x) 1165 #define BYTES512(x) BYTES256(x), BYTES256(x) 1166 #define BYTES1024(x) BYTES512(x), BYTES512(x) 1167 1168 static struct _SECTION_CONTENTS_IMAGE_FILE 1169 { 1170 IMAGE_DOS_HEADER doshdr; 1171 WORD stub[32]; 1172 IMAGE_NT_HEADERS32 nthdrs; 1173 IMAGE_SECTION_HEADER text_header; 1174 IMAGE_SECTION_HEADER rossym_header; 1175 IMAGE_SECTION_HEADER rsrc_header; 1176 IMAGE_SECTION_HEADER clc_header; 1177 BYTE pad[488]; 1178 BYTE text_data[0x400]; 1179 BYTE rossym_data[0x400]; 1180 BYTE rsrc_data[0x400]; 1181 BYTE clc_data[0x1000]; 1182 } SectionContentsImageFile = 1183 { 1184 /* IMAGE_DOS_HEADER */ 1185 { 1186 IMAGE_DOS_SIGNATURE, 144, 3, 0, 4, 0, 0xFFFF, 0, 0xB8, 0, 0, 0, 0x40, 1187 0, { 0 }, 0, 0, { 0 }, 0x80 1188 }, 1189 /* binary to print "This program cannot be run in DOS mode." */ 1190 { 1191 0x1F0E, 0x0EBA, 0xB400, 0xCD09, 0xB821, 0x4C01, 0x21CD, 0x6854, 0x7369, 1192 0x7020, 0x6F72, 0x7267, 0x6D61, 0x6320, 0x6E61, 0x6F6E, 0x2074, 0x6562, 1193 0x7220, 0x6E75, 0x6920, 0x206E, 0x4F44, 0x2053, 0x6F6D, 0x6564, 0x0D2E, 1194 0x0A0D, 0x0024, 0x0000, 0x0000, 0x0000 1195 }, 1196 /* IMAGE_NT_HEADERS32 */ 1197 { 1198 IMAGE_NT_SIGNATURE, /* Signature */ 1199 /* IMAGE_FILE_HEADER */ 1200 { 1201 IMAGE_FILE_MACHINE_I386, /* Machine */ 1202 4, /* NumberOfSections */ 1203 0x47EFDF09, /* TimeDateStamp */ 1204 0, /* PointerToSymbolTable */ 1205 0, /* NumberOfSymbols */ 1206 0xE0, /* SizeOfOptionalHeader */ 1207 IMAGE_FILE_32BIT_MACHINE | IMAGE_FILE_LOCAL_SYMS_STRIPPED | 1208 IMAGE_FILE_LINE_NUMS_STRIPPED | IMAGE_FILE_EXECUTABLE_IMAGE | 1209 IMAGE_FILE_DLL, /* Characteristics */ 1210 }, 1211 /* IMAGE_OPTIONAL_HEADER32 */ 1212 { 1213 IMAGE_NT_OPTIONAL_HDR32_MAGIC, /* Magic */ 1214 8, /* MajorLinkerVersion */ 1215 0, /* MinorLinkerVersion */ 1216 0x400, /* SizeOfCode */ 1217 0x000, /* SizeOfInitializedData */ 1218 0, /* SizeOfUninitializedData */ 1219 0x2000, /* AddressOfEntryPoint */ 1220 0x2000, /* BaseOfCode */ 1221 0x0000, /* BaseOfData */ 1222 0x400000, /* ImageBase */ 1223 0x2000, /* SectionAlignment */ 1224 0x200, /* FileAlignment */ 1225 4, /* MajorOperatingSystemVersion */ 1226 0, /* MinorOperatingSystemVersion */ 1227 0, /* MajorImageVersion */ 1228 0, /* MinorImageVersion */ 1229 4, /* MajorSubsystemVersion */ 1230 0, /* MinorSubsystemVersion */ 1231 0, /* Win32VersionValue */ 1232 0xa000, /* SizeOfImage */ 1233 0x400, /* SizeOfHeaders */ 1234 0x0, /* CheckSum */ 1235 IMAGE_SUBSYSTEM_WINDOWS_CUI, /* Subsystem */ 1236 IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE | 1237 IMAGE_DLLCHARACTERISTICS_NO_SEH | 1238 IMAGE_DLLCHARACTERISTICS_NX_COMPAT, /* DllCharacteristics */ 1239 0x100000, /* SizeOfStackReserve */ 1240 0x1000, /* SizeOfStackCommit */ 1241 0x100000, /* SizeOfHeapReserve */ 1242 0x1000, /* SizeOfHeapCommit */ 1243 0, /* LoaderFlags */ 1244 0x10, /* NumberOfRvaAndSizes */ 1245 /* IMAGE_DATA_DIRECTORY */ 1246 { 1247 { 0 }, /* Export Table */ 1248 { 0 }, /* Import Table */ 1249 { 0 }, /* Resource Table */ 1250 { 0 }, /* Exception Table */ 1251 { 0 }, /* Certificate Table */ 1252 { 0 }, /* Base Relocation Table */ 1253 { 0 }, /* Debug */ 1254 { 0 }, /* Copyright */ 1255 { 0 }, /* Global Ptr */ 1256 { 0 }, /* TLS Table */ 1257 { 0 }, /* Load Config Table */ 1258 { 0 }, /* Bound Import */ 1259 { 0 }, /* IAT */ 1260 { 0 }, /* Delay Import Descriptor */ 1261 { 0 }, /* CLI Header */ 1262 { 0 } /* Reserved */ 1263 } 1264 } 1265 }, 1266 /* IMAGE_SECTION_HEADER */ 1267 { 1268 ".text", /* Name */ 1269 { 0x394 }, /* Misc.VirtualSize */ 1270 0x2000, /* VirtualAddress */ 1271 0x400, /* SizeOfRawData */ 1272 0x400, /* PointerToRawData */ 1273 0, /* PointerToRelocations */ 1274 0, /* PointerToLinenumbers */ 1275 0, /* NumberOfRelocations */ 1276 0, /* NumberOfLinenumbers */ 1277 IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_EXECUTE | 1278 IMAGE_SCN_CNT_CODE, /* Characteristics */ 1279 }, 1280 /* IMAGE_SECTION_HEADER */ 1281 { 1282 ".rossym", /* Name */ 1283 { 0x100 }, /* Misc.VirtualSize */ 1284 0x4000, /* VirtualAddress */ 1285 0x400, /* SizeOfRawData */ 1286 0x800, /* PointerToRawData */ 1287 0, /* PointerToRelocations */ 1288 0, /* PointerToLinenumbers */ 1289 0, /* NumberOfRelocations */ 1290 0, /* NumberOfLinenumbers */ 1291 /* CORE-8384 */ 1292 IMAGE_SCN_MEM_READ | IMAGE_SCN_TYPE_NOLOAD, /* Characteristics */ 1293 }, 1294 /* IMAGE_SECTION_HEADER */ 1295 { 1296 ".rsrc", /* Name */ 1297 { 0x100 }, /* Misc.VirtualSize */ 1298 0x6000, /* VirtualAddress */ 1299 0x400, /* SizeOfRawData */ 1300 0xC00, /* PointerToRawData */ 1301 0, /* PointerToRelocations */ 1302 0, /* PointerToLinenumbers */ 1303 0, /* NumberOfRelocations */ 1304 0, /* NumberOfLinenumbers */ 1305 IMAGE_SCN_MEM_READ | 1306 IMAGE_SCN_CNT_INITIALIZED_DATA, /* Characteristics */ 1307 }, 1308 /* IMAGE_SECTION_HEADER */ 1309 { 1310 ".clc", /* Name */ 1311 { 0x2000 }, /* Misc.VirtualSize */ 1312 0x8000, /* VirtualAddress */ 1313 0x1000, /* SizeOfRawData */ 1314 0x1000, /* PointerToRawData */ 1315 0, /* PointerToRelocations */ 1316 0, /* PointerToLinenumbers */ 1317 0, /* NumberOfRelocations */ 1318 0, /* NumberOfLinenumbers */ 1319 /* CORE-12582 */ 1320 IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_EXECUTE | 1321 IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_CNT_CODE, /* Characteristics */ 1322 }, 1323 /* fill */ 1324 { 0 }, 1325 /* text */ 1326 { 0xc3, 0 }, 1327 /* rossym */ 1328 { 1329 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 1330 BYTES8(0xaa), 1331 BYTES16(0xbb), 1332 BYTES32(0xcc), 1333 BYTES64(0xdd), 1334 BYTES64(0xee), 1335 BYTES64(0xff), 1336 }, 1337 /* rsrc */ 1338 { 1339 BYTES128(0xee), 1340 BYTES128(0x55), 1341 BYTES128(0xee), 1342 BYTES128(0x11), 1343 BYTES128(0xff), 1344 BYTES128(0x00), 1345 BYTES128(0x00), 1346 BYTES128(0xdd), 1347 }, 1348 /* clc */ 1349 { 1350 BYTES512(0x11), 1351 BYTES512(0x22), 1352 BYTES512(0x33), 1353 BYTES512(0x44), 1354 BYTES512(0x55), 1355 BYTES512(0x66), 1356 BYTES512(0x77), 1357 BYTES512(0x88), 1358 }, 1359 }; 1360 1361 C_ASSERT(FIELD_OFFSET(struct _SECTION_CONTENTS_IMAGE_FILE, text_data) == 0x400); 1362 C_ASSERT(FIELD_OFFSET(struct _SECTION_CONTENTS_IMAGE_FILE, rossym_data) == 0x800); 1363 C_ASSERT(FIELD_OFFSET(struct _SECTION_CONTENTS_IMAGE_FILE, rsrc_data) == 0xc00); 1364 C_ASSERT(FIELD_OFFSET(struct _SECTION_CONTENTS_IMAGE_FILE, clc_data) == 0x1000); 1365 1366 static 1367 void 1368 Test_SectionContents(BOOL Relocate) 1369 { 1370 NTSTATUS Status; 1371 WCHAR TempPath[MAX_PATH]; 1372 WCHAR FileName[MAX_PATH]; 1373 HANDLE Handle; 1374 HANDLE SectionHandle; 1375 LARGE_INTEGER SectionOffset; 1376 PVOID BaseAddress; 1377 SIZE_T ViewSize; 1378 ULONG Written; 1379 ULONG Length; 1380 BOOL Success; 1381 1382 Length = GetTempPathW(MAX_PATH, TempPath); 1383 ok(Length != 0, "GetTempPathW failed with %lu\n", GetLastError()); 1384 Length = GetTempFileNameW(TempPath, L"nta", 0, FileName); 1385 ok(Length != 0, "GetTempFileNameW failed with %lu\n", GetLastError()); 1386 Handle = CreateFileW(FileName, 1387 FILE_ALL_ACCESS, 1388 0, 1389 NULL, 1390 CREATE_ALWAYS, 1391 0, 1392 NULL); 1393 if (Handle == INVALID_HANDLE_VALUE) 1394 { 1395 skip("Failed to create temp file %ls, error %lu\n", FileName, GetLastError()); 1396 return; 1397 } 1398 if (Relocate) 1399 { 1400 ok((ULONG_PTR)GetModuleHandle(NULL) <= 0x80000000, "Module at %p\n", GetModuleHandle(NULL)); 1401 SectionContentsImageFile.nthdrs.OptionalHeader.ImageBase = (ULONG)(ULONG_PTR)GetModuleHandle(NULL); 1402 } 1403 else 1404 { 1405 SectionContentsImageFile.nthdrs.OptionalHeader.ImageBase = 0xe400000; 1406 } 1407 1408 Success = WriteFile(Handle, 1409 &SectionContentsImageFile, 1410 sizeof(SectionContentsImageFile), 1411 &Written, 1412 NULL); 1413 ok(Success == TRUE, "WriteFile failed with %lu\n", GetLastError()); 1414 ok(Written == sizeof(SectionContentsImageFile), "WriteFile wrote %lu bytes\n", Written); 1415 1416 Status = NtCreateSection(&SectionHandle, 1417 SECTION_ALL_ACCESS, 1418 NULL, 1419 NULL, 1420 PAGE_EXECUTE_READWRITE, 1421 SEC_IMAGE, 1422 Handle); 1423 ok_ntstatus(Status, STATUS_SUCCESS); 1424 1425 if (NT_SUCCESS(Status)) 1426 { 1427 /* Map the section with */ 1428 BaseAddress = NULL; 1429 SectionOffset.QuadPart = 0; 1430 ViewSize = 0; 1431 Status = NtMapViewOfSection(SectionHandle, 1432 NtCurrentProcess(), 1433 &BaseAddress, 1434 0, 1435 0, 1436 &SectionOffset, 1437 &ViewSize, 1438 ViewShare, 1439 0, 1440 PAGE_READWRITE); 1441 if (Relocate) 1442 ok_ntstatus(Status, STATUS_IMAGE_NOT_AT_BASE); 1443 else 1444 ok_ntstatus(Status, STATUS_SUCCESS); 1445 if (NT_SUCCESS(Status)) 1446 { 1447 PUCHAR Bytes = BaseAddress; 1448 #define TEST_BYTE(n, v) StartSeh() ok_hex(Bytes[n], v); EndSeh(STATUS_SUCCESS); 1449 #define TEST_WRITE(n) StartSeh() *(volatile UCHAR *)&Bytes[n] = Bytes[n]; EndSeh(STATUS_SUCCESS); 1450 #define TEST_NOWRITE(n) StartSeh() *(volatile UCHAR *)&Bytes[n] = Bytes[n]; EndSeh(STATUS_ACCESS_VIOLATION); 1451 TEST_NOWRITE(0x2000); 1452 TEST_BYTE(0x2000, 0xc3); 1453 TEST_BYTE(0x2001, 0x00); 1454 TEST_NOWRITE(0x4000); 1455 TEST_BYTE(0x4000, 0x01); 1456 TEST_BYTE(0x4001, 0x23); 1457 TEST_BYTE(0x4007, 0xef); 1458 TEST_BYTE(0x4008, 0xaa); 1459 TEST_BYTE(0x4010, 0xbb); 1460 TEST_BYTE(0x4020, 0xcc); 1461 TEST_BYTE(0x4040, 0xdd); 1462 TEST_BYTE(0x4080, 0xee); 1463 TEST_BYTE(0x40c0, 0xff); 1464 TEST_BYTE(0x40ff, 0xff); 1465 TEST_BYTE(0x4100, 0x00); 1466 TEST_BYTE(0x41ff, 0x00); 1467 TEST_NOWRITE(0x6000); 1468 TEST_BYTE(0x6000, 0xee); 1469 TEST_BYTE(0x60ff, 0x55); 1470 TEST_BYTE(0x6100, 0xee); 1471 TEST_BYTE(0x63ff, 0xdd); 1472 TEST_BYTE(0x6400, 0x00); 1473 TEST_WRITE(0x8000); 1474 TEST_BYTE(0x8000, 0x11); 1475 TEST_BYTE(0x8400, 0x33); 1476 #undef TEST_BYTE 1477 #undef TEST_WRITE 1478 #undef TEST_NOWRITE 1479 Status = NtUnmapViewOfSection(NtCurrentProcess(), BaseAddress); 1480 ok_ntstatus(Status, STATUS_SUCCESS); 1481 } 1482 Status = NtClose(SectionHandle); 1483 ok_ntstatus(Status, STATUS_SUCCESS); 1484 } 1485 1486 CloseHandle(Handle); 1487 DeleteFileW(FileName); 1488 } 1489 1490 static struct _RAW_SIZE_IMAGE_FILE 1491 { 1492 IMAGE_DOS_HEADER doshdr; 1493 WORD stub[32]; 1494 IMAGE_NT_HEADERS32 nthdrs; 1495 IMAGE_SECTION_HEADER text_header; 1496 IMAGE_SECTION_HEADER data_header; 1497 IMAGE_SECTION_HEADER zdata_header; 1498 IMAGE_SECTION_HEADER rsrc_header; 1499 BYTE pad[488]; 1500 BYTE text_data[0x1200]; 1501 BYTE data_data[0x1200]; 1502 BYTE rsrc_data[0x400]; 1503 } RawSizeImageFile = 1504 { 1505 /* IMAGE_DOS_HEADER */ 1506 { 1507 IMAGE_DOS_SIGNATURE, 144, 3, 0, 4, 0, 0xFFFF, 0, 0xB8, 0, 0, 0, 0x40, 1508 0, { 0 }, 0, 0, { 0 }, 0x80 1509 }, 1510 /* binary to print "This program cannot be run in DOS mode." */ 1511 { 1512 0x1F0E, 0x0EBA, 0xB400, 0xCD09, 0xB821, 0x4C01, 0x21CD, 0x6854, 0x7369, 1513 0x7020, 0x6F72, 0x7267, 0x6D61, 0x6320, 0x6E61, 0x6F6E, 0x2074, 0x6562, 1514 0x7220, 0x6E75, 0x6920, 0x206E, 0x4F44, 0x2053, 0x6F6D, 0x6564, 0x0D2E, 1515 0x0A0D, 0x0024, 0x0000, 0x0000, 0x0000 1516 }, 1517 /* IMAGE_NT_HEADERS32 */ 1518 { 1519 IMAGE_NT_SIGNATURE, /* Signature */ 1520 /* IMAGE_FILE_HEADER */ 1521 { 1522 IMAGE_FILE_MACHINE_I386, /* Machine */ 1523 4, /* NumberOfSections */ 1524 0x47EFDF09, /* TimeDateStamp */ 1525 0, /* PointerToSymbolTable */ 1526 0, /* NumberOfSymbols */ 1527 0xE0, /* SizeOfOptionalHeader */ 1528 IMAGE_FILE_32BIT_MACHINE | IMAGE_FILE_LOCAL_SYMS_STRIPPED | 1529 IMAGE_FILE_LINE_NUMS_STRIPPED | IMAGE_FILE_EXECUTABLE_IMAGE | 1530 IMAGE_FILE_DLL, /* Characteristics */ 1531 }, 1532 /* IMAGE_OPTIONAL_HEADER32 */ 1533 { 1534 IMAGE_NT_OPTIONAL_HDR32_MAGIC, /* Magic */ 1535 8, /* MajorLinkerVersion */ 1536 0, /* MinorLinkerVersion */ 1537 0x400, /* SizeOfCode */ 1538 0x000, /* SizeOfInitializedData */ 1539 0, /* SizeOfUninitializedData */ 1540 0x1000, /* AddressOfEntryPoint */ 1541 0x1000, /* BaseOfCode */ 1542 0x0000, /* BaseOfData */ 1543 0x400000, /* ImageBase */ 1544 0x1000, /* SectionAlignment */ 1545 0x200, /* FileAlignment */ 1546 4, /* MajorOperatingSystemVersion */ 1547 0, /* MinorOperatingSystemVersion */ 1548 0, /* MajorImageVersion */ 1549 0, /* MinorImageVersion */ 1550 4, /* MajorSubsystemVersion */ 1551 0, /* MinorSubsystemVersion */ 1552 0, /* Win32VersionValue */ 1553 0x5000, /* SizeOfImage */ 1554 0x400, /* SizeOfHeaders */ 1555 0x0, /* CheckSum */ 1556 IMAGE_SUBSYSTEM_WINDOWS_CUI, /* Subsystem */ 1557 IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE | 1558 IMAGE_DLLCHARACTERISTICS_NO_SEH | 1559 IMAGE_DLLCHARACTERISTICS_NX_COMPAT, /* DllCharacteristics */ 1560 0x100000, /* SizeOfStackReserve */ 1561 0x1000, /* SizeOfStackCommit */ 1562 0x100000, /* SizeOfHeapReserve */ 1563 0x1000, /* SizeOfHeapCommit */ 1564 0, /* LoaderFlags */ 1565 0x10, /* NumberOfRvaAndSizes */ 1566 /* IMAGE_DATA_DIRECTORY */ 1567 { 1568 { 0 }, /* Export Table */ 1569 { 0 }, /* Import Table */ 1570 { 0 }, /* Resource Table */ 1571 { 0 }, /* Exception Table */ 1572 { 0 }, /* Certificate Table */ 1573 { 0 }, /* Base Relocation Table */ 1574 { 0 }, /* Debug */ 1575 { 0 }, /* Copyright */ 1576 { 0 }, /* Global Ptr */ 1577 { 0 }, /* TLS Table */ 1578 { 0 }, /* Load Config Table */ 1579 { 0 }, /* Bound Import */ 1580 { 0 }, /* IAT */ 1581 { 0 }, /* Delay Import Descriptor */ 1582 { 0 }, /* CLI Header */ 1583 { 0 } /* Reserved */ 1584 } 1585 } 1586 }, 1587 /* IMAGE_SECTION_HEADER */ 1588 { 1589 /* SizeOfRawData larger than VirtualSize */ 1590 ".text", /* Name */ 1591 { 0x1000 }, /* Misc.VirtualSize */ 1592 0x1000, /* VirtualAddress */ 1593 0x1200, /* SizeOfRawData */ 1594 0x400, /* PointerToRawData */ 1595 0, /* PointerToRelocations */ 1596 0, /* PointerToLinenumbers */ 1597 0, /* NumberOfRelocations */ 1598 0, /* NumberOfLinenumbers */ 1599 IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_EXECUTE | 1600 IMAGE_SCN_CNT_CODE, /* Characteristics */ 1601 }, 1602 /* IMAGE_SECTION_HEADER */ 1603 { 1604 /* SizeOfRawData larger than VirtualSize */ 1605 ".data", /* Name */ 1606 { 0x100 }, /* Misc.VirtualSize */ 1607 0x2000, /* VirtualAddress */ 1608 0x1200, /* SizeOfRawData */ 1609 0x1600, /* PointerToRawData */ 1610 0, /* PointerToRelocations */ 1611 0, /* PointerToLinenumbers */ 1612 0, /* NumberOfRelocations */ 1613 0, /* NumberOfLinenumbers */ 1614 IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_READ | 1615 IMAGE_SCN_CNT_INITIALIZED_DATA, /* Characteristics */ 1616 }, 1617 /* IMAGE_SECTION_HEADER */ 1618 { 1619 /* SizeOfRawData = 0 */ 1620 ".zdata", /* Name */ 1621 { 0x100 }, /* Misc.VirtualSize */ 1622 0x3000, /* VirtualAddress */ 1623 0, /* SizeOfRawData */ 1624 0x2800, /* PointerToRawData */ 1625 0, /* PointerToRelocations */ 1626 0, /* PointerToLinenumbers */ 1627 0, /* NumberOfRelocations */ 1628 0, /* NumberOfLinenumbers */ 1629 IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_READ | 1630 IMAGE_SCN_CNT_UNINITIALIZED_DATA, /* Characteristics */ 1631 }, 1632 /* IMAGE_SECTION_HEADER */ 1633 { 1634 /* VirtualSize larger than SizeOfRawData */ 1635 ".rsrc", /* Name */ 1636 { 0x300 }, /* Misc.VirtualSize */ 1637 0x4000, /* VirtualAddress */ 1638 0x200, /* SizeOfRawData */ 1639 0x2800, /* PointerToRawData */ 1640 0, /* PointerToRelocations */ 1641 0, /* PointerToLinenumbers */ 1642 0, /* NumberOfRelocations */ 1643 0, /* NumberOfLinenumbers */ 1644 IMAGE_SCN_MEM_READ | 1645 IMAGE_SCN_CNT_INITIALIZED_DATA, /* Characteristics */ 1646 }, 1647 /* fill */ 1648 { 0 }, 1649 /* text */ 1650 { 1651 0xc3, 0, 0, 0, 0, 0, 0, 0, 1652 BYTES8(1), 1653 BYTES16(2), 1654 BYTES32(3), 1655 BYTES64(4), 1656 BYTES128(5), 1657 BYTES256(6), 1658 BYTES512(7), 1659 BYTES1024(8), 1660 BYTES1024(9), 1661 BYTES1024(0xa), 1662 BYTES512(0xb), 1663 }, 1664 /* data */ 1665 { 1666 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 1667 BYTES8(0xaa), 1668 BYTES16(0xbb), 1669 BYTES32(0xcc), 1670 BYTES64(0xdd), 1671 BYTES128(0xee), 1672 BYTES256(0xff), 1673 BYTES512(0xee), 1674 BYTES1024(0xdd), 1675 BYTES1024(0xcc), 1676 BYTES1024(0xbb), 1677 BYTES512(0xaa), 1678 }, 1679 /* rsrc */ 1680 { 1681 BYTES256(0xff), 1682 BYTES128(0xee), 1683 BYTES64(0xdd), 1684 BYTES32(0xcc), 1685 BYTES16(0xbb), 1686 BYTES8(0xaa), 1687 0xef, 0xcd, 0xab, 0x89, 0x67, 0x45, 0x23, 0x01, 1688 }, 1689 }; 1690 1691 C_ASSERT(FIELD_OFFSET(struct _RAW_SIZE_IMAGE_FILE, text_data) == 0x400); 1692 C_ASSERT(FIELD_OFFSET(struct _RAW_SIZE_IMAGE_FILE, data_data) == 0x1600); 1693 C_ASSERT(FIELD_OFFSET(struct _RAW_SIZE_IMAGE_FILE, rsrc_data) == 0x2800); 1694 1695 // CORE-17284 1696 static 1697 void 1698 Test_RawSize(ULONG TestNumber) 1699 { 1700 NTSTATUS Status; 1701 WCHAR TempPath[MAX_PATH]; 1702 WCHAR FileName[MAX_PATH]; 1703 HANDLE Handle; 1704 HANDLE SectionHandle; 1705 LARGE_INTEGER SectionOffset; 1706 PVOID BaseAddress; 1707 SIZE_T ViewSize; 1708 ULONG Written; 1709 ULONG Length; 1710 BOOL Success; 1711 1712 Length = GetTempPathW(MAX_PATH, TempPath); 1713 ok(Length != 0, "GetTempPathW failed with %lu\n", GetLastError()); 1714 Length = GetTempFileNameW(TempPath, L"nta", 0, FileName); 1715 ok(Length != 0, "GetTempFileNameW failed with %lu\n", GetLastError()); 1716 Handle = CreateFileW(FileName, 1717 FILE_ALL_ACCESS, 1718 0, 1719 NULL, 1720 CREATE_ALWAYS, 1721 0, 1722 NULL); 1723 if (Handle == INVALID_HANDLE_VALUE) 1724 { 1725 skip("Failed to create temp file %ls, error %lu\n", FileName, GetLastError()); 1726 return; 1727 } 1728 RawSizeImageFile.nthdrs.OptionalHeader.ImageBase = 0xe400000; 1729 if (TestNumber == 1) 1730 { 1731 /* Just for fun, show that these flags don't matter. */ 1732 RawSizeImageFile.text_header.Characteristics &= ~(IMAGE_SCN_CNT_CODE | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_CNT_UNINITIALIZED_DATA); 1733 RawSizeImageFile.data_header.Characteristics &= ~(IMAGE_SCN_CNT_CODE | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_CNT_UNINITIALIZED_DATA); 1734 RawSizeImageFile.zdata_header.Characteristics &= ~(IMAGE_SCN_CNT_CODE | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_CNT_UNINITIALIZED_DATA); 1735 RawSizeImageFile.rsrc_header.Characteristics &= ~(IMAGE_SCN_CNT_CODE | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_CNT_UNINITIALIZED_DATA); 1736 } 1737 else if (TestNumber == 2) 1738 { 1739 /* SizeOfRawData is too large and will overflow. 1740 * This should cause failure to load the file */ 1741 RawSizeImageFile.rsrc_header.SizeOfRawData = (ULONG)-0x200; 1742 } 1743 1744 Success = WriteFile(Handle, 1745 &RawSizeImageFile, 1746 sizeof(RawSizeImageFile), 1747 &Written, 1748 NULL); 1749 ok(Success == TRUE, "WriteFile failed with %lu\n", GetLastError()); 1750 ok(Written == sizeof(RawSizeImageFile), "WriteFile wrote %lu bytes\n", Written); 1751 1752 Status = NtCreateSection(&SectionHandle, 1753 SECTION_ALL_ACCESS, 1754 NULL, 1755 NULL, 1756 PAGE_EXECUTE_READWRITE, 1757 SEC_IMAGE, 1758 Handle); 1759 if (TestNumber == 2) 1760 { 1761 /* overflow in SizeOfRawData */ 1762 ok_ntstatus(Status, STATUS_INVALID_IMAGE_FORMAT); 1763 } 1764 else 1765 { 1766 ok_ntstatus(Status, STATUS_SUCCESS); 1767 } 1768 1769 if (NT_SUCCESS(Status)) 1770 { 1771 /* Map the section with */ 1772 BaseAddress = NULL; 1773 SectionOffset.QuadPart = 0; 1774 ViewSize = 0; 1775 Status = NtMapViewOfSection(SectionHandle, 1776 NtCurrentProcess(), 1777 &BaseAddress, 1778 0, 1779 0, 1780 &SectionOffset, 1781 &ViewSize, 1782 ViewShare, 1783 0, 1784 PAGE_READWRITE); 1785 ok_ntstatus(Status, STATUS_SUCCESS); 1786 if (NT_SUCCESS(Status)) 1787 { 1788 PUCHAR Bytes = BaseAddress; 1789 struct _RAW_SIZE_IMAGE_FILE *ImageFile = BaseAddress; 1790 1791 /* .text section header is unmodified */ 1792 ok_hex(ImageFile->text_header.Misc.VirtualSize, RawSizeImageFile.text_header.Misc.VirtualSize); 1793 ok_hex(ImageFile->text_header.VirtualAddress, RawSizeImageFile.text_header.VirtualAddress); 1794 ok_hex(ImageFile->text_header.SizeOfRawData, RawSizeImageFile.text_header.SizeOfRawData); 1795 ok_hex(ImageFile->text_header.PointerToRawData, RawSizeImageFile.text_header.PointerToRawData); 1796 1797 /* SizeOfRawData = 0 resets PointerToRawData to 0 */ 1798 ok_hex(ImageFile->zdata_header.Misc.VirtualSize, RawSizeImageFile.zdata_header.Misc.VirtualSize); 1799 ok_hex(ImageFile->zdata_header.VirtualAddress, RawSizeImageFile.zdata_header.VirtualAddress); 1800 ok_hex(ImageFile->zdata_header.SizeOfRawData, RawSizeImageFile.zdata_header.SizeOfRawData); 1801 ok_hex(ImageFile->zdata_header.PointerToRawData, 0); 1802 1803 #define TEST_BYTE(n, v) \ 1804 StartSeh() \ 1805 ok(Bytes[n] == v, "[%lu] Bytes[%u] = 0x%x, expected 0x%x\n", \ 1806 TestNumber, n, Bytes[n], v); \ 1807 EndSeh(STATUS_SUCCESS); 1808 /* .text section data matches file up to 0x1000 */ 1809 TEST_BYTE(0x1000, 0xc3); 1810 TEST_BYTE(0x1001, 0x00); 1811 TEST_BYTE(0x1008, 0x01); 1812 TEST_BYTE(0x1010, 0x02); 1813 TEST_BYTE(0x1fff, 0x0a); 1814 1815 /* .data section data matches file up to 0x1000 */ 1816 TEST_BYTE(0x2000, 0x01); 1817 TEST_BYTE(0x2001, 0x23); 1818 TEST_BYTE(0x20ff, 0xee); 1819 TEST_BYTE(0x2100, 0xff); 1820 TEST_BYTE(0x2fff, 0xbb); 1821 1822 /* .zdata section data is all zeroes */ 1823 TEST_BYTE(0x3000, 0x00); 1824 TEST_BYTE(0x3001, 0x00); 1825 TEST_BYTE(0x3800, 0x00); 1826 TEST_BYTE(0x3fff, 0x00); 1827 1828 /* .rsrc section data matches file up to VirtualSize 0x200 */ 1829 TEST_BYTE(0x4000, 0xff); 1830 TEST_BYTE(0x4100, 0xee); 1831 TEST_BYTE(0x4180, 0xdd); 1832 TEST_BYTE(0x41c0, 0xcc); 1833 TEST_BYTE(0x41e0, 0xbb); 1834 TEST_BYTE(0x41f0, 0xaa); 1835 TEST_BYTE(0x41fe, 0x23); 1836 TEST_BYTE(0x41ff, 0x01); 1837 TEST_BYTE(0x4200, 0x00); 1838 TEST_BYTE(0x4fff, 0x00); 1839 #undef TEST_BYTE 1840 Status = NtUnmapViewOfSection(NtCurrentProcess(), BaseAddress); 1841 ok_ntstatus(Status, STATUS_SUCCESS); 1842 } 1843 Status = NtClose(SectionHandle); 1844 ok_ntstatus(Status, STATUS_SUCCESS); 1845 } 1846 1847 CloseHandle(Handle); 1848 DeleteFileW(FileName); 1849 } 1850 1851 static void 1852 Test_EmptyFile(VOID) 1853 { 1854 NTSTATUS Status; 1855 WCHAR TempPath[MAX_PATH]; 1856 WCHAR FileName[MAX_PATH]; 1857 HANDLE Handle; 1858 HANDLE SectionHandle; 1859 ULONG Length; 1860 1861 Length = GetTempPathW(MAX_PATH, TempPath); 1862 ok(Length != 0, "GetTempPathW failed with %lu\n", GetLastError()); 1863 Length = GetTempFileNameW(TempPath, L"nta", 0, FileName); 1864 ok(Length != 0, "GetTempFileNameW failed with %lu\n", GetLastError()); 1865 Handle = CreateFileW(FileName, 1866 FILE_ALL_ACCESS, 1867 0, 1868 NULL, 1869 CREATE_ALWAYS, 1870 0, 1871 NULL); 1872 if (Handle == INVALID_HANDLE_VALUE) 1873 { 1874 skip("Failed to create temp file %ls, error %lu\n", FileName, GetLastError()); 1875 return; 1876 } 1877 1878 Status = NtCreateSection(&SectionHandle, 1879 STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ, 1880 0, 0, PAGE_READONLY, SEC_COMMIT, Handle); 1881 ok_ntstatus(Status, STATUS_MAPPED_FILE_SIZE_ZERO); 1882 1883 if (NT_SUCCESS(Status)) 1884 NtClose(SectionHandle); 1885 1886 Status = NtCreateSection(&SectionHandle, 1887 STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ, 1888 0, 0, PAGE_READONLY, SEC_IMAGE, Handle); 1889 ok_ntstatus(Status, STATUS_INVALID_FILE_FOR_SECTION); 1890 1891 if (NT_SUCCESS(Status)) 1892 NtClose(SectionHandle); 1893 1894 CloseHandle(Handle); 1895 DeleteFileW(FileName); 1896 } 1897 1898 // CORE-11206 1899 static void 1900 Test_Truncate(VOID) 1901 { 1902 WCHAR TempPath[MAX_PATH]; 1903 WCHAR FileName[MAX_PATH]; 1904 NTSTATUS Status; 1905 SIZE_T ViewSize = 0; 1906 HANDLE Handle; 1907 HANDLE SectionHandle; 1908 1909 SIZE_T Length; 1910 BOOL Success; 1911 DWORD Written, Error; 1912 VOID* BaseAddress; 1913 1914 Length = GetTempPathW(MAX_PATH, TempPath); 1915 ok(Length != 0, "GetTempPathW failed with %lu\n", GetLastError()); 1916 Length = GetTempFileNameW(TempPath, L"nta", 0, FileName); 1917 ok(Length != 0, "GetTempFileNameW failed with %lu\n", GetLastError()); 1918 Handle = CreateFileW(FileName, FILE_ALL_ACCESS, 0, NULL, CREATE_ALWAYS, 0, NULL); 1919 1920 Success = WriteFile(Handle, "TESTDATA", 8, &Written, NULL); 1921 ok(Success == TRUE, "WriteFile failed with %lu\n", GetLastError()); 1922 ok(Written == 8, "WriteFile wrote %lu bytes\n", Written); 1923 1924 Written = SetFilePointer(Handle, 6, NULL, FILE_BEGIN); 1925 ok(Written == 6, "SetFilePointer returned %lu bytes\n", Written); 1926 Success = SetEndOfFile(Handle); 1927 ok(Success == TRUE, "SetEndOfFile failed with %lu\n", GetLastError()); 1928 1929 Status = NtCreateSection(&SectionHandle, 1930 STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ, 1931 0, 0, PAGE_READONLY, SEC_COMMIT, Handle); 1932 ok_ntstatus(Status, STATUS_SUCCESS); 1933 BaseAddress = NULL; 1934 ViewSize = 0; 1935 Status = NtMapViewOfSection(SectionHandle, NtCurrentProcess(), &BaseAddress, 0, 1936 0, 0, &ViewSize, ViewShare, 0, PAGE_READONLY); 1937 ok_ntstatus(Status, STATUS_SUCCESS); 1938 1939 if (BaseAddress) 1940 { 1941 // First we test data that was truncated even before the file mapping was opened 1942 Length = strlen((char*)BaseAddress); 1943 ok(Length == 6, "Old data was not properly erased! (Length=%lu)\n", Length); 1944 } 1945 1946 // Now we truncate the file on disk some more 1947 Written = SetFilePointer(Handle, 4, NULL, FILE_BEGIN); 1948 ok(Written == 4, "SetFilePointer returned %lu bytes\n", Written); 1949 Success = SetEndOfFile(Handle); 1950 Error = GetLastError(); 1951 ok(Success == FALSE, "SetEndOfFile succeeded\n"); 1952 ok(Error == ERROR_USER_MAPPED_FILE, "SetEndOfFile did not set error to ERROR_USER_MAPPED_FILE (%lu)\n", Error); 1953 1954 if (BaseAddress) 1955 { 1956 Length = strlen((char*)BaseAddress); 1957 ok(Length == 6, "Length should not have changed! (Length=%lu)\n", Length); 1958 } 1959 1960 // Unmap and set the end shorter. 1961 Status = NtUnmapViewOfSection(NtCurrentProcess(), BaseAddress); 1962 ok_ntstatus(Status, STATUS_SUCCESS); 1963 Success = CloseHandle(SectionHandle); 1964 ok(Success == TRUE, "CloseHandle failed with %lu\n", GetLastError()); 1965 1966 Written = SetFilePointer(Handle, 4, NULL, FILE_BEGIN); 1967 ok(Written == 4, "SetFilePointer returned %lu bytes\n", Written); 1968 Success = SetEndOfFile(Handle); 1969 ok(Success == TRUE, "SetEndOfFile failed with %lu\n", GetLastError()); 1970 1971 Status = NtCreateSection(&SectionHandle, 1972 STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ, 1973 0, 0, PAGE_READONLY, SEC_COMMIT, Handle); 1974 ok_ntstatus(Status, STATUS_SUCCESS); 1975 BaseAddress = NULL; 1976 ViewSize = 0; 1977 Status = NtMapViewOfSection(SectionHandle, NtCurrentProcess(), &BaseAddress, 0, 1978 0, 0, &ViewSize, ViewShare, 0, PAGE_READONLY); 1979 ok_ntstatus(Status, STATUS_SUCCESS); 1980 1981 // CLEANUP 1982 Status = NtUnmapViewOfSection(NtCurrentProcess(), BaseAddress); 1983 ok_ntstatus(Status, STATUS_SUCCESS); 1984 Success = CloseHandle(SectionHandle); 1985 ok(Success == TRUE, "CloseHandle failed with %lu\n", GetLastError()); 1986 Success = CloseHandle(Handle); 1987 ok(Success == TRUE, "CloseHandle failed with %lu\n", GetLastError()); 1988 1989 Success = DeleteFileW(FileName); 1990 ok(Success == TRUE, "DeleteFileW failed with %lu\n", GetLastError()); 1991 } 1992 1993 START_TEST(NtMapViewOfSection) 1994 { 1995 Test_PageFileSection(); 1996 Test_ImageSection(); 1997 Test_BasedSection(); 1998 Test_SectionContents(FALSE); 1999 Test_SectionContents(TRUE); 2000 Test_RawSize(0); 2001 Test_RawSize(1); 2002 Test_RawSize(2); 2003 Test_EmptyFile(); 2004 Test_Truncate(); 2005 } 2006