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
,
54 IniCacheInsertKey(IniSection
,
60 /* Create "Display" section */
61 IniSection
= IniCacheAppendSection(IniCache
,
64 /* TitleText=ReactOS Boot Manager */
65 IniCacheInsertKey(IniSection
,
69 L
"ReactOS Boot Manager");
71 /* StatusBarColor=Cyan */
72 IniCacheInsertKey(IniSection
,
78 /* StatusBarTextColor=Black */
79 IniCacheInsertKey(IniSection
,
82 L
"StatusBarTextColor",
85 /* BackdropTextColor=White */
86 IniCacheInsertKey(IniSection
,
92 /* BackdropColor=Blue */
93 IniCacheInsertKey(IniSection
,
99 /* BackdropFillStyle=Medium */
100 IniCacheInsertKey(IniSection
,
103 L
"BackdropFillStyle",
106 /* TitleBoxTextColor=White */
107 IniCacheInsertKey(IniSection
,
110 L
"TitleBoxTextColor",
113 /* TitleBoxColor=Red */
114 IniCacheInsertKey(IniSection
,
120 /* MessageBoxTextColor=White */
121 IniCacheInsertKey(IniSection
,
124 L
"MessageBoxTextColor",
127 /* MessageBoxColor=Blue */
128 IniCacheInsertKey(IniSection
,
134 /* MenuTextColor=White */
135 IniCacheInsertKey(IniSection
,
142 IniCacheInsertKey(IniSection
,
148 /* TextColor=Yellow */
149 IniCacheInsertKey(IniSection
,
155 /* SelectedTextColor=Black */
156 IniCacheInsertKey(IniSection
,
159 L
"SelectedTextColor",
162 /* SelectedColor=Gray */
163 IniCacheInsertKey(IniSection
,
172 CreateFreeLoaderIniForDos(PWCHAR IniPath
,
176 PINICACHESECTION IniSection
;
178 IniCache
= IniCacheCreate();
180 CreateCommonFreeLoaderSections(IniCache
);
182 /* Create "Operating Systems" section */
183 IniSection
= IniCacheAppendSection(IniCache
,
184 L
"Operating Systems");
186 /* REACTOS=ReactOS */
187 IniCacheInsertKey(IniSection
,
193 /* ReactOS_Debug="ReactOS (Debug)" */
194 IniCacheInsertKey(IniSection
,
198 L
"\"ReactOS (Debug)\"");
200 /* DOS=Dos/Windows */
201 IniCacheInsertKey(IniSection
,
207 /* Create "ReactOS" section */
208 IniSection
= IniCacheAppendSection(IniCache
,
211 /* BootType=ReactOS */
212 IniCacheInsertKey(IniSection
,
218 /* SystemPath=<ArcPath> */
219 IniCacheInsertKey(IniSection
,
225 /* Create "ReactOS_Debug" section */
226 IniSection
= IniCacheAppendSection(IniCache
,
229 /* BootType=ReactOS */
230 IniCacheInsertKey(IniSection
,
236 /* SystemPath=<ArcPath> */
237 IniCacheInsertKey(IniSection
,
243 /* Options=/DEBUGPORT=SCREEN /NOGUIBOOT */
244 IniCacheInsertKey(IniSection
,
248 L
"/DEBUGPORT=SCREEN /NOGUIBOOT");
250 /* Create "DOS" section */
251 IniSection
= IniCacheAppendSection(IniCache
,
254 /* BootType=BootSector */
255 IniCacheInsertKey(IniSection
,
262 IniCacheInsertKey(IniSection
,
268 /* BootPartition=1 */
269 IniCacheInsertKey(IniSection
,
275 /* BootSector=BOOTSECT.DOS */
276 IniCacheInsertKey(IniSection
,
282 IniCacheSave(IniCache
, IniPath
);
283 IniCacheDestroy(IniCache
);
285 return(STATUS_SUCCESS
);
290 CreateFreeLoaderIniForReactos(PWCHAR IniPath
,
294 PINICACHESECTION IniSection
;
296 IniCache
= IniCacheCreate();
298 CreateCommonFreeLoaderSections(IniCache
);
300 /* Create "Operating Systems" section */
301 IniSection
= IniCacheAppendSection(IniCache
,
302 L
"Operating Systems");
304 /* ReactOS="ReactOS" */
305 IniCacheInsertKey(IniSection
,
311 /* ReactOS_Debug="ReactOS (Debug)" */
312 IniCacheInsertKey(IniSection
,
316 L
"\"ReactOS (Debug)\"");
318 /* Create "ReactOS" section */
319 IniSection
= IniCacheAppendSection(IniCache
,
322 /* BootType=ReactOS */
323 IniCacheInsertKey(IniSection
,
329 /* SystemPath=<ArcPath> */
330 IniCacheInsertKey(IniSection
,
336 /* Create "ReactOS_Debug" section */
337 IniSection
= IniCacheAppendSection(IniCache
,
340 /* BootType=ReactOS */
341 IniCacheInsertKey(IniSection
,
347 /* SystemPath=<ArcPath> */
348 IniCacheInsertKey(IniSection
,
354 /* Options=/DEBUGPORT=SCREEN /NOGUIBOOT */
355 IniCacheInsertKey(IniSection
,
359 L
"/DEBUGPORT=SCREEN /NOGUIBOOT");
361 /* Save the ini file */
362 IniCacheSave(IniCache
, IniPath
);
363 IniCacheDestroy(IniCache
);
365 return(STATUS_SUCCESS
);
370 UpdateFreeLoaderIni(PWCHAR IniPath
,
375 PINICACHESECTION IniSection
;
376 PINICACHESECTION OsIniSection
;
377 WCHAR SectionName
[80];
379 WCHAR SystemPath
[200];
380 WCHAR SectionName2
[200];
385 RtlInitUnicodeString(&Name
,
388 Status
= IniCacheLoad(&IniCache
,
391 if (!NT_SUCCESS(Status
))
394 /* Get "Operating Systems" section */
395 IniSection
= IniCacheGetSection(IniCache
,
396 L
"Operating Systems");
397 if (IniSection
== NULL
)
399 IniCacheDestroy(IniCache
);
400 return(STATUS_UNSUCCESSFUL
);
403 /* Find an existing usable or an unused section name */
405 wcscpy(SectionName
, L
"ReactOS");
406 wcscpy(OsName
, L
"\"ReactOS\"");
409 Status
= IniCacheGetKey(IniSection
,
412 if (!NT_SUCCESS(Status
))
415 /* Get operation system section */
416 if (KeyData
[0] == '"')
418 wcscpy(SectionName2
, &KeyData
[1]);
419 j
= wcslen(SectionName2
);
422 SectionName2
[j
-1] = 0;
427 wcscpy(SectionName2
, KeyData
);
430 OsIniSection
= IniCacheGetSection(IniCache
,
432 if (OsIniSection
!= NULL
)
434 BOOLEAN UseExistingEntry
= TRUE
;
437 Status
= IniCacheGetKey(OsIniSection
,
440 if (NT_SUCCESS(Status
))
443 || (_wcsicmp(KeyData
, L
"ReactOS") != 0
444 && _wcsicmp(KeyData
, L
"\"ReactOS\"") != 0))
446 /* This is not a ReactOS entry */
447 UseExistingEntry
= FALSE
;
452 UseExistingEntry
= FALSE
;
455 if (UseExistingEntry
)
457 /* BootType is ReactOS. Now check SystemPath */
458 Status
= IniCacheGetKey(OsIniSection
,
461 if (NT_SUCCESS(Status
))
463 swprintf(SystemPath
, L
"\"%S\"", ArcPath
);
465 || (_wcsicmp(KeyData
, ArcPath
) != 0
466 && _wcsicmp(KeyData
, SystemPath
) != 0))
468 /* This entry is a ReactOS entry, but the SystemRoot does not
469 match the one we are looking for */
470 UseExistingEntry
= FALSE
;
475 UseExistingEntry
= FALSE
;
479 if (UseExistingEntry
)
481 IniCacheDestroy(IniCache
);
482 return(STATUS_SUCCESS
);
486 swprintf(SectionName
, L
"ReactOS_%lu", i
);
487 swprintf(OsName
, L
"\"ReactOS %lu\"", i
);
491 /* <SectionName>=<OsName> */
492 IniCacheInsertKey(IniSection
,
498 /* Create <SectionName> section */
499 IniSection
= IniCacheAppendSection(IniCache
,
502 /* BootType=ReactOS */
503 IniCacheInsertKey(IniSection
,
509 /* SystemPath=<ArcPath> */
510 IniCacheInsertKey(IniSection
,
516 IniCacheSave(IniCache
, IniPath
);
517 IniCacheDestroy(IniCache
);
519 return(STATUS_SUCCESS
);
524 SaveCurrentBootSector(PWSTR RootPath
,
527 OBJECT_ATTRIBUTES ObjectAttributes
;
528 IO_STATUS_BLOCK IoStatusBlock
;
534 /* Allocate buffer for bootsector */
535 BootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
538 if (BootSector
== NULL
)
539 return(STATUS_INSUFFICIENT_RESOURCES
);
541 /* Read current boot sector into buffer */
542 RtlInitUnicodeString(&Name
,
545 InitializeObjectAttributes(&ObjectAttributes
,
547 OBJ_CASE_INSENSITIVE
,
551 Status
= NtOpenFile(&FileHandle
,
556 FILE_SYNCHRONOUS_IO_NONALERT
);
557 if (!NT_SUCCESS(Status
))
559 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
563 Status
= NtReadFile(FileHandle
,
573 if (!NT_SUCCESS(Status
))
575 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
579 /* Write bootsector to DstPath */
580 RtlInitUnicodeString(&Name
,
583 InitializeObjectAttributes(&ObjectAttributes
,
589 Status
= NtCreateFile(&FileHandle
,
594 FILE_ATTRIBUTE_NORMAL
,
597 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
,
600 if (!NT_SUCCESS(Status
))
602 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
606 Status
= NtWriteFile(FileHandle
,
617 /* Free the new boot sector */
618 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
625 InstallFat16BootCodeToFile(PWSTR SrcPath
,
629 OBJECT_ATTRIBUTES ObjectAttributes
;
630 IO_STATUS_BLOCK IoStatusBlock
;
634 PUCHAR OrigBootSector
;
635 PUCHAR NewBootSector
;
637 /* Allocate buffer for original bootsector */
638 OrigBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
641 if (OrigBootSector
== NULL
)
642 return(STATUS_INSUFFICIENT_RESOURCES
);
644 /* Read current boot sector into buffer */
645 RtlInitUnicodeString(&Name
,
648 InitializeObjectAttributes(&ObjectAttributes
,
650 OBJ_CASE_INSENSITIVE
,
654 Status
= NtOpenFile(&FileHandle
,
659 FILE_SYNCHRONOUS_IO_NONALERT
);
660 if (!NT_SUCCESS(Status
))
662 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
666 Status
= NtReadFile(FileHandle
,
676 if (!NT_SUCCESS(Status
))
678 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
683 /* Allocate buffer for new bootsector */
684 NewBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
687 if (NewBootSector
== NULL
)
689 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
690 return(STATUS_INSUFFICIENT_RESOURCES
);
693 /* Read new bootsector from SrcPath */
694 RtlInitUnicodeString(&Name
,
697 InitializeObjectAttributes(&ObjectAttributes
,
699 OBJ_CASE_INSENSITIVE
,
703 Status
= NtOpenFile(&FileHandle
,
708 FILE_SYNCHRONOUS_IO_NONALERT
);
709 if (!NT_SUCCESS(Status
))
711 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
712 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
716 Status
= NtReadFile(FileHandle
,
726 if (!NT_SUCCESS(Status
))
728 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
729 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
733 /* Adjust bootsector (copy a part of the FAT BPB) */
734 memcpy((NewBootSector
+ 11), (OrigBootSector
+ 11), 51 /*fat BPB length*/);
736 /* Free the original boot sector */
737 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
739 /* Write new bootsector to DstPath */
740 RtlInitUnicodeString(&Name
,
743 InitializeObjectAttributes(&ObjectAttributes
,
749 Status
= NtCreateFile(&FileHandle
,
754 FILE_ATTRIBUTE_NORMAL
,
757 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
,
760 if (!NT_SUCCESS(Status
))
762 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
767 FilePosition
.QuadPart
= 0;
769 Status
= NtWriteFile(FileHandle
,
780 /* Free the new boot sector */
781 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
788 InstallFat32BootCodeToFile(PWSTR SrcPath
,
792 OBJECT_ATTRIBUTES ObjectAttributes
;
793 IO_STATUS_BLOCK IoStatusBlock
;
797 PUCHAR OrigBootSector
;
798 PUCHAR NewBootSector
;
799 LARGE_INTEGER FileOffset
;
801 /* Allocate buffer for original bootsector */
802 OrigBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
805 if (OrigBootSector
== NULL
)
806 return(STATUS_INSUFFICIENT_RESOURCES
);
808 /* Read current boot sector into buffer */
809 RtlInitUnicodeString(&Name
,
812 InitializeObjectAttributes(&ObjectAttributes
,
814 OBJ_CASE_INSENSITIVE
,
818 Status
= NtOpenFile(&FileHandle
,
823 FILE_SYNCHRONOUS_IO_NONALERT
);
824 if (!NT_SUCCESS(Status
))
826 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
830 Status
= NtReadFile(FileHandle
,
840 if (!NT_SUCCESS(Status
))
843 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
847 /* Allocate buffer for new bootsector (2 sectors) */
848 NewBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
851 if (NewBootSector
== NULL
)
853 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
854 return(STATUS_INSUFFICIENT_RESOURCES
);
857 /* Read new bootsector from SrcPath */
858 RtlInitUnicodeString(&Name
,
861 InitializeObjectAttributes(&ObjectAttributes
,
863 OBJ_CASE_INSENSITIVE
,
867 Status
= NtOpenFile(&FileHandle
,
872 FILE_SYNCHRONOUS_IO_NONALERT
);
873 if (!NT_SUCCESS(Status
))
875 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
876 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
880 Status
= NtReadFile(FileHandle
,
890 if (!NT_SUCCESS(Status
))
892 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
893 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
897 /* Adjust bootsector (copy a part of the FAT32 BPB) */
898 memcpy((NewBootSector
+ 3),
899 (OrigBootSector
+ 3),
900 87); /* FAT32 BPB length */
902 /* Disable the backup boot sector */
903 NewBootSector
[0x32] = 0x00;
904 NewBootSector
[0x33] = 0x00;
906 /* Free the original boot sector */
907 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
909 /* Write the first sector of the new bootcode to DstPath */
910 RtlInitUnicodeString(&Name
,
913 InitializeObjectAttributes(&ObjectAttributes
,
919 Status
= NtCreateFile(&FileHandle
,
924 FILE_ATTRIBUTE_NORMAL
,
927 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
,
930 if (!NT_SUCCESS(Status
))
932 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
936 Status
= NtWriteFile(FileHandle
,
946 if (!NT_SUCCESS(Status
))
948 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
952 /* Write the second sector of the new bootcode to boot disk sector 14 */
953 RtlInitUnicodeString(&Name
,
956 InitializeObjectAttributes(&ObjectAttributes
,
962 Status
= NtOpenFile(&FileHandle
,
967 FILE_SYNCHRONOUS_IO_NONALERT
);
968 if (!NT_SUCCESS(Status
))
970 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
974 FileOffset
.QuadPart
= (ULONGLONG
)(14 * SECTORSIZE
);
975 Status
= NtWriteFile(FileHandle
,
980 (NewBootSector
+ SECTORSIZE
),
984 if (!NT_SUCCESS(Status
))
989 /* Free the new boot sector */
990 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
997 InstallMbrBootCodeToDisk (PWSTR SrcPath
,
1000 OBJECT_ATTRIBUTES ObjectAttributes
;
1001 IO_STATUS_BLOCK IoStatusBlock
;
1002 UNICODE_STRING Name
;
1005 PUCHAR OrigBootSector
;
1006 PUCHAR NewBootSector
;
1008 /* Allocate buffer for original bootsector */
1009 OrigBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
1012 if (OrigBootSector
== NULL
)
1013 return(STATUS_INSUFFICIENT_RESOURCES
);
1015 /* Read current boot sector into buffer */
1016 RtlInitUnicodeString(&Name
,
1019 InitializeObjectAttributes(&ObjectAttributes
,
1021 OBJ_CASE_INSENSITIVE
,
1025 Status
= NtOpenFile(&FileHandle
,
1030 FILE_SYNCHRONOUS_IO_NONALERT
);
1031 if (!NT_SUCCESS(Status
))
1033 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1037 Status
= NtReadFile(FileHandle
,
1046 NtClose(FileHandle
);
1047 if (!NT_SUCCESS(Status
))
1049 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1054 /* Allocate buffer for new bootsector */
1055 NewBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
1058 if (NewBootSector
== NULL
)
1060 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1061 return(STATUS_INSUFFICIENT_RESOURCES
);
1064 /* Read new bootsector from SrcPath */
1065 RtlInitUnicodeString(&Name
,
1068 InitializeObjectAttributes(&ObjectAttributes
,
1070 OBJ_CASE_INSENSITIVE
,
1074 Status
= NtOpenFile(&FileHandle
,
1079 FILE_SYNCHRONOUS_IO_NONALERT
);
1080 if (!NT_SUCCESS(Status
))
1082 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1083 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1087 Status
= NtReadFile(FileHandle
,
1096 NtClose(FileHandle
);
1097 if (!NT_SUCCESS(Status
))
1099 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1100 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1104 /* Copy partition table from old MBR to new */
1105 RtlCopyMemory ((NewBootSector
+ 446),
1106 (OrigBootSector
+ 446),
1107 4*16 /* Length of partition table */);
1109 /* Free the original boot sector */
1110 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1112 /* Write new bootsector to RootPath */
1113 RtlInitUnicodeString(&Name
,
1116 InitializeObjectAttributes(&ObjectAttributes
,
1122 Status
= NtOpenFile(&FileHandle
,
1127 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1128 if (!NT_SUCCESS(Status
))
1130 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1131 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1135 Status
= NtWriteFile(FileHandle
,
1144 NtClose(FileHandle
);
1146 /* Free the new boot sector */
1147 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1154 InstallFat16BootCodeToDisk(PWSTR SrcPath
,
1157 OBJECT_ATTRIBUTES ObjectAttributes
;
1158 IO_STATUS_BLOCK IoStatusBlock
;
1159 UNICODE_STRING Name
;
1162 PUCHAR OrigBootSector
;
1163 PUCHAR NewBootSector
;
1165 /* Allocate buffer for original bootsector */
1166 OrigBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
1169 if (OrigBootSector
== NULL
)
1170 return(STATUS_INSUFFICIENT_RESOURCES
);
1172 /* Read current boot sector into buffer */
1173 RtlInitUnicodeString(&Name
,
1176 InitializeObjectAttributes(&ObjectAttributes
,
1178 OBJ_CASE_INSENSITIVE
,
1182 Status
= NtOpenFile(&FileHandle
,
1187 FILE_SYNCHRONOUS_IO_NONALERT
);
1188 if (!NT_SUCCESS(Status
))
1190 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1194 Status
= NtReadFile(FileHandle
,
1203 NtClose(FileHandle
);
1204 if (!NT_SUCCESS(Status
))
1206 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1211 /* Allocate buffer for new bootsector */
1212 NewBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
1215 if (NewBootSector
== NULL
)
1217 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1218 return(STATUS_INSUFFICIENT_RESOURCES
);
1221 /* Read new bootsector from SrcPath */
1222 RtlInitUnicodeString(&Name
,
1225 InitializeObjectAttributes(&ObjectAttributes
,
1227 OBJ_CASE_INSENSITIVE
,
1231 Status
= NtOpenFile(&FileHandle
,
1236 FILE_SYNCHRONOUS_IO_NONALERT
);
1237 if (!NT_SUCCESS(Status
))
1239 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1240 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1244 Status
= NtReadFile(FileHandle
,
1253 NtClose(FileHandle
);
1254 if (!NT_SUCCESS(Status
))
1256 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1257 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1261 /* Adjust bootsector (copy a part of the FAT16 BPB) */
1262 memcpy((NewBootSector
+ 3),
1263 (OrigBootSector
+ 3),
1264 59); /* FAT16 BPB length*/
1266 /* Free the original boot sector */
1267 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1269 /* Write new bootsector to RootPath */
1270 RtlInitUnicodeString(&Name
,
1273 InitializeObjectAttributes(&ObjectAttributes
,
1279 Status
= NtOpenFile(&FileHandle
,
1284 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1285 if (!NT_SUCCESS(Status
))
1287 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1288 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1293 FilePosition
.QuadPart
= 0;
1295 Status
= NtWriteFile(FileHandle
,
1304 NtClose(FileHandle
);
1306 /* Free the new boot sector */
1307 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1314 InstallFat32BootCodeToDisk(PWSTR SrcPath
,
1317 OBJECT_ATTRIBUTES ObjectAttributes
;
1318 IO_STATUS_BLOCK IoStatusBlock
;
1319 UNICODE_STRING Name
;
1322 PUCHAR OrigBootSector
;
1323 PUCHAR NewBootSector
;
1324 LARGE_INTEGER FileOffset
;
1325 USHORT BackupBootSector
;
1327 /* Allocate buffer for original bootsector */
1328 OrigBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
1331 if (OrigBootSector
== NULL
)
1332 return(STATUS_INSUFFICIENT_RESOURCES
);
1334 /* Read current boot sector into buffer */
1335 RtlInitUnicodeString(&Name
,
1338 InitializeObjectAttributes(&ObjectAttributes
,
1340 OBJ_CASE_INSENSITIVE
,
1344 Status
= NtOpenFile(&FileHandle
,
1349 FILE_SYNCHRONOUS_IO_NONALERT
);
1350 if (!NT_SUCCESS(Status
))
1352 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1356 Status
= NtReadFile(FileHandle
,
1365 NtClose(FileHandle
);
1366 if (!NT_SUCCESS(Status
))
1368 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1373 /* Allocate buffer for new bootsector (2 sectors) */
1374 NewBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
1377 if (NewBootSector
== NULL
)
1379 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1380 return(STATUS_INSUFFICIENT_RESOURCES
);
1383 /* Read new bootsector from SrcPath */
1384 RtlInitUnicodeString(&Name
,
1387 InitializeObjectAttributes(&ObjectAttributes
,
1389 OBJ_CASE_INSENSITIVE
,
1393 Status
= NtOpenFile(&FileHandle
,
1398 FILE_SYNCHRONOUS_IO_NONALERT
);
1399 if (!NT_SUCCESS(Status
))
1401 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1402 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1406 Status
= NtReadFile(FileHandle
,
1415 NtClose(FileHandle
);
1416 if (!NT_SUCCESS(Status
))
1418 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1419 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1423 /* Adjust bootsector (copy a part of the FAT32 BPB) */
1424 memcpy((NewBootSector
+ 3),
1425 (OrigBootSector
+ 3),
1426 87); /* FAT32 BPB length */
1428 /* Get the location of the backup boot sector */
1429 BackupBootSector
= (OrigBootSector
[0x33] << 8) + OrigBootSector
[0x32];
1431 /* Free the original boot sector */
1432 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1434 /* Write the first sector of the new bootcode to DstPath */
1435 RtlInitUnicodeString(&Name
,
1438 InitializeObjectAttributes(&ObjectAttributes
,
1444 Status
= NtOpenFile(&FileHandle
,
1449 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1450 if (!NT_SUCCESS(Status
))
1452 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1453 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1457 /* Write sector 0 */
1458 FileOffset
.QuadPart
= 0ULL;
1459 Status
= NtWriteFile(FileHandle
,
1468 if (!NT_SUCCESS(Status
))
1470 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1471 NtClose(FileHandle
);
1472 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1476 /* Write backup boot sector */
1477 if ((BackupBootSector
!= 0x0000) && (BackupBootSector
!= 0xFFFF))
1479 FileOffset
.QuadPart
= (ULONGLONG
)((ULONG
)BackupBootSector
* SECTORSIZE
);
1480 Status
= NtWriteFile(FileHandle
,
1489 if (!NT_SUCCESS(Status
))
1491 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1492 NtClose(FileHandle
);
1493 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1498 /* Write sector 14 */
1499 FileOffset
.QuadPart
= (ULONGLONG
)(14 * SECTORSIZE
);
1500 Status
= NtWriteFile(FileHandle
,
1505 (NewBootSector
+ SECTORSIZE
),
1509 if (!NT_SUCCESS(Status
))
1511 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1513 NtClose(FileHandle
);
1515 /* Free the new boot sector */
1516 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1523 UnprotectBootIni(PWSTR FileName
,
1526 UNICODE_STRING Name
;
1527 OBJECT_ATTRIBUTES ObjectAttributes
;
1528 IO_STATUS_BLOCK IoStatusBlock
;
1529 FILE_BASIC_INFORMATION FileInfo
;
1533 RtlInitUnicodeString(&Name
,
1536 InitializeObjectAttributes(&ObjectAttributes
,
1538 OBJ_CASE_INSENSITIVE
,
1542 Status
= NtOpenFile(&FileHandle
,
1543 GENERIC_READ
|GENERIC_WRITE
,
1547 FILE_SYNCHRONOUS_IO_NONALERT
);
1548 if (Status
== STATUS_NO_SUCH_FILE
)
1550 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1552 return(STATUS_SUCCESS
);
1554 if (!NT_SUCCESS(Status
))
1556 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1560 Status
= NtQueryInformationFile(FileHandle
,
1563 sizeof(FILE_BASIC_INFORMATION
),
1564 FileBasicInformation
);
1565 if (!NT_SUCCESS(Status
))
1567 DPRINT1("NtQueryInformationFile() failed (Status %lx)\n", Status
);
1568 NtClose(FileHandle
);
1572 *Attributes
= FileInfo
.FileAttributes
;
1574 /* Delete attributes SYSTEM, HIDDEN and READONLY */
1575 FileInfo
.FileAttributes
= FileInfo
.FileAttributes
&
1576 ~(FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
| FILE_ATTRIBUTE_READONLY
);
1578 Status
= NtSetInformationFile(FileHandle
,
1581 sizeof(FILE_BASIC_INFORMATION
),
1582 FileBasicInformation
);
1583 if (!NT_SUCCESS(Status
))
1585 DPRINT1("NtSetInformationFile() failed (Status %lx)\n", Status
);
1588 NtClose(FileHandle
);
1594 ProtectBootIni(PWSTR FileName
,
1597 UNICODE_STRING Name
;
1598 OBJECT_ATTRIBUTES ObjectAttributes
;
1599 IO_STATUS_BLOCK IoStatusBlock
;
1600 FILE_BASIC_INFORMATION FileInfo
;
1604 RtlInitUnicodeString(&Name
,
1607 InitializeObjectAttributes(&ObjectAttributes
,
1609 OBJ_CASE_INSENSITIVE
,
1613 Status
= NtOpenFile(&FileHandle
,
1614 GENERIC_READ
|GENERIC_WRITE
,
1618 FILE_SYNCHRONOUS_IO_NONALERT
);
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 FileInfo
.FileAttributes
= FileInfo
.FileAttributes
| Attributes
;
1639 Status
= NtSetInformationFile(FileHandle
,
1642 sizeof(FILE_BASIC_INFORMATION
),
1643 FileBasicInformation
);
1644 if (!NT_SUCCESS(Status
))
1646 DPRINT1("NtSetInformationFile() failed (Status %lx)\n", Status
);
1649 NtClose(FileHandle
);
1655 UpdateBootIni(PWSTR BootIniPath
,
1659 UNICODE_STRING Name
;
1660 PINICACHE Cache
= NULL
;
1661 PINICACHESECTION Section
= NULL
;
1663 ULONG FileAttribute
;
1665 RtlInitUnicodeString(&Name
,
1668 Status
= IniCacheLoad(&Cache
,
1671 if (!NT_SUCCESS(Status
))
1676 Section
= IniCacheGetSection(Cache
,
1677 L
"operating systems");
1678 if (Section
== NULL
)
1680 IniCacheDestroy(Cache
);
1681 return(STATUS_UNSUCCESSFUL
);
1684 IniCacheInsertKey(Section
,
1690 Status
= UnprotectBootIni(BootIniPath
,
1692 if (!NT_SUCCESS(Status
))
1694 IniCacheDestroy(Cache
);
1698 Status
= IniCacheSave(Cache
,
1700 if (!NT_SUCCESS(Status
))
1702 IniCacheDestroy(Cache
);
1706 FileAttribute
|= (FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
| FILE_ATTRIBUTE_READONLY
);
1707 Status
= ProtectBootIni(BootIniPath
,
1710 IniCacheDestroy(Cache
);
1717 CheckInstallFatBootcodeToPartition(PUNICODE_STRING SystemRootPath
)
1719 if (DoesFileExist(SystemRootPath
->Buffer
, L
"ntldr") ||
1720 DoesFileExist(SystemRootPath
->Buffer
, L
"boot.ini"))
1724 else if (DoesFileExist(SystemRootPath
->Buffer
, L
"io.sys") ||
1725 DoesFileExist(SystemRootPath
->Buffer
, L
"msdos.sys"))
1735 InstallFatBootcodeToPartition(PUNICODE_STRING SystemRootPath
,
1736 PUNICODE_STRING SourceRootPath
,
1737 PUNICODE_STRING DestinationArcPath
,
1738 UCHAR PartitionType
)
1740 WCHAR SrcPath
[MAX_PATH
];
1741 WCHAR DstPath
[MAX_PATH
];
1744 /* FAT or FAT32 partition */
1745 DPRINT1("System path: '%wZ'\n", SystemRootPath
);
1747 if (DoesFileExist(SystemRootPath
->Buffer
, L
"ntldr") == TRUE
||
1748 DoesFileExist(SystemRootPath
->Buffer
, L
"boot.ini") == TRUE
)
1750 /* Search root directory for 'ntldr' and 'boot.ini'. */
1751 DPRINT("Found Microsoft Windows NT/2000/XP boot loader\n");
1753 /* Copy FreeLoader to the boot partition */
1754 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
1755 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
1756 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1757 wcscat(DstPath
, L
"\\freeldr.sys");
1759 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
1760 Status
= SetupCopyFile(SrcPath
, DstPath
);
1761 if (!NT_SUCCESS(Status
))
1763 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
1767 /* Create or update freeldr.ini */
1768 if (DoesFileExist(SystemRootPath
->Buffer
, L
"freeldr.ini") == FALSE
)
1770 /* Create new 'freeldr.ini' */
1771 DPRINT1("Create new 'freeldr.ini'\n");
1772 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1773 wcscat(DstPath
, L
"\\freeldr.ini");
1775 Status
= CreateFreeLoaderIniForReactos(DstPath
,
1776 DestinationArcPath
->Buffer
);
1777 if (!NT_SUCCESS(Status
))
1779 DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status
);
1783 /* Install new bootcode */
1784 if (PartitionType
== PARTITION_FAT32
||
1785 PartitionType
== PARTITION_FAT32_XINT13
)
1787 /* Install FAT32 bootcode */
1788 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
1789 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
1790 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1791 wcscat(DstPath
, L
"\\bootsect.ros");
1793 DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, DstPath
);
1794 Status
= InstallFat32BootCodeToFile(SrcPath
,
1796 SystemRootPath
->Buffer
);
1797 if (!NT_SUCCESS(Status
))
1799 DPRINT1("InstallFat32BootCodeToFile() failed (Status %lx)\n", Status
);
1805 /* Install FAT16 bootcode */
1806 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
1807 wcscat(SrcPath
, L
"\\loader\\fat.bin");
1808 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1809 wcscat(DstPath
, L
"\\bootsect.ros");
1811 DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath
, DstPath
);
1812 Status
= InstallFat16BootCodeToFile(SrcPath
,
1814 SystemRootPath
->Buffer
);
1815 if (!NT_SUCCESS(Status
))
1817 DPRINT1("InstallFat16BootCodeToFile() failed (Status %lx)\n", Status
);
1822 /* Update 'boot.ini' */
1823 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1824 wcscat(DstPath
, L
"\\boot.ini");
1826 DPRINT1("Update 'boot.ini': %S\n", DstPath
);
1827 Status
= UpdateBootIni(DstPath
,
1828 L
"C:\\bootsect.ros",
1830 if (!NT_SUCCESS(Status
))
1832 DPRINT1("UpdateBootIni() failed (Status %lx)\n", Status
);
1838 /* Update existing 'freeldr.ini' */
1839 DPRINT1("Update existing 'freeldr.ini'\n");
1840 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1841 wcscat(DstPath
, L
"\\freeldr.ini");
1843 Status
= UpdateFreeLoaderIni(DstPath
,
1844 DestinationArcPath
->Buffer
);
1845 if (!NT_SUCCESS(Status
))
1847 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
1852 else if (DoesFileExist(SystemRootPath
->Buffer
, L
"io.sys") == TRUE
||
1853 DoesFileExist(SystemRootPath
->Buffer
, L
"msdos.sys") == TRUE
)
1855 /* Search for root directory for 'io.sys' and 'msdos.sys'. */
1856 DPRINT1("Found Microsoft DOS or Windows 9x boot loader\n");
1858 /* Copy FreeLoader to the boot partition */
1859 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
1860 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
1861 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1862 wcscat(DstPath
, L
"\\freeldr.sys");
1864 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
1865 Status
= SetupCopyFile(SrcPath
, DstPath
);
1866 if (!NT_SUCCESS(Status
))
1868 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
1872 /* Create or update 'freeldr.ini' */
1873 if (DoesFileExist(SystemRootPath
->Buffer
, L
"freeldr.ini") == FALSE
)
1875 /* Create new 'freeldr.ini' */
1876 DPRINT1("Create new 'freeldr.ini'\n");
1877 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1878 wcscat(DstPath
, L
"\\freeldr.ini");
1880 Status
= CreateFreeLoaderIniForDos(DstPath
,
1881 DestinationArcPath
->Buffer
);
1882 if (!NT_SUCCESS(Status
))
1884 DPRINT1("CreateFreeLoaderIniForDos() failed (Status %lx)\n", Status
);
1888 /* Save current bootsector as 'BOOTSECT.DOS' */
1889 wcscpy(SrcPath
, SystemRootPath
->Buffer
);
1890 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1891 wcscat(DstPath
, L
"\\bootsect.dos");
1893 DPRINT1("Save bootsector: %S ==> %S\n", SrcPath
, DstPath
);
1894 Status
= SaveCurrentBootSector(SrcPath
,
1896 if (!NT_SUCCESS(Status
))
1898 DPRINT1("SaveCurrentBootSector() failed (Status %lx)\n", Status
);
1902 /* Install new bootsector */
1903 if (PartitionType
== PARTITION_FAT32
||
1904 PartitionType
== PARTITION_FAT32_XINT13
)
1906 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
1907 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
1909 DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
1910 Status
= InstallFat32BootCodeToDisk(SrcPath
,
1911 SystemRootPath
->Buffer
);
1912 if (!NT_SUCCESS(Status
))
1914 DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)\n", Status
);
1920 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
1921 wcscat(SrcPath
, L
"\\loader\\fat.bin");
1923 DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
1924 Status
= InstallFat16BootCodeToDisk(SrcPath
,
1925 SystemRootPath
->Buffer
);
1926 if (!NT_SUCCESS(Status
))
1928 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status
);
1935 /* Update existing 'freeldr.ini' */
1936 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1937 wcscat(DstPath
, L
"\\freeldr.ini");
1939 Status
= UpdateFreeLoaderIni(DstPath
,
1940 DestinationArcPath
->Buffer
);
1941 if (!NT_SUCCESS(Status
))
1943 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
1950 /* No or unknown boot loader */
1951 DPRINT1("No or unknown boot loader found\n");
1953 /* Copy FreeLoader to the boot partition */
1954 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
1955 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
1956 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1957 wcscat(DstPath
, L
"\\freeldr.sys");
1959 DPRINT1("Copy: %S ==> %S\n", SrcPath
, DstPath
);
1960 Status
= SetupCopyFile(SrcPath
, DstPath
);
1961 if (!NT_SUCCESS(Status
))
1963 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
1967 /* Create or update 'freeldr.ini' */
1968 if (DoesFileExist(SystemRootPath
->Buffer
, L
"freeldr.ini") == FALSE
)
1970 /* Create new freeldr.ini */
1971 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1972 wcscat(DstPath
, L
"\\freeldr.ini");
1974 DPRINT1("Copy: %S ==> %S\n", SrcPath
, DstPath
);
1975 Status
= CreateFreeLoaderIniForReactos(DstPath
,
1976 DestinationArcPath
->Buffer
);
1977 if (!NT_SUCCESS(Status
))
1979 DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status
);
1983 /* Save current bootsector as 'BOOTSECT.OLD' */
1984 wcscpy(SrcPath
, SystemRootPath
->Buffer
);
1985 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1986 wcscat(DstPath
, L
"\\bootsect.old");
1988 DPRINT1("Save bootsector: %S ==> %S\n", SrcPath
, DstPath
);
1989 Status
= SaveCurrentBootSector(SrcPath
,
1991 if (!NT_SUCCESS(Status
))
1993 DPRINT1("SaveCurrentBootSector() failed (Status %lx)\n", Status
);
1997 /* Install new bootsector */
1998 if (PartitionType
== PARTITION_FAT32
||
1999 PartitionType
== PARTITION_FAT32_XINT13
)
2001 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2002 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
2004 DPRINT("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2005 Status
= InstallFat32BootCodeToDisk(SrcPath
,
2006 SystemRootPath
->Buffer
);
2007 if (!NT_SUCCESS(Status
))
2009 DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)\n", Status
);
2015 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2016 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2018 DPRINT("Install FAT bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2019 Status
= InstallFat16BootCodeToDisk(SrcPath
,
2020 SystemRootPath
->Buffer
);
2021 if (!NT_SUCCESS(Status
))
2023 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status
);
2030 /* Update existing 'freeldr.ini' */
2031 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2032 wcscat(DstPath
, L
"\\freeldr.ini");
2034 Status
= UpdateFreeLoaderIni(DstPath
,
2035 DestinationArcPath
->Buffer
);
2036 if (!NT_SUCCESS(Status
))
2038 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
2044 return STATUS_SUCCESS
;
2049 InstallFatBootcodeToFloppy(PUNICODE_STRING SourceRootPath
,
2050 PUNICODE_STRING DestinationArcPath
)
2052 WCHAR SrcPath
[MAX_PATH
];
2053 WCHAR DstPath
[MAX_PATH
];
2056 /* Copy FreeLoader to the boot partition */
2057 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2058 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
2060 wcscpy(DstPath
, L
"\\Device\\Floppy0\\freeldr.sys");
2062 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2063 Status
= SetupCopyFile(SrcPath
, DstPath
);
2064 if (!NT_SUCCESS(Status
))
2066 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
2070 /* Create new 'freeldr.ini' */
2071 wcscpy(DstPath
, L
"\\Device\\Floppy0\\freeldr.ini");
2073 DPRINT("Create new 'freeldr.ini'\n");
2074 Status
= CreateFreeLoaderIniForReactos(DstPath
,
2075 DestinationArcPath
->Buffer
);
2076 if (!NT_SUCCESS(Status
))
2078 DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status
);
2082 /* Install FAT12/16 boosector */
2083 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2084 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2086 wcscpy(DstPath
, L
"\\Device\\Floppy0");
2088 DPRINT("Install FAT bootcode: %S ==> %S\n", SrcPath
, DstPath
);
2089 Status
= InstallFat16BootCodeToDisk(SrcPath
,
2091 if (!NT_SUCCESS(Status
))
2093 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status
);
2097 return STATUS_SUCCESS
;