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");
497 /* ReactOS_KdSerial */
498 CreateFreeLoaderEntry(IniCache
, IniSection
,
499 L
"ReactOS_KdSerial", L
"\"ReactOS (RosDbg)\"",
500 L
"Windows2003", ArcPath
,
501 L
"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /KDSERIAL");
503 /* ReactOS_LogFile */
504 CreateFreeLoaderEntry(IniCache
, IniSection
,
505 L
"ReactOS_LogFile", L
"\"ReactOS (Log file)\"",
506 L
"Windows2003", ArcPath
,
507 L
"/DEBUG /DEBUGPORT=FILE /SOS");
510 CreateFreeLoaderEntry(IniCache
, IniSection
,
511 L
"ReactOS_Ram", L
"\"ReactOS (RAM Disk)\"",
512 L
"ReactOS", L
"ramdisk(0)\\ReactOS",
513 L
"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /RDIMAGEPATH=reactos.img /RDIMAGEOFFSET=32256");
517 CreateFreeLoaderEntry(IniCache
, IniSection
,
518 L
"ReactOS_old", L
"\"ReactOS (old boot method)\"",
522 /* ReactOS_Debug_old */
523 CreateFreeLoaderEntry(IniCache
, IniSection
,
524 L
"ReactOS_Debug_old", L
"\"ReactOS (Debug, old boot method)\"",
526 L
"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS");
528 /* Save the ini file */
529 IniCacheSave(IniCache
, IniPath
);
530 IniCacheDestroy(IniCache
);
532 return(STATUS_SUCCESS
);
537 UpdateFreeLoaderIni(PWCHAR IniPath
,
542 PINICACHESECTION IniSection
;
543 PINICACHESECTION OsIniSection
;
544 WCHAR SectionName
[80];
546 WCHAR SystemPath
[200];
547 WCHAR SectionName2
[200];
552 RtlInitUnicodeString(&Name
,
555 Status
= IniCacheLoad(&IniCache
,
558 if (!NT_SUCCESS(Status
))
561 /* Get "Operating Systems" section */
562 IniSection
= IniCacheGetSection(IniCache
,
563 L
"Operating Systems");
564 if (IniSection
== NULL
)
566 IniCacheDestroy(IniCache
);
567 return(STATUS_UNSUCCESSFUL
);
570 /* Find an existing usable or an unused section name */
572 wcscpy(SectionName
, L
"ReactOS");
573 wcscpy(OsName
, L
"\"ReactOS\"");
576 Status
= IniCacheGetKey(IniSection
,
579 if (!NT_SUCCESS(Status
))
582 /* Get operation system section */
583 if (KeyData
[0] == '"')
585 wcscpy(SectionName2
, &KeyData
[1]);
586 j
= wcslen(SectionName2
);
589 SectionName2
[j
-1] = 0;
594 wcscpy(SectionName2
, KeyData
);
597 OsIniSection
= IniCacheGetSection(IniCache
,
599 if (OsIniSection
!= NULL
)
601 BOOLEAN UseExistingEntry
= TRUE
;
604 Status
= IniCacheGetKey(OsIniSection
,
607 if (NT_SUCCESS(Status
))
610 || (_wcsicmp(KeyData
, L
"ReactOS") != 0
611 && _wcsicmp(KeyData
, L
"\"ReactOS\"") != 0))
613 /* This is not a ReactOS entry */
614 UseExistingEntry
= FALSE
;
619 UseExistingEntry
= FALSE
;
622 if (UseExistingEntry
)
624 /* BootType is ReactOS. Now check SystemPath */
625 Status
= IniCacheGetKey(OsIniSection
,
628 if (NT_SUCCESS(Status
))
630 swprintf(SystemPath
, L
"\"%S\"", ArcPath
);
632 || (_wcsicmp(KeyData
, ArcPath
) != 0
633 && _wcsicmp(KeyData
, SystemPath
) != 0))
635 /* This entry is a ReactOS entry, but the SystemRoot does not
636 match the one we are looking for */
637 UseExistingEntry
= FALSE
;
642 UseExistingEntry
= FALSE
;
646 if (UseExistingEntry
)
648 IniCacheDestroy(IniCache
);
649 return(STATUS_SUCCESS
);
653 swprintf(SectionName
, L
"ReactOS_%lu", i
);
654 swprintf(OsName
, L
"\"ReactOS %lu\"", i
);
658 /* <SectionName>=<OsName> */
659 IniCacheInsertKey(IniSection
,
665 /* Create <SectionName> section */
666 IniSection
= IniCacheAppendSection(IniCache
,
669 /* BootType=ReactOS */
670 IniCacheInsertKey(IniSection
,
676 /* SystemPath=<ArcPath> */
677 IniCacheInsertKey(IniSection
,
683 IniCacheSave(IniCache
, IniPath
);
684 IniCacheDestroy(IniCache
);
686 return(STATUS_SUCCESS
);
691 SaveCurrentBootSector(PWSTR RootPath
,
694 OBJECT_ATTRIBUTES ObjectAttributes
;
695 IO_STATUS_BLOCK IoStatusBlock
;
701 /* Allocate buffer for bootsector */
702 BootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
705 if (BootSector
== NULL
)
706 return(STATUS_INSUFFICIENT_RESOURCES
);
708 /* Read current boot sector into buffer */
709 RtlInitUnicodeString(&Name
,
712 InitializeObjectAttributes(&ObjectAttributes
,
714 OBJ_CASE_INSENSITIVE
,
718 Status
= NtOpenFile(&FileHandle
,
723 FILE_SYNCHRONOUS_IO_NONALERT
);
724 if (!NT_SUCCESS(Status
))
726 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
730 Status
= NtReadFile(FileHandle
,
740 if (!NT_SUCCESS(Status
))
742 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
746 /* Write bootsector to DstPath */
747 RtlInitUnicodeString(&Name
,
750 InitializeObjectAttributes(&ObjectAttributes
,
756 Status
= NtCreateFile(&FileHandle
,
761 FILE_ATTRIBUTE_NORMAL
,
764 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
,
767 if (!NT_SUCCESS(Status
))
769 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
773 Status
= NtWriteFile(FileHandle
,
784 /* Free the new boot sector */
785 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
792 InstallFat16BootCodeToFile(PWSTR SrcPath
,
796 OBJECT_ATTRIBUTES ObjectAttributes
;
797 IO_STATUS_BLOCK IoStatusBlock
;
801 PUCHAR OrigBootSector
;
802 PUCHAR NewBootSector
;
804 /* Allocate buffer for original bootsector */
805 OrigBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
808 if (OrigBootSector
== NULL
)
809 return(STATUS_INSUFFICIENT_RESOURCES
);
811 /* Read current boot sector into buffer */
812 RtlInitUnicodeString(&Name
,
815 InitializeObjectAttributes(&ObjectAttributes
,
817 OBJ_CASE_INSENSITIVE
,
821 Status
= NtOpenFile(&FileHandle
,
826 FILE_SYNCHRONOUS_IO_NONALERT
);
827 if (!NT_SUCCESS(Status
))
829 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
833 Status
= NtReadFile(FileHandle
,
843 if (!NT_SUCCESS(Status
))
845 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
850 /* Allocate buffer for new bootsector */
851 NewBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
854 if (NewBootSector
== NULL
)
856 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
857 return(STATUS_INSUFFICIENT_RESOURCES
);
860 /* Read new bootsector from SrcPath */
861 RtlInitUnicodeString(&Name
,
864 InitializeObjectAttributes(&ObjectAttributes
,
866 OBJ_CASE_INSENSITIVE
,
870 Status
= NtOpenFile(&FileHandle
,
875 FILE_SYNCHRONOUS_IO_NONALERT
);
876 if (!NT_SUCCESS(Status
))
878 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
879 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
883 Status
= NtReadFile(FileHandle
,
893 if (!NT_SUCCESS(Status
))
895 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
896 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
900 /* Adjust bootsector (copy a part of the FAT BPB) */
901 memcpy((NewBootSector
+ 11), (OrigBootSector
+ 11), 51 /*fat BPB length*/);
903 /* Free the original boot sector */
904 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
906 /* Write new bootsector to DstPath */
907 RtlInitUnicodeString(&Name
,
910 InitializeObjectAttributes(&ObjectAttributes
,
916 Status
= NtCreateFile(&FileHandle
,
921 FILE_ATTRIBUTE_NORMAL
,
924 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
,
927 if (!NT_SUCCESS(Status
))
929 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
934 FilePosition
.QuadPart
= 0;
936 Status
= NtWriteFile(FileHandle
,
947 /* Free the new boot sector */
948 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
955 InstallFat32BootCodeToFile(PWSTR SrcPath
,
959 OBJECT_ATTRIBUTES ObjectAttributes
;
960 IO_STATUS_BLOCK IoStatusBlock
;
964 PUCHAR OrigBootSector
;
965 PUCHAR NewBootSector
;
966 LARGE_INTEGER FileOffset
;
968 /* Allocate buffer for original bootsector */
969 OrigBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
972 if (OrigBootSector
== NULL
)
973 return(STATUS_INSUFFICIENT_RESOURCES
);
975 /* Read current boot sector into buffer */
976 RtlInitUnicodeString(&Name
,
979 InitializeObjectAttributes(&ObjectAttributes
,
981 OBJ_CASE_INSENSITIVE
,
985 Status
= NtOpenFile(&FileHandle
,
990 FILE_SYNCHRONOUS_IO_NONALERT
);
991 if (!NT_SUCCESS(Status
))
993 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
997 Status
= NtReadFile(FileHandle
,
1006 NtClose(FileHandle
);
1007 if (!NT_SUCCESS(Status
))
1009 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1013 /* Allocate buffer for new bootsector (2 sectors) */
1014 NewBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
1017 if (NewBootSector
== NULL
)
1019 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1020 return(STATUS_INSUFFICIENT_RESOURCES
);
1023 /* Read new bootsector from SrcPath */
1024 RtlInitUnicodeString(&Name
,
1027 InitializeObjectAttributes(&ObjectAttributes
,
1029 OBJ_CASE_INSENSITIVE
,
1033 Status
= NtOpenFile(&FileHandle
,
1038 FILE_SYNCHRONOUS_IO_NONALERT
);
1039 if (!NT_SUCCESS(Status
))
1041 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1042 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1046 Status
= NtReadFile(FileHandle
,
1055 NtClose(FileHandle
);
1056 if (!NT_SUCCESS(Status
))
1058 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1059 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1063 /* Adjust bootsector (copy a part of the FAT32 BPB) */
1064 memcpy((NewBootSector
+ 3),
1065 (OrigBootSector
+ 3),
1066 87); /* FAT32 BPB length */
1068 /* Disable the backup boot sector */
1069 NewBootSector
[0x32] = 0x00;
1070 NewBootSector
[0x33] = 0x00;
1072 /* Free the original boot sector */
1073 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1075 /* Write the first sector of the new bootcode to DstPath */
1076 RtlInitUnicodeString(&Name
,
1079 InitializeObjectAttributes(&ObjectAttributes
,
1085 Status
= NtCreateFile(&FileHandle
,
1090 FILE_ATTRIBUTE_NORMAL
,
1093 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
,
1096 if (!NT_SUCCESS(Status
))
1098 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1102 Status
= NtWriteFile(FileHandle
,
1111 NtClose(FileHandle
);
1112 if (!NT_SUCCESS(Status
))
1114 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1118 /* Write the second sector of the new bootcode to boot disk sector 14 */
1119 RtlInitUnicodeString(&Name
,
1122 InitializeObjectAttributes(&ObjectAttributes
,
1128 Status
= NtOpenFile(&FileHandle
,
1133 FILE_SYNCHRONOUS_IO_NONALERT
);
1134 if (!NT_SUCCESS(Status
))
1136 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1140 FileOffset
.QuadPart
= (ULONGLONG
)(14 * SECTORSIZE
);
1141 Status
= NtWriteFile(FileHandle
,
1146 (NewBootSector
+ SECTORSIZE
),
1150 if (!NT_SUCCESS(Status
))
1153 NtClose(FileHandle
);
1155 /* Free the new boot sector */
1156 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1163 InstallMbrBootCodeToDisk (PWSTR SrcPath
,
1166 OBJECT_ATTRIBUTES ObjectAttributes
;
1167 IO_STATUS_BLOCK IoStatusBlock
;
1168 UNICODE_STRING Name
;
1171 PPARTITION_SECTOR OrigBootSector
;
1172 PPARTITION_SECTOR NewBootSector
;
1174 /* Allocate buffer for original bootsector */
1175 OrigBootSector
= (PPARTITION_SECTOR
)RtlAllocateHeap(ProcessHeap
,
1177 sizeof(PARTITION_SECTOR
));
1178 if (OrigBootSector
== NULL
)
1179 return(STATUS_INSUFFICIENT_RESOURCES
);
1181 /* Read current boot sector into buffer */
1182 RtlInitUnicodeString(&Name
,
1185 InitializeObjectAttributes(&ObjectAttributes
,
1187 OBJ_CASE_INSENSITIVE
,
1191 Status
= NtOpenFile(&FileHandle
,
1196 FILE_SYNCHRONOUS_IO_NONALERT
);
1197 if (!NT_SUCCESS(Status
))
1199 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1203 Status
= NtReadFile(FileHandle
,
1212 NtClose(FileHandle
);
1213 if (!NT_SUCCESS(Status
))
1215 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1220 /* Allocate buffer for new bootsector */
1221 NewBootSector
= (PPARTITION_SECTOR
)RtlAllocateHeap(ProcessHeap
,
1223 sizeof(PARTITION_SECTOR
));
1224 if (NewBootSector
== NULL
)
1226 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1227 return(STATUS_INSUFFICIENT_RESOURCES
);
1230 /* Read new bootsector from SrcPath */
1231 RtlInitUnicodeString(&Name
,
1234 InitializeObjectAttributes(&ObjectAttributes
,
1236 OBJ_CASE_INSENSITIVE
,
1240 Status
= NtOpenFile(&FileHandle
,
1245 FILE_SYNCHRONOUS_IO_NONALERT
);
1246 if (!NT_SUCCESS(Status
))
1248 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1249 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1253 Status
= NtReadFile(FileHandle
,
1259 sizeof(PARTITION_SECTOR
),
1262 NtClose(FileHandle
);
1263 if (!NT_SUCCESS(Status
))
1265 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1266 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1270 /* Copy partition table from old MBR to new */
1271 RtlCopyMemory (&NewBootSector
->Signature
,
1272 &OrigBootSector
->Signature
,
1273 sizeof(PARTITION_SECTOR
) - offsetof(PARTITION_SECTOR
, Signature
) /* Length of partition table */);
1275 /* Free the original boot sector */
1276 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1278 /* Write new bootsector to RootPath */
1279 RtlInitUnicodeString(&Name
,
1282 InitializeObjectAttributes(&ObjectAttributes
,
1288 Status
= NtOpenFile(&FileHandle
,
1293 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1294 if (!NT_SUCCESS(Status
))
1296 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1297 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1301 Status
= NtWriteFile(FileHandle
,
1310 NtClose(FileHandle
);
1312 /* Free the new boot sector */
1313 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1320 InstallFat16BootCodeToDisk(PWSTR SrcPath
,
1323 OBJECT_ATTRIBUTES ObjectAttributes
;
1324 IO_STATUS_BLOCK IoStatusBlock
;
1325 UNICODE_STRING Name
;
1328 PFAT_BOOTSECTOR OrigBootSector
;
1329 PFAT_BOOTSECTOR NewBootSector
;
1330 PARTITION_INFORMATION
*PartInfo
;
1332 /* Allocate buffer for original bootsector */
1333 OrigBootSector
= RtlAllocateHeap(ProcessHeap
,
1336 if (OrigBootSector
== NULL
)
1337 return(STATUS_INSUFFICIENT_RESOURCES
);
1339 /* Read current boot sector into buffer */
1340 RtlInitUnicodeString(&Name
,
1343 InitializeObjectAttributes(&ObjectAttributes
,
1345 OBJ_CASE_INSENSITIVE
,
1349 Status
= NtOpenFile(&FileHandle
,
1354 FILE_SYNCHRONOUS_IO_NONALERT
);
1355 if (!NT_SUCCESS(Status
))
1357 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1361 Status
= NtReadFile(FileHandle
,
1370 NtClose(FileHandle
);
1371 if (!NT_SUCCESS(Status
))
1373 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
,
1392 InitializeObjectAttributes(&ObjectAttributes
,
1394 OBJ_CASE_INSENSITIVE
,
1398 Status
= NtOpenFile(&FileHandle
,
1403 FILE_SYNCHRONOUS_IO_NONALERT
);
1404 if (!NT_SUCCESS(Status
))
1406 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1407 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1411 Status
= NtReadFile(FileHandle
,
1420 NtClose(FileHandle
);
1421 if (!NT_SUCCESS(Status
))
1423 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1424 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1428 /* Adjust bootsector (copy a part of the FAT16 BPB) */
1429 memcpy(&NewBootSector
->BytesPerSector
,
1430 &OrigBootSector
->BytesPerSector
,
1431 51); /* FAT16 BPB length */
1433 PartInfo
= &PartitionList
->CurrentPartition
->PartInfo
[PartitionList
->CurrentPartitionNumber
];
1434 NewBootSector
->HiddenSectors
= PartInfo
->HiddenSectors
;
1436 /* Free the original boot sector */
1437 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1439 /* Write new bootsector to RootPath */
1440 RtlInitUnicodeString(&Name
,
1443 InitializeObjectAttributes(&ObjectAttributes
,
1449 Status
= NtOpenFile(&FileHandle
,
1454 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1455 if (!NT_SUCCESS(Status
))
1457 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1458 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1463 FilePosition
.QuadPart
= 0;
1465 Status
= NtWriteFile(FileHandle
,
1474 NtClose(FileHandle
);
1476 /* Free the new boot sector */
1477 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1484 InstallFat32BootCodeToDisk(PWSTR SrcPath
,
1487 OBJECT_ATTRIBUTES ObjectAttributes
;
1488 IO_STATUS_BLOCK IoStatusBlock
;
1489 UNICODE_STRING Name
;
1492 PFAT32_BOOTSECTOR OrigBootSector
;
1493 PFAT32_BOOTSECTOR NewBootSector
;
1494 LARGE_INTEGER FileOffset
;
1495 USHORT BackupBootSector
;
1496 PARTITION_INFORMATION
*PartInfo
;
1498 /* Allocate buffer for original bootsector */
1499 OrigBootSector
= RtlAllocateHeap(ProcessHeap
,
1502 if (OrigBootSector
== NULL
)
1503 return(STATUS_INSUFFICIENT_RESOURCES
);
1505 /* Read current boot sector into buffer */
1506 RtlInitUnicodeString(&Name
,
1509 InitializeObjectAttributes(&ObjectAttributes
,
1511 OBJ_CASE_INSENSITIVE
,
1515 Status
= NtOpenFile(&FileHandle
,
1520 FILE_SYNCHRONOUS_IO_NONALERT
);
1521 if (!NT_SUCCESS(Status
))
1523 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1527 Status
= NtReadFile(FileHandle
,
1536 NtClose(FileHandle
);
1537 if (!NT_SUCCESS(Status
))
1539 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1544 /* Allocate buffer for new bootsector (2 sectors) */
1545 NewBootSector
= RtlAllocateHeap(ProcessHeap
,
1548 if (NewBootSector
== NULL
)
1550 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1551 return(STATUS_INSUFFICIENT_RESOURCES
);
1554 /* Read new bootsector from SrcPath */
1555 RtlInitUnicodeString(&Name
,
1558 InitializeObjectAttributes(&ObjectAttributes
,
1560 OBJ_CASE_INSENSITIVE
,
1564 Status
= NtOpenFile(&FileHandle
,
1569 FILE_SYNCHRONOUS_IO_NONALERT
);
1570 if (!NT_SUCCESS(Status
))
1572 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1573 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1577 Status
= NtReadFile(FileHandle
,
1586 NtClose(FileHandle
);
1587 if (!NT_SUCCESS(Status
))
1589 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1590 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1594 /* Adjust bootsector (copy a part of the FAT32 BPB) */
1595 memcpy(&NewBootSector
->BytesPerSector
,
1596 &OrigBootSector
->BytesPerSector
,
1597 79); /* FAT32 BPB length */
1599 PartInfo
= &PartitionList
->CurrentPartition
->PartInfo
[PartitionList
->CurrentPartitionNumber
];
1600 NewBootSector
->HiddenSectors
= PartInfo
->HiddenSectors
;
1602 /* Get the location of the backup boot sector */
1603 BackupBootSector
= OrigBootSector
->BackupBootSector
;
1605 /* Free the original boot sector */
1606 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1608 /* Write the first sector of the new bootcode to DstPath */
1609 RtlInitUnicodeString(&Name
,
1612 InitializeObjectAttributes(&ObjectAttributes
,
1618 Status
= NtOpenFile(&FileHandle
,
1623 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1624 if (!NT_SUCCESS(Status
))
1626 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1627 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1631 /* Write sector 0 */
1632 FileOffset
.QuadPart
= 0ULL;
1633 Status
= NtWriteFile(FileHandle
,
1642 if (!NT_SUCCESS(Status
))
1644 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1645 NtClose(FileHandle
);
1646 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1650 /* Write backup boot sector */
1651 if ((BackupBootSector
!= 0x0000) && (BackupBootSector
!= 0xFFFF))
1653 FileOffset
.QuadPart
= (ULONGLONG
)((ULONG
)BackupBootSector
* SECTORSIZE
);
1654 Status
= NtWriteFile(FileHandle
,
1663 if (!NT_SUCCESS(Status
))
1665 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1666 NtClose(FileHandle
);
1667 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1672 /* Write sector 14 */
1673 FileOffset
.QuadPart
= (ULONGLONG
)(14 * SECTORSIZE
);
1674 Status
= NtWriteFile(FileHandle
,
1679 ((PUCHAR
)NewBootSector
+ SECTORSIZE
),
1683 if (!NT_SUCCESS(Status
))
1685 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1687 NtClose(FileHandle
);
1689 /* Free the new boot sector */
1690 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1697 UnprotectBootIni(PWSTR FileName
,
1700 UNICODE_STRING Name
;
1701 OBJECT_ATTRIBUTES ObjectAttributes
;
1702 IO_STATUS_BLOCK IoStatusBlock
;
1703 FILE_BASIC_INFORMATION FileInfo
;
1707 RtlInitUnicodeString(&Name
,
1710 InitializeObjectAttributes(&ObjectAttributes
,
1712 OBJ_CASE_INSENSITIVE
,
1716 Status
= NtOpenFile(&FileHandle
,
1717 GENERIC_READ
|GENERIC_WRITE
,
1721 FILE_SYNCHRONOUS_IO_NONALERT
);
1722 if (Status
== STATUS_NO_SUCH_FILE
)
1724 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1726 return(STATUS_SUCCESS
);
1728 if (!NT_SUCCESS(Status
))
1730 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1734 Status
= NtQueryInformationFile(FileHandle
,
1737 sizeof(FILE_BASIC_INFORMATION
),
1738 FileBasicInformation
);
1739 if (!NT_SUCCESS(Status
))
1741 DPRINT1("NtQueryInformationFile() failed (Status %lx)\n", Status
);
1742 NtClose(FileHandle
);
1746 *Attributes
= FileInfo
.FileAttributes
;
1748 /* Delete attributes SYSTEM, HIDDEN and READONLY */
1749 FileInfo
.FileAttributes
= FileInfo
.FileAttributes
&
1750 ~(FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
| FILE_ATTRIBUTE_READONLY
);
1752 Status
= NtSetInformationFile(FileHandle
,
1755 sizeof(FILE_BASIC_INFORMATION
),
1756 FileBasicInformation
);
1757 if (!NT_SUCCESS(Status
))
1759 DPRINT1("NtSetInformationFile() failed (Status %lx)\n", Status
);
1762 NtClose(FileHandle
);
1768 ProtectBootIni(PWSTR FileName
,
1771 UNICODE_STRING Name
;
1772 OBJECT_ATTRIBUTES ObjectAttributes
;
1773 IO_STATUS_BLOCK IoStatusBlock
;
1774 FILE_BASIC_INFORMATION FileInfo
;
1778 RtlInitUnicodeString(&Name
,
1781 InitializeObjectAttributes(&ObjectAttributes
,
1783 OBJ_CASE_INSENSITIVE
,
1787 Status
= NtOpenFile(&FileHandle
,
1788 GENERIC_READ
|GENERIC_WRITE
,
1792 FILE_SYNCHRONOUS_IO_NONALERT
);
1793 if (!NT_SUCCESS(Status
))
1795 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1799 Status
= NtQueryInformationFile(FileHandle
,
1802 sizeof(FILE_BASIC_INFORMATION
),
1803 FileBasicInformation
);
1804 if (!NT_SUCCESS(Status
))
1806 DPRINT1("NtQueryInformationFile() failed (Status %lx)\n", Status
);
1807 NtClose(FileHandle
);
1811 FileInfo
.FileAttributes
= FileInfo
.FileAttributes
| Attributes
;
1813 Status
= NtSetInformationFile(FileHandle
,
1816 sizeof(FILE_BASIC_INFORMATION
),
1817 FileBasicInformation
);
1818 if (!NT_SUCCESS(Status
))
1820 DPRINT1("NtSetInformationFile() failed (Status %lx)\n", Status
);
1823 NtClose(FileHandle
);
1829 UpdateBootIni(PWSTR BootIniPath
,
1833 UNICODE_STRING Name
;
1834 PINICACHE Cache
= NULL
;
1835 PINICACHESECTION Section
= NULL
;
1837 ULONG FileAttribute
;
1838 PWCHAR OldValue
= NULL
;
1840 RtlInitUnicodeString(&Name
,
1843 Status
= IniCacheLoad(&Cache
,
1846 if (!NT_SUCCESS(Status
))
1851 Section
= IniCacheGetSection(Cache
,
1852 L
"operating systems");
1853 if (Section
== NULL
)
1855 IniCacheDestroy(Cache
);
1856 return(STATUS_UNSUCCESSFUL
);
1859 /* Check - maybe record already exists */
1860 Status
= IniCacheGetKey(Section
,
1864 /* If either key was not found, or contains something else - add new one */
1865 if (!NT_SUCCESS(Status
) || wcscmp(OldValue
, EntryValue
))
1867 IniCacheInsertKey(Section
,
1874 Status
= UnprotectBootIni(BootIniPath
,
1876 if (!NT_SUCCESS(Status
))
1878 IniCacheDestroy(Cache
);
1882 Status
= IniCacheSave(Cache
,
1884 if (!NT_SUCCESS(Status
))
1886 IniCacheDestroy(Cache
);
1890 FileAttribute
|= (FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
| FILE_ATTRIBUTE_READONLY
);
1891 Status
= ProtectBootIni(BootIniPath
,
1894 IniCacheDestroy(Cache
);
1900 CheckInstallFatBootcodeToPartition(PUNICODE_STRING SystemRootPath
)
1903 if (DoesFileExist(SystemRootPath
->Buffer
, L
"ntldr") ||
1904 DoesFileExist(SystemRootPath
->Buffer
, L
"boot.ini"))
1908 else if (DoesFileExist(SystemRootPath
->Buffer
, L
"io.sys") ||
1909 DoesFileExist(SystemRootPath
->Buffer
, L
"msdos.sys"))
1920 InstallFatBootcodeToPartition(PUNICODE_STRING SystemRootPath
,
1921 PUNICODE_STRING SourceRootPath
,
1922 PUNICODE_STRING DestinationArcPath
,
1923 UCHAR PartitionType
)
1926 WCHAR SrcPath
[MAX_PATH
];
1927 WCHAR DstPath
[MAX_PATH
];
1930 /* FAT or FAT32 partition */
1931 DPRINT("System path: '%wZ'\n", SystemRootPath
);
1933 if (DoesFileExist(SystemRootPath
->Buffer
, L
"ntldr") == TRUE
||
1934 DoesFileExist(SystemRootPath
->Buffer
, L
"boot.ini") == TRUE
)
1936 /* Search root directory for 'ntldr' and 'boot.ini'. */
1937 DPRINT("Found Microsoft Windows NT/2000/XP boot loader\n");
1939 /* Copy FreeLoader to the boot partition */
1940 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
1941 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
1942 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1943 wcscat(DstPath
, L
"\\freeldr.sys");
1945 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
1946 Status
= SetupCopyFile(SrcPath
, DstPath
);
1947 if (!NT_SUCCESS(Status
))
1949 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
1953 /* Create or update freeldr.ini */
1954 if (DoesFileExist(SystemRootPath
->Buffer
, L
"freeldr.ini") == FALSE
)
1956 /* Create new 'freeldr.ini' */
1957 DPRINT1("Create new 'freeldr.ini'\n");
1958 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1959 wcscat(DstPath
, L
"\\freeldr.ini");
1961 Status
= CreateFreeLoaderIniForReactos(DstPath
,
1962 DestinationArcPath
->Buffer
);
1963 if (!NT_SUCCESS(Status
))
1965 DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status
);
1969 /* Install new bootcode */
1970 if (PartitionType
== PARTITION_FAT32
||
1971 PartitionType
== PARTITION_FAT32_XINT13
)
1973 /* Install FAT32 bootcode */
1974 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
1975 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
1976 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1977 wcscat(DstPath
, L
"\\bootsect.ros");
1979 DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, DstPath
);
1980 Status
= InstallFat32BootCodeToFile(SrcPath
,
1982 SystemRootPath
->Buffer
);
1983 if (!NT_SUCCESS(Status
))
1985 DPRINT1("InstallFat32BootCodeToFile() failed (Status %lx)\n", Status
);
1991 /* Install FAT16 bootcode */
1992 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
1993 wcscat(SrcPath
, L
"\\loader\\fat.bin");
1994 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1995 wcscat(DstPath
, L
"\\bootsect.ros");
1997 DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath
, DstPath
);
1998 Status
= InstallFat16BootCodeToFile(SrcPath
,
2000 SystemRootPath
->Buffer
);
2001 if (!NT_SUCCESS(Status
))
2003 DPRINT1("InstallFat16BootCodeToFile() failed (Status %lx)\n", Status
);
2010 /* Update existing 'freeldr.ini' */
2011 DPRINT1("Update existing 'freeldr.ini'\n");
2012 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2013 wcscat(DstPath
, L
"\\freeldr.ini");
2015 Status
= UpdateFreeLoaderIni(DstPath
,
2016 DestinationArcPath
->Buffer
);
2017 if (!NT_SUCCESS(Status
))
2019 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
2024 /* Update 'boot.ini' */
2025 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2026 wcscat(DstPath
, L
"\\boot.ini");
2028 DPRINT1("Update 'boot.ini': %S\n", DstPath
);
2029 Status
= UpdateBootIni(DstPath
,
2030 L
"C:\\bootsect.ros",
2032 if (!NT_SUCCESS(Status
))
2034 DPRINT1("UpdateBootIni() failed (Status %lx)\n", Status
);
2038 else if (DoesFileExist(SystemRootPath
->Buffer
, L
"io.sys") == TRUE
||
2039 DoesFileExist(SystemRootPath
->Buffer
, L
"msdos.sys") == TRUE
)
2041 /* Search for root directory for 'io.sys' and 'msdos.sys'. */
2042 DPRINT1("Found Microsoft DOS or Windows 9x boot loader\n");
2044 /* Copy FreeLoader to the boot partition */
2045 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2046 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
2047 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2048 wcscat(DstPath
, L
"\\freeldr.sys");
2050 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2051 Status
= SetupCopyFile(SrcPath
, DstPath
);
2052 if (!NT_SUCCESS(Status
))
2054 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
2058 /* Create or update 'freeldr.ini' */
2059 if (DoesFileExist(SystemRootPath
->Buffer
, L
"freeldr.ini") == FALSE
)
2061 /* Create new 'freeldr.ini' */
2062 DPRINT1("Create new 'freeldr.ini'\n");
2063 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2064 wcscat(DstPath
, L
"\\freeldr.ini");
2066 Status
= CreateFreeLoaderIniForDos(DstPath
,
2067 DestinationArcPath
->Buffer
);
2068 if (!NT_SUCCESS(Status
))
2070 DPRINT1("CreateFreeLoaderIniForDos() failed (Status %lx)\n", Status
);
2074 /* Save current bootsector as 'BOOTSECT.DOS' */
2075 wcscpy(SrcPath
, SystemRootPath
->Buffer
);
2076 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2077 wcscat(DstPath
, L
"\\bootsect.dos");
2079 DPRINT1("Save bootsector: %S ==> %S\n", SrcPath
, DstPath
);
2080 Status
= SaveCurrentBootSector(SrcPath
,
2082 if (!NT_SUCCESS(Status
))
2084 DPRINT1("SaveCurrentBootSector() failed (Status %lx)\n", Status
);
2088 /* Install new bootsector */
2089 if (PartitionType
== PARTITION_FAT32
||
2090 PartitionType
== PARTITION_FAT32_XINT13
)
2092 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2093 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
2095 DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2096 Status
= InstallFat32BootCodeToDisk(SrcPath
,
2097 SystemRootPath
->Buffer
);
2098 if (!NT_SUCCESS(Status
))
2100 DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)\n", Status
);
2106 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2107 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2109 DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2110 Status
= InstallFat16BootCodeToDisk(SrcPath
,
2111 SystemRootPath
->Buffer
);
2112 if (!NT_SUCCESS(Status
))
2114 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status
);
2121 /* Update existing 'freeldr.ini' */
2122 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2123 wcscat(DstPath
, L
"\\freeldr.ini");
2125 Status
= UpdateFreeLoaderIni(DstPath
,
2126 DestinationArcPath
->Buffer
);
2127 if (!NT_SUCCESS(Status
))
2129 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
2136 /* No or unknown boot loader */
2137 DPRINT1("No or unknown boot loader found\n");
2139 /* Copy FreeLoader to the boot partition */
2140 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2141 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
2142 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2143 wcscat(DstPath
, L
"\\freeldr.sys");
2145 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2146 Status
= SetupCopyFile(SrcPath
, DstPath
);
2147 if (!NT_SUCCESS(Status
))
2149 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
2153 /* Create or update 'freeldr.ini' */
2154 if (DoesFileExist(SystemRootPath
->Buffer
, L
"freeldr.ini") == FALSE
)
2156 /* Create new freeldr.ini */
2157 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2158 wcscat(DstPath
, L
"\\freeldr.ini");
2160 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2161 Status
= CreateFreeLoaderIniForReactos(DstPath
,
2162 DestinationArcPath
->Buffer
);
2163 if (!NT_SUCCESS(Status
))
2165 DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status
);
2169 /* Save current bootsector as 'BOOTSECT.OLD' */
2170 wcscpy(SrcPath
, SystemRootPath
->Buffer
);
2171 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2172 wcscat(DstPath
, L
"\\bootsect.old");
2174 DPRINT("Save bootsector: %S ==> %S\n", SrcPath
, DstPath
);
2175 Status
= SaveCurrentBootSector(SrcPath
,
2177 if (!NT_SUCCESS(Status
))
2179 DPRINT1("SaveCurrentBootSector() failed (Status %lx)\n", Status
);
2183 /* Install new bootsector */
2184 if (PartitionType
== PARTITION_FAT32
||
2185 PartitionType
== PARTITION_FAT32_XINT13
)
2187 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2188 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
2190 DPRINT("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2191 Status
= InstallFat32BootCodeToDisk(SrcPath
,
2192 SystemRootPath
->Buffer
);
2193 if (!NT_SUCCESS(Status
))
2195 DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)\n", Status
);
2201 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2202 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2204 DPRINT("Install FAT bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2205 Status
= InstallFat16BootCodeToDisk(SrcPath
,
2206 SystemRootPath
->Buffer
);
2207 if (!NT_SUCCESS(Status
))
2209 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status
);
2216 /* Update existing 'freeldr.ini' */
2217 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2218 wcscat(DstPath
, L
"\\freeldr.ini");
2220 Status
= UpdateFreeLoaderIni(DstPath
,
2221 DestinationArcPath
->Buffer
);
2222 if (!NT_SUCCESS(Status
))
2224 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
2230 return STATUS_SUCCESS
;
2232 return STATUS_NOT_IMPLEMENTED
;
2237 InstallVBRToPartition(PUNICODE_STRING SystemRootPath
,
2238 PUNICODE_STRING SourceRootPath
,
2239 PUNICODE_STRING DestinationArcPath
,
2240 UCHAR PartitionType
)
2242 if ((PartitionType
== PARTITION_FAT_12
) ||
2243 (PartitionType
== PARTITION_FAT_16
) ||
2244 (PartitionType
== PARTITION_HUGE
) ||
2245 (PartitionType
== PARTITION_XINT13
) ||
2246 (PartitionType
== PARTITION_FAT32
) ||
2247 (PartitionType
== PARTITION_FAT32_XINT13
))
2249 return InstallFatBootcodeToPartition(SystemRootPath
,
2255 return STATUS_UNSUCCESSFUL
;
2260 InstallFatBootcodeToFloppy(PUNICODE_STRING SourceRootPath
,
2261 PUNICODE_STRING DestinationArcPath
)
2264 WCHAR SrcPath
[MAX_PATH
];
2265 WCHAR DstPath
[MAX_PATH
];
2268 /* Copy FreeLoader to the boot partition */
2269 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2270 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
2272 wcscpy(DstPath
, L
"\\Device\\Floppy0\\freeldr.sys");
2274 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2275 Status
= SetupCopyFile(SrcPath
, DstPath
);
2276 if (!NT_SUCCESS(Status
))
2278 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
2282 /* Create new 'freeldr.ini' */
2283 wcscpy(DstPath
, L
"\\Device\\Floppy0\\freeldr.ini");
2285 DPRINT("Create new 'freeldr.ini'\n");
2286 Status
= CreateFreeLoaderIniForReactos(DstPath
,
2287 DestinationArcPath
->Buffer
);
2288 if (!NT_SUCCESS(Status
))
2290 DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status
);
2294 /* Install FAT12/16 boosector */
2295 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2296 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2298 wcscpy(DstPath
, L
"\\Device\\Floppy0");
2300 DPRINT("Install FAT bootcode: %S ==> %S\n", SrcPath
, DstPath
);
2301 Status
= InstallFat16BootCodeToDisk(SrcPath
,
2303 if (!NT_SUCCESS(Status
))
2305 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status
);
2309 return STATUS_SUCCESS
;
2311 return STATUS_NOT_IMPLEMENTED
;