diff --git a/src/sys/devctl.c b/src/sys/devctl.c index 14de171c..d6d24568 100644 --- a/src/sys/devctl.c +++ b/src/sys/devctl.c @@ -21,6 +21,8 @@ #include +static NTSTATUS FspFsvrtDeviceControl( + PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); static NTSTATUS FspFsvolDeviceControl( PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); FSP_IOCMPL_DISPATCH FspFsvolDeviceControlComplete; @@ -28,6 +30,7 @@ static FSP_IOP_REQUEST_FINI FspFsvolDeviceControlRequestFini; FSP_DRIVER_DISPATCH FspDeviceControl; #ifdef ALLOC_PRAGMA +#pragma alloc_text(PAGE, FspFsvrtDeviceControl) #pragma alloc_text(PAGE, FspFsvolDeviceControl) #pragma alloc_text(PAGE, FspFsvolDeviceControlComplete) #pragma alloc_text(PAGE, FspFsvolDeviceControlRequestFini) @@ -39,6 +42,28 @@ enum RequestFileNode = 0, }; +static NTSTATUS FspFsvrtDeviceControl( + PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp) +{ + PAGED_CODE(); + + /* + * Fix GitHub issue #177. All credit for the investigation of this issue + * and the suggested steps to reproduce and work around the problem goes + * to GitHub user @thinkport. + * + * When Windows attempts to mount a new volume it iterates over all disk file + * systems registered with IoRegisterFileSystem. Foreign (i.e. non-WinFsp) file + * systems would in some cases attempt to mount our Fsvrt volume device by + * sending it unknown IOCTL codes, which would then be failed with + * STATUS_INVALID_DEVICE_REQUEST. Unfortunately the file systems would then + * report this error code to the I/O Manager, which would cause it to abort the + * mounting process completely and thus WinFsp would never get a chance to + * mount its own volume device! + */ + return STATUS_UNRECOGNIZED_VOLUME; +} + static NTSTATUS FspFsvolDeviceControl( PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp) { @@ -155,6 +180,8 @@ NTSTATUS FspDeviceControl( { case FspFsvolDeviceExtensionKind: FSP_RETURN(Result = FspFsvolDeviceControl(DeviceObject, Irp, IrpSp)); + case FspFsvrtDeviceExtensionKind: + FSP_RETURN(Result = FspFsvrtDeviceControl(DeviceObject, Irp, IrpSp)); default: FSP_RETURN(Result = STATUS_INVALID_DEVICE_REQUEST); } diff --git a/src/sys/driver.c b/src/sys/driver.c index 928fcde7..224dec24 100644 --- a/src/sys/driver.c +++ b/src/sys/driver.c @@ -169,6 +169,21 @@ NTSTATUS DriverEntry( &FspFsmupDeviceObject); if (!NT_SUCCESS(Result)) goto exit; + +#if DBG + /* + * Fix GitHub issue #177. All credit for the investigation of this issue + * and the suggested steps to reproduce and work around the problem goes + * to GitHub user @thinkport. + * + * On debug builds set DO_LOW_PRIORITY_FILESYSTEM to place the file system + * at the end of the file system list during IoRegisterFileSystem below. + * This allows us to test the behavior of our Fsvrt devices when foreign + * file systems attempt to use them for mounting. + */ + SetFlag(FspFsctlDiskDeviceObject->Flags, DO_LOW_PRIORITY_FILESYSTEM); +#endif + Result = FspDeviceInitialize(FspFsctlDiskDeviceObject); ASSERT(STATUS_SUCCESS == Result); Result = FspDeviceInitialize(FspFsctlNetDeviceObject);