Skip to content
Permalink
Browse files

[FREELDR] Addendum / actual fix for ef76709

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
  • Loading branch information...
HBelusca committed Sep 17, 2019
1 parent ff85aa0 commit dd46d40fd26717a0526e58e612491d094f9c83b9
@@ -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;
}

@@ -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;
@@ -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;
@@ -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;
}
@@ -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;
}

@@ -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;

//

0 comments on commit dd46d40

Please sign in to comment.
You can’t perform that action at this time.