mirror of
https://github.com/reactos/reactos.git
synced 2025-02-23 00:45:24 +00:00
[SETUPLIB] Code re-organization in bootsup.c and fsutil.c.
- Move the actual VBR bootcode installation helpers into fsutil.c (they depend on the selected filesystem). - Introduce InstallBootCodeToDisk() and InstallBootCodeToFile() and bootcode.c helpers, in order to replace the several functions that were duplicating the same code.
This commit is contained in:
parent
b51b8ee2d5
commit
593bcce999
7 changed files with 784 additions and 1312 deletions
|
@ -16,6 +16,7 @@ list(APPEND SOURCE
|
||||||
utils/osdetect.c
|
utils/osdetect.c
|
||||||
utils/partlist.c
|
utils/partlist.c
|
||||||
utils/regutil.c
|
utils/regutil.c
|
||||||
|
bootcode.c
|
||||||
bootsup.c
|
bootsup.c
|
||||||
fsutil.c
|
fsutil.c
|
||||||
install.c
|
install.c
|
||||||
|
|
116
base/setup/lib/bootcode.c
Normal file
116
base/setup/lib/bootcode.c
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
/*
|
||||||
|
* PROJECT: ReactOS Setup Library
|
||||||
|
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
|
||||||
|
* PURPOSE: BootCode support functions.
|
||||||
|
* COPYRIGHT: Copyright 2020 Hermes Belusca-Maito
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* INCLUDES *****************************************************************/
|
||||||
|
|
||||||
|
#include "precomp.h"
|
||||||
|
|
||||||
|
#include "bootcode.h"
|
||||||
|
|
||||||
|
#define NDEBUG
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* FUNCTIONS ****************************************************************/
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
ReadBootCodeByHandle(
|
||||||
|
IN OUT PBOOTCODE BootCodeInfo,
|
||||||
|
IN HANDLE FileHandle,
|
||||||
|
IN ULONG Length OPTIONAL)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
PVOID BootCode;
|
||||||
|
IO_STATUS_BLOCK IoStatusBlock;
|
||||||
|
LARGE_INTEGER FileOffset;
|
||||||
|
|
||||||
|
ASSERT(BootCodeInfo);
|
||||||
|
|
||||||
|
/* Normalize the bootcode length */
|
||||||
|
if (Length == 0 || Length == (ULONG)-1)
|
||||||
|
Length = SECTORSIZE;
|
||||||
|
|
||||||
|
/* Allocate a buffer for the bootcode */
|
||||||
|
BootCode = RtlAllocateHeap(ProcessHeap, HEAP_ZERO_MEMORY, Length);
|
||||||
|
if (BootCode == NULL)
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
|
||||||
|
/* Read the bootcode from the file into the buffer */
|
||||||
|
FileOffset.QuadPart = 0ULL;
|
||||||
|
Status = NtReadFile(FileHandle,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&IoStatusBlock,
|
||||||
|
BootCode,
|
||||||
|
Length,
|
||||||
|
&FileOffset,
|
||||||
|
NULL);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
RtlFreeHeap(ProcessHeap, 0, BootCode);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update the bootcode information */
|
||||||
|
if (BootCodeInfo->BootCode)
|
||||||
|
RtlFreeHeap(ProcessHeap, 0, BootCodeInfo->BootCode);
|
||||||
|
BootCodeInfo->BootCode = BootCode;
|
||||||
|
/**/ BootCodeInfo->Length = Length; /**/
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
ReadBootCodeFromFile(
|
||||||
|
IN OUT PBOOTCODE BootCodeInfo,
|
||||||
|
IN PUNICODE_STRING FilePath,
|
||||||
|
IN ULONG Length OPTIONAL)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
|
IO_STATUS_BLOCK IoStatusBlock;
|
||||||
|
HANDLE FileHandle;
|
||||||
|
|
||||||
|
ASSERT(BootCodeInfo);
|
||||||
|
|
||||||
|
/* Open the file */
|
||||||
|
InitializeObjectAttributes(&ObjectAttributes,
|
||||||
|
FilePath,
|
||||||
|
OBJ_CASE_INSENSITIVE,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
Status = NtOpenFile(&FileHandle,
|
||||||
|
GENERIC_READ | SYNCHRONIZE,
|
||||||
|
&ObjectAttributes,
|
||||||
|
&IoStatusBlock,
|
||||||
|
FILE_SHARE_READ | FILE_SHARE_WRITE, // Is FILE_SHARE_WRITE necessary?
|
||||||
|
FILE_SYNCHRONOUS_IO_NONALERT);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
return Status;
|
||||||
|
|
||||||
|
Status = ReadBootCodeByHandle(BootCodeInfo, FileHandle, Length);
|
||||||
|
|
||||||
|
/* Close the file and return */
|
||||||
|
NtClose(FileHandle);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
FreeBootCode(
|
||||||
|
IN OUT PBOOTCODE BootCodeInfo)
|
||||||
|
{
|
||||||
|
ASSERT(BootCodeInfo);
|
||||||
|
|
||||||
|
/* Update the bootcode information */
|
||||||
|
if (BootCodeInfo->BootCode)
|
||||||
|
RtlFreeHeap(ProcessHeap, 0, BootCodeInfo->BootCode);
|
||||||
|
BootCodeInfo->BootCode = NULL;
|
||||||
|
/**/ BootCodeInfo->Length = 0; /**/
|
||||||
|
}
|
||||||
|
|
||||||
|
/* EOF */
|
37
base/setup/lib/bootcode.h
Normal file
37
base/setup/lib/bootcode.h
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
* PROJECT: ReactOS Setup Library
|
||||||
|
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
|
||||||
|
* PURPOSE: BootCode support functions.
|
||||||
|
* COPYRIGHT: Copyright 2020 Hermes Belusca-Maito
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef SECTORSIZE
|
||||||
|
#undef SECTORSIZE
|
||||||
|
#endif
|
||||||
|
#define SECTORSIZE 512
|
||||||
|
|
||||||
|
typedef struct _BOOTCODE
|
||||||
|
{
|
||||||
|
PVOID BootCode;
|
||||||
|
ULONG Length;
|
||||||
|
} BOOTCODE, *PBOOTCODE;
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
ReadBootCodeByHandle(
|
||||||
|
IN OUT PBOOTCODE BootCodeInfo,
|
||||||
|
IN HANDLE FileHandle,
|
||||||
|
IN ULONG Length OPTIONAL);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
ReadBootCodeFromFile(
|
||||||
|
IN OUT PBOOTCODE BootCodeInfo,
|
||||||
|
IN PUNICODE_STRING FilePath,
|
||||||
|
IN ULONG Length OPTIONAL);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
FreeBootCode(
|
||||||
|
IN OUT PBOOTCODE BootCodeInfo);
|
||||||
|
|
||||||
|
/* EOF */
|
File diff suppressed because it is too large
Load diff
|
@ -3,7 +3,7 @@
|
||||||
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
|
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
|
||||||
* PURPOSE: Filesystem support functions
|
* PURPOSE: Filesystem support functions
|
||||||
* COPYRIGHT: Copyright 2003-2019 Casper S. Hornstrup (chorns@users.sourceforge.net)
|
* COPYRIGHT: Copyright 2003-2019 Casper S. Hornstrup (chorns@users.sourceforge.net)
|
||||||
* Copyright 2017-2019 Hermes Belusca-Maito
|
* Copyright 2017-2020 Hermes Belusca-Maito
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
#include "partlist.h"
|
#include "partlist.h"
|
||||||
#include "fsrec.h"
|
#include "fsrec.h"
|
||||||
|
#include "bootcode.h"
|
||||||
#include "fsutil.h"
|
#include "fsutil.h"
|
||||||
|
|
||||||
#include <fslib/vfatlib.h>
|
#include <fslib/vfatlib.h>
|
||||||
|
@ -29,6 +30,92 @@
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* TYPEDEFS *****************************************************************/
|
||||||
|
|
||||||
|
#include <pshpack1.h>
|
||||||
|
typedef struct _FAT_BOOTSECTOR
|
||||||
|
{
|
||||||
|
UCHAR JumpBoot[3]; // Jump instruction to boot code
|
||||||
|
CHAR OemName[8]; // "MSWIN4.1" for MS formatted volumes
|
||||||
|
USHORT BytesPerSector; // Bytes per sector
|
||||||
|
UCHAR SectorsPerCluster; // Number of sectors in a cluster
|
||||||
|
USHORT ReservedSectors; // Reserved sectors, usually 1 (the bootsector)
|
||||||
|
UCHAR NumberOfFats; // Number of FAT tables
|
||||||
|
USHORT RootDirEntries; // Number of root directory entries (fat12/16)
|
||||||
|
USHORT TotalSectors; // Number of total sectors on the drive, 16-bit
|
||||||
|
UCHAR MediaDescriptor; // Media descriptor byte
|
||||||
|
USHORT SectorsPerFat; // Sectors per FAT table (fat12/16)
|
||||||
|
USHORT SectorsPerTrack; // Number of sectors in a track
|
||||||
|
USHORT NumberOfHeads; // Number of heads on the disk
|
||||||
|
ULONG HiddenSectors; // Hidden sectors (sectors before the partition start like the partition table)
|
||||||
|
ULONG TotalSectorsBig; // This field is the new 32-bit total count of sectors on the volume
|
||||||
|
UCHAR DriveNumber; // Int 0x13 drive number (e.g. 0x80)
|
||||||
|
UCHAR Reserved1; // Reserved (used by Windows NT). Code that formats FAT volumes should always set this byte to 0.
|
||||||
|
UCHAR BootSignature; // Extended boot signature (0x29). This is a signature byte that indicates that the following three fields in the boot sector are present.
|
||||||
|
ULONG VolumeSerialNumber; // Volume serial number
|
||||||
|
CHAR VolumeLabel[11]; // Volume label. This field matches the 11-byte volume label recorded in the root directory
|
||||||
|
CHAR FileSystemType[8]; // One of the strings "FAT12 ", "FAT16 ", or "FAT "
|
||||||
|
|
||||||
|
UCHAR BootCodeAndData[448]; // The remainder of the boot sector
|
||||||
|
|
||||||
|
USHORT BootSectorMagic; // 0xAA55
|
||||||
|
|
||||||
|
} FAT_BOOTSECTOR, *PFAT_BOOTSECTOR;
|
||||||
|
C_ASSERT(sizeof(FAT_BOOTSECTOR) == FAT_BOOTSECTOR_SIZE);
|
||||||
|
|
||||||
|
typedef struct _FAT32_BOOTSECTOR
|
||||||
|
{
|
||||||
|
UCHAR JumpBoot[3]; // Jump instruction to boot code
|
||||||
|
CHAR OemName[8]; // "MSWIN4.1" for MS formatted volumes
|
||||||
|
USHORT BytesPerSector; // Bytes per sector
|
||||||
|
UCHAR SectorsPerCluster; // Number of sectors in a cluster
|
||||||
|
USHORT ReservedSectors; // Reserved sectors, usually 1 (the bootsector)
|
||||||
|
UCHAR NumberOfFats; // Number of FAT tables
|
||||||
|
USHORT RootDirEntries; // Number of root directory entries (fat12/16)
|
||||||
|
USHORT TotalSectors; // Number of total sectors on the drive, 16-bit
|
||||||
|
UCHAR MediaDescriptor; // Media descriptor byte
|
||||||
|
USHORT SectorsPerFat; // Sectors per FAT table (fat12/16)
|
||||||
|
USHORT SectorsPerTrack; // Number of sectors in a track
|
||||||
|
USHORT NumberOfHeads; // Number of heads on the disk
|
||||||
|
ULONG HiddenSectors; // Hidden sectors (sectors before the partition start like the partition table)
|
||||||
|
ULONG TotalSectorsBig; // This field is the new 32-bit total count of sectors on the volume
|
||||||
|
ULONG SectorsPerFatBig; // This field is the FAT32 32-bit count of sectors occupied by ONE FAT. BPB_FATSz16 must be 0
|
||||||
|
USHORT ExtendedFlags; // Extended flags (fat32)
|
||||||
|
USHORT FileSystemVersion; // File system version (fat32)
|
||||||
|
ULONG RootDirStartCluster; // Starting cluster of the root directory (fat32)
|
||||||
|
USHORT FsInfo; // Sector number of FSINFO structure in the reserved area of the FAT32 volume. Usually 1.
|
||||||
|
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.
|
||||||
|
UCHAR Reserved[12]; // Reserved for future expansion
|
||||||
|
UCHAR DriveNumber; // Int 0x13 drive number (e.g. 0x80)
|
||||||
|
UCHAR Reserved1; // Reserved (used by Windows NT). Code that formats FAT volumes should always set this byte to 0.
|
||||||
|
UCHAR BootSignature; // Extended boot signature (0x29). This is a signature byte that indicates that the following three fields in the boot sector are present.
|
||||||
|
ULONG VolumeSerialNumber; // Volume serial number
|
||||||
|
CHAR VolumeLabel[11]; // Volume label. This field matches the 11-byte volume label recorded in the root directory
|
||||||
|
CHAR FileSystemType[8]; // Always set to the string "FAT32 "
|
||||||
|
|
||||||
|
UCHAR BootCodeAndData[420]; // The remainder of the boot sector
|
||||||
|
|
||||||
|
USHORT BootSectorMagic; // 0xAA55
|
||||||
|
|
||||||
|
} FAT32_BOOTSECTOR, *PFAT32_BOOTSECTOR;
|
||||||
|
C_ASSERT(sizeof(FAT32_BOOTSECTOR) == FAT32_BOOTSECTOR_SIZE);
|
||||||
|
|
||||||
|
typedef struct _BTRFS_BOOTSECTOR
|
||||||
|
{
|
||||||
|
UCHAR JumpBoot[3];
|
||||||
|
UCHAR ChunkMapSize;
|
||||||
|
UCHAR BootDrive;
|
||||||
|
ULONGLONG PartitionStartLBA;
|
||||||
|
UCHAR Fill[1521]; // 1536 - 15
|
||||||
|
USHORT BootSectorMagic;
|
||||||
|
} BTRFS_BOOTSECTOR, *PBTRFS_BOOTSECTOR;
|
||||||
|
C_ASSERT(sizeof(BTRFS_BOOTSECTOR) == BTRFS_BOOTSECTOR_SIZE);
|
||||||
|
|
||||||
|
// TODO: Add more bootsector structures!
|
||||||
|
|
||||||
|
#include <poppack.h>
|
||||||
|
|
||||||
|
|
||||||
/* LOCALS *******************************************************************/
|
/* LOCALS *******************************************************************/
|
||||||
|
|
||||||
/** IFS_PROVIDER **/
|
/** IFS_PROVIDER **/
|
||||||
|
@ -238,6 +325,297 @@ FormatFileSystem(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Bootsector routines
|
||||||
|
//
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
InstallFat1216BootCode(
|
||||||
|
IN PCWSTR SrcPath, // FAT12/16 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) FAT12/16 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,
|
||||||
|
FAT_BOOTSECTOR_SIZE);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
return Status;
|
||||||
|
|
||||||
|
/* Allocate and read the new bootsector from SrcPath */
|
||||||
|
RtlInitUnicodeString(&Name, SrcPath);
|
||||||
|
Status = ReadBootCodeFromFile(&NewBootSector,
|
||||||
|
&Name,
|
||||||
|
FAT_BOOTSECTOR_SIZE);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
FreeBootCode(&OrigBootSector);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Adjust the bootsector (copy a part of the FAT12/16 BPB) */
|
||||||
|
RtlCopyMemory(&((PFAT_BOOTSECTOR)NewBootSector.BootCode)->OemName,
|
||||||
|
&((PFAT_BOOTSECTOR)OrigBootSector.BootCode)->OemName,
|
||||||
|
FIELD_OFFSET(FAT_BOOTSECTOR, BootCodeAndData) -
|
||||||
|
FIELD_OFFSET(FAT_BOOTSECTOR, OemName));
|
||||||
|
|
||||||
|
/* Free the original bootsector */
|
||||||
|
FreeBootCode(&OrigBootSector);
|
||||||
|
|
||||||
|
/* Write the new bootsector to DstPath */
|
||||||
|
FileOffset.QuadPart = 0ULL;
|
||||||
|
Status = NtWriteFile(DstPath,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&IoStatusBlock,
|
||||||
|
NewBootSector.BootCode,
|
||||||
|
NewBootSector.Length,
|
||||||
|
&FileOffset,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
/* Free the new bootsector */
|
||||||
|
FreeBootCode(&NewBootSector);
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
InstallFat32BootCode(
|
||||||
|
IN PCWSTR SrcPath, // FAT32 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) FAT32 information
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
UNICODE_STRING Name;
|
||||||
|
IO_STATUS_BLOCK IoStatusBlock;
|
||||||
|
LARGE_INTEGER FileOffset;
|
||||||
|
USHORT BackupBootSector = 0;
|
||||||
|
BOOTCODE OrigBootSector = {0};
|
||||||
|
BOOTCODE NewBootSector = {0};
|
||||||
|
|
||||||
|
/* Allocate and read the current original partition bootsector */
|
||||||
|
Status = ReadBootCodeByHandle(&OrigBootSector,
|
||||||
|
RootPartition,
|
||||||
|
FAT32_BOOTSECTOR_SIZE);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
return Status;
|
||||||
|
|
||||||
|
/* Allocate and read the new bootsector (2 sectors) from SrcPath */
|
||||||
|
RtlInitUnicodeString(&Name, SrcPath);
|
||||||
|
Status = ReadBootCodeFromFile(&NewBootSector,
|
||||||
|
&Name,
|
||||||
|
2 * FAT32_BOOTSECTOR_SIZE);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
FreeBootCode(&OrigBootSector);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Adjust the bootsector (copy a part of the FAT32 BPB) */
|
||||||
|
RtlCopyMemory(&((PFAT32_BOOTSECTOR)NewBootSector.BootCode)->OemName,
|
||||||
|
&((PFAT32_BOOTSECTOR)OrigBootSector.BootCode)->OemName,
|
||||||
|
FIELD_OFFSET(FAT32_BOOTSECTOR, BootCodeAndData) -
|
||||||
|
FIELD_OFFSET(FAT32_BOOTSECTOR, OemName));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We know we copy the boot code to a file only when DstPath != RootPartition,
|
||||||
|
* otherwise the boot code is copied to the specified root partition.
|
||||||
|
*/
|
||||||
|
if (DstPath != RootPartition)
|
||||||
|
{
|
||||||
|
/* Copy to a file: Disable the backup bootsector */
|
||||||
|
((PFAT32_BOOTSECTOR)NewBootSector.BootCode)->BackupBootSector = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Copy to a disk: Get the location of the backup bootsector */
|
||||||
|
BackupBootSector = ((PFAT32_BOOTSECTOR)OrigBootSector.BootCode)->BackupBootSector;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free the original bootsector */
|
||||||
|
FreeBootCode(&OrigBootSector);
|
||||||
|
|
||||||
|
/* Write the first sector of the new bootcode to DstPath sector 0 */
|
||||||
|
FileOffset.QuadPart = 0ULL;
|
||||||
|
Status = NtWriteFile(DstPath,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&IoStatusBlock,
|
||||||
|
NewBootSector.BootCode,
|
||||||
|
FAT32_BOOTSECTOR_SIZE,
|
||||||
|
&FileOffset,
|
||||||
|
NULL);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("NtWriteFile() failed (Status %lx)\n", Status);
|
||||||
|
FreeBootCode(&NewBootSector);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DstPath == RootPartition)
|
||||||
|
{
|
||||||
|
/* Copy to a disk: Write the backup bootsector */
|
||||||
|
if ((BackupBootSector != 0x0000) && (BackupBootSector != 0xFFFF))
|
||||||
|
{
|
||||||
|
FileOffset.QuadPart = (ULONGLONG)((ULONG)BackupBootSector * FAT32_BOOTSECTOR_SIZE);
|
||||||
|
Status = NtWriteFile(DstPath,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&IoStatusBlock,
|
||||||
|
NewBootSector.BootCode,
|
||||||
|
FAT32_BOOTSECTOR_SIZE,
|
||||||
|
&FileOffset,
|
||||||
|
NULL);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("NtWriteFile() failed (Status %lx)\n", Status);
|
||||||
|
FreeBootCode(&NewBootSector);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write the second sector of the new bootcode to boot disk sector 14 */
|
||||||
|
// FileOffset.QuadPart = (ULONGLONG)(14 * FAT32_BOOTSECTOR_SIZE);
|
||||||
|
FileOffset.QuadPart = 14 * FAT32_BOOTSECTOR_SIZE;
|
||||||
|
Status = NtWriteFile(DstPath, // or really RootPartition ???
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&IoStatusBlock,
|
||||||
|
((PUCHAR)NewBootSector.BootCode + FAT32_BOOTSECTOR_SIZE),
|
||||||
|
FAT32_BOOTSECTOR_SIZE,
|
||||||
|
&FileOffset,
|
||||||
|
NULL);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("NtWriteFile() failed (Status %lx)\n", Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free the new bootsector */
|
||||||
|
FreeBootCode(&NewBootSector);
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
InstallBtrfsBootCode(
|
||||||
|
IN PCWSTR SrcPath, // BTRFS 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) BTRFS information
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
NTSTATUS LockStatus;
|
||||||
|
UNICODE_STRING Name;
|
||||||
|
IO_STATUS_BLOCK IoStatusBlock;
|
||||||
|
LARGE_INTEGER FileOffset;
|
||||||
|
PARTITION_INFORMATION_EX PartInfo;
|
||||||
|
BOOTCODE NewBootSector = {0};
|
||||||
|
|
||||||
|
/* Allocate and read the new bootsector from SrcPath */
|
||||||
|
RtlInitUnicodeString(&Name, SrcPath);
|
||||||
|
Status = ReadBootCodeFromFile(&NewBootSector,
|
||||||
|
&Name,
|
||||||
|
BTRFS_BOOTSECTOR_SIZE);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
return Status;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The BTRFS driver requires the volume to be locked in order to modify
|
||||||
|
* the first sectors of the partition, even though they are outside the
|
||||||
|
* file-system space / in the reserved area (they are situated before
|
||||||
|
* the super-block at 0x1000) and is in principle allowed by the NT
|
||||||
|
* storage stack.
|
||||||
|
* So we lock here in order to write the bootsector at sector 0.
|
||||||
|
* If locking fails, we ignore and continue nonetheless.
|
||||||
|
*/
|
||||||
|
LockStatus = NtFsControlFile(DstPath,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&IoStatusBlock,
|
||||||
|
FSCTL_LOCK_VOLUME,
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
0);
|
||||||
|
if (!NT_SUCCESS(LockStatus))
|
||||||
|
{
|
||||||
|
DPRINT1("WARNING: Failed to lock BTRFS volume for writing bootsector! Operations may fail! (Status 0x%lx)\n", LockStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Obtain partition info and write it to the bootsector */
|
||||||
|
Status = NtDeviceIoControlFile(RootPartition,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&IoStatusBlock,
|
||||||
|
IOCTL_DISK_GET_PARTITION_INFO_EX,
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
&PartInfo,
|
||||||
|
sizeof(PartInfo));
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("IOCTL_DISK_GET_PARTITION_INFO_EX failed (Status %lx)\n", Status);
|
||||||
|
goto Quit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write new bootsector to RootPath */
|
||||||
|
((PBTRFS_BOOTSECTOR)NewBootSector.BootCode)->PartitionStartLBA =
|
||||||
|
PartInfo.StartingOffset.QuadPart / SECTORSIZE;
|
||||||
|
|
||||||
|
/* 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:
|
||||||
|
/* Unlock the volume */
|
||||||
|
LockStatus = NtFsControlFile(DstPath,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&IoStatusBlock,
|
||||||
|
FSCTL_UNLOCK_VOLUME,
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
0);
|
||||||
|
if (!NT_SUCCESS(LockStatus))
|
||||||
|
{
|
||||||
|
DPRINT1("Failed to unlock BTRFS volume (Status 0x%lx)\n", LockStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free the new bootsector */
|
||||||
|
FreeBootCode(&NewBootSector);
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Formatting routines
|
// Formatting routines
|
||||||
//
|
//
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
|
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
|
||||||
* PURPOSE: Filesystem support functions
|
* PURPOSE: Filesystem support functions
|
||||||
* COPYRIGHT: Copyright 2003-2019 Casper S. Hornstrup (chorns@users.sourceforge.net)
|
* COPYRIGHT: Copyright 2003-2019 Casper S. Hornstrup (chorns@users.sourceforge.net)
|
||||||
* Copyright 2017-2019 Hermes Belusca-Maito
|
* Copyright 2017-2020 Hermes Belusca-Maito
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
@ -61,6 +61,42 @@ FormatFileSystem(
|
||||||
IN PFMIFSCALLBACK Callback);
|
IN PFMIFSCALLBACK Callback);
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Bootsector routines
|
||||||
|
//
|
||||||
|
|
||||||
|
#define FAT_BOOTSECTOR_SIZE (1 * SECTORSIZE)
|
||||||
|
#define FAT32_BOOTSECTOR_SIZE (1 * SECTORSIZE) // Counts only the primary sector.
|
||||||
|
#define BTRFS_BOOTSECTOR_SIZE (3 * SECTORSIZE)
|
||||||
|
|
||||||
|
typedef NTSTATUS
|
||||||
|
(/*NTAPI*/ *PFS_INSTALL_BOOTCODE)(
|
||||||
|
IN PCWSTR SrcPath, // 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) bootsector data information
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
InstallFat1216BootCode(
|
||||||
|
IN PCWSTR SrcPath,
|
||||||
|
IN HANDLE DstPath,
|
||||||
|
IN HANDLE RootPartition);
|
||||||
|
|
||||||
|
#define InstallFat12BootCode InstallFat1216BootCode
|
||||||
|
#define InstallFat16BootCode InstallFat1216BootCode
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
InstallFat32BootCode(
|
||||||
|
IN PCWSTR SrcPath,
|
||||||
|
IN HANDLE DstPath,
|
||||||
|
IN HANDLE RootPartition);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
InstallBtrfsBootCode(
|
||||||
|
IN PCWSTR SrcPath,
|
||||||
|
IN HANDLE DstPath,
|
||||||
|
IN HANDLE RootPartition);
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Formatting routines
|
// Formatting routines
|
||||||
//
|
//
|
||||||
|
|
|
@ -31,16 +31,17 @@ extern HANDLE ProcessHeap;
|
||||||
#include "utils/ntverrsrc.h"
|
#include "utils/ntverrsrc.h"
|
||||||
// #include "utils/arcname.h"
|
// #include "utils/arcname.h"
|
||||||
#include "utils/bldrsup.h"
|
#include "utils/bldrsup.h"
|
||||||
#include "bootsup.h"
|
|
||||||
#include "utils/filesup.h"
|
#include "utils/filesup.h"
|
||||||
#include "utils/fsrec.h"
|
#include "utils/fsrec.h"
|
||||||
#include "fsutil.h"
|
|
||||||
#include "utils/genlist.h"
|
#include "utils/genlist.h"
|
||||||
#include "utils/inicache.h"
|
#include "utils/inicache.h"
|
||||||
#include "utils/partlist.h"
|
#include "utils/partlist.h"
|
||||||
#include "utils/arcname.h"
|
#include "utils/arcname.h"
|
||||||
#include "utils/osdetect.h"
|
#include "utils/osdetect.h"
|
||||||
#include "utils/regutil.h"
|
#include "utils/regutil.h"
|
||||||
|
#include "bootcode.h"
|
||||||
|
#include "fsutil.h"
|
||||||
|
#include "bootsup.h"
|
||||||
#include "registry.h"
|
#include "registry.h"
|
||||||
#include "mui.h"
|
#include "mui.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
|
|
Loading…
Reference in a new issue