mirror of
https://github.com/reactos/reactos.git
synced 2025-05-29 05:58:13 +00:00
[FREELDR]
Properly count used/unused partitions. This fixes booting ReactOS when it is installed on a partition entry after an unused partition entry. Patch by Wim Hueskes CORE-11330 #resolve svn path=/trunk/; revision=71453
This commit is contained in:
parent
3e96c56d45
commit
0a04ca9713
1 changed files with 86 additions and 80 deletions
|
@ -28,7 +28,10 @@ BOOLEAN DiskGetActivePartitionEntry(UCHAR DriveNumber,
|
||||||
ULONG *ActivePartition)
|
ULONG *ActivePartition)
|
||||||
{
|
{
|
||||||
ULONG BootablePartitionCount = 0;
|
ULONG BootablePartitionCount = 0;
|
||||||
|
ULONG CurrentPartitionNumber;
|
||||||
|
ULONG Index;
|
||||||
MASTER_BOOT_RECORD MasterBootRecord;
|
MASTER_BOOT_RECORD MasterBootRecord;
|
||||||
|
PPARTITION_TABLE_ENTRY ThisPartitionTableEntry;
|
||||||
|
|
||||||
*ActivePartition = 0;
|
*ActivePartition = 0;
|
||||||
|
|
||||||
|
@ -38,26 +41,29 @@ BOOLEAN DiskGetActivePartitionEntry(UCHAR DriveNumber,
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Count the bootable partitions
|
CurrentPartitionNumber = 0;
|
||||||
if (MasterBootRecord.PartitionTable[0].BootIndicator == 0x80)
|
for (Index=0; Index<4; Index++)
|
||||||
{
|
{
|
||||||
BootablePartitionCount++;
|
ThisPartitionTableEntry = &MasterBootRecord.PartitionTable[Index];
|
||||||
*ActivePartition = 1;
|
|
||||||
}
|
if (ThisPartitionTableEntry->SystemIndicator != PARTITION_ENTRY_UNUSED &&
|
||||||
if (MasterBootRecord.PartitionTable[1].BootIndicator == 0x80)
|
ThisPartitionTableEntry->SystemIndicator != PARTITION_EXTENDED &&
|
||||||
{
|
ThisPartitionTableEntry->SystemIndicator != PARTITION_XINT13_EXTENDED)
|
||||||
BootablePartitionCount++;
|
{
|
||||||
*ActivePartition = 2;
|
CurrentPartitionNumber++;
|
||||||
}
|
|
||||||
if (MasterBootRecord.PartitionTable[2].BootIndicator == 0x80)
|
// Test if this is the bootable partition
|
||||||
{
|
if (ThisPartitionTableEntry->BootIndicator == 0x80)
|
||||||
BootablePartitionCount++;
|
{
|
||||||
*ActivePartition = 3;
|
BootablePartitionCount++;
|
||||||
}
|
*ActivePartition = CurrentPartitionNumber;
|
||||||
if (MasterBootRecord.PartitionTable[3].BootIndicator == 0x80)
|
|
||||||
{
|
// Copy the partition table entry
|
||||||
BootablePartitionCount++;
|
RtlCopyMemory(PartitionTableEntry,
|
||||||
*ActivePartition = 4;
|
ThisPartitionTableEntry,
|
||||||
|
sizeof(PARTITION_TABLE_ENTRY));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure there was only one bootable partition
|
// Make sure there was only one bootable partition
|
||||||
|
@ -72,11 +78,6 @@ BOOLEAN DiskGetActivePartitionEntry(UCHAR DriveNumber,
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy the partition table entry
|
|
||||||
RtlCopyMemory(PartitionTableEntry,
|
|
||||||
&MasterBootRecord.PartitionTable[*ActivePartition - 1],
|
|
||||||
sizeof(PARTITION_TABLE_ENTRY));
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,6 +88,8 @@ BOOLEAN DiskGetPartitionEntry(UCHAR DriveNumber, ULONG PartitionNumber, PPARTITI
|
||||||
ULONG ExtendedPartitionNumber;
|
ULONG ExtendedPartitionNumber;
|
||||||
ULONG ExtendedPartitionOffset;
|
ULONG ExtendedPartitionOffset;
|
||||||
ULONG Index;
|
ULONG Index;
|
||||||
|
ULONG CurrentPartitionNumber;
|
||||||
|
PPARTITION_TABLE_ENTRY ThisPartitionTableEntry;
|
||||||
|
|
||||||
// Read master boot record
|
// Read master boot record
|
||||||
if (!DiskReadBootRecord(DriveNumber, 0, &MasterBootRecord))
|
if (!DiskReadBootRecord(DriveNumber, 0, &MasterBootRecord))
|
||||||
|
@ -94,68 +97,71 @@ BOOLEAN DiskGetPartitionEntry(UCHAR DriveNumber, ULONG PartitionNumber, PPARTITI
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If they are asking for a primary
|
CurrentPartitionNumber = 0;
|
||||||
// partition then things are easy
|
for (Index=0; Index<4; Index++)
|
||||||
if (PartitionNumber < 5)
|
|
||||||
{
|
{
|
||||||
// PartitionNumber is one-based and we need it zero-based
|
ThisPartitionTableEntry = &MasterBootRecord.PartitionTable[Index];
|
||||||
PartitionNumber--;
|
|
||||||
|
if (ThisPartitionTableEntry->SystemIndicator != PARTITION_ENTRY_UNUSED &&
|
||||||
// Copy the partition table entry
|
ThisPartitionTableEntry->SystemIndicator != PARTITION_EXTENDED &&
|
||||||
RtlCopyMemory(PartitionTableEntry, &MasterBootRecord.PartitionTable[PartitionNumber], sizeof(PARTITION_TABLE_ENTRY));
|
ThisPartitionTableEntry->SystemIndicator != PARTITION_XINT13_EXTENDED)
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// 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 - 5;
|
|
||||||
|
|
||||||
// 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
|
CurrentPartitionNumber++;
|
||||||
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
|
if (PartitionNumber == CurrentPartitionNumber)
|
||||||
// already stored in PartitionTableEntry
|
{
|
||||||
// so just return TRUE
|
RtlCopyMemory(PartitionTableEntry, ThisPartitionTableEntry, sizeof(PARTITION_TABLE_ENTRY));
|
||||||
return TRUE;
|
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)
|
BOOLEAN DiskGetFirstPartitionEntry(PMASTER_BOOT_RECORD MasterBootRecord, PPARTITION_TABLE_ENTRY PartitionTableEntry)
|
||||||
|
|
Loading…
Reference in a new issue