diff --git a/inc/winfsp/fsctl.h b/inc/winfsp/fsctl.h index 769db1e9..fcf705db 100644 --- a/inc/winfsp/fsctl.h +++ b/inc/winfsp/fsctl.h @@ -38,6 +38,8 @@ extern const __declspec(selectany) GUID FspFsvrtDeviceClassGuid = CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 'T', METHOD_BUFFERED, FILE_ANY_ACCESS) #define FSP_FSCTL_TRANSACT_BATCH \ CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 't', METHOD_OUT_DIRECT, FILE_ANY_ACCESS) +#define FSP_FSCTL_STOP \ + CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 'S', METHOD_BUFFERED, FILE_ANY_ACCESS) #define FSP_FSCTL_VOLUME_NAME_SIZEMAX 128 @@ -322,6 +324,7 @@ FSP_API NTSTATUS FspFsctlTransact(HANDLE VolumeHandle, PVOID ResponseBuf, SIZE_T ResponseBufSize, PVOID RequestBuf, SIZE_T *PRequestBufSize, BOOLEAN Batch); +FSP_API NTSTATUS FspFsctlStop(HANDLE VolumeHandle); #endif #ifdef __cplusplus diff --git a/src/dll/dispatch.c b/src/dll/dispatch.c index 79b02b9b..43fa7769 100644 --- a/src/dll/dispatch.c +++ b/src/dll/dispatch.c @@ -98,10 +98,6 @@ static DWORD WINAPI FspFileSystemDispatcherThread(PVOID FileSystem0) if (!NT_SUCCESS(Result)) goto exit; - FspFileSystemGetDispatcherResult(FileSystem, &Result); - if (!NT_SUCCESS(Result)) - goto exit; - memset(Response, 0, sizeof *Response); if (0 == RequestSize) continue; @@ -123,10 +119,6 @@ static DWORD WINAPI FspFileSystemDispatcherThread(PVOID FileSystem0) } else Response->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; - - FspFileSystemGetDispatcherResult(FileSystem, &Result); - if (!NT_SUCCESS(Result)) - goto exit; } exit: @@ -135,6 +127,8 @@ exit: FspFileSystemSetDispatcherResult(FileSystem, Result); + FspFsctlStop(FileSystem->VolumeHandle); + if (0 != DispatcherThread) { WaitForSingleObject(DispatcherThread, INFINITE); @@ -177,7 +171,7 @@ FSP_API VOID FspFileSystemStopDispatcher(FSP_FILE_SYSTEM *FileSystem) if (0 == FileSystem->DispatcherThread) return; - FspFileSystemSetDispatcherResult(FileSystem, STATUS_CANCELLED); + FspFsctlStop(FileSystem->VolumeHandle); WaitForSingleObject(FileSystem->DispatcherThread, INFINITE); CloseHandle(FileSystem->DispatcherThread); diff --git a/src/dll/fsctl.c b/src/dll/fsctl.c index 2144006d..0b3ee1b5 100644 --- a/src/dll/fsctl.c +++ b/src/dll/fsctl.c @@ -111,3 +111,11 @@ FSP_API NTSTATUS FspFsctlTransact(HANDLE VolumeHandle, exit: return Result; } + +FSP_API NTSTATUS FspFsctlStop(HANDLE VolumeHandle) +{ + if (!DeviceIoControl(VolumeHandle, FSP_FSCTL_STOP, 0, 0, 0, 0, 0, 0)) + return FspNtStatusFromWin32(GetLastError()); + + return STATUS_SUCCESS; +} diff --git a/src/sys/debug.c b/src/sys/debug.c index b568e759..5aee230e 100644 --- a/src/sys/debug.c +++ b/src/sys/debug.c @@ -160,6 +160,7 @@ const char *IoctlCodeSym(ULONG ControlCode) SYM(FSP_FSCTL_VOLUME_NAME) SYM(FSP_FSCTL_TRANSACT) SYM(FSP_FSCTL_TRANSACT_BATCH) + SYM(FSP_FSCTL_STOP) SYM(FSP_FSCTL_WORK) SYM(FSP_FSCTL_WORK_BEST_EFFORT) // cygwin: sed -n '/[IF][OS]CTL.*CTL_CODE/s/^#define[ \t]*\([^ \t]*\).*/SYM(\1)/p' diff --git a/src/sys/driver.h b/src/sys/driver.h index b67ffcab..2c5a6312 100644 --- a/src/sys/driver.h +++ b/src/sys/driver.h @@ -545,6 +545,8 @@ NTSTATUS FspVolumeGetName( PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); NTSTATUS FspVolumeTransact( PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); +NTSTATUS FspVolumeStop( + PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); NTSTATUS FspVolumeWork( PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); diff --git a/src/sys/fsctl.c b/src/sys/fsctl.c index 104303a9..fa6bb156 100644 --- a/src/sys/fsctl.c +++ b/src/sys/fsctl.c @@ -40,6 +40,10 @@ static NTSTATUS FspFsctlFileSystemControl( if (0 != IrpSp->FileObject->FsContext2) Result = FspVolumeTransact(DeviceObject, Irp, IrpSp); break; + case FSP_FSCTL_STOP: + if (0 != IrpSp->FileObject->FsContext2) + Result = FspVolumeStop(DeviceObject, Irp, IrpSp); + break; } break; case IRP_MN_MOUNT_VOLUME: diff --git a/src/sys/volume.c b/src/sys/volume.c index 42cf8928..1f350495 100644 --- a/src/sys/volume.c +++ b/src/sys/volume.c @@ -20,6 +20,8 @@ NTSTATUS FspVolumeGetName( PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); NTSTATUS FspVolumeTransact( PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); +NTSTATUS FspVolumeStop( + PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); NTSTATUS FspVolumeWork( PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); @@ -31,6 +33,7 @@ NTSTATUS FspVolumeWork( // ! #pragma alloc_text(PAGE, FspVolumeMount) #pragma alloc_text(PAGE, FspVolumeGetName) #pragma alloc_text(PAGE, FspVolumeTransact) +#pragma alloc_text(PAGE, FspVolumeStop) #pragma alloc_text(PAGE, FspVolumeRedirQueryPathEx) #pragma alloc_text(PAGE, FspVolumeWork) #endif @@ -693,6 +696,24 @@ exit: return Result; } +NTSTATUS FspVolumeStop( + PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp) +{ + PAGED_CODE(); + + ASSERT(IRP_MJ_FILE_SYSTEM_CONTROL == IrpSp->MajorFunction); + ASSERT(IRP_MN_USER_FS_REQUEST == IrpSp->MinorFunction); + ASSERT(FSP_FSCTL_STOP == IrpSp->Parameters.FileSystemControl.FsControlCode); + ASSERT(0 != IrpSp->FileObject->FsContext2); + + PDEVICE_OBJECT FsvolDeviceObject = IrpSp->FileObject->FsContext2; + FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject); + + FspIoqStop(FsvolDeviceExtension->Ioq); + + return STATUS_SUCCESS; +} + NTSTATUS FspVolumeWork( PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp) {