diff options
Diffstat (limited to '')
-rw-r--r-- | src/core/file_sys/archive_backend.h | 18 | ||||
-rw-r--r-- | src/core/file_sys/archive_extsavedata.cpp | 36 | ||||
-rw-r--r-- | src/core/file_sys/archive_extsavedata.h | 11 | ||||
-rw-r--r-- | src/core/file_sys/archive_romfs.cpp | 8 | ||||
-rw-r--r-- | src/core/file_sys/archive_romfs.h | 3 | ||||
-rw-r--r-- | src/core/file_sys/archive_savedata.cpp | 32 | ||||
-rw-r--r-- | src/core/file_sys/archive_savedata.h | 4 | ||||
-rw-r--r-- | src/core/file_sys/archive_savedatacheck.cpp | 8 | ||||
-rw-r--r-- | src/core/file_sys/archive_savedatacheck.h | 3 | ||||
-rw-r--r-- | src/core/file_sys/archive_sdmc.cpp | 7 | ||||
-rw-r--r-- | src/core/file_sys/archive_sdmc.h | 3 | ||||
-rw-r--r-- | src/core/file_sys/archive_systemsavedata.cpp | 8 | ||||
-rw-r--r-- | src/core/file_sys/archive_systemsavedata.h | 3 |
13 files changed, 130 insertions, 14 deletions
diff --git a/src/core/file_sys/archive_backend.h b/src/core/file_sys/archive_backend.h index 60108b4b0..800ac1541 100644 --- a/src/core/file_sys/archive_backend.h +++ b/src/core/file_sys/archive_backend.h @@ -62,6 +62,14 @@ private: std::u16string u16str; }; +struct ArchiveFormatInfo { + u32 total_size; ///< The pre-defined size of the archive, as specified in the Create or Format call + u32 number_directories; ///< The pre-defined number of directories in the archive, as specified in the Create or Format call + u32 number_files; ///< The pre-defined number of files in the archive, as specified in the Create or Format call + u8 duplicate_data; ///< Whether the archive should duplicate the data, as specified in the Create or Format call +}; +static_assert(std::is_pod<ArchiveFormatInfo>::value, "ArchiveFormatInfo is not POD"); + class ArchiveBackend : NonCopyable { public: virtual ~ArchiveBackend() { @@ -159,9 +167,17 @@ public: /** * Deletes the archive contents and then re-creates the base folder * @param path Path to the archive + * @param format_info Format information for the new archive * @return ResultCode of the operation, 0 on success */ - virtual ResultCode Format(const Path& path) = 0; + virtual ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) = 0; + + /* + * Retrieves the format info about the archive with the specified path + * @param path Path to the archive + * @return Format information about the archive or error code + */ + virtual ResultVal<ArchiveFormatInfo> GetFormatInfo(const Path& path) const = 0; }; } // namespace FileSys diff --git a/src/core/file_sys/archive_extsavedata.cpp b/src/core/file_sys/archive_extsavedata.cpp index 92dad8e6f..e83a6153d 100644 --- a/src/core/file_sys/archive_extsavedata.cpp +++ b/src/core/file_sys/archive_extsavedata.cpp @@ -82,13 +82,45 @@ ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_ExtSaveData::Open(cons return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive)); } -ResultCode ArchiveFactory_ExtSaveData::Format(const Path& path) { +ResultCode ArchiveFactory_ExtSaveData::Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) { // These folders are always created with the ExtSaveData std::string user_path = GetExtSaveDataPath(mount_point, path) + "user/"; std::string boss_path = GetExtSaveDataPath(mount_point, path) + "boss/"; FileUtil::CreateFullPath(user_path); FileUtil::CreateFullPath(boss_path); - return RESULT_SUCCESS; + + // Write the format metadata + std::string metadata_path = GetExtSaveDataPath(mount_point, path) + "metadata"; + FileUtil::IOFile file(metadata_path, "wb"); + + if (file.IsOpen()) { + file.WriteBytes(&format_info, sizeof(format_info)); + return RESULT_SUCCESS; + } + + // TODO(Subv): Find the correct error code + return ResultCode(-1); +} + +ResultVal<ArchiveFormatInfo> ArchiveFactory_ExtSaveData::GetFormatInfo(const Path& path) const { + std::string metadata_path = GetExtSaveDataPath(mount_point, path) + "metadata"; + FileUtil::IOFile file(metadata_path, "rb"); + + if (file.IsOpen()) { + ArchiveFormatInfo info; + file.ReadBytes(&info, sizeof(info)); + return MakeResult<ArchiveFormatInfo>(info); + } + + LOG_ERROR(Service_FS, "Could not open metadata information for archive"); + // TODO(Subv): Verify error code + return ResultCode(ErrorDescription::FS_NotFormatted, ErrorModule::FS, ErrorSummary::InvalidState, ErrorLevel::Status); +} + +void ArchiveFactory_ExtSaveData::WriteIcon(const Path& path, u8* icon_data, u32 icon_size) { + std::string game_path = FileSys::GetExtSaveDataPath(GetMountPoint(), path); + FileUtil::IOFile icon_file(game_path + "icon", "wb+"); + icon_file.WriteBytes(icon_data, icon_size); } } // namespace FileSys diff --git a/src/core/file_sys/archive_extsavedata.h b/src/core/file_sys/archive_extsavedata.h index ec8d770fc..48e092ee7 100644 --- a/src/core/file_sys/archive_extsavedata.h +++ b/src/core/file_sys/archive_extsavedata.h @@ -31,10 +31,19 @@ public: std::string GetName() const override { return "ExtSaveData"; } ResultVal<std::unique_ptr<ArchiveBackend>> Open(const Path& path) override; - ResultCode Format(const Path& path) override; + ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) override; + ResultVal<ArchiveFormatInfo> GetFormatInfo(const Path& path) const override; const std::string& GetMountPoint() const { return mount_point; } + /* + * Writes the SMDH icon of the ExtSaveData to file + * @param path Path of this ExtSaveData + * @param icon_data Binary data of the icon + * @param icon_size Size of the icon data + */ + void WriteIcon(const Path& path, u8* icon_data, u32 icon_size); + private: /** * This holds the full directory path for this archive, it is only set after a successful call diff --git a/src/core/file_sys/archive_romfs.cpp b/src/core/file_sys/archive_romfs.cpp index 696b51a94..a9a29ebde 100644 --- a/src/core/file_sys/archive_romfs.cpp +++ b/src/core/file_sys/archive_romfs.cpp @@ -29,11 +29,17 @@ ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_RomFS::Open(const Path return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive)); } -ResultCode ArchiveFactory_RomFS::Format(const Path& path) { +ResultCode ArchiveFactory_RomFS::Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) { LOG_ERROR(Service_FS, "Attempted to format a RomFS archive."); // TODO: Verify error code return ResultCode(ErrorDescription::NotAuthorized, ErrorModule::FS, ErrorSummary::NotSupported, ErrorLevel::Permanent); } +ResultVal<ArchiveFormatInfo> ArchiveFactory_RomFS::GetFormatInfo(const Path& path) const { + // TODO(Subv): Implement + LOG_ERROR(Service_FS, "Unimplemented GetFormatInfo archive %s", GetName().c_str()); + return ResultCode(-1); +} + } // namespace FileSys diff --git a/src/core/file_sys/archive_romfs.h b/src/core/file_sys/archive_romfs.h index 2bedfa9c6..c5a329122 100644 --- a/src/core/file_sys/archive_romfs.h +++ b/src/core/file_sys/archive_romfs.h @@ -26,7 +26,8 @@ public: std::string GetName() const override { return "RomFS"; } ResultVal<std::unique_ptr<ArchiveBackend>> Open(const Path& path) override; - ResultCode Format(const Path& path) override; + ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) override; + ResultVal<ArchiveFormatInfo> GetFormatInfo(const Path& path) const override; private: std::shared_ptr<FileUtil::IOFile> romfs_file; diff --git a/src/core/file_sys/archive_savedata.cpp b/src/core/file_sys/archive_savedata.cpp index 12876899f..82f49af5d 100644 --- a/src/core/file_sys/archive_savedata.cpp +++ b/src/core/file_sys/archive_savedata.cpp @@ -31,6 +31,12 @@ static std::string GetSaveDataPath(const std::string& mount_location, u64 progra return Common::StringFromFormat("%s%08x/%08x/data/00000001/", mount_location.c_str(), high, low); } +static std::string GetSaveDataMetadataPath(const std::string& mount_location, u64 program_id) { + u32 high = program_id >> 32; + u32 low = program_id & 0xFFFFFFFF; + return Common::StringFromFormat("%s%08x/%08x/data/00000001.metadata", mount_location.c_str(), high, low); +} + ArchiveFactory_SaveData::ArchiveFactory_SaveData(const std::string& sdmc_directory) : mount_point(GetSaveDataContainerPath(sdmc_directory)) { LOG_INFO(Service_FS, "Directory %s set as SaveData.", this->mount_point.c_str()); @@ -51,11 +57,35 @@ ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_SaveData::Open(const P return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive)); } -ResultCode ArchiveFactory_SaveData::Format(const Path& path) { +ResultCode ArchiveFactory_SaveData::Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) { std::string concrete_mount_point = GetSaveDataPath(mount_point, Kernel::g_current_process->codeset->program_id); FileUtil::DeleteDirRecursively(concrete_mount_point); FileUtil::CreateFullPath(concrete_mount_point); + + // Write the format metadata + std::string metadata_path = GetSaveDataMetadataPath(mount_point, Kernel::g_current_process->codeset->program_id); + FileUtil::IOFile file(metadata_path, "wb"); + + if (file.IsOpen()) { + file.WriteBytes(&format_info, sizeof(format_info)); + return RESULT_SUCCESS; + } return RESULT_SUCCESS; } +ResultVal<ArchiveFormatInfo> ArchiveFactory_SaveData::GetFormatInfo(const Path& path) const { + std::string metadata_path = GetSaveDataMetadataPath(mount_point, Kernel::g_current_process->codeset->program_id); + FileUtil::IOFile file(metadata_path, "rb"); + + if (file.IsOpen()) { + ArchiveFormatInfo info; + file.ReadBytes(&info, sizeof(info)); + return MakeResult<ArchiveFormatInfo>(info); + } + + LOG_ERROR(Service_FS, "Could not open metadata information for archive"); + // TODO(Subv): Verify error code + return ResultCode(ErrorDescription::FS_NotFormatted, ErrorModule::FS, ErrorSummary::InvalidState, ErrorLevel::Status); +} + } // namespace FileSys diff --git a/src/core/file_sys/archive_savedata.h b/src/core/file_sys/archive_savedata.h index 1f65297dd..7a5a24089 100644 --- a/src/core/file_sys/archive_savedata.h +++ b/src/core/file_sys/archive_savedata.h @@ -23,7 +23,9 @@ public: std::string GetName() const override { return "SaveData"; } ResultVal<std::unique_ptr<ArchiveBackend>> Open(const Path& path) override; - ResultCode Format(const Path& path) override; + ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) override; + + ResultVal<ArchiveFormatInfo> GetFormatInfo(const Path& path) const override; private: std::string mount_point; diff --git a/src/core/file_sys/archive_savedatacheck.cpp b/src/core/file_sys/archive_savedatacheck.cpp index ea1dfe2c7..3db11c500 100644 --- a/src/core/file_sys/archive_savedatacheck.cpp +++ b/src/core/file_sys/archive_savedatacheck.cpp @@ -48,11 +48,17 @@ ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_SaveDataCheck::Open(co return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive)); } -ResultCode ArchiveFactory_SaveDataCheck::Format(const Path& path) { +ResultCode ArchiveFactory_SaveDataCheck::Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) { LOG_ERROR(Service_FS, "Attempted to format a SaveDataCheck archive."); // TODO: Verify error code return ResultCode(ErrorDescription::NotAuthorized, ErrorModule::FS, ErrorSummary::NotSupported, ErrorLevel::Permanent); } +ResultVal<ArchiveFormatInfo> ArchiveFactory_SaveDataCheck::GetFormatInfo(const Path& path) const { + // TODO(Subv): Implement + LOG_ERROR(Service_FS, "Unimplemented GetFormatInfo archive %s", GetName().c_str()); + return ResultCode(-1); +} + } // namespace FileSys diff --git a/src/core/file_sys/archive_savedatacheck.h b/src/core/file_sys/archive_savedatacheck.h index b14aefe8b..ea2624d64 100644 --- a/src/core/file_sys/archive_savedatacheck.h +++ b/src/core/file_sys/archive_savedatacheck.h @@ -23,7 +23,8 @@ public: std::string GetName() const override { return "SaveDataCheck"; } ResultVal<std::unique_ptr<ArchiveBackend>> Open(const Path& path) override; - ResultCode Format(const Path& path) override; + ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) override; + ResultVal<ArchiveFormatInfo> GetFormatInfo(const Path& path) const override; private: std::string mount_point; diff --git a/src/core/file_sys/archive_sdmc.cpp b/src/core/file_sys/archive_sdmc.cpp index 5c825f429..657221cbf 100644 --- a/src/core/file_sys/archive_sdmc.cpp +++ b/src/core/file_sys/archive_sdmc.cpp @@ -40,9 +40,14 @@ ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_SDMC::Open(const Path& return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive)); } -ResultCode ArchiveFactory_SDMC::Format(const Path& path) { +ResultCode ArchiveFactory_SDMC::Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) { // This is kind of an undesirable operation, so let's just ignore it. :) return RESULT_SUCCESS; } +ResultVal<ArchiveFormatInfo> ArchiveFactory_SDMC::GetFormatInfo(const Path& path) const { + // TODO(Subv): Implement + LOG_ERROR(Service_FS, "Unimplemented GetFormatInfo archive %s", GetName().c_str()); + return ResultCode(-1); +} } // namespace FileSys diff --git a/src/core/file_sys/archive_sdmc.h b/src/core/file_sys/archive_sdmc.h index 10b273bdb..35c0f3725 100644 --- a/src/core/file_sys/archive_sdmc.h +++ b/src/core/file_sys/archive_sdmc.h @@ -29,7 +29,8 @@ public: std::string GetName() const override { return "SDMC"; } ResultVal<std::unique_ptr<ArchiveBackend>> Open(const Path& path) override; - ResultCode Format(const Path& path) override; + ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) override; + ResultVal<ArchiveFormatInfo> GetFormatInfo(const Path& path) const override; private: std::string sdmc_directory; diff --git a/src/core/file_sys/archive_systemsavedata.cpp b/src/core/file_sys/archive_systemsavedata.cpp index 896f89529..e1780de2f 100644 --- a/src/core/file_sys/archive_systemsavedata.cpp +++ b/src/core/file_sys/archive_systemsavedata.cpp @@ -63,11 +63,17 @@ ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_SystemSaveData::Open(c return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive)); } -ResultCode ArchiveFactory_SystemSaveData::Format(const Path& path) { +ResultCode ArchiveFactory_SystemSaveData::Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) { std::string fullpath = GetSystemSaveDataPath(base_path, path); FileUtil::DeleteDirRecursively(fullpath); FileUtil::CreateFullPath(fullpath); return RESULT_SUCCESS; } +ResultVal<ArchiveFormatInfo> ArchiveFactory_SystemSaveData::GetFormatInfo(const Path& path) const { + // TODO(Subv): Implement + LOG_ERROR(Service_FS, "Unimplemented GetFormatInfo archive %s", GetName().c_str()); + return ResultCode(-1); +} + } // namespace FileSys diff --git a/src/core/file_sys/archive_systemsavedata.h b/src/core/file_sys/archive_systemsavedata.h index afc689848..2bc13d4ee 100644 --- a/src/core/file_sys/archive_systemsavedata.h +++ b/src/core/file_sys/archive_systemsavedata.h @@ -23,7 +23,8 @@ public: ArchiveFactory_SystemSaveData(const std::string& mount_point); ResultVal<std::unique_ptr<ArchiveBackend>> Open(const Path& path) override; - ResultCode Format(const Path& path) override; + ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) override; + ResultVal<ArchiveFormatInfo> GetFormatInfo(const Path& path) const override; std::string GetName() const override { return "SystemSaveData"; } |