-
-
Notifications
You must be signed in to change notification settings - Fork 181
/
iso.hexpat
134 lines (119 loc) · 3.08 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
#pragma description ISO 9660 file system
#pragma endian little
import std.io;
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];
};
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;
padding[0x200 + 0x28E];
}
};
VolumeDescriptor data @ 0x8000;