mirror of
https://github.com/aaru-dps/Aaru.git
synced 2025-12-16 19:24:25 +00:00
Use Mono.Options as command line parser.
This commit is contained in:
2
.idea/.idea.DiscImageChef/.idea/contentModel.xml
generated
2
.idea/.idea.DiscImageChef/.idea/contentModel.xml
generated
@@ -33,6 +33,7 @@
|
||||
<e p="Entropy.cs" t="Include" />
|
||||
<e p="ExtractFiles.cs" t="Include" />
|
||||
<e p="Formats.cs" t="Include" />
|
||||
<e p="Gui.cs" t="Include" />
|
||||
<e p="ImageInfo.cs" t="Include" />
|
||||
<e p="ListDevices.cs" t="Include" />
|
||||
<e p="ListEncodings.cs" t="Include" />
|
||||
@@ -49,7 +50,6 @@
|
||||
<e p="Info.plist" t="Include" />
|
||||
<e p="MacIcon.icns" t="Include" />
|
||||
<e p="Main.cs" t="Include" />
|
||||
<e p="Options.cs" t="Include" />
|
||||
<e p="Progress.cs" t="Include" />
|
||||
<e p="Properties" t="Include">
|
||||
<e p="launchSettings.json" t="Include" />
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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,7 +674,7 @@ namespace DiscImageChef.Commands
|
||||
}
|
||||
}
|
||||
|
||||
if(options.Debug && mediaTest.SupportsReadLong == true &&
|
||||
if(MainClass.Debug && mediaTest.SupportsReadLong == true &&
|
||||
mediaTest.LongBlockSize != mediaTest.BlockSize)
|
||||
{
|
||||
sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0,
|
||||
@@ -844,7 +891,7 @@ namespace DiscImageChef.Commands
|
||||
}
|
||||
}
|
||||
|
||||
if(options.Debug && mediaTest.SupportsReadLong == true &&
|
||||
if(MainClass.Debug && mediaTest.SupportsReadLong == true &&
|
||||
mediaTest.LongBlockSize != mediaTest.BlockSize)
|
||||
{
|
||||
sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0,
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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",
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
83
DiscImageChef/Commands/Gui.cs
Normal file
83
DiscImageChef/Commands/Gui.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -53,11 +53,11 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Commands\ConvertImage.cs" />
|
||||
<Compile Include="Commands\Gui.cs" />
|
||||
<Compile Include="Commands\ImageInfo.cs" />
|
||||
<Compile Include="Commands\ListOptions.cs" />
|
||||
<Compile Include="Commands\Update.cs" />
|
||||
<Compile Include="Main.cs" />
|
||||
<Compile Include="Options.cs" />
|
||||
<Compile Include="Commands\Formats.cs" />
|
||||
<Compile Include="Commands\Analyze.cs" />
|
||||
<Compile Include="Commands\Compare.cs" />
|
||||
@@ -262,11 +262,12 @@
|
||||
<Content Include="..\.github\PULL_REQUEST_TEMPLATE.md" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CommandLineParser" Version="2.3.0" />
|
||||
<PackageReference Include="Eto.Forms" Version="2.4.1" />
|
||||
<PackageReference Include="Eto.Platform.Gtk" Version="2.4.1" />
|
||||
<PackageReference Include="Eto.Platform.Mac64" Version="2.4.1" />
|
||||
<PackageReference Include="Eto.Platform.Wpf" Version="2.4.1" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.0" />
|
||||
<PackageReference Include="Mono.Options" Version="5.3.0.1" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
|
||||
<PackageReference Include="System.ValueTuple" Version="4.5.0" />
|
||||
<PackageReference Include="Unclassified.NetRevisionTask" Version="0.2.5" />
|
||||
|
||||
@@ -34,24 +34,35 @@ using System;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using CommandLine;
|
||||
using DiscImageChef.Commands;
|
||||
using DiscImageChef.Console;
|
||||
using DiscImageChef.Core;
|
||||
using DiscImageChef.Database;
|
||||
using DiscImageChef.Gui.Forms;
|
||||
using DiscImageChef.Settings;
|
||||
using Eto;
|
||||
using Eto.Forms;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Statistics = DiscImageChef.Core.Statistics;
|
||||
using Mono.Options;
|
||||
|
||||
namespace DiscImageChef
|
||||
{
|
||||
class MainClass
|
||||
{
|
||||
internal static bool Verbose;
|
||||
internal static bool Debug;
|
||||
internal static string AssemblyCopyright;
|
||||
internal static string AssemblyTitle;
|
||||
internal static AssemblyInformationalVersionAttribute AssemblyVersion;
|
||||
|
||||
[STAThread]
|
||||
public static void Main(string[] args)
|
||||
public static int Main(string[] args)
|
||||
{
|
||||
object[] attributes = typeof(MainClass).Assembly.GetCustomAttributes(typeof(AssemblyTitleAttribute), false);
|
||||
AssemblyTitle = ((AssemblyTitleAttribute)attributes[0]).Title;
|
||||
attributes = typeof(MainClass).Assembly.GetCustomAttributes(typeof(AssemblyCopyrightAttribute), false);
|
||||
AssemblyVersion =
|
||||
Attribute.GetCustomAttribute(typeof(MainClass).Assembly, typeof(AssemblyInformationalVersionAttribute))
|
||||
as AssemblyInformationalVersionAttribute;
|
||||
AssemblyCopyright = ((AssemblyCopyrightAttribute)attributes[0]).Copyright;
|
||||
|
||||
DicConsole.WriteLineEvent += System.Console.WriteLine;
|
||||
DicConsole.WriteEvent += System.Console.Write;
|
||||
DicConsole.ErrorWriteLineEvent += System.Console.Error.WriteLine;
|
||||
@@ -66,7 +77,7 @@ namespace DiscImageChef
|
||||
if(!File.Exists(Settings.Settings.MasterDbPath))
|
||||
{
|
||||
masterDbUpdate = true;
|
||||
Update.DoUpdate(masterDbUpdate);
|
||||
UpdateCommand.DoUpdate(masterDbUpdate);
|
||||
}
|
||||
|
||||
DicContext mctx = DicContext.Create(Settings.Settings.MasterDbPath);
|
||||
@@ -74,193 +85,63 @@ namespace DiscImageChef
|
||||
mctx.SaveChanges();
|
||||
|
||||
if((args.Length < 1 || args[0].ToLowerInvariant() != "gui") &&
|
||||
Settings.Settings.Current.GdprCompliance < DicSettings.GdprLevel) Configure.DoConfigure(true);
|
||||
Settings.Settings.Current.GdprCompliance < DicSettings.GdprLevel)
|
||||
new ConfigureCommand(true).Invoke(args);
|
||||
Statistics.LoadStats();
|
||||
if(Settings.Settings.Current.Stats != null && Settings.Settings.Current.Stats.ShareStats)
|
||||
Task.Run(() => { Statistics.SubmitStats(); });
|
||||
|
||||
Parser.Default.ParseArguments(args, typeof(AnalyzeOptions), typeof(BenchmarkOptions),
|
||||
typeof(ChecksumOptions), typeof(CompareOptions), typeof(ConfigureOptions),
|
||||
typeof(ConvertImageOptions), typeof(CreateSidecarOptions),
|
||||
typeof(DecodeOptions), typeof(DeviceInfoOptions), typeof(DeviceReportOptions),
|
||||
typeof(DumpMediaOptions), typeof(EntropyOptions), typeof(ExtractFilesOptions),
|
||||
typeof(FormatsOptions), typeof(ImageInfoOptions), typeof(ListDevicesOptions),
|
||||
typeof(ListEncodingsOptions), typeof(ListOptionsOptions), typeof(LsOptions),
|
||||
typeof(MediaInfoOptions), typeof(MediaScanOptions), typeof(PrintHexOptions),
|
||||
typeof(StatsOptions), typeof(VerifyOptions), typeof(GuiOptions),
|
||||
typeof(UpdateOptions)).WithParsed<AnalyzeOptions>(opts =>
|
||||
CommandSet commands = new CommandSet("DiscImageChef")
|
||||
{
|
||||
if(opts.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
||||
if(opts.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
||||
PrintCopyright();
|
||||
Analyze.DoAnalyze(opts);
|
||||
}).WithParsed<CompareOptions>(opts =>
|
||||
{
|
||||
if(opts.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
||||
if(opts.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
||||
PrintCopyright();
|
||||
Compare.DoCompare(opts);
|
||||
}).WithParsed<ChecksumOptions>(opts =>
|
||||
{
|
||||
if(opts.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
||||
if(opts.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
||||
PrintCopyright();
|
||||
Checksum.DoChecksum(opts);
|
||||
}).WithParsed<EntropyOptions>(opts =>
|
||||
{
|
||||
if(opts.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
||||
if(opts.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
||||
PrintCopyright();
|
||||
Entropy.DoEntropy(opts);
|
||||
}).WithParsed<VerifyOptions>(opts =>
|
||||
{
|
||||
if(opts.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
||||
if(opts.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
||||
PrintCopyright();
|
||||
Verify.DoVerify(opts);
|
||||
}).WithParsed<PrintHexOptions>(opts =>
|
||||
{
|
||||
if(opts.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
||||
if(opts.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
||||
PrintCopyright();
|
||||
Commands.PrintHex.DoPrintHex(opts);
|
||||
}).WithParsed<DecodeOptions>(opts =>
|
||||
{
|
||||
if(opts.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
||||
if(opts.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
||||
PrintCopyright();
|
||||
Decode.DoDecode(opts);
|
||||
}).WithParsed<DeviceInfoOptions>(opts =>
|
||||
{
|
||||
if(opts.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
||||
if(opts.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
||||
PrintCopyright();
|
||||
DeviceInfo.DoDeviceInfo(opts);
|
||||
}).WithParsed<MediaInfoOptions>(opts =>
|
||||
{
|
||||
if(opts.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
||||
if(opts.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
||||
PrintCopyright();
|
||||
MediaInfo.DoMediaInfo(opts);
|
||||
}).WithParsed<MediaScanOptions>(opts =>
|
||||
{
|
||||
if(opts.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
||||
if(opts.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
||||
PrintCopyright();
|
||||
MediaScan.DoMediaScan(opts);
|
||||
}).WithParsed<FormatsOptions>(opts =>
|
||||
{
|
||||
if(opts.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
||||
if(opts.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
||||
PrintCopyright();
|
||||
Formats.ListFormats(opts);
|
||||
}).WithParsed<BenchmarkOptions>(opts =>
|
||||
{
|
||||
if(opts.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
||||
if(opts.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
||||
PrintCopyright();
|
||||
Benchmark.DoBenchmark(opts);
|
||||
}).WithParsed<CreateSidecarOptions>(opts =>
|
||||
{
|
||||
if(opts.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
||||
if(opts.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
||||
PrintCopyright();
|
||||
CreateSidecar.DoSidecar(opts);
|
||||
}).WithParsed<DumpMediaOptions>(opts =>
|
||||
{
|
||||
if(opts.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
||||
if(opts.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
||||
PrintCopyright();
|
||||
DumpMedia.DoDumpMedia(opts);
|
||||
}).WithParsed<DeviceReportOptions>(opts =>
|
||||
{
|
||||
if(opts.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
||||
if(opts.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
||||
PrintCopyright();
|
||||
DeviceReport.DoDeviceReport(opts);
|
||||
}).WithParsed<LsOptions>(opts =>
|
||||
{
|
||||
if(opts.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
||||
if(opts.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
||||
PrintCopyright();
|
||||
Ls.DoLs(opts);
|
||||
}).WithParsed<ExtractFilesOptions>(opts =>
|
||||
{
|
||||
if(opts.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
||||
if(opts.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
||||
PrintCopyright();
|
||||
ExtractFiles.DoExtractFiles(opts);
|
||||
}).WithParsed<ListDevicesOptions>(opts =>
|
||||
{
|
||||
if(opts.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
||||
if(opts.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
||||
PrintCopyright();
|
||||
ListDevices.DoListDevices(opts);
|
||||
}).WithParsed<ListEncodingsOptions>(opts =>
|
||||
{
|
||||
if(opts.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
||||
if(opts.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
||||
PrintCopyright();
|
||||
ListEncodings.DoList();
|
||||
}).WithParsed<ListOptionsOptions>(opts =>
|
||||
{
|
||||
if(opts.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
||||
if(opts.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
||||
PrintCopyright();
|
||||
ListOptions.DoList();
|
||||
}).WithParsed<ConvertImageOptions>(opts =>
|
||||
{
|
||||
if(opts.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
||||
if(opts.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
||||
PrintCopyright();
|
||||
ConvertImage.DoConvert(opts);
|
||||
}).WithParsed<ImageInfoOptions>(opts =>
|
||||
{
|
||||
if(opts.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
||||
if(opts.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
||||
PrintCopyright();
|
||||
ImageInfo.GetImageInfo(opts);
|
||||
}).WithParsed<ConfigureOptions>(opts =>
|
||||
{
|
||||
PrintCopyright();
|
||||
Configure.DoConfigure(false);
|
||||
}).WithParsed<StatsOptions>(opts =>
|
||||
{
|
||||
PrintCopyright();
|
||||
Commands.Statistics.ShowStats();
|
||||
}).WithParsed<GuiOptions>(opts =>
|
||||
{
|
||||
if(opts.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
||||
if(opts.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
||||
$"{AssemblyTitle} {AssemblyVersion?.InformationalVersion}",
|
||||
$"{AssemblyCopyright}",
|
||||
"",
|
||||
"usage: DiscImageChef COMMAND [OPTIONS]",
|
||||
"",
|
||||
"Global options:",
|
||||
{"verbose|v", "Shows verbose output.", b => Verbose = b != null},
|
||||
{"debug|d", "Shows debug output from plugins.", b => Debug = b != null},
|
||||
"",
|
||||
"Available commands:",
|
||||
new AnalyzeCommand(),
|
||||
new BenchmarkCommand(),
|
||||
new ChecksumCommand(),
|
||||
new CompareCommand(),
|
||||
new ConfigureCommand(false),
|
||||
new ConvertImageCommand(),
|
||||
new CreateSidecarCommand(),
|
||||
new DecodeCommand(),
|
||||
new DeviceInfoCommand(),
|
||||
new DeviceReportCommand(),
|
||||
new DumpMediaCommand(),
|
||||
new EntropyCommand(),
|
||||
new ExtractFilesCommand(),
|
||||
new FormatsCommand(),
|
||||
new GuiCommand(),
|
||||
new ImageInfoCommand(),
|
||||
new ListDevicesCommand(),
|
||||
new ListEncodingsCommand(),
|
||||
new ListOptionsCommand(),
|
||||
new LsCommand(),
|
||||
new MediaInfoCommand(),
|
||||
new MediaScanCommand(),
|
||||
new PrintHexCommand(),
|
||||
new StatisticsCommand(),
|
||||
new UpdateCommand(masterDbUpdate),
|
||||
new VerifyCommand()
|
||||
};
|
||||
|
||||
new Application(Platform.Detect).Run(new frmMain(opts.Debug, opts.Verbose));
|
||||
}).WithParsed<UpdateOptions>(opts =>
|
||||
{
|
||||
if(!masterDbUpdate)
|
||||
{
|
||||
if(opts.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
||||
if(opts.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
||||
|
||||
Update.DoUpdate(opts);
|
||||
}
|
||||
}).WithNotParsed(errs => Environment.Exit(1));
|
||||
int ret = commands.Run(args);
|
||||
|
||||
Statistics.SaveStats();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void PrintCopyright()
|
||||
internal static void PrintCopyright()
|
||||
{
|
||||
object[] attributes =
|
||||
typeof(MainClass).Assembly.GetCustomAttributes(typeof(AssemblyTitleAttribute), false);
|
||||
string assemblyTitle = ((AssemblyTitleAttribute)attributes[0]).Title;
|
||||
attributes = typeof(MainClass).Assembly.GetCustomAttributes(typeof(AssemblyCopyrightAttribute), false);
|
||||
AssemblyInformationalVersionAttribute assemblyVersion =
|
||||
Attribute.GetCustomAttribute(typeof(MainClass).Assembly, typeof(AssemblyInformationalVersionAttribute))
|
||||
as AssemblyInformationalVersionAttribute;
|
||||
string assemblyCopyright = ((AssemblyCopyrightAttribute)attributes[0]).Copyright;
|
||||
|
||||
DicConsole.WriteLine("{0} {1}", assemblyTitle, assemblyVersion?.InformationalVersion);
|
||||
DicConsole.WriteLine("{0}", assemblyCopyright);
|
||||
DicConsole.WriteLine("{0} {1}", AssemblyTitle, AssemblyVersion?.InformationalVersion);
|
||||
DicConsole.WriteLine("{0}", AssemblyCopyright);
|
||||
DicConsole.WriteLine();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,465 +0,0 @@
|
||||
// /***************************************************************************
|
||||
// The Disc Image Chef
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
// Filename : Options.cs
|
||||
// Author(s) : Natalia Portillo <claunia@claunia.com>
|
||||
//
|
||||
// Component : Main program loop.
|
||||
//
|
||||
// --[ Description ] ----------------------------------------------------------
|
||||
//
|
||||
// Defines verbs and options.
|
||||
//
|
||||
// --[ 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 CommandLine;
|
||||
|
||||
// ReSharper disable MemberCanBeInternal
|
||||
// ReSharper disable UnusedAutoPropertyAccessor.Global
|
||||
|
||||
namespace DiscImageChef
|
||||
{
|
||||
public abstract class CommonOptions
|
||||
{
|
||||
[Option('v', "verbose", Default = false, HelpText = "Shows verbose output")]
|
||||
public bool Verbose { get; set; }
|
||||
|
||||
[Option('d', "debug", Default = false, HelpText = "Shows debug output from plugins")]
|
||||
public bool Debug { get; set; }
|
||||
}
|
||||
|
||||
[Verb("analyze", HelpText = "Analyzes a disc image and searches for partitions and/or filesystems.")]
|
||||
public class AnalyzeOptions : CommonOptions
|
||||
{
|
||||
[Option('p', "partitions", Default = true, HelpText = "Searches and interprets partitions.")]
|
||||
public bool SearchForPartitions { get; set; }
|
||||
|
||||
[Option('f', "filesystems", Default = true, HelpText = "Searches and interprets partitions.")]
|
||||
public bool SearchForFilesystems { get; set; }
|
||||
|
||||
[Option('i', "input", Required = true, HelpText = "Disc image.")]
|
||||
public string InputFile { get; set; }
|
||||
|
||||
[Option('e', "encoding", Default = null, HelpText = "Name of character encoding to use.")]
|
||||
public string EncodingName { get; set; }
|
||||
}
|
||||
|
||||
[Verb("compare", HelpText = "Compares two disc images.")]
|
||||
public class CompareOptions : CommonOptions
|
||||
{
|
||||
[Option("input1", Required = true, HelpText = "First disc image.")]
|
||||
public string InputFile1 { get; set; }
|
||||
|
||||
[Option("input2", Required = true, HelpText = "Second disc image.")]
|
||||
public string InputFile2 { get; set; }
|
||||
}
|
||||
|
||||
[Verb("checksum", HelpText = "Checksums an image.")]
|
||||
public class ChecksumOptions : CommonOptions
|
||||
{
|
||||
[Option('t', "separated-tracks", Default = true, HelpText = "Checksums each track separately.")]
|
||||
public bool SeparatedTracks { get; set; }
|
||||
|
||||
[Option('w', "whole-disc", Default = true, HelpText = "Checksums the whole disc.")]
|
||||
public bool WholeDisc { get; set; }
|
||||
|
||||
[Option('a', "adler32", Default = true, HelpText = "Calculates Adler-32.")]
|
||||
public bool DoAdler32 { get; set; }
|
||||
|
||||
[Option("crc16", Default = true, HelpText = "Calculates CRC16.")]
|
||||
public bool DoCrc16 { get; set; }
|
||||
|
||||
[Option('c', "crc32", Default = true, HelpText = "Calculates CRC32.")]
|
||||
public bool DoCrc32 { get; set; }
|
||||
|
||||
[Option("crc64", Default = false, HelpText = "Calculates CRC64 (ECMA).")]
|
||||
public bool DoCrc64 { get; set; }
|
||||
|
||||
[Option("fletcher16", Default = false, HelpText = "Calculates Fletcher-16.")]
|
||||
public bool DoFletcher16 { get; set; }
|
||||
|
||||
[Option("fletcher32", Default = false, HelpText = "Calculates Fletcher-32.")]
|
||||
public bool DoFletcher32 { get; set; }
|
||||
|
||||
[Option('m', "md5", Default = true, HelpText = "Calculates MD5.")]
|
||||
public bool DoMd5 { get; set; }
|
||||
|
||||
[Option("ripemd160", Default = false, HelpText = "Calculates RIPEMD160.")]
|
||||
public bool DoRipemd160 { get; set; }
|
||||
|
||||
[Option('s', "sha1", Default = true, HelpText = "Calculates SHA1.")]
|
||||
public bool DoSha1 { get; set; }
|
||||
|
||||
[Option("sha256", Default = false, HelpText = "Calculates SHA256.")]
|
||||
public bool DoSha256 { get; set; }
|
||||
|
||||
[Option("sha384", Default = false, HelpText = "Calculates SHA384.")]
|
||||
public bool DoSha384 { get; set; }
|
||||
|
||||
[Option("sha512", Default = false, HelpText = "Calculates SHA512.")]
|
||||
public bool DoSha512 { get; set; }
|
||||
|
||||
[Option('f', "spamsum", Default = true, HelpText = "Calculates SpamSum fuzzy hash.")]
|
||||
public bool DoSpamSum { get; set; }
|
||||
|
||||
[Option('i', "input", Required = true, HelpText = "Disc image.")]
|
||||
public string InputFile { get; set; }
|
||||
}
|
||||
|
||||
[Verb("entropy", HelpText = "Calculates entropy and/or duplicated sectors of an image.")]
|
||||
public class EntropyOptions : CommonOptions
|
||||
{
|
||||
[Option('p', "duplicated-sectors", Default = true,
|
||||
HelpText =
|
||||
"Calculates how many sectors are duplicated (have same exact data in user area).")]
|
||||
public bool DuplicatedSectors { get; set; }
|
||||
|
||||
[Option('t', "separated-tracks", Default = true, HelpText = "Calculates entropy for each track separately.")]
|
||||
public bool SeparatedTracks { get; set; }
|
||||
|
||||
[Option('w', "whole-disc", Default = true, HelpText = "Calculates entropy for the whole disc.")]
|
||||
public bool WholeDisc { get; set; }
|
||||
|
||||
[Option('i', "input", Required = true, HelpText = "Disc image.")]
|
||||
public string InputFile { get; set; }
|
||||
}
|
||||
|
||||
[Verb("verify", HelpText = "Verifies a disc image integrity, and if supported, sector integrity.")]
|
||||
public class VerifyOptions : CommonOptions
|
||||
{
|
||||
[Option('w', "verify-disc", Default = true, HelpText = "Verify disc image if supported.")]
|
||||
public bool VerifyDisc { get; set; }
|
||||
|
||||
[Option('s', "verify-sectors", Default = true, HelpText = "Verify all sectors if supported.")]
|
||||
public bool VerifySectors { get; set; }
|
||||
|
||||
[Option('i', "input", Required = true, HelpText = "Disc image.")]
|
||||
public string InputFile { get; set; }
|
||||
}
|
||||
|
||||
[Verb("printhex", HelpText = "Prints a sector, in hexadecimal values, to the console.")]
|
||||
public class PrintHexOptions : CommonOptions
|
||||
{
|
||||
[Option('s', "start", Required = true, HelpText = "Start sector.")]
|
||||
public ulong StartSector { get; set; }
|
||||
|
||||
[Option('l', "length", Default = (ulong)1, HelpText = "How many sectors to print.")]
|
||||
public ulong Length { get; set; }
|
||||
|
||||
[Option('r', "long-sectors", Default = false, HelpText = "Print sectors with tags included.")]
|
||||
public bool LongSectors { get; set; }
|
||||
|
||||
[Option('w', "width", Default = (ushort)32, HelpText = "How many bytes to print per line.")]
|
||||
public ushort WidthBytes { get; set; }
|
||||
|
||||
[Option('i', "input", Required = true, HelpText = "Disc image.")]
|
||||
public string InputFile { get; set; }
|
||||
}
|
||||
|
||||
[Verb("decode", HelpText = "Decodes and pretty prints disk and/or sector tags.")]
|
||||
public class DecodeOptions : CommonOptions
|
||||
{
|
||||
[Option('s', "start", Default = (ulong)0, HelpText = "Start sector.")]
|
||||
public ulong StartSector { get; set; }
|
||||
|
||||
[Option('l', "length", Default = "all", HelpText = "How many sectors to decode, or \"all\".")]
|
||||
public string Length { get; set; }
|
||||
|
||||
[Option('k', "disk-tags", Default = true, HelpText = "Decode disk tags.")]
|
||||
public bool DiskTags { get; set; }
|
||||
|
||||
[Option('t', "sector-tags", Default = true, HelpText = "Decode sector tags.")]
|
||||
public bool SectorTags { get; set; }
|
||||
|
||||
[Option('i', "input", Required = true, HelpText = "Disc image.")]
|
||||
public string InputFile { get; set; }
|
||||
}
|
||||
|
||||
[Verb("device-info", HelpText = "Gets information about a device.")]
|
||||
public class DeviceInfoOptions : CommonOptions
|
||||
{
|
||||
[Option('i', "device", Required = true, HelpText = "Device path.")]
|
||||
public string DevicePath { get; set; }
|
||||
|
||||
[Option('w', "output-prefix", Required = false, Default = "",
|
||||
HelpText = "Write binary responses from device with that prefix.")]
|
||||
public string OutputPrefix { get; set; }
|
||||
}
|
||||
|
||||
[Verb("media-info", HelpText = "Gets information about the media inserted on a device.")]
|
||||
public class MediaInfoOptions : CommonOptions
|
||||
{
|
||||
[Option('i', "device", Required = true, HelpText = "Device path.")]
|
||||
public string DevicePath { get; set; }
|
||||
|
||||
[Option('w', "output-prefix", Required = false, Default = "",
|
||||
HelpText = "Write binary responses from device with that prefix.")]
|
||||
public string OutputPrefix { get; set; }
|
||||
}
|
||||
|
||||
[Verb("media-scan", HelpText = "Scans the media inserted on a device.")]
|
||||
public class MediaScanOptions : CommonOptions
|
||||
{
|
||||
[Option('i', "device", Required = true, HelpText = "Device path.")]
|
||||
public string DevicePath { get; set; }
|
||||
|
||||
[Option('m', "mhdd-log", Required = false, Default = "",
|
||||
HelpText = "Write a log of the scan in the format used by MHDD.")]
|
||||
public string MhddLogPath { get; set; }
|
||||
|
||||
[Option('b', "ibg-log", Required = false, Default = "",
|
||||
HelpText = "Write a log of the scan in the format used by ImgBurn.")]
|
||||
public string IbgLogPath { get; set; }
|
||||
}
|
||||
|
||||
[Verb("formats", HelpText = "Lists all supported disc images, partition schemes and file systems.")]
|
||||
public class FormatsOptions : CommonOptions { }
|
||||
|
||||
[Verb("benchmark", HelpText = "Benchmarks hashing and entropy calculation.")]
|
||||
public class BenchmarkOptions : CommonOptions
|
||||
{
|
||||
[Option('b', "block-size", Required = false, Default = 512, HelpText = "Block size.")]
|
||||
public int BlockSize { get; set; }
|
||||
|
||||
[Option('s', "buffer-size", Required = false, Default = 128, HelpText = "Buffer size in mebibytes.")]
|
||||
public int BufferSize { get; set; }
|
||||
}
|
||||
|
||||
[Verb("create-sidecar", HelpText = "Creates CICM Metadata XML sidecar.")]
|
||||
public class CreateSidecarOptions : CommonOptions
|
||||
{
|
||||
[Option('i', "input", Required = true, HelpText = "Disc image.")]
|
||||
public string InputFile { get; set; }
|
||||
[Option('t', "tape", Required = false, Default = false,
|
||||
HelpText =
|
||||
"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).")]
|
||||
public bool Tape { get; set; }
|
||||
[Option('b', "block-size", Required = false, Default = 512,
|
||||
HelpText =
|
||||
"Only used for tapes, indicates block size. Files in the folder whose size is not a multiple of this value will simply be ignored.")]
|
||||
public int BlockSize { get; set; }
|
||||
|
||||
[Option('e', "encoding", Default = null, HelpText = "Name of character encoding to use.")]
|
||||
public string EncodingName { get; set; }
|
||||
}
|
||||
|
||||
[Verb("dump-media", HelpText = "Dumps the media inserted on a device to a media image.")]
|
||||
public class DumpMediaOptions : CommonOptions
|
||||
{
|
||||
[Option('i', "device", Required = true, HelpText = "Device path.")]
|
||||
public string DevicePath { get; set; }
|
||||
|
||||
// TODO: Disabled temporarily
|
||||
/* [Option('r', "raw", Default = false,
|
||||
HelpText = "Dump sectors with tags included. For optical media, dump scrambled sectors")]
|
||||
public bool Raw { get; set; }*/
|
||||
|
||||
[Option('s', "stop-on-error", Default = false, HelpText = "Stop media dump on first error.")]
|
||||
public bool StopOnError { get; set; }
|
||||
|
||||
[Option('f', "force", Default = false, HelpText = "Continue dump whatever happens.")]
|
||||
public bool Force { get; set; }
|
||||
|
||||
[Option('p', "retry-passes", Default = (ushort)5, HelpText = "How many retry passes to do.")]
|
||||
public ushort RetryPasses { get; set; }
|
||||
|
||||
[Option("persistent", Default = false, HelpText = "Try to recover partial or incorrect data.")]
|
||||
public bool Persistent { get; set; }
|
||||
|
||||
[Option('m', "resume", Default = true, HelpText = "Create/use resume mapfile.")]
|
||||
public bool Resume { get; set; }
|
||||
|
||||
[Option("first-pregap", Default = false,
|
||||
HelpText = "Try to read first track pregap. Only applicable to CD/DDCD/GD.")]
|
||||
public bool FirstTrackPregap { get; set; }
|
||||
|
||||
[Option('e', "encoding", Default = null, HelpText = "Name of character encoding to use.")]
|
||||
public string EncodingName { get; set; }
|
||||
|
||||
[Option('o', "output", Required = true, HelpText = "Output image.")]
|
||||
public string OutputFile { get; set; }
|
||||
|
||||
[Option('t', "format", Default = null,
|
||||
HelpText =
|
||||
"Format of the output image, as plugin name or plugin id. If not present, will try to detect it from output image extension.")]
|
||||
public string OutputFormat { get; set; }
|
||||
|
||||
[Option('O', "options", Default = null,
|
||||
HelpText = "Comma separated name=value pairs of options to pass to output image plugin")]
|
||||
public string Options { get; set; }
|
||||
|
||||
[Option('x', "cicm-xml", Default = null, HelpText = "Take metadata from existing CICM XML sidecar.")]
|
||||
public string CicmXml { get; set; }
|
||||
|
||||
[Option('k', "skip", Default = 512, HelpText = "When an unreadable sector is found skip this many sectors.")]
|
||||
public int Skip { get; set; }
|
||||
|
||||
[Option("no-metadata", Default = false, HelpText = "Disables creating CICM XML sidecar.")]
|
||||
public bool NoMetadata { get; set; }
|
||||
|
||||
[Option("no-trim", Default = false, HelpText = "Disables trimming errored from skipped sectors.")]
|
||||
public bool NoTrim { get; set; }
|
||||
}
|
||||
|
||||
[Verb("device-report", HelpText = "Tests the device capabilities and creates an XML report of them.")]
|
||||
public class DeviceReportOptions : CommonOptions
|
||||
{
|
||||
[Option('i', "device", Required = true, HelpText = "Device path.")]
|
||||
public string DevicePath { get; set; }
|
||||
}
|
||||
|
||||
[Verb("configure", HelpText = "Configures user settings and statistics.")]
|
||||
public class ConfigureOptions { }
|
||||
|
||||
[Verb("stats", HelpText = "Shows statistics.")]
|
||||
public class StatsOptions { }
|
||||
|
||||
[Verb("ls", HelpText = "Lists files in disc image.")]
|
||||
public class LsOptions : CommonOptions
|
||||
{
|
||||
[Option('i', "input", Required = true, HelpText = "Disc image.")]
|
||||
public string InputFile { get; set; }
|
||||
|
||||
[Option('l', "long", Default = false, HelpText = "Uses long format.")]
|
||||
public bool Long { get; set; }
|
||||
|
||||
[Option('e', "encoding", Default = null, HelpText = "Name of character encoding to use.")]
|
||||
public string EncodingName { get; set; }
|
||||
|
||||
[Option('O', "options", Default = null,
|
||||
HelpText = "Comma separated name=value pairs of options to pass to filesystem plugin")]
|
||||
public string Options { get; set; }
|
||||
}
|
||||
|
||||
[Verb("extract-files", HelpText = "Extracts all files in disc image.")]
|
||||
public class ExtractFilesOptions : CommonOptions
|
||||
{
|
||||
[Option('i', "input", Required = true, HelpText = "Disc image.")]
|
||||
public string InputFile { get; set; }
|
||||
|
||||
[Option('o', "output", Required = true,
|
||||
HelpText = "Directory where extracted files will be created. Will abort if it exists.")]
|
||||
public string OutputDir { get; set; }
|
||||
|
||||
[Option('x', "xattrs", Default = false, HelpText = "Extract extended attributes if present.")]
|
||||
public bool Xattrs { get; set; }
|
||||
|
||||
[Option('e', "encoding", Default = null, HelpText = "Name of character encoding to use.")]
|
||||
public string EncodingName { get; set; }
|
||||
|
||||
[Option('O', "options", Default = null,
|
||||
HelpText = "Comma separated name=value pairs of options to pass to filesystem plugin")]
|
||||
public string Options { get; set; }
|
||||
}
|
||||
|
||||
[Verb("list-devices", HelpText = "Lists all connected devices.")]
|
||||
public class ListDevicesOptions : CommonOptions { }
|
||||
|
||||
[Verb("list-encodings", HelpText = "Lists all supported text encodings and code pages.")]
|
||||
public class ListEncodingsOptions : CommonOptions { }
|
||||
|
||||
[Verb("list-options", HelpText = "Lists all options supported by read-only filesystems and writable media images.")]
|
||||
public class ListOptionsOptions : CommonOptions { }
|
||||
|
||||
[Verb("convert-image", HelpText = "Converts one image to another format.")]
|
||||
public class ConvertImageOptions : CommonOptions
|
||||
{
|
||||
[Option('i', "input", Required = true, HelpText = "Input image.")]
|
||||
public string InputFile { get; set; }
|
||||
|
||||
[Option('o', "output", Required = true, HelpText = "Output image.")]
|
||||
public string OutputFile { get; set; }
|
||||
|
||||
[Option('p', "format", Default = null,
|
||||
HelpText =
|
||||
"Format of the output image, as plugin name or plugin id. If not present, will try to detect it from output image extension.")]
|
||||
public string OutputFormat { get; set; }
|
||||
|
||||
[Option('c', "count", Default = 64, HelpText = "How many sectors to convert at once.")]
|
||||
public int Count { get; set; }
|
||||
|
||||
[Option('f', "force", Default = false,
|
||||
HelpText =
|
||||
"Continue conversion even if sector or media tags will be lost in the process.")]
|
||||
public bool Force { get; set; }
|
||||
|
||||
[Option("creator", Default = null, HelpText = "Who (person) created the image?")]
|
||||
public string Creator { get; set; }
|
||||
[Option("media-title", Default = null, HelpText = "Title of the media represented by the image")]
|
||||
public string MediaTitle { get; set; }
|
||||
[Option("comments", Default = null, HelpText = "Image comments")]
|
||||
public string Comments { get; set; }
|
||||
[Option("media-manufacturer", Default = null, HelpText = "Manufacturer of the media represented by the image")]
|
||||
public string MediaManufacturer { get; set; }
|
||||
[Option("media-model", Default = null, HelpText = "Model of the media represented by the image")]
|
||||
public string MediaModel { get; set; }
|
||||
[Option("media-serial", Default = null, HelpText = "Serial number of the media represented by the image")]
|
||||
public string MediaSerialNumber { get; set; }
|
||||
[Option("media-barcode", Default = null, HelpText = "Barcode of the media represented by the image")]
|
||||
public string MediaBarcode { get; set; }
|
||||
[Option("media-partnumber", Default = null, HelpText = "Part number of the media represented by the image")]
|
||||
public string MediaPartNumber { get; set; }
|
||||
[Option("media-sequence", Default = 0, HelpText = "Number in sequence for the media represented by the image")]
|
||||
public int MediaSequence { get; set; }
|
||||
[Option("media-lastsequence", Default = 0,
|
||||
HelpText =
|
||||
"Last media of the sequence the media represented by the image corresponds to")]
|
||||
public int LastMediaSequence { get; set; }
|
||||
[Option("drive-manufacturer", Default = null,
|
||||
HelpText =
|
||||
"Manufacturer of the drive used to read the media represented by the image")]
|
||||
public string DriveManufacturer { get; set; }
|
||||
[Option("drive-model", Default = null,
|
||||
HelpText = "Model of the drive used to read the media represented by the image")]
|
||||
public string DriveModel { get; set; }
|
||||
[Option("drive-serial", Default = null,
|
||||
HelpText = "Serial number of the drive used to read the media represented by the image")]
|
||||
public string DriveSerialNumber { get; set; }
|
||||
[Option("drive-revision", Default = null,
|
||||
HelpText =
|
||||
"Firmware revision of the drive used to read the media represented by the image")]
|
||||
public string DriveFirmwareRevision { get; set; }
|
||||
|
||||
[Option('O', "options", Default = null,
|
||||
HelpText = "Comma separated name=value pairs of options to pass to output image plugin")]
|
||||
public string Options { get; set; }
|
||||
|
||||
[Option('x', "cicm-xml", Default = null, HelpText = "Take metadata from existing CICM XML sidecar.")]
|
||||
public string CicmXml { get; set; }
|
||||
|
||||
[Option('r', "resume-file", Default = null, HelpText = "Take list of dump hardware from existing resume file.")]
|
||||
public string ResumeFile { get; set; }
|
||||
}
|
||||
|
||||
[Verb("image-info", HelpText =
|
||||
"Opens a media image and shows information about the media it represents and metadata.")]
|
||||
public class ImageInfoOptions : CommonOptions
|
||||
{
|
||||
[Option('i', "input", Required = true, HelpText = "Media image.")]
|
||||
public string InputFile { get; set; }
|
||||
}
|
||||
|
||||
[Verb("gui", HelpText = "Opens the in-progress GUI.")]
|
||||
public class GuiOptions : CommonOptions { }
|
||||
|
||||
[Verb("update", HelpText = "Updates the database.")]
|
||||
public class UpdateOptions : CommonOptions { }
|
||||
}
|
||||
Reference in New Issue
Block a user