Author: pschweitzer Date: Sun May 29 08:14:24 2016 New Revision: 71453
URL: http://svn.reactos.org/svn/reactos?rev=71453&view=rev Log: [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
Modified: trunk/reactos/boot/freeldr/freeldr/disk/partition.c
Modified: trunk/reactos/boot/freeldr/freeldr/disk/partition.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/disk/p... ============================================================================== --- trunk/reactos/boot/freeldr/freeldr/disk/partition.c [iso-8859-1] (original) +++ trunk/reactos/boot/freeldr/freeldr/disk/partition.c [iso-8859-1] Sun May 29 08:14:24 2016 @@ -28,7 +28,10 @@ ULONG *ActivePartition) { ULONG BootablePartitionCount = 0; + ULONG CurrentPartitionNumber; + ULONG Index; MASTER_BOOT_RECORD MasterBootRecord; + PPARTITION_TABLE_ENTRY ThisPartitionTableEntry;
*ActivePartition = 0;
@@ -38,26 +41,29 @@ return FALSE; }
- // Count the bootable partitions - if (MasterBootRecord.PartitionTable[0].BootIndicator == 0x80) - { - 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; + 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 @@ -71,11 +77,6 @@ ERR("Too many bootable (active) partitions found.\n"); return FALSE; } - - // Copy the partition table entry - RtlCopyMemory(PartitionTableEntry, - &MasterBootRecord.PartitionTable[*ActivePartition - 1], - sizeof(PARTITION_TABLE_ENTRY));
return TRUE; } @@ -87,6 +88,8 @@ 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 @@ return FALSE; }
- // If they are asking for a primary - // partition then things are easy - if (PartitionNumber < 5) - { - // 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++) - { - // 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; - } - + 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)