3 * Copyright (C) 2002 ReactOS Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 * COPYRIGHT: See COPYING in the top level directory
21 * PROJECT: ReactOS text-mode setup
22 * FILE: subsys/system/usetup/bootsup.c
23 * PURPOSE: Bootloader support functions
24 * PROGRAMMER: Eric Kohl
32 #define SECTORSIZE 512
35 typedef struct _FAT_BOOTSECTOR
37 UCHAR JumpBoot
[3]; // Jump instruction to boot code
38 CHAR OemName
[8]; // "MSWIN4.1" for MS formatted volumes
39 USHORT BytesPerSector
; // Bytes per sector
40 UCHAR SectorsPerCluster
; // Number of sectors in a cluster
41 USHORT ReservedSectors
; // Reserved sectors, usually 1 (the bootsector)
42 UCHAR NumberOfFats
; // Number of FAT tables
43 USHORT RootDirEntries
; // Number of root directory entries (fat12/16)
44 USHORT TotalSectors
; // Number of total sectors on the drive, 16-bit
45 UCHAR MediaDescriptor
; // Media descriptor byte
46 USHORT SectorsPerFat
; // Sectors per FAT table (fat12/16)
47 USHORT SectorsPerTrack
; // Number of sectors in a track
48 USHORT NumberOfHeads
; // Number of heads on the disk
49 ULONG HiddenSectors
; // Hidden sectors (sectors before the partition start like the partition table)
50 ULONG TotalSectorsBig
; // This field is the new 32-bit total count of sectors on the volume
51 UCHAR DriveNumber
; // Int 0x13 drive number (e.g. 0x80)
52 UCHAR Reserved1
; // Reserved (used by Windows NT). Code that formats FAT volumes should always set this byte to 0.
53 UCHAR BootSignature
; // Extended boot signature (0x29). This is a signature byte that indicates that the following three fields in the boot sector are present.
54 ULONG VolumeSerialNumber
; // Volume serial number
55 CHAR VolumeLabel
[11]; // Volume label. This field matches the 11-byte volume label recorded in the root directory
56 CHAR FileSystemType
[8]; // One of the strings "FAT12 ", "FAT16 ", or "FAT "
58 UCHAR BootCodeAndData
[448]; // The remainder of the boot sector
60 USHORT BootSectorMagic
; // 0xAA55
62 } FAT_BOOTSECTOR
, *PFAT_BOOTSECTOR
;
64 typedef struct _FAT32_BOOTSECTOR
66 UCHAR JumpBoot
[3]; // Jump instruction to boot code
67 CHAR OemName
[8]; // "MSWIN4.1" for MS formatted volumes
68 USHORT BytesPerSector
; // Bytes per sector
69 UCHAR SectorsPerCluster
; // Number of sectors in a cluster
70 USHORT ReservedSectors
; // Reserved sectors, usually 1 (the bootsector)
71 UCHAR NumberOfFats
; // Number of FAT tables
72 USHORT RootDirEntries
; // Number of root directory entries (fat12/16)
73 USHORT TotalSectors
; // Number of total sectors on the drive, 16-bit
74 UCHAR MediaDescriptor
; // Media descriptor byte
75 USHORT SectorsPerFat
; // Sectors per FAT table (fat12/16)
76 USHORT SectorsPerTrack
; // Number of sectors in a track
77 USHORT NumberOfHeads
; // Number of heads on the disk
78 ULONG HiddenSectors
; // Hidden sectors (sectors before the partition start like the partition table)
79 ULONG TotalSectorsBig
; // This field is the new 32-bit total count of sectors on the volume
80 ULONG SectorsPerFatBig
; // This field is the FAT32 32-bit count of sectors occupied by ONE FAT. BPB_FATSz16 must be 0
81 USHORT ExtendedFlags
; // Extended flags (fat32)
82 USHORT FileSystemVersion
; // File system version (fat32)
83 ULONG RootDirStartCluster
; // Starting cluster of the root directory (fat32)
84 USHORT FsInfo
; // Sector number of FSINFO structure in the reserved area of the FAT32 volume. Usually 1.
85 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.
86 UCHAR Reserved
[12]; // Reserved for future expansion
87 UCHAR DriveNumber
; // Int 0x13 drive number (e.g. 0x80)
88 UCHAR Reserved1
; // Reserved (used by Windows NT). Code that formats FAT volumes should always set this byte to 0.
89 UCHAR BootSignature
; // Extended boot signature (0x29). This is a signature byte that indicates that the following three fields in the boot sector are present.
90 ULONG VolumeSerialNumber
; // Volume serial number
91 CHAR VolumeLabel
[11]; // Volume label. This field matches the 11-byte volume label recorded in the root directory
92 CHAR FileSystemType
[8]; // Always set to the string "FAT32 "
94 UCHAR BootCodeAndData
[420]; // The remainder of the boot sector
96 USHORT BootSectorMagic
; // 0xAA55
98 } FAT32_BOOTSECTOR
, *PFAT32_BOOTSECTOR
;
101 extern PPARTLIST PartitionList
;
103 /* FUNCTIONS ****************************************************************/
107 CreateCommonFreeLoaderSections(PINICACHE IniCache
)
109 PINICACHESECTION IniSection
;
111 /* Create "FREELOADER" section */
112 IniSection
= IniCacheAppendSection(IniCache
,
116 if (IsUnattendedSetup
)
118 /* DefaultOS=ReactOS */
119 IniCacheInsertKey(IniSection
,
123 L
"ReactOS_KdSerial");
128 /* DefaultOS=ReactOS */
129 IniCacheInsertKey(IniSection
,
137 if (IsUnattendedSetup
)
140 /* Timeout=0 for unattended or non debug*/
141 IniCacheInsertKey(IniSection
,
150 /* Timeout=0 or 10 */
151 IniCacheInsertKey(IniSection
,
159 /* Create "Display" section */
160 IniSection
= IniCacheAppendSection(IniCache
,
163 /* TitleText=ReactOS Boot Manager */
164 IniCacheInsertKey(IniSection
,
168 L
"ReactOS Boot Manager");
170 /* StatusBarColor=Cyan */
171 IniCacheInsertKey(IniSection
,
177 /* StatusBarTextColor=Black */
178 IniCacheInsertKey(IniSection
,
181 L
"StatusBarTextColor",
184 /* BackdropTextColor=White */
185 IniCacheInsertKey(IniSection
,
188 L
"BackdropTextColor",
191 /* BackdropColor=Blue */
192 IniCacheInsertKey(IniSection
,
198 /* BackdropFillStyle=Medium */
199 IniCacheInsertKey(IniSection
,
202 L
"BackdropFillStyle",
205 /* TitleBoxTextColor=White */
206 IniCacheInsertKey(IniSection
,
209 L
"TitleBoxTextColor",
212 /* TitleBoxColor=Red */
213 IniCacheInsertKey(IniSection
,
219 /* MessageBoxTextColor=White */
220 IniCacheInsertKey(IniSection
,
223 L
"MessageBoxTextColor",
226 /* MessageBoxColor=Blue */
227 IniCacheInsertKey(IniSection
,
233 /* MenuTextColor=White */
234 IniCacheInsertKey(IniSection
,
241 IniCacheInsertKey(IniSection
,
247 /* TextColor=Yellow */
248 IniCacheInsertKey(IniSection
,
254 /* SelectedTextColor=Black */
255 IniCacheInsertKey(IniSection
,
258 L
"SelectedTextColor",
261 /* SelectedColor=Gray */
262 IniCacheInsertKey(IniSection
,
268 /* SelectedColor=Gray */
269 IniCacheInsertKey(IniSection
,
275 /* SelectedColor=Gray */
276 IniCacheInsertKey(IniSection
,
282 /* SelectedColor=Gray */
283 IniCacheInsertKey(IniSection
,
289 /* SelectedColor=Gray */
290 IniCacheInsertKey(IniSection
,
296 /* SelectedColor=Gray */
297 IniCacheInsertKey(IniSection
,
301 L
"Seconds until highlighted choice will be started automatically: ");
306 CreateFreeLoaderIniForDos(PWCHAR IniPath
,
310 PINICACHESECTION IniSection
;
312 IniCache
= IniCacheCreate();
314 CreateCommonFreeLoaderSections(IniCache
);
316 /* Create "Operating Systems" section */
317 IniSection
= IniCacheAppendSection(IniCache
,
318 L
"Operating Systems");
320 /* REACTOS=ReactOS */
321 IniCacheInsertKey(IniSection
,
327 /* ReactOS_Debug="ReactOS (Debug)" */
328 IniCacheInsertKey(IniSection
,
332 L
"\"ReactOS (Debug)\"");
334 /* DOS=Dos/Windows */
335 IniCacheInsertKey(IniSection
,
341 /* Create "ReactOS" section */
342 IniSection
= IniCacheAppendSection(IniCache
,
345 /* BootType=ReactOS */
346 IniCacheInsertKey(IniSection
,
352 /* SystemPath=<ArcPath> */
353 IniCacheInsertKey(IniSection
,
359 /* Create "ReactOS_Debug" section */
360 IniSection
= IniCacheAppendSection(IniCache
,
363 /* BootType=ReactOS */
364 IniCacheInsertKey(IniSection
,
370 /* SystemPath=<ArcPath> */
371 IniCacheInsertKey(IniSection
,
377 /* Options=/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS */
378 IniCacheInsertKey(IniSection
,
382 L
"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS");
384 /* Create "DOS" section */
385 IniSection
= IniCacheAppendSection(IniCache
,
388 /* BootType=BootSector */
389 IniCacheInsertKey(IniSection
,
396 IniCacheInsertKey(IniSection
,
402 /* BootPartition=1 */
403 IniCacheInsertKey(IniSection
,
409 /* BootSector=BOOTSECT.DOS */
410 IniCacheInsertKey(IniSection
,
416 IniCacheSave(IniCache
, IniPath
);
417 IniCacheDestroy(IniCache
);
419 return(STATUS_SUCCESS
);
424 CreateFreeLoaderEntry(
426 PINICACHESECTION OSSection
,
433 PINICACHESECTION IniSection
;
435 /* Insert entry into "Operating Systems" section */
436 IniCacheInsertKey(OSSection
,
442 /* Create new section */
443 IniSection
= IniCacheAppendSection(IniCache
, Section
);
446 IniCacheInsertKey(IniSection
,
453 IniCacheInsertKey(IniSection
,
460 IniCacheInsertKey(IniSection
,
466 return STATUS_SUCCESS
;
470 CreateFreeLoaderIniForReactos(PWCHAR IniPath
,
474 PINICACHESECTION IniSection
;
476 IniCache
= IniCacheCreate();
478 CreateCommonFreeLoaderSections(IniCache
);
480 /* Create "Operating Systems" section */
481 IniSection
= IniCacheAppendSection(IniCache
,
482 L
"Operating Systems");
485 CreateFreeLoaderEntry(IniCache
, IniSection
,
486 L
"ReactOS", L
"\"ReactOS\"",
487 L
"Windows2003", ArcPath
,
491 CreateFreeLoaderEntry(IniCache
, IniSection
,
492 L
"ReactOS_Debug", L
"\"ReactOS (Debug)\"",
493 L
"Windows2003", ArcPath
,
494 L
"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS");
498 /* ReactOS_KdSerial */
499 CreateFreeLoaderEntry(IniCache
, IniSection
,
500 L
"ReactOS_KdSerial", L
"\"ReactOS (RosDbg)\"",
501 L
"Windows2003", ArcPath
,
502 L
"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /KDSERIAL");
505 /* ReactOS_LogFile */
506 CreateFreeLoaderEntry(IniCache
, IniSection
,
507 L
"ReactOS_LogFile", L
"\"ReactOS (Log file)\"",
508 L
"Windows2003", ArcPath
,
509 L
"/DEBUG /DEBUGPORT=FILE /SOS");
512 CreateFreeLoaderEntry(IniCache
, IniSection
,
513 L
"ReactOS_Ram", L
"\"ReactOS (RAM Disk)\"",
514 L
"ReactOS", L
"ramdisk(0)\\ReactOS",
515 L
"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /RDIMAGEPATH=reactos.img /RDIMAGEOFFSET=32256");
518 /* Save the ini file */
519 IniCacheSave(IniCache
, IniPath
);
520 IniCacheDestroy(IniCache
);
522 return(STATUS_SUCCESS
);
527 UpdateFreeLoaderIni(PWCHAR IniPath
,
532 PINICACHESECTION IniSection
;
533 PINICACHESECTION OsIniSection
;
534 WCHAR SectionName
[80];
536 WCHAR SystemPath
[200];
537 WCHAR SectionName2
[200];
542 RtlInitUnicodeString(&Name
,
545 Status
= IniCacheLoad(&IniCache
,
548 if (!NT_SUCCESS(Status
))
551 /* Get "Operating Systems" section */
552 IniSection
= IniCacheGetSection(IniCache
,
553 L
"Operating Systems");
554 if (IniSection
== NULL
)
556 IniCacheDestroy(IniCache
);
557 return(STATUS_UNSUCCESSFUL
);
560 /* Find an existing usable or an unused section name */
562 wcscpy(SectionName
, L
"ReactOS");
563 wcscpy(OsName
, L
"\"ReactOS\"");
566 Status
= IniCacheGetKey(IniSection
,
569 if (!NT_SUCCESS(Status
))
572 /* Get operation system section */
573 if (KeyData
[0] == '"')
575 wcscpy(SectionName2
, &KeyData
[1]);
576 j
= wcslen(SectionName2
);
579 SectionName2
[j
-1] = 0;
584 wcscpy(SectionName2
, KeyData
);
587 OsIniSection
= IniCacheGetSection(IniCache
,
589 if (OsIniSection
!= NULL
)
591 BOOLEAN UseExistingEntry
= TRUE
;
594 Status
= IniCacheGetKey(OsIniSection
,
597 if (NT_SUCCESS(Status
))
600 || (_wcsicmp(KeyData
, L
"ReactOS") != 0
601 && _wcsicmp(KeyData
, L
"\"ReactOS\"") != 0))
603 /* This is not a ReactOS entry */
604 UseExistingEntry
= FALSE
;
609 UseExistingEntry
= FALSE
;
612 if (UseExistingEntry
)
614 /* BootType is ReactOS. Now check SystemPath */
615 Status
= IniCacheGetKey(OsIniSection
,
618 if (NT_SUCCESS(Status
))
620 swprintf(SystemPath
, L
"\"%S\"", ArcPath
);
622 || (_wcsicmp(KeyData
, ArcPath
) != 0
623 && _wcsicmp(KeyData
, SystemPath
) != 0))
625 /* This entry is a ReactOS entry, but the SystemRoot does not
626 match the one we are looking for */
627 UseExistingEntry
= FALSE
;
632 UseExistingEntry
= FALSE
;
636 if (UseExistingEntry
)
638 IniCacheDestroy(IniCache
);
639 return(STATUS_SUCCESS
);
643 swprintf(SectionName
, L
"ReactOS_%lu", i
);
644 swprintf(OsName
, L
"\"ReactOS %lu\"", i
);
648 /* <SectionName>=<OsName> */
649 IniCacheInsertKey(IniSection
,
655 /* Create <SectionName> section */
656 IniSection
= IniCacheAppendSection(IniCache
,
659 /* BootType=ReactOS */
660 IniCacheInsertKey(IniSection
,
666 /* SystemPath=<ArcPath> */
667 IniCacheInsertKey(IniSection
,
673 IniCacheSave(IniCache
, IniPath
);
674 IniCacheDestroy(IniCache
);
676 return(STATUS_SUCCESS
);
681 SaveCurrentBootSector(PWSTR RootPath
,
684 OBJECT_ATTRIBUTES ObjectAttributes
;
685 IO_STATUS_BLOCK IoStatusBlock
;
691 /* Allocate buffer for bootsector */
692 BootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
695 if (BootSector
== NULL
)
696 return(STATUS_INSUFFICIENT_RESOURCES
);
698 /* Read current boot sector into buffer */
699 RtlInitUnicodeString(&Name
,
702 InitializeObjectAttributes(&ObjectAttributes
,
704 OBJ_CASE_INSENSITIVE
,
708 Status
= NtOpenFile(&FileHandle
,
713 FILE_SYNCHRONOUS_IO_NONALERT
);
714 if (!NT_SUCCESS(Status
))
716 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
720 Status
= NtReadFile(FileHandle
,
730 if (!NT_SUCCESS(Status
))
732 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
736 /* Write bootsector to DstPath */
737 RtlInitUnicodeString(&Name
,
740 InitializeObjectAttributes(&ObjectAttributes
,
746 Status
= NtCreateFile(&FileHandle
,
751 FILE_ATTRIBUTE_NORMAL
,
754 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
,
757 if (!NT_SUCCESS(Status
))
759 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
763 Status
= NtWriteFile(FileHandle
,
774 /* Free the new boot sector */
775 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
782 InstallFat16BootCodeToFile(PWSTR SrcPath
,
786 OBJECT_ATTRIBUTES ObjectAttributes
;
787 IO_STATUS_BLOCK IoStatusBlock
;
791 PUCHAR OrigBootSector
;
792 PUCHAR NewBootSector
;
794 /* Allocate buffer for original bootsector */
795 OrigBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
798 if (OrigBootSector
== NULL
)
799 return(STATUS_INSUFFICIENT_RESOURCES
);
801 /* Read current boot sector into buffer */
802 RtlInitUnicodeString(&Name
,
805 InitializeObjectAttributes(&ObjectAttributes
,
807 OBJ_CASE_INSENSITIVE
,
811 Status
= NtOpenFile(&FileHandle
,
816 FILE_SYNCHRONOUS_IO_NONALERT
);
817 if (!NT_SUCCESS(Status
))
819 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
823 Status
= NtReadFile(FileHandle
,
833 if (!NT_SUCCESS(Status
))
835 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
840 /* Allocate buffer for new bootsector */
841 NewBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
844 if (NewBootSector
== NULL
)
846 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
847 return(STATUS_INSUFFICIENT_RESOURCES
);
850 /* Read new bootsector from SrcPath */
851 RtlInitUnicodeString(&Name
,
854 InitializeObjectAttributes(&ObjectAttributes
,
856 OBJ_CASE_INSENSITIVE
,
860 Status
= NtOpenFile(&FileHandle
,
865 FILE_SYNCHRONOUS_IO_NONALERT
);
866 if (!NT_SUCCESS(Status
))
868 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
869 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
873 Status
= NtReadFile(FileHandle
,
883 if (!NT_SUCCESS(Status
))
885 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
886 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
890 /* Adjust bootsector (copy a part of the FAT BPB) */
891 memcpy((NewBootSector
+ 11), (OrigBootSector
+ 11), 51 /*fat BPB length*/);
893 /* Free the original boot sector */
894 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
896 /* Write new bootsector to DstPath */
897 RtlInitUnicodeString(&Name
,
900 InitializeObjectAttributes(&ObjectAttributes
,
906 Status
= NtCreateFile(&FileHandle
,
911 FILE_ATTRIBUTE_NORMAL
,
914 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
,
917 if (!NT_SUCCESS(Status
))
919 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
924 FilePosition
.QuadPart
= 0;
926 Status
= NtWriteFile(FileHandle
,
937 /* Free the new boot sector */
938 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
945 InstallFat32BootCodeToFile(PWSTR SrcPath
,
949 OBJECT_ATTRIBUTES ObjectAttributes
;
950 IO_STATUS_BLOCK IoStatusBlock
;
954 PUCHAR OrigBootSector
;
955 PUCHAR NewBootSector
;
956 LARGE_INTEGER FileOffset
;
958 /* Allocate buffer for original bootsector */
959 OrigBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
962 if (OrigBootSector
== NULL
)
963 return(STATUS_INSUFFICIENT_RESOURCES
);
965 /* Read current boot sector into buffer */
966 RtlInitUnicodeString(&Name
,
969 InitializeObjectAttributes(&ObjectAttributes
,
971 OBJ_CASE_INSENSITIVE
,
975 Status
= NtOpenFile(&FileHandle
,
980 FILE_SYNCHRONOUS_IO_NONALERT
);
981 if (!NT_SUCCESS(Status
))
983 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
987 Status
= NtReadFile(FileHandle
,
997 if (!NT_SUCCESS(Status
))
999 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1003 /* Allocate buffer for new bootsector (2 sectors) */
1004 NewBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
1007 if (NewBootSector
== NULL
)
1009 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1010 return(STATUS_INSUFFICIENT_RESOURCES
);
1013 /* Read new bootsector from SrcPath */
1014 RtlInitUnicodeString(&Name
,
1017 InitializeObjectAttributes(&ObjectAttributes
,
1019 OBJ_CASE_INSENSITIVE
,
1023 Status
= NtOpenFile(&FileHandle
,
1028 FILE_SYNCHRONOUS_IO_NONALERT
);
1029 if (!NT_SUCCESS(Status
))
1031 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1032 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1036 Status
= NtReadFile(FileHandle
,
1045 NtClose(FileHandle
);
1046 if (!NT_SUCCESS(Status
))
1048 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1049 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1053 /* Adjust bootsector (copy a part of the FAT32 BPB) */
1054 memcpy((NewBootSector
+ 3),
1055 (OrigBootSector
+ 3),
1056 87); /* FAT32 BPB length */
1058 /* Disable the backup boot sector */
1059 NewBootSector
[0x32] = 0x00;
1060 NewBootSector
[0x33] = 0x00;
1062 /* Free the original boot sector */
1063 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1065 /* Write the first sector of the new bootcode to DstPath */
1066 RtlInitUnicodeString(&Name
,
1069 InitializeObjectAttributes(&ObjectAttributes
,
1075 Status
= NtCreateFile(&FileHandle
,
1080 FILE_ATTRIBUTE_NORMAL
,
1083 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
,
1086 if (!NT_SUCCESS(Status
))
1088 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1092 Status
= NtWriteFile(FileHandle
,
1101 NtClose(FileHandle
);
1102 if (!NT_SUCCESS(Status
))
1104 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1108 /* Write the second sector of the new bootcode to boot disk sector 14 */
1109 RtlInitUnicodeString(&Name
,
1112 InitializeObjectAttributes(&ObjectAttributes
,
1118 Status
= NtOpenFile(&FileHandle
,
1123 FILE_SYNCHRONOUS_IO_NONALERT
);
1124 if (!NT_SUCCESS(Status
))
1126 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1130 FileOffset
.QuadPart
= (ULONGLONG
)(14 * SECTORSIZE
);
1131 Status
= NtWriteFile(FileHandle
,
1136 (NewBootSector
+ SECTORSIZE
),
1140 if (!NT_SUCCESS(Status
))
1143 NtClose(FileHandle
);
1145 /* Free the new boot sector */
1146 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1153 InstallMbrBootCodeToDisk (PWSTR SrcPath
,
1156 OBJECT_ATTRIBUTES ObjectAttributes
;
1157 IO_STATUS_BLOCK IoStatusBlock
;
1158 UNICODE_STRING Name
;
1161 PPARTITION_SECTOR OrigBootSector
;
1162 PPARTITION_SECTOR NewBootSector
;
1164 /* Allocate buffer for original bootsector */
1165 OrigBootSector
= (PPARTITION_SECTOR
)RtlAllocateHeap(ProcessHeap
,
1167 sizeof(PARTITION_SECTOR
));
1168 if (OrigBootSector
== NULL
)
1169 return(STATUS_INSUFFICIENT_RESOURCES
);
1171 /* Read current boot sector into buffer */
1172 RtlInitUnicodeString(&Name
,
1175 InitializeObjectAttributes(&ObjectAttributes
,
1177 OBJ_CASE_INSENSITIVE
,
1181 Status
= NtOpenFile(&FileHandle
,
1186 FILE_SYNCHRONOUS_IO_NONALERT
);
1187 if (!NT_SUCCESS(Status
))
1189 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1193 Status
= NtReadFile(FileHandle
,
1202 NtClose(FileHandle
);
1203 if (!NT_SUCCESS(Status
))
1205 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1210 /* Allocate buffer for new bootsector */
1211 NewBootSector
= (PPARTITION_SECTOR
)RtlAllocateHeap(ProcessHeap
,
1213 sizeof(PARTITION_SECTOR
));
1214 if (NewBootSector
== NULL
)
1216 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1217 return(STATUS_INSUFFICIENT_RESOURCES
);
1220 /* Read new bootsector from SrcPath */
1221 RtlInitUnicodeString(&Name
,
1224 InitializeObjectAttributes(&ObjectAttributes
,
1226 OBJ_CASE_INSENSITIVE
,
1230 Status
= NtOpenFile(&FileHandle
,
1235 FILE_SYNCHRONOUS_IO_NONALERT
);
1236 if (!NT_SUCCESS(Status
))
1238 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1239 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1243 Status
= NtReadFile(FileHandle
,
1249 sizeof(PARTITION_SECTOR
),
1252 NtClose(FileHandle
);
1253 if (!NT_SUCCESS(Status
))
1255 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1256 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1260 /* Copy partition table from old MBR to new */
1261 RtlCopyMemory (&NewBootSector
->Signature
,
1262 &OrigBootSector
->Signature
,
1263 sizeof(PARTITION_SECTOR
) - offsetof(PARTITION_SECTOR
, Signature
) /* Length of partition table */);
1265 /* Free the original boot sector */
1266 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1268 /* Write new bootsector to RootPath */
1269 RtlInitUnicodeString(&Name
,
1272 InitializeObjectAttributes(&ObjectAttributes
,
1278 Status
= NtOpenFile(&FileHandle
,
1283 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1284 if (!NT_SUCCESS(Status
))
1286 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1287 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1291 Status
= NtWriteFile(FileHandle
,
1300 NtClose(FileHandle
);
1302 /* Free the new boot sector */
1303 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1310 InstallFat16BootCodeToDisk(PWSTR SrcPath
,
1313 OBJECT_ATTRIBUTES ObjectAttributes
;
1314 IO_STATUS_BLOCK IoStatusBlock
;
1315 UNICODE_STRING Name
;
1318 PFAT_BOOTSECTOR OrigBootSector
;
1319 PFAT_BOOTSECTOR NewBootSector
;
1320 PARTITION_INFORMATION
*PartInfo
;
1322 /* Allocate buffer for original bootsector */
1323 OrigBootSector
= RtlAllocateHeap(ProcessHeap
,
1326 if (OrigBootSector
== NULL
)
1327 return(STATUS_INSUFFICIENT_RESOURCES
);
1329 /* Read current boot sector into buffer */
1330 RtlInitUnicodeString(&Name
,
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
);
1351 Status
= NtReadFile(FileHandle
,
1360 NtClose(FileHandle
);
1361 if (!NT_SUCCESS(Status
))
1363 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1368 /* Allocate buffer for new bootsector */
1369 NewBootSector
= RtlAllocateHeap(ProcessHeap
,
1372 if (NewBootSector
== NULL
)
1374 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1375 return(STATUS_INSUFFICIENT_RESOURCES
);
1378 /* Read new bootsector from SrcPath */
1379 RtlInitUnicodeString(&Name
,
1382 InitializeObjectAttributes(&ObjectAttributes
,
1384 OBJ_CASE_INSENSITIVE
,
1388 Status
= NtOpenFile(&FileHandle
,
1393 FILE_SYNCHRONOUS_IO_NONALERT
);
1394 if (!NT_SUCCESS(Status
))
1396 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1397 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1401 Status
= NtReadFile(FileHandle
,
1410 NtClose(FileHandle
);
1411 if (!NT_SUCCESS(Status
))
1413 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1414 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1418 /* Adjust bootsector (copy a part of the FAT16 BPB) */
1419 memcpy(&NewBootSector
->BytesPerSector
,
1420 &OrigBootSector
->BytesPerSector
,
1421 51); /* FAT16 BPB length */
1423 PartInfo
= &PartitionList
->CurrentPartition
->PartInfo
[PartitionList
->CurrentPartitionNumber
];
1424 NewBootSector
->HiddenSectors
= PartInfo
->HiddenSectors
;
1426 /* Free the original boot sector */
1427 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1429 /* Write new bootsector to RootPath */
1430 RtlInitUnicodeString(&Name
,
1433 InitializeObjectAttributes(&ObjectAttributes
,
1439 Status
= NtOpenFile(&FileHandle
,
1444 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1445 if (!NT_SUCCESS(Status
))
1447 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1448 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1453 FilePosition
.QuadPart
= 0;
1455 Status
= NtWriteFile(FileHandle
,
1464 NtClose(FileHandle
);
1466 /* Free the new boot sector */
1467 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1474 InstallFat32BootCodeToDisk(PWSTR SrcPath
,
1477 OBJECT_ATTRIBUTES ObjectAttributes
;
1478 IO_STATUS_BLOCK IoStatusBlock
;
1479 UNICODE_STRING Name
;
1482 PFAT32_BOOTSECTOR OrigBootSector
;
1483 PFAT32_BOOTSECTOR NewBootSector
;
1484 LARGE_INTEGER FileOffset
;
1485 USHORT BackupBootSector
;
1486 PARTITION_INFORMATION
*PartInfo
;
1488 /* Allocate buffer for original bootsector */
1489 OrigBootSector
= RtlAllocateHeap(ProcessHeap
,
1492 if (OrigBootSector
== NULL
)
1493 return(STATUS_INSUFFICIENT_RESOURCES
);
1495 /* Read current boot sector into buffer */
1496 RtlInitUnicodeString(&Name
,
1499 InitializeObjectAttributes(&ObjectAttributes
,
1501 OBJ_CASE_INSENSITIVE
,
1505 Status
= NtOpenFile(&FileHandle
,
1510 FILE_SYNCHRONOUS_IO_NONALERT
);
1511 if (!NT_SUCCESS(Status
))
1513 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1517 Status
= NtReadFile(FileHandle
,
1526 NtClose(FileHandle
);
1527 if (!NT_SUCCESS(Status
))
1529 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1534 /* Allocate buffer for new bootsector (2 sectors) */
1535 NewBootSector
= RtlAllocateHeap(ProcessHeap
,
1538 if (NewBootSector
== NULL
)
1540 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1541 return(STATUS_INSUFFICIENT_RESOURCES
);
1544 /* Read new bootsector from SrcPath */
1545 RtlInitUnicodeString(&Name
,
1548 InitializeObjectAttributes(&ObjectAttributes
,
1550 OBJ_CASE_INSENSITIVE
,
1554 Status
= NtOpenFile(&FileHandle
,
1559 FILE_SYNCHRONOUS_IO_NONALERT
);
1560 if (!NT_SUCCESS(Status
))
1562 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1563 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1567 Status
= NtReadFile(FileHandle
,
1576 NtClose(FileHandle
);
1577 if (!NT_SUCCESS(Status
))
1579 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1580 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1584 /* Adjust bootsector (copy a part of the FAT32 BPB) */
1585 memcpy(&NewBootSector
->BytesPerSector
,
1586 &OrigBootSector
->BytesPerSector
,
1587 79); /* FAT32 BPB length */
1589 PartInfo
= &PartitionList
->CurrentPartition
->PartInfo
[PartitionList
->CurrentPartitionNumber
];
1590 NewBootSector
->HiddenSectors
= PartInfo
->HiddenSectors
;
1592 /* Get the location of the backup boot sector */
1593 BackupBootSector
= OrigBootSector
->BackupBootSector
;
1595 /* Free the original boot sector */
1596 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1598 /* Write the first sector of the new bootcode to DstPath */
1599 RtlInitUnicodeString(&Name
,
1602 InitializeObjectAttributes(&ObjectAttributes
,
1608 Status
= NtOpenFile(&FileHandle
,
1613 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1614 if (!NT_SUCCESS(Status
))
1616 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1617 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1621 /* Write sector 0 */
1622 FileOffset
.QuadPart
= 0ULL;
1623 Status
= NtWriteFile(FileHandle
,
1632 if (!NT_SUCCESS(Status
))
1634 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1635 NtClose(FileHandle
);
1636 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1640 /* Write backup boot sector */
1641 if ((BackupBootSector
!= 0x0000) && (BackupBootSector
!= 0xFFFF))
1643 FileOffset
.QuadPart
= (ULONGLONG
)((ULONG
)BackupBootSector
* SECTORSIZE
);
1644 Status
= NtWriteFile(FileHandle
,
1653 if (!NT_SUCCESS(Status
))
1655 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1656 NtClose(FileHandle
);
1657 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1662 /* Write sector 14 */
1663 FileOffset
.QuadPart
= (ULONGLONG
)(14 * SECTORSIZE
);
1664 Status
= NtWriteFile(FileHandle
,
1669 ((PUCHAR
)NewBootSector
+ SECTORSIZE
),
1673 if (!NT_SUCCESS(Status
))
1675 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1677 NtClose(FileHandle
);
1679 /* Free the new boot sector */
1680 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1687 UnprotectBootIni(PWSTR FileName
,
1690 UNICODE_STRING Name
;
1691 OBJECT_ATTRIBUTES ObjectAttributes
;
1692 IO_STATUS_BLOCK IoStatusBlock
;
1693 FILE_BASIC_INFORMATION FileInfo
;
1697 RtlInitUnicodeString(&Name
,
1700 InitializeObjectAttributes(&ObjectAttributes
,
1702 OBJ_CASE_INSENSITIVE
,
1706 Status
= NtOpenFile(&FileHandle
,
1707 GENERIC_READ
|GENERIC_WRITE
,
1711 FILE_SYNCHRONOUS_IO_NONALERT
);
1712 if (Status
== STATUS_NO_SUCH_FILE
)
1714 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1716 return(STATUS_SUCCESS
);
1718 if (!NT_SUCCESS(Status
))
1720 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1724 Status
= NtQueryInformationFile(FileHandle
,
1727 sizeof(FILE_BASIC_INFORMATION
),
1728 FileBasicInformation
);
1729 if (!NT_SUCCESS(Status
))
1731 DPRINT1("NtQueryInformationFile() failed (Status %lx)\n", Status
);
1732 NtClose(FileHandle
);
1736 *Attributes
= FileInfo
.FileAttributes
;
1738 /* Delete attributes SYSTEM, HIDDEN and READONLY */
1739 FileInfo
.FileAttributes
= FileInfo
.FileAttributes
&
1740 ~(FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
| FILE_ATTRIBUTE_READONLY
);
1742 Status
= NtSetInformationFile(FileHandle
,
1745 sizeof(FILE_BASIC_INFORMATION
),
1746 FileBasicInformation
);
1747 if (!NT_SUCCESS(Status
))
1749 DPRINT1("NtSetInformationFile() failed (Status %lx)\n", Status
);
1752 NtClose(FileHandle
);
1758 ProtectBootIni(PWSTR FileName
,
1761 UNICODE_STRING Name
;
1762 OBJECT_ATTRIBUTES ObjectAttributes
;
1763 IO_STATUS_BLOCK IoStatusBlock
;
1764 FILE_BASIC_INFORMATION FileInfo
;
1768 RtlInitUnicodeString(&Name
,
1771 InitializeObjectAttributes(&ObjectAttributes
,
1773 OBJ_CASE_INSENSITIVE
,
1777 Status
= NtOpenFile(&FileHandle
,
1778 GENERIC_READ
|GENERIC_WRITE
,
1782 FILE_SYNCHRONOUS_IO_NONALERT
);
1783 if (!NT_SUCCESS(Status
))
1785 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1789 Status
= NtQueryInformationFile(FileHandle
,
1792 sizeof(FILE_BASIC_INFORMATION
),
1793 FileBasicInformation
);
1794 if (!NT_SUCCESS(Status
))
1796 DPRINT1("NtQueryInformationFile() failed (Status %lx)\n", Status
);
1797 NtClose(FileHandle
);
1801 FileInfo
.FileAttributes
= FileInfo
.FileAttributes
| Attributes
;
1803 Status
= NtSetInformationFile(FileHandle
,
1806 sizeof(FILE_BASIC_INFORMATION
),
1807 FileBasicInformation
);
1808 if (!NT_SUCCESS(Status
))
1810 DPRINT1("NtSetInformationFile() failed (Status %lx)\n", Status
);
1813 NtClose(FileHandle
);
1819 UpdateBootIni(PWSTR BootIniPath
,
1823 UNICODE_STRING Name
;
1824 PINICACHE Cache
= NULL
;
1825 PINICACHESECTION Section
= NULL
;
1827 ULONG FileAttribute
;
1828 PWCHAR OldValue
= NULL
;
1830 RtlInitUnicodeString(&Name
,
1833 Status
= IniCacheLoad(&Cache
,
1836 if (!NT_SUCCESS(Status
))
1841 Section
= IniCacheGetSection(Cache
,
1842 L
"operating systems");
1843 if (Section
== NULL
)
1845 IniCacheDestroy(Cache
);
1846 return(STATUS_UNSUCCESSFUL
);
1849 /* Check - maybe record already exists */
1850 Status
= IniCacheGetKey(Section
,
1854 /* If either key was not found, or contains something else - add new one */
1855 if (!NT_SUCCESS(Status
) || wcscmp(OldValue
, EntryValue
))
1857 IniCacheInsertKey(Section
,
1864 Status
= UnprotectBootIni(BootIniPath
,
1866 if (!NT_SUCCESS(Status
))
1868 IniCacheDestroy(Cache
);
1872 Status
= IniCacheSave(Cache
,
1874 if (!NT_SUCCESS(Status
))
1876 IniCacheDestroy(Cache
);
1880 FileAttribute
|= (FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
| FILE_ATTRIBUTE_READONLY
);
1881 Status
= ProtectBootIni(BootIniPath
,
1884 IniCacheDestroy(Cache
);
1890 CheckInstallFatBootcodeToPartition(PUNICODE_STRING SystemRootPath
)
1893 if (DoesFileExist(SystemRootPath
->Buffer
, L
"ntldr") ||
1894 DoesFileExist(SystemRootPath
->Buffer
, L
"boot.ini"))
1898 else if (DoesFileExist(SystemRootPath
->Buffer
, L
"io.sys") ||
1899 DoesFileExist(SystemRootPath
->Buffer
, L
"msdos.sys"))
1910 InstallFatBootcodeToPartition(PUNICODE_STRING SystemRootPath
,
1911 PUNICODE_STRING SourceRootPath
,
1912 PUNICODE_STRING DestinationArcPath
,
1913 UCHAR PartitionType
)
1916 WCHAR SrcPath
[MAX_PATH
];
1917 WCHAR DstPath
[MAX_PATH
];
1920 /* FAT or FAT32 partition */
1921 DPRINT("System path: '%wZ'\n", SystemRootPath
);
1923 if (DoesFileExist(SystemRootPath
->Buffer
, L
"ntldr") == TRUE
||
1924 DoesFileExist(SystemRootPath
->Buffer
, L
"boot.ini") == TRUE
)
1926 /* Search root directory for 'ntldr' and 'boot.ini'. */
1927 DPRINT("Found Microsoft Windows NT/2000/XP boot loader\n");
1929 /* Copy FreeLoader to the boot partition */
1930 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
1931 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
1932 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1933 wcscat(DstPath
, L
"\\freeldr.sys");
1935 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
1936 Status
= SetupCopyFile(SrcPath
, DstPath
);
1937 if (!NT_SUCCESS(Status
))
1939 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
1943 /* Create or update freeldr.ini */
1944 if (DoesFileExist(SystemRootPath
->Buffer
, L
"freeldr.ini") == FALSE
)
1946 /* Create new 'freeldr.ini' */
1947 DPRINT1("Create new 'freeldr.ini'\n");
1948 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1949 wcscat(DstPath
, L
"\\freeldr.ini");
1951 Status
= CreateFreeLoaderIniForReactos(DstPath
,
1952 DestinationArcPath
->Buffer
);
1953 if (!NT_SUCCESS(Status
))
1955 DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status
);
1959 /* Install new bootcode */
1960 if (PartitionType
== PARTITION_FAT32
||
1961 PartitionType
== PARTITION_FAT32_XINT13
)
1963 /* Install FAT32 bootcode */
1964 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
1965 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
1966 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1967 wcscat(DstPath
, L
"\\bootsect.ros");
1969 DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, DstPath
);
1970 Status
= InstallFat32BootCodeToFile(SrcPath
,
1972 SystemRootPath
->Buffer
);
1973 if (!NT_SUCCESS(Status
))
1975 DPRINT1("InstallFat32BootCodeToFile() failed (Status %lx)\n", Status
);
1981 /* Install FAT16 bootcode */
1982 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
1983 wcscat(SrcPath
, L
"\\loader\\fat.bin");
1984 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1985 wcscat(DstPath
, L
"\\bootsect.ros");
1987 DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath
, DstPath
);
1988 Status
= InstallFat16BootCodeToFile(SrcPath
,
1990 SystemRootPath
->Buffer
);
1991 if (!NT_SUCCESS(Status
))
1993 DPRINT1("InstallFat16BootCodeToFile() failed (Status %lx)\n", Status
);
2000 /* Update existing 'freeldr.ini' */
2001 DPRINT1("Update existing 'freeldr.ini'\n");
2002 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2003 wcscat(DstPath
, L
"\\freeldr.ini");
2005 Status
= UpdateFreeLoaderIni(DstPath
,
2006 DestinationArcPath
->Buffer
);
2007 if (!NT_SUCCESS(Status
))
2009 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
2014 /* Update 'boot.ini' */
2015 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2016 wcscat(DstPath
, L
"\\boot.ini");
2018 DPRINT1("Update 'boot.ini': %S\n", DstPath
);
2019 Status
= UpdateBootIni(DstPath
,
2020 L
"C:\\bootsect.ros",
2022 if (!NT_SUCCESS(Status
))
2024 DPRINT1("UpdateBootIni() failed (Status %lx)\n", Status
);
2028 else if (DoesFileExist(SystemRootPath
->Buffer
, L
"io.sys") == TRUE
||
2029 DoesFileExist(SystemRootPath
->Buffer
, L
"msdos.sys") == TRUE
)
2031 /* Search for root directory for 'io.sys' and 'msdos.sys'. */
2032 DPRINT1("Found Microsoft DOS or Windows 9x boot loader\n");
2034 /* Copy FreeLoader to the boot partition */
2035 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2036 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
2037 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2038 wcscat(DstPath
, L
"\\freeldr.sys");
2040 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2041 Status
= SetupCopyFile(SrcPath
, DstPath
);
2042 if (!NT_SUCCESS(Status
))
2044 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
2048 /* Create or update 'freeldr.ini' */
2049 if (DoesFileExist(SystemRootPath
->Buffer
, L
"freeldr.ini") == FALSE
)
2051 /* Create new 'freeldr.ini' */
2052 DPRINT1("Create new 'freeldr.ini'\n");
2053 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2054 wcscat(DstPath
, L
"\\freeldr.ini");
2056 Status
= CreateFreeLoaderIniForDos(DstPath
,
2057 DestinationArcPath
->Buffer
);
2058 if (!NT_SUCCESS(Status
))
2060 DPRINT1("CreateFreeLoaderIniForDos() failed (Status %lx)\n", Status
);
2064 /* Save current bootsector as 'BOOTSECT.DOS' */
2065 wcscpy(SrcPath
, SystemRootPath
->Buffer
);
2066 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2067 wcscat(DstPath
, L
"\\bootsect.dos");
2069 DPRINT1("Save bootsector: %S ==> %S\n", SrcPath
, DstPath
);
2070 Status
= SaveCurrentBootSector(SrcPath
,
2072 if (!NT_SUCCESS(Status
))
2074 DPRINT1("SaveCurrentBootSector() failed (Status %lx)\n", Status
);
2078 /* Install new bootsector */
2079 if (PartitionType
== PARTITION_FAT32
||
2080 PartitionType
== PARTITION_FAT32_XINT13
)
2082 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2083 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
2085 DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2086 Status
= InstallFat32BootCodeToDisk(SrcPath
,
2087 SystemRootPath
->Buffer
);
2088 if (!NT_SUCCESS(Status
))
2090 DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)\n", Status
);
2096 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2097 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2099 DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2100 Status
= InstallFat16BootCodeToDisk(SrcPath
,
2101 SystemRootPath
->Buffer
);
2102 if (!NT_SUCCESS(Status
))
2104 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status
);
2111 /* Update existing 'freeldr.ini' */
2112 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2113 wcscat(DstPath
, L
"\\freeldr.ini");
2115 Status
= UpdateFreeLoaderIni(DstPath
,
2116 DestinationArcPath
->Buffer
);
2117 if (!NT_SUCCESS(Status
))
2119 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
2126 /* No or unknown boot loader */
2127 DPRINT1("No or unknown boot loader found\n");
2129 /* Copy FreeLoader to the boot partition */
2130 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2131 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
2132 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2133 wcscat(DstPath
, L
"\\freeldr.sys");
2135 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2136 Status
= SetupCopyFile(SrcPath
, DstPath
);
2137 if (!NT_SUCCESS(Status
))
2139 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
2143 /* Create or update 'freeldr.ini' */
2144 if (DoesFileExist(SystemRootPath
->Buffer
, L
"freeldr.ini") == FALSE
)
2146 /* Create new freeldr.ini */
2147 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2148 wcscat(DstPath
, L
"\\freeldr.ini");
2150 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2151 Status
= CreateFreeLoaderIniForReactos(DstPath
,
2152 DestinationArcPath
->Buffer
);
2153 if (!NT_SUCCESS(Status
))
2155 DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status
);
2159 /* Save current bootsector as 'BOOTSECT.OLD' */
2160 wcscpy(SrcPath
, SystemRootPath
->Buffer
);
2161 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2162 wcscat(DstPath
, L
"\\bootsect.old");
2164 DPRINT("Save bootsector: %S ==> %S\n", SrcPath
, DstPath
);
2165 Status
= SaveCurrentBootSector(SrcPath
,
2167 if (!NT_SUCCESS(Status
))
2169 DPRINT1("SaveCurrentBootSector() failed (Status %lx)\n", Status
);
2173 /* Install new bootsector */
2174 if (PartitionType
== PARTITION_FAT32
||
2175 PartitionType
== PARTITION_FAT32_XINT13
)
2177 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2178 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
2180 DPRINT("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2181 Status
= InstallFat32BootCodeToDisk(SrcPath
,
2182 SystemRootPath
->Buffer
);
2183 if (!NT_SUCCESS(Status
))
2185 DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)\n", Status
);
2191 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2192 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2194 DPRINT("Install FAT bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2195 Status
= InstallFat16BootCodeToDisk(SrcPath
,
2196 SystemRootPath
->Buffer
);
2197 if (!NT_SUCCESS(Status
))
2199 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status
);
2206 /* Update existing 'freeldr.ini' */
2207 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2208 wcscat(DstPath
, L
"\\freeldr.ini");
2210 Status
= UpdateFreeLoaderIni(DstPath
,
2211 DestinationArcPath
->Buffer
);
2212 if (!NT_SUCCESS(Status
))
2214 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
2220 return STATUS_SUCCESS
;
2222 return STATUS_NOT_IMPLEMENTED
;
2227 InstallVBRToPartition(PUNICODE_STRING SystemRootPath
,
2228 PUNICODE_STRING SourceRootPath
,
2229 PUNICODE_STRING DestinationArcPath
,
2230 UCHAR PartitionType
)
2232 if ((PartitionType
== PARTITION_FAT_12
) ||
2233 (PartitionType
== PARTITION_FAT_16
) ||
2234 (PartitionType
== PARTITION_HUGE
) ||
2235 (PartitionType
== PARTITION_XINT13
) ||
2236 (PartitionType
== PARTITION_FAT32
) ||
2237 (PartitionType
== PARTITION_FAT32_XINT13
))
2239 return InstallFatBootcodeToPartition(SystemRootPath
,
2245 return STATUS_UNSUCCESSFUL
;
2250 InstallFatBootcodeToFloppy(PUNICODE_STRING SourceRootPath
,
2251 PUNICODE_STRING DestinationArcPath
)
2254 WCHAR SrcPath
[MAX_PATH
];
2255 WCHAR DstPath
[MAX_PATH
];
2258 /* Copy FreeLoader to the boot partition */
2259 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2260 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
2262 wcscpy(DstPath
, L
"\\Device\\Floppy0\\freeldr.sys");
2264 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2265 Status
= SetupCopyFile(SrcPath
, DstPath
);
2266 if (!NT_SUCCESS(Status
))
2268 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
2272 /* Create new 'freeldr.ini' */
2273 wcscpy(DstPath
, L
"\\Device\\Floppy0\\freeldr.ini");
2275 DPRINT("Create new 'freeldr.ini'\n");
2276 Status
= CreateFreeLoaderIniForReactos(DstPath
,
2277 DestinationArcPath
->Buffer
);
2278 if (!NT_SUCCESS(Status
))
2280 DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status
);
2284 /* Install FAT12/16 boosector */
2285 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2286 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2288 wcscpy(DstPath
, L
"\\Device\\Floppy0");
2290 DPRINT("Install FAT bootcode: %S ==> %S\n", SrcPath
, DstPath
);
2291 Status
= InstallFat16BootCodeToDisk(SrcPath
,
2293 if (!NT_SUCCESS(Status
))
2295 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status
);
2299 return STATUS_SUCCESS
;
2301 return STATUS_NOT_IMPLEMENTED
;