sys,dll,inc: implement user mode locking

This commit is contained in:
Bill Zissimopoulos 2017-11-28 14:18:48 -08:00
parent 5c962c8fc5
commit 778939d018
No known key found for this signature in database
GPG Key ID: 3D4F95D52C7B3EA3
11 changed files with 229 additions and 23 deletions

View File

@ -153,7 +153,8 @@ typedef struct
UINT32 PassQueryDirectoryPattern:1; /* pass Pattern during QueryDirectory operations */ UINT32 PassQueryDirectoryPattern:1; /* pass Pattern during QueryDirectory operations */
UINT32 AlwaysUseDoubleBuffering:1; UINT32 AlwaysUseDoubleBuffering:1;
UINT32 PassQueryDirectoryFileName:1; /* pass FileName during QueryDirectory (GetDirInfoByName) */ 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 */ /* user-mode flags */
UINT32 UmFileContextIsUserContext2:1; /* user mode: FileContext parameter is UserContext2 */ UINT32 UmFileContextIsUserContext2:1; /* user mode: FileContext parameter is UserContext2 */
UINT32 UmFileContextIsFullContext:1; /* user mode: FileContext parameter is FullContext */ UINT32 UmFileContextIsFullContext:1; /* user mode: FileContext parameter is FullContext */
@ -259,6 +260,7 @@ typedef struct
UINT32 SetLastAccessTime:1; UINT32 SetLastAccessTime:1;
UINT32 SetLastWriteTime:1; UINT32 SetLastWriteTime:1;
UINT32 SetChangeTime:1; UINT32 SetChangeTime:1;
UINT32 UnlockAll:1;
} Cleanup; } Cleanup;
struct struct
{ {
@ -273,6 +275,7 @@ typedef struct
UINT64 Offset; UINT64 Offset;
UINT32 Length; UINT32 Length;
UINT32 Key; UINT32 Key;
UINT32 ProcessId;
} Read; } Read;
struct struct
{ {
@ -283,6 +286,8 @@ typedef struct
UINT32 Length; UINT32 Length;
UINT32 Key; UINT32 Key;
UINT32 ConstrainedIo:1; UINT32 ConstrainedIo:1;
UINT32 ReservedFlags:31;
UINT32 ProcessId;
} Write; } Write;
struct struct
{ {
@ -359,6 +364,18 @@ typedef struct
UINT16 TargetOnFileSystem; /* the target of the symbolic link is on this file system */ UINT16 TargetOnFileSystem; /* the target of the symbolic link is on this file system */
} FileSystemControl; } FileSystemControl;
struct 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 UserContext;
UINT64 UserContext2; UINT64 UserContext2;

View File

@ -133,6 +133,7 @@ enum
FspCleanupSetLastAccessTime = 0x20, FspCleanupSetLastAccessTime = 0x20,
FspCleanupSetLastWriteTime = 0x40, FspCleanupSetLastWriteTime = 0x40,
FspCleanupSetChangeTime = 0x80, FspCleanupSetChangeTime = 0x80,
FspCleanupUnlockAll = 0x0100,
}; };
/** /**
* @class FSP_FILE_SYSTEM * @class FSP_FILE_SYSTEM
@ -822,12 +823,80 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
NTSTATUS (*GetDirInfoByName)(FSP_FILE_SYSTEM *FileSystem, NTSTATUS (*GetDirInfoByName)(FSP_FILE_SYSTEM *FileSystem,
PVOID FileContext, PWSTR FileName, PVOID FileContext, PWSTR FileName,
FSP_FSCTL_DIR_INFO *DirInfo); 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. * This ensures that this interface will always contain 64 function pointers.
* Please update when changing the interface as it is important for future compatibility. * Please update when changing the interface as it is important for future compatibility.
*/ */
NTSTATUS (*Reserved[39])(); NTSTATUS (*Reserved[37])();
} FSP_FILE_SYSTEM_INTERFACE; } FSP_FILE_SYSTEM_INTERFACE;
FSP_FSCTL_STATIC_ASSERT(sizeof(FSP_FILE_SYSTEM_INTERFACE) == 64 * sizeof(NTSTATUS (*)()), FSP_FSCTL_STATIC_ASSERT(sizeof(FSP_FILE_SYSTEM_INTERFACE) == 64 * sizeof(NTSTATUS (*)()),
"FSP_FILE_SYSTEM_INTERFACE must have 64 entries."); "FSP_FILE_SYSTEM_INTERFACE must have 64 entries.");
@ -1086,7 +1155,7 @@ BOOLEAN FspFileSystemIsOperationCaseSensitive(VOID)
} }
FSP_API BOOLEAN FspFileSystemIsOperationCaseSensitiveF(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. * Valid only during Create, Open and Rename requests when the target exists.
*/ */
@ -1107,6 +1176,28 @@ UINT32 FspFileSystemOperationProcessId(VOID)
} }
} }
FSP_API UINT32 FspFileSystemOperationProcessIdF(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 * Operations
@ -1141,6 +1232,8 @@ FSP_API NTSTATUS FspFileSystemOpQueryDirectory(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response); FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response);
FSP_API NTSTATUS FspFileSystemOpFileSystemControl(FSP_FILE_SYSTEM *FileSystem, FSP_API NTSTATUS FspFileSystemOpFileSystemControl(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response); 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_API NTSTATUS FspFileSystemOpQuerySecurity(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response); FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response);
FSP_API NTSTATUS FspFileSystemOpSetSecurity(FSP_FILE_SYSTEM *FileSystem, FSP_API NTSTATUS FspFileSystemOpSetSecurity(FSP_FILE_SYSTEM *FileSystem,

View File

@ -162,6 +162,7 @@ FSP_API NTSTATUS FspFileSystemCreate(PWSTR DevicePath,
FileSystem->Operations[FspFsctlTransactSetVolumeInformationKind] = FspFileSystemOpSetVolumeInformation; FileSystem->Operations[FspFsctlTransactSetVolumeInformationKind] = FspFileSystemOpSetVolumeInformation;
FileSystem->Operations[FspFsctlTransactQueryDirectoryKind] = FspFileSystemOpQueryDirectory; FileSystem->Operations[FspFsctlTransactQueryDirectoryKind] = FspFileSystemOpQueryDirectory;
FileSystem->Operations[FspFsctlTransactFileSystemControlKind] = FspFileSystemOpFileSystemControl; FileSystem->Operations[FspFsctlTransactFileSystemControlKind] = FspFileSystemOpFileSystemControl;
FileSystem->Operations[FspFsctlTransactLockControlKind] = FspFileSystemOpLockControl;
FileSystem->Operations[FspFsctlTransactQuerySecurityKind] = FspFileSystemOpQuerySecurity; FileSystem->Operations[FspFsctlTransactQuerySecurityKind] = FspFileSystemOpQuerySecurity;
FileSystem->Operations[FspFsctlTransactSetSecurityKind] = FspFileSystemOpSetSecurity; FileSystem->Operations[FspFsctlTransactSetSecurityKind] = FspFileSystemOpSetSecurity;
FileSystem->Operations[FspFsctlTransactQueryStreamInformationKind] = FspFileSystemOpQueryStreamInformation; FileSystem->Operations[FspFsctlTransactQueryStreamInformationKind] = FspFileSystemOpQueryStreamInformation;
@ -688,3 +689,8 @@ FSP_API UINT32 FspFileSystemOperationProcessIdF(VOID)
{ {
return FspFileSystemOperationProcessId(); return FspFileSystemOperationProcessId();
} }
FSP_API UINT64 FspFileSystemOperationLockOwnerF(VOID)
{
return FspFileSystemOperationLockOwner();
}

View File

@ -886,6 +886,7 @@ FSP_API NTSTATUS FspFileSystemOpCleanup(FSP_FILE_SYSTEM *FileSystem,
(0 != Request->Req.Cleanup.SetArchiveBit ? FspCleanupSetArchiveBit : 0) | (0 != Request->Req.Cleanup.SetArchiveBit ? FspCleanupSetArchiveBit : 0) |
(0 != Request->Req.Cleanup.SetLastAccessTime ? FspCleanupSetLastAccessTime : 0) | (0 != Request->Req.Cleanup.SetLastAccessTime ? FspCleanupSetLastAccessTime : 0) |
(0 != Request->Req.Cleanup.SetLastWriteTime ? FspCleanupSetLastWriteTime : 0) | (0 != Request->Req.Cleanup.SetLastWriteTime ? FspCleanupSetLastWriteTime : 0) |
(0 != Request->Req.Cleanup.UnlockAll ? FspCleanupUnlockAll : 0) |
(0 != Request->Req.Cleanup.SetChangeTime ? FspCleanupSetChangeTime : 0)); (0 != Request->Req.Cleanup.SetChangeTime ? FspCleanupSetChangeTime : 0));
return STATUS_SUCCESS; return STATUS_SUCCESS;
@ -1247,6 +1248,43 @@ FSP_API NTSTATUS FspFileSystemOpFileSystemControl(FSP_FILE_SYSTEM *FileSystem,
return Result; 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_API NTSTATUS FspFileSystemOpQuerySecurity(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response) FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
{ {

View File

@ -117,6 +117,8 @@ static NTSTATUS FspFsvolCleanup(
Request->Req.Cleanup.SetLastWriteTime = FileModified && !FileDesc->DidSetLastWriteTime; Request->Req.Cleanup.SetLastWriteTime = FileModified && !FileDesc->DidSetLastWriteTime;
Request->Req.Cleanup.SetChangeTime = (FileModified || FileDesc->DidSetMetadata) && Request->Req.Cleanup.SetChangeTime = (FileModified || FileDesc->DidSetMetadata) &&
!FileDesc->DidSetChangeTime; !FileDesc->DidSetChangeTime;
Request->Req.Cleanup.UnlockAll = FsvolDeviceExtension->VolumeParams.UserModeFileLocking &&
FsRtlAreThereCurrentOrInProgressFileLocks(&FileNode->FileLock);
FspFileNodeAcquireExclusive(FileNode, Pgio); FspFileNodeAcquireExclusive(FileNode, Pgio);
@ -128,6 +130,7 @@ static NTSTATUS FspFsvolCleanup(
Request->Req.Cleanup.SetArchiveBit || Request->Req.Cleanup.SetArchiveBit ||
Request->Req.Cleanup.SetLastWriteTime || Request->Req.Cleanup.SetLastWriteTime ||
Request->Req.Cleanup.SetChangeTime || Request->Req.Cleanup.SetChangeTime ||
Request->Req.Cleanup.UnlockAll ||
!FsvolDeviceExtension->VolumeParams.PostCleanupWhenModifiedOnly) !FsvolDeviceExtension->VolumeParams.PostCleanupWhenModifiedOnly)
/* /*
* Note that it is still possible for this request to not be delivered, * Note that it is still possible for this request to not be delivered,

View File

@ -128,6 +128,7 @@ NTSTATUS DriverEntry(
FspIopCompleteFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = FspFsvolFileSystemControlComplete; FspIopCompleteFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = FspFsvolFileSystemControlComplete;
FspIopCompleteFunction[IRP_MJ_DEVICE_CONTROL] = FspFsvolDeviceControlComplete; FspIopCompleteFunction[IRP_MJ_DEVICE_CONTROL] = FspFsvolDeviceControlComplete;
FspIopCompleteFunction[IRP_MJ_SHUTDOWN] = FspFsvolShutdownComplete; FspIopCompleteFunction[IRP_MJ_SHUTDOWN] = FspFsvolShutdownComplete;
FspFileNodeCompleteLockIrp = FspFsvolLockControlForward;
FspIopCompleteFunction[IRP_MJ_LOCK_CONTROL] = FspFsvolLockControlComplete; FspIopCompleteFunction[IRP_MJ_LOCK_CONTROL] = FspFsvolLockControlComplete;
FspIopCompleteFunction[IRP_MJ_CLEANUP] = FspFsvolCleanupComplete; FspIopCompleteFunction[IRP_MJ_CLEANUP] = FspFsvolCleanupComplete;
FspIopCompleteFunction[IRP_MJ_QUERY_SECURITY] = FspFsvolQuerySecurityComplete; FspIopCompleteFunction[IRP_MJ_QUERY_SECURITY] = FspFsvolQuerySecurityComplete;

View File

@ -316,6 +316,7 @@ FSP_IOPREP_DISPATCH FspFsvolDirectoryControlPrepare;
FSP_IOCMPL_DISPATCH FspFsvolDirectoryControlComplete; FSP_IOCMPL_DISPATCH FspFsvolDirectoryControlComplete;
FSP_IOCMPL_DISPATCH FspFsvolFileSystemControlComplete; FSP_IOCMPL_DISPATCH FspFsvolFileSystemControlComplete;
FSP_IOCMPL_DISPATCH FspFsvolFlushBuffersComplete; FSP_IOCMPL_DISPATCH FspFsvolFlushBuffersComplete;
NTSTATUS FspFsvolLockControlForward(PVOID Context, PIRP Irp);
FSP_IOCMPL_DISPATCH FspFsvolLockControlComplete; FSP_IOCMPL_DISPATCH FspFsvolLockControlComplete;
FSP_IOCMPL_DISPATCH FspFsvolQueryEaComplete; FSP_IOCMPL_DISPATCH FspFsvolQueryEaComplete;
FSP_IOCMPL_DISPATCH FspFsvolQueryInformationComplete; FSP_IOCMPL_DISPATCH FspFsvolQueryInformationComplete;
@ -1564,6 +1565,7 @@ extern CACHE_MANAGER_CALLBACKS FspCacheManagerCallbacks;
extern FSP_IOPREP_DISPATCH *FspIopPrepareFunction[]; extern FSP_IOPREP_DISPATCH *FspIopPrepareFunction[];
extern FSP_IOCMPL_DISPATCH *FspIopCompleteFunction[]; extern FSP_IOCMPL_DISPATCH *FspIopCompleteFunction[];
extern ERESOURCE FspDeviceGlobalResource; extern ERESOURCE FspDeviceGlobalResource;
extern PCOMPLETE_LOCK_IRP_ROUTINE FspFileNodeCompleteLockIrp;
extern WCHAR FspFileDescDirectoryPatternMatchAll[]; extern WCHAR FspFileDescDirectoryPatternMatchAll[];
extern const GUID FspMainFileOpenEcpGuid; extern const GUID FspMainFileOpenEcpGuid;
extern ULONG FspProcessorCount; extern ULONG FspProcessorCount;

View File

@ -83,7 +83,6 @@ VOID FspFileNodeInvalidateStreamInfo(FSP_FILE_NODE *FileNode);
VOID FspFileNodeNotifyChange(FSP_FILE_NODE *FileNode, ULONG Filter, ULONG Action, VOID FspFileNodeNotifyChange(FSP_FILE_NODE *FileNode, ULONG Filter, ULONG Action,
BOOLEAN InvalidateCaches); BOOLEAN InvalidateCaches);
NTSTATUS FspFileNodeProcessLockIrp(FSP_FILE_NODE *FileNode, PIRP Irp); NTSTATUS FspFileNodeProcessLockIrp(FSP_FILE_NODE *FileNode, PIRP Irp);
static NTSTATUS FspFileNodeCompleteLockIrp(PVOID Context, PIRP Irp);
NTSTATUS FspFileDescCreate(FSP_FILE_DESC **PFileDesc); NTSTATUS FspFileDescCreate(FSP_FILE_DESC **PFileDesc);
VOID FspFileDescDelete(FSP_FILE_DESC *FileDesc); VOID FspFileDescDelete(FSP_FILE_DESC *FileDesc);
NTSTATUS FspFileDescResetDirectory(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, FspFileNodeInvalidateStreamInfo)
#pragma alloc_text(PAGE, FspFileNodeNotifyChange) #pragma alloc_text(PAGE, FspFileNodeNotifyChange)
#pragma alloc_text(PAGE, FspFileNodeProcessLockIrp) #pragma alloc_text(PAGE, FspFileNodeProcessLockIrp)
#pragma alloc_text(PAGE, FspFileNodeCompleteLockIrp)
#pragma alloc_text(PAGE, FspFileDescCreate) #pragma alloc_text(PAGE, FspFileDescCreate)
#pragma alloc_text(PAGE, FspFileDescDelete) #pragma alloc_text(PAGE, FspFileDescDelete)
#pragma alloc_text(PAGE, FspFileDescResetDirectory) #pragma alloc_text(PAGE, FspFileDescResetDirectory)
@ -2030,19 +2028,6 @@ NTSTATUS FspFileNodeProcessLockIrp(FSP_FILE_NODE *FileNode, PIRP Irp)
return Result; 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) NTSTATUS FspFileDescCreate(FSP_FILE_DESC **PFileDesc)
{ {
PAGED_CODE(); PAGED_CODE();
@ -2379,6 +2364,7 @@ VOID FspFileNodeOplockComplete(PVOID Context, PIRP Irp)
FspIopCompleteIrp(Irp, Irp->IoStatus.Status); FspIopCompleteIrp(Irp, Irp->IoStatus.Status);
} }
PCOMPLETE_LOCK_IRP_ROUTINE FspFileNodeCompleteLockIrp;
WCHAR FspFileDescDirectoryPatternMatchAll[] = L"*"; WCHAR FspFileDescDirectoryPatternMatchAll[] = L"*";
// {904862B4-EB3F-461E-ACB2-4DF2B3FC898B} // {904862B4-EB3F-461E-ACB2-4DF2B3FC898B}

View File

@ -22,12 +22,14 @@ static NTSTATUS FspFsvolLockControlRetry(
BOOLEAN CanWait); BOOLEAN CanWait);
static NTSTATUS FspFsvolLockControl( static NTSTATUS FspFsvolLockControl(
PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
NTSTATUS FspFsvolLockControlForward(PVOID Context, PIRP Irp);
FSP_IOCMPL_DISPATCH FspFsvolLockControlComplete; FSP_IOCMPL_DISPATCH FspFsvolLockControlComplete;
FSP_DRIVER_DISPATCH FspLockControl; FSP_DRIVER_DISPATCH FspLockControl;
#ifdef ALLOC_PRAGMA #ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, FspFsvolLockControlRetry) #pragma alloc_text(PAGE, FspFsvolLockControlRetry)
#pragma alloc_text(PAGE, FspFsvolLockControl) #pragma alloc_text(PAGE, FspFsvolLockControl)
#pragma alloc_text(PAGE, FspFsvolLockControlForward)
#pragma alloc_text(PAGE, FspFsvolLockControlComplete) #pragma alloc_text(PAGE, FspFsvolLockControlComplete)
#pragma alloc_text(PAGE, FspLockControl) #pragma alloc_text(PAGE, FspLockControl)
#endif #endif
@ -94,6 +96,57 @@ static NTSTATUS FspFsvolLockControl(
return Result; 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( NTSTATUS FspFsvolLockControlComplete(
PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response) PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response)
{ {

View File

@ -228,7 +228,6 @@ static NTSTATUS FspFsvolReadNonCached(
FSP_FILE_DESC *FileDesc = FileObject->FsContext2; FSP_FILE_DESC *FileDesc = FileObject->FsContext2;
LARGE_INTEGER ReadOffset = IrpSp->Parameters.Read.ByteOffset; LARGE_INTEGER ReadOffset = IrpSp->Parameters.Read.ByteOffset;
ULONG ReadLength = IrpSp->Parameters.Read.Length; ULONG ReadLength = IrpSp->Parameters.Read.Length;
ULONG ReadKey = IrpSp->Parameters.Read.Key;
BOOLEAN PagingIo = BooleanFlagOn(Irp->Flags, IRP_PAGING_IO); BOOLEAN PagingIo = BooleanFlagOn(Irp->Flags, IRP_PAGING_IO);
FSP_FSCTL_TRANSACT_REQ *Request; FSP_FSCTL_TRANSACT_REQ *Request;
BOOLEAN Success; BOOLEAN Success;
@ -321,7 +320,11 @@ static NTSTATUS FspFsvolReadNonCached(
Request->Req.Read.UserContext2 = FileDesc->UserContext2; Request->Req.Read.UserContext2 = FileDesc->UserContext2;
Request->Req.Read.Offset = ReadOffset.QuadPart; Request->Req.Read.Offset = ReadOffset.QuadPart;
Request->Req.Read.Length = ReadLength; 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); FspFileNodeSetOwner(FileNode, Full, Request);
FspIopRequestContext(Request, RequestIrp) = Irp; FspIopRequestContext(Request, RequestIrp) = Irp;

View File

@ -289,7 +289,6 @@ static NTSTATUS FspFsvolWriteNonCached(
FSP_FILE_DESC *FileDesc = FileObject->FsContext2; FSP_FILE_DESC *FileDesc = FileObject->FsContext2;
LARGE_INTEGER WriteOffset = IrpSp->Parameters.Write.ByteOffset; LARGE_INTEGER WriteOffset = IrpSp->Parameters.Write.ByteOffset;
ULONG WriteLength = IrpSp->Parameters.Write.Length; ULONG WriteLength = IrpSp->Parameters.Write.Length;
ULONG WriteKey = IrpSp->Parameters.Write.Key;
BOOLEAN WriteToEndOfFile = BOOLEAN WriteToEndOfFile =
FILE_WRITE_TO_END_OF_FILE == WriteOffset.LowPart && -1L == WriteOffset.HighPart; FILE_WRITE_TO_END_OF_FILE == WriteOffset.LowPart && -1L == WriteOffset.HighPart;
BOOLEAN PagingIo = BooleanFlagOn(Irp->Flags, IRP_PAGING_IO); BOOLEAN PagingIo = BooleanFlagOn(Irp->Flags, IRP_PAGING_IO);
@ -390,8 +389,13 @@ static NTSTATUS FspFsvolWriteNonCached(
Request->Req.Write.UserContext2 = FileDesc->UserContext2; Request->Req.Write.UserContext2 = FileDesc->UserContext2;
Request->Req.Write.Offset = WriteOffset.QuadPart; Request->Req.Write.Offset = WriteOffset.QuadPart;
Request->Req.Write.Length = WriteLength; Request->Req.Write.Length = WriteLength;
Request->Req.Write.Key = WriteKey; if (!PagingIo)
Request->Req.Write.ConstrainedIo = !!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); FspFileNodeSetOwner(FileNode, Full, Request);
FspIopRequestContext(Request, RequestIrp) = Irp; FspIopRequestContext(Request, RequestIrp) = Irp;