-
-
Notifications
You must be signed in to change notification settings - Fork 196
/
Copy pathiso.hexpat
178 lines (161 loc) · 4.68 KB
/
iso.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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
#pragma description ISO 9660 file system
#pragma MIME application/x-iso9660-image
#pragma endian little
import std.io;
import std.mem;
enum VolumeDescriptorTypes : u8 {
BootRecord,
PrimaryVolume,
SupplementaryVolume,
VolumePartition,
Terminator = 0xff,
};
struct di32 {
s32 leValue;
be s32 beValue;
} [[static]];
struct di16 {
s16 leValue;
be s16 beValue;
} [[static]];
struct PathTablePtr {
s32 leMainOffset;
s32 leOptOffset;
be s32 beMainOffset;
be s32 beOptOffset;
} [[static]];
struct DateFormat {
u8 year;
u8 month;
u8 day;
u8 hour;
u8 minute;
u8 second;
u8 gmtOffset;
} [[static]];
fn FormatDate(DateFormat fmt) {
s16 gmt = (-48 + fmt.gmtOffset) * 15;
float gmtHour = gmt / 60;
s16 gmtMinute = gmt % 60;
str retVal = std::format("{}.{:02}.{:02} {:02}:{:02}:{:02} GMT{:+03}:{:02}",
fmt.day, fmt.month, fmt.year + 1900,
fmt.hour, fmt.minute, fmt.second,
gmtHour, gmtMinute);
return retVal;
};
struct StrDateFormat {
char year[4];
char month[2];
char day[2];
char hour[2];
char minute[2];
char second[2];
char secondFrac[2];
u8 gmtOffset;
} [[static]];
fn FormatStrDate(StrDateFormat fmt) {
s16 gmt = (-48 + fmt.gmtOffset) * 15;
float gmtHour = gmt / 60;
s16 gmtMinute = gmt % 60;
str retVal = std::format("{}.{}.{} {}:{}:{}.{} GMT{:+03}:{:02}",
fmt.day, fmt.month, fmt.year,
fmt.hour, fmt.minute, fmt.second, fmt.secondFrac,
gmtHour, gmtMinute);
return retVal;
};
bitfield FileFlags {
hidden : 1;
directory : 1;
associatedFile : 1;
extendedAttribute : 1;
ownerAndGroupInExtendedAttribute : 1;
padding : 2;
fileRecordNotFinal : 1;
};
struct DirectoryRecord {
u8 recordSize;
u8 extendedRecordSize;
di32 extentOffset;
di32 dataSize;
DateFormat recordDate[[format("FormatDate")]];
FileFlags fileFlags;
u8 fileUnitSize;
u8 interleaveGapSize;
di16 volumeSequenceNumber;
u8 fileNameLen;
char fileName[fileNameLen];
padding[$ % 2];
u8 remainingSize = $ - addressof(this);
if (recordSize > remainingSize) {
u8 systemUse[recordSize - remainingSize];
}
};
fn GetSupplementaryEncoding() {
const u128 escapeSequencesOffset = 89 - 8;
str encoding = std::mem::read_string($ + escapeSequencesOffset, 0x20);
return encoding == "%/@\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|| encoding == "%/C\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|| encoding == "%/E\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
};
struct VolumeDescriptor {
VolumeDescriptorTypes type;
char id[5];
u8 version;
if (type == VolumeDescriptorTypes::PrimaryVolume) {
padding[1];
char systemId[0x20];
char volumeId[0x20];
padding[8];
di32 spaceSize;
padding[0x20];
di16 setSize;
di16 sequenceNumber;
di16 logicalBlockSize;
di32 pathTableSize;
PathTablePtr pathTableOffset;
DirectoryRecord rootDir;
char setId[0x80];
char publisherId[0x80];
char preparerId[0x80];
char applicationId[0x80];
char copyrightFileId[0x25];
char abstractFileId[0x25];
char bibliographicFileId[0x25];
StrDateFormat creationTime[[format("FormatStrDate")]];
StrDateFormat modificationTime[[format("FormatStrDate")]];
StrDateFormat expirationTime[[format("FormatStrDate")]];
StrDateFormat effectiveTime[[format("FormatStrDate")]];
u8 fileStructVersion;
} else if (type == VolumeDescriptorTypes::SupplementaryVolume && GetSupplementaryEncoding()) {
u8 flags;
be char16 systemId[0x10];
be char16 volumeId[0x10];
padding[8];
di32 spaceSize;
u8 escapeSequences[0x20];
di16 setSize;
di16 sequenceNumber;
di16 logicalBlockSize;
di32 pathTableSize;
PathTablePtr pathTableOffset;
DirectoryRecord rootDir;
be char16 setId[0x40];
be char16 publisherId[0x40];
be char16 preparerId[0x40];
be char16 applicationId[0x40];
be char16 copyrightFileId[0x12];
padding[1];
be char16 abstractFileId[0x12];
padding[1];
be char16 bibliographicFileId[0x12];
padding[1];
StrDateFormat creationTime[[format("FormatStrDate")]];
StrDateFormat modificationTime[[format("FormatStrDate")]];
StrDateFormat expirationTime[[format("FormatStrDate")]];
StrDateFormat effectiveTime[[format("FormatStrDate")]];
u8 fileStructVersion;
}
padding[0x800 - $ % 0x800];
};
VolumeDescriptor descriptors[while(std::mem::read_unsigned($, 1) != 0xFF)] @ 0x8000;
VolumeDescriptor terminator @ $;