mirror of
https://github.com/melonDS-emu/melonDS.git
synced 2025-07-30 01:29:52 -06:00
Refactor DSi_NAND (#1844)
* Refactor diskio's contents - Change ff_disk_read_cb/write_cb into a std::function instead of a raw pointer - Add const specifiers as needed * Refactor DSi_NAND to manage the file system's mounted lifetime with RAII * Split NANDMount into NANDMount and NANDImage - NANDImage is used for information about the NAND that doesn't require decryption or filesystem access - NANDMount is used to actually access the file system - Both classes manage their respective resources (the NAND file handle and the NAND's mount) with RAII - Also split the file loading into another function that I will remove in a later PR * Make NANDMount immovable * Remove NAND-loading code that I had sectioned off into a function - Incomplete copypasta - I must have gotten distracted * Tidy up NANDImage's initialization - Don't unmount the disk image if the constructor fails (that's NANDMount's job now) - Only assign CurFile if the constructor succeeds * Add some const-correctness * Move DSi NAND initialization to the frontend - The NANDImage is now installed via a unique_ptr in DSi * Remove Platform::DSi_NANDPath - Not Config::DSiNANDPath; that can still be configured as usual - The core no longer needs to care
This commit is contained in:

committed by
GitHub

parent
b2fcff97c1
commit
d4e51f8060
101
src/DSi_NAND.h
101
src/DSi_NAND.h
@ -20,6 +20,7 @@
|
||||
#define DSI_NAND_H
|
||||
|
||||
#include "types.h"
|
||||
#include "fatfs/ff.h"
|
||||
#include "NDS_Header.h"
|
||||
#include "DSi_TMD.h"
|
||||
#include "SPI_Firmware.h"
|
||||
@ -27,6 +28,8 @@
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
struct AES_ctx;
|
||||
|
||||
namespace DSi_NAND
|
||||
{
|
||||
|
||||
@ -40,29 +43,95 @@ enum
|
||||
union DSiFirmwareSystemSettings;
|
||||
union DSiSerialData;
|
||||
using DSiHardwareInfoN = std::array<u8, 0x9C>;
|
||||
using DSiKey = std::array<u8, 16>;
|
||||
|
||||
bool Init(u8* es_keyY);
|
||||
void DeInit();
|
||||
class NANDImage
|
||||
{
|
||||
public:
|
||||
explicit NANDImage(Platform::FileHandle* nandfile, const DSiKey& es_keyY) noexcept;
|
||||
explicit NANDImage(Platform::FileHandle* nandfile, const u8* es_keyY) noexcept;
|
||||
~NANDImage();
|
||||
NANDImage(const NANDImage&) = delete;
|
||||
NANDImage& operator=(const NANDImage&) = delete;
|
||||
|
||||
Platform::FileHandle* GetFile();
|
||||
NANDImage(NANDImage&& other) noexcept;
|
||||
NANDImage& operator=(NANDImage&& other) noexcept;
|
||||
|
||||
void GetIDs(u8* emmc_cid, u64& consoleid);
|
||||
Platform::FileHandle* GetFile() { return CurFile; }
|
||||
|
||||
void ReadHardwareInfo(DSiSerialData& dataS, DSiHardwareInfoN& dataN);
|
||||
[[nodiscard]] const DSiKey& GetEMMCID() const noexcept { return eMMC_CID; }
|
||||
[[nodiscard]] u64 GetConsoleID() const noexcept { return ConsoleID; }
|
||||
[[nodiscard]] u64 GetLength() const noexcept { return Length; }
|
||||
|
||||
void ReadUserData(DSiFirmwareSystemSettings& data);
|
||||
void PatchUserData();
|
||||
explicit operator bool() const { return CurFile != nullptr; }
|
||||
private:
|
||||
friend class NANDMount;
|
||||
void SetupFATCrypto(AES_ctx* ctx, u32 ctr);
|
||||
u32 ReadFATBlock(u64 addr, u32 len, u8* buf);
|
||||
u32 WriteFATBlock(u64 addr, u32 len, const u8* buf);
|
||||
bool ESEncrypt(u8* data, u32 len) const;
|
||||
bool ESDecrypt(u8* data, u32 len);
|
||||
Platform::FileHandle* CurFile = nullptr;
|
||||
DSiKey eMMC_CID;
|
||||
u64 ConsoleID;
|
||||
DSiKey FATIV;
|
||||
DSiKey FATKey;
|
||||
DSiKey ESKey;
|
||||
u64 Length;
|
||||
};
|
||||
|
||||
void ListTitles(u32 category, std::vector<u32>& titlelist);
|
||||
bool TitleExists(u32 category, u32 titleid);
|
||||
void GetTitleInfo(u32 category, u32 titleid, u32& version, NDSHeader* header, NDSBanner* banner);
|
||||
bool ImportTitle(const char* appfile, const DSi_TMD::TitleMetadata& tmd, bool readonly);
|
||||
bool ImportTitle(const u8* app, size_t appLength, const DSi_TMD::TitleMetadata& tmd, bool readonly);
|
||||
void DeleteTitle(u32 category, u32 titleid);
|
||||
class NANDMount
|
||||
{
|
||||
public:
|
||||
explicit NANDMount(NANDImage& nand) noexcept;
|
||||
~NANDMount();
|
||||
NANDMount(const NANDMount&) = delete;
|
||||
NANDMount& operator=(const NANDMount&) = delete;
|
||||
|
||||
// Move constructor deleted so that the closure passed to FATFS can't be invalidated
|
||||
NANDMount(NANDMount&&) = delete;
|
||||
NANDMount& operator=(NANDMount&&) = delete;
|
||||
|
||||
void ReadHardwareInfo(DSiSerialData& dataS, DSiHardwareInfoN& dataN);
|
||||
|
||||
void ReadUserData(DSiFirmwareSystemSettings& data);
|
||||
void PatchUserData();
|
||||
|
||||
void ListTitles(u32 category, std::vector<u32>& titlelist);
|
||||
bool TitleExists(u32 category, u32 titleid);
|
||||
void GetTitleInfo(u32 category, u32 titleid, u32& version, NDSHeader* header, NDSBanner* banner);
|
||||
bool ImportTitle(const char* appfile, const DSi_TMD::TitleMetadata& tmd, bool readonly);
|
||||
bool ImportTitle(const u8* app, size_t appLength, const DSi_TMD::TitleMetadata& tmd, bool readonly);
|
||||
void DeleteTitle(u32 category, u32 titleid);
|
||||
|
||||
u32 GetTitleDataMask(u32 category, u32 titleid);
|
||||
bool ImportTitleData(u32 category, u32 titleid, int type, const char* file);
|
||||
bool ExportTitleData(u32 category, u32 titleid, int type, const char* file);
|
||||
|
||||
bool ImportFile(const char* path, const u8* data, size_t len);
|
||||
bool ImportFile(const char* path, const char* in);
|
||||
bool ExportFile(const char* path, const char* out);
|
||||
void RemoveFile(const char* path);
|
||||
void RemoveDir(const char* path);
|
||||
|
||||
explicit operator bool() const { return Image != nullptr && CurFS != nullptr; }
|
||||
private:
|
||||
u32 GetTitleVersion(u32 category, u32 titleid);
|
||||
bool CreateTicket(const char* path, u32 titleid0, u32 titleid1, u8 version);
|
||||
bool CreateSaveFile(const char* path, u32 len);
|
||||
bool InitTitleFileStructure(const NDSHeader& header, const DSi_TMD::TitleMetadata& tmd, bool readonly);
|
||||
UINT FF_ReadNAND(BYTE* buf, LBA_t sector, UINT num);
|
||||
UINT FF_WriteNAND(const BYTE* buf, LBA_t sector, UINT num);
|
||||
|
||||
NANDImage* Image;
|
||||
|
||||
// We keep a pointer to CurFS because fatfs maintains a global pointer to it;
|
||||
// therefore if we embed the FATFS directly in the object,
|
||||
// we can't give it move semantics.
|
||||
std::unique_ptr<FATFS> CurFS;
|
||||
|
||||
};
|
||||
|
||||
u32 GetTitleDataMask(u32 category, u32 titleid);
|
||||
bool ImportTitleData(u32 category, u32 titleid, int type, const char* file);
|
||||
bool ExportTitleData(u32 category, u32 titleid, int type, const char* file);
|
||||
|
||||
typedef std::array<u8, 20> SHA1Hash;
|
||||
typedef std::array<u8, 8> TitleID;
|
||||
|
Reference in New Issue
Block a user