From ca179dd4240923051c910a14b8b49f452c223db8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Dr=C3=BCing?= Date: Wed, 29 Aug 2018 13:09:04 +0200 Subject: [PATCH] Add support for DataPackRat's f2d/d2f disk images They are identified by "WC DISK IMAGE" in the header --- .../DiscImageChef.DiscImages.csproj | 6 + .../WCDiskImage/Identify.cs | 82 ++++++ .../WCDiskImage/Properties.cs | 63 ++++ DiscImageChef.DiscImages/WCDiskImage/Read.cs | 274 ++++++++++++++++++ .../WCDiskImage/Structs.cs | 175 +++++++++++ .../WCDiskImage/Unsupported.cs | 139 +++++++++ .../WCDiskImage/WCDiskImage.cs | 85 ++++++ 7 files changed, 824 insertions(+) create mode 100644 DiscImageChef.DiscImages/WCDiskImage/Identify.cs create mode 100644 DiscImageChef.DiscImages/WCDiskImage/Properties.cs create mode 100644 DiscImageChef.DiscImages/WCDiskImage/Read.cs create mode 100644 DiscImageChef.DiscImages/WCDiskImage/Structs.cs create mode 100644 DiscImageChef.DiscImages/WCDiskImage/Unsupported.cs create mode 100644 DiscImageChef.DiscImages/WCDiskImage/WCDiskImage.cs diff --git a/DiscImageChef.DiscImages/DiscImageChef.DiscImages.csproj b/DiscImageChef.DiscImages/DiscImageChef.DiscImages.csproj index 492a84bb1..d8cb7c164 100644 --- a/DiscImageChef.DiscImages/DiscImageChef.DiscImages.csproj +++ b/DiscImageChef.DiscImages/DiscImageChef.DiscImages.csproj @@ -433,6 +433,12 @@ + + + + + + diff --git a/DiscImageChef.DiscImages/WCDiskImage/Identify.cs b/DiscImageChef.DiscImages/WCDiskImage/Identify.cs new file mode 100644 index 000000000..5d6912c76 --- /dev/null +++ b/DiscImageChef.DiscImages/WCDiskImage/Identify.cs @@ -0,0 +1,82 @@ +// /*************************************************************************** +// The Disc Image Chef +// ---------------------------------------------------------------------------- +// +// Filename : Identify.cs +// Author(s) : Michael Drüing +// +// Component : Disk image plugins. +// +// --[ Description ] ---------------------------------------------------------- +// +// Identifies d2f/WC DISK IMAGE disk images. +// +// --[ 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 © 2018 Michael Drüing +// Copyright © 2011-2018 Natalia Portillo +// ****************************************************************************/ + +using System; +using System.IO; +using System.Text; +using System.Runtime.InteropServices; +using DiscImageChef.CommonTypes.Interfaces; + +namespace DiscImageChef.DiscImages +{ + public partial class WCDiskImage + { + public bool Identify(IFilter imageFilter) + { + Stream stream = imageFilter.GetDataForkStream(); + stream.Seek(0, SeekOrigin.Begin); + + if (stream.Length < 32) return false; + + byte[] header = new byte[32]; + stream.Read(header, 0, 32); + + IntPtr hdrPtr = Marshal.AllocHGlobal(32); + Marshal.Copy(header, 0, hdrPtr, 32); + WCDiskImageFileHeader fheader = (WCDiskImageFileHeader)Marshal.PtrToStructure(hdrPtr, typeof(WCDiskImageFileHeader)); + Marshal.FreeHGlobal(hdrPtr); + + /* check the signature */ + if (Encoding.ASCII.GetString(fheader.signature).TrimEnd('\x00') != WCDiskImage.fileSignature) + return false; + + /* Some sanity checks on the values we just read. */ + if (fheader.version > 1) return false; + + if (fheader.heads < 1 || fheader.heads > 2) return false; + + if (fheader.sectorsPerTrack < 8 || fheader.sectorsPerTrack > 18) return false; + + if (fheader.cylinders < 1 || fheader.cylinders > 80) return false; + + if (fheader.extraTracks[0] > 1 || fheader.extraTracks[1] > 1 || fheader.extraTracks[2] > 1 || fheader.extraTracks[3] > 1) + return false; + + if (((byte)fheader.extraFlags & ~0x03) != 0) return false; + + // TODO: validate all sectors + // For now, having a valid header will suffice. + return true; + } + } +} \ No newline at end of file diff --git a/DiscImageChef.DiscImages/WCDiskImage/Properties.cs b/DiscImageChef.DiscImages/WCDiskImage/Properties.cs new file mode 100644 index 000000000..87171b1b7 --- /dev/null +++ b/DiscImageChef.DiscImages/WCDiskImage/Properties.cs @@ -0,0 +1,63 @@ +// /*************************************************************************** +// The Disc Image Chef +// ---------------------------------------------------------------------------- +// +// Filename : Properties.cs +// Author(s) : Michael Drüing +// +// Component : Disk image plugins. +// +// --[ Description ] ---------------------------------------------------------- +// +// Contains properties for d2f disk images. +// +// --[ 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 © 2018 Michael Drüing +// Copyright © 2011-2018 Natalia Portillo +// ****************************************************************************/ + +using System; +using System.Collections.Generic; +using DiscImageChef.CommonTypes; +using DiscImageChef.CommonTypes.Exceptions; +using DiscImageChef.CommonTypes.Structs; +using Schemas; + +namespace DiscImageChef.DiscImages +{ + public partial class WCDiskImage + { + public ImageInfo Info => imageInfo; + + public string Name => "d2f disk image"; + public Guid Id => new Guid("DDE01493-BCA2-41C2-A269-7E56D3716D2F"); + + public string Format => "d2f disk image"; + public List Partitions => + throw new FeatureUnsupportedImageException("Feature not supported by image format"); + + public List Tracks => + throw new FeatureUnsupportedImageException("Feature not supported by image format"); + + public List Sessions => + throw new FeatureUnsupportedImageException("Feature not supported by image format"); + + public List DumpHardware => null; + public CICMMetadataType CicmMetadata => null; + } +} \ No newline at end of file diff --git a/DiscImageChef.DiscImages/WCDiskImage/Read.cs b/DiscImageChef.DiscImages/WCDiskImage/Read.cs new file mode 100644 index 000000000..29163345b --- /dev/null +++ b/DiscImageChef.DiscImages/WCDiskImage/Read.cs @@ -0,0 +1,274 @@ +// /*************************************************************************** +// The Disc Image Chef +// ---------------------------------------------------------------------------- +// +// Filename : Read.cs +// Author(s) : Michael Drüing +// +// Component : Disk image plugins. +// +// --[ Description ] ---------------------------------------------------------- +// +// Reads d2f disk images. +// +// --[ 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 © 2018 Michael Drüing +// Copyright © 2011-2018 Natalia Portillo +// ****************************************************************************/ + +using System; +using System.IO; +using System.Text; +using System.Runtime.InteropServices; +using DiscImageChef.CommonTypes; +using DiscImageChef.CommonTypes.Enums; +using DiscImageChef.CommonTypes.Interfaces; +using DiscImageChef.Console; +using DiscImageChef.Checksums; + +namespace DiscImageChef.DiscImages +{ + public partial class WCDiskImage + { + /// + /// Read a whole track and cache it + /// + /// The stream to read from + /// The cylinder number of the track being read. + /// The head number of the track being read. + void ReadTrack(Stream stream, int cyl, int head) + { + byte[] sectorData; + byte[] crc; + short calculatedCRC; + + for (int sect = 1; sect < imageInfo.SectorsPerTrack + 1; sect++) + { + /* read the sector header */ + byte[] sheaderBuffer = new byte[6]; + stream.Read(sheaderBuffer, 0, 6); + IntPtr sectPtr = Marshal.AllocHGlobal(6); + Marshal.Copy(sheaderBuffer, 0, sectPtr, 6); + WCDiskImageSectorHeader sheader = (WCDiskImageSectorHeader)Marshal.PtrToStructure(sectPtr, typeof(WCDiskImageSectorHeader)); + Marshal.FreeHGlobal(sectPtr); + + /* validate the sector header */ + if ((sheader.cylinder != cyl) || (sheader.head != head) || (sheader.sector != sect)) + throw new InvalidDataException(String.Format("Unexpected sector encountered. Found CHS {0},{1},{2} but expected {3},{4},{5}", + sheader.cylinder, sheader.head, sheader.sector, cyl, head, sect)); + + sectorData = new byte[512]; + /* read the sector data */ + switch (sheader.flag) + { + case SectorFlag.Normal: /* read a normal sector and store it in cache */ + stream.Read(sectorData, 0, 512); + sectorCache[(cyl, head, sect)] = sectorData; + Crc16Context.Data(sectorData, 512, out crc); + calculatedCRC = (short)(256 * crc[0] | crc[1]); + /* + DicConsole.DebugWriteLine("d2f plugin", "CHS {0},{1},{2}: Regular sector, stored CRC=0x{3:x4}, calculated CRC=0x{4:x4}", + cyl, head, sect, sheader.crc, 256 * crc[0] + crc[1]); + */ + badSectors[(cyl, head, sect)] = sheader.crc != calculatedCRC; + if (calculatedCRC != sheader.crc) + { + DicConsole.DebugWriteLine("d2f plugin", "CHS {0},{1},{2}: CRC mismatch: stored CRC=0x{3:x4}, calculated CRC=0x{4:x4}", + cyl, head, sect, sheader.crc, calculatedCRC); + } + + break; + case SectorFlag.BadSector: + /* + DicConsole.DebugWriteLine("d2f plugin", "CHS {0},{1},{2}: Bad sector", + cyl, head, sect); + */ + badSectors[(cyl, head, sect)] = true; + + break; + case SectorFlag.RepeatByte: + /* + DicConsole.DebugWriteLine("d2f plugin", "CHS {0},{1},{2}: RepeatByte sector, fill byte 0x{0:x2}", + cyl, head, sect, sheader.crc & 0xff); + */ + for (int i = 0; i < 512; i++) sectorData[i] = (byte)(sheader.crc & 0xff); + + sectorCache[(cyl, head, sect)] = sectorData; + badSectors[(cyl, head, sect)] = false; + + break; + default: + throw new InvalidDataException(String.Format("Invalid sector type '{0}' encountered", sheader.flag.ToString())); + } + } + } + + public bool Open(IFilter imageFilter) + { + string comments = String.Empty; + Stream stream = imageFilter.GetDataForkStream(); + stream.Seek(0, SeekOrigin.Begin); + + byte[] header = new byte[32]; + stream.Read(header, 0, 32); + + IntPtr hdrPtr = Marshal.AllocHGlobal(32); + Marshal.Copy(header, 0, hdrPtr, 32); + WCDiskImageFileHeader fheader = (WCDiskImageFileHeader)Marshal.PtrToStructure(hdrPtr, typeof(WCDiskImageFileHeader)); + Marshal.FreeHGlobal(hdrPtr); + DicConsole.DebugWriteLine("d2f plugin", + "Detected WC DISK IMAGE with {0} heads, {1} tracks and {2} sectors per track.", + fheader.heads, fheader.cylinders, fheader.sectorsPerTrack); + + imageInfo.Cylinders = (uint)fheader.cylinders; + imageInfo.SectorsPerTrack = fheader.sectorsPerTrack; + imageInfo.SectorSize = 512; // only 512 bytes per sector supported + imageInfo.Heads = fheader.heads; + imageInfo.Sectors = imageInfo.Heads * imageInfo.Cylinders * imageInfo.SectorsPerTrack; + imageInfo.ImageSize = imageInfo.Sectors * imageInfo.SectorSize; + + imageInfo.XmlMediaType = XmlMediaType.BlockMedia; + + imageInfo.CreationTime = imageFilter.GetCreationTime(); + imageInfo.LastModificationTime = imageFilter.GetLastWriteTime(); + imageInfo.MediaTitle = Path.GetFileNameWithoutExtension(imageFilter.GetFilename()); + imageInfo.MediaType = Geometry.GetMediaType(((ushort)imageInfo.Cylinders, (byte)imageInfo.Heads, + (ushort)imageInfo.SectorsPerTrack, 512, MediaEncoding.MFM, + false)); + + /* buffer the entire disk in memory */ + for (int cyl = 0; cyl < imageInfo.Cylinders; cyl++) + { + for (int head = 0; head < imageInfo.Heads; head++) + { + ReadTrack(stream, cyl, head); + } + } + + /* if there are extra tracks, read them as well */ + if (fheader.extraTracks[0] == 1) + { + DicConsole.DebugWriteLine("d2f plugin", "Extra track 1 (head 0) present, reading"); + ReadTrack(stream, (int)imageInfo.Cylinders, 0); + } + if (fheader.extraTracks[1] == 1) + { + DicConsole.DebugWriteLine("d2f plugin", "Extra track 1 (head 1) present, reading"); + ReadTrack(stream, (int)imageInfo.Cylinders, 1); + } + if (fheader.extraTracks[2] == 1) + { + DicConsole.DebugWriteLine("d2f plugin", "Extra track 2 (head 0) present, reading"); + ReadTrack(stream, (int)imageInfo.Cylinders + 1, 0); + } + if (fheader.extraTracks[3] == 1) + { + DicConsole.DebugWriteLine("d2f plugin", "Extra track 2 (head 1) present, reading"); + ReadTrack(stream, (int)imageInfo.Cylinders + 1, 1); + } + + /* adjust number of cylinders */ + if (fheader.extraTracks[0] == 1 || fheader.extraTracks[1] == 1) + imageInfo.Cylinders++; + if (fheader.extraTracks[2] == 1 || fheader.extraTracks[3] == 1) + imageInfo.Cylinders++; + + /* read the comment and directory data if present */ + if (fheader.extraFlags.HasFlag(ExtraFlag.Comment)) + { + DicConsole.DebugWriteLine("d2f plugin", "Comment present, reading"); + byte[] sheaderBuffer = new byte[6]; + stream.Read(sheaderBuffer, 0, 6); + IntPtr sectPtr = Marshal.AllocHGlobal(6); + Marshal.Copy(sheaderBuffer, 0, sectPtr, 6); + WCDiskImageSectorHeader sheader = (WCDiskImageSectorHeader)Marshal.PtrToStructure(sectPtr, typeof(WCDiskImageSectorHeader)); + Marshal.FreeHGlobal(sectPtr); + + if (sheader.flag != SectorFlag.Comment) + throw new InvalidDataException(String.Format("Invalid sector type '{0}' encountered", sheader.flag.ToString())); + + byte[] comm = new byte[sheader.crc]; + stream.Read(comm, 0, sheader.crc); + comments += Encoding.ASCII.GetString(comm) + Environment.NewLine; + } + + if (fheader.extraFlags.HasFlag(ExtraFlag.Directory)) + { + DicConsole.DebugWriteLine("d2f plugin", "Directory listing present, reading"); + byte[] sheaderBuffer = new byte[6]; + stream.Read(sheaderBuffer, 0, 6); + IntPtr sectPtr = Marshal.AllocHGlobal(6); + Marshal.Copy(sheaderBuffer, 0, sectPtr, 6); + WCDiskImageSectorHeader sheader = (WCDiskImageSectorHeader)Marshal.PtrToStructure(sectPtr, typeof(WCDiskImageSectorHeader)); + Marshal.FreeHGlobal(sectPtr); + + if (sheader.flag != SectorFlag.Directory) + throw new InvalidDataException(String.Format("Invalid sector type '{0}' encountered", sheader.flag.ToString())); + + byte[] dir = new byte[sheader.crc]; + stream.Read(dir, 0, sheader.crc); + comments += Encoding.ASCII.GetString(dir); + } + if (comments.Length > 0) + imageInfo.Comments = comments; + + // save some variables for later use + fileHeader = fheader; + wcImageFilter = imageFilter; + return true; + } + + public byte[] ReadSector(ulong sectorAddress) + { + int sectorNumber = (int)(sectorAddress % imageInfo.SectorsPerTrack) + 1; + int trackNumber = (int)(sectorAddress / imageInfo.SectorsPerTrack); + int headNumber = imageInfo.Heads > 1 ? trackNumber % 2 : 0; + int cylinderNumber = imageInfo.Heads > 1 ? trackNumber / 2 : trackNumber; + + if (badSectors[(cylinderNumber, headNumber, sectorNumber)]) + { + DicConsole.DebugWriteLine("d2f plugin", "reading bad sector {0} ({1},{2},{3})", + sectorAddress, cylinderNumber, headNumber, sectorNumber); + + /* if we have sector data, return that */ + if (sectorCache.ContainsKey((cylinderNumber, headNumber, sectorNumber))) + { + return sectorCache[(cylinderNumber, headNumber, sectorNumber)]; + } + + /* otherwise, return an empty sector */ + return new byte[512]; + } + + return sectorCache[(cylinderNumber, headNumber, sectorNumber)]; + } + + public byte[] ReadSectors(ulong sectorAddress, uint length) + { + byte[] result = new byte[length * imageInfo.SectorSize]; + + if (sectorAddress + length > imageInfo.Sectors) + throw new ArgumentOutOfRangeException(nameof(length), "Requested more sectors than available"); + + for (int i = 0; i < length; i++) + ReadSector(sectorAddress + (ulong)i).CopyTo(result, i * imageInfo.SectorSize); + + return result; + } + } +} \ No newline at end of file diff --git a/DiscImageChef.DiscImages/WCDiskImage/Structs.cs b/DiscImageChef.DiscImages/WCDiskImage/Structs.cs new file mode 100644 index 000000000..5477002b2 --- /dev/null +++ b/DiscImageChef.DiscImages/WCDiskImage/Structs.cs @@ -0,0 +1,175 @@ +// /*************************************************************************** +// The Disc Image Chef +// ---------------------------------------------------------------------------- +// +// Filename : Structs.cs +// Author(s) : Michael Drüing +// +// Component : Disk image plugins. +// +// --[ Description ] ---------------------------------------------------------- +// +// Contains structures for d2f disk images. +// +// --[ 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 © 2018 Michael Drüing +// Copyright © 2011-2018 Natalia Portillo +// ****************************************************************************/ + +using System.Runtime.InteropServices; + +namespace DiscImageChef.DiscImages +{ + public partial class WCDiskImage + { + /// + /// The expected signature of a proper image file. + /// + const string fileSignature = "WC DISK IMAGE\x1a\x1a"; + + /// + /// The global header of a WCDiskImage file + /// + [StructLayout(LayoutKind.Sequential, Pack = 1)] + struct WCDiskImageFileHeader + { + /// + /// The signature should be "WC DISK IMAGE\0x1a\0x1a\0x00" + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] + public byte[] signature; + + /// + /// Version (currently only version 0 and 1 is known) + /// + public byte version; + + /// + /// The number of heads. Only 1 or 2 is supported + /// + public byte heads; + + /// + /// Sectors per track, maximum is 18 + /// + public byte sectorsPerTrack; + + /// + /// The number of tracks/cylinders. 80 is the maximum + /// + public byte cylinders; + + /// + /// The "extra tracks" that are present. What this means is that the + /// tracks 81 and 82 might contain data (on an 80-track disk) and that + /// this data was dumped too. The order is head0extra1, head1extra1, + /// head0extra2, head1extra2. 1 means track is present. + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] + public byte[] extraTracks; + + /// + /// Additional metadata present flags. + /// + public ExtraFlag extraFlags; + + /// + /// Padding to make the header 32 bytes. + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 7)] + public byte[] reserved; + } + + enum ExtraFlag : byte + { + /// + /// Set if a Comment is present after the image + /// + Comment = 0x01, + + /// + /// Set if a directory listing is present after the image + /// + Directory = 0x02, + } + + /// + /// The Sector header that precedes each sector + /// + [StructLayout(LayoutKind.Sequential, Pack = 1)] + struct WCDiskImageSectorHeader + { + /// + /// The sector flag (i.e. type) + /// + public SectorFlag flag; + + /// + /// The head this sector belongs to. + /// + public byte head; + + /// + /// The sector number within the track. Must be consecutive. + /// + public byte sector; + + /// + /// The cylinder number this sector belongs to. + /// + public byte cylinder; + + + /// + /// A simple CRC16 over the data, to detect errors. + /// + public short crc; + } + + enum SectorFlag : byte + { + /// + /// A normal sector + /// + Normal = 0x00, + + /// + /// A bad sector that could not be read + /// + BadSector = 0x01, + + /// + /// A sector filled with a repeating byte value. The value + /// is encoded in the LSB of the crc field. + /// + RepeatByte = 0x02, + + /// + /// Not a sector but a comment. Must come after all user data. + /// The crc field is the length of the comment data. + /// + Comment = 0x03, + + /// + /// Not a sector but the directory information. + /// The crc field is the length of the data. + /// + Directory = 0x04, + } + } +} \ No newline at end of file diff --git a/DiscImageChef.DiscImages/WCDiskImage/Unsupported.cs b/DiscImageChef.DiscImages/WCDiskImage/Unsupported.cs new file mode 100644 index 000000000..982c648c8 --- /dev/null +++ b/DiscImageChef.DiscImages/WCDiskImage/Unsupported.cs @@ -0,0 +1,139 @@ + +// The Disc Image Chef +// ---------------------------------------------------------------------------- +// +// Filename : Unsupported.cs +// Author(s) : Michael Drüing +// +// Component : Disk image plugins. +// +// --[ Description ] ---------------------------------------------------------- +// +// Contains features unsupported by d2f disk images. +// +// --[ 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 © 2018 Michael Drüing +// Copyright © 2011-2018 Natalia Portillo +// ****************************************************************************/ + +using System.Collections.Generic; +using DiscImageChef.CommonTypes.Enums; +using DiscImageChef.CommonTypes.Exceptions; +using DiscImageChef.CommonTypes.Structs; + +namespace DiscImageChef.DiscImages +{ + public partial class WCDiskImage + { + public byte[] ReadDiskTag(MediaTagType tag) + { + throw new FeatureUnsupportedImageException("Feature not supported by image format"); + } + + public byte[] ReadSectorTag(ulong sectorAddress, SectorTagType tag) + { + throw new FeatureUnsupportedImageException("Feature not supported by image format"); + } + + public byte[] ReadSector(ulong sectorAddress, uint track) + { + throw new FeatureUnsupportedImageException("Feature not supported by image format"); + } + + public byte[] ReadSectorTag(ulong sectorAddress, uint track, SectorTagType tag) + { + throw new FeatureUnsupportedImageException("Feature not supported by image format"); + } + + public byte[] ReadSectorsTag(ulong sectorAddress, uint length, SectorTagType tag) + { + throw new FeatureUnsupportedImageException("Feature not supported by image format"); + } + + public byte[] ReadSectors(ulong sectorAddress, uint length, uint track) + { + throw new FeatureUnsupportedImageException("Feature not supported by image format"); + } + + public byte[] ReadSectorsTag(ulong sectorAddress, uint length, uint track, SectorTagType tag) + { + throw new FeatureUnsupportedImageException("Feature not supported by image format"); + } + + public byte[] ReadSectorLong(ulong sectorAddress) + { + throw new FeatureUnsupportedImageException("Feature not supported by image format"); + } + + public byte[] ReadSectorLong(ulong sectorAddress, uint track) + { + throw new FeatureUnsupportedImageException("Feature not supported by image format"); + } + + public byte[] ReadSectorsLong(ulong sectorAddress, uint length) + { + throw new FeatureUnsupportedImageException("Feature not supported by image format"); + } + + public byte[] ReadSectorsLong(ulong sectorAddress, uint length, uint track) + { + throw new FeatureUnsupportedImageException("Feature not supported by image format"); + } + + public List GetSessionTracks(Session session) + { + throw new FeatureUnsupportedImageException("Feature not supported by image format"); + } + + public List GetSessionTracks(ushort session) + { + throw new FeatureUnsupportedImageException("Feature not supported by image format"); + } + + public bool? VerifySector(ulong sectorAddress) + { + return null; + } + + public bool? VerifySector(ulong sectorAddress, uint track) + { + throw new FeatureUnsupportedImageException("Feature not supported by image format"); + } + + public bool? VerifySectors(ulong sectorAddress, uint length, out List failingLbas, + out List unknownLbas) + { + failingLbas = new List(); + unknownLbas = new List(); + for (ulong i = 0; i < imageInfo.Sectors; i++) unknownLbas.Add(i); + + return null; + } + + public bool? VerifySectors(ulong sectorAddress, uint length, uint track, out List failingLbas, + out List unknownLbas) + { + throw new FeatureUnsupportedImageException("Feature not supported by image format"); + } + + public bool? VerifyMediaImage() + { + return null; + } + } +} \ No newline at end of file diff --git a/DiscImageChef.DiscImages/WCDiskImage/WCDiskImage.cs b/DiscImageChef.DiscImages/WCDiskImage/WCDiskImage.cs new file mode 100644 index 000000000..5b195525a --- /dev/null +++ b/DiscImageChef.DiscImages/WCDiskImage/WCDiskImage.cs @@ -0,0 +1,85 @@ +// /*************************************************************************** +// The Disc Image Chef +// ---------------------------------------------------------------------------- +// +// Filename : WCDiskImage.cs +// Author(s) : Michael Drüing +// +// Component : Disk image plugins. +// +// --[ Description ] ---------------------------------------------------------- +// +// Manages floppy disk images created with d2f by DataPackRat +// +// --[ 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 © 2018 Michael Drüing +// Copyright © 2011-2018 Natalia Portillo +// ****************************************************************************/ + +using System.Collections.Generic; +using DiscImageChef.CommonTypes.Enums; +using DiscImageChef.CommonTypes.Interfaces; +using DiscImageChef.CommonTypes.Structs; + +namespace DiscImageChef.DiscImages +{ + public partial class WCDiskImage : IMediaImage + { + /// + /// The file header after the image has been opened + /// + WCDiskImageFileHeader fileHeader; + + /// + /// The ImageFilter we're reading from, after the file has been opened + /// + IFilter wcImageFilter; + ImageInfo imageInfo; + + /* the sectors are cached here */ + public Dictionary<(int cylinder, int head, int sector), byte[]> sectorCache = new Dictionary<(int cylinder, int head, int sector), byte[]>(); + public Dictionary<(int cylinder, int head, int sector), bool> badSectors = new Dictionary<(int cylinder, int head, int sector), bool>(); + + public WCDiskImage() + { + imageInfo = new ImageInfo + { + ReadableSectorTags = new List(), + ReadableMediaTags = new List(), + HasPartitions = false, + HasSessions = false, + Version = null, + Application = null, + ApplicationVersion = null, + Creator = null, + Comments = null, + MediaManufacturer = null, + MediaModel = null, + MediaSerialNumber = null, + MediaBarcode = null, + MediaPartNumber = null, + MediaSequence = 0, + LastMediaSequence = 0, + DriveManufacturer = null, + DriveModel = null, + DriveSerialNumber = null, + DriveFirmwareRevision = null + }; + } + } +} \ No newline at end of file