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 along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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)\"",
431 L
"Windows2003", ArcPath
,
432 L
"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /KDSERIAL");
434 /* ReactOS_LogFile */
435 CreateFreeLoaderEntry(IniCache
, IniSection
,
436 L
"ReactOS_LogFile", L
"\"ReactOS (Log file)\"",
437 L
"Windows2003", ArcPath
,
438 L
"/DEBUG /DEBUGPORT=FILE /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");
448 CreateFreeLoaderEntry(IniCache
, IniSection
,
449 L
"ReactOS_old", L
"\"ReactOS (old boot method)\"",
453 /* ReactOS_Debug_old */
454 CreateFreeLoaderEntry(IniCache
, IniSection
,
455 L
"ReactOS_Debug_old", L
"\"ReactOS (Debug, old boot method)\"",
457 L
"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS");
459 /* Save the ini file */
460 IniCacheSave(IniCache
, IniPath
);
461 IniCacheDestroy(IniCache
);
463 return(STATUS_SUCCESS
);
468 UpdateFreeLoaderIni(PWCHAR IniPath
,
473 PINICACHESECTION IniSection
;
474 PINICACHESECTION OsIniSection
;
475 WCHAR SectionName
[80];
477 WCHAR SystemPath
[200];
478 WCHAR SectionName2
[200];
483 RtlInitUnicodeString(&Name
,
486 Status
= IniCacheLoad(&IniCache
,
489 if (!NT_SUCCESS(Status
))
492 /* Get "Operating Systems" section */
493 IniSection
= IniCacheGetSection(IniCache
,
494 L
"Operating Systems");
495 if (IniSection
== NULL
)
497 IniCacheDestroy(IniCache
);
498 return(STATUS_UNSUCCESSFUL
);
501 /* Find an existing usable or an unused section name */
503 wcscpy(SectionName
, L
"ReactOS");
504 wcscpy(OsName
, L
"\"ReactOS\"");
507 Status
= IniCacheGetKey(IniSection
,
510 if (!NT_SUCCESS(Status
))
513 /* Get operation system section */
514 if (KeyData
[0] == '"')
516 wcscpy(SectionName2
, &KeyData
[1]);
517 j
= wcslen(SectionName2
);
520 SectionName2
[j
-1] = 0;
525 wcscpy(SectionName2
, KeyData
);
528 OsIniSection
= IniCacheGetSection(IniCache
,
530 if (OsIniSection
!= NULL
)
532 BOOLEAN UseExistingEntry
= TRUE
;
535 Status
= IniCacheGetKey(OsIniSection
,
538 if (NT_SUCCESS(Status
))
541 || (_wcsicmp(KeyData
, L
"ReactOS") != 0
542 && _wcsicmp(KeyData
, L
"\"ReactOS\"") != 0))
544 /* This is not a ReactOS entry */
545 UseExistingEntry
= FALSE
;
550 UseExistingEntry
= FALSE
;
553 if (UseExistingEntry
)
555 /* BootType is ReactOS. Now check SystemPath */
556 Status
= IniCacheGetKey(OsIniSection
,
559 if (NT_SUCCESS(Status
))
561 swprintf(SystemPath
, L
"\"%S\"", ArcPath
);
563 || (_wcsicmp(KeyData
, ArcPath
) != 0
564 && _wcsicmp(KeyData
, SystemPath
) != 0))
566 /* This entry is a ReactOS entry, but the SystemRoot does not
567 match the one we are looking for */
568 UseExistingEntry
= FALSE
;
573 UseExistingEntry
= FALSE
;
577 if (UseExistingEntry
)
579 IniCacheDestroy(IniCache
);
580 return(STATUS_SUCCESS
);
584 swprintf(SectionName
, L
"ReactOS_%lu", i
);
585 swprintf(OsName
, L
"\"ReactOS %lu\"", i
);
589 /* <SectionName>=<OsName> */
590 IniCacheInsertKey(IniSection
,
596 /* Create <SectionName> section */
597 IniSection
= IniCacheAppendSection(IniCache
,
600 /* BootType=ReactOS */
601 IniCacheInsertKey(IniSection
,
607 /* SystemPath=<ArcPath> */
608 IniCacheInsertKey(IniSection
,
614 IniCacheSave(IniCache
, IniPath
);
615 IniCacheDestroy(IniCache
);
617 return(STATUS_SUCCESS
);
622 SaveCurrentBootSector(PWSTR RootPath
,
625 OBJECT_ATTRIBUTES ObjectAttributes
;
626 IO_STATUS_BLOCK IoStatusBlock
;
632 /* Allocate buffer for bootsector */
633 BootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
636 if (BootSector
== NULL
)
637 return(STATUS_INSUFFICIENT_RESOURCES
);
639 /* Read current boot sector into buffer */
640 RtlInitUnicodeString(&Name
,
643 InitializeObjectAttributes(&ObjectAttributes
,
645 OBJ_CASE_INSENSITIVE
,
649 Status
= NtOpenFile(&FileHandle
,
654 FILE_SYNCHRONOUS_IO_NONALERT
);
655 if (!NT_SUCCESS(Status
))
657 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
661 Status
= NtReadFile(FileHandle
,
671 if (!NT_SUCCESS(Status
))
673 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
677 /* Write bootsector to DstPath */
678 RtlInitUnicodeString(&Name
,
681 InitializeObjectAttributes(&ObjectAttributes
,
687 Status
= NtCreateFile(&FileHandle
,
692 FILE_ATTRIBUTE_NORMAL
,
695 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
,
698 if (!NT_SUCCESS(Status
))
700 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
704 Status
= NtWriteFile(FileHandle
,
715 /* Free the new boot sector */
716 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
723 InstallFat16BootCodeToFile(PWSTR SrcPath
,
727 OBJECT_ATTRIBUTES ObjectAttributes
;
728 IO_STATUS_BLOCK IoStatusBlock
;
732 PUCHAR OrigBootSector
;
733 PUCHAR NewBootSector
;
735 /* Allocate buffer for original bootsector */
736 OrigBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
739 if (OrigBootSector
== NULL
)
740 return(STATUS_INSUFFICIENT_RESOURCES
);
742 /* Read current boot sector into buffer */
743 RtlInitUnicodeString(&Name
,
746 InitializeObjectAttributes(&ObjectAttributes
,
748 OBJ_CASE_INSENSITIVE
,
752 Status
= NtOpenFile(&FileHandle
,
757 FILE_SYNCHRONOUS_IO_NONALERT
);
758 if (!NT_SUCCESS(Status
))
760 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
764 Status
= NtReadFile(FileHandle
,
774 if (!NT_SUCCESS(Status
))
776 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
781 /* Allocate buffer for new bootsector */
782 NewBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
785 if (NewBootSector
== NULL
)
787 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
788 return(STATUS_INSUFFICIENT_RESOURCES
);
791 /* Read new bootsector from SrcPath */
792 RtlInitUnicodeString(&Name
,
795 InitializeObjectAttributes(&ObjectAttributes
,
797 OBJ_CASE_INSENSITIVE
,
801 Status
= NtOpenFile(&FileHandle
,
806 FILE_SYNCHRONOUS_IO_NONALERT
);
807 if (!NT_SUCCESS(Status
))
809 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
810 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
814 Status
= NtReadFile(FileHandle
,
824 if (!NT_SUCCESS(Status
))
826 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
827 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
831 /* Adjust bootsector (copy a part of the FAT BPB) */
832 memcpy((NewBootSector
+ 11), (OrigBootSector
+ 11), 51 /*fat BPB length*/);
834 /* Free the original boot sector */
835 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
837 /* Write new bootsector to DstPath */
838 RtlInitUnicodeString(&Name
,
841 InitializeObjectAttributes(&ObjectAttributes
,
847 Status
= NtCreateFile(&FileHandle
,
852 FILE_ATTRIBUTE_NORMAL
,
855 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
,
858 if (!NT_SUCCESS(Status
))
860 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
865 FilePosition
.QuadPart
= 0;
867 Status
= NtWriteFile(FileHandle
,
878 /* Free the new boot sector */
879 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
886 InstallFat32BootCodeToFile(PWSTR SrcPath
,
890 OBJECT_ATTRIBUTES ObjectAttributes
;
891 IO_STATUS_BLOCK IoStatusBlock
;
895 PUCHAR OrigBootSector
;
896 PUCHAR NewBootSector
;
897 LARGE_INTEGER FileOffset
;
899 /* Allocate buffer for original bootsector */
900 OrigBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
903 if (OrigBootSector
== NULL
)
904 return(STATUS_INSUFFICIENT_RESOURCES
);
906 /* Read current boot sector into buffer */
907 RtlInitUnicodeString(&Name
,
910 InitializeObjectAttributes(&ObjectAttributes
,
912 OBJ_CASE_INSENSITIVE
,
916 Status
= NtOpenFile(&FileHandle
,
921 FILE_SYNCHRONOUS_IO_NONALERT
);
922 if (!NT_SUCCESS(Status
))
924 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
928 Status
= NtReadFile(FileHandle
,
938 if (!NT_SUCCESS(Status
))
940 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
944 /* Allocate buffer for new bootsector (2 sectors) */
945 NewBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
948 if (NewBootSector
== NULL
)
950 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
951 return(STATUS_INSUFFICIENT_RESOURCES
);
954 /* Read new bootsector from SrcPath */
955 RtlInitUnicodeString(&Name
,
958 InitializeObjectAttributes(&ObjectAttributes
,
960 OBJ_CASE_INSENSITIVE
,
964 Status
= NtOpenFile(&FileHandle
,
969 FILE_SYNCHRONOUS_IO_NONALERT
);
970 if (!NT_SUCCESS(Status
))
972 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
973 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
977 Status
= NtReadFile(FileHandle
,
987 if (!NT_SUCCESS(Status
))
989 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
990 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
994 /* Adjust bootsector (copy a part of the FAT32 BPB) */
995 memcpy((NewBootSector
+ 3),
996 (OrigBootSector
+ 3),
997 87); /* FAT32 BPB length */
999 /* Disable the backup boot sector */
1000 NewBootSector
[0x32] = 0x00;
1001 NewBootSector
[0x33] = 0x00;
1003 /* Free the original boot sector */
1004 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1006 /* Write the first sector of the new bootcode to DstPath */
1007 RtlInitUnicodeString(&Name
,
1010 InitializeObjectAttributes(&ObjectAttributes
,
1016 Status
= NtCreateFile(&FileHandle
,
1021 FILE_ATTRIBUTE_NORMAL
,
1024 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
,
1027 if (!NT_SUCCESS(Status
))
1029 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1033 Status
= NtWriteFile(FileHandle
,
1042 NtClose(FileHandle
);
1043 if (!NT_SUCCESS(Status
))
1045 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1049 /* Write the second sector of the new bootcode to boot disk sector 14 */
1050 RtlInitUnicodeString(&Name
,
1053 InitializeObjectAttributes(&ObjectAttributes
,
1059 Status
= NtOpenFile(&FileHandle
,
1064 FILE_SYNCHRONOUS_IO_NONALERT
);
1065 if (!NT_SUCCESS(Status
))
1067 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1071 FileOffset
.QuadPart
= (ULONGLONG
)(14 * SECTORSIZE
);
1072 Status
= NtWriteFile(FileHandle
,
1077 (NewBootSector
+ SECTORSIZE
),
1081 if (!NT_SUCCESS(Status
))
1084 NtClose(FileHandle
);
1086 /* Free the new boot sector */
1087 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1094 InstallMbrBootCodeToDisk (PWSTR SrcPath
,
1097 OBJECT_ATTRIBUTES ObjectAttributes
;
1098 IO_STATUS_BLOCK IoStatusBlock
;
1099 UNICODE_STRING Name
;
1102 PPARTITION_SECTOR OrigBootSector
;
1103 PPARTITION_SECTOR NewBootSector
;
1105 /* Allocate buffer for original bootsector */
1106 OrigBootSector
= (PPARTITION_SECTOR
)RtlAllocateHeap(ProcessHeap
,
1108 sizeof(PARTITION_SECTOR
));
1109 if (OrigBootSector
== NULL
)
1110 return(STATUS_INSUFFICIENT_RESOURCES
);
1112 /* Read current boot sector into buffer */
1113 RtlInitUnicodeString(&Name
,
1116 InitializeObjectAttributes(&ObjectAttributes
,
1118 OBJ_CASE_INSENSITIVE
,
1122 Status
= NtOpenFile(&FileHandle
,
1127 FILE_SYNCHRONOUS_IO_NONALERT
);
1128 if (!NT_SUCCESS(Status
))
1130 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1134 Status
= NtReadFile(FileHandle
,
1143 NtClose(FileHandle
);
1144 if (!NT_SUCCESS(Status
))
1146 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1151 /* Allocate buffer for new bootsector */
1152 NewBootSector
= (PPARTITION_SECTOR
)RtlAllocateHeap(ProcessHeap
,
1154 sizeof(PARTITION_SECTOR
));
1155 if (NewBootSector
== NULL
)
1157 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1158 return(STATUS_INSUFFICIENT_RESOURCES
);
1161 /* Read new bootsector from SrcPath */
1162 RtlInitUnicodeString(&Name
,
1165 InitializeObjectAttributes(&ObjectAttributes
,
1167 OBJ_CASE_INSENSITIVE
,
1171 Status
= NtOpenFile(&FileHandle
,
1176 FILE_SYNCHRONOUS_IO_NONALERT
);
1177 if (!NT_SUCCESS(Status
))
1179 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1180 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1184 Status
= NtReadFile(FileHandle
,
1190 sizeof(PARTITION_SECTOR
),
1193 NtClose(FileHandle
);
1194 if (!NT_SUCCESS(Status
))
1196 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1197 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1201 /* Copy partition table from old MBR to new */
1202 RtlCopyMemory (&NewBootSector
->Signature
,
1203 &OrigBootSector
->Signature
,
1204 sizeof(PARTITION_SECTOR
) - offsetof(PARTITION_SECTOR
, Signature
) /* Length of partition table */);
1206 /* Free the original boot sector */
1207 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1209 /* Write new bootsector to RootPath */
1210 RtlInitUnicodeString(&Name
,
1213 InitializeObjectAttributes(&ObjectAttributes
,
1219 Status
= NtOpenFile(&FileHandle
,
1224 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1225 if (!NT_SUCCESS(Status
))
1227 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1228 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1232 Status
= NtWriteFile(FileHandle
,
1241 NtClose(FileHandle
);
1243 /* Free the new boot sector */
1244 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1251 InstallFat16BootCodeToDisk(PWSTR SrcPath
,
1254 OBJECT_ATTRIBUTES ObjectAttributes
;
1255 IO_STATUS_BLOCK IoStatusBlock
;
1256 UNICODE_STRING Name
;
1259 PUCHAR OrigBootSector
;
1260 PUCHAR NewBootSector
;
1262 /* Allocate buffer for original bootsector */
1263 OrigBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
1266 if (OrigBootSector
== NULL
)
1267 return(STATUS_INSUFFICIENT_RESOURCES
);
1269 /* Read current boot sector into buffer */
1270 RtlInitUnicodeString(&Name
,
1273 InitializeObjectAttributes(&ObjectAttributes
,
1275 OBJ_CASE_INSENSITIVE
,
1279 Status
= NtOpenFile(&FileHandle
,
1284 FILE_SYNCHRONOUS_IO_NONALERT
);
1285 if (!NT_SUCCESS(Status
))
1287 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1291 Status
= NtReadFile(FileHandle
,
1300 NtClose(FileHandle
);
1301 if (!NT_SUCCESS(Status
))
1303 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1308 /* Allocate buffer for new bootsector */
1309 NewBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
1312 if (NewBootSector
== NULL
)
1314 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1315 return(STATUS_INSUFFICIENT_RESOURCES
);
1318 /* Read new bootsector from SrcPath */
1319 RtlInitUnicodeString(&Name
,
1322 InitializeObjectAttributes(&ObjectAttributes
,
1324 OBJ_CASE_INSENSITIVE
,
1328 Status
= NtOpenFile(&FileHandle
,
1333 FILE_SYNCHRONOUS_IO_NONALERT
);
1334 if (!NT_SUCCESS(Status
))
1336 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1337 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1341 Status
= NtReadFile(FileHandle
,
1350 NtClose(FileHandle
);
1351 if (!NT_SUCCESS(Status
))
1353 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1354 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1358 /* Adjust bootsector (copy a part of the FAT16 BPB) */
1359 memcpy((NewBootSector
+ 3),
1360 (OrigBootSector
+ 3),
1361 59); /* FAT16 BPB length*/
1363 /* Free the original boot sector */
1364 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1366 /* Write new bootsector to RootPath */
1367 RtlInitUnicodeString(&Name
,
1370 InitializeObjectAttributes(&ObjectAttributes
,
1376 Status
= NtOpenFile(&FileHandle
,
1381 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1382 if (!NT_SUCCESS(Status
))
1384 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1385 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1390 FilePosition
.QuadPart
= 0;
1392 Status
= NtWriteFile(FileHandle
,
1401 NtClose(FileHandle
);
1403 /* Free the new boot sector */
1404 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1411 InstallFat32BootCodeToDisk(PWSTR SrcPath
,
1414 OBJECT_ATTRIBUTES ObjectAttributes
;
1415 IO_STATUS_BLOCK IoStatusBlock
;
1416 UNICODE_STRING Name
;
1419 PUCHAR OrigBootSector
;
1420 PUCHAR NewBootSector
;
1421 LARGE_INTEGER FileOffset
;
1422 USHORT BackupBootSector
;
1424 /* Allocate buffer for original bootsector */
1425 OrigBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
1428 if (OrigBootSector
== NULL
)
1429 return(STATUS_INSUFFICIENT_RESOURCES
);
1431 /* Read current boot sector into buffer */
1432 RtlInitUnicodeString(&Name
,
1435 InitializeObjectAttributes(&ObjectAttributes
,
1437 OBJ_CASE_INSENSITIVE
,
1441 Status
= NtOpenFile(&FileHandle
,
1446 FILE_SYNCHRONOUS_IO_NONALERT
);
1447 if (!NT_SUCCESS(Status
))
1449 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1453 Status
= NtReadFile(FileHandle
,
1462 NtClose(FileHandle
);
1463 if (!NT_SUCCESS(Status
))
1465 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1470 /* Allocate buffer for new bootsector (2 sectors) */
1471 NewBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
1474 if (NewBootSector
== NULL
)
1476 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1477 return(STATUS_INSUFFICIENT_RESOURCES
);
1480 /* Read new bootsector from SrcPath */
1481 RtlInitUnicodeString(&Name
,
1484 InitializeObjectAttributes(&ObjectAttributes
,
1486 OBJ_CASE_INSENSITIVE
,
1490 Status
= NtOpenFile(&FileHandle
,
1495 FILE_SYNCHRONOUS_IO_NONALERT
);
1496 if (!NT_SUCCESS(Status
))
1498 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1499 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1503 Status
= NtReadFile(FileHandle
,
1512 NtClose(FileHandle
);
1513 if (!NT_SUCCESS(Status
))
1515 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1516 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1520 /* Adjust bootsector (copy a part of the FAT32 BPB) */
1521 memcpy((NewBootSector
+ 3),
1522 (OrigBootSector
+ 3),
1523 87); /* FAT32 BPB length */
1525 /* Get the location of the backup boot sector */
1526 BackupBootSector
= (OrigBootSector
[0x33] << 8) + OrigBootSector
[0x32];
1528 /* Free the original boot sector */
1529 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1531 /* Write the first sector of the new bootcode to DstPath */
1532 RtlInitUnicodeString(&Name
,
1535 InitializeObjectAttributes(&ObjectAttributes
,
1541 Status
= NtOpenFile(&FileHandle
,
1546 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1547 if (!NT_SUCCESS(Status
))
1549 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1550 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1554 /* Write sector 0 */
1555 FileOffset
.QuadPart
= 0ULL;
1556 Status
= NtWriteFile(FileHandle
,
1565 if (!NT_SUCCESS(Status
))
1567 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1568 NtClose(FileHandle
);
1569 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1573 /* Write backup boot sector */
1574 if ((BackupBootSector
!= 0x0000) && (BackupBootSector
!= 0xFFFF))
1576 FileOffset
.QuadPart
= (ULONGLONG
)((ULONG
)BackupBootSector
* SECTORSIZE
);
1577 Status
= NtWriteFile(FileHandle
,
1586 if (!NT_SUCCESS(Status
))
1588 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1589 NtClose(FileHandle
);
1590 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1595 /* Write sector 14 */
1596 FileOffset
.QuadPart
= (ULONGLONG
)(14 * SECTORSIZE
);
1597 Status
= NtWriteFile(FileHandle
,
1602 (NewBootSector
+ SECTORSIZE
),
1606 if (!NT_SUCCESS(Status
))
1608 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1610 NtClose(FileHandle
);
1612 /* Free the new boot sector */
1613 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1620 UnprotectBootIni(PWSTR FileName
,
1623 UNICODE_STRING Name
;
1624 OBJECT_ATTRIBUTES ObjectAttributes
;
1625 IO_STATUS_BLOCK IoStatusBlock
;
1626 FILE_BASIC_INFORMATION FileInfo
;
1630 RtlInitUnicodeString(&Name
,
1633 InitializeObjectAttributes(&ObjectAttributes
,
1635 OBJ_CASE_INSENSITIVE
,
1639 Status
= NtOpenFile(&FileHandle
,
1640 GENERIC_READ
|GENERIC_WRITE
,
1644 FILE_SYNCHRONOUS_IO_NONALERT
);
1645 if (Status
== STATUS_NO_SUCH_FILE
)
1647 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1649 return(STATUS_SUCCESS
);
1651 if (!NT_SUCCESS(Status
))
1653 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1657 Status
= NtQueryInformationFile(FileHandle
,
1660 sizeof(FILE_BASIC_INFORMATION
),
1661 FileBasicInformation
);
1662 if (!NT_SUCCESS(Status
))
1664 DPRINT1("NtQueryInformationFile() failed (Status %lx)\n", Status
);
1665 NtClose(FileHandle
);
1669 *Attributes
= FileInfo
.FileAttributes
;
1671 /* Delete attributes SYSTEM, HIDDEN and READONLY */
1672 FileInfo
.FileAttributes
= FileInfo
.FileAttributes
&
1673 ~(FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
| FILE_ATTRIBUTE_READONLY
);
1675 Status
= NtSetInformationFile(FileHandle
,
1678 sizeof(FILE_BASIC_INFORMATION
),
1679 FileBasicInformation
);
1680 if (!NT_SUCCESS(Status
))
1682 DPRINT1("NtSetInformationFile() failed (Status %lx)\n", Status
);
1685 NtClose(FileHandle
);
1691 ProtectBootIni(PWSTR FileName
,
1694 UNICODE_STRING Name
;
1695 OBJECT_ATTRIBUTES ObjectAttributes
;
1696 IO_STATUS_BLOCK IoStatusBlock
;
1697 FILE_BASIC_INFORMATION FileInfo
;
1701 RtlInitUnicodeString(&Name
,
1704 InitializeObjectAttributes(&ObjectAttributes
,
1706 OBJ_CASE_INSENSITIVE
,
1710 Status
= NtOpenFile(&FileHandle
,
1711 GENERIC_READ
|GENERIC_WRITE
,
1715 FILE_SYNCHRONOUS_IO_NONALERT
);
1716 if (!NT_SUCCESS(Status
))
1718 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1722 Status
= NtQueryInformationFile(FileHandle
,
1725 sizeof(FILE_BASIC_INFORMATION
),
1726 FileBasicInformation
);
1727 if (!NT_SUCCESS(Status
))
1729 DPRINT1("NtQueryInformationFile() failed (Status %lx)\n", Status
);
1730 NtClose(FileHandle
);
1734 FileInfo
.FileAttributes
= FileInfo
.FileAttributes
| Attributes
;
1736 Status
= NtSetInformationFile(FileHandle
,
1739 sizeof(FILE_BASIC_INFORMATION
),
1740 FileBasicInformation
);
1741 if (!NT_SUCCESS(Status
))
1743 DPRINT1("NtSetInformationFile() failed (Status %lx)\n", Status
);
1746 NtClose(FileHandle
);
1752 UpdateBootIni(PWSTR BootIniPath
,
1756 UNICODE_STRING Name
;
1757 PINICACHE Cache
= NULL
;
1758 PINICACHESECTION Section
= NULL
;
1760 ULONG FileAttribute
;
1761 PWCHAR OldValue
= NULL
;
1763 RtlInitUnicodeString(&Name
,
1766 Status
= IniCacheLoad(&Cache
,
1769 if (!NT_SUCCESS(Status
))
1774 Section
= IniCacheGetSection(Cache
,
1775 L
"operating systems");
1776 if (Section
== NULL
)
1778 IniCacheDestroy(Cache
);
1779 return(STATUS_UNSUCCESSFUL
);
1782 /* Check - maybe record already exists */
1783 Status
= IniCacheGetKey(Section
,
1787 /* If either key was not found, or contains something else - add new one */
1788 if (!NT_SUCCESS(Status
) || wcscmp(OldValue
, EntryValue
))
1790 IniCacheInsertKey(Section
,
1797 Status
= UnprotectBootIni(BootIniPath
,
1799 if (!NT_SUCCESS(Status
))
1801 IniCacheDestroy(Cache
);
1805 Status
= IniCacheSave(Cache
,
1807 if (!NT_SUCCESS(Status
))
1809 IniCacheDestroy(Cache
);
1813 FileAttribute
|= (FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
| FILE_ATTRIBUTE_READONLY
);
1814 Status
= ProtectBootIni(BootIniPath
,
1817 IniCacheDestroy(Cache
);
1823 CheckInstallFatBootcodeToPartition(PUNICODE_STRING SystemRootPath
)
1826 if (DoesFileExist(SystemRootPath
->Buffer
, L
"ntldr") ||
1827 DoesFileExist(SystemRootPath
->Buffer
, L
"boot.ini"))
1831 else if (DoesFileExist(SystemRootPath
->Buffer
, L
"io.sys") ||
1832 DoesFileExist(SystemRootPath
->Buffer
, L
"msdos.sys"))
1843 InstallFatBootcodeToPartition(PUNICODE_STRING SystemRootPath
,
1844 PUNICODE_STRING SourceRootPath
,
1845 PUNICODE_STRING DestinationArcPath
,
1846 UCHAR PartitionType
)
1849 WCHAR SrcPath
[MAX_PATH
];
1850 WCHAR DstPath
[MAX_PATH
];
1853 /* FAT or FAT32 partition */
1854 DPRINT("System path: '%wZ'\n", SystemRootPath
);
1856 if (DoesFileExist(SystemRootPath
->Buffer
, L
"ntldr") == TRUE
||
1857 DoesFileExist(SystemRootPath
->Buffer
, L
"boot.ini") == TRUE
)
1859 /* Search root directory for 'ntldr' and 'boot.ini'. */
1860 DPRINT("Found Microsoft Windows NT/2000/XP boot loader\n");
1862 /* Copy FreeLoader to the boot partition */
1863 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
1864 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
1865 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1866 wcscat(DstPath
, L
"\\freeldr.sys");
1868 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
1869 Status
= SetupCopyFile(SrcPath
, DstPath
);
1870 if (!NT_SUCCESS(Status
))
1872 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
1876 /* Create or update freeldr.ini */
1877 if (DoesFileExist(SystemRootPath
->Buffer
, L
"freeldr.ini") == FALSE
)
1879 /* Create new 'freeldr.ini' */
1880 DPRINT1("Create new 'freeldr.ini'\n");
1881 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1882 wcscat(DstPath
, L
"\\freeldr.ini");
1884 Status
= CreateFreeLoaderIniForReactos(DstPath
,
1885 DestinationArcPath
->Buffer
);
1886 if (!NT_SUCCESS(Status
))
1888 DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status
);
1892 /* Install new bootcode */
1893 if (PartitionType
== PARTITION_FAT32
||
1894 PartitionType
== PARTITION_FAT32_XINT13
)
1896 /* Install FAT32 bootcode */
1897 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
1898 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
1899 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1900 wcscat(DstPath
, L
"\\bootsect.ros");
1902 DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, DstPath
);
1903 Status
= InstallFat32BootCodeToFile(SrcPath
,
1905 SystemRootPath
->Buffer
);
1906 if (!NT_SUCCESS(Status
))
1908 DPRINT1("InstallFat32BootCodeToFile() failed (Status %lx)\n", Status
);
1914 /* Install FAT16 bootcode */
1915 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
1916 wcscat(SrcPath
, L
"\\loader\\fat.bin");
1917 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1918 wcscat(DstPath
, L
"\\bootsect.ros");
1920 DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath
, DstPath
);
1921 Status
= InstallFat16BootCodeToFile(SrcPath
,
1923 SystemRootPath
->Buffer
);
1924 if (!NT_SUCCESS(Status
))
1926 DPRINT1("InstallFat16BootCodeToFile() failed (Status %lx)\n", Status
);
1933 /* Update existing 'freeldr.ini' */
1934 DPRINT1("Update existing 'freeldr.ini'\n");
1935 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1936 wcscat(DstPath
, L
"\\freeldr.ini");
1938 Status
= UpdateFreeLoaderIni(DstPath
,
1939 DestinationArcPath
->Buffer
);
1940 if (!NT_SUCCESS(Status
))
1942 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
1947 /* Update 'boot.ini' */
1948 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1949 wcscat(DstPath
, L
"\\boot.ini");
1951 DPRINT1("Update 'boot.ini': %S\n", DstPath
);
1952 Status
= UpdateBootIni(DstPath
,
1953 L
"C:\\bootsect.ros",
1955 if (!NT_SUCCESS(Status
))
1957 DPRINT1("UpdateBootIni() failed (Status %lx)\n", Status
);
1961 else if (DoesFileExist(SystemRootPath
->Buffer
, L
"io.sys") == TRUE
||
1962 DoesFileExist(SystemRootPath
->Buffer
, L
"msdos.sys") == TRUE
)
1964 /* Search for root directory for 'io.sys' and 'msdos.sys'. */
1965 DPRINT1("Found Microsoft DOS or Windows 9x boot loader\n");
1967 /* Copy FreeLoader to the boot partition */
1968 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
1969 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
1970 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1971 wcscat(DstPath
, L
"\\freeldr.sys");
1973 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
1974 Status
= SetupCopyFile(SrcPath
, DstPath
);
1975 if (!NT_SUCCESS(Status
))
1977 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
1981 /* Create or update 'freeldr.ini' */
1982 if (DoesFileExist(SystemRootPath
->Buffer
, L
"freeldr.ini") == FALSE
)
1984 /* Create new 'freeldr.ini' */
1985 DPRINT1("Create new 'freeldr.ini'\n");
1986 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1987 wcscat(DstPath
, L
"\\freeldr.ini");
1989 Status
= CreateFreeLoaderIniForDos(DstPath
,
1990 DestinationArcPath
->Buffer
);
1991 if (!NT_SUCCESS(Status
))
1993 DPRINT1("CreateFreeLoaderIniForDos() failed (Status %lx)\n", Status
);
1997 /* Save current bootsector as 'BOOTSECT.DOS' */
1998 wcscpy(SrcPath
, SystemRootPath
->Buffer
);
1999 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2000 wcscat(DstPath
, L
"\\bootsect.dos");
2002 DPRINT1("Save bootsector: %S ==> %S\n", SrcPath
, DstPath
);
2003 Status
= SaveCurrentBootSector(SrcPath
,
2005 if (!NT_SUCCESS(Status
))
2007 DPRINT1("SaveCurrentBootSector() failed (Status %lx)\n", Status
);
2011 /* Install new bootsector */
2012 if (PartitionType
== PARTITION_FAT32
||
2013 PartitionType
== PARTITION_FAT32_XINT13
)
2015 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2016 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
2018 DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2019 Status
= InstallFat32BootCodeToDisk(SrcPath
,
2020 SystemRootPath
->Buffer
);
2021 if (!NT_SUCCESS(Status
))
2023 DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)\n", Status
);
2029 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2030 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2032 DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2033 Status
= InstallFat16BootCodeToDisk(SrcPath
,
2034 SystemRootPath
->Buffer
);
2035 if (!NT_SUCCESS(Status
))
2037 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status
);
2044 /* Update existing 'freeldr.ini' */
2045 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2046 wcscat(DstPath
, L
"\\freeldr.ini");
2048 Status
= UpdateFreeLoaderIni(DstPath
,
2049 DestinationArcPath
->Buffer
);
2050 if (!NT_SUCCESS(Status
))
2052 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
2059 /* No or unknown boot loader */
2060 DPRINT1("No or unknown boot loader found\n");
2062 /* Copy FreeLoader to the boot partition */
2063 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2064 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
2065 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2066 wcscat(DstPath
, L
"\\freeldr.sys");
2068 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2069 Status
= SetupCopyFile(SrcPath
, DstPath
);
2070 if (!NT_SUCCESS(Status
))
2072 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
2076 /* Create or update 'freeldr.ini' */
2077 if (DoesFileExist(SystemRootPath
->Buffer
, L
"freeldr.ini") == FALSE
)
2079 /* Create new freeldr.ini */
2080 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2081 wcscat(DstPath
, L
"\\freeldr.ini");
2083 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2084 Status
= CreateFreeLoaderIniForReactos(DstPath
,
2085 DestinationArcPath
->Buffer
);
2086 if (!NT_SUCCESS(Status
))
2088 DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status
);
2092 /* Save current bootsector as 'BOOTSECT.OLD' */
2093 wcscpy(SrcPath
, SystemRootPath
->Buffer
);
2094 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2095 wcscat(DstPath
, L
"\\bootsect.old");
2097 DPRINT("Save bootsector: %S ==> %S\n", SrcPath
, DstPath
);
2098 Status
= SaveCurrentBootSector(SrcPath
,
2100 if (!NT_SUCCESS(Status
))
2102 DPRINT1("SaveCurrentBootSector() failed (Status %lx)\n", Status
);
2106 /* Install new bootsector */
2107 if (PartitionType
== PARTITION_FAT32
||
2108 PartitionType
== PARTITION_FAT32_XINT13
)
2110 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2111 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
2113 DPRINT("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2114 Status
= InstallFat32BootCodeToDisk(SrcPath
,
2115 SystemRootPath
->Buffer
);
2116 if (!NT_SUCCESS(Status
))
2118 DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)\n", Status
);
2124 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2125 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2127 DPRINT("Install FAT bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2128 Status
= InstallFat16BootCodeToDisk(SrcPath
,
2129 SystemRootPath
->Buffer
);
2130 if (!NT_SUCCESS(Status
))
2132 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status
);
2139 /* Update existing 'freeldr.ini' */
2140 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2141 wcscat(DstPath
, L
"\\freeldr.ini");
2143 Status
= UpdateFreeLoaderIni(DstPath
,
2144 DestinationArcPath
->Buffer
);
2145 if (!NT_SUCCESS(Status
))
2147 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
2153 return STATUS_SUCCESS
;
2155 return STATUS_NOT_IMPLEMENTED
;
2161 InstallFatBootcodeToFloppy(PUNICODE_STRING SourceRootPath
,
2162 PUNICODE_STRING DestinationArcPath
)
2165 WCHAR SrcPath
[MAX_PATH
];
2166 WCHAR DstPath
[MAX_PATH
];
2169 /* Copy FreeLoader to the boot partition */
2170 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2171 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
2173 wcscpy(DstPath
, L
"\\Device\\Floppy0\\freeldr.sys");
2175 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2176 Status
= SetupCopyFile(SrcPath
, DstPath
);
2177 if (!NT_SUCCESS(Status
))
2179 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
2183 /* Create new 'freeldr.ini' */
2184 wcscpy(DstPath
, L
"\\Device\\Floppy0\\freeldr.ini");
2186 DPRINT("Create new 'freeldr.ini'\n");
2187 Status
= CreateFreeLoaderIniForReactos(DstPath
,
2188 DestinationArcPath
->Buffer
);
2189 if (!NT_SUCCESS(Status
))
2191 DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status
);
2195 /* Install FAT12/16 boosector */
2196 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2197 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2199 wcscpy(DstPath
, L
"\\Device\\Floppy0");
2201 DPRINT("Install FAT bootcode: %S ==> %S\n", SrcPath
, DstPath
);
2202 Status
= InstallFat16BootCodeToDisk(SrcPath
,
2204 if (!NT_SUCCESS(Status
))
2206 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status
);
2210 return STATUS_SUCCESS
;
2212 return STATUS_NOT_IMPLEMENTED
;