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);