mirror of
				https://github.com/winfsp/winfsp.git
				synced 2025-10-30 11:38:39 -05:00 
			
		
		
		
	sys: wq: FspWqOplockPrepare, FspWqOplockComplete
This commit is contained in:
		| @@ -796,6 +796,8 @@ NTSTATUS FspWqCreateAndPostIrpWorkItem(PIRP Irp, | |||||||
|     FSP_IOP_REQUEST_WORK *WorkRoutine, FSP_IOP_REQUEST_FINI *RequestFini, |     FSP_IOP_REQUEST_WORK *WorkRoutine, FSP_IOP_REQUEST_FINI *RequestFini, | ||||||
|     BOOLEAN CreateAndPost); |     BOOLEAN CreateAndPost); | ||||||
| VOID FspWqPostIrpWorkItem(PIRP Irp); | VOID FspWqPostIrpWorkItem(PIRP Irp); | ||||||
|  | VOID FspWqOplockPrepare(PVOID Context, PIRP Irp); | ||||||
|  | VOID FspWqOplockComplete(PVOID Context, PIRP Irp); | ||||||
| #define FspWqCreateIrpWorkItem(I, RW, RF)\ | #define FspWqCreateIrpWorkItem(I, RW, RF)\ | ||||||
|     FspWqCreateAndPostIrpWorkItem(I, RW, RF, FALSE) |     FspWqCreateAndPostIrpWorkItem(I, RW, RF, FALSE) | ||||||
| #define FspWqRepostIrpWorkItem(I, RW, RF)\ | #define FspWqRepostIrpWorkItem(I, RW, RF)\ | ||||||
|   | |||||||
							
								
								
									
										96
									
								
								src/sys/wq.c
									
									
									
									
									
								
							
							
						
						
									
										96
									
								
								src/sys/wq.c
									
									
									
									
									
								
							| @@ -17,31 +17,59 @@ | |||||||
|  |  | ||||||
| #include <sys/driver.h> | #include <sys/driver.h> | ||||||
|  |  | ||||||
|  | NTSTATUS FspWqCreateAndPostIrpWorkItem(PIRP Irp, | ||||||
|  |     FSP_IOP_REQUEST_WORK *WorkRoutine, FSP_IOP_REQUEST_FINI *RequestFini, | ||||||
|  |     BOOLEAN CreateAndPost); | ||||||
|  | VOID FspWqPostIrpWorkItem(PIRP Irp); | ||||||
| static VOID FspWqWorkRoutine(PVOID Context); | static VOID FspWqWorkRoutine(PVOID Context); | ||||||
|  | VOID FspWqOplockPrepare(PVOID Context, PIRP Irp); | ||||||
|  | VOID FspWqOplockComplete(PVOID Context, PIRP Irp); | ||||||
|  |  | ||||||
|  | #ifdef ALLOC_PRAGMA | ||||||
|  | #pragma alloc_text(PAGE, FspWqCreateAndPostIrpWorkItem) | ||||||
|  | #pragma alloc_text(PAGE, FspWqPostIrpWorkItem) | ||||||
|  | #pragma alloc_text(PAGE, FspWqWorkRoutine) | ||||||
|  | #pragma alloc_text(PAGE, FspWqOplockPrepare) | ||||||
|  | #pragma alloc_text(PAGE, FspWqOplockComplete) | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | static inline | ||||||
|  | NTSTATUS FspWqPrepareIrpWorkItem(PIRP Irp) | ||||||
|  | { | ||||||
|  |     NTSTATUS Result; | ||||||
|  |     PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); | ||||||
|  |  | ||||||
|  |     /* lock/buffer the user buffer */ | ||||||
|  |     if ((IRP_MJ_READ == IrpSp->MajorFunction || IRP_MJ_WRITE == IrpSp->MajorFunction) && | ||||||
|  |         !FlagOn(IrpSp->MinorFunction, IRP_MN_MDL)) | ||||||
|  |     { | ||||||
|  |         if (IRP_MJ_READ == IrpSp->MajorFunction) | ||||||
|  |             Result = FspLockUserBuffer(Irp, IrpSp->Parameters.Read.Length, IoWriteAccess); | ||||||
|  |         else | ||||||
|  |             Result = FspLockUserBuffer(Irp, IrpSp->Parameters.Write.Length, IoReadAccess); | ||||||
|  |         if (!NT_SUCCESS(Result)) | ||||||
|  |             return Result; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     return STATUS_SUCCESS; | ||||||
|  | } | ||||||
|  |  | ||||||
| NTSTATUS FspWqCreateAndPostIrpWorkItem(PIRP Irp, | NTSTATUS FspWqCreateAndPostIrpWorkItem(PIRP Irp, | ||||||
|     FSP_IOP_REQUEST_WORK *WorkRoutine, FSP_IOP_REQUEST_FINI *RequestFini, |     FSP_IOP_REQUEST_WORK *WorkRoutine, FSP_IOP_REQUEST_FINI *RequestFini, | ||||||
|     BOOLEAN CreateAndPost) |     BOOLEAN CreateAndPost) | ||||||
| { | { | ||||||
|  |     PAGED_CODE(); | ||||||
|  |  | ||||||
|     FSP_FSCTL_TRANSACT_REQ *Request = FspIrpRequest(Irp); |     FSP_FSCTL_TRANSACT_REQ *Request = FspIrpRequest(Irp); | ||||||
|     FSP_FSCTL_TRANSACT_REQ_WORK_ITEM *RequestWorkItem; |     FSP_FSCTL_TRANSACT_REQ_WORK_ITEM *RequestWorkItem; | ||||||
|  |  | ||||||
|     if (0 == Request) |     if (0 == Request) | ||||||
|     { |     { | ||||||
|         NTSTATUS Result; |         NTSTATUS Result; | ||||||
|         PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); |  | ||||||
|  |  | ||||||
|         /* lock/buffer the user buffer */ |         Result = FspWqPrepareIrpWorkItem(Irp); | ||||||
|         if ((IRP_MJ_READ == IrpSp->MajorFunction || IRP_MJ_WRITE == IrpSp->MajorFunction) && |         if (!NT_SUCCESS(Result)) | ||||||
|             !FlagOn(IrpSp->MinorFunction, IRP_MN_MDL)) |             return Result; | ||||||
|         { |  | ||||||
|             if (IRP_MJ_READ == IrpSp->MajorFunction) |  | ||||||
|                 Result = FspLockUserBuffer(Irp, IrpSp->Parameters.Read.Length, IoWriteAccess); |  | ||||||
|             else |  | ||||||
|                 Result = FspLockUserBuffer(Irp, IrpSp->Parameters.Write.Length, IoReadAccess); |  | ||||||
|             if (!NT_SUCCESS(Result)) |  | ||||||
|                 return Result; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         Result = FspIopCreateRequestAndWorkItem(Irp, 0, RequestFini, &Request); |         Result = FspIopCreateRequestAndWorkItem(Irp, 0, RequestFini, &Request); | ||||||
|         if (!NT_SUCCESS(Result)) |         if (!NT_SUCCESS(Result)) | ||||||
| @@ -77,9 +105,26 @@ NTSTATUS FspWqCreateAndPostIrpWorkItem(PIRP Irp, | |||||||
|  |  | ||||||
| VOID FspWqPostIrpWorkItem(PIRP Irp) | VOID FspWqPostIrpWorkItem(PIRP Irp) | ||||||
| { | { | ||||||
|  |     PAGED_CODE(); | ||||||
|  |  | ||||||
|     FSP_FSCTL_TRANSACT_REQ *Request = FspIrpRequest(Irp); |     FSP_FSCTL_TRANSACT_REQ *Request = FspIrpRequest(Irp); | ||||||
|     FSP_FSCTL_TRANSACT_REQ_WORK_ITEM *RequestWorkItem = FspIopRequestWorkItem(Request); |     FSP_FSCTL_TRANSACT_REQ_WORK_ITEM *RequestWorkItem = FspIopRequestWorkItem(Request); | ||||||
|  |  | ||||||
|  | #if DBG | ||||||
|  |     switch (IoGetCurrentIrpStackLocation(Irp)->MajorFunction) | ||||||
|  |     { | ||||||
|  |     case IRP_MJ_CREATE: | ||||||
|  |         ASSERT(0 != FspIopIrpResponse(Irp)); | ||||||
|  |         break; | ||||||
|  |     case IRP_MJ_READ: | ||||||
|  |     case IRP_MJ_WRITE: | ||||||
|  |     case IRP_MJ_DIRECTORY_CONTROL: | ||||||
|  |     case IRP_MJ_LOCK_CONTROL: | ||||||
|  |     default: | ||||||
|  |         ASSERT(0); | ||||||
|  |         break; | ||||||
|  |     } | ||||||
|  | #endif | ||||||
|     ASSERT(Request->Hint == (UINT_PTR)Irp); |     ASSERT(Request->Hint == (UINT_PTR)Irp); | ||||||
|     ASSERT(0 != RequestWorkItem); |     ASSERT(0 != RequestWorkItem); | ||||||
|     ASSERT(0 != RequestWorkItem->WorkRoutine); |     ASSERT(0 != RequestWorkItem->WorkRoutine); | ||||||
| @@ -90,6 +135,8 @@ VOID FspWqPostIrpWorkItem(PIRP Irp) | |||||||
|  |  | ||||||
| static VOID FspWqWorkRoutine(PVOID Context) | static VOID FspWqWorkRoutine(PVOID Context) | ||||||
| { | { | ||||||
|  |     PAGED_CODE(); | ||||||
|  |  | ||||||
|     PIRP Irp = Context; |     PIRP Irp = Context; | ||||||
|     PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); |     PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); | ||||||
|     PDEVICE_OBJECT DeviceObject = IrpSp->DeviceObject; |     PDEVICE_OBJECT DeviceObject = IrpSp->DeviceObject; | ||||||
| @@ -125,3 +172,28 @@ static VOID FspWqWorkRoutine(PVOID Context) | |||||||
|  |  | ||||||
|     IoSetTopLevelIrp(0); |     IoSetTopLevelIrp(0); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | VOID FspWqOplockPrepare(PVOID Context, PIRP Irp) | ||||||
|  | { | ||||||
|  |     PAGED_CODE(); | ||||||
|  |  | ||||||
|  |     NTSTATUS Result; | ||||||
|  |  | ||||||
|  |     Result = FspWqPrepareIrpWorkItem(Irp); | ||||||
|  |     if (!NT_SUCCESS(Result)) | ||||||
|  |         /* | ||||||
|  |          * Only way to communicate failure is through ExRaiseStatus. | ||||||
|  |          * We will catch it in FspCheckOplock, etc. | ||||||
|  |          */ | ||||||
|  |         ExRaiseStatus(Result); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | VOID FspWqOplockComplete(PVOID Context, PIRP Irp) | ||||||
|  | { | ||||||
|  |     PAGED_CODE(); | ||||||
|  |  | ||||||
|  |     if (STATUS_SUCCESS == Irp->IoStatus.Status) | ||||||
|  |         FspWqPostIrpWorkItem(Irp); | ||||||
|  |     else | ||||||
|  |         FspIopCompleteIrp(Irp, Irp->IoStatus.Status); | ||||||
|  | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user