// /*************************************************************************** // Aaru Data Preservation Suite // ---------------------------------------------------------------------------- // // Filename : Structs.cs // Author(s) : Natalia Portillo // // Component : High Performance Optical File System plugin. // // --[ Description ] ---------------------------------------------------------- // // High Performance Optical File System structures. // // --[ License ] -------------------------------------------------------------- // // This library is free software; you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as // published by the Free Software Foundation; either version 2.1 of the // License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, see . // // ---------------------------------------------------------------------------- // Copyright © 2011-2021 Natalia Portillo // ****************************************************************************/ using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; namespace Aaru.Filesystems { [SuppressMessage("ReSharper", "UnusedType.Local")] public sealed partial class HPOFS { /// BIOS Parameter Block, at sector 0, little-endian [StructLayout(LayoutKind.Sequential, Pack = 1)] readonly struct BiosParameterBlock { /// 0x000, Jump to boot code [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] public readonly byte[] jump; /// 0x003, OEM Name, 8 bytes, space-padded [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public readonly byte[] oem_name; /// 0x00B, Bytes per sector public readonly ushort bps; /// 0x00D, Sectors per cluster public readonly byte spc; /// 0x00E, Reserved sectors between BPB and... does it have sense in HPFS? public readonly ushort rsectors; /// 0x010, Number of FATs... seriously? public readonly byte fats_no; /// 0x011, Number of entries on root directory... ok public readonly ushort root_ent; /// 0x013, Sectors in volume... doubt it public readonly ushort sectors; /// 0x015, Media descriptor public readonly byte media; /// 0x016, Sectors per FAT... again public readonly ushort spfat; /// 0x018, Sectors per track... you're kidding public readonly ushort sptrk; /// 0x01A, Heads... stop! public readonly ushort heads; /// 0x01C, Hidden sectors before BPB public readonly uint hsectors; /// 0x024, Sectors in volume if > 65535... public readonly uint big_sectors; /// 0x028, Drive number public readonly byte drive_no; /// 0x029, Volume flags? public readonly byte nt_flags; /// 0x02A, EPB signature, 0x29 public readonly byte signature; /// 0x02B, Volume serial number public readonly uint serial_no; /// 0x02F, Volume label, 11 bytes, space-padded [MarshalAs(UnmanagedType.ByValArray, SizeConst = 11)] public readonly byte[] volume_label; /// 0x03A, Filesystem type, 8 bytes, space-padded ("HPOFS ") [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public readonly byte[] fs_type; /// Boot code. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 442)] public readonly byte[] boot_code; /// 0x1F8, Unknown public readonly uint unknown; /// 0x1FC, Unknown public readonly ushort unknown2; /// 0x1FE, 0xAA55 public readonly ushort signature2; } /// Media Information Block, at sector 13, big-endian [StructLayout(LayoutKind.Sequential, Pack = 1)] readonly struct MediaInformationBlock { /// Block identifier "MEDINFO " [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public readonly byte[] blockId; /// Volume label [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] public readonly byte[] volumeLabel; /// Volume comment [MarshalAs(UnmanagedType.ByValArray, SizeConst = 160)] public readonly byte[] comment; /// Volume serial number public readonly uint serial; /// Volume creation date, DOS format public readonly ushort creationDate; /// Volume creation time, DOS format public readonly ushort creationTime; /// Codepage type: 1 ASCII, 2 EBCDIC public readonly ushort codepageType; /// Codepage public readonly ushort codepage; /// RPS level public readonly uint rps; /// Coincides with bytes per sector, and bytes per cluster, need more media public readonly ushort bps; /// Coincides with bytes per sector, and bytes per cluster, need more media public readonly ushort bpc; /// Unknown, empty public readonly uint unknown2; /// Sectors (or clusters) public readonly uint sectors; /// Unknown, coincides with bps but changing it makes nothing public readonly uint unknown3; /// Empty? public readonly ulong unknown4; /// Format major version public readonly ushort major; /// Format minor version public readonly ushort minor; /// Empty? public readonly uint unknown5; /// Unknown, non-empty public readonly uint unknown6; /// Empty [MarshalAs(UnmanagedType.ByValArray, SizeConst = 260)] public readonly byte[] filler; } /// Volume Information Block, at sector 14, big-endian [StructLayout(LayoutKind.Sequential, Pack = 1)] readonly struct VolumeInformationBlock { /// Block identifier "VOLINFO " [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public readonly byte[] blockId; /// Unknown public readonly uint unknown; /// Unknown public readonly uint unknown2; /// Some kind of counter public readonly uint dir_intent_cnt; /// Some kind of counter, another public readonly uint dir_update_cnt; /// Unknown [MarshalAs(UnmanagedType.ByValArray, SizeConst = 22)] public readonly byte[] unknown3; /// Unknown, space-padded string [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] public readonly byte[] unknown4; /// Owner, space-padded string [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] public readonly byte[] owner; /// Unknown, space-padded string [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public readonly byte[] unknown5; /// Unknown, empty? public readonly uint unknown6; /// Maximum percent full public readonly ushort percentFull; /// Unknown, empty? public readonly ushort unknown7; /// Empty [MarshalAs(UnmanagedType.ByValArray, SizeConst = 384)] public readonly byte[] filler; } [StructLayout(LayoutKind.Sequential, Pack = 1)] readonly struct Extent { /// Extent length in sectors public readonly ushort length; /// Unknown public readonly short unknown; /// Extent starting sector public readonly int start; } [StructLayout(LayoutKind.Sequential, Pack = 1)] readonly struct SubFile { [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] public readonly Extent[] extents; /// Unknown public readonly uint unknown; /// Unknown public readonly uint unknown2; /// Logical size in bytes public readonly uint logical_size; /// Unknown public readonly uint unknown3; /// Physical size in bytes public readonly uint physical_size; /// Unknown public readonly uint unknown4; /// Physical size in bytes public readonly uint physical_size2; /// Unknown public readonly uint unknown5; /// Unknown public readonly uint unknown6; } [StructLayout(LayoutKind.Sequential, Pack = 1)] readonly struct Direct { /// Unknown public readonly uint unknown; /// Unknown public readonly uint unknown2; /// Unknown public readonly uint unknown3; /// Mask 0x6000 public readonly ushort subfiles_no; /// Unknown public readonly ushort unknown4; /// Unknown public readonly uint unknown5; /// Unknown public readonly uint unknown6; /// Unknown public readonly uint unknown7; /// Some date public readonly ushort date1; /// Some time public readonly ushort time1; /// Some date public readonly ushort date2; /// Some time public readonly ushort time2; /// Unknown public readonly uint unknown8; /// Unknown public readonly uint unknown9; /// Unknown public readonly uint unknown10; /// Unknown public readonly uint unknown11; /// Unknown public readonly uint unknown12; /// Unknown public readonly uint unknown13; /// Unknown public readonly uint unknown14; /// Subfiles, length unknown public readonly SubFile[] subfiles; } [StructLayout(LayoutKind.Sequential, Pack = 1)] readonly struct MasterRecord { /// "MAST" [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public readonly byte[] blockId; /// Unknown public readonly uint unknown; /// Unknown public readonly ushort unknown2; /// Unknown public readonly ushort unknown3; /// Unknown public readonly uint unknown4; /// Unknown public readonly ushort unknown5; /// Unknown public readonly ushort unknown6; /// Unknown public readonly ushort unknown7; /// Unknown public readonly ushort unknown8; /// Unknown public readonly uint unknown9; } [StructLayout(LayoutKind.Sequential, Pack = 1)] readonly struct DciKey { /// Unknown public readonly byte unknown; /// Name size + 2 public readonly byte size; /// Unknown public readonly byte unknown2; /// Unknown public readonly byte unknown3; /// Unknown public readonly byte unknown4; /// Unknown public readonly byte unknown5; /// Name, length = size - 2 public readonly byte[] name; } [StructLayout(LayoutKind.Sequential, Pack = 1)] readonly struct DciEntry { /// Key length public readonly ushort key_len; /// Record length public readonly ushort record_len; /// dci key public readonly DciKey key; /// Padding? Size is key_len - size of DciKey public readonly byte[] padding; /// Direct public readonly Direct dir; /// Padding? Size is record_len - size of Direct public readonly byte[] unknown; } [StructLayout(LayoutKind.Sequential, Pack = 1)] readonly struct Dci { /// "DATA" [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public readonly byte[] blockId; /// Unknown public readonly uint unknown; /// Unknown public readonly uint unknown2; /// Unknown public readonly uint unknown3; /// Unknown public readonly uint unknown4; /// Unknown public readonly uint unknown5; /// Unknown public readonly ushort unknown6; /// Unknown public readonly ushort unknown7; /// Unknown public readonly uint unknown8; /// Unknown public readonly uint unknown9; /// Entries, size unknown public readonly DciEntry[] entries; } } }