2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS text-mode setup
4 * FILE: base/setup/usetup/bootsup.c
5 * PURPOSE: Bootloader support functions
14 #define SECTORSIZE 512
17 typedef struct _FAT_BOOTSECTOR
19 UCHAR JumpBoot
[3]; // Jump instruction to boot code
20 CHAR OemName
[8]; // "MSWIN4.1" for MS formatted volumes
21 USHORT BytesPerSector
; // Bytes per sector
22 UCHAR SectorsPerCluster
; // Number of sectors in a cluster
23 USHORT ReservedSectors
; // Reserved sectors, usually 1 (the bootsector)
24 UCHAR NumberOfFats
; // Number of FAT tables
25 USHORT RootDirEntries
; // Number of root directory entries (fat12/16)
26 USHORT TotalSectors
; // Number of total sectors on the drive, 16-bit
27 UCHAR MediaDescriptor
; // Media descriptor byte
28 USHORT SectorsPerFat
; // Sectors per FAT table (fat12/16)
29 USHORT SectorsPerTrack
; // Number of sectors in a track
30 USHORT NumberOfHeads
; // Number of heads on the disk
31 ULONG HiddenSectors
; // Hidden sectors (sectors before the partition start like the partition table)
32 ULONG TotalSectorsBig
; // This field is the new 32-bit total count of sectors on the volume
33 UCHAR DriveNumber
; // Int 0x13 drive number (e.g. 0x80)
34 UCHAR Reserved1
; // Reserved (used by Windows NT). Code that formats FAT volumes should always set this byte to 0.
35 UCHAR BootSignature
; // Extended boot signature (0x29). This is a signature byte that indicates that the following three fields in the boot sector are present.
36 ULONG VolumeSerialNumber
; // Volume serial number
37 CHAR VolumeLabel
[11]; // Volume label. This field matches the 11-byte volume label recorded in the root directory
38 CHAR FileSystemType
[8]; // One of the strings "FAT12 ", "FAT16 ", or "FAT "
40 UCHAR BootCodeAndData
[448]; // The remainder of the boot sector
42 USHORT BootSectorMagic
; // 0xAA55
44 } FAT_BOOTSECTOR
, *PFAT_BOOTSECTOR
;
46 typedef struct _FAT32_BOOTSECTOR
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 ULONG SectorsPerFatBig
; // This field is the FAT32 32-bit count of sectors occupied by ONE FAT. BPB_FATSz16 must be 0
63 USHORT ExtendedFlags
; // Extended flags (fat32)
64 USHORT FileSystemVersion
; // File system version (fat32)
65 ULONG RootDirStartCluster
; // Starting cluster of the root directory (fat32)
66 USHORT FsInfo
; // Sector number of FSINFO structure in the reserved area of the FAT32 volume. Usually 1.
67 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.
68 UCHAR Reserved
[12]; // Reserved for future expansion
69 UCHAR DriveNumber
; // Int 0x13 drive number (e.g. 0x80)
70 UCHAR Reserved1
; // Reserved (used by Windows NT). Code that formats FAT volumes should always set this byte to 0.
71 UCHAR BootSignature
; // Extended boot signature (0x29). This is a signature byte that indicates that the following three fields in the boot sector are present.
72 ULONG VolumeSerialNumber
; // Volume serial number
73 CHAR VolumeLabel
[11]; // Volume label. This field matches the 11-byte volume label recorded in the root directory
74 CHAR FileSystemType
[8]; // Always set to the string "FAT32 "
76 UCHAR BootCodeAndData
[420]; // The remainder of the boot sector
78 USHORT BootSectorMagic
; // 0xAA55
80 } FAT32_BOOTSECTOR
, *PFAT32_BOOTSECTOR
;
82 typedef struct _BTRFS_BOOTSECTOR
87 ULONGLONG PartitionStartLBA
;
88 UCHAR Fill
[1521]; // 1536 - 15
89 USHORT BootSectorMagic
;
90 } BTRFS_BOOTSECTOR
, *PBTRFS_BOOTSECTOR
;
91 C_ASSERT(sizeof(BTRFS_BOOTSECTOR
) == 3 * 512);
93 // TODO: Add more bootsector structures!
97 extern PPARTLIST PartitionList
;
99 /* FUNCTIONS ****************************************************************/
104 CreateCommonFreeLoaderSections(
107 PINICACHESECTION IniSection
;
109 /* Create "FREELOADER" section */
110 IniSection
= IniCacheAppendSection(IniCache
, L
"FREELOADER");
113 if (IsUnattendedSetup
)
115 /* DefaultOS=ReactOS */
116 IniCacheInsertKey(IniSection
,
121 L
"ReactOS_KdSerial");
129 /* DefaultOS=ReactOS */
130 IniCacheInsertKey(IniSection
,
138 if (IsUnattendedSetup
)
141 /* Timeout=0 for unattended or non debug*/
142 IniCacheInsertKey(IniSection
,
151 /* Timeout=0 or 10 */
152 IniCacheInsertKey(IniSection
,
160 /* Create "Display" section */
161 IniSection
= IniCacheAppendSection(IniCache
, L
"Display");
163 /* TitleText=ReactOS Boot Manager */
164 IniCacheInsertKey(IniSection
,
168 L
"ReactOS Boot Manager");
170 /* StatusBarColor=Cyan */
171 IniCacheInsertKey(IniSection
,
177 /* StatusBarTextColor=Black */
178 IniCacheInsertKey(IniSection
,
181 L
"StatusBarTextColor",
184 /* BackdropTextColor=White */
185 IniCacheInsertKey(IniSection
,
188 L
"BackdropTextColor",
191 /* BackdropColor=Blue */
192 IniCacheInsertKey(IniSection
,
198 /* BackdropFillStyle=Medium */
199 IniCacheInsertKey(IniSection
,
202 L
"BackdropFillStyle",
205 /* TitleBoxTextColor=White */
206 IniCacheInsertKey(IniSection
,
209 L
"TitleBoxTextColor",
212 /* TitleBoxColor=Red */
213 IniCacheInsertKey(IniSection
,
219 /* MessageBoxTextColor=White */
220 IniCacheInsertKey(IniSection
,
223 L
"MessageBoxTextColor",
226 /* MessageBoxColor=Blue */
227 IniCacheInsertKey(IniSection
,
233 /* MenuTextColor=White */
234 IniCacheInsertKey(IniSection
,
241 IniCacheInsertKey(IniSection
,
247 /* TextColor=Yellow */
248 IniCacheInsertKey(IniSection
,
254 /* SelectedTextColor=Black */
255 IniCacheInsertKey(IniSection
,
258 L
"SelectedTextColor",
261 /* SelectedColor=Gray */
262 IniCacheInsertKey(IniSection
,
268 /* SelectedColor=Gray */
269 IniCacheInsertKey(IniSection
,
275 /* SelectedColor=Gray */
276 IniCacheInsertKey(IniSection
,
282 /* SelectedColor=Gray */
283 IniCacheInsertKey(IniSection
,
289 /* SelectedColor=Gray */
290 IniCacheInsertKey(IniSection
,
296 /* SelectedColor=Gray */
297 IniCacheInsertKey(IniSection
,
301 L
"Seconds until highlighted choice will be started automatically: ");
308 PINICACHESECTION OSSection
,
315 PINICACHESECTION IniSection
;
317 /* Insert entry into "Operating Systems" section */
318 IniCacheInsertKey(OSSection
,
324 /* Create new section */
325 IniSection
= IniCacheAppendSection(IniCache
, Section
);
328 IniCacheInsertKey(IniSection
,
335 IniCacheInsertKey(IniSection
,
342 IniCacheInsertKey(IniSection
,
348 return STATUS_SUCCESS
;
353 CreateFreeLoaderReactOSEntries(
357 PINICACHESECTION IniSection
;
359 /* Create "Operating Systems" section */
360 IniSection
= IniCacheAppendSection(IniCache
, L
"Operating Systems");
363 CreateNTOSEntry(IniCache
, IniSection
,
364 L
"ReactOS", L
"\"ReactOS\"",
365 L
"Windows2003", ArcPath
,
369 CreateNTOSEntry(IniCache
, IniSection
,
370 L
"ReactOS_Debug", L
"\"ReactOS (Debug)\"",
371 L
"Windows2003", ArcPath
,
372 L
"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS");
374 /* ReactOS_VBoxDebug */
375 CreateNTOSEntry(IniCache
, IniSection
,
376 L
"ReactOS_VBoxDebug", L
"\"ReactOS (VBoxDebug)\"",
377 L
"Windows2003", ArcPath
,
378 L
"/DEBUG /DEBUGPORT=VBOX /SOS");
382 /* ReactOS_KdSerial */
383 CreateNTOSEntry(IniCache
, IniSection
,
384 L
"ReactOS_KdSerial", L
"\"ReactOS (RosDbg)\"",
385 L
"Windows2003", ArcPath
,
386 L
"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /KDSERIAL");
390 CreateNTOSEntry(IniCache
, IniSection
,
391 L
"ReactOS_Screen", L
"\"ReactOS (Screen)\"",
392 L
"Windows2003", ArcPath
,
393 L
"/DEBUG /DEBUGPORT=SCREEN /SOS");
395 /* ReactOS_LogFile */
396 CreateNTOSEntry(IniCache
, IniSection
,
397 L
"ReactOS_LogFile", L
"\"ReactOS (Log file)\"",
398 L
"Windows2003", ArcPath
,
399 L
"/DEBUG /DEBUGPORT=FILE /SOS");
402 CreateNTOSEntry(IniCache
, IniSection
,
403 L
"ReactOS_Ram", L
"\"ReactOS (RAM Disk)\"",
404 L
"Windows2003", L
"ramdisk(0)\\ReactOS",
405 L
"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /RDPATH=reactos.img /RDIMAGEOFFSET=32256");
408 CreateNTOSEntry(IniCache
, IniSection
,
409 L
"ReactOS_EMS", L
"\"ReactOS (Emergency Management Services)\"",
410 L
"Windows2003", ArcPath
,
411 L
"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /redirect=com2 /redirectbaudrate=115200");
417 CreateFreeLoaderIniForReactOS(
423 /* Initialize the INI file */
424 IniCache
= IniCacheCreate();
426 /* Create the common FreeLdr sections */
427 CreateCommonFreeLoaderSections(IniCache
);
429 /* Add the ReactOS entries */
430 CreateFreeLoaderReactOSEntries(IniCache
, ArcPath
);
432 /* Save the INI file */
433 IniCacheSave(IniCache
, IniPath
);
434 IniCacheDestroy(IniCache
);
436 return STATUS_SUCCESS
;
441 CreateFreeLoaderIniForReactOSAndBootSector(
445 IN PCWSTR Description
,
447 IN PCWSTR BootPartition
,
448 IN PCWSTR BootSector
)
451 PINICACHESECTION IniSection
;
453 /* Initialize the INI file */
454 IniCache
= IniCacheCreate();
456 /* Create the common FreeLdr sections */
457 CreateCommonFreeLoaderSections(IniCache
);
459 /* Add the ReactOS entries */
460 CreateFreeLoaderReactOSEntries(IniCache
, (PWCHAR
)ArcPath
);
462 /* Get "Operating Systems" section */
463 IniSection
= IniCacheGetSection(IniCache
, L
"Operating Systems");
465 /* Insert entry into "Operating Systems" section */
466 IniCacheInsertKey(IniSection
,
470 (PWCHAR
)Description
);
472 /* Create new section */
473 IniSection
= IniCacheAppendSection(IniCache
, (PWCHAR
)Section
);
475 /* BootType=BootSector */
476 IniCacheInsertKey(IniSection
,
483 IniCacheInsertKey(IniSection
,
490 IniCacheInsertKey(IniSection
,
494 (PWCHAR
)BootPartition
);
497 IniCacheInsertKey(IniSection
,
503 /* Save the INI file */
504 IniCacheSave(IniCache
, (PWCHAR
)IniPath
);
505 IniCacheDestroy(IniCache
);
507 return STATUS_SUCCESS
;
518 PINICACHESECTION IniSection
;
519 PINICACHESECTION OsIniSection
;
520 WCHAR SectionName
[80];
522 WCHAR SystemPath
[200];
523 WCHAR SectionName2
[200];
527 Status
= IniCacheLoad(&IniCache
, IniPath
, FALSE
);
528 if (!NT_SUCCESS(Status
))
531 /* Get "Operating Systems" section */
532 IniSection
= IniCacheGetSection(IniCache
, L
"Operating Systems");
533 if (IniSection
== NULL
)
535 IniCacheDestroy(IniCache
);
536 return STATUS_UNSUCCESSFUL
;
539 /* Find an existing usable or an unused section name */
541 wcscpy(SectionName
, L
"ReactOS");
542 wcscpy(OsName
, L
"\"ReactOS\"");
545 Status
= IniCacheGetKey(IniSection
, SectionName
, &KeyData
);
546 if (!NT_SUCCESS(Status
))
549 /* Get operation system section */
550 if (KeyData
[0] == '"')
552 wcscpy(SectionName2
, &KeyData
[1]);
553 j
= wcslen(SectionName2
);
556 SectionName2
[j
-1] = 0;
561 wcscpy(SectionName2
, KeyData
);
564 /* Search for an existing ReactOS entry */
565 OsIniSection
= IniCacheGetSection(IniCache
, SectionName2
);
566 if (OsIniSection
!= NULL
)
568 BOOLEAN UseExistingEntry
= TRUE
;
570 /* Check for boot type "Windows2003" */
571 Status
= IniCacheGetKey(OsIniSection
, L
"BootType", &KeyData
);
572 if (NT_SUCCESS(Status
))
574 if ((KeyData
== NULL
) ||
575 ( (_wcsicmp(KeyData
, L
"Windows2003") != 0) &&
576 (_wcsicmp(KeyData
, L
"\"Windows2003\"") != 0) ))
578 /* This is not a ReactOS entry */
579 UseExistingEntry
= FALSE
;
584 UseExistingEntry
= FALSE
;
587 if (UseExistingEntry
)
589 /* BootType is Windows2003. Now check SystemPath. */
590 Status
= IniCacheGetKey(OsIniSection
, L
"SystemPath", &KeyData
);
591 if (NT_SUCCESS(Status
))
593 swprintf(SystemPath
, L
"\"%s\"", ArcPath
);
594 if ((KeyData
== NULL
) ||
595 ( (_wcsicmp(KeyData
, ArcPath
) != 0) &&
596 (_wcsicmp(KeyData
, SystemPath
) != 0) ))
598 /* This entry is a ReactOS entry, but the SystemRoot
599 does not match the one we are looking for. */
600 UseExistingEntry
= FALSE
;
605 UseExistingEntry
= FALSE
;
609 if (UseExistingEntry
)
611 IniCacheDestroy(IniCache
);
612 return STATUS_SUCCESS
;
616 swprintf(SectionName
, L
"ReactOS_%lu", i
);
617 swprintf(OsName
, L
"\"ReactOS %lu\"", i
);
621 /* Create a new "ReactOS" entry */
622 CreateNTOSEntry(IniCache
, IniSection
,
624 L
"Windows2003", ArcPath
,
627 IniCacheSave(IniCache
, IniPath
);
628 IniCacheDestroy(IniCache
);
630 return STATUS_SUCCESS
;
634 IsThereAValidBootSector(PWSTR RootPath
)
637 * We first demand that the bootsector has a valid signature at its end.
638 * We then check the first 3 bytes (as a ULONG) of the bootsector for a
639 * potential "valid" instruction (the BIOS starts execution of the bootsector
640 * at its beginning). Currently this criterium is that this ULONG must be
641 * non-zero. If both these tests pass, then the bootsector is valid; otherwise
642 * it is invalid and certainly needs to be overwritten.
644 BOOLEAN IsValid
= FALSE
;
647 OBJECT_ATTRIBUTES ObjectAttributes
;
648 IO_STATUS_BLOCK IoStatusBlock
;
650 LARGE_INTEGER FileOffset
;
654 /* Allocate buffer for bootsector */
655 BootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
656 if (BootSector
== NULL
)
657 return FALSE
; // STATUS_INSUFFICIENT_RESOURCES;
659 /* Read current boot sector into buffer */
660 RtlInitUnicodeString(&Name
, RootPath
);
662 InitializeObjectAttributes(&ObjectAttributes
,
664 OBJ_CASE_INSENSITIVE
,
668 Status
= NtOpenFile(&FileHandle
,
669 GENERIC_READ
| SYNCHRONIZE
,
673 FILE_SYNCHRONOUS_IO_NONALERT
);
674 if (!NT_SUCCESS(Status
))
677 RtlZeroMemory(BootSector
, SECTORSIZE
);
679 FileOffset
.QuadPart
= 0ULL;
680 Status
= NtReadFile(FileHandle
,
690 if (!NT_SUCCESS(Status
))
693 /* Check the instruction; we use a ULONG to read three bytes */
694 Instruction
= (*(PULONG
)BootSector
) & 0x00FFFFFF;
695 IsValid
= (Instruction
!= 0x00000000);
697 /* Check the bootsector signature */
698 IsValid
&= (*(PUSHORT
)(BootSector
+ 0x1fe) == 0xaa55);
701 /* Free the boot sector */
702 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
703 return IsValid
; // Status;
714 OBJECT_ATTRIBUTES ObjectAttributes
;
715 IO_STATUS_BLOCK IoStatusBlock
;
717 LARGE_INTEGER FileOffset
;
720 /* Allocate buffer for bootsector */
721 BootSector
= RtlAllocateHeap(ProcessHeap
, 0, Length
);
722 if (BootSector
== NULL
)
723 return STATUS_INSUFFICIENT_RESOURCES
;
725 /* Read current boot sector into buffer */
726 RtlInitUnicodeString(&Name
, RootPath
);
728 InitializeObjectAttributes(&ObjectAttributes
,
730 OBJ_CASE_INSENSITIVE
,
734 Status
= NtOpenFile(&FileHandle
,
735 GENERIC_READ
| SYNCHRONIZE
,
739 FILE_SYNCHRONOUS_IO_NONALERT
);
740 if (!NT_SUCCESS(Status
))
742 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
746 FileOffset
.QuadPart
= 0ULL;
747 Status
= NtReadFile(FileHandle
,
757 if (!NT_SUCCESS(Status
))
759 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
763 /* Write bootsector to DstPath */
764 RtlInitUnicodeString(&Name
, DstPath
);
766 InitializeObjectAttributes(&ObjectAttributes
,
772 Status
= NtCreateFile(&FileHandle
,
773 GENERIC_WRITE
| SYNCHRONIZE
,
777 FILE_ATTRIBUTE_NORMAL
,
780 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
,
783 if (!NT_SUCCESS(Status
))
785 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
789 Status
= NtWriteFile(FileHandle
,
800 /* Free the boot sector */
801 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
808 InstallFat16BootCodeToFile(
815 OBJECT_ATTRIBUTES ObjectAttributes
;
816 IO_STATUS_BLOCK IoStatusBlock
;
818 LARGE_INTEGER FileOffset
;
819 PFAT_BOOTSECTOR OrigBootSector
;
820 PFAT_BOOTSECTOR NewBootSector
;
822 /* Allocate buffer for original bootsector */
823 OrigBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
824 if (OrigBootSector
== NULL
)
825 return STATUS_INSUFFICIENT_RESOURCES
;
827 /* Read current boot sector into buffer */
828 RtlInitUnicodeString(&Name
, RootPath
);
830 InitializeObjectAttributes(&ObjectAttributes
,
832 OBJ_CASE_INSENSITIVE
,
836 Status
= NtOpenFile(&FileHandle
,
837 GENERIC_READ
| SYNCHRONIZE
,
841 FILE_SYNCHRONOUS_IO_NONALERT
);
842 if (!NT_SUCCESS(Status
))
844 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
848 FileOffset
.QuadPart
= 0ULL;
849 Status
= NtReadFile(FileHandle
,
859 if (!NT_SUCCESS(Status
))
861 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
865 /* Allocate buffer for new bootsector */
866 NewBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
867 if (NewBootSector
== NULL
)
869 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
870 return STATUS_INSUFFICIENT_RESOURCES
;
873 /* Read new bootsector from SrcPath */
874 RtlInitUnicodeString(&Name
, SrcPath
);
876 InitializeObjectAttributes(&ObjectAttributes
,
878 OBJ_CASE_INSENSITIVE
,
882 Status
= NtOpenFile(&FileHandle
,
883 GENERIC_READ
| SYNCHRONIZE
,
887 FILE_SYNCHRONOUS_IO_NONALERT
);
888 if (!NT_SUCCESS(Status
))
890 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
891 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
895 FileOffset
.QuadPart
= 0ULL;
896 Status
= NtReadFile(FileHandle
,
906 if (!NT_SUCCESS(Status
))
908 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
909 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
913 /* Adjust bootsector (copy a part of the FAT BPB) */
914 memcpy(&NewBootSector
->OemName
,
915 &OrigBootSector
->OemName
,
916 FIELD_OFFSET(FAT_BOOTSECTOR
, BootCodeAndData
) -
917 FIELD_OFFSET(FAT_BOOTSECTOR
, OemName
));
919 /* Free the original boot sector */
920 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
922 /* Write new bootsector to DstPath */
923 RtlInitUnicodeString(&Name
, DstPath
);
925 InitializeObjectAttributes(&ObjectAttributes
,
931 Status
= NtCreateFile(&FileHandle
,
932 GENERIC_WRITE
| SYNCHRONIZE
,
936 FILE_ATTRIBUTE_NORMAL
,
939 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
,
942 if (!NT_SUCCESS(Status
))
944 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
948 Status
= NtWriteFile(FileHandle
,
959 /* Free the new boot sector */
960 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
967 InstallFat32BootCodeToFile(
974 OBJECT_ATTRIBUTES ObjectAttributes
;
975 IO_STATUS_BLOCK IoStatusBlock
;
977 LARGE_INTEGER FileOffset
;
978 PFAT32_BOOTSECTOR OrigBootSector
;
979 PFAT32_BOOTSECTOR NewBootSector
;
981 /* Allocate buffer for original bootsector */
982 OrigBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
983 if (OrigBootSector
== NULL
)
984 return STATUS_INSUFFICIENT_RESOURCES
;
986 /* Read current boot sector into buffer */
987 RtlInitUnicodeString(&Name
, RootPath
);
989 InitializeObjectAttributes(&ObjectAttributes
,
991 OBJ_CASE_INSENSITIVE
,
995 Status
= NtOpenFile(&FileHandle
,
996 GENERIC_READ
| SYNCHRONIZE
,
1000 FILE_SYNCHRONOUS_IO_NONALERT
);
1001 if (!NT_SUCCESS(Status
))
1003 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1007 Status
= NtReadFile(FileHandle
,
1016 NtClose(FileHandle
);
1017 if (!NT_SUCCESS(Status
))
1019 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1023 /* Allocate buffer for new bootsector (2 sectors) */
1024 NewBootSector
= RtlAllocateHeap(ProcessHeap
, 0, 2 * SECTORSIZE
);
1025 if (NewBootSector
== NULL
)
1027 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1028 return STATUS_INSUFFICIENT_RESOURCES
;
1031 /* Read new bootsector from SrcPath */
1032 RtlInitUnicodeString(&Name
, SrcPath
);
1034 InitializeObjectAttributes(&ObjectAttributes
,
1036 OBJ_CASE_INSENSITIVE
,
1040 Status
= NtOpenFile(&FileHandle
,
1041 GENERIC_READ
| SYNCHRONIZE
,
1045 FILE_SYNCHRONOUS_IO_NONALERT
);
1046 if (!NT_SUCCESS(Status
))
1048 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1049 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1053 Status
= NtReadFile(FileHandle
,
1062 NtClose(FileHandle
);
1063 if (!NT_SUCCESS(Status
))
1065 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1066 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1070 /* Adjust bootsector (copy a part of the FAT32 BPB) */
1071 memcpy(&NewBootSector
->OemName
,
1072 &OrigBootSector
->OemName
,
1073 FIELD_OFFSET(FAT32_BOOTSECTOR
, BootCodeAndData
) -
1074 FIELD_OFFSET(FAT32_BOOTSECTOR
, OemName
));
1076 /* Disable the backup boot sector */
1077 NewBootSector
->BackupBootSector
= 0;
1079 /* Free the original boot sector */
1080 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1082 /* Write the first sector of the new bootcode to DstPath */
1083 RtlInitUnicodeString(&Name
, DstPath
);
1085 InitializeObjectAttributes(&ObjectAttributes
,
1091 Status
= NtCreateFile(&FileHandle
,
1092 GENERIC_WRITE
| SYNCHRONIZE
,
1096 FILE_ATTRIBUTE_NORMAL
,
1099 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
,
1102 if (!NT_SUCCESS(Status
))
1104 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1108 Status
= NtWriteFile(FileHandle
,
1117 NtClose(FileHandle
);
1118 if (!NT_SUCCESS(Status
))
1120 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1124 /* Write the second sector of the new bootcode to boot disk sector 14 */
1125 RtlInitUnicodeString(&Name
, RootPath
);
1127 InitializeObjectAttributes(&ObjectAttributes
,
1133 Status
= NtOpenFile(&FileHandle
,
1134 GENERIC_WRITE
| SYNCHRONIZE
,
1138 FILE_SYNCHRONOUS_IO_NONALERT
);
1139 if (!NT_SUCCESS(Status
))
1141 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1145 FileOffset
.QuadPart
= (ULONGLONG
)(14 * SECTORSIZE
);
1146 Status
= NtWriteFile(FileHandle
,
1151 ((PUCHAR
)NewBootSector
+ SECTORSIZE
),
1155 if (!NT_SUCCESS(Status
))
1158 NtClose(FileHandle
);
1160 /* Free the new boot sector */
1161 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1168 InstallMbrBootCodeToDisk(
1173 UNICODE_STRING Name
;
1174 OBJECT_ATTRIBUTES ObjectAttributes
;
1175 IO_STATUS_BLOCK IoStatusBlock
;
1177 LARGE_INTEGER FileOffset
;
1178 PPARTITION_SECTOR OrigBootSector
;
1179 PPARTITION_SECTOR NewBootSector
;
1181 /* Allocate buffer for original bootsector */
1182 OrigBootSector
= (PPARTITION_SECTOR
)RtlAllocateHeap(ProcessHeap
,
1184 sizeof(PARTITION_SECTOR
));
1185 if (OrigBootSector
== NULL
)
1186 return STATUS_INSUFFICIENT_RESOURCES
;
1188 /* Read current boot sector into buffer */
1189 RtlInitUnicodeString(&Name
,
1192 InitializeObjectAttributes(&ObjectAttributes
,
1194 OBJ_CASE_INSENSITIVE
,
1198 Status
= NtOpenFile(&FileHandle
,
1199 GENERIC_READ
| SYNCHRONIZE
,
1203 FILE_SYNCHRONOUS_IO_NONALERT
);
1204 if (!NT_SUCCESS(Status
))
1206 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1210 FileOffset
.QuadPart
= 0ULL;
1211 Status
= NtReadFile(FileHandle
,
1217 sizeof(PARTITION_SECTOR
),
1220 NtClose(FileHandle
);
1221 if (!NT_SUCCESS(Status
))
1223 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1227 /* Allocate buffer for new bootsector */
1228 NewBootSector
= (PPARTITION_SECTOR
)RtlAllocateHeap(ProcessHeap
,
1230 sizeof(PARTITION_SECTOR
));
1231 if (NewBootSector
== NULL
)
1233 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1234 return STATUS_INSUFFICIENT_RESOURCES
;
1237 /* Read new bootsector from SrcPath */
1238 RtlInitUnicodeString(&Name
, SrcPath
);
1240 InitializeObjectAttributes(&ObjectAttributes
,
1242 OBJ_CASE_INSENSITIVE
,
1246 Status
= NtOpenFile(&FileHandle
,
1247 GENERIC_READ
| SYNCHRONIZE
,
1251 FILE_SYNCHRONOUS_IO_NONALERT
);
1252 if (!NT_SUCCESS(Status
))
1254 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1255 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1259 Status
= NtReadFile(FileHandle
,
1265 sizeof(PARTITION_SECTOR
),
1268 NtClose(FileHandle
);
1269 if (!NT_SUCCESS(Status
))
1271 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1272 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1277 * Copy the disk signature, the reserved fields and
1278 * the partition table from the old MBR to the new one.
1280 RtlCopyMemory(&NewBootSector
->Signature
,
1281 &OrigBootSector
->Signature
,
1282 sizeof(PARTITION_SECTOR
) - offsetof(PARTITION_SECTOR
, Signature
) /* Length of partition table */);
1284 /* Free the original boot sector */
1285 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1287 /* Write new bootsector to RootPath */
1288 RtlInitUnicodeString(&Name
, RootPath
);
1290 InitializeObjectAttributes(&ObjectAttributes
,
1296 Status
= NtOpenFile(&FileHandle
,
1297 GENERIC_WRITE
| SYNCHRONIZE
,
1301 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1302 if (!NT_SUCCESS(Status
))
1304 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1305 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1309 FileOffset
.QuadPart
= 0ULL;
1310 Status
= NtWriteFile(FileHandle
,
1316 sizeof(PARTITION_SECTOR
),
1319 NtClose(FileHandle
);
1321 /* Free the new boot sector */
1322 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1329 InstallFat12BootCodeToFloppy(
1334 UNICODE_STRING Name
;
1335 OBJECT_ATTRIBUTES ObjectAttributes
;
1336 IO_STATUS_BLOCK IoStatusBlock
;
1338 LARGE_INTEGER FileOffset
;
1339 PFAT_BOOTSECTOR OrigBootSector
;
1340 PFAT_BOOTSECTOR NewBootSector
;
1342 /* Allocate buffer for original bootsector */
1343 OrigBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
1344 if (OrigBootSector
== NULL
)
1345 return STATUS_INSUFFICIENT_RESOURCES
;
1347 /* Read current boot sector into buffer */
1348 RtlInitUnicodeString(&Name
, RootPath
);
1350 InitializeObjectAttributes(&ObjectAttributes
,
1352 OBJ_CASE_INSENSITIVE
,
1356 Status
= NtOpenFile(&FileHandle
,
1357 GENERIC_READ
| SYNCHRONIZE
,
1361 FILE_SYNCHRONOUS_IO_NONALERT
);
1362 if (!NT_SUCCESS(Status
))
1364 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1368 FileOffset
.QuadPart
= 0ULL;
1369 Status
= NtReadFile(FileHandle
,
1378 NtClose(FileHandle
);
1379 if (!NT_SUCCESS(Status
))
1381 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1385 /* Allocate buffer for new bootsector */
1386 NewBootSector
= RtlAllocateHeap(ProcessHeap
,
1389 if (NewBootSector
== NULL
)
1391 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1392 return STATUS_INSUFFICIENT_RESOURCES
;
1395 /* Read new bootsector from SrcPath */
1396 RtlInitUnicodeString(&Name
, SrcPath
);
1398 InitializeObjectAttributes(&ObjectAttributes
,
1400 OBJ_CASE_INSENSITIVE
,
1404 Status
= NtOpenFile(&FileHandle
,
1405 GENERIC_READ
| SYNCHRONIZE
,
1409 FILE_SYNCHRONOUS_IO_NONALERT
);
1410 if (!NT_SUCCESS(Status
))
1412 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1413 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1417 Status
= NtReadFile(FileHandle
,
1426 NtClose(FileHandle
);
1427 if (!NT_SUCCESS(Status
))
1429 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1430 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1434 /* Adjust bootsector (copy a part of the FAT16 BPB) */
1435 memcpy(&NewBootSector
->OemName
,
1436 &OrigBootSector
->OemName
,
1437 FIELD_OFFSET(FAT_BOOTSECTOR
, BootCodeAndData
) -
1438 FIELD_OFFSET(FAT_BOOTSECTOR
, OemName
));
1440 /* Free the original boot sector */
1441 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1443 /* Write new bootsector to RootPath */
1444 RtlInitUnicodeString(&Name
, RootPath
);
1446 InitializeObjectAttributes(&ObjectAttributes
,
1452 Status
= NtOpenFile(&FileHandle
,
1453 GENERIC_WRITE
| SYNCHRONIZE
,
1457 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1458 if (!NT_SUCCESS(Status
))
1460 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1461 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1465 FileOffset
.QuadPart
= 0ULL;
1466 Status
= NtWriteFile(FileHandle
,
1475 NtClose(FileHandle
);
1477 /* Free the new boot sector */
1478 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1485 InstallFat16BootCodeToDisk(
1490 UNICODE_STRING Name
;
1491 OBJECT_ATTRIBUTES ObjectAttributes
;
1492 IO_STATUS_BLOCK IoStatusBlock
;
1494 LARGE_INTEGER FileOffset
;
1495 PFAT_BOOTSECTOR OrigBootSector
;
1496 PFAT_BOOTSECTOR NewBootSector
;
1498 /* Allocate buffer for original bootsector */
1499 OrigBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
1500 if (OrigBootSector
== NULL
)
1501 return STATUS_INSUFFICIENT_RESOURCES
;
1503 /* Read current boot sector into buffer */
1504 RtlInitUnicodeString(&Name
, RootPath
);
1506 InitializeObjectAttributes(&ObjectAttributes
,
1508 OBJ_CASE_INSENSITIVE
,
1512 Status
= NtOpenFile(&FileHandle
,
1513 GENERIC_READ
| SYNCHRONIZE
,
1517 FILE_SYNCHRONOUS_IO_NONALERT
);
1518 if (!NT_SUCCESS(Status
))
1520 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1524 FileOffset
.QuadPart
= 0ULL;
1525 Status
= NtReadFile(FileHandle
,
1534 NtClose(FileHandle
);
1535 if (!NT_SUCCESS(Status
))
1537 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1541 /* Allocate buffer for new bootsector */
1542 NewBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
1543 if (NewBootSector
== NULL
)
1545 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1546 return STATUS_INSUFFICIENT_RESOURCES
;
1549 /* Read new bootsector from SrcPath */
1550 RtlInitUnicodeString(&Name
, SrcPath
);
1552 InitializeObjectAttributes(&ObjectAttributes
,
1554 OBJ_CASE_INSENSITIVE
,
1558 Status
= NtOpenFile(&FileHandle
,
1559 GENERIC_READ
| SYNCHRONIZE
,
1563 FILE_SYNCHRONOUS_IO_NONALERT
);
1564 if (!NT_SUCCESS(Status
))
1566 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1567 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1571 Status
= NtReadFile(FileHandle
,
1580 NtClose(FileHandle
);
1581 if (!NT_SUCCESS(Status
))
1583 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1584 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1588 /* Adjust bootsector (copy a part of the FAT16 BPB) */
1589 memcpy(&NewBootSector
->OemName
,
1590 &OrigBootSector
->OemName
,
1591 FIELD_OFFSET(FAT_BOOTSECTOR
, BootCodeAndData
) -
1592 FIELD_OFFSET(FAT_BOOTSECTOR
, OemName
));
1594 /* Free the original boot sector */
1595 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1597 /* Write new bootsector to RootPath */
1598 RtlInitUnicodeString(&Name
, RootPath
);
1600 InitializeObjectAttributes(&ObjectAttributes
,
1606 Status
= NtOpenFile(&FileHandle
,
1607 GENERIC_WRITE
| SYNCHRONIZE
,
1611 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1612 if (!NT_SUCCESS(Status
))
1614 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1615 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1619 FileOffset
.QuadPart
= 0ULL;
1620 Status
= NtWriteFile(FileHandle
,
1629 NtClose(FileHandle
);
1631 /* Free the new boot sector */
1632 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1639 InstallFat32BootCodeToDisk(
1644 UNICODE_STRING Name
;
1645 OBJECT_ATTRIBUTES ObjectAttributes
;
1646 IO_STATUS_BLOCK IoStatusBlock
;
1648 LARGE_INTEGER FileOffset
;
1649 PFAT32_BOOTSECTOR OrigBootSector
;
1650 PFAT32_BOOTSECTOR NewBootSector
;
1651 USHORT BackupBootSector
;
1653 /* Allocate buffer for original bootsector */
1654 OrigBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
1655 if (OrigBootSector
== NULL
)
1656 return STATUS_INSUFFICIENT_RESOURCES
;
1658 /* Read current boot sector into buffer */
1659 RtlInitUnicodeString(&Name
, RootPath
);
1661 InitializeObjectAttributes(&ObjectAttributes
,
1663 OBJ_CASE_INSENSITIVE
,
1667 Status
= NtOpenFile(&FileHandle
,
1668 GENERIC_READ
| SYNCHRONIZE
,
1672 FILE_SYNCHRONOUS_IO_NONALERT
);
1673 if (!NT_SUCCESS(Status
))
1675 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1679 FileOffset
.QuadPart
= 0ULL;
1680 Status
= NtReadFile(FileHandle
,
1689 NtClose(FileHandle
);
1690 if (!NT_SUCCESS(Status
))
1692 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1697 /* Allocate buffer for new bootsector (2 sectors) */
1698 NewBootSector
= RtlAllocateHeap(ProcessHeap
, 0, 2 * SECTORSIZE
);
1699 if (NewBootSector
== NULL
)
1701 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1702 return STATUS_INSUFFICIENT_RESOURCES
;
1705 /* Read new bootsector from SrcPath */
1706 RtlInitUnicodeString(&Name
, SrcPath
);
1708 InitializeObjectAttributes(&ObjectAttributes
,
1710 OBJ_CASE_INSENSITIVE
,
1714 Status
= NtOpenFile(&FileHandle
,
1715 GENERIC_READ
| SYNCHRONIZE
,
1719 FILE_SYNCHRONOUS_IO_NONALERT
);
1720 if (!NT_SUCCESS(Status
))
1722 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1723 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1727 Status
= NtReadFile(FileHandle
,
1736 NtClose(FileHandle
);
1737 if (!NT_SUCCESS(Status
))
1739 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1740 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1744 /* Adjust bootsector (copy a part of the FAT32 BPB) */
1745 memcpy(&NewBootSector
->OemName
,
1746 &OrigBootSector
->OemName
,
1747 FIELD_OFFSET(FAT32_BOOTSECTOR
, BootCodeAndData
) -
1748 FIELD_OFFSET(FAT32_BOOTSECTOR
, OemName
));
1750 /* Get the location of the backup boot sector */
1751 BackupBootSector
= OrigBootSector
->BackupBootSector
;
1753 /* Free the original boot sector */
1754 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1756 /* Write the first sector of the new bootcode to DstPath */
1757 RtlInitUnicodeString(&Name
, RootPath
);
1759 InitializeObjectAttributes(&ObjectAttributes
,
1765 Status
= NtOpenFile(&FileHandle
,
1766 GENERIC_WRITE
| SYNCHRONIZE
,
1770 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1771 if (!NT_SUCCESS(Status
))
1773 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1774 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1778 /* Write sector 0 */
1779 FileOffset
.QuadPart
= 0ULL;
1780 Status
= NtWriteFile(FileHandle
,
1789 if (!NT_SUCCESS(Status
))
1791 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1792 NtClose(FileHandle
);
1793 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1797 /* Write backup boot sector */
1798 if ((BackupBootSector
!= 0x0000) && (BackupBootSector
!= 0xFFFF))
1800 FileOffset
.QuadPart
= (ULONGLONG
)((ULONG
)BackupBootSector
* SECTORSIZE
);
1801 Status
= NtWriteFile(FileHandle
,
1810 if (!NT_SUCCESS(Status
))
1812 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1813 NtClose(FileHandle
);
1814 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1819 /* Write sector 14 */
1820 FileOffset
.QuadPart
= 14 * SECTORSIZE
;
1821 Status
= NtWriteFile(FileHandle
,
1826 ((PUCHAR
)NewBootSector
+ SECTORSIZE
),
1830 if (!NT_SUCCESS(Status
))
1832 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1834 NtClose(FileHandle
);
1836 /* Free the new boot sector */
1837 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1844 InstallBtrfsBootCodeToDisk(
1849 UNICODE_STRING Name
;
1850 OBJECT_ATTRIBUTES ObjectAttributes
;
1851 IO_STATUS_BLOCK IoStatusBlock
;
1853 LARGE_INTEGER FileOffset
;
1854 // PEXT2_BOOTSECTOR OrigBootSector;
1855 PBTRFS_BOOTSECTOR NewBootSector
;
1856 // USHORT BackupBootSector;
1857 PARTITION_INFORMATION_EX PartInfo
;
1860 /* Allocate buffer for original bootsector */
1861 OrigBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
1862 if (OrigBootSector
== NULL
)
1863 return STATUS_INSUFFICIENT_RESOURCES
;
1865 /* Read current boot sector into buffer */
1866 RtlInitUnicodeString(&Name
, RootPath
);
1868 InitializeObjectAttributes(&ObjectAttributes
,
1870 OBJ_CASE_INSENSITIVE
,
1874 Status
= NtOpenFile(&FileHandle
,
1875 GENERIC_READ
| SYNCHRONIZE
,
1879 FILE_SYNCHRONOUS_IO_NONALERT
);
1880 if (!NT_SUCCESS(Status
))
1882 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1886 FileOffset
.QuadPart
= 0ULL;
1887 Status
= NtReadFile(FileHandle
,
1896 NtClose(FileHandle
);
1897 if (!NT_SUCCESS(Status
))
1899 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1904 /* Allocate buffer for new bootsector */
1905 NewBootSector
= RtlAllocateHeap(ProcessHeap
, 0, sizeof(BTRFS_BOOTSECTOR
));
1906 if (NewBootSector
== NULL
)
1908 // RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1909 return STATUS_INSUFFICIENT_RESOURCES
;
1912 /* Read new bootsector from SrcPath */
1913 RtlInitUnicodeString(&Name
, SrcPath
);
1915 InitializeObjectAttributes(&ObjectAttributes
,
1917 OBJ_CASE_INSENSITIVE
,
1921 Status
= NtOpenFile(&FileHandle
,
1922 GENERIC_READ
| SYNCHRONIZE
,
1926 FILE_SYNCHRONOUS_IO_NONALERT
);
1927 if (!NT_SUCCESS(Status
))
1929 // RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1930 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1934 Status
= NtReadFile(FileHandle
,
1940 sizeof(BTRFS_BOOTSECTOR
),
1943 NtClose(FileHandle
);
1944 if (!NT_SUCCESS(Status
))
1946 // RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1947 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1952 /* Adjust bootsector (copy a part of the FAT32 BPB) */
1953 memcpy(&NewBootSector
->OemName
,
1954 &OrigBootSector
->OemName
,
1955 FIELD_OFFSET(FAT32_BOOTSECTOR
, BootCodeAndData
) -
1956 FIELD_OFFSET(FAT32_BOOTSECTOR
, OemName
));
1958 NewBootSector
->HiddenSectors
= PartitionList
->CurrentDisk
->SectorsPerTrack
;
1960 /* Get the location of the backup boot sector */
1961 BackupBootSector
= OrigBootSector
->BackupBootSector
;
1963 /* Free the original boot sector */
1964 // RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1967 /* Write new bootsector to RootPath */
1968 RtlInitUnicodeString(&Name
, RootPath
);
1970 InitializeObjectAttributes(&ObjectAttributes
,
1976 Status
= NtOpenFile(&FileHandle
,
1977 GENERIC_WRITE
| SYNCHRONIZE
,
1981 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1982 if (!NT_SUCCESS(Status
))
1984 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1985 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1989 /* Obtaining partition info and writing it to bootsector */
1990 Status
= NtDeviceIoControlFile(FileHandle
,
1995 IOCTL_DISK_GET_PARTITION_INFO_EX
,
2001 if (!NT_SUCCESS(Status
))
2003 DPRINT1("IOCTL_DISK_GET_PARTITION_INFO_EX failed (Status %lx)\n", Status
);
2004 NtClose(FileHandle
);
2005 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
2009 NewBootSector
->PartitionStartLBA
= PartInfo
.StartingOffset
.QuadPart
/ SECTORSIZE
;
2011 /* Write sector 0 */
2012 FileOffset
.QuadPart
= 0ULL;
2013 Status
= NtWriteFile(FileHandle
,
2019 sizeof(BTRFS_BOOTSECTOR
),
2023 if (!NT_SUCCESS(Status
))
2025 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
2026 NtClose(FileHandle
);
2027 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
2031 /* Write backup boot sector */
2032 if ((BackupBootSector
!= 0x0000) && (BackupBootSector
!= 0xFFFF))
2034 FileOffset
.QuadPart
= (ULONGLONG
)((ULONG
)BackupBootSector
* SECTORSIZE
);
2035 Status
= NtWriteFile(FileHandle
,
2044 if (!NT_SUCCESS(Status
))
2046 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
2047 NtClose(FileHandle
);
2048 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
2053 /* Write sector 14 */
2054 FileOffset
.QuadPart
= 14 * SECTORSIZE
;
2055 Status
= NtWriteFile(FileHandle
,
2060 ((PUCHAR
)NewBootSector
+ SECTORSIZE
),
2064 if (!NT_SUCCESS(Status
))
2066 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
2069 NtClose(FileHandle
);
2071 /* Free the new boot sector */
2072 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
2084 UNICODE_STRING Name
;
2085 OBJECT_ATTRIBUTES ObjectAttributes
;
2086 IO_STATUS_BLOCK IoStatusBlock
;
2087 FILE_BASIC_INFORMATION FileInfo
;
2090 RtlInitUnicodeString(&Name
, FileName
);
2092 InitializeObjectAttributes(&ObjectAttributes
,
2094 OBJ_CASE_INSENSITIVE
,
2098 Status
= NtOpenFile(&FileHandle
,
2099 GENERIC_READ
| GENERIC_WRITE
| SYNCHRONIZE
,
2103 FILE_SYNCHRONOUS_IO_NONALERT
);
2104 if (Status
== STATUS_NO_SUCH_FILE
)
2106 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
2108 return STATUS_SUCCESS
;
2110 if (!NT_SUCCESS(Status
))
2112 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
2116 Status
= NtQueryInformationFile(FileHandle
,
2119 sizeof(FILE_BASIC_INFORMATION
),
2120 FileBasicInformation
);
2121 if (!NT_SUCCESS(Status
))
2123 DPRINT1("NtQueryInformationFile() failed (Status %lx)\n", Status
);
2124 NtClose(FileHandle
);
2128 *Attributes
= FileInfo
.FileAttributes
;
2130 /* Delete attributes SYSTEM, HIDDEN and READONLY */
2131 FileInfo
.FileAttributes
= FileInfo
.FileAttributes
&
2132 ~(FILE_ATTRIBUTE_SYSTEM
|
2133 FILE_ATTRIBUTE_HIDDEN
|
2134 FILE_ATTRIBUTE_READONLY
);
2136 Status
= NtSetInformationFile(FileHandle
,
2139 sizeof(FILE_BASIC_INFORMATION
),
2140 FileBasicInformation
);
2141 if (!NT_SUCCESS(Status
))
2143 DPRINT1("NtSetInformationFile() failed (Status %lx)\n", Status
);
2146 NtClose(FileHandle
);
2157 UNICODE_STRING Name
;
2158 OBJECT_ATTRIBUTES ObjectAttributes
;
2159 IO_STATUS_BLOCK IoStatusBlock
;
2160 FILE_BASIC_INFORMATION FileInfo
;
2163 RtlInitUnicodeString(&Name
, FileName
);
2165 InitializeObjectAttributes(&ObjectAttributes
,
2167 OBJ_CASE_INSENSITIVE
,
2171 Status
= NtOpenFile(&FileHandle
,
2172 GENERIC_READ
| GENERIC_WRITE
| SYNCHRONIZE
,
2176 FILE_SYNCHRONOUS_IO_NONALERT
);
2177 if (!NT_SUCCESS(Status
))
2179 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
2183 Status
= NtQueryInformationFile(FileHandle
,
2186 sizeof(FILE_BASIC_INFORMATION
),
2187 FileBasicInformation
);
2188 if (!NT_SUCCESS(Status
))
2190 DPRINT1("NtQueryInformationFile() failed (Status %lx)\n", Status
);
2191 NtClose(FileHandle
);
2195 FileInfo
.FileAttributes
= FileInfo
.FileAttributes
| Attributes
;
2197 Status
= NtSetInformationFile(FileHandle
,
2200 sizeof(FILE_BASIC_INFORMATION
),
2201 FileBasicInformation
);
2202 if (!NT_SUCCESS(Status
))
2204 DPRINT1("NtSetInformationFile() failed (Status %lx)\n", Status
);
2207 NtClose(FileHandle
);
2219 PINICACHE Cache
= NULL
;
2220 PINICACHESECTION Section
= NULL
;
2221 ULONG FileAttribute
;
2222 PWCHAR OldValue
= NULL
;
2224 Status
= IniCacheLoad(&Cache
, BootIniPath
, FALSE
);
2225 if (!NT_SUCCESS(Status
))
2230 Section
= IniCacheGetSection(Cache
,
2231 L
"operating systems");
2232 if (Section
== NULL
)
2234 IniCacheDestroy(Cache
);
2235 return STATUS_UNSUCCESSFUL
;
2238 /* Check - maybe record already exists */
2239 Status
= IniCacheGetKey(Section
, EntryName
, &OldValue
);
2241 /* If either key was not found, or contains something else - add new one */
2242 if (!NT_SUCCESS(Status
) || wcscmp(OldValue
, EntryValue
))
2244 IniCacheInsertKey(Section
,
2251 Status
= UnprotectBootIni(BootIniPath
,
2253 if (!NT_SUCCESS(Status
))
2255 IniCacheDestroy(Cache
);
2259 Status
= IniCacheSave(Cache
, BootIniPath
);
2260 if (!NT_SUCCESS(Status
))
2262 IniCacheDestroy(Cache
);
2266 FileAttribute
|= (FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
| FILE_ATTRIBUTE_READONLY
);
2267 Status
= ProtectBootIni(BootIniPath
, FileAttribute
);
2269 IniCacheDestroy(Cache
);
2276 InstallFatBootcodeToPartition(
2277 PUNICODE_STRING SystemRootPath
,
2278 PUNICODE_STRING SourceRootPath
,
2279 PUNICODE_STRING DestinationArcPath
,
2280 UCHAR PartitionType
)
2283 BOOLEAN DoesFreeLdrExist
;
2284 WCHAR SrcPath
[MAX_PATH
];
2285 WCHAR DstPath
[MAX_PATH
];
2287 /* FAT or FAT32 partition */
2288 DPRINT("System path: '%wZ'\n", SystemRootPath
);
2290 /* Copy FreeLoader to the system partition, always overwriting the older version */
2291 CombinePaths(SrcPath
, ARRAYSIZE(SrcPath
), 2, SourceRootPath
->Buffer
, L
"\\loader\\freeldr.sys");
2292 CombinePaths(DstPath
, ARRAYSIZE(DstPath
), 2, SystemRootPath
->Buffer
, L
"freeldr.sys");
2294 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2295 Status
= SetupCopyFile(SrcPath
, DstPath
);
2296 if (!NT_SUCCESS(Status
))
2298 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
2302 /* Prepare for possibly updating 'freeldr.ini' */
2303 CombinePaths(DstPath
, ARRAYSIZE(DstPath
), 2, SystemRootPath
->Buffer
, L
"freeldr.ini");
2305 DoesFreeLdrExist
= DoesFileExist(NULL
, DstPath
);
2306 if (DoesFreeLdrExist
)
2308 /* Update existing 'freeldr.ini' */
2309 DPRINT1("Update existing 'freeldr.ini'\n");
2311 Status
= UpdateFreeLoaderIni(DstPath
, DestinationArcPath
->Buffer
);
2312 if (!NT_SUCCESS(Status
))
2314 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
2319 /* Check for NT and other bootloaders */
2321 // FIXME: Check for Vista+ bootloader!
2322 /*** Status = FindNTOSBootLoader(PartitionHandle, NtLdr, &Version); ***/
2323 /*** Status = FindNTOSBootLoader(PartitionHandle, BootMgr, &Version); ***/
2324 if (DoesFileExist_2(SystemRootPath
->Buffer
, L
"NTLDR") == TRUE
||
2325 DoesFileExist_2(SystemRootPath
->Buffer
, L
"BOOT.INI") == TRUE
)
2327 /* Search root directory for 'NTLDR' and 'BOOT.INI' */
2328 DPRINT1("Found Microsoft Windows NT/2000/XP boot loader\n");
2330 /* Create or update 'freeldr.ini' */
2331 if (DoesFreeLdrExist
== FALSE
)
2333 /* Create new 'freeldr.ini' */
2334 DPRINT1("Create new 'freeldr.ini'\n");
2335 // CombinePaths(DstPath, ARRAYSIZE(DstPath), 2, SystemRootPath->Buffer, L"freeldr.ini");
2337 Status
= CreateFreeLoaderIniForReactOS(DstPath
, DestinationArcPath
->Buffer
);
2338 if (!NT_SUCCESS(Status
))
2340 DPRINT1("CreateFreeLoaderIniForReactOS() failed (Status %lx)\n", Status
);
2344 /* Install new bootcode into a file */
2345 CombinePaths(DstPath
, ARRAYSIZE(DstPath
), 2, SystemRootPath
->Buffer
, L
"bootsect.ros");
2347 if (PartitionType
== PARTITION_FAT32
||
2348 PartitionType
== PARTITION_FAT32_XINT13
)
2350 /* Install FAT32 bootcode */
2351 CombinePaths(SrcPath
, ARRAYSIZE(SrcPath
), 2, SourceRootPath
->Buffer
, L
"\\loader\\fat32.bin");
2353 DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, DstPath
);
2354 Status
= InstallFat32BootCodeToFile(SrcPath
, DstPath
,
2355 SystemRootPath
->Buffer
);
2356 if (!NT_SUCCESS(Status
))
2358 DPRINT1("InstallFat32BootCodeToFile() failed (Status %lx)\n", Status
);
2364 /* Install FAT16 bootcode */
2365 CombinePaths(SrcPath
, ARRAYSIZE(SrcPath
), 2, SourceRootPath
->Buffer
, L
"\\loader\\fat.bin");
2367 DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath
, DstPath
);
2368 Status
= InstallFat16BootCodeToFile(SrcPath
, DstPath
,
2369 SystemRootPath
->Buffer
);
2370 if (!NT_SUCCESS(Status
))
2372 DPRINT1("InstallFat16BootCodeToFile() failed (Status %lx)\n", Status
);
2378 /* Update 'boot.ini' */
2379 CombinePaths(DstPath
, ARRAYSIZE(DstPath
), 2, SystemRootPath
->Buffer
, L
"boot.ini");
2381 DPRINT1("Update 'boot.ini': %S\n", DstPath
);
2382 Status
= UpdateBootIni(DstPath
,
2383 L
"C:\\bootsect.ros",
2385 if (!NT_SUCCESS(Status
))
2387 DPRINT1("UpdateBootIni() failed (Status %lx)\n", Status
);
2393 /* Non-NT bootloaders: install our own bootloader */
2398 PCWSTR BootPartition
;
2401 /* Search for COMPAQ MS-DOS 1.x (1.11, 1.12, based on MS-DOS 1.25) boot loader */
2402 if (DoesFileExist_2(SystemRootPath
->Buffer
, L
"IOSYS.COM") == TRUE
||
2403 DoesFileExist_2(SystemRootPath
->Buffer
, L
"MSDOS.COM") == TRUE
)
2405 DPRINT1("Found COMPAQ MS-DOS 1.x (1.11, 1.12) / MS-DOS 1.25 boot loader\n");
2408 Description
= L
"\"COMPAQ MS-DOS 1.x / MS-DOS 1.25\"";
2410 BootPartition
= L
"1";
2411 BootSector
= L
"BOOTSECT.DOS";
2414 /* Search for Microsoft DOS or Windows 9x boot loader */
2415 if (DoesFileExist_2(SystemRootPath
->Buffer
, L
"IO.SYS") == TRUE
||
2416 DoesFileExist_2(SystemRootPath
->Buffer
, L
"MSDOS.SYS") == TRUE
)
2419 DPRINT1("Found Microsoft DOS or Windows 9x boot loader\n");
2422 Description
= L
"\"MS-DOS/Windows\"";
2424 BootPartition
= L
"1";
2425 BootSector
= L
"BOOTSECT.DOS";
2428 /* Search for IBM PC-DOS or DR-DOS 5.x boot loader */
2429 if (DoesFileExist_2(SystemRootPath
->Buffer
, L
"IBMIO.COM" ) == TRUE
|| // Some people refer to this file instead of IBMBIO.COM...
2430 DoesFileExist_2(SystemRootPath
->Buffer
, L
"IBMBIO.COM") == TRUE
||
2431 DoesFileExist_2(SystemRootPath
->Buffer
, L
"IBMDOS.COM") == TRUE
)
2433 DPRINT1("Found IBM PC-DOS or DR-DOS 5.x or IBM OS/2 1.0\n");
2436 Description
= L
"\"IBM PC-DOS or DR-DOS 5.x or IBM OS/2 1.0\"";
2438 BootPartition
= L
"1";
2439 BootSector
= L
"BOOTSECT.DOS";
2442 /* Search for DR-DOS 3.x boot loader */
2443 if (DoesFileExist_2(SystemRootPath
->Buffer
, L
"DRBIOS.SYS") == TRUE
||
2444 DoesFileExist_2(SystemRootPath
->Buffer
, L
"DRBDOS.SYS") == TRUE
)
2446 DPRINT1("Found DR-DOS 3.x\n");
2449 Description
= L
"\"DR-DOS 3.x\"";
2451 BootPartition
= L
"1";
2452 BootSector
= L
"BOOTSECT.DOS";
2455 /* Search for MS OS/2 1.x */
2456 if (DoesFileExist_2(SystemRootPath
->Buffer
, L
"OS2BOOT.COM") == TRUE
||
2457 DoesFileExist_2(SystemRootPath
->Buffer
, L
"OS2BIO.COM" ) == TRUE
||
2458 DoesFileExist_2(SystemRootPath
->Buffer
, L
"OS2DOS.COM" ) == TRUE
)
2460 DPRINT1("Found MS OS/2 1.x\n");
2463 Description
= L
"\"MS OS/2 1.x\"";
2465 BootPartition
= L
"1";
2466 BootSector
= L
"BOOTSECT.OS2";
2469 /* Search for MS or IBM OS/2 */
2470 if (DoesFileExist_2(SystemRootPath
->Buffer
, L
"OS2BOOT") == TRUE
||
2471 DoesFileExist_2(SystemRootPath
->Buffer
, L
"OS2LDR" ) == TRUE
||
2472 DoesFileExist_2(SystemRootPath
->Buffer
, L
"OS2KRNL") == TRUE
)
2474 DPRINT1("Found MS/IBM OS/2\n");
2477 Description
= L
"\"MS/IBM OS/2\"";
2479 BootPartition
= L
"1";
2480 BootSector
= L
"BOOTSECT.OS2";
2483 /* Search for FreeDOS boot loader */
2484 if (DoesFileExist_2(SystemRootPath
->Buffer
, L
"kernel.sys") == TRUE
)
2486 DPRINT1("Found FreeDOS boot loader\n");
2489 Description
= L
"\"FreeDOS\"";
2491 BootPartition
= L
"1";
2492 BootSector
= L
"BOOTSECT.DOS";
2496 /* No or unknown boot loader */
2497 DPRINT1("No or unknown boot loader found\n");
2499 Section
= L
"Unknown";
2500 Description
= L
"\"Unknown Operating System\"";
2502 BootPartition
= L
"1";
2503 BootSector
= L
"BOOTSECT.OLD";
2506 /* Create or update 'freeldr.ini' */
2507 if (DoesFreeLdrExist
== FALSE
)
2509 /* Create new 'freeldr.ini' */
2510 DPRINT1("Create new 'freeldr.ini'\n");
2511 // CombinePaths(DstPath, ARRAYSIZE(DstPath), 2, SystemRootPath->Buffer, L"freeldr.ini");
2513 if (IsThereAValidBootSector(SystemRootPath
->Buffer
))
2515 Status
= CreateFreeLoaderIniForReactOSAndBootSector(
2516 DstPath
, DestinationArcPath
->Buffer
,
2517 Section
, Description
,
2518 BootDrive
, BootPartition
, BootSector
);
2519 if (!NT_SUCCESS(Status
))
2521 DPRINT1("CreateFreeLoaderIniForReactOSAndBootSector() failed (Status %lx)\n", Status
);
2525 /* Save current bootsector */
2526 CombinePaths(DstPath
, ARRAYSIZE(DstPath
), 2, SystemRootPath
->Buffer
, BootSector
);
2528 DPRINT1("Save bootsector: %S ==> %S\n", SystemRootPath
->Buffer
, DstPath
);
2529 Status
= SaveBootSector(SystemRootPath
->Buffer
, DstPath
, SECTORSIZE
);
2530 if (!NT_SUCCESS(Status
))
2532 DPRINT1("SaveBootSector() failed (Status %lx)\n", Status
);
2538 Status
= CreateFreeLoaderIniForReactOS(DstPath
, DestinationArcPath
->Buffer
);
2539 if (!NT_SUCCESS(Status
))
2541 DPRINT1("CreateFreeLoaderIniForReactOS() failed (Status %lx)\n", Status
);
2546 /* Install new bootsector on the disk */
2547 if (PartitionType
== PARTITION_FAT32
||
2548 PartitionType
== PARTITION_FAT32_XINT13
)
2550 /* Install FAT32 bootcode */
2551 CombinePaths(SrcPath
, ARRAYSIZE(SrcPath
), 2, SourceRootPath
->Buffer
, L
"\\loader\\fat32.bin");
2553 DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2554 Status
= InstallFat32BootCodeToDisk(SrcPath
, SystemRootPath
->Buffer
);
2555 if (!NT_SUCCESS(Status
))
2557 DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)\n", Status
);
2563 /* Install FAT16 bootcode */
2564 CombinePaths(SrcPath
, ARRAYSIZE(SrcPath
), 2, SourceRootPath
->Buffer
, L
"\\loader\\fat.bin");
2566 DPRINT1("Install FAT16 bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2567 Status
= InstallFat16BootCodeToDisk(SrcPath
, SystemRootPath
->Buffer
);
2568 if (!NT_SUCCESS(Status
))
2570 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status
);
2577 return STATUS_SUCCESS
;
2582 InstallBtrfsBootcodeToPartition(
2583 PUNICODE_STRING SystemRootPath
,
2584 PUNICODE_STRING SourceRootPath
,
2585 PUNICODE_STRING DestinationArcPath
,
2586 UCHAR PartitionType
)
2589 BOOLEAN DoesFreeLdrExist
;
2590 WCHAR SrcPath
[MAX_PATH
];
2591 WCHAR DstPath
[MAX_PATH
];
2593 /* BTRFS partition */
2594 DPRINT("System path: '%wZ'\n", SystemRootPath
);
2596 /* Copy FreeLoader to the system partition, always overwriting the older version */
2597 CombinePaths(SrcPath
, ARRAYSIZE(SrcPath
), 2, SourceRootPath
->Buffer
, L
"\\loader\\freeldr.sys");
2598 CombinePaths(DstPath
, ARRAYSIZE(DstPath
), 2, SystemRootPath
->Buffer
, L
"freeldr.sys");
2600 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2601 Status
= SetupCopyFile(SrcPath
, DstPath
);
2602 if (!NT_SUCCESS(Status
))
2604 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
2608 /* Prepare for possibly copying 'freeldr.ini' */
2609 CombinePaths(DstPath
, ARRAYSIZE(DstPath
), 2, SystemRootPath
->Buffer
, L
"freeldr.ini");
2611 DoesFreeLdrExist
= DoesFileExist(NULL
, DstPath
);
2612 if (DoesFreeLdrExist
)
2614 /* Update existing 'freeldr.ini' */
2615 DPRINT1("Update existing 'freeldr.ini'\n");
2617 Status
= UpdateFreeLoaderIni(DstPath
, DestinationArcPath
->Buffer
);
2618 if (!NT_SUCCESS(Status
))
2620 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
2625 /* Check for *nix bootloaders */
2627 /* Create or update 'freeldr.ini' */
2628 if (DoesFreeLdrExist
== FALSE
)
2630 /* Create new 'freeldr.ini' */
2631 DPRINT1("Create new 'freeldr.ini'\n");
2632 CombinePaths(DstPath
, ARRAYSIZE(DstPath
), 2, SystemRootPath
->Buffer
, L
"\\freeldr.ini");
2634 /* Certainly SysLinux, GRUB, LILO... or an unknown boot loader */
2635 DPRINT1("*nix or unknown boot loader found\n");
2637 if (IsThereAValidBootSector(SystemRootPath
->Buffer
))
2639 PCWSTR BootSector
= L
"BOOTSECT.OLD";
2641 Status
= CreateFreeLoaderIniForReactOSAndBootSector(
2642 DstPath
, DestinationArcPath
->Buffer
,
2643 L
"Linux", L
"\"Linux\"",
2644 L
"hd0", L
"1", BootSector
);
2645 if (!NT_SUCCESS(Status
))
2647 DPRINT1("CreateFreeLoaderIniForReactOSAndBootSector() failed (Status %lx)\n", Status
);
2651 /* Save current bootsector */
2652 CombinePaths(DstPath
, ARRAYSIZE(DstPath
), 2, SystemRootPath
->Buffer
, BootSector
);
2654 DPRINT1("Save bootsector: %S ==> %S\n", SystemRootPath
->Buffer
, DstPath
);
2655 Status
= SaveBootSector(SystemRootPath
->Buffer
, DstPath
, sizeof(BTRFS_BOOTSECTOR
));
2656 if (!NT_SUCCESS(Status
))
2658 DPRINT1("SaveBootSector() failed (Status %lx)\n", Status
);
2664 Status
= CreateFreeLoaderIniForReactOS(DstPath
, DestinationArcPath
->Buffer
);
2665 if (!NT_SUCCESS(Status
))
2667 DPRINT1("CreateFreeLoaderIniForReactOS() failed (Status %lx)\n", Status
);
2672 /* Install new bootsector on the disk */
2673 // if (PartitionType == PARTITION_EXT2)
2675 /* Install BTRFS bootcode */
2676 CombinePaths(SrcPath
, ARRAYSIZE(SrcPath
), 2, SourceRootPath
->Buffer
, L
"\\loader\\btrfs.bin");
2678 DPRINT1("Install BTRFS bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2679 Status
= InstallBtrfsBootCodeToDisk(SrcPath
, SystemRootPath
->Buffer
);
2680 if (!NT_SUCCESS(Status
))
2682 DPRINT1("InstallBtrfsBootCodeToDisk() failed (Status %lx)\n", Status
);
2688 return STATUS_SUCCESS
;
2693 InstallVBRToPartition(
2694 PUNICODE_STRING SystemRootPath
,
2695 PUNICODE_STRING SourceRootPath
,
2696 PUNICODE_STRING DestinationArcPath
,
2697 UCHAR PartitionType
)
2699 switch (PartitionType
)
2701 case PARTITION_FAT_12
:
2702 case PARTITION_FAT_16
:
2703 case PARTITION_HUGE
:
2704 case PARTITION_XINT13
:
2705 case PARTITION_FAT32
:
2706 case PARTITION_FAT32_XINT13
:
2708 return InstallFatBootcodeToPartition(SystemRootPath
,
2714 case PARTITION_LINUX
:
2716 return InstallBtrfsBootcodeToPartition(SystemRootPath
,
2723 DPRINT1("Partitions of type NTFS or HPFS are not supported yet!\n");
2727 DPRINT1("PartitionType 0x%02X unknown!\n", PartitionType
);
2731 return STATUS_UNSUCCESSFUL
;
2736 InstallFatBootcodeToFloppy(
2737 PUNICODE_STRING SourceRootPath
,
2738 PUNICODE_STRING DestinationArcPath
)
2742 UNICODE_STRING FloppyDevice
= RTL_CONSTANT_STRING(L
"\\Device\\Floppy0\\");
2743 WCHAR SrcPath
[MAX_PATH
];
2744 WCHAR DstPath
[MAX_PATH
];
2746 /* Format the floppy first */
2747 FatFS
= GetFileSystemByName(L
"FAT");
2750 DPRINT1("FAT FS non existent on this system?!\n");
2751 return STATUS_NOT_SUPPORTED
;
2753 Status
= FatFS
->FormatFunc(&FloppyDevice
,
2759 if (!NT_SUCCESS(Status
))
2761 DPRINT1("VfatFormat() failed (Status %lx)\n", Status
);
2765 /* Copy FreeLoader to the boot partition */
2766 CombinePaths(SrcPath
, ARRAYSIZE(SrcPath
), 2, SourceRootPath
->Buffer
, L
"\\loader\\freeldr.sys");
2767 CombinePaths(DstPath
, ARRAYSIZE(DstPath
), 2, FloppyDevice
.Buffer
, L
"freeldr.sys");
2769 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2770 Status
= SetupCopyFile(SrcPath
, DstPath
);
2771 if (!NT_SUCCESS(Status
))
2773 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
2777 /* Create new 'freeldr.ini' */
2778 CombinePaths(DstPath
, ARRAYSIZE(DstPath
), 2, FloppyDevice
.Buffer
, L
"freeldr.ini");
2780 DPRINT("Create new 'freeldr.ini'\n");
2781 Status
= CreateFreeLoaderIniForReactOS(DstPath
, DestinationArcPath
->Buffer
);
2782 if (!NT_SUCCESS(Status
))
2784 DPRINT1("CreateFreeLoaderIniForReactOS() failed (Status %lx)\n", Status
);
2788 /* Install FAT12 boosector */
2789 CombinePaths(SrcPath
, ARRAYSIZE(SrcPath
), 2, SourceRootPath
->Buffer
, L
"\\loader\\fat.bin");
2790 RtlStringCchCopyW(DstPath
, ARRAYSIZE(DstPath
), FloppyDevice
.Buffer
);
2792 DPRINT("Install FAT bootcode: %S ==> %S\n", SrcPath
, DstPath
);
2793 Status
= InstallFat12BootCodeToFloppy(SrcPath
, DstPath
);
2794 if (!NT_SUCCESS(Status
))
2796 DPRINT1("InstallFat12BootCodeToFloppy() failed (Status %lx)\n", Status
);
2800 return STATUS_SUCCESS
;