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");
516 /* Save the ini file */
517 IniCacheSave(IniCache
, IniPath
);
518 IniCacheDestroy(IniCache
);
520 return(STATUS_SUCCESS
);
525 UpdateFreeLoaderIni(PWCHAR IniPath
,
530 PINICACHESECTION IniSection
;
531 PINICACHESECTION OsIniSection
;
532 WCHAR SectionName
[80];
534 WCHAR SystemPath
[200];
535 WCHAR SectionName2
[200];
540 RtlInitUnicodeString(&Name
,
543 Status
= IniCacheLoad(&IniCache
,
546 if (!NT_SUCCESS(Status
))
549 /* Get "Operating Systems" section */
550 IniSection
= IniCacheGetSection(IniCache
,
551 L
"Operating Systems");
552 if (IniSection
== NULL
)
554 IniCacheDestroy(IniCache
);
555 return(STATUS_UNSUCCESSFUL
);
558 /* Find an existing usable or an unused section name */
560 wcscpy(SectionName
, L
"ReactOS");
561 wcscpy(OsName
, L
"\"ReactOS\"");
564 Status
= IniCacheGetKey(IniSection
,
567 if (!NT_SUCCESS(Status
))
570 /* Get operation system section */
571 if (KeyData
[0] == '"')
573 wcscpy(SectionName2
, &KeyData
[1]);
574 j
= wcslen(SectionName2
);
577 SectionName2
[j
-1] = 0;
582 wcscpy(SectionName2
, KeyData
);
585 OsIniSection
= IniCacheGetSection(IniCache
,
587 if (OsIniSection
!= NULL
)
589 BOOLEAN UseExistingEntry
= TRUE
;
592 Status
= IniCacheGetKey(OsIniSection
,
595 if (NT_SUCCESS(Status
))
598 || (_wcsicmp(KeyData
, L
"ReactOS") != 0
599 && _wcsicmp(KeyData
, L
"\"ReactOS\"") != 0))
601 /* This is not a ReactOS entry */
602 UseExistingEntry
= FALSE
;
607 UseExistingEntry
= FALSE
;
610 if (UseExistingEntry
)
612 /* BootType is ReactOS. Now check SystemPath */
613 Status
= IniCacheGetKey(OsIniSection
,
616 if (NT_SUCCESS(Status
))
618 swprintf(SystemPath
, L
"\"%S\"", ArcPath
);
620 || (_wcsicmp(KeyData
, ArcPath
) != 0
621 && _wcsicmp(KeyData
, SystemPath
) != 0))
623 /* This entry is a ReactOS entry, but the SystemRoot does not
624 match the one we are looking for */
625 UseExistingEntry
= FALSE
;
630 UseExistingEntry
= FALSE
;
634 if (UseExistingEntry
)
636 IniCacheDestroy(IniCache
);
637 return(STATUS_SUCCESS
);
641 swprintf(SectionName
, L
"ReactOS_%lu", i
);
642 swprintf(OsName
, L
"\"ReactOS %lu\"", i
);
646 /* <SectionName>=<OsName> */
647 IniCacheInsertKey(IniSection
,
653 /* Create <SectionName> section */
654 IniSection
= IniCacheAppendSection(IniCache
,
657 /* BootType=ReactOS */
658 IniCacheInsertKey(IniSection
,
664 /* SystemPath=<ArcPath> */
665 IniCacheInsertKey(IniSection
,
671 IniCacheSave(IniCache
, IniPath
);
672 IniCacheDestroy(IniCache
);
674 return(STATUS_SUCCESS
);
679 SaveCurrentBootSector(PWSTR RootPath
,
682 OBJECT_ATTRIBUTES ObjectAttributes
;
683 IO_STATUS_BLOCK IoStatusBlock
;
689 /* Allocate buffer for bootsector */
690 BootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
693 if (BootSector
== NULL
)
694 return(STATUS_INSUFFICIENT_RESOURCES
);
696 /* Read current boot sector into buffer */
697 RtlInitUnicodeString(&Name
,
700 InitializeObjectAttributes(&ObjectAttributes
,
702 OBJ_CASE_INSENSITIVE
,
706 Status
= NtOpenFile(&FileHandle
,
711 FILE_SYNCHRONOUS_IO_NONALERT
);
712 if (!NT_SUCCESS(Status
))
714 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
718 Status
= NtReadFile(FileHandle
,
728 if (!NT_SUCCESS(Status
))
730 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
734 /* Write bootsector to DstPath */
735 RtlInitUnicodeString(&Name
,
738 InitializeObjectAttributes(&ObjectAttributes
,
744 Status
= NtCreateFile(&FileHandle
,
749 FILE_ATTRIBUTE_NORMAL
,
752 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
,
755 if (!NT_SUCCESS(Status
))
757 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
761 Status
= NtWriteFile(FileHandle
,
772 /* Free the new boot sector */
773 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
780 InstallFat16BootCodeToFile(PWSTR SrcPath
,
784 OBJECT_ATTRIBUTES ObjectAttributes
;
785 IO_STATUS_BLOCK IoStatusBlock
;
789 PUCHAR OrigBootSector
;
790 PUCHAR NewBootSector
;
792 /* Allocate buffer for original bootsector */
793 OrigBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
796 if (OrigBootSector
== NULL
)
797 return(STATUS_INSUFFICIENT_RESOURCES
);
799 /* Read current boot sector into buffer */
800 RtlInitUnicodeString(&Name
,
803 InitializeObjectAttributes(&ObjectAttributes
,
805 OBJ_CASE_INSENSITIVE
,
809 Status
= NtOpenFile(&FileHandle
,
814 FILE_SYNCHRONOUS_IO_NONALERT
);
815 if (!NT_SUCCESS(Status
))
817 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
821 Status
= NtReadFile(FileHandle
,
831 if (!NT_SUCCESS(Status
))
833 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
838 /* Allocate buffer for new bootsector */
839 NewBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
842 if (NewBootSector
== NULL
)
844 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
845 return(STATUS_INSUFFICIENT_RESOURCES
);
848 /* Read new bootsector from SrcPath */
849 RtlInitUnicodeString(&Name
,
852 InitializeObjectAttributes(&ObjectAttributes
,
854 OBJ_CASE_INSENSITIVE
,
858 Status
= NtOpenFile(&FileHandle
,
863 FILE_SYNCHRONOUS_IO_NONALERT
);
864 if (!NT_SUCCESS(Status
))
866 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
867 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
871 Status
= NtReadFile(FileHandle
,
881 if (!NT_SUCCESS(Status
))
883 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
884 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
888 /* Adjust bootsector (copy a part of the FAT BPB) */
889 memcpy((NewBootSector
+ 11), (OrigBootSector
+ 11), 51 /*fat BPB length*/);
891 /* Free the original boot sector */
892 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
894 /* Write new bootsector to DstPath */
895 RtlInitUnicodeString(&Name
,
898 InitializeObjectAttributes(&ObjectAttributes
,
904 Status
= NtCreateFile(&FileHandle
,
909 FILE_ATTRIBUTE_NORMAL
,
912 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
,
915 if (!NT_SUCCESS(Status
))
917 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
922 FilePosition
.QuadPart
= 0;
924 Status
= NtWriteFile(FileHandle
,
935 /* Free the new boot sector */
936 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
943 InstallFat32BootCodeToFile(PWSTR SrcPath
,
947 OBJECT_ATTRIBUTES ObjectAttributes
;
948 IO_STATUS_BLOCK IoStatusBlock
;
952 PUCHAR OrigBootSector
;
953 PUCHAR NewBootSector
;
954 LARGE_INTEGER FileOffset
;
956 /* Allocate buffer for original bootsector */
957 OrigBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
960 if (OrigBootSector
== NULL
)
961 return(STATUS_INSUFFICIENT_RESOURCES
);
963 /* Read current boot sector into buffer */
964 RtlInitUnicodeString(&Name
,
967 InitializeObjectAttributes(&ObjectAttributes
,
969 OBJ_CASE_INSENSITIVE
,
973 Status
= NtOpenFile(&FileHandle
,
978 FILE_SYNCHRONOUS_IO_NONALERT
);
979 if (!NT_SUCCESS(Status
))
981 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
985 Status
= NtReadFile(FileHandle
,
995 if (!NT_SUCCESS(Status
))
997 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1001 /* Allocate buffer for new bootsector (2 sectors) */
1002 NewBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
1005 if (NewBootSector
== NULL
)
1007 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1008 return(STATUS_INSUFFICIENT_RESOURCES
);
1011 /* Read new bootsector from SrcPath */
1012 RtlInitUnicodeString(&Name
,
1015 InitializeObjectAttributes(&ObjectAttributes
,
1017 OBJ_CASE_INSENSITIVE
,
1021 Status
= NtOpenFile(&FileHandle
,
1026 FILE_SYNCHRONOUS_IO_NONALERT
);
1027 if (!NT_SUCCESS(Status
))
1029 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1030 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1034 Status
= NtReadFile(FileHandle
,
1043 NtClose(FileHandle
);
1044 if (!NT_SUCCESS(Status
))
1046 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1047 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1051 /* Adjust bootsector (copy a part of the FAT32 BPB) */
1052 memcpy((NewBootSector
+ 3),
1053 (OrigBootSector
+ 3),
1054 87); /* FAT32 BPB length */
1056 /* Disable the backup boot sector */
1057 NewBootSector
[0x32] = 0x00;
1058 NewBootSector
[0x33] = 0x00;
1060 /* Free the original boot sector */
1061 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1063 /* Write the first sector of the new bootcode to DstPath */
1064 RtlInitUnicodeString(&Name
,
1067 InitializeObjectAttributes(&ObjectAttributes
,
1073 Status
= NtCreateFile(&FileHandle
,
1078 FILE_ATTRIBUTE_NORMAL
,
1081 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
,
1084 if (!NT_SUCCESS(Status
))
1086 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1090 Status
= NtWriteFile(FileHandle
,
1099 NtClose(FileHandle
);
1100 if (!NT_SUCCESS(Status
))
1102 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1106 /* Write the second sector of the new bootcode to boot disk sector 14 */
1107 RtlInitUnicodeString(&Name
,
1110 InitializeObjectAttributes(&ObjectAttributes
,
1116 Status
= NtOpenFile(&FileHandle
,
1121 FILE_SYNCHRONOUS_IO_NONALERT
);
1122 if (!NT_SUCCESS(Status
))
1124 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1128 FileOffset
.QuadPart
= (ULONGLONG
)(14 * SECTORSIZE
);
1129 Status
= NtWriteFile(FileHandle
,
1134 (NewBootSector
+ SECTORSIZE
),
1138 if (!NT_SUCCESS(Status
))
1141 NtClose(FileHandle
);
1143 /* Free the new boot sector */
1144 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1151 InstallMbrBootCodeToDisk (PWSTR SrcPath
,
1154 OBJECT_ATTRIBUTES ObjectAttributes
;
1155 IO_STATUS_BLOCK IoStatusBlock
;
1156 UNICODE_STRING Name
;
1159 PPARTITION_SECTOR OrigBootSector
;
1160 PPARTITION_SECTOR NewBootSector
;
1162 /* Allocate buffer for original bootsector */
1163 OrigBootSector
= (PPARTITION_SECTOR
)RtlAllocateHeap(ProcessHeap
,
1165 sizeof(PARTITION_SECTOR
));
1166 if (OrigBootSector
== NULL
)
1167 return(STATUS_INSUFFICIENT_RESOURCES
);
1169 /* Read current boot sector into buffer */
1170 RtlInitUnicodeString(&Name
,
1173 InitializeObjectAttributes(&ObjectAttributes
,
1175 OBJ_CASE_INSENSITIVE
,
1179 Status
= NtOpenFile(&FileHandle
,
1184 FILE_SYNCHRONOUS_IO_NONALERT
);
1185 if (!NT_SUCCESS(Status
))
1187 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1191 Status
= NtReadFile(FileHandle
,
1200 NtClose(FileHandle
);
1201 if (!NT_SUCCESS(Status
))
1203 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1208 /* Allocate buffer for new bootsector */
1209 NewBootSector
= (PPARTITION_SECTOR
)RtlAllocateHeap(ProcessHeap
,
1211 sizeof(PARTITION_SECTOR
));
1212 if (NewBootSector
== NULL
)
1214 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1215 return(STATUS_INSUFFICIENT_RESOURCES
);
1218 /* Read new bootsector from SrcPath */
1219 RtlInitUnicodeString(&Name
,
1222 InitializeObjectAttributes(&ObjectAttributes
,
1224 OBJ_CASE_INSENSITIVE
,
1228 Status
= NtOpenFile(&FileHandle
,
1233 FILE_SYNCHRONOUS_IO_NONALERT
);
1234 if (!NT_SUCCESS(Status
))
1236 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1237 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1241 Status
= NtReadFile(FileHandle
,
1247 sizeof(PARTITION_SECTOR
),
1250 NtClose(FileHandle
);
1251 if (!NT_SUCCESS(Status
))
1253 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1254 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1258 /* Copy partition table from old MBR to new */
1259 RtlCopyMemory (&NewBootSector
->Signature
,
1260 &OrigBootSector
->Signature
,
1261 sizeof(PARTITION_SECTOR
) - offsetof(PARTITION_SECTOR
, Signature
) /* Length of partition table */);
1263 /* Free the original boot sector */
1264 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1266 /* Write new bootsector to RootPath */
1267 RtlInitUnicodeString(&Name
,
1270 InitializeObjectAttributes(&ObjectAttributes
,
1276 Status
= NtOpenFile(&FileHandle
,
1281 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1282 if (!NT_SUCCESS(Status
))
1284 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1285 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1289 Status
= NtWriteFile(FileHandle
,
1298 NtClose(FileHandle
);
1300 /* Free the new boot sector */
1301 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1308 InstallFat16BootCodeToDisk(PWSTR SrcPath
,
1311 OBJECT_ATTRIBUTES ObjectAttributes
;
1312 IO_STATUS_BLOCK IoStatusBlock
;
1313 UNICODE_STRING Name
;
1316 PFAT_BOOTSECTOR OrigBootSector
;
1317 PFAT_BOOTSECTOR NewBootSector
;
1318 PARTITION_INFORMATION
*PartInfo
;
1320 /* Allocate buffer for original bootsector */
1321 OrigBootSector
= RtlAllocateHeap(ProcessHeap
,
1324 if (OrigBootSector
== NULL
)
1325 return(STATUS_INSUFFICIENT_RESOURCES
);
1327 /* Read current boot sector into buffer */
1328 RtlInitUnicodeString(&Name
,
1331 InitializeObjectAttributes(&ObjectAttributes
,
1333 OBJ_CASE_INSENSITIVE
,
1337 Status
= NtOpenFile(&FileHandle
,
1342 FILE_SYNCHRONOUS_IO_NONALERT
);
1343 if (!NT_SUCCESS(Status
))
1345 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1349 Status
= NtReadFile(FileHandle
,
1358 NtClose(FileHandle
);
1359 if (!NT_SUCCESS(Status
))
1361 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1366 /* Allocate buffer for new bootsector */
1367 NewBootSector
= RtlAllocateHeap(ProcessHeap
,
1370 if (NewBootSector
== NULL
)
1372 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1373 return(STATUS_INSUFFICIENT_RESOURCES
);
1376 /* Read new bootsector from SrcPath */
1377 RtlInitUnicodeString(&Name
,
1380 InitializeObjectAttributes(&ObjectAttributes
,
1382 OBJ_CASE_INSENSITIVE
,
1386 Status
= NtOpenFile(&FileHandle
,
1391 FILE_SYNCHRONOUS_IO_NONALERT
);
1392 if (!NT_SUCCESS(Status
))
1394 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1395 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1399 Status
= NtReadFile(FileHandle
,
1408 NtClose(FileHandle
);
1409 if (!NT_SUCCESS(Status
))
1411 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1412 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1416 /* Adjust bootsector (copy a part of the FAT16 BPB) */
1417 memcpy(&NewBootSector
->BytesPerSector
,
1418 &OrigBootSector
->BytesPerSector
,
1419 51); /* FAT16 BPB length */
1421 PartInfo
= &PartitionList
->CurrentPartition
->PartInfo
[PartitionList
->CurrentPartitionNumber
];
1422 NewBootSector
->HiddenSectors
= PartInfo
->HiddenSectors
;
1424 /* Free the original boot sector */
1425 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1427 /* Write new bootsector to RootPath */
1428 RtlInitUnicodeString(&Name
,
1431 InitializeObjectAttributes(&ObjectAttributes
,
1437 Status
= NtOpenFile(&FileHandle
,
1442 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1443 if (!NT_SUCCESS(Status
))
1445 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1446 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1451 FilePosition
.QuadPart
= 0;
1453 Status
= NtWriteFile(FileHandle
,
1462 NtClose(FileHandle
);
1464 /* Free the new boot sector */
1465 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1472 InstallFat32BootCodeToDisk(PWSTR SrcPath
,
1475 OBJECT_ATTRIBUTES ObjectAttributes
;
1476 IO_STATUS_BLOCK IoStatusBlock
;
1477 UNICODE_STRING Name
;
1480 PFAT32_BOOTSECTOR OrigBootSector
;
1481 PFAT32_BOOTSECTOR NewBootSector
;
1482 LARGE_INTEGER FileOffset
;
1483 USHORT BackupBootSector
;
1484 PARTITION_INFORMATION
*PartInfo
;
1486 /* Allocate buffer for original bootsector */
1487 OrigBootSector
= RtlAllocateHeap(ProcessHeap
,
1490 if (OrigBootSector
== NULL
)
1491 return(STATUS_INSUFFICIENT_RESOURCES
);
1493 /* Read current boot sector into buffer */
1494 RtlInitUnicodeString(&Name
,
1497 InitializeObjectAttributes(&ObjectAttributes
,
1499 OBJ_CASE_INSENSITIVE
,
1503 Status
= NtOpenFile(&FileHandle
,
1508 FILE_SYNCHRONOUS_IO_NONALERT
);
1509 if (!NT_SUCCESS(Status
))
1511 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1515 Status
= NtReadFile(FileHandle
,
1524 NtClose(FileHandle
);
1525 if (!NT_SUCCESS(Status
))
1527 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1532 /* Allocate buffer for new bootsector (2 sectors) */
1533 NewBootSector
= RtlAllocateHeap(ProcessHeap
,
1536 if (NewBootSector
== NULL
)
1538 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1539 return(STATUS_INSUFFICIENT_RESOURCES
);
1542 /* Read new bootsector from SrcPath */
1543 RtlInitUnicodeString(&Name
,
1546 InitializeObjectAttributes(&ObjectAttributes
,
1548 OBJ_CASE_INSENSITIVE
,
1552 Status
= NtOpenFile(&FileHandle
,
1557 FILE_SYNCHRONOUS_IO_NONALERT
);
1558 if (!NT_SUCCESS(Status
))
1560 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1561 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1565 Status
= NtReadFile(FileHandle
,
1574 NtClose(FileHandle
);
1575 if (!NT_SUCCESS(Status
))
1577 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1578 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1582 /* Adjust bootsector (copy a part of the FAT32 BPB) */
1583 memcpy(&NewBootSector
->BytesPerSector
,
1584 &OrigBootSector
->BytesPerSector
,
1585 79); /* FAT32 BPB length */
1587 PartInfo
= &PartitionList
->CurrentPartition
->PartInfo
[PartitionList
->CurrentPartitionNumber
];
1588 NewBootSector
->HiddenSectors
= PartInfo
->HiddenSectors
;
1590 /* Get the location of the backup boot sector */
1591 BackupBootSector
= OrigBootSector
->BackupBootSector
;
1593 /* Free the original boot sector */
1594 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1596 /* Write the first sector of the new bootcode to DstPath */
1597 RtlInitUnicodeString(&Name
,
1600 InitializeObjectAttributes(&ObjectAttributes
,
1606 Status
= NtOpenFile(&FileHandle
,
1611 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1612 if (!NT_SUCCESS(Status
))
1614 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1615 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1619 /* Write sector 0 */
1620 FileOffset
.QuadPart
= 0ULL;
1621 Status
= NtWriteFile(FileHandle
,
1630 if (!NT_SUCCESS(Status
))
1632 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1633 NtClose(FileHandle
);
1634 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1638 /* Write backup boot sector */
1639 if ((BackupBootSector
!= 0x0000) && (BackupBootSector
!= 0xFFFF))
1641 FileOffset
.QuadPart
= (ULONGLONG
)((ULONG
)BackupBootSector
* SECTORSIZE
);
1642 Status
= NtWriteFile(FileHandle
,
1651 if (!NT_SUCCESS(Status
))
1653 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1654 NtClose(FileHandle
);
1655 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1660 /* Write sector 14 */
1661 FileOffset
.QuadPart
= (ULONGLONG
)(14 * SECTORSIZE
);
1662 Status
= NtWriteFile(FileHandle
,
1667 ((PUCHAR
)NewBootSector
+ SECTORSIZE
),
1671 if (!NT_SUCCESS(Status
))
1673 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1675 NtClose(FileHandle
);
1677 /* Free the new boot sector */
1678 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1685 UnprotectBootIni(PWSTR FileName
,
1688 UNICODE_STRING Name
;
1689 OBJECT_ATTRIBUTES ObjectAttributes
;
1690 IO_STATUS_BLOCK IoStatusBlock
;
1691 FILE_BASIC_INFORMATION FileInfo
;
1695 RtlInitUnicodeString(&Name
,
1698 InitializeObjectAttributes(&ObjectAttributes
,
1700 OBJ_CASE_INSENSITIVE
,
1704 Status
= NtOpenFile(&FileHandle
,
1705 GENERIC_READ
|GENERIC_WRITE
,
1709 FILE_SYNCHRONOUS_IO_NONALERT
);
1710 if (Status
== STATUS_NO_SUCH_FILE
)
1712 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1714 return(STATUS_SUCCESS
);
1716 if (!NT_SUCCESS(Status
))
1718 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1722 Status
= NtQueryInformationFile(FileHandle
,
1725 sizeof(FILE_BASIC_INFORMATION
),
1726 FileBasicInformation
);
1727 if (!NT_SUCCESS(Status
))
1729 DPRINT1("NtQueryInformationFile() failed (Status %lx)\n", Status
);
1730 NtClose(FileHandle
);
1734 *Attributes
= FileInfo
.FileAttributes
;
1736 /* Delete attributes SYSTEM, HIDDEN and READONLY */
1737 FileInfo
.FileAttributes
= FileInfo
.FileAttributes
&
1738 ~(FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
| FILE_ATTRIBUTE_READONLY
);
1740 Status
= NtSetInformationFile(FileHandle
,
1743 sizeof(FILE_BASIC_INFORMATION
),
1744 FileBasicInformation
);
1745 if (!NT_SUCCESS(Status
))
1747 DPRINT1("NtSetInformationFile() failed (Status %lx)\n", Status
);
1750 NtClose(FileHandle
);
1756 ProtectBootIni(PWSTR FileName
,
1759 UNICODE_STRING Name
;
1760 OBJECT_ATTRIBUTES ObjectAttributes
;
1761 IO_STATUS_BLOCK IoStatusBlock
;
1762 FILE_BASIC_INFORMATION FileInfo
;
1766 RtlInitUnicodeString(&Name
,
1769 InitializeObjectAttributes(&ObjectAttributes
,
1771 OBJ_CASE_INSENSITIVE
,
1775 Status
= NtOpenFile(&FileHandle
,
1776 GENERIC_READ
|GENERIC_WRITE
,
1780 FILE_SYNCHRONOUS_IO_NONALERT
);
1781 if (!NT_SUCCESS(Status
))
1783 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1787 Status
= NtQueryInformationFile(FileHandle
,
1790 sizeof(FILE_BASIC_INFORMATION
),
1791 FileBasicInformation
);
1792 if (!NT_SUCCESS(Status
))
1794 DPRINT1("NtQueryInformationFile() failed (Status %lx)\n", Status
);
1795 NtClose(FileHandle
);
1799 FileInfo
.FileAttributes
= FileInfo
.FileAttributes
| Attributes
;
1801 Status
= NtSetInformationFile(FileHandle
,
1804 sizeof(FILE_BASIC_INFORMATION
),
1805 FileBasicInformation
);
1806 if (!NT_SUCCESS(Status
))
1808 DPRINT1("NtSetInformationFile() failed (Status %lx)\n", Status
);
1811 NtClose(FileHandle
);
1817 UpdateBootIni(PWSTR BootIniPath
,
1821 UNICODE_STRING Name
;
1822 PINICACHE Cache
= NULL
;
1823 PINICACHESECTION Section
= NULL
;
1825 ULONG FileAttribute
;
1826 PWCHAR OldValue
= NULL
;
1828 RtlInitUnicodeString(&Name
,
1831 Status
= IniCacheLoad(&Cache
,
1834 if (!NT_SUCCESS(Status
))
1839 Section
= IniCacheGetSection(Cache
,
1840 L
"operating systems");
1841 if (Section
== NULL
)
1843 IniCacheDestroy(Cache
);
1844 return(STATUS_UNSUCCESSFUL
);
1847 /* Check - maybe record already exists */
1848 Status
= IniCacheGetKey(Section
,
1852 /* If either key was not found, or contains something else - add new one */
1853 if (!NT_SUCCESS(Status
) || wcscmp(OldValue
, EntryValue
))
1855 IniCacheInsertKey(Section
,
1862 Status
= UnprotectBootIni(BootIniPath
,
1864 if (!NT_SUCCESS(Status
))
1866 IniCacheDestroy(Cache
);
1870 Status
= IniCacheSave(Cache
,
1872 if (!NT_SUCCESS(Status
))
1874 IniCacheDestroy(Cache
);
1878 FileAttribute
|= (FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
| FILE_ATTRIBUTE_READONLY
);
1879 Status
= ProtectBootIni(BootIniPath
,
1882 IniCacheDestroy(Cache
);
1888 CheckInstallFatBootcodeToPartition(PUNICODE_STRING SystemRootPath
)
1891 if (DoesFileExist(SystemRootPath
->Buffer
, L
"ntldr") ||
1892 DoesFileExist(SystemRootPath
->Buffer
, L
"boot.ini"))
1896 else if (DoesFileExist(SystemRootPath
->Buffer
, L
"io.sys") ||
1897 DoesFileExist(SystemRootPath
->Buffer
, L
"msdos.sys"))
1908 InstallFatBootcodeToPartition(PUNICODE_STRING SystemRootPath
,
1909 PUNICODE_STRING SourceRootPath
,
1910 PUNICODE_STRING DestinationArcPath
,
1911 UCHAR PartitionType
)
1914 WCHAR SrcPath
[MAX_PATH
];
1915 WCHAR DstPath
[MAX_PATH
];
1918 /* FAT or FAT32 partition */
1919 DPRINT("System path: '%wZ'\n", SystemRootPath
);
1921 if (DoesFileExist(SystemRootPath
->Buffer
, L
"ntldr") == TRUE
||
1922 DoesFileExist(SystemRootPath
->Buffer
, L
"boot.ini") == TRUE
)
1924 /* Search root directory for 'ntldr' and 'boot.ini'. */
1925 DPRINT("Found Microsoft Windows NT/2000/XP boot loader\n");
1927 /* Copy FreeLoader to the boot partition */
1928 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
1929 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
1930 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1931 wcscat(DstPath
, L
"\\freeldr.sys");
1933 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
1934 Status
= SetupCopyFile(SrcPath
, DstPath
);
1935 if (!NT_SUCCESS(Status
))
1937 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
1941 /* Create or update freeldr.ini */
1942 if (DoesFileExist(SystemRootPath
->Buffer
, L
"freeldr.ini") == FALSE
)
1944 /* Create new 'freeldr.ini' */
1945 DPRINT1("Create new 'freeldr.ini'\n");
1946 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1947 wcscat(DstPath
, L
"\\freeldr.ini");
1949 Status
= CreateFreeLoaderIniForReactos(DstPath
,
1950 DestinationArcPath
->Buffer
);
1951 if (!NT_SUCCESS(Status
))
1953 DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status
);
1957 /* Install new bootcode */
1958 if (PartitionType
== PARTITION_FAT32
||
1959 PartitionType
== PARTITION_FAT32_XINT13
)
1961 /* Install FAT32 bootcode */
1962 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
1963 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
1964 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1965 wcscat(DstPath
, L
"\\bootsect.ros");
1967 DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, DstPath
);
1968 Status
= InstallFat32BootCodeToFile(SrcPath
,
1970 SystemRootPath
->Buffer
);
1971 if (!NT_SUCCESS(Status
))
1973 DPRINT1("InstallFat32BootCodeToFile() failed (Status %lx)\n", Status
);
1979 /* Install FAT16 bootcode */
1980 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
1981 wcscat(SrcPath
, L
"\\loader\\fat.bin");
1982 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1983 wcscat(DstPath
, L
"\\bootsect.ros");
1985 DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath
, DstPath
);
1986 Status
= InstallFat16BootCodeToFile(SrcPath
,
1988 SystemRootPath
->Buffer
);
1989 if (!NT_SUCCESS(Status
))
1991 DPRINT1("InstallFat16BootCodeToFile() failed (Status %lx)\n", Status
);
1998 /* Update existing 'freeldr.ini' */
1999 DPRINT1("Update existing 'freeldr.ini'\n");
2000 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2001 wcscat(DstPath
, L
"\\freeldr.ini");
2003 Status
= UpdateFreeLoaderIni(DstPath
,
2004 DestinationArcPath
->Buffer
);
2005 if (!NT_SUCCESS(Status
))
2007 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
2012 /* Update 'boot.ini' */
2013 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2014 wcscat(DstPath
, L
"\\boot.ini");
2016 DPRINT1("Update 'boot.ini': %S\n", DstPath
);
2017 Status
= UpdateBootIni(DstPath
,
2018 L
"C:\\bootsect.ros",
2020 if (!NT_SUCCESS(Status
))
2022 DPRINT1("UpdateBootIni() failed (Status %lx)\n", Status
);
2026 else if (DoesFileExist(SystemRootPath
->Buffer
, L
"io.sys") == TRUE
||
2027 DoesFileExist(SystemRootPath
->Buffer
, L
"msdos.sys") == TRUE
)
2029 /* Search for root directory for 'io.sys' and 'msdos.sys'. */
2030 DPRINT1("Found Microsoft DOS or Windows 9x boot loader\n");
2032 /* Copy FreeLoader to the boot partition */
2033 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2034 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
2035 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2036 wcscat(DstPath
, L
"\\freeldr.sys");
2038 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2039 Status
= SetupCopyFile(SrcPath
, DstPath
);
2040 if (!NT_SUCCESS(Status
))
2042 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
2046 /* Create or update 'freeldr.ini' */
2047 if (DoesFileExist(SystemRootPath
->Buffer
, L
"freeldr.ini") == FALSE
)
2049 /* Create new 'freeldr.ini' */
2050 DPRINT1("Create new 'freeldr.ini'\n");
2051 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2052 wcscat(DstPath
, L
"\\freeldr.ini");
2054 Status
= CreateFreeLoaderIniForDos(DstPath
,
2055 DestinationArcPath
->Buffer
);
2056 if (!NT_SUCCESS(Status
))
2058 DPRINT1("CreateFreeLoaderIniForDos() failed (Status %lx)\n", Status
);
2062 /* Save current bootsector as 'BOOTSECT.DOS' */
2063 wcscpy(SrcPath
, SystemRootPath
->Buffer
);
2064 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2065 wcscat(DstPath
, L
"\\bootsect.dos");
2067 DPRINT1("Save bootsector: %S ==> %S\n", SrcPath
, DstPath
);
2068 Status
= SaveCurrentBootSector(SrcPath
,
2070 if (!NT_SUCCESS(Status
))
2072 DPRINT1("SaveCurrentBootSector() failed (Status %lx)\n", Status
);
2076 /* Install new bootsector */
2077 if (PartitionType
== PARTITION_FAT32
||
2078 PartitionType
== PARTITION_FAT32_XINT13
)
2080 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2081 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
2083 DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2084 Status
= InstallFat32BootCodeToDisk(SrcPath
,
2085 SystemRootPath
->Buffer
);
2086 if (!NT_SUCCESS(Status
))
2088 DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)\n", Status
);
2094 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2095 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2097 DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2098 Status
= InstallFat16BootCodeToDisk(SrcPath
,
2099 SystemRootPath
->Buffer
);
2100 if (!NT_SUCCESS(Status
))
2102 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status
);
2109 /* Update existing 'freeldr.ini' */
2110 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2111 wcscat(DstPath
, L
"\\freeldr.ini");
2113 Status
= UpdateFreeLoaderIni(DstPath
,
2114 DestinationArcPath
->Buffer
);
2115 if (!NT_SUCCESS(Status
))
2117 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
2124 /* No or unknown boot loader */
2125 DPRINT1("No or unknown boot loader found\n");
2127 /* Copy FreeLoader to the boot partition */
2128 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2129 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
2130 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2131 wcscat(DstPath
, L
"\\freeldr.sys");
2133 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2134 Status
= SetupCopyFile(SrcPath
, DstPath
);
2135 if (!NT_SUCCESS(Status
))
2137 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
2141 /* Create or update 'freeldr.ini' */
2142 if (DoesFileExist(SystemRootPath
->Buffer
, L
"freeldr.ini") == FALSE
)
2144 /* Create new freeldr.ini */
2145 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2146 wcscat(DstPath
, L
"\\freeldr.ini");
2148 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2149 Status
= CreateFreeLoaderIniForReactos(DstPath
,
2150 DestinationArcPath
->Buffer
);
2151 if (!NT_SUCCESS(Status
))
2153 DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status
);
2157 /* Save current bootsector as 'BOOTSECT.OLD' */
2158 wcscpy(SrcPath
, SystemRootPath
->Buffer
);
2159 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2160 wcscat(DstPath
, L
"\\bootsect.old");
2162 DPRINT("Save bootsector: %S ==> %S\n", SrcPath
, DstPath
);
2163 Status
= SaveCurrentBootSector(SrcPath
,
2165 if (!NT_SUCCESS(Status
))
2167 DPRINT1("SaveCurrentBootSector() failed (Status %lx)\n", Status
);
2171 /* Install new bootsector */
2172 if (PartitionType
== PARTITION_FAT32
||
2173 PartitionType
== PARTITION_FAT32_XINT13
)
2175 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2176 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
2178 DPRINT("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2179 Status
= InstallFat32BootCodeToDisk(SrcPath
,
2180 SystemRootPath
->Buffer
);
2181 if (!NT_SUCCESS(Status
))
2183 DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)\n", Status
);
2189 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2190 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2192 DPRINT("Install FAT bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2193 Status
= InstallFat16BootCodeToDisk(SrcPath
,
2194 SystemRootPath
->Buffer
);
2195 if (!NT_SUCCESS(Status
))
2197 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status
);
2204 /* Update existing 'freeldr.ini' */
2205 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2206 wcscat(DstPath
, L
"\\freeldr.ini");
2208 Status
= UpdateFreeLoaderIni(DstPath
,
2209 DestinationArcPath
->Buffer
);
2210 if (!NT_SUCCESS(Status
))
2212 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
2218 return STATUS_SUCCESS
;
2220 return STATUS_NOT_IMPLEMENTED
;
2225 InstallVBRToPartition(PUNICODE_STRING SystemRootPath
,
2226 PUNICODE_STRING SourceRootPath
,
2227 PUNICODE_STRING DestinationArcPath
,
2228 UCHAR PartitionType
)
2230 if ((PartitionType
== PARTITION_FAT_12
) ||
2231 (PartitionType
== PARTITION_FAT_16
) ||
2232 (PartitionType
== PARTITION_HUGE
) ||
2233 (PartitionType
== PARTITION_XINT13
) ||
2234 (PartitionType
== PARTITION_FAT32
) ||
2235 (PartitionType
== PARTITION_FAT32_XINT13
))
2237 return InstallFatBootcodeToPartition(SystemRootPath
,
2243 return STATUS_UNSUCCESSFUL
;
2248 InstallFatBootcodeToFloppy(PUNICODE_STRING SourceRootPath
,
2249 PUNICODE_STRING DestinationArcPath
)
2252 WCHAR SrcPath
[MAX_PATH
];
2253 WCHAR DstPath
[MAX_PATH
];
2256 /* Copy FreeLoader to the boot partition */
2257 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2258 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
2260 wcscpy(DstPath
, L
"\\Device\\Floppy0\\freeldr.sys");
2262 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2263 Status
= SetupCopyFile(SrcPath
, DstPath
);
2264 if (!NT_SUCCESS(Status
))
2266 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
2270 /* Create new 'freeldr.ini' */
2271 wcscpy(DstPath
, L
"\\Device\\Floppy0\\freeldr.ini");
2273 DPRINT("Create new 'freeldr.ini'\n");
2274 Status
= CreateFreeLoaderIniForReactos(DstPath
,
2275 DestinationArcPath
->Buffer
);
2276 if (!NT_SUCCESS(Status
))
2278 DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status
);
2282 /* Install FAT12/16 boosector */
2283 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2284 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2286 wcscpy(DstPath
, L
"\\Device\\Floppy0");
2288 DPRINT("Install FAT bootcode: %S ==> %S\n", SrcPath
, DstPath
);
2289 Status
= InstallFat16BootCodeToDisk(SrcPath
,
2291 if (!NT_SUCCESS(Status
))
2293 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status
);
2297 return STATUS_SUCCESS
;
2299 return STATUS_NOT_IMPLEMENTED
;