[FREELDR] Move around & static-ify some disk/partition functions.

This commit is contained in:
Hermès Bélusca-Maïto 2019-08-14 15:22:55 +02:00
parent 32fb2e7b5f
commit 41ad62ea69
No known key found for this signature in database
GPG key ID: 3B2539C65E7B93D0
2 changed files with 158 additions and 121 deletions

View file

@ -49,192 +49,15 @@ static struct
{ 0x002EE400, 0x00177000, PARTITION_FAT_16 } /* Cache3, Z: */
};
BOOLEAN DiskGetActivePartitionEntry(UCHAR DriveNumber,
PPARTITION_TABLE_ENTRY PartitionTableEntry,
ULONG *ActivePartition)
{
ULONG BootablePartitionCount = 0;
ULONG CurrentPartitionNumber;
ULONG Index;
MASTER_BOOT_RECORD MasterBootRecord;
PPARTITION_TABLE_ENTRY ThisPartitionTableEntry;
*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];
if (ThisPartitionTableEntry->SystemIndicator != PARTITION_ENTRY_UNUSED &&
ThisPartitionTableEntry->SystemIndicator != PARTITION_EXTENDED &&
ThisPartitionTableEntry->SystemIndicator != PARTITION_XINT13_EXTENDED)
{
CurrentPartitionNumber++;
// Test if this is the bootable partition
if (ThisPartitionTableEntry->BootIndicator == 0x80)
{
BootablePartitionCount++;
*ActivePartition = CurrentPartitionNumber;
// Copy the partition table entry
RtlCopyMemory(PartitionTableEntry,
ThisPartitionTableEntry,
sizeof(PARTITION_TABLE_ENTRY));
}
}
}
// Make sure there was only one bootable partition
if (BootablePartitionCount == 0)
{
ERR("No bootable (active) partitions found.\n");
return FALSE;
}
else if (BootablePartitionCount != 1)
{
ERR("Too many bootable (active) partitions found.\n");
return FALSE;
}
return TRUE;
}
BOOLEAN DiskGetMbrPartitionEntry(UCHAR DriveNumber, ULONG PartitionNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry)
{
MASTER_BOOT_RECORD MasterBootRecord;
PARTITION_TABLE_ENTRY ExtendedPartitionTableEntry;
ULONG ExtendedPartitionNumber;
ULONG ExtendedPartitionOffset;
ULONG Index;
ULONG CurrentPartitionNumber;
PPARTITION_TABLE_ENTRY ThisPartitionTableEntry;
// Read master boot record
if (!DiskReadBootRecord(DriveNumber, 0, &MasterBootRecord))
{
return FALSE;
}
CurrentPartitionNumber = 0;
for (Index=0; Index<4; Index++)
{
ThisPartitionTableEntry = &MasterBootRecord.PartitionTable[Index];
if (ThisPartitionTableEntry->SystemIndicator != PARTITION_ENTRY_UNUSED &&
ThisPartitionTableEntry->SystemIndicator != PARTITION_EXTENDED &&
ThisPartitionTableEntry->SystemIndicator != PARTITION_XINT13_EXTENDED)
{
CurrentPartitionNumber++;
}
if (PartitionNumber == CurrentPartitionNumber)
{
RtlCopyMemory(PartitionTableEntry, ThisPartitionTableEntry, sizeof(PARTITION_TABLE_ENTRY));
return TRUE;
}
}
// They want an extended partition entry so we will need
// to loop through all the extended partitions on the disk
// and return the one they want.
ExtendedPartitionNumber = PartitionNumber - CurrentPartitionNumber - 1;
// Set the initial relative starting sector to 0
// This is because extended partition starting
// sectors a numbered relative to their parent
ExtendedPartitionOffset = 0;
for (Index=0; Index<=ExtendedPartitionNumber; Index++)
{
// Get the extended partition table entry
if (!DiskGetFirstExtendedPartitionEntry(&MasterBootRecord, &ExtendedPartitionTableEntry))
{
return FALSE;
}
// Adjust the relative starting sector of the partition
ExtendedPartitionTableEntry.SectorCountBeforePartition += ExtendedPartitionOffset;
if (ExtendedPartitionOffset == 0)
{
// Set the start of the parrent extended partition
ExtendedPartitionOffset = ExtendedPartitionTableEntry.SectorCountBeforePartition;
}
// Read the partition boot record
if (!DiskReadBootRecord(DriveNumber, ExtendedPartitionTableEntry.SectorCountBeforePartition, &MasterBootRecord))
{
return FALSE;
}
// Get the first real partition table entry
if (!DiskGetFirstPartitionEntry(&MasterBootRecord, PartitionTableEntry))
{
return FALSE;
}
// Now correct the start sector of the partition
PartitionTableEntry->SectorCountBeforePartition += ExtendedPartitionTableEntry.SectorCountBeforePartition;
}
// When we get here we should have the correct entry
// already stored in PartitionTableEntry
// so just return TRUE
return TRUE;
}
BOOLEAN DiskGetFirstPartitionEntry(PMASTER_BOOT_RECORD MasterBootRecord, PPARTITION_TABLE_ENTRY PartitionTableEntry)
static BOOLEAN
DiskReadBootRecord(
IN UCHAR DriveNumber,
IN ULONGLONG LogicalSectorNumber,
OUT PMASTER_BOOT_RECORD BootRecord)
{
ULONG Index;
for (Index=0; Index<4; Index++)
{
// Check the system indicator
// If it's not an extended or unused partition
// then we're done
if ((MasterBootRecord->PartitionTable[Index].SystemIndicator != PARTITION_ENTRY_UNUSED) &&
(MasterBootRecord->PartitionTable[Index].SystemIndicator != PARTITION_EXTENDED) &&
(MasterBootRecord->PartitionTable[Index].SystemIndicator != PARTITION_XINT13_EXTENDED))
{
RtlCopyMemory(PartitionTableEntry, &MasterBootRecord->PartitionTable[Index], sizeof(PARTITION_TABLE_ENTRY));
return TRUE;
}
}
return FALSE;
}
BOOLEAN DiskGetFirstExtendedPartitionEntry(PMASTER_BOOT_RECORD MasterBootRecord, PPARTITION_TABLE_ENTRY PartitionTableEntry)
{
ULONG Index;
for (Index=0; Index<4; Index++)
{
// Check the system indicator
// If it an extended partition then we're done
if ((MasterBootRecord->PartitionTable[Index].SystemIndicator == PARTITION_EXTENDED) ||
(MasterBootRecord->PartitionTable[Index].SystemIndicator == PARTITION_XINT13_EXTENDED))
{
RtlCopyMemory(PartitionTableEntry, &MasterBootRecord->PartitionTable[Index], sizeof(PARTITION_TABLE_ENTRY));
return TRUE;
}
}
return FALSE;
}
BOOLEAN DiskReadBootRecord(UCHAR DriveNumber, ULONGLONG LogicalSectorNumber, PMASTER_BOOT_RECORD BootRecord)
{
ULONG Index;
// Read master boot record
/* Read master boot record */
if (!MachDiskReadLogicalSectors(DriveNumber, LogicalSectorNumber, 1, DiskReadBuffer))
{
return FALSE;
@ -261,7 +84,7 @@ BOOLEAN DiskReadBootRecord(UCHAR DriveNumber, ULONGLONG LogicalSectorNumber, PMA
TRACE("PartitionSectorCount: 0x%x\n", BootRecord->PartitionTable[Index].PartitionSectorCount);
}
// Check the partition table magic value
/* Check the partition table magic value */
if (BootRecord->MasterBootRecordMagic != 0xaa55)
{
return FALSE;
@ -270,8 +93,205 @@ BOOLEAN DiskReadBootRecord(UCHAR DriveNumber, ULONGLONG LogicalSectorNumber, PMA
return TRUE;
}
BOOLEAN
DiskGetBrfrPartitionEntry(UCHAR DriveNumber, ULONG PartitionNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry)
static BOOLEAN
DiskGetFirstPartitionEntry(
IN PMASTER_BOOT_RECORD MasterBootRecord,
OUT PPARTITION_TABLE_ENTRY PartitionTableEntry)
{
ULONG Index;
for (Index = 0; Index < 4; Index++)
{
/* Check the system indicator. If it's not an extended or unused partition then we're done. */
if ((MasterBootRecord->PartitionTable[Index].SystemIndicator != PARTITION_ENTRY_UNUSED) &&
(MasterBootRecord->PartitionTable[Index].SystemIndicator != PARTITION_EXTENDED) &&
(MasterBootRecord->PartitionTable[Index].SystemIndicator != PARTITION_XINT13_EXTENDED))
{
RtlCopyMemory(PartitionTableEntry, &MasterBootRecord->PartitionTable[Index], sizeof(PARTITION_TABLE_ENTRY));
return TRUE;
}
}
return FALSE;
}
static BOOLEAN
DiskGetFirstExtendedPartitionEntry(
IN PMASTER_BOOT_RECORD MasterBootRecord,
OUT PPARTITION_TABLE_ENTRY PartitionTableEntry)
{
ULONG Index;
for (Index = 0; Index < 4; Index++)
{
/* Check the system indicator. If it an extended partition then we're done. */
if ((MasterBootRecord->PartitionTable[Index].SystemIndicator == PARTITION_EXTENDED) ||
(MasterBootRecord->PartitionTable[Index].SystemIndicator == PARTITION_XINT13_EXTENDED))
{
RtlCopyMemory(PartitionTableEntry, &MasterBootRecord->PartitionTable[Index], sizeof(PARTITION_TABLE_ENTRY));
return TRUE;
}
}
return FALSE;
}
static BOOLEAN
DiskGetActivePartitionEntry(
IN UCHAR DriveNumber,
OUT PPARTITION_TABLE_ENTRY PartitionTableEntry,
OUT PULONG ActivePartition)
{
ULONG BootablePartitionCount = 0;
ULONG CurrentPartitionNumber;
ULONG Index;
MASTER_BOOT_RECORD MasterBootRecord;
PPARTITION_TABLE_ENTRY ThisPartitionTableEntry;
*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];
if (ThisPartitionTableEntry->SystemIndicator != PARTITION_ENTRY_UNUSED &&
ThisPartitionTableEntry->SystemIndicator != PARTITION_EXTENDED &&
ThisPartitionTableEntry->SystemIndicator != PARTITION_XINT13_EXTENDED)
{
CurrentPartitionNumber++;
/* Test if this is the bootable partition */
if (ThisPartitionTableEntry->BootIndicator == 0x80)
{
BootablePartitionCount++;
*ActivePartition = CurrentPartitionNumber;
/* Copy the partition table entry */
RtlCopyMemory(PartitionTableEntry,
ThisPartitionTableEntry,
sizeof(PARTITION_TABLE_ENTRY));
}
}
}
/* Make sure there was only one bootable partition */
if (BootablePartitionCount == 0)
{
ERR("No bootable (active) partitions found.\n");
return FALSE;
}
else if (BootablePartitionCount != 1)
{
ERR("Too many bootable (active) partitions found.\n");
return FALSE;
}
return TRUE;
}
static BOOLEAN
DiskGetMbrPartitionEntry(
IN UCHAR DriveNumber,
IN ULONG PartitionNumber,
OUT PPARTITION_TABLE_ENTRY PartitionTableEntry)
{
MASTER_BOOT_RECORD MasterBootRecord;
PARTITION_TABLE_ENTRY ExtendedPartitionTableEntry;
ULONG ExtendedPartitionNumber;
ULONG ExtendedPartitionOffset;
ULONG Index;
ULONG CurrentPartitionNumber;
PPARTITION_TABLE_ENTRY ThisPartitionTableEntry;
/* Read master boot record */
if (!DiskReadBootRecord(DriveNumber, 0, &MasterBootRecord))
{
return FALSE;
}
CurrentPartitionNumber = 0;
for (Index = 0; Index < 4; Index++)
{
ThisPartitionTableEntry = &MasterBootRecord.PartitionTable[Index];
if (ThisPartitionTableEntry->SystemIndicator != PARTITION_ENTRY_UNUSED &&
ThisPartitionTableEntry->SystemIndicator != PARTITION_EXTENDED &&
ThisPartitionTableEntry->SystemIndicator != PARTITION_XINT13_EXTENDED)
{
CurrentPartitionNumber++;
}
if (PartitionNumber == CurrentPartitionNumber)
{
RtlCopyMemory(PartitionTableEntry, ThisPartitionTableEntry, sizeof(PARTITION_TABLE_ENTRY));
return TRUE;
}
}
/*
* They want an extended partition entry so we will need
* to loop through all the extended partitions on the disk
* and return the one they want.
*/
ExtendedPartitionNumber = PartitionNumber - CurrentPartitionNumber - 1;
/*
* Set the initial relative starting sector to 0.
* This is because extended partition starting
* sectors a numbered relative to their parent.
*/
ExtendedPartitionOffset = 0;
for (Index = 0; Index <= ExtendedPartitionNumber; Index++)
{
/* Get the extended partition table entry */
if (!DiskGetFirstExtendedPartitionEntry(&MasterBootRecord, &ExtendedPartitionTableEntry))
{
return FALSE;
}
/* Adjust the relative starting sector of the partition */
ExtendedPartitionTableEntry.SectorCountBeforePartition += ExtendedPartitionOffset;
if (ExtendedPartitionOffset == 0)
{
/* Set the start of the parrent extended partition */
ExtendedPartitionOffset = ExtendedPartitionTableEntry.SectorCountBeforePartition;
}
/* Read the partition boot record */
if (!DiskReadBootRecord(DriveNumber, ExtendedPartitionTableEntry.SectorCountBeforePartition, &MasterBootRecord))
{
return FALSE;
}
/* Get the first real partition table entry */
if (!DiskGetFirstPartitionEntry(&MasterBootRecord, PartitionTableEntry))
{
return FALSE;
}
/* Now correct the start sector of the partition */
PartitionTableEntry->SectorCountBeforePartition += ExtendedPartitionTableEntry.SectorCountBeforePartition;
}
/*
* When we get here we should have the correct entry already
* stored in PartitionTableEntry, so just return TRUE.
*/
return TRUE;
}
static BOOLEAN
DiskGetBrfrPartitionEntry(
IN UCHAR DriveNumber,
IN ULONG PartitionNumber,
OUT PPARTITION_TABLE_ENTRY PartitionTableEntry)
{
/*
* Get partition entry of an Xbox-standard BRFR partitioned disk.
@ -296,7 +316,9 @@ DiskGetBrfrPartitionEntry(UCHAR DriveNumber, ULONG PartitionNumber, PPARTITION_T
return FALSE;
}
VOID DiskDetectPartitionType(UCHAR DriveNumber)
VOID
DiskDetectPartitionType(
IN UCHAR DriveNumber)
{
MASTER_BOOT_RECORD MasterBootRecord;
ULONG Index;
@ -347,9 +369,11 @@ VOID DiskDetectPartitionType(UCHAR DriveNumber)
TRACE("Drive 0x%X partition type unknown\n", DriveNumber);
}
BOOLEAN DiskGetBootPartitionEntry(UCHAR DriveNumber,
PPARTITION_TABLE_ENTRY PartitionTableEntry,
ULONG *BootPartition)
BOOLEAN
DiskGetBootPartitionEntry(
IN UCHAR DriveNumber,
OUT PPARTITION_TABLE_ENTRY PartitionTableEntry,
OUT PULONG BootPartition)
{
switch (DiskPartitionType[DriveNumber])
{
@ -385,7 +409,11 @@ BOOLEAN DiskGetBootPartitionEntry(UCHAR DriveNumber,
return FALSE;
}
BOOLEAN DiskGetPartitionEntry(UCHAR DriveNumber, ULONG PartitionNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry)
BOOLEAN
DiskGetPartitionEntry(
IN UCHAR DriveNumber,
IN ULONG PartitionNumber,
OUT PPARTITION_TABLE_ENTRY PartitionTableEntry)
{
switch (DiskPartitionType[DriveNumber])
{

View file

@ -145,12 +145,21 @@ extern SIZE_T DiskReadBufferSize;
//
///////////////////////////////////////////////////////////////////////////////////////
VOID DiskDetectPartitionType(UCHAR DriveNumber);
BOOLEAN DiskGetBootPartitionEntry(UCHAR DriveNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry, ULONG *BootPartition);
BOOLEAN DiskGetPartitionEntry(UCHAR DriveNumber, ULONG PartitionNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry);
BOOLEAN DiskGetFirstPartitionEntry(PMASTER_BOOT_RECORD MasterBootRecord, PPARTITION_TABLE_ENTRY PartitionTableEntry);
BOOLEAN DiskGetFirstExtendedPartitionEntry(PMASTER_BOOT_RECORD MasterBootRecord, PPARTITION_TABLE_ENTRY PartitionTableEntry);
BOOLEAN DiskReadBootRecord(UCHAR DriveNumber, ULONGLONG LogicalSectorNumber, PMASTER_BOOT_RECORD BootRecord);
VOID
DiskDetectPartitionType(
IN UCHAR DriveNumber);
BOOLEAN
DiskGetBootPartitionEntry(
IN UCHAR DriveNumber,
OUT PPARTITION_TABLE_ENTRY PartitionTableEntry,
OUT PULONG BootPartition);
BOOLEAN
DiskGetPartitionEntry(
IN UCHAR DriveNumber,
IN ULONG PartitionNumber,
OUT PPARTITION_TABLE_ENTRY PartitionTableEntry);
/*
* SCSI support (disk/scsiport.c)