Use Mono.Options as command line parser.

This commit is contained in:
2019-01-05 16:59:23 +00:00
parent bbedcfe843
commit 104bc55c5e
30 changed files with 2221 additions and 1392 deletions

View File

@@ -37,41 +37,92 @@ using DiscImageChef.CommonTypes;
using DiscImageChef.CommonTypes.Interfaces;
using DiscImageChef.Console;
using DiscImageChef.Core;
using Mono.Options;
namespace DiscImageChef.Commands
{
static class Analyze
class AnalyzeCommand : Command
{
internal static void DoAnalyze(AnalyzeOptions options)
string encodingName;
string inputFile;
bool searchForFilesystems = true;
bool searchForPartitions = true;
bool showHelp;
public AnalyzeCommand() : base("analyze",
"Analyzes a disc image and searches for partitions and/or filesystems.")
{
DicConsole.DebugWriteLine("Analyze command", "--debug={0}", options.Debug);
DicConsole.DebugWriteLine("Analyze command", "--verbose={0}", options.Verbose);
DicConsole.DebugWriteLine("Analyze command", "--input={0}", options.InputFile);
DicConsole.DebugWriteLine("Analyze command", "--filesystems={0}", options.SearchForFilesystems);
DicConsole.DebugWriteLine("Analyze command", "--partitions={0}", options.SearchForPartitions);
DicConsole.DebugWriteLine("Analyze command", "--encoding={0}", options.EncodingName);
Options = new OptionSet
{
$"{MainClass.AssemblyTitle} {MainClass.AssemblyVersion?.InformationalVersion}",
$"{MainClass.AssemblyCopyright}",
"",
$"usage: DiscImageChef {Name} [OPTIONS] imagefile",
"",
Help,
{"encoding|e=", "Name of character encoding to use.", s => encodingName = s},
{"filesystems|f", "Searches and analyzes filesystems.", b => searchForFilesystems = b != null},
{"partitions|p", "Searches and interprets partitions.", b => searchForPartitions = b != null},
{"help|h|?", "Show this message and exit.", v => showHelp = v != null}
};
}
public override int Invoke(IEnumerable<string> arguments)
{
List<string> extra = Options.Parse(arguments);
if(showHelp)
{
Options.WriteOptionDescriptions(CommandSet.Out);
return 0;
}
MainClass.PrintCopyright();
if(MainClass.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
if(MainClass.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
if(extra.Count > 1)
{
DicConsole.ErrorWriteLine("Too many arguments.");
return 1;
}
if(extra.Count == 0)
{
DicConsole.ErrorWriteLine("Missing input image.");
return 1;
}
inputFile = extra[0];
DicConsole.DebugWriteLine("Analyze command", "--debug={0}", MainClass.Debug);
DicConsole.DebugWriteLine("Analyze command", "--encoding={0}", encodingName);
DicConsole.DebugWriteLine("Analyze command", "--filesystems={0}", searchForFilesystems);
DicConsole.DebugWriteLine("Analyze command", "--input={0}", inputFile);
DicConsole.DebugWriteLine("Analyze command", "--partitions={0}", searchForPartitions);
DicConsole.DebugWriteLine("Analyze command", "--verbose={0}", MainClass.Verbose);
FiltersList filtersList = new FiltersList();
IFilter inputFilter = filtersList.GetFilter(options.InputFile);
IFilter inputFilter = filtersList.GetFilter(inputFile);
if(inputFilter == null)
{
DicConsole.ErrorWriteLine("Cannot open specified file.");
return;
return 2;
}
Encoding encoding = null;
if(options.EncodingName != null)
if(encodingName != null)
try
{
encoding = Claunia.Encoding.Encoding.GetEncoding(options.EncodingName);
if(options.Verbose) DicConsole.VerboseWriteLine("Using encoding for {0}.", encoding.EncodingName);
encoding = Claunia.Encoding.Encoding.GetEncoding(encodingName);
if(MainClass.Verbose) DicConsole.VerboseWriteLine("Using encoding for {0}.", encoding.EncodingName);
}
catch(ArgumentException)
{
DicConsole.ErrorWriteLine("Specified encoding is not supported.");
return;
return 5;
}
PluginBase plugins = GetPluginBase.Instance;
@@ -85,10 +136,10 @@ namespace DiscImageChef.Commands
if(imageFormat == null)
{
DicConsole.WriteLine("Image format not identified, not proceeding with analysis.");
return;
return 3;
}
if(options.Verbose)
if(MainClass.Verbose)
DicConsole.VerboseWriteLine("Image format identified by {0} ({1}).", imageFormat.Name,
imageFormat.Id);
else DicConsole.WriteLine("Image format identified by {0}.", imageFormat.Name);
@@ -100,31 +151,31 @@ namespace DiscImageChef.Commands
{
DicConsole.WriteLine("Unable to open image format");
DicConsole.WriteLine("No error given");
return;
return 4;
}
if(options.Verbose)
if(MainClass.Verbose)
{
Core.ImageInfo.PrintImageInfo(imageFormat);
ImageInfo.PrintImageInfo(imageFormat);
DicConsole.WriteLine();
}
Core.Statistics.AddMediaFormat(imageFormat.Format);
Core.Statistics.AddMedia(imageFormat.Info.MediaType, false);
Core.Statistics.AddFilter(inputFilter.Name);
Statistics.AddMediaFormat(imageFormat.Format);
Statistics.AddMedia(imageFormat.Info.MediaType, false);
Statistics.AddFilter(inputFilter.Name);
}
catch(Exception ex)
{
DicConsole.ErrorWriteLine("Unable to open image format");
DicConsole.ErrorWriteLine("Error: {0}", ex.Message);
DicConsole.DebugWriteLine("Analyze command", "Stack trace: {0}", ex.StackTrace);
return;
return -1;
}
List<string> idPlugins;
IFilesystem plugin;
string information;
if(options.SearchForPartitions)
if(searchForPartitions)
{
List<Partition> partitions = Core.Partitions.GetAll(imageFormat);
Core.Partitions.AddSchemesToStats(partitions);
@@ -132,10 +183,10 @@ namespace DiscImageChef.Commands
if(partitions.Count == 0)
{
DicConsole.DebugWriteLine("Analyze command", "No partitions found");
if(!options.SearchForFilesystems)
if(!searchForFilesystems)
{
DicConsole.WriteLine("No partitions founds, not searching for filesystems");
return;
return -2;
}
checkraw = true;
@@ -158,7 +209,7 @@ namespace DiscImageChef.Commands
DicConsole.WriteLine("Partition description:");
DicConsole.WriteLine(partitions[i].Description);
if(!options.SearchForFilesystems) continue;
if(!searchForFilesystems) continue;
DicConsole.WriteLine("Identifying filesystem on partition");
@@ -174,7 +225,7 @@ namespace DiscImageChef.Commands
DicConsole.WriteLine($"As identified by {plugin.Name}.");
plugin.GetInformation(imageFormat, partitions[i], out information, encoding);
DicConsole.Write(information);
Core.Statistics.AddFilesystem(plugin.XmlFsType.Type);
Statistics.AddFilesystem(plugin.XmlFsType.Type);
}
}
else
@@ -185,7 +236,7 @@ namespace DiscImageChef.Commands
DicConsole.WriteLine($"Identified by {plugin.Name}.");
plugin.GetInformation(imageFormat, partitions[i], out information, encoding);
DicConsole.Write("{0}", information);
Core.Statistics.AddFilesystem(plugin.XmlFsType.Type);
Statistics.AddFilesystem(plugin.XmlFsType.Type);
}
}
}
@@ -212,7 +263,7 @@ namespace DiscImageChef.Commands
DicConsole.WriteLine($"As identified by {plugin.Name}.");
plugin.GetInformation(imageFormat, wholePart, out information, encoding);
DicConsole.Write(information);
Core.Statistics.AddFilesystem(plugin.XmlFsType.Type);
Statistics.AddFilesystem(plugin.XmlFsType.Type);
}
}
else
@@ -223,7 +274,7 @@ namespace DiscImageChef.Commands
DicConsole.WriteLine($"Identified by {plugin.Name}.");
plugin.GetInformation(imageFormat, wholePart, out information, encoding);
DicConsole.Write(information);
Core.Statistics.AddFilesystem(plugin.XmlFsType.Type);
Statistics.AddFilesystem(plugin.XmlFsType.Type);
}
}
}
@@ -234,7 +285,8 @@ namespace DiscImageChef.Commands
DicConsole.DebugWriteLine("Analyze command", ex.StackTrace);
}
Core.Statistics.AddCommand("analyze");
Statistics.AddCommand("analyze");
return 0;
}
}
}

View File

@@ -33,19 +33,60 @@
using System.Collections.Generic;
using DiscImageChef.Console;
using DiscImageChef.Core;
using Mono.Options;
namespace DiscImageChef.Commands
{
static class Benchmark
class BenchmarkCommand : Command
{
internal static void DoBenchmark(BenchmarkOptions options)
{
Dictionary<string, double> checksumTimes = new Dictionary<string, double>();
Core.Benchmark.InitProgressEvent += Progress.InitProgress;
Core.Benchmark.UpdateProgressEvent += Progress.UpdateProgress;
Core.Benchmark.EndProgressEvent += Progress.EndProgress;
int blockSize = 512;
int bufferSize = 128;
bool showHelp;
BenchmarkResults results = Core.Benchmark.Do(options.BufferSize * 1024 * 1024, options.BlockSize);
public BenchmarkCommand() : base("benchmark", "Benchmarks hashing and entropy calculation.")
{
Options = new OptionSet
{
$"{MainClass.AssemblyTitle} {MainClass.AssemblyVersion?.InformationalVersion}",
$"{MainClass.AssemblyCopyright}",
"",
$"usage: DiscImageChef {Name} [OPTIONS]",
"",
Help,
{"block-size|b=", "Block size.", (int i) => blockSize = i},
{"buffer-size|s=", "Buffer size in mebibytes.", (int i) => bufferSize = i},
{"help|h|?", "Show this message and exit.", v => showHelp = v != null}
};
}
public override int Invoke(IEnumerable<string> arguments)
{
List<string> extra = Options.Parse(arguments);
if(showHelp)
{
Options.WriteOptionDescriptions(CommandSet.Out);
return 0;
}
MainClass.PrintCopyright();
if(MainClass.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
if(MainClass.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
if(extra.Count != 0)
{
DicConsole.ErrorWriteLine("Too many arguments.");
return 1;
}
DicConsole.DebugWriteLine("Benchmark command", "--debug={0}", MainClass.Debug);
DicConsole.DebugWriteLine("Benchmark command", "--verbose={0}", MainClass.Verbose);
Benchmark.InitProgressEvent += Progress.InitProgress;
Benchmark.UpdateProgressEvent += Progress.UpdateProgress;
Benchmark.EndProgressEvent += Progress.EndProgress;
BenchmarkResults results = Benchmark.Do(bufferSize * 1024 * 1024, blockSize);
DicConsole.WriteLine("Took {0} seconds to fill buffer, {1:F3} MiB/sec.", results.FillTime,
results.FillSpeed);
@@ -55,11 +96,8 @@ namespace DiscImageChef.Commands
results.EntropySpeed);
foreach(KeyValuePair<string, BenchmarkEntry> entry in results.Entries)
{
checksumTimes.Add(entry.Key, entry.Value.TimeSpan);
DicConsole.WriteLine("Took {0} seconds to {1} buffer, {2:F3} MiB/sec.", entry.Value.TimeSpan, entry.Key,
entry.Value.Speed);
}
DicConsole.WriteLine("Took {0} seconds to do all algorithms at the same time, {1:F3} MiB/sec.",
results.TotalTime, results.TotalSpeed);
@@ -70,7 +108,8 @@ namespace DiscImageChef.Commands
DicConsole.WriteLine("Max memory used is {0} bytes", results.MaxMemory);
DicConsole.WriteLine("Min memory used is {0} bytes", results.MinMemory);
Core.Statistics.AddCommand("benchmark");
Statistics.AddCommand("benchmark");
return 0;
}
}
}

View File

@@ -37,43 +37,117 @@ using DiscImageChef.CommonTypes.Interfaces;
using DiscImageChef.CommonTypes.Structs;
using DiscImageChef.Console;
using DiscImageChef.Core;
using Mono.Options;
using Schemas;
namespace DiscImageChef.Commands
{
static class Checksum
class ChecksumCommand : Command
{
// How many sectors to read at once
const uint SECTORS_TO_READ = 256;
internal static void DoChecksum(ChecksumOptions options)
bool doAdler32 = true;
bool doCrc16 = true;
bool doCrc32 = true;
bool doCrc64;
bool doFletcher16;
bool doFletcher32;
bool doMd5 = true;
bool doRipemd160;
bool doSha1 = true;
bool doSha256;
bool doSha384;
bool doSha512;
bool doSpamSum = true;
string inputFile;
bool separatedTracks = true;
bool showHelp;
bool wholeDisc = true;
public ChecksumCommand() : base("checksum", "Checksums an image.")
{
DicConsole.DebugWriteLine("Checksum command", "--debug={0}", options.Debug);
DicConsole.DebugWriteLine("Checksum command", "--verbose={0}", options.Verbose);
DicConsole.DebugWriteLine("Checksum command", "--separated-tracks={0}", options.SeparatedTracks);
DicConsole.DebugWriteLine("Checksum command", "--whole-disc={0}", options.WholeDisc);
DicConsole.DebugWriteLine("Checksum command", "--input={0}", options.InputFile);
DicConsole.DebugWriteLine("Checksum command", "--adler32={0}", options.DoAdler32);
DicConsole.DebugWriteLine("Checksum command", "--crc16={0}", options.DoCrc16);
DicConsole.DebugWriteLine("Checksum command", "--crc32={0}", options.DoCrc32);
DicConsole.DebugWriteLine("Checksum command", "--crc64={0}", options.DoCrc64);
DicConsole.DebugWriteLine("Checksum command", "--md5={0}", options.DoMd5);
DicConsole.DebugWriteLine("Checksum command", "--ripemd160={0}", options.DoRipemd160);
DicConsole.DebugWriteLine("Checksum command", "--sha1={0}", options.DoSha1);
DicConsole.DebugWriteLine("Checksum command", "--sha256={0}", options.DoSha256);
DicConsole.DebugWriteLine("Checksum command", "--sha384={0}", options.DoSha384);
DicConsole.DebugWriteLine("Checksum command", "--sha512={0}", options.DoSha512);
DicConsole.DebugWriteLine("Checksum command", "--spamsum={0}", options.DoSpamSum);
DicConsole.DebugWriteLine("Checksum command", "--fletcher16={0}", options.DoFletcher16);
DicConsole.DebugWriteLine("Checksum command", "--fletcher32={0}", options.DoFletcher32);
Options = new OptionSet
{
$"{MainClass.AssemblyTitle} {MainClass.AssemblyVersion?.InformationalVersion}",
$"{MainClass.AssemblyCopyright}",
"",
$"usage: DiscImageChef {Name} [OPTIONS] imagefile",
"",
Help,
{"adler32|a", "Calculates Adler-32.", b => doAdler32 = b != null},
{"crc16", "Calculates CRC16.", b => doCrc16 = b != null},
{"crc32|c", "Calculates CRC32.", b => doCrc32 = b != null},
{"crc64", "Calculates CRC64 (ECMA).", b => doCrc64 = b != null},
{"fletcher16", "Calculates Fletcher-16.", b => doFletcher16 = b != null},
{"fletcher32", "Calculates Fletcher-32.", b => doFletcher32 = b != null},
{"md5|m", "Calculates MD5.", b => doMd5 = b != null},
{"ripemd160", "Calculates RIPEMD160.", b => doRipemd160 = b != null},
{"separated-tracks|t", "Checksums each track separately.", b => separatedTracks = b != null},
{"sha1|s", "Calculates SHA1.", b => doSha1 = b != null},
{"sha256", "Calculates SHA256.", b => doSha256 = b != null},
{"sha384", "Calculates SHA384.", b => doSha384 = b != null},
{"sha512", "Calculates SHA512.", b => doSha512 = b != null},
{"spamsum|f", "Calculates SpamSum fuzzy hash.", b => doSpamSum = b != null},
{"whole-disc|w", "Checksums the whole disc.", b => wholeDisc = b != null},
{"help|h|?", "Show this message and exit.", v => showHelp = v != null}
};
}
public override int Invoke(IEnumerable<string> arguments)
{
List<string> extra = Options.Parse(arguments);
if(showHelp)
{
Options.WriteOptionDescriptions(CommandSet.Out);
return 0;
}
MainClass.PrintCopyright();
if(MainClass.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
if(MainClass.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
if(extra.Count > 1)
{
DicConsole.ErrorWriteLine("Too many arguments.");
return 1;
}
if(extra.Count == 0)
{
DicConsole.ErrorWriteLine("Missing input image.");
return 1;
}
inputFile = extra[0];
DicConsole.DebugWriteLine("Checksum command", "--adler32={0}", doAdler32);
DicConsole.DebugWriteLine("Checksum command", "--crc16={0}", doCrc16);
DicConsole.DebugWriteLine("Checksum command", "--crc32={0}", doCrc32);
DicConsole.DebugWriteLine("Checksum command", "--crc64={0}", doCrc64);
DicConsole.DebugWriteLine("Checksum command", "--debug={0}", MainClass.Debug);
DicConsole.DebugWriteLine("Checksum command", "--fletcher16={0}", doFletcher16);
DicConsole.DebugWriteLine("Checksum command", "--fletcher32={0}", doFletcher32);
DicConsole.DebugWriteLine("Checksum command", "--input={0}", inputFile);
DicConsole.DebugWriteLine("Checksum command", "--md5={0}", doMd5);
DicConsole.DebugWriteLine("Checksum command", "--ripemd160={0}", doRipemd160);
DicConsole.DebugWriteLine("Checksum command", "--separated-tracks={0}", separatedTracks);
DicConsole.DebugWriteLine("Checksum command", "--sha1={0}", doSha1);
DicConsole.DebugWriteLine("Checksum command", "--sha256={0}", doSha256);
DicConsole.DebugWriteLine("Checksum command", "--sha384={0}", doSha384);
DicConsole.DebugWriteLine("Checksum command", "--sha512={0}", doSha512);
DicConsole.DebugWriteLine("Checksum command", "--spamsum={0}", doSpamSum);
DicConsole.DebugWriteLine("Checksum command", "--verbose={0}", MainClass.Verbose);
DicConsole.DebugWriteLine("Checksum command", "--whole-disc={0}", wholeDisc);
FiltersList filtersList = new FiltersList();
IFilter inputFilter = filtersList.GetFilter(options.InputFile);
IFilter inputFilter = filtersList.GetFilter(inputFile);
if(inputFilter == null)
{
DicConsole.ErrorWriteLine("Cannot open specified file.");
return;
return 1;
}
IMediaImage inputFormat = ImageFormat.Detect(inputFilter);
@@ -81,44 +155,44 @@ namespace DiscImageChef.Commands
if(inputFormat == null)
{
DicConsole.ErrorWriteLine("Unable to recognize image format, not checksumming");
return;
return 2;
}
inputFormat.Open(inputFilter);
Core.Statistics.AddMediaFormat(inputFormat.Format);
Core.Statistics.AddMedia(inputFormat.Info.MediaType, false);
Core.Statistics.AddFilter(inputFilter.Name);
Statistics.AddMediaFormat(inputFormat.Format);
Statistics.AddMedia(inputFormat.Info.MediaType, false);
Statistics.AddFilter(inputFilter.Name);
EnableChecksum enabledChecksums = new EnableChecksum();
if(options.DoAdler32) enabledChecksums |= EnableChecksum.Adler32;
if(options.DoCrc16) enabledChecksums |= EnableChecksum.Crc16;
if(options.DoCrc32) enabledChecksums |= EnableChecksum.Crc32;
if(options.DoCrc64) enabledChecksums |= EnableChecksum.Crc64;
if(options.DoMd5) enabledChecksums |= EnableChecksum.Md5;
if(options.DoRipemd160) enabledChecksums |= EnableChecksum.Ripemd160;
if(options.DoSha1) enabledChecksums |= EnableChecksum.Sha1;
if(options.DoSha256) enabledChecksums |= EnableChecksum.Sha256;
if(options.DoSha384) enabledChecksums |= EnableChecksum.Sha384;
if(options.DoSha512) enabledChecksums |= EnableChecksum.Sha512;
if(options.DoSpamSum) enabledChecksums |= EnableChecksum.SpamSum;
if(options.DoFletcher16) enabledChecksums |= EnableChecksum.Fletcher16;
if(options.DoFletcher32) enabledChecksums |= EnableChecksum.Fletcher32;
if(doAdler32) enabledChecksums |= EnableChecksum.Adler32;
if(doCrc16) enabledChecksums |= EnableChecksum.Crc16;
if(doCrc32) enabledChecksums |= EnableChecksum.Crc32;
if(doCrc64) enabledChecksums |= EnableChecksum.Crc64;
if(doMd5) enabledChecksums |= EnableChecksum.Md5;
if(doRipemd160) enabledChecksums |= EnableChecksum.Ripemd160;
if(doSha1) enabledChecksums |= EnableChecksum.Sha1;
if(doSha256) enabledChecksums |= EnableChecksum.Sha256;
if(doSha384) enabledChecksums |= EnableChecksum.Sha384;
if(doSha512) enabledChecksums |= EnableChecksum.Sha512;
if(doSpamSum) enabledChecksums |= EnableChecksum.SpamSum;
if(doFletcher16) enabledChecksums |= EnableChecksum.Fletcher16;
if(doFletcher32) enabledChecksums |= EnableChecksum.Fletcher32;
Core.Checksum mediaChecksum = null;
Checksum mediaChecksum = null;
if(inputFormat.Info.HasPartitions)
try
{
Core.Checksum trackChecksum = null;
Checksum trackChecksum = null;
if(options.WholeDisc) mediaChecksum = new Core.Checksum(enabledChecksums);
if(wholeDisc) mediaChecksum = new Checksum(enabledChecksums);
ulong previousTrackEnd = 0;
List<Track> inputTracks = inputFormat.Tracks;
foreach(Track currentTrack in inputTracks)
{
if(currentTrack.TrackStartSector - previousTrackEnd != 0 && options.WholeDisc)
if(currentTrack.TrackStartSector - previousTrackEnd != 0 && wholeDisc)
for(ulong i = previousTrackEnd + 1; i < currentTrack.TrackStartSector; i++)
{
DicConsole.Write("\rHashing track-less sector {0}", i);
@@ -133,7 +207,7 @@ namespace DiscImageChef.Commands
currentTrack.TrackSequence, currentTrack.TrackStartSector,
currentTrack.TrackEndSector);
if(options.SeparatedTracks) trackChecksum = new Core.Checksum(enabledChecksums);
if(separatedTracks) trackChecksum = new Checksum(enabledChecksums);
ulong sectors = currentTrack.TrackEndSector - currentTrack.TrackStartSector + 1;
ulong doneSectors = 0;
@@ -160,14 +234,14 @@ namespace DiscImageChef.Commands
doneSectors += sectors - doneSectors;
}
if(options.WholeDisc) mediaChecksum?.Update(sector);
if(wholeDisc) mediaChecksum?.Update(sector);
if(options.SeparatedTracks) trackChecksum?.Update(sector);
if(separatedTracks) trackChecksum?.Update(sector);
}
DicConsole.WriteLine();
if(options.SeparatedTracks)
if(separatedTracks)
if(trackChecksum != null)
foreach(ChecksumType chk in trackChecksum.End())
DicConsole.WriteLine("Track {0}'s {1}: {2}", currentTrack.TrackSequence, chk.type,
@@ -176,7 +250,7 @@ namespace DiscImageChef.Commands
previousTrackEnd = currentTrack.TrackEndSector;
}
if(inputFormat.Info.Sectors - previousTrackEnd != 0 && options.WholeDisc)
if(inputFormat.Info.Sectors - previousTrackEnd != 0 && wholeDisc)
for(ulong i = previousTrackEnd + 1; i < inputFormat.Info.Sectors; i++)
{
DicConsole.Write("\rHashing track-less sector {0}", i);
@@ -185,19 +259,19 @@ namespace DiscImageChef.Commands
mediaChecksum?.Update(hiddenSector);
}
if(options.WholeDisc)
if(wholeDisc)
if(mediaChecksum != null)
foreach(ChecksumType chk in mediaChecksum.End())
DicConsole.WriteLine("Disk's {0}: {1}", chk.type, chk.Value);
}
catch(Exception ex)
{
if(options.Debug) DicConsole.DebugWriteLine("Could not get tracks because {0}", ex.Message);
if(MainClass.Debug) DicConsole.DebugWriteLine("Could not get tracks because {0}", ex.Message);
else DicConsole.WriteLine("Unable to get separate tracks, not checksumming them");
}
else
{
mediaChecksum = new Core.Checksum(enabledChecksums);
mediaChecksum = new Checksum(enabledChecksums);
ulong sectors = inputFormat.Info.Sectors;
DicConsole.WriteLine("Sectors {0}", sectors);
@@ -230,7 +304,8 @@ namespace DiscImageChef.Commands
DicConsole.WriteLine("Disk's {0}: {1}", chk.type, chk.Value);
}
Core.Statistics.AddCommand("checksum");
Statistics.AddCommand("checksum");
return 0;
}
}
}

View File

@@ -39,33 +39,80 @@ using DiscImageChef.CommonTypes.Interfaces;
using DiscImageChef.CommonTypes.Structs;
using DiscImageChef.Console;
using DiscImageChef.Core;
using Mono.Options;
using ImageInfo = DiscImageChef.CommonTypes.Structs.ImageInfo;
namespace DiscImageChef.Commands
{
static class Compare
class CompareCommand : Command
{
internal static void DoCompare(CompareOptions options)
string InputFile1;
string InputFile2;
bool ShowHelp;
public CompareCommand() : base("compare", "Compares two disc images.")
{
DicConsole.DebugWriteLine("Compare command", "--debug={0}", options.Debug);
DicConsole.DebugWriteLine("Compare command", "--verbose={0}", options.Verbose);
DicConsole.DebugWriteLine("Compare command", "--input1={0}", options.InputFile1);
DicConsole.DebugWriteLine("Compare command", "--input2={0}", options.InputFile2);
Options = new OptionSet
{
$"{MainClass.AssemblyTitle} {MainClass.AssemblyVersion?.InformationalVersion}",
$"{MainClass.AssemblyCopyright}",
"",
$"usage: DiscImageChef {Name} imagefile1 imagefile2",
"",
Help,
{"help|h|?", "Show this message and exit.", v => ShowHelp = v != null}
};
}
public override int Invoke(IEnumerable<string> arguments)
{
List<string> extra = Options.Parse(arguments);
if(ShowHelp)
{
Options.WriteOptionDescriptions(CommandSet.Out);
return 0;
}
MainClass.PrintCopyright();
if(MainClass.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
if(MainClass.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
if(extra.Count > 2)
{
DicConsole.ErrorWriteLine("Too many arguments.");
return 1;
}
if(extra.Count <= 1)
{
DicConsole.ErrorWriteLine("Missing input image.");
return 1;
}
InputFile1 = extra[0];
InputFile1 = extra[1];
DicConsole.DebugWriteLine("Compare command", "--debug={0}", MainClass.Debug);
DicConsole.DebugWriteLine("Compare command", "--input1={0}", InputFile1);
DicConsole.DebugWriteLine("Compare command", "--input2={0}", InputFile2);
DicConsole.DebugWriteLine("Compare command", "--verbose={0}", MainClass.Verbose);
FiltersList filtersList = new FiltersList();
IFilter inputFilter1 = filtersList.GetFilter(options.InputFile1);
IFilter inputFilter1 = filtersList.GetFilter(InputFile1);
filtersList = new FiltersList();
IFilter inputFilter2 = filtersList.GetFilter(options.InputFile2);
IFilter inputFilter2 = filtersList.GetFilter(InputFile2);
if(inputFilter1 == null)
{
DicConsole.ErrorWriteLine("Cannot open input file 1");
return;
return 1;
}
if(inputFilter2 == null)
{
DicConsole.ErrorWriteLine("Cannot open input file 2");
return;
return 2;
}
IMediaImage input1Format = ImageFormat.Detect(inputFilter1);
@@ -74,10 +121,10 @@ namespace DiscImageChef.Commands
if(input1Format == null)
{
DicConsole.ErrorWriteLine("Input file 1 format not identified, not proceeding with comparison.");
return;
return 3;
}
if(options.Verbose)
if(MainClass.Verbose)
DicConsole.VerboseWriteLine("Input file 1 format identified by {0} ({1}).", input1Format.Name,
input1Format.Id);
else DicConsole.WriteLine("Input file 1 format identified by {0}.", input1Format.Name);
@@ -85,10 +132,10 @@ namespace DiscImageChef.Commands
if(input2Format == null)
{
DicConsole.ErrorWriteLine("Input file 2 format not identified, not proceeding with comparison.");
return;
return 4;
}
if(options.Verbose)
if(MainClass.Verbose)
DicConsole.VerboseWriteLine("Input file 2 format identified by {0} ({1}).", input2Format.Name,
input2Format.Id);
else DicConsole.WriteLine("Input file 2 format identified by {0}.", input2Format.Name);
@@ -96,32 +143,32 @@ namespace DiscImageChef.Commands
input1Format.Open(inputFilter1);
input2Format.Open(inputFilter2);
Core.Statistics.AddMediaFormat(input1Format.Format);
Core.Statistics.AddMediaFormat(input2Format.Format);
Core.Statistics.AddMedia(input1Format.Info.MediaType, false);
Core.Statistics.AddMedia(input2Format.Info.MediaType, false);
Core.Statistics.AddFilter(inputFilter1.Name);
Core.Statistics.AddFilter(inputFilter2.Name);
Statistics.AddMediaFormat(input1Format.Format);
Statistics.AddMediaFormat(input2Format.Format);
Statistics.AddMedia(input1Format.Info.MediaType, false);
Statistics.AddMedia(input2Format.Info.MediaType, false);
Statistics.AddFilter(inputFilter1.Name);
Statistics.AddFilter(inputFilter2.Name);
StringBuilder sb = new StringBuilder();
if(options.Verbose)
if(MainClass.Verbose)
{
sb.AppendLine("\tDisc image 1\tDisc image 2");
sb.AppendLine("================================");
sb.AppendFormat("File\t{0}\t{1}", options.InputFile1, options.InputFile2).AppendLine();
sb.AppendFormat("File\t{0}\t{1}", InputFile1, InputFile2).AppendLine();
sb.AppendFormat("Disc image format\t{0}\t{1}", input1Format.Name, input2Format.Name).AppendLine();
}
else
{
sb.AppendFormat("Disc image 1: {0}", options.InputFile1).AppendLine();
sb.AppendFormat("Disc image 2: {0}", options.InputFile2).AppendLine();
sb.AppendFormat("Disc image 1: {0}", InputFile1).AppendLine();
sb.AppendFormat("Disc image 2: {0}", InputFile2).AppendLine();
}
bool imagesDiffer = false;
CommonTypes.Structs.ImageInfo image1Info = new CommonTypes.Structs.ImageInfo();
CommonTypes.Structs.ImageInfo image2Info = new CommonTypes.Structs.ImageInfo();
ImageInfo image1Info = new ImageInfo();
ImageInfo image2Info = new ImageInfo();
List<Session> image1Sessions = new List<Session>();
List<Session> image2Sessions = new List<Session>();
Dictionary<MediaTagType, byte[]> image1DiskTags = new Dictionary<MediaTagType, byte[]>();
@@ -221,7 +268,7 @@ namespace DiscImageChef.Commands
#pragma warning restore RECS0022 // A catch clause that catches System.Exception and has an empty body
}
if(options.Verbose)
if(MainClass.Verbose)
{
sb.AppendFormat("Has partitions?\t{0}\t{1}", image1Info.HasPartitions, image2Info.HasPartitions)
.AppendLine();
@@ -272,31 +319,31 @@ namespace DiscImageChef.Commands
if(image1Info.HasPartitions != image2Info.HasPartitions)
{
imagesDiffer = true;
if(!options.Verbose) sb.AppendLine("Image partitioned status differ");
if(!MainClass.Verbose) sb.AppendLine("Image partitioned status differ");
}
if(image1Info.HasSessions != image2Info.HasSessions)
{
imagesDiffer = true;
if(!options.Verbose) sb.AppendLine("Image session status differ");
if(!MainClass.Verbose) sb.AppendLine("Image session status differ");
}
if(image1Info.Sectors != image2Info.Sectors)
{
imagesDiffer = true;
if(!options.Verbose) sb.AppendLine("Image sectors differ");
if(!MainClass.Verbose) sb.AppendLine("Image sectors differ");
}
if(image1Info.SectorSize != image2Info.SectorSize)
{
imagesDiffer = true;
if(!options.Verbose) sb.AppendLine("Image sector size differ");
if(!MainClass.Verbose) sb.AppendLine("Image sector size differ");
}
if(image1Info.MediaType != image2Info.MediaType)
{
imagesDiffer = true;
if(!options.Verbose) sb.AppendLine("Disk type differ");
if(!MainClass.Verbose) sb.AppendLine("Disk type differ");
}
ulong leastSectors;
@@ -304,13 +351,13 @@ namespace DiscImageChef.Commands
{
imagesDiffer = true;
leastSectors = image1Info.Sectors;
if(!options.Verbose) sb.AppendLine("Image 2 has more sectors");
if(!MainClass.Verbose) sb.AppendLine("Image 2 has more sectors");
}
else if(image1Info.Sectors > image2Info.Sectors)
{
imagesDiffer = true;
leastSectors = image2Info.Sectors;
if(!options.Verbose) sb.AppendLine("Image 1 has more sectors");
if(!MainClass.Verbose) sb.AppendLine("Image 1 has more sectors");
}
else leastSectors = image1Info.Sectors;
@@ -351,7 +398,8 @@ namespace DiscImageChef.Commands
DicConsole.WriteLine(sb.ToString());
Core.Statistics.AddCommand("compare");
Statistics.AddCommand("compare");
return 0;
}
}
}

View File

@@ -31,15 +31,59 @@
// ****************************************************************************/
using System;
using System.Collections.Generic;
using DiscImageChef.Console;
using DiscImageChef.Settings;
using Mono.Options;
namespace DiscImageChef.Commands
{
static class Configure
class ConfigureCommand : Command
{
internal static void DoConfigure(bool gdprChange)
readonly bool gdprChange;
bool showHelp;
public ConfigureCommand(bool gdprChange) : base("configure", "Configures user settings and statistics.")
{
this.gdprChange = gdprChange;
Options = new OptionSet
{
$"{MainClass.AssemblyTitle} {MainClass.AssemblyVersion?.InformationalVersion}",
$"{MainClass.AssemblyCopyright}",
"",
$"usage: DiscImageChef {Name}",
"",
Help,
{"help|h|?", "Show this message and exit.", v => showHelp = v != null}
};
}
public override int Invoke(IEnumerable<string> arguments)
{
List<string> extra = Options.Parse(arguments);
if(showHelp)
{
Options.WriteOptionDescriptions(CommandSet.Out);
return 0;
}
MainClass.PrintCopyright();
if(MainClass.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
if(MainClass.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
if(extra.Count != 0)
{
DicConsole.ErrorWriteLine("Too many arguments.");
return 1;
}
if(extra.Count == 0)
{
DicConsole.ErrorWriteLine("Missing input image.");
return 1;
}
if(gdprChange)
{
DicConsole.WriteLine("In compliance with the European Union General Data Protection Regulation 2016/679 (GDPR),\n" +
@@ -228,6 +272,7 @@ namespace DiscImageChef.Commands
Settings.Settings.Current.GdprCompliance = DicSettings.GdprLevel;
Settings.Settings.SaveSettings();
return 0;
}
}
}

View File

@@ -42,107 +42,234 @@ using DiscImageChef.CommonTypes.Metadata;
using DiscImageChef.CommonTypes.Structs;
using DiscImageChef.Console;
using DiscImageChef.Core;
using Mono.Options;
using Schemas;
using ImageInfo = DiscImageChef.CommonTypes.Structs.ImageInfo;
using Version = DiscImageChef.CommonTypes.Interop.Version;
namespace DiscImageChef.Commands
{
public static class ConvertImage
class ConvertImageCommand : Command
{
public static void DoConvert(ConvertImageOptions options)
{
DicConsole.DebugWriteLine("Analyze command", "--debug={0}", options.Debug);
DicConsole.DebugWriteLine("Analyze command", "--verbose={0}", options.Verbose);
DicConsole.DebugWriteLine("Analyze command", "--input={0}", options.InputFile);
DicConsole.DebugWriteLine("Analyze command", "--output={0}", options.OutputFile);
DicConsole.DebugWriteLine("Analyze command", "--format={0}", options.OutputFormat);
DicConsole.DebugWriteLine("Analyze command", "--count={0}", options.Count);
DicConsole.DebugWriteLine("Analyze command", "--force={0}", options.Force);
DicConsole.DebugWriteLine("Analyze command", "--creator={0}", options.Creator);
DicConsole.DebugWriteLine("Analyze command", "--media-title={0}", options.MediaTitle);
DicConsole.DebugWriteLine("Analyze command", "--comments={0}", options.Comments);
DicConsole.DebugWriteLine("Analyze command", "--media-manufacturer={0}", options.MediaManufacturer);
DicConsole.DebugWriteLine("Analyze command", "--media-model={0}", options.MediaModel);
DicConsole.DebugWriteLine("Analyze command", "--media-serial={0}", options.MediaSerialNumber);
DicConsole.DebugWriteLine("Analyze command", "--media-barcode={0}", options.MediaBarcode);
DicConsole.DebugWriteLine("Analyze command", "--media-partnumber={0}", options.MediaPartNumber);
DicConsole.DebugWriteLine("Analyze command", "--media-sequence={0}", options.MediaSequence);
DicConsole.DebugWriteLine("Analyze command", "--media-lastsequence={0}", options.LastMediaSequence);
DicConsole.DebugWriteLine("Analyze command", "--drive-manufacturer={0}", options.DriveManufacturer);
DicConsole.DebugWriteLine("Analyze command", "--drive-model={0}", options.DriveModel);
DicConsole.DebugWriteLine("Analyze command", "--drive-serial={0}", options.DriveSerialNumber);
DicConsole.DebugWriteLine("Analyze command", "--drive-revision={0}", options.DriveFirmwareRevision);
DicConsole.DebugWriteLine("Analyze command", "--cicm-xml={0}", options.CicmXml);
DicConsole.DebugWriteLine("Analyze command", "--resume-file={0}", options.ResumeFile);
DicConsole.DebugWriteLine("Analyze command", "--options={0}", options.Options);
string cicmXml;
string comments;
int count = 64;
string creator;
string driveFirmwareRevision;
string driveManufacturer;
string driveModel;
string driveSerialNumber;
bool force;
string inputFile;
int lastMediaSequence;
string mediaBarcode;
string mediaManufacturer;
string mediaModel;
string mediaPartNumber;
int mediaSequence;
string mediaSerialNumber;
string mediaTitle;
string outputFile;
string outputOptions;
string resumeFile;
bool showHelp;
string wantedOutputFormat;
Dictionary<string, string> parsedOptions = Options.Parse(options.Options);
public ConvertImageCommand() : base("convert-image", "Converts one image to another format.")
{
Options = new OptionSet
{
$"{MainClass.AssemblyTitle} {MainClass.AssemblyVersion?.InformationalVersion}",
$"{MainClass.AssemblyCopyright}",
"",
$"usage: DiscImageChef {Name} [OPTIONS] inputimage outputimage",
"",
Help,
{"cicm-xml|x=", "Take metadata from existing CICM XML sidecar.", s => cicmXml = s},
{"comments=", "Image comments.", s => comments = s},
{"count|c=", "How many sectors to convert at once.", (int i) => count = i},
{"creator=", "Who (person) created the image?.", s => creator = s},
{
"drive-manufacturer=",
"Manufacturer of the drive used to read the media represented by the image.",
s => driveManufacturer = s
},
{
"drive-model=", "Model of the drive used to read the media represented by the image.",
s => driveModel = s
},
{
"drive-revision=",
"Firmware revision of the drive used to read the media represented by the image.",
s => driveFirmwareRevision = s
},
{
"drive-serial=", "Serial number of the drive used to read the media represented by the image.",
s => driveSerialNumber = s
},
{
"force|f", "Continue conversion even if sector or media tags will be lost in the process.",
b => force = b != null
},
{
"format|p=",
"Format of the output image, as plugin name or plugin id. If not present, will try to detect it from output image extension.",
s => wantedOutputFormat = s
},
{"media-barcode=", "Barcode of the media represented by the image.", s => mediaBarcode = s},
{
"media-lastsequence=",
"Last media of the sequence the media represented by the image corresponds to.",
(int i) => lastMediaSequence = i
},
{
"media-manufacturer=", "Manufacturer of the media represented by the image.",
s => mediaManufacturer = s
},
{"media-model=", "Model of the media represented by the image.", s => mediaModel = s},
{
"media-partnumber=", "Part number of the media represented by the image.",
s => mediaPartNumber = s
},
{
"media-sequence=", "Number in sequence for the media represented by the image.",
(int i) => mediaSequence = i
},
{
"media-serial=", "Serial number of the media represented by the image.",
s => mediaSerialNumber = s
},
{"media-title=", "Title of the media represented by the image.", s => mediaTitle = s},
{
"options|O=", "Comma separated name=value pairs of options to pass to output image plugin.",
s => outputOptions = s
},
{"resume-file|r=", "Take list of dump hardware from existing resume file.", s => resumeFile = s},
{"help|h|?", "Show this message and exit.", v => showHelp = v != null}
};
}
public override int Invoke(IEnumerable<string> arguments)
{
List<string> extra = Options.Parse(arguments);
if(showHelp)
{
Options.WriteOptionDescriptions(CommandSet.Out);
return 0;
}
MainClass.PrintCopyright();
if(MainClass.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
if(MainClass.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
if(extra.Count > 2)
{
DicConsole.ErrorWriteLine("Too many arguments.");
return 1;
}
if(extra.Count <= 1)
{
DicConsole.ErrorWriteLine("Missing input image.");
return 1;
}
inputFile = extra[0];
outputFile = extra[1];
DicConsole.DebugWriteLine("Analyze command", "--cicm-xml={0}", cicmXml);
DicConsole.DebugWriteLine("Analyze command", "--comments={0}", comments);
DicConsole.DebugWriteLine("Analyze command", "--count={0}", count);
DicConsole.DebugWriteLine("Analyze command", "--creator={0}", creator);
DicConsole.DebugWriteLine("Analyze command", "--debug={0}", MainClass.Debug);
DicConsole.DebugWriteLine("Analyze command", "--drive-manufacturer={0}", driveManufacturer);
DicConsole.DebugWriteLine("Analyze command", "--drive-model={0}", driveModel);
DicConsole.DebugWriteLine("Analyze command", "--drive-revision={0}", driveFirmwareRevision);
DicConsole.DebugWriteLine("Analyze command", "--drive-serial={0}", driveSerialNumber);
DicConsole.DebugWriteLine("Analyze command", "--force={0}", force);
DicConsole.DebugWriteLine("Analyze command", "--format={0}", wantedOutputFormat);
DicConsole.DebugWriteLine("Analyze command", "--input={0}", inputFile);
DicConsole.DebugWriteLine("Analyze command", "--media-barcode={0}", mediaBarcode);
DicConsole.DebugWriteLine("Analyze command", "--media-lastsequence={0}", lastMediaSequence);
DicConsole.DebugWriteLine("Analyze command", "--media-manufacturer={0}", mediaManufacturer);
DicConsole.DebugWriteLine("Analyze command", "--media-model={0}", mediaModel);
DicConsole.DebugWriteLine("Analyze command", "--media-partnumber={0}", mediaPartNumber);
DicConsole.DebugWriteLine("Analyze command", "--media-sequence={0}", mediaSequence);
DicConsole.DebugWriteLine("Analyze command", "--media-serial={0}", mediaSerialNumber);
DicConsole.DebugWriteLine("Analyze command", "--media-title={0}", mediaTitle);
DicConsole.DebugWriteLine("Analyze command", "--options={0}", outputOptions);
DicConsole.DebugWriteLine("Analyze command", "--output={0}", outputFile);
DicConsole.DebugWriteLine("Analyze command", "--resume-file={0}", resumeFile);
DicConsole.DebugWriteLine("Analyze command", "--verbose={0}", MainClass.Verbose);
Dictionary<string, string> parsedOptions = Core.Options.Parse(outputOptions);
DicConsole.DebugWriteLine("Analyze command", "Parsed options:");
foreach(KeyValuePair<string, string> parsedOption in parsedOptions)
DicConsole.DebugWriteLine("Analyze command", "{0} = {1}", parsedOption.Key, parsedOption.Value);
if(options.Count == 0)
if(count == 0)
{
DicConsole.ErrorWriteLine("Need to specify more than 0 sectors to copy at once");
return;
return 1;
}
Resume resume = null;
CICMMetadataType sidecar = null;
XmlSerializer xs = new XmlSerializer(typeof(CICMMetadataType));
if(options.CicmXml != null)
if(File.Exists(options.CicmXml))
if(cicmXml != null)
if(File.Exists(cicmXml))
try
{
StreamReader sr = new StreamReader(options.CicmXml);
StreamReader sr = new StreamReader(cicmXml);
sidecar = (CICMMetadataType)xs.Deserialize(sr);
sr.Close();
}
catch
{
DicConsole.ErrorWriteLine("Incorrect metadata sidecar file, not continuing...");
return;
return 2;
}
else
{
DicConsole.ErrorWriteLine("Could not find metadata sidecar, not continuing...");
return;
return 3;
}
xs = new XmlSerializer(typeof(Resume));
if(options.ResumeFile != null)
if(File.Exists(options.ResumeFile))
if(resumeFile != null)
if(File.Exists(resumeFile))
try
{
StreamReader sr = new StreamReader(options.ResumeFile);
StreamReader sr = new StreamReader(resumeFile);
resume = (Resume)xs.Deserialize(sr);
sr.Close();
}
catch
{
DicConsole.ErrorWriteLine("Incorrect resume file, not continuing...");
return;
return 4;
}
else
{
DicConsole.ErrorWriteLine("Could not find resume file, not continuing...");
return;
return 5;
}
FiltersList filtersList = new FiltersList();
IFilter inputFilter = filtersList.GetFilter(options.InputFile);
IFilter inputFilter = filtersList.GetFilter(inputFile);
if(inputFilter == null)
{
DicConsole.ErrorWriteLine("Cannot open specified file.");
return;
return 6;
}
if(File.Exists(options.OutputFile))
if(File.Exists(outputFile))
{
DicConsole.ErrorWriteLine("Output file already exists, not continuing.");
return;
return 8;
}
PluginBase plugins = GetPluginBase.Instance;
@@ -151,10 +278,10 @@ namespace DiscImageChef.Commands
if(inputFormat == null)
{
DicConsole.WriteLine("Input image format not identified, not proceeding with conversion.");
return;
return 7;
}
if(options.Verbose)
if(MainClass.Verbose)
DicConsole.VerboseWriteLine("Input image format identified by {0} ({1}).", inputFormat.Name,
inputFormat.Id);
else DicConsole.WriteLine("Input image format identified by {0}.", inputFormat.Name);
@@ -165,7 +292,7 @@ namespace DiscImageChef.Commands
{
DicConsole.WriteLine("Unable to open image format");
DicConsole.WriteLine("No error given");
return;
return 9;
}
DicConsole.DebugWriteLine("Convert-image command", "Correctly opened image file.");
@@ -175,66 +302,65 @@ namespace DiscImageChef.Commands
DicConsole.DebugWriteLine("Convert-image command", "Image identifies media type as {0}.",
inputFormat.Info.MediaType);
Core.Statistics.AddMediaFormat(inputFormat.Format);
Core.Statistics.AddMedia(inputFormat.Info.MediaType, false);
Core.Statistics.AddFilter(inputFilter.Name);
Statistics.AddMediaFormat(inputFormat.Format);
Statistics.AddMedia(inputFormat.Info.MediaType, false);
Statistics.AddFilter(inputFilter.Name);
}
catch(Exception ex)
{
DicConsole.ErrorWriteLine("Unable to open image format");
DicConsole.ErrorWriteLine("Error: {0}", ex.Message);
DicConsole.DebugWriteLine("Convert-image command", "Stack trace: {0}", ex.StackTrace);
return;
return 10;
}
List<IWritableImage> candidates = new List<IWritableImage>();
// Try extension
if(string.IsNullOrEmpty(options.OutputFormat))
if(string.IsNullOrEmpty(wantedOutputFormat))
candidates.AddRange(plugins.WritableImages.Values.Where(t =>
t.KnownExtensions
.Contains(Path.GetExtension(options
.OutputFile))));
.Contains(Path.GetExtension(outputFile))));
// Try Id
else if(Guid.TryParse(options.OutputFormat, out Guid outId))
else if(Guid.TryParse(wantedOutputFormat, out Guid outId))
candidates.AddRange(plugins.WritableImages.Values.Where(t => t.Id.Equals(outId)));
// Try name
else
candidates.AddRange(plugins.WritableImages.Values.Where(t => string.Equals(t.Name, options.OutputFormat,
candidates.AddRange(plugins.WritableImages.Values.Where(t => string.Equals(t.Name, wantedOutputFormat,
StringComparison
.InvariantCultureIgnoreCase)));
if(candidates.Count == 0)
{
DicConsole.WriteLine("No plugin supports requested extension.");
return;
return 11;
}
if(candidates.Count > 1)
{
DicConsole.WriteLine("More than one plugin supports requested extension.");
return;
return 12;
}
IWritableImage outputFormat = candidates[0];
if(options.Verbose)
if(MainClass.Verbose)
DicConsole.VerboseWriteLine("Output image format: {0} ({1}).", outputFormat.Name, outputFormat.Id);
else DicConsole.WriteLine("Output image format: {0}.", outputFormat.Name);
if(!outputFormat.SupportedMediaTypes.Contains(inputFormat.Info.MediaType))
{
DicConsole.ErrorWriteLine("Output format does not support media type, cannot continue...");
return;
return 13;
}
foreach(MediaTagType mediaTag in inputFormat.Info.ReadableMediaTags)
{
if(outputFormat.SupportedMediaTags.Contains(mediaTag) || options.Force) continue;
if(outputFormat.SupportedMediaTags.Contains(mediaTag) || force) continue;
DicConsole.ErrorWriteLine("Converting image will lose media tag {0}, not continuing...", mediaTag);
DicConsole.ErrorWriteLine("If you don't care, use force option.");
return;
return 14;
}
bool useLong = inputFormat.Info.ReadableSectorTags.Count != 0;
@@ -243,7 +369,7 @@ namespace DiscImageChef.Commands
{
if(outputFormat.SupportedSectorTags.Contains(sectorTag)) continue;
if(options.Force)
if(force)
{
if(sectorTag != SectorTagType.CdTrackFlags && sectorTag != SectorTagType.CdTrackIsrc &&
sectorTag != SectorTagType.CdSectorSubchannel) useLong = false;
@@ -253,44 +379,43 @@ namespace DiscImageChef.Commands
DicConsole.ErrorWriteLine("Converting image will lose sector tag {0}, not continuing...", sectorTag);
DicConsole
.ErrorWriteLine("If you don't care, use force option. This will skip all sector tags converting only user data.");
return;
return 15;
}
if(!outputFormat.Create(options.OutputFile, inputFormat.Info.MediaType, parsedOptions,
inputFormat.Info.Sectors, inputFormat.Info.SectorSize))
if(!outputFormat.Create(outputFile, inputFormat.Info.MediaType, parsedOptions, inputFormat.Info.Sectors,
inputFormat.Info.SectorSize))
{
DicConsole.ErrorWriteLine("Error {0} creating output image.", outputFormat.ErrorMessage);
return;
return 16;
}
CommonTypes.Structs.ImageInfo metadata = new CommonTypes.Structs.ImageInfo
ImageInfo metadata = new ImageInfo
{
Application = "DiscImageChef",
ApplicationVersion = Version.GetVersion(),
Comments = options.Comments ?? inputFormat.Info.Comments,
Creator = options.Creator ?? inputFormat.Info.Creator,
DriveFirmwareRevision = options.DriveFirmwareRevision ?? inputFormat.Info.DriveFirmwareRevision,
DriveManufacturer = options.DriveManufacturer ?? inputFormat.Info.DriveManufacturer,
DriveModel = options.DriveModel ?? inputFormat.Info.DriveModel,
DriveSerialNumber = options.DriveSerialNumber ?? inputFormat.Info.DriveSerialNumber,
LastMediaSequence =
options.LastMediaSequence != 0 ? options.LastMediaSequence : inputFormat.Info.LastMediaSequence,
MediaBarcode = options.MediaBarcode ?? inputFormat.Info.MediaBarcode,
MediaManufacturer = options.MediaManufacturer ?? inputFormat.Info.MediaManufacturer,
MediaModel = options.MediaModel ?? inputFormat.Info.MediaModel,
MediaPartNumber = options.MediaPartNumber ?? inputFormat.Info.MediaPartNumber,
MediaSequence = options.MediaSequence != 0 ? options.MediaSequence : inputFormat.Info.MediaSequence,
MediaSerialNumber = options.MediaSerialNumber ?? inputFormat.Info.MediaSerialNumber,
MediaTitle = options.MediaTitle ?? inputFormat.Info.MediaTitle
Comments = comments ?? inputFormat.Info.Comments,
Creator = creator ?? inputFormat.Info.Creator,
DriveFirmwareRevision = driveFirmwareRevision ?? inputFormat.Info.DriveFirmwareRevision,
DriveManufacturer = driveManufacturer ?? inputFormat.Info.DriveManufacturer,
DriveModel = driveModel ?? inputFormat.Info.DriveModel,
DriveSerialNumber = driveSerialNumber ?? inputFormat.Info.DriveSerialNumber,
LastMediaSequence = lastMediaSequence != 0 ? lastMediaSequence : inputFormat.Info.LastMediaSequence,
MediaBarcode = mediaBarcode ?? inputFormat.Info.MediaBarcode,
MediaManufacturer = mediaManufacturer ?? inputFormat.Info.MediaManufacturer,
MediaModel = mediaModel ?? inputFormat.Info.MediaModel,
MediaPartNumber = mediaPartNumber ?? inputFormat.Info.MediaPartNumber,
MediaSequence = mediaSequence != 0 ? mediaSequence : inputFormat.Info.MediaSequence,
MediaSerialNumber = mediaSerialNumber ?? inputFormat.Info.MediaSerialNumber,
MediaTitle = mediaTitle ?? inputFormat.Info.MediaTitle
};
if(!outputFormat.SetMetadata(metadata))
{
DicConsole.ErrorWrite("Error {0} setting metadata, ", outputFormat.ErrorMessage);
if(!options.Force)
if(!force)
{
DicConsole.ErrorWriteLine("not continuing...");
return;
return 17;
}
DicConsole.ErrorWriteLine("continuing...");
@@ -309,24 +434,24 @@ namespace DiscImageChef.Commands
{
DicConsole.ErrorWriteLine("Error {0} sending tracks list to output image.",
outputFormat.ErrorMessage);
return;
return 18;
}
foreach(MediaTagType mediaTag in inputFormat.Info.ReadableMediaTags)
{
if(options.Force && !outputFormat.SupportedMediaTags.Contains(mediaTag)) continue;
if(force && !outputFormat.SupportedMediaTags.Contains(mediaTag)) continue;
DicConsole.WriteLine("Converting media tag {0}", mediaTag);
byte[] tag = inputFormat.ReadDiskTag(mediaTag);
if(outputFormat.WriteMediaTag(tag, mediaTag)) continue;
if(options.Force)
if(force)
DicConsole.ErrorWriteLine("Error {0} writing media tag, continuing...", outputFormat.ErrorMessage);
else
{
DicConsole.ErrorWriteLine("Error {0} writing media tag, not continuing...",
outputFormat.ErrorMessage);
return;
return 19;
}
}
@@ -348,9 +473,10 @@ namespace DiscImageChef.Commands
byte[] sector;
uint sectorsToDo;
if(inputFormat.Info.Sectors - doneSectors >= (ulong)options.Count)
sectorsToDo = (uint)options.Count;
else sectorsToDo = (uint)(inputFormat.Info.Sectors - doneSectors);
if(inputFormat.Info.Sectors - doneSectors >= (ulong)count) sectorsToDo = (uint)count;
else
sectorsToDo =
(uint)(inputFormat.Info.Sectors - doneSectors);
DicConsole.Write("\rConverting sectors {0} to {1} ({2:P2} done)", doneSectors,
doneSectors + sectorsToDo, doneSectors / (double)inputFormat.Info.Sectors);
@@ -382,14 +508,14 @@ namespace DiscImageChef.Commands
}
if(!result)
if(options.Force)
if(force)
DicConsole.ErrorWriteLine("Error {0} writing sector {1}, continuing...",
outputFormat.ErrorMessage, doneSectors);
else
{
DicConsole.ErrorWriteLine("Error {0} writing sector {1}, not continuing...",
outputFormat.ErrorMessage, doneSectors);
return;
return 20;
}
doneSectors += sectorsToDo;
@@ -417,7 +543,7 @@ namespace DiscImageChef.Commands
continue;
}
if(options.Force && !outputFormat.SupportedSectorTags.Contains(tag)) continue;
if(force && !outputFormat.SupportedSectorTags.Contains(tag)) continue;
doneSectors = 0;
while(doneSectors < inputFormat.Info.Sectors)
@@ -425,9 +551,10 @@ namespace DiscImageChef.Commands
byte[] sector;
uint sectorsToDo;
if(inputFormat.Info.Sectors - doneSectors >= (ulong)options.Count)
sectorsToDo = (uint)options.Count;
else sectorsToDo = (uint)(inputFormat.Info.Sectors - doneSectors);
if(inputFormat.Info.Sectors - doneSectors >= (ulong)count) sectorsToDo = (uint)count;
else
sectorsToDo =
(uint)(inputFormat.Info.Sectors - doneSectors);
DicConsole.Write("\rConverting tag {2} for sectors {0} to {1} ({2:P2} done)", doneSectors,
doneSectors + sectorsToDo, doneSectors / (double)inputFormat.Info.Sectors,
@@ -446,14 +573,14 @@ namespace DiscImageChef.Commands
}
if(!result)
if(options.Force)
if(force)
DicConsole.ErrorWriteLine("Error {0} writing sector {1}, continuing...",
outputFormat.ErrorMessage, doneSectors);
else
{
DicConsole.ErrorWriteLine("Error {0} writing sector {1}, not continuing...",
outputFormat.ErrorMessage, doneSectors);
return;
return 21;
}
doneSectors += sectorsToDo;
@@ -476,10 +603,8 @@ namespace DiscImageChef.Commands
byte[] sector;
uint sectorsToDo;
if(trackSectors - doneSectors >= (ulong)options.Count) sectorsToDo = (uint)options.Count;
else
sectorsToDo =
(uint)(trackSectors - doneSectors);
if(trackSectors - doneSectors >= (ulong)count) sectorsToDo = (uint)count;
else sectorsToDo = (uint)(trackSectors - doneSectors);
DicConsole.Write("\rConverting sectors {0} to {1} in track {3} ({2:P2} done)",
doneSectors + track.TrackStartSector,
@@ -516,14 +641,14 @@ namespace DiscImageChef.Commands
}
if(!result)
if(options.Force)
if(force)
DicConsole.ErrorWriteLine("Error {0} writing sector {1}, continuing...",
outputFormat.ErrorMessage, doneSectors);
else
{
DicConsole.ErrorWriteLine("Error {0} writing sector {1}, not continuing...",
outputFormat.ErrorMessage, doneSectors);
return;
return 22;
}
doneSectors += sectorsToDo;
@@ -552,7 +677,7 @@ namespace DiscImageChef.Commands
continue;
}
if(options.Force && !outputFormat.SupportedSectorTags.Contains(tag)) continue;
if(force && !outputFormat.SupportedSectorTags.Contains(tag)) continue;
foreach(Track track in tracks)
{
@@ -570,14 +695,14 @@ namespace DiscImageChef.Commands
sector = inputFormat.ReadSectorTag(track.TrackStartSector, tag);
result = outputFormat.WriteSectorTag(sector, track.TrackStartSector, tag);
if(!result)
if(options.Force)
if(force)
DicConsole.ErrorWriteLine("Error {0} writing tag, continuing...",
outputFormat.ErrorMessage);
else
{
DicConsole.ErrorWriteLine("Error {0} writing tag, not continuing...",
outputFormat.ErrorMessage);
return;
return 23;
}
continue;
@@ -586,7 +711,7 @@ namespace DiscImageChef.Commands
while(doneSectors < trackSectors)
{
uint sectorsToDo;
if(trackSectors - doneSectors >= (ulong)options.Count) sectorsToDo = (uint)options.Count;
if(trackSectors - doneSectors >= (ulong)count) sectorsToDo = (uint)count;
else
sectorsToDo =
(uint)(trackSectors - doneSectors);
@@ -611,14 +736,14 @@ namespace DiscImageChef.Commands
}
if(!result)
if(options.Force)
if(force)
DicConsole.ErrorWriteLine("Error {0} writing tag for sector {1}, continuing...",
outputFormat.ErrorMessage, doneSectors);
else
{
DicConsole.ErrorWriteLine("Error {0} writing tag for sector {1}, not continuing...",
outputFormat.ErrorMessage, doneSectors);
return;
return 24;
}
doneSectors += sectorsToDo;
@@ -668,7 +793,8 @@ namespace DiscImageChef.Commands
DicConsole.WriteLine();
DicConsole.WriteLine("Conversion done.");
Core.Statistics.AddCommand("convert-image");
Statistics.AddCommand("convert-image");
return 0;
}
}
}

View File

@@ -40,14 +40,79 @@ using DiscImageChef.CommonTypes;
using DiscImageChef.CommonTypes.Interfaces;
using DiscImageChef.Console;
using DiscImageChef.Core;
using Mono.Options;
using Schemas;
namespace DiscImageChef.Commands
{
static class CreateSidecar
class CreateSidecarCommand : Command
{
internal static void DoSidecar(CreateSidecarOptions options)
int blockSize;
string encodingName;
string inputFile;
bool showHelp;
bool tape;
public CreateSidecarCommand() : base("create-sidecar", "Creates CICM Metadata XML sidecar.")
{
Options = new OptionSet
{
$"{MainClass.AssemblyTitle} {MainClass.AssemblyVersion?.InformationalVersion}",
$"{MainClass.AssemblyCopyright}",
"",
$"usage: DiscImageChef {Name} [OPTIONS] input",
"",
Help,
{
"block-size|b=",
"Only used for tapes, indicates block size. Files in the folder whose size is not a multiple of this value will simply be ignored.",
(int i) => blockSize = i
},
{"encoding|e=", "Name of character encoding to use.", s => encodingName = s},
{
"tape|t",
"When used indicates that input is a folder containing alphabetically sorted files extracted from a linear block-based tape with fixed block size (e.g. a SCSI tape device).",
b => tape = b != null
},
{"help|h|?", "Show this message and exit.", v => showHelp = v != null}
};
}
public override int Invoke(IEnumerable<string> arguments)
{
List<string> extra = Options.Parse(arguments);
if(showHelp)
{
Options.WriteOptionDescriptions(CommandSet.Out);
return 0;
}
MainClass.PrintCopyright();
if(MainClass.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
if(MainClass.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
if(extra.Count > 1)
{
DicConsole.ErrorWriteLine("Too many arguments.");
return 1;
}
if(extra.Count == 0)
{
DicConsole.ErrorWriteLine("Missing input image.");
return 1;
}
inputFile = extra[0];
DicConsole.DebugWriteLine("Create sidecar command", "--block-size={0}", blockSize);
DicConsole.DebugWriteLine("Create sidecar command", "--debug={0}", MainClass.Debug);
DicConsole.DebugWriteLine("Create sidecar command", "--encoding={0}", encodingName);
DicConsole.DebugWriteLine("Create sidecar command", "--input={0}", inputFile);
DicConsole.DebugWriteLine("Create sidecar command", "--tape={0}", tape);
DicConsole.DebugWriteLine("Create sidecar command", "--verbose={0}", MainClass.Verbose);
Sidecar.InitProgressEvent += Progress.InitProgress;
Sidecar.UpdateProgressEvent += Progress.UpdateProgress;
Sidecar.EndProgressEvent += Progress.EndProgress;
@@ -58,33 +123,33 @@ namespace DiscImageChef.Commands
Encoding encoding = null;
if(options.EncodingName != null)
if(encodingName != null)
try
{
encoding = Claunia.Encoding.Encoding.GetEncoding(options.EncodingName);
if(options.Verbose) DicConsole.VerboseWriteLine("Using encoding for {0}.", encoding.EncodingName);
encoding = Claunia.Encoding.Encoding.GetEncoding(encodingName);
if(MainClass.Verbose) DicConsole.VerboseWriteLine("Using encoding for {0}.", encoding.EncodingName);
}
catch(ArgumentException)
{
DicConsole.ErrorWriteLine("Specified encoding is not supported.");
return;
return 1;
}
if(File.Exists(options.InputFile))
if(File.Exists(inputFile))
{
if(options.Tape)
if(tape)
{
DicConsole.ErrorWriteLine("You cannot use --tape option when input is a file.");
return;
return 2;
}
FiltersList filtersList = new FiltersList();
IFilter inputFilter = filtersList.GetFilter(options.InputFile);
IFilter inputFilter = filtersList.GetFilter(inputFile);
if(inputFilter == null)
{
DicConsole.ErrorWriteLine("Cannot open specified file.");
return;
return 3;
}
try
@@ -94,10 +159,10 @@ namespace DiscImageChef.Commands
if(imageFormat == null)
{
DicConsole.WriteLine("Image format not identified, not proceeding with analysis.");
return;
return 4;
}
if(options.Verbose)
if(MainClass.Verbose)
DicConsole.VerboseWriteLine("Image format identified by {0} ({1}).", imageFormat.Name,
imageFormat.Id);
else DicConsole.WriteLine("Image format identified by {0}.", imageFormat.Name);
@@ -108,7 +173,7 @@ namespace DiscImageChef.Commands
{
DicConsole.WriteLine("Unable to open image format");
DicConsole.WriteLine("No error given");
return;
return 5;
}
DicConsole.DebugWriteLine("Analyze command", "Correctly opened image file.");
@@ -117,26 +182,26 @@ namespace DiscImageChef.Commands
{
DicConsole.ErrorWriteLine("Unable to open image format");
DicConsole.ErrorWriteLine("Error: {0}", ex.Message);
return;
return 6;
}
Core.Statistics.AddMediaFormat(imageFormat.Format);
Core.Statistics.AddFilter(inputFilter.Name);
Statistics.AddMediaFormat(imageFormat.Format);
Statistics.AddFilter(inputFilter.Name);
CICMMetadataType sidecar = Sidecar.Create(imageFormat, options.InputFile, inputFilter.Id, encoding);
CICMMetadataType sidecar = Sidecar.Create(imageFormat, inputFile, inputFilter.Id, encoding);
DicConsole.WriteLine("Writing metadata sidecar");
FileStream xmlFs =
new
FileStream(Path.Combine(Path.GetDirectoryName(options.InputFile) ?? throw new InvalidOperationException(), Path.GetFileNameWithoutExtension(options.InputFile) + ".cicm.xml"),
FileStream(Path.Combine(Path.GetDirectoryName(inputFile) ?? throw new InvalidOperationException(), Path.GetFileNameWithoutExtension(inputFile) + ".cicm.xml"),
FileMode.CreateNew);
XmlSerializer xmlSer = new XmlSerializer(typeof(CICMMetadataType));
xmlSer.Serialize(xmlFs, sidecar);
xmlFs.Close();
Core.Statistics.AddCommand("create-sidecar");
Statistics.AddCommand("create-sidecar");
}
catch(Exception ex)
{
@@ -144,37 +209,37 @@ namespace DiscImageChef.Commands
DicConsole.DebugWriteLine("Analyze command", ex.StackTrace);
}
}
else if(Directory.Exists(options.InputFile))
else if(Directory.Exists(inputFile))
{
if(!options.Tape)
if(!tape)
{
DicConsole.ErrorWriteLine("Cannot create a sidecar from a directory.");
return;
return 7;
}
string[] contents = Directory.GetFiles(options.InputFile, "*", SearchOption.TopDirectoryOnly);
List<string> files = contents.Where(file => new FileInfo(file).Length % options.BlockSize == 0)
.ToList();
string[] contents = Directory.GetFiles(inputFile, "*", SearchOption.TopDirectoryOnly);
List<string> files = contents.Where(file => new FileInfo(file).Length % blockSize == 0).ToList();
files.Sort(StringComparer.CurrentCultureIgnoreCase);
CICMMetadataType sidecar =
Sidecar.Create(Path.GetFileName(options.InputFile), files, options.BlockSize);
CICMMetadataType sidecar = Sidecar.Create(Path.GetFileName(inputFile), files, blockSize);
DicConsole.WriteLine("Writing metadata sidecar");
FileStream xmlFs =
new
FileStream(Path.Combine(Path.GetDirectoryName(options.InputFile) ?? throw new InvalidOperationException(), Path.GetFileNameWithoutExtension(options.InputFile) + ".cicm.xml"),
FileStream(Path.Combine(Path.GetDirectoryName(inputFile) ?? throw new InvalidOperationException(), Path.GetFileNameWithoutExtension(inputFile) + ".cicm.xml"),
FileMode.CreateNew);
XmlSerializer xmlSer = new XmlSerializer(typeof(CICMMetadataType));
xmlSer.Serialize(xmlFs, sidecar);
xmlFs.Close();
Core.Statistics.AddCommand("create-sidecar");
Statistics.AddCommand("create-sidecar");
}
else DicConsole.ErrorWriteLine("The specified input file cannot be found.");
return 0;
}
}
}

View File

@@ -30,6 +30,7 @@
// Copyright © 2011-2019 Natalia Portillo
// ****************************************************************************/
using System.Collections.Generic;
using DiscImageChef.CommonTypes;
using DiscImageChef.CommonTypes.Enums;
using DiscImageChef.CommonTypes.Interfaces;
@@ -38,28 +39,80 @@ using DiscImageChef.Core;
using DiscImageChef.Decoders.ATA;
using DiscImageChef.Decoders.CD;
using DiscImageChef.Decoders.SCSI;
using Mono.Options;
namespace DiscImageChef.Commands
{
static class Decode
class DecodeCommand : Command
{
internal static void DoDecode(DecodeOptions options)
bool diskTags = true;
string inputFile;
string length = "all";
bool sectorTags = true;
bool showHelp;
ulong startSector;
public DecodeCommand() : base("decode", "Decodes and pretty prints disk and/or sector tags.")
{
DicConsole.DebugWriteLine("Decode command", "--debug={0}", options.Debug);
DicConsole.DebugWriteLine("Decode command", "--verbose={0}", options.Verbose);
DicConsole.DebugWriteLine("Decode command", "--input={0}", options.InputFile);
DicConsole.DebugWriteLine("Decode command", "--start={0}", options.StartSector);
DicConsole.DebugWriteLine("Decode command", "--length={0}", options.Length);
DicConsole.DebugWriteLine("Decode command", "--disk-tags={0}", options.DiskTags);
DicConsole.DebugWriteLine("Decode command", "--sector-tags={0}", options.SectorTags);
Options = new OptionSet
{
$"{MainClass.AssemblyTitle} {MainClass.AssemblyVersion?.InformationalVersion}",
$"{MainClass.AssemblyCopyright}",
"",
$"usage: DiscImageChef {Name} [OPTIONS] imagefile",
"",
Help,
{"disk-tags|f", "Decode disk tags.", b => diskTags = b != null},
{"length|l=", "How many sectors to decode, or \"all\".", s => length = s},
{"sector-tags|p", "Decode sector tags.", b => sectorTags = b != null},
{"start|s=", "Name of character encoding to use.", (ulong ul) => startSector = ul},
{"help|h|?", "Show this message and exit.", v => showHelp = v != null}
};
}
public override int Invoke(IEnumerable<string> arguments)
{
List<string> extra = Options.Parse(arguments);
if(showHelp)
{
Options.WriteOptionDescriptions(CommandSet.Out);
return 0;
}
MainClass.PrintCopyright();
if(MainClass.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
if(MainClass.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
if(extra.Count > 1)
{
DicConsole.ErrorWriteLine("Too many arguments.");
return 1;
}
if(extra.Count == 0)
{
DicConsole.ErrorWriteLine("Missing input image.");
return 1;
}
inputFile = extra[0];
DicConsole.DebugWriteLine("Decode command", "--debug={0}", MainClass.Debug);
DicConsole.DebugWriteLine("Decode command", "--disk-tags={0}", diskTags);
DicConsole.DebugWriteLine("Decode command", "--input={0}", inputFile);
DicConsole.DebugWriteLine("Decode command", "--length={0}", length);
DicConsole.DebugWriteLine("Decode command", "--sector-tags={0}", sectorTags);
DicConsole.DebugWriteLine("Decode command", "--start={0}", startSector);
DicConsole.DebugWriteLine("Decode command", "--verbose={0}", MainClass.Verbose);
FiltersList filtersList = new FiltersList();
IFilter inputFilter = filtersList.GetFilter(options.InputFile);
IFilter inputFilter = filtersList.GetFilter(inputFile);
if(inputFilter == null)
{
DicConsole.ErrorWriteLine("Cannot open specified file.");
return;
return 1;
}
IMediaImage inputFormat = ImageFormat.Detect(inputFilter);
@@ -67,15 +120,15 @@ namespace DiscImageChef.Commands
if(inputFormat == null)
{
DicConsole.ErrorWriteLine("Unable to recognize image format, not decoding");
return;
return 2;
}
inputFormat.Open(inputFilter);
Core.Statistics.AddMediaFormat(inputFormat.Format);
Core.Statistics.AddMedia(inputFormat.Info.MediaType, false);
Core.Statistics.AddFilter(inputFilter.Name);
Statistics.AddMediaFormat(inputFormat.Format);
Statistics.AddMedia(inputFormat.Info.MediaType, false);
Statistics.AddFilter(inputFilter.Name);
if(options.DiskTags)
if(diskTags)
if(inputFormat.Info.ReadableMediaTags.Count == 0)
DicConsole.WriteLine("There are no disk tags in chosen disc image.");
else
@@ -237,16 +290,16 @@ namespace DiscImageChef.Commands
break;
}
if(options.SectorTags)
if(sectorTags)
{
if(options.Length.ToLowerInvariant() == "all") { }
if(length.ToLowerInvariant() == "all") { }
else
{
if(!ulong.TryParse(options.Length, out ulong _))
if(!ulong.TryParse(length, out ulong _))
{
DicConsole.WriteLine("Value \"{0}\" is not a valid number for length.", options.Length);
DicConsole.WriteLine("Value \"{0}\" is not a valid number for length.", length);
DicConsole.WriteLine("Not decoding sectors tags");
return;
return 3;
}
}
@@ -265,7 +318,8 @@ namespace DiscImageChef.Commands
// TODO: Not implemented
}
Core.Statistics.AddCommand("decode");
Statistics.AddCommand("decode");
return 0;
}
}
}

View File

@@ -40,31 +40,78 @@ using DiscImageChef.Decoders.SCSI;
using DiscImageChef.Decoders.SCSI.MMC;
using DiscImageChef.Decoders.SCSI.SSC;
using DiscImageChef.Devices;
using Mono.Options;
using DeviceInfo = DiscImageChef.Core.Devices.Info.DeviceInfo;
namespace DiscImageChef.Commands
{
static class DeviceInfo
class DeviceInfoCommand : Command
{
internal static void DoDeviceInfo(DeviceInfoOptions options)
string devicePath;
string outputPrefix;
bool showHelp;
public DeviceInfoCommand() : base("device-info", "Gets information about a device.")
{
DicConsole.DebugWriteLine("Device-Info command", "--debug={0}", options.Debug);
DicConsole.DebugWriteLine("Device-Info command", "--verbose={0}", options.Verbose);
DicConsole.DebugWriteLine("Device-Info command", "--device={0}", options.DevicePath);
DicConsole.DebugWriteLine("Device-Info command", "--output-prefix={0}", options.OutputPrefix);
Options = new OptionSet
{
$"{MainClass.AssemblyTitle} {MainClass.AssemblyVersion?.InformationalVersion}",
$"{MainClass.AssemblyCopyright}",
"",
$"usage: DiscImageChef {Name} [OPTIONS] devicepath",
"",
Help,
{"output-prefix|w=", "Name of character encoding to use.", s => outputPrefix = s},
{"help|h|?", "Show this message and exit.", v => showHelp = v != null}
};
}
if(options.DevicePath.Length == 2 && options.DevicePath[1] == ':' && options.DevicePath[0] != '/' &&
char.IsLetter(options.DevicePath[0]))
options.DevicePath = "\\\\.\\" + char.ToUpper(options.DevicePath[0]) + ':';
public override int Invoke(IEnumerable<string> arguments)
{
List<string> extra = Options.Parse(arguments);
Device dev = new Device(options.DevicePath);
if(showHelp)
{
Options.WriteOptionDescriptions(CommandSet.Out);
return 0;
}
MainClass.PrintCopyright();
if(MainClass.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
if(MainClass.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
if(extra.Count > 1)
{
DicConsole.ErrorWriteLine("Too many arguments.");
return 1;
}
if(extra.Count == 0)
{
DicConsole.ErrorWriteLine("Missing device path.");
return 1;
}
devicePath = extra[0];
DicConsole.DebugWriteLine("Device-Info command", "--debug={0}", MainClass.Debug);
DicConsole.DebugWriteLine("Device-Info command", "--device={0}", devicePath);
DicConsole.DebugWriteLine("Device-Info command", "--output-prefix={0}", outputPrefix);
DicConsole.DebugWriteLine("Device-Info command", "--verbose={0}", MainClass.Verbose);
if(devicePath.Length == 2 && devicePath[1] == ':' && devicePath[0] != '/' && char.IsLetter(devicePath[0]))
devicePath = "\\\\.\\" + char.ToUpper(devicePath[0]) + ':';
Device dev = new Device(devicePath);
if(dev.Error)
{
DicConsole.ErrorWriteLine("Error {0} opening device.", dev.LastError);
return;
return 1;
}
Core.Statistics.AddDevice(dev);
Statistics.AddDevice(dev);
if(dev.IsUsb)
{
@@ -156,11 +203,11 @@ namespace DiscImageChef.Commands
else DicConsole.DebugWriteLine("Device-Info command", "Could not get tuples");
}
Core.Devices.Info.DeviceInfo devInfo = new Core.Devices.Info.DeviceInfo(dev);
DeviceInfo devInfo = new DeviceInfo(dev);
if(devInfo.AtaIdentify != null)
{
DataFile.WriteTo("Device-Info command", options.OutputPrefix, "_ata_identify.bin", "ATA IDENTIFY",
DataFile.WriteTo("Device-Info command", outputPrefix, "_ata_identify.bin", "ATA IDENTIFY",
devInfo.AtaIdentify);
DicConsole.WriteLine(Identify.Prettify(devInfo.AtaIdentify));
@@ -202,7 +249,7 @@ namespace DiscImageChef.Commands
if(devInfo.AtapiIdentify != null)
{
DataFile.WriteTo("Device-Info command", options.OutputPrefix, "_atapi_identify.bin", "ATAPI IDENTIFY",
DataFile.WriteTo("Device-Info command", outputPrefix, "_atapi_identify.bin", "ATAPI IDENTIFY",
devInfo.AtapiIdentify);
DicConsole.WriteLine(Identify.Prettify(devInfo.AtapiIdentify));
@@ -212,7 +259,7 @@ namespace DiscImageChef.Commands
{
if(dev.Type != DeviceType.ATAPI) DicConsole.WriteLine("SCSI device");
DataFile.WriteTo("Device-Info command", options.OutputPrefix, "_scsi_inquiry.bin", "SCSI INQUIRY",
DataFile.WriteTo("Device-Info command", outputPrefix, "_scsi_inquiry.bin", "SCSI INQUIRY",
devInfo.ScsiInquiryData);
DicConsole.WriteLine(Inquiry.Prettify(devInfo.ScsiInquiry));
@@ -223,147 +270,129 @@ namespace DiscImageChef.Commands
{
DicConsole.WriteLine("ASCII Page {0:X2}h: {1}", page.Key, EVPD.DecodeASCIIPage(page.Value));
DataFile.WriteTo("Device-Info command", options.OutputPrefix, page.Value);
DataFile.WriteTo("Device-Info command", outputPrefix, page.Value);
}
else if(page.Key == 0x80)
{
DicConsole.WriteLine("Unit Serial Number: {0}", EVPD.DecodePage80(page.Value));
DataFile.WriteTo("Device-Info command", options.OutputPrefix,
$"_scsi_evpd_{page.Key:X2}h.bin", $"SCSI INQUIRY EVPD {page.Key:X2}h",
page.Value);
DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin",
$"SCSI INQUIRY EVPD {page.Key:X2}h", page.Value);
}
else if(page.Key == 0x81)
{
DicConsole.WriteLine("{0}", EVPD.PrettifyPage_81(page.Value));
DataFile.WriteTo("Device-Info command", options.OutputPrefix,
$"_scsi_evpd_{page.Key:X2}h.bin", $"SCSI INQUIRY EVPD {page.Key:X2}h",
page.Value);
DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin",
$"SCSI INQUIRY EVPD {page.Key:X2}h", page.Value);
}
else if(page.Key == 0x82)
{
DicConsole.WriteLine("ASCII implemented operating definitions: {0}",
EVPD.DecodePage82(page.Value));
DataFile.WriteTo("Device-Info command", options.OutputPrefix,
$"_scsi_evpd_{page.Key:X2}h.bin", $"SCSI INQUIRY EVPD {page.Key:X2}h",
page.Value);
DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin",
$"SCSI INQUIRY EVPD {page.Key:X2}h", page.Value);
}
else if(page.Key == 0x83)
{
DicConsole.WriteLine("{0}", EVPD.PrettifyPage_83(page.Value));
DataFile.WriteTo("Device-Info command", options.OutputPrefix,
$"_scsi_evpd_{page.Key:X2}h.bin", $"SCSI INQUIRY EVPD {page.Key:X2}h",
page.Value);
DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin",
$"SCSI INQUIRY EVPD {page.Key:X2}h", page.Value);
}
else if(page.Key == 0x84)
{
DicConsole.WriteLine("{0}", EVPD.PrettifyPage_84(page.Value));
DataFile.WriteTo("Device-Info command", options.OutputPrefix,
$"_scsi_evpd_{page.Key:X2}h.bin", $"SCSI INQUIRY EVPD {page.Key:X2}h",
page.Value);
DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin",
$"SCSI INQUIRY EVPD {page.Key:X2}h", page.Value);
}
else if(page.Key == 0x85)
{
DicConsole.WriteLine("{0}", EVPD.PrettifyPage_85(page.Value));
DataFile.WriteTo("Device-Info command", options.OutputPrefix,
$"_scsi_evpd_{page.Key:X2}h.bin", $"SCSI INQUIRY EVPD {page.Key:X2}h",
page.Value);
DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin",
$"SCSI INQUIRY EVPD {page.Key:X2}h", page.Value);
}
else if(page.Key == 0x86)
{
DicConsole.WriteLine("{0}", EVPD.PrettifyPage_86(page.Value));
DataFile.WriteTo("Device-Info command", options.OutputPrefix,
$"_scsi_evpd_{page.Key:X2}h.bin", $"SCSI INQUIRY EVPD {page.Key:X2}h",
page.Value);
DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin",
$"SCSI INQUIRY EVPD {page.Key:X2}h", page.Value);
}
else if(page.Key == 0x89)
{
DicConsole.WriteLine("{0}", EVPD.PrettifyPage_89(page.Value));
DataFile.WriteTo("Device-Info command", options.OutputPrefix,
$"_scsi_evpd_{page.Key:X2}h.bin", $"SCSI INQUIRY EVPD {page.Key:X2}h",
page.Value);
DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin",
$"SCSI INQUIRY EVPD {page.Key:X2}h", page.Value);
}
else if(page.Key == 0xB0)
{
DicConsole.WriteLine("{0}", EVPD.PrettifyPage_B0(page.Value));
DataFile.WriteTo("Device-Info command", options.OutputPrefix,
$"_scsi_evpd_{page.Key:X2}h.bin", $"SCSI INQUIRY EVPD {page.Key:X2}h",
page.Value);
DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin",
$"SCSI INQUIRY EVPD {page.Key:X2}h", page.Value);
}
else if(page.Key == 0xB1)
{
DicConsole.WriteLine("Manufacturer-assigned Serial Number: {0}",
EVPD.DecodePageB1(page.Value));
DataFile.WriteTo("Device-Info command", options.OutputPrefix,
$"_scsi_evpd_{page.Key:X2}h.bin", $"SCSI INQUIRY EVPD {page.Key:X2}h",
page.Value);
DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin",
$"SCSI INQUIRY EVPD {page.Key:X2}h", page.Value);
}
else if(page.Key == 0xB2)
{
DicConsole.WriteLine("TapeAlert Supported Flags Bitmap: 0x{0:X16}",
EVPD.DecodePageB2(page.Value));
DataFile.WriteTo("Device-Info command", options.OutputPrefix,
$"_scsi_evpd_{page.Key:X2}h.bin", $"SCSI INQUIRY EVPD {page.Key:X2}h",
page.Value);
DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin",
$"SCSI INQUIRY EVPD {page.Key:X2}h", page.Value);
}
else if(page.Key == 0xB3)
{
DicConsole.WriteLine("Automation Device Serial Number: {0}", EVPD.DecodePageB3(page.Value));
DataFile.WriteTo("Device-Info command", options.OutputPrefix,
$"_scsi_evpd_{page.Key:X2}h.bin", $"SCSI INQUIRY EVPD {page.Key:X2}h",
page.Value);
DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin",
$"SCSI INQUIRY EVPD {page.Key:X2}h", page.Value);
}
else if(page.Key == 0xB4)
{
DicConsole.WriteLine("Data Transfer Device Element Address: 0x{0}",
EVPD.DecodePageB4(page.Value));
DataFile.WriteTo("Device-Info command", options.OutputPrefix,
$"_scsi_evpd_{page.Key:X2}h.bin", $"SCSI INQUIRY EVPD {page.Key:X2}h",
page.Value);
DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin",
$"SCSI INQUIRY EVPD {page.Key:X2}h", page.Value);
}
else if(page.Key == 0xC0 &&
StringHandlers.CToString(devInfo.ScsiInquiry.Value.VendorIdentification)
.ToLowerInvariant().Trim() == "quantum")
{
DicConsole.WriteLine("{0}", EVPD.PrettifyPage_C0_Quantum(page.Value));
DataFile.WriteTo("Device-Info command", options.OutputPrefix,
$"_scsi_evpd_{page.Key:X2}h.bin", $"SCSI INQUIRY EVPD {page.Key:X2}h",
page.Value);
DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin",
$"SCSI INQUIRY EVPD {page.Key:X2}h", page.Value);
}
else if(page.Key == 0xC0 &&
StringHandlers.CToString(devInfo.ScsiInquiry.Value.VendorIdentification)
.ToLowerInvariant().Trim() == "seagate")
{
DicConsole.WriteLine("{0}", EVPD.PrettifyPage_C0_Seagate(page.Value));
DataFile.WriteTo("Device-Info command", options.OutputPrefix,
$"_scsi_evpd_{page.Key:X2}h.bin", $"SCSI INQUIRY EVPD {page.Key:X2}h",
page.Value);
DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin",
$"SCSI INQUIRY EVPD {page.Key:X2}h", page.Value);
}
else if(page.Key == 0xC0 &&
StringHandlers.CToString(devInfo.ScsiInquiry.Value.VendorIdentification)
.ToLowerInvariant().Trim() == "ibm")
{
DicConsole.WriteLine("{0}", EVPD.PrettifyPage_C0_IBM(page.Value));
DataFile.WriteTo("Device-Info command", options.OutputPrefix,
$"_scsi_evpd_{page.Key:X2}h.bin", $"SCSI INQUIRY EVPD {page.Key:X2}h",
page.Value);
DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin",
$"SCSI INQUIRY EVPD {page.Key:X2}h", page.Value);
}
else if(page.Key == 0xC1 &&
StringHandlers.CToString(devInfo.ScsiInquiry.Value.VendorIdentification)
.ToLowerInvariant().Trim() == "ibm")
{
DicConsole.WriteLine("{0}", EVPD.PrettifyPage_C1_IBM(page.Value));
DataFile.WriteTo("Device-Info command", options.OutputPrefix,
$"_scsi_evpd_{page.Key:X2}h.bin", $"SCSI INQUIRY EVPD {page.Key:X2}h",
page.Value);
DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin",
$"SCSI INQUIRY EVPD {page.Key:X2}h", page.Value);
}
else if((page.Key == 0xC0 || page.Key == 0xC1) &&
StringHandlers.CToString(devInfo.ScsiInquiry.Value.VendorIdentification)
.ToLowerInvariant().Trim() == "certance")
{
DicConsole.WriteLine("{0}", EVPD.PrettifyPage_C0_C1_Certance(page.Value));
DataFile.WriteTo("Device-Info command", options.OutputPrefix,
$"_scsi_evpd_{page.Key:X2}h.bin", $"SCSI INQUIRY EVPD {page.Key:X2}h",
page.Value);
DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin",
$"SCSI INQUIRY EVPD {page.Key:X2}h", page.Value);
}
else if((page.Key == 0xC2 || page.Key == 0xC3 || page.Key == 0xC4 || page.Key == 0xC5 ||
page.Key == 0xC6) &&
@@ -371,9 +400,8 @@ namespace DiscImageChef.Commands
.ToLowerInvariant().Trim() == "certance")
{
DicConsole.WriteLine("{0}", EVPD.PrettifyPage_C2_C3_C4_C5_C6_Certance(page.Value));
DataFile.WriteTo("Device-Info command", options.OutputPrefix,
$"_scsi_evpd_{page.Key:X2}h.bin", $"SCSI INQUIRY EVPD {page.Key:X2}h",
page.Value);
DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin",
$"SCSI INQUIRY EVPD {page.Key:X2}h", page.Value);
}
else if((page.Key == 0xC0 || page.Key == 0xC1 || page.Key == 0xC2 || page.Key == 0xC3 ||
page.Key == 0xC4 || page.Key == 0xC5) && StringHandlers
@@ -382,18 +410,16 @@ namespace DiscImageChef.Commands
.ToLowerInvariant().Trim() == "hp")
{
DicConsole.WriteLine("{0}", EVPD.PrettifyPage_C0_to_C5_HP(page.Value));
DataFile.WriteTo("Device-Info command", options.OutputPrefix,
$"_scsi_evpd_{page.Key:X2}h.bin", $"SCSI INQUIRY EVPD {page.Key:X2}h",
page.Value);
DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin",
$"SCSI INQUIRY EVPD {page.Key:X2}h", page.Value);
}
else if(page.Key == 0xDF &&
StringHandlers.CToString(devInfo.ScsiInquiry.Value.VendorIdentification)
.ToLowerInvariant().Trim() == "certance")
{
DicConsole.WriteLine("{0}", EVPD.PrettifyPage_DF_Certance(page.Value));
DataFile.WriteTo("Device-Info command", options.OutputPrefix,
$"_scsi_evpd_{page.Key:X2}h.bin", $"SCSI INQUIRY EVPD {page.Key:X2}h",
page.Value);
DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin",
$"SCSI INQUIRY EVPD {page.Key:X2}h", page.Value);
}
else
{
@@ -402,18 +428,17 @@ namespace DiscImageChef.Commands
DicConsole.DebugWriteLine("Device-Info command", "Found undecoded SCSI VPD page 0x{0:X2}",
page.Key);
DataFile.WriteTo("Device-Info command", options.OutputPrefix,
$"_scsi_evpd_{page.Key:X2}h.bin", $"SCSI INQUIRY EVPD {page.Key:X2}h",
page.Value);
DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin",
$"SCSI INQUIRY EVPD {page.Key:X2}h", page.Value);
}
if(devInfo.ScsiModeSense6 != null)
DataFile.WriteTo("Device-Info command", options.OutputPrefix, "_scsi_modesense6.bin",
"SCSI MODE SENSE", devInfo.ScsiModeSense6);
DataFile.WriteTo("Device-Info command", outputPrefix, "_scsi_modesense6.bin", "SCSI MODE SENSE",
devInfo.ScsiModeSense6);
if(devInfo.ScsiModeSense10 != null)
DataFile.WriteTo("Device-Info command", options.OutputPrefix, "_scsi_modesense10.bin",
"SCSI MODE SENSE", devInfo.ScsiModeSense10);
DataFile.WriteTo("Device-Info command", outputPrefix, "_scsi_modesense10.bin", "SCSI MODE SENSE",
devInfo.ScsiModeSense10);
if(devInfo.ScsiMode.HasValue)
PrintScsiModePages.Print(devInfo.ScsiMode.Value,
@@ -422,7 +447,7 @@ namespace DiscImageChef.Commands
if(devInfo.MmcConfiguration != null)
{
DataFile.WriteTo("Device-Info command", options.OutputPrefix, "_mmc_getconfiguration.bin",
DataFile.WriteTo("Device-Info command", outputPrefix, "_mmc_getconfiguration.bin",
"MMC GET CONFIGURATION", devInfo.MmcConfiguration);
Features.SeparatedFeatures ftr = Features.Separate(devInfo.MmcConfiguration);
@@ -629,7 +654,7 @@ namespace DiscImageChef.Commands
{
if(devInfo.PlextorFeatures.Eeprom != null)
{
DataFile.WriteTo("Device-Info command", options.OutputPrefix, "_plextor_eeprom.bin",
DataFile.WriteTo("Device-Info command", outputPrefix, "_plextor_eeprom.bin",
"PLEXTOR READ EEPROM", devInfo.PlextorFeatures.Eeprom);
DicConsole.WriteLine("Drive has loaded a total of {0} discs", devInfo.PlextorFeatures.Discs);
@@ -772,7 +797,7 @@ namespace DiscImageChef.Commands
if(devInfo.BlockLimits != null)
{
DataFile.WriteTo("Device-Info command", options.OutputPrefix, "_ssc_readblocklimits.bin",
DataFile.WriteTo("Device-Info command", outputPrefix, "_ssc_readblocklimits.bin",
"SSC READ BLOCK LIMITS", devInfo.BlockLimits);
DicConsole.WriteLine("Block limits for device:");
DicConsole.WriteLine(BlockLimits.Prettify(devInfo.BlockLimits));
@@ -780,7 +805,7 @@ namespace DiscImageChef.Commands
if(devInfo.DensitySupport != null)
{
DataFile.WriteTo("Device-Info command", options.OutputPrefix, "_ssc_reportdensitysupport.bin",
DataFile.WriteTo("Device-Info command", outputPrefix, "_ssc_reportdensitysupport.bin",
"SSC REPORT DENSITY SUPPORT", devInfo.DensitySupport);
if(devInfo.DensitySupportHeader.HasValue)
{
@@ -791,9 +816,8 @@ namespace DiscImageChef.Commands
if(devInfo.MediumDensitySupport != null)
{
DataFile.WriteTo("Device-Info command", options.OutputPrefix,
"_ssc_reportdensitysupport_medium.bin", "SSC REPORT DENSITY SUPPORT (MEDIUM)",
devInfo.MediumDensitySupport);
DataFile.WriteTo("Device-Info command", outputPrefix, "_ssc_reportdensitysupport_medium.bin",
"SSC REPORT DENSITY SUPPORT (MEDIUM)", devInfo.MediumDensitySupport);
if(devInfo.MediaTypeSupportHeader.HasValue)
{
DicConsole.WriteLine("Medium types supported by device:");
@@ -813,32 +837,29 @@ namespace DiscImageChef.Commands
if(devInfo.CID != null)
{
noInfo = false;
DataFile.WriteTo("Device-Info command", options.OutputPrefix, "_mmc_cid.bin", "MMC CID",
devInfo.CID);
DataFile.WriteTo("Device-Info command", outputPrefix, "_mmc_cid.bin", "MMC CID", devInfo.CID);
DicConsole.WriteLine("{0}", Decoders.MMC.Decoders.PrettifyCID(devInfo.CID));
}
if(devInfo.CSD != null)
{
noInfo = false;
DataFile.WriteTo("Device-Info command", options.OutputPrefix, "_mmc_csd.bin", "MMC CSD",
devInfo.CSD);
DataFile.WriteTo("Device-Info command", outputPrefix, "_mmc_csd.bin", "MMC CSD", devInfo.CSD);
DicConsole.WriteLine("{0}", Decoders.MMC.Decoders.PrettifyCSD(devInfo.CSD));
}
if(devInfo.OCR != null)
{
noInfo = false;
DataFile.WriteTo("Device-Info command", options.OutputPrefix, "_mmc_ocr.bin", "MMC OCR",
devInfo.OCR);
DataFile.WriteTo("Device-Info command", outputPrefix, "_mmc_ocr.bin", "MMC OCR", devInfo.OCR);
DicConsole.WriteLine("{0}", Decoders.MMC.Decoders.PrettifyOCR(devInfo.OCR));
}
if(devInfo.ExtendedCSD != null)
{
noInfo = false;
DataFile.WriteTo("Device-Info command", options.OutputPrefix, "_mmc_ecsd.bin",
"MMC Extended CSD", devInfo.ExtendedCSD);
DataFile.WriteTo("Device-Info command", outputPrefix, "_mmc_ecsd.bin", "MMC Extended CSD",
devInfo.ExtendedCSD);
DicConsole.WriteLine("{0}", Decoders.MMC.Decoders.PrettifyExtendedCSD(devInfo.ExtendedCSD));
}
@@ -852,32 +873,32 @@ namespace DiscImageChef.Commands
if(devInfo.CID != null)
{
noInfo = false;
DataFile.WriteTo("Device-Info command", options.OutputPrefix, "_sd_cid.bin",
"SecureDigital CID", devInfo.CID);
DataFile.WriteTo("Device-Info command", outputPrefix, "_sd_cid.bin", "SecureDigital CID",
devInfo.CID);
DicConsole.WriteLine("{0}", Decoders.SecureDigital.Decoders.PrettifyCID(devInfo.CID));
}
if(devInfo.CSD != null)
{
noInfo = false;
DataFile.WriteTo("Device-Info command", options.OutputPrefix, "_sd_csd.bin",
"SecureDigital CSD", devInfo.CSD);
DataFile.WriteTo("Device-Info command", outputPrefix, "_sd_csd.bin", "SecureDigital CSD",
devInfo.CSD);
DicConsole.WriteLine("{0}", Decoders.SecureDigital.Decoders.PrettifyCSD(devInfo.CSD));
}
if(devInfo.OCR != null)
{
noInfo = false;
DataFile.WriteTo("Device-Info command", options.OutputPrefix, "_sd_ocr.bin",
"SecureDigital OCR", devInfo.OCR);
DataFile.WriteTo("Device-Info command", outputPrefix, "_sd_ocr.bin", "SecureDigital OCR",
devInfo.OCR);
DicConsole.WriteLine("{0}", Decoders.SecureDigital.Decoders.PrettifyOCR(devInfo.OCR));
}
if(devInfo.SCR != null)
{
noInfo = false;
DataFile.WriteTo("Device-Info command", options.OutputPrefix, "_sd_scr.bin",
"SecureDigital SCR", devInfo.SCR);
DataFile.WriteTo("Device-Info command", outputPrefix, "_sd_scr.bin", "SecureDigital SCR",
devInfo.SCR);
DicConsole.WriteLine("{0}", Decoders.SecureDigital.Decoders.PrettifySCR(devInfo.SCR));
}
@@ -886,9 +907,11 @@ namespace DiscImageChef.Commands
break;
}
Core.Statistics.AddCommand("device-info");
Statistics.AddCommand("device-info");
dev.Close();
return 0;
}
}
}

View File

@@ -43,40 +43,87 @@ using DiscImageChef.Database;
using DiscImageChef.Database.Models;
using DiscImageChef.Decoders.ATA;
using DiscImageChef.Decoders.SCSI;
using Mono.Options;
using Newtonsoft.Json;
using Command = Mono.Options.Command;
using Device = DiscImageChef.Devices.Device;
using DeviceReport = DiscImageChef.Core.Devices.Report.DeviceReport;
namespace DiscImageChef.Commands
{
static class DeviceReport
class DeviceReportCommand : Command
{
internal static void DoDeviceReport(DeviceReportOptions options)
string devicePath;
bool showHelp;
public DeviceReportCommand() : base("device-report",
"Tests the device capabilities and creates an JSON report of them.")
{
DicConsole.DebugWriteLine("Device-Report command", "--debug={0}", options.Debug);
DicConsole.DebugWriteLine("Device-Report command", "--verbose={0}", options.Verbose);
DicConsole.DebugWriteLine("Device-Report command", "--device={0}", options.DevicePath);
Options = new OptionSet
{
$"{MainClass.AssemblyTitle} {MainClass.AssemblyVersion?.InformationalVersion}",
$"{MainClass.AssemblyCopyright}",
"",
$"usage: DiscImageChef {Name} devicepath",
"",
Help,
{"help|h|?", "Show this message and exit.", v => showHelp = v != null}
};
}
public override int Invoke(IEnumerable<string> arguments)
{
List<string> extra = Options.Parse(arguments);
if(showHelp)
{
Options.WriteOptionDescriptions(CommandSet.Out);
return 0;
}
MainClass.PrintCopyright();
if(MainClass.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
if(MainClass.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
if(extra.Count > 1)
{
DicConsole.ErrorWriteLine("Too many arguments.");
return 1;
}
if(extra.Count == 0)
{
DicConsole.ErrorWriteLine("Missing device path.");
return 1;
}
devicePath = extra[0];
DicConsole.DebugWriteLine("Device-Report command", "--debug={0}", MainClass.Debug);
DicConsole.DebugWriteLine("Device-Report command", "--device={0}", devicePath);
DicConsole.DebugWriteLine("Device-Report command", "--verbose={0}", MainClass.Verbose);
if(!DetectOS.IsAdmin)
{
DicConsole
.ErrorWriteLine("Because of the commands sent to a device, device report must be run with administrative privileges.");
DicConsole.ErrorWriteLine("Not continuing.");
return;
return 1;
}
if(options.DevicePath.Length == 2 && options.DevicePath[1] == ':' && options.DevicePath[0] != '/' &&
char.IsLetter(options.DevicePath[0]))
options.DevicePath = "\\\\.\\" + char.ToUpper(options.DevicePath[0]) + ':';
if(devicePath.Length == 2 && devicePath[1] == ':' && devicePath[0] != '/' && char.IsLetter(devicePath[0]))
devicePath = "\\\\.\\" + char.ToUpper(devicePath[0]) + ':';
Device dev = new Device(options.DevicePath);
Device dev = new Device(devicePath);
if(dev.Error)
{
DicConsole.ErrorWriteLine("Error {0} opening device.", dev.LastError);
return;
return 2;
}
Core.Statistics.AddDevice(dev);
Statistics.AddDevice(dev);
DeviceReportV2 report = new DeviceReportV2
{
@@ -94,7 +141,7 @@ namespace DiscImageChef.Commands
jsonFile = jsonFile.Replace('\\', '_').Replace('/', '_').Replace('?', '_');
Core.Devices.Report.DeviceReport reporter = new Core.Devices.Report.DeviceReport(dev, options.Debug);
DeviceReport reporter = new DeviceReport(dev, MainClass.Debug);
ConsoleKeyInfo pressedKey;
@@ -248,7 +295,7 @@ namespace DiscImageChef.Commands
dev.AtapiIdentify(out buffer, out _, dev.Timeout, out _);
if(!Identify.Decode(buffer).HasValue) return;
if(!Identify.Decode(buffer).HasValue) return 3;
report.ATAPI = new Ata {Identify = buffer};
@@ -448,7 +495,7 @@ namespace DiscImageChef.Commands
tryPioneer |= dev.Manufacturer.ToLowerInvariant() == "pioneer";
tryNec |= dev.Manufacturer.ToLowerInvariant() == "nec";
if(options.Debug)
if(MainClass.Debug)
{
if(!tryPlextor)
{
@@ -614,7 +661,7 @@ namespace DiscImageChef.Commands
dev.Timeout, out _);
if(!sense)
{
if(options.Debug) mediaTest.ReadLong10Data = buffer;
if(MainClass.Debug) mediaTest.ReadLong10Data = buffer;
mediaTest.LongBlockSize = i;
break;
@@ -627,8 +674,8 @@ namespace DiscImageChef.Commands
}
}
if(options.Debug && mediaTest.SupportsReadLong == true &&
mediaTest.LongBlockSize != mediaTest.BlockSize)
if(MainClass.Debug && mediaTest.SupportsReadLong == true &&
mediaTest.LongBlockSize != mediaTest.BlockSize)
{
sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0,
(ushort)mediaTest.LongBlockSize, dev.Timeout, out _);
@@ -844,8 +891,8 @@ namespace DiscImageChef.Commands
}
}
if(options.Debug && mediaTest.SupportsReadLong == true &&
mediaTest.LongBlockSize != mediaTest.BlockSize)
if(MainClass.Debug && mediaTest.SupportsReadLong == true &&
mediaTest.LongBlockSize != mediaTest.BlockSize)
{
sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0,
(ushort)mediaTest.LongBlockSize, dev.Timeout, out _);
@@ -889,7 +936,8 @@ namespace DiscImageChef.Commands
dev.Timeout, out _);
if(!sense)
{
if(options.Debug) report.SCSI.ReadCapabilities.ReadLong10Data = buffer;
if(MainClass.Debug)
report.SCSI.ReadCapabilities.ReadLong10Data = buffer;
report.SCSI.ReadCapabilities.LongBlockSize = i;
break;
@@ -902,7 +950,7 @@ namespace DiscImageChef.Commands
}
}
if(options.Debug && report.SCSI.ReadCapabilities.SupportsReadLong == true &&
if(MainClass.Debug && report.SCSI.ReadCapabilities.SupportsReadLong == true &&
report.SCSI.ReadCapabilities.LongBlockSize !=
report.SCSI.ReadCapabilities.BlockSize)
{
@@ -931,7 +979,7 @@ namespace DiscImageChef.Commands
jsonSw.Close();
jsonFs.Close();
Core.Statistics.AddCommand("device-report");
Statistics.AddCommand("device-report");
using(DicContext ctx = DicContext.Create(Settings.Settings.LocalDbPath))
{
@@ -941,6 +989,7 @@ namespace DiscImageChef.Commands
// TODO:
if(Settings.Settings.Current.ShareReports) Remote.SubmitReport(report);
return 0;
}
}
}

View File

@@ -45,16 +45,111 @@ using DiscImageChef.Core;
using DiscImageChef.Core.Devices.Dumping;
using DiscImageChef.Core.Logging;
using DiscImageChef.Devices;
using Mono.Options;
using Schemas;
using Ata = DiscImageChef.Core.Devices.Dumping.Ata;
using Scsi = DiscImageChef.Core.Devices.Dumping.Scsi;
namespace DiscImageChef.Commands
{
static class DumpMedia
class DumpMediaCommand : Command
{
internal static void DoDumpMedia(DumpMediaOptions options)
string cicmXml;
string devicePath;
bool doResume = true;
string encodingName;
bool firstTrackPregap;
bool force;
bool noMetadata;
bool noTrim;
string outputFile;
string outputOptions;
bool persistent;
// TODO: Disabled temporarily
bool raw = false;
ushort retryPasses = 5;
bool showHelp;
int skip = 512;
bool stopOnError;
string wanteOutputFormat;
public DumpMediaCommand() : base("dump-media", "Dumps the media inserted on a device to a media image.")
{
Options = new OptionSet
{
$"{MainClass.AssemblyTitle} {MainClass.AssemblyVersion?.InformationalVersion}",
$"{MainClass.AssemblyCopyright}",
"",
$"usage: DiscImageChef {Name} [OPTIONS] devicepath outputimage",
"",
Help,
{"cicm-xml|x=", "Take metadata from existing CICM XML sidecar.", s => cicmXml = s},
{"encoding|e=", "Name of character encoding to use.", s => encodingName = s},
{
"first-pregap", "Try to read first track pregap. Only applicable to CD/DDCD/GD.",
b => firstTrackPregap = b != null
},
{"force|f", "Continue dump whatever happens.", b => force = b != null},
{
"format|t=",
"Format of the output image, as plugin name or plugin id. If not present, will try to detect it from output image extension.",
s => wanteOutputFormat = s
},
{"no-metadata", "Disables creating CICM XML sidecar.", b => noMetadata = b != null},
{"no-trim", "Disables trimming errored from skipped sectors.", b => noTrim = b != null},
{
"options|O=", "Comma separated name=value pairs of options to pass to output image plugin.",
s => outputOptions = s
},
{"persistent", "Try to recover partial or incorrect data.", b => persistent = b != null},
/* TODO: Disabled temporarily
{ "raw|r", "Dump sectors with tags included. For optical media, dump scrambled sectors.", (b) => Raw = b != null}, */
{
"resume|r", "Create/use resume mapfile.",
b => doResume = b != null
},
{"retry-passes|p=", "How many retry passes to do.", (ushort us) => retryPasses = us},
{"skip|k=", "When an unreadable sector is found skip this many sectors.", (int i) => skip = i},
{
"stop-on-error|s", "Stop media dump on first error.",
b => stopOnError = b != null
},
{
"help|h|?", "Show this message and exit.",
v => showHelp = v != null
}
};
}
public override int Invoke(IEnumerable<string> arguments)
{
List<string> extra = Options.Parse(arguments);
if(showHelp)
{
Options.WriteOptionDescriptions(CommandSet.Out);
return 0;
}
MainClass.PrintCopyright();
if(MainClass.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
if(MainClass.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
if(extra.Count > 2)
{
DicConsole.ErrorWriteLine("Too many arguments.");
return 1;
}
if(extra.Count <= 1)
{
DicConsole.ErrorWriteLine("Missing paths.");
return 1;
}
devicePath = extra[0];
outputFile = extra[1];
// TODO: Be able to cancel hashing
Sidecar.InitProgressEvent += Progress.InitProgress;
Sidecar.UpdateProgressEvent += Progress.UpdateProgress;
@@ -64,65 +159,64 @@ namespace DiscImageChef.Commands
Sidecar.EndProgressEvent2 += Progress.EndProgress2;
Sidecar.UpdateStatusEvent += Progress.UpdateStatus;
DicConsole.DebugWriteLine("Dump-Media command", "--debug={0}", options.Debug);
DicConsole.DebugWriteLine("Dump-Media command", "--verbose={0}", options.Verbose);
DicConsole.DebugWriteLine("Dump-Media command", "--device={0}", options.DevicePath);
DicConsole.DebugWriteLine("Dump-Media command", "--cicm-xml={0}", cicmXml);
DicConsole.DebugWriteLine("Dump-Media command", "--debug={0}", MainClass.Debug);
DicConsole.DebugWriteLine("Dump-Media command", "--device={0}", devicePath);
DicConsole.DebugWriteLine("Dump-Media command", "--encoding={0}", encodingName);
DicConsole.DebugWriteLine("Dump-Media command", "--first-pregap={0}", firstTrackPregap);
DicConsole.DebugWriteLine("Dump-Media command", "--force={0}", force);
DicConsole.DebugWriteLine("Dump-Media command", "--force={0}", force);
DicConsole.DebugWriteLine("Dump-Media command", "--format={0}", wanteOutputFormat);
DicConsole.DebugWriteLine("Dump-Media command", "--no-metadata={0}", noMetadata);
DicConsole.DebugWriteLine("Dump-Media command", "--options={0}", Options);
DicConsole.DebugWriteLine("Dump-Media command", "--output={0}", outputFile);
DicConsole.DebugWriteLine("Dump-Media command", "--persistent={0}", persistent);
// TODO: Disabled temporarily
//DicConsole.DebugWriteLine("Dump-Media command", "--raw={0}", options.Raw);
DicConsole.DebugWriteLine("Dump-Media command", "--stop-on-error={0}", options.StopOnError);
DicConsole.DebugWriteLine("Dump-Media command", "--force={0}", options.Force);
DicConsole.DebugWriteLine("Dump-Media command", "--retry-passes={0}", options.RetryPasses);
DicConsole.DebugWriteLine("Dump-Media command", "--persistent={0}", options.Persistent);
DicConsole.DebugWriteLine("Dump-Media command", "--resume={0}", options.Resume);
DicConsole.DebugWriteLine("Dump-Media command", "--first-pregap={0}", options.FirstTrackPregap);
DicConsole.DebugWriteLine("Dump-Media command", "--encoding={0}", options.EncodingName);
DicConsole.DebugWriteLine("Dump-Media command", "--output={0}", options.OutputFile);
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);
DicConsole.DebugWriteLine("Dump-Media command", "--skip={0}", options.Skip);
DicConsole.DebugWriteLine("Dump-Media command", "--no-metadata={0}", options.NoMetadata);
//DicConsole.DebugWriteLine("Dump-Media command", "--raw={0}", raw);
DicConsole.DebugWriteLine("Dump-Media command", "--resume={0}", doResume);
DicConsole.DebugWriteLine("Dump-Media command", "--retry-passes={0}", retryPasses);
DicConsole.DebugWriteLine("Dump-Media command", "--skip={0}", skip);
DicConsole.DebugWriteLine("Dump-Media command", "--stop-on-error={0}", stopOnError);
DicConsole.DebugWriteLine("Dump-Media command", "--verbose={0}", MainClass.Verbose);
Dictionary<string, string> parsedOptions = Options.Parse(options.Options);
Dictionary<string, string> parsedOptions = Core.Options.Parse(outputOptions);
DicConsole.DebugWriteLine("Dump-Media command", "Parsed options:");
foreach(KeyValuePair<string, string> parsedOption in parsedOptions)
DicConsole.DebugWriteLine("Dump-Media command", "{0} = {1}", parsedOption.Key, parsedOption.Value);
Encoding encoding = null;
if(options.EncodingName != null)
if(encodingName != null)
try
{
encoding = Claunia.Encoding.Encoding.GetEncoding(options.EncodingName);
if(options.Verbose) DicConsole.VerboseWriteLine("Using encoding for {0}.", encoding.EncodingName);
encoding = Claunia.Encoding.Encoding.GetEncoding(encodingName);
if(MainClass.Verbose) DicConsole.VerboseWriteLine("Using encoding for {0}.", encoding.EncodingName);
}
catch(ArgumentException)
{
DicConsole.ErrorWriteLine("Specified encoding is not supported.");
return;
return 1;
}
if(options.DevicePath.Length == 2 && options.DevicePath[1] == ':' && options.DevicePath[0] != '/' &&
char.IsLetter(options.DevicePath[0]))
options.DevicePath = "\\\\.\\" + char.ToUpper(options.DevicePath[0]) + ':';
if(devicePath.Length == 2 && devicePath[1] == ':' && devicePath[0] != '/' && char.IsLetter(devicePath[0]))
devicePath = "\\\\.\\" + char.ToUpper(devicePath[0]) + ':';
Device dev = new Device(options.DevicePath);
Device dev = new Device(devicePath);
if(dev.Error)
{
DicConsole.ErrorWriteLine("Error {0} opening device.", dev.LastError);
return;
return 2;
}
Core.Statistics.AddDevice(dev);
Statistics.AddDevice(dev);
string outputPrefix = Path.Combine(Path.GetDirectoryName(options.OutputFile),
Path.GetFileNameWithoutExtension(options.OutputFile));
string outputPrefix = Path.Combine(Path.GetDirectoryName(outputFile),
Path.GetFileNameWithoutExtension(outputFile));
Resume resume = null;
XmlSerializer xs = new XmlSerializer(typeof(Resume));
if(File.Exists(outputPrefix + ".resume.xml") && options.Resume)
if(File.Exists(outputPrefix + ".resume.xml") && doResume)
try
{
StreamReader sr = new StreamReader(outputPrefix + ".resume.xml");
@@ -132,71 +226,70 @@ namespace DiscImageChef.Commands
catch
{
DicConsole.ErrorWriteLine("Incorrect resume file, not continuing...");
return;
return 3;
}
if(resume != null && resume.NextBlock > resume.LastBlock && resume.BadBlocks.Count == 0)
{
DicConsole.WriteLine("Media already dumped correctly, not continuing...");
return;
return 4;
}
CICMMetadataType sidecar = null;
XmlSerializer sidecarXs = new XmlSerializer(typeof(CICMMetadataType));
if(options.CicmXml != null)
if(File.Exists(options.CicmXml))
if(cicmXml != null)
if(File.Exists(cicmXml))
try
{
StreamReader sr = new StreamReader(options.CicmXml);
StreamReader sr = new StreamReader(cicmXml);
sidecar = (CICMMetadataType)sidecarXs.Deserialize(sr);
sr.Close();
}
catch
{
DicConsole.ErrorWriteLine("Incorrect metadata sidecar file, not continuing...");
return;
return 5;
}
else
{
DicConsole.ErrorWriteLine("Could not find metadata sidecar, not continuing...");
return;
return 6;
}
PluginBase plugins = GetPluginBase.Instance;
List<IWritableImage> candidates = new List<IWritableImage>();
// Try extension
if(string.IsNullOrEmpty(options.OutputFormat))
if(string.IsNullOrEmpty(wanteOutputFormat))
candidates.AddRange(plugins.WritableImages.Values.Where(t =>
t.KnownExtensions
.Contains(Path.GetExtension(options
.OutputFile))));
.Contains(Path.GetExtension(outputFile))));
// Try Id
else if(Guid.TryParse(options.OutputFormat, out Guid outId))
else if(Guid.TryParse(wanteOutputFormat, out Guid outId))
candidates.AddRange(plugins.WritableImages.Values.Where(t => t.Id.Equals(outId)));
// Try name
else
candidates.AddRange(plugins.WritableImages.Values.Where(t => string.Equals(t.Name, options.OutputFormat,
candidates.AddRange(plugins.WritableImages.Values.Where(t => string.Equals(t.Name, wanteOutputFormat,
StringComparison
.InvariantCultureIgnoreCase)));
if(candidates.Count == 0)
{
DicConsole.WriteLine("No plugin supports requested extension.");
return;
return 7;
}
if(candidates.Count > 1)
{
DicConsole.WriteLine("More than one plugin supports requested extension.");
return;
return 8;
}
IWritableImage outputFormat = candidates[0];
DumpLog dumpLog = new DumpLog(outputPrefix + ".log", dev);
if(options.Verbose)
if(MainClass.Verbose)
{
dumpLog.WriteLine("Output image format: {0} ({1}).", outputFormat.Name, outputFormat.Id);
DicConsole.VerboseWriteLine("Output image format: {0} ({1}).", outputFormat.Name, outputFormat.Id);
@@ -209,41 +302,33 @@ namespace DiscImageChef.Commands
if(dev.IsUsb && dev.UsbVendorId == 0x054C &&
(dev.UsbProductId == 0x01C8 || dev.UsbProductId == 0x01C9 || dev.UsbProductId == 0x02D2))
PlayStationPortable.Dump(dev, options.DevicePath, outputFormat, options.RetryPasses, options.Force,
options.Persistent, options.StopOnError, ref resume, ref dumpLog, encoding,
outputPrefix, options.OutputFile, parsedOptions, sidecar, (uint)options.Skip,
options.NoMetadata, options.NoTrim);
PlayStationPortable.Dump(dev, devicePath, outputFormat, retryPasses, force, persistent, stopOnError,
ref resume, ref dumpLog, encoding, outputPrefix, outputFile, parsedOptions,
sidecar, (uint)skip, noMetadata, noTrim);
else
switch(dev.Type)
{
case DeviceType.ATA:
Ata.Dump(dev, options.DevicePath, outputFormat, options.RetryPasses, options.Force,
false, /*options.Raw,*/
options.Persistent, options.StopOnError, ref resume, ref dumpLog, encoding,
outputPrefix, options.OutputFile, parsedOptions, sidecar, (uint)options.Skip,
options.NoMetadata, options.NoTrim);
Ata.Dump(dev, devicePath, outputFormat, retryPasses, force, false, /*raw,*/
persistent, stopOnError, ref resume, ref dumpLog, encoding, outputPrefix, outputFile,
parsedOptions, sidecar, (uint)skip, noMetadata, noTrim);
break;
case DeviceType.MMC:
case DeviceType.SecureDigital:
SecureDigital.Dump(dev, options.DevicePath, outputFormat, options.RetryPasses, options.Force,
false, /*options.Raw,*/ options.Persistent, options.StopOnError, ref resume,
ref dumpLog, encoding, outputPrefix, options.OutputFile, parsedOptions,
sidecar, (uint)options.Skip, options.NoMetadata, options.NoTrim);
SecureDigital.Dump(dev, devicePath, outputFormat, retryPasses, force, false, /*raw,*/
persistent, stopOnError, ref resume, ref dumpLog, encoding, outputPrefix,
outputFile, parsedOptions, sidecar, (uint)skip, noMetadata, noTrim);
break;
case DeviceType.NVMe:
NvMe.Dump(dev, options.DevicePath, outputFormat, options.RetryPasses, options.Force,
false, /*options.Raw,*/
options.Persistent, options.StopOnError, ref resume, ref dumpLog, encoding,
outputPrefix, options.OutputFile, parsedOptions, sidecar, (uint)options.Skip,
options.NoMetadata, options.NoTrim);
NvMe.Dump(dev, devicePath, outputFormat, retryPasses, force, false, /*raw,*/
persistent, stopOnError, ref resume, ref dumpLog, encoding, outputPrefix, outputFile,
parsedOptions, sidecar, (uint)skip, noMetadata, noTrim);
break;
case DeviceType.ATAPI:
case DeviceType.SCSI:
Scsi.Dump(dev, options.DevicePath, outputFormat, options.RetryPasses, options.Force,
false, /*options.Raw,*/
options.Persistent, options.StopOnError, ref resume, ref dumpLog,
options.FirstTrackPregap, encoding, outputPrefix, options.OutputFile, parsedOptions,
sidecar, (uint)options.Skip, options.NoMetadata, options.NoTrim);
Scsi.Dump(dev, devicePath, outputFormat, retryPasses, force, false, /*raw,*/
persistent, stopOnError, ref resume, ref dumpLog, firstTrackPregap, encoding,
outputPrefix, outputFile, parsedOptions, sidecar, (uint)skip, noMetadata, noTrim);
break;
default:
dumpLog.WriteLine("Unknown device type.");
@@ -251,7 +336,7 @@ namespace DiscImageChef.Commands
throw new NotSupportedException("Unknown device type.");
}
if(resume != null && options.Resume)
if(resume != null && doResume)
{
resume.LastWriteDate = DateTime.UtcNow;
resume.BadBlocks.Sort();
@@ -266,9 +351,10 @@ namespace DiscImageChef.Commands
dumpLog.Close();
Core.Statistics.AddCommand("dump-media");
Statistics.AddCommand("dump-media");
dev.Close();
return 0;
}
}
}

View File

@@ -30,31 +30,90 @@
// Copyright © 2011-2019 Natalia Portillo
// ****************************************************************************/
using System.Collections.Generic;
using DiscImageChef.CommonTypes;
using DiscImageChef.CommonTypes.Interfaces;
using DiscImageChef.Console;
using DiscImageChef.Core;
using Mono.Options;
namespace DiscImageChef.Commands
{
static class Entropy
class EntropyCommand : Command
{
internal static void DoEntropy(EntropyOptions options)
bool duplicatedSectors = true;
string inputFile;
bool separatedTracks = true;
bool showHelp;
bool wholeDisc = true;
public EntropyCommand() : base("entropy", "Calculates entropy and/or duplicated sectors of an image.")
{
DicConsole.DebugWriteLine("Entropy command", "--debug={0}", options.Debug);
DicConsole.DebugWriteLine("Entropy command", "--verbose={0}", options.Verbose);
DicConsole.DebugWriteLine("Entropy command", "--separated-tracks={0}", options.SeparatedTracks);
DicConsole.DebugWriteLine("Entropy command", "--whole-disc={0}", options.WholeDisc);
DicConsole.DebugWriteLine("Entropy command", "--input={0}", options.InputFile);
DicConsole.DebugWriteLine("Entropy command", "--duplicated-sectors={0}", options.DuplicatedSectors);
Options = new OptionSet
{
$"{MainClass.AssemblyTitle} {MainClass.AssemblyVersion?.InformationalVersion}",
$"{MainClass.AssemblyCopyright}",
"",
$"usage: DiscImageChef {Name} [OPTIONS] imagefile",
"",
Help,
{
"duplicated-sectors|p",
"Calculates how many sectors are duplicated (have same exact data in user area).",
b => duplicatedSectors = b != null
},
{
"separated-tracks|t", "Calculates entropy for each track separately.",
b => separatedTracks = b != null
},
{"whole-disc|w", "Calculates entropy for the whole disc.", b => wholeDisc = b != null},
{"help|h|?", "Show this message and exit.", v => showHelp = v != null}
};
}
public override int Invoke(IEnumerable<string> arguments)
{
List<string> extra = Options.Parse(arguments);
if(showHelp)
{
Options.WriteOptionDescriptions(CommandSet.Out);
return 0;
}
MainClass.PrintCopyright();
if(MainClass.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
if(MainClass.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
if(extra.Count > 1)
{
DicConsole.ErrorWriteLine("Too many arguments.");
return 1;
}
if(extra.Count == 0)
{
DicConsole.ErrorWriteLine("Missing input image.");
return 1;
}
inputFile = extra[0];
DicConsole.DebugWriteLine("Entropy command", "--debug={0}", MainClass.Debug);
DicConsole.DebugWriteLine("Entropy command", "--duplicated-sectors={0}", duplicatedSectors);
DicConsole.DebugWriteLine("Entropy command", "--input={0}", inputFile);
DicConsole.DebugWriteLine("Entropy command", "--separated-tracks={0}", separatedTracks);
DicConsole.DebugWriteLine("Entropy command", "--verbose={0}", MainClass.Verbose);
DicConsole.DebugWriteLine("Entropy command", "--whole-disc={0}", wholeDisc);
FiltersList filtersList = new FiltersList();
IFilter inputFilter = filtersList.GetFilter(options.InputFile);
IFilter inputFilter = filtersList.GetFilter(inputFile);
if(inputFilter == null)
{
DicConsole.ErrorWriteLine("Cannot open specified file.");
return;
return 1;
}
IMediaImage inputFormat = ImageFormat.Detect(inputFilter);
@@ -62,15 +121,15 @@ namespace DiscImageChef.Commands
if(inputFormat == null)
{
DicConsole.ErrorWriteLine("Unable to recognize image format, not checksumming");
return;
return 2;
}
inputFormat.Open(inputFilter);
Core.Statistics.AddMediaFormat(inputFormat.Format);
Core.Statistics.AddMedia(inputFormat.Info.MediaType, false);
Core.Statistics.AddFilter(inputFilter.Name);
Statistics.AddMediaFormat(inputFormat.Format);
Statistics.AddMedia(inputFormat.Info.MediaType, false);
Statistics.AddFilter(inputFilter.Name);
Core.Entropy entropyCalculator = new Core.Entropy(options.Debug, options.Verbose, inputFormat);
Entropy entropyCalculator = new Entropy(MainClass.Debug, MainClass.Verbose, inputFormat);
entropyCalculator.InitProgressEvent += Progress.InitProgress;
entropyCalculator.InitProgress2Event += Progress.InitProgress2;
entropyCalculator.UpdateProgressEvent += Progress.UpdateProgress;
@@ -78,9 +137,9 @@ namespace DiscImageChef.Commands
entropyCalculator.EndProgressEvent += Progress.EndProgress;
entropyCalculator.EndProgress2Event += Progress.EndProgress2;
if(options.SeparatedTracks)
if(separatedTracks)
{
EntropyResults[] tracksEntropy = entropyCalculator.CalculateTracksEntropy(options.DuplicatedSectors);
EntropyResults[] tracksEntropy = entropyCalculator.CalculateTracksEntropy(duplicatedSectors);
foreach(EntropyResults trackEntropy in tracksEntropy)
{
DicConsole.WriteLine("Entropy for track {0} is {1:F4}.", trackEntropy.Track, trackEntropy.Entropy);
@@ -91,20 +150,21 @@ namespace DiscImageChef.Commands
}
}
if(!options.WholeDisc)
if(!wholeDisc)
{
Core.Statistics.AddCommand("entropy");
return;
Statistics.AddCommand("entropy");
return 0;
}
EntropyResults entropy = entropyCalculator.CalculateMediaEntropy(options.DuplicatedSectors);
EntropyResults entropy = entropyCalculator.CalculateMediaEntropy(duplicatedSectors);
DicConsole.WriteLine("Entropy for disk is {0:F4}.", entropy.Entropy);
if(entropy.UniqueSectors != null)
DicConsole.WriteLine("Disk has {0} unique sectors ({1:P3})", entropy.UniqueSectors,
(double)entropy.UniqueSectors / (double)entropy.Sectors);
Core.Statistics.AddCommand("entropy");
Statistics.AddCommand("entropy");
return 0;
}
}
}

View File

@@ -39,47 +39,106 @@ using DiscImageChef.CommonTypes.Interfaces;
using DiscImageChef.CommonTypes.Structs;
using DiscImageChef.Console;
using DiscImageChef.Core;
using Mono.Options;
namespace DiscImageChef.Commands
{
// TODO: Rewrite this, has an insane amount of repeating code ;)
static class ExtractFiles
class ExtractFilesCommand : Command
{
internal static void DoExtractFiles(ExtractFilesOptions options)
string encodingName;
bool extractXattrs;
string inputFile;
string outputDir;
string pluginOptions;
bool showHelp;
public ExtractFilesCommand() : base("extract-files", "Extracts all files in disc image.")
{
DicConsole.DebugWriteLine("Extract-Files command", "--debug={0}", options.Debug);
DicConsole.DebugWriteLine("Extract-Files command", "--verbose={0}", options.Verbose);
DicConsole.DebugWriteLine("Extract-Files command", "--input={0}", options.InputFile);
DicConsole.DebugWriteLine("Extract-Files command", "--xattrs={0}", options.Xattrs);
DicConsole.DebugWriteLine("Extract-Files command", "--output={0}", options.OutputDir);
Options = new OptionSet
{
$"{MainClass.AssemblyTitle} {MainClass.AssemblyVersion?.InformationalVersion}",
$"{MainClass.AssemblyCopyright}",
"",
$"usage: DiscImageChef {Name} [OPTIONS] imagefile",
"",
Help,
{"encoding|e=", "Name of character encoding to use.", s => encodingName = s},
{
"options|O=", "Comma separated name=value pairs of options to pass to filesystem plugin.",
s => pluginOptions = s
},
{
"output|o=", "Directory where extracted files will be created. Will abort if it exists.",
s => outputDir = s
},
{"xattrs|x", "Extract extended attributes if present.", b => extractXattrs = b != null},
{"help|h|?", "Show this message and exit.", v => showHelp = v != null}
};
}
public override int Invoke(IEnumerable<string> arguments)
{
List<string> extra = Options.Parse(arguments);
if(showHelp)
{
Options.WriteOptionDescriptions(CommandSet.Out);
return 0;
}
MainClass.PrintCopyright();
if(MainClass.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
if(MainClass.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
if(extra.Count > 1)
{
DicConsole.ErrorWriteLine("Too many arguments.");
return 1;
}
if(extra.Count == 0)
{
DicConsole.ErrorWriteLine("Missing input image.");
return 1;
}
inputFile = extra[0];
DicConsole.DebugWriteLine("Extract-Files command", "--debug={0}", MainClass.Debug);
DicConsole.DebugWriteLine("Extract-Files command", "--encoding={0}", encodingName);
DicConsole.DebugWriteLine("Extract-Files command", "--input={0}", inputFile);
DicConsole.DebugWriteLine("Extract-Files command", "--options={0}", pluginOptions);
DicConsole.DebugWriteLine("Extract-Files command", "--output={0}", outputDir);
DicConsole.DebugWriteLine("Extract-Files command", "--verbose={0}", MainClass.Verbose);
DicConsole.DebugWriteLine("Extract-Files command", "--xattrs={0}", extractXattrs);
FiltersList filtersList = new FiltersList();
IFilter inputFilter = filtersList.GetFilter(options.InputFile);
IFilter inputFilter = filtersList.GetFilter(inputFile);
Dictionary<string, string> parsedOptions = Options.Parse(options.Options);
Dictionary<string, string> parsedOptions = Core.Options.Parse(pluginOptions);
DicConsole.DebugWriteLine("Extract-Files command", "Parsed options:");
foreach(KeyValuePair<string, string> parsedOption in parsedOptions)
DicConsole.DebugWriteLine("Extract-Files command", "{0} = {1}", parsedOption.Key, parsedOption.Value);
parsedOptions.Add("debug", options.Debug.ToString());
parsedOptions.Add("debug", MainClass.Debug.ToString());
if(inputFilter == null)
{
DicConsole.ErrorWriteLine("Cannot open specified file.");
return;
return 0;
}
Encoding encoding = null;
if(options.EncodingName != null)
if(encodingName != null)
try
{
encoding = Claunia.Encoding.Encoding.GetEncoding(options.EncodingName);
if(options.Verbose) DicConsole.VerboseWriteLine("Using encoding for {0}.", encoding.EncodingName);
encoding = Claunia.Encoding.Encoding.GetEncoding(encodingName);
if(MainClass.Verbose) DicConsole.VerboseWriteLine("Using encoding for {0}.", encoding.EncodingName);
}
catch(ArgumentException)
{
DicConsole.ErrorWriteLine("Specified encoding is not supported.");
return;
return 1;
}
PluginBase plugins = GetPluginBase.Instance;
@@ -91,21 +150,21 @@ namespace DiscImageChef.Commands
if(imageFormat == null)
{
DicConsole.WriteLine("Image format not identified, not proceeding with analysis.");
return;
return 2;
}
if(options.Verbose)
if(MainClass.Verbose)
DicConsole.VerboseWriteLine("Image format identified by {0} ({1}).", imageFormat.Name,
imageFormat.Id);
else DicConsole.WriteLine("Image format identified by {0}.", imageFormat.Name);
if(Directory.Exists(options.OutputDir) || File.Exists(options.OutputDir))
if(Directory.Exists(outputDir) || File.Exists(outputDir))
{
DicConsole.ErrorWriteLine("Destination exists, aborting.");
return;
return 3;
}
Directory.CreateDirectory(options.OutputDir);
Directory.CreateDirectory(outputDir);
try
{
@@ -113,7 +172,7 @@ namespace DiscImageChef.Commands
{
DicConsole.WriteLine("Unable to open image format");
DicConsole.WriteLine("No error given");
return;
return 4;
}
DicConsole.DebugWriteLine("Extract-Files command", "Correctly opened image file.");
@@ -124,15 +183,15 @@ namespace DiscImageChef.Commands
DicConsole.DebugWriteLine("Extract-Files command", "Image identifies disk type as {0}.",
imageFormat.Info.MediaType);
Core.Statistics.AddMediaFormat(imageFormat.Format);
Core.Statistics.AddMedia(imageFormat.Info.MediaType, false);
Core.Statistics.AddFilter(inputFilter.Name);
Statistics.AddMediaFormat(imageFormat.Format);
Statistics.AddMedia(imageFormat.Info.MediaType, false);
Statistics.AddFilter(inputFilter.Name);
}
catch(Exception ex)
{
DicConsole.ErrorWriteLine("Unable to open image format");
DicConsole.ErrorWriteLine("Error: {0}", ex.Message);
return;
return 5;
}
List<Partition> partitions = Core.Partitions.GetAll(imageFormat);
@@ -185,7 +244,7 @@ namespace DiscImageChef.Commands
{
string outputPath;
FileStream outputFile;
if(options.Xattrs)
if(extractXattrs)
{
error = fs.ListXAttr(entry, out List<string> xattrs);
if(error == Errno.NoError)
@@ -195,14 +254,15 @@ namespace DiscImageChef.Commands
error = fs.GetXattr(entry, xattr, ref xattrBuf);
if(error != Errno.NoError) continue;
Directory
.CreateDirectory(Path.Combine(options.OutputDir,
fs.XmlFsType.Type,
volumeName, ".xattrs",
xattr));
Directory.CreateDirectory(Path.Combine(outputDir,
fs.XmlFsType
.Type,
volumeName,
".xattrs",
xattr));
outputPath =
Path.Combine(options.OutputDir, fs.XmlFsType.Type,
Path.Combine(outputDir, fs.XmlFsType.Type,
volumeName, ".xattrs", xattr, entry);
if(!File.Exists(outputPath))
@@ -245,13 +305,11 @@ namespace DiscImageChef.Commands
}
}
Directory.CreateDirectory(Path.Combine(options.OutputDir,
fs.XmlFsType.Type,
Directory.CreateDirectory(Path.Combine(outputDir, fs.XmlFsType.Type,
volumeName));
outputPath =
Path.Combine(options.OutputDir, fs.XmlFsType.Type, volumeName,
entry);
Path.Combine(outputDir, fs.XmlFsType.Type, volumeName, entry);
if(!File.Exists(outputPath))
{
@@ -304,7 +362,7 @@ namespace DiscImageChef.Commands
DicConsole.ErrorWriteLine("Error {0} reading root directory {0}",
error.ToString());
Core.Statistics.AddFilesystem(fs.XmlFsType.Type);
Statistics.AddFilesystem(fs.XmlFsType.Type);
}
else
DicConsole.ErrorWriteLine("Unable to mount device, error {0}",
@@ -335,7 +393,7 @@ namespace DiscImageChef.Commands
{
FileStream outputFile;
string outputPath;
if(options.Xattrs)
if(extractXattrs)
{
error = fs.ListXAttr(entry, out List<string> xattrs);
if(error == Errno.NoError)
@@ -345,14 +403,14 @@ namespace DiscImageChef.Commands
error = fs.GetXattr(entry, xattr, ref xattrBuf);
if(error != Errno.NoError) continue;
Directory.CreateDirectory(Path.Combine(options.OutputDir,
Directory.CreateDirectory(Path.Combine(outputDir,
fs.XmlFsType.Type,
volumeName, ".xattrs",
xattr));
outputPath =
Path.Combine(options.OutputDir, fs.XmlFsType.Type,
volumeName, ".xattrs", xattr, entry);
Path.Combine(outputDir, fs.XmlFsType.Type, volumeName,
".xattrs", xattr, entry);
if(!File.Exists(outputPath))
{
@@ -392,11 +450,10 @@ namespace DiscImageChef.Commands
}
}
Directory.CreateDirectory(Path.Combine(options.OutputDir, fs.XmlFsType.Type,
Directory.CreateDirectory(Path.Combine(outputDir, fs.XmlFsType.Type,
volumeName));
outputPath =
Path.Combine(options.OutputDir, fs.XmlFsType.Type, volumeName, entry);
outputPath = Path.Combine(outputDir, fs.XmlFsType.Type, volumeName, entry);
if(!File.Exists(outputPath))
{
@@ -447,7 +504,7 @@ namespace DiscImageChef.Commands
else
DicConsole.ErrorWriteLine("Error {0} reading root directory {0}", error.ToString());
Core.Statistics.AddFilesystem(fs.XmlFsType.Type);
Statistics.AddFilesystem(fs.XmlFsType.Type);
}
else DicConsole.ErrorWriteLine("Unable to mount device, error {0}", error.ToString());
}
@@ -491,7 +548,7 @@ namespace DiscImageChef.Commands
{
FileStream outputFile;
string outputPath;
if(options.Xattrs)
if(extractXattrs)
{
error = fs.ListXAttr(entry, out List<string> xattrs);
if(error == Errno.NoError)
@@ -501,14 +558,14 @@ namespace DiscImageChef.Commands
error = fs.GetXattr(entry, xattr, ref xattrBuf);
if(error != Errno.NoError) continue;
Directory.CreateDirectory(Path.Combine(options.OutputDir,
Directory.CreateDirectory(Path.Combine(outputDir,
fs.XmlFsType.Type,
volumeName, ".xattrs",
xattr));
outputPath =
Path.Combine(options.OutputDir, fs.XmlFsType.Type,
volumeName, ".xattrs", xattr, entry);
Path.Combine(outputDir, fs.XmlFsType.Type, volumeName,
".xattrs", xattr, entry);
if(!File.Exists(outputPath))
{
@@ -548,11 +605,10 @@ namespace DiscImageChef.Commands
}
}
Directory.CreateDirectory(Path.Combine(options.OutputDir, fs.XmlFsType.Type,
Directory.CreateDirectory(Path.Combine(outputDir, fs.XmlFsType.Type,
volumeName));
outputPath =
Path.Combine(options.OutputDir, fs.XmlFsType.Type, volumeName, entry);
outputPath = Path.Combine(outputDir, fs.XmlFsType.Type, volumeName, entry);
if(!File.Exists(outputPath))
{
@@ -603,7 +659,7 @@ namespace DiscImageChef.Commands
else
DicConsole.ErrorWriteLine("Error {0} reading root directory {0}", error.ToString());
Core.Statistics.AddFilesystem(fs.XmlFsType.Type);
Statistics.AddFilesystem(fs.XmlFsType.Type);
}
else DicConsole.ErrorWriteLine("Unable to mount device, error {0}", error.ToString());
}
@@ -630,7 +686,7 @@ namespace DiscImageChef.Commands
{
string outputPath;
FileStream outputFile;
if(options.Xattrs)
if(extractXattrs)
{
error = fs.ListXAttr(entry, out List<string> xattrs);
if(error == Errno.NoError)
@@ -640,13 +696,12 @@ namespace DiscImageChef.Commands
error = fs.GetXattr(entry, xattr, ref xattrBuf);
if(error != Errno.NoError) continue;
Directory.CreateDirectory(Path.Combine(options.OutputDir,
fs.XmlFsType.Type, volumeName,
".xattrs", xattr));
Directory.CreateDirectory(Path.Combine(outputDir, fs.XmlFsType.Type,
volumeName, ".xattrs", xattr));
outputPath =
Path.Combine(options.OutputDir, fs.XmlFsType.Type, volumeName,
".xattrs", xattr, entry);
Path.Combine(outputDir, fs.XmlFsType.Type, volumeName, ".xattrs",
xattr, entry);
if(!File.Exists(outputPath))
{
@@ -686,10 +741,9 @@ namespace DiscImageChef.Commands
}
}
Directory.CreateDirectory(Path.Combine(options.OutputDir, fs.XmlFsType.Type,
volumeName));
Directory.CreateDirectory(Path.Combine(outputDir, fs.XmlFsType.Type, volumeName));
outputPath = Path.Combine(options.OutputDir, fs.XmlFsType.Type, volumeName, entry);
outputPath = Path.Combine(outputDir, fs.XmlFsType.Type, volumeName, entry);
if(!File.Exists(outputPath))
{
@@ -734,7 +788,7 @@ namespace DiscImageChef.Commands
}
else DicConsole.ErrorWriteLine("Error {0} reading root directory {0}", error.ToString());
Core.Statistics.AddFilesystem(fs.XmlFsType.Type);
Statistics.AddFilesystem(fs.XmlFsType.Type);
}
else DicConsole.ErrorWriteLine("Unable to mount device, error {0}", error.ToString());
}
@@ -745,7 +799,8 @@ namespace DiscImageChef.Commands
DicConsole.DebugWriteLine("Extract-Files command", ex.StackTrace);
}
Core.Statistics.AddCommand("extract-files");
Statistics.AddCommand("extract-files");
return 0;
}
}
}

View File

@@ -37,20 +37,59 @@ using DiscImageChef.CommonTypes.Interfaces;
using DiscImageChef.Console;
using DiscImageChef.Core;
using DiscImageChef.Partitions;
using Mono.Options;
namespace DiscImageChef.Commands
{
static class Formats
class FormatsCommand : Command
{
internal static void ListFormats(FormatsOptions formatsOptions)
bool showHelp;
public FormatsCommand() : base("formats",
"Lists all supported disc images, partition schemes and file systems.")
{
Options = new OptionSet
{
$"{MainClass.AssemblyTitle} {MainClass.AssemblyVersion?.InformationalVersion}",
$"{MainClass.AssemblyCopyright}",
"",
$"usage: DiscImageChef {Name}",
"",
Help,
{"help|h|?", "Show this message and exit.", v => showHelp = v != null}
};
}
public override int Invoke(IEnumerable<string> arguments)
{
List<string> extra = Options.Parse(arguments);
if(showHelp)
{
Options.WriteOptionDescriptions(CommandSet.Out);
return 0;
}
MainClass.PrintCopyright();
if(MainClass.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
if(MainClass.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
if(extra.Count > 0)
{
DicConsole.ErrorWriteLine("Too many arguments.");
return 1;
}
DicConsole.DebugWriteLine("Formats command", "--debug={0}", MainClass.Debug);
DicConsole.DebugWriteLine("Formats command", "--verbose={0}", MainClass.Verbose);
PluginBase plugins = GetPluginBase.Instance;
FiltersList filtersList = new FiltersList();
DicConsole.WriteLine("Supported filters ({0}):", filtersList.Filters.Count);
if(formatsOptions.Verbose) DicConsole.VerboseWriteLine("GUID\t\t\t\t\tFilter");
if(MainClass.Verbose) DicConsole.VerboseWriteLine("GUID\t\t\t\t\tFilter");
foreach(KeyValuePair<string, IFilter> kvp in filtersList.Filters)
if(formatsOptions.Verbose)
if(MainClass.Verbose)
DicConsole.VerboseWriteLine("{0}\t{1}", kvp.Value.Id, kvp.Value.Name);
else
DicConsole.WriteLine(kvp.Value.Name);
@@ -59,22 +98,22 @@ namespace DiscImageChef.Commands
DicConsole.WriteLine("Read-only media image formats ({0}):",
plugins.ImagePluginsList.Count(t => !t.Value.GetType().GetInterfaces()
.Contains(typeof(IWritableImage))));
if(formatsOptions.Verbose) DicConsole.VerboseWriteLine("GUID\t\t\t\t\tPlugin");
if(MainClass.Verbose) DicConsole.VerboseWriteLine("GUID\t\t\t\t\tPlugin");
foreach(KeyValuePair<string, IMediaImage> kvp in plugins.ImagePluginsList.Where(t => !t.Value.GetType()
.GetInterfaces()
.Contains(typeof(
IWritableImage
))))
if(formatsOptions.Verbose)
if(MainClass.Verbose)
DicConsole.VerboseWriteLine("{0}\t{1}", kvp.Value.Id, kvp.Value.Name);
else
DicConsole.WriteLine(kvp.Value.Name);
DicConsole.WriteLine();
DicConsole.WriteLine("Read/write media image formats ({0}):", plugins.WritableImages.Count);
if(formatsOptions.Verbose) DicConsole.VerboseWriteLine("GUID\t\t\t\t\tPlugin");
if(MainClass.Verbose) DicConsole.VerboseWriteLine("GUID\t\t\t\t\tPlugin");
foreach(KeyValuePair<string, IWritableImage> kvp in plugins.WritableImages)
if(formatsOptions.Verbose)
if(MainClass.Verbose)
DicConsole.VerboseWriteLine("{0}\t{1}", kvp.Value.Id, kvp.Value.Name);
else
DicConsole.WriteLine(kvp.Value.Name);
@@ -83,13 +122,13 @@ namespace DiscImageChef.Commands
DicConsole.WriteLine("Supported filesystems for identification and information only ({0}):",
plugins.PluginsList.Count(t => !t.Value.GetType().GetInterfaces()
.Contains(typeof(IReadOnlyFilesystem))));
if(formatsOptions.Verbose) DicConsole.VerboseWriteLine("GUID\t\t\t\t\tPlugin");
if(MainClass.Verbose) DicConsole.VerboseWriteLine("GUID\t\t\t\t\tPlugin");
foreach(KeyValuePair<string, IFilesystem> kvp in plugins.PluginsList.Where(t => !t.Value.GetType()
.GetInterfaces()
.Contains(typeof(
IReadOnlyFilesystem
))))
if(formatsOptions.Verbose)
if(MainClass.Verbose)
DicConsole.VerboseWriteLine("{0}\t{1}", kvp.Value.Id, kvp.Value.Name);
else
DicConsole.WriteLine(kvp.Value.Name);
@@ -97,23 +136,24 @@ namespace DiscImageChef.Commands
DicConsole.WriteLine();
DicConsole.WriteLine("Supported filesystems that can read their contents ({0}):",
plugins.ReadOnlyFilesystems.Count);
if(formatsOptions.Verbose) DicConsole.VerboseWriteLine("GUID\t\t\t\t\tPlugin");
if(MainClass.Verbose) DicConsole.VerboseWriteLine("GUID\t\t\t\t\tPlugin");
foreach(KeyValuePair<string, IReadOnlyFilesystem> kvp in plugins.ReadOnlyFilesystems)
if(formatsOptions.Verbose)
if(MainClass.Verbose)
DicConsole.VerboseWriteLine("{0}\t{1}", kvp.Value.Id, kvp.Value.Name);
else
DicConsole.WriteLine(kvp.Value.Name);
DicConsole.WriteLine();
DicConsole.WriteLine("Supported partitioning schemes ({0}):", plugins.PartPluginsList.Count);
if(formatsOptions.Verbose) DicConsole.VerboseWriteLine("GUID\t\t\t\t\tPlugin");
if(MainClass.Verbose) DicConsole.VerboseWriteLine("GUID\t\t\t\t\tPlugin");
foreach(KeyValuePair<string, IPartition> kvp in plugins.PartPluginsList)
if(formatsOptions.Verbose)
if(MainClass.Verbose)
DicConsole.VerboseWriteLine("{0}\t{1}", kvp.Value.Id, kvp.Value.Name);
else
DicConsole.WriteLine(kvp.Value.Name);
Core.Statistics.AddCommand("formats");
Statistics.AddCommand("formats");
return 0;
}
}
}

View File

@@ -0,0 +1,83 @@
// /***************************************************************************
// The Disc Image Chef
// ----------------------------------------------------------------------------
//
// Filename : Gui.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : Verbs.
//
// --[ Description ] ----------------------------------------------------------
//
// Implements the 'gui' verb.
//
// --[ License ] --------------------------------------------------------------
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2019 Natalia Portillo
// ****************************************************************************/
using System.Collections.Generic;
using DiscImageChef.Console;
using DiscImageChef.Gui.Forms;
using Eto;
using Eto.Forms;
using Mono.Options;
using Command = Mono.Options.Command;
namespace DiscImageChef.Commands
{
class GuiCommand : Command
{
bool showHelp;
public GuiCommand() : base("gui", "Opens the in-progress GUI.")
{
Options = new OptionSet
{
$"{MainClass.AssemblyTitle} {MainClass.AssemblyVersion?.InformationalVersion}",
$"{MainClass.AssemblyCopyright}",
"",
$"usage: DiscImageChef {Name}",
"",
Help,
{"help|h|?", "Show this message and exit.", v => showHelp = v != null}
};
}
public override int Invoke(IEnumerable<string> arguments)
{
List<string> extra = Options.Parse(arguments);
if(showHelp)
{
Options.WriteOptionDescriptions(CommandSet.Out);
return 0;
}
if(extra.Count > 0)
{
MainClass.PrintCopyright();
DicConsole.ErrorWriteLine("Too many arguments.");
return 1;
}
new Application(Platform.Detect).Run(new frmMain(MainClass.Debug, MainClass.Verbose));
return 0;
}
}
}

View File

@@ -31,28 +31,75 @@
// ****************************************************************************/
using System;
using System.Collections.Generic;
using DiscImageChef.CommonTypes;
using DiscImageChef.CommonTypes.Interfaces;
using DiscImageChef.Console;
using DiscImageChef.Core;
using Mono.Options;
namespace DiscImageChef.Commands
{
static class ImageInfo
class ImageInfoCommand : Command
{
internal static void GetImageInfo(ImageInfoOptions options)
string inputFile;
bool showHelp;
public ImageInfoCommand() : base("image-info",
"Opens a media image and shows information about the media it represents and metadata.")
{
DicConsole.DebugWriteLine("Analyze command", "--debug={0}", options.Debug);
DicConsole.DebugWriteLine("Analyze command", "--verbose={0}", options.Verbose);
DicConsole.DebugWriteLine("Analyze command", "--input={0}", options.InputFile);
Options = new OptionSet
{
$"{MainClass.AssemblyTitle} {MainClass.AssemblyVersion?.InformationalVersion}",
$"{MainClass.AssemblyCopyright}",
"",
$"usage: DiscImageChef {Name} imagefile",
"",
Help,
{"help|h|?", "Show this message and exit.", v => showHelp = v != null}
};
}
public override int Invoke(IEnumerable<string> arguments)
{
List<string> extra = Options.Parse(arguments);
if(showHelp)
{
Options.WriteOptionDescriptions(CommandSet.Out);
return 0;
}
MainClass.PrintCopyright();
if(MainClass.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
if(MainClass.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
if(extra.Count > 1)
{
DicConsole.ErrorWriteLine("Too many arguments.");
return 1;
}
if(extra.Count == 0)
{
DicConsole.ErrorWriteLine("Missing input image.");
return 1;
}
inputFile = extra[0];
DicConsole.DebugWriteLine("Analyze command", "--debug={0}", MainClass.Debug);
DicConsole.DebugWriteLine("Analyze command", "--input={0}", inputFile);
DicConsole.DebugWriteLine("Analyze command", "--verbose={0}", MainClass.Verbose);
FiltersList filtersList = new FiltersList();
IFilter inputFilter = filtersList.GetFilter(options.InputFile);
IFilter inputFilter = filtersList.GetFilter(inputFile);
if(inputFilter == null)
{
DicConsole.ErrorWriteLine("Cannot open specified file.");
return;
return 1;
}
try
@@ -62,7 +109,7 @@ namespace DiscImageChef.Commands
if(imageFormat == null)
{
DicConsole.WriteLine("Image format not identified.");
return;
return 2;
}
DicConsole.WriteLine("Image format identified by {0} ({1}).", imageFormat.Name, imageFormat.Id);
@@ -74,14 +121,14 @@ namespace DiscImageChef.Commands
{
DicConsole.WriteLine("Unable to open image format");
DicConsole.WriteLine("No error given");
return;
return 3;
}
Core.ImageInfo.PrintImageInfo(imageFormat);
ImageInfo.PrintImageInfo(imageFormat);
Core.Statistics.AddMediaFormat(imageFormat.Format);
Core.Statistics.AddMedia(imageFormat.Info.MediaType, false);
Core.Statistics.AddFilter(inputFilter.Name);
Statistics.AddMediaFormat(imageFormat.Format);
Statistics.AddMedia(imageFormat.Info.MediaType, false);
Statistics.AddFilter(inputFilter.Name);
}
catch(Exception ex)
{
@@ -96,7 +143,8 @@ namespace DiscImageChef.Commands
DicConsole.DebugWriteLine("Image-info command", ex.StackTrace);
}
Core.Statistics.AddCommand("image-info");
Statistics.AddCommand("image-info");
return 0;
}
}
}

View File

@@ -30,20 +30,57 @@
// Copyright © 2011-2019 Natalia Portillo
// ****************************************************************************/
using System.Collections.Generic;
using System.Linq;
using DiscImageChef.Console;
using DiscImageChef.Core;
using DiscImageChef.Devices;
using Mono.Options;
namespace DiscImageChef.Commands
{
static class ListDevices
class ListDevicesCommand : Command
{
internal static void DoListDevices(ListDevicesOptions options)
{
DicConsole.DebugWriteLine("Media-Info command", "--debug={0}", options.Debug);
DicConsole.DebugWriteLine("Media-Info command", "--verbose={0}", options.Verbose);
bool showHelp;
Devices.DeviceInfo[] devices = Device.ListDevices();
public ListDevicesCommand() : base("list-devices", "Lists all connected devices.")
{
Options = new OptionSet
{
$"{MainClass.AssemblyTitle} {MainClass.AssemblyVersion?.InformationalVersion}",
$"{MainClass.AssemblyCopyright}",
"",
$"usage: DiscImageChef {Name}",
"",
Help,
{"help|h|?", "Show this message and exit.", v => showHelp = v != null}
};
}
public override int Invoke(IEnumerable<string> arguments)
{
List<string> extra = Options.Parse(arguments);
if(showHelp)
{
Options.WriteOptionDescriptions(CommandSet.Out);
return 0;
}
MainClass.PrintCopyright();
if(MainClass.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
if(MainClass.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
if(extra.Count > 0)
{
DicConsole.ErrorWriteLine("Too many arguments.");
return 1;
}
DicConsole.DebugWriteLine("List-Devices command", "--debug={0}", MainClass.Debug);
DicConsole.DebugWriteLine("List-Devices command", "--verbose={0}", MainClass.Verbose);
DeviceInfo[] devices = Device.ListDevices();
if(devices == null || devices.Length == 0) DicConsole.WriteLine("No known devices attached.");
else
@@ -55,12 +92,13 @@ namespace DiscImageChef.Commands
DicConsole.WriteLine("{0,-22}+{1,-16}+{2,-24}+{3,-24}+{4,-10}+{5,-10}", "----------------------",
"----------------", "------------------------", "------------------------",
"----------", "----------");
foreach(Devices.DeviceInfo dev in devices)
foreach(DeviceInfo dev in devices)
DicConsole.WriteLine("{0,-22}|{1,-16}|{2,-24}|{3,-24}|{4,-10}|{5,-10}", dev.Path, dev.Vendor,
dev.Model, dev.Serial, dev.Bus, dev.Supported);
}
Core.Statistics.AddCommand("list-devices");
Statistics.AddCommand("list-devices");
return 0;
}
}
}

View File

@@ -34,13 +34,52 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using DiscImageChef.Console;
using DiscImageChef.Core;
using Mono.Options;
namespace DiscImageChef.Commands
{
static class ListEncodings
class ListEncodingsCommand : Command
{
internal static void DoList()
bool showHelp;
public ListEncodingsCommand() : base("list-encodings", "Lists all supported text encodings and code pages.")
{
Options = new OptionSet
{
$"{MainClass.AssemblyTitle} {MainClass.AssemblyVersion?.InformationalVersion}",
$"{MainClass.AssemblyCopyright}",
"",
$"usage: DiscImageChef {Name}",
"",
Help,
{"help|h|?", "Show this message and exit.", v => showHelp = v != null}
};
}
public override int Invoke(IEnumerable<string> arguments)
{
List<string> extra = Options.Parse(arguments);
if(showHelp)
{
Options.WriteOptionDescriptions(CommandSet.Out);
return 0;
}
MainClass.PrintCopyright();
if(MainClass.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
if(MainClass.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
if(extra.Count > 0)
{
DicConsole.ErrorWriteLine("Too many arguments.");
return 1;
}
DicConsole.DebugWriteLine("List-Encodings command", "--debug={0}", MainClass.Debug);
DicConsole.DebugWriteLine("List-Encodings command", "--verbose={0}", MainClass.Verbose);
List<CommonEncodingInfo> encodings = Encoding
.GetEncodings().Select(info => new CommonEncodingInfo
{
@@ -59,7 +98,8 @@ namespace DiscImageChef.Commands
foreach(CommonEncodingInfo info in encodings.OrderBy(t => t.DisplayName))
DicConsole.WriteLine("{0,-16} {1,-8}", info.Name, info.DisplayName);
Core.Statistics.AddCommand("list-encodings");
Statistics.AddCommand("list-encodings");
return 0;
}
struct CommonEncodingInfo

View File

@@ -37,13 +37,52 @@ using DiscImageChef.CommonTypes;
using DiscImageChef.CommonTypes.Interfaces;
using DiscImageChef.Console;
using DiscImageChef.Core;
using Mono.Options;
namespace DiscImageChef.Commands
{
static class ListOptions
class ListOptionsCommand : Command
{
internal static void DoList()
bool showHelp;
public ListOptionsCommand() : base("list-options",
"Lists all options supported by read-only filesystems and writable media images.")
{
Options = new OptionSet
{
$"{MainClass.AssemblyTitle} {MainClass.AssemblyVersion?.InformationalVersion}",
$"{MainClass.AssemblyCopyright}",
"",
$"usage: DiscImageChef {Name}",
"",
Help,
{"help|h|?", "Show this message and exit.", v => showHelp = v != null}
};
}
public override int Invoke(IEnumerable<string> arguments)
{
List<string> extra = Options.Parse(arguments);
if(showHelp)
{
Options.WriteOptionDescriptions(CommandSet.Out);
return 0;
}
MainClass.PrintCopyright();
if(MainClass.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
if(MainClass.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
if(extra.Count > 0)
{
DicConsole.ErrorWriteLine("Too many arguments.");
return 1;
}
DicConsole.DebugWriteLine("List-Options command", "--debug={0}", MainClass.Debug);
DicConsole.DebugWriteLine("List-Options command", "--verbose={0}", MainClass.Verbose);
PluginBase plugins = GetPluginBase.Instance;
DicConsole.WriteLine("Read-only filesystems options:");
@@ -77,6 +116,8 @@ namespace DiscImageChef.Commands
option.@default, option.description);
DicConsole.WriteLine();
}
return 0;
}
static string TypeToString(Type type)

View File

@@ -38,44 +38,99 @@ using DiscImageChef.CommonTypes.Interfaces;
using DiscImageChef.CommonTypes.Structs;
using DiscImageChef.Console;
using DiscImageChef.Core;
using Mono.Options;
namespace DiscImageChef.Commands
{
static class Ls
class LsCommand : Command
{
internal static void DoLs(LsOptions options)
string encodingName;
string inputFile;
bool longFormat;
string pluginOptions;
bool showHelp;
public LsCommand() : base("ls", "Lists files in disc image.")
{
DicConsole.DebugWriteLine("Ls command", "--debug={0}", options.Debug);
DicConsole.DebugWriteLine("Ls command", "--verbose={0}", options.Verbose);
DicConsole.DebugWriteLine("Ls command", "--input={0}", options.InputFile);
Options = new OptionSet
{
$"{MainClass.AssemblyTitle} {MainClass.AssemblyVersion?.InformationalVersion}",
$"{MainClass.AssemblyCopyright}",
"",
$"usage: DiscImageChef {Name} [OPTIONS] imagefile",
"",
Help,
{"encoding|e=", "Name of character encoding to use.", s => encodingName = s},
{"long|l", "Uses long format.", b => longFormat = b != null},
{
"options|O=", "Comma separated name=value pairs of options to pass to filesystem plugin.",
s => pluginOptions = s
},
{"help|h|?", "Show this message and exit.", v => showHelp = v != null}
};
}
public override int Invoke(IEnumerable<string> arguments)
{
List<string> extra = Options.Parse(arguments);
if(showHelp)
{
Options.WriteOptionDescriptions(CommandSet.Out);
return 0;
}
MainClass.PrintCopyright();
if(MainClass.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
if(MainClass.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
if(extra.Count > 1)
{
DicConsole.ErrorWriteLine("Too many arguments.");
return 1;
}
if(extra.Count == 0)
{
DicConsole.ErrorWriteLine("Missing input image.");
return 1;
}
inputFile = extra[0];
DicConsole.DebugWriteLine("Ls command", "--debug={0}", MainClass.Debug);
DicConsole.DebugWriteLine("Ls command", "--encoding={0}", encodingName);
DicConsole.DebugWriteLine("Ls command", "--input={0}", inputFile);
DicConsole.DebugWriteLine("Ls command", "--options={0}", pluginOptions);
DicConsole.DebugWriteLine("Ls command", "--verbose={0}", MainClass.Verbose);
FiltersList filtersList = new FiltersList();
IFilter inputFilter = filtersList.GetFilter(options.InputFile);
IFilter inputFilter = filtersList.GetFilter(inputFile);
Dictionary<string, string> parsedOptions = Options.Parse(options.Options);
Dictionary<string, string> parsedOptions = Core.Options.Parse(pluginOptions);
DicConsole.DebugWriteLine("Ls command", "Parsed options:");
foreach(KeyValuePair<string, string> parsedOption in parsedOptions)
DicConsole.DebugWriteLine("Ls command", "{0} = {1}", parsedOption.Key, parsedOption.Value);
parsedOptions.Add("debug", options.Debug.ToString());
parsedOptions.Add("debug", MainClass.Debug.ToString());
if(inputFilter == null)
{
DicConsole.ErrorWriteLine("Cannot open specified file.");
return;
return 1;
}
Encoding encoding = null;
if(options.EncodingName != null)
if(encodingName != null)
try
{
encoding = Claunia.Encoding.Encoding.GetEncoding(options.EncodingName);
if(options.Verbose) DicConsole.VerboseWriteLine("Using encoding for {0}.", encoding.EncodingName);
encoding = Claunia.Encoding.Encoding.GetEncoding(encodingName);
if(MainClass.Verbose) DicConsole.VerboseWriteLine("Using encoding for {0}.", encoding.EncodingName);
}
catch(ArgumentException)
{
DicConsole.ErrorWriteLine("Specified encoding is not supported.");
return;
return 2;
}
PluginBase plugins = GetPluginBase.Instance;
@@ -87,10 +142,10 @@ namespace DiscImageChef.Commands
if(imageFormat == null)
{
DicConsole.WriteLine("Image format not identified, not proceeding with analysis.");
return;
return 3;
}
if(options.Verbose)
if(MainClass.Verbose)
DicConsole.VerboseWriteLine("Image format identified by {0} ({1}).", imageFormat.Name,
imageFormat.Id);
else DicConsole.WriteLine("Image format identified by {0}.", imageFormat.Name);
@@ -101,7 +156,7 @@ namespace DiscImageChef.Commands
{
DicConsole.WriteLine("Unable to open image format");
DicConsole.WriteLine("No error given");
return;
return 4;
}
DicConsole.DebugWriteLine("Ls command", "Correctly opened image file.");
@@ -111,15 +166,15 @@ namespace DiscImageChef.Commands
DicConsole.DebugWriteLine("Ls command", "Image identifies disk type as {0}.",
imageFormat.Info.MediaType);
Core.Statistics.AddMediaFormat(imageFormat.Format);
Core.Statistics.AddMedia(imageFormat.Info.MediaType, false);
Core.Statistics.AddFilter(inputFilter.Name);
Statistics.AddMediaFormat(imageFormat.Format);
Statistics.AddMedia(imageFormat.Info.MediaType, false);
Statistics.AddFilter(inputFilter.Name);
}
catch(Exception ex)
{
DicConsole.ErrorWriteLine("Unable to open image format");
DicConsole.ErrorWriteLine("Error: {0}", ex.Message);
return;
return 3;
}
List<Partition> partitions = Core.Partitions.GetAll(imageFormat);
@@ -168,7 +223,7 @@ namespace DiscImageChef.Commands
DicConsole.ErrorWriteLine("Error {0} reading root directory {0}",
error.ToString());
Core.Statistics.AddFilesystem(fs.XmlFsType.Type);
Statistics.AddFilesystem(fs.XmlFsType.Type);
}
else
DicConsole.ErrorWriteLine("Unable to mount device, error {0}",
@@ -196,7 +251,7 @@ namespace DiscImageChef.Commands
else
DicConsole.ErrorWriteLine("Error {0} reading root directory {0}", error.ToString());
Core.Statistics.AddFilesystem(fs.XmlFsType.Type);
Statistics.AddFilesystem(fs.XmlFsType.Type);
}
else DicConsole.ErrorWriteLine("Unable to mount device, error {0}", error.ToString());
}
@@ -235,7 +290,7 @@ namespace DiscImageChef.Commands
else
DicConsole.ErrorWriteLine("Error {0} reading root directory {0}", error.ToString());
Core.Statistics.AddFilesystem(fs.XmlFsType.Type);
Statistics.AddFilesystem(fs.XmlFsType.Type);
}
else DicConsole.ErrorWriteLine("Unable to mount device, error {0}", error.ToString());
}
@@ -257,7 +312,7 @@ namespace DiscImageChef.Commands
error = fs.ReadDir("/", out List<string> rootDir);
if(error == Errno.NoError)
foreach(string entry in rootDir)
if(options.Long)
if(longFormat)
{
error = fs.Stat(entry, out FileEntryInfo stat);
if(error == Errno.NoError)
@@ -284,7 +339,7 @@ namespace DiscImageChef.Commands
else
DicConsole.ErrorWriteLine("Error {0} reading root directory {0}", error.ToString());
Core.Statistics.AddFilesystem(fs.XmlFsType.Type);
Statistics.AddFilesystem(fs.XmlFsType.Type);
}
else DicConsole.ErrorWriteLine("Unable to mount device, error {0}", error.ToString());
}
@@ -297,7 +352,8 @@ namespace DiscImageChef.Commands
DicConsole.DebugWriteLine("Ls command", ex.StackTrace);
}
Core.Statistics.AddCommand("ls");
Statistics.AddCommand("ls");
return 0;
}
}
}

View File

@@ -44,6 +44,7 @@ using DiscImageChef.Decoders.SCSI.MMC;
using DiscImageChef.Decoders.SCSI.SSC;
using DiscImageChef.Decoders.Xbox;
using DiscImageChef.Devices;
using Mono.Options;
using BCA = DiscImageChef.Decoders.Bluray.BCA;
using Cartridge = DiscImageChef.Decoders.DVD.Cartridge;
using DDS = DiscImageChef.Decoders.DVD.DDS;
@@ -52,28 +53,75 @@ using Spare = DiscImageChef.Decoders.DVD.Spare;
namespace DiscImageChef.Commands
{
static class MediaInfo
class MediaInfoCommand : Command
{
internal static void DoMediaInfo(MediaInfoOptions options)
string devicePath;
string outputPrefix;
bool showHelp;
public MediaInfoCommand() : base("media-info", "Gets information about the media inserted on a device.")
{
DicConsole.DebugWriteLine("Media-Info command", "--debug={0}", options.Debug);
DicConsole.DebugWriteLine("Media-Info command", "--verbose={0}", options.Verbose);
DicConsole.DebugWriteLine("Media-Info command", "--device={0}", options.DevicePath);
DicConsole.DebugWriteLine("Media-Info command", "--output-prefix={0}", options.OutputPrefix);
Options = new OptionSet
{
$"{MainClass.AssemblyTitle} {MainClass.AssemblyVersion?.InformationalVersion}",
$"{MainClass.AssemblyCopyright}",
"",
$"usage: DiscImageChef {Name} [OPTIONS] devicepath",
"",
Help,
{"output-prefix|w=", "Write binary responses from device with that prefix.", s => outputPrefix = s},
{
"help|h|?", "Show this message and exit.",
v => showHelp = v != null
}
};
}
if(options.DevicePath.Length == 2 && options.DevicePath[1] == ':' && options.DevicePath[0] != '/' &&
char.IsLetter(options.DevicePath[0]))
options.DevicePath = "\\\\.\\" + char.ToUpper(options.DevicePath[0]) + ':';
public override int Invoke(IEnumerable<string> arguments)
{
List<string> extra = Options.Parse(arguments);
Device dev = new Device(options.DevicePath);
if(showHelp)
{
Options.WriteOptionDescriptions(CommandSet.Out);
return 0;
}
MainClass.PrintCopyright();
if(MainClass.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
if(MainClass.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
if(extra.Count > 1)
{
DicConsole.ErrorWriteLine("Too many arguments.");
return 1;
}
if(extra.Count == 0)
{
DicConsole.ErrorWriteLine("Missing device path.");
return 1;
}
devicePath = extra[0];
DicConsole.DebugWriteLine("Media-Info command", "--debug={0}", MainClass.Debug);
DicConsole.DebugWriteLine("Media-Info command", "--device={0}", devicePath);
DicConsole.DebugWriteLine("Media-Info command", "--output-prefix={0}", outputPrefix);
DicConsole.DebugWriteLine("Media-Info command", "--verbose={0}", MainClass.Verbose);
if(devicePath.Length == 2 && devicePath[1] == ':' && devicePath[0] != '/' && char.IsLetter(devicePath[0]))
devicePath = "\\\\.\\" + char.ToUpper(devicePath[0]) + ':';
Device dev = new Device(devicePath);
if(dev.Error)
{
DicConsole.ErrorWriteLine("Error {0} opening device.", dev.LastError);
return;
return 1;
}
Core.Statistics.AddDevice(dev);
Statistics.AddDevice(dev);
switch(dev.Type)
{
@@ -85,16 +133,18 @@ namespace DiscImageChef.Commands
DoSdMediaInfo();
break;
case DeviceType.NVMe:
DoNvmeMediaInfo(options.OutputPrefix, dev);
DoNvmeMediaInfo(outputPrefix, dev);
break;
case DeviceType.ATAPI:
case DeviceType.SCSI:
DoScsiMediaInfo(options.OutputPrefix, dev);
DoScsiMediaInfo(outputPrefix, dev);
break;
default: throw new NotSupportedException("Unknown device type.");
}
Core.Statistics.AddCommand("media-info");
Statistics.AddCommand("media-info");
return 0;
}
static void DoAtaMediaInfo()
@@ -451,7 +501,7 @@ namespace DiscImageChef.Commands
}
DicConsole.WriteLine("Media identified as {0}", scsiInfo.MediaType);
Core.Statistics.AddMedia(scsiInfo.MediaType, true);
Statistics.AddMedia(scsiInfo.MediaType, true);
dev.Close();
}

View File

@@ -31,54 +31,103 @@
// ****************************************************************************/
using System;
using System.Collections.Generic;
using DiscImageChef.CommonTypes.Enums;
using DiscImageChef.Console;
using DiscImageChef.Core;
using DiscImageChef.Core.Devices.Scanning;
using DiscImageChef.Devices;
using Mono.Options;
namespace DiscImageChef.Commands
{
static class MediaScan
class MediaScanCommand : Command
{
internal static void DoMediaScan(MediaScanOptions options)
string devicePath;
string ibgLogPath;
string mhddLogPath;
bool showHelp;
public MediaScanCommand() : base("media-scan", "Scans the media inserted on a device.")
{
DicConsole.DebugWriteLine("Media-Scan command", "--debug={0}", options.Debug);
DicConsole.DebugWriteLine("Media-Scan command", "--verbose={0}", options.Verbose);
DicConsole.DebugWriteLine("Media-Scan command", "--device={0}", options.DevicePath);
DicConsole.DebugWriteLine("Media-Scan command", "--mhdd-log={0}", options.MhddLogPath);
DicConsole.DebugWriteLine("Media-Scan command", "--ibg-log={0}", options.IbgLogPath);
Options = new OptionSet
{
$"{MainClass.AssemblyTitle} {MainClass.AssemblyVersion?.InformationalVersion}",
$"{MainClass.AssemblyCopyright}",
"",
$"usage: DiscImageChef {Name} [OPTIONS] devicepath",
"",
Help,
{"mhdd-log|mw=", "Write a log of the scan in the format used by MHDD.", s => mhddLogPath = s},
{"ibg-log|b=", "Write a log of the scan in the format used by ImgBurn.", s => ibgLogPath = s},
{"help|h|?", "Show this message and exit.", v => showHelp = v != null}
};
}
if(options.DevicePath.Length == 2 && options.DevicePath[1] == ':' && options.DevicePath[0] != '/' &&
char.IsLetter(options.DevicePath[0]))
options.DevicePath = "\\\\.\\" + char.ToUpper(options.DevicePath[0]) + ':';
public override int Invoke(IEnumerable<string> arguments)
{
List<string> extra = Options.Parse(arguments);
Device dev = new Device(options.DevicePath);
if(showHelp)
{
Options.WriteOptionDescriptions(CommandSet.Out);
return 0;
}
MainClass.PrintCopyright();
if(MainClass.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
if(MainClass.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
if(extra.Count > 1)
{
DicConsole.ErrorWriteLine("Too many arguments.");
return 1;
}
if(extra.Count == 0)
{
DicConsole.ErrorWriteLine("Missing device path.");
return 1;
}
devicePath = extra[0];
DicConsole.DebugWriteLine("Media-Scan command", "--debug={0}", MainClass.Debug);
DicConsole.DebugWriteLine("Media-Scan command", "--device={0}", devicePath);
DicConsole.DebugWriteLine("Media-Scan command", "--ibg-log={0}", ibgLogPath);
DicConsole.DebugWriteLine("Media-Scan command", "--mhdd-log={0}", mhddLogPath);
DicConsole.DebugWriteLine("Media-Scan command", "--verbose={0}", MainClass.Verbose);
if(devicePath.Length == 2 && devicePath[1] == ':' && devicePath[0] != '/' && char.IsLetter(devicePath[0]))
devicePath = "\\\\.\\" + char.ToUpper(devicePath[0]) + ':';
Device dev = new Device(devicePath);
if(dev.Error)
{
DicConsole.ErrorWriteLine("Error {0} opening device.", dev.LastError);
return;
return 1;
}
Core.Statistics.AddDevice(dev);
Statistics.AddDevice(dev);
ScanResults results;
switch(dev.Type)
{
case DeviceType.ATA:
results = Ata.Scan(options.MhddLogPath, options.IbgLogPath, options.DevicePath, dev);
results = Ata.Scan(mhddLogPath, ibgLogPath, devicePath, dev);
break;
case DeviceType.MMC:
case DeviceType.SecureDigital:
results = SecureDigital.Scan(options.MhddLogPath, options.IbgLogPath, options.DevicePath, dev);
results = SecureDigital.Scan(mhddLogPath, ibgLogPath, devicePath, dev);
break;
case DeviceType.NVMe:
results = Nvme.Scan(options.MhddLogPath, options.IbgLogPath, options.DevicePath, dev);
results = Nvme.Scan(mhddLogPath, ibgLogPath, devicePath, dev);
break;
case DeviceType.ATAPI:
case DeviceType.SCSI:
results = Scsi.Scan(options.MhddLogPath, options.IbgLogPath, options.DevicePath, dev);
results = Scsi.Scan(mhddLogPath, ibgLogPath, devicePath, dev);
break;
default: throw new NotSupportedException("Unknown device type.");
}
@@ -109,9 +158,10 @@ namespace DiscImageChef.Commands
DicConsole.WriteLine("Testing {0} seeks, longest seek took {1:F3} ms, fastest one took {2:F3} ms. ({3:F3} ms average)",
results.SeekTimes, results.SeekMax, results.SeekMin, results.SeekTotal / 1000);
Core.Statistics.AddCommand("media-scan");
Statistics.AddCommand("media-scan");
dev.Close();
return 0;
}
}
}

View File

@@ -30,32 +30,91 @@
// Copyright © 2011-2019 Natalia Portillo
// ****************************************************************************/
using System.Collections.Generic;
using DiscImageChef.CommonTypes;
using DiscImageChef.CommonTypes.Interfaces;
using DiscImageChef.Console;
using DiscImageChef.Core;
using Mono.Options;
namespace DiscImageChef.Commands
{
static class PrintHex
class PrintHexCommand : Command
{
internal static void DoPrintHex(PrintHexOptions options)
string inputFile;
ulong length = 1;
bool longSectors;
bool showHelp;
ulong? startSector;
ushort widthBytes = 32;
public PrintHexCommand() : base("printhex", "Prints a sector, in hexadecimal values, to the console.")
{
DicConsole.DebugWriteLine("PrintHex command", "--debug={0}", options.Debug);
DicConsole.DebugWriteLine("PrintHex command", "--verbose={0}", options.Verbose);
DicConsole.DebugWriteLine("PrintHex command", "--input={0}", options.InputFile);
DicConsole.DebugWriteLine("PrintHex command", "--start={0}", options.StartSector);
DicConsole.DebugWriteLine("PrintHex command", "--length={0}", options.Length);
DicConsole.DebugWriteLine("PrintHex command", "--long-sectors={0}", options.LongSectors);
DicConsole.DebugWriteLine("PrintHex command", "--WidthBytes={0}", options.WidthBytes);
Options = new OptionSet
{
$"{MainClass.AssemblyTitle} {MainClass.AssemblyVersion?.InformationalVersion}",
$"{MainClass.AssemblyCopyright}",
"",
$"usage: DiscImageChef {Name} [OPTIONS] imagefile",
"",
Help,
{"length|l=", "How many sectors to print.", (ulong ul) => length = ul},
{"long-sectors|r", "Print sectors with tags included.", b => longSectors = b != null},
{"start|s=", "Name of character encoding to use.", (ulong ul) => startSector = ul},
{"width|w=", "How many bytes to print per line.", (ushort us) => widthBytes = us},
{"help|h|?", "Show this message and exit.", v => showHelp = v != null}
};
}
public override int Invoke(IEnumerable<string> arguments)
{
List<string> extra = Options.Parse(arguments);
if(showHelp)
{
Options.WriteOptionDescriptions(CommandSet.Out);
return 0;
}
MainClass.PrintCopyright();
if(MainClass.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
if(MainClass.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
if(extra.Count > 1)
{
DicConsole.ErrorWriteLine("Too many arguments.");
return 1;
}
if(extra.Count == 0)
{
DicConsole.ErrorWriteLine("Missing input image.");
return 1;
}
if(startSector is null)
{
DicConsole.ErrorWriteLine("Missing starting sector.");
return 1;
}
inputFile = extra[0];
DicConsole.DebugWriteLine("PrintHex command", "--debug={0}", MainClass.Debug);
DicConsole.DebugWriteLine("PrintHex command", "--input={0}", inputFile);
DicConsole.DebugWriteLine("PrintHex command", "--length={0}", length);
DicConsole.DebugWriteLine("PrintHex command", "--long-sectors={0}", longSectors);
DicConsole.DebugWriteLine("PrintHex command", "--start={0}", startSector);
DicConsole.DebugWriteLine("PrintHex command", "--verbose={0}", MainClass.Verbose);
DicConsole.DebugWriteLine("PrintHex command", "--WidthBytes={0}", widthBytes);
FiltersList filtersList = new FiltersList();
IFilter inputFilter = filtersList.GetFilter(options.InputFile);
IFilter inputFilter = filtersList.GetFilter(inputFile);
if(inputFilter == null)
{
DicConsole.ErrorWriteLine("Cannot open specified file.");
return;
return 1;
}
IMediaImage inputFormat = ImageFormat.Detect(inputFilter);
@@ -63,20 +122,20 @@ namespace DiscImageChef.Commands
if(inputFormat == null)
{
DicConsole.ErrorWriteLine("Unable to recognize image format, not verifying");
return;
return 2;
}
inputFormat.Open(inputFilter);
for(ulong i = 0; i < options.Length; i++)
for(ulong i = 0; i < length; i++)
{
DicConsole.WriteLine("Sector {0}", options.StartSector + i);
DicConsole.WriteLine("Sector {0}", startSector + i);
if(inputFormat.Info.ReadableSectorTags == null)
{
DicConsole
.WriteLine("Requested sectors with tags, unsupported by underlying image format, printing only user data.");
options.LongSectors = false;
longSectors = false;
}
else
{
@@ -84,18 +143,19 @@ namespace DiscImageChef.Commands
{
DicConsole
.WriteLine("Requested sectors with tags, unsupported by underlying image format, printing only user data.");
options.LongSectors = false;
longSectors = false;
}
}
byte[] sector = options.LongSectors
? inputFormat.ReadSectorLong(options.StartSector + i)
: inputFormat.ReadSector(options.StartSector + i);
byte[] sector = longSectors
? inputFormat.ReadSectorLong(startSector.Value + i)
: inputFormat.ReadSector(startSector.Value + i);
DiscImageChef.PrintHex.PrintHexArray(sector, options.WidthBytes);
PrintHex.PrintHexArray(sector, widthBytes);
}
Core.Statistics.AddCommand("print-hex");
Statistics.AddCommand("print-hex");
return 0;
}
}
}

View File

@@ -30,24 +30,61 @@
// Copyright © 2011-2019 Natalia Portillo
// ****************************************************************************/
using System.Collections.Generic;
using System.Linq;
using DiscImageChef.Console;
using DiscImageChef.Database;
using DiscImageChef.Database.Models;
using Mono.Options;
using Command = Mono.Options.Command;
namespace DiscImageChef.Commands
{
static class Statistics
class StatisticsCommand : Command
{
internal static void ShowStats()
bool showHelp;
public StatisticsCommand() : base("stats", "Shows statistics.")
{
Options = new OptionSet
{
$"{MainClass.AssemblyTitle} {MainClass.AssemblyVersion?.InformationalVersion}",
$"{MainClass.AssemblyCopyright}",
"",
$"usage: DiscImageChef {Name}",
"",
Help,
{"help|h|?", "Show this message and exit.", v => showHelp = v != null}
};
}
public override int Invoke(IEnumerable<string> arguments)
{
List<string> extra = Options.Parse(arguments);
if(showHelp)
{
Options.WriteOptionDescriptions(CommandSet.Out);
return 0;
}
MainClass.PrintCopyright();
if(MainClass.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
if(MainClass.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
if(extra.Count > 0)
{
DicConsole.ErrorWriteLine("Too many arguments.");
return 1;
}
DicContext ctx = DicContext.Create(Settings.Settings.LocalDbPath);
if(!ctx.Commands.Any() && !ctx.Filesystems.Any() && !ctx.Filters.Any() && !ctx.MediaFormats.Any() &&
!ctx.Medias.Any() && !ctx.Partitions.Any() && !ctx.SeenDevices.Any())
{
DicConsole.WriteLine("There are no statistics.");
return;
return 1;
}
bool thereAreStats = false;
@@ -198,6 +235,7 @@ namespace DiscImageChef.Commands
}
if(!thereAreStats) DicConsole.WriteLine("There are no statistics.");
return 0;
}
}
}

View File

@@ -30,25 +30,67 @@
// Copyright © 2011-2019 Natalia Portillo
// ****************************************************************************/
using System.Collections.Generic;
using DiscImageChef.Console;
using DiscImageChef.Core;
using Mono.Options;
namespace DiscImageChef.Commands
{
static class Update
class UpdateCommand : Command
{
internal static void DoUpdate(UpdateOptions options)
readonly bool masterDbUpdate;
bool showHelp;
public UpdateCommand(bool masterDbUpdate) : base("update", "Updates the database.")
{
DicConsole.DebugWriteLine("Media-Info command", "--debug={0}", options.Debug);
DicConsole.DebugWriteLine("Media-Info command", "--verbose={0}", options.Verbose);
this.masterDbUpdate = masterDbUpdate;
Options = new OptionSet
{
$"{MainClass.AssemblyTitle} {MainClass.AssemblyVersion?.InformationalVersion}",
$"{MainClass.AssemblyCopyright}",
"",
$"usage: DiscImageChef {Name}",
"",
Help,
{"help|h|?", "Show this message and exit.", v => showHelp = v != null}
};
}
public override int Invoke(IEnumerable<string> arguments)
{
if(masterDbUpdate) return 0;
List<string> extra = Options.Parse(arguments);
if(showHelp)
{
Options.WriteOptionDescriptions(CommandSet.Out);
return 0;
}
MainClass.PrintCopyright();
if(MainClass.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
if(MainClass.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
if(extra.Count > 0)
{
DicConsole.ErrorWriteLine("Too many arguments.");
return 1;
}
DicConsole.DebugWriteLine("Update command", "--debug={0}", MainClass.Debug);
DicConsole.DebugWriteLine("Update command", "--verbose={0}", MainClass.Verbose);
DoUpdate(false);
return 0;
}
internal static void DoUpdate(bool create)
{
Remote.UpdateMasterDatabase(create);
Core.Statistics.AddCommand("update");
Statistics.AddCommand("update");
}
}
}

View File

@@ -37,26 +37,74 @@ using DiscImageChef.CommonTypes.Interfaces;
using DiscImageChef.CommonTypes.Structs;
using DiscImageChef.Console;
using DiscImageChef.Core;
using Mono.Options;
namespace DiscImageChef.Commands
{
static class Verify
class VerifyCommand : Command
{
internal static void DoVerify(VerifyOptions options)
string inputFile;
bool showHelp;
bool verifyDisc = true;
bool verifySectors = true;
public VerifyCommand() : base("verify", "Verifies a disc image integrity, and if supported, sector integrity.")
{
DicConsole.DebugWriteLine("Verify command", "--debug={0}", options.Debug);
DicConsole.DebugWriteLine("Verify command", "--verbose={0}", options.Verbose);
DicConsole.DebugWriteLine("Verify command", "--input={0}", options.InputFile);
DicConsole.DebugWriteLine("Verify command", "--verify-disc={0}", options.VerifyDisc);
DicConsole.DebugWriteLine("Verify command", "--verify-sectors={0}", options.VerifySectors);
Options = new OptionSet
{
$"{MainClass.AssemblyTitle} {MainClass.AssemblyVersion?.InformationalVersion}",
$"{MainClass.AssemblyCopyright}",
"",
$"usage: DiscImageChef {Name} [OPTIONS] imagefile",
"",
Help,
{"verify-disc|w", "Verify disc image if supported.", b => verifyDisc = b != null},
{"verify-sectors|s", "Verify all sectors if supported.", b => verifySectors = b != null},
{"help|h|?", "Show this message and exit.", v => showHelp = v != null}
};
}
public override int Invoke(IEnumerable<string> arguments)
{
List<string> extra = Options.Parse(arguments);
if(showHelp)
{
Options.WriteOptionDescriptions(CommandSet.Out);
return 0;
}
MainClass.PrintCopyright();
if(MainClass.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
if(MainClass.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
if(extra.Count > 1)
{
DicConsole.ErrorWriteLine("Too many arguments.");
return 1;
}
if(extra.Count == 0)
{
DicConsole.ErrorWriteLine("Missing input image.");
return 1;
}
inputFile = extra[0];
DicConsole.DebugWriteLine("Verify command", "--debug={0}", MainClass.Debug);
DicConsole.DebugWriteLine("Verify command", "--input={0}", inputFile);
DicConsole.DebugWriteLine("Verify command", "--verbose={0}", MainClass.Verbose);
DicConsole.DebugWriteLine("Verify command", "--verify-disc={0}", verifyDisc);
DicConsole.DebugWriteLine("Verify command", "--verify-sectors={0}", verifySectors);
FiltersList filtersList = new FiltersList();
IFilter inputFilter = filtersList.GetFilter(options.InputFile);
IFilter inputFilter = filtersList.GetFilter(inputFile);
if(inputFilter == null)
{
DicConsole.ErrorWriteLine("Cannot open specified file.");
return;
return 1;
}
IMediaImage inputFormat = ImageFormat.Detect(inputFilter);
@@ -64,13 +112,13 @@ namespace DiscImageChef.Commands
if(inputFormat == null)
{
DicConsole.ErrorWriteLine("Unable to recognize image format, not verifying");
return;
return 2;
}
inputFormat.Open(inputFilter);
Core.Statistics.AddMediaFormat(inputFormat.Format);
Core.Statistics.AddMedia(inputFormat.Info.MediaType, false);
Core.Statistics.AddFilter(inputFilter.Name);
Statistics.AddMediaFormat(inputFormat.Format);
Statistics.AddMedia(inputFormat.Info.MediaType, false);
Statistics.AddFilter(inputFilter.Name);
bool? correctDisc = null;
long totalSectors = 0;
@@ -78,7 +126,7 @@ namespace DiscImageChef.Commands
long correctSectors = 0;
long unknownSectors = 0;
if(options.VerifyDisc)
if(verifyDisc)
{
DateTime startCheck = DateTime.UtcNow;
bool? discCheckStatus = inputFormat.VerifyMediaImage();
@@ -103,7 +151,7 @@ namespace DiscImageChef.Commands
DicConsole.VerboseWriteLine("Checking disc image checksums took {0} seconds", checkTime.TotalSeconds);
}
if(options.VerifySectors)
if(verifySectors)
{
bool formatHasTracks;
try
@@ -215,7 +263,7 @@ namespace DiscImageChef.Commands
DicConsole.VerboseWriteLine("Checking sector checksums took {0} seconds", checkTime.TotalSeconds);
if(options.Verbose)
if(MainClass.Verbose)
{
DicConsole.VerboseWriteLine("LBAs with error:");
if(failingLbas.Count == (int)inputFormat.Info.Sectors)
@@ -243,7 +291,8 @@ namespace DiscImageChef.Commands
correctSectors = totalSectors - errorSectors - unknownSectors;
}
Core.Statistics.AddCommand("verify");
Statistics.AddCommand("verify");
return 0;
}
}
}