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\"",
422 CreateFreeLoaderEntry(IniCache
, IniSection
,
423 L
"ReactOS_Debug", L
"\"ReactOS (Debug)\"",
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_WinLdr", L
"\"ReactOS (WinLdr)\"",
437 L
"Windows2003", ArcPath
,
438 L
"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS");
441 CreateFreeLoaderEntry(IniCache
, IniSection
,
442 L
"ReactOS_Ram", L
"\"ReactOS (RAM Disk)\"",
443 L
"ReactOS", L
"ramdisk(0)\\ReactOS",
444 L
"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /RDIMAGEPATH=reactos.img /RDIMAGEOFFSET=32256");
447 /* Save the ini file */
448 IniCacheSave(IniCache
, IniPath
);
449 IniCacheDestroy(IniCache
);
451 return(STATUS_SUCCESS
);
456 UpdateFreeLoaderIni(PWCHAR IniPath
,
461 PINICACHESECTION IniSection
;
462 PINICACHESECTION OsIniSection
;
463 WCHAR SectionName
[80];
465 WCHAR SystemPath
[200];
466 WCHAR SectionName2
[200];
471 RtlInitUnicodeString(&Name
,
474 Status
= IniCacheLoad(&IniCache
,
477 if (!NT_SUCCESS(Status
))
480 /* Get "Operating Systems" section */
481 IniSection
= IniCacheGetSection(IniCache
,
482 L
"Operating Systems");
483 if (IniSection
== NULL
)
485 IniCacheDestroy(IniCache
);
486 return(STATUS_UNSUCCESSFUL
);
489 /* Find an existing usable or an unused section name */
491 wcscpy(SectionName
, L
"ReactOS");
492 wcscpy(OsName
, L
"\"ReactOS\"");
495 Status
= IniCacheGetKey(IniSection
,
498 if (!NT_SUCCESS(Status
))
501 /* Get operation system section */
502 if (KeyData
[0] == '"')
504 wcscpy(SectionName2
, &KeyData
[1]);
505 j
= wcslen(SectionName2
);
508 SectionName2
[j
-1] = 0;
513 wcscpy(SectionName2
, KeyData
);
516 OsIniSection
= IniCacheGetSection(IniCache
,
518 if (OsIniSection
!= NULL
)
520 BOOLEAN UseExistingEntry
= TRUE
;
523 Status
= IniCacheGetKey(OsIniSection
,
526 if (NT_SUCCESS(Status
))
529 || (_wcsicmp(KeyData
, L
"ReactOS") != 0
530 && _wcsicmp(KeyData
, L
"\"ReactOS\"") != 0))
532 /* This is not a ReactOS entry */
533 UseExistingEntry
= FALSE
;
538 UseExistingEntry
= FALSE
;
541 if (UseExistingEntry
)
543 /* BootType is ReactOS. Now check SystemPath */
544 Status
= IniCacheGetKey(OsIniSection
,
547 if (NT_SUCCESS(Status
))
549 swprintf(SystemPath
, L
"\"%S\"", ArcPath
);
551 || (_wcsicmp(KeyData
, ArcPath
) != 0
552 && _wcsicmp(KeyData
, SystemPath
) != 0))
554 /* This entry is a ReactOS entry, but the SystemRoot does not
555 match the one we are looking for */
556 UseExistingEntry
= FALSE
;
561 UseExistingEntry
= FALSE
;
565 if (UseExistingEntry
)
567 IniCacheDestroy(IniCache
);
568 return(STATUS_SUCCESS
);
572 swprintf(SectionName
, L
"ReactOS_%lu", i
);
573 swprintf(OsName
, L
"\"ReactOS %lu\"", i
);
577 /* <SectionName>=<OsName> */
578 IniCacheInsertKey(IniSection
,
584 /* Create <SectionName> section */
585 IniSection
= IniCacheAppendSection(IniCache
,
588 /* BootType=ReactOS */
589 IniCacheInsertKey(IniSection
,
595 /* SystemPath=<ArcPath> */
596 IniCacheInsertKey(IniSection
,
602 IniCacheSave(IniCache
, IniPath
);
603 IniCacheDestroy(IniCache
);
605 return(STATUS_SUCCESS
);
610 SaveCurrentBootSector(PWSTR RootPath
,
613 OBJECT_ATTRIBUTES ObjectAttributes
;
614 IO_STATUS_BLOCK IoStatusBlock
;
620 /* Allocate buffer for bootsector */
621 BootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
624 if (BootSector
== NULL
)
625 return(STATUS_INSUFFICIENT_RESOURCES
);
627 /* Read current boot sector into buffer */
628 RtlInitUnicodeString(&Name
,
631 InitializeObjectAttributes(&ObjectAttributes
,
633 OBJ_CASE_INSENSITIVE
,
637 Status
= NtOpenFile(&FileHandle
,
642 FILE_SYNCHRONOUS_IO_NONALERT
);
643 if (!NT_SUCCESS(Status
))
645 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
649 Status
= NtReadFile(FileHandle
,
659 if (!NT_SUCCESS(Status
))
661 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
665 /* Write bootsector to DstPath */
666 RtlInitUnicodeString(&Name
,
669 InitializeObjectAttributes(&ObjectAttributes
,
675 Status
= NtCreateFile(&FileHandle
,
680 FILE_ATTRIBUTE_NORMAL
,
683 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
,
686 if (!NT_SUCCESS(Status
))
688 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
692 Status
= NtWriteFile(FileHandle
,
703 /* Free the new boot sector */
704 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
711 InstallFat16BootCodeToFile(PWSTR SrcPath
,
715 OBJECT_ATTRIBUTES ObjectAttributes
;
716 IO_STATUS_BLOCK IoStatusBlock
;
720 PUCHAR OrigBootSector
;
721 PUCHAR NewBootSector
;
723 /* Allocate buffer for original bootsector */
724 OrigBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
727 if (OrigBootSector
== NULL
)
728 return(STATUS_INSUFFICIENT_RESOURCES
);
730 /* Read current boot sector into buffer */
731 RtlInitUnicodeString(&Name
,
734 InitializeObjectAttributes(&ObjectAttributes
,
736 OBJ_CASE_INSENSITIVE
,
740 Status
= NtOpenFile(&FileHandle
,
745 FILE_SYNCHRONOUS_IO_NONALERT
);
746 if (!NT_SUCCESS(Status
))
748 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
752 Status
= NtReadFile(FileHandle
,
762 if (!NT_SUCCESS(Status
))
764 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
769 /* Allocate buffer for new bootsector */
770 NewBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
773 if (NewBootSector
== NULL
)
775 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
776 return(STATUS_INSUFFICIENT_RESOURCES
);
779 /* Read new bootsector from SrcPath */
780 RtlInitUnicodeString(&Name
,
783 InitializeObjectAttributes(&ObjectAttributes
,
785 OBJ_CASE_INSENSITIVE
,
789 Status
= NtOpenFile(&FileHandle
,
794 FILE_SYNCHRONOUS_IO_NONALERT
);
795 if (!NT_SUCCESS(Status
))
797 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
798 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
802 Status
= NtReadFile(FileHandle
,
812 if (!NT_SUCCESS(Status
))
814 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
815 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
819 /* Adjust bootsector (copy a part of the FAT BPB) */
820 memcpy((NewBootSector
+ 11), (OrigBootSector
+ 11), 51 /*fat BPB length*/);
822 /* Free the original boot sector */
823 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
825 /* Write new bootsector to DstPath */
826 RtlInitUnicodeString(&Name
,
829 InitializeObjectAttributes(&ObjectAttributes
,
835 Status
= NtCreateFile(&FileHandle
,
840 FILE_ATTRIBUTE_NORMAL
,
843 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
,
846 if (!NT_SUCCESS(Status
))
848 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
853 FilePosition
.QuadPart
= 0;
855 Status
= NtWriteFile(FileHandle
,
866 /* Free the new boot sector */
867 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
874 InstallFat32BootCodeToFile(PWSTR SrcPath
,
878 OBJECT_ATTRIBUTES ObjectAttributes
;
879 IO_STATUS_BLOCK IoStatusBlock
;
883 PUCHAR OrigBootSector
;
884 PUCHAR NewBootSector
;
885 LARGE_INTEGER FileOffset
;
887 /* Allocate buffer for original bootsector */
888 OrigBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
891 if (OrigBootSector
== NULL
)
892 return(STATUS_INSUFFICIENT_RESOURCES
);
894 /* Read current boot sector into buffer */
895 RtlInitUnicodeString(&Name
,
898 InitializeObjectAttributes(&ObjectAttributes
,
900 OBJ_CASE_INSENSITIVE
,
904 Status
= NtOpenFile(&FileHandle
,
909 FILE_SYNCHRONOUS_IO_NONALERT
);
910 if (!NT_SUCCESS(Status
))
912 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
916 Status
= NtReadFile(FileHandle
,
926 if (!NT_SUCCESS(Status
))
928 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
932 /* Allocate buffer for new bootsector (2 sectors) */
933 NewBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
936 if (NewBootSector
== NULL
)
938 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
939 return(STATUS_INSUFFICIENT_RESOURCES
);
942 /* Read new bootsector from SrcPath */
943 RtlInitUnicodeString(&Name
,
946 InitializeObjectAttributes(&ObjectAttributes
,
948 OBJ_CASE_INSENSITIVE
,
952 Status
= NtOpenFile(&FileHandle
,
957 FILE_SYNCHRONOUS_IO_NONALERT
);
958 if (!NT_SUCCESS(Status
))
960 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
961 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
965 Status
= NtReadFile(FileHandle
,
975 if (!NT_SUCCESS(Status
))
977 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
978 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
982 /* Adjust bootsector (copy a part of the FAT32 BPB) */
983 memcpy((NewBootSector
+ 3),
984 (OrigBootSector
+ 3),
985 87); /* FAT32 BPB length */
987 /* Disable the backup boot sector */
988 NewBootSector
[0x32] = 0x00;
989 NewBootSector
[0x33] = 0x00;
991 /* Free the original boot sector */
992 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
994 /* Write the first sector of the new bootcode to DstPath */
995 RtlInitUnicodeString(&Name
,
998 InitializeObjectAttributes(&ObjectAttributes
,
1004 Status
= NtCreateFile(&FileHandle
,
1009 FILE_ATTRIBUTE_NORMAL
,
1012 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
,
1015 if (!NT_SUCCESS(Status
))
1017 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1021 Status
= NtWriteFile(FileHandle
,
1030 NtClose(FileHandle
);
1031 if (!NT_SUCCESS(Status
))
1033 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1037 /* Write the second sector of the new bootcode to boot disk sector 14 */
1038 RtlInitUnicodeString(&Name
,
1041 InitializeObjectAttributes(&ObjectAttributes
,
1047 Status
= NtOpenFile(&FileHandle
,
1052 FILE_SYNCHRONOUS_IO_NONALERT
);
1053 if (!NT_SUCCESS(Status
))
1055 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1059 FileOffset
.QuadPart
= (ULONGLONG
)(14 * SECTORSIZE
);
1060 Status
= NtWriteFile(FileHandle
,
1065 (NewBootSector
+ SECTORSIZE
),
1069 if (!NT_SUCCESS(Status
))
1072 NtClose(FileHandle
);
1074 /* Free the new boot sector */
1075 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1082 InstallMbrBootCodeToDisk (PWSTR SrcPath
,
1085 OBJECT_ATTRIBUTES ObjectAttributes
;
1086 IO_STATUS_BLOCK IoStatusBlock
;
1087 UNICODE_STRING Name
;
1090 PPARTITION_SECTOR OrigBootSector
;
1091 PPARTITION_SECTOR NewBootSector
;
1093 /* Allocate buffer for original bootsector */
1094 OrigBootSector
= (PPARTITION_SECTOR
)RtlAllocateHeap(ProcessHeap
,
1096 sizeof(PARTITION_SECTOR
));
1097 if (OrigBootSector
== NULL
)
1098 return(STATUS_INSUFFICIENT_RESOURCES
);
1100 /* Read current boot sector into buffer */
1101 RtlInitUnicodeString(&Name
,
1104 InitializeObjectAttributes(&ObjectAttributes
,
1106 OBJ_CASE_INSENSITIVE
,
1110 Status
= NtOpenFile(&FileHandle
,
1115 FILE_SYNCHRONOUS_IO_NONALERT
);
1116 if (!NT_SUCCESS(Status
))
1118 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1122 Status
= NtReadFile(FileHandle
,
1131 NtClose(FileHandle
);
1132 if (!NT_SUCCESS(Status
))
1134 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1139 /* Allocate buffer for new bootsector */
1140 NewBootSector
= (PPARTITION_SECTOR
)RtlAllocateHeap(ProcessHeap
,
1142 sizeof(PARTITION_SECTOR
));
1143 if (NewBootSector
== NULL
)
1145 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1146 return(STATUS_INSUFFICIENT_RESOURCES
);
1149 /* Read new bootsector from SrcPath */
1150 RtlInitUnicodeString(&Name
,
1153 InitializeObjectAttributes(&ObjectAttributes
,
1155 OBJ_CASE_INSENSITIVE
,
1159 Status
= NtOpenFile(&FileHandle
,
1164 FILE_SYNCHRONOUS_IO_NONALERT
);
1165 if (!NT_SUCCESS(Status
))
1167 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1168 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1172 Status
= NtReadFile(FileHandle
,
1178 sizeof(PARTITION_SECTOR
),
1181 NtClose(FileHandle
);
1182 if (!NT_SUCCESS(Status
))
1184 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1185 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1189 /* Copy partition table from old MBR to new */
1190 RtlCopyMemory (&NewBootSector
->Signature
,
1191 &OrigBootSector
->Signature
,
1192 sizeof(PARTITION_SECTOR
) - offsetof(PARTITION_SECTOR
, Signature
) /* Length of partition table */);
1194 /* Free the original boot sector */
1195 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1197 /* Write new bootsector to RootPath */
1198 RtlInitUnicodeString(&Name
,
1201 InitializeObjectAttributes(&ObjectAttributes
,
1207 Status
= NtOpenFile(&FileHandle
,
1212 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1213 if (!NT_SUCCESS(Status
))
1215 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1216 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1220 Status
= NtWriteFile(FileHandle
,
1229 NtClose(FileHandle
);
1231 /* Free the new boot sector */
1232 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1239 InstallFat16BootCodeToDisk(PWSTR SrcPath
,
1242 OBJECT_ATTRIBUTES ObjectAttributes
;
1243 IO_STATUS_BLOCK IoStatusBlock
;
1244 UNICODE_STRING Name
;
1247 PUCHAR OrigBootSector
;
1248 PUCHAR NewBootSector
;
1250 /* Allocate buffer for original bootsector */
1251 OrigBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
1254 if (OrigBootSector
== NULL
)
1255 return(STATUS_INSUFFICIENT_RESOURCES
);
1257 /* Read current boot sector into buffer */
1258 RtlInitUnicodeString(&Name
,
1261 InitializeObjectAttributes(&ObjectAttributes
,
1263 OBJ_CASE_INSENSITIVE
,
1267 Status
= NtOpenFile(&FileHandle
,
1272 FILE_SYNCHRONOUS_IO_NONALERT
);
1273 if (!NT_SUCCESS(Status
))
1275 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1279 Status
= NtReadFile(FileHandle
,
1288 NtClose(FileHandle
);
1289 if (!NT_SUCCESS(Status
))
1291 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1296 /* Allocate buffer for new bootsector */
1297 NewBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
1300 if (NewBootSector
== NULL
)
1302 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1303 return(STATUS_INSUFFICIENT_RESOURCES
);
1306 /* Read new bootsector from SrcPath */
1307 RtlInitUnicodeString(&Name
,
1310 InitializeObjectAttributes(&ObjectAttributes
,
1312 OBJ_CASE_INSENSITIVE
,
1316 Status
= NtOpenFile(&FileHandle
,
1321 FILE_SYNCHRONOUS_IO_NONALERT
);
1322 if (!NT_SUCCESS(Status
))
1324 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1325 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1329 Status
= NtReadFile(FileHandle
,
1338 NtClose(FileHandle
);
1339 if (!NT_SUCCESS(Status
))
1341 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1342 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1346 /* Adjust bootsector (copy a part of the FAT16 BPB) */
1347 memcpy((NewBootSector
+ 3),
1348 (OrigBootSector
+ 3),
1349 59); /* FAT16 BPB length*/
1351 /* Free the original boot sector */
1352 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1354 /* Write new bootsector to RootPath */
1355 RtlInitUnicodeString(&Name
,
1358 InitializeObjectAttributes(&ObjectAttributes
,
1364 Status
= NtOpenFile(&FileHandle
,
1369 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1370 if (!NT_SUCCESS(Status
))
1372 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1373 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1378 FilePosition
.QuadPart
= 0;
1380 Status
= NtWriteFile(FileHandle
,
1389 NtClose(FileHandle
);
1391 /* Free the new boot sector */
1392 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1399 InstallFat32BootCodeToDisk(PWSTR SrcPath
,
1402 OBJECT_ATTRIBUTES ObjectAttributes
;
1403 IO_STATUS_BLOCK IoStatusBlock
;
1404 UNICODE_STRING Name
;
1407 PUCHAR OrigBootSector
;
1408 PUCHAR NewBootSector
;
1409 LARGE_INTEGER FileOffset
;
1410 USHORT BackupBootSector
;
1412 /* Allocate buffer for original bootsector */
1413 OrigBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
1416 if (OrigBootSector
== NULL
)
1417 return(STATUS_INSUFFICIENT_RESOURCES
);
1419 /* Read current boot sector into buffer */
1420 RtlInitUnicodeString(&Name
,
1423 InitializeObjectAttributes(&ObjectAttributes
,
1425 OBJ_CASE_INSENSITIVE
,
1429 Status
= NtOpenFile(&FileHandle
,
1434 FILE_SYNCHRONOUS_IO_NONALERT
);
1435 if (!NT_SUCCESS(Status
))
1437 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1441 Status
= NtReadFile(FileHandle
,
1450 NtClose(FileHandle
);
1451 if (!NT_SUCCESS(Status
))
1453 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1458 /* Allocate buffer for new bootsector (2 sectors) */
1459 NewBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
1462 if (NewBootSector
== NULL
)
1464 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1465 return(STATUS_INSUFFICIENT_RESOURCES
);
1468 /* Read new bootsector from SrcPath */
1469 RtlInitUnicodeString(&Name
,
1472 InitializeObjectAttributes(&ObjectAttributes
,
1474 OBJ_CASE_INSENSITIVE
,
1478 Status
= NtOpenFile(&FileHandle
,
1483 FILE_SYNCHRONOUS_IO_NONALERT
);
1484 if (!NT_SUCCESS(Status
))
1486 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1487 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1491 Status
= NtReadFile(FileHandle
,
1500 NtClose(FileHandle
);
1501 if (!NT_SUCCESS(Status
))
1503 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1504 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1508 /* Adjust bootsector (copy a part of the FAT32 BPB) */
1509 memcpy((NewBootSector
+ 3),
1510 (OrigBootSector
+ 3),
1511 87); /* FAT32 BPB length */
1513 /* Get the location of the backup boot sector */
1514 BackupBootSector
= (OrigBootSector
[0x33] << 8) + OrigBootSector
[0x32];
1516 /* Free the original boot sector */
1517 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1519 /* Write the first sector of the new bootcode to DstPath */
1520 RtlInitUnicodeString(&Name
,
1523 InitializeObjectAttributes(&ObjectAttributes
,
1529 Status
= NtOpenFile(&FileHandle
,
1534 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1535 if (!NT_SUCCESS(Status
))
1537 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1538 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1542 /* Write sector 0 */
1543 FileOffset
.QuadPart
= 0ULL;
1544 Status
= NtWriteFile(FileHandle
,
1553 if (!NT_SUCCESS(Status
))
1555 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1556 NtClose(FileHandle
);
1557 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1561 /* Write backup boot sector */
1562 if ((BackupBootSector
!= 0x0000) && (BackupBootSector
!= 0xFFFF))
1564 FileOffset
.QuadPart
= (ULONGLONG
)((ULONG
)BackupBootSector
* SECTORSIZE
);
1565 Status
= NtWriteFile(FileHandle
,
1574 if (!NT_SUCCESS(Status
))
1576 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1577 NtClose(FileHandle
);
1578 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1583 /* Write sector 14 */
1584 FileOffset
.QuadPart
= (ULONGLONG
)(14 * SECTORSIZE
);
1585 Status
= NtWriteFile(FileHandle
,
1590 (NewBootSector
+ SECTORSIZE
),
1594 if (!NT_SUCCESS(Status
))
1596 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1598 NtClose(FileHandle
);
1600 /* Free the new boot sector */
1601 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1608 UnprotectBootIni(PWSTR FileName
,
1611 UNICODE_STRING Name
;
1612 OBJECT_ATTRIBUTES ObjectAttributes
;
1613 IO_STATUS_BLOCK IoStatusBlock
;
1614 FILE_BASIC_INFORMATION FileInfo
;
1618 RtlInitUnicodeString(&Name
,
1621 InitializeObjectAttributes(&ObjectAttributes
,
1623 OBJ_CASE_INSENSITIVE
,
1627 Status
= NtOpenFile(&FileHandle
,
1628 GENERIC_READ
|GENERIC_WRITE
,
1632 FILE_SYNCHRONOUS_IO_NONALERT
);
1633 if (Status
== STATUS_NO_SUCH_FILE
)
1635 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1637 return(STATUS_SUCCESS
);
1639 if (!NT_SUCCESS(Status
))
1641 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1645 Status
= NtQueryInformationFile(FileHandle
,
1648 sizeof(FILE_BASIC_INFORMATION
),
1649 FileBasicInformation
);
1650 if (!NT_SUCCESS(Status
))
1652 DPRINT1("NtQueryInformationFile() failed (Status %lx)\n", Status
);
1653 NtClose(FileHandle
);
1657 *Attributes
= FileInfo
.FileAttributes
;
1659 /* Delete attributes SYSTEM, HIDDEN and READONLY */
1660 FileInfo
.FileAttributes
= FileInfo
.FileAttributes
&
1661 ~(FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
| FILE_ATTRIBUTE_READONLY
);
1663 Status
= NtSetInformationFile(FileHandle
,
1666 sizeof(FILE_BASIC_INFORMATION
),
1667 FileBasicInformation
);
1668 if (!NT_SUCCESS(Status
))
1670 DPRINT1("NtSetInformationFile() failed (Status %lx)\n", Status
);
1673 NtClose(FileHandle
);
1679 ProtectBootIni(PWSTR FileName
,
1682 UNICODE_STRING Name
;
1683 OBJECT_ATTRIBUTES ObjectAttributes
;
1684 IO_STATUS_BLOCK IoStatusBlock
;
1685 FILE_BASIC_INFORMATION FileInfo
;
1689 RtlInitUnicodeString(&Name
,
1692 InitializeObjectAttributes(&ObjectAttributes
,
1694 OBJ_CASE_INSENSITIVE
,
1698 Status
= NtOpenFile(&FileHandle
,
1699 GENERIC_READ
|GENERIC_WRITE
,
1703 FILE_SYNCHRONOUS_IO_NONALERT
);
1704 if (!NT_SUCCESS(Status
))
1706 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1710 Status
= NtQueryInformationFile(FileHandle
,
1713 sizeof(FILE_BASIC_INFORMATION
),
1714 FileBasicInformation
);
1715 if (!NT_SUCCESS(Status
))
1717 DPRINT1("NtQueryInformationFile() failed (Status %lx)\n", Status
);
1718 NtClose(FileHandle
);
1722 FileInfo
.FileAttributes
= FileInfo
.FileAttributes
| Attributes
;
1724 Status
= NtSetInformationFile(FileHandle
,
1727 sizeof(FILE_BASIC_INFORMATION
),
1728 FileBasicInformation
);
1729 if (!NT_SUCCESS(Status
))
1731 DPRINT1("NtSetInformationFile() failed (Status %lx)\n", Status
);
1734 NtClose(FileHandle
);
1740 UpdateBootIni(PWSTR BootIniPath
,
1744 UNICODE_STRING Name
;
1745 PINICACHE Cache
= NULL
;
1746 PINICACHESECTION Section
= NULL
;
1748 ULONG FileAttribute
;
1749 PWCHAR OldValue
= NULL
;
1751 RtlInitUnicodeString(&Name
,
1754 Status
= IniCacheLoad(&Cache
,
1757 if (!NT_SUCCESS(Status
))
1762 Section
= IniCacheGetSection(Cache
,
1763 L
"operating systems");
1764 if (Section
== NULL
)
1766 IniCacheDestroy(Cache
);
1767 return(STATUS_UNSUCCESSFUL
);
1770 /* Check - maybe record already exists */
1771 Status
= IniCacheGetKey(Section
,
1775 /* If either key was not found, or contains something else - add new one */
1776 if (!NT_SUCCESS(Status
) || wcscmp(OldValue
, EntryValue
))
1778 IniCacheInsertKey(Section
,
1785 Status
= UnprotectBootIni(BootIniPath
,
1787 if (!NT_SUCCESS(Status
))
1789 IniCacheDestroy(Cache
);
1793 Status
= IniCacheSave(Cache
,
1795 if (!NT_SUCCESS(Status
))
1797 IniCacheDestroy(Cache
);
1801 FileAttribute
|= (FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
| FILE_ATTRIBUTE_READONLY
);
1802 Status
= ProtectBootIni(BootIniPath
,
1805 IniCacheDestroy(Cache
);
1811 CheckInstallFatBootcodeToPartition(PUNICODE_STRING SystemRootPath
)
1814 if (DoesFileExist(SystemRootPath
->Buffer
, L
"ntldr") ||
1815 DoesFileExist(SystemRootPath
->Buffer
, L
"boot.ini"))
1819 else if (DoesFileExist(SystemRootPath
->Buffer
, L
"io.sys") ||
1820 DoesFileExist(SystemRootPath
->Buffer
, L
"msdos.sys"))
1831 InstallFatBootcodeToPartition(PUNICODE_STRING SystemRootPath
,
1832 PUNICODE_STRING SourceRootPath
,
1833 PUNICODE_STRING DestinationArcPath
,
1834 UCHAR PartitionType
)
1837 WCHAR SrcPath
[MAX_PATH
];
1838 WCHAR DstPath
[MAX_PATH
];
1841 /* FAT or FAT32 partition */
1842 DPRINT("System path: '%wZ'\n", SystemRootPath
);
1844 if (DoesFileExist(SystemRootPath
->Buffer
, L
"ntldr") == TRUE
||
1845 DoesFileExist(SystemRootPath
->Buffer
, L
"boot.ini") == TRUE
)
1847 /* Search root directory for 'ntldr' and 'boot.ini'. */
1848 DPRINT("Found Microsoft Windows NT/2000/XP boot loader\n");
1850 /* Copy FreeLoader to the boot partition */
1851 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
1852 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
1853 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1854 wcscat(DstPath
, L
"\\freeldr.sys");
1856 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
1857 Status
= SetupCopyFile(SrcPath
, DstPath
);
1858 if (!NT_SUCCESS(Status
))
1860 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
1864 /* Create or update freeldr.ini */
1865 if (DoesFileExist(SystemRootPath
->Buffer
, L
"freeldr.ini") == FALSE
)
1867 /* Create new 'freeldr.ini' */
1868 DPRINT1("Create new 'freeldr.ini'\n");
1869 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1870 wcscat(DstPath
, L
"\\freeldr.ini");
1872 Status
= CreateFreeLoaderIniForReactos(DstPath
,
1873 DestinationArcPath
->Buffer
);
1874 if (!NT_SUCCESS(Status
))
1876 DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status
);
1880 /* Install new bootcode */
1881 if (PartitionType
== PARTITION_FAT32
||
1882 PartitionType
== PARTITION_FAT32_XINT13
)
1884 /* Install FAT32 bootcode */
1885 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
1886 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
1887 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1888 wcscat(DstPath
, L
"\\bootsect.ros");
1890 DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, DstPath
);
1891 Status
= InstallFat32BootCodeToFile(SrcPath
,
1893 SystemRootPath
->Buffer
);
1894 if (!NT_SUCCESS(Status
))
1896 DPRINT1("InstallFat32BootCodeToFile() failed (Status %lx)\n", Status
);
1902 /* Install FAT16 bootcode */
1903 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
1904 wcscat(SrcPath
, L
"\\loader\\fat.bin");
1905 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1906 wcscat(DstPath
, L
"\\bootsect.ros");
1908 DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath
, DstPath
);
1909 Status
= InstallFat16BootCodeToFile(SrcPath
,
1911 SystemRootPath
->Buffer
);
1912 if (!NT_SUCCESS(Status
))
1914 DPRINT1("InstallFat16BootCodeToFile() failed (Status %lx)\n", Status
);
1921 /* Update existing 'freeldr.ini' */
1922 DPRINT1("Update existing 'freeldr.ini'\n");
1923 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1924 wcscat(DstPath
, L
"\\freeldr.ini");
1926 Status
= UpdateFreeLoaderIni(DstPath
,
1927 DestinationArcPath
->Buffer
);
1928 if (!NT_SUCCESS(Status
))
1930 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
1935 /* Update 'boot.ini' */
1936 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1937 wcscat(DstPath
, L
"\\boot.ini");
1939 DPRINT1("Update 'boot.ini': %S\n", DstPath
);
1940 Status
= UpdateBootIni(DstPath
,
1941 L
"C:\\bootsect.ros",
1943 if (!NT_SUCCESS(Status
))
1945 DPRINT1("UpdateBootIni() failed (Status %lx)\n", Status
);
1949 else if (DoesFileExist(SystemRootPath
->Buffer
, L
"io.sys") == TRUE
||
1950 DoesFileExist(SystemRootPath
->Buffer
, L
"msdos.sys") == TRUE
)
1952 /* Search for root directory for 'io.sys' and 'msdos.sys'. */
1953 DPRINT1("Found Microsoft DOS or Windows 9x boot loader\n");
1955 /* Copy FreeLoader to the boot partition */
1956 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
1957 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
1958 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1959 wcscat(DstPath
, L
"\\freeldr.sys");
1961 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
1962 Status
= SetupCopyFile(SrcPath
, DstPath
);
1963 if (!NT_SUCCESS(Status
))
1965 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
1969 /* Create or update 'freeldr.ini' */
1970 if (DoesFileExist(SystemRootPath
->Buffer
, L
"freeldr.ini") == FALSE
)
1972 /* Create new 'freeldr.ini' */
1973 DPRINT1("Create new 'freeldr.ini'\n");
1974 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1975 wcscat(DstPath
, L
"\\freeldr.ini");
1977 Status
= CreateFreeLoaderIniForDos(DstPath
,
1978 DestinationArcPath
->Buffer
);
1979 if (!NT_SUCCESS(Status
))
1981 DPRINT1("CreateFreeLoaderIniForDos() failed (Status %lx)\n", Status
);
1985 /* Save current bootsector as 'BOOTSECT.DOS' */
1986 wcscpy(SrcPath
, SystemRootPath
->Buffer
);
1987 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1988 wcscat(DstPath
, L
"\\bootsect.dos");
1990 DPRINT1("Save bootsector: %S ==> %S\n", SrcPath
, DstPath
);
1991 Status
= SaveCurrentBootSector(SrcPath
,
1993 if (!NT_SUCCESS(Status
))
1995 DPRINT1("SaveCurrentBootSector() failed (Status %lx)\n", Status
);
1999 /* Install new bootsector */
2000 if (PartitionType
== PARTITION_FAT32
||
2001 PartitionType
== PARTITION_FAT32_XINT13
)
2003 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2004 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
2006 DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2007 Status
= InstallFat32BootCodeToDisk(SrcPath
,
2008 SystemRootPath
->Buffer
);
2009 if (!NT_SUCCESS(Status
))
2011 DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)\n", Status
);
2017 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2018 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2020 DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2021 Status
= InstallFat16BootCodeToDisk(SrcPath
,
2022 SystemRootPath
->Buffer
);
2023 if (!NT_SUCCESS(Status
))
2025 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status
);
2032 /* Update existing 'freeldr.ini' */
2033 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2034 wcscat(DstPath
, L
"\\freeldr.ini");
2036 Status
= UpdateFreeLoaderIni(DstPath
,
2037 DestinationArcPath
->Buffer
);
2038 if (!NT_SUCCESS(Status
))
2040 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
2047 /* No or unknown boot loader */
2048 DPRINT1("No or unknown boot loader found\n");
2050 /* Copy FreeLoader to the boot partition */
2051 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2052 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
2053 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2054 wcscat(DstPath
, L
"\\freeldr.sys");
2056 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2057 Status
= SetupCopyFile(SrcPath
, DstPath
);
2058 if (!NT_SUCCESS(Status
))
2060 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
2064 /* Create or update 'freeldr.ini' */
2065 if (DoesFileExist(SystemRootPath
->Buffer
, L
"freeldr.ini") == FALSE
)
2067 /* Create new freeldr.ini */
2068 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2069 wcscat(DstPath
, L
"\\freeldr.ini");
2071 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2072 Status
= CreateFreeLoaderIniForReactos(DstPath
,
2073 DestinationArcPath
->Buffer
);
2074 if (!NT_SUCCESS(Status
))
2076 DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status
);
2080 /* Save current bootsector as 'BOOTSECT.OLD' */
2081 wcscpy(SrcPath
, SystemRootPath
->Buffer
);
2082 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2083 wcscat(DstPath
, L
"\\bootsect.old");
2085 DPRINT("Save bootsector: %S ==> %S\n", SrcPath
, DstPath
);
2086 Status
= SaveCurrentBootSector(SrcPath
,
2088 if (!NT_SUCCESS(Status
))
2090 DPRINT1("SaveCurrentBootSector() failed (Status %lx)\n", Status
);
2094 /* Install new bootsector */
2095 if (PartitionType
== PARTITION_FAT32
||
2096 PartitionType
== PARTITION_FAT32_XINT13
)
2098 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2099 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
2101 DPRINT("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2102 Status
= InstallFat32BootCodeToDisk(SrcPath
,
2103 SystemRootPath
->Buffer
);
2104 if (!NT_SUCCESS(Status
))
2106 DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)\n", Status
);
2112 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2113 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2115 DPRINT("Install FAT bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2116 Status
= InstallFat16BootCodeToDisk(SrcPath
,
2117 SystemRootPath
->Buffer
);
2118 if (!NT_SUCCESS(Status
))
2120 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status
);
2127 /* Update existing 'freeldr.ini' */
2128 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2129 wcscat(DstPath
, L
"\\freeldr.ini");
2131 Status
= UpdateFreeLoaderIni(DstPath
,
2132 DestinationArcPath
->Buffer
);
2133 if (!NT_SUCCESS(Status
))
2135 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
2141 return STATUS_SUCCESS
;
2143 return STATUS_NOT_IMPLEMENTED
;
2149 InstallFatBootcodeToFloppy(PUNICODE_STRING SourceRootPath
,
2150 PUNICODE_STRING DestinationArcPath
)
2153 WCHAR SrcPath
[MAX_PATH
];
2154 WCHAR DstPath
[MAX_PATH
];
2157 /* Copy FreeLoader to the boot partition */
2158 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2159 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
2161 wcscpy(DstPath
, L
"\\Device\\Floppy0\\freeldr.sys");
2163 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2164 Status
= SetupCopyFile(SrcPath
, DstPath
);
2165 if (!NT_SUCCESS(Status
))
2167 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
2171 /* Create new 'freeldr.ini' */
2172 wcscpy(DstPath
, L
"\\Device\\Floppy0\\freeldr.ini");
2174 DPRINT("Create new 'freeldr.ini'\n");
2175 Status
= CreateFreeLoaderIniForReactos(DstPath
,
2176 DestinationArcPath
->Buffer
);
2177 if (!NT_SUCCESS(Status
))
2179 DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status
);
2183 /* Install FAT12/16 boosector */
2184 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2185 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2187 wcscpy(DstPath
, L
"\\Device\\Floppy0");
2189 DPRINT("Install FAT bootcode: %S ==> %S\n", SrcPath
, DstPath
);
2190 Status
= InstallFat16BootCodeToDisk(SrcPath
,
2192 if (!NT_SUCCESS(Status
))
2194 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status
);
2198 return STATUS_SUCCESS
;
2200 return STATUS_NOT_IMPLEMENTED
;