From 140a9380f908a3294c2ce186f5e354426860fe4e Mon Sep 17 00:00:00 2001 From: Natalia Portillo Date: Thu, 3 Jun 2021 12:03:20 +0100 Subject: [PATCH] Fix reading of CPCDSK disk images where the headers have different case. --- Aaru.Images/CPCDSK/Constants.cs | 29 ++++++++------------------ Aaru.Images/CPCDSK/Identify.cs | 27 +++++++++++++++++------- Aaru.Images/CPCDSK/Read.cs | 37 +++++++++++++++++++++++++-------- Aaru.Images/CPCDSK/Structs.cs | 7 ++----- 4 files changed, 59 insertions(+), 41 deletions(-) diff --git a/Aaru.Images/CPCDSK/Constants.cs b/Aaru.Images/CPCDSK/Constants.cs index 992f1f46a..67dc59323 100644 --- a/Aaru.Images/CPCDSK/Constants.cs +++ b/Aaru.Images/CPCDSK/Constants.cs @@ -35,26 +35,15 @@ namespace Aaru.DiscImages public sealed partial class Cpcdsk { /// Identifier for CPCEMU disk images, "MV - CPC" + usually : "EMU Disk-File\r\nDisk-Info\r\n" but not required - readonly byte[] _cpcdskId = - { - 0x4D, 0x56, 0x20, 0x2D, 0x20, 0x43, 0x50, 0x43 - }; + const string _cpcdskId = "MV - CPCEMU Disk-File"; + /// Identifier for DU54 disk images, "MV - CPC format Disk Image (DU54)" - readonly byte[] _du54Id = - { - 0x4D, 0x56, 0x20, 0x2D, 0x20, 0x43, 0x50, 0x43, 0x20, 0x66, 0x6F, 0x72, 0x6D, 0x61, 0x74, 0x20, 0x44, 0x69, - 0x73, 0x6B, 0x20 - }; - /// Identifier for Extended CPCEMU disk images, "EXTENDED CPC DSK File" - readonly byte[] _edskId = - { - 0x45, 0x58, 0x54, 0x45, 0x4E, 0x44, 0x45, 0x44, 0x20, 0x43, 0x50, 0x43, 0x20, 0x44, 0x53, 0x4B, 0x20, 0x46, - 0x69, 0x6C, 0x65 - }; - /// Identifier for track information, "Track-Info\r\n" - readonly byte[] _trackId = - { - 0x54, 0x72, 0x61, 0x63, 0x6B, 0x2D, 0x49, 0x6E, 0x66, 0x6F - }; + const string _du54Id = "MV - CPC format Disk Image (DU54)"; + + /// Identifier for Extended CPCEMU disk images + const string _edskId = "EXTENDED CPC DSK File"; + + /// Identifier for track information, + const string _trackId = "Track-Info"; } } \ No newline at end of file diff --git a/Aaru.Images/CPCDSK/Identify.cs b/Aaru.Images/CPCDSK/Identify.cs index 58de835b9..eb790c251 100644 --- a/Aaru.Images/CPCDSK/Identify.cs +++ b/Aaru.Images/CPCDSK/Identify.cs @@ -30,11 +30,11 @@ // Copyright © 2011-2021 Natalia Portillo // ****************************************************************************/ +using System; using System.IO; -using System.Linq; +using System.Text; using Aaru.CommonTypes.Interfaces; using Aaru.Console; -using Aaru.Helpers; namespace Aaru.DiscImages { @@ -50,13 +50,26 @@ namespace Aaru.DiscImages byte[] headerB = new byte[256]; stream.Read(headerB, 0, 256); - DiskInfo header = Marshal.ByteArrayToStructureLittleEndian(headerB); - AaruConsole.DebugWriteLine("CPCDSK plugin", "header.magic = \"{0}\"", - StringHandlers.CToString(header.magic)); + int pos; - return _cpcdskId.SequenceEqual(header.magic.Take(_cpcdskId.Length)) || - _edskId.SequenceEqual(header.magic) || _du54Id.SequenceEqual(header.magic); + for(pos = 0; pos < 254; pos++) + { + if(headerB[pos] == 0x0D && + headerB[pos + 1] == 0x0A) + break; + } + + if(pos >= 254) + return false; + + string magic = Encoding.ASCII.GetString(headerB, 0, pos); + + AaruConsole.DebugWriteLine("CPCDSK plugin", "magic = \"{0}\"", magic); + + return string.Compare(_cpcdskId, magic, StringComparison.InvariantCultureIgnoreCase) == 0 || + string.Compare(_edskId, magic, StringComparison.InvariantCultureIgnoreCase) == 0 || + string.Compare(_du54Id, magic, StringComparison.InvariantCultureIgnoreCase) == 0; } } } \ No newline at end of file diff --git a/Aaru.Images/CPCDSK/Read.cs b/Aaru.Images/CPCDSK/Read.cs index d806c8021..3421e7456 100644 --- a/Aaru.Images/CPCDSK/Read.cs +++ b/Aaru.Images/CPCDSK/Read.cs @@ -34,6 +34,7 @@ using System; using System.Collections.Generic; using System.IO; using System.Linq; +using System.Text; using Aaru.Checksums; using Aaru.CommonTypes; using Aaru.CommonTypes.Enums; @@ -57,22 +58,39 @@ namespace Aaru.DiscImages byte[] headerB = new byte[256]; stream.Read(headerB, 0, 256); - DiskInfo header = Marshal.ByteArrayToStructureLittleEndian(headerB); - if(!_cpcdskId.SequenceEqual(header.magic.Take(_cpcdskId.Length)) && - !_edskId.SequenceEqual(header.magic) && - !_du54Id.SequenceEqual(header.magic)) + int pos; + + for(pos = 0; pos < 254; pos++) + { + if(headerB[pos] == 0x0D && + headerB[pos + 1] == 0x0A) + break; + } + + if(pos >= 254) return false; - _extended = _edskId.SequenceEqual(header.magic); + string magic = Encoding.ASCII.GetString(headerB, 0, pos); + + stream.Position = pos + 2; + stream.Read(headerB, 0, 256); + + DiskInfo header = Marshal.ByteArrayToStructureLittleEndian(headerB); + + if(string.Compare(_cpcdskId, magic, StringComparison.InvariantCultureIgnoreCase) != 0 && + string.Compare(_edskId, magic, StringComparison.InvariantCultureIgnoreCase) != 0 && + string.Compare(_du54Id, magic, StringComparison.InvariantCultureIgnoreCase) != 0) + return false; + + _extended = string.Compare(_edskId, magic, StringComparison.InvariantCultureIgnoreCase) == 0; AaruConsole.DebugWriteLine("CPCDSK plugin", "Extended = {0}", _extended); + AaruConsole.DebugWriteLine("CPCDSK plugin", "magic = \"{0}\"", magic); + AaruConsole.DebugWriteLine("CPCDSK plugin", "header.magic = \"{0}\"", StringHandlers.CToString(header.magic)); - AaruConsole.DebugWriteLine("CPCDSK plugin", "header.magic2 = \"{0}\"", - StringHandlers.CToString(header.magic2)); - AaruConsole.DebugWriteLine("CPCDSK plugin", "header.creator = \"{0}\"", StringHandlers.CToString(header.creator)); @@ -113,7 +131,8 @@ namespace Aaru.DiscImages stream.Read(trackB, 0, 256); TrackInfo trackInfo = Marshal.ByteArrayToStructureLittleEndian(trackB); - if(!_trackId.SequenceEqual(trackInfo.magic)) + if(string.Compare(_trackId, Encoding.ASCII.GetString(trackInfo.magic), + StringComparison.InvariantCultureIgnoreCase) != 0) { AaruConsole.ErrorWriteLine("Not the expected track info."); diff --git a/Aaru.Images/CPCDSK/Structs.cs b/Aaru.Images/CPCDSK/Structs.cs index 4228de7bf..57ad3d0f7 100644 --- a/Aaru.Images/CPCDSK/Structs.cs +++ b/Aaru.Images/CPCDSK/Structs.cs @@ -40,12 +40,9 @@ namespace Aaru.DiscImages [StructLayout(LayoutKind.Sequential, Pack = 1)] readonly struct DiskInfo { - /// Magic number, "MV - CPC" in old files, "EXTENDED CPC DSK File" in extended ones - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 21)] + /// Second part of magic, should be "Disk-Info\r\n" in all, but some emulators write spaces instead. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 11)] public readonly byte[] magic; - /// Second part of magic, should be "\r\nDisk-Info\r\n" in all, but some emulators write spaces instead. - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 13)] - public readonly byte[] magic2; /// Creator application (can be null) [MarshalAs(UnmanagedType.ByValArray, SizeConst = 14)] public readonly byte[] creator;