mirror of
https://github.com/reactos/reactos.git
synced 2026-06-02 09:20:43 +08:00
[FREELDR] Switch partition interface to using the more generic PARTITION_INFORMATION
instead of the MBR-specific PARTITION_TABLE_ENTRY structure. Simplify also some aspects of the code: - for MBR code, avoid copying around partition entries, but use pointers instead; - more generally, use the actual disk sector size instead of guessing, and pass it to the partition interface routines.
This commit is contained in:
@@ -87,9 +87,9 @@ DiskOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId)
|
||||
CONFIGURATION_TYPE DriveType;
|
||||
UCHAR DriveNumber;
|
||||
ULONG DrivePartition, SectorSize;
|
||||
ULONGLONG SectorOffset = 0;
|
||||
ULONGLONG SectorCount = 0;
|
||||
PARTITION_TABLE_ENTRY PartitionTableEntry;
|
||||
GEOMETRY Geometry;
|
||||
ULONGLONG SectorOffset;
|
||||
ULONGLONG SectorCount;
|
||||
|
||||
if (DiskReadBufferSize == 0)
|
||||
{
|
||||
@@ -102,38 +102,37 @@ DiskOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId)
|
||||
return EINVAL;
|
||||
|
||||
DriveType = DiskGetConfigType(DriveNumber);
|
||||
if (DriveType == CdromController)
|
||||
|
||||
if (!MachDiskGetDriveGeometry(DriveNumber, &Geometry))
|
||||
return EIO;
|
||||
if (Geometry.BytesPerSector == 0)
|
||||
{
|
||||
/* This is a CD-ROM device */
|
||||
SectorSize = 2048;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This is either a floppy disk or a hard disk device, but it doesn't
|
||||
* matter which one because they both have 512 bytes per sector */
|
||||
SectorSize = 512;
|
||||
WARN("MachDiskGetDriveGeometry(0x%x) failed, fall back to hardcoded values\n", DriveNumber);
|
||||
if (DriveType == CdromController)
|
||||
{
|
||||
/* This is a CD-ROM device */
|
||||
Geometry.BytesPerSector = 2048;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This is either a floppy disk or a hard disk device, but it doesn't
|
||||
* matter which one because they both have 512 bytes per sector */
|
||||
Geometry.BytesPerSector = 512;
|
||||
}
|
||||
}
|
||||
SectorSize = Geometry.BytesPerSector;
|
||||
|
||||
if (DrivePartition != 0xff && DrivePartition != 0)
|
||||
{
|
||||
if (!DiskGetPartitionEntry(DriveNumber, DrivePartition, &PartitionTableEntry))
|
||||
return EINVAL;
|
||||
PARTITION_INFORMATION PartitionEntry;
|
||||
if (!DiskGetPartitionEntry(DriveNumber, SectorSize, DrivePartition, &PartitionEntry))
|
||||
return EIO;
|
||||
|
||||
SectorOffset = PartitionTableEntry.SectorCountBeforePartition;
|
||||
SectorCount = PartitionTableEntry.PartitionSectorCount;
|
||||
SectorOffset = PartitionEntry.StartingOffset.QuadPart / SectorSize;
|
||||
SectorCount = PartitionEntry.PartitionLength.QuadPart / SectorSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
GEOMETRY Geometry;
|
||||
if (!MachDiskGetDriveGeometry(DriveNumber, &Geometry))
|
||||
return EINVAL;
|
||||
|
||||
if (SectorSize != Geometry.BytesPerSector)
|
||||
{
|
||||
ERR("SectorSize (%lu) != Geometry.BytesPerSector (%lu), expect problems!\n",
|
||||
SectorSize, Geometry.BytesPerSector);
|
||||
}
|
||||
|
||||
SectorOffset = 0;
|
||||
SectorCount = Geometry.Sectors;
|
||||
}
|
||||
@@ -202,7 +201,7 @@ DiskRead(ULONG FileId, VOID* Buffer, ULONG N, ULONG* Count)
|
||||
*Count = (ULONG)((ULONG_PTR)Ptr - (ULONG_PTR)Buffer);
|
||||
Context->SectorNumber = SectorOffset - Context->SectorOffset;
|
||||
|
||||
return (!ret) ? EIO : ESUCCESS;
|
||||
return (ret ? ESUCCESS : EIO);
|
||||
}
|
||||
|
||||
static ARC_STATUS
|
||||
@@ -406,11 +405,9 @@ DiskGetBootPath(
|
||||
}
|
||||
else
|
||||
{
|
||||
ULONG BootPartition;
|
||||
PARTITION_TABLE_ENTRY PartitionEntry;
|
||||
|
||||
/* This is a hard disk, find the boot partition */
|
||||
if (!DiskGetBootPartitionEntry(FrldrBootDrive, &PartitionEntry, &BootPartition))
|
||||
ULONG BootPartition;
|
||||
if (!DiskGetBootPartitionEntry(FrldrBootDrive, NULL, &BootPartition))
|
||||
{
|
||||
ERR("Failed to get boot partition entry\n");
|
||||
return FALSE;
|
||||
|
||||
@@ -57,6 +57,8 @@ IoSetPartitionInformation(
|
||||
}
|
||||
|
||||
#ifndef _M_AMD64
|
||||
#include "disk/part_mbr.h" // For PARTITION_TABLE_ENTRY and MASTER_BOOT_RECORD
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
IopReadBootRecord(
|
||||
@@ -203,7 +205,7 @@ IoReadPartitionTable(
|
||||
*PartitionBuffer = Partitions;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
#endif // _M_AMD64
|
||||
#endif // !_M_AMD64
|
||||
|
||||
NTSTATUS
|
||||
FASTCALL
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* PROJECT: FreeLoader UEFI Support
|
||||
* LICENSE: MIT (https://spdx.org/licenses/MIT)
|
||||
* PURPOSE: Disk Access Functions
|
||||
* COPYRIGHT: Copyright 2022 Justin Miller <justinmiller100@gmail.com>
|
||||
* COPYRIGHT: Copyright 2022-2026 Justin Miller <justin.miller@reactos.org>
|
||||
*/
|
||||
|
||||
/* INCLUDES ******************************************************************/
|
||||
@@ -169,16 +169,17 @@ DiskReadGptHeader(
|
||||
static
|
||||
BOOLEAN
|
||||
UefiGetBootPartitionEntry(
|
||||
IN UCHAR DriveNumber,
|
||||
OUT PPARTITION_TABLE_ENTRY PartitionTableEntry,
|
||||
OUT PULONG BootPartition)
|
||||
_In_ UCHAR DriveNumber,
|
||||
_Out_opt_ PPARTITION_INFORMATION PartitionEntry,
|
||||
_Out_ PULONG BootPartition)
|
||||
{
|
||||
ULONG PartitionNum;
|
||||
ULONG ArcDriveIndex;
|
||||
EFI_BLOCK_IO* BootBlockIo;
|
||||
EFI_STATUS Status;
|
||||
ULONG BlockSize;
|
||||
ULONGLONG BootPartitionSize;
|
||||
PARTITION_TABLE_ENTRY TempPartitionEntry;
|
||||
PARTITION_INFORMATION TempPartitionEntry;
|
||||
|
||||
TRACE("UefiGetBootPartitionEntry: DriveNumber: %d\n", DriveNumber - FIRST_BIOS_DISK);
|
||||
|
||||
@@ -206,16 +207,25 @@ UefiGetBootPartitionEntry(
|
||||
BootPartitionSize = BootBlockIo->Media->LastBlock + 1;
|
||||
|
||||
TRACE("Boot partition: Size=%llu blocks, BlockSize=%lu\n",
|
||||
BootPartitionSize, BootBlockIo->Media->BlockSize);
|
||||
BootPartitionSize, BootBlockIo->Media->BlockSize);
|
||||
|
||||
/* If boot handle is the root device itself (not a logical partition) */
|
||||
if (!BootBlockIo->Media->LogicalPartition)
|
||||
{
|
||||
TRACE("Boot handle is root device, using partition 0\n");
|
||||
*BootPartition = 0;
|
||||
if (PartitionTableEntry != NULL)
|
||||
if (PartitionEntry)
|
||||
{
|
||||
RtlZeroMemory(PartitionTableEntry, sizeof(*PartitionTableEntry));
|
||||
// RtlZeroMemory(PartitionEntry, sizeof(*PartitionEntry));
|
||||
/* Represent the whole disk */
|
||||
PartitionEntry->StartingOffset.QuadPart = 0ULL;
|
||||
PartitionEntry->PartitionLength.QuadPart = (BootPartitionSize * BootBlockIo->Media->BlockSize);
|
||||
PartitionEntry->HiddenSectors = 0;
|
||||
PartitionEntry->PartitionNumber = *BootPartition;
|
||||
PartitionEntry->PartitionType = PARTITION_GPT; /* Mark as GPT partition */
|
||||
PartitionEntry->BootIndicator = TRUE;
|
||||
PartitionEntry->RecognizedPartition = TRUE;
|
||||
PartitionEntry->RewritePartition = FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
@@ -228,14 +238,11 @@ UefiGetBootPartitionEntry(
|
||||
{
|
||||
/* For GPT, iterate through GPT partition entries */
|
||||
GPT_PARTITION_ENTRY GptEntry;
|
||||
ULONG ArcDriveIndex = DriveNumber - FIRST_BIOS_DISK;
|
||||
EFI_BLOCK_IO* RootBlockIo;
|
||||
ULONG BlockSize;
|
||||
ULONGLONG EntryLba;
|
||||
ULONG EntryOffset;
|
||||
ULONG EntriesPerBlock;
|
||||
EFI_STATUS Status;
|
||||
EFI_GUID UnusedGuid = EFI_PART_TYPE_UNUSED_GUID;
|
||||
EFI_GUID SystemGuid = EFI_PART_TYPE_EFI_SYSTEM_PART_GUID;
|
||||
|
||||
Status = GlobalSystemTable->BootServices->HandleProtocol(
|
||||
InternalUefiDisk[ArcDriveIndex].Handle,
|
||||
@@ -251,8 +258,8 @@ UefiGetBootPartitionEntry(
|
||||
/* Iterate through GPT partition entries */
|
||||
for (ULONG i = 0; i < GptHeader.NumberOfPartitionEntries; i++)
|
||||
{
|
||||
EntryLba = GptHeader.PartitionEntryLba + (i / EntriesPerBlock);
|
||||
EntryOffset = (i % EntriesPerBlock) * GptHeader.SizeOfPartitionEntry;
|
||||
ULONGLONG EntryLba = GptHeader.PartitionEntryLba + (i / EntriesPerBlock);
|
||||
ULONG EntryOffset = (i % EntriesPerBlock) * GptHeader.SizeOfPartitionEntry;
|
||||
|
||||
/* Read the block containing the partition entry */
|
||||
Status = RootBlockIo->ReadBlocks(
|
||||
@@ -276,28 +283,30 @@ UefiGetBootPartitionEntry(
|
||||
ULONGLONG PartitionSizeBlocks = GptEntry.EndingLba - GptEntry.StartingLba + 1;
|
||||
|
||||
TRACE("GPT Partition %lu: StartLba=%llu, EndLba=%llu, SizeBlocks=%llu\n",
|
||||
i + 1, GptEntry.StartingLba, GptEntry.EndingLba, PartitionSizeBlocks);
|
||||
i + 1, GptEntry.StartingLba, GptEntry.EndingLba, PartitionSizeBlocks);
|
||||
|
||||
/* Match partition by size (within 1 block tolerance for rounding) */
|
||||
if (PartitionSizeBlocks == BootPartitionSize ||
|
||||
(PartitionSizeBlocks > 0 &&
|
||||
(PartitionSizeBlocks > 0 &&
|
||||
(PartitionSizeBlocks - 1 <= BootPartitionSize &&
|
||||
BootPartitionSize <= PartitionSizeBlocks + 1)))
|
||||
{
|
||||
TRACE("Found matching GPT partition %lu: Size matches (%llu blocks)\n",
|
||||
i + 1, BootPartitionSize);
|
||||
i + 1, BootPartitionSize);
|
||||
|
||||
*BootPartition = i + 1; /* GPT partitions are 1-indexed */
|
||||
|
||||
/* Convert GPT entry to MBR-style entry for compatibility */
|
||||
if (PartitionTableEntry != NULL)
|
||||
/* Convert GPT entry to standard-style entry */
|
||||
if (PartitionEntry)
|
||||
{
|
||||
RtlZeroMemory(PartitionTableEntry, sizeof(*PartitionTableEntry));
|
||||
ULONGLONG StartSector = (GptEntry.StartingLba * BlockSize) / 512;
|
||||
ULONGLONG SectorCount = (PartitionSizeBlocks * BlockSize) / 512;
|
||||
PartitionTableEntry->SectorCountBeforePartition = (ULONG)StartSector;
|
||||
PartitionTableEntry->PartitionSectorCount = (ULONG)SectorCount;
|
||||
PartitionTableEntry->SystemIndicator = PARTITION_GPT;
|
||||
PartitionEntry->StartingOffset.QuadPart = (GptEntry.StartingLba * BlockSize);
|
||||
PartitionEntry->PartitionLength.QuadPart = ((ULONGLONG)PartitionSizeBlocks * BlockSize);
|
||||
PartitionEntry->HiddenSectors = 0;
|
||||
PartitionEntry->PartitionNumber = *BootPartition;
|
||||
PartitionEntry->PartitionType = PARTITION_GPT; /* Mark as GPT partition */
|
||||
PartitionEntry->BootIndicator = RtlEqualMemory(&GptEntry.PartitionTypeGuid, &SystemGuid, sizeof(SystemGuid));
|
||||
PartitionEntry->RecognizedPartition = TRUE;
|
||||
PartitionEntry->RewritePartition = FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
@@ -306,36 +315,32 @@ UefiGetBootPartitionEntry(
|
||||
else
|
||||
{
|
||||
/* MBR partition matching */
|
||||
|
||||
BlockSize = BootBlockIo->Media->BlockSize;
|
||||
|
||||
PartitionNum = FIRST_PARTITION;
|
||||
while (DiskGetPartitionEntry(DriveNumber, PartitionNum, &TempPartitionEntry))
|
||||
while (DiskGetPartitionEntry(DriveNumber, BlockSize, PartitionNum, &TempPartitionEntry))
|
||||
{
|
||||
ULONGLONG PartitionSizeSectors = TempPartitionEntry.PartitionSectorCount;
|
||||
ULONGLONG PartitionSizeBlocks;
|
||||
/* Convert partition size to UEFI blocks */
|
||||
ULONGLONG PartitionSizeBlocks = TempPartitionEntry.PartitionLength.QuadPart / BlockSize;
|
||||
ULONGLONG StartingLba = TempPartitionEntry.StartingOffset.QuadPart / BlockSize;
|
||||
ULONGLONG EndingLba = StartingLba + PartitionSizeBlocks - 1;
|
||||
|
||||
/* Convert partition size from MBR sectors (always 512 bytes) to UEFI blocks.
|
||||
* MBR partition table always uses 512-byte sectors per specification.
|
||||
* UEFI Block I/O protocol reports sizes in device's BlockSize bytes. */
|
||||
/* Compare in bytes to avoid rounding issues, then convert to boot partition's block size */
|
||||
ULONGLONG PartitionSizeBytes = PartitionSizeSectors * 512ULL;
|
||||
PartitionSizeBlocks = PartitionSizeBytes / BootBlockIo->Media->BlockSize;
|
||||
|
||||
TRACE("Partition %lu: SizeSectors=%llu, SizeBlocks=%llu\n",
|
||||
PartitionNum, PartitionSizeSectors, PartitionSizeBlocks);
|
||||
TRACE("Partition %lu: StartLba=%llu, EndLba=%llu, SizeBlocks=%llu\n",
|
||||
PartitionNum, StartingLba, EndingLba, PartitionSizeBlocks);
|
||||
|
||||
/* Match partition by size (within 1 block tolerance for rounding) */
|
||||
if (PartitionSizeBlocks == BootPartitionSize ||
|
||||
(PartitionSizeBlocks > 0 &&
|
||||
(PartitionSizeBlocks > 0 &&
|
||||
(PartitionSizeBlocks - 1 <= BootPartitionSize &&
|
||||
BootPartitionSize <= PartitionSizeBlocks + 1)))
|
||||
{
|
||||
TRACE("Found matching partition %lu: Size matches (%llu blocks)\n",
|
||||
PartitionNum, BootPartitionSize);
|
||||
PartitionNum, BootPartitionSize);
|
||||
|
||||
*BootPartition = PartitionNum;
|
||||
if (PartitionTableEntry != NULL)
|
||||
{
|
||||
RtlCopyMemory(PartitionTableEntry, &TempPartitionEntry, sizeof(*PartitionTableEntry));
|
||||
}
|
||||
if (PartitionEntry)
|
||||
RtlCopyMemory(PartitionEntry, &TempPartitionEntry, sizeof(*PartitionEntry));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -348,9 +353,18 @@ UefiGetBootPartitionEntry(
|
||||
{
|
||||
TRACE("Boot device is CD-ROM, using partition 0xFF\n");
|
||||
*BootPartition = 0xFF;
|
||||
if (PartitionTableEntry != NULL)
|
||||
if (PartitionEntry)
|
||||
{
|
||||
RtlZeroMemory(PartitionTableEntry, sizeof(*PartitionTableEntry));
|
||||
// RtlZeroMemory(PartitionEntry, sizeof(*PartitionEntry));
|
||||
/* Represent the whole disk */
|
||||
PartitionEntry->StartingOffset.QuadPart = 0ULL;
|
||||
PartitionEntry->PartitionLength.QuadPart = (BootPartitionSize * BootBlockIo->Media->BlockSize);
|
||||
PartitionEntry->HiddenSectors = 0;
|
||||
PartitionEntry->PartitionNumber = *BootPartition;
|
||||
PartitionEntry->PartitionType = PARTITION_GPT; /* Mark as GPT partition */
|
||||
PartitionEntry->BootIndicator = TRUE;
|
||||
PartitionEntry->RecognizedPartition = TRUE;
|
||||
PartitionEntry->RewritePartition = FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
@@ -358,13 +372,12 @@ UefiGetBootPartitionEntry(
|
||||
/* Fallback: if we can't determine, use partition 1 */
|
||||
ERR("Could not determine boot partition, using partition 1 as fallback\n");
|
||||
PartitionNum = FIRST_PARTITION;
|
||||
if (DiskGetPartitionEntry(DriveNumber, PartitionNum, &TempPartitionEntry))
|
||||
if (DiskGetPartitionEntry(DriveNumber, BootBlockIo->Media->BlockSize,
|
||||
PartitionNum, &TempPartitionEntry))
|
||||
{
|
||||
*BootPartition = PartitionNum;
|
||||
if (PartitionTableEntry != NULL)
|
||||
{
|
||||
RtlCopyMemory(PartitionTableEntry, &TempPartitionEntry, sizeof(*PartitionTableEntry));
|
||||
}
|
||||
if (PartitionEntry)
|
||||
RtlCopyMemory(PartitionEntry, &TempPartitionEntry, sizeof(*PartitionEntry));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -409,10 +422,9 @@ UefiDiskOpen(CHAR *Path, OPENMODE OpenMode, ULONG *FileId)
|
||||
DISKCONTEXT* Context;
|
||||
UCHAR DriveNumber;
|
||||
ULONG DrivePartition, SectorSize;
|
||||
ULONGLONG SectorOffset = 0;
|
||||
ULONGLONG SectorCount = 0;
|
||||
ULONGLONG SectorOffset;
|
||||
ULONGLONG SectorCount;
|
||||
ULONG ArcDriveIndex;
|
||||
PARTITION_TABLE_ENTRY PartitionTableEntry;
|
||||
EFI_BLOCK_IO* BlockIo;
|
||||
EFI_STATUS Status;
|
||||
|
||||
@@ -453,33 +465,29 @@ UefiDiskOpen(CHAR *Path, OPENMODE OpenMode, ULONG *FileId)
|
||||
if (!BlockIo->Media->MediaPresent)
|
||||
{
|
||||
ERR("Media not present for drive %d\n", DriveNumber);
|
||||
return EINVAL;
|
||||
return ENXIO;
|
||||
}
|
||||
|
||||
#if 0
|
||||
GEOMETRY Geometry;
|
||||
if (!MachDiskGetDriveGeometry(DriveNumber, &Geometry))
|
||||
return EIO;
|
||||
#endif
|
||||
SectorSize = BlockIo->Media->BlockSize;
|
||||
|
||||
if (DrivePartition != 0xff && DrivePartition != 0)
|
||||
{
|
||||
if (!DiskGetPartitionEntry(DriveNumber, DrivePartition, &PartitionTableEntry))
|
||||
return EINVAL;
|
||||
PARTITION_INFORMATION PartitionEntry;
|
||||
if (!DiskGetPartitionEntry(DriveNumber, SectorSize, DrivePartition, &PartitionEntry))
|
||||
return EIO;
|
||||
|
||||
SectorOffset = PartitionTableEntry.SectorCountBeforePartition;
|
||||
SectorCount = PartitionTableEntry.PartitionSectorCount;
|
||||
SectorOffset = PartitionEntry.StartingOffset.QuadPart / SectorSize;
|
||||
SectorCount = PartitionEntry.PartitionLength.QuadPart / SectorSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
GEOMETRY Geometry;
|
||||
if (!MachDiskGetDriveGeometry(DriveNumber, &Geometry))
|
||||
return EINVAL;
|
||||
|
||||
if (SectorSize != Geometry.BytesPerSector)
|
||||
{
|
||||
ERR("SectorSize (%lu) != Geometry.BytesPerSector (%lu), expect problems!\n",
|
||||
SectorSize, Geometry.BytesPerSector);
|
||||
}
|
||||
|
||||
SectorOffset = 0;
|
||||
SectorCount = Geometry.Sectors;
|
||||
SectorCount = BlockIo->Media->LastBlock + 1; // Geometry.Sectors;
|
||||
}
|
||||
|
||||
Context = FrLdrTempAlloc(sizeof(DISKCONTEXT), TAG_HW_DISK_CONTEXT);
|
||||
@@ -492,6 +500,7 @@ UefiDiskOpen(CHAR *Path, OPENMODE OpenMode, ULONG *FileId)
|
||||
Context->SectorCount = SectorCount;
|
||||
Context->SectorNumber = 0;
|
||||
FsSetDeviceSpecific(*FileId, Context);
|
||||
|
||||
return ESUCCESS;
|
||||
}
|
||||
|
||||
@@ -998,7 +1007,6 @@ UefiSetBootpath(VOID)
|
||||
else
|
||||
{
|
||||
ULONG BootPartition;
|
||||
PARTITION_TABLE_ENTRY PartitionEntry;
|
||||
|
||||
/* This is a hard disk */
|
||||
/* If boot handle is a logical partition, we need to determine which partition number */
|
||||
@@ -1013,7 +1021,7 @@ UefiSetBootpath(VOID)
|
||||
else
|
||||
{
|
||||
/* Boot handle is the root device itself */
|
||||
if (!UefiGetBootPartitionEntry(FrldrBootDrive, &PartitionEntry, &BootPartition))
|
||||
if (!UefiGetBootPartitionEntry(FrldrBootDrive, NULL, &BootPartition))
|
||||
{
|
||||
ERR("Failed to get boot partition entry\n");
|
||||
return FALSE;
|
||||
|
||||
@@ -13,7 +13,8 @@
|
||||
#include <debug.h>
|
||||
DBG_DEFAULT_CHANNEL(DISK);
|
||||
|
||||
#include "disk/part_gpt.h"
|
||||
#include "part_mbr.h" // FIXME: For MASTER_BOOT_RECORD
|
||||
#include "part_gpt.h"
|
||||
|
||||
// Defined in part_gpt.c
|
||||
extern BOOLEAN
|
||||
@@ -85,30 +86,34 @@ DiskInitialize(
|
||||
{
|
||||
PMASTER_BOOT_RECORD Mbr;
|
||||
PULONG Buffer;
|
||||
GEOMETRY Geometry;
|
||||
ULONGLONG SectorStart;
|
||||
ULONG SectorSize;
|
||||
ULONG MbrSectorSize;
|
||||
ULONG i;
|
||||
ULONG Checksum, Signature;
|
||||
BOOLEAN ValidPartitionTable;
|
||||
BOOLEAN IsCdRom;
|
||||
PGUID GptDiskGuid = NULL;
|
||||
GPT_TABLE_HEADER GptHeader;
|
||||
PARTITION_TABLE_ENTRY PartitionTableEntry;
|
||||
PARTITION_INFORMATION PartitionEntry;
|
||||
CHAR ArcName[MAX_PATH];
|
||||
NTSTATUS NtStatus;
|
||||
|
||||
TRACE("DiskInitialize(0x%02X, '%s', Type: %lu)\n", DriveNumber, DeviceName, DeviceType);
|
||||
|
||||
if (!MachDiskGetDriveGeometry(DriveNumber, &Geometry))
|
||||
return FALSE;
|
||||
|
||||
IsCdRom = (DeviceType == CdromController);
|
||||
if (IsCdRom)
|
||||
{
|
||||
SectorStart = 16ULL;
|
||||
SectorSize = 2048;
|
||||
MbrSectorSize = 2048;
|
||||
}
|
||||
else // (DeviceType == FloppyDiskPeripheral || DiskPeripheral)
|
||||
{
|
||||
SectorStart = 0ULL;
|
||||
SectorSize = 512;
|
||||
MbrSectorSize = 512;
|
||||
}
|
||||
|
||||
/* Read the MBR */
|
||||
@@ -126,7 +131,7 @@ DiskInitialize(
|
||||
|
||||
/* Calculate the MBR checksum */
|
||||
Checksum = 0;
|
||||
for (i = 0; i < SectorSize / sizeof(ULONG); i++)
|
||||
for (i = 0; i < MbrSectorSize / sizeof(ULONG); i++)
|
||||
{
|
||||
Checksum += Buffer[i];
|
||||
}
|
||||
@@ -185,9 +190,9 @@ DiskInitialize(
|
||||
|
||||
/* Add partitions */
|
||||
i = FIRST_PARTITION;
|
||||
while (DiskGetPartitionEntry(DriveNumber, i, &PartitionTableEntry))
|
||||
while (DiskGetPartitionEntry(DriveNumber, Geometry.BytesPerSector, i, &PartitionEntry))
|
||||
{
|
||||
if (PartitionTableEntry.SystemIndicator != PARTITION_ENTRY_UNUSED)
|
||||
if (PartitionEntry.PartitionType != PARTITION_ENTRY_UNUSED)
|
||||
{
|
||||
NtStatus = RtlStringCbPrintfA(ArcName, sizeof(ArcName),
|
||||
"%spartition(%lu)", DeviceName, i);
|
||||
|
||||
@@ -18,9 +18,9 @@
|
||||
|
||||
static struct
|
||||
{
|
||||
ULONG SectorCountBeforePartition;
|
||||
ULONG PartitionSectorCount;
|
||||
UCHAR SystemIndicator;
|
||||
ULONG SectorStart;
|
||||
ULONG SectorCount;
|
||||
UCHAR PartitionType;
|
||||
} XboxPartitions[] =
|
||||
{
|
||||
/* This is in the \Device\Harddisk0\Partition.. order used by the Xbox kernel */
|
||||
@@ -31,33 +31,45 @@ static struct
|
||||
{ 0x002EE400, 0x00177000, PARTITION_FAT_16 } /* Cache3, Z: */
|
||||
};
|
||||
|
||||
static BOOLEAN
|
||||
DiskIsBrfr(
|
||||
_In_ UCHAR DriveNumber)
|
||||
{
|
||||
/* Read the Xbox-specific sector */
|
||||
if (!MachDiskReadLogicalSectors(DriveNumber, XBOX_SIGNATURE_SECTOR, 1, DiskReadBuffer))
|
||||
return FALSE; /* Partition does not exist */
|
||||
|
||||
/* Verify the magic Xbox signature */
|
||||
return (*((PULONG)DiskReadBuffer) == XBOX_SIGNATURE);
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
DiskGetBrfrPartitionEntry(
|
||||
IN UCHAR DriveNumber,
|
||||
IN ULONG PartitionNumber,
|
||||
OUT PPARTITION_TABLE_ENTRY PartitionTableEntry)
|
||||
_In_ UCHAR DriveNumber,
|
||||
_In_ ULONG SectorSize,
|
||||
_In_ ULONG PartitionNumber,
|
||||
_Out_ PPARTITION_INFORMATION PartitionEntry)
|
||||
{
|
||||
/*
|
||||
* Get partition entry of an Xbox-standard BRFR partitioned disk.
|
||||
*/
|
||||
if (PartitionNumber >= 1 && PartitionNumber <= RTL_NUMBER_OF(XboxPartitions) &&
|
||||
MachDiskReadLogicalSectors(DriveNumber, XBOX_SIGNATURE_SECTOR, 1, DiskReadBuffer))
|
||||
{
|
||||
if (*((PULONG)DiskReadBuffer) != XBOX_SIGNATURE)
|
||||
{
|
||||
/* No magic Xbox partitions */
|
||||
return FALSE;
|
||||
}
|
||||
ASSERT(SectorSize >= 512);
|
||||
|
||||
RtlZeroMemory(PartitionTableEntry, sizeof(PARTITION_TABLE_ENTRY));
|
||||
PartitionTableEntry->SystemIndicator = XboxPartitions[PartitionNumber - 1].SystemIndicator;
|
||||
PartitionTableEntry->SectorCountBeforePartition = XboxPartitions[PartitionNumber - 1].SectorCountBeforePartition;
|
||||
PartitionTableEntry->PartitionSectorCount = XboxPartitions[PartitionNumber - 1].PartitionSectorCount;
|
||||
return TRUE;
|
||||
}
|
||||
if (!DiskIsBrfr(DriveNumber))
|
||||
return FALSE; /* No magic Xbox partitions */
|
||||
|
||||
/* Partition does not exist */
|
||||
return FALSE;
|
||||
/* Get partition entry of an Xbox-standard BRFR partitioned disk */
|
||||
if (!(1 <= PartitionNumber && PartitionNumber <= RTL_NUMBER_OF(XboxPartitions)))
|
||||
return FALSE; /* Partition does not exist */
|
||||
|
||||
/* Convert to standard-style entry */
|
||||
PartitionEntry->StartingOffset.QuadPart = (ULONGLONG)XboxPartitions[PartitionNumber - 1].SectorStart * SectorSize;
|
||||
PartitionEntry->PartitionLength.QuadPart = (ULONGLONG)XboxPartitions[PartitionNumber - 1].SectorCount * SectorSize;
|
||||
PartitionEntry->HiddenSectors = 0;
|
||||
PartitionEntry->PartitionNumber = PartitionNumber;
|
||||
PartitionEntry->PartitionType = XboxPartitions[PartitionNumber - 1].PartitionType;
|
||||
PartitionEntry->BootIndicator = (PartitionNumber == FATX_DATA_PARTITION);
|
||||
PartitionEntry->RecognizedPartition = TRUE;
|
||||
PartitionEntry->RewritePartition = FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -45,34 +45,33 @@ DiskReadGptHeader(
|
||||
BOOLEAN
|
||||
DiskGetGptPartitionEntry(
|
||||
_In_ UCHAR DriveNumber,
|
||||
_In_ ULONG SectorSize, // BlockSize
|
||||
_In_ ULONG PartitionNumber,
|
||||
_Out_ PPARTITION_TABLE_ENTRY PartitionTableEntry)
|
||||
_Out_ PPARTITION_INFORMATION PartitionEntry)
|
||||
{
|
||||
GPT_TABLE_HEADER GptHeader;
|
||||
GPT_PARTITION_ENTRY GptEntry;
|
||||
GEOMETRY Geometry;
|
||||
ULONG BlockSize;
|
||||
ULONGLONG EntryLba;
|
||||
ULONG EntryOffset;
|
||||
ULONG EntriesPerBlock;
|
||||
GUID UnusedGuid = EFI_PART_TYPE_UNUSED_GUID;
|
||||
GUID SystemGuid = EFI_PART_TYPE_EFI_SYSTEM_PART_GUID;
|
||||
|
||||
if (!MachDiskGetDriveGeometry(DriveNumber, &Geometry))
|
||||
return FALSE;
|
||||
BlockSize = Geometry.BytesPerSector;
|
||||
ASSERT(SectorSize >= 512);
|
||||
|
||||
/* Read GPT header */
|
||||
if (!DiskReadGptHeader(DriveNumber, &GptHeader))
|
||||
return FALSE;
|
||||
|
||||
/* Validate partition number */
|
||||
if (PartitionNumber == 0 || PartitionNumber > GptHeader.NumberOfPartitionEntries)
|
||||
//if (PartitionNumber == 0 || PartitionNumber > GptHeader.NumberOfPartitionEntries)
|
||||
if (!(1 <= PartitionNumber && PartitionNumber <= GptHeader.NumberOfPartitionEntries))
|
||||
return FALSE;
|
||||
|
||||
/* Convert to 0-based index */
|
||||
ULONG EntryIndex = PartitionNumber - 1;
|
||||
|
||||
EntriesPerBlock = BlockSize / GptHeader.SizeOfPartitionEntry;
|
||||
EntriesPerBlock = SectorSize / GptHeader.SizeOfPartitionEntry;
|
||||
EntryLba = GptHeader.PartitionEntryLba + (EntryIndex / EntriesPerBlock);
|
||||
EntryOffset = (EntryIndex % EntriesPerBlock) * GptHeader.SizeOfPartitionEntry;
|
||||
|
||||
@@ -87,20 +86,18 @@ DiskGetGptPartitionEntry(
|
||||
if (RtlEqualMemory(&GptEntry.PartitionTypeGuid, &UnusedGuid, sizeof(UnusedGuid)))
|
||||
return FALSE;
|
||||
|
||||
/* Convert GPT entry to MBR-style PARTITION_TABLE_ENTRY */
|
||||
RtlZeroMemory(PartitionTableEntry, sizeof(*PartitionTableEntry));
|
||||
/* Calculate partition size in blocks */
|
||||
ULONGLONG PartitionSizeBlocks = GptEntry.EndingLba - GptEntry.StartingLba + 1;
|
||||
|
||||
/* Calculate sector offset and count.
|
||||
* GPT uses LBA, convert to 512-byte sectors. */
|
||||
ULONGLONG SectorCount = (GptEntry.EndingLba - GptEntry.StartingLba + 1);
|
||||
|
||||
/* For GPT, we need to convert from device block size to 512-byte sectors */
|
||||
ULONGLONG StartSector = (GptEntry.StartingLba * BlockSize) / 512;
|
||||
ULONGLONG SectorCount512 = (SectorCount * BlockSize) / 512;
|
||||
|
||||
PartitionTableEntry->SectorCountBeforePartition = (ULONG)StartSector;
|
||||
PartitionTableEntry->PartitionSectorCount = (ULONG)SectorCount512;
|
||||
PartitionTableEntry->SystemIndicator = PARTITION_GPT; /* Mark as GPT partition */
|
||||
/* Convert GPT entry to standard-style entry */
|
||||
PartitionEntry->StartingOffset.QuadPart = (GptEntry.StartingLba * SectorSize);
|
||||
PartitionEntry->PartitionLength.QuadPart = (PartitionSizeBlocks * SectorSize);
|
||||
PartitionEntry->HiddenSectors = 0;
|
||||
PartitionEntry->PartitionNumber = PartitionNumber;
|
||||
PartitionEntry->PartitionType = PARTITION_GPT; /* Mark as GPT partition */
|
||||
PartitionEntry->BootIndicator = RtlEqualMemory(&GptEntry.PartitionTypeGuid, &SystemGuid, sizeof(SystemGuid));
|
||||
PartitionEntry->RecognizedPartition = TRUE;
|
||||
PartitionEntry->RewritePartition = FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
|
||||
static BOOLEAN
|
||||
DiskGetFirstPartitionEntry(
|
||||
IN PMASTER_BOOT_RECORD MasterBootRecord,
|
||||
OUT PPARTITION_TABLE_ENTRY PartitionTableEntry)
|
||||
_In_ PMASTER_BOOT_RECORD MasterBootRecord,
|
||||
_Out_ PPARTITION_TABLE_ENTRY* pPartitionTableEntry)
|
||||
{
|
||||
ULONG Index;
|
||||
|
||||
@@ -27,7 +27,7 @@ DiskGetFirstPartitionEntry(
|
||||
(MasterBootRecord->PartitionTable[Index].SystemIndicator != PARTITION_EXTENDED) &&
|
||||
(MasterBootRecord->PartitionTable[Index].SystemIndicator != PARTITION_XINT13_EXTENDED))
|
||||
{
|
||||
RtlCopyMemory(PartitionTableEntry, &MasterBootRecord->PartitionTable[Index], sizeof(PARTITION_TABLE_ENTRY));
|
||||
*pPartitionTableEntry = &MasterBootRecord->PartitionTable[Index];
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
@@ -37,8 +37,8 @@ DiskGetFirstPartitionEntry(
|
||||
|
||||
static BOOLEAN
|
||||
DiskGetFirstExtendedPartitionEntry(
|
||||
IN PMASTER_BOOT_RECORD MasterBootRecord,
|
||||
OUT PPARTITION_TABLE_ENTRY PartitionTableEntry)
|
||||
_In_ PMASTER_BOOT_RECORD MasterBootRecord,
|
||||
_Out_ PPARTITION_TABLE_ENTRY* pPartitionTableEntry)
|
||||
{
|
||||
ULONG Index;
|
||||
|
||||
@@ -48,7 +48,7 @@ DiskGetFirstExtendedPartitionEntry(
|
||||
if ((MasterBootRecord->PartitionTable[Index].SystemIndicator == PARTITION_EXTENDED) ||
|
||||
(MasterBootRecord->PartitionTable[Index].SystemIndicator == PARTITION_XINT13_EXTENDED))
|
||||
{
|
||||
RtlCopyMemory(PartitionTableEntry, &MasterBootRecord->PartitionTable[Index], sizeof(PARTITION_TABLE_ENTRY));
|
||||
*pPartitionTableEntry = &MasterBootRecord->PartitionTable[Index];
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
@@ -56,47 +56,66 @@ DiskGetFirstExtendedPartitionEntry(
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static VOID
|
||||
DiskMbrPartitionTableEntryToInformation(
|
||||
_Out_ PPARTITION_INFORMATION PartitionEntry,
|
||||
_In_ PPARTITION_TABLE_ENTRY PartitionTableEntry,
|
||||
_In_ ULONG PartitionNumber,
|
||||
_In_ ULONG SectorSize)
|
||||
{
|
||||
PartitionEntry->StartingOffset.QuadPart = (ULONGLONG)PartitionTableEntry->SectorCountBeforePartition * SectorSize;
|
||||
PartitionEntry->PartitionLength.QuadPart = (ULONGLONG)PartitionTableEntry->PartitionSectorCount * SectorSize;
|
||||
PartitionEntry->HiddenSectors = 0;
|
||||
PartitionEntry->PartitionNumber = PartitionNumber;
|
||||
PartitionEntry->PartitionType = PartitionTableEntry->SystemIndicator;
|
||||
PartitionEntry->BootIndicator = (PartitionTableEntry->BootIndicator == 0x80); // or "& 0x80"
|
||||
PartitionEntry->RecognizedPartition = TRUE;
|
||||
PartitionEntry->RewritePartition = FALSE;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
DiskGetActivePartitionEntry(
|
||||
IN UCHAR DriveNumber,
|
||||
OUT PPARTITION_TABLE_ENTRY PartitionTableEntry,
|
||||
OUT PULONG ActivePartition)
|
||||
_In_ UCHAR DriveNumber,
|
||||
_In_ ULONG SectorSize,
|
||||
_Out_opt_ PPARTITION_INFORMATION PartitionEntry,
|
||||
_Out_ PULONG ActivePartition)
|
||||
{
|
||||
MASTER_BOOT_RECORD MasterBootRecord;
|
||||
ULONG BootablePartitionCount = 0;
|
||||
ULONG CurrentPartitionNumber;
|
||||
ULONG Index;
|
||||
MASTER_BOOT_RECORD MasterBootRecord;
|
||||
PPARTITION_TABLE_ENTRY ThisPartitionTableEntry;
|
||||
|
||||
ASSERT(SectorSize >= 512);
|
||||
|
||||
*ActivePartition = 0;
|
||||
|
||||
/* Read master boot record */
|
||||
if (!DiskReadBootRecord(DriveNumber, 0, &MasterBootRecord))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
CurrentPartitionNumber = 0;
|
||||
for (Index = 0; Index < 4; Index++)
|
||||
{
|
||||
ThisPartitionTableEntry = &MasterBootRecord.PartitionTable[Index];
|
||||
PPARTITION_TABLE_ENTRY PartitionTableEntry = &MasterBootRecord.PartitionTable[Index];
|
||||
|
||||
if (ThisPartitionTableEntry->SystemIndicator != PARTITION_ENTRY_UNUSED &&
|
||||
ThisPartitionTableEntry->SystemIndicator != PARTITION_EXTENDED &&
|
||||
ThisPartitionTableEntry->SystemIndicator != PARTITION_XINT13_EXTENDED)
|
||||
if (PartitionTableEntry->SystemIndicator != PARTITION_ENTRY_UNUSED &&
|
||||
PartitionTableEntry->SystemIndicator != PARTITION_EXTENDED &&
|
||||
PartitionTableEntry->SystemIndicator != PARTITION_XINT13_EXTENDED)
|
||||
{
|
||||
CurrentPartitionNumber++;
|
||||
|
||||
/* Test if this is the bootable partition */
|
||||
if (ThisPartitionTableEntry->BootIndicator == 0x80)
|
||||
if (PartitionTableEntry->BootIndicator == 0x80)
|
||||
{
|
||||
BootablePartitionCount++;
|
||||
*ActivePartition = CurrentPartitionNumber;
|
||||
|
||||
/* Copy the partition table entry */
|
||||
RtlCopyMemory(PartitionTableEntry,
|
||||
ThisPartitionTableEntry,
|
||||
sizeof(PARTITION_TABLE_ENTRY));
|
||||
if (PartitionEntry)
|
||||
{
|
||||
DiskMbrPartitionTableEntryToInformation(PartitionEntry, PartitionTableEntry,
|
||||
*ActivePartition, SectorSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -118,39 +137,44 @@ DiskGetActivePartitionEntry(
|
||||
|
||||
BOOLEAN
|
||||
DiskGetMbrPartitionEntry(
|
||||
IN UCHAR DriveNumber,
|
||||
IN ULONG PartitionNumber,
|
||||
OUT PPARTITION_TABLE_ENTRY PartitionTableEntry)
|
||||
_In_ UCHAR DriveNumber,
|
||||
_In_ ULONG SectorSize,
|
||||
_In_ ULONG PartitionNumber,
|
||||
_Out_ PPARTITION_INFORMATION PartitionEntry)
|
||||
{
|
||||
MASTER_BOOT_RECORD MasterBootRecord;
|
||||
PARTITION_TABLE_ENTRY ExtendedPartitionTableEntry;
|
||||
PPARTITION_TABLE_ENTRY PartitionTableEntry;
|
||||
ULONG ExtendedPartitionNumber;
|
||||
ULONG ExtendedPartitionOffset;
|
||||
ULONG Index;
|
||||
ULONG CurrentPartitionNumber;
|
||||
PPARTITION_TABLE_ENTRY ThisPartitionTableEntry;
|
||||
|
||||
ASSERT(SectorSize >= 512);
|
||||
|
||||
/* Validate partition number */
|
||||
if (PartitionNumber < 1) //if (PartitionNumber == 0)
|
||||
return FALSE;
|
||||
|
||||
/* Read master boot record */
|
||||
if (!DiskReadBootRecord(DriveNumber, 0, &MasterBootRecord))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
CurrentPartitionNumber = 0;
|
||||
for (Index = 0; Index < 4; Index++)
|
||||
{
|
||||
ThisPartitionTableEntry = &MasterBootRecord.PartitionTable[Index];
|
||||
PartitionTableEntry = &MasterBootRecord.PartitionTable[Index];
|
||||
|
||||
if (ThisPartitionTableEntry->SystemIndicator != PARTITION_ENTRY_UNUSED &&
|
||||
ThisPartitionTableEntry->SystemIndicator != PARTITION_EXTENDED &&
|
||||
ThisPartitionTableEntry->SystemIndicator != PARTITION_XINT13_EXTENDED)
|
||||
if (PartitionTableEntry->SystemIndicator != PARTITION_ENTRY_UNUSED &&
|
||||
PartitionTableEntry->SystemIndicator != PARTITION_EXTENDED &&
|
||||
PartitionTableEntry->SystemIndicator != PARTITION_XINT13_EXTENDED)
|
||||
{
|
||||
CurrentPartitionNumber++;
|
||||
}
|
||||
|
||||
if (PartitionNumber == CurrentPartitionNumber)
|
||||
{
|
||||
RtlCopyMemory(PartitionTableEntry, ThisPartitionTableEntry, sizeof(PARTITION_TABLE_ENTRY));
|
||||
DiskMbrPartitionTableEntryToInformation(PartitionEntry, PartitionTableEntry,
|
||||
PartitionNumber, SectorSize);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
@@ -171,39 +195,38 @@ DiskGetMbrPartitionEntry(
|
||||
|
||||
for (Index = 0; Index <= ExtendedPartitionNumber; Index++)
|
||||
{
|
||||
PPARTITION_TABLE_ENTRY ExtendedPartitionTableEntry;
|
||||
ULONG SectorCountBeforePartition;
|
||||
|
||||
/* Get the extended partition table entry */
|
||||
if (!DiskGetFirstExtendedPartitionEntry(&MasterBootRecord, &ExtendedPartitionTableEntry))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Adjust the relative starting sector of the partition */
|
||||
ExtendedPartitionTableEntry.SectorCountBeforePartition += ExtendedPartitionOffset;
|
||||
ExtendedPartitionTableEntry->SectorCountBeforePartition += ExtendedPartitionOffset;
|
||||
if (ExtendedPartitionOffset == 0)
|
||||
{
|
||||
/* Set the start of the parrent extended partition */
|
||||
ExtendedPartitionOffset = ExtendedPartitionTableEntry.SectorCountBeforePartition;
|
||||
/* Set the start of the parent extended partition */
|
||||
ExtendedPartitionOffset = ExtendedPartitionTableEntry->SectorCountBeforePartition;
|
||||
}
|
||||
SectorCountBeforePartition = ExtendedPartitionTableEntry->SectorCountBeforePartition;
|
||||
|
||||
/* Read the partition boot record */
|
||||
if (!DiskReadBootRecord(DriveNumber, ExtendedPartitionTableEntry.SectorCountBeforePartition, &MasterBootRecord))
|
||||
{
|
||||
if (!DiskReadBootRecord(DriveNumber, SectorCountBeforePartition, &MasterBootRecord))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Get the first real partition table entry */
|
||||
if (!DiskGetFirstPartitionEntry(&MasterBootRecord, PartitionTableEntry))
|
||||
{
|
||||
if (!DiskGetFirstPartitionEntry(&MasterBootRecord, &PartitionTableEntry))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Now correct the start sector of the partition */
|
||||
PartitionTableEntry->SectorCountBeforePartition += ExtendedPartitionTableEntry.SectorCountBeforePartition;
|
||||
PartitionTableEntry->SectorCountBeforePartition += SectorCountBeforePartition;
|
||||
}
|
||||
|
||||
/*
|
||||
* When we get here we should have the correct entry already
|
||||
* stored in PartitionTableEntry, so just return TRUE.
|
||||
*/
|
||||
/* When we get here we should have the correct entry already
|
||||
* stored in PartitionTableEntry, so just return TRUE. */
|
||||
DiskMbrPartitionTableEntryToInformation(PartitionEntry, PartitionTableEntry,
|
||||
PartitionNumber, SectorSize);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
* PURPOSE: Block Device partition management
|
||||
* COPYRIGHT: Copyright 2002-2003 Brian Palmer <brianp@sginet.com>
|
||||
* Copyright 2019 Stanislav Motylkov <x86corez@gmail.com>
|
||||
* Copyright 2025-2026 Hermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
|
||||
*/
|
||||
|
||||
#ifndef _M_ARM
|
||||
@@ -16,6 +17,8 @@ DBG_DEFAULT_CHANNEL(DISK);
|
||||
#define MaxDriveNumber 0xFF
|
||||
static PARTITION_STYLE DiskPartitionType[MaxDriveNumber + 1];
|
||||
|
||||
#include "part_mbr.h" // FIXME: For MASTER_BOOT_RECORD
|
||||
|
||||
BOOLEAN
|
||||
DiskReadBootRecord(
|
||||
IN UCHAR DriveNumber,
|
||||
@@ -56,15 +59,14 @@ DiskReadBootRecord(
|
||||
}
|
||||
|
||||
#include "part_mbr.c"
|
||||
#include "part_brfr.c"
|
||||
#include "part_gpt.c"
|
||||
#include "part_brfr.c"
|
||||
|
||||
VOID
|
||||
DiskDetectPartitionType(
|
||||
IN UCHAR DriveNumber)
|
||||
_In_ UCHAR DriveNumber)
|
||||
{
|
||||
MASTER_BOOT_RECORD MasterBootRecord;
|
||||
PARTITION_TABLE_ENTRY PartitionTableEntry;
|
||||
|
||||
/* Probe for Master Boot Record */
|
||||
if (DiskReadBootRecord(DriveNumber, 0, &MasterBootRecord))
|
||||
@@ -82,17 +84,13 @@ DiskDetectPartitionType(
|
||||
/* Check for GUID Partition Table */
|
||||
for (Index = 0; Index < 4; Index++)
|
||||
{
|
||||
PPARTITION_TABLE_ENTRY ThisPartitionTableEntry;
|
||||
ThisPartitionTableEntry = &MasterBootRecord.PartitionTable[Index];
|
||||
PPARTITION_TABLE_ENTRY PartitionTableEntry = &MasterBootRecord.PartitionTable[Index];
|
||||
|
||||
if (ThisPartitionTableEntry->SystemIndicator != PARTITION_ENTRY_UNUSED)
|
||||
if (PartitionTableEntry->SystemIndicator != PARTITION_ENTRY_UNUSED)
|
||||
{
|
||||
PartitionCount++;
|
||||
|
||||
if (Index == 0 && ThisPartitionTableEntry->SystemIndicator == PARTITION_GPT)
|
||||
{
|
||||
if (Index == 0 && PartitionTableEntry->SystemIndicator == PARTITION_GPT)
|
||||
GPTProtect = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,14 +106,14 @@ DiskDetectPartitionType(
|
||||
}
|
||||
|
||||
/* Probe for Xbox-BRFR partitioning */
|
||||
if (DiskGetBrfrPartitionEntry(DriveNumber, FATX_DATA_PARTITION, &PartitionTableEntry))
|
||||
if (DiskIsBrfr(DriveNumber))
|
||||
{
|
||||
DiskPartitionType[DriveNumber] = PARTITION_STYLE_BRFR;
|
||||
TRACE("Drive 0x%X partition type Xbox-BRFR\n", DriveNumber);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Failed to detect partitions, assume partitionless disk */
|
||||
/* Failed to detect partitions, assume non-partitioned disk */
|
||||
DiskPartitionType[DriveNumber] = PARTITION_STYLE_RAW;
|
||||
TRACE("Drive 0x%X partition type unknown\n", DriveNumber);
|
||||
}
|
||||
@@ -123,15 +121,24 @@ DiskDetectPartitionType(
|
||||
// FIXME: This function is specific to BIOS-based PC platform.
|
||||
BOOLEAN
|
||||
DiskGetBootPartitionEntry(
|
||||
IN UCHAR DriveNumber,
|
||||
OUT PPARTITION_TABLE_ENTRY PartitionTableEntry,
|
||||
OUT PULONG BootPartition)
|
||||
_In_ UCHAR DriveNumber,
|
||||
_Out_opt_ PPARTITION_INFORMATION PartitionEntry,
|
||||
_Out_ PULONG BootPartition)
|
||||
{
|
||||
#if 0
|
||||
GEOMETRY Geometry;
|
||||
if (!MachDiskGetDriveGeometry(DriveNumber, &Geometry))
|
||||
return FALSE;
|
||||
#endif
|
||||
|
||||
switch (DiskPartitionType[DriveNumber])
|
||||
{
|
||||
case PARTITION_STYLE_MBR:
|
||||
{
|
||||
return DiskGetActivePartitionEntry(DriveNumber, PartitionTableEntry, BootPartition);
|
||||
return DiskGetActivePartitionEntry(DriveNumber,
|
||||
/* MBR partition table always uses 512-byte sectors per specification */
|
||||
512, // Geometry.BytesPerSector
|
||||
PartitionEntry, BootPartition);
|
||||
}
|
||||
case PARTITION_STYLE_GPT:
|
||||
{
|
||||
@@ -145,7 +152,13 @@ DiskGetBootPartitionEntry(
|
||||
}
|
||||
case PARTITION_STYLE_BRFR:
|
||||
{
|
||||
if (DiskGetBrfrPartitionEntry(DriveNumber, FATX_DATA_PARTITION, PartitionTableEntry))
|
||||
PARTITION_INFORMATION TempPartitionEntry;
|
||||
if (!PartitionEntry)
|
||||
PartitionEntry = &TempPartitionEntry;
|
||||
if (DiskGetBrfrPartitionEntry(DriveNumber,
|
||||
512, // Geometry.BytesPerSector
|
||||
FATX_DATA_PARTITION,
|
||||
PartitionEntry))
|
||||
{
|
||||
*BootPartition = FATX_DATA_PARTITION;
|
||||
return TRUE;
|
||||
@@ -163,19 +176,40 @@ DiskGetBootPartitionEntry(
|
||||
|
||||
BOOLEAN
|
||||
DiskGetPartitionEntry(
|
||||
IN UCHAR DriveNumber,
|
||||
IN ULONG PartitionNumber,
|
||||
OUT PPARTITION_TABLE_ENTRY PartitionTableEntry)
|
||||
_In_ UCHAR DriveNumber,
|
||||
_In_opt_ ULONG SectorSize,
|
||||
_In_ ULONG PartitionNumber,
|
||||
_Out_ PPARTITION_INFORMATION PartitionEntry)
|
||||
{
|
||||
if (SectorSize == 0)
|
||||
{
|
||||
GEOMETRY Geometry;
|
||||
if (!MachDiskGetDriveGeometry(DriveNumber, &Geometry))
|
||||
return FALSE;
|
||||
SectorSize = Geometry.BytesPerSector;
|
||||
}
|
||||
if (SectorSize < 512)
|
||||
{
|
||||
ERR("Drive 0x%X: Invalid sector size %lu\n", DriveNumber, SectorSize);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
switch (DiskPartitionType[DriveNumber])
|
||||
{
|
||||
case PARTITION_STYLE_MBR:
|
||||
{
|
||||
return DiskGetMbrPartitionEntry(DriveNumber, PartitionNumber, PartitionTableEntry);
|
||||
return DiskGetMbrPartitionEntry(DriveNumber,
|
||||
/* MBR partition table always uses 512-byte sectors per specification */
|
||||
512, // SectorSize
|
||||
PartitionNumber,
|
||||
PartitionEntry);
|
||||
}
|
||||
case PARTITION_STYLE_GPT:
|
||||
{
|
||||
return DiskGetGptPartitionEntry(DriveNumber, PartitionNumber, PartitionTableEntry);
|
||||
return DiskGetGptPartitionEntry(DriveNumber,
|
||||
SectorSize,
|
||||
PartitionNumber,
|
||||
PartitionEntry);
|
||||
}
|
||||
case PARTITION_STYLE_RAW:
|
||||
{
|
||||
@@ -184,7 +218,10 @@ DiskGetPartitionEntry(
|
||||
}
|
||||
case PARTITION_STYLE_BRFR:
|
||||
{
|
||||
return DiskGetBrfrPartitionEntry(DriveNumber, PartitionNumber, PartitionTableEntry);
|
||||
return DiskGetBrfrPartitionEntry(DriveNumber,
|
||||
512, // SectorSize
|
||||
PartitionNumber,
|
||||
PartitionEntry);
|
||||
}
|
||||
default:
|
||||
{
|
||||
|
||||
@@ -29,9 +29,6 @@ typedef struct _GEOMETRY
|
||||
ULONGLONG Sectors; ///< Total number of disk sectors/LBA blocks
|
||||
} GEOMETRY, *PGEOMETRY;
|
||||
|
||||
// Some modules use the explicit MBR structures. TODO: Deprecate
|
||||
#include "disk/part_mbr.h"
|
||||
|
||||
/*
|
||||
* Partition type defines (of PSDK)
|
||||
*/
|
||||
@@ -111,19 +108,20 @@ DiskInitialize(
|
||||
|
||||
VOID
|
||||
DiskDetectPartitionType(
|
||||
IN UCHAR DriveNumber);
|
||||
_In_ UCHAR DriveNumber);
|
||||
|
||||
BOOLEAN
|
||||
DiskGetBootPartitionEntry(
|
||||
IN UCHAR DriveNumber,
|
||||
OUT PPARTITION_TABLE_ENTRY PartitionTableEntry,
|
||||
OUT PULONG BootPartition);
|
||||
_In_ UCHAR DriveNumber,
|
||||
_Out_opt_ PPARTITION_INFORMATION PartitionEntry,
|
||||
_Out_ PULONG BootPartition);
|
||||
|
||||
BOOLEAN
|
||||
DiskGetPartitionEntry(
|
||||
IN UCHAR DriveNumber,
|
||||
IN ULONG PartitionNumber,
|
||||
OUT PPARTITION_TABLE_ENTRY PartitionTableEntry);
|
||||
_In_ UCHAR DriveNumber,
|
||||
_In_opt_ ULONG SectorSize,
|
||||
_In_ ULONG PartitionNumber,
|
||||
_Out_ PPARTITION_INFORMATION PartitionEntry);
|
||||
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user