mirror of
				https://github.com/winfsp/winfsp.git
				synced 2025-10-30 19:48:38 -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, | ||||
|     BOOLEAN CreateAndPost); | ||||
| VOID FspWqPostIrpWorkItem(PIRP Irp); | ||||
| VOID FspWqOplockPrepare(PVOID Context, PIRP Irp); | ||||
| VOID FspWqOplockComplete(PVOID Context, PIRP Irp); | ||||
| #define FspWqCreateIrpWorkItem(I, RW, RF)\ | ||||
|     FspWqCreateAndPostIrpWorkItem(I, RW, RF, FALSE) | ||||
| #define FspWqRepostIrpWorkItem(I, RW, RF)\ | ||||
|   | ||||
							
								
								
									
										96
									
								
								src/sys/wq.c
									
									
									
									
									
								
							
							
						
						
									
										96
									
								
								src/sys/wq.c
									
									
									
									
									
								
							| @@ -17,31 +17,59 @@ | ||||
|  | ||||
| #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); | ||||
| 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, | ||||
|     FSP_IOP_REQUEST_WORK *WorkRoutine, FSP_IOP_REQUEST_FINI *RequestFini, | ||||
|     BOOLEAN CreateAndPost) | ||||
| { | ||||
|     PAGED_CODE(); | ||||
|  | ||||
|     FSP_FSCTL_TRANSACT_REQ *Request = FspIrpRequest(Irp); | ||||
|     FSP_FSCTL_TRANSACT_REQ_WORK_ITEM *RequestWorkItem; | ||||
|  | ||||
|     if (0 == Request) | ||||
|     { | ||||
|         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; | ||||
|         } | ||||
|         Result = FspWqPrepareIrpWorkItem(Irp); | ||||
|         if (!NT_SUCCESS(Result)) | ||||
|             return Result; | ||||
|  | ||||
|         Result = FspIopCreateRequestAndWorkItem(Irp, 0, RequestFini, &Request); | ||||
|         if (!NT_SUCCESS(Result)) | ||||
| @@ -77,9 +105,26 @@ NTSTATUS FspWqCreateAndPostIrpWorkItem(PIRP Irp, | ||||
|  | ||||
| VOID FspWqPostIrpWorkItem(PIRP Irp) | ||||
| { | ||||
|     PAGED_CODE(); | ||||
|  | ||||
|     FSP_FSCTL_TRANSACT_REQ *Request = FspIrpRequest(Irp); | ||||
|     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(0 != RequestWorkItem); | ||||
|     ASSERT(0 != RequestWorkItem->WorkRoutine); | ||||
| @@ -90,6 +135,8 @@ VOID FspWqPostIrpWorkItem(PIRP Irp) | ||||
|  | ||||
| static VOID FspWqWorkRoutine(PVOID Context) | ||||
| { | ||||
|     PAGED_CODE(); | ||||
|  | ||||
|     PIRP Irp = Context; | ||||
|     PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); | ||||
|     PDEVICE_OBJECT DeviceObject = IrpSp->DeviceObject; | ||||
| @@ -125,3 +172,28 @@ static VOID FspWqWorkRoutine(PVOID Context) | ||||
|  | ||||
|     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