sys: IRP_MJ_READ: implementation

This commit is contained in:
Bill Zissimopoulos
2016-03-04 17:08:46 -08:00
parent b4160f4aac
commit c7c367ccc8
4 changed files with 249 additions and 7 deletions

View File

@ -7,18 +7,160 @@
#include <sys/driver.h>
static NTSTATUS FspFsvolRead(
PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
static NTSTATUS FspFsvolReadCached(
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp,
BOOLEAN CanWait);
static NTSTATUS FspFsvolReadNonCached(
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
FSP_IOCMPL_DISPATCH FspFsvolReadComplete;
static FSP_IOP_REQUEST_FINI FspFsvolReadNonCachedRequestFini;
FSP_DRIVER_DISPATCH FspRead;
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, FspFsvolRead)
#pragma alloc_text(PAGE, FspFsvolReadCached)
#pragma alloc_text(PAGE, FspFsvolReadNonCached)
#pragma alloc_text(PAGE, FspFsvolReadComplete)
#pragma alloc_text(PAGE, FspFsvolReadNonCachedRequestFini)
#pragma alloc_text(PAGE, FspRead)
#endif
static NTSTATUS FspFsvolRead(
PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
{
PAGED_CODE();
/* is this a valid FileObject? */
if (!FspFileNodeIsValid(IrpSp->FileObject->FsContext))
return STATUS_INVALID_DEVICE_REQUEST;
NTSTATUS Result;
PFILE_OBJECT FileObject = IrpSp->FileObject;
FSP_FILE_NODE *FileNode = FileObject->FsContext;
/* is this an MDL complete request? */
if (FlagOn(IrpSp->MinorFunction, IRP_MN_COMPLETE))
{
Result = FspCcMdlReadComplete(FileObject, Irp->MdlAddress);
Irp->MdlAddress = 0;
return Result;
}
/* only regular files can be read */
if (FileNode->IsDirectory)
return STATUS_INVALID_PARAMETER;
/* do we have anything to read? */
if (0 == IrpSp->Parameters.Read.Length)
{
Irp->IoStatus.Information = 0;
return STATUS_SUCCESS;
}
/* are we doing cached or non-cached I/O? */
if (FlagOn(FileObject->Flags, FO_CACHE_SUPPORTED) &&
!FlagOn(Irp->Flags, IRP_PAGING_IO | IRP_NOCACHE))
Result = FspFsvolReadCached(FsvolDeviceObject, Irp, IrpSp, IoIsOperationSynchronous(Irp));
else
Result = FspFsvolReadNonCached(FsvolDeviceObject, Irp, IrpSp);
return Result;
}
static NTSTATUS FspFsvolReadCached(
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp,
BOOLEAN CanWait)
{
PAGED_CODE();
NTSTATUS Result;
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
PFILE_OBJECT FileObject = IrpSp->FileObject;
FSP_FILE_NODE *FileNode = FileObject->FsContext;
FSP_FILE_DESC *FileDesc = FileObject->FsContext2;
LARGE_INTEGER ReadOffset = IrpSp->Parameters.Read.ByteOffset;
ULONG ReadLength = IrpSp->Parameters.Read.Length;
#if 0
/* !!!: lock support! */
ULONG ReadKey = IrpSp->Parameters.Read.Key;
#endif
BOOLEAN SynchronousIo = BooleanFlagOn(FileObject->Flags, FO_SYNCHRONOUS_IO);
FSP_FSCTL_FILE_INFO FileInfo;
CC_FILE_SIZES FileSizes;
BOOLEAN Success;
ASSERT(FileNode == FileDesc->FileNode);
/* try to acquire the FileNode Main shared */
Success = DEBUGTEST(90, TRUE) &&
FspFileNodeTryAcquireSharedF(FileNode, FspFileNodeAcquireMain, CanWait);
if (!Success)
return FspWqRepostIrpWorkItem(Irp, FspFsvolReadCached, 0);
/* initialize cache if not already initialized! */
if (0 == FileObject->PrivateCacheMap)
{
ASSERT(FspTimeoutInfinity32 == FsvolDeviceExtension->VolumeParams.FileInfoTimeout);
FspFileNodeGetFileInfo(FileNode, &FileInfo);
FileSizes.AllocationSize.QuadPart = FileInfo.AllocationSize;
FileSizes.FileSize.QuadPart = FileInfo.FileSize;
FileSizes.ValidDataLength.QuadPart = MAXLONGLONG;
Result = FspCcInitializeCacheMap(FileObject, &FileSizes, FALSE,
&FspCacheManagerCallbacks, FileNode);
if (!NT_SUCCESS(Result))
{
FspFileNodeRelease(FileNode, Main);
return Result;
}
}
/* are we using the copy or MDL interface? */
if (!FlagOn(IrpSp->MinorFunction, IRP_MN_MDL))
{
PVOID Buffer;
Buffer = 0 == Irp->MdlAddress ?
Irp->UserBuffer : MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
if (0 == Buffer)
{
FspFileNodeRelease(FileNode, Main);
return STATUS_INSUFFICIENT_RESOURCES;
}
Result = FspCcCopyRead(FileObject, &ReadOffset, ReadLength, CanWait, Buffer,
&Irp->IoStatus);
if (STATUS_PENDING == Result)
{
FspFileNodeRelease(FileNode, Main);
return FspWqRepostIrpWorkItem(Irp, FspFsvolReadCached, 0);
}
}
else
{
ASSERT(0 == Irp->MdlAddress);
Result = FspCcMdlRead(FileObject, &ReadOffset, ReadLength, &Irp->MdlAddress,
&Irp->IoStatus);
if (!NT_SUCCESS(Result))
{
FspFileNodeRelease(FileNode, Main);
return Result;
}
}
/* update the current file offset if synchronous I/O */
if (SynchronousIo)
FileObject->CurrentByteOffset.QuadPart = ReadOffset.QuadPart + Irp->IoStatus.Information;
FspFileNodeRelease(FileNode, Main);
return STATUS_SUCCESS;
}
static NTSTATUS FspFsvolReadNonCached(
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
{
PAGED_CODE();
@ -30,7 +172,13 @@ NTSTATUS FspFsvolReadComplete(
{
FSP_ENTER_IOC(PAGED_CODE());
FSP_LEAVE_IOC("%s", "");
FSP_LEAVE_IOC(
"FileObject=%p, UserBuffer=%p, MdlAddress=%p, "
"Key=%#lx, ByteOffset=%#lx:%#lx, Length=%ld",
IrpSp->FileObject, Irp->UserBuffer, Irp->MdlAddress,
IrpSp->Parameters.Read.Key,
IrpSp->Parameters.Read.ByteOffset.HighPart, IrpSp->Parameters.Read.ByteOffset.LowPart,
IrpSp->Parameters.Read.Length);
}
NTSTATUS FspRead(
@ -46,5 +194,11 @@ NTSTATUS FspRead(
FSP_RETURN(Result = STATUS_INVALID_DEVICE_REQUEST);
}
FSP_LEAVE_MJ("%s", "");
FSP_LEAVE_MJ(
"FileObject=%p, UserBuffer=%p, MdlAddress=%p, "
"Key=%#lx, ByteOffset=%#lx:%#lx, Length=%ld",
IrpSp->FileObject, Irp->UserBuffer, Irp->MdlAddress,
IrpSp->Parameters.Read.Key,
IrpSp->Parameters.Read.ByteOffset.HighPart, IrpSp->Parameters.Read.ByteOffset.LowPart,
IrpSp->Parameters.Read.Length);
}