diff --git a/include/seafile/seafile_api.hpp b/include/seafile/seafile_api.hpp index 7c9d7e1..505fbd0 100644 --- a/include/seafile/seafile_api.hpp +++ b/include/seafile/seafile_api.hpp @@ -53,7 +53,7 @@ namespace seafile response.error.message)); } - if (response.status_code != 200) + if (response.status_code != 200 && response.status_code != 206) { return tl::make_unexpected( SeafileException( @@ -265,8 +265,12 @@ namespace seafile start ? std::to_string(*start) : "", end ? std::to_string(*end) : ""); header.emplace("range", range); - const auto response = cpr::Get(url, header); - return parseResponse(response); + const auto& response = cpr::Get(url, header); + if (response.status_code != 200 && response.status_code != 206) { + return tl::make_unexpected(SeafileException{std::format("HTTP Error:{}", response.status_code)}); + }else { + return response.text; + } } else { diff --git a/src/seafile/fs/seafile_file_system.cpp b/src/seafile/fs/seafile_file_system.cpp index 13b662a..f498c72 100644 --- a/src/seafile/fs/seafile_file_system.cpp +++ b/src/seafile/fs/seafile_file_system.cpp @@ -2,36 +2,31 @@ #include "seafile/fs/file_context.hpp" #include "util/string_util.hpp" +#include -namespace seafile::fs -{ - namespace - { +namespace seafile::fs { + namespace { constexpr int64_t UNIX_EPOCH_AS_FILETIME = 116444736000000000LL; constexpr int64_t HUNDREDS_OF_NANOSECONDS_PER_SECOND = 10000000LL; - int64_t UnixTimeToFileTime(int64_t unix_time) - { + int64_t UnixTimeToFileTime(int64_t unix_time) { return UNIX_EPOCH_AS_FILETIME + unix_time * HUNDREDS_OF_NANOSECONDS_PER_SECOND; } - std::string normalize_path(const std::string& path) - { + std::string normalize_path(const std::string &path) { std::string result = path; std::ranges::replace(result, '\\', '/'); return result; } - int64_t NowFileTime() - { + int64_t NowFileTime() { FILETIME ft; GetSystemTimeAsFileTime(&ft); return (static_cast(ft.dwHighDateTime) << 32) | ft.dwLowDateTime; } - void SetFileInfo(FSP_FSCTL_FILE_INFO* FileInfo, uint32_t attributes, uint64_t size, int64_t mtime) - { + void SetFileInfo(FSP_FSCTL_FILE_INFO *FileInfo, uint32_t attributes, uint64_t size, int64_t mtime) { FileInfo->FileAttributes = attributes; FileInfo->AllocationSize = size; FileInfo->FileSize = size; @@ -45,40 +40,33 @@ namespace seafile::fs } - tl::expected SeafileFileSystem::initialize(const std::string& username, - const std::string& password) - { + tl::expected SeafileFileSystem::initialize(const std::string &username, + const std::string &password) { const auto authToken = api.authToken(username, password); - if (authToken.has_value()) - { + if (authToken.has_value()) { this->token = authToken.value().token; - if (const auto repo = api.defaultRepo(this->token, this->token_type); repo.has_value()) - { + if (const auto repo = api.defaultRepo(this->token, this->token_type); repo.has_value()) { this->repo_id = repo.value().repo_id.value_or(""); return {}; } + spdlog::error("no default repo found"); return tl::make_unexpected(SeafileException("No default repo found")); } + spdlog::error(std::format("user login failed:{}", authToken.error().what())); return tl::make_unexpected(authToken.error()); } - void SeafileFileSystem::Close(PVOID FileContext) - { - delete static_cast(FileContext); + void SeafileFileSystem::Close(PVOID FileContext) { + delete static_cast(FileContext); } NTSTATUS SeafileFileSystem::GetSecurityByName(PWSTR FileName, PUINT32 PFileAttributes, PSECURITY_DESCRIPTOR SecurityDescriptor, - SIZE_T* PSecurityDescriptorSize) - { - if (PFileAttributes) - { - if (wcscmp(FileName, L"\\") == 0) - { + SIZE_T *PSecurityDescriptorSize) { + if (PFileAttributes) { + if (wcscmp(FileName, L"\\") == 0) { *PFileAttributes = FILE_ATTRIBUTE_DIRECTORY; - } - else - { + } else { *PFileAttributes = FILE_ATTRIBUTE_NORMAL; } } @@ -89,69 +77,67 @@ namespace seafile::fs } NTSTATUS SeafileFileSystem::Overwrite(PVOID FileContext, UINT32 FileAttributes, BOOLEAN ReplaceFileAttributes, - UINT64 AllocationSize, FSP_FSCTL_FILE_INFO* FileInfo) - { + UINT64 AllocationSize, FSP_FSCTL_FILE_INFO *FileInfo) { return STATUS_MEDIA_WRITE_PROTECTED; } - NTSTATUS SeafileFileSystem::GetVolumeInfo(FSP_FSCTL_VOLUME_INFO* VolumeInfo) const - { - if (const auto userInfo = api.accountInfo(this->token, this->token_type); userInfo.has_value()) - { - const auto& info = userInfo.value(); + NTSTATUS SeafileFileSystem::GetVolumeInfo(FSP_FSCTL_VOLUME_INFO *VolumeInfo) const { + if (const auto userInfo = api.accountInfo(this->token, this->token_type); userInfo.has_value()) { + const auto &info = userInfo.value(); VolumeInfo->FreeSize = info.total - info.usage; VolumeInfo->TotalSize = info.total; - if (!this->volume_label.empty()) - { + if (!this->volume_label.empty()) { wcscpy_s(VolumeInfo->VolumeLabel, this->volume_label.data()); VolumeInfo->VolumeLabelLength = static_cast((wcslen(VolumeInfo->VolumeLabel) * sizeof(WCHAR))); } + spdlog::info(std::format("volume total size: {}, free size: {}", VolumeInfo->TotalSize, + VolumeInfo->FreeSize)); return STATUS_SUCCESS; } + spdlog::error("failed to get volume info"); return STATUS_END_OF_MEDIA; } - void SeafileFileSystem::Cleanup(PVOID FileContext, PWSTR FileName, ULONG Flags) - { + void SeafileFileSystem::Cleanup(PVOID FileContext, PWSTR FileName, ULONG Flags) { } - NTSTATUS SeafileFileSystem::Open(PWSTR FileName, UINT32 CreateOptions, UINT32 GrantedAccess, PVOID* PFileContext, - FSP_FSCTL_FILE_INFO* FileInfo) - { - if (repo_id.empty()) - { + NTSTATUS SeafileFileSystem::Open(PWSTR FileName, UINT32 CreateOptions, UINT32 GrantedAccess, PVOID *PFileContext, + FSP_FSCTL_FILE_INFO *FileInfo) { + const auto path = normalize_path(shell::util::StringUtil::utf16le_to_utf8(FileName)); + if (repo_id.empty()) { + spdlog::error(std::format("can't open file: {}, repo id is empty", path)); return STATUS_OBJECT_NAME_NOT_FOUND; } - const auto path = normalize_path(shell::util::StringUtil::utf16le_to_utf8(FileName)); - if (path == "/") - { + + if (path == "/") { auto repo = api.repoInfo(repo_id, token, token_type); if (!repo.has_value()) return STATUS_OBJECT_NAME_NOT_FOUND; const auto ctx = new SeaFileContext{repo->id, path, SeaFileContext::Type::DIRECTORY, 0, ""}; *PFileContext = ctx; SetFileInfo(FileInfo, FILE_ATTRIBUTE_DIRECTORY, repo->size, repo->mtime); + spdlog::info(std::format("open directory {} success", path)); return STATUS_SUCCESS; } - if (const auto dirInfo = api.dirDetail(repo_id, path, token, token_type); dirInfo.has_value()) - { - const auto& info = dirInfo.value(); + if (const auto dirInfo = api.dirDetail(repo_id, path, token, token_type); dirInfo.has_value()) { + const auto &info = dirInfo.value(); const auto ctx = new SeaFileContext{info.repo_id, info.path, SeaFileContext::Type::DIRECTORY, 0, ""}; *PFileContext = ctx; SetFileInfo(FileInfo,FILE_ATTRIBUTE_DIRECTORY, 0, 0); + spdlog::info(std::format("open directory {} success", path)); return STATUS_SUCCESS; } - if (const auto fileInfo = api.fileDetail(repo_id, path, token, token_type); fileInfo.has_value()) - { - const auto& info = fileInfo.value(); + if (const auto fileInfo = api.fileDetail(repo_id, path, token, token_type); fileInfo.has_value()) { + const auto &info = fileInfo.value(); const auto ctx = new SeaFileContext(repo_id, path, SeaFileContext::Type::FILE, info.size, ""); *PFileContext = ctx; - SetFileInfo(FileInfo,FILE_ATTRIBUTE_ARCHIVE, 0, 0); + SetFileInfo(FileInfo,FILE_ATTRIBUTE_ARCHIVE, info.size, 0); + spdlog::info(std::format("open file {} success", path)); return STATUS_SUCCESS; } @@ -159,76 +145,62 @@ namespace seafile::fs } NTSTATUS SeafileFileSystem::Read(PVOID FileContext, PVOID Buffer, UINT64 Offset, ULONG Length, - PULONG PBytesTransferred) - { - const auto fc = static_cast(FileContext); + PULONG PBytesTransferred) { + const auto fc = static_cast(FileContext); auto result = api.downloadFile( fc->repo_id, fc->path, Offset, Offset + Length - 1, token, token_type); - if (result.has_value()) - { - const auto& data = result.value(); + if (result.has_value()) { + const auto &data = result.value(); const auto copy_len = (std::min)(data.size(), static_cast(Length)); memcpy(Buffer, data.data(), copy_len); *PBytesTransferred = static_cast(copy_len); + spdlog::info(std::format("read file {} bytes offset {} length {} success", fc->path,Offset, Length)); return STATUS_SUCCESS; } return STATUS_UNSUCCESSFUL; } NTSTATUS SeafileFileSystem::ReadDirectory(PVOID FileContext, PWSTR Pattern, PWSTR Marker, - PVOID Buffer, ULONG BufferLength, PULONG PBytesTransferred) - { - const auto fc = static_cast(FileContext); + PVOID Buffer, ULONG BufferLength, PULONG PBytesTransferred) { + const auto fc = static_cast(FileContext); *PBytesTransferred = 0; const auto path = std::ranges::replace(fc->path, '\\', '/'); const auto entries_result = api.repoDir(fc->repo_id, fc->path, token, token_type); - if (entries_result.has_value()) - { - const auto& entries = entries_result.value(); + if (entries_result.has_value()) { + const auto &entries = entries_result.value(); size_t start = 0; - if (Marker) - { + if (Marker) { const auto marker = shell::util::StringUtil::utf16le_to_utf8(Marker); - for (auto i = 0; i < entries.size(); ++i) - { - if (entries[i].name == marker) - { + for (auto i = 0; i < entries.size(); ++i) { + if (entries[i].name == marker) { start = i + 1; break; } } } - for (auto i = start; i < entries.size(); ++i) - { - const auto& entry = entries[i]; + for (auto i = start; i < entries.size(); ++i) { + const auto &entry = entries[i]; const auto entry_name = shell::util::StringUtil::utf8_to_utf16le(entry.name); const auto size = sizeof(FSP_FSCTL_DIR_INFO) + ((entry_name.size() + 1) * sizeof(WCHAR)); - const auto dir_info = static_cast(std::malloc(size)); + const auto dir_info = static_cast(std::malloc(size)); std::memset(dir_info, 0, size); dir_info->Size = size; dir_info->FileInfo.FileSize = entry.size.value_or(0); - if (entry.type == "file") - { + if (entry.type == "file") { dir_info->FileInfo.FileAttributes = FILE_ATTRIBUTE_ARCHIVE; - } - else - { + } else { dir_info->FileInfo.FileAttributes = FILE_ATTRIBUTE_DIRECTORY; } wcscpy_s(dir_info->FileNameBuf, entry_name.size() + 1, entry_name.data()); - if (*PBytesTransferred + size < BufferLength) - { - if (!FspFileSystemAddDirInfo(dir_info, Buffer, BufferLength, PBytesTransferred)) - { + if (*PBytesTransferred + size < BufferLength) { + if (!FspFileSystemAddDirInfo(dir_info, Buffer, BufferLength, PBytesTransferred)) { break; } - } - else - { + } else { break; } } @@ -240,13 +212,10 @@ namespace seafile::fs return STATUS_UNSUCCESSFUL; } - NTSTATUS SeafileFileSystem::GetFileInfo(HANDLE Handle, FSP_FSCTL_FILE_INFO* FileInfo) - { - auto fc = static_cast(Handle); - if (fc->repo_id.empty() || fc->path == "/" || fc->path.back() == '/') - { - if (fc->repo_id.empty()) - { + NTSTATUS SeafileFileSystem::GetFileInfo(HANDLE Handle, FSP_FSCTL_FILE_INFO *FileInfo) { + auto fc = static_cast(Handle); + if (fc->repo_id.empty() || fc->path == "/" || fc->path.back() == '/') { + if (fc->repo_id.empty()) { SetFileInfo(FileInfo, FILE_ATTRIBUTE_DIRECTORY, 0, 0); return STATUS_SUCCESS; } @@ -260,24 +229,22 @@ namespace seafile::fs if (!fdetail.has_value()) return STATUS_UNSUCCESSFUL; SetFileInfo(FileInfo, FILE_ATTRIBUTE_NORMAL, fdetail->size, fdetail->mtime); + spdlog::info(std::format("get file {} info success", fc->path)); return STATUS_SUCCESS; } NTSTATUS SeafileFileSystem::Create(PWSTR FileName, UINT32 CreateOptions, UINT32 GrantedAccess, UINT32 FileAttributes, PSECURITY_DESCRIPTOR SecurityDescriptor, - UINT64 AllocationSize, PVOID* PFileContext, FSP_FSCTL_FILE_INFO* FileInfo) - { + UINT64 AllocationSize, PVOID *PFileContext, FSP_FSCTL_FILE_INFO *FileInfo) { return Open(FileName, CreateOptions, GrantedAccess, PFileContext, FileInfo); } NTSTATUS SeafileFileSystem::GetDirInfoByName(PVOID FileContext, PWSTR FileName, - FSP_FSCTL_DIR_INFO* DirInfo) - { - auto fc = static_cast(FileContext); + FSP_FSCTL_DIR_INFO *DirInfo) { + auto fc = static_cast(FileContext); std::wstring name(FileName); - if (name == L"." || name == L"..") - { + if (name == L"." || name == L"..") { memset(DirInfo, 0, sizeof(FSP_FSCTL_DIR_INFO)); DirInfo->Size = sizeof(FSP_FSCTL_DIR_INFO) + (wcslen(FileName) + 1) * sizeof(WCHAR); SetFileInfo(&DirInfo->FileInfo, FILE_ATTRIBUTE_DIRECTORY, 0, 0); @@ -286,11 +253,10 @@ namespace seafile::fs } std::string utf8_name; - for (const auto c : name) + for (const auto c: name) utf8_name += static_cast(c); - if (fc->repo_id.empty()) - { + if (fc->repo_id.empty()) { return STATUS_OBJECT_NAME_NOT_FOUND; } @@ -298,8 +264,7 @@ namespace seafile::fs if (!entries.has_value()) return STATUS_OBJECT_NAME_NOT_FOUND; - for (const auto& entry : entries.value()) - { + for (const auto &entry: entries.value()) { if (entry.name != utf8_name) continue; memset(DirInfo, 0, sizeof(FSP_FSCTL_DIR_INFO)); @@ -314,8 +279,7 @@ namespace seafile::fs return STATUS_OBJECT_NAME_NOT_FOUND; } - NTSTATUS SeafileFileSystem::SetVolumeLabel_(PWSTR VolumeLabel, FSP_FSCTL_VOLUME_INFO* VolumeInfo) - { + NTSTATUS SeafileFileSystem::SetVolumeLabel_(PWSTR VolumeLabel, FSP_FSCTL_VOLUME_INFO *VolumeInfo) { return STATUS_ACCESS_DENIED; } } diff --git a/src/seafile/fs/winfsp_adapter.cpp b/src/seafile/fs/winfsp_adapter.cpp index a408f4d..294ae6c 100644 --- a/src/seafile/fs/winfsp_adapter.cpp +++ b/src/seafile/fs/winfsp_adapter.cpp @@ -64,7 +64,7 @@ namespace seafile::fs return Result; } auto mount_point = std::wstring(L"X:"); - auto seafile_file_system = new SeafileFileSystem("https://pan.hanwangsoft.com", mount_point); + auto seafile_file_system = new SeafileFileSystem("https://pan.hanwangsoft.com", L"Seafile"); if (const auto ret= seafile_file_system->initialize("asypost@yeah.net", "Shell0805@china"); !ret.has_value()) { Result = STATUS_UNSUCCESSFUL; @@ -76,7 +76,7 @@ namespace seafile::fs FileSystem->UserContext = seafile_file_system; fstab.insert({FileSystem, seafile_file_system}); - Result = FspFileSystemSetMountPoint(FileSystem, static_cast(mount_point.data())); + Result = FspFileSystemSetMountPoint(FileSystem, mount_point.data()); if (!NT_SUCCESS(Result)) { @@ -121,7 +121,6 @@ namespace seafile::fs 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); }