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