static LONG DiskClose(ULONG FileId) { DISKCONTEXT* Context = FsGetDeviceSpecific(FileId); MmHeapFree(Context); return ESUCCESS; }
static LONG DiskRead(ULONG FileId, VOID* Buffer, ULONG N, ULONG* Count) { DISKCONTEXT* Context = FsGetDeviceSpecific(FileId); UCHAR* Ptr = (UCHAR*)Buffer; ULONG i, Length, Sectors; BOOLEAN ret; *Count = 0; i = 0; while (N > 0) { Length = N; if (Length > DISKREADBUFFER_SIZE) Length = DISKREADBUFFER_SIZE; Sectors = (Length + Context->SectorSize - 1) / Context->SectorSize; ret = MachDiskReadLogicalSectors( Context->DriveNumber, Context->SectorNumber + Context->SectorOffset + i, Sectors, (PVOID)DISKREADBUFFER); if (!ret) return EIO; RtlCopyMemory(Ptr, (PVOID)DISKREADBUFFER, Length); Ptr += Length; *Count += Length; N -= Length; i += Sectors; } return ESUCCESS; }
static ARC_STATUS DiskClose(ULONG FileId) { DISKCONTEXT* Context = FsGetDeviceSpecific(FileId); ExFreePool(Context); return ESUCCESS; }
LONG IsoClose(ULONG FileId) { PISO_FILE_INFO FileHandle = FsGetDeviceSpecific(FileId); MmHeapFree(FileHandle); return ESUCCESS; }
static ARC_STATUS DiskRead(ULONG FileId, VOID* Buffer, ULONG N, ULONG* Count) { DISKCONTEXT* Context = FsGetDeviceSpecific(FileId); PSCSI_REQUEST_BLOCK Srb; PCDB Cdb; ULONG FullSectors, NbSectors; ULONG Lba; *Count = 0; if (N == 0) return ESUCCESS; FullSectors = N / Context->SectorSize; NbSectors = (N + Context->SectorSize - 1) / Context->SectorSize; if (Context->SectorNumber + NbSectors >= Context->SectorCount) return EINVAL; if (FullSectors > 0xffff) return EINVAL; /* Read full sectors */ ASSERT(Context->SectorNumber < 0xFFFFFFFF); Lba = (ULONG)Context->SectorNumber; if (FullSectors > 0) { Srb = ExAllocatePool(PagedPool, sizeof(SCSI_REQUEST_BLOCK)); if (!Srb) return ENOMEM; RtlZeroMemory(Srb, sizeof(SCSI_REQUEST_BLOCK)); Srb->Length = sizeof(SCSI_REQUEST_BLOCK); Srb->Function = SRB_FUNCTION_EXECUTE_SCSI; Srb->PathId = Context->PathId; Srb->TargetId = Context->TargetId; Srb->Lun = Context->Lun; Srb->CdbLength = 10; Srb->SrbFlags = SRB_FLAGS_DATA_IN; Srb->DataTransferLength = FullSectors * Context->SectorSize; Srb->TimeOutValue = 5; /* in seconds */ Srb->DataBuffer = Buffer; Cdb = (PCDB)Srb->Cdb; Cdb->CDB10.OperationCode = SCSIOP_READ; Cdb->CDB10.LogicalUnitNumber = Srb->Lun; Cdb->CDB10.LogicalBlockByte0 = (Lba >> 24) & 0xff; Cdb->CDB10.LogicalBlockByte1 = (Lba >> 16) & 0xff; Cdb->CDB10.LogicalBlockByte2 = (Lba >> 8) & 0xff; Cdb->CDB10.LogicalBlockByte3 = Lba & 0xff; Cdb->CDB10.TransferBlocksMsb = (FullSectors >> 8) & 0xff; Cdb->CDB10.TransferBlocksLsb = FullSectors & 0xff; if (!SpiSendSynchronousSrb(Context->DeviceExtension, Srb)) { return EIO; } Buffer = (PUCHAR)Buffer + FullSectors * Context->SectorSize; N -= FullSectors * Context->SectorSize; *Count += FullSectors * Context->SectorSize; Lba += FullSectors; }
static LONG DiskGetFileInformation(ULONG FileId, FILEINFORMATION* Information) { DISKCONTEXT* Context = FsGetDeviceSpecific(FileId); RtlZeroMemory(Information, sizeof(FILEINFORMATION)); Information->EndingAddress.QuadPart = (Context->SectorOffset + Context->SectorCount) * Context->SectorSize; Information->CurrentAddress.QuadPart = (Context->SectorOffset + Context->SectorNumber) * Context->SectorSize; return ESUCCESS; }
static LONG DiskSeek(ULONG FileId, LARGE_INTEGER* Position, SEEKMODE SeekMode) { DISKCONTEXT* Context = FsGetDeviceSpecific(FileId); if (SeekMode != SeekAbsolute) return EINVAL; if (Position->LowPart & (Context->SectorSize - 1)) return EINVAL; Context->SectorNumber = (ULONG)(Position->QuadPart / Context->SectorSize); return ESUCCESS; }
LONG IsoGetFileInformation(ULONG FileId, FILEINFORMATION* Information) { PISO_FILE_INFO FileHandle = FsGetDeviceSpecific(FileId); TRACE("IsoGetFileInformation() FileSize = %d\n", FileHandle->FileSize); TRACE("IsoGetFileInformation() FilePointer = %d\n", FileHandle->FilePointer); RtlZeroMemory(Information, sizeof(FILEINFORMATION)); Information->EndingAddress.LowPart = FileHandle->FileSize; Information->CurrentAddress.LowPart = FileHandle->FilePointer; return ESUCCESS; }
static LONG DiskSeek(ULONG FileId, LARGE_INTEGER* Position, SEEKMODE SeekMode) { DISKCONTEXT* Context = FsGetDeviceSpecific(FileId); if (SeekMode != SeekAbsolute) return EINVAL; if (Position->LowPart & (Context->SectorSize - 1)) return EINVAL; /* FIXME: take HighPart into account */ Context->SectorNumber = Position->LowPart / Context->SectorSize; return ESUCCESS; }
LONG IsoSeek(ULONG FileId, LARGE_INTEGER* Position, SEEKMODE SeekMode) { PISO_FILE_INFO FileHandle = FsGetDeviceSpecific(FileId); TRACE("IsoSeek() NewFilePointer = %lu\n", Position->LowPart); if (SeekMode != SeekAbsolute) return EINVAL; if (Position->HighPart != 0) return EINVAL; if (Position->LowPart >= FileHandle->FileSize) return EINVAL; FileHandle->FilePointer = Position->LowPart; return ESUCCESS; }
static LONG DiskRead(ULONG FileId, VOID* Buffer, ULONG N, ULONG* Count) { DISKCONTEXT* Context = FsGetDeviceSpecific(FileId); UCHAR* Ptr = (UCHAR*)Buffer; ULONG Length, TotalSectors, MaxSectors, ReadSectors; BOOLEAN ret; ULONGLONG SectorOffset; TotalSectors = (N + Context->SectorSize - 1) / Context->SectorSize; MaxSectors = DISKREADBUFFER_SIZE / Context->SectorSize; SectorOffset = Context->SectorNumber + Context->SectorOffset; ret = 1; while (TotalSectors) { ReadSectors = TotalSectors; if (ReadSectors > MaxSectors) ReadSectors = MaxSectors; ret = MachDiskReadLogicalSectors( Context->DriveNumber, SectorOffset, ReadSectors, (PVOID)DISKREADBUFFER); if (!ret) break; Length = ReadSectors * Context->SectorSize; if (Length > N) Length = N; RtlCopyMemory(Ptr, (PVOID)DISKREADBUFFER, Length); Ptr += Length; N -= Length; SectorOffset += ReadSectors; TotalSectors -= ReadSectors; } *Count = (ULONG)(Ptr - (UCHAR*)Buffer); return (!ret) ? EIO : ESUCCESS; }
LONG IsoRead(ULONG FileId, VOID* Buffer, ULONG N, ULONG* Count) { PISO_FILE_INFO FileHandle = FsGetDeviceSpecific(FileId); UCHAR SectorBuffer[SECTORSIZE]; LARGE_INTEGER Position; ULONG DeviceId; ULONG FilePointer; ULONG SectorNumber; ULONG OffsetInSector; ULONG LengthInSector; ULONG NumberOfSectors; ULONG BytesRead; LONG ret; TRACE("IsoRead() Buffer = %p, N = %lu\n", Buffer, N); DeviceId = FsGetDeviceId(FileId); *Count = 0; // // If they are trying to read past the // end of the file then return success // with Count == 0 // FilePointer = FileHandle->FilePointer; if (FilePointer >= FileHandle->FileSize) { return ESUCCESS; } // // If they are trying to read more than there is to read // then adjust the amount to read // if (FilePointer + N > FileHandle->FileSize) { N = FileHandle->FileSize - FilePointer; } // // Ok, now we have to perform at most 3 calculations // I'll draw you a picture (using nifty ASCII art): // // CurrentFilePointer -+ // | // +----------------+ // | // +-----------+-----------+-----------+-----------+ // | Sector 1 | Sector 2 | Sector 3 | Sector 4 | // +-----------+-----------+-----------+-----------+ // | | // +---------------+--------------------+ // | // N -----------------+ // // 1 - The first calculation (and read) will align // the file pointer with the next sector // boundary (if we are supposed to read that much) // 2 - The next calculation (and read) will read // in all the full sectors that the requested // amount of data would cover (in this case // sectors 2 & 3). // 3 - The last calculation (and read) would read // in the remainder of the data requested out of // the last sector. // // // Only do the first read if we // aren't aligned on a cluster boundary // if (FilePointer % SECTORSIZE) { // // Do the math for our first read // SectorNumber = FileHandle->FileStart + (FilePointer / SECTORSIZE); OffsetInSector = FilePointer % SECTORSIZE; LengthInSector = (N > (SECTORSIZE - OffsetInSector)) ? (SECTORSIZE - OffsetInSector) : N; // // Now do the read and update Count, N, FilePointer, & Buffer // Position.HighPart = 0; Position.LowPart = SectorNumber * SECTORSIZE; ret = ArcSeek(DeviceId, &Position, SeekAbsolute); if (ret != ESUCCESS) { return ret; } ret = ArcRead(DeviceId, SectorBuffer, SECTORSIZE, &BytesRead); if (ret != ESUCCESS || BytesRead != SECTORSIZE) { return EIO; } RtlCopyMemory(Buffer, SectorBuffer + OffsetInSector, LengthInSector); *Count += LengthInSector; N -= LengthInSector; FilePointer += LengthInSector; Buffer = (PVOID)((ULONG_PTR)Buffer + LengthInSector); } // // Do the math for our second read (if any data left) // if (N > 0) { // // Determine how many full clusters we need to read // NumberOfSectors = (N / SECTORSIZE); SectorNumber = FileHandle->FileStart + (FilePointer / SECTORSIZE); // // Now do the read and update Count, N, FilePointer, & Buffer // Position.HighPart = 0; Position.LowPart = SectorNumber * SECTORSIZE; ret = ArcSeek(DeviceId, &Position, SeekAbsolute); if (ret != ESUCCESS) { return ret; } ret = ArcRead(DeviceId, Buffer, NumberOfSectors * SECTORSIZE, &BytesRead); if (ret != ESUCCESS || BytesRead != NumberOfSectors * SECTORSIZE) { return EIO; } *Count += NumberOfSectors * SECTORSIZE; N -= NumberOfSectors * SECTORSIZE; FilePointer += NumberOfSectors * SECTORSIZE; Buffer = (PVOID)((ULONG_PTR)Buffer + NumberOfSectors * SECTORSIZE); } // // Do the math for our third read (if any data left) // if (N > 0) { SectorNumber = FileHandle->FileStart + (FilePointer / SECTORSIZE); // // Now do the read and update Count, N, FilePointer, & Buffer // Position.HighPart = 0; Position.LowPart = SectorNumber * SECTORSIZE; ret = ArcSeek(DeviceId, &Position, SeekAbsolute); if (ret != ESUCCESS) { return ret; } ret = ArcRead(DeviceId, SectorBuffer, SECTORSIZE, &BytesRead); if (ret != ESUCCESS || BytesRead != SECTORSIZE) { return EIO; } RtlCopyMemory(Buffer, SectorBuffer, N); *Count += N; FilePointer += N; } TRACE("IsoRead() done\n"); return ESUCCESS; }