From 2ffb8a1c97f6e6d39d3e34c86366e4859ac51656 Mon Sep 17 00:00:00 2001 From: Bill Zissimopoulos Date: Sun, 24 May 2020 21:04:28 -0700 Subject: [PATCH] sys: FSP_FSCTL_QUERY_WINFSP The FSP_FSCTL_QUERY_WINFSP code provides a simple method to determine if the file system backing a file is a WinFsp file system. To use issue a DeviceIoControl(Handle, FSP_FSCTL_QUERY_WINFSP, 0, 0, 0, 0, &Bytes, 0) If the return value is TRUE this is a WinFsp file system. --- inc/winfsp/fsctl.h | 4 ++++ src/sys/fsctl.c | 4 ++++ tst/winfsp-tests/info-test.c | 42 ++++++++++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+) diff --git a/inc/winfsp/fsctl.h b/inc/winfsp/fsctl.h index 353bf5fb..4615fa85 100644 --- a/inc/winfsp/fsctl.h +++ b/inc/winfsp/fsctl.h @@ -71,6 +71,10 @@ extern const __declspec(selectany) GUID FspFsvrtDeviceClassGuid = #define FSP_FSCTL_TRANSACT_INTERNAL \ CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 'I', METHOD_NEITHER, FILE_ANY_ACCESS) +/* fsvol device codes */ +#define FSP_FSCTL_QUERY_WINFSP \ + CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + '?', METHOD_BUFFERED, FILE_ANY_ACCESS) + #define FSP_FSCTL_VOLUME_PARAMS_PREFIX "\\VolumeParams=" #define FSP_FSCTL_VOLUME_NAME_SIZE (64 * sizeof(WCHAR)) diff --git a/src/sys/fsctl.c b/src/sys/fsctl.c index 1b9bc5de..175a6096 100644 --- a/src/sys/fsctl.c +++ b/src/sys/fsctl.c @@ -698,6 +698,10 @@ static NTSTATUS FspFsvolFileSystemControl( case FSP_FSCTL_WORK_BEST_EFFORT: Result = FspVolumeWork(FsvolDeviceObject, Irp, IrpSp); break; + case FSP_FSCTL_QUERY_WINFSP: + Irp->IoStatus.Information = 0; + Result = STATUS_SUCCESS; + break; case FSCTL_GET_REPARSE_POINT: Result = FspFsvolFileSystemControlReparsePoint(FsvolDeviceObject, Irp, IrpSp, FALSE); break; diff --git a/tst/winfsp-tests/info-test.c b/tst/winfsp-tests/info-test.c index b72f9c84..0d6b893e 100644 --- a/tst/winfsp-tests/info-test.c +++ b/tst/winfsp-tests/info-test.c @@ -1930,6 +1930,47 @@ void setvolinfo_test(void) } } +void query_winfsp_dotest(ULONG Flags, PWSTR Prefix, ULONG FileInfoTimeout, BOOLEAN ExpectWinFsp) +{ + void* memfs = memfs_start_ex(Flags, FileInfoTimeout); + + WCHAR FilePath[MAX_PATH]; + HANDLE Handle; + DWORD BytesTransferred; + + StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\", + Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); + + Handle = CreateFileW(FilePath, + 0, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS, 0); + ASSERT(INVALID_HANDLE_VALUE != Handle); + + if (ExpectWinFsp) + ASSERT(DeviceIoControl(Handle, FSP_FSCTL_QUERY_WINFSP, 0, 0, 0, 0, &BytesTransferred, 0)); + else + ASSERT(!DeviceIoControl(Handle, FSP_FSCTL_QUERY_WINFSP, 0, 0, 0, 0, &BytesTransferred, 0) && + ERROR_INVALID_FUNCTION == GetLastError()); + + CloseHandle(Handle); + + memfs_stop(memfs); +} + +void query_winfsp_test(void) +{ + if (NtfsTests) + { + WCHAR DirBuf[MAX_PATH], DriveBuf[3]; + GetTestDirectoryAndDrive(DirBuf, DriveBuf); + query_winfsp_dotest(-1, DriveBuf, 0, FALSE); + } + if (WinFspDiskTests) + query_winfsp_dotest(MemfsDisk, 0, 0, TRUE); + if (WinFspNetTests) + query_winfsp_dotest(MemfsNet, L"\\\\memfs\\share", 0, TRUE); +} + void info_tests(void) { if (!OptShareName) @@ -1955,4 +1996,5 @@ void info_tests(void) TEST(rename_pid_test); TEST(getvolinfo_test); TEST(setvolinfo_test); + TEST(query_winfsp_test); }