[FREELDR]
authorPierre Schweitzer <pierre@reactos.org>
Sun, 29 May 2016 08:14:24 +0000 (08:14 +0000)
committerPierre Schweitzer <pierre@reactos.org>
Sun, 29 May 2016 08:14:24 +0000 (08:14 +0000)
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

index 46c515e..5e2319a 100644 (file)
@@ -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)
-    {
-        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)
+    CurrentPartitionNumber = 0;
+    for (Index=0; Index<4; Index++)
     {
-        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));
+        ThisPartitionTableEntry = &MasterBootRecord.PartitionTable[Index];
+        
+        if (ThisPartitionTableEntry->SystemIndicator != PARTITION_ENTRY_UNUSED &&
+            ThisPartitionTableEntry->SystemIndicator != PARTITION_EXTENDED &&
+            ThisPartitionTableEntry->SystemIndicator != PARTITION_XINT13_EXTENDED)
+        {
+            CurrentPartitionNumber++;
+        }
 
-        return TRUE;
+        if (PartitionNumber == CurrentPartitionNumber)
+        {
+            RtlCopyMemory(PartitionTableEntry, ThisPartitionTableEntry, 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;
+    // 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.
 
-        // Set the initial relative starting sector to 0
-        // This is because extended partition starting
-        // sectors a numbered relative to their parent
-        ExtendedPartitionOffset = 0;
+    ExtendedPartitionNumber = PartitionNumber - CurrentPartitionNumber - 1;
 
-        for (Index=0; Index<=ExtendedPartitionNumber; Index++)
-        {
-            // Get the extended partition table entry
-            if (!DiskGetFirstExtendedPartitionEntry(&MasterBootRecord, &ExtendedPartitionTableEntry))
-            {
-                return FALSE;
-            }
+    // Set the initial relative starting sector to 0
+    // This is because extended partition starting
+    // sectors a numbered relative to their parent
+    ExtendedPartitionOffset = 0;
 
-            // 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;
-            }
+    for (Index=0; Index<=ExtendedPartitionNumber; Index++)
+    {
+        // Get the extended partition table entry
+        if (!DiskGetFirstExtendedPartitionEntry(&MasterBootRecord, &ExtendedPartitionTableEntry))
+        {
+            return FALSE;
+        }
 
-            // Get the first real partition table entry
-            if (!DiskGetFirstPartitionEntry(&MasterBootRecord, PartitionTableEntry))
-            {
-                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;
+        }
 
-            // Now correct the start sector of the partition
-            PartitionTableEntry->SectorCountBeforePartition += ExtendedPartitionTableEntry.SectorCountBeforePartition;
+        // Get the first real partition table entry
+        if (!DiskGetFirstPartitionEntry(&MasterBootRecord, PartitionTableEntry))
+        {
+            return FALSE;
         }
 
-        // When we get here we should have the correct entry
-        // already stored in PartitionTableEntry
-        // so just return TRUE
-        return TRUE;
+        // 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)