3 * Copyright (C) 2002 ReactOS Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 * COPYRIGHT: See COPYING in the top level directory
21 * PROJECT: ReactOS text-mode setup
22 * FILE: subsys/system/usetup/bootsup.c
23 * PURPOSE: Bootloader support functions
24 * PROGRAMMER: Eric Kohl
32 #define SECTORSIZE 512
34 /* FUNCTIONS ****************************************************************/
38 CreateCommonFreeLoaderSections(PINICACHE IniCache
)
40 PINICACHESECTION IniSection
;
42 /* Create "FREELOADER" section */
43 IniSection
= IniCacheAppendSection(IniCache
,
47 if (IsUnattendedSetup
)
49 /* DefaultOS=ReactOS */
50 IniCacheInsertKey(IniSection
,
59 /* DefaultOS=ReactOS */
60 IniCacheInsertKey(IniSection
,
68 if (IsUnattendedSetup
)
71 /* Timeout=0 for unattended or non debug*/
72 IniCacheInsertKey(IniSection
,
82 IniCacheInsertKey(IniSection
,
90 /* Create "Display" section */
91 IniSection
= IniCacheAppendSection(IniCache
,
94 /* TitleText=ReactOS Boot Manager */
95 IniCacheInsertKey(IniSection
,
99 L
"ReactOS Boot Manager");
101 /* StatusBarColor=Cyan */
102 IniCacheInsertKey(IniSection
,
108 /* StatusBarTextColor=Black */
109 IniCacheInsertKey(IniSection
,
112 L
"StatusBarTextColor",
115 /* BackdropTextColor=White */
116 IniCacheInsertKey(IniSection
,
119 L
"BackdropTextColor",
122 /* BackdropColor=Blue */
123 IniCacheInsertKey(IniSection
,
129 /* BackdropFillStyle=Medium */
130 IniCacheInsertKey(IniSection
,
133 L
"BackdropFillStyle",
136 /* TitleBoxTextColor=White */
137 IniCacheInsertKey(IniSection
,
140 L
"TitleBoxTextColor",
143 /* TitleBoxColor=Red */
144 IniCacheInsertKey(IniSection
,
150 /* MessageBoxTextColor=White */
151 IniCacheInsertKey(IniSection
,
154 L
"MessageBoxTextColor",
157 /* MessageBoxColor=Blue */
158 IniCacheInsertKey(IniSection
,
164 /* MenuTextColor=White */
165 IniCacheInsertKey(IniSection
,
172 IniCacheInsertKey(IniSection
,
178 /* TextColor=Yellow */
179 IniCacheInsertKey(IniSection
,
185 /* SelectedTextColor=Black */
186 IniCacheInsertKey(IniSection
,
189 L
"SelectedTextColor",
192 /* SelectedColor=Gray */
193 IniCacheInsertKey(IniSection
,
199 /* SelectedColor=Gray */
200 IniCacheInsertKey(IniSection
,
206 /* SelectedColor=Gray */
207 IniCacheInsertKey(IniSection
,
213 /* SelectedColor=Gray */
214 IniCacheInsertKey(IniSection
,
220 /* SelectedColor=Gray */
221 IniCacheInsertKey(IniSection
,
227 /* SelectedColor=Gray */
228 IniCacheInsertKey(IniSection
,
232 L
"Seconds until highlighted choice will be started automatically: ");
237 CreateFreeLoaderIniForDos(PWCHAR IniPath
,
241 PINICACHESECTION IniSection
;
243 IniCache
= IniCacheCreate();
245 CreateCommonFreeLoaderSections(IniCache
);
247 /* Create "Operating Systems" section */
248 IniSection
= IniCacheAppendSection(IniCache
,
249 L
"Operating Systems");
251 /* REACTOS=ReactOS */
252 IniCacheInsertKey(IniSection
,
258 /* ReactOS_Debug="ReactOS (Debug)" */
259 IniCacheInsertKey(IniSection
,
263 L
"\"ReactOS (Debug)\"");
265 /* DOS=Dos/Windows */
266 IniCacheInsertKey(IniSection
,
272 /* Create "ReactOS" section */
273 IniSection
= IniCacheAppendSection(IniCache
,
276 /* BootType=ReactOS */
277 IniCacheInsertKey(IniSection
,
283 /* SystemPath=<ArcPath> */
284 IniCacheInsertKey(IniSection
,
290 /* Create "ReactOS_Debug" section */
291 IniSection
= IniCacheAppendSection(IniCache
,
294 /* BootType=ReactOS */
295 IniCacheInsertKey(IniSection
,
301 /* SystemPath=<ArcPath> */
302 IniCacheInsertKey(IniSection
,
308 /* Options=/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS*/
309 IniCacheInsertKey(IniSection
,
313 L
"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS");
315 /* Create "DOS" section */
316 IniSection
= IniCacheAppendSection(IniCache
,
319 /* BootType=BootSector */
320 IniCacheInsertKey(IniSection
,
327 IniCacheInsertKey(IniSection
,
333 /* BootPartition=1 */
334 IniCacheInsertKey(IniSection
,
340 /* BootSector=BOOTSECT.DOS */
341 IniCacheInsertKey(IniSection
,
347 IniCacheSave(IniCache
, IniPath
);
348 IniCacheDestroy(IniCache
);
350 return(STATUS_SUCCESS
);
355 CreateFreeLoaderIniForReactos(PWCHAR IniPath
,
359 PINICACHESECTION IniSection
;
361 IniCache
= IniCacheCreate();
363 CreateCommonFreeLoaderSections(IniCache
);
365 /* Create "Operating Systems" section */
366 IniSection
= IniCacheAppendSection(IniCache
,
367 L
"Operating Systems");
369 /* ReactOS="ReactOS" */
370 IniCacheInsertKey(IniSection
,
376 /* ReactOS_Debug="ReactOS (Debug)" */
377 IniCacheInsertKey(IniSection
,
381 L
"\"ReactOS (Debug)\"");
384 /* ReactOS_KdSerial="ReactOS (RosDbg)" */
385 IniCacheInsertKey(IniSection
,
389 L
"\"ReactOS (RosDbg)\"");
391 /* ReactOS_WinLdr="ReactOS (WinLdr)" */
392 IniCacheInsertKey(IniSection
,
396 L
"\"ReactOS (WinLdr)\"");
398 /* ReactOS_Ram="ReactOS (RAM Disk)" */
399 IniCacheInsertKey(IniSection
,
403 L
"\"ReactOS (RAM Disk)\"");
406 /* Create "ReactOS" section */
407 IniSection
= IniCacheAppendSection(IniCache
,
410 /* BootType=ReactOS */
411 IniCacheInsertKey(IniSection
,
417 /* SystemPath=<ArcPath> */
418 IniCacheInsertKey(IniSection
,
425 IniCacheInsertKey(IniSection
,
431 /* Create "ReactOS_Debug" section */
432 IniSection
= IniCacheAppendSection(IniCache
,
435 /* BootType=ReactOS */
436 IniCacheInsertKey(IniSection
,
442 /* SystemPath=<ArcPath> */
443 IniCacheInsertKey(IniSection
,
449 /* Options=/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS*/
450 IniCacheInsertKey(IniSection
,
454 L
"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS");
458 /* Create "ReactOS_KdSerial" section */
459 IniSection
= IniCacheAppendSection(IniCache
,
460 L
"ReactOS_KdSerial");
462 /* BootType=ReactOS */
463 IniCacheInsertKey(IniSection
,
469 /* SystemPath=<ArcPath> */
470 IniCacheInsertKey(IniSection
,
476 /* Options=/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS*/
477 IniCacheInsertKey(IniSection
,
481 L
"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /KDSERIAL");
483 /* ------------------------------------------------------------------------------ */
485 /* Create "ReactOS_WinLdr" section */
486 IniSection
= IniCacheAppendSection(IniCache
,
489 /* BootType=Windows2003 */
490 IniCacheInsertKey(IniSection
,
496 /* SystemPath=<ArcPath> */
497 IniCacheInsertKey(IniSection
,
503 /* Options=/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS*/
504 IniCacheInsertKey(IniSection
,
508 L
"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS");
510 /* Create "ReactOS_Ram" section */
511 IniSection
= IniCacheAppendSection(IniCache
,
514 /* BootType=ReactOS */
515 IniCacheInsertKey(IniSection
,
521 /* SystemPath=ramdisk(0)\\ReactOS */
522 IniCacheInsertKey(IniSection
,
526 L
"ramdisk(0)\\ReactOS");
528 /* Options=/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /RDIMAGEPATH=reactos.img /RDIMAGEOFFSET=32256*/
529 IniCacheInsertKey(IniSection
,
533 L
"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /RDIMAGEPATH=reactos.img /RDIMAGEOFFSET=32256");
537 /* Save the ini file */
538 IniCacheSave(IniCache
, IniPath
);
539 IniCacheDestroy(IniCache
);
541 return(STATUS_SUCCESS
);
546 UpdateFreeLoaderIni(PWCHAR IniPath
,
551 PINICACHESECTION IniSection
;
552 PINICACHESECTION OsIniSection
;
553 WCHAR SectionName
[80];
555 WCHAR SystemPath
[200];
556 WCHAR SectionName2
[200];
561 RtlInitUnicodeString(&Name
,
564 Status
= IniCacheLoad(&IniCache
,
567 if (!NT_SUCCESS(Status
))
570 /* Get "Operating Systems" section */
571 IniSection
= IniCacheGetSection(IniCache
,
572 L
"Operating Systems");
573 if (IniSection
== NULL
)
575 IniCacheDestroy(IniCache
);
576 return(STATUS_UNSUCCESSFUL
);
579 /* Find an existing usable or an unused section name */
581 wcscpy(SectionName
, L
"ReactOS");
582 wcscpy(OsName
, L
"\"ReactOS\"");
585 Status
= IniCacheGetKey(IniSection
,
588 if (!NT_SUCCESS(Status
))
591 /* Get operation system section */
592 if (KeyData
[0] == '"')
594 wcscpy(SectionName2
, &KeyData
[1]);
595 j
= wcslen(SectionName2
);
598 SectionName2
[j
-1] = 0;
603 wcscpy(SectionName2
, KeyData
);
606 OsIniSection
= IniCacheGetSection(IniCache
,
608 if (OsIniSection
!= NULL
)
610 BOOLEAN UseExistingEntry
= TRUE
;
613 Status
= IniCacheGetKey(OsIniSection
,
616 if (NT_SUCCESS(Status
))
619 || (_wcsicmp(KeyData
, L
"ReactOS") != 0
620 && _wcsicmp(KeyData
, L
"\"ReactOS\"") != 0))
622 /* This is not a ReactOS entry */
623 UseExistingEntry
= FALSE
;
628 UseExistingEntry
= FALSE
;
631 if (UseExistingEntry
)
633 /* BootType is ReactOS. Now check SystemPath */
634 Status
= IniCacheGetKey(OsIniSection
,
637 if (NT_SUCCESS(Status
))
639 swprintf(SystemPath
, L
"\"%S\"", ArcPath
);
641 || (_wcsicmp(KeyData
, ArcPath
) != 0
642 && _wcsicmp(KeyData
, SystemPath
) != 0))
644 /* This entry is a ReactOS entry, but the SystemRoot does not
645 match the one we are looking for */
646 UseExistingEntry
= FALSE
;
651 UseExistingEntry
= FALSE
;
655 if (UseExistingEntry
)
657 IniCacheDestroy(IniCache
);
658 return(STATUS_SUCCESS
);
662 swprintf(SectionName
, L
"ReactOS_%lu", i
);
663 swprintf(OsName
, L
"\"ReactOS %lu\"", i
);
667 /* <SectionName>=<OsName> */
668 IniCacheInsertKey(IniSection
,
674 /* Create <SectionName> section */
675 IniSection
= IniCacheAppendSection(IniCache
,
678 /* BootType=ReactOS */
679 IniCacheInsertKey(IniSection
,
685 /* SystemPath=<ArcPath> */
686 IniCacheInsertKey(IniSection
,
692 IniCacheSave(IniCache
, IniPath
);
693 IniCacheDestroy(IniCache
);
695 return(STATUS_SUCCESS
);
700 SaveCurrentBootSector(PWSTR RootPath
,
703 OBJECT_ATTRIBUTES ObjectAttributes
;
704 IO_STATUS_BLOCK IoStatusBlock
;
710 /* Allocate buffer for bootsector */
711 BootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
714 if (BootSector
== NULL
)
715 return(STATUS_INSUFFICIENT_RESOURCES
);
717 /* Read current boot sector into buffer */
718 RtlInitUnicodeString(&Name
,
721 InitializeObjectAttributes(&ObjectAttributes
,
723 OBJ_CASE_INSENSITIVE
,
727 Status
= NtOpenFile(&FileHandle
,
732 FILE_SYNCHRONOUS_IO_NONALERT
);
733 if (!NT_SUCCESS(Status
))
735 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
739 Status
= NtReadFile(FileHandle
,
749 if (!NT_SUCCESS(Status
))
751 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
755 /* Write bootsector to DstPath */
756 RtlInitUnicodeString(&Name
,
759 InitializeObjectAttributes(&ObjectAttributes
,
765 Status
= NtCreateFile(&FileHandle
,
770 FILE_ATTRIBUTE_NORMAL
,
773 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
,
776 if (!NT_SUCCESS(Status
))
778 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
782 Status
= NtWriteFile(FileHandle
,
793 /* Free the new boot sector */
794 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
801 InstallFat16BootCodeToFile(PWSTR SrcPath
,
805 OBJECT_ATTRIBUTES ObjectAttributes
;
806 IO_STATUS_BLOCK IoStatusBlock
;
810 PUCHAR OrigBootSector
;
811 PUCHAR NewBootSector
;
813 /* Allocate buffer for original bootsector */
814 OrigBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
817 if (OrigBootSector
== NULL
)
818 return(STATUS_INSUFFICIENT_RESOURCES
);
820 /* Read current boot sector into buffer */
821 RtlInitUnicodeString(&Name
,
824 InitializeObjectAttributes(&ObjectAttributes
,
826 OBJ_CASE_INSENSITIVE
,
830 Status
= NtOpenFile(&FileHandle
,
835 FILE_SYNCHRONOUS_IO_NONALERT
);
836 if (!NT_SUCCESS(Status
))
838 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
842 Status
= NtReadFile(FileHandle
,
852 if (!NT_SUCCESS(Status
))
854 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
859 /* Allocate buffer for new bootsector */
860 NewBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
863 if (NewBootSector
== NULL
)
865 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
866 return(STATUS_INSUFFICIENT_RESOURCES
);
869 /* Read new bootsector from SrcPath */
870 RtlInitUnicodeString(&Name
,
873 InitializeObjectAttributes(&ObjectAttributes
,
875 OBJ_CASE_INSENSITIVE
,
879 Status
= NtOpenFile(&FileHandle
,
884 FILE_SYNCHRONOUS_IO_NONALERT
);
885 if (!NT_SUCCESS(Status
))
887 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
888 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
892 Status
= NtReadFile(FileHandle
,
902 if (!NT_SUCCESS(Status
))
904 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
905 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
909 /* Adjust bootsector (copy a part of the FAT BPB) */
910 memcpy((NewBootSector
+ 11), (OrigBootSector
+ 11), 51 /*fat BPB length*/);
912 /* Free the original boot sector */
913 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
915 /* Write new bootsector to DstPath */
916 RtlInitUnicodeString(&Name
,
919 InitializeObjectAttributes(&ObjectAttributes
,
925 Status
= NtCreateFile(&FileHandle
,
930 FILE_ATTRIBUTE_NORMAL
,
933 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
,
936 if (!NT_SUCCESS(Status
))
938 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
943 FilePosition
.QuadPart
= 0;
945 Status
= NtWriteFile(FileHandle
,
956 /* Free the new boot sector */
957 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
964 InstallFat32BootCodeToFile(PWSTR SrcPath
,
968 OBJECT_ATTRIBUTES ObjectAttributes
;
969 IO_STATUS_BLOCK IoStatusBlock
;
973 PUCHAR OrigBootSector
;
974 PUCHAR NewBootSector
;
975 LARGE_INTEGER FileOffset
;
977 /* Allocate buffer for original bootsector */
978 OrigBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
981 if (OrigBootSector
== NULL
)
982 return(STATUS_INSUFFICIENT_RESOURCES
);
984 /* Read current boot sector into buffer */
985 RtlInitUnicodeString(&Name
,
988 InitializeObjectAttributes(&ObjectAttributes
,
990 OBJ_CASE_INSENSITIVE
,
994 Status
= NtOpenFile(&FileHandle
,
999 FILE_SYNCHRONOUS_IO_NONALERT
);
1000 if (!NT_SUCCESS(Status
))
1002 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1006 Status
= NtReadFile(FileHandle
,
1015 NtClose(FileHandle
);
1016 if (!NT_SUCCESS(Status
))
1018 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1022 /* Allocate buffer for new bootsector (2 sectors) */
1023 NewBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
1026 if (NewBootSector
== NULL
)
1028 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1029 return(STATUS_INSUFFICIENT_RESOURCES
);
1032 /* Read new bootsector from SrcPath */
1033 RtlInitUnicodeString(&Name
,
1036 InitializeObjectAttributes(&ObjectAttributes
,
1038 OBJ_CASE_INSENSITIVE
,
1042 Status
= NtOpenFile(&FileHandle
,
1047 FILE_SYNCHRONOUS_IO_NONALERT
);
1048 if (!NT_SUCCESS(Status
))
1050 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1051 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1055 Status
= NtReadFile(FileHandle
,
1064 NtClose(FileHandle
);
1065 if (!NT_SUCCESS(Status
))
1067 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1068 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1072 /* Adjust bootsector (copy a part of the FAT32 BPB) */
1073 memcpy((NewBootSector
+ 3),
1074 (OrigBootSector
+ 3),
1075 87); /* FAT32 BPB length */
1077 /* Disable the backup boot sector */
1078 NewBootSector
[0x32] = 0x00;
1079 NewBootSector
[0x33] = 0x00;
1081 /* Free the original boot sector */
1082 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1084 /* Write the first sector of the new bootcode to DstPath */
1085 RtlInitUnicodeString(&Name
,
1088 InitializeObjectAttributes(&ObjectAttributes
,
1094 Status
= NtCreateFile(&FileHandle
,
1099 FILE_ATTRIBUTE_NORMAL
,
1102 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
,
1105 if (!NT_SUCCESS(Status
))
1107 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1111 Status
= NtWriteFile(FileHandle
,
1120 NtClose(FileHandle
);
1121 if (!NT_SUCCESS(Status
))
1123 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1127 /* Write the second sector of the new bootcode to boot disk sector 14 */
1128 RtlInitUnicodeString(&Name
,
1131 InitializeObjectAttributes(&ObjectAttributes
,
1137 Status
= NtOpenFile(&FileHandle
,
1142 FILE_SYNCHRONOUS_IO_NONALERT
);
1143 if (!NT_SUCCESS(Status
))
1145 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1149 FileOffset
.QuadPart
= (ULONGLONG
)(14 * SECTORSIZE
);
1150 Status
= NtWriteFile(FileHandle
,
1155 (NewBootSector
+ SECTORSIZE
),
1159 if (!NT_SUCCESS(Status
))
1162 NtClose(FileHandle
);
1164 /* Free the new boot sector */
1165 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1172 InstallMbrBootCodeToDisk (PWSTR SrcPath
,
1175 OBJECT_ATTRIBUTES ObjectAttributes
;
1176 IO_STATUS_BLOCK IoStatusBlock
;
1177 UNICODE_STRING Name
;
1180 PPARTITION_SECTOR OrigBootSector
;
1181 PPARTITION_SECTOR NewBootSector
;
1183 /* Allocate buffer for original bootsector */
1184 OrigBootSector
= (PPARTITION_SECTOR
)RtlAllocateHeap(ProcessHeap
,
1186 sizeof(PARTITION_SECTOR
));
1187 if (OrigBootSector
== NULL
)
1188 return(STATUS_INSUFFICIENT_RESOURCES
);
1190 /* Read current boot sector into buffer */
1191 RtlInitUnicodeString(&Name
,
1194 InitializeObjectAttributes(&ObjectAttributes
,
1196 OBJ_CASE_INSENSITIVE
,
1200 Status
= NtOpenFile(&FileHandle
,
1205 FILE_SYNCHRONOUS_IO_NONALERT
);
1206 if (!NT_SUCCESS(Status
))
1208 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1212 Status
= NtReadFile(FileHandle
,
1221 NtClose(FileHandle
);
1222 if (!NT_SUCCESS(Status
))
1224 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1229 /* Allocate buffer for new bootsector */
1230 NewBootSector
= (PPARTITION_SECTOR
)RtlAllocateHeap(ProcessHeap
,
1232 sizeof(PARTITION_SECTOR
));
1233 if (NewBootSector
== NULL
)
1235 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1236 return(STATUS_INSUFFICIENT_RESOURCES
);
1239 /* Read new bootsector from SrcPath */
1240 RtlInitUnicodeString(&Name
,
1243 InitializeObjectAttributes(&ObjectAttributes
,
1245 OBJ_CASE_INSENSITIVE
,
1249 Status
= NtOpenFile(&FileHandle
,
1254 FILE_SYNCHRONOUS_IO_NONALERT
);
1255 if (!NT_SUCCESS(Status
))
1257 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1258 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1262 Status
= NtReadFile(FileHandle
,
1268 sizeof(PARTITION_SECTOR
),
1271 NtClose(FileHandle
);
1272 if (!NT_SUCCESS(Status
))
1274 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1275 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1279 /* Copy partition table from old MBR to new */
1280 RtlCopyMemory (&NewBootSector
->Signature
,
1281 &OrigBootSector
->Signature
,
1282 sizeof(PARTITION_SECTOR
) - offsetof(PARTITION_SECTOR
, Signature
) /* Length of partition table */);
1284 /* Free the original boot sector */
1285 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1287 /* Write new bootsector to RootPath */
1288 RtlInitUnicodeString(&Name
,
1291 InitializeObjectAttributes(&ObjectAttributes
,
1297 Status
= NtOpenFile(&FileHandle
,
1302 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1303 if (!NT_SUCCESS(Status
))
1305 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1306 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1310 Status
= NtWriteFile(FileHandle
,
1319 NtClose(FileHandle
);
1321 /* Free the new boot sector */
1322 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1329 InstallFat16BootCodeToDisk(PWSTR SrcPath
,
1332 OBJECT_ATTRIBUTES ObjectAttributes
;
1333 IO_STATUS_BLOCK IoStatusBlock
;
1334 UNICODE_STRING Name
;
1337 PUCHAR OrigBootSector
;
1338 PUCHAR NewBootSector
;
1340 /* Allocate buffer for original bootsector */
1341 OrigBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
1344 if (OrigBootSector
== NULL
)
1345 return(STATUS_INSUFFICIENT_RESOURCES
);
1347 /* Read current boot sector into buffer */
1348 RtlInitUnicodeString(&Name
,
1351 InitializeObjectAttributes(&ObjectAttributes
,
1353 OBJ_CASE_INSENSITIVE
,
1357 Status
= NtOpenFile(&FileHandle
,
1362 FILE_SYNCHRONOUS_IO_NONALERT
);
1363 if (!NT_SUCCESS(Status
))
1365 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1369 Status
= NtReadFile(FileHandle
,
1378 NtClose(FileHandle
);
1379 if (!NT_SUCCESS(Status
))
1381 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1386 /* Allocate buffer for new bootsector */
1387 NewBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
1390 if (NewBootSector
== NULL
)
1392 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1393 return(STATUS_INSUFFICIENT_RESOURCES
);
1396 /* Read new bootsector from SrcPath */
1397 RtlInitUnicodeString(&Name
,
1400 InitializeObjectAttributes(&ObjectAttributes
,
1402 OBJ_CASE_INSENSITIVE
,
1406 Status
= NtOpenFile(&FileHandle
,
1411 FILE_SYNCHRONOUS_IO_NONALERT
);
1412 if (!NT_SUCCESS(Status
))
1414 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1415 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1419 Status
= NtReadFile(FileHandle
,
1428 NtClose(FileHandle
);
1429 if (!NT_SUCCESS(Status
))
1431 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1432 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1436 /* Adjust bootsector (copy a part of the FAT16 BPB) */
1437 memcpy((NewBootSector
+ 3),
1438 (OrigBootSector
+ 3),
1439 59); /* FAT16 BPB length*/
1441 /* Free the original boot sector */
1442 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1444 /* Write new bootsector to RootPath */
1445 RtlInitUnicodeString(&Name
,
1448 InitializeObjectAttributes(&ObjectAttributes
,
1454 Status
= NtOpenFile(&FileHandle
,
1459 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1460 if (!NT_SUCCESS(Status
))
1462 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1463 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1468 FilePosition
.QuadPart
= 0;
1470 Status
= NtWriteFile(FileHandle
,
1479 NtClose(FileHandle
);
1481 /* Free the new boot sector */
1482 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1489 InstallFat32BootCodeToDisk(PWSTR SrcPath
,
1492 OBJECT_ATTRIBUTES ObjectAttributes
;
1493 IO_STATUS_BLOCK IoStatusBlock
;
1494 UNICODE_STRING Name
;
1497 PUCHAR OrigBootSector
;
1498 PUCHAR NewBootSector
;
1499 LARGE_INTEGER FileOffset
;
1500 USHORT BackupBootSector
;
1502 /* Allocate buffer for original bootsector */
1503 OrigBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
1506 if (OrigBootSector
== NULL
)
1507 return(STATUS_INSUFFICIENT_RESOURCES
);
1509 /* Read current boot sector into buffer */
1510 RtlInitUnicodeString(&Name
,
1513 InitializeObjectAttributes(&ObjectAttributes
,
1515 OBJ_CASE_INSENSITIVE
,
1519 Status
= NtOpenFile(&FileHandle
,
1524 FILE_SYNCHRONOUS_IO_NONALERT
);
1525 if (!NT_SUCCESS(Status
))
1527 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1531 Status
= NtReadFile(FileHandle
,
1540 NtClose(FileHandle
);
1541 if (!NT_SUCCESS(Status
))
1543 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1548 /* Allocate buffer for new bootsector (2 sectors) */
1549 NewBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
1552 if (NewBootSector
== NULL
)
1554 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1555 return(STATUS_INSUFFICIENT_RESOURCES
);
1558 /* Read new bootsector from SrcPath */
1559 RtlInitUnicodeString(&Name
,
1562 InitializeObjectAttributes(&ObjectAttributes
,
1564 OBJ_CASE_INSENSITIVE
,
1568 Status
= NtOpenFile(&FileHandle
,
1573 FILE_SYNCHRONOUS_IO_NONALERT
);
1574 if (!NT_SUCCESS(Status
))
1576 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1577 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1581 Status
= NtReadFile(FileHandle
,
1590 NtClose(FileHandle
);
1591 if (!NT_SUCCESS(Status
))
1593 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1594 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1598 /* Adjust bootsector (copy a part of the FAT32 BPB) */
1599 memcpy((NewBootSector
+ 3),
1600 (OrigBootSector
+ 3),
1601 87); /* FAT32 BPB length */
1603 /* Get the location of the backup boot sector */
1604 BackupBootSector
= (OrigBootSector
[0x33] << 8) + OrigBootSector
[0x32];
1606 /* Free the original boot sector */
1607 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1609 /* Write the first sector of the new bootcode to DstPath */
1610 RtlInitUnicodeString(&Name
,
1613 InitializeObjectAttributes(&ObjectAttributes
,
1619 Status
= NtOpenFile(&FileHandle
,
1624 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1625 if (!NT_SUCCESS(Status
))
1627 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1628 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1632 /* Write sector 0 */
1633 FileOffset
.QuadPart
= 0ULL;
1634 Status
= NtWriteFile(FileHandle
,
1643 if (!NT_SUCCESS(Status
))
1645 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1646 NtClose(FileHandle
);
1647 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1651 /* Write backup boot sector */
1652 if ((BackupBootSector
!= 0x0000) && (BackupBootSector
!= 0xFFFF))
1654 FileOffset
.QuadPart
= (ULONGLONG
)((ULONG
)BackupBootSector
* SECTORSIZE
);
1655 Status
= NtWriteFile(FileHandle
,
1664 if (!NT_SUCCESS(Status
))
1666 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1667 NtClose(FileHandle
);
1668 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1673 /* Write sector 14 */
1674 FileOffset
.QuadPart
= (ULONGLONG
)(14 * SECTORSIZE
);
1675 Status
= NtWriteFile(FileHandle
,
1680 (NewBootSector
+ SECTORSIZE
),
1684 if (!NT_SUCCESS(Status
))
1686 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1688 NtClose(FileHandle
);
1690 /* Free the new boot sector */
1691 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1698 UnprotectBootIni(PWSTR FileName
,
1701 UNICODE_STRING Name
;
1702 OBJECT_ATTRIBUTES ObjectAttributes
;
1703 IO_STATUS_BLOCK IoStatusBlock
;
1704 FILE_BASIC_INFORMATION FileInfo
;
1708 RtlInitUnicodeString(&Name
,
1711 InitializeObjectAttributes(&ObjectAttributes
,
1713 OBJ_CASE_INSENSITIVE
,
1717 Status
= NtOpenFile(&FileHandle
,
1718 GENERIC_READ
|GENERIC_WRITE
,
1722 FILE_SYNCHRONOUS_IO_NONALERT
);
1723 if (Status
== STATUS_NO_SUCH_FILE
)
1725 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1727 return(STATUS_SUCCESS
);
1729 if (!NT_SUCCESS(Status
))
1731 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1735 Status
= NtQueryInformationFile(FileHandle
,
1738 sizeof(FILE_BASIC_INFORMATION
),
1739 FileBasicInformation
);
1740 if (!NT_SUCCESS(Status
))
1742 DPRINT1("NtQueryInformationFile() failed (Status %lx)\n", Status
);
1743 NtClose(FileHandle
);
1747 *Attributes
= FileInfo
.FileAttributes
;
1749 /* Delete attributes SYSTEM, HIDDEN and READONLY */
1750 FileInfo
.FileAttributes
= FileInfo
.FileAttributes
&
1751 ~(FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
| FILE_ATTRIBUTE_READONLY
);
1753 Status
= NtSetInformationFile(FileHandle
,
1756 sizeof(FILE_BASIC_INFORMATION
),
1757 FileBasicInformation
);
1758 if (!NT_SUCCESS(Status
))
1760 DPRINT1("NtSetInformationFile() failed (Status %lx)\n", Status
);
1763 NtClose(FileHandle
);
1769 ProtectBootIni(PWSTR FileName
,
1772 UNICODE_STRING Name
;
1773 OBJECT_ATTRIBUTES ObjectAttributes
;
1774 IO_STATUS_BLOCK IoStatusBlock
;
1775 FILE_BASIC_INFORMATION FileInfo
;
1779 RtlInitUnicodeString(&Name
,
1782 InitializeObjectAttributes(&ObjectAttributes
,
1784 OBJ_CASE_INSENSITIVE
,
1788 Status
= NtOpenFile(&FileHandle
,
1789 GENERIC_READ
|GENERIC_WRITE
,
1793 FILE_SYNCHRONOUS_IO_NONALERT
);
1794 if (!NT_SUCCESS(Status
))
1796 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1800 Status
= NtQueryInformationFile(FileHandle
,
1803 sizeof(FILE_BASIC_INFORMATION
),
1804 FileBasicInformation
);
1805 if (!NT_SUCCESS(Status
))
1807 DPRINT1("NtQueryInformationFile() failed (Status %lx)\n", Status
);
1808 NtClose(FileHandle
);
1812 FileInfo
.FileAttributes
= FileInfo
.FileAttributes
| Attributes
;
1814 Status
= NtSetInformationFile(FileHandle
,
1817 sizeof(FILE_BASIC_INFORMATION
),
1818 FileBasicInformation
);
1819 if (!NT_SUCCESS(Status
))
1821 DPRINT1("NtSetInformationFile() failed (Status %lx)\n", Status
);
1824 NtClose(FileHandle
);
1830 UpdateBootIni(PWSTR BootIniPath
,
1834 UNICODE_STRING Name
;
1835 PINICACHE Cache
= NULL
;
1836 PINICACHESECTION Section
= NULL
;
1838 ULONG FileAttribute
;
1839 PWCHAR OldValue
= NULL
;
1841 RtlInitUnicodeString(&Name
,
1844 Status
= IniCacheLoad(&Cache
,
1847 if (!NT_SUCCESS(Status
))
1852 Section
= IniCacheGetSection(Cache
,
1853 L
"operating systems");
1854 if (Section
== NULL
)
1856 IniCacheDestroy(Cache
);
1857 return(STATUS_UNSUCCESSFUL
);
1860 /* Check - maybe record already exists */
1861 Status
= IniCacheGetKey(Section
,
1865 /* If either key was not found, or contains something else - add new one */
1866 if (!NT_SUCCESS(Status
) || wcscmp(OldValue
, EntryValue
))
1868 IniCacheInsertKey(Section
,
1875 Status
= UnprotectBootIni(BootIniPath
,
1877 if (!NT_SUCCESS(Status
))
1879 IniCacheDestroy(Cache
);
1883 Status
= IniCacheSave(Cache
,
1885 if (!NT_SUCCESS(Status
))
1887 IniCacheDestroy(Cache
);
1891 FileAttribute
|= (FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
| FILE_ATTRIBUTE_READONLY
);
1892 Status
= ProtectBootIni(BootIniPath
,
1895 IniCacheDestroy(Cache
);
1901 CheckInstallFatBootcodeToPartition(PUNICODE_STRING SystemRootPath
)
1904 if (DoesFileExist(SystemRootPath
->Buffer
, L
"ntldr") ||
1905 DoesFileExist(SystemRootPath
->Buffer
, L
"boot.ini"))
1909 else if (DoesFileExist(SystemRootPath
->Buffer
, L
"io.sys") ||
1910 DoesFileExist(SystemRootPath
->Buffer
, L
"msdos.sys"))
1921 InstallFatBootcodeToPartition(PUNICODE_STRING SystemRootPath
,
1922 PUNICODE_STRING SourceRootPath
,
1923 PUNICODE_STRING DestinationArcPath
,
1924 UCHAR PartitionType
)
1927 WCHAR SrcPath
[MAX_PATH
];
1928 WCHAR DstPath
[MAX_PATH
];
1931 /* FAT or FAT32 partition */
1932 DPRINT("System path: '%wZ'\n", SystemRootPath
);
1934 if (DoesFileExist(SystemRootPath
->Buffer
, L
"ntldr") == TRUE
||
1935 DoesFileExist(SystemRootPath
->Buffer
, L
"boot.ini") == TRUE
)
1937 /* Search root directory for 'ntldr' and 'boot.ini'. */
1938 DPRINT("Found Microsoft Windows NT/2000/XP boot loader\n");
1940 /* Copy FreeLoader to the boot partition */
1941 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
1942 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
1943 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1944 wcscat(DstPath
, L
"\\freeldr.sys");
1946 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
1947 Status
= SetupCopyFile(SrcPath
, DstPath
);
1948 if (!NT_SUCCESS(Status
))
1950 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
1954 /* Create or update freeldr.ini */
1955 if (DoesFileExist(SystemRootPath
->Buffer
, L
"freeldr.ini") == FALSE
)
1957 /* Create new 'freeldr.ini' */
1958 DPRINT1("Create new 'freeldr.ini'\n");
1959 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1960 wcscat(DstPath
, L
"\\freeldr.ini");
1962 Status
= CreateFreeLoaderIniForReactos(DstPath
,
1963 DestinationArcPath
->Buffer
);
1964 if (!NT_SUCCESS(Status
))
1966 DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status
);
1970 /* Install new bootcode */
1971 if (PartitionType
== PARTITION_FAT32
||
1972 PartitionType
== PARTITION_FAT32_XINT13
)
1974 /* Install FAT32 bootcode */
1975 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
1976 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
1977 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1978 wcscat(DstPath
, L
"\\bootsect.ros");
1980 DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, DstPath
);
1981 Status
= InstallFat32BootCodeToFile(SrcPath
,
1983 SystemRootPath
->Buffer
);
1984 if (!NT_SUCCESS(Status
))
1986 DPRINT1("InstallFat32BootCodeToFile() failed (Status %lx)\n", Status
);
1992 /* Install FAT16 bootcode */
1993 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
1994 wcscat(SrcPath
, L
"\\loader\\fat.bin");
1995 wcscpy(DstPath
, SystemRootPath
->Buffer
);
1996 wcscat(DstPath
, L
"\\bootsect.ros");
1998 DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath
, DstPath
);
1999 Status
= InstallFat16BootCodeToFile(SrcPath
,
2001 SystemRootPath
->Buffer
);
2002 if (!NT_SUCCESS(Status
))
2004 DPRINT1("InstallFat16BootCodeToFile() failed (Status %lx)\n", Status
);
2011 /* Update existing 'freeldr.ini' */
2012 DPRINT1("Update existing 'freeldr.ini'\n");
2013 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2014 wcscat(DstPath
, L
"\\freeldr.ini");
2016 Status
= UpdateFreeLoaderIni(DstPath
,
2017 DestinationArcPath
->Buffer
);
2018 if (!NT_SUCCESS(Status
))
2020 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
2025 /* Update 'boot.ini' */
2026 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2027 wcscat(DstPath
, L
"\\boot.ini");
2029 DPRINT1("Update 'boot.ini': %S\n", DstPath
);
2030 Status
= UpdateBootIni(DstPath
,
2031 L
"C:\\bootsect.ros",
2033 if (!NT_SUCCESS(Status
))
2035 DPRINT1("UpdateBootIni() failed (Status %lx)\n", Status
);
2039 else if (DoesFileExist(SystemRootPath
->Buffer
, L
"io.sys") == TRUE
||
2040 DoesFileExist(SystemRootPath
->Buffer
, L
"msdos.sys") == TRUE
)
2042 /* Search for root directory for 'io.sys' and 'msdos.sys'. */
2043 DPRINT1("Found Microsoft DOS or Windows 9x boot loader\n");
2045 /* Copy FreeLoader to the boot partition */
2046 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2047 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
2048 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2049 wcscat(DstPath
, L
"\\freeldr.sys");
2051 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2052 Status
= SetupCopyFile(SrcPath
, DstPath
);
2053 if (!NT_SUCCESS(Status
))
2055 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
2059 /* Create or update 'freeldr.ini' */
2060 if (DoesFileExist(SystemRootPath
->Buffer
, L
"freeldr.ini") == FALSE
)
2062 /* Create new 'freeldr.ini' */
2063 DPRINT1("Create new 'freeldr.ini'\n");
2064 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2065 wcscat(DstPath
, L
"\\freeldr.ini");
2067 Status
= CreateFreeLoaderIniForDos(DstPath
,
2068 DestinationArcPath
->Buffer
);
2069 if (!NT_SUCCESS(Status
))
2071 DPRINT1("CreateFreeLoaderIniForDos() failed (Status %lx)\n", Status
);
2075 /* Save current bootsector as 'BOOTSECT.DOS' */
2076 wcscpy(SrcPath
, SystemRootPath
->Buffer
);
2077 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2078 wcscat(DstPath
, L
"\\bootsect.dos");
2080 DPRINT1("Save bootsector: %S ==> %S\n", SrcPath
, DstPath
);
2081 Status
= SaveCurrentBootSector(SrcPath
,
2083 if (!NT_SUCCESS(Status
))
2085 DPRINT1("SaveCurrentBootSector() failed (Status %lx)\n", Status
);
2089 /* Install new bootsector */
2090 if (PartitionType
== PARTITION_FAT32
||
2091 PartitionType
== PARTITION_FAT32_XINT13
)
2093 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2094 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
2096 DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2097 Status
= InstallFat32BootCodeToDisk(SrcPath
,
2098 SystemRootPath
->Buffer
);
2099 if (!NT_SUCCESS(Status
))
2101 DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)\n", Status
);
2107 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2108 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2110 DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2111 Status
= InstallFat16BootCodeToDisk(SrcPath
,
2112 SystemRootPath
->Buffer
);
2113 if (!NT_SUCCESS(Status
))
2115 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status
);
2122 /* Update existing 'freeldr.ini' */
2123 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2124 wcscat(DstPath
, L
"\\freeldr.ini");
2126 Status
= UpdateFreeLoaderIni(DstPath
,
2127 DestinationArcPath
->Buffer
);
2128 if (!NT_SUCCESS(Status
))
2130 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
2137 /* No or unknown boot loader */
2138 DPRINT1("No or unknown boot loader found\n");
2140 /* Copy FreeLoader to the boot partition */
2141 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2142 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
2143 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2144 wcscat(DstPath
, L
"\\freeldr.sys");
2146 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2147 Status
= SetupCopyFile(SrcPath
, DstPath
);
2148 if (!NT_SUCCESS(Status
))
2150 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
2154 /* Create or update 'freeldr.ini' */
2155 if (DoesFileExist(SystemRootPath
->Buffer
, L
"freeldr.ini") == FALSE
)
2157 /* Create new freeldr.ini */
2158 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2159 wcscat(DstPath
, L
"\\freeldr.ini");
2161 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2162 Status
= CreateFreeLoaderIniForReactos(DstPath
,
2163 DestinationArcPath
->Buffer
);
2164 if (!NT_SUCCESS(Status
))
2166 DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status
);
2170 /* Save current bootsector as 'BOOTSECT.OLD' */
2171 wcscpy(SrcPath
, SystemRootPath
->Buffer
);
2172 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2173 wcscat(DstPath
, L
"\\bootsect.old");
2175 DPRINT("Save bootsector: %S ==> %S\n", SrcPath
, DstPath
);
2176 Status
= SaveCurrentBootSector(SrcPath
,
2178 if (!NT_SUCCESS(Status
))
2180 DPRINT1("SaveCurrentBootSector() failed (Status %lx)\n", Status
);
2184 /* Install new bootsector */
2185 if (PartitionType
== PARTITION_FAT32
||
2186 PartitionType
== PARTITION_FAT32_XINT13
)
2188 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2189 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
2191 DPRINT("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2192 Status
= InstallFat32BootCodeToDisk(SrcPath
,
2193 SystemRootPath
->Buffer
);
2194 if (!NT_SUCCESS(Status
))
2196 DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)\n", Status
);
2202 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2203 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2205 DPRINT("Install FAT bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2206 Status
= InstallFat16BootCodeToDisk(SrcPath
,
2207 SystemRootPath
->Buffer
);
2208 if (!NT_SUCCESS(Status
))
2210 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status
);
2217 /* Update existing 'freeldr.ini' */
2218 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2219 wcscat(DstPath
, L
"\\freeldr.ini");
2221 Status
= UpdateFreeLoaderIni(DstPath
,
2222 DestinationArcPath
->Buffer
);
2223 if (!NT_SUCCESS(Status
))
2225 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
2231 return STATUS_SUCCESS
;
2233 return STATUS_NOT_IMPLEMENTED
;
2239 InstallFatBootcodeToFloppy(PUNICODE_STRING SourceRootPath
,
2240 PUNICODE_STRING DestinationArcPath
)
2243 WCHAR SrcPath
[MAX_PATH
];
2244 WCHAR DstPath
[MAX_PATH
];
2247 /* Copy FreeLoader to the boot partition */
2248 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2249 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
2251 wcscpy(DstPath
, L
"\\Device\\Floppy0\\freeldr.sys");
2253 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2254 Status
= SetupCopyFile(SrcPath
, DstPath
);
2255 if (!NT_SUCCESS(Status
))
2257 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
2261 /* Create new 'freeldr.ini' */
2262 wcscpy(DstPath
, L
"\\Device\\Floppy0\\freeldr.ini");
2264 DPRINT("Create new 'freeldr.ini'\n");
2265 Status
= CreateFreeLoaderIniForReactos(DstPath
,
2266 DestinationArcPath
->Buffer
);
2267 if (!NT_SUCCESS(Status
))
2269 DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status
);
2273 /* Install FAT12/16 boosector */
2274 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2275 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2277 wcscpy(DstPath
, L
"\\Device\\Floppy0");
2279 DPRINT("Install FAT bootcode: %S ==> %S\n", SrcPath
, DstPath
);
2280 Status
= InstallFat16BootCodeToDisk(SrcPath
,
2282 if (!NT_SUCCESS(Status
))
2284 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status
);
2288 return STATUS_SUCCESS
;
2290 return STATUS_NOT_IMPLEMENTED
;