mirror of
https://github.com/reactos/reactos.git
synced 2025-08-06 10:22:59 +00:00
[SETUPLIB] Add NTFS boot support. (#3778)
This commit is contained in:
parent
a33719500c
commit
2580889cfa
3 changed files with 200 additions and 4 deletions
|
@ -1227,6 +1227,107 @@ InstallBtrfsBootcodeToPartition(
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
NTSTATUS
|
||||||
|
InstallNtfsBootcodeToPartition(
|
||||||
|
IN PUNICODE_STRING SystemRootPath,
|
||||||
|
IN PUNICODE_STRING SourceRootPath,
|
||||||
|
IN PUNICODE_STRING DestinationArcPath)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
BOOLEAN DoesFreeLdrExist;
|
||||||
|
WCHAR SrcPath[MAX_PATH];
|
||||||
|
WCHAR DstPath[MAX_PATH];
|
||||||
|
|
||||||
|
/* NTFS partition */
|
||||||
|
DPRINT("System path: '%wZ'\n", SystemRootPath);
|
||||||
|
|
||||||
|
/* Copy FreeLoader to the system partition, always overwriting the older version */
|
||||||
|
CombinePaths(SrcPath, ARRAYSIZE(SrcPath), 2, SourceRootPath->Buffer, L"\\loader\\freeldr.sys");
|
||||||
|
CombinePaths(DstPath, ARRAYSIZE(DstPath), 2, SystemRootPath->Buffer, L"freeldr.sys");
|
||||||
|
|
||||||
|
DPRINT1("Copy: %S ==> %S\n", SrcPath, DstPath);
|
||||||
|
Status = SetupCopyFile(SrcPath, DstPath, FALSE);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Prepare for possibly updating 'freeldr.ini' */
|
||||||
|
DoesFreeLdrExist = DoesFileExist_2(SystemRootPath->Buffer, L"freeldr.ini");
|
||||||
|
if (DoesFreeLdrExist)
|
||||||
|
{
|
||||||
|
/* Update existing 'freeldr.ini' */
|
||||||
|
DPRINT1("Update existing 'freeldr.ini'\n");
|
||||||
|
Status = UpdateFreeLoaderIni(SystemRootPath->Buffer, DestinationArcPath->Buffer);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check for *nix bootloaders */
|
||||||
|
|
||||||
|
DPRINT1("Create new 'freeldr.ini'\n");
|
||||||
|
|
||||||
|
/* Certainly SysLinux, GRUB, LILO... or an unknown boot loader */
|
||||||
|
DPRINT1("*nix or unknown boot loader found\n");
|
||||||
|
|
||||||
|
if (IsThereAValidBootSector(SystemRootPath->Buffer))
|
||||||
|
{
|
||||||
|
PCWSTR BootSector = L"BOOTSECT.OLD";
|
||||||
|
|
||||||
|
Status = CreateFreeLoaderIniForReactOSAndBootSector(
|
||||||
|
SystemRootPath->Buffer, DestinationArcPath->Buffer,
|
||||||
|
L"Linux", L"\"Linux\"",
|
||||||
|
L"hd0", L"1", BootSector);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("CreateFreeLoaderIniForReactOSAndBootSector() failed (Status %lx)\n", Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Save current bootsector */
|
||||||
|
CombinePaths(DstPath, ARRAYSIZE(DstPath), 2, SystemRootPath->Buffer, BootSector);
|
||||||
|
|
||||||
|
DPRINT1("Save bootsector: %S ==> %S\n", SystemRootPath->Buffer, DstPath);
|
||||||
|
Status = SaveBootSector(SystemRootPath->Buffer, DstPath, NTFS_BOOTSECTOR_SIZE);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("SaveBootSector() failed (Status %lx)\n", Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Status = CreateFreeLoaderIniForReactOS(SystemRootPath->Buffer, DestinationArcPath->Buffer);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("CreateFreeLoaderIniForReactOS() failed (Status %lx)\n", Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Install new bootsector on the disk */
|
||||||
|
|
||||||
|
/* Install NTFS bootcode */
|
||||||
|
CombinePaths(SrcPath, ARRAYSIZE(SrcPath), 2, SourceRootPath->Buffer, L"\\loader\\ntfs.bin");
|
||||||
|
|
||||||
|
DPRINT1("Install NTFS bootcode: %S ==> %S\n", SrcPath, SystemRootPath->Buffer);
|
||||||
|
Status = InstallBootCodeToDisk(SrcPath, SystemRootPath->Buffer, InstallNtfsBootCode);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("InstallBootCodeToDisk(NTFS) failed (Status %lx)\n", Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
InstallVBRToPartition(
|
InstallVBRToPartition(
|
||||||
|
@ -1243,13 +1344,12 @@ InstallVBRToPartition(
|
||||||
DestinationArcPath,
|
DestinationArcPath,
|
||||||
FileSystemName);
|
FileSystemName);
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
else if (wcsicmp(FileSystemName, L"NTFS") == 0)
|
else if (wcsicmp(FileSystemName, L"NTFS") == 0)
|
||||||
{
|
{
|
||||||
DPRINT1("Partitions of type NTFS or HPFS are not supported yet!\n");
|
return InstallNtfsBootcodeToPartition(SystemRootPath,
|
||||||
return STATUS_NOT_SUPPORTED;
|
SourceRootPath,
|
||||||
|
DestinationArcPath);
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
else if (wcsicmp(FileSystemName, L"BTRFS") == 0)
|
else if (wcsicmp(FileSystemName, L"BTRFS") == 0)
|
||||||
{
|
{
|
||||||
return InstallBtrfsBootcodeToPartition(SystemRootPath,
|
return InstallBtrfsBootcodeToPartition(SystemRootPath,
|
||||||
|
|
|
@ -111,6 +111,35 @@ typedef struct _BTRFS_BOOTSECTOR
|
||||||
} BTRFS_BOOTSECTOR, *PBTRFS_BOOTSECTOR;
|
} BTRFS_BOOTSECTOR, *PBTRFS_BOOTSECTOR;
|
||||||
C_ASSERT(sizeof(BTRFS_BOOTSECTOR) == BTRFS_BOOTSECTOR_SIZE);
|
C_ASSERT(sizeof(BTRFS_BOOTSECTOR) == BTRFS_BOOTSECTOR_SIZE);
|
||||||
|
|
||||||
|
typedef struct _NTFS_BOOTSECTOR
|
||||||
|
{
|
||||||
|
UCHAR Jump[3];
|
||||||
|
UCHAR OEMID[8];
|
||||||
|
USHORT BytesPerSector;
|
||||||
|
UCHAR SectorsPerCluster;
|
||||||
|
UCHAR Unused0[7];
|
||||||
|
UCHAR MediaId;
|
||||||
|
UCHAR Unused1[2];
|
||||||
|
USHORT SectorsPerTrack;
|
||||||
|
USHORT Heads;
|
||||||
|
UCHAR Unused2[4];
|
||||||
|
UCHAR Unused3[4];
|
||||||
|
USHORT Unknown[2];
|
||||||
|
ULONGLONG SectorCount;
|
||||||
|
ULONGLONG MftLocation;
|
||||||
|
ULONGLONG MftMirrLocation;
|
||||||
|
CHAR ClustersPerMftRecord;
|
||||||
|
UCHAR Unused4[3];
|
||||||
|
CHAR ClustersPerIndexRecord;
|
||||||
|
UCHAR Unused5[3];
|
||||||
|
ULONGLONG SerialNumber;
|
||||||
|
UCHAR Checksum[4];
|
||||||
|
UCHAR BootStrap[426];
|
||||||
|
USHORT EndSector;
|
||||||
|
UCHAR BootCodeAndData[7680]; // The remainder of the boot sector (8192 - 512)
|
||||||
|
} NTFS_BOOTSECTOR, *PNTFS_BOOTSECTOR;
|
||||||
|
C_ASSERT(sizeof(NTFS_BOOTSECTOR) == NTFS_BOOTSECTOR_SIZE);
|
||||||
|
|
||||||
// TODO: Add more bootsector structures!
|
// TODO: Add more bootsector structures!
|
||||||
|
|
||||||
#include <poppack.h>
|
#include <poppack.h>
|
||||||
|
@ -659,6 +688,66 @@ Quit:
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
InstallNtfsBootCode(
|
||||||
|
IN PCWSTR SrcPath, // NTFS bootsector source file (on the installation medium)
|
||||||
|
IN HANDLE DstPath, // Where to save the bootsector built from the source + partition information
|
||||||
|
IN HANDLE RootPartition) // Partition holding the (old) NTFS information
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
UNICODE_STRING Name;
|
||||||
|
IO_STATUS_BLOCK IoStatusBlock;
|
||||||
|
LARGE_INTEGER FileOffset;
|
||||||
|
BOOTCODE OrigBootSector = {0};
|
||||||
|
BOOTCODE NewBootSector = {0};
|
||||||
|
|
||||||
|
/* Allocate and read the current original partition bootsector */
|
||||||
|
Status = ReadBootCodeByHandle(&OrigBootSector, RootPartition, NTFS_BOOTSECTOR_SIZE);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("InstallNtfsBootCode: Status %lx\n", Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate and read the new bootsector (16 sectors) from SrcPath */
|
||||||
|
RtlInitUnicodeString(&Name, SrcPath);
|
||||||
|
Status = ReadBootCodeFromFile(&NewBootSector, &Name, NTFS_BOOTSECTOR_SIZE);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("InstallNtfsBootCode: Status %lx\n", Status);
|
||||||
|
FreeBootCode(&OrigBootSector);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Adjust the bootsector (copy a part of the NTFS BPB) */
|
||||||
|
RtlCopyMemory(&((PNTFS_BOOTSECTOR)NewBootSector.BootCode)->OEMID,
|
||||||
|
&((PNTFS_BOOTSECTOR)OrigBootSector.BootCode)->OEMID,
|
||||||
|
FIELD_OFFSET(NTFS_BOOTSECTOR, BootStrap) - FIELD_OFFSET(NTFS_BOOTSECTOR, OEMID));
|
||||||
|
|
||||||
|
/* Write sector 0 */
|
||||||
|
FileOffset.QuadPart = 0ULL;
|
||||||
|
Status = NtWriteFile(DstPath,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&IoStatusBlock,
|
||||||
|
NewBootSector.BootCode,
|
||||||
|
NewBootSector.Length,
|
||||||
|
&FileOffset,
|
||||||
|
NULL);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("NtWriteFile() failed (Status %lx)\n", Status);
|
||||||
|
goto Quit;
|
||||||
|
}
|
||||||
|
|
||||||
|
Quit:
|
||||||
|
/* Free the new bootsector */
|
||||||
|
FreeBootCode(&NewBootSector);
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Formatting routines
|
// Formatting routines
|
||||||
|
|
|
@ -68,6 +68,7 @@ FormatFileSystem(
|
||||||
#define FAT_BOOTSECTOR_SIZE (1 * SECTORSIZE)
|
#define FAT_BOOTSECTOR_SIZE (1 * SECTORSIZE)
|
||||||
#define FAT32_BOOTSECTOR_SIZE (1 * SECTORSIZE) // Counts only the primary sector.
|
#define FAT32_BOOTSECTOR_SIZE (1 * SECTORSIZE) // Counts only the primary sector.
|
||||||
#define BTRFS_BOOTSECTOR_SIZE (3 * SECTORSIZE)
|
#define BTRFS_BOOTSECTOR_SIZE (3 * SECTORSIZE)
|
||||||
|
#define NTFS_BOOTSECTOR_SIZE (16 * SECTORSIZE)
|
||||||
|
|
||||||
typedef NTSTATUS
|
typedef NTSTATUS
|
||||||
(/*NTAPI*/ *PFS_INSTALL_BOOTCODE)(
|
(/*NTAPI*/ *PFS_INSTALL_BOOTCODE)(
|
||||||
|
@ -96,6 +97,12 @@ InstallBtrfsBootCode(
|
||||||
IN HANDLE DstPath,
|
IN HANDLE DstPath,
|
||||||
IN HANDLE RootPartition);
|
IN HANDLE RootPartition);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
InstallNtfsBootCode(
|
||||||
|
IN PCWSTR SrcPath,
|
||||||
|
IN HANDLE DstPath,
|
||||||
|
IN HANDLE RootPartition);
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Formatting routines
|
// Formatting routines
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue