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 RtlCopyMemory ((NewBootSector + 446),
1034 (OrigBootSector + 446),
1035 4*16 /* Length of partition table */);
1037 /* Free the original boot sector */
1038 RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1040 /* Write new bootsector to RootPath */
1041 RtlInitUnicodeString(&Name,
1044 InitializeObjectAttributes(&ObjectAttributes,
1050 Status = NtCreateFile(&FileHandle,
1055 FILE_ATTRIBUTE_NORMAL,
1058 FILE_SYNCHRONOUS_IO_ALERT | FILE_SEQUENTIAL_ONLY,
1061 if (!NT_SUCCESS(Status))
1063 RtlFreeHeap(ProcessHeap, 0, NewBootSector);
1067 Status = NtWriteFile(FileHandle,
1076 NtClose(FileHandle);
1078 /* Free the new boot sector */
1079 RtlFreeHeap(ProcessHeap, 0, NewBootSector);
1086 InstallFat16BootCodeToDisk(PWSTR SrcPath,
1089 OBJECT_ATTRIBUTES ObjectAttributes;
1090 IO_STATUS_BLOCK IoStatusBlock;
1091 UNICODE_STRING Name;
1094 PUCHAR OrigBootSector;
1095 PUCHAR NewBootSector;
1097 /* Allocate buffer for original bootsector */
1098 OrigBootSector = (PUCHAR)RtlAllocateHeap(ProcessHeap,
1101 if (OrigBootSector == NULL)
1102 return(STATUS_INSUFFICIENT_RESOURCES);
1104 /* Read current boot sector into buffer */
1105 RtlInitUnicodeString(&Name,
1108 InitializeObjectAttributes(&ObjectAttributes,
1110 OBJ_CASE_INSENSITIVE,
1114 Status = NtOpenFile(&FileHandle,
1119 FILE_SYNCHRONOUS_IO_ALERT);
1120 if (!NT_SUCCESS(Status))
1122 RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1126 Status = NtReadFile(FileHandle,
1135 NtClose(FileHandle);
1136 if (!NT_SUCCESS(Status))
1138 RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1143 /* Allocate buffer for new bootsector */
1144 NewBootSector = (PUCHAR)RtlAllocateHeap(ProcessHeap,
1147 if (NewBootSector == NULL)
1149 RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1150 return(STATUS_INSUFFICIENT_RESOURCES);
1153 /* Read new bootsector from SrcPath */
1154 RtlInitUnicodeString(&Name,
1157 InitializeObjectAttributes(&ObjectAttributes,
1159 OBJ_CASE_INSENSITIVE,
1163 Status = NtOpenFile(&FileHandle,
1168 FILE_SYNCHRONOUS_IO_ALERT);
1169 if (!NT_SUCCESS(Status))
1171 RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1172 RtlFreeHeap(ProcessHeap, 0, NewBootSector);
1176 Status = NtReadFile(FileHandle,
1185 NtClose(FileHandle);
1186 if (!NT_SUCCESS(Status))
1188 RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1189 RtlFreeHeap(ProcessHeap, 0, NewBootSector);
1193 /* Adjust bootsector (copy a part of the FAT16 BPB) */
1194 memcpy((NewBootSector + 3),
1195 (OrigBootSector + 3),
1196 59); /* FAT16 BPB length*/
1198 /* Free the original boot sector */
1199 RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1201 /* Write new bootsector to RootPath */
1202 RtlInitUnicodeString(&Name,
1205 InitializeObjectAttributes(&ObjectAttributes,
1211 Status = NtCreateFile(&FileHandle,
1216 FILE_ATTRIBUTE_NORMAL,
1219 FILE_SYNCHRONOUS_IO_ALERT | FILE_SEQUENTIAL_ONLY,
1222 if (!NT_SUCCESS(Status))
1224 RtlFreeHeap(ProcessHeap, 0, NewBootSector);
1229 FilePosition.QuadPart = 0;
1231 Status = NtWriteFile(FileHandle,
1240 NtClose(FileHandle);
1242 /* Free the new boot sector */
1243 RtlFreeHeap(ProcessHeap, 0, NewBootSector);
1250 InstallFat32BootCodeToDisk(PWSTR SrcPath,
1253 OBJECT_ATTRIBUTES ObjectAttributes;
1254 IO_STATUS_BLOCK IoStatusBlock;
1255 UNICODE_STRING Name;
1258 PUCHAR OrigBootSector;
1259 PUCHAR NewBootSector;
1260 LARGE_INTEGER FileOffset;
1261 USHORT BackupBootSector;
1263 /* Allocate buffer for original bootsector */
1264 OrigBootSector = (PUCHAR)RtlAllocateHeap(ProcessHeap,
1267 if (OrigBootSector == NULL)
1268 return(STATUS_INSUFFICIENT_RESOURCES);
1270 /* Read current boot sector into buffer */
1271 RtlInitUnicodeString(&Name,
1274 InitializeObjectAttributes(&ObjectAttributes,
1276 OBJ_CASE_INSENSITIVE,
1280 Status = NtOpenFile(&FileHandle,
1285 FILE_SYNCHRONOUS_IO_ALERT);
1286 if (!NT_SUCCESS(Status))
1288 RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1292 Status = NtReadFile(FileHandle,
1301 NtClose(FileHandle);
1302 if (!NT_SUCCESS(Status))
1304 RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1309 /* Allocate buffer for new bootsector (2 sectors) */
1310 NewBootSector = (PUCHAR)RtlAllocateHeap(ProcessHeap,
1313 if (NewBootSector == NULL)
1315 RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1316 return(STATUS_INSUFFICIENT_RESOURCES);
1319 /* Read new bootsector from SrcPath */
1320 RtlInitUnicodeString(&Name,
1323 InitializeObjectAttributes(&ObjectAttributes,
1325 OBJ_CASE_INSENSITIVE,
1329 Status = NtOpenFile(&FileHandle,
1334 FILE_SYNCHRONOUS_IO_ALERT);
1335 if (!NT_SUCCESS(Status))
1337 RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1338 RtlFreeHeap(ProcessHeap, 0, NewBootSector);
1342 Status = NtReadFile(FileHandle,
1351 NtClose(FileHandle);
1352 if (!NT_SUCCESS(Status))
1354 RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1355 RtlFreeHeap(ProcessHeap, 0, NewBootSector);
1359 /* Adjust bootsector (copy a part of the FAT32 BPB) */
1360 memcpy((NewBootSector + 3),
1361 (OrigBootSector + 3),
1362 87); /* FAT32 BPB length */
1364 /* Get the location of the backup boot sector */
1365 BackupBootSector = (OrigBootSector[0x33] << 8) + OrigBootSector[0x32];
1367 /* Free the original boot sector */
1368 RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1370 /* Write the first sector of the new bootcode to DstPath */
1371 RtlInitUnicodeString(&Name,
1374 InitializeObjectAttributes(&ObjectAttributes,
1380 Status = NtOpenFile(&FileHandle,
1381 FILE_WRITE_ACCESS | FILE_WRITE_ATTRIBUTES,
1385 FILE_SYNCHRONOUS_IO_ALERT | FILE_SEQUENTIAL_ONLY);
1386 if (!NT_SUCCESS(Status))
1388 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status);
1389 RtlFreeHeap(ProcessHeap, 0, NewBootSector);
1393 /* Write sector 0 */
1394 FileOffset.QuadPart = 0ULL;
1395 Status = NtWriteFile(FileHandle,
1404 if (!NT_SUCCESS(Status))
1406 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status);
1407 NtClose(FileHandle);
1408 RtlFreeHeap(ProcessHeap, 0, NewBootSector);
1412 /* Write backup boot sector */
1413 if ((BackupBootSector != 0x0000) && (BackupBootSector != 0xFFFF))
1415 FileOffset.QuadPart = (ULONGLONG)((ULONG)BackupBootSector * SECTORSIZE);
1416 Status = NtWriteFile(FileHandle,
1425 if (!NT_SUCCESS(Status))
1427 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status);
1428 NtClose(FileHandle);
1429 RtlFreeHeap(ProcessHeap, 0, NewBootSector);
1434 /* Write sector 14 */
1435 FileOffset.QuadPart = (ULONGLONG)(14 * SECTORSIZE);
1436 Status = NtWriteFile(FileHandle,
1441 (NewBootSector + SECTORSIZE),
1445 if (!NT_SUCCESS(Status))
1447 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status);
1449 NtClose(FileHandle);
1451 /* Free the new boot sector */
1452 RtlFreeHeap(ProcessHeap, 0, NewBootSector);
1459 UnprotectBootIni(PWSTR FileName,
1462 UNICODE_STRING Name;
1463 OBJECT_ATTRIBUTES ObjectAttributes;
1464 IO_STATUS_BLOCK IoStatusBlock;
1465 FILE_BASIC_INFORMATION FileInfo;
1469 RtlInitUnicodeString(&Name,
1472 InitializeObjectAttributes(&ObjectAttributes,
1474 OBJ_CASE_INSENSITIVE,
1478 Status = NtOpenFile(&FileHandle,
1479 FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES,
1483 FILE_SYNCHRONOUS_IO_ALERT);
1484 if (Status == STATUS_NO_SUCH_FILE)
1486 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status);
1488 return(STATUS_SUCCESS);
1490 if (!NT_SUCCESS(Status))
1492 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status);
1496 Status = NtQueryInformationFile(FileHandle,
1499 sizeof(FILE_BASIC_INFORMATION),
1500 FileBasicInformation);
1501 if (!NT_SUCCESS(Status))
1503 DPRINT1("NtQueryInformationFile() failed (Status %lx)\n", Status);
1504 NtClose(FileHandle);
1508 *Attributes = FileInfo.FileAttributes;
1510 /* Delete attributes SYSTEM, HIDDEN and READONLY */
1511 FileInfo.FileAttributes = FileInfo.FileAttributes &
1512 ~(FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_READONLY);
1514 Status = NtSetInformationFile(FileHandle,
1517 sizeof(FILE_BASIC_INFORMATION),
1518 FileBasicInformation);
1519 if (!NT_SUCCESS(Status))
1521 DPRINT1("NtSetInformationFile() failed (Status %lx)\n", Status);
1524 NtClose(FileHandle);
1530 ProtectBootIni(PWSTR FileName,
1533 UNICODE_STRING Name;
1534 OBJECT_ATTRIBUTES ObjectAttributes;
1535 IO_STATUS_BLOCK IoStatusBlock;
1536 FILE_BASIC_INFORMATION FileInfo;
1540 RtlInitUnicodeString(&Name,
1543 InitializeObjectAttributes(&ObjectAttributes,
1545 OBJ_CASE_INSENSITIVE,
1549 Status = NtOpenFile(&FileHandle,
1550 FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES,
1554 FILE_SYNCHRONOUS_IO_ALERT);
1555 if (!NT_SUCCESS(Status))
1557 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status);
1561 Status = NtQueryInformationFile(FileHandle,
1564 sizeof(FILE_BASIC_INFORMATION),
1565 FileBasicInformation);
1566 if (!NT_SUCCESS(Status))
1568 DPRINT1("NtQueryInformationFile() failed (Status %lx)\n", Status);
1569 NtClose(FileHandle);
1573 FileInfo.FileAttributes = FileInfo.FileAttributes | Attributes;
1575 Status = NtSetInformationFile(FileHandle,
1578 sizeof(FILE_BASIC_INFORMATION),
1579 FileBasicInformation);
1580 if (!NT_SUCCESS(Status))
1582 DPRINT1("NtSetInformationFile() failed (Status %lx)\n", Status);
1585 NtClose(FileHandle);
1591 UpdateBootIni(PWSTR BootIniPath,
1595 UNICODE_STRING Name;
1596 PINICACHE Cache = NULL;
1597 PINICACHESECTION Section = NULL;
1599 ULONG FileAttribute;
1601 RtlInitUnicodeString(&Name,
1604 Status = IniCacheLoad(&Cache,
1607 if (!NT_SUCCESS(Status))
1613 Section = IniCacheGetSection(Cache,
1614 L"operating systems");
1615 if (Section == NULL)
1618 IniCacheDestroy(Cache);
1619 return(STATUS_UNSUCCESSFUL);
1622 IniCacheInsertKey(Section,
1628 Status = UnprotectBootIni(BootIniPath,
1630 if (!NT_SUCCESS(Status))
1633 IniCacheDestroy(Cache);
1637 Status = IniCacheSave(Cache,
1639 if (!NT_SUCCESS(Status))
1642 IniCacheDestroy(Cache);
1646 FileAttribute |= (FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_READONLY);
1647 Status = ProtectBootIni(BootIniPath,
1650 IniCacheDestroy(Cache);