2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS text-mode setup
4 * FILE: subsys/system/usetup/bootsup.c
5 * PURPOSE: Bootloader support functions
6 * PROGRAMMER: Eric Kohl
14 #define SECTORSIZE 512
17 typedef struct _FAT_BOOTSECTOR
19 UCHAR JumpBoot
[3]; // Jump instruction to boot code
20 CHAR OemName
[8]; // "MSWIN4.1" for MS formatted volumes
21 USHORT BytesPerSector
; // Bytes per sector
22 UCHAR SectorsPerCluster
; // Number of sectors in a cluster
23 USHORT ReservedSectors
; // Reserved sectors, usually 1 (the bootsector)
24 UCHAR NumberOfFats
; // Number of FAT tables
25 USHORT RootDirEntries
; // Number of root directory entries (fat12/16)
26 USHORT TotalSectors
; // Number of total sectors on the drive, 16-bit
27 UCHAR MediaDescriptor
; // Media descriptor byte
28 USHORT SectorsPerFat
; // Sectors per FAT table (fat12/16)
29 USHORT SectorsPerTrack
; // Number of sectors in a track
30 USHORT NumberOfHeads
; // Number of heads on the disk
31 ULONG HiddenSectors
; // Hidden sectors (sectors before the partition start like the partition table)
32 ULONG TotalSectorsBig
; // This field is the new 32-bit total count of sectors on the volume
33 UCHAR DriveNumber
; // Int 0x13 drive number (e.g. 0x80)
34 UCHAR Reserved1
; // Reserved (used by Windows NT). Code that formats FAT volumes should always set this byte to 0.
35 UCHAR BootSignature
; // Extended boot signature (0x29). This is a signature byte that indicates that the following three fields in the boot sector are present.
36 ULONG VolumeSerialNumber
; // Volume serial number
37 CHAR VolumeLabel
[11]; // Volume label. This field matches the 11-byte volume label recorded in the root directory
38 CHAR FileSystemType
[8]; // One of the strings "FAT12 ", "FAT16 ", or "FAT "
40 UCHAR BootCodeAndData
[448]; // The remainder of the boot sector
42 USHORT BootSectorMagic
; // 0xAA55
44 } FAT_BOOTSECTOR
, *PFAT_BOOTSECTOR
;
46 typedef struct _FAT32_BOOTSECTOR
48 UCHAR JumpBoot
[3]; // Jump instruction to boot code
49 CHAR OemName
[8]; // "MSWIN4.1" for MS formatted volumes
50 USHORT BytesPerSector
; // Bytes per sector
51 UCHAR SectorsPerCluster
; // Number of sectors in a cluster
52 USHORT ReservedSectors
; // Reserved sectors, usually 1 (the bootsector)
53 UCHAR NumberOfFats
; // Number of FAT tables
54 USHORT RootDirEntries
; // Number of root directory entries (fat12/16)
55 USHORT TotalSectors
; // Number of total sectors on the drive, 16-bit
56 UCHAR MediaDescriptor
; // Media descriptor byte
57 USHORT SectorsPerFat
; // Sectors per FAT table (fat12/16)
58 USHORT SectorsPerTrack
; // Number of sectors in a track
59 USHORT NumberOfHeads
; // Number of heads on the disk
60 ULONG HiddenSectors
; // Hidden sectors (sectors before the partition start like the partition table)
61 ULONG TotalSectorsBig
; // This field is the new 32-bit total count of sectors on the volume
62 ULONG SectorsPerFatBig
; // This field is the FAT32 32-bit count of sectors occupied by ONE FAT. BPB_FATSz16 must be 0
63 USHORT ExtendedFlags
; // Extended flags (fat32)
64 USHORT FileSystemVersion
; // File system version (fat32)
65 ULONG RootDirStartCluster
; // Starting cluster of the root directory (fat32)
66 USHORT FsInfo
; // Sector number of FSINFO structure in the reserved area of the FAT32 volume. Usually 1.
67 USHORT BackupBootSector
; // If non-zero, indicates the sector number in the reserved area of the volume of a copy of the boot record. Usually 6.
68 UCHAR Reserved
[12]; // Reserved for future expansion
69 UCHAR DriveNumber
; // Int 0x13 drive number (e.g. 0x80)
70 UCHAR Reserved1
; // Reserved (used by Windows NT). Code that formats FAT volumes should always set this byte to 0.
71 UCHAR BootSignature
; // Extended boot signature (0x29). This is a signature byte that indicates that the following three fields in the boot sector are present.
72 ULONG VolumeSerialNumber
; // Volume serial number
73 CHAR VolumeLabel
[11]; // Volume label. This field matches the 11-byte volume label recorded in the root directory
74 CHAR FileSystemType
[8]; // Always set to the string "FAT32 "
76 UCHAR BootCodeAndData
[420]; // The remainder of the boot sector
78 USHORT BootSectorMagic
; // 0xAA55
80 } FAT32_BOOTSECTOR
, *PFAT32_BOOTSECTOR
;
83 extern PPARTLIST PartitionList
;
85 /* FUNCTIONS ****************************************************************/
90 CreateCommonFreeLoaderSections(
93 PINICACHESECTION IniSection
;
95 /* Create "FREELOADER" section */
96 IniSection
= IniCacheAppendSection(IniCache
,
100 if (IsUnattendedSetup
)
102 /* DefaultOS=ReactOS */
103 IniCacheInsertKey(IniSection
,
108 L
"ReactOS_KdSerial");
116 /* DefaultOS=ReactOS */
117 IniCacheInsertKey(IniSection
,
125 if (IsUnattendedSetup
)
128 /* Timeout=0 for unattended or non debug*/
129 IniCacheInsertKey(IniSection
,
138 /* Timeout=0 or 10 */
139 IniCacheInsertKey(IniSection
,
147 /* Create "Display" section */
148 IniSection
= IniCacheAppendSection(IniCache
, L
"Display");
150 /* TitleText=ReactOS Boot Manager */
151 IniCacheInsertKey(IniSection
,
155 L
"ReactOS Boot Manager");
157 /* StatusBarColor=Cyan */
158 IniCacheInsertKey(IniSection
,
164 /* StatusBarTextColor=Black */
165 IniCacheInsertKey(IniSection
,
168 L
"StatusBarTextColor",
171 /* BackdropTextColor=White */
172 IniCacheInsertKey(IniSection
,
175 L
"BackdropTextColor",
178 /* BackdropColor=Blue */
179 IniCacheInsertKey(IniSection
,
185 /* BackdropFillStyle=Medium */
186 IniCacheInsertKey(IniSection
,
189 L
"BackdropFillStyle",
192 /* TitleBoxTextColor=White */
193 IniCacheInsertKey(IniSection
,
196 L
"TitleBoxTextColor",
199 /* TitleBoxColor=Red */
200 IniCacheInsertKey(IniSection
,
206 /* MessageBoxTextColor=White */
207 IniCacheInsertKey(IniSection
,
210 L
"MessageBoxTextColor",
213 /* MessageBoxColor=Blue */
214 IniCacheInsertKey(IniSection
,
220 /* MenuTextColor=White */
221 IniCacheInsertKey(IniSection
,
228 IniCacheInsertKey(IniSection
,
234 /* TextColor=Yellow */
235 IniCacheInsertKey(IniSection
,
241 /* SelectedTextColor=Black */
242 IniCacheInsertKey(IniSection
,
245 L
"SelectedTextColor",
248 /* SelectedColor=Gray */
249 IniCacheInsertKey(IniSection
,
255 /* SelectedColor=Gray */
256 IniCacheInsertKey(IniSection
,
262 /* SelectedColor=Gray */
263 IniCacheInsertKey(IniSection
,
269 /* SelectedColor=Gray */
270 IniCacheInsertKey(IniSection
,
276 /* SelectedColor=Gray */
277 IniCacheInsertKey(IniSection
,
283 /* SelectedColor=Gray */
284 IniCacheInsertKey(IniSection
,
288 L
"Seconds until highlighted choice will be started automatically: ");
293 CreateFreeLoaderIniForDos(
298 PINICACHESECTION IniSection
;
300 IniCache
= IniCacheCreate();
302 CreateCommonFreeLoaderSections(IniCache
);
304 /* Create "Operating Systems" section */
305 IniSection
= IniCacheAppendSection(IniCache
, L
"Operating Systems");
307 /* REACTOS=ReactOS */
308 IniCacheInsertKey(IniSection
,
314 /* ReactOS_Debug="ReactOS (Debug)" */
315 IniCacheInsertKey(IniSection
,
319 L
"\"ReactOS (Debug)\"");
321 /* DOS=Dos/Windows */
322 IniCacheInsertKey(IniSection
,
328 /* Create "ReactOS" section */
329 IniSection
= IniCacheAppendSection(IniCache
, L
"ReactOS");
331 /* BootType=ReactOS */
332 IniCacheInsertKey(IniSection
,
338 /* SystemPath=<ArcPath> */
339 IniCacheInsertKey(IniSection
,
345 /* Create "ReactOS_Debug" section */
346 IniSection
= IniCacheAppendSection(IniCache
, L
"ReactOS_Debug");
348 /* BootType=ReactOS */
349 IniCacheInsertKey(IniSection
,
355 /* SystemPath=<ArcPath> */
356 IniCacheInsertKey(IniSection
,
362 /* Options=/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS */
363 IniCacheInsertKey(IniSection
,
367 L
"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS");
369 /* Create "DOS" section */
370 IniSection
= IniCacheAppendSection(IniCache
,
373 /* BootType=BootSector */
374 IniCacheInsertKey(IniSection
,
381 IniCacheInsertKey(IniSection
,
387 /* BootPartition=1 */
388 IniCacheInsertKey(IniSection
,
394 /* BootSector=BOOTSECT.DOS */
395 IniCacheInsertKey(IniSection
,
401 IniCacheSave(IniCache
, IniPath
);
402 IniCacheDestroy(IniCache
);
404 return STATUS_SUCCESS
;
409 CreateFreeLoaderEntry(
411 PINICACHESECTION OSSection
,
418 PINICACHESECTION IniSection
;
420 /* Insert entry into "Operating Systems" section */
421 IniCacheInsertKey(OSSection
,
427 /* Create new section */
428 IniSection
= IniCacheAppendSection(IniCache
, Section
);
431 IniCacheInsertKey(IniSection
,
438 IniCacheInsertKey(IniSection
,
445 IniCacheInsertKey(IniSection
,
451 return STATUS_SUCCESS
;
455 CreateFreeLoaderIniForReactos(
460 PINICACHESECTION IniSection
;
462 IniCache
= IniCacheCreate();
464 CreateCommonFreeLoaderSections(IniCache
);
466 /* Create "Operating Systems" section */
467 IniSection
= IniCacheAppendSection(IniCache
, L
"Operating Systems");
470 CreateFreeLoaderEntry(IniCache
, IniSection
,
471 L
"ReactOS", L
"\"ReactOS\"",
472 L
"Windows2003", ArcPath
,
476 CreateFreeLoaderEntry(IniCache
, IniSection
,
477 L
"ReactOS_Debug", L
"\"ReactOS (Debug)\"",
478 L
"Windows2003", ArcPath
,
479 L
"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS");
483 /* ReactOS_KdSerial */
484 CreateFreeLoaderEntry(IniCache
, IniSection
,
485 L
"ReactOS_KdSerial", L
"\"ReactOS (RosDbg)\"",
486 L
"Windows2003", ArcPath
,
487 L
"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /KDSERIAL");
491 CreateFreeLoaderEntry(IniCache
, IniSection
,
492 L
"ReactOS_Screen", L
"\"ReactOS (Screen)\"",
493 L
"Windows2003", ArcPath
,
494 L
"/DEBUG /DEBUGPORT=SCREEN /SOS");
496 /* ReactOS_LogFile */
497 CreateFreeLoaderEntry(IniCache
, IniSection
,
498 L
"ReactOS_LogFile", L
"\"ReactOS (Log file)\"",
499 L
"Windows2003", ArcPath
,
500 L
"/DEBUG /DEBUGPORT=FILE /SOS");
503 CreateFreeLoaderEntry(IniCache
, IniSection
,
504 L
"ReactOS_Ram", L
"\"ReactOS (RAM Disk)\"",
505 L
"Windows2003", L
"ramdisk(0)\\ReactOS",
506 L
"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /RDIMAGEPATH=reactos.img /RDIMAGEOFFSET=32256");
509 CreateFreeLoaderEntry(IniCache
, IniSection
,
510 L
"ReactOS_EMS", L
"\"ReactOS (Emergency Management Services)\"",
511 L
"Windows2003", ArcPath
,
512 L
"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /redirect=com2 /redirectbaudrate=115200");
515 /* Save the ini file */
516 IniCacheSave(IniCache
, IniPath
);
517 IniCacheDestroy(IniCache
);
519 return STATUS_SUCCESS
;
530 PINICACHESECTION IniSection
;
531 PINICACHESECTION OsIniSection
;
532 WCHAR SectionName
[80];
534 WCHAR SystemPath
[200];
535 WCHAR SectionName2
[200];
540 RtlInitUnicodeString(&Name
, IniPath
);
542 Status
= IniCacheLoad(&IniCache
, &Name
, FALSE
);
543 if (!NT_SUCCESS(Status
))
546 /* Get "Operating Systems" section */
547 IniSection
= IniCacheGetSection(IniCache
, L
"Operating Systems");
548 if (IniSection
== NULL
)
550 IniCacheDestroy(IniCache
);
551 return STATUS_UNSUCCESSFUL
;
554 /* Find an existing usable or an unused section name */
556 wcscpy(SectionName
, L
"ReactOS");
557 wcscpy(OsName
, L
"\"ReactOS\"");
560 Status
= IniCacheGetKey(IniSection
, SectionName
, &KeyData
);
561 if (!NT_SUCCESS(Status
))
564 /* Get operation system section */
565 if (KeyData
[0] == '"')
567 wcscpy(SectionName2
, &KeyData
[1]);
568 j
= wcslen(SectionName2
);
571 SectionName2
[j
-1] = 0;
576 wcscpy(SectionName2
, KeyData
);
579 OsIniSection
= IniCacheGetSection(IniCache
, SectionName2
);
580 if (OsIniSection
!= NULL
)
582 BOOLEAN UseExistingEntry
= TRUE
;
585 Status
= IniCacheGetKey(OsIniSection
, L
"BootType", &KeyData
);
586 if (NT_SUCCESS(Status
))
588 if ((KeyData
== NULL
) ||
589 ( (_wcsicmp(KeyData
, L
"ReactOS") != 0) &&
590 (_wcsicmp(KeyData
, L
"\"ReactOS\"") != 0) ))
592 /* This is not a ReactOS entry */
593 UseExistingEntry
= FALSE
;
598 UseExistingEntry
= FALSE
;
601 if (UseExistingEntry
)
603 /* BootType is ReactOS. Now check SystemPath */
604 Status
= IniCacheGetKey(OsIniSection
, L
"SystemPath", &KeyData
);
605 if (NT_SUCCESS(Status
))
607 swprintf(SystemPath
, L
"\"%S\"", ArcPath
);
608 if ((KeyData
== NULL
) ||
609 ((_wcsicmp(KeyData
, ArcPath
) != 0) &&
610 (_wcsicmp(KeyData
, SystemPath
) != 0) ))
612 /* This entry is a ReactOS entry, but the SystemRoot does not
613 match the one we are looking for */
614 UseExistingEntry
= FALSE
;
619 UseExistingEntry
= FALSE
;
623 if (UseExistingEntry
)
625 IniCacheDestroy(IniCache
);
626 return STATUS_SUCCESS
;
630 swprintf(SectionName
, L
"ReactOS_%lu", i
);
631 swprintf(OsName
, L
"\"ReactOS %lu\"", i
);
635 /* <SectionName>=<OsName> */
636 IniCacheInsertKey(IniSection
,
642 /* Create <SectionName> section */
643 IniSection
= IniCacheAppendSection(IniCache
, SectionName
);
645 /* BootType=ReactOS */
646 IniCacheInsertKey(IniSection
,
652 /* SystemPath=<ArcPath> */
653 IniCacheInsertKey(IniSection
,
659 IniCacheSave(IniCache
, IniPath
);
660 IniCacheDestroy(IniCache
);
662 return STATUS_SUCCESS
;
667 SaveCurrentBootSector(
671 OBJECT_ATTRIBUTES ObjectAttributes
;
672 IO_STATUS_BLOCK IoStatusBlock
;
678 /* Allocate buffer for bootsector */
679 BootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
680 if (BootSector
== NULL
)
681 return STATUS_INSUFFICIENT_RESOURCES
;
683 /* Read current boot sector into buffer */
684 RtlInitUnicodeString(&Name
, RootPath
);
686 InitializeObjectAttributes(&ObjectAttributes
,
688 OBJ_CASE_INSENSITIVE
,
692 Status
= NtOpenFile(&FileHandle
,
693 GENERIC_READ
| SYNCHRONIZE
,
697 FILE_SYNCHRONOUS_IO_NONALERT
);
698 if (!NT_SUCCESS(Status
))
700 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
704 Status
= NtReadFile(FileHandle
,
714 if (!NT_SUCCESS(Status
))
716 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
720 /* Write bootsector to DstPath */
721 RtlInitUnicodeString(&Name
, DstPath
);
723 InitializeObjectAttributes(&ObjectAttributes
,
729 Status
= NtCreateFile(&FileHandle
,
730 GENERIC_WRITE
| SYNCHRONIZE
,
734 FILE_ATTRIBUTE_NORMAL
,
737 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
,
740 if (!NT_SUCCESS(Status
))
742 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
746 Status
= NtWriteFile(FileHandle
,
757 /* Free the new boot sector */
758 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
765 InstallFat16BootCodeToFile(
770 OBJECT_ATTRIBUTES ObjectAttributes
;
771 IO_STATUS_BLOCK IoStatusBlock
;
775 PFAT_BOOTSECTOR OrigBootSector
;
776 PFAT_BOOTSECTOR NewBootSector
;
778 /* Allocate buffer for original bootsector */
779 OrigBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
780 if (OrigBootSector
== NULL
)
781 return STATUS_INSUFFICIENT_RESOURCES
;
783 /* Read current boot sector into buffer */
784 RtlInitUnicodeString(&Name
, RootPath
);
786 InitializeObjectAttributes(&ObjectAttributes
,
788 OBJ_CASE_INSENSITIVE
,
792 Status
= NtOpenFile(&FileHandle
,
793 GENERIC_READ
| SYNCHRONIZE
,
797 FILE_SYNCHRONOUS_IO_NONALERT
);
798 if (!NT_SUCCESS(Status
))
800 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
804 Status
= NtReadFile(FileHandle
,
814 if (!NT_SUCCESS(Status
))
816 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
820 /* Allocate buffer for new bootsector */
821 NewBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
822 if (NewBootSector
== NULL
)
824 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
825 return STATUS_INSUFFICIENT_RESOURCES
;
828 /* Read new bootsector from SrcPath */
829 RtlInitUnicodeString(&Name
, SrcPath
);
831 InitializeObjectAttributes(&ObjectAttributes
,
833 OBJ_CASE_INSENSITIVE
,
837 Status
= NtOpenFile(&FileHandle
,
838 GENERIC_READ
| SYNCHRONIZE
,
842 FILE_SYNCHRONOUS_IO_NONALERT
);
843 if (!NT_SUCCESS(Status
))
845 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
846 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
850 Status
= NtReadFile(FileHandle
,
860 if (!NT_SUCCESS(Status
))
862 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
863 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
867 /* Adjust bootsector (copy a part of the FAT BPB) */
868 memcpy(&NewBootSector
->OemName
,
869 &OrigBootSector
->OemName
,
870 FIELD_OFFSET(FAT_BOOTSECTOR
, BootCodeAndData
) -
871 FIELD_OFFSET(FAT_BOOTSECTOR
, OemName
));
873 /* Free the original boot sector */
874 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
876 /* Write new bootsector to DstPath */
877 RtlInitUnicodeString(&Name
, DstPath
);
879 InitializeObjectAttributes(&ObjectAttributes
,
885 Status
= NtCreateFile(&FileHandle
,
886 GENERIC_WRITE
| SYNCHRONIZE
,
890 FILE_ATTRIBUTE_NORMAL
,
893 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
,
896 if (!NT_SUCCESS(Status
))
898 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
903 FilePosition
.QuadPart
= 0;
905 Status
= NtWriteFile(FileHandle
,
916 /* Free the new boot sector */
917 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
924 InstallFat32BootCodeToFile(
929 OBJECT_ATTRIBUTES ObjectAttributes
;
930 IO_STATUS_BLOCK IoStatusBlock
;
934 PFAT32_BOOTSECTOR OrigBootSector
;
935 PFAT32_BOOTSECTOR NewBootSector
;
936 LARGE_INTEGER FileOffset
;
938 /* Allocate buffer for original bootsector */
939 OrigBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
940 if (OrigBootSector
== NULL
)
941 return STATUS_INSUFFICIENT_RESOURCES
;
943 /* Read current boot sector into buffer */
944 RtlInitUnicodeString(&Name
, RootPath
);
946 InitializeObjectAttributes(&ObjectAttributes
,
948 OBJ_CASE_INSENSITIVE
,
952 Status
= NtOpenFile(&FileHandle
,
953 GENERIC_READ
| SYNCHRONIZE
,
957 FILE_SYNCHRONOUS_IO_NONALERT
);
958 if (!NT_SUCCESS(Status
))
960 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
964 Status
= NtReadFile(FileHandle
,
974 if (!NT_SUCCESS(Status
))
976 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
980 /* Allocate buffer for new bootsector (2 sectors) */
981 NewBootSector
= RtlAllocateHeap(ProcessHeap
, 0, 2 * SECTORSIZE
);
982 if (NewBootSector
== NULL
)
984 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
985 return STATUS_INSUFFICIENT_RESOURCES
;
988 /* Read new bootsector from SrcPath */
989 RtlInitUnicodeString(&Name
, SrcPath
);
991 InitializeObjectAttributes(&ObjectAttributes
,
993 OBJ_CASE_INSENSITIVE
,
997 Status
= NtOpenFile(&FileHandle
,
998 GENERIC_READ
| SYNCHRONIZE
,
1002 FILE_SYNCHRONOUS_IO_NONALERT
);
1003 if (!NT_SUCCESS(Status
))
1005 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1006 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1010 Status
= NtReadFile(FileHandle
,
1019 NtClose(FileHandle
);
1020 if (!NT_SUCCESS(Status
))
1022 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1023 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1027 /* Adjust bootsector (copy a part of the FAT32 BPB) */
1028 memcpy(&NewBootSector
->OemName
,
1029 &OrigBootSector
->OemName
,
1030 FIELD_OFFSET(FAT32_BOOTSECTOR
, BootCodeAndData
) -
1031 FIELD_OFFSET(FAT32_BOOTSECTOR
, OemName
));
1033 /* Disable the backup boot sector */
1034 NewBootSector
->BackupBootSector
= 0;
1036 /* Free the original boot sector */
1037 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1039 /* Write the first sector of the new bootcode to DstPath */
1040 RtlInitUnicodeString(&Name
, DstPath
);
1042 InitializeObjectAttributes(&ObjectAttributes
,
1048 Status
= NtCreateFile(&FileHandle
,
1049 GENERIC_WRITE
| SYNCHRONIZE
,
1053 FILE_ATTRIBUTE_NORMAL
,
1056 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
,
1059 if (!NT_SUCCESS(Status
))
1061 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1065 Status
= NtWriteFile(FileHandle
,
1074 NtClose(FileHandle
);
1075 if (!NT_SUCCESS(Status
))
1077 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1081 /* Write the second sector of the new bootcode to boot disk sector 14 */
1082 RtlInitUnicodeString(&Name
, RootPath
);
1084 InitializeObjectAttributes(&ObjectAttributes
,
1090 Status
= NtOpenFile(&FileHandle
,
1091 GENERIC_WRITE
| SYNCHRONIZE
,
1095 FILE_SYNCHRONOUS_IO_NONALERT
);
1096 if (!NT_SUCCESS(Status
))
1098 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1102 FileOffset
.QuadPart
= (ULONGLONG
)(14 * SECTORSIZE
);
1103 Status
= NtWriteFile(FileHandle
,
1108 ((PUCHAR
)NewBootSector
+ SECTORSIZE
),
1112 if (!NT_SUCCESS(Status
))
1115 NtClose(FileHandle
);
1117 /* Free the new boot sector */
1118 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1125 InstallMbrBootCodeToDisk(
1129 OBJECT_ATTRIBUTES ObjectAttributes
;
1130 IO_STATUS_BLOCK IoStatusBlock
;
1131 UNICODE_STRING Name
;
1134 PPARTITION_SECTOR OrigBootSector
;
1135 PPARTITION_SECTOR NewBootSector
;
1137 /* Allocate buffer for original bootsector */
1138 OrigBootSector
= (PPARTITION_SECTOR
)RtlAllocateHeap(ProcessHeap
,
1140 sizeof(PARTITION_SECTOR
));
1141 if (OrigBootSector
== NULL
)
1142 return STATUS_INSUFFICIENT_RESOURCES
;
1144 /* Read current boot sector into buffer */
1145 RtlInitUnicodeString(&Name
,
1148 InitializeObjectAttributes(&ObjectAttributes
,
1150 OBJ_CASE_INSENSITIVE
,
1154 Status
= NtOpenFile(&FileHandle
,
1155 GENERIC_READ
| SYNCHRONIZE
,
1159 FILE_SYNCHRONOUS_IO_NONALERT
);
1160 if (!NT_SUCCESS(Status
))
1162 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1166 Status
= NtReadFile(FileHandle
,
1175 NtClose(FileHandle
);
1176 if (!NT_SUCCESS(Status
))
1178 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1182 /* Allocate buffer for new bootsector */
1183 NewBootSector
= (PPARTITION_SECTOR
)RtlAllocateHeap(ProcessHeap
,
1185 sizeof(PARTITION_SECTOR
));
1186 if (NewBootSector
== NULL
)
1188 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1189 return STATUS_INSUFFICIENT_RESOURCES
;
1192 /* Read new bootsector from SrcPath */
1193 RtlInitUnicodeString(&Name
, SrcPath
);
1195 InitializeObjectAttributes(&ObjectAttributes
,
1197 OBJ_CASE_INSENSITIVE
,
1201 Status
= NtOpenFile(&FileHandle
,
1202 GENERIC_READ
| SYNCHRONIZE
,
1206 FILE_SYNCHRONOUS_IO_NONALERT
);
1207 if (!NT_SUCCESS(Status
))
1209 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1210 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1214 Status
= NtReadFile(FileHandle
,
1220 sizeof(PARTITION_SECTOR
),
1223 NtClose(FileHandle
);
1224 if (!NT_SUCCESS(Status
))
1226 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1227 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1231 /* Copy partition table from old MBR to new */
1232 RtlCopyMemory (&NewBootSector
->Signature
,
1233 &OrigBootSector
->Signature
,
1234 sizeof(PARTITION_SECTOR
) - offsetof(PARTITION_SECTOR
, Signature
) /* Length of partition table */);
1236 /* Free the original boot sector */
1237 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1239 /* Write new bootsector to RootPath */
1240 RtlInitUnicodeString(&Name
, RootPath
);
1242 InitializeObjectAttributes(&ObjectAttributes
,
1248 Status
= NtOpenFile(&FileHandle
,
1249 GENERIC_WRITE
| SYNCHRONIZE
,
1253 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1254 if (!NT_SUCCESS(Status
))
1256 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1257 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1261 Status
= NtWriteFile(FileHandle
,
1270 NtClose(FileHandle
);
1272 /* Free the new boot sector */
1273 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1280 InstallFat12BootCodeToFloppy(
1284 OBJECT_ATTRIBUTES ObjectAttributes
;
1285 IO_STATUS_BLOCK IoStatusBlock
;
1286 UNICODE_STRING Name
;
1289 PFAT_BOOTSECTOR OrigBootSector
;
1290 PFAT_BOOTSECTOR NewBootSector
;
1292 /* Allocate buffer for original bootsector */
1293 OrigBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
1294 if (OrigBootSector
== NULL
)
1295 return STATUS_INSUFFICIENT_RESOURCES
;
1297 /* Read current boot sector into buffer */
1298 RtlInitUnicodeString(&Name
, RootPath
);
1300 InitializeObjectAttributes(&ObjectAttributes
,
1302 OBJ_CASE_INSENSITIVE
,
1306 Status
= NtOpenFile(&FileHandle
,
1307 GENERIC_READ
| SYNCHRONIZE
,
1311 FILE_SYNCHRONOUS_IO_NONALERT
);
1312 if (!NT_SUCCESS(Status
))
1314 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1318 Status
= NtReadFile(FileHandle
,
1327 NtClose(FileHandle
);
1328 if (!NT_SUCCESS(Status
))
1330 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1334 /* Allocate buffer for new bootsector */
1335 NewBootSector
= RtlAllocateHeap(ProcessHeap
,
1338 if (NewBootSector
== NULL
)
1340 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1341 return STATUS_INSUFFICIENT_RESOURCES
;
1344 /* Read new bootsector from SrcPath */
1345 RtlInitUnicodeString(&Name
, SrcPath
);
1347 InitializeObjectAttributes(&ObjectAttributes
,
1349 OBJ_CASE_INSENSITIVE
,
1353 Status
= NtOpenFile(&FileHandle
,
1354 GENERIC_READ
| SYNCHRONIZE
,
1358 FILE_SYNCHRONOUS_IO_NONALERT
);
1359 if (!NT_SUCCESS(Status
))
1361 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1362 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1366 Status
= NtReadFile(FileHandle
,
1375 NtClose(FileHandle
);
1376 if (!NT_SUCCESS(Status
))
1378 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1379 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1383 /* Adjust bootsector (copy a part of the FAT16 BPB) */
1384 memcpy(&NewBootSector
->OemName
,
1385 &OrigBootSector
->OemName
,
1386 FIELD_OFFSET(FAT_BOOTSECTOR
, BootCodeAndData
) -
1387 FIELD_OFFSET(FAT_BOOTSECTOR
, OemName
));
1389 /* Free the original boot sector */
1390 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1392 /* Write new bootsector to RootPath */
1393 RtlInitUnicodeString(&Name
, RootPath
);
1395 InitializeObjectAttributes(&ObjectAttributes
,
1401 Status
= NtOpenFile(&FileHandle
,
1402 GENERIC_WRITE
| SYNCHRONIZE
,
1406 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1407 if (!NT_SUCCESS(Status
))
1409 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1410 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1415 FilePosition
.QuadPart
= 0;
1417 Status
= NtWriteFile(FileHandle
,
1426 NtClose(FileHandle
);
1428 /* Free the new boot sector */
1429 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1436 InstallFat16BootCodeToDisk(
1440 OBJECT_ATTRIBUTES ObjectAttributes
;
1441 IO_STATUS_BLOCK IoStatusBlock
;
1442 UNICODE_STRING Name
;
1445 PFAT_BOOTSECTOR OrigBootSector
;
1446 PFAT_BOOTSECTOR NewBootSector
;
1448 /* Allocate buffer for original bootsector */
1449 OrigBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
1450 if (OrigBootSector
== NULL
)
1451 return STATUS_INSUFFICIENT_RESOURCES
;
1453 /* Read current boot sector into buffer */
1454 RtlInitUnicodeString(&Name
, RootPath
);
1456 InitializeObjectAttributes(&ObjectAttributes
,
1458 OBJ_CASE_INSENSITIVE
,
1462 Status
= NtOpenFile(&FileHandle
,
1463 GENERIC_READ
| SYNCHRONIZE
,
1467 FILE_SYNCHRONOUS_IO_NONALERT
);
1468 if (!NT_SUCCESS(Status
))
1470 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1474 Status
= NtReadFile(FileHandle
,
1483 NtClose(FileHandle
);
1484 if (!NT_SUCCESS(Status
))
1486 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1490 /* Allocate buffer for new bootsector */
1491 NewBootSector
= RtlAllocateHeap(ProcessHeap
,
1494 if (NewBootSector
== NULL
)
1496 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1497 return STATUS_INSUFFICIENT_RESOURCES
;
1500 /* Read new bootsector from SrcPath */
1501 RtlInitUnicodeString(&Name
, SrcPath
);
1503 InitializeObjectAttributes(&ObjectAttributes
,
1505 OBJ_CASE_INSENSITIVE
,
1509 Status
= NtOpenFile(&FileHandle
,
1510 GENERIC_READ
| SYNCHRONIZE
,
1514 FILE_SYNCHRONOUS_IO_NONALERT
);
1515 if (!NT_SUCCESS(Status
))
1517 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1518 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1522 Status
= NtReadFile(FileHandle
,
1531 NtClose(FileHandle
);
1532 if (!NT_SUCCESS(Status
))
1534 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1535 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1539 /* Adjust bootsector (copy a part of the FAT16 BPB) */
1540 memcpy(&NewBootSector
->OemName
,
1541 &OrigBootSector
->OemName
,
1542 FIELD_OFFSET(FAT_BOOTSECTOR
, BootCodeAndData
) -
1543 FIELD_OFFSET(FAT_BOOTSECTOR
, OemName
));
1545 NewBootSector
->HiddenSectors
= PartitionList
->CurrentDisk
->SectorsPerTrack
;
1547 /* Free the original boot sector */
1548 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1550 /* Write new bootsector to RootPath */
1551 RtlInitUnicodeString(&Name
, RootPath
);
1553 InitializeObjectAttributes(&ObjectAttributes
,
1559 Status
= NtOpenFile(&FileHandle
,
1560 GENERIC_WRITE
| SYNCHRONIZE
,
1564 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1565 if (!NT_SUCCESS(Status
))
1567 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1568 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1573 FilePosition
.QuadPart
= 0;
1575 Status
= NtWriteFile(FileHandle
,
1584 NtClose(FileHandle
);
1586 /* Free the new boot sector */
1587 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1594 InstallFat32BootCodeToDisk(
1598 OBJECT_ATTRIBUTES ObjectAttributes
;
1599 IO_STATUS_BLOCK IoStatusBlock
;
1600 UNICODE_STRING Name
;
1603 PFAT32_BOOTSECTOR OrigBootSector
;
1604 PFAT32_BOOTSECTOR NewBootSector
;
1605 LARGE_INTEGER FileOffset
;
1606 USHORT BackupBootSector
;
1608 /* Allocate buffer for original bootsector */
1609 OrigBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
1610 if (OrigBootSector
== NULL
)
1611 return STATUS_INSUFFICIENT_RESOURCES
;
1613 /* Read current boot sector into buffer */
1614 RtlInitUnicodeString(&Name
, RootPath
);
1616 InitializeObjectAttributes(&ObjectAttributes
,
1618 OBJ_CASE_INSENSITIVE
,
1622 Status
= NtOpenFile(&FileHandle
,
1623 GENERIC_READ
| SYNCHRONIZE
,
1627 FILE_SYNCHRONOUS_IO_NONALERT
);
1628 if (!NT_SUCCESS(Status
))
1630 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1634 Status
= NtReadFile(FileHandle
,
1643 NtClose(FileHandle
);
1644 if (!NT_SUCCESS(Status
))
1646 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1651 /* Allocate buffer for new bootsector (2 sectors) */
1652 NewBootSector
= RtlAllocateHeap(ProcessHeap
, 0, 2 * SECTORSIZE
);
1653 if (NewBootSector
== NULL
)
1655 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1656 return STATUS_INSUFFICIENT_RESOURCES
;
1659 /* Read new bootsector from SrcPath */
1660 RtlInitUnicodeString(&Name
, SrcPath
);
1662 InitializeObjectAttributes(&ObjectAttributes
,
1664 OBJ_CASE_INSENSITIVE
,
1668 Status
= NtOpenFile(&FileHandle
,
1669 GENERIC_READ
| SYNCHRONIZE
,
1673 FILE_SYNCHRONOUS_IO_NONALERT
);
1674 if (!NT_SUCCESS(Status
))
1676 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1677 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1681 Status
= NtReadFile(FileHandle
,
1690 NtClose(FileHandle
);
1691 if (!NT_SUCCESS(Status
))
1693 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1694 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1698 /* Adjust bootsector (copy a part of the FAT32 BPB) */
1699 memcpy(&NewBootSector
->OemName
,
1700 &OrigBootSector
->OemName
,
1701 FIELD_OFFSET(FAT32_BOOTSECTOR
, BootCodeAndData
) -
1702 FIELD_OFFSET(FAT32_BOOTSECTOR
, OemName
));
1704 NewBootSector
->HiddenSectors
= PartitionList
->CurrentDisk
->SectorsPerTrack
;
1706 /* Get the location of the backup boot sector */
1707 BackupBootSector
= OrigBootSector
->BackupBootSector
;
1709 /* Free the original boot sector */
1710 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1712 /* Write the first sector of the new bootcode to DstPath */
1713 RtlInitUnicodeString(&Name
, RootPath
);
1715 InitializeObjectAttributes(&ObjectAttributes
,
1721 Status
= NtOpenFile(&FileHandle
,
1722 GENERIC_WRITE
| SYNCHRONIZE
,
1726 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1727 if (!NT_SUCCESS(Status
))
1729 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1730 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1734 /* Write sector 0 */
1735 FileOffset
.QuadPart
= 0ULL;
1736 Status
= NtWriteFile(FileHandle
,
1745 if (!NT_SUCCESS(Status
))
1747 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1748 NtClose(FileHandle
);
1749 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1753 /* Write backup boot sector */
1754 if ((BackupBootSector
!= 0x0000) && (BackupBootSector
!= 0xFFFF))
1756 FileOffset
.QuadPart
= (ULONGLONG
)((ULONG
)BackupBootSector
* SECTORSIZE
);
1757 Status
= NtWriteFile(FileHandle
,
1766 if (!NT_SUCCESS(Status
))
1768 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1769 NtClose(FileHandle
);
1770 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1775 /* Write sector 14 */
1776 FileOffset
.QuadPart
= 14 * SECTORSIZE
;
1777 Status
= NtWriteFile(FileHandle
,
1782 ((PUCHAR
)NewBootSector
+ SECTORSIZE
),
1786 if (!NT_SUCCESS(Status
))
1788 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1790 NtClose(FileHandle
);
1792 /* Free the new boot sector */
1793 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1805 UNICODE_STRING Name
;
1806 OBJECT_ATTRIBUTES ObjectAttributes
;
1807 IO_STATUS_BLOCK IoStatusBlock
;
1808 FILE_BASIC_INFORMATION FileInfo
;
1812 RtlInitUnicodeString(&Name
, FileName
);
1814 InitializeObjectAttributes(&ObjectAttributes
,
1816 OBJ_CASE_INSENSITIVE
,
1820 Status
= NtOpenFile(&FileHandle
,
1821 GENERIC_READ
| GENERIC_WRITE
| SYNCHRONIZE
,
1825 FILE_SYNCHRONOUS_IO_NONALERT
);
1826 if (Status
== STATUS_NO_SUCH_FILE
)
1828 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1830 return STATUS_SUCCESS
;
1832 if (!NT_SUCCESS(Status
))
1834 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1838 Status
= NtQueryInformationFile(FileHandle
,
1841 sizeof(FILE_BASIC_INFORMATION
),
1842 FileBasicInformation
);
1843 if (!NT_SUCCESS(Status
))
1845 DPRINT1("NtQueryInformationFile() failed (Status %lx)\n", Status
);
1846 NtClose(FileHandle
);
1850 *Attributes
= FileInfo
.FileAttributes
;
1852 /* Delete attributes SYSTEM, HIDDEN and READONLY */
1853 FileInfo
.FileAttributes
= FileInfo
.FileAttributes
&
1854 ~(FILE_ATTRIBUTE_SYSTEM
|
1855 FILE_ATTRIBUTE_HIDDEN
|
1856 FILE_ATTRIBUTE_READONLY
);
1858 Status
= NtSetInformationFile(FileHandle
,
1861 sizeof(FILE_BASIC_INFORMATION
),
1862 FileBasicInformation
);
1863 if (!NT_SUCCESS(Status
))
1865 DPRINT1("NtSetInformationFile() failed (Status %lx)\n", Status
);
1868 NtClose(FileHandle
);
1879 UNICODE_STRING Name
;
1880 OBJECT_ATTRIBUTES ObjectAttributes
;
1881 IO_STATUS_BLOCK IoStatusBlock
;
1882 FILE_BASIC_INFORMATION FileInfo
;
1886 RtlInitUnicodeString(&Name
, FileName
);
1888 InitializeObjectAttributes(&ObjectAttributes
,
1890 OBJ_CASE_INSENSITIVE
,
1894 Status
= NtOpenFile(&FileHandle
,
1895 GENERIC_READ
| GENERIC_WRITE
| SYNCHRONIZE
,
1899 FILE_SYNCHRONOUS_IO_NONALERT
);
1900 if (!NT_SUCCESS(Status
))
1902 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1906 Status
= NtQueryInformationFile(FileHandle
,
1909 sizeof(FILE_BASIC_INFORMATION
),
1910 FileBasicInformation
);
1911 if (!NT_SUCCESS(Status
))
1913 DPRINT1("NtQueryInformationFile() failed (Status %lx)\n", Status
);
1914 NtClose(FileHandle
);
1918 FileInfo
.FileAttributes
= FileInfo
.FileAttributes
| Attributes
;
1920 Status
= NtSetInformationFile(FileHandle
,
1923 sizeof(FILE_BASIC_INFORMATION
),
1924 FileBasicInformation
);
1925 if (!NT_SUCCESS(Status
))
1927 DPRINT1("NtSetInformationFile() failed (Status %lx)\n", Status
);
1930 NtClose(FileHandle
);
1941 UNICODE_STRING Name
;
1942 PINICACHE Cache
= NULL
;
1943 PINICACHESECTION Section
= NULL
;
1945 ULONG FileAttribute
;
1946 PWCHAR OldValue
= NULL
;
1948 RtlInitUnicodeString(&Name
, BootIniPath
);
1950 Status
= IniCacheLoad(&Cache
, &Name
, FALSE
);
1951 if (!NT_SUCCESS(Status
))
1956 Section
= IniCacheGetSection(Cache
,
1957 L
"operating systems");
1958 if (Section
== NULL
)
1960 IniCacheDestroy(Cache
);
1961 return STATUS_UNSUCCESSFUL
;
1964 /* Check - maybe record already exists */
1965 Status
= IniCacheGetKey(Section
, EntryName
, &OldValue
);
1967 /* If either key was not found, or contains something else - add new one */
1968 if (!NT_SUCCESS(Status
) || wcscmp(OldValue
, EntryValue
))
1970 IniCacheInsertKey(Section
,
1977 Status
= UnprotectBootIni(BootIniPath
,
1979 if (!NT_SUCCESS(Status
))
1981 IniCacheDestroy(Cache
);
1985 Status
= IniCacheSave(Cache
, BootIniPath
);
1986 if (!NT_SUCCESS(Status
))
1988 IniCacheDestroy(Cache
);
1992 FileAttribute
|= (FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
| FILE_ATTRIBUTE_READONLY
);
1993 Status
= ProtectBootIni(BootIniPath
, FileAttribute
);
1995 IniCacheDestroy(Cache
);
2002 CheckInstallFatBootcodeToPartition(
2003 PUNICODE_STRING SystemRootPath
)
2006 if (DoesFileExist(SystemRootPath
->Buffer
, L
"ntldr") ||
2007 DoesFileExist(SystemRootPath
->Buffer
, L
"boot.ini"))
2011 else if (DoesFileExist(SystemRootPath
->Buffer
, L
"io.sys") ||
2012 DoesFileExist(SystemRootPath
->Buffer
, L
"msdos.sys"))
2023 InstallFatBootcodeToPartition(
2024 PUNICODE_STRING SystemRootPath
,
2025 PUNICODE_STRING SourceRootPath
,
2026 PUNICODE_STRING DestinationArcPath
,
2027 UCHAR PartitionType
)
2030 WCHAR SrcPath
[MAX_PATH
];
2031 WCHAR DstPath
[MAX_PATH
];
2034 /* FAT or FAT32 partition */
2035 DPRINT("System path: '%wZ'\n", SystemRootPath
);
2037 if (DoesFileExist(SystemRootPath
->Buffer
, L
"ntldr") == TRUE
||
2038 DoesFileExist(SystemRootPath
->Buffer
, L
"boot.ini") == TRUE
)
2040 /* Search root directory for 'ntldr' and 'boot.ini'. */
2041 DPRINT("Found Microsoft Windows NT/2000/XP boot loader\n");
2043 /* Copy FreeLoader to the boot partition */
2044 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2045 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
2046 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2047 wcscat(DstPath
, L
"\\freeldr.sys");
2049 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2050 Status
= SetupCopyFile(SrcPath
, DstPath
);
2051 if (!NT_SUCCESS(Status
))
2053 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
2057 /* Create or update freeldr.ini */
2058 if (DoesFileExist(SystemRootPath
->Buffer
, L
"freeldr.ini") == FALSE
)
2060 /* Create new 'freeldr.ini' */
2061 DPRINT1("Create new 'freeldr.ini'\n");
2062 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2063 wcscat(DstPath
, L
"\\freeldr.ini");
2065 Status
= CreateFreeLoaderIniForReactos(DstPath
,
2066 DestinationArcPath
->Buffer
);
2067 if (!NT_SUCCESS(Status
))
2069 DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status
);
2073 /* Install new bootcode */
2074 if (PartitionType
== PARTITION_FAT32
||
2075 PartitionType
== PARTITION_FAT32_XINT13
)
2077 /* Install FAT32 bootcode */
2078 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2079 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
2080 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2081 wcscat(DstPath
, L
"\\bootsect.ros");
2083 DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, DstPath
);
2084 Status
= InstallFat32BootCodeToFile(SrcPath
,
2086 SystemRootPath
->Buffer
);
2087 if (!NT_SUCCESS(Status
))
2089 DPRINT1("InstallFat32BootCodeToFile() failed (Status %lx)\n", Status
);
2095 /* Install FAT16 bootcode */
2096 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2097 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2098 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2099 wcscat(DstPath
, L
"\\bootsect.ros");
2101 DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath
, DstPath
);
2102 Status
= InstallFat16BootCodeToFile(SrcPath
,
2104 SystemRootPath
->Buffer
);
2105 if (!NT_SUCCESS(Status
))
2107 DPRINT1("InstallFat16BootCodeToFile() failed (Status %lx)\n", Status
);
2114 /* Update existing 'freeldr.ini' */
2115 DPRINT1("Update existing 'freeldr.ini'\n");
2116 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2117 wcscat(DstPath
, L
"\\freeldr.ini");
2119 Status
= UpdateFreeLoaderIni(DstPath
,
2120 DestinationArcPath
->Buffer
);
2121 if (!NT_SUCCESS(Status
))
2123 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
2128 /* Update 'boot.ini' */
2129 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2130 wcscat(DstPath
, L
"\\boot.ini");
2132 DPRINT1("Update 'boot.ini': %S\n", DstPath
);
2133 Status
= UpdateBootIni(DstPath
,
2134 L
"C:\\bootsect.ros",
2136 if (!NT_SUCCESS(Status
))
2138 DPRINT1("UpdateBootIni() failed (Status %lx)\n", Status
);
2142 else if (DoesFileExist(SystemRootPath
->Buffer
, L
"io.sys") == TRUE
||
2143 DoesFileExist(SystemRootPath
->Buffer
, L
"msdos.sys") == TRUE
)
2145 /* Search for root directory for 'io.sys' and 'msdos.sys'. */
2146 DPRINT1("Found Microsoft DOS or Windows 9x boot loader\n");
2148 /* Copy FreeLoader to the boot partition */
2149 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2150 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
2151 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2152 wcscat(DstPath
, L
"\\freeldr.sys");
2154 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2155 Status
= SetupCopyFile(SrcPath
, DstPath
);
2156 if (!NT_SUCCESS(Status
))
2158 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
2162 /* Create or update 'freeldr.ini' */
2163 if (DoesFileExist(SystemRootPath
->Buffer
, L
"freeldr.ini") == FALSE
)
2165 /* Create new 'freeldr.ini' */
2166 DPRINT1("Create new 'freeldr.ini'\n");
2167 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2168 wcscat(DstPath
, L
"\\freeldr.ini");
2170 Status
= CreateFreeLoaderIniForDos(DstPath
,
2171 DestinationArcPath
->Buffer
);
2172 if (!NT_SUCCESS(Status
))
2174 DPRINT1("CreateFreeLoaderIniForDos() failed (Status %lx)\n", Status
);
2178 /* Save current bootsector as 'BOOTSECT.DOS' */
2179 wcscpy(SrcPath
, SystemRootPath
->Buffer
);
2180 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2181 wcscat(DstPath
, L
"\\bootsect.dos");
2183 DPRINT1("Save bootsector: %S ==> %S\n", SrcPath
, DstPath
);
2184 Status
= SaveCurrentBootSector(SrcPath
,
2186 if (!NT_SUCCESS(Status
))
2188 DPRINT1("SaveCurrentBootSector() failed (Status %lx)\n", Status
);
2192 /* Install new bootsector */
2193 if (PartitionType
== PARTITION_FAT32
||
2194 PartitionType
== PARTITION_FAT32_XINT13
)
2196 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2197 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
2199 DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2200 Status
= InstallFat32BootCodeToDisk(SrcPath
,
2201 SystemRootPath
->Buffer
);
2202 if (!NT_SUCCESS(Status
))
2204 DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)\n", Status
);
2210 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2211 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2213 DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2214 Status
= InstallFat16BootCodeToDisk(SrcPath
,
2215 SystemRootPath
->Buffer
);
2216 if (!NT_SUCCESS(Status
))
2218 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status
);
2225 /* Update existing 'freeldr.ini' */
2226 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2227 wcscat(DstPath
, L
"\\freeldr.ini");
2229 Status
= UpdateFreeLoaderIni(DstPath
, DestinationArcPath
->Buffer
);
2230 if (!NT_SUCCESS(Status
))
2232 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
2239 /* No or unknown boot loader */
2240 DPRINT1("No or unknown boot loader found\n");
2242 /* Copy FreeLoader to the boot partition */
2243 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2244 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
2245 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2246 wcscat(DstPath
, L
"\\freeldr.sys");
2248 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2249 Status
= SetupCopyFile(SrcPath
, DstPath
);
2250 if (!NT_SUCCESS(Status
))
2252 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
2256 /* Create or update 'freeldr.ini' */
2257 if (DoesFileExist(SystemRootPath
->Buffer
, L
"freeldr.ini") == FALSE
)
2259 /* Create new freeldr.ini */
2260 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2261 wcscat(DstPath
, L
"\\freeldr.ini");
2263 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2264 Status
= CreateFreeLoaderIniForReactos(DstPath
,
2265 DestinationArcPath
->Buffer
);
2266 if (!NT_SUCCESS(Status
))
2268 DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status
);
2272 /* Save current bootsector as 'BOOTSECT.OLD' */
2273 wcscpy(SrcPath
, SystemRootPath
->Buffer
);
2274 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2275 wcscat(DstPath
, L
"\\bootsect.old");
2277 DPRINT("Save bootsector: %S ==> %S\n", SrcPath
, DstPath
);
2278 Status
= SaveCurrentBootSector(SrcPath
,
2280 if (!NT_SUCCESS(Status
))
2282 DPRINT1("SaveCurrentBootSector() failed (Status %lx)\n", Status
);
2286 /* Install new bootsector */
2287 if ((PartitionType
== PARTITION_FAT32
) ||
2288 (PartitionType
== PARTITION_FAT32_XINT13
))
2290 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2291 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
2293 DPRINT("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2294 Status
= InstallFat32BootCodeToDisk(SrcPath
,
2295 SystemRootPath
->Buffer
);
2296 if (!NT_SUCCESS(Status
))
2298 DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)\n", Status
);
2304 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2305 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2307 DPRINT("Install FAT bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2308 Status
= InstallFat16BootCodeToDisk(SrcPath
,
2309 SystemRootPath
->Buffer
);
2310 if (!NT_SUCCESS(Status
))
2312 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status
);
2319 /* Update existing 'freeldr.ini' */
2320 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2321 wcscat(DstPath
, L
"\\freeldr.ini");
2323 Status
= UpdateFreeLoaderIni(DstPath
,
2324 DestinationArcPath
->Buffer
);
2325 if (!NT_SUCCESS(Status
))
2327 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
2333 return STATUS_SUCCESS
;
2335 return STATUS_NOT_IMPLEMENTED
;
2341 InstallVBRToPartition(
2342 PUNICODE_STRING SystemRootPath
,
2343 PUNICODE_STRING SourceRootPath
,
2344 PUNICODE_STRING DestinationArcPath
,
2345 UCHAR PartitionType
)
2347 if ((PartitionType
== PARTITION_FAT_12
) ||
2348 (PartitionType
== PARTITION_FAT_16
) ||
2349 (PartitionType
== PARTITION_HUGE
) ||
2350 (PartitionType
== PARTITION_XINT13
) ||
2351 (PartitionType
== PARTITION_FAT32
) ||
2352 (PartitionType
== PARTITION_FAT32_XINT13
))
2354 return InstallFatBootcodeToPartition(SystemRootPath
,
2360 return STATUS_UNSUCCESSFUL
;
2365 InstallFatBootcodeToFloppy(
2366 PUNICODE_STRING SourceRootPath
,
2367 PUNICODE_STRING DestinationArcPath
)
2370 UNICODE_STRING FloppyDevice
= RTL_CONSTANT_STRING(L
"\\Device\\Floppy0");
2371 WCHAR SrcPath
[MAX_PATH
];
2372 WCHAR DstPath
[MAX_PATH
];
2375 /* Format the floppy first */
2376 Status
= VfatFormat(&FloppyDevice
,
2382 if (!NT_SUCCESS(Status
))
2384 DPRINT1("VfatFormat() failed (Status %lx)\n", Status
);
2388 /* Copy FreeLoader to the boot partition */
2389 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2390 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
2392 wcscpy(DstPath
, L
"\\Device\\Floppy0\\freeldr.sys");
2394 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2395 Status
= SetupCopyFile(SrcPath
, DstPath
);
2396 if (!NT_SUCCESS(Status
))
2398 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
2402 /* Create new 'freeldr.ini' */
2403 wcscpy(DstPath
, L
"\\Device\\Floppy0\\freeldr.ini");
2405 DPRINT("Create new 'freeldr.ini'\n");
2406 Status
= CreateFreeLoaderIniForReactos(DstPath
, DestinationArcPath
->Buffer
);
2407 if (!NT_SUCCESS(Status
))
2409 DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status
);
2413 /* Install FAT12/16 boosector */
2414 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2415 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2417 wcscpy(DstPath
, L
"\\Device\\Floppy0");
2419 DPRINT("Install FAT bootcode: %S ==> %S\n", SrcPath
, DstPath
);
2420 Status
= InstallFat12BootCodeToFloppy(SrcPath
, DstPath
);
2421 if (!NT_SUCCESS(Status
))
2423 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status
);
2427 return STATUS_SUCCESS
;
2429 return STATUS_NOT_IMPLEMENTED
;