3 * Copyright (C) 2002 ReactOS Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 * COPYRIGHT: See COPYING in the top level directory
21 * PROJECT: ReactOS text-mode setup
22 * FILE: subsys/system/usetup/bootsup.c
23 * PURPOSE: Bootloader support functions
24 * PROGRAMMER: Eric Kohl
32 #define SECTORSIZE 512
34 /* FUNCTIONS ****************************************************************/
38 CreateCommonFreeLoaderSections(PINICACHE IniCache
)
40 PINICACHESECTION IniSection
;
42 /* Create "FREELOADER" section */
43 IniSection
= IniCacheAppendSection(IniCache
,
47 if (IsUnattendedSetup
)
49 /* DefaultOS=ReactOS */
50 IniCacheInsertKey(IniSection
,
59 /* DefaultOS=ReactOS */
60 IniCacheInsertKey(IniSection
,
68 if (IsUnattendedSetup
)
71 /* Timeout=0 for unattended or non debug*/
72 IniCacheInsertKey(IniSection
,
82 IniCacheInsertKey(IniSection
,
90 /* Create "Display" section */
91 IniSection
= IniCacheAppendSection(IniCache
,
94 /* TitleText=ReactOS Boot Manager */
95 IniCacheInsertKey(IniSection
,
99 L
"ReactOS Boot Manager");
101 /* StatusBarColor=Cyan */
102 IniCacheInsertKey(IniSection
,
108 /* StatusBarTextColor=Black */
109 IniCacheInsertKey(IniSection
,
112 L
"StatusBarTextColor",
115 /* BackdropTextColor=White */
116 IniCacheInsertKey(IniSection
,
119 L
"BackdropTextColor",
122 /* BackdropColor=Blue */
123 IniCacheInsertKey(IniSection
,
129 /* BackdropFillStyle=Medium */
130 IniCacheInsertKey(IniSection
,
133 L
"BackdropFillStyle",
136 /* TitleBoxTextColor=White */
137 IniCacheInsertKey(IniSection
,
140 L
"TitleBoxTextColor",
143 /* TitleBoxColor=Red */
144 IniCacheInsertKey(IniSection
,
150 /* MessageBoxTextColor=White */
151 IniCacheInsertKey(IniSection
,
154 L
"MessageBoxTextColor",
157 /* MessageBoxColor=Blue */
158 IniCacheInsertKey(IniSection
,
164 /* MenuTextColor=White */
165 IniCacheInsertKey(IniSection
,
172 IniCacheInsertKey(IniSection
,
178 /* TextColor=Yellow */
179 IniCacheInsertKey(IniSection
,
185 /* SelectedTextColor=Black */
186 IniCacheInsertKey(IniSection
,
189 L
"SelectedTextColor",
192 /* SelectedColor=Gray */
193 IniCacheInsertKey(IniSection
,
199 /* SelectedColor=Gray */
200 IniCacheInsertKey(IniSection
,
206 /* SelectedColor=Gray */
207 IniCacheInsertKey(IniSection
,
213 /* SelectedColor=Gray */
214 IniCacheInsertKey(IniSection
,
220 /* SelectedColor=Gray */
221 IniCacheInsertKey(IniSection
,
227 /* SelectedColor=Gray */
228 IniCacheInsertKey(IniSection
,
232 L
"Seconds until highlighted choice will be started automatically: ");
237 CreateFreeLoaderIniForDos(PWCHAR IniPath
,
241 PINICACHESECTION IniSection
;
243 IniCache
= IniCacheCreate();
245 CreateCommonFreeLoaderSections(IniCache
);
247 /* Create "Operating Systems" section */
248 IniSection
= IniCacheAppendSection(IniCache
,
249 L
"Operating Systems");
251 /* REACTOS=ReactOS */
252 IniCacheInsertKey(IniSection
,
258 /* ReactOS_Debug="ReactOS (Debug)" */
259 IniCacheInsertKey(IniSection
,
263 L
"\"ReactOS (Debug)\"");
265 /* DOS=Dos/Windows */
266 IniCacheInsertKey(IniSection
,
272 /* Create "ReactOS" section */
273 IniSection
= IniCacheAppendSection(IniCache
,
276 /* BootType=ReactOS */
277 IniCacheInsertKey(IniSection
,
283 /* SystemPath=<ArcPath> */
284 IniCacheInsertKey(IniSection
,
290 /* Create "ReactOS_Debug" section */
291 IniSection
= IniCacheAppendSection(IniCache
,
294 /* BootType=ReactOS */
295 IniCacheInsertKey(IniSection
,
301 /* SystemPath=<ArcPath> */
302 IniCacheInsertKey(IniSection
,
308 /* Options=/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS*/
309 IniCacheInsertKey(IniSection
,
313 L
"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS");
315 /* Create "DOS" section */
316 IniSection
= IniCacheAppendSection(IniCache
,
319 /* BootType=BootSector */
320 IniCacheInsertKey(IniSection
,
327 IniCacheInsertKey(IniSection
,
333 /* BootPartition=1 */
334 IniCacheInsertKey(IniSection
,
340 /* BootSector=BOOTSECT.DOS */
341 IniCacheInsertKey(IniSection
,
347 IniCacheSave(IniCache
, IniPath
);
348 IniCacheDestroy(IniCache
);
350 return(STATUS_SUCCESS
);
355 CreateFreeLoaderIniForReactos(PWCHAR IniPath
,
359 PINICACHESECTION IniSection
;
361 IniCache
= IniCacheCreate();
363 CreateCommonFreeLoaderSections(IniCache
);
365 /* Create "Operating Systems" section */
366 IniSection
= IniCacheAppendSection(IniCache
,
367 L
"Operating Systems");
369 /* ReactOS="ReactOS" */
370 IniCacheInsertKey(IniSection
,
376 /* ReactOS_Debug="ReactOS (Debug)" */
377 IniCacheInsertKey(IniSection
,
381 L
"\"ReactOS (Debug)\"");
383 /* Create "ReactOS" section */
384 IniSection
= IniCacheAppendSection(IniCache
,
387 /* BootType=ReactOS */
388 IniCacheInsertKey(IniSection
,
394 /* SystemPath=<ArcPath> */
395 IniCacheInsertKey(IniSection
,
402 IniCacheInsertKey(IniSection
,
408 /* Create "ReactOS_Debug" section */
409 IniSection
= IniCacheAppendSection(IniCache
,
412 /* BootType=ReactOS */
413 IniCacheInsertKey(IniSection
,
419 /* SystemPath=<ArcPath> */
420 IniCacheInsertKey(IniSection
,
426 /* Options=/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS*/
427 IniCacheInsertKey(IniSection
,
431 L
"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS");
433 /* Save the ini file */
434 IniCacheSave(IniCache
, IniPath
);
435 IniCacheDestroy(IniCache
);
437 return(STATUS_SUCCESS
);
442 UpdateFreeLoaderIni(PWCHAR IniPath
,
447 PINICACHESECTION IniSection
;
448 PINICACHESECTION OsIniSection
;
449 WCHAR SectionName
[80];
451 WCHAR SystemPath
[200];
452 WCHAR SectionName2
[200];
457 RtlInitUnicodeString(&Name
,
460 Status
= IniCacheLoad(&IniCache
,
463 if (!NT_SUCCESS(Status
))
466 /* Get "Operating Systems" section */
467 IniSection
= IniCacheGetSection(IniCache
,
468 L
"Operating Systems");
469 if (IniSection
== NULL
)
471 IniCacheDestroy(IniCache
);
472 return(STATUS_UNSUCCESSFUL
);
475 /* Find an existing usable or an unused section name */
477 wcscpy(SectionName
, L
"ReactOS");
478 wcscpy(OsName
, L
"\"ReactOS\"");
481 Status
= IniCacheGetKey(IniSection
,
484 if (!NT_SUCCESS(Status
))
487 /* Get operation system section */
488 if (KeyData
[0] == '"')
490 wcscpy(SectionName2
, &KeyData
[1]);
491 j
= wcslen(SectionName2
);
494 SectionName2
[j
-1] = 0;
499 wcscpy(SectionName2
, KeyData
);
502 OsIniSection
= IniCacheGetSection(IniCache
,
504 if (OsIniSection
!= NULL
)
506 BOOLEAN UseExistingEntry
= TRUE
;
509 Status
= IniCacheGetKey(OsIniSection
,
512 if (NT_SUCCESS(Status
))
515 || (_wcsicmp(KeyData
, L
"ReactOS") != 0
516 && _wcsicmp(KeyData
, L
"\"ReactOS\"") != 0))
518 /* This is not a ReactOS entry */
519 UseExistingEntry
= FALSE
;
524 UseExistingEntry
= FALSE
;
527 if (UseExistingEntry
)
529 /* BootType is ReactOS. Now check SystemPath */
530 Status
= IniCacheGetKey(OsIniSection
,
533 if (NT_SUCCESS(Status
))
535 swprintf(SystemPath
, L
"\"%S\"", ArcPath
);
537 || (_wcsicmp(KeyData
, ArcPath
) != 0
538 && _wcsicmp(KeyData
, SystemPath
) != 0))
540 /* This entry is a ReactOS entry, but the SystemRoot does not
541 match the one we are looking for */
542 UseExistingEntry
= FALSE
;
547 UseExistingEntry
= FALSE
;
551 if (UseExistingEntry
)
553 IniCacheDestroy(IniCache
);
554 return(STATUS_SUCCESS
);
558 swprintf(SectionName
, L
"ReactOS_%lu", i
);
559 swprintf(OsName
, L
"\"ReactOS %lu\"", i
);
563 /* <SectionName>=<OsName> */
564 IniCacheInsertKey(IniSection
,
570 /* Create <SectionName> section */
571 IniSection
= IniCacheAppendSection(IniCache
,
574 /* BootType=ReactOS */
575 IniCacheInsertKey(IniSection
,
581 /* SystemPath=<ArcPath> */
582 IniCacheInsertKey(IniSection
,
588 IniCacheSave(IniCache
, IniPath
);
589 IniCacheDestroy(IniCache
);
591 return(STATUS_SUCCESS
);
596 SaveCurrentBootSector(PWSTR RootPath
,
599 OBJECT_ATTRIBUTES ObjectAttributes
;
600 IO_STATUS_BLOCK IoStatusBlock
;
606 /* Allocate buffer for bootsector */
607 BootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
610 if (BootSector
== NULL
)
611 return(STATUS_INSUFFICIENT_RESOURCES
);
613 /* Read current boot sector into buffer */
614 RtlInitUnicodeString(&Name
,
617 InitializeObjectAttributes(&ObjectAttributes
,
619 OBJ_CASE_INSENSITIVE
,
623 Status
= NtOpenFile(&FileHandle
,
628 FILE_SYNCHRONOUS_IO_NONALERT
);
629 if (!NT_SUCCESS(Status
))
631 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
635 Status
= NtReadFile(FileHandle
,
645 if (!NT_SUCCESS(Status
))
647 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
651 /* Write bootsector to DstPath */
652 RtlInitUnicodeString(&Name
,
655 InitializeObjectAttributes(&ObjectAttributes
,
661 Status
= NtCreateFile(&FileHandle
,
666 FILE_ATTRIBUTE_NORMAL
,
669 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
,
672 if (!NT_SUCCESS(Status
))
674 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
678 Status
= NtWriteFile(FileHandle
,
689 /* Free the new boot sector */
690 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
697 InstallFat16BootCodeToFile(PWSTR SrcPath
,
701 OBJECT_ATTRIBUTES ObjectAttributes
;
702 IO_STATUS_BLOCK IoStatusBlock
;
706 PUCHAR OrigBootSector
;
707 PUCHAR NewBootSector
;
709 /* Allocate buffer for original bootsector */
710 OrigBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
713 if (OrigBootSector
== NULL
)
714 return(STATUS_INSUFFICIENT_RESOURCES
);
716 /* Read current boot sector into buffer */
717 RtlInitUnicodeString(&Name
,
720 InitializeObjectAttributes(&ObjectAttributes
,
722 OBJ_CASE_INSENSITIVE
,
726 Status
= NtOpenFile(&FileHandle
,
731 FILE_SYNCHRONOUS_IO_NONALERT
);
732 if (!NT_SUCCESS(Status
))
734 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
738 Status
= NtReadFile(FileHandle
,
748 if (!NT_SUCCESS(Status
))
750 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
755 /* Allocate buffer for new bootsector */
756 NewBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
759 if (NewBootSector
== NULL
)
761 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
762 return(STATUS_INSUFFICIENT_RESOURCES
);
765 /* Read new bootsector from SrcPath */
766 RtlInitUnicodeString(&Name
,
769 InitializeObjectAttributes(&ObjectAttributes
,
771 OBJ_CASE_INSENSITIVE
,
775 Status
= NtOpenFile(&FileHandle
,
780 FILE_SYNCHRONOUS_IO_NONALERT
);
781 if (!NT_SUCCESS(Status
))
783 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
784 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
788 Status
= NtReadFile(FileHandle
,
798 if (!NT_SUCCESS(Status
))
800 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
801 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
805 /* Adjust bootsector (copy a part of the FAT BPB) */
806 memcpy((NewBootSector
+ 11), (OrigBootSector
+ 11), 51 /*fat BPB length*/);
808 /* Free the original boot sector */
809 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
811 /* Write new bootsector to DstPath */
812 RtlInitUnicodeString(&Name
,
815 InitializeObjectAttributes(&ObjectAttributes
,
821 Status
= NtCreateFile(&FileHandle
,
826 FILE_ATTRIBUTE_NORMAL
,
829 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
,
832 if (!NT_SUCCESS(Status
))
834 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
839 FilePosition
.QuadPart
= 0;
841 Status
= NtWriteFile(FileHandle
,
852 /* Free the new boot sector */
853 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
860 InstallFat32BootCodeToFile(PWSTR SrcPath
,
864 OBJECT_ATTRIBUTES ObjectAttributes
;
865 IO_STATUS_BLOCK IoStatusBlock
;
869 PUCHAR OrigBootSector
;
870 PUCHAR NewBootSector
;
871 LARGE_INTEGER FileOffset
;
873 /* Allocate buffer for original bootsector */
874 OrigBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
877 if (OrigBootSector
== NULL
)
878 return(STATUS_INSUFFICIENT_RESOURCES
);
880 /* Read current boot sector into buffer */
881 RtlInitUnicodeString(&Name
,
884 InitializeObjectAttributes(&ObjectAttributes
,
886 OBJ_CASE_INSENSITIVE
,
890 Status
= NtOpenFile(&FileHandle
,
895 FILE_SYNCHRONOUS_IO_NONALERT
);
896 if (!NT_SUCCESS(Status
))
898 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
902 Status
= NtReadFile(FileHandle
,
912 if (!NT_SUCCESS(Status
))
915 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
919 /* Allocate buffer for new bootsector (2 sectors) */
920 NewBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
923 if (NewBootSector
== NULL
)
925 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
926 return(STATUS_INSUFFICIENT_RESOURCES
);
929 /* Read new bootsector from SrcPath */
930 RtlInitUnicodeString(&Name
,
933 InitializeObjectAttributes(&ObjectAttributes
,
935 OBJ_CASE_INSENSITIVE
,
939 Status
= NtOpenFile(&FileHandle
,
944 FILE_SYNCHRONOUS_IO_NONALERT
);
945 if (!NT_SUCCESS(Status
))
947 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
948 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
952 Status
= NtReadFile(FileHandle
,
962 if (!NT_SUCCESS(Status
))
964 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
965 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
969 /* Adjust bootsector (copy a part of the FAT32 BPB) */
970 memcpy((NewBootSector
+ 3),
971 (OrigBootSector
+ 3),
972 87); /* FAT32 BPB length */
974 /* Disable the backup boot sector */
975 NewBootSector
[0x32] = 0x00;
976 NewBootSector
[0x33] = 0x00;
978 /* Free the original boot sector */
979 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
981 /* Write the first sector of the new bootcode to DstPath */
982 RtlInitUnicodeString(&Name
,
985 InitializeObjectAttributes(&ObjectAttributes
,
991 Status
= NtCreateFile(&FileHandle
,
996 FILE_ATTRIBUTE_NORMAL
,
999 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
,
1002 if (!NT_SUCCESS(Status
))
1004 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1008 Status
= NtWriteFile(FileHandle
,
1017 NtClose(FileHandle
);
1018 if (!NT_SUCCESS(Status
))
1020 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1024 /* Write the second sector of the new bootcode to boot disk sector 14 */
1025 RtlInitUnicodeString(&Name
,
1028 InitializeObjectAttributes(&ObjectAttributes
,
1034 Status
= NtOpenFile(&FileHandle
,
1039 FILE_SYNCHRONOUS_IO_NONALERT
);
1040 if (!NT_SUCCESS(Status
))
1042 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1046 FileOffset
.QuadPart
= (ULONGLONG
)(14 * SECTORSIZE
);
1047 Status
= NtWriteFile(FileHandle
,
1052 (NewBootSector
+ SECTORSIZE
),
1056 if (!NT_SUCCESS(Status
))
1059 NtClose(FileHandle
);
1061 /* Free the new boot sector */
1062 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1069 InstallMbrBootCodeToDisk (PWSTR SrcPath
,
1072 OBJECT_ATTRIBUTES ObjectAttributes
;
1073 IO_STATUS_BLOCK IoStatusBlock
;
1074 UNICODE_STRING Name
;
1077 PPARTITION_SECTOR OrigBootSector
;
1078 PPARTITION_SECTOR NewBootSector
;
1080 /* Allocate buffer for original bootsector */
1081 OrigBootSector
= (PPARTITION_SECTOR
)RtlAllocateHeap(ProcessHeap
,
1083 sizeof(PARTITION_SECTOR
));
1084 if (OrigBootSector
== NULL
)
1085 return(STATUS_INSUFFICIENT_RESOURCES
);
1087 /* Read current boot sector into buffer */
1088 RtlInitUnicodeString(&Name
,
1091 InitializeObjectAttributes(&ObjectAttributes
,
1093 OBJ_CASE_INSENSITIVE
,
1097 Status
= NtOpenFile(&FileHandle
,
1102 FILE_SYNCHRONOUS_IO_NONALERT
);
1103 if (!NT_SUCCESS(Status
))
1105 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1109 Status
= NtReadFile(FileHandle
,
1118 NtClose(FileHandle
);
1119 if (!NT_SUCCESS(Status
))
1121 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1126 /* Allocate buffer for new bootsector */
1127 NewBootSector
= (PPARTITION_SECTOR
)RtlAllocateHeap(ProcessHeap
,
1129 sizeof(PARTITION_SECTOR
));
1130 if (NewBootSector
== NULL
)
1132 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1133 return(STATUS_INSUFFICIENT_RESOURCES
);
1136 /* Read new bootsector from SrcPath */
1137 RtlInitUnicodeString(&Name
,
1140 InitializeObjectAttributes(&ObjectAttributes
,
1142 OBJ_CASE_INSENSITIVE
,
1146 Status
= NtOpenFile(&FileHandle
,
1151 FILE_SYNCHRONOUS_IO_NONALERT
);
1152 if (!NT_SUCCESS(Status
))
1154 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1155 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1159 Status
= NtReadFile(FileHandle
,
1165 sizeof(PARTITION_SECTOR
),
1168 NtClose(FileHandle
);
1169 if (!NT_SUCCESS(Status
))
1171 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1172 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1176 /* Copy partition table from old MBR to new */
1177 RtlCopyMemory (&NewBootSector
->Signature
,
1178 &OrigBootSector
->Signature
,
1179 sizeof(PARTITION_SECTOR
) - offsetof(PARTITION_SECTOR
, Signature
) /* Length of partition table */);
1181 /* Free the original boot sector */
1182 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1184 /* Write new bootsector to RootPath */
1185 RtlInitUnicodeString(&Name
,
1188 InitializeObjectAttributes(&ObjectAttributes
,
1194 Status
= NtOpenFile(&FileHandle
,
1199 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1200 if (!NT_SUCCESS(Status
))
1202 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1203 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1207 Status
= NtWriteFile(FileHandle
,
1216 NtClose(FileHandle
);
1218 /* Free the new boot sector */
1219 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1226 InstallFat16BootCodeToDisk(PWSTR SrcPath
,
1229 OBJECT_ATTRIBUTES ObjectAttributes
;
1230 IO_STATUS_BLOCK IoStatusBlock
;
1231 UNICODE_STRING Name
;
1234 PUCHAR OrigBootSector
;
1235 PUCHAR NewBootSector
;
1237 /* Allocate buffer for original bootsector */
1238 OrigBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
1241 if (OrigBootSector
== NULL
)
1242 return(STATUS_INSUFFICIENT_RESOURCES
);
1244 /* Read current boot sector into buffer */
1245 RtlInitUnicodeString(&Name
,
1248 InitializeObjectAttributes(&ObjectAttributes
,
1250 OBJ_CASE_INSENSITIVE
,
1254 Status
= NtOpenFile(&FileHandle
,
1259 FILE_SYNCHRONOUS_IO_NONALERT
);
1260 if (!NT_SUCCESS(Status
))
1262 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1266 Status
= NtReadFile(FileHandle
,
1275 NtClose(FileHandle
);
1276 if (!NT_SUCCESS(Status
))
1278 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1283 /* Allocate buffer for new bootsector */
1284 NewBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
1287 if (NewBootSector
== NULL
)
1289 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1290 return(STATUS_INSUFFICIENT_RESOURCES
);
1293 /* Read new bootsector from SrcPath */
1294 RtlInitUnicodeString(&Name
,
1297 InitializeObjectAttributes(&ObjectAttributes
,
1299 OBJ_CASE_INSENSITIVE
,
1303 Status
= NtOpenFile(&FileHandle
,
1308 FILE_SYNCHRONOUS_IO_NONALERT
);
1309 if (!NT_SUCCESS(Status
))
1311 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1312 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1316 Status
= NtReadFile(FileHandle
,
1325 NtClose(FileHandle
);
1326 if (!NT_SUCCESS(Status
))
1328 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1329 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1333 /* Adjust bootsector (copy a part of the FAT16 BPB) */
1334 memcpy((NewBootSector
+ 3),
1335 (OrigBootSector
+ 3),
1336 59); /* FAT16 BPB length*/
1338 /* Free the original boot sector */
1339 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1341 /* Write new bootsector to RootPath */
1342 RtlInitUnicodeString(&Name
,
1345 InitializeObjectAttributes(&ObjectAttributes
,
1351 Status
= NtOpenFile(&FileHandle
,
1356 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1357 if (!NT_SUCCESS(Status
))
1359 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1360 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1365 FilePosition
.QuadPart
= 0;
1367 Status
= NtWriteFile(FileHandle
,
1376 NtClose(FileHandle
);
1378 /* Free the new boot sector */
1379 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1386 InstallFat32BootCodeToDisk(PWSTR SrcPath
,
1389 OBJECT_ATTRIBUTES ObjectAttributes
;
1390 IO_STATUS_BLOCK IoStatusBlock
;
1391 UNICODE_STRING Name
;
1394 PUCHAR OrigBootSector
;
1395 PUCHAR NewBootSector
;
1396 LARGE_INTEGER FileOffset
;
1397 USHORT BackupBootSector
;
1399 /* Allocate buffer for original bootsector */
1400 OrigBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
1403 if (OrigBootSector
== NULL
)
1404 return(STATUS_INSUFFICIENT_RESOURCES
);
1406 /* Read current boot sector into buffer */
1407 RtlInitUnicodeString(&Name
,
1410 InitializeObjectAttributes(&ObjectAttributes
,
1412 OBJ_CASE_INSENSITIVE
,
1416 Status
= NtOpenFile(&FileHandle
,
1421 FILE_SYNCHRONOUS_IO_NONALERT
);
1422 if (!NT_SUCCESS(Status
))
1424 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1428 Status
= NtReadFile(FileHandle
,
1437 NtClose(FileHandle
);
1438 if (!NT_SUCCESS(Status
))
1440 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1445 /* Allocate buffer for new bootsector (2 sectors) */
1446 NewBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
1449 if (NewBootSector
== NULL
)
1451 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1452 return(STATUS_INSUFFICIENT_RESOURCES
);
1455 /* Read new bootsector from SrcPath */
1456 RtlInitUnicodeString(&Name
,
1459 InitializeObjectAttributes(&ObjectAttributes
,
1461 OBJ_CASE_INSENSITIVE
,
1465 Status
= NtOpenFile(&FileHandle
,
1470 FILE_SYNCHRONOUS_IO_NONALERT
);
1471 if (!NT_SUCCESS(Status
))
1473 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1474 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1478 Status
= NtReadFile(FileHandle
,
1487 NtClose(FileHandle
);
1488 if (!NT_SUCCESS(Status
))
1490 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1491 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1495 /* Adjust bootsector (copy a part of the FAT32 BPB) */
1496 memcpy((NewBootSector
+ 3),
1497 (OrigBootSector
+ 3),
1498 87); /* FAT32 BPB length */
1500 /* Get the location of the backup boot sector */
1501 BackupBootSector
= (OrigBootSector
[0x33] << 8) + OrigBootSector
[0x32];
1503 /* Free the original boot sector */
1504 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1506 /* Write the first sector of the new bootcode to DstPath */
1507 RtlInitUnicodeString(&Name
,
1510 InitializeObjectAttributes(&ObjectAttributes
,
1516 Status
= NtOpenFile(&FileHandle
,
1521 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1522 if (!NT_SUCCESS(Status
))
1524 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1525 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1529 /* Write sector 0 */
1530 FileOffset
.QuadPart
= 0ULL;
1531 Status
= NtWriteFile(FileHandle
,
1540 if (!NT_SUCCESS(Status
))
1542 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1543 NtClose(FileHandle
);
1544 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1548 /* Write backup boot sector */
1549 if ((BackupBootSector
!= 0x0000) && (BackupBootSector
!= 0xFFFF))
1551 FileOffset
.QuadPart
= (ULONGLONG
)((ULONG
)BackupBootSector
* SECTORSIZE
);
1552 Status
= NtWriteFile(FileHandle
,
1561 if (!NT_SUCCESS(Status
))
1563 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1564 NtClose(FileHandle
);
1565 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1570 /* Write sector 14 */
1571 FileOffset
.QuadPart
= (ULONGLONG
)(14 * SECTORSIZE
);
1572 Status
= NtWriteFile(FileHandle
,
1577 (NewBootSector
+ SECTORSIZE
),
1581 if (!NT_SUCCESS(Status
))
1583 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1585 NtClose(FileHandle
);
1587 /* Free the new boot sector */
1588 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1595 UnprotectBootIni(PWSTR FileName
,
1598 UNICODE_STRING Name
;
1599 OBJECT_ATTRIBUTES ObjectAttributes
;
1600 IO_STATUS_BLOCK IoStatusBlock
;
1601 FILE_BASIC_INFORMATION FileInfo
;
1605 RtlInitUnicodeString(&Name
,
1608 InitializeObjectAttributes(&ObjectAttributes
,
1610 OBJ_CASE_INSENSITIVE
,
1614 Status
= NtOpenFile(&FileHandle
,
1615 GENERIC_READ
|GENERIC_WRITE
,
1619 FILE_SYNCHRONOUS_IO_NONALERT
);
1620 if (Status
== STATUS_NO_SUCH_FILE
)
1622 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1624 return(STATUS_SUCCESS
);
1626 if (!NT_SUCCESS(Status
))
1628 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1632 Status
= NtQueryInformationFile(FileHandle
,
1635 sizeof(FILE_BASIC_INFORMATION
),
1636 FileBasicInformation
);
1637 if (!NT_SUCCESS(Status
))
1639 DPRINT1("NtQueryInformationFile() failed (Status %lx)\n", Status
);
1640 NtClose(FileHandle
);
1644 *Attributes
= FileInfo
.FileAttributes
;
1646 /* Delete attributes SYSTEM, HIDDEN and READONLY */
1647 FileInfo
.FileAttributes
= FileInfo
.FileAttributes
&
1648 ~(FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
| FILE_ATTRIBUTE_READONLY
);
1650 Status
= NtSetInformationFile(FileHandle
,
1653 sizeof(FILE_BASIC_INFORMATION
),
1654 FileBasicInformation
);
1655 if (!NT_SUCCESS(Status
))
1657 DPRINT1("NtSetInformationFile() failed (Status %lx)\n", Status
);
1660 NtClose(FileHandle
);
1666 ProtectBootIni(PWSTR FileName
,
1669 UNICODE_STRING Name
;
1670 OBJECT_ATTRIBUTES ObjectAttributes
;
1671 IO_STATUS_BLOCK IoStatusBlock
;
1672 FILE_BASIC_INFORMATION FileInfo
;
1676 RtlInitUnicodeString(&Name
,
1679 InitializeObjectAttributes(&ObjectAttributes
,
1681 OBJ_CASE_INSENSITIVE
,
1685 Status
= NtOpenFile(&FileHandle
,
1686 GENERIC_READ
|GENERIC_WRITE
,
1690 FILE_SYNCHRONOUS_IO_NONALERT
);
1691 if (!NT_SUCCESS(Status
))
1693 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1697 Status
= NtQueryInformationFile(FileHandle
,
1700 sizeof(FILE_BASIC_INFORMATION
),
1701 FileBasicInformation
);
1702 if (!NT_SUCCESS(Status
))
1704 DPRINT1("NtQueryInformationFile() failed (Status %lx)\n", Status
);
1705 NtClose(FileHandle
);
1709 FileInfo
.FileAttributes
= FileInfo
.FileAttributes
| Attributes
;
1711 Status
= NtSetInformationFile(FileHandle
,
1714 sizeof(FILE_BASIC_INFORMATION
),
1715 FileBasicInformation
);
1716 if (!NT_SUCCESS(Status
))
1718 DPRINT1("NtSetInformationFile() failed (Status %lx)\n", Status
);
1721 NtClose(FileHandle
);
1727 UpdateBootIni(PWSTR BootIniPath
,
1731 UNICODE_STRING Name
;
1732 PINICACHE Cache
= NULL
;
1733 PINICACHESECTION Section
= NULL
;
1735 ULONG FileAttribute
;
1736 PWCHAR OldValue
= NULL
;
1738 RtlInitUnicodeString(&Name
,
1741 Status
= IniCacheLoad(&Cache
,
1744 if (!NT_SUCCESS(Status
))
1749 Section
= IniCacheGetSection(Cache
,
1750 L
"operating systems");
1751 if (Section
== NULL
)
1753 IniCacheDestroy(Cache
);
1754 return(STATUS_UNSUCCESSFUL
);
1757 /* Check - maybe record already exists */
1758 Status
= IniCacheGetKey(Section
,
1762 /* If either key was not found, or contains something else - add new one */
1763 if (!NT_SUCCESS(Status
) || wcscmp(OldValue
, EntryValue
))
1765 IniCacheInsertKey(Section
,
1772 Status
= UnprotectBootIni(BootIniPath
,
1774 if (!NT_SUCCESS(Status
))
1776 IniCacheDestroy(Cache
);
1780 Status
= IniCacheSave(Cache
,
1782 if (!NT_SUCCESS(Status
))
1784 IniCacheDestroy(Cache
);
1788 FileAttribute
|= (FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
| FILE_ATTRIBUTE_READONLY
);
1789 Status
= ProtectBootIni(BootIniPath
,
1792 IniCacheDestroy(Cache
);
1798 CheckInstallFatBootcodeToPartition(PUNICODE_STRING SystemRootPath
)
1801 if (DoesFileExist(SystemRootPath
->Buffer
, L
"ntldr") ||
1802 DoesFileExist(SystemRootPath
->Buffer
, L
"boot.ini"))
1806 else if (DoesFileExist(SystemRootPath
->Buffer
, L
"io.sys") ||
1807 DoesFileExist(SystemRootPath
->Buffer
, L
"msdos.sys"))
1818 InstallFatBootcodeToPartition(PUNICODE_STRING SystemRootPath
,
1819 PUNICODE_STRING SourceRootPath
,
1820 PUNICODE_STRING DestinationArcPath
,
1821 UCHAR PartitionType
)
1824 WCHAR SrcPath
[MAX_PATH
];
1825 WCHAR DstPath
[MAX_PATH
];
1828 /* FAT or FAT32 partition */
1829 DPRINT("System path: '%wZ'\n", SystemRootPath
);
1831 if (DoesFileExist(SystemRootPath
->Buffer
, L
"ntldr") == TRUE
||
1832 DoesFileExist(SystemRootPath
->Buffer
, L
"boot.ini") == TRUE
)
1834 /* Search root directory for 'ntldr' and 'boot.ini'. */
1835 DPRINT("Found Microsoft Windows NT/2000/XP boot loader\n");
1837 /* Copy FreeLoader to the boot partition */
1838 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
1839 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
1840 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1841 wcscat(DstPath
, L
"\\freeldr.sys");
1843 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
1844 Status
= SetupCopyFile(SrcPath
, DstPath
);
1845 if (!NT_SUCCESS(Status
))
1847 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
1851 /* Create or update freeldr.ini */
1852 if (DoesFileExist(SystemRootPath
->Buffer
, L
"freeldr.ini") == FALSE
)
1854 /* Create new 'freeldr.ini' */
1855 DPRINT1("Create new 'freeldr.ini'\n");
1856 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1857 wcscat(DstPath
, L
"\\freeldr.ini");
1859 Status
= CreateFreeLoaderIniForReactos(DstPath
,
1860 DestinationArcPath
->Buffer
);
1861 if (!NT_SUCCESS(Status
))
1863 DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status
);
1867 /* Install new bootcode */
1868 if (PartitionType
== PARTITION_FAT32
||
1869 PartitionType
== PARTITION_FAT32_XINT13
)
1871 /* Install FAT32 bootcode */
1872 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
1873 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
1874 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1875 wcscat(DstPath
, L
"\\bootsect.ros");
1877 DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, DstPath
);
1878 Status
= InstallFat32BootCodeToFile(SrcPath
,
1880 SystemRootPath
->Buffer
);
1881 if (!NT_SUCCESS(Status
))
1883 DPRINT1("InstallFat32BootCodeToFile() failed (Status %lx)\n", Status
);
1889 /* Install FAT16 bootcode */
1890 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
1891 wcscat(SrcPath
, L
"\\loader\\fat.bin");
1892 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1893 wcscat(DstPath
, L
"\\bootsect.ros");
1895 DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath
, DstPath
);
1896 Status
= InstallFat16BootCodeToFile(SrcPath
,
1898 SystemRootPath
->Buffer
);
1899 if (!NT_SUCCESS(Status
))
1901 DPRINT1("InstallFat16BootCodeToFile() failed (Status %lx)\n", Status
);
1908 /* Update existing 'freeldr.ini' */
1909 DPRINT1("Update existing 'freeldr.ini'\n");
1910 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1911 wcscat(DstPath
, L
"\\freeldr.ini");
1913 Status
= UpdateFreeLoaderIni(DstPath
,
1914 DestinationArcPath
->Buffer
);
1915 if (!NT_SUCCESS(Status
))
1917 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
1922 /* Update 'boot.ini' */
1923 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1924 wcscat(DstPath
, L
"\\boot.ini");
1926 DPRINT1("Update 'boot.ini': %S\n", DstPath
);
1927 Status
= UpdateBootIni(DstPath
,
1928 L
"C:\\bootsect.ros",
1930 if (!NT_SUCCESS(Status
))
1932 DPRINT1("UpdateBootIni() failed (Status %lx)\n", Status
);
1936 else if (DoesFileExist(SystemRootPath
->Buffer
, L
"io.sys") == TRUE
||
1937 DoesFileExist(SystemRootPath
->Buffer
, L
"msdos.sys") == TRUE
)
1939 /* Search for root directory for 'io.sys' and 'msdos.sys'. */
1940 DPRINT1("Found Microsoft DOS or Windows 9x boot loader\n");
1942 /* Copy FreeLoader to the boot partition */
1943 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
1944 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
1945 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1946 wcscat(DstPath
, L
"\\freeldr.sys");
1948 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
1949 Status
= SetupCopyFile(SrcPath
, DstPath
);
1950 if (!NT_SUCCESS(Status
))
1952 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
1956 /* Create or update 'freeldr.ini' */
1957 if (DoesFileExist(SystemRootPath
->Buffer
, L
"freeldr.ini") == FALSE
)
1959 /* Create new 'freeldr.ini' */
1960 DPRINT1("Create new 'freeldr.ini'\n");
1961 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1962 wcscat(DstPath
, L
"\\freeldr.ini");
1964 Status
= CreateFreeLoaderIniForDos(DstPath
,
1965 DestinationArcPath
->Buffer
);
1966 if (!NT_SUCCESS(Status
))
1968 DPRINT1("CreateFreeLoaderIniForDos() failed (Status %lx)\n", Status
);
1972 /* Save current bootsector as 'BOOTSECT.DOS' */
1973 wcscpy(SrcPath
, SystemRootPath
->Buffer
);
1974 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1975 wcscat(DstPath
, L
"\\bootsect.dos");
1977 DPRINT1("Save bootsector: %S ==> %S\n", SrcPath
, DstPath
);
1978 Status
= SaveCurrentBootSector(SrcPath
,
1980 if (!NT_SUCCESS(Status
))
1982 DPRINT1("SaveCurrentBootSector() failed (Status %lx)\n", Status
);
1986 /* Install new bootsector */
1987 if (PartitionType
== PARTITION_FAT32
||
1988 PartitionType
== PARTITION_FAT32_XINT13
)
1990 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
1991 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
1993 DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
1994 Status
= InstallFat32BootCodeToDisk(SrcPath
,
1995 SystemRootPath
->Buffer
);
1996 if (!NT_SUCCESS(Status
))
1998 DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)\n", Status
);
2004 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2005 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2007 DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2008 Status
= InstallFat16BootCodeToDisk(SrcPath
,
2009 SystemRootPath
->Buffer
);
2010 if (!NT_SUCCESS(Status
))
2012 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status
);
2019 /* Update existing 'freeldr.ini' */
2020 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2021 wcscat(DstPath
, L
"\\freeldr.ini");
2023 Status
= UpdateFreeLoaderIni(DstPath
,
2024 DestinationArcPath
->Buffer
);
2025 if (!NT_SUCCESS(Status
))
2027 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
2034 /* No or unknown boot loader */
2035 DPRINT1("No or unknown boot loader found\n");
2037 /* Copy FreeLoader to the boot partition */
2038 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2039 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
2040 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2041 wcscat(DstPath
, L
"\\freeldr.sys");
2043 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2044 Status
= SetupCopyFile(SrcPath
, DstPath
);
2045 if (!NT_SUCCESS(Status
))
2047 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
2051 /* Create or update 'freeldr.ini' */
2052 if (DoesFileExist(SystemRootPath
->Buffer
, L
"freeldr.ini") == FALSE
)
2054 /* Create new freeldr.ini */
2055 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2056 wcscat(DstPath
, L
"\\freeldr.ini");
2058 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2059 Status
= CreateFreeLoaderIniForReactos(DstPath
,
2060 DestinationArcPath
->Buffer
);
2061 if (!NT_SUCCESS(Status
))
2063 DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status
);
2067 /* Save current bootsector as 'BOOTSECT.OLD' */
2068 wcscpy(SrcPath
, SystemRootPath
->Buffer
);
2069 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2070 wcscat(DstPath
, L
"\\bootsect.old");
2072 DPRINT("Save bootsector: %S ==> %S\n", SrcPath
, DstPath
);
2073 Status
= SaveCurrentBootSector(SrcPath
,
2075 if (!NT_SUCCESS(Status
))
2077 DPRINT1("SaveCurrentBootSector() failed (Status %lx)\n", Status
);
2081 /* Install new bootsector */
2082 if (PartitionType
== PARTITION_FAT32
||
2083 PartitionType
== PARTITION_FAT32_XINT13
)
2085 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2086 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
2088 DPRINT("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2089 Status
= InstallFat32BootCodeToDisk(SrcPath
,
2090 SystemRootPath
->Buffer
);
2091 if (!NT_SUCCESS(Status
))
2093 DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)\n", Status
);
2099 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2100 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2102 DPRINT("Install FAT bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2103 Status
= InstallFat16BootCodeToDisk(SrcPath
,
2104 SystemRootPath
->Buffer
);
2105 if (!NT_SUCCESS(Status
))
2107 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status
);
2114 /* Update existing 'freeldr.ini' */
2115 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2116 wcscat(DstPath
, L
"\\freeldr.ini");
2118 Status
= UpdateFreeLoaderIni(DstPath
,
2119 DestinationArcPath
->Buffer
);
2120 if (!NT_SUCCESS(Status
))
2122 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
2128 return STATUS_SUCCESS
;
2130 return STATUS_NOT_IMPLEMENTED
;
2136 InstallFatBootcodeToFloppy(PUNICODE_STRING SourceRootPath
,
2137 PUNICODE_STRING DestinationArcPath
)
2140 WCHAR SrcPath
[MAX_PATH
];
2141 WCHAR DstPath
[MAX_PATH
];
2144 /* Copy FreeLoader to the boot partition */
2145 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2146 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
2148 wcscpy(DstPath
, L
"\\Device\\Floppy0\\freeldr.sys");
2150 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2151 Status
= SetupCopyFile(SrcPath
, DstPath
);
2152 if (!NT_SUCCESS(Status
))
2154 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
2158 /* Create new 'freeldr.ini' */
2159 wcscpy(DstPath
, L
"\\Device\\Floppy0\\freeldr.ini");
2161 DPRINT("Create new 'freeldr.ini'\n");
2162 Status
= CreateFreeLoaderIniForReactos(DstPath
,
2163 DestinationArcPath
->Buffer
);
2164 if (!NT_SUCCESS(Status
))
2166 DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status
);
2170 /* Install FAT12/16 boosector */
2171 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2172 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2174 wcscpy(DstPath
, L
"\\Device\\Floppy0");
2176 DPRINT("Install FAT bootcode: %S ==> %S\n", SrcPath
, DstPath
);
2177 Status
= InstallFat16BootCodeToDisk(SrcPath
,
2179 if (!NT_SUCCESS(Status
))
2181 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status
);
2185 return STATUS_SUCCESS
;
2187 return STATUS_NOT_IMPLEMENTED
;