[FREELDR] Fix 64 bit issues
[reactos.git] / boot / freeldr / freeldr / disk / partition.c
index 147b320..1feaf51 100644 (file)
  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
+/*
+ * TODO: This is here where we should add support for GPT partitions
+ * as well as partitionless disks!
+ */
+
 #ifndef _M_ARM
 #include <freeldr.h>
+
 #include <debug.h>
 
 DBG_DEFAULT_CHANNEL(DISK);
 
+/* This function serves to retrieve a partition entry for devices that handle partitions differently */
+DISK_GET_PARTITION_ENTRY DiskGetPartitionEntry = DiskGetMbrPartitionEntry;
+
 BOOLEAN DiskGetActivePartitionEntry(UCHAR DriveNumber,
-                                 PPARTITION_TABLE_ENTRY PartitionTableEntry,
-                                 ULONG *ActivePartition)
+                                    PPARTITION_TABLE_ENTRY PartitionTableEntry,
+                                    ULONG *ActivePartition)
 {
-       ULONG                   BootablePartitionCount = 0;
-       MASTER_BOOT_RECORD      MasterBootRecord;
-
-       *ActivePartition = 0;
-       // Read master boot record
-       if (!DiskReadBootRecord(DriveNumber, 0, &MasterBootRecord))
-       {
-               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;
-       }
-
-       // 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;
-       }
-
-       // Copy the partition table entry
-       RtlCopyMemory(PartitionTableEntry,
-                     &MasterBootRecord.PartitionTable[*ActivePartition - 1],
-                     sizeof(PARTITION_TABLE_ENTRY));
-
-       return TRUE;
+    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 DiskGetPartitionEntry(UCHAR DriveNumber, ULONG PartitionNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry)
+BOOLEAN DiskGetMbrPartitionEntry(UCHAR DriveNumber, ULONG PartitionNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry)
 {
-       MASTER_BOOT_RECORD              MasterBootRecord;
-       PARTITION_TABLE_ENTRY   ExtendedPartitionTableEntry;
-       ULONG                                           ExtendedPartitionNumber;
-       ULONG                                           ExtendedPartitionOffset;
-       ULONG                                           Index;
-
-       // Read master boot record
-       if (!DiskReadBootRecord(DriveNumber, 0, &MasterBootRecord))
-       {
-               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;
-       }
+    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)
 {
-       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;
+    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;
+    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
-       if (!MachDiskReadLogicalSectors(DriveNumber, LogicalSectorNumber, 1, (PVOID)DISKREADBUFFER))
-       {
-               return FALSE;
-       }
-       RtlCopyMemory(BootRecord, (PVOID)DISKREADBUFFER, sizeof(MASTER_BOOT_RECORD));
-
-
-       TRACE("Dumping partition table for drive 0x%x:\n", DriveNumber);
-       TRACE("Boot record logical start sector = %d\n", LogicalSectorNumber);
-       TRACE("sizeof(MASTER_BOOT_RECORD) = 0x%x.\n", sizeof(MASTER_BOOT_RECORD));
-
-       for (Index=0; Index<4; Index++)
-       {
-               TRACE("-------------------------------------------\n");
-               TRACE("Partition %d\n", (Index + 1));
-               TRACE("BootIndicator: 0x%x\n", BootRecord->PartitionTable[Index].BootIndicator);
-               TRACE("StartHead: 0x%x\n", BootRecord->PartitionTable[Index].StartHead);
-               TRACE("StartSector (Plus 2 cylinder bits): 0x%x\n", BootRecord->PartitionTable[Index].StartSector);
-               TRACE("StartCylinder: 0x%x\n", BootRecord->PartitionTable[Index].StartCylinder);
-               TRACE("SystemIndicator: 0x%x\n", BootRecord->PartitionTable[Index].SystemIndicator);
-               TRACE("EndHead: 0x%x\n", BootRecord->PartitionTable[Index].EndHead);
-               TRACE("EndSector (Plus 2 cylinder bits): 0x%x\n", BootRecord->PartitionTable[Index].EndSector);
-               TRACE("EndCylinder: 0x%x\n", BootRecord->PartitionTable[Index].EndCylinder);
-               TRACE("SectorCountBeforePartition: 0x%x\n", BootRecord->PartitionTable[Index].SectorCountBeforePartition);
-               TRACE("PartitionSectorCount: 0x%x\n", BootRecord->PartitionTable[Index].PartitionSectorCount);
-       }
-
-       // Check the partition table magic value
-       if (BootRecord->MasterBootRecordMagic != 0xaa55)
-       {
-               return FALSE;
-       }
-
-       return TRUE;
+    ULONG Index;
+
+    // Read master boot record
+    if (!MachDiskReadLogicalSectors(DriveNumber, LogicalSectorNumber, 1, DiskReadBuffer))
+    {
+        return FALSE;
+    }
+    RtlCopyMemory(BootRecord, DiskReadBuffer, sizeof(MASTER_BOOT_RECORD));
+
+    TRACE("Dumping partition table for drive 0x%x:\n", DriveNumber);
+    TRACE("Boot record logical start sector = %d\n", LogicalSectorNumber);
+    TRACE("sizeof(MASTER_BOOT_RECORD) = 0x%x.\n", sizeof(MASTER_BOOT_RECORD));
+
+    for (Index=0; Index<4; Index++)
+    {
+        TRACE("-------------------------------------------\n");
+        TRACE("Partition %d\n", (Index + 1));
+        TRACE("BootIndicator: 0x%x\n", BootRecord->PartitionTable[Index].BootIndicator);
+        TRACE("StartHead: 0x%x\n", BootRecord->PartitionTable[Index].StartHead);
+        TRACE("StartSector (Plus 2 cylinder bits): 0x%x\n", BootRecord->PartitionTable[Index].StartSector);
+        TRACE("StartCylinder: 0x%x\n", BootRecord->PartitionTable[Index].StartCylinder);
+        TRACE("SystemIndicator: 0x%x\n", BootRecord->PartitionTable[Index].SystemIndicator);
+        TRACE("EndHead: 0x%x\n", BootRecord->PartitionTable[Index].EndHead);
+        TRACE("EndSector (Plus 2 cylinder bits): 0x%x\n", BootRecord->PartitionTable[Index].EndSector);
+        TRACE("EndCylinder: 0x%x\n", BootRecord->PartitionTable[Index].EndCylinder);
+        TRACE("SectorCountBeforePartition: 0x%x\n", BootRecord->PartitionTable[Index].SectorCountBeforePartition);
+        TRACE("PartitionSectorCount: 0x%x\n", BootRecord->PartitionTable[Index].PartitionSectorCount);
+    }
+
+    // Check the partition table magic value
+    if (BootRecord->MasterBootRecordMagic != 0xaa55)
+    {
+        return FALSE;
+    }
+
+    return TRUE;
 }
 
+#ifndef _M_AMD64
 NTSTATUS
 NTAPI
 IopReadBootRecord(
@@ -246,10 +262,10 @@ IopReadBootRecord(
     IN ULONG SectorSize,
     OUT PMASTER_BOOT_RECORD BootRecord)
 {
-    ULONG FileId = (ULONG)DeviceObject;
+    ULONG_PTR FileId = (ULONG_PTR)DeviceObject;
     LARGE_INTEGER Position;
     ULONG BytesRead;
-    ULONG Status;
+    ARC_STATUS Status;
 
     Position.QuadPart = LogicalSectorNumber * SectorSize;
     Status = ArcSeek(FileId, &Position, SeekAbsolute);
@@ -384,5 +400,5 @@ IoReadPartitionTable(
     *PartitionBuffer = Partitions;
     return STATUS_SUCCESS;
 }
-
+#endif // _M_AMD64
 #endif