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
27 #include <ddk/ntddk.h>
28 #include <ntdll/rtl.h>
35 #define SECTORSIZE 512
37 /* FUNCTIONS ****************************************************************/
41 CreateCommonFreeLoaderSections(PINICACHE IniCache
)
43 PINICACHESECTION IniSection
;
45 /* Create "FREELOADER" section */
46 IniSection
= IniCacheAppendSection(IniCache
,
49 /* DefaultOS=ReactOS */
50 IniCacheInsertKey(IniSection
,
58 IniCacheInsertKey(IniSection
,
65 /* Create "Display" section */
66 IniSection
= IniCacheAppendSection(IniCache
,
69 /* TitleText=ReactOS Boot Manager */
70 IniCacheInsertKey(IniSection
,
74 L
"ReactOS Boot Manager");
76 /* StatusBarColor=Cyan */
77 IniCacheInsertKey(IniSection
,
83 /* StatusBarTextColor=Black */
84 IniCacheInsertKey(IniSection
,
87 L
"StatusBarTextColor",
90 /* BackdropTextColor=White */
91 IniCacheInsertKey(IniSection
,
97 /* BackdropColor=Blue */
98 IniCacheInsertKey(IniSection
,
104 /* BackdropFillStyle=Medium */
105 IniCacheInsertKey(IniSection
,
108 L
"BackdropFillStyle",
111 /* TitleBoxTextColor=White */
112 IniCacheInsertKey(IniSection
,
115 L
"TitleBoxTextColor",
118 /* TitleBoxColor=Red */
119 IniCacheInsertKey(IniSection
,
125 /* MessageBoxTextColor=White */
126 IniCacheInsertKey(IniSection
,
129 L
"MessageBoxTextColor",
132 /* MessageBoxColor=Blue */
133 IniCacheInsertKey(IniSection
,
139 /* MenuTextColor=White */
140 IniCacheInsertKey(IniSection
,
147 IniCacheInsertKey(IniSection
,
153 /* TextColor=Yellow */
154 IniCacheInsertKey(IniSection
,
160 /* SelectedTextColor=Black */
161 IniCacheInsertKey(IniSection
,
164 L
"SelectedTextColor",
167 /* SelectedColor=Gray */
168 IniCacheInsertKey(IniSection
,
177 CreateFreeLoaderIniForDos(PWCHAR IniPath
,
181 PINICACHESECTION IniSection
;
183 IniCache
= IniCacheCreate();
185 CreateCommonFreeLoaderSections(IniCache
);
187 /* Create "Operating Systems" section */
188 IniSection
= IniCacheAppendSection(IniCache
,
189 L
"Operating Systems");
191 /* REACTOS=ReactOS */
192 IniCacheInsertKey(IniSection
,
198 /* ReactOS_Debug="ReactOS (Debug)" */
199 IniCacheInsertKey(IniSection
,
203 L
"\"ReactOS (Debug)\"");
205 /* DOS=Dos/Windows */
206 IniCacheInsertKey(IniSection
,
212 /* Create "ReactOS" section */
213 IniSection
= IniCacheAppendSection(IniCache
,
216 /* BootType=ReactOS */
217 IniCacheInsertKey(IniSection
,
223 /* SystemPath=<ArcPath> */
224 IniCacheInsertKey(IniSection
,
230 /* Create "ReactOS_Debug" section */
231 IniSection
= IniCacheAppendSection(IniCache
,
234 /* BootType=ReactOS */
235 IniCacheInsertKey(IniSection
,
241 /* SystemPath=<ArcPath> */
242 IniCacheInsertKey(IniSection
,
248 /* Options=/DEBUGPORT=SCREEN */
249 IniCacheInsertKey(IniSection
,
253 L
"/DEBUGPORT=SCREEN");
255 /* Create "DOS" section */
256 IniSection
= IniCacheAppendSection(IniCache
,
259 /* BootType=BootSector */
260 IniCacheInsertKey(IniSection
,
267 IniCacheInsertKey(IniSection
,
273 /* BootPartition=1 */
274 IniCacheInsertKey(IniSection
,
280 /* BootSector=BOOTSECT.DOS */
281 IniCacheInsertKey(IniSection
,
287 IniCacheSave(IniCache
, IniPath
);
288 IniCacheDestroy(IniCache
);
290 return(STATUS_SUCCESS
);
295 CreateFreeLoaderIniForReactos(PWCHAR IniPath
,
299 PINICACHESECTION IniSection
;
301 IniCache
= IniCacheCreate();
303 CreateCommonFreeLoaderSections(IniCache
);
305 /* Create "Operating Systems" section */
306 IniSection
= IniCacheAppendSection(IniCache
,
307 L
"Operating Systems");
309 /* ReactOS="ReactOS" */
310 IniCacheInsertKey(IniSection
,
316 /* ReactOS_Debug="ReactOS (Debug)" */
317 IniCacheInsertKey(IniSection
,
321 L
"\"ReactOS (Debug)\"");
323 /* Create "ReactOS" section */
324 IniSection
= IniCacheAppendSection(IniCache
,
327 /* BootType=ReactOS */
328 IniCacheInsertKey(IniSection
,
334 /* SystemPath=<ArcPath> */
335 IniCacheInsertKey(IniSection
,
341 /* Create "ReactOS_Debug" section */
342 IniSection
= IniCacheAppendSection(IniCache
,
345 /* BootType=ReactOS */
346 IniCacheInsertKey(IniSection
,
352 /* SystemPath=<ArcPath> */
353 IniCacheInsertKey(IniSection
,
359 /* Options=/DEBUGPORT=SCREEN */
360 IniCacheInsertKey(IniSection
,
364 L
"/DEBUGPORT=SCREEN");
366 /* Save the ini file */
367 IniCacheSave(IniCache
, IniPath
);
368 IniCacheDestroy(IniCache
);
370 return(STATUS_SUCCESS
);
375 UpdateFreeLoaderIni(PWCHAR IniPath
,
380 PINICACHESECTION IniSection
;
381 WCHAR SectionName
[80];
387 RtlInitUnicodeString(&Name
,
390 Status
= IniCacheLoad(&IniCache
,
393 if (!NT_SUCCESS(Status
))
396 /* Get "Operating Systems" section */
397 IniSection
= IniCacheGetSection(IniCache
,
398 L
"Operating Systems");
399 if (IniSection
== NULL
)
400 return(STATUS_UNSUCCESSFUL
);
402 /* Find an unused section name */
404 wcscpy(SectionName
, L
"ReactOS");
405 wcscpy(OsName
, L
"\"ReactOS\"");
408 Status
= IniCacheGetKey(IniSection
,
411 if (!NT_SUCCESS(Status
))
414 swprintf(SectionName
, L
"ReactOS_%lu", i
);
415 swprintf(OsName
, L
"\"ReactOS %lu\"", i
);
419 /* <SectionName>=<OsName> */
420 IniCacheInsertKey(IniSection
,
426 /* Create <SectionName> section */
427 IniSection
= IniCacheAppendSection(IniCache
,
430 /* BootType=ReactOS */
431 IniCacheInsertKey(IniSection
,
437 /* SystemPath=<ArcPath> */
438 IniCacheInsertKey(IniSection
,
444 IniCacheSave(IniCache
, IniPath
);
445 IniCacheDestroy(IniCache
);
447 return(STATUS_SUCCESS
);
452 SaveCurrentBootSector(PWSTR RootPath
,
455 OBJECT_ATTRIBUTES ObjectAttributes
;
456 IO_STATUS_BLOCK IoStatusBlock
;
462 /* Allocate buffer for bootsector */
463 BootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
466 if (BootSector
== NULL
)
467 return(STATUS_INSUFFICIENT_RESOURCES
);
469 /* Read current boot sector into buffer */
470 RtlInitUnicodeString(&Name
,
473 InitializeObjectAttributes(&ObjectAttributes
,
475 OBJ_CASE_INSENSITIVE
,
479 Status
= NtOpenFile(&FileHandle
,
484 FILE_SYNCHRONOUS_IO_ALERT
);
485 if (!NT_SUCCESS(Status
))
487 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
491 Status
= NtReadFile(FileHandle
,
501 if (!NT_SUCCESS(Status
))
503 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
507 /* Write bootsector to DstPath */
508 RtlInitUnicodeString(&Name
,
511 InitializeObjectAttributes(&ObjectAttributes
,
517 Status
= NtCreateFile(&FileHandle
,
522 FILE_ATTRIBUTE_NORMAL
,
525 FILE_SYNCHRONOUS_IO_ALERT
| FILE_SEQUENTIAL_ONLY
,
528 if (!NT_SUCCESS(Status
))
530 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
534 Status
= NtWriteFile(FileHandle
,
545 /* Free the new boot sector */
546 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
553 InstallFat16BootCodeToFile(PWSTR SrcPath
,
557 OBJECT_ATTRIBUTES ObjectAttributes
;
558 IO_STATUS_BLOCK IoStatusBlock
;
562 PUCHAR OrigBootSector
;
563 PUCHAR NewBootSector
;
565 /* Allocate buffer for original bootsector */
566 OrigBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
569 if (OrigBootSector
== NULL
)
570 return(STATUS_INSUFFICIENT_RESOURCES
);
572 /* Read current boot sector into buffer */
573 RtlInitUnicodeString(&Name
,
576 InitializeObjectAttributes(&ObjectAttributes
,
578 OBJ_CASE_INSENSITIVE
,
582 Status
= NtOpenFile(&FileHandle
,
587 FILE_SYNCHRONOUS_IO_ALERT
);
588 if (!NT_SUCCESS(Status
))
590 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
594 Status
= NtReadFile(FileHandle
,
604 if (!NT_SUCCESS(Status
))
606 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
611 /* Allocate buffer for new bootsector */
612 NewBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
615 if (NewBootSector
== NULL
)
617 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
618 return(STATUS_INSUFFICIENT_RESOURCES
);
621 /* Read new bootsector from SrcPath */
622 RtlInitUnicodeString(&Name
,
625 InitializeObjectAttributes(&ObjectAttributes
,
627 OBJ_CASE_INSENSITIVE
,
631 Status
= NtOpenFile(&FileHandle
,
636 FILE_SYNCHRONOUS_IO_ALERT
);
637 if (!NT_SUCCESS(Status
))
639 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
640 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
644 Status
= NtReadFile(FileHandle
,
654 if (!NT_SUCCESS(Status
))
656 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
657 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
661 /* Adjust bootsector (copy a part of the FAT BPB) */
662 memcpy((NewBootSector
+ 11), (OrigBootSector
+ 11), 51 /*fat BPB length*/);
664 /* Free the original boot sector */
665 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
667 /* Write new bootsector to DstPath */
668 RtlInitUnicodeString(&Name
,
671 InitializeObjectAttributes(&ObjectAttributes
,
677 Status
= NtCreateFile(&FileHandle
,
682 FILE_ATTRIBUTE_NORMAL
,
685 FILE_SYNCHRONOUS_IO_ALERT
| FILE_SEQUENTIAL_ONLY
,
688 if (!NT_SUCCESS(Status
))
690 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
695 FilePosition
.QuadPart
= 0;
697 Status
= NtWriteFile(FileHandle
,
708 /* Free the new boot sector */
709 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
716 InstallFat32BootCodeToFile(PWSTR SrcPath
,
720 OBJECT_ATTRIBUTES ObjectAttributes
;
721 IO_STATUS_BLOCK IoStatusBlock
;
725 PUCHAR OrigBootSector
;
726 PUCHAR NewBootSector
;
727 LARGE_INTEGER FileOffset
;
729 /* Allocate buffer for original bootsector */
730 OrigBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
733 if (OrigBootSector
== NULL
)
734 return(STATUS_INSUFFICIENT_RESOURCES
);
736 /* Read current boot sector into buffer */
737 RtlInitUnicodeString(&Name
,
740 InitializeObjectAttributes(&ObjectAttributes
,
742 OBJ_CASE_INSENSITIVE
,
746 Status
= NtOpenFile(&FileHandle
,
751 FILE_SYNCHRONOUS_IO_ALERT
);
752 if (!NT_SUCCESS(Status
))
754 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
758 Status
= NtReadFile(FileHandle
,
768 if (!NT_SUCCESS(Status
))
771 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
775 /* Allocate buffer for new bootsector (2 sectors) */
776 NewBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
779 if (NewBootSector
== NULL
)
781 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
782 return(STATUS_INSUFFICIENT_RESOURCES
);
785 /* Read new bootsector from SrcPath */
786 RtlInitUnicodeString(&Name
,
789 InitializeObjectAttributes(&ObjectAttributes
,
791 OBJ_CASE_INSENSITIVE
,
795 Status
= NtOpenFile(&FileHandle
,
800 FILE_SYNCHRONOUS_IO_ALERT
);
801 if (!NT_SUCCESS(Status
))
803 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
804 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
808 Status
= NtReadFile(FileHandle
,
818 if (!NT_SUCCESS(Status
))
820 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
821 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
825 /* Adjust bootsector (copy a part of the FAT32 BPB) */
826 memcpy((NewBootSector
+ 3),
827 (OrigBootSector
+ 3),
828 87); /* FAT32 BPB length */
830 /* Disable the backup boot sector */
831 NewBootSector
[0x32] = 0x00;
832 NewBootSector
[0x33] = 0x00;
834 /* Free the original boot sector */
835 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
837 /* Write the first sector of the new bootcode to DstPath */
838 RtlInitUnicodeString(&Name
,
841 InitializeObjectAttributes(&ObjectAttributes
,
847 Status
= NtCreateFile(&FileHandle
,
852 FILE_ATTRIBUTE_NORMAL
,
855 FILE_SYNCHRONOUS_IO_ALERT
| FILE_SEQUENTIAL_ONLY
,
858 if (!NT_SUCCESS(Status
))
860 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
864 Status
= NtWriteFile(FileHandle
,
874 if (!NT_SUCCESS(Status
))
876 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
880 /* Write the second sector of the new bootcode to boot disk sector 14 */
881 RtlInitUnicodeString(&Name
,
884 InitializeObjectAttributes(&ObjectAttributes
,
890 Status
= NtOpenFile(&FileHandle
,
895 FILE_SYNCHRONOUS_IO_ALERT
);
896 if (!NT_SUCCESS(Status
))
898 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
902 FileOffset
.QuadPart
= (ULONGLONG
)(14 * SECTORSIZE
);
903 Status
= NtWriteFile(FileHandle
,
908 (NewBootSector
+ SECTORSIZE
),
912 if (!NT_SUCCESS(Status
))
917 /* Free the new boot sector */
918 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
925 InstallMBRBootCodeToDisk(PWSTR SrcPath
,
928 OBJECT_ATTRIBUTES ObjectAttributes
;
929 IO_STATUS_BLOCK IoStatusBlock
;
933 PUCHAR OrigBootSector
;
934 PUCHAR NewBootSector
;
936 /* Allocate buffer for original bootsector */
937 OrigBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
940 if (OrigBootSector
== NULL
)
941 return(STATUS_INSUFFICIENT_RESOURCES
);
943 /* Read current boot sector into buffer */
944 RtlInitUnicodeString(&Name
,
947 InitializeObjectAttributes(&ObjectAttributes
,
949 OBJ_CASE_INSENSITIVE
,
953 Status
= NtOpenFile(&FileHandle
,
958 FILE_SYNCHRONOUS_IO_ALERT
);
959 if (!NT_SUCCESS(Status
))
961 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
965 Status
= NtReadFile(FileHandle
,
975 if (!NT_SUCCESS(Status
))
977 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
982 /* Allocate buffer for new bootsector */
983 NewBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
986 if (NewBootSector
== NULL
)
988 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
989 return(STATUS_INSUFFICIENT_RESOURCES
);
992 /* Read new bootsector from SrcPath */
993 RtlInitUnicodeString(&Name
,
996 InitializeObjectAttributes(&ObjectAttributes
,
998 OBJ_CASE_INSENSITIVE
,
1002 Status
= NtOpenFile(&FileHandle
,
1007 FILE_SYNCHRONOUS_IO_ALERT
);
1008 if (!NT_SUCCESS(Status
))
1010 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1011 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1015 Status
= NtReadFile(FileHandle
,
1024 NtClose(FileHandle
);
1025 if (!NT_SUCCESS(Status
))
1027 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1028 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1032 /* Copy partition table from old MBR to new */
1033 memcpy((NewBootSector
+ 446), (OrigBootSector
+ 446), 4*16 /* Length of partition table */);
1035 /* Free the original boot sector */
1036 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1038 /* Write new bootsector to RootPath */
1039 RtlInitUnicodeString(&Name
,
1042 InitializeObjectAttributes(&ObjectAttributes
,
1048 Status
= NtCreateFile(&FileHandle
,
1053 FILE_ATTRIBUTE_NORMAL
,
1056 FILE_SYNCHRONOUS_IO_ALERT
| FILE_SEQUENTIAL_ONLY
,
1059 if (!NT_SUCCESS(Status
))
1061 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1065 Status
= NtWriteFile(FileHandle
,
1074 NtClose(FileHandle
);
1076 /* Free the new boot sector */
1077 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1084 InstallFat16BootCodeToDisk(PWSTR SrcPath
,
1087 OBJECT_ATTRIBUTES ObjectAttributes
;
1088 IO_STATUS_BLOCK IoStatusBlock
;
1089 UNICODE_STRING Name
;
1092 PUCHAR OrigBootSector
;
1093 PUCHAR NewBootSector
;
1095 /* Allocate buffer for original bootsector */
1096 OrigBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
1099 if (OrigBootSector
== NULL
)
1100 return(STATUS_INSUFFICIENT_RESOURCES
);
1102 /* Read current boot sector into buffer */
1103 RtlInitUnicodeString(&Name
,
1106 InitializeObjectAttributes(&ObjectAttributes
,
1108 OBJ_CASE_INSENSITIVE
,
1112 Status
= NtOpenFile(&FileHandle
,
1117 FILE_SYNCHRONOUS_IO_ALERT
);
1118 if (!NT_SUCCESS(Status
))
1120 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1124 Status
= NtReadFile(FileHandle
,
1133 NtClose(FileHandle
);
1134 if (!NT_SUCCESS(Status
))
1136 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1141 /* Allocate buffer for new bootsector */
1142 NewBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
1145 if (NewBootSector
== NULL
)
1147 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1148 return(STATUS_INSUFFICIENT_RESOURCES
);
1151 /* Read new bootsector from SrcPath */
1152 RtlInitUnicodeString(&Name
,
1155 InitializeObjectAttributes(&ObjectAttributes
,
1157 OBJ_CASE_INSENSITIVE
,
1161 Status
= NtOpenFile(&FileHandle
,
1166 FILE_SYNCHRONOUS_IO_ALERT
);
1167 if (!NT_SUCCESS(Status
))
1169 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1170 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1174 Status
= NtReadFile(FileHandle
,
1183 NtClose(FileHandle
);
1184 if (!NT_SUCCESS(Status
))
1186 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1187 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1191 /* Adjust bootsector (copy a part of the FAT BPB) */
1192 memcpy((NewBootSector
+ 11), (OrigBootSector
+ 11), 51 /*fat BPB length*/);
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
= NtCreateFile(&FileHandle
,
1212 FILE_ATTRIBUTE_NORMAL
,
1215 FILE_SYNCHRONOUS_IO_ALERT
| FILE_SEQUENTIAL_ONLY
,
1218 if (!NT_SUCCESS(Status
))
1220 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1225 FilePosition
.QuadPart
= 0;
1227 Status
= NtWriteFile(FileHandle
,
1236 NtClose(FileHandle
);
1238 /* Free the new boot sector */
1239 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1246 InstallFat32BootCodeToDisk(PWSTR SrcPath
,
1249 OBJECT_ATTRIBUTES ObjectAttributes
;
1250 IO_STATUS_BLOCK IoStatusBlock
;
1251 UNICODE_STRING Name
;
1254 PUCHAR OrigBootSector
;
1255 PUCHAR NewBootSector
;
1256 LARGE_INTEGER FileOffset
;
1257 USHORT BackupBootSector
;
1259 /* Allocate buffer for original bootsector */
1260 OrigBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
1263 if (OrigBootSector
== NULL
)
1264 return(STATUS_INSUFFICIENT_RESOURCES
);
1266 /* Read current boot sector into buffer */
1267 RtlInitUnicodeString(&Name
,
1270 InitializeObjectAttributes(&ObjectAttributes
,
1272 OBJ_CASE_INSENSITIVE
,
1276 Status
= NtOpenFile(&FileHandle
,
1281 FILE_SYNCHRONOUS_IO_ALERT
);
1282 if (!NT_SUCCESS(Status
))
1284 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1288 Status
= NtReadFile(FileHandle
,
1297 NtClose(FileHandle
);
1298 if (!NT_SUCCESS(Status
))
1300 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1305 /* Allocate buffer for new bootsector (2 sectors) */
1306 NewBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
1309 if (NewBootSector
== NULL
)
1311 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1312 return(STATUS_INSUFFICIENT_RESOURCES
);
1315 /* Read new bootsector from SrcPath */
1316 RtlInitUnicodeString(&Name
,
1319 InitializeObjectAttributes(&ObjectAttributes
,
1321 OBJ_CASE_INSENSITIVE
,
1325 Status
= NtOpenFile(&FileHandle
,
1330 FILE_SYNCHRONOUS_IO_ALERT
);
1331 if (!NT_SUCCESS(Status
))
1333 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1334 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1338 Status
= NtReadFile(FileHandle
,
1347 NtClose(FileHandle
);
1348 if (!NT_SUCCESS(Status
))
1350 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1351 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1355 /* Adjust bootsector (copy a part of the FAT32 BPB) */
1356 memcpy((NewBootSector
+ 3),
1357 (OrigBootSector
+ 3),
1358 87); /* FAT32 BPB length */
1360 /* Get the location of the backup boot sector */
1361 BackupBootSector
= (OrigBootSector
[0x33] << 8) + OrigBootSector
[0x32];
1363 /* Free the original boot sector */
1364 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1366 /* Write the first sector of the new bootcode to DstPath */
1367 RtlInitUnicodeString(&Name
,
1370 InitializeObjectAttributes(&ObjectAttributes
,
1376 Status
= NtOpenFile(&FileHandle
,
1377 FILE_WRITE_ACCESS
| FILE_WRITE_ATTRIBUTES
,
1381 FILE_SYNCHRONOUS_IO_ALERT
| FILE_SEQUENTIAL_ONLY
);
1382 if (!NT_SUCCESS(Status
))
1384 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1385 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1389 /* Write sector 0 */
1390 FileOffset
.QuadPart
= 0ULL;
1391 Status
= NtWriteFile(FileHandle
,
1400 if (!NT_SUCCESS(Status
))
1402 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1403 NtClose(FileHandle
);
1404 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1408 /* Write backup boot sector */
1409 if ((BackupBootSector
!= 0x0000) && (BackupBootSector
!= 0xFFFF))
1411 FileOffset
.QuadPart
= (ULONGLONG
)((ULONG
)BackupBootSector
* SECTORSIZE
);
1412 Status
= NtWriteFile(FileHandle
,
1421 if (!NT_SUCCESS(Status
))
1423 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1424 NtClose(FileHandle
);
1425 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1430 /* Write sector 14 */
1431 FileOffset
.QuadPart
= (ULONGLONG
)(14 * SECTORSIZE
);
1432 Status
= NtWriteFile(FileHandle
,
1437 (NewBootSector
+ SECTORSIZE
),
1441 if (!NT_SUCCESS(Status
))
1443 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1445 NtClose(FileHandle
);
1447 /* Free the new boot sector */
1448 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1455 UnprotectBootIni(PWSTR FileName
,
1458 UNICODE_STRING Name
;
1459 OBJECT_ATTRIBUTES ObjectAttributes
;
1460 IO_STATUS_BLOCK IoStatusBlock
;
1461 FILE_BASIC_INFORMATION FileInfo
;
1465 RtlInitUnicodeString(&Name
,
1468 InitializeObjectAttributes(&ObjectAttributes
,
1470 OBJ_CASE_INSENSITIVE
,
1474 Status
= NtOpenFile(&FileHandle
,
1475 FILE_READ_ATTRIBUTES
| FILE_WRITE_ATTRIBUTES
,
1479 FILE_SYNCHRONOUS_IO_ALERT
);
1480 if (Status
== STATUS_NO_SUCH_FILE
)
1482 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1484 return(STATUS_SUCCESS
);
1486 if (!NT_SUCCESS(Status
))
1488 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1492 Status
= NtQueryInformationFile(FileHandle
,
1495 sizeof(FILE_BASIC_INFORMATION
),
1496 FileBasicInformation
);
1497 if (!NT_SUCCESS(Status
))
1499 DPRINT1("NtQueryInformationFile() failed (Status %lx)\n", Status
);
1500 NtClose(FileHandle
);
1504 *Attributes
= FileInfo
.FileAttributes
;
1506 /* Delete attributes SYSTEM, HIDDEN and READONLY */
1507 FileInfo
.FileAttributes
= FileInfo
.FileAttributes
&
1508 ~(FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
| FILE_ATTRIBUTE_READONLY
);
1510 Status
= NtSetInformationFile(FileHandle
,
1513 sizeof(FILE_BASIC_INFORMATION
),
1514 FileBasicInformation
);
1515 if (!NT_SUCCESS(Status
))
1517 DPRINT1("NtSetInformationFile() failed (Status %lx)\n", Status
);
1520 NtClose(FileHandle
);
1526 ProtectBootIni(PWSTR FileName
,
1529 UNICODE_STRING Name
;
1530 OBJECT_ATTRIBUTES ObjectAttributes
;
1531 IO_STATUS_BLOCK IoStatusBlock
;
1532 FILE_BASIC_INFORMATION FileInfo
;
1536 RtlInitUnicodeString(&Name
,
1539 InitializeObjectAttributes(&ObjectAttributes
,
1541 OBJ_CASE_INSENSITIVE
,
1545 Status
= NtOpenFile(&FileHandle
,
1546 FILE_READ_ATTRIBUTES
| FILE_WRITE_ATTRIBUTES
,
1550 FILE_SYNCHRONOUS_IO_ALERT
);
1551 if (!NT_SUCCESS(Status
))
1553 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1557 Status
= NtQueryInformationFile(FileHandle
,
1560 sizeof(FILE_BASIC_INFORMATION
),
1561 FileBasicInformation
);
1562 if (!NT_SUCCESS(Status
))
1564 DPRINT1("NtQueryInformationFile() failed (Status %lx)\n", Status
);
1565 NtClose(FileHandle
);
1569 FileInfo
.FileAttributes
= FileInfo
.FileAttributes
| Attributes
;
1571 Status
= NtSetInformationFile(FileHandle
,
1574 sizeof(FILE_BASIC_INFORMATION
),
1575 FileBasicInformation
);
1576 if (!NT_SUCCESS(Status
))
1578 DPRINT1("NtSetInformationFile() failed (Status %lx)\n", Status
);
1581 NtClose(FileHandle
);
1587 UpdateBootIni(PWSTR BootIniPath
,
1591 UNICODE_STRING Name
;
1592 PINICACHE Cache
= NULL
;
1593 PINICACHESECTION Section
= NULL
;
1595 ULONG FileAttribute
;
1597 RtlInitUnicodeString(&Name
,
1600 Status
= IniCacheLoad(&Cache
,
1603 if (!NT_SUCCESS(Status
))
1609 Section
= IniCacheGetSection(Cache
,
1610 L
"operating systems");
1611 if (Section
== NULL
)
1614 IniCacheDestroy(Cache
);
1615 return(STATUS_UNSUCCESSFUL
);
1618 IniCacheInsertKey(Section
,
1624 Status
= UnprotectBootIni(BootIniPath
,
1626 if (!NT_SUCCESS(Status
))
1629 IniCacheDestroy(Cache
);
1633 Status
= IniCacheSave(Cache
,
1635 if (!NT_SUCCESS(Status
))
1638 IniCacheDestroy(Cache
);
1642 FileAttribute
|= (FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
| FILE_ATTRIBUTE_READONLY
);
1643 Status
= ProtectBootIni(BootIniPath
,
1646 IniCacheDestroy(Cache
);