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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -59,7 +59,8 @@ namespace DiscImageChef.Core.Devices.Dumping
/// <param name="resume">Information for dump resuming</param> /// <param name="resume">Information for dump resuming</param>
/// <param name="dumpLog">Dump logger</param> /// <param name="dumpLog">Dump logger</param>
internal static void Dump(Device dev, string outputPrefix, string devicePath, ref Resume resume, internal static void Dump(Device dev, string outputPrefix, string devicePath, ref Resume resume,
ref DumpLog dumpLog) ref DumpLog dumpLog,
CICMMetadataType preSidecar)
{ {
FixedSense? fxSense; FixedSense? fxSense;
bool aborted; bool aborted;
@@ -74,7 +75,7 @@ namespace DiscImageChef.Core.Devices.Dumping
double currentSpeed = 0; double currentSpeed = 0;
double maxSpeed = double.MinValue; double maxSpeed = double.MinValue;
double minSpeed = double.MaxValue; double minSpeed = double.MaxValue;
CICMMetadataType sidecar = new CICMMetadataType(); CICMMetadataType sidecar = preSidecar ?? new CICMMetadataType();
dev.RequestSense(out byte[] senseBuf, dev.Timeout, out double duration); dev.RequestSense(out byte[] senseBuf, dev.Timeout, out double duration);
fxSense = Sense.DecodeFixed(senseBuf, out string strSense); 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, bool force, bool dumpRaw, bool persistent, bool stopOnError,
ref Resume resume, ref Resume resume,
ref ref
DumpLog dumpLog, Encoding encoding, string outputPrefix, string outputPath, DumpLog dumpLog, Encoding encoding, string outputPrefix,
string outputPath,
Dictionary<string, string> Dictionary<string, string>
formatOptions) formatOptions, CICMMetadataType preSidecar)
{ {
bool aborted; bool aborted;
@@ -391,6 +392,7 @@ namespace DiscImageChef.Core.Devices.Dumping
currentTry.Extents = ExtentsConverter.ToMetadata(extents); currentTry.Extents = ExtentsConverter.ToMetadata(extents);
outputPlugin.SetDumpHardware(resume.Tries); outputPlugin.SetDumpHardware(resume.Tries);
if(preSidecar != null) outputPlugin.SetCicmMetadata(preSidecar);
dumpLog.WriteLine("Closing output file."); dumpLog.WriteLine("Closing output file.");
DicConsole.WriteLine("Closing output file."); DicConsole.WriteLine("Closing output file.");
outputPlugin.Close(); outputPlugin.Close();
@@ -410,6 +412,12 @@ namespace DiscImageChef.Core.Devices.Dumping
DateTime chkStart = DateTime.UtcNow; DateTime chkStart = DateTime.UtcNow;
CICMMetadataType sidecar = Sidecar.Create(inputPlugin, outputPath, filter.Id, encoding); CICMMetadataType sidecar = Sidecar.Create(inputPlugin, outputPath, filter.Id, encoding);
if(preSidecar != null)
{
preSidecar.BlockMedia = sidecar.BlockMedia;
sidecar = preSidecar;
}
switch(dev.Type) switch(dev.Type)
{ {
case DeviceType.MMC: case DeviceType.MMC:

View File

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

View File

@@ -43,6 +43,7 @@ using DiscImageChef.Core.Logging;
using DiscImageChef.Devices; using DiscImageChef.Devices;
using DiscImageChef.DiscImages; using DiscImageChef.DiscImages;
using DiscImageChef.Metadata; using DiscImageChef.Metadata;
using Schemas;
namespace DiscImageChef.Commands namespace DiscImageChef.Commands
{ {
@@ -74,6 +75,7 @@ namespace DiscImageChef.Commands
DicConsole.DebugWriteLine("Dump-Media command", "--format={0}", options.OutputFormat); DicConsole.DebugWriteLine("Dump-Media command", "--format={0}", options.OutputFormat);
DicConsole.DebugWriteLine("Dump-Media command", "--force={0}", options.Force); DicConsole.DebugWriteLine("Dump-Media command", "--force={0}", options.Force);
DicConsole.DebugWriteLine("Dump-Media command", "--options={0}", options.Options); 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); Dictionary<string, string> parsedOptions = Options.Parse(options.Options);
DicConsole.DebugWriteLine("Dump-Media command", "Parsed options:"); DicConsole.DebugWriteLine("Dump-Media command", "Parsed options:");
@@ -132,6 +134,27 @@ namespace DiscImageChef.Commands
return; 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(); PluginBase plugins = new PluginBase();
List<IWritableImage> candidates = new List<IWritableImage>(); List<IWritableImage> candidates = new List<IWritableImage>();
@@ -182,24 +205,24 @@ namespace DiscImageChef.Commands
case DeviceType.ATA: case DeviceType.ATA:
Ata.Dump(dev, options.DevicePath, outputFormat, options.RetryPasses, options.Force, options.Raw, Ata.Dump(dev, options.DevicePath, outputFormat, options.RetryPasses, options.Force, options.Raw,
options.Persistent, options.StopOnError, ref resume, ref dumpLog, encoding, outputPrefix, options.Persistent, options.StopOnError, ref resume, ref dumpLog, encoding, outputPrefix,
options.OutputFile, parsedOptions); options.OutputFile, parsedOptions, sidecar);
break; break;
case DeviceType.MMC: case DeviceType.MMC:
case DeviceType.SecureDigital: case DeviceType.SecureDigital:
SecureDigital.Dump(dev, options.DevicePath, outputFormat, options.RetryPasses, options.Force, SecureDigital.Dump(dev, options.DevicePath, outputFormat, options.RetryPasses, options.Force,
options.Raw, options.Persistent, options.StopOnError, ref resume, ref dumpLog, options.Raw, options.Persistent, options.StopOnError, ref resume, ref dumpLog,
encoding, outputPrefix, options.OutputFile, parsedOptions); encoding, outputPrefix, options.OutputFile, parsedOptions, sidecar);
break; break;
case DeviceType.NVMe: case DeviceType.NVMe:
NvMe.Dump(dev, options.DevicePath, outputFormat, options.RetryPasses, options.Force, options.Raw, NvMe.Dump(dev, options.DevicePath, outputFormat, options.RetryPasses, options.Force, options.Raw,
options.Persistent, options.StopOnError, ref resume, ref dumpLog, encoding, outputPrefix, options.Persistent, options.StopOnError, ref resume, ref dumpLog, encoding, outputPrefix,
options.OutputFile, parsedOptions); options.OutputFile, parsedOptions, sidecar);
break; break;
case DeviceType.ATAPI: case DeviceType.ATAPI:
case DeviceType.SCSI: case DeviceType.SCSI:
Scsi.Dump(dev, options.DevicePath, outputFormat, options.RetryPasses, options.Force, options.Raw, Scsi.Dump(dev, options.DevicePath, outputFormat, options.RetryPasses, options.Force, options.Raw,
options.Persistent, options.StopOnError, ref resume, ref dumpLog, options.LeadIn, options.Persistent, options.StopOnError, ref resume, ref dumpLog, options.LeadIn,
encoding, outputPrefix, options.OutputFile, parsedOptions); encoding, outputPrefix, options.OutputFile, parsedOptions, sidecar);
break; break;
default: default:
dumpLog.WriteLine("Unknown device type."); dumpLog.WriteLine("Unknown device type.");

View File

@@ -305,6 +305,9 @@ namespace DiscImageChef
[Option('O', "options", Default = null, [Option('O', "options", Default = null,
HelpText = "Comma separated name=value pairs of options to pass to output image plugin")] HelpText = "Comma separated name=value pairs of options to pass to output image plugin")]
public string Options { get; set; } 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.")] [Verb("device-report", HelpText = "Tests the device capabilities and creates an XML report of them.")]