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 * 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 FileOffset
.QuadPart
= 0ULL;
945 Status
= NtWriteFile(FileHandle
,
956 /* Free the new boot sector */
957 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
964 InstallFat32BootCodeToFile(
971 OBJECT_ATTRIBUTES ObjectAttributes
;
972 IO_STATUS_BLOCK IoStatusBlock
;
974 LARGE_INTEGER FileOffset
;
975 PFAT32_BOOTSECTOR OrigBootSector
;
976 PFAT32_BOOTSECTOR NewBootSector
;
978 /* Allocate buffer for original bootsector */
979 OrigBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
980 if (OrigBootSector
== NULL
)
981 return STATUS_INSUFFICIENT_RESOURCES
;
983 /* Read current boot sector into buffer */
984 RtlInitUnicodeString(&Name
, RootPath
);
986 InitializeObjectAttributes(&ObjectAttributes
,
988 OBJ_CASE_INSENSITIVE
,
992 Status
= NtOpenFile(&FileHandle
,
993 GENERIC_READ
| SYNCHRONIZE
,
997 FILE_SYNCHRONOUS_IO_NONALERT
);
998 if (!NT_SUCCESS(Status
))
1000 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1004 FileOffset
.QuadPart
= 0ULL;
1005 Status
= NtReadFile(FileHandle
,
1014 NtClose(FileHandle
);
1015 if (!NT_SUCCESS(Status
))
1017 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1021 /* Allocate buffer for new bootsector (2 sectors) */
1022 NewBootSector
= RtlAllocateHeap(ProcessHeap
, 0, 2 * SECTORSIZE
);
1023 if (NewBootSector
== NULL
)
1025 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1026 return STATUS_INSUFFICIENT_RESOURCES
;
1029 /* Read new bootsector from SrcPath */
1030 RtlInitUnicodeString(&Name
, SrcPath
);
1032 InitializeObjectAttributes(&ObjectAttributes
,
1034 OBJ_CASE_INSENSITIVE
,
1038 Status
= NtOpenFile(&FileHandle
,
1039 GENERIC_READ
| SYNCHRONIZE
,
1043 FILE_SYNCHRONOUS_IO_NONALERT
);
1044 if (!NT_SUCCESS(Status
))
1046 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1047 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1051 Status
= NtReadFile(FileHandle
,
1060 NtClose(FileHandle
);
1061 if (!NT_SUCCESS(Status
))
1063 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1064 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1068 /* Adjust bootsector (copy a part of the FAT32 BPB) */
1069 memcpy(&NewBootSector
->OemName
,
1070 &OrigBootSector
->OemName
,
1071 FIELD_OFFSET(FAT32_BOOTSECTOR
, BootCodeAndData
) -
1072 FIELD_OFFSET(FAT32_BOOTSECTOR
, OemName
));
1074 /* Disable the backup boot sector */
1075 NewBootSector
->BackupBootSector
= 0;
1077 /* Free the original boot sector */
1078 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1080 /* Write the first sector of the new bootcode to DstPath */
1081 RtlInitUnicodeString(&Name
, DstPath
);
1083 InitializeObjectAttributes(&ObjectAttributes
,
1089 Status
= NtCreateFile(&FileHandle
,
1090 GENERIC_WRITE
| SYNCHRONIZE
,
1094 FILE_ATTRIBUTE_NORMAL
,
1097 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
,
1100 if (!NT_SUCCESS(Status
))
1102 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1106 FileOffset
.QuadPart
= 0ULL;
1107 Status
= NtWriteFile(FileHandle
,
1116 NtClose(FileHandle
);
1117 if (!NT_SUCCESS(Status
))
1119 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1123 /* Write the second sector of the new bootcode to boot disk sector 14 */
1124 RtlInitUnicodeString(&Name
, RootPath
);
1126 InitializeObjectAttributes(&ObjectAttributes
,
1132 Status
= NtOpenFile(&FileHandle
,
1133 GENERIC_WRITE
| SYNCHRONIZE
,
1137 FILE_SYNCHRONOUS_IO_NONALERT
);
1138 if (!NT_SUCCESS(Status
))
1140 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1144 FileOffset
.QuadPart
= (ULONGLONG
)(14 * SECTORSIZE
);
1145 Status
= NtWriteFile(FileHandle
,
1150 ((PUCHAR
)NewBootSector
+ SECTORSIZE
),
1154 if (!NT_SUCCESS(Status
))
1157 NtClose(FileHandle
);
1159 /* Free the new boot sector */
1160 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1167 InstallMbrBootCodeToDisk(
1172 UNICODE_STRING Name
;
1173 OBJECT_ATTRIBUTES ObjectAttributes
;
1174 IO_STATUS_BLOCK IoStatusBlock
;
1176 LARGE_INTEGER FileOffset
;
1177 PPARTITION_SECTOR OrigBootSector
;
1178 PPARTITION_SECTOR NewBootSector
;
1180 /* Allocate buffer for original bootsector */
1181 OrigBootSector
= (PPARTITION_SECTOR
)RtlAllocateHeap(ProcessHeap
,
1183 sizeof(PARTITION_SECTOR
));
1184 if (OrigBootSector
== NULL
)
1185 return STATUS_INSUFFICIENT_RESOURCES
;
1187 /* Read current boot sector into buffer */
1188 RtlInitUnicodeString(&Name
,
1191 InitializeObjectAttributes(&ObjectAttributes
,
1193 OBJ_CASE_INSENSITIVE
,
1197 Status
= NtOpenFile(&FileHandle
,
1198 GENERIC_READ
| SYNCHRONIZE
,
1202 FILE_SYNCHRONOUS_IO_NONALERT
);
1203 if (!NT_SUCCESS(Status
))
1205 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1209 FileOffset
.QuadPart
= 0ULL;
1210 Status
= NtReadFile(FileHandle
,
1216 sizeof(PARTITION_SECTOR
),
1219 NtClose(FileHandle
);
1220 if (!NT_SUCCESS(Status
))
1222 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1226 /* Allocate buffer for new bootsector */
1227 NewBootSector
= (PPARTITION_SECTOR
)RtlAllocateHeap(ProcessHeap
,
1229 sizeof(PARTITION_SECTOR
));
1230 if (NewBootSector
== NULL
)
1232 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1233 return STATUS_INSUFFICIENT_RESOURCES
;
1236 /* Read new bootsector from SrcPath */
1237 RtlInitUnicodeString(&Name
, SrcPath
);
1239 InitializeObjectAttributes(&ObjectAttributes
,
1241 OBJ_CASE_INSENSITIVE
,
1245 Status
= NtOpenFile(&FileHandle
,
1246 GENERIC_READ
| SYNCHRONIZE
,
1250 FILE_SYNCHRONOUS_IO_NONALERT
);
1251 if (!NT_SUCCESS(Status
))
1253 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1254 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1258 Status
= NtReadFile(FileHandle
,
1264 sizeof(PARTITION_SECTOR
),
1267 NtClose(FileHandle
);
1268 if (!NT_SUCCESS(Status
))
1270 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1271 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1275 /* Copy partition table from old MBR to new */
1276 RtlCopyMemory(&NewBootSector
->Signature
,
1277 &OrigBootSector
->Signature
,
1278 sizeof(PARTITION_SECTOR
) - offsetof(PARTITION_SECTOR
, Signature
) /* Length of partition table */);
1280 /* Free the original boot sector */
1281 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1283 /* Write new bootsector to RootPath */
1284 RtlInitUnicodeString(&Name
, RootPath
);
1286 InitializeObjectAttributes(&ObjectAttributes
,
1292 Status
= NtOpenFile(&FileHandle
,
1293 GENERIC_WRITE
| SYNCHRONIZE
,
1297 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1298 if (!NT_SUCCESS(Status
))
1300 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1301 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1305 FileOffset
.QuadPart
= 0ULL;
1306 Status
= NtWriteFile(FileHandle
,
1312 sizeof(PARTITION_SECTOR
),
1315 NtClose(FileHandle
);
1317 /* Free the new boot sector */
1318 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1325 InstallFat12BootCodeToFloppy(
1330 UNICODE_STRING Name
;
1331 OBJECT_ATTRIBUTES ObjectAttributes
;
1332 IO_STATUS_BLOCK IoStatusBlock
;
1334 LARGE_INTEGER FileOffset
;
1335 PFAT_BOOTSECTOR OrigBootSector
;
1336 PFAT_BOOTSECTOR NewBootSector
;
1338 /* Allocate buffer for original bootsector */
1339 OrigBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
1340 if (OrigBootSector
== NULL
)
1341 return STATUS_INSUFFICIENT_RESOURCES
;
1343 /* Read current boot sector into buffer */
1344 RtlInitUnicodeString(&Name
, RootPath
);
1346 InitializeObjectAttributes(&ObjectAttributes
,
1348 OBJ_CASE_INSENSITIVE
,
1352 Status
= NtOpenFile(&FileHandle
,
1353 GENERIC_READ
| SYNCHRONIZE
,
1357 FILE_SYNCHRONOUS_IO_NONALERT
);
1358 if (!NT_SUCCESS(Status
))
1360 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1364 FileOffset
.QuadPart
= 0ULL;
1365 Status
= NtReadFile(FileHandle
,
1374 NtClose(FileHandle
);
1375 if (!NT_SUCCESS(Status
))
1377 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1381 /* Allocate buffer for new bootsector */
1382 NewBootSector
= RtlAllocateHeap(ProcessHeap
,
1385 if (NewBootSector
== NULL
)
1387 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1388 return STATUS_INSUFFICIENT_RESOURCES
;
1391 /* Read new bootsector from SrcPath */
1392 RtlInitUnicodeString(&Name
, SrcPath
);
1394 InitializeObjectAttributes(&ObjectAttributes
,
1396 OBJ_CASE_INSENSITIVE
,
1400 Status
= NtOpenFile(&FileHandle
,
1401 GENERIC_READ
| SYNCHRONIZE
,
1405 FILE_SYNCHRONOUS_IO_NONALERT
);
1406 if (!NT_SUCCESS(Status
))
1408 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1409 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1413 Status
= NtReadFile(FileHandle
,
1422 NtClose(FileHandle
);
1423 if (!NT_SUCCESS(Status
))
1425 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1426 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1430 /* Adjust bootsector (copy a part of the FAT16 BPB) */
1431 memcpy(&NewBootSector
->OemName
,
1432 &OrigBootSector
->OemName
,
1433 FIELD_OFFSET(FAT_BOOTSECTOR
, BootCodeAndData
) -
1434 FIELD_OFFSET(FAT_BOOTSECTOR
, OemName
));
1436 /* Free the original boot sector */
1437 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1439 /* Write new bootsector to RootPath */
1440 RtlInitUnicodeString(&Name
, RootPath
);
1442 InitializeObjectAttributes(&ObjectAttributes
,
1448 Status
= NtOpenFile(&FileHandle
,
1449 GENERIC_WRITE
| SYNCHRONIZE
,
1453 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1454 if (!NT_SUCCESS(Status
))
1456 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1457 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1461 FileOffset
.QuadPart
= 0ULL;
1462 Status
= NtWriteFile(FileHandle
,
1471 NtClose(FileHandle
);
1473 /* Free the new boot sector */
1474 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1481 InstallFat16BootCodeToDisk(
1486 UNICODE_STRING Name
;
1487 OBJECT_ATTRIBUTES ObjectAttributes
;
1488 IO_STATUS_BLOCK IoStatusBlock
;
1490 LARGE_INTEGER FileOffset
;
1491 PFAT_BOOTSECTOR OrigBootSector
;
1492 PFAT_BOOTSECTOR NewBootSector
;
1494 /* Allocate buffer for original bootsector */
1495 OrigBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
1496 if (OrigBootSector
== NULL
)
1497 return STATUS_INSUFFICIENT_RESOURCES
;
1499 /* Read current boot sector into buffer */
1500 RtlInitUnicodeString(&Name
, RootPath
);
1502 InitializeObjectAttributes(&ObjectAttributes
,
1504 OBJ_CASE_INSENSITIVE
,
1508 Status
= NtOpenFile(&FileHandle
,
1509 GENERIC_READ
| SYNCHRONIZE
,
1513 FILE_SYNCHRONOUS_IO_NONALERT
);
1514 if (!NT_SUCCESS(Status
))
1516 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1520 FileOffset
.QuadPart
= 0ULL;
1521 Status
= NtReadFile(FileHandle
,
1530 NtClose(FileHandle
);
1531 if (!NT_SUCCESS(Status
))
1533 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1537 /* Allocate buffer for new bootsector */
1538 NewBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
1539 if (NewBootSector
== NULL
)
1541 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1542 return STATUS_INSUFFICIENT_RESOURCES
;
1545 /* Read new bootsector from SrcPath */
1546 RtlInitUnicodeString(&Name
, SrcPath
);
1548 InitializeObjectAttributes(&ObjectAttributes
,
1550 OBJ_CASE_INSENSITIVE
,
1554 Status
= NtOpenFile(&FileHandle
,
1555 GENERIC_READ
| SYNCHRONIZE
,
1559 FILE_SYNCHRONOUS_IO_NONALERT
);
1560 if (!NT_SUCCESS(Status
))
1562 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1563 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1567 Status
= NtReadFile(FileHandle
,
1576 NtClose(FileHandle
);
1577 if (!NT_SUCCESS(Status
))
1579 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1580 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1584 /* Adjust bootsector (copy a part of the FAT16 BPB) */
1585 memcpy(&NewBootSector
->OemName
,
1586 &OrigBootSector
->OemName
,
1587 FIELD_OFFSET(FAT_BOOTSECTOR
, BootCodeAndData
) -
1588 FIELD_OFFSET(FAT_BOOTSECTOR
, OemName
));
1590 /* Free the original boot sector */
1591 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1593 /* Write new bootsector to RootPath */
1594 RtlInitUnicodeString(&Name
, RootPath
);
1596 InitializeObjectAttributes(&ObjectAttributes
,
1602 Status
= NtOpenFile(&FileHandle
,
1603 GENERIC_WRITE
| SYNCHRONIZE
,
1607 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1608 if (!NT_SUCCESS(Status
))
1610 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1611 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1615 FileOffset
.QuadPart
= 0ULL;
1616 Status
= NtWriteFile(FileHandle
,
1625 NtClose(FileHandle
);
1627 /* Free the new boot sector */
1628 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1635 InstallFat32BootCodeToDisk(
1640 UNICODE_STRING Name
;
1641 OBJECT_ATTRIBUTES ObjectAttributes
;
1642 IO_STATUS_BLOCK IoStatusBlock
;
1644 LARGE_INTEGER FileOffset
;
1645 PFAT32_BOOTSECTOR OrigBootSector
;
1646 PFAT32_BOOTSECTOR NewBootSector
;
1647 USHORT BackupBootSector
;
1649 /* Allocate buffer for original bootsector */
1650 OrigBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
1651 if (OrigBootSector
== NULL
)
1652 return STATUS_INSUFFICIENT_RESOURCES
;
1654 /* Read current boot sector into buffer */
1655 RtlInitUnicodeString(&Name
, RootPath
);
1657 InitializeObjectAttributes(&ObjectAttributes
,
1659 OBJ_CASE_INSENSITIVE
,
1663 Status
= NtOpenFile(&FileHandle
,
1664 GENERIC_READ
| SYNCHRONIZE
,
1668 FILE_SYNCHRONOUS_IO_NONALERT
);
1669 if (!NT_SUCCESS(Status
))
1671 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1675 FileOffset
.QuadPart
= 0ULL;
1676 Status
= NtReadFile(FileHandle
,
1685 NtClose(FileHandle
);
1686 if (!NT_SUCCESS(Status
))
1688 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1693 /* Allocate buffer for new bootsector (2 sectors) */
1694 NewBootSector
= RtlAllocateHeap(ProcessHeap
, 0, 2 * SECTORSIZE
);
1695 if (NewBootSector
== NULL
)
1697 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1698 return STATUS_INSUFFICIENT_RESOURCES
;
1701 /* Read new bootsector from SrcPath */
1702 RtlInitUnicodeString(&Name
, SrcPath
);
1704 InitializeObjectAttributes(&ObjectAttributes
,
1706 OBJ_CASE_INSENSITIVE
,
1710 Status
= NtOpenFile(&FileHandle
,
1711 GENERIC_READ
| SYNCHRONIZE
,
1715 FILE_SYNCHRONOUS_IO_NONALERT
);
1716 if (!NT_SUCCESS(Status
))
1718 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1719 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1723 Status
= NtReadFile(FileHandle
,
1732 NtClose(FileHandle
);
1733 if (!NT_SUCCESS(Status
))
1735 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1736 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1740 /* Adjust bootsector (copy a part of the FAT32 BPB) */
1741 memcpy(&NewBootSector
->OemName
,
1742 &OrigBootSector
->OemName
,
1743 FIELD_OFFSET(FAT32_BOOTSECTOR
, BootCodeAndData
) -
1744 FIELD_OFFSET(FAT32_BOOTSECTOR
, OemName
));
1746 /* Get the location of the backup boot sector */
1747 BackupBootSector
= OrigBootSector
->BackupBootSector
;
1749 /* Free the original boot sector */
1750 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1752 /* Write the first sector of the new bootcode to DstPath */
1753 RtlInitUnicodeString(&Name
, RootPath
);
1755 InitializeObjectAttributes(&ObjectAttributes
,
1761 Status
= NtOpenFile(&FileHandle
,
1762 GENERIC_WRITE
| SYNCHRONIZE
,
1766 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1767 if (!NT_SUCCESS(Status
))
1769 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1770 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1774 /* Write sector 0 */
1775 FileOffset
.QuadPart
= 0ULL;
1776 Status
= NtWriteFile(FileHandle
,
1785 if (!NT_SUCCESS(Status
))
1787 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1788 NtClose(FileHandle
);
1789 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1793 /* Write backup boot sector */
1794 if ((BackupBootSector
!= 0x0000) && (BackupBootSector
!= 0xFFFF))
1796 FileOffset
.QuadPart
= (ULONGLONG
)((ULONG
)BackupBootSector
* SECTORSIZE
);
1797 Status
= NtWriteFile(FileHandle
,
1806 if (!NT_SUCCESS(Status
))
1808 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1809 NtClose(FileHandle
);
1810 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1815 /* Write sector 14 */
1816 FileOffset
.QuadPart
= 14 * SECTORSIZE
;
1817 Status
= NtWriteFile(FileHandle
,
1822 ((PUCHAR
)NewBootSector
+ SECTORSIZE
),
1826 if (!NT_SUCCESS(Status
))
1828 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1830 NtClose(FileHandle
);
1832 /* Free the new boot sector */
1833 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1840 InstallExt2BootCodeToDisk(
1845 UNICODE_STRING Name
;
1846 OBJECT_ATTRIBUTES ObjectAttributes
;
1847 IO_STATUS_BLOCK IoStatusBlock
;
1849 LARGE_INTEGER FileOffset
;
1850 // PEXT2_BOOTSECTOR OrigBootSector;
1851 PEXT2_BOOTSECTOR NewBootSector
;
1852 // USHORT BackupBootSector;
1855 /* Allocate buffer for original bootsector */
1856 OrigBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
1857 if (OrigBootSector
== NULL
)
1858 return STATUS_INSUFFICIENT_RESOURCES
;
1860 /* Read current boot sector into buffer */
1861 RtlInitUnicodeString(&Name
, RootPath
);
1863 InitializeObjectAttributes(&ObjectAttributes
,
1865 OBJ_CASE_INSENSITIVE
,
1869 Status
= NtOpenFile(&FileHandle
,
1870 GENERIC_READ
| SYNCHRONIZE
,
1874 FILE_SYNCHRONOUS_IO_NONALERT
);
1875 if (!NT_SUCCESS(Status
))
1877 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1881 FileOffset
.QuadPart
= 0ULL;
1882 Status
= NtReadFile(FileHandle
,
1891 NtClose(FileHandle
);
1892 if (!NT_SUCCESS(Status
))
1894 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1899 /* Allocate buffer for new bootsector */
1900 NewBootSector
= RtlAllocateHeap(ProcessHeap
, 0, sizeof(EXT2_BOOTSECTOR
));
1901 if (NewBootSector
== NULL
)
1903 // RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1904 return STATUS_INSUFFICIENT_RESOURCES
;
1907 /* Read new bootsector from SrcPath */
1908 RtlInitUnicodeString(&Name
, SrcPath
);
1910 InitializeObjectAttributes(&ObjectAttributes
,
1912 OBJ_CASE_INSENSITIVE
,
1916 Status
= NtOpenFile(&FileHandle
,
1917 GENERIC_READ
| SYNCHRONIZE
,
1921 FILE_SYNCHRONOUS_IO_NONALERT
);
1922 if (!NT_SUCCESS(Status
))
1924 // RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1925 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1929 Status
= NtReadFile(FileHandle
,
1935 sizeof(EXT2_BOOTSECTOR
),
1938 NtClose(FileHandle
);
1939 if (!NT_SUCCESS(Status
))
1941 // RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1942 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1947 /* Adjust bootsector (copy a part of the FAT32 BPB) */
1948 memcpy(&NewBootSector
->OemName
,
1949 &OrigBootSector
->OemName
,
1950 FIELD_OFFSET(FAT32_BOOTSECTOR
, BootCodeAndData
) -
1951 FIELD_OFFSET(FAT32_BOOTSECTOR
, OemName
));
1953 NewBootSector
->HiddenSectors
= PartitionList
->CurrentDisk
->SectorsPerTrack
;
1955 /* Get the location of the backup boot sector */
1956 BackupBootSector
= OrigBootSector
->BackupBootSector
;
1958 /* Free the original boot sector */
1959 // RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1962 /* Write new bootsector to RootPath */
1963 RtlInitUnicodeString(&Name
, RootPath
);
1965 InitializeObjectAttributes(&ObjectAttributes
,
1971 Status
= NtOpenFile(&FileHandle
,
1972 GENERIC_WRITE
| SYNCHRONIZE
,
1976 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1977 if (!NT_SUCCESS(Status
))
1979 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1980 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1984 /* Write sector 0 */
1985 FileOffset
.QuadPart
= 0ULL;
1986 Status
= NtWriteFile(FileHandle
,
1992 sizeof(EXT2_BOOTSECTOR
),
1996 if (!NT_SUCCESS(Status
))
1998 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1999 NtClose(FileHandle
);
2000 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
2004 /* Write backup boot sector */
2005 if ((BackupBootSector
!= 0x0000) && (BackupBootSector
!= 0xFFFF))
2007 FileOffset
.QuadPart
= (ULONGLONG
)((ULONG
)BackupBootSector
* SECTORSIZE
);
2008 Status
= NtWriteFile(FileHandle
,
2017 if (!NT_SUCCESS(Status
))
2019 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
2020 NtClose(FileHandle
);
2021 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
2026 /* Write sector 14 */
2027 FileOffset
.QuadPart
= 14 * SECTORSIZE
;
2028 Status
= NtWriteFile(FileHandle
,
2033 ((PUCHAR
)NewBootSector
+ SECTORSIZE
),
2037 if (!NT_SUCCESS(Status
))
2039 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
2042 NtClose(FileHandle
);
2044 /* Free the new boot sector */
2045 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
2057 UNICODE_STRING Name
;
2058 OBJECT_ATTRIBUTES ObjectAttributes
;
2059 IO_STATUS_BLOCK IoStatusBlock
;
2060 FILE_BASIC_INFORMATION FileInfo
;
2063 RtlInitUnicodeString(&Name
, FileName
);
2065 InitializeObjectAttributes(&ObjectAttributes
,
2067 OBJ_CASE_INSENSITIVE
,
2071 Status
= NtOpenFile(&FileHandle
,
2072 GENERIC_READ
| GENERIC_WRITE
| SYNCHRONIZE
,
2076 FILE_SYNCHRONOUS_IO_NONALERT
);
2077 if (Status
== STATUS_NO_SUCH_FILE
)
2079 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
2081 return STATUS_SUCCESS
;
2083 if (!NT_SUCCESS(Status
))
2085 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
2089 Status
= NtQueryInformationFile(FileHandle
,
2092 sizeof(FILE_BASIC_INFORMATION
),
2093 FileBasicInformation
);
2094 if (!NT_SUCCESS(Status
))
2096 DPRINT1("NtQueryInformationFile() failed (Status %lx)\n", Status
);
2097 NtClose(FileHandle
);
2101 *Attributes
= FileInfo
.FileAttributes
;
2103 /* Delete attributes SYSTEM, HIDDEN and READONLY */
2104 FileInfo
.FileAttributes
= FileInfo
.FileAttributes
&
2105 ~(FILE_ATTRIBUTE_SYSTEM
|
2106 FILE_ATTRIBUTE_HIDDEN
|
2107 FILE_ATTRIBUTE_READONLY
);
2109 Status
= NtSetInformationFile(FileHandle
,
2112 sizeof(FILE_BASIC_INFORMATION
),
2113 FileBasicInformation
);
2114 if (!NT_SUCCESS(Status
))
2116 DPRINT1("NtSetInformationFile() failed (Status %lx)\n", Status
);
2119 NtClose(FileHandle
);
2130 UNICODE_STRING Name
;
2131 OBJECT_ATTRIBUTES ObjectAttributes
;
2132 IO_STATUS_BLOCK IoStatusBlock
;
2133 FILE_BASIC_INFORMATION FileInfo
;
2136 RtlInitUnicodeString(&Name
, FileName
);
2138 InitializeObjectAttributes(&ObjectAttributes
,
2140 OBJ_CASE_INSENSITIVE
,
2144 Status
= NtOpenFile(&FileHandle
,
2145 GENERIC_READ
| GENERIC_WRITE
| SYNCHRONIZE
,
2149 FILE_SYNCHRONOUS_IO_NONALERT
);
2150 if (!NT_SUCCESS(Status
))
2152 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
2156 Status
= NtQueryInformationFile(FileHandle
,
2159 sizeof(FILE_BASIC_INFORMATION
),
2160 FileBasicInformation
);
2161 if (!NT_SUCCESS(Status
))
2163 DPRINT1("NtQueryInformationFile() failed (Status %lx)\n", Status
);
2164 NtClose(FileHandle
);
2168 FileInfo
.FileAttributes
= FileInfo
.FileAttributes
| Attributes
;
2170 Status
= NtSetInformationFile(FileHandle
,
2173 sizeof(FILE_BASIC_INFORMATION
),
2174 FileBasicInformation
);
2175 if (!NT_SUCCESS(Status
))
2177 DPRINT1("NtSetInformationFile() failed (Status %lx)\n", Status
);
2180 NtClose(FileHandle
);
2192 PINICACHE Cache
= NULL
;
2193 PINICACHESECTION Section
= NULL
;
2194 ULONG FileAttribute
;
2195 PWCHAR OldValue
= NULL
;
2197 Status
= IniCacheLoad(&Cache
, BootIniPath
, FALSE
);
2198 if (!NT_SUCCESS(Status
))
2203 Section
= IniCacheGetSection(Cache
,
2204 L
"operating systems");
2205 if (Section
== NULL
)
2207 IniCacheDestroy(Cache
);
2208 return STATUS_UNSUCCESSFUL
;
2211 /* Check - maybe record already exists */
2212 Status
= IniCacheGetKey(Section
, EntryName
, &OldValue
);
2214 /* If either key was not found, or contains something else - add new one */
2215 if (!NT_SUCCESS(Status
) || wcscmp(OldValue
, EntryValue
))
2217 IniCacheInsertKey(Section
,
2224 Status
= UnprotectBootIni(BootIniPath
,
2226 if (!NT_SUCCESS(Status
))
2228 IniCacheDestroy(Cache
);
2232 Status
= IniCacheSave(Cache
, BootIniPath
);
2233 if (!NT_SUCCESS(Status
))
2235 IniCacheDestroy(Cache
);
2239 FileAttribute
|= (FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
| FILE_ATTRIBUTE_READONLY
);
2240 Status
= ProtectBootIni(BootIniPath
, FileAttribute
);
2242 IniCacheDestroy(Cache
);
2249 InstallFatBootcodeToPartition(
2250 PUNICODE_STRING SystemRootPath
,
2251 PUNICODE_STRING SourceRootPath
,
2252 PUNICODE_STRING DestinationArcPath
,
2253 UCHAR PartitionType
)
2257 BOOLEAN DoesFreeLdrExist
;
2258 WCHAR SrcPath
[MAX_PATH
];
2259 WCHAR DstPath
[MAX_PATH
];
2261 /* FAT or FAT32 partition */
2262 DPRINT("System path: '%wZ'\n", SystemRootPath
);
2264 /* Copy FreeLoader to the system partition */
2265 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2266 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
2267 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2268 wcscat(DstPath
, L
"\\freeldr.sys");
2270 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2271 Status
= SetupCopyFile(SrcPath
, DstPath
);
2272 if (!NT_SUCCESS(Status
))
2274 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
2278 /* Prepare for possibly copying 'freeldr.ini' */
2279 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2280 wcscat(DstPath
, L
"\\freeldr.ini");
2282 DoesFreeLdrExist
= DoesFileExist(SystemRootPath
->Buffer
, L
"freeldr.ini");
2283 if (DoesFreeLdrExist
)
2285 /* Update existing 'freeldr.ini' */
2286 DPRINT1("Update existing 'freeldr.ini'\n");
2288 Status
= UpdateFreeLoaderIni(DstPath
, DestinationArcPath
->Buffer
);
2289 if (!NT_SUCCESS(Status
))
2291 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
2296 /* Check for NT and other bootloaders */
2298 // FIXME: Check for Vista+ bootloader!
2299 if (DoesFileExist(SystemRootPath
->Buffer
, L
"ntldr") == TRUE
||
2300 DoesFileExist(SystemRootPath
->Buffer
, L
"boot.ini") == TRUE
)
2302 /* Search root directory for 'ntldr' and 'boot.ini' */
2303 DPRINT1("Found Microsoft Windows NT/2000/XP boot loader\n");
2305 /* Create or update 'freeldr.ini' */
2306 if (DoesFreeLdrExist
== FALSE
)
2308 /* Create new 'freeldr.ini' */
2309 DPRINT1("Create new 'freeldr.ini'\n");
2310 // wcscpy(DstPath, SystemRootPath->Buffer);
2311 // wcscat(DstPath, L"\\freeldr.ini");
2313 Status
= CreateFreeLoaderIniForReactOS(DstPath
, DestinationArcPath
->Buffer
);
2314 if (!NT_SUCCESS(Status
))
2316 DPRINT1("CreateFreeLoaderIniForReactOS() failed (Status %lx)\n", Status
);
2320 /* Install new bootcode into a file */
2321 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2322 wcscat(DstPath
, L
"\\bootsect.ros");
2324 if (PartitionType
== PARTITION_FAT32
||
2325 PartitionType
== PARTITION_FAT32_XINT13
)
2327 /* Install FAT32 bootcode */
2328 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2329 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
2331 DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, DstPath
);
2332 Status
= InstallFat32BootCodeToFile(SrcPath
, DstPath
,
2333 SystemRootPath
->Buffer
);
2334 if (!NT_SUCCESS(Status
))
2336 DPRINT1("InstallFat32BootCodeToFile() failed (Status %lx)\n", Status
);
2342 /* Install FAT16 bootcode */
2343 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2344 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2346 DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath
, DstPath
);
2347 Status
= InstallFat16BootCodeToFile(SrcPath
, DstPath
,
2348 SystemRootPath
->Buffer
);
2349 if (!NT_SUCCESS(Status
))
2351 DPRINT1("InstallFat16BootCodeToFile() failed (Status %lx)\n", Status
);
2357 /* Update 'boot.ini' */
2358 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2359 wcscat(DstPath
, L
"\\boot.ini");
2361 DPRINT1("Update 'boot.ini': %S\n", DstPath
);
2362 Status
= UpdateBootIni(DstPath
,
2363 L
"C:\\bootsect.ros",
2365 if (!NT_SUCCESS(Status
))
2367 DPRINT1("UpdateBootIni() failed (Status %lx)\n", Status
);
2373 /* Non-NT bootloaders: install our own bootloader */
2378 PWCHAR BootPartition
;
2380 PWCHAR BootSectorFileName
;
2382 if (DoesFileExist(SystemRootPath
->Buffer
, L
"io.sys") == TRUE
||
2383 DoesFileExist(SystemRootPath
->Buffer
, L
"msdos.sys") == TRUE
)
2385 /* Search for root directory for 'io.sys' and 'msdos.sys' */
2386 DPRINT1("Found Microsoft DOS or Windows 9x boot loader\n");
2389 Description
= L
"\"DOS/Windows\"";
2391 BootPartition
= L
"1";
2392 BootSector
= L
"BOOTSECT.DOS";
2394 BootSectorFileName
= L
"\\bootsect.dos";
2397 if (DoesFileExist(SystemRootPath
->Buffer
, L
"kernel.sys") == TRUE
)
2399 /* Search for root directory for 'kernel.sys' */
2400 DPRINT1("Found FreeDOS boot loader\n");
2403 Description
= L
"\"FreeDOS\"";
2405 BootPartition
= L
"1";
2406 BootSector
= L
"BOOTSECT.DOS";
2408 BootSectorFileName
= L
"\\bootsect.dos";
2412 /* No or unknown boot loader */
2413 DPRINT1("No or unknown boot loader found\n");
2415 Section
= L
"Unknown";
2416 Description
= L
"\"Unknown Operating System\"";
2418 BootPartition
= L
"1";
2419 BootSector
= L
"BOOTSECT.OLD";
2421 BootSectorFileName
= L
"\\bootsect.old";
2424 /* Create or update 'freeldr.ini' */
2425 if (DoesFreeLdrExist
== FALSE
)
2427 /* Create new 'freeldr.ini' */
2428 DPRINT1("Create new 'freeldr.ini'\n");
2429 // wcscpy(DstPath, SystemRootPath->Buffer);
2430 // wcscat(DstPath, L"\\freeldr.ini");
2432 if (IsThereAValidBootSector(SystemRootPath
->Buffer
))
2434 Status
= CreateFreeLoaderIniForReactOSAndBootSector(
2435 DstPath
, DestinationArcPath
->Buffer
,
2436 Section
, Description
,
2437 BootDrive
, BootPartition
, BootSector
);
2438 if (!NT_SUCCESS(Status
))
2440 DPRINT1("CreateFreeLoaderIniForReactOSAndBootSector() failed (Status %lx)\n", Status
);
2444 /* Save current bootsector */
2445 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2446 wcscat(DstPath
, BootSectorFileName
);
2448 DPRINT1("Save bootsector: %S ==> %S\n", SystemRootPath
->Buffer
, DstPath
);
2449 Status
= SaveBootSector(SystemRootPath
->Buffer
, DstPath
, SECTORSIZE
);
2450 if (!NT_SUCCESS(Status
))
2452 DPRINT1("SaveBootSector() failed (Status %lx)\n", Status
);
2458 Status
= CreateFreeLoaderIniForReactOS(DstPath
, DestinationArcPath
->Buffer
);
2459 if (!NT_SUCCESS(Status
))
2461 DPRINT1("CreateFreeLoaderIniForReactOS() failed (Status %lx)\n", Status
);
2466 /* Install new bootsector on the disk */
2467 if (PartitionType
== PARTITION_FAT32
||
2468 PartitionType
== PARTITION_FAT32_XINT13
)
2470 /* Install FAT32 bootcode */
2471 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2472 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
2474 DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2475 Status
= InstallFat32BootCodeToDisk(SrcPath
, SystemRootPath
->Buffer
);
2476 if (!NT_SUCCESS(Status
))
2478 DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)\n", Status
);
2484 /* Install FAT16 bootcode */
2485 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2486 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2488 DPRINT1("Install FAT16 bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2489 Status
= InstallFat16BootCodeToDisk(SrcPath
, SystemRootPath
->Buffer
);
2490 if (!NT_SUCCESS(Status
))
2492 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status
);
2499 return STATUS_SUCCESS
;
2501 return STATUS_NOT_IMPLEMENTED
;
2507 InstallExt2BootcodeToPartition(
2508 PUNICODE_STRING SystemRootPath
,
2509 PUNICODE_STRING SourceRootPath
,
2510 PUNICODE_STRING DestinationArcPath
,
2511 UCHAR PartitionType
)
2515 BOOLEAN DoesFreeLdrExist
;
2516 WCHAR SrcPath
[MAX_PATH
];
2517 WCHAR DstPath
[MAX_PATH
];
2519 /* EXT2 partition */
2520 DPRINT("System path: '%wZ'\n", SystemRootPath
);
2522 /* Copy FreeLoader to the system partition */
2523 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2524 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
2525 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2526 wcscat(DstPath
, L
"\\freeldr.sys");
2528 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2529 Status
= SetupCopyFile(SrcPath
, DstPath
);
2530 if (!NT_SUCCESS(Status
))
2532 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
2536 /* Prepare for possibly copying 'freeldr.ini' */
2537 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2538 wcscat(DstPath
, L
"\\freeldr.ini");
2540 DoesFreeLdrExist
= DoesFileExist(SystemRootPath
->Buffer
, L
"freeldr.ini");
2541 if (DoesFreeLdrExist
)
2543 /* Update existing 'freeldr.ini' */
2544 DPRINT1("Update existing 'freeldr.ini'\n");
2546 Status
= UpdateFreeLoaderIni(DstPath
, DestinationArcPath
->Buffer
);
2547 if (!NT_SUCCESS(Status
))
2549 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
2554 /* Check for *nix bootloaders */
2556 /* Create or update 'freeldr.ini' */
2557 if (DoesFreeLdrExist
== FALSE
)
2559 /* Create new 'freeldr.ini' */
2560 DPRINT1("Create new 'freeldr.ini'\n");
2561 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2562 wcscat(DstPath
, L
"\\freeldr.ini");
2564 /* Certainly SysLinux, GRUB, LILO... or an unknown boot loader */
2565 DPRINT1("*nix or unknown boot loader found\n");
2567 if (IsThereAValidBootSector(SystemRootPath
->Buffer
))
2569 Status
= CreateFreeLoaderIniForReactOSAndBootSector(
2570 DstPath
, DestinationArcPath
->Buffer
,
2571 L
"Linux", L
"\"Linux\"",
2572 L
"hd0", L
"1", L
"BOOTSECT.OLD");
2573 if (!NT_SUCCESS(Status
))
2575 DPRINT1("CreateFreeLoaderIniForReactOSAndBootSector() failed (Status %lx)\n", Status
);
2579 /* Save current bootsector */
2580 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2581 wcscat(DstPath
, L
"\\bootsect.old");
2583 DPRINT1("Save bootsector: %S ==> %S\n", SystemRootPath
->Buffer
, DstPath
);
2584 Status
= SaveBootSector(SystemRootPath
->Buffer
, DstPath
, sizeof(EXT2_BOOTSECTOR
));
2585 if (!NT_SUCCESS(Status
))
2587 DPRINT1("SaveBootSector() failed (Status %lx)\n", Status
);
2593 Status
= CreateFreeLoaderIniForReactOS(DstPath
, DestinationArcPath
->Buffer
);
2594 if (!NT_SUCCESS(Status
))
2596 DPRINT1("CreateFreeLoaderIniForReactOS() failed (Status %lx)\n", Status
);
2601 /* Install new bootsector on the disk */
2602 // if (PartitionType == PARTITION_EXT2)
2604 /* Install EXT2 bootcode */
2605 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2606 wcscat(SrcPath
, L
"\\loader\\ext2.bin");
2608 DPRINT1("Install EXT2 bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2609 Status
= InstallExt2BootCodeToDisk(SrcPath
, SystemRootPath
->Buffer
);
2610 if (!NT_SUCCESS(Status
))
2612 DPRINT1("InstallExt2BootCodeToDisk() failed (Status %lx)\n", Status
);
2618 return STATUS_SUCCESS
;
2620 return STATUS_NOT_IMPLEMENTED
;
2626 InstallVBRToPartition(
2627 PUNICODE_STRING SystemRootPath
,
2628 PUNICODE_STRING SourceRootPath
,
2629 PUNICODE_STRING DestinationArcPath
,
2630 UCHAR PartitionType
)
2632 switch (PartitionType
)
2634 case PARTITION_FAT_12
:
2635 case PARTITION_FAT_16
:
2636 case PARTITION_HUGE
:
2637 case PARTITION_XINT13
:
2638 case PARTITION_FAT32
:
2639 case PARTITION_FAT32_XINT13
:
2641 return InstallFatBootcodeToPartition(SystemRootPath
,
2647 case PARTITION_EXT2
:
2649 return InstallExt2BootcodeToPartition(SystemRootPath
,
2659 DPRINT1("PartitionType 0x%02X unknown!\n", PartitionType
);
2663 return STATUS_UNSUCCESSFUL
;
2668 InstallFatBootcodeToFloppy(
2669 PUNICODE_STRING SourceRootPath
,
2670 PUNICODE_STRING DestinationArcPath
)
2674 UNICODE_STRING FloppyDevice
= RTL_CONSTANT_STRING(L
"\\Device\\Floppy0");
2675 WCHAR SrcPath
[MAX_PATH
];
2676 WCHAR DstPath
[MAX_PATH
];
2678 /* Format the floppy first */
2679 Status
= VfatFormat(&FloppyDevice
,
2685 if (!NT_SUCCESS(Status
))
2687 DPRINT1("VfatFormat() failed (Status %lx)\n", Status
);
2691 /* Copy FreeLoader to the boot partition */
2692 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2693 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
2695 wcscpy(DstPath
, L
"\\Device\\Floppy0\\freeldr.sys");
2697 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2698 Status
= SetupCopyFile(SrcPath
, DstPath
);
2699 if (!NT_SUCCESS(Status
))
2701 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
2705 /* Create new 'freeldr.ini' */
2706 wcscpy(DstPath
, L
"\\Device\\Floppy0\\freeldr.ini");
2708 DPRINT("Create new 'freeldr.ini'\n");
2709 Status
= CreateFreeLoaderIniForReactOS(DstPath
, DestinationArcPath
->Buffer
);
2710 if (!NT_SUCCESS(Status
))
2712 DPRINT1("CreateFreeLoaderIniForReactOS() failed (Status %lx)\n", Status
);
2716 /* Install FAT12/16 boosector */
2717 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2718 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2720 wcscpy(DstPath
, L
"\\Device\\Floppy0");
2722 DPRINT("Install FAT bootcode: %S ==> %S\n", SrcPath
, DstPath
);
2723 Status
= InstallFat12BootCodeToFloppy(SrcPath
, DstPath
);
2724 if (!NT_SUCCESS(Status
))
2726 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status
);
2730 return STATUS_SUCCESS
;
2732 return STATUS_NOT_IMPLEMENTED
;