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] = 0xFF;
832 NewBootSector
[0x33] = 0xFF;
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 InstallFat16BootCodeToDisk(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 /* Adjust bootsector (copy a part of the FAT BPB) */
1033 memcpy((NewBootSector
+ 11), (OrigBootSector
+ 11), 51 /*fat BPB length*/);
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
);
1066 FilePosition
.QuadPart
= 0;
1068 Status
= NtWriteFile(FileHandle
,
1077 NtClose(FileHandle
);
1079 /* Free the new boot sector */
1080 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1087 InstallFat32BootCodeToDisk(PWSTR SrcPath
,
1090 OBJECT_ATTRIBUTES ObjectAttributes
;
1091 IO_STATUS_BLOCK IoStatusBlock
;
1092 UNICODE_STRING Name
;
1095 PUCHAR OrigBootSector
;
1096 PUCHAR NewBootSector
;
1097 LARGE_INTEGER FileOffset
;
1098 USHORT BackupBootSector
;
1100 /* Allocate buffer for original bootsector */
1101 OrigBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
1104 if (OrigBootSector
== NULL
)
1105 return(STATUS_INSUFFICIENT_RESOURCES
);
1107 /* Read current boot sector into buffer */
1108 RtlInitUnicodeString(&Name
,
1111 InitializeObjectAttributes(&ObjectAttributes
,
1113 OBJ_CASE_INSENSITIVE
,
1117 Status
= NtOpenFile(&FileHandle
,
1122 FILE_SYNCHRONOUS_IO_ALERT
);
1123 if (!NT_SUCCESS(Status
))
1125 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1129 Status
= NtReadFile(FileHandle
,
1138 NtClose(FileHandle
);
1139 if (!NT_SUCCESS(Status
))
1141 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1146 /* Allocate buffer for new bootsector (2 sectors) */
1147 NewBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
1150 if (NewBootSector
== NULL
)
1152 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1153 return(STATUS_INSUFFICIENT_RESOURCES
);
1156 /* Read new bootsector from SrcPath */
1157 RtlInitUnicodeString(&Name
,
1160 InitializeObjectAttributes(&ObjectAttributes
,
1162 OBJ_CASE_INSENSITIVE
,
1166 Status
= NtOpenFile(&FileHandle
,
1171 FILE_SYNCHRONOUS_IO_ALERT
);
1172 if (!NT_SUCCESS(Status
))
1174 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1175 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1179 Status
= NtReadFile(FileHandle
,
1188 NtClose(FileHandle
);
1189 if (!NT_SUCCESS(Status
))
1191 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1192 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1196 /* Adjust bootsector (copy a part of the FAT32 BPB) */
1197 memcpy((NewBootSector
+ 3),
1198 (OrigBootSector
+ 3),
1199 87); /* FAT32 BPB length */
1201 /* Get the location of the backup boot sector */
1202 BackupBootSector
= (OrigBootSector
[0x33] << 8) + OrigBootSector
[0x33];
1204 /* Free the original boot sector */
1205 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1207 /* Write the first sector of the new bootcode to DstPath */
1208 RtlInitUnicodeString(&Name
,
1211 InitializeObjectAttributes(&ObjectAttributes
,
1217 Status
= NtOpenFile(&FileHandle
,
1218 FILE_WRITE_ACCESS
| FILE_WRITE_ATTRIBUTES
,
1222 FILE_SYNCHRONOUS_IO_ALERT
| FILE_SEQUENTIAL_ONLY
);
1223 if (!NT_SUCCESS(Status
))
1225 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1226 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1230 /* Write sector 0 */
1231 FileOffset
.QuadPart
= 0ULL;
1232 Status
= NtWriteFile(FileHandle
,
1241 if (!NT_SUCCESS(Status
))
1243 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1244 NtClose(FileHandle
);
1245 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1249 /* Write backup boot sector */
1250 if (BackupBootSector
!= 0xFFFF)
1252 FileOffset
.QuadPart
= (ULONGLONG
)((ULONG
)BackupBootSector
* SECTORSIZE
);
1253 Status
= NtWriteFile(FileHandle
,
1262 if (!NT_SUCCESS(Status
))
1264 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1265 NtClose(FileHandle
);
1266 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1271 /* Write sector 14 */
1272 FileOffset
.QuadPart
= (ULONGLONG
)(14 * SECTORSIZE
);
1273 Status
= NtWriteFile(FileHandle
,
1278 (NewBootSector
+ SECTORSIZE
),
1282 if (!NT_SUCCESS(Status
))
1284 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1286 NtClose(FileHandle
);
1288 /* Free the new boot sector */
1289 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1296 UnprotectBootIni(PWSTR FileName
,
1299 UNICODE_STRING Name
;
1300 OBJECT_ATTRIBUTES ObjectAttributes
;
1301 IO_STATUS_BLOCK IoStatusBlock
;
1302 FILE_BASIC_INFORMATION FileInfo
;
1306 RtlInitUnicodeString(&Name
,
1309 InitializeObjectAttributes(&ObjectAttributes
,
1311 OBJ_CASE_INSENSITIVE
,
1315 Status
= NtOpenFile(&FileHandle
,
1316 FILE_READ_ATTRIBUTES
| FILE_WRITE_ATTRIBUTES
,
1320 FILE_SYNCHRONOUS_IO_ALERT
);
1321 if (Status
== STATUS_NO_SUCH_FILE
)
1323 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1325 return(STATUS_SUCCESS
);
1327 if (!NT_SUCCESS(Status
))
1329 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1333 Status
= NtQueryInformationFile(FileHandle
,
1336 sizeof(FILE_BASIC_INFORMATION
),
1337 FileBasicInformation
);
1338 if (!NT_SUCCESS(Status
))
1340 DPRINT1("NtQueryInformationFile() failed (Status %lx)\n", Status
);
1341 NtClose(FileHandle
);
1345 *Attributes
= FileInfo
.FileAttributes
;
1347 /* Delete attributes SYSTEM, HIDDEN and READONLY */
1348 FileInfo
.FileAttributes
= FileInfo
.FileAttributes
&
1349 ~(FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
| FILE_ATTRIBUTE_READONLY
);
1351 Status
= NtSetInformationFile(FileHandle
,
1354 sizeof(FILE_BASIC_INFORMATION
),
1355 FileBasicInformation
);
1356 if (!NT_SUCCESS(Status
))
1358 DPRINT1("NtSetInformationFile() failed (Status %lx)\n", Status
);
1361 NtClose(FileHandle
);
1367 ProtectBootIni(PWSTR FileName
,
1370 UNICODE_STRING Name
;
1371 OBJECT_ATTRIBUTES ObjectAttributes
;
1372 IO_STATUS_BLOCK IoStatusBlock
;
1373 FILE_BASIC_INFORMATION FileInfo
;
1377 RtlInitUnicodeString(&Name
,
1380 InitializeObjectAttributes(&ObjectAttributes
,
1382 OBJ_CASE_INSENSITIVE
,
1386 Status
= NtOpenFile(&FileHandle
,
1387 FILE_READ_ATTRIBUTES
| FILE_WRITE_ATTRIBUTES
,
1391 FILE_SYNCHRONOUS_IO_ALERT
);
1392 if (!NT_SUCCESS(Status
))
1394 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1398 Status
= NtQueryInformationFile(FileHandle
,
1401 sizeof(FILE_BASIC_INFORMATION
),
1402 FileBasicInformation
);
1403 if (!NT_SUCCESS(Status
))
1405 DPRINT1("NtQueryInformationFile() failed (Status %lx)\n", Status
);
1406 NtClose(FileHandle
);
1410 FileInfo
.FileAttributes
= FileInfo
.FileAttributes
| Attributes
;
1412 Status
= NtSetInformationFile(FileHandle
,
1415 sizeof(FILE_BASIC_INFORMATION
),
1416 FileBasicInformation
);
1417 if (!NT_SUCCESS(Status
))
1419 DPRINT1("NtSetInformationFile() failed (Status %lx)\n", Status
);
1422 NtClose(FileHandle
);
1428 UpdateBootIni(PWSTR BootIniPath
,
1432 UNICODE_STRING Name
;
1433 PINICACHE Cache
= NULL
;
1434 PINICACHESECTION Section
= NULL
;
1436 ULONG FileAttribute
;
1438 RtlInitUnicodeString(&Name
,
1441 Status
= IniCacheLoad(&Cache
,
1444 if (!NT_SUCCESS(Status
))
1450 Section
= IniCacheGetSection(Cache
,
1451 L
"operating systems");
1452 if (Section
== NULL
)
1455 IniCacheDestroy(Cache
);
1456 return(STATUS_UNSUCCESSFUL
);
1459 IniCacheInsertKey(Section
,
1465 Status
= UnprotectBootIni(BootIniPath
,
1467 if (!NT_SUCCESS(Status
))
1470 IniCacheDestroy(Cache
);
1474 Status
= IniCacheSave(Cache
,
1476 if (!NT_SUCCESS(Status
))
1479 IniCacheDestroy(Cache
);
1483 FileAttribute
|= (FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
| FILE_ATTRIBUTE_READONLY
);
1484 Status
= ProtectBootIni(BootIniPath
,
1487 IniCacheDestroy(Cache
);