Allow to use an existing metadata sidecar when dumping media.

This commit is contained in:
2018-01-28 21:18:52 +00:00
parent df5f062500
commit 484782f8e1
11 changed files with 120 additions and 38 deletions

View File

@@ -78,9 +78,10 @@ namespace DiscImageChef.Core.Devices.Dumping
bool force, bool dumpRaw, bool persistent, bool stopOnError,
ref Resume resume,
ref
DumpLog dumpLog, Encoding encoding, string outputPrefix, string outputPath,
DumpLog dumpLog, Encoding encoding, string outputPrefix,
string outputPath,
Dictionary<string, string>
formatOptions)
formatOptions, CICMMetadataType preSidecar)
{
bool aborted;
@@ -418,6 +419,7 @@ namespace DiscImageChef.Core.Devices.Dumping
}
outputPlugin.SetDumpHardware(resume.Tries);
if(preSidecar != null) outputPlugin.SetCicmMetadata(preSidecar);
dumpLog.WriteLine("Closing output file.");
DicConsole.WriteLine("Closing output file.");
outputPlugin.Close();
@@ -436,6 +438,11 @@ namespace DiscImageChef.Core.Devices.Dumping
DateTime chkStart = DateTime.UtcNow;
CICMMetadataType sidecar = Sidecar.Create(inputPlugin, outputPath, filter.Id, encoding);
if(preSidecar != null)
{
preSidecar.BlockMedia = sidecar.BlockMedia;
sidecar = preSidecar;
}
if(dev.IsUsb)
{

View File

@@ -89,7 +89,9 @@ namespace DiscImageChef.Core.Devices.Dumping
Resume resume, ref DumpLog dumpLog, bool dumpLeadIn,
Encoding encoding,
string
outputPrefix, string outputPath, Dictionary<string, string> formatOptions)
outputPrefix, string outputPath, Dictionary<string, string> formatOptions,
CICMMetadataType
preSidecar)
{
uint subSize;
DateTime start;
@@ -887,6 +889,7 @@ namespace DiscImageChef.Core.Devices.Dumping
}
outputPlugin.SetDumpHardware(resume.Tries);
if(preSidecar != null) outputPlugin.SetCicmMetadata(preSidecar);
dumpLog.WriteLine("Closing output file.");
DicConsole.WriteLine("Closing output file.");
outputPlugin.Close();
@@ -915,6 +918,12 @@ namespace DiscImageChef.Core.Devices.Dumping
dumpLog.WriteLine("Average checksum speed {0:F3} KiB/sec.",
(double)blockSize * (double)(blocks + 1) / 1024 / (totalChkDuration / 1000));
if(preSidecar == null)
{
preSidecar.OpticalDisc = sidecar.OpticalDisc;
sidecar = preSidecar;
}
sidecar.OpticalDisc[0].Dimensions = Dimensions.DimensionsFromMediaType(dskType);
Metadata.MediaType.MediaTypeToString(dskType, out string xmlDskTyp, out string xmlDskSubTyp);
sidecar.OpticalDisc[0].DiscType = xmlDskTyp;

View File

@@ -82,7 +82,9 @@ namespace DiscImageChef.Core.Devices.Dumping
Resume resume, ref DumpLog dumpLog, bool dumpLeadIn,
Encoding encoding,
string
outputPrefix, string outputPath, Dictionary<string, string> formatOptions)
outputPrefix, string outputPath, Dictionary<string, string> formatOptions,
CICMMetadataType
preSidecar)
{
bool sense;
ulong blocks;
@@ -198,7 +200,7 @@ namespace DiscImageChef.Core.Devices.Dumping
{
CompactDisc.Dump(dev, devicePath, outputPlugin, retryPasses, force, dumpRaw, persistent, stopOnError,
ref dskType, ref resume, ref dumpLog, dumpLeadIn, encoding, outputPrefix, outputPath,
formatOptions);
formatOptions, preSidecar);
return;
}
@@ -599,12 +601,14 @@ namespace DiscImageChef.Core.Devices.Dumping
if(isXbox)
{
Xgd.Dump(dev, devicePath, outputPlugin, retryPasses, force, dumpRaw, persistent, stopOnError, mediaTags,
ref dskType, ref resume, ref dumpLog, encoding, outputPrefix, outputPath, formatOptions);
ref dskType, ref resume, ref dumpLog, encoding, outputPrefix, outputPath, formatOptions,
preSidecar);
return;
}
Sbc.Dump(dev, devicePath, outputPlugin, retryPasses, force, dumpRaw, persistent, stopOnError, mediaTags,
ref dskType, true, ref resume, ref dumpLog, encoding, outputPrefix, outputPath, formatOptions);
ref dskType, true, ref resume, ref dumpLog, encoding, outputPrefix, outputPath, formatOptions,
preSidecar);
}
internal static void AddMediaTagToSidecar(string outputPath,

View File

@@ -37,6 +37,7 @@ using DiscImageChef.Core.Logging;
using DiscImageChef.Devices;
using DiscImageChef.DiscImages;
using DiscImageChef.Metadata;
using Schemas;
namespace DiscImageChef.Core.Devices.Dumping
{
@@ -46,9 +47,10 @@ namespace DiscImageChef.Core.Devices.Dumping
bool force, bool dumpRaw, bool persistent, bool stopOnError,
ref Resume resume,
ref
DumpLog dumpLog, Encoding encoding, string outputPrefix, string outputPath,
DumpLog dumpLog, Encoding encoding, string outputPrefix,
string outputPath,
Dictionary<string, string>
formatOptions)
formatOptions, CICMMetadataType preSidecar)
{
throw new NotImplementedException("NVMe devices not yet supported.");
}

View File

@@ -85,7 +85,8 @@ namespace DiscImageChef.Core.Devices.Dumping
ref Resume resume,
ref DumpLog dumpLog, Encoding encoding, string outputPrefix,
string outputPath,
Dictionary<string, string> formatOptions)
Dictionary<string, string> formatOptions,
CICMMetadataType preSidecar)
{
bool sense;
ulong blocks;
@@ -646,6 +647,7 @@ namespace DiscImageChef.Core.Devices.Dumping
}
outputPlugin.SetDumpHardware(resume.Tries);
if(preSidecar != null) outputPlugin.SetCicmMetadata(preSidecar);
dumpLog.WriteLine("Closing output file.");
DicConsole.WriteLine("Closing output file.");
outputPlugin.Close();
@@ -676,6 +678,12 @@ namespace DiscImageChef.Core.Devices.Dumping
if(opticalDisc)
{
if(preSidecar != null)
{
preSidecar.OpticalDisc = sidecar.OpticalDisc;
sidecar = preSidecar;
}
// TODO: Implement layers
sidecar.OpticalDisc[0].Dimensions = Dimensions.DimensionsFromMediaType(dskType);
Metadata.MediaType.MediaTypeToString(dskType, out string xmlDskTyp, out string xmlDskSubTyp);
@@ -689,6 +697,12 @@ namespace DiscImageChef.Core.Devices.Dumping
}
else
{
if(preSidecar != null)
{
preSidecar.BlockMedia = sidecar.BlockMedia;
sidecar = preSidecar;
}
// All USB flash drives report as removable, even if the media is not removable
if(!dev.IsRemovable || dev.IsUsb)
{

View File

@@ -40,6 +40,7 @@ using DiscImageChef.Decoders.SCSI;
using DiscImageChef.Devices;
using DiscImageChef.DiscImages;
using DiscImageChef.Metadata;
using Schemas;
using MediaType = DiscImageChef.CommonTypes.MediaType;
namespace DiscImageChef.Core.Devices.Dumping
@@ -76,7 +77,9 @@ namespace DiscImageChef.Core.Devices.Dumping
DumpLog dumpLog, bool dumpLeadIn, Encoding encoding,
string outputPrefix,
string
outputPath, Dictionary<string, string> formatOptions)
outputPath, Dictionary<string, string> formatOptions,
CICMMetadataType
preSidecar)
{
MediaType dskType = MediaType.Unknown;
int resets = 0;
@@ -204,17 +207,17 @@ namespace DiscImageChef.Core.Devices.Dumping
case PeripheralDeviceTypes.SequentialAccess:
if(dumpRaw) throw new ArgumentException("Tapes cannot be dumped raw.");
Ssc.Dump(dev, outputPrefix, devicePath, ref resume, ref dumpLog);
Ssc.Dump(dev, outputPrefix, devicePath, ref resume, ref dumpLog, preSidecar);
return;
case PeripheralDeviceTypes.MultiMediaDevice:
Mmc.Dump(dev, devicePath, outputPlugin, retryPasses, force, dumpRaw, persistent, stopOnError,
ref dskType, ref resume, ref dumpLog, dumpLeadIn, encoding, outputPrefix, outputPath,
formatOptions);
formatOptions, preSidecar);
return;
default:
Sbc.Dump(dev, devicePath, outputPlugin, retryPasses, force, dumpRaw, persistent, stopOnError, null,
ref dskType, false, ref resume, ref dumpLog, encoding, outputPrefix, outputPath,
formatOptions);
formatOptions, preSidecar);
break;
}
}

View File

@@ -59,7 +59,8 @@ namespace DiscImageChef.Core.Devices.Dumping
/// <param name="resume">Information for dump resuming</param>
/// <param name="dumpLog">Dump logger</param>
internal static void Dump(Device dev, string outputPrefix, string devicePath, ref Resume resume,
ref DumpLog dumpLog)
ref DumpLog dumpLog,
CICMMetadataType preSidecar)
{
FixedSense? fxSense;
bool aborted;
@@ -74,7 +75,7 @@ namespace DiscImageChef.Core.Devices.Dumping
double currentSpeed = 0;
double maxSpeed = double.MinValue;
double minSpeed = double.MaxValue;
CICMMetadataType sidecar = new CICMMetadataType();
CICMMetadataType sidecar = preSidecar ?? new CICMMetadataType();
dev.RequestSense(out byte[] senseBuf, dev.Timeout, out double duration);
fxSense = Sense.DecodeFixed(senseBuf, out string strSense);

View File

@@ -76,9 +76,10 @@ namespace DiscImageChef.Core.Devices.Dumping
bool force, bool dumpRaw, bool persistent, bool stopOnError,
ref Resume resume,
ref
DumpLog dumpLog, Encoding encoding, string outputPrefix, string outputPath,
DumpLog dumpLog, Encoding encoding, string outputPrefix,
string outputPath,
Dictionary<string, string>
formatOptions)
formatOptions, CICMMetadataType preSidecar)
{
bool aborted;
@@ -391,6 +392,7 @@ namespace DiscImageChef.Core.Devices.Dumping
currentTry.Extents = ExtentsConverter.ToMetadata(extents);
outputPlugin.SetDumpHardware(resume.Tries);
if(preSidecar != null) outputPlugin.SetCicmMetadata(preSidecar);
dumpLog.WriteLine("Closing output file.");
DicConsole.WriteLine("Closing output file.");
outputPlugin.Close();
@@ -410,6 +412,12 @@ namespace DiscImageChef.Core.Devices.Dumping
DateTime chkStart = DateTime.UtcNow;
CICMMetadataType sidecar = Sidecar.Create(inputPlugin, outputPath, filter.Id, encoding);
if(preSidecar != null)
{
preSidecar.BlockMedia = sidecar.BlockMedia;
sidecar = preSidecar;
}
switch(dev.Type)
{
case DeviceType.MMC:

View File

@@ -87,7 +87,8 @@ namespace DiscImageChef.Core.Devices.Dumping
ref Resume resume,
ref DumpLog dumpLog,
Encoding encoding, string outputPrefix, string outputPath,
Dictionary<string, string> formatOptions)
Dictionary<string, string> formatOptions,
CICMMetadataType preSidecar)
{
bool sense;
ulong blocks;
@@ -771,6 +772,7 @@ namespace DiscImageChef.Core.Devices.Dumping
}
outputPlugin.SetDumpHardware(resume.Tries);
if(preSidecar != null) outputPlugin.SetCicmMetadata(preSidecar);
dumpLog.WriteLine("Closing output file.");
DicConsole.WriteLine("Closing output file.");
outputPlugin.Close();
@@ -794,6 +796,12 @@ namespace DiscImageChef.Core.Devices.Dumping
CICMMetadataType sidecar = Sidecar.Create(inputPlugin, outputPath, filter.Id, encoding);
end = DateTime.UtcNow;
if(preSidecar != null)
{
preSidecar.OpticalDisc = sidecar.OpticalDisc;
sidecar = preSidecar;
}
totalChkDuration = (end - chkStart).TotalMilliseconds;
dumpLog.WriteLine("Sidecar created in {0} seconds.", (end - chkStart).TotalSeconds);
dumpLog.WriteLine("Average checksum speed {0:F3} KiB/sec.",

View File

@@ -43,6 +43,7 @@ using DiscImageChef.Core.Logging;
using DiscImageChef.Devices;
using DiscImageChef.DiscImages;
using DiscImageChef.Metadata;
using Schemas;
namespace DiscImageChef.Commands
{
@@ -74,6 +75,7 @@ namespace DiscImageChef.Commands
DicConsole.DebugWriteLine("Dump-Media command", "--format={0}", options.OutputFormat);
DicConsole.DebugWriteLine("Dump-Media command", "--force={0}", options.Force);
DicConsole.DebugWriteLine("Dump-Media command", "--options={0}", options.Options);
DicConsole.DebugWriteLine("Dump-Media command", "--cicm-xml={0}", options.CicmXml);
Dictionary<string, string> parsedOptions = Options.Parse(options.Options);
DicConsole.DebugWriteLine("Dump-Media command", "Parsed options:");
@@ -132,6 +134,27 @@ namespace DiscImageChef.Commands
return;
}
CICMMetadataType sidecar = null;
XmlSerializer sidecarXs = new XmlSerializer(typeof(CICMMetadataType));
if(options.CicmXml != null)
if(File.Exists(options.CicmXml))
try
{
StreamReader sr = new StreamReader(options.CicmXml);
sidecar = (CICMMetadataType)sidecarXs.Deserialize(sr);
sr.Close();
}
catch
{
DicConsole.ErrorWriteLine("Incorrect metadata sidecar file, not continuing...");
return;
}
else
{
DicConsole.ErrorWriteLine("Could not find metadata sidecar, not continuing...");
return;
}
PluginBase plugins = new PluginBase();
List<IWritableImage> candidates = new List<IWritableImage>();
@@ -182,24 +205,24 @@ namespace DiscImageChef.Commands
case DeviceType.ATA:
Ata.Dump(dev, options.DevicePath, outputFormat, options.RetryPasses, options.Force, options.Raw,
options.Persistent, options.StopOnError, ref resume, ref dumpLog, encoding, outputPrefix,
options.OutputFile, parsedOptions);
options.OutputFile, parsedOptions, sidecar);
break;
case DeviceType.MMC:
case DeviceType.SecureDigital:
SecureDigital.Dump(dev, options.DevicePath, outputFormat, options.RetryPasses, options.Force,
options.Raw, options.Persistent, options.StopOnError, ref resume, ref dumpLog,
encoding, outputPrefix, options.OutputFile, parsedOptions);
encoding, outputPrefix, options.OutputFile, parsedOptions, sidecar);
break;
case DeviceType.NVMe:
NvMe.Dump(dev, options.DevicePath, outputFormat, options.RetryPasses, options.Force, options.Raw,
options.Persistent, options.StopOnError, ref resume, ref dumpLog, encoding, outputPrefix,
options.OutputFile, parsedOptions);
options.OutputFile, parsedOptions, sidecar);
break;
case DeviceType.ATAPI:
case DeviceType.SCSI:
Scsi.Dump(dev, options.DevicePath, outputFormat, options.RetryPasses, options.Force, options.Raw,
options.Persistent, options.StopOnError, ref resume, ref dumpLog, options.LeadIn,
encoding, outputPrefix, options.OutputFile, parsedOptions);
encoding, outputPrefix, options.OutputFile, parsedOptions, sidecar);
break;
default:
dumpLog.WriteLine("Unknown device type.");

View File

@@ -305,6 +305,9 @@ namespace DiscImageChef
[Option('O', "options", Default = null,
HelpText = "Comma separated name=value pairs of options to pass to output image plugin")]
public string Options { get; set; }
[Option('x', "cicm-xml", Default = null, HelpText = "Take metadata from existing CICM XML sidecar.")]
public string CicmXml { get; set; }
}
[Verb("device-report", HelpText = "Tests the device capabilities and creates an XML report of them.")]