#include "seafile/fs/winfsp_adapter.hpp" #include "seafile/fs/seafile_file_system.hpp" // // Created by Shell on 2026/6/20. // #include namespace seafile::fs { namespace { FSP_FILE_SYSTEM_INTERFACE FsInterface = { .GetVolumeInfo = WinFSPAdapter::GetVolumeInfo, .SetVolumeLabel = WinFSPAdapter::SetVolumeLabel_, .GetSecurityByName = WinFSPAdapter::GetSecurityByName, .Create = WinFSPAdapter::Create, .Open = WinFSPAdapter::Open, .Overwrite = WinFSPAdapter::Overwrite, .Cleanup = WinFSPAdapter::Cleanup, .Close = WinFSPAdapter::Close, .Read = WinFSPAdapter::Read, .GetFileInfo = WinFSPAdapter::GetFileInfo, .GetSecurity = WinFSPAdapter::GetSecurity, .SetSecurity = WinFSPAdapter::SetSecurity, .ReadDirectory = WinFSPAdapter::ReadDirectory, .GetDirInfoByName = WinFSPAdapter::GetDirInfoByName }; std::unordered_map fstab; } NTSTATUS WinFSPAdapter::SvcStart(FSP_SERVICE* Service, ULONG argc, PWSTR* argv) { FILETIME CreationTime; FSP_FSCTL_VOLUME_PARAMS VolumeParams = {}; FSP_FILE_SYSTEM* FileSystem = nullptr; GetSystemTimeAsFileTime(&CreationTime); std::memset(&VolumeParams, 0, sizeof(VolumeParams)); VolumeParams.SectorSize = 4096; VolumeParams.SectorsPerAllocationUnit = 1; VolumeParams.MaxComponentLength = 255; VolumeParams.VolumeCreationTime = reinterpret_cast(&CreationTime)->QuadPart; VolumeParams.VolumeSerialNumber = 0; VolumeParams.FileInfoTimeout = 1000; VolumeParams.CaseSensitiveSearch = 0; VolumeParams.CasePreservedNames = 1; VolumeParams.UnicodeOnDisk = 1; VolumeParams.PersistentAcls = 0; VolumeParams.PostCleanupWhenModifiedOnly = 1; // (4) VolumeParams.UmFileContextIsUserContext2 = 1; // (4) VolumeParams.ReadOnlyVolume = 1; wcscpy_s(VolumeParams.FileSystemName, sizeof VolumeParams.FileSystemName / sizeof(WCHAR), L"SeafileFS"); NTSTATUS Result = FspFileSystemCreate( const_cast(L"" FSP_FSCTL_DISK_DEVICE_NAME), &VolumeParams, &FsInterface, &FileSystem); if (!NT_SUCCESS(Result)) { return Result; } auto mount_point = std::wstring(L"X:"); auto seafile_file_system = new SeafileFileSystem("https://pan.hanwangsoft.com", mount_point); if (const auto ret= seafile_file_system->initialize("asypost@yeah.net", "Shell0805@china"); !ret.has_value()) { Result = STATUS_UNSUCCESSFUL; FspFileSystemDelete(FileSystem); delete seafile_file_system; return Result; } FileSystem->UserContext = seafile_file_system; fstab.insert({FileSystem, seafile_file_system}); Result = FspFileSystemSetMountPoint(FileSystem, static_cast(mount_point.data())); if (!NT_SUCCESS(Result)) { FspFileSystemDelete(FileSystem); fstab.erase(FileSystem); delete seafile_file_system; return Result; } Result = FspFileSystemStartDispatcher(FileSystem, 0); if (!NT_SUCCESS(Result)) { FspFileSystemDelete(FileSystem); fstab.erase(FileSystem); delete seafile_file_system; return Result; } FspFileSystemSetDebugLog( FileSystem, TRUE); std::cout << Result << std::endl; return Result; } NTSTATUS WinFSPAdapter::SvcStop(FSP_SERVICE* Service) { for (auto& [fileSystem, seafileFs] : fstab) { FspFileSystemStopDispatcher(fileSystem); fileSystem->UserContext = nullptr; FspFileSystemDelete(fileSystem); delete seafileFs; } fstab.clear(); return STATUS_SUCCESS; } NTSTATUS WinFSPAdapter::GetVolumeInfo(FSP_FILE_SYSTEM* FileSystem, FSP_FSCTL_VOLUME_INFO* VolumeInfo) { std::cout << "Getting Volume Info" << std::endl; const auto fs = static_cast(FileSystem->UserContext); return fs->GetVolumeInfo(VolumeInfo); } NTSTATUS WinFSPAdapter::Overwrite(FSP_FILE_SYSTEM* FileSystem, PVOID FileContext, UINT32 FileAttributes, BOOLEAN ReplaceFileAttributes, UINT64 AllocationSize, FSP_FSCTL_FILE_INFO* FileInfo) { const auto fs = static_cast(FileSystem->UserContext); return fs->Overwrite(FileContext, FileAttributes, ReplaceFileAttributes, AllocationSize, FileInfo); } void WinFSPAdapter::Close(FSP_FILE_SYSTEM* FileSystem, PVOID FileContext) { const auto fs = static_cast(FileSystem->UserContext); fs->Close(FileContext); } NTSTATUS WinFSPAdapter::Create(FSP_FILE_SYSTEM* FileSystem, PWSTR FileName, UINT32 CreateOptions, UINT32 GrantedAccess, UINT32 FileAttributes, PSECURITY_DESCRIPTOR SecurityDescriptor, UINT64 AllocationSize, PVOID* PFileContext, FSP_FSCTL_FILE_INFO* FileInfo) { const auto fs = static_cast(FileSystem->UserContext); return fs->Create(FileName, CreateOptions, GrantedAccess, FileAttributes, SecurityDescriptor, AllocationSize, PFileContext, FileInfo); } VOID WinFSPAdapter::Cleanup(FSP_FILE_SYSTEM* FileSystem, PVOID FileContext, PWSTR FileName, ULONG Flags) { const auto fs = static_cast(FileSystem->UserContext); fs->Cleanup(FileContext, FileName, Flags); } NTSTATUS WinFSPAdapter::ReadDirectory(FSP_FILE_SYSTEM* FileSystem, PVOID FileContext0, PWSTR Pattern, PWSTR Marker, PVOID Buffer, ULONG BufferLength, PULONG PBytesTransferred) { const auto fs = static_cast(FileSystem->UserContext); return fs->ReadDirectory(FileContext0, Pattern, Marker, Buffer, BufferLength, PBytesTransferred); } NTSTATUS WinFSPAdapter::GetDirInfoByName(FSP_FILE_SYSTEM* FileSystem, PVOID FileContext, PWSTR FileName, FSP_FSCTL_DIR_INFO* DirInfo) { const auto fs = static_cast(FileSystem->UserContext); return fs->GetDirInfoByName(FileContext, FileName, DirInfo); } NTSTATUS WinFSPAdapter::GetSecurityByName(FSP_FILE_SYSTEM* FileSystem, PWSTR FileName, PUINT32 PFileAttributes, PSECURITY_DESCRIPTOR SecurityDescriptor, SIZE_T* PSecurityDescriptorSize) { const auto fs = static_cast(FileSystem->UserContext); return fs->GetSecurityByName(FileName, PFileAttributes, SecurityDescriptor, PSecurityDescriptorSize); } NTSTATUS WinFSPAdapter::SetVolumeLabel_(FSP_FILE_SYSTEM* FileSystem, PWSTR VolumeLabel, FSP_FSCTL_VOLUME_INFO* VolumeInfo) { const auto fs = static_cast(FileSystem->UserContext); return fs->SetVolumeLabel_(VolumeLabel, VolumeInfo); } NTSTATUS WinFSPAdapter::Open(FSP_FILE_SYSTEM* FileSystem, PWSTR FileName, UINT32 CreateOptions, UINT32 GrantedAccess, PVOID* PFileContext, FSP_FSCTL_FILE_INFO* FileInfo) { const auto fs = static_cast(FileSystem->UserContext); return fs->Open(FileName, CreateOptions, GrantedAccess, PFileContext, FileInfo); } NTSTATUS WinFSPAdapter::Read(FSP_FILE_SYSTEM* FileSystem, PVOID FileContext, PVOID Buffer, UINT64 Offset, ULONG Length, PULONG PBytesTransferred) { const auto fs = static_cast(FileSystem->UserContext); return fs->Read(FileContext, Buffer, Offset, Length, PBytesTransferred); } NTSTATUS WinFSPAdapter::GetFileInfo(FSP_FILE_SYSTEM* FileSystem, HANDLE Handle, FSP_FSCTL_FILE_INFO* FileInfo) { const auto fs = static_cast(FileSystem->UserContext); return fs->GetFileInfo(Handle, FileInfo); } NTSTATUS WinFSPAdapter::SetSecurity(FSP_FILE_SYSTEM* FileSystem, PVOID FileContext, SECURITY_INFORMATION SecurityInformation, PSECURITY_DESCRIPTOR ModificationDescriptor) { return STATUS_ACCESS_DENIED; } NTSTATUS WinFSPAdapter::GetSecurity(FSP_FILE_SYSTEM* FileSystem, PVOID FileContext, PSECURITY_DESCRIPTOR SecurityDescriptor, SIZE_T* PSecurityDescriptorSize) { return STATUS_NOT_IMPLEMENTED; } }