From 0a04ca9713284c11154e6c675108bc68f3e22d5c Mon Sep 17 00:00:00 2001 From: Pierre Schweitzer Date: Sun, 29 May 2016 08:14:24 +0000 Subject: [PATCH] [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 --- reactos/boot/freeldr/freeldr/disk/partition.c | 166 +++++++++--------- 1 file changed, 86 insertions(+), 80 deletions(-) diff --git a/reactos/boot/freeldr/freeldr/disk/partition.c b/reactos/boot/freeldr/freeldr/disk/partition.c index 46c515e2ae2..5e2319aa31b 100644 --- a/reactos/boot/freeldr/freeldr/disk/partition.c +++ b/reactos/boot/freeldr/freeldr/disk/partition.c @@ -28,7 +28,10 @@ BOOLEAN DiskGetActivePartitionEntry(UCHAR DriveNumber, ULONG *ActivePartition) { ULONG BootablePartitionCount = 0; + ULONG CurrentPartitionNumber; + ULONG Index; MASTER_BOOT_RECORD MasterBootRecord; + PPARTITION_TABLE_ENTRY ThisPartitionTableEntry; *ActivePartition = 0; @@ -38,26 +41,29 @@ BOOLEAN DiskGetActivePartitionEntry(UCHAR DriveNumber, return FALSE; } - // Count the bootable partitions - if (MasterBootRecord.PartitionTable[0].BootIndicator == 0x80) + CurrentPartitionNumber = 0; + for (Index=0; Index<4; Index++) { - BootablePartitionCount++; - *ActivePartition = 1; - } - if (MasterBootRecord.PartitionTable[1].BootIndicator == 0x80) - { - BootablePartitionCount++; - *ActivePartition = 2; - } - if (MasterBootRecord.PartitionTable[2].BootIndicator == 0x80) - { - BootablePartitionCount++; - *ActivePartition = 3; - } - if (MasterBootRecord.PartitionTable[3].BootIndicator == 0x80) - { - BootablePartitionCount++; - *ActivePartition = 4; + 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 @@ -72,11 +78,6 @@ BOOLEAN DiskGetActivePartitionEntry(UCHAR DriveNumber, return FALSE; } - // Copy the partition table entry - RtlCopyMemory(PartitionTableEntry, - &MasterBootRecord.PartitionTable[*ActivePartition - 1], - sizeof(PARTITION_TABLE_ENTRY)); - return TRUE; } @@ -87,6 +88,8 @@ BOOLEAN DiskGetPartitionEntry(UCHAR DriveNumber, ULONG PartitionNumber, PPARTITI ULONG ExtendedPartitionNumber; ULONG ExtendedPartitionOffset; ULONG Index; + ULONG CurrentPartitionNumber; + PPARTITION_TABLE_ENTRY ThisPartitionTableEntry; // Read master boot record if (!DiskReadBootRecord(DriveNumber, 0, &MasterBootRecord)) @@ -94,68 +97,71 @@ BOOLEAN DiskGetPartitionEntry(UCHAR DriveNumber, ULONG PartitionNumber, PPARTITI return FALSE; } - // If they are asking for a primary - // partition then things are easy - if (PartitionNumber < 5) + CurrentPartitionNumber = 0; + for (Index=0; Index<4; Index++) { - // PartitionNumber is one-based and we need it zero-based - PartitionNumber--; - - // Copy the partition table entry - RtlCopyMemory(PartitionTableEntry, &MasterBootRecord.PartitionTable[PartitionNumber], sizeof(PARTITION_TABLE_ENTRY)); - - 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++) + ThisPartitionTableEntry = &MasterBootRecord.PartitionTable[Index]; + + if (ThisPartitionTableEntry->SystemIndicator != PARTITION_ENTRY_UNUSED && + ThisPartitionTableEntry->SystemIndicator != PARTITION_EXTENDED && + ThisPartitionTableEntry->SystemIndicator != PARTITION_XINT13_EXTENDED) { - // 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; + CurrentPartitionNumber++; } - // When we get here we should have the correct entry - // already stored in PartitionTableEntry - // so just return TRUE - return TRUE; + 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)