Reactos

[SETUPLIB] Code re-organization in bootsup.c and fsutil.c.

- Move the actual VBR bootcode installation helpers into fsutil.c
(they depend on the selected filesystem).

- Introduce InstallBootCodeToDisk() and InstallBootCodeToFile()
and bootcode.c helpers, in order to replace the several functions
that were duplicating the same code.

+715 -1243
+1
base/setup/lib/CMakeLists.txt
··· 16 16 utils/osdetect.c 17 17 utils/partlist.c 18 18 utils/regutil.c 19 + bootcode.c 19 20 bootsup.c 20 21 fsutil.c 21 22 install.c
+116
base/setup/lib/bootcode.c
··· 1 + /* 2 + * PROJECT: ReactOS Setup Library 3 + * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) 4 + * PURPOSE: BootCode support functions. 5 + * COPYRIGHT: Copyright 2020 Hermes Belusca-Maito 6 + */ 7 + 8 + /* INCLUDES *****************************************************************/ 9 + 10 + #include "precomp.h" 11 + 12 + #include "bootcode.h" 13 + 14 + #define NDEBUG 15 + #include <debug.h> 16 + 17 + 18 + /* FUNCTIONS ****************************************************************/ 19 + 20 + NTSTATUS 21 + ReadBootCodeByHandle( 22 + IN OUT PBOOTCODE BootCodeInfo, 23 + IN HANDLE FileHandle, 24 + IN ULONG Length OPTIONAL) 25 + { 26 + NTSTATUS Status; 27 + PVOID BootCode; 28 + IO_STATUS_BLOCK IoStatusBlock; 29 + LARGE_INTEGER FileOffset; 30 + 31 + ASSERT(BootCodeInfo); 32 + 33 + /* Normalize the bootcode length */ 34 + if (Length == 0 || Length == (ULONG)-1) 35 + Length = SECTORSIZE; 36 + 37 + /* Allocate a buffer for the bootcode */ 38 + BootCode = RtlAllocateHeap(ProcessHeap, HEAP_ZERO_MEMORY, Length); 39 + if (BootCode == NULL) 40 + return STATUS_INSUFFICIENT_RESOURCES; 41 + 42 + /* Read the bootcode from the file into the buffer */ 43 + FileOffset.QuadPart = 0ULL; 44 + Status = NtReadFile(FileHandle, 45 + NULL, 46 + NULL, 47 + NULL, 48 + &IoStatusBlock, 49 + BootCode, 50 + Length, 51 + &FileOffset, 52 + NULL); 53 + if (!NT_SUCCESS(Status)) 54 + { 55 + RtlFreeHeap(ProcessHeap, 0, BootCode); 56 + return Status; 57 + } 58 + 59 + /* Update the bootcode information */ 60 + if (BootCodeInfo->BootCode) 61 + RtlFreeHeap(ProcessHeap, 0, BootCodeInfo->BootCode); 62 + BootCodeInfo->BootCode = BootCode; 63 + /**/ BootCodeInfo->Length = Length; /**/ 64 + 65 + return STATUS_SUCCESS; 66 + } 67 + 68 + NTSTATUS 69 + ReadBootCodeFromFile( 70 + IN OUT PBOOTCODE BootCodeInfo, 71 + IN PUNICODE_STRING FilePath, 72 + IN ULONG Length OPTIONAL) 73 + { 74 + NTSTATUS Status; 75 + OBJECT_ATTRIBUTES ObjectAttributes; 76 + IO_STATUS_BLOCK IoStatusBlock; 77 + HANDLE FileHandle; 78 + 79 + ASSERT(BootCodeInfo); 80 + 81 + /* Open the file */ 82 + InitializeObjectAttributes(&ObjectAttributes, 83 + FilePath, 84 + OBJ_CASE_INSENSITIVE, 85 + NULL, 86 + NULL); 87 + Status = NtOpenFile(&FileHandle, 88 + GENERIC_READ | SYNCHRONIZE, 89 + &ObjectAttributes, 90 + &IoStatusBlock, 91 + FILE_SHARE_READ | FILE_SHARE_WRITE, // Is FILE_SHARE_WRITE necessary? 92 + FILE_SYNCHRONOUS_IO_NONALERT); 93 + if (!NT_SUCCESS(Status)) 94 + return Status; 95 + 96 + Status = ReadBootCodeByHandle(BootCodeInfo, FileHandle, Length); 97 + 98 + /* Close the file and return */ 99 + NtClose(FileHandle); 100 + return Status; 101 + } 102 + 103 + VOID 104 + FreeBootCode( 105 + IN OUT PBOOTCODE BootCodeInfo) 106 + { 107 + ASSERT(BootCodeInfo); 108 + 109 + /* Update the bootcode information */ 110 + if (BootCodeInfo->BootCode) 111 + RtlFreeHeap(ProcessHeap, 0, BootCodeInfo->BootCode); 112 + BootCodeInfo->BootCode = NULL; 113 + /**/ BootCodeInfo->Length = 0; /**/ 114 + } 115 + 116 + /* EOF */
+37
base/setup/lib/bootcode.h
··· 1 + /* 2 + * PROJECT: ReactOS Setup Library 3 + * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) 4 + * PURPOSE: BootCode support functions. 5 + * COPYRIGHT: Copyright 2020 Hermes Belusca-Maito 6 + */ 7 + 8 + #pragma once 9 + 10 + #ifdef SECTORSIZE 11 + #undef SECTORSIZE 12 + #endif 13 + #define SECTORSIZE 512 14 + 15 + typedef struct _BOOTCODE 16 + { 17 + PVOID BootCode; 18 + ULONG Length; 19 + } BOOTCODE, *PBOOTCODE; 20 + 21 + NTSTATUS 22 + ReadBootCodeByHandle( 23 + IN OUT PBOOTCODE BootCodeInfo, 24 + IN HANDLE FileHandle, 25 + IN ULONG Length OPTIONAL); 26 + 27 + NTSTATUS 28 + ReadBootCodeFromFile( 29 + IN OUT PBOOTCODE BootCodeInfo, 30 + IN PUNICODE_STRING FilePath, 31 + IN ULONG Length OPTIONAL); 32 + 33 + VOID 34 + FreeBootCode( 35 + IN OUT PBOOTCODE BootCodeInfo); 36 + 37 + /* EOF */
+142 -1239
base/setup/lib/bootsup.c
··· 13 13 14 14 #include "bldrsup.h" 15 15 #include "filesup.h" 16 + #include "partlist.h" 17 + #include "bootcode.h" 16 18 #include "fsutil.h" 17 - #include "partlist.h" 18 19 19 20 #include "setuplib.h" // HAXX for IsUnattendedSetup!! 20 21 ··· 23 24 #define NDEBUG 24 25 #include <debug.h> 25 26 26 - 27 - /* TYPEDEFS *****************************************************************/ 28 - 29 27 /* 30 28 * BIG FIXME!! 31 29 * =========== 32 30 * 33 - * All that stuff *MUST* go into the fsutil.c module. 34 - * Indeed, all that relates to filesystem formatting details and as such 35 - * *MUST* be abstracted out from this module (bootsup.c). 36 - * However, bootsup.c can still deal with MBR code (actually it'll have 37 - * at some point to share or give it to partlist.c, because when we'll 38 - * support GPT disks, things will change a bit). 39 - * And, bootsup.c can still manage initializing / adding boot entries 40 - * into NTLDR and FREELDR, and installing the latter, and saving the old 41 - * MBR / boot sectors in files. 31 + * bootsup.c can deal with MBR code (actually it'll have at some point 32 + * to share or give it to partlist.c, because when we'll support GPT disks, 33 + * things will change a bit). 34 + * And, bootsup.c can manage initializing / adding boot entries into NTLDR 35 + * and FREELDR, and installing the latter, and saving the old MBR / boot 36 + * sectors in files. 42 37 */ 43 - #define SECTORSIZE 512 44 - 45 - #include <pshpack1.h> 46 - typedef struct _FAT_BOOTSECTOR 47 - { 48 - UCHAR JumpBoot[3]; // Jump instruction to boot code 49 - CHAR OemName[8]; // "MSWIN4.1" for MS formatted volumes 50 - USHORT BytesPerSector; // Bytes per sector 51 - UCHAR SectorsPerCluster; // Number of sectors in a cluster 52 - USHORT ReservedSectors; // Reserved sectors, usually 1 (the bootsector) 53 - UCHAR NumberOfFats; // Number of FAT tables 54 - USHORT RootDirEntries; // Number of root directory entries (fat12/16) 55 - USHORT TotalSectors; // Number of total sectors on the drive, 16-bit 56 - UCHAR MediaDescriptor; // Media descriptor byte 57 - USHORT SectorsPerFat; // Sectors per FAT table (fat12/16) 58 - USHORT SectorsPerTrack; // Number of sectors in a track 59 - USHORT NumberOfHeads; // Number of heads on the disk 60 - ULONG HiddenSectors; // Hidden sectors (sectors before the partition start like the partition table) 61 - ULONG TotalSectorsBig; // This field is the new 32-bit total count of sectors on the volume 62 - UCHAR DriveNumber; // Int 0x13 drive number (e.g. 0x80) 63 - UCHAR Reserved1; // Reserved (used by Windows NT). Code that formats FAT volumes should always set this byte to 0. 64 - UCHAR BootSignature; // Extended boot signature (0x29). This is a signature byte that indicates that the following three fields in the boot sector are present. 65 - ULONG VolumeSerialNumber; // Volume serial number 66 - CHAR VolumeLabel[11]; // Volume label. This field matches the 11-byte volume label recorded in the root directory 67 - CHAR FileSystemType[8]; // One of the strings "FAT12 ", "FAT16 ", or "FAT " 68 - 69 - UCHAR BootCodeAndData[448]; // The remainder of the boot sector 70 - 71 - USHORT BootSectorMagic; // 0xAA55 72 - 73 - } FAT_BOOTSECTOR, *PFAT_BOOTSECTOR; 74 - 75 - typedef struct _FAT32_BOOTSECTOR 76 - { 77 - UCHAR JumpBoot[3]; // Jump instruction to boot code 78 - CHAR OemName[8]; // "MSWIN4.1" for MS formatted volumes 79 - USHORT BytesPerSector; // Bytes per sector 80 - UCHAR SectorsPerCluster; // Number of sectors in a cluster 81 - USHORT ReservedSectors; // Reserved sectors, usually 1 (the bootsector) 82 - UCHAR NumberOfFats; // Number of FAT tables 83 - USHORT RootDirEntries; // Number of root directory entries (fat12/16) 84 - USHORT TotalSectors; // Number of total sectors on the drive, 16-bit 85 - UCHAR MediaDescriptor; // Media descriptor byte 86 - USHORT SectorsPerFat; // Sectors per FAT table (fat12/16) 87 - USHORT SectorsPerTrack; // Number of sectors in a track 88 - USHORT NumberOfHeads; // Number of heads on the disk 89 - ULONG HiddenSectors; // Hidden sectors (sectors before the partition start like the partition table) 90 - ULONG TotalSectorsBig; // This field is the new 32-bit total count of sectors on the volume 91 - ULONG SectorsPerFatBig; // This field is the FAT32 32-bit count of sectors occupied by ONE FAT. BPB_FATSz16 must be 0 92 - USHORT ExtendedFlags; // Extended flags (fat32) 93 - USHORT FileSystemVersion; // File system version (fat32) 94 - ULONG RootDirStartCluster; // Starting cluster of the root directory (fat32) 95 - USHORT FsInfo; // Sector number of FSINFO structure in the reserved area of the FAT32 volume. Usually 1. 96 - USHORT BackupBootSector; // If non-zero, indicates the sector number in the reserved area of the volume of a copy of the boot record. Usually 6. 97 - UCHAR Reserved[12]; // Reserved for future expansion 98 - UCHAR DriveNumber; // Int 0x13 drive number (e.g. 0x80) 99 - UCHAR Reserved1; // Reserved (used by Windows NT). Code that formats FAT volumes should always set this byte to 0. 100 - UCHAR BootSignature; // Extended boot signature (0x29). This is a signature byte that indicates that the following three fields in the boot sector are present. 101 - ULONG VolumeSerialNumber; // Volume serial number 102 - CHAR VolumeLabel[11]; // Volume label. This field matches the 11-byte volume label recorded in the root directory 103 - CHAR FileSystemType[8]; // Always set to the string "FAT32 " 104 - 105 - UCHAR BootCodeAndData[420]; // The remainder of the boot sector 106 - 107 - USHORT BootSectorMagic; // 0xAA55 108 - 109 - } FAT32_BOOTSECTOR, *PFAT32_BOOTSECTOR; 110 - 111 - typedef struct _BTRFS_BOOTSECTOR 112 - { 113 - UCHAR JumpBoot[3]; 114 - UCHAR ChunkMapSize; 115 - UCHAR BootDrive; 116 - ULONGLONG PartitionStartLBA; 117 - UCHAR Fill[1521]; // 1536 - 15 118 - USHORT BootSectorMagic; 119 - } BTRFS_BOOTSECTOR, *PBTRFS_BOOTSECTOR; 120 - C_ASSERT(sizeof(BTRFS_BOOTSECTOR) == 3 * 512); 121 - 122 - // TODO: Add more bootsector structures! 123 - 124 - #include <poppack.h> 125 - 126 - /* End of BIG FIXME!! */ 127 - 128 38 129 39 /* FUNCTIONS ****************************************************************/ 130 40 ··· 550 460 BOOLEAN IsValid = FALSE; 551 461 NTSTATUS Status; 552 462 UNICODE_STRING RootPartition; 553 - OBJECT_ATTRIBUTES ObjectAttributes; 554 - IO_STATUS_BLOCK IoStatusBlock; 555 - HANDLE FileHandle; 556 - LARGE_INTEGER FileOffset; 557 - PUCHAR BootSector; 463 + BOOTCODE BootSector = {0}; 558 464 559 - /* Allocate buffer for bootsector */ 560 - BootSector = RtlAllocateHeap(ProcessHeap, 0, SECTORSIZE); 561 - if (BootSector == NULL) 562 - return FALSE; // STATUS_INSUFFICIENT_RESOURCES; 563 - RtlZeroMemory(BootSector, SECTORSIZE); 564 - 565 - /* Open the root partition - Remove any trailing backslash if needed */ 465 + /* Allocate and read the root partition bootsector. 466 + * Remove any trailing backslash if needed. */ 566 467 RtlInitUnicodeString(&RootPartition, RootPath); 567 468 TrimTrailingPathSeparators_UStr(&RootPartition); 568 - 569 - InitializeObjectAttributes(&ObjectAttributes, 570 - &RootPartition, 571 - OBJ_CASE_INSENSITIVE, 572 - NULL, 573 - NULL); 574 - 575 - Status = NtOpenFile(&FileHandle, 576 - GENERIC_READ | SYNCHRONIZE, 577 - &ObjectAttributes, 578 - &IoStatusBlock, 579 - FILE_SHARE_READ | FILE_SHARE_WRITE, 580 - FILE_SYNCHRONOUS_IO_NONALERT); 581 - if (!NT_SUCCESS(Status)) 582 - goto Quit; 583 - 584 - /* Read current boot sector into buffer */ 585 - FileOffset.QuadPart = 0ULL; 586 - Status = NtReadFile(FileHandle, 587 - NULL, 588 - NULL, 589 - NULL, 590 - &IoStatusBlock, 591 - BootSector, 592 - SECTORSIZE, 593 - &FileOffset, 594 - NULL); 595 - NtClose(FileHandle); 469 + Status = ReadBootCodeFromFile(&BootSector, &RootPartition, SECTORSIZE); 596 470 if (!NT_SUCCESS(Status)) 597 - goto Quit; 471 + return FALSE; 598 472 599 473 /* Check for the existence of the bootsector signature */ 600 - IsValid = (*(PUSHORT)(BootSector + 0x1FE) == 0xAA55); 474 + IsValid = (*(PUSHORT)((PUCHAR)BootSector.BootCode + 0x1FE) == 0xAA55); 601 475 if (IsValid) 602 476 { 603 477 /* Check for the first instruction encoded on three bytes */ 604 - IsValid = (((*(PULONG)BootSector) & 0x00FFFFFF) != 0x00000000); 478 + IsValid = (((*(PULONG)BootSector.BootCode) & 0x00FFFFFF) != 0x00000000); 605 479 } 606 480 607 - Quit: 608 - /* Free the boot sector */ 609 - RtlFreeHeap(ProcessHeap, 0, BootSector); 481 + /* Free the bootsector and return */ 482 + FreeBootCode(&BootSector); 610 483 return IsValid; 611 484 } 612 485 ··· 622 495 OBJECT_ATTRIBUTES ObjectAttributes; 623 496 IO_STATUS_BLOCK IoStatusBlock; 624 497 HANDLE FileHandle; 625 - LARGE_INTEGER FileOffset; 626 - PUCHAR BootSector; 627 - 628 - /* Allocate buffer for bootsector */ 629 - BootSector = RtlAllocateHeap(ProcessHeap, 0, Length); 630 - if (BootSector == NULL) 631 - return STATUS_INSUFFICIENT_RESOURCES; 498 + // LARGE_INTEGER FileOffset; 499 + BOOTCODE BootSector = {0}; 632 500 633 - /* Open the root partition - Remove any trailing backslash if needed */ 501 + /* Allocate and read the root partition bootsector. 502 + * Remove any trailing backslash if needed. */ 634 503 RtlInitUnicodeString(&Name, RootPath); 635 504 TrimTrailingPathSeparators_UStr(&Name); 636 - 637 - InitializeObjectAttributes(&ObjectAttributes, 638 - &Name, 639 - OBJ_CASE_INSENSITIVE, 640 - NULL, 641 - NULL); 642 - 643 - Status = NtOpenFile(&FileHandle, 644 - GENERIC_READ | SYNCHRONIZE, 645 - &ObjectAttributes, 646 - &IoStatusBlock, 647 - FILE_SHARE_READ | FILE_SHARE_WRITE, 648 - FILE_SYNCHRONOUS_IO_NONALERT); 649 - if (!NT_SUCCESS(Status)) 650 - { 651 - RtlFreeHeap(ProcessHeap, 0, BootSector); 652 - return Status; 653 - } 654 - 655 - /* Read current boot sector into buffer */ 656 - FileOffset.QuadPart = 0ULL; 657 - Status = NtReadFile(FileHandle, 658 - NULL, 659 - NULL, 660 - NULL, 661 - &IoStatusBlock, 662 - BootSector, 663 - Length, 664 - &FileOffset, 665 - NULL); 666 - NtClose(FileHandle); 505 + Status = ReadBootCodeFromFile(&BootSector, &Name, Length); 667 506 if (!NT_SUCCESS(Status)) 668 - { 669 - RtlFreeHeap(ProcessHeap, 0, BootSector); 670 507 return Status; 671 - } 672 508 673 - /* Write bootsector to DstPath */ 509 + /* Write the bootsector to DstPath */ 674 510 RtlInitUnicodeString(&Name, DstPath); 675 511 InitializeObjectAttributes(&ObjectAttributes, 676 512 &Name, ··· 691 527 0); 692 528 if (!NT_SUCCESS(Status)) 693 529 { 694 - RtlFreeHeap(ProcessHeap, 0, BootSector); 530 + FreeBootCode(&BootSector); 695 531 return Status; 696 532 } 697 533 ··· 700 536 NULL, 701 537 NULL, 702 538 &IoStatusBlock, 703 - BootSector, 704 - Length, 539 + BootSector.BootCode, 540 + BootSector.Length, 705 541 NULL, 706 542 NULL); 707 543 NtClose(FileHandle); 708 544 709 - /* Free the boot sector */ 710 - RtlFreeHeap(ProcessHeap, 0, BootSector); 711 - 545 + /* Free the bootsector and return */ 546 + FreeBootCode(&BootSector); 712 547 return Status; 713 548 } 714 549 715 550 716 551 static 717 552 NTSTATUS 718 - InstallMbrBootCodeToDiskHelper( 553 + InstallBootCodeToDisk( 719 554 IN PCWSTR SrcPath, 720 - IN PCWSTR RootPath) 555 + IN PCWSTR RootPath, 556 + IN PFS_INSTALL_BOOTCODE InstallBootCode) 721 557 { 722 558 NTSTATUS Status; 723 559 UNICODE_STRING Name; 724 560 OBJECT_ATTRIBUTES ObjectAttributes; 725 561 IO_STATUS_BLOCK IoStatusBlock; 726 - HANDLE FileHandle; 727 - LARGE_INTEGER FileOffset; 728 - PPARTITION_SECTOR OrigBootSector; 729 - PPARTITION_SECTOR NewBootSector; 730 - 731 - /* Allocate buffer for original bootsector */ 732 - OrigBootSector = RtlAllocateHeap(ProcessHeap, 0, sizeof(PARTITION_SECTOR)); 733 - if (OrigBootSector == NULL) 734 - return STATUS_INSUFFICIENT_RESOURCES; 735 - 736 - /* Open the root partition - Remove any trailing backslash if needed */ 737 - RtlInitUnicodeString(&Name, RootPath); 738 - TrimTrailingPathSeparators_UStr(&Name); 739 - 740 - InitializeObjectAttributes(&ObjectAttributes, 741 - &Name, 742 - OBJ_CASE_INSENSITIVE, 743 - NULL, 744 - NULL); 745 - 746 - Status = NtOpenFile(&FileHandle, 747 - GENERIC_READ | SYNCHRONIZE, 748 - &ObjectAttributes, 749 - &IoStatusBlock, 750 - FILE_SHARE_READ | FILE_SHARE_WRITE, 751 - FILE_SYNCHRONOUS_IO_NONALERT); 752 - if (!NT_SUCCESS(Status)) 753 - { 754 - RtlFreeHeap(ProcessHeap, 0, OrigBootSector); 755 - return Status; 756 - } 757 - 758 - /* Read current boot sector into buffer */ 759 - FileOffset.QuadPart = 0ULL; 760 - Status = NtReadFile(FileHandle, 761 - NULL, 762 - NULL, 763 - NULL, 764 - &IoStatusBlock, 765 - OrigBootSector, 766 - sizeof(PARTITION_SECTOR), 767 - &FileOffset, 768 - NULL); 769 - NtClose(FileHandle); 770 - if (!NT_SUCCESS(Status)) 771 - { 772 - RtlFreeHeap(ProcessHeap, 0, OrigBootSector); 773 - return Status; 774 - } 775 - 776 - /* Allocate buffer for new bootsector */ 777 - NewBootSector = RtlAllocateHeap(ProcessHeap, 0, sizeof(PARTITION_SECTOR)); 778 - if (NewBootSector == NULL) 779 - { 780 - RtlFreeHeap(ProcessHeap, 0, OrigBootSector); 781 - return STATUS_INSUFFICIENT_RESOURCES; 782 - } 783 - 784 - /* Read new bootsector from SrcPath */ 785 - RtlInitUnicodeString(&Name, SrcPath); 786 - InitializeObjectAttributes(&ObjectAttributes, 787 - &Name, 788 - OBJ_CASE_INSENSITIVE, 789 - NULL, 790 - NULL); 791 - 792 - Status = NtOpenFile(&FileHandle, 793 - GENERIC_READ | SYNCHRONIZE, 794 - &ObjectAttributes, 795 - &IoStatusBlock, 796 - FILE_SHARE_READ, 797 - FILE_SYNCHRONOUS_IO_NONALERT); 798 - if (!NT_SUCCESS(Status)) 799 - { 800 - RtlFreeHeap(ProcessHeap, 0, OrigBootSector); 801 - RtlFreeHeap(ProcessHeap, 0, NewBootSector); 802 - return Status; 803 - } 804 - 805 - Status = NtReadFile(FileHandle, 806 - NULL, 807 - NULL, 808 - NULL, 809 - &IoStatusBlock, 810 - NewBootSector, 811 - sizeof(PARTITION_SECTOR), 812 - NULL, 813 - NULL); 814 - NtClose(FileHandle); 815 - if (!NT_SUCCESS(Status)) 816 - { 817 - RtlFreeHeap(ProcessHeap, 0, OrigBootSector); 818 - RtlFreeHeap(ProcessHeap, 0, NewBootSector); 819 - return Status; 820 - } 562 + HANDLE PartitionHandle; 821 563 822 564 /* 823 - * Copy the disk signature, the reserved fields and 824 - * the partition table from the old MBR to the new one. 565 + * Open the root partition from which the bootcode (MBR, VBR) parameters 566 + * will be obtained; this is also where we will write the updated bootcode. 567 + * Remove any trailing backslash if needed. 825 568 */ 826 - RtlCopyMemory(&NewBootSector->Signature, 827 - &OrigBootSector->Signature, 828 - sizeof(PARTITION_SECTOR) - offsetof(PARTITION_SECTOR, Signature) 829 - /* Length of partition table */); 830 - 831 - /* Free the original boot sector */ 832 - RtlFreeHeap(ProcessHeap, 0, OrigBootSector); 833 - 834 - /* Open the root partition - Remove any trailing backslash if needed */ 835 569 RtlInitUnicodeString(&Name, RootPath); 836 570 TrimTrailingPathSeparators_UStr(&Name); 837 571 ··· 841 575 NULL, 842 576 NULL); 843 577 844 - Status = NtOpenFile(&FileHandle, 845 - GENERIC_WRITE | SYNCHRONIZE, 578 + Status = NtOpenFile(&PartitionHandle, 579 + GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, 846 580 &ObjectAttributes, 847 581 &IoStatusBlock, 848 582 FILE_SHARE_READ | FILE_SHARE_WRITE, 849 - FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY); 583 + FILE_SYNCHRONOUS_IO_NONALERT /* | FILE_SEQUENTIAL_ONLY */); 850 584 if (!NT_SUCCESS(Status)) 851 - { 852 - DPRINT1("NtOpenFile() failed (Status %lx)\n", Status); 853 - RtlFreeHeap(ProcessHeap, 0, NewBootSector); 854 585 return Status; 855 - } 856 586 857 - /* Write new bootsector to RootPath */ 858 - FileOffset.QuadPart = 0ULL; 859 - Status = NtWriteFile(FileHandle, 860 - NULL, 861 - NULL, 862 - NULL, 863 - &IoStatusBlock, 864 - NewBootSector, 865 - sizeof(PARTITION_SECTOR), 866 - &FileOffset, 867 - NULL); 868 - NtClose(FileHandle); 587 + /* Install the bootcode (MBR, VBR) */ 588 + Status = InstallBootCode(SrcPath, PartitionHandle, PartitionHandle); 869 589 870 - /* Free the new boot sector */ 871 - RtlFreeHeap(ProcessHeap, 0, NewBootSector); 590 + /* Close the partition */ 591 + NtClose(PartitionHandle); 872 592 873 593 return Status; 874 594 } 875 595 876 - NTSTATUS 877 - InstallMbrBootCodeToDisk( 878 - IN PUNICODE_STRING SystemRootPath, 879 - IN PUNICODE_STRING SourceRootPath, 880 - IN PCWSTR DestinationDevicePathBuffer) 881 - { 882 - NTSTATUS Status; 883 - WCHAR SourceMbrPathBuffer[MAX_PATH]; 884 - WCHAR DstPath[MAX_PATH]; 885 - 886 - #if 0 887 - /* 888 - * The DestinationDevicePathBuffer parameter has been built with 889 - * the following instruction by the caller; I'm not yet sure whether 890 - * I actually want this function to build the path instead, hence 891 - * I keep this code here but disabled for now... 892 - */ 893 - WCHAR DestinationDevicePathBuffer[MAX_PATH]; 894 - RtlStringCchPrintfW(DestinationDevicePathBuffer, ARRAYSIZE(DestinationDevicePathBuffer), 895 - L"\\Device\\Harddisk%d\\Partition0", 896 - DiskNumber); 897 - #endif 898 - 899 - CombinePaths(SourceMbrPathBuffer, ARRAYSIZE(SourceMbrPathBuffer), 2, 900 - SourceRootPath->Buffer, L"\\loader\\dosmbr.bin"); 901 - 902 - if (IsThereAValidBootSector(DestinationDevicePathBuffer)) 903 - { 904 - /* Save current MBR */ 905 - CombinePaths(DstPath, ARRAYSIZE(DstPath), 2, 906 - SystemRootPath->Buffer, L"mbr.old"); 907 - 908 - DPRINT1("Save MBR: %S ==> %S\n", DestinationDevicePathBuffer, DstPath); 909 - Status = SaveBootSector(DestinationDevicePathBuffer, DstPath, sizeof(PARTITION_SECTOR)); 910 - if (!NT_SUCCESS(Status)) 911 - { 912 - DPRINT1("SaveBootSector() failed (Status %lx)\n", Status); 913 - // Don't care if we succeeded or not saving the old MBR, just go ahead. 914 - } 915 - } 916 - 917 - DPRINT1("Install MBR bootcode: %S ==> %S\n", 918 - SourceMbrPathBuffer, DestinationDevicePathBuffer); 919 - 920 - return InstallMbrBootCodeToDiskHelper(SourceMbrPathBuffer, 921 - DestinationDevicePathBuffer); 922 - } 923 - 924 - 925 596 static 926 597 NTSTATUS 927 - InstallFat12BootCodeToFloppy( 928 - IN PCWSTR SrcPath, 929 - IN PCWSTR RootPath) 930 - { 931 - NTSTATUS Status; 932 - UNICODE_STRING Name; 933 - OBJECT_ATTRIBUTES ObjectAttributes; 934 - IO_STATUS_BLOCK IoStatusBlock; 935 - HANDLE FileHandle; 936 - LARGE_INTEGER FileOffset; 937 - PFAT_BOOTSECTOR OrigBootSector; 938 - PFAT_BOOTSECTOR NewBootSector; 939 - 940 - /* Allocate buffer for original bootsector */ 941 - OrigBootSector = RtlAllocateHeap(ProcessHeap, 0, SECTORSIZE); 942 - if (OrigBootSector == NULL) 943 - return STATUS_INSUFFICIENT_RESOURCES; 944 - 945 - /* Open the root partition - Remove any trailing backslash if needed */ 946 - RtlInitUnicodeString(&Name, RootPath); 947 - TrimTrailingPathSeparators_UStr(&Name); 948 - 949 - InitializeObjectAttributes(&ObjectAttributes, 950 - &Name, 951 - OBJ_CASE_INSENSITIVE, 952 - NULL, 953 - NULL); 954 - 955 - Status = NtOpenFile(&FileHandle, 956 - GENERIC_READ | SYNCHRONIZE, 957 - &ObjectAttributes, 958 - &IoStatusBlock, 959 - FILE_SHARE_READ | FILE_SHARE_WRITE, 960 - FILE_SYNCHRONOUS_IO_NONALERT); 961 - if (!NT_SUCCESS(Status)) 962 - { 963 - RtlFreeHeap(ProcessHeap, 0, OrigBootSector); 964 - return Status; 965 - } 966 - 967 - /* Read current boot sector into buffer */ 968 - FileOffset.QuadPart = 0ULL; 969 - Status = NtReadFile(FileHandle, 970 - NULL, 971 - NULL, 972 - NULL, 973 - &IoStatusBlock, 974 - OrigBootSector, 975 - SECTORSIZE, 976 - &FileOffset, 977 - NULL); 978 - NtClose(FileHandle); 979 - if (!NT_SUCCESS(Status)) 980 - { 981 - RtlFreeHeap(ProcessHeap, 0, OrigBootSector); 982 - return Status; 983 - } 984 - 985 - /* Allocate buffer for new bootsector */ 986 - NewBootSector = RtlAllocateHeap(ProcessHeap, 987 - 0, 988 - SECTORSIZE); 989 - if (NewBootSector == NULL) 990 - { 991 - RtlFreeHeap(ProcessHeap, 0, OrigBootSector); 992 - return STATUS_INSUFFICIENT_RESOURCES; 993 - } 994 - 995 - /* Read new bootsector from SrcPath */ 996 - RtlInitUnicodeString(&Name, SrcPath); 997 - 998 - InitializeObjectAttributes(&ObjectAttributes, 999 - &Name, 1000 - OBJ_CASE_INSENSITIVE, 1001 - NULL, 1002 - NULL); 1003 - 1004 - Status = NtOpenFile(&FileHandle, 1005 - GENERIC_READ | SYNCHRONIZE, 1006 - &ObjectAttributes, 1007 - &IoStatusBlock, 1008 - FILE_SHARE_READ, 1009 - FILE_SYNCHRONOUS_IO_NONALERT); 1010 - if (!NT_SUCCESS(Status)) 1011 - { 1012 - RtlFreeHeap(ProcessHeap, 0, OrigBootSector); 1013 - RtlFreeHeap(ProcessHeap, 0, NewBootSector); 1014 - return Status; 1015 - } 1016 - 1017 - Status = NtReadFile(FileHandle, 1018 - NULL, 1019 - NULL, 1020 - NULL, 1021 - &IoStatusBlock, 1022 - NewBootSector, 1023 - SECTORSIZE, 1024 - NULL, 1025 - NULL); 1026 - NtClose(FileHandle); 1027 - if (!NT_SUCCESS(Status)) 1028 - { 1029 - RtlFreeHeap(ProcessHeap, 0, OrigBootSector); 1030 - RtlFreeHeap(ProcessHeap, 0, NewBootSector); 1031 - return Status; 1032 - } 1033 - 1034 - /* Adjust bootsector (copy a part of the FAT16 BPB) */ 1035 - memcpy(&NewBootSector->OemName, 1036 - &OrigBootSector->OemName, 1037 - FIELD_OFFSET(FAT_BOOTSECTOR, BootCodeAndData) - 1038 - FIELD_OFFSET(FAT_BOOTSECTOR, OemName)); 1039 - 1040 - /* Free the original boot sector */ 1041 - RtlFreeHeap(ProcessHeap, 0, OrigBootSector); 1042 - 1043 - /* Open the root partition - Remove any trailing backslash if needed */ 1044 - RtlInitUnicodeString(&Name, RootPath); 1045 - TrimTrailingPathSeparators_UStr(&Name); 1046 - 1047 - InitializeObjectAttributes(&ObjectAttributes, 1048 - &Name, 1049 - OBJ_CASE_INSENSITIVE, 1050 - NULL, 1051 - NULL); 1052 - 1053 - Status = NtOpenFile(&FileHandle, 1054 - GENERIC_WRITE | SYNCHRONIZE, 1055 - &ObjectAttributes, 1056 - &IoStatusBlock, 1057 - FILE_SHARE_READ | FILE_SHARE_WRITE, 1058 - FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY); 1059 - if (!NT_SUCCESS(Status)) 1060 - { 1061 - DPRINT1("NtOpenFile() failed (Status %lx)\n", Status); 1062 - RtlFreeHeap(ProcessHeap, 0, NewBootSector); 1063 - return Status; 1064 - } 1065 - 1066 - /* Write new bootsector to RootPath */ 1067 - FileOffset.QuadPart = 0ULL; 1068 - Status = NtWriteFile(FileHandle, 1069 - NULL, 1070 - NULL, 1071 - NULL, 1072 - &IoStatusBlock, 1073 - NewBootSector, 1074 - SECTORSIZE, 1075 - &FileOffset, 1076 - NULL); 1077 - NtClose(FileHandle); 1078 - 1079 - /* Free the new boot sector */ 1080 - RtlFreeHeap(ProcessHeap, 0, NewBootSector); 1081 - 1082 - return Status; 1083 - } 1084 - 1085 - static 1086 - NTSTATUS 1087 - InstallFat16BootCode( 1088 - IN PCWSTR SrcPath, // FAT16 bootsector source file (on the installation medium) 1089 - IN HANDLE DstPath, // Where to save the bootsector built from the source + partition information 1090 - IN HANDLE RootPartition) // Partition holding the (old) FAT16 information 1091 - { 1092 - NTSTATUS Status; 1093 - UNICODE_STRING Name; 1094 - OBJECT_ATTRIBUTES ObjectAttributes; 1095 - IO_STATUS_BLOCK IoStatusBlock; 1096 - HANDLE FileHandle; 1097 - LARGE_INTEGER FileOffset; 1098 - PFAT_BOOTSECTOR OrigBootSector; 1099 - PFAT_BOOTSECTOR NewBootSector; 1100 - 1101 - /* Allocate a buffer for the original bootsector */ 1102 - OrigBootSector = RtlAllocateHeap(ProcessHeap, 0, SECTORSIZE); 1103 - if (OrigBootSector == NULL) 1104 - return STATUS_INSUFFICIENT_RESOURCES; 1105 - 1106 - /* Read the current partition boot sector into the buffer */ 1107 - FileOffset.QuadPart = 0ULL; 1108 - Status = NtReadFile(RootPartition, 1109 - NULL, 1110 - NULL, 1111 - NULL, 1112 - &IoStatusBlock, 1113 - OrigBootSector, 1114 - SECTORSIZE, 1115 - &FileOffset, 1116 - NULL); 1117 - if (!NT_SUCCESS(Status)) 1118 - { 1119 - RtlFreeHeap(ProcessHeap, 0, OrigBootSector); 1120 - return Status; 1121 - } 1122 - 1123 - /* Allocate a buffer for the new bootsector */ 1124 - NewBootSector = RtlAllocateHeap(ProcessHeap, 0, SECTORSIZE); 1125 - if (NewBootSector == NULL) 1126 - { 1127 - RtlFreeHeap(ProcessHeap, 0, OrigBootSector); 1128 - return STATUS_INSUFFICIENT_RESOURCES; 1129 - } 1130 - 1131 - /* Read the new bootsector from SrcPath */ 1132 - RtlInitUnicodeString(&Name, SrcPath); 1133 - InitializeObjectAttributes(&ObjectAttributes, 1134 - &Name, 1135 - OBJ_CASE_INSENSITIVE, 1136 - NULL, 1137 - NULL); 1138 - 1139 - Status = NtOpenFile(&FileHandle, 1140 - GENERIC_READ | SYNCHRONIZE, 1141 - &ObjectAttributes, 1142 - &IoStatusBlock, 1143 - FILE_SHARE_READ, 1144 - FILE_SYNCHRONOUS_IO_NONALERT); 1145 - if (!NT_SUCCESS(Status)) 1146 - { 1147 - RtlFreeHeap(ProcessHeap, 0, OrigBootSector); 1148 - RtlFreeHeap(ProcessHeap, 0, NewBootSector); 1149 - return Status; 1150 - } 1151 - 1152 - FileOffset.QuadPart = 0ULL; 1153 - Status = NtReadFile(FileHandle, 1154 - NULL, 1155 - NULL, 1156 - NULL, 1157 - &IoStatusBlock, 1158 - NewBootSector, 1159 - SECTORSIZE, 1160 - &FileOffset, 1161 - NULL); 1162 - NtClose(FileHandle); 1163 - if (!NT_SUCCESS(Status)) 1164 - { 1165 - RtlFreeHeap(ProcessHeap, 0, OrigBootSector); 1166 - RtlFreeHeap(ProcessHeap, 0, NewBootSector); 1167 - return Status; 1168 - } 1169 - 1170 - /* Adjust the bootsector (copy a part of the FAT16 BPB) */ 1171 - memcpy(&NewBootSector->OemName, 1172 - &OrigBootSector->OemName, 1173 - FIELD_OFFSET(FAT_BOOTSECTOR, BootCodeAndData) - 1174 - FIELD_OFFSET(FAT_BOOTSECTOR, OemName)); 1175 - 1176 - /* Free the original boot sector */ 1177 - RtlFreeHeap(ProcessHeap, 0, OrigBootSector); 1178 - 1179 - /* Write the new bootsector to DstPath */ 1180 - FileOffset.QuadPart = 0ULL; 1181 - Status = NtWriteFile(DstPath, 1182 - NULL, 1183 - NULL, 1184 - NULL, 1185 - &IoStatusBlock, 1186 - NewBootSector, 1187 - SECTORSIZE, 1188 - &FileOffset, 1189 - NULL); 1190 - 1191 - /* Free the new boot sector */ 1192 - RtlFreeHeap(ProcessHeap, 0, NewBootSector); 1193 - 1194 - return Status; 1195 - } 1196 - 1197 - static 1198 - NTSTATUS 1199 - InstallFat16BootCodeToFile( 598 + InstallBootCodeToFile( 1200 599 IN PCWSTR SrcPath, 1201 600 IN PCWSTR DstPath, 1202 - IN PCWSTR RootPath) 601 + IN PCWSTR RootPath, 602 + IN PFS_INSTALL_BOOTCODE InstallBootCode) 1203 603 { 1204 604 NTSTATUS Status; 1205 605 UNICODE_STRING Name; ··· 1208 608 HANDLE PartitionHandle, FileHandle; 1209 609 1210 610 /* 1211 - * Open the root partition from which the boot sector 611 + * Open the root partition from which the bootcode (MBR, VBR) 1212 612 * parameters will be obtained. 613 + * 614 + * FIXME? It might be possible that we need to also open it for writing 615 + * access in case we really need to still write the second portion of 616 + * the boot sector ???? 617 + * 1213 618 * Remove any trailing backslash if needed. 1214 619 */ 1215 620 RtlInitUnicodeString(&Name, RootPath); ··· 1245 650 NULL, 1246 651 FILE_ATTRIBUTE_NORMAL, 1247 652 0, 1248 - FILE_OVERWRITE_IF, 653 + FILE_SUPERSEDE, // FILE_OVERWRITE_IF 1249 654 FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY, 1250 655 NULL, 1251 656 0); ··· 1256 661 return Status; 1257 662 } 1258 663 1259 - /* Install the FAT16 boot sector */ 1260 - Status = InstallFat16BootCode(SrcPath, FileHandle, PartitionHandle); 664 + /* Install the bootcode (MBR, VBR) */ 665 + Status = InstallBootCode(SrcPath, FileHandle, PartitionHandle); 1261 666 1262 667 /* Close the file and the partition */ 1263 668 NtClose(FileHandle); ··· 1266 671 return Status; 1267 672 } 1268 673 1269 - static 1270 - NTSTATUS 1271 - InstallFat16BootCodeToDisk( 1272 - IN PCWSTR SrcPath, 1273 - IN PCWSTR RootPath) 1274 - { 1275 - NTSTATUS Status; 1276 - UNICODE_STRING Name; 1277 - OBJECT_ATTRIBUTES ObjectAttributes; 1278 - IO_STATUS_BLOCK IoStatusBlock; 1279 - HANDLE PartitionHandle; 1280 - 1281 - /* 1282 - * Open the root partition from which the boot sector parameters will be 1283 - * obtained; this is also where we will write the updated boot sector. 1284 - * Remove any trailing backslash if needed. 1285 - */ 1286 - RtlInitUnicodeString(&Name, RootPath); 1287 - TrimTrailingPathSeparators_UStr(&Name); 1288 - 1289 - InitializeObjectAttributes(&ObjectAttributes, 1290 - &Name, 1291 - OBJ_CASE_INSENSITIVE, 1292 - NULL, 1293 - NULL); 1294 - 1295 - Status = NtOpenFile(&PartitionHandle, 1296 - GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, 1297 - &ObjectAttributes, 1298 - &IoStatusBlock, 1299 - FILE_SHARE_READ | FILE_SHARE_WRITE, 1300 - FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY); 1301 - if (!NT_SUCCESS(Status)) 1302 - return Status; 1303 - 1304 - /* Install the FAT16 boot sector */ 1305 - Status = InstallFat16BootCode(SrcPath, PartitionHandle, PartitionHandle); 1306 - 1307 - /* Close the partition */ 1308 - NtClose(PartitionHandle); 1309 - 1310 - return Status; 1311 - } 1312 - 1313 674 1314 675 static 1315 676 NTSTATUS 1316 - InstallFat32BootCode( 1317 - IN PCWSTR SrcPath, // FAT32 bootsector source file (on the installation medium) 1318 - IN HANDLE DstPath, // Where to save the bootsector built from the source + partition information 1319 - IN HANDLE RootPartition) // Partition holding the (old) FAT32 information 677 + InstallMbrBootCode( 678 + IN PCWSTR SrcPath, // MBR source file (on the installation medium) 679 + IN HANDLE DstPath, // Where to save the bootsector built from the source + disk information 680 + IN HANDLE DiskHandle) // Disk holding the (old) MBR information 1320 681 { 1321 682 NTSTATUS Status; 1322 683 UNICODE_STRING Name; 1323 - OBJECT_ATTRIBUTES ObjectAttributes; 1324 684 IO_STATUS_BLOCK IoStatusBlock; 1325 - HANDLE FileHandle; 1326 685 LARGE_INTEGER FileOffset; 1327 - PFAT32_BOOTSECTOR OrigBootSector; 1328 - PFAT32_BOOTSECTOR NewBootSector; 1329 - USHORT BackupBootSector; 686 + BOOTCODE OrigBootSector = {0}; 687 + BOOTCODE NewBootSector = {0}; 1330 688 1331 - /* Allocate a buffer for the original bootsector */ 1332 - OrigBootSector = RtlAllocateHeap(ProcessHeap, 0, SECTORSIZE); 1333 - if (OrigBootSector == NULL) 1334 - return STATUS_INSUFFICIENT_RESOURCES; 689 + C_ASSERT(sizeof(PARTITION_SECTOR) == SECTORSIZE); 1335 690 1336 - /* Read the current boot sector into the buffer */ 1337 - FileOffset.QuadPart = 0ULL; 1338 - Status = NtReadFile(RootPartition, 1339 - NULL, 1340 - NULL, 1341 - NULL, 1342 - &IoStatusBlock, 1343 - OrigBootSector, 1344 - SECTORSIZE, 1345 - &FileOffset, 1346 - NULL); 691 + /* Allocate and read the current original MBR bootsector */ 692 + Status = ReadBootCodeByHandle(&OrigBootSector, 693 + DiskHandle, 694 + sizeof(PARTITION_SECTOR)); 1347 695 if (!NT_SUCCESS(Status)) 1348 - { 1349 - RtlFreeHeap(ProcessHeap, 0, OrigBootSector); 1350 696 return Status; 1351 - } 1352 697 1353 - /* Allocate a buffer for the new bootsector (2 sectors) */ 1354 - NewBootSector = RtlAllocateHeap(ProcessHeap, 0, 2 * SECTORSIZE); 1355 - if (NewBootSector == NULL) 1356 - { 1357 - RtlFreeHeap(ProcessHeap, 0, OrigBootSector); 1358 - return STATUS_INSUFFICIENT_RESOURCES; 1359 - } 1360 - 1361 - /* Read the new bootsector from SrcPath */ 698 + /* Allocate and read the new bootsector from SrcPath */ 1362 699 RtlInitUnicodeString(&Name, SrcPath); 1363 - InitializeObjectAttributes(&ObjectAttributes, 1364 - &Name, 1365 - OBJ_CASE_INSENSITIVE, 1366 - NULL, 1367 - NULL); 1368 - 1369 - Status = NtOpenFile(&FileHandle, 1370 - GENERIC_READ | SYNCHRONIZE, 1371 - &ObjectAttributes, 1372 - &IoStatusBlock, 1373 - FILE_SHARE_READ, 1374 - FILE_SYNCHRONOUS_IO_NONALERT); 1375 - if (!NT_SUCCESS(Status)) 1376 - { 1377 - RtlFreeHeap(ProcessHeap, 0, OrigBootSector); 1378 - RtlFreeHeap(ProcessHeap, 0, NewBootSector); 1379 - return Status; 1380 - } 1381 - 1382 - FileOffset.QuadPart = 0ULL; 1383 - Status = NtReadFile(FileHandle, 1384 - NULL, 1385 - NULL, 1386 - NULL, 1387 - &IoStatusBlock, 1388 - NewBootSector, 1389 - 2 * SECTORSIZE, 1390 - &FileOffset, 1391 - NULL); 1392 - NtClose(FileHandle); 700 + Status = ReadBootCodeFromFile(&NewBootSector, 701 + &Name, 702 + sizeof(PARTITION_SECTOR)); 1393 703 if (!NT_SUCCESS(Status)) 1394 704 { 1395 - RtlFreeHeap(ProcessHeap, 0, OrigBootSector); 1396 - RtlFreeHeap(ProcessHeap, 0, NewBootSector); 705 + FreeBootCode(&OrigBootSector); 1397 706 return Status; 1398 707 } 1399 708 1400 - /* Adjust the bootsector (copy a part of the FAT32 BPB) */ 1401 - memcpy(&NewBootSector->OemName, 1402 - &OrigBootSector->OemName, 1403 - FIELD_OFFSET(FAT32_BOOTSECTOR, BootCodeAndData) - 1404 - FIELD_OFFSET(FAT32_BOOTSECTOR, OemName)); 1405 - 1406 709 /* 1407 - * We know we copy the boot code to a file only when DstPath != RootPartition, 1408 - * otherwise the boot code is copied to the specified root partition. 710 + * Copy the disk signature, the reserved fields and 711 + * the partition table from the old MBR to the new one. 1409 712 */ 1410 - if (DstPath != RootPartition) 1411 - { 1412 - /* Copy to a file: Disable the backup boot sector */ 1413 - NewBootSector->BackupBootSector = 0; 1414 - } 1415 - else 1416 - { 1417 - /* Copy to a disk: Get the location of the backup boot sector */ 1418 - BackupBootSector = OrigBootSector->BackupBootSector; 1419 - } 713 + RtlCopyMemory(&((PPARTITION_SECTOR)NewBootSector.BootCode)->Signature, 714 + &((PPARTITION_SECTOR)OrigBootSector.BootCode)->Signature, 715 + sizeof(PARTITION_SECTOR) - 716 + FIELD_OFFSET(PARTITION_SECTOR, Signature) 717 + /* Length of partition table */); 1420 718 1421 - /* Free the original boot sector */ 1422 - RtlFreeHeap(ProcessHeap, 0, OrigBootSector); 719 + /* Free the original bootsector */ 720 + FreeBootCode(&OrigBootSector); 1423 721 1424 - /* Write the first sector of the new bootcode to DstPath sector 0 */ 722 + /* Write the new bootsector to DstPath */ 1425 723 FileOffset.QuadPart = 0ULL; 1426 724 Status = NtWriteFile(DstPath, 1427 725 NULL, 1428 726 NULL, 1429 727 NULL, 1430 728 &IoStatusBlock, 1431 - NewBootSector, 1432 - SECTORSIZE, 729 + NewBootSector.BootCode, 730 + NewBootSector.Length, 1433 731 &FileOffset, 1434 732 NULL); 1435 - if (!NT_SUCCESS(Status)) 1436 - { 1437 - DPRINT1("NtWriteFile() failed (Status %lx)\n", Status); 1438 - RtlFreeHeap(ProcessHeap, 0, NewBootSector); 1439 - return Status; 1440 - } 1441 - 1442 - if (DstPath == RootPartition) 1443 - { 1444 - /* Copy to a disk: Write the backup boot sector */ 1445 - if ((BackupBootSector != 0x0000) && (BackupBootSector != 0xFFFF)) 1446 - { 1447 - FileOffset.QuadPart = (ULONGLONG)((ULONG)BackupBootSector * SECTORSIZE); 1448 - Status = NtWriteFile(DstPath, 1449 - NULL, 1450 - NULL, 1451 - NULL, 1452 - &IoStatusBlock, 1453 - NewBootSector, 1454 - SECTORSIZE, 1455 - &FileOffset, 1456 - NULL); 1457 - if (!NT_SUCCESS(Status)) 1458 - { 1459 - DPRINT1("NtWriteFile() failed (Status %lx)\n", Status); 1460 - RtlFreeHeap(ProcessHeap, 0, NewBootSector); 1461 - return Status; 1462 - } 1463 - } 1464 - } 1465 - 1466 - /* Write the second sector of the new bootcode to boot disk sector 14 */ 1467 - // FileOffset.QuadPart = (ULONGLONG)(14 * SECTORSIZE); 1468 - FileOffset.QuadPart = 14 * SECTORSIZE; 1469 - Status = NtWriteFile(DstPath, // or really RootPartition ??? 1470 - NULL, 1471 - NULL, 1472 - NULL, 1473 - &IoStatusBlock, 1474 - ((PUCHAR)NewBootSector + SECTORSIZE), 1475 - SECTORSIZE, 1476 - &FileOffset, 1477 - NULL); 1478 - if (!NT_SUCCESS(Status)) 1479 - { 1480 - DPRINT1("NtWriteFile() failed (Status %lx)\n", Status); 1481 - } 1482 - 1483 - /* Free the new boot sector */ 1484 - RtlFreeHeap(ProcessHeap, 0, NewBootSector); 1485 - 1486 - return Status; 1487 - } 1488 - 1489 - static 1490 - NTSTATUS 1491 - InstallFat32BootCodeToFile( 1492 - IN PCWSTR SrcPath, 1493 - IN PCWSTR DstPath, 1494 - IN PCWSTR RootPath) 1495 - { 1496 - NTSTATUS Status; 1497 - UNICODE_STRING Name; 1498 - OBJECT_ATTRIBUTES ObjectAttributes; 1499 - IO_STATUS_BLOCK IoStatusBlock; 1500 - HANDLE PartitionHandle, FileHandle; 1501 - 1502 - /* 1503 - * Open the root partition from which the boot sector parameters 1504 - * will be obtained. 1505 - * FIXME? It might be possible that we need to also open it for writing 1506 - * access in case we really need to still write the second portion of 1507 - * the boot sector ???? 1508 - * 1509 - * Remove any trailing backslash if needed. 1510 - */ 1511 - RtlInitUnicodeString(&Name, RootPath); 1512 - TrimTrailingPathSeparators_UStr(&Name); 1513 - 1514 - InitializeObjectAttributes(&ObjectAttributes, 1515 - &Name, 1516 - OBJ_CASE_INSENSITIVE, 1517 - NULL, 1518 - NULL); 1519 733 1520 - Status = NtOpenFile(&PartitionHandle, 1521 - GENERIC_READ | SYNCHRONIZE, 1522 - &ObjectAttributes, 1523 - &IoStatusBlock, 1524 - FILE_SHARE_READ | FILE_SHARE_WRITE, 1525 - FILE_SYNCHRONOUS_IO_NONALERT /* | FILE_SEQUENTIAL_ONLY */); 1526 - if (!NT_SUCCESS(Status)) 1527 - return Status; 1528 - 1529 - /* Open or create the file where (the first sector of ????) the new bootsector will be saved */ 1530 - RtlInitUnicodeString(&Name, DstPath); 1531 - InitializeObjectAttributes(&ObjectAttributes, 1532 - &Name, 1533 - OBJ_CASE_INSENSITIVE, 1534 - NULL, 1535 - NULL); 1536 - 1537 - Status = NtCreateFile(&FileHandle, 1538 - GENERIC_WRITE | SYNCHRONIZE, 1539 - &ObjectAttributes, 1540 - &IoStatusBlock, 1541 - NULL, 1542 - FILE_ATTRIBUTE_NORMAL, 1543 - 0, 1544 - FILE_SUPERSEDE, // FILE_OVERWRITE_IF, <- is used for FAT16 1545 - FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY, 1546 - NULL, 1547 - 0); 1548 - if (!NT_SUCCESS(Status)) 1549 - { 1550 - DPRINT1("NtCreateFile() failed (Status %lx)\n", Status); 1551 - NtClose(PartitionHandle); 1552 - return Status; 1553 - } 1554 - 1555 - /* Install the FAT32 boot sector */ 1556 - Status = InstallFat32BootCode(SrcPath, FileHandle, PartitionHandle); 1557 - 1558 - /* Close the file and the partition */ 1559 - NtClose(FileHandle); 1560 - NtClose(PartitionHandle); 1561 - 1562 - return Status; 1563 - } 1564 - 1565 - static 1566 - NTSTATUS 1567 - InstallFat32BootCodeToDisk( 1568 - IN PCWSTR SrcPath, 1569 - IN PCWSTR RootPath) 1570 - { 1571 - NTSTATUS Status; 1572 - UNICODE_STRING Name; 1573 - OBJECT_ATTRIBUTES ObjectAttributes; 1574 - IO_STATUS_BLOCK IoStatusBlock; 1575 - HANDLE PartitionHandle; 1576 - 1577 - /* 1578 - * Open the root partition from which the boot sector parameters will be 1579 - * obtained; this is also where we will write the updated boot sector. 1580 - * Remove any trailing backslash if needed. 1581 - */ 1582 - RtlInitUnicodeString(&Name, RootPath); 1583 - TrimTrailingPathSeparators_UStr(&Name); 1584 - 1585 - InitializeObjectAttributes(&ObjectAttributes, 1586 - &Name, 1587 - OBJ_CASE_INSENSITIVE, 1588 - NULL, 1589 - NULL); 1590 - 1591 - Status = NtOpenFile(&PartitionHandle, 1592 - GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, 1593 - &ObjectAttributes, 1594 - &IoStatusBlock, 1595 - FILE_SHARE_READ | FILE_SHARE_WRITE, 1596 - FILE_SYNCHRONOUS_IO_NONALERT /* | FILE_SEQUENTIAL_ONLY */); 1597 - if (!NT_SUCCESS(Status)) 1598 - return Status; 1599 - 1600 - /* Install the FAT32 boot sector */ 1601 - Status = InstallFat32BootCode(SrcPath, PartitionHandle, PartitionHandle); 1602 - 1603 - /* Close the partition */ 1604 - NtClose(PartitionHandle); 734 + /* Free the new bootsector */ 735 + FreeBootCode(&NewBootSector); 1605 736 1606 737 return Status; 1607 738 } 1608 739 1609 - static 1610 740 NTSTATUS 1611 - InstallBtrfsBootCodeToDisk( 1612 - IN PCWSTR SrcPath, 1613 - IN PCWSTR RootPath) 741 + InstallMbrBootCodeToDisk( 742 + IN PUNICODE_STRING SystemRootPath, 743 + IN PUNICODE_STRING SourceRootPath, 744 + IN PCWSTR DestinationDevicePathBuffer) 1614 745 { 1615 746 NTSTATUS Status; 1616 - NTSTATUS LockStatus; 1617 - UNICODE_STRING Name; 1618 - OBJECT_ATTRIBUTES ObjectAttributes; 1619 - IO_STATUS_BLOCK IoStatusBlock; 1620 - HANDLE FileHandle; 1621 - LARGE_INTEGER FileOffset; 1622 - // PEXT2_BOOTSECTOR OrigBootSector; 1623 - PBTRFS_BOOTSECTOR NewBootSector; 1624 - // USHORT BackupBootSector; 1625 - PARTITION_INFORMATION_EX PartInfo; 747 + WCHAR SourceMbrPathBuffer[MAX_PATH]; 748 + WCHAR DstPath[MAX_PATH]; 1626 749 1627 750 #if 0 1628 - /* Allocate buffer for original bootsector */ 1629 - OrigBootSector = RtlAllocateHeap(ProcessHeap, 0, SECTORSIZE); 1630 - if (OrigBootSector == NULL) 1631 - return STATUS_INSUFFICIENT_RESOURCES; 1632 - 1633 - /* Open the root partition - Remove any trailing backslash if needed */ 1634 - RtlInitUnicodeString(&Name, RootPath); 1635 - TrimTrailingPathSeparators_UStr(&Name); 1636 - 1637 - InitializeObjectAttributes(&ObjectAttributes, 1638 - &Name, 1639 - OBJ_CASE_INSENSITIVE, 1640 - NULL, 1641 - NULL); 1642 - 1643 - Status = NtOpenFile(&FileHandle, 1644 - GENERIC_READ | SYNCHRONIZE, 1645 - &ObjectAttributes, 1646 - &IoStatusBlock, 1647 - FILE_SHARE_READ | FILE_SHARE_WRITE, 1648 - FILE_SYNCHRONOUS_IO_NONALERT); 1649 - if (!NT_SUCCESS(Status)) 1650 - { 1651 - RtlFreeHeap(ProcessHeap, 0, OrigBootSector); 1652 - return Status; 1653 - } 1654 - 1655 - /* Read current boot sector into buffer */ 1656 - FileOffset.QuadPart = 0ULL; 1657 - Status = NtReadFile(FileHandle, 1658 - NULL, 1659 - NULL, 1660 - NULL, 1661 - &IoStatusBlock, 1662 - OrigBootSector, 1663 - SECTORSIZE, 1664 - &FileOffset, 1665 - NULL); 1666 - NtClose(FileHandle); 1667 - if (!NT_SUCCESS(Status)) 1668 - { 1669 - RtlFreeHeap(ProcessHeap, 0, OrigBootSector); 1670 - return Status; 1671 - } 1672 - #endif 1673 - 1674 - /* Allocate buffer for new bootsector */ 1675 - NewBootSector = RtlAllocateHeap(ProcessHeap, 0, sizeof(BTRFS_BOOTSECTOR)); 1676 - if (NewBootSector == NULL) 1677 - { 1678 - // RtlFreeHeap(ProcessHeap, 0, OrigBootSector); 1679 - return STATUS_INSUFFICIENT_RESOURCES; 1680 - } 1681 - 1682 - /* Read new bootsector from SrcPath */ 1683 - RtlInitUnicodeString(&Name, SrcPath); 1684 - 1685 - InitializeObjectAttributes(&ObjectAttributes, 1686 - &Name, 1687 - OBJ_CASE_INSENSITIVE, 1688 - NULL, 1689 - NULL); 1690 - 1691 - Status = NtOpenFile(&FileHandle, 1692 - GENERIC_READ | SYNCHRONIZE, 1693 - &ObjectAttributes, 1694 - &IoStatusBlock, 1695 - FILE_SHARE_READ, 1696 - FILE_SYNCHRONOUS_IO_NONALERT); 1697 - if (!NT_SUCCESS(Status)) 1698 - { 1699 - // RtlFreeHeap(ProcessHeap, 0, OrigBootSector); 1700 - RtlFreeHeap(ProcessHeap, 0, NewBootSector); 1701 - return Status; 1702 - } 1703 - 1704 - Status = NtReadFile(FileHandle, 1705 - NULL, 1706 - NULL, 1707 - NULL, 1708 - &IoStatusBlock, 1709 - NewBootSector, 1710 - sizeof(BTRFS_BOOTSECTOR), 1711 - NULL, 1712 - NULL); 1713 - NtClose(FileHandle); 1714 - if (!NT_SUCCESS(Status)) 1715 - { 1716 - // RtlFreeHeap(ProcessHeap, 0, OrigBootSector); 1717 - RtlFreeHeap(ProcessHeap, 0, NewBootSector); 1718 - return Status; 1719 - } 1720 - 1721 - #if 0 1722 - /* Adjust bootsector (copy a part of the FAT32 BPB) */ 1723 - memcpy(&NewBootSector->OemName, 1724 - &OrigBootSector->OemName, 1725 - FIELD_OFFSET(FAT32_BOOTSECTOR, BootCodeAndData) - 1726 - FIELD_OFFSET(FAT32_BOOTSECTOR, OemName)); 1727 - 1728 - /* Get the location of the backup boot sector */ 1729 - BackupBootSector = OrigBootSector->BackupBootSector; 1730 - 1731 - /* Free the original boot sector */ 1732 - // RtlFreeHeap(ProcessHeap, 0, OrigBootSector); 1733 - #endif 1734 - 1735 - /* Open the root partition - Remove any trailing backslash if needed */ 1736 - RtlInitUnicodeString(&Name, RootPath); 1737 - TrimTrailingPathSeparators_UStr(&Name); 1738 - 1739 - InitializeObjectAttributes(&ObjectAttributes, 1740 - &Name, 1741 - OBJ_CASE_INSENSITIVE, 1742 - NULL, 1743 - NULL); 1744 - 1745 - Status = NtOpenFile(&FileHandle, 1746 - GENERIC_WRITE | SYNCHRONIZE, 1747 - &ObjectAttributes, 1748 - &IoStatusBlock, 1749 - FILE_SHARE_READ | FILE_SHARE_WRITE, 1750 - FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY); 1751 - if (!NT_SUCCESS(Status)) 1752 - { 1753 - DPRINT1("NtOpenFile() failed (Status %lx)\n", Status); 1754 - RtlFreeHeap(ProcessHeap, 0, NewBootSector); 1755 - return Status; 1756 - } 1757 - 1758 751 /* 1759 - * The BTRFS driver requires the volume to be locked in order to modify 1760 - * the first sectors of the partition, even though they are outside the 1761 - * file-system space / in the reserved area (they are situated before 1762 - * the super-block at 0x1000) and is in principle allowed by the NT 1763 - * storage stack. 1764 - * So we lock here in order to write the bootsector at sector 0. 1765 - * If locking fails, we ignore and continue nonetheless. 752 + * The DestinationDevicePathBuffer parameter has been built with 753 + * the following instruction by the caller; I'm not yet sure whether 754 + * I actually want this function to build the path instead, hence 755 + * I keep this code here but disabled for now... 1766 756 */ 1767 - LockStatus = NtFsControlFile(FileHandle, 1768 - NULL, 1769 - NULL, 1770 - NULL, 1771 - &IoStatusBlock, 1772 - FSCTL_LOCK_VOLUME, 1773 - NULL, 1774 - 0, 1775 - NULL, 1776 - 0); 1777 - if (!NT_SUCCESS(LockStatus)) 1778 - { 1779 - DPRINT1("WARNING: Failed to lock BTRFS volume for writing bootsector! Operations may fail! (Status 0x%lx)\n", LockStatus); 1780 - } 757 + WCHAR DestinationDevicePathBuffer[MAX_PATH]; 758 + RtlStringCchPrintfW(DestinationDevicePathBuffer, ARRAYSIZE(DestinationDevicePathBuffer), 759 + L"\\Device\\Harddisk%d\\Partition0", 760 + DiskNumber); 761 + #endif 1781 762 1782 - /* Obtaining partition info and writing it to bootsector */ 1783 - Status = NtDeviceIoControlFile(FileHandle, 1784 - NULL, 1785 - NULL, 1786 - NULL, 1787 - &IoStatusBlock, 1788 - IOCTL_DISK_GET_PARTITION_INFO_EX, 1789 - NULL, 1790 - 0, 1791 - &PartInfo, 1792 - sizeof(PartInfo)); 1793 - if (!NT_SUCCESS(Status)) 1794 - { 1795 - DPRINT1("IOCTL_DISK_GET_PARTITION_INFO_EX failed (Status %lx)\n", Status); 1796 - goto Quit; 1797 - } 763 + CombinePaths(SourceMbrPathBuffer, ARRAYSIZE(SourceMbrPathBuffer), 2, 764 + SourceRootPath->Buffer, L"\\loader\\dosmbr.bin"); 1798 765 1799 - /* Write new bootsector to RootPath */ 1800 - 1801 - NewBootSector->PartitionStartLBA = PartInfo.StartingOffset.QuadPart / SECTORSIZE; 1802 - 1803 - /* Write sector 0 */ 1804 - FileOffset.QuadPart = 0ULL; 1805 - Status = NtWriteFile(FileHandle, 1806 - NULL, 1807 - NULL, 1808 - NULL, 1809 - &IoStatusBlock, 1810 - NewBootSector, 1811 - sizeof(BTRFS_BOOTSECTOR), 1812 - &FileOffset, 1813 - NULL); 1814 - if (!NT_SUCCESS(Status)) 766 + if (IsThereAValidBootSector(DestinationDevicePathBuffer)) 1815 767 { 1816 - DPRINT1("NtWriteFile() failed (Status %lx)\n", Status); 1817 - goto Quit; 1818 - } 768 + /* Save current MBR */ 769 + CombinePaths(DstPath, ARRAYSIZE(DstPath), 2, 770 + SystemRootPath->Buffer, L"mbr.old"); 1819 771 1820 - #if 0 1821 - /* Write backup boot sector */ 1822 - if ((BackupBootSector != 0x0000) && (BackupBootSector != 0xFFFF)) 1823 - { 1824 - FileOffset.QuadPart = (ULONGLONG)((ULONG)BackupBootSector * SECTORSIZE); 1825 - Status = NtWriteFile(FileHandle, 1826 - NULL, 1827 - NULL, 1828 - NULL, 1829 - &IoStatusBlock, 1830 - NewBootSector, 1831 - SECTORSIZE, 1832 - &FileOffset, 1833 - NULL); 772 + DPRINT1("Save MBR: %S ==> %S\n", DestinationDevicePathBuffer, DstPath); 773 + Status = SaveBootSector(DestinationDevicePathBuffer, DstPath, sizeof(PARTITION_SECTOR)); 1834 774 if (!NT_SUCCESS(Status)) 1835 775 { 1836 - DPRINT1("NtWriteFile() failed (Status %lx)\n", Status); 1837 - goto Quit; 776 + DPRINT1("SaveBootSector() failed (Status %lx)\n", Status); 777 + // Don't care if we succeeded or not saving the old MBR, just go ahead. 1838 778 } 1839 779 } 1840 780 1841 - /* Write sector 14 */ 1842 - FileOffset.QuadPart = 14 * SECTORSIZE; 1843 - Status = NtWriteFile(FileHandle, 1844 - NULL, 1845 - NULL, 1846 - NULL, 1847 - &IoStatusBlock, 1848 - ((PUCHAR)NewBootSector + SECTORSIZE), 1849 - SECTORSIZE, 1850 - &FileOffset, 1851 - NULL); 1852 - if (!NT_SUCCESS(Status)) 1853 - { 1854 - DPRINT1("NtWriteFile() failed (Status %lx)\n", Status); 1855 - } 1856 - #endif 1857 - 1858 - Quit: 1859 - /* Unlock the volume */ 1860 - LockStatus = NtFsControlFile(FileHandle, 1861 - NULL, 1862 - NULL, 1863 - NULL, 1864 - &IoStatusBlock, 1865 - FSCTL_UNLOCK_VOLUME, 1866 - NULL, 1867 - 0, 1868 - NULL, 1869 - 0); 1870 - if (!NT_SUCCESS(LockStatus)) 1871 - { 1872 - DPRINT1("Failed to unlock BTRFS volume (Status 0x%lx)\n", LockStatus); 1873 - } 781 + DPRINT1("Install MBR bootcode: %S ==> %S\n", 782 + SourceMbrPathBuffer, DestinationDevicePathBuffer); 1874 783 1875 - /* Close the volume */ 1876 - NtClose(FileHandle); 1877 - 1878 - /* Free the new boot sector */ 1879 - RtlFreeHeap(ProcessHeap, 0, NewBootSector); 1880 - 1881 - return Status; 784 + /* Install the MBR */ 785 + return InstallBootCodeToDisk(SourceMbrPathBuffer, 786 + DestinationDevicePathBuffer, 787 + InstallMbrBootCode); 1882 788 } 1883 789 1884 790 ··· 1957 863 CombinePaths(SrcPath, ARRAYSIZE(SrcPath), 2, SourceRootPath->Buffer, L"\\loader\\fat32.bin"); 1958 864 1959 865 DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath, DstPath); 1960 - Status = InstallFat32BootCodeToFile(SrcPath, DstPath, 1961 - SystemRootPath->Buffer); 866 + Status = InstallBootCodeToFile(SrcPath, DstPath, 867 + SystemRootPath->Buffer, 868 + InstallFat32BootCode); 1962 869 if (!NT_SUCCESS(Status)) 1963 870 { 1964 - DPRINT1("InstallFat32BootCodeToFile() failed (Status %lx)\n", Status); 871 + DPRINT1("InstallBootCodeToFile(FAT32) failed (Status %lx)\n", Status); 1965 872 return Status; 1966 873 } 1967 874 } ··· 1970 877 /* Install FAT16 bootcode */ 1971 878 CombinePaths(SrcPath, ARRAYSIZE(SrcPath), 2, SourceRootPath->Buffer, L"\\loader\\fat.bin"); 1972 879 1973 - DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath, DstPath); 1974 - Status = InstallFat16BootCodeToFile(SrcPath, DstPath, 1975 - SystemRootPath->Buffer); 880 + DPRINT1("Install FAT16 bootcode: %S ==> %S\n", SrcPath, DstPath); 881 + Status = InstallBootCodeToFile(SrcPath, DstPath, 882 + SystemRootPath->Buffer, 883 + InstallFat16BootCode); 1976 884 if (!NT_SUCCESS(Status)) 1977 885 { 1978 - DPRINT1("InstallFat16BootCodeToFile() failed (Status %lx)\n", Status); 886 + DPRINT1("InstallBootCodeToFile(FAT16) failed (Status %lx)\n", Status); 1979 887 return Status; 1980 888 } 1981 889 } ··· 2169 1077 CombinePaths(SrcPath, ARRAYSIZE(SrcPath), 2, SourceRootPath->Buffer, L"\\loader\\fat32.bin"); 2170 1078 2171 1079 DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath, SystemRootPath->Buffer); 2172 - Status = InstallFat32BootCodeToDisk(SrcPath, SystemRootPath->Buffer); 1080 + Status = InstallBootCodeToDisk(SrcPath, SystemRootPath->Buffer, InstallFat32BootCode); 2173 1081 if (!NT_SUCCESS(Status)) 2174 1082 { 2175 - DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)\n", Status); 1083 + DPRINT1("InstallBootCodeToDisk(FAT32) failed (Status %lx)\n", Status); 2176 1084 return Status; 2177 1085 } 2178 1086 } ··· 2182 1090 CombinePaths(SrcPath, ARRAYSIZE(SrcPath), 2, SourceRootPath->Buffer, L"\\loader\\fat.bin"); 2183 1091 2184 1092 DPRINT1("Install FAT16 bootcode: %S ==> %S\n", SrcPath, SystemRootPath->Buffer); 2185 - Status = InstallFat16BootCodeToDisk(SrcPath, SystemRootPath->Buffer); 1093 + Status = InstallBootCodeToDisk(SrcPath, SystemRootPath->Buffer, InstallFat16BootCode); 2186 1094 if (!NT_SUCCESS(Status)) 2187 1095 { 2188 - DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status); 1096 + DPRINT1("InstallBootCodeToDisk(FAT16) failed (Status %lx)\n", Status); 2189 1097 return Status; 2190 1098 } 2191 1099 } ··· 2200 1108 InstallBtrfsBootcodeToPartition( 2201 1109 IN PUNICODE_STRING SystemRootPath, 2202 1110 IN PUNICODE_STRING SourceRootPath, 2203 - IN PUNICODE_STRING DestinationArcPath, 2204 - IN UCHAR PartitionType) 1111 + IN PUNICODE_STRING DestinationArcPath) 2205 1112 { 2206 1113 NTSTATUS Status; 2207 1114 BOOLEAN DoesFreeLdrExist; ··· 2266 1173 CombinePaths(DstPath, ARRAYSIZE(DstPath), 2, SystemRootPath->Buffer, BootSector); 2267 1174 2268 1175 DPRINT1("Save bootsector: %S ==> %S\n", SystemRootPath->Buffer, DstPath); 2269 - Status = SaveBootSector(SystemRootPath->Buffer, DstPath, sizeof(BTRFS_BOOTSECTOR)); 1176 + Status = SaveBootSector(SystemRootPath->Buffer, DstPath, BTRFS_BOOTSECTOR_SIZE); 2270 1177 if (!NT_SUCCESS(Status)) 2271 1178 { 2272 1179 DPRINT1("SaveBootSector() failed (Status %lx)\n", Status); ··· 2284 1191 } 2285 1192 2286 1193 /* Install new bootsector on the disk */ 2287 - // if (PartitionType == PARTITION_EXT2) 1194 + /* Install BTRFS bootcode */ 1195 + CombinePaths(SrcPath, ARRAYSIZE(SrcPath), 2, SourceRootPath->Buffer, L"\\loader\\btrfs.bin"); 1196 + 1197 + DPRINT1("Install BTRFS bootcode: %S ==> %S\n", SrcPath, SystemRootPath->Buffer); 1198 + Status = InstallBootCodeToDisk(SrcPath, SystemRootPath->Buffer, InstallBtrfsBootCode); 1199 + if (!NT_SUCCESS(Status)) 2288 1200 { 2289 - /* Install BTRFS bootcode */ 2290 - CombinePaths(SrcPath, ARRAYSIZE(SrcPath), 2, SourceRootPath->Buffer, L"\\loader\\btrfs.bin"); 2291 - 2292 - DPRINT1("Install BTRFS bootcode: %S ==> %S\n", SrcPath, SystemRootPath->Buffer); 2293 - Status = InstallBtrfsBootCodeToDisk(SrcPath, SystemRootPath->Buffer); 2294 - if (!NT_SUCCESS(Status)) 2295 - { 2296 - DPRINT1("InstallBtrfsBootCodeToDisk() failed (Status %lx)\n", Status); 2297 - return Status; 2298 - } 1201 + DPRINT1("InstallBootCodeToDisk(BTRFS) failed (Status %lx)\n", Status); 1202 + return Status; 2299 1203 } 2300 1204 } 2301 1205 ··· 2329 1233 { 2330 1234 return InstallBtrfsBootcodeToPartition(SystemRootPath, 2331 1235 SourceRootPath, 2332 - DestinationArcPath, 2333 - PartitionType); 1236 + DestinationArcPath); 2334 1237 } 2335 1238 2336 1239 case PARTITION_IFS: ··· 2405 1308 CombinePaths(SrcPath, ARRAYSIZE(SrcPath), 2, SourceRootPath->Buffer, L"\\loader\\fat.bin"); 2406 1309 CombinePaths(DstPath, ARRAYSIZE(DstPath), 1, FloppyDevice); 2407 1310 2408 - DPRINT("Install FAT bootcode: %S ==> %S\n", SrcPath, DstPath); 2409 - Status = InstallFat12BootCodeToFloppy(SrcPath, DstPath); 1311 + DPRINT("Install FAT12 bootcode: %S ==> %S\n", SrcPath, DstPath); 1312 + Status = InstallBootCodeToDisk(SrcPath, DstPath, InstallFat12BootCode); 2410 1313 if (!NT_SUCCESS(Status)) 2411 1314 { 2412 - DPRINT1("InstallFat12BootCodeToFloppy() failed (Status %lx)\n", Status); 1315 + DPRINT1("InstallBootCodeToDisk(FAT12) failed (Status %lx)\n", Status); 2413 1316 return Status; 2414 1317 } 2415 1318
+379 -1
base/setup/lib/fsutil.c
··· 3 3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) 4 4 * PURPOSE: Filesystem support functions 5 5 * COPYRIGHT: Copyright 2003-2019 Casper S. Hornstrup (chorns@users.sourceforge.net) 6 - * Copyright 2017-2019 Hermes Belusca-Maito 6 + * Copyright 2017-2020 Hermes Belusca-Maito 7 7 */ 8 8 9 9 // ··· 18 18 19 19 #include "partlist.h" 20 20 #include "fsrec.h" 21 + #include "bootcode.h" 21 22 #include "fsutil.h" 22 23 23 24 #include <fslib/vfatlib.h> ··· 27 28 28 29 #define NDEBUG 29 30 #include <debug.h> 31 + 32 + 33 + /* TYPEDEFS *****************************************************************/ 34 + 35 + #include <pshpack1.h> 36 + typedef struct _FAT_BOOTSECTOR 37 + { 38 + UCHAR JumpBoot[3]; // Jump instruction to boot code 39 + CHAR OemName[8]; // "MSWIN4.1" for MS formatted volumes 40 + USHORT BytesPerSector; // Bytes per sector 41 + UCHAR SectorsPerCluster; // Number of sectors in a cluster 42 + USHORT ReservedSectors; // Reserved sectors, usually 1 (the bootsector) 43 + UCHAR NumberOfFats; // Number of FAT tables 44 + USHORT RootDirEntries; // Number of root directory entries (fat12/16) 45 + USHORT TotalSectors; // Number of total sectors on the drive, 16-bit 46 + UCHAR MediaDescriptor; // Media descriptor byte 47 + USHORT SectorsPerFat; // Sectors per FAT table (fat12/16) 48 + USHORT SectorsPerTrack; // Number of sectors in a track 49 + USHORT NumberOfHeads; // Number of heads on the disk 50 + ULONG HiddenSectors; // Hidden sectors (sectors before the partition start like the partition table) 51 + ULONG TotalSectorsBig; // This field is the new 32-bit total count of sectors on the volume 52 + UCHAR DriveNumber; // Int 0x13 drive number (e.g. 0x80) 53 + UCHAR Reserved1; // Reserved (used by Windows NT). Code that formats FAT volumes should always set this byte to 0. 54 + UCHAR BootSignature; // Extended boot signature (0x29). This is a signature byte that indicates that the following three fields in the boot sector are present. 55 + ULONG VolumeSerialNumber; // Volume serial number 56 + CHAR VolumeLabel[11]; // Volume label. This field matches the 11-byte volume label recorded in the root directory 57 + CHAR FileSystemType[8]; // One of the strings "FAT12 ", "FAT16 ", or "FAT " 58 + 59 + UCHAR BootCodeAndData[448]; // The remainder of the boot sector 60 + 61 + USHORT BootSectorMagic; // 0xAA55 62 + 63 + } FAT_BOOTSECTOR, *PFAT_BOOTSECTOR; 64 + C_ASSERT(sizeof(FAT_BOOTSECTOR) == FAT_BOOTSECTOR_SIZE); 65 + 66 + typedef struct _FAT32_BOOTSECTOR 67 + { 68 + UCHAR JumpBoot[3]; // Jump instruction to boot code 69 + CHAR OemName[8]; // "MSWIN4.1" for MS formatted volumes 70 + USHORT BytesPerSector; // Bytes per sector 71 + UCHAR SectorsPerCluster; // Number of sectors in a cluster 72 + USHORT ReservedSectors; // Reserved sectors, usually 1 (the bootsector) 73 + UCHAR NumberOfFats; // Number of FAT tables 74 + USHORT RootDirEntries; // Number of root directory entries (fat12/16) 75 + USHORT TotalSectors; // Number of total sectors on the drive, 16-bit 76 + UCHAR MediaDescriptor; // Media descriptor byte 77 + USHORT SectorsPerFat; // Sectors per FAT table (fat12/16) 78 + USHORT SectorsPerTrack; // Number of sectors in a track 79 + USHORT NumberOfHeads; // Number of heads on the disk 80 + ULONG HiddenSectors; // Hidden sectors (sectors before the partition start like the partition table) 81 + ULONG TotalSectorsBig; // This field is the new 32-bit total count of sectors on the volume 82 + ULONG SectorsPerFatBig; // This field is the FAT32 32-bit count of sectors occupied by ONE FAT. BPB_FATSz16 must be 0 83 + USHORT ExtendedFlags; // Extended flags (fat32) 84 + USHORT FileSystemVersion; // File system version (fat32) 85 + ULONG RootDirStartCluster; // Starting cluster of the root directory (fat32) 86 + USHORT FsInfo; // Sector number of FSINFO structure in the reserved area of the FAT32 volume. Usually 1. 87 + USHORT BackupBootSector; // If non-zero, indicates the sector number in the reserved area of the volume of a copy of the boot record. Usually 6. 88 + UCHAR Reserved[12]; // Reserved for future expansion 89 + UCHAR DriveNumber; // Int 0x13 drive number (e.g. 0x80) 90 + UCHAR Reserved1; // Reserved (used by Windows NT). Code that formats FAT volumes should always set this byte to 0. 91 + UCHAR BootSignature; // Extended boot signature (0x29). This is a signature byte that indicates that the following three fields in the boot sector are present. 92 + ULONG VolumeSerialNumber; // Volume serial number 93 + CHAR VolumeLabel[11]; // Volume label. This field matches the 11-byte volume label recorded in the root directory 94 + CHAR FileSystemType[8]; // Always set to the string "FAT32 " 95 + 96 + UCHAR BootCodeAndData[420]; // The remainder of the boot sector 97 + 98 + USHORT BootSectorMagic; // 0xAA55 99 + 100 + } FAT32_BOOTSECTOR, *PFAT32_BOOTSECTOR; 101 + C_ASSERT(sizeof(FAT32_BOOTSECTOR) == FAT32_BOOTSECTOR_SIZE); 102 + 103 + typedef struct _BTRFS_BOOTSECTOR 104 + { 105 + UCHAR JumpBoot[3]; 106 + UCHAR ChunkMapSize; 107 + UCHAR BootDrive; 108 + ULONGLONG PartitionStartLBA; 109 + UCHAR Fill[1521]; // 1536 - 15 110 + USHORT BootSectorMagic; 111 + } BTRFS_BOOTSECTOR, *PBTRFS_BOOTSECTOR; 112 + C_ASSERT(sizeof(BTRFS_BOOTSECTOR) == BTRFS_BOOTSECTOR_SIZE); 113 + 114 + // TODO: Add more bootsector structures! 115 + 116 + #include <poppack.h> 30 117 31 118 32 119 /* LOCALS *******************************************************************/ ··· 235 322 QuickFormat, 236 323 ClusterSize, 237 324 Callback); 325 + } 326 + 327 + 328 + // 329 + // Bootsector routines 330 + // 331 + 332 + NTSTATUS 333 + InstallFat1216BootCode( 334 + IN PCWSTR SrcPath, // FAT12/16 bootsector source file (on the installation medium) 335 + IN HANDLE DstPath, // Where to save the bootsector built from the source + partition information 336 + IN HANDLE RootPartition) // Partition holding the (old) FAT12/16 information 337 + { 338 + NTSTATUS Status; 339 + UNICODE_STRING Name; 340 + IO_STATUS_BLOCK IoStatusBlock; 341 + LARGE_INTEGER FileOffset; 342 + BOOTCODE OrigBootSector = {0}; 343 + BOOTCODE NewBootSector = {0}; 344 + 345 + /* Allocate and read the current original partition bootsector */ 346 + Status = ReadBootCodeByHandle(&OrigBootSector, 347 + RootPartition, 348 + FAT_BOOTSECTOR_SIZE); 349 + if (!NT_SUCCESS(Status)) 350 + return Status; 351 + 352 + /* Allocate and read the new bootsector from SrcPath */ 353 + RtlInitUnicodeString(&Name, SrcPath); 354 + Status = ReadBootCodeFromFile(&NewBootSector, 355 + &Name, 356 + FAT_BOOTSECTOR_SIZE); 357 + if (!NT_SUCCESS(Status)) 358 + { 359 + FreeBootCode(&OrigBootSector); 360 + return Status; 361 + } 362 + 363 + /* Adjust the bootsector (copy a part of the FAT12/16 BPB) */ 364 + RtlCopyMemory(&((PFAT_BOOTSECTOR)NewBootSector.BootCode)->OemName, 365 + &((PFAT_BOOTSECTOR)OrigBootSector.BootCode)->OemName, 366 + FIELD_OFFSET(FAT_BOOTSECTOR, BootCodeAndData) - 367 + FIELD_OFFSET(FAT_BOOTSECTOR, OemName)); 368 + 369 + /* Free the original bootsector */ 370 + FreeBootCode(&OrigBootSector); 371 + 372 + /* Write the new bootsector to DstPath */ 373 + FileOffset.QuadPart = 0ULL; 374 + Status = NtWriteFile(DstPath, 375 + NULL, 376 + NULL, 377 + NULL, 378 + &IoStatusBlock, 379 + NewBootSector.BootCode, 380 + NewBootSector.Length, 381 + &FileOffset, 382 + NULL); 383 + 384 + /* Free the new bootsector */ 385 + FreeBootCode(&NewBootSector); 386 + 387 + return Status; 388 + } 389 + 390 + NTSTATUS 391 + InstallFat32BootCode( 392 + IN PCWSTR SrcPath, // FAT32 bootsector source file (on the installation medium) 393 + IN HANDLE DstPath, // Where to save the bootsector built from the source + partition information 394 + IN HANDLE RootPartition) // Partition holding the (old) FAT32 information 395 + { 396 + NTSTATUS Status; 397 + UNICODE_STRING Name; 398 + IO_STATUS_BLOCK IoStatusBlock; 399 + LARGE_INTEGER FileOffset; 400 + USHORT BackupBootSector = 0; 401 + BOOTCODE OrigBootSector = {0}; 402 + BOOTCODE NewBootSector = {0}; 403 + 404 + /* Allocate and read the current original partition bootsector */ 405 + Status = ReadBootCodeByHandle(&OrigBootSector, 406 + RootPartition, 407 + FAT32_BOOTSECTOR_SIZE); 408 + if (!NT_SUCCESS(Status)) 409 + return Status; 410 + 411 + /* Allocate and read the new bootsector (2 sectors) from SrcPath */ 412 + RtlInitUnicodeString(&Name, SrcPath); 413 + Status = ReadBootCodeFromFile(&NewBootSector, 414 + &Name, 415 + 2 * FAT32_BOOTSECTOR_SIZE); 416 + if (!NT_SUCCESS(Status)) 417 + { 418 + FreeBootCode(&OrigBootSector); 419 + return Status; 420 + } 421 + 422 + /* Adjust the bootsector (copy a part of the FAT32 BPB) */ 423 + RtlCopyMemory(&((PFAT32_BOOTSECTOR)NewBootSector.BootCode)->OemName, 424 + &((PFAT32_BOOTSECTOR)OrigBootSector.BootCode)->OemName, 425 + FIELD_OFFSET(FAT32_BOOTSECTOR, BootCodeAndData) - 426 + FIELD_OFFSET(FAT32_BOOTSECTOR, OemName)); 427 + 428 + /* 429 + * We know we copy the boot code to a file only when DstPath != RootPartition, 430 + * otherwise the boot code is copied to the specified root partition. 431 + */ 432 + if (DstPath != RootPartition) 433 + { 434 + /* Copy to a file: Disable the backup bootsector */ 435 + ((PFAT32_BOOTSECTOR)NewBootSector.BootCode)->BackupBootSector = 0; 436 + } 437 + else 438 + { 439 + /* Copy to a disk: Get the location of the backup bootsector */ 440 + BackupBootSector = ((PFAT32_BOOTSECTOR)OrigBootSector.BootCode)->BackupBootSector; 441 + } 442 + 443 + /* Free the original bootsector */ 444 + FreeBootCode(&OrigBootSector); 445 + 446 + /* Write the first sector of the new bootcode to DstPath sector 0 */ 447 + FileOffset.QuadPart = 0ULL; 448 + Status = NtWriteFile(DstPath, 449 + NULL, 450 + NULL, 451 + NULL, 452 + &IoStatusBlock, 453 + NewBootSector.BootCode, 454 + FAT32_BOOTSECTOR_SIZE, 455 + &FileOffset, 456 + NULL); 457 + if (!NT_SUCCESS(Status)) 458 + { 459 + DPRINT1("NtWriteFile() failed (Status %lx)\n", Status); 460 + FreeBootCode(&NewBootSector); 461 + return Status; 462 + } 463 + 464 + if (DstPath == RootPartition) 465 + { 466 + /* Copy to a disk: Write the backup bootsector */ 467 + if ((BackupBootSector != 0x0000) && (BackupBootSector != 0xFFFF)) 468 + { 469 + FileOffset.QuadPart = (ULONGLONG)((ULONG)BackupBootSector * FAT32_BOOTSECTOR_SIZE); 470 + Status = NtWriteFile(DstPath, 471 + NULL, 472 + NULL, 473 + NULL, 474 + &IoStatusBlock, 475 + NewBootSector.BootCode, 476 + FAT32_BOOTSECTOR_SIZE, 477 + &FileOffset, 478 + NULL); 479 + if (!NT_SUCCESS(Status)) 480 + { 481 + DPRINT1("NtWriteFile() failed (Status %lx)\n", Status); 482 + FreeBootCode(&NewBootSector); 483 + return Status; 484 + } 485 + } 486 + } 487 + 488 + /* Write the second sector of the new bootcode to boot disk sector 14 */ 489 + // FileOffset.QuadPart = (ULONGLONG)(14 * FAT32_BOOTSECTOR_SIZE); 490 + FileOffset.QuadPart = 14 * FAT32_BOOTSECTOR_SIZE; 491 + Status = NtWriteFile(DstPath, // or really RootPartition ??? 492 + NULL, 493 + NULL, 494 + NULL, 495 + &IoStatusBlock, 496 + ((PUCHAR)NewBootSector.BootCode + FAT32_BOOTSECTOR_SIZE), 497 + FAT32_BOOTSECTOR_SIZE, 498 + &FileOffset, 499 + NULL); 500 + if (!NT_SUCCESS(Status)) 501 + { 502 + DPRINT1("NtWriteFile() failed (Status %lx)\n", Status); 503 + } 504 + 505 + /* Free the new bootsector */ 506 + FreeBootCode(&NewBootSector); 507 + 508 + return Status; 509 + } 510 + 511 + NTSTATUS 512 + InstallBtrfsBootCode( 513 + IN PCWSTR SrcPath, // BTRFS bootsector source file (on the installation medium) 514 + IN HANDLE DstPath, // Where to save the bootsector built from the source + partition information 515 + IN HANDLE RootPartition) // Partition holding the (old) BTRFS information 516 + { 517 + NTSTATUS Status; 518 + NTSTATUS LockStatus; 519 + UNICODE_STRING Name; 520 + IO_STATUS_BLOCK IoStatusBlock; 521 + LARGE_INTEGER FileOffset; 522 + PARTITION_INFORMATION_EX PartInfo; 523 + BOOTCODE NewBootSector = {0}; 524 + 525 + /* Allocate and read the new bootsector from SrcPath */ 526 + RtlInitUnicodeString(&Name, SrcPath); 527 + Status = ReadBootCodeFromFile(&NewBootSector, 528 + &Name, 529 + BTRFS_BOOTSECTOR_SIZE); 530 + if (!NT_SUCCESS(Status)) 531 + return Status; 532 + 533 + /* 534 + * The BTRFS driver requires the volume to be locked in order to modify 535 + * the first sectors of the partition, even though they are outside the 536 + * file-system space / in the reserved area (they are situated before 537 + * the super-block at 0x1000) and is in principle allowed by the NT 538 + * storage stack. 539 + * So we lock here in order to write the bootsector at sector 0. 540 + * If locking fails, we ignore and continue nonetheless. 541 + */ 542 + LockStatus = NtFsControlFile(DstPath, 543 + NULL, 544 + NULL, 545 + NULL, 546 + &IoStatusBlock, 547 + FSCTL_LOCK_VOLUME, 548 + NULL, 549 + 0, 550 + NULL, 551 + 0); 552 + if (!NT_SUCCESS(LockStatus)) 553 + { 554 + DPRINT1("WARNING: Failed to lock BTRFS volume for writing bootsector! Operations may fail! (Status 0x%lx)\n", LockStatus); 555 + } 556 + 557 + /* Obtain partition info and write it to the bootsector */ 558 + Status = NtDeviceIoControlFile(RootPartition, 559 + NULL, 560 + NULL, 561 + NULL, 562 + &IoStatusBlock, 563 + IOCTL_DISK_GET_PARTITION_INFO_EX, 564 + NULL, 565 + 0, 566 + &PartInfo, 567 + sizeof(PartInfo)); 568 + if (!NT_SUCCESS(Status)) 569 + { 570 + DPRINT1("IOCTL_DISK_GET_PARTITION_INFO_EX failed (Status %lx)\n", Status); 571 + goto Quit; 572 + } 573 + 574 + /* Write new bootsector to RootPath */ 575 + ((PBTRFS_BOOTSECTOR)NewBootSector.BootCode)->PartitionStartLBA = 576 + PartInfo.StartingOffset.QuadPart / SECTORSIZE; 577 + 578 + /* Write sector 0 */ 579 + FileOffset.QuadPart = 0ULL; 580 + Status = NtWriteFile(DstPath, 581 + NULL, 582 + NULL, 583 + NULL, 584 + &IoStatusBlock, 585 + NewBootSector.BootCode, 586 + NewBootSector.Length, 587 + &FileOffset, 588 + NULL); 589 + if (!NT_SUCCESS(Status)) 590 + { 591 + DPRINT1("NtWriteFile() failed (Status %lx)\n", Status); 592 + goto Quit; 593 + } 594 + 595 + Quit: 596 + /* Unlock the volume */ 597 + LockStatus = NtFsControlFile(DstPath, 598 + NULL, 599 + NULL, 600 + NULL, 601 + &IoStatusBlock, 602 + FSCTL_UNLOCK_VOLUME, 603 + NULL, 604 + 0, 605 + NULL, 606 + 0); 607 + if (!NT_SUCCESS(LockStatus)) 608 + { 609 + DPRINT1("Failed to unlock BTRFS volume (Status 0x%lx)\n", LockStatus); 610 + } 611 + 612 + /* Free the new bootsector */ 613 + FreeBootCode(&NewBootSector); 614 + 615 + return Status; 238 616 } 239 617 240 618
+37 -1
base/setup/lib/fsutil.h
··· 3 3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) 4 4 * PURPOSE: Filesystem support functions 5 5 * COPYRIGHT: Copyright 2003-2019 Casper S. Hornstrup (chorns@users.sourceforge.net) 6 - * Copyright 2017-2019 Hermes Belusca-Maito 6 + * Copyright 2017-2020 Hermes Belusca-Maito 7 7 */ 8 8 9 9 #pragma once ··· 59 59 IN BOOLEAN QuickFormat, 60 60 IN ULONG ClusterSize, 61 61 IN PFMIFSCALLBACK Callback); 62 + 63 + 64 + // 65 + // Bootsector routines 66 + // 67 + 68 + #define FAT_BOOTSECTOR_SIZE (1 * SECTORSIZE) 69 + #define FAT32_BOOTSECTOR_SIZE (1 * SECTORSIZE) // Counts only the primary sector. 70 + #define BTRFS_BOOTSECTOR_SIZE (3 * SECTORSIZE) 71 + 72 + typedef NTSTATUS 73 + (/*NTAPI*/ *PFS_INSTALL_BOOTCODE)( 74 + IN PCWSTR SrcPath, // Bootsector source file (on the installation medium) 75 + IN HANDLE DstPath, // Where to save the bootsector built from the source + partition information 76 + IN HANDLE RootPartition); // Partition holding the (old) bootsector data information 77 + 78 + NTSTATUS 79 + InstallFat1216BootCode( 80 + IN PCWSTR SrcPath, 81 + IN HANDLE DstPath, 82 + IN HANDLE RootPartition); 83 + 84 + #define InstallFat12BootCode InstallFat1216BootCode 85 + #define InstallFat16BootCode InstallFat1216BootCode 86 + 87 + NTSTATUS 88 + InstallFat32BootCode( 89 + IN PCWSTR SrcPath, 90 + IN HANDLE DstPath, 91 + IN HANDLE RootPartition); 92 + 93 + NTSTATUS 94 + InstallBtrfsBootCode( 95 + IN PCWSTR SrcPath, 96 + IN HANDLE DstPath, 97 + IN HANDLE RootPartition); 62 98 63 99 64 100 //
+3 -2
base/setup/lib/setuplib.h
··· 31 31 #include "utils/ntverrsrc.h" 32 32 // #include "utils/arcname.h" 33 33 #include "utils/bldrsup.h" 34 - #include "bootsup.h" 35 34 #include "utils/filesup.h" 36 35 #include "utils/fsrec.h" 37 - #include "fsutil.h" 38 36 #include "utils/genlist.h" 39 37 #include "utils/inicache.h" 40 38 #include "utils/partlist.h" 41 39 #include "utils/arcname.h" 42 40 #include "utils/osdetect.h" 43 41 #include "utils/regutil.h" 42 + #include "bootcode.h" 43 + #include "fsutil.h" 44 + #include "bootsup.h" 44 45 #include "registry.h" 45 46 #include "mui.h" 46 47 #include "settings.h"