mirror of
				https://github.com/winfsp/winfsp.git
				synced 2025-10-30 19:48:38 -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;        \ |         fsp_device_deref = TRUE;        \ | ||||||
|     } while (0,0) |     } while (0,0) | ||||||
| #define FSP_LEAVE_MJ(fmt, ...)          \ | #define FSP_LEAVE_MJ_COND(COND, fmt, ...)\ | ||||||
|     FSP_LEAVE_(                         \ |     FSP_LEAVE_(                         \ | ||||||
|         if (STATUS_PENDING != Result)   \ |         if (COND)                       \ | ||||||
|         {                               \ |         {                               \ | ||||||
|             ASSERT(0 == (FSP_STATUS_PRIVATE_BIT & Result) ||\ |             ASSERT(0 == (FSP_STATUS_PRIVATE_BIT & Result) ||\ | ||||||
|                 FSP_STATUS_IOQ_POST == Result || FSP_STATUS_IOQ_POST_BEST_EFFORT == 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);\ |         IoSetTopLevelIrp(fsp_top_level_irp);\ | ||||||
|     );                                  \ |     );                                  \ | ||||||
|     return Result |     return Result | ||||||
|  | #define FSP_LEAVE_MJ(fmt, ...)          \ | ||||||
|  |     FSP_LEAVE_MJ_COND(STATUS_PENDING != Result, fmt, __VA_ARGS__) | ||||||
| #define FSP_ENTER_IOC(...)              \ | #define FSP_ENTER_IOC(...)              \ | ||||||
|     NTSTATUS Result = STATUS_SUCCESS;   \ |     NTSTATUS Result = STATUS_SUCCESS;   \ | ||||||
|     PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); (VOID)IrpSp;\ |     PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); (VOID)IrpSp;\ | ||||||
| @@ -873,6 +875,7 @@ typedef struct | |||||||
|     ULONG SecurityChangeNumber; |     ULONG SecurityChangeNumber; | ||||||
|     ULONG DirInfoChangeNumber; |     ULONG DirInfoChangeNumber; | ||||||
|     BOOLEAN TruncateOnClose; |     BOOLEAN TruncateOnClose; | ||||||
|  |     FILE_LOCK FileLock; | ||||||
|     union |     union | ||||||
|     { |     { | ||||||
|         PVOID LazyWriteThread; |         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, | BOOLEAN FspFileNodeTrySetDirInfo(FSP_FILE_NODE *FileNode, PCVOID Buffer, ULONG Size, | ||||||
|     ULONG DirInfoChangeNumber); |     ULONG DirInfoChangeNumber); | ||||||
| VOID FspFileNodeNotifyChange(FSP_FILE_NODE *FileNode, ULONG Filter, ULONG Action); | 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); | NTSTATUS FspFileDescCreate(FSP_FILE_DESC **PFileDesc); | ||||||
| VOID FspFileDescDelete(FSP_FILE_DESC *FileDesc); | VOID FspFileDescDelete(FSP_FILE_DESC *FileDesc); | ||||||
| NTSTATUS FspFileDescResetDirectoryPattern(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); | static VOID FspFileNodeInvalidateDirInfo(FSP_FILE_NODE *FileNode); | ||||||
| VOID FspFileNodeNotifyChange(FSP_FILE_NODE *FileNode, | VOID FspFileNodeNotifyChange(FSP_FILE_NODE *FileNode, | ||||||
|     ULONG Filter, ULONG Action); |     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); | NTSTATUS FspFileDescCreate(FSP_FILE_DESC **PFileDesc); | ||||||
| VOID FspFileDescDelete(FSP_FILE_DESC *FileDesc); | VOID FspFileDescDelete(FSP_FILE_DESC *FileDesc); | ||||||
| NTSTATUS FspFileDescResetDirectoryPattern(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, FspFileNodeTrySetDirInfo) | ||||||
| // !#pragma alloc_text(PAGE, FspFileNodeInvalidateDirInfo) | // !#pragma alloc_text(PAGE, FspFileNodeInvalidateDirInfo) | ||||||
| #pragma alloc_text(PAGE, FspFileNodeNotifyChange) | #pragma alloc_text(PAGE, FspFileNodeNotifyChange) | ||||||
|  | #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, FspFileDescResetDirectoryPattern) | #pragma alloc_text(PAGE, FspFileDescResetDirectoryPattern) | ||||||
| @@ -178,6 +182,8 @@ NTSTATUS FspFileNodeCreate(PDEVICE_OBJECT DeviceObject, | |||||||
|     FspDeviceReference(FileNode->FsvolDeviceObject); |     FspDeviceReference(FileNode->FsvolDeviceObject); | ||||||
|     RtlInitEmptyUnicodeString(&FileNode->FileName, FileNode->FileNameBuf, (USHORT)ExtraSize); |     RtlInitEmptyUnicodeString(&FileNode->FileName, FileNode->FileNameBuf, (USHORT)ExtraSize); | ||||||
|  |  | ||||||
|  |     FsRtlInitializeFileLock(&FileNode->FileLock, FspFileNodeCompleteLockIrp, 0); | ||||||
|  |  | ||||||
|     *PFileNode = FileNode; |     *PFileNode = FileNode; | ||||||
|  |  | ||||||
|     return STATUS_SUCCESS; |     return STATUS_SUCCESS; | ||||||
| @@ -190,6 +196,8 @@ VOID FspFileNodeDelete(FSP_FILE_NODE *FileNode) | |||||||
|     FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = |     FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = | ||||||
|         FspFsvolDeviceExtension(FileNode->FsvolDeviceObject); |         FspFsvolDeviceExtension(FileNode->FsvolDeviceObject); | ||||||
|  |  | ||||||
|  |     FsRtlUninitializeFileLock(&FileNode->FileLock); | ||||||
|  |  | ||||||
|     FsRtlTeardownPerStreamContexts(&FileNode->Header); |     FsRtlTeardownPerStreamContexts(&FileNode->Header); | ||||||
|  |  | ||||||
|     FspMetaCacheInvalidateItem(FsvolDeviceExtension->DirInfoCache, FileNode->NonPaged->DirInfo); |     FspMetaCacheInvalidateItem(FsvolDeviceExtension->DirInfoCache, FileNode->NonPaged->DirInfo); | ||||||
| @@ -932,6 +940,47 @@ VOID FspFileNodeNotifyChange(FSP_FILE_NODE *FileNode, | |||||||
|         0, Filter, Action); |         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) | NTSTATUS FspFileDescCreate(FSP_FILE_DESC **PFileDesc) | ||||||
| { | { | ||||||
|     PAGED_CODE(); |     PAGED_CODE(); | ||||||
|   | |||||||
| @@ -7,7 +7,8 @@ | |||||||
| #include <sys/driver.h> | #include <sys/driver.h> | ||||||
|  |  | ||||||
| static NTSTATUS FspFsvolLockControl( | 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_IOCMPL_DISPATCH FspFsvolLockControlComplete; | ||||||
| FSP_DRIVER_DISPATCH FspLockControl; | FSP_DRIVER_DISPATCH FspLockControl; | ||||||
|  |  | ||||||
| @@ -18,11 +19,27 @@ FSP_DRIVER_DISPATCH FspLockControl; | |||||||
| #endif | #endif | ||||||
|  |  | ||||||
| static NTSTATUS FspFsvolLockControl( | 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(); |     PAGED_CODE(); | ||||||
|  |  | ||||||
|  |     /* is this a valid FileObject? */ | ||||||
|  |     if (!FspFileNodeIsValid(IrpSp->FileObject->FsContext)) | ||||||
|         return STATUS_INVALID_DEVICE_REQUEST; |         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( | NTSTATUS FspFsvolLockControlComplete( | ||||||
| @@ -30,21 +47,36 @@ NTSTATUS FspFsvolLockControlComplete( | |||||||
| { | { | ||||||
|     FSP_ENTER_IOC(PAGED_CODE()); |     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( | NTSTATUS FspLockControl( | ||||||
|     PDEVICE_OBJECT DeviceObject, PIRP Irp) |     PDEVICE_OBJECT DeviceObject, PIRP Irp) | ||||||
| { | { | ||||||
|  |     BOOLEAN IrpRelinquished = FALSE; | ||||||
|  |  | ||||||
|     FSP_ENTER_MJ(PAGED_CODE()); |     FSP_ENTER_MJ(PAGED_CODE()); | ||||||
|  |  | ||||||
|     switch (FspDeviceExtension(DeviceObject)->Kind) |     switch (FspDeviceExtension(DeviceObject)->Kind) | ||||||
|     { |     { | ||||||
|     case FspFsvolDeviceExtensionKind: |     case FspFsvolDeviceExtensionKind: | ||||||
|         FSP_RETURN(Result = FspFsvolLockControl(DeviceObject, Irp, IrpSp)); |         FSP_RETURN(Result = FspFsvolLockControl(DeviceObject, Irp, IrpSp, &IrpRelinquished)); | ||||||
|     default: |     default: | ||||||
|         FSP_RETURN(Result = STATUS_INVALID_DEVICE_REQUEST); |         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