mirror of
				https://github.com/winfsp/winfsp.git
				synced 2025-10-30 19:48:38 -05:00 
			
		
		
		
	sys: FspFsvrtTransact: now has timeout
This commit is contained in:
		| @@ -70,11 +70,18 @@ enum | ||||
|     FspFsctlTransactQuerySecurityKind = 'S', | ||||
|     FspFsctlTransactSetSecurityKind = 's', | ||||
| }; | ||||
| enum | ||||
| { | ||||
|     FspFsctlTransactTimeoutMinimum = 1000, | ||||
|     FspFsctlTransactTimeoutMaximum = 10000, | ||||
|     FspFsctlTransactTimeoutDefault = 1000, | ||||
| }; | ||||
| typedef struct | ||||
| { | ||||
|     UINT16 Version; | ||||
|     UINT16 SectorSize; | ||||
|     UINT32 SerialNumber; | ||||
|     UINT32 TransactTimeout;             /* milliseconds; values between 1000ms and 10000ms */ | ||||
|     UINT32 EaSupported:1;               /* supports extended attributes (unimplemented; set to 0) */ | ||||
|     UINT32 FileNameRequired:1;          /* FileName required for all operations (not just Create) */ | ||||
|     UINT32 NoSystemAccessCheck:1;       /* if set the user-mode flie system performs access checks */ | ||||
|   | ||||
| @@ -246,6 +246,7 @@ FAST_IO_ACQUIRE_FOR_CCFLUSH FspAcquireForCcFlush; | ||||
| FAST_IO_RELEASE_FOR_CCFLUSH FspReleaseForCcFlush; | ||||
|  | ||||
| /* I/O queue */ | ||||
| #define FspIoqTimeout                   ((PIRP)1) | ||||
| typedef struct | ||||
| { | ||||
|     KSPIN_LOCK SpinLock; | ||||
| @@ -258,7 +259,7 @@ VOID FspIoqInitialize(FSP_IOQ *Ioq); | ||||
| VOID FspIoqStop(FSP_IOQ *Ioq); | ||||
| BOOLEAN FspIoqStopped(FSP_IOQ *Ioq); | ||||
| BOOLEAN FspIoqPostIrp(FSP_IOQ *Ioq, PIRP Irp); | ||||
| PIRP FspIoqNextPendingIrp(FSP_IOQ *Ioq, ULONG millis); | ||||
| PIRP FspIoqNextPendingIrp(FSP_IOQ *Ioq, PLARGE_INTEGER Timeout); | ||||
| BOOLEAN FspIoqStartProcessingIrp(FSP_IOQ *Ioq, PIRP Irp); | ||||
| PIRP FspIoqEndProcessingIrp(FSP_IOQ *Ioq, UINT_PTR IrpHint); | ||||
|  | ||||
|   | ||||
| @@ -353,6 +353,8 @@ static NTSTATUS FspFsvrtTransact( | ||||
|     FSP_FSCTL_TRANSACT_RSP *Response, *NextResponse; | ||||
|     FSP_FSCTL_TRANSACT_REQ *Request, *PendingIrpRequest; | ||||
|     PIRP ProcessIrp, PendingIrp; | ||||
|     ULONG TransactTimeout; | ||||
|     LARGE_INTEGER Timeout; | ||||
|  | ||||
|     /* access check */ | ||||
|     Result = FspSecuritySubjectContextAccessCheck( | ||||
| @@ -380,12 +382,21 @@ static NTSTATUS FspFsvrtTransact( | ||||
|     } | ||||
|  | ||||
|     /* wait for an IRP to arrive */ | ||||
| retry: | ||||
|     while (0 == (PendingIrp = FspIoqNextPendingIrp(&FsvrtDeviceExtension->Ioq, (ULONG)-1L))) | ||||
|     TransactTimeout = FsvrtDeviceExtension->VolumeParams.TransactTimeout; | ||||
|     if (FspFsctlTransactTimeoutMinimum > TransactTimeout || TransactTimeout > FspFsctlTransactTimeoutMaximum) | ||||
|         TransactTimeout = FspFsctlTransactTimeoutDefault; | ||||
|     KeQuerySystemTime(&Timeout); | ||||
|     Timeout.QuadPart += TransactTimeout * 10000; /* convert millis to nanos and add to absolute time */ | ||||
|     while (0 == (PendingIrp = FspIoqNextPendingIrp(&FsvrtDeviceExtension->Ioq, &Timeout))) | ||||
|     { | ||||
|         if (FspIoqStopped(&FsvrtDeviceExtension->Ioq)) | ||||
|             return STATUS_CANCELLED; | ||||
|     } | ||||
|     if (FspIoqTimeout == PendingIrp) | ||||
|     { | ||||
|         Irp->IoStatus.Information = 0; | ||||
|         return STATUS_SUCCESS; | ||||
|     } | ||||
|  | ||||
|     /* send any pending IRP's to the user-mode file system */ | ||||
|     Request = SystemBuffer; | ||||
| @@ -426,10 +437,6 @@ retry: | ||||
|             break; | ||||
|  | ||||
|     } | ||||
|  | ||||
|     if (Request == SystemBuffer) | ||||
|         goto retry; | ||||
|  | ||||
|     Irp->IoStatus.Information = (PUINT8)Request - (PUINT8)SystemBuffer; | ||||
|  | ||||
|     return STATUS_SUCCESS; | ||||
|   | ||||
| @@ -209,17 +209,17 @@ BOOLEAN FspIoqPostIrp(FSP_IOQ *Ioq, PIRP Irp) | ||||
|     return NT_SUCCESS(Result); | ||||
| } | ||||
|  | ||||
| PIRP FspIoqNextPendingIrp(FSP_IOQ *Ioq, ULONG millis) | ||||
| PIRP FspIoqNextPendingIrp(FSP_IOQ *Ioq, PLARGE_INTEGER Timeout) | ||||
| { | ||||
|     if (0 != millis) | ||||
|     /* timeout of 0 normally means infinite wait; for us it means do not do any wait at all! */ | ||||
|     if (0 != Timeout) | ||||
|     { | ||||
|         NTSTATUS Result; | ||||
|         LARGE_INTEGER Timeout; | ||||
|         Timeout.QuadPart = (LONGLONG)millis * 10000; | ||||
|         Result = KeWaitForSingleObject(&Ioq->PendingIrpEvent, Executive, KernelMode, FALSE, | ||||
|             -1 == millis ? 0 : &Timeout); | ||||
|         if (STATUS_SUCCESS != Result) | ||||
|             return 0; | ||||
|             Timeout); | ||||
|         ASSERT(STATUS_SUCCESS == Result || STATUS_TIMEOUT == Result); | ||||
|         if (STATUS_TIMEOUT == Result) | ||||
|             return FspIoqTimeout; | ||||
|     } | ||||
|     return IoCsqRemoveNextIrp(&Ioq->PendingIoCsq, (PVOID)1); | ||||
| } | ||||
|   | ||||
| @@ -194,13 +194,8 @@ void mount_volume_transact_dotest(PWSTR DeviceName) | ||||
|     Response->Size = sizeof *Response; | ||||
|     Response->Hint = Request->Hint; | ||||
|     Response->Kind = Request->Kind; | ||||
|     Response->IoStatus.Status = STATUS_SUCCESS; | ||||
|     Response->IoStatus.Information = FILE_CREATED; | ||||
|     Response->Rsp.Create.Opened.UserContext = 41; | ||||
|     Response->Rsp.Create.Opened.UserContext2 = 42; | ||||
|     Response->Rsp.Create.Opened.FileAttributes = FILE_ATTRIBUTE_NORMAL; | ||||
|     Response->Rsp.Create.Opened.SecurityDescriptor.Offset = 0; | ||||
|     Response->Rsp.Create.Opened.SecurityDescriptor.Size = 0; | ||||
|     Response->IoStatus.Status = STATUS_ACCESS_DENIED; | ||||
|     Response->IoStatus.Information = 0; | ||||
|  | ||||
|     Response = FspFsctlTransactProduceResponse(Response, Response->Size); | ||||
|     ASSERT(0 != Response); | ||||
| @@ -224,7 +219,7 @@ void mount_volume_transact_dotest(PWSTR DeviceName) | ||||
|     GetExitCodeThread(Thread, &ExitCode); | ||||
|     CloseHandle(Thread); | ||||
|  | ||||
|     ASSERT(0 == ExitCode); | ||||
|     ASSERT(ERROR_ACCESS_DENIED == ExitCode); | ||||
| } | ||||
|  | ||||
| void mount_volume_transact_test(void) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user