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 _EXT2_BOOTSECTOR
84 // The EXT2 bootsector is completely user-specific.
85 // No FS data is stored there.
87 } EXT2_BOOTSECTOR
, *PEXT2_BOOTSECTOR
;
89 // TODO: Add more bootsector structures!
93 extern PPARTLIST PartitionList
;
95 /* FUNCTIONS ****************************************************************/
100 CreateCommonFreeLoaderSections(
103 PINICACHESECTION IniSection
;
105 /* Create "FREELOADER" section */
106 IniSection
= IniCacheAppendSection(IniCache
, L
"FREELOADER");
109 if (IsUnattendedSetup
)
111 /* DefaultOS=ReactOS */
112 IniCacheInsertKey(IniSection
,
117 L
"ReactOS_KdSerial");
125 /* DefaultOS=ReactOS */
126 IniCacheInsertKey(IniSection
,
134 if (IsUnattendedSetup
)
137 /* Timeout=0 for unattended or non debug*/
138 IniCacheInsertKey(IniSection
,
147 /* Timeout=0 or 10 */
148 IniCacheInsertKey(IniSection
,
156 /* Create "Display" section */
157 IniSection
= IniCacheAppendSection(IniCache
, L
"Display");
159 /* TitleText=ReactOS Boot Manager */
160 IniCacheInsertKey(IniSection
,
164 L
"ReactOS Boot Manager");
166 /* StatusBarColor=Cyan */
167 IniCacheInsertKey(IniSection
,
173 /* StatusBarTextColor=Black */
174 IniCacheInsertKey(IniSection
,
177 L
"StatusBarTextColor",
180 /* BackdropTextColor=White */
181 IniCacheInsertKey(IniSection
,
184 L
"BackdropTextColor",
187 /* BackdropColor=Blue */
188 IniCacheInsertKey(IniSection
,
194 /* BackdropFillStyle=Medium */
195 IniCacheInsertKey(IniSection
,
198 L
"BackdropFillStyle",
201 /* TitleBoxTextColor=White */
202 IniCacheInsertKey(IniSection
,
205 L
"TitleBoxTextColor",
208 /* TitleBoxColor=Red */
209 IniCacheInsertKey(IniSection
,
215 /* MessageBoxTextColor=White */
216 IniCacheInsertKey(IniSection
,
219 L
"MessageBoxTextColor",
222 /* MessageBoxColor=Blue */
223 IniCacheInsertKey(IniSection
,
229 /* MenuTextColor=White */
230 IniCacheInsertKey(IniSection
,
237 IniCacheInsertKey(IniSection
,
243 /* TextColor=Yellow */
244 IniCacheInsertKey(IniSection
,
250 /* SelectedTextColor=Black */
251 IniCacheInsertKey(IniSection
,
254 L
"SelectedTextColor",
257 /* SelectedColor=Gray */
258 IniCacheInsertKey(IniSection
,
264 /* SelectedColor=Gray */
265 IniCacheInsertKey(IniSection
,
271 /* SelectedColor=Gray */
272 IniCacheInsertKey(IniSection
,
278 /* SelectedColor=Gray */
279 IniCacheInsertKey(IniSection
,
285 /* SelectedColor=Gray */
286 IniCacheInsertKey(IniSection
,
292 /* SelectedColor=Gray */
293 IniCacheInsertKey(IniSection
,
297 L
"Seconds until highlighted choice will be started automatically: ");
304 PINICACHESECTION OSSection
,
311 PINICACHESECTION IniSection
;
313 /* Insert entry into "Operating Systems" section */
314 IniCacheInsertKey(OSSection
,
320 /* Create new section */
321 IniSection
= IniCacheAppendSection(IniCache
, Section
);
324 IniCacheInsertKey(IniSection
,
331 IniCacheInsertKey(IniSection
,
338 IniCacheInsertKey(IniSection
,
344 return STATUS_SUCCESS
;
349 CreateFreeLoaderReactOSEntries(
353 PINICACHESECTION IniSection
;
355 /* Create "Operating Systems" section */
356 IniSection
= IniCacheAppendSection(IniCache
, L
"Operating Systems");
359 CreateNTOSEntry(IniCache
, IniSection
,
360 L
"ReactOS", L
"\"ReactOS\"",
361 L
"Windows2003", ArcPath
,
365 CreateNTOSEntry(IniCache
, IniSection
,
366 L
"ReactOS_Debug", L
"\"ReactOS (Debug)\"",
367 L
"Windows2003", ArcPath
,
368 L
"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS");
370 /* ReactOS_VBoxDebug */
371 CreateNTOSEntry(IniCache
, IniSection
,
372 L
"ReactOS_VBoxDebug", L
"\"ReactOS (VBoxDebug)\"",
373 L
"Windows2003", ArcPath
,
374 L
"/DEBUG /DEBUGPORT=VBOX /SOS");
378 /* ReactOS_KdSerial */
379 CreateNTOSEntry(IniCache
, IniSection
,
380 L
"ReactOS_KdSerial", L
"\"ReactOS (RosDbg)\"",
381 L
"Windows2003", ArcPath
,
382 L
"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /KDSERIAL");
386 CreateNTOSEntry(IniCache
, IniSection
,
387 L
"ReactOS_Screen", L
"\"ReactOS (Screen)\"",
388 L
"Windows2003", ArcPath
,
389 L
"/DEBUG /DEBUGPORT=SCREEN /SOS");
391 /* ReactOS_LogFile */
392 CreateNTOSEntry(IniCache
, IniSection
,
393 L
"ReactOS_LogFile", L
"\"ReactOS (Log file)\"",
394 L
"Windows2003", ArcPath
,
395 L
"/DEBUG /DEBUGPORT=FILE /SOS");
398 CreateNTOSEntry(IniCache
, IniSection
,
399 L
"ReactOS_Ram", L
"\"ReactOS (RAM Disk)\"",
400 L
"Windows2003", L
"ramdisk(0)\\ReactOS",
401 L
"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /RDPATH=reactos.img /RDIMAGEOFFSET=32256");
404 CreateNTOSEntry(IniCache
, IniSection
,
405 L
"ReactOS_EMS", L
"\"ReactOS (Emergency Management Services)\"",
406 L
"Windows2003", ArcPath
,
407 L
"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /redirect=com2 /redirectbaudrate=115200");
413 CreateFreeLoaderIniForReactOS(
419 /* Initialize the INI file */
420 IniCache
= IniCacheCreate();
422 /* Create the common FreeLdr sections */
423 CreateCommonFreeLoaderSections(IniCache
);
425 /* Add the ReactOS entries */
426 CreateFreeLoaderReactOSEntries(IniCache
, ArcPath
);
428 /* Save the INI file */
429 IniCacheSave(IniCache
, IniPath
);
430 IniCacheDestroy(IniCache
);
432 return STATUS_SUCCESS
;
437 CreateFreeLoaderIniForReactOSAndBootSector(
443 PWCHAR BootPartition
,
447 PINICACHESECTION IniSection
;
449 /* Initialize the INI file */
450 IniCache
= IniCacheCreate();
452 /* Create the common FreeLdr sections */
453 CreateCommonFreeLoaderSections(IniCache
);
455 /* Add the ReactOS entries */
456 CreateFreeLoaderReactOSEntries(IniCache
, ArcPath
);
458 /* Get "Operating Systems" section */
459 IniSection
= IniCacheGetSection(IniCache
, L
"Operating Systems");
461 /* Insert entry into "Operating Systems" section */
462 IniCacheInsertKey(IniSection
,
468 /* Create new section */
469 IniSection
= IniCacheAppendSection(IniCache
, Section
);
471 /* BootType=BootSector */
472 IniCacheInsertKey(IniSection
,
479 IniCacheInsertKey(IniSection
,
486 IniCacheInsertKey(IniSection
,
493 IniCacheInsertKey(IniSection
,
499 /* Save the INI file */
500 IniCacheSave(IniCache
, IniPath
);
501 IniCacheDestroy(IniCache
);
503 return STATUS_SUCCESS
;
514 PINICACHESECTION IniSection
;
515 PINICACHESECTION OsIniSection
;
516 WCHAR SectionName
[80];
518 WCHAR SystemPath
[200];
519 WCHAR SectionName2
[200];
523 Status
= IniCacheLoad(&IniCache
, IniPath
, FALSE
);
524 if (!NT_SUCCESS(Status
))
527 /* Get "Operating Systems" section */
528 IniSection
= IniCacheGetSection(IniCache
, L
"Operating Systems");
529 if (IniSection
== NULL
)
531 IniCacheDestroy(IniCache
);
532 return STATUS_UNSUCCESSFUL
;
535 /* Find an existing usable or an unused section name */
537 wcscpy(SectionName
, L
"ReactOS");
538 wcscpy(OsName
, L
"\"ReactOS\"");
541 Status
= IniCacheGetKey(IniSection
, SectionName
, &KeyData
);
542 if (!NT_SUCCESS(Status
))
545 /* Get operation system section */
546 if (KeyData
[0] == '"')
548 wcscpy(SectionName2
, &KeyData
[1]);
549 j
= wcslen(SectionName2
);
552 SectionName2
[j
-1] = 0;
557 wcscpy(SectionName2
, KeyData
);
560 /* Search for an existing ReactOS entry */
561 OsIniSection
= IniCacheGetSection(IniCache
, SectionName2
);
562 if (OsIniSection
!= NULL
)
564 BOOLEAN UseExistingEntry
= TRUE
;
566 /* Check for boot type "Windows2003" */
567 Status
= IniCacheGetKey(OsIniSection
, L
"BootType", &KeyData
);
568 if (NT_SUCCESS(Status
))
570 if ((KeyData
== NULL
) ||
571 ( (_wcsicmp(KeyData
, L
"Windows2003") != 0) &&
572 (_wcsicmp(KeyData
, L
"\"Windows2003\"") != 0) ))
574 /* This is not a ReactOS entry */
575 UseExistingEntry
= FALSE
;
580 UseExistingEntry
= FALSE
;
583 if (UseExistingEntry
)
585 /* BootType is Windows2003. Now check SystemPath. */
586 Status
= IniCacheGetKey(OsIniSection
, L
"SystemPath", &KeyData
);
587 if (NT_SUCCESS(Status
))
589 swprintf(SystemPath
, L
"\"%s\"", ArcPath
);
590 if ((KeyData
== NULL
) ||
591 ( (_wcsicmp(KeyData
, ArcPath
) != 0) &&
592 (_wcsicmp(KeyData
, SystemPath
) != 0) ))
594 /* This entry is a ReactOS entry, but the SystemRoot
595 does not match the one we are looking for. */
596 UseExistingEntry
= FALSE
;
601 UseExistingEntry
= FALSE
;
605 if (UseExistingEntry
)
607 IniCacheDestroy(IniCache
);
608 return STATUS_SUCCESS
;
612 swprintf(SectionName
, L
"ReactOS_%lu", i
);
613 swprintf(OsName
, L
"\"ReactOS %lu\"", i
);
617 /* Create a new "ReactOS" entry */
618 CreateNTOSEntry(IniCache
, IniSection
,
620 L
"Windows2003", ArcPath
,
623 IniCacheSave(IniCache
, IniPath
);
624 IniCacheDestroy(IniCache
);
626 return STATUS_SUCCESS
;
630 IsThereAValidBootSector(PWSTR RootPath
)
633 * We first demand that the bootsector has a valid signature at its end.
634 * We then check the first 3 bytes (as a ULONG) of the bootsector for a
635 * potential "valid" instruction (the BIOS starts execution of the bootsector
636 * at its beginning). Currently this criterium is that this ULONG must be
637 * non-zero. If both these tests pass, then the bootsector is valid; otherwise
638 * it is invalid and certainly needs to be overwritten.
640 BOOLEAN IsValid
= FALSE
;
643 OBJECT_ATTRIBUTES ObjectAttributes
;
644 IO_STATUS_BLOCK IoStatusBlock
;
646 LARGE_INTEGER FileOffset
;
650 /* Allocate buffer for bootsector */
651 BootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
652 if (BootSector
== NULL
)
653 return FALSE
; // STATUS_INSUFFICIENT_RESOURCES;
655 /* Read current boot sector into buffer */
656 RtlInitUnicodeString(&Name
, RootPath
);
658 InitializeObjectAttributes(&ObjectAttributes
,
660 OBJ_CASE_INSENSITIVE
,
664 Status
= NtOpenFile(&FileHandle
,
665 GENERIC_READ
| SYNCHRONIZE
,
669 FILE_SYNCHRONOUS_IO_NONALERT
);
670 if (!NT_SUCCESS(Status
))
673 RtlZeroMemory(BootSector
, SECTORSIZE
);
675 FileOffset
.QuadPart
= 0ULL;
676 Status
= NtReadFile(FileHandle
,
686 if (!NT_SUCCESS(Status
))
689 /* Check the instruction; we use a ULONG to read three bytes */
690 Instruction
= (*(PULONG
)BootSector
) & 0x00FFFFFF;
691 IsValid
= (Instruction
!= 0x00000000);
693 /* Check the bootsector signature */
694 IsValid
&= (*(PUSHORT
)(BootSector
+ 0x1fe) == 0xaa55);
697 /* Free the boot sector */
698 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
699 return IsValid
; // Status;
710 OBJECT_ATTRIBUTES ObjectAttributes
;
711 IO_STATUS_BLOCK IoStatusBlock
;
713 LARGE_INTEGER FileOffset
;
716 /* Allocate buffer for bootsector */
717 BootSector
= RtlAllocateHeap(ProcessHeap
, 0, Length
);
718 if (BootSector
== NULL
)
719 return STATUS_INSUFFICIENT_RESOURCES
;
721 /* Read current boot sector into buffer */
722 RtlInitUnicodeString(&Name
, RootPath
);
724 InitializeObjectAttributes(&ObjectAttributes
,
726 OBJ_CASE_INSENSITIVE
,
730 Status
= NtOpenFile(&FileHandle
,
731 GENERIC_READ
| SYNCHRONIZE
,
735 FILE_SYNCHRONOUS_IO_NONALERT
);
736 if (!NT_SUCCESS(Status
))
738 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
742 FileOffset
.QuadPart
= 0ULL;
743 Status
= NtReadFile(FileHandle
,
753 if (!NT_SUCCESS(Status
))
755 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
759 /* Write bootsector to DstPath */
760 RtlInitUnicodeString(&Name
, DstPath
);
762 InitializeObjectAttributes(&ObjectAttributes
,
768 Status
= NtCreateFile(&FileHandle
,
769 GENERIC_WRITE
| SYNCHRONIZE
,
773 FILE_ATTRIBUTE_NORMAL
,
776 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
,
779 if (!NT_SUCCESS(Status
))
781 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
785 Status
= NtWriteFile(FileHandle
,
796 /* Free the boot sector */
797 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
804 InstallFat16BootCodeToFile(
811 OBJECT_ATTRIBUTES ObjectAttributes
;
812 IO_STATUS_BLOCK IoStatusBlock
;
814 LARGE_INTEGER FileOffset
;
815 PFAT_BOOTSECTOR OrigBootSector
;
816 PFAT_BOOTSECTOR NewBootSector
;
818 /* Allocate buffer for original bootsector */
819 OrigBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
820 if (OrigBootSector
== NULL
)
821 return STATUS_INSUFFICIENT_RESOURCES
;
823 /* Read current boot sector into buffer */
824 RtlInitUnicodeString(&Name
, RootPath
);
826 InitializeObjectAttributes(&ObjectAttributes
,
828 OBJ_CASE_INSENSITIVE
,
832 Status
= NtOpenFile(&FileHandle
,
833 GENERIC_READ
| SYNCHRONIZE
,
837 FILE_SYNCHRONOUS_IO_NONALERT
);
838 if (!NT_SUCCESS(Status
))
840 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
844 FileOffset
.QuadPart
= 0ULL;
845 Status
= NtReadFile(FileHandle
,
855 if (!NT_SUCCESS(Status
))
857 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
861 /* Allocate buffer for new bootsector */
862 NewBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
863 if (NewBootSector
== NULL
)
865 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
866 return STATUS_INSUFFICIENT_RESOURCES
;
869 /* Read new bootsector from SrcPath */
870 RtlInitUnicodeString(&Name
, SrcPath
);
872 InitializeObjectAttributes(&ObjectAttributes
,
874 OBJ_CASE_INSENSITIVE
,
878 Status
= NtOpenFile(&FileHandle
,
879 GENERIC_READ
| SYNCHRONIZE
,
883 FILE_SYNCHRONOUS_IO_NONALERT
);
884 if (!NT_SUCCESS(Status
))
886 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
887 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
891 FileOffset
.QuadPart
= 0ULL;
892 Status
= NtReadFile(FileHandle
,
902 if (!NT_SUCCESS(Status
))
904 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
905 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
909 /* Adjust bootsector (copy a part of the FAT BPB) */
910 memcpy(&NewBootSector
->OemName
,
911 &OrigBootSector
->OemName
,
912 FIELD_OFFSET(FAT_BOOTSECTOR
, BootCodeAndData
) -
913 FIELD_OFFSET(FAT_BOOTSECTOR
, OemName
));
915 /* Free the original boot sector */
916 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
918 /* Write new bootsector to DstPath */
919 RtlInitUnicodeString(&Name
, DstPath
);
921 InitializeObjectAttributes(&ObjectAttributes
,
927 Status
= NtCreateFile(&FileHandle
,
928 GENERIC_WRITE
| SYNCHRONIZE
,
932 FILE_ATTRIBUTE_NORMAL
,
935 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
,
938 if (!NT_SUCCESS(Status
))
940 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
944 Status
= NtWriteFile(FileHandle
,
955 /* Free the new boot sector */
956 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
963 InstallFat32BootCodeToFile(
970 OBJECT_ATTRIBUTES ObjectAttributes
;
971 IO_STATUS_BLOCK IoStatusBlock
;
973 LARGE_INTEGER FileOffset
;
974 PFAT32_BOOTSECTOR OrigBootSector
;
975 PFAT32_BOOTSECTOR NewBootSector
;
977 /* Allocate buffer for original bootsector */
978 OrigBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
979 if (OrigBootSector
== NULL
)
980 return STATUS_INSUFFICIENT_RESOURCES
;
982 /* Read current boot sector into buffer */
983 RtlInitUnicodeString(&Name
, RootPath
);
985 InitializeObjectAttributes(&ObjectAttributes
,
987 OBJ_CASE_INSENSITIVE
,
991 Status
= NtOpenFile(&FileHandle
,
992 GENERIC_READ
| SYNCHRONIZE
,
996 FILE_SYNCHRONOUS_IO_NONALERT
);
997 if (!NT_SUCCESS(Status
))
999 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1003 Status
= NtReadFile(FileHandle
,
1012 NtClose(FileHandle
);
1013 if (!NT_SUCCESS(Status
))
1015 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1019 /* Allocate buffer for new bootsector (2 sectors) */
1020 NewBootSector
= RtlAllocateHeap(ProcessHeap
, 0, 2 * SECTORSIZE
);
1021 if (NewBootSector
== NULL
)
1023 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1024 return STATUS_INSUFFICIENT_RESOURCES
;
1027 /* Read new bootsector from SrcPath */
1028 RtlInitUnicodeString(&Name
, SrcPath
);
1030 InitializeObjectAttributes(&ObjectAttributes
,
1032 OBJ_CASE_INSENSITIVE
,
1036 Status
= NtOpenFile(&FileHandle
,
1037 GENERIC_READ
| SYNCHRONIZE
,
1041 FILE_SYNCHRONOUS_IO_NONALERT
);
1042 if (!NT_SUCCESS(Status
))
1044 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1045 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1049 Status
= NtReadFile(FileHandle
,
1058 NtClose(FileHandle
);
1059 if (!NT_SUCCESS(Status
))
1061 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1062 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1066 /* Adjust bootsector (copy a part of the FAT32 BPB) */
1067 memcpy(&NewBootSector
->OemName
,
1068 &OrigBootSector
->OemName
,
1069 FIELD_OFFSET(FAT32_BOOTSECTOR
, BootCodeAndData
) -
1070 FIELD_OFFSET(FAT32_BOOTSECTOR
, OemName
));
1072 /* Disable the backup boot sector */
1073 NewBootSector
->BackupBootSector
= 0;
1075 /* Free the original boot sector */
1076 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1078 /* Write the first sector of the new bootcode to DstPath */
1079 RtlInitUnicodeString(&Name
, DstPath
);
1081 InitializeObjectAttributes(&ObjectAttributes
,
1087 Status
= NtCreateFile(&FileHandle
,
1088 GENERIC_WRITE
| SYNCHRONIZE
,
1092 FILE_ATTRIBUTE_NORMAL
,
1095 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
,
1098 if (!NT_SUCCESS(Status
))
1100 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1104 Status
= NtWriteFile(FileHandle
,
1113 NtClose(FileHandle
);
1114 if (!NT_SUCCESS(Status
))
1116 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1120 /* Write the second sector of the new bootcode to boot disk sector 14 */
1121 RtlInitUnicodeString(&Name
, RootPath
);
1123 InitializeObjectAttributes(&ObjectAttributes
,
1129 Status
= NtOpenFile(&FileHandle
,
1130 GENERIC_WRITE
| SYNCHRONIZE
,
1134 FILE_SYNCHRONOUS_IO_NONALERT
);
1135 if (!NT_SUCCESS(Status
))
1137 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1141 FileOffset
.QuadPart
= (ULONGLONG
)(14 * SECTORSIZE
);
1142 Status
= NtWriteFile(FileHandle
,
1147 ((PUCHAR
)NewBootSector
+ SECTORSIZE
),
1151 if (!NT_SUCCESS(Status
))
1154 NtClose(FileHandle
);
1156 /* Free the new boot sector */
1157 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1164 InstallMbrBootCodeToDisk(
1169 UNICODE_STRING Name
;
1170 OBJECT_ATTRIBUTES ObjectAttributes
;
1171 IO_STATUS_BLOCK IoStatusBlock
;
1173 LARGE_INTEGER FileOffset
;
1174 PPARTITION_SECTOR OrigBootSector
;
1175 PPARTITION_SECTOR NewBootSector
;
1177 /* Allocate buffer for original bootsector */
1178 OrigBootSector
= (PPARTITION_SECTOR
)RtlAllocateHeap(ProcessHeap
,
1180 sizeof(PARTITION_SECTOR
));
1181 if (OrigBootSector
== NULL
)
1182 return STATUS_INSUFFICIENT_RESOURCES
;
1184 /* Read current boot sector into buffer */
1185 RtlInitUnicodeString(&Name
,
1188 InitializeObjectAttributes(&ObjectAttributes
,
1190 OBJ_CASE_INSENSITIVE
,
1194 Status
= NtOpenFile(&FileHandle
,
1195 GENERIC_READ
| SYNCHRONIZE
,
1199 FILE_SYNCHRONOUS_IO_NONALERT
);
1200 if (!NT_SUCCESS(Status
))
1202 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1206 FileOffset
.QuadPart
= 0ULL;
1207 Status
= NtReadFile(FileHandle
,
1213 sizeof(PARTITION_SECTOR
),
1216 NtClose(FileHandle
);
1217 if (!NT_SUCCESS(Status
))
1219 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1223 /* Allocate buffer for new bootsector */
1224 NewBootSector
= (PPARTITION_SECTOR
)RtlAllocateHeap(ProcessHeap
,
1226 sizeof(PARTITION_SECTOR
));
1227 if (NewBootSector
== NULL
)
1229 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1230 return STATUS_INSUFFICIENT_RESOURCES
;
1233 /* Read new bootsector from SrcPath */
1234 RtlInitUnicodeString(&Name
, SrcPath
);
1236 InitializeObjectAttributes(&ObjectAttributes
,
1238 OBJ_CASE_INSENSITIVE
,
1242 Status
= NtOpenFile(&FileHandle
,
1243 GENERIC_READ
| SYNCHRONIZE
,
1247 FILE_SYNCHRONOUS_IO_NONALERT
);
1248 if (!NT_SUCCESS(Status
))
1250 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1251 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1255 Status
= NtReadFile(FileHandle
,
1261 sizeof(PARTITION_SECTOR
),
1264 NtClose(FileHandle
);
1265 if (!NT_SUCCESS(Status
))
1267 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1268 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1272 /* Copy partition table from old MBR to new */
1273 RtlCopyMemory(&NewBootSector
->Signature
,
1274 &OrigBootSector
->Signature
,
1275 sizeof(PARTITION_SECTOR
) - offsetof(PARTITION_SECTOR
, Signature
) /* Length of partition table */);
1277 /* Free the original boot sector */
1278 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1280 /* Write new bootsector to RootPath */
1281 RtlInitUnicodeString(&Name
, RootPath
);
1283 InitializeObjectAttributes(&ObjectAttributes
,
1289 Status
= NtOpenFile(&FileHandle
,
1290 GENERIC_WRITE
| SYNCHRONIZE
,
1294 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1295 if (!NT_SUCCESS(Status
))
1297 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1298 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1302 FileOffset
.QuadPart
= 0ULL;
1303 Status
= NtWriteFile(FileHandle
,
1309 sizeof(PARTITION_SECTOR
),
1312 NtClose(FileHandle
);
1314 /* Free the new boot sector */
1315 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1322 InstallFat12BootCodeToFloppy(
1327 UNICODE_STRING Name
;
1328 OBJECT_ATTRIBUTES ObjectAttributes
;
1329 IO_STATUS_BLOCK IoStatusBlock
;
1331 LARGE_INTEGER FileOffset
;
1332 PFAT_BOOTSECTOR OrigBootSector
;
1333 PFAT_BOOTSECTOR NewBootSector
;
1335 /* Allocate buffer for original bootsector */
1336 OrigBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
1337 if (OrigBootSector
== NULL
)
1338 return STATUS_INSUFFICIENT_RESOURCES
;
1340 /* Read current boot sector into buffer */
1341 RtlInitUnicodeString(&Name
, RootPath
);
1343 InitializeObjectAttributes(&ObjectAttributes
,
1345 OBJ_CASE_INSENSITIVE
,
1349 Status
= NtOpenFile(&FileHandle
,
1350 GENERIC_READ
| SYNCHRONIZE
,
1354 FILE_SYNCHRONOUS_IO_NONALERT
);
1355 if (!NT_SUCCESS(Status
))
1357 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1361 FileOffset
.QuadPart
= 0ULL;
1362 Status
= NtReadFile(FileHandle
,
1371 NtClose(FileHandle
);
1372 if (!NT_SUCCESS(Status
))
1374 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1378 /* Allocate buffer for new bootsector */
1379 NewBootSector
= RtlAllocateHeap(ProcessHeap
,
1382 if (NewBootSector
== NULL
)
1384 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1385 return STATUS_INSUFFICIENT_RESOURCES
;
1388 /* Read new bootsector from SrcPath */
1389 RtlInitUnicodeString(&Name
, SrcPath
);
1391 InitializeObjectAttributes(&ObjectAttributes
,
1393 OBJ_CASE_INSENSITIVE
,
1397 Status
= NtOpenFile(&FileHandle
,
1398 GENERIC_READ
| SYNCHRONIZE
,
1402 FILE_SYNCHRONOUS_IO_NONALERT
);
1403 if (!NT_SUCCESS(Status
))
1405 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1406 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1410 Status
= NtReadFile(FileHandle
,
1419 NtClose(FileHandle
);
1420 if (!NT_SUCCESS(Status
))
1422 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1423 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1427 /* Adjust bootsector (copy a part of the FAT16 BPB) */
1428 memcpy(&NewBootSector
->OemName
,
1429 &OrigBootSector
->OemName
,
1430 FIELD_OFFSET(FAT_BOOTSECTOR
, BootCodeAndData
) -
1431 FIELD_OFFSET(FAT_BOOTSECTOR
, OemName
));
1433 /* Free the original boot sector */
1434 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1436 /* Write new bootsector to RootPath */
1437 RtlInitUnicodeString(&Name
, RootPath
);
1439 InitializeObjectAttributes(&ObjectAttributes
,
1445 Status
= NtOpenFile(&FileHandle
,
1446 GENERIC_WRITE
| SYNCHRONIZE
,
1450 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1451 if (!NT_SUCCESS(Status
))
1453 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1454 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1458 FileOffset
.QuadPart
= 0ULL;
1459 Status
= NtWriteFile(FileHandle
,
1468 NtClose(FileHandle
);
1470 /* Free the new boot sector */
1471 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1478 InstallFat16BootCodeToDisk(
1483 UNICODE_STRING Name
;
1484 OBJECT_ATTRIBUTES ObjectAttributes
;
1485 IO_STATUS_BLOCK IoStatusBlock
;
1487 LARGE_INTEGER FileOffset
;
1488 PFAT_BOOTSECTOR OrigBootSector
;
1489 PFAT_BOOTSECTOR NewBootSector
;
1491 /* Allocate buffer for original bootsector */
1492 OrigBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
1493 if (OrigBootSector
== NULL
)
1494 return STATUS_INSUFFICIENT_RESOURCES
;
1496 /* Read current boot sector into buffer */
1497 RtlInitUnicodeString(&Name
, RootPath
);
1499 InitializeObjectAttributes(&ObjectAttributes
,
1501 OBJ_CASE_INSENSITIVE
,
1505 Status
= NtOpenFile(&FileHandle
,
1506 GENERIC_READ
| SYNCHRONIZE
,
1510 FILE_SYNCHRONOUS_IO_NONALERT
);
1511 if (!NT_SUCCESS(Status
))
1513 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1517 FileOffset
.QuadPart
= 0ULL;
1518 Status
= NtReadFile(FileHandle
,
1527 NtClose(FileHandle
);
1528 if (!NT_SUCCESS(Status
))
1530 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1534 /* Allocate buffer for new bootsector */
1535 NewBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
1536 if (NewBootSector
== NULL
)
1538 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1539 return STATUS_INSUFFICIENT_RESOURCES
;
1542 /* Read new bootsector from SrcPath */
1543 RtlInitUnicodeString(&Name
, SrcPath
);
1545 InitializeObjectAttributes(&ObjectAttributes
,
1547 OBJ_CASE_INSENSITIVE
,
1551 Status
= NtOpenFile(&FileHandle
,
1552 GENERIC_READ
| SYNCHRONIZE
,
1556 FILE_SYNCHRONOUS_IO_NONALERT
);
1557 if (!NT_SUCCESS(Status
))
1559 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1560 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1564 Status
= NtReadFile(FileHandle
,
1573 NtClose(FileHandle
);
1574 if (!NT_SUCCESS(Status
))
1576 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1577 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1581 /* Adjust bootsector (copy a part of the FAT16 BPB) */
1582 memcpy(&NewBootSector
->OemName
,
1583 &OrigBootSector
->OemName
,
1584 FIELD_OFFSET(FAT_BOOTSECTOR
, BootCodeAndData
) -
1585 FIELD_OFFSET(FAT_BOOTSECTOR
, OemName
));
1587 /* Free the original boot sector */
1588 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1590 /* Write new bootsector to RootPath */
1591 RtlInitUnicodeString(&Name
, RootPath
);
1593 InitializeObjectAttributes(&ObjectAttributes
,
1599 Status
= NtOpenFile(&FileHandle
,
1600 GENERIC_WRITE
| SYNCHRONIZE
,
1604 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1605 if (!NT_SUCCESS(Status
))
1607 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1608 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1612 FileOffset
.QuadPart
= 0ULL;
1613 Status
= NtWriteFile(FileHandle
,
1622 NtClose(FileHandle
);
1624 /* Free the new boot sector */
1625 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1632 InstallFat32BootCodeToDisk(
1637 UNICODE_STRING Name
;
1638 OBJECT_ATTRIBUTES ObjectAttributes
;
1639 IO_STATUS_BLOCK IoStatusBlock
;
1641 LARGE_INTEGER FileOffset
;
1642 PFAT32_BOOTSECTOR OrigBootSector
;
1643 PFAT32_BOOTSECTOR NewBootSector
;
1644 USHORT BackupBootSector
;
1646 /* Allocate buffer for original bootsector */
1647 OrigBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
1648 if (OrigBootSector
== NULL
)
1649 return STATUS_INSUFFICIENT_RESOURCES
;
1651 /* Read current boot sector into buffer */
1652 RtlInitUnicodeString(&Name
, RootPath
);
1654 InitializeObjectAttributes(&ObjectAttributes
,
1656 OBJ_CASE_INSENSITIVE
,
1660 Status
= NtOpenFile(&FileHandle
,
1661 GENERIC_READ
| SYNCHRONIZE
,
1665 FILE_SYNCHRONOUS_IO_NONALERT
);
1666 if (!NT_SUCCESS(Status
))
1668 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1672 FileOffset
.QuadPart
= 0ULL;
1673 Status
= NtReadFile(FileHandle
,
1682 NtClose(FileHandle
);
1683 if (!NT_SUCCESS(Status
))
1685 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1690 /* Allocate buffer for new bootsector (2 sectors) */
1691 NewBootSector
= RtlAllocateHeap(ProcessHeap
, 0, 2 * SECTORSIZE
);
1692 if (NewBootSector
== NULL
)
1694 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1695 return STATUS_INSUFFICIENT_RESOURCES
;
1698 /* Read new bootsector from SrcPath */
1699 RtlInitUnicodeString(&Name
, SrcPath
);
1701 InitializeObjectAttributes(&ObjectAttributes
,
1703 OBJ_CASE_INSENSITIVE
,
1707 Status
= NtOpenFile(&FileHandle
,
1708 GENERIC_READ
| SYNCHRONIZE
,
1712 FILE_SYNCHRONOUS_IO_NONALERT
);
1713 if (!NT_SUCCESS(Status
))
1715 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1716 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1720 Status
= NtReadFile(FileHandle
,
1729 NtClose(FileHandle
);
1730 if (!NT_SUCCESS(Status
))
1732 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1733 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1737 /* Adjust bootsector (copy a part of the FAT32 BPB) */
1738 memcpy(&NewBootSector
->OemName
,
1739 &OrigBootSector
->OemName
,
1740 FIELD_OFFSET(FAT32_BOOTSECTOR
, BootCodeAndData
) -
1741 FIELD_OFFSET(FAT32_BOOTSECTOR
, OemName
));
1743 /* Get the location of the backup boot sector */
1744 BackupBootSector
= OrigBootSector
->BackupBootSector
;
1746 /* Free the original boot sector */
1747 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1749 /* Write the first sector of the new bootcode to DstPath */
1750 RtlInitUnicodeString(&Name
, RootPath
);
1752 InitializeObjectAttributes(&ObjectAttributes
,
1758 Status
= NtOpenFile(&FileHandle
,
1759 GENERIC_WRITE
| SYNCHRONIZE
,
1763 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1764 if (!NT_SUCCESS(Status
))
1766 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1767 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1771 /* Write sector 0 */
1772 FileOffset
.QuadPart
= 0ULL;
1773 Status
= NtWriteFile(FileHandle
,
1782 if (!NT_SUCCESS(Status
))
1784 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1785 NtClose(FileHandle
);
1786 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1790 /* Write backup boot sector */
1791 if ((BackupBootSector
!= 0x0000) && (BackupBootSector
!= 0xFFFF))
1793 FileOffset
.QuadPart
= (ULONGLONG
)((ULONG
)BackupBootSector
* SECTORSIZE
);
1794 Status
= NtWriteFile(FileHandle
,
1803 if (!NT_SUCCESS(Status
))
1805 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1806 NtClose(FileHandle
);
1807 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1812 /* Write sector 14 */
1813 FileOffset
.QuadPart
= 14 * SECTORSIZE
;
1814 Status
= NtWriteFile(FileHandle
,
1819 ((PUCHAR
)NewBootSector
+ SECTORSIZE
),
1823 if (!NT_SUCCESS(Status
))
1825 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1827 NtClose(FileHandle
);
1829 /* Free the new boot sector */
1830 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1837 InstallExt2BootCodeToDisk(
1842 UNICODE_STRING Name
;
1843 OBJECT_ATTRIBUTES ObjectAttributes
;
1844 IO_STATUS_BLOCK IoStatusBlock
;
1846 LARGE_INTEGER FileOffset
;
1847 // PEXT2_BOOTSECTOR OrigBootSector;
1848 PEXT2_BOOTSECTOR NewBootSector
;
1849 // USHORT BackupBootSector;
1852 /* Allocate buffer for original bootsector */
1853 OrigBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
1854 if (OrigBootSector
== NULL
)
1855 return STATUS_INSUFFICIENT_RESOURCES
;
1857 /* Read current boot sector into buffer */
1858 RtlInitUnicodeString(&Name
, RootPath
);
1860 InitializeObjectAttributes(&ObjectAttributes
,
1862 OBJ_CASE_INSENSITIVE
,
1866 Status
= NtOpenFile(&FileHandle
,
1867 GENERIC_READ
| SYNCHRONIZE
,
1871 FILE_SYNCHRONOUS_IO_NONALERT
);
1872 if (!NT_SUCCESS(Status
))
1874 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1878 FileOffset
.QuadPart
= 0ULL;
1879 Status
= NtReadFile(FileHandle
,
1888 NtClose(FileHandle
);
1889 if (!NT_SUCCESS(Status
))
1891 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1896 /* Allocate buffer for new bootsector */
1897 NewBootSector
= RtlAllocateHeap(ProcessHeap
, 0, sizeof(EXT2_BOOTSECTOR
));
1898 if (NewBootSector
== NULL
)
1900 // RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1901 return STATUS_INSUFFICIENT_RESOURCES
;
1904 /* Read new bootsector from SrcPath */
1905 RtlInitUnicodeString(&Name
, SrcPath
);
1907 InitializeObjectAttributes(&ObjectAttributes
,
1909 OBJ_CASE_INSENSITIVE
,
1913 Status
= NtOpenFile(&FileHandle
,
1914 GENERIC_READ
| SYNCHRONIZE
,
1918 FILE_SYNCHRONOUS_IO_NONALERT
);
1919 if (!NT_SUCCESS(Status
))
1921 // RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1922 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1926 Status
= NtReadFile(FileHandle
,
1932 sizeof(EXT2_BOOTSECTOR
),
1935 NtClose(FileHandle
);
1936 if (!NT_SUCCESS(Status
))
1938 // RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1939 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1944 /* Adjust bootsector (copy a part of the FAT32 BPB) */
1945 memcpy(&NewBootSector
->OemName
,
1946 &OrigBootSector
->OemName
,
1947 FIELD_OFFSET(FAT32_BOOTSECTOR
, BootCodeAndData
) -
1948 FIELD_OFFSET(FAT32_BOOTSECTOR
, OemName
));
1950 NewBootSector
->HiddenSectors
= PartitionList
->CurrentDisk
->SectorsPerTrack
;
1952 /* Get the location of the backup boot sector */
1953 BackupBootSector
= OrigBootSector
->BackupBootSector
;
1955 /* Free the original boot sector */
1956 // RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1959 /* Write new bootsector to RootPath */
1960 RtlInitUnicodeString(&Name
, RootPath
);
1962 InitializeObjectAttributes(&ObjectAttributes
,
1968 Status
= NtOpenFile(&FileHandle
,
1969 GENERIC_WRITE
| SYNCHRONIZE
,
1973 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1974 if (!NT_SUCCESS(Status
))
1976 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1977 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1981 /* Write sector 0 */
1982 FileOffset
.QuadPart
= 0ULL;
1983 Status
= NtWriteFile(FileHandle
,
1989 sizeof(EXT2_BOOTSECTOR
),
1993 if (!NT_SUCCESS(Status
))
1995 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1996 NtClose(FileHandle
);
1997 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
2001 /* Write backup boot sector */
2002 if ((BackupBootSector
!= 0x0000) && (BackupBootSector
!= 0xFFFF))
2004 FileOffset
.QuadPart
= (ULONGLONG
)((ULONG
)BackupBootSector
* SECTORSIZE
);
2005 Status
= NtWriteFile(FileHandle
,
2014 if (!NT_SUCCESS(Status
))
2016 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
2017 NtClose(FileHandle
);
2018 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
2023 /* Write sector 14 */
2024 FileOffset
.QuadPart
= 14 * SECTORSIZE
;
2025 Status
= NtWriteFile(FileHandle
,
2030 ((PUCHAR
)NewBootSector
+ SECTORSIZE
),
2034 if (!NT_SUCCESS(Status
))
2036 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
2039 NtClose(FileHandle
);
2041 /* Free the new boot sector */
2042 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
2054 UNICODE_STRING Name
;
2055 OBJECT_ATTRIBUTES ObjectAttributes
;
2056 IO_STATUS_BLOCK IoStatusBlock
;
2057 FILE_BASIC_INFORMATION FileInfo
;
2060 RtlInitUnicodeString(&Name
, FileName
);
2062 InitializeObjectAttributes(&ObjectAttributes
,
2064 OBJ_CASE_INSENSITIVE
,
2068 Status
= NtOpenFile(&FileHandle
,
2069 GENERIC_READ
| GENERIC_WRITE
| SYNCHRONIZE
,
2073 FILE_SYNCHRONOUS_IO_NONALERT
);
2074 if (Status
== STATUS_NO_SUCH_FILE
)
2076 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
2078 return STATUS_SUCCESS
;
2080 if (!NT_SUCCESS(Status
))
2082 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
2086 Status
= NtQueryInformationFile(FileHandle
,
2089 sizeof(FILE_BASIC_INFORMATION
),
2090 FileBasicInformation
);
2091 if (!NT_SUCCESS(Status
))
2093 DPRINT1("NtQueryInformationFile() failed (Status %lx)\n", Status
);
2094 NtClose(FileHandle
);
2098 *Attributes
= FileInfo
.FileAttributes
;
2100 /* Delete attributes SYSTEM, HIDDEN and READONLY */
2101 FileInfo
.FileAttributes
= FileInfo
.FileAttributes
&
2102 ~(FILE_ATTRIBUTE_SYSTEM
|
2103 FILE_ATTRIBUTE_HIDDEN
|
2104 FILE_ATTRIBUTE_READONLY
);
2106 Status
= NtSetInformationFile(FileHandle
,
2109 sizeof(FILE_BASIC_INFORMATION
),
2110 FileBasicInformation
);
2111 if (!NT_SUCCESS(Status
))
2113 DPRINT1("NtSetInformationFile() failed (Status %lx)\n", Status
);
2116 NtClose(FileHandle
);
2127 UNICODE_STRING Name
;
2128 OBJECT_ATTRIBUTES ObjectAttributes
;
2129 IO_STATUS_BLOCK IoStatusBlock
;
2130 FILE_BASIC_INFORMATION FileInfo
;
2133 RtlInitUnicodeString(&Name
, FileName
);
2135 InitializeObjectAttributes(&ObjectAttributes
,
2137 OBJ_CASE_INSENSITIVE
,
2141 Status
= NtOpenFile(&FileHandle
,
2142 GENERIC_READ
| GENERIC_WRITE
| SYNCHRONIZE
,
2146 FILE_SYNCHRONOUS_IO_NONALERT
);
2147 if (!NT_SUCCESS(Status
))
2149 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
2153 Status
= NtQueryInformationFile(FileHandle
,
2156 sizeof(FILE_BASIC_INFORMATION
),
2157 FileBasicInformation
);
2158 if (!NT_SUCCESS(Status
))
2160 DPRINT1("NtQueryInformationFile() failed (Status %lx)\n", Status
);
2161 NtClose(FileHandle
);
2165 FileInfo
.FileAttributes
= FileInfo
.FileAttributes
| Attributes
;
2167 Status
= NtSetInformationFile(FileHandle
,
2170 sizeof(FILE_BASIC_INFORMATION
),
2171 FileBasicInformation
);
2172 if (!NT_SUCCESS(Status
))
2174 DPRINT1("NtSetInformationFile() failed (Status %lx)\n", Status
);
2177 NtClose(FileHandle
);
2189 PINICACHE Cache
= NULL
;
2190 PINICACHESECTION Section
= NULL
;
2191 ULONG FileAttribute
;
2192 PWCHAR OldValue
= NULL
;
2194 Status
= IniCacheLoad(&Cache
, BootIniPath
, FALSE
);
2195 if (!NT_SUCCESS(Status
))
2200 Section
= IniCacheGetSection(Cache
,
2201 L
"operating systems");
2202 if (Section
== NULL
)
2204 IniCacheDestroy(Cache
);
2205 return STATUS_UNSUCCESSFUL
;
2208 /* Check - maybe record already exists */
2209 Status
= IniCacheGetKey(Section
, EntryName
, &OldValue
);
2211 /* If either key was not found, or contains something else - add new one */
2212 if (!NT_SUCCESS(Status
) || wcscmp(OldValue
, EntryValue
))
2214 IniCacheInsertKey(Section
,
2221 Status
= UnprotectBootIni(BootIniPath
,
2223 if (!NT_SUCCESS(Status
))
2225 IniCacheDestroy(Cache
);
2229 Status
= IniCacheSave(Cache
, BootIniPath
);
2230 if (!NT_SUCCESS(Status
))
2232 IniCacheDestroy(Cache
);
2236 FileAttribute
|= (FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
| FILE_ATTRIBUTE_READONLY
);
2237 Status
= ProtectBootIni(BootIniPath
, FileAttribute
);
2239 IniCacheDestroy(Cache
);
2246 InstallFatBootcodeToPartition(
2247 PUNICODE_STRING SystemRootPath
,
2248 PUNICODE_STRING SourceRootPath
,
2249 PUNICODE_STRING DestinationArcPath
,
2250 UCHAR PartitionType
)
2253 BOOLEAN DoesFreeLdrExist
;
2254 WCHAR SrcPath
[MAX_PATH
];
2255 WCHAR DstPath
[MAX_PATH
];
2257 /* FAT or FAT32 partition */
2258 DPRINT("System path: '%wZ'\n", SystemRootPath
);
2260 /* Copy FreeLoader to the system partition */
2261 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2262 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
2263 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2264 wcscat(DstPath
, L
"\\freeldr.sys");
2266 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2267 Status
= SetupCopyFile(SrcPath
, DstPath
);
2268 if (!NT_SUCCESS(Status
))
2270 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
2274 /* Prepare for possibly copying 'freeldr.ini' */
2275 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2276 wcscat(DstPath
, L
"\\freeldr.ini");
2278 DoesFreeLdrExist
= DoesFileExist(NULL
, SystemRootPath
->Buffer
, L
"freeldr.ini");
2279 if (DoesFreeLdrExist
)
2281 /* Update existing 'freeldr.ini' */
2282 DPRINT1("Update existing 'freeldr.ini'\n");
2284 Status
= UpdateFreeLoaderIni(DstPath
, DestinationArcPath
->Buffer
);
2285 if (!NT_SUCCESS(Status
))
2287 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
2292 /* Check for NT and other bootloaders */
2294 // FIXME: Check for Vista+ bootloader!
2295 if (DoesFileExist(NULL
, SystemRootPath
->Buffer
, L
"ntldr") == TRUE
||
2296 DoesFileExist(NULL
, SystemRootPath
->Buffer
, L
"boot.ini") == TRUE
)
2298 /* Search root directory for 'ntldr' and 'boot.ini' */
2299 DPRINT1("Found Microsoft Windows NT/2000/XP boot loader\n");
2301 /* Create or update 'freeldr.ini' */
2302 if (DoesFreeLdrExist
== FALSE
)
2304 /* Create new 'freeldr.ini' */
2305 DPRINT1("Create new 'freeldr.ini'\n");
2306 // wcscpy(DstPath, SystemRootPath->Buffer);
2307 // wcscat(DstPath, L"\\freeldr.ini");
2309 Status
= CreateFreeLoaderIniForReactOS(DstPath
, DestinationArcPath
->Buffer
);
2310 if (!NT_SUCCESS(Status
))
2312 DPRINT1("CreateFreeLoaderIniForReactOS() failed (Status %lx)\n", Status
);
2316 /* Install new bootcode into a file */
2317 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2318 wcscat(DstPath
, L
"\\bootsect.ros");
2320 if (PartitionType
== PARTITION_FAT32
||
2321 PartitionType
== PARTITION_FAT32_XINT13
)
2323 /* Install FAT32 bootcode */
2324 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2325 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
2327 DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, DstPath
);
2328 Status
= InstallFat32BootCodeToFile(SrcPath
, DstPath
,
2329 SystemRootPath
->Buffer
);
2330 if (!NT_SUCCESS(Status
))
2332 DPRINT1("InstallFat32BootCodeToFile() failed (Status %lx)\n", Status
);
2338 /* Install FAT16 bootcode */
2339 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2340 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2342 DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath
, DstPath
);
2343 Status
= InstallFat16BootCodeToFile(SrcPath
, DstPath
,
2344 SystemRootPath
->Buffer
);
2345 if (!NT_SUCCESS(Status
))
2347 DPRINT1("InstallFat16BootCodeToFile() failed (Status %lx)\n", Status
);
2353 /* Update 'boot.ini' */
2354 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2355 wcscat(DstPath
, L
"\\boot.ini");
2357 DPRINT1("Update 'boot.ini': %S\n", DstPath
);
2358 Status
= UpdateBootIni(DstPath
,
2359 L
"C:\\bootsect.ros",
2361 if (!NT_SUCCESS(Status
))
2363 DPRINT1("UpdateBootIni() failed (Status %lx)\n", Status
);
2369 /* Non-NT bootloaders: install our own bootloader */
2374 PWCHAR BootPartition
;
2376 PWCHAR BootSectorFileName
;
2378 if (DoesFileExist(NULL
, SystemRootPath
->Buffer
, L
"io.sys") == TRUE
||
2379 DoesFileExist(NULL
, SystemRootPath
->Buffer
, L
"msdos.sys") == TRUE
)
2381 /* Search for root directory for 'io.sys' and 'msdos.sys' */
2382 DPRINT1("Found Microsoft DOS or Windows 9x boot loader\n");
2385 Description
= L
"\"DOS/Windows\"";
2387 BootPartition
= L
"1";
2388 BootSector
= L
"BOOTSECT.DOS";
2390 BootSectorFileName
= L
"\\bootsect.dos";
2393 if (DoesFileExist(NULL
, SystemRootPath
->Buffer
, L
"kernel.sys") == TRUE
)
2395 /* Search for root directory for 'kernel.sys' */
2396 DPRINT1("Found FreeDOS boot loader\n");
2399 Description
= L
"\"FreeDOS\"";
2401 BootPartition
= L
"1";
2402 BootSector
= L
"BOOTSECT.DOS";
2404 BootSectorFileName
= L
"\\bootsect.dos";
2408 /* No or unknown boot loader */
2409 DPRINT1("No or unknown boot loader found\n");
2411 Section
= L
"Unknown";
2412 Description
= L
"\"Unknown Operating System\"";
2414 BootPartition
= L
"1";
2415 BootSector
= L
"BOOTSECT.OLD";
2417 BootSectorFileName
= L
"\\bootsect.old";
2420 /* Create or update 'freeldr.ini' */
2421 if (DoesFreeLdrExist
== FALSE
)
2423 /* Create new 'freeldr.ini' */
2424 DPRINT1("Create new 'freeldr.ini'\n");
2425 // wcscpy(DstPath, SystemRootPath->Buffer);
2426 // wcscat(DstPath, L"\\freeldr.ini");
2428 if (IsThereAValidBootSector(SystemRootPath
->Buffer
))
2430 Status
= CreateFreeLoaderIniForReactOSAndBootSector(
2431 DstPath
, DestinationArcPath
->Buffer
,
2432 Section
, Description
,
2433 BootDrive
, BootPartition
, BootSector
);
2434 if (!NT_SUCCESS(Status
))
2436 DPRINT1("CreateFreeLoaderIniForReactOSAndBootSector() failed (Status %lx)\n", Status
);
2440 /* Save current bootsector */
2441 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2442 wcscat(DstPath
, BootSectorFileName
);
2444 DPRINT1("Save bootsector: %S ==> %S\n", SystemRootPath
->Buffer
, DstPath
);
2445 Status
= SaveBootSector(SystemRootPath
->Buffer
, DstPath
, SECTORSIZE
);
2446 if (!NT_SUCCESS(Status
))
2448 DPRINT1("SaveBootSector() failed (Status %lx)\n", Status
);
2454 Status
= CreateFreeLoaderIniForReactOS(DstPath
, DestinationArcPath
->Buffer
);
2455 if (!NT_SUCCESS(Status
))
2457 DPRINT1("CreateFreeLoaderIniForReactOS() failed (Status %lx)\n", Status
);
2462 /* Install new bootsector on the disk */
2463 if (PartitionType
== PARTITION_FAT32
||
2464 PartitionType
== PARTITION_FAT32_XINT13
)
2466 /* Install FAT32 bootcode */
2467 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2468 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
2470 DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2471 Status
= InstallFat32BootCodeToDisk(SrcPath
, SystemRootPath
->Buffer
);
2472 if (!NT_SUCCESS(Status
))
2474 DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)\n", Status
);
2480 /* Install FAT16 bootcode */
2481 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2482 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2484 DPRINT1("Install FAT16 bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2485 Status
= InstallFat16BootCodeToDisk(SrcPath
, SystemRootPath
->Buffer
);
2486 if (!NT_SUCCESS(Status
))
2488 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status
);
2495 return STATUS_SUCCESS
;
2500 InstallExt2BootcodeToPartition(
2501 PUNICODE_STRING SystemRootPath
,
2502 PUNICODE_STRING SourceRootPath
,
2503 PUNICODE_STRING DestinationArcPath
,
2504 UCHAR PartitionType
)
2507 BOOLEAN DoesFreeLdrExist
;
2508 WCHAR SrcPath
[MAX_PATH
];
2509 WCHAR DstPath
[MAX_PATH
];
2511 /* EXT2 partition */
2512 DPRINT("System path: '%wZ'\n", SystemRootPath
);
2514 /* Copy FreeLoader to the system partition */
2515 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2516 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
2517 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2518 wcscat(DstPath
, L
"\\freeldr.sys");
2520 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2521 Status
= SetupCopyFile(SrcPath
, DstPath
);
2522 if (!NT_SUCCESS(Status
))
2524 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
2528 /* Prepare for possibly copying 'freeldr.ini' */
2529 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2530 wcscat(DstPath
, L
"\\freeldr.ini");
2532 DoesFreeLdrExist
= DoesFileExist(NULL
, SystemRootPath
->Buffer
, L
"freeldr.ini");
2533 if (DoesFreeLdrExist
)
2535 /* Update existing 'freeldr.ini' */
2536 DPRINT1("Update existing 'freeldr.ini'\n");
2538 Status
= UpdateFreeLoaderIni(DstPath
, DestinationArcPath
->Buffer
);
2539 if (!NT_SUCCESS(Status
))
2541 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
2546 /* Check for *nix bootloaders */
2548 /* Create or update 'freeldr.ini' */
2549 if (DoesFreeLdrExist
== FALSE
)
2551 /* Create new 'freeldr.ini' */
2552 DPRINT1("Create new 'freeldr.ini'\n");
2553 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2554 wcscat(DstPath
, L
"\\freeldr.ini");
2556 /* Certainly SysLinux, GRUB, LILO... or an unknown boot loader */
2557 DPRINT1("*nix or unknown boot loader found\n");
2559 if (IsThereAValidBootSector(SystemRootPath
->Buffer
))
2561 Status
= CreateFreeLoaderIniForReactOSAndBootSector(
2562 DstPath
, DestinationArcPath
->Buffer
,
2563 L
"Linux", L
"\"Linux\"",
2564 L
"hd0", L
"1", L
"BOOTSECT.OLD");
2565 if (!NT_SUCCESS(Status
))
2567 DPRINT1("CreateFreeLoaderIniForReactOSAndBootSector() failed (Status %lx)\n", Status
);
2571 /* Save current bootsector */
2572 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2573 wcscat(DstPath
, L
"\\bootsect.old");
2575 DPRINT1("Save bootsector: %S ==> %S\n", SystemRootPath
->Buffer
, DstPath
);
2576 Status
= SaveBootSector(SystemRootPath
->Buffer
, DstPath
, sizeof(EXT2_BOOTSECTOR
));
2577 if (!NT_SUCCESS(Status
))
2579 DPRINT1("SaveBootSector() failed (Status %lx)\n", Status
);
2585 Status
= CreateFreeLoaderIniForReactOS(DstPath
, DestinationArcPath
->Buffer
);
2586 if (!NT_SUCCESS(Status
))
2588 DPRINT1("CreateFreeLoaderIniForReactOS() failed (Status %lx)\n", Status
);
2593 /* Install new bootsector on the disk */
2594 // if (PartitionType == PARTITION_EXT2)
2596 /* Install EXT2 bootcode */
2597 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2598 wcscat(SrcPath
, L
"\\loader\\ext2.bin");
2600 DPRINT1("Install EXT2 bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2601 Status
= InstallExt2BootCodeToDisk(SrcPath
, SystemRootPath
->Buffer
);
2602 if (!NT_SUCCESS(Status
))
2604 DPRINT1("InstallExt2BootCodeToDisk() failed (Status %lx)\n", Status
);
2610 return STATUS_SUCCESS
;
2615 InstallVBRToPartition(
2616 PUNICODE_STRING SystemRootPath
,
2617 PUNICODE_STRING SourceRootPath
,
2618 PUNICODE_STRING DestinationArcPath
,
2619 UCHAR PartitionType
)
2621 switch (PartitionType
)
2623 case PARTITION_FAT_12
:
2624 case PARTITION_FAT_16
:
2625 case PARTITION_HUGE
:
2626 case PARTITION_XINT13
:
2627 case PARTITION_FAT32
:
2628 case PARTITION_FAT32_XINT13
:
2630 return InstallFatBootcodeToPartition(SystemRootPath
,
2636 case PARTITION_EXT2
:
2638 return InstallExt2BootcodeToPartition(SystemRootPath
,
2648 DPRINT1("PartitionType 0x%02X unknown!\n", PartitionType
);
2652 return STATUS_UNSUCCESSFUL
;
2657 InstallFatBootcodeToFloppy(
2658 PUNICODE_STRING SourceRootPath
,
2659 PUNICODE_STRING DestinationArcPath
)
2663 UNICODE_STRING FloppyDevice
= RTL_CONSTANT_STRING(L
"\\Device\\Floppy0");
2664 WCHAR SrcPath
[MAX_PATH
];
2665 WCHAR DstPath
[MAX_PATH
];
2667 /* Format the floppy first */
2668 FatFS
= GetFileSystemByName(L
"FAT");
2671 DPRINT1("FAT FS non existent on this system?!\n");
2672 return STATUS_NOT_SUPPORTED
;
2674 Status
= FatFS
->FormatFunc(&FloppyDevice
,
2680 if (!NT_SUCCESS(Status
))
2682 DPRINT1("VfatFormat() failed (Status %lx)\n", Status
);
2686 /* Copy FreeLoader to the boot partition */
2687 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2688 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
2690 wcscpy(DstPath
, L
"\\Device\\Floppy0\\freeldr.sys");
2692 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2693 Status
= SetupCopyFile(SrcPath
, DstPath
);
2694 if (!NT_SUCCESS(Status
))
2696 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
2700 /* Create new 'freeldr.ini' */
2701 wcscpy(DstPath
, L
"\\Device\\Floppy0\\freeldr.ini");
2703 DPRINT("Create new 'freeldr.ini'\n");
2704 Status
= CreateFreeLoaderIniForReactOS(DstPath
, DestinationArcPath
->Buffer
);
2705 if (!NT_SUCCESS(Status
))
2707 DPRINT1("CreateFreeLoaderIniForReactOS() failed (Status %lx)\n", Status
);
2711 /* Install FAT12/16 boosector */
2712 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2713 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2715 wcscpy(DstPath
, L
"\\Device\\Floppy0");
2717 DPRINT("Install FAT bootcode: %S ==> %S\n", SrcPath
, DstPath
);
2718 Status
= InstallFat12BootCodeToFloppy(SrcPath
, DstPath
);
2719 if (!NT_SUCCESS(Status
))
2721 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status
);
2725 return STATUS_SUCCESS
;