WiiSave: Refactor import/export code
The current WiiSave code is extremely messy, as it exposes all kinds of implementation details in the header (including internal struct definitions and magic numbers that don't have to be). The read/write code is intermingled, so it's hard to tell which members are used, or when/where they are set at all. It also implicitly relies on some functions being called in a specific order since it doesn't seek manually every time, which makes the code even more fragile. The logic is also hardcoded to only support bin->nand or nand->bin, even though it would be useful to support nand->nand (for the Movie save copying code, for example). This commit attempts to solve these problems by getting rid of the WiiSave class: * Read/write code is moved to new Storage classes (NandStorage and DataBinStorage) with small, clear functions that do one and only one thing. * The import/export logic was refactored into a generic Copy function that takes two storages as parameters. * The existing import and export functions are now just small wrappers that call Copy with the appropriate storages.
This commit is contained in:
parent
dd77ace56a
commit
a46a8dd378
File diff suppressed because it is too large
Load Diff
|
@ -4,138 +4,42 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/Swap.h"
|
||||
|
||||
namespace IOS
|
||||
{
|
||||
namespace HLE
|
||||
{
|
||||
class Kernel;
|
||||
namespace FS
|
||||
{
|
||||
class FileSystem;
|
||||
}
|
||||
class IOSC;
|
||||
}
|
||||
} // namespace IOS::HLE
|
||||
|
||||
class WiiSave
|
||||
namespace WiiSave
|
||||
{
|
||||
public:
|
||||
/// Import a save into the NAND from a .bin file.
|
||||
static bool Import(std::string filename);
|
||||
/// Export a save to a .bin file.
|
||||
static bool Export(u64 title_id, std::string export_path);
|
||||
/// Export all saves that are in the NAND. Returns the number of exported saves.
|
||||
static size_t ExportAll(std::string export_path);
|
||||
|
||||
private:
|
||||
WiiSave(IOS::HLE::Kernel& ios, std::string filename);
|
||||
WiiSave(IOS::HLE::Kernel& ios, u64 title_id, std::string export_path);
|
||||
~WiiSave();
|
||||
|
||||
bool Import();
|
||||
bool Export();
|
||||
|
||||
void ReadHDR();
|
||||
void ReadBKHDR();
|
||||
void WriteHDR();
|
||||
void WriteBKHDR();
|
||||
void ImportWiiSaveFiles();
|
||||
void ExportWiiSaveFiles();
|
||||
void do_sig();
|
||||
bool getPaths(bool for_export = false);
|
||||
void ScanForFiles(const std::string& save_directory, std::vector<std::string>& file_list,
|
||||
u32* num_files, u32* size_files);
|
||||
|
||||
IOS::HLE::Kernel& m_ios;
|
||||
|
||||
std::array<u8, 0x10> m_sd_iv;
|
||||
std::vector<std::string> m_files_list;
|
||||
|
||||
std::string m_encrypted_save_path;
|
||||
|
||||
std::string m_wii_title_path;
|
||||
|
||||
std::array<u8, 0x10> m_iv;
|
||||
|
||||
u64 m_title_id;
|
||||
|
||||
bool m_valid;
|
||||
|
||||
enum
|
||||
{
|
||||
BLOCK_SZ = 0x40,
|
||||
HDR_SZ = 0x20,
|
||||
ICON_SZ = 0x1200,
|
||||
BNR_SZ = 0x60a0,
|
||||
FULL_BNR_MIN = 0x72a0, // BNR_SZ + 1*ICON_SZ
|
||||
FULL_BNR_MAX = 0xF0A0, // BNR_SZ + 8*ICON_SZ
|
||||
HEADER_SZ = 0xF0C0, // HDR_SZ + FULL_BNR_MAX
|
||||
BK_LISTED_SZ = 0x70, // Size before rounding to nearest block
|
||||
BK_SZ = 0x80,
|
||||
FILE_HDR_SZ = 0x80,
|
||||
|
||||
SIG_SZ = 0x40,
|
||||
NG_CERT_SZ = 0x180,
|
||||
AP_CERT_SZ = 0x180,
|
||||
FULL_CERT_SZ = 0x3C0, // SIG_SZ + NG_CERT_SZ + AP_CERT_SZ + 0x80?
|
||||
|
||||
BK_HDR_MAGIC = 0x426B0001,
|
||||
FILE_HDR_MAGIC = 0x03adf17e
|
||||
};
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
struct DataBinHeader // encrypted
|
||||
{
|
||||
Common::BigEndianValue<u64> save_game_title;
|
||||
Common::BigEndianValue<u32> banner_size; // (0x72A0 or 0xF0A0, also seen 0xBAA0)
|
||||
u8 permissions;
|
||||
u8 unk1; // maybe permissions is a be16
|
||||
std::array<u8, 0x10> md5; // md5 of plaintext header with md5 blanker applied
|
||||
Common::BigEndianValue<u16> unk2;
|
||||
};
|
||||
|
||||
struct Header
|
||||
{
|
||||
DataBinHeader hdr;
|
||||
u8 banner[FULL_BNR_MAX];
|
||||
};
|
||||
|
||||
struct BkHeader // Not encrypted
|
||||
{
|
||||
Common::BigEndianValue<u32> size; // 0x00000070
|
||||
// u16 magic; // 'Bk'
|
||||
// u16 magic2; // or version (0x0001)
|
||||
Common::BigEndianValue<u32> magic; // 0x426B0001
|
||||
Common::BigEndianValue<u32> ngid;
|
||||
Common::BigEndianValue<u32> number_of_files;
|
||||
Common::BigEndianValue<u32> size_of_files;
|
||||
Common::BigEndianValue<u32> unk1;
|
||||
Common::BigEndianValue<u32> unk2;
|
||||
Common::BigEndianValue<u32> total_size;
|
||||
std::array<u8, 64> unk3;
|
||||
Common::BigEndianValue<u64> save_game_title;
|
||||
std::array<u8, 6> mac_address;
|
||||
std::array<u8, 0x12> padding;
|
||||
};
|
||||
|
||||
struct FileHDR // encrypted
|
||||
{
|
||||
Common::BigEndianValue<u32> magic; // 0x03adf17e
|
||||
Common::BigEndianValue<u32> size;
|
||||
u8 permissions;
|
||||
u8 attrib;
|
||||
u8 type; // (1=file, 2=directory)
|
||||
std::array<char, 0x45> name;
|
||||
std::array<u8, 0x10> iv;
|
||||
std::array<u8, 0x20> unk;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
Header m_header;
|
||||
Header m_encrypted_header;
|
||||
BkHeader m_bk_hdr;
|
||||
class Storage;
|
||||
struct StorageDeleter
|
||||
{
|
||||
void operator()(Storage* p) const;
|
||||
};
|
||||
|
||||
using StoragePointer = std::unique_ptr<Storage, StorageDeleter>;
|
||||
StoragePointer MakeNandStorage(IOS::HLE::FS::FileSystem* fs, u64 tid);
|
||||
StoragePointer MakeDataBinStorage(IOS::HLE::IOSC* iosc, const std::string& path, const char* mode);
|
||||
|
||||
bool Copy(Storage* source, Storage* destination);
|
||||
|
||||
/// Import a save into the NAND from a .bin file.
|
||||
bool Import(const std::string& data_bin_path);
|
||||
/// Export a save to a .bin file.
|
||||
bool Export(u64 tid, const std::string& export_path);
|
||||
/// Export all saves that are in the NAND. Returns the number of exported saves.
|
||||
size_t ExportAll(const std::string& export_path);
|
||||
} // namespace WiiSave
|
||||
|
|
Loading…
Reference in New Issue