diff options
| author | FearlessTobi <thm.frey@gmail.com> | 2024-02-10 20:58:43 +0100 | 
|---|---|---|
| committer | FearlessTobi <thm.frey@gmail.com> | 2024-02-19 19:20:46 +0100 | 
| commit | 934e420e36e817c673a839e2a417785906bfe91c (patch) | |
| tree | 13777628e911468f88ed928d0bfa6f4a3d416f10 | |
| parent | d5e4617ab5c8b7e72e2155de886135766ce61c7a (diff) | |
fs: Refactor to use cmif serialization
| -rw-r--r-- | src/core/file_sys/fssrv/fssrv_sf_path.h | 36 | ||||
| -rw-r--r-- | src/core/hle/service/filesystem/fsp/fs_i_directory.cpp | 32 | ||||
| -rw-r--r-- | src/core/hle/service/filesystem/fsp/fs_i_directory.h | 6 | ||||
| -rw-r--r-- | src/core/hle/service/filesystem/fsp/fs_i_file.cpp | 78 | ||||
| -rw-r--r-- | src/core/hle/service/filesystem/fsp/fs_i_file.h | 16 | ||||
| -rw-r--r-- | src/core/hle/service/filesystem/fsp/fs_i_filesystem.cpp | 292 | ||||
| -rw-r--r-- | src/core/hle/service/filesystem/fsp/fs_i_filesystem.h | 80 | 
7 files changed, 245 insertions, 295 deletions
diff --git a/src/core/file_sys/fssrv/fssrv_sf_path.h b/src/core/file_sys/fssrv/fssrv_sf_path.h new file mode 100644 index 000000000..1752a413d --- /dev/null +++ b/src/core/file_sys/fssrv/fssrv_sf_path.h @@ -0,0 +1,36 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "core/file_sys/fs_directory.h" + +namespace FileSys::Sf { + +struct Path { +    char str[EntryNameLengthMax + 1]; + +    static constexpr Path Encode(const char* p) { +        Path path = {}; +        for (size_t i = 0; i < sizeof(path) - 1; i++) { +            path.str[i] = p[i]; +            if (p[i] == '\x00') { +                break; +            } +        } +        return path; +    } + +    static constexpr size_t GetPathLength(const Path& path) { +        size_t len = 0; +        for (size_t i = 0; i < sizeof(path) - 1 && path.str[i] != '\x00'; i++) { +            len++; +        } +        return len; +    } +}; +static_assert(std::is_trivially_copyable_v<Path>, "Path must be trivially copyable."); + +using FspPath = Path; + +} // namespace FileSys::Sf
\ No newline at end of file diff --git a/src/core/hle/service/filesystem/fsp/fs_i_directory.cpp b/src/core/hle/service/filesystem/fsp/fs_i_directory.cpp index 661da5326..8483394d0 100644 --- a/src/core/hle/service/filesystem/fsp/fs_i_directory.cpp +++ b/src/core/hle/service/filesystem/fsp/fs_i_directory.cpp @@ -3,8 +3,8 @@  #include "core/file_sys/fs_filesystem.h"  #include "core/file_sys/savedata_factory.h" +#include "core/hle/service/cmif_serialization.h"  #include "core/hle/service/filesystem/fsp/fs_i_directory.h" -#include "core/hle/service/ipc_helpers.h"  namespace Service::FileSystem { @@ -13,38 +13,24 @@ IDirectory::IDirectory(Core::System& system_, FileSys::VirtualDir directory_,      : ServiceFramework{system_, "IDirectory"},        backend(std::make_unique<FileSys::Fsa::IDirectory>(directory_, mode)) {      static const FunctionInfo functions[] = { -        {0, &IDirectory::Read, "Read"}, -        {1, &IDirectory::GetEntryCount, "GetEntryCount"}, +        {0, D<&IDirectory::Read>, "Read"}, +        {1, D<&IDirectory::GetEntryCount>, "GetEntryCount"},      };      RegisterHandlers(functions);  } -void IDirectory::Read(HLERequestContext& ctx) { +Result IDirectory::Read( +    Out<s64> out_count, +    const OutArray<FileSys::DirectoryEntry, BufferAttr_HipcMapAlias> out_entries) {      LOG_DEBUG(Service_FS, "called."); -    // Calculate how many entries we can fit in the output buffer -    const u64 count_entries = ctx.GetWriteBufferNumElements<FileSys::DirectoryEntry>(); - -    s64 out_count{}; -    FileSys::DirectoryEntry* out_entries = nullptr; -    const auto result = backend->Read(&out_count, out_entries, count_entries); - -    // Write the data to memory -    ctx.WriteBuffer(out_entries, out_count); - -    IPC::ResponseBuilder rb{ctx, 4}; -    rb.Push(result); -    rb.Push(out_count); +    R_RETURN(backend->Read(out_count, out_entries.data(), out_entries.size()));  } -void IDirectory::GetEntryCount(HLERequestContext& ctx) { +Result IDirectory::GetEntryCount(Out<s64> out_count) {      LOG_DEBUG(Service_FS, "called"); -    s64 out_count{}; - -    IPC::ResponseBuilder rb{ctx, 4}; -    rb.Push(backend->GetEntryCount(&out_count)); -    rb.Push(out_count); +    R_RETURN(backend->GetEntryCount(out_count));  }  } // namespace Service::FileSystem diff --git a/src/core/hle/service/filesystem/fsp/fs_i_directory.h b/src/core/hle/service/filesystem/fsp/fs_i_directory.h index 0dec4367b..b6251f7fd 100644 --- a/src/core/hle/service/filesystem/fsp/fs_i_directory.h +++ b/src/core/hle/service/filesystem/fsp/fs_i_directory.h @@ -5,6 +5,7 @@  #include "core/file_sys/fsa/fs_i_directory.h"  #include "core/file_sys/vfs/vfs.h" +#include "core/hle/service/cmif_types.h"  #include "core/hle/service/filesystem/filesystem.h"  #include "core/hle/service/service.h" @@ -22,8 +23,9 @@ public:  private:      std::unique_ptr<FileSys::Fsa::IDirectory> backend; -    void Read(HLERequestContext& ctx); -    void GetEntryCount(HLERequestContext& ctx); +    Result Read(Out<s64> out_count, +                const OutArray<FileSys::DirectoryEntry, BufferAttr_HipcMapAlias> out_entries); +    Result GetEntryCount(Out<s64> out_count);  };  } // namespace Service::FileSystem diff --git a/src/core/hle/service/filesystem/fsp/fs_i_file.cpp b/src/core/hle/service/filesystem/fsp/fs_i_file.cpp index 8fb8620de..a355d46ae 100644 --- a/src/core/hle/service/filesystem/fsp/fs_i_file.cpp +++ b/src/core/hle/service/filesystem/fsp/fs_i_file.cpp @@ -2,86 +2,64 @@  // SPDX-License-Identifier: GPL-2.0-or-later  #include "core/file_sys/errors.h" +#include "core/hle/service/cmif_serialization.h"  #include "core/hle/service/filesystem/fsp/fs_i_file.h" -#include "core/hle/service/ipc_helpers.h"  namespace Service::FileSystem {  IFile::IFile(Core::System& system_, FileSys::VirtualFile file_)      : ServiceFramework{system_, "IFile"}, backend{std::make_unique<FileSys::Fsa::IFile>(file_)} { +    // clang-format off      static const FunctionInfo functions[] = { -        {0, &IFile::Read, "Read"}, -        {1, &IFile::Write, "Write"}, -        {2, &IFile::Flush, "Flush"}, -        {3, &IFile::SetSize, "SetSize"}, -        {4, &IFile::GetSize, "GetSize"}, +        {0, D<&IFile::Read>, "Read"}, +        {1, D<&IFile::Write>, "Write"}, +        {2, D<&IFile::Flush>, "Flush"}, +        {3, D<&IFile::SetSize>, "SetSize"}, +        {4, D<&IFile::GetSize>, "GetSize"},          {5, nullptr, "OperateRange"},          {6, nullptr, "OperateRangeWithBuffer"},      }; +    // clang-format on      RegisterHandlers(functions);  } -void IFile::Read(HLERequestContext& ctx) { -    IPC::RequestParser rp{ctx}; -    const u64 option = rp.Pop<u64>(); -    const s64 offset = rp.Pop<s64>(); -    const s64 length = rp.Pop<s64>(); - -    LOG_DEBUG(Service_FS, "called, option={}, offset=0x{:X}, length={}", option, offset, length); +Result IFile::Read( +    FileSys::ReadOption option, Out<s64> out_size, s64 offset, +    const OutBuffer<BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure> out_buffer, +    s64 size) { +    LOG_DEBUG(Service_FS, "called, option={}, offset=0x{:X}, length={}", option.value, offset, +              size);      // Read the data from the Storage backend -    std::vector<u8> output(length); -    std::size_t bytes_read; -    const auto result = backend->Read(&bytes_read, offset, output.data(), length); - -    // Write the data to memory -    ctx.WriteBuffer(output); - -    IPC::ResponseBuilder rb{ctx, 4}; -    rb.Push(result); -    rb.Push(static_cast<u64>(bytes_read)); +    R_RETURN( +        backend->Read(reinterpret_cast<size_t*>(out_size.Get()), offset, out_buffer.data(), size));  } -void IFile::Write(HLERequestContext& ctx) { -    IPC::RequestParser rp{ctx}; -    const auto option = rp.PopRaw<FileSys::WriteOption>(); -    [[maybe_unused]] const u32 unused = rp.Pop<u32>(); -    const s64 offset = rp.Pop<s64>(); -    const s64 length = rp.Pop<s64>(); - +Result IFile::Write( +    const InBuffer<BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure> buffer, +    FileSys::WriteOption option, s64 offset, s64 size) {      LOG_DEBUG(Service_FS, "called, option={}, offset=0x{:X}, length={}", option.value, offset, -              length); - -    const auto data = ctx.ReadBuffer(); +              size); -    IPC::ResponseBuilder rb{ctx, 2}; -    rb.Push(backend->Write(offset, data.data(), length, option)); +    R_RETURN(backend->Write(offset, buffer.data(), size, option));  } -void IFile::Flush(HLERequestContext& ctx) { +Result IFile::Flush() {      LOG_DEBUG(Service_FS, "called"); -    IPC::ResponseBuilder rb{ctx, 2}; -    rb.Push(backend->Flush()); +    R_RETURN(backend->Flush());  } -void IFile::SetSize(HLERequestContext& ctx) { -    IPC::RequestParser rp{ctx}; -    const u64 size = rp.Pop<u64>(); +Result IFile::SetSize(s64 size) {      LOG_DEBUG(Service_FS, "called, size={}", size); -    IPC::ResponseBuilder rb{ctx, 2}; -    rb.Push(backend->SetSize(size)); +    R_RETURN(backend->SetSize(size));  } -void IFile::GetSize(HLERequestContext& ctx) { -    s64 size; -    const auto result = backend->GetSize(&size); -    LOG_DEBUG(Service_FS, "called, size={}", size); +Result IFile::GetSize(Out<s64> out_size) { +    LOG_DEBUG(Service_FS, "called"); -    IPC::ResponseBuilder rb{ctx, 4}; -    rb.Push(result); -    rb.Push<u64>(size); +    R_RETURN(backend->GetSize(out_size));  }  } // namespace Service::FileSystem diff --git a/src/core/hle/service/filesystem/fsp/fs_i_file.h b/src/core/hle/service/filesystem/fsp/fs_i_file.h index 887fd3ba2..e8599ee2f 100644 --- a/src/core/hle/service/filesystem/fsp/fs_i_file.h +++ b/src/core/hle/service/filesystem/fsp/fs_i_file.h @@ -4,6 +4,7 @@  #pragma once  #include "core/file_sys/fsa/fs_i_file.h" +#include "core/hle/service/cmif_types.h"  #include "core/hle/service/filesystem/filesystem.h"  #include "core/hle/service/service.h" @@ -16,11 +17,16 @@ public:  private:      std::unique_ptr<FileSys::Fsa::IFile> backend; -    void Read(HLERequestContext& ctx); -    void Write(HLERequestContext& ctx); -    void Flush(HLERequestContext& ctx); -    void SetSize(HLERequestContext& ctx); -    void GetSize(HLERequestContext& ctx); +    Result Read(FileSys::ReadOption option, Out<s64> out_size, s64 offset, +                const OutBuffer<BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure> +                    out_buffer, +                s64 size); +    Result Write( +        const InBuffer<BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure> buffer, +        FileSys::WriteOption option, s64 offset, s64 size); +    Result Flush(); +    Result SetSize(s64 size); +    Result GetSize(Out<s64> out_size);  };  } // namespace Service::FileSystem diff --git a/src/core/hle/service/filesystem/fsp/fs_i_filesystem.cpp b/src/core/hle/service/filesystem/fsp/fs_i_filesystem.cpp index 1e69d22b8..7fc62cb3e 100644 --- a/src/core/hle/service/filesystem/fsp/fs_i_filesystem.cpp +++ b/src/core/hle/service/filesystem/fsp/fs_i_filesystem.cpp @@ -2,274 +2,172 @@  // SPDX-License-Identifier: GPL-2.0-or-later  #include "common/string_util.h" +#include "core/file_sys/fssrv/fssrv_sf_path.h" +#include "core/hle/service/cmif_serialization.h"  #include "core/hle/service/filesystem/fsp/fs_i_directory.h"  #include "core/hle/service/filesystem/fsp/fs_i_file.h"  #include "core/hle/service/filesystem/fsp/fs_i_filesystem.h" -#include "core/hle/service/ipc_helpers.h"  namespace Service::FileSystem { -IFileSystem::IFileSystem(Core::System& system_, FileSys::VirtualDir dir_, SizeGetter size_) +IFileSystem::IFileSystem(Core::System& system_, FileSys::VirtualDir dir_, SizeGetter size_getter_)      : ServiceFramework{system_, "IFileSystem"}, -      backend{std::make_unique<FileSys::Fsa::IFileSystem>(dir_)}, size{std::move(size_)} { +      backend{std::make_unique<FileSys::Fsa::IFileSystem>(dir_)}, +      size_getter{std::move(size_getter_)} {      static const FunctionInfo functions[] = { -        {0, &IFileSystem::CreateFile, "CreateFile"}, -        {1, &IFileSystem::DeleteFile, "DeleteFile"}, -        {2, &IFileSystem::CreateDirectory, "CreateDirectory"}, -        {3, &IFileSystem::DeleteDirectory, "DeleteDirectory"}, -        {4, &IFileSystem::DeleteDirectoryRecursively, "DeleteDirectoryRecursively"}, -        {5, &IFileSystem::RenameFile, "RenameFile"}, +        {0, D<&IFileSystem::CreateFile>, "CreateFile"}, +        {1, D<&IFileSystem::DeleteFile>, "DeleteFile"}, +        {2, D<&IFileSystem::CreateDirectory>, "CreateDirectory"}, +        {3, D<&IFileSystem::DeleteDirectory>, "DeleteDirectory"}, +        {4, D<&IFileSystem::DeleteDirectoryRecursively>, "DeleteDirectoryRecursively"}, +        {5, D<&IFileSystem::RenameFile>, "RenameFile"},          {6, nullptr, "RenameDirectory"}, -        {7, &IFileSystem::GetEntryType, "GetEntryType"}, -        {8, &IFileSystem::OpenFile, "OpenFile"}, -        {9, &IFileSystem::OpenDirectory, "OpenDirectory"}, -        {10, &IFileSystem::Commit, "Commit"}, -        {11, &IFileSystem::GetFreeSpaceSize, "GetFreeSpaceSize"}, -        {12, &IFileSystem::GetTotalSpaceSize, "GetTotalSpaceSize"}, -        {13, &IFileSystem::CleanDirectoryRecursively, "CleanDirectoryRecursively"}, -        {14, &IFileSystem::GetFileTimeStampRaw, "GetFileTimeStampRaw"}, +        {7, D<&IFileSystem::GetEntryType>, "GetEntryType"}, +        {8, D<&IFileSystem::OpenFile>, "OpenFile"}, +        {9, D<&IFileSystem::OpenDirectory>, "OpenDirectory"}, +        {10, D<&IFileSystem::Commit>, "Commit"}, +        {11, D<&IFileSystem::GetFreeSpaceSize>, "GetFreeSpaceSize"}, +        {12, D<&IFileSystem::GetTotalSpaceSize>, "GetTotalSpaceSize"}, +        {13, D<&IFileSystem::CleanDirectoryRecursively>, "CleanDirectoryRecursively"}, +        {14, D<&IFileSystem::GetFileTimeStampRaw>, "GetFileTimeStampRaw"},          {15, nullptr, "QueryEntry"}, -        {16, &IFileSystem::GetFileSystemAttribute, "GetFileSystemAttribute"}, +        {16, D<&IFileSystem::GetFileSystemAttribute>, "GetFileSystemAttribute"},      };      RegisterHandlers(functions);  } -void IFileSystem::CreateFile(HLERequestContext& ctx) { -    IPC::RequestParser rp{ctx}; +Result IFileSystem::CreateFile(const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path, +                               s32 option, s64 size) { +    LOG_DEBUG(Service_FS, "called. file={}, option=0x{:X}, size=0x{:08X}", path->str, option, size); -    const auto file_buffer = ctx.ReadBuffer(); -    const std::string name = Common::StringFromBuffer(file_buffer); -    const auto path = FileSys::Path(name.c_str()); - -    const u64 file_mode = rp.Pop<u64>(); -    const u32 file_size = rp.Pop<u32>(); - -    LOG_DEBUG(Service_FS, "called. file={}, mode=0x{:X}, size=0x{:08X}", name, file_mode, -              file_size); - -    IPC::ResponseBuilder rb{ctx, 2}; -    rb.Push(backend->CreateFile(path, file_size)); +    R_RETURN(backend->CreateFile(FileSys::Path(path->str), size));  } -void IFileSystem::DeleteFile(HLERequestContext& ctx) { -    const auto file_buffer = ctx.ReadBuffer(); -    const std::string name = Common::StringFromBuffer(file_buffer); -    const auto path = FileSys::Path(name.c_str()); +Result IFileSystem::DeleteFile(const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path) { +    LOG_DEBUG(Service_FS, "called. file={}", path->str); -    LOG_DEBUG(Service_FS, "called. file={}", name); - -    IPC::ResponseBuilder rb{ctx, 2}; -    rb.Push(backend->DeleteFile(path)); +    R_RETURN(backend->DeleteFile(FileSys::Path(path->str)));  } -void IFileSystem::CreateDirectory(HLERequestContext& ctx) { -    const auto file_buffer = ctx.ReadBuffer(); -    const std::string name = Common::StringFromBuffer(file_buffer); -    const auto path = FileSys::Path(name.c_str()); - -    LOG_DEBUG(Service_FS, "called. directory={}", name); +Result IFileSystem::CreateDirectory( +    const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path) { +    LOG_DEBUG(Service_FS, "called. directory={}", path->str); -    IPC::ResponseBuilder rb{ctx, 2}; -    rb.Push(backend->CreateDirectory(path)); +    R_RETURN(backend->CreateDirectory(FileSys::Path(path->str)));  } -void IFileSystem::DeleteDirectory(HLERequestContext& ctx) { -    const auto file_buffer = ctx.ReadBuffer(); -    const std::string name = Common::StringFromBuffer(file_buffer); -    const auto path = FileSys::Path(name.c_str()); - -    LOG_DEBUG(Service_FS, "called. directory={}", name); +Result IFileSystem::DeleteDirectory( +    const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path) { +    LOG_DEBUG(Service_FS, "called. directory={}", path->str); -    IPC::ResponseBuilder rb{ctx, 2}; -    rb.Push(backend->DeleteDirectory(path)); +    R_RETURN(backend->DeleteDirectory(FileSys::Path(path->str)));  } -void IFileSystem::DeleteDirectoryRecursively(HLERequestContext& ctx) { -    const auto file_buffer = ctx.ReadBuffer(); -    const std::string name = Common::StringFromBuffer(file_buffer); -    const auto path = FileSys::Path(name.c_str()); +Result IFileSystem::DeleteDirectoryRecursively( +    const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path) { +    LOG_DEBUG(Service_FS, "called. directory={}", path->str); -    LOG_DEBUG(Service_FS, "called. directory={}", name); - -    IPC::ResponseBuilder rb{ctx, 2}; -    rb.Push(backend->DeleteDirectoryRecursively(path)); +    R_RETURN(backend->DeleteDirectoryRecursively(FileSys::Path(path->str)));  } -void IFileSystem::CleanDirectoryRecursively(HLERequestContext& ctx) { -    const auto file_buffer = ctx.ReadBuffer(); -    const std::string name = Common::StringFromBuffer(file_buffer); -    const auto path = FileSys::Path(name.c_str()); - -    LOG_DEBUG(Service_FS, "called. Directory: {}", name); +Result IFileSystem::CleanDirectoryRecursively( +    const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path) { +    LOG_DEBUG(Service_FS, "called. Directory: {}", path->str); -    IPC::ResponseBuilder rb{ctx, 2}; -    rb.Push(backend->CleanDirectoryRecursively(path)); +    R_RETURN(backend->CleanDirectoryRecursively(FileSys::Path(path->str)));  } -void IFileSystem::RenameFile(HLERequestContext& ctx) { -    const std::string src_name = Common::StringFromBuffer(ctx.ReadBuffer(0)); -    const std::string dst_name = Common::StringFromBuffer(ctx.ReadBuffer(1)); - -    const auto src_path = FileSys::Path(src_name.c_str()); -    const auto dst_path = FileSys::Path(dst_name.c_str()); +Result IFileSystem::RenameFile( +    const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> old_path, +    const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> new_path) { +    LOG_DEBUG(Service_FS, "called. file '{}' to file '{}'", old_path->str, new_path->str); -    LOG_DEBUG(Service_FS, "called. file '{}' to file '{}'", src_name, dst_name); - -    IPC::ResponseBuilder rb{ctx, 2}; -    rb.Push(backend->RenameFile(src_path, dst_path)); +    R_RETURN(backend->RenameFile(FileSys::Path(old_path->str), FileSys::Path(new_path->str)));  } -void IFileSystem::OpenFile(HLERequestContext& ctx) { -    IPC::RequestParser rp{ctx}; - -    const auto file_buffer = ctx.ReadBuffer(); -    const std::string name = Common::StringFromBuffer(file_buffer); -    const auto path = FileSys::Path(name.c_str()); - -    const auto mode = static_cast<FileSys::OpenMode>(rp.Pop<u32>()); - -    LOG_DEBUG(Service_FS, "called. file={}, mode={}", name, mode); +Result IFileSystem::OpenFile(OutInterface<IFile> out_interface, +                             const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path, +                             u32 mode) { +    LOG_DEBUG(Service_FS, "called. file={}, mode={}", path->str, mode);      FileSys::VirtualFile vfs_file{}; -    auto result = backend->OpenFile(&vfs_file, path, mode); -    if (result != ResultSuccess) { -        IPC::ResponseBuilder rb{ctx, 2}; -        rb.Push(result); -        return; -    } - -    auto file = std::make_shared<IFile>(system, vfs_file); - -    IPC::ResponseBuilder rb{ctx, 2, 0, 1}; -    rb.Push(ResultSuccess); -    rb.PushIpcInterface<IFile>(std::move(file)); -} - -void IFileSystem::OpenDirectory(HLERequestContext& ctx) { -    IPC::RequestParser rp{ctx}; +    R_TRY(backend->OpenFile(&vfs_file, FileSys::Path(path->str), +                            static_cast<FileSys::OpenMode>(mode))); -    const auto file_buffer = ctx.ReadBuffer(); -    const std::string name = Common::StringFromBuffer(file_buffer); -    const auto path = FileSys::Path(name.c_str()); -    const auto mode = rp.PopRaw<FileSys::OpenDirectoryMode>(); +    *out_interface = std::make_shared<IFile>(system, vfs_file); +    R_SUCCEED(); +} -    LOG_DEBUG(Service_FS, "called. directory={}, mode={}", name, mode); +Result IFileSystem::OpenDirectory(OutInterface<IDirectory> out_interface, +                                  const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path, +                                  u32 mode) { +    LOG_DEBUG(Service_FS, "called. directory={}, mode={}", path->str, mode);      FileSys::VirtualDir vfs_dir{}; -    auto result = backend->OpenDirectory(&vfs_dir, path, mode); -    if (result != ResultSuccess) { -        IPC::ResponseBuilder rb{ctx, 2}; -        rb.Push(result); -        return; -    } - -    auto directory = std::make_shared<IDirectory>(system, vfs_dir, mode); - -    IPC::ResponseBuilder rb{ctx, 2, 0, 1}; -    rb.Push(ResultSuccess); -    rb.PushIpcInterface<IDirectory>(std::move(directory)); -} +    R_TRY(backend->OpenDirectory(&vfs_dir, FileSys::Path(path->str), +                                 static_cast<FileSys::OpenDirectoryMode>(mode))); -void IFileSystem::GetEntryType(HLERequestContext& ctx) { -    const auto file_buffer = ctx.ReadBuffer(); -    const std::string name = Common::StringFromBuffer(file_buffer); -    const auto path = FileSys::Path(name.c_str()); +    *out_interface = std::make_shared<IDirectory>(system, vfs_dir, +                                                  static_cast<FileSys::OpenDirectoryMode>(mode)); +    R_SUCCEED(); +} -    LOG_DEBUG(Service_FS, "called. file={}", name); +Result IFileSystem::GetEntryType( +    Out<u32> out_type, const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path) { +    LOG_DEBUG(Service_FS, "called. file={}", path->str);      FileSys::DirectoryEntryType vfs_entry_type{}; -    auto result = backend->GetEntryType(&vfs_entry_type, path); -    if (result != ResultSuccess) { -        IPC::ResponseBuilder rb{ctx, 2}; -        rb.Push(result); -        return; -    } - -    IPC::ResponseBuilder rb{ctx, 3}; -    rb.Push(ResultSuccess); -    rb.Push<u32>(static_cast<u32>(vfs_entry_type)); +    R_TRY(backend->GetEntryType(&vfs_entry_type, FileSys::Path(path->str))); + +    *out_type = static_cast<u32>(vfs_entry_type); +    R_SUCCEED();  } -void IFileSystem::Commit(HLERequestContext& ctx) { +Result IFileSystem::Commit() {      LOG_WARNING(Service_FS, "(STUBBED) called"); -    IPC::ResponseBuilder rb{ctx, 2}; -    rb.Push(ResultSuccess); +    R_SUCCEED();  } -void IFileSystem::GetFreeSpaceSize(HLERequestContext& ctx) { +Result IFileSystem::GetFreeSpaceSize( +    Out<s64> out_size, const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path) {      LOG_DEBUG(Service_FS, "called"); -    IPC::ResponseBuilder rb{ctx, 4}; -    rb.Push(ResultSuccess); -    rb.Push(size.get_free_size()); +    *out_size = size_getter.get_free_size(); +    R_SUCCEED();  } -void IFileSystem::GetTotalSpaceSize(HLERequestContext& ctx) { +Result IFileSystem::GetTotalSpaceSize( +    Out<s64> out_size, const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path) {      LOG_DEBUG(Service_FS, "called"); -    IPC::ResponseBuilder rb{ctx, 4}; -    rb.Push(ResultSuccess); -    rb.Push(size.get_total_size()); +    *out_size = size_getter.get_total_size(); +    R_SUCCEED();  } -void IFileSystem::GetFileTimeStampRaw(HLERequestContext& ctx) { -    const auto file_buffer = ctx.ReadBuffer(); -    const std::string name = Common::StringFromBuffer(file_buffer); -    const auto path = FileSys::Path(name.c_str()); - -    LOG_WARNING(Service_FS, "(Partial Implementation) called. file={}", name); +Result IFileSystem::GetFileTimeStampRaw( +    Out<FileSys::FileTimeStampRaw> out_timestamp, +    const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path) { +    LOG_WARNING(Service_FS, "(Partial Implementation) called. file={}", path->str);      FileSys::FileTimeStampRaw vfs_timestamp{}; -    auto result = backend->GetFileTimeStampRaw(&vfs_timestamp, path); -    if (result != ResultSuccess) { -        IPC::ResponseBuilder rb{ctx, 2}; -        rb.Push(result); -        return; -    } - -    IPC::ResponseBuilder rb{ctx, 10}; -    rb.Push(ResultSuccess); -    rb.PushRaw(vfs_timestamp); +    R_TRY(backend->GetFileTimeStampRaw(&vfs_timestamp, FileSys::Path(path->str))); + +    *out_timestamp = vfs_timestamp; +    R_SUCCEED();  } -void IFileSystem::GetFileSystemAttribute(HLERequestContext& ctx) { +Result IFileSystem::GetFileSystemAttribute(Out<FileSystemAttribute> out_attribute) {      LOG_WARNING(Service_FS, "(STUBBED) called"); -    struct FileSystemAttribute { -        u8 dir_entry_name_length_max_defined; -        u8 file_entry_name_length_max_defined; -        u8 dir_path_name_length_max_defined; -        u8 file_path_name_length_max_defined; -        INSERT_PADDING_BYTES_NOINIT(0x5); -        u8 utf16_dir_entry_name_length_max_defined; -        u8 utf16_file_entry_name_length_max_defined; -        u8 utf16_dir_path_name_length_max_defined; -        u8 utf16_file_path_name_length_max_defined; -        INSERT_PADDING_BYTES_NOINIT(0x18); -        s32 dir_entry_name_length_max; -        s32 file_entry_name_length_max; -        s32 dir_path_name_length_max; -        s32 file_path_name_length_max; -        INSERT_PADDING_WORDS_NOINIT(0x5); -        s32 utf16_dir_entry_name_length_max; -        s32 utf16_file_entry_name_length_max; -        s32 utf16_dir_path_name_length_max; -        s32 utf16_file_path_name_length_max; -        INSERT_PADDING_WORDS_NOINIT(0x18); -        INSERT_PADDING_WORDS_NOINIT(0x1); -    }; -    static_assert(sizeof(FileSystemAttribute) == 0xc0, "FileSystemAttribute has incorrect size"); -      FileSystemAttribute savedata_attribute{};      savedata_attribute.dir_entry_name_length_max_defined = true;      savedata_attribute.file_entry_name_length_max_defined = true;      savedata_attribute.dir_entry_name_length_max = 0x40;      savedata_attribute.file_entry_name_length_max = 0x40; -    IPC::ResponseBuilder rb{ctx, 50}; -    rb.Push(ResultSuccess); -    rb.PushRaw(savedata_attribute); +    *out_attribute = savedata_attribute; +    R_SUCCEED();  }  } // namespace Service::FileSystem diff --git a/src/core/hle/service/filesystem/fsp/fs_i_filesystem.h b/src/core/hle/service/filesystem/fsp/fs_i_filesystem.h index d500be725..d07b74938 100644 --- a/src/core/hle/service/filesystem/fsp/fs_i_filesystem.h +++ b/src/core/hle/service/filesystem/fsp/fs_i_filesystem.h @@ -5,35 +5,79 @@  #include "core/file_sys/fsa/fs_i_filesystem.h"  #include "core/file_sys/vfs/vfs.h" +#include "core/hle/service/cmif_types.h"  #include "core/hle/service/filesystem/filesystem.h"  #include "core/hle/service/filesystem/fsp/fsp_util.h"  #include "core/hle/service/service.h" +namespace FileSys::Sf { +struct Path; +} +  namespace Service::FileSystem { +class IFile; +class IDirectory; +  class IFileSystem final : public ServiceFramework<IFileSystem> {  public: -    explicit IFileSystem(Core::System& system_, FileSys::VirtualDir dir_, SizeGetter size_); - -    void CreateFile(HLERequestContext& ctx); -    void DeleteFile(HLERequestContext& ctx); -    void CreateDirectory(HLERequestContext& ctx); -    void DeleteDirectory(HLERequestContext& ctx); -    void DeleteDirectoryRecursively(HLERequestContext& ctx); -    void CleanDirectoryRecursively(HLERequestContext& ctx); -    void RenameFile(HLERequestContext& ctx); -    void OpenFile(HLERequestContext& ctx); -    void OpenDirectory(HLERequestContext& ctx); -    void GetEntryType(HLERequestContext& ctx); -    void Commit(HLERequestContext& ctx); -    void GetFreeSpaceSize(HLERequestContext& ctx); -    void GetTotalSpaceSize(HLERequestContext& ctx); -    void GetFileTimeStampRaw(HLERequestContext& ctx); -    void GetFileSystemAttribute(HLERequestContext& ctx); +    explicit IFileSystem(Core::System& system_, FileSys::VirtualDir dir_, SizeGetter size_getter_); + +    struct FileSystemAttribute { +        u8 dir_entry_name_length_max_defined; +        u8 file_entry_name_length_max_defined; +        u8 dir_path_name_length_max_defined; +        u8 file_path_name_length_max_defined; +        INSERT_PADDING_BYTES_NOINIT(0x5); +        u8 utf16_dir_entry_name_length_max_defined; +        u8 utf16_file_entry_name_length_max_defined; +        u8 utf16_dir_path_name_length_max_defined; +        u8 utf16_file_path_name_length_max_defined; +        INSERT_PADDING_BYTES_NOINIT(0x18); +        s32 dir_entry_name_length_max; +        s32 file_entry_name_length_max; +        s32 dir_path_name_length_max; +        s32 file_path_name_length_max; +        INSERT_PADDING_WORDS_NOINIT(0x5); +        s32 utf16_dir_entry_name_length_max; +        s32 utf16_file_entry_name_length_max; +        s32 utf16_dir_path_name_length_max; +        s32 utf16_file_path_name_length_max; +        INSERT_PADDING_WORDS_NOINIT(0x18); +        INSERT_PADDING_WORDS_NOINIT(0x1); +    }; +    static_assert(sizeof(FileSystemAttribute) == 0xC0, "FileSystemAttribute has incorrect size"); + +    Result CreateFile(const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path, +                      s32 option, s64 size); +    Result DeleteFile(const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path); +    Result CreateDirectory(const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path); +    Result DeleteDirectory(const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path); +    Result DeleteDirectoryRecursively( +        const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path); +    Result CleanDirectoryRecursively( +        const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path); +    Result RenameFile(const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> old_path, +                      const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> new_path); +    Result OpenFile(OutInterface<IFile> out_interface, +                    const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path, u32 mode); +    Result OpenDirectory(OutInterface<IDirectory> out_interface, +                         const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path, +                         u32 mode); +    Result GetEntryType(Out<u32> out_type, +                        const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path); +    Result Commit(); +    Result GetFreeSpaceSize(Out<s64> out_size, +                            const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path); +    Result GetTotalSpaceSize(Out<s64> out_size, +                             const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path); +    Result GetFileTimeStampRaw(Out<FileSys::FileTimeStampRaw> out_timestamp, +                               const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path); +    Result GetFileSystemAttribute(Out<FileSystemAttribute> out_attribute);  private:      std::unique_ptr<FileSys::Fsa::IFileSystem> backend; -    SizeGetter size; +    SizeGetter size_getter;  };  } // namespace Service::FileSystem  | 
