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
"Windows2003", L
"ramdisk(0)\\ReactOS",
505 L
"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /RDIMAGEPATH=reactos.img /RDIMAGEOFFSET=32256");
508 CreateFreeLoaderEntry(IniCache
, IniSection
,
509 L
"ReactOS_EMS", L
"\"ReactOS (Emergency Management Services)\"",
510 L
"Windows2003", ArcPath
,
511 L
"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /redirect=com2 /redirectbaudrate=115200");
514 /* Save the ini file */
515 IniCacheSave(IniCache
, IniPath
);
516 IniCacheDestroy(IniCache
);
518 return STATUS_SUCCESS
;
529 PINICACHESECTION IniSection
;
530 PINICACHESECTION OsIniSection
;
531 WCHAR SectionName
[80];
533 WCHAR SystemPath
[200];
534 WCHAR SectionName2
[200];
539 RtlInitUnicodeString(&Name
, IniPath
);
541 Status
= IniCacheLoad(&IniCache
, &Name
, FALSE
);
542 if (!NT_SUCCESS(Status
))
545 /* Get "Operating Systems" section */
546 IniSection
= IniCacheGetSection(IniCache
, L
"Operating Systems");
547 if (IniSection
== NULL
)
549 IniCacheDestroy(IniCache
);
550 return STATUS_UNSUCCESSFUL
;
553 /* Find an existing usable or an unused section name */
555 wcscpy(SectionName
, L
"ReactOS");
556 wcscpy(OsName
, L
"\"ReactOS\"");
559 Status
= IniCacheGetKey(IniSection
, SectionName
, &KeyData
);
560 if (!NT_SUCCESS(Status
))
563 /* Get operation system section */
564 if (KeyData
[0] == '"')
566 wcscpy(SectionName2
, &KeyData
[1]);
567 j
= wcslen(SectionName2
);
570 SectionName2
[j
-1] = 0;
575 wcscpy(SectionName2
, KeyData
);
578 OsIniSection
= IniCacheGetSection(IniCache
, SectionName2
);
579 if (OsIniSection
!= NULL
)
581 BOOLEAN UseExistingEntry
= TRUE
;
584 Status
= IniCacheGetKey(OsIniSection
, L
"BootType", &KeyData
);
585 if (NT_SUCCESS(Status
))
587 if ((KeyData
== NULL
) ||
588 ( (_wcsicmp(KeyData
, L
"ReactOS") != 0) &&
589 (_wcsicmp(KeyData
, L
"\"ReactOS\"") != 0) ))
591 /* This is not a ReactOS entry */
592 UseExistingEntry
= FALSE
;
597 UseExistingEntry
= FALSE
;
600 if (UseExistingEntry
)
602 /* BootType is ReactOS. Now check SystemPath */
603 Status
= IniCacheGetKey(OsIniSection
, L
"SystemPath", &KeyData
);
604 if (NT_SUCCESS(Status
))
606 swprintf(SystemPath
, L
"\"%S\"", ArcPath
);
607 if ((KeyData
== NULL
) ||
608 ((_wcsicmp(KeyData
, ArcPath
) != 0) &&
609 (_wcsicmp(KeyData
, SystemPath
) != 0) ))
611 /* This entry is a ReactOS entry, but the SystemRoot does not
612 match the one we are looking for */
613 UseExistingEntry
= FALSE
;
618 UseExistingEntry
= FALSE
;
622 if (UseExistingEntry
)
624 IniCacheDestroy(IniCache
);
625 return STATUS_SUCCESS
;
629 swprintf(SectionName
, L
"ReactOS_%lu", i
);
630 swprintf(OsName
, L
"\"ReactOS %lu\"", i
);
634 /* <SectionName>=<OsName> */
635 IniCacheInsertKey(IniSection
,
641 /* Create <SectionName> section */
642 IniSection
= IniCacheAppendSection(IniCache
, SectionName
);
644 /* BootType=ReactOS */
645 IniCacheInsertKey(IniSection
,
651 /* SystemPath=<ArcPath> */
652 IniCacheInsertKey(IniSection
,
658 IniCacheSave(IniCache
, IniPath
);
659 IniCacheDestroy(IniCache
);
661 return STATUS_SUCCESS
;
666 SaveCurrentBootSector(
670 OBJECT_ATTRIBUTES ObjectAttributes
;
671 IO_STATUS_BLOCK IoStatusBlock
;
677 /* Allocate buffer for bootsector */
678 BootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
679 if (BootSector
== NULL
)
680 return STATUS_INSUFFICIENT_RESOURCES
;
682 /* Read current boot sector into buffer */
683 RtlInitUnicodeString(&Name
, RootPath
);
685 InitializeObjectAttributes(&ObjectAttributes
,
687 OBJ_CASE_INSENSITIVE
,
691 Status
= NtOpenFile(&FileHandle
,
692 GENERIC_READ
| SYNCHRONIZE
,
696 FILE_SYNCHRONOUS_IO_NONALERT
);
697 if (!NT_SUCCESS(Status
))
699 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
703 Status
= NtReadFile(FileHandle
,
713 if (!NT_SUCCESS(Status
))
715 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
719 /* Write bootsector to DstPath */
720 RtlInitUnicodeString(&Name
, DstPath
);
722 InitializeObjectAttributes(&ObjectAttributes
,
728 Status
= NtCreateFile(&FileHandle
,
729 GENERIC_WRITE
| SYNCHRONIZE
,
733 FILE_ATTRIBUTE_NORMAL
,
736 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
,
739 if (!NT_SUCCESS(Status
))
741 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
745 Status
= NtWriteFile(FileHandle
,
756 /* Free the new boot sector */
757 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
764 InstallFat16BootCodeToFile(
769 OBJECT_ATTRIBUTES ObjectAttributes
;
770 IO_STATUS_BLOCK IoStatusBlock
;
774 PFAT_BOOTSECTOR OrigBootSector
;
775 PFAT_BOOTSECTOR NewBootSector
;
777 /* Allocate buffer for original bootsector */
778 OrigBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
779 if (OrigBootSector
== NULL
)
780 return STATUS_INSUFFICIENT_RESOURCES
;
782 /* Read current boot sector into buffer */
783 RtlInitUnicodeString(&Name
, RootPath
);
785 InitializeObjectAttributes(&ObjectAttributes
,
787 OBJ_CASE_INSENSITIVE
,
791 Status
= NtOpenFile(&FileHandle
,
792 GENERIC_READ
| SYNCHRONIZE
,
796 FILE_SYNCHRONOUS_IO_NONALERT
);
797 if (!NT_SUCCESS(Status
))
799 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
803 Status
= NtReadFile(FileHandle
,
813 if (!NT_SUCCESS(Status
))
815 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
819 /* Allocate buffer for new bootsector */
820 NewBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
821 if (NewBootSector
== NULL
)
823 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
824 return STATUS_INSUFFICIENT_RESOURCES
;
827 /* Read new bootsector from SrcPath */
828 RtlInitUnicodeString(&Name
, SrcPath
);
830 InitializeObjectAttributes(&ObjectAttributes
,
832 OBJ_CASE_INSENSITIVE
,
836 Status
= NtOpenFile(&FileHandle
,
837 GENERIC_READ
| SYNCHRONIZE
,
841 FILE_SYNCHRONOUS_IO_NONALERT
);
842 if (!NT_SUCCESS(Status
))
844 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
845 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
849 Status
= NtReadFile(FileHandle
,
859 if (!NT_SUCCESS(Status
))
861 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
862 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
866 /* Adjust bootsector (copy a part of the FAT BPB) */
867 memcpy(&NewBootSector
->OemName
,
868 &OrigBootSector
->OemName
,
869 FIELD_OFFSET(FAT_BOOTSECTOR
, BootCodeAndData
) -
870 FIELD_OFFSET(FAT_BOOTSECTOR
, OemName
));
872 /* Free the original boot sector */
873 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
875 /* Write new bootsector to DstPath */
876 RtlInitUnicodeString(&Name
, DstPath
);
878 InitializeObjectAttributes(&ObjectAttributes
,
884 Status
= NtCreateFile(&FileHandle
,
885 GENERIC_WRITE
| SYNCHRONIZE
,
889 FILE_ATTRIBUTE_NORMAL
,
892 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
,
895 if (!NT_SUCCESS(Status
))
897 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
902 FilePosition
.QuadPart
= 0;
904 Status
= NtWriteFile(FileHandle
,
915 /* Free the new boot sector */
916 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
923 InstallFat32BootCodeToFile(
928 OBJECT_ATTRIBUTES ObjectAttributes
;
929 IO_STATUS_BLOCK IoStatusBlock
;
933 PFAT32_BOOTSECTOR OrigBootSector
;
934 PFAT32_BOOTSECTOR NewBootSector
;
935 LARGE_INTEGER FileOffset
;
937 /* Allocate buffer for original bootsector */
938 OrigBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
939 if (OrigBootSector
== NULL
)
940 return STATUS_INSUFFICIENT_RESOURCES
;
942 /* Read current boot sector into buffer */
943 RtlInitUnicodeString(&Name
, RootPath
);
945 InitializeObjectAttributes(&ObjectAttributes
,
947 OBJ_CASE_INSENSITIVE
,
951 Status
= NtOpenFile(&FileHandle
,
952 GENERIC_READ
| SYNCHRONIZE
,
956 FILE_SYNCHRONOUS_IO_NONALERT
);
957 if (!NT_SUCCESS(Status
))
959 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
963 Status
= NtReadFile(FileHandle
,
973 if (!NT_SUCCESS(Status
))
975 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
979 /* Allocate buffer for new bootsector (2 sectors) */
980 NewBootSector
= RtlAllocateHeap(ProcessHeap
, 0, 2 * SECTORSIZE
);
981 if (NewBootSector
== NULL
)
983 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
984 return STATUS_INSUFFICIENT_RESOURCES
;
987 /* Read new bootsector from SrcPath */
988 RtlInitUnicodeString(&Name
, SrcPath
);
990 InitializeObjectAttributes(&ObjectAttributes
,
992 OBJ_CASE_INSENSITIVE
,
996 Status
= NtOpenFile(&FileHandle
,
997 GENERIC_READ
| SYNCHRONIZE
,
1001 FILE_SYNCHRONOUS_IO_NONALERT
);
1002 if (!NT_SUCCESS(Status
))
1004 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1005 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1009 Status
= NtReadFile(FileHandle
,
1018 NtClose(FileHandle
);
1019 if (!NT_SUCCESS(Status
))
1021 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1022 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1026 /* Adjust bootsector (copy a part of the FAT32 BPB) */
1027 memcpy(&NewBootSector
->OemName
,
1028 &OrigBootSector
->OemName
,
1029 FIELD_OFFSET(FAT32_BOOTSECTOR
, BootCodeAndData
) -
1030 FIELD_OFFSET(FAT32_BOOTSECTOR
, OemName
));
1032 /* Disable the backup boot sector */
1033 NewBootSector
->BackupBootSector
= 0;
1035 /* Free the original boot sector */
1036 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1038 /* Write the first sector of the new bootcode to DstPath */
1039 RtlInitUnicodeString(&Name
, DstPath
);
1041 InitializeObjectAttributes(&ObjectAttributes
,
1047 Status
= NtCreateFile(&FileHandle
,
1048 GENERIC_WRITE
| SYNCHRONIZE
,
1052 FILE_ATTRIBUTE_NORMAL
,
1055 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
,
1058 if (!NT_SUCCESS(Status
))
1060 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1064 Status
= NtWriteFile(FileHandle
,
1073 NtClose(FileHandle
);
1074 if (!NT_SUCCESS(Status
))
1076 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1080 /* Write the second sector of the new bootcode to boot disk sector 14 */
1081 RtlInitUnicodeString(&Name
, RootPath
);
1083 InitializeObjectAttributes(&ObjectAttributes
,
1089 Status
= NtOpenFile(&FileHandle
,
1090 GENERIC_WRITE
| SYNCHRONIZE
,
1094 FILE_SYNCHRONOUS_IO_NONALERT
);
1095 if (!NT_SUCCESS(Status
))
1097 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1101 FileOffset
.QuadPart
= (ULONGLONG
)(14 * SECTORSIZE
);
1102 Status
= NtWriteFile(FileHandle
,
1107 ((PUCHAR
)NewBootSector
+ SECTORSIZE
),
1111 if (!NT_SUCCESS(Status
))
1114 NtClose(FileHandle
);
1116 /* Free the new boot sector */
1117 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1124 InstallMbrBootCodeToDisk(
1128 OBJECT_ATTRIBUTES ObjectAttributes
;
1129 IO_STATUS_BLOCK IoStatusBlock
;
1130 UNICODE_STRING Name
;
1133 PPARTITION_SECTOR OrigBootSector
;
1134 PPARTITION_SECTOR NewBootSector
;
1136 /* Allocate buffer for original bootsector */
1137 OrigBootSector
= (PPARTITION_SECTOR
)RtlAllocateHeap(ProcessHeap
,
1139 sizeof(PARTITION_SECTOR
));
1140 if (OrigBootSector
== NULL
)
1141 return STATUS_INSUFFICIENT_RESOURCES
;
1143 /* Read current boot sector into buffer */
1144 RtlInitUnicodeString(&Name
,
1147 InitializeObjectAttributes(&ObjectAttributes
,
1149 OBJ_CASE_INSENSITIVE
,
1153 Status
= NtOpenFile(&FileHandle
,
1154 GENERIC_READ
| SYNCHRONIZE
,
1158 FILE_SYNCHRONOUS_IO_NONALERT
);
1159 if (!NT_SUCCESS(Status
))
1161 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1165 Status
= NtReadFile(FileHandle
,
1174 NtClose(FileHandle
);
1175 if (!NT_SUCCESS(Status
))
1177 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
);
1279 InstallFat12BootCodeToFloppy(PWSTR SrcPath
,
1282 OBJECT_ATTRIBUTES ObjectAttributes
;
1283 IO_STATUS_BLOCK IoStatusBlock
;
1284 UNICODE_STRING Name
;
1287 PFAT_BOOTSECTOR OrigBootSector
;
1288 PFAT_BOOTSECTOR NewBootSector
;
1290 /* Allocate buffer for original bootsector */
1291 OrigBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
1292 if (OrigBootSector
== NULL
)
1293 return STATUS_INSUFFICIENT_RESOURCES
;
1295 /* Read current boot sector into buffer */
1296 RtlInitUnicodeString(&Name
, RootPath
);
1298 InitializeObjectAttributes(&ObjectAttributes
,
1300 OBJ_CASE_INSENSITIVE
,
1304 Status
= NtOpenFile(&FileHandle
,
1305 GENERIC_READ
| SYNCHRONIZE
,
1309 FILE_SYNCHRONOUS_IO_NONALERT
);
1310 if (!NT_SUCCESS(Status
))
1312 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1316 Status
= NtReadFile(FileHandle
,
1325 NtClose(FileHandle
);
1326 if (!NT_SUCCESS(Status
))
1328 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1333 /* Allocate buffer for new bootsector */
1334 NewBootSector
= RtlAllocateHeap(ProcessHeap
,
1337 if (NewBootSector
== NULL
)
1339 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1340 return STATUS_INSUFFICIENT_RESOURCES
;
1343 /* Read new bootsector from SrcPath */
1344 RtlInitUnicodeString(&Name
, SrcPath
);
1346 InitializeObjectAttributes(&ObjectAttributes
,
1348 OBJ_CASE_INSENSITIVE
,
1352 Status
= NtOpenFile(&FileHandle
,
1353 GENERIC_READ
| SYNCHRONIZE
,
1357 FILE_SYNCHRONOUS_IO_NONALERT
);
1358 if (!NT_SUCCESS(Status
))
1360 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1361 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1365 Status
= NtReadFile(FileHandle
,
1374 NtClose(FileHandle
);
1375 if (!NT_SUCCESS(Status
))
1377 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1378 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1382 /* Adjust bootsector (copy a part of the FAT16 BPB) */
1383 memcpy(&NewBootSector
->OemName
,
1384 &OrigBootSector
->OemName
,
1385 FIELD_OFFSET(FAT_BOOTSECTOR
, BootCodeAndData
) -
1386 FIELD_OFFSET(FAT_BOOTSECTOR
, OemName
));
1388 /* Free the original boot sector */
1389 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1391 /* Write new bootsector to RootPath */
1392 RtlInitUnicodeString(&Name
, RootPath
);
1394 InitializeObjectAttributes(&ObjectAttributes
,
1400 Status
= NtOpenFile(&FileHandle
,
1401 GENERIC_WRITE
| SYNCHRONIZE
,
1405 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1406 if (!NT_SUCCESS(Status
))
1408 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1409 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1414 FilePosition
.QuadPart
= 0;
1416 Status
= NtWriteFile(FileHandle
,
1425 NtClose(FileHandle
);
1427 /* Free the new boot sector */
1428 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1435 InstallFat16BootCodeToDisk(
1439 OBJECT_ATTRIBUTES ObjectAttributes
;
1440 IO_STATUS_BLOCK IoStatusBlock
;
1441 UNICODE_STRING Name
;
1444 PFAT_BOOTSECTOR OrigBootSector
;
1445 PFAT_BOOTSECTOR NewBootSector
;
1446 PARTITION_INFORMATION
*PartInfo
;
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
);
1491 /* Allocate buffer for new bootsector */
1492 NewBootSector
= RtlAllocateHeap(ProcessHeap
,
1495 if (NewBootSector
== NULL
)
1497 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1498 return STATUS_INSUFFICIENT_RESOURCES
;
1501 /* Read new bootsector from SrcPath */
1502 RtlInitUnicodeString(&Name
, SrcPath
);
1504 InitializeObjectAttributes(&ObjectAttributes
,
1506 OBJ_CASE_INSENSITIVE
,
1510 Status
= NtOpenFile(&FileHandle
,
1511 GENERIC_READ
| SYNCHRONIZE
,
1515 FILE_SYNCHRONOUS_IO_NONALERT
);
1516 if (!NT_SUCCESS(Status
))
1518 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1519 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1523 Status
= NtReadFile(FileHandle
,
1532 NtClose(FileHandle
);
1533 if (!NT_SUCCESS(Status
))
1535 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1536 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1540 /* Adjust bootsector (copy a part of the FAT16 BPB) */
1541 memcpy(&NewBootSector
->OemName
,
1542 &OrigBootSector
->OemName
,
1543 FIELD_OFFSET(FAT_BOOTSECTOR
, BootCodeAndData
) -
1544 FIELD_OFFSET(FAT_BOOTSECTOR
, OemName
));
1546 PartInfo
= &PartitionList
->CurrentPartition
->PartInfo
[PartitionList
->CurrentPartitionNumber
];
1547 NewBootSector
->HiddenSectors
= PartInfo
->HiddenSectors
;
1549 /* Free the original boot sector */
1550 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1552 /* Write new bootsector to RootPath */
1553 RtlInitUnicodeString(&Name
, RootPath
);
1555 InitializeObjectAttributes(&ObjectAttributes
,
1561 Status
= NtOpenFile(&FileHandle
,
1562 GENERIC_WRITE
| SYNCHRONIZE
,
1566 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1567 if (!NT_SUCCESS(Status
))
1569 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1570 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1575 FilePosition
.QuadPart
= 0;
1577 Status
= NtWriteFile(FileHandle
,
1586 NtClose(FileHandle
);
1588 /* Free the new boot sector */
1589 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1596 InstallFat32BootCodeToDisk(
1600 OBJECT_ATTRIBUTES ObjectAttributes
;
1601 IO_STATUS_BLOCK IoStatusBlock
;
1602 UNICODE_STRING Name
;
1605 PFAT32_BOOTSECTOR OrigBootSector
;
1606 PFAT32_BOOTSECTOR NewBootSector
;
1607 LARGE_INTEGER FileOffset
;
1608 USHORT BackupBootSector
;
1609 PARTITION_INFORMATION
*PartInfo
;
1611 /* Allocate buffer for original bootsector */
1612 OrigBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
1613 if (OrigBootSector
== NULL
)
1614 return STATUS_INSUFFICIENT_RESOURCES
;
1616 /* Read current boot sector into buffer */
1617 RtlInitUnicodeString(&Name
, RootPath
);
1619 InitializeObjectAttributes(&ObjectAttributes
,
1621 OBJ_CASE_INSENSITIVE
,
1625 Status
= NtOpenFile(&FileHandle
,
1626 GENERIC_READ
| SYNCHRONIZE
,
1630 FILE_SYNCHRONOUS_IO_NONALERT
);
1631 if (!NT_SUCCESS(Status
))
1633 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1637 Status
= NtReadFile(FileHandle
,
1646 NtClose(FileHandle
);
1647 if (!NT_SUCCESS(Status
))
1649 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1654 /* Allocate buffer for new bootsector (2 sectors) */
1655 NewBootSector
= RtlAllocateHeap(ProcessHeap
, 0, 2 * SECTORSIZE
);
1656 if (NewBootSector
== NULL
)
1658 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1659 return STATUS_INSUFFICIENT_RESOURCES
;
1662 /* Read new bootsector from SrcPath */
1663 RtlInitUnicodeString(&Name
, SrcPath
);
1665 InitializeObjectAttributes(&ObjectAttributes
,
1667 OBJ_CASE_INSENSITIVE
,
1671 Status
= NtOpenFile(&FileHandle
,
1672 GENERIC_READ
| SYNCHRONIZE
,
1676 FILE_SYNCHRONOUS_IO_NONALERT
);
1677 if (!NT_SUCCESS(Status
))
1679 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1680 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1684 Status
= NtReadFile(FileHandle
,
1693 NtClose(FileHandle
);
1694 if (!NT_SUCCESS(Status
))
1696 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1697 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1701 /* Adjust bootsector (copy a part of the FAT32 BPB) */
1702 memcpy(&NewBootSector
->OemName
,
1703 &OrigBootSector
->OemName
,
1704 FIELD_OFFSET(FAT32_BOOTSECTOR
, BootCodeAndData
) -
1705 FIELD_OFFSET(FAT32_BOOTSECTOR
, OemName
));
1707 PartInfo
= &PartitionList
->CurrentPartition
->PartInfo
[PartitionList
->CurrentPartitionNumber
];
1708 NewBootSector
->HiddenSectors
= PartInfo
->HiddenSectors
;
1710 /* Get the location of the backup boot sector */
1711 BackupBootSector
= OrigBootSector
->BackupBootSector
;
1713 /* Free the original boot sector */
1714 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1716 /* Write the first sector of the new bootcode to DstPath */
1717 RtlInitUnicodeString(&Name
, RootPath
);
1719 InitializeObjectAttributes(&ObjectAttributes
,
1725 Status
= NtOpenFile(&FileHandle
,
1726 GENERIC_WRITE
| SYNCHRONIZE
,
1730 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1731 if (!NT_SUCCESS(Status
))
1733 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1734 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1738 /* Write sector 0 */
1739 FileOffset
.QuadPart
= 0ULL;
1740 Status
= NtWriteFile(FileHandle
,
1749 if (!NT_SUCCESS(Status
))
1751 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1752 NtClose(FileHandle
);
1753 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1757 /* Write backup boot sector */
1758 if ((BackupBootSector
!= 0x0000) && (BackupBootSector
!= 0xFFFF))
1760 FileOffset
.QuadPart
= (ULONGLONG
)((ULONG
)BackupBootSector
* SECTORSIZE
);
1761 Status
= NtWriteFile(FileHandle
,
1770 if (!NT_SUCCESS(Status
))
1772 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1773 NtClose(FileHandle
);
1774 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1779 /* Write sector 14 */
1780 FileOffset
.QuadPart
= 14 * SECTORSIZE
;
1781 Status
= NtWriteFile(FileHandle
,
1786 ((PUCHAR
)NewBootSector
+ SECTORSIZE
),
1790 if (!NT_SUCCESS(Status
))
1792 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status
);
1794 NtClose(FileHandle
);
1796 /* Free the new boot sector */
1797 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1809 UNICODE_STRING Name
;
1810 OBJECT_ATTRIBUTES ObjectAttributes
;
1811 IO_STATUS_BLOCK IoStatusBlock
;
1812 FILE_BASIC_INFORMATION FileInfo
;
1816 RtlInitUnicodeString(&Name
, FileName
);
1818 InitializeObjectAttributes(&ObjectAttributes
,
1820 OBJ_CASE_INSENSITIVE
,
1824 Status
= NtOpenFile(&FileHandle
,
1825 GENERIC_READ
| GENERIC_WRITE
| SYNCHRONIZE
,
1829 FILE_SYNCHRONOUS_IO_NONALERT
);
1830 if (Status
== STATUS_NO_SUCH_FILE
)
1832 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1834 return STATUS_SUCCESS
;
1836 if (!NT_SUCCESS(Status
))
1838 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1842 Status
= NtQueryInformationFile(FileHandle
,
1845 sizeof(FILE_BASIC_INFORMATION
),
1846 FileBasicInformation
);
1847 if (!NT_SUCCESS(Status
))
1849 DPRINT1("NtQueryInformationFile() failed (Status %lx)\n", Status
);
1850 NtClose(FileHandle
);
1854 *Attributes
= FileInfo
.FileAttributes
;
1856 /* Delete attributes SYSTEM, HIDDEN and READONLY */
1857 FileInfo
.FileAttributes
= FileInfo
.FileAttributes
&
1858 ~(FILE_ATTRIBUTE_SYSTEM
|
1859 FILE_ATTRIBUTE_HIDDEN
|
1860 FILE_ATTRIBUTE_READONLY
);
1862 Status
= NtSetInformationFile(FileHandle
,
1865 sizeof(FILE_BASIC_INFORMATION
),
1866 FileBasicInformation
);
1867 if (!NT_SUCCESS(Status
))
1869 DPRINT1("NtSetInformationFile() failed (Status %lx)\n", Status
);
1872 NtClose(FileHandle
);
1883 UNICODE_STRING Name
;
1884 OBJECT_ATTRIBUTES ObjectAttributes
;
1885 IO_STATUS_BLOCK IoStatusBlock
;
1886 FILE_BASIC_INFORMATION FileInfo
;
1890 RtlInitUnicodeString(&Name
, FileName
);
1892 InitializeObjectAttributes(&ObjectAttributes
,
1894 OBJ_CASE_INSENSITIVE
,
1898 Status
= NtOpenFile(&FileHandle
,
1899 GENERIC_READ
| GENERIC_WRITE
| SYNCHRONIZE
,
1903 FILE_SYNCHRONOUS_IO_NONALERT
);
1904 if (!NT_SUCCESS(Status
))
1906 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1910 Status
= NtQueryInformationFile(FileHandle
,
1913 sizeof(FILE_BASIC_INFORMATION
),
1914 FileBasicInformation
);
1915 if (!NT_SUCCESS(Status
))
1917 DPRINT1("NtQueryInformationFile() failed (Status %lx)\n", Status
);
1918 NtClose(FileHandle
);
1922 FileInfo
.FileAttributes
= FileInfo
.FileAttributes
| Attributes
;
1924 Status
= NtSetInformationFile(FileHandle
,
1927 sizeof(FILE_BASIC_INFORMATION
),
1928 FileBasicInformation
);
1929 if (!NT_SUCCESS(Status
))
1931 DPRINT1("NtSetInformationFile() failed (Status %lx)\n", Status
);
1934 NtClose(FileHandle
);
1945 UNICODE_STRING Name
;
1946 PINICACHE Cache
= NULL
;
1947 PINICACHESECTION Section
= NULL
;
1949 ULONG FileAttribute
;
1950 PWCHAR OldValue
= NULL
;
1952 RtlInitUnicodeString(&Name
, BootIniPath
);
1954 Status
= IniCacheLoad(&Cache
, &Name
, FALSE
);
1955 if (!NT_SUCCESS(Status
))
1960 Section
= IniCacheGetSection(Cache
,
1961 L
"operating systems");
1962 if (Section
== NULL
)
1964 IniCacheDestroy(Cache
);
1965 return STATUS_UNSUCCESSFUL
;
1968 /* Check - maybe record already exists */
1969 Status
= IniCacheGetKey(Section
, EntryName
, &OldValue
);
1971 /* If either key was not found, or contains something else - add new one */
1972 if (!NT_SUCCESS(Status
) || wcscmp(OldValue
, EntryValue
))
1974 IniCacheInsertKey(Section
,
1981 Status
= UnprotectBootIni(BootIniPath
,
1983 if (!NT_SUCCESS(Status
))
1985 IniCacheDestroy(Cache
);
1989 Status
= IniCacheSave(Cache
, BootIniPath
);
1990 if (!NT_SUCCESS(Status
))
1992 IniCacheDestroy(Cache
);
1996 FileAttribute
|= (FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
| FILE_ATTRIBUTE_READONLY
);
1997 Status
= ProtectBootIni(BootIniPath
, FileAttribute
);
1999 IniCacheDestroy(Cache
);
2005 CheckInstallFatBootcodeToPartition(
2006 PUNICODE_STRING SystemRootPath
)
2009 if (DoesFileExist(SystemRootPath
->Buffer
, L
"ntldr") ||
2010 DoesFileExist(SystemRootPath
->Buffer
, L
"boot.ini"))
2014 else if (DoesFileExist(SystemRootPath
->Buffer
, L
"io.sys") ||
2015 DoesFileExist(SystemRootPath
->Buffer
, L
"msdos.sys"))
2026 InstallFatBootcodeToPartition(
2027 PUNICODE_STRING SystemRootPath
,
2028 PUNICODE_STRING SourceRootPath
,
2029 PUNICODE_STRING DestinationArcPath
,
2030 UCHAR PartitionType
)
2033 WCHAR SrcPath
[MAX_PATH
];
2034 WCHAR DstPath
[MAX_PATH
];
2037 /* FAT or FAT32 partition */
2038 DPRINT("System path: '%wZ'\n", SystemRootPath
);
2040 if (DoesFileExist(SystemRootPath
->Buffer
, L
"ntldr") == TRUE
||
2041 DoesFileExist(SystemRootPath
->Buffer
, L
"boot.ini") == TRUE
)
2043 /* Search root directory for 'ntldr' and 'boot.ini'. */
2044 DPRINT("Found Microsoft Windows NT/2000/XP boot loader\n");
2046 /* Copy FreeLoader to the boot partition */
2047 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2048 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
2049 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2050 wcscat(DstPath
, L
"\\freeldr.sys");
2052 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2053 Status
= SetupCopyFile(SrcPath
, DstPath
);
2054 if (!NT_SUCCESS(Status
))
2056 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
2060 /* Create or update freeldr.ini */
2061 if (DoesFileExist(SystemRootPath
->Buffer
, L
"freeldr.ini") == FALSE
)
2063 /* Create new 'freeldr.ini' */
2064 DPRINT1("Create new 'freeldr.ini'\n");
2065 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2066 wcscat(DstPath
, L
"\\freeldr.ini");
2068 Status
= CreateFreeLoaderIniForReactos(DstPath
,
2069 DestinationArcPath
->Buffer
);
2070 if (!NT_SUCCESS(Status
))
2072 DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status
);
2076 /* Install new bootcode */
2077 if (PartitionType
== PARTITION_FAT32
||
2078 PartitionType
== PARTITION_FAT32_XINT13
)
2080 /* Install FAT32 bootcode */
2081 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2082 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
2083 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2084 wcscat(DstPath
, L
"\\bootsect.ros");
2086 DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, DstPath
);
2087 Status
= InstallFat32BootCodeToFile(SrcPath
,
2089 SystemRootPath
->Buffer
);
2090 if (!NT_SUCCESS(Status
))
2092 DPRINT1("InstallFat32BootCodeToFile() failed (Status %lx)\n", Status
);
2098 /* Install FAT16 bootcode */
2099 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2100 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2101 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2102 wcscat(DstPath
, L
"\\bootsect.ros");
2104 DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath
, DstPath
);
2105 Status
= InstallFat16BootCodeToFile(SrcPath
,
2107 SystemRootPath
->Buffer
);
2108 if (!NT_SUCCESS(Status
))
2110 DPRINT1("InstallFat16BootCodeToFile() failed (Status %lx)\n", Status
);
2117 /* Update existing 'freeldr.ini' */
2118 DPRINT1("Update existing 'freeldr.ini'\n");
2119 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2120 wcscat(DstPath
, L
"\\freeldr.ini");
2122 Status
= UpdateFreeLoaderIni(DstPath
,
2123 DestinationArcPath
->Buffer
);
2124 if (!NT_SUCCESS(Status
))
2126 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
2131 /* Update 'boot.ini' */
2132 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2133 wcscat(DstPath
, L
"\\boot.ini");
2135 DPRINT1("Update 'boot.ini': %S\n", DstPath
);
2136 Status
= UpdateBootIni(DstPath
,
2137 L
"C:\\bootsect.ros",
2139 if (!NT_SUCCESS(Status
))
2141 DPRINT1("UpdateBootIni() failed (Status %lx)\n", Status
);
2145 else if (DoesFileExist(SystemRootPath
->Buffer
, L
"io.sys") == TRUE
||
2146 DoesFileExist(SystemRootPath
->Buffer
, L
"msdos.sys") == TRUE
)
2148 /* Search for root directory for 'io.sys' and 'msdos.sys'. */
2149 DPRINT1("Found Microsoft DOS or Windows 9x boot loader\n");
2151 /* Copy FreeLoader to the boot partition */
2152 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2153 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
2154 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2155 wcscat(DstPath
, L
"\\freeldr.sys");
2157 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2158 Status
= SetupCopyFile(SrcPath
, DstPath
);
2159 if (!NT_SUCCESS(Status
))
2161 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
2165 /* Create or update 'freeldr.ini' */
2166 if (DoesFileExist(SystemRootPath
->Buffer
, L
"freeldr.ini") == FALSE
)
2168 /* Create new 'freeldr.ini' */
2169 DPRINT1("Create new 'freeldr.ini'\n");
2170 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2171 wcscat(DstPath
, L
"\\freeldr.ini");
2173 Status
= CreateFreeLoaderIniForDos(DstPath
,
2174 DestinationArcPath
->Buffer
);
2175 if (!NT_SUCCESS(Status
))
2177 DPRINT1("CreateFreeLoaderIniForDos() failed (Status %lx)\n", Status
);
2181 /* Save current bootsector as 'BOOTSECT.DOS' */
2182 wcscpy(SrcPath
, SystemRootPath
->Buffer
);
2183 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2184 wcscat(DstPath
, L
"\\bootsect.dos");
2186 DPRINT1("Save bootsector: %S ==> %S\n", SrcPath
, DstPath
);
2187 Status
= SaveCurrentBootSector(SrcPath
,
2189 if (!NT_SUCCESS(Status
))
2191 DPRINT1("SaveCurrentBootSector() failed (Status %lx)\n", Status
);
2195 /* Install new bootsector */
2196 if (PartitionType
== PARTITION_FAT32
||
2197 PartitionType
== PARTITION_FAT32_XINT13
)
2199 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2200 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
2202 DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2203 Status
= InstallFat32BootCodeToDisk(SrcPath
,
2204 SystemRootPath
->Buffer
);
2205 if (!NT_SUCCESS(Status
))
2207 DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)\n", Status
);
2213 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2214 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2216 DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2217 Status
= InstallFat16BootCodeToDisk(SrcPath
,
2218 SystemRootPath
->Buffer
);
2219 if (!NT_SUCCESS(Status
))
2221 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status
);
2228 /* Update existing 'freeldr.ini' */
2229 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2230 wcscat(DstPath
, L
"\\freeldr.ini");
2232 Status
= UpdateFreeLoaderIni(DstPath
, DestinationArcPath
->Buffer
);
2233 if (!NT_SUCCESS(Status
))
2235 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
2242 /* No or unknown boot loader */
2243 DPRINT1("No or unknown boot loader found\n");
2245 /* Copy FreeLoader to the boot partition */
2246 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2247 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
2248 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2249 wcscat(DstPath
, L
"\\freeldr.sys");
2251 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2252 Status
= SetupCopyFile(SrcPath
, DstPath
);
2253 if (!NT_SUCCESS(Status
))
2255 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
2259 /* Create or update 'freeldr.ini' */
2260 if (DoesFileExist(SystemRootPath
->Buffer
, L
"freeldr.ini") == FALSE
)
2262 /* Create new freeldr.ini */
2263 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2264 wcscat(DstPath
, L
"\\freeldr.ini");
2266 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2267 Status
= CreateFreeLoaderIniForReactos(DstPath
,
2268 DestinationArcPath
->Buffer
);
2269 if (!NT_SUCCESS(Status
))
2271 DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status
);
2275 /* Save current bootsector as 'BOOTSECT.OLD' */
2276 wcscpy(SrcPath
, SystemRootPath
->Buffer
);
2277 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2278 wcscat(DstPath
, L
"\\bootsect.old");
2280 DPRINT("Save bootsector: %S ==> %S\n", SrcPath
, DstPath
);
2281 Status
= SaveCurrentBootSector(SrcPath
,
2283 if (!NT_SUCCESS(Status
))
2285 DPRINT1("SaveCurrentBootSector() failed (Status %lx)\n", Status
);
2289 /* Install new bootsector */
2290 if ((PartitionType
== PARTITION_FAT32
) ||
2291 (PartitionType
== PARTITION_FAT32_XINT13
))
2293 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2294 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
2296 DPRINT("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2297 Status
= InstallFat32BootCodeToDisk(SrcPath
,
2298 SystemRootPath
->Buffer
);
2299 if (!NT_SUCCESS(Status
))
2301 DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)\n", Status
);
2307 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2308 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2310 DPRINT("Install FAT bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2311 Status
= InstallFat16BootCodeToDisk(SrcPath
,
2312 SystemRootPath
->Buffer
);
2313 if (!NT_SUCCESS(Status
))
2315 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status
);
2322 /* Update existing 'freeldr.ini' */
2323 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2324 wcscat(DstPath
, L
"\\freeldr.ini");
2326 Status
= UpdateFreeLoaderIni(DstPath
,
2327 DestinationArcPath
->Buffer
);
2328 if (!NT_SUCCESS(Status
))
2330 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
2336 return STATUS_SUCCESS
;
2338 return STATUS_NOT_IMPLEMENTED
;
2343 InstallVBRToPartition(
2344 PUNICODE_STRING SystemRootPath
,
2345 PUNICODE_STRING SourceRootPath
,
2346 PUNICODE_STRING DestinationArcPath
,
2347 UCHAR PartitionType
)
2349 if ((PartitionType
== PARTITION_FAT_12
) ||
2350 (PartitionType
== PARTITION_FAT_16
) ||
2351 (PartitionType
== PARTITION_HUGE
) ||
2352 (PartitionType
== PARTITION_XINT13
) ||
2353 (PartitionType
== PARTITION_FAT32
) ||
2354 (PartitionType
== PARTITION_FAT32_XINT13
))
2356 return InstallFatBootcodeToPartition(SystemRootPath
,
2362 return STATUS_UNSUCCESSFUL
;
2367 InstallFatBootcodeToFloppy(
2368 PUNICODE_STRING SourceRootPath
,
2369 PUNICODE_STRING DestinationArcPath
)
2372 UNICODE_STRING FloppyDevice
= RTL_CONSTANT_STRING(L
"\\Device\\Floppy0");
2373 WCHAR SrcPath
[MAX_PATH
];
2374 WCHAR DstPath
[MAX_PATH
];
2377 /* Format the floppy first */
2378 Status
= VfatFormat(&FloppyDevice
,
2384 if (!NT_SUCCESS(Status
))
2386 DPRINT1("VfatFormat() failed (Status %lx)\n", Status
);
2390 /* Copy FreeLoader to the boot partition */
2391 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2392 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
2394 wcscpy(DstPath
, L
"\\Device\\Floppy0\\freeldr.sys");
2396 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2397 Status
= SetupCopyFile(SrcPath
, DstPath
);
2398 if (!NT_SUCCESS(Status
))
2400 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
2404 /* Create new 'freeldr.ini' */
2405 wcscpy(DstPath
, L
"\\Device\\Floppy0\\freeldr.ini");
2407 DPRINT("Create new 'freeldr.ini'\n");
2408 Status
= CreateFreeLoaderIniForReactos(DstPath
, DestinationArcPath
->Buffer
);
2409 if (!NT_SUCCESS(Status
))
2411 DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status
);
2415 /* Install FAT12/16 boosector */
2416 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2417 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2419 wcscpy(DstPath
, L
"\\Device\\Floppy0");
2421 DPRINT("Install FAT bootcode: %S ==> %S\n", SrcPath
, DstPath
);
2422 Status
= InstallFat12BootCodeToFloppy(SrcPath
, DstPath
);
2423 if (!NT_SUCCESS(Status
))
2425 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status
);
2429 return STATUS_SUCCESS
;
2431 return STATUS_NOT_IMPLEMENTED
;