diff options
| author | bunnei <bunneidev@gmail.com> | 2018-07-07 19:30:58 -0700 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-07-07 19:30:58 -0700 | 
| commit | f89b47fdf7c2060223b6648af3617a9b85fe6804 (patch) | |
| tree | b660920a49f538f0ee00486c50a0d153d53c423d /src/core/hle | |
| parent | 3417f46dd5a40a67204d5491d143bd6792e1e9fb (diff) | |
| parent | 913896cbd99e414c325c9d47a987376ed6d9fffd (diff) | |
Merge pull request #639 from bunnei/revert-vfs
Revert "Virtual Filesystem (#597)"
Diffstat (limited to 'src/core/hle')
| -rw-r--r-- | src/core/hle/service/am/am.cpp | 2 | ||||
| -rw-r--r-- | src/core/hle/service/filesystem/filesystem.cpp | 225 | ||||
| -rw-r--r-- | src/core/hle/service/filesystem/filesystem.h | 133 | ||||
| -rw-r--r-- | src/core/hle/service/filesystem/fsp_srv.cpp | 114 | ||||
| -rw-r--r-- | src/core/hle/service/filesystem/fsp_srv.h | 2 | 
5 files changed, 71 insertions, 405 deletions
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index 7bb13c735..a871b3eaa 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp @@ -621,7 +621,7 @@ void IApplicationFunctions::EnsureSaveData(Kernel::HLERequestContext& ctx) {      IPC::ResponseBuilder rb{ctx, 4};      FileSys::Path unused; -    auto savedata = FileSystem::OpenFileSystem(FileSystem::Type::SaveData); +    auto savedata = FileSystem::OpenFileSystem(FileSystem::Type::SaveData, unused);      if (savedata.Failed()) {          // Create the save data and return an error indicating that the operation was performed.          FileSystem::FormatFileSystem(FileSystem::Type::SaveData); diff --git a/src/core/hle/service/filesystem/filesystem.cpp b/src/core/hle/service/filesystem/filesystem.cpp index 25810c165..f58b518b6 100644 --- a/src/core/hle/service/filesystem/filesystem.cpp +++ b/src/core/hle/service/filesystem/filesystem.cpp @@ -2,221 +2,36 @@  // Licensed under GPLv2 or any later version  // Refer to the license.txt file included. -#include "boost/container/flat_map.hpp" -#include "common/assert.h" -#include "common/common_paths.h" +#include <boost/container/flat_map.hpp>  #include "common/file_util.h" -#include "core/core.h" -#include "core/file_sys/errors.h"  #include "core/file_sys/filesystem.h" -#include "core/file_sys/vfs.h" -#include "core/file_sys/vfs_offset.h" -#include "core/file_sys/vfs_real.h" -#include "core/hle/kernel/process.h" +#include "core/file_sys/savedata_factory.h" +#include "core/file_sys/sdmc_factory.h"  #include "core/hle/service/filesystem/filesystem.h"  #include "core/hle/service/filesystem/fsp_srv.h"  namespace Service::FileSystem { -// Size of emulated sd card free space, reported in bytes. -// Just using 32GB because thats reasonable -// TODO(DarkLordZach): Eventually make this configurable in settings. -constexpr u64 EMULATED_SD_REPORTED_SIZE = 32000000000; - -static FileSys::VirtualDir GetDirectoryRelativeWrapped(FileSys::VirtualDir base, -                                                       const std::string& dir_name) { -    if (dir_name == "." || dir_name == "" || dir_name == "/" || dir_name == "\\") -        return base; - -    return base->GetDirectoryRelative(dir_name); -} - -VfsDirectoryServiceWrapper::VfsDirectoryServiceWrapper(FileSys::VirtualDir backing_) -    : backing(backing_) {} - -std::string VfsDirectoryServiceWrapper::GetName() const { -    return backing->GetName(); -} - -ResultCode VfsDirectoryServiceWrapper::CreateFile(const std::string& path, u64 size) const { -    auto dir = GetDirectoryRelativeWrapped(backing, FileUtil::GetParentPath(path)); -    auto file = dir->CreateFile(FileUtil::GetFilename(path)); -    if (file == nullptr) -        return ResultCode(-1); -    if (!file->Resize(size)) -        return ResultCode(-1); -    return RESULT_SUCCESS; -} - -ResultCode VfsDirectoryServiceWrapper::DeleteFile(const std::string& path) const { -    auto dir = GetDirectoryRelativeWrapped(backing, FileUtil::GetParentPath(path)); -    if (!backing->DeleteFile(FileUtil::GetFilename(path))) -        return ResultCode(-1); -    return RESULT_SUCCESS; -} - -ResultCode VfsDirectoryServiceWrapper::CreateDirectory(const std::string& path) const { -    auto dir = GetDirectoryRelativeWrapped(backing, FileUtil::GetParentPath(path)); -    if (dir == nullptr && FileUtil::GetFilename(FileUtil::GetParentPath(path)).empty()) -        dir = backing; -    auto new_dir = dir->CreateSubdirectory(FileUtil::GetFilename(path)); -    if (new_dir == nullptr) -        return ResultCode(-1); -    return RESULT_SUCCESS; -} - -ResultCode VfsDirectoryServiceWrapper::DeleteDirectory(const std::string& path) const { -    auto dir = GetDirectoryRelativeWrapped(backing, FileUtil::GetParentPath(path)); -    if (!dir->DeleteSubdirectory(FileUtil::GetFilename(path))) -        return ResultCode(-1); -    return RESULT_SUCCESS; -} - -ResultCode VfsDirectoryServiceWrapper::DeleteDirectoryRecursively(const std::string& path) const { -    auto dir = GetDirectoryRelativeWrapped(backing, FileUtil::GetParentPath(path)); -    if (!dir->DeleteSubdirectoryRecursive(FileUtil::GetFilename(path))) -        return ResultCode(-1); -    return RESULT_SUCCESS; -} - -ResultCode VfsDirectoryServiceWrapper::RenameFile(const std::string& src_path, -                                                  const std::string& dest_path) const { -    auto src = backing->GetFileRelative(src_path); -    if (FileUtil::GetParentPath(src_path) == FileUtil::GetParentPath(dest_path)) { -        // Use more-optimized vfs implementation rename. -        if (src == nullptr) -            return FileSys::ERROR_PATH_NOT_FOUND; -        if (!src->Rename(FileUtil::GetFilename(dest_path))) -            return ResultCode(-1); -        return RESULT_SUCCESS; -    } - -    // Move by hand -- TODO(DarkLordZach): Optimize -    auto c_res = CreateFile(dest_path, src->GetSize()); -    if (c_res != RESULT_SUCCESS) -        return c_res; - -    auto dest = backing->GetFileRelative(dest_path); -    ASSERT_MSG(dest != nullptr, "Newly created file with success cannot be found."); - -    ASSERT_MSG(dest->WriteBytes(src->ReadAllBytes()) == src->GetSize(), -               "Could not write all of the bytes but everything else has succeded."); - -    if (!src->GetContainingDirectory()->DeleteFile(FileUtil::GetFilename(src_path))) -        return ResultCode(-1); - -    return RESULT_SUCCESS; -} - -ResultCode VfsDirectoryServiceWrapper::RenameDirectory(const std::string& src_path, -                                                       const std::string& dest_path) const { -    auto src = GetDirectoryRelativeWrapped(backing, src_path); -    if (FileUtil::GetParentPath(src_path) == FileUtil::GetParentPath(dest_path)) { -        // Use more-optimized vfs implementation rename. -        if (src == nullptr) -            return FileSys::ERROR_PATH_NOT_FOUND; -        if (!src->Rename(FileUtil::GetFilename(dest_path))) -            return ResultCode(-1); -        return RESULT_SUCCESS; -    } - -    // TODO(DarkLordZach): Implement renaming across the tree (move). -    ASSERT_MSG(false, -               "Could not rename directory with path \"{}\" to new path \"{}\" because parent dirs " -               "don't match -- UNIMPLEMENTED", -               src_path, dest_path); - -    return ResultCode(-1); -} - -ResultVal<FileSys::VirtualFile> VfsDirectoryServiceWrapper::OpenFile(const std::string& path, -                                                                     FileSys::Mode mode) const { -    auto file = backing->GetFileRelative(path); -    if (file == nullptr) -        return FileSys::ERROR_PATH_NOT_FOUND; - -    if ((static_cast<u32>(mode) & static_cast<u32>(FileSys::Mode::Append)) != 0) { -        return MakeResult<FileSys::VirtualFile>( -            std::make_shared<FileSys::OffsetVfsFile>(file, 0, file->GetSize())); -    } - -    return MakeResult<FileSys::VirtualFile>(file); -} - -ResultVal<FileSys::VirtualDir> VfsDirectoryServiceWrapper::OpenDirectory(const std::string& path) { -    auto dir = GetDirectoryRelativeWrapped(backing, path); -    if (dir == nullptr) -        return ResultCode(-1); -    return MakeResult(dir); -} - -u64 VfsDirectoryServiceWrapper::GetFreeSpaceSize() const { -    if (backing->IsWritable()) -        return EMULATED_SD_REPORTED_SIZE; - -    return 0; -} - -ResultVal<FileSys::EntryType> VfsDirectoryServiceWrapper::GetEntryType( -    const std::string& path) const { -    auto dir = GetDirectoryRelativeWrapped(backing, FileUtil::GetParentPath(path)); -    if (dir == nullptr) -        return ResultCode(-1); -    auto filename = FileUtil::GetFilename(path); -    if (dir->GetFile(filename) != nullptr) -        return MakeResult(FileSys::EntryType::File); -    if (dir->GetSubdirectory(filename) != nullptr) -        return MakeResult(FileSys::EntryType::Directory); -    return ResultCode(-1); -} - -// A deferred filesystem for nand save data. -// This must be deferred because the directory is dependent on title id, which is not set at -// registration time. -struct SaveDataDeferredFilesystem : DeferredFilesystem { -protected: -    FileSys::VirtualDir CreateFilesystem() override { -        u64 title_id = Core::CurrentProcess()->program_id; -        // TODO(DarkLordZach): Users -        u32 user_id = 0; -        std::string nand_directory = fmt::format( -            "{}save/{:016X}/{:08X}/", FileUtil::GetUserPath(D_NAND_IDX), title_id, user_id); - -        auto savedata = -            std::make_shared<FileSys::RealVfsDirectory>(nand_directory, FileSys::Mode::Write); -        return savedata; -    } -}; -  /**   * Map of registered file systems, identified by type. Once an file system is registered here, it   * is never removed until UnregisterFileSystems is called.   */ -static boost::container::flat_map<Type, std::unique_ptr<DeferredFilesystem>> filesystem_map; -static FileSys::VirtualFile filesystem_romfs = nullptr; +static boost::container::flat_map<Type, std::unique_ptr<FileSys::FileSystemFactory>> filesystem_map; -ResultCode RegisterFileSystem(std::unique_ptr<DeferredFilesystem>&& factory, Type type) { +ResultCode RegisterFileSystem(std::unique_ptr<FileSys::FileSystemFactory>&& factory, Type type) {      auto result = filesystem_map.emplace(type, std::move(factory));      bool inserted = result.second;      ASSERT_MSG(inserted, "Tried to register more than one system with same id code");      auto& filesystem = result.first->second; -    LOG_DEBUG(Service_FS, "Registered file system with id code 0x{:08X}", static_cast<u32>(type)); -    return RESULT_SUCCESS; -} - -ResultCode RegisterRomFS(FileSys::VirtualFile filesystem) { -    ASSERT_MSG(filesystem_romfs == nullptr, -               "Tried to register more than one system with same id code"); - -    filesystem_romfs = filesystem;      LOG_DEBUG(Service_FS, "Registered file system {} with id code 0x{:08X}", filesystem->GetName(), -              static_cast<u32>(Type::RomFS)); +              static_cast<u32>(type));      return RESULT_SUCCESS;  } -ResultVal<FileSys::VirtualDir> OpenFileSystem(Type type) { +ResultVal<std::unique_ptr<FileSys::FileSystemBackend>> OpenFileSystem(Type type, +                                                                      FileSys::Path& path) {      LOG_TRACE(Service_FS, "Opening FileSystem with type={}", static_cast<u32>(type));      auto itr = filesystem_map.find(type); @@ -225,13 +40,7 @@ ResultVal<FileSys::VirtualDir> OpenFileSystem(Type type) {          return ResultCode(-1);      } -    return MakeResult(itr->second->Get()); -} - -ResultVal<FileSys::VirtualFile> OpenRomFS() { -    if (filesystem_romfs == nullptr) -        return ResultCode(-1); -    return MakeResult(filesystem_romfs); +    return itr->second->Open(path);  }  ResultCode FormatFileSystem(Type type) { @@ -243,21 +52,21 @@ ResultCode FormatFileSystem(Type type) {          return ResultCode(-1);      } -    return itr->second->Get()->GetParentDirectory()->DeleteSubdirectory( -               itr->second->Get()->GetName()) -               ? RESULT_SUCCESS -               : ResultCode(-1); +    FileSys::Path unused; +    return itr->second->Format(unused);  }  void RegisterFileSystems() {      filesystem_map.clear(); -    filesystem_romfs = nullptr; +    std::string nand_directory = FileUtil::GetUserPath(D_NAND_IDX);      std::string sd_directory = FileUtil::GetUserPath(D_SDMC_IDX); -    auto sdcard = std::make_shared<FileSys::RealVfsDirectory>(sd_directory, FileSys::Mode::Write); -    RegisterFileSystem(std::make_unique<DeferredFilesystem>(sdcard), Type::SDMC); -    RegisterFileSystem(std::make_unique<SaveDataDeferredFilesystem>(), Type::SaveData); +    auto savedata = std::make_unique<FileSys::SaveData_Factory>(std::move(nand_directory)); +    RegisterFileSystem(std::move(savedata), Type::SaveData); + +    auto sdcard = std::make_unique<FileSys::SDMC_Factory>(std::move(sd_directory)); +    RegisterFileSystem(std::move(sdcard), Type::SDMC);  }  void InstallInterfaces(SM::ServiceManager& service_manager) { diff --git a/src/core/hle/service/filesystem/filesystem.h b/src/core/hle/service/filesystem/filesystem.h index d3de797f1..56d26146e 100644 --- a/src/core/hle/service/filesystem/filesystem.h +++ b/src/core/hle/service/filesystem/filesystem.h @@ -6,8 +6,6 @@  #include <memory>  #include "common/common_types.h" -#include "core/file_sys/filesystem.h" -#include "core/file_sys/vfs.h"  #include "core/hle/result.h"  namespace FileSys { @@ -31,136 +29,12 @@ enum class Type {      SDMC = 3,  }; -// A class that wraps a VfsDirectory with methods that return ResultVal and ResultCode instead of -// pointers and booleans. This makes using a VfsDirectory with switch services much easier and -// avoids repetitive code. -class VfsDirectoryServiceWrapper { -public: -    explicit VfsDirectoryServiceWrapper(FileSys::VirtualDir backing); - -    /** -     * Get a descriptive name for the archive (e.g. "RomFS", "SaveData", etc.) -     */ -    std::string GetName() const; - -    /** -     * Create a file specified by its path -     * @param path Path relative to the Archive -     * @param size The size of the new file, filled with zeroes -     * @return Result of the operation -     */ -    ResultCode CreateFile(const std::string& path, u64 size) const; - -    /** -     * Delete a file specified by its path -     * @param path Path relative to the archive -     * @return Result of the operation -     */ -    ResultCode DeleteFile(const std::string& path) const; - -    /** -     * Create a directory specified by its path -     * @param path Path relative to the archive -     * @return Result of the operation -     */ -    ResultCode CreateDirectory(const std::string& path) const; - -    /** -     * Delete a directory specified by its path -     * @param path Path relative to the archive -     * @return Result of the operation -     */ -    ResultCode DeleteDirectory(const std::string& path) const; - -    /** -     * Delete a directory specified by its path and anything under it -     * @param path Path relative to the archive -     * @return Result of the operation -     */ -    ResultCode DeleteDirectoryRecursively(const std::string& path) const; - -    /** -     * Rename a File specified by its path -     * @param src_path Source path relative to the archive -     * @param dest_path Destination path relative to the archive -     * @return Result of the operation -     */ -    ResultCode RenameFile(const std::string& src_path, const std::string& dest_path) const; - -    /** -     * Rename a Directory specified by its path -     * @param src_path Source path relative to the archive -     * @param dest_path Destination path relative to the archive -     * @return Result of the operation -     */ -    ResultCode RenameDirectory(const std::string& src_path, const std::string& dest_path) const; - -    /** -     * Open a file specified by its path, using the specified mode -     * @param path Path relative to the archive -     * @param mode Mode to open the file with -     * @return Opened file, or error code -     */ -    ResultVal<FileSys::VirtualFile> OpenFile(const std::string& path, FileSys::Mode mode) const; - -    /** -     * Open a directory specified by its path -     * @param path Path relative to the archive -     * @return Opened directory, or error code -     */ -    ResultVal<FileSys::VirtualDir> OpenDirectory(const std::string& path); - -    /** -     * Get the free space -     * @return The number of free bytes in the archive -     */ -    u64 GetFreeSpaceSize() const; - -    /** -     * Get the type of the specified path -     * @return The type of the specified path or error code -     */ -    ResultVal<FileSys::EntryType> GetEntryType(const std::string& path) const; - -private: -    FileSys::VirtualDir backing; -}; - -// A class that deferres the creation of a filesystem until a later time. -// This is useful if construction depends on a variable not known when the filesystem is registered. -// Construct this with a filesystem (VirtualDir) to avoid the deferrence feature or override the -//     CreateFilesystem method which will be called on first use. -struct DeferredFilesystem { -    DeferredFilesystem() = default; - -    explicit DeferredFilesystem(FileSys::VirtualDir vfs_directory) : fs(std::move(vfs_directory)) {} - -    FileSys::VirtualDir Get() { -        if (fs == nullptr) -            fs = CreateFilesystem(); - -        return fs; -    } - -    virtual ~DeferredFilesystem() = default; - -protected: -    virtual FileSys::VirtualDir CreateFilesystem() { -        return fs; -    } - -private: -    FileSys::VirtualDir fs; -}; -  /**   * Registers a FileSystem, instances of which can later be opened using its IdCode.   * @param factory FileSystem backend interface to use   * @param type Type used to access this type of FileSystem   */ -ResultCode RegisterFileSystem(std::unique_ptr<DeferredFilesystem>&& fs, Type type); - -ResultCode RegisterRomFS(FileSys::VirtualFile fs); +ResultCode RegisterFileSystem(std::unique_ptr<FileSys::FileSystemFactory>&& factory, Type type);  /**   * Opens a file system @@ -168,9 +42,8 @@ ResultCode RegisterRomFS(FileSys::VirtualFile fs);   * @param path Path to the file system, used with Binary paths   * @return FileSys::FileSystemBackend interface to the file system   */ -ResultVal<FileSys::VirtualDir> OpenFileSystem(Type type); - -ResultVal<FileSys::VirtualFile> OpenRomFS(); +ResultVal<std::unique_ptr<FileSys::FileSystemBackend>> OpenFileSystem(Type type, +                                                                      FileSys::Path& path);  /**   * Formats a file system diff --git a/src/core/hle/service/filesystem/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp_srv.cpp index 26e8a8c88..216bfea0a 100644 --- a/src/core/hle/service/filesystem/fsp_srv.cpp +++ b/src/core/hle/service/filesystem/fsp_srv.cpp @@ -19,8 +19,8 @@ namespace Service::FileSystem {  class IStorage final : public ServiceFramework<IStorage> {  public: -    IStorage(FileSys::VirtualFile backend_) -        : ServiceFramework("IStorage"), backend(std::move(backend_)) { +    IStorage(std::unique_ptr<FileSys::StorageBackend>&& backend) +        : ServiceFramework("IStorage"), backend(std::move(backend)) {          static const FunctionInfo functions[] = {              {0, &IStorage::Read, "Read"}, {1, nullptr, "Write"},   {2, nullptr, "Flush"},              {3, nullptr, "SetSize"},      {4, nullptr, "GetSize"}, {5, nullptr, "OperateRange"}, @@ -29,7 +29,7 @@ public:      }  private: -    FileSys::VirtualFile backend; +    std::unique_ptr<FileSys::StorageBackend> backend;      void Read(Kernel::HLERequestContext& ctx) {          IPC::RequestParser rp{ctx}; @@ -51,8 +51,8 @@ private:          }          // Read the data from the Storage backend -        std::vector<u8> output = backend->ReadBytes(length, offset); -        auto res = MakeResult<size_t>(output.size()); +        std::vector<u8> output(length); +        ResultVal<size_t> res = backend->Read(offset, length, output.data());          if (res.Failed()) {              IPC::ResponseBuilder rb{ctx, 2};              rb.Push(res.Code()); @@ -69,8 +69,8 @@ private:  class IFile final : public ServiceFramework<IFile> {  public: -    explicit IFile(FileSys::VirtualFile backend_) -        : ServiceFramework("IFile"), backend(std::move(backend_)) { +    explicit IFile(std::unique_ptr<FileSys::StorageBackend>&& backend) +        : ServiceFramework("IFile"), backend(std::move(backend)) {          static const FunctionInfo functions[] = {              {0, &IFile::Read, "Read"},       {1, &IFile::Write, "Write"},              {2, &IFile::Flush, "Flush"},     {3, &IFile::SetSize, "SetSize"}, @@ -80,7 +80,7 @@ public:      }  private: -    FileSys::VirtualFile backend; +    std::unique_ptr<FileSys::StorageBackend> backend;      void Read(Kernel::HLERequestContext& ctx) {          IPC::RequestParser rp{ctx}; @@ -103,8 +103,8 @@ private:          }          // Read the data from the Storage backend -        std::vector<u8> output = backend->ReadBytes(length, offset); -        auto res = MakeResult<size_t>(output.size()); +        std::vector<u8> output(length); +        ResultVal<size_t> res = backend->Read(offset, length, output.data());          if (res.Failed()) {              IPC::ResponseBuilder rb{ctx, 2};              rb.Push(res.Code()); @@ -139,10 +139,9 @@ private:              return;          } -        std::vector<u8> data = ctx.ReadBuffer(); -        data.resize(length);          // Write the data to the Storage backend -        auto res = MakeResult<size_t>(backend->WriteBytes(data, offset)); +        std::vector<u8> data = ctx.ReadBuffer(); +        ResultVal<size_t> res = backend->Write(offset, length, true, data.data());          if (res.Failed()) {              IPC::ResponseBuilder rb{ctx, 2};              rb.Push(res.Code()); @@ -155,8 +154,7 @@ private:      void Flush(Kernel::HLERequestContext& ctx) {          LOG_DEBUG(Service_FS, "called"); - -        // Exists for SDK compatibiltity -- No need to flush file. +        backend->Flush();          IPC::ResponseBuilder rb{ctx, 2};          rb.Push(RESULT_SUCCESS); @@ -165,7 +163,7 @@ private:      void SetSize(Kernel::HLERequestContext& ctx) {          IPC::RequestParser rp{ctx};          const u64 size = rp.Pop<u64>(); -        backend->Resize(size); +        backend->SetSize(size);          LOG_DEBUG(Service_FS, "called, size={}", size);          IPC::ResponseBuilder rb{ctx, 2}; @@ -182,38 +180,19 @@ private:      }  }; -template <typename T> -static void BuildEntryIndex(std::vector<FileSys::Entry>& entries, const std::vector<T>& new_data, -                            FileSys::EntryType type) { -    for (const auto& new_entry : new_data) { -        FileSys::Entry entry; -        entry.filename[0] = '\0'; -        std::strncat(entry.filename, new_entry->GetName().c_str(), FileSys::FILENAME_LENGTH - 1); -        entry.type = type; -        entry.file_size = new_entry->GetSize(); -        entries.emplace_back(std::move(entry)); -    } -} -  class IDirectory final : public ServiceFramework<IDirectory> {  public: -    explicit IDirectory(FileSys::VirtualDir backend_) -        : ServiceFramework("IDirectory"), backend(std::move(backend_)) { +    explicit IDirectory(std::unique_ptr<FileSys::DirectoryBackend>&& backend) +        : ServiceFramework("IDirectory"), backend(std::move(backend)) {          static const FunctionInfo functions[] = {              {0, &IDirectory::Read, "Read"},              {1, &IDirectory::GetEntryCount, "GetEntryCount"},          };          RegisterHandlers(functions); - -        // Build entry index now to save time later. -        BuildEntryIndex(entries, backend->GetFiles(), FileSys::File); -        BuildEntryIndex(entries, backend->GetSubdirectories(), FileSys::Directory);      }  private: -    FileSys::VirtualDir backend; -    std::vector<FileSys::Entry> entries; -    u64 next_entry_index = 0; +    std::unique_ptr<FileSys::DirectoryBackend> backend;      void Read(Kernel::HLERequestContext& ctx) {          IPC::RequestParser rp{ctx}; @@ -224,31 +203,26 @@ private:          // Calculate how many entries we can fit in the output buffer          u64 count_entries = ctx.GetWriteBufferSize() / sizeof(FileSys::Entry); -        // Cap at total number of entries. -        u64 actual_entries = std::min(count_entries, entries.size() - next_entry_index); -          // Read the data from the Directory backend -        std::vector<FileSys::Entry> entry_data(entries.begin() + next_entry_index, -                                               entries.begin() + next_entry_index + actual_entries); - -        next_entry_index += actual_entries; +        std::vector<FileSys::Entry> entries(count_entries); +        u64 read_entries = backend->Read(count_entries, entries.data());          // Convert the data into a byte array -        std::vector<u8> output(entry_data.size() * sizeof(FileSys::Entry)); -        std::memcpy(output.data(), entry_data.data(), output.size()); +        std::vector<u8> output(entries.size() * sizeof(FileSys::Entry)); +        std::memcpy(output.data(), entries.data(), output.size());          // Write the data to memory          ctx.WriteBuffer(output);          IPC::ResponseBuilder rb{ctx, 4};          rb.Push(RESULT_SUCCESS); -        rb.Push(actual_entries); +        rb.Push(read_entries);      }      void GetEntryCount(Kernel::HLERequestContext& ctx) {          LOG_DEBUG(Service_FS, "called"); -        u64 count = entries.size() - next_entry_index; +        u64 count = backend->GetEntryCount();          IPC::ResponseBuilder rb{ctx, 4};          rb.Push(RESULT_SUCCESS); @@ -258,7 +232,7 @@ private:  class IFileSystem final : public ServiceFramework<IFileSystem> {  public: -    explicit IFileSystem(FileSys::VirtualDir backend) +    explicit IFileSystem(std::unique_ptr<FileSys::FileSystemBackend>&& backend)          : ServiceFramework("IFileSystem"), backend(std::move(backend)) {          static const FunctionInfo functions[] = {              {0, &IFileSystem::CreateFile, "CreateFile"}, @@ -293,7 +267,7 @@ public:          LOG_DEBUG(Service_FS, "called file {} mode 0x{:X} size 0x{:08X}", name, mode, size);          IPC::ResponseBuilder rb{ctx, 2}; -        rb.Push(backend.CreateFile(name, size)); +        rb.Push(backend->CreateFile(name, size));      }      void DeleteFile(Kernel::HLERequestContext& ctx) { @@ -305,7 +279,7 @@ public:          LOG_DEBUG(Service_FS, "called file {}", name);          IPC::ResponseBuilder rb{ctx, 2}; -        rb.Push(backend.DeleteFile(name)); +        rb.Push(backend->DeleteFile(name));      }      void CreateDirectory(Kernel::HLERequestContext& ctx) { @@ -317,7 +291,7 @@ public:          LOG_DEBUG(Service_FS, "called directory {}", name);          IPC::ResponseBuilder rb{ctx, 2}; -        rb.Push(backend.CreateDirectory(name)); +        rb.Push(backend->CreateDirectory(name));      }      void RenameFile(Kernel::HLERequestContext& ctx) { @@ -335,7 +309,7 @@ public:          LOG_DEBUG(Service_FS, "called file '{}' to file '{}'", src_name, dst_name);          IPC::ResponseBuilder rb{ctx, 2}; -        rb.Push(backend.RenameFile(src_name, dst_name)); +        rb.Push(backend->RenameFile(src_name, dst_name));      }      void OpenFile(Kernel::HLERequestContext& ctx) { @@ -348,14 +322,14 @@ public:          LOG_DEBUG(Service_FS, "called file {} mode {}", name, static_cast<u32>(mode)); -        auto result = backend.OpenFile(name, mode); +        auto result = backend->OpenFile(name, mode);          if (result.Failed()) {              IPC::ResponseBuilder rb{ctx, 2};              rb.Push(result.Code());              return;          } -        IFile file(result.Unwrap()); +        auto file = std::move(result.Unwrap());          IPC::ResponseBuilder rb{ctx, 2, 0, 1};          rb.Push(RESULT_SUCCESS); @@ -373,14 +347,14 @@ public:          LOG_DEBUG(Service_FS, "called directory {} filter {}", name, filter_flags); -        auto result = backend.OpenDirectory(name); +        auto result = backend->OpenDirectory(name);          if (result.Failed()) {              IPC::ResponseBuilder rb{ctx, 2};              rb.Push(result.Code());              return;          } -        IDirectory directory(result.Unwrap()); +        auto directory = std::move(result.Unwrap());          IPC::ResponseBuilder rb{ctx, 2, 0, 1};          rb.Push(RESULT_SUCCESS); @@ -395,7 +369,7 @@ public:          LOG_DEBUG(Service_FS, "called file {}", name); -        auto result = backend.GetEntryType(name); +        auto result = backend->GetEntryType(name);          if (result.Failed()) {              IPC::ResponseBuilder rb{ctx, 2};              rb.Push(result.Code()); @@ -415,7 +389,7 @@ public:      }  private: -    VfsDirectoryServiceWrapper backend; +    std::unique_ptr<FileSys::FileSystemBackend> backend;  };  FSP_SRV::FSP_SRV() : ServiceFramework("fsp-srv") { @@ -516,7 +490,8 @@ void FSP_SRV::TryLoadRomFS() {      if (romfs) {          return;      } -    auto res = OpenRomFS(); +    FileSys::Path unused; +    auto res = OpenFileSystem(Type::RomFS, unused);      if (res.Succeeded()) {          romfs = std::move(res.Unwrap());      } @@ -532,7 +507,8 @@ void FSP_SRV::Initialize(Kernel::HLERequestContext& ctx) {  void FSP_SRV::MountSdCard(Kernel::HLERequestContext& ctx) {      LOG_DEBUG(Service_FS, "called"); -    IFileSystem filesystem(OpenFileSystem(Type::SDMC).Unwrap()); +    FileSys::Path unused; +    auto filesystem = OpenFileSystem(Type::SDMC, unused).Unwrap();      IPC::ResponseBuilder rb{ctx, 2, 0, 1};      rb.Push(RESULT_SUCCESS); @@ -555,7 +531,8 @@ void FSP_SRV::CreateSaveData(Kernel::HLERequestContext& ctx) {  void FSP_SRV::MountSaveData(Kernel::HLERequestContext& ctx) {      LOG_WARNING(Service_FS, "(STUBBED) called"); -    IFileSystem filesystem(OpenFileSystem(Type::SaveData).Unwrap()); +    FileSys::Path unused; +    auto filesystem = OpenFileSystem(Type::SaveData, unused).Unwrap();      IPC::ResponseBuilder rb{ctx, 2, 0, 1};      rb.Push(RESULT_SUCCESS); @@ -582,11 +559,18 @@ void FSP_SRV::OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx) {          return;      } -    IStorage storage(romfs); +    // Attempt to open a StorageBackend interface to the RomFS +    auto storage = romfs->OpenFile({}, {}); +    if (storage.Failed()) { +        LOG_CRITICAL(Service_FS, "no storage interface available!"); +        IPC::ResponseBuilder rb{ctx, 2}; +        rb.Push(storage.Code()); +        return; +    }      IPC::ResponseBuilder rb{ctx, 2, 0, 1};      rb.Push(RESULT_SUCCESS); -    rb.PushIpcInterface<IStorage>(std::move(storage)); +    rb.PushIpcInterface<IStorage>(std::move(storage.Unwrap()));  }  void FSP_SRV::OpenRomStorage(Kernel::HLERequestContext& ctx) { diff --git a/src/core/hle/service/filesystem/fsp_srv.h b/src/core/hle/service/filesystem/fsp_srv.h index b1ef6397f..acb78fac1 100644 --- a/src/core/hle/service/filesystem/fsp_srv.h +++ b/src/core/hle/service/filesystem/fsp_srv.h @@ -29,7 +29,7 @@ private:      void OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx);      void OpenRomStorage(Kernel::HLERequestContext& ctx); -    FileSys::VirtualFile romfs; +    std::unique_ptr<FileSys::FileSystemBackend> romfs;  };  } // namespace Service::FileSystem  | 
