Merge pull request #4908 from hamish-milne/feature/savestates-2

Save states
This commit is contained in:
Ben 2020-04-17 21:52:51 +02:00 committed by GitHub
commit c605bb42db
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
354 changed files with 6100 additions and 604 deletions

View file

@ -8,6 +8,8 @@
#include <string>
#include <utility>
#include <vector>
#include <boost/serialization/string.hpp>
#include <boost/serialization/vector.hpp>
#include "common/bit_field.h"
#include "common/common_types.h"
#include "common/swap.h"
@ -64,6 +66,32 @@ private:
std::vector<u8> binary;
std::string string;
std::u16string u16str;
template <class Archive>
void serialize(Archive& ar, const unsigned int) {
ar& type;
switch (type) {
case LowPathType::Binary:
ar& binary;
break;
case LowPathType::Char:
ar& string;
break;
case LowPathType::Wchar: {
std::vector<char16_t> data;
if (Archive::is_saving::value) {
std::copy(u16str.begin(), u16str.end(), std::back_inserter(data));
}
ar& data;
if (Archive::is_loading::value) {
u16str = std::u16string(data.data(), data.size());
}
} break;
default:
break;
}
}
friend class boost::serialization::access;
};
/// Parameters of the archive, as specified in the Create or Format call.
@ -169,6 +197,13 @@ public:
protected:
std::unique_ptr<DelayGenerator> delay_generator;
private:
template <class Archive>
void serialize(Archive& ar, const unsigned int) {
ar& delay_generator;
}
friend class boost::serialization::access;
};
class ArchiveFactory : NonCopyable {
@ -205,6 +240,10 @@ public:
* @return Format information about the archive or error code
*/
virtual ResultVal<ArchiveFormatInfo> GetFormatInfo(const Path& path, u64 program_id) const = 0;
template <class Archive>
void serialize(Archive& ar, const unsigned int) {}
friend class boost::serialization::access;
};
} // namespace FileSys

View file

@ -6,6 +6,7 @@
#include <memory>
#include <vector>
#include <fmt/format.h>
#include "common/archives.h"
#include "common/common_types.h"
#include "common/file_util.h"
#include "common/logging/log.h"
@ -19,6 +20,8 @@
////////////////////////////////////////////////////////////////////////////////////////////////////
// FileSys namespace
SERIALIZE_EXPORT_IMPL(FileSys::ArchiveFactory_ExtSaveData)
namespace FileSys {
/**
@ -77,6 +80,8 @@ public:
static constexpr u64 IPCDelayNanoseconds(3085068);
return IPCDelayNanoseconds;
}
SERIALIZE_DELAY_GENERATOR
};
/**
@ -162,6 +167,14 @@ public:
}
return SaveDataArchive::CreateFile(path, size);
}
private:
ExtSaveDataArchive() = default;
template <class Archive>
void serialize(Archive& ar, const unsigned int) {
ar& boost::serialization::base_object<SaveDataArchive>(*this);
}
friend class boost::serialization::access;
};
struct ExtSaveDataArchivePath {
@ -297,3 +310,6 @@ void ArchiveFactory_ExtSaveData::WriteIcon(const Path& path, const u8* icon_data
}
} // namespace FileSys
SERIALIZE_EXPORT_IMPL(FileSys::ExtSaveDataDelayGenerator)
SERIALIZE_EXPORT_IMPL(FileSys::ExtSaveDataArchive)

View file

@ -6,6 +6,8 @@
#include <memory>
#include <string>
#include <boost/serialization/export.hpp>
#include <boost/serialization/string.hpp>
#include "common/common_types.h"
#include "core/file_sys/archive_backend.h"
#include "core/hle/result.h"
@ -54,6 +56,15 @@ private:
/// Returns a path with the correct SaveIdHigh value for Shared extdata paths.
Path GetCorrectedPath(const Path& path);
ArchiveFactory_ExtSaveData() = default;
template <class Archive>
void serialize(Archive& ar, const unsigned int) {
ar& boost::serialization::base_object<ArchiveFactory>(*this);
ar& shared;
ar& mount_point;
}
friend class boost::serialization::access;
};
/**
@ -93,4 +104,9 @@ std::string GetExtDataContainerPath(const std::string& mount_point, bool shared)
*/
Path ConstructExtDataBinaryPath(u32 media_type, u32 high, u32 low);
class ExtSaveDataDelayGenerator;
} // namespace FileSys
BOOST_CLASS_EXPORT_KEY(FileSys::ArchiveFactory_ExtSaveData)
BOOST_CLASS_EXPORT_KEY(FileSys::ExtSaveDataDelayGenerator)

View file

@ -8,6 +8,7 @@
#include <utility>
#include <vector>
#include "bad_word_list.app.romfs.h"
#include "common/archives.h"
#include "common/common_types.h"
#include "common/file_util.h"
#include "common/logging/log.h"
@ -28,6 +29,10 @@
////////////////////////////////////////////////////////////////////////////////////////////////////
// FileSys namespace
SERIALIZE_EXPORT_IMPL(FileSys::NCCHArchive)
SERIALIZE_EXPORT_IMPL(FileSys::NCCHFile)
SERIALIZE_EXPORT_IMPL(FileSys::ArchiveFactory_NCCH)
namespace FileSys {
struct NCCHArchivePath {

View file

@ -7,6 +7,9 @@
#include <array>
#include <memory>
#include <string>
#include <boost/serialization/base_object.hpp>
#include <boost/serialization/export.hpp>
#include <boost/serialization/vector.hpp>
#include "core/file_sys/archive_backend.h"
#include "core/file_sys/file_backend.h"
#include "core/hle/result.h"
@ -63,6 +66,17 @@ public:
protected:
u64 title_id;
Service::FS::MediaType media_type;
private:
NCCHArchive() = default;
template <class Archive>
void serialize(Archive& ar, const unsigned int) {
ar& boost::serialization::base_object<ArchiveBackend>(*this);
ar& title_id;
ar& media_type;
}
friend class boost::serialization::access;
};
// File backend for NCCH files
@ -82,6 +96,15 @@ public:
private:
std::vector<u8> file_buffer;
NCCHFile() = default;
template <class Archive>
void serialize(Archive& ar, const unsigned int) {
ar& boost::serialization::base_object<FileBackend>(*this);
ar& file_buffer;
}
friend class boost::serialization::access;
};
/// File system interface to the NCCH archive
@ -97,6 +120,17 @@ public:
ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info,
u64 program_id) override;
ResultVal<ArchiveFormatInfo> GetFormatInfo(const Path& path, u64 program_id) const override;
private:
template <class Archive>
void serialize(Archive& ar, const unsigned int) {
ar& boost::serialization::base_object<ArchiveFactory>(*this);
}
friend class boost::serialization::access;
};
} // namespace FileSys
BOOST_CLASS_EXPORT_KEY(FileSys::NCCHArchive)
BOOST_CLASS_EXPORT_KEY(FileSys::NCCHFile)
BOOST_CLASS_EXPORT_KEY(FileSys::ArchiveFactory_NCCH)

View file

@ -4,6 +4,7 @@
#include <tuple>
#include <utility>
#include "common/archives.h"
#include "core/file_sys/archive_other_savedata.h"
#include "core/file_sys/errors.h"
#include "core/hle/kernel/process.h"
@ -12,6 +13,9 @@
////////////////////////////////////////////////////////////////////////////////////////////////////
// FileSys namespace
SERIALIZE_EXPORT_IMPL(FileSys::ArchiveFactory_OtherSaveDataPermitted)
SERIALIZE_EXPORT_IMPL(FileSys::ArchiveFactory_OtherSaveDataGeneral)
namespace FileSys {
// TODO(wwylele): The storage info in exheader should be checked before accessing these archives

View file

@ -4,6 +4,9 @@
#pragma once
#include <boost/serialization/base_object.hpp>
#include <boost/serialization/export.hpp>
#include <boost/serialization/shared_ptr.hpp>
#include "core/file_sys/archive_source_sd_savedata.h"
////////////////////////////////////////////////////////////////////////////////////////////////////
@ -27,8 +30,15 @@ public:
ResultVal<ArchiveFormatInfo> GetFormatInfo(const Path& path, u64 program_id) const override;
private:
std::string mount_point;
std::shared_ptr<ArchiveSource_SDSaveData> sd_savedata_source;
ArchiveFactory_OtherSaveDataPermitted() = default;
template <class Archive>
void serialize(Archive& ar, const unsigned int) {
ar& boost::serialization::base_object<ArchiveFactory>(*this);
ar& sd_savedata_source;
}
friend class boost::serialization::access;
};
/// File system interface to the OtherSaveDataGeneral archive
@ -47,8 +57,18 @@ public:
ResultVal<ArchiveFormatInfo> GetFormatInfo(const Path& path, u64 program_id) const override;
private:
std::string mount_point;
std::shared_ptr<ArchiveSource_SDSaveData> sd_savedata_source;
ArchiveFactory_OtherSaveDataGeneral() = default;
template <class Archive>
void serialize(Archive& ar, const unsigned int) {
ar& boost::serialization::base_object<ArchiveFactory>(*this);
ar& sd_savedata_source;
}
friend class boost::serialization::access;
};
} // namespace FileSys
BOOST_CLASS_EXPORT_KEY(FileSys::ArchiveFactory_OtherSaveDataPermitted)
BOOST_CLASS_EXPORT_KEY(FileSys::ArchiveFactory_OtherSaveDataGeneral)

View file

@ -3,6 +3,7 @@
// Refer to the license.txt file included.
#include <utility>
#include "common/archives.h"
#include "core/core.h"
#include "core/file_sys/archive_savedata.h"
#include "core/hle/kernel/process.h"
@ -10,6 +11,8 @@
////////////////////////////////////////////////////////////////////////////////////////////////////
// FileSys namespace
SERIALIZE_EXPORT_IMPL(FileSys::ArchiveFactory_SaveData)
namespace FileSys {
ArchiveFactory_SaveData::ArchiveFactory_SaveData(

View file

@ -4,6 +4,8 @@
#pragma once
#include <boost/serialization/base_object.hpp>
#include <boost/serialization/shared_ptr.hpp>
#include "core/file_sys/archive_source_sd_savedata.h"
////////////////////////////////////////////////////////////////////////////////////////////////////
@ -27,8 +29,17 @@ public:
ResultVal<ArchiveFormatInfo> GetFormatInfo(const Path& path, u64 program_id) const override;
private:
std::string mount_point;
std::shared_ptr<ArchiveSource_SDSaveData> sd_savedata_source;
ArchiveFactory_SaveData() = default;
template <class Archive>
void serialize(Archive& ar, const unsigned int) {
ar& boost::serialization::base_object<ArchiveFactory>(*this);
ar& sd_savedata_source;
}
friend class boost::serialization::access;
};
} // namespace FileSys
BOOST_CLASS_EXPORT_KEY(FileSys::ArchiveFactory_SaveData)

View file

@ -4,6 +4,7 @@
#include <algorithm>
#include <memory>
#include "common/archives.h"
#include "common/file_util.h"
#include "common/logging/log.h"
#include "core/file_sys/archive_sdmc.h"
@ -15,6 +16,9 @@
////////////////////////////////////////////////////////////////////////////////////////////////////
// FileSys namespace
SERIALIZE_EXPORT_IMPL(FileSys::SDMCArchive)
SERIALIZE_EXPORT_IMPL(FileSys::ArchiveFactory_SDMC)
namespace FileSys {
class SDMCDelayGenerator : public DelayGenerator {
@ -37,6 +41,8 @@ public:
static constexpr u64 IPCDelayNanoseconds(269082);
return IPCDelayNanoseconds;
}
SERIALIZE_DELAY_GENERATOR
};
ResultVal<std::unique_ptr<FileBackend>> SDMCArchive::OpenFile(const Path& path,
@ -405,3 +411,5 @@ ResultVal<ArchiveFormatInfo> ArchiveFactory_SDMC::GetFormatInfo(const Path& path
return ResultCode(-1);
}
} // namespace FileSys
SERIALIZE_EXPORT_IMPL(FileSys::SDMCDelayGenerator)

View file

@ -6,6 +6,9 @@
#include <memory>
#include <string>
#include <boost/serialization/base_object.hpp>
#include <boost/serialization/export.hpp>
#include <boost/serialization/string.hpp>
#include "core/file_sys/archive_backend.h"
#include "core/hle/result.h"
@ -42,6 +45,14 @@ public:
protected:
ResultVal<std::unique_ptr<FileBackend>> OpenFileBase(const Path& path, const Mode& mode) const;
std::string mount_point;
SDMCArchive() = default;
template <class Archive>
void serialize(Archive& ar, const unsigned int) {
ar& boost::serialization::base_object<ArchiveBackend>(*this);
ar& mount_point;
}
friend class boost::serialization::access;
};
/// File system interface to the SDMC archive
@ -66,6 +77,20 @@ public:
private:
std::string sdmc_directory;
ArchiveFactory_SDMC() = default;
template <class Archive>
void serialize(Archive& ar, const unsigned int) {
ar& boost::serialization::base_object<ArchiveFactory>(*this);
ar& sdmc_directory;
}
friend class boost::serialization::access;
};
class SDMCDelayGenerator;
} // namespace FileSys
BOOST_CLASS_EXPORT_KEY(FileSys::SDMCArchive)
BOOST_CLASS_EXPORT_KEY(FileSys::ArchiveFactory_SDMC)
BOOST_CLASS_EXPORT_KEY(FileSys::SDMCDelayGenerator)

View file

@ -3,6 +3,7 @@
// Refer to the license.txt file included.
#include <memory>
#include "common/archives.h"
#include "common/file_util.h"
#include "core/file_sys/archive_sdmcwriteonly.h"
#include "core/file_sys/directory_backend.h"
@ -13,6 +14,9 @@
////////////////////////////////////////////////////////////////////////////////////////////////////
// FileSys namespace
SERIALIZE_EXPORT_IMPL(FileSys::SDMCWriteOnlyArchive)
SERIALIZE_EXPORT_IMPL(FileSys::ArchiveFactory_SDMCWriteOnly)
namespace FileSys {
class SDMCWriteOnlyDelayGenerator : public DelayGenerator {
@ -35,6 +39,8 @@ public:
static constexpr u64 IPCDelayNanoseconds(269082);
return IPCDelayNanoseconds;
}
SERIALIZE_DELAY_GENERATOR
};
ResultVal<std::unique_ptr<FileBackend>> SDMCWriteOnlyArchive::OpenFile(const Path& path,
@ -96,3 +102,5 @@ ResultVal<ArchiveFormatInfo> ArchiveFactory_SDMCWriteOnly::GetFormatInfo(const P
}
} // namespace FileSys
SERIALIZE_EXPORT_IMPL(FileSys::SDMCWriteOnlyDelayGenerator)

View file

@ -31,6 +31,14 @@ public:
const Mode& mode) const override;
ResultVal<std::unique_ptr<DirectoryBackend>> OpenDirectory(const Path& path) const override;
private:
SDMCWriteOnlyArchive() = default;
template <class Archive>
void serialize(Archive& ar, const unsigned int) {
ar& boost::serialization::base_object<SDMCArchive>(*this);
}
friend class boost::serialization::access;
};
/// File system interface to the SDMC write-only archive
@ -55,6 +63,20 @@ public:
private:
std::string sdmc_directory;
ArchiveFactory_SDMCWriteOnly() = default;
template <class Archive>
void serialize(Archive& ar, const unsigned int) {
ar& boost::serialization::base_object<ArchiveFactory>(*this);
ar& sdmc_directory;
}
friend class boost::serialization::access;
};
class SDMCWriteOnlyDelayGenerator;
} // namespace FileSys
BOOST_CLASS_EXPORT_KEY(FileSys::SDMCWriteOnlyArchive)
BOOST_CLASS_EXPORT_KEY(FileSys::ArchiveFactory_SDMCWriteOnly)
BOOST_CLASS_EXPORT_KEY(FileSys::SDMCWriteOnlyDelayGenerator)

View file

@ -4,6 +4,7 @@
#include <array>
#include <cinttypes>
#include "common/archives.h"
#include "common/common_types.h"
#include "common/logging/log.h"
#include "common/swap.h"
@ -16,6 +17,8 @@
////////////////////////////////////////////////////////////////////////////////////////////////////
// FileSys namespace
SERIALIZE_EXPORT_IMPL(FileSys::ArchiveFactory_SelfNCCH)
namespace FileSys {
enum class SelfNCCHFilePathType : u32 {
@ -74,6 +77,15 @@ public:
private:
std::shared_ptr<std::vector<u8>> data;
ExeFSSectionFile() = default;
template <class Archive>
void serialize(Archive& ar, const unsigned int) {
ar& boost::serialization::base_object<FileBackend>(*this);
ar& data;
}
friend class boost::serialization::access;
};
// SelfNCCHArchive represents the running application itself. From this archive the application can
@ -231,6 +243,15 @@ private:
}
NCCHData ncch_data;
SelfNCCHArchive() = default;
template <class Archive>
void serialize(Archive& ar, const unsigned int) {
ar& boost::serialization::base_object<ArchiveBackend>(*this);
ar& ncch_data;
}
friend class boost::serialization::access;
};
void ArchiveFactory_SelfNCCH::Register(Loader::AppLoader& app_loader) {
@ -297,3 +318,6 @@ ResultVal<ArchiveFormatInfo> ArchiveFactory_SelfNCCH::GetFormatInfo(const Path&,
}
} // namespace FileSys
SERIALIZE_EXPORT_IMPL(FileSys::ExeFSSectionFile)
SERIALIZE_EXPORT_IMPL(FileSys::SelfNCCHArchive)

View file

@ -8,6 +8,10 @@
#include <string>
#include <unordered_map>
#include <vector>
#include <boost/serialization/export.hpp>
#include <boost/serialization/shared_ptr.hpp>
#include <boost/serialization/unordered_map.hpp>
#include <boost/serialization/vector.hpp>
#include "common/common_types.h"
#include "core/file_sys/archive_backend.h"
#include "core/hle/result.h"
@ -24,6 +28,17 @@ struct NCCHData {
std::shared_ptr<std::vector<u8>> banner;
std::shared_ptr<RomFSReader> romfs_file;
std::shared_ptr<RomFSReader> update_romfs_file;
private:
template <class Archive>
void serialize(Archive& ar, const unsigned int) {
ar& icon;
ar& logo;
ar& banner;
ar& romfs_file;
ar& update_romfs_file;
}
friend class boost::serialization::access;
};
/// File system interface to the SelfNCCH archive
@ -45,6 +60,20 @@ public:
private:
/// Mapping of ProgramId -> NCCHData
std::unordered_map<u64, NCCHData> ncch_data;
template <class Archive>
void serialize(Archive& ar, const unsigned int) {
ar& boost::serialization::base_object<ArchiveFactory>(*this);
ar& ncch_data;
}
friend class boost::serialization::access;
};
class ExeFSSectionFile;
class SelfNCCHArchive;
} // namespace FileSys
BOOST_CLASS_EXPORT_KEY(FileSys::ArchiveFactory_SelfNCCH)
BOOST_CLASS_EXPORT_KEY(FileSys::ExeFSSectionFile)
BOOST_CLASS_EXPORT_KEY(FileSys::SelfNCCHArchive)

View file

@ -3,6 +3,7 @@
// Refer to the license.txt file included.
#include <fmt/format.h>
#include "common/archives.h"
#include "common/file_util.h"
#include "common/logging/log.h"
#include "core/file_sys/archive_source_sd_savedata.h"
@ -13,6 +14,8 @@
////////////////////////////////////////////////////////////////////////////////////////////////////
// FileSys namespace
SERIALIZE_EXPORT_IMPL(FileSys::ArchiveSource_SDSaveData)
namespace FileSys {
namespace {

View file

@ -6,6 +6,8 @@
#include <memory>
#include <string>
#include <boost/serialization/export.hpp>
#include <boost/serialization/string.hpp>
#include "core/file_sys/archive_backend.h"
#include "core/hle/result.h"
@ -27,6 +29,15 @@ public:
private:
std::string mount_point;
ArchiveSource_SDSaveData() = default;
template <class Archive>
void serialize(Archive& ar, const unsigned int) {
ar& mount_point;
}
friend class boost::serialization::access;
};
} // namespace FileSys
BOOST_CLASS_EXPORT_KEY(FileSys::ArchiveSource_SDSaveData)

View file

@ -7,6 +7,7 @@
#include <memory>
#include <vector>
#include <fmt/format.h>
#include "common/archives.h"
#include "common/common_types.h"
#include "common/file_util.h"
#include "core/file_sys/archive_systemsavedata.h"
@ -17,6 +18,8 @@
////////////////////////////////////////////////////////////////////////////////////////////////////
// FileSys namespace
SERIALIZE_EXPORT_IMPL(FileSys::ArchiveFactory_SystemSaveData)
namespace FileSys {
std::string GetSystemSaveDataPath(const std::string& mount_point, const Path& path) {

View file

@ -6,6 +6,8 @@
#include <memory>
#include <string>
#include <boost/serialization/export.hpp>
#include <boost/serialization/string.hpp>
#include "common/common_types.h"
#include "core/file_sys/archive_backend.h"
#include "core/hle/result.h"
@ -31,6 +33,14 @@ public:
private:
std::string base_path;
ArchiveFactory_SystemSaveData() = default;
template <class Archive>
void serialize(Archive& ar, const unsigned int) {
ar& boost::serialization::base_object<ArchiveFactory>(*this);
ar& base_path;
}
friend class boost::serialization::access;
};
/**
@ -60,3 +70,5 @@ std::string GetSystemSaveDataContainerPath(const std::string& mount_point);
Path ConstructSystemSaveDataBinaryPath(u32 high, u32 low);
} // namespace FileSys
BOOST_CLASS_EXPORT_KEY(FileSys::ArchiveFactory_SystemSaveData)

View file

@ -3,8 +3,11 @@
// Refer to the license.txt file included.
#include <algorithm>
#include "common/archives.h"
#include "core/file_sys/delay_generator.h"
SERIALIZE_EXPORT_IMPL(FileSys::DefaultDelayGenerator)
namespace FileSys {
DelayGenerator::~DelayGenerator() = default;

View file

@ -5,8 +5,18 @@
#pragma once
#include <cstddef>
#include <boost/serialization/base_object.hpp>
#include <boost/serialization/export.hpp>
#include "common/common_types.h"
#define SERIALIZE_DELAY_GENERATOR \
private: \
template <class Archive> \
void serialize(Archive& ar, const unsigned int) { \
ar& boost::serialization::base_object<DelayGenerator>(*this); \
} \
friend class boost::serialization::access;
namespace FileSys {
class DelayGenerator {
@ -16,12 +26,20 @@ public:
virtual u64 GetOpenDelayNs() = 0;
// TODO (B3N30): Add getter for all other file/directory io operations
private:
template <class Archive>
void serialize(Archive& ar, const unsigned int) {}
friend class boost::serialization::access;
};
class DefaultDelayGenerator : public DelayGenerator {
public:
u64 GetReadDelayNs(std::size_t length) override;
u64 GetOpenDelayNs() override;
SERIALIZE_DELAY_GENERATOR
};
} // namespace FileSys
BOOST_CLASS_EXPORT_KEY(FileSys::DefaultDelayGenerator);

View file

@ -53,6 +53,11 @@ public:
* @return true if the directory closed correctly
*/
virtual bool Close() const = 0;
private:
template <class Archive>
void serialize(Archive& ar, const unsigned int) {}
friend class boost::serialization::access;
};
} // namespace FileSys

View file

@ -5,6 +5,7 @@
#include <algorithm>
#include <cstdio>
#include <memory>
#include "common/archives.h"
#include "common/common_types.h"
#include "common/file_util.h"
#include "common/logging/log.h"
@ -14,6 +15,9 @@
////////////////////////////////////////////////////////////////////////////////////////////////////
// FileSys namespace
SERIALIZE_EXPORT_IMPL(FileSys::DiskFile)
SERIALIZE_EXPORT_IMPL(FileSys::DiskDirectory)
namespace FileSys {
ResultVal<std::size_t> DiskFile::Read(const u64 offset, const std::size_t length,

View file

@ -8,6 +8,9 @@
#include <memory>
#include <string>
#include <vector>
#include <boost/serialization/base_object.hpp>
#include <boost/serialization/unique_ptr.hpp>
#include <boost/serialization/vector.hpp>
#include "common/common_types.h"
#include "common/file_util.h"
#include "core/file_sys/archive_backend.h"
@ -43,6 +46,17 @@ public:
protected:
Mode mode;
std::unique_ptr<FileUtil::IOFile> file;
private:
DiskFile() = default;
template <class Archive>
void serialize(Archive& ar, const unsigned int) {
ar& boost::serialization::base_object<FileBackend>(*this);
ar& mode.hex;
ar& file;
}
friend class boost::serialization::access;
};
class DiskDirectory : public DirectoryBackend {
@ -65,6 +79,27 @@ protected:
// We need to remember the last entry we returned, so a subsequent call to Read will continue
// from the next one. This iterator will always point to the next unread entry.
std::vector<FileUtil::FSTEntry>::iterator children_iterator;
private:
DiskDirectory() = default;
template <class Archive>
void serialize(Archive& ar, const unsigned int) {
ar& boost::serialization::base_object<DirectoryBackend>(*this);
ar& directory;
u64 child_index;
if (Archive::is_saving::value) {
child_index = children_iterator - directory.children.begin();
}
ar& child_index;
if (Archive::is_loading::value) {
children_iterator = directory.children.begin() + child_index;
}
}
friend class boost::serialization::access;
};
} // namespace FileSys
BOOST_CLASS_EXPORT_KEY(FileSys::DiskFile)
BOOST_CLASS_EXPORT_KEY(FileSys::DiskDirectory)

View file

@ -7,6 +7,7 @@
#include <algorithm>
#include <cstddef>
#include <memory>
#include <boost/serialization/unique_ptr.hpp>
#include "common/common_types.h"
#include "core/hle/result.h"
#include "delay_generator.h"
@ -90,6 +91,12 @@ public:
protected:
std::unique_ptr<DelayGenerator> delay_generator;
template <class Archive>
void serialize(Archive& ar, const unsigned int) {
ar& delay_generator;
}
friend class boost::serialization::access;
};
} // namespace FileSys

View file

@ -5,6 +5,7 @@
#include <cstring>
#include <memory>
#include <utility>
#include "common/archives.h"
#include "common/common_types.h"
#include "common/logging/log.h"
#include "core/file_sys/ivfc_archive.h"
@ -12,6 +13,12 @@
////////////////////////////////////////////////////////////////////////////////////////////////////
// FileSys namespace
SERIALIZE_EXPORT_IMPL(FileSys::IVFCFile)
SERIALIZE_EXPORT_IMPL(FileSys::IVFCFileInMemory)
SERIALIZE_EXPORT_IMPL(FileSys::IVFCDelayGenerator)
SERIALIZE_EXPORT_IMPL(FileSys::RomFSDelayGenerator)
SERIALIZE_EXPORT_IMPL(FileSys::ExeFSDelayGenerator)
namespace FileSys {
IVFCArchive::IVFCArchive(std::shared_ptr<RomFSReader> file,

View file

@ -8,6 +8,8 @@
#include <memory>
#include <string>
#include <vector>
#include <boost/serialization/export.hpp>
#include <boost/serialization/shared_ptr.hpp>
#include "common/common_types.h"
#include "common/file_util.h"
#include "core/file_sys/archive_backend.h"
@ -38,6 +40,8 @@ class IVFCDelayGenerator : public DelayGenerator {
static constexpr u64 IPCDelayNanoseconds(9438006);
return IPCDelayNanoseconds;
}
SERIALIZE_DELAY_GENERATOR
};
class RomFSDelayGenerator : public DelayGenerator {
@ -60,6 +64,8 @@ public:
static constexpr u64 IPCDelayNanoseconds(9438006);
return IPCDelayNanoseconds;
}
SERIALIZE_DELAY_GENERATOR
};
class ExeFSDelayGenerator : public DelayGenerator {
@ -82,6 +88,8 @@ public:
static constexpr u64 IPCDelayNanoseconds(9438006);
return IPCDelayNanoseconds;
}
SERIALIZE_DELAY_GENERATOR
};
/**
@ -128,6 +136,15 @@ public:
private:
std::shared_ptr<RomFSReader> romfs_file;
IVFCFile() = default;
template <class Archive>
void serialize(Archive& ar, const unsigned int) {
ar& boost::serialization::base_object<FileBackend>(*this);
ar& romfs_file;
}
friend class boost::serialization::access;
};
class IVFCDirectory : public DirectoryBackend {
@ -159,6 +176,23 @@ private:
std::vector<u8> romfs_file;
u64 data_offset;
u64 data_size;
IVFCFileInMemory() = default;
template <class Archive>
void serialize(Archive& ar, const unsigned int) {
ar& boost::serialization::base_object<FileBackend>(*this);
ar& romfs_file;
ar& data_offset;
ar& data_size;
}
friend class boost::serialization::access;
};
} // namespace FileSys
BOOST_CLASS_EXPORT_KEY(FileSys::IVFCFile)
BOOST_CLASS_EXPORT_KEY(FileSys::IVFCFileInMemory)
BOOST_CLASS_EXPORT_KEY(FileSys::IVFCDelayGenerator)
BOOST_CLASS_EXPORT_KEY(FileSys::RomFSDelayGenerator)
BOOST_CLASS_EXPORT_KEY(FileSys::ExeFSDelayGenerator)

View file

@ -5,6 +5,7 @@
#include <algorithm>
#include <cstring>
#include "common/alignment.h"
#include "common/archives.h"
#include "common/assert.h"
#include "common/common_paths.h"
#include "common/file_util.h"
@ -13,6 +14,8 @@
#include "core/file_sys/layered_fs.h"
#include "core/file_sys/patch.h"
SERIALIZE_EXPORT_IMPL(FileSys::LayeredFS)
namespace FileSys {
struct FileRelocationInfo {
@ -51,11 +54,16 @@ struct FileMetadata {
};
static_assert(sizeof(FileMetadata) == 0x20, "Size of FileMetadata is not correct");
LayeredFS::LayeredFS(std::shared_ptr<RomFSReader> romfs_, std::string patch_path_,
std::string patch_ext_path_, bool load_relocations)
: romfs(std::move(romfs_)), patch_path(std::move(patch_path_)),
patch_ext_path(std::move(patch_ext_path_)) {
LayeredFS::LayeredFS() = default;
LayeredFS::LayeredFS(std::shared_ptr<RomFSReader> romfs_, std::string patch_path_,
std::string patch_ext_path_, bool load_relocations_)
: romfs(std::move(romfs_)), patch_path(std::move(patch_path_)),
patch_ext_path(std::move(patch_ext_path_)), load_relocations(load_relocations_) {
Load();
}
void LayeredFS::Load() {
romfs->ReadFile(0, sizeof(header), reinterpret_cast<u8*>(&header));
ASSERT_MSG(header.header_length == sizeof(header), "Header size is incorrect");
@ -273,7 +281,7 @@ std::size_t GetNameSize(const std::string& name) {
}
void LayeredFS::PrepareBuildDirectory(Directory& current) {
directory_metadata_offset_map.emplace(&current, current_directory_offset);
directory_metadata_offset_map.emplace(&current, static_cast<u32>(current_directory_offset));
directory_list.emplace_back(&current);
current_directory_offset += sizeof(DirectoryMetadata) + GetNameSize(current.name);
}
@ -282,7 +290,7 @@ void LayeredFS::PrepareBuildFile(File& current) {
if (current.relocation.type == 3) { // Deleted files are not counted
return;
}
file_metadata_offset_map.emplace(&current, current_file_offset);
file_metadata_offset_map.emplace(&current, static_cast<u32>(current_file_offset));
file_list.emplace_back(&current);
current_file_offset += sizeof(FileMetadata) + GetNameSize(current.name);
}
@ -361,7 +369,7 @@ void LayeredFS::BuildDirectories() {
// Write metadata and name
std::u16string u16name = Common::UTF8ToUTF16(directory->name);
metadata.name_length = u16name.size() * 2;
metadata.name_length = static_cast<u32_le>(u16name.size() * 2);
std::memcpy(directory_metadata_table.data() + written, &metadata, sizeof(metadata));
written += sizeof(metadata);
@ -410,7 +418,7 @@ void LayeredFS::BuildFiles() {
// Write metadata and name
std::u16string u16name = Common::UTF8ToUTF16(file->name);
metadata.name_length = u16name.size() * 2;
metadata.name_length = static_cast<u32_le>(u16name.size() * 2);
std::memcpy(file_metadata_table.data() + written, &metadata, sizeof(metadata));
written += sizeof(metadata);

View file

@ -9,6 +9,10 @@
#include <string>
#include <unordered_map>
#include <vector>
#include <boost/serialization/base_object.hpp>
#include <boost/serialization/export.hpp>
#include <boost/serialization/shared_ptr.hpp>
#include <boost/serialization/string.hpp>
#include "common/common_types.h"
#include "common/swap.h"
#include "core/file_sys/romfs_reader.h"
@ -92,9 +96,12 @@ private:
void RebuildMetadata();
void Load();
std::shared_ptr<RomFSReader> romfs;
std::string patch_path;
std::string patch_ext_path;
bool load_relocations;
RomFSHeader header;
Directory root;
@ -118,6 +125,24 @@ private:
u64 current_file_offset{}; // current file metadata offset
std::vector<u8> file_metadata_table; // rebuilt file metadata table
u64 current_data_offset{}; // current assigned data offset
LayeredFS();
template <class Archive>
void serialize(Archive& ar, const unsigned int) {
ar& boost::serialization::base_object<RomFSReader>(*this);
ar& romfs;
ar& patch_path;
ar& patch_ext_path;
ar& load_relocations;
if (Archive::is_loading::value) {
Load();
}
// NOTE: Everything else is essentially cached, updated when we call Load
}
friend class boost::serialization::access;
};
} // namespace FileSys
BOOST_CLASS_EXPORT_KEY(FileSys::LayeredFS)

View file

@ -1,15 +1,18 @@
#include <algorithm>
#include <cryptopp/aes.h>
#include <cryptopp/modes.h>
#include "common/archives.h"
#include "core/file_sys/romfs_reader.h"
SERIALIZE_EXPORT_IMPL(FileSys::DirectRomFSReader)
namespace FileSys {
std::size_t DirectRomFSReader::ReadFile(std::size_t offset, std::size_t length, u8* buffer) {
if (length == 0)
return 0; // Crypto++ does not like zero size buffer
file.Seek(file_offset + offset, SEEK_SET);
std::size_t read_length = std::min(length, data_size - offset);
std::size_t read_length = std::min(length, static_cast<std::size_t>(data_size) - offset);
read_length = file.ReadBytes(buffer, read_length);
if (is_encrypted) {
CryptoPP::CTR_Mode<CryptoPP::AES>::Decryption d(key.data(), key.size(), ctr.data());

View file

@ -1,6 +1,9 @@
#pragma once
#include <array>
#include <boost/serialization/array.hpp>
#include <boost/serialization/base_object.hpp>
#include <boost/serialization/export.hpp>
#include "common/common_types.h"
#include "common/file_util.h"
@ -15,6 +18,11 @@ public:
virtual std::size_t GetSize() const = 0;
virtual std::size_t ReadFile(std::size_t offset, std::size_t length, u8* buffer) = 0;
private:
template <class Archive>
void serialize(Archive& ar, const unsigned int file_version) {}
friend class boost::serialization::access;
};
/**
@ -45,9 +53,26 @@ private:
FileUtil::IOFile file;
std::array<u8, 16> key;
std::array<u8, 16> ctr;
std::size_t file_offset;
std::size_t crypto_offset;
std::size_t data_size;
u64 file_offset;
u64 crypto_offset;
u64 data_size;
DirectRomFSReader() = default;
template <class Archive>
void serialize(Archive& ar, const unsigned int) {
ar& boost::serialization::base_object<RomFSReader>(*this);
ar& is_encrypted;
ar& file;
ar& key;
ar& ctr;
ar& file_offset;
ar& crypto_offset;
ar& data_size;
}
friend class boost::serialization::access;
};
} // namespace FileSys
BOOST_CLASS_EXPORT_KEY(FileSys::DirectRomFSReader)

View file

@ -2,6 +2,7 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include "common/archives.h"
#include "common/file_util.h"
#include "core/file_sys/disk_archive.h"
#include "core/file_sys/errors.h"
@ -33,6 +34,8 @@ public:
static constexpr u64 IPCDelayNanoseconds(269082);
return IPCDelayNanoseconds;
}
SERIALIZE_DELAY_GENERATOR
};
ResultVal<std::unique_ptr<FileBackend>> SaveDataArchive::OpenFile(const Path& path,
@ -353,3 +356,6 @@ u64 SaveDataArchive::GetFreeBytes() const {
}
} // namespace FileSys
SERIALIZE_EXPORT_IMPL(FileSys::SaveDataArchive)
SERIALIZE_EXPORT_IMPL(FileSys::SaveDataDelayGenerator)

View file

@ -38,6 +38,22 @@ public:
protected:
std::string mount_point;
SaveDataArchive() = default;
private:
template <class Archive>
void serialize(Archive& ar, const unsigned int) {
ar& boost::serialization::base_object<ArchiveBackend>(*this);
ar& mount_point;
}
friend class boost::serialization::access;
};
class SaveDataDelayGenerator;
class ExtSaveDataArchive;
} // namespace FileSys
BOOST_CLASS_EXPORT_KEY(FileSys::SaveDataArchive)
BOOST_CLASS_EXPORT_KEY(FileSys::SaveDataDelayGenerator)
BOOST_CLASS_EXPORT_KEY(FileSys::ExtSaveDataArchive)