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(PINICACHE IniCache
)
92 PINICACHESECTION IniSection
;
94 /* Create "FREELOADER" section */
95 IniSection
= IniCacheAppendSection(IniCache
,
99 if (IsUnattendedSetup
)
101 /* DefaultOS=ReactOS */
102 IniCacheInsertKey(IniSection
,
107 L
"ReactOS_KdSerial");
115 /* DefaultOS=ReactOS */
116 IniCacheInsertKey(IniSection
,
124 if (IsUnattendedSetup
)
127 /* Timeout=0 for unattended or non debug*/
128 IniCacheInsertKey(IniSection
,
137 /* Timeout=0 or 10 */
138 IniCacheInsertKey(IniSection
,
146 /* Create "Display" section */
147 IniSection
= IniCacheAppendSection(IniCache
, L
"Display");
149 /* TitleText=ReactOS Boot Manager */
150 IniCacheInsertKey(IniSection
,
154 L
"ReactOS Boot Manager");
156 /* StatusBarColor=Cyan */
157 IniCacheInsertKey(IniSection
,
163 /* StatusBarTextColor=Black */
164 IniCacheInsertKey(IniSection
,
167 L
"StatusBarTextColor",
170 /* BackdropTextColor=White */
171 IniCacheInsertKey(IniSection
,
174 L
"BackdropTextColor",
177 /* BackdropColor=Blue */
178 IniCacheInsertKey(IniSection
,
184 /* BackdropFillStyle=Medium */
185 IniCacheInsertKey(IniSection
,
188 L
"BackdropFillStyle",
191 /* TitleBoxTextColor=White */
192 IniCacheInsertKey(IniSection
,
195 L
"TitleBoxTextColor",
198 /* TitleBoxColor=Red */
199 IniCacheInsertKey(IniSection
,
205 /* MessageBoxTextColor=White */
206 IniCacheInsertKey(IniSection
,
209 L
"MessageBoxTextColor",
212 /* MessageBoxColor=Blue */
213 IniCacheInsertKey(IniSection
,
219 /* MenuTextColor=White */
220 IniCacheInsertKey(IniSection
,
227 IniCacheInsertKey(IniSection
,
233 /* TextColor=Yellow */
234 IniCacheInsertKey(IniSection
,
240 /* SelectedTextColor=Black */
241 IniCacheInsertKey(IniSection
,
244 L
"SelectedTextColor",
247 /* SelectedColor=Gray */
248 IniCacheInsertKey(IniSection
,
254 /* SelectedColor=Gray */
255 IniCacheInsertKey(IniSection
,
261 /* SelectedColor=Gray */
262 IniCacheInsertKey(IniSection
,
268 /* SelectedColor=Gray */
269 IniCacheInsertKey(IniSection
,
275 /* SelectedColor=Gray */
276 IniCacheInsertKey(IniSection
,
282 /* SelectedColor=Gray */
283 IniCacheInsertKey(IniSection
,
287 L
"Seconds until highlighted choice will be started automatically: ");
292 CreateFreeLoaderIniForDos(
297 PINICACHESECTION IniSection
;
299 IniCache
= IniCacheCreate();
301 CreateCommonFreeLoaderSections(IniCache
);
303 /* Create "Operating Systems" section */
304 IniSection
= IniCacheAppendSection(IniCache
, L
"Operating Systems");
306 /* REACTOS=ReactOS */
307 IniCacheInsertKey(IniSection
,
313 /* ReactOS_Debug="ReactOS (Debug)" */
314 IniCacheInsertKey(IniSection
,
318 L
"\"ReactOS (Debug)\"");
320 /* DOS=Dos/Windows */
321 IniCacheInsertKey(IniSection
,
327 /* Create "ReactOS" section */
328 IniSection
= IniCacheAppendSection(IniCache
, L
"ReactOS");
330 /* BootType=ReactOS */
331 IniCacheInsertKey(IniSection
,
337 /* SystemPath=<ArcPath> */
338 IniCacheInsertKey(IniSection
,
344 /* Create "ReactOS_Debug" section */
345 IniSection
= IniCacheAppendSection(IniCache
, L
"ReactOS_Debug");
347 /* BootType=ReactOS */
348 IniCacheInsertKey(IniSection
,
354 /* SystemPath=<ArcPath> */
355 IniCacheInsertKey(IniSection
,
361 /* Options=/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS */
362 IniCacheInsertKey(IniSection
,
366 L
"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS");
368 /* Create "DOS" section */
369 IniSection
= IniCacheAppendSection(IniCache
,
372 /* BootType=BootSector */
373 IniCacheInsertKey(IniSection
,
380 IniCacheInsertKey(IniSection
,
386 /* BootPartition=1 */
387 IniCacheInsertKey(IniSection
,
393 /* BootSector=BOOTSECT.DOS */
394 IniCacheInsertKey(IniSection
,
400 IniCacheSave(IniCache
, IniPath
);
401 IniCacheDestroy(IniCache
);
403 return STATUS_SUCCESS
;
408 CreateFreeLoaderEntry(
410 PINICACHESECTION OSSection
,
417 PINICACHESECTION IniSection
;
419 /* Insert entry into "Operating Systems" section */
420 IniCacheInsertKey(OSSection
,
426 /* Create new section */
427 IniSection
= IniCacheAppendSection(IniCache
, Section
);
430 IniCacheInsertKey(IniSection
,
437 IniCacheInsertKey(IniSection
,
444 IniCacheInsertKey(IniSection
,
450 return STATUS_SUCCESS
;
454 CreateFreeLoaderIniForReactos(
459 PINICACHESECTION IniSection
;
461 IniCache
= IniCacheCreate();
463 CreateCommonFreeLoaderSections(IniCache
);
465 /* Create "Operating Systems" section */
466 IniSection
= IniCacheAppendSection(IniCache
, L
"Operating Systems");
469 CreateFreeLoaderEntry(IniCache
, IniSection
,
470 L
"ReactOS", L
"\"ReactOS\"",
471 L
"Windows2003", ArcPath
,
475 CreateFreeLoaderEntry(IniCache
, IniSection
,
476 L
"ReactOS_Debug", L
"\"ReactOS (Debug)\"",
477 L
"Windows2003", ArcPath
,
478 L
"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS");
482 /* ReactOS_KdSerial */
483 CreateFreeLoaderEntry(IniCache
, IniSection
,
484 L
"ReactOS_KdSerial", L
"\"ReactOS (RosDbg)\"",
485 L
"Windows2003", ArcPath
,
486 L
"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /KDSERIAL");
490 CreateFreeLoaderEntry(IniCache
, IniSection
,
491 L
"ReactOS_Screen", L
"\"ReactOS (Screen)\"",
492 L
"Windows2003", ArcPath
,
493 L
"/DEBUG /DEBUGPORT=SCREEN /SOS");
495 /* ReactOS_LogFile */
496 CreateFreeLoaderEntry(IniCache
, IniSection
,
497 L
"ReactOS_LogFile", L
"\"ReactOS (Log file)\"",
498 L
"Windows2003", ArcPath
,
499 L
"/DEBUG /DEBUGPORT=FILE /SOS");
502 CreateFreeLoaderEntry(IniCache
, IniSection
,
503 L
"ReactOS_Ram", L
"\"ReactOS (RAM Disk)\"",
504 L
"ReactOS", L
"ramdisk(0)\\ReactOS",
505 L
"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /RDIMAGEPATH=reactos.img /RDIMAGEOFFSET=32256");
508 /* Save the ini file */
509 IniCacheSave(IniCache
, IniPath
);
510 IniCacheDestroy(IniCache
);
512 return STATUS_SUCCESS
;
523 PINICACHESECTION IniSection
;
524 PINICACHESECTION OsIniSection
;
525 WCHAR SectionName
[80];
527 WCHAR SystemPath
[200];
528 WCHAR SectionName2
[200];
533 RtlInitUnicodeString(&Name
, IniPath
);
535 Status
= IniCacheLoad(&IniCache
, &Name
, FALSE
);
536 if (!NT_SUCCESS(Status
))
539 /* Get "Operating Systems" section */
540 IniSection
= IniCacheGetSection(IniCache
, L
"Operating Systems");
541 if (IniSection
== NULL
)
543 IniCacheDestroy(IniCache
);
544 return STATUS_UNSUCCESSFUL
;
547 /* Find an existing usable or an unused section name */
549 wcscpy(SectionName
, L
"ReactOS");
550 wcscpy(OsName
, L
"\"ReactOS\"");
553 Status
= IniCacheGetKey(IniSection
, SectionName
, &KeyData
);
554 if (!NT_SUCCESS(Status
))
557 /* Get operation system section */
558 if (KeyData
[0] == '"')
560 wcscpy(SectionName2
, &KeyData
[1]);
561 j
= wcslen(SectionName2
);
564 SectionName2
[j
-1] = 0;
569 wcscpy(SectionName2
, KeyData
);
572 OsIniSection
= IniCacheGetSection(IniCache
, SectionName2
);
573 if (OsIniSection
!= NULL
)
575 BOOLEAN UseExistingEntry
= TRUE
;
578 Status
= IniCacheGetKey(OsIniSection
, L
"BootType", &KeyData
);
579 if (NT_SUCCESS(Status
))
581 if ((KeyData
== NULL
) ||
582 ( (_wcsicmp(KeyData
, L
"ReactOS") != 0) &&
583 (_wcsicmp(KeyData
, L
"\"ReactOS\"") != 0) ))
585 /* This is not a ReactOS entry */
586 UseExistingEntry
= FALSE
;
591 UseExistingEntry
= FALSE
;
594 if (UseExistingEntry
)
596 /* BootType is ReactOS. Now check SystemPath */
597 Status
= IniCacheGetKey(OsIniSection
, L
"SystemPath", &KeyData
);
598 if (NT_SUCCESS(Status
))
600 swprintf(SystemPath
, L
"\"%S\"", ArcPath
);
601 if ((KeyData
== NULL
) ||
602 ((_wcsicmp(KeyData
, ArcPath
) != 0) &&
603 (_wcsicmp(KeyData
, SystemPath
) != 0) ))
605 /* This entry is a ReactOS entry, but the SystemRoot does not
606 match the one we are looking for */
607 UseExistingEntry
= FALSE
;
612 UseExistingEntry
= FALSE
;
616 if (UseExistingEntry
)
618 IniCacheDestroy(IniCache
);
619 return STATUS_SUCCESS
;
623 swprintf(SectionName
, L
"ReactOS_%lu", i
);
624 swprintf(OsName
, L
"\"ReactOS %lu\"", i
);
628 /* <SectionName>=<OsName> */
629 IniCacheInsertKey(IniSection
,
635 /* Create <SectionName> section */
636 IniSection
= IniCacheAppendSection(IniCache
, SectionName
);
638 /* BootType=ReactOS */
639 IniCacheInsertKey(IniSection
,
645 /* SystemPath=<ArcPath> */
646 IniCacheInsertKey(IniSection
,
652 IniCacheSave(IniCache
, IniPath
);
653 IniCacheDestroy(IniCache
);
655 return STATUS_SUCCESS
;
660 SaveCurrentBootSector(
664 OBJECT_ATTRIBUTES ObjectAttributes
;
665 IO_STATUS_BLOCK IoStatusBlock
;
671 /* Allocate buffer for bootsector */
672 BootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
673 if (BootSector
== NULL
)
674 return STATUS_INSUFFICIENT_RESOURCES
;
676 /* Read current boot sector into buffer */
677 RtlInitUnicodeString(&Name
, RootPath
);
679 InitializeObjectAttributes(&ObjectAttributes
,
681 OBJ_CASE_INSENSITIVE
,
685 Status
= NtOpenFile(&FileHandle
,
690 FILE_SYNCHRONOUS_IO_NONALERT
);
691 if (!NT_SUCCESS(Status
))
693 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
697 Status
= NtReadFile(FileHandle
,
707 if (!NT_SUCCESS(Status
))
709 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
713 /* Write bootsector to DstPath */
714 RtlInitUnicodeString(&Name
, DstPath
);
716 InitializeObjectAttributes(&ObjectAttributes
,
722 Status
= NtCreateFile(&FileHandle
,
727 FILE_ATTRIBUTE_NORMAL
,
730 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
,
733 if (!NT_SUCCESS(Status
))
735 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
739 Status
= NtWriteFile(FileHandle
,
750 /* Free the new boot sector */
751 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
758 InstallFat16BootCodeToFile(
763 OBJECT_ATTRIBUTES ObjectAttributes
;
764 IO_STATUS_BLOCK IoStatusBlock
;
768 PFAT_BOOTSECTOR OrigBootSector
;
769 PFAT_BOOTSECTOR NewBootSector
;
771 /* Allocate buffer for original bootsector */
772 OrigBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
773 if (OrigBootSector
== NULL
)
774 return STATUS_INSUFFICIENT_RESOURCES
;
776 /* Read current boot sector into buffer */
777 RtlInitUnicodeString(&Name
, RootPath
);
779 InitializeObjectAttributes(&ObjectAttributes
,
781 OBJ_CASE_INSENSITIVE
,
785 Status
= NtOpenFile(&FileHandle
,
790 FILE_SYNCHRONOUS_IO_NONALERT
);
791 if (!NT_SUCCESS(Status
))
793 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
797 Status
= NtReadFile(FileHandle
,
807 if (!NT_SUCCESS(Status
))
809 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
813 /* Allocate buffer for new bootsector */
814 NewBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
815 if (NewBootSector
== NULL
)
817 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
818 return STATUS_INSUFFICIENT_RESOURCES
;
821 /* Read new bootsector from SrcPath */
822 RtlInitUnicodeString(&Name
, SrcPath
);
824 InitializeObjectAttributes(&ObjectAttributes
,
826 OBJ_CASE_INSENSITIVE
,
830 Status
= NtOpenFile(&FileHandle
,
835 FILE_SYNCHRONOUS_IO_NONALERT
);
836 if (!NT_SUCCESS(Status
))
838 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
839 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
843 Status
= NtReadFile(FileHandle
,
853 if (!NT_SUCCESS(Status
))
855 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
856 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
860 /* Adjust bootsector (copy a part of the FAT BPB) */
861 memcpy(&NewBootSector
->OemName
,
862 &OrigBootSector
->OemName
,
863 FIELD_OFFSET(FAT_BOOTSECTOR
, BootCodeAndData
) -
864 FIELD_OFFSET(FAT_BOOTSECTOR
, OemName
));
866 /* Free the original boot sector */
867 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
869 /* Write new bootsector to DstPath */
870 RtlInitUnicodeString(&Name
, DstPath
);
872 InitializeObjectAttributes(&ObjectAttributes
,
878 Status
= NtCreateFile(&FileHandle
,
883 FILE_ATTRIBUTE_NORMAL
,
886 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
,
889 if (!NT_SUCCESS(Status
))
891 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
896 FilePosition
.QuadPart
= 0;
898 Status
= NtWriteFile(FileHandle
,
909 /* Free the new boot sector */
910 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
917 InstallFat32BootCodeToFile(
922 OBJECT_ATTRIBUTES ObjectAttributes
;
923 IO_STATUS_BLOCK IoStatusBlock
;
927 PFAT32_BOOTSECTOR OrigBootSector
;
928 PFAT32_BOOTSECTOR NewBootSector
;
929 LARGE_INTEGER FileOffset
;
931 /* Allocate buffer for original bootsector */
932 OrigBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
933 if (OrigBootSector
== NULL
)
934 return STATUS_INSUFFICIENT_RESOURCES
;
936 /* Read current boot sector into buffer */
937 RtlInitUnicodeString(&Name
, RootPath
);
939 InitializeObjectAttributes(&ObjectAttributes
,
941 OBJ_CASE_INSENSITIVE
,
945 Status
= NtOpenFile(&FileHandle
,
950 FILE_SYNCHRONOUS_IO_NONALERT
);
951 if (!NT_SUCCESS(Status
))
953 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
957 Status
= NtReadFile(FileHandle
,
967 if (!NT_SUCCESS(Status
))
969 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
973 /* Allocate buffer for new bootsector (2 sectors) */
974 NewBootSector
= RtlAllocateHeap(ProcessHeap
, 0, 2 * SECTORSIZE
);
975 if (NewBootSector
== NULL
)
977 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
978 return STATUS_INSUFFICIENT_RESOURCES
;
981 /* Read new bootsector from SrcPath */
982 RtlInitUnicodeString(&Name
, SrcPath
);
984 InitializeObjectAttributes(&ObjectAttributes
,
986 OBJ_CASE_INSENSITIVE
,
990 Status
= NtOpenFile(&FileHandle
,
995 FILE_SYNCHRONOUS_IO_NONALERT
);
996 if (!NT_SUCCESS(Status
))
998 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
999 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1003 Status
= NtReadFile(FileHandle
,
1012 NtClose(FileHandle
);
1013 if (!NT_SUCCESS(Status
))
1015 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1016 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1020 /* Adjust bootsector (copy a part of the FAT32 BPB) */
1021 memcpy(&NewBootSector
->OemName
,
1022 &OrigBootSector
->OemName
,
1023 FIELD_OFFSET(FAT32_BOOTSECTOR
, BootCodeAndData
) -
1024 FIELD_OFFSET(FAT32_BOOTSECTOR
, OemName
));
1026 /* Disable the backup boot sector */
1027 NewBootSector
->BackupBootSector
= 0;
1029 /* Free the original boot sector */
1030 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1032 /* Write the first sector of the new bootcode to DstPath */
1033 RtlInitUnicodeString(&Name
, DstPath
);
1035 InitializeObjectAttributes(&ObjectAttributes
,
1041 Status
= NtCreateFile(&FileHandle
,
1046 FILE_ATTRIBUTE_NORMAL
,
1049 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
,
1052 if (!NT_SUCCESS(Status
))
1054 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1058 Status
= NtWriteFile(FileHandle
,
1067 NtClose(FileHandle
);
1068 if (!NT_SUCCESS(Status
))
1070 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1074 /* Write the second sector of the new bootcode to boot disk sector 14 */
1075 RtlInitUnicodeString(&Name
, RootPath
);
1077 InitializeObjectAttributes(&ObjectAttributes
,
1083 Status
= NtOpenFile(&FileHandle
,
1088 FILE_SYNCHRONOUS_IO_NONALERT
);
1089 if (!NT_SUCCESS(Status
))
1091 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1095 FileOffset
.QuadPart
= (ULONGLONG
)(14 * SECTORSIZE
);
1096 Status
= NtWriteFile(FileHandle
,
1101 ((PUCHAR
)NewBootSector
+ SECTORSIZE
),
1105 if (!NT_SUCCESS(Status
))
1108 NtClose(FileHandle
);
1110 /* Free the new boot sector */
1111 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1118 InstallMbrBootCodeToDisk(
1122 OBJECT_ATTRIBUTES ObjectAttributes
;
1123 IO_STATUS_BLOCK IoStatusBlock
;
1124 UNICODE_STRING Name
;
1127 PPARTITION_SECTOR OrigBootSector
;
1128 PPARTITION_SECTOR NewBootSector
;
1130 /* Allocate buffer for original bootsector */
1131 OrigBootSector
= (PPARTITION_SECTOR
)RtlAllocateHeap(ProcessHeap
,
1133 sizeof(PARTITION_SECTOR
));
1134 if (OrigBootSector
== NULL
)
1135 return STATUS_INSUFFICIENT_RESOURCES
;
1137 /* Read current boot sector into buffer */
1138 RtlInitUnicodeString(&Name
,
1141 InitializeObjectAttributes(&ObjectAttributes
,
1143 OBJ_CASE_INSENSITIVE
,
1147 Status
= NtOpenFile(&FileHandle
,
1152 FILE_SYNCHRONOUS_IO_NONALERT
);
1153 if (!NT_SUCCESS(Status
))
1155 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1159 Status
= NtReadFile(FileHandle
,
1168 NtClose(FileHandle
);
1169 if (!NT_SUCCESS(Status
))
1171 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1176 /* Allocate buffer for new bootsector */
1177 NewBootSector
= (PPARTITION_SECTOR
)RtlAllocateHeap(ProcessHeap
,
1179 sizeof(PARTITION_SECTOR
));
1180 if (NewBootSector
== NULL
)
1182 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1183 return STATUS_INSUFFICIENT_RESOURCES
;
1186 /* Read new bootsector from SrcPath */
1187 RtlInitUnicodeString(&Name
, SrcPath
);
1189 InitializeObjectAttributes(&ObjectAttributes
,
1191 OBJ_CASE_INSENSITIVE
,
1195 Status
= NtOpenFile(&FileHandle
,
1200 FILE_SYNCHRONOUS_IO_NONALERT
);
1201 if (!NT_SUCCESS(Status
))
1203 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1204 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1208 Status
= NtReadFile(FileHandle
,
1214 sizeof(PARTITION_SECTOR
),
1217 NtClose(FileHandle
);
1218 if (!NT_SUCCESS(Status
))
1220 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1221 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1225 /* Copy partition table from old MBR to new */
1226 RtlCopyMemory (&NewBootSector
->Signature
,
1227 &OrigBootSector
->Signature
,
1228 sizeof(PARTITION_SECTOR
) - offsetof(PARTITION_SECTOR
, Signature
) /* Length of partition table */);
1230 /* Free the original boot sector */
1231 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1233 /* Write new bootsector to RootPath */
1234 RtlInitUnicodeString(&Name
, RootPath
);
1236 InitializeObjectAttributes(&ObjectAttributes
,
1242 Status
= NtOpenFile(&FileHandle
,
1247 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1248 if (!NT_SUCCESS(Status
))
1250 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1251 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1255 Status
= NtWriteFile(FileHandle
,
1264 NtClose(FileHandle
);
1266 /* Free the new boot sector */
1267 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1273 InstallFat12BootCodeToFloppy(PWSTR SrcPath
,
1276 OBJECT_ATTRIBUTES ObjectAttributes
;
1277 IO_STATUS_BLOCK IoStatusBlock
;
1278 UNICODE_STRING Name
;
1281 PFAT_BOOTSECTOR OrigBootSector
;
1282 PFAT_BOOTSECTOR NewBootSector
;
1284 /* Allocate buffer for original bootsector */
1285 OrigBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
1286 if (OrigBootSector
== NULL
)
1287 return STATUS_INSUFFICIENT_RESOURCES
;
1289 /* Read current boot sector into buffer */
1290 RtlInitUnicodeString(&Name
, RootPath
);
1292 InitializeObjectAttributes(&ObjectAttributes
,
1294 OBJ_CASE_INSENSITIVE
,
1298 Status
= NtOpenFile(&FileHandle
,
1303 FILE_SYNCHRONOUS_IO_NONALERT
);
1304 if (!NT_SUCCESS(Status
))
1306 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1310 Status
= NtReadFile(FileHandle
,
1319 NtClose(FileHandle
);
1320 if (!NT_SUCCESS(Status
))
1322 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1327 /* Allocate buffer for new bootsector */
1328 NewBootSector
= RtlAllocateHeap(ProcessHeap
,
1331 if (NewBootSector
== NULL
)
1333 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1334 return STATUS_INSUFFICIENT_RESOURCES
;
1337 /* Read new bootsector from SrcPath */
1338 RtlInitUnicodeString(&Name
, SrcPath
);
1340 InitializeObjectAttributes(&ObjectAttributes
,
1342 OBJ_CASE_INSENSITIVE
,
1346 Status
= NtOpenFile(&FileHandle
,
1351 FILE_SYNCHRONOUS_IO_NONALERT
);
1352 if (!NT_SUCCESS(Status
))
1354 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1355 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1359 Status
= NtReadFile(FileHandle
,
1368 NtClose(FileHandle
);
1369 if (!NT_SUCCESS(Status
))
1371 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1372 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1376 /* Adjust bootsector (copy a part of the FAT16 BPB) */
1377 memcpy(&NewBootSector
->OemName
,
1378 &OrigBootSector
->OemName
,
1379 FIELD_OFFSET(FAT_BOOTSECTOR
, BootCodeAndData
) -
1380 FIELD_OFFSET(FAT_BOOTSECTOR
, OemName
));
1382 /* Free the original boot sector */
1383 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1385 /* Write new bootsector to RootPath */
1386 RtlInitUnicodeString(&Name
, RootPath
);
1388 InitializeObjectAttributes(&ObjectAttributes
,
1394 Status
= NtOpenFile(&FileHandle
,
1399 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1400 if (!NT_SUCCESS(Status
))
1402 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1403 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1408 FilePosition
.QuadPart
= 0;
1410 Status
= NtWriteFile(FileHandle
,
1419 NtClose(FileHandle
);
1421 /* Free the new boot sector */
1422 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1429 InstallFat16BootCodeToDisk(
1433 OBJECT_ATTRIBUTES ObjectAttributes
;
1434 IO_STATUS_BLOCK IoStatusBlock
;
1435 UNICODE_STRING Name
;
1438 PFAT_BOOTSECTOR OrigBootSector
;
1439 PFAT_BOOTSECTOR NewBootSector
;
1440 PARTITION_INFORMATION
*PartInfo
;
1442 /* Allocate buffer for original bootsector */
1443 OrigBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
1444 if (OrigBootSector
== NULL
)
1445 return STATUS_INSUFFICIENT_RESOURCES
;
1447 /* Read current boot sector into buffer */
1448 RtlInitUnicodeString(&Name
, RootPath
);
1450 InitializeObjectAttributes(&ObjectAttributes
,
1452 OBJ_CASE_INSENSITIVE
,
1456 Status
= NtOpenFile(&FileHandle
,
1461 FILE_SYNCHRONOUS_IO_NONALERT
);
1462 if (!NT_SUCCESS(Status
))
1464 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1468 Status
= NtReadFile(FileHandle
,
1477 NtClose(FileHandle
);
1478 if (!NT_SUCCESS(Status
))
1480 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1485 /* Allocate buffer for new bootsector */
1486 NewBootSector
= RtlAllocateHeap(ProcessHeap
,
1489 if (NewBootSector
== NULL
)
1491 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1492 return STATUS_INSUFFICIENT_RESOURCES
;
1495 /* Read new bootsector from SrcPath */
1496 RtlInitUnicodeString(&Name
, SrcPath
);
1498 InitializeObjectAttributes(&ObjectAttributes
,
1500 OBJ_CASE_INSENSITIVE
,
1504 Status
= NtOpenFile(&FileHandle
,
1509 FILE_SYNCHRONOUS_IO_NONALERT
);
1510 if (!NT_SUCCESS(Status
))
1512 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1513 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1517 Status
= NtReadFile(FileHandle
,
1526 NtClose(FileHandle
);
1527 if (!NT_SUCCESS(Status
))
1529 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1530 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1534 /* Adjust bootsector (copy a part of the FAT16 BPB) */
1535 memcpy(&NewBootSector
->OemName
,
1536 &OrigBootSector
->OemName
,
1537 FIELD_OFFSET(FAT_BOOTSECTOR
, BootCodeAndData
) -
1538 FIELD_OFFSET(FAT_BOOTSECTOR
, OemName
));
1540 PartInfo
= &PartitionList
->CurrentPartition
->PartInfo
[PartitionList
->CurrentPartitionNumber
];
1541 NewBootSector
->HiddenSectors
= PartInfo
->HiddenSectors
;
1543 /* Free the original boot sector */
1544 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1546 /* Write new bootsector to RootPath */
1547 RtlInitUnicodeString(&Name
, RootPath
);
1549 InitializeObjectAttributes(&ObjectAttributes
,
1555 Status
= NtOpenFile(&FileHandle
,
1560 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1561 if (!NT_SUCCESS(Status
))
1563 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1564 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1569 FilePosition
.QuadPart
= 0;
1571 Status
= NtWriteFile(FileHandle
,
1580 NtClose(FileHandle
);
1582 /* Free the new boot sector */
1583 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1590 InstallFat32BootCodeToDisk(
1594 OBJECT_ATTRIBUTES ObjectAttributes
;
1595 IO_STATUS_BLOCK IoStatusBlock
;
1596 UNICODE_STRING Name
;
1599 PFAT32_BOOTSECTOR OrigBootSector
;
1600 PFAT32_BOOTSECTOR NewBootSector
;
1601 LARGE_INTEGER FileOffset
;
1602 USHORT BackupBootSector
;
1603 PARTITION_INFORMATION
*PartInfo
;
1605 /* Allocate buffer for original bootsector */
1606 OrigBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
1607 if (OrigBootSector
== NULL
)
1608 return STATUS_INSUFFICIENT_RESOURCES
;
1610 /* Read current boot sector into buffer */
1611 RtlInitUnicodeString(&Name
, RootPath
);
1613 InitializeObjectAttributes(&ObjectAttributes
,
1615 OBJ_CASE_INSENSITIVE
,
1619 Status
= NtOpenFile(&FileHandle
,
1624 FILE_SYNCHRONOUS_IO_NONALERT
);
1625 if (!NT_SUCCESS(Status
))
1627 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1631 Status
= NtReadFile(FileHandle
,
1640 NtClose(FileHandle
);
1641 if (!NT_SUCCESS(Status
))
1643 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1648 /* Allocate buffer for new bootsector (2 sectors) */
1649 NewBootSector
= RtlAllocateHeap(ProcessHeap
, 0, 2 * SECTORSIZE
);
1650 if (NewBootSector
== NULL
)
1652 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1653 return STATUS_INSUFFICIENT_RESOURCES
;
1656 /* Read new bootsector from SrcPath */
1657 RtlInitUnicodeString(&Name
, SrcPath
);
1659 InitializeObjectAttributes(&ObjectAttributes
,
1661 OBJ_CASE_INSENSITIVE
,
1665 Status
= NtOpenFile(&FileHandle
,
1670 FILE_SYNCHRONOUS_IO_NONALERT
);
1671 if (!NT_SUCCESS(Status
))
1673 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1674 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1678 Status
= NtReadFile(FileHandle
,
1687 NtClose(FileHandle
);
1688 if (!NT_SUCCESS(Status
))
1690 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1691 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1695 /* Adjust bootsector (copy a part of the FAT32 BPB) */
1696 memcpy(&NewBootSector
->OemName
,
1697 &OrigBootSector
->OemName
,
1698 FIELD_OFFSET(FAT32_BOOTSECTOR
, BootCodeAndData
) -
1699 FIELD_OFFSET(FAT32_BOOTSECTOR
, OemName
));
1701 PartInfo
= &PartitionList
->CurrentPartition
->PartInfo
[PartitionList
->CurrentPartitionNumber
];
1702 NewBootSector
->HiddenSectors
= PartInfo
->HiddenSectors
;
1704 /* Get the location of the backup boot sector */
1705 BackupBootSector
= OrigBootSector
->BackupBootSector
;
1707 /* Free the original boot sector */
1708 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1710 /* Write the first sector of the new bootcode to DstPath */
1711 RtlInitUnicodeString(&Name
, RootPath
);
1713 InitializeObjectAttributes(&ObjectAttributes
,
1719 Status
= NtOpenFile(&FileHandle
,
1724 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1725 if (!NT_SUCCESS(Status
))
1727 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1728 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1732 /* Write sector 0 */
1733 FileOffset
.QuadPart
= 0ULL;
1734 Status
= NtWriteFile(FileHandle
,
1743 if (!NT_SUCCESS(Status
))
1745 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1746 NtClose(FileHandle
);
1747 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1751 /* Write backup boot sector */
1752 if ((BackupBootSector
!= 0x0000) && (BackupBootSector
!= 0xFFFF))
1754 FileOffset
.QuadPart
= (ULONGLONG
)((ULONG
)BackupBootSector
* SECTORSIZE
);
1755 Status
= NtWriteFile(FileHandle
,
1764 if (!NT_SUCCESS(Status
))
1766 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1767 NtClose(FileHandle
);
1768 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1773 /* Write sector 14 */
1774 FileOffset
.QuadPart
= 14 * SECTORSIZE
;
1775 Status
= NtWriteFile(FileHandle
,
1780 ((PUCHAR
)NewBootSector
+ SECTORSIZE
),
1784 if (!NT_SUCCESS(Status
))
1786 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1788 NtClose(FileHandle
);
1790 /* Free the new boot sector */
1791 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1803 UNICODE_STRING Name
;
1804 OBJECT_ATTRIBUTES ObjectAttributes
;
1805 IO_STATUS_BLOCK IoStatusBlock
;
1806 FILE_BASIC_INFORMATION FileInfo
;
1810 RtlInitUnicodeString(&Name
, FileName
);
1812 InitializeObjectAttributes(&ObjectAttributes
,
1814 OBJ_CASE_INSENSITIVE
,
1818 Status
= NtOpenFile(&FileHandle
,
1819 GENERIC_READ
|GENERIC_WRITE
,
1823 FILE_SYNCHRONOUS_IO_NONALERT
);
1824 if (Status
== STATUS_NO_SUCH_FILE
)
1826 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1828 return STATUS_SUCCESS
;
1830 if (!NT_SUCCESS(Status
))
1832 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1836 Status
= NtQueryInformationFile(FileHandle
,
1839 sizeof(FILE_BASIC_INFORMATION
),
1840 FileBasicInformation
);
1841 if (!NT_SUCCESS(Status
))
1843 DPRINT1("NtQueryInformationFile() failed (Status %lx)\n", Status
);
1844 NtClose(FileHandle
);
1848 *Attributes
= FileInfo
.FileAttributes
;
1850 /* Delete attributes SYSTEM, HIDDEN and READONLY */
1851 FileInfo
.FileAttributes
= FileInfo
.FileAttributes
&
1852 ~(FILE_ATTRIBUTE_SYSTEM
|
1853 FILE_ATTRIBUTE_HIDDEN
|
1854 FILE_ATTRIBUTE_READONLY
);
1856 Status
= NtSetInformationFile(FileHandle
,
1859 sizeof(FILE_BASIC_INFORMATION
),
1860 FileBasicInformation
);
1861 if (!NT_SUCCESS(Status
))
1863 DPRINT1("NtSetInformationFile() failed (Status %lx)\n", Status
);
1866 NtClose(FileHandle
);
1877 UNICODE_STRING Name
;
1878 OBJECT_ATTRIBUTES ObjectAttributes
;
1879 IO_STATUS_BLOCK IoStatusBlock
;
1880 FILE_BASIC_INFORMATION FileInfo
;
1884 RtlInitUnicodeString(&Name
, FileName
);
1886 InitializeObjectAttributes(&ObjectAttributes
,
1888 OBJ_CASE_INSENSITIVE
,
1892 Status
= NtOpenFile(&FileHandle
,
1893 GENERIC_READ
|GENERIC_WRITE
,
1897 FILE_SYNCHRONOUS_IO_NONALERT
);
1898 if (!NT_SUCCESS(Status
))
1900 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1904 Status
= NtQueryInformationFile(FileHandle
,
1907 sizeof(FILE_BASIC_INFORMATION
),
1908 FileBasicInformation
);
1909 if (!NT_SUCCESS(Status
))
1911 DPRINT1("NtQueryInformationFile() failed (Status %lx)\n", Status
);
1912 NtClose(FileHandle
);
1916 FileInfo
.FileAttributes
= FileInfo
.FileAttributes
| Attributes
;
1918 Status
= NtSetInformationFile(FileHandle
,
1921 sizeof(FILE_BASIC_INFORMATION
),
1922 FileBasicInformation
);
1923 if (!NT_SUCCESS(Status
))
1925 DPRINT1("NtSetInformationFile() failed (Status %lx)\n", Status
);
1928 NtClose(FileHandle
);
1939 UNICODE_STRING Name
;
1940 PINICACHE Cache
= NULL
;
1941 PINICACHESECTION Section
= NULL
;
1943 ULONG FileAttribute
;
1944 PWCHAR OldValue
= NULL
;
1946 RtlInitUnicodeString(&Name
, BootIniPath
);
1948 Status
= IniCacheLoad(&Cache
, &Name
, FALSE
);
1949 if (!NT_SUCCESS(Status
))
1954 Section
= IniCacheGetSection(Cache
,
1955 L
"operating systems");
1956 if (Section
== NULL
)
1958 IniCacheDestroy(Cache
);
1959 return STATUS_UNSUCCESSFUL
;
1962 /* Check - maybe record already exists */
1963 Status
= IniCacheGetKey(Section
, EntryName
, &OldValue
);
1965 /* If either key was not found, or contains something else - add new one */
1966 if (!NT_SUCCESS(Status
) || wcscmp(OldValue
, EntryValue
))
1968 IniCacheInsertKey(Section
,
1975 Status
= UnprotectBootIni(BootIniPath
,
1977 if (!NT_SUCCESS(Status
))
1979 IniCacheDestroy(Cache
);
1983 Status
= IniCacheSave(Cache
, BootIniPath
);
1984 if (!NT_SUCCESS(Status
))
1986 IniCacheDestroy(Cache
);
1990 FileAttribute
|= (FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
| FILE_ATTRIBUTE_READONLY
);
1991 Status
= ProtectBootIni(BootIniPath
, FileAttribute
);
1993 IniCacheDestroy(Cache
);
1999 CheckInstallFatBootcodeToPartition(
2000 PUNICODE_STRING SystemRootPath
)
2003 if (DoesFileExist(SystemRootPath
->Buffer
, L
"ntldr") ||
2004 DoesFileExist(SystemRootPath
->Buffer
, L
"boot.ini"))
2008 else if (DoesFileExist(SystemRootPath
->Buffer
, L
"io.sys") ||
2009 DoesFileExist(SystemRootPath
->Buffer
, L
"msdos.sys"))
2020 InstallFatBootcodeToPartition(
2021 PUNICODE_STRING SystemRootPath
,
2022 PUNICODE_STRING SourceRootPath
,
2023 PUNICODE_STRING DestinationArcPath
,
2024 UCHAR PartitionType
)
2027 WCHAR SrcPath
[MAX_PATH
];
2028 WCHAR DstPath
[MAX_PATH
];
2031 /* FAT or FAT32 partition */
2032 DPRINT("System path: '%wZ'\n", SystemRootPath
);
2034 if (DoesFileExist(SystemRootPath
->Buffer
, L
"ntldr") == TRUE
||
2035 DoesFileExist(SystemRootPath
->Buffer
, L
"boot.ini") == TRUE
)
2037 /* Search root directory for 'ntldr' and 'boot.ini'. */
2038 DPRINT("Found Microsoft Windows NT/2000/XP boot loader\n");
2040 /* Copy FreeLoader to the boot partition */
2041 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2042 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
2043 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2044 wcscat(DstPath
, L
"\\freeldr.sys");
2046 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2047 Status
= SetupCopyFile(SrcPath
, DstPath
);
2048 if (!NT_SUCCESS(Status
))
2050 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
2054 /* Create or update freeldr.ini */
2055 if (DoesFileExist(SystemRootPath
->Buffer
, L
"freeldr.ini") == FALSE
)
2057 /* Create new 'freeldr.ini' */
2058 DPRINT1("Create new 'freeldr.ini'\n");
2059 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2060 wcscat(DstPath
, L
"\\freeldr.ini");
2062 Status
= CreateFreeLoaderIniForReactos(DstPath
,
2063 DestinationArcPath
->Buffer
);
2064 if (!NT_SUCCESS(Status
))
2066 DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status
);
2070 /* Install new bootcode */
2071 if (PartitionType
== PARTITION_FAT32
||
2072 PartitionType
== PARTITION_FAT32_XINT13
)
2074 /* Install FAT32 bootcode */
2075 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2076 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
2077 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2078 wcscat(DstPath
, L
"\\bootsect.ros");
2080 DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, DstPath
);
2081 Status
= InstallFat32BootCodeToFile(SrcPath
,
2083 SystemRootPath
->Buffer
);
2084 if (!NT_SUCCESS(Status
))
2086 DPRINT1("InstallFat32BootCodeToFile() failed (Status %lx)\n", Status
);
2092 /* Install FAT16 bootcode */
2093 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2094 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2095 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2096 wcscat(DstPath
, L
"\\bootsect.ros");
2098 DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath
, DstPath
);
2099 Status
= InstallFat16BootCodeToFile(SrcPath
,
2101 SystemRootPath
->Buffer
);
2102 if (!NT_SUCCESS(Status
))
2104 DPRINT1("InstallFat16BootCodeToFile() failed (Status %lx)\n", Status
);
2111 /* Update existing 'freeldr.ini' */
2112 DPRINT1("Update existing 'freeldr.ini'\n");
2113 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2114 wcscat(DstPath
, L
"\\freeldr.ini");
2116 Status
= UpdateFreeLoaderIni(DstPath
,
2117 DestinationArcPath
->Buffer
);
2118 if (!NT_SUCCESS(Status
))
2120 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
2125 /* Update 'boot.ini' */
2126 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2127 wcscat(DstPath
, L
"\\boot.ini");
2129 DPRINT1("Update 'boot.ini': %S\n", DstPath
);
2130 Status
= UpdateBootIni(DstPath
,
2131 L
"C:\\bootsect.ros",
2133 if (!NT_SUCCESS(Status
))
2135 DPRINT1("UpdateBootIni() failed (Status %lx)\n", Status
);
2139 else if (DoesFileExist(SystemRootPath
->Buffer
, L
"io.sys") == TRUE
||
2140 DoesFileExist(SystemRootPath
->Buffer
, L
"msdos.sys") == TRUE
)
2142 /* Search for root directory for 'io.sys' and 'msdos.sys'. */
2143 DPRINT1("Found Microsoft DOS or Windows 9x boot loader\n");
2145 /* Copy FreeLoader to the boot partition */
2146 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2147 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
2148 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2149 wcscat(DstPath
, L
"\\freeldr.sys");
2151 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2152 Status
= SetupCopyFile(SrcPath
, DstPath
);
2153 if (!NT_SUCCESS(Status
))
2155 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
2159 /* Create or update 'freeldr.ini' */
2160 if (DoesFileExist(SystemRootPath
->Buffer
, L
"freeldr.ini") == FALSE
)
2162 /* Create new 'freeldr.ini' */
2163 DPRINT1("Create new 'freeldr.ini'\n");
2164 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2165 wcscat(DstPath
, L
"\\freeldr.ini");
2167 Status
= CreateFreeLoaderIniForDos(DstPath
,
2168 DestinationArcPath
->Buffer
);
2169 if (!NT_SUCCESS(Status
))
2171 DPRINT1("CreateFreeLoaderIniForDos() failed (Status %lx)\n", Status
);
2175 /* Save current bootsector as 'BOOTSECT.DOS' */
2176 wcscpy(SrcPath
, SystemRootPath
->Buffer
);
2177 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2178 wcscat(DstPath
, L
"\\bootsect.dos");
2180 DPRINT1("Save bootsector: %S ==> %S\n", SrcPath
, DstPath
);
2181 Status
= SaveCurrentBootSector(SrcPath
,
2183 if (!NT_SUCCESS(Status
))
2185 DPRINT1("SaveCurrentBootSector() failed (Status %lx)\n", Status
);
2189 /* Install new bootsector */
2190 if (PartitionType
== PARTITION_FAT32
||
2191 PartitionType
== PARTITION_FAT32_XINT13
)
2193 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2194 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
2196 DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2197 Status
= InstallFat32BootCodeToDisk(SrcPath
,
2198 SystemRootPath
->Buffer
);
2199 if (!NT_SUCCESS(Status
))
2201 DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)\n", Status
);
2207 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2208 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2210 DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2211 Status
= InstallFat16BootCodeToDisk(SrcPath
,
2212 SystemRootPath
->Buffer
);
2213 if (!NT_SUCCESS(Status
))
2215 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status
);
2222 /* Update existing 'freeldr.ini' */
2223 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2224 wcscat(DstPath
, L
"\\freeldr.ini");
2226 Status
= UpdateFreeLoaderIni(DstPath
, DestinationArcPath
->Buffer
);
2227 if (!NT_SUCCESS(Status
))
2229 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
2236 /* No or unknown boot loader */
2237 DPRINT1("No or unknown boot loader found\n");
2239 /* Copy FreeLoader to the boot partition */
2240 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2241 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
2242 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2243 wcscat(DstPath
, L
"\\freeldr.sys");
2245 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2246 Status
= SetupCopyFile(SrcPath
, DstPath
);
2247 if (!NT_SUCCESS(Status
))
2249 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
2253 /* Create or update 'freeldr.ini' */
2254 if (DoesFileExist(SystemRootPath
->Buffer
, L
"freeldr.ini") == FALSE
)
2256 /* Create new freeldr.ini */
2257 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2258 wcscat(DstPath
, L
"\\freeldr.ini");
2260 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2261 Status
= CreateFreeLoaderIniForReactos(DstPath
,
2262 DestinationArcPath
->Buffer
);
2263 if (!NT_SUCCESS(Status
))
2265 DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status
);
2269 /* Save current bootsector as 'BOOTSECT.OLD' */
2270 wcscpy(SrcPath
, SystemRootPath
->Buffer
);
2271 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2272 wcscat(DstPath
, L
"\\bootsect.old");
2274 DPRINT("Save bootsector: %S ==> %S\n", SrcPath
, DstPath
);
2275 Status
= SaveCurrentBootSector(SrcPath
,
2277 if (!NT_SUCCESS(Status
))
2279 DPRINT1("SaveCurrentBootSector() failed (Status %lx)\n", Status
);
2283 /* Install new bootsector */
2284 if ((PartitionType
== PARTITION_FAT32
) ||
2285 (PartitionType
== PARTITION_FAT32_XINT13
))
2287 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2288 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
2290 DPRINT("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2291 Status
= InstallFat32BootCodeToDisk(SrcPath
,
2292 SystemRootPath
->Buffer
);
2293 if (!NT_SUCCESS(Status
))
2295 DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)\n", Status
);
2301 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2302 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2304 DPRINT("Install FAT bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2305 Status
= InstallFat16BootCodeToDisk(SrcPath
,
2306 SystemRootPath
->Buffer
);
2307 if (!NT_SUCCESS(Status
))
2309 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status
);
2316 /* Update existing 'freeldr.ini' */
2317 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2318 wcscat(DstPath
, L
"\\freeldr.ini");
2320 Status
= UpdateFreeLoaderIni(DstPath
,
2321 DestinationArcPath
->Buffer
);
2322 if (!NT_SUCCESS(Status
))
2324 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
2330 return STATUS_SUCCESS
;
2332 return STATUS_NOT_IMPLEMENTED
;
2337 InstallVBRToPartition(
2338 PUNICODE_STRING SystemRootPath
,
2339 PUNICODE_STRING SourceRootPath
,
2340 PUNICODE_STRING DestinationArcPath
,
2341 UCHAR PartitionType
)
2343 if ((PartitionType
== PARTITION_FAT_12
) ||
2344 (PartitionType
== PARTITION_FAT_16
) ||
2345 (PartitionType
== PARTITION_HUGE
) ||
2346 (PartitionType
== PARTITION_XINT13
) ||
2347 (PartitionType
== PARTITION_FAT32
) ||
2348 (PartitionType
== PARTITION_FAT32_XINT13
))
2350 return InstallFatBootcodeToPartition(SystemRootPath
,
2356 return STATUS_UNSUCCESSFUL
;
2361 InstallFatBootcodeToFloppy(
2362 PUNICODE_STRING SourceRootPath
,
2363 PUNICODE_STRING DestinationArcPath
)
2366 UNICODE_STRING FloppyDevice
= RTL_CONSTANT_STRING(L
"\\Device\\Floppy0");
2367 WCHAR SrcPath
[MAX_PATH
];
2368 WCHAR DstPath
[MAX_PATH
];
2371 /* Format the floppy first */
2372 Status
= VfatFormat(&FloppyDevice
,
2378 if (!NT_SUCCESS(Status
))
2380 DPRINT1("VfatFormat() failed (Status %lx)\n", Status
);
2384 /* Copy FreeLoader to the boot partition */
2385 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2386 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
2388 wcscpy(DstPath
, L
"\\Device\\Floppy0\\freeldr.sys");
2390 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2391 Status
= SetupCopyFile(SrcPath
, DstPath
);
2392 if (!NT_SUCCESS(Status
))
2394 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
2398 /* Create new 'freeldr.ini' */
2399 wcscpy(DstPath
, L
"\\Device\\Floppy0\\freeldr.ini");
2401 DPRINT("Create new 'freeldr.ini'\n");
2402 Status
= CreateFreeLoaderIniForReactos(DstPath
, DestinationArcPath
->Buffer
);
2403 if (!NT_SUCCESS(Status
))
2405 DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status
);
2409 /* Install FAT12/16 boosector */
2410 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2411 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2413 wcscpy(DstPath
, L
"\\Device\\Floppy0");
2415 DPRINT("Install FAT bootcode: %S ==> %S\n", SrcPath
, DstPath
);
2416 Status
= InstallFat12BootCodeToFloppy(SrcPath
, DstPath
);
2417 if (!NT_SUCCESS(Status
))
2419 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status
);
2423 return STATUS_SUCCESS
;
2425 return STATUS_NOT_IMPLEMENTED
;