summaryrefslogtreecommitdiffstats
path: root/src/core/file_sys
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/file_sys')
-rw-r--r--src/core/file_sys/archive_backend.h18
-rw-r--r--src/core/file_sys/archive_extsavedata.cpp36
-rw-r--r--src/core/file_sys/archive_extsavedata.h11
-rw-r--r--src/core/file_sys/archive_romfs.cpp8
-rw-r--r--src/core/file_sys/archive_romfs.h3
-rw-r--r--src/core/file_sys/archive_savedata.cpp32
-rw-r--r--src/core/file_sys/archive_savedata.h4
-rw-r--r--src/core/file_sys/archive_savedatacheck.cpp8
-rw-r--r--src/core/file_sys/archive_savedatacheck.h3
-rw-r--r--src/core/file_sys/archive_sdmc.cpp7
-rw-r--r--src/core/file_sys/archive_sdmc.h3
-rw-r--r--src/core/file_sys/archive_systemsavedata.cpp8
-rw-r--r--src/core/file_sys/archive_systemsavedata.h3
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"; }