upgraded winfsp to v2.1
Some checks failed
BlockStorage/repertory/pipeline/head There was a failure building this commit

This commit is contained in:
2025-07-21 10:59:07 -05:00
parent 1ea2d1496d
commit 39fcce0e88
57 changed files with 8650 additions and 8257 deletions

View File

@@ -17,6 +17,7 @@
* Drive letters in UI should always be lowercase * Drive letters in UI should always be lowercase
* Fixed WinFSP directory rename for non-empty directories * Fixed WinFSP directory rename for non-empty directories
* Migrated to v2 error handling * Migrated to v2 error handling
* Upgraded WinFSP to v2.1 (20205)
## v2.0.5-rc ## v2.0.5-rc

View File

@@ -48,7 +48,7 @@ on Windows.
* [Sia renterd](https://github.com/SiaFoundation/renterd/releases) v2.0.0+ for Sia support * [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 * Linux requires `fusermount3`; otherwise, `repertory` must be manually compiled with `libfuse2` support
* Windows requires the following dependencies to be installed: * 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 ### Supported Operating Systems

View File

@@ -2,9 +2,9 @@ if(PROJECT_ENABLE_WINFSP AND PROJECT_IS_MINGW)
if(PROJECT_BUILD) if(PROJECT_BUILD)
add_definitions(-DPROJECT_ENABLE_WINFSP) 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) if(PROJECT_IS_ARM64)
link_libraries(winfsp-a64) link_libraries(winfsp-a64)

View File

@@ -194,7 +194,7 @@ if [ "${PROJECT_ENABLE_WINFSP}" == "ON" ]; then
fi fi
if [ "${WINFSP_DLL_PART}" != "" ]; then 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
fi fi

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -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 <devioctl.h>
#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

View File

@@ -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 <winfsp/winfsp.h>
#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

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,54 +1,54 @@
@echo off @echo off
setlocal setlocal
setlocal EnableDelayedExpansion setlocal EnableDelayedExpansion
REM Determine the SxS (side-by-side) identifier. REM Determine the SxS (side-by-side) identifier.
set SxsDir= set SxsDir=
set RegKey="HKLM\SOFTWARE\WinFsp" set RegKey="HKLM\SOFTWARE\WinFsp"
set RegVal="SxsDir" set RegVal="SxsDir"
reg query !RegKey! /v !RegVal! /reg:32 >nul 2>&1 reg query !RegKey! /v !RegVal! /reg:32 >nul 2>&1
if !ERRORLEVEL! equ 0 ( if !ERRORLEVEL! equ 0 (
for /f "tokens=2,*" %%i in ('reg query !RegKey! /v !RegVal! /reg:32 ^| findstr !RegVal!') do ( for /f "tokens=2,*" %%i in ('reg query !RegKey! /v !RegVal! /reg:32 ^| findstr !RegVal!') do (
set SxsDir=%%j set SxsDir=%%j
) )
) )
set SxsSuffix= set SxsSuffix=
if defined SxsDir ( if defined SxsDir (
set SxsSuffix=!SxsDir:*SxS\sxs.=! set SxsSuffix=!SxsDir:*SxS\sxs.=!
if !SxsSuffix:~-1!==\ set SxsSuffix=!SxsSuffix:~0,-1! if !SxsSuffix:~-1!==\ set SxsSuffix=!SxsSuffix:~0,-1!
set SxsSuffix=+!SxsSuffix! set SxsSuffix=+!SxsSuffix!
) )
echo WINFSP FSD echo WINFSP FSD
sc query WinFsp!SxsSuffix! sc query WinFsp!SxsSuffix!
sc qc WinFsp!SxsSuffix! sc qc WinFsp!SxsSuffix!
sc sdshow WinFsp!SxsSuffix! sc sdshow WinFsp!SxsSuffix!
echo. echo.
echo. echo.
echo WINFSP DLL echo WINFSP DLL
reg query HKLM\SYSTEM\CurrentControlSet\Control\NetworkProvider\Order reg query HKLM\SYSTEM\CurrentControlSet\Control\NetworkProvider\Order
reg query HKLM\SYSTEM\CurrentControlSet\Services\WinFsp.Np\NetworkProvider reg query HKLM\SYSTEM\CurrentControlSet\Services\WinFsp.Np\NetworkProvider
reg query HKLM\SYSTEM\CurrentControlSet\Services\EventLog\Application\WinFsp reg query HKLM\SYSTEM\CurrentControlSet\Services\EventLog\Application\WinFsp
echo. echo.
echo WINFSP LAUNCHER echo WINFSP LAUNCHER
sc query WinFsp.Launcher sc query WinFsp.Launcher
sc qc WinFsp.Launcher sc qc WinFsp.Launcher
sc sdshow WinFsp.Launcher sc sdshow WinFsp.Launcher
echo. echo.
echo. echo.
echo WINFSP REGISTRY echo WINFSP REGISTRY
reg query HKLM\SOFTWARE\WinFsp /s /reg:32 reg query HKLM\SOFTWARE\WinFsp /s /reg:32
echo. echo.
echo FILE SYSTEM FILTERS (REQUIRES ADMINISTRATOR) echo FILE SYSTEM FILTERS (REQUIRES ADMINISTRATOR)
fltmc filters fltmc filters
echo. echo.
echo. echo.
echo OS INFORMATION echo OS INFORMATION
systeminfo systeminfo
echo. echo.

View File

@@ -1,42 +1,42 @@
@echo off @echo off
setlocal setlocal
setlocal EnableDelayedExpansion setlocal EnableDelayedExpansion
set RegKey=HKLM\Software\WinFsp\Services set RegKey=HKLM\Software\WinFsp\Services
if not X%1==X-u ( if not X%1==X-u (
set unreg=0 set unreg=0
if not X%1==X set fsname=%1 if not X%1==X set fsname=%1
if not X%2==X set fsexec="%~f2" if not X%2==X set fsexec="%~f2"
if not X%3==X set fscmdl=%3 if not X%3==X set fscmdl=%3
if not X%4==X set fssecu=%4 if not X%4==X set fssecu=%4
if X!fscmdl!==X goto usage if X!fscmdl!==X goto usage
if not exist !fsexec! goto notfound 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 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 CommandLine /t REG_SZ /d !fscmdl! /f /reg:32
reg add !RegKey!\!fsname! /v JobControl /t REG_DWORD /d 1 /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 if not X!fssecu!==X reg add !RegKey!\!fsname! /v Security /t REG_SZ /d !fssecu! /f /reg:32
) else ( ) else (
set unreg=1 set unreg=1
if not X%2==X set fsname=%2 if not X%2==X set fsname=%2
if X!fsname!==X goto usage if X!fsname!==X goto usage
reg delete !RegKey!\!fsname! /f /reg:32 reg delete !RegKey!\!fsname! /f /reg:32
) )
exit /b 0 exit /b 0
:notfound :notfound
echo executable !fsexec! not found >&2 echo executable !fsexec! not found >&2
exit /b 2 exit /b 2
:usage :usage
echo usage: fsreg NAME EXECUTABLE COMMANDLINE [SECURITY] >&2 echo usage: fsreg NAME EXECUTABLE COMMANDLINE [SECURITY] >&2
echo usage: fsreg -u NAME >&2 echo usage: fsreg -u NAME >&2
exit /b 2 exit /b 2

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,271 +1,271 @@
/** /**
* @file fuse/fuse.h * @file fuse/fuse.h
* WinFsp FUSE compatible API. * WinFsp FUSE compatible API.
* *
* This file is derived from libfuse/include/fuse.h: * This file is derived from libfuse/include/fuse.h:
* FUSE: Filesystem in Userspace * FUSE: Filesystem in Userspace
* Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu> * Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
* *
* @copyright 2015-2022 Bill Zissimopoulos * @copyright 2015-2025 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
* *
* You can redistribute it and/or modify it under the terms of the GNU * 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 * General Public License version 3 as published by the Free Software
* Foundation. * Foundation.
* *
* Licensees holding a valid commercial license may use this software * Licensees holding a valid commercial license may use this software
* in accordance with the commercial license agreement provided in * in accordance with the commercial license agreement provided in
* conjunction with the software. The terms and conditions of any such * conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render * commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software, * ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or * notwithstanding of any reference thereto in the software or
* associated repository. * associated repository.
*/ */
#ifndef FUSE_H_ #ifndef FUSE_H_
#define FUSE_H_ #define FUSE_H_
#include "fuse_common.h" #include "fuse_common.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
struct fuse; struct fuse;
typedef int (*fuse_fill_dir_t)(void *buf, const char *name, typedef int (*fuse_fill_dir_t)(void *buf, const char *name,
const struct fuse_stat *stbuf, fuse_off_t off); const struct fuse_stat *stbuf, fuse_off_t off);
typedef struct fuse_dirhandle *fuse_dirh_t; typedef struct fuse_dirhandle *fuse_dirh_t;
typedef int (*fuse_dirfil_t)(fuse_dirh_t h, const char *name, typedef int (*fuse_dirfil_t)(fuse_dirh_t h, const char *name,
int type, fuse_ino_t ino); int type, fuse_ino_t ino);
struct fuse_operations struct fuse_operations
{ {
/* S - supported by WinFsp */ /* S - supported by WinFsp */
/* S */ int (*getattr)(const char *path, struct fuse_stat *stbuf); /* 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 (*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 (*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 (*mknod)(const char *path, fuse_mode_t mode, fuse_dev_t dev);
/* S */ int (*mkdir)(const char *path, fuse_mode_t mode); /* S */ int (*mkdir)(const char *path, fuse_mode_t mode);
/* S */ int (*unlink)(const char *path); /* S */ int (*unlink)(const char *path);
/* S */ int (*rmdir)(const char *path); /* S */ int (*rmdir)(const char *path);
/* S */ int (*symlink)(const char *dstpath, const char *srcpath); /* S */ int (*symlink)(const char *dstpath, const char *srcpath);
/* S */ int (*rename)(const char *oldpath, const char *newpath); /* S */ int (*rename)(const char *oldpath, const char *newpath);
/* _ */ int (*link)(const char *srcpath, const char *dstpath); /* _ */ int (*link)(const char *srcpath, const char *dstpath);
/* S */ int (*chmod)(const char *path, fuse_mode_t mode); /* 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 (*chown)(const char *path, fuse_uid_t uid, fuse_gid_t gid);
/* S */ int (*truncate)(const char *path, fuse_off_t size); /* S */ int (*truncate)(const char *path, fuse_off_t size);
/* S */ int (*utime)(const char *path, struct fuse_utimbuf *timbuf); /* S */ int (*utime)(const char *path, struct fuse_utimbuf *timbuf);
/* S */ int (*open)(const char *path, struct fuse_file_info *fi); /* 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, /* S */ int (*read)(const char *path, char *buf, size_t size, fuse_off_t off,
struct fuse_file_info *fi); struct fuse_file_info *fi);
/* S */ int (*write)(const char *path, const char *buf, size_t size, fuse_off_t off, /* S */ int (*write)(const char *path, const char *buf, size_t size, fuse_off_t off,
struct fuse_file_info *fi); struct fuse_file_info *fi);
/* S */ int (*statfs)(const char *path, struct fuse_statvfs *stbuf); /* S */ int (*statfs)(const char *path, struct fuse_statvfs *stbuf);
/* S */ int (*flush)(const char *path, struct fuse_file_info *fi); /* S */ int (*flush)(const char *path, struct fuse_file_info *fi);
/* S */ int (*release)(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 (*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, /* S */ int (*setxattr)(const char *path, const char *name, const char *value, size_t size,
int flags); int flags);
/* S */ int (*getxattr)(const char *path, const char *name, char *value, size_t size); /* 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 (*listxattr)(const char *path, char *namebuf, size_t size);
/* S */ int (*removexattr)(const char *path, const char *name); /* S */ int (*removexattr)(const char *path, const char *name);
/* S */ int (*opendir)(const char *path, struct fuse_file_info *fi); /* 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, /* S */ int (*readdir)(const char *path, void *buf, fuse_fill_dir_t filler, fuse_off_t off,
struct fuse_file_info *fi); struct fuse_file_info *fi);
/* S */ int (*releasedir)(const char *path, 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 */ int (*fsyncdir)(const char *path, int datasync, struct fuse_file_info *fi);
/* S */ void *(*init)(struct fuse_conn_info *conn); /* S */ void *(*init)(struct fuse_conn_info *conn);
/* S */ void (*destroy)(void *data); /* S */ void (*destroy)(void *data);
/* S */ int (*access)(const char *path, int mask); /* 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 (*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 (*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); /* S */ int (*fgetattr)(const char *path, struct fuse_stat *stbuf, struct fuse_file_info *fi);
/* _ */ int (*lock)(const char *path, /* _ */ int (*lock)(const char *path,
struct fuse_file_info *fi, int cmd, struct fuse_flock *lock); struct fuse_file_info *fi, int cmd, struct fuse_flock *lock);
/* S */ int (*utimens)(const char *path, const struct fuse_timespec tv[2]); /* S */ int (*utimens)(const char *path, const struct fuse_timespec tv[2]);
/* _ */ int (*bmap)(const char *path, size_t blocksize, uint64_t *idx); /* _ */ int (*bmap)(const char *path, size_t blocksize, uint64_t *idx);
/* _ */ unsigned int flag_nullpath_ok:1; /* _ */ unsigned int flag_nullpath_ok:1;
/* _ */ unsigned int flag_nopath:1; /* _ */ unsigned int flag_nopath:1;
/* _ */ unsigned int flag_utime_omit_ok:1; /* _ */ unsigned int flag_utime_omit_ok:1;
/* _ */ unsigned int flag_reserved:29; /* _ */ unsigned int flag_reserved:29;
/* S */ int (*ioctl)(const char *path, int cmd, void *arg, struct fuse_file_info *fi, /* S */ int (*ioctl)(const char *path, int cmd, void *arg, struct fuse_file_info *fi,
unsigned int flags, void *data); unsigned int flags, void *data);
/* _ */ int (*poll)(const char *path, struct fuse_file_info *fi, /* _ */ int (*poll)(const char *path, struct fuse_file_info *fi,
struct fuse_pollhandle *ph, unsigned *reventsp); struct fuse_pollhandle *ph, unsigned *reventsp);
/* FUSE 2.9 */ /* FUSE 2.9 */
/* _ */ int (*write_buf)(const char *path, /* _ */ int (*write_buf)(const char *path,
struct fuse_bufvec *buf, fuse_off_t off, struct fuse_file_info *fi); struct fuse_bufvec *buf, fuse_off_t off, struct fuse_file_info *fi);
/* _ */ int (*read_buf)(const char *path, /* _ */ int (*read_buf)(const char *path,
struct fuse_bufvec **bufp, size_t size, fuse_off_t off, struct fuse_file_info *fi); 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 (*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, /* _ */ int (*fallocate)(const char *path, int mode, fuse_off_t off, fuse_off_t len,
struct fuse_file_info *fi); struct fuse_file_info *fi);
/* WinFsp */ /* WinFsp */
/* S */ int (*getpath)(const char *path, char *buf, size_t size, /* S */ int (*getpath)(const char *path, char *buf, size_t size,
struct fuse_file_info *fi); struct fuse_file_info *fi);
/* OSXFUSE */ /* OSXFUSE */
/* _ */ int (*reserved01)(); /* _ */ int (*reserved01)();
/* _ */ int (*reserved02)(); /* _ */ int (*reserved02)();
/* _ */ int (*statfs_x)(const char *path, struct fuse_statfs *stbuf); /* _ */ int (*statfs_x)(const char *path, struct fuse_statfs *stbuf);
/* _ */ int (*setvolname)(const char *volname); /* _ */ int (*setvolname)(const char *volname);
/* _ */ int (*exchange)(const char *oldpath, const char *newpath, unsigned long flags); /* _ */ int (*exchange)(const char *oldpath, const char *newpath, unsigned long flags);
/* _ */ int (*getxtimes)(const char *path, /* _ */ int (*getxtimes)(const char *path,
struct fuse_timespec *bkuptime, struct fuse_timespec *crtime); struct fuse_timespec *bkuptime, struct fuse_timespec *crtime);
/* _ */ int (*setbkuptime)(const char *path, const struct fuse_timespec *tv); /* _ */ int (*setbkuptime)(const char *path, const struct fuse_timespec *tv);
/* S */ int (*setchgtime)(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 (*setcrtime)(const char *path, const struct fuse_timespec *tv);
/* S */ int (*chflags)(const char *path, uint32_t flags); /* S */ int (*chflags)(const char *path, uint32_t flags);
/* _ */ int (*setattr_x)(const char *path, struct fuse_setattr_x *attr); /* _ */ int (*setattr_x)(const char *path, struct fuse_setattr_x *attr);
/* _ */ int (*fsetattr_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_file_info *fi);
}; };
struct fuse_context struct fuse_context
{ {
struct fuse *fuse; struct fuse *fuse;
fuse_uid_t uid; fuse_uid_t uid;
fuse_gid_t gid; fuse_gid_t gid;
fuse_pid_t pid; fuse_pid_t pid;
void *private_data; void *private_data;
fuse_mode_t umask; fuse_mode_t umask;
}; };
#define fuse_main(argc, argv, ops, data)\ #define fuse_main(argc, argv, ops, data)\
fuse_main_real(argc, argv, ops, sizeof *(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, FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse_main_real)(struct fsp_fuse_env *env,
int argc, char *argv[], int argc, char *argv[],
const struct fuse_operations *ops, size_t opsize, void *data); 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, FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse_is_lib_option)(struct fsp_fuse_env *env,
const char *opt); const char *opt);
FSP_FUSE_API struct fuse *FSP_FUSE_API_NAME(fsp_fuse_new)(struct fsp_fuse_env *env, 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, struct fuse_chan *ch, struct fuse_args *args,
const struct fuse_operations *ops, size_t opsize, void *data); 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, FSP_FUSE_API void FSP_FUSE_API_NAME(fsp_fuse_destroy)(struct fsp_fuse_env *env,
struct fuse *f); struct fuse *f);
FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse_loop)(struct fsp_fuse_env *env, FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse_loop)(struct fsp_fuse_env *env,
struct fuse *f); struct fuse *f);
FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse_loop_mt)(struct fsp_fuse_env *env, FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse_loop_mt)(struct fsp_fuse_env *env,
struct fuse *f); struct fuse *f);
FSP_FUSE_API void FSP_FUSE_API_NAME(fsp_fuse_exit)(struct fsp_fuse_env *env, FSP_FUSE_API void FSP_FUSE_API_NAME(fsp_fuse_exit)(struct fsp_fuse_env *env,
struct fuse *f); struct fuse *f);
FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse_exited)(struct fsp_fuse_env *env, FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse_exited)(struct fsp_fuse_env *env,
struct fuse *f); struct fuse *f);
FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse_notify)(struct fsp_fuse_env *env, 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); 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_API struct fuse_context *FSP_FUSE_API_NAME(fsp_fuse_get_context)(struct fsp_fuse_env *env);
FSP_FUSE_SYM( FSP_FUSE_SYM(
int fuse_main_real(int argc, char *argv[], int fuse_main_real(int argc, char *argv[],
const struct fuse_operations *ops, size_t opsize, void *data), const struct fuse_operations *ops, size_t opsize, void *data),
{ {
return FSP_FUSE_API_CALL(fsp_fuse_main_real) return FSP_FUSE_API_CALL(fsp_fuse_main_real)
(fsp_fuse_env(), argc, argv, ops, opsize, data); (fsp_fuse_env(), argc, argv, ops, opsize, data);
}) })
FSP_FUSE_SYM( FSP_FUSE_SYM(
int fuse_is_lib_option(const char *opt), int fuse_is_lib_option(const char *opt),
{ {
return FSP_FUSE_API_CALL(fsp_fuse_is_lib_option) return FSP_FUSE_API_CALL(fsp_fuse_is_lib_option)
(fsp_fuse_env(), opt); (fsp_fuse_env(), opt);
}) })
FSP_FUSE_SYM( FSP_FUSE_SYM(
struct fuse *fuse_new(struct fuse_chan *ch, struct fuse_args *args, struct fuse *fuse_new(struct fuse_chan *ch, struct fuse_args *args,
const struct fuse_operations *ops, size_t opsize, void *data), const struct fuse_operations *ops, size_t opsize, void *data),
{ {
return FSP_FUSE_API_CALL(fsp_fuse_new) return FSP_FUSE_API_CALL(fsp_fuse_new)
(fsp_fuse_env(), ch, args, ops, opsize, data); (fsp_fuse_env(), ch, args, ops, opsize, data);
}) })
FSP_FUSE_SYM( FSP_FUSE_SYM(
void fuse_destroy(struct fuse *f), void fuse_destroy(struct fuse *f),
{ {
FSP_FUSE_API_CALL(fsp_fuse_destroy) FSP_FUSE_API_CALL(fsp_fuse_destroy)
(fsp_fuse_env(), f); (fsp_fuse_env(), f);
}) })
FSP_FUSE_SYM( FSP_FUSE_SYM(
int fuse_loop(struct fuse *f), int fuse_loop(struct fuse *f),
{ {
return FSP_FUSE_API_CALL(fsp_fuse_loop) return FSP_FUSE_API_CALL(fsp_fuse_loop)
(fsp_fuse_env(), f); (fsp_fuse_env(), f);
}) })
FSP_FUSE_SYM( FSP_FUSE_SYM(
int fuse_loop_mt(struct fuse *f), int fuse_loop_mt(struct fuse *f),
{ {
return FSP_FUSE_API_CALL(fsp_fuse_loop_mt) return FSP_FUSE_API_CALL(fsp_fuse_loop_mt)
(fsp_fuse_env(), f); (fsp_fuse_env(), f);
}) })
FSP_FUSE_SYM( FSP_FUSE_SYM(
void fuse_exit(struct fuse *f), void fuse_exit(struct fuse *f),
{ {
FSP_FUSE_API_CALL(fsp_fuse_exit) FSP_FUSE_API_CALL(fsp_fuse_exit)
(fsp_fuse_env(), f); (fsp_fuse_env(), f);
}) })
FSP_FUSE_SYM( FSP_FUSE_SYM(
int fuse_exited(struct fuse *f), int fuse_exited(struct fuse *f),
{ {
return FSP_FUSE_API_CALL(fsp_fuse_exited) return FSP_FUSE_API_CALL(fsp_fuse_exited)
(fsp_fuse_env(), f); (fsp_fuse_env(), f);
}) })
FSP_FUSE_SYM( FSP_FUSE_SYM(
int fuse_notify(struct fuse *f, const char *path, uint32_t action), int fuse_notify(struct fuse *f, const char *path, uint32_t action),
{ {
return FSP_FUSE_API_CALL(fsp_fuse_notify) return FSP_FUSE_API_CALL(fsp_fuse_notify)
(fsp_fuse_env(), f, path, action); (fsp_fuse_env(), f, path, action);
}) })
FSP_FUSE_SYM( FSP_FUSE_SYM(
struct fuse_context *fuse_get_context(void), struct fuse_context *fuse_get_context(void),
{ {
return FSP_FUSE_API_CALL(fsp_fuse_get_context) return FSP_FUSE_API_CALL(fsp_fuse_get_context)
(fsp_fuse_env()); (fsp_fuse_env());
}) })
FSP_FUSE_SYM( FSP_FUSE_SYM(
int fuse_getgroups(int size, fuse_gid_t list[]), int fuse_getgroups(int size, fuse_gid_t list[]),
{ {
(void)size; (void)size;
(void)list; (void)list;
return -ENOSYS; return -ENOSYS;
}) })
FSP_FUSE_SYM( FSP_FUSE_SYM(
int fuse_interrupted(void), int fuse_interrupted(void),
{ {
return 0; return 0;
}) })
FSP_FUSE_SYM( FSP_FUSE_SYM(
int fuse_invalidate(struct fuse *f, const char *path), int fuse_invalidate(struct fuse *f, const char *path),
{ {
return FSP_FUSE_API_CALL(fsp_fuse_notify) return FSP_FUSE_API_CALL(fsp_fuse_notify)
(fsp_fuse_env(), f, path, 0); (fsp_fuse_env(), f, path, 0);
}) })
FSP_FUSE_SYM( FSP_FUSE_SYM(
int fuse_notify_poll(struct fuse_pollhandle *ph), int fuse_notify_poll(struct fuse_pollhandle *ph),
{ {
(void)ph; (void)ph;
return 0; return 0;
}) })
FSP_FUSE_SYM( FSP_FUSE_SYM(
struct fuse_session *fuse_get_session(struct fuse *f), struct fuse_session *fuse_get_session(struct fuse *f),
{ {
return (struct fuse_session *)f; return (struct fuse_session *)f;
}) })
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif #endif

View File

@@ -1,202 +1,202 @@
/** /**
* @file fuse/fuse_common.h * @file fuse/fuse_common.h
* WinFsp FUSE compatible API. * WinFsp FUSE compatible API.
* *
* This file is derived from libfuse/include/fuse_common.h: * This file is derived from libfuse/include/fuse_common.h:
* FUSE: Filesystem in Userspace * FUSE: Filesystem in Userspace
* Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu> * Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
* *
* @copyright 2015-2022 Bill Zissimopoulos * @copyright 2015-2025 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
* *
* You can redistribute it and/or modify it under the terms of the GNU * 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 * General Public License version 3 as published by the Free Software
* Foundation. * Foundation.
* *
* Licensees holding a valid commercial license may use this software * Licensees holding a valid commercial license may use this software
* in accordance with the commercial license agreement provided in * in accordance with the commercial license agreement provided in
* conjunction with the software. The terms and conditions of any such * conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render * commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software, * ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or * notwithstanding of any reference thereto in the software or
* associated repository. * associated repository.
*/ */
#ifndef FUSE_COMMON_H_ #ifndef FUSE_COMMON_H_
#define FUSE_COMMON_H_ #define FUSE_COMMON_H_
#include "winfsp_fuse.h" #include "winfsp_fuse.h"
#include "fuse_opt.h" #include "fuse_opt.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
#define FUSE_MAJOR_VERSION 2 #define FUSE_MAJOR_VERSION 2
#define FUSE_MINOR_VERSION 8 #define FUSE_MINOR_VERSION 8
#define FUSE_MAKE_VERSION(maj, min) ((maj) * 10 + (min)) #define FUSE_MAKE_VERSION(maj, min) ((maj) * 10 + (min))
#define FUSE_VERSION FUSE_MAKE_VERSION(FUSE_MAJOR_VERSION, FUSE_MINOR_VERSION) #define FUSE_VERSION FUSE_MAKE_VERSION(FUSE_MAJOR_VERSION, FUSE_MINOR_VERSION)
#define FUSE_CAP_ASYNC_READ (1 << 0) #define FUSE_CAP_ASYNC_READ (1 << 0)
#define FUSE_CAP_POSIX_LOCKS (1 << 1) #define FUSE_CAP_POSIX_LOCKS (1 << 1)
#define FUSE_CAP_ATOMIC_O_TRUNC (1 << 3) #define FUSE_CAP_ATOMIC_O_TRUNC (1 << 3)
#define FUSE_CAP_EXPORT_SUPPORT (1 << 4) #define FUSE_CAP_EXPORT_SUPPORT (1 << 4)
#define FUSE_CAP_BIG_WRITES (1 << 5) #define FUSE_CAP_BIG_WRITES (1 << 5)
#define FUSE_CAP_DONT_MASK (1 << 6) #define FUSE_CAP_DONT_MASK (1 << 6)
#define FUSE_CAP_ALLOCATE (1 << 27) /* reserved (OSXFUSE) */ #define FUSE_CAP_ALLOCATE (1 << 27) /* reserved (OSXFUSE) */
#define FUSE_CAP_EXCHANGE_DATA (1 << 28) /* 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_CASE_INSENSITIVE (1 << 29) /* file system is case insensitive */
#define FUSE_CAP_VOL_RENAME (1 << 30) /* reserved (OSXFUSE) */ #define FUSE_CAP_VOL_RENAME (1 << 30) /* reserved (OSXFUSE) */
#define FUSE_CAP_XTIMES (1 << 31) /* 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_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_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_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_DELETE_ACCESS (1 << 24) /* file system supports access with DELETE_OK */
#define FSP_FUSE_CAP_CASE_INSENSITIVE FUSE_CAP_CASE_INSENSITIVE #define FSP_FUSE_CAP_CASE_INSENSITIVE FUSE_CAP_CASE_INSENSITIVE
#define FUSE_IOCTL_COMPAT (1 << 0) #define FUSE_IOCTL_COMPAT (1 << 0)
#define FUSE_IOCTL_UNRESTRICTED (1 << 1) #define FUSE_IOCTL_UNRESTRICTED (1 << 1)
#define FUSE_IOCTL_RETRY (1 << 2) #define FUSE_IOCTL_RETRY (1 << 2)
#define FUSE_IOCTL_MAX_IOV 256 #define FUSE_IOCTL_MAX_IOV 256
/* from FreeBSD */ /* from FreeBSD */
#define FSP_FUSE_UF_HIDDEN 0x00008000 #define FSP_FUSE_UF_HIDDEN 0x00008000
#define FSP_FUSE_UF_READONLY 0x00001000 #define FSP_FUSE_UF_READONLY 0x00001000
#define FSP_FUSE_UF_SYSTEM 0x00000080 #define FSP_FUSE_UF_SYSTEM 0x00000080
#define FSP_FUSE_UF_ARCHIVE 0x00000800 #define FSP_FUSE_UF_ARCHIVE 0x00000800
#if !defined(UF_HIDDEN) #if !defined(UF_HIDDEN)
#define UF_HIDDEN FSP_FUSE_UF_HIDDEN #define UF_HIDDEN FSP_FUSE_UF_HIDDEN
#endif #endif
#if !defined(UF_READONLY) #if !defined(UF_READONLY)
#define UF_READONLY FSP_FUSE_UF_READONLY #define UF_READONLY FSP_FUSE_UF_READONLY
#endif #endif
#if !defined(UF_SYSTEM) #if !defined(UF_SYSTEM)
#define UF_SYSTEM FSP_FUSE_UF_SYSTEM #define UF_SYSTEM FSP_FUSE_UF_SYSTEM
#endif #endif
#if !defined(UF_ARCHIVE) #if !defined(UF_ARCHIVE)
#define UF_ARCHIVE FSP_FUSE_UF_ARCHIVE #define UF_ARCHIVE FSP_FUSE_UF_ARCHIVE
#endif #endif
/* delete access */ /* delete access */
#define FSP_FUSE_DELETE_OK 0x40000000 #define FSP_FUSE_DELETE_OK 0x40000000
/* notify extension */ /* notify extension */
#define FSP_FUSE_NOTIFY_MKDIR 0x0001 #define FSP_FUSE_NOTIFY_MKDIR 0x0001
#define FSP_FUSE_NOTIFY_RMDIR 0x0002 #define FSP_FUSE_NOTIFY_RMDIR 0x0002
#define FSP_FUSE_NOTIFY_CREATE 0x0004 #define FSP_FUSE_NOTIFY_CREATE 0x0004
#define FSP_FUSE_NOTIFY_UNLINK 0x0008 #define FSP_FUSE_NOTIFY_UNLINK 0x0008
#define FSP_FUSE_NOTIFY_CHMOD 0x0010 #define FSP_FUSE_NOTIFY_CHMOD 0x0010
#define FSP_FUSE_NOTIFY_CHOWN 0x0020 #define FSP_FUSE_NOTIFY_CHOWN 0x0020
#define FSP_FUSE_NOTIFY_UTIME 0x0040 #define FSP_FUSE_NOTIFY_UTIME 0x0040
#define FSP_FUSE_NOTIFY_CHFLAGS 0x0080 #define FSP_FUSE_NOTIFY_CHFLAGS 0x0080
#define FSP_FUSE_NOTIFY_TRUNCATE 0x0100 #define FSP_FUSE_NOTIFY_TRUNCATE 0x0100
/* getpath extension */ /* getpath extension */
#define FSP_FUSE_HAS_GETPATH 1 #define FSP_FUSE_HAS_GETPATH 1
struct fuse_file_info struct fuse_file_info
{ {
int flags; int flags;
unsigned int fh_old; unsigned int fh_old;
int writepage; int writepage;
unsigned int direct_io:1; unsigned int direct_io:1;
unsigned int keep_cache:1; unsigned int keep_cache:1;
unsigned int flush:1; unsigned int flush:1;
unsigned int nonseekable:1; unsigned int nonseekable:1;
unsigned int padding:28; unsigned int padding:28;
uint64_t fh; uint64_t fh;
uint64_t lock_owner; uint64_t lock_owner;
}; };
struct fuse_conn_info struct fuse_conn_info
{ {
unsigned proto_major; unsigned proto_major;
unsigned proto_minor; unsigned proto_minor;
unsigned async_read; unsigned async_read;
unsigned max_write; unsigned max_write;
unsigned max_readahead; unsigned max_readahead;
unsigned capable; unsigned capable;
unsigned want; unsigned want;
unsigned reserved[25]; unsigned reserved[25];
}; };
struct fuse_session; struct fuse_session;
struct fuse_chan; struct fuse_chan;
struct fuse_pollhandle; struct fuse_pollhandle;
struct fuse_bufvec; struct fuse_bufvec;
struct fuse_statfs; struct fuse_statfs;
struct fuse_setattr_x; struct fuse_setattr_x;
FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse_version)(struct fsp_fuse_env *env); 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, 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); const char *mountpoint, struct fuse_args *args);
FSP_FUSE_API void FSP_FUSE_API_NAME(fsp_fuse_unmount)(struct fsp_fuse_env *env, FSP_FUSE_API void FSP_FUSE_API_NAME(fsp_fuse_unmount)(struct fsp_fuse_env *env,
const char *mountpoint, struct fuse_chan *ch); const char *mountpoint, struct fuse_chan *ch);
FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse_parse_cmdline)(struct fsp_fuse_env *env, FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse_parse_cmdline)(struct fsp_fuse_env *env,
struct fuse_args *args, struct fuse_args *args,
char **mountpoint, int *multithreaded, int *foreground); 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, FSP_FUSE_API int32_t FSP_FUSE_API_NAME(fsp_fuse_ntstatus_from_errno)(struct fsp_fuse_env *env,
int err); int err);
FSP_FUSE_SYM( FSP_FUSE_SYM(
int fuse_version(void), int fuse_version(void),
{ {
return FSP_FUSE_API_CALL(fsp_fuse_version) return FSP_FUSE_API_CALL(fsp_fuse_version)
(fsp_fuse_env()); (fsp_fuse_env());
}) })
FSP_FUSE_SYM( FSP_FUSE_SYM(
struct fuse_chan *fuse_mount(const char *mountpoint, struct fuse_args *args), struct fuse_chan *fuse_mount(const char *mountpoint, struct fuse_args *args),
{ {
return FSP_FUSE_API_CALL(fsp_fuse_mount) return FSP_FUSE_API_CALL(fsp_fuse_mount)
(fsp_fuse_env(), mountpoint, args); (fsp_fuse_env(), mountpoint, args);
}) })
FSP_FUSE_SYM( FSP_FUSE_SYM(
void fuse_unmount(const char *mountpoint, struct fuse_chan *ch), void fuse_unmount(const char *mountpoint, struct fuse_chan *ch),
{ {
FSP_FUSE_API_CALL(fsp_fuse_unmount) FSP_FUSE_API_CALL(fsp_fuse_unmount)
(fsp_fuse_env(), mountpoint, ch); (fsp_fuse_env(), mountpoint, ch);
}) })
FSP_FUSE_SYM( FSP_FUSE_SYM(
int fuse_parse_cmdline(struct fuse_args *args, int fuse_parse_cmdline(struct fuse_args *args,
char **mountpoint, int *multithreaded, int *foreground), char **mountpoint, int *multithreaded, int *foreground),
{ {
return FSP_FUSE_API_CALL(fsp_fuse_parse_cmdline) return FSP_FUSE_API_CALL(fsp_fuse_parse_cmdline)
(fsp_fuse_env(), args, mountpoint, multithreaded, foreground); (fsp_fuse_env(), args, mountpoint, multithreaded, foreground);
}) })
FSP_FUSE_SYM( FSP_FUSE_SYM(
void fuse_pollhandle_destroy(struct fuse_pollhandle *ph), void fuse_pollhandle_destroy(struct fuse_pollhandle *ph),
{ {
(void)ph; (void)ph;
}) })
FSP_FUSE_SYM( FSP_FUSE_SYM(
int fuse_daemonize(int foreground), int fuse_daemonize(int foreground),
{ {
return fsp_fuse_daemonize(foreground); return fsp_fuse_daemonize(foreground);
}) })
FSP_FUSE_SYM( FSP_FUSE_SYM(
int fuse_set_signal_handlers(struct fuse_session *se), int fuse_set_signal_handlers(struct fuse_session *se),
{ {
return fsp_fuse_set_signal_handlers(se); return fsp_fuse_set_signal_handlers(se);
}) })
FSP_FUSE_SYM( FSP_FUSE_SYM(
void fuse_remove_signal_handlers(struct fuse_session *se), void fuse_remove_signal_handlers(struct fuse_session *se),
{ {
(void)se; (void)se;
fsp_fuse_set_signal_handlers(0); fsp_fuse_set_signal_handlers(0);
}) })
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif #endif

View File

@@ -1,133 +1,133 @@
/** /**
* @file fuse/fuse_opt.h * @file fuse/fuse_opt.h
* WinFsp FUSE compatible API. * WinFsp FUSE compatible API.
* *
* This file is derived from libfuse/include/fuse_opt.h: * This file is derived from libfuse/include/fuse_opt.h:
* FUSE: Filesystem in Userspace * FUSE: Filesystem in Userspace
* Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu> * Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
* *
* @copyright 2015-2022 Bill Zissimopoulos * @copyright 2015-2025 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
* *
* You can redistribute it and/or modify it under the terms of the GNU * 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 * General Public License version 3 as published by the Free Software
* Foundation. * Foundation.
* *
* Licensees holding a valid commercial license may use this software * Licensees holding a valid commercial license may use this software
* in accordance with the commercial license agreement provided in * in accordance with the commercial license agreement provided in
* conjunction with the software. The terms and conditions of any such * conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render * commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software, * ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or * notwithstanding of any reference thereto in the software or
* associated repository. * associated repository.
*/ */
#ifndef FUSE_OPT_H_ #ifndef FUSE_OPT_H_
#define FUSE_OPT_H_ #define FUSE_OPT_H_
#include "winfsp_fuse.h" #include "winfsp_fuse.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
#define FUSE_OPT_KEY(templ, key) { templ, -1, key } #define FUSE_OPT_KEY(templ, key) { templ, -1, key }
#define FUSE_OPT_END { NULL, 0, 0 } #define FUSE_OPT_END { NULL, 0, 0 }
#define FUSE_OPT_KEY_OPT -1 #define FUSE_OPT_KEY_OPT -1
#define FUSE_OPT_KEY_NONOPT -2 #define FUSE_OPT_KEY_NONOPT -2
#define FUSE_OPT_KEY_KEEP -3 #define FUSE_OPT_KEY_KEEP -3
#define FUSE_OPT_KEY_DISCARD -4 #define FUSE_OPT_KEY_DISCARD -4
#define FUSE_ARGS_INIT(argc, argv) { argc, argv, 0 } #define FUSE_ARGS_INIT(argc, argv) { argc, argv, 0 }
struct fuse_opt struct fuse_opt
{ {
const char *templ; const char *templ;
unsigned int offset; unsigned int offset;
int value; int value;
}; };
struct fuse_args struct fuse_args
{ {
int argc; int argc;
char **argv; char **argv;
int allocated; int allocated;
}; };
typedef int (*fuse_opt_proc_t)(void *data, const char *arg, int key, typedef int (*fuse_opt_proc_t)(void *data, const char *arg, int key,
struct fuse_args *outargs); struct fuse_args *outargs);
FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse_opt_parse)(struct fsp_fuse_env *env, FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse_opt_parse)(struct fsp_fuse_env *env,
struct fuse_args *args, void *data, struct fuse_args *args, void *data,
const struct fuse_opt opts[], fuse_opt_proc_t proc); 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, 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); 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, 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); 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, FSP_FUSE_API void FSP_FUSE_API_NAME(fsp_fuse_opt_free_args)(struct fsp_fuse_env *env,
struct fuse_args *args); struct fuse_args *args);
FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse_opt_add_opt)(struct fsp_fuse_env *env, FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse_opt_add_opt)(struct fsp_fuse_env *env,
char **opts, const char *opt); char **opts, const char *opt);
FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse_opt_add_opt_escaped)(struct fsp_fuse_env *env, FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse_opt_add_opt_escaped)(struct fsp_fuse_env *env,
char **opts, const char *opt); char **opts, const char *opt);
FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse_opt_match)(struct fsp_fuse_env *env, 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); const struct fuse_opt opts[], const char *opt);
FSP_FUSE_SYM( FSP_FUSE_SYM(
int fuse_opt_parse(struct fuse_args *args, void *data, int fuse_opt_parse(struct fuse_args *args, void *data,
const struct fuse_opt opts[], fuse_opt_proc_t proc), const struct fuse_opt opts[], fuse_opt_proc_t proc),
{ {
return FSP_FUSE_API_CALL(fsp_fuse_opt_parse) return FSP_FUSE_API_CALL(fsp_fuse_opt_parse)
(fsp_fuse_env(), args, data, opts, proc); (fsp_fuse_env(), args, data, opts, proc);
}) })
FSP_FUSE_SYM( FSP_FUSE_SYM(
int fuse_opt_add_arg(struct fuse_args *args, const char *arg), int fuse_opt_add_arg(struct fuse_args *args, const char *arg),
{ {
return FSP_FUSE_API_CALL(fsp_fuse_opt_add_arg) return FSP_FUSE_API_CALL(fsp_fuse_opt_add_arg)
(fsp_fuse_env(), args, arg); (fsp_fuse_env(), args, arg);
}) })
FSP_FUSE_SYM( FSP_FUSE_SYM(
int fuse_opt_insert_arg(struct fuse_args *args, int pos, const char *arg), int fuse_opt_insert_arg(struct fuse_args *args, int pos, const char *arg),
{ {
return FSP_FUSE_API_CALL(fsp_fuse_opt_insert_arg) return FSP_FUSE_API_CALL(fsp_fuse_opt_insert_arg)
(fsp_fuse_env(), args, pos, arg); (fsp_fuse_env(), args, pos, arg);
}) })
FSP_FUSE_SYM( FSP_FUSE_SYM(
void fuse_opt_free_args(struct fuse_args *args), void fuse_opt_free_args(struct fuse_args *args),
{ {
FSP_FUSE_API_CALL(fsp_fuse_opt_free_args) FSP_FUSE_API_CALL(fsp_fuse_opt_free_args)
(fsp_fuse_env(), args); (fsp_fuse_env(), args);
}) })
FSP_FUSE_SYM( FSP_FUSE_SYM(
int fuse_opt_add_opt(char **opts, const char *opt), int fuse_opt_add_opt(char **opts, const char *opt),
{ {
return FSP_FUSE_API_CALL(fsp_fuse_opt_add_opt) return FSP_FUSE_API_CALL(fsp_fuse_opt_add_opt)
(fsp_fuse_env(), opts, opt); (fsp_fuse_env(), opts, opt);
}) })
FSP_FUSE_SYM( FSP_FUSE_SYM(
int fuse_opt_add_opt_escaped(char **opts, const char *opt), int fuse_opt_add_opt_escaped(char **opts, const char *opt),
{ {
return FSP_FUSE_API_CALL(fsp_fuse_opt_add_opt_escaped) return FSP_FUSE_API_CALL(fsp_fuse_opt_add_opt_escaped)
(fsp_fuse_env(), opts, opt); (fsp_fuse_env(), opts, opt);
}) })
FSP_FUSE_SYM( FSP_FUSE_SYM(
int fuse_opt_match(const struct fuse_opt opts[], const char *opt), int fuse_opt_match(const struct fuse_opt opts[], const char *opt),
{ {
return FSP_FUSE_API_CALL(fsp_fuse_opt_match) return FSP_FUSE_API_CALL(fsp_fuse_opt_match)
(fsp_fuse_env(), opts, opt); (fsp_fuse_env(), opts, opt);
}) })
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif #endif

View File

@@ -1,434 +1,435 @@
/** /**
* @file fuse/winfsp_fuse.h * @file fuse/winfsp_fuse.h
* WinFsp FUSE compatible API. * WinFsp FUSE compatible API.
* *
* @copyright 2015-2022 Bill Zissimopoulos * @copyright 2015-2025 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
* *
* You can redistribute it and/or modify it under the terms of the GNU * 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 * General Public License version 3 as published by the Free Software
* Foundation. * Foundation.
* *
* Licensees holding a valid commercial license may use this software * Licensees holding a valid commercial license may use this software
* in accordance with the commercial license agreement provided in * in accordance with the commercial license agreement provided in
* conjunction with the software. The terms and conditions of any such * conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render * commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software, * ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or * notwithstanding of any reference thereto in the software or
* associated repository. * associated repository.
*/ */
#ifndef FUSE_WINFSP_FUSE_H_INCLUDED #ifndef FUSE_WINFSP_FUSE_H_INCLUDED
#define FUSE_WINFSP_FUSE_H_INCLUDED #define FUSE_WINFSP_FUSE_H_INCLUDED
#include <errno.h> #include <errno.h>
#include <stdint.h> #include <stdint.h>
#if !defined(WINFSP_DLL_INTERNAL) #if !defined(WINFSP_DLL_INTERNAL)
#include <stdlib.h> #include <stdlib.h>
#endif #include <string.h>
#endif
#ifdef __cplusplus
extern "C" { #ifdef __cplusplus
#endif extern "C" {
#endif
#if !defined(FSP_FUSE_API)
#if defined(WINFSP_DLL_INTERNAL) #if !defined(FSP_FUSE_API)
#define FSP_FUSE_API __declspec(dllexport) #if defined(WINFSP_DLL_INTERNAL)
#else #define FSP_FUSE_API __declspec(dllexport)
#define FSP_FUSE_API __declspec(dllimport) #else
#endif #define FSP_FUSE_API __declspec(dllimport)
#endif #endif
#endif
#if !defined(FSP_FUSE_API_NAME)
#define FSP_FUSE_API_NAME(n) (n) #if !defined(FSP_FUSE_API_NAME)
#endif #define FSP_FUSE_API_NAME(n) (n)
#endif
#if !defined(FSP_FUSE_API_CALL)
#define FSP_FUSE_API_CALL(n) (n) #if !defined(FSP_FUSE_API_CALL)
#endif #define FSP_FUSE_API_CALL(n) (n)
#endif
#if !defined(FSP_FUSE_SYM)
#if !defined(CYGFUSE) #if !defined(FSP_FUSE_SYM)
#define FSP_FUSE_SYM(proto, ...) static inline proto { __VA_ARGS__ } #if !defined(CYGFUSE)
#else #define FSP_FUSE_SYM(proto, ...) static inline proto { __VA_ARGS__ }
#define FSP_FUSE_SYM(proto, ...) proto; #else
#endif #define FSP_FUSE_SYM(proto, ...) proto;
#endif #endif
#endif
#define FSP_FUSE_DEVICE_TYPE (0x8000 | 'W' | 'F' * 0x100) /* DeviceIoControl -> ioctl */
#define FSP_FUSE_CTLCODE_FROM_IOCTL(cmd)\ #define FSP_FUSE_DEVICE_TYPE (0x8000 | 'W' | 'F' * 0x100) /* DeviceIoControl -> ioctl */
(FSP_FUSE_DEVICE_TYPE << 16) | (((cmd) & 0x0fff) << 2) #define FSP_FUSE_CTLCODE_FROM_IOCTL(cmd)\
#define FSP_FUSE_IOCTL(cmd, isiz, osiz) \ (FSP_FUSE_DEVICE_TYPE << 16) | (((cmd) & 0x0fff) << 2)
( \ #define FSP_FUSE_IOCTL(cmd, isiz, osiz) \
(((osiz) != 0) << 31) | \ ( \
(((isiz) != 0) << 30) | \ (((osiz) != 0) << 31) | \
(((isiz) | (osiz)) << 16) | \ (((isiz) != 0) << 30) | \
(cmd) \ (((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 * FUSE uses a number of types (notably: struct stat) that are OS specific.
* within the same OS. This is certainly true on Windows, where these types * Furthermore there are sometimes multiple definitions of the same type even
* are not even native. * 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 * For this reason we will define our own fuse_* types which represent the
* to be compatible with the equivalent Cygwin types as we want WinFsp-FUSE * types as the WinFsp DLL expects to see them. We will define these types
* to be usable from Cygwin. * 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; \ #define FSP_FUSE_STAT_FIELD_DEFN \
fuse_ino_t st_ino; \ fuse_dev_t st_dev; \
fuse_mode_t st_mode; \ fuse_ino_t st_ino; \
fuse_nlink_t st_nlink; \ fuse_mode_t st_mode; \
fuse_uid_t st_uid; \ fuse_nlink_t st_nlink; \
fuse_gid_t st_gid; \ fuse_uid_t st_uid; \
fuse_dev_t st_rdev; \ fuse_gid_t st_gid; \
fuse_off_t st_size; \ fuse_dev_t st_rdev; \
struct fuse_timespec st_atim; \ fuse_off_t st_size; \
struct fuse_timespec st_mtim; \ struct fuse_timespec st_atim; \
struct fuse_timespec st_ctim; \ struct fuse_timespec st_mtim; \
fuse_blksize_t st_blksize; \ struct fuse_timespec st_ctim; \
fuse_blkcnt_t st_blocks; \ fuse_blksize_t st_blksize; \
struct fuse_timespec st_birthtim; fuse_blkcnt_t st_blocks; \
#define FSP_FUSE_STAT_EX_FIELD_DEFN \ struct fuse_timespec st_birthtim;
FSP_FUSE_STAT_FIELD_DEFN \ #define FSP_FUSE_STAT_EX_FIELD_DEFN \
uint32_t st_flags; \ FSP_FUSE_STAT_FIELD_DEFN \
uint32_t st_reserved32[3]; \ uint32_t st_flags; \
uint64_t st_reserved64[2]; uint32_t st_reserved32[3]; \
uint64_t st_reserved64[2];
#if defined(_WIN64) || defined(_WIN32)
#if defined(_WIN64) || defined(_WIN32)
typedef uint32_t fuse_uid_t;
typedef uint32_t fuse_gid_t; typedef uint32_t fuse_uid_t;
typedef int32_t fuse_pid_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_dev_t;
typedef uint32_t fuse_mode_t; typedef uint64_t fuse_ino_t;
typedef uint16_t fuse_nlink_t; typedef uint32_t fuse_mode_t;
typedef int64_t fuse_off_t; typedef uint16_t fuse_nlink_t;
typedef int64_t fuse_off_t;
#if defined(_WIN64)
typedef uint64_t fuse_fsblkcnt_t; #if defined(_WIN64)
typedef uint64_t fuse_fsfilcnt_t; typedef uint64_t fuse_fsblkcnt_t;
#else typedef uint64_t fuse_fsfilcnt_t;
typedef uint32_t fuse_fsblkcnt_t; #else
typedef uint32_t fuse_fsfilcnt_t; typedef uint32_t fuse_fsblkcnt_t;
#endif typedef uint32_t fuse_fsfilcnt_t;
typedef int32_t fuse_blksize_t; #endif
typedef int64_t fuse_blkcnt_t; typedef int32_t fuse_blksize_t;
typedef int64_t fuse_blkcnt_t;
#if defined(_WIN64)
struct fuse_utimbuf #if defined(_WIN64)
{ struct fuse_utimbuf
int64_t actime; {
int64_t modtime; int64_t actime;
}; int64_t modtime;
struct fuse_timespec };
{ struct fuse_timespec
int64_t tv_sec; {
int64_t tv_nsec; int64_t tv_sec;
}; int64_t tv_nsec;
#else };
struct fuse_utimbuf #else
{ struct fuse_utimbuf
int32_t actime; {
int32_t modtime; int32_t actime;
}; int32_t modtime;
struct fuse_timespec };
{ struct fuse_timespec
int32_t tv_sec; {
int32_t tv_nsec; int32_t tv_sec;
}; int32_t tv_nsec;
#endif };
#endif
#if !defined(FSP_FUSE_USE_STAT_EX)
struct fuse_stat #if !defined(FSP_FUSE_USE_STAT_EX)
{ struct fuse_stat
FSP_FUSE_STAT_FIELD_DEFN {
}; FSP_FUSE_STAT_FIELD_DEFN
#else };
struct fuse_stat #else
{ struct fuse_stat
FSP_FUSE_STAT_EX_FIELD_DEFN {
}; FSP_FUSE_STAT_EX_FIELD_DEFN
#endif };
#endif
#if defined(_WIN64)
struct fuse_statvfs #if defined(_WIN64)
{ struct fuse_statvfs
uint64_t f_bsize; {
uint64_t f_frsize; uint64_t f_bsize;
fuse_fsblkcnt_t f_blocks; uint64_t f_frsize;
fuse_fsblkcnt_t f_bfree; fuse_fsblkcnt_t f_blocks;
fuse_fsblkcnt_t f_bavail; fuse_fsblkcnt_t f_bfree;
fuse_fsfilcnt_t f_files; fuse_fsblkcnt_t f_bavail;
fuse_fsfilcnt_t f_ffree; fuse_fsfilcnt_t f_files;
fuse_fsfilcnt_t f_favail; fuse_fsfilcnt_t f_ffree;
uint64_t f_fsid; fuse_fsfilcnt_t f_favail;
uint64_t f_flag; uint64_t f_fsid;
uint64_t f_namemax; uint64_t f_flag;
}; uint64_t f_namemax;
#else };
struct fuse_statvfs #else
{ struct fuse_statvfs
uint32_t f_bsize; {
uint32_t f_frsize; uint32_t f_bsize;
fuse_fsblkcnt_t f_blocks; uint32_t f_frsize;
fuse_fsblkcnt_t f_bfree; fuse_fsblkcnt_t f_blocks;
fuse_fsblkcnt_t f_bavail; fuse_fsblkcnt_t f_bfree;
fuse_fsfilcnt_t f_files; fuse_fsblkcnt_t f_bavail;
fuse_fsfilcnt_t f_ffree; fuse_fsfilcnt_t f_files;
fuse_fsfilcnt_t f_favail; fuse_fsfilcnt_t f_ffree;
uint32_t f_fsid; fuse_fsfilcnt_t f_favail;
uint32_t f_flag; uint32_t f_fsid;
uint32_t f_namemax; uint32_t f_flag;
}; uint32_t f_namemax;
#endif };
#endif
struct fuse_flock
{ struct fuse_flock
int16_t l_type; {
int16_t l_whence; int16_t l_type;
fuse_off_t l_start; int16_t l_whence;
fuse_off_t l_len; fuse_off_t l_start;
fuse_pid_t l_pid; fuse_off_t l_len;
}; fuse_pid_t l_pid;
};
#if defined(WINFSP_DLL_INTERNAL)
#define FSP_FUSE_ENV_INIT \ #if defined(WINFSP_DLL_INTERNAL)
{ \ #define FSP_FUSE_ENV_INIT \
'W', \ { \
MemAlloc, MemFree, \ 'W', \
fsp_fuse_daemonize, \ MemAlloc, MemFree, \
fsp_fuse_set_signal_handlers, \ fsp_fuse_daemonize, \
0/*conv_to_win_path*/, \ fsp_fuse_set_signal_handlers, \
0/*winpid_to_pid*/, \ 0/*conv_to_win_path*/, \
{ 0 }, \ 0/*winpid_to_pid*/, \
} { 0 }, \
#else }
#define FSP_FUSE_ENV_INIT \ #else
{ \ #define FSP_FUSE_ENV_INIT \
'W', \ { \
malloc, free, \ 'W', \
fsp_fuse_daemonize, \ malloc, free, \
fsp_fuse_set_signal_handlers, \ fsp_fuse_daemonize, \
0/*conv_to_win_path*/, \ fsp_fuse_set_signal_handlers, \
0/*winpid_to_pid*/, \ 0/*conv_to_win_path*/, \
{ 0 }, \ 0/*winpid_to_pid*/, \
} { 0 }, \
#endif }
#endif
#elif defined(__CYGWIN__)
#elif defined(__CYGWIN__)
#include <fcntl.h>
#include <pthread.h> #include <fcntl.h>
#include <signal.h> #include <pthread.h>
#include <sys/stat.h> #include <signal.h>
#include <sys/statvfs.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/statvfs.h>
#include <utime.h> #include <sys/types.h>
#include <utime.h>
#define fuse_uid_t uid_t
#define fuse_gid_t gid_t #define fuse_uid_t uid_t
#define fuse_pid_t pid_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_dev_t dev_t
#define fuse_mode_t mode_t #define fuse_ino_t ino_t
#define fuse_nlink_t nlink_t #define fuse_mode_t mode_t
#define fuse_off_t off_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_fsblkcnt_t fsblkcnt_t
#define fuse_blksize_t blksize_t #define fuse_fsfilcnt_t fsfilcnt_t
#define fuse_blkcnt_t blkcnt_t #define fuse_blksize_t blksize_t
#define fuse_blkcnt_t blkcnt_t
#define fuse_utimbuf utimbuf
#define fuse_timespec timespec #define fuse_utimbuf utimbuf
#define fuse_timespec timespec
#if !defined(FSP_FUSE_USE_STAT_EX)
#define fuse_stat stat #if !defined(FSP_FUSE_USE_STAT_EX)
#else #define fuse_stat stat
struct fuse_stat #else
{ struct fuse_stat
FSP_FUSE_STAT_EX_FIELD_DEFN {
}; FSP_FUSE_STAT_EX_FIELD_DEFN
#endif };
#define fuse_statvfs statvfs #endif
#define fuse_flock flock #define fuse_statvfs statvfs
#define fuse_flock flock
#define FSP_FUSE_ENV_INIT \
{ \ #define FSP_FUSE_ENV_INIT \
'C', \ { \
malloc, free, \ 'C', \
fsp_fuse_daemonize, \ malloc, free, \
fsp_fuse_set_signal_handlers, \ fsp_fuse_daemonize, \
fsp_fuse_conv_to_win_path, \ fsp_fuse_set_signal_handlers, \
fsp_fuse_winpid_to_pid, \ fsp_fuse_conv_to_win_path, \
{ 0 }, \ 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. * 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 #else
#endif #error unsupported environment
#endif
struct fuse_stat_ex
{ struct fuse_stat_ex
FSP_FUSE_STAT_EX_FIELD_DEFN {
}; FSP_FUSE_STAT_EX_FIELD_DEFN
};
struct fsp_fuse_env
{ struct fsp_fuse_env
unsigned environment; {
void *(*memalloc)(size_t); unsigned environment;
void (*memfree)(void *); void *(*memalloc)(size_t);
int (*daemonize)(int); void (*memfree)(void *);
int (*set_signal_handlers)(void *); int (*daemonize)(int);
char *(*conv_to_win_path)(const char *); int (*set_signal_handlers)(void *);
fuse_pid_t (*winpid_to_pid)(uint32_t); char *(*conv_to_win_path)(const char *);
void (*reserved[2])(); 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);
FSP_FUSE_API void FSP_FUSE_API_NAME(fsp_fuse_signal_handler)(int sig);
#if defined(_WIN64) || defined(_WIN32)
#if defined(_WIN64) || defined(_WIN32)
static inline int fsp_fuse_daemonize(int foreground)
{ static inline int fsp_fuse_daemonize(int foreground)
(void)foreground; {
return 0; (void)foreground;
} return 0;
}
static inline int fsp_fuse_set_signal_handlers(void *se)
{ static inline int fsp_fuse_set_signal_handlers(void *se)
(void)se; {
return 0; (void)se;
} return 0;
}
#elif defined(__CYGWIN__)
#elif defined(__CYGWIN__)
static inline int fsp_fuse_daemonize(int foreground)
{ static inline int fsp_fuse_daemonize(int foreground)
int daemon(int nochdir, int noclose); {
int chdir(const char *path); int daemon(int nochdir, int noclose);
int chdir(const char *path);
if (!foreground)
{ if (!foreground)
if (-1 == daemon(0, 0)) {
return -1; if (-1 == daemon(0, 0))
} return -1;
else }
chdir("/"); else
chdir("/");
return 0;
} return 0;
}
static inline void *fsp_fuse_signal_thread(void *psigmask)
{ static inline void *fsp_fuse_signal_thread(void *psigmask)
int sig; {
int sig;
if (0 == sigwait((sigset_t *)psigmask, &sig))
FSP_FUSE_API_CALL(fsp_fuse_signal_handler)(sig); if (0 == sigwait((sigset_t *)psigmask, &sig))
FSP_FUSE_API_CALL(fsp_fuse_signal_handler)(sig);
return 0;
} return 0;
}
static inline int fsp_fuse_set_signal_handlers(void *se)
{ static inline int fsp_fuse_set_signal_handlers(void *se)
#define FSP_FUSE_SET_SIGNAL_HANDLER(sig, newha)\ {
if (-1 != sigaction((sig), 0, &oldsa) &&\ #define FSP_FUSE_SET_SIGNAL_HANDLER(sig, newha)\
oldsa.sa_handler == (se ? SIG_DFL : (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);\ newsa.sa_handler = se ? (newha) : SIG_DFL;\
} sigaction((sig), &newsa, 0);\
#define FSP_FUSE_SIGADDSET(sig)\ }
if (-1 != sigaction((sig), 0, &oldsa) &&\ #define FSP_FUSE_SIGADDSET(sig)\
oldsa.sa_handler == SIG_DFL)\ if (-1 != sigaction((sig), 0, &oldsa) &&\
sigaddset(&sigmask, (sig)); oldsa.sa_handler == SIG_DFL)\
sigaddset(&sigmask, (sig));
static sigset_t sigmask;
static pthread_t sigthr; static sigset_t sigmask;
struct sigaction oldsa, newsa; static pthread_t sigthr;
struct sigaction oldsa, newsa;
// memset instead of initializer to avoid GCC -Wmissing-field-initializers warning
memset(&newsa, 0, sizeof newsa); // memset instead of initializer to avoid GCC -Wmissing-field-initializers warning
memset(&newsa, 0, sizeof newsa);
if (0 != se)
{ if (0 != se)
if (0 == sigthr) {
{ if (0 == sigthr)
FSP_FUSE_SET_SIGNAL_HANDLER(SIGPIPE, SIG_IGN); {
FSP_FUSE_SET_SIGNAL_HANDLER(SIGPIPE, SIG_IGN);
sigemptyset(&sigmask);
FSP_FUSE_SIGADDSET(SIGHUP); sigemptyset(&sigmask);
FSP_FUSE_SIGADDSET(SIGINT); FSP_FUSE_SIGADDSET(SIGHUP);
FSP_FUSE_SIGADDSET(SIGTERM); FSP_FUSE_SIGADDSET(SIGINT);
if (0 != pthread_sigmask(SIG_BLOCK, &sigmask, 0)) FSP_FUSE_SIGADDSET(SIGTERM);
return -1; if (0 != pthread_sigmask(SIG_BLOCK, &sigmask, 0))
return -1;
if (0 != pthread_create(&sigthr, 0, fsp_fuse_signal_thread, &sigmask))
return -1; if (0 != pthread_create(&sigthr, 0, fsp_fuse_signal_thread, &sigmask))
} return -1;
} }
else }
{ else
if (0 != sigthr) {
{ if (0 != sigthr)
pthread_cancel(sigthr); {
pthread_join(sigthr, 0); pthread_cancel(sigthr);
sigthr = 0; pthread_join(sigthr, 0);
sigthr = 0;
if (0 != pthread_sigmask(SIG_UNBLOCK, &sigmask, 0))
return -1; if (0 != pthread_sigmask(SIG_UNBLOCK, &sigmask, 0))
sigemptyset(&sigmask); return -1;
sigemptyset(&sigmask);
FSP_FUSE_SET_SIGNAL_HANDLER(SIGPIPE, SIG_IGN);
} FSP_FUSE_SET_SIGNAL_HANDLER(SIGPIPE, SIG_IGN);
} }
}
return 0;
return 0;
#undef FSP_FUSE_SIGADDSET
#undef FSP_FUSE_SET_SIGNAL_HANDLER #undef FSP_FUSE_SIGADDSET
} #undef FSP_FUSE_SET_SIGNAL_HANDLER
}
static inline char *fsp_fuse_conv_to_win_path(const char *path)
{ static inline char *fsp_fuse_conv_to_win_path(const char *path)
void *cygwin_create_path(unsigned, const void *); {
return (char *)cygwin_create_path( void *cygwin_create_path(unsigned, const void *);
0/*CCP_POSIX_TO_WIN_A*/ | 0x100/*CCP_RELATIVE*/, return (char *)cygwin_create_path(
path); 0/*CCP_POSIX_TO_WIN_A*/ | 0x100/*CCP_RELATIVE*/,
} path);
}
static inline fuse_pid_t fsp_fuse_winpid_to_pid(uint32_t winpid)
{ 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); pid_t cygwin_winpid_to_pid(int winpid);
return -1 != pid ? pid : (fuse_pid_t)winpid; pid_t pid = cygwin_winpid_to_pid(winpid);
} return -1 != pid ? pid : (fuse_pid_t)winpid;
#endif }
#endif
static inline struct fsp_fuse_env *fsp_fuse_env(void)
{ static inline struct fsp_fuse_env *fsp_fuse_env(void)
static struct fsp_fuse_env env = FSP_FUSE_ENV_INIT; {
return &env; static struct fsp_fuse_env env = FSP_FUSE_ENV_INIT;
} return &env;
}
#ifdef __cplusplus
} #ifdef __cplusplus
#endif }
#endif
#endif
#endif

View File

@@ -1,338 +1,338 @@
/** /**
* @file fuse3/fuse.h * @file fuse3/fuse.h
* WinFsp FUSE3 compatible API. * WinFsp FUSE3 compatible API.
* *
* This file is derived from libfuse/include/fuse.h: * This file is derived from libfuse/include/fuse.h:
* FUSE: Filesystem in Userspace * FUSE: Filesystem in Userspace
* Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu> * Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
* *
* @copyright 2015-2022 Bill Zissimopoulos * @copyright 2015-2025 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
* *
* You can redistribute it and/or modify it under the terms of the GNU * 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 * General Public License version 3 as published by the Free Software
* Foundation. * Foundation.
* *
* Licensees holding a valid commercial license may use this software * Licensees holding a valid commercial license may use this software
* in accordance with the commercial license agreement provided in * in accordance with the commercial license agreement provided in
* conjunction with the software. The terms and conditions of any such * conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render * commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software, * ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or * notwithstanding of any reference thereto in the software or
* associated repository. * associated repository.
*/ */
#ifndef FUSE_H_ #ifndef FUSE_H_
#define FUSE_H_ #define FUSE_H_
#include "fuse_common.h" #include "fuse_common.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
struct fuse3; struct fuse3;
enum fuse3_readdir_flags enum fuse3_readdir_flags
{ {
FUSE_READDIR_PLUS = (1 << 0), FUSE_READDIR_PLUS = (1 << 0),
}; };
enum fuse3_fill_dir_flags enum fuse3_fill_dir_flags
{ {
FUSE_FILL_DIR_PLUS = (1 << 1), FUSE_FILL_DIR_PLUS = (1 << 1),
}; };
typedef int (*fuse3_fill_dir_t)(void *buf, const char *name, typedef int (*fuse3_fill_dir_t)(void *buf, const char *name,
const struct fuse_stat *stbuf, fuse_off_t off, const struct fuse_stat *stbuf, fuse_off_t off,
enum fuse3_fill_dir_flags flags); enum fuse3_fill_dir_flags flags);
struct fuse3_config struct fuse3_config
{ {
int set_gid; int set_gid;
unsigned int gid; unsigned int gid;
int set_uid; int set_uid;
unsigned int uid; unsigned int uid;
int set_mode; int set_mode;
unsigned int umask; unsigned int umask;
double entry_timeout; double entry_timeout;
double negative_timeout; double negative_timeout;
double attr_timeout; double attr_timeout;
int intr; int intr;
int intr_signal; int intr_signal;
int remember; int remember;
int hard_remove; int hard_remove;
int use_ino; int use_ino;
int readdir_ino; int readdir_ino;
int direct_io; int direct_io;
int kernel_cache; int kernel_cache;
int auto_cache; int auto_cache;
int ac_attr_timeout_set; int ac_attr_timeout_set;
double ac_attr_timeout; double ac_attr_timeout;
int nullpath_ok; int nullpath_ok;
/* private */ /* private */
int show_help; int show_help;
char *modules; char *modules;
int debug; int debug;
}; };
struct fuse3_operations struct fuse3_operations
{ {
/* S - supported by WinFsp */ /* S - supported by WinFsp */
/* S */ int (*getattr)(const char *path, struct fuse_stat *stbuf, /* S */ int (*getattr)(const char *path, struct fuse_stat *stbuf,
struct fuse3_file_info *fi); struct fuse3_file_info *fi);
/* S */ int (*readlink)(const char *path, char *buf, size_t size); /* 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 (*mknod)(const char *path, fuse_mode_t mode, fuse_dev_t dev);
/* S */ int (*mkdir)(const char *path, fuse_mode_t mode); /* S */ int (*mkdir)(const char *path, fuse_mode_t mode);
/* S */ int (*unlink)(const char *path); /* S */ int (*unlink)(const char *path);
/* S */ int (*rmdir)(const char *path); /* S */ int (*rmdir)(const char *path);
/* S */ int (*symlink)(const char *dstpath, const char *srcpath); /* S */ int (*symlink)(const char *dstpath, const char *srcpath);
/* S */ int (*rename)(const char *oldpath, const char *newpath, unsigned int flags); /* S */ int (*rename)(const char *oldpath, const char *newpath, unsigned int flags);
/* _ */ int (*link)(const char *srcpath, const char *dstpath); /* _ */ int (*link)(const char *srcpath, const char *dstpath);
/* S */ int (*chmod)(const char *path, fuse_mode_t mode, /* S */ int (*chmod)(const char *path, fuse_mode_t mode,
struct fuse3_file_info *fi); struct fuse3_file_info *fi);
/* S */ int (*chown)(const char *path, fuse_uid_t uid, fuse_gid_t gid, /* S */ int (*chown)(const char *path, fuse_uid_t uid, fuse_gid_t gid,
struct fuse3_file_info *fi); struct fuse3_file_info *fi);
/* S */ int (*truncate)(const char *path, fuse_off_t size, /* S */ int (*truncate)(const char *path, fuse_off_t size,
struct fuse3_file_info *fi); struct fuse3_file_info *fi);
/* S */ int (*open)(const char *path, 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, /* S */ int (*read)(const char *path, char *buf, size_t size, fuse_off_t off,
struct fuse3_file_info *fi); struct fuse3_file_info *fi);
/* S */ int (*write)(const char *path, const char *buf, size_t size, fuse_off_t off, /* S */ int (*write)(const char *path, const char *buf, size_t size, fuse_off_t off,
struct fuse3_file_info *fi); struct fuse3_file_info *fi);
/* S */ int (*statfs)(const char *path, struct fuse_statvfs *stbuf); /* S */ int (*statfs)(const char *path, struct fuse_statvfs *stbuf);
/* S */ int (*flush)(const char *path, struct fuse3_file_info *fi); /* S */ int (*flush)(const char *path, struct fuse3_file_info *fi);
/* S */ int (*release)(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 (*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, /* S */ int (*setxattr)(const char *path, const char *name, const char *value, size_t size,
int flags); int flags);
/* S */ int (*getxattr)(const char *path, const char *name, char *value, size_t size); /* 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 (*listxattr)(const char *path, char *namebuf, size_t size);
/* S */ int (*removexattr)(const char *path, const char *name); /* S */ int (*removexattr)(const char *path, const char *name);
/* S */ int (*opendir)(const char *path, struct fuse3_file_info *fi); /* 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, /* 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); struct fuse3_file_info *fi, enum fuse3_readdir_flags);
/* S */ int (*releasedir)(const char *path, struct fuse3_file_info *fi); /* 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 */ int (*fsyncdir)(const char *path, int datasync, struct fuse3_file_info *fi);
/* S */ void *(*init)(struct fuse3_conn_info *conn, /* S */ void *(*init)(struct fuse3_conn_info *conn,
struct fuse3_config *conf); struct fuse3_config *conf);
/* S */ void (*destroy)(void *data); /* S */ void (*destroy)(void *data);
/* _ */ int (*access)(const char *path, int mask); /* _ */ int (*access)(const char *path, int mask);
/* S */ int (*create)(const char *path, fuse_mode_t mode, struct fuse3_file_info *fi); /* S */ int (*create)(const char *path, fuse_mode_t mode, struct fuse3_file_info *fi);
/* _ */ int (*lock)(const char *path, /* _ */ int (*lock)(const char *path,
struct fuse3_file_info *fi, int cmd, struct fuse_flock *lock); struct fuse3_file_info *fi, int cmd, struct fuse_flock *lock);
/* S */ int (*utimens)(const char *path, const struct fuse_timespec tv[2], /* S */ int (*utimens)(const char *path, const struct fuse_timespec tv[2],
struct fuse3_file_info *fi); struct fuse3_file_info *fi);
/* _ */ int (*bmap)(const char *path, size_t blocksize, uint64_t *idx); /* _ */ 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, /* S */ int (*ioctl)(const char *path, int cmd, void *arg, struct fuse3_file_info *fi,
unsigned int flags, void *data); unsigned int flags, void *data);
/* _ */ int (*poll)(const char *path, struct fuse3_file_info *fi, /* _ */ int (*poll)(const char *path, struct fuse3_file_info *fi,
struct fuse3_pollhandle *ph, unsigned *reventsp); struct fuse3_pollhandle *ph, unsigned *reventsp);
/* _ */ int (*write_buf)(const char *path, /* _ */ int (*write_buf)(const char *path,
struct fuse3_bufvec *buf, fuse_off_t off, struct fuse3_file_info *fi); struct fuse3_bufvec *buf, fuse_off_t off, struct fuse3_file_info *fi);
/* _ */ int (*read_buf)(const char *path, /* _ */ int (*read_buf)(const char *path,
struct fuse3_bufvec **bufp, size_t size, fuse_off_t off, struct fuse3_file_info *fi); 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 (*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, /* _ */ int (*fallocate)(const char *path, int mode, fuse_off_t off, fuse_off_t len,
struct fuse3_file_info *fi); struct fuse3_file_info *fi);
}; };
struct fuse3_context struct fuse3_context
{ {
struct fuse3 *fuse; struct fuse3 *fuse;
fuse_uid_t uid; fuse_uid_t uid;
fuse_gid_t gid; fuse_gid_t gid;
fuse_pid_t pid; fuse_pid_t pid;
void *private_data; void *private_data;
fuse_mode_t umask; fuse_mode_t umask;
}; };
#define fuse_main(argc, argv, ops, data)\ #define fuse_main(argc, argv, ops, data)\
fuse3_main_real(argc, argv, ops, sizeof *(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, FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse3_main_real)(struct fsp_fuse_env *env,
int argc, char *argv[], int argc, char *argv[],
const struct fuse3_operations *ops, size_t opsize, void *data); 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, FSP_FUSE_API void FSP_FUSE_API_NAME(fsp_fuse3_lib_help)(struct fsp_fuse_env *env,
struct fuse_args *args); struct fuse_args *args);
FSP_FUSE_API struct fuse3 *FSP_FUSE_API_NAME(fsp_fuse3_new_30)(struct fsp_fuse_env *env, FSP_FUSE_API struct fuse3 *FSP_FUSE_API_NAME(fsp_fuse3_new_30)(struct fsp_fuse_env *env,
struct fuse_args *args, struct fuse_args *args,
const struct fuse3_operations *ops, size_t opsize, void *data); 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, FSP_FUSE_API struct fuse3 *FSP_FUSE_API_NAME(fsp_fuse3_new)(struct fsp_fuse_env *env,
struct fuse_args *args, struct fuse_args *args,
const struct fuse3_operations *ops, size_t opsize, void *data); 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, FSP_FUSE_API void FSP_FUSE_API_NAME(fsp_fuse3_destroy)(struct fsp_fuse_env *env,
struct fuse3 *f); struct fuse3 *f);
FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse3_mount)(struct fsp_fuse_env *env, FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse3_mount)(struct fsp_fuse_env *env,
struct fuse3 *f, const char *mountpoint); struct fuse3 *f, const char *mountpoint);
FSP_FUSE_API void FSP_FUSE_API_NAME(fsp_fuse3_unmount)(struct fsp_fuse_env *env, FSP_FUSE_API void FSP_FUSE_API_NAME(fsp_fuse3_unmount)(struct fsp_fuse_env *env,
struct fuse3 *f); struct fuse3 *f);
FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse3_loop)(struct fsp_fuse_env *env, FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse3_loop)(struct fsp_fuse_env *env,
struct fuse3 *f); struct fuse3 *f);
FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse3_loop_mt_31)(struct fsp_fuse_env *env, FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse3_loop_mt_31)(struct fsp_fuse_env *env,
struct fuse3 *f, int clone_fd); struct fuse3 *f, int clone_fd);
FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse3_loop_mt)(struct fsp_fuse_env *env, 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); struct fuse3 *f, struct fuse3_loop_config *config);
FSP_FUSE_API void FSP_FUSE_API_NAME(fsp_fuse3_exit)(struct fsp_fuse_env *env, FSP_FUSE_API void FSP_FUSE_API_NAME(fsp_fuse3_exit)(struct fsp_fuse_env *env,
struct fuse3 *f); struct fuse3 *f);
FSP_FUSE_API struct fuse3_context *FSP_FUSE_API_NAME(fsp_fuse3_get_context)(struct fsp_fuse_env *env); FSP_FUSE_API struct fuse3_context *FSP_FUSE_API_NAME(fsp_fuse3_get_context)(struct fsp_fuse_env *env);
FSP_FUSE_SYM( FSP_FUSE_SYM(
int fuse3_main_real(int argc, char *argv[], int fuse3_main_real(int argc, char *argv[],
const struct fuse3_operations *ops, size_t opsize, void *data), const struct fuse3_operations *ops, size_t opsize, void *data),
{ {
return FSP_FUSE_API_CALL(fsp_fuse3_main_real) return FSP_FUSE_API_CALL(fsp_fuse3_main_real)
(fsp_fuse_env(), argc, argv, ops, opsize, data); (fsp_fuse_env(), argc, argv, ops, opsize, data);
}) })
FSP_FUSE_SYM( FSP_FUSE_SYM(
void fuse3_lib_help(struct fuse_args *args), void fuse3_lib_help(struct fuse_args *args),
{ {
FSP_FUSE_API_CALL(fsp_fuse3_lib_help) FSP_FUSE_API_CALL(fsp_fuse3_lib_help)
(fsp_fuse_env(), args); (fsp_fuse_env(), args);
}) })
#if FUSE_USE_VERSION == 30 #if FUSE_USE_VERSION == 30
FSP_FUSE_SYM( FSP_FUSE_SYM(
struct fuse3 *fuse3_new_30(struct fuse_args *args, struct fuse3 *fuse3_new_30(struct fuse_args *args,
const struct fuse3_operations *ops, size_t opsize, void *data), const struct fuse3_operations *ops, size_t opsize, void *data),
{ {
return FSP_FUSE_API_CALL(fsp_fuse3_new_30) return FSP_FUSE_API_CALL(fsp_fuse3_new_30)
(fsp_fuse_env(), args, ops, opsize, data); (fsp_fuse_env(), args, ops, opsize, data);
}) })
#define fuse_new(args, op, size, data)\ #define fuse_new(args, op, size, data)\
fuse3_new_30(args, op, size, data) fuse3_new_30(args, op, size, data)
#else #else
FSP_FUSE_SYM( FSP_FUSE_SYM(
struct fuse3 *fuse3_new(struct fuse_args *args, struct fuse3 *fuse3_new(struct fuse_args *args,
const struct fuse3_operations *ops, size_t opsize, void *data), const struct fuse3_operations *ops, size_t opsize, void *data),
{ {
return FSP_FUSE_API_CALL(fsp_fuse3_new) return FSP_FUSE_API_CALL(fsp_fuse3_new)
(fsp_fuse_env(), args, ops, opsize, data); (fsp_fuse_env(), args, ops, opsize, data);
}) })
#endif #endif
FSP_FUSE_SYM( FSP_FUSE_SYM(
void fuse3_destroy(struct fuse3 *f), void fuse3_destroy(struct fuse3 *f),
{ {
FSP_FUSE_API_CALL(fsp_fuse3_destroy) FSP_FUSE_API_CALL(fsp_fuse3_destroy)
(fsp_fuse_env(), f); (fsp_fuse_env(), f);
}) })
FSP_FUSE_SYM( FSP_FUSE_SYM(
int fuse3_mount(struct fuse3 *f, const char *mountpoint), int fuse3_mount(struct fuse3 *f, const char *mountpoint),
{ {
return FSP_FUSE_API_CALL(fsp_fuse3_mount) return FSP_FUSE_API_CALL(fsp_fuse3_mount)
(fsp_fuse_env(), f, mountpoint); (fsp_fuse_env(), f, mountpoint);
}) })
FSP_FUSE_SYM( FSP_FUSE_SYM(
void fuse3_unmount(struct fuse3 *f), void fuse3_unmount(struct fuse3 *f),
{ {
FSP_FUSE_API_CALL(fsp_fuse3_unmount) FSP_FUSE_API_CALL(fsp_fuse3_unmount)
(fsp_fuse_env(), f); (fsp_fuse_env(), f);
}) })
FSP_FUSE_SYM( FSP_FUSE_SYM(
int fuse3_loop(struct fuse3 *f), int fuse3_loop(struct fuse3 *f),
{ {
return FSP_FUSE_API_CALL(fsp_fuse3_loop) return FSP_FUSE_API_CALL(fsp_fuse3_loop)
(fsp_fuse_env(), f); (fsp_fuse_env(), f);
}) })
#if FUSE_USE_VERSION < 32 #if FUSE_USE_VERSION < 32
FSP_FUSE_SYM( FSP_FUSE_SYM(
int fuse3_loop_mt_31(struct fuse3 *f, int clone_fd), int fuse3_loop_mt_31(struct fuse3 *f, int clone_fd),
{ {
return FSP_FUSE_API_CALL(fsp_fuse3_loop_mt_31) return FSP_FUSE_API_CALL(fsp_fuse3_loop_mt_31)
(fsp_fuse_env(), f, clone_fd); (fsp_fuse_env(), f, clone_fd);
}) })
#define fuse_loop_mt(f, clone_fd)\ #define fuse_loop_mt(f, clone_fd)\
fuse3_loop_mt_31(f, clone_fd) fuse3_loop_mt_31(f, clone_fd)
#else #else
FSP_FUSE_SYM( FSP_FUSE_SYM(
int fuse3_loop_mt(struct fuse3 *f, struct fuse3_loop_config *config), int fuse3_loop_mt(struct fuse3 *f, struct fuse3_loop_config *config),
{ {
return FSP_FUSE_API_CALL(fsp_fuse3_loop_mt) return FSP_FUSE_API_CALL(fsp_fuse3_loop_mt)
(fsp_fuse_env(), f, config); (fsp_fuse_env(), f, config);
}) })
#endif #endif
FSP_FUSE_SYM( FSP_FUSE_SYM(
void fuse3_exit(struct fuse3 *f), void fuse3_exit(struct fuse3 *f),
{ {
FSP_FUSE_API_CALL(fsp_fuse3_exit) FSP_FUSE_API_CALL(fsp_fuse3_exit)
(fsp_fuse_env(), f); (fsp_fuse_env(), f);
}) })
FSP_FUSE_SYM( FSP_FUSE_SYM(
struct fuse3_context *fuse3_get_context(void), struct fuse3_context *fuse3_get_context(void),
{ {
return FSP_FUSE_API_CALL(fsp_fuse3_get_context) return FSP_FUSE_API_CALL(fsp_fuse3_get_context)
(fsp_fuse_env()); (fsp_fuse_env());
}) })
FSP_FUSE_SYM( FSP_FUSE_SYM(
int fuse3_getgroups(int size, fuse_gid_t list[]), int fuse3_getgroups(int size, fuse_gid_t list[]),
{ {
(void)size; (void)size;
(void)list; (void)list;
return -ENOSYS; return -ENOSYS;
}) })
FSP_FUSE_SYM( FSP_FUSE_SYM(
int fuse3_interrupted(void), int fuse3_interrupted(void),
{ {
return 0; return 0;
}) })
FSP_FUSE_SYM( FSP_FUSE_SYM(
int fuse3_invalidate_path(struct fuse3 *f, const char *path), int fuse3_invalidate_path(struct fuse3 *f, const char *path),
{ {
(void)f; (void)f;
(void)path; (void)path;
return -ENOENT; return -ENOENT;
}) })
FSP_FUSE_SYM( FSP_FUSE_SYM(
int fuse3_notify_poll(struct fuse3_pollhandle *ph), int fuse3_notify_poll(struct fuse3_pollhandle *ph),
{ {
(void)ph; (void)ph;
return 0; return 0;
}) })
FSP_FUSE_SYM( FSP_FUSE_SYM(
int fuse3_start_cleanup_thread(struct fuse3 *f), int fuse3_start_cleanup_thread(struct fuse3 *f),
{ {
(void)f; (void)f;
return 0; return 0;
}) })
FSP_FUSE_SYM( FSP_FUSE_SYM(
void fuse3_stop_cleanup_thread(struct fuse3 *f), void fuse3_stop_cleanup_thread(struct fuse3 *f),
{ {
(void)f; (void)f;
}) })
FSP_FUSE_SYM( FSP_FUSE_SYM(
int fuse3_clean_cache(struct fuse3 *f), int fuse3_clean_cache(struct fuse3 *f),
{ {
(void)f; (void)f;
return 600; return 600;
}) })
FSP_FUSE_SYM( FSP_FUSE_SYM(
struct fuse3_session *fuse3_get_session(struct fuse3 *f), struct fuse3_session *fuse3_get_session(struct fuse3 *f),
{ {
return (struct fuse3_session *)f; return (struct fuse3_session *)f;
}) })
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif #endif

View File

@@ -1,238 +1,238 @@
/** /**
* @file fuse3/fuse_common.h * @file fuse3/fuse_common.h
* WinFsp FUSE3 compatible API. * WinFsp FUSE3 compatible API.
* *
* This file is derived from libfuse/include/fuse_common.h: * This file is derived from libfuse/include/fuse_common.h:
* FUSE: Filesystem in Userspace * FUSE: Filesystem in Userspace
* Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu> * Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
* *
* @copyright 2015-2022 Bill Zissimopoulos * @copyright 2015-2025 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
* *
* You can redistribute it and/or modify it under the terms of the GNU * 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 * General Public License version 3 as published by the Free Software
* Foundation. * Foundation.
* *
* Licensees holding a valid commercial license may use this software * Licensees holding a valid commercial license may use this software
* in accordance with the commercial license agreement provided in * in accordance with the commercial license agreement provided in
* conjunction with the software. The terms and conditions of any such * conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render * commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software, * ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or * notwithstanding of any reference thereto in the software or
* associated repository. * associated repository.
*/ */
#ifndef FUSE_COMMON_H_ #ifndef FUSE_COMMON_H_
#define FUSE_COMMON_H_ #define FUSE_COMMON_H_
#include "winfsp_fuse.h" #include "winfsp_fuse.h"
#if !defined(WINFSP_DLL_INTERNAL) #if !defined(WINFSP_DLL_INTERNAL)
#include "fuse_opt.h" #include "fuse_opt.h"
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
#define FUSE_MAJOR_VERSION 3 #define FUSE_MAJOR_VERSION 3
#define FUSE_MINOR_VERSION 2 #define FUSE_MINOR_VERSION 2
#define FUSE_MAKE_VERSION(maj, min) ((maj) * 10 + (min)) #define FUSE_MAKE_VERSION(maj, min) ((maj) * 10 + (min))
#define FUSE_VERSION FUSE_MAKE_VERSION(FUSE_MAJOR_VERSION, FUSE_MINOR_VERSION) #define FUSE_VERSION FUSE_MAKE_VERSION(FUSE_MAJOR_VERSION, FUSE_MINOR_VERSION)
#define FUSE_CAP_ASYNC_READ (1 << 0) #define FUSE_CAP_ASYNC_READ (1 << 0)
#define FUSE_CAP_POSIX_LOCKS (1 << 1) #define FUSE_CAP_POSIX_LOCKS (1 << 1)
#define FUSE_CAP_ATOMIC_O_TRUNC (1 << 3) #define FUSE_CAP_ATOMIC_O_TRUNC (1 << 3)
#define FUSE_CAP_EXPORT_SUPPORT (1 << 4) #define FUSE_CAP_EXPORT_SUPPORT (1 << 4)
#define FUSE_CAP_DONT_MASK (1 << 6) #define FUSE_CAP_DONT_MASK (1 << 6)
#define FUSE_CAP_SPLICE_WRITE (1 << 7) #define FUSE_CAP_SPLICE_WRITE (1 << 7)
#define FUSE_CAP_SPLICE_MOVE (1 << 8) #define FUSE_CAP_SPLICE_MOVE (1 << 8)
#define FUSE_CAP_SPLICE_READ (1 << 9) #define FUSE_CAP_SPLICE_READ (1 << 9)
#define FUSE_CAP_FLOCK_LOCKS (1 << 10) #define FUSE_CAP_FLOCK_LOCKS (1 << 10)
#define FUSE_CAP_IOCTL_DIR (1 << 11) #define FUSE_CAP_IOCTL_DIR (1 << 11)
#define FUSE_CAP_AUTO_INVAL_DATA (1 << 12) #define FUSE_CAP_AUTO_INVAL_DATA (1 << 12)
#define FUSE_CAP_READDIRPLUS (1 << 13) #define FUSE_CAP_READDIRPLUS (1 << 13)
#define FUSE_CAP_READDIRPLUS_AUTO (1 << 14) #define FUSE_CAP_READDIRPLUS_AUTO (1 << 14)
#define FUSE_CAP_ASYNC_DIO (1 << 15) #define FUSE_CAP_ASYNC_DIO (1 << 15)
#define FUSE_CAP_WRITEBACK_CACHE (1 << 16) #define FUSE_CAP_WRITEBACK_CACHE (1 << 16)
#define FUSE_CAP_NO_OPEN_SUPPORT (1 << 17) #define FUSE_CAP_NO_OPEN_SUPPORT (1 << 17)
#define FUSE_CAP_PARALLEL_DIROPS (1 << 18) #define FUSE_CAP_PARALLEL_DIROPS (1 << 18)
#define FUSE_CAP_POSIX_ACL (1 << 19) #define FUSE_CAP_POSIX_ACL (1 << 19)
#define FUSE_CAP_HANDLE_KILLPRIV (1 << 20) #define FUSE_CAP_HANDLE_KILLPRIV (1 << 20)
#define FUSE_CAP_ALLOCATE (1 << 27) /* reserved (OSXFUSE) */ #define FUSE_CAP_ALLOCATE (1 << 27) /* reserved (OSXFUSE) */
#define FUSE_CAP_EXCHANGE_DATA (1 << 28) /* 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_CASE_INSENSITIVE (1 << 29) /* file system is case insensitive */
#define FUSE_CAP_VOL_RENAME (1 << 30) /* reserved (OSXFUSE) */ #define FUSE_CAP_VOL_RENAME (1 << 30) /* reserved (OSXFUSE) */
#define FUSE_CAP_XTIMES (1 << 31) /* reserved (OSXFUSE) */ #define FUSE_CAP_XTIMES (1 << 31) /* reserved (OSXFUSE) */
#define FSP_FUSE_CAP_CASE_INSENSITIVE FUSE_CAP_CASE_INSENSITIVE #define FSP_FUSE_CAP_CASE_INSENSITIVE FUSE_CAP_CASE_INSENSITIVE
#define FUSE_IOCTL_COMPAT (1 << 0) #define FUSE_IOCTL_COMPAT (1 << 0)
#define FUSE_IOCTL_UNRESTRICTED (1 << 1) #define FUSE_IOCTL_UNRESTRICTED (1 << 1)
#define FUSE_IOCTL_RETRY (1 << 2) #define FUSE_IOCTL_RETRY (1 << 2)
#define FUSE_IOCTL_DIR (1 << 4) #define FUSE_IOCTL_DIR (1 << 4)
#define FUSE_IOCTL_MAX_IOV 256 #define FUSE_IOCTL_MAX_IOV 256
#define FUSE_BUFVEC_INIT(s) \ #define FUSE_BUFVEC_INIT(s) \
((struct fuse3_bufvec){ 1, 0, 0, { {s, (enum fuse3_buf_flags)0, 0, -1, 0} } }) ((struct fuse3_bufvec){ 1, 0, 0, { {s, (enum fuse3_buf_flags)0, 0, -1, 0} } })
struct fuse3_file_info struct fuse3_file_info
{ {
int flags; int flags;
unsigned int writepage:1; unsigned int writepage:1;
unsigned int direct_io:1; unsigned int direct_io:1;
unsigned int keep_cache:1; unsigned int keep_cache:1;
unsigned int flush:1; unsigned int flush:1;
unsigned int nonseekable:1; unsigned int nonseekable:1;
unsigned int flock_release:1; unsigned int flock_release:1;
unsigned int padding:27; unsigned int padding:27;
uint64_t fh; uint64_t fh;
uint64_t lock_owner; uint64_t lock_owner;
uint32_t poll_events; uint32_t poll_events;
}; };
struct fuse3_loop_config struct fuse3_loop_config
{ {
int clone_fd; int clone_fd;
unsigned int max_idle_threads; unsigned int max_idle_threads;
}; };
struct fuse3_conn_info struct fuse3_conn_info
{ {
unsigned proto_major; unsigned proto_major;
unsigned proto_minor; unsigned proto_minor;
unsigned max_write; unsigned max_write;
unsigned max_read; unsigned max_read;
unsigned max_readahead; unsigned max_readahead;
unsigned capable; unsigned capable;
unsigned want; unsigned want;
unsigned max_background; unsigned max_background;
unsigned congestion_threshold; unsigned congestion_threshold;
unsigned time_gran; unsigned time_gran;
unsigned reserved[22]; unsigned reserved[22];
}; };
enum fuse3_buf_flags enum fuse3_buf_flags
{ {
FUSE_BUF_IS_FD = (1 << 1), FUSE_BUF_IS_FD = (1 << 1),
FUSE_BUF_FD_SEEK = (1 << 2), FUSE_BUF_FD_SEEK = (1 << 2),
FUSE_BUF_FD_RETRY = (1 << 3), FUSE_BUF_FD_RETRY = (1 << 3),
}; };
enum fuse3_buf_copy_flags enum fuse3_buf_copy_flags
{ {
FUSE_BUF_NO_SPLICE = (1 << 1), FUSE_BUF_NO_SPLICE = (1 << 1),
FUSE_BUF_FORCE_SPLICE = (1 << 2), FUSE_BUF_FORCE_SPLICE = (1 << 2),
FUSE_BUF_SPLICE_MOVE = (1 << 3), FUSE_BUF_SPLICE_MOVE = (1 << 3),
FUSE_BUF_SPLICE_NONBLOCK = (1 << 4), FUSE_BUF_SPLICE_NONBLOCK = (1 << 4),
}; };
struct fuse3_buf struct fuse3_buf
{ {
size_t size; size_t size;
enum fuse3_buf_flags flags; enum fuse3_buf_flags flags;
void *mem; void *mem;
int fd; int fd;
fuse_off_t pos; fuse_off_t pos;
}; };
struct fuse3_bufvec struct fuse3_bufvec
{ {
size_t count; size_t count;
size_t idx; size_t idx;
size_t off; size_t off;
struct fuse3_buf buf[1]; struct fuse3_buf buf[1];
}; };
struct fuse3_session; struct fuse3_session;
struct fuse3_pollhandle; struct fuse3_pollhandle;
struct fuse3_conn_info_opts; struct fuse3_conn_info_opts;
FSP_FUSE_API struct fuse3_conn_info_opts *FSP_FUSE_API_NAME(fsp_fuse3_parse_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 fsp_fuse_env *env,
struct fuse_args *args); struct fuse_args *args);
FSP_FUSE_API void FSP_FUSE_API_NAME(fsp_fuse3_apply_conn_info_opts)(struct fsp_fuse_env *env, 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); 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 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 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, FSP_FUSE_API int32_t FSP_FUSE_API_NAME(fsp_fuse_ntstatus_from_errno)(struct fsp_fuse_env *env,
int err); int err);
FSP_FUSE_SYM( FSP_FUSE_SYM(
struct fuse3_conn_info_opts* fuse3_parse_conn_info_opts( struct fuse3_conn_info_opts* fuse3_parse_conn_info_opts(
struct fuse_args *args), struct fuse_args *args),
{ {
return FSP_FUSE_API_CALL(fsp_fuse3_parse_conn_info_opts) return FSP_FUSE_API_CALL(fsp_fuse3_parse_conn_info_opts)
(fsp_fuse_env(), args); (fsp_fuse_env(), args);
}) })
FSP_FUSE_SYM( FSP_FUSE_SYM(
void fuse3_apply_conn_info_opts( void fuse3_apply_conn_info_opts(
struct fuse3_conn_info_opts *opts, struct fuse3_conn_info *conn), struct fuse3_conn_info_opts *opts, struct fuse3_conn_info *conn),
{ {
FSP_FUSE_API_CALL(fsp_fuse3_apply_conn_info_opts) FSP_FUSE_API_CALL(fsp_fuse3_apply_conn_info_opts)
(fsp_fuse_env(), opts, conn); (fsp_fuse_env(), opts, conn);
}) })
FSP_FUSE_SYM( FSP_FUSE_SYM(
int fuse3_version(void), int fuse3_version(void),
{ {
return FSP_FUSE_API_CALL(fsp_fuse3_version) return FSP_FUSE_API_CALL(fsp_fuse3_version)
(fsp_fuse_env()); (fsp_fuse_env());
}) })
FSP_FUSE_SYM( FSP_FUSE_SYM(
const char *fuse3_pkgversion(void), const char *fuse3_pkgversion(void),
{ {
return FSP_FUSE_API_CALL(fsp_fuse3_pkgversion) return FSP_FUSE_API_CALL(fsp_fuse3_pkgversion)
(fsp_fuse_env()); (fsp_fuse_env());
}) })
FSP_FUSE_SYM( FSP_FUSE_SYM(
void fuse3_pollhandle_destroy(struct fuse3_pollhandle *ph), void fuse3_pollhandle_destroy(struct fuse3_pollhandle *ph),
{ {
(void)ph; (void)ph;
}) })
FSP_FUSE_SYM( FSP_FUSE_SYM(
size_t fuse3_buf_size(const struct fuse3_bufvec *bufv), size_t fuse3_buf_size(const struct fuse3_bufvec *bufv),
{ {
(void)bufv; (void)bufv;
return 0; return 0;
}) })
FSP_FUSE_SYM( FSP_FUSE_SYM(
ssize_t fuse3_buf_copy(struct fuse3_bufvec *dst, struct fuse3_bufvec *src, ssize_t fuse3_buf_copy(struct fuse3_bufvec *dst, struct fuse3_bufvec *src,
enum fuse3_buf_copy_flags flags), enum fuse3_buf_copy_flags flags),
{ {
(void)dst; (void)dst;
(void)src; (void)src;
(void)flags; (void)flags;
return 0; return 0;
}) })
FSP_FUSE_SYM( FSP_FUSE_SYM(
int fuse3_daemonize(int foreground), int fuse3_daemonize(int foreground),
{ {
return fsp_fuse_daemonize(foreground); return fsp_fuse_daemonize(foreground);
}) })
FSP_FUSE_SYM( FSP_FUSE_SYM(
int fuse3_set_signal_handlers(struct fuse3_session *se), int fuse3_set_signal_handlers(struct fuse3_session *se),
{ {
return fsp_fuse_set_signal_handlers(se); return fsp_fuse_set_signal_handlers(se);
}) })
FSP_FUSE_SYM( FSP_FUSE_SYM(
void fuse3_remove_signal_handlers(struct fuse3_session *se), void fuse3_remove_signal_handlers(struct fuse3_session *se),
{ {
(void)se; (void)se;
fsp_fuse_set_signal_handlers(0); fsp_fuse_set_signal_handlers(0);
}) })
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif #endif

View File

@@ -1,23 +1,23 @@
/** /**
* @file fuse3/fuse_opt.h * @file fuse3/fuse_opt.h
* WinFsp FUSE3 compatible API. * WinFsp FUSE3 compatible API.
* *
* @copyright 2015-2022 Bill Zissimopoulos * @copyright 2015-2025 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
* *
* You can redistribute it and/or modify it under the terms of the GNU * 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 * General Public License version 3 as published by the Free Software
* Foundation. * Foundation.
* *
* Licensees holding a valid commercial license may use this software * Licensees holding a valid commercial license may use this software
* in accordance with the commercial license agreement provided in * in accordance with the commercial license agreement provided in
* conjunction with the software. The terms and conditions of any such * conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render * commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software, * ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or * notwithstanding of any reference thereto in the software or
* associated repository. * associated repository.
*/ */
#include "../fuse/fuse_opt.h" #include "../fuse/fuse_opt.h"

View File

@@ -1,82 +1,82 @@
/** /**
* @file fuse3/winfsp_fuse.h * @file fuse3/winfsp_fuse.h
* WinFsp FUSE3 compatible API. * WinFsp FUSE3 compatible API.
* *
* @copyright 2015-2022 Bill Zissimopoulos * @copyright 2015-2025 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
* *
* You can redistribute it and/or modify it under the terms of the GNU * 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 * General Public License version 3 as published by the Free Software
* Foundation. * Foundation.
* *
* Licensees holding a valid commercial license may use this software * Licensees holding a valid commercial license may use this software
* in accordance with the commercial license agreement provided in * in accordance with the commercial license agreement provided in
* conjunction with the software. The terms and conditions of any such * conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render * commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software, * ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or * notwithstanding of any reference thereto in the software or
* associated repository. * associated repository.
*/ */
#ifndef FUSE3_WINFSP_FUSE_H_INCLUDED #ifndef FUSE3_WINFSP_FUSE_H_INCLUDED
#define FUSE3_WINFSP_FUSE_H_INCLUDED #define FUSE3_WINFSP_FUSE_H_INCLUDED
#include "../fuse/winfsp_fuse.h" #include "../fuse/winfsp_fuse.h"
#if defined(_WIN64) || defined(_WIN32) #if defined(_WIN64) || defined(_WIN32)
typedef intptr_t ssize_t; typedef intptr_t ssize_t;
#endif #endif
#if !defined(WINFSP_DLL_INTERNAL) #if !defined(WINFSP_DLL_INTERNAL)
#define fuse3 fuse #define fuse3 fuse
#define fuse3_apply_conn_info_opts fuse_apply_conn_info_opts #define fuse3_apply_conn_info_opts fuse_apply_conn_info_opts
#define fuse3_buf fuse_buf #define fuse3_buf fuse_buf
#define fuse3_buf_copy fuse_buf_copy #define fuse3_buf_copy fuse_buf_copy
#define fuse3_buf_copy_flags fuse_buf_copy_flags #define fuse3_buf_copy_flags fuse_buf_copy_flags
#define fuse3_buf_flags fuse_buf_flags #define fuse3_buf_flags fuse_buf_flags
#define fuse3_buf_size fuse_buf_size #define fuse3_buf_size fuse_buf_size
#define fuse3_bufvec fuse_bufvec #define fuse3_bufvec fuse_bufvec
#define fuse3_clean_cache fuse_clean_cache #define fuse3_clean_cache fuse_clean_cache
#define fuse3_config fuse_config #define fuse3_config fuse_config
#define fuse3_conn_info fuse_conn_info #define fuse3_conn_info fuse_conn_info
#define fuse3_conn_info_opts fuse_conn_info_opts #define fuse3_conn_info_opts fuse_conn_info_opts
#define fuse3_context fuse_context #define fuse3_context fuse_context
#define fuse3_daemonize fuse_daemonize #define fuse3_daemonize fuse_daemonize
#define fuse3_destroy fuse_destroy #define fuse3_destroy fuse_destroy
#define fuse3_exit fuse_exit #define fuse3_exit fuse_exit
#define fuse3_file_info fuse_file_info #define fuse3_file_info fuse_file_info
#define fuse3_fill_dir_flags fuse_fill_dir_flags #define fuse3_fill_dir_flags fuse_fill_dir_flags
#define fuse3_fill_dir_t fuse_fill_dir_t #define fuse3_fill_dir_t fuse_fill_dir_t
#define fuse3_get_context fuse_get_context #define fuse3_get_context fuse_get_context
#define fuse3_get_session fuse_get_session #define fuse3_get_session fuse_get_session
#define fuse3_getgroups fuse_getgroups #define fuse3_getgroups fuse_getgroups
#define fuse3_interrupted fuse_interrupted #define fuse3_interrupted fuse_interrupted
#define fuse3_invalidate_path fuse_invalidate_path #define fuse3_invalidate_path fuse_invalidate_path
#define fuse3_lib_help fuse_lib_help #define fuse3_lib_help fuse_lib_help
#define fuse3_loop fuse_loop #define fuse3_loop fuse_loop
#define fuse3_loop_config fuse_loop_config #define fuse3_loop_config fuse_loop_config
#define fuse3_loop_mt fuse_loop_mt #define fuse3_loop_mt fuse_loop_mt
#define fuse3_loop_mt_31 fuse_loop_mt_31 #define fuse3_loop_mt_31 fuse_loop_mt_31
#define fuse3_main_real fuse_main_real #define fuse3_main_real fuse_main_real
#define fuse3_mount fuse_mount #define fuse3_mount fuse_mount
#define fuse3_new fuse_new #define fuse3_new fuse_new
#define fuse3_new_30 fuse_new_30 #define fuse3_new_30 fuse_new_30
#define fuse3_notify_poll fuse_notify_poll #define fuse3_notify_poll fuse_notify_poll
#define fuse3_operations fuse_operations #define fuse3_operations fuse_operations
#define fuse3_parse_conn_info_opts fuse_parse_conn_info_opts #define fuse3_parse_conn_info_opts fuse_parse_conn_info_opts
#define fuse3_pkgversion fuse_pkgversion #define fuse3_pkgversion fuse_pkgversion
#define fuse3_pollhandle fuse_pollhandle #define fuse3_pollhandle fuse_pollhandle
#define fuse3_pollhandle_destroy fuse_pollhandle_destroy #define fuse3_pollhandle_destroy fuse_pollhandle_destroy
#define fuse3_readdir_flags fuse_readdir_flags #define fuse3_readdir_flags fuse_readdir_flags
#define fuse3_remove_signal_handlers fuse_remove_signal_handlers #define fuse3_remove_signal_handlers fuse_remove_signal_handlers
#define fuse3_session fuse_session #define fuse3_session fuse_session
#define fuse3_set_signal_handlers fuse_set_signal_handlers #define fuse3_set_signal_handlers fuse_set_signal_handlers
#define fuse3_start_cleanup_thread fuse_start_cleanup_thread #define fuse3_start_cleanup_thread fuse_start_cleanup_thread
#define fuse3_stop_cleanup_thread fuse_stop_cleanup_thread #define fuse3_stop_cleanup_thread fuse_stop_cleanup_thread
#define fuse3_unmount fuse_unmount #define fuse3_unmount fuse_unmount
#define fuse3_version fuse_version #define fuse3_version fuse_version
#endif #endif
#endif #endif

View File

@@ -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 <devioctl.h>
#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

View File

@@ -1,350 +1,350 @@
/** /**
* @file winfsp/launch.h * @file winfsp/launch.h
* WinFsp Launch API. * WinFsp Launch API.
* *
* In order to use the WinFsp Launch API a program must include &lt;winfsp/launch.h&gt; * In order to use the WinFsp Launch API a program must include &lt;winfsp/launch.h&gt;
* and link with the winfsp_x64.dll (or winfsp_x86.dll) library. * and link with the winfsp_x64.dll (or winfsp_x86.dll) library.
* *
* @copyright 2015-2022 Bill Zissimopoulos * @copyright 2015-2025 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
* *
* You can redistribute it and/or modify it under the terms of the GNU * 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 * General Public License version 3 as published by the Free Software
* Foundation. * Foundation.
* *
* Licensees holding a valid commercial license may use this software * Licensees holding a valid commercial license may use this software
* in accordance with the commercial license agreement provided in * in accordance with the commercial license agreement provided in
* conjunction with the software. The terms and conditions of any such * conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render * commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software, * ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or * notwithstanding of any reference thereto in the software or
* associated repository. * associated repository.
*/ */
#ifndef WINFSP_LAUNCH_H_INCLUDED #ifndef WINFSP_LAUNCH_H_INCLUDED
#define WINFSP_LAUNCH_H_INCLUDED #define WINFSP_LAUNCH_H_INCLUDED
#include <winfsp/winfsp.h> #include <winfsp/winfsp.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
#define FSP_LAUNCH_REGKEY FSP_FSCTL_PRODUCT_REGKEY "\\Services" #define FSP_LAUNCH_REGKEY FSP_FSCTL_PRODUCT_REGKEY "\\Services"
#define FSP_LAUNCH_REGKEY_WOW64 FSP_FSCTL_PRODUCT_REGKEY_WOW64 #define FSP_LAUNCH_REGKEY_WOW64 FSP_FSCTL_PRODUCT_REGKEY_WOW64
#define FSP_LAUNCH_FULL_REGKEY FSP_FSCTL_PRODUCT_FULL_REGKEY "\\Services" #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_NAME "\\\\.\\pipe\\" FSP_FSCTL_PRODUCT_NAME ".{14E7137D-22B4-437A-B0C1-D21D1BDF3767}"
#define FSP_LAUNCH_PIPE_BUFFER_SIZE 4096 #define FSP_LAUNCH_PIPE_BUFFER_SIZE 4096
#define FSP_LAUNCH_PIPE_OWNER ((PSID)WinLocalSystemSid) #define FSP_LAUNCH_PIPE_OWNER ((PSID)WinLocalSystemSid)
/* /*
* The launcher named pipe SDDL gives full access to LocalSystem and Administrators and * 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 * 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 * FILE_CREATE_PIPE_INSTANCE right to Everyone to disallow the creation of additional
* pipe instances. * pipe instances.
*/ */
#define FSP_LAUNCH_PIPE_SDDL "O:SYG:SYD:P(A;;GA;;;SY)(A;;GA;;;BA)(A;;GRDCCR;;;WD)" #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 default service instance SDDL gives full access to LocalSystem and Administrators.
* The only possible service instance rights are as follows: * The only possible service instance rights are as follows:
* RP SERVICE_START * RP SERVICE_START
* WP SERVICE_STOP * WP SERVICE_STOP
* LC SERVICE_QUERY_STATUS * LC SERVICE_QUERY_STATUS
* *
* To create a service that can be started, stopped or queried by Everyone, you can set * To create a service that can be started, stopped or queried by Everyone, you can set
* the following SDDL: * the following SDDL:
* D:P(A;;RPWPLC;;;WD) * D:P(A;;RPWPLC;;;WD)
*/ */
#define FSP_LAUNCH_SERVICE_DEFAULT_SDDL "D:P(A;;RPWPLC;;;SY)(A;;RPWPLC;;;BA)" #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)" #define FSP_LAUNCH_SERVICE_WORLD_SDDL "D:P(A;;RPWPLC;;;WD)"
enum enum
{ {
FspLaunchCmdStart = 'S', /* requires: SERVICE_START */ FspLaunchCmdStart = 'S', /* requires: SERVICE_START */
FspLaunchCmdStartWithSecret = 'X', /* requires: SERVICE_START */ FspLaunchCmdStartWithSecret = 'X', /* requires: SERVICE_START */
FspLaunchCmdStop = 'T', /* requires: SERVICE_STOP */ FspLaunchCmdStop = 'T', /* requires: SERVICE_STOP */
FspLaunchCmdGetInfo = 'I', /* requires: SERVICE_QUERY_STATUS */ FspLaunchCmdGetInfo = 'I', /* requires: SERVICE_QUERY_STATUS */
FspLaunchCmdGetNameList = 'L', /* requires: none*/ FspLaunchCmdGetNameList = 'L', /* requires: none*/
FspLaunchCmdDefineDosDevice = 'D', /* internal: do not use! */ FspLaunchCmdDefineDosDevice = 'D', /* internal: do not use! */
FspLaunchCmdQuit = 'Q', /* DEBUG version only */ FspLaunchCmdQuit = 'Q', /* DEBUG version only */
}; };
enum enum
{ {
FspLaunchCmdSuccess = '$', FspLaunchCmdSuccess = '$',
FspLaunchCmdFailure = '!', FspLaunchCmdFailure = '!',
}; };
/** /**
* @group Launch Control * @group Launch Control
*/ */
/** /**
* Call launcher pipe. * Call launcher pipe.
* *
* This function is used to send a command to the launcher and receive a response. * This function is used to send a command to the launcher and receive a response.
* *
* @param Command * @param Command
* Launcher command to send. For example, the 'L' launcher command instructs * Launcher command to send. For example, the 'L' launcher command instructs
* the launcher to list all running service instances. * the launcher to list all running service instances.
* @param Argc * @param Argc
* Command argument count. May be 0. * Command argument count. May be 0.
* @param Argv * @param Argv
* Command argument array. May be NULL. * Command argument array. May be NULL.
* @param Argl * @param Argl
* Command argument length array. May be NULL. If this is NULL all command arguments * 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 * 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. * to be NULL-terminated; in this case pass -1 in the corresponding Argl position.
* @param Buffer * @param Buffer
* Buffer that receives the command response. May be NULL. * Buffer that receives the command response. May be NULL.
* @param PSize * @param PSize
* Pointer to a ULONG. On input it contains the size of the Buffer. On output it * 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. * contains the number of bytes transferred. May be NULL.
* @param PLauncherError * @param PLauncherError
* Receives the launcher error if any. This is always a Win32 error code. May not be NULL. * Receives the launcher error if any. This is always a Win32 error code. May not be NULL.
* @return * @return
* STATUS_SUCCESS if the command is sent successfully to the launcher, even if the launcher * 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 * returns an error. Other status codes indicate a communication error. Launcher errors are
* reported through PLauncherError. * reported through PLauncherError.
*/ */
FSP_API NTSTATUS FspLaunchCallLauncherPipe( FSP_API NTSTATUS FspLaunchCallLauncherPipe(
WCHAR Command, ULONG Argc, PWSTR *Argv, ULONG *Argl, WCHAR Command, ULONG Argc, PWSTR *Argv, ULONG *Argl,
PWSTR Buffer, PULONG PSize, PWSTR Buffer, PULONG PSize,
PULONG PLauncherError); PULONG PLauncherError);
/** /**
* Call launcher pipe. * Call launcher pipe.
* *
* This function is used to send a command to the launcher and receive a response. * This function is used to send a command to the launcher and receive a response.
* *
* @param Command * @param Command
* Launcher command to send. For example, the 'L' launcher command instructs * Launcher command to send. For example, the 'L' launcher command instructs
* the launcher to list all running service instances. * the launcher to list all running service instances.
* @param Argc * @param Argc
* Command argument count. May be 0. * Command argument count. May be 0.
* @param Argv * @param Argv
* Command argument array. May be NULL. * Command argument array. May be NULL.
* @param Argl * @param Argl
* Command argument length array. May be NULL. If this is NULL all command arguments * 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 * 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. * to be NULL-terminated; in this case pass -1 in the corresponding Argl position.
* @param Buffer * @param Buffer
* Buffer that receives the command response. May be NULL. * Buffer that receives the command response. May be NULL.
* @param PSize * @param PSize
* Pointer to a ULONG. On input it contains the size of the Buffer. On output it * 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. * contains the number of bytes transferred. May be NULL.
* @param AllowImpersonation * @param AllowImpersonation
* Allow caller to be impersonated by launcher. * Allow caller to be impersonated by launcher.
* @param PLauncherError * @param PLauncherError
* Receives the launcher error if any. This is always a Win32 error code. May not be NULL. * Receives the launcher error if any. This is always a Win32 error code. May not be NULL.
* @return * @return
* STATUS_SUCCESS if the command is sent successfully to the launcher, even if the launcher * 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 * returns an error. Other status codes indicate a communication error. Launcher errors are
* reported through PLauncherError. * reported through PLauncherError.
*/ */
FSP_API NTSTATUS FspLaunchCallLauncherPipeEx( FSP_API NTSTATUS FspLaunchCallLauncherPipeEx(
WCHAR Command, ULONG Argc, PWSTR *Argv, ULONG *Argl, WCHAR Command, ULONG Argc, PWSTR *Argv, ULONG *Argl,
PWSTR Buffer, PULONG PSize, PWSTR Buffer, PULONG PSize,
BOOLEAN AllowImpersonation, BOOLEAN AllowImpersonation,
PULONG PLauncherError); PULONG PLauncherError);
/** /**
* Start a service instance. * Start a service instance.
* *
* @param ClassName * @param ClassName
* Class name of the service instance to start. * Class name of the service instance to start.
* @param InstanceName * @param InstanceName
* Instance name of the service instance to start. * Instance name of the service instance to start.
* @param Argc * @param Argc
* Service instance argument count. May be 0. * Service instance argument count. May be 0.
* @param Argv * @param Argv
* Service instance argument array. May be NULL. * Service instance argument array. May be NULL.
* @param HasSecret * @param HasSecret
* Whether the last argument in Argv is assumed to be a secret (e.g. password) or not. * 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 * Secrets are passed to service instances through standard input rather than the command
* line. * line.
* @param PLauncherError * @param PLauncherError
* Receives the launcher error if any. This is always a Win32 error code. May not be NULL. * Receives the launcher error if any. This is always a Win32 error code. May not be NULL.
* @return * @return
* STATUS_SUCCESS if the command is sent successfully to the launcher, even if the launcher * 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 * returns an error. Other status codes indicate a communication error. Launcher errors are
* reported through PLauncherError. * reported through PLauncherError.
*/ */
FSP_API NTSTATUS FspLaunchStart( FSP_API NTSTATUS FspLaunchStart(
PWSTR ClassName, PWSTR InstanceName, ULONG Argc, PWSTR *Argv, PWSTR ClassName, PWSTR InstanceName, ULONG Argc, PWSTR *Argv,
BOOLEAN HasSecret, BOOLEAN HasSecret,
PULONG PLauncherError); PULONG PLauncherError);
/** /**
* Start a service instance. * Start a service instance.
* *
* @param ClassName * @param ClassName
* Class name of the service instance to start. * Class name of the service instance to start.
* @param InstanceName * @param InstanceName
* Instance name of the service instance to start. * Instance name of the service instance to start.
* @param Argc * @param Argc
* Service instance argument count. May be 0. * Service instance argument count. May be 0.
* @param Argv * @param Argv
* Service instance argument array. May be NULL. * Service instance argument array. May be NULL.
* @param HasSecret * @param HasSecret
* Whether the last argument in Argv is assumed to be a secret (e.g. password) or not. * 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 * Secrets are passed to service instances through standard input rather than the command
* line. * line.
* @param AllowImpersonation * @param AllowImpersonation
* Allow caller to be impersonated by launcher. * Allow caller to be impersonated by launcher.
* @param PLauncherError * @param PLauncherError
* Receives the launcher error if any. This is always a Win32 error code. May not be NULL. * Receives the launcher error if any. This is always a Win32 error code. May not be NULL.
* @return * @return
* STATUS_SUCCESS if the command is sent successfully to the launcher, even if the launcher * 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 * returns an error. Other status codes indicate a communication error. Launcher errors are
* reported through PLauncherError. * reported through PLauncherError.
*/ */
FSP_API NTSTATUS FspLaunchStartEx( FSP_API NTSTATUS FspLaunchStartEx(
PWSTR ClassName, PWSTR InstanceName, ULONG Argc, PWSTR *Argv, PWSTR ClassName, PWSTR InstanceName, ULONG Argc, PWSTR *Argv,
BOOLEAN HasSecret, BOOLEAN HasSecret,
BOOLEAN AllowImpersonation, BOOLEAN AllowImpersonation,
PULONG PLauncherError); PULONG PLauncherError);
/** /**
* Stop a service instance. * Stop a service instance.
* *
* @param ClassName * @param ClassName
* Class name of the service instance to stop. * Class name of the service instance to stop.
* @param InstanceName * @param InstanceName
* Instance name of the service instance to stop. * Instance name of the service instance to stop.
* @param PLauncherError * @param PLauncherError
* Receives the launcher error if any. This is always a Win32 error code. May not be NULL. * Receives the launcher error if any. This is always a Win32 error code. May not be NULL.
* @return * @return
* STATUS_SUCCESS if the command is sent successfully to the launcher, even if the launcher * 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 * returns an error. Other status codes indicate a communication error. Launcher errors are
* reported through PLauncherError. * reported through PLauncherError.
*/ */
FSP_API NTSTATUS FspLaunchStop( FSP_API NTSTATUS FspLaunchStop(
PWSTR ClassName, PWSTR InstanceName, PWSTR ClassName, PWSTR InstanceName,
PULONG PLauncherError); PULONG PLauncherError);
/** /**
* Get information about a service instance. * Get information about a service instance.
* *
* The information is a list of NULL-terminated strings: the class name of the 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 * the instance name of the service instance and the full command line used to start the service
* instance. * instance.
* *
* @param ClassName * @param ClassName
* Class name of the service instance to stop. * Class name of the service instance to stop.
* @param InstanceName * @param InstanceName
* Instance name of the service instance to stop. * Instance name of the service instance to stop.
* @param Buffer * @param Buffer
* Buffer that receives the command response. May be NULL. * Buffer that receives the command response. May be NULL.
* @param PSize * @param PSize
* Pointer to a ULONG. On input it contains the size of the Buffer. On output it * 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. * contains the number of bytes transferred. May be NULL.
* @param PLauncherError * @param PLauncherError
* Receives the launcher error if any. This is always a Win32 error code. May not be NULL. * Receives the launcher error if any. This is always a Win32 error code. May not be NULL.
* @return * @return
* STATUS_SUCCESS if the command is sent successfully to the launcher, even if the launcher * 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 * returns an error. Other status codes indicate a communication error. Launcher errors are
* reported through PLauncherError. * reported through PLauncherError.
*/ */
FSP_API NTSTATUS FspLaunchGetInfo( FSP_API NTSTATUS FspLaunchGetInfo(
PWSTR ClassName, PWSTR InstanceName, PWSTR ClassName, PWSTR InstanceName,
PWSTR Buffer, PULONG PSize, PWSTR Buffer, PULONG PSize,
PULONG PLauncherError); PULONG PLauncherError);
/** /**
* List service instances. * List service instances.
* *
* The information is a list of pairs of NULL-terminated strings. Each pair contains the class * 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 * name and instance name of a service instance. All currently running service instances are
* listed. * listed.
* *
* @param Buffer * @param Buffer
* Buffer that receives the command response. May be NULL. * Buffer that receives the command response. May be NULL.
* @param PSize * @param PSize
* Pointer to a ULONG. On input it contains the size of the Buffer. On output it * 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. * contains the number of bytes transferred. May be NULL.
* @param PLauncherError * @param PLauncherError
* Receives the launcher error if any. This is always a Win32 error code. May not be NULL. * Receives the launcher error if any. This is always a Win32 error code. May not be NULL.
* @return * @return
* STATUS_SUCCESS if the command is sent successfully to the launcher, even if the launcher * 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 * returns an error. Other status codes indicate a communication error. Launcher errors are
* reported through PLauncherError. * reported through PLauncherError.
*/ */
FSP_API NTSTATUS FspLaunchGetNameList( FSP_API NTSTATUS FspLaunchGetNameList(
PWSTR Buffer, PULONG PSize, PWSTR Buffer, PULONG PSize,
PULONG PLauncherError); PULONG PLauncherError);
/** /**
* @group Service Registry * @group Service Registry
*/ */
#pragma warning(push) #pragma warning(push)
#pragma warning(disable:4200) /* zero-sized array in struct/union */ #pragma warning(disable:4200) /* zero-sized array in struct/union */
/** /**
* Service registry record. * Service registry record.
*/ */
typedef struct _FSP_LAUNCH_REG_RECORD typedef struct _FSP_LAUNCH_REG_RECORD
{ {
PWSTR Agent; PWSTR Agent;
PWSTR Executable; PWSTR Executable;
PWSTR CommandLine; PWSTR CommandLine;
PWSTR WorkDirectory; PWSTR WorkDirectory;
PWSTR RunAs; PWSTR RunAs;
PWSTR Security; PWSTR Security;
PWSTR AuthPackage; PWSTR AuthPackage;
PWSTR Stderr; PWSTR Stderr;
PVOID Reserved0[4]; PVOID Reserved0[4];
ULONG JobControl; ULONG JobControl;
ULONG Credentials; ULONG Credentials;
ULONG AuthPackageId; ULONG AuthPackageId;
ULONG Recovery; ULONG Recovery;
ULONG Reserved1[4]; ULONG Reserved1[4];
UINT8 Buffer[]; UINT8 Buffer[];
} FSP_LAUNCH_REG_RECORD; } FSP_LAUNCH_REG_RECORD;
#pragma warning(pop) #pragma warning(pop)
/** /**
* Add/change/delete a service registry record. * Add/change/delete a service registry record.
* *
* @param ClassName * @param ClassName
* The service class name. * The service class name.
* @param Record * @param Record
* The record to set in the registry. If NULL, the registry record is deleted. * The record to set in the registry. If NULL, the registry record is deleted.
* @return * @return
* STATUS_SUCCESS or error code. * STATUS_SUCCESS or error code.
*/ */
FSP_API NTSTATUS FspLaunchRegSetRecord( FSP_API NTSTATUS FspLaunchRegSetRecord(
PWSTR ClassName, PWSTR ClassName,
const FSP_LAUNCH_REG_RECORD *Record); const FSP_LAUNCH_REG_RECORD *Record);
/** /**
* Get a service registry record. * Get a service registry record.
* *
* @param ClassName * @param ClassName
* The service class name. * The service class name.
* @param Agent * @param Agent
* The name of the agent that is retrieving the service record. This API matches * 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 supplied Agent against the Agent in the service record and it only returns
* the record if they match. Pass NULL to match any Agent. * the record if they match. Pass NULL to match any Agent.
* @param PRecord * @param PRecord
* Pointer to a record pointer. Memory for the service record will be allocated * 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 * and a pointer to it will be stored at this address. This memory must be later
* freed using FspLaunchRegFreeRecord. * freed using FspLaunchRegFreeRecord.
* @return * @return
* STATUS_SUCCESS or error code. * STATUS_SUCCESS or error code.
* @see * @see
* FspLaunchRegFreeRecord * FspLaunchRegFreeRecord
*/ */
FSP_API NTSTATUS FspLaunchRegGetRecord( FSP_API NTSTATUS FspLaunchRegGetRecord(
PWSTR ClassName, PWSTR Agent, PWSTR ClassName, PWSTR Agent,
FSP_LAUNCH_REG_RECORD **PRecord); FSP_LAUNCH_REG_RECORD **PRecord);
/** /**
* Free a service registry record. * Free a service registry record.
* *
* @param Record * @param Record
* The service record to free. * The service record to free.
* @see * @see
* FspLaunchRegGetRecord * FspLaunchRegGetRecord
*/ */
FSP_API VOID FspLaunchRegFreeRecord( FSP_API VOID FspLaunchRegFreeRecord(
FSP_LAUNCH_REG_RECORD *Record); FSP_LAUNCH_REG_RECORD *Record);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif #endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,11 +1,11 @@
arch=x64 arch=x64
prefix=${pcfiledir}/.. prefix=${pcfiledir}/..
incdir=${prefix}/inc/fuse incdir=${prefix}/inc/fuse
implib=${prefix}/bin/winfsp-${arch}.dll implib=${prefix}/bin/winfsp-${arch}.dll
Name: fuse Name: fuse
Description: WinFsp FUSE compatible API Description: WinFsp FUSE compatible API
Version: 2.8 Version: 2.8
URL: https://winfsp.dev URL: https://winfsp.dev
Libs: "${implib}" Libs: "${implib}"
Cflags: -I"${incdir}" Cflags: -I"${incdir}"

View File

@@ -1,11 +1,11 @@
arch=x64 arch=x64
prefix=${pcfiledir}/.. prefix=${pcfiledir}/..
incdir=${prefix}/inc/fuse3 incdir=${prefix}/inc/fuse3
implib=${prefix}/bin/winfsp-${arch}.dll implib=${prefix}/bin/winfsp-${arch}.dll
Name: fuse3 Name: fuse3
Description: WinFsp FUSE3 compatible API Description: WinFsp FUSE3 compatible API
Version: 3.2 Version: 3.2
URL: https://winfsp.dev URL: https://winfsp.dev
Libs: "${implib}" Libs: "${implib}"
Cflags: -I"${incdir}" Cflags: -I"${incdir}"

Binary file not shown.

Binary file not shown.

Binary file not shown.