diff --git a/arm9/source/game/bdri.c b/arm9/source/game/bdri.c index 3de4649..35613d8 100644 --- a/arm9/source/game/bdri.c +++ b/arm9/source/game/bdri.c @@ -7,6 +7,75 @@ #define getfatindex(uv) ((uv) & 0x7FFFFFFFUL) #define buildfatuv(index, flag) ((index) | ((flag) ? 0x80000000UL : 0)) +typedef struct { + char magic[4]; // "BDRI" + u32 version; // == 0x30000 + u64 info_offset; // == 0x20 + u64 image_size; // in blocks; and including the pre-header + u32 image_block_size; + u8 padding1[4]; + u8 unknown[4]; + u32 data_block_size; + u64 dht_offset; + u32 dht_bucket_count; + u8 padding2[4]; + u64 fht_offset; + u32 fht_bucket_count; + u8 padding3[4]; + u64 fat_offset; + u32 fat_entry_count; // exculdes 0th entry + u8 padding4[4]; + u64 data_offset; + u32 data_block_count; // == fat_entry_count + u8 padding5[4]; + u32 det_start_block; + u32 det_block_count; + u32 max_dir_count; + u8 padding6[4]; + u32 fet_start_block; + u32 fet_block_count; + u32 max_file_count; + u8 padding7[4]; +} __attribute__((packed)) BDRIFsHeader; + +typedef struct { + char magic[8]; // varies based on media type and importdb vs titledb + u8 reserved[0x78]; + BDRIFsHeader fs_header; +} __attribute__((packed)) TitleDBPreHeader; + +typedef struct { + char magic[4]; // "TICK" + u32 unknown1; // usually (assuming always) == 1 + u32 unknown2; + u32 unknown3; + BDRIFsHeader fs_header; +} __attribute__((packed)) TickDBPreHeader; + +typedef struct { + u32 parent_index; + u8 title_id[8]; + u32 next_sibling_index; + u8 padding1[4]; + u32 start_block_index; + u64 size; // in bytes + u8 padding2[8]; + u32 hash_bucket_next_index; +} __attribute__((packed)) TdbFileEntry; + +typedef struct { + u32 total_entry_count; + u32 max_entry_count; // == max_file_count + 1 + u8 padding[32]; + u32 next_dummy_index; +} __attribute__((packed)) DummyFileEntry; + +typedef struct { + u32 unknown; // usually (assuming always) == 1 + u32 ticket_size; // == 0x350 == sizeof(Ticket) + Ticket ticket; +} __attribute__((packed, aligned(4))) TicketEntry; + static FIL* bdrifp; static FRESULT BDRIRead(UINT ofs, UINT btr, void* buf) { diff --git a/arm9/source/game/bdri.h b/arm9/source/game/bdri.h index 28d68c6..4eb2d86 100644 --- a/arm9/source/game/bdri.h +++ b/arm9/source/game/bdri.h @@ -9,69 +9,6 @@ // https://www.3dbrew.org/wiki/Inner_FAT // https://www.3dbrew.org/wiki/Title_Database -typedef struct { - char magic[4]; // "BDRI" - u32 version; // == 0x30000 - u64 info_offset; // == 0x20 - u64 image_size; // in blocks; and including the pre-header - u32 image_block_size; - u8 padding1[4]; - u8 unknown[4]; - u32 data_block_size; - u64 dht_offset; - u32 dht_bucket_count; - u8 padding2[4]; - u64 fht_offset; - u32 fht_bucket_count; - u8 padding3[4]; - u64 fat_offset; - u32 fat_entry_count; // exculdes 0th entry - u8 padding4[4]; - u64 data_offset; - u32 data_block_count; // == fat_entry_count - u8 padding5[4]; - u32 det_start_block; - u32 det_block_count; - u32 max_dir_count; - u8 padding6[4]; - u32 fet_start_block; - u32 fet_block_count; - u32 max_file_count; - u8 padding7[4]; -} __attribute__((packed)) BDRIFsHeader; - -typedef struct { - char magic[8]; // varies based on media type and importdb vs titledb - u8 reserved[0x78]; - BDRIFsHeader fs_header; -} __attribute__((packed)) TitleDBPreHeader; - -typedef struct { - char magic[4]; // "TICK" - u32 unknown1; // usually (assuming always) == 1 - u32 unknown2; - u32 unknown3; - BDRIFsHeader fs_header; -} __attribute__((packed)) TickDBPreHeader; - -typedef struct { - u32 parent_index; - u8 title_id[8]; - u32 next_sibling_index; - u8 padding1[4]; - u32 start_block_index; - u64 size; // in bytes - u8 padding2[8]; - u32 hash_bucket_next_index; -} __attribute__((packed)) TdbFileEntry; - -typedef struct { - u32 total_entry_count; - u32 max_entry_count; // == max_file_count + 1 - u8 padding[32]; - u32 next_dummy_index; -} __attribute__((packed)) DummyFileEntry; - typedef struct { u64 title_size; // in bytes u32 title_type; // usually == 0x40 @@ -89,12 +26,6 @@ typedef struct { u8 reserved3[44]; } __attribute__((packed)) TitleInfoEntry; -typedef struct { - u32 unknown; // usually (assuming always) == 1 - u32 ticket_size; // commonly == 0x350 - Ticket ticket; -} __attribute__((packed, aligned(4))) TicketEntry; - u32 GetNumTitleInfoEntries(const char* path); u32 GetNumTickets(const char* path); u32 ListTitleInfoEntryTitleIDs(const char* path, u8* title_ids, u32 max_title_ids); @@ -104,4 +35,4 @@ u32 ReadTicketFromDB(const char* path, const u8* title_id, Ticket** ticket); u32 RemoveTitleInfoEntryFromDB(const char* path, const u8* title_id); u32 RemoveTicketFromDB(const char* path, const u8* title_id); u32 AddTitleInfoEntryToDB(const char* path, const u8* title_id, const TitleInfoEntry* tie, bool replace); -u32 AddTicketToDB(const char* path, const u8* title_id, const Ticket* ticket, bool replace); \ No newline at end of file +u32 AddTicketToDB(const char* path, const u8* title_id, const Ticket* ticket, bool replace); diff --git a/arm9/source/game/disadiff.c b/arm9/source/game/disadiff.c index ce0a104..a31b6a0 100644 --- a/arm9/source/game/disadiff.c +++ b/arm9/source/game/disadiff.c @@ -5,6 +5,98 @@ #define GET_DPFS_BIT(b, lvl) (((((u32*) (void*) lvl)[b >> 5]) >> (31 - (b % 32))) & 1) +typedef struct { + u8 magic[8]; // "DISA" 0x00040000 + u32 n_partitions; + u8 padding0[4]; + u64 offset_table1; + u64 offset_table0; + u64 size_table; + u64 offset_descA; + u64 size_descA; + u64 offset_descB; + u64 size_descB; + u64 offset_partitionA; + u64 size_partitionA; + u64 offset_partitionB; + u64 size_partitionB; + u8 active_table; // 0 or 1 + u8 padding1[3]; + u8 hash_table[0x20]; // for the active table + u8 unused[0x74]; +} PACKED_STRUCT DisaHeader; + +typedef struct { + u8 magic[8]; // "DIFF" 0x00030000 + u64 offset_table1; // also desc offset + u64 offset_table0; // also desc offset + u64 size_table; // includes desc size + u64 offset_partition; + u64 size_partition; + u32 active_table; // 0 or 1 + u8 hash_table[0x20]; // for the active table + u64 unique_id; // see: http://3dbrew.org/wiki/Extdata + u8 unused[0xA4]; +} PACKED_STRUCT DiffHeader; + +typedef struct { + u8 magic[8]; // "DIFI" 0x00010000 + u64 offset_ivfc; // always 0x44 + u64 size_ivfc; // always 0x78 + u64 offset_dpfs; // always 0xBC + u64 size_dpfs; // always 0x50 + u64 offset_hash; // always 0x10C + u64 size_hash; // may include padding + u8 ivfc_use_extlvl4; + u8 dpfs_lvl1_selector; + u8 padding[2]; + u64 ivfc_offset_extlvl4; +} PACKED_STRUCT DifiHeader; + +typedef struct { + u8 magic[8]; // "IVFC" 0x00020000 + u64 size_hash; // same as the one in DIFI, may include padding + u64 offset_lvl1; + u64 size_lvl1; + u32 log_lvl1; + u8 padding0[4]; + u64 offset_lvl2; + u64 size_lvl2; + u32 log_lvl2; + u8 padding1[4]; + u64 offset_lvl3; + u64 size_lvl3; + u32 log_lvl3; + u8 padding2[4]; + u64 offset_lvl4; + u64 size_lvl4; + u64 log_lvl4; + u64 size_ivfc; // 0x78 +} PACKED_STRUCT IvfcDescriptor; + +typedef struct { + u8 magic[8]; // "DPFS" 0x00010000 + u64 offset_lvl1; + u64 size_lvl1; + u32 log_lvl1; + u8 padding0[4]; + u64 offset_lvl2; + u64 size_lvl2; + u32 log_lvl2; + u8 padding1[4]; + u64 offset_lvl3; + u64 size_lvl3; + u32 log_lvl3; + u8 padding2[4]; +} PACKED_STRUCT DpfsDescriptor; + +typedef struct { + DifiHeader difi; + IvfcDescriptor ivfc; + DpfsDescriptor dpfs; + u8 hash[0x20]; + u8 padding[4]; // all zeroes when encrypted +} PACKED_STRUCT DifiStruct; static FIL ddfile; static FIL* ddfp = NULL; diff --git a/arm9/source/game/disadiff.h b/arm9/source/game/disadiff.h index 5dd25bf..33b0efb 100644 --- a/arm9/source/game/disadiff.h +++ b/arm9/source/game/disadiff.h @@ -14,99 +14,6 @@ #define DIFI_MAGIC 'D', 'I', 'F', 'I', 0x00, 0x00, 0x01, 0x00 -typedef struct { - u8 magic[8]; // "DISA" 0x00040000 - u32 n_partitions; - u8 padding0[4]; - u64 offset_table1; - u64 offset_table0; - u64 size_table; - u64 offset_descA; - u64 size_descA; - u64 offset_descB; - u64 size_descB; - u64 offset_partitionA; - u64 size_partitionA; - u64 offset_partitionB; - u64 size_partitionB; - u8 active_table; // 0 or 1 - u8 padding1[3]; - u8 hash_table[0x20]; // for the active table - u8 unused[0x74]; -} PACKED_STRUCT DisaHeader; - -typedef struct { - u8 magic[8]; // "DIFF" 0x00030000 - u64 offset_table1; // also desc offset - u64 offset_table0; // also desc offset - u64 size_table; // includes desc size - u64 offset_partition; - u64 size_partition; - u32 active_table; // 0 or 1 - u8 hash_table[0x20]; // for the active table - u64 unique_id; // see: http://3dbrew.org/wiki/Extdata - u8 unused[0xA4]; -} PACKED_STRUCT DiffHeader; - -typedef struct { - u8 magic[8]; // "DIFI" 0x00010000 - u64 offset_ivfc; // always 0x44 - u64 size_ivfc; // always 0x78 - u64 offset_dpfs; // always 0xBC - u64 size_dpfs; // always 0x50 - u64 offset_hash; // always 0x10C - u64 size_hash; // may include padding - u8 ivfc_use_extlvl4; - u8 dpfs_lvl1_selector; - u8 padding[2]; - u64 ivfc_offset_extlvl4; -} PACKED_STRUCT DifiHeader; - -typedef struct { - u8 magic[8]; // "IVFC" 0x00020000 - u64 size_hash; // same as the one in DIFI, may include padding - u64 offset_lvl1; - u64 size_lvl1; - u32 log_lvl1; - u8 padding0[4]; - u64 offset_lvl2; - u64 size_lvl2; - u32 log_lvl2; - u8 padding1[4]; - u64 offset_lvl3; - u64 size_lvl3; - u32 log_lvl3; - u8 padding2[4]; - u64 offset_lvl4; - u64 size_lvl4; - u64 log_lvl4; - u64 size_ivfc; // 0x78 -} PACKED_STRUCT IvfcDescriptor; - -typedef struct { - u8 magic[8]; // "DPFS" 0x00010000 - u64 offset_lvl1; - u64 size_lvl1; - u32 log_lvl1; - u8 padding0[4]; - u64 offset_lvl2; - u64 size_lvl2; - u32 log_lvl2; - u8 padding1[4]; - u64 offset_lvl3; - u64 size_lvl3; - u32 log_lvl3; - u8 padding2[4]; -} PACKED_STRUCT DpfsDescriptor; - -typedef struct { - DifiHeader difi; - IvfcDescriptor ivfc; - DpfsDescriptor dpfs; - u8 hash[0x20]; - u8 padding[4]; // all zeroes when encrypted -} PACKED_STRUCT DifiStruct; - // condensed info to enable reading/writing IVFC lvl4 typedef struct { u32 offset_table;