2.0.0-rc (#9)
Some checks failed
BlockStorage/repertory_osx/pipeline/head This commit looks good
BlockStorage/repertory_windows/pipeline/head This commit looks good
BlockStorage/repertory/pipeline/head There was a failure building this commit
BlockStorage/repertory_linux_builds/pipeline/head This commit looks good
BlockStorage/repertory_osx_builds/pipeline/head There was a failure building this commit
Some checks failed
BlockStorage/repertory_osx/pipeline/head This commit looks good
BlockStorage/repertory_windows/pipeline/head This commit looks good
BlockStorage/repertory/pipeline/head There was a failure building this commit
BlockStorage/repertory_linux_builds/pipeline/head This commit looks good
BlockStorage/repertory_osx_builds/pipeline/head There was a failure building this commit
### Issues * \#1 \[bug\] Unable to mount S3 due to 'item_not_found' exception * \#2 Require bucket name for S3 mounts * \#3 \[bug\] File size is not being updated in S3 mount * \#4 Upgrade to libfuse-3.x.x * \#5 Switch to renterd for Sia support * \#6 Switch to cpp-httplib to further reduce dependencies * \#7 Remove global_data and calculate used disk space per provider * \#8 Switch to libcurl for S3 mount support ### Changes from v1.x.x * Added read-only encrypt provider * Pass-through mount point that transparently encrypts source data using `XChaCha20-Poly1305` * Added S3 encryption support via `XChaCha20-Poly1305` * Added replay protection to remote mounts * Added support base64 writes in remote FUSE * Created static linked Linux binaries for `amd64` and `aarch64` using `musl-libc` * Removed legacy Sia renter support * Removed Skynet support * Fixed multiple remote mount WinFSP API issues on \*NIX servers * Implemented chunked read and write * Writes for non-cached files are performed in chunks of 8Mib * Removed `repertory-ui` support * Removed `FreeBSD` support * Switched to `libsodium` over `CryptoPP` * Switched to `XChaCha20-Poly1305` for remote mounts * Updated `GoogleTest` to v1.14.0 * Updated `JSON for Modern C++` to v3.11.2 * Updated `OpenSSL` to v1.1.1w * Updated `RocksDB` to v8.5.3 * Updated `WinFSP` to 2023 * Updated `boost` to v1.78.0 * Updated `cURL` to v8.3.0 * Updated `zlib` to v1.3 * Use `upload_manager` for all providers * Adds a delay to uploads to prevent excessive API calls * Supports re-upload after mount restart for incomplete uploads * NOTE: Uploads for all providers are full file (no resume support) * Multipart upload support is planned for S3 Reviewed-on: #9
This commit is contained in:
902
3rd_party/winfsp-2.0/inc/winfsp/winfsp.hpp
vendored
Normal file
902
3rd_party/winfsp-2.0/inc/winfsp/winfsp.hpp
vendored
Normal file
@@ -0,0 +1,902 @@
|
||||
/**
|
||||
* @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
|
Reference in New Issue
Block a user