#pragma endian little #include 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;