diff --git a/inc/winfsp/fsctl.h b/inc/winfsp/fsctl.h index 3d7b8ef0..bdc204e2 100644 --- a/inc/winfsp/fsctl.h +++ b/inc/winfsp/fsctl.h @@ -76,13 +76,18 @@ enum FspFsctlTransactTimeoutMinimum = 1000, FspFsctlTransactTimeoutMaximum = 10000, FspFsctlTransactTimeoutDefault = 1000, + FspFsctlIrpTimeoutMinimum = 60000, + FspFsctlIrpTimeoutMaximum = 600000, + FspFsctlIrpTimeoutDefault = 300000, + FspFsctlIrpTimeoutDebug = 42, /* special value for IRP timeout testing; debug driver only */ }; typedef struct { UINT16 Version; UINT16 SectorSize; UINT32 SerialNumber; - UINT32 TransactTimeout; /* milliseconds; values between 1000ms and 10000ms */ + UINT32 TransactTimeout; /* milliseconds; values between 1 sec and 10 sec */ + UINT32 IrpTimeout; /* milliseconds; values between 1 min and 10 min */ 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 */ diff --git a/src/sys/fsctl.c b/src/sys/fsctl.c index d7c3d684..3e5c2f68 100644 --- a/src/sys/fsctl.c +++ b/src/sys/fsctl.c @@ -119,10 +119,22 @@ static NTSTATUS FspFsctlCreateVolume( return STATUS_BUFFER_TOO_SMALL; NTSTATUS Result; - FSP_FSCTL_VOLUME_PARAMS Params = *(FSP_FSCTL_VOLUME_PARAMS *)SystemBuffer; + FSP_FSCTL_VOLUME_PARAMS VolumeParams = *(FSP_FSCTL_VOLUME_PARAMS *)SystemBuffer; PVOID SecurityDescriptorBuf = 0; FSP_FSVRT_DEVICE_EXTENSION *FsvrtDeviceExtension; + /* check the passed in VolumeParams */ + if (FspFsctlIrpTimeoutMinimum > VolumeParams.IrpTimeout || + VolumeParams.IrpTimeout > FspFsctlIrpTimeoutMaximum) +#if DBG + /* allow the debug timeout value on debug builds */ + if (FspFsctlIrpTimeoutDebug != VolumeParams.IrpTimeout) +#endif + VolumeParams.IrpTimeout = FspFsctlIrpTimeoutDefault; + if (FspFsctlTransactTimeoutMinimum > VolumeParams.TransactTimeout || + VolumeParams.TransactTimeout > FspFsctlTransactTimeoutMaximum) + VolumeParams.TransactTimeout = FspFsctlTransactTimeoutDefault; + /* create volume guid */ GUID Guid; Result = FspCreateGuid(&Guid); @@ -160,10 +172,10 @@ static NTSTATUS FspFsctlCreateVolume( if (NT_SUCCESS(Result)) { #pragma prefast(suppress:28175, "We are a filesystem: ok to access SectorSize") - FsvrtDeviceObject->SectorSize = Params.SectorSize; + FsvrtDeviceObject->SectorSize = VolumeParams.SectorSize; FsvrtDeviceExtension = FspFsvrtDeviceExtension(FsvrtDeviceObject); FsvrtDeviceExtension->FsctlDeviceObject = DeviceObject; - FsvrtDeviceExtension->VolumeParams = Params; + FsvrtDeviceExtension->VolumeParams = VolumeParams; RtlCopyMemory(FsvrtDeviceExtension->SecurityDescriptorBuf, SecurityDescriptorBuf, SecurityDescriptorSize); ClearFlag(FsvrtDeviceObject->Flags, DO_DEVICE_INITIALIZING); @@ -422,7 +434,6 @@ 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 */ @@ -451,11 +462,9 @@ static NTSTATUS FspFsvrtTransact( } /* wait for an IRP to arrive */ - 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 */ + Timeout.QuadPart += FsvrtDeviceExtension->VolumeParams.TransactTimeout * 10000; + /* convert millis to nanos and add to absolute time */ while (0 == (PendingIrp = FspIoqNextPendingIrp(&FsvrtDeviceExtension->Ioq, &Timeout))) { if (FspIoqStopped(&FsvrtDeviceExtension->Ioq))