mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-23 00:43:00 -05:00
sys: IRP_MJ_READ: implementation
This commit is contained in:
parent
b4160f4aac
commit
c7c367ccc8
@ -380,8 +380,13 @@ NTSTATUS FspMapLockedPagesInUserMode(PMDL Mdl, PVOID *PAddress);
|
||||
NTSTATUS FspCcInitializeCacheMap(PFILE_OBJECT FileObject, PCC_FILE_SIZES FileSizes,
|
||||
BOOLEAN PinAccess, PCACHE_MANAGER_CALLBACKS Callbacks, PVOID CallbackContext);
|
||||
NTSTATUS FspCcSetFileSizes(PFILE_OBJECT FileObject, PCC_FILE_SIZES FileSizes);
|
||||
NTSTATUS FspCcCopyRead(PFILE_OBJECT FileObject, PLARGE_INTEGER FileOffset, ULONG Length,
|
||||
BOOLEAN Wait, PVOID Buffer, PIO_STATUS_BLOCK IoStatus);
|
||||
NTSTATUS FspCcCopyWrite(PFILE_OBJECT FileObject, PLARGE_INTEGER FileOffset, ULONG Length,
|
||||
BOOLEAN Wait, PVOID Buffer);
|
||||
NTSTATUS FspCcMdlRead(PFILE_OBJECT FileObject, PLARGE_INTEGER FileOffset, ULONG Length,
|
||||
PMDL *PMdlChain, PIO_STATUS_BLOCK IoStatus);
|
||||
NTSTATUS FspCcMdlReadComplete(PFILE_OBJECT FileObject, PMDL MdlChain);
|
||||
NTSTATUS FspCcPrepareMdlWrite(PFILE_OBJECT FileObject, PLARGE_INTEGER FileOffset, ULONG Length,
|
||||
PMDL *PMdlChain, PIO_STATUS_BLOCK IoStatus);
|
||||
NTSTATUS FspCcMdlWriteComplete(PFILE_OBJECT FileObject, PLARGE_INTEGER FileOffset, PMDL MdlChain);
|
||||
|
162
src/sys/read.c
162
src/sys/read.c
@ -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);
|
||||
}
|
||||
|
@ -15,8 +15,13 @@ NTSTATUS FspMapLockedPagesInUserMode(PMDL Mdl, PVOID *PAddress);
|
||||
NTSTATUS FspCcInitializeCacheMap(PFILE_OBJECT FileObject, PCC_FILE_SIZES FileSizes,
|
||||
BOOLEAN PinAccess, PCACHE_MANAGER_CALLBACKS Callbacks, PVOID CallbackContext);
|
||||
NTSTATUS FspCcSetFileSizes(PFILE_OBJECT FileObject, PCC_FILE_SIZES FileSizes);
|
||||
NTSTATUS FspCcCopyRead(PFILE_OBJECT FileObject, PLARGE_INTEGER FileOffset, ULONG Length,
|
||||
BOOLEAN Wait, PVOID Buffer, PIO_STATUS_BLOCK IoStatus);
|
||||
NTSTATUS FspCcCopyWrite(PFILE_OBJECT FileObject, PLARGE_INTEGER FileOffset, ULONG Length,
|
||||
BOOLEAN Wait, PVOID Buffer);
|
||||
NTSTATUS FspCcMdlRead(PFILE_OBJECT FileObject, PLARGE_INTEGER FileOffset, ULONG Length,
|
||||
PMDL *PMdlChain, PIO_STATUS_BLOCK IoStatus);
|
||||
NTSTATUS FspCcMdlReadComplete(PFILE_OBJECT FileObject, PMDL MdlChain);
|
||||
NTSTATUS FspCcPrepareMdlWrite(PFILE_OBJECT FileObject, PLARGE_INTEGER FileOffset, ULONG Length,
|
||||
PMDL *PMdlChain, PIO_STATUS_BLOCK IoStatus);
|
||||
NTSTATUS FspCcMdlWriteComplete(PFILE_OBJECT FileObject, PLARGE_INTEGER FileOffset, PMDL MdlChain);
|
||||
@ -44,7 +49,10 @@ VOID FspSafeMdlDelete(FSP_SAFE_MDL *SafeMdl);
|
||||
#pragma alloc_text(PAGE, FspMapLockedPagesInUserMode)
|
||||
#pragma alloc_text(PAGE, FspCcInitializeCacheMap)
|
||||
#pragma alloc_text(PAGE, FspCcSetFileSizes)
|
||||
#pragma alloc_text(PAGE, FspCcCopyRead)
|
||||
#pragma alloc_text(PAGE, FspCcCopyWrite)
|
||||
#pragma alloc_text(PAGE, FspCcMdlRead)
|
||||
#pragma alloc_text(PAGE, FspCcMdlReadComplete)
|
||||
#pragma alloc_text(PAGE, FspCcPrepareMdlWrite)
|
||||
#pragma alloc_text(PAGE, FspCcMdlWriteComplete)
|
||||
#pragma alloc_text(PAGE, FspQuerySecurityDescriptorInfo)
|
||||
@ -249,6 +257,32 @@ NTSTATUS FspCcSetFileSizes(PFILE_OBJECT FileObject, PCC_FILE_SIZES FileSizes)
|
||||
}
|
||||
}
|
||||
|
||||
NTSTATUS FspCcCopyRead(PFILE_OBJECT FileObject, PLARGE_INTEGER FileOffset, ULONG Length,
|
||||
BOOLEAN Wait, PVOID Buffer, PIO_STATUS_BLOCK IoStatus)
|
||||
{
|
||||
PAGED_CODE();
|
||||
|
||||
NTSTATUS Result;
|
||||
|
||||
try
|
||||
{
|
||||
BOOLEAN Success = CcCopyRead(FileObject, FileOffset, Length, Wait, Buffer, IoStatus);
|
||||
Result = Success ? STATUS_SUCCESS : STATUS_PENDING;
|
||||
}
|
||||
except (EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
Result = GetExceptionCode();
|
||||
}
|
||||
|
||||
if (!NT_SUCCESS(Result))
|
||||
{
|
||||
IoStatus->Information = 0;
|
||||
IoStatus->Status = Result;
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
NTSTATUS FspCcCopyWrite(PFILE_OBJECT FileObject, PLARGE_INTEGER FileOffset, ULONG Length,
|
||||
BOOLEAN Wait, PVOID Buffer)
|
||||
{
|
||||
@ -265,6 +299,55 @@ NTSTATUS FspCcCopyWrite(PFILE_OBJECT FileObject, PLARGE_INTEGER FileOffset, ULON
|
||||
}
|
||||
}
|
||||
|
||||
NTSTATUS FspCcMdlRead(PFILE_OBJECT FileObject, PLARGE_INTEGER FileOffset, ULONG Length,
|
||||
PMDL *PMdlChain, PIO_STATUS_BLOCK IoStatus)
|
||||
{
|
||||
PAGED_CODE();
|
||||
|
||||
NTSTATUS Result;
|
||||
|
||||
*PMdlChain = 0;
|
||||
|
||||
try
|
||||
{
|
||||
CcMdlRead(FileObject, FileOffset, Length, PMdlChain, IoStatus);
|
||||
Result = IoStatus->Status;
|
||||
}
|
||||
except(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
Result = GetExceptionCode();
|
||||
}
|
||||
|
||||
if (!NT_SUCCESS(Result))
|
||||
{
|
||||
if (0 != *PMdlChain)
|
||||
{
|
||||
CcMdlReadComplete(FileObject, *PMdlChain);
|
||||
*PMdlChain = 0;
|
||||
}
|
||||
|
||||
IoStatus->Information = 0;
|
||||
IoStatus->Status = Result;
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
NTSTATUS FspCcMdlReadComplete(PFILE_OBJECT FileObject, PMDL MdlChain)
|
||||
{
|
||||
PAGED_CODE();
|
||||
|
||||
try
|
||||
{
|
||||
CcMdlReadComplete(FileObject, MdlChain);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
except (EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
return GetExceptionCode();
|
||||
}
|
||||
}
|
||||
|
||||
NTSTATUS FspCcPrepareMdlWrite(PFILE_OBJECT FileObject, PLARGE_INTEGER FileOffset, ULONG Length,
|
||||
PMDL *PMdlChain, PIO_STATUS_BLOCK IoStatus)
|
||||
{
|
||||
|
@ -188,7 +188,7 @@ static NTSTATUS FspFsvolWriteCached(
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
Result = FspCcCopyWrite(FileObject, &WriteOffset, WriteLength, CanWait || Retrying, Buffer);
|
||||
Result = FspCcCopyWrite(FileObject, &WriteOffset, WriteLength, CanWait, Buffer);
|
||||
if (STATUS_PENDING == Result)
|
||||
{
|
||||
FspFileNodeRelease(FileNode, Main);
|
||||
@ -201,8 +201,8 @@ static NTSTATUS FspFsvolWriteCached(
|
||||
{
|
||||
ASSERT(0 == Irp->MdlAddress);
|
||||
|
||||
Result = FspCcPrepareMdlWrite(FileObject, &WriteOffset, WriteLength,
|
||||
&Irp->MdlAddress, &Irp->IoStatus);
|
||||
Result = FspCcPrepareMdlWrite(FileObject, &WriteOffset, WriteLength, &Irp->MdlAddress,
|
||||
&Irp->IoStatus);
|
||||
if (!NT_SUCCESS(Result))
|
||||
{
|
||||
FspFileNodeRelease(FileNode, Main);
|
||||
|
Loading…
x
Reference in New Issue
Block a user