mirror of
				https://github.com/winfsp/winfsp.git
				synced 2025-10-30 11:38:39 -05:00 
			
		
		
		
	sys: IRP_MJ_LOCK_CONTROL
This commit is contained in:
		| @@ -155,9 +155,9 @@ extern __declspec(selectany) int fsp_dt = 1; | ||||
|         }                               \ | ||||
|         fsp_device_deref = TRUE;        \ | ||||
|     } while (0,0) | ||||
| #define FSP_LEAVE_MJ(fmt, ...)          \ | ||||
| #define FSP_LEAVE_MJ_COND(COND, fmt, ...)\ | ||||
|     FSP_LEAVE_(                         \ | ||||
|         if (STATUS_PENDING != Result)   \ | ||||
|         if (COND)                       \ | ||||
|         {                               \ | ||||
|             ASSERT(0 == (FSP_STATUS_PRIVATE_BIT & Result) ||\ | ||||
|                 FSP_STATUS_IOQ_POST == Result || FSP_STATUS_IOQ_POST_BEST_EFFORT == Result);\ | ||||
| @@ -187,6 +187,8 @@ extern __declspec(selectany) int fsp_dt = 1; | ||||
|         IoSetTopLevelIrp(fsp_top_level_irp);\ | ||||
|     );                                  \ | ||||
|     return Result | ||||
| #define FSP_LEAVE_MJ(fmt, ...)          \ | ||||
|     FSP_LEAVE_MJ_COND(STATUS_PENDING != Result, fmt, __VA_ARGS__) | ||||
| #define FSP_ENTER_IOC(...)              \ | ||||
|     NTSTATUS Result = STATUS_SUCCESS;   \ | ||||
|     PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); (VOID)IrpSp;\ | ||||
| @@ -873,6 +875,7 @@ typedef struct | ||||
|     ULONG SecurityChangeNumber; | ||||
|     ULONG DirInfoChangeNumber; | ||||
|     BOOLEAN TruncateOnClose; | ||||
|     FILE_LOCK FileLock; | ||||
|     union | ||||
|     { | ||||
|         PVOID LazyWriteThread; | ||||
| @@ -951,6 +954,8 @@ VOID FspFileNodeSetDirInfo(FSP_FILE_NODE *FileNode, PCVOID Buffer, ULONG Size); | ||||
| BOOLEAN FspFileNodeTrySetDirInfo(FSP_FILE_NODE *FileNode, PCVOID Buffer, ULONG Size, | ||||
|     ULONG DirInfoChangeNumber); | ||||
| VOID FspFileNodeNotifyChange(FSP_FILE_NODE *FileNode, ULONG Filter, ULONG Action); | ||||
| NTSTATUS FspFileNodeProcessLockIrp(FSP_FILE_NODE *FileNode, PIRP Irp, | ||||
|     PBOOLEAN PIrpRelinquished); | ||||
| NTSTATUS FspFileDescCreate(FSP_FILE_DESC **PFileDesc); | ||||
| VOID FspFileDescDelete(FSP_FILE_DESC *FileDesc); | ||||
| NTSTATUS FspFileDescResetDirectoryPattern(FSP_FILE_DESC *FileDesc, | ||||
|   | ||||
| @@ -48,6 +48,9 @@ BOOLEAN FspFileNodeTrySetDirInfo(FSP_FILE_NODE *FileNode, PCVOID Buffer, ULONG S | ||||
| static VOID FspFileNodeInvalidateDirInfo(FSP_FILE_NODE *FileNode); | ||||
| VOID FspFileNodeNotifyChange(FSP_FILE_NODE *FileNode, | ||||
|     ULONG Filter, ULONG Action); | ||||
| NTSTATUS FspFileNodeProcessLockIrp(FSP_FILE_NODE *FileNode, PIRP Irp, | ||||
|     PBOOLEAN PIrpRelinquished); | ||||
| static NTSTATUS FspFileNodeCompleteLockIrp(PVOID Context, PIRP Irp); | ||||
| NTSTATUS FspFileDescCreate(FSP_FILE_DESC **PFileDesc); | ||||
| VOID FspFileDescDelete(FSP_FILE_DESC *FileDesc); | ||||
| NTSTATUS FspFileDescResetDirectoryPattern(FSP_FILE_DESC *FileDesc, | ||||
| @@ -85,6 +88,7 @@ NTSTATUS FspFileDescResetDirectoryPattern(FSP_FILE_DESC *FileDesc, | ||||
| // !#pragma alloc_text(PAGE, FspFileNodeTrySetDirInfo) | ||||
| // !#pragma alloc_text(PAGE, FspFileNodeInvalidateDirInfo) | ||||
| #pragma alloc_text(PAGE, FspFileNodeNotifyChange) | ||||
| #pragma alloc_text(PAGE, FspFileNodeCompleteLockIrp) | ||||
| #pragma alloc_text(PAGE, FspFileDescCreate) | ||||
| #pragma alloc_text(PAGE, FspFileDescDelete) | ||||
| #pragma alloc_text(PAGE, FspFileDescResetDirectoryPattern) | ||||
| @@ -178,6 +182,8 @@ NTSTATUS FspFileNodeCreate(PDEVICE_OBJECT DeviceObject, | ||||
|     FspDeviceReference(FileNode->FsvolDeviceObject); | ||||
|     RtlInitEmptyUnicodeString(&FileNode->FileName, FileNode->FileNameBuf, (USHORT)ExtraSize); | ||||
|  | ||||
|     FsRtlInitializeFileLock(&FileNode->FileLock, FspFileNodeCompleteLockIrp, 0); | ||||
|  | ||||
|     *PFileNode = FileNode; | ||||
|  | ||||
|     return STATUS_SUCCESS; | ||||
| @@ -190,6 +196,8 @@ VOID FspFileNodeDelete(FSP_FILE_NODE *FileNode) | ||||
|     FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = | ||||
|         FspFsvolDeviceExtension(FileNode->FsvolDeviceObject); | ||||
|  | ||||
|     FsRtlUninitializeFileLock(&FileNode->FileLock); | ||||
|  | ||||
|     FsRtlTeardownPerStreamContexts(&FileNode->Header); | ||||
|  | ||||
|     FspMetaCacheInvalidateItem(FsvolDeviceExtension->DirInfoCache, FileNode->NonPaged->DirInfo); | ||||
| @@ -932,6 +940,47 @@ VOID FspFileNodeNotifyChange(FSP_FILE_NODE *FileNode, | ||||
|         0, Filter, Action); | ||||
| } | ||||
|  | ||||
| NTSTATUS FspFileNodeProcessLockIrp(FSP_FILE_NODE *FileNode, PIRP Irp, | ||||
|     PBOOLEAN PIrpRelinquished) | ||||
| { | ||||
|     PAGED_CODE(); | ||||
|  | ||||
|     NTSTATUS Result; | ||||
|  | ||||
|     FspFileNodeAcquireShared(FileNode, Main); | ||||
|     FspFileNodeSetOwner(FileNode, Main, Irp); | ||||
|  | ||||
|     try | ||||
|     { | ||||
|         Result = FsRtlProcessFileLock(&FileNode->FileLock, Irp, FileNode); | ||||
|         *PIrpRelinquished = TRUE; | ||||
|     } | ||||
|     except (EXCEPTION_EXECUTE_HANDLER) | ||||
|     { | ||||
|         FspFileNodeReleaseOwner(FileNode, Main, Irp); | ||||
|         Result = GetExceptionCode(); | ||||
|         *PIrpRelinquished = FALSE; | ||||
|     } | ||||
|  | ||||
|     return Result; | ||||
| } | ||||
|  | ||||
| static NTSTATUS FspFileNodeCompleteLockIrp(PVOID Context, PIRP Irp) | ||||
| { | ||||
|     PAGED_CODE(); | ||||
|  | ||||
|     FSP_FILE_NODE *FileNode = Context; | ||||
|     NTSTATUS Result = Irp->IoStatus.Status; | ||||
|  | ||||
|     FspFileNodeReleaseOwner(FileNode, Main, Irp); | ||||
|  | ||||
|     DEBUGLOGIRP(Irp, Result); | ||||
|  | ||||
|     FspIopCompleteIrp(Irp, Result); | ||||
|  | ||||
|     return Result; | ||||
| } | ||||
|  | ||||
| NTSTATUS FspFileDescCreate(FSP_FILE_DESC **PFileDesc) | ||||
| { | ||||
|     PAGED_CODE(); | ||||
|   | ||||
| @@ -7,7 +7,8 @@ | ||||
| #include <sys/driver.h> | ||||
|  | ||||
| static NTSTATUS FspFsvolLockControl( | ||||
|     PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); | ||||
|     PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp, | ||||
|     PBOOLEAN PIrpRelinquished); | ||||
| FSP_IOCMPL_DISPATCH FspFsvolLockControlComplete; | ||||
| FSP_DRIVER_DISPATCH FspLockControl; | ||||
|  | ||||
| @@ -18,11 +19,27 @@ FSP_DRIVER_DISPATCH FspLockControl; | ||||
| #endif | ||||
|  | ||||
| static NTSTATUS FspFsvolLockControl( | ||||
|     PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp) | ||||
|     PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp, | ||||
|     PBOOLEAN PIrpRelinquished) | ||||
| { | ||||
|     PAGED_CODE(); | ||||
|  | ||||
|     return STATUS_INVALID_DEVICE_REQUEST; | ||||
|     /* 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; | ||||
|  | ||||
|     /* only regular files can be locked */ | ||||
|     if (FileNode->IsDirectory) | ||||
|         return STATUS_INVALID_PARAMETER; | ||||
|  | ||||
|     /* let the FSRTL package handle this one! */ | ||||
|     Result = FspFileNodeProcessLockIrp(FileNode, Irp, PIrpRelinquished); | ||||
|  | ||||
|     return Result; | ||||
| } | ||||
|  | ||||
| NTSTATUS FspFsvolLockControlComplete( | ||||
| @@ -30,21 +47,36 @@ NTSTATUS FspFsvolLockControlComplete( | ||||
| { | ||||
|     FSP_ENTER_IOC(PAGED_CODE()); | ||||
|  | ||||
|     FSP_LEAVE_IOC("%s", ""); | ||||
|     FSP_LEAVE_IOC("FileObject=%p, " | ||||
|         "Key=%#lx, ByteOffset=%#lx:%#lx, Length=%ld", | ||||
|         IrpSp->FileObject, | ||||
|         IrpSp->Parameters.LockControl.Key, | ||||
|         IrpSp->Parameters.LockControl.ByteOffset.HighPart, | ||||
|         IrpSp->Parameters.LockControl.ByteOffset.LowPart, | ||||
|         IrpSp->Parameters.LockControl.Length); | ||||
| } | ||||
|  | ||||
| NTSTATUS FspLockControl( | ||||
|     PDEVICE_OBJECT DeviceObject, PIRP Irp) | ||||
| { | ||||
|     BOOLEAN IrpRelinquished = FALSE; | ||||
|  | ||||
|     FSP_ENTER_MJ(PAGED_CODE()); | ||||
|  | ||||
|     switch (FspDeviceExtension(DeviceObject)->Kind) | ||||
|     { | ||||
|     case FspFsvolDeviceExtensionKind: | ||||
|         FSP_RETURN(Result = FspFsvolLockControl(DeviceObject, Irp, IrpSp)); | ||||
|         FSP_RETURN(Result = FspFsvolLockControl(DeviceObject, Irp, IrpSp, &IrpRelinquished)); | ||||
|     default: | ||||
|         FSP_RETURN(Result = STATUS_INVALID_DEVICE_REQUEST); | ||||
|     } | ||||
|  | ||||
|     FSP_LEAVE_MJ("%s", ""); | ||||
|     FSP_LEAVE_MJ_COND(!IrpRelinquished && STATUS_PENDING != Result, | ||||
|         "FileObject=%p, " | ||||
|         "Key=%#lx, ByteOffset=%#lx:%#lx, Length=%ld", | ||||
|         IrpSp->FileObject, | ||||
|         IrpSp->Parameters.LockControl.Key, | ||||
|         IrpSp->Parameters.LockControl.ByteOffset.HighPart, | ||||
|         IrpSp->Parameters.LockControl.ByteOffset.LowPart, | ||||
|         IrpSp->Parameters.LockControl.Length); | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user