Add option to pass an arbitrary list of options to IReadOnlyFilesystem.Mount()

This commit is contained in:
2017-12-27 23:55:59 +00:00
parent e009d86fcc
commit a1f82e0e72
11 changed files with 454 additions and 417 deletions

View File

@@ -57,6 +57,11 @@ namespace DiscImageChef.Filesystems.AppleDOS
public string Name => "Apple DOS File System";
public Guid Id => new Guid("8658A1E9-B2E7-4BCC-9638-157A31B0A700\n");
static Dictionary<string, string> GetDefaultOptions()
{
return new Dictionary<string, string> {{"debug", false.ToString()}};
}
#region Caches
/// <summary>Caches track/sector lists</summary>
Dictionary<string, byte[]> extentCache;

View File

@@ -31,6 +31,7 @@
// ****************************************************************************/
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using Claunia.Encoding;
using DiscImageChef.CommonTypes;
@@ -46,7 +47,8 @@ namespace DiscImageChef.Filesystems.AppleDOS
/// <summary>
/// Mounts an Apple DOS filesystem
/// </summary>
public Errno Mount(IMediaImage imagePlugin, Partition partition, Encoding encoding, bool debug)
public Errno Mount(IMediaImage imagePlugin, Partition partition, Encoding encoding,
Dictionary<string, string> options)
{
device = imagePlugin;
start = partition.Start;
@@ -111,7 +113,8 @@ namespace DiscImageChef.Filesystems.AppleDOS
};
XmlFsType.FreeClusters = XmlFsType.Clusters - usedSectors;
this.debug = debug;
if(options == null) options = GetDefaultOptions();
if(options.TryGetValue("debug", out string debugString)) bool.TryParse(debugString, out debug);
mounted = true;
return Errno.NoError;
}

View File

@@ -33,7 +33,6 @@
using System;
using System.Collections.Generic;
using System.Text;
using DiscImageChef.CommonTypes;
using DiscImageChef.DiscImages;
using Schemas;
@@ -68,21 +67,9 @@ namespace DiscImageChef.Filesystems.AppleMFS
public Guid Id => new Guid("36405F8D-0D26-4066-6538-5DBF5D065C3A");
public Encoding Encoding { get; private set; }
public AppleMFS()
static Dictionary<string, string> GetDefaultOptions()
{
Encoding = Encoding.GetEncoding("macintosh");
}
public AppleMFS(Encoding encoding)
{
Encoding = encoding ?? Encoding.GetEncoding("macintosh");
}
public AppleMFS(IMediaImage imagePlugin, Partition partition, Encoding encoding)
{
device = imagePlugin;
partitionStart = partition.Start;
Encoding = encoding ?? Encoding.GetEncoding("macintosh");
return new Dictionary<string, string> {{"debug", false.ToString()}};
}
}
}

View File

@@ -31,6 +31,7 @@
// ****************************************************************************/
using System;
using System.Collections.Generic;
using System.Text;
using DiscImageChef.CommonTypes;
using DiscImageChef.DiscImages;
@@ -41,12 +42,14 @@ namespace DiscImageChef.Filesystems.AppleMFS
// Information from Inside Macintosh Volume II
public partial class AppleMFS
{
public Errno Mount(IMediaImage imagePlugin, Partition partition, Encoding encoding, bool debug)
public Errno Mount(IMediaImage imagePlugin, Partition partition, Encoding encoding,
Dictionary<string, string> options)
{
device = imagePlugin;
partitionStart = partition.Start;
Encoding = encoding ?? Encoding.GetEncoding("macintosh");
this.debug = debug;
if(options == null) options = GetDefaultOptions();
if(options.TryGetValue("debug", out string debugString)) bool.TryParse(debugString, out debug);
volMDB = new MFS_MasterDirectoryBlock();
mdbBlocks = device.ReadSector(2 + partitionStart);
@@ -92,7 +95,8 @@ namespace DiscImageChef.Filesystems.AppleMFS
uint tmp2 = 0;
uint tmp3 = 0;
if(offset + 4 <= blockMapBytes.Length) tmp1 = BigEndianBitConverter.ToUInt32(blockMapBytes, offset);
if(offset + 4 <= blockMapBytes.Length)
tmp1 = BigEndianBitConverter.ToUInt32(blockMapBytes, offset);
if(offset + 4 + 4 <= blockMapBytes.Length)
tmp2 = BigEndianBitConverter.ToUInt32(blockMapBytes, offset + 4);
if(offset + 8 + 4 <= blockMapBytes.Length)
@@ -136,6 +140,7 @@ namespace DiscImageChef.Filesystems.AppleMFS
XmlFsType.BackupDate = DateHandlers.MacToDateTime(volMDB.drLsBkUp);
XmlFsType.BackupDateSpecified = true;
}
XmlFsType.Bootable = bbSig == MFSBB_MAGIC;
XmlFsType.Clusters = volMDB.drNmAlBlks;
XmlFsType.ClusterSize = (int)volMDB.drAlBlkSiz;
@@ -144,6 +149,7 @@ namespace DiscImageChef.Filesystems.AppleMFS
XmlFsType.CreationDate = DateHandlers.MacToDateTime(volMDB.drCrDate);
XmlFsType.CreationDateSpecified = true;
}
XmlFsType.Files = volMDB.drNmFls;
XmlFsType.FilesSpecified = true;
XmlFsType.FreeClusters = volMDB.drFreeBks;

View File

@@ -116,5 +116,10 @@ namespace DiscImageChef.Filesystems.CPM
public Encoding Encoding { get; private set; }
public string Name => "CP/M File System";
public Guid Id => new Guid("AA2B8585-41DF-4E3B-8A35-D1A935E2F8A1");
static Dictionary<string, string> GetDefaultOptions()
{
return new Dictionary<string, string> {{"debug", false.ToString()}};
}
}
}

View File

@@ -47,10 +47,11 @@ namespace DiscImageChef.Filesystems.CPM
{
partial class CPM
{
public Errno Mount(IMediaImage imagePlugin, Partition partition1, Encoding encoding, bool debug)
public Errno Mount(IMediaImage imagePlugin, Partition partition, Encoding encoding,
Dictionary<string, string> options)
{
device = imagePlugin;
partition = partition;
this.partition = partition;
Encoding = encoding ?? Encoding.GetEncoding("IBM437");
// As the identification is so complex, just call Identify() and relay on its findings
@@ -96,9 +97,8 @@ namespace DiscImageChef.Filesystems.CPM
return Errno.NotImplemented;
}
// TODO: Implement COLUMBIA ordering
else if(
string.Compare(workingDefinition.order, "COLUMBIA", StringComparison.InvariantCultureIgnoreCase) ==
0)
else if(string.Compare(workingDefinition.order, "COLUMBIA",
StringComparison.InvariantCultureIgnoreCase) == 0)
{
DicConsole.DebugWriteLine("CP/M Plugin",
"Don't know how to handle COLUMBIA ordering, not proceeding with this definition.");
@@ -134,7 +134,8 @@ namespace DiscImageChef.Filesystems.CPM
device.ReadSector((ulong)((int)partition.Start + p / sectorMask.Length * sectorMask.Length +
sectorMask[p % sectorMask.Length]));
if(workingDefinition.complement)
for(int b = 0; b < readSector.Length; b++) readSector[b] = (byte)(~readSector[b] & 0xFF);
for(int b = 0; b < readSector.Length; b++)
readSector[b] = (byte)(~readSector[b] & 0xFF);
deinterleavedSectors.Add((ulong)p, readSector);
}
@@ -174,7 +175,8 @@ namespace DiscImageChef.Filesystems.CPM
blockMs = new MemoryStream();
}
// CP/M blocks are same size than physical sectors
else allocationBlocks.Add(blockNo++, sector);
else
allocationBlocks.Add(blockNo++, sector);
}
DicConsole.DebugWriteLine("CP/M Plugin", "Reading directory.");
@@ -238,6 +240,7 @@ namespace DiscImageChef.Filesystems.CPM
entry.filename[i] &= 0x7F;
validEntry &= entry.filename[i] >= 0x20;
}
for(int i = 0; i < 3; i++)
{
entry.extension[i] &= 0x7F;
@@ -273,11 +276,11 @@ namespace DiscImageChef.Filesystems.CPM
if(rdOnly) fInfo.Attributes |= FileAttributes.ReadOnly;
if(system) fInfo.Attributes |= FileAttributes.System;
// Supposedly there is a value in the directory entry telling how many blocks are designated in this entry
// However some implementations tend to do whatever they wish, but none will ever allocate block 0 for a file
// because that's where the directory resides.
// There is also a field telling how many bytes are used in the last block, but its meaning is non-standard so
// we must ignore it.
// Supposedly there is a value in the directory entry telling how many blocks are designated in
// this entry. However some implementations tend to do whatever they wish, but none will ever
// allocate block 0 for a file because that's where the directory resides.
// There is also a field telling how many bytes are used in the last block, but its meaning is
// non-standard so we must ignore it.
foreach(ushort blk in entry.allocations.Where(blk => !blocks.Contains(blk) && blk != 0))
blocks.Add(blk);
@@ -326,6 +329,7 @@ namespace DiscImageChef.Filesystems.CPM
entry.filename[i] &= 0x7F;
validEntry &= entry.filename[i] >= 0x20;
}
for(int i = 0; i < 3; i++)
{
entry.extension[i] &= 0x7F;
@@ -361,11 +365,11 @@ namespace DiscImageChef.Filesystems.CPM
if(rdOnly) fInfo.Attributes |= FileAttributes.ReadOnly;
if(system) fInfo.Attributes |= FileAttributes.System;
// Supposedly there is a value in the directory entry telling how many blocks are designated in this entry
// However some implementations tend to do whatever they wish, but none will ever allocate block 0 for a file
// because that's where the directory resides.
// There is also a field telling how many bytes are used in the last block, but its meaning is non-standard so
// we must ignore it.
// Supposedly there is a value in the directory entry telling how many blocks are designated in
// this entry. However some implementations tend to do whatever they wish, but none will ever
// allocate block 0 for a file because that's where the directory resides.
// There is also a field telling how many bytes are used in the last block, but its meaning is
// non-standard so we must ignore it.
foreach(ushort blk in entry.allocations.Cast<ushort>()
.Where(blk => !blocks.Contains(blk) && blk != 0)) blocks.Add(blk);
@@ -449,7 +453,8 @@ namespace DiscImageChef.Filesystems.CPM
labelEntry = (LabelEntry)Marshal.PtrToStructure(dirPtr, typeof(LabelEntry));
Marshal.FreeHGlobal(dirPtr);
// The volume label defines if one of the fields in CP/M 3 timestamp is a creation or an access time
// The volume label defines if one of the fields in CP/M 3 timestamp is a creation or an
// access time
atime |= (labelEntry.flags & 0x40) == 0x40;
label = Encoding.ASCII.GetString(directory, dOff + 1, 11).Trim();
@@ -595,6 +600,7 @@ namespace DiscImageChef.Filesystems.CPM
file3 = null;
dirCnt = 0;
}
break;
}
@@ -671,11 +677,13 @@ namespace DiscImageChef.Filesystems.CPM
XmlFsType.CreationDate = DateHandlers.CpmToDateTime(labelCreationDate);
XmlFsType.CreationDateSpecified = true;
}
if(labelUpdateDate != null)
{
XmlFsType.ModificationDate = DateHandlers.CpmToDateTime(labelUpdateDate);
XmlFsType.ModificationDateSpecified = true;
}
if(!string.IsNullOrEmpty(label)) XmlFsType.VolumeName = label;
mounted = true;

View File

@@ -31,12 +31,10 @@
// Copyright © 2011-2018 Natalia Portillo
// ****************************************************************************/
using System;
using System.Collections.Generic;
using System.Text;
using DiscImageChef.CommonTypes;
using DiscImageChef.DiscImages;
using Schemas;
namespace DiscImageChef.Filesystems
{
@@ -52,13 +50,13 @@ namespace DiscImageChef.Filesystems
/// <param name="imagePlugin"></param>
/// <param name="partition"></param>
/// <param name="encoding">Which encoding to use for this filesystem.</param>
/// <param name="debug">If <c>true</c> enable debug.</param>
Errno Mount(IMediaImage imagePlugin, Partition partition, Encoding encoding, bool debug);
/// <param name="options">Dictionary of key=value pairs containing options to pass to the filesystem</param>
Errno Mount(IMediaImage imagePlugin, Partition partition, Encoding encoding,
Dictionary<string, string> options);
/// <summary>
/// Frees all internal structures created by
/// <see
/// cref="M:DiscImageChef.Filesystems.Filesystem.Mount(DiscImageChef.DiscImages.IMediaImage,DiscImageChef.CommonTypes.Partition,System.Text.Encoding,System.Boolean)" />
/// <see cref="Mount" />
/// </summary>
Errno Unmount();

View File

@@ -56,6 +56,11 @@ namespace DiscImageChef.Filesystems.LisaFS
public Encoding Encoding { get; private set; }
public FileSystemType XmlFsType { get; private set; }
static Dictionary<string, string> GetDefaultOptions()
{
return new Dictionary<string, string> {{"debug", false.ToString()}};
}
#region Caches
/// <summary>Caches Extents Files</summary>
Dictionary<short, ExtentFile> extentCache;

View File

@@ -47,7 +47,8 @@ namespace DiscImageChef.Filesystems.LisaFS
/// <summary>
/// Mounts an Apple Lisa filesystem
/// </summary>
public Errno Mount(IMediaImage imagePlugin, Partition partition, Encoding encoding, bool debug)
public Errno Mount(IMediaImage imagePlugin, Partition partition, Encoding encoding,
Dictionary<string, string> options)
{
try
{
@@ -104,7 +105,8 @@ namespace DiscImageChef.Filesystems.LisaFS
mddf.unknown1 = sector[0x2D];
Array.Copy(sector, 0x2E, pString, 0, 33);
// Prevent garbage
mddf.password = pString[0] <= 32 ? StringHandlers.PascalToString(pString, Encoding) : "";
mddf.password =
pString[0] <= 32 ? StringHandlers.PascalToString(pString, Encoding) : "";
mddf.unknown2 = sector[0x4F];
mddf.machine_id = BigEndianBitConverter.ToUInt32(sector, 0x50);
mddf.master_copy_id = BigEndianBitConverter.ToUInt32(sector, 0x54);
@@ -176,10 +178,14 @@ namespace DiscImageChef.Filesystems.LisaFS
mddf.vol_left_mounted = sector[0x138];
// Check that the MDDF is correct
if(mddf.mddf_block != i - volumePrefix || mddf.vol_size > device.Info.Sectors ||
mddf.vol_size - 1 != mddf.volsize_minus_one ||
mddf.vol_size - i - 1 != mddf.volsize_minus_mddf_minus_one - volumePrefix ||
mddf.datasize > mddf.blocksize || mddf.blocksize < device.Info.SectorSize ||
if(mddf.mddf_block != i - volumePrefix ||
mddf.vol_size > device.Info.Sectors ||
mddf.vol_size - 1 !=
mddf.volsize_minus_one ||
mddf.vol_size - i - 1 !=
mddf.volsize_minus_mddf_minus_one - volumePrefix ||
mddf.datasize >
mddf.blocksize || mddf.blocksize < device.Info.SectorSize ||
mddf.datasize != device.Info.SectorSize)
{
DicConsole.DebugWriteLine("LisaFS plugin", "Incorrect MDDF found");
@@ -211,7 +217,8 @@ namespace DiscImageChef.Filesystems.LisaFS
fileSizeCache = new Dictionary<short, int>();
mounted = true;
this.debug = debug;
if(options == null) options = GetDefaultOptions();
if(options.TryGetValue("debug", out string debugString)) bool.TryParse(debugString, out debug);
if(debug) printedExtents = new List<short>();
@@ -287,6 +294,7 @@ namespace DiscImageChef.Filesystems.LisaFS
XmlFsType.BackupDate = mddf.dtvb;
XmlFsType.BackupDateSpecified = true;
}
XmlFsType.Clusters = mddf.vol_size;
XmlFsType.ClusterSize = mddf.clustersize * mddf.datasize;
if(DateTime.Compare(mddf.dtvc, DateHandlers.LisaToDateTime(0)) > 0)
@@ -294,6 +302,7 @@ namespace DiscImageChef.Filesystems.LisaFS
XmlFsType.CreationDate = mddf.dtvc;
XmlFsType.CreationDateSpecified = true;
}
XmlFsType.Dirty = mddf.vol_left_mounted != 0;
XmlFsType.Files = mddf.filecount;
XmlFsType.FilesSpecified = true;

View File

@@ -43,11 +43,13 @@ namespace DiscImageChef.Filesystems.UCSDPascal
// Information from Call-A.P.P.L.E. Pascal Disk Directory Structure
public partial class PascalPlugin
{
public Errno Mount(IMediaImage imagePlugin, Partition partition, Encoding encoding, bool debug)
public Errno Mount(IMediaImage imagePlugin, Partition partition, Encoding encoding,
Dictionary<string, string> options)
{
device = imagePlugin;
Encoding = encoding ?? new Apple2();
this.debug = debug;
if(options == null) options = GetDefaultOptions();
if(options.TryGetValue("debug", out string debugString)) bool.TryParse(debugString, out debug);
if(device.Info.Sectors < 3) return Errno.InvalidArgument;
// Blocks 0 and 1 are boot code
@@ -66,11 +68,14 @@ namespace DiscImageChef.Filesystems.UCSDPascal
mountedVolEntry.lastBoot = BigEndianBitConverter.ToInt16(catalogBlocks, 0x14);
mountedVolEntry.tail = BigEndianBitConverter.ToInt32(catalogBlocks, 0x16);
if(mountedVolEntry.firstBlock != 0 || mountedVolEntry.lastBlock <= mountedVolEntry.firstBlock ||
if(mountedVolEntry.firstBlock != 0 ||
mountedVolEntry.lastBlock <= mountedVolEntry.firstBlock ||
(ulong)mountedVolEntry.lastBlock > device.Info.Sectors - 2 ||
mountedVolEntry.entryType != PascalFileKind.Volume &&
mountedVolEntry.entryType != PascalFileKind.Secure || mountedVolEntry.volumeName[0] > 7 ||
mountedVolEntry.blocks < 0 || (ulong)mountedVolEntry.blocks != device.Info.Sectors ||
mountedVolEntry.entryType != PascalFileKind.Secure ||
mountedVolEntry.volumeName[0] > 7 ||
mountedVolEntry.blocks < 0 ||
(ulong)mountedVolEntry.blocks != device.Info.Sectors ||
mountedVolEntry.files < 0) return Errno.InvalidArgument;
catalogBlocks = device.ReadSectors(2, (uint)(mountedVolEntry.lastBlock - mountedVolEntry.firstBlock - 2));
@@ -133,6 +138,7 @@ namespace DiscImageChef.Filesystems.UCSDPascal
};
stat.FreeBlocks = mountedVolEntry.blocks - (mountedVolEntry.lastBlock - mountedVolEntry.firstBlock);
foreach(PascalFileEntry entry in fileEntries) stat.FreeBlocks -= entry.lastBlock - entry.firstBlock;
return Errno.NotImplemented;

View File

@@ -72,5 +72,10 @@ namespace DiscImageChef.Filesystems.UCSDPascal
dest = null;
return Errno.NotSupported;
}
static Dictionary<string, string> GetDefaultOptions()
{
return new Dictionary<string, string> {{"debug", false.ToString()}};
}
}
}