mirror of
https://github.com/d0k3/GodMode9.git
synced 2025-06-26 05:32:47 +00:00
fix compilation warnings due to unaligned packed structures in newer gcc
This commit is contained in:
parent
88751ab96a
commit
d6c6f56526
@ -64,7 +64,7 @@ typedef struct {
|
|||||||
u32 red[8];
|
u32 red[8];
|
||||||
u32 green[8];
|
u32 green[8];
|
||||||
u32 blue[8];
|
u32 blue[8];
|
||||||
} __attribute__((packed)) MCU_NotificationLED;
|
} PACKED_STRUCT MCU_NotificationLED;
|
||||||
|
|
||||||
static u8 cached_volume_slider = 0;
|
static u8 cached_volume_slider = 0;
|
||||||
static u32 spec_hid = 0, shell_state = SHELL_OPEN;
|
static u32 spec_hid = 0, shell_state = SHELL_OPEN;
|
||||||
|
@ -17,7 +17,7 @@ typedef struct {
|
|||||||
u8 bcd_M;
|
u8 bcd_M;
|
||||||
u8 bcd_Y;
|
u8 bcd_Y;
|
||||||
u8 leap_count;
|
u8 leap_count;
|
||||||
} __attribute__((packed)) DsTime;
|
} PACKED_STRUCT DsTime;
|
||||||
|
|
||||||
bool is_valid_dstime(DsTime* dstime);
|
bool is_valid_dstime(DsTime* dstime);
|
||||||
bool get_dstime(DsTime* dstime);
|
bool get_dstime(DsTime* dstime);
|
||||||
|
@ -8,7 +8,7 @@ typedef struct {
|
|||||||
u8 slot; // keyslot, 0x00...0x39
|
u8 slot; // keyslot, 0x00...0x39
|
||||||
u8 keyUnitType; // 0 for ALL units / 1 for devkit exclusive / 2 for retail exclusive
|
u8 keyUnitType; // 0 for ALL units / 1 for devkit exclusive / 2 for retail exclusive
|
||||||
u8 sample[16]; // sample data, encoded with src = keyY = ctr = { 0 }
|
u8 sample[16]; // sample data, encoded with src = keyY = ctr = { 0 }
|
||||||
} __attribute__((packed)) AesNcchSampleInfo;
|
} PACKED_STRUCT AesNcchSampleInfo;
|
||||||
|
|
||||||
static u64 keyState = 0;
|
static u64 keyState = 0;
|
||||||
static u64 keyXState = 0;
|
static u64 keyXState = 0;
|
||||||
|
@ -24,7 +24,7 @@ typedef struct {
|
|||||||
u8 keyUnitType; // 0 for ALL units / 1 for devkit exclusive / 2 for retail exclusive
|
u8 keyUnitType; // 0 for ALL units / 1 for devkit exclusive / 2 for retail exclusive
|
||||||
u8 isEncrypted; // 0 if not / anything else if it is
|
u8 isEncrypted; // 0 if not / anything else if it is
|
||||||
u8 key[16];
|
u8 key[16];
|
||||||
} __attribute__((packed)) __attribute__((aligned(16))) AesKeyInfo;
|
} PACKED_STRUCT __attribute__((aligned(16))) AesKeyInfo;
|
||||||
|
|
||||||
u32 GetUnitKeysType(void);
|
u32 GetUnitKeysType(void);
|
||||||
void CryptAesKeyInfo(AesKeyInfo* info);
|
void CryptAesKeyInfo(AesKeyInfo* info);
|
||||||
|
@ -11,13 +11,13 @@ typedef struct {
|
|||||||
u8 chs_end[3]; // 0xFE 0xFF 0xFF
|
u8 chs_end[3]; // 0xFE 0xFF 0xFF
|
||||||
u32 sector; // 0x2000 (4MB offset, 512 byte sectors)
|
u32 sector; // 0x2000 (4MB offset, 512 byte sectors)
|
||||||
u32 count;
|
u32 count;
|
||||||
} __attribute__((packed)) MbrPartitionInfo;
|
} PACKED_ALIGN(2) MbrPartitionInfo;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char text[446];
|
char text[446];
|
||||||
MbrPartitionInfo partitions[4];
|
MbrPartitionInfo partitions[4];
|
||||||
u16 magic; // 0xAA55
|
u16 magic; // 0xAA55
|
||||||
} __attribute__((packed)) MbrHeader;
|
} PACKED_ALIGN(2) MbrHeader;
|
||||||
|
|
||||||
typedef struct { // unused
|
typedef struct { // unused
|
||||||
u32 signature0; // 0x41615252
|
u32 signature0; // 0x41615252
|
||||||
@ -27,7 +27,7 @@ typedef struct { // unused
|
|||||||
u32 clr_next; // 0xFFFFFFFF
|
u32 clr_next; // 0xFFFFFFFF
|
||||||
u8 reserved1[14];
|
u8 reserved1[14];
|
||||||
u16 magic; // 0xAA55
|
u16 magic; // 0xAA55
|
||||||
} __attribute__((packed)) FileSystemInfo;
|
} PACKED_STRUCT FileSystemInfo;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u8 jmp[3]; // 0x90 0x00 0xEB
|
u8 jmp[3]; // 0x90 0x00 0xEB
|
||||||
@ -59,7 +59,7 @@ typedef struct {
|
|||||||
char fs_type[8]; // "FAT32 "
|
char fs_type[8]; // "FAT32 "
|
||||||
u8 reserved4[420];
|
u8 reserved4[420];
|
||||||
u16 magic; // 0xAA55
|
u16 magic; // 0xAA55
|
||||||
} __attribute__((packed)) Fat32Header;
|
} PACKED_STRUCT Fat32Header;
|
||||||
|
|
||||||
typedef struct { // this struct is not tested enough!
|
typedef struct { // this struct is not tested enough!
|
||||||
u8 jmp[3]; // 0x90 0x00 0xEB
|
u8 jmp[3]; // 0x90 0x00 0xEB
|
||||||
@ -84,7 +84,7 @@ typedef struct { // this struct is not tested enough!
|
|||||||
char fs_type[8]; // "FAT16 "
|
char fs_type[8]; // "FAT16 "
|
||||||
u8 reserved4[448];
|
u8 reserved4[448];
|
||||||
u16 magic; // 0xAA55
|
u16 magic; // 0xAA55
|
||||||
} __attribute__((packed)) Fat16Header;
|
} PACKED_STRUCT Fat16Header;
|
||||||
|
|
||||||
u32 ValidateMbrHeader(MbrHeader* mbr);
|
u32 ValidateMbrHeader(MbrHeader* mbr);
|
||||||
u32 ValidateFatHeader(void* fat);
|
u32 ValidateFatHeader(void* fat);
|
||||||
|
@ -18,20 +18,19 @@ u64 IdentifyFileType(const char* path) {
|
|||||||
const u8 smdh_magic[] = { SMDH_MAGIC };
|
const u8 smdh_magic[] = { SMDH_MAGIC };
|
||||||
const u8 threedsx_magic[] = { THREEDSX_EXT_MAGIC };
|
const u8 threedsx_magic[] = { THREEDSX_EXT_MAGIC };
|
||||||
const u8 png_magic[] = { PNG_MAGIC };
|
const u8 png_magic[] = { PNG_MAGIC };
|
||||||
|
|
||||||
if (!path) return 0; // safety
|
if (!path) return 0; // safety
|
||||||
u8 header[0x200] __attribute__((aligned(32))); // minimum required size
|
u8 ALIGN(32) header[0x200]; // minimum required size
|
||||||
void* data = (void*) header;
|
void* data = (void*) header;
|
||||||
size_t fsize = FileGetSize(path);
|
size_t fsize = FileGetSize(path);
|
||||||
char* fname = strrchr(path, '/');
|
char* fname = strrchr(path, '/');
|
||||||
char* ext = (fname) ? strrchr(++fname, '.') : NULL;
|
char* ext = (fname) ? strrchr(++fname, '.') : NULL;
|
||||||
u32 id = 0;
|
u32 id = 0;
|
||||||
|
|
||||||
|
|
||||||
// block crappy "._" files from getting recognized as filetype
|
// block crappy "._" files from getting recognized as filetype
|
||||||
if (!fname) return 0;
|
if (!fname) return 0;
|
||||||
if (strncmp(fname, "._", 2) == 0) return 0;
|
if (strncmp(fname, "._", 2) == 0) return 0;
|
||||||
|
|
||||||
if (ext) {
|
if (ext) {
|
||||||
ext++;
|
ext++;
|
||||||
} else {
|
} else {
|
||||||
@ -39,7 +38,7 @@ u64 IdentifyFileType(const char* path) {
|
|||||||
}
|
}
|
||||||
if (FileGetData(path, header, 0x200, 0) < min(0x200, fsize)) return 0;
|
if (FileGetData(path, header, 0x200, 0) < min(0x200, fsize)) return 0;
|
||||||
if (!fsize) return 0;
|
if (!fsize) return 0;
|
||||||
|
|
||||||
if (fsize >= 0x200) {
|
if (fsize >= 0x200) {
|
||||||
if (ValidateNandNcsdHeader((NandNcsdHeader*) data) == 0) {
|
if (ValidateNandNcsdHeader((NandNcsdHeader*) data) == 0) {
|
||||||
return (fsize >= GetNandNcsdMinSizeSectors((NandNcsdHeader*) data) * 0x200) ?
|
return (fsize >= GetNandNcsdMinSizeSectors((NandNcsdHeader*) data) * 0x200) ?
|
||||||
@ -57,7 +56,7 @@ u64 IdentifyFileType(const char* path) {
|
|||||||
} else if (ValidateCiaHeader((CiaHeader*) data) == 0) {
|
} else if (ValidateCiaHeader((CiaHeader*) data) == 0) {
|
||||||
// this only works because these functions ignore CIA content index
|
// this only works because these functions ignore CIA content index
|
||||||
CiaInfo info;
|
CiaInfo info;
|
||||||
GetCiaInfo(&info, (CiaHeader*) header);
|
GetCiaInfo(&info, data);
|
||||||
if (fsize >= info.size_cia)
|
if (fsize >= info.size_cia)
|
||||||
return GAME_CIA; // CIA file
|
return GAME_CIA; // CIA file
|
||||||
} else if (ValidateNcsdHeader((NcsdHeader*) data) == 0) {
|
} else if (ValidateNcsdHeader((NcsdHeader*) data) == 0) {
|
||||||
|
@ -11,7 +11,7 @@ typedef struct {
|
|||||||
FIL* fptr;
|
FIL* fptr;
|
||||||
u8 ctr[16];
|
u8 ctr[16];
|
||||||
u8 keyy[16];
|
u8 keyy[16];
|
||||||
} __attribute__((packed)) FilCryptInfo;
|
} PACKED_STRUCT FilCryptInfo;
|
||||||
|
|
||||||
static FilCryptInfo filcrypt[NUM_FILCRYPTINFO] = { 0 };
|
static FilCryptInfo filcrypt[NUM_FILCRYPTINFO] = { 0 };
|
||||||
|
|
||||||
|
@ -20,4 +20,4 @@ typedef struct {
|
|||||||
u32 offset_smdh;
|
u32 offset_smdh;
|
||||||
u32 size_smdh;
|
u32 size_smdh;
|
||||||
u32 offset_romfs_lv3;
|
u32 offset_romfs_lv3;
|
||||||
} __attribute__((packed)) ThreedsxHeader;
|
} PACKED_STRUCT ThreedsxHeader;
|
||||||
|
@ -35,7 +35,7 @@ typedef struct {
|
|||||||
u8 unknown3[4];
|
u8 unknown3[4];
|
||||||
u8 hash_payload[0x20];
|
u8 hash_payload[0x20];
|
||||||
u8 signature_payload[0x100];
|
u8 signature_payload[0x100];
|
||||||
} __attribute__((packed)) BossHeader;
|
} PACKED_STRUCT BossHeader;
|
||||||
|
|
||||||
u32 ValidateBossHeader(BossHeader* header, u32 fsize);
|
u32 ValidateBossHeader(BossHeader* header, u32 fsize);
|
||||||
u32 GetBossPayloadHashHeader(u8* header, BossHeader* boss);
|
u32 GetBossPayloadHashHeader(u8* header, BossHeader* boss);
|
||||||
|
@ -17,6 +17,6 @@ typedef struct {
|
|||||||
u8 mod[0x100];
|
u8 mod[0x100];
|
||||||
u8 exp[0x04];
|
u8 exp[0x04];
|
||||||
u8 padding1[0x34];
|
u8 padding1[0x34];
|
||||||
} __attribute__((packed)) Certificate;
|
} PACKED_STRUCT Certificate;
|
||||||
|
|
||||||
u32 LoadCertFromCertDb(u64 offset, Certificate* cert, u32* mod, u32* exp);
|
u32 LoadCertFromCertDb(u64 offset, Certificate* cert, u32* mod, u32* exp);
|
||||||
|
@ -15,7 +15,7 @@ typedef struct {
|
|||||||
u32 core_version; // 2 normally
|
u32 core_version; // 2 normally
|
||||||
u8 reserved1[0xFC];
|
u8 reserved1[0xFC];
|
||||||
u8 smdh[0x36C0]; // from ExeFS
|
u8 smdh[0x36C0]; // from ExeFS
|
||||||
} __attribute__((packed)) CiaMeta;
|
} PACKED_STRUCT CiaMeta;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u32 size_header;
|
u32 size_header;
|
||||||
@ -27,7 +27,7 @@ typedef struct {
|
|||||||
u32 size_meta;
|
u32 size_meta;
|
||||||
u64 size_content;
|
u64 size_content;
|
||||||
u8 content_index[0x2000];
|
u8 content_index[0x2000];
|
||||||
} __attribute__((packed)) CiaHeader;
|
} PACKED_STRUCT CiaHeader;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
CiaHeader header;
|
CiaHeader header;
|
||||||
@ -38,7 +38,7 @@ typedef struct {
|
|||||||
u8 ticket_padding[0x40 - (TICKET_SIZE % 0x40)];
|
u8 ticket_padding[0x40 - (TICKET_SIZE % 0x40)];
|
||||||
TitleMetaData tmd;
|
TitleMetaData tmd;
|
||||||
TmdContentChunk content_list[TMD_MAX_CONTENTS];
|
TmdContentChunk content_list[TMD_MAX_CONTENTS];
|
||||||
} __attribute__((packed, aligned(16))) CiaStub;
|
} PACKED_ALIGN(16) CiaStub;
|
||||||
|
|
||||||
typedef struct { // first 0x20 bytes are identical with CIA header
|
typedef struct { // first 0x20 bytes are identical with CIA header
|
||||||
u32 size_header;
|
u32 size_header;
|
||||||
@ -58,7 +58,7 @@ typedef struct { // first 0x20 bytes are identical with CIA header
|
|||||||
u32 offset_meta;
|
u32 offset_meta;
|
||||||
u32 offset_content_list;
|
u32 offset_content_list;
|
||||||
u32 max_contents;
|
u32 max_contents;
|
||||||
} __attribute__((packed)) CiaInfo;
|
} PACKED_STRUCT CiaInfo;
|
||||||
|
|
||||||
u32 ValidateCiaHeader(CiaHeader* header);
|
u32 ValidateCiaHeader(CiaHeader* header);
|
||||||
u32 GetCiaInfo(CiaInfo* info, CiaHeader* header);
|
u32 GetCiaInfo(CiaInfo* info, CiaHeader* header);
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
u32 off_size_comp; // 0xOOSSSSSS, where O == reverse offset and S == size
|
u32 off_size_comp; // 0xOOSSSSSS, where O == reverse offset and S == size
|
||||||
u32 addsize_dec; // decompressed size - compressed size
|
u32 addsize_dec; // decompressed size - compressed size
|
||||||
} __attribute__((packed)) CodeLzssFooter;
|
} PACKED_ALIGN(4) CodeLzssFooter;
|
||||||
|
|
||||||
|
|
||||||
u32 GetCodeLzssUncompressedSize(void* footer, u32 comp_size) {
|
u32 GetCodeLzssUncompressedSize(void* footer, u32 comp_size) {
|
||||||
@ -353,7 +353,7 @@ bool CompressCodeLzss(const u8* a_pUncompressed, u32 a_uUncompressedSize, u8* a_
|
|||||||
memcpy(a_pCompressed, a_pUncompressed, uOrigSafe);
|
memcpy(a_pCompressed, a_pUncompressed, uOrigSafe);
|
||||||
memmove(a_pCompressed + uOrigSafe, pCompressBuffer + uCompressSafe, uCompressedSize);
|
memmove(a_pCompressed + uOrigSafe, pCompressBuffer + uCompressSafe, uCompressedSize);
|
||||||
memset(a_pCompressed + uPadOffset, 0xFF, uCompFooterOffset - uPadOffset);
|
memset(a_pCompressed + uPadOffset, 0xFF, uCompFooterOffset - uPadOffset);
|
||||||
CodeLzssFooter* pCompFooter = (CodeLzssFooter*)(a_pCompressed + uCompFooterOffset);
|
CodeLzssFooter* pCompFooter = (void*)(a_pCompressed + uCompFooterOffset);
|
||||||
pCompFooter->off_size_comp = uTop | (uBottom << 24);
|
pCompFooter->off_size_comp = uTop | (uBottom << 24);
|
||||||
pCompFooter->addsize_dec = a_uUncompressedSize - *a_uCompressedSize;
|
pCompFooter->addsize_dec = a_uUncompressedSize - *a_uCompressedSize;
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ typedef struct {
|
|||||||
u8 padding1[3];
|
u8 padding1[3];
|
||||||
u8 hash_table[0x20]; // for the active table
|
u8 hash_table[0x20]; // for the active table
|
||||||
u8 unused[0x74];
|
u8 unused[0x74];
|
||||||
} __attribute__((packed)) DisaHeader;
|
} PACKED_STRUCT DisaHeader;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u8 magic[8]; // "DIFF" 0x00030000
|
u8 magic[8]; // "DIFF" 0x00030000
|
||||||
@ -46,7 +46,7 @@ typedef struct {
|
|||||||
u8 hash_table[0x20]; // for the active table
|
u8 hash_table[0x20]; // for the active table
|
||||||
u64 unique_id; // see: http://3dbrew.org/wiki/Extdata
|
u64 unique_id; // see: http://3dbrew.org/wiki/Extdata
|
||||||
u8 unused[0xA4];
|
u8 unused[0xA4];
|
||||||
} __attribute__((packed)) DiffHeader;
|
} PACKED_STRUCT DiffHeader;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u8 magic[8]; // "DIFI" 0x00010000
|
u8 magic[8]; // "DIFI" 0x00010000
|
||||||
@ -60,7 +60,7 @@ typedef struct {
|
|||||||
u8 dpfs_lvl1_selector;
|
u8 dpfs_lvl1_selector;
|
||||||
u8 padding[2];
|
u8 padding[2];
|
||||||
u64 ivfc_offset_extlvl4;
|
u64 ivfc_offset_extlvl4;
|
||||||
} __attribute__((packed)) DifiHeader;
|
} PACKED_STRUCT DifiHeader;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u8 magic[8]; // "IVFC" 0x00020000
|
u8 magic[8]; // "IVFC" 0x00020000
|
||||||
@ -81,7 +81,7 @@ typedef struct {
|
|||||||
u64 size_lvl4;
|
u64 size_lvl4;
|
||||||
u64 log_lvl4;
|
u64 log_lvl4;
|
||||||
u64 size_ivfc; // 0x78
|
u64 size_ivfc; // 0x78
|
||||||
} __attribute__((packed)) IvfcDescriptor;
|
} PACKED_STRUCT IvfcDescriptor;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u8 magic[8]; // "DPFS" 0x00010000
|
u8 magic[8]; // "DPFS" 0x00010000
|
||||||
@ -97,7 +97,7 @@ typedef struct {
|
|||||||
u64 size_lvl3;
|
u64 size_lvl3;
|
||||||
u32 log_lvl3;
|
u32 log_lvl3;
|
||||||
u8 padding2[4];
|
u8 padding2[4];
|
||||||
} __attribute__((packed)) DpfsDescriptor;
|
} PACKED_STRUCT DpfsDescriptor;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
DifiHeader difi;
|
DifiHeader difi;
|
||||||
@ -105,7 +105,7 @@ typedef struct {
|
|||||||
DpfsDescriptor dpfs;
|
DpfsDescriptor dpfs;
|
||||||
u8 hash[0x20];
|
u8 hash[0x20];
|
||||||
u8 padding[4]; // all zeroes when encrypted
|
u8 padding[4]; // all zeroes when encrypted
|
||||||
} __attribute__((packed)) DifiStruct;
|
} PACKED_STRUCT DifiStruct;
|
||||||
|
|
||||||
// condensed info to enable reading IVFC lvl4
|
// condensed info to enable reading IVFC lvl4
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -122,7 +122,7 @@ typedef struct {
|
|||||||
u8 dpfs_lvl1_selector;
|
u8 dpfs_lvl1_selector;
|
||||||
u8 ivfc_use_extlvl4;
|
u8 ivfc_use_extlvl4;
|
||||||
u8* dpfs_lvl2_cache; // optional, NULL when unused
|
u8* dpfs_lvl2_cache; // optional, NULL when unused
|
||||||
} __attribute__((packed)) DisaDiffReaderInfo;
|
} PACKED_STRUCT DisaDiffReaderInfo;
|
||||||
|
|
||||||
u32 GetDisaDiffReaderInfo(const char* path, DisaDiffReaderInfo* info, bool partitionB);
|
u32 GetDisaDiffReaderInfo(const char* path, DisaDiffReaderInfo* info, bool partitionB);
|
||||||
u32 BuildDisaDiffDpfsLvl2Cache(const char* path, DisaDiffReaderInfo* info, u8* cache, u32 cache_size);
|
u32 BuildDisaDiffDpfsLvl2Cache(const char* path, DisaDiffReaderInfo* info, u8* cache, u32 cache_size);
|
||||||
|
@ -6,7 +6,7 @@ typedef struct {
|
|||||||
char name[8];
|
char name[8];
|
||||||
u32 offset;
|
u32 offset;
|
||||||
u32 size;
|
u32 size;
|
||||||
} __attribute__((packed)) ExeFsFileHeader;
|
} PACKED_STRUCT ExeFsFileHeader;
|
||||||
|
|
||||||
// see: https://www.3dbrew.org/wiki/ExeFS
|
// see: https://www.3dbrew.org/wiki/ExeFS
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -28,7 +28,7 @@ typedef struct {
|
|||||||
u32 size;
|
u32 size;
|
||||||
u32 method;
|
u32 method;
|
||||||
u8 hash[0x20];
|
u8 hash[0x20];
|
||||||
} __attribute__((packed)) FirmSectionHeader;
|
} PACKED_STRUCT FirmSectionHeader;
|
||||||
|
|
||||||
// see: https://www.3dbrew.org/wiki/FIRM#FIRM_Header
|
// see: https://www.3dbrew.org/wiki/FIRM#FIRM_Header
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -51,7 +51,7 @@ typedef struct {
|
|||||||
u8 unknown2[44];
|
u8 unknown2[44];
|
||||||
u8 magic[4]; // ".CAA"
|
u8 magic[4]; // ".CAA"
|
||||||
u8 unknown3[12];
|
u8 unknown3[12];
|
||||||
} __attribute__((packed)) AgbVcFooter;
|
} PACKED_STRUCT AgbVcFooter;
|
||||||
|
|
||||||
// see: http://3dbrew.org/wiki/3DS_Virtual_Console#NAND_Savegame
|
// see: http://3dbrew.org/wiki/3DS_Virtual_Console#NAND_Savegame
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -69,7 +69,7 @@ typedef struct {
|
|||||||
u32 unknown1; // has to do with ARM7?
|
u32 unknown1; // has to do with ARM7?
|
||||||
u32 unknown2; // has to do with ARM7?
|
u32 unknown2; // has to do with ARM7?
|
||||||
u8 reserved3[0x198]; // always 0xFF
|
u8 reserved3[0x198]; // always 0xFF
|
||||||
} __attribute__((packed)) AgbSaveHeader;
|
} PACKED_STRUCT AgbSaveHeader;
|
||||||
|
|
||||||
// see: http://problemkaputt.de/gbatek.htm#gbacartridgeheader
|
// see: http://problemkaputt.de/gbatek.htm#gbacartridgeheader
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -93,13 +93,13 @@ typedef struct {
|
|||||||
u64 titleId;
|
u64 titleId;
|
||||||
u8 seed[16];
|
u8 seed[16];
|
||||||
u8 reserved[8];
|
u8 reserved[8];
|
||||||
} __attribute__((packed)) SeedInfoEntry;
|
} PACKED_STRUCT SeedInfoEntry;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u32 n_entries;
|
u32 n_entries;
|
||||||
u8 padding[12];
|
u8 padding[12];
|
||||||
SeedInfoEntry entries[256]; // this number is only a placeholder
|
SeedInfoEntry entries[256]; // this number is only a placeholder
|
||||||
} __attribute__((packed)) SeedInfo;
|
} PACKED_STRUCT SeedInfo;
|
||||||
|
|
||||||
u32 ValidateNcchHeader(NcchHeader* header);
|
u32 ValidateNcchHeader(NcchHeader* header);
|
||||||
u32 SetNcchKey(NcchHeader* ncch, u16 crypto, u32 keyid);
|
u32 SetNcchKey(NcchHeader* ncch, u16 crypto, u32 keyid);
|
||||||
|
@ -16,7 +16,7 @@ typedef struct {
|
|||||||
u32 ncchFlag3;
|
u32 ncchFlag3;
|
||||||
u64 titleId;
|
u64 titleId;
|
||||||
char filename[112];
|
char filename[112];
|
||||||
} __attribute__((packed)) NcchInfoEntry;
|
} PACKED_STRUCT NcchInfoEntry;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u32 padding;
|
u32 padding;
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
u32 offset;
|
u32 offset;
|
||||||
u32 size;
|
u32 size;
|
||||||
} __attribute__((packed)) NcchPartition;
|
} PACKED_STRUCT NcchPartition;
|
||||||
|
|
||||||
// see: https://www.3dbrew.org/wiki/NCSD#NCSD_header
|
// see: https://www.3dbrew.org/wiki/NCSD#NCSD_header
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -34,7 +34,7 @@ typedef struct {
|
|||||||
u8 partition_flags[8];
|
u8 partition_flags[8];
|
||||||
u8 partitionId_table[8][8];
|
u8 partitionId_table[8][8];
|
||||||
u8 reserved[0x30];
|
u8 reserved[0x30];
|
||||||
} __attribute__((packed)) NcsdHeader;
|
} PACKED_STRUCT NcsdHeader;
|
||||||
|
|
||||||
u32 ValidateNcsdHeader(NcsdHeader* header);
|
u32 ValidateNcsdHeader(NcsdHeader* header);
|
||||||
u64 GetNcsdTrimmedSize(NcsdHeader* header);
|
u64 GetNcsdTrimmedSize(NcsdHeader* header);
|
||||||
|
@ -13,12 +13,12 @@ typedef struct {
|
|||||||
u32 subtable_offset;
|
u32 subtable_offset;
|
||||||
u16 file0_id;
|
u16 file0_id;
|
||||||
u16 parent_id; // total # of dirs for root entry
|
u16 parent_id; // total # of dirs for root entry
|
||||||
} __attribute__((packed)) NitroFntBaseEntry;
|
} PACKED_ALIGN(1) NitroFntBaseEntry;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u32 start_address;
|
u32 start_address;
|
||||||
u32 end_address;
|
u32 end_address;
|
||||||
} __attribute__((packed)) NitroFatEntry;
|
} PACKED_ALIGN(1) NitroFatEntry;
|
||||||
|
|
||||||
|
|
||||||
u32 ValidateTwlHeader(TwlHeader* twl) {
|
u32 ValidateTwlHeader(TwlHeader* twl) {
|
||||||
@ -27,8 +27,8 @@ u32 ValidateTwlHeader(TwlHeader* twl) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
u32 LoadTwlMetaData(const char* path, TwlHeader* hdr, TwlIconData* icon) {
|
u32 LoadTwlMetaData(const char* path, TwlHeader* hdr, TwlIconData* icon) {
|
||||||
u8 ntr_header[0x200]; // we only need the NTR header (ignore TWL stuff)
|
u8 ALIGN(32) ntr_header[0x200]; // we only need the NTR header (ignore TWL stuff)
|
||||||
TwlHeader* twl = hdr ? hdr : (TwlHeader*) ntr_header;
|
TwlHeader* twl = hdr ? hdr : (void*) ntr_header;
|
||||||
u32 hdr_size = hdr ? sizeof(TwlHeader) : 0x200; // load full header if buffer provided
|
u32 hdr_size = hdr ? sizeof(TwlHeader) : 0x200; // load full header if buffer provided
|
||||||
UINT br;
|
UINT br;
|
||||||
if ((fvx_qread(path, twl, 0, hdr_size, &br) != FR_OK) || (br != hdr_size) ||
|
if ((fvx_qread(path, twl, 0, hdr_size, &br) != FR_OK) || (br != hdr_size) ||
|
||||||
|
@ -45,7 +45,7 @@ typedef struct {
|
|||||||
u8 icon_anim[0x200 * 0x8]; // 32x32x4bpp / 8 frames
|
u8 icon_anim[0x200 * 0x8]; // 32x32x4bpp / 8 frames
|
||||||
u16 palette_anim[0x10 * 0x8]; // 8 frames
|
u16 palette_anim[0x10 * 0x8]; // 8 frames
|
||||||
u16 sequence_anim[0x40];
|
u16 sequence_anim[0x40];
|
||||||
} __attribute__((packed)) TwlIconData;
|
} PACKED_STRUCT TwlIconData;
|
||||||
|
|
||||||
// very limited, information taken from here:
|
// very limited, information taken from here:
|
||||||
// https://github.com/devkitPro/ndstool/blob/dsi-support/source/header.h
|
// https://github.com/devkitPro/ndstool/blob/dsi-support/source/header.h
|
||||||
@ -121,7 +121,7 @@ typedef struct {
|
|||||||
u8 reserved3[176];
|
u8 reserved3[176];
|
||||||
u8 unknown3[0x10];
|
u8 unknown3[0x10];
|
||||||
u8 ignored4[0xD00]; // ignored
|
u8 ignored4[0xD00]; // ignored
|
||||||
} __attribute__((packed)) TwlHeader;
|
} PACKED_STRUCT TwlHeader;
|
||||||
|
|
||||||
u32 ValidateTwlHeader(TwlHeader* twl);
|
u32 ValidateTwlHeader(TwlHeader* twl);
|
||||||
u32 LoadTwlMetaData(const char* path, TwlHeader* hdr, TwlIconData* icon);
|
u32 LoadTwlMetaData(const char* path, TwlHeader* hdr, TwlIconData* icon);
|
||||||
|
@ -51,7 +51,7 @@ u32 ValidateLv3Header(RomFsLv3Header* lv3, u32 max_size) {
|
|||||||
|
|
||||||
// build index of RomFS lvl3
|
// build index of RomFS lvl3
|
||||||
u32 BuildLv3Index(RomFsLv3Index* index, u8* lv3) {
|
u32 BuildLv3Index(RomFsLv3Index* index, u8* lv3) {
|
||||||
RomFsLv3Header* hdr = (RomFsLv3Header*) lv3;
|
RomFsLv3Header* hdr = (void*)lv3;
|
||||||
index->header = hdr;
|
index->header = hdr;
|
||||||
index->dirhash = (u32*) (void*) (lv3 + hdr->offset_dirhash);
|
index->dirhash = (u32*) (void*) (lv3 + hdr->offset_dirhash);
|
||||||
index->dirmeta = lv3 + hdr->offset_dirmeta;
|
index->dirmeta = lv3 + hdr->offset_dirmeta;
|
||||||
@ -90,7 +90,7 @@ RomFsLv3DirMeta* GetLv3DirMeta(const char* name, u32 offset_parent, RomFsLv3Inde
|
|||||||
// process the hashbucket (make sure we got the correct data)
|
// process the hashbucket (make sure we got the correct data)
|
||||||
// slim chance of endless loop with broken lvl3 here
|
// slim chance of endless loop with broken lvl3 here
|
||||||
for (; offset < index->size_dirmeta; offset = meta->offset_samehash) {
|
for (; offset < index->size_dirmeta; offset = meta->offset_samehash) {
|
||||||
meta = (RomFsLv3DirMeta*) (index->dirmeta + offset);
|
meta = (void*)(index->dirmeta + offset);
|
||||||
if ((offset_parent == meta->offset_parent) &&
|
if ((offset_parent == meta->offset_parent) &&
|
||||||
((u32) name_len == meta->name_len / 2) &&
|
((u32) name_len == meta->name_len / 2) &&
|
||||||
(memcmp(wname, meta->wname, name_len * 2) == 0))
|
(memcmp(wname, meta->wname, name_len * 2) == 0))
|
||||||
@ -115,7 +115,7 @@ RomFsLv3FileMeta* GetLv3FileMeta(const char* name, u32 offset_parent, RomFsLv3In
|
|||||||
// process the hashbucket (make sure we got the correct data)
|
// process the hashbucket (make sure we got the correct data)
|
||||||
// slim chance of endless loop with broken lvl3 here
|
// slim chance of endless loop with broken lvl3 here
|
||||||
for (; offset < index->size_filemeta; offset = meta->offset_samehash) {
|
for (; offset < index->size_filemeta; offset = meta->offset_samehash) {
|
||||||
meta = (RomFsLv3FileMeta*) (index->filemeta + offset);
|
meta = (void*)(index->filemeta + offset);
|
||||||
if ((offset_parent == meta->offset_parent) &&
|
if ((offset_parent == meta->offset_parent) &&
|
||||||
((u32) name_len == meta->name_len / 2) &&
|
((u32) name_len == meta->name_len / 2) &&
|
||||||
(memcmp(wname, meta->wname, name_len * 2) == 0))
|
(memcmp(wname, meta->wname, name_len * 2) == 0))
|
||||||
|
@ -44,7 +44,7 @@ typedef struct {
|
|||||||
u32 unknown0;
|
u32 unknown0;
|
||||||
u32 unknown1;
|
u32 unknown1;
|
||||||
u8 padding[4]; // masterhash follows
|
u8 padding[4]; // masterhash follows
|
||||||
} __attribute__((packed)) RomFsIvfcHeader;
|
} PACKED_STRUCT RomFsIvfcHeader;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u32 size_header;
|
u32 size_header;
|
||||||
@ -57,7 +57,7 @@ typedef struct {
|
|||||||
u32 offset_filemeta;
|
u32 offset_filemeta;
|
||||||
u32 size_filemeta;
|
u32 size_filemeta;
|
||||||
u32 offset_filedata;
|
u32 offset_filedata;
|
||||||
} __attribute__((packed)) RomFsLv3Header;
|
} PACKED_STRUCT RomFsLv3Header;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u32 offset_parent;
|
u32 offset_parent;
|
||||||
@ -67,7 +67,7 @@ typedef struct {
|
|||||||
u32 offset_samehash;
|
u32 offset_samehash;
|
||||||
u32 name_len;
|
u32 name_len;
|
||||||
u16 wname[256]; // 256 assumed to be max name length
|
u16 wname[256]; // 256 assumed to be max name length
|
||||||
} __attribute__((packed)) RomFsLv3DirMeta;
|
} PACKED_STRUCT RomFsLv3DirMeta;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u32 offset_parent;
|
u32 offset_parent;
|
||||||
@ -77,7 +77,7 @@ typedef struct {
|
|||||||
u32 offset_samehash;
|
u32 offset_samehash;
|
||||||
u32 name_len;
|
u32 name_len;
|
||||||
u16 wname[256]; // 256 assumed to be max name length
|
u16 wname[256]; // 256 assumed to be max name length
|
||||||
} __attribute__((packed)) RomFsLv3FileMeta;
|
} PACKED_STRUCT RomFsLv3FileMeta;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
RomFsLv3Header* header;
|
RomFsLv3Header* header;
|
||||||
@ -90,7 +90,7 @@ typedef struct {
|
|||||||
u32 mod_file;
|
u32 mod_file;
|
||||||
u32 size_dirmeta;
|
u32 size_dirmeta;
|
||||||
u32 size_filemeta;
|
u32 size_filemeta;
|
||||||
} __attribute__((packed)) RomFsLv3Index;
|
} PACKED_STRUCT RomFsLv3Index;
|
||||||
|
|
||||||
|
|
||||||
u64 GetRomFsLvOffset(RomFsIvfcHeader* ivfc, u32 lvl);
|
u64 GetRomFsLvOffset(RomFsIvfcHeader* ivfc, u32 lvl);
|
||||||
|
@ -17,7 +17,7 @@ typedef struct {
|
|||||||
u16 short_desc[0x40];
|
u16 short_desc[0x40];
|
||||||
u16 long_desc[0x80];
|
u16 long_desc[0x80];
|
||||||
u16 publisher[0x40];
|
u16 publisher[0x40];
|
||||||
} __attribute__((packed)) SmdhAppTitle;
|
} PACKED_STRUCT SmdhAppTitle;
|
||||||
|
|
||||||
// see: https://www.3dbrew.org/wiki/SMDH
|
// see: https://www.3dbrew.org/wiki/SMDH
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -37,7 +37,7 @@ typedef struct {
|
|||||||
u64 reserved2;
|
u64 reserved2;
|
||||||
u16 icon_small[0x240]; // 24x24x16bpp / 8x8 tiles / rgb565
|
u16 icon_small[0x240]; // 24x24x16bpp / 8x8 tiles / rgb565
|
||||||
u16 icon_big[0x900]; // 48x48x16bpp / 8x8 tiles / rgb565
|
u16 icon_big[0x900]; // 48x48x16bpp / 8x8 tiles / rgb565
|
||||||
} __attribute__((packed)) Smdh;
|
} PACKED_STRUCT Smdh;
|
||||||
|
|
||||||
u32 GetSmdhDescShort(char* desc, const Smdh* smdh);
|
u32 GetSmdhDescShort(char* desc, const Smdh* smdh);
|
||||||
u32 GetSmdhDescLong(char* desc, const Smdh* smdh);
|
u32 GetSmdhDescLong(char* desc, const Smdh* smdh);
|
||||||
|
@ -16,19 +16,19 @@ typedef struct {
|
|||||||
u32 header_end;
|
u32 header_end;
|
||||||
u32 footer_end;
|
u32 footer_end;
|
||||||
u32 content_end[TAD_NUM_CONTENT];
|
u32 content_end[TAD_NUM_CONTENT];
|
||||||
} __attribute__((packed)) TadContentTable;
|
} PACKED_STRUCT TadContentTable;
|
||||||
|
|
||||||
// see: https://www.3dbrew.org/wiki/DSiWare_Exports#Block_Metadata
|
// see: https://www.3dbrew.org/wiki/DSiWare_Exports#Block_Metadata
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u8 cmac[16];
|
u8 cmac[16];
|
||||||
u8 iv0[16];
|
u8 iv0[16];
|
||||||
} __attribute__((packed)) TadBlockMetaData;
|
} PACKED_STRUCT TadBlockMetaData;
|
||||||
|
|
||||||
// see: https://www.3dbrew.org/wiki/DSiWare_Exports#File_Structure_v2
|
// see: https://www.3dbrew.org/wiki/DSiWare_Exports#File_Structure_v2
|
||||||
typedef struct {
|
typedef struct {
|
||||||
TwlIconData icon_data;
|
TwlIconData icon_data;
|
||||||
u8 unknown[0x4000 - sizeof(TwlIconData)];
|
u8 unknown[0x4000 - sizeof(TwlIconData)];
|
||||||
} __attribute__((packed)) TadBanner;
|
} PACKED_STRUCT TadBanner;
|
||||||
|
|
||||||
// see: https://www.3dbrew.org/wiki/DSiWare_Exports#Header_2
|
// see: https://www.3dbrew.org/wiki/DSiWare_Exports#Header_2
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -43,7 +43,7 @@ typedef struct {
|
|||||||
u8 unknown1[0x30];
|
u8 unknown1[0x30];
|
||||||
u8 tmd_reserved[0x3E];
|
u8 tmd_reserved[0x3E];
|
||||||
u8 padding[0x0E];
|
u8 padding[0x0E];
|
||||||
} __attribute__((packed)) TadHeader;
|
} PACKED_STRUCT TadHeader;
|
||||||
|
|
||||||
// see: https://www.3dbrew.org/wiki/DSiWare_Exports#Footer
|
// see: https://www.3dbrew.org/wiki/DSiWare_Exports#Footer
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -54,6 +54,6 @@ typedef struct {
|
|||||||
u8 ecdsa_apcert[0x180];
|
u8 ecdsa_apcert[0x180];
|
||||||
u8 ecdsa_ctcert[0x180];
|
u8 ecdsa_ctcert[0x180];
|
||||||
u8 padding[0x4];
|
u8 padding[0x4];
|
||||||
} __attribute__((packed)) TadFooter;
|
} PACKED_STRUCT TadFooter;
|
||||||
|
|
||||||
u32 BuildTadContentTable(void* table, void* header);
|
u32 BuildTadContentTable(void* table, void* header);
|
||||||
|
@ -25,13 +25,13 @@ typedef struct {
|
|||||||
u8 reserved[4];
|
u8 reserved[4];
|
||||||
u8 title_id[8];
|
u8 title_id[8];
|
||||||
u8 titlekey[16];
|
u8 titlekey[16];
|
||||||
} __attribute__((packed)) TitleKeyEntry;
|
} PACKED_STRUCT TitleKeyEntry;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u32 n_entries;
|
u32 n_entries;
|
||||||
u8 reserved[12];
|
u8 reserved[12];
|
||||||
TitleKeyEntry entries[256]; // this number is only a placeholder
|
TitleKeyEntry entries[256]; // this number is only a placeholder
|
||||||
} __attribute__((packed)) TitleKeysInfo;
|
} PACKED_STRUCT TitleKeysInfo;
|
||||||
|
|
||||||
|
|
||||||
u32 GetTitleKey(u8* titlekey, Ticket* ticket);
|
u32 GetTitleKey(u8* titlekey, Ticket* ticket);
|
||||||
|
@ -24,7 +24,7 @@ typedef struct {
|
|||||||
u64 cart_size;
|
u64 cart_size;
|
||||||
u64 data_size;
|
u64 data_size;
|
||||||
u32 unused_offset;
|
u32 unused_offset;
|
||||||
} __attribute__((packed, aligned(16))) CartDataCtr;
|
} PACKED_ALIGN(16) CartDataCtr;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
TwlHeader ntr_header;
|
TwlHeader ntr_header;
|
||||||
@ -38,15 +38,15 @@ typedef struct {
|
|||||||
u64 cart_size;
|
u64 cart_size;
|
||||||
u64 data_size;
|
u64 data_size;
|
||||||
u32 arm9i_rom_offset;
|
u32 arm9i_rom_offset;
|
||||||
} __attribute__((packed, aligned(16))) CartDataNtrTwl;
|
} PACKED_ALIGN(16) CartDataNtrTwl;
|
||||||
|
|
||||||
u32 GetCartName(char* name, CartData* cdata) {
|
u32 GetCartName(char* name, CartData* cdata) {
|
||||||
if (cdata->cart_type & CART_CTR) {
|
if (cdata->cart_type & CART_CTR) {
|
||||||
CartDataCtr* cdata_i = (CartDataCtr*)(void*) cdata;
|
CartDataCtr* cdata_i = (CartDataCtr*)cdata;
|
||||||
NcsdHeader* ncsd = &(cdata_i->ncsd);
|
NcsdHeader* ncsd = &(cdata_i->ncsd);
|
||||||
snprintf(name, 24, "%016llX_v%02lu", ncsd->mediaId, cdata_i->rom_version);
|
snprintf(name, 24, "%016llX_v%02lu", ncsd->mediaId, cdata_i->rom_version);
|
||||||
} else if (cdata->cart_type & CART_NTR) {
|
} else if (cdata->cart_type & CART_NTR) {
|
||||||
CartDataNtrTwl* cdata_i = (CartDataNtrTwl*)(void*) cdata;
|
CartDataNtrTwl* cdata_i = (CartDataNtrTwl*)cdata;
|
||||||
TwlHeader* nds = &(cdata_i->ntr_header);
|
TwlHeader* nds = &(cdata_i->ntr_header);
|
||||||
snprintf(name, 24, "%.12s_%.6s_%02u", nds->game_title, nds->game_code, nds->rom_version);
|
snprintf(name, 24, "%.12s_%.6s_%02u", nds->game_title, nds->game_code, nds->rom_version);
|
||||||
} else return 1;
|
} else return 1;
|
||||||
@ -95,7 +95,7 @@ u32 InitCardRead(CartData* cdata) {
|
|||||||
memset(priv_header + 0x48, 0xFF, 8);
|
memset(priv_header + 0x48, 0xFF, 8);
|
||||||
} else {
|
} else {
|
||||||
// NTR header
|
// NTR header
|
||||||
TwlHeader* nds_header = (TwlHeader*) cdata->header;
|
TwlHeader* nds_header = (void*)cdata->header;
|
||||||
NTR_CmdReadHeader(cdata->header);
|
NTR_CmdReadHeader(cdata->header);
|
||||||
if (!(*(cdata->header))) return 1; // error reading the header
|
if (!(*(cdata->header))) return 1; // error reading the header
|
||||||
if (!NTR_Secure_Init(cdata->header, Cart_GetID(), 0)) return 1;
|
if (!NTR_Secure_Init(cdata->header, Cart_GetID(), 0)) return 1;
|
||||||
|
@ -18,7 +18,7 @@ typedef struct {
|
|||||||
u64 cart_size;
|
u64 cart_size;
|
||||||
u64 data_size;
|
u64 data_size;
|
||||||
u32 arm9i_rom_offset; // TWL specific
|
u32 arm9i_rom_offset; // TWL specific
|
||||||
} __attribute__((packed)) CartData;
|
} PACKED_ALIGN(16) CartData;
|
||||||
|
|
||||||
u32 GetCartName(char* name, CartData* cdata);
|
u32 GetCartName(char* name, CartData* cdata);
|
||||||
u32 InitCardRead(CartData* cdata);
|
u32 InitCardRead(CartData* cdata);
|
||||||
|
@ -17,7 +17,7 @@ typedef struct {
|
|||||||
u8 signature[0x100];
|
u8 signature[0x100];
|
||||||
u8 unknown[0x8]; // normally zero
|
u8 unknown[0x8]; // normally zero
|
||||||
u8 codeseed[0x8]; // the actual data
|
u8 codeseed[0x8]; // the actual data
|
||||||
} __attribute__((packed, aligned(4))) LocalFriendCodeSeed;
|
} PACKED_STRUCT LocalFriendCodeSeed;
|
||||||
|
|
||||||
// /private/movable.sed file
|
// /private/movable.sed file
|
||||||
// see: http://3dbrew.org/wiki/Nand/private/movable.sed
|
// see: http://3dbrew.org/wiki/Nand/private/movable.sed
|
||||||
@ -28,7 +28,7 @@ typedef struct {
|
|||||||
u8 keyy_high[8];
|
u8 keyy_high[8];
|
||||||
u8 unknown[0x10];
|
u8 unknown[0x10];
|
||||||
u8 cmac[0x10];
|
u8 cmac[0x10];
|
||||||
} __attribute__((packed, aligned(4))) MovableSed;
|
} PACKED_STRUCT MovableSed;
|
||||||
|
|
||||||
// /rw/sys/SecureInfo_A (/_B) file
|
// /rw/sys/SecureInfo_A (/_B) file
|
||||||
// see: http://3dbrew.org/wiki/Nandrw/sys/SecureInfo_A
|
// see: http://3dbrew.org/wiki/Nandrw/sys/SecureInfo_A
|
||||||
@ -37,7 +37,7 @@ typedef struct {
|
|||||||
u8 region;
|
u8 region;
|
||||||
u8 unknown;
|
u8 unknown;
|
||||||
char serial[0xF];
|
char serial[0xF];
|
||||||
} __attribute__((packed, aligned(4))) SecureInfo;
|
} PACKED_STRUCT SecureInfo;
|
||||||
|
|
||||||
// includes all essential system files
|
// includes all essential system files
|
||||||
// (this is of our own making)
|
// (this is of our own making)
|
||||||
@ -58,4 +58,4 @@ typedef struct {
|
|||||||
u8 padding_hwcal0[0x200 - (SIZE_HWCAL%0x200)];
|
u8 padding_hwcal0[0x200 - (SIZE_HWCAL%0x200)];
|
||||||
u8 hwcal1[SIZE_HWCAL];
|
u8 hwcal1[SIZE_HWCAL];
|
||||||
u8 padding_hwcal1[0x200 - (SIZE_HWCAL%0x200)];
|
u8 padding_hwcal1[0x200 - (SIZE_HWCAL%0x200)];
|
||||||
} __attribute__((packed, aligned(16))) EssentialBackup;
|
} PACKED_ALIGN(16) EssentialBackup;
|
||||||
|
@ -505,24 +505,24 @@ u32 GetNandPartitionInfo(NandPartitionInfo* info, u32 type, u32 subtype, u32 ind
|
|||||||
// workaround for info == NULL
|
// workaround for info == NULL
|
||||||
NandPartitionInfo dummy;
|
NandPartitionInfo dummy;
|
||||||
if (!info) info = &dummy;
|
if (!info) info = &dummy;
|
||||||
|
|
||||||
// workaround for ZERONAND
|
// workaround for ZERONAND
|
||||||
if (nand_src == NAND_ZERONAND) nand_src = NAND_SYSNAND;
|
if (nand_src == NAND_ZERONAND) nand_src = NAND_SYSNAND;
|
||||||
|
|
||||||
// find type & subtype in NCSD header
|
// find type & subtype in NCSD header
|
||||||
u8 header[0x200];
|
u8 ALIGN(8) header[0x200];
|
||||||
ReadNandSectors(header, 0x00, 1, 0xFF, nand_src);
|
ReadNandSectors(header, 0x00, 1, 0xFF, nand_src);
|
||||||
NandNcsdHeader* ncsd = (NandNcsdHeader*) header;
|
NandNcsdHeader* ncsd = (void*)header;
|
||||||
if ((ValidateNandNcsdHeader(ncsd) != 0) ||
|
if ((ValidateNandNcsdHeader(ncsd) != 0) ||
|
||||||
((type == NP_TYPE_FAT) && (GetNandNcsdPartitionInfo(info, NP_TYPE_STD, subtype, 0, ncsd) != 0)) ||
|
((type == NP_TYPE_FAT) && (GetNandNcsdPartitionInfo(info, NP_TYPE_STD, subtype, 0, ncsd) != 0)) ||
|
||||||
((type != NP_TYPE_FAT) && (GetNandNcsdPartitionInfo(info, type, subtype, index, ncsd) != 0)))
|
((type != NP_TYPE_FAT) && (GetNandNcsdPartitionInfo(info, type, subtype, index, ncsd) != 0)))
|
||||||
return 1; // not found
|
return 1; // not found
|
||||||
|
|
||||||
if (type == NP_TYPE_BONUS) { // size of bonus partition
|
if (type == NP_TYPE_BONUS) { // size of bonus partition
|
||||||
info->count = GetNandSizeSectors(nand_src) - info->sector;
|
info->count = GetNandSizeSectors(nand_src) - info->sector;
|
||||||
} else if (type == NP_TYPE_FAT) { // FAT type specific stuff
|
} else if (type == NP_TYPE_FAT) { // FAT type specific stuff
|
||||||
ReadNandSectors(header, info->sector, 1, info->keyslot, nand_src);
|
ReadNandSectors(header, info->sector, 1, info->keyslot, nand_src);
|
||||||
MbrHeader* mbr = (MbrHeader*) header;
|
MbrHeader* mbr = (void*)header;
|
||||||
if ((ValidateMbrHeader(mbr) != 0) || (index >= 4) ||
|
if ((ValidateMbrHeader(mbr) != 0) || (index >= 4) ||
|
||||||
(mbr->partitions[index].sector == 0) || (mbr->partitions[index].count == 0) ||
|
(mbr->partitions[index].sector == 0) || (mbr->partitions[index].count == 0) ||
|
||||||
(mbr->partitions[index].sector + mbr->partitions[index].count > info->count))
|
(mbr->partitions[index].sector + mbr->partitions[index].count > info->count))
|
||||||
@ -530,7 +530,7 @@ u32 GetNandPartitionInfo(NandPartitionInfo* info, u32 type, u32 subtype, u32 ind
|
|||||||
info->sector += mbr->partitions[index].sector;
|
info->sector += mbr->partitions[index].sector;
|
||||||
info->count = mbr->partitions[index].count;
|
info->count = mbr->partitions[index].count;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,12 +49,12 @@ typedef struct {
|
|||||||
u32 sector;
|
u32 sector;
|
||||||
u32 count;
|
u32 count;
|
||||||
u32 keyslot;
|
u32 keyslot;
|
||||||
} __attribute__((packed)) NandPartitionInfo;
|
} PACKED_STRUCT NandPartitionInfo;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u32 offset;
|
u32 offset;
|
||||||
u32 size;
|
u32 size;
|
||||||
} __attribute__((packed)) NandNcsdPartition;
|
} PACKED_STRUCT NandNcsdPartition;
|
||||||
|
|
||||||
// see: https://www.3dbrew.org/wiki/NCSD#NCSD_header
|
// see: https://www.3dbrew.org/wiki/NCSD#NCSD_header
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -67,7 +67,7 @@ typedef struct {
|
|||||||
NandNcsdPartition partitions[8];
|
NandNcsdPartition partitions[8];
|
||||||
u8 unknown[0x5E];
|
u8 unknown[0x5E];
|
||||||
u8 twl_mbr[0x42];
|
u8 twl_mbr[0x42];
|
||||||
} __attribute__((packed)) NandNcsdHeader;
|
} PACKED_STRUCT NandNcsdHeader;
|
||||||
|
|
||||||
|
|
||||||
bool InitNandCrypto(bool init_full);
|
bool InitNandCrypto(bool init_full);
|
||||||
|
@ -26,7 +26,7 @@ typedef struct {
|
|||||||
char dev_minor[8];
|
char dev_minor[8];
|
||||||
char fname_prefix[155];
|
char fname_prefix[155];
|
||||||
char unused[12];
|
char unused[12];
|
||||||
} __attribute__((packed)) TarHeader;
|
} PACKED_STRUCT TarHeader;
|
||||||
|
|
||||||
|
|
||||||
u32 ValidateTarHeader(void* tardata, void* tardata_end);
|
u32 ValidateTarHeader(void* tardata, void* tardata_end);
|
||||||
|
@ -120,7 +120,7 @@ u32 EmbedEssentialBackup(const char* path) {
|
|||||||
|
|
||||||
// leaving out the write permissions check here, it's okay
|
// leaving out the write permissions check here, it's okay
|
||||||
if ((BuildEssentialBackup(path, essential) != 0) ||
|
if ((BuildEssentialBackup(path, essential) != 0) ||
|
||||||
(ValidateNandNcsdHeader((NandNcsdHeader*) essential->nand_hdr) != 0) ||
|
(ValidateNandNcsdHeader((void*)essential->nand_hdr) != 0) ||
|
||||||
(fvx_qwrite(path, essential, SECTOR_D0K3 * 0x200, sizeof(EssentialBackup), NULL) != FR_OK)) {
|
(fvx_qwrite(path, essential, SECTOR_D0K3 * 0x200, sizeof(EssentialBackup), NULL) != FR_OK)) {
|
||||||
free(essential);
|
free(essential);
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -678,8 +678,8 @@ bool BuildVGameTadDir(void) {
|
|||||||
u32 n = 0;
|
u32 n = 0;
|
||||||
|
|
||||||
// read header, setup table
|
// read header, setup table
|
||||||
u8 hdr_data[TAD_HEADER_LEN];
|
u8 ALIGN(32) hdr_data[TAD_HEADER_LEN];
|
||||||
TadHeader* hdr = (TadHeader*) hdr_data;
|
TadHeader* hdr = (void*)hdr_data;
|
||||||
TadContentTable tbl;
|
TadContentTable tbl;
|
||||||
ReadGameImageBytes(hdr_data, TAD_HEADER_OFFSET, TAD_HEADER_LEN);
|
ReadGameImageBytes(hdr_data, TAD_HEADER_OFFSET, TAD_HEADER_LEN);
|
||||||
if (BuildTadContentTable(&tbl, hdr_data) != 0) {
|
if (BuildTadContentTable(&tbl, hdr_data) != 0) {
|
||||||
@ -772,18 +772,18 @@ u64 InitVGameDrive(void) { // prerequisite: game file mounted as image
|
|||||||
(type & GAME_NDS ) ? VFLAG_NDS :
|
(type & GAME_NDS ) ? VFLAG_NDS :
|
||||||
(type & GAME_TAD ) ? VFLAG_TAD : 0;
|
(type & GAME_TAD ) ? VFLAG_TAD : 0;
|
||||||
if (!base_vdir) return 0;
|
if (!base_vdir) return 0;
|
||||||
|
|
||||||
// set up vgame buffer
|
// set up vgame buffer
|
||||||
vgame_buffer = (void*) malloc(0x40000);
|
vgame_buffer = (void*) malloc(0x40000);
|
||||||
if (!vgame_buffer) return 0;
|
if (!vgame_buffer) return 0;
|
||||||
|
|
||||||
templates_cia = (VirtualFile*) ((u8*) vgame_buffer); // first 184kb reserved (enough for 3364 entries)
|
templates_cia = (void*) ((u8*) vgame_buffer); // first 184kb reserved (enough for 3364 entries)
|
||||||
templates_firm = (VirtualFile*) (((u8*) vgame_buffer) + 0x2E000); // 2kb reserved (enough for 36 entries)
|
templates_firm = (void*) (((u8*) vgame_buffer) + 0x2E000); // 2kb reserved (enough for 36 entries)
|
||||||
templates_ncsd = (VirtualFile*) (((u8*) vgame_buffer) + 0x2E800); // 2kb reserved (enough for 36 entries)
|
templates_ncsd = (void*) (((u8*) vgame_buffer) + 0x2E800); // 2kb reserved (enough for 36 entries)
|
||||||
templates_ncch = (VirtualFile*) (((u8*) vgame_buffer) + 0x2F000); // 1kb reserved (enough for 18 entries)
|
templates_ncch = (void*) (((u8*) vgame_buffer) + 0x2F000); // 1kb reserved (enough for 18 entries)
|
||||||
templates_nds = (VirtualFile*) (((u8*) vgame_buffer) + 0x2F400); // 1kb reserved (enough for 18 entries)
|
templates_nds = (void*) (((u8*) vgame_buffer) + 0x2F400); // 1kb reserved (enough for 18 entries)
|
||||||
templates_exefs = (VirtualFile*) (((u8*) vgame_buffer) + 0x2F800); // 1kb reserved (enough for 18 entries)
|
templates_exefs = (void*) (((u8*) vgame_buffer) + 0x2F800); // 1kb reserved (enough for 18 entries)
|
||||||
templates_tad = (VirtualFile*) (((u8*) vgame_buffer) + 0x2FC00); // 1kb reserved (enough for 18 entries)
|
templates_tad = (void*) (((u8*) vgame_buffer) + 0x2FC00); // 1kb reserved (enough for 18 entries)
|
||||||
cia = (CiaStub*) (void*) (((u8*) vgame_buffer) + 0x30000); // 61kB reserved - should be enough by far
|
cia = (CiaStub*) (void*) (((u8*) vgame_buffer) + 0x30000); // 61kB reserved - should be enough by far
|
||||||
twl = (TwlHeader*) (void*) (((u8*) vgame_buffer) + 0x3F400); // 512 byte reserved (not the full thing)
|
twl = (TwlHeader*) (void*) (((u8*) vgame_buffer) + 0x3F400); // 512 byte reserved (not the full thing)
|
||||||
a9l = (FirmA9LHeader*) (void*) (((u8*) vgame_buffer) + 0x3F600); // 512 byte reserved
|
a9l = (FirmA9LHeader*) (void*) (((u8*) vgame_buffer) + 0x3F600); // 512 byte reserved
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
char drv_letter;
|
char drv_letter;
|
||||||
u32 virtual_src;
|
u32 virtual_src;
|
||||||
} __attribute__((packed)) VirtualDrive;
|
} PACKED_STRUCT VirtualDrive;
|
||||||
|
|
||||||
static const VirtualDrive virtualDrives[] = { VRT_DRIVES };
|
static const VirtualDrive virtualDrives[] = { VRT_DRIVES };
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ typedef struct {
|
|||||||
u64 size;
|
u64 size;
|
||||||
u32 keyslot;
|
u32 keyslot;
|
||||||
u32 flags;
|
u32 flags;
|
||||||
} __attribute__((packed)) VirtualFile;
|
} VirtualFile;
|
||||||
|
|
||||||
// virtual dirs are only relevant for virtual game drives
|
// virtual dirs are only relevant for virtual game drives
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -45,7 +45,7 @@ typedef struct {
|
|||||||
u64 offset;
|
u64 offset;
|
||||||
u64 size;
|
u64 size;
|
||||||
u32 flags;
|
u32 flags;
|
||||||
} __attribute__((packed)) VirtualDir;
|
} VirtualDir;
|
||||||
|
|
||||||
u32 GetVirtualSource(const char* path);
|
u32 GetVirtualSource(const char* path);
|
||||||
bool InitVirtualImageDrive(void);
|
bool InitVirtualImageDrive(void);
|
||||||
|
@ -17,7 +17,7 @@ typedef struct {
|
|||||||
u32 subtype;
|
u32 subtype;
|
||||||
u32 index;
|
u32 index;
|
||||||
u32 flags;
|
u32 flags;
|
||||||
} __attribute__((packed)) VirtualNandTemplate;
|
} PACKED_STRUCT VirtualNandTemplate;
|
||||||
|
|
||||||
// see NP_TYPE_ and NP_SUBTYPE_ in nand.h
|
// see NP_TYPE_ and NP_SUBTYPE_ in nand.h
|
||||||
static const VirtualNandTemplate vNandTemplates[] = {
|
static const VirtualNandTemplate vNandTemplates[] = {
|
||||||
|
@ -24,13 +24,13 @@ typedef struct {
|
|||||||
u8 ticket_id[8];
|
u8 ticket_id[8];
|
||||||
u8 console_id[4];
|
u8 console_id[4];
|
||||||
u8 eshop_id[4];
|
u8 eshop_id[4];
|
||||||
} __attribute__((packed)) TickDbEntry;
|
} PACKED_STRUCT TickDbEntry;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u32 n_entries;
|
u32 n_entries;
|
||||||
u8 reserved[12];
|
u8 reserved[12];
|
||||||
TickDbEntry entries[256]; // this number is only a placeholder (dangerous?)
|
TickDbEntry entries[256]; // this number is only a placeholder (dangerous?)
|
||||||
} __attribute__((packed)) TickDbInfo;
|
} PACKED_STRUCT TickDbInfo;
|
||||||
|
|
||||||
// only for the main directory
|
// only for the main directory
|
||||||
static const VirtualFile vTickDbFileTemplates[] = {
|
static const VirtualFile vTickDbFileTemplates[] = {
|
||||||
|
@ -13,6 +13,10 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#define ALIGN(n) __attribute__((aligned(n)))
|
||||||
|
#define PACKED_ALIGN(n) __attribute__((packed, aligned(n)))
|
||||||
|
#define PACKED_STRUCT PACKED_ALIGN(4)
|
||||||
|
|
||||||
#define asm_v asm __volatile__
|
#define asm_v asm __volatile__
|
||||||
|
|
||||||
typedef uint8_t u8;
|
typedef uint8_t u8;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user