From 778939d018d5ffc4c1e04901b9830d534cead7d8 Mon Sep 17 00:00:00 2001 From: Bill Zissimopoulos Date: Tue, 28 Nov 2017 14:18:48 -0800 Subject: [PATCH] sys,dll,inc: implement user mode locking --- inc/winfsp/fsctl.h | 19 ++++++++- inc/winfsp/winfsp.h | 97 ++++++++++++++++++++++++++++++++++++++++++++- src/dll/fs.c | 6 +++ src/dll/fsop.c | 38 ++++++++++++++++++ src/sys/cleanup.c | 3 ++ src/sys/driver.c | 1 + src/sys/driver.h | 2 + src/sys/file.c | 16 +------- src/sys/lockctl.c | 53 +++++++++++++++++++++++++ src/sys/read.c | 7 +++- src/sys/write.c | 10 +++-- 11 files changed, 229 insertions(+), 23 deletions(-) diff --git a/inc/winfsp/fsctl.h b/inc/winfsp/fsctl.h index da6bd84a..2ff3de84 100644 --- a/inc/winfsp/fsctl.h +++ b/inc/winfsp/fsctl.h @@ -153,7 +153,8 @@ typedef struct UINT32 PassQueryDirectoryPattern:1; /* pass Pattern during QueryDirectory operations */ UINT32 AlwaysUseDoubleBuffering:1; UINT32 PassQueryDirectoryFileName:1; /* pass FileName during QueryDirectory (GetDirInfoByName) */ - UINT32 KmReservedFlags:2; + UINT32 UserModeFileLocking:1; /* pass file locking requests to user mode */ + UINT32 KmReservedFlags:1; /* user-mode flags */ UINT32 UmFileContextIsUserContext2:1; /* user mode: FileContext parameter is UserContext2 */ UINT32 UmFileContextIsFullContext:1; /* user mode: FileContext parameter is FullContext */ @@ -259,6 +260,7 @@ typedef struct UINT32 SetLastAccessTime:1; UINT32 SetLastWriteTime:1; UINT32 SetChangeTime:1; + UINT32 UnlockAll:1; } Cleanup; struct { @@ -273,6 +275,7 @@ typedef struct UINT64 Offset; UINT32 Length; UINT32 Key; + UINT32 ProcessId; } Read; struct { @@ -283,6 +286,8 @@ typedef struct UINT32 Length; UINT32 Key; UINT32 ConstrainedIo:1; + UINT32 ReservedFlags:31; + UINT32 ProcessId; } Write; struct { @@ -359,6 +364,18 @@ typedef struct UINT16 TargetOnFileSystem; /* the target of the symbolic link is on this file system */ } FileSystemControl; struct + { + UINT64 UserContext; + UINT64 UserContext2; + UINT32 LockFunction; + UINT64 Offset; + UINT64 Length; + UINT32 Key; + UINT32 ProcessId; + UINT32 Exclusive:1; + UINT32 FailImmediately:1; + } LockControl; + struct { UINT64 UserContext; UINT64 UserContext2; diff --git a/inc/winfsp/winfsp.h b/inc/winfsp/winfsp.h index 9fd5b97f..beb1c79d 100644 --- a/inc/winfsp/winfsp.h +++ b/inc/winfsp/winfsp.h @@ -133,6 +133,7 @@ enum FspCleanupSetLastAccessTime = 0x20, FspCleanupSetLastWriteTime = 0x40, FspCleanupSetChangeTime = 0x80, + FspCleanupUnlockAll = 0x0100, }; /** * @class FSP_FILE_SYSTEM @@ -822,12 +823,80 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE NTSTATUS (*GetDirInfoByName)(FSP_FILE_SYSTEM *FileSystem, PVOID FileContext, PWSTR FileName, FSP_FSCTL_DIR_INFO *DirInfo); + /** + * Lock a file range. + * + * At the time of this call the FSD has already done its own locking processing. + * Thus the kernel may fail a lock control request or a Read or Write without + * informing the user mode file system. + * + * @param FileSystem + * The file system on which this request is posted. + * @param FileContext + * The file context of the file to be locked. + * @param Offset + * Offset within the file to lock. + * @param Length + * Length of data to lock. + * @param Owner + * Lock owner. This 64-bit value consists of a PID in the high 32-bits and a "Key" + * in the low 32-bits. The PID is that of the process requesting the lock. The Key + * is an arbitrary value. + * + * The triplet (FileDesc,PID,Key) uniquely identifies the lock owner. + * @param Exclusive + * When TRUE an exclusive lock is requested. Otherwise a shared lock is requested. + * @param FailImmediately + * When TRUE the function should return immediately if it is unable to acquire the + * requested lock. Otherwise the function should wait until the lock can be granted. + * In this case the function may also return STATUS_PENDING. + * @return + * STATUS_SUCCESS or error code. STATUS_PENDING is supported allowing for asynchronous + * operation. + */ + NTSTATUS (*Lock)(FSP_FILE_SYSTEM *FileSystem, + PVOID FileContext, UINT64 Offset, UINT64 Length, UINT64 Owner, + BOOLEAN Exclusive, BOOLEAN FailImmediately); + /** + * Unlock file ranges. + * + * At the time of this call the FSD has already done its own locking processing. + * Thus the kernel may fail a lock control request or a Read or Write without + * informing the user mode file system. + * + * An Unlock operation with Offset == Length == -1 is a request to remove multiple locks. + * The set of possible locks to remove includes all locks made by the process described + * by the Owner parameter through the file descriptor described by the FileContext parameter. + * If the Key portion of the Owner parameter is 0, all the locks in the set are removed. + * If the Key portion of the Owner paramter is non-0, only locks that match the Key are + * removed. + * + * @param FileSystem + * The file system on which this request is posted. + * @param FileContext + * The file context of the file to be unlocked. + * @param Offset + * Offset within the file to unlock. + * @param Length + * Length of data to unlock. + * @param Owner + * Lock owner. This 64-bit value consists of a PID in the high 32-bits and a "Key" + * in the low 32-bits. The PID is that of the process requesting the lock. The Key + * is an arbitrary value. + * + * The triplet (FileDesc,PID,Key) uniquely identifies the lock owner. + * @return + * STATUS_SUCCESS or error code. STATUS_PENDING is supported allowing for asynchronous + * operation. + */ + NTSTATUS (*Unlock)(FSP_FILE_SYSTEM *FileSystem, + PVOID FileContext, UINT64 Offset, UINT64 Length, UINT64 Owner); /* * This ensures that this interface will always contain 64 function pointers. * Please update when changing the interface as it is important for future compatibility. */ - NTSTATUS (*Reserved[39])(); + NTSTATUS (*Reserved[37])(); } FSP_FILE_SYSTEM_INTERFACE; FSP_FSCTL_STATIC_ASSERT(sizeof(FSP_FILE_SYSTEM_INTERFACE) == 64 * sizeof(NTSTATUS (*)()), "FSP_FILE_SYSTEM_INTERFACE must have 64 entries."); @@ -1086,7 +1155,7 @@ BOOLEAN FspFileSystemIsOperationCaseSensitive(VOID) } FSP_API BOOLEAN FspFileSystemIsOperationCaseSensitiveF(VOID); /** - * Gets the originating process ID. + * Get the originating process ID. * * Valid only during Create, Open and Rename requests when the target exists. */ @@ -1107,6 +1176,28 @@ UINT32 FspFileSystemOperationProcessId(VOID) } } FSP_API UINT32 FspFileSystemOperationProcessIdF(VOID); +/** + * Get the lock owner. + * + * Valid only during Read, Write, Lock and Unlock requests. + */ +static inline +UINT64 FspFileSystemOperationLockOwner(VOID) +{ + FSP_FSCTL_TRANSACT_REQ *Request = FspFileSystemGetOperationContext()->Request; + switch (Request->Kind) + { + case FspFsctlTransactReadKind: + return ((UINT64)Request->Req.Read.ProcessId << 32) | (UINT64)Request->Req.Read.Key; + case FspFsctlTransactWriteKind: + return ((UINT64)Request->Req.Write.ProcessId << 32) | (UINT64)Request->Req.Write.Key; + case FspFsctlTransactLockControlKind: + return ((UINT64)Request->Req.LockControl.ProcessId << 32) | (UINT64)Request->Req.LockControl.Key; + default: + return 0; + } +} +FSP_API UINT64 FspFileSystemOperationLockOwnerF(VOID); /* * Operations @@ -1141,6 +1232,8 @@ FSP_API NTSTATUS FspFileSystemOpQueryDirectory(FSP_FILE_SYSTEM *FileSystem, FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response); FSP_API NTSTATUS FspFileSystemOpFileSystemControl(FSP_FILE_SYSTEM *FileSystem, FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response); +FSP_API NTSTATUS FspFileSystemOpLockControl(FSP_FILE_SYSTEM *FileSystem, + FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response); FSP_API NTSTATUS FspFileSystemOpQuerySecurity(FSP_FILE_SYSTEM *FileSystem, FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response); FSP_API NTSTATUS FspFileSystemOpSetSecurity(FSP_FILE_SYSTEM *FileSystem, diff --git a/src/dll/fs.c b/src/dll/fs.c index 66d7e634..235829ee 100644 --- a/src/dll/fs.c +++ b/src/dll/fs.c @@ -162,6 +162,7 @@ FSP_API NTSTATUS FspFileSystemCreate(PWSTR DevicePath, FileSystem->Operations[FspFsctlTransactSetVolumeInformationKind] = FspFileSystemOpSetVolumeInformation; FileSystem->Operations[FspFsctlTransactQueryDirectoryKind] = FspFileSystemOpQueryDirectory; FileSystem->Operations[FspFsctlTransactFileSystemControlKind] = FspFileSystemOpFileSystemControl; + FileSystem->Operations[FspFsctlTransactLockControlKind] = FspFileSystemOpLockControl; FileSystem->Operations[FspFsctlTransactQuerySecurityKind] = FspFileSystemOpQuerySecurity; FileSystem->Operations[FspFsctlTransactSetSecurityKind] = FspFileSystemOpSetSecurity; FileSystem->Operations[FspFsctlTransactQueryStreamInformationKind] = FspFileSystemOpQueryStreamInformation; @@ -688,3 +689,8 @@ FSP_API UINT32 FspFileSystemOperationProcessIdF(VOID) { return FspFileSystemOperationProcessId(); } + +FSP_API UINT64 FspFileSystemOperationLockOwnerF(VOID) +{ + return FspFileSystemOperationLockOwner(); +} diff --git a/src/dll/fsop.c b/src/dll/fsop.c index 4e9d0469..7b837627 100644 --- a/src/dll/fsop.c +++ b/src/dll/fsop.c @@ -886,6 +886,7 @@ FSP_API NTSTATUS FspFileSystemOpCleanup(FSP_FILE_SYSTEM *FileSystem, (0 != Request->Req.Cleanup.SetArchiveBit ? FspCleanupSetArchiveBit : 0) | (0 != Request->Req.Cleanup.SetLastAccessTime ? FspCleanupSetLastAccessTime : 0) | (0 != Request->Req.Cleanup.SetLastWriteTime ? FspCleanupSetLastWriteTime : 0) | + (0 != Request->Req.Cleanup.UnlockAll ? FspCleanupUnlockAll : 0) | (0 != Request->Req.Cleanup.SetChangeTime ? FspCleanupSetChangeTime : 0)); return STATUS_SUCCESS; @@ -1247,6 +1248,43 @@ FSP_API NTSTATUS FspFileSystemOpFileSystemControl(FSP_FILE_SYSTEM *FileSystem, return Result; } +FSP_API NTSTATUS FspFileSystemOpLockControl(FSP_FILE_SYSTEM *FileSystem, + FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response) +{ + NTSTATUS Result; + + Result = STATUS_INVALID_DEVICE_REQUEST; + switch (Request->Req.LockControl.LockFunction) + { + case 0x01/*IRP_MN_LOCK*/: + if (0 != FileSystem->Interface->Lock) + Result = FileSystem->Interface->Lock(FileSystem, + (PVOID)ValOfFileContext(Request->Req.LockControl), + Request->Req.LockControl.Offset, Request->Req.LockControl.Length, + ((UINT64)Request->Req.LockControl.ProcessId << 32) | (UINT64)Request->Req.LockControl.Key, + 0 != Request->Req.LockControl.Exclusive, + 0 != Request->Req.LockControl.FailImmediately); + break; + case 0x02/*IRP_MN_UNLOCK_SINGLE*/: + if (0 != FileSystem->Interface->Unlock) + Result = FileSystem->Interface->Unlock(FileSystem, + (PVOID)ValOfFileContext(Request->Req.LockControl), + Request->Req.LockControl.Offset, Request->Req.LockControl.Length, + ((UINT64)Request->Req.LockControl.ProcessId << 32) | (UINT64)Request->Req.LockControl.Key); + break; + case 0x03/*IRP_MN_UNLOCK_ALL*/: + case 0x04/*IRP_MN_UNLOCK_ALL_BY_KEY*/: + if (0 != FileSystem->Interface->Unlock) + Result = FileSystem->Interface->Unlock(FileSystem, + (PVOID)ValOfFileContext(Request->Req.LockControl), + (UINT64)-1LL, (UINT64)-1LL, + ((UINT64)Request->Req.LockControl.ProcessId << 32) | (UINT64)Request->Req.LockControl.Key); + break; + } + + return Result; +} + FSP_API NTSTATUS FspFileSystemOpQuerySecurity(FSP_FILE_SYSTEM *FileSystem, FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response) { diff --git a/src/sys/cleanup.c b/src/sys/cleanup.c index b4470b42..912ab189 100644 --- a/src/sys/cleanup.c +++ b/src/sys/cleanup.c @@ -117,6 +117,8 @@ static NTSTATUS FspFsvolCleanup( Request->Req.Cleanup.SetLastWriteTime = FileModified && !FileDesc->DidSetLastWriteTime; Request->Req.Cleanup.SetChangeTime = (FileModified || FileDesc->DidSetMetadata) && !FileDesc->DidSetChangeTime; + Request->Req.Cleanup.UnlockAll = FsvolDeviceExtension->VolumeParams.UserModeFileLocking && + FsRtlAreThereCurrentOrInProgressFileLocks(&FileNode->FileLock); FspFileNodeAcquireExclusive(FileNode, Pgio); @@ -128,6 +130,7 @@ static NTSTATUS FspFsvolCleanup( Request->Req.Cleanup.SetArchiveBit || Request->Req.Cleanup.SetLastWriteTime || Request->Req.Cleanup.SetChangeTime || + Request->Req.Cleanup.UnlockAll || !FsvolDeviceExtension->VolumeParams.PostCleanupWhenModifiedOnly) /* * Note that it is still possible for this request to not be delivered, diff --git a/src/sys/driver.c b/src/sys/driver.c index 1cbf9e46..674e4b23 100644 --- a/src/sys/driver.c +++ b/src/sys/driver.c @@ -128,6 +128,7 @@ NTSTATUS DriverEntry( FspIopCompleteFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = FspFsvolFileSystemControlComplete; FspIopCompleteFunction[IRP_MJ_DEVICE_CONTROL] = FspFsvolDeviceControlComplete; FspIopCompleteFunction[IRP_MJ_SHUTDOWN] = FspFsvolShutdownComplete; + FspFileNodeCompleteLockIrp = FspFsvolLockControlForward; FspIopCompleteFunction[IRP_MJ_LOCK_CONTROL] = FspFsvolLockControlComplete; FspIopCompleteFunction[IRP_MJ_CLEANUP] = FspFsvolCleanupComplete; FspIopCompleteFunction[IRP_MJ_QUERY_SECURITY] = FspFsvolQuerySecurityComplete; diff --git a/src/sys/driver.h b/src/sys/driver.h index 9cf2c752..e155e35b 100644 --- a/src/sys/driver.h +++ b/src/sys/driver.h @@ -316,6 +316,7 @@ FSP_IOPREP_DISPATCH FspFsvolDirectoryControlPrepare; FSP_IOCMPL_DISPATCH FspFsvolDirectoryControlComplete; FSP_IOCMPL_DISPATCH FspFsvolFileSystemControlComplete; FSP_IOCMPL_DISPATCH FspFsvolFlushBuffersComplete; +NTSTATUS FspFsvolLockControlForward(PVOID Context, PIRP Irp); FSP_IOCMPL_DISPATCH FspFsvolLockControlComplete; FSP_IOCMPL_DISPATCH FspFsvolQueryEaComplete; FSP_IOCMPL_DISPATCH FspFsvolQueryInformationComplete; @@ -1564,6 +1565,7 @@ extern CACHE_MANAGER_CALLBACKS FspCacheManagerCallbacks; extern FSP_IOPREP_DISPATCH *FspIopPrepareFunction[]; extern FSP_IOCMPL_DISPATCH *FspIopCompleteFunction[]; extern ERESOURCE FspDeviceGlobalResource; +extern PCOMPLETE_LOCK_IRP_ROUTINE FspFileNodeCompleteLockIrp; extern WCHAR FspFileDescDirectoryPatternMatchAll[]; extern const GUID FspMainFileOpenEcpGuid; extern ULONG FspProcessorCount; diff --git a/src/sys/file.c b/src/sys/file.c index bc60a64a..8c5ab6ea 100644 --- a/src/sys/file.c +++ b/src/sys/file.c @@ -83,7 +83,6 @@ VOID FspFileNodeInvalidateStreamInfo(FSP_FILE_NODE *FileNode); VOID FspFileNodeNotifyChange(FSP_FILE_NODE *FileNode, ULONG Filter, ULONG Action, BOOLEAN InvalidateCaches); NTSTATUS FspFileNodeProcessLockIrp(FSP_FILE_NODE *FileNode, PIRP Irp); -static NTSTATUS FspFileNodeCompleteLockIrp(PVOID Context, PIRP Irp); NTSTATUS FspFileDescCreate(FSP_FILE_DESC **PFileDesc); VOID FspFileDescDelete(FSP_FILE_DESC *FileDesc); NTSTATUS FspFileDescResetDirectory(FSP_FILE_DESC *FileDesc, @@ -149,7 +148,6 @@ VOID FspFileNodeOplockComplete(PVOID Context, PIRP Irp); // !#pragma alloc_text(PAGE, FspFileNodeInvalidateStreamInfo) #pragma alloc_text(PAGE, FspFileNodeNotifyChange) #pragma alloc_text(PAGE, FspFileNodeProcessLockIrp) -#pragma alloc_text(PAGE, FspFileNodeCompleteLockIrp) #pragma alloc_text(PAGE, FspFileDescCreate) #pragma alloc_text(PAGE, FspFileDescDelete) #pragma alloc_text(PAGE, FspFileDescResetDirectory) @@ -2030,19 +2028,6 @@ NTSTATUS FspFileNodeProcessLockIrp(FSP_FILE_NODE *FileNode, PIRP Irp) return Result; } -static NTSTATUS FspFileNodeCompleteLockIrp(PVOID Context, PIRP Irp) -{ - PAGED_CODE(); - - NTSTATUS Result = Irp->IoStatus.Status; - - DEBUGLOGIRP(Irp, Result); - - FspIopCompleteIrp(Irp, Result); - - return Result; -} - NTSTATUS FspFileDescCreate(FSP_FILE_DESC **PFileDesc) { PAGED_CODE(); @@ -2379,6 +2364,7 @@ VOID FspFileNodeOplockComplete(PVOID Context, PIRP Irp) FspIopCompleteIrp(Irp, Irp->IoStatus.Status); } +PCOMPLETE_LOCK_IRP_ROUTINE FspFileNodeCompleteLockIrp; WCHAR FspFileDescDirectoryPatternMatchAll[] = L"*"; // {904862B4-EB3F-461E-ACB2-4DF2B3FC898B} diff --git a/src/sys/lockctl.c b/src/sys/lockctl.c index 433c719d..82ab5126 100644 --- a/src/sys/lockctl.c +++ b/src/sys/lockctl.c @@ -22,12 +22,14 @@ static NTSTATUS FspFsvolLockControlRetry( BOOLEAN CanWait); static NTSTATUS FspFsvolLockControl( PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); +NTSTATUS FspFsvolLockControlForward(PVOID Context, PIRP Irp); FSP_IOCMPL_DISPATCH FspFsvolLockControlComplete; FSP_DRIVER_DISPATCH FspLockControl; #ifdef ALLOC_PRAGMA #pragma alloc_text(PAGE, FspFsvolLockControlRetry) #pragma alloc_text(PAGE, FspFsvolLockControl) +#pragma alloc_text(PAGE, FspFsvolLockControlForward) #pragma alloc_text(PAGE, FspFsvolLockControlComplete) #pragma alloc_text(PAGE, FspLockControl) #endif @@ -94,6 +96,57 @@ static NTSTATUS FspFsvolLockControl( return Result; } +NTSTATUS FspFsvolLockControlForward(PVOID Context, PIRP Irp) +{ + /* + * At this point the FSRTL package has processed the lock IRP. + * Either complete the IRP or if we are supposed to forward to + * user mode do so now. + */ + + PAGED_CODE(); + + PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); + PDEVICE_OBJECT FsvolDeviceObject = IrpSp->DeviceObject; + FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject); + NTSTATUS Result = Irp->IoStatus.Status; + + if (!NT_SUCCESS(Result) || !FsvolDeviceExtension->VolumeParams.UserModeFileLocking) + goto complete; + + PFILE_OBJECT FileObject = IrpSp->FileObject; + FSP_FILE_NODE *FileNode = FileObject->FsContext; + FSP_FILE_DESC *FileDesc = FileObject->FsContext2; + FSP_FSCTL_TRANSACT_REQ *Request; + + ASSERT(FileNode == FileDesc->FileNode); + + Result = FspIopCreateRequest(Irp, 0, 0, &Request); + if (!NT_SUCCESS(Result)) + goto complete; + + Request->Kind = FspFsctlTransactLockControlKind; + Request->Req.LockControl.UserContext = FileNode->UserContext; + Request->Req.LockControl.UserContext2 = FileDesc->UserContext2; + Request->Req.LockControl.LockFunction = IrpSp->MinorFunction; + Request->Req.LockControl.Offset = IrpSp->Parameters.LockControl.ByteOffset.QuadPart; + Request->Req.LockControl.Length = IrpSp->Parameters.LockControl.Length->QuadPart; + Request->Req.LockControl.Key = IrpSp->Parameters.LockControl.Key; + Request->Req.LockControl.ProcessId = IoGetRequestorProcessId(Irp); + Request->Req.LockControl.Exclusive = 0 != (IrpSp->Flags & SL_EXCLUSIVE_LOCK); + Request->Req.LockControl.FailImmediately = 0 != (IrpSp->Flags & SL_FAIL_IMMEDIATELY); + + if (!FspIoqPostIrp(FsvolDeviceExtension->Ioq, Irp, &Result)) + goto complete; + + return Result; + +complete: + DEBUGLOGIRP(Irp, Result); + FspIopCompleteIrp(Irp, Result); + return Result; +} + NTSTATUS FspFsvolLockControlComplete( PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response) { diff --git a/src/sys/read.c b/src/sys/read.c index 688a153d..069e9b70 100644 --- a/src/sys/read.c +++ b/src/sys/read.c @@ -228,7 +228,6 @@ static NTSTATUS FspFsvolReadNonCached( FSP_FILE_DESC *FileDesc = FileObject->FsContext2; LARGE_INTEGER ReadOffset = IrpSp->Parameters.Read.ByteOffset; ULONG ReadLength = IrpSp->Parameters.Read.Length; - ULONG ReadKey = IrpSp->Parameters.Read.Key; BOOLEAN PagingIo = BooleanFlagOn(Irp->Flags, IRP_PAGING_IO); FSP_FSCTL_TRANSACT_REQ *Request; BOOLEAN Success; @@ -321,7 +320,11 @@ static NTSTATUS FspFsvolReadNonCached( Request->Req.Read.UserContext2 = FileDesc->UserContext2; Request->Req.Read.Offset = ReadOffset.QuadPart; Request->Req.Read.Length = ReadLength; - Request->Req.Read.Key = ReadKey; + if (!PagingIo) + { + Request->Req.Read.Key = IrpSp->Parameters.Read.Key; + Request->Req.Read.ProcessId = IoGetRequestorProcessId(Irp); + } FspFileNodeSetOwner(FileNode, Full, Request); FspIopRequestContext(Request, RequestIrp) = Irp; diff --git a/src/sys/write.c b/src/sys/write.c index ad7e51eb..6daa419e 100644 --- a/src/sys/write.c +++ b/src/sys/write.c @@ -289,7 +289,6 @@ static NTSTATUS FspFsvolWriteNonCached( FSP_FILE_DESC *FileDesc = FileObject->FsContext2; LARGE_INTEGER WriteOffset = IrpSp->Parameters.Write.ByteOffset; ULONG WriteLength = IrpSp->Parameters.Write.Length; - ULONG WriteKey = IrpSp->Parameters.Write.Key; BOOLEAN WriteToEndOfFile = FILE_WRITE_TO_END_OF_FILE == WriteOffset.LowPart && -1L == WriteOffset.HighPart; BOOLEAN PagingIo = BooleanFlagOn(Irp->Flags, IRP_PAGING_IO); @@ -390,8 +389,13 @@ static NTSTATUS FspFsvolWriteNonCached( Request->Req.Write.UserContext2 = FileDesc->UserContext2; Request->Req.Write.Offset = WriteOffset.QuadPart; Request->Req.Write.Length = WriteLength; - Request->Req.Write.Key = WriteKey; - Request->Req.Write.ConstrainedIo = !!PagingIo; + if (!PagingIo) + { + Request->Req.Write.Key = IrpSp->Parameters.Write.Key; + Request->Req.Write.ProcessId = IoGetRequestorProcessId(Irp); + } + else + Request->Req.Write.ConstrainedIo = TRUE; FspFileNodeSetOwner(FileNode, Full, Request); FspIopRequestContext(Request, RequestIrp) = Irp;