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
;
631 IsThereAValidBootSector(PWSTR RootPath
)
634 * Check the first DWORD (4 bytes) of the bootsector for a potential
635 * "valid" instruction (the BIOS starts execution of the bootsector
636 * at its beginning). Currently the criterium is that this DWORD must
642 OBJECT_ATTRIBUTES ObjectAttributes
;
643 IO_STATUS_BLOCK IoStatusBlock
;
645 LARGE_INTEGER FileOffset
;
649 /* Allocate buffer for bootsector */
650 BootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
651 if (BootSector
== NULL
)
652 return FALSE
; // STATUS_INSUFFICIENT_RESOURCES;
654 /* Read current boot sector into buffer */
655 RtlInitUnicodeString(&Name
, RootPath
);
657 InitializeObjectAttributes(&ObjectAttributes
,
659 OBJ_CASE_INSENSITIVE
,
663 Status
= NtOpenFile(&FileHandle
,
664 GENERIC_READ
| SYNCHRONIZE
,
668 FILE_SYNCHRONOUS_IO_NONALERT
);
669 if (!NT_SUCCESS(Status
))
671 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
672 return FALSE
; // Status;
675 FileOffset
.QuadPart
= 0ULL;
676 Status
= NtReadFile(FileHandle
,
687 Instruction
= *(PULONG
)BootSector
;
689 /* Free the boot sector */
690 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
692 if (!NT_SUCCESS(Status
))
693 return FALSE
; // Status;
695 return (Instruction
!= 0x00000000);
700 SaveCurrentBootSector(
707 OBJECT_ATTRIBUTES ObjectAttributes
;
708 IO_STATUS_BLOCK IoStatusBlock
;
710 LARGE_INTEGER FileOffset
;
713 /* Allocate buffer for bootsector */
714 BootSector
= RtlAllocateHeap(ProcessHeap
, 0, Length
);
715 if (BootSector
== NULL
)
716 return STATUS_INSUFFICIENT_RESOURCES
;
718 /* Read current boot sector into buffer */
719 RtlInitUnicodeString(&Name
, RootPath
);
721 InitializeObjectAttributes(&ObjectAttributes
,
723 OBJ_CASE_INSENSITIVE
,
727 Status
= NtOpenFile(&FileHandle
,
728 GENERIC_READ
| SYNCHRONIZE
,
732 FILE_SYNCHRONOUS_IO_NONALERT
);
733 if (!NT_SUCCESS(Status
))
735 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
739 FileOffset
.QuadPart
= 0ULL;
740 Status
= NtReadFile(FileHandle
,
750 if (!NT_SUCCESS(Status
))
752 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
756 /* Write bootsector to DstPath */
757 RtlInitUnicodeString(&Name
, DstPath
);
759 InitializeObjectAttributes(&ObjectAttributes
,
765 Status
= NtCreateFile(&FileHandle
,
766 GENERIC_WRITE
| SYNCHRONIZE
,
770 FILE_ATTRIBUTE_NORMAL
,
773 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
,
776 if (!NT_SUCCESS(Status
))
778 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
782 Status
= NtWriteFile(FileHandle
,
793 /* Free the boot sector */
794 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
801 InstallFat16BootCodeToFile(
808 OBJECT_ATTRIBUTES ObjectAttributes
;
809 IO_STATUS_BLOCK IoStatusBlock
;
811 LARGE_INTEGER FileOffset
;
812 PFAT_BOOTSECTOR OrigBootSector
;
813 PFAT_BOOTSECTOR NewBootSector
;
815 /* Allocate buffer for original bootsector */
816 OrigBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
817 if (OrigBootSector
== NULL
)
818 return STATUS_INSUFFICIENT_RESOURCES
;
820 /* Read current boot sector into buffer */
821 RtlInitUnicodeString(&Name
, RootPath
);
823 InitializeObjectAttributes(&ObjectAttributes
,
825 OBJ_CASE_INSENSITIVE
,
829 Status
= NtOpenFile(&FileHandle
,
830 GENERIC_READ
| SYNCHRONIZE
,
834 FILE_SYNCHRONOUS_IO_NONALERT
);
835 if (!NT_SUCCESS(Status
))
837 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
841 FileOffset
.QuadPart
= 0ULL;
842 Status
= NtReadFile(FileHandle
,
852 if (!NT_SUCCESS(Status
))
854 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
858 /* Allocate buffer for new bootsector */
859 NewBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
860 if (NewBootSector
== NULL
)
862 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
863 return STATUS_INSUFFICIENT_RESOURCES
;
866 /* Read new bootsector from SrcPath */
867 RtlInitUnicodeString(&Name
, SrcPath
);
869 InitializeObjectAttributes(&ObjectAttributes
,
871 OBJ_CASE_INSENSITIVE
,
875 Status
= NtOpenFile(&FileHandle
,
876 GENERIC_READ
| SYNCHRONIZE
,
880 FILE_SYNCHRONOUS_IO_NONALERT
);
881 if (!NT_SUCCESS(Status
))
883 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
884 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
888 FileOffset
.QuadPart
= 0ULL;
889 Status
= NtReadFile(FileHandle
,
899 if (!NT_SUCCESS(Status
))
901 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
902 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
906 /* Adjust bootsector (copy a part of the FAT BPB) */
907 memcpy(&NewBootSector
->OemName
,
908 &OrigBootSector
->OemName
,
909 FIELD_OFFSET(FAT_BOOTSECTOR
, BootCodeAndData
) -
910 FIELD_OFFSET(FAT_BOOTSECTOR
, OemName
));
912 /* Free the original boot sector */
913 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
915 /* Write new bootsector to DstPath */
916 RtlInitUnicodeString(&Name
, DstPath
);
918 InitializeObjectAttributes(&ObjectAttributes
,
924 Status
= NtCreateFile(&FileHandle
,
925 GENERIC_WRITE
| SYNCHRONIZE
,
929 FILE_ATTRIBUTE_NORMAL
,
932 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
,
935 if (!NT_SUCCESS(Status
))
937 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
941 FileOffset
.QuadPart
= 0ULL;
942 Status
= NtWriteFile(FileHandle
,
953 /* Free the new boot sector */
954 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
961 InstallFat32BootCodeToFile(
968 OBJECT_ATTRIBUTES ObjectAttributes
;
969 IO_STATUS_BLOCK IoStatusBlock
;
971 LARGE_INTEGER FileOffset
;
972 PFAT32_BOOTSECTOR OrigBootSector
;
973 PFAT32_BOOTSECTOR NewBootSector
;
975 /* Allocate buffer for original bootsector */
976 OrigBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
977 if (OrigBootSector
== NULL
)
978 return STATUS_INSUFFICIENT_RESOURCES
;
980 /* Read current boot sector into buffer */
981 RtlInitUnicodeString(&Name
, RootPath
);
983 InitializeObjectAttributes(&ObjectAttributes
,
985 OBJ_CASE_INSENSITIVE
,
989 Status
= NtOpenFile(&FileHandle
,
990 GENERIC_READ
| SYNCHRONIZE
,
994 FILE_SYNCHRONOUS_IO_NONALERT
);
995 if (!NT_SUCCESS(Status
))
997 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1001 FileOffset
.QuadPart
= 0ULL;
1002 Status
= NtReadFile(FileHandle
,
1011 NtClose(FileHandle
);
1012 if (!NT_SUCCESS(Status
))
1014 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1018 /* Allocate buffer for new bootsector (2 sectors) */
1019 NewBootSector
= RtlAllocateHeap(ProcessHeap
, 0, 2 * SECTORSIZE
);
1020 if (NewBootSector
== NULL
)
1022 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1023 return STATUS_INSUFFICIENT_RESOURCES
;
1026 /* Read new bootsector from SrcPath */
1027 RtlInitUnicodeString(&Name
, SrcPath
);
1029 InitializeObjectAttributes(&ObjectAttributes
,
1031 OBJ_CASE_INSENSITIVE
,
1035 Status
= NtOpenFile(&FileHandle
,
1036 GENERIC_READ
| SYNCHRONIZE
,
1040 FILE_SYNCHRONOUS_IO_NONALERT
);
1041 if (!NT_SUCCESS(Status
))
1043 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1044 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1048 Status
= NtReadFile(FileHandle
,
1057 NtClose(FileHandle
);
1058 if (!NT_SUCCESS(Status
))
1060 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1061 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1065 /* Adjust bootsector (copy a part of the FAT32 BPB) */
1066 memcpy(&NewBootSector
->OemName
,
1067 &OrigBootSector
->OemName
,
1068 FIELD_OFFSET(FAT32_BOOTSECTOR
, BootCodeAndData
) -
1069 FIELD_OFFSET(FAT32_BOOTSECTOR
, OemName
));
1071 /* Disable the backup boot sector */
1072 NewBootSector
->BackupBootSector
= 0;
1074 /* Free the original boot sector */
1075 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1077 /* Write the first sector of the new bootcode to DstPath */
1078 RtlInitUnicodeString(&Name
, DstPath
);
1080 InitializeObjectAttributes(&ObjectAttributes
,
1086 Status
= NtCreateFile(&FileHandle
,
1087 GENERIC_WRITE
| SYNCHRONIZE
,
1091 FILE_ATTRIBUTE_NORMAL
,
1094 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
,
1097 if (!NT_SUCCESS(Status
))
1099 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1103 FileOffset
.QuadPart
= 0ULL;
1104 Status
= NtWriteFile(FileHandle
,
1113 NtClose(FileHandle
);
1114 if (!NT_SUCCESS(Status
))
1116 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1120 /* Write the second sector of the new bootcode to boot disk sector 14 */
1121 RtlInitUnicodeString(&Name
, RootPath
);
1123 InitializeObjectAttributes(&ObjectAttributes
,
1129 Status
= NtOpenFile(&FileHandle
,
1130 GENERIC_WRITE
| SYNCHRONIZE
,
1134 FILE_SYNCHRONOUS_IO_NONALERT
);
1135 if (!NT_SUCCESS(Status
))
1137 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1141 FileOffset
.QuadPart
= (ULONGLONG
)(14 * SECTORSIZE
);
1142 Status
= NtWriteFile(FileHandle
,
1147 ((PUCHAR
)NewBootSector
+ SECTORSIZE
),
1151 if (!NT_SUCCESS(Status
))
1154 NtClose(FileHandle
);
1156 /* Free the new boot sector */
1157 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1164 InstallMbrBootCodeToDisk(
1169 UNICODE_STRING Name
;
1170 OBJECT_ATTRIBUTES ObjectAttributes
;
1171 IO_STATUS_BLOCK IoStatusBlock
;
1173 LARGE_INTEGER FileOffset
;
1174 PPARTITION_SECTOR OrigBootSector
;
1175 PPARTITION_SECTOR NewBootSector
;
1177 /* Allocate buffer for original bootsector */
1178 OrigBootSector
= (PPARTITION_SECTOR
)RtlAllocateHeap(ProcessHeap
,
1180 sizeof(PARTITION_SECTOR
));
1181 if (OrigBootSector
== NULL
)
1182 return STATUS_INSUFFICIENT_RESOURCES
;
1184 /* Read current boot sector into buffer */
1185 RtlInitUnicodeString(&Name
,
1188 InitializeObjectAttributes(&ObjectAttributes
,
1190 OBJ_CASE_INSENSITIVE
,
1194 Status
= NtOpenFile(&FileHandle
,
1195 GENERIC_READ
| SYNCHRONIZE
,
1199 FILE_SYNCHRONOUS_IO_NONALERT
);
1200 if (!NT_SUCCESS(Status
))
1202 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1206 FileOffset
.QuadPart
= 0ULL;
1207 Status
= NtReadFile(FileHandle
,
1216 NtClose(FileHandle
);
1217 if (!NT_SUCCESS(Status
))
1219 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1223 /* Allocate buffer for new bootsector */
1224 NewBootSector
= (PPARTITION_SECTOR
)RtlAllocateHeap(ProcessHeap
,
1226 sizeof(PARTITION_SECTOR
));
1227 if (NewBootSector
== NULL
)
1229 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1230 return STATUS_INSUFFICIENT_RESOURCES
;
1233 /* Read new bootsector from SrcPath */
1234 RtlInitUnicodeString(&Name
, SrcPath
);
1236 InitializeObjectAttributes(&ObjectAttributes
,
1238 OBJ_CASE_INSENSITIVE
,
1242 Status
= NtOpenFile(&FileHandle
,
1243 GENERIC_READ
| SYNCHRONIZE
,
1247 FILE_SYNCHRONOUS_IO_NONALERT
);
1248 if (!NT_SUCCESS(Status
))
1250 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1251 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1255 Status
= NtReadFile(FileHandle
,
1261 sizeof(PARTITION_SECTOR
),
1264 NtClose(FileHandle
);
1265 if (!NT_SUCCESS(Status
))
1267 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1268 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1272 /* Copy partition table from old MBR to new */
1273 RtlCopyMemory(&NewBootSector
->Signature
,
1274 &OrigBootSector
->Signature
,
1275 sizeof(PARTITION_SECTOR
) - offsetof(PARTITION_SECTOR
, Signature
) /* Length of partition table */);
1277 /* Free the original boot sector */
1278 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1280 /* Write new bootsector to RootPath */
1281 RtlInitUnicodeString(&Name
, RootPath
);
1283 InitializeObjectAttributes(&ObjectAttributes
,
1289 Status
= NtOpenFile(&FileHandle
,
1290 GENERIC_WRITE
| SYNCHRONIZE
,
1294 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1295 if (!NT_SUCCESS(Status
))
1297 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1298 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1302 FileOffset
.QuadPart
= 0ULL;
1303 Status
= NtWriteFile(FileHandle
,
1312 NtClose(FileHandle
);
1314 /* Free the new boot sector */
1315 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1322 InstallFat12BootCodeToFloppy(
1327 UNICODE_STRING Name
;
1328 OBJECT_ATTRIBUTES ObjectAttributes
;
1329 IO_STATUS_BLOCK IoStatusBlock
;
1331 LARGE_INTEGER FileOffset
;
1332 PFAT_BOOTSECTOR OrigBootSector
;
1333 PFAT_BOOTSECTOR NewBootSector
;
1335 /* Allocate buffer for original bootsector */
1336 OrigBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
1337 if (OrigBootSector
== NULL
)
1338 return STATUS_INSUFFICIENT_RESOURCES
;
1340 /* Read current boot sector into buffer */
1341 RtlInitUnicodeString(&Name
, RootPath
);
1343 InitializeObjectAttributes(&ObjectAttributes
,
1345 OBJ_CASE_INSENSITIVE
,
1349 Status
= NtOpenFile(&FileHandle
,
1350 GENERIC_READ
| SYNCHRONIZE
,
1354 FILE_SYNCHRONOUS_IO_NONALERT
);
1355 if (!NT_SUCCESS(Status
))
1357 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1361 FileOffset
.QuadPart
= 0ULL;
1362 Status
= NtReadFile(FileHandle
,
1371 NtClose(FileHandle
);
1372 if (!NT_SUCCESS(Status
))
1374 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1378 /* Allocate buffer for new bootsector */
1379 NewBootSector
= RtlAllocateHeap(ProcessHeap
,
1382 if (NewBootSector
== NULL
)
1384 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1385 return STATUS_INSUFFICIENT_RESOURCES
;
1388 /* Read new bootsector from SrcPath */
1389 RtlInitUnicodeString(&Name
, SrcPath
);
1391 InitializeObjectAttributes(&ObjectAttributes
,
1393 OBJ_CASE_INSENSITIVE
,
1397 Status
= NtOpenFile(&FileHandle
,
1398 GENERIC_READ
| SYNCHRONIZE
,
1402 FILE_SYNCHRONOUS_IO_NONALERT
);
1403 if (!NT_SUCCESS(Status
))
1405 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1406 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1410 Status
= NtReadFile(FileHandle
,
1419 NtClose(FileHandle
);
1420 if (!NT_SUCCESS(Status
))
1422 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1423 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1427 /* Adjust bootsector (copy a part of the FAT16 BPB) */
1428 memcpy(&NewBootSector
->OemName
,
1429 &OrigBootSector
->OemName
,
1430 FIELD_OFFSET(FAT_BOOTSECTOR
, BootCodeAndData
) -
1431 FIELD_OFFSET(FAT_BOOTSECTOR
, OemName
));
1433 /* Free the original boot sector */
1434 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1436 /* Write new bootsector to RootPath */
1437 RtlInitUnicodeString(&Name
, RootPath
);
1439 InitializeObjectAttributes(&ObjectAttributes
,
1445 Status
= NtOpenFile(&FileHandle
,
1446 GENERIC_WRITE
| SYNCHRONIZE
,
1450 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1451 if (!NT_SUCCESS(Status
))
1453 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1454 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1458 FileOffset
.QuadPart
= 0ULL;
1459 Status
= NtWriteFile(FileHandle
,
1468 NtClose(FileHandle
);
1470 /* Free the new boot sector */
1471 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1478 InstallFat16BootCodeToDisk(
1483 UNICODE_STRING Name
;
1484 OBJECT_ATTRIBUTES ObjectAttributes
;
1485 IO_STATUS_BLOCK IoStatusBlock
;
1487 LARGE_INTEGER FileOffset
;
1488 PFAT_BOOTSECTOR OrigBootSector
;
1489 PFAT_BOOTSECTOR NewBootSector
;
1491 /* Allocate buffer for original bootsector */
1492 OrigBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
1493 if (OrigBootSector
== NULL
)
1494 return STATUS_INSUFFICIENT_RESOURCES
;
1496 /* Read current boot sector into buffer */
1497 RtlInitUnicodeString(&Name
, RootPath
);
1499 InitializeObjectAttributes(&ObjectAttributes
,
1501 OBJ_CASE_INSENSITIVE
,
1505 Status
= NtOpenFile(&FileHandle
,
1506 GENERIC_READ
| SYNCHRONIZE
,
1510 FILE_SYNCHRONOUS_IO_NONALERT
);
1511 if (!NT_SUCCESS(Status
))
1513 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1517 FileOffset
.QuadPart
= 0ULL;
1518 Status
= NtReadFile(FileHandle
,
1527 NtClose(FileHandle
);
1528 if (!NT_SUCCESS(Status
))
1530 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1534 /* Allocate buffer for new bootsector */
1535 NewBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
1536 if (NewBootSector
== NULL
)
1538 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1539 return STATUS_INSUFFICIENT_RESOURCES
;
1542 /* Read new bootsector from SrcPath */
1543 RtlInitUnicodeString(&Name
, SrcPath
);
1545 InitializeObjectAttributes(&ObjectAttributes
,
1547 OBJ_CASE_INSENSITIVE
,
1551 Status
= NtOpenFile(&FileHandle
,
1552 GENERIC_READ
| SYNCHRONIZE
,
1556 FILE_SYNCHRONOUS_IO_NONALERT
);
1557 if (!NT_SUCCESS(Status
))
1559 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1560 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1564 Status
= NtReadFile(FileHandle
,
1573 NtClose(FileHandle
);
1574 if (!NT_SUCCESS(Status
))
1576 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1577 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1581 /* Adjust bootsector (copy a part of the FAT16 BPB) */
1582 memcpy(&NewBootSector
->OemName
,
1583 &OrigBootSector
->OemName
,
1584 FIELD_OFFSET(FAT_BOOTSECTOR
, BootCodeAndData
) -
1585 FIELD_OFFSET(FAT_BOOTSECTOR
, OemName
));
1587 NewBootSector
->HiddenSectors
= PartitionList
->CurrentDisk
->SectorsPerTrack
;
1589 /* Free the original boot sector */
1590 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1592 /* Write new bootsector to RootPath */
1593 RtlInitUnicodeString(&Name
, RootPath
);
1595 InitializeObjectAttributes(&ObjectAttributes
,
1601 Status
= NtOpenFile(&FileHandle
,
1602 GENERIC_WRITE
| SYNCHRONIZE
,
1606 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1607 if (!NT_SUCCESS(Status
))
1609 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1610 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1614 FileOffset
.QuadPart
= 0ULL;
1615 Status
= NtWriteFile(FileHandle
,
1624 NtClose(FileHandle
);
1626 /* Free the new boot sector */
1627 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1634 InstallFat32BootCodeToDisk(
1639 UNICODE_STRING Name
;
1640 OBJECT_ATTRIBUTES ObjectAttributes
;
1641 IO_STATUS_BLOCK IoStatusBlock
;
1643 LARGE_INTEGER FileOffset
;
1644 PFAT32_BOOTSECTOR OrigBootSector
;
1645 PFAT32_BOOTSECTOR NewBootSector
;
1646 USHORT BackupBootSector
;
1648 /* Allocate buffer for original bootsector */
1649 OrigBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
1650 if (OrigBootSector
== NULL
)
1651 return STATUS_INSUFFICIENT_RESOURCES
;
1653 /* Read current boot sector into buffer */
1654 RtlInitUnicodeString(&Name
, RootPath
);
1656 InitializeObjectAttributes(&ObjectAttributes
,
1658 OBJ_CASE_INSENSITIVE
,
1662 Status
= NtOpenFile(&FileHandle
,
1663 GENERIC_READ
| SYNCHRONIZE
,
1667 FILE_SYNCHRONOUS_IO_NONALERT
);
1668 if (!NT_SUCCESS(Status
))
1670 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1674 FileOffset
.QuadPart
= 0ULL;
1675 Status
= NtReadFile(FileHandle
,
1684 NtClose(FileHandle
);
1685 if (!NT_SUCCESS(Status
))
1687 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1692 /* Allocate buffer for new bootsector (2 sectors) */
1693 NewBootSector
= RtlAllocateHeap(ProcessHeap
, 0, 2 * SECTORSIZE
);
1694 if (NewBootSector
== NULL
)
1696 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1697 return STATUS_INSUFFICIENT_RESOURCES
;
1700 /* Read new bootsector from SrcPath */
1701 RtlInitUnicodeString(&Name
, SrcPath
);
1703 InitializeObjectAttributes(&ObjectAttributes
,
1705 OBJ_CASE_INSENSITIVE
,
1709 Status
= NtOpenFile(&FileHandle
,
1710 GENERIC_READ
| SYNCHRONIZE
,
1714 FILE_SYNCHRONOUS_IO_NONALERT
);
1715 if (!NT_SUCCESS(Status
))
1717 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1718 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1722 Status
= NtReadFile(FileHandle
,
1731 NtClose(FileHandle
);
1732 if (!NT_SUCCESS(Status
))
1734 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1735 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1739 /* Adjust bootsector (copy a part of the FAT32 BPB) */
1740 memcpy(&NewBootSector
->OemName
,
1741 &OrigBootSector
->OemName
,
1742 FIELD_OFFSET(FAT32_BOOTSECTOR
, BootCodeAndData
) -
1743 FIELD_OFFSET(FAT32_BOOTSECTOR
, OemName
));
1745 NewBootSector
->HiddenSectors
= PartitionList
->CurrentDisk
->SectorsPerTrack
;
1747 /* Get the location of the backup boot sector */
1748 BackupBootSector
= OrigBootSector
->BackupBootSector
;
1750 /* Free the original boot sector */
1751 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1753 /* Write the first sector of the new bootcode to DstPath */
1754 RtlInitUnicodeString(&Name
, RootPath
);
1756 InitializeObjectAttributes(&ObjectAttributes
,
1762 Status
= NtOpenFile(&FileHandle
,
1763 GENERIC_WRITE
| SYNCHRONIZE
,
1767 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1768 if (!NT_SUCCESS(Status
))
1770 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1771 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1775 /* Write sector 0 */
1776 FileOffset
.QuadPart
= 0ULL;
1777 Status
= NtWriteFile(FileHandle
,
1786 if (!NT_SUCCESS(Status
))
1788 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1789 NtClose(FileHandle
);
1790 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1794 /* Write backup boot sector */
1795 if ((BackupBootSector
!= 0x0000) && (BackupBootSector
!= 0xFFFF))
1797 FileOffset
.QuadPart
= (ULONGLONG
)((ULONG
)BackupBootSector
* SECTORSIZE
);
1798 Status
= NtWriteFile(FileHandle
,
1807 if (!NT_SUCCESS(Status
))
1809 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1810 NtClose(FileHandle
);
1811 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1816 /* Write sector 14 */
1817 FileOffset
.QuadPart
= 14 * SECTORSIZE
;
1818 Status
= NtWriteFile(FileHandle
,
1823 ((PUCHAR
)NewBootSector
+ SECTORSIZE
),
1827 if (!NT_SUCCESS(Status
))
1829 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1831 NtClose(FileHandle
);
1833 /* Free the new boot sector */
1834 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1841 InstallExt2BootCodeToDisk(
1846 UNICODE_STRING Name
;
1847 OBJECT_ATTRIBUTES ObjectAttributes
;
1848 IO_STATUS_BLOCK IoStatusBlock
;
1850 LARGE_INTEGER FileOffset
;
1851 // PEXT2_BOOTSECTOR OrigBootSector;
1852 PEXT2_BOOTSECTOR NewBootSector
;
1853 // USHORT BackupBootSector;
1856 /* Allocate buffer for original bootsector */
1857 OrigBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
1858 if (OrigBootSector
== NULL
)
1859 return STATUS_INSUFFICIENT_RESOURCES
;
1861 /* Read current boot sector into buffer */
1862 RtlInitUnicodeString(&Name
, RootPath
);
1864 InitializeObjectAttributes(&ObjectAttributes
,
1866 OBJ_CASE_INSENSITIVE
,
1870 Status
= NtOpenFile(&FileHandle
,
1871 GENERIC_READ
| SYNCHRONIZE
,
1875 FILE_SYNCHRONOUS_IO_NONALERT
);
1876 if (!NT_SUCCESS(Status
))
1878 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1882 FileOffset
.QuadPart
= 0ULL;
1883 Status
= NtReadFile(FileHandle
,
1892 NtClose(FileHandle
);
1893 if (!NT_SUCCESS(Status
))
1895 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1900 /* Allocate buffer for new bootsector */
1901 NewBootSector
= RtlAllocateHeap(ProcessHeap
, 0, sizeof(EXT2_BOOTSECTOR
));
1902 if (NewBootSector
== NULL
)
1904 // RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1905 return STATUS_INSUFFICIENT_RESOURCES
;
1908 /* Read new bootsector from SrcPath */
1909 RtlInitUnicodeString(&Name
, SrcPath
);
1911 InitializeObjectAttributes(&ObjectAttributes
,
1913 OBJ_CASE_INSENSITIVE
,
1917 Status
= NtOpenFile(&FileHandle
,
1918 GENERIC_READ
| SYNCHRONIZE
,
1922 FILE_SYNCHRONOUS_IO_NONALERT
);
1923 if (!NT_SUCCESS(Status
))
1925 // RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1926 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1930 Status
= NtReadFile(FileHandle
,
1936 sizeof(EXT2_BOOTSECTOR
),
1939 NtClose(FileHandle
);
1940 if (!NT_SUCCESS(Status
))
1942 // RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1943 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1948 /* Adjust bootsector (copy a part of the FAT32 BPB) */
1949 memcpy(&NewBootSector
->OemName
,
1950 &OrigBootSector
->OemName
,
1951 FIELD_OFFSET(FAT32_BOOTSECTOR
, BootCodeAndData
) -
1952 FIELD_OFFSET(FAT32_BOOTSECTOR
, OemName
));
1954 NewBootSector
->HiddenSectors
= PartitionList
->CurrentDisk
->SectorsPerTrack
;
1956 /* Get the location of the backup boot sector */
1957 BackupBootSector
= OrigBootSector
->BackupBootSector
;
1959 /* Free the original boot sector */
1960 // RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1963 /* Write new bootsector to RootPath */
1964 RtlInitUnicodeString(&Name
, RootPath
);
1966 InitializeObjectAttributes(&ObjectAttributes
,
1972 Status
= NtOpenFile(&FileHandle
,
1973 GENERIC_WRITE
| SYNCHRONIZE
,
1977 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1978 if (!NT_SUCCESS(Status
))
1980 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1981 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1985 /* Write sector 0 */
1986 FileOffset
.QuadPart
= 0ULL;
1987 Status
= NtWriteFile(FileHandle
,
1993 sizeof(EXT2_BOOTSECTOR
),
1997 if (!NT_SUCCESS(Status
))
1999 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
2000 NtClose(FileHandle
);
2001 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
2005 /* Write backup boot sector */
2006 if ((BackupBootSector
!= 0x0000) && (BackupBootSector
!= 0xFFFF))
2008 FileOffset
.QuadPart
= (ULONGLONG
)((ULONG
)BackupBootSector
* SECTORSIZE
);
2009 Status
= NtWriteFile(FileHandle
,
2018 if (!NT_SUCCESS(Status
))
2020 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
2021 NtClose(FileHandle
);
2022 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
2027 /* Write sector 14 */
2028 FileOffset
.QuadPart
= 14 * SECTORSIZE
;
2029 Status
= NtWriteFile(FileHandle
,
2034 ((PUCHAR
)NewBootSector
+ SECTORSIZE
),
2038 if (!NT_SUCCESS(Status
))
2040 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
2043 NtClose(FileHandle
);
2045 /* Free the new boot sector */
2046 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
2058 UNICODE_STRING Name
;
2059 OBJECT_ATTRIBUTES ObjectAttributes
;
2060 IO_STATUS_BLOCK IoStatusBlock
;
2061 FILE_BASIC_INFORMATION FileInfo
;
2064 RtlInitUnicodeString(&Name
, FileName
);
2066 InitializeObjectAttributes(&ObjectAttributes
,
2068 OBJ_CASE_INSENSITIVE
,
2072 Status
= NtOpenFile(&FileHandle
,
2073 GENERIC_READ
| GENERIC_WRITE
| SYNCHRONIZE
,
2077 FILE_SYNCHRONOUS_IO_NONALERT
);
2078 if (Status
== STATUS_NO_SUCH_FILE
)
2080 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
2082 return STATUS_SUCCESS
;
2084 if (!NT_SUCCESS(Status
))
2086 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
2090 Status
= NtQueryInformationFile(FileHandle
,
2093 sizeof(FILE_BASIC_INFORMATION
),
2094 FileBasicInformation
);
2095 if (!NT_SUCCESS(Status
))
2097 DPRINT1("NtQueryInformationFile() failed (Status %lx)\n", Status
);
2098 NtClose(FileHandle
);
2102 *Attributes
= FileInfo
.FileAttributes
;
2104 /* Delete attributes SYSTEM, HIDDEN and READONLY */
2105 FileInfo
.FileAttributes
= FileInfo
.FileAttributes
&
2106 ~(FILE_ATTRIBUTE_SYSTEM
|
2107 FILE_ATTRIBUTE_HIDDEN
|
2108 FILE_ATTRIBUTE_READONLY
);
2110 Status
= NtSetInformationFile(FileHandle
,
2113 sizeof(FILE_BASIC_INFORMATION
),
2114 FileBasicInformation
);
2115 if (!NT_SUCCESS(Status
))
2117 DPRINT1("NtSetInformationFile() failed (Status %lx)\n", Status
);
2120 NtClose(FileHandle
);
2131 UNICODE_STRING Name
;
2132 OBJECT_ATTRIBUTES ObjectAttributes
;
2133 IO_STATUS_BLOCK IoStatusBlock
;
2134 FILE_BASIC_INFORMATION FileInfo
;
2137 RtlInitUnicodeString(&Name
, FileName
);
2139 InitializeObjectAttributes(&ObjectAttributes
,
2141 OBJ_CASE_INSENSITIVE
,
2145 Status
= NtOpenFile(&FileHandle
,
2146 GENERIC_READ
| GENERIC_WRITE
| SYNCHRONIZE
,
2150 FILE_SYNCHRONOUS_IO_NONALERT
);
2151 if (!NT_SUCCESS(Status
))
2153 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
2157 Status
= NtQueryInformationFile(FileHandle
,
2160 sizeof(FILE_BASIC_INFORMATION
),
2161 FileBasicInformation
);
2162 if (!NT_SUCCESS(Status
))
2164 DPRINT1("NtQueryInformationFile() failed (Status %lx)\n", Status
);
2165 NtClose(FileHandle
);
2169 FileInfo
.FileAttributes
= FileInfo
.FileAttributes
| Attributes
;
2171 Status
= NtSetInformationFile(FileHandle
,
2174 sizeof(FILE_BASIC_INFORMATION
),
2175 FileBasicInformation
);
2176 if (!NT_SUCCESS(Status
))
2178 DPRINT1("NtSetInformationFile() failed (Status %lx)\n", Status
);
2181 NtClose(FileHandle
);
2193 PINICACHE Cache
= NULL
;
2194 PINICACHESECTION Section
= NULL
;
2195 ULONG FileAttribute
;
2196 PWCHAR OldValue
= NULL
;
2198 Status
= IniCacheLoad(&Cache
, BootIniPath
, FALSE
);
2199 if (!NT_SUCCESS(Status
))
2204 Section
= IniCacheGetSection(Cache
,
2205 L
"operating systems");
2206 if (Section
== NULL
)
2208 IniCacheDestroy(Cache
);
2209 return STATUS_UNSUCCESSFUL
;
2212 /* Check - maybe record already exists */
2213 Status
= IniCacheGetKey(Section
, EntryName
, &OldValue
);
2215 /* If either key was not found, or contains something else - add new one */
2216 if (!NT_SUCCESS(Status
) || wcscmp(OldValue
, EntryValue
))
2218 IniCacheInsertKey(Section
,
2225 Status
= UnprotectBootIni(BootIniPath
,
2227 if (!NT_SUCCESS(Status
))
2229 IniCacheDestroy(Cache
);
2233 Status
= IniCacheSave(Cache
, BootIniPath
);
2234 if (!NT_SUCCESS(Status
))
2236 IniCacheDestroy(Cache
);
2240 FileAttribute
|= (FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
| FILE_ATTRIBUTE_READONLY
);
2241 Status
= ProtectBootIni(BootIniPath
, FileAttribute
);
2243 IniCacheDestroy(Cache
);
2250 InstallFatBootcodeToPartition(
2251 PUNICODE_STRING SystemRootPath
,
2252 PUNICODE_STRING SourceRootPath
,
2253 PUNICODE_STRING DestinationArcPath
,
2254 UCHAR PartitionType
)
2258 BOOLEAN DoesFreeLdrExist
;
2259 WCHAR SrcPath
[MAX_PATH
];
2260 WCHAR DstPath
[MAX_PATH
];
2262 /* FAT or FAT32 partition */
2263 DPRINT("System path: '%wZ'\n", SystemRootPath
);
2265 /* Copy FreeLoader to the system partition */
2266 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2267 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
2268 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2269 wcscat(DstPath
, L
"\\freeldr.sys");
2271 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2272 Status
= SetupCopyFile(SrcPath
, DstPath
);
2273 if (!NT_SUCCESS(Status
))
2275 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
2279 /* Prepare for possibly copying 'freeldr.ini' */
2280 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2281 wcscat(DstPath
, L
"\\freeldr.ini");
2283 DoesFreeLdrExist
= DoesFileExist(SystemRootPath
->Buffer
, L
"freeldr.ini");
2284 if (DoesFreeLdrExist
)
2286 /* Update existing 'freeldr.ini' */
2287 DPRINT1("Update existing 'freeldr.ini'\n");
2289 Status
= UpdateFreeLoaderIni(DstPath
, DestinationArcPath
->Buffer
);
2290 if (!NT_SUCCESS(Status
))
2292 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
2297 /* Check for NT and other bootloaders */
2299 // FIXME: Check for Vista+ bootloader!
2300 if (DoesFileExist(SystemRootPath
->Buffer
, L
"ntldr") == TRUE
||
2301 DoesFileExist(SystemRootPath
->Buffer
, L
"boot.ini") == TRUE
)
2303 /* Search root directory for 'ntldr' and 'boot.ini' */
2304 DPRINT1("Found Microsoft Windows NT/2000/XP boot loader\n");
2306 /* Create or update 'freeldr.ini' */
2307 if (DoesFreeLdrExist
== FALSE
)
2309 /* Create new 'freeldr.ini' */
2310 DPRINT1("Create new 'freeldr.ini'\n");
2311 // wcscpy(DstPath, SystemRootPath->Buffer);
2312 // wcscat(DstPath, L"\\freeldr.ini");
2314 Status
= CreateFreeLoaderIniForReactOS(DstPath
, DestinationArcPath
->Buffer
);
2315 if (!NT_SUCCESS(Status
))
2317 DPRINT1("CreateFreeLoaderIniForReactOS() failed (Status %lx)\n", Status
);
2321 /* Install new bootcode into a file */
2322 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2323 wcscat(DstPath
, L
"\\bootsect.ros");
2325 if (PartitionType
== PARTITION_FAT32
||
2326 PartitionType
== PARTITION_FAT32_XINT13
)
2328 /* Install FAT32 bootcode */
2329 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2330 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
2332 DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, DstPath
);
2333 Status
= InstallFat32BootCodeToFile(SrcPath
, DstPath
,
2334 SystemRootPath
->Buffer
);
2335 if (!NT_SUCCESS(Status
))
2337 DPRINT1("InstallFat32BootCodeToFile() failed (Status %lx)\n", Status
);
2343 /* Install FAT16 bootcode */
2344 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2345 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2347 DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath
, DstPath
);
2348 Status
= InstallFat16BootCodeToFile(SrcPath
, DstPath
,
2349 SystemRootPath
->Buffer
);
2350 if (!NT_SUCCESS(Status
))
2352 DPRINT1("InstallFat16BootCodeToFile() failed (Status %lx)\n", Status
);
2358 /* Update 'boot.ini' */
2359 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2360 wcscat(DstPath
, L
"\\boot.ini");
2362 DPRINT1("Update 'boot.ini': %S\n", DstPath
);
2363 Status
= UpdateBootIni(DstPath
,
2364 L
"C:\\bootsect.ros",
2366 if (!NT_SUCCESS(Status
))
2368 DPRINT1("UpdateBootIni() failed (Status %lx)\n", Status
);
2374 /* Non-NT bootloaders: install our own bootloader */
2379 PWCHAR BootPartition
;
2381 PWCHAR BootSectorFileName
;
2383 if (DoesFileExist(SystemRootPath
->Buffer
, L
"io.sys") == TRUE
||
2384 DoesFileExist(SystemRootPath
->Buffer
, L
"msdos.sys") == TRUE
)
2386 /* Search for root directory for 'io.sys' and 'msdos.sys' */
2387 DPRINT1("Found Microsoft DOS or Windows 9x boot loader\n");
2390 Description
= L
"\"DOS/Windows\"";
2392 BootPartition
= L
"1";
2393 BootSector
= L
"BOOTSECT.DOS";
2395 BootSectorFileName
= L
"\\bootsect.dos";
2398 if (DoesFileExist(SystemRootPath
->Buffer
, L
"kernel.sys") == TRUE
)
2400 /* Search for root directory for 'kernel.sys' */
2401 DPRINT1("Found FreeDOS boot loader\n");
2404 Description
= L
"\"FreeDOS\"";
2406 BootPartition
= L
"1";
2407 BootSector
= L
"BOOTSECT.DOS";
2409 BootSectorFileName
= L
"\\bootsect.dos";
2413 /* No or unknown boot loader */
2414 DPRINT1("No or unknown boot loader found\n");
2416 Section
= L
"Unknown";
2417 Description
= L
"\"Unknown Operating System\"";
2419 BootPartition
= L
"1";
2420 BootSector
= L
"BOOTSECT.OLD";
2422 BootSectorFileName
= L
"\\bootsect.old";
2425 /* Create or update 'freeldr.ini' */
2426 if (DoesFreeLdrExist
== FALSE
)
2428 /* Create new 'freeldr.ini' */
2429 DPRINT1("Create new 'freeldr.ini'\n");
2430 // wcscpy(DstPath, SystemRootPath->Buffer);
2431 // wcscat(DstPath, L"\\freeldr.ini");
2433 if (IsThereAValidBootSector(SystemRootPath
->Buffer
))
2435 Status
= CreateFreeLoaderIniForReactOSAndBootSector(
2436 DstPath
, DestinationArcPath
->Buffer
,
2437 Section
, Description
,
2438 BootDrive
, BootPartition
, BootSector
);
2439 if (!NT_SUCCESS(Status
))
2441 DPRINT1("CreateFreeLoaderIniForReactOSAndBootSector() failed (Status %lx)\n", Status
);
2445 /* Save current bootsector */
2446 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2447 wcscat(DstPath
, BootSectorFileName
);
2449 DPRINT1("Save bootsector: %S ==> %S\n", SystemRootPath
->Buffer
, DstPath
);
2450 Status
= SaveCurrentBootSector(SystemRootPath
->Buffer
, DstPath
, SECTORSIZE
);
2451 if (!NT_SUCCESS(Status
))
2453 DPRINT1("SaveCurrentBootSector() failed (Status %lx)\n", Status
);
2459 Status
= CreateFreeLoaderIniForReactOS(DstPath
, DestinationArcPath
->Buffer
);
2460 if (!NT_SUCCESS(Status
))
2462 DPRINT1("CreateFreeLoaderIniForReactOS() failed (Status %lx)\n", Status
);
2467 /* Install new bootsector on the disk */
2468 if (PartitionType
== PARTITION_FAT32
||
2469 PartitionType
== PARTITION_FAT32_XINT13
)
2471 /* Install FAT32 bootcode */
2472 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2473 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
2475 DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2476 Status
= InstallFat32BootCodeToDisk(SrcPath
, SystemRootPath
->Buffer
);
2477 if (!NT_SUCCESS(Status
))
2479 DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)\n", Status
);
2485 /* Install FAT16 bootcode */
2486 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2487 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2489 DPRINT1("Install FAT16 bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2490 Status
= InstallFat16BootCodeToDisk(SrcPath
, SystemRootPath
->Buffer
);
2491 if (!NT_SUCCESS(Status
))
2493 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status
);
2500 return STATUS_SUCCESS
;
2502 return STATUS_NOT_IMPLEMENTED
;
2508 InstallExt2BootcodeToPartition(
2509 PUNICODE_STRING SystemRootPath
,
2510 PUNICODE_STRING SourceRootPath
,
2511 PUNICODE_STRING DestinationArcPath
,
2512 UCHAR PartitionType
)
2516 BOOLEAN DoesFreeLdrExist
;
2517 WCHAR SrcPath
[MAX_PATH
];
2518 WCHAR DstPath
[MAX_PATH
];
2520 /* EXT2 partition */
2521 DPRINT("System path: '%wZ'\n", SystemRootPath
);
2523 /* Copy FreeLoader to the system partition */
2524 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2525 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
2526 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2527 wcscat(DstPath
, L
"\\freeldr.sys");
2529 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2530 Status
= SetupCopyFile(SrcPath
, DstPath
);
2531 if (!NT_SUCCESS(Status
))
2533 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
2537 /* Prepare for possibly copying 'freeldr.ini' */
2538 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2539 wcscat(DstPath
, L
"\\freeldr.ini");
2541 DoesFreeLdrExist
= DoesFileExist(SystemRootPath
->Buffer
, L
"freeldr.ini");
2542 if (DoesFreeLdrExist
)
2544 /* Update existing 'freeldr.ini' */
2545 DPRINT1("Update existing 'freeldr.ini'\n");
2547 Status
= UpdateFreeLoaderIni(DstPath
, DestinationArcPath
->Buffer
);
2548 if (!NT_SUCCESS(Status
))
2550 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
2555 /* Check for *nix bootloaders */
2557 /* Create or update 'freeldr.ini' */
2558 if (DoesFreeLdrExist
== FALSE
)
2560 /* Create new 'freeldr.ini' */
2561 DPRINT1("Create new 'freeldr.ini'\n");
2562 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2563 wcscat(DstPath
, L
"\\freeldr.ini");
2565 /* Certainly SysLinux, GRUB, LILO... or an unknown boot loader */
2566 DPRINT1("*nix or unknown boot loader found\n");
2568 if (IsThereAValidBootSector(SystemRootPath
->Buffer
))
2570 Status
= CreateFreeLoaderIniForReactOSAndBootSector(
2571 DstPath
, DestinationArcPath
->Buffer
,
2572 L
"Linux", L
"\"Linux\"",
2573 L
"hd0", L
"1", L
"BOOTSECT.OLD");
2574 if (!NT_SUCCESS(Status
))
2576 DPRINT1("CreateFreeLoaderIniForReactOSAndBootSector() failed (Status %lx)\n", Status
);
2580 /* Save current bootsector */
2581 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2582 wcscat(DstPath
, L
"\\bootsect.old");
2584 DPRINT1("Save bootsector: %S ==> %S\n", SystemRootPath
->Buffer
, DstPath
);
2585 Status
= SaveCurrentBootSector(SystemRootPath
->Buffer
, DstPath
, sizeof(EXT2_BOOTSECTOR
));
2586 if (!NT_SUCCESS(Status
))
2588 DPRINT1("SaveCurrentBootSector() failed (Status %lx)\n", Status
);
2594 Status
= CreateFreeLoaderIniForReactOS(DstPath
, DestinationArcPath
->Buffer
);
2595 if (!NT_SUCCESS(Status
))
2597 DPRINT1("CreateFreeLoaderIniForReactOS() failed (Status %lx)\n", Status
);
2602 /* Install new bootsector on the disk */
2603 // if (PartitionType == PARTITION_EXT2)
2605 /* Install EXT2 bootcode */
2606 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2607 wcscat(SrcPath
, L
"\\loader\\ext2.bin");
2609 DPRINT1("Install EXT2 bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2610 Status
= InstallExt2BootCodeToDisk(SrcPath
, SystemRootPath
->Buffer
);
2611 if (!NT_SUCCESS(Status
))
2613 DPRINT1("InstallExt2BootCodeToDisk() failed (Status %lx)\n", Status
);
2619 return STATUS_SUCCESS
;
2621 return STATUS_NOT_IMPLEMENTED
;
2627 InstallVBRToPartition(
2628 PUNICODE_STRING SystemRootPath
,
2629 PUNICODE_STRING SourceRootPath
,
2630 PUNICODE_STRING DestinationArcPath
,
2631 UCHAR PartitionType
)
2633 switch (PartitionType
)
2635 case PARTITION_FAT_12
:
2636 case PARTITION_FAT_16
:
2637 case PARTITION_HUGE
:
2638 case PARTITION_XINT13
:
2639 case PARTITION_FAT32
:
2640 case PARTITION_FAT32_XINT13
:
2642 return InstallFatBootcodeToPartition(SystemRootPath
,
2648 case PARTITION_EXT2
:
2650 return InstallExt2BootcodeToPartition(SystemRootPath
,
2660 DPRINT1("PartitionType 0x%02X unknown!\n", PartitionType
);
2664 return STATUS_UNSUCCESSFUL
;
2669 InstallFatBootcodeToFloppy(
2670 PUNICODE_STRING SourceRootPath
,
2671 PUNICODE_STRING DestinationArcPath
)
2675 UNICODE_STRING FloppyDevice
= RTL_CONSTANT_STRING(L
"\\Device\\Floppy0");
2676 WCHAR SrcPath
[MAX_PATH
];
2677 WCHAR DstPath
[MAX_PATH
];
2679 /* Format the floppy first */
2680 Status
= VfatFormat(&FloppyDevice
,
2686 if (!NT_SUCCESS(Status
))
2688 DPRINT1("VfatFormat() failed (Status %lx)\n", Status
);
2692 /* Copy FreeLoader to the boot partition */
2693 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2694 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
2696 wcscpy(DstPath
, L
"\\Device\\Floppy0\\freeldr.sys");
2698 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2699 Status
= SetupCopyFile(SrcPath
, DstPath
);
2700 if (!NT_SUCCESS(Status
))
2702 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
2706 /* Create new 'freeldr.ini' */
2707 wcscpy(DstPath
, L
"\\Device\\Floppy0\\freeldr.ini");
2709 DPRINT("Create new 'freeldr.ini'\n");
2710 Status
= CreateFreeLoaderIniForReactOS(DstPath
, DestinationArcPath
->Buffer
);
2711 if (!NT_SUCCESS(Status
))
2713 DPRINT1("CreateFreeLoaderIniForReactOS() failed (Status %lx)\n", Status
);
2717 /* Install FAT12/16 boosector */
2718 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2719 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2721 wcscpy(DstPath
, L
"\\Device\\Floppy0");
2723 DPRINT("Install FAT bootcode: %S ==> %S\n", SrcPath
, DstPath
);
2724 Status
= InstallFat12BootCodeToFloppy(SrcPath
, DstPath
);
2725 if (!NT_SUCCESS(Status
))
2727 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status
);
2731 return STATUS_SUCCESS
;
2733 return STATUS_NOT_IMPLEMENTED
;