From cdcb32ccfc8e9b5d3607d5226843fc8115e4ef70 Mon Sep 17 00:00:00 2001 From: Natalia Portillo Date: Thu, 1 Aug 2019 17:00:30 +0100 Subject: [PATCH] Add missing Opera structs and constants. --- DiscImageChef.Filesystems/Opera/Consts.cs | 29 +++++++- DiscImageChef.Filesystems/Opera/Info.cs | 12 +-- DiscImageChef.Filesystems/Opera/Structs.cs | 87 +++++++++++++++++++--- 3 files changed, 111 insertions(+), 17 deletions(-) diff --git a/DiscImageChef.Filesystems/Opera/Consts.cs b/DiscImageChef.Filesystems/Opera/Consts.cs index e43dcce95..4ee4cc7b0 100644 --- a/DiscImageChef.Filesystems/Opera/Consts.cs +++ b/DiscImageChef.Filesystems/Opera/Consts.cs @@ -1,4 +1,31 @@ namespace DiscImageChef.Filesystems { - public partial class OperaFS { } + public partial class OperaFS + { + const string SYNC = "ZZZZZ"; + const uint FLAGS_MASK = 0xFF; + const int MAX_NAME = 32; + + /// + /// Directory + /// + const uint TYPE_DIR = 0x2A646972; + /// + /// Disc label + /// + const uint TYPE_LBL = 0x2A6C626C; + /// + /// Catapult + /// + const uint TYPE_ZAP = 0x2A7A6170; + + enum FileFlags : uint + { + File = 2, + Special = 6, + Directory = 7, + LastEntryInBlock = 0x40000000, + LastEntry = 0x80000000 + } + } } \ No newline at end of file diff --git a/DiscImageChef.Filesystems/Opera/Info.cs b/DiscImageChef.Filesystems/Opera/Info.cs index 6ad1b24c0..555c24c2b 100644 --- a/DiscImageChef.Filesystems/Opera/Info.cs +++ b/DiscImageChef.Filesystems/Opera/Info.cs @@ -23,7 +23,7 @@ namespace DiscImageChef.Filesystems if(recordType != 1 || recordVersion != 1) return false; - return Encoding.ASCII.GetString(syncBytes) == "ZZZZZ"; + return Encoding.ASCII.GetString(syncBytes) == SYNC; } public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information, @@ -36,11 +36,11 @@ namespace DiscImageChef.Filesystems byte[] sbSector = imagePlugin.ReadSector(0 + partition.Start); - OperaSuperBlock sb = Marshal.ByteArrayToStructureBigEndian(sbSector); + SuperBlock sb = Marshal.ByteArrayToStructureBigEndian(sbSector); sb.sync_bytes = new byte[5]; if(sb.record_type != 1 || sb.record_version != 1) return; - if(Encoding.ASCII.GetString(sb.sync_bytes) != "ZZZZZ") return; + if(Encoding.ASCII.GetString(sb.sync_bytes) != SYNC) return; superBlockMetadata.AppendFormat("Opera filesystem disc.").AppendLine(); if(!string.IsNullOrEmpty(StringHandlers.CToString(sb.volume_label, Encoding))) @@ -68,7 +68,7 @@ namespace DiscImageChef.Filesystems superBlockMetadata .AppendFormat("Volume size: {0} blocks, {1} bytes", sb.block_count, sb.block_size * sb.block_count) .AppendLine(); - if((ulong)sb.block_count > imagePlugin.Info.Sectors) + if(sb.block_count > imagePlugin.Info.Sectors) superBlockMetadata .AppendFormat("WARNING: Filesystem indicates {0} blocks while device indicates {1} blocks", sb.block_count, imagePlugin.Info.Sectors); @@ -84,8 +84,8 @@ namespace DiscImageChef.Filesystems { Type = "Opera", VolumeName = StringHandlers.CToString(sb.volume_label, Encoding), - ClusterSize = (uint)sb.block_size, - Clusters = (ulong)sb.block_count + ClusterSize = sb.block_size, + Clusters = sb.block_count }; } } diff --git a/DiscImageChef.Filesystems/Opera/Structs.cs b/DiscImageChef.Filesystems/Opera/Structs.cs index fdd76bc5c..4bb41665c 100644 --- a/DiscImageChef.Filesystems/Opera/Structs.cs +++ b/DiscImageChef.Filesystems/Opera/Structs.cs @@ -5,7 +5,7 @@ namespace DiscImageChef.Filesystems public partial class OperaFS { [StructLayout(LayoutKind.Sequential, Pack = 1)] - struct OperaSuperBlock + struct SuperBlock { /// 0x000, Record type, must be 1 public readonly byte record_type; @@ -17,25 +17,92 @@ namespace DiscImageChef.Filesystems /// 0x007, Volume flags public readonly byte volume_flags; /// 0x008, 32 bytes, volume comment - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_NAME)] public readonly byte[] volume_comment; /// 0x028, 32 bytes, volume label - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_NAME)] public readonly byte[] volume_label; /// 0x048, Volume ID - public readonly int volume_id; + public readonly uint volume_id; /// 0x04C, Block size in bytes - public readonly int block_size; + public readonly uint block_size; /// 0x050, Blocks in volume - public readonly int block_count; + public readonly uint block_count; /// 0x054, Root directory ID - public readonly int root_dirid; + public readonly uint root_dirid; /// 0x058, Root directory blocks - public readonly int rootdir_blocks; + public readonly uint rootdir_blocks; /// 0x05C, Root directory block size - public readonly int rootdir_bsize; + public readonly uint rootdir_bsize; /// 0x060, Last root directory copy - public readonly int last_root_copy; + public readonly uint last_root_copy; + } + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + struct DirectoryHeader + { + /// + /// Next block from this directory, -1 if last + /// + public readonly int next_block; + /// + /// Previous block from this directory, -1 if first + /// + public readonly int prev_block; + /// + /// Directory flags + /// + public readonly uint flags; + /// + /// Offset to first free unused byte in the directory + /// + public readonly uint first_free; + /// + /// Offset to first directory entry + /// + public readonly uint first_used; + } + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + struct DirectoryEntry + { + /// + /// File flags, see + /// + public readonly uint flags; + /// + /// Unique file identifier + /// + public readonly uint id; + /// + /// Entry type + /// + public readonly uint type; + /// + /// Block size + /// + public readonly uint block_size; + /// + /// Block count + /// + public readonly uint block_count; + /// + /// Unknown + /// + public readonly uint burst; + /// + /// Unknown + /// + public readonly uint gap; + /// + /// Filename + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_NAME)] + public readonly byte[] name; + /// + /// Last copy + /// + public readonly uint last_copy; } } } \ No newline at end of file