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
,
106 L
"ReactOS_KdSerial");
111 /* DefaultOS=ReactOS */
112 IniCacheInsertKey(IniSection
,
120 if (IsUnattendedSetup
)
123 /* Timeout=0 for unattended or non debug*/
124 IniCacheInsertKey(IniSection
,
133 /* Timeout=0 or 10 */
134 IniCacheInsertKey(IniSection
,
142 /* Create "Display" section */
143 IniSection
= IniCacheAppendSection(IniCache
, L
"Display");
145 /* TitleText=ReactOS Boot Manager */
146 IniCacheInsertKey(IniSection
,
150 L
"ReactOS Boot Manager");
152 /* StatusBarColor=Cyan */
153 IniCacheInsertKey(IniSection
,
159 /* StatusBarTextColor=Black */
160 IniCacheInsertKey(IniSection
,
163 L
"StatusBarTextColor",
166 /* BackdropTextColor=White */
167 IniCacheInsertKey(IniSection
,
170 L
"BackdropTextColor",
173 /* BackdropColor=Blue */
174 IniCacheInsertKey(IniSection
,
180 /* BackdropFillStyle=Medium */
181 IniCacheInsertKey(IniSection
,
184 L
"BackdropFillStyle",
187 /* TitleBoxTextColor=White */
188 IniCacheInsertKey(IniSection
,
191 L
"TitleBoxTextColor",
194 /* TitleBoxColor=Red */
195 IniCacheInsertKey(IniSection
,
201 /* MessageBoxTextColor=White */
202 IniCacheInsertKey(IniSection
,
205 L
"MessageBoxTextColor",
208 /* MessageBoxColor=Blue */
209 IniCacheInsertKey(IniSection
,
215 /* MenuTextColor=White */
216 IniCacheInsertKey(IniSection
,
223 IniCacheInsertKey(IniSection
,
229 /* TextColor=Yellow */
230 IniCacheInsertKey(IniSection
,
236 /* SelectedTextColor=Black */
237 IniCacheInsertKey(IniSection
,
240 L
"SelectedTextColor",
243 /* SelectedColor=Gray */
244 IniCacheInsertKey(IniSection
,
250 /* SelectedColor=Gray */
251 IniCacheInsertKey(IniSection
,
257 /* SelectedColor=Gray */
258 IniCacheInsertKey(IniSection
,
264 /* SelectedColor=Gray */
265 IniCacheInsertKey(IniSection
,
271 /* SelectedColor=Gray */
272 IniCacheInsertKey(IniSection
,
278 /* SelectedColor=Gray */
279 IniCacheInsertKey(IniSection
,
283 L
"Seconds until highlighted choice will be started automatically: ");
288 CreateFreeLoaderIniForDos(
293 PINICACHESECTION IniSection
;
295 IniCache
= IniCacheCreate();
297 CreateCommonFreeLoaderSections(IniCache
);
299 /* Create "Operating Systems" section */
300 IniSection
= IniCacheAppendSection(IniCache
, L
"Operating Systems");
302 /* REACTOS=ReactOS */
303 IniCacheInsertKey(IniSection
,
309 /* ReactOS_Debug="ReactOS (Debug)" */
310 IniCacheInsertKey(IniSection
,
314 L
"\"ReactOS (Debug)\"");
316 /* DOS=Dos/Windows */
317 IniCacheInsertKey(IniSection
,
323 /* Create "ReactOS" section */
324 IniSection
= IniCacheAppendSection(IniCache
, L
"ReactOS");
326 /* BootType=ReactOS */
327 IniCacheInsertKey(IniSection
,
333 /* SystemPath=<ArcPath> */
334 IniCacheInsertKey(IniSection
,
340 /* Create "ReactOS_Debug" section */
341 IniSection
= IniCacheAppendSection(IniCache
, L
"ReactOS_Debug");
343 /* BootType=ReactOS */
344 IniCacheInsertKey(IniSection
,
350 /* SystemPath=<ArcPath> */
351 IniCacheInsertKey(IniSection
,
357 /* Options=/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS */
358 IniCacheInsertKey(IniSection
,
362 L
"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS");
364 /* Create "DOS" section */
365 IniSection
= IniCacheAppendSection(IniCache
,
368 /* BootType=BootSector */
369 IniCacheInsertKey(IniSection
,
376 IniCacheInsertKey(IniSection
,
382 /* BootPartition=1 */
383 IniCacheInsertKey(IniSection
,
389 /* BootSector=BOOTSECT.DOS */
390 IniCacheInsertKey(IniSection
,
396 IniCacheSave(IniCache
, IniPath
);
397 IniCacheDestroy(IniCache
);
399 return STATUS_SUCCESS
;
404 CreateFreeLoaderEntry(
406 PINICACHESECTION OSSection
,
413 PINICACHESECTION IniSection
;
415 /* Insert entry into "Operating Systems" section */
416 IniCacheInsertKey(OSSection
,
422 /* Create new section */
423 IniSection
= IniCacheAppendSection(IniCache
, Section
);
426 IniCacheInsertKey(IniSection
,
433 IniCacheInsertKey(IniSection
,
440 IniCacheInsertKey(IniSection
,
446 return STATUS_SUCCESS
;
450 CreateFreeLoaderIniForReactos(
455 PINICACHESECTION IniSection
;
457 IniCache
= IniCacheCreate();
459 CreateCommonFreeLoaderSections(IniCache
);
461 /* Create "Operating Systems" section */
462 IniSection
= IniCacheAppendSection(IniCache
, L
"Operating Systems");
465 CreateFreeLoaderEntry(IniCache
, IniSection
,
466 L
"ReactOS", L
"\"ReactOS\"",
467 L
"Windows2003", ArcPath
,
471 CreateFreeLoaderEntry(IniCache
, IniSection
,
472 L
"ReactOS_Debug", L
"\"ReactOS (Debug)\"",
473 L
"Windows2003", ArcPath
,
474 L
"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS");
478 /* ReactOS_KdSerial */
479 CreateFreeLoaderEntry(IniCache
, IniSection
,
480 L
"ReactOS_KdSerial", L
"\"ReactOS (RosDbg)\"",
481 L
"Windows2003", ArcPath
,
482 L
"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /KDSERIAL");
485 /* ReactOS_LogFile */
486 CreateFreeLoaderEntry(IniCache
, IniSection
,
487 L
"ReactOS_LogFile", L
"\"ReactOS (Log file)\"",
488 L
"Windows2003", ArcPath
,
489 L
"/DEBUG /DEBUGPORT=FILE /SOS");
492 CreateFreeLoaderEntry(IniCache
, IniSection
,
493 L
"ReactOS_Ram", L
"\"ReactOS (RAM Disk)\"",
494 L
"ReactOS", L
"ramdisk(0)\\ReactOS",
495 L
"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /RDIMAGEPATH=reactos.img /RDIMAGEOFFSET=32256");
498 /* Save the ini file */
499 IniCacheSave(IniCache
, IniPath
);
500 IniCacheDestroy(IniCache
);
502 return STATUS_SUCCESS
;
513 PINICACHESECTION IniSection
;
514 PINICACHESECTION OsIniSection
;
515 WCHAR SectionName
[80];
517 WCHAR SystemPath
[200];
518 WCHAR SectionName2
[200];
523 RtlInitUnicodeString(&Name
, IniPath
);
525 Status
= IniCacheLoad(&IniCache
, &Name
, FALSE
);
526 if (!NT_SUCCESS(Status
))
529 /* Get "Operating Systems" section */
530 IniSection
= IniCacheGetSection(IniCache
, L
"Operating Systems");
531 if (IniSection
== NULL
)
533 IniCacheDestroy(IniCache
);
534 return STATUS_UNSUCCESSFUL
;
537 /* Find an existing usable or an unused section name */
539 wcscpy(SectionName
, L
"ReactOS");
540 wcscpy(OsName
, L
"\"ReactOS\"");
543 Status
= IniCacheGetKey(IniSection
, SectionName
, &KeyData
);
544 if (!NT_SUCCESS(Status
))
547 /* Get operation system section */
548 if (KeyData
[0] == '"')
550 wcscpy(SectionName2
, &KeyData
[1]);
551 j
= wcslen(SectionName2
);
554 SectionName2
[j
-1] = 0;
559 wcscpy(SectionName2
, KeyData
);
562 OsIniSection
= IniCacheGetSection(IniCache
, SectionName2
);
563 if (OsIniSection
!= NULL
)
565 BOOLEAN UseExistingEntry
= TRUE
;
568 Status
= IniCacheGetKey(OsIniSection
, L
"BootType", &KeyData
);
569 if (NT_SUCCESS(Status
))
571 if ((KeyData
== NULL
) ||
572 ( (_wcsicmp(KeyData
, L
"ReactOS") != 0) &&
573 (_wcsicmp(KeyData
, L
"\"ReactOS\"") != 0) ))
575 /* This is not a ReactOS entry */
576 UseExistingEntry
= FALSE
;
581 UseExistingEntry
= FALSE
;
584 if (UseExistingEntry
)
586 /* BootType is ReactOS. Now check SystemPath */
587 Status
= IniCacheGetKey(OsIniSection
, L
"SystemPath", &KeyData
);
588 if (NT_SUCCESS(Status
))
590 swprintf(SystemPath
, L
"\"%S\"", ArcPath
);
591 if ((KeyData
== NULL
) ||
592 ((_wcsicmp(KeyData
, ArcPath
) != 0) &&
593 (_wcsicmp(KeyData
, SystemPath
) != 0) ))
595 /* This entry is a ReactOS entry, but the SystemRoot does not
596 match the one we are looking for */
597 UseExistingEntry
= FALSE
;
602 UseExistingEntry
= FALSE
;
606 if (UseExistingEntry
)
608 IniCacheDestroy(IniCache
);
609 return STATUS_SUCCESS
;
613 swprintf(SectionName
, L
"ReactOS_%lu", i
);
614 swprintf(OsName
, L
"\"ReactOS %lu\"", i
);
618 /* <SectionName>=<OsName> */
619 IniCacheInsertKey(IniSection
,
625 /* Create <SectionName> section */
626 IniSection
= IniCacheAppendSection(IniCache
, SectionName
);
628 /* BootType=ReactOS */
629 IniCacheInsertKey(IniSection
,
635 /* SystemPath=<ArcPath> */
636 IniCacheInsertKey(IniSection
,
642 IniCacheSave(IniCache
, IniPath
);
643 IniCacheDestroy(IniCache
);
645 return STATUS_SUCCESS
;
650 SaveCurrentBootSector(
654 OBJECT_ATTRIBUTES ObjectAttributes
;
655 IO_STATUS_BLOCK IoStatusBlock
;
661 /* Allocate buffer for bootsector */
662 BootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
663 if (BootSector
== NULL
)
664 return STATUS_INSUFFICIENT_RESOURCES
;
666 /* Read current boot sector into buffer */
667 RtlInitUnicodeString(&Name
, RootPath
);
669 InitializeObjectAttributes(&ObjectAttributes
,
671 OBJ_CASE_INSENSITIVE
,
675 Status
= NtOpenFile(&FileHandle
,
680 FILE_SYNCHRONOUS_IO_NONALERT
);
681 if (!NT_SUCCESS(Status
))
683 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
687 Status
= NtReadFile(FileHandle
,
697 if (!NT_SUCCESS(Status
))
699 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
703 /* Write bootsector to DstPath */
704 RtlInitUnicodeString(&Name
, DstPath
);
706 InitializeObjectAttributes(&ObjectAttributes
,
712 Status
= NtCreateFile(&FileHandle
,
717 FILE_ATTRIBUTE_NORMAL
,
720 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
,
723 if (!NT_SUCCESS(Status
))
725 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
729 Status
= NtWriteFile(FileHandle
,
740 /* Free the new boot sector */
741 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
748 InstallFat16BootCodeToFile(
753 OBJECT_ATTRIBUTES ObjectAttributes
;
754 IO_STATUS_BLOCK IoStatusBlock
;
758 PFAT_BOOTSECTOR OrigBootSector
;
759 PFAT_BOOTSECTOR NewBootSector
;
761 /* Allocate buffer for original bootsector */
762 OrigBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
763 if (OrigBootSector
== NULL
)
764 return STATUS_INSUFFICIENT_RESOURCES
;
766 /* Read current boot sector into buffer */
767 RtlInitUnicodeString(&Name
, RootPath
);
769 InitializeObjectAttributes(&ObjectAttributes
,
771 OBJ_CASE_INSENSITIVE
,
775 Status
= NtOpenFile(&FileHandle
,
780 FILE_SYNCHRONOUS_IO_NONALERT
);
781 if (!NT_SUCCESS(Status
))
783 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
787 Status
= NtReadFile(FileHandle
,
797 if (!NT_SUCCESS(Status
))
799 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
803 /* Allocate buffer for new bootsector */
804 NewBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
805 if (NewBootSector
== NULL
)
807 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
808 return STATUS_INSUFFICIENT_RESOURCES
;
811 /* Read new bootsector from SrcPath */
812 RtlInitUnicodeString(&Name
, SrcPath
);
814 InitializeObjectAttributes(&ObjectAttributes
,
816 OBJ_CASE_INSENSITIVE
,
820 Status
= NtOpenFile(&FileHandle
,
825 FILE_SYNCHRONOUS_IO_NONALERT
);
826 if (!NT_SUCCESS(Status
))
828 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
829 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
833 Status
= NtReadFile(FileHandle
,
843 if (!NT_SUCCESS(Status
))
845 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
846 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
850 /* Adjust bootsector (copy a part of the FAT BPB) */
851 memcpy(&NewBootSector
->OemName
,
852 &OrigBootSector
->OemName
,
853 FIELD_OFFSET(FAT_BOOTSECTOR
, BootCodeAndData
) -
854 FIELD_OFFSET(FAT_BOOTSECTOR
, OemName
));
856 /* Free the original boot sector */
857 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
859 /* Write new bootsector to DstPath */
860 RtlInitUnicodeString(&Name
, DstPath
);
862 InitializeObjectAttributes(&ObjectAttributes
,
868 Status
= NtCreateFile(&FileHandle
,
873 FILE_ATTRIBUTE_NORMAL
,
876 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
,
879 if (!NT_SUCCESS(Status
))
881 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
886 FilePosition
.QuadPart
= 0;
888 Status
= NtWriteFile(FileHandle
,
899 /* Free the new boot sector */
900 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
907 InstallFat32BootCodeToFile(
912 OBJECT_ATTRIBUTES ObjectAttributes
;
913 IO_STATUS_BLOCK IoStatusBlock
;
917 PFAT32_BOOTSECTOR OrigBootSector
;
918 PFAT32_BOOTSECTOR NewBootSector
;
919 LARGE_INTEGER FileOffset
;
921 /* Allocate buffer for original bootsector */
922 OrigBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
923 if (OrigBootSector
== NULL
)
924 return STATUS_INSUFFICIENT_RESOURCES
;
926 /* Read current boot sector into buffer */
927 RtlInitUnicodeString(&Name
, RootPath
);
929 InitializeObjectAttributes(&ObjectAttributes
,
931 OBJ_CASE_INSENSITIVE
,
935 Status
= NtOpenFile(&FileHandle
,
940 FILE_SYNCHRONOUS_IO_NONALERT
);
941 if (!NT_SUCCESS(Status
))
943 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
947 Status
= NtReadFile(FileHandle
,
957 if (!NT_SUCCESS(Status
))
959 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
963 /* Allocate buffer for new bootsector (2 sectors) */
964 NewBootSector
= RtlAllocateHeap(ProcessHeap
, 0, 2 * SECTORSIZE
);
965 if (NewBootSector
== NULL
)
967 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
968 return STATUS_INSUFFICIENT_RESOURCES
;
971 /* Read new bootsector from SrcPath */
972 RtlInitUnicodeString(&Name
, SrcPath
);
974 InitializeObjectAttributes(&ObjectAttributes
,
976 OBJ_CASE_INSENSITIVE
,
980 Status
= NtOpenFile(&FileHandle
,
985 FILE_SYNCHRONOUS_IO_NONALERT
);
986 if (!NT_SUCCESS(Status
))
988 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
989 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
993 Status
= NtReadFile(FileHandle
,
1002 NtClose(FileHandle
);
1003 if (!NT_SUCCESS(Status
))
1005 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1006 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1010 /* Adjust bootsector (copy a part of the FAT32 BPB) */
1011 memcpy(&NewBootSector
->OemName
,
1012 &OrigBootSector
->OemName
,
1013 FIELD_OFFSET(FAT32_BOOTSECTOR
, BootCodeAndData
) -
1014 FIELD_OFFSET(FAT32_BOOTSECTOR
, OemName
));
1016 /* Disable the backup boot sector */
1017 NewBootSector
->BackupBootSector
= 0;
1019 /* Free the original boot sector */
1020 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1022 /* Write the first sector of the new bootcode to DstPath */
1023 RtlInitUnicodeString(&Name
, DstPath
);
1025 InitializeObjectAttributes(&ObjectAttributes
,
1031 Status
= NtCreateFile(&FileHandle
,
1036 FILE_ATTRIBUTE_NORMAL
,
1039 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
,
1042 if (!NT_SUCCESS(Status
))
1044 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1048 Status
= NtWriteFile(FileHandle
,
1057 NtClose(FileHandle
);
1058 if (!NT_SUCCESS(Status
))
1060 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1064 /* Write the second sector of the new bootcode to boot disk sector 14 */
1065 RtlInitUnicodeString(&Name
, RootPath
);
1067 InitializeObjectAttributes(&ObjectAttributes
,
1073 Status
= NtOpenFile(&FileHandle
,
1078 FILE_SYNCHRONOUS_IO_NONALERT
);
1079 if (!NT_SUCCESS(Status
))
1081 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1085 FileOffset
.QuadPart
= (ULONGLONG
)(14 * SECTORSIZE
);
1086 Status
= NtWriteFile(FileHandle
,
1091 ((PUCHAR
)NewBootSector
+ SECTORSIZE
),
1095 if (!NT_SUCCESS(Status
))
1098 NtClose(FileHandle
);
1100 /* Free the new boot sector */
1101 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1108 InstallMbrBootCodeToDisk(
1112 OBJECT_ATTRIBUTES ObjectAttributes
;
1113 IO_STATUS_BLOCK IoStatusBlock
;
1114 UNICODE_STRING Name
;
1117 PPARTITION_SECTOR OrigBootSector
;
1118 PPARTITION_SECTOR NewBootSector
;
1120 /* Allocate buffer for original bootsector */
1121 OrigBootSector
= (PPARTITION_SECTOR
)RtlAllocateHeap(ProcessHeap
,
1123 sizeof(PARTITION_SECTOR
));
1124 if (OrigBootSector
== NULL
)
1125 return STATUS_INSUFFICIENT_RESOURCES
;
1127 /* Read current boot sector into buffer */
1128 RtlInitUnicodeString(&Name
,
1131 InitializeObjectAttributes(&ObjectAttributes
,
1133 OBJ_CASE_INSENSITIVE
,
1137 Status
= NtOpenFile(&FileHandle
,
1142 FILE_SYNCHRONOUS_IO_NONALERT
);
1143 if (!NT_SUCCESS(Status
))
1145 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1149 Status
= NtReadFile(FileHandle
,
1158 NtClose(FileHandle
);
1159 if (!NT_SUCCESS(Status
))
1161 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1166 /* Allocate buffer for new bootsector */
1167 NewBootSector
= (PPARTITION_SECTOR
)RtlAllocateHeap(ProcessHeap
,
1169 sizeof(PARTITION_SECTOR
));
1170 if (NewBootSector
== NULL
)
1172 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1173 return STATUS_INSUFFICIENT_RESOURCES
;
1176 /* Read new bootsector from SrcPath */
1177 RtlInitUnicodeString(&Name
, SrcPath
);
1179 InitializeObjectAttributes(&ObjectAttributes
,
1181 OBJ_CASE_INSENSITIVE
,
1185 Status
= NtOpenFile(&FileHandle
,
1190 FILE_SYNCHRONOUS_IO_NONALERT
);
1191 if (!NT_SUCCESS(Status
))
1193 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1194 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1198 Status
= NtReadFile(FileHandle
,
1204 sizeof(PARTITION_SECTOR
),
1207 NtClose(FileHandle
);
1208 if (!NT_SUCCESS(Status
))
1210 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1211 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1215 /* Copy partition table from old MBR to new */
1216 RtlCopyMemory (&NewBootSector
->Signature
,
1217 &OrigBootSector
->Signature
,
1218 sizeof(PARTITION_SECTOR
) - offsetof(PARTITION_SECTOR
, Signature
) /* Length of partition table */);
1220 /* Free the original boot sector */
1221 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1223 /* Write new bootsector to RootPath */
1224 RtlInitUnicodeString(&Name
, RootPath
);
1226 InitializeObjectAttributes(&ObjectAttributes
,
1232 Status
= NtOpenFile(&FileHandle
,
1237 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1238 if (!NT_SUCCESS(Status
))
1240 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1241 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1245 Status
= NtWriteFile(FileHandle
,
1254 NtClose(FileHandle
);
1256 /* Free the new boot sector */
1257 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1263 InstallFat12BootCodeToFloppy(PWSTR SrcPath
,
1266 OBJECT_ATTRIBUTES ObjectAttributes
;
1267 IO_STATUS_BLOCK IoStatusBlock
;
1268 UNICODE_STRING Name
;
1271 PFAT_BOOTSECTOR OrigBootSector
;
1272 PFAT_BOOTSECTOR NewBootSector
;
1274 /* Allocate buffer for original bootsector */
1275 OrigBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
1276 if (OrigBootSector
== NULL
)
1277 return STATUS_INSUFFICIENT_RESOURCES
;
1279 /* Read current boot sector into buffer */
1280 RtlInitUnicodeString(&Name
, RootPath
);
1282 InitializeObjectAttributes(&ObjectAttributes
,
1284 OBJ_CASE_INSENSITIVE
,
1288 Status
= NtOpenFile(&FileHandle
,
1293 FILE_SYNCHRONOUS_IO_NONALERT
);
1294 if (!NT_SUCCESS(Status
))
1296 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1300 Status
= NtReadFile(FileHandle
,
1309 NtClose(FileHandle
);
1310 if (!NT_SUCCESS(Status
))
1312 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1317 /* Allocate buffer for new bootsector */
1318 NewBootSector
= RtlAllocateHeap(ProcessHeap
,
1321 if (NewBootSector
== NULL
)
1323 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1324 return STATUS_INSUFFICIENT_RESOURCES
;
1327 /* Read new bootsector from SrcPath */
1328 RtlInitUnicodeString(&Name
, SrcPath
);
1330 InitializeObjectAttributes(&ObjectAttributes
,
1332 OBJ_CASE_INSENSITIVE
,
1336 Status
= NtOpenFile(&FileHandle
,
1341 FILE_SYNCHRONOUS_IO_NONALERT
);
1342 if (!NT_SUCCESS(Status
))
1344 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1345 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1349 Status
= NtReadFile(FileHandle
,
1358 NtClose(FileHandle
);
1359 if (!NT_SUCCESS(Status
))
1361 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1362 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1366 /* Adjust bootsector (copy a part of the FAT16 BPB) */
1367 memcpy(&NewBootSector
->OemName
,
1368 &OrigBootSector
->OemName
,
1369 FIELD_OFFSET(FAT_BOOTSECTOR
, BootCodeAndData
) -
1370 FIELD_OFFSET(FAT_BOOTSECTOR
, OemName
));
1372 /* Free the original boot sector */
1373 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1375 /* Write new bootsector to RootPath */
1376 RtlInitUnicodeString(&Name
, RootPath
);
1378 InitializeObjectAttributes(&ObjectAttributes
,
1384 Status
= NtOpenFile(&FileHandle
,
1389 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1390 if (!NT_SUCCESS(Status
))
1392 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1393 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1398 FilePosition
.QuadPart
= 0;
1400 Status
= NtWriteFile(FileHandle
,
1409 NtClose(FileHandle
);
1411 /* Free the new boot sector */
1412 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1419 InstallFat16BootCodeToDisk(
1423 OBJECT_ATTRIBUTES ObjectAttributes
;
1424 IO_STATUS_BLOCK IoStatusBlock
;
1425 UNICODE_STRING Name
;
1428 PFAT_BOOTSECTOR OrigBootSector
;
1429 PFAT_BOOTSECTOR NewBootSector
;
1430 PARTITION_INFORMATION
*PartInfo
;
1432 /* Allocate buffer for original bootsector */
1433 OrigBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
1434 if (OrigBootSector
== NULL
)
1435 return STATUS_INSUFFICIENT_RESOURCES
;
1437 /* Read current boot sector into buffer */
1438 RtlInitUnicodeString(&Name
, RootPath
);
1440 InitializeObjectAttributes(&ObjectAttributes
,
1442 OBJ_CASE_INSENSITIVE
,
1446 Status
= NtOpenFile(&FileHandle
,
1451 FILE_SYNCHRONOUS_IO_NONALERT
);
1452 if (!NT_SUCCESS(Status
))
1454 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1458 Status
= NtReadFile(FileHandle
,
1467 NtClose(FileHandle
);
1468 if (!NT_SUCCESS(Status
))
1470 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1475 /* Allocate buffer for new bootsector */
1476 NewBootSector
= RtlAllocateHeap(ProcessHeap
,
1479 if (NewBootSector
== NULL
)
1481 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1482 return STATUS_INSUFFICIENT_RESOURCES
;
1485 /* Read new bootsector from SrcPath */
1486 RtlInitUnicodeString(&Name
, SrcPath
);
1488 InitializeObjectAttributes(&ObjectAttributes
,
1490 OBJ_CASE_INSENSITIVE
,
1494 Status
= NtOpenFile(&FileHandle
,
1499 FILE_SYNCHRONOUS_IO_NONALERT
);
1500 if (!NT_SUCCESS(Status
))
1502 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1503 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1507 Status
= NtReadFile(FileHandle
,
1516 NtClose(FileHandle
);
1517 if (!NT_SUCCESS(Status
))
1519 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1520 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1524 /* Adjust bootsector (copy a part of the FAT16 BPB) */
1525 memcpy(&NewBootSector
->OemName
,
1526 &OrigBootSector
->OemName
,
1527 FIELD_OFFSET(FAT_BOOTSECTOR
, BootCodeAndData
) -
1528 FIELD_OFFSET(FAT_BOOTSECTOR
, OemName
));
1530 PartInfo
= &PartitionList
->CurrentPartition
->PartInfo
[PartitionList
->CurrentPartitionNumber
];
1531 NewBootSector
->HiddenSectors
= PartInfo
->HiddenSectors
;
1533 /* Free the original boot sector */
1534 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1536 /* Write new bootsector to RootPath */
1537 RtlInitUnicodeString(&Name
, RootPath
);
1539 InitializeObjectAttributes(&ObjectAttributes
,
1545 Status
= NtOpenFile(&FileHandle
,
1550 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1551 if (!NT_SUCCESS(Status
))
1553 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1554 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1559 FilePosition
.QuadPart
= 0;
1561 Status
= NtWriteFile(FileHandle
,
1570 NtClose(FileHandle
);
1572 /* Free the new boot sector */
1573 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1580 InstallFat32BootCodeToDisk(
1584 OBJECT_ATTRIBUTES ObjectAttributes
;
1585 IO_STATUS_BLOCK IoStatusBlock
;
1586 UNICODE_STRING Name
;
1589 PFAT32_BOOTSECTOR OrigBootSector
;
1590 PFAT32_BOOTSECTOR NewBootSector
;
1591 LARGE_INTEGER FileOffset
;
1592 USHORT BackupBootSector
;
1593 PARTITION_INFORMATION
*PartInfo
;
1595 /* Allocate buffer for original bootsector */
1596 OrigBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
1597 if (OrigBootSector
== NULL
)
1598 return STATUS_INSUFFICIENT_RESOURCES
;
1600 /* Read current boot sector into buffer */
1601 RtlInitUnicodeString(&Name
, RootPath
);
1603 InitializeObjectAttributes(&ObjectAttributes
,
1605 OBJ_CASE_INSENSITIVE
,
1609 Status
= NtOpenFile(&FileHandle
,
1614 FILE_SYNCHRONOUS_IO_NONALERT
);
1615 if (!NT_SUCCESS(Status
))
1617 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1621 Status
= NtReadFile(FileHandle
,
1630 NtClose(FileHandle
);
1631 if (!NT_SUCCESS(Status
))
1633 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1638 /* Allocate buffer for new bootsector (2 sectors) */
1639 NewBootSector
= RtlAllocateHeap(ProcessHeap
, 0, 2 * SECTORSIZE
);
1640 if (NewBootSector
== NULL
)
1642 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1643 return STATUS_INSUFFICIENT_RESOURCES
;
1646 /* Read new bootsector from SrcPath */
1647 RtlInitUnicodeString(&Name
, SrcPath
);
1649 InitializeObjectAttributes(&ObjectAttributes
,
1651 OBJ_CASE_INSENSITIVE
,
1655 Status
= NtOpenFile(&FileHandle
,
1660 FILE_SYNCHRONOUS_IO_NONALERT
);
1661 if (!NT_SUCCESS(Status
))
1663 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1664 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1668 Status
= NtReadFile(FileHandle
,
1677 NtClose(FileHandle
);
1678 if (!NT_SUCCESS(Status
))
1680 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1681 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1685 /* Adjust bootsector (copy a part of the FAT32 BPB) */
1686 memcpy(&NewBootSector
->OemName
,
1687 &OrigBootSector
->OemName
,
1688 FIELD_OFFSET(FAT32_BOOTSECTOR
, BootCodeAndData
) -
1689 FIELD_OFFSET(FAT32_BOOTSECTOR
, OemName
));
1691 PartInfo
= &PartitionList
->CurrentPartition
->PartInfo
[PartitionList
->CurrentPartitionNumber
];
1692 NewBootSector
->HiddenSectors
= PartInfo
->HiddenSectors
;
1694 /* Get the location of the backup boot sector */
1695 BackupBootSector
= OrigBootSector
->BackupBootSector
;
1697 /* Free the original boot sector */
1698 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1700 /* Write the first sector of the new bootcode to DstPath */
1701 RtlInitUnicodeString(&Name
, RootPath
);
1703 InitializeObjectAttributes(&ObjectAttributes
,
1709 Status
= NtOpenFile(&FileHandle
,
1714 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1715 if (!NT_SUCCESS(Status
))
1717 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1718 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1722 /* Write sector 0 */
1723 FileOffset
.QuadPart
= 0ULL;
1724 Status
= NtWriteFile(FileHandle
,
1733 if (!NT_SUCCESS(Status
))
1735 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1736 NtClose(FileHandle
);
1737 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1741 /* Write backup boot sector */
1742 if ((BackupBootSector
!= 0x0000) && (BackupBootSector
!= 0xFFFF))
1744 FileOffset
.QuadPart
= (ULONGLONG
)((ULONG
)BackupBootSector
* SECTORSIZE
);
1745 Status
= NtWriteFile(FileHandle
,
1754 if (!NT_SUCCESS(Status
))
1756 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1757 NtClose(FileHandle
);
1758 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1763 /* Write sector 14 */
1764 FileOffset
.QuadPart
= 14 * SECTORSIZE
;
1765 Status
= NtWriteFile(FileHandle
,
1770 ((PUCHAR
)NewBootSector
+ SECTORSIZE
),
1774 if (!NT_SUCCESS(Status
))
1776 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1778 NtClose(FileHandle
);
1780 /* Free the new boot sector */
1781 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1793 UNICODE_STRING Name
;
1794 OBJECT_ATTRIBUTES ObjectAttributes
;
1795 IO_STATUS_BLOCK IoStatusBlock
;
1796 FILE_BASIC_INFORMATION FileInfo
;
1800 RtlInitUnicodeString(&Name
, FileName
);
1802 InitializeObjectAttributes(&ObjectAttributes
,
1804 OBJ_CASE_INSENSITIVE
,
1808 Status
= NtOpenFile(&FileHandle
,
1809 GENERIC_READ
|GENERIC_WRITE
,
1813 FILE_SYNCHRONOUS_IO_NONALERT
);
1814 if (Status
== STATUS_NO_SUCH_FILE
)
1816 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1818 return STATUS_SUCCESS
;
1820 if (!NT_SUCCESS(Status
))
1822 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1826 Status
= NtQueryInformationFile(FileHandle
,
1829 sizeof(FILE_BASIC_INFORMATION
),
1830 FileBasicInformation
);
1831 if (!NT_SUCCESS(Status
))
1833 DPRINT1("NtQueryInformationFile() failed (Status %lx)\n", Status
);
1834 NtClose(FileHandle
);
1838 *Attributes
= FileInfo
.FileAttributes
;
1840 /* Delete attributes SYSTEM, HIDDEN and READONLY */
1841 FileInfo
.FileAttributes
= FileInfo
.FileAttributes
&
1842 ~(FILE_ATTRIBUTE_SYSTEM
|
1843 FILE_ATTRIBUTE_HIDDEN
|
1844 FILE_ATTRIBUTE_READONLY
);
1846 Status
= NtSetInformationFile(FileHandle
,
1849 sizeof(FILE_BASIC_INFORMATION
),
1850 FileBasicInformation
);
1851 if (!NT_SUCCESS(Status
))
1853 DPRINT1("NtSetInformationFile() failed (Status %lx)\n", Status
);
1856 NtClose(FileHandle
);
1867 UNICODE_STRING Name
;
1868 OBJECT_ATTRIBUTES ObjectAttributes
;
1869 IO_STATUS_BLOCK IoStatusBlock
;
1870 FILE_BASIC_INFORMATION FileInfo
;
1874 RtlInitUnicodeString(&Name
, FileName
);
1876 InitializeObjectAttributes(&ObjectAttributes
,
1878 OBJ_CASE_INSENSITIVE
,
1882 Status
= NtOpenFile(&FileHandle
,
1883 GENERIC_READ
|GENERIC_WRITE
,
1887 FILE_SYNCHRONOUS_IO_NONALERT
);
1888 if (!NT_SUCCESS(Status
))
1890 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1894 Status
= NtQueryInformationFile(FileHandle
,
1897 sizeof(FILE_BASIC_INFORMATION
),
1898 FileBasicInformation
);
1899 if (!NT_SUCCESS(Status
))
1901 DPRINT1("NtQueryInformationFile() failed (Status %lx)\n", Status
);
1902 NtClose(FileHandle
);
1906 FileInfo
.FileAttributes
= FileInfo
.FileAttributes
| Attributes
;
1908 Status
= NtSetInformationFile(FileHandle
,
1911 sizeof(FILE_BASIC_INFORMATION
),
1912 FileBasicInformation
);
1913 if (!NT_SUCCESS(Status
))
1915 DPRINT1("NtSetInformationFile() failed (Status %lx)\n", Status
);
1918 NtClose(FileHandle
);
1929 UNICODE_STRING Name
;
1930 PINICACHE Cache
= NULL
;
1931 PINICACHESECTION Section
= NULL
;
1933 ULONG FileAttribute
;
1934 PWCHAR OldValue
= NULL
;
1936 RtlInitUnicodeString(&Name
, BootIniPath
);
1938 Status
= IniCacheLoad(&Cache
, &Name
, FALSE
);
1939 if (!NT_SUCCESS(Status
))
1944 Section
= IniCacheGetSection(Cache
,
1945 L
"operating systems");
1946 if (Section
== NULL
)
1948 IniCacheDestroy(Cache
);
1949 return STATUS_UNSUCCESSFUL
;
1952 /* Check - maybe record already exists */
1953 Status
= IniCacheGetKey(Section
, EntryName
, &OldValue
);
1955 /* If either key was not found, or contains something else - add new one */
1956 if (!NT_SUCCESS(Status
) || wcscmp(OldValue
, EntryValue
))
1958 IniCacheInsertKey(Section
,
1965 Status
= UnprotectBootIni(BootIniPath
,
1967 if (!NT_SUCCESS(Status
))
1969 IniCacheDestroy(Cache
);
1973 Status
= IniCacheSave(Cache
, BootIniPath
);
1974 if (!NT_SUCCESS(Status
))
1976 IniCacheDestroy(Cache
);
1980 FileAttribute
|= (FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
| FILE_ATTRIBUTE_READONLY
);
1981 Status
= ProtectBootIni(BootIniPath
, FileAttribute
);
1983 IniCacheDestroy(Cache
);
1989 CheckInstallFatBootcodeToPartition(
1990 PUNICODE_STRING SystemRootPath
)
1993 if (DoesFileExist(SystemRootPath
->Buffer
, L
"ntldr") ||
1994 DoesFileExist(SystemRootPath
->Buffer
, L
"boot.ini"))
1998 else if (DoesFileExist(SystemRootPath
->Buffer
, L
"io.sys") ||
1999 DoesFileExist(SystemRootPath
->Buffer
, L
"msdos.sys"))
2010 InstallFatBootcodeToPartition(
2011 PUNICODE_STRING SystemRootPath
,
2012 PUNICODE_STRING SourceRootPath
,
2013 PUNICODE_STRING DestinationArcPath
,
2014 UCHAR PartitionType
)
2017 WCHAR SrcPath
[MAX_PATH
];
2018 WCHAR DstPath
[MAX_PATH
];
2021 /* FAT or FAT32 partition */
2022 DPRINT("System path: '%wZ'\n", SystemRootPath
);
2024 if (DoesFileExist(SystemRootPath
->Buffer
, L
"ntldr") == TRUE
||
2025 DoesFileExist(SystemRootPath
->Buffer
, L
"boot.ini") == TRUE
)
2027 /* Search root directory for 'ntldr' and 'boot.ini'. */
2028 DPRINT("Found Microsoft Windows NT/2000/XP boot loader\n");
2030 /* Copy FreeLoader to the boot partition */
2031 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2032 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
2033 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2034 wcscat(DstPath
, L
"\\freeldr.sys");
2036 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2037 Status
= SetupCopyFile(SrcPath
, DstPath
);
2038 if (!NT_SUCCESS(Status
))
2040 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
2044 /* Create or update freeldr.ini */
2045 if (DoesFileExist(SystemRootPath
->Buffer
, L
"freeldr.ini") == FALSE
)
2047 /* Create new 'freeldr.ini' */
2048 DPRINT1("Create new 'freeldr.ini'\n");
2049 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2050 wcscat(DstPath
, L
"\\freeldr.ini");
2052 Status
= CreateFreeLoaderIniForReactos(DstPath
,
2053 DestinationArcPath
->Buffer
);
2054 if (!NT_SUCCESS(Status
))
2056 DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status
);
2060 /* Install new bootcode */
2061 if (PartitionType
== PARTITION_FAT32
||
2062 PartitionType
== PARTITION_FAT32_XINT13
)
2064 /* Install FAT32 bootcode */
2065 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2066 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
2067 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2068 wcscat(DstPath
, L
"\\bootsect.ros");
2070 DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, DstPath
);
2071 Status
= InstallFat32BootCodeToFile(SrcPath
,
2073 SystemRootPath
->Buffer
);
2074 if (!NT_SUCCESS(Status
))
2076 DPRINT1("InstallFat32BootCodeToFile() failed (Status %lx)\n", Status
);
2082 /* Install FAT16 bootcode */
2083 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2084 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2085 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2086 wcscat(DstPath
, L
"\\bootsect.ros");
2088 DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath
, DstPath
);
2089 Status
= InstallFat16BootCodeToFile(SrcPath
,
2091 SystemRootPath
->Buffer
);
2092 if (!NT_SUCCESS(Status
))
2094 DPRINT1("InstallFat16BootCodeToFile() failed (Status %lx)\n", Status
);
2101 /* Update existing 'freeldr.ini' */
2102 DPRINT1("Update existing 'freeldr.ini'\n");
2103 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2104 wcscat(DstPath
, L
"\\freeldr.ini");
2106 Status
= UpdateFreeLoaderIni(DstPath
,
2107 DestinationArcPath
->Buffer
);
2108 if (!NT_SUCCESS(Status
))
2110 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
2115 /* Update 'boot.ini' */
2116 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2117 wcscat(DstPath
, L
"\\boot.ini");
2119 DPRINT1("Update 'boot.ini': %S\n", DstPath
);
2120 Status
= UpdateBootIni(DstPath
,
2121 L
"C:\\bootsect.ros",
2123 if (!NT_SUCCESS(Status
))
2125 DPRINT1("UpdateBootIni() failed (Status %lx)\n", Status
);
2129 else if (DoesFileExist(SystemRootPath
->Buffer
, L
"io.sys") == TRUE
||
2130 DoesFileExist(SystemRootPath
->Buffer
, L
"msdos.sys") == TRUE
)
2132 /* Search for root directory for 'io.sys' and 'msdos.sys'. */
2133 DPRINT1("Found Microsoft DOS or Windows 9x boot loader\n");
2135 /* Copy FreeLoader to the boot partition */
2136 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2137 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
2138 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2139 wcscat(DstPath
, L
"\\freeldr.sys");
2141 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2142 Status
= SetupCopyFile(SrcPath
, DstPath
);
2143 if (!NT_SUCCESS(Status
))
2145 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
2149 /* Create or update 'freeldr.ini' */
2150 if (DoesFileExist(SystemRootPath
->Buffer
, L
"freeldr.ini") == FALSE
)
2152 /* Create new 'freeldr.ini' */
2153 DPRINT1("Create new 'freeldr.ini'\n");
2154 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2155 wcscat(DstPath
, L
"\\freeldr.ini");
2157 Status
= CreateFreeLoaderIniForDos(DstPath
,
2158 DestinationArcPath
->Buffer
);
2159 if (!NT_SUCCESS(Status
))
2161 DPRINT1("CreateFreeLoaderIniForDos() failed (Status %lx)\n", Status
);
2165 /* Save current bootsector as 'BOOTSECT.DOS' */
2166 wcscpy(SrcPath
, SystemRootPath
->Buffer
);
2167 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2168 wcscat(DstPath
, L
"\\bootsect.dos");
2170 DPRINT1("Save bootsector: %S ==> %S\n", SrcPath
, DstPath
);
2171 Status
= SaveCurrentBootSector(SrcPath
,
2173 if (!NT_SUCCESS(Status
))
2175 DPRINT1("SaveCurrentBootSector() failed (Status %lx)\n", Status
);
2179 /* Install new bootsector */
2180 if (PartitionType
== PARTITION_FAT32
||
2181 PartitionType
== PARTITION_FAT32_XINT13
)
2183 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2184 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
2186 DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2187 Status
= InstallFat32BootCodeToDisk(SrcPath
,
2188 SystemRootPath
->Buffer
);
2189 if (!NT_SUCCESS(Status
))
2191 DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)\n", Status
);
2197 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2198 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2200 DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2201 Status
= InstallFat16BootCodeToDisk(SrcPath
,
2202 SystemRootPath
->Buffer
);
2203 if (!NT_SUCCESS(Status
))
2205 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status
);
2212 /* Update existing 'freeldr.ini' */
2213 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2214 wcscat(DstPath
, L
"\\freeldr.ini");
2216 Status
= UpdateFreeLoaderIni(DstPath
, DestinationArcPath
->Buffer
);
2217 if (!NT_SUCCESS(Status
))
2219 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
2226 /* No or unknown boot loader */
2227 DPRINT1("No or unknown boot loader found\n");
2229 /* Copy FreeLoader to the boot partition */
2230 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2231 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
2232 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2233 wcscat(DstPath
, L
"\\freeldr.sys");
2235 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2236 Status
= SetupCopyFile(SrcPath
, DstPath
);
2237 if (!NT_SUCCESS(Status
))
2239 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
2243 /* Create or update 'freeldr.ini' */
2244 if (DoesFileExist(SystemRootPath
->Buffer
, L
"freeldr.ini") == FALSE
)
2246 /* Create new freeldr.ini */
2247 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2248 wcscat(DstPath
, L
"\\freeldr.ini");
2250 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2251 Status
= CreateFreeLoaderIniForReactos(DstPath
,
2252 DestinationArcPath
->Buffer
);
2253 if (!NT_SUCCESS(Status
))
2255 DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status
);
2259 /* Save current bootsector as 'BOOTSECT.OLD' */
2260 wcscpy(SrcPath
, SystemRootPath
->Buffer
);
2261 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2262 wcscat(DstPath
, L
"\\bootsect.old");
2264 DPRINT("Save bootsector: %S ==> %S\n", SrcPath
, DstPath
);
2265 Status
= SaveCurrentBootSector(SrcPath
,
2267 if (!NT_SUCCESS(Status
))
2269 DPRINT1("SaveCurrentBootSector() failed (Status %lx)\n", Status
);
2273 /* Install new bootsector */
2274 if ((PartitionType
== PARTITION_FAT32
) ||
2275 (PartitionType
== PARTITION_FAT32_XINT13
))
2277 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2278 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
2280 DPRINT("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2281 Status
= InstallFat32BootCodeToDisk(SrcPath
,
2282 SystemRootPath
->Buffer
);
2283 if (!NT_SUCCESS(Status
))
2285 DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)\n", Status
);
2291 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2292 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2294 DPRINT("Install FAT bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2295 Status
= InstallFat16BootCodeToDisk(SrcPath
,
2296 SystemRootPath
->Buffer
);
2297 if (!NT_SUCCESS(Status
))
2299 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status
);
2306 /* Update existing 'freeldr.ini' */
2307 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2308 wcscat(DstPath
, L
"\\freeldr.ini");
2310 Status
= UpdateFreeLoaderIni(DstPath
,
2311 DestinationArcPath
->Buffer
);
2312 if (!NT_SUCCESS(Status
))
2314 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
2320 return STATUS_SUCCESS
;
2322 return STATUS_NOT_IMPLEMENTED
;
2327 InstallVBRToPartition(
2328 PUNICODE_STRING SystemRootPath
,
2329 PUNICODE_STRING SourceRootPath
,
2330 PUNICODE_STRING DestinationArcPath
,
2331 UCHAR PartitionType
)
2333 if ((PartitionType
== PARTITION_FAT_12
) ||
2334 (PartitionType
== PARTITION_FAT_16
) ||
2335 (PartitionType
== PARTITION_HUGE
) ||
2336 (PartitionType
== PARTITION_XINT13
) ||
2337 (PartitionType
== PARTITION_FAT32
) ||
2338 (PartitionType
== PARTITION_FAT32_XINT13
))
2340 return InstallFatBootcodeToPartition(SystemRootPath
,
2346 return STATUS_UNSUCCESSFUL
;
2351 InstallFatBootcodeToFloppy(
2352 PUNICODE_STRING SourceRootPath
,
2353 PUNICODE_STRING DestinationArcPath
)
2356 UNICODE_STRING FloppyDevice
= RTL_CONSTANT_STRING(L
"\\Device\\Floppy0");
2357 WCHAR SrcPath
[MAX_PATH
];
2358 WCHAR DstPath
[MAX_PATH
];
2361 /* Format the floppy first */
2362 Status
= VfatFormat(&FloppyDevice
,
2368 if (!NT_SUCCESS(Status
))
2370 DPRINT1("VfatFormat() failed (Status %lx)\n", Status
);
2374 /* Copy FreeLoader to the boot partition */
2375 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2376 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
2378 wcscpy(DstPath
, L
"\\Device\\Floppy0\\freeldr.sys");
2380 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2381 Status
= SetupCopyFile(SrcPath
, DstPath
);
2382 if (!NT_SUCCESS(Status
))
2384 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
2388 /* Create new 'freeldr.ini' */
2389 wcscpy(DstPath
, L
"\\Device\\Floppy0\\freeldr.ini");
2391 DPRINT("Create new 'freeldr.ini'\n");
2392 Status
= CreateFreeLoaderIniForReactos(DstPath
, DestinationArcPath
->Buffer
);
2393 if (!NT_SUCCESS(Status
))
2395 DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status
);
2399 /* Install FAT12/16 boosector */
2400 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2401 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2403 wcscpy(DstPath
, L
"\\Device\\Floppy0");
2405 DPRINT("Install FAT bootcode: %S ==> %S\n", SrcPath
, DstPath
);
2406 Status
= InstallFat12BootCodeToFloppy(SrcPath
, DstPath
);
2407 if (!NT_SUCCESS(Status
))
2409 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status
);
2413 return STATUS_SUCCESS
;
2415 return STATUS_NOT_IMPLEMENTED
;