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 CreateFreeLoaderEntry(
357 PINICACHESECTION OSSection
,
364 PINICACHESECTION IniSection
;
366 /* Insert entry into "Operating Systems" section */
367 IniCacheInsertKey(OSSection
,
373 /* Create new section */
374 IniSection
= IniCacheAppendSection(IniCache
, Section
);
377 IniCacheInsertKey(IniSection
,
384 IniCacheInsertKey(IniSection
,
391 IniCacheInsertKey(IniSection
,
397 return STATUS_SUCCESS
;
401 CreateFreeLoaderIniForReactos(PWCHAR IniPath
,
405 PINICACHESECTION IniSection
;
407 IniCache
= IniCacheCreate();
409 CreateCommonFreeLoaderSections(IniCache
);
411 /* Create "Operating Systems" section */
412 IniSection
= IniCacheAppendSection(IniCache
,
413 L
"Operating Systems");
416 CreateFreeLoaderEntry(IniCache
, IniSection
,
417 L
"ReactOS", L
"\"ReactOS\"",
418 L
"Windows2003", ArcPath
,
422 CreateFreeLoaderEntry(IniCache
, IniSection
,
423 L
"ReactOS_Debug", L
"\"ReactOS (Debug)\"",
424 L
"Windows2003", ArcPath
,
425 L
"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS");
428 /* ReactOS_KdSerial */
429 CreateFreeLoaderEntry(IniCache
, IniSection
,
430 L
"ReactOS_KdSerial", L
"\"ReactOS (RosDbg)\"",
432 L
"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /KDSERIAL");
435 CreateFreeLoaderEntry(IniCache
, IniSection
,
436 L
"ReactOS_Ram", L
"\"ReactOS (RAM Disk)\"",
437 L
"ReactOS", L
"ramdisk(0)\\ReactOS",
438 L
"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /RDIMAGEPATH=reactos.img /RDIMAGEOFFSET=32256");
442 CreateFreeLoaderEntry(IniCache
, IniSection
,
443 L
"ReactOS_old", L
"\"ReactOS (old boot method)\"",
447 /* ReactOS_Debug_old */
448 CreateFreeLoaderEntry(IniCache
, IniSection
,
449 L
"ReactOS_Debug_old", L
"\"ReactOS (Debug, old boot method)\"",
451 L
"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS");
453 /* Save the ini file */
454 IniCacheSave(IniCache
, IniPath
);
455 IniCacheDestroy(IniCache
);
457 return(STATUS_SUCCESS
);
462 UpdateFreeLoaderIni(PWCHAR IniPath
,
467 PINICACHESECTION IniSection
;
468 PINICACHESECTION OsIniSection
;
469 WCHAR SectionName
[80];
471 WCHAR SystemPath
[200];
472 WCHAR SectionName2
[200];
477 RtlInitUnicodeString(&Name
,
480 Status
= IniCacheLoad(&IniCache
,
483 if (!NT_SUCCESS(Status
))
486 /* Get "Operating Systems" section */
487 IniSection
= IniCacheGetSection(IniCache
,
488 L
"Operating Systems");
489 if (IniSection
== NULL
)
491 IniCacheDestroy(IniCache
);
492 return(STATUS_UNSUCCESSFUL
);
495 /* Find an existing usable or an unused section name */
497 wcscpy(SectionName
, L
"ReactOS");
498 wcscpy(OsName
, L
"\"ReactOS\"");
501 Status
= IniCacheGetKey(IniSection
,
504 if (!NT_SUCCESS(Status
))
507 /* Get operation system section */
508 if (KeyData
[0] == '"')
510 wcscpy(SectionName2
, &KeyData
[1]);
511 j
= wcslen(SectionName2
);
514 SectionName2
[j
-1] = 0;
519 wcscpy(SectionName2
, KeyData
);
522 OsIniSection
= IniCacheGetSection(IniCache
,
524 if (OsIniSection
!= NULL
)
526 BOOLEAN UseExistingEntry
= TRUE
;
529 Status
= IniCacheGetKey(OsIniSection
,
532 if (NT_SUCCESS(Status
))
535 || (_wcsicmp(KeyData
, L
"ReactOS") != 0
536 && _wcsicmp(KeyData
, L
"\"ReactOS\"") != 0))
538 /* This is not a ReactOS entry */
539 UseExistingEntry
= FALSE
;
544 UseExistingEntry
= FALSE
;
547 if (UseExistingEntry
)
549 /* BootType is ReactOS. Now check SystemPath */
550 Status
= IniCacheGetKey(OsIniSection
,
553 if (NT_SUCCESS(Status
))
555 swprintf(SystemPath
, L
"\"%S\"", ArcPath
);
557 || (_wcsicmp(KeyData
, ArcPath
) != 0
558 && _wcsicmp(KeyData
, SystemPath
) != 0))
560 /* This entry is a ReactOS entry, but the SystemRoot does not
561 match the one we are looking for */
562 UseExistingEntry
= FALSE
;
567 UseExistingEntry
= FALSE
;
571 if (UseExistingEntry
)
573 IniCacheDestroy(IniCache
);
574 return(STATUS_SUCCESS
);
578 swprintf(SectionName
, L
"ReactOS_%lu", i
);
579 swprintf(OsName
, L
"\"ReactOS %lu\"", i
);
583 /* <SectionName>=<OsName> */
584 IniCacheInsertKey(IniSection
,
590 /* Create <SectionName> section */
591 IniSection
= IniCacheAppendSection(IniCache
,
594 /* BootType=ReactOS */
595 IniCacheInsertKey(IniSection
,
601 /* SystemPath=<ArcPath> */
602 IniCacheInsertKey(IniSection
,
608 IniCacheSave(IniCache
, IniPath
);
609 IniCacheDestroy(IniCache
);
611 return(STATUS_SUCCESS
);
616 SaveCurrentBootSector(PWSTR RootPath
,
619 OBJECT_ATTRIBUTES ObjectAttributes
;
620 IO_STATUS_BLOCK IoStatusBlock
;
626 /* Allocate buffer for bootsector */
627 BootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
630 if (BootSector
== NULL
)
631 return(STATUS_INSUFFICIENT_RESOURCES
);
633 /* Read current boot sector into buffer */
634 RtlInitUnicodeString(&Name
,
637 InitializeObjectAttributes(&ObjectAttributes
,
639 OBJ_CASE_INSENSITIVE
,
643 Status
= NtOpenFile(&FileHandle
,
648 FILE_SYNCHRONOUS_IO_NONALERT
);
649 if (!NT_SUCCESS(Status
))
651 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
655 Status
= NtReadFile(FileHandle
,
665 if (!NT_SUCCESS(Status
))
667 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
671 /* Write bootsector to DstPath */
672 RtlInitUnicodeString(&Name
,
675 InitializeObjectAttributes(&ObjectAttributes
,
681 Status
= NtCreateFile(&FileHandle
,
686 FILE_ATTRIBUTE_NORMAL
,
689 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
,
692 if (!NT_SUCCESS(Status
))
694 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
698 Status
= NtWriteFile(FileHandle
,
709 /* Free the new boot sector */
710 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
717 InstallFat16BootCodeToFile(PWSTR SrcPath
,
721 OBJECT_ATTRIBUTES ObjectAttributes
;
722 IO_STATUS_BLOCK IoStatusBlock
;
726 PUCHAR OrigBootSector
;
727 PUCHAR NewBootSector
;
729 /* Allocate buffer for original bootsector */
730 OrigBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
733 if (OrigBootSector
== NULL
)
734 return(STATUS_INSUFFICIENT_RESOURCES
);
736 /* Read current boot sector into buffer */
737 RtlInitUnicodeString(&Name
,
740 InitializeObjectAttributes(&ObjectAttributes
,
742 OBJ_CASE_INSENSITIVE
,
746 Status
= NtOpenFile(&FileHandle
,
751 FILE_SYNCHRONOUS_IO_NONALERT
);
752 if (!NT_SUCCESS(Status
))
754 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
758 Status
= NtReadFile(FileHandle
,
768 if (!NT_SUCCESS(Status
))
770 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
775 /* Allocate buffer for new bootsector */
776 NewBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
779 if (NewBootSector
== NULL
)
781 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
782 return(STATUS_INSUFFICIENT_RESOURCES
);
785 /* Read new bootsector from SrcPath */
786 RtlInitUnicodeString(&Name
,
789 InitializeObjectAttributes(&ObjectAttributes
,
791 OBJ_CASE_INSENSITIVE
,
795 Status
= NtOpenFile(&FileHandle
,
800 FILE_SYNCHRONOUS_IO_NONALERT
);
801 if (!NT_SUCCESS(Status
))
803 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
804 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
808 Status
= NtReadFile(FileHandle
,
818 if (!NT_SUCCESS(Status
))
820 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
821 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
825 /* Adjust bootsector (copy a part of the FAT BPB) */
826 memcpy((NewBootSector
+ 11), (OrigBootSector
+ 11), 51 /*fat BPB length*/);
828 /* Free the original boot sector */
829 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
831 /* Write new bootsector to DstPath */
832 RtlInitUnicodeString(&Name
,
835 InitializeObjectAttributes(&ObjectAttributes
,
841 Status
= NtCreateFile(&FileHandle
,
846 FILE_ATTRIBUTE_NORMAL
,
849 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
,
852 if (!NT_SUCCESS(Status
))
854 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
859 FilePosition
.QuadPart
= 0;
861 Status
= NtWriteFile(FileHandle
,
872 /* Free the new boot sector */
873 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
880 InstallFat32BootCodeToFile(PWSTR SrcPath
,
884 OBJECT_ATTRIBUTES ObjectAttributes
;
885 IO_STATUS_BLOCK IoStatusBlock
;
889 PUCHAR OrigBootSector
;
890 PUCHAR NewBootSector
;
891 LARGE_INTEGER FileOffset
;
893 /* Allocate buffer for original bootsector */
894 OrigBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
897 if (OrigBootSector
== NULL
)
898 return(STATUS_INSUFFICIENT_RESOURCES
);
900 /* Read current boot sector into buffer */
901 RtlInitUnicodeString(&Name
,
904 InitializeObjectAttributes(&ObjectAttributes
,
906 OBJ_CASE_INSENSITIVE
,
910 Status
= NtOpenFile(&FileHandle
,
915 FILE_SYNCHRONOUS_IO_NONALERT
);
916 if (!NT_SUCCESS(Status
))
918 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
922 Status
= NtReadFile(FileHandle
,
932 if (!NT_SUCCESS(Status
))
934 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
938 /* Allocate buffer for new bootsector (2 sectors) */
939 NewBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
942 if (NewBootSector
== NULL
)
944 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
945 return(STATUS_INSUFFICIENT_RESOURCES
);
948 /* Read new bootsector from SrcPath */
949 RtlInitUnicodeString(&Name
,
952 InitializeObjectAttributes(&ObjectAttributes
,
954 OBJ_CASE_INSENSITIVE
,
958 Status
= NtOpenFile(&FileHandle
,
963 FILE_SYNCHRONOUS_IO_NONALERT
);
964 if (!NT_SUCCESS(Status
))
966 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
967 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
971 Status
= NtReadFile(FileHandle
,
981 if (!NT_SUCCESS(Status
))
983 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
984 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
988 /* Adjust bootsector (copy a part of the FAT32 BPB) */
989 memcpy((NewBootSector
+ 3),
990 (OrigBootSector
+ 3),
991 87); /* FAT32 BPB length */
993 /* Disable the backup boot sector */
994 NewBootSector
[0x32] = 0x00;
995 NewBootSector
[0x33] = 0x00;
997 /* Free the original boot sector */
998 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1000 /* Write the first sector of the new bootcode to DstPath */
1001 RtlInitUnicodeString(&Name
,
1004 InitializeObjectAttributes(&ObjectAttributes
,
1010 Status
= NtCreateFile(&FileHandle
,
1015 FILE_ATTRIBUTE_NORMAL
,
1018 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
,
1021 if (!NT_SUCCESS(Status
))
1023 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1027 Status
= NtWriteFile(FileHandle
,
1036 NtClose(FileHandle
);
1037 if (!NT_SUCCESS(Status
))
1039 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1043 /* Write the second sector of the new bootcode to boot disk sector 14 */
1044 RtlInitUnicodeString(&Name
,
1047 InitializeObjectAttributes(&ObjectAttributes
,
1053 Status
= NtOpenFile(&FileHandle
,
1058 FILE_SYNCHRONOUS_IO_NONALERT
);
1059 if (!NT_SUCCESS(Status
))
1061 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1065 FileOffset
.QuadPart
= (ULONGLONG
)(14 * SECTORSIZE
);
1066 Status
= NtWriteFile(FileHandle
,
1071 (NewBootSector
+ SECTORSIZE
),
1075 if (!NT_SUCCESS(Status
))
1078 NtClose(FileHandle
);
1080 /* Free the new boot sector */
1081 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1088 InstallMbrBootCodeToDisk (PWSTR SrcPath
,
1091 OBJECT_ATTRIBUTES ObjectAttributes
;
1092 IO_STATUS_BLOCK IoStatusBlock
;
1093 UNICODE_STRING Name
;
1096 PPARTITION_SECTOR OrigBootSector
;
1097 PPARTITION_SECTOR NewBootSector
;
1099 /* Allocate buffer for original bootsector */
1100 OrigBootSector
= (PPARTITION_SECTOR
)RtlAllocateHeap(ProcessHeap
,
1102 sizeof(PARTITION_SECTOR
));
1103 if (OrigBootSector
== NULL
)
1104 return(STATUS_INSUFFICIENT_RESOURCES
);
1106 /* Read current boot sector into buffer */
1107 RtlInitUnicodeString(&Name
,
1110 InitializeObjectAttributes(&ObjectAttributes
,
1112 OBJ_CASE_INSENSITIVE
,
1116 Status
= NtOpenFile(&FileHandle
,
1121 FILE_SYNCHRONOUS_IO_NONALERT
);
1122 if (!NT_SUCCESS(Status
))
1124 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1128 Status
= NtReadFile(FileHandle
,
1137 NtClose(FileHandle
);
1138 if (!NT_SUCCESS(Status
))
1140 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1145 /* Allocate buffer for new bootsector */
1146 NewBootSector
= (PPARTITION_SECTOR
)RtlAllocateHeap(ProcessHeap
,
1148 sizeof(PARTITION_SECTOR
));
1149 if (NewBootSector
== NULL
)
1151 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1152 return(STATUS_INSUFFICIENT_RESOURCES
);
1155 /* Read new bootsector from SrcPath */
1156 RtlInitUnicodeString(&Name
,
1159 InitializeObjectAttributes(&ObjectAttributes
,
1161 OBJ_CASE_INSENSITIVE
,
1165 Status
= NtOpenFile(&FileHandle
,
1170 FILE_SYNCHRONOUS_IO_NONALERT
);
1171 if (!NT_SUCCESS(Status
))
1173 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1174 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1178 Status
= NtReadFile(FileHandle
,
1184 sizeof(PARTITION_SECTOR
),
1187 NtClose(FileHandle
);
1188 if (!NT_SUCCESS(Status
))
1190 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1191 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1195 /* Copy partition table from old MBR to new */
1196 RtlCopyMemory (&NewBootSector
->Signature
,
1197 &OrigBootSector
->Signature
,
1198 sizeof(PARTITION_SECTOR
) - offsetof(PARTITION_SECTOR
, Signature
) /* Length of partition table */);
1200 /* Free the original boot sector */
1201 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1203 /* Write new bootsector to RootPath */
1204 RtlInitUnicodeString(&Name
,
1207 InitializeObjectAttributes(&ObjectAttributes
,
1213 Status
= NtOpenFile(&FileHandle
,
1218 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1219 if (!NT_SUCCESS(Status
))
1221 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1222 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1226 Status
= NtWriteFile(FileHandle
,
1235 NtClose(FileHandle
);
1237 /* Free the new boot sector */
1238 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1245 InstallFat16BootCodeToDisk(PWSTR SrcPath
,
1248 OBJECT_ATTRIBUTES ObjectAttributes
;
1249 IO_STATUS_BLOCK IoStatusBlock
;
1250 UNICODE_STRING Name
;
1253 PUCHAR OrigBootSector
;
1254 PUCHAR NewBootSector
;
1256 /* Allocate buffer for original bootsector */
1257 OrigBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
1260 if (OrigBootSector
== NULL
)
1261 return(STATUS_INSUFFICIENT_RESOURCES
);
1263 /* Read current boot sector into buffer */
1264 RtlInitUnicodeString(&Name
,
1267 InitializeObjectAttributes(&ObjectAttributes
,
1269 OBJ_CASE_INSENSITIVE
,
1273 Status
= NtOpenFile(&FileHandle
,
1278 FILE_SYNCHRONOUS_IO_NONALERT
);
1279 if (!NT_SUCCESS(Status
))
1281 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1285 Status
= NtReadFile(FileHandle
,
1294 NtClose(FileHandle
);
1295 if (!NT_SUCCESS(Status
))
1297 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1302 /* Allocate buffer for new bootsector */
1303 NewBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
1306 if (NewBootSector
== NULL
)
1308 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1309 return(STATUS_INSUFFICIENT_RESOURCES
);
1312 /* Read new bootsector from SrcPath */
1313 RtlInitUnicodeString(&Name
,
1316 InitializeObjectAttributes(&ObjectAttributes
,
1318 OBJ_CASE_INSENSITIVE
,
1322 Status
= NtOpenFile(&FileHandle
,
1327 FILE_SYNCHRONOUS_IO_NONALERT
);
1328 if (!NT_SUCCESS(Status
))
1330 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1331 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1335 Status
= NtReadFile(FileHandle
,
1344 NtClose(FileHandle
);
1345 if (!NT_SUCCESS(Status
))
1347 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1348 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1352 /* Adjust bootsector (copy a part of the FAT16 BPB) */
1353 memcpy((NewBootSector
+ 3),
1354 (OrigBootSector
+ 3),
1355 59); /* FAT16 BPB length*/
1357 /* Free the original boot sector */
1358 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1360 /* Write new bootsector to RootPath */
1361 RtlInitUnicodeString(&Name
,
1364 InitializeObjectAttributes(&ObjectAttributes
,
1370 Status
= NtOpenFile(&FileHandle
,
1375 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1376 if (!NT_SUCCESS(Status
))
1378 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1379 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1384 FilePosition
.QuadPart
= 0;
1386 Status
= NtWriteFile(FileHandle
,
1395 NtClose(FileHandle
);
1397 /* Free the new boot sector */
1398 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1405 InstallFat32BootCodeToDisk(PWSTR SrcPath
,
1408 OBJECT_ATTRIBUTES ObjectAttributes
;
1409 IO_STATUS_BLOCK IoStatusBlock
;
1410 UNICODE_STRING Name
;
1413 PUCHAR OrigBootSector
;
1414 PUCHAR NewBootSector
;
1415 LARGE_INTEGER FileOffset
;
1416 USHORT BackupBootSector
;
1418 /* Allocate buffer for original bootsector */
1419 OrigBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
1422 if (OrigBootSector
== NULL
)
1423 return(STATUS_INSUFFICIENT_RESOURCES
);
1425 /* Read current boot sector into buffer */
1426 RtlInitUnicodeString(&Name
,
1429 InitializeObjectAttributes(&ObjectAttributes
,
1431 OBJ_CASE_INSENSITIVE
,
1435 Status
= NtOpenFile(&FileHandle
,
1440 FILE_SYNCHRONOUS_IO_NONALERT
);
1441 if (!NT_SUCCESS(Status
))
1443 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1447 Status
= NtReadFile(FileHandle
,
1456 NtClose(FileHandle
);
1457 if (!NT_SUCCESS(Status
))
1459 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1464 /* Allocate buffer for new bootsector (2 sectors) */
1465 NewBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
1468 if (NewBootSector
== NULL
)
1470 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1471 return(STATUS_INSUFFICIENT_RESOURCES
);
1474 /* Read new bootsector from SrcPath */
1475 RtlInitUnicodeString(&Name
,
1478 InitializeObjectAttributes(&ObjectAttributes
,
1480 OBJ_CASE_INSENSITIVE
,
1484 Status
= NtOpenFile(&FileHandle
,
1489 FILE_SYNCHRONOUS_IO_NONALERT
);
1490 if (!NT_SUCCESS(Status
))
1492 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1493 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1497 Status
= NtReadFile(FileHandle
,
1506 NtClose(FileHandle
);
1507 if (!NT_SUCCESS(Status
))
1509 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1510 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1514 /* Adjust bootsector (copy a part of the FAT32 BPB) */
1515 memcpy((NewBootSector
+ 3),
1516 (OrigBootSector
+ 3),
1517 87); /* FAT32 BPB length */
1519 /* Get the location of the backup boot sector */
1520 BackupBootSector
= (OrigBootSector
[0x33] << 8) + OrigBootSector
[0x32];
1522 /* Free the original boot sector */
1523 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1525 /* Write the first sector of the new bootcode to DstPath */
1526 RtlInitUnicodeString(&Name
,
1529 InitializeObjectAttributes(&ObjectAttributes
,
1535 Status
= NtOpenFile(&FileHandle
,
1540 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1541 if (!NT_SUCCESS(Status
))
1543 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1544 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1548 /* Write sector 0 */
1549 FileOffset
.QuadPart
= 0ULL;
1550 Status
= NtWriteFile(FileHandle
,
1559 if (!NT_SUCCESS(Status
))
1561 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1562 NtClose(FileHandle
);
1563 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1567 /* Write backup boot sector */
1568 if ((BackupBootSector
!= 0x0000) && (BackupBootSector
!= 0xFFFF))
1570 FileOffset
.QuadPart
= (ULONGLONG
)((ULONG
)BackupBootSector
* SECTORSIZE
);
1571 Status
= NtWriteFile(FileHandle
,
1580 if (!NT_SUCCESS(Status
))
1582 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1583 NtClose(FileHandle
);
1584 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1589 /* Write sector 14 */
1590 FileOffset
.QuadPart
= (ULONGLONG
)(14 * SECTORSIZE
);
1591 Status
= NtWriteFile(FileHandle
,
1596 (NewBootSector
+ SECTORSIZE
),
1600 if (!NT_SUCCESS(Status
))
1602 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1604 NtClose(FileHandle
);
1606 /* Free the new boot sector */
1607 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1614 UnprotectBootIni(PWSTR FileName
,
1617 UNICODE_STRING Name
;
1618 OBJECT_ATTRIBUTES ObjectAttributes
;
1619 IO_STATUS_BLOCK IoStatusBlock
;
1620 FILE_BASIC_INFORMATION FileInfo
;
1624 RtlInitUnicodeString(&Name
,
1627 InitializeObjectAttributes(&ObjectAttributes
,
1629 OBJ_CASE_INSENSITIVE
,
1633 Status
= NtOpenFile(&FileHandle
,
1634 GENERIC_READ
|GENERIC_WRITE
,
1638 FILE_SYNCHRONOUS_IO_NONALERT
);
1639 if (Status
== STATUS_NO_SUCH_FILE
)
1641 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1643 return(STATUS_SUCCESS
);
1645 if (!NT_SUCCESS(Status
))
1647 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1651 Status
= NtQueryInformationFile(FileHandle
,
1654 sizeof(FILE_BASIC_INFORMATION
),
1655 FileBasicInformation
);
1656 if (!NT_SUCCESS(Status
))
1658 DPRINT1("NtQueryInformationFile() failed (Status %lx)\n", Status
);
1659 NtClose(FileHandle
);
1663 *Attributes
= FileInfo
.FileAttributes
;
1665 /* Delete attributes SYSTEM, HIDDEN and READONLY */
1666 FileInfo
.FileAttributes
= FileInfo
.FileAttributes
&
1667 ~(FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
| FILE_ATTRIBUTE_READONLY
);
1669 Status
= NtSetInformationFile(FileHandle
,
1672 sizeof(FILE_BASIC_INFORMATION
),
1673 FileBasicInformation
);
1674 if (!NT_SUCCESS(Status
))
1676 DPRINT1("NtSetInformationFile() failed (Status %lx)\n", Status
);
1679 NtClose(FileHandle
);
1685 ProtectBootIni(PWSTR FileName
,
1688 UNICODE_STRING Name
;
1689 OBJECT_ATTRIBUTES ObjectAttributes
;
1690 IO_STATUS_BLOCK IoStatusBlock
;
1691 FILE_BASIC_INFORMATION FileInfo
;
1695 RtlInitUnicodeString(&Name
,
1698 InitializeObjectAttributes(&ObjectAttributes
,
1700 OBJ_CASE_INSENSITIVE
,
1704 Status
= NtOpenFile(&FileHandle
,
1705 GENERIC_READ
|GENERIC_WRITE
,
1709 FILE_SYNCHRONOUS_IO_NONALERT
);
1710 if (!NT_SUCCESS(Status
))
1712 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1716 Status
= NtQueryInformationFile(FileHandle
,
1719 sizeof(FILE_BASIC_INFORMATION
),
1720 FileBasicInformation
);
1721 if (!NT_SUCCESS(Status
))
1723 DPRINT1("NtQueryInformationFile() failed (Status %lx)\n", Status
);
1724 NtClose(FileHandle
);
1728 FileInfo
.FileAttributes
= FileInfo
.FileAttributes
| Attributes
;
1730 Status
= NtSetInformationFile(FileHandle
,
1733 sizeof(FILE_BASIC_INFORMATION
),
1734 FileBasicInformation
);
1735 if (!NT_SUCCESS(Status
))
1737 DPRINT1("NtSetInformationFile() failed (Status %lx)\n", Status
);
1740 NtClose(FileHandle
);
1746 UpdateBootIni(PWSTR BootIniPath
,
1750 UNICODE_STRING Name
;
1751 PINICACHE Cache
= NULL
;
1752 PINICACHESECTION Section
= NULL
;
1754 ULONG FileAttribute
;
1755 PWCHAR OldValue
= NULL
;
1757 RtlInitUnicodeString(&Name
,
1760 Status
= IniCacheLoad(&Cache
,
1763 if (!NT_SUCCESS(Status
))
1768 Section
= IniCacheGetSection(Cache
,
1769 L
"operating systems");
1770 if (Section
== NULL
)
1772 IniCacheDestroy(Cache
);
1773 return(STATUS_UNSUCCESSFUL
);
1776 /* Check - maybe record already exists */
1777 Status
= IniCacheGetKey(Section
,
1781 /* If either key was not found, or contains something else - add new one */
1782 if (!NT_SUCCESS(Status
) || wcscmp(OldValue
, EntryValue
))
1784 IniCacheInsertKey(Section
,
1791 Status
= UnprotectBootIni(BootIniPath
,
1793 if (!NT_SUCCESS(Status
))
1795 IniCacheDestroy(Cache
);
1799 Status
= IniCacheSave(Cache
,
1801 if (!NT_SUCCESS(Status
))
1803 IniCacheDestroy(Cache
);
1807 FileAttribute
|= (FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
| FILE_ATTRIBUTE_READONLY
);
1808 Status
= ProtectBootIni(BootIniPath
,
1811 IniCacheDestroy(Cache
);
1817 CheckInstallFatBootcodeToPartition(PUNICODE_STRING SystemRootPath
)
1820 if (DoesFileExist(SystemRootPath
->Buffer
, L
"ntldr") ||
1821 DoesFileExist(SystemRootPath
->Buffer
, L
"boot.ini"))
1825 else if (DoesFileExist(SystemRootPath
->Buffer
, L
"io.sys") ||
1826 DoesFileExist(SystemRootPath
->Buffer
, L
"msdos.sys"))
1837 InstallFatBootcodeToPartition(PUNICODE_STRING SystemRootPath
,
1838 PUNICODE_STRING SourceRootPath
,
1839 PUNICODE_STRING DestinationArcPath
,
1840 UCHAR PartitionType
)
1843 WCHAR SrcPath
[MAX_PATH
];
1844 WCHAR DstPath
[MAX_PATH
];
1847 /* FAT or FAT32 partition */
1848 DPRINT("System path: '%wZ'\n", SystemRootPath
);
1850 if (DoesFileExist(SystemRootPath
->Buffer
, L
"ntldr") == TRUE
||
1851 DoesFileExist(SystemRootPath
->Buffer
, L
"boot.ini") == TRUE
)
1853 /* Search root directory for 'ntldr' and 'boot.ini'. */
1854 DPRINT("Found Microsoft Windows NT/2000/XP boot loader\n");
1856 /* Copy FreeLoader to the boot partition */
1857 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
1858 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
1859 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1860 wcscat(DstPath
, L
"\\freeldr.sys");
1862 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
1863 Status
= SetupCopyFile(SrcPath
, DstPath
);
1864 if (!NT_SUCCESS(Status
))
1866 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
1870 /* Create or update freeldr.ini */
1871 if (DoesFileExist(SystemRootPath
->Buffer
, L
"freeldr.ini") == FALSE
)
1873 /* Create new 'freeldr.ini' */
1874 DPRINT1("Create new 'freeldr.ini'\n");
1875 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1876 wcscat(DstPath
, L
"\\freeldr.ini");
1878 Status
= CreateFreeLoaderIniForReactos(DstPath
,
1879 DestinationArcPath
->Buffer
);
1880 if (!NT_SUCCESS(Status
))
1882 DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status
);
1886 /* Install new bootcode */
1887 if (PartitionType
== PARTITION_FAT32
||
1888 PartitionType
== PARTITION_FAT32_XINT13
)
1890 /* Install FAT32 bootcode */
1891 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
1892 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
1893 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1894 wcscat(DstPath
, L
"\\bootsect.ros");
1896 DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, DstPath
);
1897 Status
= InstallFat32BootCodeToFile(SrcPath
,
1899 SystemRootPath
->Buffer
);
1900 if (!NT_SUCCESS(Status
))
1902 DPRINT1("InstallFat32BootCodeToFile() failed (Status %lx)\n", Status
);
1908 /* Install FAT16 bootcode */
1909 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
1910 wcscat(SrcPath
, L
"\\loader\\fat.bin");
1911 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1912 wcscat(DstPath
, L
"\\bootsect.ros");
1914 DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath
, DstPath
);
1915 Status
= InstallFat16BootCodeToFile(SrcPath
,
1917 SystemRootPath
->Buffer
);
1918 if (!NT_SUCCESS(Status
))
1920 DPRINT1("InstallFat16BootCodeToFile() failed (Status %lx)\n", Status
);
1927 /* Update existing 'freeldr.ini' */
1928 DPRINT1("Update existing 'freeldr.ini'\n");
1929 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1930 wcscat(DstPath
, L
"\\freeldr.ini");
1932 Status
= UpdateFreeLoaderIni(DstPath
,
1933 DestinationArcPath
->Buffer
);
1934 if (!NT_SUCCESS(Status
))
1936 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
1941 /* Update 'boot.ini' */
1942 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1943 wcscat(DstPath
, L
"\\boot.ini");
1945 DPRINT1("Update 'boot.ini': %S\n", DstPath
);
1946 Status
= UpdateBootIni(DstPath
,
1947 L
"C:\\bootsect.ros",
1949 if (!NT_SUCCESS(Status
))
1951 DPRINT1("UpdateBootIni() failed (Status %lx)\n", Status
);
1955 else if (DoesFileExist(SystemRootPath
->Buffer
, L
"io.sys") == TRUE
||
1956 DoesFileExist(SystemRootPath
->Buffer
, L
"msdos.sys") == TRUE
)
1958 /* Search for root directory for 'io.sys' and 'msdos.sys'. */
1959 DPRINT1("Found Microsoft DOS or Windows 9x boot loader\n");
1961 /* Copy FreeLoader to the boot partition */
1962 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
1963 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
1964 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1965 wcscat(DstPath
, L
"\\freeldr.sys");
1967 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
1968 Status
= SetupCopyFile(SrcPath
, DstPath
);
1969 if (!NT_SUCCESS(Status
))
1971 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
1975 /* Create or update 'freeldr.ini' */
1976 if (DoesFileExist(SystemRootPath
->Buffer
, L
"freeldr.ini") == FALSE
)
1978 /* Create new 'freeldr.ini' */
1979 DPRINT1("Create new 'freeldr.ini'\n");
1980 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1981 wcscat(DstPath
, L
"\\freeldr.ini");
1983 Status
= CreateFreeLoaderIniForDos(DstPath
,
1984 DestinationArcPath
->Buffer
);
1985 if (!NT_SUCCESS(Status
))
1987 DPRINT1("CreateFreeLoaderIniForDos() failed (Status %lx)\n", Status
);
1991 /* Save current bootsector as 'BOOTSECT.DOS' */
1992 wcscpy(SrcPath
, SystemRootPath
->Buffer
);
1993 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1994 wcscat(DstPath
, L
"\\bootsect.dos");
1996 DPRINT1("Save bootsector: %S ==> %S\n", SrcPath
, DstPath
);
1997 Status
= SaveCurrentBootSector(SrcPath
,
1999 if (!NT_SUCCESS(Status
))
2001 DPRINT1("SaveCurrentBootSector() failed (Status %lx)\n", Status
);
2005 /* Install new bootsector */
2006 if (PartitionType
== PARTITION_FAT32
||
2007 PartitionType
== PARTITION_FAT32_XINT13
)
2009 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2010 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
2012 DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2013 Status
= InstallFat32BootCodeToDisk(SrcPath
,
2014 SystemRootPath
->Buffer
);
2015 if (!NT_SUCCESS(Status
))
2017 DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)\n", Status
);
2023 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2024 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2026 DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2027 Status
= InstallFat16BootCodeToDisk(SrcPath
,
2028 SystemRootPath
->Buffer
);
2029 if (!NT_SUCCESS(Status
))
2031 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status
);
2038 /* Update existing 'freeldr.ini' */
2039 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2040 wcscat(DstPath
, L
"\\freeldr.ini");
2042 Status
= UpdateFreeLoaderIni(DstPath
,
2043 DestinationArcPath
->Buffer
);
2044 if (!NT_SUCCESS(Status
))
2046 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
2053 /* No or unknown boot loader */
2054 DPRINT1("No or unknown boot loader found\n");
2056 /* Copy FreeLoader to the boot partition */
2057 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2058 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
2059 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2060 wcscat(DstPath
, L
"\\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 or update 'freeldr.ini' */
2071 if (DoesFileExist(SystemRootPath
->Buffer
, L
"freeldr.ini") == FALSE
)
2073 /* Create new freeldr.ini */
2074 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2075 wcscat(DstPath
, L
"\\freeldr.ini");
2077 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2078 Status
= CreateFreeLoaderIniForReactos(DstPath
,
2079 DestinationArcPath
->Buffer
);
2080 if (!NT_SUCCESS(Status
))
2082 DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status
);
2086 /* Save current bootsector as 'BOOTSECT.OLD' */
2087 wcscpy(SrcPath
, SystemRootPath
->Buffer
);
2088 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2089 wcscat(DstPath
, L
"\\bootsect.old");
2091 DPRINT("Save bootsector: %S ==> %S\n", SrcPath
, DstPath
);
2092 Status
= SaveCurrentBootSector(SrcPath
,
2094 if (!NT_SUCCESS(Status
))
2096 DPRINT1("SaveCurrentBootSector() failed (Status %lx)\n", Status
);
2100 /* Install new bootsector */
2101 if (PartitionType
== PARTITION_FAT32
||
2102 PartitionType
== PARTITION_FAT32_XINT13
)
2104 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2105 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
2107 DPRINT("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2108 Status
= InstallFat32BootCodeToDisk(SrcPath
,
2109 SystemRootPath
->Buffer
);
2110 if (!NT_SUCCESS(Status
))
2112 DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)\n", Status
);
2118 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2119 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2121 DPRINT("Install FAT bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2122 Status
= InstallFat16BootCodeToDisk(SrcPath
,
2123 SystemRootPath
->Buffer
);
2124 if (!NT_SUCCESS(Status
))
2126 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status
);
2133 /* Update existing 'freeldr.ini' */
2134 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2135 wcscat(DstPath
, L
"\\freeldr.ini");
2137 Status
= UpdateFreeLoaderIni(DstPath
,
2138 DestinationArcPath
->Buffer
);
2139 if (!NT_SUCCESS(Status
))
2141 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
2147 return STATUS_SUCCESS
;
2149 return STATUS_NOT_IMPLEMENTED
;
2155 InstallFatBootcodeToFloppy(PUNICODE_STRING SourceRootPath
,
2156 PUNICODE_STRING DestinationArcPath
)
2159 WCHAR SrcPath
[MAX_PATH
];
2160 WCHAR DstPath
[MAX_PATH
];
2163 /* Copy FreeLoader to the boot partition */
2164 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2165 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
2167 wcscpy(DstPath
, L
"\\Device\\Floppy0\\freeldr.sys");
2169 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2170 Status
= SetupCopyFile(SrcPath
, DstPath
);
2171 if (!NT_SUCCESS(Status
))
2173 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
2177 /* Create new 'freeldr.ini' */
2178 wcscpy(DstPath
, L
"\\Device\\Floppy0\\freeldr.ini");
2180 DPRINT("Create new 'freeldr.ini'\n");
2181 Status
= CreateFreeLoaderIniForReactos(DstPath
,
2182 DestinationArcPath
->Buffer
);
2183 if (!NT_SUCCESS(Status
))
2185 DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status
);
2189 /* Install FAT12/16 boosector */
2190 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2191 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2193 wcscpy(DstPath
, L
"\\Device\\Floppy0");
2195 DPRINT("Install FAT bootcode: %S ==> %S\n", SrcPath
, DstPath
);
2196 Status
= InstallFat16BootCodeToDisk(SrcPath
,
2198 if (!NT_SUCCESS(Status
))
2200 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status
);
2204 return STATUS_SUCCESS
;
2206 return STATUS_NOT_IMPLEMENTED
;