Add some structs for files that DSi_NAND reads (#1842)

* Add DSiFirmwareSystemSettings

* Replace DSiFirmwareSystemSettings::TouchCalibration fields with std::arrays

- So assignment can be done in one line

* Make DSiFirmwareSystemSettings a union

- So its bytes can be accessed

* Add a comment

* Use DSiFirmwareSystemSettings instead of raw byte offsets

* Add definitions for DSiSerialData and DSiHardwareInfoN

* Move DSiFirmwareSystemSettings's hash update logic into its own method
This commit is contained in:
Jesse Talavera-Greenberg
2023-10-02 11:54:17 -04:00
committed by GitHub
parent bb09ce7d70
commit b2fcff97c1
3 changed files with 144 additions and 35 deletions

View File

@ -22,6 +22,8 @@
#include "types.h"
#include "NDS_Header.h"
#include "DSi_TMD.h"
#include "SPI_Firmware.h"
#include <array>
#include <vector>
#include <string>
@ -35,6 +37,10 @@ enum
TitleData_BannerSav,
};
union DSiFirmwareSystemSettings;
union DSiSerialData;
using DSiHardwareInfoN = std::array<u8, 0x9C>;
bool Init(u8* es_keyY);
void DeInit();
@ -42,9 +48,9 @@ Platform::FileHandle* GetFile();
void GetIDs(u8* emmc_cid, u64& consoleid);
void ReadHardwareInfo(u8* dataS, u8* dataN);
void ReadHardwareInfo(DSiSerialData& dataS, DSiHardwareInfoN& dataN);
void ReadUserData(u8* data);
void ReadUserData(DSiFirmwareSystemSettings& data);
void PatchUserData();
void ListTitles(u32 category, std::vector<u32>& titlelist);
@ -58,6 +64,108 @@ 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;
/// Firmware settings for the DSi, saved to the NAND as TWLCFG0.dat or TWLCFG1.dat.
/// The DSi mirrors this information to its own firmware for compatibility with NDS games.
/// @note The file is normally 16KiB, but only the first 432 bytes are used;
/// the rest is FF-padded.
/// This struct excludes the padding.
/// @see https://problemkaputt.de/gbatek.htm#dsisdmmcfirmwaresystemsettingsdatafiles
union DSiFirmwareSystemSettings
{
struct
{
SHA1Hash Hash;
u8 Zero00[108];
u8 Version;
u8 UpdateCounter;
u8 Zero01[2];
u32 BelowRAMAreaSize;
u32 ConfigFlags;
u8 Zero02;
u8 CountryCode;
SPI_Firmware::Language Language;
u8 RTCYear;
u32 RTCOffset;
u8 Zero3[4];
u8 EULAVersion;
u8 Zero04[9];
u8 AlarmHour;
u8 AlarmMinute;
u8 Zero05[2];
bool AlarmEnable;
u8 Zero06[2];
u8 SystemMenuUsedTitleSlots;
u8 SystemMenuFreeTitleSlots;
u8 Unknown0;
u8 Unknown1;
u8 Zero07[3];
TitleID SystemMenuMostRecentTitleID;
std::array<u16, 2> TouchCalibrationADC1;
std::array<u8, 2> TouchCalibrationPixel1;
std::array<u16, 2> TouchCalibrationADC2;
std::array<u8, 2> TouchCalibrationPixel2;
u8 Unknown2[4];
u8 Zero08[4];
u8 FavoriteColor;
u8 Zero09;
u8 BirthdayMonth;
u8 BirthdayDay;
char16_t Nickname[11];
char16_t Message[27];
u8 ParentalControlsFlags;
u8 Zero10[6];
u8 ParentalControlsRegion;
u8 ParentalControlsYearsOfAgeRating;
u8 ParentalControlsSecretQuestion;
u8 Unknown3;
u8 Zero11[2];
char ParentalControlsPIN[5];
char16_t ParentalControlsSecretAnswer[65];
};
u8 Bytes[432];
void UpdateHash();
};
static_assert(sizeof(DSiFirmwareSystemSettings) == 432, "DSiFirmwareSystemSettings must be exactly 432 bytes");
enum class ConsoleRegion : u8
{
Japan,
USA,
Europe,
Australia,
China,
Korea,
};
/// Data file saved to 0:/sys/HWINFO_S.dat.
/// @note The file is normally 16KiB, but only the first 164 bytes are used;
/// the rest is FF-padded.
/// This struct excludes the padding.
/// @see https://problemkaputt.de/gbatek.htm#dsisdmmcfirmwaremiscfiles
union DSiSerialData
{
struct
{
u8 RsaSha1HMAC[0x80];
u32 Version;
u32 EntrySize;
u32 SupportedLanguages;
u8 Unknown0[4];
ConsoleRegion Region;
char Serial[12];
u8 Unknown1[3];
u8 TitleIDLSBs[4];
};
u8 Bytes[164];
};
static_assert(sizeof(DSiSerialData) == 164, "DSiSerialData must be exactly 164 bytes");
}
#endif // DSI_NAND_H