diff options
| author | 2018-07-07 20:24:51 -0700 | |
|---|---|---|
| committer | 2018-07-07 20:24:51 -0700 | |
| commit | 913896cbd99e414c325c9d47a987376ed6d9fffd (patch) | |
| tree | b660920a49f538f0ee00486c50a0d153d53c423d /src/core/hle | |
| parent | Merge pull request #632 from FearlessTobi/add-discord-link (diff) | |
| download | yuzu-913896cbd99e414c325c9d47a987376ed6d9fffd.tar.gz yuzu-913896cbd99e414c325c9d47a987376ed6d9fffd.tar.xz yuzu-913896cbd99e414c325c9d47a987376ed6d9fffd.zip | |
Revert "Virtual Filesystem (#597)"
This reverts commit 77c684c1140f6bf3fb7d4560d06d2efb1a2ee5e2.
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) { | |||
| 621 | IPC::ResponseBuilder rb{ctx, 4}; | 621 | IPC::ResponseBuilder rb{ctx, 4}; |
| 622 | 622 | ||
| 623 | FileSys::Path unused; | 623 | FileSys::Path unused; |
| 624 | auto savedata = FileSystem::OpenFileSystem(FileSystem::Type::SaveData); | 624 | auto savedata = FileSystem::OpenFileSystem(FileSystem::Type::SaveData, unused); |
| 625 | if (savedata.Failed()) { | 625 | if (savedata.Failed()) { |
| 626 | // Create the save data and return an error indicating that the operation was performed. | 626 | // Create the save data and return an error indicating that the operation was performed. |
| 627 | FileSystem::FormatFileSystem(FileSystem::Type::SaveData); | 627 | 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 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include "boost/container/flat_map.hpp" | 5 | #include <boost/container/flat_map.hpp> |
| 6 | #include "common/assert.h" | ||
| 7 | #include "common/common_paths.h" | ||
| 8 | #include "common/file_util.h" | 6 | #include "common/file_util.h" |
| 9 | #include "core/core.h" | ||
| 10 | #include "core/file_sys/errors.h" | ||
| 11 | #include "core/file_sys/filesystem.h" | 7 | #include "core/file_sys/filesystem.h" |
| 12 | #include "core/file_sys/vfs.h" | 8 | #include "core/file_sys/savedata_factory.h" |
| 13 | #include "core/file_sys/vfs_offset.h" | 9 | #include "core/file_sys/sdmc_factory.h" |
| 14 | #include "core/file_sys/vfs_real.h" | ||
| 15 | #include "core/hle/kernel/process.h" | ||
| 16 | #include "core/hle/service/filesystem/filesystem.h" | 10 | #include "core/hle/service/filesystem/filesystem.h" |
| 17 | #include "core/hle/service/filesystem/fsp_srv.h" | 11 | #include "core/hle/service/filesystem/fsp_srv.h" |
| 18 | 12 | ||
| 19 | namespace Service::FileSystem { | 13 | namespace Service::FileSystem { |
| 20 | 14 | ||
| 21 | // Size of emulated sd card free space, reported in bytes. | ||
| 22 | // Just using 32GB because thats reasonable | ||
| 23 | // TODO(DarkLordZach): Eventually make this configurable in settings. | ||
| 24 | constexpr u64 EMULATED_SD_REPORTED_SIZE = 32000000000; | ||
| 25 | |||
| 26 | static FileSys::VirtualDir GetDirectoryRelativeWrapped(FileSys::VirtualDir base, | ||
| 27 | const std::string& dir_name) { | ||
| 28 | if (dir_name == "." || dir_name == "" || dir_name == "/" || dir_name == "\\") | ||
| 29 | return base; | ||
| 30 | |||
| 31 | return base->GetDirectoryRelative(dir_name); | ||
| 32 | } | ||
| 33 | |||
| 34 | VfsDirectoryServiceWrapper::VfsDirectoryServiceWrapper(FileSys::VirtualDir backing_) | ||
| 35 | : backing(backing_) {} | ||
| 36 | |||
| 37 | std::string VfsDirectoryServiceWrapper::GetName() const { | ||
| 38 | return backing->GetName(); | ||
| 39 | } | ||
| 40 | |||
| 41 | ResultCode VfsDirectoryServiceWrapper::CreateFile(const std::string& path, u64 size) const { | ||
| 42 | auto dir = GetDirectoryRelativeWrapped(backing, FileUtil::GetParentPath(path)); | ||
| 43 | auto file = dir->CreateFile(FileUtil::GetFilename(path)); | ||
| 44 | if (file == nullptr) | ||
| 45 | return ResultCode(-1); | ||
| 46 | if (!file->Resize(size)) | ||
| 47 | return ResultCode(-1); | ||
| 48 | return RESULT_SUCCESS; | ||
| 49 | } | ||
| 50 | |||
| 51 | ResultCode VfsDirectoryServiceWrapper::DeleteFile(const std::string& path) const { | ||
| 52 | auto dir = GetDirectoryRelativeWrapped(backing, FileUtil::GetParentPath(path)); | ||
| 53 | if (!backing->DeleteFile(FileUtil::GetFilename(path))) | ||
| 54 | return ResultCode(-1); | ||
| 55 | return RESULT_SUCCESS; | ||
| 56 | } | ||
| 57 | |||
| 58 | ResultCode VfsDirectoryServiceWrapper::CreateDirectory(const std::string& path) const { | ||
| 59 | auto dir = GetDirectoryRelativeWrapped(backing, FileUtil::GetParentPath(path)); | ||
| 60 | if (dir == nullptr && FileUtil::GetFilename(FileUtil::GetParentPath(path)).empty()) | ||
| 61 | dir = backing; | ||
| 62 | auto new_dir = dir->CreateSubdirectory(FileUtil::GetFilename(path)); | ||
| 63 | if (new_dir == nullptr) | ||
| 64 | return ResultCode(-1); | ||
| 65 | return RESULT_SUCCESS; | ||
| 66 | } | ||
| 67 | |||
| 68 | ResultCode VfsDirectoryServiceWrapper::DeleteDirectory(const std::string& path) const { | ||
| 69 | auto dir = GetDirectoryRelativeWrapped(backing, FileUtil::GetParentPath(path)); | ||
| 70 | if (!dir->DeleteSubdirectory(FileUtil::GetFilename(path))) | ||
| 71 | return ResultCode(-1); | ||
| 72 | return RESULT_SUCCESS; | ||
| 73 | } | ||
| 74 | |||
| 75 | ResultCode VfsDirectoryServiceWrapper::DeleteDirectoryRecursively(const std::string& path) const { | ||
| 76 | auto dir = GetDirectoryRelativeWrapped(backing, FileUtil::GetParentPath(path)); | ||
| 77 | if (!dir->DeleteSubdirectoryRecursive(FileUtil::GetFilename(path))) | ||
| 78 | return ResultCode(-1); | ||
| 79 | return RESULT_SUCCESS; | ||
| 80 | } | ||
| 81 | |||
| 82 | ResultCode VfsDirectoryServiceWrapper::RenameFile(const std::string& src_path, | ||
| 83 | const std::string& dest_path) const { | ||
| 84 | auto src = backing->GetFileRelative(src_path); | ||
| 85 | if (FileUtil::GetParentPath(src_path) == FileUtil::GetParentPath(dest_path)) { | ||
| 86 | // Use more-optimized vfs implementation rename. | ||
| 87 | if (src == nullptr) | ||
| 88 | return FileSys::ERROR_PATH_NOT_FOUND; | ||
| 89 | if (!src->Rename(FileUtil::GetFilename(dest_path))) | ||
| 90 | return ResultCode(-1); | ||
| 91 | return RESULT_SUCCESS; | ||
| 92 | } | ||
| 93 | |||
| 94 | // Move by hand -- TODO(DarkLordZach): Optimize | ||
| 95 | auto c_res = CreateFile(dest_path, src->GetSize()); | ||
| 96 | if (c_res != RESULT_SUCCESS) | ||
| 97 | return c_res; | ||
| 98 | |||
| 99 | auto dest = backing->GetFileRelative(dest_path); | ||
| 100 | ASSERT_MSG(dest != nullptr, "Newly created file with success cannot be found."); | ||
| 101 | |||
| 102 | ASSERT_MSG(dest->WriteBytes(src->ReadAllBytes()) == src->GetSize(), | ||
| 103 | "Could not write all of the bytes but everything else has succeded."); | ||
| 104 | |||
| 105 | if (!src->GetContainingDirectory()->DeleteFile(FileUtil::GetFilename(src_path))) | ||
| 106 | return ResultCode(-1); | ||
| 107 | |||
| 108 | return RESULT_SUCCESS; | ||
| 109 | } | ||
| 110 | |||
| 111 | ResultCode VfsDirectoryServiceWrapper::RenameDirectory(const std::string& src_path, | ||
| 112 | const std::string& dest_path) const { | ||
| 113 | auto src = GetDirectoryRelativeWrapped(backing, src_path); | ||
| 114 | if (FileUtil::GetParentPath(src_path) == FileUtil::GetParentPath(dest_path)) { | ||
| 115 | // Use more-optimized vfs implementation rename. | ||
| 116 | if (src == nullptr) | ||
| 117 | return FileSys::ERROR_PATH_NOT_FOUND; | ||
| 118 | if (!src->Rename(FileUtil::GetFilename(dest_path))) | ||
| 119 | return ResultCode(-1); | ||
| 120 | return RESULT_SUCCESS; | ||
| 121 | } | ||
| 122 | |||
| 123 | // TODO(DarkLordZach): Implement renaming across the tree (move). | ||
| 124 | ASSERT_MSG(false, | ||
| 125 | "Could not rename directory with path \"{}\" to new path \"{}\" because parent dirs " | ||
| 126 | "don't match -- UNIMPLEMENTED", | ||
| 127 | src_path, dest_path); | ||
| 128 | |||
| 129 | return ResultCode(-1); | ||
| 130 | } | ||
| 131 | |||
| 132 | ResultVal<FileSys::VirtualFile> VfsDirectoryServiceWrapper::OpenFile(const std::string& path, | ||
| 133 | FileSys::Mode mode) const { | ||
| 134 | auto file = backing->GetFileRelative(path); | ||
| 135 | if (file == nullptr) | ||
| 136 | return FileSys::ERROR_PATH_NOT_FOUND; | ||
| 137 | |||
| 138 | if ((static_cast<u32>(mode) & static_cast<u32>(FileSys::Mode::Append)) != 0) { | ||
| 139 | return MakeResult<FileSys::VirtualFile>( | ||
| 140 | std::make_shared<FileSys::OffsetVfsFile>(file, 0, file->GetSize())); | ||
| 141 | } | ||
| 142 | |||
| 143 | return MakeResult<FileSys::VirtualFile>(file); | ||
| 144 | } | ||
| 145 | |||
| 146 | ResultVal<FileSys::VirtualDir> VfsDirectoryServiceWrapper::OpenDirectory(const std::string& path) { | ||
| 147 | auto dir = GetDirectoryRelativeWrapped(backing, path); | ||
| 148 | if (dir == nullptr) | ||
| 149 | return ResultCode(-1); | ||
| 150 | return MakeResult(dir); | ||
| 151 | } | ||
| 152 | |||
| 153 | u64 VfsDirectoryServiceWrapper::GetFreeSpaceSize() const { | ||
| 154 | if (backing->IsWritable()) | ||
| 155 | return EMULATED_SD_REPORTED_SIZE; | ||
| 156 | |||
| 157 | return 0; | ||
| 158 | } | ||
| 159 | |||
| 160 | ResultVal<FileSys::EntryType> VfsDirectoryServiceWrapper::GetEntryType( | ||
| 161 | const std::string& path) const { | ||
| 162 | auto dir = GetDirectoryRelativeWrapped(backing, FileUtil::GetParentPath(path)); | ||
| 163 | if (dir == nullptr) | ||
| 164 | return ResultCode(-1); | ||
| 165 | auto filename = FileUtil::GetFilename(path); | ||
| 166 | if (dir->GetFile(filename) != nullptr) | ||
| 167 | return MakeResult(FileSys::EntryType::File); | ||
| 168 | if (dir->GetSubdirectory(filename) != nullptr) | ||
| 169 | return MakeResult(FileSys::EntryType::Directory); | ||
| 170 | return ResultCode(-1); | ||
| 171 | } | ||
| 172 | |||
| 173 | // A deferred filesystem for nand save data. | ||
| 174 | // This must be deferred because the directory is dependent on title id, which is not set at | ||
| 175 | // registration time. | ||
| 176 | struct SaveDataDeferredFilesystem : DeferredFilesystem { | ||
| 177 | protected: | ||
| 178 | FileSys::VirtualDir CreateFilesystem() override { | ||
| 179 | u64 title_id = Core::CurrentProcess()->program_id; | ||
| 180 | // TODO(DarkLordZach): Users | ||
| 181 | u32 user_id = 0; | ||
| 182 | std::string nand_directory = fmt::format( | ||
| 183 | "{}save/{:016X}/{:08X}/", FileUtil::GetUserPath(D_NAND_IDX), title_id, user_id); | ||
| 184 | |||
| 185 | auto savedata = | ||
| 186 | std::make_shared<FileSys::RealVfsDirectory>(nand_directory, FileSys::Mode::Write); | ||
| 187 | return savedata; | ||
| 188 | } | ||
| 189 | }; | ||
| 190 | |||
| 191 | /** | 15 | /** |
| 192 | * Map of registered file systems, identified by type. Once an file system is registered here, it | 16 | * Map of registered file systems, identified by type. Once an file system is registered here, it |
| 193 | * is never removed until UnregisterFileSystems is called. | 17 | * is never removed until UnregisterFileSystems is called. |
| 194 | */ | 18 | */ |
| 195 | static boost::container::flat_map<Type, std::unique_ptr<DeferredFilesystem>> filesystem_map; | 19 | static boost::container::flat_map<Type, std::unique_ptr<FileSys::FileSystemFactory>> filesystem_map; |
| 196 | static FileSys::VirtualFile filesystem_romfs = nullptr; | ||
| 197 | 20 | ||
| 198 | ResultCode RegisterFileSystem(std::unique_ptr<DeferredFilesystem>&& factory, Type type) { | 21 | ResultCode RegisterFileSystem(std::unique_ptr<FileSys::FileSystemFactory>&& factory, Type type) { |
| 199 | auto result = filesystem_map.emplace(type, std::move(factory)); | 22 | auto result = filesystem_map.emplace(type, std::move(factory)); |
| 200 | 23 | ||
| 201 | bool inserted = result.second; | 24 | bool inserted = result.second; |
| 202 | ASSERT_MSG(inserted, "Tried to register more than one system with same id code"); | 25 | ASSERT_MSG(inserted, "Tried to register more than one system with same id code"); |
| 203 | 26 | ||
| 204 | auto& filesystem = result.first->second; | 27 | auto& filesystem = result.first->second; |
| 205 | LOG_DEBUG(Service_FS, "Registered file system with id code 0x{:08X}", static_cast<u32>(type)); | ||
| 206 | return RESULT_SUCCESS; | ||
| 207 | } | ||
| 208 | |||
| 209 | ResultCode RegisterRomFS(FileSys::VirtualFile filesystem) { | ||
| 210 | ASSERT_MSG(filesystem_romfs == nullptr, | ||
| 211 | "Tried to register more than one system with same id code"); | ||
| 212 | |||
| 213 | filesystem_romfs = filesystem; | ||
| 214 | LOG_DEBUG(Service_FS, "Registered file system {} with id code 0x{:08X}", filesystem->GetName(), | 28 | LOG_DEBUG(Service_FS, "Registered file system {} with id code 0x{:08X}", filesystem->GetName(), |
| 215 | static_cast<u32>(Type::RomFS)); | 29 | static_cast<u32>(type)); |
| 216 | return RESULT_SUCCESS; | 30 | return RESULT_SUCCESS; |
| 217 | } | 31 | } |
| 218 | 32 | ||
| 219 | ResultVal<FileSys::VirtualDir> OpenFileSystem(Type type) { | 33 | ResultVal<std::unique_ptr<FileSys::FileSystemBackend>> OpenFileSystem(Type type, |
| 34 | FileSys::Path& path) { | ||
| 220 | LOG_TRACE(Service_FS, "Opening FileSystem with type={}", static_cast<u32>(type)); | 35 | LOG_TRACE(Service_FS, "Opening FileSystem with type={}", static_cast<u32>(type)); |
| 221 | 36 | ||
| 222 | auto itr = filesystem_map.find(type); | 37 | auto itr = filesystem_map.find(type); |
| @@ -225,13 +40,7 @@ ResultVal<FileSys::VirtualDir> OpenFileSystem(Type type) { | |||
| 225 | return ResultCode(-1); | 40 | return ResultCode(-1); |
| 226 | } | 41 | } |
| 227 | 42 | ||
| 228 | return MakeResult(itr->second->Get()); | 43 | return itr->second->Open(path); |
| 229 | } | ||
| 230 | |||
| 231 | ResultVal<FileSys::VirtualFile> OpenRomFS() { | ||
| 232 | if (filesystem_romfs == nullptr) | ||
| 233 | return ResultCode(-1); | ||
| 234 | return MakeResult(filesystem_romfs); | ||
| 235 | } | 44 | } |
| 236 | 45 | ||
| 237 | ResultCode FormatFileSystem(Type type) { | 46 | ResultCode FormatFileSystem(Type type) { |
| @@ -243,21 +52,21 @@ ResultCode FormatFileSystem(Type type) { | |||
| 243 | return ResultCode(-1); | 52 | return ResultCode(-1); |
| 244 | } | 53 | } |
| 245 | 54 | ||
| 246 | return itr->second->Get()->GetParentDirectory()->DeleteSubdirectory( | 55 | FileSys::Path unused; |
| 247 | itr->second->Get()->GetName()) | 56 | return itr->second->Format(unused); |
| 248 | ? RESULT_SUCCESS | ||
| 249 | : ResultCode(-1); | ||
| 250 | } | 57 | } |
| 251 | 58 | ||
| 252 | void RegisterFileSystems() { | 59 | void RegisterFileSystems() { |
| 253 | filesystem_map.clear(); | 60 | filesystem_map.clear(); |
| 254 | filesystem_romfs = nullptr; | ||
| 255 | 61 | ||
| 62 | std::string nand_directory = FileUtil::GetUserPath(D_NAND_IDX); | ||
| 256 | std::string sd_directory = FileUtil::GetUserPath(D_SDMC_IDX); | 63 | std::string sd_directory = FileUtil::GetUserPath(D_SDMC_IDX); |
| 257 | auto sdcard = std::make_shared<FileSys::RealVfsDirectory>(sd_directory, FileSys::Mode::Write); | ||
| 258 | RegisterFileSystem(std::make_unique<DeferredFilesystem>(sdcard), Type::SDMC); | ||
| 259 | 64 | ||
| 260 | RegisterFileSystem(std::make_unique<SaveDataDeferredFilesystem>(), Type::SaveData); | 65 | auto savedata = std::make_unique<FileSys::SaveData_Factory>(std::move(nand_directory)); |
| 66 | RegisterFileSystem(std::move(savedata), Type::SaveData); | ||
| 67 | |||
| 68 | auto sdcard = std::make_unique<FileSys::SDMC_Factory>(std::move(sd_directory)); | ||
| 69 | RegisterFileSystem(std::move(sdcard), Type::SDMC); | ||
| 261 | } | 70 | } |
| 262 | 71 | ||
| 263 | void InstallInterfaces(SM::ServiceManager& service_manager) { | 72 | 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 @@ | |||
| 6 | 6 | ||
| 7 | #include <memory> | 7 | #include <memory> |
| 8 | #include "common/common_types.h" | 8 | #include "common/common_types.h" |
| 9 | #include "core/file_sys/filesystem.h" | ||
| 10 | #include "core/file_sys/vfs.h" | ||
| 11 | #include "core/hle/result.h" | 9 | #include "core/hle/result.h" |
| 12 | 10 | ||
| 13 | namespace FileSys { | 11 | namespace FileSys { |
| @@ -31,136 +29,12 @@ enum class Type { | |||
| 31 | SDMC = 3, | 29 | SDMC = 3, |
| 32 | }; | 30 | }; |
| 33 | 31 | ||
| 34 | // A class that wraps a VfsDirectory with methods that return ResultVal and ResultCode instead of | ||
| 35 | // pointers and booleans. This makes using a VfsDirectory with switch services much easier and | ||
| 36 | // avoids repetitive code. | ||
| 37 | class VfsDirectoryServiceWrapper { | ||
| 38 | public: | ||
| 39 | explicit VfsDirectoryServiceWrapper(FileSys::VirtualDir backing); | ||
| 40 | |||
| 41 | /** | ||
| 42 | * Get a descriptive name for the archive (e.g. "RomFS", "SaveData", etc.) | ||
| 43 | */ | ||
| 44 | std::string GetName() const; | ||
| 45 | |||
| 46 | /** | ||
| 47 | * Create a file specified by its path | ||
| 48 | * @param path Path relative to the Archive | ||
| 49 | * @param size The size of the new file, filled with zeroes | ||
| 50 | * @return Result of the operation | ||
| 51 | */ | ||
| 52 | ResultCode CreateFile(const std::string& path, u64 size) const; | ||
| 53 | |||
| 54 | /** | ||
| 55 | * Delete a file specified by its path | ||
| 56 | * @param path Path relative to the archive | ||
| 57 | * @return Result of the operation | ||
| 58 | */ | ||
| 59 | ResultCode DeleteFile(const std::string& path) const; | ||
| 60 | |||
| 61 | /** | ||
| 62 | * Create a directory specified by its path | ||
| 63 | * @param path Path relative to the archive | ||
| 64 | * @return Result of the operation | ||
| 65 | */ | ||
| 66 | ResultCode CreateDirectory(const std::string& path) const; | ||
| 67 | |||
| 68 | /** | ||
| 69 | * Delete a directory specified by its path | ||
| 70 | * @param path Path relative to the archive | ||
| 71 | * @return Result of the operation | ||
| 72 | */ | ||
| 73 | ResultCode DeleteDirectory(const std::string& path) const; | ||
| 74 | |||
| 75 | /** | ||
| 76 | * Delete a directory specified by its path and anything under it | ||
| 77 | * @param path Path relative to the archive | ||
| 78 | * @return Result of the operation | ||
| 79 | */ | ||
| 80 | ResultCode DeleteDirectoryRecursively(const std::string& path) const; | ||
| 81 | |||
| 82 | /** | ||
| 83 | * Rename a File specified by its path | ||
| 84 | * @param src_path Source path relative to the archive | ||
| 85 | * @param dest_path Destination path relative to the archive | ||
| 86 | * @return Result of the operation | ||
| 87 | */ | ||
| 88 | ResultCode RenameFile(const std::string& src_path, const std::string& dest_path) const; | ||
| 89 | |||
| 90 | /** | ||
| 91 | * Rename a Directory specified by its path | ||
| 92 | * @param src_path Source path relative to the archive | ||
| 93 | * @param dest_path Destination path relative to the archive | ||
| 94 | * @return Result of the operation | ||
| 95 | */ | ||
| 96 | ResultCode RenameDirectory(const std::string& src_path, const std::string& dest_path) const; | ||
| 97 | |||
| 98 | /** | ||
| 99 | * Open a file specified by its path, using the specified mode | ||
| 100 | * @param path Path relative to the archive | ||
| 101 | * @param mode Mode to open the file with | ||
| 102 | * @return Opened file, or error code | ||
| 103 | */ | ||
| 104 | ResultVal<FileSys::VirtualFile> OpenFile(const std::string& path, FileSys::Mode mode) const; | ||
| 105 | |||
| 106 | /** | ||
| 107 | * Open a directory specified by its path | ||
| 108 | * @param path Path relative to the archive | ||
| 109 | * @return Opened directory, or error code | ||
| 110 | */ | ||
| 111 | ResultVal<FileSys::VirtualDir> OpenDirectory(const std::string& path); | ||
| 112 | |||
| 113 | /** | ||
| 114 | * Get the free space | ||
| 115 | * @return The number of free bytes in the archive | ||
| 116 | */ | ||
| 117 | u64 GetFreeSpaceSize() const; | ||
| 118 | |||
| 119 | /** | ||
| 120 | * Get the type of the specified path | ||
| 121 | * @return The type of the specified path or error code | ||
| 122 | */ | ||
| 123 | ResultVal<FileSys::EntryType> GetEntryType(const std::string& path) const; | ||
| 124 | |||
| 125 | private: | ||
| 126 | FileSys::VirtualDir backing; | ||
| 127 | }; | ||
| 128 | |||
| 129 | // A class that deferres the creation of a filesystem until a later time. | ||
| 130 | // This is useful if construction depends on a variable not known when the filesystem is registered. | ||
| 131 | // Construct this with a filesystem (VirtualDir) to avoid the deferrence feature or override the | ||
| 132 | // CreateFilesystem method which will be called on first use. | ||
| 133 | struct DeferredFilesystem { | ||
| 134 | DeferredFilesystem() = default; | ||
| 135 | |||
| 136 | explicit DeferredFilesystem(FileSys::VirtualDir vfs_directory) : fs(std::move(vfs_directory)) {} | ||
| 137 | |||
| 138 | FileSys::VirtualDir Get() { | ||
| 139 | if (fs == nullptr) | ||
| 140 | fs = CreateFilesystem(); | ||
| 141 | |||
| 142 | return fs; | ||
| 143 | } | ||
| 144 | |||
| 145 | virtual ~DeferredFilesystem() = default; | ||
| 146 | |||
| 147 | protected: | ||
| 148 | virtual FileSys::VirtualDir CreateFilesystem() { | ||
| 149 | return fs; | ||
| 150 | } | ||
| 151 | |||
| 152 | private: | ||
| 153 | FileSys::VirtualDir fs; | ||
| 154 | }; | ||
| 155 | |||
| 156 | /** | 32 | /** |
| 157 | * Registers a FileSystem, instances of which can later be opened using its IdCode. | 33 | * Registers a FileSystem, instances of which can later be opened using its IdCode. |
| 158 | * @param factory FileSystem backend interface to use | 34 | * @param factory FileSystem backend interface to use |
| 159 | * @param type Type used to access this type of FileSystem | 35 | * @param type Type used to access this type of FileSystem |
| 160 | */ | 36 | */ |
| 161 | ResultCode RegisterFileSystem(std::unique_ptr<DeferredFilesystem>&& fs, Type type); | 37 | ResultCode RegisterFileSystem(std::unique_ptr<FileSys::FileSystemFactory>&& factory, Type type); |
| 162 | |||
| 163 | ResultCode RegisterRomFS(FileSys::VirtualFile fs); | ||
| 164 | 38 | ||
| 165 | /** | 39 | /** |
| 166 | * Opens a file system | 40 | * Opens a file system |
| @@ -168,9 +42,8 @@ ResultCode RegisterRomFS(FileSys::VirtualFile fs); | |||
| 168 | * @param path Path to the file system, used with Binary paths | 42 | * @param path Path to the file system, used with Binary paths |
| 169 | * @return FileSys::FileSystemBackend interface to the file system | 43 | * @return FileSys::FileSystemBackend interface to the file system |
| 170 | */ | 44 | */ |
| 171 | ResultVal<FileSys::VirtualDir> OpenFileSystem(Type type); | 45 | ResultVal<std::unique_ptr<FileSys::FileSystemBackend>> OpenFileSystem(Type type, |
| 172 | 46 | FileSys::Path& path); | |
| 173 | ResultVal<FileSys::VirtualFile> OpenRomFS(); | ||
| 174 | 47 | ||
| 175 | /** | 48 | /** |
| 176 | * Formats a file system | 49 | * 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 { | |||
| 19 | 19 | ||
| 20 | class IStorage final : public ServiceFramework<IStorage> { | 20 | class IStorage final : public ServiceFramework<IStorage> { |
| 21 | public: | 21 | public: |
| 22 | IStorage(FileSys::VirtualFile backend_) | 22 | IStorage(std::unique_ptr<FileSys::StorageBackend>&& backend) |
| 23 | : ServiceFramework("IStorage"), backend(std::move(backend_)) { | 23 | : ServiceFramework("IStorage"), backend(std::move(backend)) { |
| 24 | static const FunctionInfo functions[] = { | 24 | static const FunctionInfo functions[] = { |
| 25 | {0, &IStorage::Read, "Read"}, {1, nullptr, "Write"}, {2, nullptr, "Flush"}, | 25 | {0, &IStorage::Read, "Read"}, {1, nullptr, "Write"}, {2, nullptr, "Flush"}, |
| 26 | {3, nullptr, "SetSize"}, {4, nullptr, "GetSize"}, {5, nullptr, "OperateRange"}, | 26 | {3, nullptr, "SetSize"}, {4, nullptr, "GetSize"}, {5, nullptr, "OperateRange"}, |
| @@ -29,7 +29,7 @@ public: | |||
| 29 | } | 29 | } |
| 30 | 30 | ||
| 31 | private: | 31 | private: |
| 32 | FileSys::VirtualFile backend; | 32 | std::unique_ptr<FileSys::StorageBackend> backend; |
| 33 | 33 | ||
| 34 | void Read(Kernel::HLERequestContext& ctx) { | 34 | void Read(Kernel::HLERequestContext& ctx) { |
| 35 | IPC::RequestParser rp{ctx}; | 35 | IPC::RequestParser rp{ctx}; |
| @@ -51,8 +51,8 @@ private: | |||
| 51 | } | 51 | } |
| 52 | 52 | ||
| 53 | // Read the data from the Storage backend | 53 | // Read the data from the Storage backend |
| 54 | std::vector<u8> output = backend->ReadBytes(length, offset); | 54 | std::vector<u8> output(length); |
| 55 | auto res = MakeResult<size_t>(output.size()); | 55 | ResultVal<size_t> res = backend->Read(offset, length, output.data()); |
| 56 | if (res.Failed()) { | 56 | if (res.Failed()) { |
| 57 | IPC::ResponseBuilder rb{ctx, 2}; | 57 | IPC::ResponseBuilder rb{ctx, 2}; |
| 58 | rb.Push(res.Code()); | 58 | rb.Push(res.Code()); |
| @@ -69,8 +69,8 @@ private: | |||
| 69 | 69 | ||
| 70 | class IFile final : public ServiceFramework<IFile> { | 70 | class IFile final : public ServiceFramework<IFile> { |
| 71 | public: | 71 | public: |
| 72 | explicit IFile(FileSys::VirtualFile backend_) | 72 | explicit IFile(std::unique_ptr<FileSys::StorageBackend>&& backend) |
| 73 | : ServiceFramework("IFile"), backend(std::move(backend_)) { | 73 | : ServiceFramework("IFile"), backend(std::move(backend)) { |
| 74 | static const FunctionInfo functions[] = { | 74 | static const FunctionInfo functions[] = { |
| 75 | {0, &IFile::Read, "Read"}, {1, &IFile::Write, "Write"}, | 75 | {0, &IFile::Read, "Read"}, {1, &IFile::Write, "Write"}, |
| 76 | {2, &IFile::Flush, "Flush"}, {3, &IFile::SetSize, "SetSize"}, | 76 | {2, &IFile::Flush, "Flush"}, {3, &IFile::SetSize, "SetSize"}, |
| @@ -80,7 +80,7 @@ public: | |||
| 80 | } | 80 | } |
| 81 | 81 | ||
| 82 | private: | 82 | private: |
| 83 | FileSys::VirtualFile backend; | 83 | std::unique_ptr<FileSys::StorageBackend> backend; |
| 84 | 84 | ||
| 85 | void Read(Kernel::HLERequestContext& ctx) { | 85 | void Read(Kernel::HLERequestContext& ctx) { |
| 86 | IPC::RequestParser rp{ctx}; | 86 | IPC::RequestParser rp{ctx}; |
| @@ -103,8 +103,8 @@ private: | |||
| 103 | } | 103 | } |
| 104 | 104 | ||
| 105 | // Read the data from the Storage backend | 105 | // Read the data from the Storage backend |
| 106 | std::vector<u8> output = backend->ReadBytes(length, offset); | 106 | std::vector<u8> output(length); |
| 107 | auto res = MakeResult<size_t>(output.size()); | 107 | ResultVal<size_t> res = backend->Read(offset, length, output.data()); |
| 108 | if (res.Failed()) { | 108 | if (res.Failed()) { |
| 109 | IPC::ResponseBuilder rb{ctx, 2}; | 109 | IPC::ResponseBuilder rb{ctx, 2}; |
| 110 | rb.Push(res.Code()); | 110 | rb.Push(res.Code()); |
| @@ -139,10 +139,9 @@ private: | |||
| 139 | return; | 139 | return; |
| 140 | } | 140 | } |
| 141 | 141 | ||
| 142 | std::vector<u8> data = ctx.ReadBuffer(); | ||
| 143 | data.resize(length); | ||
| 144 | // Write the data to the Storage backend | 142 | // Write the data to the Storage backend |
| 145 | auto res = MakeResult<size_t>(backend->WriteBytes(data, offset)); | 143 | std::vector<u8> data = ctx.ReadBuffer(); |
| 144 | ResultVal<size_t> res = backend->Write(offset, length, true, data.data()); | ||
| 146 | if (res.Failed()) { | 145 | if (res.Failed()) { |
| 147 | IPC::ResponseBuilder rb{ctx, 2}; | 146 | IPC::ResponseBuilder rb{ctx, 2}; |
| 148 | rb.Push(res.Code()); | 147 | rb.Push(res.Code()); |
| @@ -155,8 +154,7 @@ private: | |||
| 155 | 154 | ||
| 156 | void Flush(Kernel::HLERequestContext& ctx) { | 155 | void Flush(Kernel::HLERequestContext& ctx) { |
| 157 | LOG_DEBUG(Service_FS, "called"); | 156 | LOG_DEBUG(Service_FS, "called"); |
| 158 | 157 | backend->Flush(); | |
| 159 | // Exists for SDK compatibiltity -- No need to flush file. | ||
| 160 | 158 | ||
| 161 | IPC::ResponseBuilder rb{ctx, 2}; | 159 | IPC::ResponseBuilder rb{ctx, 2}; |
| 162 | rb.Push(RESULT_SUCCESS); | 160 | rb.Push(RESULT_SUCCESS); |
| @@ -165,7 +163,7 @@ private: | |||
| 165 | void SetSize(Kernel::HLERequestContext& ctx) { | 163 | void SetSize(Kernel::HLERequestContext& ctx) { |
| 166 | IPC::RequestParser rp{ctx}; | 164 | IPC::RequestParser rp{ctx}; |
| 167 | const u64 size = rp.Pop<u64>(); | 165 | const u64 size = rp.Pop<u64>(); |
| 168 | backend->Resize(size); | 166 | backend->SetSize(size); |
| 169 | LOG_DEBUG(Service_FS, "called, size={}", size); | 167 | LOG_DEBUG(Service_FS, "called, size={}", size); |
| 170 | 168 | ||
| 171 | IPC::ResponseBuilder rb{ctx, 2}; | 169 | IPC::ResponseBuilder rb{ctx, 2}; |
| @@ -182,38 +180,19 @@ private: | |||
| 182 | } | 180 | } |
| 183 | }; | 181 | }; |
| 184 | 182 | ||
| 185 | template <typename T> | ||
| 186 | static void BuildEntryIndex(std::vector<FileSys::Entry>& entries, const std::vector<T>& new_data, | ||
| 187 | FileSys::EntryType type) { | ||
| 188 | for (const auto& new_entry : new_data) { | ||
| 189 | FileSys::Entry entry; | ||
| 190 | entry.filename[0] = '\0'; | ||
| 191 | std::strncat(entry.filename, new_entry->GetName().c_str(), FileSys::FILENAME_LENGTH - 1); | ||
| 192 | entry.type = type; | ||
| 193 | entry.file_size = new_entry->GetSize(); | ||
| 194 | entries.emplace_back(std::move(entry)); | ||
| 195 | } | ||
| 196 | } | ||
| 197 | |||
| 198 | class IDirectory final : public ServiceFramework<IDirectory> { | 183 | class IDirectory final : public ServiceFramework<IDirectory> { |
| 199 | public: | 184 | public: |
| 200 | explicit IDirectory(FileSys::VirtualDir backend_) | 185 | explicit IDirectory(std::unique_ptr<FileSys::DirectoryBackend>&& backend) |
| 201 | : ServiceFramework("IDirectory"), backend(std::move(backend_)) { | 186 | : ServiceFramework("IDirectory"), backend(std::move(backend)) { |
| 202 | static const FunctionInfo functions[] = { | 187 | static const FunctionInfo functions[] = { |
| 203 | {0, &IDirectory::Read, "Read"}, | 188 | {0, &IDirectory::Read, "Read"}, |
| 204 | {1, &IDirectory::GetEntryCount, "GetEntryCount"}, | 189 | {1, &IDirectory::GetEntryCount, "GetEntryCount"}, |
| 205 | }; | 190 | }; |
| 206 | RegisterHandlers(functions); | 191 | RegisterHandlers(functions); |
| 207 | |||
| 208 | // Build entry index now to save time later. | ||
| 209 | BuildEntryIndex(entries, backend->GetFiles(), FileSys::File); | ||
| 210 | BuildEntryIndex(entries, backend->GetSubdirectories(), FileSys::Directory); | ||
| 211 | } | 192 | } |
| 212 | 193 | ||
| 213 | private: | 194 | private: |
| 214 | FileSys::VirtualDir backend; | 195 | std::unique_ptr<FileSys::DirectoryBackend> backend; |
| 215 | std::vector<FileSys::Entry> entries; | ||
| 216 | u64 next_entry_index = 0; | ||
| 217 | 196 | ||
| 218 | void Read(Kernel::HLERequestContext& ctx) { | 197 | void Read(Kernel::HLERequestContext& ctx) { |
| 219 | IPC::RequestParser rp{ctx}; | 198 | IPC::RequestParser rp{ctx}; |
| @@ -224,31 +203,26 @@ private: | |||
| 224 | // Calculate how many entries we can fit in the output buffer | 203 | // Calculate how many entries we can fit in the output buffer |
| 225 | u64 count_entries = ctx.GetWriteBufferSize() / sizeof(FileSys::Entry); | 204 | u64 count_entries = ctx.GetWriteBufferSize() / sizeof(FileSys::Entry); |
| 226 | 205 | ||
| 227 | // Cap at total number of entries. | ||
| 228 | u64 actual_entries = std::min(count_entries, entries.size() - next_entry_index); | ||
| 229 | |||
| 230 | // Read the data from the Directory backend | 206 | // Read the data from the Directory backend |
| 231 | std::vector<FileSys::Entry> entry_data(entries.begin() + next_entry_index, | 207 | std::vector<FileSys::Entry> entries(count_entries); |
| 232 | entries.begin() + next_entry_index + actual_entries); | 208 | u64 read_entries = backend->Read(count_entries, entries.data()); |
| 233 | |||
| 234 | next_entry_index += actual_entries; | ||
| 235 | 209 | ||
| 236 | // Convert the data into a byte array | 210 | // Convert the data into a byte array |
| 237 | std::vector<u8> output(entry_data.size() * sizeof(FileSys::Entry)); | 211 | std::vector<u8> output(entries.size() * sizeof(FileSys::Entry)); |
| 238 | std::memcpy(output.data(), entry_data.data(), output.size()); | 212 | std::memcpy(output.data(), entries.data(), output.size()); |
| 239 | 213 | ||
| 240 | // Write the data to memory | 214 | // Write the data to memory |
| 241 | ctx.WriteBuffer(output); | 215 | ctx.WriteBuffer(output); |
| 242 | 216 | ||
| 243 | IPC::ResponseBuilder rb{ctx, 4}; | 217 | IPC::ResponseBuilder rb{ctx, 4}; |
| 244 | rb.Push(RESULT_SUCCESS); | 218 | rb.Push(RESULT_SUCCESS); |
| 245 | rb.Push(actual_entries); | 219 | rb.Push(read_entries); |
| 246 | } | 220 | } |
| 247 | 221 | ||
| 248 | void GetEntryCount(Kernel::HLERequestContext& ctx) { | 222 | void GetEntryCount(Kernel::HLERequestContext& ctx) { |
| 249 | LOG_DEBUG(Service_FS, "called"); | 223 | LOG_DEBUG(Service_FS, "called"); |
| 250 | 224 | ||
| 251 | u64 count = entries.size() - next_entry_index; | 225 | u64 count = backend->GetEntryCount(); |
| 252 | 226 | ||
| 253 | IPC::ResponseBuilder rb{ctx, 4}; | 227 | IPC::ResponseBuilder rb{ctx, 4}; |
| 254 | rb.Push(RESULT_SUCCESS); | 228 | rb.Push(RESULT_SUCCESS); |
| @@ -258,7 +232,7 @@ private: | |||
| 258 | 232 | ||
| 259 | class IFileSystem final : public ServiceFramework<IFileSystem> { | 233 | class IFileSystem final : public ServiceFramework<IFileSystem> { |
| 260 | public: | 234 | public: |
| 261 | explicit IFileSystem(FileSys::VirtualDir backend) | 235 | explicit IFileSystem(std::unique_ptr<FileSys::FileSystemBackend>&& backend) |
| 262 | : ServiceFramework("IFileSystem"), backend(std::move(backend)) { | 236 | : ServiceFramework("IFileSystem"), backend(std::move(backend)) { |
| 263 | static const FunctionInfo functions[] = { | 237 | static const FunctionInfo functions[] = { |
| 264 | {0, &IFileSystem::CreateFile, "CreateFile"}, | 238 | {0, &IFileSystem::CreateFile, "CreateFile"}, |
| @@ -293,7 +267,7 @@ public: | |||
| 293 | LOG_DEBUG(Service_FS, "called file {} mode 0x{:X} size 0x{:08X}", name, mode, size); | 267 | LOG_DEBUG(Service_FS, "called file {} mode 0x{:X} size 0x{:08X}", name, mode, size); |
| 294 | 268 | ||
| 295 | IPC::ResponseBuilder rb{ctx, 2}; | 269 | IPC::ResponseBuilder rb{ctx, 2}; |
| 296 | rb.Push(backend.CreateFile(name, size)); | 270 | rb.Push(backend->CreateFile(name, size)); |
| 297 | } | 271 | } |
| 298 | 272 | ||
| 299 | void DeleteFile(Kernel::HLERequestContext& ctx) { | 273 | void DeleteFile(Kernel::HLERequestContext& ctx) { |
| @@ -305,7 +279,7 @@ public: | |||
| 305 | LOG_DEBUG(Service_FS, "called file {}", name); | 279 | LOG_DEBUG(Service_FS, "called file {}", name); |
| 306 | 280 | ||
| 307 | IPC::ResponseBuilder rb{ctx, 2}; | 281 | IPC::ResponseBuilder rb{ctx, 2}; |
| 308 | rb.Push(backend.DeleteFile(name)); | 282 | rb.Push(backend->DeleteFile(name)); |
| 309 | } | 283 | } |
| 310 | 284 | ||
| 311 | void CreateDirectory(Kernel::HLERequestContext& ctx) { | 285 | void CreateDirectory(Kernel::HLERequestContext& ctx) { |
| @@ -317,7 +291,7 @@ public: | |||
| 317 | LOG_DEBUG(Service_FS, "called directory {}", name); | 291 | LOG_DEBUG(Service_FS, "called directory {}", name); |
| 318 | 292 | ||
| 319 | IPC::ResponseBuilder rb{ctx, 2}; | 293 | IPC::ResponseBuilder rb{ctx, 2}; |
| 320 | rb.Push(backend.CreateDirectory(name)); | 294 | rb.Push(backend->CreateDirectory(name)); |
| 321 | } | 295 | } |
| 322 | 296 | ||
| 323 | void RenameFile(Kernel::HLERequestContext& ctx) { | 297 | void RenameFile(Kernel::HLERequestContext& ctx) { |
| @@ -335,7 +309,7 @@ public: | |||
| 335 | LOG_DEBUG(Service_FS, "called file '{}' to file '{}'", src_name, dst_name); | 309 | LOG_DEBUG(Service_FS, "called file '{}' to file '{}'", src_name, dst_name); |
| 336 | 310 | ||
| 337 | IPC::ResponseBuilder rb{ctx, 2}; | 311 | IPC::ResponseBuilder rb{ctx, 2}; |
| 338 | rb.Push(backend.RenameFile(src_name, dst_name)); | 312 | rb.Push(backend->RenameFile(src_name, dst_name)); |
| 339 | } | 313 | } |
| 340 | 314 | ||
| 341 | void OpenFile(Kernel::HLERequestContext& ctx) { | 315 | void OpenFile(Kernel::HLERequestContext& ctx) { |
| @@ -348,14 +322,14 @@ public: | |||
| 348 | 322 | ||
| 349 | LOG_DEBUG(Service_FS, "called file {} mode {}", name, static_cast<u32>(mode)); | 323 | LOG_DEBUG(Service_FS, "called file {} mode {}", name, static_cast<u32>(mode)); |
| 350 | 324 | ||
| 351 | auto result = backend.OpenFile(name, mode); | 325 | auto result = backend->OpenFile(name, mode); |
| 352 | if (result.Failed()) { | 326 | if (result.Failed()) { |
| 353 | IPC::ResponseBuilder rb{ctx, 2}; | 327 | IPC::ResponseBuilder rb{ctx, 2}; |
| 354 | rb.Push(result.Code()); | 328 | rb.Push(result.Code()); |
| 355 | return; | 329 | return; |
| 356 | } | 330 | } |
| 357 | 331 | ||
| 358 | IFile file(result.Unwrap()); | 332 | auto file = std::move(result.Unwrap()); |
| 359 | 333 | ||
| 360 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 334 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 361 | rb.Push(RESULT_SUCCESS); | 335 | rb.Push(RESULT_SUCCESS); |
| @@ -373,14 +347,14 @@ public: | |||
| 373 | 347 | ||
| 374 | LOG_DEBUG(Service_FS, "called directory {} filter {}", name, filter_flags); | 348 | LOG_DEBUG(Service_FS, "called directory {} filter {}", name, filter_flags); |
| 375 | 349 | ||
| 376 | auto result = backend.OpenDirectory(name); | 350 | auto result = backend->OpenDirectory(name); |
| 377 | if (result.Failed()) { | 351 | if (result.Failed()) { |
| 378 | IPC::ResponseBuilder rb{ctx, 2}; | 352 | IPC::ResponseBuilder rb{ctx, 2}; |
| 379 | rb.Push(result.Code()); | 353 | rb.Push(result.Code()); |
| 380 | return; | 354 | return; |
| 381 | } | 355 | } |
| 382 | 356 | ||
| 383 | IDirectory directory(result.Unwrap()); | 357 | auto directory = std::move(result.Unwrap()); |
| 384 | 358 | ||
| 385 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 359 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 386 | rb.Push(RESULT_SUCCESS); | 360 | rb.Push(RESULT_SUCCESS); |
| @@ -395,7 +369,7 @@ public: | |||
| 395 | 369 | ||
| 396 | LOG_DEBUG(Service_FS, "called file {}", name); | 370 | LOG_DEBUG(Service_FS, "called file {}", name); |
| 397 | 371 | ||
| 398 | auto result = backend.GetEntryType(name); | 372 | auto result = backend->GetEntryType(name); |
| 399 | if (result.Failed()) { | 373 | if (result.Failed()) { |
| 400 | IPC::ResponseBuilder rb{ctx, 2}; | 374 | IPC::ResponseBuilder rb{ctx, 2}; |
| 401 | rb.Push(result.Code()); | 375 | rb.Push(result.Code()); |
| @@ -415,7 +389,7 @@ public: | |||
| 415 | } | 389 | } |
| 416 | 390 | ||
| 417 | private: | 391 | private: |
| 418 | VfsDirectoryServiceWrapper backend; | 392 | std::unique_ptr<FileSys::FileSystemBackend> backend; |
| 419 | }; | 393 | }; |
| 420 | 394 | ||
| 421 | FSP_SRV::FSP_SRV() : ServiceFramework("fsp-srv") { | 395 | FSP_SRV::FSP_SRV() : ServiceFramework("fsp-srv") { |
| @@ -516,7 +490,8 @@ void FSP_SRV::TryLoadRomFS() { | |||
| 516 | if (romfs) { | 490 | if (romfs) { |
| 517 | return; | 491 | return; |
| 518 | } | 492 | } |
| 519 | auto res = OpenRomFS(); | 493 | FileSys::Path unused; |
| 494 | auto res = OpenFileSystem(Type::RomFS, unused); | ||
| 520 | if (res.Succeeded()) { | 495 | if (res.Succeeded()) { |
| 521 | romfs = std::move(res.Unwrap()); | 496 | romfs = std::move(res.Unwrap()); |
| 522 | } | 497 | } |
| @@ -532,7 +507,8 @@ void FSP_SRV::Initialize(Kernel::HLERequestContext& ctx) { | |||
| 532 | void FSP_SRV::MountSdCard(Kernel::HLERequestContext& ctx) { | 507 | void FSP_SRV::MountSdCard(Kernel::HLERequestContext& ctx) { |
| 533 | LOG_DEBUG(Service_FS, "called"); | 508 | LOG_DEBUG(Service_FS, "called"); |
| 534 | 509 | ||
| 535 | IFileSystem filesystem(OpenFileSystem(Type::SDMC).Unwrap()); | 510 | FileSys::Path unused; |
| 511 | auto filesystem = OpenFileSystem(Type::SDMC, unused).Unwrap(); | ||
| 536 | 512 | ||
| 537 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 513 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 538 | rb.Push(RESULT_SUCCESS); | 514 | rb.Push(RESULT_SUCCESS); |
| @@ -555,7 +531,8 @@ void FSP_SRV::CreateSaveData(Kernel::HLERequestContext& ctx) { | |||
| 555 | void FSP_SRV::MountSaveData(Kernel::HLERequestContext& ctx) { | 531 | void FSP_SRV::MountSaveData(Kernel::HLERequestContext& ctx) { |
| 556 | LOG_WARNING(Service_FS, "(STUBBED) called"); | 532 | LOG_WARNING(Service_FS, "(STUBBED) called"); |
| 557 | 533 | ||
| 558 | IFileSystem filesystem(OpenFileSystem(Type::SaveData).Unwrap()); | 534 | FileSys::Path unused; |
| 535 | auto filesystem = OpenFileSystem(Type::SaveData, unused).Unwrap(); | ||
| 559 | 536 | ||
| 560 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 537 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 561 | rb.Push(RESULT_SUCCESS); | 538 | rb.Push(RESULT_SUCCESS); |
| @@ -582,11 +559,18 @@ void FSP_SRV::OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx) { | |||
| 582 | return; | 559 | return; |
| 583 | } | 560 | } |
| 584 | 561 | ||
| 585 | IStorage storage(romfs); | 562 | // Attempt to open a StorageBackend interface to the RomFS |
| 563 | auto storage = romfs->OpenFile({}, {}); | ||
| 564 | if (storage.Failed()) { | ||
| 565 | LOG_CRITICAL(Service_FS, "no storage interface available!"); | ||
| 566 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 567 | rb.Push(storage.Code()); | ||
| 568 | return; | ||
| 569 | } | ||
| 586 | 570 | ||
| 587 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 571 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 588 | rb.Push(RESULT_SUCCESS); | 572 | rb.Push(RESULT_SUCCESS); |
| 589 | rb.PushIpcInterface<IStorage>(std::move(storage)); | 573 | rb.PushIpcInterface<IStorage>(std::move(storage.Unwrap())); |
| 590 | } | 574 | } |
| 591 | 575 | ||
| 592 | void FSP_SRV::OpenRomStorage(Kernel::HLERequestContext& ctx) { | 576 | 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: | |||
| 29 | void OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx); | 29 | void OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx); |
| 30 | void OpenRomStorage(Kernel::HLERequestContext& ctx); | 30 | void OpenRomStorage(Kernel::HLERequestContext& ctx); |
| 31 | 31 | ||
| 32 | FileSys::VirtualFile romfs; | 32 | std::unique_ptr<FileSys::FileSystemBackend> romfs; |
| 33 | }; | 33 | }; |
| 34 | 34 | ||
| 35 | } // namespace Service::FileSystem | 35 | } // namespace Service::FileSystem |