diff options
| author | 2015-02-10 18:27:16 -0500 | |
|---|---|---|
| committer | 2015-02-10 18:27:16 -0500 | |
| commit | 27e6e6b3cb2ee1ab3a996c2b4be1d9a3c4e6b75d (patch) | |
| tree | fd8b0290d4a0353c11c0e168200b20b5a89e297c /src/core/file_sys | |
| parent | Merge pull request #553 from lioncash/denorm (diff) | |
| parent | PTM: Fixed a problem with the gamecoin PTM file. (diff) | |
| download | yuzu-27e6e6b3cb2ee1ab3a996c2b4be1d9a3c4e6b75d.tar.gz yuzu-27e6e6b3cb2ee1ab3a996c2b4be1d9a3c4e6b75d.tar.xz yuzu-27e6e6b3cb2ee1ab3a996c2b4be1d9a3c4e6b75d.zip | |
Merge pull request #540 from yuriks/multi-archives
FS: Allow multiple instances of the same archive type to be open at once
Diffstat (limited to 'src/core/file_sys')
| -rw-r--r-- | src/core/file_sys/archive_backend.h | 39 | ||||
| -rw-r--r-- | src/core/file_sys/archive_extsavedata.cpp | 15 | ||||
| -rw-r--r-- | src/core/file_sys/archive_extsavedata.h | 21 | ||||
| -rw-r--r-- | src/core/file_sys/archive_romfs.cpp | 17 | ||||
| -rw-r--r-- | src/core/file_sys/archive_romfs.h | 11 | ||||
| -rw-r--r-- | src/core/file_sys/archive_savedata.cpp | 23 | ||||
| -rw-r--r-- | src/core/file_sys/archive_savedata.h | 17 | ||||
| -rw-r--r-- | src/core/file_sys/archive_savedatacheck.cpp | 28 | ||||
| -rw-r--r-- | src/core/file_sys/archive_savedatacheck.h | 8 | ||||
| -rw-r--r-- | src/core/file_sys/archive_sdmc.cpp | 17 | ||||
| -rw-r--r-- | src/core/file_sys/archive_sdmc.h | 10 | ||||
| -rw-r--r-- | src/core/file_sys/disk_archive.cpp | 26 | ||||
| -rw-r--r-- | src/core/file_sys/disk_archive.h | 25 | ||||
| -rw-r--r-- | src/core/file_sys/ivfc_archive.cpp | 22 | ||||
| -rw-r--r-- | src/core/file_sys/ivfc_archive.h | 13 |
15 files changed, 163 insertions, 129 deletions
diff --git a/src/core/file_sys/archive_backend.h b/src/core/file_sys/archive_backend.h index 390178f67..43a106549 100644 --- a/src/core/file_sys/archive_backend.h +++ b/src/core/file_sys/archive_backend.h | |||
| @@ -181,20 +181,6 @@ public: | |||
| 181 | } | 181 | } |
| 182 | 182 | ||
| 183 | /** | 183 | /** |
| 184 | * Tries to open the archive of this type with the specified path | ||
| 185 | * @param path Path to the archive | ||
| 186 | * @return ResultCode of the operation | ||
| 187 | */ | ||
| 188 | virtual ResultCode Open(const Path& path) = 0; | ||
| 189 | |||
| 190 | /** | ||
| 191 | * Deletes the archive contents and then re-creates the base folder | ||
| 192 | * @param path Path to the archive | ||
| 193 | * @return ResultCode of the operation, 0 on success | ||
| 194 | */ | ||
| 195 | virtual ResultCode Format(const Path& path) const = 0; | ||
| 196 | |||
| 197 | /** | ||
| 198 | * Get a descriptive name for the archive (e.g. "RomFS", "SaveData", etc.) | 184 | * Get a descriptive name for the archive (e.g. "RomFS", "SaveData", etc.) |
| 199 | */ | 185 | */ |
| 200 | virtual std::string GetName() const = 0; | 186 | virtual std::string GetName() const = 0; |
| @@ -260,4 +246,29 @@ public: | |||
| 260 | virtual std::unique_ptr<DirectoryBackend> OpenDirectory(const Path& path) const = 0; | 246 | virtual std::unique_ptr<DirectoryBackend> OpenDirectory(const Path& path) const = 0; |
| 261 | }; | 247 | }; |
| 262 | 248 | ||
| 249 | class ArchiveFactory : NonCopyable { | ||
| 250 | public: | ||
| 251 | virtual ~ArchiveFactory() { | ||
| 252 | } | ||
| 253 | |||
| 254 | /** | ||
| 255 | * Get a descriptive name for the archive (e.g. "RomFS", "SaveData", etc.) | ||
| 256 | */ | ||
| 257 | virtual std::string GetName() const = 0; | ||
| 258 | |||
| 259 | /** | ||
| 260 | * Tries to open the archive of this type with the specified path | ||
| 261 | * @param path Path to the archive | ||
| 262 | * @return An ArchiveBackend corresponding operating specified archive path. | ||
| 263 | */ | ||
| 264 | virtual ResultVal<std::unique_ptr<ArchiveBackend>> Open(const Path& path) = 0; | ||
| 265 | |||
| 266 | /** | ||
| 267 | * Deletes the archive contents and then re-creates the base folder | ||
| 268 | * @param path Path to the archive | ||
| 269 | * @return ResultCode of the operation, 0 on success | ||
| 270 | */ | ||
| 271 | virtual ResultCode Format(const Path& path) = 0; | ||
| 272 | }; | ||
| 273 | |||
| 263 | } // namespace FileSys | 274 | } // namespace FileSys |
diff --git a/src/core/file_sys/archive_extsavedata.cpp b/src/core/file_sys/archive_extsavedata.cpp index 33e4e76f8..0363c9771 100644 --- a/src/core/file_sys/archive_extsavedata.cpp +++ b/src/core/file_sys/archive_extsavedata.cpp | |||
| @@ -6,6 +6,7 @@ | |||
| 6 | 6 | ||
| 7 | #include "common/common_types.h" | 7 | #include "common/common_types.h" |
| 8 | #include "common/file_util.h" | 8 | #include "common/file_util.h" |
| 9 | #include "common/make_unique.h" | ||
| 9 | 10 | ||
| 10 | #include "core/file_sys/archive_extsavedata.h" | 11 | #include "core/file_sys/archive_extsavedata.h" |
| 11 | #include "core/file_sys/disk_archive.h" | 12 | #include "core/file_sys/disk_archive.h" |
| @@ -33,12 +34,12 @@ std::string GetExtDataContainerPath(const std::string& mount_point, bool shared) | |||
| 33 | SYSTEM_ID.c_str(), SDCARD_ID.c_str()); | 34 | SYSTEM_ID.c_str(), SDCARD_ID.c_str()); |
| 34 | } | 35 | } |
| 35 | 36 | ||
| 36 | Archive_ExtSaveData::Archive_ExtSaveData(const std::string& mount_location, bool shared) | 37 | ArchiveFactory_ExtSaveData::ArchiveFactory_ExtSaveData(const std::string& mount_location, bool shared) |
| 37 | : DiskArchive(GetExtDataContainerPath(mount_location, shared)) { | 38 | : mount_point(GetExtDataContainerPath(mount_location, shared)) { |
| 38 | LOG_INFO(Service_FS, "Directory %s set as base for ExtSaveData.", mount_point.c_str()); | 39 | LOG_INFO(Service_FS, "Directory %s set as base for ExtSaveData.", mount_point.c_str()); |
| 39 | } | 40 | } |
| 40 | 41 | ||
| 41 | bool Archive_ExtSaveData::Initialize() { | 42 | bool ArchiveFactory_ExtSaveData::Initialize() { |
| 42 | if (!FileUtil::CreateFullPath(mount_point)) { | 43 | if (!FileUtil::CreateFullPath(mount_point)) { |
| 43 | LOG_ERROR(Service_FS, "Unable to create ExtSaveData base path."); | 44 | LOG_ERROR(Service_FS, "Unable to create ExtSaveData base path."); |
| 44 | return false; | 45 | return false; |
| @@ -47,18 +48,18 @@ bool Archive_ExtSaveData::Initialize() { | |||
| 47 | return true; | 48 | return true; |
| 48 | } | 49 | } |
| 49 | 50 | ||
| 50 | ResultCode Archive_ExtSaveData::Open(const Path& path) { | 51 | ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_ExtSaveData::Open(const Path& path) { |
| 51 | std::string fullpath = GetExtSaveDataPath(mount_point, path); | 52 | std::string fullpath = GetExtSaveDataPath(mount_point, path); |
| 52 | if (!FileUtil::Exists(fullpath)) { | 53 | if (!FileUtil::Exists(fullpath)) { |
| 53 | // TODO(Subv): Check error code, this one is probably wrong | 54 | // TODO(Subv): Check error code, this one is probably wrong |
| 54 | return ResultCode(ErrorDescription::FS_NotFormatted, ErrorModule::FS, | 55 | return ResultCode(ErrorDescription::FS_NotFormatted, ErrorModule::FS, |
| 55 | ErrorSummary::InvalidState, ErrorLevel::Status); | 56 | ErrorSummary::InvalidState, ErrorLevel::Status); |
| 56 | } | 57 | } |
| 57 | concrete_mount_point = fullpath; | 58 | auto archive = Common::make_unique<DiskArchive>(fullpath); |
| 58 | return RESULT_SUCCESS; | 59 | return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive)); |
| 59 | } | 60 | } |
| 60 | 61 | ||
| 61 | ResultCode Archive_ExtSaveData::Format(const Path& path) const { | 62 | ResultCode ArchiveFactory_ExtSaveData::Format(const Path& path) { |
| 62 | std::string fullpath = GetExtSaveDataPath(mount_point, path); | 63 | std::string fullpath = GetExtSaveDataPath(mount_point, path); |
| 63 | FileUtil::CreateFullPath(fullpath); | 64 | FileUtil::CreateFullPath(fullpath); |
| 64 | return RESULT_SUCCESS; | 65 | return RESULT_SUCCESS; |
diff --git a/src/core/file_sys/archive_extsavedata.h b/src/core/file_sys/archive_extsavedata.h index 802a11b5f..83c6b0291 100644 --- a/src/core/file_sys/archive_extsavedata.h +++ b/src/core/file_sys/archive_extsavedata.h | |||
| @@ -15,9 +15,9 @@ | |||
| 15 | namespace FileSys { | 15 | namespace FileSys { |
| 16 | 16 | ||
| 17 | /// File system interface to the ExtSaveData archive | 17 | /// File system interface to the ExtSaveData archive |
| 18 | class Archive_ExtSaveData final : public DiskArchive { | 18 | class ArchiveFactory_ExtSaveData final : public ArchiveFactory { |
| 19 | public: | 19 | public: |
| 20 | Archive_ExtSaveData(const std::string& mount_point, bool shared); | 20 | ArchiveFactory_ExtSaveData(const std::string& mount_point, bool shared); |
| 21 | 21 | ||
| 22 | /** | 22 | /** |
| 23 | * Initialize the archive. | 23 | * Initialize the archive. |
| @@ -25,21 +25,20 @@ public: | |||
| 25 | */ | 25 | */ |
| 26 | bool Initialize(); | 26 | bool Initialize(); |
| 27 | 27 | ||
| 28 | ResultCode Open(const Path& path) override; | ||
| 29 | ResultCode Format(const Path& path) const override; | ||
| 30 | std::string GetName() const override { return "ExtSaveData"; } | 28 | std::string GetName() const override { return "ExtSaveData"; } |
| 31 | 29 | ||
| 32 | const std::string& GetMountPoint() const override { | 30 | ResultVal<std::unique_ptr<ArchiveBackend>> Open(const Path& path) override; |
| 33 | return concrete_mount_point; | 31 | ResultCode Format(const Path& path) override; |
| 34 | } | ||
| 35 | 32 | ||
| 36 | protected: | 33 | const std::string& GetMountPoint() const { return mount_point; } |
| 34 | |||
| 35 | private: | ||
| 37 | /** | 36 | /** |
| 38 | * This holds the full directory path for this archive, it is only set after a successful call to Open, | 37 | * This holds the full directory path for this archive, it is only set after a successful call |
| 39 | * this is formed as <base extsavedatapath>/<type>/<high>/<low>. | 38 | * to Open, this is formed as <base extsavedatapath>/<type>/<high>/<low>. |
| 40 | * See GetExtSaveDataPath for the code that extracts this data from an archive path. | 39 | * See GetExtSaveDataPath for the code that extracts this data from an archive path. |
| 41 | */ | 40 | */ |
| 42 | std::string concrete_mount_point; | 41 | std::string mount_point; |
| 43 | }; | 42 | }; |
| 44 | 43 | ||
| 45 | /** | 44 | /** |
diff --git a/src/core/file_sys/archive_romfs.cpp b/src/core/file_sys/archive_romfs.cpp index a30f73d0e..bf54a3866 100644 --- a/src/core/file_sys/archive_romfs.cpp +++ b/src/core/file_sys/archive_romfs.cpp | |||
| @@ -15,11 +15,24 @@ | |||
| 15 | 15 | ||
| 16 | namespace FileSys { | 16 | namespace FileSys { |
| 17 | 17 | ||
| 18 | Archive_RomFS::Archive_RomFS(const Loader::AppLoader& app_loader) { | 18 | ArchiveFactory_RomFS::ArchiveFactory_RomFS(const Loader::AppLoader& app_loader) |
| 19 | : romfs_data(std::make_shared<std::vector<u8>>()) { | ||
| 19 | // Load the RomFS from the app | 20 | // Load the RomFS from the app |
| 20 | if (Loader::ResultStatus::Success != app_loader.ReadRomFS(raw_data)) { | 21 | if (Loader::ResultStatus::Success != app_loader.ReadRomFS(*romfs_data)) { |
| 21 | LOG_ERROR(Service_FS, "Unable to read RomFS!"); | 22 | LOG_ERROR(Service_FS, "Unable to read RomFS!"); |
| 22 | } | 23 | } |
| 23 | } | 24 | } |
| 24 | 25 | ||
| 26 | ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_RomFS::Open(const Path& path) { | ||
| 27 | auto archive = Common::make_unique<IVFCArchive>(romfs_data); | ||
| 28 | return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive)); | ||
| 29 | } | ||
| 30 | |||
| 31 | ResultCode ArchiveFactory_RomFS::Format(const Path& path) { | ||
| 32 | LOG_ERROR(Service_FS, "Attempted to format a RomFS archive."); | ||
| 33 | // TODO: Verify error code | ||
| 34 | return ResultCode(ErrorDescription::NotAuthorized, ErrorModule::FS, | ||
| 35 | ErrorSummary::NotSupported, ErrorLevel::Permanent); | ||
| 36 | } | ||
| 37 | |||
| 25 | } // namespace FileSys | 38 | } // namespace FileSys |
diff --git a/src/core/file_sys/archive_romfs.h b/src/core/file_sys/archive_romfs.h index 5cb75e04d..409bc670a 100644 --- a/src/core/file_sys/archive_romfs.h +++ b/src/core/file_sys/archive_romfs.h | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <memory> | ||
| 7 | #include <vector> | 8 | #include <vector> |
| 8 | 9 | ||
| 9 | #include "common/common_types.h" | 10 | #include "common/common_types.h" |
| @@ -17,12 +18,16 @@ | |||
| 17 | namespace FileSys { | 18 | namespace FileSys { |
| 18 | 19 | ||
| 19 | /// File system interface to the RomFS archive | 20 | /// File system interface to the RomFS archive |
| 20 | class Archive_RomFS final : public IVFCArchive { | 21 | class ArchiveFactory_RomFS final : public ArchiveFactory { |
| 21 | public: | 22 | public: |
| 22 | Archive_RomFS(const Loader::AppLoader& app_loader); | 23 | ArchiveFactory_RomFS(const Loader::AppLoader& app_loader); |
| 23 | 24 | ||
| 24 | std::string GetName() const override { return "RomFS"; } | 25 | std::string GetName() const override { return "RomFS"; } |
| 25 | ResultCode Open(const Path& path) override { return RESULT_SUCCESS; } | 26 | ResultVal<std::unique_ptr<ArchiveBackend>> Open(const Path& path) override; |
| 27 | ResultCode Format(const Path& path) override; | ||
| 28 | |||
| 29 | private: | ||
| 30 | std::shared_ptr<std::vector<u8>> romfs_data; | ||
| 26 | }; | 31 | }; |
| 27 | 32 | ||
| 28 | } // namespace FileSys | 33 | } // namespace FileSys |
diff --git a/src/core/file_sys/archive_savedata.cpp b/src/core/file_sys/archive_savedata.cpp index 3baee5294..8496e06f3 100644 --- a/src/core/file_sys/archive_savedata.cpp +++ b/src/core/file_sys/archive_savedata.cpp | |||
| @@ -6,6 +6,7 @@ | |||
| 6 | 6 | ||
| 7 | #include "common/common_types.h" | 7 | #include "common/common_types.h" |
| 8 | #include "common/file_util.h" | 8 | #include "common/file_util.h" |
| 9 | #include "common/make_unique.h" | ||
| 9 | 10 | ||
| 10 | #include "core/file_sys/archive_savedata.h" | 11 | #include "core/file_sys/archive_savedata.h" |
| 11 | #include "core/file_sys/disk_archive.h" | 12 | #include "core/file_sys/disk_archive.h" |
| @@ -28,26 +29,28 @@ static std::string GetSaveDataPath(const std::string& mount_location, u64 progra | |||
| 28 | return Common::StringFromFormat("%s%08x/%08x/data/00000001/", mount_location.c_str(), high, low); | 29 | return Common::StringFromFormat("%s%08x/%08x/data/00000001/", mount_location.c_str(), high, low); |
| 29 | } | 30 | } |
| 30 | 31 | ||
| 31 | Archive_SaveData::Archive_SaveData(const std::string& sdmc_directory) | 32 | ArchiveFactory_SaveData::ArchiveFactory_SaveData(const std::string& sdmc_directory) |
| 32 | : DiskArchive(GetSaveDataContainerPath(sdmc_directory)) { | 33 | : mount_point(GetSaveDataContainerPath(sdmc_directory)) { |
| 33 | LOG_INFO(Service_FS, "Directory %s set as SaveData.", this->mount_point.c_str()); | 34 | LOG_INFO(Service_FS, "Directory %s set as SaveData.", this->mount_point.c_str()); |
| 34 | } | 35 | } |
| 35 | 36 | ||
| 36 | ResultCode Archive_SaveData::Open(const Path& path) { | 37 | ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_SaveData::Open(const Path& path) { |
| 37 | if (concrete_mount_point.empty()) | 38 | std::string concrete_mount_point = GetSaveDataPath(mount_point, Kernel::g_program_id); |
| 38 | concrete_mount_point = GetSaveDataPath(mount_point, Kernel::g_program_id); | ||
| 39 | if (!FileUtil::Exists(concrete_mount_point)) { | 39 | if (!FileUtil::Exists(concrete_mount_point)) { |
| 40 | // When a SaveData archive is created for the first time, it is not yet formatted | 40 | // When a SaveData archive is created for the first time, it is not yet formatted |
| 41 | // and the save file/directory structure expected by the game has not yet been initialized. | 41 | // and the save file/directory structure expected by the game has not yet been initialized. |
| 42 | // Returning the NotFormatted error code will signal the game to provision the SaveData archive | 42 | // Returning the NotFormatted error code will signal the game to provision the SaveData archive |
| 43 | // with the files and folders that it expects. | 43 | // with the files and folders that it expects. |
| 44 | return ResultCode(ErrorDescription::FS_NotFormatted, ErrorModule::FS, | 44 | return ResultCode(ErrorDescription::FS_NotFormatted, ErrorModule::FS, |
| 45 | ErrorSummary::InvalidState, ErrorLevel::Status); | 45 | ErrorSummary::InvalidState, ErrorLevel::Status); |
| 46 | } | 46 | } |
| 47 | return RESULT_SUCCESS; | 47 | |
| 48 | auto archive = Common::make_unique<DiskArchive>(std::move(concrete_mount_point)); | ||
| 49 | return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive)); | ||
| 48 | } | 50 | } |
| 49 | 51 | ||
| 50 | ResultCode Archive_SaveData::Format(const Path& path) const { | 52 | ResultCode ArchiveFactory_SaveData::Format(const Path& path) { |
| 53 | std::string concrete_mount_point = GetSaveDataPath(mount_point, Kernel::g_program_id); | ||
| 51 | FileUtil::DeleteDirRecursively(concrete_mount_point); | 54 | FileUtil::DeleteDirRecursively(concrete_mount_point); |
| 52 | FileUtil::CreateFullPath(concrete_mount_point); | 55 | FileUtil::CreateFullPath(concrete_mount_point); |
| 53 | return RESULT_SUCCESS; | 56 | return RESULT_SUCCESS; |
diff --git a/src/core/file_sys/archive_savedata.h b/src/core/file_sys/archive_savedata.h index 07c7f7eff..db17afc92 100644 --- a/src/core/file_sys/archive_savedata.h +++ b/src/core/file_sys/archive_savedata.h | |||
| @@ -15,22 +15,17 @@ | |||
| 15 | namespace FileSys { | 15 | namespace FileSys { |
| 16 | 16 | ||
| 17 | /// File system interface to the SaveData archive | 17 | /// File system interface to the SaveData archive |
| 18 | class Archive_SaveData final : public DiskArchive { | 18 | class ArchiveFactory_SaveData final : public ArchiveFactory { |
| 19 | public: | 19 | public: |
| 20 | Archive_SaveData(const std::string& mount_point); | 20 | ArchiveFactory_SaveData(const std::string& mount_point); |
| 21 | 21 | ||
| 22 | std::string GetName() const override { return "SaveData"; } | 22 | std::string GetName() const override { return "SaveData"; } |
| 23 | 23 | ||
| 24 | ResultCode Open(const Path& path) override; | 24 | ResultVal<std::unique_ptr<ArchiveBackend>> Open(const Path& path) override; |
| 25 | ResultCode Format(const Path& path) override; | ||
| 25 | 26 | ||
| 26 | ResultCode Format(const Path& path) const override; | 27 | private: |
| 27 | 28 | std::string mount_point; | |
| 28 | const std::string& GetMountPoint() const override { | ||
| 29 | return concrete_mount_point; | ||
| 30 | } | ||
| 31 | |||
| 32 | protected: | ||
| 33 | std::string concrete_mount_point; | ||
| 34 | }; | 29 | }; |
| 35 | 30 | ||
| 36 | } // namespace FileSys | 31 | } // namespace FileSys |
diff --git a/src/core/file_sys/archive_savedatacheck.cpp b/src/core/file_sys/archive_savedatacheck.cpp index a7a507536..47d8a9d25 100644 --- a/src/core/file_sys/archive_savedatacheck.cpp +++ b/src/core/file_sys/archive_savedatacheck.cpp | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include "common/file_util.h" | 5 | #include "common/file_util.h" |
| 6 | #include "common/make_unique.h" | ||
| 6 | 7 | ||
| 7 | #include "core/file_sys/archive_savedatacheck.h" | 8 | #include "core/file_sys/archive_savedatacheck.h" |
| 8 | #include "core/hle/service/fs/archive.h" | 9 | #include "core/hle/service/fs/archive.h" |
| @@ -21,32 +22,33 @@ static std::string GetSaveDataCheckPath(const std::string& mount_point, u32 high | |||
| 21 | mount_point.c_str(), high, low); | 22 | mount_point.c_str(), high, low); |
| 22 | } | 23 | } |
| 23 | 24 | ||
| 24 | Archive_SaveDataCheck::Archive_SaveDataCheck(const std::string& nand_directory) : | 25 | ArchiveFactory_SaveDataCheck::ArchiveFactory_SaveDataCheck(const std::string& nand_directory) : |
| 25 | mount_point(GetSaveDataCheckContainerPath(nand_directory)) { | 26 | mount_point(GetSaveDataCheckContainerPath(nand_directory)) { |
| 26 | } | 27 | } |
| 27 | 28 | ||
| 28 | ResultCode Archive_SaveDataCheck::Open(const Path& path) { | 29 | ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_SaveDataCheck::Open(const Path& path) { |
| 29 | // TODO(Subv): We should not be overwriting raw_data everytime this function is called, | ||
| 30 | // but until we use factory classes to create the archives at runtime instead of creating them beforehand | ||
| 31 | // and allow multiple archives of the same type to be open at the same time without clobbering each other, | ||
| 32 | // we won't be able to maintain the state of each archive, hence we overwrite it every time it's needed. | ||
| 33 | // There are a number of problems with this, for example opening a file in this archive, then opening | ||
| 34 | // this archive again with a different path, will corrupt the previously open file. | ||
| 35 | auto vec = path.AsBinary(); | 30 | auto vec = path.AsBinary(); |
| 36 | const u32* data = reinterpret_cast<u32*>(vec.data()); | 31 | const u32* data = reinterpret_cast<u32*>(vec.data()); |
| 37 | std::string file_path = GetSaveDataCheckPath(mount_point, data[1], data[0]); | 32 | std::string file_path = GetSaveDataCheckPath(mount_point, data[1], data[0]); |
| 38 | FileUtil::IOFile file(file_path, "rb"); | 33 | FileUtil::IOFile file(file_path, "rb"); |
| 39 | 34 | ||
| 40 | std::fill(raw_data.begin(), raw_data.end(), 0); | ||
| 41 | |||
| 42 | if (!file.IsOpen()) { | 35 | if (!file.IsOpen()) { |
| 43 | return ResultCode(-1); // TODO(Subv): Find the right error code | 36 | return ResultCode(-1); // TODO(Subv): Find the right error code |
| 44 | } | 37 | } |
| 45 | auto size = file.GetSize(); | 38 | auto size = file.GetSize(); |
| 46 | raw_data.resize(size); | 39 | auto raw_data = std::make_shared<std::vector<u8>>(size); |
| 47 | file.ReadBytes(raw_data.data(), size); | 40 | file.ReadBytes(raw_data->data(), size); |
| 48 | file.Close(); | 41 | file.Close(); |
| 49 | return RESULT_SUCCESS; | 42 | |
| 43 | auto archive = Common::make_unique<IVFCArchive>(std::move(raw_data)); | ||
| 44 | return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive)); | ||
| 45 | } | ||
| 46 | |||
| 47 | ResultCode ArchiveFactory_SaveDataCheck::Format(const Path& path) { | ||
| 48 | LOG_ERROR(Service_FS, "Attempted to format a SaveDataCheck archive."); | ||
| 49 | // TODO: Verify error code | ||
| 50 | return ResultCode(ErrorDescription::NotAuthorized, ErrorModule::FS, | ||
| 51 | ErrorSummary::NotSupported, ErrorLevel::Permanent); | ||
| 50 | } | 52 | } |
| 51 | 53 | ||
| 52 | } // namespace FileSys | 54 | } // namespace FileSys |
diff --git a/src/core/file_sys/archive_savedatacheck.h b/src/core/file_sys/archive_savedatacheck.h index f6e73e803..f78a6f02e 100644 --- a/src/core/file_sys/archive_savedatacheck.h +++ b/src/core/file_sys/archive_savedatacheck.h | |||
| @@ -17,12 +17,14 @@ | |||
| 17 | namespace FileSys { | 17 | namespace FileSys { |
| 18 | 18 | ||
| 19 | /// File system interface to the SaveDataCheck archive | 19 | /// File system interface to the SaveDataCheck archive |
| 20 | class Archive_SaveDataCheck final : public IVFCArchive { | 20 | class ArchiveFactory_SaveDataCheck final : public ArchiveFactory { |
| 21 | public: | 21 | public: |
| 22 | Archive_SaveDataCheck(const std::string& mount_point); | 22 | ArchiveFactory_SaveDataCheck(const std::string& mount_point); |
| 23 | 23 | ||
| 24 | std::string GetName() const override { return "SaveDataCheck"; } | 24 | std::string GetName() const override { return "SaveDataCheck"; } |
| 25 | ResultCode Open(const Path& path) override; | 25 | |
| 26 | ResultVal<std::unique_ptr<ArchiveBackend>> Open(const Path& path) override; | ||
| 27 | ResultCode Format(const Path& path) override; | ||
| 26 | 28 | ||
| 27 | private: | 29 | private: |
| 28 | std::string mount_point; | 30 | std::string mount_point; |
diff --git a/src/core/file_sys/archive_sdmc.cpp b/src/core/file_sys/archive_sdmc.cpp index 26b03e82f..92b20c7f6 100644 --- a/src/core/file_sys/archive_sdmc.cpp +++ b/src/core/file_sys/archive_sdmc.cpp | |||
| @@ -6,6 +6,7 @@ | |||
| 6 | 6 | ||
| 7 | #include "common/common_types.h" | 7 | #include "common/common_types.h" |
| 8 | #include "common/file_util.h" | 8 | #include "common/file_util.h" |
| 9 | #include "common/make_unique.h" | ||
| 9 | 10 | ||
| 10 | #include "core/file_sys/archive_sdmc.h" | 11 | #include "core/file_sys/archive_sdmc.h" |
| 11 | #include "core/file_sys/disk_archive.h" | 12 | #include "core/file_sys/disk_archive.h" |
| @@ -16,17 +17,17 @@ | |||
| 16 | 17 | ||
| 17 | namespace FileSys { | 18 | namespace FileSys { |
| 18 | 19 | ||
| 19 | Archive_SDMC::Archive_SDMC(const std::string& sdmc_directory) : DiskArchive(sdmc_directory) { | 20 | ArchiveFactory_SDMC::ArchiveFactory_SDMC(const std::string& sdmc_directory) : sdmc_directory(sdmc_directory) { |
| 20 | LOG_INFO(Service_FS, "Directory %s set as SDMC.", sdmc_directory.c_str()); | 21 | LOG_INFO(Service_FS, "Directory %s set as SDMC.", sdmc_directory.c_str()); |
| 21 | } | 22 | } |
| 22 | 23 | ||
| 23 | bool Archive_SDMC::Initialize() { | 24 | bool ArchiveFactory_SDMC::Initialize() { |
| 24 | if (!Settings::values.use_virtual_sd) { | 25 | if (!Settings::values.use_virtual_sd) { |
| 25 | LOG_WARNING(Service_FS, "SDMC disabled by config."); | 26 | LOG_WARNING(Service_FS, "SDMC disabled by config."); |
| 26 | return false; | 27 | return false; |
| 27 | } | 28 | } |
| 28 | 29 | ||
| 29 | if (!FileUtil::CreateFullPath(mount_point)) { | 30 | if (!FileUtil::CreateFullPath(sdmc_directory)) { |
| 30 | LOG_ERROR(Service_FS, "Unable to create SDMC path."); | 31 | LOG_ERROR(Service_FS, "Unable to create SDMC path."); |
| 31 | return false; | 32 | return false; |
| 32 | } | 33 | } |
| @@ -34,4 +35,14 @@ bool Archive_SDMC::Initialize() { | |||
| 34 | return true; | 35 | return true; |
| 35 | } | 36 | } |
| 36 | 37 | ||
| 38 | ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_SDMC::Open(const Path& path) { | ||
| 39 | auto archive = Common::make_unique<DiskArchive>(sdmc_directory); | ||
| 40 | return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive)); | ||
| 41 | } | ||
| 42 | |||
| 43 | ResultCode ArchiveFactory_SDMC::Format(const Path& path) { | ||
| 44 | // This is kind of an undesirable operation, so let's just ignore it. :) | ||
| 45 | return RESULT_SUCCESS; | ||
| 46 | } | ||
| 47 | |||
| 37 | } // namespace FileSys | 48 | } // namespace FileSys |
diff --git a/src/core/file_sys/archive_sdmc.h b/src/core/file_sys/archive_sdmc.h index 1b801f217..1becf6c0f 100644 --- a/src/core/file_sys/archive_sdmc.h +++ b/src/core/file_sys/archive_sdmc.h | |||
| @@ -15,9 +15,9 @@ | |||
| 15 | namespace FileSys { | 15 | namespace FileSys { |
| 16 | 16 | ||
| 17 | /// File system interface to the SDMC archive | 17 | /// File system interface to the SDMC archive |
| 18 | class Archive_SDMC final : public DiskArchive { | 18 | class ArchiveFactory_SDMC final : public ArchiveFactory { |
| 19 | public: | 19 | public: |
| 20 | Archive_SDMC(const std::string& mount_point); | 20 | ArchiveFactory_SDMC(const std::string& mount_point); |
| 21 | 21 | ||
| 22 | /** | 22 | /** |
| 23 | * Initialize the archive. | 23 | * Initialize the archive. |
| @@ -26,6 +26,12 @@ public: | |||
| 26 | bool Initialize(); | 26 | bool Initialize(); |
| 27 | 27 | ||
| 28 | std::string GetName() const override { return "SDMC"; } | 28 | std::string GetName() const override { return "SDMC"; } |
| 29 | |||
| 30 | ResultVal<std::unique_ptr<ArchiveBackend>> Open(const Path& path) override; | ||
| 31 | ResultCode Format(const Path& path) override; | ||
| 32 | |||
| 33 | private: | ||
| 34 | std::string sdmc_directory; | ||
| 29 | }; | 35 | }; |
| 30 | 36 | ||
| 31 | } // namespace FileSys | 37 | } // namespace FileSys |
diff --git a/src/core/file_sys/disk_archive.cpp b/src/core/file_sys/disk_archive.cpp index c6e033fcd..f53fd57db 100644 --- a/src/core/file_sys/disk_archive.cpp +++ b/src/core/file_sys/disk_archive.cpp | |||
| @@ -18,26 +18,26 @@ namespace FileSys { | |||
| 18 | 18 | ||
| 19 | std::unique_ptr<FileBackend> DiskArchive::OpenFile(const Path& path, const Mode mode) const { | 19 | std::unique_ptr<FileBackend> DiskArchive::OpenFile(const Path& path, const Mode mode) const { |
| 20 | LOG_DEBUG(Service_FS, "called path=%s mode=%01X", path.DebugStr().c_str(), mode.hex); | 20 | LOG_DEBUG(Service_FS, "called path=%s mode=%01X", path.DebugStr().c_str(), mode.hex); |
| 21 | auto file = Common::make_unique<DiskFile>(this, path, mode); | 21 | auto file = Common::make_unique<DiskFile>(*this, path, mode); |
| 22 | if (!file->Open()) | 22 | if (!file->Open()) |
| 23 | return nullptr; | 23 | return nullptr; |
| 24 | return std::move(file); | 24 | return std::move(file); |
| 25 | } | 25 | } |
| 26 | 26 | ||
| 27 | bool DiskArchive::DeleteFile(const Path& path) const { | 27 | bool DiskArchive::DeleteFile(const Path& path) const { |
| 28 | return FileUtil::Delete(GetMountPoint() + path.AsString()); | 28 | return FileUtil::Delete(mount_point + path.AsString()); |
| 29 | } | 29 | } |
| 30 | 30 | ||
| 31 | bool DiskArchive::RenameFile(const Path& src_path, const Path& dest_path) const { | 31 | bool DiskArchive::RenameFile(const Path& src_path, const Path& dest_path) const { |
| 32 | return FileUtil::Rename(GetMountPoint() + src_path.AsString(), GetMountPoint() + dest_path.AsString()); | 32 | return FileUtil::Rename(mount_point + src_path.AsString(), mount_point + dest_path.AsString()); |
| 33 | } | 33 | } |
| 34 | 34 | ||
| 35 | bool DiskArchive::DeleteDirectory(const Path& path) const { | 35 | bool DiskArchive::DeleteDirectory(const Path& path) const { |
| 36 | return FileUtil::DeleteDir(GetMountPoint() + path.AsString()); | 36 | return FileUtil::DeleteDir(mount_point + path.AsString()); |
| 37 | } | 37 | } |
| 38 | 38 | ||
| 39 | ResultCode DiskArchive::CreateFile(const FileSys::Path& path, u32 size) const { | 39 | ResultCode DiskArchive::CreateFile(const FileSys::Path& path, u32 size) const { |
| 40 | std::string full_path = GetMountPoint() + path.AsString(); | 40 | std::string full_path = mount_point + path.AsString(); |
| 41 | 41 | ||
| 42 | if (FileUtil::Exists(full_path)) | 42 | if (FileUtil::Exists(full_path)) |
| 43 | return ResultCode(ErrorDescription::AlreadyExists, ErrorModule::FS, ErrorSummary::NothingHappened, ErrorLevel::Info); | 43 | return ResultCode(ErrorDescription::AlreadyExists, ErrorModule::FS, ErrorSummary::NothingHappened, ErrorLevel::Info); |
| @@ -58,16 +58,16 @@ ResultCode DiskArchive::CreateFile(const FileSys::Path& path, u32 size) const { | |||
| 58 | 58 | ||
| 59 | 59 | ||
| 60 | bool DiskArchive::CreateDirectory(const Path& path) const { | 60 | bool DiskArchive::CreateDirectory(const Path& path) const { |
| 61 | return FileUtil::CreateDir(GetMountPoint() + path.AsString()); | 61 | return FileUtil::CreateDir(mount_point + path.AsString()); |
| 62 | } | 62 | } |
| 63 | 63 | ||
| 64 | bool DiskArchive::RenameDirectory(const Path& src_path, const Path& dest_path) const { | 64 | bool DiskArchive::RenameDirectory(const Path& src_path, const Path& dest_path) const { |
| 65 | return FileUtil::Rename(GetMountPoint() + src_path.AsString(), GetMountPoint() + dest_path.AsString()); | 65 | return FileUtil::Rename(mount_point + src_path.AsString(), mount_point + dest_path.AsString()); |
| 66 | } | 66 | } |
| 67 | 67 | ||
| 68 | std::unique_ptr<DirectoryBackend> DiskArchive::OpenDirectory(const Path& path) const { | 68 | std::unique_ptr<DirectoryBackend> DiskArchive::OpenDirectory(const Path& path) const { |
| 69 | LOG_DEBUG(Service_FS, "called path=%s", path.DebugStr().c_str()); | 69 | LOG_DEBUG(Service_FS, "called path=%s", path.DebugStr().c_str()); |
| 70 | auto directory = Common::make_unique<DiskDirectory>(this, path); | 70 | auto directory = Common::make_unique<DiskDirectory>(*this, path); |
| 71 | if (!directory->Open()) | 71 | if (!directory->Open()) |
| 72 | return nullptr; | 72 | return nullptr; |
| 73 | return std::move(directory); | 73 | return std::move(directory); |
| @@ -75,13 +75,12 @@ std::unique_ptr<DirectoryBackend> DiskArchive::OpenDirectory(const Path& path) c | |||
| 75 | 75 | ||
| 76 | //////////////////////////////////////////////////////////////////////////////////////////////////// | 76 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
| 77 | 77 | ||
| 78 | DiskFile::DiskFile(const DiskArchive* archive, const Path& path, const Mode mode) { | 78 | DiskFile::DiskFile(const DiskArchive& archive, const Path& path, const Mode mode) { |
| 79 | // TODO(Link Mauve): normalize path into an absolute path without "..", it can currently bypass | 79 | // TODO(Link Mauve): normalize path into an absolute path without "..", it can currently bypass |
| 80 | // the root directory we set while opening the archive. | 80 | // the root directory we set while opening the archive. |
| 81 | // For example, opening /../../etc/passwd can give the emulated program your users list. | 81 | // For example, opening /../../etc/passwd can give the emulated program your users list. |
| 82 | this->path = archive->GetMountPoint() + path.AsString(); | 82 | this->path = archive.mount_point + path.AsString(); |
| 83 | this->mode.hex = mode.hex; | 83 | this->mode.hex = mode.hex; |
| 84 | this->archive = archive; | ||
| 85 | } | 84 | } |
| 86 | 85 | ||
| 87 | bool DiskFile::Open() { | 86 | bool DiskFile::Open() { |
| @@ -134,12 +133,11 @@ bool DiskFile::Close() const { | |||
| 134 | 133 | ||
| 135 | //////////////////////////////////////////////////////////////////////////////////////////////////// | 134 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
| 136 | 135 | ||
| 137 | DiskDirectory::DiskDirectory(const DiskArchive* archive, const Path& path) { | 136 | DiskDirectory::DiskDirectory(const DiskArchive& archive, const Path& path) { |
| 138 | // TODO(Link Mauve): normalize path into an absolute path without "..", it can currently bypass | 137 | // TODO(Link Mauve): normalize path into an absolute path without "..", it can currently bypass |
| 139 | // the root directory we set while opening the archive. | 138 | // the root directory we set while opening the archive. |
| 140 | // For example, opening /../../usr/bin can give the emulated program your installed programs. | 139 | // For example, opening /../../usr/bin can give the emulated program your installed programs. |
| 141 | this->path = archive->GetMountPoint() + path.AsString(); | 140 | this->path = archive.mount_point + path.AsString(); |
| 142 | this->archive = archive; | ||
| 143 | } | 141 | } |
| 144 | 142 | ||
| 145 | bool DiskDirectory::Open() { | 143 | bool DiskDirectory::Open() { |
diff --git a/src/core/file_sys/disk_archive.h b/src/core/file_sys/disk_archive.h index 3472f6874..dbbdced74 100644 --- a/src/core/file_sys/disk_archive.h +++ b/src/core/file_sys/disk_archive.h | |||
| @@ -24,8 +24,8 @@ class DiskArchive : public ArchiveBackend { | |||
| 24 | public: | 24 | public: |
| 25 | DiskArchive(const std::string& mount_point_) : mount_point(mount_point_) {} | 25 | DiskArchive(const std::string& mount_point_) : mount_point(mount_point_) {} |
| 26 | 26 | ||
| 27 | virtual std::string GetName() const = 0; | 27 | virtual std::string GetName() const { return "DiskArchive: " + mount_point; } |
| 28 | virtual ResultCode Format(const Path& path) const { return RESULT_SUCCESS; } | 28 | |
| 29 | std::unique_ptr<FileBackend> OpenFile(const Path& path, const Mode mode) const override; | 29 | std::unique_ptr<FileBackend> OpenFile(const Path& path, const Mode mode) const override; |
| 30 | bool DeleteFile(const Path& path) const override; | 30 | bool DeleteFile(const Path& path) const override; |
| 31 | bool RenameFile(const Path& src_path, const Path& dest_path) const override; | 31 | bool RenameFile(const Path& src_path, const Path& dest_path) const override; |
| @@ -35,26 +35,17 @@ public: | |||
| 35 | bool RenameDirectory(const Path& src_path, const Path& dest_path) const override; | 35 | bool RenameDirectory(const Path& src_path, const Path& dest_path) const override; |
| 36 | std::unique_ptr<DirectoryBackend> OpenDirectory(const Path& path) const override; | 36 | std::unique_ptr<DirectoryBackend> OpenDirectory(const Path& path) const override; |
| 37 | 37 | ||
| 38 | virtual ResultCode Open(const Path& path) override { | ||
| 39 | return RESULT_SUCCESS; | ||
| 40 | } | ||
| 41 | |||
| 42 | /** | ||
| 43 | * Getter for the path used for this Archive | ||
| 44 | * @return Mount point of that passthrough archive | ||
| 45 | */ | ||
| 46 | virtual const std::string& GetMountPoint() const { | ||
| 47 | return mount_point; | ||
| 48 | } | ||
| 49 | |||
| 50 | protected: | 38 | protected: |
| 39 | friend class DiskFile; | ||
| 40 | friend class DiskDirectory; | ||
| 41 | |||
| 51 | std::string mount_point; | 42 | std::string mount_point; |
| 52 | }; | 43 | }; |
| 53 | 44 | ||
| 54 | class DiskFile : public FileBackend { | 45 | class DiskFile : public FileBackend { |
| 55 | public: | 46 | public: |
| 56 | DiskFile(); | 47 | DiskFile(); |
| 57 | DiskFile(const DiskArchive* archive, const Path& path, const Mode mode); | 48 | DiskFile(const DiskArchive& archive, const Path& path, const Mode mode); |
| 58 | 49 | ||
| 59 | bool Open() override; | 50 | bool Open() override; |
| 60 | size_t Read(const u64 offset, const u32 length, u8* buffer) const override; | 51 | size_t Read(const u64 offset, const u32 length, u8* buffer) const override; |
| @@ -68,7 +59,6 @@ public: | |||
| 68 | } | 59 | } |
| 69 | 60 | ||
| 70 | protected: | 61 | protected: |
| 71 | const DiskArchive* archive; | ||
| 72 | std::string path; | 62 | std::string path; |
| 73 | Mode mode; | 63 | Mode mode; |
| 74 | std::unique_ptr<FileUtil::IOFile> file; | 64 | std::unique_ptr<FileUtil::IOFile> file; |
| @@ -77,7 +67,7 @@ protected: | |||
| 77 | class DiskDirectory : public DirectoryBackend { | 67 | class DiskDirectory : public DirectoryBackend { |
| 78 | public: | 68 | public: |
| 79 | DiskDirectory(); | 69 | DiskDirectory(); |
| 80 | DiskDirectory(const DiskArchive* archive, const Path& path); | 70 | DiskDirectory(const DiskArchive& archive, const Path& path); |
| 81 | 71 | ||
| 82 | ~DiskDirectory() override { | 72 | ~DiskDirectory() override { |
| 83 | Close(); | 73 | Close(); |
| @@ -91,7 +81,6 @@ public: | |||
| 91 | } | 81 | } |
| 92 | 82 | ||
| 93 | protected: | 83 | protected: |
| 94 | const DiskArchive* archive; | ||
| 95 | std::string path; | 84 | std::string path; |
| 96 | u32 total_entries_in_directory; | 85 | u32 total_entries_in_directory; |
| 97 | FileUtil::FSTEntry directory; | 86 | FileUtil::FSTEntry directory; |
diff --git a/src/core/file_sys/ivfc_archive.cpp b/src/core/file_sys/ivfc_archive.cpp index 68c3c8b81..35aca54fa 100644 --- a/src/core/file_sys/ivfc_archive.cpp +++ b/src/core/file_sys/ivfc_archive.cpp | |||
| @@ -15,11 +15,15 @@ | |||
| 15 | 15 | ||
| 16 | namespace FileSys { | 16 | namespace FileSys { |
| 17 | 17 | ||
| 18 | IVFCArchive::IVFCArchive() { | 18 | IVFCArchive::IVFCArchive(std::shared_ptr<const std::vector<u8>> data) : data(data) { |
| 19 | } | ||
| 20 | |||
| 21 | std::string IVFCArchive::GetName() const { | ||
| 22 | return "IVFC"; | ||
| 19 | } | 23 | } |
| 20 | 24 | ||
| 21 | std::unique_ptr<FileBackend> IVFCArchive::OpenFile(const Path& path, const Mode mode) const { | 25 | std::unique_ptr<FileBackend> IVFCArchive::OpenFile(const Path& path, const Mode mode) const { |
| 22 | return Common::make_unique<IVFCFile>(this); | 26 | return Common::make_unique<IVFCFile>(data); |
| 23 | } | 27 | } |
| 24 | 28 | ||
| 25 | bool IVFCArchive::DeleteFile(const Path& path) const { | 29 | bool IVFCArchive::DeleteFile(const Path& path) const { |
| @@ -57,31 +61,25 @@ std::unique_ptr<DirectoryBackend> IVFCArchive::OpenDirectory(const Path& path) c | |||
| 57 | return Common::make_unique<IVFCDirectory>(); | 61 | return Common::make_unique<IVFCDirectory>(); |
| 58 | } | 62 | } |
| 59 | 63 | ||
| 60 | ResultCode IVFCArchive::Format(const Path& path) const { | ||
| 61 | LOG_CRITICAL(Service_FS, "Attempted to format an IVFC archive (%s).", GetName().c_str()); | ||
| 62 | // TODO: Verify error code | ||
| 63 | return ResultCode(ErrorDescription::NotAuthorized, ErrorModule::FS, ErrorSummary::NotSupported, ErrorLevel::Permanent); | ||
| 64 | } | ||
| 65 | |||
| 66 | //////////////////////////////////////////////////////////////////////////////////////////////////// | 64 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
| 67 | 65 | ||
| 68 | size_t IVFCFile::Read(const u64 offset, const u32 length, u8* buffer) const { | 66 | size_t IVFCFile::Read(const u64 offset, const u32 length, u8* buffer) const { |
| 69 | LOG_TRACE(Service_FS, "called offset=%llu, length=%d", offset, length); | 67 | LOG_TRACE(Service_FS, "called offset=%llu, length=%d", offset, length); |
| 70 | memcpy(buffer, &archive->raw_data[(u32)offset], length); | 68 | memcpy(buffer, data->data() + offset, length); |
| 71 | return length; | 69 | return length; |
| 72 | } | 70 | } |
| 73 | 71 | ||
| 74 | size_t IVFCFile::Write(const u64 offset, const u32 length, const u32 flush, const u8* buffer) const { | 72 | size_t IVFCFile::Write(const u64 offset, const u32 length, const u32 flush, const u8* buffer) const { |
| 75 | LOG_CRITICAL(Service_FS, "Attempted to write to IVFC file in archive %s.", archive->GetName().c_str()); | 73 | LOG_ERROR(Service_FS, "Attempted to write to IVFC file"); |
| 76 | return 0; | 74 | return 0; |
| 77 | } | 75 | } |
| 78 | 76 | ||
| 79 | size_t IVFCFile::GetSize() const { | 77 | size_t IVFCFile::GetSize() const { |
| 80 | return sizeof(u8) * archive->raw_data.size(); | 78 | return sizeof(u8) * data->size(); |
| 81 | } | 79 | } |
| 82 | 80 | ||
| 83 | bool IVFCFile::SetSize(const u64 size) const { | 81 | bool IVFCFile::SetSize(const u64 size) const { |
| 84 | LOG_CRITICAL(Service_FS, "Attempted to set the size of an IVFC file in archive %s", archive->GetName().c_str()); | 82 | LOG_ERROR(Service_FS, "Attempted to set the size of an IVFC file"); |
| 85 | return false; | 83 | return false; |
| 86 | } | 84 | } |
| 87 | 85 | ||
diff --git a/src/core/file_sys/ivfc_archive.h b/src/core/file_sys/ivfc_archive.h index 6f4cc86df..1aff9e0a4 100644 --- a/src/core/file_sys/ivfc_archive.h +++ b/src/core/file_sys/ivfc_archive.h | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <memory> | ||
| 7 | #include <vector> | 8 | #include <vector> |
| 8 | 9 | ||
| 9 | #include "common/common_types.h" | 10 | #include "common/common_types.h" |
| @@ -23,7 +24,9 @@ namespace FileSys { | |||
| 23 | */ | 24 | */ |
| 24 | class IVFCArchive : public ArchiveBackend { | 25 | class IVFCArchive : public ArchiveBackend { |
| 25 | public: | 26 | public: |
| 26 | IVFCArchive(); | 27 | IVFCArchive(std::shared_ptr<const std::vector<u8>> data); |
| 28 | |||
| 29 | std::string GetName() const override; | ||
| 27 | 30 | ||
| 28 | std::unique_ptr<FileBackend> OpenFile(const Path& path, const Mode mode) const override; | 31 | std::unique_ptr<FileBackend> OpenFile(const Path& path, const Mode mode) const override; |
| 29 | bool DeleteFile(const Path& path) const override; | 32 | bool DeleteFile(const Path& path) const override; |
| @@ -33,16 +36,14 @@ public: | |||
| 33 | bool CreateDirectory(const Path& path) const override; | 36 | bool CreateDirectory(const Path& path) const override; |
| 34 | bool RenameDirectory(const Path& src_path, const Path& dest_path) const override; | 37 | bool RenameDirectory(const Path& src_path, const Path& dest_path) const override; |
| 35 | std::unique_ptr<DirectoryBackend> OpenDirectory(const Path& path) const override; | 38 | std::unique_ptr<DirectoryBackend> OpenDirectory(const Path& path) const override; |
| 36 | ResultCode Format(const Path& path) const override; | ||
| 37 | 39 | ||
| 38 | protected: | 40 | protected: |
| 39 | friend class IVFCFile; | 41 | std::shared_ptr<const std::vector<u8>> data; |
| 40 | std::vector<u8> raw_data; | ||
| 41 | }; | 42 | }; |
| 42 | 43 | ||
| 43 | class IVFCFile : public FileBackend { | 44 | class IVFCFile : public FileBackend { |
| 44 | public: | 45 | public: |
| 45 | IVFCFile(const IVFCArchive* archive) : archive(archive) {} | 46 | IVFCFile(std::shared_ptr<const std::vector<u8>> data) : data(data) {} |
| 46 | 47 | ||
| 47 | bool Open() override { return true; } | 48 | bool Open() override { return true; } |
| 48 | size_t Read(const u64 offset, const u32 length, u8* buffer) const override; | 49 | size_t Read(const u64 offset, const u32 length, u8* buffer) const override; |
| @@ -53,7 +54,7 @@ public: | |||
| 53 | void Flush() const override { } | 54 | void Flush() const override { } |
| 54 | 55 | ||
| 55 | private: | 56 | private: |
| 56 | const IVFCArchive* archive; | 57 | std::shared_ptr<const std::vector<u8>> data; |
| 57 | }; | 58 | }; |
| 58 | 59 | ||
| 59 | class IVFCDirectory : public DirectoryBackend { | 60 | class IVFCDirectory : public DirectoryBackend { |