#include <freeldr.h>
#include <debug.h>
-
DBG_DEFAULT_CHANNEL(HWDETECT);
/*
DiskClose(ULONG FileId)
{
DISKCONTEXT* Context = FsGetDeviceSpecific(FileId);
-
FrLdrTempFree(Context, TAG_HW_DISK_CONTEXT);
return ESUCCESS;
}
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;
}
ULONGLONG SectorOffset = 0;
ULONGLONG SectorCount = 0;
PARTITION_TABLE_ENTRY PartitionTableEntry;
- CHAR FileName[1];
if (DiskReadBufferSize == 0)
{
return ENOMEM;
}
- if (!DissectArcPath(Path, FileName, &DriveNumber, &DrivePartition))
+ if (!DissectArcPath(Path, NULL, &DriveNumber, &DrivePartition))
return EINVAL;
if (DrivePartition == 0xff)
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)
DISKCONTEXT* Context = FsGetDeviceSpecific(FileId);
UCHAR* Ptr = (UCHAR*)Buffer;
ULONG Length, TotalSectors, MaxSectors, ReadSectors;
- BOOLEAN ret;
ULONGLONG SectorOffset;
+ BOOLEAN ret;
ASSERT(DiskReadBufferSize > 0);
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
+ // If MaxSectors is 0, this will lead to infinite loop.
// In release builds assertions are disabled, however we also have sanity checks in DiskOpen()
ASSERT(MaxSectors > 0);
TotalSectors -= ReadSectors;
}
- *Count = (ULONG)(Ptr - (UCHAR*)Buffer);
+ *Count = (ULONG)((ULONG_PTR)Ptr - (ULONG_PTR)Buffer);
+ Context->SectorNumber = SectorOffset - Context->SectorOffset;
return (!ret) ? EIO : ESUCCESS;
}
DiskSeek(ULONG FileId, LARGE_INTEGER* Position, SEEKMODE SeekMode)
{
DISKCONTEXT* Context = FsGetDeviceSpecific(FileId);
+ LARGE_INTEGER NewPosition = *Position;
+
+ switch (SeekMode)
+ {
+ case SeekAbsolute:
+ break;
+ case SeekRelative:
+ NewPosition.QuadPart += (Context->SectorNumber * Context->SectorSize);
+ break;
+ default:
+ ASSERT(FALSE);
+ return EINVAL;
+ }
- if (SeekMode != SeekAbsolute)
+ if (NewPosition.QuadPart & (Context->SectorSize - 1))
return EINVAL;
- if (Position->LowPart & (Context->SectorSize - 1))
+
+ /* Convert in number of sectors */
+ NewPosition.QuadPart /= Context->SectorSize;
+
+ /* HACK: CDROMs may have a SectorCount of 0 */
+ if (Context->SectorCount != 0 && NewPosition.QuadPart >= Context->SectorCount)
return EINVAL;
- Context->SectorNumber = Position->QuadPart / Context->SectorSize;
+ Context->SectorNumber = NewPosition.QuadPart;
return ESUCCESS;
}
DiskCount = 0;
DriveNumber = 0x80;
+ ASSERT(DiskReadBufferSize > 0);
+
/*
* There are some really broken BIOSes out there. There are even BIOSes
* that happily report success when you ask them to read from non-existent
return DiskCount;
}
+// FIXME: Copied from pcdisk.c
+// Actually this function is REALLY PC-specific!!
+static BOOLEAN
+DiskIsDriveRemovable(UCHAR DriveNumber)
+{
+ /*
+ * Hard disks use drive numbers >= 0x80 . So if the drive number
+ * indicates a hard disk then return FALSE.
+ * 0x49 is our magic ramdisk drive, so return FALSE for that too.
+ */
+ if ((DriveNumber >= 0x80) || (DriveNumber == 0x49))
+ return FALSE;
+
+ /* The drive is a floppy diskette so return TRUE */
+ return TRUE;
+}
+
+static BOOLEAN
+DiskGetBootPath(BOOLEAN IsPxe)
+{
+ if (*FrLdrBootPath)
+ return TRUE;
+
+ // FIXME! FIXME! Do this in some drive recognition procedure!!!!
+ if (IsPxe)
+ {
+ RtlStringCbCopyA(FrLdrBootPath, sizeof(FrLdrBootPath), "net(0)");
+ }
+ else
+ /* 0x49 is our magic ramdisk drive, so try to detect it first */
+ if (FrldrBootDrive == 0x49)
+ {
+ /* This is the ramdisk. See ArmInitializeBootDevices() too... */
+ // RtlStringCbPrintfA(FrLdrBootPath, sizeof(FrLdrBootPath), "ramdisk(%u)", 0);
+ RtlStringCbCopyA(FrLdrBootPath, sizeof(FrLdrBootPath), "ramdisk(0)");
+ }
+ else if (FrldrBootDrive < 0x80)
+ {
+ /* This is a floppy */
+ RtlStringCbPrintfA(FrLdrBootPath, sizeof(FrLdrBootPath),
+ "multi(0)disk(0)fdisk(%u)", FrldrBootDrive);
+ }
+ else if (FrldrBootPartition == 0xFF)
+ {
+ /* Boot Partition 0xFF is the magic value that indicates booting from CD-ROM (see isoboot.S) */
+ RtlStringCbPrintfA(FrLdrBootPath, sizeof(FrLdrBootPath),
+ "multi(0)disk(0)cdrom(%u)", FrldrBootDrive - 0x80);
+ }
+ else
+ {
+ ULONG BootPartition;
+ PARTITION_TABLE_ENTRY PartitionEntry;
+
+ /* This is a hard disk */
+ if (!DiskGetBootPartitionEntry(FrldrBootDrive, &PartitionEntry, &BootPartition))
+ {
+ ERR("Failed to get boot partition entry\n");
+ return FALSE;
+ }
+
+ FrldrBootPartition = BootPartition;
+
+ RtlStringCbPrintfA(FrLdrBootPath, sizeof(FrLdrBootPath),
+ "multi(0)disk(0)rdisk(%u)partition(%lu)",
+ FrldrBootDrive - 0x80, FrldrBootPartition);
+ }
+
+ return TRUE;
+}
+
BOOLEAN
PcInitializeBootDevices(VOID)
{
UCHAR DiskCount;
BOOLEAN BootDriveReported = FALSE;
ULONG i;
- CHAR BootPath[MAX_PATH];
DiskCount = EnumerateHarddisks(&BootDriveReported);
- /* Get the drive we're booting from */
- MachDiskGetBootPath(BootPath, sizeof(BootPath));
+ /* Initialize FrLdrBootPath, the boot path we're booting from (the "SystemPartition") */
+ DiskGetBootPath(PxeInit());
/* Add it, if it's a floppy or cdrom */
if ((FrldrBootDrive >= 0x80 && !BootDriveReported) ||
TRACE("Checksum: %x\n", Checksum);
/* Fill out the ARC disk block */
- AddReactOSArcDiskInfo(BootPath, Signature, Checksum, TRUE);
+ AddReactOSArcDiskInfo(FrLdrBootPath, Signature, Checksum, TRUE);
- FsRegisterDevice(BootPath, &DiskVtbl);
+ FsRegisterDevice(FrLdrBootPath, &DiskVtbl);
DiskCount++; // This is not accounted for in the number of pre-enumerated BIOS drives!
TRACE("Additional boot drive detected: 0x%02X\n", (int)FrldrBootDrive);
}