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
,
392 if (!NT_SUCCESS(Status
))
395 /* Get "Operating Systems" section */
396 IniSection
= IniCacheGetSection(IniCache
,
397 L
"Operating Systems");
398 if (IniSection
== NULL
)
399 return(STATUS_UNSUCCESSFUL
);
401 /* Find an unused section name */
403 wcscpy(SectionName
, L
"ReactOS");
404 wcscpy(OsName
, L
"\"ReactOS\"");
407 Status
= IniCacheGetKey(IniSection
,
410 if (!NT_SUCCESS(Status
))
413 swprintf(SectionName
, L
"ReactOS_%lu", i
);
414 swprintf(OsName
, L
"\"ReactOS %lu\"", i
);
418 /* <SectionName>=<OsName> */
419 IniCacheInsertKey(IniSection
,
425 /* Create <SectionName> section */
426 IniSection
= IniCacheAppendSection(IniCache
,
429 /* BootType=ReactOS */
430 IniCacheInsertKey(IniSection
,
436 /* SystemPath=<ArcPath> */
437 IniCacheInsertKey(IniSection
,
443 IniCacheSave(IniCache
, IniPath
);
444 IniCacheDestroy(IniCache
);
446 return(STATUS_SUCCESS
);
451 SaveCurrentBootSector(PWSTR RootPath
,
454 OBJECT_ATTRIBUTES ObjectAttributes
;
455 IO_STATUS_BLOCK IoStatusBlock
;
461 /* Allocate buffer for bootsector */
462 BootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
465 if (BootSector
== NULL
)
466 return(STATUS_INSUFFICIENT_RESOURCES
);
468 /* Read current boot sector into buffer */
469 RtlInitUnicodeString(&Name
,
472 InitializeObjectAttributes(&ObjectAttributes
,
474 OBJ_CASE_INSENSITIVE
,
478 Status
= NtOpenFile(&FileHandle
,
483 FILE_SYNCHRONOUS_IO_ALERT
);
484 if (!NT_SUCCESS(Status
))
486 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
490 Status
= NtReadFile(FileHandle
,
500 if (!NT_SUCCESS(Status
))
502 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
506 /* Write bootsector to DstPath */
507 RtlInitUnicodeString(&Name
,
510 InitializeObjectAttributes(&ObjectAttributes
,
516 Status
= NtCreateFile(&FileHandle
,
521 FILE_ATTRIBUTE_NORMAL
,
524 FILE_SYNCHRONOUS_IO_ALERT
| FILE_SEQUENTIAL_ONLY
,
527 if (!NT_SUCCESS(Status
))
529 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
533 Status
= NtWriteFile(FileHandle
,
544 /* Free the new boot sector */
545 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
552 InstallFat16BootCodeToFile(PWSTR SrcPath
,
556 OBJECT_ATTRIBUTES ObjectAttributes
;
557 IO_STATUS_BLOCK IoStatusBlock
;
561 PUCHAR OrigBootSector
;
562 PUCHAR NewBootSector
;
564 /* Allocate buffer for original bootsector */
565 OrigBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
568 if (OrigBootSector
== NULL
)
569 return(STATUS_INSUFFICIENT_RESOURCES
);
571 /* Read current boot sector into buffer */
572 RtlInitUnicodeString(&Name
,
575 InitializeObjectAttributes(&ObjectAttributes
,
577 OBJ_CASE_INSENSITIVE
,
581 Status
= NtOpenFile(&FileHandle
,
586 FILE_SYNCHRONOUS_IO_ALERT
);
587 if (!NT_SUCCESS(Status
))
589 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
593 Status
= NtReadFile(FileHandle
,
603 if (!NT_SUCCESS(Status
))
605 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
610 /* Allocate buffer for new bootsector */
611 NewBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
614 if (NewBootSector
== NULL
)
616 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
617 return(STATUS_INSUFFICIENT_RESOURCES
);
620 /* Read new bootsector from SrcPath */
621 RtlInitUnicodeString(&Name
,
624 InitializeObjectAttributes(&ObjectAttributes
,
626 OBJ_CASE_INSENSITIVE
,
630 Status
= NtOpenFile(&FileHandle
,
635 FILE_SYNCHRONOUS_IO_ALERT
);
636 if (!NT_SUCCESS(Status
))
638 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
639 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
643 Status
= NtReadFile(FileHandle
,
653 if (!NT_SUCCESS(Status
))
655 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
656 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
660 /* Adjust bootsector (copy a part of the FAT BPB) */
661 memcpy((NewBootSector
+ 11), (OrigBootSector
+ 11), 51 /*fat BPB length*/);
663 /* Free the original boot sector */
664 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
666 /* Write new bootsector to DstPath */
667 RtlInitUnicodeString(&Name
,
670 InitializeObjectAttributes(&ObjectAttributes
,
676 Status
= NtCreateFile(&FileHandle
,
681 FILE_ATTRIBUTE_NORMAL
,
684 FILE_SYNCHRONOUS_IO_ALERT
| FILE_SEQUENTIAL_ONLY
,
687 if (!NT_SUCCESS(Status
))
689 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
694 FilePosition
.QuadPart
= 0;
696 Status
= NtWriteFile(FileHandle
,
707 /* Free the new boot sector */
708 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
715 InstallFat32BootCodeToFile(PWSTR SrcPath
,
719 OBJECT_ATTRIBUTES ObjectAttributes
;
720 IO_STATUS_BLOCK IoStatusBlock
;
724 PUCHAR OrigBootSector
;
725 PUCHAR NewBootSector
;
726 LARGE_INTEGER FileOffset
;
728 /* Allocate buffer for original bootsector */
729 OrigBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
732 if (OrigBootSector
== NULL
)
733 return(STATUS_INSUFFICIENT_RESOURCES
);
735 /* Read current boot sector into buffer */
736 RtlInitUnicodeString(&Name
,
739 InitializeObjectAttributes(&ObjectAttributes
,
741 OBJ_CASE_INSENSITIVE
,
745 Status
= NtOpenFile(&FileHandle
,
750 FILE_SYNCHRONOUS_IO_ALERT
);
751 if (!NT_SUCCESS(Status
))
753 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
757 Status
= NtReadFile(FileHandle
,
767 if (!NT_SUCCESS(Status
))
770 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
774 /* Allocate buffer for new bootsector (2 sectors) */
775 NewBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
778 if (NewBootSector
== NULL
)
780 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
781 return(STATUS_INSUFFICIENT_RESOURCES
);
784 /* Read new bootsector from SrcPath */
785 RtlInitUnicodeString(&Name
,
788 InitializeObjectAttributes(&ObjectAttributes
,
790 OBJ_CASE_INSENSITIVE
,
794 Status
= NtOpenFile(&FileHandle
,
799 FILE_SYNCHRONOUS_IO_ALERT
);
800 if (!NT_SUCCESS(Status
))
802 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
803 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
807 Status
= NtReadFile(FileHandle
,
817 if (!NT_SUCCESS(Status
))
819 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
820 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
824 /* Adjust bootsector (copy a part of the FAT32 BPB) */
825 memcpy((NewBootSector
+ 3),
826 (OrigBootSector
+ 3),
827 87); /* FAT32 BPB length */
829 /* Disable the backup boot sector */
830 NewBootSector
[0x32] = 0xFF;
831 NewBootSector
[0x33] = 0xFF;
833 /* Free the original boot sector */
834 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
836 /* Write the first sector of the new bootcode to DstPath */
837 RtlInitUnicodeString(&Name
,
840 InitializeObjectAttributes(&ObjectAttributes
,
846 Status
= NtCreateFile(&FileHandle
,
851 FILE_ATTRIBUTE_NORMAL
,
854 FILE_SYNCHRONOUS_IO_ALERT
| FILE_SEQUENTIAL_ONLY
,
857 if (!NT_SUCCESS(Status
))
859 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
863 Status
= NtWriteFile(FileHandle
,
873 if (!NT_SUCCESS(Status
))
875 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
879 /* Write the second sector of the new bootcode to boot disk sector 14 */
880 RtlInitUnicodeString(&Name
,
883 InitializeObjectAttributes(&ObjectAttributes
,
889 Status
= NtOpenFile(&FileHandle
,
894 FILE_SYNCHRONOUS_IO_ALERT
);
895 if (!NT_SUCCESS(Status
))
897 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
901 FileOffset
.QuadPart
= (ULONGLONG
)(14 * SECTORSIZE
);
902 Status
= NtWriteFile(FileHandle
,
907 (NewBootSector
+ SECTORSIZE
),
911 if (!NT_SUCCESS(Status
))
916 /* Free the new boot sector */
917 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
924 InstallFat16BootCodeToDisk(PWSTR SrcPath
,
927 OBJECT_ATTRIBUTES ObjectAttributes
;
928 IO_STATUS_BLOCK IoStatusBlock
;
932 PUCHAR OrigBootSector
;
933 PUCHAR NewBootSector
;
935 /* Allocate buffer for original bootsector */
936 OrigBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
939 if (OrigBootSector
== NULL
)
940 return(STATUS_INSUFFICIENT_RESOURCES
);
942 /* Read current boot sector into buffer */
943 RtlInitUnicodeString(&Name
,
946 InitializeObjectAttributes(&ObjectAttributes
,
948 OBJ_CASE_INSENSITIVE
,
952 Status
= NtOpenFile(&FileHandle
,
957 FILE_SYNCHRONOUS_IO_ALERT
);
958 if (!NT_SUCCESS(Status
))
960 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
964 Status
= NtReadFile(FileHandle
,
974 if (!NT_SUCCESS(Status
))
976 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
981 /* Allocate buffer for new bootsector */
982 NewBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
985 if (NewBootSector
== NULL
)
987 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
988 return(STATUS_INSUFFICIENT_RESOURCES
);
991 /* Read new bootsector from SrcPath */
992 RtlInitUnicodeString(&Name
,
995 InitializeObjectAttributes(&ObjectAttributes
,
997 OBJ_CASE_INSENSITIVE
,
1001 Status
= NtOpenFile(&FileHandle
,
1006 FILE_SYNCHRONOUS_IO_ALERT
);
1007 if (!NT_SUCCESS(Status
))
1009 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1010 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1014 Status
= NtReadFile(FileHandle
,
1023 NtClose(FileHandle
);
1024 if (!NT_SUCCESS(Status
))
1026 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1027 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1031 /* Adjust bootsector (copy a part of the FAT BPB) */
1032 memcpy((NewBootSector
+ 11), (OrigBootSector
+ 11), 51 /*fat BPB length*/);
1034 /* Free the original boot sector */
1035 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1037 /* Write new bootsector to RootPath */
1038 RtlInitUnicodeString(&Name
,
1041 InitializeObjectAttributes(&ObjectAttributes
,
1047 Status
= NtCreateFile(&FileHandle
,
1052 FILE_ATTRIBUTE_NORMAL
,
1055 FILE_SYNCHRONOUS_IO_ALERT
| FILE_SEQUENTIAL_ONLY
,
1058 if (!NT_SUCCESS(Status
))
1060 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1065 FilePosition
.QuadPart
= 0;
1067 Status
= NtWriteFile(FileHandle
,
1076 NtClose(FileHandle
);
1078 /* Free the new boot sector */
1079 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1086 InstallFat32BootCodeToDisk(PWSTR SrcPath
,
1089 OBJECT_ATTRIBUTES ObjectAttributes
;
1090 IO_STATUS_BLOCK IoStatusBlock
;
1091 UNICODE_STRING Name
;
1094 PUCHAR OrigBootSector
;
1095 PUCHAR NewBootSector
;
1096 LARGE_INTEGER FileOffset
;
1097 USHORT BackupBootSector
;
1099 /* Allocate buffer for original bootsector */
1100 OrigBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
1103 if (OrigBootSector
== NULL
)
1104 return(STATUS_INSUFFICIENT_RESOURCES
);
1106 /* Read current boot sector into buffer */
1107 RtlInitUnicodeString(&Name
,
1110 InitializeObjectAttributes(&ObjectAttributes
,
1112 OBJ_CASE_INSENSITIVE
,
1116 Status
= NtOpenFile(&FileHandle
,
1121 FILE_SYNCHRONOUS_IO_ALERT
);
1122 if (!NT_SUCCESS(Status
))
1124 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1128 Status
= NtReadFile(FileHandle
,
1137 NtClose(FileHandle
);
1138 if (!NT_SUCCESS(Status
))
1140 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1145 /* Allocate buffer for new bootsector (2 sectors) */
1146 NewBootSector
= (PUCHAR
)RtlAllocateHeap(ProcessHeap
,
1149 if (NewBootSector
== NULL
)
1151 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1152 return(STATUS_INSUFFICIENT_RESOURCES
);
1155 /* Read new bootsector from SrcPath */
1156 RtlInitUnicodeString(&Name
,
1159 InitializeObjectAttributes(&ObjectAttributes
,
1161 OBJ_CASE_INSENSITIVE
,
1165 Status
= NtOpenFile(&FileHandle
,
1170 FILE_SYNCHRONOUS_IO_ALERT
);
1171 if (!NT_SUCCESS(Status
))
1173 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1174 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1178 Status
= NtReadFile(FileHandle
,
1187 NtClose(FileHandle
);
1188 if (!NT_SUCCESS(Status
))
1190 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1191 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1195 /* Adjust bootsector (copy a part of the FAT32 BPB) */
1196 memcpy((NewBootSector
+ 3),
1197 (OrigBootSector
+ 3),
1198 87); /* FAT32 BPB length */
1200 /* Get the location of the backup boot sector */
1201 BackupBootSector
= (OrigBootSector
[0x33] << 8) + OrigBootSector
[0x33];
1203 /* Free the original boot sector */
1204 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1206 /* Write the first sector of the new bootcode to DstPath */
1207 RtlInitUnicodeString(&Name
,
1210 InitializeObjectAttributes(&ObjectAttributes
,
1216 Status
= NtOpenFile(&FileHandle
,
1217 FILE_WRITE_ACCESS
| FILE_WRITE_ATTRIBUTES
,
1221 FILE_SYNCHRONOUS_IO_ALERT
| FILE_SEQUENTIAL_ONLY
);
1222 if (!NT_SUCCESS(Status
))
1224 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1225 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1229 /* Write sector 0 */
1230 FileOffset
.QuadPart
= 0ULL;
1231 Status
= NtWriteFile(FileHandle
,
1240 if (!NT_SUCCESS(Status
))
1242 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1243 NtClose(FileHandle
);
1244 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1248 /* Write backup boot sector */
1249 if (BackupBootSector
!= 0xFFFF)
1251 FileOffset
.QuadPart
= (ULONGLONG
)((ULONG
)BackupBootSector
* SECTORSIZE
);
1252 Status
= NtWriteFile(FileHandle
,
1261 if (!NT_SUCCESS(Status
))
1263 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1264 NtClose(FileHandle
);
1265 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1270 /* Write sector 14 */
1271 FileOffset
.QuadPart
= (ULONGLONG
)(14 * SECTORSIZE
);
1272 Status
= NtWriteFile(FileHandle
,
1277 (NewBootSector
+ SECTORSIZE
),
1281 if (!NT_SUCCESS(Status
))
1283 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1285 NtClose(FileHandle
);
1287 /* Free the new boot sector */
1288 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1295 UnprotectBootIni(PWSTR FileName
,
1298 UNICODE_STRING Name
;
1299 OBJECT_ATTRIBUTES ObjectAttributes
;
1300 IO_STATUS_BLOCK IoStatusBlock
;
1301 FILE_BASIC_INFORMATION FileInfo
;
1305 RtlInitUnicodeString(&Name
,
1308 InitializeObjectAttributes(&ObjectAttributes
,
1310 OBJ_CASE_INSENSITIVE
,
1314 Status
= NtOpenFile(&FileHandle
,
1315 FILE_READ_ATTRIBUTES
| FILE_WRITE_ATTRIBUTES
,
1319 FILE_SYNCHRONOUS_IO_ALERT
);
1320 if (Status
== STATUS_NO_SUCH_FILE
)
1322 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1324 return(STATUS_SUCCESS
);
1326 if (!NT_SUCCESS(Status
))
1328 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1332 Status
= NtQueryInformationFile(FileHandle
,
1335 sizeof(FILE_BASIC_INFORMATION
),
1336 FileBasicInformation
);
1337 if (!NT_SUCCESS(Status
))
1339 DPRINT1("NtQueryInformationFile() failed (Status %lx)\n", Status
);
1340 NtClose(FileHandle
);
1344 *Attributes
= FileInfo
.FileAttributes
;
1346 /* Delete attributes SYSTEM, HIDDEN and READONLY */
1347 FileInfo
.FileAttributes
= FileInfo
.FileAttributes
&
1348 ~(FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
| FILE_ATTRIBUTE_READONLY
);
1350 Status
= NtSetInformationFile(FileHandle
,
1353 sizeof(FILE_BASIC_INFORMATION
),
1354 FileBasicInformation
);
1355 if (!NT_SUCCESS(Status
))
1357 DPRINT1("NtSetInformationFile() failed (Status %lx)\n", Status
);
1360 NtClose(FileHandle
);
1366 ProtectBootIni(PWSTR FileName
,
1369 UNICODE_STRING Name
;
1370 OBJECT_ATTRIBUTES ObjectAttributes
;
1371 IO_STATUS_BLOCK IoStatusBlock
;
1372 FILE_BASIC_INFORMATION FileInfo
;
1376 RtlInitUnicodeString(&Name
,
1379 InitializeObjectAttributes(&ObjectAttributes
,
1381 OBJ_CASE_INSENSITIVE
,
1385 Status
= NtOpenFile(&FileHandle
,
1386 FILE_READ_ATTRIBUTES
| FILE_WRITE_ATTRIBUTES
,
1390 FILE_SYNCHRONOUS_IO_ALERT
);
1391 if (!NT_SUCCESS(Status
))
1393 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1397 Status
= NtQueryInformationFile(FileHandle
,
1400 sizeof(FILE_BASIC_INFORMATION
),
1401 FileBasicInformation
);
1402 if (!NT_SUCCESS(Status
))
1404 DPRINT1("NtQueryInformationFile() failed (Status %lx)\n", Status
);
1405 NtClose(FileHandle
);
1409 FileInfo
.FileAttributes
= FileInfo
.FileAttributes
| Attributes
;
1411 Status
= NtSetInformationFile(FileHandle
,
1414 sizeof(FILE_BASIC_INFORMATION
),
1415 FileBasicInformation
);
1416 if (!NT_SUCCESS(Status
))
1418 DPRINT1("NtSetInformationFile() failed (Status %lx)\n", Status
);
1421 NtClose(FileHandle
);
1427 UpdateBootIni(PWSTR BootIniPath
,
1431 UNICODE_STRING Name
;
1432 PINICACHE Cache
= NULL
;
1433 PINICACHESECTION Section
= NULL
;
1435 ULONG FileAttribute
;
1437 RtlInitUnicodeString(&Name
,
1440 Status
= IniCacheLoad(&Cache
,
1442 if (!NT_SUCCESS(Status
))
1448 Section
= IniCacheGetSection(Cache
,
1449 L
"operating systems");
1450 if (Section
== NULL
)
1453 IniCacheDestroy(Cache
);
1454 return(STATUS_UNSUCCESSFUL
);
1457 IniCacheInsertKey(Section
,
1463 Status
= UnprotectBootIni(BootIniPath
,
1465 if (!NT_SUCCESS(Status
))
1468 IniCacheDestroy(Cache
);
1472 Status
= IniCacheSave(Cache
,
1474 if (!NT_SUCCESS(Status
))
1477 IniCacheDestroy(Cache
);
1481 FileAttribute
|= (FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
| FILE_ATTRIBUTE_READONLY
);
1482 Status
= ProtectBootIni(BootIniPath
,
1485 IniCacheDestroy(Cache
);