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
,
46 /* DefaultOS=ReactOS */
47 IniCacheInsertKey(IniSection
,
55 IniCacheInsertKey(IniSection
,
62 /* Create "Display" section */
63 IniSection
= IniCacheAppendSection(IniCache
,
66 /* TitleText=ReactOS Boot Manager */
67 IniCacheInsertKey(IniSection
,
71 L
"ReactOS Boot Manager");
73 /* StatusBarColor=Cyan */
74 IniCacheInsertKey(IniSection
,
80 /* StatusBarTextColor=Black */
81 IniCacheInsertKey(IniSection
,
84 L
"StatusBarTextColor",
87 /* BackdropTextColor=White */
88 IniCacheInsertKey(IniSection
,
94 /* BackdropColor=Blue */
95 IniCacheInsertKey(IniSection
,
101 /* BackdropFillStyle=Medium */
102 IniCacheInsertKey(IniSection
,
105 L
"BackdropFillStyle",
108 /* TitleBoxTextColor=White */
109 IniCacheInsertKey(IniSection
,
112 L
"TitleBoxTextColor",
115 /* TitleBoxColor=Red */
116 IniCacheInsertKey(IniSection
,
122 /* MessageBoxTextColor=White */
123 IniCacheInsertKey(IniSection
,
126 L
"MessageBoxTextColor",
129 /* MessageBoxColor=Blue */
130 IniCacheInsertKey(IniSection
,
136 /* MenuTextColor=White */
137 IniCacheInsertKey(IniSection
,
144 IniCacheInsertKey(IniSection
,
150 /* TextColor=Yellow */
151 IniCacheInsertKey(IniSection
,
157 /* SelectedTextColor=Black */
158 IniCacheInsertKey(IniSection
,
161 L
"SelectedTextColor",
164 /* SelectedColor=Gray */
165 IniCacheInsertKey(IniSection
,
172 IniCacheInsertKey(IniSection
,
181 CreateFreeLoaderIniForDos(PWCHAR IniPath
,
185 PINICACHESECTION IniSection
;
187 IniCache
= IniCacheCreate();
189 CreateCommonFreeLoaderSections(IniCache
);
191 /* Create "Operating Systems" section */
192 IniSection
= IniCacheAppendSection(IniCache
,
193 L
"Operating Systems");
195 /* REACTOS=ReactOS */
196 IniCacheInsertKey(IniSection
,
202 /* ReactOS_Debug="ReactOS (Debug)" */
203 IniCacheInsertKey(IniSection
,
207 L
"\"ReactOS (Debug)\"");
209 /* DOS=Dos/Windows */
210 IniCacheInsertKey(IniSection
,
216 /* Create "ReactOS" section */
217 IniSection
= IniCacheAppendSection(IniCache
,
220 /* BootType=ReactOS */
221 IniCacheInsertKey(IniSection
,
227 /* SystemPath=<ArcPath> */
228 IniCacheInsertKey(IniSection
,
234 /* Create "ReactOS_Debug" section */
235 IniSection
= IniCacheAppendSection(IniCache
,
238 /* BootType=ReactOS */
239 IniCacheInsertKey(IniSection
,
245 /* SystemPath=<ArcPath> */
246 IniCacheInsertKey(IniSection
,
252 /* Options=/DEBUGPORT=SCREEN /NOGUIBOOT */
253 IniCacheInsertKey(IniSection
,
257 L
"/DEBUGPORT=SCREEN /NOGUIBOOT");
259 /* Create "DOS" section */
260 IniSection
= IniCacheAppendSection(IniCache
,
263 /* BootType=BootSector */
264 IniCacheInsertKey(IniSection
,
271 IniCacheInsertKey(IniSection
,
277 /* BootPartition=1 */
278 IniCacheInsertKey(IniSection
,
284 /* BootSector=BOOTSECT.DOS */
285 IniCacheInsertKey(IniSection
,
291 IniCacheSave(IniCache
, IniPath
);
292 IniCacheDestroy(IniCache
);
294 return(STATUS_SUCCESS
);
299 CreateFreeLoaderIniForReactos(PWCHAR IniPath
,
303 PINICACHESECTION IniSection
;
305 IniCache
= IniCacheCreate();
307 CreateCommonFreeLoaderSections(IniCache
);
309 /* Create "Operating Systems" section */
310 IniSection
= IniCacheAppendSection(IniCache
,
311 L
"Operating Systems");
313 /* ReactOS="ReactOS" */
314 IniCacheInsertKey(IniSection
,
320 /* ReactOS_Debug="ReactOS (Debug)" */
321 IniCacheInsertKey(IniSection
,
325 L
"\"ReactOS (Debug)\"");
327 /* Create "ReactOS" section */
328 IniSection
= IniCacheAppendSection(IniCache
,
331 /* BootType=ReactOS */
332 IniCacheInsertKey(IniSection
,
338 /* SystemPath=<ArcPath> */
339 IniCacheInsertKey(IniSection
,
345 /* Create "ReactOS_Debug" section */
346 IniSection
= IniCacheAppendSection(IniCache
,
349 /* BootType=ReactOS */
350 IniCacheInsertKey(IniSection
,
356 /* SystemPath=<ArcPath> */
357 IniCacheInsertKey(IniSection
,
363 /* Options=/DEBUGPORT=SCREEN /NOGUIBOOT */
364 IniCacheInsertKey(IniSection
,
368 L
"/DEBUGPORT=SCREEN /NOGUIBOOT");
370 /* Save the ini file */
371 IniCacheSave(IniCache
, IniPath
);
372 IniCacheDestroy(IniCache
);
374 return(STATUS_SUCCESS
);
379 UpdateFreeLoaderIni(PWCHAR IniPath
,
384 PINICACHESECTION IniSection
;
385 PINICACHESECTION OsIniSection
;
386 WCHAR SectionName
[80];
388 WCHAR SystemPath
[200];
389 WCHAR SectionName2
[200];
394 RtlInitUnicodeString(&Name
,
397 Status
= IniCacheLoad(&IniCache
,
400 if (!NT_SUCCESS(Status
))
403 /* Get "Operating Systems" section */
404 IniSection
= IniCacheGetSection(IniCache
,
405 L
"Operating Systems");
406 if (IniSection
== NULL
)
408 IniCacheDestroy(IniCache
);
409 return(STATUS_UNSUCCESSFUL
);
412 /* Find an existing usable or an unused section name */
414 wcscpy(SectionName
, L
"ReactOS");
415 wcscpy(OsName
, L
"\"ReactOS\"");
418 Status
= IniCacheGetKey(IniSection
,
421 if (!NT_SUCCESS(Status
))
424 /* Get operation system section */
425 if (KeyData
[0] == '"')
427 wcscpy(SectionName2
, &KeyData
[1]);
428 j
= wcslen(SectionName2
);
431 SectionName2
[j
-1] = 0;
436 wcscpy(SectionName2
, KeyData
);
439 OsIniSection
= IniCacheGetSection(IniCache
,
441 if (OsIniSection
!= NULL
)
443 BOOLEAN UseExistingEntry
= TRUE
;
446 Status
= IniCacheGetKey(OsIniSection
,
449 if (NT_SUCCESS(Status
))
452 || (_wcsicmp(KeyData
, L
"ReactOS") != 0
453 && _wcsicmp(KeyData
, L
"\"ReactOS\"") != 0))
455 /* This is not a ReactOS entry */
456 UseExistingEntry
= FALSE
;
461 UseExistingEntry
= FALSE
;
464 if (UseExistingEntry
)
466 /* BootType is ReactOS. Now check SystemPath */
467 Status
= IniCacheGetKey(OsIniSection
,
470 if (NT_SUCCESS(Status
))
472 swprintf(SystemPath
, L
"\"%S\"", ArcPath
);
474 || (_wcsicmp(KeyData
, ArcPath
) != 0
475 && _wcsicmp(KeyData
, SystemPath
) != 0))
477 /* This entry is a ReactOS entry, but the SystemRoot does not
478 match the one we are looking for */
479 UseExistingEntry
= FALSE
;
484 UseExistingEntry
= FALSE
;
488 if (UseExistingEntry
)
490 IniCacheDestroy(IniCache
);
491 return(STATUS_SUCCESS
);
495 swprintf(SectionName
, L
"ReactOS_%lu", i
);
496 swprintf(OsName
, L
"\"ReactOS %lu\"", i
);
500 /* <SectionName>=<OsName> */
501 IniCacheInsertKey(IniSection
,
507 /* Create <SectionName> section */
508 IniSection
= IniCacheAppendSection(IniCache
,
511 /* BootType=ReactOS */
512 IniCacheInsertKey(IniSection
,
518 /* SystemPath=<ArcPath> */
519 IniCacheInsertKey(IniSection
,
525 IniCacheSave(IniCache
, IniPath
);
526 IniCacheDestroy(IniCache
);
528 return(STATUS_SUCCESS
);
533 SaveCurrentBootSector(PWSTR RootPath
,
536 OBJECT_ATTRIBUTES ObjectAttributes
;
537 IO_STATUS_BLOCK IoStatusBlock
;
543 /* Allocate buffer for bootsector */
544 BootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
547 if (BootSector
== NULL
)
548 return(STATUS_INSUFFICIENT_RESOURCES
);
550 /* Read current boot sector into buffer */
551 RtlInitUnicodeString(&Name
,
554 InitializeObjectAttributes(&ObjectAttributes
,
556 OBJ_CASE_INSENSITIVE
,
560 Status
= NtOpenFile(&FileHandle
,
565 FILE_SYNCHRONOUS_IO_NONALERT
);
566 if (!NT_SUCCESS(Status
))
568 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
572 Status
= NtReadFile(FileHandle
,
582 if (!NT_SUCCESS(Status
))
584 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
588 /* Write bootsector to DstPath */
589 RtlInitUnicodeString(&Name
,
592 InitializeObjectAttributes(&ObjectAttributes
,
598 Status
= NtCreateFile(&FileHandle
,
603 FILE_ATTRIBUTE_NORMAL
,
606 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
,
609 if (!NT_SUCCESS(Status
))
611 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
615 Status
= NtWriteFile(FileHandle
,
626 /* Free the new boot sector */
627 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
634 InstallFat16BootCodeToFile(PWSTR SrcPath
,
638 OBJECT_ATTRIBUTES ObjectAttributes
;
639 IO_STATUS_BLOCK IoStatusBlock
;
643 PUCHAR OrigBootSector
;
644 PUCHAR NewBootSector
;
646 /* Allocate buffer for original bootsector */
647 OrigBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
650 if (OrigBootSector
== NULL
)
651 return(STATUS_INSUFFICIENT_RESOURCES
);
653 /* Read current boot sector into buffer */
654 RtlInitUnicodeString(&Name
,
657 InitializeObjectAttributes(&ObjectAttributes
,
659 OBJ_CASE_INSENSITIVE
,
663 Status
= NtOpenFile(&FileHandle
,
668 FILE_SYNCHRONOUS_IO_NONALERT
);
669 if (!NT_SUCCESS(Status
))
671 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
675 Status
= NtReadFile(FileHandle
,
685 if (!NT_SUCCESS(Status
))
687 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
692 /* Allocate buffer for new bootsector */
693 NewBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
696 if (NewBootSector
== NULL
)
698 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
699 return(STATUS_INSUFFICIENT_RESOURCES
);
702 /* Read new bootsector from SrcPath */
703 RtlInitUnicodeString(&Name
,
706 InitializeObjectAttributes(&ObjectAttributes
,
708 OBJ_CASE_INSENSITIVE
,
712 Status
= NtOpenFile(&FileHandle
,
717 FILE_SYNCHRONOUS_IO_NONALERT
);
718 if (!NT_SUCCESS(Status
))
720 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
721 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
725 Status
= NtReadFile(FileHandle
,
735 if (!NT_SUCCESS(Status
))
737 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
738 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
742 /* Adjust bootsector (copy a part of the FAT BPB) */
743 memcpy((NewBootSector
+ 11), (OrigBootSector
+ 11), 51 /*fat BPB length*/);
745 /* Free the original boot sector */
746 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
748 /* Write new bootsector to DstPath */
749 RtlInitUnicodeString(&Name
,
752 InitializeObjectAttributes(&ObjectAttributes
,
758 Status
= NtCreateFile(&FileHandle
,
763 FILE_ATTRIBUTE_NORMAL
,
766 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
,
769 if (!NT_SUCCESS(Status
))
771 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
776 FilePosition
.QuadPart
= 0;
778 Status
= NtWriteFile(FileHandle
,
789 /* Free the new boot sector */
790 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
797 InstallFat32BootCodeToFile(PWSTR SrcPath
,
801 OBJECT_ATTRIBUTES ObjectAttributes
;
802 IO_STATUS_BLOCK IoStatusBlock
;
806 PUCHAR OrigBootSector
;
807 PUCHAR NewBootSector
;
808 LARGE_INTEGER FileOffset
;
810 /* Allocate buffer for original bootsector */
811 OrigBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
814 if (OrigBootSector
== NULL
)
815 return(STATUS_INSUFFICIENT_RESOURCES
);
817 /* Read current boot sector into buffer */
818 RtlInitUnicodeString(&Name
,
821 InitializeObjectAttributes(&ObjectAttributes
,
823 OBJ_CASE_INSENSITIVE
,
827 Status
= NtOpenFile(&FileHandle
,
832 FILE_SYNCHRONOUS_IO_NONALERT
);
833 if (!NT_SUCCESS(Status
))
835 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
839 Status
= NtReadFile(FileHandle
,
849 if (!NT_SUCCESS(Status
))
852 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
856 /* Allocate buffer for new bootsector (2 sectors) */
857 NewBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
860 if (NewBootSector
== NULL
)
862 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
863 return(STATUS_INSUFFICIENT_RESOURCES
);
866 /* Read new bootsector from SrcPath */
867 RtlInitUnicodeString(&Name
,
870 InitializeObjectAttributes(&ObjectAttributes
,
872 OBJ_CASE_INSENSITIVE
,
876 Status
= NtOpenFile(&FileHandle
,
881 FILE_SYNCHRONOUS_IO_NONALERT
);
882 if (!NT_SUCCESS(Status
))
884 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
885 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
889 Status
= NtReadFile(FileHandle
,
899 if (!NT_SUCCESS(Status
))
901 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
902 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
906 /* Adjust bootsector (copy a part of the FAT32 BPB) */
907 memcpy((NewBootSector
+ 3),
908 (OrigBootSector
+ 3),
909 87); /* FAT32 BPB length */
911 /* Disable the backup boot sector */
912 NewBootSector
[0x32] = 0x00;
913 NewBootSector
[0x33] = 0x00;
915 /* Free the original boot sector */
916 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
918 /* Write the first sector of the new bootcode to DstPath */
919 RtlInitUnicodeString(&Name
,
922 InitializeObjectAttributes(&ObjectAttributes
,
928 Status
= NtCreateFile(&FileHandle
,
933 FILE_ATTRIBUTE_NORMAL
,
936 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
,
939 if (!NT_SUCCESS(Status
))
941 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
945 Status
= NtWriteFile(FileHandle
,
955 if (!NT_SUCCESS(Status
))
957 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
961 /* Write the second sector of the new bootcode to boot disk sector 14 */
962 RtlInitUnicodeString(&Name
,
965 InitializeObjectAttributes(&ObjectAttributes
,
971 Status
= NtOpenFile(&FileHandle
,
976 FILE_SYNCHRONOUS_IO_NONALERT
);
977 if (!NT_SUCCESS(Status
))
979 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
983 FileOffset
.QuadPart
= (ULONGLONG
)(14 * SECTORSIZE
);
984 Status
= NtWriteFile(FileHandle
,
989 (NewBootSector
+ SECTORSIZE
),
993 if (!NT_SUCCESS(Status
))
998 /* Free the new boot sector */
999 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1006 InstallMbrBootCodeToDisk (PWSTR SrcPath
,
1009 OBJECT_ATTRIBUTES ObjectAttributes
;
1010 IO_STATUS_BLOCK IoStatusBlock
;
1011 UNICODE_STRING Name
;
1014 PUCHAR OrigBootSector
;
1015 PUCHAR NewBootSector
;
1017 /* Allocate buffer for original bootsector */
1018 OrigBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
1021 if (OrigBootSector
== NULL
)
1022 return(STATUS_INSUFFICIENT_RESOURCES
);
1024 /* Read current boot sector into buffer */
1025 RtlInitUnicodeString(&Name
,
1028 InitializeObjectAttributes(&ObjectAttributes
,
1030 OBJ_CASE_INSENSITIVE
,
1034 Status
= NtOpenFile(&FileHandle
,
1039 FILE_SYNCHRONOUS_IO_NONALERT
);
1040 if (!NT_SUCCESS(Status
))
1042 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1046 Status
= NtReadFile(FileHandle
,
1055 NtClose(FileHandle
);
1056 if (!NT_SUCCESS(Status
))
1058 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1063 /* Allocate buffer for new bootsector */
1064 NewBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
1067 if (NewBootSector
== NULL
)
1069 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1070 return(STATUS_INSUFFICIENT_RESOURCES
);
1073 /* Read new bootsector from SrcPath */
1074 RtlInitUnicodeString(&Name
,
1077 InitializeObjectAttributes(&ObjectAttributes
,
1079 OBJ_CASE_INSENSITIVE
,
1083 Status
= NtOpenFile(&FileHandle
,
1088 FILE_SYNCHRONOUS_IO_NONALERT
);
1089 if (!NT_SUCCESS(Status
))
1091 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1092 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1096 Status
= NtReadFile(FileHandle
,
1105 NtClose(FileHandle
);
1106 if (!NT_SUCCESS(Status
))
1108 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1109 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1113 /* Copy partition table from old MBR to new */
1114 RtlCopyMemory ((NewBootSector
+ 446),
1115 (OrigBootSector
+ 446),
1116 4*16 /* Length of partition table */);
1118 /* Free the original boot sector */
1119 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1121 /* Write new bootsector to RootPath */
1122 RtlInitUnicodeString(&Name
,
1125 InitializeObjectAttributes(&ObjectAttributes
,
1131 Status
= NtOpenFile(&FileHandle
,
1136 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1137 if (!NT_SUCCESS(Status
))
1139 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1140 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1144 Status
= NtWriteFile(FileHandle
,
1153 NtClose(FileHandle
);
1155 /* Free the new boot sector */
1156 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1163 InstallFat16BootCodeToDisk(PWSTR SrcPath
,
1166 OBJECT_ATTRIBUTES ObjectAttributes
;
1167 IO_STATUS_BLOCK IoStatusBlock
;
1168 UNICODE_STRING Name
;
1171 PUCHAR OrigBootSector
;
1172 PUCHAR NewBootSector
;
1174 /* Allocate buffer for original bootsector */
1175 OrigBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
1178 if (OrigBootSector
== NULL
)
1179 return(STATUS_INSUFFICIENT_RESOURCES
);
1181 /* Read current boot sector into buffer */
1182 RtlInitUnicodeString(&Name
,
1185 InitializeObjectAttributes(&ObjectAttributes
,
1187 OBJ_CASE_INSENSITIVE
,
1191 Status
= NtOpenFile(&FileHandle
,
1196 FILE_SYNCHRONOUS_IO_NONALERT
);
1197 if (!NT_SUCCESS(Status
))
1199 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1203 Status
= NtReadFile(FileHandle
,
1212 NtClose(FileHandle
);
1213 if (!NT_SUCCESS(Status
))
1215 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1220 /* Allocate buffer for new bootsector */
1221 NewBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
1224 if (NewBootSector
== NULL
)
1226 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1227 return(STATUS_INSUFFICIENT_RESOURCES
);
1230 /* Read new bootsector from SrcPath */
1231 RtlInitUnicodeString(&Name
,
1234 InitializeObjectAttributes(&ObjectAttributes
,
1236 OBJ_CASE_INSENSITIVE
,
1240 Status
= NtOpenFile(&FileHandle
,
1245 FILE_SYNCHRONOUS_IO_NONALERT
);
1246 if (!NT_SUCCESS(Status
))
1248 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1249 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1253 Status
= NtReadFile(FileHandle
,
1262 NtClose(FileHandle
);
1263 if (!NT_SUCCESS(Status
))
1265 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1266 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1270 /* Adjust bootsector (copy a part of the FAT16 BPB) */
1271 memcpy((NewBootSector
+ 3),
1272 (OrigBootSector
+ 3),
1273 59); /* FAT16 BPB length*/
1275 /* Free the original boot sector */
1276 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1278 /* Write new bootsector to RootPath */
1279 RtlInitUnicodeString(&Name
,
1282 InitializeObjectAttributes(&ObjectAttributes
,
1288 Status
= NtOpenFile(&FileHandle
,
1293 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1294 if (!NT_SUCCESS(Status
))
1296 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1297 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1302 FilePosition
.QuadPart
= 0;
1304 Status
= NtWriteFile(FileHandle
,
1313 NtClose(FileHandle
);
1315 /* Free the new boot sector */
1316 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1323 InstallFat32BootCodeToDisk(PWSTR SrcPath
,
1326 OBJECT_ATTRIBUTES ObjectAttributes
;
1327 IO_STATUS_BLOCK IoStatusBlock
;
1328 UNICODE_STRING Name
;
1331 PUCHAR OrigBootSector
;
1332 PUCHAR NewBootSector
;
1333 LARGE_INTEGER FileOffset
;
1334 USHORT BackupBootSector
;
1336 /* Allocate buffer for original bootsector */
1337 OrigBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
1340 if (OrigBootSector
== NULL
)
1341 return(STATUS_INSUFFICIENT_RESOURCES
);
1343 /* Read current boot sector into buffer */
1344 RtlInitUnicodeString(&Name
,
1347 InitializeObjectAttributes(&ObjectAttributes
,
1349 OBJ_CASE_INSENSITIVE
,
1353 Status
= NtOpenFile(&FileHandle
,
1358 FILE_SYNCHRONOUS_IO_NONALERT
);
1359 if (!NT_SUCCESS(Status
))
1361 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1365 Status
= NtReadFile(FileHandle
,
1374 NtClose(FileHandle
);
1375 if (!NT_SUCCESS(Status
))
1377 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1382 /* Allocate buffer for new bootsector (2 sectors) */
1383 NewBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
1386 if (NewBootSector
== NULL
)
1388 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1389 return(STATUS_INSUFFICIENT_RESOURCES
);
1392 /* Read new bootsector from SrcPath */
1393 RtlInitUnicodeString(&Name
,
1396 InitializeObjectAttributes(&ObjectAttributes
,
1398 OBJ_CASE_INSENSITIVE
,
1402 Status
= NtOpenFile(&FileHandle
,
1407 FILE_SYNCHRONOUS_IO_NONALERT
);
1408 if (!NT_SUCCESS(Status
))
1410 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1411 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1415 Status
= NtReadFile(FileHandle
,
1424 NtClose(FileHandle
);
1425 if (!NT_SUCCESS(Status
))
1427 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1428 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1432 /* Adjust bootsector (copy a part of the FAT32 BPB) */
1433 memcpy((NewBootSector
+ 3),
1434 (OrigBootSector
+ 3),
1435 87); /* FAT32 BPB length */
1437 /* Get the location of the backup boot sector */
1438 BackupBootSector
= (OrigBootSector
[0x33] << 8) + OrigBootSector
[0x32];
1440 /* Free the original boot sector */
1441 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1443 /* Write the first sector of the new bootcode to DstPath */
1444 RtlInitUnicodeString(&Name
,
1447 InitializeObjectAttributes(&ObjectAttributes
,
1453 Status
= NtOpenFile(&FileHandle
,
1458 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1459 if (!NT_SUCCESS(Status
))
1461 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1462 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1466 /* Write sector 0 */
1467 FileOffset
.QuadPart
= 0ULL;
1468 Status
= NtWriteFile(FileHandle
,
1477 if (!NT_SUCCESS(Status
))
1479 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1480 NtClose(FileHandle
);
1481 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1485 /* Write backup boot sector */
1486 if ((BackupBootSector
!= 0x0000) && (BackupBootSector
!= 0xFFFF))
1488 FileOffset
.QuadPart
= (ULONGLONG
)((ULONG
)BackupBootSector
* SECTORSIZE
);
1489 Status
= NtWriteFile(FileHandle
,
1498 if (!NT_SUCCESS(Status
))
1500 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1501 NtClose(FileHandle
);
1502 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1507 /* Write sector 14 */
1508 FileOffset
.QuadPart
= (ULONGLONG
)(14 * SECTORSIZE
);
1509 Status
= NtWriteFile(FileHandle
,
1514 (NewBootSector
+ SECTORSIZE
),
1518 if (!NT_SUCCESS(Status
))
1520 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1522 NtClose(FileHandle
);
1524 /* Free the new boot sector */
1525 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1532 UnprotectBootIni(PWSTR FileName
,
1535 UNICODE_STRING Name
;
1536 OBJECT_ATTRIBUTES ObjectAttributes
;
1537 IO_STATUS_BLOCK IoStatusBlock
;
1538 FILE_BASIC_INFORMATION FileInfo
;
1542 RtlInitUnicodeString(&Name
,
1545 InitializeObjectAttributes(&ObjectAttributes
,
1547 OBJ_CASE_INSENSITIVE
,
1551 Status
= NtOpenFile(&FileHandle
,
1552 GENERIC_READ
|GENERIC_WRITE
,
1556 FILE_SYNCHRONOUS_IO_NONALERT
);
1557 if (Status
== STATUS_NO_SUCH_FILE
)
1559 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1561 return(STATUS_SUCCESS
);
1563 if (!NT_SUCCESS(Status
))
1565 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1569 Status
= NtQueryInformationFile(FileHandle
,
1572 sizeof(FILE_BASIC_INFORMATION
),
1573 FileBasicInformation
);
1574 if (!NT_SUCCESS(Status
))
1576 DPRINT1("NtQueryInformationFile() failed (Status %lx)\n", Status
);
1577 NtClose(FileHandle
);
1581 *Attributes
= FileInfo
.FileAttributes
;
1583 /* Delete attributes SYSTEM, HIDDEN and READONLY */
1584 FileInfo
.FileAttributes
= FileInfo
.FileAttributes
&
1585 ~(FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
| FILE_ATTRIBUTE_READONLY
);
1587 Status
= NtSetInformationFile(FileHandle
,
1590 sizeof(FILE_BASIC_INFORMATION
),
1591 FileBasicInformation
);
1592 if (!NT_SUCCESS(Status
))
1594 DPRINT1("NtSetInformationFile() failed (Status %lx)\n", Status
);
1597 NtClose(FileHandle
);
1603 ProtectBootIni(PWSTR FileName
,
1606 UNICODE_STRING Name
;
1607 OBJECT_ATTRIBUTES ObjectAttributes
;
1608 IO_STATUS_BLOCK IoStatusBlock
;
1609 FILE_BASIC_INFORMATION FileInfo
;
1613 RtlInitUnicodeString(&Name
,
1616 InitializeObjectAttributes(&ObjectAttributes
,
1618 OBJ_CASE_INSENSITIVE
,
1622 Status
= NtOpenFile(&FileHandle
,
1623 GENERIC_READ
|GENERIC_WRITE
,
1627 FILE_SYNCHRONOUS_IO_NONALERT
);
1628 if (!NT_SUCCESS(Status
))
1630 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1634 Status
= NtQueryInformationFile(FileHandle
,
1637 sizeof(FILE_BASIC_INFORMATION
),
1638 FileBasicInformation
);
1639 if (!NT_SUCCESS(Status
))
1641 DPRINT1("NtQueryInformationFile() failed (Status %lx)\n", Status
);
1642 NtClose(FileHandle
);
1646 FileInfo
.FileAttributes
= FileInfo
.FileAttributes
| Attributes
;
1648 Status
= NtSetInformationFile(FileHandle
,
1651 sizeof(FILE_BASIC_INFORMATION
),
1652 FileBasicInformation
);
1653 if (!NT_SUCCESS(Status
))
1655 DPRINT1("NtSetInformationFile() failed (Status %lx)\n", Status
);
1658 NtClose(FileHandle
);
1664 UpdateBootIni(PWSTR BootIniPath
,
1668 UNICODE_STRING Name
;
1669 PINICACHE Cache
= NULL
;
1670 PINICACHESECTION Section
= NULL
;
1672 ULONG FileAttribute
;
1674 RtlInitUnicodeString(&Name
,
1677 Status
= IniCacheLoad(&Cache
,
1680 if (!NT_SUCCESS(Status
))
1685 Section
= IniCacheGetSection(Cache
,
1686 L
"operating systems");
1687 if (Section
== NULL
)
1689 IniCacheDestroy(Cache
);
1690 return(STATUS_UNSUCCESSFUL
);
1693 IniCacheInsertKey(Section
,
1699 Status
= UnprotectBootIni(BootIniPath
,
1701 if (!NT_SUCCESS(Status
))
1703 IniCacheDestroy(Cache
);
1707 Status
= IniCacheSave(Cache
,
1709 if (!NT_SUCCESS(Status
))
1711 IniCacheDestroy(Cache
);
1715 FileAttribute
|= (FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
| FILE_ATTRIBUTE_READONLY
);
1716 Status
= ProtectBootIni(BootIniPath
,
1719 IniCacheDestroy(Cache
);
1726 CheckInstallFatBootcodeToPartition(PUNICODE_STRING SystemRootPath
)
1728 if (DoesFileExist(SystemRootPath
->Buffer
, L
"ntldr") ||
1729 DoesFileExist(SystemRootPath
->Buffer
, L
"boot.ini"))
1733 else if (DoesFileExist(SystemRootPath
->Buffer
, L
"io.sys") ||
1734 DoesFileExist(SystemRootPath
->Buffer
, L
"msdos.sys"))
1744 InstallFatBootcodeToPartition(PUNICODE_STRING SystemRootPath
,
1745 PUNICODE_STRING SourceRootPath
,
1746 PUNICODE_STRING DestinationArcPath
,
1747 UCHAR PartitionType
)
1749 WCHAR SrcPath
[MAX_PATH
];
1750 WCHAR DstPath
[MAX_PATH
];
1753 /* FAT or FAT32 partition */
1754 DPRINT1("System path: '%wZ'\n", SystemRootPath
);
1756 if (DoesFileExist(SystemRootPath
->Buffer
, L
"ntldr") == TRUE
||
1757 DoesFileExist(SystemRootPath
->Buffer
, L
"boot.ini") == TRUE
)
1759 /* Search root directory for 'ntldr' and 'boot.ini'. */
1760 DPRINT("Found Microsoft Windows NT/2000/XP boot loader\n");
1762 /* Copy FreeLoader to the boot partition */
1763 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
1764 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
1765 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1766 wcscat(DstPath
, L
"\\freeldr.sys");
1768 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
1769 Status
= SetupCopyFile(SrcPath
, DstPath
);
1770 if (!NT_SUCCESS(Status
))
1772 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
1776 /* Create or update freeldr.ini */
1777 if (DoesFileExist(SystemRootPath
->Buffer
, L
"freeldr.ini") == FALSE
)
1779 /* Create new 'freeldr.ini' */
1780 DPRINT1("Create new 'freeldr.ini'\n");
1781 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1782 wcscat(DstPath
, L
"\\freeldr.ini");
1784 Status
= CreateFreeLoaderIniForReactos(DstPath
,
1785 DestinationArcPath
->Buffer
);
1786 if (!NT_SUCCESS(Status
))
1788 DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status
);
1792 /* Install new bootcode */
1793 if (PartitionType
== PARTITION_FAT32
||
1794 PartitionType
== PARTITION_FAT32_XINT13
)
1796 /* Install FAT32 bootcode */
1797 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
1798 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
1799 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1800 wcscat(DstPath
, L
"\\bootsect.ros");
1802 DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, DstPath
);
1803 Status
= InstallFat32BootCodeToFile(SrcPath
,
1805 SystemRootPath
->Buffer
);
1806 if (!NT_SUCCESS(Status
))
1808 DPRINT1("InstallFat32BootCodeToFile() failed (Status %lx)\n", Status
);
1814 /* Install FAT16 bootcode */
1815 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
1816 wcscat(SrcPath
, L
"\\loader\\fat.bin");
1817 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1818 wcscat(DstPath
, L
"\\bootsect.ros");
1820 DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath
, DstPath
);
1821 Status
= InstallFat16BootCodeToFile(SrcPath
,
1823 SystemRootPath
->Buffer
);
1824 if (!NT_SUCCESS(Status
))
1826 DPRINT1("InstallFat16BootCodeToFile() failed (Status %lx)\n", Status
);
1831 /* Update 'boot.ini' */
1832 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1833 wcscat(DstPath
, L
"\\boot.ini");
1835 DPRINT1("Update 'boot.ini': %S\n", DstPath
);
1836 Status
= UpdateBootIni(DstPath
,
1837 L
"C:\\bootsect.ros",
1839 if (!NT_SUCCESS(Status
))
1841 DPRINT1("UpdateBootIni() failed (Status %lx)\n", Status
);
1847 /* Update existing 'freeldr.ini' */
1848 DPRINT1("Update existing 'freeldr.ini'\n");
1849 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1850 wcscat(DstPath
, L
"\\freeldr.ini");
1852 Status
= UpdateFreeLoaderIni(DstPath
,
1853 DestinationArcPath
->Buffer
);
1854 if (!NT_SUCCESS(Status
))
1856 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
1861 else if (DoesFileExist(SystemRootPath
->Buffer
, L
"io.sys") == TRUE
||
1862 DoesFileExist(SystemRootPath
->Buffer
, L
"msdos.sys") == TRUE
)
1864 /* Search for root directory for 'io.sys' and 'msdos.sys'. */
1865 DPRINT1("Found Microsoft DOS or Windows 9x boot loader\n");
1867 /* Copy FreeLoader to the boot partition */
1868 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
1869 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
1870 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1871 wcscat(DstPath
, L
"\\freeldr.sys");
1873 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
1874 Status
= SetupCopyFile(SrcPath
, DstPath
);
1875 if (!NT_SUCCESS(Status
))
1877 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
1881 /* Create or update 'freeldr.ini' */
1882 if (DoesFileExist(SystemRootPath
->Buffer
, L
"freeldr.ini") == FALSE
)
1884 /* Create new 'freeldr.ini' */
1885 DPRINT1("Create new 'freeldr.ini'\n");
1886 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1887 wcscat(DstPath
, L
"\\freeldr.ini");
1889 Status
= CreateFreeLoaderIniForDos(DstPath
,
1890 DestinationArcPath
->Buffer
);
1891 if (!NT_SUCCESS(Status
))
1893 DPRINT1("CreateFreeLoaderIniForDos() failed (Status %lx)\n", Status
);
1897 /* Save current bootsector as 'BOOTSECT.DOS' */
1898 wcscpy(SrcPath
, SystemRootPath
->Buffer
);
1899 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1900 wcscat(DstPath
, L
"\\bootsect.dos");
1902 DPRINT1("Save bootsector: %S ==> %S\n", SrcPath
, DstPath
);
1903 Status
= SaveCurrentBootSector(SrcPath
,
1905 if (!NT_SUCCESS(Status
))
1907 DPRINT1("SaveCurrentBootSector() failed (Status %lx)\n", Status
);
1911 /* Install new bootsector */
1912 if (PartitionType
== PARTITION_FAT32
||
1913 PartitionType
== PARTITION_FAT32_XINT13
)
1915 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
1916 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
1918 DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
1919 Status
= InstallFat32BootCodeToDisk(SrcPath
,
1920 SystemRootPath
->Buffer
);
1921 if (!NT_SUCCESS(Status
))
1923 DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)\n", Status
);
1929 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
1930 wcscat(SrcPath
, L
"\\loader\\fat.bin");
1932 DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
1933 Status
= InstallFat16BootCodeToDisk(SrcPath
,
1934 SystemRootPath
->Buffer
);
1935 if (!NT_SUCCESS(Status
))
1937 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status
);
1944 /* Update existing 'freeldr.ini' */
1945 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1946 wcscat(DstPath
, L
"\\freeldr.ini");
1948 Status
= UpdateFreeLoaderIni(DstPath
,
1949 DestinationArcPath
->Buffer
);
1950 if (!NT_SUCCESS(Status
))
1952 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
1959 /* No or unknown boot loader */
1960 DPRINT1("No or unknown boot loader found\n");
1962 /* Copy FreeLoader to the boot partition */
1963 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
1964 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
1965 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1966 wcscat(DstPath
, L
"\\freeldr.sys");
1968 DPRINT1("Copy: %S ==> %S\n", SrcPath
, DstPath
);
1969 Status
= SetupCopyFile(SrcPath
, DstPath
);
1970 if (!NT_SUCCESS(Status
))
1972 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
1976 /* Create or update 'freeldr.ini' */
1977 if (DoesFileExist(SystemRootPath
->Buffer
, L
"freeldr.ini") == FALSE
)
1979 /* Create new freeldr.ini */
1980 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1981 wcscat(DstPath
, L
"\\freeldr.ini");
1983 DPRINT1("Copy: %S ==> %S\n", SrcPath
, DstPath
);
1984 Status
= CreateFreeLoaderIniForReactos(DstPath
,
1985 DestinationArcPath
->Buffer
);
1986 if (!NT_SUCCESS(Status
))
1988 DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status
);
1992 /* Save current bootsector as 'BOOTSECT.OLD' */
1993 wcscpy(SrcPath
, SystemRootPath
->Buffer
);
1994 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1995 wcscat(DstPath
, L
"\\bootsect.old");
1997 DPRINT1("Save bootsector: %S ==> %S\n", SrcPath
, DstPath
);
1998 Status
= SaveCurrentBootSector(SrcPath
,
2000 if (!NT_SUCCESS(Status
))
2002 DPRINT1("SaveCurrentBootSector() failed (Status %lx)\n", Status
);
2006 /* Install new bootsector */
2007 if (PartitionType
== PARTITION_FAT32
||
2008 PartitionType
== PARTITION_FAT32_XINT13
)
2010 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2011 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
2013 DPRINT("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2014 Status
= InstallFat32BootCodeToDisk(SrcPath
,
2015 SystemRootPath
->Buffer
);
2016 if (!NT_SUCCESS(Status
))
2018 DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)\n", Status
);
2024 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2025 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2027 DPRINT("Install FAT bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2028 Status
= InstallFat16BootCodeToDisk(SrcPath
,
2029 SystemRootPath
->Buffer
);
2030 if (!NT_SUCCESS(Status
))
2032 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status
);
2039 /* Update existing 'freeldr.ini' */
2040 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2041 wcscat(DstPath
, L
"\\freeldr.ini");
2043 Status
= UpdateFreeLoaderIni(DstPath
,
2044 DestinationArcPath
->Buffer
);
2045 if (!NT_SUCCESS(Status
))
2047 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
2053 return STATUS_SUCCESS
;
2058 InstallFatBootcodeToFloppy(PUNICODE_STRING SourceRootPath
,
2059 PUNICODE_STRING DestinationArcPath
)
2061 WCHAR SrcPath
[MAX_PATH
];
2062 WCHAR DstPath
[MAX_PATH
];
2065 /* Copy FreeLoader to the boot partition */
2066 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2067 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
2069 wcscpy(DstPath
, L
"\\Device\\Floppy0\\freeldr.sys");
2071 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2072 Status
= SetupCopyFile(SrcPath
, DstPath
);
2073 if (!NT_SUCCESS(Status
))
2075 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
2079 /* Create new 'freeldr.ini' */
2080 wcscpy(DstPath
, L
"\\Device\\Floppy0\\freeldr.ini");
2082 DPRINT("Create new 'freeldr.ini'\n");
2083 Status
= CreateFreeLoaderIniForReactos(DstPath
,
2084 DestinationArcPath
->Buffer
);
2085 if (!NT_SUCCESS(Status
))
2087 DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status
);
2091 /* Install FAT12/16 boosector */
2092 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2093 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2095 wcscpy(DstPath
, L
"\\Device\\Floppy0");
2097 DPRINT("Install FAT bootcode: %S ==> %S\n", SrcPath
, DstPath
);
2098 Status
= InstallFat16BootCodeToDisk(SrcPath
,
2100 if (!NT_SUCCESS(Status
))
2102 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status
);
2106 return STATUS_SUCCESS
;