static ARC_STATUS DiskClose(ULONG FileId)
{
DISKCONTEXT* Context = FsGetDeviceSpecific(FileId);
-
ExFreePool(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;
}
/* 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));
Buffer = (PUCHAR)Buffer + FullSectors * Context->SectorSize;
N -= FullSectors * Context->SectorSize;
*Count += FullSectors * Context->SectorSize;
+ Context->SectorNumber += FullSectors;
Lba += FullSectors;
}
}
RtlCopyMemory(Buffer, Sector, N);
*Count += N;
+ /* Context->SectorNumber remains untouched (incomplete sector read) */
ExFreePool(Sector);
}
static ARC_STATUS 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->QuadPart & (Context->SectorSize - 1))
+
+ /* Convert in number of sectors */
+ NewPosition.QuadPart /= Context->SectorSize;
+ if (NewPosition.QuadPart >= Context->SectorCount)
return EINVAL;
- Context->SectorNumber = Position->QuadPart / Context->SectorSize;
+ Context->SectorNumber = NewPosition.QuadPart;
return ESUCCESS;
}
-static const DEVVTBL DiskVtbl = {
+static const DEVVTBL DiskVtbl =
+{
DiskClose,
DiskGetFileInformation,
DiskOpen,
InitializeListHead(&ModuleListHead);
/* Create full ntbootdd.sys path */
- MachDiskGetBootPath(NtBootDdPath, sizeof(NtBootDdPath));
+ strcpy(NtBootDdPath, FrLdrBootPath);
strcat(NtBootDdPath, "\\NTBOOTDD.SYS");
/* Load file */
- Success = WinLdrLoadImage(NtBootDdPath, LoaderBootDriver, &ImageBase);
+ Success = PeLdrLoadImage(NtBootDdPath, LoaderBootDriver, &ImageBase);
if (!Success)
{
/* That's OK. File simply doesn't exist */
}
/* Allocate a DTE for ntbootdd */
- Success = WinLdrAllocateDataTableEntry(&ModuleListHead, "ntbootdd.sys",
- "NTBOOTDD.SYS", ImageBase, &BootDdDTE);
+ Success = PeLdrAllocateDataTableEntry(&ModuleListHead, "ntbootdd.sys",
+ "NTBOOTDD.SYS", ImageBase, &BootDdDTE);
if (!Success)
return EIO;
/* Add the PE part of freeldr.sys to the list of loaded executables, it
contains ScsiPort* exports, imported by ntbootdd.sys */
- Success = WinLdrAllocateDataTableEntry(&ModuleListHead, "scsiport.sys",
- "FREELDR.SYS", &__ImageBase, &FreeldrDTE);
+ Success = PeLdrAllocateDataTableEntry(&ModuleListHead, "scsiport.sys",
+ "FREELDR.SYS", &__ImageBase, &FreeldrDTE);
if (!Success)
{
RemoveEntryList(&BootDdDTE->InLoadOrderLinks);
}
/* Fix imports */
- Success = WinLdrScanImportDescriptorTable(&ModuleListHead, "", BootDdDTE);
+ Success = PeLdrScanImportDescriptorTable(&ModuleListHead, "", BootDdDTE);
/* Now unlinkt the DTEs, they won't be valid later */
RemoveEntryList(&BootDdDTE->InLoadOrderLinks);