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
28 #include <ntdll/rtl.h>
38 #define SECTORSIZE 512
40 /* FUNCTIONS ****************************************************************/
44 CreateCommonFreeLoaderSections(PINICACHE IniCache
)
46 PINICACHESECTION IniSection
;
48 /* Create "FREELOADER" section */
49 IniSection
= IniCacheAppendSection(IniCache
,
52 /* DefaultOS=ReactOS */
53 IniCacheInsertKey(IniSection
,
61 IniCacheInsertKey(IniSection
,
68 /* Create "Display" section */
69 IniSection
= IniCacheAppendSection(IniCache
,
72 /* TitleText=ReactOS Boot Manager */
73 IniCacheInsertKey(IniSection
,
77 L
"ReactOS Boot Manager");
79 /* StatusBarColor=Cyan */
80 IniCacheInsertKey(IniSection
,
86 /* StatusBarTextColor=Black */
87 IniCacheInsertKey(IniSection
,
90 L
"StatusBarTextColor",
93 /* BackdropTextColor=White */
94 IniCacheInsertKey(IniSection
,
100 /* BackdropColor=Blue */
101 IniCacheInsertKey(IniSection
,
107 /* BackdropFillStyle=Medium */
108 IniCacheInsertKey(IniSection
,
111 L
"BackdropFillStyle",
114 /* TitleBoxTextColor=White */
115 IniCacheInsertKey(IniSection
,
118 L
"TitleBoxTextColor",
121 /* TitleBoxColor=Red */
122 IniCacheInsertKey(IniSection
,
128 /* MessageBoxTextColor=White */
129 IniCacheInsertKey(IniSection
,
132 L
"MessageBoxTextColor",
135 /* MessageBoxColor=Blue */
136 IniCacheInsertKey(IniSection
,
142 /* MenuTextColor=White */
143 IniCacheInsertKey(IniSection
,
150 IniCacheInsertKey(IniSection
,
156 /* TextColor=Yellow */
157 IniCacheInsertKey(IniSection
,
163 /* SelectedTextColor=Black */
164 IniCacheInsertKey(IniSection
,
167 L
"SelectedTextColor",
170 /* SelectedColor=Gray */
171 IniCacheInsertKey(IniSection
,
180 CreateFreeLoaderIniForDos(PWCHAR IniPath
,
184 PINICACHESECTION IniSection
;
186 IniCache
= IniCacheCreate();
188 CreateCommonFreeLoaderSections(IniCache
);
190 /* Create "Operating Systems" section */
191 IniSection
= IniCacheAppendSection(IniCache
,
192 L
"Operating Systems");
194 /* REACTOS=ReactOS */
195 IniCacheInsertKey(IniSection
,
201 /* ReactOS_Debug="ReactOS (Debug)" */
202 IniCacheInsertKey(IniSection
,
206 L
"\"ReactOS (Debug)\"");
208 /* DOS=Dos/Windows */
209 IniCacheInsertKey(IniSection
,
215 /* Create "ReactOS" section */
216 IniSection
= IniCacheAppendSection(IniCache
,
219 /* BootType=ReactOS */
220 IniCacheInsertKey(IniSection
,
226 /* SystemPath=<ArcPath> */
227 IniCacheInsertKey(IniSection
,
233 /* Create "ReactOS_Debug" section */
234 IniSection
= IniCacheAppendSection(IniCache
,
237 /* BootType=ReactOS */
238 IniCacheInsertKey(IniSection
,
244 /* SystemPath=<ArcPath> */
245 IniCacheInsertKey(IniSection
,
251 /* Options=/DEBUGPORT=SCREEN /NOGUIBOOT */
252 IniCacheInsertKey(IniSection
,
256 L
"/DEBUGPORT=SCREEN /NOGUIBOOT");
258 /* Create "DOS" section */
259 IniSection
= IniCacheAppendSection(IniCache
,
262 /* BootType=BootSector */
263 IniCacheInsertKey(IniSection
,
270 IniCacheInsertKey(IniSection
,
276 /* BootPartition=1 */
277 IniCacheInsertKey(IniSection
,
283 /* BootSector=BOOTSECT.DOS */
284 IniCacheInsertKey(IniSection
,
290 IniCacheSave(IniCache
, IniPath
);
291 IniCacheDestroy(IniCache
);
293 return(STATUS_SUCCESS
);
298 CreateFreeLoaderIniForReactos(PWCHAR IniPath
,
302 PINICACHESECTION IniSection
;
304 IniCache
= IniCacheCreate();
306 CreateCommonFreeLoaderSections(IniCache
);
308 /* Create "Operating Systems" section */
309 IniSection
= IniCacheAppendSection(IniCache
,
310 L
"Operating Systems");
312 /* ReactOS="ReactOS" */
313 IniCacheInsertKey(IniSection
,
319 /* ReactOS_Debug="ReactOS (Debug)" */
320 IniCacheInsertKey(IniSection
,
324 L
"\"ReactOS (Debug)\"");
326 /* Create "ReactOS" section */
327 IniSection
= IniCacheAppendSection(IniCache
,
330 /* BootType=ReactOS */
331 IniCacheInsertKey(IniSection
,
337 /* SystemPath=<ArcPath> */
338 IniCacheInsertKey(IniSection
,
344 /* Create "ReactOS_Debug" section */
345 IniSection
= IniCacheAppendSection(IniCache
,
348 /* BootType=ReactOS */
349 IniCacheInsertKey(IniSection
,
355 /* SystemPath=<ArcPath> */
356 IniCacheInsertKey(IniSection
,
362 /* Options=/DEBUGPORT=SCREEN /NOGUIBOOT */
363 IniCacheInsertKey(IniSection
,
367 L
"/DEBUGPORT=SCREEN /NOGUIBOOT");
369 /* Save the ini file */
370 IniCacheSave(IniCache
, IniPath
);
371 IniCacheDestroy(IniCache
);
373 return(STATUS_SUCCESS
);
378 UpdateFreeLoaderIni(PWCHAR IniPath
,
383 PINICACHESECTION IniSection
;
384 PINICACHESECTION OsIniSection
;
385 WCHAR SectionName
[80];
387 WCHAR SystemPath
[200];
388 WCHAR SectionName2
[200];
393 RtlInitUnicodeString(&Name
,
396 Status
= IniCacheLoad(&IniCache
,
399 if (!NT_SUCCESS(Status
))
402 /* Get "Operating Systems" section */
403 IniSection
= IniCacheGetSection(IniCache
,
404 L
"Operating Systems");
405 if (IniSection
== NULL
)
407 IniCacheDestroy(IniCache
);
408 return(STATUS_UNSUCCESSFUL
);
411 /* Find an existing usable or an unused section name */
413 wcscpy(SectionName
, L
"ReactOS");
414 wcscpy(OsName
, L
"\"ReactOS\"");
417 Status
= IniCacheGetKey(IniSection
,
420 if (!NT_SUCCESS(Status
))
423 /* Get operation system section */
424 if (KeyData
[0] == '"')
426 wcscpy(SectionName2
, &KeyData
[1]);
427 j
= wcslen(SectionName2
);
430 SectionName2
[j
-1] = 0;
435 wcscpy(SectionName2
, KeyData
);
438 OsIniSection
= IniCacheGetSection(IniCache
,
440 if (OsIniSection
!= NULL
)
442 BOOLEAN UseExistingEntry
= TRUE
;
445 Status
= IniCacheGetKey(OsIniSection
,
448 if (NT_SUCCESS(Status
))
451 || (_wcsicmp(KeyData
, L
"ReactOS") != 0
452 && _wcsicmp(KeyData
, L
"\"ReactOS\"") != 0))
454 /* This is not a ReactOS entry */
455 UseExistingEntry
= FALSE
;
460 UseExistingEntry
= FALSE
;
463 if (UseExistingEntry
)
465 /* BootType is ReactOS. Now check SystemPath */
466 Status
= IniCacheGetKey(OsIniSection
,
469 if (NT_SUCCESS(Status
))
471 swprintf(SystemPath
, L
"\"%S\"", ArcPath
);
473 || (_wcsicmp(KeyData
, ArcPath
) != 0
474 && _wcsicmp(KeyData
, SystemPath
) != 0))
476 /* This entry is a ReactOS entry, but the SystemRoot does not
477 match the one we are looking for */
478 UseExistingEntry
= FALSE
;
483 UseExistingEntry
= FALSE
;
487 if (UseExistingEntry
)
489 IniCacheDestroy(IniCache
);
490 return(STATUS_SUCCESS
);
494 swprintf(SectionName
, L
"ReactOS_%lu", i
);
495 swprintf(OsName
, L
"\"ReactOS %lu\"", i
);
499 /* <SectionName>=<OsName> */
500 IniCacheInsertKey(IniSection
,
506 /* Create <SectionName> section */
507 IniSection
= IniCacheAppendSection(IniCache
,
510 /* BootType=ReactOS */
511 IniCacheInsertKey(IniSection
,
517 /* SystemPath=<ArcPath> */
518 IniCacheInsertKey(IniSection
,
524 IniCacheSave(IniCache
, IniPath
);
525 IniCacheDestroy(IniCache
);
527 return(STATUS_SUCCESS
);
532 SaveCurrentBootSector(PWSTR RootPath
,
535 OBJECT_ATTRIBUTES ObjectAttributes
;
536 IO_STATUS_BLOCK IoStatusBlock
;
542 /* Allocate buffer for bootsector */
543 BootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
546 if (BootSector
== NULL
)
547 return(STATUS_INSUFFICIENT_RESOURCES
);
549 /* Read current boot sector into buffer */
550 RtlInitUnicodeString(&Name
,
553 InitializeObjectAttributes(&ObjectAttributes
,
555 OBJ_CASE_INSENSITIVE
,
559 Status
= NtOpenFile(&FileHandle
,
564 FILE_SYNCHRONOUS_IO_NONALERT
);
565 if (!NT_SUCCESS(Status
))
567 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
571 Status
= NtReadFile(FileHandle
,
581 if (!NT_SUCCESS(Status
))
583 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
587 /* Write bootsector to DstPath */
588 RtlInitUnicodeString(&Name
,
591 InitializeObjectAttributes(&ObjectAttributes
,
597 Status
= NtCreateFile(&FileHandle
,
602 FILE_ATTRIBUTE_NORMAL
,
605 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
,
608 if (!NT_SUCCESS(Status
))
610 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
614 Status
= NtWriteFile(FileHandle
,
625 /* Free the new boot sector */
626 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
633 InstallFat16BootCodeToFile(PWSTR SrcPath
,
637 OBJECT_ATTRIBUTES ObjectAttributes
;
638 IO_STATUS_BLOCK IoStatusBlock
;
642 PUCHAR OrigBootSector
;
643 PUCHAR NewBootSector
;
645 /* Allocate buffer for original bootsector */
646 OrigBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
649 if (OrigBootSector
== NULL
)
650 return(STATUS_INSUFFICIENT_RESOURCES
);
652 /* Read current boot sector into buffer */
653 RtlInitUnicodeString(&Name
,
656 InitializeObjectAttributes(&ObjectAttributes
,
658 OBJ_CASE_INSENSITIVE
,
662 Status
= NtOpenFile(&FileHandle
,
667 FILE_SYNCHRONOUS_IO_NONALERT
);
668 if (!NT_SUCCESS(Status
))
670 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
674 Status
= NtReadFile(FileHandle
,
684 if (!NT_SUCCESS(Status
))
686 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
691 /* Allocate buffer for new bootsector */
692 NewBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
695 if (NewBootSector
== NULL
)
697 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
698 return(STATUS_INSUFFICIENT_RESOURCES
);
701 /* Read new bootsector from SrcPath */
702 RtlInitUnicodeString(&Name
,
705 InitializeObjectAttributes(&ObjectAttributes
,
707 OBJ_CASE_INSENSITIVE
,
711 Status
= NtOpenFile(&FileHandle
,
716 FILE_SYNCHRONOUS_IO_NONALERT
);
717 if (!NT_SUCCESS(Status
))
719 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
720 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
724 Status
= NtReadFile(FileHandle
,
734 if (!NT_SUCCESS(Status
))
736 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
737 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
741 /* Adjust bootsector (copy a part of the FAT BPB) */
742 memcpy((NewBootSector
+ 11), (OrigBootSector
+ 11), 51 /*fat BPB length*/);
744 /* Free the original boot sector */
745 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
747 /* Write new bootsector to DstPath */
748 RtlInitUnicodeString(&Name
,
751 InitializeObjectAttributes(&ObjectAttributes
,
757 Status
= NtCreateFile(&FileHandle
,
762 FILE_ATTRIBUTE_NORMAL
,
765 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
,
768 if (!NT_SUCCESS(Status
))
770 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
775 FilePosition
.QuadPart
= 0;
777 Status
= NtWriteFile(FileHandle
,
788 /* Free the new boot sector */
789 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
796 InstallFat32BootCodeToFile(PWSTR SrcPath
,
800 OBJECT_ATTRIBUTES ObjectAttributes
;
801 IO_STATUS_BLOCK IoStatusBlock
;
805 PUCHAR OrigBootSector
;
806 PUCHAR NewBootSector
;
807 LARGE_INTEGER FileOffset
;
809 /* Allocate buffer for original bootsector */
810 OrigBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
813 if (OrigBootSector
== NULL
)
814 return(STATUS_INSUFFICIENT_RESOURCES
);
816 /* Read current boot sector into buffer */
817 RtlInitUnicodeString(&Name
,
820 InitializeObjectAttributes(&ObjectAttributes
,
822 OBJ_CASE_INSENSITIVE
,
826 Status
= NtOpenFile(&FileHandle
,
831 FILE_SYNCHRONOUS_IO_NONALERT
);
832 if (!NT_SUCCESS(Status
))
834 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
838 Status
= NtReadFile(FileHandle
,
848 if (!NT_SUCCESS(Status
))
851 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
855 /* Allocate buffer for new bootsector (2 sectors) */
856 NewBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
859 if (NewBootSector
== NULL
)
861 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
862 return(STATUS_INSUFFICIENT_RESOURCES
);
865 /* Read new bootsector from SrcPath */
866 RtlInitUnicodeString(&Name
,
869 InitializeObjectAttributes(&ObjectAttributes
,
871 OBJ_CASE_INSENSITIVE
,
875 Status
= NtOpenFile(&FileHandle
,
880 FILE_SYNCHRONOUS_IO_NONALERT
);
881 if (!NT_SUCCESS(Status
))
883 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
884 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
888 Status
= NtReadFile(FileHandle
,
898 if (!NT_SUCCESS(Status
))
900 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
901 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
905 /* Adjust bootsector (copy a part of the FAT32 BPB) */
906 memcpy((NewBootSector
+ 3),
907 (OrigBootSector
+ 3),
908 87); /* FAT32 BPB length */
910 /* Disable the backup boot sector */
911 NewBootSector
[0x32] = 0x00;
912 NewBootSector
[0x33] = 0x00;
914 /* Free the original boot sector */
915 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
917 /* Write the first sector of the new bootcode to DstPath */
918 RtlInitUnicodeString(&Name
,
921 InitializeObjectAttributes(&ObjectAttributes
,
927 Status
= NtCreateFile(&FileHandle
,
932 FILE_ATTRIBUTE_NORMAL
,
935 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
,
938 if (!NT_SUCCESS(Status
))
940 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
944 Status
= NtWriteFile(FileHandle
,
954 if (!NT_SUCCESS(Status
))
956 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
960 /* Write the second sector of the new bootcode to boot disk sector 14 */
961 RtlInitUnicodeString(&Name
,
964 InitializeObjectAttributes(&ObjectAttributes
,
970 Status
= NtOpenFile(&FileHandle
,
975 FILE_SYNCHRONOUS_IO_NONALERT
);
976 if (!NT_SUCCESS(Status
))
978 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
982 FileOffset
.QuadPart
= (ULONGLONG
)(14 * SECTORSIZE
);
983 Status
= NtWriteFile(FileHandle
,
988 (NewBootSector
+ SECTORSIZE
),
992 if (!NT_SUCCESS(Status
))
997 /* Free the new boot sector */
998 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1005 InstallMbrBootCodeToDisk (PWSTR SrcPath
,
1008 OBJECT_ATTRIBUTES ObjectAttributes
;
1009 IO_STATUS_BLOCK IoStatusBlock
;
1010 UNICODE_STRING Name
;
1013 PUCHAR OrigBootSector
;
1014 PUCHAR NewBootSector
;
1016 /* Allocate buffer for original bootsector */
1017 OrigBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
1020 if (OrigBootSector
== NULL
)
1021 return(STATUS_INSUFFICIENT_RESOURCES
);
1023 /* Read current boot sector into buffer */
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
);
1045 Status
= NtReadFile(FileHandle
,
1054 NtClose(FileHandle
);
1055 if (!NT_SUCCESS(Status
))
1057 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1062 /* Allocate buffer for new bootsector */
1063 NewBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
1066 if (NewBootSector
== NULL
)
1068 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1069 return(STATUS_INSUFFICIENT_RESOURCES
);
1072 /* Read new bootsector from SrcPath */
1073 RtlInitUnicodeString(&Name
,
1076 InitializeObjectAttributes(&ObjectAttributes
,
1078 OBJ_CASE_INSENSITIVE
,
1082 Status
= NtOpenFile(&FileHandle
,
1087 FILE_SYNCHRONOUS_IO_NONALERT
);
1088 if (!NT_SUCCESS(Status
))
1090 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1091 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1095 Status
= NtReadFile(FileHandle
,
1104 NtClose(FileHandle
);
1105 if (!NT_SUCCESS(Status
))
1107 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1108 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1112 /* Copy partition table from old MBR to new */
1113 RtlCopyMemory ((NewBootSector
+ 446),
1114 (OrigBootSector
+ 446),
1115 4*16 /* Length of partition table */);
1117 /* Free the original boot sector */
1118 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1120 /* Write new bootsector to RootPath */
1121 RtlInitUnicodeString(&Name
,
1124 InitializeObjectAttributes(&ObjectAttributes
,
1130 Status
= NtCreateFile(&FileHandle
,
1135 FILE_ATTRIBUTE_NORMAL
,
1138 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
,
1141 if (!NT_SUCCESS(Status
))
1143 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1147 Status
= NtWriteFile(FileHandle
,
1156 NtClose(FileHandle
);
1158 /* Free the new boot sector */
1159 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1166 InstallFat16BootCodeToDisk(PWSTR SrcPath
,
1169 OBJECT_ATTRIBUTES ObjectAttributes
;
1170 IO_STATUS_BLOCK IoStatusBlock
;
1171 UNICODE_STRING Name
;
1174 PUCHAR OrigBootSector
;
1175 PUCHAR NewBootSector
;
1177 /* Allocate buffer for original bootsector */
1178 OrigBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
1181 if (OrigBootSector
== NULL
)
1182 return(STATUS_INSUFFICIENT_RESOURCES
);
1184 /* Read current boot sector into buffer */
1185 RtlInitUnicodeString(&Name
,
1188 InitializeObjectAttributes(&ObjectAttributes
,
1190 OBJ_CASE_INSENSITIVE
,
1194 Status
= NtOpenFile(&FileHandle
,
1199 FILE_SYNCHRONOUS_IO_NONALERT
);
1200 if (!NT_SUCCESS(Status
))
1202 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1206 Status
= NtReadFile(FileHandle
,
1215 NtClose(FileHandle
);
1216 if (!NT_SUCCESS(Status
))
1218 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1223 /* Allocate buffer for new bootsector */
1224 NewBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
1227 if (NewBootSector
== NULL
)
1229 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1230 return(STATUS_INSUFFICIENT_RESOURCES
);
1233 /* Read new bootsector from SrcPath */
1234 RtlInitUnicodeString(&Name
,
1237 InitializeObjectAttributes(&ObjectAttributes
,
1239 OBJ_CASE_INSENSITIVE
,
1243 Status
= NtOpenFile(&FileHandle
,
1248 FILE_SYNCHRONOUS_IO_NONALERT
);
1249 if (!NT_SUCCESS(Status
))
1251 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1252 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1256 Status
= NtReadFile(FileHandle
,
1265 NtClose(FileHandle
);
1266 if (!NT_SUCCESS(Status
))
1268 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1269 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1273 /* Adjust bootsector (copy a part of the FAT16 BPB) */
1274 memcpy((NewBootSector
+ 3),
1275 (OrigBootSector
+ 3),
1276 59); /* FAT16 BPB length*/
1278 /* Free the original boot sector */
1279 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1281 /* Write new bootsector to RootPath */
1282 RtlInitUnicodeString(&Name
,
1285 InitializeObjectAttributes(&ObjectAttributes
,
1291 Status
= NtCreateFile(&FileHandle
,
1296 FILE_ATTRIBUTE_NORMAL
,
1299 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
,
1302 if (!NT_SUCCESS(Status
))
1304 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1309 FilePosition
.QuadPart
= 0;
1311 Status
= NtWriteFile(FileHandle
,
1320 NtClose(FileHandle
);
1322 /* Free the new boot sector */
1323 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1330 InstallFat32BootCodeToDisk(PWSTR SrcPath
,
1333 OBJECT_ATTRIBUTES ObjectAttributes
;
1334 IO_STATUS_BLOCK IoStatusBlock
;
1335 UNICODE_STRING Name
;
1338 PUCHAR OrigBootSector
;
1339 PUCHAR NewBootSector
;
1340 LARGE_INTEGER FileOffset
;
1341 USHORT BackupBootSector
;
1343 /* Allocate buffer for original bootsector */
1344 OrigBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
1347 if (OrigBootSector
== NULL
)
1348 return(STATUS_INSUFFICIENT_RESOURCES
);
1350 /* Read current boot sector into buffer */
1351 RtlInitUnicodeString(&Name
,
1354 InitializeObjectAttributes(&ObjectAttributes
,
1356 OBJ_CASE_INSENSITIVE
,
1360 Status
= NtOpenFile(&FileHandle
,
1365 FILE_SYNCHRONOUS_IO_NONALERT
);
1366 if (!NT_SUCCESS(Status
))
1368 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1372 Status
= NtReadFile(FileHandle
,
1381 NtClose(FileHandle
);
1382 if (!NT_SUCCESS(Status
))
1384 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1389 /* Allocate buffer for new bootsector (2 sectors) */
1390 NewBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
1393 if (NewBootSector
== NULL
)
1395 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1396 return(STATUS_INSUFFICIENT_RESOURCES
);
1399 /* Read new bootsector from SrcPath */
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
);
1418 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1422 Status
= NtReadFile(FileHandle
,
1431 NtClose(FileHandle
);
1432 if (!NT_SUCCESS(Status
))
1434 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1435 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1439 /* Adjust bootsector (copy a part of the FAT32 BPB) */
1440 memcpy((NewBootSector
+ 3),
1441 (OrigBootSector
+ 3),
1442 87); /* FAT32 BPB length */
1444 /* Get the location of the backup boot sector */
1445 BackupBootSector
= (OrigBootSector
[0x33] << 8) + OrigBootSector
[0x32];
1447 /* Free the original boot sector */
1448 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1450 /* Write the first sector of the new bootcode to DstPath */
1451 RtlInitUnicodeString(&Name
,
1454 InitializeObjectAttributes(&ObjectAttributes
,
1460 Status
= NtOpenFile(&FileHandle
,
1461 FILE_WRITE_ACCESS
| FILE_WRITE_ATTRIBUTES
,
1465 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1466 if (!NT_SUCCESS(Status
))
1468 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1469 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1473 /* Write sector 0 */
1474 FileOffset
.QuadPart
= 0ULL;
1475 Status
= NtWriteFile(FileHandle
,
1484 if (!NT_SUCCESS(Status
))
1486 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1487 NtClose(FileHandle
);
1488 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1492 /* Write backup boot sector */
1493 if ((BackupBootSector
!= 0x0000) && (BackupBootSector
!= 0xFFFF))
1495 FileOffset
.QuadPart
= (ULONGLONG
)((ULONG
)BackupBootSector
* SECTORSIZE
);
1496 Status
= NtWriteFile(FileHandle
,
1505 if (!NT_SUCCESS(Status
))
1507 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1508 NtClose(FileHandle
);
1509 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1514 /* Write sector 14 */
1515 FileOffset
.QuadPart
= (ULONGLONG
)(14 * SECTORSIZE
);
1516 Status
= NtWriteFile(FileHandle
,
1521 (NewBootSector
+ SECTORSIZE
),
1525 if (!NT_SUCCESS(Status
))
1527 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1529 NtClose(FileHandle
);
1531 /* Free the new boot sector */
1532 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1539 UnprotectBootIni(PWSTR FileName
,
1542 UNICODE_STRING Name
;
1543 OBJECT_ATTRIBUTES ObjectAttributes
;
1544 IO_STATUS_BLOCK IoStatusBlock
;
1545 FILE_BASIC_INFORMATION FileInfo
;
1549 RtlInitUnicodeString(&Name
,
1552 InitializeObjectAttributes(&ObjectAttributes
,
1554 OBJ_CASE_INSENSITIVE
,
1558 Status
= NtOpenFile(&FileHandle
,
1559 FILE_READ_ATTRIBUTES
| FILE_WRITE_ATTRIBUTES
,
1563 FILE_SYNCHRONOUS_IO_NONALERT
);
1564 if (Status
== STATUS_NO_SUCH_FILE
)
1566 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1568 return(STATUS_SUCCESS
);
1570 if (!NT_SUCCESS(Status
))
1572 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1576 Status
= NtQueryInformationFile(FileHandle
,
1579 sizeof(FILE_BASIC_INFORMATION
),
1580 FileBasicInformation
);
1581 if (!NT_SUCCESS(Status
))
1583 DPRINT1("NtQueryInformationFile() failed (Status %lx)\n", Status
);
1584 NtClose(FileHandle
);
1588 *Attributes
= FileInfo
.FileAttributes
;
1590 /* Delete attributes SYSTEM, HIDDEN and READONLY */
1591 FileInfo
.FileAttributes
= FileInfo
.FileAttributes
&
1592 ~(FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
| FILE_ATTRIBUTE_READONLY
);
1594 Status
= NtSetInformationFile(FileHandle
,
1597 sizeof(FILE_BASIC_INFORMATION
),
1598 FileBasicInformation
);
1599 if (!NT_SUCCESS(Status
))
1601 DPRINT1("NtSetInformationFile() failed (Status %lx)\n", Status
);
1604 NtClose(FileHandle
);
1610 ProtectBootIni(PWSTR FileName
,
1613 UNICODE_STRING Name
;
1614 OBJECT_ATTRIBUTES ObjectAttributes
;
1615 IO_STATUS_BLOCK IoStatusBlock
;
1616 FILE_BASIC_INFORMATION FileInfo
;
1620 RtlInitUnicodeString(&Name
,
1623 InitializeObjectAttributes(&ObjectAttributes
,
1625 OBJ_CASE_INSENSITIVE
,
1629 Status
= NtOpenFile(&FileHandle
,
1630 FILE_READ_ATTRIBUTES
| FILE_WRITE_ATTRIBUTES
,
1634 FILE_SYNCHRONOUS_IO_NONALERT
);
1635 if (!NT_SUCCESS(Status
))
1637 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1641 Status
= NtQueryInformationFile(FileHandle
,
1644 sizeof(FILE_BASIC_INFORMATION
),
1645 FileBasicInformation
);
1646 if (!NT_SUCCESS(Status
))
1648 DPRINT1("NtQueryInformationFile() failed (Status %lx)\n", Status
);
1649 NtClose(FileHandle
);
1653 FileInfo
.FileAttributes
= FileInfo
.FileAttributes
| Attributes
;
1655 Status
= NtSetInformationFile(FileHandle
,
1658 sizeof(FILE_BASIC_INFORMATION
),
1659 FileBasicInformation
);
1660 if (!NT_SUCCESS(Status
))
1662 DPRINT1("NtSetInformationFile() failed (Status %lx)\n", Status
);
1665 NtClose(FileHandle
);
1671 UpdateBootIni(PWSTR BootIniPath
,
1675 UNICODE_STRING Name
;
1676 PINICACHE Cache
= NULL
;
1677 PINICACHESECTION Section
= NULL
;
1679 ULONG FileAttribute
;
1681 RtlInitUnicodeString(&Name
,
1684 Status
= IniCacheLoad(&Cache
,
1687 if (!NT_SUCCESS(Status
))
1692 Section
= IniCacheGetSection(Cache
,
1693 L
"operating systems");
1694 if (Section
== NULL
)
1696 IniCacheDestroy(Cache
);
1697 return(STATUS_UNSUCCESSFUL
);
1700 IniCacheInsertKey(Section
,
1706 Status
= UnprotectBootIni(BootIniPath
,
1708 if (!NT_SUCCESS(Status
))
1710 IniCacheDestroy(Cache
);
1714 Status
= IniCacheSave(Cache
,
1716 if (!NT_SUCCESS(Status
))
1718 IniCacheDestroy(Cache
);
1722 FileAttribute
|= (FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
| FILE_ATTRIBUTE_READONLY
);
1723 Status
= ProtectBootIni(BootIniPath
,
1726 IniCacheDestroy(Cache
);
1733 CheckInstallFatBootcodeToPartition(PUNICODE_STRING SystemRootPath
)
1735 if (DoesFileExist(SystemRootPath
->Buffer
, L
"ntldr") ||
1736 DoesFileExist(SystemRootPath
->Buffer
, L
"boot.ini"))
1740 else if (DoesFileExist(SystemRootPath
->Buffer
, L
"io.sys") ||
1741 DoesFileExist(SystemRootPath
->Buffer
, L
"msdos.sys"))
1751 InstallFatBootcodeToPartition(PUNICODE_STRING SystemRootPath
,
1752 PUNICODE_STRING SourceRootPath
,
1753 PUNICODE_STRING DestinationArcPath
,
1754 UCHAR PartitionType
)
1756 WCHAR SrcPath
[MAX_PATH
];
1757 WCHAR DstPath
[MAX_PATH
];
1760 /* FAT or FAT32 partition */
1761 DPRINT1("System path: '%wZ'\n", SystemRootPath
);
1763 if (DoesFileExist(SystemRootPath
->Buffer
, L
"ntldr") == TRUE
||
1764 DoesFileExist(SystemRootPath
->Buffer
, L
"boot.ini") == TRUE
)
1766 /* Search root directory for 'ntldr' and 'boot.ini'. */
1767 DPRINT("Found Microsoft Windows NT/2000/XP boot loader\n");
1769 /* Copy FreeLoader to the boot partition */
1770 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
1771 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
1772 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1773 wcscat(DstPath
, L
"\\freeldr.sys");
1775 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
1776 Status
= SetupCopyFile(SrcPath
, DstPath
);
1777 if (!NT_SUCCESS(Status
))
1779 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
1783 /* Create or update freeldr.ini */
1784 if (DoesFileExist(SystemRootPath
->Buffer
, L
"freeldr.ini") == FALSE
)
1786 /* Create new 'freeldr.ini' */
1787 DPRINT1("Create new 'freeldr.ini'\n");
1788 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1789 wcscat(DstPath
, L
"\\freeldr.ini");
1791 Status
= CreateFreeLoaderIniForReactos(DstPath
,
1792 DestinationArcPath
->Buffer
);
1793 if (!NT_SUCCESS(Status
))
1795 DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status
);
1799 /* Install new bootcode */
1800 if (PartitionType
== PARTITION_FAT32
||
1801 PartitionType
== PARTITION_FAT32_XINT13
)
1803 /* Install FAT32 bootcode */
1804 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
1805 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
1806 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1807 wcscat(DstPath
, L
"\\bootsect.ros");
1809 DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, DstPath
);
1810 Status
= InstallFat32BootCodeToFile(SrcPath
,
1812 SystemRootPath
->Buffer
);
1813 if (!NT_SUCCESS(Status
))
1815 DPRINT1("InstallFat32BootCodeToFile() failed (Status %lx)\n", Status
);
1821 /* Install FAT16 bootcode */
1822 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
1823 wcscat(SrcPath
, L
"\\loader\\fat.bin");
1824 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1825 wcscat(DstPath
, L
"\\bootsect.ros");
1827 DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath
, DstPath
);
1828 Status
= InstallFat16BootCodeToFile(SrcPath
,
1830 SystemRootPath
->Buffer
);
1831 if (!NT_SUCCESS(Status
))
1833 DPRINT1("InstallFat16BootCodeToFile() failed (Status %lx)\n", Status
);
1838 /* Update 'boot.ini' */
1839 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1840 wcscat(DstPath
, L
"\\boot.ini");
1842 DPRINT1("Update 'boot.ini': %S\n", DstPath
);
1843 Status
= UpdateBootIni(DstPath
,
1844 L
"C:\\bootsect.ros",
1846 if (!NT_SUCCESS(Status
))
1848 DPRINT1("UpdateBootIni() failed (Status %lx)\n", Status
);
1854 /* Update existing 'freeldr.ini' */
1855 DPRINT1("Update existing 'freeldr.ini'\n");
1856 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1857 wcscat(DstPath
, L
"\\freeldr.ini");
1859 Status
= UpdateFreeLoaderIni(DstPath
,
1860 DestinationArcPath
->Buffer
);
1861 if (!NT_SUCCESS(Status
))
1863 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
1868 else if (DoesFileExist(SystemRootPath
->Buffer
, L
"io.sys") == TRUE
||
1869 DoesFileExist(SystemRootPath
->Buffer
, L
"msdos.sys") == TRUE
)
1871 /* Search for root directory for 'io.sys' and 'msdos.sys'. */
1872 DPRINT1("Found Microsoft DOS or Windows 9x boot loader\n");
1874 /* Copy FreeLoader to the boot partition */
1875 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
1876 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
1877 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1878 wcscat(DstPath
, L
"\\freeldr.sys");
1880 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
1881 Status
= SetupCopyFile(SrcPath
, DstPath
);
1882 if (!NT_SUCCESS(Status
))
1884 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
1888 /* Create or update 'freeldr.ini' */
1889 if (DoesFileExist(SystemRootPath
->Buffer
, L
"freeldr.ini") == FALSE
)
1891 /* Create new 'freeldr.ini' */
1892 DPRINT1("Create new 'freeldr.ini'\n");
1893 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1894 wcscat(DstPath
, L
"\\freeldr.ini");
1896 Status
= CreateFreeLoaderIniForDos(DstPath
,
1897 DestinationArcPath
->Buffer
);
1898 if (!NT_SUCCESS(Status
))
1900 DPRINT1("CreateFreeLoaderIniForDos() failed (Status %lx)\n", Status
);
1904 /* Save current bootsector as 'BOOTSECT.DOS' */
1905 wcscpy(SrcPath
, SystemRootPath
->Buffer
);
1906 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1907 wcscat(DstPath
, L
"\\bootsect.dos");
1909 DPRINT1("Save bootsector: %S ==> %S\n", SrcPath
, DstPath
);
1910 Status
= SaveCurrentBootSector(SrcPath
,
1912 if (!NT_SUCCESS(Status
))
1914 DPRINT1("SaveCurrentBootSector() failed (Status %lx)\n", Status
);
1918 /* Install new bootsector */
1919 if (PartitionType
== PARTITION_FAT32
||
1920 PartitionType
== PARTITION_FAT32_XINT13
)
1922 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
1923 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
1925 DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
1926 Status
= InstallFat32BootCodeToDisk(SrcPath
,
1927 SystemRootPath
->Buffer
);
1928 if (!NT_SUCCESS(Status
))
1930 DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)\n", Status
);
1936 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
1937 wcscat(SrcPath
, L
"\\loader\\fat.bin");
1939 DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
1940 Status
= InstallFat16BootCodeToDisk(SrcPath
,
1941 SystemRootPath
->Buffer
);
1942 if (!NT_SUCCESS(Status
))
1944 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status
);
1951 /* Update existing 'freeldr.ini' */
1952 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1953 wcscat(DstPath
, L
"\\freeldr.ini");
1955 Status
= UpdateFreeLoaderIni(DstPath
,
1956 DestinationArcPath
->Buffer
);
1957 if (!NT_SUCCESS(Status
))
1959 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
1966 /* No or unknown boot loader */
1967 DPRINT1("No or unknown boot loader found\n");
1969 /* Copy FreeLoader to the boot partition */
1970 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
1971 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
1972 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1973 wcscat(DstPath
, L
"\\freeldr.sys");
1975 DPRINT1("Copy: %S ==> %S\n", SrcPath
, DstPath
);
1976 Status
= SetupCopyFile(SrcPath
, DstPath
);
1977 if (!NT_SUCCESS(Status
))
1979 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
1983 /* Create or update 'freeldr.ini' */
1984 if (DoesFileExist(SystemRootPath
->Buffer
, L
"freeldr.ini") == FALSE
)
1986 /* Create new freeldr.ini */
1987 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1988 wcscat(DstPath
, L
"\\freeldr.ini");
1990 DPRINT1("Copy: %S ==> %S\n", SrcPath
, DstPath
);
1991 Status
= CreateFreeLoaderIniForReactos(DstPath
,
1992 DestinationArcPath
->Buffer
);
1993 if (!NT_SUCCESS(Status
))
1995 DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status
);
1999 /* Save current bootsector as 'BOOTSECT.OLD' */
2000 wcscpy(SrcPath
, SystemRootPath
->Buffer
);
2001 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2002 wcscat(DstPath
, L
"\\bootsect.old");
2004 DPRINT1("Save bootsector: %S ==> %S\n", SrcPath
, DstPath
);
2005 Status
= SaveCurrentBootSector(SrcPath
,
2007 if (!NT_SUCCESS(Status
))
2009 DPRINT1("SaveCurrentBootSector() failed (Status %lx)\n", Status
);
2013 /* Install new bootsector */
2014 if (PartitionType
== PARTITION_FAT32
||
2015 PartitionType
== PARTITION_FAT32_XINT13
)
2017 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2018 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
2020 DPRINT("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2021 Status
= InstallFat32BootCodeToDisk(SrcPath
,
2022 SystemRootPath
->Buffer
);
2023 if (!NT_SUCCESS(Status
))
2025 DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)\n", Status
);
2031 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2032 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2034 DPRINT("Install FAT bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2035 Status
= InstallFat16BootCodeToDisk(SrcPath
,
2036 SystemRootPath
->Buffer
);
2037 if (!NT_SUCCESS(Status
))
2039 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status
);
2046 /* Update existing 'freeldr.ini' */
2047 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2048 wcscat(DstPath
, L
"\\freeldr.ini");
2050 Status
= UpdateFreeLoaderIni(DstPath
,
2051 DestinationArcPath
->Buffer
);
2052 if (!NT_SUCCESS(Status
))
2054 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
2060 return STATUS_SUCCESS
;
2065 InstallFatBootcodeToFloppy(PUNICODE_STRING SourceRootPath
,
2066 PUNICODE_STRING DestinationArcPath
)
2068 WCHAR SrcPath
[MAX_PATH
];
2069 WCHAR DstPath
[MAX_PATH
];
2072 /* Copy FreeLoader to the boot partition */
2073 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2074 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
2076 wcscat(DstPath
, L
"\\Device\\Floppy0\\freeldr.sys");
2078 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2079 Status
= SetupCopyFile(SrcPath
, DstPath
);
2080 if (!NT_SUCCESS(Status
))
2082 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
2086 /* Create new 'freeldr.ini' */
2087 wcscat(DstPath
, L
"\\Device\\Floppy0\\freeldr.ini");
2089 DPRINT("Create new 'freeldr.ini'\n");
2090 Status
= CreateFreeLoaderIniForReactos(DstPath
,
2091 DestinationArcPath
->Buffer
);
2092 if (!NT_SUCCESS(Status
))
2094 DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status
);
2098 /* Install FAT12/16 boosector */
2099 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2100 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2102 wcscat(DstPath
, L
"\\Device\\Floppy0");
2104 DPRINT("Install FAT bootcode: %S ==> %S\n", SrcPath
, DstPath
);
2105 Status
= InstallFat16BootCodeToDisk(SrcPath
,
2107 if (!NT_SUCCESS(Status
))
2109 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status
);
2113 return STATUS_SUCCESS
;