[FREELDR] Addendum / actual fix for ef76709b
authorHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Tue, 17 Sep 2019 23:06:15 +0000 (01:06 +0200)
committerHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Tue, 17 Sep 2019 23:12:58 +0000 (01:12 +0200)
According to the Advanced RISC Computing Specification v1.2, for partitions,
StartingAddress and EndingAddress are the start and end positions of the
partition in terms of byte offsets from the start of the disk.
CurrentAddress is the current offset into (i.e. relative to) the partition.

Fix also the FAT filesystem in accordance.

- FIXME fix: Retrieve the size of the disk in number of sectors in DiskOpen().
- Add extra validity checks in the DiskSeek() functions.
- Explicitly call PcDisk* functions in machpc.c and pcdisk.c, and
  XboxDisk* functions in machxbox.c (the code in these files is not
  called cross-platform).

CORE-16216 CORE-16248

boot/freeldr/freeldr/arch/i386/hwdisk.c
boot/freeldr/freeldr/arch/i386/machpc.c
boot/freeldr/freeldr/arch/i386/machxbox.c
boot/freeldr/freeldr/arch/i386/pcdisk.c
boot/freeldr/freeldr/disk/scsiport.c
boot/freeldr/freeldr/lib/fs/fat.c

index 9f623a3..ef13c24 100644 (file)
@@ -63,8 +63,16 @@ DiskGetFileInformation(ULONG FileId, FILEINFORMATION* Information)
     DISKCONTEXT* Context = FsGetDeviceSpecific(FileId);
 
     RtlZeroMemory(Information, sizeof(*Information));
-    Information->EndingAddress.QuadPart = Context->SectorCount * Context->SectorSize;
-    Information->CurrentAddress.QuadPart = Context->SectorNumber * Context->SectorSize;
+
+    /*
+     * The ARC specification mentions that for partitions, StartingAddress and
+     * EndingAddress are the start and end positions of the partition in terms
+     * of byte offsets from the start of the disk.
+     * CurrentAddress is the current offset into (i.e. relative to) the partition.
+     */
+    Information->StartingAddress.QuadPart = Context->SectorOffset * Context->SectorSize;
+    Information->EndingAddress.QuadPart   = (Context->SectorOffset + Context->SectorCount) * Context->SectorSize;
+    Information->CurrentAddress.QuadPart  = Context->SectorNumber * Context->SectorSize;
 
     return ESUCCESS;
 }
@@ -113,12 +121,21 @@ DiskOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId)
         SectorOffset = PartitionTableEntry.SectorCountBeforePartition;
         SectorCount = PartitionTableEntry.PartitionSectorCount;
     }
-#if 0 // FIXME: Investigate
     else
     {
-        SectorCount = 0; /* FIXME */
+        GEOMETRY Geometry;
+        if (!MachDiskGetDriveGeometry(DriveNumber, &Geometry))
+            return EINVAL;
+
+        if (SectorSize != Geometry.BytesPerSector)
+        {
+            ERR("SectorSize (%lu) != Geometry.BytesPerSector (%lu), expect problems!\n",
+                SectorSize, Geometry.BytesPerSector);
+        }
+
+        SectorOffset = 0;
+        SectorCount = (ULONGLONG)Geometry.Cylinders * Geometry.Heads * Geometry.Sectors;
     }
-#endif
 
     Context = FrLdrTempAlloc(sizeof(DISKCONTEXT), TAG_HW_DISK_CONTEXT);
     if (!Context)
@@ -147,7 +164,7 @@ DiskRead(ULONG FileId, VOID* Buffer, ULONG N, ULONG* Count)
 
     TotalSectors = (N + Context->SectorSize - 1) / Context->SectorSize;
     MaxSectors   = DiskReadBufferSize / Context->SectorSize;
-    SectorOffset = Context->SectorNumber + Context->SectorOffset;
+    SectorOffset = Context->SectorOffset + Context->SectorNumber;
 
     // If MaxSectors is 0, this will lead to infinite loop.
     // In release builds assertions are disabled, however we also have sanity checks in DiskOpen()
@@ -189,13 +206,18 @@ static ARC_STATUS
 DiskSeek(ULONG FileId, LARGE_INTEGER* Position, SEEKMODE SeekMode)
 {
     DISKCONTEXT* Context = FsGetDeviceSpecific(FileId);
+    ULONGLONG SectorNumber;
 
     if (SeekMode != SeekAbsolute)
         return EINVAL;
     if (Position->LowPart & (Context->SectorSize - 1))
         return EINVAL;
 
-    Context->SectorNumber = Position->QuadPart / Context->SectorSize;
+    SectorNumber = Position->QuadPart / Context->SectorSize;
+    if (SectorNumber >= Context->SectorCount)
+        return EINVAL;
+
+    Context->SectorNumber = SectorNumber;
     return ESUCCESS;
 }
 
index d95f70f..712a057 100644 (file)
@@ -147,7 +147,7 @@ PcGetHarddiskConfigurationData(UCHAR DriveNumber, ULONG* pSize)
         DiskGeometry->SectorsPerTrack = ExtGeometry.SectorsPerTrack;
         DiskGeometry->NumberOfHeads = ExtGeometry.Heads;
     }
-    else if (MachDiskGetDriveGeometry(DriveNumber, &Geometry))
+    else if (PcDiskGetDriveGeometry(DriveNumber, &Geometry))
     {
         DiskGeometry->BytesPerSector = Geometry.BytesPerSector;
         DiskGeometry->NumberOfCylinders = Geometry.Cylinders;
index 2bdee5f..7b12084 100644 (file)
@@ -133,7 +133,7 @@ XboxGetHarddiskConfigurationData(UCHAR DriveNumber, ULONG* pSize)
     /* Get the disk geometry */
     //ExtGeometry.Size = sizeof(EXTENDED_GEOMETRY);
 
-    if (MachDiskGetDriveGeometry(DriveNumber, &Geometry))
+    if (XboxDiskGetDriveGeometry(DriveNumber, &Geometry))
     {
         DiskGeometry->BytesPerSector = Geometry.BytesPerSector;
         DiskGeometry->NumberOfCylinders = Geometry.Cylinders;
index 87c21fc..f9fc4f0 100644 (file)
@@ -240,9 +240,11 @@ static BOOLEAN PcDiskReadLogicalSectorsCHS(UCHAR DriveNumber, ULONGLONG SectorNu
     TRACE("PcDiskReadLogicalSectorsCHS()\n");
 
     /* Get the drive geometry */
-    if (!MachDiskGetDriveGeometry(DriveNumber, &DriveGeometry) ||
-        DriveGeometry.Sectors == 0 ||
-        DriveGeometry.Heads == 0)
+    //
+    // TODO: Cache this information for the given drive.
+    //
+    if (!PcDiskGetDriveGeometry(DriveNumber, &DriveGeometry) ||
+        DriveGeometry.Sectors == 0 || DriveGeometry.Heads == 0)
     {
         return FALSE;
     }
index 21b7390..92b032e 100644 (file)
@@ -178,8 +178,16 @@ static ARC_STATUS DiskGetFileInformation(ULONG FileId, FILEINFORMATION* Informat
     DISKCONTEXT* Context = FsGetDeviceSpecific(FileId);
 
     RtlZeroMemory(Information, sizeof(*Information));
-    Information->EndingAddress.QuadPart = Context->SectorCount * Context->SectorSize;
-    Information->CurrentAddress.QuadPart = Context->SectorNumber * Context->SectorSize;
+
+    /*
+     * The ARC specification mentions that for partitions, StartingAddress and
+     * EndingAddress are the start and end positions of the partition in terms
+     * of byte offsets from the start of the disk.
+     * CurrentAddress is the current offset into (i.e. relative to) the partition.
+     */
+    Information->StartingAddress.QuadPart = Context->SectorOffset * Context->SectorSize;
+    Information->EndingAddress.QuadPart   = (Context->SectorOffset + Context->SectorCount) * Context->SectorSize;
+    Information->CurrentAddress.QuadPart  = Context->SectorNumber * Context->SectorSize;
 
     return ESUCCESS;
 }
@@ -276,7 +284,7 @@ static ARC_STATUS DiskRead(ULONG FileId, VOID* Buffer, ULONG N, ULONG* Count)
 
     /* Read full sectors */
     ASSERT(Context->SectorNumber < 0xFFFFFFFF);
-    Lba = (ULONG)Context->SectorNumber;
+    Lba = (ULONG)(Context->SectorOffset + Context->SectorNumber);
     if (FullSectors > 0)
     {
         Srb = ExAllocatePool(PagedPool, sizeof(SCSI_REQUEST_BLOCK));
@@ -365,13 +373,18 @@ static ARC_STATUS DiskRead(ULONG FileId, VOID* Buffer, ULONG N, ULONG* Count)
 static ARC_STATUS DiskSeek(ULONG FileId, LARGE_INTEGER* Position, SEEKMODE SeekMode)
 {
     DISKCONTEXT* Context = FsGetDeviceSpecific(FileId);
+    ULONGLONG SectorNumber;
 
     if (SeekMode != SeekAbsolute)
         return EINVAL;
     if (Position->QuadPart & (Context->SectorSize - 1))
         return EINVAL;
 
-    Context->SectorNumber = Position->QuadPart / Context->SectorSize;
+    SectorNumber = Position->QuadPart / Context->SectorSize;
+    if (SectorNumber >= Context->SectorCount)
+        return EINVAL;
+
+    Context->SectorNumber = SectorNumber;
     return ESUCCESS;
 }
 
index 63a1283..7dad4f2 100644 (file)
@@ -1570,7 +1570,7 @@ const DEVVTBL* FatMount(ULONG DeviceId)
         FrLdrTempFree(Volume, TAG_FAT_VOLUME);
         return NULL;
     }
-    SectorCount.QuadPart = FileInformation.EndingAddress.QuadPart;
+    SectorCount.QuadPart = (FileInformation.EndingAddress.QuadPart - FileInformation.StartingAddress.QuadPart);
     SectorCount.QuadPart /= SECTOR_SIZE;
 
     //