-
-
Notifications
You must be signed in to change notification settings - Fork 195
/
Copy pathcab.hexpat
110 lines (97 loc) · 2.34 KB
/
cab.hexpat
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
#pragma author The Wandering Trader
#pragma description Microsoft Cabinet (CAB) Files
#pragma magic [4D 53 43 46] @ 0x00
import type.time;
import type.magic;
import type.size;
fn format_string(auto string) {
return std::format("{}",string);
};
bitfield flags {
bool cfhdrPREV_CABINET : 1;
bool cfhdrNEXT_CABINET : 1;
bool cfhdrRESERVE_PRESENT : 1;
padding : 13;
};
struct CFHEADER {
type::Magic<"MSCF"> signature;
u32 reserved1;
type::Size32 cbCabinet;
u32 reserved2;
u32 coffFiles;
u32 reserved3;
u8 versionMajor;
u8 versionMinor;
u16 cFolders;
u16 cFiles;
flags flags;
u16 setID;
u16 iCabinet;
if (flags.cfhdrRESERVE_PRESENT) {
type::Size16 cbCFHeader;
type::Size8 cbCFFolder;
type::Size8 cbCFData;
u8 abReserve[cbCFHeader];
}
if (flags.cfhdrPREV_CABINET) {
char szCabinetPrev[] [[format("format_string")]];
char szDiskPrev[] [[format("format_string")]];
}
if (flags.cfhdrNEXT_CABINET) {
char szCabinetNext[] [[format("format_string")]];
char szDiskNext[] [[format("format_string")]];
}
};
enum typeCompress : u8{
tcompMASK_TYPE = 0x000F,
tcompTYPE_NONE = 0x0000,
tcompTYPE_MSZIP = 0x0001,
tcompTYPE_QUANTUM = 0x0002,
tcompTYPE_LZX = 0x0003,
};
using CFDATA;
struct CFFOLDER {
u32 coffCabStart;
u16 cCfData;
typeCompress typeCompress;
u8 compressionLevel;
if (CFHEADER.flags.cfhdrRESERVE_PRESENT) {
u8 abReserve[CFHEADER.cbCFFolder];
}
CFDATA CFDATA[cCfData] @ coffCabStart;
};
bitfield attribs {
bool _A_RDONLY : 1;
bool _A_HIDDEN : 1;
bool _A_SYSTEM : 1;
padding : 2;
bool _A_ARCH : 1;
bool _A_EXEC : 1;
bool _A_NAME_IS_UTF : 1;
padding : 8;
};
struct CFFILE {
type::Size32 cbFile;
u32 uoffFolderStart;
u16 iFolder;
type::DOSDate date;
type::DOSTime time;
attribs attribs;
if (attribs._A_NAME_IS_UTF) {
char16 szName[];
} else {
char szName[] [[format("format_string")]];
}
};
struct CFDATA {
u32 csum;
type::Size16 cbData;
type::Size16 cbUncomp;
if (CFHEADER.flags.cfhdrRESERVE_PRESENT) {
u8 abReserve[CFHEADER.cbCFData];
}
u8 ab[cbData];
};
CFHEADER CFHEADER @ 0;
CFFOLDER CFFOLDER[CFHEADER.cFolders] @ $;
CFFILE CFFILE[CFHEADER.cFiles] @ $;