//------------------------------------------------
//--- 010 Editor v8.0.1 Binary Template
//
//      File: aaruformat.bt
//   Authors: Natalia Portillo
//   Version: 1.2
//   Purpose: Aaru format
//  Category: Misc
// File Mask: *.dicf
//  ID Bytes: 41 41 52 55 46 52 4D 54 // AARUFRMT
//   History:
//   1.0 2018-01-26 Natalia Portillo: Initial release
//   1.1 2020-02-29 Natalia Portillo: Rebranding
//   1.2 2020-03-04 Natalia Portillo: Add version 2 index
//------------------------------------------------

#define DIC_MAGIC  0x544D52464D434944
#define AARU_MAGIC 0x544D524655524141

enum<uint> MediaType
{
    Unknown     = 0,
    UnknownMO   = 1,
    GENERIC_HDD = 2,
    Microdrive  = 3,
    Zone_HDD    = 4,
    FlashDrive  = 5,
    UnknownTape = 6,

    CD         = 10,
    CDDA       = 11,
    CDG        = 12,
    CDEG       = 13,
    CDI        = 14,
    CDROM      = 15,
    CDROMXA    = 16,
    CDPLUS     = 17,
    CDMO       = 18,
    CDR        = 19,
    CDRW       = 20,
    CDMRW      = 21,
    VCD        = 22,
    SVCD       = 23,
    PCD        = 24,
    SACD       = 25,
    DDCD       = 26,
    DDCDR      = 27,
    DDCDRW     = 28,
    DTSCD      = 29,
    CDMIDI     = 30,
    CDV        = 31,
    PD650      = 32,
    PD650_WORM = 33,
    CDIREADY   = 34,
    FMTOWNS    = 35,

    DVDROM      = 40,
    DVDR        = 41,
    DVDRW       = 42,
    DVDPR       = 43,
    DVDPRW      = 44,
    DVDPRWDL    = 45,
    DVDRDL      = 46,
    DVDPRDL     = 47,
    DVDRAM      = 48,
    DVDRWDL     = 49,
    DVDDownload = 50,

    HDDVDROM  = 51,
    HDDVDRAM  = 52,
    HDDVDR    = 53,
    HDDVDRW   = 54,
    HDDVDRDL  = 55,
    HDDVDRWDL = 56,

    BDROM  = 60,
    BDR    = 61,
    BDRE   = 62,
    BDRXL  = 63,
    BDREXL = 64,

    EVD   = 70,
    FVD   = 71,
    HVD   = 72,
    CBHD  = 73,
    HDVMD = 74,
    VCDHD = 75,
    SVOD  = 76,
    FDDVD = 77,

    LD     = 80,
    LDROM  = 81,
    LDROM2 = 82,
    LVROM  = 83,
    MegaLD = 84,

    HiMD    = 90,
    MD      = 91,
    MDData  = 92,
    MDData2 = 93,
    MD60    = 94,
    MD74    = 95,
    MD80    = 96,

    UDO       = 100,
    UDO2      = 101,
    UDO2_WORM = 102,

    PlayStationMemoryCard   = 110,
    PlayStationMemoryCard2  = 111,
    PS1CD                   = 112,
    PS2CD                   = 113,
    PS2DVD                  = 114,
    PS3DVD                  = 115,
    PS3BD                   = 116,
    PS4BD                   = 117,
    UMD                     = 118,
    PlayStationVitaGameCard = 119,

    XGD  = 130,
    XGD2 = 131,
    XGD3 = 132,
    XGD4 = 133,

    MEGACD   = 150,
    SATURNCD = 151,
    GDROM    = 152,
    GDR      = 153,
    SegaCard = 154,
    MilCD    = 155,

    HuCard      = 170,
    SuperCDROM2 = 171,
    JaguarCD    = 172,
    ThreeDO     = 173,
    PCFX        = 174,
    NeoGeoCD    = 175,
    CDTV        = 176,
    CD32        = 177,
    Nuon        = 178,
    Playdia     = 179,

    Apple32SS     = 180,
    Apple32DS     = 181,
    Apple33SS     = 182,
    Apple33DS     = 183,
    AppleSonySS   = 184,
    AppleSonyDS   = 185,
    AppleFileWare = 186,

    DOS_525_SS_DD_8 = 190,
    DOS_525_SS_DD_9 = 191,
    DOS_525_DS_DD_8 = 192,
    DOS_525_DS_DD_9 = 193,
    DOS_525_HD      = 194,
    DOS_35_SS_DD_8  = 195,
    DOS_35_SS_DD_9  = 196,
    DOS_35_DS_DD_8  = 197,
    DOS_35_DS_DD_9  = 198,
    DOS_35_HD       = 199,
    DOS_35_ED       = 200,
    DMF             = 201,
    DMF_82          = 202,
    XDF_525         = 203,
    XDF_35          = 204,

    IBM23FD      = 210,
    IBM33FD_128  = 211,
    IBM33FD_256  = 212,
    IBM33FD_512  = 213,
    IBM43FD_128  = 214,
    IBM43FD_256  = 215,
    IBM53FD_256  = 216,
    IBM53FD_512  = 217,
    IBM53FD_1024 = 218,

    RX01 = 220,
    RX02 = 221,
    RX03 = 222,
    RX50 = 223,

    ACORN_525_SS_SD_40 = 230,
    ACORN_525_SS_SD_80 = 231,
    ACORN_525_SS_DD_40 = 232,
    ACORN_525_SS_DD_80 = 233,
    ACORN_525_DS_DD    = 234,
    ACORN_35_DS_DD     = 235,
    ACORN_35_DS_HD     = 236,

    ATARI_525_SD      = 240,
    ATARI_525_ED      = 241,
    ATARI_525_DD      = 242,
    ATARI_35_SS_DD    = 243,
    ATARI_35_DS_DD    = 244,
    ATARI_35_SS_DD_11 = 245,
    ATARI_35_DS_DD_11 = 246,

    CBM_35_DD       = 250,
    CBM_AMIGA_35_DD = 251,
    CBM_AMIGA_35_HD = 252,
    CBM_1540        = 253,
    CBM_1540_Ext    = 254,
    CBM_1571        = 255,

    NEC_8_SD     = 260,
    NEC_8_DD     = 261,
    NEC_525_SS   = 262,
    NEC_525_DS   = 263,
    NEC_525_HD   = 264,
    NEC_35_HD_8  = 265,
    NEC_35_HD_15 = 266,
    NEC_35_TD    = 267,
    SHARP_525    = NEC_525_HD,
    SHARP_525_9  = 268,
    SHARP_35     = NEC_35_HD_8,
    SHARP_35_9   = 269,

    ECMA_99_8  = 270,
    ECMA_99_15 = 271,
    ECMA_99_26 = 272,
    ECMA_100   = DOS_35_DS_DD_9,
    ECMA_125   = DOS_35_HD,
    ECMA_147   = DOS_35_ED,
    ECMA_54    = 273,
    ECMA_59    = 274,
    ECMA_66    = 275,
    ECMA_69_8  = 276,
    ECMA_69_15 = 277,
    ECMA_69_26 = 278,
    ECMA_70    = 279,
    ECMA_78    = 280,
    ECMA_78_2  = 281,

    FDFORMAT_525_DD = 290,
    FDFORMAT_525_HD = 291,
    FDFORMAT_35_DD  = 292,
    FDFORMAT_35_HD  = 293,

    Apricot_35 = 309,

    ADR2120 = 310,
    ADR260  = 311,
    ADR30   = 312,
    ADR50   = 313,

    AIT1      = 320,
    AIT1Turbo = 321,
    AIT2      = 322,
    AIT2Turbo = 323,
    AIT3      = 324,
    AIT3Ex    = 325,
    AIT3Turbo = 326,
    AIT4      = 327,
    AIT5      = 328,
    AITETurbo = 329,
    SAIT1     = 330,
    SAIT2     = 331,

    Bernoulli    = 340,
    Bernoulli2   = 341,
    Ditto        = 342,
    DittoMax     = 343,
    Jaz          = 344,
    Jaz2         = 345,
    PocketZip    = 346,
    REV120       = 347,
    REV35        = 348,
    REV70        = 349,
    ZIP100       = 350,
    ZIP250       = 351,
    ZIP750       = 352,
    Bernoulli35  = 353,
    Bernoulli44  = 354,
    Bernoulli65  = 355,
    Bernoulli90  = 356,
    Bernoulli105 = 357,
    Bernoulli150 = 358,
    Bernoulli230 = 359,

    CompactCassette = 360,
    Data8           = 361,
    MiniDV          = 362,
    Dcas25          = 363,
    Dcas85          = 364,
    Dcas103         = 365,

    CFast             = 370,
    CompactFlash      = 371,
    CompactFlashType2 = 372,

    DigitalAudioTape = 380,
    DAT160           = 381,
    DAT320           = 382,
    DAT72            = 383,
    DDS1             = 384,
    DDS2             = 385,
    DDS3             = 386,
    DDS4             = 387,

    CompactTapeI  = 390,
    CompactTapeII = 391,
    DECtapeII     = 392,
    DLTtapeIII    = 393,
    DLTtapeIIIxt  = 394,
    DLTtapeIV     = 395,
    DLTtapeS4     = 396,
    SDLT1         = 397,
    SDLT2         = 398,
    VStapeI       = 399,

    Exatape15m    = 400,
    Exatape22m    = 401,
    Exatape22mAME = 402,
    Exatape28m    = 403,
    Exatape40m    = 404,
    Exatape45m    = 405,
    Exatape54m    = 406,
    Exatape75m    = 407,
    Exatape76m    = 408,
    Exatape80m    = 409,
    Exatape106m   = 410,
    Exatape160mXL = 411,
    Exatape112m   = 412,
    Exatape125m   = 413,
    Exatape150m   = 414,
    Exatape170m   = 415,
    Exatape225m   = 416,

    ExpressCard34 = 420,
    ExpressCard54 = 421,
    PCCardTypeI   = 422,
    PCCardTypeII  = 423,
    PCCardTypeIII = 424,
    PCCardTypeIV  = 425,

    EZ135  = 430,
    EZ230  = 431,
    Quest  = 432,
    SparQ  = 433,
    SQ100  = 434,
    SQ200  = 435,
    SQ300  = 436,
    SQ310  = 437,
    SQ327  = 438,
    SQ400  = 439,
    SQ800  = 440,
    SQ1500 = 441,
    SQ2000 = 442,
    SyJet  = 443,

    FamicomGamePak        = 450,
    GameBoyAdvanceGamePak = 451,
    GameBoyGamePak        = 452,
    GOD                   = 453,
    N64DD                 = 454,
    N64GamePak            = 455,
    NESGamePak            = 456,
    Nintendo3DSGameCard   = 457,
    NintendoDiskCard      = 458,
    NintendoDSGameCard    = 459,
    NintendoDSiGameCard   = 460,
    SNESGamePak           = 461,
    SNESGamePakUS         = 462,
    WOD                   = 463,
    WUOD                  = 464,
    SwitchGameCard        = 465,

    IBM3470  = 470,
    IBM3480  = 471,
    IBM3490  = 472,
    IBM3490E = 473,
    IBM3592  = 474,

    LTO      = 480,
    LTO2     = 481,
    LTO3     = 482,
    LTO3WORM = 483,
    LTO4     = 484,
    LTO4WORM = 485,
    LTO5     = 486,
    LTO5WORM = 487,
    LTO6     = 488,
    LTO6WORM = 489,
    LTO7     = 490,
    LTO7WORM = 491,

    MemoryStick       = 510,
    MemoryStickDuo    = 511,
    MemoryStickMicro  = 512,
    MemoryStickPro    = 513,
    MemoryStickProDuo = 514,

    microSD       = 520,
    miniSD        = 521,
    SecureDigital = 522,

    MMC       = 530,
    MMCmicro  = 531,
    RSMMC     = 532,
    MMCplus   = 533,
    MMCmobile = 534,

    MLR1        = 540,
    MLR1SL      = 541,
    MLR3        = 542,
    SLR1        = 543,
    SLR2        = 544,
    SLR3        = 545,
    SLR32       = 546,
    SLR32SL     = 547,
    SLR4        = 548,
    SLR5        = 549,
    SLR5SL      = 550,
    SLR6        = 551,
    SLRtape7    = 552,
    SLRtape7SL  = 553,
    SLRtape24   = 554,
    SLRtape24SL = 555,
    SLRtape40   = 556,
    SLRtape50   = 557,
    SLRtape60   = 558,
    SLRtape75   = 559,
    SLRtape100  = 560,
    SLRtape140  = 561,

    QIC11   = 570,
    QIC120  = 571,
    QIC1350 = 572,
    QIC150  = 573,
    QIC24   = 574,
    QIC3010 = 575,
    QIC3020 = 576,
    QIC3080 = 577,
    QIC3095 = 578,
    QIC320  = 579,
    QIC40   = 580,
    QIC525  = 581,
    QIC80   = 582,

    STK4480 = 590,
    STK4490 = 591,
    STK9490 = 592,
    T9840A  = 593,
    T9840B  = 594,
    T9840C  = 595,
    T9840D  = 596,
    T9940A  = 597,
    T9940B  = 598,
    T10000A = 599,
    T10000B = 600,
    T10000C = 601,
    T10000D = 602,

    Travan    = 610,
    Travan1Ex = 611,
    Travan3   = 612,
    Travan3Ex = 613,
    Travan4   = 614,
    Travan5   = 615,
    Travan7   = 616,

    VXA1 = 620,
    VXA2 = 621,
    VXA3 = 622,

    ECMA_153        = 630,
    ECMA_153_512    = 631,
    ECMA_154        = 632,
    ECMA_183_512    = 633,
    ECMA_183        = 634,
    ECMA_184_512    = 635,
    ECMA_184        = 636,
    ECMA_189        = 637,
    ECMA_190        = 638,
    ECMA_195        = 639,
    ECMA_195_512    = 640,
    ECMA_201        = 641,
    ECMA_201_ROM    = 642,
    ECMA_223        = 643,
    ECMA_223_512    = 644,
    ECMA_238        = 645,
    ECMA_239        = 646,
    ECMA_260        = 647,
    ECMA_260_Double = 648,
    ECMA_280        = 649,
    ECMA_317        = 650,
    ECMA_322        = 651,
    ECMA_322_2k     = 652,
    GigaMo          = 653,
    GigaMo2         = 654,

    CompactFloppy = 660,
    DemiDiskette  = 661,
    Floptical     = 662,
    HiFD          = 663,
    QuickDisk     = 664,
    UHD144        = 665,
    VideoFloppy   = 666,
    Wafer         = 667,
    ZXMicrodrive  = 668,

    BeeCard     = 670,
    Borsu       = 671,
    DataStore   = 672,
    DIR         = 673,
    DST         = 674,
    DTF         = 675,
    DTF2        = 676,
    Flextra3020 = 677,
    Flextra3225 = 678,
    HiTC1       = 679,
    HiTC2       = 680,
    LT1         = 681,
    MiniCard    = 872,
    Orb         = 683,
    Orb5        = 684,
    SmartMedia  = 685,
    xD          = 686,
    XQD         = 687,
    DataPlay    = 688,

    AppleProfile   = 690,
    AppleWidget    = 691,
    AppleHD20      = 692,
    PriamDataTower = 693,
    Pippin         = 694,

    RA60    = 700,
    RA80    = 701,
    RA81    = 702,
    RC25    = 703,
    RD31    = 704,
    RD32    = 705,
    RD51    = 706,
    RD52    = 707,
    RD53    = 708,
    RD54    = 709,
    RK06    = 710,
    RK06_18 = 711,
    RK07    = 712,
    RK07_18 = 713,
    RM02    = 714,
    RM03    = 715,
    RM05    = 716,
    RP02    = 717,
    RP02_18 = 718,
    RP03    = 719,
    RP03_18 = 720,
    RP04    = 721,
    RP04_18 = 722,
    RP05    = 723,
    RP05_18 = 724,
    RP06    = 725,
    RP06_18 = 726,

    LS120  = 730,
    LS240  = 731,
    FD32MB = 732,
    RDX    = 733,
    RDX320 = 734,

    VideoNow      = 740,
    VideoNowColor = 741,
    VideoNowXp    = 742,

    Bernoulli10      = 750,
    Bernoulli20      = 751,
    BernoulliBox2_20 = 752,

    KodakVerbatim3  = 760,
    KodakVerbatim6  = 761,
    KodakVerbatim12 = 762,

    ProfessionalDisc       = 770,
    ProfessionalDiscDual   = 771,
    ProfessionalDiscTriple = 772,
    ProfessionalDiscQuad   = 773,
    PDD                    = 774,
    PDD_WORM               = 775,
    ArchivalDisc           = 776,
    ArchivalDisc2          = 777,
    ArchivalDisc3          = 779,
    ODC300R                = 778,
    ODC300RE               = 780,
    ODC600R                = 781,
    ODC600RE               = 782,
    ODC1200RE              = 783,
    ODC1500R               = 784,
    ODC3300R               = 785,
    ODC5500R               = 786
};

enum<ushort> CompressionType
{
    None = 0,
    Lzma = 1,
    Flac = 2
};

enum<ushort> DataType
{
    NoData                           = 0,
    UserData                         = 1,
    CompactDiscPartialToc            = 2,
    CompactDiscSessionInfo           = 3,
    CompactDiscToc                   = 4,
    CompactDiscPma                   = 5,
    CompactDiscAtip                  = 6,
    CompactDiscLeadInCdText          = 7,
    DvdPfi                           = 8,
    DvdLeadInCmi                     = 9,
    DvdDiscKey                       = 10,
    DvdBca                           = 11,
    DvdDmi                           = 12,
    DvdMediaIdentifier               = 13,
    DvdMediaKeyBlock                 = 14,
    DvdRamDds                        = 15,
    DvdRamMediumStatus               = 16,
    DvdRamSpareArea                  = 17,
    DvdRRmd                          = 18,
    DvdRPrerecordedInfo              = 19,
    DvdRMediaIdentifier              = 20,
    DvdRPfi                          = 21,
    DvdAdip                          = 22,
    HdDvdCpi                         = 23,
    HdDvdMediumStatus                = 24,
    DvdDlLayerCapacity               = 25,
    DvdDlMiddleZoneAddress           = 26,
    DvdDlJumpIntervalSize            = 27,
    DvdDlManualLayerJumpLba          = 28,
    BlurayDi                         = 29,
    BlurayBca                        = 30,
    BlurayDds                        = 31,
    BlurayCartridgeStatus            = 32,
    BluraySpareArea                  = 33,
    AacsVolumeIdentifier             = 34,
    AacsSerialNumber                 = 35,
    AacsMediaIdentifier              = 36,
    AacsMediaKeyBlock                = 37,
    AacsDataKeys                     = 38,
    AacsLbaExtents                   = 39,
    CprmMediaKeyBlock                = 40,
    HybridRecognizedLayers           = 41,
    ScsiMmcWriteProtection           = 42,
    ScsiMmcDiscInformation           = 43,
    ScsiMmcTrackResourcesInformation = 44,
    ScsiMmcPowResourcesInformation   = 45,
    ScsiInquiry                      = 46,
    ScsiModePage2A                   = 47,
    AtaIdentify                      = 48,
    AtapiIdentify                    = 49,
    PcmciaCis                        = 50,
    SecureDigitalCid                 = 51,
    SecureDigitalCsd                 = 52,
    SecureDigitalScr                 = 53,
    SecureDigitalOcr                 = 54,
    MultiMediaCardCid                = 55,
    MultiMediaCardCsd                = 56,
    MultiMediaCardOcr                = 57,
    MultiMediaCardExtendedCsd        = 58,
    XboxSecuritySector               = 59,
    FloppyLeadOut                    = 60,
    DvdDiscControlBlock              = 61,
    CompactDiscFirstTrackPregap      = 62,
    CompactDiscLeadOut               = 63,
    ScsiModeSense6                   = 64,
    ScsiModeSense10                  = 65,
    UsbDescriptors                   = 66,
    XboxDmi                          = 67,
    XboxPfi                          = 68,
    CdSectorPrefix                   = 69,
    CdSectorSuffix                   = 70,
    CdSectorSubchannel               = 71,
    AppleProfileTag                  = 72,
    AppleSonyTag                     = 73,
    PriamDataTowerTag                = 74,
    CompactDiscMediaCatalogueNumber  = 75,
    CdSectorPrefixCorrected          = 76,
    CdSectorSuffixCorrected          = 77,
    CompactDiscMode2Subheader        = 78,
    CompactDiscLeadIn                = 79,
    DecryptedDVDDiscKey              = 80,
    DVD_CPI_MAI                      = 81,
    DecryptedDVDTitleKey             = 82,
    FluxData                         = 83,
    BitstreamData                    = 84
};

enum<uint> BlockType
{
    DataBlock                    = 0x4B4C4244,
    DeDuplicationTable           = 0X2A544444,
    DeDuplicationTable2          = 0x32454444,
    Index                        = 0X58444E49,
    Index2                       = 0x32584449,
    IndexContinuation            = 0x43584449,
    GeometryBlock                = 0x4D4F4547,
    MetadataBlock                = 0x4154454D,
    TracksBlock                  = 0x534B5254,
    CicmBlock                    = 0x4D434943,
    ChecksumBlock                = 0x4D534B43,
    DataPositionMeasurementBlock = 0x2A4D5044,
    SnapshotBlock                = 0x50414E53,
    ParentBlock                  = 0x50524E54,
    DumpHardwareBlock            = 0x2A504D44,
    TapeFileBlock                = 0x454C4654,
    TwinSectorTable              = 0x42545754,
    CompactDiscIndexesBlock      = 0x58494443,
    FluxDataBlock                = 0x58554C46,
    BitstreamDataBlock           = 0x53544942,
    TrackLayoutBlock             = 0x594C4B54
};

enum<byte> TrackType
{
    Audio           = 0,
    Data            = 1,
    CdMode1         = 2,
    CdMode2Formless = 3,
    CdMode2Form1    = 4,
    CdMode2Form2    = 5
};

enum<byte> ChecksumAlgorithm
{
    Invalid = 0,
    Md5     = 1,
    Sha1    = 2,
    Sha256  = 3,
    SpamSum = 4
};

typedef struct
{
    char      identifier[8];
    wchar_t   application[32];
    byte      imageMajorVersion;
    byte      imageMinorVersion;
    byte      applicationMajorVersion;
    byte      applicationMinorVersion;
    MediaType mediaType;
    uint64    indexOffset;
    FILETIME  creationTime;
    FILETIME  lastWrittenTime;
    if(imageMajorVersion >= 3)
    {
        uint32 mediaType2;
        GUID   imageIdentifier;
    }
} AaruHeader;

typedef struct
{
    BlockType       identifier;
    DataType        type;
    CompressionType compression;
    byte            shift;
    uint64          entries;
    uint64          cmpLength;
    uint64          length;
    uint64          cmpCrc64<format = hex>;
    uint64          crc64<format = hex>;
} DdtHeader;

typedef struct
{
    BlockType       identifier;
    DataType        type;
    CompressionType compression;
    byte            shift;
    byte            levels;
    byte            tableLevel;
    uint64          previousLevel;
    uint16          negative;
    uint64          start;
    byte            alignment;
    byte            shift;
    byte            sizeType;
    uint64          entries;
    uint64          cmpLength;
    uint64          length;
    uint64          cmpCrc64<format = hex>;
    uint64          crc64<format = hex>;
} Ddt2Header;

typedef struct
{
    BlockType blockType;
    DataType  dataType;
    uint64    offset;
} IndexEntry;

typedef struct
{
    BlockType  identifier;
    ushort     entries;
    uint64     crc64<format = hex>;
    IndexEntry items[entries];
} Index;

typedef struct
{
    BlockType  identifier;
    uint64     entries;
    uint64     crc64<format = hex>;
    IndexEntry items[entries];
} Index2;

typedef struct
{
    BlockType  identifier;
    uint64     entries;
    uint64     crc64<format = hex>;
    uint64     previous;
    IndexEntry items[entries];
} IndexContinuation;

typedef struct
{
    BlockType       identifier;
    DataType        type;
    CompressionType compression;
    uint            sectorSize;
    uint            cmpLength;
    uint            length;
    uint64          cmpCrc64<format = hex>;
    uint64          crc64<format = hex>;
} BlockHeader;

typedef struct
{
    BlockType identifier;
    uint      cylinders;
    uint      heads;
    uint      sectorsPerTrack;
} GeometryBlock;

typedef struct
{
    BlockType identifier;
    uint      blockSize;
    int       mediaSequence;
    int       lastMediaSequence;
    uint      creatorOffset;
    uint      creatorLength;
    uint      commentsOffset;
    uint      commentsLength;
    uint      mediaTitleOffset;
    uint      mediaTitleLength;
    uint      mediaManufacturerOffset;
    uint      mediaManufacturerLength;
    uint      mediaModelOffset;
    uint      mediaModelLength;
    uint      mediaSerialNumberOffset;
    uint      mediaSerialNumberLength;
    uint      mediaBarcodeOffset;
    uint      mediaBarcodeLength;
    uint      mediaPartNumberOffset;
    uint      mediaPartNumberLength;
    uint      driveManufacturerOffset;
    uint      driveManufacturerLength;
    uint      driveModelOffset;
    uint      driveModelLength;
    uint      driveSerialNumberOffset;
    uint      driveSerialNumberLength;
    uint      driveFirmwareRevisionOffset;
    uint      driveFirmwareRevisionLength;
} MetadataBlock;

typedef struct
{
    byte      sequence;
    TrackType type;
    int64     start;
    int64     end;
    int64     pregap;
    byte      session;
    char      isrc[13];
    byte      flags;
} TrackEntry;

typedef struct
{
    BlockType  identifier;
    ushort     entries;
    uint64     crc64;
    TrackEntry tracks[entries];
} TracksHeader;

typedef struct
{
    BlockType identifier;
    uint      length;
    char      xml[length];
} CicmMetadataBlock;

typedef struct
{
    uint64 start;
    uint64 end;
} DumpHardwareExtent;

typedef struct
{
    uint               manufacturerLength;
    uint               modelLength;
    uint               revisionLength;
    uint               firmwareLength;
    uint               serialLength;
    uint               softwareNameLength;
    uint               softwareVersionLength;
    uint               softwareOperatingSystemLength;
    uint               extentCount;
    char               manufacturer[manufacturerLength];
    char               model[modelLength];
    char               revision[revisionLength];
    char               firmware[firmwareLength];
    char               serial[serialLength];
    char               softwareName[softwareNameLength];
    char               softwareVersion[softwareVersionLength];
    char               softwareOperatingSystem[softwareOperatingSystemLength];
    DumpHardwareExtent extents[extentCount];
} DumpHardwareEntry;

typedef struct
{
    BlockType         identifier;
    ushort            entries;
    uint              length;
    uint64            crc64<format = hex>;
    DumpHardwareEntry dumpHardware[entries];
} DumpHardwareHeader<optimize = false>;

typedef struct
{
    ChecksumAlgorithm type;
    uint              length;
    if(type == 4)
        char checksum[length]<format = hex>;
    else
        byte checksum[length]<format = hex>;
} ChecksumEntry<optimize = false>;

typedef struct
{
    BlockType     identifier;
    uint          length;
    byte          entries;
    ChecksumEntry checksums[entries];
} ChecksumHeader;

typedef struct
{
    uint   file;
    char   partition;
    uint64 first_block;
    uint64 last_block;
} TapeFileEntry;

typedef struct
{
    BlockType     identifier;
    uint          entries;
    uint64        length;
    uint64        crc64<format = hex>;
    TapeFileEntry files[entries];
} TapeFileHeader;

typedef struct
{
    byte   number;
    uint64 first_block;
    uint64 last_block;
} TapePartitionEntry;

typedef struct
{
    BlockType          identifier;
    byte               entries;
    uint64             length;
    uint64             crc64<format = hex>;
    TapePartitionEntry partitions[entries];
} TapePartitionHeader;

typedef struct
{
    BlockType identifier;
    byte      alignment;
    byte      shift;
    uint64    entries;
    uint64    length;
    uint64    crc64<format = hex>;
    uint64    pointers[entries];
} TwinSectorTable;

typedef struct
{
    BlockType identifier;
    uint64    length;
    GUID      parentId;
    uint16    parentClueLength;
    char      parentClue[parentClueLength];
} ParentFileBlock;

typedef struct
{
    BlockType identifier;
    uint64    length;
    uint16    generation;
    uint64    indexOffset;
    FILETIME  creationTime;
} SnapshotBlock;

typedef struct
{
    uint16 track;
    uint16 index;
    uint32 lba;
} CompactDiscIndexEntry;

typedef struct
{
    BlockType             identifier;
    uint16                entries;
    uint64                length;
    uint64                crc64<format = hex>;
    CompactDiscIndexEntry indexes[entries];
} CompactDiscIndexesBlock;

typedef struct
{
    uint32 head;
    uint16 track;
    byte   subtrack;
    uint64 resolution;
    uint64 tableEntry;
} FluxDataEntry;

typedef struct
{
    BlockType     identifier;
    uint16        entries;
    uint64        crc64<format = hex>;
    FluxDataEntry fluxes[entries];
} FluxDataBlock;

typedef struct
{
    uint32 head;
    uint16 track;
    byte   subtrack;
    uint64 tableEntry;
} BitstreamDataEntry;

typedef struct
{
    BlockType          identifier;
    uint16             entries;
    uint64             crc64<format = hex>;
    BitstreamDataEntry bitstreams[entries];
} BitstreamDataBlock;

typedef struct
{
    uint16 sector;
    uint64 block;
} SectorMapEntry;

typedef struct
{
    BlockType      identifier;
    uint64         crc64<format = hex>;
    uint32         head;
    uint16         track;
    byte           subtrack;
    uint16         sectors;
    uint64         flux;
    uint64         bitstream;
    SectorMapEntry mappings[sectors];
} TrackLayoutBlock;

LittleEndian();

local int i;

Assert(ReadUInt64() == DIC_MAGIC || ReadUInt64() == AARU_MAGIC, "Incorrect signature!");

AaruHeader header;

FSeek(header.indexOffset);
local uint idxid = ReadUInt();
FSeek(header.indexOffset);

if(idxid == 0x32584449) { Index2 index; }
else { Index index; }

for(i = 0; i < index.entries; i++)
{
    FSeek(index.items[i].offset);
    switch(index.items[i].blockType)
    {
        case 0x4B4C4244:
            BlockHeader dataBlock;
            break;
        case 0x2A544444:
            DdtHeader deduplicationTable;
            break;
        case 0x4D4F4547:
            GeometryBlock geometry;
            break;
        case 0x4154454D:
            MetadataBlock metadata;
            if(metadata.creatorOffset > 0)
            {
                FSeek(index.items[i].offset + metadata.creatorOffset);
                wchar_t Creator[metadata.creatorLength / 2];
            }
            if(metadata.commentsOffset > 0)
            {
                FSeek(index.items[i].offset + metadata.commentsOffset);
                wchar_t Comments[metadata.commentsLength / 2];
            }
            if(metadata.mediaTitleOffset > 0)
            {
                FSeek(index.items[i].offset + metadata.mediaTitleOffset);
                wchar_t MediaTitle[metadata.mediaTitleLength / 2];
            }
            if(metadata.mediaManufacturerOffset > 0)
            {
                FSeek(index.items[i].offset + metadata.mediaManufacturerOffset);
                wchar_t MediaManufacturer[metadata.mediaManufacturerLength / 2];
            }
            if(metadata.mediaModelOffset > 0)
            {
                FSeek(index.items[i].offset + metadata.mediaModelOffset);
                wchar_t MediaModel[metadata.mediaModelLength / 2];
            }
            if(metadata.mediaSerialNumberOffset > 0)
            {
                FSeek(index.items[i].offset + metadata.mediaSerialNumberOffset);
                wchar_t MediaSerialNumber[metadata.mediaSerialNumberLength / 2];
            }
            if(metadata.mediaBarcodeOffset > 0)
            {
                FSeek(index.items[i].offset + metadata.mediaBarcodeOffset);
                wchar_t MediaBarcode[metadata.mediaBarcodeLength / 2];
            }
            if(metadata.mediaPartNumberOffset > 0)
            {
                FSeek(index.items[i].offset + metadata.mediaPartNumberOffset);
                wchar_t MediaPartNumber[metadata.mediaPartNumberLength / 2];
            }
            if(metadata.driveManufacturerOffset > 0)
            {
                FSeek(index.items[i].offset + metadata.driveManufacturerOffset);
                wchar_t DriveManufacturer[metadata.driveManufacturerLength / 2];
            }
            if(metadata.driveModelOffset > 0)
            {
                FSeek(index.items[i].offset + metadata.driveModelOffset);
                wchar_t DriveModel[metadata.driveModelLength / 2];
            }
            if(metadata.driveSerialNumberOffset > 0)
            {
                FSeek(index.items[i].offset + metadata.driveSerialNumberOffset);
                wchar_t DriveSerialNumber[metadata.driveSerialNumberLength / 2];
            }
            if(metadata.driveFirmwareRevisionOffset > 0)
            {
                FSeek(index.items[i].offset + metadata.driveFirmwareRevisionOffset);
                wchar_t DriveFirmwareRevision[metadata.driveFirmwareRevisionLength / 2];
            }
            break;
        case 0x534B5254:
            TracksHeader tracks;
            break;
        case 0x4D434943:
            CicmMetadataBlock cicmMetadata;
            break;
        case 0x2A504D44:
            DumpHardwareHeader dumpHardware;
            break;
        case 0x4D534B43:
            ChecksumHeader checksum;
            break;
        case 0x54425054:
            TapePartitionHeader partitions;
            break;
        case 0x454C4654:
            TapeFileHeader files;
            break;
        case 0x32454444:
            Ddt2Header deduplicationTable2;
            break;
        case 0x43584449:  // TODO: Index Continuation
            IndexContinuation indexContinuation;
            break;
        case 0x2A4D5044:  // TODO: Data Position Measurement
            break;
        case 0x50414E53:
            SnapshotBlock snapshot;
            break;
        case 0x50524E54:
            ParentFileBlock parent;
            break;
        case 0x42545754:
            TwinSectorTable twinSector;
            break;
        case 0x58494443:
            CompactDiscIndexesBlock compactDiscIndexes;
            break;
        case 0x58554C46:
            FluxDataBlock fluxData;
            break;
        case 0x53544942:
            BitstreamDataBlock bitstreamData;
            break;
        case 0x594C4B54:
            TrackLayoutBlock trackLayout;
            break;
    }
}