This repository has been archived by the owner on Jul 22, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
disadiff.h
126 lines (114 loc) · 3.38 KB
/
disadiff.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#pragma once
// #include "common.h"
#include "types.h"
// info taken from here:
// http://3dbrew.org/wiki/DISA_and_DIFF
// https://github.com/wwylele/3ds-save-tool
#define DISA_MAGIC 'D', 'I', 'S', 'A', 0x00, 0x00, 0x04, 0x00
#define DIFF_MAGIC 'D', 'I', 'F', 'F', 0x00, 0x00, 0x03, 0x00
#define IVFC_MAGIC 'I', 'V', 'F', 'C', 0x00, 0x00, 0x02, 0x00
#define DPFS_MAGIC 'D', 'P', 'F', 'S', 0x00, 0x00, 0x01, 0x00
#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];
} __attribute__((packed)) 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];
} __attribute__((packed)) 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;
} __attribute__((packed)) 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
} __attribute__((packed)) 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];
} __attribute__((packed)) DpfsDescriptor;
typedef struct {
DifiHeader difi;
IvfcDescriptor ivfc;
DpfsDescriptor dpfs;
u8 hash[0x20];
u8 padding[4]; // all zeroes when encrypted
} __attribute__((packed)) DifiStruct;
// condensed info to enable reading IVFC lvl4
typedef struct {
u32 offset_dpfs_lvl1; // relative to start of file
u32 offset_dpfs_lvl2; // relative to start of file
u32 offset_dpfs_lvl3; // relative to start of file
u32 size_dpfs_lvl1;
u32 size_dpfs_lvl2;
u32 size_dpfs_lvl3;
u32 log_dpfs_lvl2;
u32 log_dpfs_lvl3;
u32 offset_ivfc_lvl4; // relative to DPFS lvl3 if not external
u32 size_ivfc_lvl4;
u8 dpfs_lvl1_selector;
u8 ivfc_use_extlvl4;
u8* dpfs_lvl2_cache; // optional, NULL when unused
} __attribute__((packed)) DisaDiffReaderInfo;