2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS text-mode setup
4 * FILE: subsys/system/usetup/bootsup.c
5 * PURPOSE: Bootloader support functions
6 * PROGRAMMER: Eric Kohl
14 #define SECTORSIZE 512
17 typedef struct _FAT_BOOTSECTOR
19 UCHAR JumpBoot
[3]; // Jump instruction to boot code
20 CHAR OemName
[8]; // "MSWIN4.1" for MS formatted volumes
21 USHORT BytesPerSector
; // Bytes per sector
22 UCHAR SectorsPerCluster
; // Number of sectors in a cluster
23 USHORT ReservedSectors
; // Reserved sectors, usually 1 (the bootsector)
24 UCHAR NumberOfFats
; // Number of FAT tables
25 USHORT RootDirEntries
; // Number of root directory entries (fat12/16)
26 USHORT TotalSectors
; // Number of total sectors on the drive, 16-bit
27 UCHAR MediaDescriptor
; // Media descriptor byte
28 USHORT SectorsPerFat
; // Sectors per FAT table (fat12/16)
29 USHORT SectorsPerTrack
; // Number of sectors in a track
30 USHORT NumberOfHeads
; // Number of heads on the disk
31 ULONG HiddenSectors
; // Hidden sectors (sectors before the partition start like the partition table)
32 ULONG TotalSectorsBig
; // This field is the new 32-bit total count of sectors on the volume
33 UCHAR DriveNumber
; // Int 0x13 drive number (e.g. 0x80)
34 UCHAR Reserved1
; // Reserved (used by Windows NT). Code that formats FAT volumes should always set this byte to 0.
35 UCHAR BootSignature
; // Extended boot signature (0x29). This is a signature byte that indicates that the following three fields in the boot sector are present.
36 ULONG VolumeSerialNumber
; // Volume serial number
37 CHAR VolumeLabel
[11]; // Volume label. This field matches the 11-byte volume label recorded in the root directory
38 CHAR FileSystemType
[8]; // One of the strings "FAT12 ", "FAT16 ", or "FAT "
40 UCHAR BootCodeAndData
[448]; // The remainder of the boot sector
42 USHORT BootSectorMagic
; // 0xAA55
44 } FAT_BOOTSECTOR
, *PFAT_BOOTSECTOR
;
46 typedef struct _FAT32_BOOTSECTOR
48 UCHAR JumpBoot
[3]; // Jump instruction to boot code
49 CHAR OemName
[8]; // "MSWIN4.1" for MS formatted volumes
50 USHORT BytesPerSector
; // Bytes per sector
51 UCHAR SectorsPerCluster
; // Number of sectors in a cluster
52 USHORT ReservedSectors
; // Reserved sectors, usually 1 (the bootsector)
53 UCHAR NumberOfFats
; // Number of FAT tables
54 USHORT RootDirEntries
; // Number of root directory entries (fat12/16)
55 USHORT TotalSectors
; // Number of total sectors on the drive, 16-bit
56 UCHAR MediaDescriptor
; // Media descriptor byte
57 USHORT SectorsPerFat
; // Sectors per FAT table (fat12/16)
58 USHORT SectorsPerTrack
; // Number of sectors in a track
59 USHORT NumberOfHeads
; // Number of heads on the disk
60 ULONG HiddenSectors
; // Hidden sectors (sectors before the partition start like the partition table)
61 ULONG TotalSectorsBig
; // This field is the new 32-bit total count of sectors on the volume
62 ULONG SectorsPerFatBig
; // This field is the FAT32 32-bit count of sectors occupied by ONE FAT. BPB_FATSz16 must be 0
63 USHORT ExtendedFlags
; // Extended flags (fat32)
64 USHORT FileSystemVersion
; // File system version (fat32)
65 ULONG RootDirStartCluster
; // Starting cluster of the root directory (fat32)
66 USHORT FsInfo
; // Sector number of FSINFO structure in the reserved area of the FAT32 volume. Usually 1.
67 USHORT BackupBootSector
; // If non-zero, indicates the sector number in the reserved area of the volume of a copy of the boot record. Usually 6.
68 UCHAR Reserved
[12]; // Reserved for future expansion
69 UCHAR DriveNumber
; // Int 0x13 drive number (e.g. 0x80)
70 UCHAR Reserved1
; // Reserved (used by Windows NT). Code that formats FAT volumes should always set this byte to 0.
71 UCHAR BootSignature
; // Extended boot signature (0x29). This is a signature byte that indicates that the following three fields in the boot sector are present.
72 ULONG VolumeSerialNumber
; // Volume serial number
73 CHAR VolumeLabel
[11]; // Volume label. This field matches the 11-byte volume label recorded in the root directory
74 CHAR FileSystemType
[8]; // Always set to the string "FAT32 "
76 UCHAR BootCodeAndData
[420]; // The remainder of the boot sector
78 USHORT BootSectorMagic
; // 0xAA55
80 } FAT32_BOOTSECTOR
, *PFAT32_BOOTSECTOR
;
83 extern PPARTLIST PartitionList
;
85 /* FUNCTIONS ****************************************************************/
90 CreateCommonFreeLoaderSections(
93 PINICACHESECTION IniSection
;
95 /* Create "FREELOADER" section */
96 IniSection
= IniCacheAppendSection(IniCache
,
100 if (IsUnattendedSetup
)
102 /* DefaultOS=ReactOS */
103 IniCacheInsertKey(IniSection
,
108 L
"ReactOS_KdSerial");
116 /* DefaultOS=ReactOS */
117 IniCacheInsertKey(IniSection
,
125 if (IsUnattendedSetup
)
128 /* Timeout=0 for unattended or non debug*/
129 IniCacheInsertKey(IniSection
,
138 /* Timeout=0 or 10 */
139 IniCacheInsertKey(IniSection
,
147 /* Create "Display" section */
148 IniSection
= IniCacheAppendSection(IniCache
, L
"Display");
150 /* TitleText=ReactOS Boot Manager */
151 IniCacheInsertKey(IniSection
,
155 L
"ReactOS Boot Manager");
157 /* StatusBarColor=Cyan */
158 IniCacheInsertKey(IniSection
,
164 /* StatusBarTextColor=Black */
165 IniCacheInsertKey(IniSection
,
168 L
"StatusBarTextColor",
171 /* BackdropTextColor=White */
172 IniCacheInsertKey(IniSection
,
175 L
"BackdropTextColor",
178 /* BackdropColor=Blue */
179 IniCacheInsertKey(IniSection
,
185 /* BackdropFillStyle=Medium */
186 IniCacheInsertKey(IniSection
,
189 L
"BackdropFillStyle",
192 /* TitleBoxTextColor=White */
193 IniCacheInsertKey(IniSection
,
196 L
"TitleBoxTextColor",
199 /* TitleBoxColor=Red */
200 IniCacheInsertKey(IniSection
,
206 /* MessageBoxTextColor=White */
207 IniCacheInsertKey(IniSection
,
210 L
"MessageBoxTextColor",
213 /* MessageBoxColor=Blue */
214 IniCacheInsertKey(IniSection
,
220 /* MenuTextColor=White */
221 IniCacheInsertKey(IniSection
,
228 IniCacheInsertKey(IniSection
,
234 /* TextColor=Yellow */
235 IniCacheInsertKey(IniSection
,
241 /* SelectedTextColor=Black */
242 IniCacheInsertKey(IniSection
,
245 L
"SelectedTextColor",
248 /* SelectedColor=Gray */
249 IniCacheInsertKey(IniSection
,
255 /* SelectedColor=Gray */
256 IniCacheInsertKey(IniSection
,
262 /* SelectedColor=Gray */
263 IniCacheInsertKey(IniSection
,
269 /* SelectedColor=Gray */
270 IniCacheInsertKey(IniSection
,
276 /* SelectedColor=Gray */
277 IniCacheInsertKey(IniSection
,
283 /* SelectedColor=Gray */
284 IniCacheInsertKey(IniSection
,
288 L
"Seconds until highlighted choice will be started automatically: ");
293 CreateFreeLoaderIniForDos(
298 PINICACHESECTION IniSection
;
300 IniCache
= IniCacheCreate();
302 CreateCommonFreeLoaderSections(IniCache
);
304 /* Create "Operating Systems" section */
305 IniSection
= IniCacheAppendSection(IniCache
, L
"Operating Systems");
307 /* REACTOS=ReactOS */
308 IniCacheInsertKey(IniSection
,
314 /* ReactOS_Debug="ReactOS (Debug)" */
315 IniCacheInsertKey(IniSection
,
319 L
"\"ReactOS (Debug)\"");
321 /* DOS=Dos/Windows */
322 IniCacheInsertKey(IniSection
,
328 /* Create "ReactOS" section */
329 IniSection
= IniCacheAppendSection(IniCache
, L
"ReactOS");
331 /* BootType=ReactOS */
332 IniCacheInsertKey(IniSection
,
338 /* SystemPath=<ArcPath> */
339 IniCacheInsertKey(IniSection
,
345 /* Create "ReactOS_Debug" section */
346 IniSection
= IniCacheAppendSection(IniCache
, L
"ReactOS_Debug");
348 /* BootType=ReactOS */
349 IniCacheInsertKey(IniSection
,
355 /* SystemPath=<ArcPath> */
356 IniCacheInsertKey(IniSection
,
362 /* Options=/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS */
363 IniCacheInsertKey(IniSection
,
367 L
"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS");
369 /* Create "DOS" section */
370 IniSection
= IniCacheAppendSection(IniCache
,
373 /* BootType=BootSector */
374 IniCacheInsertKey(IniSection
,
381 IniCacheInsertKey(IniSection
,
387 /* BootPartition=1 */
388 IniCacheInsertKey(IniSection
,
394 /* BootSector=BOOTSECT.DOS */
395 IniCacheInsertKey(IniSection
,
401 IniCacheSave(IniCache
, IniPath
);
402 IniCacheDestroy(IniCache
);
404 return STATUS_SUCCESS
;
409 CreateFreeLoaderEntry(
411 PINICACHESECTION OSSection
,
418 PINICACHESECTION IniSection
;
420 /* Insert entry into "Operating Systems" section */
421 IniCacheInsertKey(OSSection
,
427 /* Create new section */
428 IniSection
= IniCacheAppendSection(IniCache
, Section
);
431 IniCacheInsertKey(IniSection
,
438 IniCacheInsertKey(IniSection
,
445 IniCacheInsertKey(IniSection
,
451 return STATUS_SUCCESS
;
455 CreateFreeLoaderIniForReactos(
460 PINICACHESECTION IniSection
;
462 IniCache
= IniCacheCreate();
464 CreateCommonFreeLoaderSections(IniCache
);
466 /* Create "Operating Systems" section */
467 IniSection
= IniCacheAppendSection(IniCache
, L
"Operating Systems");
470 CreateFreeLoaderEntry(IniCache
, IniSection
,
471 L
"ReactOS", L
"\"ReactOS\"",
472 L
"Windows2003", ArcPath
,
476 CreateFreeLoaderEntry(IniCache
, IniSection
,
477 L
"ReactOS_Debug", L
"\"ReactOS (Debug)\"",
478 L
"Windows2003", ArcPath
,
479 L
"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS");
483 /* ReactOS_KdSerial */
484 CreateFreeLoaderEntry(IniCache
, IniSection
,
485 L
"ReactOS_KdSerial", L
"\"ReactOS (RosDbg)\"",
486 L
"Windows2003", ArcPath
,
487 L
"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /KDSERIAL");
491 CreateFreeLoaderEntry(IniCache
, IniSection
,
492 L
"ReactOS_Screen", L
"\"ReactOS (Screen)\"",
493 L
"Windows2003", ArcPath
,
494 L
"/DEBUG /DEBUGPORT=SCREEN /SOS");
496 /* ReactOS_LogFile */
497 CreateFreeLoaderEntry(IniCache
, IniSection
,
498 L
"ReactOS_LogFile", L
"\"ReactOS (Log file)\"",
499 L
"Windows2003", ArcPath
,
500 L
"/DEBUG /DEBUGPORT=FILE /SOS");
503 CreateFreeLoaderEntry(IniCache
, IniSection
,
504 L
"ReactOS_Ram", L
"\"ReactOS (RAM Disk)\"",
505 L
"Windows2003", L
"ramdisk(0)\\ReactOS",
506 L
"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /RDIMAGEPATH=reactos.img /RDIMAGEOFFSET=32256");
509 CreateFreeLoaderEntry(IniCache
, IniSection
,
510 L
"ReactOS_EMS", L
"\"ReactOS (Emergency Management Services)\"",
511 L
"Windows2003", ArcPath
,
512 L
"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /redirect=com2 /redirectbaudrate=115200");
515 /* Save the ini file */
516 IniCacheSave(IniCache
, IniPath
);
517 IniCacheDestroy(IniCache
);
519 return STATUS_SUCCESS
;
530 PINICACHESECTION IniSection
;
531 PINICACHESECTION OsIniSection
;
532 WCHAR SectionName
[80];
534 WCHAR SystemPath
[200];
535 WCHAR SectionName2
[200];
540 RtlInitUnicodeString(&Name
, IniPath
);
542 Status
= IniCacheLoad(&IniCache
, &Name
, FALSE
);
543 if (!NT_SUCCESS(Status
))
546 /* Get "Operating Systems" section */
547 IniSection
= IniCacheGetSection(IniCache
, L
"Operating Systems");
548 if (IniSection
== NULL
)
550 IniCacheDestroy(IniCache
);
551 return STATUS_UNSUCCESSFUL
;
554 /* Find an existing usable or an unused section name */
556 wcscpy(SectionName
, L
"ReactOS");
557 wcscpy(OsName
, L
"\"ReactOS\"");
560 Status
= IniCacheGetKey(IniSection
, SectionName
, &KeyData
);
561 if (!NT_SUCCESS(Status
))
564 /* Get operation system section */
565 if (KeyData
[0] == '"')
567 wcscpy(SectionName2
, &KeyData
[1]);
568 j
= wcslen(SectionName2
);
571 SectionName2
[j
-1] = 0;
576 wcscpy(SectionName2
, KeyData
);
579 OsIniSection
= IniCacheGetSection(IniCache
, SectionName2
);
580 if (OsIniSection
!= NULL
)
582 BOOLEAN UseExistingEntry
= TRUE
;
585 Status
= IniCacheGetKey(OsIniSection
, L
"BootType", &KeyData
);
586 if (NT_SUCCESS(Status
))
588 if ((KeyData
== NULL
) ||
589 ( (_wcsicmp(KeyData
, L
"ReactOS") != 0) &&
590 (_wcsicmp(KeyData
, L
"\"ReactOS\"") != 0) ))
592 /* This is not a ReactOS entry */
593 UseExistingEntry
= FALSE
;
598 UseExistingEntry
= FALSE
;
601 if (UseExistingEntry
)
603 /* BootType is ReactOS. Now check SystemPath */
604 Status
= IniCacheGetKey(OsIniSection
, L
"SystemPath", &KeyData
);
605 if (NT_SUCCESS(Status
))
607 swprintf(SystemPath
, L
"\"%S\"", ArcPath
);
608 if ((KeyData
== NULL
) ||
609 ((_wcsicmp(KeyData
, ArcPath
) != 0) &&
610 (_wcsicmp(KeyData
, SystemPath
) != 0) ))
612 /* This entry is a ReactOS entry, but the SystemRoot does not
613 match the one we are looking for */
614 UseExistingEntry
= FALSE
;
619 UseExistingEntry
= FALSE
;
623 if (UseExistingEntry
)
625 IniCacheDestroy(IniCache
);
626 return STATUS_SUCCESS
;
630 swprintf(SectionName
, L
"ReactOS_%lu", i
);
631 swprintf(OsName
, L
"\"ReactOS %lu\"", i
);
635 /* <SectionName>=<OsName> */
636 IniCacheInsertKey(IniSection
,
642 /* Create <SectionName> section */
643 IniSection
= IniCacheAppendSection(IniCache
, SectionName
);
645 /* BootType=ReactOS */
646 IniCacheInsertKey(IniSection
,
652 /* SystemPath=<ArcPath> */
653 IniCacheInsertKey(IniSection
,
659 IniCacheSave(IniCache
, IniPath
);
660 IniCacheDestroy(IniCache
);
662 return STATUS_SUCCESS
;
667 SaveCurrentBootSector(
671 OBJECT_ATTRIBUTES ObjectAttributes
;
672 IO_STATUS_BLOCK IoStatusBlock
;
678 /* Allocate buffer for bootsector */
679 BootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
680 if (BootSector
== NULL
)
681 return STATUS_INSUFFICIENT_RESOURCES
;
683 /* Read current boot sector into buffer */
684 RtlInitUnicodeString(&Name
, RootPath
);
686 InitializeObjectAttributes(&ObjectAttributes
,
688 OBJ_CASE_INSENSITIVE
,
692 Status
= NtOpenFile(&FileHandle
,
693 GENERIC_READ
| SYNCHRONIZE
,
697 FILE_SYNCHRONOUS_IO_NONALERT
);
698 if (!NT_SUCCESS(Status
))
700 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
704 Status
= NtReadFile(FileHandle
,
714 if (!NT_SUCCESS(Status
))
716 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
720 /* Write bootsector to DstPath */
721 RtlInitUnicodeString(&Name
, DstPath
);
723 InitializeObjectAttributes(&ObjectAttributes
,
729 Status
= NtCreateFile(&FileHandle
,
730 GENERIC_WRITE
| SYNCHRONIZE
,
734 FILE_ATTRIBUTE_NORMAL
,
737 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
,
740 if (!NT_SUCCESS(Status
))
742 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
746 Status
= NtWriteFile(FileHandle
,
757 /* Free the new boot sector */
758 RtlFreeHeap(ProcessHeap
, 0, BootSector
);
765 InstallFat16BootCodeToFile(
770 OBJECT_ATTRIBUTES ObjectAttributes
;
771 IO_STATUS_BLOCK IoStatusBlock
;
775 PFAT_BOOTSECTOR OrigBootSector
;
776 PFAT_BOOTSECTOR NewBootSector
;
778 /* Allocate buffer for original bootsector */
779 OrigBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
780 if (OrigBootSector
== NULL
)
781 return STATUS_INSUFFICIENT_RESOURCES
;
783 /* Read current boot sector into buffer */
784 RtlInitUnicodeString(&Name
, RootPath
);
786 InitializeObjectAttributes(&ObjectAttributes
,
788 OBJ_CASE_INSENSITIVE
,
792 Status
= NtOpenFile(&FileHandle
,
793 GENERIC_READ
| SYNCHRONIZE
,
797 FILE_SYNCHRONOUS_IO_NONALERT
);
798 if (!NT_SUCCESS(Status
))
800 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
804 Status
= NtReadFile(FileHandle
,
814 if (!NT_SUCCESS(Status
))
816 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
820 /* Allocate buffer for new bootsector */
821 NewBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
822 if (NewBootSector
== NULL
)
824 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
825 return STATUS_INSUFFICIENT_RESOURCES
;
828 /* Read new bootsector from SrcPath */
829 RtlInitUnicodeString(&Name
, SrcPath
);
831 InitializeObjectAttributes(&ObjectAttributes
,
833 OBJ_CASE_INSENSITIVE
,
837 Status
= NtOpenFile(&FileHandle
,
838 GENERIC_READ
| SYNCHRONIZE
,
842 FILE_SYNCHRONOUS_IO_NONALERT
);
843 if (!NT_SUCCESS(Status
))
845 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
846 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
850 Status
= NtReadFile(FileHandle
,
860 if (!NT_SUCCESS(Status
))
862 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
863 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
867 /* Adjust bootsector (copy a part of the FAT BPB) */
868 memcpy(&NewBootSector
->OemName
,
869 &OrigBootSector
->OemName
,
870 FIELD_OFFSET(FAT_BOOTSECTOR
, BootCodeAndData
) -
871 FIELD_OFFSET(FAT_BOOTSECTOR
, OemName
));
873 /* Free the original boot sector */
874 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
876 /* Write new bootsector to DstPath */
877 RtlInitUnicodeString(&Name
, DstPath
);
879 InitializeObjectAttributes(&ObjectAttributes
,
885 Status
= NtCreateFile(&FileHandle
,
886 GENERIC_WRITE
| SYNCHRONIZE
,
890 FILE_ATTRIBUTE_NORMAL
,
893 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
,
896 if (!NT_SUCCESS(Status
))
898 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
903 FilePosition
.QuadPart
= 0;
905 Status
= NtWriteFile(FileHandle
,
916 /* Free the new boot sector */
917 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
924 InstallFat32BootCodeToFile(
929 OBJECT_ATTRIBUTES ObjectAttributes
;
930 IO_STATUS_BLOCK IoStatusBlock
;
934 PFAT32_BOOTSECTOR OrigBootSector
;
935 PFAT32_BOOTSECTOR NewBootSector
;
936 LARGE_INTEGER FileOffset
;
938 /* Allocate buffer for original bootsector */
939 OrigBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
940 if (OrigBootSector
== NULL
)
941 return STATUS_INSUFFICIENT_RESOURCES
;
943 /* Read current boot sector into buffer */
944 RtlInitUnicodeString(&Name
, RootPath
);
946 InitializeObjectAttributes(&ObjectAttributes
,
948 OBJ_CASE_INSENSITIVE
,
952 Status
= NtOpenFile(&FileHandle
,
953 GENERIC_READ
| SYNCHRONIZE
,
957 FILE_SYNCHRONOUS_IO_NONALERT
);
958 if (!NT_SUCCESS(Status
))
960 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
964 Status
= NtReadFile(FileHandle
,
974 if (!NT_SUCCESS(Status
))
976 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
980 /* Allocate buffer for new bootsector (2 sectors) */
981 NewBootSector
= RtlAllocateHeap(ProcessHeap
, 0, 2 * SECTORSIZE
);
982 if (NewBootSector
== NULL
)
984 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
985 return STATUS_INSUFFICIENT_RESOURCES
;
988 /* Read new bootsector from SrcPath */
989 RtlInitUnicodeString(&Name
, SrcPath
);
991 InitializeObjectAttributes(&ObjectAttributes
,
993 OBJ_CASE_INSENSITIVE
,
997 Status
= NtOpenFile(&FileHandle
,
998 GENERIC_READ
| SYNCHRONIZE
,
1002 FILE_SYNCHRONOUS_IO_NONALERT
);
1003 if (!NT_SUCCESS(Status
))
1005 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1006 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1010 Status
= NtReadFile(FileHandle
,
1019 NtClose(FileHandle
);
1020 if (!NT_SUCCESS(Status
))
1022 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1023 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1027 /* Adjust bootsector (copy a part of the FAT32 BPB) */
1028 memcpy(&NewBootSector
->OemName
,
1029 &OrigBootSector
->OemName
,
1030 FIELD_OFFSET(FAT32_BOOTSECTOR
, BootCodeAndData
) -
1031 FIELD_OFFSET(FAT32_BOOTSECTOR
, OemName
));
1033 /* Disable the backup boot sector */
1034 NewBootSector
->BackupBootSector
= 0;
1036 /* Free the original boot sector */
1037 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1039 /* Write the first sector of the new bootcode to DstPath */
1040 RtlInitUnicodeString(&Name
, DstPath
);
1042 InitializeObjectAttributes(&ObjectAttributes
,
1048 Status
= NtCreateFile(&FileHandle
,
1049 GENERIC_WRITE
| SYNCHRONIZE
,
1053 FILE_ATTRIBUTE_NORMAL
,
1056 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
,
1059 if (!NT_SUCCESS(Status
))
1061 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1065 Status
= NtWriteFile(FileHandle
,
1074 NtClose(FileHandle
);
1075 if (!NT_SUCCESS(Status
))
1077 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1081 /* Write the second sector of the new bootcode to boot disk sector 14 */
1082 RtlInitUnicodeString(&Name
, RootPath
);
1084 InitializeObjectAttributes(&ObjectAttributes
,
1090 Status
= NtOpenFile(&FileHandle
,
1091 GENERIC_WRITE
| SYNCHRONIZE
,
1095 FILE_SYNCHRONOUS_IO_NONALERT
);
1096 if (!NT_SUCCESS(Status
))
1098 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1102 FileOffset
.QuadPart
= (ULONGLONG
)(14 * SECTORSIZE
);
1103 Status
= NtWriteFile(FileHandle
,
1108 ((PUCHAR
)NewBootSector
+ SECTORSIZE
),
1112 if (!NT_SUCCESS(Status
))
1115 NtClose(FileHandle
);
1117 /* Free the new boot sector */
1118 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1125 InstallMbrBootCodeToDisk(
1129 OBJECT_ATTRIBUTES ObjectAttributes
;
1130 IO_STATUS_BLOCK IoStatusBlock
;
1131 UNICODE_STRING Name
;
1134 PPARTITION_SECTOR OrigBootSector
;
1135 PPARTITION_SECTOR NewBootSector
;
1137 /* Allocate buffer for original bootsector */
1138 OrigBootSector
= (PPARTITION_SECTOR
)RtlAllocateHeap(ProcessHeap
,
1140 sizeof(PARTITION_SECTOR
));
1141 if (OrigBootSector
== NULL
)
1142 return STATUS_INSUFFICIENT_RESOURCES
;
1144 /* Read current boot sector into buffer */
1145 RtlInitUnicodeString(&Name
,
1148 InitializeObjectAttributes(&ObjectAttributes
,
1150 OBJ_CASE_INSENSITIVE
,
1154 Status
= NtOpenFile(&FileHandle
,
1155 GENERIC_READ
| SYNCHRONIZE
,
1159 FILE_SYNCHRONOUS_IO_NONALERT
);
1160 if (!NT_SUCCESS(Status
))
1162 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1166 Status
= NtReadFile(FileHandle
,
1175 NtClose(FileHandle
);
1176 if (!NT_SUCCESS(Status
))
1178 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1182 /* Allocate buffer for new bootsector */
1183 NewBootSector
= (PPARTITION_SECTOR
)RtlAllocateHeap(ProcessHeap
,
1185 sizeof(PARTITION_SECTOR
));
1186 if (NewBootSector
== NULL
)
1188 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1189 return STATUS_INSUFFICIENT_RESOURCES
;
1192 /* Read new bootsector from SrcPath */
1193 RtlInitUnicodeString(&Name
, SrcPath
);
1195 InitializeObjectAttributes(&ObjectAttributes
,
1197 OBJ_CASE_INSENSITIVE
,
1201 Status
= NtOpenFile(&FileHandle
,
1202 GENERIC_READ
| SYNCHRONIZE
,
1206 FILE_SYNCHRONOUS_IO_NONALERT
);
1207 if (!NT_SUCCESS(Status
))
1209 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1210 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1214 Status
= NtReadFile(FileHandle
,
1220 sizeof(PARTITION_SECTOR
),
1223 NtClose(FileHandle
);
1224 if (!NT_SUCCESS(Status
))
1226 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1227 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1231 /* Copy partition table from old MBR to new */
1232 RtlCopyMemory (&NewBootSector
->Signature
,
1233 &OrigBootSector
->Signature
,
1234 sizeof(PARTITION_SECTOR
) - offsetof(PARTITION_SECTOR
, Signature
) /* Length of partition table */);
1236 /* Free the original boot sector */
1237 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1239 /* Write new bootsector to RootPath */
1240 RtlInitUnicodeString(&Name
, RootPath
);
1242 InitializeObjectAttributes(&ObjectAttributes
,
1248 Status
= NtOpenFile(&FileHandle
,
1249 GENERIC_WRITE
| SYNCHRONIZE
,
1253 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1254 if (!NT_SUCCESS(Status
))
1256 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1257 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1261 Status
= NtWriteFile(FileHandle
,
1270 NtClose(FileHandle
);
1272 /* Free the new boot sector */
1273 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1280 InstallFat12BootCodeToFloppy(
1284 OBJECT_ATTRIBUTES ObjectAttributes
;
1285 IO_STATUS_BLOCK IoStatusBlock
;
1286 UNICODE_STRING Name
;
1289 PFAT_BOOTSECTOR OrigBootSector
;
1290 PFAT_BOOTSECTOR NewBootSector
;
1292 /* Allocate buffer for original bootsector */
1293 OrigBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
1294 if (OrigBootSector
== NULL
)
1295 return STATUS_INSUFFICIENT_RESOURCES
;
1297 /* Read current boot sector into buffer */
1298 RtlInitUnicodeString(&Name
, RootPath
);
1300 InitializeObjectAttributes(&ObjectAttributes
,
1302 OBJ_CASE_INSENSITIVE
,
1306 Status
= NtOpenFile(&FileHandle
,
1307 GENERIC_READ
| SYNCHRONIZE
,
1311 FILE_SYNCHRONOUS_IO_NONALERT
);
1312 if (!NT_SUCCESS(Status
))
1314 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1318 Status
= NtReadFile(FileHandle
,
1327 NtClose(FileHandle
);
1328 if (!NT_SUCCESS(Status
))
1330 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1334 /* Allocate buffer for new bootsector */
1335 NewBootSector
= RtlAllocateHeap(ProcessHeap
,
1338 if (NewBootSector
== NULL
)
1340 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1341 return STATUS_INSUFFICIENT_RESOURCES
;
1344 /* Read new bootsector from SrcPath */
1345 RtlInitUnicodeString(&Name
, SrcPath
);
1347 InitializeObjectAttributes(&ObjectAttributes
,
1349 OBJ_CASE_INSENSITIVE
,
1353 Status
= NtOpenFile(&FileHandle
,
1354 GENERIC_READ
| SYNCHRONIZE
,
1358 FILE_SYNCHRONOUS_IO_NONALERT
);
1359 if (!NT_SUCCESS(Status
))
1361 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1362 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1366 Status
= NtReadFile(FileHandle
,
1375 NtClose(FileHandle
);
1376 if (!NT_SUCCESS(Status
))
1378 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1379 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1383 /* Adjust bootsector (copy a part of the FAT16 BPB) */
1384 memcpy(&NewBootSector
->OemName
,
1385 &OrigBootSector
->OemName
,
1386 FIELD_OFFSET(FAT_BOOTSECTOR
, BootCodeAndData
) -
1387 FIELD_OFFSET(FAT_BOOTSECTOR
, OemName
));
1389 /* Free the original boot sector */
1390 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1392 /* Write new bootsector to RootPath */
1393 RtlInitUnicodeString(&Name
, RootPath
);
1395 InitializeObjectAttributes(&ObjectAttributes
,
1401 Status
= NtOpenFile(&FileHandle
,
1402 GENERIC_WRITE
| SYNCHRONIZE
,
1406 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
1407 if (!NT_SUCCESS(Status
))
1409 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status
);
1410 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1415 FilePosition
.QuadPart
= 0;
1417 Status
= NtWriteFile(FileHandle
,
1426 NtClose(FileHandle
);
1428 /* Free the new boot sector */
1429 RtlFreeHeap(ProcessHeap
, 0, NewBootSector
);
1436 InstallFat16BootCodeToDisk(
1440 OBJECT_ATTRIBUTES ObjectAttributes
;
1441 IO_STATUS_BLOCK IoStatusBlock
;
1442 UNICODE_STRING Name
;
1445 PFAT_BOOTSECTOR OrigBootSector
;
1446 PFAT_BOOTSECTOR NewBootSector
;
1447 PARTITION_INFORMATION
*PartInfo
;
1449 /* Allocate buffer for original bootsector */
1450 OrigBootSector
= RtlAllocateHeap(ProcessHeap
, 0, SECTORSIZE
);
1451 if (OrigBootSector
== NULL
)
1452 return STATUS_INSUFFICIENT_RESOURCES
;
1454 /* Read current boot sector into buffer */
1455 RtlInitUnicodeString(&Name
, RootPath
);
1457 InitializeObjectAttributes(&ObjectAttributes
,
1459 OBJ_CASE_INSENSITIVE
,
1463 Status
= NtOpenFile(&FileHandle
,
1464 GENERIC_READ
| SYNCHRONIZE
,
1468 FILE_SYNCHRONOUS_IO_NONALERT
);
1469 if (!NT_SUCCESS(Status
))
1471 RtlFreeHeap(ProcessHeap
, 0, OrigBootSector
);
1475 Status
= NtReadFile(FileHandle
,
1484 NtClose(FileHandle
);
1485 if (!NT_SUCCESS(Status
))
1487 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
);
2006 CheckInstallFatBootcodeToPartition(
2007 PUNICODE_STRING SystemRootPath
)
2010 if (DoesFileExist(SystemRootPath
->Buffer
, L
"ntldr") ||
2011 DoesFileExist(SystemRootPath
->Buffer
, L
"boot.ini"))
2015 else if (DoesFileExist(SystemRootPath
->Buffer
, L
"io.sys") ||
2016 DoesFileExist(SystemRootPath
->Buffer
, L
"msdos.sys"))
2027 InstallFatBootcodeToPartition(
2028 PUNICODE_STRING SystemRootPath
,
2029 PUNICODE_STRING SourceRootPath
,
2030 PUNICODE_STRING DestinationArcPath
,
2031 UCHAR PartitionType
)
2034 WCHAR SrcPath
[MAX_PATH
];
2035 WCHAR DstPath
[MAX_PATH
];
2038 /* FAT or FAT32 partition */
2039 DPRINT("System path: '%wZ'\n", SystemRootPath
);
2041 if (DoesFileExist(SystemRootPath
->Buffer
, L
"ntldr") == TRUE
||
2042 DoesFileExist(SystemRootPath
->Buffer
, L
"boot.ini") == TRUE
)
2044 /* Search root directory for 'ntldr' and 'boot.ini'. */
2045 DPRINT("Found Microsoft Windows NT/2000/XP boot loader\n");
2047 /* Copy FreeLoader to the boot partition */
2048 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2049 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
2050 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2051 wcscat(DstPath
, L
"\\freeldr.sys");
2053 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2054 Status
= SetupCopyFile(SrcPath
, DstPath
);
2055 if (!NT_SUCCESS(Status
))
2057 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
2061 /* Create or update freeldr.ini */
2062 if (DoesFileExist(SystemRootPath
->Buffer
, L
"freeldr.ini") == FALSE
)
2064 /* Create new 'freeldr.ini' */
2065 DPRINT1("Create new 'freeldr.ini'\n");
2066 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2067 wcscat(DstPath
, L
"\\freeldr.ini");
2069 Status
= CreateFreeLoaderIniForReactos(DstPath
,
2070 DestinationArcPath
->Buffer
);
2071 if (!NT_SUCCESS(Status
))
2073 DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status
);
2077 /* Install new bootcode */
2078 if (PartitionType
== PARTITION_FAT32
||
2079 PartitionType
== PARTITION_FAT32_XINT13
)
2081 /* Install FAT32 bootcode */
2082 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2083 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
2084 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2085 wcscat(DstPath
, L
"\\bootsect.ros");
2087 DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, DstPath
);
2088 Status
= InstallFat32BootCodeToFile(SrcPath
,
2090 SystemRootPath
->Buffer
);
2091 if (!NT_SUCCESS(Status
))
2093 DPRINT1("InstallFat32BootCodeToFile() failed (Status %lx)\n", Status
);
2099 /* Install FAT16 bootcode */
2100 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2101 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2102 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2103 wcscat(DstPath
, L
"\\bootsect.ros");
2105 DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath
, DstPath
);
2106 Status
= InstallFat16BootCodeToFile(SrcPath
,
2108 SystemRootPath
->Buffer
);
2109 if (!NT_SUCCESS(Status
))
2111 DPRINT1("InstallFat16BootCodeToFile() failed (Status %lx)\n", Status
);
2118 /* Update existing 'freeldr.ini' */
2119 DPRINT1("Update existing 'freeldr.ini'\n");
2120 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2121 wcscat(DstPath
, L
"\\freeldr.ini");
2123 Status
= UpdateFreeLoaderIni(DstPath
,
2124 DestinationArcPath
->Buffer
);
2125 if (!NT_SUCCESS(Status
))
2127 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
2132 /* Update 'boot.ini' */
2133 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2134 wcscat(DstPath
, L
"\\boot.ini");
2136 DPRINT1("Update 'boot.ini': %S\n", DstPath
);
2137 Status
= UpdateBootIni(DstPath
,
2138 L
"C:\\bootsect.ros",
2140 if (!NT_SUCCESS(Status
))
2142 DPRINT1("UpdateBootIni() failed (Status %lx)\n", Status
);
2146 else if (DoesFileExist(SystemRootPath
->Buffer
, L
"io.sys") == TRUE
||
2147 DoesFileExist(SystemRootPath
->Buffer
, L
"msdos.sys") == TRUE
)
2149 /* Search for root directory for 'io.sys' and 'msdos.sys'. */
2150 DPRINT1("Found Microsoft DOS or Windows 9x boot loader\n");
2152 /* Copy FreeLoader to the boot partition */
2153 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2154 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
2155 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2156 wcscat(DstPath
, L
"\\freeldr.sys");
2158 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2159 Status
= SetupCopyFile(SrcPath
, DstPath
);
2160 if (!NT_SUCCESS(Status
))
2162 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
2166 /* Create or update 'freeldr.ini' */
2167 if (DoesFileExist(SystemRootPath
->Buffer
, L
"freeldr.ini") == FALSE
)
2169 /* Create new 'freeldr.ini' */
2170 DPRINT1("Create new 'freeldr.ini'\n");
2171 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2172 wcscat(DstPath
, L
"\\freeldr.ini");
2174 Status
= CreateFreeLoaderIniForDos(DstPath
,
2175 DestinationArcPath
->Buffer
);
2176 if (!NT_SUCCESS(Status
))
2178 DPRINT1("CreateFreeLoaderIniForDos() failed (Status %lx)\n", Status
);
2182 /* Save current bootsector as 'BOOTSECT.DOS' */
2183 wcscpy(SrcPath
, SystemRootPath
->Buffer
);
2184 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2185 wcscat(DstPath
, L
"\\bootsect.dos");
2187 DPRINT1("Save bootsector: %S ==> %S\n", SrcPath
, DstPath
);
2188 Status
= SaveCurrentBootSector(SrcPath
,
2190 if (!NT_SUCCESS(Status
))
2192 DPRINT1("SaveCurrentBootSector() failed (Status %lx)\n", Status
);
2196 /* Install new bootsector */
2197 if (PartitionType
== PARTITION_FAT32
||
2198 PartitionType
== PARTITION_FAT32_XINT13
)
2200 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2201 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
2203 DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2204 Status
= InstallFat32BootCodeToDisk(SrcPath
,
2205 SystemRootPath
->Buffer
);
2206 if (!NT_SUCCESS(Status
))
2208 DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)\n", Status
);
2214 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2215 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2217 DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2218 Status
= InstallFat16BootCodeToDisk(SrcPath
,
2219 SystemRootPath
->Buffer
);
2220 if (!NT_SUCCESS(Status
))
2222 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status
);
2229 /* Update existing 'freeldr.ini' */
2230 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2231 wcscat(DstPath
, L
"\\freeldr.ini");
2233 Status
= UpdateFreeLoaderIni(DstPath
, DestinationArcPath
->Buffer
);
2234 if (!NT_SUCCESS(Status
))
2236 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
2243 /* No or unknown boot loader */
2244 DPRINT1("No or unknown boot loader found\n");
2246 /* Copy FreeLoader to the boot partition */
2247 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2248 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
2249 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2250 wcscat(DstPath
, L
"\\freeldr.sys");
2252 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2253 Status
= SetupCopyFile(SrcPath
, DstPath
);
2254 if (!NT_SUCCESS(Status
))
2256 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
2260 /* Create or update 'freeldr.ini' */
2261 if (DoesFileExist(SystemRootPath
->Buffer
, L
"freeldr.ini") == FALSE
)
2263 /* Create new freeldr.ini */
2264 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2265 wcscat(DstPath
, L
"\\freeldr.ini");
2267 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2268 Status
= CreateFreeLoaderIniForReactos(DstPath
,
2269 DestinationArcPath
->Buffer
);
2270 if (!NT_SUCCESS(Status
))
2272 DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status
);
2276 /* Save current bootsector as 'BOOTSECT.OLD' */
2277 wcscpy(SrcPath
, SystemRootPath
->Buffer
);
2278 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2279 wcscat(DstPath
, L
"\\bootsect.old");
2281 DPRINT("Save bootsector: %S ==> %S\n", SrcPath
, DstPath
);
2282 Status
= SaveCurrentBootSector(SrcPath
,
2284 if (!NT_SUCCESS(Status
))
2286 DPRINT1("SaveCurrentBootSector() failed (Status %lx)\n", Status
);
2290 /* Install new bootsector */
2291 if ((PartitionType
== PARTITION_FAT32
) ||
2292 (PartitionType
== PARTITION_FAT32_XINT13
))
2294 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2295 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
2297 DPRINT("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2298 Status
= InstallFat32BootCodeToDisk(SrcPath
,
2299 SystemRootPath
->Buffer
);
2300 if (!NT_SUCCESS(Status
))
2302 DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)\n", Status
);
2308 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2309 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2311 DPRINT("Install FAT bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
->Buffer
);
2312 Status
= InstallFat16BootCodeToDisk(SrcPath
,
2313 SystemRootPath
->Buffer
);
2314 if (!NT_SUCCESS(Status
))
2316 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status
);
2323 /* Update existing 'freeldr.ini' */
2324 wcscpy(DstPath
, SystemRootPath
->Buffer
);
2325 wcscat(DstPath
, L
"\\freeldr.ini");
2327 Status
= UpdateFreeLoaderIni(DstPath
,
2328 DestinationArcPath
->Buffer
);
2329 if (!NT_SUCCESS(Status
))
2331 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
2337 return STATUS_SUCCESS
;
2339 return STATUS_NOT_IMPLEMENTED
;
2345 InstallVBRToPartition(
2346 PUNICODE_STRING SystemRootPath
,
2347 PUNICODE_STRING SourceRootPath
,
2348 PUNICODE_STRING DestinationArcPath
,
2349 UCHAR PartitionType
)
2351 if ((PartitionType
== PARTITION_FAT_12
) ||
2352 (PartitionType
== PARTITION_FAT_16
) ||
2353 (PartitionType
== PARTITION_HUGE
) ||
2354 (PartitionType
== PARTITION_XINT13
) ||
2355 (PartitionType
== PARTITION_FAT32
) ||
2356 (PartitionType
== PARTITION_FAT32_XINT13
))
2358 return InstallFatBootcodeToPartition(SystemRootPath
,
2364 return STATUS_UNSUCCESSFUL
;
2369 InstallFatBootcodeToFloppy(
2370 PUNICODE_STRING SourceRootPath
,
2371 PUNICODE_STRING DestinationArcPath
)
2374 UNICODE_STRING FloppyDevice
= RTL_CONSTANT_STRING(L
"\\Device\\Floppy0");
2375 WCHAR SrcPath
[MAX_PATH
];
2376 WCHAR DstPath
[MAX_PATH
];
2379 /* Format the floppy first */
2380 Status
= VfatFormat(&FloppyDevice
,
2386 if (!NT_SUCCESS(Status
))
2388 DPRINT1("VfatFormat() failed (Status %lx)\n", Status
);
2392 /* Copy FreeLoader to the boot partition */
2393 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2394 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
2396 wcscpy(DstPath
, L
"\\Device\\Floppy0\\freeldr.sys");
2398 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2399 Status
= SetupCopyFile(SrcPath
, DstPath
);
2400 if (!NT_SUCCESS(Status
))
2402 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
2406 /* Create new 'freeldr.ini' */
2407 wcscpy(DstPath
, L
"\\Device\\Floppy0\\freeldr.ini");
2409 DPRINT("Create new 'freeldr.ini'\n");
2410 Status
= CreateFreeLoaderIniForReactos(DstPath
, DestinationArcPath
->Buffer
);
2411 if (!NT_SUCCESS(Status
))
2413 DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status
);
2417 /* Install FAT12/16 boosector */
2418 wcscpy(SrcPath
, SourceRootPath
->Buffer
);
2419 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2421 wcscpy(DstPath
, L
"\\Device\\Floppy0");
2423 DPRINT("Install FAT bootcode: %S ==> %S\n", SrcPath
, DstPath
);
2424 Status
= InstallFat12BootCodeToFloppy(SrcPath
, DstPath
);
2425 if (!NT_SUCCESS(Status
))
2427 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status
);
2431 return STATUS_SUCCESS
;
2433 return STATUS_NOT_IMPLEMENTED
;