mirror of
				https://github.com/winfsp/winfsp.git
				synced 2025-10-30 19:48:38 -05:00 
			
		
		
		
	sys: FspIopDispatchRetryComplete()
This commit is contained in:
		| @@ -14,6 +14,7 @@ static NTSTATUS FspFsvolCreate( | ||||
|     PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); | ||||
| FSP_IOPREP_DISPATCH FspFsvolCreatePrepare; | ||||
| FSP_IOCMPL_DISPATCH FspFsvolCreateComplete; | ||||
| FSP_IORETR_DISPATCH FspFsvolCreateRetryComplete; | ||||
| static NTSTATUS FspFsvolCreateTryOpen(PIRP Irp, FSP_FSCTL_TRANSACT_REQ *Request, | ||||
|     FSP_FILE_NODE *FileNode, FSP_FILE_DESC *FileDesc, PFILE_OBJECT FileObject); | ||||
| static VOID FspFsvolCreatePostClose(FSP_FILE_DESC *FileDesc); | ||||
| @@ -28,6 +29,7 @@ FSP_DRIVER_DISPATCH FspCreate; | ||||
| #pragma alloc_text(PAGE, FspFsvolCreate) | ||||
| #pragma alloc_text(PAGE, FspFsvolCreatePrepare) | ||||
| #pragma alloc_text(PAGE, FspFsvolCreateComplete) | ||||
| #pragma alloc_text(PAGE, FspFsvolCreateRetryComplete) | ||||
| #pragma alloc_text(PAGE, FspFsvolCreateTryOpen) | ||||
| #pragma alloc_text(PAGE, FspFsvolCreatePostClose) | ||||
| #pragma alloc_text(PAGE, FspFsvolCreateRequestFini) | ||||
| @@ -711,6 +713,14 @@ VOID FspFsvolCreateComplete( | ||||
|         IrpSp->FileObject, IrpSp->FileObject->RelatedFileObject, IrpSp->FileObject->FileName); | ||||
| } | ||||
|  | ||||
| NTSTATUS FspFsvolCreateRetryComplete( | ||||
|     PIRP Irp, FSP_FSCTL_TRANSACT_REQ *Request) | ||||
| { | ||||
|     PAGED_CODE(); | ||||
|  | ||||
|     return STATUS_NOT_IMPLEMENTED; | ||||
| } | ||||
|  | ||||
| static NTSTATUS FspFsvolCreateTryOpen(PIRP Irp, FSP_FSCTL_TRANSACT_REQ *Request, | ||||
|     FSP_FILE_NODE *FileNode, FSP_FILE_DESC *FileDesc, PFILE_OBJECT FileObject) | ||||
| { | ||||
|   | ||||
| @@ -66,11 +66,10 @@ NTSTATUS DriverEntry( | ||||
|     DriverObject->MajorFunction[IRP_MJ_QUERY_SECURITY] = FspQuerySecurity; | ||||
|     DriverObject->MajorFunction[IRP_MJ_SET_SECURITY] = FspSetSecurity; | ||||
|  | ||||
|     /* setup the I/O preparation functions */ | ||||
|     /* setup the I/O prepare/complete functions */ | ||||
|     FspIopPrepareFunction[IRP_MJ_CREATE] = FspFsvolCreatePrepare; | ||||
|  | ||||
|     /* setup the I/O completion functions */ | ||||
|     FspIopCompleteFunction[IRP_MJ_CREATE] = FspFsvolCreateComplete; | ||||
|     FspIopRetryCompleteFunction[IRP_MJ_CREATE] = FspFsvolCreateRetryComplete; | ||||
|     FspIopCompleteFunction[IRP_MJ_CLOSE] = FspFsvolCloseComplete; | ||||
|     FspIopCompleteFunction[IRP_MJ_READ] = FspFsvolReadComplete; | ||||
|     FspIopCompleteFunction[IRP_MJ_WRITE] = FspFsvolWriteComplete; | ||||
|   | ||||
| @@ -225,10 +225,15 @@ _IRQL_requires_max_(APC_LEVEL) | ||||
| _IRQL_requires_same_ | ||||
| typedef VOID FSP_IOCMPL_DISPATCH( | ||||
|     _Inout_ PIRP Irp, _In_ const FSP_FSCTL_TRANSACT_RSP *Response); | ||||
| FSP_IOPREP_DISPATCH FspFsvolCreatePrepare; | ||||
| _IRQL_requires_max_(APC_LEVEL) | ||||
| _IRQL_requires_same_ | ||||
| typedef NTSTATUS FSP_IORETR_DISPATCH( | ||||
|     _Inout_ PIRP Irp, _Inout_ FSP_FSCTL_TRANSACT_REQ *Request); | ||||
| FSP_IOCMPL_DISPATCH FspFsvolCleanupComplete; | ||||
| FSP_IOCMPL_DISPATCH FspFsvolCloseComplete; | ||||
| FSP_IOPREP_DISPATCH FspFsvolCreatePrepare; | ||||
| FSP_IOCMPL_DISPATCH FspFsvolCreateComplete; | ||||
| FSP_IORETR_DISPATCH FspFsvolCreateRetryComplete; | ||||
| FSP_IOCMPL_DISPATCH FspFsvolDeviceControlComplete; | ||||
| FSP_IOCMPL_DISPATCH FspFsvolDirectoryControlComplete; | ||||
| FSP_IOCMPL_DISPATCH FspFsvolFileSystemControlComplete; | ||||
| @@ -385,7 +390,7 @@ BOOLEAN FspIoqPostIrpEx(FSP_IOQ *Ioq, PIRP Irp, BOOLEAN BestEffort, NTSTATUS *PR | ||||
| PIRP FspIoqNextPendingIrp(FSP_IOQ *Ioq, PIRP BoundaryIrp, PLARGE_INTEGER Timeout); | ||||
| BOOLEAN FspIoqStartProcessingIrp(FSP_IOQ *Ioq, PIRP Irp); | ||||
| PIRP FspIoqEndProcessingIrp(FSP_IOQ *Ioq, UINT_PTR IrpHint); | ||||
| BOOLEAN FspIoqRetryCompleteIrp(FSP_IOQ *Ioq, PIRP Irp); | ||||
| BOOLEAN FspIoqRetryCompleteIrp(FSP_IOQ *Ioq, PIRP Irp, NTSTATUS *PResult); | ||||
| PIRP FspIoqNextCompleteIrp(FSP_IOQ *Ioq, PIRP BoundaryIrp); | ||||
|  | ||||
| /* I/O processing */ | ||||
| @@ -418,6 +423,7 @@ VOID FspIopCompleteIrpEx(PIRP Irp, NTSTATUS Result, BOOLEAN DeviceDereference); | ||||
| VOID FspIopCompleteCanceledIrp(PIRP Irp); | ||||
| NTSTATUS FspIopDispatchPrepare(PIRP Irp, FSP_FSCTL_TRANSACT_REQ *Request); | ||||
| VOID FspIopDispatchComplete(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response); | ||||
| NTSTATUS FspIopDispatchRetryComplete(PIRP Irp, FSP_FSCTL_TRANSACT_REQ *Request); | ||||
|  | ||||
| /* device management */ | ||||
| #define FSP_DEVICE_VOLUME_NAME_LENMAX   (FSP_FSCTL_VOLUME_NAME_SIZEMAX - sizeof(WCHAR)) | ||||
| @@ -654,5 +660,6 @@ extern PDEVICE_OBJECT FspFsctlDiskDeviceObject; | ||||
| extern PDEVICE_OBJECT FspFsctlNetDeviceObject; | ||||
| extern FSP_IOPREP_DISPATCH *FspIopPrepareFunction[]; | ||||
| extern FSP_IOCMPL_DISPATCH *FspIopCompleteFunction[]; | ||||
| extern FSP_IORETR_DISPATCH *FspIopRetryCompleteFunction[]; | ||||
|  | ||||
| #endif | ||||
|   | ||||
| @@ -19,6 +19,7 @@ VOID FspIopCompleteIrpEx(PIRP Irp, NTSTATUS Result, BOOLEAN DeviceDereference); | ||||
| VOID FspIopCompleteCanceledIrp(PIRP Irp); | ||||
| NTSTATUS FspIopDispatchPrepare(PIRP Irp, FSP_FSCTL_TRANSACT_REQ *Request); | ||||
| VOID FspIopDispatchComplete(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response); | ||||
| NTSTATUS FspIopDispatchRetryComplete(PIRP Irp, FSP_FSCTL_TRANSACT_REQ *Request); | ||||
|  | ||||
| #ifdef ALLOC_PRAGMA | ||||
| #pragma alloc_text(PAGE, FspIopCreateRequestFunnel) | ||||
| @@ -29,6 +30,7 @@ VOID FspIopDispatchComplete(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response); | ||||
| #pragma alloc_text(PAGE, FspIopCompleteCanceledIrp) | ||||
| #pragma alloc_text(PAGE, FspIopDispatchPrepare) | ||||
| #pragma alloc_text(PAGE, FspIopDispatchComplete) | ||||
| #pragma alloc_text(PAGE, FspIopDispatchRetryComplete) | ||||
| #endif | ||||
|  | ||||
| static const LONG Delays[] = | ||||
| @@ -268,5 +270,19 @@ VOID FspIopDispatchComplete(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response) | ||||
|     FspIopCompleteFunction[IrpSp->MajorFunction](Irp, Response); | ||||
| } | ||||
|  | ||||
| NTSTATUS FspIopDispatchRetryComplete(PIRP Irp, FSP_FSCTL_TRANSACT_REQ *Request) | ||||
| { | ||||
|     PAGED_CODE(); | ||||
|  | ||||
|     PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); | ||||
|  | ||||
|     ASSERT(IRP_MJ_MAXIMUM_FUNCTION >= IrpSp->MajorFunction); | ||||
|     if (0 != FspIopRetryCompleteFunction[IrpSp->MajorFunction]) | ||||
|         return FspIopRetryCompleteFunction[IrpSp->MajorFunction](Irp, Request); | ||||
|     else | ||||
|         return STATUS_SUCCESS; | ||||
| } | ||||
|  | ||||
| FSP_IOPREP_DISPATCH *FspIopPrepareFunction[IRP_MJ_MAXIMUM_FUNCTION + 1]; | ||||
| FSP_IOCMPL_DISPATCH *FspIopCompleteFunction[IRP_MJ_MAXIMUM_FUNCTION + 1]; | ||||
| FSP_IORETR_DISPATCH *FspIopRetryCompleteFunction[IRP_MJ_MAXIMUM_FUNCTION + 1]; | ||||
|   | ||||
| @@ -518,7 +518,7 @@ PIRP FspIoqEndProcessingIrp(FSP_IOQ *Ioq, UINT_PTR IrpHint) | ||||
|     return FspCsqRemoveNextIrp(&Ioq->ProcessIoCsq, &PeekContext); | ||||
| } | ||||
|  | ||||
| BOOLEAN FspIoqRetryCompleteIrp(FSP_IOQ *Ioq, PIRP Irp) | ||||
| BOOLEAN FspIoqRetryCompleteIrp(FSP_IOQ *Ioq, PIRP Irp, NTSTATUS *PResult) | ||||
| { | ||||
|     NTSTATUS Result; | ||||
| #if defined(FSP_IOQ_PROCESS_NO_CANCEL) | ||||
| @@ -528,7 +528,18 @@ BOOLEAN FspIoqRetryCompleteIrp(FSP_IOQ *Ioq, PIRP Irp) | ||||
|         FspIrpTimestamp(Irp) = QueryInterruptTimeInSec() + Ioq->IrpTimeout; | ||||
| #endif | ||||
|     Result = FspCsqInsertIrpEx(&Ioq->RetriedIoCsq, Irp, 0, 0); | ||||
|     return NT_SUCCESS(Result); | ||||
|     if (NT_SUCCESS(Result)) | ||||
|     { | ||||
|         if (0 != PResult) | ||||
|             *PResult = STATUS_PENDING; | ||||
|         return TRUE; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         if (0 != PResult) | ||||
|             *PResult = Result; | ||||
|         return FALSE; | ||||
|     } | ||||
| } | ||||
|  | ||||
| PIRP FspIoqNextCompleteIrp(FSP_IOQ *Ioq, PIRP BoundaryIrp) | ||||
| @@ -536,5 +547,5 @@ PIRP FspIoqNextCompleteIrp(FSP_IOQ *Ioq, PIRP BoundaryIrp) | ||||
|     FSP_IOQ_PEEK_CONTEXT PeekContext; | ||||
|     PeekContext.IrpHint = 0 != BoundaryIrp ? BoundaryIrp : (PVOID)1; | ||||
|     PeekContext.ExpirationTime = 0; | ||||
|     return IoCsqRemoveNextIrp(&Ioq->RetriedIoCsq, &PeekContext); | ||||
|     return FspCsqRemoveNextIrp(&Ioq->RetriedIoCsq, &PeekContext); | ||||
| } | ||||
|   | ||||
| @@ -517,7 +517,7 @@ NTSTATUS FspVolumeTransact( | ||||
|     PUINT8 BufferEnd; | ||||
|     FSP_FSCTL_TRANSACT_RSP *Response, *NextResponse; | ||||
|     FSP_FSCTL_TRANSACT_REQ *Request, *PendingIrpRequest; | ||||
|     PIRP ProcessIrp, PendingIrp, RepostedIrp = 0; | ||||
|     PIRP ProcessIrp, PendingIrp, RetriedIrp, RepostedIrp; | ||||
|     LARGE_INTEGER Timeout; | ||||
|  | ||||
|     /* process any user-mode file system responses */ | ||||
| @@ -539,6 +539,27 @@ NTSTATUS FspVolumeTransact( | ||||
|         Response = NextResponse; | ||||
|     } | ||||
|  | ||||
|     /* process any retried IRP's */ | ||||
|     RepostedIrp = 0; | ||||
|     for (;;) | ||||
|     { | ||||
|         /* get the next retried IRP, but do not go beyond the first reposted IRP! */ | ||||
|         RetriedIrp = FspIoqNextCompleteIrp(FsvolDeviceExtension->Ioq, RepostedIrp); | ||||
|         if (0 == RetriedIrp) | ||||
|             break; | ||||
|  | ||||
|         Result = FspIopDispatchRetryComplete(RetriedIrp, FspIrpRequest(RetriedIrp)); | ||||
|         if (STATUS_PENDING == Result) | ||||
|         { | ||||
|             /* | ||||
|              * The IRP has been reposted to our Ioq. Remember the first such IRP, | ||||
|              * so that we know to break the loop if we see it again. | ||||
|              */ | ||||
|             if (0 == RepostedIrp) | ||||
|                 RepostedIrp = RetriedIrp; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /* were we sent an output buffer? */ | ||||
|     if (0 == Irp->MdlAddress) | ||||
|     { | ||||
| @@ -564,6 +585,7 @@ NTSTATUS FspVolumeTransact( | ||||
|     } | ||||
|  | ||||
|     /* send any pending IRP's to the user-mode file system */ | ||||
|     RepostedIrp = 0; | ||||
|     Request = MdlBuffer; | ||||
|     BufferEnd = (PUINT8)MdlBuffer + OutputBufferLength; | ||||
|     ASSERT(FspFsctlTransactCanProduceRequest(Request, BufferEnd)); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user