diff --git a/CHANGELOG.md b/CHANGELOG.md index b8711912..8ba52c19 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ * Drive letters in UI should always be lowercase * Fixed WinFSP directory rename for non-empty directories * Migrated to v2 error handling +* Upgraded WinFSP to v2.1 (20205) ## v2.0.5-rc diff --git a/README.md b/README.md index fafe53d7..e4ccd0ee 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,7 @@ on Windows. * [Sia renterd](https://github.com/SiaFoundation/renterd/releases) v2.0.0+ for Sia support * Linux requires `fusermount3`; otherwise, `repertory` must be manually compiled with `libfuse2` support * Windows requires the following dependencies to be installed: - * [WinFSP 2023](https://github.com/winfsp/winfsp/releases/download/v2.0/winfsp-2.0.23075.msi) + * [WinFSP 2025](https://github.com/winfsp/winfsp/releases/download/v2.1/winfsp-2.1.25156.msi) ### Supported Operating Systems diff --git a/cmake/libraries/winfsp.cmake b/cmake/libraries/winfsp.cmake index 5b7b4586..9fd0900a 100644 --- a/cmake/libraries/winfsp.cmake +++ b/cmake/libraries/winfsp.cmake @@ -2,9 +2,9 @@ if(PROJECT_ENABLE_WINFSP AND PROJECT_IS_MINGW) if(PROJECT_BUILD) add_definitions(-DPROJECT_ENABLE_WINFSP) - include_directories(BEFORE SYSTEM ${PROJECT_3RD_PARTY_DIR}/winfsp-2.0/inc) + include_directories(BEFORE SYSTEM ${PROJECT_3RD_PARTY_DIR}/winfsp-2.1/inc) - link_directories(BEFORE ${PROJECT_3RD_PARTY_DIR}/winfsp-2.0/lib) + link_directories(BEFORE ${PROJECT_3RD_PARTY_DIR}/winfsp-2.1/lib) if(PROJECT_IS_ARM64) link_libraries(winfsp-a64) diff --git a/scripts/copy_mingw64_deps.sh b/scripts/copy_mingw64_deps.sh index 51cf3416..ab905e7e 100755 --- a/scripts/copy_mingw64_deps.sh +++ b/scripts/copy_mingw64_deps.sh @@ -194,7 +194,7 @@ if [ "${PROJECT_ENABLE_WINFSP}" == "ON" ]; then fi if [ "${WINFSP_DLL_PART}" != "" ]; then - PROJECT_MINGW64_COPY_DEPENDENCIES+=(${PROJECT_3RD_PARTY_DIR}/winfsp-2.0/bin/winfsp-${WINFSP_DLL_PART}.dll) + PROJECT_MINGW64_COPY_DEPENDENCIES+=(${PROJECT_3RD_PARTY_DIR}/winfsp-2.1/bin/winfsp-${WINFSP_DLL_PART}.dll) fi fi diff --git a/support/3rd_party/winfsp-2.0/bin/memfs-a64.exe b/support/3rd_party/winfsp-2.0/bin/memfs-a64.exe deleted file mode 100644 index bf44ad4b..00000000 Binary files a/support/3rd_party/winfsp-2.0/bin/memfs-a64.exe and /dev/null differ diff --git a/support/3rd_party/winfsp-2.0/bin/memfs-x64.exe b/support/3rd_party/winfsp-2.0/bin/memfs-x64.exe deleted file mode 100644 index 930f5aed..00000000 Binary files a/support/3rd_party/winfsp-2.0/bin/memfs-x64.exe and /dev/null differ diff --git a/support/3rd_party/winfsp-2.0/bin/memfs-x86.exe b/support/3rd_party/winfsp-2.0/bin/memfs-x86.exe deleted file mode 100644 index a9c1c995..00000000 Binary files a/support/3rd_party/winfsp-2.0/bin/memfs-x86.exe and /dev/null differ diff --git a/support/3rd_party/winfsp-2.0/bin/winfsp-a64.dll b/support/3rd_party/winfsp-2.0/bin/winfsp-a64.dll deleted file mode 100644 index 43f11e9e..00000000 Binary files a/support/3rd_party/winfsp-2.0/bin/winfsp-a64.dll and /dev/null differ diff --git a/support/3rd_party/winfsp-2.0/bin/winfsp-x64.dll b/support/3rd_party/winfsp-2.0/bin/winfsp-x64.dll deleted file mode 100644 index 34cc3772..00000000 Binary files a/support/3rd_party/winfsp-2.0/bin/winfsp-x64.dll and /dev/null differ diff --git a/support/3rd_party/winfsp-2.0/bin/winfsp-x64.sys b/support/3rd_party/winfsp-2.0/bin/winfsp-x64.sys deleted file mode 100644 index 3dc7463d..00000000 Binary files a/support/3rd_party/winfsp-2.0/bin/winfsp-x64.sys and /dev/null differ diff --git a/support/3rd_party/winfsp-2.0/bin/winfsp-x86.dll b/support/3rd_party/winfsp-2.0/bin/winfsp-x86.dll deleted file mode 100644 index 0dacb652..00000000 Binary files a/support/3rd_party/winfsp-2.0/bin/winfsp-x86.dll and /dev/null differ diff --git a/support/3rd_party/winfsp-2.0/inc/winfsp/fsctl.h b/support/3rd_party/winfsp-2.0/inc/winfsp/fsctl.h deleted file mode 100644 index 1d8c1fcb..00000000 --- a/support/3rd_party/winfsp-2.0/inc/winfsp/fsctl.h +++ /dev/null @@ -1,839 +0,0 @@ -/** - * @file winfsp/fsctl.h - * - * @copyright 2015-2022 Bill Zissimopoulos - */ -/* - * This file is part of WinFsp. - * - * You can redistribute it and/or modify it under the terms of the GNU - * General Public License version 3 as published by the Free Software - * Foundation. - * - * Licensees holding a valid commercial license may use this software - * in accordance with the commercial license agreement provided in - * conjunction with the software. The terms and conditions of any such - * commercial license agreement shall govern, supersede, and render - * ineffective any application of the GPLv3 license to this software, - * notwithstanding of any reference thereto in the software or - * associated repository. - */ - -#ifndef WINFSP_FSCTL_H_INCLUDED -#define WINFSP_FSCTL_H_INCLUDED - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* static_assert is a C++11 feature, but seems to work with C on MSVC 2015 */ -#if defined(WINFSP_SYS_INTERNAL) || defined(WINFSP_DLL_INTERNAL) -#define FSP_FSCTL_STATIC_ASSERT(e, m) static_assert(e, m) -#else -#define FSP_FSCTL_STATIC_ASSERT(e, m) static_assert(1, "") -#endif - -#define FSP_FSCTL_STR(x) FSP_FSCTL_STR_(x) -#define FSP_FSCTL_STR_(x) #x -#if defined(MyProductName) -#define FSP_FSCTL_PRODUCT_NAME FSP_FSCTL_STR(MyProductName) -#else -#define FSP_FSCTL_PRODUCT_NAME "WinFsp" -#endif -#if defined(MyProductFileName) -#define FSP_FSCTL_PRODUCT_FILE_NAME FSP_FSCTL_STR(MyProductFileName) -#else -#define FSP_FSCTL_PRODUCT_FILE_NAME "winfsp" -#endif - -#define FSP_FSCTL_DRIVER_NAME FSP_FSCTL_PRODUCT_NAME -#define FSP_FSCTL_DISK_DEVICE_NAME FSP_FSCTL_DRIVER_NAME ".Disk" -#define FSP_FSCTL_NET_DEVICE_NAME FSP_FSCTL_DRIVER_NAME ".Net" -#define FSP_FSCTL_MUP_DEVICE_NAME FSP_FSCTL_DRIVER_NAME ".Mup" - -#if defined(MyFspFsctlDeviceClassGuid) -extern const __declspec(selectany) GUID FspFsctlDeviceClassGuid = - MyFspFsctlDeviceClassGuid; -#else -extern const __declspec(selectany) GUID FspFsctlDeviceClassGuid = { - 0x6f9d25fa, - 0x6dee, - 0x4a9d, - {0x80, 0xf5, 0xe9, 0x8e, 0x14, 0xf3, 0x5e, 0x54}}; -#endif -#if defined(MyFspFsvrtDeviceClassGuid) -extern const __declspec(selectany) GUID FspFsvrtDeviceClassGuid = - MyFspFsvrtDeviceClassGuid; -#else -extern const __declspec(selectany) GUID FspFsvrtDeviceClassGuid = { - 0xb48171c3, - 0xdd50, - 0x4852, - {0x83, 0xa3, 0x34, 0x4c, 0x50, 0xd9, 0x3b, 0x17}}; -#endif - -/* locations */ -#define FSP_FSCTL_PRODUCT_REGKEY "Software\\" FSP_FSCTL_PRODUCT_NAME -#define FSP_FSCTL_PRODUCT_REGKEY_WOW64 KEY_WOW64_32KEY -#if defined(_ARM64_) -#define FSP_FSCTL_PRODUCT_FULL_REGKEY \ - "Software\\WOW6432Node\\" FSP_FSCTL_PRODUCT_NAME -#define FSP_FSCTL_PRODUCT_FILE_ARCH "a64" -#elif defined(_AMD64_) -#define FSP_FSCTL_PRODUCT_FULL_REGKEY \ - "Software\\WOW6432Node\\" FSP_FSCTL_PRODUCT_NAME -#define FSP_FSCTL_PRODUCT_FILE_ARCH "x64" -#elif defined(_X86_) -#define FSP_FSCTL_PRODUCT_FULL_REGKEY "Software\\" FSP_FSCTL_PRODUCT_NAME -#define FSP_FSCTL_PRODUCT_FILE_ARCH "x86" -#else -#error unknown architecture -#endif - -/* alignment macros */ -#define FSP_FSCTL_ALIGN_UP(x, s) (((x) + ((s)-1L)) & ~((s)-1L)) -#define FSP_FSCTL_DEFAULT_ALIGNMENT 8 -#define FSP_FSCTL_DEFAULT_ALIGN_UP(x) \ - FSP_FSCTL_ALIGN_UP(x, FSP_FSCTL_DEFAULT_ALIGNMENT) -#define FSP_FSCTL_DECLSPEC_ALIGN __declspec(align(FSP_FSCTL_DEFAULT_ALIGNMENT)) - -/* fsctl device codes */ -#define FSP_FSCTL_MOUNTDEV \ - CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 'M', METHOD_BUFFERED, \ - FILE_ANY_ACCESS) -#define FSP_FSCTL_MOUNTMGR \ - CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 'm', METHOD_BUFFERED, \ - FILE_ANY_ACCESS) -#define FSP_FSCTL_VOLUME_NAME \ - CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 'N', METHOD_BUFFERED, \ - FILE_ANY_ACCESS) -#define FSP_FSCTL_VOLUME_LIST \ - CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 'L', METHOD_BUFFERED, \ - FILE_ANY_ACCESS) -#define FSP_FSCTL_TRANSACT \ - CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 'T', METHOD_BUFFERED, \ - FILE_ANY_ACCESS) -#define FSP_IOCTL_TRANSACT \ - CTL_CODE(0x8000 | ('F' << 8) | 'W', 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_IOCTL_TRANSACT_BATCH \ - CTL_CODE(0x8000 | ('F' << 8) | 'W', 0x800 + 't', METHOD_BUFFERED, \ - FILE_ANY_ACCESS) -#define FSP_FSCTL_STOP \ - CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 'S', METHOD_BUFFERED, \ - FILE_ANY_ACCESS) -#define FSP_FSCTL_STOP0 \ - 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_NEITHER, \ - FILE_ANY_ACCESS) -#define FSP_FSCTL_UNLOAD \ - CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 'U', METHOD_NEITHER, \ - FILE_ANY_ACCESS) - -/* fsctl internal device codes (usable only in-kernel) */ -#define FSP_FSCTL_TRANSACT_INTERNAL \ - CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 'I', METHOD_NEITHER, \ - FILE_ANY_ACCESS) -#define FSP_IOCTL_TRANSACT_INTERNAL \ - CTL_CODE(0x8000 | ('F' << 8) | 'W', 0x800 + 'I', METHOD_BUFFERED, \ - 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)) -#define FSP_FSCTL_VOLUME_PREFIX_SIZE (192 * sizeof(WCHAR)) -#define FSP_FSCTL_VOLUME_FSNAME_SIZE (16 * sizeof(WCHAR)) -#define FSP_FSCTL_VOLUME_NAME_SIZEMAX \ - (FSP_FSCTL_VOLUME_NAME_SIZE + FSP_FSCTL_VOLUME_PREFIX_SIZE) -FSP_FSCTL_STATIC_ASSERT(FSP_FSCTL_VOLUME_NAME_SIZEMAX <= 260 * sizeof(WCHAR), - "Max volume name size is greater than MAX_PATH."); - -#define FSP_FSCTL_TRANSACT_PATH_SIZEMAX (1024 * sizeof(WCHAR)) - -#define FSP_FSCTL_TRANSACT_REQ_SIZEMAX \ - (16 * 1024 - 64) /* 64: size for internal request header */ -#define FSP_FSCTL_TRANSACT_RSP_SIZEMAX (16 * 1024) -#define FSP_FSCTL_TRANSACT_REQ_BUFFER_SIZEMAX \ - (FSP_FSCTL_TRANSACT_REQ_SIZEMAX - sizeof(FSP_FSCTL_TRANSACT_REQ)) -#define FSP_FSCTL_TRANSACT_RSP_BUFFER_SIZEMAX \ - (FSP_FSCTL_TRANSACT_RSP_SIZEMAX - sizeof(FSP_FSCTL_TRANSACT_RSP)) -#define FSP_FSCTL_TRANSACT_BATCH_BUFFER_SIZEMIN (64 * 1024) -#define FSP_FSCTL_TRANSACT_BUFFER_SIZEMIN FSP_FSCTL_TRANSACT_REQ_SIZEMAX - -#define FSP_FSCTL_TRANSACT_REQ_TOKEN_HANDLE(T) \ - ((HANDLE)((UINT_PTR)((T) & 0xffffffff))) -#define FSP_FSCTL_TRANSACT_REQ_TOKEN_PID(T) ((UINT32)(((T) >> 32) & 0xffffffff)) - -#define FSP_FSCTL_DEVICECONTROL_SIZEMAX \ - (4 * 1024) /* must be < FSP_FSCTL_TRANSACT_{REQ,RSP}_SIZEMAX */ - -/* marshalling */ -#pragma warning(push) -#pragma warning(disable : 4200 4201) /* zero-sized array in struct/union; \ - nameless struct/union */ -enum { - FspFsctlTransactReservedKind = 0, - FspFsctlTransactCreateKind, - FspFsctlTransactOverwriteKind, - FspFsctlTransactCleanupKind, - FspFsctlTransactCloseKind, - FspFsctlTransactReadKind, - FspFsctlTransactWriteKind, - FspFsctlTransactQueryInformationKind, - FspFsctlTransactSetInformationKind, - FspFsctlTransactQueryEaKind, - FspFsctlTransactSetEaKind, - FspFsctlTransactFlushBuffersKind, - FspFsctlTransactQueryVolumeInformationKind, - FspFsctlTransactSetVolumeInformationKind, - FspFsctlTransactQueryDirectoryKind, - FspFsctlTransactFileSystemControlKind, - FspFsctlTransactDeviceControlKind, - FspFsctlTransactShutdownKind, - FspFsctlTransactLockControlKind, - FspFsctlTransactQuerySecurityKind, - FspFsctlTransactSetSecurityKind, - FspFsctlTransactQueryStreamInformationKind, - FspFsctlTransactKindCount, -}; -enum { - FspFsctlTransactTimeoutMinimum = 1000, - FspFsctlTransactTimeoutMaximum = 10000, - FspFsctlTransactTimeoutDefault = - 1000, /* DEPRECATED: default is unspecified */ - FspFsctlIrpTimeoutMinimum = 60000, - FspFsctlIrpTimeoutMaximum = 600000, - FspFsctlIrpTimeoutDefault = 300000, - FspFsctlIrpTimeoutDebug = 142, /* special value for IRP timeout testing */ - FspFsctlIrpCapacityMinimum = 100, - FspFsctlIrpCapacityMaximum = 1000, - FspFsctlIrpCapacityDefault = 1000, -}; -#define FSP_FSCTL_VOLUME_PARAMS_V0_FIELD_DEFN \ - UINT16 Version; /* set to 0 or sizeof(FSP_FSCTL_VOLUME_PARAMS) */ \ - /* volume information */ \ - UINT16 SectorSize; \ - UINT16 SectorsPerAllocationUnit; \ - UINT16 MaxComponentLength; /* maximum file name component length (bytes) */ \ - UINT64 VolumeCreationTime; \ - UINT32 VolumeSerialNumber; \ - /* I/O timeouts, capacity, etc. */ \ - UINT32 TransactTimeout; /* DEPRECATED: (millis; 1 sec - 10 sec) */ \ - UINT32 IrpTimeout; /* pending IRP timeout (millis; 1 min - 10 min) */ \ - UINT32 IrpCapacity; /* maximum number of pending IRP's (100 - 1000)*/ \ - UINT32 FileInfoTimeout; /* FileInfo/Security/VolumeInfo timeout (millis) */ \ - /* FILE_FS_ATTRIBUTE_INFORMATION::FileSystemAttributes */ \ - UINT32 CaseSensitiveSearch : 1; /* file system supports case-sensitive file \ - names */ \ - UINT32 CasePreservedNames : 1; /* file system preserves the case of file \ - names */ \ - UINT32 UnicodeOnDisk : 1; /* file system supports Unicode in file names */ \ - UINT32 PersistentAcls : 1; /* file system preserves and enforces access \ - control lists */ \ - UINT32 ReparsePoints : 1; /* file system supports reparse points */ \ - UINT32 ReparsePointsAccessCheck : 1; /* file system performs reparse point \ - access checks */ \ - UINT32 NamedStreams : 1; /* file system supports named streams */ \ - UINT32 HardLinks : 1; /* unimplemented; set to 0 */ \ - UINT32 \ - ExtendedAttributes: \ - 1; /* file system supports extended attributes */ \ - UINT32 ReadOnlyVolume : 1; \ - /* kernel-mode flags */ \ - UINT32 PostCleanupWhenModifiedOnly : 1; /* post Cleanup when a file was \ - modified/deleted */ \ - UINT32 PassQueryDirectoryPattern : 1; /* pass Pattern during QueryDirectory \ - operations */ \ - UINT32 AlwaysUseDoubleBuffering : 1; \ - UINT32 \ - PassQueryDirectoryFileName: \ - 1; /* pass FileName during QueryDirectory \ - (GetDirInfoByName) */ \ - UINT32 FlushAndPurgeOnCleanup : 1; /* keeps file off "standby" list */ \ - UINT32 DeviceControl : 1; /* support user-mode ioctl handling */ \ - /* user-mode flags */ \ - UINT32 UmFileContextIsUserContext2 : 1; /* user mode: FileContext parameter \ - is UserContext2 */ \ - UINT32 UmFileContextIsFullContext : 1; /* user mode: FileContext parameter \ - is FullContext */ \ - UINT32 UmNoReparsePointsDirCheck : 1; /* user mode: no dir option check for \ - reparse points */ \ - UINT32 UmReservedFlags : 5; \ - /* additional kernel-mode flags */ \ - UINT32 AllowOpenInKernelMode : 1; /* allow kernel mode to open files when \ - possible */ \ - UINT32 CasePreservedExtendedAttributes : 1; /* preserve case of EA (default \ - is UPPERCASE) */ \ - UINT32 WslFeatures : 1; /* support features required for WSLinux */ \ - UINT32 DirectoryMarkerAsNextOffset : 1; /* directory marker is next offset \ - instead of last name */ \ - UINT32 RejectIrpPriorToTransact0 : 1; /* DEPRECATED: reject IRP's prior to \ - FspFsctlTransact0 */ \ - UINT32 SupportsPosixUnlinkRename : 1; /* file system supports POSIX-style \ - unlink and rename */ \ - UINT32 PostDispositionWhenNecessaryOnly : 1; /* post Disposition for dirs or \ - READONLY attr check */ \ - UINT32 KmReservedFlags : 1; \ - WCHAR Prefix[FSP_FSCTL_VOLUME_PREFIX_SIZE / \ - sizeof(WCHAR)]; /* UNC prefix (\Server\Share) */ \ - WCHAR FileSystemName[FSP_FSCTL_VOLUME_FSNAME_SIZE / sizeof(WCHAR)]; -#define FSP_FSCTL_VOLUME_PARAMS_V1_FIELD_DEFN \ - /* additional fields; specify .Version == sizeof(FSP_FSCTL_VOLUME_PARAMS) */ \ - UINT32 VolumeInfoTimeoutValid : 1; /* VolumeInfoTimeout field is valid */ \ - UINT32 DirInfoTimeoutValid : 1; /* DirInfoTimeout field is valid */ \ - UINT32 SecurityTimeoutValid : 1; /* SecurityTimeout field is valid*/ \ - UINT32 StreamInfoTimeoutValid : 1; /* StreamInfoTimeout field is valid */ \ - UINT32 EaTimeoutValid : 1; /* EaTimeout field is valid */ \ - UINT32 KmAdditionalReservedFlags : 27; \ - UINT32 VolumeInfoTimeout; /* volume info timeout (millis); overrides \ - FileInfoTimeout */ \ - UINT32 DirInfoTimeout; /* dir info timeout (millis); overrides \ - FileInfoTimeout */ \ - UINT32 SecurityTimeout; /* security info timeout (millis); overrides \ - FileInfoTimeout */ \ - UINT32 StreamInfoTimeout; /* stream info timeout (millis); overrides \ - FileInfoTimeout */ \ - UINT32 EaTimeout; /* EA timeout (millis); overrides FileInfoTimeout */ \ - UINT32 FsextControlCode; \ - UINT32 Reserved32[1]; \ - UINT64 Reserved64[2]; -typedef struct { - FSP_FSCTL_VOLUME_PARAMS_V0_FIELD_DEFN -} FSP_FSCTL_VOLUME_PARAMS_V0; -FSP_FSCTL_STATIC_ASSERT( - 456 == sizeof(FSP_FSCTL_VOLUME_PARAMS_V0), - "sizeof(FSP_FSCTL_VOLUME_PARAMS_V0) must be exactly 456."); -typedef struct { - FSP_FSCTL_VOLUME_PARAMS_V0_FIELD_DEFN - FSP_FSCTL_VOLUME_PARAMS_V1_FIELD_DEFN -} FSP_FSCTL_VOLUME_PARAMS; -FSP_FSCTL_STATIC_ASSERT(504 == sizeof(FSP_FSCTL_VOLUME_PARAMS), - "sizeof(FSP_FSCTL_VOLUME_PARAMS) is currently 504. " - "Update this assertion check if it changes."); -typedef struct { - UINT64 TotalSize; - UINT64 FreeSize; - UINT16 VolumeLabelLength; - WCHAR VolumeLabel[32]; -} FSP_FSCTL_VOLUME_INFO; -FSP_FSCTL_STATIC_ASSERT(88 == sizeof(FSP_FSCTL_VOLUME_INFO), - "sizeof(FSP_FSCTL_VOLUME_INFO) must be exactly 88."); -typedef struct { - UINT32 FileAttributes; - UINT32 ReparseTag; - UINT64 AllocationSize; - UINT64 FileSize; - UINT64 CreationTime; - UINT64 LastAccessTime; - UINT64 LastWriteTime; - UINT64 ChangeTime; - UINT64 IndexNumber; - UINT32 HardLinks; /* unimplemented: set to 0 */ - UINT32 EaSize; -} FSP_FSCTL_FILE_INFO; -FSP_FSCTL_STATIC_ASSERT(72 == sizeof(FSP_FSCTL_FILE_INFO), - "sizeof(FSP_FSCTL_FILE_INFO) must be exactly 72."); -typedef struct { - FSP_FSCTL_FILE_INFO FileInfo; - PWSTR NormalizedName; - UINT16 NormalizedNameSize; -} FSP_FSCTL_OPEN_FILE_INFO; -typedef struct { - UINT16 Size; - FSP_FSCTL_FILE_INFO FileInfo; - union { - UINT64 NextOffset; - UINT8 Padding[24]; - /* make struct as big as FILE_ID_BOTH_DIR_INFORMATION; allows for in-place - * copying */ - } DUMMYUNIONNAME; - WCHAR FileNameBuf[]; -} FSP_FSCTL_DIR_INFO; -FSP_FSCTL_STATIC_ASSERT(104 == sizeof(FSP_FSCTL_DIR_INFO), - "sizeof(FSP_FSCTL_DIR_INFO) must be exactly 104."); -typedef struct { - UINT16 Size; - UINT64 StreamSize; - UINT64 StreamAllocationSize; - WCHAR StreamNameBuf[]; -} FSP_FSCTL_STREAM_INFO; -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; -} FSP_FSCTL_TRANSACT_FULL_CONTEXT; -typedef struct { - UINT16 Offset; - UINT16 Size; -} FSP_FSCTL_TRANSACT_BUF; -typedef struct { - UINT16 Version; - UINT16 Size; - UINT32 Kind; - UINT64 Hint; - union { - struct { - UINT32 CreateOptions; /* Disposition: high 8 bits; Options: low 24 bits */ - UINT32 FileAttributes; /* file attributes for new files */ - FSP_FSCTL_TRANSACT_BUF - SecurityDescriptor; /* security descriptor for new files */ - UINT64 AllocationSize; /* initial allocation size */ - UINT64 AccessToken; /* request access token (PID,HANDLE) */ - UINT32 DesiredAccess; /* FILE_{READ_DATA,WRITE_DATA,etc.} */ - UINT32 GrantedAccess; /* FILE_{READ_DATA,WRITE_DATA,etc.} */ - UINT32 ShareAccess; /* FILE_SHARE_{READ,WRITE,DELETE} */ - FSP_FSCTL_TRANSACT_BUF - Ea; /* extended attributes or reparse point buffer */ - UINT32 UserMode : 1; /* request originated in user mode */ - UINT32 HasTraversePrivilege : 1; /* requestor has - TOKEN_HAS_TRAVERSE_PRIVILEGE */ - UINT32 - HasBackupPrivilege : 1; /* requestor has TOKEN_HAS_BACKUP_PRIVILEGE */ - UINT32 HasRestorePrivilege : 1; /* requestor has - TOKEN_HAS_RESTORE_PRIVILEGE */ - UINT32 OpenTargetDirectory : 1; /* open target dir and report - FILE_{EXISTS,DOES_NOT_EXIST} */ - UINT32 - CaseSensitive : 1; /* FileName comparisons should be case-sensitive */ - UINT32 HasTrailingBackslash : 1; /* FileName had trailing backslash */ - UINT32 AcceptsSecurityDescriptor : 1; - UINT32 EaIsReparsePoint : 1; /* Ea buffer is reparse point */ - UINT32 ReservedFlags : 24; - UINT16 NamedStream; /* request targets named stream; colon offset in - FileName */ - } Create; - struct { - UINT64 UserContext; - UINT64 UserContext2; - UINT32 - FileAttributes; /* file attributes for overwritten/superseded files */ - UINT64 - AllocationSize; /* allocation size for overwritten/superseded files */ - UINT32 Supersede : 1; /* 0: FILE_OVERWRITE operation, 1: FILE_SUPERSEDE - operation */ - FSP_FSCTL_TRANSACT_BUF Ea; /* extended attributes buffer */ - } Overwrite; - struct { - UINT64 UserContext; - UINT64 UserContext2; - UINT32 Delete : 1; /* file must be deleted */ - UINT32 SetAllocationSize : 1; - UINT32 SetArchiveBit : 1; - UINT32 SetLastAccessTime : 1; - UINT32 SetLastWriteTime : 1; - UINT32 SetChangeTime : 1; - } Cleanup; - struct { - UINT64 UserContext; - UINT64 UserContext2; - } Close; - struct { - UINT64 UserContext; - UINT64 UserContext2; - UINT64 Address; - UINT64 Offset; - UINT32 Length; - UINT32 Key; - } Read; - struct { - UINT64 UserContext; - UINT64 UserContext2; - UINT64 Address; - UINT64 Offset; - UINT32 Length; - UINT32 Key; - UINT32 ConstrainedIo : 1; - } Write; - struct { - UINT64 UserContext; - UINT64 UserContext2; - } QueryInformation; - struct { - UINT64 UserContext; - UINT64 UserContext2; - UINT32 FileInformationClass; - union { - struct { - UINT64 AllocationSize; - } Allocation; - struct { - UINT32 FileAttributes; - UINT64 CreationTime; - UINT64 LastAccessTime; - UINT64 LastWriteTime; - UINT64 ChangeTime; - } Basic; - struct { - UINT32 Delete : 1; - } Disposition; - struct { - UINT32 Flags; - } DispositionEx; - struct { - UINT64 FileSize; - } EndOfFile; - struct { - FSP_FSCTL_TRANSACT_BUF NewFileName; - UINT64 AccessToken; /* request access token (PID,HANDLE) */ - } Rename; - struct { - FSP_FSCTL_TRANSACT_BUF NewFileName; - UINT64 AccessToken; /* request access token (PID,HANDLE) */ - UINT32 Flags; - } RenameEx; - } Info; - } SetInformation; - struct { - UINT64 UserContext; - UINT64 UserContext2; - } QueryEa; - struct { - UINT64 UserContext; - UINT64 UserContext2; - FSP_FSCTL_TRANSACT_BUF Ea; - } SetEa; - struct { - UINT64 UserContext; - UINT64 UserContext2; - } FlushBuffers; - struct { - UINT32 FsInformationClass; - union { - struct { - FSP_FSCTL_TRANSACT_BUF VolumeLabel; - } Label; - } Info; - } SetVolumeInformation; - struct { - UINT64 UserContext; - UINT64 UserContext2; - UINT64 Address; - UINT32 Length; - FSP_FSCTL_TRANSACT_BUF Pattern; - FSP_FSCTL_TRANSACT_BUF Marker; - UINT32 - CaseSensitive : 1; /* FileName comparisons should be case-sensitive */ - UINT32 PatternIsFileName : 1; /* Pattern does not contain wildcards */ - } QueryDirectory; - struct { - UINT64 UserContext; - UINT64 UserContext2; - UINT32 FsControlCode; - FSP_FSCTL_TRANSACT_BUF Buffer; - UINT16 TargetOnFileSystem; /* the target of the symbolic link is on this - file system */ - } FileSystemControl; - struct { - UINT64 UserContext; - UINT64 UserContext2; - UINT32 IoControlCode; - FSP_FSCTL_TRANSACT_BUF Buffer; - UINT32 OutputLength; - } DeviceControl; - struct { - UINT64 UserContext; - UINT64 UserContext2; - } QuerySecurity; - struct { - UINT64 UserContext; - UINT64 UserContext2; - UINT32 SecurityInformation; - FSP_FSCTL_TRANSACT_BUF SecurityDescriptor; - } SetSecurity; - struct { - UINT64 UserContext; - UINT64 UserContext2; - } QueryStreamInformation; - } Req; - FSP_FSCTL_TRANSACT_BUF FileName; - /* Create,Cleanup,SetInformation{Disposition,Rename},FileSystemControl{ReparsePoint} - */ - FSP_FSCTL_DECLSPEC_ALIGN UINT8 Buffer[]; -} FSP_FSCTL_TRANSACT_REQ; -typedef struct { - UINT16 Version; - UINT16 Size; - UINT32 Kind; - UINT64 Hint; - struct { - UINT32 Information; - UINT32 Status; - } IoStatus; - union { - union { - /* IoStatus.Status == STATUS_SUCCESS */ - struct { - UINT64 UserContext; /* user context associated with file node */ - UINT64 UserContext2; /* user context associated with file descriptor - (handle) */ - UINT32 GrantedAccess; /* FILE_{READ_DATA,WRITE_DATA,etc.} */ - FSP_FSCTL_TRANSACT_BUF SecurityDescriptor; - FSP_FSCTL_FILE_INFO FileInfo; - FSP_FSCTL_TRANSACT_BUF FileName; - UINT32 DisableCache : 1; - UINT32 HasSecurityDescriptor : 1; - } Opened; - /* IoStatus.Status == STATUS_REPARSE */ - struct { - FSP_FSCTL_TRANSACT_BUF Buffer; - } Reparse; - } Create; - struct { - FSP_FSCTL_FILE_INFO FileInfo; - } Overwrite; - struct { - FSP_FSCTL_FILE_INFO FileInfo; - } Write; - struct { - FSP_FSCTL_FILE_INFO FileInfo; - } QueryInformation; - struct { - FSP_FSCTL_FILE_INFO - FileInfo; /* valid: File{Allocation,Basic,EndOfFile}Information */ - } SetInformation; - struct { - FSP_FSCTL_TRANSACT_BUF Ea; - } QueryEa; - struct { - FSP_FSCTL_FILE_INFO FileInfo; - FSP_FSCTL_TRANSACT_BUF - Ea; /* Size==0 means no extended atttributed returned */ - } SetEa; - struct { - FSP_FSCTL_FILE_INFO FileInfo; /* valid when flushing file (not volume) */ - } FlushBuffers; - struct { - FSP_FSCTL_VOLUME_INFO VolumeInfo; - } QueryVolumeInformation; - struct { - FSP_FSCTL_VOLUME_INFO VolumeInfo; - } SetVolumeInformation; - struct { - FSP_FSCTL_TRANSACT_BUF Buffer; - } FileSystemControl; - struct { - FSP_FSCTL_TRANSACT_BUF Buffer; - } DeviceControl; - struct { - FSP_FSCTL_TRANSACT_BUF SecurityDescriptor; - } QuerySecurity; - struct { - FSP_FSCTL_TRANSACT_BUF SecurityDescriptor; /* Size==0 means no security - descriptor returned */ - } SetSecurity; - struct { - FSP_FSCTL_TRANSACT_BUF Buffer; - } QueryStreamInformation; - } Rsp; - FSP_FSCTL_DECLSPEC_ALIGN UINT8 Buffer[]; -} FSP_FSCTL_TRANSACT_RSP; -#pragma warning(pop) -FSP_FSCTL_STATIC_ASSERT(FSP_FSCTL_TRANSACT_RSP_BUFFER_SIZEMAX > - FSP_FSCTL_TRANSACT_PATH_SIZEMAX, - "FSP_FSCTL_TRANSACT_RSP_BUFFER_SIZEMAX must be greater " - "than FSP_FSCTL_TRANSACT_PATH_SIZEMAX " - "to detect when a normalized name has been set during " - "a Create/Open request."); -static inline BOOLEAN -FspFsctlTransactCanProduceRequest(FSP_FSCTL_TRANSACT_REQ *Request, - PVOID RequestBufEnd) { - return (PUINT8)Request + FSP_FSCTL_TRANSACT_REQ_SIZEMAX <= - (PUINT8)RequestBufEnd; -} -static inline FSP_FSCTL_TRANSACT_REQ * -FspFsctlTransactProduceRequest(FSP_FSCTL_TRANSACT_REQ *Request, - SIZE_T RequestSize) { - PVOID NextRequest = (PUINT8)Request + FSP_FSCTL_DEFAULT_ALIGN_UP(RequestSize); - return (FSP_FSCTL_TRANSACT_REQ *)NextRequest; -} -static inline FSP_FSCTL_TRANSACT_REQ * -FspFsctlTransactConsumeRequest(FSP_FSCTL_TRANSACT_REQ *Request, - PVOID RequestBufEnd) { - if ((PUINT8)Request + sizeof(Request->Size) > (PUINT8)RequestBufEnd || - sizeof(FSP_FSCTL_TRANSACT_REQ) > Request->Size) - return 0; - PVOID NextRequest = - (PUINT8)Request + FSP_FSCTL_DEFAULT_ALIGN_UP(Request->Size); - return NextRequest <= RequestBufEnd ? (FSP_FSCTL_TRANSACT_REQ *)NextRequest - : 0; -} -static inline BOOLEAN -FspFsctlTransactCanProduceResponse(FSP_FSCTL_TRANSACT_RSP *Response, - PVOID ResponseBufEnd) { - return (PUINT8)Response + FSP_FSCTL_TRANSACT_RSP_SIZEMAX <= - (PUINT8)ResponseBufEnd; -} -static inline FSP_FSCTL_TRANSACT_RSP * -FspFsctlTransactProduceResponse(FSP_FSCTL_TRANSACT_RSP *Response, - SIZE_T ResponseSize) { - PVOID NextResponse = - (PUINT8)Response + FSP_FSCTL_DEFAULT_ALIGN_UP(ResponseSize); - return (FSP_FSCTL_TRANSACT_RSP *)NextResponse; -} -static inline FSP_FSCTL_TRANSACT_RSP * -FspFsctlTransactConsumeResponse(FSP_FSCTL_TRANSACT_RSP *Response, - PVOID ResponseBufEnd) { - if ((PUINT8)Response + sizeof(Response->Size) > (PUINT8)ResponseBufEnd || - sizeof(FSP_FSCTL_TRANSACT_RSP) > Response->Size) - return 0; - PVOID NextResponse = - (PUINT8)Response + FSP_FSCTL_DEFAULT_ALIGN_UP(Response->Size); - return NextResponse <= ResponseBufEnd ? (FSP_FSCTL_TRANSACT_RSP *)NextResponse - : 0; -} - -#if !defined(_KERNEL_MODE) -FSP_API NTSTATUS FspFsctlCreateVolume( - PWSTR DevicePath, const FSP_FSCTL_VOLUME_PARAMS *VolumeParams, - PWCHAR VolumeNameBuf, SIZE_T VolumeNameSize, PHANDLE PVolumeHandle); -FSP_API NTSTATUS FspFsctlMakeMountdev(HANDLE VolumeHandle, BOOLEAN Persistent, - GUID *UniqueId); -FSP_API NTSTATUS FspFsctlUseMountmgr(HANDLE VolumeHandle, PWSTR MountPoint); -FSP_API NTSTATUS FspFsctlTransact(HANDLE VolumeHandle, PVOID ResponseBuf, - SIZE_T ResponseBufSize, PVOID RequestBuf, - SIZE_T *PRequestBufSize, BOOLEAN Batch); -FSP_API NTSTATUS FspFsctlStop(HANDLE VolumeHandle); -FSP_API NTSTATUS FspFsctlStop0(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); -FSP_API NTSTATUS FspFsctlStartService(VOID); -FSP_API NTSTATUS FspFsctlStopService(VOID); -FSP_API NTSTATUS FspFsctlEnumServices(VOID (*EnumFn)(PVOID Context, - PWSTR ServiceName, - BOOLEAN Running), - PVOID Context); - -typedef struct { - /* in */ - HANDLE VolumeHandle; /* volume handle returned by FspFsctlCreateVolume */ - PWSTR VolumeName; /* volume name returned by FspFsctlCreateVolume */ - PSECURITY_DESCRIPTOR - Security; /* optional: security descriptor for directories */ - UINT64 Reserved; /* reserved for future use */ - /* in/out */ - PWSTR MountPoint; /* FspMountSet sets drive in buffer when passed "*:" */ - HANDLE MountHandle; /* FspMountSet sets, FspMountRemove uses */ -} FSP_MOUNT_DESC; -FSP_API NTSTATUS FspMountSet(FSP_MOUNT_DESC *Desc); -FSP_API NTSTATUS FspMountRemove(FSP_MOUNT_DESC *Desc); -#endif - -/* - * Atomics - * - * See https://www.cl.cam.ac.uk/~pes20/cpp/cpp0xmappings.html - * (https://archive.is/mJfFX) - */ -#if _MSC_VER >= 1920 /* VS2019 or later */ -__int32 __iso_volatile_load32(const volatile __int32 *); -void __iso_volatile_store32(volatile __int32 *, __int32); -__int64 __iso_volatile_load64(const volatile __int64 *); -void __iso_volatile_store64(volatile __int64 *, __int64); -#define FSP_INTERLOCKED__LOAD32(p) __iso_volatile_load32(p) -#define FSP_INTERLOCKED__STORE32(p, v) __iso_volatile_store32(p, v) -#define FSP_INTERLOCKED__LOAD64(p) __iso_volatile_load64(p) -#define FSP_INTERLOCKED__STORE64(p, v) __iso_volatile_store64(p, v) -#else -#define FSP_INTERLOCKED__LOAD32(p) (*(p)) -#define FSP_INTERLOCKED__STORE32(p, v) (*(p) = (v)) -#define FSP_INTERLOCKED__LOAD64(p) (*(p)) -#define FSP_INTERLOCKED__STORE64(p, v) (*(p) = (v)) -#endif -static inline INT32 FspInterlockedLoad32(INT32 volatile *p) { -#if defined(_M_ARM64) - void __dmb(unsigned int); - INT32 v = FSP_INTERLOCKED__LOAD32(p); - __dmb(0xb); - return v; - -#elif defined(_M_X64) || defined(_M_IX86) -#ifndef _ReadWriteBarrier - void _ReadWriteBarrier(void); -#endif - INT32 v = FSP_INTERLOCKED__LOAD32(p); - _ReadWriteBarrier(); - return v; - -#endif -} -static inline VOID FspInterlockedStore32(INT32 volatile *p, INT32 v) { -#if defined(_M_ARM64) - void __dmb(unsigned int); - __dmb(0xb); - FSP_INTERLOCKED__STORE32(p, v); - __dmb(0xb); - -#elif defined(_M_X64) || defined(_M_IX86) - long _InterlockedExchange(long volatile *, long); - _InterlockedExchange((long volatile *)p, v); - -#endif -} -static inline VOID *FspInterlockedLoadPointer(VOID *volatile *p) { -#if defined(_M_ARM64) - void __dmb(unsigned int); - VOID *v = (VOID *)FSP_INTERLOCKED__LOAD64((__int64 volatile *)(p)); - __dmb(0xb); - return v; - -#elif defined(_M_X64) -#ifndef _ReadWriteBarrier - void _ReadWriteBarrier(void); -#endif - VOID *v = (VOID *)FSP_INTERLOCKED__LOAD64((__int64 volatile *)(p)); - _ReadWriteBarrier(); - return v; - -#elif defined(_M_IX86) -#ifndef _ReadWriteBarrier - void _ReadWriteBarrier(void); -#endif - VOID *v = (VOID *)FSP_INTERLOCKED__LOAD32((__int32 volatile *)(p)); - _ReadWriteBarrier(); - return v; - -#endif -} -static inline VOID FspInterlockedStorePointer(VOID *volatile *p, VOID *v) { -#if defined(_M_ARM64) - void __dmb(unsigned int); - __dmb(0xb); - FSP_INTERLOCKED__STORE64((__int64 volatile *)(p), (__int64)(v)); - __dmb(0xb); - -#elif defined(_M_X64) || defined(_M_IX86) - void *_InterlockedExchangePointer(void *volatile *, void *); - _InterlockedExchangePointer(p, v); - -#endif -} - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/support/3rd_party/winfsp-2.0/inc/winfsp/winfsp.hpp b/support/3rd_party/winfsp-2.0/inc/winfsp/winfsp.hpp deleted file mode 100644 index eb17aee6..00000000 --- a/support/3rd_party/winfsp-2.0/inc/winfsp/winfsp.hpp +++ /dev/null @@ -1,902 +0,0 @@ -/** - * @file winfsp/winfsp.hpp - * WinFsp C++ Layer. - * - * @copyright 2015-2022 Bill Zissimopoulos - */ -/* - * This file is part of WinFsp. - * - * You can redistribute it and/or modify it under the terms of the GNU - * General Public License version 3 as published by the Free Software - * Foundation. - * - * Licensees holding a valid commercial license may use this software - * in accordance with the commercial license agreement provided in - * conjunction with the software. The terms and conditions of any such - * commercial license agreement shall govern, supersede, and render - * ineffective any application of the GPLv3 license to this software, - * notwithstanding of any reference thereto in the software or - * associated repository. - */ - -#ifndef WINFSP_WINFSP_HPP_INCLUDED -#define WINFSP_WINFSP_HPP_INCLUDED - -#ifndef __cplusplus -#error this header requires a C++ compiler -#endif - -#include - -#define FSP_CPP_EXCEPTION_GUARD(...) \ - try { \ - __VA_ARGS__ \ - } catch (...) { \ - return self->ExceptionHandler(); \ - } -#define FSP_CPP_EXCEPTION_GUARD_VOID(...) \ - try { \ - __VA_ARGS__ \ - } catch (...) { \ - self->ExceptionHandler(); \ - return; \ - } - -namespace Fsp { - -inline NTSTATUS Initialize() { - static NTSTATUS LoadResult = FspLoad(0); - return LoadResult; -} - -class FileSystemBase { -public: - typedef FSP_FSCTL_VOLUME_INFO VolumeInfo; - typedef FSP_FSCTL_FILE_INFO FileInfo; - typedef FSP_FSCTL_OPEN_FILE_INFO OpenFileInfo; - typedef FSP_FSCTL_DIR_INFO DirInfo; - typedef FSP_FSCTL_STREAM_INFO StreamInfo; - enum CleanupFlags { - CleanupDelete = FspCleanupDelete, - CleanupSetAllocationSize = FspCleanupSetAllocationSize, - CleanupSetArchiveBit = FspCleanupSetArchiveBit, - CleanupSetLastAccessTime = FspCleanupSetLastAccessTime, - CleanupSetLastWriteTime = FspCleanupSetLastWriteTime, - CleanupSetChangeTime = FspCleanupSetChangeTime, - }; - -public: - FileSystemBase() {} - virtual ~FileSystemBase() {} - - /* operations */ - virtual NTSTATUS ExceptionHandler() { return STATUS_UNEXPECTED_IO_ERROR; } - virtual NTSTATUS Init(PVOID Host) { return STATUS_SUCCESS; } - virtual NTSTATUS Mounted(PVOID Host) { return STATUS_SUCCESS; } - virtual VOID Unmounted(PVOID Host) {} - virtual NTSTATUS GetVolumeInfo(VolumeInfo *VolumeInfo) { - return STATUS_INVALID_DEVICE_REQUEST; - } - virtual NTSTATUS SetVolumeLabel_(PWSTR VolumeLabel, VolumeInfo *VolumeInfo) { - return STATUS_INVALID_DEVICE_REQUEST; - } - virtual NTSTATUS - GetSecurityByName(PWSTR FileName, - PUINT32 PFileAttributes /* or ReparsePointIndex */, - PSECURITY_DESCRIPTOR SecurityDescriptor, - SIZE_T *PSecurityDescriptorSize) { - return STATUS_INVALID_DEVICE_REQUEST; - } - virtual NTSTATUS Create(PWSTR FileName, UINT32 CreateOptions, - UINT32 GrantedAccess, UINT32 FileAttributes, - PSECURITY_DESCRIPTOR SecurityDescriptor, - UINT64 AllocationSize, PVOID *PFileNode, - PVOID *PFileDesc, OpenFileInfo *OpenFileInfo) { - return STATUS_INVALID_DEVICE_REQUEST; - } - virtual NTSTATUS Open(PWSTR FileName, UINT32 CreateOptions, - UINT32 GrantedAccess, PVOID *PFileNode, - PVOID *PFileDesc, OpenFileInfo *OpenFileInfo) { - return STATUS_INVALID_DEVICE_REQUEST; - } - virtual NTSTATUS Overwrite(PVOID FileNode, PVOID FileDesc, - UINT32 FileAttributes, - BOOLEAN ReplaceFileAttributes, - UINT64 AllocationSize, FileInfo *FileInfo) { - return STATUS_INVALID_DEVICE_REQUEST; - } - virtual VOID Cleanup(PVOID FileNode, PVOID FileDesc, PWSTR FileName, - ULONG Flags) {} - virtual VOID Close(PVOID FileNode, PVOID FileDesc) {} - virtual NTSTATUS Read(PVOID FileNode, PVOID FileDesc, PVOID Buffer, - UINT64 Offset, ULONG Length, PULONG PBytesTransferred) { - return STATUS_INVALID_DEVICE_REQUEST; - } - virtual NTSTATUS Write(PVOID FileNode, PVOID FileDesc, PVOID Buffer, - UINT64 Offset, ULONG Length, BOOLEAN WriteToEndOfFile, - BOOLEAN ConstrainedIo, PULONG PBytesTransferred, - FileInfo *FileInfo) { - return STATUS_INVALID_DEVICE_REQUEST; - } - virtual NTSTATUS Flush(PVOID FileNode, PVOID FileDesc, FileInfo *FileInfo) { - return STATUS_INVALID_DEVICE_REQUEST; - } - virtual NTSTATUS GetFileInfo(PVOID FileNode, PVOID FileDesc, - FileInfo *FileInfo) { - return STATUS_INVALID_DEVICE_REQUEST; - } - virtual NTSTATUS SetBasicInfo(PVOID FileNode, PVOID FileDesc, - UINT32 FileAttributes, UINT64 CreationTime, - UINT64 LastAccessTime, UINT64 LastWriteTime, - UINT64 ChangeTime, FileInfo *FileInfo) { - return STATUS_INVALID_DEVICE_REQUEST; - } - virtual NTSTATUS SetFileSize(PVOID FileNode, PVOID FileDesc, UINT64 NewSize, - BOOLEAN SetAllocationSize, FileInfo *FileInfo) { - return STATUS_INVALID_DEVICE_REQUEST; - } - virtual NTSTATUS CanDelete(PVOID FileNode, PVOID FileDesc, PWSTR FileName) { - return STATUS_INVALID_DEVICE_REQUEST; - } - virtual NTSTATUS Rename(PVOID FileNode, PVOID FileDesc, PWSTR FileName, - PWSTR NewFileName, BOOLEAN ReplaceIfExists) { - return STATUS_INVALID_DEVICE_REQUEST; - } - virtual NTSTATUS GetSecurity(PVOID FileNode, PVOID FileDesc, - PSECURITY_DESCRIPTOR SecurityDescriptor, - SIZE_T *PSecurityDescriptorSize) { - return STATUS_INVALID_DEVICE_REQUEST; - } - virtual NTSTATUS SetSecurity(PVOID FileNode, PVOID FileDesc, - SECURITY_INFORMATION SecurityInformation, - PSECURITY_DESCRIPTOR ModificationDescriptor) { - return STATUS_INVALID_DEVICE_REQUEST; - } - virtual NTSTATUS ReadDirectory(PVOID FileNode, PVOID FileDesc, PWSTR Pattern, - PWSTR Marker, PVOID Buffer, ULONG Length, - PULONG PBytesTransferred) { - return SeekableReadDirectory(FileNode, FileDesc, Pattern, Marker, Buffer, - Length, PBytesTransferred); - } - virtual NTSTATUS ReadDirectoryEntry(PVOID FileNode, PVOID FileDesc, - PWSTR Pattern, PWSTR Marker, - PVOID *PContext, DirInfo *DirInfo) { - return STATUS_INVALID_DEVICE_REQUEST; - } - virtual NTSTATUS ResolveReparsePoints(PWSTR FileName, - UINT32 ReparsePointIndex, - BOOLEAN ResolveLastPathComponent, - PIO_STATUS_BLOCK PIoStatus, - PVOID Buffer, PSIZE_T PSize) { - return FspFileSystemResolveReparsePoints( - 0, GetReparsePointByName, this, FileName, ReparsePointIndex, - ResolveLastPathComponent, PIoStatus, Buffer, PSize); - } - virtual NTSTATUS GetReparsePointByName(PWSTR FileName, BOOLEAN IsDirectory, - PVOID Buffer, PSIZE_T PSize) { - return STATUS_INVALID_DEVICE_REQUEST; - } - virtual NTSTATUS GetReparsePoint(PVOID FileNode, PVOID FileDesc, - PWSTR FileName, PVOID Buffer, - PSIZE_T PSize) { - return STATUS_INVALID_DEVICE_REQUEST; - } - virtual NTSTATUS SetReparsePoint(PVOID FileNode, PVOID FileDesc, - PWSTR FileName, PVOID Buffer, SIZE_T Size) { - return STATUS_INVALID_DEVICE_REQUEST; - } - virtual NTSTATUS DeleteReparsePoint(PVOID FileNode, PVOID FileDesc, - PWSTR FileName, PVOID Buffer, - SIZE_T Size) { - return STATUS_INVALID_DEVICE_REQUEST; - } - virtual NTSTATUS GetStreamInfo(PVOID FileNode, PVOID FileDesc, PVOID Buffer, - ULONG Length, PULONG PBytesTransferred) { - return STATUS_INVALID_DEVICE_REQUEST; - } - - /* helpers */ - static NTSTATUS NtStatusFromWin32(DWORD Error) { - return FspNtStatusFromWin32(Error); - } - static DWORD Win32FromNtStatus(NTSTATUS Status) { - return FspWin32FromNtStatus(Status); - } - static VOID DeleteDirectoryBuffer(PVOID *PDirBuffer) { - FspFileSystemDeleteDirectoryBuffer(PDirBuffer); - } - NTSTATUS SeekableReadDirectory(PVOID FileNode, PVOID FileDesc, PWSTR Pattern, - PWSTR Marker, PVOID Buffer, ULONG Length, - PULONG PBytesTransferred) { - PVOID Context = 0; - union { - UINT8 B[FIELD_OFFSET(FileSystemBase::DirInfo, FileNameBuf) + - MAX_PATH * sizeof(WCHAR)]; - FileSystemBase::DirInfo D; - } DirInfoBuf; - FileSystemBase::DirInfo *DirInfo = &DirInfoBuf.D; - NTSTATUS Result = STATUS_SUCCESS; - *PBytesTransferred = 0; - for (;;) { - Result = ReadDirectoryEntry(FileNode, FileDesc, Pattern, Marker, &Context, - DirInfo); - if (STATUS_NO_MORE_FILES == Result) { - Result = STATUS_SUCCESS; - break; - } - if (!NT_SUCCESS(Result)) - break; - if (!FspFileSystemAddDirInfo(DirInfo, Buffer, Length, PBytesTransferred)) - break; - } - if (!NT_SUCCESS(Result)) - return Result; - return STATUS_SUCCESS; - } - NTSTATUS BufferedReadDirectory(PVOID *PDirBuffer, PVOID FileNode, - PVOID FileDesc, PWSTR Pattern, PWSTR Marker, - PVOID Buffer, ULONG Length, - PULONG PBytesTransferred) { - PVOID Context = 0; - union { - UINT8 B[FIELD_OFFSET(FileSystemBase::DirInfo, FileNameBuf) + - MAX_PATH * sizeof(WCHAR)]; - FileSystemBase::DirInfo D; - } DirInfoBuf; - FileSystemBase::DirInfo *DirInfo = &DirInfoBuf.D; - NTSTATUS Result = STATUS_SUCCESS; - *PBytesTransferred = 0; - if (FspFileSystemAcquireDirectoryBuffer(PDirBuffer, 0 == Marker, &Result)) { - try { - for (;;) { - Result = ReadDirectoryEntry(FileNode, FileDesc, Pattern, Marker, - &Context, DirInfo); - if (STATUS_NO_MORE_FILES == Result) { - Result = STATUS_SUCCESS; - break; - } - if (!NT_SUCCESS(Result)) - break; - if (!FspFileSystemFillDirectoryBuffer(PDirBuffer, DirInfo, &Result)) - break; - } - } catch (...) { - FspFileSystemReleaseDirectoryBuffer(PDirBuffer); - throw; - } - FspFileSystemReleaseDirectoryBuffer(PDirBuffer); - } - if (!NT_SUCCESS(Result)) - return Result; - FspFileSystemReadDirectoryBuffer(PDirBuffer, Marker, Buffer, Length, - PBytesTransferred); - return STATUS_SUCCESS; - } - BOOLEAN FindReparsePoint(PWSTR FileName, PUINT32 PReparsePointIndex) { - return FspFileSystemFindReparsePoint(0, GetReparsePointByName, this, - FileName, PReparsePointIndex); - } - static NTSTATUS CanReplaceReparsePoint(PVOID CurrentReparseData, - SIZE_T CurrentReparseDataSize, - PVOID ReplaceReparseData, - SIZE_T ReplaceReparseDataSize) { - return FspFileSystemCanReplaceReparsePoint( - CurrentReparseData, CurrentReparseDataSize, ReplaceReparseData, - ReplaceReparseDataSize); - } - static BOOLEAN AddStreamInfo(StreamInfo *StreamInfo, PVOID Buffer, - ULONG Length, PULONG PBytesTransferred) { - return FspFileSystemAddStreamInfo(StreamInfo, Buffer, Length, - PBytesTransferred); - } - -private: - static NTSTATUS GetReparsePointByName(FSP_FILE_SYSTEM *FileSystem, - PVOID Context, PWSTR FileName, - BOOLEAN IsDirectory, PVOID Buffer, - PSIZE_T PSize) { - FileSystemBase *self = (FileSystemBase *)Context; - FSP_CPP_EXCEPTION_GUARD(return self->GetReparsePointByName( - FileName, IsDirectory, Buffer, PSize);) - } - -private: - /* disallow copy and assignment */ - FileSystemBase(const FileSystemBase &); - FileSystemBase &operator=(const FileSystemBase &); -}; - -class FileSystemHost { -public: - /* ctor/dtor */ - FileSystemHost(FileSystemBase &FileSystem) - : _VolumeParams(), _FileSystemPtr(0), _FileSystem(&FileSystem) { - Initialize(); - _VolumeParams.UmFileContextIsFullContext = 1; - } - virtual ~FileSystemHost() { - if (0 != _FileSystemPtr) - FspFileSystemDelete(_FileSystemPtr); - } - - /* properties */ - UINT16 SectorSize() { return _VolumeParams.SectorSize; } - VOID SetSectorSize(UINT16 SectorSize) { - _VolumeParams.SectorSize = SectorSize; - } - UINT16 SectorsPerAllocationUnit() { - return _VolumeParams.SectorsPerAllocationUnit; - } - VOID SetSectorsPerAllocationUnit(UINT16 SectorsPerAllocationUnit) { - _VolumeParams.SectorsPerAllocationUnit = SectorsPerAllocationUnit; - } - UINT16 MaxComponentLength() { return _VolumeParams.MaxComponentLength; } - VOID SetMaxComponentLength(UINT16 MaxComponentLength) { - _VolumeParams.MaxComponentLength = MaxComponentLength; - } - UINT64 VolumeCreationTime() { return _VolumeParams.VolumeCreationTime; } - VOID SetVolumeCreationTime(UINT64 VolumeCreationTime) { - _VolumeParams.VolumeCreationTime = VolumeCreationTime; - } - UINT32 VolumeSerialNumber() { return _VolumeParams.VolumeSerialNumber; } - VOID SetVolumeSerialNumber(UINT32 VolumeSerialNumber) { - _VolumeParams.VolumeSerialNumber = VolumeSerialNumber; - } - UINT32 FileInfoTimeout() { return _VolumeParams.FileInfoTimeout; } - VOID SetFileInfoTimeout(UINT32 FileInfoTimeout) { - _VolumeParams.FileInfoTimeout = FileInfoTimeout; - } - BOOLEAN CaseSensitiveSearch() { return _VolumeParams.CaseSensitiveSearch; } - VOID SetCaseSensitiveSearch(BOOLEAN CaseSensitiveSearch) { - _VolumeParams.CaseSensitiveSearch = !!CaseSensitiveSearch; - } - BOOLEAN CasePreservedNames() { return _VolumeParams.CasePreservedNames; } - VOID SetCasePreservedNames(BOOLEAN CasePreservedNames) { - _VolumeParams.CasePreservedNames = !!CasePreservedNames; - } - BOOLEAN UnicodeOnDisk() { return _VolumeParams.UnicodeOnDisk; } - VOID SetUnicodeOnDisk(BOOLEAN UnicodeOnDisk) { - _VolumeParams.UnicodeOnDisk = !!UnicodeOnDisk; - } - BOOLEAN PersistentAcls() { return _VolumeParams.PersistentAcls; } - VOID SetPersistentAcls(BOOLEAN PersistentAcls) { - _VolumeParams.PersistentAcls = !!PersistentAcls; - } - BOOLEAN ReparsePoints() { return _VolumeParams.ReparsePoints; } - VOID SetReparsePoints(BOOLEAN ReparsePoints) { - _VolumeParams.ReparsePoints = !!ReparsePoints; - } - BOOLEAN ReparsePointsAccessCheck() { - return _VolumeParams.ReparsePointsAccessCheck; - } - VOID SetReparsePointsAccessCheck(BOOLEAN ReparsePointsAccessCheck) { - _VolumeParams.ReparsePointsAccessCheck = !!ReparsePointsAccessCheck; - } - BOOLEAN NamedStreams() { return _VolumeParams.NamedStreams; } - VOID SetNamedStreams(BOOLEAN NamedStreams) { - _VolumeParams.NamedStreams = !!NamedStreams; - } - BOOLEAN PostCleanupWhenModifiedOnly() { - return _VolumeParams.PostCleanupWhenModifiedOnly; - } - VOID SetPostCleanupWhenModifiedOnly(BOOLEAN PostCleanupWhenModifiedOnly) { - _VolumeParams.PostCleanupWhenModifiedOnly = !!PostCleanupWhenModifiedOnly; - } - BOOLEAN PassQueryDirectoryPattern() { - return _VolumeParams.PassQueryDirectoryPattern; - } - VOID SetPassQueryDirectoryPattern(BOOLEAN PassQueryDirectoryPattern) { - _VolumeParams.PassQueryDirectoryPattern = !!PassQueryDirectoryPattern; - } - BOOLEAN FlushAndPurgeOnCleanup() { - return _VolumeParams.FlushAndPurgeOnCleanup; - } - VOID SetFlushAndPurgeOnCleanup(BOOLEAN FlushAndPurgeOnCleanup) { - _VolumeParams.FlushAndPurgeOnCleanup = !!FlushAndPurgeOnCleanup; - } - PWSTR Prefix() { return _VolumeParams.Prefix; } - VOID SetPrefix(PWSTR Prefix) { - int Size = lstrlenW(Prefix) * sizeof(WCHAR); - if (Size > sizeof _VolumeParams.Prefix - sizeof(WCHAR)) - Size = sizeof _VolumeParams.Prefix - sizeof(WCHAR); - RtlCopyMemory(_VolumeParams.Prefix, Prefix, Size); - _VolumeParams.Prefix[Size / sizeof(WCHAR)] = L'\0'; - } - PWSTR FileSystemName() { return _VolumeParams.FileSystemName; } - VOID SetFileSystemName(PWSTR FileSystemName) { - int Size = lstrlenW(FileSystemName) * sizeof(WCHAR); - if (Size > sizeof _VolumeParams.FileSystemName - sizeof(WCHAR)) - Size = sizeof _VolumeParams.FileSystemName - sizeof(WCHAR); - RtlCopyMemory(_VolumeParams.FileSystemName, FileSystemName, Size); - _VolumeParams.FileSystemName[Size / sizeof(WCHAR)] = L'\0'; - } - - /* control */ - NTSTATUS Preflight(PWSTR MountPoint) { - return FspFileSystemPreflight((PWSTR)(_VolumeParams.Prefix[0] - ? L"" FSP_FSCTL_NET_DEVICE_NAME - : L"" FSP_FSCTL_DISK_DEVICE_NAME), - MountPoint); - } - NTSTATUS Mount(PWSTR MountPoint, PSECURITY_DESCRIPTOR SecurityDescriptor = 0, - BOOLEAN Synchronized = FALSE, UINT32 DebugLog = 0) { - NTSTATUS Result; - try { - Result = _FileSystem->Init(this); - } catch (...) { - Result = _FileSystem->ExceptionHandler(); - } - if (!NT_SUCCESS(Result)) - return Result; - Result = FspFileSystemCreate((PWSTR)(_VolumeParams.Prefix[0] - ? L"" FSP_FSCTL_NET_DEVICE_NAME - : L"" FSP_FSCTL_DISK_DEVICE_NAME), - &_VolumeParams, Interface(), &_FileSystemPtr); - if (!NT_SUCCESS(Result)) - return Result; - _FileSystemPtr->UserContext = _FileSystem; - FspFileSystemSetOperationGuardStrategy( - _FileSystemPtr, Synchronized - ? FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY_COARSE - : FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY_FINE); - FspFileSystemSetDebugLog(_FileSystemPtr, DebugLog); - Result = FspFileSystemSetMountPointEx(_FileSystemPtr, MountPoint, - SecurityDescriptor); - if (NT_SUCCESS(Result)) { - try { - Result = _FileSystem->Mounted(this); - } catch (...) { - Result = _FileSystem->ExceptionHandler(); - } - if (NT_SUCCESS(Result)) { - Result = FspFileSystemStartDispatcher(_FileSystemPtr, 0); - if (!NT_SUCCESS(Result)) - try { - _FileSystem->Unmounted(this); - } catch (...) { - _FileSystem->ExceptionHandler(); - } - } - } - if (!NT_SUCCESS(Result)) { - FspFileSystemDelete(_FileSystemPtr); - _FileSystemPtr = 0; - } - return Result; - } - VOID Unmount() { - FspFileSystemStopDispatcher(_FileSystemPtr); - try { - _FileSystem->Unmounted(this); - } catch (...) { - _FileSystem->ExceptionHandler(); - } - _FileSystemPtr->UserContext = 0; - FspFileSystemDelete(_FileSystemPtr); - _FileSystemPtr = 0; - } - PWSTR MountPoint() { - return 0 != _FileSystemPtr ? FspFileSystemMountPoint(_FileSystemPtr) : 0; - } - FSP_FILE_SYSTEM *FileSystemHandle() { return _FileSystemPtr; } - FileSystemBase &FileSystem() { return *_FileSystem; } - static NTSTATUS SetDebugLogFile(PWSTR FileName) { - HANDLE Handle; - if ('-' == FileName[0] && '\0' == FileName[1]) - Handle = GetStdHandle(STD_ERROR_HANDLE); - else - Handle = CreateFileW(FileName, FILE_APPEND_DATA, - FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_ALWAYS, - FILE_ATTRIBUTE_NORMAL, 0); - if (INVALID_HANDLE_VALUE == Handle) - return FspNtStatusFromWin32(GetLastError()); - FspDebugLogSetHandle(Handle); - return STATUS_SUCCESS; - } - -private: - /* FSP_FILE_SYSTEM_INTERFACE */ - static NTSTATUS GetVolumeInfo(FSP_FILE_SYSTEM *FileSystem0, - FSP_FSCTL_VOLUME_INFO *VolumeInfo) { - FileSystemBase *self = (FileSystemBase *)FileSystem0->UserContext; - FSP_CPP_EXCEPTION_GUARD(return self->GetVolumeInfo(VolumeInfo);) - } - static NTSTATUS SetVolumeLabel_(FSP_FILE_SYSTEM *FileSystem0, - PWSTR VolumeLabel, - FSP_FSCTL_VOLUME_INFO *VolumeInfo) { - FileSystemBase *self = (FileSystemBase *)FileSystem0->UserContext; - FSP_CPP_EXCEPTION_GUARD( - return self->SetVolumeLabel_(VolumeLabel, VolumeInfo);) - } - static NTSTATUS - GetSecurityByName(FSP_FILE_SYSTEM *FileSystem0, PWSTR FileName, - PUINT32 PFileAttributes /* or ReparsePointIndex */, - PSECURITY_DESCRIPTOR SecurityDescriptor, - SIZE_T *PSecurityDescriptorSize) { - FileSystemBase *self = (FileSystemBase *)FileSystem0->UserContext; - FSP_CPP_EXCEPTION_GUARD(return self->GetSecurityByName( - FileName, PFileAttributes, SecurityDescriptor, - PSecurityDescriptorSize);) - } - static NTSTATUS Create(FSP_FILE_SYSTEM *FileSystem0, PWSTR FileName, - UINT32 CreateOptions, UINT32 GrantedAccess, - UINT32 FileAttributes, - PSECURITY_DESCRIPTOR SecurityDescriptor, - UINT64 AllocationSize, PVOID *FullContext, - FSP_FSCTL_FILE_INFO *FileInfo) { - FileSystemBase *self = (FileSystemBase *)FileSystem0->UserContext; - PVOID FileNode, FileDesc; - NTSTATUS Result; - FSP_CPP_EXCEPTION_GUARD( - Result = - self->Create(FileName, CreateOptions, GrantedAccess, FileAttributes, - SecurityDescriptor, AllocationSize, &FileNode, - &FileDesc, FspFileSystemGetOpenFileInfo(FileInfo));) - ((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext = - (UINT64)(UINT_PTR)FileNode; - ((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2 = - (UINT64)(UINT_PTR)FileDesc; - return Result; - } - static NTSTATUS Open(FSP_FILE_SYSTEM *FileSystem0, PWSTR FileName, - UINT32 CreateOptions, UINT32 GrantedAccess, - PVOID *FullContext, FSP_FSCTL_FILE_INFO *FileInfo) { - FileSystemBase *self = (FileSystemBase *)FileSystem0->UserContext; - PVOID FileNode, FileDesc; - NTSTATUS Result; - FSP_CPP_EXCEPTION_GUARD( - Result = self->Open(FileName, CreateOptions, GrantedAccess, &FileNode, - &FileDesc, FspFileSystemGetOpenFileInfo(FileInfo));) - ((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext = - (UINT64)(UINT_PTR)FileNode; - ((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2 = - (UINT64)(UINT_PTR)FileDesc; - return Result; - } - static NTSTATUS Overwrite(FSP_FILE_SYSTEM *FileSystem0, PVOID FullContext, - UINT32 FileAttributes, - BOOLEAN ReplaceFileAttributes, - UINT64 AllocationSize, - FSP_FSCTL_FILE_INFO *FileInfo) { - FileSystemBase *self = (FileSystemBase *)FileSystem0->UserContext; - FSP_CPP_EXCEPTION_GUARD(return self->Overwrite( - (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext) - ->UserContext, - (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext) - ->UserContext2, - FileAttributes, ReplaceFileAttributes, AllocationSize, FileInfo);) - } - static VOID Cleanup(FSP_FILE_SYSTEM *FileSystem0, PVOID FullContext, - PWSTR FileName, ULONG Flags) { - FileSystemBase *self = (FileSystemBase *)FileSystem0->UserContext; - FSP_CPP_EXCEPTION_GUARD_VOID(return self->Cleanup( - (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext) - ->UserContext, - (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext) - ->UserContext2, - FileName, Flags);) - } - static VOID Close(FSP_FILE_SYSTEM *FileSystem0, PVOID FullContext) { - FileSystemBase *self = (FileSystemBase *)FileSystem0->UserContext; - FSP_CPP_EXCEPTION_GUARD_VOID(return self->Close( - (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext) - ->UserContext, - (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext) - ->UserContext2);) - } - static NTSTATUS Read(FSP_FILE_SYSTEM *FileSystem0, PVOID FullContext, - PVOID Buffer, UINT64 Offset, ULONG Length, - PULONG PBytesTransferred) { - FileSystemBase *self = (FileSystemBase *)FileSystem0->UserContext; - FSP_CPP_EXCEPTION_GUARD(return self->Read( - (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext) - ->UserContext, - (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext) - ->UserContext2, - Buffer, Offset, Length, PBytesTransferred);) - } - static NTSTATUS Write(FSP_FILE_SYSTEM *FileSystem0, PVOID FullContext, - PVOID Buffer, UINT64 Offset, ULONG Length, - BOOLEAN WriteToEndOfFile, BOOLEAN ConstrainedIo, - PULONG PBytesTransferred, - FSP_FSCTL_FILE_INFO *FileInfo) { - FileSystemBase *self = (FileSystemBase *)FileSystem0->UserContext; - FSP_CPP_EXCEPTION_GUARD(return self->Write( - (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext) - ->UserContext, - (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext) - ->UserContext2, - Buffer, Offset, Length, WriteToEndOfFile, ConstrainedIo, - PBytesTransferred, FileInfo);) - } - static NTSTATUS Flush(FSP_FILE_SYSTEM *FileSystem0, PVOID FullContext, - FSP_FSCTL_FILE_INFO *FileInfo) { - FileSystemBase *self = (FileSystemBase *)FileSystem0->UserContext; - FSP_CPP_EXCEPTION_GUARD(return self->Flush( - (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext) - ->UserContext, - (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext) - ->UserContext2, - FileInfo);) - } - static NTSTATUS GetFileInfo(FSP_FILE_SYSTEM *FileSystem0, PVOID FullContext, - FSP_FSCTL_FILE_INFO *FileInfo) { - FileSystemBase *self = (FileSystemBase *)FileSystem0->UserContext; - FSP_CPP_EXCEPTION_GUARD(return self->GetFileInfo( - (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext) - ->UserContext, - (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext) - ->UserContext2, - FileInfo);) - } - static NTSTATUS SetBasicInfo(FSP_FILE_SYSTEM *FileSystem0, PVOID FullContext, - UINT32 FileAttributes, UINT64 CreationTime, - UINT64 LastAccessTime, UINT64 LastWriteTime, - UINT64 ChangeTime, - FSP_FSCTL_FILE_INFO *FileInfo) { - FileSystemBase *self = (FileSystemBase *)FileSystem0->UserContext; - FSP_CPP_EXCEPTION_GUARD(return self->SetBasicInfo( - (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext) - ->UserContext, - (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext) - ->UserContext2, - FileAttributes, CreationTime, LastAccessTime, LastWriteTime, ChangeTime, - FileInfo);) - } - static NTSTATUS SetFileSize(FSP_FILE_SYSTEM *FileSystem0, PVOID FullContext, - UINT64 NewSize, BOOLEAN SetAllocationSize, - FSP_FSCTL_FILE_INFO *FileInfo) { - FileSystemBase *self = (FileSystemBase *)FileSystem0->UserContext; - FSP_CPP_EXCEPTION_GUARD(return self->SetFileSize( - (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext) - ->UserContext, - (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext) - ->UserContext2, - NewSize, SetAllocationSize, FileInfo);) - } - static NTSTATUS CanDelete(FSP_FILE_SYSTEM *FileSystem0, PVOID FullContext, - PWSTR FileName) { - FileSystemBase *self = (FileSystemBase *)FileSystem0->UserContext; - FSP_CPP_EXCEPTION_GUARD(return self->CanDelete( - (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext) - ->UserContext, - (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext) - ->UserContext2, - FileName);) - } - static NTSTATUS Rename(FSP_FILE_SYSTEM *FileSystem0, PVOID FullContext, - PWSTR FileName, PWSTR NewFileName, - BOOLEAN ReplaceIfExists) { - FileSystemBase *self = (FileSystemBase *)FileSystem0->UserContext; - FSP_CPP_EXCEPTION_GUARD(return self->Rename( - (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext) - ->UserContext, - (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext) - ->UserContext2, - FileName, NewFileName, ReplaceIfExists);) - } - static NTSTATUS GetSecurity(FSP_FILE_SYSTEM *FileSystem0, PVOID FullContext, - PSECURITY_DESCRIPTOR SecurityDescriptor, - SIZE_T *PSecurityDescriptorSize) { - FileSystemBase *self = (FileSystemBase *)FileSystem0->UserContext; - FSP_CPP_EXCEPTION_GUARD(return self->GetSecurity( - (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext) - ->UserContext, - (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext) - ->UserContext2, - SecurityDescriptor, PSecurityDescriptorSize);) - } - static NTSTATUS SetSecurity(FSP_FILE_SYSTEM *FileSystem0, PVOID FullContext, - SECURITY_INFORMATION SecurityInformation, - PSECURITY_DESCRIPTOR ModificationDescriptor) { - FileSystemBase *self = (FileSystemBase *)FileSystem0->UserContext; - FSP_CPP_EXCEPTION_GUARD(return self->SetSecurity( - (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext) - ->UserContext, - (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext) - ->UserContext2, - SecurityInformation, ModificationDescriptor);) - } - static NTSTATUS ReadDirectory(FSP_FILE_SYSTEM *FileSystem0, PVOID FullContext, - PWSTR Pattern, PWSTR Marker, PVOID Buffer, - ULONG Length, PULONG PBytesTransferred) { - FileSystemBase *self = (FileSystemBase *)FileSystem0->UserContext; - FSP_CPP_EXCEPTION_GUARD(return self->ReadDirectory( - (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext) - ->UserContext, - (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext) - ->UserContext2, - Pattern, Marker, Buffer, Length, PBytesTransferred);) - } - static NTSTATUS ResolveReparsePoints(FSP_FILE_SYSTEM *FileSystem0, - PWSTR FileName, UINT32 ReparsePointIndex, - BOOLEAN ResolveLastPathComponent, - PIO_STATUS_BLOCK PIoStatus, PVOID Buffer, - PSIZE_T PSize) { - FileSystemBase *self = (FileSystemBase *)FileSystem0->UserContext; - FSP_CPP_EXCEPTION_GUARD(return self->ResolveReparsePoints( - FileName, ReparsePointIndex, ResolveLastPathComponent, PIoStatus, - Buffer, PSize);) - } - static NTSTATUS GetReparsePoint(FSP_FILE_SYSTEM *FileSystem0, - PVOID FullContext, PWSTR FileName, - PVOID Buffer, PSIZE_T PSize) { - FileSystemBase *self = (FileSystemBase *)FileSystem0->UserContext; - FSP_CPP_EXCEPTION_GUARD(return self->GetReparsePoint( - (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext) - ->UserContext, - (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext) - ->UserContext2, - FileName, Buffer, PSize);) - } - static NTSTATUS SetReparsePoint(FSP_FILE_SYSTEM *FileSystem0, - PVOID FullContext, PWSTR FileName, - PVOID Buffer, SIZE_T Size) { - FileSystemBase *self = (FileSystemBase *)FileSystem0->UserContext; - FSP_CPP_EXCEPTION_GUARD(return self->SetReparsePoint( - (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext) - ->UserContext, - (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext) - ->UserContext2, - FileName, Buffer, Size);) - } - static NTSTATUS DeleteReparsePoint(FSP_FILE_SYSTEM *FileSystem0, - PVOID FullContext, PWSTR FileName, - PVOID Buffer, SIZE_T Size) { - FileSystemBase *self = (FileSystemBase *)FileSystem0->UserContext; - FSP_CPP_EXCEPTION_GUARD(return self->DeleteReparsePoint( - (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext) - ->UserContext, - (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext) - ->UserContext2, - FileName, Buffer, Size);) - } - static NTSTATUS GetStreamInfo(FSP_FILE_SYSTEM *FileSystem0, PVOID FullContext, - PVOID Buffer, ULONG Length, - PULONG PBytesTransferred) { - FileSystemBase *self = (FileSystemBase *)FileSystem0->UserContext; - FSP_CPP_EXCEPTION_GUARD(return self->GetStreamInfo( - (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext) - ->UserContext, - (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext) - ->UserContext2, - Buffer, Length, PBytesTransferred);) - } - static FSP_FILE_SYSTEM_INTERFACE *Interface() { - static FSP_FILE_SYSTEM_INTERFACE _Interface = { - GetVolumeInfo, - SetVolumeLabel_, - GetSecurityByName, - Create, - Open, - Overwrite, - Cleanup, - Close, - Read, - Write, - Flush, - GetFileInfo, - SetBasicInfo, - SetFileSize, - CanDelete, - Rename, - GetSecurity, - SetSecurity, - ReadDirectory, - ResolveReparsePoints, - GetReparsePoint, - SetReparsePoint, - DeleteReparsePoint, - GetStreamInfo, - }; - return &_Interface; - } - -private: - /* disallow copy and assignment */ - FileSystemHost(const FileSystemHost &); - FileSystemHost &operator=(const FileSystemHost &); - -private: - FSP_FSCTL_VOLUME_PARAMS _VolumeParams; - FSP_FILE_SYSTEM *_FileSystemPtr; - FileSystemBase *_FileSystem; -}; - -class Service { -public: - /* ctor/dtor */ - Service(PWSTR ServiceName) : _Service(0) { - Initialize(); - FspServiceCreate(ServiceName, OnStart, OnStop, 0, &_Service); - if (0 != _Service) - _Service->UserContext = this; - } - virtual ~Service() { - if (0 != _Service) - FspServiceDelete(_Service); - } - - /* control */ - ULONG Run() { - if (0 == _Service) { - FspServiceLog(EVENTLOG_ERROR_TYPE, - L"The service cannot be created (Status=%lx).", - STATUS_INSUFFICIENT_RESOURCES); - return FspWin32FromNtStatus(STATUS_INSUFFICIENT_RESOURCES); - } - FspServiceAllowConsoleMode(_Service); - NTSTATUS Result = FspServiceLoop(_Service); - ULONG ExitCode = FspServiceGetExitCode(_Service); - if (!NT_SUCCESS(Result)) { - FspServiceLog(EVENTLOG_ERROR_TYPE, - L"The service has failed to run (Status=%lx).", Result); - return FspWin32FromNtStatus(Result); - } - return ExitCode; - } - VOID Stop() { - if (0 == _Service) - return; - FspServiceStop(_Service); - } - VOID RequestTime(ULONG Time) { - if (0 == _Service) - return; - FspServiceRequestTime(_Service, Time); - } - ULONG GetExitCode() { - return 0 != _Service ? FspServiceGetExitCode(_Service) - : ERROR_NO_SYSTEM_RESOURCES; - } - VOID SetExitCode(ULONG ExitCode) { - if (0 == _Service) - return; - FspServiceSetExitCode(_Service, ExitCode); - } - FSP_SERVICE *ServiceHandle() { return _Service; } - static VOID Log(ULONG Type, PWSTR Format, ...) { - va_list ap; - va_start(ap, Format); - FspServiceLogV(Type, Format, ap); - va_end(ap); - } - static VOID LogV(ULONG Type, PWSTR Format, va_list ap) { - FspServiceLogV(Type, Format, ap); - } - -protected: - /* start/stop */ - virtual NTSTATUS ExceptionHandler() { - return 0xE06D7363 /*STATUS_CPP_EH_EXCEPTION*/; - } - virtual NTSTATUS OnStart(ULONG Argc, PWSTR *Argv) { return STATUS_SUCCESS; } - virtual NTSTATUS OnStop() { return STATUS_SUCCESS; } - -private: - /* callbacks */ - static NTSTATUS OnStart(FSP_SERVICE *Service0, ULONG Argc, PWSTR *Argv) { - Service *self = (Service *)Service0->UserContext; - FSP_CPP_EXCEPTION_GUARD(return self->OnStart(Argc, Argv);) - } - static NTSTATUS OnStop(FSP_SERVICE *Service0) { - Service *self = (Service *)Service0->UserContext; - FSP_CPP_EXCEPTION_GUARD(return self->OnStop();) - } - -private: - /* disallow copy and assignment */ - Service(const Service &); - Service &operator=(const Service &); - -private: - FSP_SERVICE *_Service; -}; - -} // namespace Fsp - -#undef FSP_CPP_EXCEPTION_GUARD -#undef FSP_CPP_EXCEPTION_GUARD_VOID - -#endif diff --git a/support/3rd_party/winfsp-2.0/lib/winfsp-a64.lib b/support/3rd_party/winfsp-2.0/lib/winfsp-a64.lib deleted file mode 100644 index 06bc179f..00000000 Binary files a/support/3rd_party/winfsp-2.0/lib/winfsp-a64.lib and /dev/null differ diff --git a/support/3rd_party/winfsp-2.0/lib/winfsp-x64.lib b/support/3rd_party/winfsp-2.0/lib/winfsp-x64.lib deleted file mode 100644 index 004d6402..00000000 Binary files a/support/3rd_party/winfsp-2.0/lib/winfsp-x64.lib and /dev/null differ diff --git a/support/3rd_party/winfsp-2.0/lib/winfsp-x86.lib b/support/3rd_party/winfsp-2.0/lib/winfsp-x86.lib deleted file mode 100644 index c2fbc9de..00000000 Binary files a/support/3rd_party/winfsp-2.0/lib/winfsp-x86.lib and /dev/null differ diff --git a/support/3rd_party/winfsp-2.0/License.txt b/support/3rd_party/winfsp-2.1/License.txt similarity index 98% rename from support/3rd_party/winfsp-2.0/License.txt rename to support/3rd_party/winfsp-2.1/License.txt index 7fc809bd..372164f9 100644 --- a/support/3rd_party/winfsp-2.0/License.txt +++ b/support/3rd_party/winfsp-2.1/License.txt @@ -1,708 +1,708 @@ -The WinFsp project is Copyright (C) Bill Zissimopoulos. It is licensed -under the terms of the GPLv3. - -As a special exception to GPLv3, Bill Zissimopoulos grants additional -permissions to Free/Libre and Open Source Software ("FLOSS") without requiring -that such software is covered by the GPLv3. - - 1. Permission to link with a platform specific version of the WinFsp DLL - (one of: winfsp-a64.dll, winfsp-x64.dll, winfsp-x86.dll, winfsp-msil.dll). - - 2. Permission to distribute unmodified binary releases of the WinFsp - installer (as released by the WinFsp project). - - These permissions (and no other) are granted provided that the software: - - 1. Is distributed under a license that satisfies the Free Software - Definition Version 1.141 (https://www.gnu.org/philosophy/free-sw.en.html) - or the Open Source Definition Version 1.9 (https://opensource.org/osd). - - 2. Includes the copyright notice "WinFsp - Windows File System Proxy, - Copyright (C) Bill Zissimopoulos" and a link to the WinFsp repository in - its user-interface and any user-facing documentation. - - 3. Is not linked or distributed with proprietary (non-FLOSS) software. - [You cannot mix FLOSS and proprietary software while using WinFsp under - this special exception.] - -Commercial licensing options are also available: Please contact -Bill Zissimopoulos . - -The full text of the GPLv3 license follows below. - ------------------------------------------------------------------------ - - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. +The WinFsp project is Copyright (C) Bill Zissimopoulos. It is licensed +under the terms of the GPLv3. + +As a special exception to GPLv3, Bill Zissimopoulos grants additional +permissions to Free/Libre and Open Source Software ("FLOSS") without requiring +that such software is covered by the GPLv3. + + 1. Permission to link with a platform specific version of the WinFsp DLL + (one of: winfsp-a64.dll, winfsp-x64.dll, winfsp-x86.dll, winfsp-msil.dll). + + 2. Permission to distribute unmodified binary releases of the WinFsp + installer (as released by the WinFsp project). + + These permissions (and no other) are granted provided that the software: + + 1. Is distributed under a license that satisfies the Free Software + Definition Version 1.141 (https://www.gnu.org/philosophy/free-sw.en.html) + or the Open Source Definition Version 1.9 (https://opensource.org/osd). + + 2. Includes the copyright notice "WinFsp - Windows File System Proxy, + Copyright (C) Bill Zissimopoulos" and a link to the WinFsp repository in + its user-interface and any user-facing documentation. + + 3. Is not linked or distributed with proprietary (non-FLOSS) software. + [You cannot mix FLOSS and proprietary software while using WinFsp under + this special exception.] + +Commercial licensing options are also available: Please contact +Bill Zissimopoulos . + +The full text of the GPLv3 license follows below. + +----------------------------------------------------------------------- + + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/support/3rd_party/winfsp-2.0/bin/diag.bat b/support/3rd_party/winfsp-2.1/bin/diag.bat similarity index 95% rename from support/3rd_party/winfsp-2.0/bin/diag.bat rename to support/3rd_party/winfsp-2.1/bin/diag.bat index d282601a..676e257b 100644 --- a/support/3rd_party/winfsp-2.0/bin/diag.bat +++ b/support/3rd_party/winfsp-2.1/bin/diag.bat @@ -1,54 +1,54 @@ -@echo off - -setlocal -setlocal EnableDelayedExpansion - -REM Determine the SxS (side-by-side) identifier. -set SxsDir= -set RegKey="HKLM\SOFTWARE\WinFsp" -set RegVal="SxsDir" -reg query !RegKey! /v !RegVal! /reg:32 >nul 2>&1 -if !ERRORLEVEL! equ 0 ( - for /f "tokens=2,*" %%i in ('reg query !RegKey! /v !RegVal! /reg:32 ^| findstr !RegVal!') do ( - set SxsDir=%%j - ) -) -set SxsSuffix= -if defined SxsDir ( - set SxsSuffix=!SxsDir:*SxS\sxs.=! - if !SxsSuffix:~-1!==\ set SxsSuffix=!SxsSuffix:~0,-1! - set SxsSuffix=+!SxsSuffix! -) - -echo WINFSP FSD -sc query WinFsp!SxsSuffix! -sc qc WinFsp!SxsSuffix! -sc sdshow WinFsp!SxsSuffix! -echo. -echo. - -echo WINFSP DLL -reg query HKLM\SYSTEM\CurrentControlSet\Control\NetworkProvider\Order -reg query HKLM\SYSTEM\CurrentControlSet\Services\WinFsp.Np\NetworkProvider -reg query HKLM\SYSTEM\CurrentControlSet\Services\EventLog\Application\WinFsp -echo. - -echo WINFSP LAUNCHER -sc query WinFsp.Launcher -sc qc WinFsp.Launcher -sc sdshow WinFsp.Launcher -echo. -echo. - -echo WINFSP REGISTRY -reg query HKLM\SOFTWARE\WinFsp /s /reg:32 -echo. - -echo FILE SYSTEM FILTERS (REQUIRES ADMINISTRATOR) -fltmc filters -echo. -echo. - -echo OS INFORMATION -systeminfo -echo. +@echo off + +setlocal +setlocal EnableDelayedExpansion + +REM Determine the SxS (side-by-side) identifier. +set SxsDir= +set RegKey="HKLM\SOFTWARE\WinFsp" +set RegVal="SxsDir" +reg query !RegKey! /v !RegVal! /reg:32 >nul 2>&1 +if !ERRORLEVEL! equ 0 ( + for /f "tokens=2,*" %%i in ('reg query !RegKey! /v !RegVal! /reg:32 ^| findstr !RegVal!') do ( + set SxsDir=%%j + ) +) +set SxsSuffix= +if defined SxsDir ( + set SxsSuffix=!SxsDir:*SxS\sxs.=! + if !SxsSuffix:~-1!==\ set SxsSuffix=!SxsSuffix:~0,-1! + set SxsSuffix=+!SxsSuffix! +) + +echo WINFSP FSD +sc query WinFsp!SxsSuffix! +sc qc WinFsp!SxsSuffix! +sc sdshow WinFsp!SxsSuffix! +echo. +echo. + +echo WINFSP DLL +reg query HKLM\SYSTEM\CurrentControlSet\Control\NetworkProvider\Order +reg query HKLM\SYSTEM\CurrentControlSet\Services\WinFsp.Np\NetworkProvider +reg query HKLM\SYSTEM\CurrentControlSet\Services\EventLog\Application\WinFsp +echo. + +echo WINFSP LAUNCHER +sc query WinFsp.Launcher +sc qc WinFsp.Launcher +sc sdshow WinFsp.Launcher +echo. +echo. + +echo WINFSP REGISTRY +reg query HKLM\SOFTWARE\WinFsp /s /reg:32 +echo. + +echo FILE SYSTEM FILTERS (REQUIRES ADMINISTRATOR) +fltmc filters +echo. +echo. + +echo OS INFORMATION +systeminfo +echo. diff --git a/support/3rd_party/winfsp-2.0/bin/fsptool-a64.exe b/support/3rd_party/winfsp-2.1/bin/fsptool-a64.exe similarity index 72% rename from support/3rd_party/winfsp-2.0/bin/fsptool-a64.exe rename to support/3rd_party/winfsp-2.1/bin/fsptool-a64.exe index 534e3b02..c8065631 100644 Binary files a/support/3rd_party/winfsp-2.0/bin/fsptool-a64.exe and b/support/3rd_party/winfsp-2.1/bin/fsptool-a64.exe differ diff --git a/support/3rd_party/winfsp-2.0/bin/fsptool-x64.exe b/support/3rd_party/winfsp-2.1/bin/fsptool-x64.exe similarity index 72% rename from support/3rd_party/winfsp-2.0/bin/fsptool-x64.exe rename to support/3rd_party/winfsp-2.1/bin/fsptool-x64.exe index e8c5307a..56fafd7b 100644 Binary files a/support/3rd_party/winfsp-2.0/bin/fsptool-x64.exe and b/support/3rd_party/winfsp-2.1/bin/fsptool-x64.exe differ diff --git a/support/3rd_party/winfsp-2.0/bin/fsptool-x86.exe b/support/3rd_party/winfsp-2.1/bin/fsptool-x86.exe similarity index 70% rename from support/3rd_party/winfsp-2.0/bin/fsptool-x86.exe rename to support/3rd_party/winfsp-2.1/bin/fsptool-x86.exe index bb76fef6..a18c7307 100644 Binary files a/support/3rd_party/winfsp-2.0/bin/fsptool-x86.exe and b/support/3rd_party/winfsp-2.1/bin/fsptool-x86.exe differ diff --git a/support/3rd_party/winfsp-2.0/bin/fsreg.bat b/support/3rd_party/winfsp-2.1/bin/fsreg.bat similarity index 95% rename from support/3rd_party/winfsp-2.0/bin/fsreg.bat rename to support/3rd_party/winfsp-2.1/bin/fsreg.bat index 519132ce..8cad12a8 100644 --- a/support/3rd_party/winfsp-2.0/bin/fsreg.bat +++ b/support/3rd_party/winfsp-2.1/bin/fsreg.bat @@ -1,42 +1,42 @@ -@echo off - -setlocal -setlocal EnableDelayedExpansion - -set RegKey=HKLM\Software\WinFsp\Services - -if not X%1==X-u ( - set unreg=0 - - if not X%1==X set fsname=%1 - if not X%2==X set fsexec="%~f2" - if not X%3==X set fscmdl=%3 - if not X%4==X set fssecu=%4 - - if X!fscmdl!==X goto usage - if not exist !fsexec! goto notfound - - reg add !RegKey!\!fsname! /v Executable /t REG_SZ /d !fsexec! /f /reg:32 - reg add !RegKey!\!fsname! /v CommandLine /t REG_SZ /d !fscmdl! /f /reg:32 - reg add !RegKey!\!fsname! /v JobControl /t REG_DWORD /d 1 /f /reg:32 - if not X!fssecu!==X reg add !RegKey!\!fsname! /v Security /t REG_SZ /d !fssecu! /f /reg:32 -) else ( - set unreg=1 - - if not X%2==X set fsname=%2 - - if X!fsname!==X goto usage - - reg delete !RegKey!\!fsname! /f /reg:32 -) - -exit /b 0 - -:notfound -echo executable !fsexec! not found >&2 -exit /b 2 - -:usage -echo usage: fsreg NAME EXECUTABLE COMMANDLINE [SECURITY] >&2 -echo usage: fsreg -u NAME >&2 -exit /b 2 +@echo off + +setlocal +setlocal EnableDelayedExpansion + +set RegKey=HKLM\Software\WinFsp\Services + +if not X%1==X-u ( + set unreg=0 + + if not X%1==X set fsname=%1 + if not X%2==X set fsexec="%~f2" + if not X%3==X set fscmdl=%3 + if not X%4==X set fssecu=%4 + + if X!fscmdl!==X goto usage + if not exist !fsexec! goto notfound + + reg add !RegKey!\!fsname! /v Executable /t REG_SZ /d !fsexec! /f /reg:32 + reg add !RegKey!\!fsname! /v CommandLine /t REG_SZ /d !fscmdl! /f /reg:32 + reg add !RegKey!\!fsname! /v JobControl /t REG_DWORD /d 1 /f /reg:32 + if not X!fssecu!==X reg add !RegKey!\!fsname! /v Security /t REG_SZ /d !fssecu! /f /reg:32 +) else ( + set unreg=1 + + if not X%2==X set fsname=%2 + + if X!fsname!==X goto usage + + reg delete !RegKey!\!fsname! /f /reg:32 +) + +exit /b 0 + +:notfound +echo executable !fsexec! not found >&2 +exit /b 2 + +:usage +echo usage: fsreg NAME EXECUTABLE COMMANDLINE [SECURITY] >&2 +echo usage: fsreg -u NAME >&2 +exit /b 2 diff --git a/support/3rd_party/winfsp-2.0/bin/launchctl-a64.exe b/support/3rd_party/winfsp-2.1/bin/launchctl-a64.exe similarity index 69% rename from support/3rd_party/winfsp-2.0/bin/launchctl-a64.exe rename to support/3rd_party/winfsp-2.1/bin/launchctl-a64.exe index f77c16ef..1a381b35 100644 Binary files a/support/3rd_party/winfsp-2.0/bin/launchctl-a64.exe and b/support/3rd_party/winfsp-2.1/bin/launchctl-a64.exe differ diff --git a/support/3rd_party/winfsp-2.0/bin/launchctl-x64.exe b/support/3rd_party/winfsp-2.1/bin/launchctl-x64.exe similarity index 66% rename from support/3rd_party/winfsp-2.0/bin/launchctl-x64.exe rename to support/3rd_party/winfsp-2.1/bin/launchctl-x64.exe index b252d9a5..19358e5a 100644 Binary files a/support/3rd_party/winfsp-2.0/bin/launchctl-x64.exe and b/support/3rd_party/winfsp-2.1/bin/launchctl-x64.exe differ diff --git a/support/3rd_party/winfsp-2.0/bin/launchctl-x86.exe b/support/3rd_party/winfsp-2.1/bin/launchctl-x86.exe similarity index 67% rename from support/3rd_party/winfsp-2.0/bin/launchctl-x86.exe rename to support/3rd_party/winfsp-2.1/bin/launchctl-x86.exe index 46e0b8f6..ac018f90 100644 Binary files a/support/3rd_party/winfsp-2.0/bin/launchctl-x86.exe and b/support/3rd_party/winfsp-2.1/bin/launchctl-x86.exe differ diff --git a/support/3rd_party/winfsp-2.0/bin/launcher-a64.exe b/support/3rd_party/winfsp-2.1/bin/launcher-a64.exe similarity index 79% rename from support/3rd_party/winfsp-2.0/bin/launcher-a64.exe rename to support/3rd_party/winfsp-2.1/bin/launcher-a64.exe index ad4e134a..306c1f05 100644 Binary files a/support/3rd_party/winfsp-2.0/bin/launcher-a64.exe and b/support/3rd_party/winfsp-2.1/bin/launcher-a64.exe differ diff --git a/support/3rd_party/winfsp-2.0/bin/launcher-x64.exe b/support/3rd_party/winfsp-2.1/bin/launcher-x64.exe similarity index 81% rename from support/3rd_party/winfsp-2.0/bin/launcher-x64.exe rename to support/3rd_party/winfsp-2.1/bin/launcher-x64.exe index c5172f9f..d6dbb588 100644 Binary files a/support/3rd_party/winfsp-2.0/bin/launcher-x64.exe and b/support/3rd_party/winfsp-2.1/bin/launcher-x64.exe differ diff --git a/support/3rd_party/winfsp-2.0/bin/launcher-x86.exe b/support/3rd_party/winfsp-2.1/bin/launcher-x86.exe similarity index 76% rename from support/3rd_party/winfsp-2.0/bin/launcher-x86.exe rename to support/3rd_party/winfsp-2.1/bin/launcher-x86.exe index 5abcc6a7..6ebc1ab8 100644 Binary files a/support/3rd_party/winfsp-2.0/bin/launcher-x86.exe and b/support/3rd_party/winfsp-2.1/bin/launcher-x86.exe differ diff --git a/support/3rd_party/winfsp-2.1/bin/memfs-a64.exe b/support/3rd_party/winfsp-2.1/bin/memfs-a64.exe new file mode 100644 index 00000000..7d0189a9 Binary files /dev/null and b/support/3rd_party/winfsp-2.1/bin/memfs-a64.exe differ diff --git a/support/3rd_party/winfsp-2.0/bin/memfs-dotnet-msil.exe b/support/3rd_party/winfsp-2.1/bin/memfs-dotnet-msil.exe similarity index 88% rename from support/3rd_party/winfsp-2.0/bin/memfs-dotnet-msil.exe rename to support/3rd_party/winfsp-2.1/bin/memfs-dotnet-msil.exe index 90dcb721..fd5c7db3 100644 Binary files a/support/3rd_party/winfsp-2.0/bin/memfs-dotnet-msil.exe and b/support/3rd_party/winfsp-2.1/bin/memfs-dotnet-msil.exe differ diff --git a/support/3rd_party/winfsp-2.1/bin/memfs-x64.exe b/support/3rd_party/winfsp-2.1/bin/memfs-x64.exe new file mode 100644 index 00000000..2666e4d7 Binary files /dev/null and b/support/3rd_party/winfsp-2.1/bin/memfs-x64.exe differ diff --git a/support/3rd_party/winfsp-2.1/bin/memfs-x86.exe b/support/3rd_party/winfsp-2.1/bin/memfs-x86.exe new file mode 100644 index 00000000..dc96d74d Binary files /dev/null and b/support/3rd_party/winfsp-2.1/bin/memfs-x86.exe differ diff --git a/support/3rd_party/winfsp-2.1/bin/winfsp-a64.dll b/support/3rd_party/winfsp-2.1/bin/winfsp-a64.dll new file mode 100644 index 00000000..abc71d83 Binary files /dev/null and b/support/3rd_party/winfsp-2.1/bin/winfsp-a64.dll differ diff --git a/support/3rd_party/winfsp-2.0/bin/winfsp-a64.sys b/support/3rd_party/winfsp-2.1/bin/winfsp-a64.sys similarity index 61% rename from support/3rd_party/winfsp-2.0/bin/winfsp-a64.sys rename to support/3rd_party/winfsp-2.1/bin/winfsp-a64.sys index 75f0f270..62d18b04 100644 Binary files a/support/3rd_party/winfsp-2.0/bin/winfsp-a64.sys and b/support/3rd_party/winfsp-2.1/bin/winfsp-a64.sys differ diff --git a/support/3rd_party/winfsp-2.0/bin/winfsp-msil.dll b/support/3rd_party/winfsp-2.1/bin/winfsp-msil.dll similarity index 97% rename from support/3rd_party/winfsp-2.0/bin/winfsp-msil.dll rename to support/3rd_party/winfsp-2.1/bin/winfsp-msil.dll index b7fef259..d63076da 100644 Binary files a/support/3rd_party/winfsp-2.0/bin/winfsp-msil.dll and b/support/3rd_party/winfsp-2.1/bin/winfsp-msil.dll differ diff --git a/support/3rd_party/winfsp-2.0/bin/winfsp-msil.xml b/support/3rd_party/winfsp-2.1/bin/winfsp-msil.xml similarity index 97% rename from support/3rd_party/winfsp-2.0/bin/winfsp-msil.xml rename to support/3rd_party/winfsp-2.1/bin/winfsp-msil.xml index 219ef2a2..96597eb8 100644 --- a/support/3rd_party/winfsp-2.0/bin/winfsp-msil.xml +++ b/support/3rd_party/winfsp-2.1/bin/winfsp-msil.xml @@ -1,1375 +1,1375 @@ - - - - winfsp-msil - - - - - Provides the base class that user mode file systems must inherit from. - - - - - Provides a means to customize the returned status code when an exception happens. - - - STATUS_SUCCESS or error code. - - - - Occurs just before the file system is mounted. - File systems may override this method to configure the file system host. - - - The file system host that is mounting this file system. - - STATUS_SUCCESS or error code. - - - - Occurs just after the file system is mounted, - but prior to receiving any file system operation. - - - The file system host that is mounting this file system. - - STATUS_SUCCESS or error code. - - - - Occurs just after the file system is unmounted. - No other file system operations will be received on this file system. - - - The file system host that is mounting this file system. - - - - - Gets the volume information. - - - Receives the volume information. - - STATUS_SUCCESS or error code. - - - - Sets the volume label. - - - The new label for the volume. - - - Receives the updated volume information. - - STATUS_SUCCESS or error code. - - - - Gets file or directory attributes and security descriptor given a file name. - - - The name of the file or directory to get the attributes and security descriptor for. - - - Receives the file attributes on successful return. - If this call returns STATUS_REPARSE, the file system may place here the index of the - first reparse point within FileName. - - - Receives the file security descriptor. If the SecurityDescriptor parameter is null - on input the file system should not fill this value. - - - STATUS_SUCCESS, STATUS_REPARSE or error code. - STATUS_REPARSE should be returned by file systems that support reparse points when - they encounter a FileName that contains reparse points anywhere but the final path - component. - - - - - Creates a new file or directory. - - - The name of the file or directory to be created. - - - Create options for this request. - - - Determines the specific access rights that have been granted for this request. - - - File attributes to apply to the newly created file or directory. - - - Security descriptor to apply to the newly created file or directory. - - - Allocation size for the newly created file. - - - Receives the file node for the newly created file. - - - Receives the file descriptor for the newly created file. - - - Receives the file information for the newly created file. - - - Receives the normalized name for the newly created file. - - STATUS_SUCCESS or error code. - - - - Opens a file or directory. - - - The name of the file or directory to be opened. - - - Create options for this request. - - - Determines the specific access rights that have been granted for this request. - - - Receives the file node for the newly opened file. - - - Receives the file descriptor for the newly opened file. - - - Receives the file information for the newly opened file. - - - Receives the normalized name for the newly opened file. - - STATUS_SUCCESS or error code. - - - - Overwrites a file. - - - The file node for the file to be overwritten. - - - The file descriptor for the file to be overwritten. - - - File attributes to apply to the overwritten file. - - - When true the existing file attributes should be replaced with the new ones. - When false the existing file attributes should be merged (or'ed) with the new ones. - - - Allocation size for the overwritten file. - - - Receives the updated file information. - - STATUS_SUCCESS or error code. - - - - Cleans up a file or directory. - - - - When CreateFile is used to open or create a file the kernel creates a kernel mode file - object (type FILE_OBJECT) and a handle for it, which it returns to user-mode. The handle may - be duplicated (using DuplicateHandle), but all duplicate handles always refer to the same - file object. When all handles for a particular file object get closed (using CloseHandle) - the system sends a Cleanup request to the file system. - - There will be a Cleanup operation for every Create or Open operation posted to the user mode - file system. However the Cleanup operation is not the final close operation on a file. - The file system must be ready to receive additional operations until close time. This is true - even when the file is being deleted! - - The Flags parameter contains information about the cleanup operation: - - CleanupDelete - - An important function of the Cleanup operation is to complete a delete operation. Deleting - a file or directory in Windows is a three-stage process where the file is first opened, then - tested to see if the delete can proceed and if the answer is positive the file is then - deleted during Cleanup. - When this flag is set, this is the last outstanding cleanup for this particular file node. - - CleanupSetAllocationSize - - The NTFS and FAT file systems reset a file's allocation size when they receive the last - outstanding cleanup for a particular file node. User mode file systems that implement - allocation size and wish to duplicate the NTFS and FAT behavior can use this flag. - - CleanupSetArchiveBit - - File systems that support the archive bit should set the file node's archive bit when this - flag is set. - - CleanupSetLastAccessTime, CleanupSetLastWriteTime, CleanupSetChangeTime - - File systems should set the corresponding file time when each one of these flags is set. - Note that updating the last access time is expensive and a file system may choose to not - implement it. - - - - There is no way to report failure of this operation. This is a Windows limitation. - - - - The file node of the file or directory to cleanup. - - - The file descriptor of the file or directory to cleanup. - - - The name of the file or directory to cleanup. Sent only when a Delete is requested. - - - These flags determine whether the file was modified and whether to delete the file. - - - - - - - - Closes a file or directory. - - - The file node of the file or directory to close. - - - The file descriptor of the file or directory to close. - - - - - Reads a file. - - - The file node of the file to read. - - - The file descriptor of the file to read. - - - Pointer to a buffer that receives the results of the read operation. - - - Offset within the file to read from. - - - Length of data to read. - - - Receives the actual number of bytes read. - - STATUS_SUCCESS or error code. - - - - Writes a file. - - - The file node of the file to write. - - - The file descriptor of the file to write. - - - Pointer to a buffer that receives the results of the write operation. - - - Offset within the file to write to. - - - Length of data to write. - - - When true the file system must write to the current end of file. In this case the Offset - parameter will contain the value -1. - - - When true the file system must not extend the file (i.e. change the file size). - - - Receives the actual number of bytes written. - - - Receives the updated file information. - - STATUS_SUCCESS or error code. - - - - Flushes a file or volume. - - - Note that the FSD will also flush all file/volume caches prior to invoking this operation. - - - The file node of the file to flush. - When this and the FileDesc parameter are null the whole volume is being flushed. - - - The file descriptor of the file to flush. - When this and the FileNode parameter are null the whole volume is being flushed. - - - Receives the updated file information. - - STATUS_SUCCESS or error code. - - - - Gets file or directory information. - - - The file node of the file to get information for. - - - The file descriptor of the file to get information for. - - - Receives the file information. - - STATUS_SUCCESS or error code. - - - - Sets file or directory basic information. - - - The file node of the file to set information for. - - - The file descriptor of the file to set information for. - - - File attributes to apply to the file or directory. - If the value -1 is sent, the file attributes should not be changed. - - - Creation time to apply to the file or directory. - If the value 0 is sent, the creation time should not be changed. - - - Last access time to apply to the file or directory. - If the value 0 is sent, the last access time should not be changed. - - - Last write time to apply to the file or directory. - If the value 0 is sent, the last write time should not be changed. - - - Change time to apply to the file or directory. - If the value 0 is sent, the change time should not be changed. - - - Receives the updated file information. - - STATUS_SUCCESS or error code. - - - - Sets file/allocation size. - - - - This function is used to change a file's sizes. Windows file systems maintain two kinds - of sizes: the file size is where the End Of File (EOF) is, and the allocation size is the - actual size that a file takes up on the "disk". - - The rules regarding file/allocation size are: - - - Allocation size must always be aligned to the allocation unit boundary. The allocation - unit is the product SectorSize * SectorsPerAllocationUnit. The FSD will always send - properly aligned allocation sizes when setting the allocation size. - - - Allocation size is always greater or equal to the file size. - - - A file size of more than the current allocation size will also extend the allocation - size to the next allocation unit boundary. - - - An allocation size of less than the current file size should also truncate the current - file size. - - - - - - The file node of the file to set the file/allocation size for. - - - The file descriptor of the file to set the file/allocation size for. - - - New file/allocation size to apply to the file. - - - If true, then the allocation size is being set. if false, then the file size is being set. - - - Receives the updated file information. - - STATUS_SUCCESS or error code. - - - - Determines whether a file or directory can be deleted. - - - - This function tests whether a file or directory can be safely deleted. This function does - not need to perform access checks, but may performs tasks such as check for empty - directories, etc. - - This function should NEVER delete the file or directory in question. Deletion should - happen during Cleanup with the CleanupDelete flag set. - - This function gets called when Win32 API's such as DeleteFile or RemoveDirectory are used. - It does not get called when a file or directory is opened with FILE_DELETE_ON_CLOSE. - - NOTE: If both CanDelete and SetDelete are defined, SetDelete takes precedence. However - most file systems need only implement the CanDelete operation. - - - - The file node of the file or directory to test for deletion. - - - The file descriptor of the file or directory to test for deletion. - - - The name of the file or directory to test for deletion. - - STATUS_SUCCESS or error code. - - - - - - Renames a file or directory. - - - The kernel mode FSD provides certain guarantees prior to posting a rename operation: - - - A file cannot be renamed if a file with the same name exists and has open handles. - - - A directory cannot be renamed if it or any of its subdirectories contains a file that - has open handles. - - - - - The file node of the file or directory to be renamed. - - - The file descriptor of the file or directory to be renamed. - - - The current name of the file or directory to rename. - - - The new name for the file or directory. - - - Whether to replace a file that already exists at NewFileName. - - STATUS_SUCCESS or error code. - - - - Gets file or directory security descriptor. - - - The file node of the file or directory to get the security descriptor for. - - - The file descriptor of the file or directory to get the security descriptor for. - - - Receives the file security descriptor. - - STATUS_SUCCESS or error code. - - - - Sets file or directory security descriptor. - - - The file node of the file or directory to set the security descriptor for. - - - The file descriptor of the file or directory to set the security descriptor for. - - - Describes what parts of the file or directory security descriptor should be modified. - - - Describes the modifications to apply to the file or directory security descriptor. - - STATUS_SUCCESS or error code. - - - - - Reads a directory. - - - - - - Reads a directory entry. - - - The file node of the directory to be read. - - - The file descriptor of the directory to be read. - - - The pattern to match against files in this directory. Can be null. The file system - can choose to ignore this parameter as the FSD will always perform its own pattern - matching on the returned results. - - - A file name that marks where in the directory to start reading. Files with names - that are greater than (not equal to) this marker (in the directory order determined - by the file system) should be returned. Can be null. - - - Can be used by the file system to track the ReadDirectory operation. - - - Receives the file name for the directory entry. - - - Receives the file information for the directory entry. - - True if there are additional directory entries to return. False otherwise. - - - - - Resolves reparse points. - - - - - Gets a reparse point given a file name. - - - The name of the file or directory to get the reparse point for. - - - Determines whether the passed file name is assumed to be a directory. - - - Receives the reparse data for the file or directory. - - STATUS_SUCCESS or error code. - - - - Gets a reparse point. - - - The file node of the reparse point. - - - The file descriptor of the reparse point. - - - The file name of the reparse point. - - - Receives the reparse data for the reparse point. - - STATUS_SUCCESS or error code. - - - - Sets a reparse point. - - - The file node of the reparse point. - - - The file descriptor of the reparse point. - - - The file name of the reparse point. - - - The new reparse data for the reparse point. - - STATUS_SUCCESS or error code. - - - - Deletes a reparse point. - - - The file node of the reparse point. - - - The file descriptor of the reparse point. - - - The file name of the reparse point. - - - The reparse data for the reparse point. - - STATUS_SUCCESS or error code. - - - - Gets named streams information. - - - - - Gets named streams information entry. - - - The file node of the file or directory to get stream information for. - - - The file descriptor of the file or directory to get stream information for. - - - Can be used by the file system to track the GetStreamInfo operation. - - - Receives the stream name for the stream entry. - - - Receives the stream size for the stream entry. - - - Receives the stream allocation size for the stream entry. - - True if there are additional stream entries to return. False otherwise. - - - - Gets directory information for a single file or directory within a parent directory. - - - The file node of the parent directory. - - - The file descriptor of the parent directory. - - - The name of the file or directory to get information for. This name is relative - to the parent directory and is a single path component. - - - Receives the normalized name from the directory entry. - - - Receives the file information. - - STATUS_SUCCESS or error code. - - - - Processes a control code. - - - This function is called when a program uses the DeviceIoControl API. - - - The file node of the file or directory to be controled. - - - The file descriptor of the file or directory to be controled. - - - The control code for the operation. This code must have a DeviceType with bit - 0x8000 set and must have a TransferType of METHOD_BUFFERED. - - - Pointer to a buffer that contains the input data. - - - Input data length. - - - Pointer to a buffer that will receive the output data. - - - Output data length. - - - Receives the actual number of bytes transferred. - - STATUS_SUCCESS or error code. - - - - Sets the file delete flag. - - - - This function sets a flag to indicates whether the FSD file should delete a file - when it is closed. This function does not need to perform access checks, but may - performs tasks such as check for empty directories, etc. - - This function should NEVER delete the file or directory in question. Deletion should - happen during Cleanup with the CleanupDelete flag set. - - This function gets called when Win32 API's such as DeleteFile or RemoveDirectory are used. - It does not get called when a file or directory is opened with FILE_DELETE_ON_CLOSE. - - NOTE: If both CanDelete and SetDelete are defined, SetDelete takes precedence. However - most file systems need only implement the CanDelete operation. - - - - The file node of the file or directory to set the delete flag for. - - - The file descriptor of the file or directory to set the delete flag for. - - - The name of the file or directory to set the delete flag for. - - - If set to TRUE the FSD indicates that the file will be deleted on Cleanup; otherwise - it will not be deleted. It is legal to receive multiple SetDelete calls for the same - file with different DeleteFile parameters. - - STATUS_SUCCESS or error code. - - - - - - Inform the file system that its dispatcher has been stopped. - - - - Prior to WinFsp v2.0 the FSD would never unmount a file system volume unless - the user mode file system requested the unmount. Since WinFsp v2.0 it is possible - for the FSD to unmount a file system volume without an explicit user mode file system - request. For example, this happens when the FSD is being uninstalled. - - A user mode file system can use this operation to determine when its dispatcher - has been stopped. The Normally parameter can be used to determine why the dispatcher - was stopped: it is TRUE when the file system is being stopped normally (i.e. via the - native FspFileSystemStopDispatcher) and FALSE otherwise. - - A file system that uses the Service class infrastructure may use the - StopServiceIfNecessary method to correctly handle all cases. The base implementation - of this method calls the StopServiceIfNecessary method. - - This operation is the last one that a file system will receive. - - - - TRUE if the file system is being stopped via the native FspFileSystemStopDispatcher. - FALSE if the file system is being stopped because of another reason such - as driver unload/uninstall. - - - - - - Converts a Win32 error code to a Windows kernel status code. - - - - - Converts a Windows kernel status code to a Win32 error code. - - - - - Gets the originating process ID. - - - Valid only during Create, Open and Rename requests when the target exists. - - - - - Modifies a security descriptor. [OBSOLETE] - - - This is a helper for implementing the SetSecurity operation. - - - The original security descriptor. - - - Describes what parts of the file or directory security descriptor should be modified. - - - Describes the modifications to apply to the file or directory security descriptor. - - The modified security descriptor. - - - - - Modifies a security descriptor. - - - This is a helper for implementing the SetSecurity operation. - - - The original security descriptor. - - - Describes what parts of the file or directory security descriptor should be modified. - - - Describes the modifications to apply to the file or directory security descriptor. - - - The modified security descriptor. This parameter is modified only on success. - - STATUS_SUCCESS or error code. - - - - - Finds a reparse point in file name. - - - This is a helper for implementing the GetSecurityByName operation in file systems - that support reparse points. - - - The name of the file or directory. - - - Receives the index of the first reparse point within FileName. - - True if a reparse point was found, false otherwise. - - - - - Makes a byte array that contains a reparse point. - - The reparse point byte array. - - - - Gets the reparse tag from reparse data. - - - The reparse data to extract the reparse tag from. - - The reparse tag. - - - - Tests whether reparse data can be replaced. - - - This is a helper for implementing the SetReparsePoint/DeleteReparsePoint operation - in file systems that support reparse points. - - - The current reparse data. - - - The replacement reparse data. - - STATUS_SUCCESS or error code. - - - - - - Provides a means to host (mount) a file system. - - - - - Creates an instance of the FileSystemHost class. - - The file system to host. - - - - Unmounts the file system and releases all associated resources. - - - - - Gets or sets the sector size used by the file system. - - - - - Gets or sets the sectors per allocation unit used by the file system. - - - - - Gets or sets the maximum path component length used by the file system. - - - - - Gets or sets the volume creation time. - - - - - Gets or sets the volume serial number. - - - - - Gets or sets the file information timeout. - - - - - Gets or sets the volume information timeout. - - - - - Gets or sets the directory information timeout. - - - - - Gets or sets the security information timeout. - - - - - Gets or sets the stream information timeout. - - - - - Gets or sets the EA information timeout. - - - - - Gets or sets a value that determines whether the file system is case sensitive. - - - - - Gets or sets a value that determines whether a case insensitive file system - preserves case in file names. - - - - - Gets or sets a value that determines whether file names support unicode characters. - - - - - Gets or sets a value that determines whether the file system supports ACL security. - - - - - Gets or sets a value that determines whether the file system supports reparse points. - - - - - Gets or sets a value that determines whether the file system allows creation of - symbolic links without additional privileges. - - - - - Gets or sets a value that determines whether the file system supports named streams. - - - - - Gets or sets a value that determines whether the file system supports extended attributes. - - - - - Gets or sets the prefix for a network file system. - - - - - Gets or sets the file system name. - - - - - Checks whether mounting a file system is possible. - - - The mount point for the new file system. A value of null means that - the file system should use the next available drive letter counting - downwards from Z: as its mount point. - - STATUS_SUCCESS or error code. - - - - Mounts a file system. - - - The mount point for the new file system. A value of null means that - the file system should use the next available drive letter counting - downwards from Z: as its mount point. - - - Security descriptor to use if mounting on (newly created) directory. - A value of null means the directory should be created with default - security. - - - If true file system operations are synchronized using an exclusive lock. - - - A value of 0 disables all debug logging. - A value of -1 enables all debug logging. - - STATUS_SUCCESS or error code. - - - - Mounts a file system. - - - The mount point for the new file system. A value of null means that - the file system should use the next available drive letter counting - downwards from Z: as its mount point. - - - Number of threads to use to service file system requests. A value - of 0 means that the default number of threads should be used. - - - Security descriptor to use if mounting on (newly created) directory. - A value of null means the directory should be created with default - security. - - - If true file system operations are synchronized using an exclusive lock. - - - A value of 0 disables all debug logging. - A value of -1 enables all debug logging. - - STATUS_SUCCESS or error code. - - - - Unmounts the file system and releases all associated resources. - - - - - Gets the file system mount point. - - The file system mount point. - - - - Gets the hosted file system. - - The hosted file system. - - - - Sets the debug log file to use when debug logging is enabled. - - - The debug log file name. A value of "-" means standard error output. - - STATUS_SUCCESS or error code. - - - - Return the installed version of WinFsp. - - - - - Returns a RequestHint to reference the current operation asynchronously. - - - - - Asynchronously complete a Read operation. - - - A reference to the operation to complete. - - - STATUS_SUCCESS or error code. - - - Number of bytes read. - - - - - Asynchronously complete a Write operation. - - - A reference to the operation to complete. - - - STATUS_SUCCESS or error code. - - - The number of bytes written. - - - Updated file information. - - - - - Asynchronously complete a ReadDirectory operation. - - - A reference to the operation to complete. - - - STATUS_SUCCESS or error code. - - - Number of bytes read. - - - - - Begin notifying Windows that the file system has file changes. - - - - A file system that wishes to notify Windows about file changes must - first issue an FspFileSystemBegin call, followed by 0 or more - FspFileSystemNotify calls, followed by an FspFileSystemNotifyEnd call. - - This operation blocks concurrent file rename operations. File rename - operations may interfere with file notification, because a file being - notified may also be concurrently renamed. After all file change - notifications have been issued, you must make sure to call - FspFileSystemNotifyEnd to allow file rename operations to proceed. - - - - STATUS_SUCCESS or error code. The error code STATUS_CANT_WAIT means that - a file rename operation is currently in progress and the operation must be - retried at a later time. - - - - - End notifying Windows that the file system has file changes. - - - - A file system that wishes to notify Windows about file changes must - first issue an FspFileSystemBegin call, followed by 0 or more - FspFileSystemNotify calls, followed by an FspFileSystemNotifyEnd call. - - This operation allows any blocked file rename operations to proceed. - - - STATUS_SUCCESS or error code. - - - - Notify Windows that the file system has file changes. - - - - A file system that wishes to notify Windows about file changes must - first issue an FspFileSystemBegin call, followed by 0 or more - FspFileSystemNotify calls, followed by an FspFileSystemNotifyEnd call. - - Note that FspFileSystemNotify requires file names to be normalized. A - normalized file name is one that contains the correct case of all characters - in the file name. - - For case-sensitive file systems all file names are normalized by definition. - For case-insensitive file systems that implement file name normalization, - a normalized file name is the one that the file system specifies in the - response to Create or Open (see also FspFileSystemGetOpenFileInfo). For - case-insensitive file systems that do not implement file name normalization - a normalized file name is the upper case version of the file name used - to open the file. - - - STATUS_SUCCESS or error code. - - - - Contains volume information about a file system. - - - - - Total size of volume in bytes. - - - - - Free size of volume in bytes. - - - - - Sets the volume label. - - - - - Contains metadata information about a file or directory. - - - - - The file or directory attributes. - - - - - The reparse tag of the file or directory. - This value is 0 if the file or directory is not a reparse point. - - - - - The allocation size of the file. - - - - - The file size of the file (end of file). - - - - - The time that the file or directory was created. - - - - - The time that the file or directory was last accessed. - - - - - The time that the file or direcotry was last modified. - - - - - The time that the file or directory metadata was last modified. - - - - - A unique identifier that is associated with the file or directory. - Not all file systems support this value. - - - - - The number of hard links. - Not currently implemented. Set to 0. - - - - - The extended attribute size of the file. - - - - - Enumeration of all the possible values for NotifyInfo.Action - - - - - Enumeration of all the possible values for NotifyInfo.Filter - - - - - Contains file change notification information. - - - - - Provides the base class for a process that can be run as a service, - command line application or under the control of the WinFsp launcher. - - - - - Creates an instance of the Service class. - - The name of the service. - - - - Runs a service. - - Service process exit code. - - - - Stops a running service. - - - - - Gets or sets the service process exit code. - - - - - Provides a means to customize the returned status code when an exception happens. - - - STATUS_SUCCESS or error code. - - - - Occurs when the service starts. - - Command line arguments passed to the service. - - - - Occurs when the service stops. - - - - + + + + winfsp-msil + + + + + Provides the base class that user mode file systems must inherit from. + + + + + Provides a means to customize the returned status code when an exception happens. + + + STATUS_SUCCESS or error code. + + + + Occurs just before the file system is mounted. + File systems may override this method to configure the file system host. + + + The file system host that is mounting this file system. + + STATUS_SUCCESS or error code. + + + + Occurs just after the file system is mounted, + but prior to receiving any file system operation. + + + The file system host that is mounting this file system. + + STATUS_SUCCESS or error code. + + + + Occurs just after the file system is unmounted. + No other file system operations will be received on this file system. + + + The file system host that is mounting this file system. + + + + + Gets the volume information. + + + Receives the volume information. + + STATUS_SUCCESS or error code. + + + + Sets the volume label. + + + The new label for the volume. + + + Receives the updated volume information. + + STATUS_SUCCESS or error code. + + + + Gets file or directory attributes and security descriptor given a file name. + + + The name of the file or directory to get the attributes and security descriptor for. + + + Receives the file attributes on successful return. + If this call returns STATUS_REPARSE, the file system may place here the index of the + first reparse point within FileName. + + + Receives the file security descriptor. If the SecurityDescriptor parameter is null + on input the file system should not fill this value. + + + STATUS_SUCCESS, STATUS_REPARSE or error code. + STATUS_REPARSE should be returned by file systems that support reparse points when + they encounter a FileName that contains reparse points anywhere but the final path + component. + + + + + Creates a new file or directory. + + + The name of the file or directory to be created. + + + Create options for this request. + + + Determines the specific access rights that have been granted for this request. + + + File attributes to apply to the newly created file or directory. + + + Security descriptor to apply to the newly created file or directory. + + + Allocation size for the newly created file. + + + Receives the file node for the newly created file. + + + Receives the file descriptor for the newly created file. + + + Receives the file information for the newly created file. + + + Receives the normalized name for the newly created file. + + STATUS_SUCCESS or error code. + + + + Opens a file or directory. + + + The name of the file or directory to be opened. + + + Create options for this request. + + + Determines the specific access rights that have been granted for this request. + + + Receives the file node for the newly opened file. + + + Receives the file descriptor for the newly opened file. + + + Receives the file information for the newly opened file. + + + Receives the normalized name for the newly opened file. + + STATUS_SUCCESS or error code. + + + + Overwrites a file. + + + The file node for the file to be overwritten. + + + The file descriptor for the file to be overwritten. + + + File attributes to apply to the overwritten file. + + + When true the existing file attributes should be replaced with the new ones. + When false the existing file attributes should be merged (or'ed) with the new ones. + + + Allocation size for the overwritten file. + + + Receives the updated file information. + + STATUS_SUCCESS or error code. + + + + Cleans up a file or directory. + + + + When CreateFile is used to open or create a file the kernel creates a kernel mode file + object (type FILE_OBJECT) and a handle for it, which it returns to user-mode. The handle may + be duplicated (using DuplicateHandle), but all duplicate handles always refer to the same + file object. When all handles for a particular file object get closed (using CloseHandle) + the system sends a Cleanup request to the file system. + + There will be a Cleanup operation for every Create or Open operation posted to the user mode + file system. However the Cleanup operation is not the final close operation on a file. + The file system must be ready to receive additional operations until close time. This is true + even when the file is being deleted! + + The Flags parameter contains information about the cleanup operation: + + CleanupDelete - + An important function of the Cleanup operation is to complete a delete operation. Deleting + a file or directory in Windows is a three-stage process where the file is first opened, then + tested to see if the delete can proceed and if the answer is positive the file is then + deleted during Cleanup. + When this flag is set, this is the last outstanding cleanup for this particular file node. + + CleanupSetAllocationSize - + The NTFS and FAT file systems reset a file's allocation size when they receive the last + outstanding cleanup for a particular file node. User mode file systems that implement + allocation size and wish to duplicate the NTFS and FAT behavior can use this flag. + + CleanupSetArchiveBit - + File systems that support the archive bit should set the file node's archive bit when this + flag is set. + + CleanupSetLastAccessTime, CleanupSetLastWriteTime, CleanupSetChangeTime - + File systems should set the corresponding file time when each one of these flags is set. + Note that updating the last access time is expensive and a file system may choose to not + implement it. + + + + There is no way to report failure of this operation. This is a Windows limitation. + + + + The file node of the file or directory to cleanup. + + + The file descriptor of the file or directory to cleanup. + + + The name of the file or directory to cleanup. Sent only when a Delete is requested. + + + These flags determine whether the file was modified and whether to delete the file. + + + + + + + + Closes a file or directory. + + + The file node of the file or directory to close. + + + The file descriptor of the file or directory to close. + + + + + Reads a file. + + + The file node of the file to read. + + + The file descriptor of the file to read. + + + Pointer to a buffer that receives the results of the read operation. + + + Offset within the file to read from. + + + Length of data to read. + + + Receives the actual number of bytes read. + + STATUS_SUCCESS or error code. + + + + Writes a file. + + + The file node of the file to write. + + + The file descriptor of the file to write. + + + Pointer to a buffer that receives the results of the write operation. + + + Offset within the file to write to. + + + Length of data to write. + + + When true the file system must write to the current end of file. In this case the Offset + parameter will contain the value -1. + + + When true the file system must not extend the file (i.e. change the file size). + + + Receives the actual number of bytes written. + + + Receives the updated file information. + + STATUS_SUCCESS or error code. + + + + Flushes a file or volume. + + + Note that the FSD will also flush all file/volume caches prior to invoking this operation. + + + The file node of the file to flush. + When this and the FileDesc parameter are null the whole volume is being flushed. + + + The file descriptor of the file to flush. + When this and the FileNode parameter are null the whole volume is being flushed. + + + Receives the updated file information. + + STATUS_SUCCESS or error code. + + + + Gets file or directory information. + + + The file node of the file to get information for. + + + The file descriptor of the file to get information for. + + + Receives the file information. + + STATUS_SUCCESS or error code. + + + + Sets file or directory basic information. + + + The file node of the file to set information for. + + + The file descriptor of the file to set information for. + + + File attributes to apply to the file or directory. + If the value -1 is sent, the file attributes should not be changed. + + + Creation time to apply to the file or directory. + If the value 0 is sent, the creation time should not be changed. + + + Last access time to apply to the file or directory. + If the value 0 is sent, the last access time should not be changed. + + + Last write time to apply to the file or directory. + If the value 0 is sent, the last write time should not be changed. + + + Change time to apply to the file or directory. + If the value 0 is sent, the change time should not be changed. + + + Receives the updated file information. + + STATUS_SUCCESS or error code. + + + + Sets file/allocation size. + + + + This function is used to change a file's sizes. Windows file systems maintain two kinds + of sizes: the file size is where the End Of File (EOF) is, and the allocation size is the + actual size that a file takes up on the "disk". + + The rules regarding file/allocation size are: + + + Allocation size must always be aligned to the allocation unit boundary. The allocation + unit is the product SectorSize * SectorsPerAllocationUnit. The FSD will always send + properly aligned allocation sizes when setting the allocation size. + + + Allocation size is always greater or equal to the file size. + + + A file size of more than the current allocation size will also extend the allocation + size to the next allocation unit boundary. + + + An allocation size of less than the current file size should also truncate the current + file size. + + + + + + The file node of the file to set the file/allocation size for. + + + The file descriptor of the file to set the file/allocation size for. + + + New file/allocation size to apply to the file. + + + If true, then the allocation size is being set. if false, then the file size is being set. + + + Receives the updated file information. + + STATUS_SUCCESS or error code. + + + + Determines whether a file or directory can be deleted. + + + + This function tests whether a file or directory can be safely deleted. This function does + not need to perform access checks, but may performs tasks such as check for empty + directories, etc. + + This function should NEVER delete the file or directory in question. Deletion should + happen during Cleanup with the CleanupDelete flag set. + + This function gets called when Win32 API's such as DeleteFile or RemoveDirectory are used. + It does not get called when a file or directory is opened with FILE_DELETE_ON_CLOSE. + + NOTE: If both CanDelete and SetDelete are defined, SetDelete takes precedence. However + most file systems need only implement the CanDelete operation. + + + + The file node of the file or directory to test for deletion. + + + The file descriptor of the file or directory to test for deletion. + + + The name of the file or directory to test for deletion. + + STATUS_SUCCESS or error code. + + + + + + Renames a file or directory. + + + The kernel mode FSD provides certain guarantees prior to posting a rename operation: + + + A file cannot be renamed if a file with the same name exists and has open handles. + + + A directory cannot be renamed if it or any of its subdirectories contains a file that + has open handles. + + + + + The file node of the file or directory to be renamed. + + + The file descriptor of the file or directory to be renamed. + + + The current name of the file or directory to rename. + + + The new name for the file or directory. + + + Whether to replace a file that already exists at NewFileName. + + STATUS_SUCCESS or error code. + + + + Gets file or directory security descriptor. + + + The file node of the file or directory to get the security descriptor for. + + + The file descriptor of the file or directory to get the security descriptor for. + + + Receives the file security descriptor. + + STATUS_SUCCESS or error code. + + + + Sets file or directory security descriptor. + + + The file node of the file or directory to set the security descriptor for. + + + The file descriptor of the file or directory to set the security descriptor for. + + + Describes what parts of the file or directory security descriptor should be modified. + + + Describes the modifications to apply to the file or directory security descriptor. + + STATUS_SUCCESS or error code. + + + + + Reads a directory. + + + + + + Reads a directory entry. + + + The file node of the directory to be read. + + + The file descriptor of the directory to be read. + + + The pattern to match against files in this directory. Can be null. The file system + can choose to ignore this parameter as the FSD will always perform its own pattern + matching on the returned results. + + + A file name that marks where in the directory to start reading. Files with names + that are greater than (not equal to) this marker (in the directory order determined + by the file system) should be returned. Can be null. + + + Can be used by the file system to track the ReadDirectory operation. + + + Receives the file name for the directory entry. + + + Receives the file information for the directory entry. + + True if there are additional directory entries to return. False otherwise. + + + + + Resolves reparse points. + + + + + Gets a reparse point given a file name. + + + The name of the file or directory to get the reparse point for. + + + Determines whether the passed file name is assumed to be a directory. + + + Receives the reparse data for the file or directory. + + STATUS_SUCCESS or error code. + + + + Gets a reparse point. + + + The file node of the reparse point. + + + The file descriptor of the reparse point. + + + The file name of the reparse point. + + + Receives the reparse data for the reparse point. + + STATUS_SUCCESS or error code. + + + + Sets a reparse point. + + + The file node of the reparse point. + + + The file descriptor of the reparse point. + + + The file name of the reparse point. + + + The new reparse data for the reparse point. + + STATUS_SUCCESS or error code. + + + + Deletes a reparse point. + + + The file node of the reparse point. + + + The file descriptor of the reparse point. + + + The file name of the reparse point. + + + The reparse data for the reparse point. + + STATUS_SUCCESS or error code. + + + + Gets named streams information. + + + + + Gets named streams information entry. + + + The file node of the file or directory to get stream information for. + + + The file descriptor of the file or directory to get stream information for. + + + Can be used by the file system to track the GetStreamInfo operation. + + + Receives the stream name for the stream entry. + + + Receives the stream size for the stream entry. + + + Receives the stream allocation size for the stream entry. + + True if there are additional stream entries to return. False otherwise. + + + + Gets directory information for a single file or directory within a parent directory. + + + The file node of the parent directory. + + + The file descriptor of the parent directory. + + + The name of the file or directory to get information for. This name is relative + to the parent directory and is a single path component. + + + Receives the normalized name from the directory entry. + + + Receives the file information. + + STATUS_SUCCESS or error code. + + + + Processes a control code. + + + This function is called when a program uses the DeviceIoControl API. + + + The file node of the file or directory to be controled. + + + The file descriptor of the file or directory to be controled. + + + The control code for the operation. This code must have a DeviceType with bit + 0x8000 set and must have a TransferType of METHOD_BUFFERED. + + + Pointer to a buffer that contains the input data. + + + Input data length. + + + Pointer to a buffer that will receive the output data. + + + Output data length. + + + Receives the actual number of bytes transferred. + + STATUS_SUCCESS or error code. + + + + Sets the file delete flag. + + + + This function sets a flag to indicates whether the FSD file should delete a file + when it is closed. This function does not need to perform access checks, but may + performs tasks such as check for empty directories, etc. + + This function should NEVER delete the file or directory in question. Deletion should + happen during Cleanup with the CleanupDelete flag set. + + This function gets called when Win32 API's such as DeleteFile or RemoveDirectory are used. + It does not get called when a file or directory is opened with FILE_DELETE_ON_CLOSE. + + NOTE: If both CanDelete and SetDelete are defined, SetDelete takes precedence. However + most file systems need only implement the CanDelete operation. + + + + The file node of the file or directory to set the delete flag for. + + + The file descriptor of the file or directory to set the delete flag for. + + + The name of the file or directory to set the delete flag for. + + + If set to TRUE the FSD indicates that the file will be deleted on Cleanup; otherwise + it will not be deleted. It is legal to receive multiple SetDelete calls for the same + file with different DeleteFile parameters. + + STATUS_SUCCESS or error code. + + + + + + Inform the file system that its dispatcher has been stopped. + + + + Prior to WinFsp v2.0 the FSD would never unmount a file system volume unless + the user mode file system requested the unmount. Since WinFsp v2.0 it is possible + for the FSD to unmount a file system volume without an explicit user mode file system + request. For example, this happens when the FSD is being uninstalled. + + A user mode file system can use this operation to determine when its dispatcher + has been stopped. The Normally parameter can be used to determine why the dispatcher + was stopped: it is TRUE when the file system is being stopped normally (i.e. via the + native FspFileSystemStopDispatcher) and FALSE otherwise. + + A file system that uses the Service class infrastructure may use the + StopServiceIfNecessary method to correctly handle all cases. The base implementation + of this method calls the StopServiceIfNecessary method. + + This operation is the last one that a file system will receive. + + + + TRUE if the file system is being stopped via the native FspFileSystemStopDispatcher. + FALSE if the file system is being stopped because of another reason such + as driver unload/uninstall. + + + + + + Converts a Win32 error code to a Windows kernel status code. + + + + + Converts a Windows kernel status code to a Win32 error code. + + + + + Gets the originating process ID. + + + Valid only during Create, Open and Rename requests when the target exists. + + + + + Modifies a security descriptor. [OBSOLETE] + + + This is a helper for implementing the SetSecurity operation. + + + The original security descriptor. + + + Describes what parts of the file or directory security descriptor should be modified. + + + Describes the modifications to apply to the file or directory security descriptor. + + The modified security descriptor. + + + + + Modifies a security descriptor. + + + This is a helper for implementing the SetSecurity operation. + + + The original security descriptor. + + + Describes what parts of the file or directory security descriptor should be modified. + + + Describes the modifications to apply to the file or directory security descriptor. + + + The modified security descriptor. This parameter is modified only on success. + + STATUS_SUCCESS or error code. + + + + + Finds a reparse point in file name. + + + This is a helper for implementing the GetSecurityByName operation in file systems + that support reparse points. + + + The name of the file or directory. + + + Receives the index of the first reparse point within FileName. + + True if a reparse point was found, false otherwise. + + + + + Makes a byte array that contains a reparse point. + + The reparse point byte array. + + + + Gets the reparse tag from reparse data. + + + The reparse data to extract the reparse tag from. + + The reparse tag. + + + + Tests whether reparse data can be replaced. + + + This is a helper for implementing the SetReparsePoint/DeleteReparsePoint operation + in file systems that support reparse points. + + + The current reparse data. + + + The replacement reparse data. + + STATUS_SUCCESS or error code. + + + + + + Provides a means to host (mount) a file system. + + + + + Creates an instance of the FileSystemHost class. + + The file system to host. + + + + Unmounts the file system and releases all associated resources. + + + + + Gets or sets the sector size used by the file system. + + + + + Gets or sets the sectors per allocation unit used by the file system. + + + + + Gets or sets the maximum path component length used by the file system. + + + + + Gets or sets the volume creation time. + + + + + Gets or sets the volume serial number. + + + + + Gets or sets the file information timeout. + + + + + Gets or sets the volume information timeout. + + + + + Gets or sets the directory information timeout. + + + + + Gets or sets the security information timeout. + + + + + Gets or sets the stream information timeout. + + + + + Gets or sets the EA information timeout. + + + + + Gets or sets a value that determines whether the file system is case sensitive. + + + + + Gets or sets a value that determines whether a case insensitive file system + preserves case in file names. + + + + + Gets or sets a value that determines whether file names support unicode characters. + + + + + Gets or sets a value that determines whether the file system supports ACL security. + + + + + Gets or sets a value that determines whether the file system supports reparse points. + + + + + Gets or sets a value that determines whether the file system allows creation of + symbolic links without additional privileges. + + + + + Gets or sets a value that determines whether the file system supports named streams. + + + + + Gets or sets a value that determines whether the file system supports extended attributes. + + + + + Gets or sets the prefix for a network file system. + + + + + Gets or sets the file system name. + + + + + Checks whether mounting a file system is possible. + + + The mount point for the new file system. A value of null means that + the file system should use the next available drive letter counting + downwards from Z: as its mount point. + + STATUS_SUCCESS or error code. + + + + Mounts a file system. + + + The mount point for the new file system. A value of null means that + the file system should use the next available drive letter counting + downwards from Z: as its mount point. + + + Security descriptor to use if mounting on (newly created) directory. + A value of null means the directory should be created with default + security. + + + If true file system operations are synchronized using an exclusive lock. + + + A value of 0 disables all debug logging. + A value of -1 enables all debug logging. + + STATUS_SUCCESS or error code. + + + + Mounts a file system. + + + The mount point for the new file system. A value of null means that + the file system should use the next available drive letter counting + downwards from Z: as its mount point. + + + Number of threads to use to service file system requests. A value + of 0 means that the default number of threads should be used. + + + Security descriptor to use if mounting on (newly created) directory. + A value of null means the directory should be created with default + security. + + + If true file system operations are synchronized using an exclusive lock. + + + A value of 0 disables all debug logging. + A value of -1 enables all debug logging. + + STATUS_SUCCESS or error code. + + + + Unmounts the file system and releases all associated resources. + + + + + Gets the file system mount point. + + The file system mount point. + + + + Gets the hosted file system. + + The hosted file system. + + + + Sets the debug log file to use when debug logging is enabled. + + + The debug log file name. A value of "-" means standard error output. + + STATUS_SUCCESS or error code. + + + + Return the installed version of WinFsp. + + + + + Returns a RequestHint to reference the current operation asynchronously. + + + + + Asynchronously complete a Read operation. + + + A reference to the operation to complete. + + + STATUS_SUCCESS or error code. + + + Number of bytes read. + + + + + Asynchronously complete a Write operation. + + + A reference to the operation to complete. + + + STATUS_SUCCESS or error code. + + + The number of bytes written. + + + Updated file information. + + + + + Asynchronously complete a ReadDirectory operation. + + + A reference to the operation to complete. + + + STATUS_SUCCESS or error code. + + + Number of bytes read. + + + + + Begin notifying Windows that the file system has file changes. + + + + A file system that wishes to notify Windows about file changes must + first issue an FspFileSystemBegin call, followed by 0 or more + FspFileSystemNotify calls, followed by an FspFileSystemNotifyEnd call. + + This operation blocks concurrent file rename operations. File rename + operations may interfere with file notification, because a file being + notified may also be concurrently renamed. After all file change + notifications have been issued, you must make sure to call + FspFileSystemNotifyEnd to allow file rename operations to proceed. + + + + STATUS_SUCCESS or error code. The error code STATUS_CANT_WAIT means that + a file rename operation is currently in progress and the operation must be + retried at a later time. + + + + + End notifying Windows that the file system has file changes. + + + + A file system that wishes to notify Windows about file changes must + first issue an FspFileSystemBegin call, followed by 0 or more + FspFileSystemNotify calls, followed by an FspFileSystemNotifyEnd call. + + This operation allows any blocked file rename operations to proceed. + + + STATUS_SUCCESS or error code. + + + + Notify Windows that the file system has file changes. + + + + A file system that wishes to notify Windows about file changes must + first issue an FspFileSystemBegin call, followed by 0 or more + FspFileSystemNotify calls, followed by an FspFileSystemNotifyEnd call. + + Note that FspFileSystemNotify requires file names to be normalized. A + normalized file name is one that contains the correct case of all characters + in the file name. + + For case-sensitive file systems all file names are normalized by definition. + For case-insensitive file systems that implement file name normalization, + a normalized file name is the one that the file system specifies in the + response to Create or Open (see also FspFileSystemGetOpenFileInfo). For + case-insensitive file systems that do not implement file name normalization + a normalized file name is the upper case version of the file name used + to open the file. + + + STATUS_SUCCESS or error code. + + + + Contains volume information about a file system. + + + + + Total size of volume in bytes. + + + + + Free size of volume in bytes. + + + + + Sets the volume label. + + + + + Contains metadata information about a file or directory. + + + + + The file or directory attributes. + + + + + The reparse tag of the file or directory. + This value is 0 if the file or directory is not a reparse point. + + + + + The allocation size of the file. + + + + + The file size of the file (end of file). + + + + + The time that the file or directory was created. + + + + + The time that the file or directory was last accessed. + + + + + The time that the file or direcotry was last modified. + + + + + The time that the file or directory metadata was last modified. + + + + + A unique identifier that is associated with the file or directory. + Not all file systems support this value. + + + + + The number of hard links. + Not currently implemented. Set to 0. + + + + + The extended attribute size of the file. + + + + + Enumeration of all the possible values for NotifyInfo.Action + + + + + Enumeration of all the possible values for NotifyInfo.Filter + + + + + Contains file change notification information. + + + + + Provides the base class for a process that can be run as a service, + command line application or under the control of the WinFsp launcher. + + + + + Creates an instance of the Service class. + + The name of the service. + + + + Runs a service. + + Service process exit code. + + + + Stops a running service. + + + + + Gets or sets the service process exit code. + + + + + Provides a means to customize the returned status code when an exception happens. + + + STATUS_SUCCESS or error code. + + + + Occurs when the service starts. + + Command line arguments passed to the service. + + + + Occurs when the service stops. + + + + diff --git a/support/3rd_party/winfsp-2.1/bin/winfsp-x64.dll b/support/3rd_party/winfsp-2.1/bin/winfsp-x64.dll new file mode 100644 index 00000000..2ab0e8f5 Binary files /dev/null and b/support/3rd_party/winfsp-2.1/bin/winfsp-x64.dll differ diff --git a/support/3rd_party/winfsp-2.1/bin/winfsp-x64.sys b/support/3rd_party/winfsp-2.1/bin/winfsp-x64.sys new file mode 100644 index 00000000..863f00d8 Binary files /dev/null and b/support/3rd_party/winfsp-2.1/bin/winfsp-x64.sys differ diff --git a/support/3rd_party/winfsp-2.1/bin/winfsp-x86.dll b/support/3rd_party/winfsp-2.1/bin/winfsp-x86.dll new file mode 100644 index 00000000..d54fe3a8 Binary files /dev/null and b/support/3rd_party/winfsp-2.1/bin/winfsp-x86.dll differ diff --git a/support/3rd_party/winfsp-2.0/bin/winfsp-x86.sys b/support/3rd_party/winfsp-2.1/bin/winfsp-x86.sys similarity index 53% rename from support/3rd_party/winfsp-2.0/bin/winfsp-x86.sys rename to support/3rd_party/winfsp-2.1/bin/winfsp-x86.sys index 1bb5e01c..6176ff7e 100644 Binary files a/support/3rd_party/winfsp-2.0/bin/winfsp-x86.sys and b/support/3rd_party/winfsp-2.1/bin/winfsp-x86.sys differ diff --git a/support/3rd_party/winfsp-2.0/inc/fuse/fuse.h b/support/3rd_party/winfsp-2.1/inc/fuse/fuse.h similarity index 96% rename from support/3rd_party/winfsp-2.0/inc/fuse/fuse.h rename to support/3rd_party/winfsp-2.1/inc/fuse/fuse.h index 6807cd60..e84d656b 100644 --- a/support/3rd_party/winfsp-2.0/inc/fuse/fuse.h +++ b/support/3rd_party/winfsp-2.1/inc/fuse/fuse.h @@ -1,271 +1,271 @@ -/** - * @file fuse/fuse.h - * WinFsp FUSE compatible API. - * - * This file is derived from libfuse/include/fuse.h: - * FUSE: Filesystem in Userspace - * Copyright (C) 2001-2007 Miklos Szeredi - * - * @copyright 2015-2022 Bill Zissimopoulos - */ -/* - * This file is part of WinFsp. - * - * You can redistribute it and/or modify it under the terms of the GNU - * General Public License version 3 as published by the Free Software - * Foundation. - * - * Licensees holding a valid commercial license may use this software - * in accordance with the commercial license agreement provided in - * conjunction with the software. The terms and conditions of any such - * commercial license agreement shall govern, supersede, and render - * ineffective any application of the GPLv3 license to this software, - * notwithstanding of any reference thereto in the software or - * associated repository. - */ - -#ifndef FUSE_H_ -#define FUSE_H_ - -#include "fuse_common.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct fuse; - -typedef int (*fuse_fill_dir_t)(void *buf, const char *name, - const struct fuse_stat *stbuf, fuse_off_t off); -typedef struct fuse_dirhandle *fuse_dirh_t; -typedef int (*fuse_dirfil_t)(fuse_dirh_t h, const char *name, - int type, fuse_ino_t ino); - -struct fuse_operations -{ - /* S - supported by WinFsp */ - /* S */ int (*getattr)(const char *path, struct fuse_stat *stbuf); - /* S */ int (*getdir)(const char *path, fuse_dirh_t h, fuse_dirfil_t filler); - /* S */ int (*readlink)(const char *path, char *buf, size_t size); - /* S */ int (*mknod)(const char *path, fuse_mode_t mode, fuse_dev_t dev); - /* S */ int (*mkdir)(const char *path, fuse_mode_t mode); - /* S */ int (*unlink)(const char *path); - /* S */ int (*rmdir)(const char *path); - /* S */ int (*symlink)(const char *dstpath, const char *srcpath); - /* S */ int (*rename)(const char *oldpath, const char *newpath); - /* _ */ int (*link)(const char *srcpath, const char *dstpath); - /* S */ int (*chmod)(const char *path, fuse_mode_t mode); - /* S */ int (*chown)(const char *path, fuse_uid_t uid, fuse_gid_t gid); - /* S */ int (*truncate)(const char *path, fuse_off_t size); - /* S */ int (*utime)(const char *path, struct fuse_utimbuf *timbuf); - /* S */ int (*open)(const char *path, struct fuse_file_info *fi); - /* S */ int (*read)(const char *path, char *buf, size_t size, fuse_off_t off, - struct fuse_file_info *fi); - /* S */ int (*write)(const char *path, const char *buf, size_t size, fuse_off_t off, - struct fuse_file_info *fi); - /* S */ int (*statfs)(const char *path, struct fuse_statvfs *stbuf); - /* S */ int (*flush)(const char *path, struct fuse_file_info *fi); - /* S */ int (*release)(const char *path, struct fuse_file_info *fi); - /* S */ int (*fsync)(const char *path, int datasync, struct fuse_file_info *fi); - /* S */ int (*setxattr)(const char *path, const char *name, const char *value, size_t size, - int flags); - /* S */ int (*getxattr)(const char *path, const char *name, char *value, size_t size); - /* S */ int (*listxattr)(const char *path, char *namebuf, size_t size); - /* S */ int (*removexattr)(const char *path, const char *name); - /* S */ int (*opendir)(const char *path, struct fuse_file_info *fi); - /* S */ int (*readdir)(const char *path, void *buf, fuse_fill_dir_t filler, fuse_off_t off, - struct fuse_file_info *fi); - /* S */ int (*releasedir)(const char *path, struct fuse_file_info *fi); - /* S */ int (*fsyncdir)(const char *path, int datasync, struct fuse_file_info *fi); - /* S */ void *(*init)(struct fuse_conn_info *conn); - /* S */ void (*destroy)(void *data); - /* S */ int (*access)(const char *path, int mask); - /* S */ int (*create)(const char *path, fuse_mode_t mode, struct fuse_file_info *fi); - /* S */ int (*ftruncate)(const char *path, fuse_off_t off, struct fuse_file_info *fi); - /* S */ int (*fgetattr)(const char *path, struct fuse_stat *stbuf, struct fuse_file_info *fi); - /* _ */ int (*lock)(const char *path, - struct fuse_file_info *fi, int cmd, struct fuse_flock *lock); - /* S */ int (*utimens)(const char *path, const struct fuse_timespec tv[2]); - /* _ */ int (*bmap)(const char *path, size_t blocksize, uint64_t *idx); - /* _ */ unsigned int flag_nullpath_ok:1; - /* _ */ unsigned int flag_nopath:1; - /* _ */ unsigned int flag_utime_omit_ok:1; - /* _ */ unsigned int flag_reserved:29; - /* S */ int (*ioctl)(const char *path, int cmd, void *arg, struct fuse_file_info *fi, - unsigned int flags, void *data); - /* _ */ int (*poll)(const char *path, struct fuse_file_info *fi, - struct fuse_pollhandle *ph, unsigned *reventsp); - /* FUSE 2.9 */ - /* _ */ int (*write_buf)(const char *path, - struct fuse_bufvec *buf, fuse_off_t off, struct fuse_file_info *fi); - /* _ */ int (*read_buf)(const char *path, - struct fuse_bufvec **bufp, size_t size, fuse_off_t off, struct fuse_file_info *fi); - /* _ */ int (*flock)(const char *path, struct fuse_file_info *, int op); - /* _ */ int (*fallocate)(const char *path, int mode, fuse_off_t off, fuse_off_t len, - struct fuse_file_info *fi); - /* WinFsp */ - /* S */ int (*getpath)(const char *path, char *buf, size_t size, - struct fuse_file_info *fi); - /* OSXFUSE */ - /* _ */ int (*reserved01)(); - /* _ */ int (*reserved02)(); - /* _ */ int (*statfs_x)(const char *path, struct fuse_statfs *stbuf); - /* _ */ int (*setvolname)(const char *volname); - /* _ */ int (*exchange)(const char *oldpath, const char *newpath, unsigned long flags); - /* _ */ int (*getxtimes)(const char *path, - struct fuse_timespec *bkuptime, struct fuse_timespec *crtime); - /* _ */ int (*setbkuptime)(const char *path, const struct fuse_timespec *tv); - /* S */ int (*setchgtime)(const char *path, const struct fuse_timespec *tv); - /* S */ int (*setcrtime)(const char *path, const struct fuse_timespec *tv); - /* S */ int (*chflags)(const char *path, uint32_t flags); - /* _ */ int (*setattr_x)(const char *path, struct fuse_setattr_x *attr); - /* _ */ int (*fsetattr_x)(const char *path, struct fuse_setattr_x *attr, - struct fuse_file_info *fi); -}; - -struct fuse_context -{ - struct fuse *fuse; - fuse_uid_t uid; - fuse_gid_t gid; - fuse_pid_t pid; - void *private_data; - fuse_mode_t umask; -}; - -#define fuse_main(argc, argv, ops, data)\ - fuse_main_real(argc, argv, ops, sizeof *(ops), data) - -FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse_main_real)(struct fsp_fuse_env *env, - int argc, char *argv[], - const struct fuse_operations *ops, size_t opsize, void *data); -FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse_is_lib_option)(struct fsp_fuse_env *env, - const char *opt); -FSP_FUSE_API struct fuse *FSP_FUSE_API_NAME(fsp_fuse_new)(struct fsp_fuse_env *env, - struct fuse_chan *ch, struct fuse_args *args, - const struct fuse_operations *ops, size_t opsize, void *data); -FSP_FUSE_API void FSP_FUSE_API_NAME(fsp_fuse_destroy)(struct fsp_fuse_env *env, - struct fuse *f); -FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse_loop)(struct fsp_fuse_env *env, - struct fuse *f); -FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse_loop_mt)(struct fsp_fuse_env *env, - struct fuse *f); -FSP_FUSE_API void FSP_FUSE_API_NAME(fsp_fuse_exit)(struct fsp_fuse_env *env, - struct fuse *f); -FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse_exited)(struct fsp_fuse_env *env, - struct fuse *f); -FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse_notify)(struct fsp_fuse_env *env, - struct fuse *f, const char *path, uint32_t action); -FSP_FUSE_API struct fuse_context *FSP_FUSE_API_NAME(fsp_fuse_get_context)(struct fsp_fuse_env *env); - -FSP_FUSE_SYM( -int fuse_main_real(int argc, char *argv[], - const struct fuse_operations *ops, size_t opsize, void *data), -{ - return FSP_FUSE_API_CALL(fsp_fuse_main_real) - (fsp_fuse_env(), argc, argv, ops, opsize, data); -}) - -FSP_FUSE_SYM( -int fuse_is_lib_option(const char *opt), -{ - return FSP_FUSE_API_CALL(fsp_fuse_is_lib_option) - (fsp_fuse_env(), opt); -}) - -FSP_FUSE_SYM( -struct fuse *fuse_new(struct fuse_chan *ch, struct fuse_args *args, - const struct fuse_operations *ops, size_t opsize, void *data), -{ - return FSP_FUSE_API_CALL(fsp_fuse_new) - (fsp_fuse_env(), ch, args, ops, opsize, data); -}) - -FSP_FUSE_SYM( -void fuse_destroy(struct fuse *f), -{ - FSP_FUSE_API_CALL(fsp_fuse_destroy) - (fsp_fuse_env(), f); -}) - -FSP_FUSE_SYM( -int fuse_loop(struct fuse *f), -{ - return FSP_FUSE_API_CALL(fsp_fuse_loop) - (fsp_fuse_env(), f); -}) - -FSP_FUSE_SYM( -int fuse_loop_mt(struct fuse *f), -{ - return FSP_FUSE_API_CALL(fsp_fuse_loop_mt) - (fsp_fuse_env(), f); -}) - -FSP_FUSE_SYM( -void fuse_exit(struct fuse *f), -{ - FSP_FUSE_API_CALL(fsp_fuse_exit) - (fsp_fuse_env(), f); -}) - -FSP_FUSE_SYM( -int fuse_exited(struct fuse *f), -{ - return FSP_FUSE_API_CALL(fsp_fuse_exited) - (fsp_fuse_env(), f); -}) - -FSP_FUSE_SYM( -int fuse_notify(struct fuse *f, const char *path, uint32_t action), -{ - return FSP_FUSE_API_CALL(fsp_fuse_notify) - (fsp_fuse_env(), f, path, action); -}) - -FSP_FUSE_SYM( -struct fuse_context *fuse_get_context(void), -{ - return FSP_FUSE_API_CALL(fsp_fuse_get_context) - (fsp_fuse_env()); -}) - -FSP_FUSE_SYM( -int fuse_getgroups(int size, fuse_gid_t list[]), -{ - (void)size; - (void)list; - return -ENOSYS; -}) - -FSP_FUSE_SYM( -int fuse_interrupted(void), -{ - return 0; -}) - -FSP_FUSE_SYM( -int fuse_invalidate(struct fuse *f, const char *path), -{ - return FSP_FUSE_API_CALL(fsp_fuse_notify) - (fsp_fuse_env(), f, path, 0); -}) - -FSP_FUSE_SYM( -int fuse_notify_poll(struct fuse_pollhandle *ph), -{ - (void)ph; - return 0; -}) - -FSP_FUSE_SYM( -struct fuse_session *fuse_get_session(struct fuse *f), -{ - return (struct fuse_session *)f; -}) - -#ifdef __cplusplus -} -#endif - -#endif +/** + * @file fuse/fuse.h + * WinFsp FUSE compatible API. + * + * This file is derived from libfuse/include/fuse.h: + * FUSE: Filesystem in Userspace + * Copyright (C) 2001-2007 Miklos Szeredi + * + * @copyright 2015-2025 Bill Zissimopoulos + */ +/* + * This file is part of WinFsp. + * + * You can redistribute it and/or modify it under the terms of the GNU + * General Public License version 3 as published by the Free Software + * Foundation. + * + * Licensees holding a valid commercial license may use this software + * in accordance with the commercial license agreement provided in + * conjunction with the software. The terms and conditions of any such + * commercial license agreement shall govern, supersede, and render + * ineffective any application of the GPLv3 license to this software, + * notwithstanding of any reference thereto in the software or + * associated repository. + */ + +#ifndef FUSE_H_ +#define FUSE_H_ + +#include "fuse_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct fuse; + +typedef int (*fuse_fill_dir_t)(void *buf, const char *name, + const struct fuse_stat *stbuf, fuse_off_t off); +typedef struct fuse_dirhandle *fuse_dirh_t; +typedef int (*fuse_dirfil_t)(fuse_dirh_t h, const char *name, + int type, fuse_ino_t ino); + +struct fuse_operations +{ + /* S - supported by WinFsp */ + /* S */ int (*getattr)(const char *path, struct fuse_stat *stbuf); + /* S */ int (*getdir)(const char *path, fuse_dirh_t h, fuse_dirfil_t filler); + /* S */ int (*readlink)(const char *path, char *buf, size_t size); + /* S */ int (*mknod)(const char *path, fuse_mode_t mode, fuse_dev_t dev); + /* S */ int (*mkdir)(const char *path, fuse_mode_t mode); + /* S */ int (*unlink)(const char *path); + /* S */ int (*rmdir)(const char *path); + /* S */ int (*symlink)(const char *dstpath, const char *srcpath); + /* S */ int (*rename)(const char *oldpath, const char *newpath); + /* _ */ int (*link)(const char *srcpath, const char *dstpath); + /* S */ int (*chmod)(const char *path, fuse_mode_t mode); + /* S */ int (*chown)(const char *path, fuse_uid_t uid, fuse_gid_t gid); + /* S */ int (*truncate)(const char *path, fuse_off_t size); + /* S */ int (*utime)(const char *path, struct fuse_utimbuf *timbuf); + /* S */ int (*open)(const char *path, struct fuse_file_info *fi); + /* S */ int (*read)(const char *path, char *buf, size_t size, fuse_off_t off, + struct fuse_file_info *fi); + /* S */ int (*write)(const char *path, const char *buf, size_t size, fuse_off_t off, + struct fuse_file_info *fi); + /* S */ int (*statfs)(const char *path, struct fuse_statvfs *stbuf); + /* S */ int (*flush)(const char *path, struct fuse_file_info *fi); + /* S */ int (*release)(const char *path, struct fuse_file_info *fi); + /* S */ int (*fsync)(const char *path, int datasync, struct fuse_file_info *fi); + /* S */ int (*setxattr)(const char *path, const char *name, const char *value, size_t size, + int flags); + /* S */ int (*getxattr)(const char *path, const char *name, char *value, size_t size); + /* S */ int (*listxattr)(const char *path, char *namebuf, size_t size); + /* S */ int (*removexattr)(const char *path, const char *name); + /* S */ int (*opendir)(const char *path, struct fuse_file_info *fi); + /* S */ int (*readdir)(const char *path, void *buf, fuse_fill_dir_t filler, fuse_off_t off, + struct fuse_file_info *fi); + /* S */ int (*releasedir)(const char *path, struct fuse_file_info *fi); + /* S */ int (*fsyncdir)(const char *path, int datasync, struct fuse_file_info *fi); + /* S */ void *(*init)(struct fuse_conn_info *conn); + /* S */ void (*destroy)(void *data); + /* S */ int (*access)(const char *path, int mask); + /* S */ int (*create)(const char *path, fuse_mode_t mode, struct fuse_file_info *fi); + /* S */ int (*ftruncate)(const char *path, fuse_off_t off, struct fuse_file_info *fi); + /* S */ int (*fgetattr)(const char *path, struct fuse_stat *stbuf, struct fuse_file_info *fi); + /* _ */ int (*lock)(const char *path, + struct fuse_file_info *fi, int cmd, struct fuse_flock *lock); + /* S */ int (*utimens)(const char *path, const struct fuse_timespec tv[2]); + /* _ */ int (*bmap)(const char *path, size_t blocksize, uint64_t *idx); + /* _ */ unsigned int flag_nullpath_ok:1; + /* _ */ unsigned int flag_nopath:1; + /* _ */ unsigned int flag_utime_omit_ok:1; + /* _ */ unsigned int flag_reserved:29; + /* S */ int (*ioctl)(const char *path, int cmd, void *arg, struct fuse_file_info *fi, + unsigned int flags, void *data); + /* _ */ int (*poll)(const char *path, struct fuse_file_info *fi, + struct fuse_pollhandle *ph, unsigned *reventsp); + /* FUSE 2.9 */ + /* _ */ int (*write_buf)(const char *path, + struct fuse_bufvec *buf, fuse_off_t off, struct fuse_file_info *fi); + /* _ */ int (*read_buf)(const char *path, + struct fuse_bufvec **bufp, size_t size, fuse_off_t off, struct fuse_file_info *fi); + /* _ */ int (*flock)(const char *path, struct fuse_file_info *, int op); + /* _ */ int (*fallocate)(const char *path, int mode, fuse_off_t off, fuse_off_t len, + struct fuse_file_info *fi); + /* WinFsp */ + /* S */ int (*getpath)(const char *path, char *buf, size_t size, + struct fuse_file_info *fi); + /* OSXFUSE */ + /* _ */ int (*reserved01)(); + /* _ */ int (*reserved02)(); + /* _ */ int (*statfs_x)(const char *path, struct fuse_statfs *stbuf); + /* _ */ int (*setvolname)(const char *volname); + /* _ */ int (*exchange)(const char *oldpath, const char *newpath, unsigned long flags); + /* _ */ int (*getxtimes)(const char *path, + struct fuse_timespec *bkuptime, struct fuse_timespec *crtime); + /* _ */ int (*setbkuptime)(const char *path, const struct fuse_timespec *tv); + /* S */ int (*setchgtime)(const char *path, const struct fuse_timespec *tv); + /* S */ int (*setcrtime)(const char *path, const struct fuse_timespec *tv); + /* S */ int (*chflags)(const char *path, uint32_t flags); + /* _ */ int (*setattr_x)(const char *path, struct fuse_setattr_x *attr); + /* _ */ int (*fsetattr_x)(const char *path, struct fuse_setattr_x *attr, + struct fuse_file_info *fi); +}; + +struct fuse_context +{ + struct fuse *fuse; + fuse_uid_t uid; + fuse_gid_t gid; + fuse_pid_t pid; + void *private_data; + fuse_mode_t umask; +}; + +#define fuse_main(argc, argv, ops, data)\ + fuse_main_real(argc, argv, ops, sizeof *(ops), data) + +FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse_main_real)(struct fsp_fuse_env *env, + int argc, char *argv[], + const struct fuse_operations *ops, size_t opsize, void *data); +FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse_is_lib_option)(struct fsp_fuse_env *env, + const char *opt); +FSP_FUSE_API struct fuse *FSP_FUSE_API_NAME(fsp_fuse_new)(struct fsp_fuse_env *env, + struct fuse_chan *ch, struct fuse_args *args, + const struct fuse_operations *ops, size_t opsize, void *data); +FSP_FUSE_API void FSP_FUSE_API_NAME(fsp_fuse_destroy)(struct fsp_fuse_env *env, + struct fuse *f); +FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse_loop)(struct fsp_fuse_env *env, + struct fuse *f); +FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse_loop_mt)(struct fsp_fuse_env *env, + struct fuse *f); +FSP_FUSE_API void FSP_FUSE_API_NAME(fsp_fuse_exit)(struct fsp_fuse_env *env, + struct fuse *f); +FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse_exited)(struct fsp_fuse_env *env, + struct fuse *f); +FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse_notify)(struct fsp_fuse_env *env, + struct fuse *f, const char *path, uint32_t action); +FSP_FUSE_API struct fuse_context *FSP_FUSE_API_NAME(fsp_fuse_get_context)(struct fsp_fuse_env *env); + +FSP_FUSE_SYM( +int fuse_main_real(int argc, char *argv[], + const struct fuse_operations *ops, size_t opsize, void *data), +{ + return FSP_FUSE_API_CALL(fsp_fuse_main_real) + (fsp_fuse_env(), argc, argv, ops, opsize, data); +}) + +FSP_FUSE_SYM( +int fuse_is_lib_option(const char *opt), +{ + return FSP_FUSE_API_CALL(fsp_fuse_is_lib_option) + (fsp_fuse_env(), opt); +}) + +FSP_FUSE_SYM( +struct fuse *fuse_new(struct fuse_chan *ch, struct fuse_args *args, + const struct fuse_operations *ops, size_t opsize, void *data), +{ + return FSP_FUSE_API_CALL(fsp_fuse_new) + (fsp_fuse_env(), ch, args, ops, opsize, data); +}) + +FSP_FUSE_SYM( +void fuse_destroy(struct fuse *f), +{ + FSP_FUSE_API_CALL(fsp_fuse_destroy) + (fsp_fuse_env(), f); +}) + +FSP_FUSE_SYM( +int fuse_loop(struct fuse *f), +{ + return FSP_FUSE_API_CALL(fsp_fuse_loop) + (fsp_fuse_env(), f); +}) + +FSP_FUSE_SYM( +int fuse_loop_mt(struct fuse *f), +{ + return FSP_FUSE_API_CALL(fsp_fuse_loop_mt) + (fsp_fuse_env(), f); +}) + +FSP_FUSE_SYM( +void fuse_exit(struct fuse *f), +{ + FSP_FUSE_API_CALL(fsp_fuse_exit) + (fsp_fuse_env(), f); +}) + +FSP_FUSE_SYM( +int fuse_exited(struct fuse *f), +{ + return FSP_FUSE_API_CALL(fsp_fuse_exited) + (fsp_fuse_env(), f); +}) + +FSP_FUSE_SYM( +int fuse_notify(struct fuse *f, const char *path, uint32_t action), +{ + return FSP_FUSE_API_CALL(fsp_fuse_notify) + (fsp_fuse_env(), f, path, action); +}) + +FSP_FUSE_SYM( +struct fuse_context *fuse_get_context(void), +{ + return FSP_FUSE_API_CALL(fsp_fuse_get_context) + (fsp_fuse_env()); +}) + +FSP_FUSE_SYM( +int fuse_getgroups(int size, fuse_gid_t list[]), +{ + (void)size; + (void)list; + return -ENOSYS; +}) + +FSP_FUSE_SYM( +int fuse_interrupted(void), +{ + return 0; +}) + +FSP_FUSE_SYM( +int fuse_invalidate(struct fuse *f, const char *path), +{ + return FSP_FUSE_API_CALL(fsp_fuse_notify) + (fsp_fuse_env(), f, path, 0); +}) + +FSP_FUSE_SYM( +int fuse_notify_poll(struct fuse_pollhandle *ph), +{ + (void)ph; + return 0; +}) + +FSP_FUSE_SYM( +struct fuse_session *fuse_get_session(struct fuse *f), +{ + return (struct fuse_session *)f; +}) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/support/3rd_party/winfsp-2.0/inc/fuse/fuse_common.h b/support/3rd_party/winfsp-2.1/inc/fuse/fuse_common.h similarity index 96% rename from support/3rd_party/winfsp-2.0/inc/fuse/fuse_common.h rename to support/3rd_party/winfsp-2.1/inc/fuse/fuse_common.h index 5daa7a41..6c6e7e5f 100644 --- a/support/3rd_party/winfsp-2.0/inc/fuse/fuse_common.h +++ b/support/3rd_party/winfsp-2.1/inc/fuse/fuse_common.h @@ -1,202 +1,202 @@ -/** - * @file fuse/fuse_common.h - * WinFsp FUSE compatible API. - * - * This file is derived from libfuse/include/fuse_common.h: - * FUSE: Filesystem in Userspace - * Copyright (C) 2001-2007 Miklos Szeredi - * - * @copyright 2015-2022 Bill Zissimopoulos - */ -/* - * This file is part of WinFsp. - * - * You can redistribute it and/or modify it under the terms of the GNU - * General Public License version 3 as published by the Free Software - * Foundation. - * - * Licensees holding a valid commercial license may use this software - * in accordance with the commercial license agreement provided in - * conjunction with the software. The terms and conditions of any such - * commercial license agreement shall govern, supersede, and render - * ineffective any application of the GPLv3 license to this software, - * notwithstanding of any reference thereto in the software or - * associated repository. - */ - -#ifndef FUSE_COMMON_H_ -#define FUSE_COMMON_H_ - -#include "winfsp_fuse.h" -#include "fuse_opt.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define FUSE_MAJOR_VERSION 2 -#define FUSE_MINOR_VERSION 8 -#define FUSE_MAKE_VERSION(maj, min) ((maj) * 10 + (min)) -#define FUSE_VERSION FUSE_MAKE_VERSION(FUSE_MAJOR_VERSION, FUSE_MINOR_VERSION) - -#define FUSE_CAP_ASYNC_READ (1 << 0) -#define FUSE_CAP_POSIX_LOCKS (1 << 1) -#define FUSE_CAP_ATOMIC_O_TRUNC (1 << 3) -#define FUSE_CAP_EXPORT_SUPPORT (1 << 4) -#define FUSE_CAP_BIG_WRITES (1 << 5) -#define FUSE_CAP_DONT_MASK (1 << 6) -#define FUSE_CAP_ALLOCATE (1 << 27) /* reserved (OSXFUSE) */ -#define FUSE_CAP_EXCHANGE_DATA (1 << 28) /* reserved (OSXFUSE) */ -#define FUSE_CAP_CASE_INSENSITIVE (1 << 29) /* file system is case insensitive */ -#define FUSE_CAP_VOL_RENAME (1 << 30) /* reserved (OSXFUSE) */ -#define FUSE_CAP_XTIMES (1 << 31) /* reserved (OSXFUSE) */ - -#define FSP_FUSE_CAP_READDIR_PLUS (1 << 21) /* file system supports enhanced readdir */ -#define FSP_FUSE_CAP_READ_ONLY (1 << 22) /* file system is marked read-only */ -#define FSP_FUSE_CAP_STAT_EX (1 << 23) /* file system supports fuse_stat_ex */ -#define FSP_FUSE_CAP_DELETE_ACCESS (1 << 24) /* file system supports access with DELETE_OK */ -#define FSP_FUSE_CAP_CASE_INSENSITIVE FUSE_CAP_CASE_INSENSITIVE - -#define FUSE_IOCTL_COMPAT (1 << 0) -#define FUSE_IOCTL_UNRESTRICTED (1 << 1) -#define FUSE_IOCTL_RETRY (1 << 2) -#define FUSE_IOCTL_MAX_IOV 256 - -/* from FreeBSD */ -#define FSP_FUSE_UF_HIDDEN 0x00008000 -#define FSP_FUSE_UF_READONLY 0x00001000 -#define FSP_FUSE_UF_SYSTEM 0x00000080 -#define FSP_FUSE_UF_ARCHIVE 0x00000800 -#if !defined(UF_HIDDEN) -#define UF_HIDDEN FSP_FUSE_UF_HIDDEN -#endif -#if !defined(UF_READONLY) -#define UF_READONLY FSP_FUSE_UF_READONLY -#endif -#if !defined(UF_SYSTEM) -#define UF_SYSTEM FSP_FUSE_UF_SYSTEM -#endif -#if !defined(UF_ARCHIVE) -#define UF_ARCHIVE FSP_FUSE_UF_ARCHIVE -#endif - -/* delete access */ -#define FSP_FUSE_DELETE_OK 0x40000000 - -/* notify extension */ -#define FSP_FUSE_NOTIFY_MKDIR 0x0001 -#define FSP_FUSE_NOTIFY_RMDIR 0x0002 -#define FSP_FUSE_NOTIFY_CREATE 0x0004 -#define FSP_FUSE_NOTIFY_UNLINK 0x0008 -#define FSP_FUSE_NOTIFY_CHMOD 0x0010 -#define FSP_FUSE_NOTIFY_CHOWN 0x0020 -#define FSP_FUSE_NOTIFY_UTIME 0x0040 -#define FSP_FUSE_NOTIFY_CHFLAGS 0x0080 -#define FSP_FUSE_NOTIFY_TRUNCATE 0x0100 - -/* getpath extension */ -#define FSP_FUSE_HAS_GETPATH 1 - -struct fuse_file_info -{ - int flags; - unsigned int fh_old; - int writepage; - unsigned int direct_io:1; - unsigned int keep_cache:1; - unsigned int flush:1; - unsigned int nonseekable:1; - unsigned int padding:28; - uint64_t fh; - uint64_t lock_owner; -}; - -struct fuse_conn_info -{ - unsigned proto_major; - unsigned proto_minor; - unsigned async_read; - unsigned max_write; - unsigned max_readahead; - unsigned capable; - unsigned want; - unsigned reserved[25]; -}; - -struct fuse_session; -struct fuse_chan; -struct fuse_pollhandle; -struct fuse_bufvec; -struct fuse_statfs; -struct fuse_setattr_x; - -FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse_version)(struct fsp_fuse_env *env); -FSP_FUSE_API struct fuse_chan *FSP_FUSE_API_NAME(fsp_fuse_mount)(struct fsp_fuse_env *env, - const char *mountpoint, struct fuse_args *args); -FSP_FUSE_API void FSP_FUSE_API_NAME(fsp_fuse_unmount)(struct fsp_fuse_env *env, - const char *mountpoint, struct fuse_chan *ch); -FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse_parse_cmdline)(struct fsp_fuse_env *env, - struct fuse_args *args, - char **mountpoint, int *multithreaded, int *foreground); -FSP_FUSE_API int32_t FSP_FUSE_API_NAME(fsp_fuse_ntstatus_from_errno)(struct fsp_fuse_env *env, - int err); - -FSP_FUSE_SYM( -int fuse_version(void), -{ - return FSP_FUSE_API_CALL(fsp_fuse_version) - (fsp_fuse_env()); -}) - -FSP_FUSE_SYM( -struct fuse_chan *fuse_mount(const char *mountpoint, struct fuse_args *args), -{ - return FSP_FUSE_API_CALL(fsp_fuse_mount) - (fsp_fuse_env(), mountpoint, args); -}) - -FSP_FUSE_SYM( -void fuse_unmount(const char *mountpoint, struct fuse_chan *ch), -{ - FSP_FUSE_API_CALL(fsp_fuse_unmount) - (fsp_fuse_env(), mountpoint, ch); -}) - -FSP_FUSE_SYM( -int fuse_parse_cmdline(struct fuse_args *args, - char **mountpoint, int *multithreaded, int *foreground), -{ - return FSP_FUSE_API_CALL(fsp_fuse_parse_cmdline) - (fsp_fuse_env(), args, mountpoint, multithreaded, foreground); -}) - -FSP_FUSE_SYM( -void fuse_pollhandle_destroy(struct fuse_pollhandle *ph), -{ - (void)ph; -}) - -FSP_FUSE_SYM( -int fuse_daemonize(int foreground), -{ - return fsp_fuse_daemonize(foreground); -}) - -FSP_FUSE_SYM( -int fuse_set_signal_handlers(struct fuse_session *se), -{ - return fsp_fuse_set_signal_handlers(se); -}) - -FSP_FUSE_SYM( -void fuse_remove_signal_handlers(struct fuse_session *se), -{ - (void)se; - fsp_fuse_set_signal_handlers(0); -}) - -#ifdef __cplusplus -} -#endif - -#endif +/** + * @file fuse/fuse_common.h + * WinFsp FUSE compatible API. + * + * This file is derived from libfuse/include/fuse_common.h: + * FUSE: Filesystem in Userspace + * Copyright (C) 2001-2007 Miklos Szeredi + * + * @copyright 2015-2025 Bill Zissimopoulos + */ +/* + * This file is part of WinFsp. + * + * You can redistribute it and/or modify it under the terms of the GNU + * General Public License version 3 as published by the Free Software + * Foundation. + * + * Licensees holding a valid commercial license may use this software + * in accordance with the commercial license agreement provided in + * conjunction with the software. The terms and conditions of any such + * commercial license agreement shall govern, supersede, and render + * ineffective any application of the GPLv3 license to this software, + * notwithstanding of any reference thereto in the software or + * associated repository. + */ + +#ifndef FUSE_COMMON_H_ +#define FUSE_COMMON_H_ + +#include "winfsp_fuse.h" +#include "fuse_opt.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define FUSE_MAJOR_VERSION 2 +#define FUSE_MINOR_VERSION 8 +#define FUSE_MAKE_VERSION(maj, min) ((maj) * 10 + (min)) +#define FUSE_VERSION FUSE_MAKE_VERSION(FUSE_MAJOR_VERSION, FUSE_MINOR_VERSION) + +#define FUSE_CAP_ASYNC_READ (1 << 0) +#define FUSE_CAP_POSIX_LOCKS (1 << 1) +#define FUSE_CAP_ATOMIC_O_TRUNC (1 << 3) +#define FUSE_CAP_EXPORT_SUPPORT (1 << 4) +#define FUSE_CAP_BIG_WRITES (1 << 5) +#define FUSE_CAP_DONT_MASK (1 << 6) +#define FUSE_CAP_ALLOCATE (1 << 27) /* reserved (OSXFUSE) */ +#define FUSE_CAP_EXCHANGE_DATA (1 << 28) /* reserved (OSXFUSE) */ +#define FUSE_CAP_CASE_INSENSITIVE (1 << 29) /* file system is case insensitive */ +#define FUSE_CAP_VOL_RENAME (1 << 30) /* reserved (OSXFUSE) */ +#define FUSE_CAP_XTIMES (1 << 31) /* reserved (OSXFUSE) */ + +#define FSP_FUSE_CAP_READDIR_PLUS (1 << 21) /* file system supports enhanced readdir */ +#define FSP_FUSE_CAP_READ_ONLY (1 << 22) /* file system is marked read-only */ +#define FSP_FUSE_CAP_STAT_EX (1 << 23) /* file system supports fuse_stat_ex */ +#define FSP_FUSE_CAP_DELETE_ACCESS (1 << 24) /* file system supports access with DELETE_OK */ +#define FSP_FUSE_CAP_CASE_INSENSITIVE FUSE_CAP_CASE_INSENSITIVE + +#define FUSE_IOCTL_COMPAT (1 << 0) +#define FUSE_IOCTL_UNRESTRICTED (1 << 1) +#define FUSE_IOCTL_RETRY (1 << 2) +#define FUSE_IOCTL_MAX_IOV 256 + +/* from FreeBSD */ +#define FSP_FUSE_UF_HIDDEN 0x00008000 +#define FSP_FUSE_UF_READONLY 0x00001000 +#define FSP_FUSE_UF_SYSTEM 0x00000080 +#define FSP_FUSE_UF_ARCHIVE 0x00000800 +#if !defined(UF_HIDDEN) +#define UF_HIDDEN FSP_FUSE_UF_HIDDEN +#endif +#if !defined(UF_READONLY) +#define UF_READONLY FSP_FUSE_UF_READONLY +#endif +#if !defined(UF_SYSTEM) +#define UF_SYSTEM FSP_FUSE_UF_SYSTEM +#endif +#if !defined(UF_ARCHIVE) +#define UF_ARCHIVE FSP_FUSE_UF_ARCHIVE +#endif + +/* delete access */ +#define FSP_FUSE_DELETE_OK 0x40000000 + +/* notify extension */ +#define FSP_FUSE_NOTIFY_MKDIR 0x0001 +#define FSP_FUSE_NOTIFY_RMDIR 0x0002 +#define FSP_FUSE_NOTIFY_CREATE 0x0004 +#define FSP_FUSE_NOTIFY_UNLINK 0x0008 +#define FSP_FUSE_NOTIFY_CHMOD 0x0010 +#define FSP_FUSE_NOTIFY_CHOWN 0x0020 +#define FSP_FUSE_NOTIFY_UTIME 0x0040 +#define FSP_FUSE_NOTIFY_CHFLAGS 0x0080 +#define FSP_FUSE_NOTIFY_TRUNCATE 0x0100 + +/* getpath extension */ +#define FSP_FUSE_HAS_GETPATH 1 + +struct fuse_file_info +{ + int flags; + unsigned int fh_old; + int writepage; + unsigned int direct_io:1; + unsigned int keep_cache:1; + unsigned int flush:1; + unsigned int nonseekable:1; + unsigned int padding:28; + uint64_t fh; + uint64_t lock_owner; +}; + +struct fuse_conn_info +{ + unsigned proto_major; + unsigned proto_minor; + unsigned async_read; + unsigned max_write; + unsigned max_readahead; + unsigned capable; + unsigned want; + unsigned reserved[25]; +}; + +struct fuse_session; +struct fuse_chan; +struct fuse_pollhandle; +struct fuse_bufvec; +struct fuse_statfs; +struct fuse_setattr_x; + +FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse_version)(struct fsp_fuse_env *env); +FSP_FUSE_API struct fuse_chan *FSP_FUSE_API_NAME(fsp_fuse_mount)(struct fsp_fuse_env *env, + const char *mountpoint, struct fuse_args *args); +FSP_FUSE_API void FSP_FUSE_API_NAME(fsp_fuse_unmount)(struct fsp_fuse_env *env, + const char *mountpoint, struct fuse_chan *ch); +FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse_parse_cmdline)(struct fsp_fuse_env *env, + struct fuse_args *args, + char **mountpoint, int *multithreaded, int *foreground); +FSP_FUSE_API int32_t FSP_FUSE_API_NAME(fsp_fuse_ntstatus_from_errno)(struct fsp_fuse_env *env, + int err); + +FSP_FUSE_SYM( +int fuse_version(void), +{ + return FSP_FUSE_API_CALL(fsp_fuse_version) + (fsp_fuse_env()); +}) + +FSP_FUSE_SYM( +struct fuse_chan *fuse_mount(const char *mountpoint, struct fuse_args *args), +{ + return FSP_FUSE_API_CALL(fsp_fuse_mount) + (fsp_fuse_env(), mountpoint, args); +}) + +FSP_FUSE_SYM( +void fuse_unmount(const char *mountpoint, struct fuse_chan *ch), +{ + FSP_FUSE_API_CALL(fsp_fuse_unmount) + (fsp_fuse_env(), mountpoint, ch); +}) + +FSP_FUSE_SYM( +int fuse_parse_cmdline(struct fuse_args *args, + char **mountpoint, int *multithreaded, int *foreground), +{ + return FSP_FUSE_API_CALL(fsp_fuse_parse_cmdline) + (fsp_fuse_env(), args, mountpoint, multithreaded, foreground); +}) + +FSP_FUSE_SYM( +void fuse_pollhandle_destroy(struct fuse_pollhandle *ph), +{ + (void)ph; +}) + +FSP_FUSE_SYM( +int fuse_daemonize(int foreground), +{ + return fsp_fuse_daemonize(foreground); +}) + +FSP_FUSE_SYM( +int fuse_set_signal_handlers(struct fuse_session *se), +{ + return fsp_fuse_set_signal_handlers(se); +}) + +FSP_FUSE_SYM( +void fuse_remove_signal_handlers(struct fuse_session *se), +{ + (void)se; + fsp_fuse_set_signal_handlers(0); +}) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/support/3rd_party/winfsp-2.0/inc/fuse/fuse_opt.h b/support/3rd_party/winfsp-2.1/inc/fuse/fuse_opt.h similarity index 95% rename from support/3rd_party/winfsp-2.0/inc/fuse/fuse_opt.h rename to support/3rd_party/winfsp-2.1/inc/fuse/fuse_opt.h index f30a4a7e..6767a93b 100644 --- a/support/3rd_party/winfsp-2.0/inc/fuse/fuse_opt.h +++ b/support/3rd_party/winfsp-2.1/inc/fuse/fuse_opt.h @@ -1,133 +1,133 @@ -/** - * @file fuse/fuse_opt.h - * WinFsp FUSE compatible API. - * - * This file is derived from libfuse/include/fuse_opt.h: - * FUSE: Filesystem in Userspace - * Copyright (C) 2001-2007 Miklos Szeredi - * - * @copyright 2015-2022 Bill Zissimopoulos - */ -/* - * This file is part of WinFsp. - * - * You can redistribute it and/or modify it under the terms of the GNU - * General Public License version 3 as published by the Free Software - * Foundation. - * - * Licensees holding a valid commercial license may use this software - * in accordance with the commercial license agreement provided in - * conjunction with the software. The terms and conditions of any such - * commercial license agreement shall govern, supersede, and render - * ineffective any application of the GPLv3 license to this software, - * notwithstanding of any reference thereto in the software or - * associated repository. - */ - -#ifndef FUSE_OPT_H_ -#define FUSE_OPT_H_ - -#include "winfsp_fuse.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define FUSE_OPT_KEY(templ, key) { templ, -1, key } -#define FUSE_OPT_END { NULL, 0, 0 } - -#define FUSE_OPT_KEY_OPT -1 -#define FUSE_OPT_KEY_NONOPT -2 -#define FUSE_OPT_KEY_KEEP -3 -#define FUSE_OPT_KEY_DISCARD -4 - -#define FUSE_ARGS_INIT(argc, argv) { argc, argv, 0 } - -struct fuse_opt -{ - const char *templ; - unsigned int offset; - int value; -}; - -struct fuse_args -{ - int argc; - char **argv; - int allocated; -}; - -typedef int (*fuse_opt_proc_t)(void *data, const char *arg, int key, - struct fuse_args *outargs); - -FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse_opt_parse)(struct fsp_fuse_env *env, - struct fuse_args *args, void *data, - const struct fuse_opt opts[], fuse_opt_proc_t proc); -FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse_opt_add_arg)(struct fsp_fuse_env *env, - struct fuse_args *args, const char *arg); -FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse_opt_insert_arg)(struct fsp_fuse_env *env, - struct fuse_args *args, int pos, const char *arg); -FSP_FUSE_API void FSP_FUSE_API_NAME(fsp_fuse_opt_free_args)(struct fsp_fuse_env *env, - struct fuse_args *args); -FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse_opt_add_opt)(struct fsp_fuse_env *env, - char **opts, const char *opt); -FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse_opt_add_opt_escaped)(struct fsp_fuse_env *env, - char **opts, const char *opt); -FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse_opt_match)(struct fsp_fuse_env *env, - const struct fuse_opt opts[], const char *opt); - -FSP_FUSE_SYM( -int fuse_opt_parse(struct fuse_args *args, void *data, - const struct fuse_opt opts[], fuse_opt_proc_t proc), -{ - return FSP_FUSE_API_CALL(fsp_fuse_opt_parse) - (fsp_fuse_env(), args, data, opts, proc); -}) - -FSP_FUSE_SYM( -int fuse_opt_add_arg(struct fuse_args *args, const char *arg), -{ - return FSP_FUSE_API_CALL(fsp_fuse_opt_add_arg) - (fsp_fuse_env(), args, arg); -}) - -FSP_FUSE_SYM( -int fuse_opt_insert_arg(struct fuse_args *args, int pos, const char *arg), -{ - return FSP_FUSE_API_CALL(fsp_fuse_opt_insert_arg) - (fsp_fuse_env(), args, pos, arg); -}) - -FSP_FUSE_SYM( -void fuse_opt_free_args(struct fuse_args *args), -{ - FSP_FUSE_API_CALL(fsp_fuse_opt_free_args) - (fsp_fuse_env(), args); -}) - -FSP_FUSE_SYM( -int fuse_opt_add_opt(char **opts, const char *opt), -{ - return FSP_FUSE_API_CALL(fsp_fuse_opt_add_opt) - (fsp_fuse_env(), opts, opt); -}) - -FSP_FUSE_SYM( -int fuse_opt_add_opt_escaped(char **opts, const char *opt), -{ - return FSP_FUSE_API_CALL(fsp_fuse_opt_add_opt_escaped) - (fsp_fuse_env(), opts, opt); -}) - -FSP_FUSE_SYM( -int fuse_opt_match(const struct fuse_opt opts[], const char *opt), -{ - return FSP_FUSE_API_CALL(fsp_fuse_opt_match) - (fsp_fuse_env(), opts, opt); -}) - -#ifdef __cplusplus -} -#endif - -#endif +/** + * @file fuse/fuse_opt.h + * WinFsp FUSE compatible API. + * + * This file is derived from libfuse/include/fuse_opt.h: + * FUSE: Filesystem in Userspace + * Copyright (C) 2001-2007 Miklos Szeredi + * + * @copyright 2015-2025 Bill Zissimopoulos + */ +/* + * This file is part of WinFsp. + * + * You can redistribute it and/or modify it under the terms of the GNU + * General Public License version 3 as published by the Free Software + * Foundation. + * + * Licensees holding a valid commercial license may use this software + * in accordance with the commercial license agreement provided in + * conjunction with the software. The terms and conditions of any such + * commercial license agreement shall govern, supersede, and render + * ineffective any application of the GPLv3 license to this software, + * notwithstanding of any reference thereto in the software or + * associated repository. + */ + +#ifndef FUSE_OPT_H_ +#define FUSE_OPT_H_ + +#include "winfsp_fuse.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define FUSE_OPT_KEY(templ, key) { templ, -1, key } +#define FUSE_OPT_END { NULL, 0, 0 } + +#define FUSE_OPT_KEY_OPT -1 +#define FUSE_OPT_KEY_NONOPT -2 +#define FUSE_OPT_KEY_KEEP -3 +#define FUSE_OPT_KEY_DISCARD -4 + +#define FUSE_ARGS_INIT(argc, argv) { argc, argv, 0 } + +struct fuse_opt +{ + const char *templ; + unsigned int offset; + int value; +}; + +struct fuse_args +{ + int argc; + char **argv; + int allocated; +}; + +typedef int (*fuse_opt_proc_t)(void *data, const char *arg, int key, + struct fuse_args *outargs); + +FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse_opt_parse)(struct fsp_fuse_env *env, + struct fuse_args *args, void *data, + const struct fuse_opt opts[], fuse_opt_proc_t proc); +FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse_opt_add_arg)(struct fsp_fuse_env *env, + struct fuse_args *args, const char *arg); +FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse_opt_insert_arg)(struct fsp_fuse_env *env, + struct fuse_args *args, int pos, const char *arg); +FSP_FUSE_API void FSP_FUSE_API_NAME(fsp_fuse_opt_free_args)(struct fsp_fuse_env *env, + struct fuse_args *args); +FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse_opt_add_opt)(struct fsp_fuse_env *env, + char **opts, const char *opt); +FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse_opt_add_opt_escaped)(struct fsp_fuse_env *env, + char **opts, const char *opt); +FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse_opt_match)(struct fsp_fuse_env *env, + const struct fuse_opt opts[], const char *opt); + +FSP_FUSE_SYM( +int fuse_opt_parse(struct fuse_args *args, void *data, + const struct fuse_opt opts[], fuse_opt_proc_t proc), +{ + return FSP_FUSE_API_CALL(fsp_fuse_opt_parse) + (fsp_fuse_env(), args, data, opts, proc); +}) + +FSP_FUSE_SYM( +int fuse_opt_add_arg(struct fuse_args *args, const char *arg), +{ + return FSP_FUSE_API_CALL(fsp_fuse_opt_add_arg) + (fsp_fuse_env(), args, arg); +}) + +FSP_FUSE_SYM( +int fuse_opt_insert_arg(struct fuse_args *args, int pos, const char *arg), +{ + return FSP_FUSE_API_CALL(fsp_fuse_opt_insert_arg) + (fsp_fuse_env(), args, pos, arg); +}) + +FSP_FUSE_SYM( +void fuse_opt_free_args(struct fuse_args *args), +{ + FSP_FUSE_API_CALL(fsp_fuse_opt_free_args) + (fsp_fuse_env(), args); +}) + +FSP_FUSE_SYM( +int fuse_opt_add_opt(char **opts, const char *opt), +{ + return FSP_FUSE_API_CALL(fsp_fuse_opt_add_opt) + (fsp_fuse_env(), opts, opt); +}) + +FSP_FUSE_SYM( +int fuse_opt_add_opt_escaped(char **opts, const char *opt), +{ + return FSP_FUSE_API_CALL(fsp_fuse_opt_add_opt_escaped) + (fsp_fuse_env(), opts, opt); +}) + +FSP_FUSE_SYM( +int fuse_opt_match(const struct fuse_opt opts[], const char *opt), +{ + return FSP_FUSE_API_CALL(fsp_fuse_opt_match) + (fsp_fuse_env(), opts, opt); +}) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/support/3rd_party/winfsp-2.0/inc/fuse/winfsp_fuse.h b/support/3rd_party/winfsp-2.1/inc/fuse/winfsp_fuse.h similarity index 95% rename from support/3rd_party/winfsp-2.0/inc/fuse/winfsp_fuse.h rename to support/3rd_party/winfsp-2.1/inc/fuse/winfsp_fuse.h index a99a0bed..f41dd431 100644 --- a/support/3rd_party/winfsp-2.0/inc/fuse/winfsp_fuse.h +++ b/support/3rd_party/winfsp-2.1/inc/fuse/winfsp_fuse.h @@ -1,434 +1,435 @@ -/** - * @file fuse/winfsp_fuse.h - * WinFsp FUSE compatible API. - * - * @copyright 2015-2022 Bill Zissimopoulos - */ -/* - * This file is part of WinFsp. - * - * You can redistribute it and/or modify it under the terms of the GNU - * General Public License version 3 as published by the Free Software - * Foundation. - * - * Licensees holding a valid commercial license may use this software - * in accordance with the commercial license agreement provided in - * conjunction with the software. The terms and conditions of any such - * commercial license agreement shall govern, supersede, and render - * ineffective any application of the GPLv3 license to this software, - * notwithstanding of any reference thereto in the software or - * associated repository. - */ - -#ifndef FUSE_WINFSP_FUSE_H_INCLUDED -#define FUSE_WINFSP_FUSE_H_INCLUDED - -#include -#include -#if !defined(WINFSP_DLL_INTERNAL) -#include -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -#if !defined(FSP_FUSE_API) -#if defined(WINFSP_DLL_INTERNAL) -#define FSP_FUSE_API __declspec(dllexport) -#else -#define FSP_FUSE_API __declspec(dllimport) -#endif -#endif - -#if !defined(FSP_FUSE_API_NAME) -#define FSP_FUSE_API_NAME(n) (n) -#endif - -#if !defined(FSP_FUSE_API_CALL) -#define FSP_FUSE_API_CALL(n) (n) -#endif - -#if !defined(FSP_FUSE_SYM) -#if !defined(CYGFUSE) -#define FSP_FUSE_SYM(proto, ...) static inline proto { __VA_ARGS__ } -#else -#define FSP_FUSE_SYM(proto, ...) proto; -#endif -#endif - -#define FSP_FUSE_DEVICE_TYPE (0x8000 | 'W' | 'F' * 0x100) /* DeviceIoControl -> ioctl */ -#define FSP_FUSE_CTLCODE_FROM_IOCTL(cmd)\ - (FSP_FUSE_DEVICE_TYPE << 16) | (((cmd) & 0x0fff) << 2) -#define FSP_FUSE_IOCTL(cmd, isiz, osiz) \ - ( \ - (((osiz) != 0) << 31) | \ - (((isiz) != 0) << 30) | \ - (((isiz) | (osiz)) << 16) | \ - (cmd) \ - ) - -/* - * FUSE uses a number of types (notably: struct stat) that are OS specific. - * Furthermore there are sometimes multiple definitions of the same type even - * within the same OS. This is certainly true on Windows, where these types - * are not even native. - * - * For this reason we will define our own fuse_* types which represent the - * types as the WinFsp DLL expects to see them. We will define these types - * to be compatible with the equivalent Cygwin types as we want WinFsp-FUSE - * to be usable from Cygwin. - */ - -#define FSP_FUSE_STAT_FIELD_DEFN \ - fuse_dev_t st_dev; \ - fuse_ino_t st_ino; \ - fuse_mode_t st_mode; \ - fuse_nlink_t st_nlink; \ - fuse_uid_t st_uid; \ - fuse_gid_t st_gid; \ - fuse_dev_t st_rdev; \ - fuse_off_t st_size; \ - struct fuse_timespec st_atim; \ - struct fuse_timespec st_mtim; \ - struct fuse_timespec st_ctim; \ - fuse_blksize_t st_blksize; \ - fuse_blkcnt_t st_blocks; \ - struct fuse_timespec st_birthtim; -#define FSP_FUSE_STAT_EX_FIELD_DEFN \ - FSP_FUSE_STAT_FIELD_DEFN \ - uint32_t st_flags; \ - uint32_t st_reserved32[3]; \ - uint64_t st_reserved64[2]; - -#if defined(_WIN64) || defined(_WIN32) - -typedef uint32_t fuse_uid_t; -typedef uint32_t fuse_gid_t; -typedef int32_t fuse_pid_t; - -typedef uint32_t fuse_dev_t; -typedef uint64_t fuse_ino_t; -typedef uint32_t fuse_mode_t; -typedef uint16_t fuse_nlink_t; -typedef int64_t fuse_off_t; - -#if defined(_WIN64) -typedef uint64_t fuse_fsblkcnt_t; -typedef uint64_t fuse_fsfilcnt_t; -#else -typedef uint32_t fuse_fsblkcnt_t; -typedef uint32_t fuse_fsfilcnt_t; -#endif -typedef int32_t fuse_blksize_t; -typedef int64_t fuse_blkcnt_t; - -#if defined(_WIN64) -struct fuse_utimbuf -{ - int64_t actime; - int64_t modtime; -}; -struct fuse_timespec -{ - int64_t tv_sec; - int64_t tv_nsec; -}; -#else -struct fuse_utimbuf -{ - int32_t actime; - int32_t modtime; -}; -struct fuse_timespec -{ - int32_t tv_sec; - int32_t tv_nsec; -}; -#endif - -#if !defined(FSP_FUSE_USE_STAT_EX) -struct fuse_stat -{ - FSP_FUSE_STAT_FIELD_DEFN -}; -#else -struct fuse_stat -{ - FSP_FUSE_STAT_EX_FIELD_DEFN -}; -#endif - -#if defined(_WIN64) -struct fuse_statvfs -{ - uint64_t f_bsize; - uint64_t f_frsize; - fuse_fsblkcnt_t f_blocks; - fuse_fsblkcnt_t f_bfree; - fuse_fsblkcnt_t f_bavail; - fuse_fsfilcnt_t f_files; - fuse_fsfilcnt_t f_ffree; - fuse_fsfilcnt_t f_favail; - uint64_t f_fsid; - uint64_t f_flag; - uint64_t f_namemax; -}; -#else -struct fuse_statvfs -{ - uint32_t f_bsize; - uint32_t f_frsize; - fuse_fsblkcnt_t f_blocks; - fuse_fsblkcnt_t f_bfree; - fuse_fsblkcnt_t f_bavail; - fuse_fsfilcnt_t f_files; - fuse_fsfilcnt_t f_ffree; - fuse_fsfilcnt_t f_favail; - uint32_t f_fsid; - uint32_t f_flag; - uint32_t f_namemax; -}; -#endif - -struct fuse_flock -{ - int16_t l_type; - int16_t l_whence; - fuse_off_t l_start; - fuse_off_t l_len; - fuse_pid_t l_pid; -}; - -#if defined(WINFSP_DLL_INTERNAL) -#define FSP_FUSE_ENV_INIT \ - { \ - 'W', \ - MemAlloc, MemFree, \ - fsp_fuse_daemonize, \ - fsp_fuse_set_signal_handlers, \ - 0/*conv_to_win_path*/, \ - 0/*winpid_to_pid*/, \ - { 0 }, \ - } -#else -#define FSP_FUSE_ENV_INIT \ - { \ - 'W', \ - malloc, free, \ - fsp_fuse_daemonize, \ - fsp_fuse_set_signal_handlers, \ - 0/*conv_to_win_path*/, \ - 0/*winpid_to_pid*/, \ - { 0 }, \ - } -#endif - -#elif defined(__CYGWIN__) - -#include -#include -#include -#include -#include -#include -#include - -#define fuse_uid_t uid_t -#define fuse_gid_t gid_t -#define fuse_pid_t pid_t - -#define fuse_dev_t dev_t -#define fuse_ino_t ino_t -#define fuse_mode_t mode_t -#define fuse_nlink_t nlink_t -#define fuse_off_t off_t - -#define fuse_fsblkcnt_t fsblkcnt_t -#define fuse_fsfilcnt_t fsfilcnt_t -#define fuse_blksize_t blksize_t -#define fuse_blkcnt_t blkcnt_t - -#define fuse_utimbuf utimbuf -#define fuse_timespec timespec - -#if !defined(FSP_FUSE_USE_STAT_EX) -#define fuse_stat stat -#else -struct fuse_stat -{ - FSP_FUSE_STAT_EX_FIELD_DEFN -}; -#endif -#define fuse_statvfs statvfs -#define fuse_flock flock - -#define FSP_FUSE_ENV_INIT \ - { \ - 'C', \ - malloc, free, \ - fsp_fuse_daemonize, \ - fsp_fuse_set_signal_handlers, \ - fsp_fuse_conv_to_win_path, \ - fsp_fuse_winpid_to_pid, \ - { 0 }, \ - } - -/* - * Note that long is 8 bytes long in Cygwin64 and 4 bytes long in Win64. - * For this reason we avoid using long anywhere in these headers. - */ - -#else -#error unsupported environment -#endif - -struct fuse_stat_ex -{ - FSP_FUSE_STAT_EX_FIELD_DEFN -}; - -struct fsp_fuse_env -{ - unsigned environment; - void *(*memalloc)(size_t); - void (*memfree)(void *); - int (*daemonize)(int); - int (*set_signal_handlers)(void *); - char *(*conv_to_win_path)(const char *); - fuse_pid_t (*winpid_to_pid)(uint32_t); - void (*reserved[2])(); -}; - -FSP_FUSE_API void FSP_FUSE_API_NAME(fsp_fuse_signal_handler)(int sig); - -#if defined(_WIN64) || defined(_WIN32) - -static inline int fsp_fuse_daemonize(int foreground) -{ - (void)foreground; - return 0; -} - -static inline int fsp_fuse_set_signal_handlers(void *se) -{ - (void)se; - return 0; -} - -#elif defined(__CYGWIN__) - -static inline int fsp_fuse_daemonize(int foreground) -{ - int daemon(int nochdir, int noclose); - int chdir(const char *path); - - if (!foreground) - { - if (-1 == daemon(0, 0)) - return -1; - } - else - chdir("/"); - - return 0; -} - -static inline void *fsp_fuse_signal_thread(void *psigmask) -{ - int sig; - - if (0 == sigwait((sigset_t *)psigmask, &sig)) - FSP_FUSE_API_CALL(fsp_fuse_signal_handler)(sig); - - return 0; -} - -static inline int fsp_fuse_set_signal_handlers(void *se) -{ -#define FSP_FUSE_SET_SIGNAL_HANDLER(sig, newha)\ - if (-1 != sigaction((sig), 0, &oldsa) &&\ - oldsa.sa_handler == (se ? SIG_DFL : (newha)))\ - {\ - newsa.sa_handler = se ? (newha) : SIG_DFL;\ - sigaction((sig), &newsa, 0);\ - } -#define FSP_FUSE_SIGADDSET(sig)\ - if (-1 != sigaction((sig), 0, &oldsa) &&\ - oldsa.sa_handler == SIG_DFL)\ - sigaddset(&sigmask, (sig)); - - static sigset_t sigmask; - static pthread_t sigthr; - struct sigaction oldsa, newsa; - - // memset instead of initializer to avoid GCC -Wmissing-field-initializers warning - memset(&newsa, 0, sizeof newsa); - - if (0 != se) - { - if (0 == sigthr) - { - FSP_FUSE_SET_SIGNAL_HANDLER(SIGPIPE, SIG_IGN); - - sigemptyset(&sigmask); - FSP_FUSE_SIGADDSET(SIGHUP); - FSP_FUSE_SIGADDSET(SIGINT); - FSP_FUSE_SIGADDSET(SIGTERM); - if (0 != pthread_sigmask(SIG_BLOCK, &sigmask, 0)) - return -1; - - if (0 != pthread_create(&sigthr, 0, fsp_fuse_signal_thread, &sigmask)) - return -1; - } - } - else - { - if (0 != sigthr) - { - pthread_cancel(sigthr); - pthread_join(sigthr, 0); - sigthr = 0; - - if (0 != pthread_sigmask(SIG_UNBLOCK, &sigmask, 0)) - return -1; - sigemptyset(&sigmask); - - FSP_FUSE_SET_SIGNAL_HANDLER(SIGPIPE, SIG_IGN); - } - } - - return 0; - -#undef FSP_FUSE_SIGADDSET -#undef FSP_FUSE_SET_SIGNAL_HANDLER -} - -static inline char *fsp_fuse_conv_to_win_path(const char *path) -{ - void *cygwin_create_path(unsigned, const void *); - return (char *)cygwin_create_path( - 0/*CCP_POSIX_TO_WIN_A*/ | 0x100/*CCP_RELATIVE*/, - path); -} - -static inline fuse_pid_t fsp_fuse_winpid_to_pid(uint32_t winpid) -{ - pid_t cygwin_winpid_to_pid(int winpid); - pid_t pid = cygwin_winpid_to_pid(winpid); - return -1 != pid ? pid : (fuse_pid_t)winpid; -} -#endif - - -static inline struct fsp_fuse_env *fsp_fuse_env(void) -{ - static struct fsp_fuse_env env = FSP_FUSE_ENV_INIT; - return &env; -} - -#ifdef __cplusplus -} -#endif - -#endif +/** + * @file fuse/winfsp_fuse.h + * WinFsp FUSE compatible API. + * + * @copyright 2015-2025 Bill Zissimopoulos + */ +/* + * This file is part of WinFsp. + * + * You can redistribute it and/or modify it under the terms of the GNU + * General Public License version 3 as published by the Free Software + * Foundation. + * + * Licensees holding a valid commercial license may use this software + * in accordance with the commercial license agreement provided in + * conjunction with the software. The terms and conditions of any such + * commercial license agreement shall govern, supersede, and render + * ineffective any application of the GPLv3 license to this software, + * notwithstanding of any reference thereto in the software or + * associated repository. + */ + +#ifndef FUSE_WINFSP_FUSE_H_INCLUDED +#define FUSE_WINFSP_FUSE_H_INCLUDED + +#include +#include +#if !defined(WINFSP_DLL_INTERNAL) +#include +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(FSP_FUSE_API) +#if defined(WINFSP_DLL_INTERNAL) +#define FSP_FUSE_API __declspec(dllexport) +#else +#define FSP_FUSE_API __declspec(dllimport) +#endif +#endif + +#if !defined(FSP_FUSE_API_NAME) +#define FSP_FUSE_API_NAME(n) (n) +#endif + +#if !defined(FSP_FUSE_API_CALL) +#define FSP_FUSE_API_CALL(n) (n) +#endif + +#if !defined(FSP_FUSE_SYM) +#if !defined(CYGFUSE) +#define FSP_FUSE_SYM(proto, ...) static inline proto { __VA_ARGS__ } +#else +#define FSP_FUSE_SYM(proto, ...) proto; +#endif +#endif + +#define FSP_FUSE_DEVICE_TYPE (0x8000 | 'W' | 'F' * 0x100) /* DeviceIoControl -> ioctl */ +#define FSP_FUSE_CTLCODE_FROM_IOCTL(cmd)\ + (FSP_FUSE_DEVICE_TYPE << 16) | (((cmd) & 0x0fff) << 2) +#define FSP_FUSE_IOCTL(cmd, isiz, osiz) \ + ( \ + (((osiz) != 0) << 31) | \ + (((isiz) != 0) << 30) | \ + (((isiz) | (osiz)) << 16) | \ + (cmd) \ + ) + +/* + * FUSE uses a number of types (notably: struct stat) that are OS specific. + * Furthermore there are sometimes multiple definitions of the same type even + * within the same OS. This is certainly true on Windows, where these types + * are not even native. + * + * For this reason we will define our own fuse_* types which represent the + * types as the WinFsp DLL expects to see them. We will define these types + * to be compatible with the equivalent Cygwin types as we want WinFsp-FUSE + * to be usable from Cygwin. + */ + +#define FSP_FUSE_STAT_FIELD_DEFN \ + fuse_dev_t st_dev; \ + fuse_ino_t st_ino; \ + fuse_mode_t st_mode; \ + fuse_nlink_t st_nlink; \ + fuse_uid_t st_uid; \ + fuse_gid_t st_gid; \ + fuse_dev_t st_rdev; \ + fuse_off_t st_size; \ + struct fuse_timespec st_atim; \ + struct fuse_timespec st_mtim; \ + struct fuse_timespec st_ctim; \ + fuse_blksize_t st_blksize; \ + fuse_blkcnt_t st_blocks; \ + struct fuse_timespec st_birthtim; +#define FSP_FUSE_STAT_EX_FIELD_DEFN \ + FSP_FUSE_STAT_FIELD_DEFN \ + uint32_t st_flags; \ + uint32_t st_reserved32[3]; \ + uint64_t st_reserved64[2]; + +#if defined(_WIN64) || defined(_WIN32) + +typedef uint32_t fuse_uid_t; +typedef uint32_t fuse_gid_t; +typedef int32_t fuse_pid_t; + +typedef uint32_t fuse_dev_t; +typedef uint64_t fuse_ino_t; +typedef uint32_t fuse_mode_t; +typedef uint16_t fuse_nlink_t; +typedef int64_t fuse_off_t; + +#if defined(_WIN64) +typedef uint64_t fuse_fsblkcnt_t; +typedef uint64_t fuse_fsfilcnt_t; +#else +typedef uint32_t fuse_fsblkcnt_t; +typedef uint32_t fuse_fsfilcnt_t; +#endif +typedef int32_t fuse_blksize_t; +typedef int64_t fuse_blkcnt_t; + +#if defined(_WIN64) +struct fuse_utimbuf +{ + int64_t actime; + int64_t modtime; +}; +struct fuse_timespec +{ + int64_t tv_sec; + int64_t tv_nsec; +}; +#else +struct fuse_utimbuf +{ + int32_t actime; + int32_t modtime; +}; +struct fuse_timespec +{ + int32_t tv_sec; + int32_t tv_nsec; +}; +#endif + +#if !defined(FSP_FUSE_USE_STAT_EX) +struct fuse_stat +{ + FSP_FUSE_STAT_FIELD_DEFN +}; +#else +struct fuse_stat +{ + FSP_FUSE_STAT_EX_FIELD_DEFN +}; +#endif + +#if defined(_WIN64) +struct fuse_statvfs +{ + uint64_t f_bsize; + uint64_t f_frsize; + fuse_fsblkcnt_t f_blocks; + fuse_fsblkcnt_t f_bfree; + fuse_fsblkcnt_t f_bavail; + fuse_fsfilcnt_t f_files; + fuse_fsfilcnt_t f_ffree; + fuse_fsfilcnt_t f_favail; + uint64_t f_fsid; + uint64_t f_flag; + uint64_t f_namemax; +}; +#else +struct fuse_statvfs +{ + uint32_t f_bsize; + uint32_t f_frsize; + fuse_fsblkcnt_t f_blocks; + fuse_fsblkcnt_t f_bfree; + fuse_fsblkcnt_t f_bavail; + fuse_fsfilcnt_t f_files; + fuse_fsfilcnt_t f_ffree; + fuse_fsfilcnt_t f_favail; + uint32_t f_fsid; + uint32_t f_flag; + uint32_t f_namemax; +}; +#endif + +struct fuse_flock +{ + int16_t l_type; + int16_t l_whence; + fuse_off_t l_start; + fuse_off_t l_len; + fuse_pid_t l_pid; +}; + +#if defined(WINFSP_DLL_INTERNAL) +#define FSP_FUSE_ENV_INIT \ + { \ + 'W', \ + MemAlloc, MemFree, \ + fsp_fuse_daemonize, \ + fsp_fuse_set_signal_handlers, \ + 0/*conv_to_win_path*/, \ + 0/*winpid_to_pid*/, \ + { 0 }, \ + } +#else +#define FSP_FUSE_ENV_INIT \ + { \ + 'W', \ + malloc, free, \ + fsp_fuse_daemonize, \ + fsp_fuse_set_signal_handlers, \ + 0/*conv_to_win_path*/, \ + 0/*winpid_to_pid*/, \ + { 0 }, \ + } +#endif + +#elif defined(__CYGWIN__) + +#include +#include +#include +#include +#include +#include +#include + +#define fuse_uid_t uid_t +#define fuse_gid_t gid_t +#define fuse_pid_t pid_t + +#define fuse_dev_t dev_t +#define fuse_ino_t ino_t +#define fuse_mode_t mode_t +#define fuse_nlink_t nlink_t +#define fuse_off_t off_t + +#define fuse_fsblkcnt_t fsblkcnt_t +#define fuse_fsfilcnt_t fsfilcnt_t +#define fuse_blksize_t blksize_t +#define fuse_blkcnt_t blkcnt_t + +#define fuse_utimbuf utimbuf +#define fuse_timespec timespec + +#if !defined(FSP_FUSE_USE_STAT_EX) +#define fuse_stat stat +#else +struct fuse_stat +{ + FSP_FUSE_STAT_EX_FIELD_DEFN +}; +#endif +#define fuse_statvfs statvfs +#define fuse_flock flock + +#define FSP_FUSE_ENV_INIT \ + { \ + 'C', \ + malloc, free, \ + fsp_fuse_daemonize, \ + fsp_fuse_set_signal_handlers, \ + fsp_fuse_conv_to_win_path, \ + fsp_fuse_winpid_to_pid, \ + { 0 }, \ + } + +/* + * Note that long is 8 bytes long in Cygwin64 and 4 bytes long in Win64. + * For this reason we avoid using long anywhere in these headers. + */ + +#else +#error unsupported environment +#endif + +struct fuse_stat_ex +{ + FSP_FUSE_STAT_EX_FIELD_DEFN +}; + +struct fsp_fuse_env +{ + unsigned environment; + void *(*memalloc)(size_t); + void (*memfree)(void *); + int (*daemonize)(int); + int (*set_signal_handlers)(void *); + char *(*conv_to_win_path)(const char *); + fuse_pid_t (*winpid_to_pid)(uint32_t); + void (*reserved[2])(); +}; + +FSP_FUSE_API void FSP_FUSE_API_NAME(fsp_fuse_signal_handler)(int sig); + +#if defined(_WIN64) || defined(_WIN32) + +static inline int fsp_fuse_daemonize(int foreground) +{ + (void)foreground; + return 0; +} + +static inline int fsp_fuse_set_signal_handlers(void *se) +{ + (void)se; + return 0; +} + +#elif defined(__CYGWIN__) + +static inline int fsp_fuse_daemonize(int foreground) +{ + int daemon(int nochdir, int noclose); + int chdir(const char *path); + + if (!foreground) + { + if (-1 == daemon(0, 0)) + return -1; + } + else + chdir("/"); + + return 0; +} + +static inline void *fsp_fuse_signal_thread(void *psigmask) +{ + int sig; + + if (0 == sigwait((sigset_t *)psigmask, &sig)) + FSP_FUSE_API_CALL(fsp_fuse_signal_handler)(sig); + + return 0; +} + +static inline int fsp_fuse_set_signal_handlers(void *se) +{ +#define FSP_FUSE_SET_SIGNAL_HANDLER(sig, newha)\ + if (-1 != sigaction((sig), 0, &oldsa) &&\ + oldsa.sa_handler == (se ? SIG_DFL : (newha)))\ + {\ + newsa.sa_handler = se ? (newha) : SIG_DFL;\ + sigaction((sig), &newsa, 0);\ + } +#define FSP_FUSE_SIGADDSET(sig)\ + if (-1 != sigaction((sig), 0, &oldsa) &&\ + oldsa.sa_handler == SIG_DFL)\ + sigaddset(&sigmask, (sig)); + + static sigset_t sigmask; + static pthread_t sigthr; + struct sigaction oldsa, newsa; + + // memset instead of initializer to avoid GCC -Wmissing-field-initializers warning + memset(&newsa, 0, sizeof newsa); + + if (0 != se) + { + if (0 == sigthr) + { + FSP_FUSE_SET_SIGNAL_HANDLER(SIGPIPE, SIG_IGN); + + sigemptyset(&sigmask); + FSP_FUSE_SIGADDSET(SIGHUP); + FSP_FUSE_SIGADDSET(SIGINT); + FSP_FUSE_SIGADDSET(SIGTERM); + if (0 != pthread_sigmask(SIG_BLOCK, &sigmask, 0)) + return -1; + + if (0 != pthread_create(&sigthr, 0, fsp_fuse_signal_thread, &sigmask)) + return -1; + } + } + else + { + if (0 != sigthr) + { + pthread_cancel(sigthr); + pthread_join(sigthr, 0); + sigthr = 0; + + if (0 != pthread_sigmask(SIG_UNBLOCK, &sigmask, 0)) + return -1; + sigemptyset(&sigmask); + + FSP_FUSE_SET_SIGNAL_HANDLER(SIGPIPE, SIG_IGN); + } + } + + return 0; + +#undef FSP_FUSE_SIGADDSET +#undef FSP_FUSE_SET_SIGNAL_HANDLER +} + +static inline char *fsp_fuse_conv_to_win_path(const char *path) +{ + void *cygwin_create_path(unsigned, const void *); + return (char *)cygwin_create_path( + 0/*CCP_POSIX_TO_WIN_A*/ | 0x100/*CCP_RELATIVE*/, + path); +} + +static inline fuse_pid_t fsp_fuse_winpid_to_pid(uint32_t winpid) +{ + pid_t cygwin_winpid_to_pid(int winpid); + pid_t pid = cygwin_winpid_to_pid(winpid); + return -1 != pid ? pid : (fuse_pid_t)winpid; +} +#endif + + +static inline struct fsp_fuse_env *fsp_fuse_env(void) +{ + static struct fsp_fuse_env env = FSP_FUSE_ENV_INIT; + return &env; +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/support/3rd_party/winfsp-2.0/inc/fuse3/fuse.h b/support/3rd_party/winfsp-2.1/inc/fuse3/fuse.h similarity index 96% rename from support/3rd_party/winfsp-2.0/inc/fuse3/fuse.h rename to support/3rd_party/winfsp-2.1/inc/fuse3/fuse.h index 3eae0d68..66dc594e 100644 --- a/support/3rd_party/winfsp-2.0/inc/fuse3/fuse.h +++ b/support/3rd_party/winfsp-2.1/inc/fuse3/fuse.h @@ -1,338 +1,338 @@ -/** - * @file fuse3/fuse.h - * WinFsp FUSE3 compatible API. - * - * This file is derived from libfuse/include/fuse.h: - * FUSE: Filesystem in Userspace - * Copyright (C) 2001-2007 Miklos Szeredi - * - * @copyright 2015-2022 Bill Zissimopoulos - */ -/* - * This file is part of WinFsp. - * - * You can redistribute it and/or modify it under the terms of the GNU - * General Public License version 3 as published by the Free Software - * Foundation. - * - * Licensees holding a valid commercial license may use this software - * in accordance with the commercial license agreement provided in - * conjunction with the software. The terms and conditions of any such - * commercial license agreement shall govern, supersede, and render - * ineffective any application of the GPLv3 license to this software, - * notwithstanding of any reference thereto in the software or - * associated repository. - */ - -#ifndef FUSE_H_ -#define FUSE_H_ - -#include "fuse_common.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct fuse3; - -enum fuse3_readdir_flags -{ - FUSE_READDIR_PLUS = (1 << 0), -}; - -enum fuse3_fill_dir_flags -{ - FUSE_FILL_DIR_PLUS = (1 << 1), -}; - -typedef int (*fuse3_fill_dir_t)(void *buf, const char *name, - const struct fuse_stat *stbuf, fuse_off_t off, - enum fuse3_fill_dir_flags flags); - -struct fuse3_config -{ - int set_gid; - unsigned int gid; - int set_uid; - unsigned int uid; - int set_mode; - unsigned int umask; - double entry_timeout; - double negative_timeout; - double attr_timeout; - int intr; - int intr_signal; - int remember; - int hard_remove; - int use_ino; - int readdir_ino; - int direct_io; - int kernel_cache; - int auto_cache; - int ac_attr_timeout_set; - double ac_attr_timeout; - int nullpath_ok; - /* private */ - int show_help; - char *modules; - int debug; -}; - -struct fuse3_operations -{ - /* S - supported by WinFsp */ - /* S */ int (*getattr)(const char *path, struct fuse_stat *stbuf, - struct fuse3_file_info *fi); - /* S */ int (*readlink)(const char *path, char *buf, size_t size); - /* S */ int (*mknod)(const char *path, fuse_mode_t mode, fuse_dev_t dev); - /* S */ int (*mkdir)(const char *path, fuse_mode_t mode); - /* S */ int (*unlink)(const char *path); - /* S */ int (*rmdir)(const char *path); - /* S */ int (*symlink)(const char *dstpath, const char *srcpath); - /* S */ int (*rename)(const char *oldpath, const char *newpath, unsigned int flags); - /* _ */ int (*link)(const char *srcpath, const char *dstpath); - /* S */ int (*chmod)(const char *path, fuse_mode_t mode, - struct fuse3_file_info *fi); - /* S */ int (*chown)(const char *path, fuse_uid_t uid, fuse_gid_t gid, - struct fuse3_file_info *fi); - /* S */ int (*truncate)(const char *path, fuse_off_t size, - struct fuse3_file_info *fi); - /* S */ int (*open)(const char *path, struct fuse3_file_info *fi); - /* S */ int (*read)(const char *path, char *buf, size_t size, fuse_off_t off, - struct fuse3_file_info *fi); - /* S */ int (*write)(const char *path, const char *buf, size_t size, fuse_off_t off, - struct fuse3_file_info *fi); - /* S */ int (*statfs)(const char *path, struct fuse_statvfs *stbuf); - /* S */ int (*flush)(const char *path, struct fuse3_file_info *fi); - /* S */ int (*release)(const char *path, struct fuse3_file_info *fi); - /* S */ int (*fsync)(const char *path, int datasync, struct fuse3_file_info *fi); - /* S */ int (*setxattr)(const char *path, const char *name, const char *value, size_t size, - int flags); - /* S */ int (*getxattr)(const char *path, const char *name, char *value, size_t size); - /* S */ int (*listxattr)(const char *path, char *namebuf, size_t size); - /* S */ int (*removexattr)(const char *path, const char *name); - /* S */ int (*opendir)(const char *path, struct fuse3_file_info *fi); - /* S */ int (*readdir)(const char *path, void *buf, fuse3_fill_dir_t filler, fuse_off_t off, - struct fuse3_file_info *fi, enum fuse3_readdir_flags); - /* S */ int (*releasedir)(const char *path, struct fuse3_file_info *fi); - /* S */ int (*fsyncdir)(const char *path, int datasync, struct fuse3_file_info *fi); - /* S */ void *(*init)(struct fuse3_conn_info *conn, - struct fuse3_config *conf); - /* S */ void (*destroy)(void *data); - /* _ */ int (*access)(const char *path, int mask); - /* S */ int (*create)(const char *path, fuse_mode_t mode, struct fuse3_file_info *fi); - /* _ */ int (*lock)(const char *path, - struct fuse3_file_info *fi, int cmd, struct fuse_flock *lock); - /* S */ int (*utimens)(const char *path, const struct fuse_timespec tv[2], - struct fuse3_file_info *fi); - /* _ */ int (*bmap)(const char *path, size_t blocksize, uint64_t *idx); - /* S */ int (*ioctl)(const char *path, int cmd, void *arg, struct fuse3_file_info *fi, - unsigned int flags, void *data); - /* _ */ int (*poll)(const char *path, struct fuse3_file_info *fi, - struct fuse3_pollhandle *ph, unsigned *reventsp); - /* _ */ int (*write_buf)(const char *path, - struct fuse3_bufvec *buf, fuse_off_t off, struct fuse3_file_info *fi); - /* _ */ int (*read_buf)(const char *path, - struct fuse3_bufvec **bufp, size_t size, fuse_off_t off, struct fuse3_file_info *fi); - /* _ */ int (*flock)(const char *path, struct fuse3_file_info *, int op); - /* _ */ int (*fallocate)(const char *path, int mode, fuse_off_t off, fuse_off_t len, - struct fuse3_file_info *fi); -}; - -struct fuse3_context -{ - struct fuse3 *fuse; - fuse_uid_t uid; - fuse_gid_t gid; - fuse_pid_t pid; - void *private_data; - fuse_mode_t umask; -}; - -#define fuse_main(argc, argv, ops, data)\ - fuse3_main_real(argc, argv, ops, sizeof *(ops), data) - -FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse3_main_real)(struct fsp_fuse_env *env, - int argc, char *argv[], - const struct fuse3_operations *ops, size_t opsize, void *data); -FSP_FUSE_API void FSP_FUSE_API_NAME(fsp_fuse3_lib_help)(struct fsp_fuse_env *env, - struct fuse_args *args); -FSP_FUSE_API struct fuse3 *FSP_FUSE_API_NAME(fsp_fuse3_new_30)(struct fsp_fuse_env *env, - struct fuse_args *args, - const struct fuse3_operations *ops, size_t opsize, void *data); -FSP_FUSE_API struct fuse3 *FSP_FUSE_API_NAME(fsp_fuse3_new)(struct fsp_fuse_env *env, - struct fuse_args *args, - const struct fuse3_operations *ops, size_t opsize, void *data); -FSP_FUSE_API void FSP_FUSE_API_NAME(fsp_fuse3_destroy)(struct fsp_fuse_env *env, - struct fuse3 *f); -FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse3_mount)(struct fsp_fuse_env *env, - struct fuse3 *f, const char *mountpoint); -FSP_FUSE_API void FSP_FUSE_API_NAME(fsp_fuse3_unmount)(struct fsp_fuse_env *env, - struct fuse3 *f); -FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse3_loop)(struct fsp_fuse_env *env, - struct fuse3 *f); -FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse3_loop_mt_31)(struct fsp_fuse_env *env, - struct fuse3 *f, int clone_fd); -FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse3_loop_mt)(struct fsp_fuse_env *env, - struct fuse3 *f, struct fuse3_loop_config *config); -FSP_FUSE_API void FSP_FUSE_API_NAME(fsp_fuse3_exit)(struct fsp_fuse_env *env, - struct fuse3 *f); -FSP_FUSE_API struct fuse3_context *FSP_FUSE_API_NAME(fsp_fuse3_get_context)(struct fsp_fuse_env *env); - -FSP_FUSE_SYM( -int fuse3_main_real(int argc, char *argv[], - const struct fuse3_operations *ops, size_t opsize, void *data), -{ - return FSP_FUSE_API_CALL(fsp_fuse3_main_real) - (fsp_fuse_env(), argc, argv, ops, opsize, data); -}) - -FSP_FUSE_SYM( -void fuse3_lib_help(struct fuse_args *args), -{ - FSP_FUSE_API_CALL(fsp_fuse3_lib_help) - (fsp_fuse_env(), args); -}) - -#if FUSE_USE_VERSION == 30 -FSP_FUSE_SYM( -struct fuse3 *fuse3_new_30(struct fuse_args *args, - const struct fuse3_operations *ops, size_t opsize, void *data), -{ - return FSP_FUSE_API_CALL(fsp_fuse3_new_30) - (fsp_fuse_env(), args, ops, opsize, data); -}) -#define fuse_new(args, op, size, data)\ - fuse3_new_30(args, op, size, data) - -#else -FSP_FUSE_SYM( -struct fuse3 *fuse3_new(struct fuse_args *args, - const struct fuse3_operations *ops, size_t opsize, void *data), -{ - return FSP_FUSE_API_CALL(fsp_fuse3_new) - (fsp_fuse_env(), args, ops, opsize, data); -}) -#endif - -FSP_FUSE_SYM( -void fuse3_destroy(struct fuse3 *f), -{ - FSP_FUSE_API_CALL(fsp_fuse3_destroy) - (fsp_fuse_env(), f); -}) - -FSP_FUSE_SYM( -int fuse3_mount(struct fuse3 *f, const char *mountpoint), -{ - return FSP_FUSE_API_CALL(fsp_fuse3_mount) - (fsp_fuse_env(), f, mountpoint); -}) - -FSP_FUSE_SYM( -void fuse3_unmount(struct fuse3 *f), -{ - FSP_FUSE_API_CALL(fsp_fuse3_unmount) - (fsp_fuse_env(), f); -}) - -FSP_FUSE_SYM( -int fuse3_loop(struct fuse3 *f), -{ - return FSP_FUSE_API_CALL(fsp_fuse3_loop) - (fsp_fuse_env(), f); -}) - -#if FUSE_USE_VERSION < 32 -FSP_FUSE_SYM( -int fuse3_loop_mt_31(struct fuse3 *f, int clone_fd), -{ - return FSP_FUSE_API_CALL(fsp_fuse3_loop_mt_31) - (fsp_fuse_env(), f, clone_fd); -}) -#define fuse_loop_mt(f, clone_fd)\ - fuse3_loop_mt_31(f, clone_fd) - -#else -FSP_FUSE_SYM( -int fuse3_loop_mt(struct fuse3 *f, struct fuse3_loop_config *config), -{ - return FSP_FUSE_API_CALL(fsp_fuse3_loop_mt) - (fsp_fuse_env(), f, config); -}) -#endif - -FSP_FUSE_SYM( -void fuse3_exit(struct fuse3 *f), -{ - FSP_FUSE_API_CALL(fsp_fuse3_exit) - (fsp_fuse_env(), f); -}) - -FSP_FUSE_SYM( -struct fuse3_context *fuse3_get_context(void), -{ - return FSP_FUSE_API_CALL(fsp_fuse3_get_context) - (fsp_fuse_env()); -}) - -FSP_FUSE_SYM( -int fuse3_getgroups(int size, fuse_gid_t list[]), -{ - (void)size; - (void)list; - return -ENOSYS; -}) - -FSP_FUSE_SYM( -int fuse3_interrupted(void), -{ - return 0; -}) - -FSP_FUSE_SYM( -int fuse3_invalidate_path(struct fuse3 *f, const char *path), -{ - (void)f; - (void)path; - return -ENOENT; -}) - -FSP_FUSE_SYM( -int fuse3_notify_poll(struct fuse3_pollhandle *ph), -{ - (void)ph; - return 0; -}) - -FSP_FUSE_SYM( -int fuse3_start_cleanup_thread(struct fuse3 *f), -{ - (void)f; - return 0; -}) - -FSP_FUSE_SYM( -void fuse3_stop_cleanup_thread(struct fuse3 *f), -{ - (void)f; -}) - -FSP_FUSE_SYM( -int fuse3_clean_cache(struct fuse3 *f), -{ - (void)f; - return 600; -}) - -FSP_FUSE_SYM( -struct fuse3_session *fuse3_get_session(struct fuse3 *f), -{ - return (struct fuse3_session *)f; -}) - -#ifdef __cplusplus -} -#endif - -#endif +/** + * @file fuse3/fuse.h + * WinFsp FUSE3 compatible API. + * + * This file is derived from libfuse/include/fuse.h: + * FUSE: Filesystem in Userspace + * Copyright (C) 2001-2007 Miklos Szeredi + * + * @copyright 2015-2025 Bill Zissimopoulos + */ +/* + * This file is part of WinFsp. + * + * You can redistribute it and/or modify it under the terms of the GNU + * General Public License version 3 as published by the Free Software + * Foundation. + * + * Licensees holding a valid commercial license may use this software + * in accordance with the commercial license agreement provided in + * conjunction with the software. The terms and conditions of any such + * commercial license agreement shall govern, supersede, and render + * ineffective any application of the GPLv3 license to this software, + * notwithstanding of any reference thereto in the software or + * associated repository. + */ + +#ifndef FUSE_H_ +#define FUSE_H_ + +#include "fuse_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct fuse3; + +enum fuse3_readdir_flags +{ + FUSE_READDIR_PLUS = (1 << 0), +}; + +enum fuse3_fill_dir_flags +{ + FUSE_FILL_DIR_PLUS = (1 << 1), +}; + +typedef int (*fuse3_fill_dir_t)(void *buf, const char *name, + const struct fuse_stat *stbuf, fuse_off_t off, + enum fuse3_fill_dir_flags flags); + +struct fuse3_config +{ + int set_gid; + unsigned int gid; + int set_uid; + unsigned int uid; + int set_mode; + unsigned int umask; + double entry_timeout; + double negative_timeout; + double attr_timeout; + int intr; + int intr_signal; + int remember; + int hard_remove; + int use_ino; + int readdir_ino; + int direct_io; + int kernel_cache; + int auto_cache; + int ac_attr_timeout_set; + double ac_attr_timeout; + int nullpath_ok; + /* private */ + int show_help; + char *modules; + int debug; +}; + +struct fuse3_operations +{ + /* S - supported by WinFsp */ + /* S */ int (*getattr)(const char *path, struct fuse_stat *stbuf, + struct fuse3_file_info *fi); + /* S */ int (*readlink)(const char *path, char *buf, size_t size); + /* S */ int (*mknod)(const char *path, fuse_mode_t mode, fuse_dev_t dev); + /* S */ int (*mkdir)(const char *path, fuse_mode_t mode); + /* S */ int (*unlink)(const char *path); + /* S */ int (*rmdir)(const char *path); + /* S */ int (*symlink)(const char *dstpath, const char *srcpath); + /* S */ int (*rename)(const char *oldpath, const char *newpath, unsigned int flags); + /* _ */ int (*link)(const char *srcpath, const char *dstpath); + /* S */ int (*chmod)(const char *path, fuse_mode_t mode, + struct fuse3_file_info *fi); + /* S */ int (*chown)(const char *path, fuse_uid_t uid, fuse_gid_t gid, + struct fuse3_file_info *fi); + /* S */ int (*truncate)(const char *path, fuse_off_t size, + struct fuse3_file_info *fi); + /* S */ int (*open)(const char *path, struct fuse3_file_info *fi); + /* S */ int (*read)(const char *path, char *buf, size_t size, fuse_off_t off, + struct fuse3_file_info *fi); + /* S */ int (*write)(const char *path, const char *buf, size_t size, fuse_off_t off, + struct fuse3_file_info *fi); + /* S */ int (*statfs)(const char *path, struct fuse_statvfs *stbuf); + /* S */ int (*flush)(const char *path, struct fuse3_file_info *fi); + /* S */ int (*release)(const char *path, struct fuse3_file_info *fi); + /* S */ int (*fsync)(const char *path, int datasync, struct fuse3_file_info *fi); + /* S */ int (*setxattr)(const char *path, const char *name, const char *value, size_t size, + int flags); + /* S */ int (*getxattr)(const char *path, const char *name, char *value, size_t size); + /* S */ int (*listxattr)(const char *path, char *namebuf, size_t size); + /* S */ int (*removexattr)(const char *path, const char *name); + /* S */ int (*opendir)(const char *path, struct fuse3_file_info *fi); + /* S */ int (*readdir)(const char *path, void *buf, fuse3_fill_dir_t filler, fuse_off_t off, + struct fuse3_file_info *fi, enum fuse3_readdir_flags); + /* S */ int (*releasedir)(const char *path, struct fuse3_file_info *fi); + /* S */ int (*fsyncdir)(const char *path, int datasync, struct fuse3_file_info *fi); + /* S */ void *(*init)(struct fuse3_conn_info *conn, + struct fuse3_config *conf); + /* S */ void (*destroy)(void *data); + /* _ */ int (*access)(const char *path, int mask); + /* S */ int (*create)(const char *path, fuse_mode_t mode, struct fuse3_file_info *fi); + /* _ */ int (*lock)(const char *path, + struct fuse3_file_info *fi, int cmd, struct fuse_flock *lock); + /* S */ int (*utimens)(const char *path, const struct fuse_timespec tv[2], + struct fuse3_file_info *fi); + /* _ */ int (*bmap)(const char *path, size_t blocksize, uint64_t *idx); + /* S */ int (*ioctl)(const char *path, int cmd, void *arg, struct fuse3_file_info *fi, + unsigned int flags, void *data); + /* _ */ int (*poll)(const char *path, struct fuse3_file_info *fi, + struct fuse3_pollhandle *ph, unsigned *reventsp); + /* _ */ int (*write_buf)(const char *path, + struct fuse3_bufvec *buf, fuse_off_t off, struct fuse3_file_info *fi); + /* _ */ int (*read_buf)(const char *path, + struct fuse3_bufvec **bufp, size_t size, fuse_off_t off, struct fuse3_file_info *fi); + /* _ */ int (*flock)(const char *path, struct fuse3_file_info *, int op); + /* _ */ int (*fallocate)(const char *path, int mode, fuse_off_t off, fuse_off_t len, + struct fuse3_file_info *fi); +}; + +struct fuse3_context +{ + struct fuse3 *fuse; + fuse_uid_t uid; + fuse_gid_t gid; + fuse_pid_t pid; + void *private_data; + fuse_mode_t umask; +}; + +#define fuse_main(argc, argv, ops, data)\ + fuse3_main_real(argc, argv, ops, sizeof *(ops), data) + +FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse3_main_real)(struct fsp_fuse_env *env, + int argc, char *argv[], + const struct fuse3_operations *ops, size_t opsize, void *data); +FSP_FUSE_API void FSP_FUSE_API_NAME(fsp_fuse3_lib_help)(struct fsp_fuse_env *env, + struct fuse_args *args); +FSP_FUSE_API struct fuse3 *FSP_FUSE_API_NAME(fsp_fuse3_new_30)(struct fsp_fuse_env *env, + struct fuse_args *args, + const struct fuse3_operations *ops, size_t opsize, void *data); +FSP_FUSE_API struct fuse3 *FSP_FUSE_API_NAME(fsp_fuse3_new)(struct fsp_fuse_env *env, + struct fuse_args *args, + const struct fuse3_operations *ops, size_t opsize, void *data); +FSP_FUSE_API void FSP_FUSE_API_NAME(fsp_fuse3_destroy)(struct fsp_fuse_env *env, + struct fuse3 *f); +FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse3_mount)(struct fsp_fuse_env *env, + struct fuse3 *f, const char *mountpoint); +FSP_FUSE_API void FSP_FUSE_API_NAME(fsp_fuse3_unmount)(struct fsp_fuse_env *env, + struct fuse3 *f); +FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse3_loop)(struct fsp_fuse_env *env, + struct fuse3 *f); +FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse3_loop_mt_31)(struct fsp_fuse_env *env, + struct fuse3 *f, int clone_fd); +FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse3_loop_mt)(struct fsp_fuse_env *env, + struct fuse3 *f, struct fuse3_loop_config *config); +FSP_FUSE_API void FSP_FUSE_API_NAME(fsp_fuse3_exit)(struct fsp_fuse_env *env, + struct fuse3 *f); +FSP_FUSE_API struct fuse3_context *FSP_FUSE_API_NAME(fsp_fuse3_get_context)(struct fsp_fuse_env *env); + +FSP_FUSE_SYM( +int fuse3_main_real(int argc, char *argv[], + const struct fuse3_operations *ops, size_t opsize, void *data), +{ + return FSP_FUSE_API_CALL(fsp_fuse3_main_real) + (fsp_fuse_env(), argc, argv, ops, opsize, data); +}) + +FSP_FUSE_SYM( +void fuse3_lib_help(struct fuse_args *args), +{ + FSP_FUSE_API_CALL(fsp_fuse3_lib_help) + (fsp_fuse_env(), args); +}) + +#if FUSE_USE_VERSION == 30 +FSP_FUSE_SYM( +struct fuse3 *fuse3_new_30(struct fuse_args *args, + const struct fuse3_operations *ops, size_t opsize, void *data), +{ + return FSP_FUSE_API_CALL(fsp_fuse3_new_30) + (fsp_fuse_env(), args, ops, opsize, data); +}) +#define fuse_new(args, op, size, data)\ + fuse3_new_30(args, op, size, data) + +#else +FSP_FUSE_SYM( +struct fuse3 *fuse3_new(struct fuse_args *args, + const struct fuse3_operations *ops, size_t opsize, void *data), +{ + return FSP_FUSE_API_CALL(fsp_fuse3_new) + (fsp_fuse_env(), args, ops, opsize, data); +}) +#endif + +FSP_FUSE_SYM( +void fuse3_destroy(struct fuse3 *f), +{ + FSP_FUSE_API_CALL(fsp_fuse3_destroy) + (fsp_fuse_env(), f); +}) + +FSP_FUSE_SYM( +int fuse3_mount(struct fuse3 *f, const char *mountpoint), +{ + return FSP_FUSE_API_CALL(fsp_fuse3_mount) + (fsp_fuse_env(), f, mountpoint); +}) + +FSP_FUSE_SYM( +void fuse3_unmount(struct fuse3 *f), +{ + FSP_FUSE_API_CALL(fsp_fuse3_unmount) + (fsp_fuse_env(), f); +}) + +FSP_FUSE_SYM( +int fuse3_loop(struct fuse3 *f), +{ + return FSP_FUSE_API_CALL(fsp_fuse3_loop) + (fsp_fuse_env(), f); +}) + +#if FUSE_USE_VERSION < 32 +FSP_FUSE_SYM( +int fuse3_loop_mt_31(struct fuse3 *f, int clone_fd), +{ + return FSP_FUSE_API_CALL(fsp_fuse3_loop_mt_31) + (fsp_fuse_env(), f, clone_fd); +}) +#define fuse_loop_mt(f, clone_fd)\ + fuse3_loop_mt_31(f, clone_fd) + +#else +FSP_FUSE_SYM( +int fuse3_loop_mt(struct fuse3 *f, struct fuse3_loop_config *config), +{ + return FSP_FUSE_API_CALL(fsp_fuse3_loop_mt) + (fsp_fuse_env(), f, config); +}) +#endif + +FSP_FUSE_SYM( +void fuse3_exit(struct fuse3 *f), +{ + FSP_FUSE_API_CALL(fsp_fuse3_exit) + (fsp_fuse_env(), f); +}) + +FSP_FUSE_SYM( +struct fuse3_context *fuse3_get_context(void), +{ + return FSP_FUSE_API_CALL(fsp_fuse3_get_context) + (fsp_fuse_env()); +}) + +FSP_FUSE_SYM( +int fuse3_getgroups(int size, fuse_gid_t list[]), +{ + (void)size; + (void)list; + return -ENOSYS; +}) + +FSP_FUSE_SYM( +int fuse3_interrupted(void), +{ + return 0; +}) + +FSP_FUSE_SYM( +int fuse3_invalidate_path(struct fuse3 *f, const char *path), +{ + (void)f; + (void)path; + return -ENOENT; +}) + +FSP_FUSE_SYM( +int fuse3_notify_poll(struct fuse3_pollhandle *ph), +{ + (void)ph; + return 0; +}) + +FSP_FUSE_SYM( +int fuse3_start_cleanup_thread(struct fuse3 *f), +{ + (void)f; + return 0; +}) + +FSP_FUSE_SYM( +void fuse3_stop_cleanup_thread(struct fuse3 *f), +{ + (void)f; +}) + +FSP_FUSE_SYM( +int fuse3_clean_cache(struct fuse3 *f), +{ + (void)f; + return 600; +}) + +FSP_FUSE_SYM( +struct fuse3_session *fuse3_get_session(struct fuse3 *f), +{ + return (struct fuse3_session *)f; +}) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/support/3rd_party/winfsp-2.0/inc/fuse3/fuse_common.h b/support/3rd_party/winfsp-2.1/inc/fuse3/fuse_common.h similarity index 95% rename from support/3rd_party/winfsp-2.0/inc/fuse3/fuse_common.h rename to support/3rd_party/winfsp-2.1/inc/fuse3/fuse_common.h index 0cccea33..c7eb170d 100644 --- a/support/3rd_party/winfsp-2.0/inc/fuse3/fuse_common.h +++ b/support/3rd_party/winfsp-2.1/inc/fuse3/fuse_common.h @@ -1,238 +1,238 @@ -/** - * @file fuse3/fuse_common.h - * WinFsp FUSE3 compatible API. - * - * This file is derived from libfuse/include/fuse_common.h: - * FUSE: Filesystem in Userspace - * Copyright (C) 2001-2007 Miklos Szeredi - * - * @copyright 2015-2022 Bill Zissimopoulos - */ -/* - * This file is part of WinFsp. - * - * You can redistribute it and/or modify it under the terms of the GNU - * General Public License version 3 as published by the Free Software - * Foundation. - * - * Licensees holding a valid commercial license may use this software - * in accordance with the commercial license agreement provided in - * conjunction with the software. The terms and conditions of any such - * commercial license agreement shall govern, supersede, and render - * ineffective any application of the GPLv3 license to this software, - * notwithstanding of any reference thereto in the software or - * associated repository. - */ - -#ifndef FUSE_COMMON_H_ -#define FUSE_COMMON_H_ - -#include "winfsp_fuse.h" -#if !defined(WINFSP_DLL_INTERNAL) -#include "fuse_opt.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -#define FUSE_MAJOR_VERSION 3 -#define FUSE_MINOR_VERSION 2 -#define FUSE_MAKE_VERSION(maj, min) ((maj) * 10 + (min)) -#define FUSE_VERSION FUSE_MAKE_VERSION(FUSE_MAJOR_VERSION, FUSE_MINOR_VERSION) - -#define FUSE_CAP_ASYNC_READ (1 << 0) -#define FUSE_CAP_POSIX_LOCKS (1 << 1) -#define FUSE_CAP_ATOMIC_O_TRUNC (1 << 3) -#define FUSE_CAP_EXPORT_SUPPORT (1 << 4) -#define FUSE_CAP_DONT_MASK (1 << 6) -#define FUSE_CAP_SPLICE_WRITE (1 << 7) -#define FUSE_CAP_SPLICE_MOVE (1 << 8) -#define FUSE_CAP_SPLICE_READ (1 << 9) -#define FUSE_CAP_FLOCK_LOCKS (1 << 10) -#define FUSE_CAP_IOCTL_DIR (1 << 11) -#define FUSE_CAP_AUTO_INVAL_DATA (1 << 12) -#define FUSE_CAP_READDIRPLUS (1 << 13) -#define FUSE_CAP_READDIRPLUS_AUTO (1 << 14) -#define FUSE_CAP_ASYNC_DIO (1 << 15) -#define FUSE_CAP_WRITEBACK_CACHE (1 << 16) -#define FUSE_CAP_NO_OPEN_SUPPORT (1 << 17) -#define FUSE_CAP_PARALLEL_DIROPS (1 << 18) -#define FUSE_CAP_POSIX_ACL (1 << 19) -#define FUSE_CAP_HANDLE_KILLPRIV (1 << 20) -#define FUSE_CAP_ALLOCATE (1 << 27) /* reserved (OSXFUSE) */ -#define FUSE_CAP_EXCHANGE_DATA (1 << 28) /* reserved (OSXFUSE) */ -#define FUSE_CAP_CASE_INSENSITIVE (1 << 29) /* file system is case insensitive */ -#define FUSE_CAP_VOL_RENAME (1 << 30) /* reserved (OSXFUSE) */ -#define FUSE_CAP_XTIMES (1 << 31) /* reserved (OSXFUSE) */ - -#define FSP_FUSE_CAP_CASE_INSENSITIVE FUSE_CAP_CASE_INSENSITIVE - -#define FUSE_IOCTL_COMPAT (1 << 0) -#define FUSE_IOCTL_UNRESTRICTED (1 << 1) -#define FUSE_IOCTL_RETRY (1 << 2) -#define FUSE_IOCTL_DIR (1 << 4) -#define FUSE_IOCTL_MAX_IOV 256 - -#define FUSE_BUFVEC_INIT(s) \ - ((struct fuse3_bufvec){ 1, 0, 0, { {s, (enum fuse3_buf_flags)0, 0, -1, 0} } }) - -struct fuse3_file_info -{ - int flags; - unsigned int writepage:1; - unsigned int direct_io:1; - unsigned int keep_cache:1; - unsigned int flush:1; - unsigned int nonseekable:1; - unsigned int flock_release:1; - unsigned int padding:27; - uint64_t fh; - uint64_t lock_owner; - uint32_t poll_events; -}; - -struct fuse3_loop_config -{ - int clone_fd; - unsigned int max_idle_threads; -}; - -struct fuse3_conn_info -{ - unsigned proto_major; - unsigned proto_minor; - unsigned max_write; - unsigned max_read; - unsigned max_readahead; - unsigned capable; - unsigned want; - unsigned max_background; - unsigned congestion_threshold; - unsigned time_gran; - unsigned reserved[22]; -}; - -enum fuse3_buf_flags -{ - FUSE_BUF_IS_FD = (1 << 1), - FUSE_BUF_FD_SEEK = (1 << 2), - FUSE_BUF_FD_RETRY = (1 << 3), -}; - -enum fuse3_buf_copy_flags -{ - FUSE_BUF_NO_SPLICE = (1 << 1), - FUSE_BUF_FORCE_SPLICE = (1 << 2), - FUSE_BUF_SPLICE_MOVE = (1 << 3), - FUSE_BUF_SPLICE_NONBLOCK = (1 << 4), -}; - -struct fuse3_buf -{ - size_t size; - enum fuse3_buf_flags flags; - void *mem; - int fd; - fuse_off_t pos; -}; - -struct fuse3_bufvec -{ - size_t count; - size_t idx; - size_t off; - struct fuse3_buf buf[1]; -}; - -struct fuse3_session; -struct fuse3_pollhandle; -struct fuse3_conn_info_opts; - -FSP_FUSE_API struct fuse3_conn_info_opts *FSP_FUSE_API_NAME(fsp_fuse3_parse_conn_info_opts)( - struct fsp_fuse_env *env, - struct fuse_args *args); -FSP_FUSE_API void FSP_FUSE_API_NAME(fsp_fuse3_apply_conn_info_opts)(struct fsp_fuse_env *env, - struct fuse3_conn_info_opts *opts, struct fuse3_conn_info *conn); -FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse3_version)(struct fsp_fuse_env *env); -FSP_FUSE_API const char *FSP_FUSE_API_NAME(fsp_fuse3_pkgversion)(struct fsp_fuse_env *env); -FSP_FUSE_API int32_t FSP_FUSE_API_NAME(fsp_fuse_ntstatus_from_errno)(struct fsp_fuse_env *env, - int err); - -FSP_FUSE_SYM( -struct fuse3_conn_info_opts* fuse3_parse_conn_info_opts( - struct fuse_args *args), -{ - return FSP_FUSE_API_CALL(fsp_fuse3_parse_conn_info_opts) - (fsp_fuse_env(), args); -}) - -FSP_FUSE_SYM( -void fuse3_apply_conn_info_opts( - struct fuse3_conn_info_opts *opts, struct fuse3_conn_info *conn), -{ - FSP_FUSE_API_CALL(fsp_fuse3_apply_conn_info_opts) - (fsp_fuse_env(), opts, conn); -}) - -FSP_FUSE_SYM( -int fuse3_version(void), -{ - return FSP_FUSE_API_CALL(fsp_fuse3_version) - (fsp_fuse_env()); -}) - -FSP_FUSE_SYM( -const char *fuse3_pkgversion(void), -{ - return FSP_FUSE_API_CALL(fsp_fuse3_pkgversion) - (fsp_fuse_env()); -}) - -FSP_FUSE_SYM( -void fuse3_pollhandle_destroy(struct fuse3_pollhandle *ph), -{ - (void)ph; -}) - -FSP_FUSE_SYM( -size_t fuse3_buf_size(const struct fuse3_bufvec *bufv), -{ - (void)bufv; - return 0; -}) - -FSP_FUSE_SYM( -ssize_t fuse3_buf_copy(struct fuse3_bufvec *dst, struct fuse3_bufvec *src, - enum fuse3_buf_copy_flags flags), -{ - (void)dst; - (void)src; - (void)flags; - return 0; -}) - -FSP_FUSE_SYM( -int fuse3_daemonize(int foreground), -{ - return fsp_fuse_daemonize(foreground); -}) - -FSP_FUSE_SYM( -int fuse3_set_signal_handlers(struct fuse3_session *se), -{ - return fsp_fuse_set_signal_handlers(se); -}) - -FSP_FUSE_SYM( -void fuse3_remove_signal_handlers(struct fuse3_session *se), -{ - (void)se; - fsp_fuse_set_signal_handlers(0); -}) - -#ifdef __cplusplus -} -#endif - -#endif +/** + * @file fuse3/fuse_common.h + * WinFsp FUSE3 compatible API. + * + * This file is derived from libfuse/include/fuse_common.h: + * FUSE: Filesystem in Userspace + * Copyright (C) 2001-2007 Miklos Szeredi + * + * @copyright 2015-2025 Bill Zissimopoulos + */ +/* + * This file is part of WinFsp. + * + * You can redistribute it and/or modify it under the terms of the GNU + * General Public License version 3 as published by the Free Software + * Foundation. + * + * Licensees holding a valid commercial license may use this software + * in accordance with the commercial license agreement provided in + * conjunction with the software. The terms and conditions of any such + * commercial license agreement shall govern, supersede, and render + * ineffective any application of the GPLv3 license to this software, + * notwithstanding of any reference thereto in the software or + * associated repository. + */ + +#ifndef FUSE_COMMON_H_ +#define FUSE_COMMON_H_ + +#include "winfsp_fuse.h" +#if !defined(WINFSP_DLL_INTERNAL) +#include "fuse_opt.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#define FUSE_MAJOR_VERSION 3 +#define FUSE_MINOR_VERSION 2 +#define FUSE_MAKE_VERSION(maj, min) ((maj) * 10 + (min)) +#define FUSE_VERSION FUSE_MAKE_VERSION(FUSE_MAJOR_VERSION, FUSE_MINOR_VERSION) + +#define FUSE_CAP_ASYNC_READ (1 << 0) +#define FUSE_CAP_POSIX_LOCKS (1 << 1) +#define FUSE_CAP_ATOMIC_O_TRUNC (1 << 3) +#define FUSE_CAP_EXPORT_SUPPORT (1 << 4) +#define FUSE_CAP_DONT_MASK (1 << 6) +#define FUSE_CAP_SPLICE_WRITE (1 << 7) +#define FUSE_CAP_SPLICE_MOVE (1 << 8) +#define FUSE_CAP_SPLICE_READ (1 << 9) +#define FUSE_CAP_FLOCK_LOCKS (1 << 10) +#define FUSE_CAP_IOCTL_DIR (1 << 11) +#define FUSE_CAP_AUTO_INVAL_DATA (1 << 12) +#define FUSE_CAP_READDIRPLUS (1 << 13) +#define FUSE_CAP_READDIRPLUS_AUTO (1 << 14) +#define FUSE_CAP_ASYNC_DIO (1 << 15) +#define FUSE_CAP_WRITEBACK_CACHE (1 << 16) +#define FUSE_CAP_NO_OPEN_SUPPORT (1 << 17) +#define FUSE_CAP_PARALLEL_DIROPS (1 << 18) +#define FUSE_CAP_POSIX_ACL (1 << 19) +#define FUSE_CAP_HANDLE_KILLPRIV (1 << 20) +#define FUSE_CAP_ALLOCATE (1 << 27) /* reserved (OSXFUSE) */ +#define FUSE_CAP_EXCHANGE_DATA (1 << 28) /* reserved (OSXFUSE) */ +#define FUSE_CAP_CASE_INSENSITIVE (1 << 29) /* file system is case insensitive */ +#define FUSE_CAP_VOL_RENAME (1 << 30) /* reserved (OSXFUSE) */ +#define FUSE_CAP_XTIMES (1 << 31) /* reserved (OSXFUSE) */ + +#define FSP_FUSE_CAP_CASE_INSENSITIVE FUSE_CAP_CASE_INSENSITIVE + +#define FUSE_IOCTL_COMPAT (1 << 0) +#define FUSE_IOCTL_UNRESTRICTED (1 << 1) +#define FUSE_IOCTL_RETRY (1 << 2) +#define FUSE_IOCTL_DIR (1 << 4) +#define FUSE_IOCTL_MAX_IOV 256 + +#define FUSE_BUFVEC_INIT(s) \ + ((struct fuse3_bufvec){ 1, 0, 0, { {s, (enum fuse3_buf_flags)0, 0, -1, 0} } }) + +struct fuse3_file_info +{ + int flags; + unsigned int writepage:1; + unsigned int direct_io:1; + unsigned int keep_cache:1; + unsigned int flush:1; + unsigned int nonseekable:1; + unsigned int flock_release:1; + unsigned int padding:27; + uint64_t fh; + uint64_t lock_owner; + uint32_t poll_events; +}; + +struct fuse3_loop_config +{ + int clone_fd; + unsigned int max_idle_threads; +}; + +struct fuse3_conn_info +{ + unsigned proto_major; + unsigned proto_minor; + unsigned max_write; + unsigned max_read; + unsigned max_readahead; + unsigned capable; + unsigned want; + unsigned max_background; + unsigned congestion_threshold; + unsigned time_gran; + unsigned reserved[22]; +}; + +enum fuse3_buf_flags +{ + FUSE_BUF_IS_FD = (1 << 1), + FUSE_BUF_FD_SEEK = (1 << 2), + FUSE_BUF_FD_RETRY = (1 << 3), +}; + +enum fuse3_buf_copy_flags +{ + FUSE_BUF_NO_SPLICE = (1 << 1), + FUSE_BUF_FORCE_SPLICE = (1 << 2), + FUSE_BUF_SPLICE_MOVE = (1 << 3), + FUSE_BUF_SPLICE_NONBLOCK = (1 << 4), +}; + +struct fuse3_buf +{ + size_t size; + enum fuse3_buf_flags flags; + void *mem; + int fd; + fuse_off_t pos; +}; + +struct fuse3_bufvec +{ + size_t count; + size_t idx; + size_t off; + struct fuse3_buf buf[1]; +}; + +struct fuse3_session; +struct fuse3_pollhandle; +struct fuse3_conn_info_opts; + +FSP_FUSE_API struct fuse3_conn_info_opts *FSP_FUSE_API_NAME(fsp_fuse3_parse_conn_info_opts)( + struct fsp_fuse_env *env, + struct fuse_args *args); +FSP_FUSE_API void FSP_FUSE_API_NAME(fsp_fuse3_apply_conn_info_opts)(struct fsp_fuse_env *env, + struct fuse3_conn_info_opts *opts, struct fuse3_conn_info *conn); +FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse3_version)(struct fsp_fuse_env *env); +FSP_FUSE_API const char *FSP_FUSE_API_NAME(fsp_fuse3_pkgversion)(struct fsp_fuse_env *env); +FSP_FUSE_API int32_t FSP_FUSE_API_NAME(fsp_fuse_ntstatus_from_errno)(struct fsp_fuse_env *env, + int err); + +FSP_FUSE_SYM( +struct fuse3_conn_info_opts* fuse3_parse_conn_info_opts( + struct fuse_args *args), +{ + return FSP_FUSE_API_CALL(fsp_fuse3_parse_conn_info_opts) + (fsp_fuse_env(), args); +}) + +FSP_FUSE_SYM( +void fuse3_apply_conn_info_opts( + struct fuse3_conn_info_opts *opts, struct fuse3_conn_info *conn), +{ + FSP_FUSE_API_CALL(fsp_fuse3_apply_conn_info_opts) + (fsp_fuse_env(), opts, conn); +}) + +FSP_FUSE_SYM( +int fuse3_version(void), +{ + return FSP_FUSE_API_CALL(fsp_fuse3_version) + (fsp_fuse_env()); +}) + +FSP_FUSE_SYM( +const char *fuse3_pkgversion(void), +{ + return FSP_FUSE_API_CALL(fsp_fuse3_pkgversion) + (fsp_fuse_env()); +}) + +FSP_FUSE_SYM( +void fuse3_pollhandle_destroy(struct fuse3_pollhandle *ph), +{ + (void)ph; +}) + +FSP_FUSE_SYM( +size_t fuse3_buf_size(const struct fuse3_bufvec *bufv), +{ + (void)bufv; + return 0; +}) + +FSP_FUSE_SYM( +ssize_t fuse3_buf_copy(struct fuse3_bufvec *dst, struct fuse3_bufvec *src, + enum fuse3_buf_copy_flags flags), +{ + (void)dst; + (void)src; + (void)flags; + return 0; +}) + +FSP_FUSE_SYM( +int fuse3_daemonize(int foreground), +{ + return fsp_fuse_daemonize(foreground); +}) + +FSP_FUSE_SYM( +int fuse3_set_signal_handlers(struct fuse3_session *se), +{ + return fsp_fuse_set_signal_handlers(se); +}) + +FSP_FUSE_SYM( +void fuse3_remove_signal_handlers(struct fuse3_session *se), +{ + (void)se; + fsp_fuse_set_signal_handlers(0); +}) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/support/3rd_party/winfsp-2.0/inc/fuse3/fuse_opt.h b/support/3rd_party/winfsp-2.1/inc/fuse3/fuse_opt.h similarity index 91% rename from support/3rd_party/winfsp-2.0/inc/fuse3/fuse_opt.h rename to support/3rd_party/winfsp-2.1/inc/fuse3/fuse_opt.h index a4522798..9ffe10f7 100644 --- a/support/3rd_party/winfsp-2.0/inc/fuse3/fuse_opt.h +++ b/support/3rd_party/winfsp-2.1/inc/fuse3/fuse_opt.h @@ -1,23 +1,23 @@ -/** - * @file fuse3/fuse_opt.h - * WinFsp FUSE3 compatible API. - * - * @copyright 2015-2022 Bill Zissimopoulos - */ -/* - * This file is part of WinFsp. - * - * You can redistribute it and/or modify it under the terms of the GNU - * General Public License version 3 as published by the Free Software - * Foundation. - * - * Licensees holding a valid commercial license may use this software - * in accordance with the commercial license agreement provided in - * conjunction with the software. The terms and conditions of any such - * commercial license agreement shall govern, supersede, and render - * ineffective any application of the GPLv3 license to this software, - * notwithstanding of any reference thereto in the software or - * associated repository. - */ - -#include "../fuse/fuse_opt.h" +/** + * @file fuse3/fuse_opt.h + * WinFsp FUSE3 compatible API. + * + * @copyright 2015-2025 Bill Zissimopoulos + */ +/* + * This file is part of WinFsp. + * + * You can redistribute it and/or modify it under the terms of the GNU + * General Public License version 3 as published by the Free Software + * Foundation. + * + * Licensees holding a valid commercial license may use this software + * in accordance with the commercial license agreement provided in + * conjunction with the software. The terms and conditions of any such + * commercial license agreement shall govern, supersede, and render + * ineffective any application of the GPLv3 license to this software, + * notwithstanding of any reference thereto in the software or + * associated repository. + */ + +#include "../fuse/fuse_opt.h" diff --git a/support/3rd_party/winfsp-2.0/inc/fuse3/winfsp_fuse.h b/support/3rd_party/winfsp-2.1/inc/fuse3/winfsp_fuse.h similarity index 96% rename from support/3rd_party/winfsp-2.0/inc/fuse3/winfsp_fuse.h rename to support/3rd_party/winfsp-2.1/inc/fuse3/winfsp_fuse.h index db5d593f..bae9aa74 100644 --- a/support/3rd_party/winfsp-2.0/inc/fuse3/winfsp_fuse.h +++ b/support/3rd_party/winfsp-2.1/inc/fuse3/winfsp_fuse.h @@ -1,82 +1,82 @@ -/** - * @file fuse3/winfsp_fuse.h - * WinFsp FUSE3 compatible API. - * - * @copyright 2015-2022 Bill Zissimopoulos - */ -/* - * This file is part of WinFsp. - * - * You can redistribute it and/or modify it under the terms of the GNU - * General Public License version 3 as published by the Free Software - * Foundation. - * - * Licensees holding a valid commercial license may use this software - * in accordance with the commercial license agreement provided in - * conjunction with the software. The terms and conditions of any such - * commercial license agreement shall govern, supersede, and render - * ineffective any application of the GPLv3 license to this software, - * notwithstanding of any reference thereto in the software or - * associated repository. - */ - -#ifndef FUSE3_WINFSP_FUSE_H_INCLUDED -#define FUSE3_WINFSP_FUSE_H_INCLUDED - -#include "../fuse/winfsp_fuse.h" - -#if defined(_WIN64) || defined(_WIN32) -typedef intptr_t ssize_t; -#endif - -#if !defined(WINFSP_DLL_INTERNAL) -#define fuse3 fuse -#define fuse3_apply_conn_info_opts fuse_apply_conn_info_opts -#define fuse3_buf fuse_buf -#define fuse3_buf_copy fuse_buf_copy -#define fuse3_buf_copy_flags fuse_buf_copy_flags -#define fuse3_buf_flags fuse_buf_flags -#define fuse3_buf_size fuse_buf_size -#define fuse3_bufvec fuse_bufvec -#define fuse3_clean_cache fuse_clean_cache -#define fuse3_config fuse_config -#define fuse3_conn_info fuse_conn_info -#define fuse3_conn_info_opts fuse_conn_info_opts -#define fuse3_context fuse_context -#define fuse3_daemonize fuse_daemonize -#define fuse3_destroy fuse_destroy -#define fuse3_exit fuse_exit -#define fuse3_file_info fuse_file_info -#define fuse3_fill_dir_flags fuse_fill_dir_flags -#define fuse3_fill_dir_t fuse_fill_dir_t -#define fuse3_get_context fuse_get_context -#define fuse3_get_session fuse_get_session -#define fuse3_getgroups fuse_getgroups -#define fuse3_interrupted fuse_interrupted -#define fuse3_invalidate_path fuse_invalidate_path -#define fuse3_lib_help fuse_lib_help -#define fuse3_loop fuse_loop -#define fuse3_loop_config fuse_loop_config -#define fuse3_loop_mt fuse_loop_mt -#define fuse3_loop_mt_31 fuse_loop_mt_31 -#define fuse3_main_real fuse_main_real -#define fuse3_mount fuse_mount -#define fuse3_new fuse_new -#define fuse3_new_30 fuse_new_30 -#define fuse3_notify_poll fuse_notify_poll -#define fuse3_operations fuse_operations -#define fuse3_parse_conn_info_opts fuse_parse_conn_info_opts -#define fuse3_pkgversion fuse_pkgversion -#define fuse3_pollhandle fuse_pollhandle -#define fuse3_pollhandle_destroy fuse_pollhandle_destroy -#define fuse3_readdir_flags fuse_readdir_flags -#define fuse3_remove_signal_handlers fuse_remove_signal_handlers -#define fuse3_session fuse_session -#define fuse3_set_signal_handlers fuse_set_signal_handlers -#define fuse3_start_cleanup_thread fuse_start_cleanup_thread -#define fuse3_stop_cleanup_thread fuse_stop_cleanup_thread -#define fuse3_unmount fuse_unmount -#define fuse3_version fuse_version -#endif - -#endif +/** + * @file fuse3/winfsp_fuse.h + * WinFsp FUSE3 compatible API. + * + * @copyright 2015-2025 Bill Zissimopoulos + */ +/* + * This file is part of WinFsp. + * + * You can redistribute it and/or modify it under the terms of the GNU + * General Public License version 3 as published by the Free Software + * Foundation. + * + * Licensees holding a valid commercial license may use this software + * in accordance with the commercial license agreement provided in + * conjunction with the software. The terms and conditions of any such + * commercial license agreement shall govern, supersede, and render + * ineffective any application of the GPLv3 license to this software, + * notwithstanding of any reference thereto in the software or + * associated repository. + */ + +#ifndef FUSE3_WINFSP_FUSE_H_INCLUDED +#define FUSE3_WINFSP_FUSE_H_INCLUDED + +#include "../fuse/winfsp_fuse.h" + +#if defined(_WIN64) || defined(_WIN32) +typedef intptr_t ssize_t; +#endif + +#if !defined(WINFSP_DLL_INTERNAL) +#define fuse3 fuse +#define fuse3_apply_conn_info_opts fuse_apply_conn_info_opts +#define fuse3_buf fuse_buf +#define fuse3_buf_copy fuse_buf_copy +#define fuse3_buf_copy_flags fuse_buf_copy_flags +#define fuse3_buf_flags fuse_buf_flags +#define fuse3_buf_size fuse_buf_size +#define fuse3_bufvec fuse_bufvec +#define fuse3_clean_cache fuse_clean_cache +#define fuse3_config fuse_config +#define fuse3_conn_info fuse_conn_info +#define fuse3_conn_info_opts fuse_conn_info_opts +#define fuse3_context fuse_context +#define fuse3_daemonize fuse_daemonize +#define fuse3_destroy fuse_destroy +#define fuse3_exit fuse_exit +#define fuse3_file_info fuse_file_info +#define fuse3_fill_dir_flags fuse_fill_dir_flags +#define fuse3_fill_dir_t fuse_fill_dir_t +#define fuse3_get_context fuse_get_context +#define fuse3_get_session fuse_get_session +#define fuse3_getgroups fuse_getgroups +#define fuse3_interrupted fuse_interrupted +#define fuse3_invalidate_path fuse_invalidate_path +#define fuse3_lib_help fuse_lib_help +#define fuse3_loop fuse_loop +#define fuse3_loop_config fuse_loop_config +#define fuse3_loop_mt fuse_loop_mt +#define fuse3_loop_mt_31 fuse_loop_mt_31 +#define fuse3_main_real fuse_main_real +#define fuse3_mount fuse_mount +#define fuse3_new fuse_new +#define fuse3_new_30 fuse_new_30 +#define fuse3_notify_poll fuse_notify_poll +#define fuse3_operations fuse_operations +#define fuse3_parse_conn_info_opts fuse_parse_conn_info_opts +#define fuse3_pkgversion fuse_pkgversion +#define fuse3_pollhandle fuse_pollhandle +#define fuse3_pollhandle_destroy fuse_pollhandle_destroy +#define fuse3_readdir_flags fuse_readdir_flags +#define fuse3_remove_signal_handlers fuse_remove_signal_handlers +#define fuse3_session fuse_session +#define fuse3_set_signal_handlers fuse_set_signal_handlers +#define fuse3_start_cleanup_thread fuse_start_cleanup_thread +#define fuse3_stop_cleanup_thread fuse_stop_cleanup_thread +#define fuse3_unmount fuse_unmount +#define fuse3_version fuse_version +#endif + +#endif diff --git a/support/3rd_party/winfsp-2.1/inc/winfsp/fsctl.h b/support/3rd_party/winfsp-2.1/inc/winfsp/fsctl.h new file mode 100644 index 00000000..94ade4a9 --- /dev/null +++ b/support/3rd_party/winfsp-2.1/inc/winfsp/fsctl.h @@ -0,0 +1,812 @@ +/** + * @file winfsp/fsctl.h + * + * @copyright 2015-2025 Bill Zissimopoulos + */ +/* + * This file is part of WinFsp. + * + * You can redistribute it and/or modify it under the terms of the GNU + * General Public License version 3 as published by the Free Software + * Foundation. + * + * Licensees holding a valid commercial license may use this software + * in accordance with the commercial license agreement provided in + * conjunction with the software. The terms and conditions of any such + * commercial license agreement shall govern, supersede, and render + * ineffective any application of the GPLv3 license to this software, + * notwithstanding of any reference thereto in the software or + * associated repository. + */ + +#ifndef WINFSP_FSCTL_H_INCLUDED +#define WINFSP_FSCTL_H_INCLUDED + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* static_assert is a C++11 feature, but seems to work with C on MSVC 2015 */ +#if defined(WINFSP_SYS_INTERNAL) || defined(WINFSP_DLL_INTERNAL) +#define FSP_FSCTL_STATIC_ASSERT(e,m) static_assert(e,m) +#else +#define FSP_FSCTL_STATIC_ASSERT(e,m) static_assert(1,"") +#endif + +#define FSP_FSCTL_STR(x) FSP_FSCTL_STR_(x) +#define FSP_FSCTL_STR_(x) #x +#if defined(MyProductName) +#define FSP_FSCTL_PRODUCT_NAME FSP_FSCTL_STR(MyProductName) +#else +#define FSP_FSCTL_PRODUCT_NAME "WinFsp" +#endif +#if defined(MyProductFileName) +#define FSP_FSCTL_PRODUCT_FILE_NAME FSP_FSCTL_STR(MyProductFileName) +#else +#define FSP_FSCTL_PRODUCT_FILE_NAME "winfsp" +#endif + +#define FSP_FSCTL_DRIVER_NAME FSP_FSCTL_PRODUCT_NAME +#define FSP_FSCTL_DISK_DEVICE_NAME FSP_FSCTL_DRIVER_NAME ".Disk" +#define FSP_FSCTL_NET_DEVICE_NAME FSP_FSCTL_DRIVER_NAME ".Net" +#define FSP_FSCTL_MUP_DEVICE_NAME FSP_FSCTL_DRIVER_NAME ".Mup" + +#if defined(MyFspFsctlDeviceClassGuid) +extern const __declspec(selectany) GUID FspFsctlDeviceClassGuid = MyFspFsctlDeviceClassGuid; +#else +extern const __declspec(selectany) GUID FspFsctlDeviceClassGuid = + { 0x6f9d25fa, 0x6dee, 0x4a9d, { 0x80, 0xf5, 0xe9, 0x8e, 0x14, 0xf3, 0x5e, 0x54 } }; +#endif +#if defined(MyFspFsvrtDeviceClassGuid) +extern const __declspec(selectany) GUID FspFsvrtDeviceClassGuid = MyFspFsvrtDeviceClassGuid; +#else +extern const __declspec(selectany) GUID FspFsvrtDeviceClassGuid = + { 0xb48171c3, 0xdd50, 0x4852, { 0x83, 0xa3, 0x34, 0x4c, 0x50, 0xd9, 0x3b, 0x17 } }; +#endif + +/* locations */ +#define FSP_FSCTL_PRODUCT_REGKEY "Software\\" FSP_FSCTL_PRODUCT_NAME +#define FSP_FSCTL_PRODUCT_REGKEY_WOW64 KEY_WOW64_32KEY +#if defined(_ARM64_) +#define FSP_FSCTL_PRODUCT_FULL_REGKEY "Software\\WOW6432Node\\" FSP_FSCTL_PRODUCT_NAME +#define FSP_FSCTL_PRODUCT_FILE_ARCH "a64" +#elif defined(_AMD64_) +#define FSP_FSCTL_PRODUCT_FULL_REGKEY "Software\\WOW6432Node\\" FSP_FSCTL_PRODUCT_NAME +#define FSP_FSCTL_PRODUCT_FILE_ARCH "x64" +#elif defined(_X86_) +#define FSP_FSCTL_PRODUCT_FULL_REGKEY "Software\\" FSP_FSCTL_PRODUCT_NAME +#define FSP_FSCTL_PRODUCT_FILE_ARCH "x86" +#else +#error unknown architecture +#endif + +/* alignment macros */ +#define FSP_FSCTL_ALIGN_UP(x, s) (((x) + ((s) - 1L)) & ~((s) - 1L)) +#define FSP_FSCTL_DEFAULT_ALIGNMENT 8 +#define FSP_FSCTL_DEFAULT_ALIGN_UP(x) FSP_FSCTL_ALIGN_UP(x, FSP_FSCTL_DEFAULT_ALIGNMENT) +#define FSP_FSCTL_DECLSPEC_ALIGN __declspec(align(FSP_FSCTL_DEFAULT_ALIGNMENT)) + +/* fsctl device codes */ +#define FSP_FSCTL_MOUNTDEV \ + CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 'M', METHOD_BUFFERED, FILE_ANY_ACCESS) +#define FSP_FSCTL_MOUNTMGR \ + CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 'm', METHOD_BUFFERED, FILE_ANY_ACCESS) +#define FSP_FSCTL_VOLUME_NAME \ + CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 'N', METHOD_BUFFERED, FILE_ANY_ACCESS) +#define FSP_FSCTL_VOLUME_LIST \ + CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 'L', METHOD_BUFFERED, FILE_ANY_ACCESS) +#define FSP_FSCTL_TRANSACT \ + CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 'T', METHOD_BUFFERED, FILE_ANY_ACCESS) +#define FSP_IOCTL_TRANSACT \ + CTL_CODE(0x8000 | ('F'<<8) | 'W', 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_IOCTL_TRANSACT_BATCH \ + CTL_CODE(0x8000 | ('F'<<8) | 'W', 0x800 + 't', METHOD_BUFFERED, FILE_ANY_ACCESS) +#define FSP_FSCTL_STOP \ + CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 'S', METHOD_BUFFERED, FILE_ANY_ACCESS) +#define FSP_FSCTL_STOP0 \ + 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_NEITHER, FILE_ANY_ACCESS) +#define FSP_FSCTL_UNLOAD \ + CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 'U', METHOD_NEITHER, FILE_ANY_ACCESS) + +/* fsctl internal device codes (usable only in-kernel) */ +#define FSP_FSCTL_TRANSACT_INTERNAL \ + CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 'I', METHOD_NEITHER, FILE_ANY_ACCESS) +#define FSP_IOCTL_TRANSACT_INTERNAL \ + CTL_CODE(0x8000 | ('F'<<8) | 'W', 0x800 + 'I', METHOD_BUFFERED, 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)) +#define FSP_FSCTL_VOLUME_PREFIX_SIZE (192 * sizeof(WCHAR)) +#define FSP_FSCTL_VOLUME_FSNAME_SIZE (16 * sizeof(WCHAR)) +#define FSP_FSCTL_VOLUME_NAME_SIZEMAX (FSP_FSCTL_VOLUME_NAME_SIZE + FSP_FSCTL_VOLUME_PREFIX_SIZE) +FSP_FSCTL_STATIC_ASSERT(FSP_FSCTL_VOLUME_NAME_SIZEMAX <= 260 * sizeof(WCHAR), + "Max volume name size is greater than MAX_PATH."); + +#define FSP_FSCTL_TRANSACT_PATH_SIZEMAX (1024 * sizeof(WCHAR)) + +#define FSP_FSCTL_TRANSACT_REQ_SIZEMAX (16 * 1024 - 64) /* 64: size for internal request header */ +#define FSP_FSCTL_TRANSACT_RSP_SIZEMAX (16 * 1024) +#define FSP_FSCTL_TRANSACT_REQ_BUFFER_SIZEMAX (FSP_FSCTL_TRANSACT_REQ_SIZEMAX - sizeof(FSP_FSCTL_TRANSACT_REQ)) +#define FSP_FSCTL_TRANSACT_RSP_BUFFER_SIZEMAX (FSP_FSCTL_TRANSACT_RSP_SIZEMAX - sizeof(FSP_FSCTL_TRANSACT_RSP)) +#define FSP_FSCTL_TRANSACT_BATCH_BUFFER_SIZEMIN (64 * 1024) +#define FSP_FSCTL_TRANSACT_BUFFER_SIZEMIN FSP_FSCTL_TRANSACT_REQ_SIZEMAX + +#define FSP_FSCTL_TRANSACT_REQ_TOKEN_HANDLE(T) ((HANDLE)((UINT_PTR)((T) & 0xffffffff))) +#define FSP_FSCTL_TRANSACT_REQ_TOKEN_PID(T) ((UINT32)(((T) >> 32) & 0xffffffff)) + +#define FSP_FSCTL_DEVICECONTROL_SIZEMAX (4 * 1024) /* must be < FSP_FSCTL_TRANSACT_{REQ,RSP}_SIZEMAX */ + +/* marshalling */ +#pragma warning(push) +#pragma warning(disable:4200 4201) /* zero-sized array in struct/union; nameless struct/union */ +enum +{ + FspFsctlTransactReservedKind = 0, + FspFsctlTransactCreateKind, + FspFsctlTransactOverwriteKind, + FspFsctlTransactCleanupKind, + FspFsctlTransactCloseKind, + FspFsctlTransactReadKind, + FspFsctlTransactWriteKind, + FspFsctlTransactQueryInformationKind, + FspFsctlTransactSetInformationKind, + FspFsctlTransactQueryEaKind, + FspFsctlTransactSetEaKind, + FspFsctlTransactFlushBuffersKind, + FspFsctlTransactQueryVolumeInformationKind, + FspFsctlTransactSetVolumeInformationKind, + FspFsctlTransactQueryDirectoryKind, + FspFsctlTransactFileSystemControlKind, + FspFsctlTransactDeviceControlKind, + FspFsctlTransactShutdownKind, + FspFsctlTransactLockControlKind, + FspFsctlTransactQuerySecurityKind, + FspFsctlTransactSetSecurityKind, + FspFsctlTransactQueryStreamInformationKind, + FspFsctlTransactKindCount, +}; +enum +{ + FspFsctlTransactTimeoutMinimum = 1000, + FspFsctlTransactTimeoutMaximum = 10000, + FspFsctlTransactTimeoutDefault = 1000, /* DEPRECATED: default is unspecified */ + FspFsctlIrpTimeoutMinimum = 60000, + FspFsctlIrpTimeoutMaximum = 600000, + FspFsctlIrpTimeoutDefault = 300000, + FspFsctlIrpTimeoutDebug = 142, /* special value for IRP timeout testing */ + FspFsctlIrpCapacityMinimum = 100, + FspFsctlIrpCapacityMaximum = 1000, + FspFsctlIrpCapacityDefault = 1000, +}; +#define FSP_FSCTL_VOLUME_PARAMS_V0_FIELD_DEFN\ + UINT16 Version; /* set to 0 or sizeof(FSP_FSCTL_VOLUME_PARAMS) */\ + /* volume information */\ + UINT16 SectorSize;\ + UINT16 SectorsPerAllocationUnit;\ + UINT16 MaxComponentLength; /* maximum file name component length (bytes) */\ + UINT64 VolumeCreationTime;\ + UINT32 VolumeSerialNumber;\ + /* I/O timeouts, capacity, etc. */\ + UINT32 TransactTimeout; /* DEPRECATED: (millis; 1 sec - 10 sec) */\ + UINT32 IrpTimeout; /* pending IRP timeout (millis; 1 min - 10 min) */\ + UINT32 IrpCapacity; /* maximum number of pending IRP's (100 - 1000)*/\ + UINT32 FileInfoTimeout; /* FileInfo/Security/VolumeInfo timeout (millis) */\ + /* FILE_FS_ATTRIBUTE_INFORMATION::FileSystemAttributes */\ + UINT32 CaseSensitiveSearch:1; /* file system supports case-sensitive file names */\ + UINT32 CasePreservedNames:1; /* file system preserves the case of file names */\ + UINT32 UnicodeOnDisk:1; /* file system supports Unicode in file names */\ + UINT32 PersistentAcls:1; /* file system preserves and enforces access control lists */\ + UINT32 ReparsePoints:1; /* file system supports reparse points */\ + UINT32 ReparsePointsAccessCheck:1; /* file system performs reparse point access checks */\ + UINT32 NamedStreams:1; /* file system supports named streams */\ + UINT32 HardLinks:1; /* unimplemented; set to 0 */\ + UINT32 ExtendedAttributes:1; /* file system supports extended attributes */\ + UINT32 ReadOnlyVolume:1;\ + /* kernel-mode flags */\ + UINT32 PostCleanupWhenModifiedOnly:1; /* post Cleanup when a file was modified/deleted */\ + UINT32 PassQueryDirectoryPattern:1; /* pass Pattern during QueryDirectory operations */\ + UINT32 AlwaysUseDoubleBuffering:1;\ + UINT32 PassQueryDirectoryFileName:1; /* pass FileName during QueryDirectory (GetDirInfoByName) */\ + UINT32 FlushAndPurgeOnCleanup:1; /* keeps file off "standby" list */\ + UINT32 DeviceControl:1; /* support user-mode ioctl handling */\ + /* user-mode flags */\ + UINT32 UmFileContextIsUserContext2:1; /* user mode: FileContext parameter is UserContext2 */\ + UINT32 UmFileContextIsFullContext:1; /* user mode: FileContext parameter is FullContext */\ + UINT32 UmNoReparsePointsDirCheck:1; /* user mode: no dir option check for reparse points */\ + UINT32 UmReservedFlags:5;\ + /* additional kernel-mode flags */\ + UINT32 AllowOpenInKernelMode:1; /* allow kernel mode to open files when possible */\ + UINT32 CasePreservedExtendedAttributes:1; /* preserve case of EA (default is UPPERCASE) */\ + UINT32 WslFeatures:1; /* support features required for WSLinux */\ + UINT32 DirectoryMarkerAsNextOffset:1; /* directory marker is next offset instead of last name */\ + UINT32 RejectIrpPriorToTransact0:1; /* DEPRECATED: reject IRP's prior to FspFsctlTransact0 */\ + UINT32 SupportsPosixUnlinkRename:1; /* file system supports POSIX-style unlink and rename */\ + UINT32 PostDispositionWhenNecessaryOnly:1; /* post Disposition for dirs or READONLY attr check */\ + UINT32 KmReservedFlags:1;\ + WCHAR Prefix[FSP_FSCTL_VOLUME_PREFIX_SIZE / sizeof(WCHAR)]; /* UNC prefix (\Server\Share) */\ + WCHAR FileSystemName[FSP_FSCTL_VOLUME_FSNAME_SIZE / sizeof(WCHAR)]; +#define FSP_FSCTL_VOLUME_PARAMS_V1_FIELD_DEFN\ + /* additional fields; specify .Version == sizeof(FSP_FSCTL_VOLUME_PARAMS) */\ + UINT32 VolumeInfoTimeoutValid:1; /* VolumeInfoTimeout field is valid */\ + UINT32 DirInfoTimeoutValid:1; /* DirInfoTimeout field is valid */\ + UINT32 SecurityTimeoutValid:1; /* SecurityTimeout field is valid*/\ + UINT32 StreamInfoTimeoutValid:1; /* StreamInfoTimeout field is valid */\ + UINT32 EaTimeoutValid:1; /* EaTimeout field is valid */\ + UINT32 KmAdditionalReservedFlags:27;\ + UINT32 VolumeInfoTimeout; /* volume info timeout (millis); overrides FileInfoTimeout */\ + UINT32 DirInfoTimeout; /* dir info timeout (millis); overrides FileInfoTimeout */\ + UINT32 SecurityTimeout; /* security info timeout (millis); overrides FileInfoTimeout */\ + UINT32 StreamInfoTimeout; /* stream info timeout (millis); overrides FileInfoTimeout */\ + UINT32 EaTimeout; /* EA timeout (millis); overrides FileInfoTimeout */\ + UINT32 FsextControlCode;\ + UINT32 Reserved32[1];\ + UINT64 Reserved64[2]; +typedef struct +{ + FSP_FSCTL_VOLUME_PARAMS_V0_FIELD_DEFN +} FSP_FSCTL_VOLUME_PARAMS_V0; +FSP_FSCTL_STATIC_ASSERT(456 == sizeof(FSP_FSCTL_VOLUME_PARAMS_V0), + "sizeof(FSP_FSCTL_VOLUME_PARAMS_V0) must be exactly 456."); +typedef struct +{ + FSP_FSCTL_VOLUME_PARAMS_V0_FIELD_DEFN + FSP_FSCTL_VOLUME_PARAMS_V1_FIELD_DEFN +} FSP_FSCTL_VOLUME_PARAMS; +FSP_FSCTL_STATIC_ASSERT(504 == sizeof(FSP_FSCTL_VOLUME_PARAMS), + "sizeof(FSP_FSCTL_VOLUME_PARAMS) is currently 504. Update this assertion check if it changes."); +typedef struct +{ + UINT64 TotalSize; + UINT64 FreeSize; + UINT16 VolumeLabelLength; + WCHAR VolumeLabel[32]; +} FSP_FSCTL_VOLUME_INFO; +FSP_FSCTL_STATIC_ASSERT(88 == sizeof(FSP_FSCTL_VOLUME_INFO), + "sizeof(FSP_FSCTL_VOLUME_INFO) must be exactly 88."); +typedef struct +{ + UINT32 FileAttributes; + UINT32 ReparseTag; + UINT64 AllocationSize; + UINT64 FileSize; + UINT64 CreationTime; + UINT64 LastAccessTime; + UINT64 LastWriteTime; + UINT64 ChangeTime; + UINT64 IndexNumber; + UINT32 HardLinks; /* unimplemented: set to 0 */ + UINT32 EaSize; +} FSP_FSCTL_FILE_INFO; +FSP_FSCTL_STATIC_ASSERT(72 == sizeof(FSP_FSCTL_FILE_INFO), + "sizeof(FSP_FSCTL_FILE_INFO) must be exactly 72."); +typedef struct +{ + FSP_FSCTL_FILE_INFO FileInfo; + PWSTR NormalizedName; + UINT16 NormalizedNameSize; +} FSP_FSCTL_OPEN_FILE_INFO; +typedef struct +{ + UINT16 Size; + FSP_FSCTL_FILE_INFO FileInfo; + union + { + UINT64 NextOffset; + UINT8 Padding[24]; + /* make struct as big as FILE_ID_BOTH_DIR_INFORMATION; allows for in-place copying */ + } DUMMYUNIONNAME; + WCHAR FileNameBuf[]; +} FSP_FSCTL_DIR_INFO; +FSP_FSCTL_STATIC_ASSERT(104 == sizeof(FSP_FSCTL_DIR_INFO), + "sizeof(FSP_FSCTL_DIR_INFO) must be exactly 104."); +typedef struct +{ + UINT16 Size; + UINT64 StreamSize; + UINT64 StreamAllocationSize; + WCHAR StreamNameBuf[]; +} FSP_FSCTL_STREAM_INFO; +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; +} FSP_FSCTL_TRANSACT_FULL_CONTEXT; +typedef struct +{ + UINT16 Offset; + UINT16 Size; +} FSP_FSCTL_TRANSACT_BUF; +typedef struct +{ + UINT16 Version; + UINT16 Size; + UINT32 Kind; + UINT64 Hint; + union + { + struct + { + UINT32 CreateOptions; /* Disposition: high 8 bits; Options: low 24 bits */ + UINT32 FileAttributes; /* file attributes for new files */ + FSP_FSCTL_TRANSACT_BUF SecurityDescriptor; /* security descriptor for new files */ + UINT64 AllocationSize; /* initial allocation size */ + UINT64 AccessToken; /* request access token (PID,HANDLE) */ + UINT32 DesiredAccess; /* FILE_{READ_DATA,WRITE_DATA,etc.} */ + UINT32 GrantedAccess; /* FILE_{READ_DATA,WRITE_DATA,etc.} */ + UINT32 ShareAccess; /* FILE_SHARE_{READ,WRITE,DELETE} */ + FSP_FSCTL_TRANSACT_BUF Ea; /* extended attributes or reparse point buffer */ + UINT32 UserMode:1; /* request originated in user mode */ + UINT32 HasTraversePrivilege:1; /* requestor has TOKEN_HAS_TRAVERSE_PRIVILEGE */ + UINT32 HasBackupPrivilege:1; /* requestor has TOKEN_HAS_BACKUP_PRIVILEGE */ + UINT32 HasRestorePrivilege:1; /* requestor has TOKEN_HAS_RESTORE_PRIVILEGE */ + UINT32 OpenTargetDirectory:1; /* open target dir and report FILE_{EXISTS,DOES_NOT_EXIST} */ + UINT32 CaseSensitive:1; /* FileName comparisons should be case-sensitive */ + UINT32 HasTrailingBackslash:1; /* FileName had trailing backslash */ + UINT32 AcceptsSecurityDescriptor:1; + UINT32 EaIsReparsePoint:1; /* Ea buffer is reparse point */ + UINT32 ReservedFlags:24; + UINT16 NamedStream; /* request targets named stream; colon offset in FileName */ + } Create; + struct + { + UINT64 UserContext; + UINT64 UserContext2; + UINT32 FileAttributes; /* file attributes for overwritten/superseded files */ + UINT64 AllocationSize; /* allocation size for overwritten/superseded files */ + UINT32 Supersede:1; /* 0: FILE_OVERWRITE operation, 1: FILE_SUPERSEDE operation */ + FSP_FSCTL_TRANSACT_BUF Ea; /* extended attributes buffer */ + } Overwrite; + struct + { + UINT64 UserContext; + UINT64 UserContext2; + UINT32 Delete:1; /* file must be deleted */ + UINT32 SetAllocationSize:1; + UINT32 SetArchiveBit:1; + UINT32 SetLastAccessTime:1; + UINT32 SetLastWriteTime:1; + UINT32 SetChangeTime:1; + } Cleanup; + struct + { + UINT64 UserContext; + UINT64 UserContext2; + } Close; + struct + { + UINT64 UserContext; + UINT64 UserContext2; + UINT64 Address; + UINT64 Offset; + UINT32 Length; + UINT32 Key; + } Read; + struct + { + UINT64 UserContext; + UINT64 UserContext2; + UINT64 Address; + UINT64 Offset; + UINT32 Length; + UINT32 Key; + UINT32 ConstrainedIo:1; + } Write; + struct + { + UINT64 UserContext; + UINT64 UserContext2; + } QueryInformation; + struct + { + UINT64 UserContext; + UINT64 UserContext2; + UINT32 FileInformationClass; + union + { + struct + { + UINT64 AllocationSize; + } Allocation; + struct + { + UINT32 FileAttributes; + UINT64 CreationTime; + UINT64 LastAccessTime; + UINT64 LastWriteTime; + UINT64 ChangeTime; + } Basic; + struct + { + UINT32 Delete:1; + } Disposition; + struct + { + UINT32 Flags; + } DispositionEx; + struct + { + UINT64 FileSize; + } EndOfFile; + struct + { + FSP_FSCTL_TRANSACT_BUF NewFileName; + UINT64 AccessToken; /* request access token (PID,HANDLE) */ + } Rename; + struct + { + FSP_FSCTL_TRANSACT_BUF NewFileName; + UINT64 AccessToken; /* request access token (PID,HANDLE) */ + UINT32 Flags; + } RenameEx; + } Info; + } SetInformation; + struct + { + UINT64 UserContext; + UINT64 UserContext2; + } QueryEa; + struct + { + UINT64 UserContext; + UINT64 UserContext2; + FSP_FSCTL_TRANSACT_BUF Ea; + } SetEa; + struct + { + UINT64 UserContext; + UINT64 UserContext2; + } FlushBuffers; + struct + { + UINT32 FsInformationClass; + union + { + struct + { + FSP_FSCTL_TRANSACT_BUF VolumeLabel; + } Label; + } Info; + } SetVolumeInformation; + struct + { + UINT64 UserContext; + UINT64 UserContext2; + UINT64 Address; + UINT32 Length; + FSP_FSCTL_TRANSACT_BUF Pattern; + FSP_FSCTL_TRANSACT_BUF Marker; + UINT32 CaseSensitive:1; /* FileName comparisons should be case-sensitive */ + UINT32 PatternIsFileName:1; /* Pattern does not contain wildcards */ + } QueryDirectory; + struct + { + UINT64 UserContext; + UINT64 UserContext2; + UINT32 FsControlCode; + FSP_FSCTL_TRANSACT_BUF Buffer; + UINT16 TargetOnFileSystem; /* the target of the symbolic link is on this file system */ + } FileSystemControl; + struct + { + UINT64 UserContext; + UINT64 UserContext2; + UINT32 IoControlCode; + FSP_FSCTL_TRANSACT_BUF Buffer; + UINT32 OutputLength; + } DeviceControl; + struct + { + UINT64 UserContext; + UINT64 UserContext2; + } QuerySecurity; + struct + { + UINT64 UserContext; + UINT64 UserContext2; + UINT32 SecurityInformation; + FSP_FSCTL_TRANSACT_BUF SecurityDescriptor; + } SetSecurity; + struct + { + UINT64 UserContext; + UINT64 UserContext2; + } QueryStreamInformation; + } Req; + FSP_FSCTL_TRANSACT_BUF FileName; + /* Create,Cleanup,SetInformation{Disposition,Rename},FileSystemControl{ReparsePoint} */ + FSP_FSCTL_DECLSPEC_ALIGN UINT8 Buffer[]; +} FSP_FSCTL_TRANSACT_REQ; +typedef struct +{ + UINT16 Version; + UINT16 Size; + UINT32 Kind; + UINT64 Hint; + struct + { + UINT32 Information; + UINT32 Status; + } IoStatus; + union + { + union + { + /* IoStatus.Status == STATUS_SUCCESS */ + struct + { + UINT64 UserContext; /* user context associated with file node */ + UINT64 UserContext2; /* user context associated with file descriptor (handle) */ + UINT32 GrantedAccess; /* FILE_{READ_DATA,WRITE_DATA,etc.} */ + FSP_FSCTL_TRANSACT_BUF SecurityDescriptor; + FSP_FSCTL_FILE_INFO FileInfo; + FSP_FSCTL_TRANSACT_BUF FileName; + UINT32 DisableCache:1; + UINT32 HasSecurityDescriptor:1; + } Opened; + /* IoStatus.Status == STATUS_REPARSE */ + struct + { + FSP_FSCTL_TRANSACT_BUF Buffer; + } Reparse; + } Create; + struct + { + FSP_FSCTL_FILE_INFO FileInfo; + } Overwrite; + struct + { + FSP_FSCTL_FILE_INFO FileInfo; + } Write; + struct + { + FSP_FSCTL_FILE_INFO FileInfo; + } QueryInformation; + struct + { + FSP_FSCTL_FILE_INFO FileInfo; /* valid: File{Allocation,Basic,EndOfFile}Information */ + } SetInformation; + struct + { + FSP_FSCTL_TRANSACT_BUF Ea; + } QueryEa; + struct + { + FSP_FSCTL_FILE_INFO FileInfo; + FSP_FSCTL_TRANSACT_BUF Ea; /* Size==0 means no extended atttributed returned */ + } SetEa; + struct + { + FSP_FSCTL_FILE_INFO FileInfo; /* valid when flushing file (not volume) */ + } FlushBuffers; + struct + { + FSP_FSCTL_VOLUME_INFO VolumeInfo; + } QueryVolumeInformation; + struct + { + FSP_FSCTL_VOLUME_INFO VolumeInfo; + } SetVolumeInformation; + struct + { + FSP_FSCTL_TRANSACT_BUF Buffer; + } FileSystemControl; + struct + { + FSP_FSCTL_TRANSACT_BUF Buffer; + } DeviceControl; + struct + { + FSP_FSCTL_TRANSACT_BUF SecurityDescriptor; + } QuerySecurity; + struct + { + FSP_FSCTL_TRANSACT_BUF SecurityDescriptor; /* Size==0 means no security descriptor returned */ + } SetSecurity; + struct + { + FSP_FSCTL_TRANSACT_BUF Buffer; + } QueryStreamInformation; + } Rsp; + FSP_FSCTL_DECLSPEC_ALIGN UINT8 Buffer[]; +} FSP_FSCTL_TRANSACT_RSP; +#pragma warning(pop) +FSP_FSCTL_STATIC_ASSERT(FSP_FSCTL_TRANSACT_RSP_BUFFER_SIZEMAX > FSP_FSCTL_TRANSACT_PATH_SIZEMAX, + "FSP_FSCTL_TRANSACT_RSP_BUFFER_SIZEMAX must be greater than FSP_FSCTL_TRANSACT_PATH_SIZEMAX " + "to detect when a normalized name has been set during a Create/Open request."); +static inline BOOLEAN FspFsctlTransactCanProduceRequest( + FSP_FSCTL_TRANSACT_REQ *Request, PVOID RequestBufEnd) +{ + return (PUINT8)Request + FSP_FSCTL_TRANSACT_REQ_SIZEMAX <= (PUINT8)RequestBufEnd; +} +static inline FSP_FSCTL_TRANSACT_REQ *FspFsctlTransactProduceRequest( + FSP_FSCTL_TRANSACT_REQ *Request, SIZE_T RequestSize) +{ + PVOID NextRequest = (PUINT8)Request + FSP_FSCTL_DEFAULT_ALIGN_UP(RequestSize); + return (FSP_FSCTL_TRANSACT_REQ *)NextRequest; +} +static inline FSP_FSCTL_TRANSACT_REQ *FspFsctlTransactConsumeRequest( + FSP_FSCTL_TRANSACT_REQ *Request, PVOID RequestBufEnd) +{ + if ((PUINT8)Request + sizeof(Request->Size) > (PUINT8)RequestBufEnd || + sizeof(FSP_FSCTL_TRANSACT_REQ) > Request->Size) + return 0; + PVOID NextRequest = (PUINT8)Request + FSP_FSCTL_DEFAULT_ALIGN_UP(Request->Size); + return NextRequest <= RequestBufEnd ? (FSP_FSCTL_TRANSACT_REQ *)NextRequest : 0; +} +static inline BOOLEAN FspFsctlTransactCanProduceResponse( + FSP_FSCTL_TRANSACT_RSP *Response, PVOID ResponseBufEnd) +{ + return (PUINT8)Response + FSP_FSCTL_TRANSACT_RSP_SIZEMAX <= (PUINT8)ResponseBufEnd; +} +static inline FSP_FSCTL_TRANSACT_RSP *FspFsctlTransactProduceResponse( + FSP_FSCTL_TRANSACT_RSP *Response, SIZE_T ResponseSize) +{ + PVOID NextResponse = (PUINT8)Response + FSP_FSCTL_DEFAULT_ALIGN_UP(ResponseSize); + return (FSP_FSCTL_TRANSACT_RSP *)NextResponse; +} +static inline FSP_FSCTL_TRANSACT_RSP *FspFsctlTransactConsumeResponse( + FSP_FSCTL_TRANSACT_RSP *Response, PVOID ResponseBufEnd) +{ + if ((PUINT8)Response + sizeof(Response->Size) > (PUINT8)ResponseBufEnd || + sizeof(FSP_FSCTL_TRANSACT_RSP) > Response->Size) + return 0; + PVOID NextResponse = (PUINT8)Response + FSP_FSCTL_DEFAULT_ALIGN_UP(Response->Size); + return NextResponse <= ResponseBufEnd ? (FSP_FSCTL_TRANSACT_RSP *)NextResponse : 0; +} + +#if !defined(_KERNEL_MODE) +FSP_API NTSTATUS FspFsctlCreateVolume(PWSTR DevicePath, + const FSP_FSCTL_VOLUME_PARAMS *VolumeParams, + PWCHAR VolumeNameBuf, SIZE_T VolumeNameSize, + PHANDLE PVolumeHandle); +FSP_API NTSTATUS FspFsctlMakeMountdev(HANDLE VolumeHandle, + BOOLEAN Persistent, GUID *UniqueId); +FSP_API NTSTATUS FspFsctlUseMountmgr(HANDLE VolumeHandle, + PWSTR MountPoint); +FSP_API NTSTATUS FspFsctlTransact(HANDLE VolumeHandle, + PVOID ResponseBuf, SIZE_T ResponseBufSize, + PVOID RequestBuf, SIZE_T *PRequestBufSize, + BOOLEAN Batch); +FSP_API NTSTATUS FspFsctlStop(HANDLE VolumeHandle); +FSP_API NTSTATUS FspFsctlStop0(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); +FSP_API NTSTATUS FspFsctlServiceVersion(PUINT32 PVersion); +FSP_API NTSTATUS FspFsctlStartService(VOID); +FSP_API NTSTATUS FspFsctlStopService(VOID); +FSP_API NTSTATUS FspFsctlEnumServices( + VOID (*EnumFn)(PVOID Context, PWSTR ServiceName, BOOLEAN Running), + PVOID Context); + +typedef struct +{ + /* in */ + HANDLE VolumeHandle; /* volume handle returned by FspFsctlCreateVolume */ + PWSTR VolumeName; /* volume name returned by FspFsctlCreateVolume */ + PSECURITY_DESCRIPTOR Security; /* optional: security descriptor for directories */ + UINT64 Reserved; /* reserved for future use */ + /* in/out */ + PWSTR MountPoint; /* FspMountSet sets drive in buffer when passed "*:" */ + HANDLE MountHandle; /* FspMountSet sets, FspMountRemove uses */ +} FSP_MOUNT_DESC; +FSP_API NTSTATUS FspMountSet(FSP_MOUNT_DESC *Desc); +FSP_API NTSTATUS FspMountRemove(FSP_MOUNT_DESC *Desc); +#endif + +/* + * Atomics + * + * See https://www.cl.cam.ac.uk/~pes20/cpp/cpp0xmappings.html (https://archive.is/mJfFX) + */ +#if _MSC_VER >= 1920 /* VS2019 or later */ +__int32 __iso_volatile_load32(const volatile __int32 *); +void __iso_volatile_store32(volatile __int32 *, __int32); +__int64 __iso_volatile_load64(const volatile __int64 *); +void __iso_volatile_store64(volatile __int64 *, __int64); +#define FSP_INTERLOCKED__LOAD32(p) __iso_volatile_load32(p) +#define FSP_INTERLOCKED__STORE32(p,v) __iso_volatile_store32(p,v) +#define FSP_INTERLOCKED__LOAD64(p) __iso_volatile_load64(p) +#define FSP_INTERLOCKED__STORE64(p,v) __iso_volatile_store64(p,v) +#else +#define FSP_INTERLOCKED__LOAD32(p) (*(p)) +#define FSP_INTERLOCKED__STORE32(p,v) (*(p) = (v)) +#define FSP_INTERLOCKED__LOAD64(p) (*(p)) +#define FSP_INTERLOCKED__STORE64(p,v) (*(p) = (v)) +#endif +static inline INT32 FspInterlockedLoad32(INT32 volatile *p) +{ +#if defined(_M_ARM64) + void __dmb(unsigned int); + INT32 v = FSP_INTERLOCKED__LOAD32(p); + __dmb(0xb); + return v; + +#elif defined(_M_X64) || defined(_M_IX86) + void _ReadWriteBarrier(void); + INT32 v = FSP_INTERLOCKED__LOAD32(p); + _ReadWriteBarrier(); + return v; + +#endif +} +static inline VOID FspInterlockedStore32(INT32 volatile *p, INT32 v) +{ +#if defined(_M_ARM64) + void __dmb(unsigned int); + __dmb(0xb); + FSP_INTERLOCKED__STORE32(p, v); + __dmb(0xb); + +#elif defined(_M_X64) || defined(_M_IX86) + long _InterlockedExchange(long volatile *, long); + _InterlockedExchange((long volatile *)p, v); + +#endif +} +static inline VOID *FspInterlockedLoadPointer(VOID *volatile *p) +{ +#if defined(_M_ARM64) + void __dmb(unsigned int); + VOID *v = (VOID *)FSP_INTERLOCKED__LOAD64((__int64 volatile *)(p)); + __dmb(0xb); + return v; + +#elif defined(_M_X64) + void _ReadWriteBarrier(void); + VOID *v = (VOID *)FSP_INTERLOCKED__LOAD64((__int64 volatile *)(p)); + _ReadWriteBarrier(); + return v; + +#elif defined(_M_IX86) + void _ReadWriteBarrier(void); + VOID *v = (VOID *)FSP_INTERLOCKED__LOAD32((__int32 volatile *)(p)); + _ReadWriteBarrier(); + return v; + +#endif +} +static inline VOID FspInterlockedStorePointer(VOID *volatile *p, VOID *v) +{ +#if defined(_M_ARM64) + void __dmb(unsigned int); + __dmb(0xb); + FSP_INTERLOCKED__STORE64((__int64 volatile *)(p), (__int64)(v)); + __dmb(0xb); + +#elif defined(_M_X64) || defined(_M_IX86) + void *_InterlockedExchangePointer(void *volatile *, void *); + _InterlockedExchangePointer(p, v); + +#endif +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/support/3rd_party/winfsp-2.0/inc/winfsp/launch.h b/support/3rd_party/winfsp-2.1/inc/winfsp/launch.h similarity index 97% rename from support/3rd_party/winfsp-2.0/inc/winfsp/launch.h rename to support/3rd_party/winfsp-2.1/inc/winfsp/launch.h index 93b8b6d1..a07b916a 100644 --- a/support/3rd_party/winfsp-2.0/inc/winfsp/launch.h +++ b/support/3rd_party/winfsp-2.1/inc/winfsp/launch.h @@ -1,350 +1,350 @@ -/** - * @file winfsp/launch.h - * WinFsp Launch API. - * - * In order to use the WinFsp Launch API a program must include <winfsp/launch.h> - * and link with the winfsp_x64.dll (or winfsp_x86.dll) library. - * - * @copyright 2015-2022 Bill Zissimopoulos - */ -/* - * This file is part of WinFsp. - * - * You can redistribute it and/or modify it under the terms of the GNU - * General Public License version 3 as published by the Free Software - * Foundation. - * - * Licensees holding a valid commercial license may use this software - * in accordance with the commercial license agreement provided in - * conjunction with the software. The terms and conditions of any such - * commercial license agreement shall govern, supersede, and render - * ineffective any application of the GPLv3 license to this software, - * notwithstanding of any reference thereto in the software or - * associated repository. - */ - -#ifndef WINFSP_LAUNCH_H_INCLUDED -#define WINFSP_LAUNCH_H_INCLUDED - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define FSP_LAUNCH_REGKEY FSP_FSCTL_PRODUCT_REGKEY "\\Services" -#define FSP_LAUNCH_REGKEY_WOW64 FSP_FSCTL_PRODUCT_REGKEY_WOW64 -#define FSP_LAUNCH_FULL_REGKEY FSP_FSCTL_PRODUCT_FULL_REGKEY "\\Services" - -#define FSP_LAUNCH_PIPE_NAME "\\\\.\\pipe\\" FSP_FSCTL_PRODUCT_NAME ".{14E7137D-22B4-437A-B0C1-D21D1BDF3767}" -#define FSP_LAUNCH_PIPE_BUFFER_SIZE 4096 -#define FSP_LAUNCH_PIPE_OWNER ((PSID)WinLocalSystemSid) - -/* - * The launcher named pipe SDDL gives full access to LocalSystem and Administrators and - * GENERIC_READ and FILE_WRITE_DATA access to Everyone. We are careful not to give the - * FILE_CREATE_PIPE_INSTANCE right to Everyone to disallow the creation of additional - * pipe instances. - */ -#define FSP_LAUNCH_PIPE_SDDL "O:SYG:SYD:P(A;;GA;;;SY)(A;;GA;;;BA)(A;;GRDCCR;;;WD)" - -/* - * The default service instance SDDL gives full access to LocalSystem and Administrators. - * The only possible service instance rights are as follows: - * RP SERVICE_START - * WP SERVICE_STOP - * LC SERVICE_QUERY_STATUS - * - * To create a service that can be started, stopped or queried by Everyone, you can set - * the following SDDL: - * D:P(A;;RPWPLC;;;WD) - */ -#define FSP_LAUNCH_SERVICE_DEFAULT_SDDL "D:P(A;;RPWPLC;;;SY)(A;;RPWPLC;;;BA)" -#define FSP_LAUNCH_SERVICE_WORLD_SDDL "D:P(A;;RPWPLC;;;WD)" - -enum -{ - FspLaunchCmdStart = 'S', /* requires: SERVICE_START */ - FspLaunchCmdStartWithSecret = 'X', /* requires: SERVICE_START */ - FspLaunchCmdStop = 'T', /* requires: SERVICE_STOP */ - FspLaunchCmdGetInfo = 'I', /* requires: SERVICE_QUERY_STATUS */ - FspLaunchCmdGetNameList = 'L', /* requires: none*/ - FspLaunchCmdDefineDosDevice = 'D', /* internal: do not use! */ - FspLaunchCmdQuit = 'Q', /* DEBUG version only */ -}; - -enum -{ - FspLaunchCmdSuccess = '$', - FspLaunchCmdFailure = '!', -}; - -/** - * @group Launch Control - */ -/** - * Call launcher pipe. - * - * This function is used to send a command to the launcher and receive a response. - * - * @param Command - * Launcher command to send. For example, the 'L' launcher command instructs - * the launcher to list all running service instances. - * @param Argc - * Command argument count. May be 0. - * @param Argv - * Command argument array. May be NULL. - * @param Argl - * Command argument length array. May be NULL. If this is NULL all command arguments - * are assumed to be NULL-terminated strings. It is also possible for specific arguments - * to be NULL-terminated; in this case pass -1 in the corresponding Argl position. - * @param Buffer - * Buffer that receives the command response. May be NULL. - * @param PSize - * Pointer to a ULONG. On input it contains the size of the Buffer. On output it - * contains the number of bytes transferred. May be NULL. - * @param PLauncherError - * Receives the launcher error if any. This is always a Win32 error code. May not be NULL. - * @return - * STATUS_SUCCESS if the command is sent successfully to the launcher, even if the launcher - * returns an error. Other status codes indicate a communication error. Launcher errors are - * reported through PLauncherError. - */ -FSP_API NTSTATUS FspLaunchCallLauncherPipe( - WCHAR Command, ULONG Argc, PWSTR *Argv, ULONG *Argl, - PWSTR Buffer, PULONG PSize, - PULONG PLauncherError); -/** - * Call launcher pipe. - * - * This function is used to send a command to the launcher and receive a response. - * - * @param Command - * Launcher command to send. For example, the 'L' launcher command instructs - * the launcher to list all running service instances. - * @param Argc - * Command argument count. May be 0. - * @param Argv - * Command argument array. May be NULL. - * @param Argl - * Command argument length array. May be NULL. If this is NULL all command arguments - * are assumed to be NULL-terminated strings. It is also possible for specific arguments - * to be NULL-terminated; in this case pass -1 in the corresponding Argl position. - * @param Buffer - * Buffer that receives the command response. May be NULL. - * @param PSize - * Pointer to a ULONG. On input it contains the size of the Buffer. On output it - * contains the number of bytes transferred. May be NULL. - * @param AllowImpersonation - * Allow caller to be impersonated by launcher. - * @param PLauncherError - * Receives the launcher error if any. This is always a Win32 error code. May not be NULL. - * @return - * STATUS_SUCCESS if the command is sent successfully to the launcher, even if the launcher - * returns an error. Other status codes indicate a communication error. Launcher errors are - * reported through PLauncherError. - */ -FSP_API NTSTATUS FspLaunchCallLauncherPipeEx( - WCHAR Command, ULONG Argc, PWSTR *Argv, ULONG *Argl, - PWSTR Buffer, PULONG PSize, - BOOLEAN AllowImpersonation, - PULONG PLauncherError); -/** - * Start a service instance. - * - * @param ClassName - * Class name of the service instance to start. - * @param InstanceName - * Instance name of the service instance to start. - * @param Argc - * Service instance argument count. May be 0. - * @param Argv - * Service instance argument array. May be NULL. - * @param HasSecret - * Whether the last argument in Argv is assumed to be a secret (e.g. password) or not. - * Secrets are passed to service instances through standard input rather than the command - * line. - * @param PLauncherError - * Receives the launcher error if any. This is always a Win32 error code. May not be NULL. - * @return - * STATUS_SUCCESS if the command is sent successfully to the launcher, even if the launcher - * returns an error. Other status codes indicate a communication error. Launcher errors are - * reported through PLauncherError. - */ -FSP_API NTSTATUS FspLaunchStart( - PWSTR ClassName, PWSTR InstanceName, ULONG Argc, PWSTR *Argv, - BOOLEAN HasSecret, - PULONG PLauncherError); -/** - * Start a service instance. - * - * @param ClassName - * Class name of the service instance to start. - * @param InstanceName - * Instance name of the service instance to start. - * @param Argc - * Service instance argument count. May be 0. - * @param Argv - * Service instance argument array. May be NULL. - * @param HasSecret - * Whether the last argument in Argv is assumed to be a secret (e.g. password) or not. - * Secrets are passed to service instances through standard input rather than the command - * line. - * @param AllowImpersonation - * Allow caller to be impersonated by launcher. - * @param PLauncherError - * Receives the launcher error if any. This is always a Win32 error code. May not be NULL. - * @return - * STATUS_SUCCESS if the command is sent successfully to the launcher, even if the launcher - * returns an error. Other status codes indicate a communication error. Launcher errors are - * reported through PLauncherError. - */ -FSP_API NTSTATUS FspLaunchStartEx( - PWSTR ClassName, PWSTR InstanceName, ULONG Argc, PWSTR *Argv, - BOOLEAN HasSecret, - BOOLEAN AllowImpersonation, - PULONG PLauncherError); -/** - * Stop a service instance. - * - * @param ClassName - * Class name of the service instance to stop. - * @param InstanceName - * Instance name of the service instance to stop. - * @param PLauncherError - * Receives the launcher error if any. This is always a Win32 error code. May not be NULL. - * @return - * STATUS_SUCCESS if the command is sent successfully to the launcher, even if the launcher - * returns an error. Other status codes indicate a communication error. Launcher errors are - * reported through PLauncherError. - */ -FSP_API NTSTATUS FspLaunchStop( - PWSTR ClassName, PWSTR InstanceName, - PULONG PLauncherError); -/** - * Get information about a service instance. - * - * The information is a list of NULL-terminated strings: the class name of the service instance, - * the instance name of the service instance and the full command line used to start the service - * instance. - * - * @param ClassName - * Class name of the service instance to stop. - * @param InstanceName - * Instance name of the service instance to stop. - * @param Buffer - * Buffer that receives the command response. May be NULL. - * @param PSize - * Pointer to a ULONG. On input it contains the size of the Buffer. On output it - * contains the number of bytes transferred. May be NULL. - * @param PLauncherError - * Receives the launcher error if any. This is always a Win32 error code. May not be NULL. - * @return - * STATUS_SUCCESS if the command is sent successfully to the launcher, even if the launcher - * returns an error. Other status codes indicate a communication error. Launcher errors are - * reported through PLauncherError. - */ -FSP_API NTSTATUS FspLaunchGetInfo( - PWSTR ClassName, PWSTR InstanceName, - PWSTR Buffer, PULONG PSize, - PULONG PLauncherError); -/** - * List service instances. - * - * The information is a list of pairs of NULL-terminated strings. Each pair contains the class - * name and instance name of a service instance. All currently running service instances are - * listed. - * - * @param Buffer - * Buffer that receives the command response. May be NULL. - * @param PSize - * Pointer to a ULONG. On input it contains the size of the Buffer. On output it - * contains the number of bytes transferred. May be NULL. - * @param PLauncherError - * Receives the launcher error if any. This is always a Win32 error code. May not be NULL. - * @return - * STATUS_SUCCESS if the command is sent successfully to the launcher, even if the launcher - * returns an error. Other status codes indicate a communication error. Launcher errors are - * reported through PLauncherError. - */ -FSP_API NTSTATUS FspLaunchGetNameList( - PWSTR Buffer, PULONG PSize, - PULONG PLauncherError); - -/** - * @group Service Registry - */ -#pragma warning(push) -#pragma warning(disable:4200) /* zero-sized array in struct/union */ -/** - * Service registry record. - */ -typedef struct _FSP_LAUNCH_REG_RECORD -{ - PWSTR Agent; - PWSTR Executable; - PWSTR CommandLine; - PWSTR WorkDirectory; - PWSTR RunAs; - PWSTR Security; - PWSTR AuthPackage; - PWSTR Stderr; - PVOID Reserved0[4]; - ULONG JobControl; - ULONG Credentials; - ULONG AuthPackageId; - ULONG Recovery; - ULONG Reserved1[4]; - UINT8 Buffer[]; -} FSP_LAUNCH_REG_RECORD; -#pragma warning(pop) -/** - * Add/change/delete a service registry record. - * - * @param ClassName - * The service class name. - * @param Record - * The record to set in the registry. If NULL, the registry record is deleted. - * @return - * STATUS_SUCCESS or error code. - */ -FSP_API NTSTATUS FspLaunchRegSetRecord( - PWSTR ClassName, - const FSP_LAUNCH_REG_RECORD *Record); -/** - * Get a service registry record. - * - * @param ClassName - * The service class name. - * @param Agent - * The name of the agent that is retrieving the service record. This API matches - * the supplied Agent against the Agent in the service record and it only returns - * the record if they match. Pass NULL to match any Agent. - * @param PRecord - * Pointer to a record pointer. Memory for the service record will be allocated - * and a pointer to it will be stored at this address. This memory must be later - * freed using FspLaunchRegFreeRecord. - * @return - * STATUS_SUCCESS or error code. - * @see - * FspLaunchRegFreeRecord - */ -FSP_API NTSTATUS FspLaunchRegGetRecord( - PWSTR ClassName, PWSTR Agent, - FSP_LAUNCH_REG_RECORD **PRecord); -/** - * Free a service registry record. - * - * @param Record - * The service record to free. - * @see - * FspLaunchRegGetRecord - */ -FSP_API VOID FspLaunchRegFreeRecord( - FSP_LAUNCH_REG_RECORD *Record); - -#ifdef __cplusplus -} -#endif - -#endif +/** + * @file winfsp/launch.h + * WinFsp Launch API. + * + * In order to use the WinFsp Launch API a program must include <winfsp/launch.h> + * and link with the winfsp_x64.dll (or winfsp_x86.dll) library. + * + * @copyright 2015-2025 Bill Zissimopoulos + */ +/* + * This file is part of WinFsp. + * + * You can redistribute it and/or modify it under the terms of the GNU + * General Public License version 3 as published by the Free Software + * Foundation. + * + * Licensees holding a valid commercial license may use this software + * in accordance with the commercial license agreement provided in + * conjunction with the software. The terms and conditions of any such + * commercial license agreement shall govern, supersede, and render + * ineffective any application of the GPLv3 license to this software, + * notwithstanding of any reference thereto in the software or + * associated repository. + */ + +#ifndef WINFSP_LAUNCH_H_INCLUDED +#define WINFSP_LAUNCH_H_INCLUDED + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define FSP_LAUNCH_REGKEY FSP_FSCTL_PRODUCT_REGKEY "\\Services" +#define FSP_LAUNCH_REGKEY_WOW64 FSP_FSCTL_PRODUCT_REGKEY_WOW64 +#define FSP_LAUNCH_FULL_REGKEY FSP_FSCTL_PRODUCT_FULL_REGKEY "\\Services" + +#define FSP_LAUNCH_PIPE_NAME "\\\\.\\pipe\\" FSP_FSCTL_PRODUCT_NAME ".{14E7137D-22B4-437A-B0C1-D21D1BDF3767}" +#define FSP_LAUNCH_PIPE_BUFFER_SIZE 4096 +#define FSP_LAUNCH_PIPE_OWNER ((PSID)WinLocalSystemSid) + +/* + * The launcher named pipe SDDL gives full access to LocalSystem and Administrators and + * GENERIC_READ and FILE_WRITE_DATA access to Everyone. We are careful not to give the + * FILE_CREATE_PIPE_INSTANCE right to Everyone to disallow the creation of additional + * pipe instances. + */ +#define FSP_LAUNCH_PIPE_SDDL "O:SYG:SYD:P(A;;GA;;;SY)(A;;GA;;;BA)(A;;GRDCCR;;;WD)" + +/* + * The default service instance SDDL gives full access to LocalSystem and Administrators. + * The only possible service instance rights are as follows: + * RP SERVICE_START + * WP SERVICE_STOP + * LC SERVICE_QUERY_STATUS + * + * To create a service that can be started, stopped or queried by Everyone, you can set + * the following SDDL: + * D:P(A;;RPWPLC;;;WD) + */ +#define FSP_LAUNCH_SERVICE_DEFAULT_SDDL "D:P(A;;RPWPLC;;;SY)(A;;RPWPLC;;;BA)" +#define FSP_LAUNCH_SERVICE_WORLD_SDDL "D:P(A;;RPWPLC;;;WD)" + +enum +{ + FspLaunchCmdStart = 'S', /* requires: SERVICE_START */ + FspLaunchCmdStartWithSecret = 'X', /* requires: SERVICE_START */ + FspLaunchCmdStop = 'T', /* requires: SERVICE_STOP */ + FspLaunchCmdGetInfo = 'I', /* requires: SERVICE_QUERY_STATUS */ + FspLaunchCmdGetNameList = 'L', /* requires: none*/ + FspLaunchCmdDefineDosDevice = 'D', /* internal: do not use! */ + FspLaunchCmdQuit = 'Q', /* DEBUG version only */ +}; + +enum +{ + FspLaunchCmdSuccess = '$', + FspLaunchCmdFailure = '!', +}; + +/** + * @group Launch Control + */ +/** + * Call launcher pipe. + * + * This function is used to send a command to the launcher and receive a response. + * + * @param Command + * Launcher command to send. For example, the 'L' launcher command instructs + * the launcher to list all running service instances. + * @param Argc + * Command argument count. May be 0. + * @param Argv + * Command argument array. May be NULL. + * @param Argl + * Command argument length array. May be NULL. If this is NULL all command arguments + * are assumed to be NULL-terminated strings. It is also possible for specific arguments + * to be NULL-terminated; in this case pass -1 in the corresponding Argl position. + * @param Buffer + * Buffer that receives the command response. May be NULL. + * @param PSize + * Pointer to a ULONG. On input it contains the size of the Buffer. On output it + * contains the number of bytes transferred. May be NULL. + * @param PLauncherError + * Receives the launcher error if any. This is always a Win32 error code. May not be NULL. + * @return + * STATUS_SUCCESS if the command is sent successfully to the launcher, even if the launcher + * returns an error. Other status codes indicate a communication error. Launcher errors are + * reported through PLauncherError. + */ +FSP_API NTSTATUS FspLaunchCallLauncherPipe( + WCHAR Command, ULONG Argc, PWSTR *Argv, ULONG *Argl, + PWSTR Buffer, PULONG PSize, + PULONG PLauncherError); +/** + * Call launcher pipe. + * + * This function is used to send a command to the launcher and receive a response. + * + * @param Command + * Launcher command to send. For example, the 'L' launcher command instructs + * the launcher to list all running service instances. + * @param Argc + * Command argument count. May be 0. + * @param Argv + * Command argument array. May be NULL. + * @param Argl + * Command argument length array. May be NULL. If this is NULL all command arguments + * are assumed to be NULL-terminated strings. It is also possible for specific arguments + * to be NULL-terminated; in this case pass -1 in the corresponding Argl position. + * @param Buffer + * Buffer that receives the command response. May be NULL. + * @param PSize + * Pointer to a ULONG. On input it contains the size of the Buffer. On output it + * contains the number of bytes transferred. May be NULL. + * @param AllowImpersonation + * Allow caller to be impersonated by launcher. + * @param PLauncherError + * Receives the launcher error if any. This is always a Win32 error code. May not be NULL. + * @return + * STATUS_SUCCESS if the command is sent successfully to the launcher, even if the launcher + * returns an error. Other status codes indicate a communication error. Launcher errors are + * reported through PLauncherError. + */ +FSP_API NTSTATUS FspLaunchCallLauncherPipeEx( + WCHAR Command, ULONG Argc, PWSTR *Argv, ULONG *Argl, + PWSTR Buffer, PULONG PSize, + BOOLEAN AllowImpersonation, + PULONG PLauncherError); +/** + * Start a service instance. + * + * @param ClassName + * Class name of the service instance to start. + * @param InstanceName + * Instance name of the service instance to start. + * @param Argc + * Service instance argument count. May be 0. + * @param Argv + * Service instance argument array. May be NULL. + * @param HasSecret + * Whether the last argument in Argv is assumed to be a secret (e.g. password) or not. + * Secrets are passed to service instances through standard input rather than the command + * line. + * @param PLauncherError + * Receives the launcher error if any. This is always a Win32 error code. May not be NULL. + * @return + * STATUS_SUCCESS if the command is sent successfully to the launcher, even if the launcher + * returns an error. Other status codes indicate a communication error. Launcher errors are + * reported through PLauncherError. + */ +FSP_API NTSTATUS FspLaunchStart( + PWSTR ClassName, PWSTR InstanceName, ULONG Argc, PWSTR *Argv, + BOOLEAN HasSecret, + PULONG PLauncherError); +/** + * Start a service instance. + * + * @param ClassName + * Class name of the service instance to start. + * @param InstanceName + * Instance name of the service instance to start. + * @param Argc + * Service instance argument count. May be 0. + * @param Argv + * Service instance argument array. May be NULL. + * @param HasSecret + * Whether the last argument in Argv is assumed to be a secret (e.g. password) or not. + * Secrets are passed to service instances through standard input rather than the command + * line. + * @param AllowImpersonation + * Allow caller to be impersonated by launcher. + * @param PLauncherError + * Receives the launcher error if any. This is always a Win32 error code. May not be NULL. + * @return + * STATUS_SUCCESS if the command is sent successfully to the launcher, even if the launcher + * returns an error. Other status codes indicate a communication error. Launcher errors are + * reported through PLauncherError. + */ +FSP_API NTSTATUS FspLaunchStartEx( + PWSTR ClassName, PWSTR InstanceName, ULONG Argc, PWSTR *Argv, + BOOLEAN HasSecret, + BOOLEAN AllowImpersonation, + PULONG PLauncherError); +/** + * Stop a service instance. + * + * @param ClassName + * Class name of the service instance to stop. + * @param InstanceName + * Instance name of the service instance to stop. + * @param PLauncherError + * Receives the launcher error if any. This is always a Win32 error code. May not be NULL. + * @return + * STATUS_SUCCESS if the command is sent successfully to the launcher, even if the launcher + * returns an error. Other status codes indicate a communication error. Launcher errors are + * reported through PLauncherError. + */ +FSP_API NTSTATUS FspLaunchStop( + PWSTR ClassName, PWSTR InstanceName, + PULONG PLauncherError); +/** + * Get information about a service instance. + * + * The information is a list of NULL-terminated strings: the class name of the service instance, + * the instance name of the service instance and the full command line used to start the service + * instance. + * + * @param ClassName + * Class name of the service instance to stop. + * @param InstanceName + * Instance name of the service instance to stop. + * @param Buffer + * Buffer that receives the command response. May be NULL. + * @param PSize + * Pointer to a ULONG. On input it contains the size of the Buffer. On output it + * contains the number of bytes transferred. May be NULL. + * @param PLauncherError + * Receives the launcher error if any. This is always a Win32 error code. May not be NULL. + * @return + * STATUS_SUCCESS if the command is sent successfully to the launcher, even if the launcher + * returns an error. Other status codes indicate a communication error. Launcher errors are + * reported through PLauncherError. + */ +FSP_API NTSTATUS FspLaunchGetInfo( + PWSTR ClassName, PWSTR InstanceName, + PWSTR Buffer, PULONG PSize, + PULONG PLauncherError); +/** + * List service instances. + * + * The information is a list of pairs of NULL-terminated strings. Each pair contains the class + * name and instance name of a service instance. All currently running service instances are + * listed. + * + * @param Buffer + * Buffer that receives the command response. May be NULL. + * @param PSize + * Pointer to a ULONG. On input it contains the size of the Buffer. On output it + * contains the number of bytes transferred. May be NULL. + * @param PLauncherError + * Receives the launcher error if any. This is always a Win32 error code. May not be NULL. + * @return + * STATUS_SUCCESS if the command is sent successfully to the launcher, even if the launcher + * returns an error. Other status codes indicate a communication error. Launcher errors are + * reported through PLauncherError. + */ +FSP_API NTSTATUS FspLaunchGetNameList( + PWSTR Buffer, PULONG PSize, + PULONG PLauncherError); + +/** + * @group Service Registry + */ +#pragma warning(push) +#pragma warning(disable:4200) /* zero-sized array in struct/union */ +/** + * Service registry record. + */ +typedef struct _FSP_LAUNCH_REG_RECORD +{ + PWSTR Agent; + PWSTR Executable; + PWSTR CommandLine; + PWSTR WorkDirectory; + PWSTR RunAs; + PWSTR Security; + PWSTR AuthPackage; + PWSTR Stderr; + PVOID Reserved0[4]; + ULONG JobControl; + ULONG Credentials; + ULONG AuthPackageId; + ULONG Recovery; + ULONG Reserved1[4]; + UINT8 Buffer[]; +} FSP_LAUNCH_REG_RECORD; +#pragma warning(pop) +/** + * Add/change/delete a service registry record. + * + * @param ClassName + * The service class name. + * @param Record + * The record to set in the registry. If NULL, the registry record is deleted. + * @return + * STATUS_SUCCESS or error code. + */ +FSP_API NTSTATUS FspLaunchRegSetRecord( + PWSTR ClassName, + const FSP_LAUNCH_REG_RECORD *Record); +/** + * Get a service registry record. + * + * @param ClassName + * The service class name. + * @param Agent + * The name of the agent that is retrieving the service record. This API matches + * the supplied Agent against the Agent in the service record and it only returns + * the record if they match. Pass NULL to match any Agent. + * @param PRecord + * Pointer to a record pointer. Memory for the service record will be allocated + * and a pointer to it will be stored at this address. This memory must be later + * freed using FspLaunchRegFreeRecord. + * @return + * STATUS_SUCCESS or error code. + * @see + * FspLaunchRegFreeRecord + */ +FSP_API NTSTATUS FspLaunchRegGetRecord( + PWSTR ClassName, PWSTR Agent, + FSP_LAUNCH_REG_RECORD **PRecord); +/** + * Free a service registry record. + * + * @param Record + * The service record to free. + * @see + * FspLaunchRegGetRecord + */ +FSP_API VOID FspLaunchRegFreeRecord( + FSP_LAUNCH_REG_RECORD *Record); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/support/3rd_party/winfsp-2.0/inc/winfsp/winfsp.h b/support/3rd_party/winfsp-2.1/inc/winfsp/winfsp.h similarity index 97% rename from support/3rd_party/winfsp-2.0/inc/winfsp/winfsp.h rename to support/3rd_party/winfsp-2.1/inc/winfsp/winfsp.h index 036f55f5..c0cd62ca 100644 --- a/support/3rd_party/winfsp-2.0/inc/winfsp/winfsp.h +++ b/support/3rd_party/winfsp-2.1/inc/winfsp/winfsp.h @@ -1,2240 +1,2240 @@ -/** - * @file winfsp/winfsp.h - * WinFsp User Mode API. - * - * In order to use the WinFsp API the user mode file system must include <winfsp/winfsp.h> - * and link with the winfsp_x64.dll (or winfsp_x86.dll) library. - * - * @copyright 2015-2022 Bill Zissimopoulos - */ -/* - * This file is part of WinFsp. - * - * You can redistribute it and/or modify it under the terms of the GNU - * General Public License version 3 as published by the Free Software - * Foundation. - * - * Licensees holding a valid commercial license may use this software - * in accordance with the commercial license agreement provided in - * conjunction with the software. The terms and conditions of any such - * commercial license agreement shall govern, supersede, and render - * ineffective any application of the GPLv3 license to this software, - * notwithstanding of any reference thereto in the software or - * associated repository. - */ - -#ifndef WINFSP_WINFSP_H_INCLUDED -#define WINFSP_WINFSP_H_INCLUDED - -#define WIN32_NO_STATUS -#include -#undef WIN32_NO_STATUS -#include -#pragma warning(push) -#pragma warning(disable:4005) /* macro redefinition */ -#include -#pragma warning(pop) - -#if defined(WINFSP_DLL_INTERNAL) -#define FSP_API __declspec(dllexport) -#else -#define FSP_API __declspec(dllimport) -#endif - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * The REPARSE_DATA_BUFFER definitions appear to be missing from the user mode headers. - */ -#if !defined(SYMLINK_FLAG_RELATIVE) -#define SYMLINK_FLAG_RELATIVE 1 -#define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER, GenericReparseBuffer) -typedef struct _REPARSE_DATA_BUFFER -{ - ULONG ReparseTag; - USHORT ReparseDataLength; - USHORT Reserved; - union - { - struct - { - USHORT SubstituteNameOffset; - USHORT SubstituteNameLength; - USHORT PrintNameOffset; - USHORT PrintNameLength; - ULONG Flags; - WCHAR PathBuffer[1]; - } SymbolicLinkReparseBuffer; - struct - { - USHORT SubstituteNameOffset; - USHORT SubstituteNameLength; - USHORT PrintNameOffset; - USHORT PrintNameLength; - WCHAR PathBuffer[1]; - } MountPointReparseBuffer; - struct - { - UCHAR DataBuffer[1]; - } GenericReparseBuffer; - } DUMMYUNIONNAME; -} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER; -#endif - -/* - * The FILE_FULL_EA_INFORMATION definitions are missing from the user mode headers. - */ -#if !defined(FILE_NEED_EA) -#define FILE_NEED_EA 0x00000080 -#endif -#if !defined(__MINGW32__) -typedef struct _FILE_FULL_EA_INFORMATION -{ - ULONG NextEntryOffset; - UCHAR Flags; - UCHAR EaNameLength; - USHORT EaValueLength; - CHAR EaName[1]; -} FILE_FULL_EA_INFORMATION, *PFILE_FULL_EA_INFORMATION; -#endif - -/** - * @group File System - * - * A user mode file system is a program that uses the WinFsp API to expose a file system to - * Windows. The user mode file system must implement the operations in FSP_FILE_SYSTEM_INTERFACE, - * create a file system object using FspFileSystemCreate and start its dispatcher using - * FspFileSystemStartDispatcher. At that point it will start receiving file system requests on the - * FSP_FILE_SYSTEM_INTERFACE operations. - */ -typedef struct _FSP_FILE_SYSTEM FSP_FILE_SYSTEM; -typedef NTSTATUS FSP_FILE_SYSTEM_OPERATION_GUARD(FSP_FILE_SYSTEM *, - FSP_FSCTL_TRANSACT_REQ *, FSP_FSCTL_TRANSACT_RSP *); -typedef NTSTATUS FSP_FILE_SYSTEM_OPERATION(FSP_FILE_SYSTEM *, - FSP_FSCTL_TRANSACT_REQ *, FSP_FSCTL_TRANSACT_RSP *); -/** - * User mode file system locking strategy. - * - * Two concurrency models are provided: - * - * 1. A fine-grained concurrency model where file system NAMESPACE accesses - * are guarded using an exclusive-shared (read-write) lock. File I/O is not - * guarded and concurrent reads/writes/etc. are possible. [Note that the FSD - * will still apply an exclusive-shared lock PER INDIVIDUAL FILE, but it will - * not limit I/O operations for different files.] - * - * The fine-grained concurrency model applies the exclusive-shared lock as - * follows: - *
    - *
  • EXCL: SetVolumeLabel, Flush(Volume), - * Create, Cleanup(Delete), SetInformation(Rename)
  • - *
  • SHRD: GetVolumeInfo, Open, SetInformation(Disposition), ReadDirectory
  • - *
  • NONE: all other operations
  • - *
- * - * 2. A coarse-grained concurrency model where all file system accesses are - * guarded by a mutually exclusive lock. - * - * @see FspFileSystemSetOperationGuardStrategy - */ -typedef enum -{ - FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY_FINE = 0, - FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY_COARSE, -} FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY; -enum -{ - FspCleanupDelete = 0x01, - FspCleanupSetAllocationSize = 0x02, - FspCleanupSetArchiveBit = 0x10, - FspCleanupSetLastAccessTime = 0x20, - FspCleanupSetLastWriteTime = 0x40, - FspCleanupSetChangeTime = 0x80, -}; -/** - * @class FSP_FILE_SYSTEM - * File system interface. - * - * The operations in this interface must be implemented by the user mode - * file system. Not all operations need be implemented. For example, - * a user mode file system that does not wish to support reparse points, - * need not implement the reparse point operations. - * - * Most of the operations accept a FileContext parameter. This parameter - * has different meanings depending on the value of the FSP_FSCTL_VOLUME_PARAMS - * flags UmFileContextIsUserContext2 and UmFileContextIsFullContext. - * - * There are three cases to consider: - *
    - *
  • When both of these flags are unset (default), the FileContext parameter - * represents the file node. The file node is a void pointer (or an integer - * that can fit in a pointer) that is used to uniquely identify an open file. - * Opening the same file name should always yield the same file node value - * for as long as the file with that name remains open anywhere in the system. - *
  • - *
  • When the UmFileContextIsUserContext2 is set, the FileContext parameter - * represents the file descriptor. The file descriptor is a void pointer (or - * an integer that can fit in a pointer) that is used to identify an open - * instance of a file. Opening the same file name may yield a different file - * descriptor. - *
  • - *
  • When the UmFileContextIsFullContext is set, the FileContext parameter - * is a pointer to a FSP_FSCTL_TRANSACT_FULL_CONTEXT. This allows a user mode - * file system to access the low-level UserContext and UserContext2 values. - * The UserContext is used to store the file node and the UserContext2 is - * used to store the file descriptor for an open file. - *
  • - *
- */ -typedef struct _FSP_FILE_SYSTEM_INTERFACE -{ - /** - * Get volume information. - * - * @param FileSystem - * The file system on which this request is posted. - * @param VolumeInfo [out] - * Pointer to a structure that will receive the volume information on successful return - * from this call. - * @return - * STATUS_SUCCESS or error code. - */ - NTSTATUS (*GetVolumeInfo)(FSP_FILE_SYSTEM *FileSystem, - FSP_FSCTL_VOLUME_INFO *VolumeInfo); - /** - * Set volume label. - * - * @param FileSystem - * The file system on which this request is posted. - * @param VolumeLabel - * The new label for the volume. - * @param VolumeInfo [out] - * Pointer to a structure that will receive the volume information on successful return - * from this call. - * @return - * STATUS_SUCCESS or error code. - */ - NTSTATUS (*SetVolumeLabel)(FSP_FILE_SYSTEM *FileSystem, - PWSTR VolumeLabel, - FSP_FSCTL_VOLUME_INFO *VolumeInfo); - /** - * Get file or directory attributes and security descriptor given a file name. - * - * @param FileSystem - * The file system on which this request is posted. - * @param FileName - * The name of the file or directory to get the attributes and security descriptor for. - * @param PFileAttributes - * Pointer to a memory location that will receive the file attributes on successful return - * from this call. May be NULL. - * - * If this call returns STATUS_REPARSE, the file system MAY place here the index of the - * first reparse point within FileName. The file system MAY also leave this at its default - * value of 0. - * @param SecurityDescriptor - * Pointer to a buffer that will receive the file security descriptor on successful return - * from this call. May be NULL. - * @param PSecurityDescriptorSize [in,out] - * Pointer to the security descriptor buffer size. On input it contains the size of the - * security descriptor buffer. On output it will contain the actual size of the security - * descriptor copied into the security descriptor buffer. May be NULL. - * @return - * STATUS_SUCCESS, STATUS_REPARSE or error code. - * - * STATUS_REPARSE should be returned by file systems that support reparse points when - * they encounter a FileName that contains reparse points anywhere but the final path - * component. - */ - NTSTATUS (*GetSecurityByName)(FSP_FILE_SYSTEM *FileSystem, - PWSTR FileName, PUINT32 PFileAttributes/* or ReparsePointIndex */, - PSECURITY_DESCRIPTOR SecurityDescriptor, SIZE_T *PSecurityDescriptorSize); - /** - * Create new file or directory. - * - * @param FileSystem - * The file system on which this request is posted. - * @param FileName - * The name of the file or directory to be created. - * @param CreateOptions - * Create options for this request. This parameter has the same meaning as the - * CreateOptions parameter of the NtCreateFile API. User mode file systems should typically - * only be concerned with the flag FILE_DIRECTORY_FILE, which is an instruction to create a - * directory rather than a file. Some file systems may also want to pay attention to the - * FILE_NO_INTERMEDIATE_BUFFERING and FILE_WRITE_THROUGH flags, although these are - * typically handled by the FSD component. - * @param GrantedAccess - * Determines the specific access rights that have been granted for this request. Upon - * receiving this call all access checks have been performed and the user mode file system - * need not perform any additional checks. However this parameter may be useful to a user - * mode file system; for example the WinFsp-FUSE layer uses this parameter to determine - * which flags to use in its POSIX open() call. - * @param FileAttributes - * File attributes to apply to the newly created file or directory. - * @param SecurityDescriptor - * Security descriptor to apply to the newly created file or directory. This security - * descriptor will always be in self-relative format. Its length can be retrieved using the - * Windows GetSecurityDescriptorLength API. Will be NULL for named streams. - * @param AllocationSize - * Allocation size for the newly created file. - * @param PFileContext [out] - * Pointer that will receive the file context on successful return from this call. - * @param FileInfo [out] - * Pointer to a structure that will receive the file information on successful return - * from this call. This information includes file attributes, file times, etc. - * @return - * STATUS_SUCCESS or error code. - */ - NTSTATUS (*Create)(FSP_FILE_SYSTEM *FileSystem, - PWSTR FileName, UINT32 CreateOptions, UINT32 GrantedAccess, - UINT32 FileAttributes, PSECURITY_DESCRIPTOR SecurityDescriptor, UINT64 AllocationSize, - PVOID *PFileContext, FSP_FSCTL_FILE_INFO *FileInfo); - /** - * Open a file or directory. - * - * @param FileSystem - * The file system on which this request is posted. - * @param FileName - * The name of the file or directory to be opened. - * @param CreateOptions - * Create options for this request. This parameter has the same meaning as the - * CreateOptions parameter of the NtCreateFile API. User mode file systems typically - * do not need to do anything special with respect to this parameter. Some file systems may - * also want to pay attention to the FILE_NO_INTERMEDIATE_BUFFERING and FILE_WRITE_THROUGH - * flags, although these are typically handled by the FSD component. - * @param GrantedAccess - * Determines the specific access rights that have been granted for this request. Upon - * receiving this call all access checks have been performed and the user mode file system - * need not perform any additional checks. However this parameter may be useful to a user - * mode file system; for example the WinFsp-FUSE layer uses this parameter to determine - * which flags to use in its POSIX open() call. - * @param PFileContext [out] - * Pointer that will receive the file context on successful return from this call. - * @param FileInfo [out] - * Pointer to a structure that will receive the file information on successful return - * from this call. This information includes file attributes, file times, etc. - * @return - * STATUS_SUCCESS or error code. - */ - NTSTATUS (*Open)(FSP_FILE_SYSTEM *FileSystem, - PWSTR FileName, UINT32 CreateOptions, UINT32 GrantedAccess, - PVOID *PFileContext, FSP_FSCTL_FILE_INFO *FileInfo); - /** - * Overwrite a file. - * - * @param FileSystem - * The file system on which this request is posted. - * @param FileContext - * The file context of the file to overwrite. - * @param FileAttributes - * File attributes to apply to the overwritten file. - * @param ReplaceFileAttributes - * When TRUE the existing file attributes should be replaced with the new ones. - * When FALSE the existing file attributes should be merged (or'ed) with the new ones. - * @param AllocationSize - * Allocation size for the overwritten file. - * @param FileInfo [out] - * Pointer to a structure that will receive the file information on successful return - * from this call. This information includes file attributes, file times, etc. - * @return - * STATUS_SUCCESS or error code. - */ - NTSTATUS (*Overwrite)(FSP_FILE_SYSTEM *FileSystem, - PVOID FileContext, UINT32 FileAttributes, BOOLEAN ReplaceFileAttributes, UINT64 AllocationSize, - FSP_FSCTL_FILE_INFO *FileInfo); - /** - * Cleanup a file. - * - * When CreateFile is used to open or create a file the kernel creates a kernel mode file - * object (type FILE_OBJECT) and a handle for it, which it returns to user-mode. The handle may - * be duplicated (using DuplicateHandle), but all duplicate handles always refer to the same - * file object. When all handles for a particular file object get closed (using CloseHandle) - * the system sends a Cleanup request to the file system. - * - * There will be a Cleanup operation for every Create or Open operation posted to the user mode - * file system. However the Cleanup operation is not the final close operation on a file. - * The file system must be ready to receive additional operations until close time. This is true - * even when the file is being deleted! - * - * The Flags parameter contains information about the cleanup operation: - *
    - *
  • FspCleanupDelete - - * An important function of the Cleanup operation is to complete a delete operation. Deleting - * a file or directory in Windows is a three-stage process where the file is first opened, then - * tested to see if the delete can proceed and if the answer is positive the file is then - * deleted during Cleanup. - * - * If the file system supports POSIX unlink (FSP_FSCTL_VOLUME_PARAMS :: - * SupportsPosixUnlinkRename), then a Cleanup / FspCleanupDelete operation may arrive while - * there are other open file handles for this particular file node. If the file system does not - * support POSIX unlink, then a Cleanup / FspCleanupDelete operation will always be the last - * outstanding cleanup for this particular file node. - *
  • - *
  • FspCleanupSetAllocationSize - - * The NTFS and FAT file systems reset a file's allocation size when they receive the last - * outstanding cleanup for a particular file node. User mode file systems that implement - * allocation size and wish to duplicate the NTFS and FAT behavior can use this flag. - *
  • - *
  • - * FspCleanupSetArchiveBit - - * File systems that support the archive bit should set the file node's archive bit when this - * flag is set. - *
  • - *
  • FspCleanupSetLastAccessTime, FspCleanupSetLastWriteTime, FspCleanupSetChangeTime - File - * systems should set the corresponding file time when each one of these flags is set. Note that - * updating the last access time is expensive and a file system may choose to not implement it. - *
- * - * There is no way to report failure of this operation. This is a Windows limitation. - * - * As an optimization a file system may specify the FSP_FSCTL_VOLUME_PARAMS :: - * PostCleanupWhenModifiedOnly flag. In this case the FSD will only post Cleanup requests when - * the file was modified/deleted. - * - * @param FileSystem - * The file system on which this request is posted. - * @param FileContext - * The file context of the file or directory to cleanup. - * @param FileName - * The name of the file or directory to cleanup. Sent only when a Delete is requested. - * @param Flags - * These flags determine whether the file was modified and whether to delete the file. - * @see - * Close - * CanDelete - * SetDelete - */ - VOID (*Cleanup)(FSP_FILE_SYSTEM *FileSystem, - PVOID FileContext, PWSTR FileName, ULONG Flags); - /** - * Close a file. - * - * @param FileSystem - * The file system on which this request is posted. - * @param FileContext - * The file context of the file or directory to be closed. - */ - VOID (*Close)(FSP_FILE_SYSTEM *FileSystem, - PVOID FileContext); - /** - * Read a file. - * - * @param FileSystem - * The file system on which this request is posted. - * @param FileContext - * The file context of the file to be read. - * @param Buffer - * Pointer to a buffer that will receive the results of the read operation. - * @param Offset - * Offset within the file to read from. - * @param Length - * Length of data to read. - * @param PBytesTransferred [out] - * Pointer to a memory location that will receive the actual number of bytes read. - * @return - * STATUS_SUCCESS or error code. STATUS_PENDING is supported allowing for asynchronous - * operation. - */ - NTSTATUS (*Read)(FSP_FILE_SYSTEM *FileSystem, - PVOID FileContext, PVOID Buffer, UINT64 Offset, ULONG Length, - PULONG PBytesTransferred); - /** - * Write a file. - * - * @param FileSystem - * The file system on which this request is posted. - * @param FileContext - * The file context of the file to be written. - * @param Buffer - * Pointer to a buffer that contains the data to write. - * @param Offset - * Offset within the file to write to. - * @param Length - * Length of data to write. - * @param WriteToEndOfFile - * When TRUE the file system must write to the current end of file. In this case the Offset - * parameter will contain the value -1. - * @param ConstrainedIo - * When TRUE the file system must not extend the file (i.e. change the file size). - * @param PBytesTransferred [out] - * Pointer to a memory location that will receive the actual number of bytes written. - * @param FileInfo [out] - * Pointer to a structure that will receive the file information on successful return - * from this call. This information includes file attributes, file times, etc. - * @return - * STATUS_SUCCESS or error code. STATUS_PENDING is supported allowing for asynchronous - * operation. - */ - NTSTATUS (*Write)(FSP_FILE_SYSTEM *FileSystem, - PVOID FileContext, PVOID Buffer, UINT64 Offset, ULONG Length, - BOOLEAN WriteToEndOfFile, BOOLEAN ConstrainedIo, - PULONG PBytesTransferred, FSP_FSCTL_FILE_INFO *FileInfo); - /** - * Flush a file or volume. - * - * Note that the FSD will also flush all file/volume caches prior to invoking this operation. - * - * @param FileSystem - * The file system on which this request is posted. - * @param FileContext - * The file context of the file to be flushed. When NULL the whole volume is being flushed. - * @param FileInfo [out] - * Pointer to a structure that will receive the file information on successful return - * from this call. This information includes file attributes, file times, etc. Used when - * flushing file (not volume). - * @return - * STATUS_SUCCESS or error code. - */ - NTSTATUS (*Flush)(FSP_FILE_SYSTEM *FileSystem, - PVOID FileContext, - FSP_FSCTL_FILE_INFO *FileInfo); - /** - * Get file or directory information. - * - * @param FileSystem - * The file system on which this request is posted. - * @param FileContext - * The file context of the file or directory to get information for. - * @param FileInfo [out] - * Pointer to a structure that will receive the file information on successful return - * from this call. This information includes file attributes, file times, etc. - * @return - * STATUS_SUCCESS or error code. - */ - NTSTATUS (*GetFileInfo)(FSP_FILE_SYSTEM *FileSystem, - PVOID FileContext, - FSP_FSCTL_FILE_INFO *FileInfo); - /** - * Set file or directory basic information. - * - * @param FileSystem - * The file system on which this request is posted. - * @param FileContext - * The file context of the file or directory to set information for. - * @param FileAttributes - * File attributes to apply to the file or directory. If the value INVALID_FILE_ATTRIBUTES - * is sent, the file attributes should not be changed. - * @param CreationTime - * Creation time to apply to the file or directory. If the value 0 is sent, the creation - * time should not be changed. - * @param LastAccessTime - * Last access time to apply to the file or directory. If the value 0 is sent, the last - * access time should not be changed. - * @param LastWriteTime - * Last write time to apply to the file or directory. If the value 0 is sent, the last - * write time should not be changed. - * @param ChangeTime - * Change time to apply to the file or directory. If the value 0 is sent, the change time - * should not be changed. - * @param FileInfo [out] - * Pointer to a structure that will receive the file information on successful return - * from this call. This information includes file attributes, file times, etc. - * @return - * STATUS_SUCCESS or error code. - */ - NTSTATUS (*SetBasicInfo)(FSP_FILE_SYSTEM *FileSystem, - PVOID FileContext, UINT32 FileAttributes, - UINT64 CreationTime, UINT64 LastAccessTime, UINT64 LastWriteTime, UINT64 ChangeTime, - FSP_FSCTL_FILE_INFO *FileInfo); - /** - * Set file/allocation size. - * - * This function is used to change a file's sizes. Windows file systems maintain two kinds - * of sizes: the file size is where the End Of File (EOF) is, and the allocation size is the - * actual size that a file takes up on the "disk". - * - * The rules regarding file/allocation size are: - *
    - *
  • Allocation size must always be aligned to the allocation unit boundary. The allocation - * unit is the product (UINT64)SectorSize * (UINT64)SectorsPerAllocationUnit from - * the FSP_FSCTL_VOLUME_PARAMS structure. The FSD will always send properly aligned allocation - * sizes when setting the allocation size.
  • - *
  • Allocation size is always greater or equal to the file size.
  • - *
  • A file size of more than the current allocation size will also extend the allocation - * size to the next allocation unit boundary.
  • - *
  • An allocation size of less than the current file size should also truncate the current - * file size.
  • - *
- * - * @param FileSystem - * The file system on which this request is posted. - * @param FileContext - * The file context of the file to set the file/allocation size for. - * @param NewSize - * New file/allocation size to apply to the file. - * @param SetAllocationSize - * If TRUE, then the allocation size is being set. if FALSE, then the file size is being set. - * @param FileInfo [out] - * Pointer to a structure that will receive the file information on successful return - * from this call. This information includes file attributes, file times, etc. - * @return - * STATUS_SUCCESS or error code. - */ - NTSTATUS (*SetFileSize)(FSP_FILE_SYSTEM *FileSystem, - PVOID FileContext, UINT64 NewSize, BOOLEAN SetAllocationSize, - FSP_FSCTL_FILE_INFO *FileInfo); - /** - * Determine whether a file or directory can be deleted. - * - * This function tests whether a file or directory can be safely deleted. This function does - * not need to perform access checks, but may performs tasks such as check for empty - * directories, etc. - * - * This function should NEVER delete the file or directory in question. Deletion should - * happen during Cleanup with the FspCleanupDelete flag set. - * - * This function gets called when Win32 API's such as DeleteFile or RemoveDirectory are used. - * It does not get called when a file or directory is opened with FILE_DELETE_ON_CLOSE. - * - * NOTE: If both CanDelete and SetDelete are defined, SetDelete takes precedence. However - * most file systems need only implement the CanDelete operation. - * - * @param FileSystem - * The file system on which this request is posted. - * @param FileContext - * The file context of the file or directory to test for deletion. - * @param FileName - * The name of the file or directory to test for deletion. - * @return - * STATUS_SUCCESS or error code. - * @see - * Cleanup - * SetDelete - */ - NTSTATUS (*CanDelete)(FSP_FILE_SYSTEM *FileSystem, - PVOID FileContext, PWSTR FileName); - /** - * Renames a file or directory. - * - * The kernel mode FSD provides certain guarantees prior to posting a rename operation: - *
    - *
  • A file cannot be renamed if a file with the same name exists and has open handles.
  • - *
  • A directory cannot be renamed if it or any of its subdirectories contains a file that - * has open handles.
  • - *
- * - * @param FileSystem - * The file system on which this request is posted. - * @param FileContext - * The file context of the file or directory to be renamed. - * @param FileName - * The current name of the file or directory to rename. - * @param NewFileName - * The new name for the file or directory. - * @param ReplaceIfExists - * Whether to replace a file that already exists at NewFileName. - * @return - * STATUS_SUCCESS or error code. - */ - NTSTATUS (*Rename)(FSP_FILE_SYSTEM *FileSystem, - PVOID FileContext, - PWSTR FileName, PWSTR NewFileName, BOOLEAN ReplaceIfExists); - /** - * Get file or directory security descriptor. - * - * @param FileSystem - * The file system on which this request is posted. - * @param FileContext - * The file context of the file or directory to get the security descriptor for. - * @param SecurityDescriptor - * Pointer to a buffer that will receive the file security descriptor on successful return - * from this call. May be NULL. - * @param PSecurityDescriptorSize [in,out] - * Pointer to the security descriptor buffer size. On input it contains the size of the - * security descriptor buffer. On output it will contain the actual size of the security - * descriptor copied into the security descriptor buffer. Cannot be NULL. - * @return - * STATUS_SUCCESS or error code. - */ - NTSTATUS (*GetSecurity)(FSP_FILE_SYSTEM *FileSystem, - PVOID FileContext, - PSECURITY_DESCRIPTOR SecurityDescriptor, SIZE_T *PSecurityDescriptorSize); - /** - * Set file or directory security descriptor. - * - * @param FileSystem - * The file system on which this request is posted. - * @param FileContext - * The file context of the file or directory to set the security descriptor for. - * @param SecurityInformation - * Describes what parts of the file or directory security descriptor should - * be modified. - * @param ModificationDescriptor - * Describes the modifications to apply to the file or directory security descriptor. - * @return - * STATUS_SUCCESS or error code. - * @see - * FspSetSecurityDescriptor - * FspDeleteSecurityDescriptor - */ - NTSTATUS (*SetSecurity)(FSP_FILE_SYSTEM *FileSystem, - PVOID FileContext, - SECURITY_INFORMATION SecurityInformation, PSECURITY_DESCRIPTOR ModificationDescriptor); - /** - * Read a directory. - * - * @param FileSystem - * The file system on which this request is posted. - * @param FileContext - * The file context of the directory to be read. - * @param Pattern - * The pattern to match against files in this directory. Can be NULL. The file system - * can choose to ignore this parameter as the FSD will always perform its own pattern - * matching on the returned results. - * @param Marker - * A file name that marks where in the directory to start reading. Files with names - * that are greater than (not equal to) this marker (in the directory order determined - * by the file system) should be returned. Can be NULL. - * @param Buffer - * Pointer to a buffer that will receive the results of the read operation. - * @param Length - * Length of data to read. - * @param PBytesTransferred [out] - * Pointer to a memory location that will receive the actual number of bytes read. - * @return - * STATUS_SUCCESS or error code. STATUS_PENDING is supported allowing for asynchronous - * operation. - * @see - * FspFileSystemAddDirInfo - */ - NTSTATUS (*ReadDirectory)(FSP_FILE_SYSTEM *FileSystem, - PVOID FileContext, PWSTR Pattern, PWSTR Marker, - PVOID Buffer, ULONG Length, PULONG PBytesTransferred); - /** - * Resolve reparse points. - * - * Reparse points are a general mechanism for attaching special behavior to files. - * A file or directory can contain a reparse point. A reparse point is data that has - * special meaning to the file system, Windows or user applications. For example, NTFS - * and Windows use reparse points to implement symbolic links. As another example, - * a particular file system may use reparse points to emulate UNIX FIFO's. - * - * This function is expected to resolve as many reparse points as possible. If a reparse - * point is encountered that is not understood by the file system further reparse point - * resolution should stop; the reparse point data should be returned to the FSD with status - * STATUS_REPARSE/reparse-tag. If a reparse point (symbolic link) is encountered that is - * understood by the file system but points outside it, the reparse point should be - * resolved, but further reparse point resolution should stop; the resolved file name - * should be returned to the FSD with status STATUS_REPARSE/IO_REPARSE. - * - * @param FileSystem - * The file system on which this request is posted. - * @param FileName - * The name of the file or directory to have its reparse points resolved. - * @param ReparsePointIndex - * The index of the first reparse point within FileName. - * @param ResolveLastPathComponent - * If FALSE, the last path component of FileName should not be resolved, even - * if it is a reparse point that can be resolved. If TRUE, all path components - * should be resolved if possible. - * @param PIoStatus - * Pointer to storage that will receive the status to return to the FSD. When - * this function succeeds it must set PIoStatus->Status to STATUS_REPARSE and - * PIoStatus->Information to either IO_REPARSE or the reparse tag. - * @param Buffer - * Pointer to a buffer that will receive the resolved file name (IO_REPARSE) or - * reparse data (reparse tag). If the function returns a file name, it should - * not be NULL terminated. - * @param PSize [in,out] - * Pointer to the buffer size. On input it contains the size of the buffer. - * On output it will contain the actual size of data copied. - * @return - * STATUS_REPARSE or error code. - */ - NTSTATUS (*ResolveReparsePoints)(FSP_FILE_SYSTEM *FileSystem, - PWSTR FileName, UINT32 ReparsePointIndex, BOOLEAN ResolveLastPathComponent, - PIO_STATUS_BLOCK PIoStatus, PVOID Buffer, PSIZE_T PSize); - /** - * Get reparse point. - * - * @param FileSystem - * The file system on which this request is posted. - * @param FileContext - * The file context of the reparse point. - * @param FileName - * The file name of the reparse point. - * @param Buffer - * Pointer to a buffer that will receive the results of this operation. If - * the function returns a symbolic link path, it should not be NULL terminated. - * @param PSize [in,out] - * Pointer to the buffer size. On input it contains the size of the buffer. - * On output it will contain the actual size of data copied. - * @return - * STATUS_SUCCESS or error code. - * @see - * SetReparsePoint - */ - NTSTATUS (*GetReparsePoint)(FSP_FILE_SYSTEM *FileSystem, - PVOID FileContext, - PWSTR FileName, PVOID Buffer, PSIZE_T PSize); - /** - * Set reparse point. - * - * @param FileSystem - * The file system on which this request is posted. - * @param FileContext - * The file context of the reparse point. - * @param FileName - * The file name of the reparse point. - * @param Buffer - * Pointer to a buffer that contains the data for this operation. If this buffer - * contains a symbolic link path, it should not be assumed to be NULL terminated. - * @param Size - * Size of data to write. - * @return - * STATUS_SUCCESS or error code. - * @see - * GetReparsePoint - */ - NTSTATUS (*SetReparsePoint)(FSP_FILE_SYSTEM *FileSystem, - PVOID FileContext, - PWSTR FileName, PVOID Buffer, SIZE_T Size); - /** - * Delete reparse point. - * - * @param FileSystem - * The file system on which this request is posted. - * @param FileContext - * The file context of the reparse point. - * @param FileName - * The file name of the reparse point. - * @param Buffer - * Pointer to a buffer that contains the data for this operation. - * @param Size - * Size of data to write. - * @return - * STATUS_SUCCESS or error code. - */ - NTSTATUS (*DeleteReparsePoint)(FSP_FILE_SYSTEM *FileSystem, - PVOID FileContext, - PWSTR FileName, PVOID Buffer, SIZE_T Size); - /** - * Get named streams information. - * - * @param FileSystem - * The file system on which this request is posted. - * @param FileContext - * The file context of the file or directory to get stream information for. - * @param Buffer - * Pointer to a buffer that will receive the stream information. - * @param Length - * Length of buffer. - * @param PBytesTransferred [out] - * Pointer to a memory location that will receive the actual number of bytes stored. - * @return - * STATUS_SUCCESS or error code. - * @see - * FspFileSystemAddStreamInfo - */ - NTSTATUS (*GetStreamInfo)(FSP_FILE_SYSTEM *FileSystem, - PVOID FileContext, PVOID Buffer, ULONG Length, - PULONG PBytesTransferred); - /** - * Get directory information for a single file or directory within a parent directory. - * - * @param FileSystem - * The file system on which this request is posted. - * @param FileContext - * The file context of the parent directory. - * @param FileName - * The name of the file or directory to get information for. This name is relative - * to the parent directory and is a single path component. - * @param DirInfo [out] - * Pointer to a structure that will receive the directory information on successful - * return from this call. This information includes the file name, but also file - * attributes, file times, etc. - * @return - * STATUS_SUCCESS or error code. - */ - NTSTATUS (*GetDirInfoByName)(FSP_FILE_SYSTEM *FileSystem, - PVOID FileContext, PWSTR FileName, - FSP_FSCTL_DIR_INFO *DirInfo); - /** - * Process control code. - * - * This function is called when a program uses the DeviceIoControl API. - * - * @param FileSystem - * The file system on which this request is posted. - * @param FileContext - * The file context of the file or directory to be controled. - * @param ControlCode - * The control code for the operation. This code must have a DeviceType with bit - * 0x8000 set and must have a TransferType of METHOD_BUFFERED. - * @param InputBuffer - * Pointer to a buffer that contains the input data. - * @param InputBufferLength - * Input data length. - * @param OutputBuffer - * Pointer to a buffer that will receive the output data. - * @param OutputBufferLength - * Output data length. - * @param PBytesTransferred [out] - * Pointer to a memory location that will receive the actual number of bytes transferred. - * @return - * STATUS_SUCCESS or error code. - */ - NTSTATUS (*Control)(FSP_FILE_SYSTEM *FileSystem, - PVOID FileContext, UINT32 ControlCode, - PVOID InputBuffer, ULONG InputBufferLength, - PVOID OutputBuffer, ULONG OutputBufferLength, PULONG PBytesTransferred); - /** - * Set the file delete flag. - * - * This function sets a flag to indicates whether the FSD file should delete a file - * when it is closed. This function does not need to perform access checks, but may - * performs tasks such as check for empty directories, etc. - * - * This function should NEVER delete the file or directory in question. Deletion should - * happen during Cleanup with the FspCleanupDelete flag set. - * - * This function gets called when Win32 API's such as DeleteFile or RemoveDirectory are used. - * It does not get called when a file or directory is opened with FILE_DELETE_ON_CLOSE. - * - * NOTE: If both CanDelete and SetDelete are defined, SetDelete takes precedence. However - * most file systems need only implement the CanDelete operation. - * - * @param FileSystem - * The file system on which this request is posted. - * @param FileContext - * The file context of the file or directory to set the delete flag for. - * @param FileName - * The name of the file or directory to set the delete flag for. - * @param DeleteFile - * If set to TRUE the FSD indicates that the file will be deleted on Cleanup; otherwise - * it will not be deleted. It is legal to receive multiple SetDelete calls for the same - * file with different DeleteFile parameters. - * @return - * STATUS_SUCCESS or error code. - * @see - * Cleanup - * CanDelete - */ - NTSTATUS (*SetDelete)(FSP_FILE_SYSTEM *FileSystem, - PVOID FileContext, PWSTR FileName, BOOLEAN DeleteFile); - /** - * Create new file or directory. - * - * This function works like Create, except that it also accepts an extra buffer that - * may contain extended attributes or a reparse point. - * - * NOTE: If both Create and CreateEx are defined, CreateEx takes precedence. - * - * @param FileSystem - * The file system on which this request is posted. - * @param FileName - * The name of the file or directory to be created. - * @param CreateOptions - * Create options for this request. This parameter has the same meaning as the - * CreateOptions parameter of the NtCreateFile API. User mode file systems should typically - * only be concerned with the flag FILE_DIRECTORY_FILE, which is an instruction to create a - * directory rather than a file. Some file systems may also want to pay attention to the - * FILE_NO_INTERMEDIATE_BUFFERING and FILE_WRITE_THROUGH flags, although these are - * typically handled by the FSD component. - * @param GrantedAccess - * Determines the specific access rights that have been granted for this request. Upon - * receiving this call all access checks have been performed and the user mode file system - * need not perform any additional checks. However this parameter may be useful to a user - * mode file system; for example the WinFsp-FUSE layer uses this parameter to determine - * which flags to use in its POSIX open() call. - * @param FileAttributes - * File attributes to apply to the newly created file or directory. - * @param SecurityDescriptor - * Security descriptor to apply to the newly created file or directory. This security - * descriptor will always be in self-relative format. Its length can be retrieved using the - * Windows GetSecurityDescriptorLength API. Will be NULL for named streams. - * @param AllocationSize - * Allocation size for the newly created file. - * @param ExtraBuffer - * Extended attributes or reparse point buffer. - * @param ExtraLength - * Extended attributes or reparse point buffer length. - * @param ExtraBufferIsReparsePoint - * FALSE: extra buffer is extended attributes; TRUE: extra buffer is reparse point. - * @param PFileContext [out] - * Pointer that will receive the file context on successful return from this call. - * @param FileInfo [out] - * Pointer to a structure that will receive the file information on successful return - * from this call. This information includes file attributes, file times, etc. - * @return - * STATUS_SUCCESS or error code. - */ - NTSTATUS (*CreateEx)(FSP_FILE_SYSTEM *FileSystem, - PWSTR FileName, UINT32 CreateOptions, UINT32 GrantedAccess, - UINT32 FileAttributes, PSECURITY_DESCRIPTOR SecurityDescriptor, UINT64 AllocationSize, - PVOID ExtraBuffer, ULONG ExtraLength, BOOLEAN ExtraBufferIsReparsePoint, - PVOID *PFileContext, FSP_FSCTL_FILE_INFO *FileInfo); - /** - * Overwrite a file. - * - * This function works like Overwrite, except that it also accepts EA (extended attributes). - * - * NOTE: If both Overwrite and OverwriteEx are defined, OverwriteEx takes precedence. - * - * @param FileSystem - * The file system on which this request is posted. - * @param FileContext - * The file context of the file to overwrite. - * @param FileAttributes - * File attributes to apply to the overwritten file. - * @param ReplaceFileAttributes - * When TRUE the existing file attributes should be replaced with the new ones. - * When FALSE the existing file attributes should be merged (or'ed) with the new ones. - * @param AllocationSize - * Allocation size for the overwritten file. - * @param Ea - * Extended attributes buffer. - * @param EaLength - * Extended attributes buffer length. - * @param FileInfo [out] - * Pointer to a structure that will receive the file information on successful return - * from this call. This information includes file attributes, file times, etc. - * @return - * STATUS_SUCCESS or error code. - */ - NTSTATUS (*OverwriteEx)(FSP_FILE_SYSTEM *FileSystem, - PVOID FileContext, UINT32 FileAttributes, BOOLEAN ReplaceFileAttributes, UINT64 AllocationSize, - PFILE_FULL_EA_INFORMATION Ea, ULONG EaLength, - FSP_FSCTL_FILE_INFO *FileInfo); - /** - * Get extended attributes. - * - * @param FileSystem - * The file system on which this request is posted. - * @param FileContext - * The file context of the file to get extended attributes for. - * @param Ea - * Extended attributes buffer. - * @param EaLength - * Extended attributes buffer length. - * @param PBytesTransferred [out] - * Pointer to a memory location that will receive the actual number of bytes transferred. - * @return - * STATUS_SUCCESS or error code. - * @see - * SetEa - * FspFileSystemAddEa - */ - NTSTATUS (*GetEa)(FSP_FILE_SYSTEM *FileSystem, - PVOID FileContext, - PFILE_FULL_EA_INFORMATION Ea, ULONG EaLength, PULONG PBytesTransferred); - /** - * Set extended attributes. - * - * @param FileSystem - * The file system on which this request is posted. - * @param FileContext - * The file context of the file to set extended attributes for. - * @param Ea - * Extended attributes buffer. - * @param EaLength - * Extended attributes buffer length. - * @param FileInfo [out] - * Pointer to a structure that will receive the file information on successful return - * from this call. This information includes file attributes, file times, etc. - * @return - * STATUS_SUCCESS or error code. - * @see - * GetEa - */ - NTSTATUS (*SetEa)(FSP_FILE_SYSTEM *FileSystem, - PVOID FileContext, - PFILE_FULL_EA_INFORMATION Ea, ULONG EaLength, - FSP_FSCTL_FILE_INFO *FileInfo); - - NTSTATUS (*Obsolete0)(VOID); - - /** - * Inform the file system that its dispatcher has been stopped. - * - * Prior to WinFsp v2.0 the FSD would never unmount a file system volume unless - * the user mode file system requested the unmount. Since WinFsp v2.0 it is possible - * for the FSD to unmount a file system volume without an explicit user mode file system - * request. For example, this happens when the FSD is being uninstalled. - * - * A user mode file system can use this operation to determine when its dispatcher - * has been stopped. The Normally parameter can be used to determine why the dispatcher - * was stopped: it is TRUE when the file system is being stopped via - * FspFileSystemStopDispatcher and FALSE otherwise. - * - * When the file system receives a request with Normally == TRUE it need not take any - * extra steps. This case is the same as for pre-v2.0 versions: since the file system - * stopped the dispatcher via FspFileSystemStopDispatcher, it will likely exit its - * process soon. - * - * When the file system receives a request with Normally == FALSE it may need to take - * extra steps to exit its process as this is not done by default. - * - * A file system that uses the FspService infrastructure may use the - * FspFileSystemStopServiceIfNecessary API to correctly handle all cases. - * - * This operation is the last one that a file system will receive. - * - * @param FileSystem - * The file system on which this request is posted. - * @param Normally - * TRUE if the file system is being stopped via FspFileSystemStopDispatcher. - * FALSE if the file system is being stopped because of another reason such - * as driver unload/uninstall. - * @see - * FspFileSystemStopServiceIfNecessary - */ - VOID (*DispatcherStopped)(FSP_FILE_SYSTEM *FileSystem, - BOOLEAN Normally); - - /* - * This ensures that this interface will always contain 64 function pointers. - * Please update when changing the interface as it is important for future compatibility. - */ - NTSTATUS (*Reserved[31])(); -} FSP_FILE_SYSTEM_INTERFACE; -FSP_FSCTL_STATIC_ASSERT(sizeof(FSP_FILE_SYSTEM_INTERFACE) == 64 * sizeof(NTSTATUS (*)()), - "FSP_FILE_SYSTEM_INTERFACE must have 64 entries."); -typedef struct _FSP_FILE_SYSTEM -{ - UINT16 Version; - PVOID UserContext; - WCHAR VolumeName[FSP_FSCTL_VOLUME_NAME_SIZEMAX / sizeof(WCHAR)]; - HANDLE VolumeHandle; - FSP_FILE_SYSTEM_OPERATION_GUARD *EnterOperation, *LeaveOperation; - FSP_FILE_SYSTEM_OPERATION *Operations[FspFsctlTransactKindCount]; - const FSP_FILE_SYSTEM_INTERFACE *Interface; - HANDLE DispatcherThread; - ULONG DispatcherThreadCount; - NTSTATUS DispatcherResult; - PWSTR MountPoint; - HANDLE MountHandle; - UINT32 DebugLog; - FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY OpGuardStrategy; - SRWLOCK OpGuardLock; - BOOLEAN UmFileContextIsUserContext2, UmFileContextIsFullContext; - UINT16 UmNoReparsePointsDirCheck:1; - UINT16 UmReservedFlags:14; - UINT16 DispatcherStopping:1; -} FSP_FILE_SYSTEM; -FSP_FSCTL_STATIC_ASSERT( - (4 == sizeof(PVOID) && 660 == sizeof(FSP_FILE_SYSTEM)) || - (8 == sizeof(PVOID) && 792 == sizeof(FSP_FILE_SYSTEM)), - "sizeof(FSP_FILE_SYSTEM) must be exactly 660 in 32-bit and 792 in 64-bit."); -typedef struct _FSP_FILE_SYSTEM_OPERATION_CONTEXT -{ - FSP_FSCTL_TRANSACT_REQ *Request; - FSP_FSCTL_TRANSACT_RSP *Response; -} FSP_FILE_SYSTEM_OPERATION_CONTEXT; -/** - * Check whether creating a file system object is possible. - * - * @param DevicePath - * The name of the control device for this file system. This must be either - * FSP_FSCTL_DISK_DEVICE_NAME or FSP_FSCTL_NET_DEVICE_NAME. - * @param MountPoint - * The mount point for the new file system. A value of NULL means that the file system should - * use the next available drive letter counting downwards from Z: as its mount point. - * @return - * STATUS_SUCCESS or error code. - */ -FSP_API NTSTATUS FspFileSystemPreflight(PWSTR DevicePath, - PWSTR MountPoint); -/** - * Create a file system object. - * - * @param DevicePath - * The name of the control device for this file system. This must be either - * FSP_FSCTL_DISK_DEVICE_NAME or FSP_FSCTL_NET_DEVICE_NAME. - * @param VolumeParams - * Volume parameters for the newly created file system. - * @param Interface - * A pointer to the operations that implement this user mode file system. - * @param PFileSystem [out] - * Pointer that will receive the file system object created on successful return from this - * call. - * @return - * STATUS_SUCCESS or error code. - */ -FSP_API NTSTATUS FspFileSystemCreate(PWSTR DevicePath, - const FSP_FSCTL_VOLUME_PARAMS *VolumeParams, - const FSP_FILE_SYSTEM_INTERFACE *Interface, - FSP_FILE_SYSTEM **PFileSystem); -/** - * Delete a file system object. - * - * @param FileSystem - * The file system object. - */ -FSP_API VOID FspFileSystemDelete(FSP_FILE_SYSTEM *FileSystem); -/** - * Set the mount point for a file system. - * - * This function supports drive letters (X:) or directories as mount points: - *
    - *
  • Drive letters: Refer to the documentation of the DefineDosDevice Windows API - * to better understand how they are created.
  • - *
  • Directories: They can be used as mount points for disk based file systems. They cannot - * be used for network file systems. This is a limitation that Windows imposes on junctions.
  • - *
- * - * @param FileSystem - * The file system object. - * @param MountPoint - * The mount point for the new file system. A value of NULL means that the file system should - * use the next available drive letter counting downwards from Z: as its mount point. - * @return - * STATUS_SUCCESS or error code. - */ -FSP_API NTSTATUS FspFileSystemSetMountPoint(FSP_FILE_SYSTEM *FileSystem, PWSTR MountPoint); -FSP_API NTSTATUS FspFileSystemSetMountPointEx(FSP_FILE_SYSTEM *FileSystem, PWSTR MountPoint, - PSECURITY_DESCRIPTOR SecurityDescriptor); -/** - * Remove the mount point for a file system. - * - * @param FileSystem - * The file system object. - */ -FSP_API VOID FspFileSystemRemoveMountPoint(FSP_FILE_SYSTEM *FileSystem); -/** - * Start the file system dispatcher. - * - * The file system dispatcher is used to dispatch operations posted by the FSD to the user mode - * file system. Once this call starts executing the user mode file system will start receiving - * file system requests from the kernel. - * - * @param FileSystem - * The file system object. - * @param ThreadCount - * The number of threads for the file system dispatcher. A value of 0 will create a default - * number of threads and should be chosen in most cases. - * @return - * STATUS_SUCCESS or error code. - */ -FSP_API NTSTATUS FspFileSystemStartDispatcher(FSP_FILE_SYSTEM *FileSystem, ULONG ThreadCount); -/** - * Stop the file system dispatcher. - * - * @param FileSystem - * The file system object. - */ -FSP_API VOID FspFileSystemStopDispatcher(FSP_FILE_SYSTEM *FileSystem); -/** - * Send a response to the FSD. - * - * This call is not required when the user mode file system performs synchronous processing of - * requests. It is possible however for the following FSP_FILE_SYSTEM_INTERFACE operations to be - * processed asynchronously: - *
    - *
  • Read
  • - *
  • Write
  • - *
  • ReadDirectory
  • - *
- * - * These operations are allowed to return STATUS_PENDING to postpone sending a response to the FSD. - * At a later time the file system can use FspFileSystemSendResponse to send the response. - * - * @param FileSystem - * The file system object. - * @param Response - * The response buffer. - */ -FSP_API VOID FspFileSystemSendResponse(FSP_FILE_SYSTEM *FileSystem, - FSP_FSCTL_TRANSACT_RSP *Response); -/** - * Begin notifying Windows that the file system has file changes. - * - * A file system that wishes to notify Windows about file changes must - * first issue an FspFileSystemBegin call, followed by 0 or more - * FspFileSystemNotify calls, followed by an FspFileSystemNotifyEnd call. - * - * This operation blocks concurrent file rename operations. File rename - * operations may interfere with file notification, because a file being - * notified may also be concurrently renamed. After all file change - * notifications have been issued, you must make sure to call - * FspFileSystemNotifyEnd to allow file rename operations to proceed. - * - * @param FileSystem - * The file system object. - * @return - * STATUS_SUCCESS or error code. The error code STATUS_CANT_WAIT means that - * a file rename operation is currently in progress and the operation must be - * retried at a later time. - */ -FSP_API NTSTATUS FspFileSystemNotifyBegin(FSP_FILE_SYSTEM *FileSystem, ULONG Timeout); -/** - * End notifying Windows that the file system has file changes. - * - * A file system that wishes to notify Windows about file changes must - * first issue an FspFileSystemBegin call, followed by 0 or more - * FspFileSystemNotify calls, followed by an FspFileSystemNotifyEnd call. - * - * This operation allows any blocked file rename operations to proceed. - * - * @param FileSystem - * The file system object. - * @return - * STATUS_SUCCESS or error code. - */ -FSP_API NTSTATUS FspFileSystemNotifyEnd(FSP_FILE_SYSTEM *FileSystem); -/** - * Notify Windows that the file system has file changes. - * - * A file system that wishes to notify Windows about file changes must - * first issue an FspFileSystemBegin call, followed by 0 or more - * FspFileSystemNotify calls, followed by an FspFileSystemNotifyEnd call. - * - * Note that FspFileSystemNotify requires file names to be normalized. A - * normalized file name is one that contains the correct case of all characters - * in the file name. - * - * For case-sensitive file systems all file names are normalized by definition. - * For case-insensitive file systems that implement file name normalization, - * a normalized file name is the one that the file system specifies in the - * response to Create or Open (see also FspFileSystemGetOpenFileInfo). For - * case-insensitive file systems that do not implement file name normalization - * a normalized file name is the upper case version of the file name used - * to open the file. - * - * @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. - * - * This function may be used only when servicing one of the FSP_FILE_SYSTEM_INTERFACE operations. - * The current operation context is stored in thread local storage. It allows access to the - * Request and Response associated with this operation. - * - * @return - * The current operation context. - */ -FSP_API FSP_FILE_SYSTEM_OPERATION_CONTEXT *FspFileSystemGetOperationContext(VOID); -static inline -PWSTR FspFileSystemMountPoint(FSP_FILE_SYSTEM *FileSystem) -{ - return FileSystem->MountPoint; -} -FSP_API PWSTR FspFileSystemMountPointF(FSP_FILE_SYSTEM *FileSystem); -static inline -NTSTATUS FspFileSystemEnterOperation(FSP_FILE_SYSTEM *FileSystem, - FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response) -{ - if (0 == FileSystem->EnterOperation) - return STATUS_SUCCESS; - - return FileSystem->EnterOperation(FileSystem, Request, Response); -} -FSP_API NTSTATUS FspFileSystemEnterOperationF(FSP_FILE_SYSTEM *FileSystem, - FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response); -static inline -NTSTATUS FspFileSystemLeaveOperation(FSP_FILE_SYSTEM *FileSystem, - FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response) -{ - if (0 == FileSystem->LeaveOperation) - return STATUS_SUCCESS; - - return FileSystem->LeaveOperation(FileSystem, Request, Response); -} -FSP_API NTSTATUS FspFileSystemLeaveOperationF(FSP_FILE_SYSTEM *FileSystem, - FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response); -static inline -VOID FspFileSystemSetOperationGuard(FSP_FILE_SYSTEM *FileSystem, - FSP_FILE_SYSTEM_OPERATION_GUARD *EnterOperation, - FSP_FILE_SYSTEM_OPERATION_GUARD *LeaveOperation) -{ - FileSystem->EnterOperation = EnterOperation; - FileSystem->LeaveOperation = LeaveOperation; -} -FSP_API VOID FspFileSystemSetOperationGuardF(FSP_FILE_SYSTEM *FileSystem, - FSP_FILE_SYSTEM_OPERATION_GUARD *EnterOperation, - FSP_FILE_SYSTEM_OPERATION_GUARD *LeaveOperation); -/** - * Set file system locking strategy. - * - * @param FileSystem - * The file system object. - * @param GuardStrategy - * The locking (guard) strategy. - * @see - * FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY - */ -static inline -VOID FspFileSystemSetOperationGuardStrategy(FSP_FILE_SYSTEM *FileSystem, - FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY GuardStrategy) -{ - FileSystem->OpGuardStrategy = GuardStrategy; -} -FSP_API VOID FspFileSystemSetOperationGuardStrategyF(FSP_FILE_SYSTEM *FileSystem, - FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY GuardStrategy); -static inline -VOID FspFileSystemSetOperation(FSP_FILE_SYSTEM *FileSystem, - ULONG Index, - FSP_FILE_SYSTEM_OPERATION *Operation) -{ - FileSystem->Operations[Index] = Operation; -} -FSP_API VOID FspFileSystemSetOperationF(FSP_FILE_SYSTEM *FileSystem, - ULONG Index, - FSP_FILE_SYSTEM_OPERATION *Operation); -static inline -VOID FspFileSystemGetDispatcherResult(FSP_FILE_SYSTEM *FileSystem, - NTSTATUS *PDispatcherResult) -{ - *PDispatcherResult = FspInterlockedLoad32((INT32 *)&FileSystem->DispatcherResult); -} -FSP_API VOID FspFileSystemGetDispatcherResultF(FSP_FILE_SYSTEM *FileSystem, - NTSTATUS *PDispatcherResult); -static inline -VOID FspFileSystemSetDispatcherResult(FSP_FILE_SYSTEM *FileSystem, - NTSTATUS DispatcherResult) -{ - if (NT_SUCCESS(DispatcherResult)) - return; - InterlockedCompareExchange(&FileSystem->DispatcherResult, DispatcherResult, 0); -} -FSP_API VOID FspFileSystemSetDispatcherResultF(FSP_FILE_SYSTEM *FileSystem, - NTSTATUS DispatcherResult); -static inline -VOID FspFileSystemSetDebugLog(FSP_FILE_SYSTEM *FileSystem, - UINT32 DebugLog) -{ - FileSystem->DebugLog = DebugLog; -} -FSP_API VOID FspFileSystemSetDebugLogF(FSP_FILE_SYSTEM *FileSystem, - UINT32 DebugLog); -static inline -BOOLEAN FspFileSystemIsOperationCaseSensitive(VOID) -{ - FSP_FSCTL_TRANSACT_REQ *Request = FspFileSystemGetOperationContext()->Request; - return - FspFsctlTransactCreateKind == Request->Kind && Request->Req.Create.CaseSensitive || - FspFsctlTransactQueryDirectoryKind == Request->Kind && Request->Req.QueryDirectory.CaseSensitive; -} -FSP_API BOOLEAN FspFileSystemIsOperationCaseSensitiveF(VOID); -/** - * Gets the originating process ID. - * - * Valid only during Create, Open and Rename requests when the target exists. - */ -static inline -UINT32 FspFileSystemOperationProcessId(VOID) -{ - FSP_FSCTL_TRANSACT_REQ *Request = FspFileSystemGetOperationContext()->Request; - switch (Request->Kind) - { - case FspFsctlTransactCreateKind: - return FSP_FSCTL_TRANSACT_REQ_TOKEN_PID(Request->Req.Create.AccessToken); - case FspFsctlTransactSetInformationKind: - if (10/*FileRenameInformation*/ == Request->Req.SetInformation.FileInformationClass || - 65/*FileRenameInformationEx*/ == Request->Req.SetInformation.FileInformationClass) - return FSP_FSCTL_TRANSACT_REQ_TOKEN_PID(Request->Req.SetInformation.Info.Rename.AccessToken); - /* fall through! */ - default: - return 0; - } -} -FSP_API UINT32 FspFileSystemOperationProcessIdF(VOID); - -/* - * Operations - */ -FSP_API NTSTATUS FspFileSystemOpEnter(FSP_FILE_SYSTEM *FileSystem, - FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response); -FSP_API NTSTATUS FspFileSystemOpLeave(FSP_FILE_SYSTEM *FileSystem, - FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response); -FSP_API NTSTATUS FspFileSystemOpCreate(FSP_FILE_SYSTEM *FileSystem, - FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response); -FSP_API NTSTATUS FspFileSystemOpOverwrite(FSP_FILE_SYSTEM *FileSystem, - FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response); -FSP_API NTSTATUS FspFileSystemOpCleanup(FSP_FILE_SYSTEM *FileSystem, - FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response); -FSP_API NTSTATUS FspFileSystemOpClose(FSP_FILE_SYSTEM *FileSystem, - FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response); -FSP_API NTSTATUS FspFileSystemOpRead(FSP_FILE_SYSTEM *FileSystem, - FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response); -FSP_API NTSTATUS FspFileSystemOpWrite(FSP_FILE_SYSTEM *FileSystem, - FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response); -FSP_API NTSTATUS FspFileSystemOpQueryInformation(FSP_FILE_SYSTEM *FileSystem, - FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response); -FSP_API NTSTATUS FspFileSystemOpSetInformation(FSP_FILE_SYSTEM *FileSystem, - FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response); -FSP_API NTSTATUS FspFileSystemOpQueryEa(FSP_FILE_SYSTEM *FileSystem, - FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response); -FSP_API NTSTATUS FspFileSystemOpSetEa(FSP_FILE_SYSTEM *FileSystem, - FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response); -FSP_API NTSTATUS FspFileSystemOpFlushBuffers(FSP_FILE_SYSTEM *FileSystem, - FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response); -FSP_API NTSTATUS FspFileSystemOpQueryVolumeInformation(FSP_FILE_SYSTEM *FileSystem, - FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response); -FSP_API NTSTATUS FspFileSystemOpSetVolumeInformation(FSP_FILE_SYSTEM *FileSystem, - FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response); -FSP_API NTSTATUS FspFileSystemOpQueryDirectory(FSP_FILE_SYSTEM *FileSystem, - FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response); -FSP_API NTSTATUS FspFileSystemOpFileSystemControl(FSP_FILE_SYSTEM *FileSystem, - FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response); -FSP_API NTSTATUS FspFileSystemOpDeviceControl(FSP_FILE_SYSTEM *FileSystem, - FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response); -FSP_API NTSTATUS FspFileSystemOpQuerySecurity(FSP_FILE_SYSTEM *FileSystem, - FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response); -FSP_API NTSTATUS FspFileSystemOpSetSecurity(FSP_FILE_SYSTEM *FileSystem, - FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response); -FSP_API NTSTATUS FspFileSystemOpQueryStreamInformation(FSP_FILE_SYSTEM *FileSystem, - FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response); - -/* - * Helpers - */ -/** - * Get open information buffer. - * - * This is a helper for implementing the Create and Open operations. It cannot be used with - * any other operations. - * - * The FileInfo parameter to Create and Open is typed as pointer to FSP_FSCTL_FILE_INFO. The - * true type of this parameter is pointer to FSP_FSCTL_OPEN_FILE_INFO. This simple function - * converts from one type to the other. - * - * The FSP_FSCTL_OPEN_FILE_INFO type contains a FSP_FSCTL_FILE_INFO as well as the fields - * NormalizedName and NormalizedNameSize. These fields can be used for file name normalization. - * File name normalization is used to ensure that the FSD and the OS know the correct case - * of a newly opened file name. - * - * For case-sensitive file systems this functionality should be ignored. The FSD will always - * assume that the normalized file name is the same as the file name used to open the file. - * - * For case-insensitive file systems this functionality may be ignored. In this case the FSD - * will assume that the normalized file name is the upper case version of the file name used - * to open the file. The file system will work correctly and the only way an application will - * be able to tell that the file system does not preserve case in normalized file names is by - * issuing a GetFinalPathNameByHandle API call (or NtQueryInformationFile with - * FileNameInformation/FileNormalizedNameInformation). - * - * For case-insensitive file systems this functionality may also be used. In this case the - * user mode file system may use the NormalizedName and NormalizedNameSize parameters to - * report to the FSD the normalized file name. It should be noted that the normalized file - * name may only differ in case from the file name used to open the file. The NormalizedName - * field will point to a buffer that can receive the normalized file name. The - * NormalizedNameSize field will contain the size of the normalized file name buffer. On - * completion of the Create or Open operation it should contain the actual size of the - * normalized file name copied into the normalized file name buffer. The normalized file name - * should not contain a terminating zero. - * - * @param FileInfo - * The FileInfo parameter as passed to Create or Open operation. - * @return - * A pointer to the open information buffer for this Create or Open operation. - * @see - * Create - * Open - */ -static inline -FSP_FSCTL_OPEN_FILE_INFO *FspFileSystemGetOpenFileInfo(FSP_FSCTL_FILE_INFO *FileInfo) -{ - return (FSP_FSCTL_OPEN_FILE_INFO *)FileInfo; -} -/** - * Add directory information to a buffer. - * - * This is a helper for implementing the ReadDirectory operation. - * - * @param DirInfo - * The directory information to add. A value of NULL acts as an EOF marker for a ReadDirectory - * operation. - * @param Buffer - * Pointer to a buffer that will receive the results of the read operation. This should contain - * the same value passed to the ReadDirectory Buffer parameter. - * @param Length - * Length of data to read. This should contain the same value passed to the ReadDirectory - * Length parameter. - * @param PBytesTransferred [out] - * Pointer to a memory location that will receive the actual number of bytes read. This should - * contain the same value passed to the ReadDirectory PBytesTransferred parameter. - * FspFileSystemAddDirInfo uses the value pointed by this parameter to track how much of the - * buffer has been used so far. - * @return - * TRUE if the directory information was added, FALSE if there was not enough space to add it. - * @see - * ReadDirectory - */ -FSP_API BOOLEAN FspFileSystemAddDirInfo(FSP_FSCTL_DIR_INFO *DirInfo, - PVOID Buffer, ULONG Length, PULONG PBytesTransferred); -/** - * Find reparse point in file name. - * - * Given a file name this function returns an index to the first path component that is a reparse - * point. The function will call the supplied GetReparsePointByName function for every path - * component until it finds a reparse point or the whole path is processed. - * - * This is a helper for implementing the GetSecurityByName operation in file systems - * that support reparse points. - * - * @param FileSystem - * The file system object. - * @param GetReparsePointByName - * Pointer to function that can retrieve reparse point information by name. The - * FspFileSystemFindReparsePoint will call this function with the Buffer and PSize - * arguments set to NULL. The function should return STATUS_SUCCESS if the passed - * FileName is a reparse point or STATUS_NOT_A_REPARSE_POINT (or other error code) - * otherwise. - * @param Context - * User context to supply to GetReparsePointByName. - * @param FileName - * The name of the file or directory. - * @param PReparsePointIndex - * Pointer to a memory location that will receive the index of the first reparse point - * within FileName. A value is only placed in this memory location if the function returns - * TRUE. May be NULL. - * @return - * TRUE if a reparse point was found, FALSE otherwise. - * @see - * GetSecurityByName - */ -FSP_API BOOLEAN FspFileSystemFindReparsePoint(FSP_FILE_SYSTEM *FileSystem, - NTSTATUS (*GetReparsePointByName)( - FSP_FILE_SYSTEM *FileSystem, PVOID Context, - PWSTR FileName, BOOLEAN IsDirectory, PVOID Buffer, PSIZE_T PSize), - PVOID Context, - PWSTR FileName, PUINT32 PReparsePointIndex); -/** - * Resolve reparse points. - * - * Given a file name (and an index where to start resolving) this function will attempt to - * resolve as many reparse points as possible. The function will call the supplied - * GetReparsePointByName function for every path component until it resolves the reparse points - * or the whole path is processed. - * - * This is a helper for implementing the ResolveReparsePoints operation in file systems - * that support reparse points. - * - * @param FileSystem - * The file system object. - * @param GetReparsePointByName - * Pointer to function that can retrieve reparse point information by name. The function - * should return STATUS_SUCCESS if the passed FileName is a reparse point or - * STATUS_NOT_A_REPARSE_POINT (or other error code) otherwise. - * @param Context - * User context to supply to GetReparsePointByName. - * @param FileName - * The name of the file or directory to have its reparse points resolved. - * @param ReparsePointIndex - * The index of the first reparse point within FileName. - * @param ResolveLastPathComponent - * If FALSE, the last path component of FileName should not be resolved, even - * if it is a reparse point that can be resolved. If TRUE, all path components - * should be resolved if possible. - * @param PIoStatus - * Pointer to storage that will receive the status to return to the FSD. When - * this function succeeds it must set PIoStatus->Status to STATUS_REPARSE and - * PIoStatus->Information to either IO_REPARSE or the reparse tag. - * @param Buffer - * Pointer to a buffer that will receive the resolved file name (IO_REPARSE) or - * reparse data (reparse tag). If the function returns a file name, it should - * not be NULL terminated. - * @param PSize [in,out] - * Pointer to the buffer size. On input it contains the size of the buffer. - * On output it will contain the actual size of data copied. - * @return - * STATUS_REPARSE or error code. - * @see - * ResolveReparsePoints - */ -FSP_API NTSTATUS FspFileSystemResolveReparsePoints(FSP_FILE_SYSTEM *FileSystem, - NTSTATUS (*GetReparsePointByName)( - FSP_FILE_SYSTEM *FileSystem, PVOID Context, - PWSTR FileName, BOOLEAN IsDirectory, PVOID Buffer, PSIZE_T PSize), - PVOID Context, - PWSTR FileName, UINT32 ReparsePointIndex, BOOLEAN ResolveLastPathComponent, - PIO_STATUS_BLOCK PIoStatus, PVOID Buffer, PSIZE_T PSize); -/** - * Test whether reparse data can be replaced. - * - * This is a helper for implementing the SetReparsePoint/DeleteReparsePoint operation - * in file systems that support reparse points. - * - * @param CurrentReparseData - * Pointer to the current reparse data. - * @param CurrentReparseDataSize - * Pointer to the current reparse data size. - * @param ReplaceReparseData - * Pointer to the replacement reparse data. - * @param ReplaceReparseDataSize - * Pointer to the replacement reparse data size. - * @return - * STATUS_SUCCESS or error code. - * @see - * SetReparsePoint - * DeleteReparsePoint - */ -FSP_API NTSTATUS FspFileSystemCanReplaceReparsePoint( - PVOID CurrentReparseData, SIZE_T CurrentReparseDataSize, - PVOID ReplaceReparseData, SIZE_T ReplaceReparseDataSize); -/** - * Add named stream information to a buffer. - * - * This is a helper for implementing the GetStreamInfo operation. - * - * @param StreamInfo - * The stream information to add. A value of NULL acts as an EOF marker for a GetStreamInfo - * operation. - * @param Buffer - * Pointer to a buffer that will receive the stream information. This should contain - * the same value passed to the GetStreamInfo Buffer parameter. - * @param Length - * Length of buffer. This should contain the same value passed to the GetStreamInfo - * Length parameter. - * @param PBytesTransferred [out] - * Pointer to a memory location that will receive the actual number of bytes stored. This should - * contain the same value passed to the GetStreamInfo PBytesTransferred parameter. - * @return - * TRUE if the stream information was added, FALSE if there was not enough space to add it. - * @see - * GetStreamInfo - */ -FSP_API BOOLEAN FspFileSystemAddStreamInfo(FSP_FSCTL_STREAM_INFO *StreamInfo, - PVOID Buffer, ULONG Length, PULONG PBytesTransferred); -/** - * Enumerate extended attributes in a buffer. - * - * This is a helper for implementing the CreateEx and SetEa operations in file systems - * that support extended attributes. - * - * @param FileSystem - * The file system object. - * @param EnumerateEa - * Pointer to function that receives a single extended attribute. The function - * should return STATUS_SUCCESS or an error code if unsuccessful. - * @param Context - * User context to supply to EnumEa. - * @param Ea - * Extended attributes buffer. - * @param EaLength - * Extended attributes buffer length. - * @return - * STATUS_SUCCESS or error code from EnumerateEa. - */ -FSP_API NTSTATUS FspFileSystemEnumerateEa(FSP_FILE_SYSTEM *FileSystem, - NTSTATUS (*EnumerateEa)( - FSP_FILE_SYSTEM *FileSystem, PVOID Context, - PFILE_FULL_EA_INFORMATION SingleEa), - PVOID Context, - PFILE_FULL_EA_INFORMATION Ea, ULONG EaLength); -/** - * Add extended attribute to a buffer. - * - * This is a helper for implementing the GetEa operation. - * - * @param SingleEa - * The extended attribute to add. A value of NULL acts as an EOF marker for a GetEa - * operation. - * @param Ea - * Pointer to a buffer that will receive the extended attribute. This should contain - * the same value passed to the GetEa Ea parameter. - * @param EaLength - * Length of buffer. This should contain the same value passed to the GetEa - * EaLength parameter. - * @param PBytesTransferred [out] - * Pointer to a memory location that will receive the actual number of bytes stored. This should - * contain the same value passed to the GetEa PBytesTransferred parameter. - * @return - * TRUE if the extended attribute was added, FALSE if there was not enough space to add it. - * @see - * GetEa - */ -FSP_API BOOLEAN FspFileSystemAddEa(PFILE_FULL_EA_INFORMATION SingleEa, - PFILE_FULL_EA_INFORMATION Ea, ULONG EaLength, PULONG PBytesTransferred); -/** - * Get extended attribute "packed" size. This computation matches what NTFS reports. - * - * @param SingleEa - * The extended attribute to get the size for. - * @return - * The packed size of the extended attribute. - */ -static inline -UINT32 FspFileSystemGetEaPackedSize(PFILE_FULL_EA_INFORMATION SingleEa) -{ - /* magic computations are courtesy of NTFS */ - return 5 + SingleEa->EaNameLength + SingleEa->EaValueLength; -} -/** - * Add notify information to a buffer. - * - * This is a helper for filling a buffer to use with FspFileSystemNotify. - * - * @param NotifyInfo - * The notify information to add. - * @param Buffer - * Pointer to a buffer that will receive the notify information. - * @param Length - * Length of buffer. - * @param PBytesTransferred [out] - * Pointer to a memory location that will receive the actual number of bytes stored. This should - * be initialized to 0 prior to the first call to FspFileSystemAddNotifyInfo for a particular - * buffer. - * @return - * TRUE if the notify information was added, FALSE if there was not enough space to add it. - * @see - * FspFileSystemNotify - */ -FSP_API BOOLEAN FspFileSystemAddNotifyInfo(FSP_FSCTL_NOTIFY_INFO *NotifyInfo, - PVOID Buffer, ULONG Length, PULONG PBytesTransferred); -/** - * Stop a file system service, if any. - * - * This is a helper for implementing the DispatcherStopped operation, but only for file systems - * that use the FspService infrastructure. - * - * @param FileSystem - * The file system object. - * @param Normally - * TRUE if the file system is being stopped via FspFileSystemStopDispatcher. - * FALSE if the file system is being stopped because of another reason such - * as driver unload/uninstall. - * @see - * DispatcherStopped - */ -FSP_API VOID FspFileSystemStopServiceIfNecessary(FSP_FILE_SYSTEM *FileSystem, - BOOLEAN Normally); - -/* - * Directory buffering - */ -FSP_API BOOLEAN FspFileSystemAcquireDirectoryBufferEx(PVOID* PDirBuffer, - BOOLEAN Reset, ULONG CapacityHint, PNTSTATUS PResult); -FSP_API BOOLEAN FspFileSystemAcquireDirectoryBuffer(PVOID *PDirBuffer, - BOOLEAN Reset, PNTSTATUS PResult); -FSP_API BOOLEAN FspFileSystemFillDirectoryBuffer(PVOID *PDirBuffer, - FSP_FSCTL_DIR_INFO *DirInfo, PNTSTATUS PResult); -FSP_API VOID FspFileSystemReleaseDirectoryBuffer(PVOID *PDirBuffer); -FSP_API VOID FspFileSystemReadDirectoryBuffer(PVOID *PDirBuffer, - PWSTR Marker, - PVOID Buffer, ULONG Length, PULONG PBytesTransferred); -FSP_API VOID FspFileSystemDeleteDirectoryBuffer(PVOID *PDirBuffer); - -/* - * Security - */ -FSP_API PGENERIC_MAPPING FspGetFileGenericMapping(VOID); -FSP_API NTSTATUS FspAccessCheckEx(FSP_FILE_SYSTEM *FileSystem, - FSP_FSCTL_TRANSACT_REQ *Request, - BOOLEAN CheckParentOrMain, BOOLEAN AllowTraverseCheck, - UINT32 DesiredAccess, PUINT32 PGrantedAccess/* or ReparsePointIndex */, - PSECURITY_DESCRIPTOR *PSecurityDescriptor); -FSP_API NTSTATUS FspCreateSecurityDescriptor(FSP_FILE_SYSTEM *FileSystem, - FSP_FSCTL_TRANSACT_REQ *Request, - PSECURITY_DESCRIPTOR ParentDescriptor, - PSECURITY_DESCRIPTOR *PSecurityDescriptor); -/** - * Modify security descriptor. - * - * This is a helper for implementing the SetSecurity operation. - * - * @param InputDescriptor - * The input security descriptor to be modified. - * @param SecurityInformation - * Describes what parts of the InputDescriptor should be modified. This should contain - * the same value passed to the SetSecurity SecurityInformation parameter. - * @param ModificationDescriptor - * Describes the modifications to apply to the InputDescriptor. This should contain - * the same value passed to the SetSecurity ModificationDescriptor parameter. - * @param PSecurityDescriptor [out] - * Pointer to a memory location that will receive the resulting security descriptor. - * This security descriptor can be later freed using FspDeleteSecurityDescriptor. - * @return - * STATUS_SUCCESS or error code. - * @see - * SetSecurity - * FspDeleteSecurityDescriptor - */ -FSP_API NTSTATUS FspSetSecurityDescriptor( - PSECURITY_DESCRIPTOR InputDescriptor, - SECURITY_INFORMATION SecurityInformation, - PSECURITY_DESCRIPTOR ModificationDescriptor, - PSECURITY_DESCRIPTOR *PSecurityDescriptor); -/** - * Delete security descriptor. - * - * This is a helper for implementing the SetSecurity operation. - * - * @param SecurityDescriptor - * The security descriptor to be deleted. - * @param CreateFunc - * Function used to create the security descriptor. This parameter should be - * set to FspSetSecurityDescriptor for the public API. - * @return - * STATUS_SUCCESS or error code. - * @see - * SetSecurity - * FspSetSecurityDescriptor - */ -FSP_API VOID FspDeleteSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor, - NTSTATUS (*CreateFunc)()); -static inline -NTSTATUS FspAccessCheck(FSP_FILE_SYSTEM *FileSystem, - FSP_FSCTL_TRANSACT_REQ *Request, - BOOLEAN CheckParentOrMain, BOOLEAN AllowTraverseCheck, - UINT32 DesiredAccess, PUINT32 PGrantedAccess) -{ - return FspAccessCheckEx(FileSystem, Request, - CheckParentOrMain, AllowTraverseCheck, - DesiredAccess, PGrantedAccess, - 0); -} - -/* - * POSIX Interop - */ -FSP_API NTSTATUS FspPosixSetUidMap(UINT32 Uid[], PSID Sid[], ULONG Count); -FSP_API NTSTATUS FspPosixMapUidToSid(UINT32 Uid, PSID *PSid); -FSP_API NTSTATUS FspPosixMapSidToUid(PSID Sid, PUINT32 PUid); -FSP_API VOID FspDeleteSid(PSID Sid, NTSTATUS (*CreateFunc)()); -FSP_API NTSTATUS FspPosixMapPermissionsToSecurityDescriptor( - UINT32 Uid, UINT32 Gid, UINT32 Mode, - PSECURITY_DESCRIPTOR *PSecurityDescriptor); -FSP_API NTSTATUS FspPosixMergePermissionsToSecurityDescriptor( - UINT32 Uid, UINT32 Gid, UINT32 Mode, - PSECURITY_DESCRIPTOR ExistingSecurityDescriptor, - PSECURITY_DESCRIPTOR *PSecurityDescriptor); -FSP_API NTSTATUS FspPosixMapSecurityDescriptorToPermissions( - PSECURITY_DESCRIPTOR SecurityDescriptor, - PUINT32 PUid, PUINT32 PGid, PUINT32 PMode); -FSP_API NTSTATUS FspPosixMapWindowsToPosixPathEx(PWSTR WindowsPath, char **PPosixPath, - BOOLEAN Translate); -FSP_API NTSTATUS FspPosixMapPosixToWindowsPathEx(const char *PosixPath, PWSTR *PWindowsPath, - BOOLEAN Translate); -static inline -NTSTATUS FspPosixMapWindowsToPosixPath(PWSTR WindowsPath, char **PPosixPath) -{ - return FspPosixMapWindowsToPosixPathEx(WindowsPath, PPosixPath, TRUE); -} -static inline -NTSTATUS FspPosixMapPosixToWindowsPath(const char *PosixPath, PWSTR *PWindowsPath) -{ - return FspPosixMapPosixToWindowsPathEx(PosixPath, PWindowsPath, TRUE); -} -FSP_API VOID FspPosixDeletePath(void *Path); -FSP_API VOID FspPosixEncodeWindowsPath(PWSTR WindowsPath, ULONG Size); -FSP_API VOID FspPosixDecodeWindowsPath(PWSTR WindowsPath, ULONG Size); -static inline -VOID FspPosixFileTimeToUnixTime(UINT64 FileTime0, __int3264 UnixTime[2]) -{ - INT64 FileTime = (INT64)FileTime0 - 116444736000000000LL; - UnixTime[0] = (__int3264)(FileTime / 10000000); - UnixTime[1] = (__int3264)(FileTime % 10000000 * 100); - /* may produce negative nsec for times before UNIX epoch; strictly speaking this is incorrect */ -} -static inline -VOID FspPosixUnixTimeToFileTime(const __int3264 UnixTime[2], PUINT64 PFileTime) -{ - INT64 FileTime = (INT64)UnixTime[0] * 10000000 + (INT64)UnixTime[1] / 100 + - 116444736000000000LL; - *PFileTime = FileTime; -} - -/* - * Path Handling - */ -FSP_API VOID FspPathPrefix(PWSTR Path, PWSTR *PPrefix, PWSTR *PRemain, PWSTR Root); -FSP_API VOID FspPathSuffix(PWSTR Path, PWSTR *PRemain, PWSTR *PSuffix, PWSTR Root); -FSP_API VOID FspPathCombine(PWSTR Prefix, PWSTR Suffix); - -/** - * @group Service Framework - * - * User mode file systems typically are run as Windows services. WinFsp provides an API to make - * the creation of Windows services easier. This API is provided for convenience and is not - * necessary to expose a user mode file system to Windows. - */ -typedef struct _FSP_SERVICE FSP_SERVICE; -typedef NTSTATUS FSP_SERVICE_START(FSP_SERVICE *, ULONG, PWSTR *); -typedef NTSTATUS FSP_SERVICE_STOP(FSP_SERVICE *); -typedef NTSTATUS FSP_SERVICE_CONTROL(FSP_SERVICE *, ULONG, ULONG, PVOID); -#pragma warning(push) -#pragma warning(disable:4200) /* zero-sized array in struct/union */ -typedef struct _FSP_SERVICE -{ - UINT16 Version; - PVOID UserContext; - FSP_SERVICE_START *OnStart; - FSP_SERVICE_STOP *OnStop; - FSP_SERVICE_CONTROL *OnControl; - ULONG AcceptControl; - ULONG ExitCode; - SERVICE_STATUS_HANDLE StatusHandle; - SERVICE_STATUS ServiceStatus; - CRITICAL_SECTION ServiceStatusGuard; - CRITICAL_SECTION ServiceStopGuard; - BOOLEAN AllowConsoleMode; - WCHAR ServiceName[]; -} FSP_SERVICE; -#pragma warning(pop) -/** - * Run a service. - * - * This function wraps calls to FspServiceCreate, FspServiceLoop and FspServiceDelete to create, - * run and delete a service. It is intended to be used from a service's main/wmain function. - * - * This function runs a service with console mode allowed. - * - * @param ServiceName - * The name of the service. - * @param OnStart - * Function to call when the service starts. - * @param OnStop - * Function to call when the service stops. - * @param OnControl - * Function to call when the service receives a service control code. - * @return - * Service process exit code. - */ -FSP_API ULONG FspServiceRunEx(PWSTR ServiceName, - FSP_SERVICE_START *OnStart, - FSP_SERVICE_STOP *OnStop, - FSP_SERVICE_CONTROL *OnControl, - PVOID UserContext); -static inline -ULONG FspServiceRun(PWSTR ServiceName, - FSP_SERVICE_START *OnStart, - FSP_SERVICE_STOP *OnStop, - FSP_SERVICE_CONTROL *OnControl) -{ - return FspServiceRunEx(ServiceName, OnStart, OnStop, OnControl, 0); -} -/** - * Create a service object. - * - * @param ServiceName - * The name of the service. - * @param OnStart - * Function to call when the service starts. - * @param OnStop - * Function to call when the service stops. - * @param OnControl - * Function to call when the service receives a service control code. - * @param PService [out] - * Pointer that will receive the service object created on successful return from this - * call. - * @return - * STATUS_SUCCESS or error code. - */ -FSP_API NTSTATUS FspServiceCreate(PWSTR ServiceName, - FSP_SERVICE_START *OnStart, - FSP_SERVICE_STOP *OnStop, - FSP_SERVICE_CONTROL *OnControl, - FSP_SERVICE **PService); -/** - * Delete a service object. - * - * @param Service - * The service object. - */ -FSP_API VOID FspServiceDelete(FSP_SERVICE *Service); -/** - * Allow a service to run in console mode. - * - * A service that is run in console mode runs with a console attached and outside the control of - * the Service Control Manager. This is useful for debugging and testing a service during - * development. - * - * User mode file systems that wish to use the WinFsp Launcher functionality must also use this - * call. The WinFsp Launcher is a Windows service that can be configured to launch and manage - * multiple instances of a user mode file system. - * - * @param Service - * The service object. - */ -FSP_API VOID FspServiceAllowConsoleMode(FSP_SERVICE *Service); -/** - * Configure the control codes that a service accepts. - * - * This API should be used prior to Start operations. - * - * @param Service - * The service object. - * @param Control - * The control codes to accept. Note that the SERVICE_ACCEPT_PAUSE_CONTINUE code is silently - * ignored. - */ -FSP_API VOID FspServiceAcceptControl(FSP_SERVICE *Service, ULONG Control); -/** - * Request additional time from the Service Control Manager. - * - * This API should be used during Start and Stop operations only. - * - * @param Service - * The service object. - * @param Time - * Additional time (in milliseconds). - */ -FSP_API VOID FspServiceRequestTime(FSP_SERVICE *Service, ULONG Time); -/** - * Set the service process exit code. - * - * @param Service - * The service object. - * @param ExitCode - * Service process exit code. - */ -FSP_API VOID FspServiceSetExitCode(FSP_SERVICE *Service, ULONG ExitCode); -/** - * Get the service process exit code. - * - * @param Service - * The service object. - * @return - * Service process exit code. - */ -FSP_API ULONG FspServiceGetExitCode(FSP_SERVICE *Service); -/** - * Run a service main loop. - * - * This function starts and runs a service. It executes the Windows StartServiceCtrlDispatcher API - * to connect the service process to the Service Control Manager. If the Service Control Manager is - * not available (and console mode is allowed) it will enter console mode. - * - * This function should be called once per process. - * - * @param Service - * The service object. - * @return - * STATUS_SUCCESS or error code. - */ -FSP_API NTSTATUS FspServiceLoop(FSP_SERVICE *Service); -/** - * Stops a running service. - * - * Stopping a service usually happens when the Service Control Manager instructs the service to - * stop. In some situations (e.g. fatal errors) the service may wish to stop itself. It can do so - * in a clean manner by calling this function. - * - * @param Service - * The service object. - * @return - * STATUS_SUCCESS or error code. - */ -FSP_API VOID FspServiceStop(FSP_SERVICE *Service); -/** - * Determine if the current process is running in user interactive mode. - * - * @return - * TRUE if the process is running in running user interactive mode. - */ -FSP_API BOOLEAN FspServiceIsInteractive(VOID); -/** - * Check if the supplied token is from the service context. - * - * @param Token - * Token to check. Pass NULL to check the current process token. - * @param PIsLocalSystem - * Pointer to a boolean that will receive a TRUE value if the token belongs to LocalSystem - * and FALSE otherwise. May be NULL. - * @return - * STATUS_SUCCESS if the token is from the service context. STATUS_ACCESS_DENIED if it is not. - * Other error codes are possible. - */ -FSP_API NTSTATUS FspServiceContextCheck(HANDLE Token, PBOOLEAN PIsLocalSystem); -/** - * Log a service message. - * - * This function can be used to log an arbitrary message to the Windows Event Log or to the current - * console if running in user interactive mode. - * - * @param Type - * One of EVENTLOG_INFORMATION_TYPE, EVENTLOG_WARNING_TYPE, EVENTLOG_ERROR_TYPE. - * @param Format - * Format specification. This function uses the Windows wsprintf API for formatting. Refer to - * that API's documentation for details on the format specification. - */ -FSP_API VOID FspServiceLog(ULONG Type, PWSTR Format, ...); -FSP_API VOID FspServiceLogV(ULONG Type, PWSTR Format, va_list ap); - -/* - * Utility - */ -FSP_API NTSTATUS FspNtStatusFromWin32(DWORD Error); -FSP_API DWORD FspWin32FromNtStatus(NTSTATUS Status); -FSP_API VOID FspEventLog(ULONG Type, PWSTR Format, ...); -FSP_API VOID FspEventLogV(ULONG Type, PWSTR Format, va_list ap); -FSP_API VOID FspDebugLogSetHandle(HANDLE Handle); -FSP_API VOID FspDebugLog(const char *Format, ...); -FSP_API VOID FspDebugLogSD(const char *Format, PSECURITY_DESCRIPTOR SecurityDescriptor); -FSP_API VOID FspDebugLogSid(const char *format, PSID Sid); -FSP_API VOID FspDebugLogFT(const char *Format, PFILETIME FileTime); -FSP_API VOID FspDebugLogRequest(FSP_FSCTL_TRANSACT_REQ *Request); -FSP_API VOID FspDebugLogResponse(FSP_FSCTL_TRANSACT_RSP *Response); -FSP_API NTSTATUS FspCallNamedPipeSecurely(PWSTR PipeName, - PVOID InBuffer, ULONG InBufferSize, PVOID OutBuffer, ULONG OutBufferSize, - PULONG PBytesTransferred, ULONG Timeout, - PSID Sid); -FSP_API NTSTATUS FspCallNamedPipeSecurelyEx(PWSTR PipeName, - PVOID InBuffer, ULONG InBufferSize, PVOID OutBuffer, ULONG OutBufferSize, - PULONG PBytesTransferred, ULONG Timeout, BOOLEAN AllowImpersonation, - PSID Sid); -FSP_API NTSTATUS FspVersion(PUINT32 PVersion); -FSP_API PWSTR FspSxsIdent(VOID); - -/* - * Delay load - */ -static inline -NTSTATUS FspLoad(PVOID *PModule) -{ -#define FSP_DLLNAME FSP_FSCTL_PRODUCT_FILE_NAME "-" FSP_FSCTL_PRODUCT_FILE_ARCH ".dll" -#define FSP_DLLPATH "bin\\" FSP_DLLNAME - - WINADVAPI - LSTATUS - APIENTRY - RegGetValueW( - HKEY hkey, - LPCWSTR lpSubKey, - LPCWSTR lpValue, - DWORD dwFlags, - LPDWORD pdwType, - PVOID pvData, - LPDWORD pcbData); - - WCHAR PathBuf[MAX_PATH]; - DWORD Size; - LONG Result; - HMODULE Module; - - if (0 != PModule) - *PModule = 0; - - Module = LoadLibraryW(L"" FSP_DLLNAME); - if (0 == Module) - { - Size = sizeof PathBuf - sizeof L"" FSP_DLLPATH + sizeof(WCHAR); - Result = RegGetValueW(HKEY_LOCAL_MACHINE, L"" FSP_FSCTL_PRODUCT_FULL_REGKEY, L"InstallDir", - RRF_RT_REG_SZ, 0, PathBuf, &Size); - if (ERROR_SUCCESS != Result) - return STATUS_OBJECT_NAME_NOT_FOUND; - - RtlCopyMemory(PathBuf + (Size / sizeof(WCHAR) - 1), L"" FSP_DLLPATH, sizeof L"" FSP_DLLPATH); - Module = LoadLibraryW(PathBuf); - if (0 == Module) - return STATUS_DLL_NOT_FOUND; - } - - if (0 != PModule) - *PModule = Module; - - return STATUS_SUCCESS; - -#undef FSP_DLLPATH -#undef FSP_DLLNAME -} - -#ifdef __cplusplus -} -#endif - -#endif +/** + * @file winfsp/winfsp.h + * WinFsp User Mode API. + * + * In order to use the WinFsp API the user mode file system must include <winfsp/winfsp.h> + * and link with the winfsp_x64.dll (or winfsp_x86.dll) library. + * + * @copyright 2015-2025 Bill Zissimopoulos + */ +/* + * This file is part of WinFsp. + * + * You can redistribute it and/or modify it under the terms of the GNU + * General Public License version 3 as published by the Free Software + * Foundation. + * + * Licensees holding a valid commercial license may use this software + * in accordance with the commercial license agreement provided in + * conjunction with the software. The terms and conditions of any such + * commercial license agreement shall govern, supersede, and render + * ineffective any application of the GPLv3 license to this software, + * notwithstanding of any reference thereto in the software or + * associated repository. + */ + +#ifndef WINFSP_WINFSP_H_INCLUDED +#define WINFSP_WINFSP_H_INCLUDED + +#define WIN32_NO_STATUS +#include +#undef WIN32_NO_STATUS +#include +#pragma warning(push) +#pragma warning(disable:4005) /* macro redefinition */ +#include +#pragma warning(pop) + +#if defined(WINFSP_DLL_INTERNAL) +#define FSP_API __declspec(dllexport) +#else +#define FSP_API __declspec(dllimport) +#endif + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * The REPARSE_DATA_BUFFER definitions appear to be missing from the user mode headers. + */ +#if !defined(SYMLINK_FLAG_RELATIVE) +#define SYMLINK_FLAG_RELATIVE 1 +#define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER, GenericReparseBuffer) +typedef struct _REPARSE_DATA_BUFFER +{ + ULONG ReparseTag; + USHORT ReparseDataLength; + USHORT Reserved; + union + { + struct + { + USHORT SubstituteNameOffset; + USHORT SubstituteNameLength; + USHORT PrintNameOffset; + USHORT PrintNameLength; + ULONG Flags; + WCHAR PathBuffer[1]; + } SymbolicLinkReparseBuffer; + struct + { + USHORT SubstituteNameOffset; + USHORT SubstituteNameLength; + USHORT PrintNameOffset; + USHORT PrintNameLength; + WCHAR PathBuffer[1]; + } MountPointReparseBuffer; + struct + { + UCHAR DataBuffer[1]; + } GenericReparseBuffer; + } DUMMYUNIONNAME; +} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER; +#endif + +/* + * The FILE_FULL_EA_INFORMATION definitions are missing from the user mode headers. + */ +#if !defined(FILE_NEED_EA) +#define FILE_NEED_EA 0x00000080 +#endif +#if !defined(__MINGW32__) +typedef struct _FILE_FULL_EA_INFORMATION +{ + ULONG NextEntryOffset; + UCHAR Flags; + UCHAR EaNameLength; + USHORT EaValueLength; + CHAR EaName[1]; +} FILE_FULL_EA_INFORMATION, *PFILE_FULL_EA_INFORMATION; +#endif + +/** + * @group File System + * + * A user mode file system is a program that uses the WinFsp API to expose a file system to + * Windows. The user mode file system must implement the operations in FSP_FILE_SYSTEM_INTERFACE, + * create a file system object using FspFileSystemCreate and start its dispatcher using + * FspFileSystemStartDispatcher. At that point it will start receiving file system requests on the + * FSP_FILE_SYSTEM_INTERFACE operations. + */ +typedef struct _FSP_FILE_SYSTEM FSP_FILE_SYSTEM; +typedef NTSTATUS FSP_FILE_SYSTEM_OPERATION_GUARD(FSP_FILE_SYSTEM *, + FSP_FSCTL_TRANSACT_REQ *, FSP_FSCTL_TRANSACT_RSP *); +typedef NTSTATUS FSP_FILE_SYSTEM_OPERATION(FSP_FILE_SYSTEM *, + FSP_FSCTL_TRANSACT_REQ *, FSP_FSCTL_TRANSACT_RSP *); +/** + * User mode file system locking strategy. + * + * Two concurrency models are provided: + * + * 1. A fine-grained concurrency model where file system NAMESPACE accesses + * are guarded using an exclusive-shared (read-write) lock. File I/O is not + * guarded and concurrent reads/writes/etc. are possible. [Note that the FSD + * will still apply an exclusive-shared lock PER INDIVIDUAL FILE, but it will + * not limit I/O operations for different files.] + * + * The fine-grained concurrency model applies the exclusive-shared lock as + * follows: + *
    + *
  • EXCL: SetVolumeLabel, Flush(Volume), + * Create, Cleanup(Delete), SetInformation(Rename)
  • + *
  • SHRD: GetVolumeInfo, Open, SetInformation(Disposition), ReadDirectory
  • + *
  • NONE: all other operations
  • + *
+ * + * 2. A coarse-grained concurrency model where all file system accesses are + * guarded by a mutually exclusive lock. + * + * @see FspFileSystemSetOperationGuardStrategy + */ +typedef enum +{ + FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY_FINE = 0, + FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY_COARSE, +} FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY; +enum +{ + FspCleanupDelete = 0x01, + FspCleanupSetAllocationSize = 0x02, + FspCleanupSetArchiveBit = 0x10, + FspCleanupSetLastAccessTime = 0x20, + FspCleanupSetLastWriteTime = 0x40, + FspCleanupSetChangeTime = 0x80, +}; +/** + * @class FSP_FILE_SYSTEM + * File system interface. + * + * The operations in this interface must be implemented by the user mode + * file system. Not all operations need be implemented. For example, + * a user mode file system that does not wish to support reparse points, + * need not implement the reparse point operations. + * + * Most of the operations accept a FileContext parameter. This parameter + * has different meanings depending on the value of the FSP_FSCTL_VOLUME_PARAMS + * flags UmFileContextIsUserContext2 and UmFileContextIsFullContext. + * + * There are three cases to consider: + *
    + *
  • When both of these flags are unset (default), the FileContext parameter + * represents the file node. The file node is a void pointer (or an integer + * that can fit in a pointer) that is used to uniquely identify an open file. + * Opening the same file name should always yield the same file node value + * for as long as the file with that name remains open anywhere in the system. + *
  • + *
  • When the UmFileContextIsUserContext2 is set, the FileContext parameter + * represents the file descriptor. The file descriptor is a void pointer (or + * an integer that can fit in a pointer) that is used to identify an open + * instance of a file. Opening the same file name may yield a different file + * descriptor. + *
  • + *
  • When the UmFileContextIsFullContext is set, the FileContext parameter + * is a pointer to a FSP_FSCTL_TRANSACT_FULL_CONTEXT. This allows a user mode + * file system to access the low-level UserContext and UserContext2 values. + * The UserContext is used to store the file node and the UserContext2 is + * used to store the file descriptor for an open file. + *
  • + *
+ */ +typedef struct _FSP_FILE_SYSTEM_INTERFACE +{ + /** + * Get volume information. + * + * @param FileSystem + * The file system on which this request is posted. + * @param VolumeInfo [out] + * Pointer to a structure that will receive the volume information on successful return + * from this call. + * @return + * STATUS_SUCCESS or error code. + */ + NTSTATUS (*GetVolumeInfo)(FSP_FILE_SYSTEM *FileSystem, + FSP_FSCTL_VOLUME_INFO *VolumeInfo); + /** + * Set volume label. + * + * @param FileSystem + * The file system on which this request is posted. + * @param VolumeLabel + * The new label for the volume. + * @param VolumeInfo [out] + * Pointer to a structure that will receive the volume information on successful return + * from this call. + * @return + * STATUS_SUCCESS or error code. + */ + NTSTATUS (*SetVolumeLabel)(FSP_FILE_SYSTEM *FileSystem, + PWSTR VolumeLabel, + FSP_FSCTL_VOLUME_INFO *VolumeInfo); + /** + * Get file or directory attributes and security descriptor given a file name. + * + * @param FileSystem + * The file system on which this request is posted. + * @param FileName + * The name of the file or directory to get the attributes and security descriptor for. + * @param PFileAttributes + * Pointer to a memory location that will receive the file attributes on successful return + * from this call. May be NULL. + * + * If this call returns STATUS_REPARSE, the file system MAY place here the index of the + * first reparse point within FileName. The file system MAY also leave this at its default + * value of 0. + * @param SecurityDescriptor + * Pointer to a buffer that will receive the file security descriptor on successful return + * from this call. May be NULL. + * @param PSecurityDescriptorSize [in,out] + * Pointer to the security descriptor buffer size. On input it contains the size of the + * security descriptor buffer. On output it will contain the actual size of the security + * descriptor copied into the security descriptor buffer. May be NULL. + * @return + * STATUS_SUCCESS, STATUS_REPARSE or error code. + * + * STATUS_REPARSE should be returned by file systems that support reparse points when + * they encounter a FileName that contains reparse points anywhere but the final path + * component. + */ + NTSTATUS (*GetSecurityByName)(FSP_FILE_SYSTEM *FileSystem, + PWSTR FileName, PUINT32 PFileAttributes/* or ReparsePointIndex */, + PSECURITY_DESCRIPTOR SecurityDescriptor, SIZE_T *PSecurityDescriptorSize); + /** + * Create new file or directory. + * + * @param FileSystem + * The file system on which this request is posted. + * @param FileName + * The name of the file or directory to be created. + * @param CreateOptions + * Create options for this request. This parameter has the same meaning as the + * CreateOptions parameter of the NtCreateFile API. User mode file systems should typically + * only be concerned with the flag FILE_DIRECTORY_FILE, which is an instruction to create a + * directory rather than a file. Some file systems may also want to pay attention to the + * FILE_NO_INTERMEDIATE_BUFFERING and FILE_WRITE_THROUGH flags, although these are + * typically handled by the FSD component. + * @param GrantedAccess + * Determines the specific access rights that have been granted for this request. Upon + * receiving this call all access checks have been performed and the user mode file system + * need not perform any additional checks. However this parameter may be useful to a user + * mode file system; for example the WinFsp-FUSE layer uses this parameter to determine + * which flags to use in its POSIX open() call. + * @param FileAttributes + * File attributes to apply to the newly created file or directory. + * @param SecurityDescriptor + * Security descriptor to apply to the newly created file or directory. This security + * descriptor will always be in self-relative format. Its length can be retrieved using the + * Windows GetSecurityDescriptorLength API. Will be NULL for named streams. + * @param AllocationSize + * Allocation size for the newly created file. + * @param PFileContext [out] + * Pointer that will receive the file context on successful return from this call. + * @param FileInfo [out] + * Pointer to a structure that will receive the file information on successful return + * from this call. This information includes file attributes, file times, etc. + * @return + * STATUS_SUCCESS or error code. + */ + NTSTATUS (*Create)(FSP_FILE_SYSTEM *FileSystem, + PWSTR FileName, UINT32 CreateOptions, UINT32 GrantedAccess, + UINT32 FileAttributes, PSECURITY_DESCRIPTOR SecurityDescriptor, UINT64 AllocationSize, + PVOID *PFileContext, FSP_FSCTL_FILE_INFO *FileInfo); + /** + * Open a file or directory. + * + * @param FileSystem + * The file system on which this request is posted. + * @param FileName + * The name of the file or directory to be opened. + * @param CreateOptions + * Create options for this request. This parameter has the same meaning as the + * CreateOptions parameter of the NtCreateFile API. User mode file systems typically + * do not need to do anything special with respect to this parameter. Some file systems may + * also want to pay attention to the FILE_NO_INTERMEDIATE_BUFFERING and FILE_WRITE_THROUGH + * flags, although these are typically handled by the FSD component. + * @param GrantedAccess + * Determines the specific access rights that have been granted for this request. Upon + * receiving this call all access checks have been performed and the user mode file system + * need not perform any additional checks. However this parameter may be useful to a user + * mode file system; for example the WinFsp-FUSE layer uses this parameter to determine + * which flags to use in its POSIX open() call. + * @param PFileContext [out] + * Pointer that will receive the file context on successful return from this call. + * @param FileInfo [out] + * Pointer to a structure that will receive the file information on successful return + * from this call. This information includes file attributes, file times, etc. + * @return + * STATUS_SUCCESS or error code. + */ + NTSTATUS (*Open)(FSP_FILE_SYSTEM *FileSystem, + PWSTR FileName, UINT32 CreateOptions, UINT32 GrantedAccess, + PVOID *PFileContext, FSP_FSCTL_FILE_INFO *FileInfo); + /** + * Overwrite a file. + * + * @param FileSystem + * The file system on which this request is posted. + * @param FileContext + * The file context of the file to overwrite. + * @param FileAttributes + * File attributes to apply to the overwritten file. + * @param ReplaceFileAttributes + * When TRUE the existing file attributes should be replaced with the new ones. + * When FALSE the existing file attributes should be merged (or'ed) with the new ones. + * @param AllocationSize + * Allocation size for the overwritten file. + * @param FileInfo [out] + * Pointer to a structure that will receive the file information on successful return + * from this call. This information includes file attributes, file times, etc. + * @return + * STATUS_SUCCESS or error code. + */ + NTSTATUS (*Overwrite)(FSP_FILE_SYSTEM *FileSystem, + PVOID FileContext, UINT32 FileAttributes, BOOLEAN ReplaceFileAttributes, UINT64 AllocationSize, + FSP_FSCTL_FILE_INFO *FileInfo); + /** + * Cleanup a file. + * + * When CreateFile is used to open or create a file the kernel creates a kernel mode file + * object (type FILE_OBJECT) and a handle for it, which it returns to user-mode. The handle may + * be duplicated (using DuplicateHandle), but all duplicate handles always refer to the same + * file object. When all handles for a particular file object get closed (using CloseHandle) + * the system sends a Cleanup request to the file system. + * + * There will be a Cleanup operation for every Create or Open operation posted to the user mode + * file system. However the Cleanup operation is not the final close operation on a file. + * The file system must be ready to receive additional operations until close time. This is true + * even when the file is being deleted! + * + * The Flags parameter contains information about the cleanup operation: + *
    + *
  • FspCleanupDelete - + * An important function of the Cleanup operation is to complete a delete operation. Deleting + * a file or directory in Windows is a three-stage process where the file is first opened, then + * tested to see if the delete can proceed and if the answer is positive the file is then + * deleted during Cleanup. + * + * If the file system supports POSIX unlink (FSP_FSCTL_VOLUME_PARAMS :: + * SupportsPosixUnlinkRename), then a Cleanup / FspCleanupDelete operation may arrive while + * there are other open file handles for this particular file node. If the file system does not + * support POSIX unlink, then a Cleanup / FspCleanupDelete operation will always be the last + * outstanding cleanup for this particular file node. + *
  • + *
  • FspCleanupSetAllocationSize - + * The NTFS and FAT file systems reset a file's allocation size when they receive the last + * outstanding cleanup for a particular file node. User mode file systems that implement + * allocation size and wish to duplicate the NTFS and FAT behavior can use this flag. + *
  • + *
  • + * FspCleanupSetArchiveBit - + * File systems that support the archive bit should set the file node's archive bit when this + * flag is set. + *
  • + *
  • FspCleanupSetLastAccessTime, FspCleanupSetLastWriteTime, FspCleanupSetChangeTime - File + * systems should set the corresponding file time when each one of these flags is set. Note that + * updating the last access time is expensive and a file system may choose to not implement it. + *
+ * + * There is no way to report failure of this operation. This is a Windows limitation. + * + * As an optimization a file system may specify the FSP_FSCTL_VOLUME_PARAMS :: + * PostCleanupWhenModifiedOnly flag. In this case the FSD will only post Cleanup requests when + * the file was modified/deleted. + * + * @param FileSystem + * The file system on which this request is posted. + * @param FileContext + * The file context of the file or directory to cleanup. + * @param FileName + * The name of the file or directory to cleanup. Sent only when a Delete is requested. + * @param Flags + * These flags determine whether the file was modified and whether to delete the file. + * @see + * Close + * CanDelete + * SetDelete + */ + VOID (*Cleanup)(FSP_FILE_SYSTEM *FileSystem, + PVOID FileContext, PWSTR FileName, ULONG Flags); + /** + * Close a file. + * + * @param FileSystem + * The file system on which this request is posted. + * @param FileContext + * The file context of the file or directory to be closed. + */ + VOID (*Close)(FSP_FILE_SYSTEM *FileSystem, + PVOID FileContext); + /** + * Read a file. + * + * @param FileSystem + * The file system on which this request is posted. + * @param FileContext + * The file context of the file to be read. + * @param Buffer + * Pointer to a buffer that will receive the results of the read operation. + * @param Offset + * Offset within the file to read from. + * @param Length + * Length of data to read. + * @param PBytesTransferred [out] + * Pointer to a memory location that will receive the actual number of bytes read. + * @return + * STATUS_SUCCESS or error code. STATUS_PENDING is supported allowing for asynchronous + * operation. + */ + NTSTATUS (*Read)(FSP_FILE_SYSTEM *FileSystem, + PVOID FileContext, PVOID Buffer, UINT64 Offset, ULONG Length, + PULONG PBytesTransferred); + /** + * Write a file. + * + * @param FileSystem + * The file system on which this request is posted. + * @param FileContext + * The file context of the file to be written. + * @param Buffer + * Pointer to a buffer that contains the data to write. + * @param Offset + * Offset within the file to write to. + * @param Length + * Length of data to write. + * @param WriteToEndOfFile + * When TRUE the file system must write to the current end of file. In this case the Offset + * parameter will contain the value -1. + * @param ConstrainedIo + * When TRUE the file system must not extend the file (i.e. change the file size). + * @param PBytesTransferred [out] + * Pointer to a memory location that will receive the actual number of bytes written. + * @param FileInfo [out] + * Pointer to a structure that will receive the file information on successful return + * from this call. This information includes file attributes, file times, etc. + * @return + * STATUS_SUCCESS or error code. STATUS_PENDING is supported allowing for asynchronous + * operation. + */ + NTSTATUS (*Write)(FSP_FILE_SYSTEM *FileSystem, + PVOID FileContext, PVOID Buffer, UINT64 Offset, ULONG Length, + BOOLEAN WriteToEndOfFile, BOOLEAN ConstrainedIo, + PULONG PBytesTransferred, FSP_FSCTL_FILE_INFO *FileInfo); + /** + * Flush a file or volume. + * + * Note that the FSD will also flush all file/volume caches prior to invoking this operation. + * + * @param FileSystem + * The file system on which this request is posted. + * @param FileContext + * The file context of the file to be flushed. When NULL the whole volume is being flushed. + * @param FileInfo [out] + * Pointer to a structure that will receive the file information on successful return + * from this call. This information includes file attributes, file times, etc. Used when + * flushing file (not volume). + * @return + * STATUS_SUCCESS or error code. + */ + NTSTATUS (*Flush)(FSP_FILE_SYSTEM *FileSystem, + PVOID FileContext, + FSP_FSCTL_FILE_INFO *FileInfo); + /** + * Get file or directory information. + * + * @param FileSystem + * The file system on which this request is posted. + * @param FileContext + * The file context of the file or directory to get information for. + * @param FileInfo [out] + * Pointer to a structure that will receive the file information on successful return + * from this call. This information includes file attributes, file times, etc. + * @return + * STATUS_SUCCESS or error code. + */ + NTSTATUS (*GetFileInfo)(FSP_FILE_SYSTEM *FileSystem, + PVOID FileContext, + FSP_FSCTL_FILE_INFO *FileInfo); + /** + * Set file or directory basic information. + * + * @param FileSystem + * The file system on which this request is posted. + * @param FileContext + * The file context of the file or directory to set information for. + * @param FileAttributes + * File attributes to apply to the file or directory. If the value INVALID_FILE_ATTRIBUTES + * is sent, the file attributes should not be changed. + * @param CreationTime + * Creation time to apply to the file or directory. If the value 0 is sent, the creation + * time should not be changed. + * @param LastAccessTime + * Last access time to apply to the file or directory. If the value 0 is sent, the last + * access time should not be changed. + * @param LastWriteTime + * Last write time to apply to the file or directory. If the value 0 is sent, the last + * write time should not be changed. + * @param ChangeTime + * Change time to apply to the file or directory. If the value 0 is sent, the change time + * should not be changed. + * @param FileInfo [out] + * Pointer to a structure that will receive the file information on successful return + * from this call. This information includes file attributes, file times, etc. + * @return + * STATUS_SUCCESS or error code. + */ + NTSTATUS (*SetBasicInfo)(FSP_FILE_SYSTEM *FileSystem, + PVOID FileContext, UINT32 FileAttributes, + UINT64 CreationTime, UINT64 LastAccessTime, UINT64 LastWriteTime, UINT64 ChangeTime, + FSP_FSCTL_FILE_INFO *FileInfo); + /** + * Set file/allocation size. + * + * This function is used to change a file's sizes. Windows file systems maintain two kinds + * of sizes: the file size is where the End Of File (EOF) is, and the allocation size is the + * actual size that a file takes up on the "disk". + * + * The rules regarding file/allocation size are: + *
    + *
  • Allocation size must always be aligned to the allocation unit boundary. The allocation + * unit is the product (UINT64)SectorSize * (UINT64)SectorsPerAllocationUnit from + * the FSP_FSCTL_VOLUME_PARAMS structure. The FSD will always send properly aligned allocation + * sizes when setting the allocation size.
  • + *
  • Allocation size is always greater or equal to the file size.
  • + *
  • A file size of more than the current allocation size will also extend the allocation + * size to the next allocation unit boundary.
  • + *
  • An allocation size of less than the current file size should also truncate the current + * file size.
  • + *
+ * + * @param FileSystem + * The file system on which this request is posted. + * @param FileContext + * The file context of the file to set the file/allocation size for. + * @param NewSize + * New file/allocation size to apply to the file. + * @param SetAllocationSize + * If TRUE, then the allocation size is being set. if FALSE, then the file size is being set. + * @param FileInfo [out] + * Pointer to a structure that will receive the file information on successful return + * from this call. This information includes file attributes, file times, etc. + * @return + * STATUS_SUCCESS or error code. + */ + NTSTATUS (*SetFileSize)(FSP_FILE_SYSTEM *FileSystem, + PVOID FileContext, UINT64 NewSize, BOOLEAN SetAllocationSize, + FSP_FSCTL_FILE_INFO *FileInfo); + /** + * Determine whether a file or directory can be deleted. + * + * This function tests whether a file or directory can be safely deleted. This function does + * not need to perform access checks, but may performs tasks such as check for empty + * directories, etc. + * + * This function should NEVER delete the file or directory in question. Deletion should + * happen during Cleanup with the FspCleanupDelete flag set. + * + * This function gets called when Win32 API's such as DeleteFile or RemoveDirectory are used. + * It does not get called when a file or directory is opened with FILE_DELETE_ON_CLOSE. + * + * NOTE: If both CanDelete and SetDelete are defined, SetDelete takes precedence. However + * most file systems need only implement the CanDelete operation. + * + * @param FileSystem + * The file system on which this request is posted. + * @param FileContext + * The file context of the file or directory to test for deletion. + * @param FileName + * The name of the file or directory to test for deletion. + * @return + * STATUS_SUCCESS or error code. + * @see + * Cleanup + * SetDelete + */ + NTSTATUS (*CanDelete)(FSP_FILE_SYSTEM *FileSystem, + PVOID FileContext, PWSTR FileName); + /** + * Renames a file or directory. + * + * The kernel mode FSD provides certain guarantees prior to posting a rename operation: + *
    + *
  • A file cannot be renamed if a file with the same name exists and has open handles.
  • + *
  • A directory cannot be renamed if it or any of its subdirectories contains a file that + * has open handles.
  • + *
+ * + * @param FileSystem + * The file system on which this request is posted. + * @param FileContext + * The file context of the file or directory to be renamed. + * @param FileName + * The current name of the file or directory to rename. + * @param NewFileName + * The new name for the file or directory. + * @param ReplaceIfExists + * Whether to replace a file that already exists at NewFileName. + * @return + * STATUS_SUCCESS or error code. + */ + NTSTATUS (*Rename)(FSP_FILE_SYSTEM *FileSystem, + PVOID FileContext, + PWSTR FileName, PWSTR NewFileName, BOOLEAN ReplaceIfExists); + /** + * Get file or directory security descriptor. + * + * @param FileSystem + * The file system on which this request is posted. + * @param FileContext + * The file context of the file or directory to get the security descriptor for. + * @param SecurityDescriptor + * Pointer to a buffer that will receive the file security descriptor on successful return + * from this call. May be NULL. + * @param PSecurityDescriptorSize [in,out] + * Pointer to the security descriptor buffer size. On input it contains the size of the + * security descriptor buffer. On output it will contain the actual size of the security + * descriptor copied into the security descriptor buffer. Cannot be NULL. + * @return + * STATUS_SUCCESS or error code. + */ + NTSTATUS (*GetSecurity)(FSP_FILE_SYSTEM *FileSystem, + PVOID FileContext, + PSECURITY_DESCRIPTOR SecurityDescriptor, SIZE_T *PSecurityDescriptorSize); + /** + * Set file or directory security descriptor. + * + * @param FileSystem + * The file system on which this request is posted. + * @param FileContext + * The file context of the file or directory to set the security descriptor for. + * @param SecurityInformation + * Describes what parts of the file or directory security descriptor should + * be modified. + * @param ModificationDescriptor + * Describes the modifications to apply to the file or directory security descriptor. + * @return + * STATUS_SUCCESS or error code. + * @see + * FspSetSecurityDescriptor + * FspDeleteSecurityDescriptor + */ + NTSTATUS (*SetSecurity)(FSP_FILE_SYSTEM *FileSystem, + PVOID FileContext, + SECURITY_INFORMATION SecurityInformation, PSECURITY_DESCRIPTOR ModificationDescriptor); + /** + * Read a directory. + * + * @param FileSystem + * The file system on which this request is posted. + * @param FileContext + * The file context of the directory to be read. + * @param Pattern + * The pattern to match against files in this directory. Can be NULL. The file system + * can choose to ignore this parameter as the FSD will always perform its own pattern + * matching on the returned results. + * @param Marker + * A file name that marks where in the directory to start reading. Files with names + * that are greater than (not equal to) this marker (in the directory order determined + * by the file system) should be returned. Can be NULL. + * @param Buffer + * Pointer to a buffer that will receive the results of the read operation. + * @param Length + * Length of data to read. + * @param PBytesTransferred [out] + * Pointer to a memory location that will receive the actual number of bytes read. + * @return + * STATUS_SUCCESS or error code. STATUS_PENDING is supported allowing for asynchronous + * operation. + * @see + * FspFileSystemAddDirInfo + */ + NTSTATUS (*ReadDirectory)(FSP_FILE_SYSTEM *FileSystem, + PVOID FileContext, PWSTR Pattern, PWSTR Marker, + PVOID Buffer, ULONG Length, PULONG PBytesTransferred); + /** + * Resolve reparse points. + * + * Reparse points are a general mechanism for attaching special behavior to files. + * A file or directory can contain a reparse point. A reparse point is data that has + * special meaning to the file system, Windows or user applications. For example, NTFS + * and Windows use reparse points to implement symbolic links. As another example, + * a particular file system may use reparse points to emulate UNIX FIFO's. + * + * This function is expected to resolve as many reparse points as possible. If a reparse + * point is encountered that is not understood by the file system further reparse point + * resolution should stop; the reparse point data should be returned to the FSD with status + * STATUS_REPARSE/reparse-tag. If a reparse point (symbolic link) is encountered that is + * understood by the file system but points outside it, the reparse point should be + * resolved, but further reparse point resolution should stop; the resolved file name + * should be returned to the FSD with status STATUS_REPARSE/IO_REPARSE. + * + * @param FileSystem + * The file system on which this request is posted. + * @param FileName + * The name of the file or directory to have its reparse points resolved. + * @param ReparsePointIndex + * The index of the first reparse point within FileName. + * @param ResolveLastPathComponent + * If FALSE, the last path component of FileName should not be resolved, even + * if it is a reparse point that can be resolved. If TRUE, all path components + * should be resolved if possible. + * @param PIoStatus + * Pointer to storage that will receive the status to return to the FSD. When + * this function succeeds it must set PIoStatus->Status to STATUS_REPARSE and + * PIoStatus->Information to either IO_REPARSE or the reparse tag. + * @param Buffer + * Pointer to a buffer that will receive the resolved file name (IO_REPARSE) or + * reparse data (reparse tag). If the function returns a file name, it should + * not be NULL terminated. + * @param PSize [in,out] + * Pointer to the buffer size. On input it contains the size of the buffer. + * On output it will contain the actual size of data copied. + * @return + * STATUS_REPARSE or error code. + */ + NTSTATUS (*ResolveReparsePoints)(FSP_FILE_SYSTEM *FileSystem, + PWSTR FileName, UINT32 ReparsePointIndex, BOOLEAN ResolveLastPathComponent, + PIO_STATUS_BLOCK PIoStatus, PVOID Buffer, PSIZE_T PSize); + /** + * Get reparse point. + * + * @param FileSystem + * The file system on which this request is posted. + * @param FileContext + * The file context of the reparse point. + * @param FileName + * The file name of the reparse point. + * @param Buffer + * Pointer to a buffer that will receive the results of this operation. If + * the function returns a symbolic link path, it should not be NULL terminated. + * @param PSize [in,out] + * Pointer to the buffer size. On input it contains the size of the buffer. + * On output it will contain the actual size of data copied. + * @return + * STATUS_SUCCESS or error code. + * @see + * SetReparsePoint + */ + NTSTATUS (*GetReparsePoint)(FSP_FILE_SYSTEM *FileSystem, + PVOID FileContext, + PWSTR FileName, PVOID Buffer, PSIZE_T PSize); + /** + * Set reparse point. + * + * @param FileSystem + * The file system on which this request is posted. + * @param FileContext + * The file context of the reparse point. + * @param FileName + * The file name of the reparse point. + * @param Buffer + * Pointer to a buffer that contains the data for this operation. If this buffer + * contains a symbolic link path, it should not be assumed to be NULL terminated. + * @param Size + * Size of data to write. + * @return + * STATUS_SUCCESS or error code. + * @see + * GetReparsePoint + */ + NTSTATUS (*SetReparsePoint)(FSP_FILE_SYSTEM *FileSystem, + PVOID FileContext, + PWSTR FileName, PVOID Buffer, SIZE_T Size); + /** + * Delete reparse point. + * + * @param FileSystem + * The file system on which this request is posted. + * @param FileContext + * The file context of the reparse point. + * @param FileName + * The file name of the reparse point. + * @param Buffer + * Pointer to a buffer that contains the data for this operation. + * @param Size + * Size of data to write. + * @return + * STATUS_SUCCESS or error code. + */ + NTSTATUS (*DeleteReparsePoint)(FSP_FILE_SYSTEM *FileSystem, + PVOID FileContext, + PWSTR FileName, PVOID Buffer, SIZE_T Size); + /** + * Get named streams information. + * + * @param FileSystem + * The file system on which this request is posted. + * @param FileContext + * The file context of the file or directory to get stream information for. + * @param Buffer + * Pointer to a buffer that will receive the stream information. + * @param Length + * Length of buffer. + * @param PBytesTransferred [out] + * Pointer to a memory location that will receive the actual number of bytes stored. + * @return + * STATUS_SUCCESS or error code. + * @see + * FspFileSystemAddStreamInfo + */ + NTSTATUS (*GetStreamInfo)(FSP_FILE_SYSTEM *FileSystem, + PVOID FileContext, PVOID Buffer, ULONG Length, + PULONG PBytesTransferred); + /** + * Get directory information for a single file or directory within a parent directory. + * + * @param FileSystem + * The file system on which this request is posted. + * @param FileContext + * The file context of the parent directory. + * @param FileName + * The name of the file or directory to get information for. This name is relative + * to the parent directory and is a single path component. + * @param DirInfo [out] + * Pointer to a structure that will receive the directory information on successful + * return from this call. This information includes the file name, but also file + * attributes, file times, etc. + * @return + * STATUS_SUCCESS or error code. + */ + NTSTATUS (*GetDirInfoByName)(FSP_FILE_SYSTEM *FileSystem, + PVOID FileContext, PWSTR FileName, + FSP_FSCTL_DIR_INFO *DirInfo); + /** + * Process control code. + * + * This function is called when a program uses the DeviceIoControl API. + * + * @param FileSystem + * The file system on which this request is posted. + * @param FileContext + * The file context of the file or directory to be controled. + * @param ControlCode + * The control code for the operation. This code must have a DeviceType with bit + * 0x8000 set and must have a TransferType of METHOD_BUFFERED. + * @param InputBuffer + * Pointer to a buffer that contains the input data. + * @param InputBufferLength + * Input data length. + * @param OutputBuffer + * Pointer to a buffer that will receive the output data. + * @param OutputBufferLength + * Output data length. + * @param PBytesTransferred [out] + * Pointer to a memory location that will receive the actual number of bytes transferred. + * @return + * STATUS_SUCCESS or error code. + */ + NTSTATUS (*Control)(FSP_FILE_SYSTEM *FileSystem, + PVOID FileContext, UINT32 ControlCode, + PVOID InputBuffer, ULONG InputBufferLength, + PVOID OutputBuffer, ULONG OutputBufferLength, PULONG PBytesTransferred); + /** + * Set the file delete flag. + * + * This function sets a flag to indicates whether the FSD file should delete a file + * when it is closed. This function does not need to perform access checks, but may + * performs tasks such as check for empty directories, etc. + * + * This function should NEVER delete the file or directory in question. Deletion should + * happen during Cleanup with the FspCleanupDelete flag set. + * + * This function gets called when Win32 API's such as DeleteFile or RemoveDirectory are used. + * It does not get called when a file or directory is opened with FILE_DELETE_ON_CLOSE. + * + * NOTE: If both CanDelete and SetDelete are defined, SetDelete takes precedence. However + * most file systems need only implement the CanDelete operation. + * + * @param FileSystem + * The file system on which this request is posted. + * @param FileContext + * The file context of the file or directory to set the delete flag for. + * @param FileName + * The name of the file or directory to set the delete flag for. + * @param DeleteFile + * If set to TRUE the FSD indicates that the file will be deleted on Cleanup; otherwise + * it will not be deleted. It is legal to receive multiple SetDelete calls for the same + * file with different DeleteFile parameters. + * @return + * STATUS_SUCCESS or error code. + * @see + * Cleanup + * CanDelete + */ + NTSTATUS (*SetDelete)(FSP_FILE_SYSTEM *FileSystem, + PVOID FileContext, PWSTR FileName, BOOLEAN DeleteFile); + /** + * Create new file or directory. + * + * This function works like Create, except that it also accepts an extra buffer that + * may contain extended attributes or a reparse point. + * + * NOTE: If both Create and CreateEx are defined, CreateEx takes precedence. + * + * @param FileSystem + * The file system on which this request is posted. + * @param FileName + * The name of the file or directory to be created. + * @param CreateOptions + * Create options for this request. This parameter has the same meaning as the + * CreateOptions parameter of the NtCreateFile API. User mode file systems should typically + * only be concerned with the flag FILE_DIRECTORY_FILE, which is an instruction to create a + * directory rather than a file. Some file systems may also want to pay attention to the + * FILE_NO_INTERMEDIATE_BUFFERING and FILE_WRITE_THROUGH flags, although these are + * typically handled by the FSD component. + * @param GrantedAccess + * Determines the specific access rights that have been granted for this request. Upon + * receiving this call all access checks have been performed and the user mode file system + * need not perform any additional checks. However this parameter may be useful to a user + * mode file system; for example the WinFsp-FUSE layer uses this parameter to determine + * which flags to use in its POSIX open() call. + * @param FileAttributes + * File attributes to apply to the newly created file or directory. + * @param SecurityDescriptor + * Security descriptor to apply to the newly created file or directory. This security + * descriptor will always be in self-relative format. Its length can be retrieved using the + * Windows GetSecurityDescriptorLength API. Will be NULL for named streams. + * @param AllocationSize + * Allocation size for the newly created file. + * @param ExtraBuffer + * Extended attributes or reparse point buffer. + * @param ExtraLength + * Extended attributes or reparse point buffer length. + * @param ExtraBufferIsReparsePoint + * FALSE: extra buffer is extended attributes; TRUE: extra buffer is reparse point. + * @param PFileContext [out] + * Pointer that will receive the file context on successful return from this call. + * @param FileInfo [out] + * Pointer to a structure that will receive the file information on successful return + * from this call. This information includes file attributes, file times, etc. + * @return + * STATUS_SUCCESS or error code. + */ + NTSTATUS (*CreateEx)(FSP_FILE_SYSTEM *FileSystem, + PWSTR FileName, UINT32 CreateOptions, UINT32 GrantedAccess, + UINT32 FileAttributes, PSECURITY_DESCRIPTOR SecurityDescriptor, UINT64 AllocationSize, + PVOID ExtraBuffer, ULONG ExtraLength, BOOLEAN ExtraBufferIsReparsePoint, + PVOID *PFileContext, FSP_FSCTL_FILE_INFO *FileInfo); + /** + * Overwrite a file. + * + * This function works like Overwrite, except that it also accepts EA (extended attributes). + * + * NOTE: If both Overwrite and OverwriteEx are defined, OverwriteEx takes precedence. + * + * @param FileSystem + * The file system on which this request is posted. + * @param FileContext + * The file context of the file to overwrite. + * @param FileAttributes + * File attributes to apply to the overwritten file. + * @param ReplaceFileAttributes + * When TRUE the existing file attributes should be replaced with the new ones. + * When FALSE the existing file attributes should be merged (or'ed) with the new ones. + * @param AllocationSize + * Allocation size for the overwritten file. + * @param Ea + * Extended attributes buffer. + * @param EaLength + * Extended attributes buffer length. + * @param FileInfo [out] + * Pointer to a structure that will receive the file information on successful return + * from this call. This information includes file attributes, file times, etc. + * @return + * STATUS_SUCCESS or error code. + */ + NTSTATUS (*OverwriteEx)(FSP_FILE_SYSTEM *FileSystem, + PVOID FileContext, UINT32 FileAttributes, BOOLEAN ReplaceFileAttributes, UINT64 AllocationSize, + PFILE_FULL_EA_INFORMATION Ea, ULONG EaLength, + FSP_FSCTL_FILE_INFO *FileInfo); + /** + * Get extended attributes. + * + * @param FileSystem + * The file system on which this request is posted. + * @param FileContext + * The file context of the file to get extended attributes for. + * @param Ea + * Extended attributes buffer. + * @param EaLength + * Extended attributes buffer length. + * @param PBytesTransferred [out] + * Pointer to a memory location that will receive the actual number of bytes transferred. + * @return + * STATUS_SUCCESS or error code. + * @see + * SetEa + * FspFileSystemAddEa + */ + NTSTATUS (*GetEa)(FSP_FILE_SYSTEM *FileSystem, + PVOID FileContext, + PFILE_FULL_EA_INFORMATION Ea, ULONG EaLength, PULONG PBytesTransferred); + /** + * Set extended attributes. + * + * @param FileSystem + * The file system on which this request is posted. + * @param FileContext + * The file context of the file to set extended attributes for. + * @param Ea + * Extended attributes buffer. + * @param EaLength + * Extended attributes buffer length. + * @param FileInfo [out] + * Pointer to a structure that will receive the file information on successful return + * from this call. This information includes file attributes, file times, etc. + * @return + * STATUS_SUCCESS or error code. + * @see + * GetEa + */ + NTSTATUS (*SetEa)(FSP_FILE_SYSTEM *FileSystem, + PVOID FileContext, + PFILE_FULL_EA_INFORMATION Ea, ULONG EaLength, + FSP_FSCTL_FILE_INFO *FileInfo); + + NTSTATUS (*Obsolete0)(VOID); + + /** + * Inform the file system that its dispatcher has been stopped. + * + * Prior to WinFsp v2.0 the FSD would never unmount a file system volume unless + * the user mode file system requested the unmount. Since WinFsp v2.0 it is possible + * for the FSD to unmount a file system volume without an explicit user mode file system + * request. For example, this happens when the FSD is being uninstalled. + * + * A user mode file system can use this operation to determine when its dispatcher + * has been stopped. The Normally parameter can be used to determine why the dispatcher + * was stopped: it is TRUE when the file system is being stopped via + * FspFileSystemStopDispatcher and FALSE otherwise. + * + * When the file system receives a request with Normally == TRUE it need not take any + * extra steps. This case is the same as for pre-v2.0 versions: since the file system + * stopped the dispatcher via FspFileSystemStopDispatcher, it will likely exit its + * process soon. + * + * When the file system receives a request with Normally == FALSE it may need to take + * extra steps to exit its process as this is not done by default. + * + * A file system that uses the FspService infrastructure may use the + * FspFileSystemStopServiceIfNecessary API to correctly handle all cases. + * + * This operation is the last one that a file system will receive. + * + * @param FileSystem + * The file system on which this request is posted. + * @param Normally + * TRUE if the file system is being stopped via FspFileSystemStopDispatcher. + * FALSE if the file system is being stopped because of another reason such + * as driver unload/uninstall. + * @see + * FspFileSystemStopServiceIfNecessary + */ + VOID (*DispatcherStopped)(FSP_FILE_SYSTEM *FileSystem, + BOOLEAN Normally); + + /* + * This ensures that this interface will always contain 64 function pointers. + * Please update when changing the interface as it is important for future compatibility. + */ + NTSTATUS (*Reserved[31])(); +} FSP_FILE_SYSTEM_INTERFACE; +FSP_FSCTL_STATIC_ASSERT(sizeof(FSP_FILE_SYSTEM_INTERFACE) == 64 * sizeof(NTSTATUS (*)()), + "FSP_FILE_SYSTEM_INTERFACE must have 64 entries."); +typedef struct _FSP_FILE_SYSTEM +{ + UINT16 Version; + PVOID UserContext; + WCHAR VolumeName[FSP_FSCTL_VOLUME_NAME_SIZEMAX / sizeof(WCHAR)]; + HANDLE VolumeHandle; + FSP_FILE_SYSTEM_OPERATION_GUARD *EnterOperation, *LeaveOperation; + FSP_FILE_SYSTEM_OPERATION *Operations[FspFsctlTransactKindCount]; + const FSP_FILE_SYSTEM_INTERFACE *Interface; + HANDLE DispatcherThread; + ULONG DispatcherThreadCount; + NTSTATUS DispatcherResult; + PWSTR MountPoint; + HANDLE MountHandle; + UINT32 DebugLog; + FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY OpGuardStrategy; + SRWLOCK OpGuardLock; + BOOLEAN UmFileContextIsUserContext2, UmFileContextIsFullContext; + UINT16 UmNoReparsePointsDirCheck:1; + UINT16 UmReservedFlags:14; + UINT16 DispatcherStopping:1; +} FSP_FILE_SYSTEM; +FSP_FSCTL_STATIC_ASSERT( + (4 == sizeof(PVOID) && 660 == sizeof(FSP_FILE_SYSTEM)) || + (8 == sizeof(PVOID) && 792 == sizeof(FSP_FILE_SYSTEM)), + "sizeof(FSP_FILE_SYSTEM) must be exactly 660 in 32-bit and 792 in 64-bit."); +typedef struct _FSP_FILE_SYSTEM_OPERATION_CONTEXT +{ + FSP_FSCTL_TRANSACT_REQ *Request; + FSP_FSCTL_TRANSACT_RSP *Response; +} FSP_FILE_SYSTEM_OPERATION_CONTEXT; +/** + * Check whether creating a file system object is possible. + * + * @param DevicePath + * The name of the control device for this file system. This must be either + * FSP_FSCTL_DISK_DEVICE_NAME or FSP_FSCTL_NET_DEVICE_NAME. + * @param MountPoint + * The mount point for the new file system. A value of NULL means that the file system should + * use the next available drive letter counting downwards from Z: as its mount point. + * @return + * STATUS_SUCCESS or error code. + */ +FSP_API NTSTATUS FspFileSystemPreflight(PWSTR DevicePath, + PWSTR MountPoint); +/** + * Create a file system object. + * + * @param DevicePath + * The name of the control device for this file system. This must be either + * FSP_FSCTL_DISK_DEVICE_NAME or FSP_FSCTL_NET_DEVICE_NAME. + * @param VolumeParams + * Volume parameters for the newly created file system. + * @param Interface + * A pointer to the operations that implement this user mode file system. + * @param PFileSystem [out] + * Pointer that will receive the file system object created on successful return from this + * call. + * @return + * STATUS_SUCCESS or error code. + */ +FSP_API NTSTATUS FspFileSystemCreate(PWSTR DevicePath, + const FSP_FSCTL_VOLUME_PARAMS *VolumeParams, + const FSP_FILE_SYSTEM_INTERFACE *Interface, + FSP_FILE_SYSTEM **PFileSystem); +/** + * Delete a file system object. + * + * @param FileSystem + * The file system object. + */ +FSP_API VOID FspFileSystemDelete(FSP_FILE_SYSTEM *FileSystem); +/** + * Set the mount point for a file system. + * + * This function supports drive letters (X:) or directories as mount points: + *
    + *
  • Drive letters: Refer to the documentation of the DefineDosDevice Windows API + * to better understand how they are created.
  • + *
  • Directories: They can be used as mount points for disk based file systems. They cannot + * be used for network file systems. This is a limitation that Windows imposes on junctions.
  • + *
+ * + * @param FileSystem + * The file system object. + * @param MountPoint + * The mount point for the new file system. A value of NULL means that the file system should + * use the next available drive letter counting downwards from Z: as its mount point. + * @return + * STATUS_SUCCESS or error code. + */ +FSP_API NTSTATUS FspFileSystemSetMountPoint(FSP_FILE_SYSTEM *FileSystem, PWSTR MountPoint); +FSP_API NTSTATUS FspFileSystemSetMountPointEx(FSP_FILE_SYSTEM *FileSystem, PWSTR MountPoint, + PSECURITY_DESCRIPTOR SecurityDescriptor); +/** + * Remove the mount point for a file system. + * + * @param FileSystem + * The file system object. + */ +FSP_API VOID FspFileSystemRemoveMountPoint(FSP_FILE_SYSTEM *FileSystem); +/** + * Start the file system dispatcher. + * + * The file system dispatcher is used to dispatch operations posted by the FSD to the user mode + * file system. Once this call starts executing the user mode file system will start receiving + * file system requests from the kernel. + * + * @param FileSystem + * The file system object. + * @param ThreadCount + * The number of threads for the file system dispatcher. A value of 0 will create a default + * number of threads and should be chosen in most cases. + * @return + * STATUS_SUCCESS or error code. + */ +FSP_API NTSTATUS FspFileSystemStartDispatcher(FSP_FILE_SYSTEM *FileSystem, ULONG ThreadCount); +/** + * Stop the file system dispatcher. + * + * @param FileSystem + * The file system object. + */ +FSP_API VOID FspFileSystemStopDispatcher(FSP_FILE_SYSTEM *FileSystem); +/** + * Send a response to the FSD. + * + * This call is not required when the user mode file system performs synchronous processing of + * requests. It is possible however for the following FSP_FILE_SYSTEM_INTERFACE operations to be + * processed asynchronously: + *
    + *
  • Read
  • + *
  • Write
  • + *
  • ReadDirectory
  • + *
+ * + * These operations are allowed to return STATUS_PENDING to postpone sending a response to the FSD. + * At a later time the file system can use FspFileSystemSendResponse to send the response. + * + * @param FileSystem + * The file system object. + * @param Response + * The response buffer. + */ +FSP_API VOID FspFileSystemSendResponse(FSP_FILE_SYSTEM *FileSystem, + FSP_FSCTL_TRANSACT_RSP *Response); +/** + * Begin notifying Windows that the file system has file changes. + * + * A file system that wishes to notify Windows about file changes must + * first issue an FspFileSystemBegin call, followed by 0 or more + * FspFileSystemNotify calls, followed by an FspFileSystemNotifyEnd call. + * + * This operation blocks concurrent file rename operations. File rename + * operations may interfere with file notification, because a file being + * notified may also be concurrently renamed. After all file change + * notifications have been issued, you must make sure to call + * FspFileSystemNotifyEnd to allow file rename operations to proceed. + * + * @param FileSystem + * The file system object. + * @return + * STATUS_SUCCESS or error code. The error code STATUS_CANT_WAIT means that + * a file rename operation is currently in progress and the operation must be + * retried at a later time. + */ +FSP_API NTSTATUS FspFileSystemNotifyBegin(FSP_FILE_SYSTEM *FileSystem, ULONG Timeout); +/** + * End notifying Windows that the file system has file changes. + * + * A file system that wishes to notify Windows about file changes must + * first issue an FspFileSystemBegin call, followed by 0 or more + * FspFileSystemNotify calls, followed by an FspFileSystemNotifyEnd call. + * + * This operation allows any blocked file rename operations to proceed. + * + * @param FileSystem + * The file system object. + * @return + * STATUS_SUCCESS or error code. + */ +FSP_API NTSTATUS FspFileSystemNotifyEnd(FSP_FILE_SYSTEM *FileSystem); +/** + * Notify Windows that the file system has file changes. + * + * A file system that wishes to notify Windows about file changes must + * first issue an FspFileSystemBegin call, followed by 0 or more + * FspFileSystemNotify calls, followed by an FspFileSystemNotifyEnd call. + * + * Note that FspFileSystemNotify requires file names to be normalized. A + * normalized file name is one that contains the correct case of all characters + * in the file name. + * + * For case-sensitive file systems all file names are normalized by definition. + * For case-insensitive file systems that implement file name normalization, + * a normalized file name is the one that the file system specifies in the + * response to Create or Open (see also FspFileSystemGetOpenFileInfo). For + * case-insensitive file systems that do not implement file name normalization + * a normalized file name is the upper case version of the file name used + * to open the file. + * + * @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. + * + * This function may be used only when servicing one of the FSP_FILE_SYSTEM_INTERFACE operations. + * The current operation context is stored in thread local storage. It allows access to the + * Request and Response associated with this operation. + * + * @return + * The current operation context. + */ +FSP_API FSP_FILE_SYSTEM_OPERATION_CONTEXT *FspFileSystemGetOperationContext(VOID); +static inline +PWSTR FspFileSystemMountPoint(FSP_FILE_SYSTEM *FileSystem) +{ + return FileSystem->MountPoint; +} +FSP_API PWSTR FspFileSystemMountPointF(FSP_FILE_SYSTEM *FileSystem); +static inline +NTSTATUS FspFileSystemEnterOperation(FSP_FILE_SYSTEM *FileSystem, + FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response) +{ + if (0 == FileSystem->EnterOperation) + return STATUS_SUCCESS; + + return FileSystem->EnterOperation(FileSystem, Request, Response); +} +FSP_API NTSTATUS FspFileSystemEnterOperationF(FSP_FILE_SYSTEM *FileSystem, + FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response); +static inline +NTSTATUS FspFileSystemLeaveOperation(FSP_FILE_SYSTEM *FileSystem, + FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response) +{ + if (0 == FileSystem->LeaveOperation) + return STATUS_SUCCESS; + + return FileSystem->LeaveOperation(FileSystem, Request, Response); +} +FSP_API NTSTATUS FspFileSystemLeaveOperationF(FSP_FILE_SYSTEM *FileSystem, + FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response); +static inline +VOID FspFileSystemSetOperationGuard(FSP_FILE_SYSTEM *FileSystem, + FSP_FILE_SYSTEM_OPERATION_GUARD *EnterOperation, + FSP_FILE_SYSTEM_OPERATION_GUARD *LeaveOperation) +{ + FileSystem->EnterOperation = EnterOperation; + FileSystem->LeaveOperation = LeaveOperation; +} +FSP_API VOID FspFileSystemSetOperationGuardF(FSP_FILE_SYSTEM *FileSystem, + FSP_FILE_SYSTEM_OPERATION_GUARD *EnterOperation, + FSP_FILE_SYSTEM_OPERATION_GUARD *LeaveOperation); +/** + * Set file system locking strategy. + * + * @param FileSystem + * The file system object. + * @param GuardStrategy + * The locking (guard) strategy. + * @see + * FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY + */ +static inline +VOID FspFileSystemSetOperationGuardStrategy(FSP_FILE_SYSTEM *FileSystem, + FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY GuardStrategy) +{ + FileSystem->OpGuardStrategy = GuardStrategy; +} +FSP_API VOID FspFileSystemSetOperationGuardStrategyF(FSP_FILE_SYSTEM *FileSystem, + FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY GuardStrategy); +static inline +VOID FspFileSystemSetOperation(FSP_FILE_SYSTEM *FileSystem, + ULONG Index, + FSP_FILE_SYSTEM_OPERATION *Operation) +{ + FileSystem->Operations[Index] = Operation; +} +FSP_API VOID FspFileSystemSetOperationF(FSP_FILE_SYSTEM *FileSystem, + ULONG Index, + FSP_FILE_SYSTEM_OPERATION *Operation); +static inline +VOID FspFileSystemGetDispatcherResult(FSP_FILE_SYSTEM *FileSystem, + NTSTATUS *PDispatcherResult) +{ + *PDispatcherResult = FspInterlockedLoad32((INT32 *)&FileSystem->DispatcherResult); +} +FSP_API VOID FspFileSystemGetDispatcherResultF(FSP_FILE_SYSTEM *FileSystem, + NTSTATUS *PDispatcherResult); +static inline +VOID FspFileSystemSetDispatcherResult(FSP_FILE_SYSTEM *FileSystem, + NTSTATUS DispatcherResult) +{ + if (NT_SUCCESS(DispatcherResult)) + return; + InterlockedCompareExchange(&FileSystem->DispatcherResult, DispatcherResult, 0); +} +FSP_API VOID FspFileSystemSetDispatcherResultF(FSP_FILE_SYSTEM *FileSystem, + NTSTATUS DispatcherResult); +static inline +VOID FspFileSystemSetDebugLog(FSP_FILE_SYSTEM *FileSystem, + UINT32 DebugLog) +{ + FileSystem->DebugLog = DebugLog; +} +FSP_API VOID FspFileSystemSetDebugLogF(FSP_FILE_SYSTEM *FileSystem, + UINT32 DebugLog); +static inline +BOOLEAN FspFileSystemIsOperationCaseSensitive(VOID) +{ + FSP_FSCTL_TRANSACT_REQ *Request = FspFileSystemGetOperationContext()->Request; + return + FspFsctlTransactCreateKind == Request->Kind && Request->Req.Create.CaseSensitive || + FspFsctlTransactQueryDirectoryKind == Request->Kind && Request->Req.QueryDirectory.CaseSensitive; +} +FSP_API BOOLEAN FspFileSystemIsOperationCaseSensitiveF(VOID); +/** + * Gets the originating process ID. + * + * Valid only during Create, Open and Rename requests when the target exists. + */ +static inline +UINT32 FspFileSystemOperationProcessId(VOID) +{ + FSP_FSCTL_TRANSACT_REQ *Request = FspFileSystemGetOperationContext()->Request; + switch (Request->Kind) + { + case FspFsctlTransactCreateKind: + return FSP_FSCTL_TRANSACT_REQ_TOKEN_PID(Request->Req.Create.AccessToken); + case FspFsctlTransactSetInformationKind: + if (10/*FileRenameInformation*/ == Request->Req.SetInformation.FileInformationClass || + 65/*FileRenameInformationEx*/ == Request->Req.SetInformation.FileInformationClass) + return FSP_FSCTL_TRANSACT_REQ_TOKEN_PID(Request->Req.SetInformation.Info.Rename.AccessToken); + /* fall through! */ + default: + return 0; + } +} +FSP_API UINT32 FspFileSystemOperationProcessIdF(VOID); + +/* + * Operations + */ +FSP_API NTSTATUS FspFileSystemOpEnter(FSP_FILE_SYSTEM *FileSystem, + FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response); +FSP_API NTSTATUS FspFileSystemOpLeave(FSP_FILE_SYSTEM *FileSystem, + FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response); +FSP_API NTSTATUS FspFileSystemOpCreate(FSP_FILE_SYSTEM *FileSystem, + FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response); +FSP_API NTSTATUS FspFileSystemOpOverwrite(FSP_FILE_SYSTEM *FileSystem, + FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response); +FSP_API NTSTATUS FspFileSystemOpCleanup(FSP_FILE_SYSTEM *FileSystem, + FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response); +FSP_API NTSTATUS FspFileSystemOpClose(FSP_FILE_SYSTEM *FileSystem, + FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response); +FSP_API NTSTATUS FspFileSystemOpRead(FSP_FILE_SYSTEM *FileSystem, + FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response); +FSP_API NTSTATUS FspFileSystemOpWrite(FSP_FILE_SYSTEM *FileSystem, + FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response); +FSP_API NTSTATUS FspFileSystemOpQueryInformation(FSP_FILE_SYSTEM *FileSystem, + FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response); +FSP_API NTSTATUS FspFileSystemOpSetInformation(FSP_FILE_SYSTEM *FileSystem, + FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response); +FSP_API NTSTATUS FspFileSystemOpQueryEa(FSP_FILE_SYSTEM *FileSystem, + FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response); +FSP_API NTSTATUS FspFileSystemOpSetEa(FSP_FILE_SYSTEM *FileSystem, + FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response); +FSP_API NTSTATUS FspFileSystemOpFlushBuffers(FSP_FILE_SYSTEM *FileSystem, + FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response); +FSP_API NTSTATUS FspFileSystemOpQueryVolumeInformation(FSP_FILE_SYSTEM *FileSystem, + FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response); +FSP_API NTSTATUS FspFileSystemOpSetVolumeInformation(FSP_FILE_SYSTEM *FileSystem, + FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response); +FSP_API NTSTATUS FspFileSystemOpQueryDirectory(FSP_FILE_SYSTEM *FileSystem, + FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response); +FSP_API NTSTATUS FspFileSystemOpFileSystemControl(FSP_FILE_SYSTEM *FileSystem, + FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response); +FSP_API NTSTATUS FspFileSystemOpDeviceControl(FSP_FILE_SYSTEM *FileSystem, + FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response); +FSP_API NTSTATUS FspFileSystemOpQuerySecurity(FSP_FILE_SYSTEM *FileSystem, + FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response); +FSP_API NTSTATUS FspFileSystemOpSetSecurity(FSP_FILE_SYSTEM *FileSystem, + FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response); +FSP_API NTSTATUS FspFileSystemOpQueryStreamInformation(FSP_FILE_SYSTEM *FileSystem, + FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response); + +/* + * Helpers + */ +/** + * Get open information buffer. + * + * This is a helper for implementing the Create and Open operations. It cannot be used with + * any other operations. + * + * The FileInfo parameter to Create and Open is typed as pointer to FSP_FSCTL_FILE_INFO. The + * true type of this parameter is pointer to FSP_FSCTL_OPEN_FILE_INFO. This simple function + * converts from one type to the other. + * + * The FSP_FSCTL_OPEN_FILE_INFO type contains a FSP_FSCTL_FILE_INFO as well as the fields + * NormalizedName and NormalizedNameSize. These fields can be used for file name normalization. + * File name normalization is used to ensure that the FSD and the OS know the correct case + * of a newly opened file name. + * + * For case-sensitive file systems this functionality should be ignored. The FSD will always + * assume that the normalized file name is the same as the file name used to open the file. + * + * For case-insensitive file systems this functionality may be ignored. In this case the FSD + * will assume that the normalized file name is the upper case version of the file name used + * to open the file. The file system will work correctly and the only way an application will + * be able to tell that the file system does not preserve case in normalized file names is by + * issuing a GetFinalPathNameByHandle API call (or NtQueryInformationFile with + * FileNameInformation/FileNormalizedNameInformation). + * + * For case-insensitive file systems this functionality may also be used. In this case the + * user mode file system may use the NormalizedName and NormalizedNameSize parameters to + * report to the FSD the normalized file name. It should be noted that the normalized file + * name may only differ in case from the file name used to open the file. The NormalizedName + * field will point to a buffer that can receive the normalized file name. The + * NormalizedNameSize field will contain the size of the normalized file name buffer. On + * completion of the Create or Open operation it should contain the actual size of the + * normalized file name copied into the normalized file name buffer. The normalized file name + * should not contain a terminating zero. + * + * @param FileInfo + * The FileInfo parameter as passed to Create or Open operation. + * @return + * A pointer to the open information buffer for this Create or Open operation. + * @see + * Create + * Open + */ +static inline +FSP_FSCTL_OPEN_FILE_INFO *FspFileSystemGetOpenFileInfo(FSP_FSCTL_FILE_INFO *FileInfo) +{ + return (FSP_FSCTL_OPEN_FILE_INFO *)FileInfo; +} +/** + * Add directory information to a buffer. + * + * This is a helper for implementing the ReadDirectory operation. + * + * @param DirInfo + * The directory information to add. A value of NULL acts as an EOF marker for a ReadDirectory + * operation. + * @param Buffer + * Pointer to a buffer that will receive the results of the read operation. This should contain + * the same value passed to the ReadDirectory Buffer parameter. + * @param Length + * Length of data to read. This should contain the same value passed to the ReadDirectory + * Length parameter. + * @param PBytesTransferred [out] + * Pointer to a memory location that will receive the actual number of bytes read. This should + * contain the same value passed to the ReadDirectory PBytesTransferred parameter. + * FspFileSystemAddDirInfo uses the value pointed by this parameter to track how much of the + * buffer has been used so far. + * @return + * TRUE if the directory information was added, FALSE if there was not enough space to add it. + * @see + * ReadDirectory + */ +FSP_API BOOLEAN FspFileSystemAddDirInfo(FSP_FSCTL_DIR_INFO *DirInfo, + PVOID Buffer, ULONG Length, PULONG PBytesTransferred); +/** + * Find reparse point in file name. + * + * Given a file name this function returns an index to the first path component that is a reparse + * point. The function will call the supplied GetReparsePointByName function for every path + * component until it finds a reparse point or the whole path is processed. + * + * This is a helper for implementing the GetSecurityByName operation in file systems + * that support reparse points. + * + * @param FileSystem + * The file system object. + * @param GetReparsePointByName + * Pointer to function that can retrieve reparse point information by name. The + * FspFileSystemFindReparsePoint will call this function with the Buffer and PSize + * arguments set to NULL. The function should return STATUS_SUCCESS if the passed + * FileName is a reparse point or STATUS_NOT_A_REPARSE_POINT (or other error code) + * otherwise. + * @param Context + * User context to supply to GetReparsePointByName. + * @param FileName + * The name of the file or directory. + * @param PReparsePointIndex + * Pointer to a memory location that will receive the index of the first reparse point + * within FileName. A value is only placed in this memory location if the function returns + * TRUE. May be NULL. + * @return + * TRUE if a reparse point was found, FALSE otherwise. + * @see + * GetSecurityByName + */ +FSP_API BOOLEAN FspFileSystemFindReparsePoint(FSP_FILE_SYSTEM *FileSystem, + NTSTATUS (*GetReparsePointByName)( + FSP_FILE_SYSTEM *FileSystem, PVOID Context, + PWSTR FileName, BOOLEAN IsDirectory, PVOID Buffer, PSIZE_T PSize), + PVOID Context, + PWSTR FileName, PUINT32 PReparsePointIndex); +/** + * Resolve reparse points. + * + * Given a file name (and an index where to start resolving) this function will attempt to + * resolve as many reparse points as possible. The function will call the supplied + * GetReparsePointByName function for every path component until it resolves the reparse points + * or the whole path is processed. + * + * This is a helper for implementing the ResolveReparsePoints operation in file systems + * that support reparse points. + * + * @param FileSystem + * The file system object. + * @param GetReparsePointByName + * Pointer to function that can retrieve reparse point information by name. The function + * should return STATUS_SUCCESS if the passed FileName is a reparse point or + * STATUS_NOT_A_REPARSE_POINT (or other error code) otherwise. + * @param Context + * User context to supply to GetReparsePointByName. + * @param FileName + * The name of the file or directory to have its reparse points resolved. + * @param ReparsePointIndex + * The index of the first reparse point within FileName. + * @param ResolveLastPathComponent + * If FALSE, the last path component of FileName should not be resolved, even + * if it is a reparse point that can be resolved. If TRUE, all path components + * should be resolved if possible. + * @param PIoStatus + * Pointer to storage that will receive the status to return to the FSD. When + * this function succeeds it must set PIoStatus->Status to STATUS_REPARSE and + * PIoStatus->Information to either IO_REPARSE or the reparse tag. + * @param Buffer + * Pointer to a buffer that will receive the resolved file name (IO_REPARSE) or + * reparse data (reparse tag). If the function returns a file name, it should + * not be NULL terminated. + * @param PSize [in,out] + * Pointer to the buffer size. On input it contains the size of the buffer. + * On output it will contain the actual size of data copied. + * @return + * STATUS_REPARSE or error code. + * @see + * ResolveReparsePoints + */ +FSP_API NTSTATUS FspFileSystemResolveReparsePoints(FSP_FILE_SYSTEM *FileSystem, + NTSTATUS (*GetReparsePointByName)( + FSP_FILE_SYSTEM *FileSystem, PVOID Context, + PWSTR FileName, BOOLEAN IsDirectory, PVOID Buffer, PSIZE_T PSize), + PVOID Context, + PWSTR FileName, UINT32 ReparsePointIndex, BOOLEAN ResolveLastPathComponent, + PIO_STATUS_BLOCK PIoStatus, PVOID Buffer, PSIZE_T PSize); +/** + * Test whether reparse data can be replaced. + * + * This is a helper for implementing the SetReparsePoint/DeleteReparsePoint operation + * in file systems that support reparse points. + * + * @param CurrentReparseData + * Pointer to the current reparse data. + * @param CurrentReparseDataSize + * Pointer to the current reparse data size. + * @param ReplaceReparseData + * Pointer to the replacement reparse data. + * @param ReplaceReparseDataSize + * Pointer to the replacement reparse data size. + * @return + * STATUS_SUCCESS or error code. + * @see + * SetReparsePoint + * DeleteReparsePoint + */ +FSP_API NTSTATUS FspFileSystemCanReplaceReparsePoint( + PVOID CurrentReparseData, SIZE_T CurrentReparseDataSize, + PVOID ReplaceReparseData, SIZE_T ReplaceReparseDataSize); +/** + * Add named stream information to a buffer. + * + * This is a helper for implementing the GetStreamInfo operation. + * + * @param StreamInfo + * The stream information to add. A value of NULL acts as an EOF marker for a GetStreamInfo + * operation. + * @param Buffer + * Pointer to a buffer that will receive the stream information. This should contain + * the same value passed to the GetStreamInfo Buffer parameter. + * @param Length + * Length of buffer. This should contain the same value passed to the GetStreamInfo + * Length parameter. + * @param PBytesTransferred [out] + * Pointer to a memory location that will receive the actual number of bytes stored. This should + * contain the same value passed to the GetStreamInfo PBytesTransferred parameter. + * @return + * TRUE if the stream information was added, FALSE if there was not enough space to add it. + * @see + * GetStreamInfo + */ +FSP_API BOOLEAN FspFileSystemAddStreamInfo(FSP_FSCTL_STREAM_INFO *StreamInfo, + PVOID Buffer, ULONG Length, PULONG PBytesTransferred); +/** + * Enumerate extended attributes in a buffer. + * + * This is a helper for implementing the CreateEx and SetEa operations in file systems + * that support extended attributes. + * + * @param FileSystem + * The file system object. + * @param EnumerateEa + * Pointer to function that receives a single extended attribute. The function + * should return STATUS_SUCCESS or an error code if unsuccessful. + * @param Context + * User context to supply to EnumEa. + * @param Ea + * Extended attributes buffer. + * @param EaLength + * Extended attributes buffer length. + * @return + * STATUS_SUCCESS or error code from EnumerateEa. + */ +FSP_API NTSTATUS FspFileSystemEnumerateEa(FSP_FILE_SYSTEM *FileSystem, + NTSTATUS (*EnumerateEa)( + FSP_FILE_SYSTEM *FileSystem, PVOID Context, + PFILE_FULL_EA_INFORMATION SingleEa), + PVOID Context, + PFILE_FULL_EA_INFORMATION Ea, ULONG EaLength); +/** + * Add extended attribute to a buffer. + * + * This is a helper for implementing the GetEa operation. + * + * @param SingleEa + * The extended attribute to add. A value of NULL acts as an EOF marker for a GetEa + * operation. + * @param Ea + * Pointer to a buffer that will receive the extended attribute. This should contain + * the same value passed to the GetEa Ea parameter. + * @param EaLength + * Length of buffer. This should contain the same value passed to the GetEa + * EaLength parameter. + * @param PBytesTransferred [out] + * Pointer to a memory location that will receive the actual number of bytes stored. This should + * contain the same value passed to the GetEa PBytesTransferred parameter. + * @return + * TRUE if the extended attribute was added, FALSE if there was not enough space to add it. + * @see + * GetEa + */ +FSP_API BOOLEAN FspFileSystemAddEa(PFILE_FULL_EA_INFORMATION SingleEa, + PFILE_FULL_EA_INFORMATION Ea, ULONG EaLength, PULONG PBytesTransferred); +/** + * Get extended attribute "packed" size. This computation matches what NTFS reports. + * + * @param SingleEa + * The extended attribute to get the size for. + * @return + * The packed size of the extended attribute. + */ +static inline +UINT32 FspFileSystemGetEaPackedSize(PFILE_FULL_EA_INFORMATION SingleEa) +{ + /* magic computations are courtesy of NTFS */ + return 5 + SingleEa->EaNameLength + SingleEa->EaValueLength; +} +/** + * Add notify information to a buffer. + * + * This is a helper for filling a buffer to use with FspFileSystemNotify. + * + * @param NotifyInfo + * The notify information to add. + * @param Buffer + * Pointer to a buffer that will receive the notify information. + * @param Length + * Length of buffer. + * @param PBytesTransferred [out] + * Pointer to a memory location that will receive the actual number of bytes stored. This should + * be initialized to 0 prior to the first call to FspFileSystemAddNotifyInfo for a particular + * buffer. + * @return + * TRUE if the notify information was added, FALSE if there was not enough space to add it. + * @see + * FspFileSystemNotify + */ +FSP_API BOOLEAN FspFileSystemAddNotifyInfo(FSP_FSCTL_NOTIFY_INFO *NotifyInfo, + PVOID Buffer, ULONG Length, PULONG PBytesTransferred); +/** + * Stop a file system service, if any. + * + * This is a helper for implementing the DispatcherStopped operation, but only for file systems + * that use the FspService infrastructure. + * + * @param FileSystem + * The file system object. + * @param Normally + * TRUE if the file system is being stopped via FspFileSystemStopDispatcher. + * FALSE if the file system is being stopped because of another reason such + * as driver unload/uninstall. + * @see + * DispatcherStopped + */ +FSP_API VOID FspFileSystemStopServiceIfNecessary(FSP_FILE_SYSTEM *FileSystem, + BOOLEAN Normally); + +/* + * Directory buffering + */ +FSP_API BOOLEAN FspFileSystemAcquireDirectoryBufferEx(PVOID* PDirBuffer, + BOOLEAN Reset, ULONG CapacityHint, PNTSTATUS PResult); +FSP_API BOOLEAN FspFileSystemAcquireDirectoryBuffer(PVOID *PDirBuffer, + BOOLEAN Reset, PNTSTATUS PResult); +FSP_API BOOLEAN FspFileSystemFillDirectoryBuffer(PVOID *PDirBuffer, + FSP_FSCTL_DIR_INFO *DirInfo, PNTSTATUS PResult); +FSP_API VOID FspFileSystemReleaseDirectoryBuffer(PVOID *PDirBuffer); +FSP_API VOID FspFileSystemReadDirectoryBuffer(PVOID *PDirBuffer, + PWSTR Marker, + PVOID Buffer, ULONG Length, PULONG PBytesTransferred); +FSP_API VOID FspFileSystemDeleteDirectoryBuffer(PVOID *PDirBuffer); + +/* + * Security + */ +FSP_API PGENERIC_MAPPING FspGetFileGenericMapping(VOID); +FSP_API NTSTATUS FspAccessCheckEx(FSP_FILE_SYSTEM *FileSystem, + FSP_FSCTL_TRANSACT_REQ *Request, + BOOLEAN CheckParentOrMain, BOOLEAN AllowTraverseCheck, + UINT32 DesiredAccess, PUINT32 PGrantedAccess/* or ReparsePointIndex */, + PSECURITY_DESCRIPTOR *PSecurityDescriptor); +FSP_API NTSTATUS FspCreateSecurityDescriptor(FSP_FILE_SYSTEM *FileSystem, + FSP_FSCTL_TRANSACT_REQ *Request, + PSECURITY_DESCRIPTOR ParentDescriptor, + PSECURITY_DESCRIPTOR *PSecurityDescriptor); +/** + * Modify security descriptor. + * + * This is a helper for implementing the SetSecurity operation. + * + * @param InputDescriptor + * The input security descriptor to be modified. + * @param SecurityInformation + * Describes what parts of the InputDescriptor should be modified. This should contain + * the same value passed to the SetSecurity SecurityInformation parameter. + * @param ModificationDescriptor + * Describes the modifications to apply to the InputDescriptor. This should contain + * the same value passed to the SetSecurity ModificationDescriptor parameter. + * @param PSecurityDescriptor [out] + * Pointer to a memory location that will receive the resulting security descriptor. + * This security descriptor can be later freed using FspDeleteSecurityDescriptor. + * @return + * STATUS_SUCCESS or error code. + * @see + * SetSecurity + * FspDeleteSecurityDescriptor + */ +FSP_API NTSTATUS FspSetSecurityDescriptor( + PSECURITY_DESCRIPTOR InputDescriptor, + SECURITY_INFORMATION SecurityInformation, + PSECURITY_DESCRIPTOR ModificationDescriptor, + PSECURITY_DESCRIPTOR *PSecurityDescriptor); +/** + * Delete security descriptor. + * + * This is a helper for implementing the SetSecurity operation. + * + * @param SecurityDescriptor + * The security descriptor to be deleted. + * @param CreateFunc + * Function used to create the security descriptor. This parameter should be + * set to FspSetSecurityDescriptor for the public API. + * @return + * STATUS_SUCCESS or error code. + * @see + * SetSecurity + * FspSetSecurityDescriptor + */ +FSP_API VOID FspDeleteSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor, + NTSTATUS (*CreateFunc)()); +static inline +NTSTATUS FspAccessCheck(FSP_FILE_SYSTEM *FileSystem, + FSP_FSCTL_TRANSACT_REQ *Request, + BOOLEAN CheckParentOrMain, BOOLEAN AllowTraverseCheck, + UINT32 DesiredAccess, PUINT32 PGrantedAccess) +{ + return FspAccessCheckEx(FileSystem, Request, + CheckParentOrMain, AllowTraverseCheck, + DesiredAccess, PGrantedAccess, + 0); +} + +/* + * POSIX Interop + */ +FSP_API NTSTATUS FspPosixSetUidMap(UINT32 Uid[], PSID Sid[], ULONG Count); +FSP_API NTSTATUS FspPosixMapUidToSid(UINT32 Uid, PSID *PSid); +FSP_API NTSTATUS FspPosixMapSidToUid(PSID Sid, PUINT32 PUid); +FSP_API VOID FspDeleteSid(PSID Sid, NTSTATUS (*CreateFunc)()); +FSP_API NTSTATUS FspPosixMapPermissionsToSecurityDescriptor( + UINT32 Uid, UINT32 Gid, UINT32 Mode, + PSECURITY_DESCRIPTOR *PSecurityDescriptor); +FSP_API NTSTATUS FspPosixMergePermissionsToSecurityDescriptor( + UINT32 Uid, UINT32 Gid, UINT32 Mode, + PSECURITY_DESCRIPTOR ExistingSecurityDescriptor, + PSECURITY_DESCRIPTOR *PSecurityDescriptor); +FSP_API NTSTATUS FspPosixMapSecurityDescriptorToPermissions( + PSECURITY_DESCRIPTOR SecurityDescriptor, + PUINT32 PUid, PUINT32 PGid, PUINT32 PMode); +FSP_API NTSTATUS FspPosixMapWindowsToPosixPathEx(PWSTR WindowsPath, char **PPosixPath, + BOOLEAN Translate); +FSP_API NTSTATUS FspPosixMapPosixToWindowsPathEx(const char *PosixPath, PWSTR *PWindowsPath, + BOOLEAN Translate); +static inline +NTSTATUS FspPosixMapWindowsToPosixPath(PWSTR WindowsPath, char **PPosixPath) +{ + return FspPosixMapWindowsToPosixPathEx(WindowsPath, PPosixPath, TRUE); +} +static inline +NTSTATUS FspPosixMapPosixToWindowsPath(const char *PosixPath, PWSTR *PWindowsPath) +{ + return FspPosixMapPosixToWindowsPathEx(PosixPath, PWindowsPath, TRUE); +} +FSP_API VOID FspPosixDeletePath(void *Path); +FSP_API VOID FspPosixEncodeWindowsPath(PWSTR WindowsPath, ULONG Size); +FSP_API VOID FspPosixDecodeWindowsPath(PWSTR WindowsPath, ULONG Size); +static inline +VOID FspPosixFileTimeToUnixTime(UINT64 FileTime0, __int3264 UnixTime[2]) +{ + INT64 FileTime = (INT64)FileTime0 - 116444736000000000LL; + UnixTime[0] = (__int3264)(FileTime / 10000000); + UnixTime[1] = (__int3264)(FileTime % 10000000 * 100); + /* may produce negative nsec for times before UNIX epoch; strictly speaking this is incorrect */ +} +static inline +VOID FspPosixUnixTimeToFileTime(const __int3264 UnixTime[2], PUINT64 PFileTime) +{ + INT64 FileTime = (INT64)UnixTime[0] * 10000000 + (INT64)UnixTime[1] / 100 + + 116444736000000000LL; + *PFileTime = FileTime; +} + +/* + * Path Handling + */ +FSP_API VOID FspPathPrefix(PWSTR Path, PWSTR *PPrefix, PWSTR *PRemain, PWSTR Root); +FSP_API VOID FspPathSuffix(PWSTR Path, PWSTR *PRemain, PWSTR *PSuffix, PWSTR Root); +FSP_API VOID FspPathCombine(PWSTR Prefix, PWSTR Suffix); + +/** + * @group Service Framework + * + * User mode file systems typically are run as Windows services. WinFsp provides an API to make + * the creation of Windows services easier. This API is provided for convenience and is not + * necessary to expose a user mode file system to Windows. + */ +typedef struct _FSP_SERVICE FSP_SERVICE; +typedef NTSTATUS FSP_SERVICE_START(FSP_SERVICE *, ULONG, PWSTR *); +typedef NTSTATUS FSP_SERVICE_STOP(FSP_SERVICE *); +typedef NTSTATUS FSP_SERVICE_CONTROL(FSP_SERVICE *, ULONG, ULONG, PVOID); +#pragma warning(push) +#pragma warning(disable:4200) /* zero-sized array in struct/union */ +typedef struct _FSP_SERVICE +{ + UINT16 Version; + PVOID UserContext; + FSP_SERVICE_START *OnStart; + FSP_SERVICE_STOP *OnStop; + FSP_SERVICE_CONTROL *OnControl; + ULONG AcceptControl; + ULONG ExitCode; + SERVICE_STATUS_HANDLE StatusHandle; + SERVICE_STATUS ServiceStatus; + CRITICAL_SECTION ServiceStatusGuard; + CRITICAL_SECTION ServiceStopGuard; + BOOLEAN AllowConsoleMode; + WCHAR ServiceName[]; +} FSP_SERVICE; +#pragma warning(pop) +/** + * Run a service. + * + * This function wraps calls to FspServiceCreate, FspServiceLoop and FspServiceDelete to create, + * run and delete a service. It is intended to be used from a service's main/wmain function. + * + * This function runs a service with console mode allowed. + * + * @param ServiceName + * The name of the service. + * @param OnStart + * Function to call when the service starts. + * @param OnStop + * Function to call when the service stops. + * @param OnControl + * Function to call when the service receives a service control code. + * @return + * Service process exit code. + */ +FSP_API ULONG FspServiceRunEx(PWSTR ServiceName, + FSP_SERVICE_START *OnStart, + FSP_SERVICE_STOP *OnStop, + FSP_SERVICE_CONTROL *OnControl, + PVOID UserContext); +static inline +ULONG FspServiceRun(PWSTR ServiceName, + FSP_SERVICE_START *OnStart, + FSP_SERVICE_STOP *OnStop, + FSP_SERVICE_CONTROL *OnControl) +{ + return FspServiceRunEx(ServiceName, OnStart, OnStop, OnControl, 0); +} +/** + * Create a service object. + * + * @param ServiceName + * The name of the service. + * @param OnStart + * Function to call when the service starts. + * @param OnStop + * Function to call when the service stops. + * @param OnControl + * Function to call when the service receives a service control code. + * @param PService [out] + * Pointer that will receive the service object created on successful return from this + * call. + * @return + * STATUS_SUCCESS or error code. + */ +FSP_API NTSTATUS FspServiceCreate(PWSTR ServiceName, + FSP_SERVICE_START *OnStart, + FSP_SERVICE_STOP *OnStop, + FSP_SERVICE_CONTROL *OnControl, + FSP_SERVICE **PService); +/** + * Delete a service object. + * + * @param Service + * The service object. + */ +FSP_API VOID FspServiceDelete(FSP_SERVICE *Service); +/** + * Allow a service to run in console mode. + * + * A service that is run in console mode runs with a console attached and outside the control of + * the Service Control Manager. This is useful for debugging and testing a service during + * development. + * + * User mode file systems that wish to use the WinFsp Launcher functionality must also use this + * call. The WinFsp Launcher is a Windows service that can be configured to launch and manage + * multiple instances of a user mode file system. + * + * @param Service + * The service object. + */ +FSP_API VOID FspServiceAllowConsoleMode(FSP_SERVICE *Service); +/** + * Configure the control codes that a service accepts. + * + * This API should be used prior to Start operations. + * + * @param Service + * The service object. + * @param Control + * The control codes to accept. Note that the SERVICE_ACCEPT_PAUSE_CONTINUE code is silently + * ignored. + */ +FSP_API VOID FspServiceAcceptControl(FSP_SERVICE *Service, ULONG Control); +/** + * Request additional time from the Service Control Manager. + * + * This API should be used during Start and Stop operations only. + * + * @param Service + * The service object. + * @param Time + * Additional time (in milliseconds). + */ +FSP_API VOID FspServiceRequestTime(FSP_SERVICE *Service, ULONG Time); +/** + * Set the service process exit code. + * + * @param Service + * The service object. + * @param ExitCode + * Service process exit code. + */ +FSP_API VOID FspServiceSetExitCode(FSP_SERVICE *Service, ULONG ExitCode); +/** + * Get the service process exit code. + * + * @param Service + * The service object. + * @return + * Service process exit code. + */ +FSP_API ULONG FspServiceGetExitCode(FSP_SERVICE *Service); +/** + * Run a service main loop. + * + * This function starts and runs a service. It executes the Windows StartServiceCtrlDispatcher API + * to connect the service process to the Service Control Manager. If the Service Control Manager is + * not available (and console mode is allowed) it will enter console mode. + * + * This function should be called once per process. + * + * @param Service + * The service object. + * @return + * STATUS_SUCCESS or error code. + */ +FSP_API NTSTATUS FspServiceLoop(FSP_SERVICE *Service); +/** + * Stops a running service. + * + * Stopping a service usually happens when the Service Control Manager instructs the service to + * stop. In some situations (e.g. fatal errors) the service may wish to stop itself. It can do so + * in a clean manner by calling this function. + * + * @param Service + * The service object. + * @return + * STATUS_SUCCESS or error code. + */ +FSP_API VOID FspServiceStop(FSP_SERVICE *Service); +/** + * Determine if the current process is running in user interactive mode. + * + * @return + * TRUE if the process is running in running user interactive mode. + */ +FSP_API BOOLEAN FspServiceIsInteractive(VOID); +/** + * Check if the supplied token is from the service context. + * + * @param Token + * Token to check. Pass NULL to check the current process token. + * @param PIsLocalSystem + * Pointer to a boolean that will receive a TRUE value if the token belongs to LocalSystem + * and FALSE otherwise. May be NULL. + * @return + * STATUS_SUCCESS if the token is from the service context. STATUS_ACCESS_DENIED if it is not. + * Other error codes are possible. + */ +FSP_API NTSTATUS FspServiceContextCheck(HANDLE Token, PBOOLEAN PIsLocalSystem); +/** + * Log a service message. + * + * This function can be used to log an arbitrary message to the Windows Event Log or to the current + * console if running in user interactive mode. + * + * @param Type + * One of EVENTLOG_INFORMATION_TYPE, EVENTLOG_WARNING_TYPE, EVENTLOG_ERROR_TYPE. + * @param Format + * Format specification. This function uses the Windows wsprintf API for formatting. Refer to + * that API's documentation for details on the format specification. + */ +FSP_API VOID FspServiceLog(ULONG Type, PWSTR Format, ...); +FSP_API VOID FspServiceLogV(ULONG Type, PWSTR Format, va_list ap); + +/* + * Utility + */ +FSP_API NTSTATUS FspNtStatusFromWin32(DWORD Error); +FSP_API DWORD FspWin32FromNtStatus(NTSTATUS Status); +FSP_API VOID FspEventLog(ULONG Type, PWSTR Format, ...); +FSP_API VOID FspEventLogV(ULONG Type, PWSTR Format, va_list ap); +FSP_API VOID FspDebugLogSetHandle(HANDLE Handle); +FSP_API VOID FspDebugLog(const char *Format, ...); +FSP_API VOID FspDebugLogSD(const char *Format, PSECURITY_DESCRIPTOR SecurityDescriptor); +FSP_API VOID FspDebugLogSid(const char *format, PSID Sid); +FSP_API VOID FspDebugLogFT(const char *Format, PFILETIME FileTime); +FSP_API VOID FspDebugLogRequest(FSP_FSCTL_TRANSACT_REQ *Request); +FSP_API VOID FspDebugLogResponse(FSP_FSCTL_TRANSACT_RSP *Response); +FSP_API NTSTATUS FspCallNamedPipeSecurely(PWSTR PipeName, + PVOID InBuffer, ULONG InBufferSize, PVOID OutBuffer, ULONG OutBufferSize, + PULONG PBytesTransferred, ULONG Timeout, + PSID Sid); +FSP_API NTSTATUS FspCallNamedPipeSecurelyEx(PWSTR PipeName, + PVOID InBuffer, ULONG InBufferSize, PVOID OutBuffer, ULONG OutBufferSize, + PULONG PBytesTransferred, ULONG Timeout, BOOLEAN AllowImpersonation, + PSID Sid); +FSP_API NTSTATUS FspVersion(PUINT32 PVersion); +FSP_API PWSTR FspSxsIdent(VOID); + +/* + * Delay load + */ +static inline +NTSTATUS FspLoad(PVOID *PModule) +{ +#define FSP_DLLNAME FSP_FSCTL_PRODUCT_FILE_NAME "-" FSP_FSCTL_PRODUCT_FILE_ARCH ".dll" +#define FSP_DLLPATH "bin\\" FSP_DLLNAME + + WINADVAPI + LSTATUS + APIENTRY + RegGetValueW( + HKEY hkey, + LPCWSTR lpSubKey, + LPCWSTR lpValue, + DWORD dwFlags, + LPDWORD pdwType, + PVOID pvData, + LPDWORD pcbData); + + WCHAR PathBuf[MAX_PATH]; + DWORD Size; + LONG Result; + HMODULE Module; + + if (0 != PModule) + *PModule = 0; + + Module = LoadLibraryW(L"" FSP_DLLNAME); + if (0 == Module) + { + Size = sizeof PathBuf - sizeof L"" FSP_DLLPATH + sizeof(WCHAR); + Result = RegGetValueW(HKEY_LOCAL_MACHINE, L"" FSP_FSCTL_PRODUCT_FULL_REGKEY, L"InstallDir", + RRF_RT_REG_SZ, 0, PathBuf, &Size); + if (ERROR_SUCCESS != Result) + return STATUS_OBJECT_NAME_NOT_FOUND; + + RtlCopyMemory(PathBuf + (Size / sizeof(WCHAR) - 1), L"" FSP_DLLPATH, sizeof L"" FSP_DLLPATH); + Module = LoadLibraryW(PathBuf); + if (0 == Module) + return STATUS_DLL_NOT_FOUND; + } + + if (0 != PModule) + *PModule = Module; + + return STATUS_SUCCESS; + +#undef FSP_DLLPATH +#undef FSP_DLLNAME +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/support/3rd_party/winfsp-2.1/inc/winfsp/winfsp.hpp b/support/3rd_party/winfsp-2.1/inc/winfsp/winfsp.hpp new file mode 100644 index 00000000..33bb494b --- /dev/null +++ b/support/3rd_party/winfsp-2.1/inc/winfsp/winfsp.hpp @@ -0,0 +1,1320 @@ +/** + * @file winfsp/winfsp.hpp + * WinFsp C++ Layer. + * + * @copyright 2015-2025 Bill Zissimopoulos + */ +/* + * This file is part of WinFsp. + * + * You can redistribute it and/or modify it under the terms of the GNU + * General Public License version 3 as published by the Free Software + * Foundation. + * + * Licensees holding a valid commercial license may use this software + * in accordance with the commercial license agreement provided in + * conjunction with the software. The terms and conditions of any such + * commercial license agreement shall govern, supersede, and render + * ineffective any application of the GPLv3 license to this software, + * notwithstanding of any reference thereto in the software or + * associated repository. + */ + +#ifndef WINFSP_WINFSP_HPP_INCLUDED +#define WINFSP_WINFSP_HPP_INCLUDED + +#ifndef __cplusplus +#error this header requires a C++ compiler +#endif + +#include + +#define FSP_CPP_EXCEPTION_GUARD(...)\ + try { __VA_ARGS__ } catch (...) { return self->ExceptionHandler(); } +#define FSP_CPP_EXCEPTION_GUARD_VOID(...)\ + try { __VA_ARGS__ } catch (...) { self->ExceptionHandler(); return; } + +namespace Fsp { + +inline NTSTATUS Initialize() +{ + static NTSTATUS LoadResult = FspLoad(0); + return LoadResult; +} + +class FileSystemBase +{ +public: + typedef FSP_FSCTL_VOLUME_INFO VolumeInfo; + typedef FSP_FSCTL_FILE_INFO FileInfo; + typedef FSP_FSCTL_OPEN_FILE_INFO OpenFileInfo; + typedef FSP_FSCTL_DIR_INFO DirInfo; + typedef FSP_FSCTL_STREAM_INFO StreamInfo; + enum CleanupFlags + { + CleanupDelete = FspCleanupDelete, + CleanupSetAllocationSize = FspCleanupSetAllocationSize, + CleanupSetArchiveBit = FspCleanupSetArchiveBit, + CleanupSetLastAccessTime = FspCleanupSetLastAccessTime, + CleanupSetLastWriteTime = FspCleanupSetLastWriteTime, + CleanupSetChangeTime = FspCleanupSetChangeTime, + }; + +public: + FileSystemBase() + { + } + virtual ~FileSystemBase() + { + } + + /* operations */ + virtual NTSTATUS ExceptionHandler() + { + return STATUS_UNEXPECTED_IO_ERROR; + } + virtual NTSTATUS Init(PVOID Host) + { + return STATUS_SUCCESS; + } + virtual NTSTATUS Mounted(PVOID Host) + { + return STATUS_SUCCESS; + } + virtual VOID Unmounted(PVOID Host) + { + } + virtual NTSTATUS GetVolumeInfo( + VolumeInfo *VolumeInfo) + { + return STATUS_INVALID_DEVICE_REQUEST; + } + virtual NTSTATUS SetVolumeLabel_( + PWSTR VolumeLabel, + VolumeInfo *VolumeInfo) + { + return STATUS_INVALID_DEVICE_REQUEST; + } + virtual NTSTATUS GetSecurityByName( + PWSTR FileName, + PUINT32 PFileAttributes/* or ReparsePointIndex */, + PSECURITY_DESCRIPTOR SecurityDescriptor, + SIZE_T *PSecurityDescriptorSize) + { + return STATUS_INVALID_DEVICE_REQUEST; + } + virtual NTSTATUS Create( + PWSTR FileName, + UINT32 CreateOptions, + UINT32 GrantedAccess, + UINT32 FileAttributes, + PSECURITY_DESCRIPTOR SecurityDescriptor, + UINT64 AllocationSize, + PVOID *PFileNode, + PVOID *PFileDesc, + OpenFileInfo *OpenFileInfo) + { + return STATUS_INVALID_DEVICE_REQUEST; + } + virtual NTSTATUS Open( + PWSTR FileName, + UINT32 CreateOptions, + UINT32 GrantedAccess, + PVOID *PFileNode, + PVOID *PFileDesc, + OpenFileInfo *OpenFileInfo) + { + return STATUS_INVALID_DEVICE_REQUEST; + } + virtual NTSTATUS Overwrite( + PVOID FileNode, + PVOID FileDesc, + UINT32 FileAttributes, + BOOLEAN ReplaceFileAttributes, + UINT64 AllocationSize, + FileInfo *FileInfo) + { + return STATUS_INVALID_DEVICE_REQUEST; + } + virtual VOID Cleanup( + PVOID FileNode, + PVOID FileDesc, + PWSTR FileName, + ULONG Flags) + { + } + virtual VOID Close( + PVOID FileNode, + PVOID FileDesc) + { + } + virtual NTSTATUS Read( + PVOID FileNode, + PVOID FileDesc, + PVOID Buffer, + UINT64 Offset, + ULONG Length, + PULONG PBytesTransferred) + { + return STATUS_INVALID_DEVICE_REQUEST; + } + virtual NTSTATUS Write( + PVOID FileNode, + PVOID FileDesc, + PVOID Buffer, + UINT64 Offset, + ULONG Length, + BOOLEAN WriteToEndOfFile, + BOOLEAN ConstrainedIo, + PULONG PBytesTransferred, + FileInfo *FileInfo) + { + return STATUS_INVALID_DEVICE_REQUEST; + } + virtual NTSTATUS Flush( + PVOID FileNode, + PVOID FileDesc, + FileInfo *FileInfo) + { + return STATUS_INVALID_DEVICE_REQUEST; + } + virtual NTSTATUS GetFileInfo( + PVOID FileNode, + PVOID FileDesc, + FileInfo *FileInfo) + { + return STATUS_INVALID_DEVICE_REQUEST; + } + virtual NTSTATUS SetBasicInfo( + PVOID FileNode, + PVOID FileDesc, + UINT32 FileAttributes, + UINT64 CreationTime, + UINT64 LastAccessTime, + UINT64 LastWriteTime, + UINT64 ChangeTime, + FileInfo *FileInfo) + { + return STATUS_INVALID_DEVICE_REQUEST; + } + virtual NTSTATUS SetFileSize( + PVOID FileNode, + PVOID FileDesc, + UINT64 NewSize, + BOOLEAN SetAllocationSize, + FileInfo *FileInfo) + { + return STATUS_INVALID_DEVICE_REQUEST; + } + virtual NTSTATUS CanDelete( + PVOID FileNode, + PVOID FileDesc, + PWSTR FileName) + { + return STATUS_INVALID_DEVICE_REQUEST; + } + virtual NTSTATUS Rename( + PVOID FileNode, + PVOID FileDesc, + PWSTR FileName, + PWSTR NewFileName, + BOOLEAN ReplaceIfExists) + { + return STATUS_INVALID_DEVICE_REQUEST; + } + virtual NTSTATUS GetSecurity( + PVOID FileNode, + PVOID FileDesc, + PSECURITY_DESCRIPTOR SecurityDescriptor, + SIZE_T *PSecurityDescriptorSize) + { + return STATUS_INVALID_DEVICE_REQUEST; + } + virtual NTSTATUS SetSecurity( + PVOID FileNode, + PVOID FileDesc, + SECURITY_INFORMATION SecurityInformation, + PSECURITY_DESCRIPTOR ModificationDescriptor) + { + return STATUS_INVALID_DEVICE_REQUEST; + } + virtual NTSTATUS ReadDirectory( + PVOID FileNode, + PVOID FileDesc, + PWSTR Pattern, + PWSTR Marker, + PVOID Buffer, + ULONG Length, + PULONG PBytesTransferred) + { + return SeekableReadDirectory( + FileNode, + FileDesc, + Pattern, + Marker, + Buffer, + Length, + PBytesTransferred); + } + virtual NTSTATUS ReadDirectoryEntry( + PVOID FileNode, + PVOID FileDesc, + PWSTR Pattern, + PWSTR Marker, + PVOID *PContext, + DirInfo *DirInfo) + { + return STATUS_INVALID_DEVICE_REQUEST; + } + virtual NTSTATUS ResolveReparsePoints( + PWSTR FileName, + UINT32 ReparsePointIndex, + BOOLEAN ResolveLastPathComponent, + PIO_STATUS_BLOCK PIoStatus, + PVOID Buffer, + PSIZE_T PSize) + { + return FspFileSystemResolveReparsePoints( + 0, + GetReparsePointByName, + this, + FileName, + ReparsePointIndex, + ResolveLastPathComponent, + PIoStatus, + Buffer, + PSize); + } + virtual NTSTATUS GetReparsePointByName( + PWSTR FileName, + BOOLEAN IsDirectory, + PVOID Buffer, + PSIZE_T PSize) + { + return STATUS_INVALID_DEVICE_REQUEST; + } + virtual NTSTATUS GetReparsePoint( + PVOID FileNode, + PVOID FileDesc, + PWSTR FileName, + PVOID Buffer, + PSIZE_T PSize) + { + return STATUS_INVALID_DEVICE_REQUEST; + } + virtual NTSTATUS SetReparsePoint( + PVOID FileNode, + PVOID FileDesc, + PWSTR FileName, + PVOID Buffer, + SIZE_T Size) + { + return STATUS_INVALID_DEVICE_REQUEST; + } + virtual NTSTATUS DeleteReparsePoint( + PVOID FileNode, + PVOID FileDesc, + PWSTR FileName, + PVOID Buffer, + SIZE_T Size) + { + return STATUS_INVALID_DEVICE_REQUEST; + } + virtual NTSTATUS GetStreamInfo( + PVOID FileNode, + PVOID FileDesc, + PVOID Buffer, + ULONG Length, + PULONG PBytesTransferred) + { + return STATUS_INVALID_DEVICE_REQUEST; + } + + /* helpers */ + static NTSTATUS NtStatusFromWin32(DWORD Error) + { + return FspNtStatusFromWin32(Error); + } + static DWORD Win32FromNtStatus(NTSTATUS Status) + { + return FspWin32FromNtStatus(Status); + } + static VOID DeleteDirectoryBuffer(PVOID *PDirBuffer) + { + FspFileSystemDeleteDirectoryBuffer(PDirBuffer); + } + NTSTATUS SeekableReadDirectory( + PVOID FileNode, + PVOID FileDesc, + PWSTR Pattern, + PWSTR Marker, + PVOID Buffer, + ULONG Length, + PULONG PBytesTransferred) + { + PVOID Context = 0; + union + { + UINT8 B[FIELD_OFFSET(FileSystemBase::DirInfo, FileNameBuf) + MAX_PATH * sizeof(WCHAR)]; + FileSystemBase::DirInfo D; + } DirInfoBuf; + FileSystemBase::DirInfo *DirInfo = &DirInfoBuf.D; + NTSTATUS Result = STATUS_SUCCESS; + *PBytesTransferred = 0; + for (;;) + { + Result = ReadDirectoryEntry(FileNode, FileDesc, Pattern, Marker, &Context, DirInfo); + if (STATUS_NO_MORE_FILES == Result) + { + Result = STATUS_SUCCESS; + break; + } + if (!NT_SUCCESS(Result)) + break; + if (!FspFileSystemAddDirInfo(DirInfo, Buffer, Length, PBytesTransferred)) + break; + } + if (!NT_SUCCESS(Result)) + return Result; + return STATUS_SUCCESS; + } + NTSTATUS BufferedReadDirectory( + PVOID *PDirBuffer, + PVOID FileNode, + PVOID FileDesc, + PWSTR Pattern, + PWSTR Marker, + PVOID Buffer, + ULONG Length, + PULONG PBytesTransferred) + { + PVOID Context = 0; + union + { + UINT8 B[FIELD_OFFSET(FileSystemBase::DirInfo, FileNameBuf) + MAX_PATH * sizeof(WCHAR)]; + FileSystemBase::DirInfo D; + } DirInfoBuf; + FileSystemBase::DirInfo *DirInfo = &DirInfoBuf.D; + NTSTATUS Result = STATUS_SUCCESS; + *PBytesTransferred = 0; + if (FspFileSystemAcquireDirectoryBuffer(PDirBuffer, 0 == Marker, &Result)) + { + try + { + for (;;) + { + Result = ReadDirectoryEntry(FileNode, FileDesc, Pattern, Marker, &Context, DirInfo); + if (STATUS_NO_MORE_FILES == Result) + { + Result = STATUS_SUCCESS; + break; + } + if (!NT_SUCCESS(Result)) + break; + if (!FspFileSystemFillDirectoryBuffer(PDirBuffer, DirInfo, &Result)) + break; + } + } + catch (...) + { + FspFileSystemReleaseDirectoryBuffer(PDirBuffer); + throw; + } + FspFileSystemReleaseDirectoryBuffer(PDirBuffer); + } + if (!NT_SUCCESS(Result)) + return Result; + FspFileSystemReadDirectoryBuffer(PDirBuffer, Marker, Buffer, Length, PBytesTransferred); + return STATUS_SUCCESS; + } + BOOLEAN FindReparsePoint( + PWSTR FileName, PUINT32 PReparsePointIndex) + { + return FspFileSystemFindReparsePoint( + 0, + GetReparsePointByName, + this, + FileName, + PReparsePointIndex); + } + static NTSTATUS CanReplaceReparsePoint( + PVOID CurrentReparseData, SIZE_T CurrentReparseDataSize, + PVOID ReplaceReparseData, SIZE_T ReplaceReparseDataSize) + { + return FspFileSystemCanReplaceReparsePoint( + CurrentReparseData, CurrentReparseDataSize, + ReplaceReparseData, ReplaceReparseDataSize); + } + static BOOLEAN AddStreamInfo(StreamInfo *StreamInfo, + PVOID Buffer, ULONG Length, PULONG PBytesTransferred) + { + return FspFileSystemAddStreamInfo(StreamInfo, Buffer, Length, PBytesTransferred); + } + +private: + static NTSTATUS GetReparsePointByName(FSP_FILE_SYSTEM *FileSystem, + PVOID Context, + PWSTR FileName, + BOOLEAN IsDirectory, + PVOID Buffer, + PSIZE_T PSize) + { + FileSystemBase *self = (FileSystemBase *)Context; + FSP_CPP_EXCEPTION_GUARD( + return self->GetReparsePointByName( + FileName, + IsDirectory, + Buffer, + PSize); + ) + } + +private: + /* disallow copy and assignment */ + FileSystemBase(const FileSystemBase &); + FileSystemBase &operator=(const FileSystemBase &); +}; + +class FileSystemHost +{ +public: + /* ctor/dtor */ + FileSystemHost(FileSystemBase &FileSystem) : + _VolumeParams(), _FileSystemPtr(0), _FileSystem(&FileSystem) + { + Initialize(); + _VolumeParams.UmFileContextIsFullContext = 1; + } + virtual ~FileSystemHost() + { + if (0 != _FileSystemPtr) + FspFileSystemDelete(_FileSystemPtr); + } + + /* properties */ + UINT16 SectorSize() + { + return _VolumeParams.SectorSize; + } + VOID SetSectorSize(UINT16 SectorSize) + { + _VolumeParams.SectorSize = SectorSize; + } + UINT16 SectorsPerAllocationUnit() + { + return _VolumeParams.SectorsPerAllocationUnit; + } + VOID SetSectorsPerAllocationUnit(UINT16 SectorsPerAllocationUnit) + { + _VolumeParams.SectorsPerAllocationUnit = SectorsPerAllocationUnit; + } + UINT16 MaxComponentLength() + { + return _VolumeParams.MaxComponentLength; + } + VOID SetMaxComponentLength(UINT16 MaxComponentLength) + { + _VolumeParams.MaxComponentLength = MaxComponentLength; + } + UINT64 VolumeCreationTime() + { + return _VolumeParams.VolumeCreationTime; + } + VOID SetVolumeCreationTime(UINT64 VolumeCreationTime) + { + _VolumeParams.VolumeCreationTime = VolumeCreationTime; + } + UINT32 VolumeSerialNumber() + { + return _VolumeParams.VolumeSerialNumber; + } + VOID SetVolumeSerialNumber(UINT32 VolumeSerialNumber) + { + _VolumeParams.VolumeSerialNumber = VolumeSerialNumber; + } + UINT32 FileInfoTimeout() + { + return _VolumeParams.FileInfoTimeout; + } + VOID SetFileInfoTimeout(UINT32 FileInfoTimeout) + { + _VolumeParams.FileInfoTimeout = FileInfoTimeout; + } + BOOLEAN CaseSensitiveSearch() + { + return _VolumeParams.CaseSensitiveSearch; + } + VOID SetCaseSensitiveSearch(BOOLEAN CaseSensitiveSearch) + { + _VolumeParams.CaseSensitiveSearch = !!CaseSensitiveSearch; + } + BOOLEAN CasePreservedNames() + { + return _VolumeParams.CasePreservedNames; + } + VOID SetCasePreservedNames(BOOLEAN CasePreservedNames) + { + _VolumeParams.CasePreservedNames = !!CasePreservedNames; + } + BOOLEAN UnicodeOnDisk() + { + return _VolumeParams.UnicodeOnDisk; + } + VOID SetUnicodeOnDisk(BOOLEAN UnicodeOnDisk) + { + _VolumeParams.UnicodeOnDisk = !!UnicodeOnDisk; + } + BOOLEAN PersistentAcls() + { + return _VolumeParams.PersistentAcls; + } + VOID SetPersistentAcls(BOOLEAN PersistentAcls) + { + _VolumeParams.PersistentAcls = !!PersistentAcls; + } + BOOLEAN ReparsePoints() + { + return _VolumeParams.ReparsePoints; + } + VOID SetReparsePoints(BOOLEAN ReparsePoints) + { + _VolumeParams.ReparsePoints = !!ReparsePoints; + } + BOOLEAN ReparsePointsAccessCheck() + { + return _VolumeParams.ReparsePointsAccessCheck; + } + VOID SetReparsePointsAccessCheck(BOOLEAN ReparsePointsAccessCheck) + { + _VolumeParams.ReparsePointsAccessCheck = !!ReparsePointsAccessCheck; + } + BOOLEAN NamedStreams() + { + return _VolumeParams.NamedStreams; + } + VOID SetNamedStreams(BOOLEAN NamedStreams) + { + _VolumeParams.NamedStreams = !!NamedStreams; + } + BOOLEAN PostCleanupWhenModifiedOnly() + { + return _VolumeParams.PostCleanupWhenModifiedOnly; + } + VOID SetPostCleanupWhenModifiedOnly(BOOLEAN PostCleanupWhenModifiedOnly) + { + _VolumeParams.PostCleanupWhenModifiedOnly = !!PostCleanupWhenModifiedOnly; + } + BOOLEAN PassQueryDirectoryPattern() + { + return _VolumeParams.PassQueryDirectoryPattern; + } + VOID SetPassQueryDirectoryPattern(BOOLEAN PassQueryDirectoryPattern) + { + _VolumeParams.PassQueryDirectoryPattern = !!PassQueryDirectoryPattern; + } + BOOLEAN FlushAndPurgeOnCleanup() + { + return _VolumeParams.FlushAndPurgeOnCleanup; + } + VOID SetFlushAndPurgeOnCleanup(BOOLEAN FlushAndPurgeOnCleanup) + { + _VolumeParams.FlushAndPurgeOnCleanup = !!FlushAndPurgeOnCleanup; + } + PWSTR Prefix() + { + return _VolumeParams.Prefix; + } + VOID SetPrefix(PWSTR Prefix) + { + int Size = lstrlenW(Prefix) * sizeof(WCHAR); + if (Size > sizeof _VolumeParams.Prefix - sizeof(WCHAR)) + Size = sizeof _VolumeParams.Prefix - sizeof(WCHAR); + RtlCopyMemory(_VolumeParams.Prefix, Prefix, Size); + _VolumeParams.Prefix[Size / sizeof(WCHAR)] = L'\0'; + } + PWSTR FileSystemName() + { + return _VolumeParams.FileSystemName; + } + VOID SetFileSystemName(PWSTR FileSystemName) + { + int Size = lstrlenW(FileSystemName) * sizeof(WCHAR); + if (Size > sizeof _VolumeParams.FileSystemName - sizeof(WCHAR)) + Size = sizeof _VolumeParams.FileSystemName - sizeof(WCHAR); + RtlCopyMemory(_VolumeParams.FileSystemName, FileSystemName, Size); + _VolumeParams.FileSystemName[Size / sizeof(WCHAR)] = L'\0'; + } + + /* control */ + NTSTATUS Preflight(PWSTR MountPoint) + { + return FspFileSystemPreflight( + _VolumeParams.Prefix[0] ? L"" FSP_FSCTL_NET_DEVICE_NAME : L"" FSP_FSCTL_DISK_DEVICE_NAME, + MountPoint); + } + NTSTATUS Mount(PWSTR MountPoint, + PSECURITY_DESCRIPTOR SecurityDescriptor = 0, + BOOLEAN Synchronized = FALSE, + UINT32 DebugLog = 0) + { + NTSTATUS Result; + try + { + Result = _FileSystem->Init(this); + } + catch (...) + { + Result = _FileSystem->ExceptionHandler(); + } + if (!NT_SUCCESS(Result)) + return Result; + Result = FspFileSystemCreate( + _VolumeParams.Prefix[0] ? L"" FSP_FSCTL_NET_DEVICE_NAME : L"" FSP_FSCTL_DISK_DEVICE_NAME, + &_VolumeParams, Interface(), &_FileSystemPtr); + if (!NT_SUCCESS(Result)) + return Result; + _FileSystemPtr->UserContext = _FileSystem; + FspFileSystemSetOperationGuardStrategy(_FileSystemPtr, Synchronized ? + FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY_COARSE : + FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY_FINE); + FspFileSystemSetDebugLog(_FileSystemPtr, DebugLog); + Result = FspFileSystemSetMountPointEx(_FileSystemPtr, MountPoint, SecurityDescriptor); + if (NT_SUCCESS(Result)) + { + try + { + Result = _FileSystem->Mounted(this); + } + catch (...) + { + Result = _FileSystem->ExceptionHandler(); + } + if (NT_SUCCESS(Result)) + { + Result = FspFileSystemStartDispatcher(_FileSystemPtr, 0); + if (!NT_SUCCESS(Result)) + try + { + _FileSystem->Unmounted(this); + } + catch (...) + { + _FileSystem->ExceptionHandler(); + } + } + } + if (!NT_SUCCESS(Result)) + { + FspFileSystemDelete(_FileSystemPtr); + _FileSystemPtr = 0; + } + return Result; + } + VOID Unmount() + { + FspFileSystemStopDispatcher(_FileSystemPtr); + try + { + _FileSystem->Unmounted(this); + } + catch (...) + { + _FileSystem->ExceptionHandler(); + } + _FileSystemPtr->UserContext = 0; + FspFileSystemDelete(_FileSystemPtr); + _FileSystemPtr = 0; + } + PWSTR MountPoint() + { + return 0 != _FileSystemPtr ? FspFileSystemMountPoint(_FileSystemPtr) : 0; + } + FSP_FILE_SYSTEM *FileSystemHandle() + { + return _FileSystemPtr; + } + FileSystemBase &FileSystem() + { + return *_FileSystem; + } + static NTSTATUS SetDebugLogFile(PWSTR FileName) + { + HANDLE Handle; + if ('-' == FileName[0] && '\0' == FileName[1]) + Handle = GetStdHandle(STD_ERROR_HANDLE); + else + Handle = CreateFileW( + FileName, + FILE_APPEND_DATA, + FILE_SHARE_READ | FILE_SHARE_WRITE, + 0, + OPEN_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + 0); + if (INVALID_HANDLE_VALUE == Handle) + return FspNtStatusFromWin32(GetLastError()); + FspDebugLogSetHandle(Handle); + return STATUS_SUCCESS; + } + +private: + /* FSP_FILE_SYSTEM_INTERFACE */ + static NTSTATUS GetVolumeInfo(FSP_FILE_SYSTEM *FileSystem0, + FSP_FSCTL_VOLUME_INFO *VolumeInfo) + { + FileSystemBase *self = (FileSystemBase *)FileSystem0->UserContext; + FSP_CPP_EXCEPTION_GUARD( + return self->GetVolumeInfo( + VolumeInfo); + ) + } + static NTSTATUS SetVolumeLabel_(FSP_FILE_SYSTEM *FileSystem0, + PWSTR VolumeLabel, + FSP_FSCTL_VOLUME_INFO *VolumeInfo) + { + FileSystemBase *self = (FileSystemBase *)FileSystem0->UserContext; + FSP_CPP_EXCEPTION_GUARD( + return self->SetVolumeLabel_( + VolumeLabel, + VolumeInfo); + ) + } + static NTSTATUS GetSecurityByName(FSP_FILE_SYSTEM *FileSystem0, + PWSTR FileName, + PUINT32 PFileAttributes/* or ReparsePointIndex */, + PSECURITY_DESCRIPTOR SecurityDescriptor, + SIZE_T *PSecurityDescriptorSize) + { + FileSystemBase *self = (FileSystemBase *)FileSystem0->UserContext; + FSP_CPP_EXCEPTION_GUARD( + return self->GetSecurityByName( + FileName, + PFileAttributes, + SecurityDescriptor, + PSecurityDescriptorSize); + ) + } + static NTSTATUS Create(FSP_FILE_SYSTEM *FileSystem0, + PWSTR FileName, + UINT32 CreateOptions, + UINT32 GrantedAccess, + UINT32 FileAttributes, + PSECURITY_DESCRIPTOR SecurityDescriptor, + UINT64 AllocationSize, + PVOID *FullContext, + FSP_FSCTL_FILE_INFO *FileInfo) + { + FileSystemBase *self = (FileSystemBase *)FileSystem0->UserContext; + PVOID FileNode, FileDesc; + NTSTATUS Result; + FSP_CPP_EXCEPTION_GUARD( + Result = self->Create( + FileName, + CreateOptions, + GrantedAccess, + FileAttributes, + SecurityDescriptor, + AllocationSize, + &FileNode, + &FileDesc, + FspFileSystemGetOpenFileInfo(FileInfo)); + ) + ((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext = (UINT64)(UINT_PTR)FileNode; + ((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2 = (UINT64)(UINT_PTR)FileDesc; + return Result; + } + static NTSTATUS Open(FSP_FILE_SYSTEM *FileSystem0, + PWSTR FileName, + UINT32 CreateOptions, + UINT32 GrantedAccess, + PVOID *FullContext, + FSP_FSCTL_FILE_INFO *FileInfo) + { + FileSystemBase *self = (FileSystemBase *)FileSystem0->UserContext; + PVOID FileNode, FileDesc; + NTSTATUS Result; + FSP_CPP_EXCEPTION_GUARD( + Result = self->Open( + FileName, + CreateOptions, + GrantedAccess, + &FileNode, + &FileDesc, + FspFileSystemGetOpenFileInfo(FileInfo)); + ) + ((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext = (UINT64)(UINT_PTR)FileNode; + ((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2 = (UINT64)(UINT_PTR)FileDesc; + return Result; + } + static NTSTATUS Overwrite(FSP_FILE_SYSTEM *FileSystem0, + PVOID FullContext, + UINT32 FileAttributes, + BOOLEAN ReplaceFileAttributes, + UINT64 AllocationSize, + FSP_FSCTL_FILE_INFO *FileInfo) + { + FileSystemBase *self = (FileSystemBase *)FileSystem0->UserContext; + FSP_CPP_EXCEPTION_GUARD( + return self->Overwrite( + (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext, + (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2, + FileAttributes, + ReplaceFileAttributes, + AllocationSize, + FileInfo); + ) + } + static VOID Cleanup(FSP_FILE_SYSTEM *FileSystem0, + PVOID FullContext, + PWSTR FileName, + ULONG Flags) + { + FileSystemBase *self = (FileSystemBase *)FileSystem0->UserContext; + FSP_CPP_EXCEPTION_GUARD_VOID( + return self->Cleanup( + (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext, + (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2, + FileName, + Flags); + ) + } + static VOID Close(FSP_FILE_SYSTEM *FileSystem0, + PVOID FullContext) + { + FileSystemBase *self = (FileSystemBase *)FileSystem0->UserContext; + FSP_CPP_EXCEPTION_GUARD_VOID( + return self->Close( + (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext, + (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2); + ) + } + static NTSTATUS Read(FSP_FILE_SYSTEM *FileSystem0, + PVOID FullContext, + PVOID Buffer, + UINT64 Offset, + ULONG Length, + PULONG PBytesTransferred) + { + FileSystemBase *self = (FileSystemBase *)FileSystem0->UserContext; + FSP_CPP_EXCEPTION_GUARD( + return self->Read( + (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext, + (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2, + Buffer, + Offset, + Length, + PBytesTransferred); + ) + } + static NTSTATUS Write(FSP_FILE_SYSTEM *FileSystem0, + PVOID FullContext, + PVOID Buffer, + UINT64 Offset, + ULONG Length, + BOOLEAN WriteToEndOfFile, + BOOLEAN ConstrainedIo, + PULONG PBytesTransferred, + FSP_FSCTL_FILE_INFO *FileInfo) + { + FileSystemBase *self = (FileSystemBase *)FileSystem0->UserContext; + FSP_CPP_EXCEPTION_GUARD( + return self->Write( + (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext, + (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2, + Buffer, + Offset, + Length, + WriteToEndOfFile, + ConstrainedIo, + PBytesTransferred, + FileInfo); + ) + } + static NTSTATUS Flush(FSP_FILE_SYSTEM *FileSystem0, + PVOID FullContext, + FSP_FSCTL_FILE_INFO *FileInfo) + { + FileSystemBase *self = (FileSystemBase *)FileSystem0->UserContext; + FSP_CPP_EXCEPTION_GUARD( + return self->Flush( + (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext, + (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2, + FileInfo); + ) + } + static NTSTATUS GetFileInfo(FSP_FILE_SYSTEM *FileSystem0, + PVOID FullContext, + FSP_FSCTL_FILE_INFO *FileInfo) + { + FileSystemBase *self = (FileSystemBase *)FileSystem0->UserContext; + FSP_CPP_EXCEPTION_GUARD( + return self->GetFileInfo( + (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext, + (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2, + FileInfo); + ) + } + static NTSTATUS SetBasicInfo(FSP_FILE_SYSTEM *FileSystem0, + PVOID FullContext, + UINT32 FileAttributes, + UINT64 CreationTime, + UINT64 LastAccessTime, + UINT64 LastWriteTime, + UINT64 ChangeTime, + FSP_FSCTL_FILE_INFO *FileInfo) + { + FileSystemBase *self = (FileSystemBase *)FileSystem0->UserContext; + FSP_CPP_EXCEPTION_GUARD( + return self->SetBasicInfo( + (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext, + (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2, + FileAttributes, + CreationTime, + LastAccessTime, + LastWriteTime, + ChangeTime, + FileInfo); + ) + } + static NTSTATUS SetFileSize(FSP_FILE_SYSTEM *FileSystem0, + PVOID FullContext, + UINT64 NewSize, + BOOLEAN SetAllocationSize, + FSP_FSCTL_FILE_INFO *FileInfo) + { + FileSystemBase *self = (FileSystemBase *)FileSystem0->UserContext; + FSP_CPP_EXCEPTION_GUARD( + return self->SetFileSize( + (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext, + (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2, + NewSize, + SetAllocationSize, + FileInfo); + ) + } + static NTSTATUS CanDelete(FSP_FILE_SYSTEM *FileSystem0, + PVOID FullContext, + PWSTR FileName) + { + FileSystemBase *self = (FileSystemBase *)FileSystem0->UserContext; + FSP_CPP_EXCEPTION_GUARD( + return self->CanDelete( + (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext, + (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2, + FileName); + ) + } + static NTSTATUS Rename(FSP_FILE_SYSTEM *FileSystem0, + PVOID FullContext, + PWSTR FileName, + PWSTR NewFileName, + BOOLEAN ReplaceIfExists) + { + FileSystemBase *self = (FileSystemBase *)FileSystem0->UserContext; + FSP_CPP_EXCEPTION_GUARD( + return self->Rename( + (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext, + (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2, + FileName, + NewFileName, + ReplaceIfExists); + ) + } + static NTSTATUS GetSecurity(FSP_FILE_SYSTEM *FileSystem0, + PVOID FullContext, + PSECURITY_DESCRIPTOR SecurityDescriptor, + SIZE_T *PSecurityDescriptorSize) + { + FileSystemBase *self = (FileSystemBase *)FileSystem0->UserContext; + FSP_CPP_EXCEPTION_GUARD( + return self->GetSecurity( + (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext, + (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2, + SecurityDescriptor, + PSecurityDescriptorSize); + ) + } + static NTSTATUS SetSecurity(FSP_FILE_SYSTEM *FileSystem0, + PVOID FullContext, + SECURITY_INFORMATION SecurityInformation, + PSECURITY_DESCRIPTOR ModificationDescriptor) + { + FileSystemBase *self = (FileSystemBase *)FileSystem0->UserContext; + FSP_CPP_EXCEPTION_GUARD( + return self->SetSecurity( + (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext, + (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2, + SecurityInformation, + ModificationDescriptor); + ) + } + static NTSTATUS ReadDirectory(FSP_FILE_SYSTEM *FileSystem0, + PVOID FullContext, + PWSTR Pattern, + PWSTR Marker, + PVOID Buffer, + ULONG Length, + PULONG PBytesTransferred) + { + FileSystemBase *self = (FileSystemBase *)FileSystem0->UserContext; + FSP_CPP_EXCEPTION_GUARD( + return self->ReadDirectory( + (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext, + (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2, + Pattern, + Marker, + Buffer, + Length, + PBytesTransferred); + ) + } + static NTSTATUS ResolveReparsePoints(FSP_FILE_SYSTEM *FileSystem0, + PWSTR FileName, + UINT32 ReparsePointIndex, + BOOLEAN ResolveLastPathComponent, + PIO_STATUS_BLOCK PIoStatus, + PVOID Buffer, + PSIZE_T PSize) + { + FileSystemBase *self = (FileSystemBase *)FileSystem0->UserContext; + FSP_CPP_EXCEPTION_GUARD( + return self->ResolveReparsePoints( + FileName, + ReparsePointIndex, + ResolveLastPathComponent, + PIoStatus, + Buffer, + PSize); + ) + } + static NTSTATUS GetReparsePoint(FSP_FILE_SYSTEM *FileSystem0, + PVOID FullContext, + PWSTR FileName, + PVOID Buffer, + PSIZE_T PSize) + { + FileSystemBase *self = (FileSystemBase *)FileSystem0->UserContext; + FSP_CPP_EXCEPTION_GUARD( + return self->GetReparsePoint( + (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext, + (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2, + FileName, + Buffer, + PSize); + ) + } + static NTSTATUS SetReparsePoint(FSP_FILE_SYSTEM *FileSystem0, + PVOID FullContext, + PWSTR FileName, + PVOID Buffer, + SIZE_T Size) + { + FileSystemBase *self = (FileSystemBase *)FileSystem0->UserContext; + FSP_CPP_EXCEPTION_GUARD( + return self->SetReparsePoint( + (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext, + (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2, + FileName, + Buffer, + Size); + ) + } + static NTSTATUS DeleteReparsePoint(FSP_FILE_SYSTEM *FileSystem0, + PVOID FullContext, + PWSTR FileName, + PVOID Buffer, + SIZE_T Size) + { + FileSystemBase *self = (FileSystemBase *)FileSystem0->UserContext; + FSP_CPP_EXCEPTION_GUARD( + return self->DeleteReparsePoint( + (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext, + (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2, + FileName, + Buffer, + Size); + ) + } + static NTSTATUS GetStreamInfo(FSP_FILE_SYSTEM *FileSystem0, + PVOID FullContext, + PVOID Buffer, + ULONG Length, + PULONG PBytesTransferred) + { + FileSystemBase *self = (FileSystemBase *)FileSystem0->UserContext; + FSP_CPP_EXCEPTION_GUARD( + return self->GetStreamInfo( + (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext, + (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2, + Buffer, + Length, + PBytesTransferred); + ) + } + static FSP_FILE_SYSTEM_INTERFACE *Interface() + { + static FSP_FILE_SYSTEM_INTERFACE _Interface = + { + GetVolumeInfo, + SetVolumeLabel_, + GetSecurityByName, + Create, + Open, + Overwrite, + Cleanup, + Close, + Read, + Write, + Flush, + GetFileInfo, + SetBasicInfo, + SetFileSize, + CanDelete, + Rename, + GetSecurity, + SetSecurity, + ReadDirectory, + ResolveReparsePoints, + GetReparsePoint, + SetReparsePoint, + DeleteReparsePoint, + GetStreamInfo, + }; + return &_Interface; + } + +private: + /* disallow copy and assignment */ + FileSystemHost(const FileSystemHost &); + FileSystemHost &operator=(const FileSystemHost &); + +private: + FSP_FSCTL_VOLUME_PARAMS _VolumeParams; + FSP_FILE_SYSTEM *_FileSystemPtr; + FileSystemBase *_FileSystem; +}; + +class Service +{ +public: + /* ctor/dtor */ + Service(PWSTR ServiceName) : _Service(0) + { + Initialize(); + FspServiceCreate(ServiceName, OnStart, OnStop, 0, &_Service); + if (0 != _Service) + _Service->UserContext = this; + } + virtual ~Service() + { + if (0 != _Service) + FspServiceDelete(_Service); + } + + /* control */ + ULONG Run() + { + if (0 == _Service) + { + FspServiceLog(EVENTLOG_ERROR_TYPE, + L"The service cannot be created (Status=%lx).", + STATUS_INSUFFICIENT_RESOURCES); + return FspWin32FromNtStatus(STATUS_INSUFFICIENT_RESOURCES); + } + FspServiceAllowConsoleMode(_Service); + NTSTATUS Result = FspServiceLoop(_Service); + ULONG ExitCode = FspServiceGetExitCode(_Service); + if (!NT_SUCCESS(Result)) + { + FspServiceLog(EVENTLOG_ERROR_TYPE, + L"The service has failed to run (Status=%lx).", + Result); + return FspWin32FromNtStatus(Result); + } + return ExitCode; + } + VOID Stop() + { + if (0 == _Service) + return; + FspServiceStop(_Service); + } + VOID RequestTime(ULONG Time) + { + if (0 == _Service) + return; + FspServiceRequestTime(_Service, Time); + } + ULONG GetExitCode() + { + return 0 != _Service ? FspServiceGetExitCode(_Service) : ERROR_NO_SYSTEM_RESOURCES; + } + VOID SetExitCode(ULONG ExitCode) + { + if (0 == _Service) + return; + FspServiceSetExitCode(_Service, ExitCode); + } + FSP_SERVICE *ServiceHandle() + { + return _Service; + } + static VOID Log(ULONG Type, PWSTR Format, ...) + { + va_list ap; + va_start(ap, Format); + FspServiceLogV(Type, Format, ap); + va_end(ap); + } + static VOID LogV(ULONG Type, PWSTR Format, va_list ap) + { + FspServiceLogV(Type, Format, ap); + } + +protected: + /* start/stop */ + virtual NTSTATUS ExceptionHandler() + { + return 0xE06D7363/*STATUS_CPP_EH_EXCEPTION*/; + } + virtual NTSTATUS OnStart(ULONG Argc, PWSTR *Argv) + { + return STATUS_SUCCESS; + } + virtual NTSTATUS OnStop() + { + return STATUS_SUCCESS; + } + +private: + /* callbacks */ + static NTSTATUS OnStart(FSP_SERVICE *Service0, ULONG Argc, PWSTR *Argv) + { + Service *self = (Service *)Service0->UserContext; + FSP_CPP_EXCEPTION_GUARD( + return self->OnStart(Argc, Argv); + ) + } + static NTSTATUS OnStop(FSP_SERVICE *Service0) + { + Service *self = (Service *)Service0->UserContext; + FSP_CPP_EXCEPTION_GUARD( + return self->OnStop(); + ) + } + +private: + /* disallow copy and assignment */ + Service(const Service &); + Service &operator=(const Service &); + +private: + FSP_SERVICE *_Service; +}; + +} + +#undef FSP_CPP_EXCEPTION_GUARD +#undef FSP_CPP_EXCEPTION_GUARD_VOID + +#endif diff --git a/support/3rd_party/winfsp-2.0/lib/fuse.pc b/support/3rd_party/winfsp-2.1/lib/fuse.pc similarity index 95% rename from support/3rd_party/winfsp-2.0/lib/fuse.pc rename to support/3rd_party/winfsp-2.1/lib/fuse.pc index 93cc49b4..b0fdca75 100644 --- a/support/3rd_party/winfsp-2.0/lib/fuse.pc +++ b/support/3rd_party/winfsp-2.1/lib/fuse.pc @@ -1,11 +1,11 @@ -arch=x64 -prefix=${pcfiledir}/.. -incdir=${prefix}/inc/fuse -implib=${prefix}/bin/winfsp-${arch}.dll - -Name: fuse -Description: WinFsp FUSE compatible API -Version: 2.8 -URL: https://winfsp.dev -Libs: "${implib}" -Cflags: -I"${incdir}" +arch=x64 +prefix=${pcfiledir}/.. +incdir=${prefix}/inc/fuse +implib=${prefix}/bin/winfsp-${arch}.dll + +Name: fuse +Description: WinFsp FUSE compatible API +Version: 2.8 +URL: https://winfsp.dev +Libs: "${implib}" +Cflags: -I"${incdir}" diff --git a/support/3rd_party/winfsp-2.0/lib/fuse3.pc b/support/3rd_party/winfsp-2.1/lib/fuse3.pc similarity index 95% rename from support/3rd_party/winfsp-2.0/lib/fuse3.pc rename to support/3rd_party/winfsp-2.1/lib/fuse3.pc index 703ec774..62e83042 100644 --- a/support/3rd_party/winfsp-2.0/lib/fuse3.pc +++ b/support/3rd_party/winfsp-2.1/lib/fuse3.pc @@ -1,11 +1,11 @@ -arch=x64 -prefix=${pcfiledir}/.. -incdir=${prefix}/inc/fuse3 -implib=${prefix}/bin/winfsp-${arch}.dll - -Name: fuse3 -Description: WinFsp FUSE3 compatible API -Version: 3.2 -URL: https://winfsp.dev -Libs: "${implib}" -Cflags: -I"${incdir}" +arch=x64 +prefix=${pcfiledir}/.. +incdir=${prefix}/inc/fuse3 +implib=${prefix}/bin/winfsp-${arch}.dll + +Name: fuse3 +Description: WinFsp FUSE3 compatible API +Version: 3.2 +URL: https://winfsp.dev +Libs: "${implib}" +Cflags: -I"${incdir}" diff --git a/support/3rd_party/winfsp-2.1/lib/winfsp-a64.lib b/support/3rd_party/winfsp-2.1/lib/winfsp-a64.lib new file mode 100644 index 00000000..6297e339 Binary files /dev/null and b/support/3rd_party/winfsp-2.1/lib/winfsp-a64.lib differ diff --git a/support/3rd_party/winfsp-2.1/lib/winfsp-x64.lib b/support/3rd_party/winfsp-2.1/lib/winfsp-x64.lib new file mode 100644 index 00000000..2a3fbaf4 Binary files /dev/null and b/support/3rd_party/winfsp-2.1/lib/winfsp-x64.lib differ diff --git a/support/3rd_party/winfsp-2.1/lib/winfsp-x86.lib b/support/3rd_party/winfsp-2.1/lib/winfsp-x86.lib new file mode 100644 index 00000000..b5fb7444 Binary files /dev/null and b/support/3rd_party/winfsp-2.1/lib/winfsp-x86.lib differ