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
6 * PROGRAMMER: Eric Kohl
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 * Check the first DWORD (4 bytes) of the bootsector for a potential
634 * "valid" instruction (the BIOS starts execution of the bootsector
635 * at its beginning). Currently the criterium is that this DWORD must
641 OBJECT_ATTRIBUTES ObjectAttributes
;
642 IO_STATUS_BLOCK IoStatusBlock
;
644 LARGE_INTEGER FileOffset
;
648 /* Allocate buffer for bootsector */
649 BootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
650 if (BootSector
== NULL
)
651 return FALSE
; // STATUS_INSUFFICIENT_RESOURCES;
653 /* Read current boot sector into buffer */
654 RtlInitUnicodeString(&Name
, RootPath
);
656 InitializeObjectAttributes(&ObjectAttributes
,
658 OBJ_CASE_INSENSITIVE
,
662 Status
= NtOpenFile(&FileHandle
,
663 GENERIC_READ
| SYNCHRONIZE
,
667 FILE_SYNCHRONOUS_IO_NONALERT
);
668 if (!NT_SUCCESS(Status
))
670 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
671 return FALSE
; // Status;
674 FileOffset
.QuadPart
= 0ULL;
675 Status
= NtReadFile(FileHandle
,
686 Instruction
= *(PULONG
)BootSector
;
688 /* Free the boot sector */
689 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
691 if (!NT_SUCCESS(Status
))
692 return FALSE
; // Status;
694 return (Instruction
!= 0x00000000);
705 OBJECT_ATTRIBUTES ObjectAttributes
;
706 IO_STATUS_BLOCK IoStatusBlock
;
708 LARGE_INTEGER FileOffset
;
711 /* Allocate buffer for bootsector */
712 BootSector
= RtlAllocateHeap(ProcessHeap
, 0, Length
);
713 if (BootSector
== NULL
)
714 return STATUS_INSUFFICIENT_RESOURCES
;
716 /* Read current boot sector into buffer */
717 RtlInitUnicodeString(&Name
, RootPath
);
719 InitializeObjectAttributes(&ObjectAttributes
,
721 OBJ_CASE_INSENSITIVE
,
725 Status
= NtOpenFile(&FileHandle
,
726 GENERIC_READ
| SYNCHRONIZE
,
730 FILE_SYNCHRONOUS_IO_NONALERT
);
731 if (!NT_SUCCESS(Status
))
733 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
737 FileOffset
.QuadPart
= 0ULL;
738 Status
= NtReadFile(FileHandle
,
748 if (!NT_SUCCESS(Status
))
750 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
754 /* Write bootsector to DstPath */
755 RtlInitUnicodeString(&Name
, DstPath
);
757 InitializeObjectAttributes(&ObjectAttributes
,
763 Status
= NtCreateFile(&FileHandle
,
764 GENERIC_WRITE
| SYNCHRONIZE
,
768 FILE_ATTRIBUTE_NORMAL
,
771 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
,
774 if (!NT_SUCCESS(Status
))
776 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
780 Status
= NtWriteFile(FileHandle
,
791 /* Free the boot sector */
792 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
799 InstallFat16BootCodeToFile(
806 OBJECT_ATTRIBUTES ObjectAttributes
;
807 IO_STATUS_BLOCK IoStatusBlock
;
809 LARGE_INTEGER FileOffset
;
810 PFAT_BOOTSECTOR OrigBootSector
;
811 PFAT_BOOTSECTOR NewBootSector
;
813 /* Allocate buffer for original bootsector */
814 OrigBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
815 if (OrigBootSector
== NULL
)
816 return STATUS_INSUFFICIENT_RESOURCES
;
818 /* Read current boot sector into buffer */
819 RtlInitUnicodeString(&Name
, RootPath
);
821 InitializeObjectAttributes(&ObjectAttributes
,
823 OBJ_CASE_INSENSITIVE
,
827 Status
= NtOpenFile(&FileHandle
,
828 GENERIC_READ
| SYNCHRONIZE
,
832 FILE_SYNCHRONOUS_IO_NONALERT
);
833 if (!NT_SUCCESS(Status
))
835 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
839 FileOffset
.QuadPart
= 0ULL;
840 Status
= NtReadFile(FileHandle
,
850 if (!NT_SUCCESS(Status
))
852 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
856 /* Allocate buffer for new bootsector */
857 NewBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
858 if (NewBootSector
== NULL
)
860 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
861 return STATUS_INSUFFICIENT_RESOURCES
;
864 /* Read new bootsector from SrcPath */
865 RtlInitUnicodeString(&Name
, SrcPath
);
867 InitializeObjectAttributes(&ObjectAttributes
,
869 OBJ_CASE_INSENSITIVE
,
873 Status
= NtOpenFile(&FileHandle
,
874 GENERIC_READ
| SYNCHRONIZE
,
878 FILE_SYNCHRONOUS_IO_NONALERT
);
879 if (!NT_SUCCESS(Status
))
881 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
882 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
886 FileOffset
.QuadPart
= 0ULL;
887 Status
= NtReadFile(FileHandle
,
897 if (!NT_SUCCESS(Status
))
899 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
900 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
904 /* Adjust bootsector (copy a part of the FAT BPB) */
905 memcpy(&NewBootSector
->OemName
,
906 &OrigBootSector
->OemName
,
907 FIELD_OFFSET(FAT_BOOTSECTOR
, BootCodeAndData
) -
908 FIELD_OFFSET(FAT_BOOTSECTOR
, OemName
));
910 /* Free the original boot sector */
911 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
913 /* Write new bootsector to DstPath */
914 RtlInitUnicodeString(&Name
, DstPath
);
916 InitializeObjectAttributes(&ObjectAttributes
,
922 Status
= NtCreateFile(&FileHandle
,
923 GENERIC_WRITE
| SYNCHRONIZE
,
927 FILE_ATTRIBUTE_NORMAL
,
930 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
,
933 if (!NT_SUCCESS(Status
))
935 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
939 FileOffset
.QuadPart
= 0ULL;
940 Status
= NtWriteFile(FileHandle
,
951 /* Free the new boot sector */
952 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
959 InstallFat32BootCodeToFile(
966 OBJECT_ATTRIBUTES ObjectAttributes
;
967 IO_STATUS_BLOCK IoStatusBlock
;
969 LARGE_INTEGER FileOffset
;
970 PFAT32_BOOTSECTOR OrigBootSector
;
971 PFAT32_BOOTSECTOR NewBootSector
;
973 /* Allocate buffer for original bootsector */
974 OrigBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
975 if (OrigBootSector
== NULL
)
976 return STATUS_INSUFFICIENT_RESOURCES
;
978 /* Read current boot sector into buffer */
979 RtlInitUnicodeString(&Name
, RootPath
);
981 InitializeObjectAttributes(&ObjectAttributes
,
983 OBJ_CASE_INSENSITIVE
,
987 Status
= NtOpenFile(&FileHandle
,
988 GENERIC_READ
| SYNCHRONIZE
,
992 FILE_SYNCHRONOUS_IO_NONALERT
);
993 if (!NT_SUCCESS(Status
))
995 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
999 FileOffset
.QuadPart
= 0ULL;
1000 Status
= NtReadFile(FileHandle
,
1009 NtClose(FileHandle
);
1010 if (!NT_SUCCESS(Status
))
1012 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1016 /* Allocate buffer for new bootsector (2 sectors) */
1017 NewBootSector
= RtlAllocateHeap(ProcessHeap
, 0, 2 * SECTORSIZE
);
1018 if (NewBootSector
== NULL
)
1020 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1021 return STATUS_INSUFFICIENT_RESOURCES
;
1024 /* Read new bootsector from SrcPath */
1025 RtlInitUnicodeString(&Name
, SrcPath
);
1027 InitializeObjectAttributes(&ObjectAttributes
,
1029 OBJ_CASE_INSENSITIVE
,
1033 Status
= NtOpenFile(&FileHandle
,
1034 GENERIC_READ
| SYNCHRONIZE
,
1038 FILE_SYNCHRONOUS_IO_NONALERT
);
1039 if (!NT_SUCCESS(Status
))
1041 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1042 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1046 Status
= NtReadFile(FileHandle
,
1055 NtClose(FileHandle
);
1056 if (!NT_SUCCESS(Status
))
1058 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1059 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1063 /* Adjust bootsector (copy a part of the FAT32 BPB) */
1064 memcpy(&NewBootSector
->OemName
,
1065 &OrigBootSector
->OemName
,
1066 FIELD_OFFSET(FAT32_BOOTSECTOR
, BootCodeAndData
) -
1067 FIELD_OFFSET(FAT32_BOOTSECTOR
, OemName
));
1069 /* Disable the backup boot sector */
1070 NewBootSector
->BackupBootSector
= 0;
1072 /* Free the original boot sector */
1073 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1075 /* Write the first sector of the new bootcode to DstPath */
1076 RtlInitUnicodeString(&Name
, DstPath
);
1078 InitializeObjectAttributes(&ObjectAttributes
,
1084 Status
= NtCreateFile(&FileHandle
,
1085 GENERIC_WRITE
| SYNCHRONIZE
,
1089 FILE_ATTRIBUTE_NORMAL
,
1092 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
,
1095 if (!NT_SUCCESS(Status
))
1097 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1101 FileOffset
.QuadPart
= 0ULL;
1102 Status
= NtWriteFile(FileHandle
,
1111 NtClose(FileHandle
);
1112 if (!NT_SUCCESS(Status
))
1114 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1118 /* Write the second sector of the new bootcode to boot disk sector 14 */
1119 RtlInitUnicodeString(&Name
, RootPath
);
1121 InitializeObjectAttributes(&ObjectAttributes
,
1127 Status
= NtOpenFile(&FileHandle
,
1128 GENERIC_WRITE
| SYNCHRONIZE
,
1132 FILE_SYNCHRONOUS_IO_NONALERT
);
1133 if (!NT_SUCCESS(Status
))
1135 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1139 FileOffset
.QuadPart
= (ULONGLONG
)(14 * SECTORSIZE
);
1140 Status
= NtWriteFile(FileHandle
,
1145 ((PUCHAR
)NewBootSector
+ SECTORSIZE
),
1149 if (!NT_SUCCESS(Status
))
1152 NtClose(FileHandle
);
1154 /* Free the new boot sector */
1155 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1162 InstallMbrBootCodeToDisk(
1167 UNICODE_STRING Name
;
1168 OBJECT_ATTRIBUTES ObjectAttributes
;
1169 IO_STATUS_BLOCK IoStatusBlock
;
1171 LARGE_INTEGER FileOffset
;
1172 PPARTITION_SECTOR OrigBootSector
;
1173 PPARTITION_SECTOR NewBootSector
;
1175 /* Allocate buffer for original bootsector */
1176 OrigBootSector
= (PPARTITION_SECTOR
)RtlAllocateHeap(ProcessHeap
,
1178 sizeof(PARTITION_SECTOR
));
1179 if (OrigBootSector
== NULL
)
1180 return STATUS_INSUFFICIENT_RESOURCES
;
1182 /* Read current boot sector into buffer */
1183 RtlInitUnicodeString(&Name
,
1186 InitializeObjectAttributes(&ObjectAttributes
,
1188 OBJ_CASE_INSENSITIVE
,
1192 Status
= NtOpenFile(&FileHandle
,
1193 GENERIC_READ
| SYNCHRONIZE
,
1197 FILE_SYNCHRONOUS_IO_NONALERT
);
1198 if (!NT_SUCCESS(Status
))
1200 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1204 FileOffset
.QuadPart
= 0ULL;
1205 Status
= NtReadFile(FileHandle
,
1211 sizeof(PARTITION_SECTOR
),
1214 NtClose(FileHandle
);
1215 if (!NT_SUCCESS(Status
))
1217 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1221 /* Allocate buffer for new bootsector */
1222 NewBootSector
= (PPARTITION_SECTOR
)RtlAllocateHeap(ProcessHeap
,
1224 sizeof(PARTITION_SECTOR
));
1225 if (NewBootSector
== NULL
)
1227 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1228 return STATUS_INSUFFICIENT_RESOURCES
;
1231 /* Read new bootsector from SrcPath */
1232 RtlInitUnicodeString(&Name
, SrcPath
);
1234 InitializeObjectAttributes(&ObjectAttributes
,
1236 OBJ_CASE_INSENSITIVE
,
1240 Status
= NtOpenFile(&FileHandle
,
1241 GENERIC_READ
| SYNCHRONIZE
,
1245 FILE_SYNCHRONOUS_IO_NONALERT
);
1246 if (!NT_SUCCESS(Status
))
1248 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1249 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1253 Status
= NtReadFile(FileHandle
,
1259 sizeof(PARTITION_SECTOR
),
1262 NtClose(FileHandle
);
1263 if (!NT_SUCCESS(Status
))
1265 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1266 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1270 /* Copy partition table from old MBR to new */
1271 RtlCopyMemory(&NewBootSector
->Signature
,
1272 &OrigBootSector
->Signature
,
1273 sizeof(PARTITION_SECTOR
) - offsetof(PARTITION_SECTOR
, Signature
) /* Length of partition table */);
1275 /* Free the original boot sector */
1276 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1278 /* Write new bootsector to RootPath */
1279 RtlInitUnicodeString(&Name
, RootPath
);
1281 InitializeObjectAttributes(&ObjectAttributes
,
1287 Status
= NtOpenFile(&FileHandle
,
1288 GENERIC_WRITE
| SYNCHRONIZE
,
1292 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1293 if (!NT_SUCCESS(Status
))
1295 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1296 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1300 FileOffset
.QuadPart
= 0ULL;
1301 Status
= NtWriteFile(FileHandle
,
1307 sizeof(PARTITION_SECTOR
),
1310 NtClose(FileHandle
);
1312 /* Free the new boot sector */
1313 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1320 InstallFat12BootCodeToFloppy(
1325 UNICODE_STRING Name
;
1326 OBJECT_ATTRIBUTES ObjectAttributes
;
1327 IO_STATUS_BLOCK IoStatusBlock
;
1329 LARGE_INTEGER FileOffset
;
1330 PFAT_BOOTSECTOR OrigBootSector
;
1331 PFAT_BOOTSECTOR NewBootSector
;
1333 /* Allocate buffer for original bootsector */
1334 OrigBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
1335 if (OrigBootSector
== NULL
)
1336 return STATUS_INSUFFICIENT_RESOURCES
;
1338 /* Read current boot sector into buffer */
1339 RtlInitUnicodeString(&Name
, RootPath
);
1341 InitializeObjectAttributes(&ObjectAttributes
,
1343 OBJ_CASE_INSENSITIVE
,
1347 Status
= NtOpenFile(&FileHandle
,
1348 GENERIC_READ
| SYNCHRONIZE
,
1352 FILE_SYNCHRONOUS_IO_NONALERT
);
1353 if (!NT_SUCCESS(Status
))
1355 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1359 FileOffset
.QuadPart
= 0ULL;
1360 Status
= NtReadFile(FileHandle
,
1369 NtClose(FileHandle
);
1370 if (!NT_SUCCESS(Status
))
1372 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1376 /* Allocate buffer for new bootsector */
1377 NewBootSector
= RtlAllocateHeap(ProcessHeap
,
1380 if (NewBootSector
== NULL
)
1382 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1383 return STATUS_INSUFFICIENT_RESOURCES
;
1386 /* Read new bootsector from SrcPath */
1387 RtlInitUnicodeString(&Name
, SrcPath
);
1389 InitializeObjectAttributes(&ObjectAttributes
,
1391 OBJ_CASE_INSENSITIVE
,
1395 Status
= NtOpenFile(&FileHandle
,
1396 GENERIC_READ
| SYNCHRONIZE
,
1400 FILE_SYNCHRONOUS_IO_NONALERT
);
1401 if (!NT_SUCCESS(Status
))
1403 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1404 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1408 Status
= NtReadFile(FileHandle
,
1417 NtClose(FileHandle
);
1418 if (!NT_SUCCESS(Status
))
1420 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1421 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1425 /* Adjust bootsector (copy a part of the FAT16 BPB) */
1426 memcpy(&NewBootSector
->OemName
,
1427 &OrigBootSector
->OemName
,
1428 FIELD_OFFSET(FAT_BOOTSECTOR
, BootCodeAndData
) -
1429 FIELD_OFFSET(FAT_BOOTSECTOR
, OemName
));
1431 /* Free the original boot sector */
1432 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1434 /* Write new bootsector to RootPath */
1435 RtlInitUnicodeString(&Name
, RootPath
);
1437 InitializeObjectAttributes(&ObjectAttributes
,
1443 Status
= NtOpenFile(&FileHandle
,
1444 GENERIC_WRITE
| SYNCHRONIZE
,
1448 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1449 if (!NT_SUCCESS(Status
))
1451 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1452 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1456 FileOffset
.QuadPart
= 0ULL;
1457 Status
= NtWriteFile(FileHandle
,
1466 NtClose(FileHandle
);
1468 /* Free the new boot sector */
1469 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1476 InstallFat16BootCodeToDisk(
1481 UNICODE_STRING Name
;
1482 OBJECT_ATTRIBUTES ObjectAttributes
;
1483 IO_STATUS_BLOCK IoStatusBlock
;
1485 LARGE_INTEGER FileOffset
;
1486 PFAT_BOOTSECTOR OrigBootSector
;
1487 PFAT_BOOTSECTOR NewBootSector
;
1489 /* Allocate buffer for original bootsector */
1490 OrigBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
1491 if (OrigBootSector
== NULL
)
1492 return STATUS_INSUFFICIENT_RESOURCES
;
1494 /* Read current boot sector into buffer */
1495 RtlInitUnicodeString(&Name
, RootPath
);
1497 InitializeObjectAttributes(&ObjectAttributes
,
1499 OBJ_CASE_INSENSITIVE
,
1503 Status
= NtOpenFile(&FileHandle
,
1504 GENERIC_READ
| SYNCHRONIZE
,
1508 FILE_SYNCHRONOUS_IO_NONALERT
);
1509 if (!NT_SUCCESS(Status
))
1511 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1515 FileOffset
.QuadPart
= 0ULL;
1516 Status
= NtReadFile(FileHandle
,
1525 NtClose(FileHandle
);
1526 if (!NT_SUCCESS(Status
))
1528 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1532 /* Allocate buffer for new bootsector */
1533 NewBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
1534 if (NewBootSector
== NULL
)
1536 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1537 return STATUS_INSUFFICIENT_RESOURCES
;
1540 /* Read new bootsector from SrcPath */
1541 RtlInitUnicodeString(&Name
, SrcPath
);
1543 InitializeObjectAttributes(&ObjectAttributes
,
1545 OBJ_CASE_INSENSITIVE
,
1549 Status
= NtOpenFile(&FileHandle
,
1550 GENERIC_READ
| SYNCHRONIZE
,
1554 FILE_SYNCHRONOUS_IO_NONALERT
);
1555 if (!NT_SUCCESS(Status
))
1557 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1558 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1562 Status
= NtReadFile(FileHandle
,
1571 NtClose(FileHandle
);
1572 if (!NT_SUCCESS(Status
))
1574 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1575 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1579 /* Adjust bootsector (copy a part of the FAT16 BPB) */
1580 memcpy(&NewBootSector
->OemName
,
1581 &OrigBootSector
->OemName
,
1582 FIELD_OFFSET(FAT_BOOTSECTOR
, BootCodeAndData
) -
1583 FIELD_OFFSET(FAT_BOOTSECTOR
, OemName
));
1585 /* Free the original boot sector */
1586 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1588 /* Write new bootsector to RootPath */
1589 RtlInitUnicodeString(&Name
, RootPath
);
1591 InitializeObjectAttributes(&ObjectAttributes
,
1597 Status
= NtOpenFile(&FileHandle
,
1598 GENERIC_WRITE
| SYNCHRONIZE
,
1602 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1603 if (!NT_SUCCESS(Status
))
1605 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1606 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1610 FileOffset
.QuadPart
= 0ULL;
1611 Status
= NtWriteFile(FileHandle
,
1620 NtClose(FileHandle
);
1622 /* Free the new boot sector */
1623 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1630 InstallFat32BootCodeToDisk(
1635 UNICODE_STRING Name
;
1636 OBJECT_ATTRIBUTES ObjectAttributes
;
1637 IO_STATUS_BLOCK IoStatusBlock
;
1639 LARGE_INTEGER FileOffset
;
1640 PFAT32_BOOTSECTOR OrigBootSector
;
1641 PFAT32_BOOTSECTOR NewBootSector
;
1642 USHORT BackupBootSector
;
1644 /* Allocate buffer for original bootsector */
1645 OrigBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
1646 if (OrigBootSector
== NULL
)
1647 return STATUS_INSUFFICIENT_RESOURCES
;
1649 /* Read current boot sector into buffer */
1650 RtlInitUnicodeString(&Name
, RootPath
);
1652 InitializeObjectAttributes(&ObjectAttributes
,
1654 OBJ_CASE_INSENSITIVE
,
1658 Status
= NtOpenFile(&FileHandle
,
1659 GENERIC_READ
| SYNCHRONIZE
,
1663 FILE_SYNCHRONOUS_IO_NONALERT
);
1664 if (!NT_SUCCESS(Status
))
1666 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1670 FileOffset
.QuadPart
= 0ULL;
1671 Status
= NtReadFile(FileHandle
,
1680 NtClose(FileHandle
);
1681 if (!NT_SUCCESS(Status
))
1683 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1688 /* Allocate buffer for new bootsector (2 sectors) */
1689 NewBootSector
= RtlAllocateHeap(ProcessHeap
, 0, 2 * SECTORSIZE
);
1690 if (NewBootSector
== NULL
)
1692 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1693 return STATUS_INSUFFICIENT_RESOURCES
;
1696 /* Read new bootsector from SrcPath */
1697 RtlInitUnicodeString(&Name
, SrcPath
);
1699 InitializeObjectAttributes(&ObjectAttributes
,
1701 OBJ_CASE_INSENSITIVE
,
1705 Status
= NtOpenFile(&FileHandle
,
1706 GENERIC_READ
| SYNCHRONIZE
,
1710 FILE_SYNCHRONOUS_IO_NONALERT
);
1711 if (!NT_SUCCESS(Status
))
1713 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1714 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1718 Status
= NtReadFile(FileHandle
,
1727 NtClose(FileHandle
);
1728 if (!NT_SUCCESS(Status
))
1730 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1731 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1735 /* Adjust bootsector (copy a part of the FAT32 BPB) */
1736 memcpy(&NewBootSector
->OemName
,
1737 &OrigBootSector
->OemName
,
1738 FIELD_OFFSET(FAT32_BOOTSECTOR
, BootCodeAndData
) -
1739 FIELD_OFFSET(FAT32_BOOTSECTOR
, OemName
));
1741 /* Get the location of the backup boot sector */
1742 BackupBootSector
= OrigBootSector
->BackupBootSector
;
1744 /* Free the original boot sector */
1745 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1747 /* Write the first sector of the new bootcode to DstPath */
1748 RtlInitUnicodeString(&Name
, RootPath
);
1750 InitializeObjectAttributes(&ObjectAttributes
,
1756 Status
= NtOpenFile(&FileHandle
,
1757 GENERIC_WRITE
| SYNCHRONIZE
,
1761 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1762 if (!NT_SUCCESS(Status
))
1764 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1765 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1769 /* Write sector 0 */
1770 FileOffset
.QuadPart
= 0ULL;
1771 Status
= NtWriteFile(FileHandle
,
1780 if (!NT_SUCCESS(Status
))
1782 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1783 NtClose(FileHandle
);
1784 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1788 /* Write backup boot sector */
1789 if ((BackupBootSector
!= 0x0000) && (BackupBootSector
!= 0xFFFF))
1791 FileOffset
.QuadPart
= (ULONGLONG
)((ULONG
)BackupBootSector
* SECTORSIZE
);
1792 Status
= NtWriteFile(FileHandle
,
1801 if (!NT_SUCCESS(Status
))
1803 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1804 NtClose(FileHandle
);
1805 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1810 /* Write sector 14 */
1811 FileOffset
.QuadPart
= 14 * SECTORSIZE
;
1812 Status
= NtWriteFile(FileHandle
,
1817 ((PUCHAR
)NewBootSector
+ SECTORSIZE
),
1821 if (!NT_SUCCESS(Status
))
1823 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1825 NtClose(FileHandle
);
1827 /* Free the new boot sector */
1828 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1835 InstallExt2BootCodeToDisk(
1840 UNICODE_STRING Name
;
1841 OBJECT_ATTRIBUTES ObjectAttributes
;
1842 IO_STATUS_BLOCK IoStatusBlock
;
1844 LARGE_INTEGER FileOffset
;
1845 // PEXT2_BOOTSECTOR OrigBootSector;
1846 PEXT2_BOOTSECTOR NewBootSector
;
1847 // USHORT BackupBootSector;
1850 /* Allocate buffer for original bootsector */
1851 OrigBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
1852 if (OrigBootSector
== NULL
)
1853 return STATUS_INSUFFICIENT_RESOURCES
;
1855 /* Read current boot sector into buffer */
1856 RtlInitUnicodeString(&Name
, RootPath
);
1858 InitializeObjectAttributes(&ObjectAttributes
,
1860 OBJ_CASE_INSENSITIVE
,
1864 Status
= NtOpenFile(&FileHandle
,
1865 GENERIC_READ
| SYNCHRONIZE
,
1869 FILE_SYNCHRONOUS_IO_NONALERT
);
1870 if (!NT_SUCCESS(Status
))
1872 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1876 FileOffset
.QuadPart
= 0ULL;
1877 Status
= NtReadFile(FileHandle
,
1886 NtClose(FileHandle
);
1887 if (!NT_SUCCESS(Status
))
1889 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1894 /* Allocate buffer for new bootsector */
1895 NewBootSector
= RtlAllocateHeap(ProcessHeap
, 0, sizeof(EXT2_BOOTSECTOR
));
1896 if (NewBootSector
== NULL
)
1898 // RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1899 return STATUS_INSUFFICIENT_RESOURCES
;
1902 /* Read new bootsector from SrcPath */
1903 RtlInitUnicodeString(&Name
, SrcPath
);
1905 InitializeObjectAttributes(&ObjectAttributes
,
1907 OBJ_CASE_INSENSITIVE
,
1911 Status
= NtOpenFile(&FileHandle
,
1912 GENERIC_READ
| SYNCHRONIZE
,
1916 FILE_SYNCHRONOUS_IO_NONALERT
);
1917 if (!NT_SUCCESS(Status
))
1919 // RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1920 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1924 Status
= NtReadFile(FileHandle
,
1930 sizeof(EXT2_BOOTSECTOR
),
1933 NtClose(FileHandle
);
1934 if (!NT_SUCCESS(Status
))
1936 // RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1937 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1942 /* Adjust bootsector (copy a part of the FAT32 BPB) */
1943 memcpy(&NewBootSector
->OemName
,
1944 &OrigBootSector
->OemName
,
1945 FIELD_OFFSET(FAT32_BOOTSECTOR
, BootCodeAndData
) -
1946 FIELD_OFFSET(FAT32_BOOTSECTOR
, OemName
));
1948 NewBootSector
->HiddenSectors
= PartitionList
->CurrentDisk
->SectorsPerTrack
;
1950 /* Get the location of the backup boot sector */
1951 BackupBootSector
= OrigBootSector
->BackupBootSector
;
1953 /* Free the original boot sector */
1954 // RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1957 /* Write new bootsector to RootPath */
1958 RtlInitUnicodeString(&Name
, RootPath
);
1960 InitializeObjectAttributes(&ObjectAttributes
,
1966 Status
= NtOpenFile(&FileHandle
,
1967 GENERIC_WRITE
| SYNCHRONIZE
,
1971 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1972 if (!NT_SUCCESS(Status
))
1974 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1975 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1979 /* Write sector 0 */
1980 FileOffset
.QuadPart
= 0ULL;
1981 Status
= NtWriteFile(FileHandle
,
1987 sizeof(EXT2_BOOTSECTOR
),
1991 if (!NT_SUCCESS(Status
))
1993 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1994 NtClose(FileHandle
);
1995 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1999 /* Write backup boot sector */
2000 if ((BackupBootSector
!= 0x0000) && (BackupBootSector
!= 0xFFFF))
2002 FileOffset
.QuadPart
= (ULONGLONG
)((ULONG
)BackupBootSector
* SECTORSIZE
);
2003 Status
= NtWriteFile(FileHandle
,
2012 if (!NT_SUCCESS(Status
))
2014 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
2015 NtClose(FileHandle
);
2016 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
2021 /* Write sector 14 */
2022 FileOffset
.QuadPart
= 14 * SECTORSIZE
;
2023 Status
= NtWriteFile(FileHandle
,
2028 ((PUCHAR
)NewBootSector
+ SECTORSIZE
),
2032 if (!NT_SUCCESS(Status
))
2034 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
2037 NtClose(FileHandle
);
2039 /* Free the new boot sector */
2040 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
2052 UNICODE_STRING Name
;
2053 OBJECT_ATTRIBUTES ObjectAttributes
;
2054 IO_STATUS_BLOCK IoStatusBlock
;
2055 FILE_BASIC_INFORMATION FileInfo
;
2058 RtlInitUnicodeString(&Name
, FileName
);
2060 InitializeObjectAttributes(&ObjectAttributes
,
2062 OBJ_CASE_INSENSITIVE
,
2066 Status
= NtOpenFile(&FileHandle
,
2067 GENERIC_READ
| GENERIC_WRITE
| SYNCHRONIZE
,
2071 FILE_SYNCHRONOUS_IO_NONALERT
);
2072 if (Status
== STATUS_NO_SUCH_FILE
)
2074 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
2076 return STATUS_SUCCESS
;
2078 if (!NT_SUCCESS(Status
))
2080 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
2084 Status
= NtQueryInformationFile(FileHandle
,
2087 sizeof(FILE_BASIC_INFORMATION
),
2088 FileBasicInformation
);
2089 if (!NT_SUCCESS(Status
))
2091 DPRINT1("NtQueryInformationFile() failed (Status %lx)\n", Status
);
2092 NtClose(FileHandle
);
2096 *Attributes
= FileInfo
.FileAttributes
;
2098 /* Delete attributes SYSTEM, HIDDEN and READONLY */
2099 FileInfo
.FileAttributes
= FileInfo
.FileAttributes
&
2100 ~(FILE_ATTRIBUTE_SYSTEM
|
2101 FILE_ATTRIBUTE_HIDDEN
|
2102 FILE_ATTRIBUTE_READONLY
);
2104 Status
= NtSetInformationFile(FileHandle
,
2107 sizeof(FILE_BASIC_INFORMATION
),
2108 FileBasicInformation
);
2109 if (!NT_SUCCESS(Status
))
2111 DPRINT1("NtSetInformationFile() failed (Status %lx)\n", Status
);
2114 NtClose(FileHandle
);
2125 UNICODE_STRING Name
;
2126 OBJECT_ATTRIBUTES ObjectAttributes
;
2127 IO_STATUS_BLOCK IoStatusBlock
;
2128 FILE_BASIC_INFORMATION FileInfo
;
2131 RtlInitUnicodeString(&Name
, FileName
);
2133 InitializeObjectAttributes(&ObjectAttributes
,
2135 OBJ_CASE_INSENSITIVE
,
2139 Status
= NtOpenFile(&FileHandle
,
2140 GENERIC_READ
| GENERIC_WRITE
| SYNCHRONIZE
,
2144 FILE_SYNCHRONOUS_IO_NONALERT
);
2145 if (!NT_SUCCESS(Status
))
2147 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
2151 Status
= NtQueryInformationFile(FileHandle
,
2154 sizeof(FILE_BASIC_INFORMATION
),
2155 FileBasicInformation
);
2156 if (!NT_SUCCESS(Status
))
2158 DPRINT1("NtQueryInformationFile() failed (Status %lx)\n", Status
);
2159 NtClose(FileHandle
);
2163 FileInfo
.FileAttributes
= FileInfo
.FileAttributes
| Attributes
;
2165 Status
= NtSetInformationFile(FileHandle
,
2168 sizeof(FILE_BASIC_INFORMATION
),
2169 FileBasicInformation
);
2170 if (!NT_SUCCESS(Status
))
2172 DPRINT1("NtSetInformationFile() failed (Status %lx)\n", Status
);
2175 NtClose(FileHandle
);
2187 PINICACHE Cache
= NULL
;
2188 PINICACHESECTION Section
= NULL
;
2189 ULONG FileAttribute
;
2190 PWCHAR OldValue
= NULL
;
2192 Status
= IniCacheLoad(&Cache
, BootIniPath
, FALSE
);
2193 if (!NT_SUCCESS(Status
))
2198 Section
= IniCacheGetSection(Cache
,
2199 L
"operating systems");
2200 if (Section
== NULL
)
2202 IniCacheDestroy(Cache
);
2203 return STATUS_UNSUCCESSFUL
;
2206 /* Check - maybe record already exists */
2207 Status
= IniCacheGetKey(Section
, EntryName
, &OldValue
);
2209 /* If either key was not found, or contains something else - add new one */
2210 if (!NT_SUCCESS(Status
) || wcscmp(OldValue
, EntryValue
))
2212 IniCacheInsertKey(Section
,
2219 Status
= UnprotectBootIni(BootIniPath
,
2221 if (!NT_SUCCESS(Status
))
2223 IniCacheDestroy(Cache
);
2227 Status
= IniCacheSave(Cache
, BootIniPath
);
2228 if (!NT_SUCCESS(Status
))
2230 IniCacheDestroy(Cache
);
2234 FileAttribute
|= (FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
| FILE_ATTRIBUTE_READONLY
);
2235 Status
= ProtectBootIni(BootIniPath
, FileAttribute
);
2237 IniCacheDestroy(Cache
);
2244 InstallFatBootcodeToPartition(
2245 PUNICODE_STRING SystemRootPath
,
2246 PUNICODE_STRING SourceRootPath
,
2247 PUNICODE_STRING DestinationArcPath
,
2248 UCHAR PartitionType
)
2252 BOOLEAN DoesFreeLdrExist
;
2253 WCHAR SrcPath
[MAX_PATH
];
2254 WCHAR DstPath
[MAX_PATH
];
2256 /* FAT or FAT32 partition */
2257 DPRINT("System path: '%wZ'\n", SystemRootPath
);
2259 /* Copy FreeLoader to the system partition */
2260 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2261 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
2262 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2263 wcscat(DstPath
, L
"\\freeldr.sys");
2265 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2266 Status
= SetupCopyFile(SrcPath
, DstPath
);
2267 if (!NT_SUCCESS(Status
))
2269 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
2273 /* Prepare for possibly copying 'freeldr.ini' */
2274 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2275 wcscat(DstPath
, L
"\\freeldr.ini");
2277 DoesFreeLdrExist
= DoesFileExist(SystemRootPath
->Buffer
, L
"freeldr.ini");
2278 if (DoesFreeLdrExist
)
2280 /* Update existing 'freeldr.ini' */
2281 DPRINT1("Update existing 'freeldr.ini'\n");
2283 Status
= UpdateFreeLoaderIni(DstPath
, DestinationArcPath
->Buffer
);
2284 if (!NT_SUCCESS(Status
))
2286 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
2291 /* Check for NT and other bootloaders */
2293 // FIXME: Check for Vista+ bootloader!
2294 if (DoesFileExist(SystemRootPath
->Buffer
, L
"ntldr") == TRUE
||
2295 DoesFileExist(SystemRootPath
->Buffer
, L
"boot.ini") == TRUE
)
2297 /* Search root directory for 'ntldr' and 'boot.ini' */
2298 DPRINT1("Found Microsoft Windows NT/2000/XP boot loader\n");
2300 /* Create or update 'freeldr.ini' */
2301 if (DoesFreeLdrExist
== FALSE
)
2303 /* Create new 'freeldr.ini' */
2304 DPRINT1("Create new 'freeldr.ini'\n");
2305 // wcscpy(DstPath, SystemRootPath->Buffer);
2306 // wcscat(DstPath, L"\\freeldr.ini");
2308 Status
= CreateFreeLoaderIniForReactOS(DstPath
, DestinationArcPath
->Buffer
);
2309 if (!NT_SUCCESS(Status
))
2311 DPRINT1("CreateFreeLoaderIniForReactOS() failed (Status %lx)\n", Status
);
2315 /* Install new bootcode into a file */
2316 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2317 wcscat(DstPath
, L
"\\bootsect.ros");
2319 if (PartitionType
== PARTITION_FAT32
||
2320 PartitionType
== PARTITION_FAT32_XINT13
)
2322 /* Install FAT32 bootcode */
2323 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2324 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
2326 DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, DstPath
);
2327 Status
= InstallFat32BootCodeToFile(SrcPath
, DstPath
,
2328 SystemRootPath
->Buffer
);
2329 if (!NT_SUCCESS(Status
))
2331 DPRINT1("InstallFat32BootCodeToFile() failed (Status %lx)\n", Status
);
2337 /* Install FAT16 bootcode */
2338 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2339 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2341 DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath
, DstPath
);
2342 Status
= InstallFat16BootCodeToFile(SrcPath
, DstPath
,
2343 SystemRootPath
->Buffer
);
2344 if (!NT_SUCCESS(Status
))
2346 DPRINT1("InstallFat16BootCodeToFile() failed (Status %lx)\n", Status
);
2352 /* Update 'boot.ini' */
2353 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2354 wcscat(DstPath
, L
"\\boot.ini");
2356 DPRINT1("Update 'boot.ini': %S\n", DstPath
);
2357 Status
= UpdateBootIni(DstPath
,
2358 L
"C:\\bootsect.ros",
2360 if (!NT_SUCCESS(Status
))
2362 DPRINT1("UpdateBootIni() failed (Status %lx)\n", Status
);
2368 /* Non-NT bootloaders: install our own bootloader */
2373 PWCHAR BootPartition
;
2375 PWCHAR BootSectorFileName
;
2377 if (DoesFileExist(SystemRootPath
->Buffer
, L
"io.sys") == TRUE
||
2378 DoesFileExist(SystemRootPath
->Buffer
, L
"msdos.sys") == TRUE
)
2380 /* Search for root directory for 'io.sys' and 'msdos.sys' */
2381 DPRINT1("Found Microsoft DOS or Windows 9x boot loader\n");
2384 Description
= L
"\"DOS/Windows\"";
2386 BootPartition
= L
"1";
2387 BootSector
= L
"BOOTSECT.DOS";
2389 BootSectorFileName
= L
"\\bootsect.dos";
2392 if (DoesFileExist(SystemRootPath
->Buffer
, L
"kernel.sys") == TRUE
)
2394 /* Search for root directory for 'kernel.sys' */
2395 DPRINT1("Found FreeDOS boot loader\n");
2398 Description
= L
"\"FreeDOS\"";
2400 BootPartition
= L
"1";
2401 BootSector
= L
"BOOTSECT.DOS";
2403 BootSectorFileName
= L
"\\bootsect.dos";
2407 /* No or unknown boot loader */
2408 DPRINT1("No or unknown boot loader found\n");
2410 Section
= L
"Unknown";
2411 Description
= L
"\"Unknown Operating System\"";
2413 BootPartition
= L
"1";
2414 BootSector
= L
"BOOTSECT.OLD";
2416 BootSectorFileName
= L
"\\bootsect.old";
2419 /* Create or update 'freeldr.ini' */
2420 if (DoesFreeLdrExist
== FALSE
)
2422 /* Create new 'freeldr.ini' */
2423 DPRINT1("Create new 'freeldr.ini'\n");
2424 // wcscpy(DstPath, SystemRootPath->Buffer);
2425 // wcscat(DstPath, L"\\freeldr.ini");
2427 if (IsThereAValidBootSector(SystemRootPath
->Buffer
))
2429 Status
= CreateFreeLoaderIniForReactOSAndBootSector(
2430 DstPath
, DestinationArcPath
->Buffer
,
2431 Section
, Description
,
2432 BootDrive
, BootPartition
, BootSector
);
2433 if (!NT_SUCCESS(Status
))
2435 DPRINT1("CreateFreeLoaderIniForReactOSAndBootSector() failed (Status %lx)\n", Status
);
2439 /* Save current bootsector */
2440 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2441 wcscat(DstPath
, BootSectorFileName
);
2443 DPRINT1("Save bootsector: %S ==> %S\n", SystemRootPath
->Buffer
, DstPath
);
2444 Status
= SaveBootSector(SystemRootPath
->Buffer
, DstPath
, SECTORSIZE
);
2445 if (!NT_SUCCESS(Status
))
2447 DPRINT1("SaveBootSector() failed (Status %lx)\n", Status
);
2453 Status
= CreateFreeLoaderIniForReactOS(DstPath
, DestinationArcPath
->Buffer
);
2454 if (!NT_SUCCESS(Status
))
2456 DPRINT1("CreateFreeLoaderIniForReactOS() failed (Status %lx)\n", Status
);
2461 /* Install new bootsector on the disk */
2462 if (PartitionType
== PARTITION_FAT32
||
2463 PartitionType
== PARTITION_FAT32_XINT13
)
2465 /* Install FAT32 bootcode */
2466 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2467 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
2469 DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2470 Status
= InstallFat32BootCodeToDisk(SrcPath
, SystemRootPath
->Buffer
);
2471 if (!NT_SUCCESS(Status
))
2473 DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)\n", Status
);
2479 /* Install FAT16 bootcode */
2480 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2481 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2483 DPRINT1("Install FAT16 bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2484 Status
= InstallFat16BootCodeToDisk(SrcPath
, SystemRootPath
->Buffer
);
2485 if (!NT_SUCCESS(Status
))
2487 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status
);
2494 return STATUS_SUCCESS
;
2496 return STATUS_NOT_IMPLEMENTED
;
2502 InstallExt2BootcodeToPartition(
2503 PUNICODE_STRING SystemRootPath
,
2504 PUNICODE_STRING SourceRootPath
,
2505 PUNICODE_STRING DestinationArcPath
,
2506 UCHAR PartitionType
)
2510 BOOLEAN DoesFreeLdrExist
;
2511 WCHAR SrcPath
[MAX_PATH
];
2512 WCHAR DstPath
[MAX_PATH
];
2514 /* EXT2 partition */
2515 DPRINT("System path: '%wZ'\n", SystemRootPath
);
2517 /* Copy FreeLoader to the system partition */
2518 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2519 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
2520 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2521 wcscat(DstPath
, L
"\\freeldr.sys");
2523 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2524 Status
= SetupCopyFile(SrcPath
, DstPath
);
2525 if (!NT_SUCCESS(Status
))
2527 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
2531 /* Prepare for possibly copying 'freeldr.ini' */
2532 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2533 wcscat(DstPath
, L
"\\freeldr.ini");
2535 DoesFreeLdrExist
= DoesFileExist(SystemRootPath
->Buffer
, L
"freeldr.ini");
2536 if (DoesFreeLdrExist
)
2538 /* Update existing 'freeldr.ini' */
2539 DPRINT1("Update existing 'freeldr.ini'\n");
2541 Status
= UpdateFreeLoaderIni(DstPath
, DestinationArcPath
->Buffer
);
2542 if (!NT_SUCCESS(Status
))
2544 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
2549 /* Check for *nix bootloaders */
2551 /* Create or update 'freeldr.ini' */
2552 if (DoesFreeLdrExist
== FALSE
)
2554 /* Create new 'freeldr.ini' */
2555 DPRINT1("Create new 'freeldr.ini'\n");
2556 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2557 wcscat(DstPath
, L
"\\freeldr.ini");
2559 /* Certainly SysLinux, GRUB, LILO... or an unknown boot loader */
2560 DPRINT1("*nix or unknown boot loader found\n");
2562 if (IsThereAValidBootSector(SystemRootPath
->Buffer
))
2564 Status
= CreateFreeLoaderIniForReactOSAndBootSector(
2565 DstPath
, DestinationArcPath
->Buffer
,
2566 L
"Linux", L
"\"Linux\"",
2567 L
"hd0", L
"1", L
"BOOTSECT.OLD");
2568 if (!NT_SUCCESS(Status
))
2570 DPRINT1("CreateFreeLoaderIniForReactOSAndBootSector() failed (Status %lx)\n", Status
);
2574 /* Save current bootsector */
2575 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2576 wcscat(DstPath
, L
"\\bootsect.old");
2578 DPRINT1("Save bootsector: %S ==> %S\n", SystemRootPath
->Buffer
, DstPath
);
2579 Status
= SaveBootSector(SystemRootPath
->Buffer
, DstPath
, sizeof(EXT2_BOOTSECTOR
));
2580 if (!NT_SUCCESS(Status
))
2582 DPRINT1("SaveBootSector() failed (Status %lx)\n", Status
);
2588 Status
= CreateFreeLoaderIniForReactOS(DstPath
, DestinationArcPath
->Buffer
);
2589 if (!NT_SUCCESS(Status
))
2591 DPRINT1("CreateFreeLoaderIniForReactOS() failed (Status %lx)\n", Status
);
2596 /* Install new bootsector on the disk */
2597 // if (PartitionType == PARTITION_EXT2)
2599 /* Install EXT2 bootcode */
2600 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2601 wcscat(SrcPath
, L
"\\loader\\ext2.bin");
2603 DPRINT1("Install EXT2 bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2604 Status
= InstallExt2BootCodeToDisk(SrcPath
, SystemRootPath
->Buffer
);
2605 if (!NT_SUCCESS(Status
))
2607 DPRINT1("InstallExt2BootCodeToDisk() failed (Status %lx)\n", Status
);
2613 return STATUS_SUCCESS
;
2615 return STATUS_NOT_IMPLEMENTED
;
2621 InstallVBRToPartition(
2622 PUNICODE_STRING SystemRootPath
,
2623 PUNICODE_STRING SourceRootPath
,
2624 PUNICODE_STRING DestinationArcPath
,
2625 UCHAR PartitionType
)
2627 switch (PartitionType
)
2629 case PARTITION_FAT_12
:
2630 case PARTITION_FAT_16
:
2631 case PARTITION_HUGE
:
2632 case PARTITION_XINT13
:
2633 case PARTITION_FAT32
:
2634 case PARTITION_FAT32_XINT13
:
2636 return InstallFatBootcodeToPartition(SystemRootPath
,
2642 case PARTITION_EXT2
:
2644 return InstallExt2BootcodeToPartition(SystemRootPath
,
2654 DPRINT1("PartitionType 0x%02X unknown!\n", PartitionType
);
2658 return STATUS_UNSUCCESSFUL
;
2663 InstallFatBootcodeToFloppy(
2664 PUNICODE_STRING SourceRootPath
,
2665 PUNICODE_STRING DestinationArcPath
)
2669 UNICODE_STRING FloppyDevice
= RTL_CONSTANT_STRING(L
"\\Device\\Floppy0");
2670 WCHAR SrcPath
[MAX_PATH
];
2671 WCHAR DstPath
[MAX_PATH
];
2673 /* Format the floppy first */
2674 Status
= VfatFormat(&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
;
2727 return STATUS_NOT_IMPLEMENTED
;