From 844fb7171e228fd773270cc348efd042fdaa6cd4 Mon Sep 17 00:00:00 2001 From: Bill Zissimopoulos Date: Tue, 6 Oct 2020 16:37:33 -0700 Subject: [PATCH] inc,dll,sys: notify implementation skeleton --- inc/winfsp/fsctl.h | 13 +++++++++++++ inc/winfsp/winfsp.h | 14 ++++++++++++++ src/dll/fs.c | 6 ++++++ src/dll/fsctl.c | 19 +++++++++++++++++++ src/sys/driver.h | 2 ++ src/sys/fsctl.c | 4 ++++ src/sys/volume.c | 21 +++++++++++++++++++++ 7 files changed, 79 insertions(+) diff --git a/inc/winfsp/fsctl.h b/inc/winfsp/fsctl.h index 4615fa85..3a66a9ad 100644 --- a/inc/winfsp/fsctl.h +++ b/inc/winfsp/fsctl.h @@ -66,6 +66,8 @@ extern const __declspec(selectany) GUID FspFsvrtDeviceClassGuid = 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_NOTIFY \ + CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 'n', METHOD_BUFFERED, FILE_ANY_ACCESS) /* fsctl internal device codes (usable only in-kernel) */ #define FSP_FSCTL_TRANSACT_INTERNAL \ @@ -268,6 +270,15 @@ typedef struct FSP_FSCTL_STATIC_ASSERT(24 == sizeof(FSP_FSCTL_STREAM_INFO), "sizeof(FSP_FSCTL_STREAM_INFO) must be exactly 24."); typedef struct +{ + UINT16 Size; + UINT32 Filter; + UINT32 Action; + WCHAR FileNameBuf[]; +} FSP_FSCTL_NOTIFY_INFO; +FSP_FSCTL_STATIC_ASSERT(12 == sizeof(FSP_FSCTL_NOTIFY_INFO), + "sizeof(FSP_FSCTL_NOTIFY_INFO) must be exactly 12."); +typedef struct { UINT64 UserContext; UINT64 UserContext2; @@ -617,6 +628,8 @@ FSP_API NTSTATUS FspFsctlTransact(HANDLE VolumeHandle, PVOID RequestBuf, SIZE_T *PRequestBufSize, BOOLEAN Batch); FSP_API NTSTATUS FspFsctlStop(HANDLE VolumeHandle); +FSP_API NTSTATUS FspFsctlNotify(HANDLE VolumeHandle, + FSP_FSCTL_NOTIFY_INFO *NotifyInfo, SIZE_T Size); FSP_API NTSTATUS FspFsctlGetVolumeList(PWSTR DevicePath, PWCHAR VolumeListBuf, PSIZE_T PVolumeListSize); FSP_API NTSTATUS FspFsctlPreflight(PWSTR DevicePath); diff --git a/inc/winfsp/winfsp.h b/inc/winfsp/winfsp.h index 0cd30bc3..15dd6a77 100644 --- a/inc/winfsp/winfsp.h +++ b/inc/winfsp/winfsp.h @@ -1186,6 +1186,20 @@ FSP_API VOID FspFileSystemStopDispatcher(FSP_FILE_SYSTEM *FileSystem); */ FSP_API VOID FspFileSystemSendResponse(FSP_FILE_SYSTEM *FileSystem, FSP_FSCTL_TRANSACT_RSP *Response); +/** + * Notify Windows that the file system has file changes. + * + * @param FileSystem + * The file system object. + * @param NotifyInfo + * Buffer containing information about file changes. + * @param Size + * Size of buffer. + * @return + * STATUS_SUCCESS or error code. + */ +FSP_API NTSTATUS FspFileSystemNotify(FSP_FILE_SYSTEM *FileSystem, + FSP_FSCTL_NOTIFY_INFO *NotifyInfo, SIZE_T Size); /** * Get the current operation context. * diff --git a/src/dll/fs.c b/src/dll/fs.c index d378694b..4f926b59 100644 --- a/src/dll/fs.c +++ b/src/dll/fs.c @@ -432,6 +432,12 @@ FSP_API FSP_FILE_SYSTEM_OPERATION_CONTEXT *FspFileSystemGetOperationContext(VOID return (FSP_FILE_SYSTEM_OPERATION_CONTEXT *)TlsGetValue(FspFileSystemTlsKey); } +FSP_API NTSTATUS FspFileSystemNotify(FSP_FILE_SYSTEM *FileSystem, + FSP_FSCTL_NOTIFY_INFO *NotifyInfo, SIZE_T Size) +{ + return FspFsctlNotify(FileSystem->VolumeHandle, NotifyInfo, Size); +} + /* * Out-of-Line */ diff --git a/src/dll/fsctl.c b/src/dll/fsctl.c index c5023815..f666b847 100644 --- a/src/dll/fsctl.c +++ b/src/dll/fsctl.c @@ -161,6 +161,25 @@ FSP_API NTSTATUS FspFsctlStop(HANDLE VolumeHandle) return STATUS_SUCCESS; } +FSP_API NTSTATUS FspFsctlNotify(HANDLE VolumeHandle, + FSP_FSCTL_NOTIFY_INFO *NotifyInfo, SIZE_T Size) +{ + NTSTATUS Result = STATUS_SUCCESS; + DWORD Bytes = 0; + + if (!DeviceIoControl(VolumeHandle, + FSP_FSCTL_NOTIFY, + NotifyInfo, (DWORD)Size, 0, 0, + &Bytes, 0)) + { + Result = FspNtStatusFromWin32(GetLastError()); + goto exit; + } + +exit: + return Result; +} + FSP_API NTSTATUS FspFsctlGetVolumeList(PWSTR DevicePath, PWCHAR VolumeListBuf, PSIZE_T PVolumeListSize) { diff --git a/src/sys/driver.h b/src/sys/driver.h index 9391541a..2c249ebb 100644 --- a/src/sys/driver.h +++ b/src/sys/driver.h @@ -1328,6 +1328,8 @@ NTSTATUS FspVolumeTransactFsext( PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); NTSTATUS FspVolumeStop( PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); +NTSTATUS FspVolumeNotify( + 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 175a6096..b6b18cc9 100644 --- a/src/sys/fsctl.c +++ b/src/sys/fsctl.c @@ -98,6 +98,10 @@ static NTSTATUS FspFsctlFileSystemControl( if (0 != IrpSp->FileObject->FsContext2) Result = FspVolumeStop(FsctlDeviceObject, Irp, IrpSp); break; + case FSP_FSCTL_NOTIFY: + if (0 != IrpSp->FileObject->FsContext2) + Result = FspVolumeNotify(FsctlDeviceObject, Irp, IrpSp); + break; default: if (CTL_CODE(0, 0xC00, 0, 0) == (IrpSp->Parameters.FileSystemControl.FsControlCode & CTL_CODE(0, 0xC00, 0, 0))) diff --git a/src/sys/volume.c b/src/sys/volume.c index 1922b39d..81ebfdf3 100644 --- a/src/sys/volume.c +++ b/src/sys/volume.c @@ -50,6 +50,8 @@ NTSTATUS FspVolumeTransactFsext( PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); NTSTATUS FspVolumeStop( PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); +NTSTATUS FspVolumeNotify( + PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); NTSTATUS FspVolumeWork( PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); @@ -68,6 +70,7 @@ NTSTATUS FspVolumeWork( #pragma alloc_text(PAGE, FspVolumeTransact) #pragma alloc_text(PAGE, FspVolumeTransactFsext) #pragma alloc_text(PAGE, FspVolumeStop) +#pragma alloc_text(PAGE, FspVolumeNotify) #pragma alloc_text(PAGE, FspVolumeWork) #endif @@ -1054,6 +1057,24 @@ NTSTATUS FspVolumeStop( return STATUS_SUCCESS; } +NTSTATUS FspVolumeNotify( + 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_NOTIFY == IrpSp->Parameters.FileSystemControl.FsControlCode); + ASSERT(0 != IrpSp->FileObject->FsContext2); + +#if 0 + PDEVICE_OBJECT FsvolDeviceObject = IrpSp->FileObject->FsContext2; + FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject); +#endif + + return STATUS_SUCCESS; +} + NTSTATUS FspVolumeWork( PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp) {