🎨Converted all plugin types to interfaces.

This commit is contained in:
2017-12-26 06:05:12 +00:00
parent a002253fa4
commit f66a0bdd42
295 changed files with 9499 additions and 10414 deletions

View File

@@ -35,12 +35,12 @@ using System.Collections.Generic;
using System.Text;
using DiscImageChef.CommonTypes;
using DiscImageChef.DiscImages;
using Schemas;
namespace DiscImageChef.Filesystems.CPM
{
partial class CPM : Filesystem
partial class CPM : IFilesystem
{
readonly ImagePlugin device;
/// <summary>
/// True if <see cref="Identify" /> thinks this is a CP/M filesystem
/// </summary>
@@ -50,6 +50,8 @@ namespace DiscImageChef.Filesystems.CPM
/// Cached <see cref="FileSystemInfo" />
/// </summary>
FileSystemInfo cpmStat;
Encoding currentEncoding;
/// <summary>
/// Cached file passwords, decoded
/// </summary>
@@ -59,6 +61,7 @@ namespace DiscImageChef.Filesystems.CPM
/// Stores all known CP/M disk definitions
/// </summary>
CpmDefinitions definitions;
IMediaImage device;
/// <summary>
/// Cached directory listing
/// </summary>
@@ -109,28 +112,10 @@ namespace DiscImageChef.Filesystems.CPM
/// If <see cref="Identify" /> thinks this is a CP/M filesystem, this is the definition for it
/// </summary>
CpmDefinition workingDefinition;
public CPM()
{
Name = "CP/M File System";
PluginUuid = new Guid("AA2B8585-41DF-4E3B-8A35-D1A935E2F8A1");
CurrentEncoding = Encoding.GetEncoding("IBM437");
}
public CPM(Encoding encoding)
{
Name = "CP/M File System";
PluginUuid = new Guid("AA2B8585-41DF-4E3B-8A35-D1A935E2F8A1");
CurrentEncoding = encoding ?? Encoding.GetEncoding("IBM437");
}
public CPM(ImagePlugin imagePlugin, Partition partition, Encoding encoding)
{
device = imagePlugin;
this.partition = partition;
Name = "CP/M File System";
PluginUuid = new Guid("AA2B8585-41DF-4E3B-8A35-D1A935E2F8A1");
CurrentEncoding = encoding ?? Encoding.GetEncoding("IBM437");
}
FileSystemType xmlFsType;
public virtual FileSystemType XmlFsType => xmlFsType;
public virtual Encoding Encoding => currentEncoding;
public virtual string Name => "CP/M File System";
public virtual Guid Id => new Guid("AA2B8585-41DF-4E3B-8A35-D1A935E2F8A1");
}
}

View File

@@ -39,7 +39,7 @@ namespace DiscImageChef.Filesystems.CPM
{
partial class CPM
{
public override Errno ReadDir(string path, ref List<string> contents)
public virtual Errno ReadDir(string path, ref List<string> contents)
{
if(!mounted) return Errno.AccessDenied;

View File

@@ -36,7 +36,7 @@ namespace DiscImageChef.Filesystems.CPM
{
partial class CPM
{
public override Errno GetAttributes(string path, ref FileAttributes attributes)
public virtual Errno GetAttributes(string path, ref FileAttributes attributes)
{
if(!mounted) return Errno.AccessDenied;
@@ -59,12 +59,12 @@ namespace DiscImageChef.Filesystems.CPM
}
// TODO: Implementing this would require storing the interleaving
public override Errno MapBlock(string path, long fileBlock, ref long deviceBlock)
public virtual Errno MapBlock(string path, long fileBlock, ref long deviceBlock)
{
return !mounted ? Errno.AccessDenied : Errno.NotImplemented;
}
public override Errno Read(string path, long offset, long size, ref byte[] buf)
public virtual Errno Read(string path, long offset, long size, ref byte[] buf)
{
if(!mounted) return Errno.AccessDenied;
@@ -90,12 +90,12 @@ namespace DiscImageChef.Filesystems.CPM
return Errno.NoError;
}
public override Errno ReadLink(string path, ref string dest)
public virtual Errno ReadLink(string path, ref string dest)
{
return !mounted ? Errno.AccessDenied : Errno.NotSupported;
}
public override Errno Stat(string path, ref FileEntryInfo stat)
public virtual Errno Stat(string path, ref FileEntryInfo stat)
{
if(!mounted) return Errno.AccessDenied;
@@ -107,7 +107,7 @@ namespace DiscImageChef.Filesystems.CPM
if(labelCreationDate != null) stat.CreationTime = DateHandlers.CpmToDateTime(labelCreationDate);
if(labelUpdateDate != null) stat.StatusChangeTime = DateHandlers.CpmToDateTime(labelUpdateDate);
stat.Attributes = FileAttributes.Directory;
stat.BlockSize = XmlFsType.ClusterSize;
stat.BlockSize = xmlFsType.ClusterSize;
return Errno.NoError;
}

View File

@@ -44,11 +44,11 @@ namespace DiscImageChef.Filesystems.CPM
{
partial class CPM
{
public override bool Identify(ImagePlugin imagePlugin, Partition partition)
public virtual bool Identify(IMediaImage imagePlugin, Partition partition)
{
// This will only continue on devices with a chance to have ever been used by CP/M while failing on all others
// It's ugly, but will stop a lot of false positives
switch(imagePlugin.ImageInfo.MediaType)
switch(imagePlugin.Info.MediaType)
{
case MediaType.Unknown:
case MediaType.Apple32SS:
@@ -203,8 +203,8 @@ namespace DiscImageChef.Filesystems.CPM
sectorSize = (ulong)(128 << amsSb.psh);
// Compare device limits from superblock to real limits
if(sectorSize == imagePlugin.ImageInfo.SectorSize &&
sectorCount == imagePlugin.ImageInfo.Sectors)
if(sectorSize == imagePlugin.Info.SectorSize &&
sectorCount == imagePlugin.Info.Sectors)
{
cpmFound = true;
firstDirectorySector = (ulong)(amsSb.off * amsSb.spt);
@@ -319,7 +319,7 @@ namespace DiscImageChef.Filesystems.CPM
(ulong)((hddSb.firstCylinder * hddSb.heads + hddSb.heads) * hddSb.sectorsPerTrack);
// If volume size corresponds with working partition (this variant will be inside MBR partitioning)
if(sectorSize == imagePlugin.ImageInfo.SectorSize && startingSector == partition.Start &&
if(sectorSize == imagePlugin.Info.SectorSize && startingSector == partition.Start &&
sectorsInPartition + partition.Start <= partition.End)
{
cpmFound = true;
@@ -405,7 +405,7 @@ namespace DiscImageChef.Filesystems.CPM
switch((FormatByte)formatByte)
{
case FormatByte.k160:
if(imagePlugin.ImageInfo.SectorSize == 512 && imagePlugin.ImageInfo.Sectors == 320)
if(imagePlugin.Info.SectorSize == 512 && imagePlugin.Info.Sectors == 320)
{
cpmFound = true;
firstDirectorySector86 = 8;
@@ -453,7 +453,7 @@ namespace DiscImageChef.Filesystems.CPM
break;
case FormatByte.k320:
if(imagePlugin.ImageInfo.SectorSize == 512 && imagePlugin.ImageInfo.Sectors == 640)
if(imagePlugin.Info.SectorSize == 512 && imagePlugin.Info.Sectors == 640)
{
cpmFound = true;
firstDirectorySector86 = 16;
@@ -506,7 +506,7 @@ namespace DiscImageChef.Filesystems.CPM
case FormatByte.k360:
case FormatByte.k360Alt:
case FormatByte.k360Alt2:
if(imagePlugin.ImageInfo.SectorSize == 512 && imagePlugin.ImageInfo.Sectors == 720)
if(imagePlugin.Info.SectorSize == 512 && imagePlugin.Info.Sectors == 720)
{
cpmFound = true;
firstDirectorySector86 = 36;
@@ -558,7 +558,7 @@ namespace DiscImageChef.Filesystems.CPM
break;
case FormatByte.k720:
case FormatByte.k720Alt:
if(imagePlugin.ImageInfo.SectorSize == 512 && imagePlugin.ImageInfo.Sectors == 1440)
if(imagePlugin.Info.SectorSize == 512 && imagePlugin.Info.Sectors == 1440)
{
cpmFound = true;
firstDirectorySector86 = 36;
@@ -609,7 +609,7 @@ namespace DiscImageChef.Filesystems.CPM
break;
case FormatByte.f720:
if(imagePlugin.ImageInfo.SectorSize == 512 && imagePlugin.ImageInfo.Sectors == 1440)
if(imagePlugin.Info.SectorSize == 512 && imagePlugin.Info.Sectors == 1440)
{
cpmFound = true;
firstDirectorySector86 = 18;
@@ -660,7 +660,7 @@ namespace DiscImageChef.Filesystems.CPM
break;
case FormatByte.f1200:
if(imagePlugin.ImageInfo.SectorSize == 512 && imagePlugin.ImageInfo.Sectors == 2400)
if(imagePlugin.Info.SectorSize == 512 && imagePlugin.Info.Sectors == 2400)
{
cpmFound = true;
firstDirectorySector86 = 30;
@@ -711,7 +711,7 @@ namespace DiscImageChef.Filesystems.CPM
break;
case FormatByte.f1440:
if(imagePlugin.ImageInfo.SectorSize == 512 && imagePlugin.ImageInfo.Sectors == 2880)
if(imagePlugin.Info.SectorSize == 512 && imagePlugin.Info.Sectors == 2880)
{
cpmFound = true;
firstDirectorySector86 = 36;
@@ -765,7 +765,7 @@ namespace DiscImageChef.Filesystems.CPM
if(cpmFound)
{
uint directoryLength = (uint)(((ulong)dpb.drm + 1) * 32 / imagePlugin.ImageInfo.SectorSize);
uint directoryLength = (uint)(((ulong)dpb.drm + 1) * 32 / imagePlugin.Info.SectorSize);
directory = imagePlugin.ReadSectors(firstDirectorySector86 + partition.Start, directoryLength);
DicConsole.DebugWriteLine("CP/M Plugin", "Found CP/M-86 floppy identifier.");
}
@@ -794,8 +794,8 @@ namespace DiscImageChef.Filesystems.CPM
foreach(CpmDefinition def in from def in definitions.definitions
let sectors =
(ulong)(def.cylinders * def.sides * def.sectorsPerTrack)
where sectors == imagePlugin.ImageInfo.Sectors &&
def.bytesPerSector == imagePlugin.ImageInfo.SectorSize
where sectors == imagePlugin.Info.Sectors &&
def.bytesPerSector == imagePlugin.Info.SectorSize
select def)
{
// Definition seems to describe current disk, at least, same number of volume sectors and bytes per sector
@@ -976,8 +976,9 @@ namespace DiscImageChef.Filesystems.CPM
}
}
public override void GetInformation(ImagePlugin imagePlugin, Partition partition, out string information)
public virtual void GetInformation(IMediaImage imagePlugin, Partition partition, out string information, Encoding encoding)
{
currentEncoding = encoding ?? Encoding.GetEncoding("IBM437");
information = "";
// As the identification is so complex, just call Identify() and relay on its findings
if(!Identify(imagePlugin, partition) || !cpmFound || workingDefinition == null || dpb == null) return;
@@ -1050,23 +1051,23 @@ namespace DiscImageChef.Filesystems.CPM
if(labelUpdateDate != null)
sb.AppendFormat("Volume updated on {0}", DateHandlers.CpmToDateTime(labelUpdateDate)).AppendLine();
XmlFsType = new FileSystemType();
XmlFsType.Bootable |= workingDefinition.sofs > 0 || workingDefinition.ofs > 0;
XmlFsType.ClusterSize = 128 << dpb.bsh;
if(dpb.dsm > 0) XmlFsType.Clusters = dpb.dsm;
else XmlFsType.Clusters = (long)(partition.End - partition.Start);
xmlFsType = new FileSystemType();
xmlFsType.Bootable |= workingDefinition.sofs > 0 || workingDefinition.ofs > 0;
xmlFsType.ClusterSize = 128 << dpb.bsh;
if(dpb.dsm > 0) xmlFsType.Clusters = dpb.dsm;
else xmlFsType.Clusters = (long)(partition.End - partition.Start);
if(labelCreationDate != null)
{
XmlFsType.CreationDate = DateHandlers.CpmToDateTime(labelCreationDate);
XmlFsType.CreationDateSpecified = true;
xmlFsType.CreationDate = DateHandlers.CpmToDateTime(labelCreationDate);
xmlFsType.CreationDateSpecified = true;
}
if(labelUpdateDate != null)
{
XmlFsType.ModificationDate = DateHandlers.CpmToDateTime(labelUpdateDate);
XmlFsType.ModificationDateSpecified = true;
xmlFsType.ModificationDate = DateHandlers.CpmToDateTime(labelUpdateDate);
xmlFsType.ModificationDateSpecified = true;
}
XmlFsType.Type = "CP/M";
XmlFsType.VolumeName = label;
xmlFsType.Type = "CP/M";
xmlFsType.VolumeName = label;
information = sb.ToString();
}

View File

@@ -38,20 +38,21 @@ using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using DiscImageChef.CommonTypes;
using DiscImageChef.Console;
using DiscImageChef.DiscImages;
using Schemas;
namespace DiscImageChef.Filesystems.CPM
{
partial class CPM
{
public override Errno Mount()
public virtual Errno Mount(IMediaImage imagePlugin, Partition partition1, Encoding encoding, bool debug)
{
return Mount(false);
}
device = imagePlugin;
this.partition = partition;
currentEncoding = encoding ?? Encoding.GetEncoding("IBM437");
public override Errno Mount(bool debug)
{
// As the identification is so complex, just call Identify() and relay on its findings
if(!Identify(device, partition) || !cpmFound || workingDefinition == null || dpb == null)
return Errno.InvalidArgument;
@@ -651,11 +652,11 @@ namespace DiscImageChef.Filesystems.CPM
cpmStat.FilenameLength = 11;
cpmStat.Files = (ulong)fileCache.Count;
cpmStat.FreeBlocks = cpmStat.Blocks - usedBlocks;
cpmStat.PluginId = PluginUuid;
cpmStat.PluginId = Id;
cpmStat.Type = "CP/M filesystem";
// Generate XML info
XmlFsType = new FileSystemType
xmlFsType = new FileSystemType
{
Clusters = cpmStat.Blocks,
ClusterSize = blockSize,
@@ -667,15 +668,15 @@ namespace DiscImageChef.Filesystems.CPM
};
if(labelCreationDate != null)
{
XmlFsType.CreationDate = DateHandlers.CpmToDateTime(labelCreationDate);
XmlFsType.CreationDateSpecified = true;
xmlFsType.CreationDate = DateHandlers.CpmToDateTime(labelCreationDate);
xmlFsType.CreationDateSpecified = true;
}
if(labelUpdateDate != null)
{
XmlFsType.ModificationDate = DateHandlers.CpmToDateTime(labelUpdateDate);
XmlFsType.ModificationDateSpecified = true;
xmlFsType.ModificationDate = DateHandlers.CpmToDateTime(labelUpdateDate);
xmlFsType.ModificationDateSpecified = true;
}
if(!string.IsNullOrEmpty(label)) XmlFsType.VolumeName = label;
if(!string.IsNullOrEmpty(label)) xmlFsType.VolumeName = label;
mounted = true;
return Errno.NoError;
@@ -685,7 +686,7 @@ namespace DiscImageChef.Filesystems.CPM
/// Gets information about the mounted volume.
/// </summary>
/// <param name="stat">Information about the mounted volume.</param>
public override Errno StatFs(ref FileSystemInfo stat)
public virtual Errno StatFs(ref FileSystemInfo stat)
{
if(!mounted) return Errno.AccessDenied;
@@ -694,7 +695,7 @@ namespace DiscImageChef.Filesystems.CPM
return Errno.NoError;
}
public override Errno Unmount()
public virtual Errno Unmount()
{
mounted = false;
definitions = null;

View File

@@ -44,7 +44,7 @@ namespace DiscImageChef.Filesystems.CPM
/// <param name="path">File path.</param>
/// <param name="xattr">Extendad attribute, alternate data stream or fork name.</param>
/// <param name="buf">Buffer.</param>
public override Errno GetXattr(string path, string xattr, ref byte[] buf)
public virtual Errno GetXattr(string path, string xattr, ref byte[] buf)
{
if(!mounted) return Errno.AccessDenied;
@@ -70,7 +70,7 @@ namespace DiscImageChef.Filesystems.CPM
/// <returns>Error number.</returns>
/// <param name="path">Path.</param>
/// <param name="xattrs">List of extended attributes, alternate data streams and forks.</param>
public override Errno ListXAttr(string path, ref List<string> xattrs)
public virtual Errno ListXAttr(string path, ref List<string> xattrs)
{
if(!mounted) return Errno.AccessDenied;