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
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, 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
34 /* FUNCTIONS ****************************************************************/
38 CreateCommonFreeLoaderSections(PINICACHE IniCache
)
40 PINICACHESECTION IniSection
;
42 /* Create "FREELOADER" section */
43 IniSection
= IniCacheAppendSection(IniCache
,
47 if (IsUnattendedSetup
)
49 /* DefaultOS=ReactOS */
50 IniCacheInsertKey(IniSection
,
59 /* DefaultOS=ReactOS */
60 IniCacheInsertKey(IniSection
,
68 if (IsUnattendedSetup
)
71 /* Timeout=0 for unattended or non debug*/
72 IniCacheInsertKey(IniSection
,
82 IniCacheInsertKey(IniSection
,
90 /* Create "Display" section */
91 IniSection
= IniCacheAppendSection(IniCache
,
94 /* TitleText=ReactOS Boot Manager */
95 IniCacheInsertKey(IniSection
,
99 L
"ReactOS Boot Manager");
101 /* StatusBarColor=Cyan */
102 IniCacheInsertKey(IniSection
,
108 /* StatusBarTextColor=Black */
109 IniCacheInsertKey(IniSection
,
112 L
"StatusBarTextColor",
115 /* BackdropTextColor=White */
116 IniCacheInsertKey(IniSection
,
119 L
"BackdropTextColor",
122 /* BackdropColor=Blue */
123 IniCacheInsertKey(IniSection
,
129 /* BackdropFillStyle=Medium */
130 IniCacheInsertKey(IniSection
,
133 L
"BackdropFillStyle",
136 /* TitleBoxTextColor=White */
137 IniCacheInsertKey(IniSection
,
140 L
"TitleBoxTextColor",
143 /* TitleBoxColor=Red */
144 IniCacheInsertKey(IniSection
,
150 /* MessageBoxTextColor=White */
151 IniCacheInsertKey(IniSection
,
154 L
"MessageBoxTextColor",
157 /* MessageBoxColor=Blue */
158 IniCacheInsertKey(IniSection
,
164 /* MenuTextColor=White */
165 IniCacheInsertKey(IniSection
,
172 IniCacheInsertKey(IniSection
,
178 /* TextColor=Yellow */
179 IniCacheInsertKey(IniSection
,
185 /* SelectedTextColor=Black */
186 IniCacheInsertKey(IniSection
,
189 L
"SelectedTextColor",
192 /* SelectedColor=Gray */
193 IniCacheInsertKey(IniSection
,
199 /* SelectedColor=Gray */
200 IniCacheInsertKey(IniSection
,
206 /* SelectedColor=Gray */
207 IniCacheInsertKey(IniSection
,
213 /* SelectedColor=Gray */
214 IniCacheInsertKey(IniSection
,
220 /* SelectedColor=Gray */
221 IniCacheInsertKey(IniSection
,
227 /* SelectedColor=Gray */
228 IniCacheInsertKey(IniSection
,
232 L
"Seconds until highlighted choice will be started automatically: ");
237 CreateFreeLoaderIniForDos(PWCHAR IniPath
,
241 PINICACHESECTION IniSection
;
243 IniCache
= IniCacheCreate();
245 CreateCommonFreeLoaderSections(IniCache
);
247 /* Create "Operating Systems" section */
248 IniSection
= IniCacheAppendSection(IniCache
,
249 L
"Operating Systems");
251 /* REACTOS=ReactOS */
252 IniCacheInsertKey(IniSection
,
258 /* ReactOS_Debug="ReactOS (Debug)" */
259 IniCacheInsertKey(IniSection
,
263 L
"\"ReactOS (Debug)\"");
265 /* DOS=Dos/Windows */
266 IniCacheInsertKey(IniSection
,
272 /* Create "ReactOS" section */
273 IniSection
= IniCacheAppendSection(IniCache
,
276 /* BootType=ReactOS */
277 IniCacheInsertKey(IniSection
,
283 /* SystemPath=<ArcPath> */
284 IniCacheInsertKey(IniSection
,
290 /* Create "ReactOS_Debug" section */
291 IniSection
= IniCacheAppendSection(IniCache
,
294 /* BootType=ReactOS */
295 IniCacheInsertKey(IniSection
,
301 /* SystemPath=<ArcPath> */
302 IniCacheInsertKey(IniSection
,
308 /* Options=/DEBUGPORT=SCREEN /NOGUIBOOT */
309 IniCacheInsertKey(IniSection
,
313 L
"/DEBUGPORT=SCREEN /NOGUIBOOT");
315 /* Create "DOS" section */
316 IniSection
= IniCacheAppendSection(IniCache
,
319 /* BootType=BootSector */
320 IniCacheInsertKey(IniSection
,
327 IniCacheInsertKey(IniSection
,
333 /* BootPartition=1 */
334 IniCacheInsertKey(IniSection
,
340 /* BootSector=BOOTSECT.DOS */
341 IniCacheInsertKey(IniSection
,
347 IniCacheSave(IniCache
, IniPath
);
348 IniCacheDestroy(IniCache
);
350 return(STATUS_SUCCESS
);
355 CreateFreeLoaderIniForReactos(PWCHAR IniPath
,
359 PINICACHESECTION IniSection
;
361 IniCache
= IniCacheCreate();
363 CreateCommonFreeLoaderSections(IniCache
);
365 /* Create "Operating Systems" section */
366 IniSection
= IniCacheAppendSection(IniCache
,
367 L
"Operating Systems");
369 /* ReactOS="ReactOS" */
370 IniCacheInsertKey(IniSection
,
376 /* ReactOS_Debug="ReactOS (Debug)" */
377 IniCacheInsertKey(IniSection
,
381 L
"\"ReactOS (Debug)\"");
383 /* Create "ReactOS" section */
384 IniSection
= IniCacheAppendSection(IniCache
,
387 /* BootType=ReactOS */
388 IniCacheInsertKey(IniSection
,
394 /* SystemPath=<ArcPath> */
395 IniCacheInsertKey(IniSection
,
401 /* Create "ReactOS_Debug" section */
402 IniSection
= IniCacheAppendSection(IniCache
,
405 /* BootType=ReactOS */
406 IniCacheInsertKey(IniSection
,
412 /* SystemPath=<ArcPath> */
413 IniCacheInsertKey(IniSection
,
419 /* Options=/DEBUGPORT=SCREEN /NOGUIBOOT */
420 IniCacheInsertKey(IniSection
,
424 L
"/DEBUGPORT=COM1 /NOGUIBOOT");
426 /* Save the ini file */
427 IniCacheSave(IniCache
, IniPath
);
428 IniCacheDestroy(IniCache
);
430 return(STATUS_SUCCESS
);
435 UpdateFreeLoaderIni(PWCHAR IniPath
,
440 PINICACHESECTION IniSection
;
441 PINICACHESECTION OsIniSection
;
442 WCHAR SectionName
[80];
444 WCHAR SystemPath
[200];
445 WCHAR SectionName2
[200];
450 RtlInitUnicodeString(&Name
,
453 Status
= IniCacheLoad(&IniCache
,
456 if (!NT_SUCCESS(Status
))
459 /* Get "Operating Systems" section */
460 IniSection
= IniCacheGetSection(IniCache
,
461 L
"Operating Systems");
462 if (IniSection
== NULL
)
464 IniCacheDestroy(IniCache
);
465 return(STATUS_UNSUCCESSFUL
);
468 /* Find an existing usable or an unused section name */
470 wcscpy(SectionName
, L
"ReactOS");
471 wcscpy(OsName
, L
"\"ReactOS\"");
474 Status
= IniCacheGetKey(IniSection
,
477 if (!NT_SUCCESS(Status
))
480 /* Get operation system section */
481 if (KeyData
[0] == '"')
483 wcscpy(SectionName2
, &KeyData
[1]);
484 j
= wcslen(SectionName2
);
487 SectionName2
[j
-1] = 0;
492 wcscpy(SectionName2
, KeyData
);
495 OsIniSection
= IniCacheGetSection(IniCache
,
497 if (OsIniSection
!= NULL
)
499 BOOLEAN UseExistingEntry
= TRUE
;
502 Status
= IniCacheGetKey(OsIniSection
,
505 if (NT_SUCCESS(Status
))
508 || (_wcsicmp(KeyData
, L
"ReactOS") != 0
509 && _wcsicmp(KeyData
, L
"\"ReactOS\"") != 0))
511 /* This is not a ReactOS entry */
512 UseExistingEntry
= FALSE
;
517 UseExistingEntry
= FALSE
;
520 if (UseExistingEntry
)
522 /* BootType is ReactOS. Now check SystemPath */
523 Status
= IniCacheGetKey(OsIniSection
,
526 if (NT_SUCCESS(Status
))
528 swprintf(SystemPath
, L
"\"%S\"", ArcPath
);
530 || (_wcsicmp(KeyData
, ArcPath
) != 0
531 && _wcsicmp(KeyData
, SystemPath
) != 0))
533 /* This entry is a ReactOS entry, but the SystemRoot does not
534 match the one we are looking for */
535 UseExistingEntry
= FALSE
;
540 UseExistingEntry
= FALSE
;
544 if (UseExistingEntry
)
546 IniCacheDestroy(IniCache
);
547 return(STATUS_SUCCESS
);
551 swprintf(SectionName
, L
"ReactOS_%lu", i
);
552 swprintf(OsName
, L
"\"ReactOS %lu\"", i
);
556 /* <SectionName>=<OsName> */
557 IniCacheInsertKey(IniSection
,
563 /* Create <SectionName> section */
564 IniSection
= IniCacheAppendSection(IniCache
,
567 /* BootType=ReactOS */
568 IniCacheInsertKey(IniSection
,
574 /* SystemPath=<ArcPath> */
575 IniCacheInsertKey(IniSection
,
581 IniCacheSave(IniCache
, IniPath
);
582 IniCacheDestroy(IniCache
);
584 return(STATUS_SUCCESS
);
589 SaveCurrentBootSector(PWSTR RootPath
,
592 OBJECT_ATTRIBUTES ObjectAttributes
;
593 IO_STATUS_BLOCK IoStatusBlock
;
599 /* Allocate buffer for bootsector */
600 BootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
603 if (BootSector
== NULL
)
604 return(STATUS_INSUFFICIENT_RESOURCES
);
606 /* Read current boot sector into buffer */
607 RtlInitUnicodeString(&Name
,
610 InitializeObjectAttributes(&ObjectAttributes
,
612 OBJ_CASE_INSENSITIVE
,
616 Status
= NtOpenFile(&FileHandle
,
621 FILE_SYNCHRONOUS_IO_NONALERT
);
622 if (!NT_SUCCESS(Status
))
624 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
628 Status
= NtReadFile(FileHandle
,
638 if (!NT_SUCCESS(Status
))
640 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
644 /* Write bootsector to DstPath */
645 RtlInitUnicodeString(&Name
,
648 InitializeObjectAttributes(&ObjectAttributes
,
654 Status
= NtCreateFile(&FileHandle
,
659 FILE_ATTRIBUTE_NORMAL
,
662 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
,
665 if (!NT_SUCCESS(Status
))
667 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
671 Status
= NtWriteFile(FileHandle
,
682 /* Free the new boot sector */
683 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
690 InstallFat16BootCodeToFile(PWSTR SrcPath
,
694 OBJECT_ATTRIBUTES ObjectAttributes
;
695 IO_STATUS_BLOCK IoStatusBlock
;
699 PUCHAR OrigBootSector
;
700 PUCHAR NewBootSector
;
702 /* Allocate buffer for original bootsector */
703 OrigBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
706 if (OrigBootSector
== NULL
)
707 return(STATUS_INSUFFICIENT_RESOURCES
);
709 /* Read current boot sector into buffer */
710 RtlInitUnicodeString(&Name
,
713 InitializeObjectAttributes(&ObjectAttributes
,
715 OBJ_CASE_INSENSITIVE
,
719 Status
= NtOpenFile(&FileHandle
,
724 FILE_SYNCHRONOUS_IO_NONALERT
);
725 if (!NT_SUCCESS(Status
))
727 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
731 Status
= NtReadFile(FileHandle
,
741 if (!NT_SUCCESS(Status
))
743 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
748 /* Allocate buffer for new bootsector */
749 NewBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
752 if (NewBootSector
== NULL
)
754 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
755 return(STATUS_INSUFFICIENT_RESOURCES
);
758 /* Read new bootsector from SrcPath */
759 RtlInitUnicodeString(&Name
,
762 InitializeObjectAttributes(&ObjectAttributes
,
764 OBJ_CASE_INSENSITIVE
,
768 Status
= NtOpenFile(&FileHandle
,
773 FILE_SYNCHRONOUS_IO_NONALERT
);
774 if (!NT_SUCCESS(Status
))
776 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
777 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
781 Status
= NtReadFile(FileHandle
,
791 if (!NT_SUCCESS(Status
))
793 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
794 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
798 /* Adjust bootsector (copy a part of the FAT BPB) */
799 memcpy((NewBootSector
+ 11), (OrigBootSector
+ 11), 51 /*fat BPB length*/);
801 /* Free the original boot sector */
802 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
804 /* Write new bootsector to DstPath */
805 RtlInitUnicodeString(&Name
,
808 InitializeObjectAttributes(&ObjectAttributes
,
814 Status
= NtCreateFile(&FileHandle
,
819 FILE_ATTRIBUTE_NORMAL
,
822 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
,
825 if (!NT_SUCCESS(Status
))
827 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
832 FilePosition
.QuadPart
= 0;
834 Status
= NtWriteFile(FileHandle
,
845 /* Free the new boot sector */
846 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
853 InstallFat32BootCodeToFile(PWSTR SrcPath
,
857 OBJECT_ATTRIBUTES ObjectAttributes
;
858 IO_STATUS_BLOCK IoStatusBlock
;
862 PUCHAR OrigBootSector
;
863 PUCHAR NewBootSector
;
864 LARGE_INTEGER FileOffset
;
866 /* Allocate buffer for original bootsector */
867 OrigBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
870 if (OrigBootSector
== NULL
)
871 return(STATUS_INSUFFICIENT_RESOURCES
);
873 /* Read current boot sector into buffer */
874 RtlInitUnicodeString(&Name
,
877 InitializeObjectAttributes(&ObjectAttributes
,
879 OBJ_CASE_INSENSITIVE
,
883 Status
= NtOpenFile(&FileHandle
,
888 FILE_SYNCHRONOUS_IO_NONALERT
);
889 if (!NT_SUCCESS(Status
))
891 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
895 Status
= NtReadFile(FileHandle
,
905 if (!NT_SUCCESS(Status
))
908 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
912 /* Allocate buffer for new bootsector (2 sectors) */
913 NewBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
916 if (NewBootSector
== NULL
)
918 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
919 return(STATUS_INSUFFICIENT_RESOURCES
);
922 /* Read new bootsector from SrcPath */
923 RtlInitUnicodeString(&Name
,
926 InitializeObjectAttributes(&ObjectAttributes
,
928 OBJ_CASE_INSENSITIVE
,
932 Status
= NtOpenFile(&FileHandle
,
937 FILE_SYNCHRONOUS_IO_NONALERT
);
938 if (!NT_SUCCESS(Status
))
940 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
941 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
945 Status
= NtReadFile(FileHandle
,
955 if (!NT_SUCCESS(Status
))
957 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
958 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
962 /* Adjust bootsector (copy a part of the FAT32 BPB) */
963 memcpy((NewBootSector
+ 3),
964 (OrigBootSector
+ 3),
965 87); /* FAT32 BPB length */
967 /* Disable the backup boot sector */
968 NewBootSector
[0x32] = 0x00;
969 NewBootSector
[0x33] = 0x00;
971 /* Free the original boot sector */
972 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
974 /* Write the first sector of the new bootcode to DstPath */
975 RtlInitUnicodeString(&Name
,
978 InitializeObjectAttributes(&ObjectAttributes
,
984 Status
= NtCreateFile(&FileHandle
,
989 FILE_ATTRIBUTE_NORMAL
,
992 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
,
995 if (!NT_SUCCESS(Status
))
997 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1001 Status
= NtWriteFile(FileHandle
,
1010 NtClose(FileHandle
);
1011 if (!NT_SUCCESS(Status
))
1013 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1017 /* Write the second sector of the new bootcode to boot disk sector 14 */
1018 RtlInitUnicodeString(&Name
,
1021 InitializeObjectAttributes(&ObjectAttributes
,
1027 Status
= NtOpenFile(&FileHandle
,
1032 FILE_SYNCHRONOUS_IO_NONALERT
);
1033 if (!NT_SUCCESS(Status
))
1035 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1039 FileOffset
.QuadPart
= (ULONGLONG
)(14 * SECTORSIZE
);
1040 Status
= NtWriteFile(FileHandle
,
1045 (NewBootSector
+ SECTORSIZE
),
1049 if (!NT_SUCCESS(Status
))
1052 NtClose(FileHandle
);
1054 /* Free the new boot sector */
1055 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1062 InstallMbrBootCodeToDisk (PWSTR SrcPath
,
1065 OBJECT_ATTRIBUTES ObjectAttributes
;
1066 IO_STATUS_BLOCK IoStatusBlock
;
1067 UNICODE_STRING Name
;
1070 PPARTITION_SECTOR OrigBootSector
;
1071 PPARTITION_SECTOR NewBootSector
;
1073 /* Allocate buffer for original bootsector */
1074 OrigBootSector
= (PPARTITION_SECTOR
)RtlAllocateHeap(ProcessHeap
,
1076 sizeof(PARTITION_SECTOR
));
1077 if (OrigBootSector
== NULL
)
1078 return(STATUS_INSUFFICIENT_RESOURCES
);
1080 /* Read current boot sector into buffer */
1081 RtlInitUnicodeString(&Name
,
1084 InitializeObjectAttributes(&ObjectAttributes
,
1086 OBJ_CASE_INSENSITIVE
,
1090 Status
= NtOpenFile(&FileHandle
,
1095 FILE_SYNCHRONOUS_IO_NONALERT
);
1096 if (!NT_SUCCESS(Status
))
1098 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1102 Status
= NtReadFile(FileHandle
,
1111 NtClose(FileHandle
);
1112 if (!NT_SUCCESS(Status
))
1114 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1119 /* Allocate buffer for new bootsector */
1120 NewBootSector
= (PPARTITION_SECTOR
)RtlAllocateHeap(ProcessHeap
,
1122 sizeof(PARTITION_SECTOR
));
1123 if (NewBootSector
== NULL
)
1125 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1126 return(STATUS_INSUFFICIENT_RESOURCES
);
1129 /* Read new bootsector from SrcPath */
1130 RtlInitUnicodeString(&Name
,
1133 InitializeObjectAttributes(&ObjectAttributes
,
1135 OBJ_CASE_INSENSITIVE
,
1139 Status
= NtOpenFile(&FileHandle
,
1144 FILE_SYNCHRONOUS_IO_NONALERT
);
1145 if (!NT_SUCCESS(Status
))
1147 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1148 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1152 Status
= NtReadFile(FileHandle
,
1158 sizeof(PARTITION_SECTOR
),
1161 NtClose(FileHandle
);
1162 if (!NT_SUCCESS(Status
))
1164 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1165 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1169 /* Copy partition table from old MBR to new */
1170 RtlCopyMemory (&NewBootSector
->Signature
,
1171 &OrigBootSector
->Signature
,
1172 sizeof(PARTITION_SECTOR
) - offsetof(PARTITION_SECTOR
, Signature
) /* Length of partition table */);
1174 /* Free the original boot sector */
1175 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1177 /* Write new bootsector to RootPath */
1178 RtlInitUnicodeString(&Name
,
1181 InitializeObjectAttributes(&ObjectAttributes
,
1187 Status
= NtOpenFile(&FileHandle
,
1192 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1193 if (!NT_SUCCESS(Status
))
1195 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1196 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1200 Status
= NtWriteFile(FileHandle
,
1209 NtClose(FileHandle
);
1211 /* Free the new boot sector */
1212 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1219 InstallFat16BootCodeToDisk(PWSTR SrcPath
,
1222 OBJECT_ATTRIBUTES ObjectAttributes
;
1223 IO_STATUS_BLOCK IoStatusBlock
;
1224 UNICODE_STRING Name
;
1227 PUCHAR OrigBootSector
;
1228 PUCHAR NewBootSector
;
1230 /* Allocate buffer for original bootsector */
1231 OrigBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
1234 if (OrigBootSector
== NULL
)
1235 return(STATUS_INSUFFICIENT_RESOURCES
);
1237 /* Read current boot sector into buffer */
1238 RtlInitUnicodeString(&Name
,
1241 InitializeObjectAttributes(&ObjectAttributes
,
1243 OBJ_CASE_INSENSITIVE
,
1247 Status
= NtOpenFile(&FileHandle
,
1252 FILE_SYNCHRONOUS_IO_NONALERT
);
1253 if (!NT_SUCCESS(Status
))
1255 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1259 Status
= NtReadFile(FileHandle
,
1268 NtClose(FileHandle
);
1269 if (!NT_SUCCESS(Status
))
1271 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1276 /* Allocate buffer for new bootsector */
1277 NewBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
1280 if (NewBootSector
== NULL
)
1282 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1283 return(STATUS_INSUFFICIENT_RESOURCES
);
1286 /* Read new bootsector from SrcPath */
1287 RtlInitUnicodeString(&Name
,
1290 InitializeObjectAttributes(&ObjectAttributes
,
1292 OBJ_CASE_INSENSITIVE
,
1296 Status
= NtOpenFile(&FileHandle
,
1301 FILE_SYNCHRONOUS_IO_NONALERT
);
1302 if (!NT_SUCCESS(Status
))
1304 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1305 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1309 Status
= NtReadFile(FileHandle
,
1318 NtClose(FileHandle
);
1319 if (!NT_SUCCESS(Status
))
1321 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1322 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1326 /* Adjust bootsector (copy a part of the FAT16 BPB) */
1327 memcpy((NewBootSector
+ 3),
1328 (OrigBootSector
+ 3),
1329 59); /* FAT16 BPB length*/
1331 /* Free the original boot sector */
1332 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1334 /* Write new bootsector to RootPath */
1335 RtlInitUnicodeString(&Name
,
1338 InitializeObjectAttributes(&ObjectAttributes
,
1344 Status
= NtOpenFile(&FileHandle
,
1349 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1350 if (!NT_SUCCESS(Status
))
1352 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1353 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1358 FilePosition
.QuadPart
= 0;
1360 Status
= NtWriteFile(FileHandle
,
1369 NtClose(FileHandle
);
1371 /* Free the new boot sector */
1372 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1379 InstallFat32BootCodeToDisk(PWSTR SrcPath
,
1382 OBJECT_ATTRIBUTES ObjectAttributes
;
1383 IO_STATUS_BLOCK IoStatusBlock
;
1384 UNICODE_STRING Name
;
1387 PUCHAR OrigBootSector
;
1388 PUCHAR NewBootSector
;
1389 LARGE_INTEGER FileOffset
;
1390 USHORT BackupBootSector
;
1392 /* Allocate buffer for original bootsector */
1393 OrigBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
1396 if (OrigBootSector
== NULL
)
1397 return(STATUS_INSUFFICIENT_RESOURCES
);
1399 /* Read current boot sector into buffer */
1400 RtlInitUnicodeString(&Name
,
1403 InitializeObjectAttributes(&ObjectAttributes
,
1405 OBJ_CASE_INSENSITIVE
,
1409 Status
= NtOpenFile(&FileHandle
,
1414 FILE_SYNCHRONOUS_IO_NONALERT
);
1415 if (!NT_SUCCESS(Status
))
1417 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1421 Status
= NtReadFile(FileHandle
,
1430 NtClose(FileHandle
);
1431 if (!NT_SUCCESS(Status
))
1433 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1438 /* Allocate buffer for new bootsector (2 sectors) */
1439 NewBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
1442 if (NewBootSector
== NULL
)
1444 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1445 return(STATUS_INSUFFICIENT_RESOURCES
);
1448 /* Read new bootsector from SrcPath */
1449 RtlInitUnicodeString(&Name
,
1452 InitializeObjectAttributes(&ObjectAttributes
,
1454 OBJ_CASE_INSENSITIVE
,
1458 Status
= NtOpenFile(&FileHandle
,
1463 FILE_SYNCHRONOUS_IO_NONALERT
);
1464 if (!NT_SUCCESS(Status
))
1466 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1467 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1471 Status
= NtReadFile(FileHandle
,
1480 NtClose(FileHandle
);
1481 if (!NT_SUCCESS(Status
))
1483 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1484 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1488 /* Adjust bootsector (copy a part of the FAT32 BPB) */
1489 memcpy((NewBootSector
+ 3),
1490 (OrigBootSector
+ 3),
1491 87); /* FAT32 BPB length */
1493 /* Get the location of the backup boot sector */
1494 BackupBootSector
= (OrigBootSector
[0x33] << 8) + OrigBootSector
[0x32];
1496 /* Free the original boot sector */
1497 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1499 /* Write the first sector of the new bootcode to DstPath */
1500 RtlInitUnicodeString(&Name
,
1503 InitializeObjectAttributes(&ObjectAttributes
,
1509 Status
= NtOpenFile(&FileHandle
,
1514 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1515 if (!NT_SUCCESS(Status
))
1517 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1518 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1522 /* Write sector 0 */
1523 FileOffset
.QuadPart
= 0ULL;
1524 Status
= NtWriteFile(FileHandle
,
1533 if (!NT_SUCCESS(Status
))
1535 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1536 NtClose(FileHandle
);
1537 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1541 /* Write backup boot sector */
1542 if ((BackupBootSector
!= 0x0000) && (BackupBootSector
!= 0xFFFF))
1544 FileOffset
.QuadPart
= (ULONGLONG
)((ULONG
)BackupBootSector
* SECTORSIZE
);
1545 Status
= NtWriteFile(FileHandle
,
1554 if (!NT_SUCCESS(Status
))
1556 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1557 NtClose(FileHandle
);
1558 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1563 /* Write sector 14 */
1564 FileOffset
.QuadPart
= (ULONGLONG
)(14 * SECTORSIZE
);
1565 Status
= NtWriteFile(FileHandle
,
1570 (NewBootSector
+ SECTORSIZE
),
1574 if (!NT_SUCCESS(Status
))
1576 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1578 NtClose(FileHandle
);
1580 /* Free the new boot sector */
1581 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1588 UnprotectBootIni(PWSTR FileName
,
1591 UNICODE_STRING Name
;
1592 OBJECT_ATTRIBUTES ObjectAttributes
;
1593 IO_STATUS_BLOCK IoStatusBlock
;
1594 FILE_BASIC_INFORMATION FileInfo
;
1598 RtlInitUnicodeString(&Name
,
1601 InitializeObjectAttributes(&ObjectAttributes
,
1603 OBJ_CASE_INSENSITIVE
,
1607 Status
= NtOpenFile(&FileHandle
,
1608 GENERIC_READ
|GENERIC_WRITE
,
1612 FILE_SYNCHRONOUS_IO_NONALERT
);
1613 if (Status
== STATUS_NO_SUCH_FILE
)
1615 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1617 return(STATUS_SUCCESS
);
1619 if (!NT_SUCCESS(Status
))
1621 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1625 Status
= NtQueryInformationFile(FileHandle
,
1628 sizeof(FILE_BASIC_INFORMATION
),
1629 FileBasicInformation
);
1630 if (!NT_SUCCESS(Status
))
1632 DPRINT1("NtQueryInformationFile() failed (Status %lx)\n", Status
);
1633 NtClose(FileHandle
);
1637 *Attributes
= FileInfo
.FileAttributes
;
1639 /* Delete attributes SYSTEM, HIDDEN and READONLY */
1640 FileInfo
.FileAttributes
= FileInfo
.FileAttributes
&
1641 ~(FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
| FILE_ATTRIBUTE_READONLY
);
1643 Status
= NtSetInformationFile(FileHandle
,
1646 sizeof(FILE_BASIC_INFORMATION
),
1647 FileBasicInformation
);
1648 if (!NT_SUCCESS(Status
))
1650 DPRINT1("NtSetInformationFile() failed (Status %lx)\n", Status
);
1653 NtClose(FileHandle
);
1659 ProtectBootIni(PWSTR FileName
,
1662 UNICODE_STRING Name
;
1663 OBJECT_ATTRIBUTES ObjectAttributes
;
1664 IO_STATUS_BLOCK IoStatusBlock
;
1665 FILE_BASIC_INFORMATION FileInfo
;
1669 RtlInitUnicodeString(&Name
,
1672 InitializeObjectAttributes(&ObjectAttributes
,
1674 OBJ_CASE_INSENSITIVE
,
1678 Status
= NtOpenFile(&FileHandle
,
1679 GENERIC_READ
|GENERIC_WRITE
,
1683 FILE_SYNCHRONOUS_IO_NONALERT
);
1684 if (!NT_SUCCESS(Status
))
1686 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1690 Status
= NtQueryInformationFile(FileHandle
,
1693 sizeof(FILE_BASIC_INFORMATION
),
1694 FileBasicInformation
);
1695 if (!NT_SUCCESS(Status
))
1697 DPRINT1("NtQueryInformationFile() failed (Status %lx)\n", Status
);
1698 NtClose(FileHandle
);
1702 FileInfo
.FileAttributes
= FileInfo
.FileAttributes
| Attributes
;
1704 Status
= NtSetInformationFile(FileHandle
,
1707 sizeof(FILE_BASIC_INFORMATION
),
1708 FileBasicInformation
);
1709 if (!NT_SUCCESS(Status
))
1711 DPRINT1("NtSetInformationFile() failed (Status %lx)\n", Status
);
1714 NtClose(FileHandle
);
1720 UpdateBootIni(PWSTR BootIniPath
,
1724 UNICODE_STRING Name
;
1725 PINICACHE Cache
= NULL
;
1726 PINICACHESECTION Section
= NULL
;
1728 ULONG FileAttribute
;
1729 PWCHAR OldValue
= NULL
;
1731 RtlInitUnicodeString(&Name
,
1734 Status
= IniCacheLoad(&Cache
,
1737 if (!NT_SUCCESS(Status
))
1742 Section
= IniCacheGetSection(Cache
,
1743 L
"operating systems");
1744 if (Section
== NULL
)
1746 IniCacheDestroy(Cache
);
1747 return(STATUS_UNSUCCESSFUL
);
1750 /* Check - maybe record already exists */
1751 Status
= IniCacheGetKey(Section
,
1755 /* If either key was not found, or contains something else - add new one */
1756 if (!NT_SUCCESS(Status
) || wcscmp(OldValue
, EntryValue
))
1758 IniCacheInsertKey(Section
,
1765 Status
= UnprotectBootIni(BootIniPath
,
1767 if (!NT_SUCCESS(Status
))
1769 IniCacheDestroy(Cache
);
1773 Status
= IniCacheSave(Cache
,
1775 if (!NT_SUCCESS(Status
))
1777 IniCacheDestroy(Cache
);
1781 FileAttribute
|= (FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
| FILE_ATTRIBUTE_READONLY
);
1782 Status
= ProtectBootIni(BootIniPath
,
1785 IniCacheDestroy(Cache
);
1791 CheckInstallFatBootcodeToPartition(PUNICODE_STRING SystemRootPath
)
1794 if (DoesFileExist(SystemRootPath
->Buffer
, L
"ntldr") ||
1795 DoesFileExist(SystemRootPath
->Buffer
, L
"boot.ini"))
1799 else if (DoesFileExist(SystemRootPath
->Buffer
, L
"io.sys") ||
1800 DoesFileExist(SystemRootPath
->Buffer
, L
"msdos.sys"))
1811 InstallFatBootcodeToPartition(PUNICODE_STRING SystemRootPath
,
1812 PUNICODE_STRING SourceRootPath
,
1813 PUNICODE_STRING DestinationArcPath
,
1814 UCHAR PartitionType
)
1817 WCHAR SrcPath
[MAX_PATH
];
1818 WCHAR DstPath
[MAX_PATH
];
1821 /* FAT or FAT32 partition */
1822 DPRINT1("System path: '%wZ'\n", SystemRootPath
);
1824 if (DoesFileExist(SystemRootPath
->Buffer
, L
"ntldr") == TRUE
||
1825 DoesFileExist(SystemRootPath
->Buffer
, L
"boot.ini") == TRUE
)
1827 /* Search root directory for 'ntldr' and 'boot.ini'. */
1828 DPRINT("Found Microsoft Windows NT/2000/XP boot loader\n");
1830 /* Copy FreeLoader to the boot partition */
1831 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
1832 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
1833 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1834 wcscat(DstPath
, L
"\\freeldr.sys");
1836 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
1837 Status
= SetupCopyFile(SrcPath
, DstPath
);
1838 if (!NT_SUCCESS(Status
))
1840 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
1844 /* Create or update freeldr.ini */
1845 if (DoesFileExist(SystemRootPath
->Buffer
, L
"freeldr.ini") == FALSE
)
1847 /* Create new 'freeldr.ini' */
1848 DPRINT1("Create new 'freeldr.ini'\n");
1849 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1850 wcscat(DstPath
, L
"\\freeldr.ini");
1852 Status
= CreateFreeLoaderIniForReactos(DstPath
,
1853 DestinationArcPath
->Buffer
);
1854 if (!NT_SUCCESS(Status
))
1856 DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status
);
1860 /* Install new bootcode */
1861 if (PartitionType
== PARTITION_FAT32
||
1862 PartitionType
== PARTITION_FAT32_XINT13
)
1864 /* Install FAT32 bootcode */
1865 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
1866 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
1867 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1868 wcscat(DstPath
, L
"\\bootsect.ros");
1870 DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, DstPath
);
1871 Status
= InstallFat32BootCodeToFile(SrcPath
,
1873 SystemRootPath
->Buffer
);
1874 if (!NT_SUCCESS(Status
))
1876 DPRINT1("InstallFat32BootCodeToFile() failed (Status %lx)\n", Status
);
1882 /* Install FAT16 bootcode */
1883 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
1884 wcscat(SrcPath
, L
"\\loader\\fat.bin");
1885 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1886 wcscat(DstPath
, L
"\\bootsect.ros");
1888 DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath
, DstPath
);
1889 Status
= InstallFat16BootCodeToFile(SrcPath
,
1891 SystemRootPath
->Buffer
);
1892 if (!NT_SUCCESS(Status
))
1894 DPRINT1("InstallFat16BootCodeToFile() failed (Status %lx)\n", Status
);
1901 /* Update existing 'freeldr.ini' */
1902 DPRINT1("Update existing 'freeldr.ini'\n");
1903 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1904 wcscat(DstPath
, L
"\\freeldr.ini");
1906 Status
= UpdateFreeLoaderIni(DstPath
,
1907 DestinationArcPath
->Buffer
);
1908 if (!NT_SUCCESS(Status
))
1910 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
1915 /* Update 'boot.ini' */
1916 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1917 wcscat(DstPath
, L
"\\boot.ini");
1919 DPRINT1("Update 'boot.ini': %S\n", DstPath
);
1920 Status
= UpdateBootIni(DstPath
,
1921 L
"C:\\bootsect.ros",
1923 if (!NT_SUCCESS(Status
))
1925 DPRINT1("UpdateBootIni() failed (Status %lx)\n", Status
);
1929 else if (DoesFileExist(SystemRootPath
->Buffer
, L
"io.sys") == TRUE
||
1930 DoesFileExist(SystemRootPath
->Buffer
, L
"msdos.sys") == TRUE
)
1932 /* Search for root directory for 'io.sys' and 'msdos.sys'. */
1933 DPRINT1("Found Microsoft DOS or Windows 9x boot loader\n");
1935 /* Copy FreeLoader to the boot partition */
1936 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
1937 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
1938 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1939 wcscat(DstPath
, L
"\\freeldr.sys");
1941 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
1942 Status
= SetupCopyFile(SrcPath
, DstPath
);
1943 if (!NT_SUCCESS(Status
))
1945 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
1949 /* Create or update 'freeldr.ini' */
1950 if (DoesFileExist(SystemRootPath
->Buffer
, L
"freeldr.ini") == FALSE
)
1952 /* Create new 'freeldr.ini' */
1953 DPRINT1("Create new 'freeldr.ini'\n");
1954 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1955 wcscat(DstPath
, L
"\\freeldr.ini");
1957 Status
= CreateFreeLoaderIniForDos(DstPath
,
1958 DestinationArcPath
->Buffer
);
1959 if (!NT_SUCCESS(Status
))
1961 DPRINT1("CreateFreeLoaderIniForDos() failed (Status %lx)\n", Status
);
1965 /* Save current bootsector as 'BOOTSECT.DOS' */
1966 wcscpy(SrcPath
, SystemRootPath
->Buffer
);
1967 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1968 wcscat(DstPath
, L
"\\bootsect.dos");
1970 DPRINT1("Save bootsector: %S ==> %S\n", SrcPath
, DstPath
);
1971 Status
= SaveCurrentBootSector(SrcPath
,
1973 if (!NT_SUCCESS(Status
))
1975 DPRINT1("SaveCurrentBootSector() failed (Status %lx)\n", Status
);
1979 /* Install new bootsector */
1980 if (PartitionType
== PARTITION_FAT32
||
1981 PartitionType
== PARTITION_FAT32_XINT13
)
1983 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
1984 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
1986 DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
1987 Status
= InstallFat32BootCodeToDisk(SrcPath
,
1988 SystemRootPath
->Buffer
);
1989 if (!NT_SUCCESS(Status
))
1991 DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)\n", Status
);
1997 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
1998 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2000 DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2001 Status
= InstallFat16BootCodeToDisk(SrcPath
,
2002 SystemRootPath
->Buffer
);
2003 if (!NT_SUCCESS(Status
))
2005 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status
);
2012 /* Update existing 'freeldr.ini' */
2013 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2014 wcscat(DstPath
, L
"\\freeldr.ini");
2016 Status
= UpdateFreeLoaderIni(DstPath
,
2017 DestinationArcPath
->Buffer
);
2018 if (!NT_SUCCESS(Status
))
2020 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
2027 /* No or unknown boot loader */
2028 DPRINT1("No or unknown boot loader found\n");
2030 /* Copy FreeLoader to the boot partition */
2031 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2032 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
2033 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2034 wcscat(DstPath
, L
"\\freeldr.sys");
2036 DPRINT1("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2037 Status
= SetupCopyFile(SrcPath
, DstPath
);
2038 if (!NT_SUCCESS(Status
))
2040 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
2044 /* Create or update 'freeldr.ini' */
2045 if (DoesFileExist(SystemRootPath
->Buffer
, L
"freeldr.ini") == FALSE
)
2047 /* Create new freeldr.ini */
2048 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2049 wcscat(DstPath
, L
"\\freeldr.ini");
2051 DPRINT1("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2052 Status
= CreateFreeLoaderIniForReactos(DstPath
,
2053 DestinationArcPath
->Buffer
);
2054 if (!NT_SUCCESS(Status
))
2056 DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status
);
2060 /* Save current bootsector as 'BOOTSECT.OLD' */
2061 wcscpy(SrcPath
, SystemRootPath
->Buffer
);
2062 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2063 wcscat(DstPath
, L
"\\bootsect.old");
2065 DPRINT1("Save bootsector: %S ==> %S\n", SrcPath
, DstPath
);
2066 Status
= SaveCurrentBootSector(SrcPath
,
2068 if (!NT_SUCCESS(Status
))
2070 DPRINT1("SaveCurrentBootSector() failed (Status %lx)\n", Status
);
2074 /* Install new bootsector */
2075 if (PartitionType
== PARTITION_FAT32
||
2076 PartitionType
== PARTITION_FAT32_XINT13
)
2078 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2079 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
2081 DPRINT("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2082 Status
= InstallFat32BootCodeToDisk(SrcPath
,
2083 SystemRootPath
->Buffer
);
2084 if (!NT_SUCCESS(Status
))
2086 DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)\n", Status
);
2092 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2093 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2095 DPRINT("Install FAT bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2096 Status
= InstallFat16BootCodeToDisk(SrcPath
,
2097 SystemRootPath
->Buffer
);
2098 if (!NT_SUCCESS(Status
))
2100 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status
);
2107 /* Update existing 'freeldr.ini' */
2108 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2109 wcscat(DstPath
, L
"\\freeldr.ini");
2111 Status
= UpdateFreeLoaderIni(DstPath
,
2112 DestinationArcPath
->Buffer
);
2113 if (!NT_SUCCESS(Status
))
2115 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
2121 return STATUS_SUCCESS
;
2123 return STATUS_NOT_IMPLEMENTED
;
2129 InstallFatBootcodeToFloppy(PUNICODE_STRING SourceRootPath
,
2130 PUNICODE_STRING DestinationArcPath
)
2133 WCHAR SrcPath
[MAX_PATH
];
2134 WCHAR DstPath
[MAX_PATH
];
2137 /* Copy FreeLoader to the boot partition */
2138 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2139 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
2141 wcscpy(DstPath
, L
"\\Device\\Floppy0\\freeldr.sys");
2143 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2144 Status
= SetupCopyFile(SrcPath
, DstPath
);
2145 if (!NT_SUCCESS(Status
))
2147 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
2151 /* Create new 'freeldr.ini' */
2152 wcscpy(DstPath
, L
"\\Device\\Floppy0\\freeldr.ini");
2154 DPRINT("Create new 'freeldr.ini'\n");
2155 Status
= CreateFreeLoaderIniForReactos(DstPath
,
2156 DestinationArcPath
->Buffer
);
2157 if (!NT_SUCCESS(Status
))
2159 DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status
);
2163 /* Install FAT12/16 boosector */
2164 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2165 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2167 wcscpy(DstPath
, L
"\\Device\\Floppy0");
2169 DPRINT("Install FAT bootcode: %S ==> %S\n", SrcPath
, DstPath
);
2170 Status
= InstallFat16BootCodeToDisk(SrcPath
,
2172 if (!NT_SUCCESS(Status
))
2174 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status
);
2178 return STATUS_SUCCESS
;
2180 return STATUS_NOT_IMPLEMENTED
;