diff --git a/boot/freeldr/freeldr/arch/i386/hwdisk.c b/boot/freeldr/freeldr/arch/i386/hwdisk.c index 9f623a36fe6..ef13c24bbe4 100644 --- a/boot/freeldr/freeldr/arch/i386/hwdisk.c +++ b/boot/freeldr/freeldr/arch/i386/hwdisk.c @@ -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; } diff --git a/boot/freeldr/freeldr/arch/i386/machpc.c b/boot/freeldr/freeldr/arch/i386/machpc.c index d95f70f6a25..712a0575b44 100644 --- a/boot/freeldr/freeldr/arch/i386/machpc.c +++ b/boot/freeldr/freeldr/arch/i386/machpc.c @@ -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; diff --git a/boot/freeldr/freeldr/arch/i386/machxbox.c b/boot/freeldr/freeldr/arch/i386/machxbox.c index 2bdee5f0f45..7b12084c294 100644 --- a/boot/freeldr/freeldr/arch/i386/machxbox.c +++ b/boot/freeldr/freeldr/arch/i386/machxbox.c @@ -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; diff --git a/boot/freeldr/freeldr/arch/i386/pcdisk.c b/boot/freeldr/freeldr/arch/i386/pcdisk.c index 87c21fc3b64..f9fc4f0c1ba 100644 --- a/boot/freeldr/freeldr/arch/i386/pcdisk.c +++ b/boot/freeldr/freeldr/arch/i386/pcdisk.c @@ -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; } diff --git a/boot/freeldr/freeldr/disk/scsiport.c b/boot/freeldr/freeldr/disk/scsiport.c index 21b7390e021..92b032ea574 100644 --- a/boot/freeldr/freeldr/disk/scsiport.c +++ b/boot/freeldr/freeldr/disk/scsiport.c @@ -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; } diff --git a/boot/freeldr/freeldr/lib/fs/fat.c b/boot/freeldr/freeldr/lib/fs/fat.c index 63a1283a439..7dad4f2f516 100644 --- a/boot/freeldr/freeldr/lib/fs/fat.c +++ b/boot/freeldr/freeldr/lib/fs/fat.c @@ -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; //