2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS text-mode setup
4 * FILE: subsys/system/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
;
83 extern PPARTLIST PartitionList
;
85 /* FUNCTIONS ****************************************************************/
90 CreateCommonFreeLoaderSections(PINICACHE IniCache
)
92 PINICACHESECTION IniSection
;
94 /* Create "FREELOADER" section */
95 IniSection
= IniCacheAppendSection(IniCache
,
99 if (IsUnattendedSetup
)
101 /* DefaultOS=ReactOS */
102 IniCacheInsertKey(IniSection
,
106 L
"ReactOS_KdSerial");
111 /* DefaultOS=ReactOS */
112 IniCacheInsertKey(IniSection
,
120 if (IsUnattendedSetup
)
123 /* Timeout=0 for unattended or non debug*/
124 IniCacheInsertKey(IniSection
,
133 /* Timeout=0 or 10 */
134 IniCacheInsertKey(IniSection
,
142 /* Create "Display" section */
143 IniSection
= IniCacheAppendSection(IniCache
, L
"Display");
145 /* TitleText=ReactOS Boot Manager */
146 IniCacheInsertKey(IniSection
,
150 L
"ReactOS Boot Manager");
152 /* StatusBarColor=Cyan */
153 IniCacheInsertKey(IniSection
,
159 /* StatusBarTextColor=Black */
160 IniCacheInsertKey(IniSection
,
163 L
"StatusBarTextColor",
166 /* BackdropTextColor=White */
167 IniCacheInsertKey(IniSection
,
170 L
"BackdropTextColor",
173 /* BackdropColor=Blue */
174 IniCacheInsertKey(IniSection
,
180 /* BackdropFillStyle=Medium */
181 IniCacheInsertKey(IniSection
,
184 L
"BackdropFillStyle",
187 /* TitleBoxTextColor=White */
188 IniCacheInsertKey(IniSection
,
191 L
"TitleBoxTextColor",
194 /* TitleBoxColor=Red */
195 IniCacheInsertKey(IniSection
,
201 /* MessageBoxTextColor=White */
202 IniCacheInsertKey(IniSection
,
205 L
"MessageBoxTextColor",
208 /* MessageBoxColor=Blue */
209 IniCacheInsertKey(IniSection
,
215 /* MenuTextColor=White */
216 IniCacheInsertKey(IniSection
,
223 IniCacheInsertKey(IniSection
,
229 /* TextColor=Yellow */
230 IniCacheInsertKey(IniSection
,
236 /* SelectedTextColor=Black */
237 IniCacheInsertKey(IniSection
,
240 L
"SelectedTextColor",
243 /* SelectedColor=Gray */
244 IniCacheInsertKey(IniSection
,
250 /* SelectedColor=Gray */
251 IniCacheInsertKey(IniSection
,
257 /* SelectedColor=Gray */
258 IniCacheInsertKey(IniSection
,
264 /* SelectedColor=Gray */
265 IniCacheInsertKey(IniSection
,
271 /* SelectedColor=Gray */
272 IniCacheInsertKey(IniSection
,
278 /* SelectedColor=Gray */
279 IniCacheInsertKey(IniSection
,
283 L
"Seconds until highlighted choice will be started automatically: ");
288 CreateFreeLoaderIniForDos(
293 PINICACHESECTION IniSection
;
295 IniCache
= IniCacheCreate();
297 CreateCommonFreeLoaderSections(IniCache
);
299 /* Create "Operating Systems" section */
300 IniSection
= IniCacheAppendSection(IniCache
, L
"Operating Systems");
302 /* REACTOS=ReactOS */
303 IniCacheInsertKey(IniSection
,
309 /* ReactOS_Debug="ReactOS (Debug)" */
310 IniCacheInsertKey(IniSection
,
314 L
"\"ReactOS (Debug)\"");
316 /* DOS=Dos/Windows */
317 IniCacheInsertKey(IniSection
,
323 /* Create "ReactOS" section */
324 IniSection
= IniCacheAppendSection(IniCache
, L
"ReactOS");
326 /* BootType=ReactOS */
327 IniCacheInsertKey(IniSection
,
333 /* SystemPath=<ArcPath> */
334 IniCacheInsertKey(IniSection
,
340 /* Create "ReactOS_Debug" section */
341 IniSection
= IniCacheAppendSection(IniCache
, L
"ReactOS_Debug");
343 /* BootType=ReactOS */
344 IniCacheInsertKey(IniSection
,
350 /* SystemPath=<ArcPath> */
351 IniCacheInsertKey(IniSection
,
357 /* Options=/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS */
358 IniCacheInsertKey(IniSection
,
362 L
"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS");
364 /* Create "DOS" section */
365 IniSection
= IniCacheAppendSection(IniCache
,
368 /* BootType=BootSector */
369 IniCacheInsertKey(IniSection
,
376 IniCacheInsertKey(IniSection
,
382 /* BootPartition=1 */
383 IniCacheInsertKey(IniSection
,
389 /* BootSector=BOOTSECT.DOS */
390 IniCacheInsertKey(IniSection
,
396 IniCacheSave(IniCache
, IniPath
);
397 IniCacheDestroy(IniCache
);
399 return STATUS_SUCCESS
;
404 CreateFreeLoaderEntry(
406 PINICACHESECTION OSSection
,
413 PINICACHESECTION IniSection
;
415 /* Insert entry into "Operating Systems" section */
416 IniCacheInsertKey(OSSection
,
422 /* Create new section */
423 IniSection
= IniCacheAppendSection(IniCache
, Section
);
426 IniCacheInsertKey(IniSection
,
433 IniCacheInsertKey(IniSection
,
440 IniCacheInsertKey(IniSection
,
446 return STATUS_SUCCESS
;
450 CreateFreeLoaderIniForReactos(
455 PINICACHESECTION IniSection
;
457 IniCache
= IniCacheCreate();
459 CreateCommonFreeLoaderSections(IniCache
);
461 /* Create "Operating Systems" section */
462 IniSection
= IniCacheAppendSection(IniCache
, L
"Operating Systems");
465 CreateFreeLoaderEntry(IniCache
, IniSection
,
466 L
"ReactOS", L
"\"ReactOS\"",
467 L
"Windows2003", ArcPath
,
471 CreateFreeLoaderEntry(IniCache
, IniSection
,
472 L
"ReactOS_Debug", L
"\"ReactOS (Debug)\"",
473 L
"Windows2003", ArcPath
,
474 L
"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS");
478 /* ReactOS_KdSerial */
479 CreateFreeLoaderEntry(IniCache
, IniSection
,
480 L
"ReactOS_KdSerial", L
"\"ReactOS (RosDbg)\"",
481 L
"Windows2003", ArcPath
,
482 L
"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /KDSERIAL");
485 /* ReactOS_LogFile */
486 CreateFreeLoaderEntry(IniCache
, IniSection
,
487 L
"ReactOS_LogFile", L
"\"ReactOS (Log file)\"",
488 L
"Windows2003", ArcPath
,
489 L
"/DEBUG /DEBUGPORT=FILE /SOS");
492 CreateFreeLoaderEntry(IniCache
, IniSection
,
493 L
"ReactOS_Ram", L
"\"ReactOS (RAM Disk)\"",
494 L
"ReactOS", L
"ramdisk(0)\\ReactOS",
495 L
"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /RDIMAGEPATH=reactos.img /RDIMAGEOFFSET=32256");
498 /* Save the ini file */
499 IniCacheSave(IniCache
, IniPath
);
500 IniCacheDestroy(IniCache
);
502 return STATUS_SUCCESS
;
513 PINICACHESECTION IniSection
;
514 PINICACHESECTION OsIniSection
;
515 WCHAR SectionName
[80];
517 WCHAR SystemPath
[200];
518 WCHAR SectionName2
[200];
523 RtlInitUnicodeString(&Name
, IniPath
);
525 Status
= IniCacheLoad(&IniCache
, &Name
, FALSE
);
526 if (!NT_SUCCESS(Status
))
529 /* Get "Operating Systems" section */
530 IniSection
= IniCacheGetSection(IniCache
, L
"Operating Systems");
531 if (IniSection
== NULL
)
533 IniCacheDestroy(IniCache
);
534 return STATUS_UNSUCCESSFUL
;
537 /* Find an existing usable or an unused section name */
539 wcscpy(SectionName
, L
"ReactOS");
540 wcscpy(OsName
, L
"\"ReactOS\"");
543 Status
= IniCacheGetKey(IniSection
, SectionName
, &KeyData
);
544 if (!NT_SUCCESS(Status
))
547 /* Get operation system section */
548 if (KeyData
[0] == '"')
550 wcscpy(SectionName2
, &KeyData
[1]);
551 j
= wcslen(SectionName2
);
554 SectionName2
[j
-1] = 0;
559 wcscpy(SectionName2
, KeyData
);
562 OsIniSection
= IniCacheGetSection(IniCache
, SectionName2
);
563 if (OsIniSection
!= NULL
)
565 BOOLEAN UseExistingEntry
= TRUE
;
568 Status
= IniCacheGetKey(OsIniSection
, L
"BootType", &KeyData
);
569 if (NT_SUCCESS(Status
))
571 if ((KeyData
== NULL
) ||
572 ( (_wcsicmp(KeyData
, L
"ReactOS") != 0) &&
573 (_wcsicmp(KeyData
, L
"\"ReactOS\"") != 0) ))
575 /* This is not a ReactOS entry */
576 UseExistingEntry
= FALSE
;
581 UseExistingEntry
= FALSE
;
584 if (UseExistingEntry
)
586 /* BootType is ReactOS. Now check SystemPath */
587 Status
= IniCacheGetKey(OsIniSection
, L
"SystemPath", &KeyData
);
588 if (NT_SUCCESS(Status
))
590 swprintf(SystemPath
, L
"\"%S\"", ArcPath
);
591 if ((KeyData
== NULL
) ||
592 ((_wcsicmp(KeyData
, ArcPath
) != 0) &&
593 (_wcsicmp(KeyData
, SystemPath
) != 0) ))
595 /* This entry is a ReactOS entry, but the SystemRoot does not
596 match the one we are looking for */
597 UseExistingEntry
= FALSE
;
602 UseExistingEntry
= FALSE
;
606 if (UseExistingEntry
)
608 IniCacheDestroy(IniCache
);
609 return STATUS_SUCCESS
;
613 swprintf(SectionName
, L
"ReactOS_%lu", i
);
614 swprintf(OsName
, L
"\"ReactOS %lu\"", i
);
618 /* <SectionName>=<OsName> */
619 IniCacheInsertKey(IniSection
,
625 /* Create <SectionName> section */
626 IniSection
= IniCacheAppendSection(IniCache
, SectionName
);
628 /* BootType=ReactOS */
629 IniCacheInsertKey(IniSection
,
635 /* SystemPath=<ArcPath> */
636 IniCacheInsertKey(IniSection
,
642 IniCacheSave(IniCache
, IniPath
);
643 IniCacheDestroy(IniCache
);
645 return STATUS_SUCCESS
;
650 SaveCurrentBootSector(
654 OBJECT_ATTRIBUTES ObjectAttributes
;
655 IO_STATUS_BLOCK IoStatusBlock
;
661 /* Allocate buffer for bootsector */
662 BootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
663 if (BootSector
== NULL
)
664 return STATUS_INSUFFICIENT_RESOURCES
;
666 /* Read current boot sector into buffer */
667 RtlInitUnicodeString(&Name
, RootPath
);
669 InitializeObjectAttributes(&ObjectAttributes
,
671 OBJ_CASE_INSENSITIVE
,
675 Status
= NtOpenFile(&FileHandle
,
680 FILE_SYNCHRONOUS_IO_NONALERT
);
681 if (!NT_SUCCESS(Status
))
683 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
687 Status
= NtReadFile(FileHandle
,
697 if (!NT_SUCCESS(Status
))
699 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
703 /* Write bootsector to DstPath */
704 RtlInitUnicodeString(&Name
, DstPath
);
706 InitializeObjectAttributes(&ObjectAttributes
,
712 Status
= NtCreateFile(&FileHandle
,
717 FILE_ATTRIBUTE_NORMAL
,
720 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
,
723 if (!NT_SUCCESS(Status
))
725 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
729 Status
= NtWriteFile(FileHandle
,
740 /* Free the new boot sector */
741 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
748 InstallFat16BootCodeToFile(
753 OBJECT_ATTRIBUTES ObjectAttributes
;
754 IO_STATUS_BLOCK IoStatusBlock
;
758 PFAT_BOOTSECTOR OrigBootSector
;
759 PFAT_BOOTSECTOR NewBootSector
;
761 /* Allocate buffer for original bootsector */
762 OrigBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
763 if (OrigBootSector
== NULL
)
764 return STATUS_INSUFFICIENT_RESOURCES
;
766 /* Read current boot sector into buffer */
767 RtlInitUnicodeString(&Name
, RootPath
);
769 InitializeObjectAttributes(&ObjectAttributes
,
771 OBJ_CASE_INSENSITIVE
,
775 Status
= NtOpenFile(&FileHandle
,
780 FILE_SYNCHRONOUS_IO_NONALERT
);
781 if (!NT_SUCCESS(Status
))
783 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
787 Status
= NtReadFile(FileHandle
,
797 if (!NT_SUCCESS(Status
))
799 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
803 /* Allocate buffer for new bootsector */
804 NewBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
805 if (NewBootSector
== NULL
)
807 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
808 return STATUS_INSUFFICIENT_RESOURCES
;
811 /* Read new bootsector from SrcPath */
812 RtlInitUnicodeString(&Name
, SrcPath
);
814 InitializeObjectAttributes(&ObjectAttributes
,
816 OBJ_CASE_INSENSITIVE
,
820 Status
= NtOpenFile(&FileHandle
,
825 FILE_SYNCHRONOUS_IO_NONALERT
);
826 if (!NT_SUCCESS(Status
))
828 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
829 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
833 Status
= NtReadFile(FileHandle
,
843 if (!NT_SUCCESS(Status
))
845 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
846 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
850 /* Adjust bootsector (copy a part of the FAT BPB) */
851 memcpy(&NewBootSector
->OemName
,
852 &OrigBootSector
->OemName
,
853 FIELD_OFFSET(FAT_BOOTSECTOR
, BootCodeAndData
) -
854 FIELD_OFFSET(FAT_BOOTSECTOR
, OemName
));
856 /* Free the original boot sector */
857 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
859 /* Write new bootsector to DstPath */
860 RtlInitUnicodeString(&Name
, DstPath
);
862 InitializeObjectAttributes(&ObjectAttributes
,
868 Status
= NtCreateFile(&FileHandle
,
873 FILE_ATTRIBUTE_NORMAL
,
876 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
,
879 if (!NT_SUCCESS(Status
))
881 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
886 FilePosition
.QuadPart
= 0;
888 Status
= NtWriteFile(FileHandle
,
899 /* Free the new boot sector */
900 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
907 InstallFat32BootCodeToFile(
912 OBJECT_ATTRIBUTES ObjectAttributes
;
913 IO_STATUS_BLOCK IoStatusBlock
;
917 PFAT32_BOOTSECTOR OrigBootSector
;
918 PFAT32_BOOTSECTOR NewBootSector
;
919 LARGE_INTEGER FileOffset
;
921 /* Allocate buffer for original bootsector */
922 OrigBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
923 if (OrigBootSector
== NULL
)
924 return STATUS_INSUFFICIENT_RESOURCES
;
926 /* Read current boot sector into buffer */
927 RtlInitUnicodeString(&Name
, RootPath
);
929 InitializeObjectAttributes(&ObjectAttributes
,
931 OBJ_CASE_INSENSITIVE
,
935 Status
= NtOpenFile(&FileHandle
,
940 FILE_SYNCHRONOUS_IO_NONALERT
);
941 if (!NT_SUCCESS(Status
))
943 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
947 Status
= NtReadFile(FileHandle
,
957 if (!NT_SUCCESS(Status
))
959 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
963 /* Allocate buffer for new bootsector (2 sectors) */
964 NewBootSector
= RtlAllocateHeap(ProcessHeap
, 0, 2 * SECTORSIZE
);
965 if (NewBootSector
== NULL
)
967 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
968 return STATUS_INSUFFICIENT_RESOURCES
;
971 /* Read new bootsector from SrcPath */
972 RtlInitUnicodeString(&Name
, SrcPath
);
974 InitializeObjectAttributes(&ObjectAttributes
,
976 OBJ_CASE_INSENSITIVE
,
980 Status
= NtOpenFile(&FileHandle
,
985 FILE_SYNCHRONOUS_IO_NONALERT
);
986 if (!NT_SUCCESS(Status
))
988 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
989 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
993 Status
= NtReadFile(FileHandle
,
1002 NtClose(FileHandle
);
1003 if (!NT_SUCCESS(Status
))
1005 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1006 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1010 /* Adjust bootsector (copy a part of the FAT32 BPB) */
1011 memcpy(&NewBootSector
->OemName
,
1012 &OrigBootSector
->OemName
,
1013 FIELD_OFFSET(FAT32_BOOTSECTOR
, BootCodeAndData
) -
1014 FIELD_OFFSET(FAT32_BOOTSECTOR
, OemName
));
1016 /* Disable the backup boot sector */
1017 NewBootSector
->BackupBootSector
= 0;
1019 /* Free the original boot sector */
1020 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1022 /* Write the first sector of the new bootcode to DstPath */
1023 RtlInitUnicodeString(&Name
, DstPath
);
1025 InitializeObjectAttributes(&ObjectAttributes
,
1031 Status
= NtCreateFile(&FileHandle
,
1036 FILE_ATTRIBUTE_NORMAL
,
1039 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
,
1042 if (!NT_SUCCESS(Status
))
1044 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1048 Status
= NtWriteFile(FileHandle
,
1057 NtClose(FileHandle
);
1058 if (!NT_SUCCESS(Status
))
1060 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1064 /* Write the second sector of the new bootcode to boot disk sector 14 */
1065 RtlInitUnicodeString(&Name
, RootPath
);
1067 InitializeObjectAttributes(&ObjectAttributes
,
1073 Status
= NtOpenFile(&FileHandle
,
1078 FILE_SYNCHRONOUS_IO_NONALERT
);
1079 if (!NT_SUCCESS(Status
))
1081 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1085 FileOffset
.QuadPart
= (ULONGLONG
)(14 * SECTORSIZE
);
1086 Status
= NtWriteFile(FileHandle
,
1091 (NewBootSector
+ SECTORSIZE
),
1095 if (!NT_SUCCESS(Status
))
1098 NtClose(FileHandle
);
1100 /* Free the new boot sector */
1101 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1108 InstallMbrBootCodeToDisk(
1112 OBJECT_ATTRIBUTES ObjectAttributes
;
1113 IO_STATUS_BLOCK IoStatusBlock
;
1114 UNICODE_STRING Name
;
1117 PPARTITION_SECTOR OrigBootSector
;
1118 PPARTITION_SECTOR NewBootSector
;
1120 /* Allocate buffer for original bootsector */
1121 OrigBootSector
= (PPARTITION_SECTOR
)RtlAllocateHeap(ProcessHeap
,
1123 sizeof(PARTITION_SECTOR
));
1124 if (OrigBootSector
== NULL
)
1125 return STATUS_INSUFFICIENT_RESOURCES
;
1127 /* Read current boot sector into buffer */
1128 RtlInitUnicodeString(&Name
,
1131 InitializeObjectAttributes(&ObjectAttributes
,
1133 OBJ_CASE_INSENSITIVE
,
1137 Status
= NtOpenFile(&FileHandle
,
1142 FILE_SYNCHRONOUS_IO_NONALERT
);
1143 if (!NT_SUCCESS(Status
))
1145 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1149 Status
= NtReadFile(FileHandle
,
1158 NtClose(FileHandle
);
1159 if (!NT_SUCCESS(Status
))
1161 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1166 /* Allocate buffer for new bootsector */
1167 NewBootSector
= (PPARTITION_SECTOR
)RtlAllocateHeap(ProcessHeap
,
1169 sizeof(PARTITION_SECTOR
));
1170 if (NewBootSector
== NULL
)
1172 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1173 return STATUS_INSUFFICIENT_RESOURCES
;
1176 /* Read new bootsector from SrcPath */
1177 RtlInitUnicodeString(&Name
, SrcPath
);
1179 InitializeObjectAttributes(&ObjectAttributes
,
1181 OBJ_CASE_INSENSITIVE
,
1185 Status
= NtOpenFile(&FileHandle
,
1190 FILE_SYNCHRONOUS_IO_NONALERT
);
1191 if (!NT_SUCCESS(Status
))
1193 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1194 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1198 Status
= NtReadFile(FileHandle
,
1204 sizeof(PARTITION_SECTOR
),
1207 NtClose(FileHandle
);
1208 if (!NT_SUCCESS(Status
))
1210 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1211 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1215 /* Copy partition table from old MBR to new */
1216 RtlCopyMemory (&NewBootSector
->Signature
,
1217 &OrigBootSector
->Signature
,
1218 sizeof(PARTITION_SECTOR
) - offsetof(PARTITION_SECTOR
, Signature
) /* Length of partition table */);
1220 /* Free the original boot sector */
1221 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1223 /* Write new bootsector to RootPath */
1224 RtlInitUnicodeString(&Name
, RootPath
);
1226 InitializeObjectAttributes(&ObjectAttributes
,
1232 Status
= NtOpenFile(&FileHandle
,
1237 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1238 if (!NT_SUCCESS(Status
))
1240 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1241 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1245 Status
= NtWriteFile(FileHandle
,
1254 NtClose(FileHandle
);
1256 /* Free the new boot sector */
1257 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1264 InstallFat16BootCodeToDisk(
1268 OBJECT_ATTRIBUTES ObjectAttributes
;
1269 IO_STATUS_BLOCK IoStatusBlock
;
1270 UNICODE_STRING Name
;
1273 PFAT_BOOTSECTOR OrigBootSector
;
1274 PFAT_BOOTSECTOR NewBootSector
;
1275 PARTITION_INFORMATION
*PartInfo
;
1277 /* Allocate buffer for original bootsector */
1278 OrigBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
1279 if (OrigBootSector
== NULL
)
1280 return STATUS_INSUFFICIENT_RESOURCES
;
1282 /* Read current boot sector into buffer */
1283 RtlInitUnicodeString(&Name
, RootPath
);
1285 InitializeObjectAttributes(&ObjectAttributes
,
1287 OBJ_CASE_INSENSITIVE
,
1291 Status
= NtOpenFile(&FileHandle
,
1296 FILE_SYNCHRONOUS_IO_NONALERT
);
1297 if (!NT_SUCCESS(Status
))
1299 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1303 Status
= NtReadFile(FileHandle
,
1312 NtClose(FileHandle
);
1313 if (!NT_SUCCESS(Status
))
1315 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1320 /* Allocate buffer for new bootsector */
1321 NewBootSector
= RtlAllocateHeap(ProcessHeap
,
1324 if (NewBootSector
== NULL
)
1326 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1327 return STATUS_INSUFFICIENT_RESOURCES
;
1330 /* Read new bootsector from SrcPath */
1331 RtlInitUnicodeString(&Name
, SrcPath
);
1333 InitializeObjectAttributes(&ObjectAttributes
,
1335 OBJ_CASE_INSENSITIVE
,
1339 Status
= NtOpenFile(&FileHandle
,
1344 FILE_SYNCHRONOUS_IO_NONALERT
);
1345 if (!NT_SUCCESS(Status
))
1347 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1348 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1352 Status
= NtReadFile(FileHandle
,
1361 NtClose(FileHandle
);
1362 if (!NT_SUCCESS(Status
))
1364 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1365 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1369 /* Adjust bootsector (copy a part of the FAT16 BPB) */
1370 memcpy(&NewBootSector
->OemName
,
1371 &OrigBootSector
->OemName
,
1372 FIELD_OFFSET(FAT_BOOTSECTOR
, BootCodeAndData
) -
1373 FIELD_OFFSET(FAT_BOOTSECTOR
, OemName
));
1375 PartInfo
= &PartitionList
->CurrentPartition
->PartInfo
[PartitionList
->CurrentPartitionNumber
];
1376 NewBootSector
->HiddenSectors
= PartInfo
->HiddenSectors
;
1378 /* Free the original boot sector */
1379 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1381 /* Write new bootsector to RootPath */
1382 RtlInitUnicodeString(&Name
, RootPath
);
1384 InitializeObjectAttributes(&ObjectAttributes
,
1390 Status
= NtOpenFile(&FileHandle
,
1395 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1396 if (!NT_SUCCESS(Status
))
1398 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1399 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1404 FilePosition
.QuadPart
= 0;
1406 Status
= NtWriteFile(FileHandle
,
1415 NtClose(FileHandle
);
1417 /* Free the new boot sector */
1418 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1425 InstallFat32BootCodeToDisk(
1429 OBJECT_ATTRIBUTES ObjectAttributes
;
1430 IO_STATUS_BLOCK IoStatusBlock
;
1431 UNICODE_STRING Name
;
1434 PFAT32_BOOTSECTOR OrigBootSector
;
1435 PFAT32_BOOTSECTOR NewBootSector
;
1436 LARGE_INTEGER FileOffset
;
1437 USHORT BackupBootSector
;
1438 PARTITION_INFORMATION
*PartInfo
;
1440 /* Allocate buffer for original bootsector */
1441 OrigBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
1442 if (OrigBootSector
== NULL
)
1443 return STATUS_INSUFFICIENT_RESOURCES
;
1445 /* Read current boot sector into buffer */
1446 RtlInitUnicodeString(&Name
, RootPath
);
1448 InitializeObjectAttributes(&ObjectAttributes
,
1450 OBJ_CASE_INSENSITIVE
,
1454 Status
= NtOpenFile(&FileHandle
,
1459 FILE_SYNCHRONOUS_IO_NONALERT
);
1460 if (!NT_SUCCESS(Status
))
1462 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1466 Status
= NtReadFile(FileHandle
,
1475 NtClose(FileHandle
);
1476 if (!NT_SUCCESS(Status
))
1478 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1483 /* Allocate buffer for new bootsector (2 sectors) */
1484 NewBootSector
= RtlAllocateHeap(ProcessHeap
, 0, 2 * SECTORSIZE
);
1485 if (NewBootSector
== NULL
)
1487 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1488 return STATUS_INSUFFICIENT_RESOURCES
;
1491 /* Read new bootsector from SrcPath */
1492 RtlInitUnicodeString(&Name
, SrcPath
);
1494 InitializeObjectAttributes(&ObjectAttributes
,
1496 OBJ_CASE_INSENSITIVE
,
1500 Status
= NtOpenFile(&FileHandle
,
1505 FILE_SYNCHRONOUS_IO_NONALERT
);
1506 if (!NT_SUCCESS(Status
))
1508 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1509 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1513 Status
= NtReadFile(FileHandle
,
1522 NtClose(FileHandle
);
1523 if (!NT_SUCCESS(Status
))
1525 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1526 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1530 /* Adjust bootsector (copy a part of the FAT32 BPB) */
1531 memcpy(&NewBootSector
->OemName
,
1532 &OrigBootSector
->OemName
,
1533 FIELD_OFFSET(FAT32_BOOTSECTOR
, BootCodeAndData
) -
1534 FIELD_OFFSET(FAT32_BOOTSECTOR
, OemName
));
1536 PartInfo
= &PartitionList
->CurrentPartition
->PartInfo
[PartitionList
->CurrentPartitionNumber
];
1537 NewBootSector
->HiddenSectors
= PartInfo
->HiddenSectors
;
1539 /* Get the location of the backup boot sector */
1540 BackupBootSector
= OrigBootSector
->BackupBootSector
;
1542 /* Free the original boot sector */
1543 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1545 /* Write the first sector of the new bootcode to DstPath */
1546 RtlInitUnicodeString(&Name
, RootPath
);
1548 InitializeObjectAttributes(&ObjectAttributes
,
1554 Status
= NtOpenFile(&FileHandle
,
1559 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1560 if (!NT_SUCCESS(Status
))
1562 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1563 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1567 /* Write sector 0 */
1568 FileOffset
.QuadPart
= 0ULL;
1569 Status
= NtWriteFile(FileHandle
,
1578 if (!NT_SUCCESS(Status
))
1580 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1581 NtClose(FileHandle
);
1582 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1586 /* Write backup boot sector */
1587 if ((BackupBootSector
!= 0x0000) && (BackupBootSector
!= 0xFFFF))
1589 FileOffset
.QuadPart
= (ULONGLONG
)((ULONG
)BackupBootSector
* SECTORSIZE
);
1590 Status
= NtWriteFile(FileHandle
,
1599 if (!NT_SUCCESS(Status
))
1601 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1602 NtClose(FileHandle
);
1603 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1608 /* Write sector 14 */
1609 FileOffset
.QuadPart
= 14 * SECTORSIZE
;
1610 Status
= NtWriteFile(FileHandle
,
1615 ((PUCHAR
)NewBootSector
+ SECTORSIZE
),
1619 if (!NT_SUCCESS(Status
))
1621 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1623 NtClose(FileHandle
);
1625 /* Free the new boot sector */
1626 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1638 UNICODE_STRING Name
;
1639 OBJECT_ATTRIBUTES ObjectAttributes
;
1640 IO_STATUS_BLOCK IoStatusBlock
;
1641 FILE_BASIC_INFORMATION FileInfo
;
1645 RtlInitUnicodeString(&Name
, FileName
);
1647 InitializeObjectAttributes(&ObjectAttributes
,
1649 OBJ_CASE_INSENSITIVE
,
1653 Status
= NtOpenFile(&FileHandle
,
1654 GENERIC_READ
|GENERIC_WRITE
,
1658 FILE_SYNCHRONOUS_IO_NONALERT
);
1659 if (Status
== STATUS_NO_SUCH_FILE
)
1661 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1663 return STATUS_SUCCESS
;
1665 if (!NT_SUCCESS(Status
))
1667 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1671 Status
= NtQueryInformationFile(FileHandle
,
1674 sizeof(FILE_BASIC_INFORMATION
),
1675 FileBasicInformation
);
1676 if (!NT_SUCCESS(Status
))
1678 DPRINT1("NtQueryInformationFile() failed (Status %lx)\n", Status
);
1679 NtClose(FileHandle
);
1683 *Attributes
= FileInfo
.FileAttributes
;
1685 /* Delete attributes SYSTEM, HIDDEN and READONLY */
1686 FileInfo
.FileAttributes
= FileInfo
.FileAttributes
&
1687 ~(FILE_ATTRIBUTE_SYSTEM
|
1688 FILE_ATTRIBUTE_HIDDEN
|
1689 FILE_ATTRIBUTE_READONLY
);
1691 Status
= NtSetInformationFile(FileHandle
,
1694 sizeof(FILE_BASIC_INFORMATION
),
1695 FileBasicInformation
);
1696 if (!NT_SUCCESS(Status
))
1698 DPRINT1("NtSetInformationFile() failed (Status %lx)\n", Status
);
1701 NtClose(FileHandle
);
1712 UNICODE_STRING Name
;
1713 OBJECT_ATTRIBUTES ObjectAttributes
;
1714 IO_STATUS_BLOCK IoStatusBlock
;
1715 FILE_BASIC_INFORMATION FileInfo
;
1719 RtlInitUnicodeString(&Name
, FileName
);
1721 InitializeObjectAttributes(&ObjectAttributes
,
1723 OBJ_CASE_INSENSITIVE
,
1727 Status
= NtOpenFile(&FileHandle
,
1728 GENERIC_READ
|GENERIC_WRITE
,
1732 FILE_SYNCHRONOUS_IO_NONALERT
);
1733 if (!NT_SUCCESS(Status
))
1735 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1739 Status
= NtQueryInformationFile(FileHandle
,
1742 sizeof(FILE_BASIC_INFORMATION
),
1743 FileBasicInformation
);
1744 if (!NT_SUCCESS(Status
))
1746 DPRINT1("NtQueryInformationFile() failed (Status %lx)\n", Status
);
1747 NtClose(FileHandle
);
1751 FileInfo
.FileAttributes
= FileInfo
.FileAttributes
| Attributes
;
1753 Status
= NtSetInformationFile(FileHandle
,
1756 sizeof(FILE_BASIC_INFORMATION
),
1757 FileBasicInformation
);
1758 if (!NT_SUCCESS(Status
))
1760 DPRINT1("NtSetInformationFile() failed (Status %lx)\n", Status
);
1763 NtClose(FileHandle
);
1774 UNICODE_STRING Name
;
1775 PINICACHE Cache
= NULL
;
1776 PINICACHESECTION Section
= NULL
;
1778 ULONG FileAttribute
;
1779 PWCHAR OldValue
= NULL
;
1781 RtlInitUnicodeString(&Name
, BootIniPath
);
1783 Status
= IniCacheLoad(&Cache
, &Name
, FALSE
);
1784 if (!NT_SUCCESS(Status
))
1789 Section
= IniCacheGetSection(Cache
,
1790 L
"operating systems");
1791 if (Section
== NULL
)
1793 IniCacheDestroy(Cache
);
1794 return STATUS_UNSUCCESSFUL
;
1797 /* Check - maybe record already exists */
1798 Status
= IniCacheGetKey(Section
, EntryName
, &OldValue
);
1800 /* If either key was not found, or contains something else - add new one */
1801 if (!NT_SUCCESS(Status
) || wcscmp(OldValue
, EntryValue
))
1803 IniCacheInsertKey(Section
,
1810 Status
= UnprotectBootIni(BootIniPath
,
1812 if (!NT_SUCCESS(Status
))
1814 IniCacheDestroy(Cache
);
1818 Status
= IniCacheSave(Cache
, BootIniPath
);
1819 if (!NT_SUCCESS(Status
))
1821 IniCacheDestroy(Cache
);
1825 FileAttribute
|= (FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
| FILE_ATTRIBUTE_READONLY
);
1826 Status
= ProtectBootIni(BootIniPath
, FileAttribute
);
1828 IniCacheDestroy(Cache
);
1834 CheckInstallFatBootcodeToPartition(
1835 PUNICODE_STRING SystemRootPath
)
1838 if (DoesFileExist(SystemRootPath
->Buffer
, L
"ntldr") ||
1839 DoesFileExist(SystemRootPath
->Buffer
, L
"boot.ini"))
1843 else if (DoesFileExist(SystemRootPath
->Buffer
, L
"io.sys") ||
1844 DoesFileExist(SystemRootPath
->Buffer
, L
"msdos.sys"))
1855 InstallFatBootcodeToPartition(
1856 PUNICODE_STRING SystemRootPath
,
1857 PUNICODE_STRING SourceRootPath
,
1858 PUNICODE_STRING DestinationArcPath
,
1859 UCHAR PartitionType
)
1862 WCHAR SrcPath
[MAX_PATH
];
1863 WCHAR DstPath
[MAX_PATH
];
1866 /* FAT or FAT32 partition */
1867 DPRINT("System path: '%wZ'\n", SystemRootPath
);
1869 if (DoesFileExist(SystemRootPath
->Buffer
, L
"ntldr") == TRUE
||
1870 DoesFileExist(SystemRootPath
->Buffer
, L
"boot.ini") == TRUE
)
1872 /* Search root directory for 'ntldr' and 'boot.ini'. */
1873 DPRINT("Found Microsoft Windows NT/2000/XP boot loader\n");
1875 /* Copy FreeLoader to the boot partition */
1876 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
1877 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
1878 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1879 wcscat(DstPath
, L
"\\freeldr.sys");
1881 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
1882 Status
= SetupCopyFile(SrcPath
, DstPath
);
1883 if (!NT_SUCCESS(Status
))
1885 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
1889 /* Create or update freeldr.ini */
1890 if (DoesFileExist(SystemRootPath
->Buffer
, L
"freeldr.ini") == FALSE
)
1892 /* Create new 'freeldr.ini' */
1893 DPRINT1("Create new 'freeldr.ini'\n");
1894 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1895 wcscat(DstPath
, L
"\\freeldr.ini");
1897 Status
= CreateFreeLoaderIniForReactos(DstPath
,
1898 DestinationArcPath
->Buffer
);
1899 if (!NT_SUCCESS(Status
))
1901 DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status
);
1905 /* Install new bootcode */
1906 if (PartitionType
== PARTITION_FAT32
||
1907 PartitionType
== PARTITION_FAT32_XINT13
)
1909 /* Install FAT32 bootcode */
1910 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
1911 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
1912 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1913 wcscat(DstPath
, L
"\\bootsect.ros");
1915 DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, DstPath
);
1916 Status
= InstallFat32BootCodeToFile(SrcPath
,
1918 SystemRootPath
->Buffer
);
1919 if (!NT_SUCCESS(Status
))
1921 DPRINT1("InstallFat32BootCodeToFile() failed (Status %lx)\n", Status
);
1927 /* Install FAT16 bootcode */
1928 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
1929 wcscat(SrcPath
, L
"\\loader\\fat.bin");
1930 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1931 wcscat(DstPath
, L
"\\bootsect.ros");
1933 DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath
, DstPath
);
1934 Status
= InstallFat16BootCodeToFile(SrcPath
,
1936 SystemRootPath
->Buffer
);
1937 if (!NT_SUCCESS(Status
))
1939 DPRINT1("InstallFat16BootCodeToFile() failed (Status %lx)\n", Status
);
1946 /* Update existing 'freeldr.ini' */
1947 DPRINT1("Update existing 'freeldr.ini'\n");
1948 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1949 wcscat(DstPath
, L
"\\freeldr.ini");
1951 Status
= UpdateFreeLoaderIni(DstPath
,
1952 DestinationArcPath
->Buffer
);
1953 if (!NT_SUCCESS(Status
))
1955 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
1960 /* Update 'boot.ini' */
1961 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1962 wcscat(DstPath
, L
"\\boot.ini");
1964 DPRINT1("Update 'boot.ini': %S\n", DstPath
);
1965 Status
= UpdateBootIni(DstPath
,
1966 L
"C:\\bootsect.ros",
1968 if (!NT_SUCCESS(Status
))
1970 DPRINT1("UpdateBootIni() failed (Status %lx)\n", Status
);
1974 else if (DoesFileExist(SystemRootPath
->Buffer
, L
"io.sys") == TRUE
||
1975 DoesFileExist(SystemRootPath
->Buffer
, L
"msdos.sys") == TRUE
)
1977 /* Search for root directory for 'io.sys' and 'msdos.sys'. */
1978 DPRINT1("Found Microsoft DOS or Windows 9x boot loader\n");
1980 /* Copy FreeLoader to the boot partition */
1981 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
1982 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
1983 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1984 wcscat(DstPath
, L
"\\freeldr.sys");
1986 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
1987 Status
= SetupCopyFile(SrcPath
, DstPath
);
1988 if (!NT_SUCCESS(Status
))
1990 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
1994 /* Create or update 'freeldr.ini' */
1995 if (DoesFileExist(SystemRootPath
->Buffer
, L
"freeldr.ini") == FALSE
)
1997 /* Create new 'freeldr.ini' */
1998 DPRINT1("Create new 'freeldr.ini'\n");
1999 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2000 wcscat(DstPath
, L
"\\freeldr.ini");
2002 Status
= CreateFreeLoaderIniForDos(DstPath
,
2003 DestinationArcPath
->Buffer
);
2004 if (!NT_SUCCESS(Status
))
2006 DPRINT1("CreateFreeLoaderIniForDos() failed (Status %lx)\n", Status
);
2010 /* Save current bootsector as 'BOOTSECT.DOS' */
2011 wcscpy(SrcPath
, SystemRootPath
->Buffer
);
2012 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2013 wcscat(DstPath
, L
"\\bootsect.dos");
2015 DPRINT1("Save bootsector: %S ==> %S\n", SrcPath
, DstPath
);
2016 Status
= SaveCurrentBootSector(SrcPath
,
2018 if (!NT_SUCCESS(Status
))
2020 DPRINT1("SaveCurrentBootSector() failed (Status %lx)\n", Status
);
2024 /* Install new bootsector */
2025 if (PartitionType
== PARTITION_FAT32
||
2026 PartitionType
== PARTITION_FAT32_XINT13
)
2028 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2029 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
2031 DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2032 Status
= InstallFat32BootCodeToDisk(SrcPath
,
2033 SystemRootPath
->Buffer
);
2034 if (!NT_SUCCESS(Status
))
2036 DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)\n", Status
);
2042 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2043 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2045 DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2046 Status
= InstallFat16BootCodeToDisk(SrcPath
,
2047 SystemRootPath
->Buffer
);
2048 if (!NT_SUCCESS(Status
))
2050 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status
);
2057 /* Update existing 'freeldr.ini' */
2058 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2059 wcscat(DstPath
, L
"\\freeldr.ini");
2061 Status
= UpdateFreeLoaderIni(DstPath
, DestinationArcPath
->Buffer
);
2062 if (!NT_SUCCESS(Status
))
2064 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
2071 /* No or unknown boot loader */
2072 DPRINT1("No or unknown boot loader found\n");
2074 /* Copy FreeLoader to the boot partition */
2075 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2076 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
2077 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2078 wcscat(DstPath
, L
"\\freeldr.sys");
2080 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2081 Status
= SetupCopyFile(SrcPath
, DstPath
);
2082 if (!NT_SUCCESS(Status
))
2084 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
2088 /* Create or update 'freeldr.ini' */
2089 if (DoesFileExist(SystemRootPath
->Buffer
, L
"freeldr.ini") == FALSE
)
2091 /* Create new freeldr.ini */
2092 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2093 wcscat(DstPath
, L
"\\freeldr.ini");
2095 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2096 Status
= CreateFreeLoaderIniForReactos(DstPath
,
2097 DestinationArcPath
->Buffer
);
2098 if (!NT_SUCCESS(Status
))
2100 DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status
);
2104 /* Save current bootsector as 'BOOTSECT.OLD' */
2105 wcscpy(SrcPath
, SystemRootPath
->Buffer
);
2106 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2107 wcscat(DstPath
, L
"\\bootsect.old");
2109 DPRINT("Save bootsector: %S ==> %S\n", SrcPath
, DstPath
);
2110 Status
= SaveCurrentBootSector(SrcPath
,
2112 if (!NT_SUCCESS(Status
))
2114 DPRINT1("SaveCurrentBootSector() failed (Status %lx)\n", Status
);
2118 /* Install new bootsector */
2119 if ((PartitionType
== PARTITION_FAT32
) ||
2120 (PartitionType
== PARTITION_FAT32_XINT13
))
2122 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2123 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
2125 DPRINT("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2126 Status
= InstallFat32BootCodeToDisk(SrcPath
,
2127 SystemRootPath
->Buffer
);
2128 if (!NT_SUCCESS(Status
))
2130 DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)\n", Status
);
2136 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2137 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2139 DPRINT("Install FAT bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2140 Status
= InstallFat16BootCodeToDisk(SrcPath
,
2141 SystemRootPath
->Buffer
);
2142 if (!NT_SUCCESS(Status
))
2144 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status
);
2151 /* Update existing 'freeldr.ini' */
2152 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2153 wcscat(DstPath
, L
"\\freeldr.ini");
2155 Status
= UpdateFreeLoaderIni(DstPath
,
2156 DestinationArcPath
->Buffer
);
2157 if (!NT_SUCCESS(Status
))
2159 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
2165 return STATUS_SUCCESS
;
2167 return STATUS_NOT_IMPLEMENTED
;
2172 InstallVBRToPartition(
2173 PUNICODE_STRING SystemRootPath
,
2174 PUNICODE_STRING SourceRootPath
,
2175 PUNICODE_STRING DestinationArcPath
,
2176 UCHAR PartitionType
)
2178 if ((PartitionType
== PARTITION_FAT_12
) ||
2179 (PartitionType
== PARTITION_FAT_16
) ||
2180 (PartitionType
== PARTITION_HUGE
) ||
2181 (PartitionType
== PARTITION_XINT13
) ||
2182 (PartitionType
== PARTITION_FAT32
) ||
2183 (PartitionType
== PARTITION_FAT32_XINT13
))
2185 return InstallFatBootcodeToPartition(SystemRootPath
,
2191 return STATUS_UNSUCCESSFUL
;
2196 InstallFatBootcodeToFloppy(
2197 PUNICODE_STRING SourceRootPath
,
2198 PUNICODE_STRING DestinationArcPath
)
2201 WCHAR SrcPath
[MAX_PATH
];
2202 WCHAR DstPath
[MAX_PATH
];
2205 /* Copy FreeLoader to the boot partition */
2206 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2207 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
2209 wcscpy(DstPath
, L
"\\Device\\Floppy0\\freeldr.sys");
2211 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2212 Status
= SetupCopyFile(SrcPath
, DstPath
);
2213 if (!NT_SUCCESS(Status
))
2215 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
2219 /* Create new 'freeldr.ini' */
2220 wcscpy(DstPath
, L
"\\Device\\Floppy0\\freeldr.ini");
2222 DPRINT("Create new 'freeldr.ini'\n");
2223 Status
= CreateFreeLoaderIniForReactos(DstPath
, DestinationArcPath
->Buffer
);
2224 if (!NT_SUCCESS(Status
))
2226 DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status
);
2230 /* Install FAT12/16 boosector */
2231 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2232 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2234 wcscpy(DstPath
, L
"\\Device\\Floppy0");
2236 DPRINT("Install FAT bootcode: %S ==> %S\n", SrcPath
, DstPath
);
2237 Status
= InstallFat16BootCodeToDisk(SrcPath
, DstPath
);
2238 if (!NT_SUCCESS(Status
))
2240 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status
);
2244 return STATUS_SUCCESS
;
2246 return STATUS_NOT_IMPLEMENTED
;