mirror of
https://github.com/aaru-dps/Aaru.git
synced 2025-12-16 19:24:25 +00:00
Replace Mono.Options with System.CommandLine
This commit is contained in:
@@ -186,8 +186,11 @@
|
|||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=ATAPI/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=ATAPI/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=ATIP/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=ATIP/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=BANDAI/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=BANDAI/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=bitsetting/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Bluray/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Bluray/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=cartstatus/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=CDDA/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=CDDA/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=cdtext/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=CDTV/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=CDTV/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=cdrom/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=cdrom/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=certance/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=certance/@EntryIndexedValue">True</s:Boolean>
|
||||||
@@ -196,20 +199,39 @@
|
|||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=cicm/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=cicm/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Claunia/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Claunia/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=DDCD/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=DDCD/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=dicremote/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Drive_0027s/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Drive_0027s/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=dvdr/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=dvdram/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=ecsd/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=eeprom/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=EVPD/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=EVPD/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=formatlayers/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=getconfiguration/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=hddvd/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=hddvdr/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Hldtst/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Hldtst/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=iomega/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=iomega/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=isrc/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=isrc/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Kreon/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Kreon/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=lastrmd/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=lastsequence/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=layercap/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Lbas/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=leadout/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=leadout/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=manuallj/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=mapfile/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=mediaid/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=mediaserialnumber/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=mhdd/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=mhdd/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=mhddlog/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=mhddlog/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=milcd/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=milcd/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=MINIX/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=MINIX/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=modesense/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=NTFS/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=NTFS/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=NTSC/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=NTSC/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Nuon/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Nuon/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Nvme/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=opticals/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=opticals/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=PCMCIA/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=PCMCIA/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Plextor/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Plextor/@EntryIndexedValue">True</s:Boolean>
|
||||||
@@ -219,18 +241,34 @@
|
|||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Plextor/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Plextor/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=pmin/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=pmin/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Portillo/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Portillo/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Powe/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=pregap/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=pregap/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=pregaps/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=pregaps/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=printhex/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=psec/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=psec/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=rawtoc/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=readblocklimits/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=readcapacity/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=readcd/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=readcd/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=readdiscinformation/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=readdiscstructure/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Recordables/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Recordables/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Reiser/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Reiser/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=remapanchor/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=reportdensitysupport/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=SDHCI/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=SDHCI/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Secu/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=spamsum/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=subchannels/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=subchannels/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=subpages/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=subpages/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=subchannel/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=subchannel/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=subchannels/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=subchannels/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=umounting/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=umounting/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=undecoded/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Vari/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=writeprotection/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Wxripper/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Wxripper/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=xattr/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=xattrs/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=xeto/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=xeto/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Xtreme/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Xtreme/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
|
||||||
@@ -32,104 +32,103 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.CommandLine;
|
||||||
|
using System.CommandLine.Invocation;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using DiscImageChef.CommonTypes;
|
using DiscImageChef.CommonTypes;
|
||||||
using DiscImageChef.CommonTypes.Enums;
|
using DiscImageChef.CommonTypes.Enums;
|
||||||
using DiscImageChef.CommonTypes.Interfaces;
|
using DiscImageChef.CommonTypes.Interfaces;
|
||||||
using DiscImageChef.Console;
|
using DiscImageChef.Console;
|
||||||
using DiscImageChef.Core;
|
using DiscImageChef.Core;
|
||||||
using Mono.Options;
|
|
||||||
|
|
||||||
namespace DiscImageChef.Commands
|
namespace DiscImageChef.Commands
|
||||||
{
|
{
|
||||||
class AnalyzeCommand : Command
|
internal class AnalyzeCommand : Command
|
||||||
{
|
{
|
||||||
string encodingName;
|
|
||||||
string inputFile;
|
|
||||||
bool searchForFilesystems = true;
|
|
||||||
bool searchForPartitions = true;
|
|
||||||
bool showHelp;
|
|
||||||
|
|
||||||
public AnalyzeCommand() : base("analyze",
|
public AnalyzeCommand() : base("analyze",
|
||||||
"Analyzes a disc image and searches for partitions and/or filesystems.")
|
"Analyzes a disc image and searches for partitions and/or filesystems.")
|
||||||
{
|
{
|
||||||
Options = new OptionSet
|
Add(new Option(new[]
|
||||||
{
|
{
|
||||||
$"{MainClass.AssemblyTitle} {MainClass.AssemblyVersion?.InformationalVersion}",
|
"--encoding", "-e"
|
||||||
$"{MainClass.AssemblyCopyright}",
|
}, "Name of character encoding to use.")
|
||||||
"",
|
{
|
||||||
$"usage: DiscImageChef {Name} [OPTIONS] imagefile",
|
Argument = new Argument<string>(() => null), Required = false
|
||||||
"",
|
});
|
||||||
Help,
|
|
||||||
{"encoding|e=", "Name of character encoding to use.", s => encodingName = s},
|
Add(new Option(new[]
|
||||||
{"filesystems|f", "Searches and analyzes filesystems.", b => searchForFilesystems = b != null},
|
{
|
||||||
{"partitions|p", "Searches and interprets partitions.", b => searchForPartitions = b != null},
|
"--filesystems", "-f"
|
||||||
{"help|h|?", "Show this message and exit.", v => showHelp = v != null}
|
}, "Searches and analyzes filesystems.")
|
||||||
};
|
{
|
||||||
|
Argument = new Argument<bool>(() => true), Required = false
|
||||||
|
});
|
||||||
|
|
||||||
|
Add(new Option(new[]
|
||||||
|
{
|
||||||
|
"--partitions", "-p"
|
||||||
|
}, "Searches and interprets partitions.")
|
||||||
|
{
|
||||||
|
Argument = new Argument<bool>(() => true), Required = false
|
||||||
|
});
|
||||||
|
|
||||||
|
AddArgument(new Argument<string>
|
||||||
|
{
|
||||||
|
Arity = ArgumentArity.ExactlyOne, Description = "Disc image path", Name = "image-path"
|
||||||
|
});
|
||||||
|
|
||||||
|
Handler = CommandHandler.Create(GetType().GetMethod(nameof(Invoke)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override int Invoke(IEnumerable<string> arguments)
|
int Invoke(bool verbose, bool debug, string encoding, bool filesystems, bool partitions, string imagePath)
|
||||||
{
|
{
|
||||||
List<string> extra = Options.Parse(arguments);
|
|
||||||
|
|
||||||
if(showHelp)
|
|
||||||
{
|
|
||||||
Options.WriteOptionDescriptions(CommandSet.Out);
|
|
||||||
return (int)ErrorNumber.HelpRequested;
|
|
||||||
}
|
|
||||||
|
|
||||||
MainClass.PrintCopyright();
|
MainClass.PrintCopyright();
|
||||||
if(MainClass.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
|
||||||
if(MainClass.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
if(debug)
|
||||||
|
DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
||||||
|
|
||||||
|
if(verbose)
|
||||||
|
DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
||||||
|
|
||||||
Statistics.AddCommand("analyze");
|
Statistics.AddCommand("analyze");
|
||||||
|
|
||||||
if(extra.Count > 1)
|
DicConsole.DebugWriteLine("Analyze command", "--debug={0}", debug);
|
||||||
{
|
DicConsole.DebugWriteLine("Analyze command", "--encoding={0}", encoding);
|
||||||
DicConsole.ErrorWriteLine("Too many arguments.");
|
DicConsole.DebugWriteLine("Analyze command", "--filesystems={0}", filesystems);
|
||||||
return (int)ErrorNumber.UnexpectedArgumentCount;
|
DicConsole.DebugWriteLine("Analyze command", "--input={0}", imagePath);
|
||||||
}
|
DicConsole.DebugWriteLine("Analyze command", "--partitions={0}", partitions);
|
||||||
|
DicConsole.DebugWriteLine("Analyze command", "--verbose={0}", verbose);
|
||||||
|
|
||||||
if(extra.Count == 0)
|
var filtersList = new FiltersList();
|
||||||
{
|
IFilter inputFilter = filtersList.GetFilter(imagePath);
|
||||||
DicConsole.ErrorWriteLine("Missing input image.");
|
|
||||||
return (int)ErrorNumber.MissingArgument;
|
|
||||||
}
|
|
||||||
|
|
||||||
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(inputFile);
|
|
||||||
|
|
||||||
if(inputFilter == null)
|
if(inputFilter == null)
|
||||||
{
|
{
|
||||||
DicConsole.ErrorWriteLine("Cannot open specified file.");
|
DicConsole.ErrorWriteLine("Cannot open specified file.");
|
||||||
return (int)ErrorNumber.CannotOpenFile;
|
|
||||||
|
return(int)ErrorNumber.CannotOpenFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
Encoding encoding = null;
|
Encoding encodingClass = null;
|
||||||
|
|
||||||
if(encodingName != null)
|
if(encoding != null)
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
encoding = Claunia.Encoding.Encoding.GetEncoding(encodingName);
|
encodingClass = Claunia.Encoding.Encoding.GetEncoding(encoding);
|
||||||
if(MainClass.Verbose) DicConsole.VerboseWriteLine("Using encoding for {0}.", encoding.EncodingName);
|
|
||||||
|
if(verbose)
|
||||||
|
DicConsole.VerboseWriteLine("Using encoding for {0}.", encodingClass.EncodingName);
|
||||||
}
|
}
|
||||||
catch(ArgumentException)
|
catch(ArgumentException)
|
||||||
{
|
{
|
||||||
DicConsole.ErrorWriteLine("Specified encoding is not supported.");
|
DicConsole.ErrorWriteLine("Specified encoding is not supported.");
|
||||||
return (int)ErrorNumber.EncodingUnknown;
|
|
||||||
|
return(int)ErrorNumber.EncodingUnknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
PluginBase plugins = GetPluginBase.Instance;
|
PluginBase plugins = GetPluginBase.Instance;
|
||||||
|
|
||||||
bool checkraw = false;
|
bool checkRaw = false;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -138,13 +137,16 @@ namespace DiscImageChef.Commands
|
|||||||
if(imageFormat == null)
|
if(imageFormat == null)
|
||||||
{
|
{
|
||||||
DicConsole.WriteLine("Image format not identified, not proceeding with analysis.");
|
DicConsole.WriteLine("Image format not identified, not proceeding with analysis.");
|
||||||
return (int)ErrorNumber.UnrecognizedFormat;
|
|
||||||
|
return(int)ErrorNumber.UnrecognizedFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(MainClass.Verbose)
|
if(verbose)
|
||||||
DicConsole.VerboseWriteLine("Image format identified by {0} ({1}).", imageFormat.Name,
|
DicConsole.VerboseWriteLine("Image format identified by {0} ({1}).", imageFormat.Name,
|
||||||
imageFormat.Id);
|
imageFormat.Id);
|
||||||
else DicConsole.WriteLine("Image format identified by {0}.", imageFormat.Name);
|
else
|
||||||
|
DicConsole.WriteLine("Image format identified by {0}.", imageFormat.Name);
|
||||||
|
|
||||||
DicConsole.WriteLine();
|
DicConsole.WriteLine();
|
||||||
|
|
||||||
try
|
try
|
||||||
@@ -153,10 +155,11 @@ namespace DiscImageChef.Commands
|
|||||||
{
|
{
|
||||||
DicConsole.WriteLine("Unable to open image format");
|
DicConsole.WriteLine("Unable to open image format");
|
||||||
DicConsole.WriteLine("No error given");
|
DicConsole.WriteLine("No error given");
|
||||||
return (int)ErrorNumber.CannotOpenFormat;
|
|
||||||
|
return(int)ErrorNumber.CannotOpenFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(MainClass.Verbose)
|
if(verbose)
|
||||||
{
|
{
|
||||||
ImageInfo.PrintImageInfo(imageFormat);
|
ImageInfo.PrintImageInfo(imageFormat);
|
||||||
DicConsole.WriteLine();
|
DicConsole.WriteLine();
|
||||||
@@ -171,52 +174,62 @@ namespace DiscImageChef.Commands
|
|||||||
DicConsole.ErrorWriteLine("Unable to open image format");
|
DicConsole.ErrorWriteLine("Unable to open image format");
|
||||||
DicConsole.ErrorWriteLine("Error: {0}", ex.Message);
|
DicConsole.ErrorWriteLine("Error: {0}", ex.Message);
|
||||||
DicConsole.DebugWriteLine("Analyze command", "Stack trace: {0}", ex.StackTrace);
|
DicConsole.DebugWriteLine("Analyze command", "Stack trace: {0}", ex.StackTrace);
|
||||||
return (int)ErrorNumber.CannotOpenFormat;
|
|
||||||
|
return(int)ErrorNumber.CannotOpenFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<string> idPlugins;
|
List<string> idPlugins;
|
||||||
IFilesystem plugin;
|
IFilesystem plugin;
|
||||||
string information;
|
string information;
|
||||||
if(searchForPartitions)
|
|
||||||
{
|
|
||||||
List<Partition> partitions = Core.Partitions.GetAll(imageFormat);
|
|
||||||
Core.Partitions.AddSchemesToStats(partitions);
|
|
||||||
|
|
||||||
if(partitions.Count == 0)
|
if(partitions)
|
||||||
|
{
|
||||||
|
List<Partition> partitionsList = Core.Partitions.GetAll(imageFormat);
|
||||||
|
Core.Partitions.AddSchemesToStats(partitionsList);
|
||||||
|
|
||||||
|
if(partitionsList.Count == 0)
|
||||||
{
|
{
|
||||||
DicConsole.DebugWriteLine("Analyze command", "No partitions found");
|
DicConsole.DebugWriteLine("Analyze command", "No partitions found");
|
||||||
if(!searchForFilesystems)
|
|
||||||
|
if(!filesystems)
|
||||||
{
|
{
|
||||||
DicConsole.WriteLine("No partitions founds, not searching for filesystems");
|
DicConsole.WriteLine("No partitions founds, not searching for filesystems");
|
||||||
return (int)ErrorNumber.NothingFound;
|
|
||||||
|
return(int)ErrorNumber.NothingFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
checkraw = true;
|
checkRaw = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DicConsole.WriteLine("{0} partitions found.", partitions.Count);
|
DicConsole.WriteLine("{0} partitions found.", partitionsList.Count);
|
||||||
|
|
||||||
for(int i = 0; i < partitions.Count; i++)
|
for(int i = 0; i < partitionsList.Count; i++)
|
||||||
{
|
{
|
||||||
DicConsole.WriteLine();
|
DicConsole.WriteLine();
|
||||||
DicConsole.WriteLine("Partition {0}:", partitions[i].Sequence);
|
DicConsole.WriteLine("Partition {0}:", partitionsList[i].Sequence);
|
||||||
DicConsole.WriteLine("Partition name: {0}", partitions[i].Name);
|
DicConsole.WriteLine("Partition name: {0}", partitionsList[i].Name);
|
||||||
DicConsole.WriteLine("Partition type: {0}", partitions[i].Type);
|
DicConsole.WriteLine("Partition type: {0}", partitionsList[i].Type);
|
||||||
DicConsole.WriteLine("Partition start: sector {0}, byte {1}", partitions[i].Start,
|
|
||||||
partitions[i].Offset);
|
|
||||||
DicConsole.WriteLine("Partition length: {0} sectors, {1} bytes", partitions[i].Length,
|
|
||||||
partitions[i].Size);
|
|
||||||
DicConsole.WriteLine("Partition scheme: {0}", partitions[i].Scheme);
|
|
||||||
DicConsole.WriteLine("Partition description:");
|
|
||||||
DicConsole.WriteLine(partitions[i].Description);
|
|
||||||
|
|
||||||
if(!searchForFilesystems) continue;
|
DicConsole.WriteLine("Partition start: sector {0}, byte {1}", partitionsList[i].Start,
|
||||||
|
partitionsList[i].Offset);
|
||||||
|
|
||||||
|
DicConsole.WriteLine("Partition length: {0} sectors, {1} bytes", partitionsList[i].Length,
|
||||||
|
partitionsList[i].Size);
|
||||||
|
|
||||||
|
DicConsole.WriteLine("Partition scheme: {0}", partitionsList[i].Scheme);
|
||||||
|
DicConsole.WriteLine("Partition description:");
|
||||||
|
DicConsole.WriteLine(partitionsList[i].Description);
|
||||||
|
|
||||||
|
if(!filesystems)
|
||||||
|
continue;
|
||||||
|
|
||||||
DicConsole.WriteLine("Identifying filesystem on partition");
|
DicConsole.WriteLine("Identifying filesystem on partition");
|
||||||
|
|
||||||
Core.Filesystems.Identify(imageFormat, out idPlugins, partitions[i]);
|
Core.Filesystems.Identify(imageFormat, out idPlugins, partitionsList[i]);
|
||||||
if(idPlugins.Count == 0) DicConsole.WriteLine("Filesystem not identified");
|
|
||||||
|
if(idPlugins.Count == 0)
|
||||||
|
DicConsole.WriteLine("Filesystem not identified");
|
||||||
else if(idPlugins.Count > 1)
|
else if(idPlugins.Count > 1)
|
||||||
{
|
{
|
||||||
DicConsole.WriteLine($"Identified by {idPlugins.Count} plugins");
|
DicConsole.WriteLine($"Identified by {idPlugins.Count} plugins");
|
||||||
@@ -225,7 +238,10 @@ namespace DiscImageChef.Commands
|
|||||||
if(plugins.PluginsList.TryGetValue(pluginName, out plugin))
|
if(plugins.PluginsList.TryGetValue(pluginName, out plugin))
|
||||||
{
|
{
|
||||||
DicConsole.WriteLine($"As identified by {plugin.Name}.");
|
DicConsole.WriteLine($"As identified by {plugin.Name}.");
|
||||||
plugin.GetInformation(imageFormat, partitions[i], out information, encoding);
|
|
||||||
|
plugin.GetInformation(imageFormat, partitionsList[i], out information,
|
||||||
|
encodingClass);
|
||||||
|
|
||||||
DicConsole.Write(information);
|
DicConsole.Write(information);
|
||||||
Statistics.AddFilesystem(plugin.XmlFsType.Type);
|
Statistics.AddFilesystem(plugin.XmlFsType.Type);
|
||||||
}
|
}
|
||||||
@@ -233,10 +249,12 @@ namespace DiscImageChef.Commands
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
plugins.PluginsList.TryGetValue(idPlugins[0], out plugin);
|
plugins.PluginsList.TryGetValue(idPlugins[0], out plugin);
|
||||||
if(plugin == null) continue;
|
|
||||||
|
if(plugin == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
DicConsole.WriteLine($"Identified by {plugin.Name}.");
|
DicConsole.WriteLine($"Identified by {plugin.Name}.");
|
||||||
plugin.GetInformation(imageFormat, partitions[i], out information, encoding);
|
plugin.GetInformation(imageFormat, partitionsList[i], out information, encodingClass);
|
||||||
DicConsole.Write("{0}", information);
|
DicConsole.Write("{0}", information);
|
||||||
Statistics.AddFilesystem(plugin.XmlFsType.Type);
|
Statistics.AddFilesystem(plugin.XmlFsType.Type);
|
||||||
}
|
}
|
||||||
@@ -244,17 +262,18 @@ namespace DiscImageChef.Commands
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(checkraw)
|
if(checkRaw)
|
||||||
{
|
{
|
||||||
Partition wholePart = new Partition
|
var wholePart = new Partition
|
||||||
{
|
{
|
||||||
Name = "Whole device",
|
Name = "Whole device", Length = imageFormat.Info.Sectors,
|
||||||
Length = imageFormat.Info.Sectors,
|
|
||||||
Size = imageFormat.Info.Sectors * imageFormat.Info.SectorSize
|
Size = imageFormat.Info.Sectors * imageFormat.Info.SectorSize
|
||||||
};
|
};
|
||||||
|
|
||||||
Core.Filesystems.Identify(imageFormat, out idPlugins, wholePart);
|
Core.Filesystems.Identify(imageFormat, out idPlugins, wholePart);
|
||||||
if(idPlugins.Count == 0) DicConsole.WriteLine("Filesystem not identified");
|
|
||||||
|
if(idPlugins.Count == 0)
|
||||||
|
DicConsole.WriteLine("Filesystem not identified");
|
||||||
else if(idPlugins.Count > 1)
|
else if(idPlugins.Count > 1)
|
||||||
{
|
{
|
||||||
DicConsole.WriteLine($"Identified by {idPlugins.Count} plugins");
|
DicConsole.WriteLine($"Identified by {idPlugins.Count} plugins");
|
||||||
@@ -263,7 +282,7 @@ namespace DiscImageChef.Commands
|
|||||||
if(plugins.PluginsList.TryGetValue(pluginName, out plugin))
|
if(plugins.PluginsList.TryGetValue(pluginName, out plugin))
|
||||||
{
|
{
|
||||||
DicConsole.WriteLine($"As identified by {plugin.Name}.");
|
DicConsole.WriteLine($"As identified by {plugin.Name}.");
|
||||||
plugin.GetInformation(imageFormat, wholePart, out information, encoding);
|
plugin.GetInformation(imageFormat, wholePart, out information, encodingClass);
|
||||||
DicConsole.Write(information);
|
DicConsole.Write(information);
|
||||||
Statistics.AddFilesystem(plugin.XmlFsType.Type);
|
Statistics.AddFilesystem(plugin.XmlFsType.Type);
|
||||||
}
|
}
|
||||||
@@ -271,10 +290,11 @@ namespace DiscImageChef.Commands
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
plugins.PluginsList.TryGetValue(idPlugins[0], out plugin);
|
plugins.PluginsList.TryGetValue(idPlugins[0], out plugin);
|
||||||
|
|
||||||
if(plugin != null)
|
if(plugin != null)
|
||||||
{
|
{
|
||||||
DicConsole.WriteLine($"Identified by {plugin.Name}.");
|
DicConsole.WriteLine($"Identified by {plugin.Name}.");
|
||||||
plugin.GetInformation(imageFormat, wholePart, out information, encoding);
|
plugin.GetInformation(imageFormat, wholePart, out information, encodingClass);
|
||||||
DicConsole.Write(information);
|
DicConsole.Write(information);
|
||||||
Statistics.AddFilesystem(plugin.XmlFsType.Type);
|
Statistics.AddFilesystem(plugin.XmlFsType.Type);
|
||||||
}
|
}
|
||||||
@@ -285,10 +305,11 @@ namespace DiscImageChef.Commands
|
|||||||
{
|
{
|
||||||
DicConsole.ErrorWriteLine($"Error reading file: {ex.Message}");
|
DicConsole.ErrorWriteLine($"Error reading file: {ex.Message}");
|
||||||
DicConsole.DebugWriteLine("Analyze command", ex.StackTrace);
|
DicConsole.DebugWriteLine("Analyze command", ex.StackTrace);
|
||||||
return (int)ErrorNumber.UnexpectedException;
|
|
||||||
|
return(int)ErrorNumber.UnexpectedException;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (int)ErrorNumber.NoError;
|
return(int)ErrorNumber.NoError;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -31,58 +31,56 @@
|
|||||||
// ****************************************************************************/
|
// ****************************************************************************/
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.CommandLine;
|
||||||
|
using System.CommandLine.Invocation;
|
||||||
using DiscImageChef.CommonTypes.Enums;
|
using DiscImageChef.CommonTypes.Enums;
|
||||||
using DiscImageChef.Console;
|
using DiscImageChef.Console;
|
||||||
using DiscImageChef.Core;
|
using DiscImageChef.Core;
|
||||||
using Mono.Options;
|
|
||||||
|
|
||||||
namespace DiscImageChef.Commands
|
namespace DiscImageChef.Commands
|
||||||
{
|
{
|
||||||
class BenchmarkCommand : Command
|
internal class BenchmarkCommand : Command
|
||||||
{
|
{
|
||||||
int blockSize = 512;
|
|
||||||
int bufferSize = 128;
|
|
||||||
bool showHelp;
|
|
||||||
|
|
||||||
public BenchmarkCommand() : base("benchmark", "Benchmarks hashing and entropy calculation.")
|
public BenchmarkCommand() : base("benchmark", "Benchmarks hashing and entropy calculation.")
|
||||||
{
|
{
|
||||||
Options = new OptionSet
|
Add(new Option(new[]
|
||||||
{
|
{
|
||||||
$"{MainClass.AssemblyTitle} {MainClass.AssemblyVersion?.InformationalVersion}",
|
"--block-size", "-b"
|
||||||
$"{MainClass.AssemblyCopyright}",
|
}, "Block size.")
|
||||||
"",
|
{
|
||||||
$"usage: DiscImageChef {Name} [OPTIONS]",
|
Argument = new Argument<int>(() => 512), Required = false
|
||||||
"",
|
});
|
||||||
Help,
|
|
||||||
{"block-size|b=", "Block size.", (int i) => blockSize = i},
|
Add(new Option(new[]
|
||||||
{"buffer-size|s=", "Buffer size in mebibytes.", (int i) => bufferSize = i},
|
{
|
||||||
{"help|h|?", "Show this message and exit.", v => showHelp = v != null}
|
"--buffer-size", "-s"
|
||||||
};
|
}, "Buffer size in mebibytes.")
|
||||||
|
{
|
||||||
|
Argument = new Argument<int>(() => 128), Required = false
|
||||||
|
});
|
||||||
|
|
||||||
|
AddArgument(new Argument<string>
|
||||||
|
{
|
||||||
|
Arity = ArgumentArity.ExactlyOne, Description = "Disc image path", Name = "image-path"
|
||||||
|
});
|
||||||
|
|
||||||
|
Handler = CommandHandler.Create(GetType().GetMethod(nameof(Invoke)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override int Invoke(IEnumerable<string> arguments)
|
static int Invoke(bool debug, bool verbose, int blockSize, int bufferSize)
|
||||||
{
|
{
|
||||||
List<string> extra = Options.Parse(arguments);
|
|
||||||
|
|
||||||
if(showHelp)
|
|
||||||
{
|
|
||||||
Options.WriteOptionDescriptions(CommandSet.Out);
|
|
||||||
return (int)ErrorNumber.HelpRequested;
|
|
||||||
}
|
|
||||||
|
|
||||||
MainClass.PrintCopyright();
|
MainClass.PrintCopyright();
|
||||||
if(MainClass.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
|
||||||
if(MainClass.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
if(debug)
|
||||||
|
DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
||||||
|
|
||||||
|
if(verbose)
|
||||||
|
DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
||||||
|
|
||||||
Statistics.AddCommand("benchmark");
|
Statistics.AddCommand("benchmark");
|
||||||
|
|
||||||
if(extra.Count != 0)
|
DicConsole.DebugWriteLine("Benchmark command", "--debug={0}", debug);
|
||||||
{
|
DicConsole.DebugWriteLine("Benchmark command", "--verbose={0}", verbose);
|
||||||
DicConsole.ErrorWriteLine("Too many arguments.");
|
|
||||||
return (int)ErrorNumber.UnexpectedArgumentCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
DicConsole.DebugWriteLine("Benchmark command", "--debug={0}", MainClass.Debug);
|
|
||||||
DicConsole.DebugWriteLine("Benchmark command", "--verbose={0}", MainClass.Verbose);
|
|
||||||
|
|
||||||
Benchmark.InitProgressEvent += Progress.InitProgress;
|
Benchmark.InitProgressEvent += Progress.InitProgress;
|
||||||
Benchmark.UpdateProgressEvent += Progress.UpdateProgress;
|
Benchmark.UpdateProgressEvent += Progress.UpdateProgress;
|
||||||
@@ -92,8 +90,10 @@ namespace DiscImageChef.Commands
|
|||||||
|
|
||||||
DicConsole.WriteLine("Took {0} seconds to fill buffer, {1:F3} MiB/sec.", results.FillTime,
|
DicConsole.WriteLine("Took {0} seconds to fill buffer, {1:F3} MiB/sec.", results.FillTime,
|
||||||
results.FillSpeed);
|
results.FillSpeed);
|
||||||
|
|
||||||
DicConsole.WriteLine("Took {0} seconds to read buffer, {1:F3} MiB/sec.", results.ReadTime,
|
DicConsole.WriteLine("Took {0} seconds to read buffer, {1:F3} MiB/sec.", results.ReadTime,
|
||||||
results.ReadSpeed);
|
results.ReadSpeed);
|
||||||
|
|
||||||
DicConsole.WriteLine("Took {0} seconds to entropy buffer, {1:F3} MiB/sec.", results.EntropyTime,
|
DicConsole.WriteLine("Took {0} seconds to entropy buffer, {1:F3} MiB/sec.", results.EntropyTime,
|
||||||
results.EntropySpeed);
|
results.EntropySpeed);
|
||||||
|
|
||||||
@@ -103,6 +103,7 @@ namespace DiscImageChef.Commands
|
|||||||
|
|
||||||
DicConsole.WriteLine("Took {0} seconds to do all algorithms at the same time, {1:F3} MiB/sec.",
|
DicConsole.WriteLine("Took {0} seconds to do all algorithms at the same time, {1:F3} MiB/sec.",
|
||||||
results.TotalTime, results.TotalSpeed);
|
results.TotalTime, results.TotalSpeed);
|
||||||
|
|
||||||
DicConsole.WriteLine("Took {0} seconds to do all algorithms sequentially, {1:F3} MiB/sec.",
|
DicConsole.WriteLine("Took {0} seconds to do all algorithms sequentially, {1:F3} MiB/sec.",
|
||||||
results.SeparateTime, results.SeparateSpeed);
|
results.SeparateTime, results.SeparateSpeed);
|
||||||
|
|
||||||
@@ -110,7 +111,7 @@ namespace DiscImageChef.Commands
|
|||||||
DicConsole.WriteLine("Max memory used is {0} bytes", results.MaxMemory);
|
DicConsole.WriteLine("Max memory used is {0} bytes", results.MaxMemory);
|
||||||
DicConsole.WriteLine("Min memory used is {0} bytes", results.MinMemory);
|
DicConsole.WriteLine("Min memory used is {0} bytes", results.MinMemory);
|
||||||
|
|
||||||
return (int)ErrorNumber.NoError;
|
return(int)ErrorNumber.NoError;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -32,121 +32,167 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.CommandLine;
|
||||||
|
using System.CommandLine.Invocation;
|
||||||
using DiscImageChef.CommonTypes;
|
using DiscImageChef.CommonTypes;
|
||||||
using DiscImageChef.CommonTypes.Enums;
|
using DiscImageChef.CommonTypes.Enums;
|
||||||
using DiscImageChef.CommonTypes.Interfaces;
|
using DiscImageChef.CommonTypes.Interfaces;
|
||||||
using DiscImageChef.CommonTypes.Structs;
|
using DiscImageChef.CommonTypes.Structs;
|
||||||
using DiscImageChef.Console;
|
using DiscImageChef.Console;
|
||||||
using DiscImageChef.Core;
|
using DiscImageChef.Core;
|
||||||
using Mono.Options;
|
|
||||||
using Schemas;
|
using Schemas;
|
||||||
|
|
||||||
namespace DiscImageChef.Commands
|
namespace DiscImageChef.Commands
|
||||||
{
|
{
|
||||||
class ChecksumCommand : Command
|
internal class ChecksumCommand : Command
|
||||||
{
|
{
|
||||||
// How many sectors to read at once
|
// How many sectors to read at once
|
||||||
const uint SECTORS_TO_READ = 256;
|
const uint SECTORS_TO_READ = 256;
|
||||||
|
|
||||||
bool doAdler32 = true;
|
|
||||||
bool doCrc16 = true;
|
|
||||||
bool doCrc32 = true;
|
|
||||||
bool doCrc64;
|
|
||||||
bool doFletcher16;
|
|
||||||
bool doFletcher32;
|
|
||||||
bool doMd5 = true;
|
|
||||||
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.")
|
public ChecksumCommand() : base("checksum", "Checksums an image.")
|
||||||
{
|
{
|
||||||
Options = new OptionSet
|
Add(new Option(new[]
|
||||||
{
|
{
|
||||||
$"{MainClass.AssemblyTitle} {MainClass.AssemblyVersion?.InformationalVersion}",
|
"--adler32", "-a"
|
||||||
$"{MainClass.AssemblyCopyright}",
|
}, "Calculates Adler32.")
|
||||||
"",
|
{
|
||||||
$"usage: DiscImageChef {Name} [OPTIONS] imagefile",
|
Argument = new Argument<bool>(() => true), Required = false
|
||||||
"",
|
});
|
||||||
Help,
|
|
||||||
{"adler32|a", "Calculates Adler-32.", b => doAdler32 = b != null},
|
Add(new Option("--crc16", "Calculates CRC16.")
|
||||||
{"crc16", "Calculates CRC16.", b => doCrc16 = b != null},
|
{
|
||||||
{"crc32|c", "Calculates CRC32.", b => doCrc32 = b != null},
|
Argument = new Argument<bool>(() => true), Required = false
|
||||||
{"crc64", "Calculates CRC64 (ECMA).", b => doCrc64 = b != null},
|
});
|
||||||
{"fletcher16", "Calculates Fletcher-16.", b => doFletcher16 = b != null},
|
|
||||||
{"fletcher32", "Calculates Fletcher-32.", b => doFletcher32 = b != null},
|
Add(new Option(new[]
|
||||||
{"md5|m", "Calculates MD5.", b => doMd5 = b != null},
|
{
|
||||||
{"separated-tracks|t", "Checksums each track separately.", b => separatedTracks = b != null},
|
"--crc32", "-c"
|
||||||
{"sha1|s", "Calculates SHA1.", b => doSha1 = b != null},
|
}, "Calculates CRC32.")
|
||||||
{"sha256", "Calculates SHA256.", b => doSha256 = b != null},
|
{
|
||||||
{"sha384", "Calculates SHA384.", b => doSha384 = b != null},
|
Argument = new Argument<bool>(() => true), Required = false
|
||||||
{"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},
|
Add(new Option("--crc64", "Calculates CRC64.")
|
||||||
{"help|h|?", "Show this message and exit.", v => showHelp = v != null}
|
{
|
||||||
};
|
Argument = new Argument<bool>(() => true), Required = false
|
||||||
|
});
|
||||||
|
|
||||||
|
Add(new Option("--fletcher16", "Calculates Fletcher-16.")
|
||||||
|
{
|
||||||
|
Argument = new Argument<bool>(() => true), Required = false
|
||||||
|
});
|
||||||
|
|
||||||
|
Add(new Option("--fletcher32", "Calculates Fletcher-32.")
|
||||||
|
{
|
||||||
|
Argument = new Argument<bool>(() => true), Required = false
|
||||||
|
});
|
||||||
|
|
||||||
|
Add(new Option(new[]
|
||||||
|
{
|
||||||
|
"--md5", "-m"
|
||||||
|
}, "Calculates MD5.")
|
||||||
|
{
|
||||||
|
Argument = new Argument<bool>(() => true), Required = false
|
||||||
|
});
|
||||||
|
|
||||||
|
Add(new Option(new[]
|
||||||
|
{
|
||||||
|
"--separated-tracks", "-t"
|
||||||
|
}, "Checksums each track separately.")
|
||||||
|
{
|
||||||
|
Argument = new Argument<bool>(() => true), Required = false
|
||||||
|
});
|
||||||
|
|
||||||
|
Add(new Option(new[]
|
||||||
|
{
|
||||||
|
"--sha1", "-s"
|
||||||
|
}, "Calculates SHA1.")
|
||||||
|
{
|
||||||
|
Argument = new Argument<bool>(() => true), Required = false
|
||||||
|
});
|
||||||
|
|
||||||
|
Add(new Option(new[]
|
||||||
|
{
|
||||||
|
"--sha256", "-a"
|
||||||
|
}, "Calculates SHA256.")
|
||||||
|
{
|
||||||
|
Argument = new Argument<bool>(() => true), Required = false
|
||||||
|
});
|
||||||
|
|
||||||
|
Add(new Option("--sha384", "Calculates SHA384.")
|
||||||
|
{
|
||||||
|
Argument = new Argument<bool>(() => true), Required = false
|
||||||
|
});
|
||||||
|
|
||||||
|
Add(new Option("--sha512", "Calculates SHA512.")
|
||||||
|
{
|
||||||
|
Argument = new Argument<bool>(() => true), Required = false
|
||||||
|
});
|
||||||
|
|
||||||
|
Add(new Option(new[]
|
||||||
|
{
|
||||||
|
"--spamsum", "-f"
|
||||||
|
}, "Calculates SpamSum fuzzy hash.")
|
||||||
|
{
|
||||||
|
Argument = new Argument<bool>(() => true), Required = false
|
||||||
|
});
|
||||||
|
|
||||||
|
Add(new Option(new[]
|
||||||
|
{
|
||||||
|
"--whole-disc", "-w"
|
||||||
|
}, "Checksums the whole disc.")
|
||||||
|
{
|
||||||
|
Argument = new Argument<bool>(() => true), Required = false
|
||||||
|
});
|
||||||
|
|
||||||
|
AddArgument(new Argument<string>
|
||||||
|
{
|
||||||
|
Arity = ArgumentArity.ExactlyOne, Description = "Media image path", Name = "image-path"
|
||||||
|
});
|
||||||
|
|
||||||
|
Handler = CommandHandler.Create(GetType().GetMethod(nameof(Invoke)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override int Invoke(IEnumerable<string> arguments)
|
static int Invoke(bool debug, bool verbose, bool adler32, bool crc16, bool crc32, bool crc64, bool fletcher16,
|
||||||
|
bool fletcher32, bool md5, bool sha1, bool sha256, bool sha384, bool sha512, bool spamSum,
|
||||||
|
string imagePath, bool separatedTracks, bool wholeDisc)
|
||||||
{
|
{
|
||||||
List<string> extra = Options.Parse(arguments);
|
|
||||||
|
|
||||||
if(showHelp)
|
|
||||||
{
|
|
||||||
Options.WriteOptionDescriptions(CommandSet.Out);
|
|
||||||
return (int)ErrorNumber.HelpRequested;
|
|
||||||
}
|
|
||||||
|
|
||||||
MainClass.PrintCopyright();
|
MainClass.PrintCopyright();
|
||||||
if(MainClass.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
|
||||||
if(MainClass.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
if(debug)
|
||||||
|
DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
||||||
|
|
||||||
|
if(verbose)
|
||||||
|
DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
||||||
|
|
||||||
Statistics.AddCommand("checksum");
|
Statistics.AddCommand("checksum");
|
||||||
|
|
||||||
if(extra.Count > 1)
|
DicConsole.DebugWriteLine("Checksum command", "--adler32={0}", adler32);
|
||||||
{
|
DicConsole.DebugWriteLine("Checksum command", "--crc16={0}", crc16);
|
||||||
DicConsole.ErrorWriteLine("Too many arguments.");
|
DicConsole.DebugWriteLine("Checksum command", "--crc32={0}", crc32);
|
||||||
return (int)ErrorNumber.UnexpectedArgumentCount;
|
DicConsole.DebugWriteLine("Checksum command", "--crc64={0}", crc64);
|
||||||
}
|
DicConsole.DebugWriteLine("Checksum command", "--debug={0}", debug);
|
||||||
|
DicConsole.DebugWriteLine("Checksum command", "--fletcher16={0}", fletcher16);
|
||||||
if(extra.Count == 0)
|
DicConsole.DebugWriteLine("Checksum command", "--fletcher32={0}", fletcher32);
|
||||||
{
|
DicConsole.DebugWriteLine("Checksum command", "--input={0}", imagePath);
|
||||||
DicConsole.ErrorWriteLine("Missing input image.");
|
DicConsole.DebugWriteLine("Checksum command", "--md5={0}", md5);
|
||||||
return (int)ErrorNumber.MissingArgument;
|
|
||||||
}
|
|
||||||
|
|
||||||
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", "--separated-tracks={0}", separatedTracks);
|
DicConsole.DebugWriteLine("Checksum command", "--separated-tracks={0}", separatedTracks);
|
||||||
DicConsole.DebugWriteLine("Checksum command", "--sha1={0}", doSha1);
|
DicConsole.DebugWriteLine("Checksum command", "--sha1={0}", sha1);
|
||||||
DicConsole.DebugWriteLine("Checksum command", "--sha256={0}", doSha256);
|
DicConsole.DebugWriteLine("Checksum command", "--sha256={0}", sha256);
|
||||||
DicConsole.DebugWriteLine("Checksum command", "--sha384={0}", doSha384);
|
DicConsole.DebugWriteLine("Checksum command", "--sha384={0}", sha384);
|
||||||
DicConsole.DebugWriteLine("Checksum command", "--sha512={0}", doSha512);
|
DicConsole.DebugWriteLine("Checksum command", "--sha512={0}", sha512);
|
||||||
DicConsole.DebugWriteLine("Checksum command", "--spamsum={0}", doSpamSum);
|
DicConsole.DebugWriteLine("Checksum command", "--spamsum={0}", spamSum);
|
||||||
DicConsole.DebugWriteLine("Checksum command", "--verbose={0}", MainClass.Verbose);
|
DicConsole.DebugWriteLine("Checksum command", "--verbose={0}", verbose);
|
||||||
DicConsole.DebugWriteLine("Checksum command", "--whole-disc={0}", wholeDisc);
|
DicConsole.DebugWriteLine("Checksum command", "--whole-disc={0}", wholeDisc);
|
||||||
|
|
||||||
FiltersList filtersList = new FiltersList();
|
var filtersList = new FiltersList();
|
||||||
IFilter inputFilter = filtersList.GetFilter(inputFile);
|
IFilter inputFilter = filtersList.GetFilter(imagePath);
|
||||||
|
|
||||||
if(inputFilter == null)
|
if(inputFilter == null)
|
||||||
{
|
{
|
||||||
DicConsole.ErrorWriteLine("Cannot open specified file.");
|
DicConsole.ErrorWriteLine("Cannot open specified file.");
|
||||||
return (int)ErrorNumber.CannotOpenFile;
|
|
||||||
|
return(int)ErrorNumber.CannotOpenFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
IMediaImage inputFormat = ImageFormat.Detect(inputFilter);
|
IMediaImage inputFormat = ImageFormat.Detect(inputFilter);
|
||||||
@@ -154,27 +200,51 @@ namespace DiscImageChef.Commands
|
|||||||
if(inputFormat == null)
|
if(inputFormat == null)
|
||||||
{
|
{
|
||||||
DicConsole.ErrorWriteLine("Unable to recognize image format, not checksumming");
|
DicConsole.ErrorWriteLine("Unable to recognize image format, not checksumming");
|
||||||
return (int)ErrorNumber.UnrecognizedFormat;
|
|
||||||
|
return(int)ErrorNumber.UnrecognizedFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
inputFormat.Open(inputFilter);
|
inputFormat.Open(inputFilter);
|
||||||
Statistics.AddMediaFormat(inputFormat.Format);
|
Statistics.AddMediaFormat(inputFormat.Format);
|
||||||
Statistics.AddMedia(inputFormat.Info.MediaType, false);
|
Statistics.AddMedia(inputFormat.Info.MediaType, false);
|
||||||
Statistics.AddFilter(inputFilter.Name);
|
Statistics.AddFilter(inputFilter.Name);
|
||||||
EnableChecksum enabledChecksums = new EnableChecksum();
|
var enabledChecksums = new EnableChecksum();
|
||||||
|
|
||||||
if(doAdler32) enabledChecksums |= EnableChecksum.Adler32;
|
if(adler32)
|
||||||
if(doCrc16) enabledChecksums |= EnableChecksum.Crc16;
|
enabledChecksums |= EnableChecksum.Adler32;
|
||||||
if(doCrc32) enabledChecksums |= EnableChecksum.Crc32;
|
|
||||||
if(doCrc64) enabledChecksums |= EnableChecksum.Crc64;
|
if(crc16)
|
||||||
if(doMd5) enabledChecksums |= EnableChecksum.Md5;
|
enabledChecksums |= EnableChecksum.Crc16;
|
||||||
if(doSha1) enabledChecksums |= EnableChecksum.Sha1;
|
|
||||||
if(doSha256) enabledChecksums |= EnableChecksum.Sha256;
|
if(crc32)
|
||||||
if(doSha384) enabledChecksums |= EnableChecksum.Sha384;
|
enabledChecksums |= EnableChecksum.Crc32;
|
||||||
if(doSha512) enabledChecksums |= EnableChecksum.Sha512;
|
|
||||||
if(doSpamSum) enabledChecksums |= EnableChecksum.SpamSum;
|
if(crc64)
|
||||||
if(doFletcher16) enabledChecksums |= EnableChecksum.Fletcher16;
|
enabledChecksums |= EnableChecksum.Crc64;
|
||||||
if(doFletcher32) enabledChecksums |= EnableChecksum.Fletcher32;
|
|
||||||
|
if(md5)
|
||||||
|
enabledChecksums |= EnableChecksum.Md5;
|
||||||
|
|
||||||
|
if(sha1)
|
||||||
|
enabledChecksums |= EnableChecksum.Sha1;
|
||||||
|
|
||||||
|
if(sha256)
|
||||||
|
enabledChecksums |= EnableChecksum.Sha256;
|
||||||
|
|
||||||
|
if(sha384)
|
||||||
|
enabledChecksums |= EnableChecksum.Sha384;
|
||||||
|
|
||||||
|
if(sha512)
|
||||||
|
enabledChecksums |= EnableChecksum.Sha512;
|
||||||
|
|
||||||
|
if(spamSum)
|
||||||
|
enabledChecksums |= EnableChecksum.SpamSum;
|
||||||
|
|
||||||
|
if(fletcher16)
|
||||||
|
enabledChecksums |= EnableChecksum.Fletcher16;
|
||||||
|
|
||||||
|
if(fletcher32)
|
||||||
|
enabledChecksums |= EnableChecksum.Fletcher32;
|
||||||
|
|
||||||
Checksum mediaChecksum = null;
|
Checksum mediaChecksum = null;
|
||||||
|
|
||||||
@@ -185,11 +255,13 @@ namespace DiscImageChef.Commands
|
|||||||
{
|
{
|
||||||
Checksum trackChecksum = null;
|
Checksum trackChecksum = null;
|
||||||
|
|
||||||
if(wholeDisc) mediaChecksum = new Checksum(enabledChecksums);
|
if(wholeDisc)
|
||||||
|
mediaChecksum = new Checksum(enabledChecksums);
|
||||||
|
|
||||||
ulong previousTrackEnd = 0;
|
ulong previousTrackEnd = 0;
|
||||||
|
|
||||||
List<Track> inputTracks = opticalInput.Tracks;
|
List<Track> inputTracks = opticalInput.Tracks;
|
||||||
|
|
||||||
foreach(Track currentTrack in inputTracks)
|
foreach(Track currentTrack in inputTracks)
|
||||||
{
|
{
|
||||||
if(currentTrack.TrackStartSector - previousTrackEnd != 0 && wholeDisc)
|
if(currentTrack.TrackStartSector - previousTrackEnd != 0 && wholeDisc)
|
||||||
@@ -207,9 +279,10 @@ namespace DiscImageChef.Commands
|
|||||||
currentTrack.TrackSequence, currentTrack.TrackStartSector,
|
currentTrack.TrackSequence, currentTrack.TrackStartSector,
|
||||||
currentTrack.TrackEndSector);
|
currentTrack.TrackEndSector);
|
||||||
|
|
||||||
if(separatedTracks) trackChecksum = new Checksum(enabledChecksums);
|
if(separatedTracks)
|
||||||
|
trackChecksum = new Checksum(enabledChecksums);
|
||||||
|
|
||||||
ulong sectors = currentTrack.TrackEndSector - currentTrack.TrackStartSector + 1;
|
ulong sectors = (currentTrack.TrackEndSector - currentTrack.TrackStartSector) + 1;
|
||||||
ulong doneSectors = 0;
|
ulong doneSectors = 0;
|
||||||
DicConsole.WriteLine("Track {0} has {1} sectors", currentTrack.TrackSequence, sectors);
|
DicConsole.WriteLine("Track {0} has {1} sectors", currentTrack.TrackSequence, sectors);
|
||||||
|
|
||||||
@@ -221,22 +294,28 @@ namespace DiscImageChef.Commands
|
|||||||
{
|
{
|
||||||
sector = opticalInput.ReadSectors(doneSectors, SECTORS_TO_READ,
|
sector = opticalInput.ReadSectors(doneSectors, SECTORS_TO_READ,
|
||||||
currentTrack.TrackSequence);
|
currentTrack.TrackSequence);
|
||||||
DicConsole.Write("\rHashings sectors {0} to {2} of track {1}", doneSectors,
|
|
||||||
|
DicConsole.Write("\rHashing sectors {0} to {2} of track {1}", doneSectors,
|
||||||
currentTrack.TrackSequence, doneSectors + SECTORS_TO_READ);
|
currentTrack.TrackSequence, doneSectors + SECTORS_TO_READ);
|
||||||
|
|
||||||
doneSectors += SECTORS_TO_READ;
|
doneSectors += SECTORS_TO_READ;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sector = opticalInput.ReadSectors(doneSectors, (uint)(sectors - doneSectors),
|
sector = opticalInput.ReadSectors(doneSectors, (uint)(sectors - doneSectors),
|
||||||
currentTrack.TrackSequence);
|
currentTrack.TrackSequence);
|
||||||
DicConsole.Write("\rHashings sectors {0} to {2} of track {1}", doneSectors,
|
|
||||||
|
DicConsole.Write("\rHashing sectors {0} to {2} of track {1}", doneSectors,
|
||||||
currentTrack.TrackSequence, doneSectors + (sectors - doneSectors));
|
currentTrack.TrackSequence, doneSectors + (sectors - doneSectors));
|
||||||
|
|
||||||
doneSectors += sectors - doneSectors;
|
doneSectors += sectors - doneSectors;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(wholeDisc) mediaChecksum?.Update(sector);
|
if(wholeDisc)
|
||||||
|
mediaChecksum?.Update(sector);
|
||||||
|
|
||||||
if(separatedTracks) trackChecksum?.Update(sector);
|
if(separatedTracks)
|
||||||
|
trackChecksum?.Update(sector);
|
||||||
}
|
}
|
||||||
|
|
||||||
DicConsole.WriteLine();
|
DicConsole.WriteLine();
|
||||||
@@ -266,8 +345,10 @@ namespace DiscImageChef.Commands
|
|||||||
}
|
}
|
||||||
catch(Exception ex)
|
catch(Exception ex)
|
||||||
{
|
{
|
||||||
if(MainClass.Debug) DicConsole.DebugWriteLine("Could not get tracks because {0}", ex.Message);
|
if(debug)
|
||||||
else DicConsole.WriteLine("Unable to get separate tracks, not checksumming them");
|
DicConsole.DebugWriteLine("Could not get tracks because {0}", ex.Message);
|
||||||
|
else
|
||||||
|
DicConsole.WriteLine("Unable to get separate tracks, not checksumming them");
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -276,7 +357,8 @@ namespace DiscImageChef.Commands
|
|||||||
{
|
{
|
||||||
Checksum trackChecksum = null;
|
Checksum trackChecksum = null;
|
||||||
|
|
||||||
if(wholeDisc) mediaChecksum = new Checksum(enabledChecksums);
|
if(wholeDisc)
|
||||||
|
mediaChecksum = new Checksum(enabledChecksums);
|
||||||
|
|
||||||
ulong previousTrackEnd = 0;
|
ulong previousTrackEnd = 0;
|
||||||
|
|
||||||
@@ -296,9 +378,10 @@ namespace DiscImageChef.Commands
|
|||||||
"Track {0} starts at sector {1} and ends at block {2}",
|
"Track {0} starts at sector {1} and ends at block {2}",
|
||||||
currentFile.File, currentFile.FirstBlock, currentFile.LastBlock);
|
currentFile.File, currentFile.FirstBlock, currentFile.LastBlock);
|
||||||
|
|
||||||
if(separatedTracks) trackChecksum = new Checksum(enabledChecksums);
|
if(separatedTracks)
|
||||||
|
trackChecksum = new Checksum(enabledChecksums);
|
||||||
|
|
||||||
ulong sectors = currentFile.LastBlock - currentFile.FirstBlock + 1;
|
ulong sectors = (currentFile.LastBlock - currentFile.FirstBlock) + 1;
|
||||||
ulong doneSectors = 0;
|
ulong doneSectors = 0;
|
||||||
DicConsole.WriteLine("File {0} has {1} sectors", currentFile.File, sectors);
|
DicConsole.WriteLine("File {0} has {1} sectors", currentFile.File, sectors);
|
||||||
|
|
||||||
@@ -309,22 +392,28 @@ namespace DiscImageChef.Commands
|
|||||||
if(sectors - doneSectors >= SECTORS_TO_READ)
|
if(sectors - doneSectors >= SECTORS_TO_READ)
|
||||||
{
|
{
|
||||||
sector = tapeImage.ReadSectors(doneSectors + currentFile.FirstBlock, SECTORS_TO_READ);
|
sector = tapeImage.ReadSectors(doneSectors + currentFile.FirstBlock, SECTORS_TO_READ);
|
||||||
DicConsole.Write("\rHashings blocks {0} to {2} of file {1}", doneSectors,
|
|
||||||
|
DicConsole.Write("\rHashing blocks {0} to {2} of file {1}", doneSectors,
|
||||||
currentFile.File, doneSectors + SECTORS_TO_READ);
|
currentFile.File, doneSectors + SECTORS_TO_READ);
|
||||||
|
|
||||||
doneSectors += SECTORS_TO_READ;
|
doneSectors += SECTORS_TO_READ;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sector = tapeImage.ReadSectors(doneSectors + currentFile.FirstBlock,
|
sector = tapeImage.ReadSectors(doneSectors + currentFile.FirstBlock,
|
||||||
(uint)(sectors - doneSectors));
|
(uint)(sectors - doneSectors));
|
||||||
DicConsole.Write("\rHashings blocks {0} to {2} of file {1}", doneSectors,
|
|
||||||
|
DicConsole.Write("\rHashing blocks {0} to {2} of file {1}", doneSectors,
|
||||||
currentFile.File, doneSectors + (sectors - doneSectors));
|
currentFile.File, doneSectors + (sectors - doneSectors));
|
||||||
|
|
||||||
doneSectors += sectors - doneSectors;
|
doneSectors += sectors - doneSectors;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(wholeDisc) mediaChecksum?.Update(sector);
|
if(wholeDisc)
|
||||||
|
mediaChecksum?.Update(sector);
|
||||||
|
|
||||||
if(separatedTracks) trackChecksum?.Update(sector);
|
if(separatedTracks)
|
||||||
|
trackChecksum?.Update(sector);
|
||||||
}
|
}
|
||||||
|
|
||||||
DicConsole.WriteLine();
|
DicConsole.WriteLine();
|
||||||
@@ -350,6 +439,7 @@ namespace DiscImageChef.Commands
|
|||||||
if(mediaChecksum != null)
|
if(mediaChecksum != null)
|
||||||
foreach(ChecksumType chk in mediaChecksum.End())
|
foreach(ChecksumType chk in mediaChecksum.End())
|
||||||
DicConsole.WriteLine("Tape's {0}: {1}", chk.type, chk.Value);
|
DicConsole.WriteLine("Tape's {0}: {1}", chk.type, chk.Value);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -368,15 +458,19 @@ namespace DiscImageChef.Commands
|
|||||||
if(sectors - doneSectors >= SECTORS_TO_READ)
|
if(sectors - doneSectors >= SECTORS_TO_READ)
|
||||||
{
|
{
|
||||||
sector = inputFormat.ReadSectors(doneSectors, SECTORS_TO_READ);
|
sector = inputFormat.ReadSectors(doneSectors, SECTORS_TO_READ);
|
||||||
DicConsole.Write("\rHashings sectors {0} to {1}", doneSectors,
|
|
||||||
|
DicConsole.Write("\rHashing sectors {0} to {1}", doneSectors,
|
||||||
doneSectors + SECTORS_TO_READ);
|
doneSectors + SECTORS_TO_READ);
|
||||||
|
|
||||||
doneSectors += SECTORS_TO_READ;
|
doneSectors += SECTORS_TO_READ;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sector = inputFormat.ReadSectors(doneSectors, (uint)(sectors - doneSectors));
|
sector = inputFormat.ReadSectors(doneSectors, (uint)(sectors - doneSectors));
|
||||||
DicConsole.Write("\rHashings sectors {0} to {1}", doneSectors,
|
|
||||||
|
DicConsole.Write("\rHashing sectors {0} to {1}", doneSectors,
|
||||||
doneSectors + (sectors - doneSectors));
|
doneSectors + (sectors - doneSectors));
|
||||||
|
|
||||||
doneSectors += sectors - doneSectors;
|
doneSectors += sectors - doneSectors;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -387,11 +481,12 @@ namespace DiscImageChef.Commands
|
|||||||
|
|
||||||
foreach(ChecksumType chk in mediaChecksum.End())
|
foreach(ChecksumType chk in mediaChecksum.End())
|
||||||
DicConsole.WriteLine("Disk's {0}: {1}", chk.type, chk.Value);
|
DicConsole.WriteLine("Disk's {0}: {1}", chk.type, chk.Value);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (int)ErrorNumber.NoError;
|
return(int)ErrorNumber.NoError;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -32,6 +32,8 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.CommandLine;
|
||||||
|
using System.CommandLine.Invocation;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using DiscImageChef.CommonTypes;
|
using DiscImageChef.CommonTypes;
|
||||||
using DiscImageChef.CommonTypes.Enums;
|
using DiscImageChef.CommonTypes.Enums;
|
||||||
@@ -39,81 +41,61 @@ using DiscImageChef.CommonTypes.Interfaces;
|
|||||||
using DiscImageChef.CommonTypes.Structs;
|
using DiscImageChef.CommonTypes.Structs;
|
||||||
using DiscImageChef.Console;
|
using DiscImageChef.Console;
|
||||||
using DiscImageChef.Core;
|
using DiscImageChef.Core;
|
||||||
using Mono.Options;
|
|
||||||
using ImageInfo = DiscImageChef.CommonTypes.Structs.ImageInfo;
|
using ImageInfo = DiscImageChef.CommonTypes.Structs.ImageInfo;
|
||||||
|
|
||||||
namespace DiscImageChef.Commands
|
namespace DiscImageChef.Commands
|
||||||
{
|
{
|
||||||
class CompareCommand : Command
|
internal class CompareCommand : Command
|
||||||
{
|
{
|
||||||
string inputFile1;
|
|
||||||
string inputFile2;
|
|
||||||
bool showHelp;
|
|
||||||
|
|
||||||
public CompareCommand() : base("compare", "Compares two disc images.")
|
public CompareCommand() : base("compare", "Compares two disc images.")
|
||||||
{
|
{
|
||||||
Options = new OptionSet
|
AddArgument(new Argument<string>
|
||||||
{
|
{
|
||||||
$"{MainClass.AssemblyTitle} {MainClass.AssemblyVersion?.InformationalVersion}",
|
Arity = ArgumentArity.ExactlyOne, Description = "First media image path", Name = "image-path1"
|
||||||
$"{MainClass.AssemblyCopyright}",
|
});
|
||||||
"",
|
|
||||||
$"usage: DiscImageChef {Name} imagefile1 imagefile2",
|
AddArgument(new Argument<string>
|
||||||
"",
|
{
|
||||||
Help,
|
Arity = ArgumentArity.ExactlyOne, Description = "Second media image path", Name = "image-path2"
|
||||||
{"help|h|?", "Show this message and exit.", v => showHelp = v != null}
|
});
|
||||||
};
|
|
||||||
|
Handler = CommandHandler.Create(GetType().GetMethod(nameof(Invoke)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override int Invoke(IEnumerable<string> arguments)
|
static int Invoke(bool debug, bool verbose, string imagePath1, string imagePath2)
|
||||||
{
|
{
|
||||||
List<string> extra = Options.Parse(arguments);
|
|
||||||
|
|
||||||
if(showHelp)
|
|
||||||
{
|
|
||||||
Options.WriteOptionDescriptions(CommandSet.Out);
|
|
||||||
return (int)ErrorNumber.HelpRequested;
|
|
||||||
}
|
|
||||||
|
|
||||||
MainClass.PrintCopyright();
|
MainClass.PrintCopyright();
|
||||||
if(MainClass.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
|
||||||
if(MainClass.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
if(debug)
|
||||||
|
DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
||||||
|
|
||||||
|
if(verbose)
|
||||||
|
DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
||||||
|
|
||||||
Statistics.AddCommand("compare");
|
Statistics.AddCommand("compare");
|
||||||
|
|
||||||
if(extra.Count > 2)
|
DicConsole.DebugWriteLine("Compare command", "--debug={0}", debug);
|
||||||
{
|
DicConsole.DebugWriteLine("Compare command", "--input1={0}", imagePath1);
|
||||||
DicConsole.ErrorWriteLine("Too many arguments.");
|
DicConsole.DebugWriteLine("Compare command", "--input2={0}", imagePath2);
|
||||||
return (int)ErrorNumber.UnexpectedArgumentCount;
|
DicConsole.DebugWriteLine("Compare command", "--verbose={0}", verbose);
|
||||||
}
|
|
||||||
|
|
||||||
if(extra.Count <= 1)
|
var filtersList = new FiltersList();
|
||||||
{
|
IFilter inputFilter1 = filtersList.GetFilter(imagePath1);
|
||||||
DicConsole.ErrorWriteLine("Missing input image.");
|
|
||||||
return (int)ErrorNumber.MissingArgument;
|
|
||||||
}
|
|
||||||
|
|
||||||
inputFile1 = extra[0];
|
|
||||||
inputFile2 = 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(inputFile1);
|
|
||||||
filtersList = new FiltersList();
|
filtersList = new FiltersList();
|
||||||
IFilter inputFilter2 = filtersList.GetFilter(inputFile2);
|
IFilter inputFilter2 = filtersList.GetFilter(imagePath2);
|
||||||
|
|
||||||
if(inputFilter1 == null)
|
if(inputFilter1 == null)
|
||||||
{
|
{
|
||||||
DicConsole.ErrorWriteLine("Cannot open input file 1");
|
DicConsole.ErrorWriteLine("Cannot open input file 1");
|
||||||
return (int)ErrorNumber.CannotOpenFile;
|
|
||||||
|
return(int)ErrorNumber.CannotOpenFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(inputFilter2 == null)
|
if(inputFilter2 == null)
|
||||||
{
|
{
|
||||||
DicConsole.ErrorWriteLine("Cannot open input file 2");
|
DicConsole.ErrorWriteLine("Cannot open input file 2");
|
||||||
return (int)ErrorNumber.CannotOpenFile;
|
|
||||||
|
return(int)ErrorNumber.CannotOpenFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
IMediaImage input1Format = ImageFormat.Detect(inputFilter1);
|
IMediaImage input1Format = ImageFormat.Detect(inputFilter1);
|
||||||
@@ -122,24 +104,28 @@ namespace DiscImageChef.Commands
|
|||||||
if(input1Format == null)
|
if(input1Format == null)
|
||||||
{
|
{
|
||||||
DicConsole.ErrorWriteLine("Input file 1 format not identified, not proceeding with comparison.");
|
DicConsole.ErrorWriteLine("Input file 1 format not identified, not proceeding with comparison.");
|
||||||
return (int)ErrorNumber.UnrecognizedFormat;
|
|
||||||
|
return(int)ErrorNumber.UnrecognizedFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(MainClass.Verbose)
|
if(verbose)
|
||||||
DicConsole.VerboseWriteLine("Input file 1 format identified by {0} ({1}).", input1Format.Name,
|
DicConsole.VerboseWriteLine("Input file 1 format identified by {0} ({1}).", input1Format.Name,
|
||||||
input1Format.Id);
|
input1Format.Id);
|
||||||
else DicConsole.WriteLine("Input file 1 format identified by {0}.", input1Format.Name);
|
else
|
||||||
|
DicConsole.WriteLine("Input file 1 format identified by {0}.", input1Format.Name);
|
||||||
|
|
||||||
if(input2Format == null)
|
if(input2Format == null)
|
||||||
{
|
{
|
||||||
DicConsole.ErrorWriteLine("Input file 2 format not identified, not proceeding with comparison.");
|
DicConsole.ErrorWriteLine("Input file 2 format not identified, not proceeding with comparison.");
|
||||||
return (int)ErrorNumber.UnrecognizedFormat;
|
|
||||||
|
return(int)ErrorNumber.UnrecognizedFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(MainClass.Verbose)
|
if(verbose)
|
||||||
DicConsole.VerboseWriteLine("Input file 2 format identified by {0} ({1}).", input2Format.Name,
|
DicConsole.VerboseWriteLine("Input file 2 format identified by {0} ({1}).", input2Format.Name,
|
||||||
input2Format.Id);
|
input2Format.Id);
|
||||||
else DicConsole.WriteLine("Input file 2 format identified by {0}.", input2Format.Name);
|
else
|
||||||
|
DicConsole.WriteLine("Input file 2 format identified by {0}.", input2Format.Name);
|
||||||
|
|
||||||
input1Format.Open(inputFilter1);
|
input1Format.Open(inputFilter1);
|
||||||
input2Format.Open(inputFilter2);
|
input2Format.Open(inputFilter2);
|
||||||
@@ -151,19 +137,19 @@ namespace DiscImageChef.Commands
|
|||||||
Statistics.AddFilter(inputFilter1.Name);
|
Statistics.AddFilter(inputFilter1.Name);
|
||||||
Statistics.AddFilter(inputFilter2.Name);
|
Statistics.AddFilter(inputFilter2.Name);
|
||||||
|
|
||||||
StringBuilder sb = new StringBuilder();
|
var sb = new StringBuilder();
|
||||||
|
|
||||||
if(MainClass.Verbose)
|
if(verbose)
|
||||||
{
|
{
|
||||||
sb.AppendLine("\tDisc image 1\tDisc image 2");
|
sb.AppendLine("\tDisc image 1\tDisc image 2");
|
||||||
sb.AppendLine("================================");
|
sb.AppendLine("================================");
|
||||||
sb.AppendFormat("File\t{0}\t{1}", inputFile1, inputFile2).AppendLine();
|
sb.AppendFormat("File\t{0}\t{1}", imagePath1, imagePath2).AppendLine();
|
||||||
sb.AppendFormat("Disc image format\t{0}\t{1}", input1Format.Name, input2Format.Name).AppendLine();
|
sb.AppendFormat("Disc image format\t{0}\t{1}", input1Format.Name, input2Format.Name).AppendLine();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sb.AppendFormat("Disc image 1: {0}", inputFile1).AppendLine();
|
sb.AppendFormat("Disc image 1: {0}", imagePath1).AppendLine();
|
||||||
sb.AppendFormat("Disc image 2: {0}", inputFile2).AppendLine();
|
sb.AppendFormat("Disc image 2: {0}", imagePath2).AppendLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool imagesDiffer = false;
|
bool imagesDiffer = false;
|
||||||
@@ -205,47 +191,66 @@ namespace DiscImageChef.Commands
|
|||||||
#pragma warning restore RECS0022 // A catch clause that catches System.Exception and has an empty body
|
#pragma warning restore RECS0022 // A catch clause that catches System.Exception and has an empty body
|
||||||
}
|
}
|
||||||
|
|
||||||
if(MainClass.Verbose)
|
if(verbose)
|
||||||
{
|
{
|
||||||
sb.AppendFormat("Has partitions?\t{0}\t{1}", image1Info.HasPartitions, image2Info.HasPartitions)
|
sb.AppendFormat("Has partitions?\t{0}\t{1}", image1Info.HasPartitions, image2Info.HasPartitions).
|
||||||
.AppendLine();
|
AppendLine();
|
||||||
|
|
||||||
sb.AppendFormat("Has sessions?\t{0}\t{1}", image1Info.HasSessions, image2Info.HasSessions).AppendLine();
|
sb.AppendFormat("Has sessions?\t{0}\t{1}", image1Info.HasSessions, image2Info.HasSessions).AppendLine();
|
||||||
sb.AppendFormat("Image size\t{0}\t{1}", image1Info.ImageSize, image2Info.ImageSize).AppendLine();
|
sb.AppendFormat("Image size\t{0}\t{1}", image1Info.ImageSize, image2Info.ImageSize).AppendLine();
|
||||||
sb.AppendFormat("Sectors\t{0}\t{1}", image1Info.Sectors, image2Info.Sectors).AppendLine();
|
sb.AppendFormat("Sectors\t{0}\t{1}", image1Info.Sectors, image2Info.Sectors).AppendLine();
|
||||||
sb.AppendFormat("Sector size\t{0}\t{1}", image1Info.SectorSize, image2Info.SectorSize).AppendLine();
|
sb.AppendFormat("Sector size\t{0}\t{1}", image1Info.SectorSize, image2Info.SectorSize).AppendLine();
|
||||||
sb.AppendFormat("Creation time\t{0}\t{1}", image1Info.CreationTime, image2Info.CreationTime)
|
|
||||||
.AppendLine();
|
sb.AppendFormat("Creation time\t{0}\t{1}", image1Info.CreationTime, image2Info.CreationTime).
|
||||||
|
AppendLine();
|
||||||
|
|
||||||
sb.AppendFormat("Last modification time\t{0}\t{1}", image1Info.LastModificationTime,
|
sb.AppendFormat("Last modification time\t{0}\t{1}", image1Info.LastModificationTime,
|
||||||
image2Info.LastModificationTime).AppendLine();
|
image2Info.LastModificationTime).AppendLine();
|
||||||
|
|
||||||
sb.AppendFormat("Disk type\t{0}\t{1}", image1Info.MediaType, image2Info.MediaType).AppendLine();
|
sb.AppendFormat("Disk type\t{0}\t{1}", image1Info.MediaType, image2Info.MediaType).AppendLine();
|
||||||
sb.AppendFormat("Image version\t{0}\t{1}", image1Info.Version, image2Info.Version).AppendLine();
|
sb.AppendFormat("Image version\t{0}\t{1}", image1Info.Version, image2Info.Version).AppendLine();
|
||||||
sb.AppendFormat("Image application\t{0}\t{1}", image1Info.Application, image2Info.Application)
|
|
||||||
.AppendLine();
|
sb.AppendFormat("Image application\t{0}\t{1}", image1Info.Application, image2Info.Application).
|
||||||
|
AppendLine();
|
||||||
|
|
||||||
sb.AppendFormat("Image application version\t{0}\t{1}", image1Info.ApplicationVersion,
|
sb.AppendFormat("Image application version\t{0}\t{1}", image1Info.ApplicationVersion,
|
||||||
image2Info.ApplicationVersion).AppendLine();
|
image2Info.ApplicationVersion).AppendLine();
|
||||||
|
|
||||||
sb.AppendFormat("Image creator\t{0}\t{1}", image1Info.Creator, image2Info.Creator).AppendLine();
|
sb.AppendFormat("Image creator\t{0}\t{1}", image1Info.Creator, image2Info.Creator).AppendLine();
|
||||||
sb.AppendFormat("Image name\t{0}\t{1}", image1Info.MediaTitle, image2Info.MediaTitle).AppendLine();
|
sb.AppendFormat("Image name\t{0}\t{1}", image1Info.MediaTitle, image2Info.MediaTitle).AppendLine();
|
||||||
sb.AppendFormat("Image comments\t{0}\t{1}", image1Info.Comments, image2Info.Comments).AppendLine();
|
sb.AppendFormat("Image comments\t{0}\t{1}", image1Info.Comments, image2Info.Comments).AppendLine();
|
||||||
|
|
||||||
sb.AppendFormat("Disk manufacturer\t{0}\t{1}", image1Info.MediaManufacturer,
|
sb.AppendFormat("Disk manufacturer\t{0}\t{1}", image1Info.MediaManufacturer,
|
||||||
image2Info.MediaManufacturer).AppendLine();
|
image2Info.MediaManufacturer).AppendLine();
|
||||||
|
|
||||||
sb.AppendFormat("Disk model\t{0}\t{1}", image1Info.MediaModel, image2Info.MediaModel).AppendLine();
|
sb.AppendFormat("Disk model\t{0}\t{1}", image1Info.MediaModel, image2Info.MediaModel).AppendLine();
|
||||||
|
|
||||||
sb.AppendFormat("Disk serial number\t{0}\t{1}", image1Info.MediaSerialNumber,
|
sb.AppendFormat("Disk serial number\t{0}\t{1}", image1Info.MediaSerialNumber,
|
||||||
image2Info.MediaSerialNumber).AppendLine();
|
image2Info.MediaSerialNumber).AppendLine();
|
||||||
sb.AppendFormat("Disk barcode\t{0}\t{1}", image1Info.MediaBarcode, image2Info.MediaBarcode)
|
|
||||||
.AppendLine();
|
sb.AppendFormat("Disk barcode\t{0}\t{1}", image1Info.MediaBarcode, image2Info.MediaBarcode).
|
||||||
sb.AppendFormat("Disk part no.\t{0}\t{1}", image1Info.MediaPartNumber, image2Info.MediaPartNumber)
|
AppendLine();
|
||||||
.AppendLine();
|
|
||||||
sb.AppendFormat("Disk sequence\t{0}\t{1}", image1Info.MediaSequence, image2Info.MediaSequence)
|
sb.AppendFormat("Disk part no.\t{0}\t{1}", image1Info.MediaPartNumber, image2Info.MediaPartNumber).
|
||||||
.AppendLine();
|
AppendLine();
|
||||||
|
|
||||||
|
sb.AppendFormat("Disk sequence\t{0}\t{1}", image1Info.MediaSequence, image2Info.MediaSequence).
|
||||||
|
AppendLine();
|
||||||
|
|
||||||
sb.AppendFormat("Last disk on sequence\t{0}\t{1}", image1Info.LastMediaSequence,
|
sb.AppendFormat("Last disk on sequence\t{0}\t{1}", image1Info.LastMediaSequence,
|
||||||
image2Info.LastMediaSequence).AppendLine();
|
image2Info.LastMediaSequence).AppendLine();
|
||||||
|
|
||||||
sb.AppendFormat("Drive manufacturer\t{0}\t{1}", image1Info.DriveManufacturer,
|
sb.AppendFormat("Drive manufacturer\t{0}\t{1}", image1Info.DriveManufacturer,
|
||||||
image2Info.DriveManufacturer).AppendLine();
|
image2Info.DriveManufacturer).AppendLine();
|
||||||
|
|
||||||
sb.AppendFormat("Drive firmware revision\t{0}\t{1}", image1Info.DriveFirmwareRevision,
|
sb.AppendFormat("Drive firmware revision\t{0}\t{1}", image1Info.DriveFirmwareRevision,
|
||||||
image2Info.DriveFirmwareRevision).AppendLine();
|
image2Info.DriveFirmwareRevision).AppendLine();
|
||||||
|
|
||||||
sb.AppendFormat("Drive model\t{0}\t{1}", image1Info.DriveModel, image2Info.DriveModel).AppendLine();
|
sb.AppendFormat("Drive model\t{0}\t{1}", image1Info.DriveModel, image2Info.DriveModel).AppendLine();
|
||||||
|
|
||||||
sb.AppendFormat("Drive serial number\t{0}\t{1}", image1Info.DriveSerialNumber,
|
sb.AppendFormat("Drive serial number\t{0}\t{1}", image1Info.DriveSerialNumber,
|
||||||
image2Info.DriveSerialNumber).AppendLine();
|
image2Info.DriveSerialNumber).AppendLine();
|
||||||
|
|
||||||
foreach(MediaTagType disktag in Enum.GetValues(typeof(MediaTagType)))
|
foreach(MediaTagType disktag in Enum.GetValues(typeof(MediaTagType)))
|
||||||
sb.AppendFormat("Has {0}?\t{1}\t{2}", disktag, image1DiskTags.ContainsKey(disktag),
|
sb.AppendFormat("Has {0}?\t{1}\t{2}", disktag, image1DiskTags.ContainsKey(disktag),
|
||||||
image2DiskTags.ContainsKey(disktag)).AppendLine();
|
image2DiskTags.ContainsKey(disktag)).AppendLine();
|
||||||
@@ -256,58 +261,76 @@ namespace DiscImageChef.Commands
|
|||||||
if(image1Info.HasPartitions != image2Info.HasPartitions)
|
if(image1Info.HasPartitions != image2Info.HasPartitions)
|
||||||
{
|
{
|
||||||
imagesDiffer = true;
|
imagesDiffer = true;
|
||||||
if(!MainClass.Verbose) sb.AppendLine("Image partitioned status differ");
|
|
||||||
|
if(!verbose)
|
||||||
|
sb.AppendLine("Image partitioned status differ");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(image1Info.HasSessions != image2Info.HasSessions)
|
if(image1Info.HasSessions != image2Info.HasSessions)
|
||||||
{
|
{
|
||||||
imagesDiffer = true;
|
imagesDiffer = true;
|
||||||
if(!MainClass.Verbose) sb.AppendLine("Image session status differ");
|
|
||||||
|
if(!verbose)
|
||||||
|
sb.AppendLine("Image session status differ");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(image1Info.Sectors != image2Info.Sectors)
|
if(image1Info.Sectors != image2Info.Sectors)
|
||||||
{
|
{
|
||||||
imagesDiffer = true;
|
imagesDiffer = true;
|
||||||
if(!MainClass.Verbose) sb.AppendLine("Image sectors differ");
|
|
||||||
|
if(!verbose)
|
||||||
|
sb.AppendLine("Image sectors differ");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(image1Info.SectorSize != image2Info.SectorSize)
|
if(image1Info.SectorSize != image2Info.SectorSize)
|
||||||
{
|
{
|
||||||
imagesDiffer = true;
|
imagesDiffer = true;
|
||||||
if(!MainClass.Verbose) sb.AppendLine("Image sector size differ");
|
|
||||||
|
if(!verbose)
|
||||||
|
sb.AppendLine("Image sector size differ");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(image1Info.MediaType != image2Info.MediaType)
|
if(image1Info.MediaType != image2Info.MediaType)
|
||||||
{
|
{
|
||||||
imagesDiffer = true;
|
imagesDiffer = true;
|
||||||
if(!MainClass.Verbose) sb.AppendLine("Disk type differ");
|
|
||||||
|
if(!verbose)
|
||||||
|
sb.AppendLine("Disk type differ");
|
||||||
}
|
}
|
||||||
|
|
||||||
ulong leastSectors;
|
ulong leastSectors;
|
||||||
|
|
||||||
if(image1Info.Sectors < image2Info.Sectors)
|
if(image1Info.Sectors < image2Info.Sectors)
|
||||||
{
|
{
|
||||||
imagesDiffer = true;
|
imagesDiffer = true;
|
||||||
leastSectors = image1Info.Sectors;
|
leastSectors = image1Info.Sectors;
|
||||||
if(!MainClass.Verbose) sb.AppendLine("Image 2 has more sectors");
|
|
||||||
|
if(!verbose)
|
||||||
|
sb.AppendLine("Image 2 has more sectors");
|
||||||
}
|
}
|
||||||
else if(image1Info.Sectors > image2Info.Sectors)
|
else if(image1Info.Sectors > image2Info.Sectors)
|
||||||
{
|
{
|
||||||
imagesDiffer = true;
|
imagesDiffer = true;
|
||||||
leastSectors = image2Info.Sectors;
|
leastSectors = image2Info.Sectors;
|
||||||
if(!MainClass.Verbose) sb.AppendLine("Image 1 has more sectors");
|
|
||||||
|
if(!verbose)
|
||||||
|
sb.AppendLine("Image 1 has more sectors");
|
||||||
}
|
}
|
||||||
else leastSectors = image1Info.Sectors;
|
else
|
||||||
|
leastSectors = image1Info.Sectors;
|
||||||
|
|
||||||
DicConsole.WriteLine("Comparing sectors...");
|
DicConsole.WriteLine("Comparing sectors...");
|
||||||
|
|
||||||
for(ulong sector = 0; sector < leastSectors; sector++)
|
for(ulong sector = 0; sector < leastSectors; sector++)
|
||||||
{
|
{
|
||||||
DicConsole.Write("\rComparing sector {0} of {1}...", sector + 1, leastSectors);
|
DicConsole.Write("\rComparing sector {0} of {1}...", sector + 1, leastSectors);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
byte[] image1Sector = input1Format.ReadSector(sector);
|
byte[] image1Sector = input1Format.ReadSector(sector);
|
||||||
byte[] image2Sector = input2Format.ReadSector(sector);
|
byte[] image2Sector = input2Format.ReadSector(sector);
|
||||||
ArrayHelpers.CompareBytes(out bool different, out bool sameSize, image1Sector, image2Sector);
|
ArrayHelpers.CompareBytes(out bool different, out bool sameSize, image1Sector, image2Sector);
|
||||||
|
|
||||||
if(different)
|
if(different)
|
||||||
{
|
{
|
||||||
imagesDiffer = true;
|
imagesDiffer = true;
|
||||||
@@ -316,8 +339,9 @@ namespace DiscImageChef.Commands
|
|||||||
else if(!sameSize)
|
else if(!sameSize)
|
||||||
{
|
{
|
||||||
imagesDiffer = true;
|
imagesDiffer = true;
|
||||||
sb
|
|
||||||
.AppendFormat("Sector {0} has different sizes ({1} bytes in image 1, {2} in image 2) but are otherwise identical",
|
sb.
|
||||||
|
AppendFormat("Sector {0} has different sizes ({1} bytes in image 1, {2} in image 2) but are otherwise identical",
|
||||||
sector, image1Sector.LongLength, image2Sector.LongLength).AppendLine();
|
sector, image1Sector.LongLength, image2Sector.LongLength).AppendLine();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -335,7 +359,7 @@ namespace DiscImageChef.Commands
|
|||||||
|
|
||||||
DicConsole.WriteLine(sb.ToString());
|
DicConsole.WriteLine(sb.ToString());
|
||||||
|
|
||||||
return (int)ErrorNumber.NoError;
|
return(int)ErrorNumber.NoError;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -31,79 +31,65 @@
|
|||||||
// ****************************************************************************/
|
// ****************************************************************************/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.CommandLine;
|
||||||
|
using System.CommandLine.Invocation;
|
||||||
using DiscImageChef.CommonTypes.Enums;
|
using DiscImageChef.CommonTypes.Enums;
|
||||||
using DiscImageChef.Console;
|
using DiscImageChef.Console;
|
||||||
using DiscImageChef.Settings;
|
using DiscImageChef.Settings;
|
||||||
using Mono.Options;
|
|
||||||
|
|
||||||
namespace DiscImageChef.Commands
|
namespace DiscImageChef.Commands
|
||||||
{
|
{
|
||||||
class ConfigureCommand : Command
|
internal class ConfigureCommand : Command
|
||||||
{
|
{
|
||||||
readonly bool gdprChange;
|
readonly bool _autoCall;
|
||||||
bool autoCall;
|
readonly bool _gdprChange;
|
||||||
bool showHelp;
|
|
||||||
|
|
||||||
public ConfigureCommand(bool gdprChange, bool autoCall) : base("configure",
|
public ConfigureCommand(bool gdprChange, bool autoCall) : base("configure",
|
||||||
"Configures user settings and statistics.")
|
"Configures user settings and statistics.")
|
||||||
{
|
{
|
||||||
this.gdprChange = gdprChange;
|
_gdprChange = gdprChange;
|
||||||
this.autoCall = autoCall;
|
_autoCall = autoCall;
|
||||||
Options = new OptionSet
|
|
||||||
{
|
Handler = CommandHandler.Create(GetType().GetMethod(nameof(Invoke)));
|
||||||
$"{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)
|
int Invoke(bool debug, bool verbose)
|
||||||
{
|
{
|
||||||
if(!autoCall)
|
if(!_autoCall)
|
||||||
{
|
{
|
||||||
List<string> extra = Options.Parse(arguments);
|
|
||||||
|
|
||||||
if(showHelp)
|
|
||||||
{
|
|
||||||
Options.WriteOptionDescriptions(CommandSet.Out);
|
|
||||||
return (int)ErrorNumber.HelpRequested;
|
|
||||||
}
|
|
||||||
|
|
||||||
MainClass.PrintCopyright();
|
MainClass.PrintCopyright();
|
||||||
if(MainClass.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
|
||||||
if(MainClass.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
|
||||||
|
|
||||||
if(extra.Count != 0)
|
if(debug)
|
||||||
{
|
DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
||||||
DicConsole.ErrorWriteLine("Too many arguments.");
|
|
||||||
return (int)ErrorNumber.UnexpectedArgumentCount;
|
if(verbose)
|
||||||
}
|
DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(gdprChange)
|
if(_gdprChange)
|
||||||
{
|
{
|
||||||
DicConsole.WriteLine("In compliance with the European Union General Data Protection Regulation 2016/679 (GDPR),\n" +
|
DicConsole.WriteLine("In compliance with the European Union General Data Protection Regulation 2016/679 (GDPR),\n" +
|
||||||
"we must give you the following information about DiscImageChef and ask if you want to opt-in\n" +
|
"we must give you the following information about DiscImageChef and ask if you want to opt-in\n" +
|
||||||
"in some information sharing.");
|
"in some information sharing.");
|
||||||
|
|
||||||
DicConsole.WriteLine();
|
DicConsole.WriteLine();
|
||||||
|
|
||||||
DicConsole.WriteLine("Disclaimer: Because DiscImageChef is an open source software this information, and therefore,\n" +
|
DicConsole.WriteLine("Disclaimer: Because DiscImageChef is an open source software this information, and therefore,\n" +
|
||||||
"compliance with GDPR only holds true if you obtained a certificated copy from its original\n" +
|
"compliance with GDPR only holds true if you obtained a certificated copy from its original\n" +
|
||||||
"authors. In case of doubt, close DiscImageChef now and ask in our IRC support channel.");
|
"authors. In case of doubt, close DiscImageChef now and ask in our IRC support channel.");
|
||||||
|
|
||||||
DicConsole.WriteLine();
|
DicConsole.WriteLine();
|
||||||
|
|
||||||
DicConsole.WriteLine("For any information sharing your IP address may be stored in our server, in a way that is not\n" +
|
DicConsole.WriteLine("For any information sharing your IP address may be stored in our server, in a way that is not\n" +
|
||||||
"possible for any person, manual, or automated process, to link with your identity, unless\n" +
|
"possible for any person, manual, or automated process, to link with your identity, unless\n" +
|
||||||
"specified otherwise.");
|
"specified otherwise.");
|
||||||
}
|
}
|
||||||
|
|
||||||
ConsoleKeyInfo pressedKey = new ConsoleKeyInfo();
|
var pressedKey = new ConsoleKeyInfo();
|
||||||
|
|
||||||
#region Device reports
|
#region Device reports
|
||||||
DicConsole.WriteLine();
|
DicConsole.WriteLine();
|
||||||
|
|
||||||
DicConsole.WriteLine(
|
DicConsole.WriteLine(
|
||||||
"With the 'device-report' command, DiscImageChef creates a report of a device, that includes its\n" +
|
"With the 'device-report' command, DiscImageChef creates a report of a device, that includes its\n" +
|
||||||
"manufacturer, model, firmware revision and/or version, attached bus, size, and supported commands.\n" +
|
"manufacturer, model, firmware revision and/or version, attached bus, size, and supported commands.\n" +
|
||||||
@@ -113,7 +99,8 @@ namespace DiscImageChef.Commands
|
|||||||
"of devices. A human-readable copy of the report in XML format is always created in the same directory\n" +
|
"of devices. A human-readable copy of the report in XML format is always created in the same directory\n" +
|
||||||
"where DiscImageChef is being run from.");
|
"where DiscImageChef is being run from.");
|
||||||
|
|
||||||
while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N)
|
while(pressedKey.Key != ConsoleKey.Y &&
|
||||||
|
pressedKey.Key != ConsoleKey.N)
|
||||||
{
|
{
|
||||||
DicConsole.Write("Do you want to save device reports in shared folder of your computer? (Y/N): ");
|
DicConsole.Write("Do you want to save device reports in shared folder of your computer? (Y/N): ");
|
||||||
pressedKey = System.Console.ReadKey();
|
pressedKey = System.Console.ReadKey();
|
||||||
@@ -124,12 +111,15 @@ namespace DiscImageChef.Commands
|
|||||||
|
|
||||||
pressedKey = new ConsoleKeyInfo();
|
pressedKey = new ConsoleKeyInfo();
|
||||||
DicConsole.WriteLine();
|
DicConsole.WriteLine();
|
||||||
|
|
||||||
DicConsole.WriteLine("Sharing a report with us will send it to our server, that's in the european union territory, where it\n" +
|
DicConsole.WriteLine("Sharing a report with us will send it to our server, that's in the european union territory, where it\n" +
|
||||||
"will be manually analized by an european union citizen to remove any trace of personal identification\n" +
|
"will be manually analyzed by an european union citizen to remove any trace of personal identification\n" +
|
||||||
"from it. Once that is done, it will be shared in our stats website, https://www.discimagechef.app\n" +
|
"from it. Once that is done, it will be shared in our stats website, https://www.discimagechef.app\n" +
|
||||||
"These report will be used to improve DiscImageChef support, and in some cases, to provide emulation of the\n" +
|
"These report will be used to improve DiscImageChef support, and in some cases, to provide emulation of the\n" +
|
||||||
"devices to other open-source projects. In any case, no information linking the report to you will be stored.");
|
"devices to other open-source projects. In any case, no information linking the report to you will be stored.");
|
||||||
while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N)
|
|
||||||
|
while(pressedKey.Key != ConsoleKey.Y &&
|
||||||
|
pressedKey.Key != ConsoleKey.N)
|
||||||
{
|
{
|
||||||
DicConsole.Write("Do you want to share your device reports with us? (Y/N): ");
|
DicConsole.Write("Do you want to share your device reports with us? (Y/N): ");
|
||||||
pressedKey = System.Console.ReadKey();
|
pressedKey = System.Console.ReadKey();
|
||||||
@@ -141,13 +131,16 @@ namespace DiscImageChef.Commands
|
|||||||
|
|
||||||
#region Statistics
|
#region Statistics
|
||||||
DicConsole.WriteLine();
|
DicConsole.WriteLine();
|
||||||
|
|
||||||
DicConsole.WriteLine("DiscImageChef can store some usage statistics. These statistics are limited to the number of times a\n" +
|
DicConsole.WriteLine("DiscImageChef can store some usage statistics. These statistics are limited to the number of times a\n" +
|
||||||
"command is executed, a filesystem, partition, or device is used, the operating system version, and other.\n" +
|
"command is executed, a filesystem, partition, or device is used, the operating system version, and other.\n" +
|
||||||
"In no case, any information besides pure statistical usage numbers is stored, and they're just joint to the\n" +
|
"In no case, any information besides pure statistical usage numbers is stored, and they're just joint to the\n" +
|
||||||
"pool with no way of using them to identify you.");
|
"pool with no way of using them to identify you.");
|
||||||
|
|
||||||
pressedKey = new ConsoleKeyInfo();
|
pressedKey = new ConsoleKeyInfo();
|
||||||
while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N)
|
|
||||||
|
while(pressedKey.Key != ConsoleKey.Y &&
|
||||||
|
pressedKey.Key != ConsoleKey.N)
|
||||||
{
|
{
|
||||||
DicConsole.Write("Do you want to save stats about your DiscImageChef usage? (Y/N): ");
|
DicConsole.Write("Do you want to save stats about your DiscImageChef usage? (Y/N): ");
|
||||||
pressedKey = System.Console.ReadKey();
|
pressedKey = System.Console.ReadKey();
|
||||||
@@ -159,7 +152,9 @@ namespace DiscImageChef.Commands
|
|||||||
Settings.Settings.Current.Stats = new StatsSettings();
|
Settings.Settings.Current.Stats = new StatsSettings();
|
||||||
|
|
||||||
pressedKey = new ConsoleKeyInfo();
|
pressedKey = new ConsoleKeyInfo();
|
||||||
while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N)
|
|
||||||
|
while(pressedKey.Key != ConsoleKey.Y &&
|
||||||
|
pressedKey.Key != ConsoleKey.N)
|
||||||
{
|
{
|
||||||
DicConsole.Write("Do you want to share your stats anonymously? (Y/N): ");
|
DicConsole.Write("Do you want to share your stats anonymously? (Y/N): ");
|
||||||
pressedKey = System.Console.ReadKey();
|
pressedKey = System.Console.ReadKey();
|
||||||
@@ -169,7 +164,9 @@ namespace DiscImageChef.Commands
|
|||||||
Settings.Settings.Current.Stats.ShareStats = pressedKey.Key == ConsoleKey.Y;
|
Settings.Settings.Current.Stats.ShareStats = pressedKey.Key == ConsoleKey.Y;
|
||||||
|
|
||||||
pressedKey = new ConsoleKeyInfo();
|
pressedKey = new ConsoleKeyInfo();
|
||||||
while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N)
|
|
||||||
|
while(pressedKey.Key != ConsoleKey.Y &&
|
||||||
|
pressedKey.Key != ConsoleKey.N)
|
||||||
{
|
{
|
||||||
DicConsole.Write("Do you want to gather statistics about benchmarks? (Y/N): ");
|
DicConsole.Write("Do you want to gather statistics about benchmarks? (Y/N): ");
|
||||||
pressedKey = System.Console.ReadKey();
|
pressedKey = System.Console.ReadKey();
|
||||||
@@ -179,7 +176,9 @@ namespace DiscImageChef.Commands
|
|||||||
Settings.Settings.Current.Stats.BenchmarkStats = pressedKey.Key == ConsoleKey.Y;
|
Settings.Settings.Current.Stats.BenchmarkStats = pressedKey.Key == ConsoleKey.Y;
|
||||||
|
|
||||||
pressedKey = new ConsoleKeyInfo();
|
pressedKey = new ConsoleKeyInfo();
|
||||||
while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N)
|
|
||||||
|
while(pressedKey.Key != ConsoleKey.Y &&
|
||||||
|
pressedKey.Key != ConsoleKey.N)
|
||||||
{
|
{
|
||||||
DicConsole.Write("Do you want to gather statistics about command usage? (Y/N): ");
|
DicConsole.Write("Do you want to gather statistics about command usage? (Y/N): ");
|
||||||
pressedKey = System.Console.ReadKey();
|
pressedKey = System.Console.ReadKey();
|
||||||
@@ -189,7 +188,9 @@ namespace DiscImageChef.Commands
|
|||||||
Settings.Settings.Current.Stats.CommandStats = pressedKey.Key == ConsoleKey.Y;
|
Settings.Settings.Current.Stats.CommandStats = pressedKey.Key == ConsoleKey.Y;
|
||||||
|
|
||||||
pressedKey = new ConsoleKeyInfo();
|
pressedKey = new ConsoleKeyInfo();
|
||||||
while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N)
|
|
||||||
|
while(pressedKey.Key != ConsoleKey.Y &&
|
||||||
|
pressedKey.Key != ConsoleKey.N)
|
||||||
{
|
{
|
||||||
DicConsole.Write("Do you want to gather statistics about found devices? (Y/N): ");
|
DicConsole.Write("Do you want to gather statistics about found devices? (Y/N): ");
|
||||||
pressedKey = System.Console.ReadKey();
|
pressedKey = System.Console.ReadKey();
|
||||||
@@ -199,7 +200,9 @@ namespace DiscImageChef.Commands
|
|||||||
Settings.Settings.Current.Stats.DeviceStats = pressedKey.Key == ConsoleKey.Y;
|
Settings.Settings.Current.Stats.DeviceStats = pressedKey.Key == ConsoleKey.Y;
|
||||||
|
|
||||||
pressedKey = new ConsoleKeyInfo();
|
pressedKey = new ConsoleKeyInfo();
|
||||||
while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N)
|
|
||||||
|
while(pressedKey.Key != ConsoleKey.Y &&
|
||||||
|
pressedKey.Key != ConsoleKey.N)
|
||||||
{
|
{
|
||||||
DicConsole.Write("Do you want to gather statistics about found filesystems? (Y/N): ");
|
DicConsole.Write("Do you want to gather statistics about found filesystems? (Y/N): ");
|
||||||
pressedKey = System.Console.ReadKey();
|
pressedKey = System.Console.ReadKey();
|
||||||
@@ -209,7 +212,9 @@ namespace DiscImageChef.Commands
|
|||||||
Settings.Settings.Current.Stats.FilesystemStats = pressedKey.Key == ConsoleKey.Y;
|
Settings.Settings.Current.Stats.FilesystemStats = pressedKey.Key == ConsoleKey.Y;
|
||||||
|
|
||||||
pressedKey = new ConsoleKeyInfo();
|
pressedKey = new ConsoleKeyInfo();
|
||||||
while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N)
|
|
||||||
|
while(pressedKey.Key != ConsoleKey.Y &&
|
||||||
|
pressedKey.Key != ConsoleKey.N)
|
||||||
{
|
{
|
||||||
DicConsole.Write("Do you want to gather statistics about found file filters? (Y/N): ");
|
DicConsole.Write("Do you want to gather statistics about found file filters? (Y/N): ");
|
||||||
pressedKey = System.Console.ReadKey();
|
pressedKey = System.Console.ReadKey();
|
||||||
@@ -219,7 +224,9 @@ namespace DiscImageChef.Commands
|
|||||||
Settings.Settings.Current.Stats.FilterStats = pressedKey.Key == ConsoleKey.Y;
|
Settings.Settings.Current.Stats.FilterStats = pressedKey.Key == ConsoleKey.Y;
|
||||||
|
|
||||||
pressedKey = new ConsoleKeyInfo();
|
pressedKey = new ConsoleKeyInfo();
|
||||||
while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N)
|
|
||||||
|
while(pressedKey.Key != ConsoleKey.Y &&
|
||||||
|
pressedKey.Key != ConsoleKey.N)
|
||||||
{
|
{
|
||||||
DicConsole.Write("Do you want to gather statistics about found media image formats? (Y/N): ");
|
DicConsole.Write("Do you want to gather statistics about found media image formats? (Y/N): ");
|
||||||
pressedKey = System.Console.ReadKey();
|
pressedKey = System.Console.ReadKey();
|
||||||
@@ -229,7 +236,9 @@ namespace DiscImageChef.Commands
|
|||||||
Settings.Settings.Current.Stats.MediaImageStats = pressedKey.Key == ConsoleKey.Y;
|
Settings.Settings.Current.Stats.MediaImageStats = pressedKey.Key == ConsoleKey.Y;
|
||||||
|
|
||||||
pressedKey = new ConsoleKeyInfo();
|
pressedKey = new ConsoleKeyInfo();
|
||||||
while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N)
|
|
||||||
|
while(pressedKey.Key != ConsoleKey.Y &&
|
||||||
|
pressedKey.Key != ConsoleKey.N)
|
||||||
{
|
{
|
||||||
DicConsole.Write("Do you want to gather statistics about scanned media? (Y/N): ");
|
DicConsole.Write("Do you want to gather statistics about scanned media? (Y/N): ");
|
||||||
pressedKey = System.Console.ReadKey();
|
pressedKey = System.Console.ReadKey();
|
||||||
@@ -239,7 +248,9 @@ namespace DiscImageChef.Commands
|
|||||||
Settings.Settings.Current.Stats.MediaScanStats = pressedKey.Key == ConsoleKey.Y;
|
Settings.Settings.Current.Stats.MediaScanStats = pressedKey.Key == ConsoleKey.Y;
|
||||||
|
|
||||||
pressedKey = new ConsoleKeyInfo();
|
pressedKey = new ConsoleKeyInfo();
|
||||||
while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N)
|
|
||||||
|
while(pressedKey.Key != ConsoleKey.Y &&
|
||||||
|
pressedKey.Key != ConsoleKey.N)
|
||||||
{
|
{
|
||||||
DicConsole.Write("Do you want to gather statistics about found partitioning schemes? (Y/N): ");
|
DicConsole.Write("Do you want to gather statistics about found partitioning schemes? (Y/N): ");
|
||||||
pressedKey = System.Console.ReadKey();
|
pressedKey = System.Console.ReadKey();
|
||||||
@@ -249,7 +260,9 @@ namespace DiscImageChef.Commands
|
|||||||
Settings.Settings.Current.Stats.PartitionStats = pressedKey.Key == ConsoleKey.Y;
|
Settings.Settings.Current.Stats.PartitionStats = pressedKey.Key == ConsoleKey.Y;
|
||||||
|
|
||||||
pressedKey = new ConsoleKeyInfo();
|
pressedKey = new ConsoleKeyInfo();
|
||||||
while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N)
|
|
||||||
|
while(pressedKey.Key != ConsoleKey.Y &&
|
||||||
|
pressedKey.Key != ConsoleKey.N)
|
||||||
{
|
{
|
||||||
DicConsole.Write("Do you want to gather statistics about media types? (Y/N): ");
|
DicConsole.Write("Do you want to gather statistics about media types? (Y/N): ");
|
||||||
pressedKey = System.Console.ReadKey();
|
pressedKey = System.Console.ReadKey();
|
||||||
@@ -259,7 +272,9 @@ namespace DiscImageChef.Commands
|
|||||||
Settings.Settings.Current.Stats.MediaStats = pressedKey.Key == ConsoleKey.Y;
|
Settings.Settings.Current.Stats.MediaStats = pressedKey.Key == ConsoleKey.Y;
|
||||||
|
|
||||||
pressedKey = new ConsoleKeyInfo();
|
pressedKey = new ConsoleKeyInfo();
|
||||||
while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N)
|
|
||||||
|
while(pressedKey.Key != ConsoleKey.Y &&
|
||||||
|
pressedKey.Key != ConsoleKey.N)
|
||||||
{
|
{
|
||||||
DicConsole.Write("Do you want to gather statistics about media image verifications? (Y/N): ");
|
DicConsole.Write("Do you want to gather statistics about media image verifications? (Y/N): ");
|
||||||
pressedKey = System.Console.ReadKey();
|
pressedKey = System.Console.ReadKey();
|
||||||
@@ -268,12 +283,14 @@ namespace DiscImageChef.Commands
|
|||||||
|
|
||||||
Settings.Settings.Current.Stats.VerifyStats = pressedKey.Key == ConsoleKey.Y;
|
Settings.Settings.Current.Stats.VerifyStats = pressedKey.Key == ConsoleKey.Y;
|
||||||
}
|
}
|
||||||
else Settings.Settings.Current.Stats = null;
|
else
|
||||||
|
Settings.Settings.Current.Stats = null;
|
||||||
#endregion Statistics
|
#endregion Statistics
|
||||||
|
|
||||||
Settings.Settings.Current.GdprCompliance = DicSettings.GdprLevel;
|
Settings.Settings.Current.GdprCompliance = DicSettings.GdprLevel;
|
||||||
Settings.Settings.SaveSettings();
|
Settings.Settings.SaveSettings();
|
||||||
return (int)ErrorNumber.NoError;
|
|
||||||
|
return(int)ErrorNumber.NoError;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -32,6 +32,8 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.CommandLine;
|
||||||
|
using System.CommandLine.Invocation;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Xml.Serialization;
|
using System.Xml.Serialization;
|
||||||
@@ -42,155 +44,181 @@ using DiscImageChef.CommonTypes.Metadata;
|
|||||||
using DiscImageChef.CommonTypes.Structs;
|
using DiscImageChef.CommonTypes.Structs;
|
||||||
using DiscImageChef.Console;
|
using DiscImageChef.Console;
|
||||||
using DiscImageChef.Core;
|
using DiscImageChef.Core;
|
||||||
using Mono.Options;
|
|
||||||
using Schemas;
|
using Schemas;
|
||||||
using ImageInfo = DiscImageChef.CommonTypes.Structs.ImageInfo;
|
using ImageInfo = DiscImageChef.CommonTypes.Structs.ImageInfo;
|
||||||
using Version = DiscImageChef.CommonTypes.Interop.Version;
|
using Version = DiscImageChef.CommonTypes.Interop.Version;
|
||||||
|
|
||||||
namespace DiscImageChef.Commands
|
namespace DiscImageChef.Commands
|
||||||
{
|
{
|
||||||
class ConvertImageCommand : Command
|
internal class ConvertImageCommand : Command
|
||||||
{
|
{
|
||||||
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;
|
|
||||||
|
|
||||||
public ConvertImageCommand() : base("convert-image", "Converts one image to another format.")
|
public ConvertImageCommand() : base("convert-image", "Converts one image to another format.")
|
||||||
{
|
{
|
||||||
Options = new OptionSet
|
Add(new Option(new[]
|
||||||
{
|
{
|
||||||
$"{MainClass.AssemblyTitle} {MainClass.AssemblyVersion?.InformationalVersion}",
|
"--cicm-xml", "-x"
|
||||||
$"{MainClass.AssemblyCopyright}",
|
}, "Take metadata from existing CICM XML sidecar.")
|
||||||
"",
|
|
||||||
$"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=",
|
Argument = new Argument<string>(() => null), Required = false
|
||||||
"Manufacturer of the drive used to read the media represented by the image.",
|
});
|
||||||
s => driveManufacturer = s
|
|
||||||
|
Add(new Option("--comments", "Image comments.")
|
||||||
|
{
|
||||||
|
Argument = new Argument<string>(() => null), Required = false
|
||||||
|
});
|
||||||
|
|
||||||
|
Add(new Option(new[]
|
||||||
|
{
|
||||||
|
"--count", "-c"
|
||||||
|
}, "How many sectors to convert at once.")
|
||||||
|
{
|
||||||
|
Argument = new Argument<int>(() => 64), Required = false
|
||||||
|
});
|
||||||
|
|
||||||
|
Add(new Option("--creator", "Who (person) created the image?.")
|
||||||
|
{
|
||||||
|
Argument = new Argument<string>(() => null), Required = false
|
||||||
|
});
|
||||||
|
|
||||||
|
Add(new Option("--drive-manufacturer",
|
||||||
|
"Manufacturer of the drive used to read the media represented by the image.")
|
||||||
|
{
|
||||||
|
Argument = new Argument<string>(() => null), Required = false
|
||||||
|
});
|
||||||
|
|
||||||
|
Add(new Option("--drive-model", "Model of the drive used to read the media represented by the image.")
|
||||||
|
{
|
||||||
|
Argument = new Argument<string>(() => null), Required = false
|
||||||
|
});
|
||||||
|
|
||||||
|
Add(new Option("--drive-revision",
|
||||||
|
"Firmware revision of the drive used to read the media represented by the image.")
|
||||||
|
{
|
||||||
|
Argument = new Argument<string>(() => null), Required = false
|
||||||
|
});
|
||||||
|
|
||||||
|
Add(new Option("--drive-serial",
|
||||||
|
"Serial number of the drive used to read the media represented by the image.")
|
||||||
|
{
|
||||||
|
Argument = new Argument<string>(() => null), Required = false
|
||||||
|
});
|
||||||
|
|
||||||
|
Add(new Option(new[]
|
||||||
|
{
|
||||||
|
"--force", "-f"
|
||||||
|
}, "Continue conversion even if sector or media tags will be lost in the process.")
|
||||||
|
{
|
||||||
|
Argument = new Argument<bool>(() => false), Required = false
|
||||||
|
});
|
||||||
|
|
||||||
|
Add(new Option(new[]
|
||||||
|
{
|
||||||
|
"--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.")
|
||||||
{
|
{
|
||||||
"drive-model=", "Model of the drive used to read the media represented by the image.",
|
Argument = new Argument<string>(() => null), Required = false
|
||||||
s => driveModel = s
|
});
|
||||||
},
|
|
||||||
|
Add(new Option("--media-barcode", "Barcode of the media represented by the image.")
|
||||||
{
|
{
|
||||||
"drive-revision=",
|
Argument = new Argument<string>(() => null), Required = false
|
||||||
"Firmware revision of the drive used to read the media represented by the image.",
|
});
|
||||||
s => driveFirmwareRevision = s
|
|
||||||
},
|
Add(new Option("--media-lastsequence",
|
||||||
|
"Last media of the sequence the media represented by the image corresponds to.")
|
||||||
{
|
{
|
||||||
"drive-serial=", "Serial number of the drive used to read the media represented by the image.",
|
Argument = new Argument<int>(() => 0), Required = false
|
||||||
s => driveSerialNumber = s
|
});
|
||||||
},
|
|
||||||
|
Add(new Option("--media-manufacturer", "Manufacturer of the media represented by the image.")
|
||||||
{
|
{
|
||||||
"force|f", "Continue conversion even if sector or media tags will be lost in the process.",
|
Argument = new Argument<string>(() => null), Required = false
|
||||||
b => force = b != null
|
});
|
||||||
},
|
|
||||||
|
Add(new Option("--media-model", "Model of the media represented by the image.")
|
||||||
{
|
{
|
||||||
"format|p=",
|
Argument = new Argument<string>(() => null), Required = false
|
||||||
"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
|
|
||||||
},
|
Add(new Option("--media-partnumber", "Part number of the media represented by the image.")
|
||||||
{"media-barcode=", "Barcode of the media represented by the image.", s => mediaBarcode = s},
|
|
||||||
{
|
{
|
||||||
"media-lastsequence=",
|
Argument = new Argument<string>(() => null), Required = false
|
||||||
"Last media of the sequence the media represented by the image corresponds to.",
|
});
|
||||||
(int i) => lastMediaSequence = i
|
|
||||||
},
|
Add(new Option("--media-sequence", "Number in sequence for the media represented by the image.")
|
||||||
{
|
{
|
||||||
"media-manufacturer=", "Manufacturer of the media represented by the image.",
|
Argument = new Argument<int>(() => 0), Required = false
|
||||||
s => mediaManufacturer = s
|
});
|
||||||
},
|
|
||||||
{"media-model=", "Model of the media represented by the image.", s => mediaModel = s},
|
Add(new Option("--media-serial", "Serial number of the media represented by the image.")
|
||||||
{
|
{
|
||||||
"media-partnumber=", "Part number of the media represented by the image.",
|
Argument = new Argument<string>(() => null), Required = false
|
||||||
s => mediaPartNumber = s
|
});
|
||||||
},
|
|
||||||
|
Add(new Option("--media-title", "Title of the media represented by the image.")
|
||||||
{
|
{
|
||||||
"media-sequence=", "Number in sequence for the media represented by the image.",
|
Argument = new Argument<string>(() => null), Required = false
|
||||||
(int i) => mediaSequence = i
|
});
|
||||||
},
|
|
||||||
|
Add(new Option(new[]
|
||||||
{
|
{
|
||||||
"media-serial=", "Serial number of the media represented by the image.",
|
"--options", "-O"
|
||||||
s => mediaSerialNumber = s
|
}, "Comma separated name=value pairs of options to pass to output image plugin.")
|
||||||
},
|
|
||||||
{"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.",
|
Argument = new Argument<string>(() => null), Required = false
|
||||||
s => outputOptions = s
|
});
|
||||||
},
|
|
||||||
{"resume-file|r=", "Take list of dump hardware from existing resume file.", s => resumeFile = s},
|
Add(new Option(new[]
|
||||||
{"help|h|?", "Show this message and exit.", v => showHelp = v != null}
|
{
|
||||||
};
|
"--resume-file", "-r"
|
||||||
|
}, "Take list of dump hardware from existing resume file.")
|
||||||
|
{
|
||||||
|
Argument = new Argument<string>(() => null), Required = false
|
||||||
|
});
|
||||||
|
|
||||||
|
AddArgument(new Argument<string>
|
||||||
|
{
|
||||||
|
Arity = ArgumentArity.ExactlyOne, Description = "Input image path", Name = "input-path"
|
||||||
|
});
|
||||||
|
|
||||||
|
AddArgument(new Argument<string>
|
||||||
|
{
|
||||||
|
Arity = ArgumentArity.ExactlyOne, Description = "Output image path", Name = "output-path"
|
||||||
|
});
|
||||||
|
|
||||||
|
Handler = CommandHandler.Create(GetType().GetMethod(nameof(Invoke)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override int Invoke(IEnumerable<string> arguments)
|
static int Invoke(bool verbose, bool debug, string cicmXml, string comments, int count, string creator,
|
||||||
|
string driveFirmwareRevision, string driveManufacturer, string driveModel,
|
||||||
|
string driveSerialNumber, bool force, string inputPath, int lastMediaSequence,
|
||||||
|
string mediaBarcode, string mediaManufacturer, string mediaModel, string mediaPartNumber,
|
||||||
|
int mediaSequence, string mediaSerialNumber, string mediaTitle, string outputPath,
|
||||||
|
string outputOptions, string resumeFile, string format)
|
||||||
{
|
{
|
||||||
List<string> extra = Options.Parse(arguments);
|
|
||||||
|
|
||||||
if(showHelp)
|
|
||||||
{
|
|
||||||
Options.WriteOptionDescriptions(CommandSet.Out);
|
|
||||||
return (int)ErrorNumber.HelpRequested;
|
|
||||||
}
|
|
||||||
|
|
||||||
MainClass.PrintCopyright();
|
MainClass.PrintCopyright();
|
||||||
if(MainClass.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
|
||||||
if(MainClass.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
if(debug)
|
||||||
|
DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
||||||
|
|
||||||
|
if(verbose)
|
||||||
|
DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
||||||
|
|
||||||
Statistics.AddCommand("convert-image");
|
Statistics.AddCommand("convert-image");
|
||||||
|
|
||||||
if(extra.Count > 2)
|
|
||||||
{
|
|
||||||
DicConsole.ErrorWriteLine("Too many arguments.");
|
|
||||||
return (int)ErrorNumber.UnexpectedArgumentCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(extra.Count <= 1)
|
|
||||||
{
|
|
||||||
DicConsole.ErrorWriteLine("Missing input image.");
|
|
||||||
return (int)ErrorNumber.MissingArgument;
|
|
||||||
}
|
|
||||||
|
|
||||||
inputFile = extra[0];
|
|
||||||
outputFile = extra[1];
|
|
||||||
|
|
||||||
DicConsole.DebugWriteLine("Analyze command", "--cicm-xml={0}", cicmXml);
|
DicConsole.DebugWriteLine("Analyze command", "--cicm-xml={0}", cicmXml);
|
||||||
DicConsole.DebugWriteLine("Analyze command", "--comments={0}", comments);
|
DicConsole.DebugWriteLine("Analyze command", "--comments={0}", comments);
|
||||||
DicConsole.DebugWriteLine("Analyze command", "--count={0}", count);
|
DicConsole.DebugWriteLine("Analyze command", "--count={0}", count);
|
||||||
DicConsole.DebugWriteLine("Analyze command", "--creator={0}", creator);
|
DicConsole.DebugWriteLine("Analyze command", "--creator={0}", creator);
|
||||||
DicConsole.DebugWriteLine("Analyze command", "--debug={0}", MainClass.Debug);
|
DicConsole.DebugWriteLine("Analyze command", "--debug={0}", debug);
|
||||||
DicConsole.DebugWriteLine("Analyze command", "--drive-manufacturer={0}", driveManufacturer);
|
DicConsole.DebugWriteLine("Analyze command", "--drive-manufacturer={0}", driveManufacturer);
|
||||||
DicConsole.DebugWriteLine("Analyze command", "--drive-model={0}", driveModel);
|
DicConsole.DebugWriteLine("Analyze command", "--drive-model={0}", driveModel);
|
||||||
DicConsole.DebugWriteLine("Analyze command", "--drive-revision={0}", driveFirmwareRevision);
|
DicConsole.DebugWriteLine("Analyze command", "--drive-revision={0}", driveFirmwareRevision);
|
||||||
DicConsole.DebugWriteLine("Analyze command", "--drive-serial={0}", driveSerialNumber);
|
DicConsole.DebugWriteLine("Analyze command", "--drive-serial={0}", driveSerialNumber);
|
||||||
DicConsole.DebugWriteLine("Analyze command", "--force={0}", force);
|
DicConsole.DebugWriteLine("Analyze command", "--force={0}", force);
|
||||||
DicConsole.DebugWriteLine("Analyze command", "--format={0}", wantedOutputFormat);
|
DicConsole.DebugWriteLine("Analyze command", "--format={0}", format);
|
||||||
DicConsole.DebugWriteLine("Analyze command", "--input={0}", inputFile);
|
DicConsole.DebugWriteLine("Analyze command", "--input={0}", inputPath);
|
||||||
DicConsole.DebugWriteLine("Analyze command", "--media-barcode={0}", mediaBarcode);
|
DicConsole.DebugWriteLine("Analyze command", "--media-barcode={0}", mediaBarcode);
|
||||||
DicConsole.DebugWriteLine("Analyze command", "--media-lastsequence={0}", lastMediaSequence);
|
DicConsole.DebugWriteLine("Analyze command", "--media-lastsequence={0}", lastMediaSequence);
|
||||||
DicConsole.DebugWriteLine("Analyze command", "--media-manufacturer={0}", mediaManufacturer);
|
DicConsole.DebugWriteLine("Analyze command", "--media-manufacturer={0}", mediaManufacturer);
|
||||||
@@ -200,77 +228,87 @@ namespace DiscImageChef.Commands
|
|||||||
DicConsole.DebugWriteLine("Analyze command", "--media-serial={0}", mediaSerialNumber);
|
DicConsole.DebugWriteLine("Analyze command", "--media-serial={0}", mediaSerialNumber);
|
||||||
DicConsole.DebugWriteLine("Analyze command", "--media-title={0}", mediaTitle);
|
DicConsole.DebugWriteLine("Analyze command", "--media-title={0}", mediaTitle);
|
||||||
DicConsole.DebugWriteLine("Analyze command", "--options={0}", outputOptions);
|
DicConsole.DebugWriteLine("Analyze command", "--options={0}", outputOptions);
|
||||||
DicConsole.DebugWriteLine("Analyze command", "--output={0}", outputFile);
|
DicConsole.DebugWriteLine("Analyze command", "--output={0}", outputPath);
|
||||||
DicConsole.DebugWriteLine("Analyze command", "--resume-file={0}", resumeFile);
|
DicConsole.DebugWriteLine("Analyze command", "--resume-file={0}", resumeFile);
|
||||||
DicConsole.DebugWriteLine("Analyze command", "--verbose={0}", MainClass.Verbose);
|
DicConsole.DebugWriteLine("Analyze command", "--verbose={0}", verbose);
|
||||||
|
|
||||||
Dictionary<string, string> parsedOptions = Core.Options.Parse(outputOptions);
|
Dictionary<string, string> parsedOptions = Core.Options.Parse(outputOptions);
|
||||||
DicConsole.DebugWriteLine("Analyze command", "Parsed options:");
|
DicConsole.DebugWriteLine("Analyze command", "Parsed options:");
|
||||||
|
|
||||||
foreach(KeyValuePair<string, string> parsedOption in parsedOptions)
|
foreach(KeyValuePair<string, string> parsedOption in parsedOptions)
|
||||||
DicConsole.DebugWriteLine("Analyze command", "{0} = {1}", parsedOption.Key, parsedOption.Value);
|
DicConsole.DebugWriteLine("Analyze command", "{0} = {1}", parsedOption.Key, parsedOption.Value);
|
||||||
|
|
||||||
if(count == 0)
|
if(count == 0)
|
||||||
{
|
{
|
||||||
DicConsole.ErrorWriteLine("Need to specify more than 0 sectors to copy at once");
|
DicConsole.ErrorWriteLine("Need to specify more than 0 sectors to copy at once");
|
||||||
return (int)ErrorNumber.InvalidArgument;
|
|
||||||
|
return(int)ErrorNumber.InvalidArgument;
|
||||||
}
|
}
|
||||||
|
|
||||||
Resume resume = null;
|
Resume resume = null;
|
||||||
CICMMetadataType sidecar = null;
|
CICMMetadataType sidecar = null;
|
||||||
|
|
||||||
XmlSerializer xs = new XmlSerializer(typeof(CICMMetadataType));
|
var xs = new XmlSerializer(typeof(CICMMetadataType));
|
||||||
|
|
||||||
if(cicmXml != null)
|
if(cicmXml != null)
|
||||||
if(File.Exists(cicmXml))
|
if(File.Exists(cicmXml))
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
StreamReader sr = new StreamReader(cicmXml);
|
var sr = new StreamReader(cicmXml);
|
||||||
sidecar = (CICMMetadataType)xs.Deserialize(sr);
|
sidecar = (CICMMetadataType)xs.Deserialize(sr);
|
||||||
sr.Close();
|
sr.Close();
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
DicConsole.ErrorWriteLine("Incorrect metadata sidecar file, not continuing...");
|
DicConsole.ErrorWriteLine("Incorrect metadata sidecar file, not continuing...");
|
||||||
return (int)ErrorNumber.InvalidSidecar;
|
|
||||||
|
return(int)ErrorNumber.InvalidSidecar;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DicConsole.ErrorWriteLine("Could not find metadata sidecar, not continuing...");
|
DicConsole.ErrorWriteLine("Could not find metadata sidecar, not continuing...");
|
||||||
return (int)ErrorNumber.FileNotFound;
|
|
||||||
|
return(int)ErrorNumber.FileNotFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
xs = new XmlSerializer(typeof(Resume));
|
xs = new XmlSerializer(typeof(Resume));
|
||||||
|
|
||||||
if(resumeFile != null)
|
if(resumeFile != null)
|
||||||
if(File.Exists(resumeFile))
|
if(File.Exists(resumeFile))
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
StreamReader sr = new StreamReader(resumeFile);
|
var sr = new StreamReader(resumeFile);
|
||||||
resume = (Resume)xs.Deserialize(sr);
|
resume = (Resume)xs.Deserialize(sr);
|
||||||
sr.Close();
|
sr.Close();
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
DicConsole.ErrorWriteLine("Incorrect resume file, not continuing...");
|
DicConsole.ErrorWriteLine("Incorrect resume file, not continuing...");
|
||||||
return (int)ErrorNumber.InvalidResume;
|
|
||||||
|
return(int)ErrorNumber.InvalidResume;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DicConsole.ErrorWriteLine("Could not find resume file, not continuing...");
|
DicConsole.ErrorWriteLine("Could not find resume file, not continuing...");
|
||||||
return (int)ErrorNumber.FileNotFound;
|
|
||||||
|
return(int)ErrorNumber.FileNotFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
FiltersList filtersList = new FiltersList();
|
var filtersList = new FiltersList();
|
||||||
IFilter inputFilter = filtersList.GetFilter(inputFile);
|
IFilter inputFilter = filtersList.GetFilter(inputPath);
|
||||||
|
|
||||||
if(inputFilter == null)
|
if(inputFilter == null)
|
||||||
{
|
{
|
||||||
DicConsole.ErrorWriteLine("Cannot open specified file.");
|
DicConsole.ErrorWriteLine("Cannot open specified file.");
|
||||||
return (int)ErrorNumber.CannotOpenFile;
|
|
||||||
|
return(int)ErrorNumber.CannotOpenFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(File.Exists(outputFile))
|
if(File.Exists(outputPath))
|
||||||
{
|
{
|
||||||
DicConsole.ErrorWriteLine("Output file already exists, not continuing.");
|
DicConsole.ErrorWriteLine("Output file already exists, not continuing.");
|
||||||
return (int)ErrorNumber.DestinationExists;
|
|
||||||
|
return(int)ErrorNumber.DestinationExists;
|
||||||
}
|
}
|
||||||
|
|
||||||
PluginBase plugins = GetPluginBase.Instance;
|
PluginBase plugins = GetPluginBase.Instance;
|
||||||
@@ -279,13 +317,15 @@ namespace DiscImageChef.Commands
|
|||||||
if(inputFormat == null)
|
if(inputFormat == null)
|
||||||
{
|
{
|
||||||
DicConsole.WriteLine("Input image format not identified, not proceeding with conversion.");
|
DicConsole.WriteLine("Input image format not identified, not proceeding with conversion.");
|
||||||
return (int)ErrorNumber.UnrecognizedFormat;
|
|
||||||
|
return(int)ErrorNumber.UnrecognizedFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(MainClass.Verbose)
|
if(verbose)
|
||||||
DicConsole.VerboseWriteLine("Input image format identified by {0} ({1}).", inputFormat.Name,
|
DicConsole.VerboseWriteLine("Input image format identified by {0} ({1}).", inputFormat.Name,
|
||||||
inputFormat.Id);
|
inputFormat.Id);
|
||||||
else DicConsole.WriteLine("Input image format identified by {0}.", inputFormat.Name);
|
else
|
||||||
|
DicConsole.WriteLine("Input image format identified by {0}.", inputFormat.Name);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -293,13 +333,17 @@ namespace DiscImageChef.Commands
|
|||||||
{
|
{
|
||||||
DicConsole.WriteLine("Unable to open image format");
|
DicConsole.WriteLine("Unable to open image format");
|
||||||
DicConsole.WriteLine("No error given");
|
DicConsole.WriteLine("No error given");
|
||||||
return (int)ErrorNumber.CannotOpenFormat;
|
|
||||||
|
return(int)ErrorNumber.CannotOpenFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
DicConsole.DebugWriteLine("Convert-image command", "Correctly opened image file.");
|
DicConsole.DebugWriteLine("Convert-image command", "Correctly opened image file.");
|
||||||
|
|
||||||
DicConsole.DebugWriteLine("Convert-image command", "Image without headers is {0} bytes.",
|
DicConsole.DebugWriteLine("Convert-image command", "Image without headers is {0} bytes.",
|
||||||
inputFormat.Info.ImageSize);
|
inputFormat.Info.ImageSize);
|
||||||
|
|
||||||
DicConsole.DebugWriteLine("Convert-image command", "Image has {0} sectors.", inputFormat.Info.Sectors);
|
DicConsole.DebugWriteLine("Convert-image command", "Image has {0} sectors.", inputFormat.Info.Sectors);
|
||||||
|
|
||||||
DicConsole.DebugWriteLine("Convert-image command", "Image identifies media type as {0}.",
|
DicConsole.DebugWriteLine("Convert-image command", "Image identifies media type as {0}.",
|
||||||
inputFormat.Info.MediaType);
|
inputFormat.Info.MediaType);
|
||||||
|
|
||||||
@@ -312,85 +356,101 @@ namespace DiscImageChef.Commands
|
|||||||
DicConsole.ErrorWriteLine("Unable to open image format");
|
DicConsole.ErrorWriteLine("Unable to open image format");
|
||||||
DicConsole.ErrorWriteLine("Error: {0}", ex.Message);
|
DicConsole.ErrorWriteLine("Error: {0}", ex.Message);
|
||||||
DicConsole.DebugWriteLine("Convert-image command", "Stack trace: {0}", ex.StackTrace);
|
DicConsole.DebugWriteLine("Convert-image command", "Stack trace: {0}", ex.StackTrace);
|
||||||
return (int)ErrorNumber.CannotOpenFormat;
|
|
||||||
|
return(int)ErrorNumber.CannotOpenFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<IWritableImage> candidates = new List<IWritableImage>();
|
List<IWritableImage> candidates = new List<IWritableImage>();
|
||||||
|
|
||||||
// Try extension
|
// Try extension
|
||||||
if(string.IsNullOrEmpty(wantedOutputFormat))
|
if(string.IsNullOrEmpty(format))
|
||||||
candidates.AddRange(plugins.WritableImages.Values.Where(t =>
|
candidates.AddRange(plugins.WritableImages.Values.Where(t =>
|
||||||
t.KnownExtensions
|
t.KnownExtensions.
|
||||||
.Contains(Path.GetExtension(outputFile))));
|
Contains(Path.GetExtension(outputPath))));
|
||||||
|
|
||||||
// Try Id
|
// Try Id
|
||||||
else if(Guid.TryParse(wantedOutputFormat, out Guid outId))
|
else if(Guid.TryParse(format, out Guid outId))
|
||||||
candidates.AddRange(plugins.WritableImages.Values.Where(t => t.Id.Equals(outId)));
|
candidates.AddRange(plugins.WritableImages.Values.Where(t => t.Id.Equals(outId)));
|
||||||
|
|
||||||
// Try name
|
// Try name
|
||||||
else
|
else
|
||||||
candidates.AddRange(plugins.WritableImages.Values.Where(t => string.Equals(t.Name, wantedOutputFormat,
|
candidates.AddRange(plugins.WritableImages.Values.Where(t => string.Equals(t.Name, format,
|
||||||
StringComparison
|
StringComparison.
|
||||||
.InvariantCultureIgnoreCase)));
|
InvariantCultureIgnoreCase)));
|
||||||
|
|
||||||
if(candidates.Count == 0)
|
if(candidates.Count == 0)
|
||||||
{
|
{
|
||||||
DicConsole.WriteLine("No plugin supports requested extension.");
|
DicConsole.WriteLine("No plugin supports requested extension.");
|
||||||
return (int)ErrorNumber.FormatNotFound;
|
|
||||||
|
return(int)ErrorNumber.FormatNotFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(candidates.Count > 1)
|
if(candidates.Count > 1)
|
||||||
{
|
{
|
||||||
DicConsole.WriteLine("More than one plugin supports requested extension.");
|
DicConsole.WriteLine("More than one plugin supports requested extension.");
|
||||||
return (int)ErrorNumber.TooManyFormats;
|
|
||||||
|
return(int)ErrorNumber.TooManyFormats;
|
||||||
}
|
}
|
||||||
|
|
||||||
IWritableImage outputFormat = candidates[0];
|
IWritableImage outputFormat = candidates[0];
|
||||||
|
|
||||||
if(MainClass.Verbose)
|
if(verbose)
|
||||||
DicConsole.VerboseWriteLine("Output image format: {0} ({1}).", outputFormat.Name, outputFormat.Id);
|
DicConsole.VerboseWriteLine("Output image format: {0} ({1}).", outputFormat.Name, outputFormat.Id);
|
||||||
else DicConsole.WriteLine("Output image format: {0}.", outputFormat.Name);
|
else
|
||||||
|
DicConsole.WriteLine("Output image format: {0}.", outputFormat.Name);
|
||||||
|
|
||||||
if(!outputFormat.SupportedMediaTypes.Contains(inputFormat.Info.MediaType))
|
if(!outputFormat.SupportedMediaTypes.Contains(inputFormat.Info.MediaType))
|
||||||
{
|
{
|
||||||
DicConsole.ErrorWriteLine("Output format does not support media type, cannot continue...");
|
DicConsole.ErrorWriteLine("Output format does not support media type, cannot continue...");
|
||||||
return (int)ErrorNumber.UnsupportedMedia;
|
|
||||||
|
return(int)ErrorNumber.UnsupportedMedia;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach(MediaTagType mediaTag in inputFormat.Info.ReadableMediaTags)
|
foreach(MediaTagType mediaTag in inputFormat.Info.ReadableMediaTags)
|
||||||
{
|
{
|
||||||
if(outputFormat.SupportedMediaTags.Contains(mediaTag) || force) continue;
|
if(outputFormat.SupportedMediaTags.Contains(mediaTag) || force)
|
||||||
|
continue;
|
||||||
|
|
||||||
DicConsole.ErrorWriteLine("Converting image will lose media tag {0}, not continuing...", mediaTag);
|
DicConsole.ErrorWriteLine("Converting image will lose media tag {0}, not continuing...", mediaTag);
|
||||||
DicConsole.ErrorWriteLine("If you don't care, use force option.");
|
DicConsole.ErrorWriteLine("If you don't care, use force option.");
|
||||||
return (int)ErrorNumber.DataWillBeLost;
|
|
||||||
|
return(int)ErrorNumber.DataWillBeLost;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool useLong = inputFormat.Info.ReadableSectorTags.Count != 0;
|
bool useLong = inputFormat.Info.ReadableSectorTags.Count != 0;
|
||||||
|
|
||||||
foreach(SectorTagType sectorTag in inputFormat.Info.ReadableSectorTags)
|
foreach(SectorTagType sectorTag in inputFormat.Info.ReadableSectorTags)
|
||||||
{
|
{
|
||||||
if(outputFormat.SupportedSectorTags.Contains(sectorTag)) continue;
|
if(outputFormat.SupportedSectorTags.Contains(sectorTag))
|
||||||
|
continue;
|
||||||
|
|
||||||
if(force)
|
if(force)
|
||||||
{
|
{
|
||||||
if(sectorTag != SectorTagType.CdTrackFlags && sectorTag != SectorTagType.CdTrackIsrc &&
|
if(sectorTag != SectorTagType.CdTrackFlags &&
|
||||||
sectorTag != SectorTagType.CdSectorSubchannel) useLong = false;
|
sectorTag != SectorTagType.CdTrackIsrc &&
|
||||||
|
sectorTag != SectorTagType.CdSectorSubchannel)
|
||||||
|
useLong = false;
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
DicConsole.ErrorWriteLine("Converting image will lose sector tag {0}, not continuing...", sectorTag);
|
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.");
|
DicConsole.
|
||||||
return (int)ErrorNumber.DataWillBeLost;
|
ErrorWriteLine("If you don't care, use force option. This will skip all sector tags converting only user data.");
|
||||||
|
|
||||||
|
return(int)ErrorNumber.DataWillBeLost;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!outputFormat.Create(outputFile, inputFormat.Info.MediaType, parsedOptions, inputFormat.Info.Sectors,
|
if(!outputFormat.Create(outputPath, inputFormat.Info.MediaType, parsedOptions, inputFormat.Info.Sectors,
|
||||||
inputFormat.Info.SectorSize))
|
inputFormat.Info.SectorSize))
|
||||||
{
|
{
|
||||||
DicConsole.ErrorWriteLine("Error {0} creating output image.", outputFormat.ErrorMessage);
|
DicConsole.ErrorWriteLine("Error {0} creating output image.", outputFormat.ErrorMessage);
|
||||||
return (int)ErrorNumber.CannotCreateFormat;
|
|
||||||
|
return(int)ErrorNumber.CannotCreateFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageInfo metadata = new ImageInfo
|
var metadata = new ImageInfo
|
||||||
{
|
{
|
||||||
Application = "DiscImageChef",
|
Application = "DiscImageChef",
|
||||||
ApplicationVersion = Version.GetVersion(),
|
ApplicationVersion = Version.GetVersion(),
|
||||||
@@ -413,10 +473,12 @@ namespace DiscImageChef.Commands
|
|||||||
if(!outputFormat.SetMetadata(metadata))
|
if(!outputFormat.SetMetadata(metadata))
|
||||||
{
|
{
|
||||||
DicConsole.ErrorWrite("Error {0} setting metadata, ", outputFormat.ErrorMessage);
|
DicConsole.ErrorWrite("Error {0} setting metadata, ", outputFormat.ErrorMessage);
|
||||||
|
|
||||||
if(!force)
|
if(!force)
|
||||||
{
|
{
|
||||||
DicConsole.ErrorWriteLine("not continuing...");
|
DicConsole.ErrorWriteLine("not continuing...");
|
||||||
return (int)ErrorNumber.WriteError;
|
|
||||||
|
return(int)ErrorNumber.WriteError;
|
||||||
}
|
}
|
||||||
|
|
||||||
DicConsole.ErrorWriteLine("continuing...");
|
DicConsole.ErrorWriteLine("continuing...");
|
||||||
@@ -427,11 +489,14 @@ namespace DiscImageChef.Commands
|
|||||||
|
|
||||||
foreach(MediaTagType mediaTag in inputFormat.Info.ReadableMediaTags)
|
foreach(MediaTagType mediaTag in inputFormat.Info.ReadableMediaTags)
|
||||||
{
|
{
|
||||||
if(force && !outputFormat.SupportedMediaTags.Contains(mediaTag)) continue;
|
if(force && !outputFormat.SupportedMediaTags.Contains(mediaTag))
|
||||||
|
continue;
|
||||||
|
|
||||||
DicConsole.WriteLine("Converting media tag {0}", mediaTag);
|
DicConsole.WriteLine("Converting media tag {0}", mediaTag);
|
||||||
byte[] tag = inputFormat.ReadDiskTag(mediaTag);
|
byte[] tag = inputFormat.ReadDiskTag(mediaTag);
|
||||||
if(outputFormat.WriteMediaTag(tag, mediaTag)) continue;
|
|
||||||
|
if(outputFormat.WriteMediaTag(tag, mediaTag))
|
||||||
|
continue;
|
||||||
|
|
||||||
if(force)
|
if(force)
|
||||||
DicConsole.ErrorWriteLine("Error {0} writing media tag, continuing...", outputFormat.ErrorMessage);
|
DicConsole.ErrorWriteLine("Error {0} writing media tag, continuing...", outputFormat.ErrorMessage);
|
||||||
@@ -439,35 +504,41 @@ namespace DiscImageChef.Commands
|
|||||||
{
|
{
|
||||||
DicConsole.ErrorWriteLine("Error {0} writing media tag, not continuing...",
|
DicConsole.ErrorWriteLine("Error {0} writing media tag, not continuing...",
|
||||||
outputFormat.ErrorMessage);
|
outputFormat.ErrorMessage);
|
||||||
return (int)ErrorNumber.WriteError;
|
|
||||||
|
return(int)ErrorNumber.WriteError;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DicConsole.WriteLine("{0} sectors to convert", inputFormat.Info.Sectors);
|
DicConsole.WriteLine("{0} sectors to convert", inputFormat.Info.Sectors);
|
||||||
ulong doneSectors = 0;
|
ulong doneSectors = 0;
|
||||||
|
|
||||||
if(inputFormat is IOpticalMediaImage inputOptical && outputFormat is IWritableOpticalImage outputOptical &&
|
if(inputFormat is IOpticalMediaImage inputOptical &&
|
||||||
|
outputFormat is IWritableOpticalImage outputOptical &&
|
||||||
inputOptical.Tracks != null)
|
inputOptical.Tracks != null)
|
||||||
{
|
{
|
||||||
if(!outputOptical.SetTracks(inputOptical.Tracks))
|
if(!outputOptical.SetTracks(inputOptical.Tracks))
|
||||||
{
|
{
|
||||||
DicConsole.ErrorWriteLine("Error {0} sending tracks list to output image.",
|
DicConsole.ErrorWriteLine("Error {0} sending tracks list to output image.",
|
||||||
outputFormat.ErrorMessage);
|
outputFormat.ErrorMessage);
|
||||||
return (int)ErrorNumber.WriteError;
|
|
||||||
|
return(int)ErrorNumber.WriteError;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach(Track track in inputOptical.Tracks)
|
foreach(Track track in inputOptical.Tracks)
|
||||||
{
|
{
|
||||||
doneSectors = 0;
|
doneSectors = 0;
|
||||||
ulong trackSectors = track.TrackEndSector - track.TrackStartSector + 1;
|
ulong trackSectors = (track.TrackEndSector - track.TrackStartSector) + 1;
|
||||||
|
|
||||||
while(doneSectors < trackSectors)
|
while(doneSectors < trackSectors)
|
||||||
{
|
{
|
||||||
byte[] sector;
|
byte[] sector;
|
||||||
|
|
||||||
uint sectorsToDo;
|
uint sectorsToDo;
|
||||||
if(trackSectors - doneSectors >= (ulong)count) sectorsToDo = (uint)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)",
|
DicConsole.Write("\rConverting sectors {0} to {1} in track {3} ({2:P2} done)",
|
||||||
doneSectors + track.TrackStartSector,
|
doneSectors + track.TrackStartSector,
|
||||||
@@ -476,6 +547,7 @@ namespace DiscImageChef.Commands
|
|||||||
track.TrackSequence);
|
track.TrackSequence);
|
||||||
|
|
||||||
bool result;
|
bool result;
|
||||||
|
|
||||||
if(useLong)
|
if(useLong)
|
||||||
if(sectorsToDo == 1)
|
if(sectorsToDo == 1)
|
||||||
{
|
{
|
||||||
@@ -485,6 +557,7 @@ namespace DiscImageChef.Commands
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
sector = inputFormat.ReadSectorsLong(doneSectors + track.TrackStartSector, sectorsToDo);
|
sector = inputFormat.ReadSectorsLong(doneSectors + track.TrackStartSector, sectorsToDo);
|
||||||
|
|
||||||
result = outputFormat.WriteSectorsLong(sector, doneSectors + track.TrackStartSector,
|
result = outputFormat.WriteSectorsLong(sector, doneSectors + track.TrackStartSector,
|
||||||
sectorsToDo);
|
sectorsToDo);
|
||||||
}
|
}
|
||||||
@@ -498,6 +571,7 @@ namespace DiscImageChef.Commands
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
sector = inputFormat.ReadSectors(doneSectors + track.TrackStartSector, sectorsToDo);
|
sector = inputFormat.ReadSectors(doneSectors + track.TrackStartSector, sectorsToDo);
|
||||||
|
|
||||||
result = outputFormat.WriteSectors(sector, doneSectors + track.TrackStartSector,
|
result = outputFormat.WriteSectors(sector, doneSectors + track.TrackStartSector,
|
||||||
sectorsToDo);
|
sectorsToDo);
|
||||||
}
|
}
|
||||||
@@ -511,7 +585,8 @@ namespace DiscImageChef.Commands
|
|||||||
{
|
{
|
||||||
DicConsole.ErrorWriteLine("Error {0} writing sector {1}, not continuing...",
|
DicConsole.ErrorWriteLine("Error {0} writing sector {1}, not continuing...",
|
||||||
outputFormat.ErrorMessage, doneSectors);
|
outputFormat.ErrorMessage, doneSectors);
|
||||||
return (int)ErrorNumber.WriteError;
|
|
||||||
|
return(int)ErrorNumber.WriteError;
|
||||||
}
|
}
|
||||||
|
|
||||||
doneSectors += sectorsToDo;
|
doneSectors += sectorsToDo;
|
||||||
@@ -520,11 +595,13 @@ namespace DiscImageChef.Commands
|
|||||||
|
|
||||||
DicConsole.Write("\rConverting sectors {0} to {1} in track {3} ({2:P2} done)", inputFormat.Info.Sectors,
|
DicConsole.Write("\rConverting sectors {0} to {1} in track {3} ({2:P2} done)", inputFormat.Info.Sectors,
|
||||||
inputFormat.Info.Sectors, 1.0, inputOptical.Tracks.Count);
|
inputFormat.Info.Sectors, 1.0, inputOptical.Tracks.Count);
|
||||||
|
|
||||||
DicConsole.WriteLine();
|
DicConsole.WriteLine();
|
||||||
|
|
||||||
foreach(SectorTagType tag in inputFormat.Info.ReadableSectorTags.OrderBy(t => t))
|
foreach(SectorTagType tag in inputFormat.Info.ReadableSectorTags.OrderBy(t => t))
|
||||||
{
|
{
|
||||||
if(!useLong) break;
|
if(!useLong)
|
||||||
|
break;
|
||||||
|
|
||||||
switch(tag)
|
switch(tag)
|
||||||
{
|
{
|
||||||
@@ -540,12 +617,13 @@ namespace DiscImageChef.Commands
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(force && !outputFormat.SupportedSectorTags.Contains(tag)) continue;
|
if(force && !outputFormat.SupportedSectorTags.Contains(tag))
|
||||||
|
continue;
|
||||||
|
|
||||||
foreach(Track track in inputOptical.Tracks)
|
foreach(Track track in inputOptical.Tracks)
|
||||||
{
|
{
|
||||||
doneSectors = 0;
|
doneSectors = 0;
|
||||||
ulong trackSectors = track.TrackEndSector - track.TrackStartSector + 1;
|
ulong trackSectors = (track.TrackEndSector - track.TrackStartSector) + 1;
|
||||||
byte[] sector;
|
byte[] sector;
|
||||||
bool result;
|
bool result;
|
||||||
|
|
||||||
@@ -556,8 +634,10 @@ namespace DiscImageChef.Commands
|
|||||||
DicConsole.Write("\rConverting tag {0} in track {1} ({2:P2} done).", tag,
|
DicConsole.Write("\rConverting tag {0} in track {1} ({2:P2} done).", tag,
|
||||||
track.TrackSequence,
|
track.TrackSequence,
|
||||||
track.TrackSequence / (double)inputOptical.Tracks.Count);
|
track.TrackSequence / (double)inputOptical.Tracks.Count);
|
||||||
|
|
||||||
sector = inputFormat.ReadSectorTag(track.TrackStartSector, tag);
|
sector = inputFormat.ReadSectorTag(track.TrackStartSector, tag);
|
||||||
result = outputFormat.WriteSectorTag(sector, track.TrackStartSector, tag);
|
result = outputFormat.WriteSectorTag(sector, track.TrackStartSector, tag);
|
||||||
|
|
||||||
if(!result)
|
if(!result)
|
||||||
if(force)
|
if(force)
|
||||||
DicConsole.ErrorWriteLine("Error {0} writing tag, continuing...",
|
DicConsole.ErrorWriteLine("Error {0} writing tag, continuing...",
|
||||||
@@ -566,7 +646,8 @@ namespace DiscImageChef.Commands
|
|||||||
{
|
{
|
||||||
DicConsole.ErrorWriteLine("Error {0} writing tag, not continuing...",
|
DicConsole.ErrorWriteLine("Error {0} writing tag, not continuing...",
|
||||||
outputFormat.ErrorMessage);
|
outputFormat.ErrorMessage);
|
||||||
return (int)ErrorNumber.WriteError;
|
|
||||||
|
return(int)ErrorNumber.WriteError;
|
||||||
}
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
@@ -575,10 +656,11 @@ namespace DiscImageChef.Commands
|
|||||||
while(doneSectors < trackSectors)
|
while(doneSectors < trackSectors)
|
||||||
{
|
{
|
||||||
uint sectorsToDo;
|
uint sectorsToDo;
|
||||||
if(trackSectors - doneSectors >= (ulong)count) sectorsToDo = (uint)count;
|
|
||||||
|
if(trackSectors - doneSectors >= (ulong)count)
|
||||||
|
sectorsToDo = (uint)count;
|
||||||
else
|
else
|
||||||
sectorsToDo =
|
sectorsToDo = (uint)(trackSectors - doneSectors);
|
||||||
(uint)(trackSectors - doneSectors);
|
|
||||||
|
|
||||||
DicConsole.Write("\rConverting tag {4} for sectors {0} to {1} in track {3} ({2:P2} done)",
|
DicConsole.Write("\rConverting tag {4} for sectors {0} to {1} in track {3} ({2:P2} done)",
|
||||||
doneSectors + track.TrackStartSector,
|
doneSectors + track.TrackStartSector,
|
||||||
@@ -595,6 +677,7 @@ namespace DiscImageChef.Commands
|
|||||||
{
|
{
|
||||||
sector = inputFormat.ReadSectorsTag(doneSectors + track.TrackStartSector, sectorsToDo,
|
sector = inputFormat.ReadSectorsTag(doneSectors + track.TrackStartSector, sectorsToDo,
|
||||||
tag);
|
tag);
|
||||||
|
|
||||||
result = outputFormat.WriteSectorsTag(sector, doneSectors + track.TrackStartSector,
|
result = outputFormat.WriteSectorsTag(sector, doneSectors + track.TrackStartSector,
|
||||||
sectorsToDo, tag);
|
sectorsToDo, tag);
|
||||||
}
|
}
|
||||||
@@ -607,7 +690,8 @@ namespace DiscImageChef.Commands
|
|||||||
{
|
{
|
||||||
DicConsole.ErrorWriteLine("Error {0} writing tag for sector {1}, not continuing...",
|
DicConsole.ErrorWriteLine("Error {0} writing tag for sector {1}, not continuing...",
|
||||||
outputFormat.ErrorMessage, doneSectors);
|
outputFormat.ErrorMessage, doneSectors);
|
||||||
return (int)ErrorNumber.WriteError;
|
|
||||||
|
return(int)ErrorNumber.WriteError;
|
||||||
}
|
}
|
||||||
|
|
||||||
doneSectors += sectorsToDo;
|
doneSectors += sectorsToDo;
|
||||||
@@ -620,11 +704,13 @@ namespace DiscImageChef.Commands
|
|||||||
case SectorTagType.CdTrackIsrc:
|
case SectorTagType.CdTrackIsrc:
|
||||||
DicConsole.Write("\rConverting tag {0} in track {1} ({2:P2} done).", tag,
|
DicConsole.Write("\rConverting tag {0} in track {1} ({2:P2} done).", tag,
|
||||||
inputOptical.Tracks.Count, 1.0);
|
inputOptical.Tracks.Count, 1.0);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
DicConsole.Write("\rConverting tag {4} for sectors {0} to {1} in track {3} ({2:P2} done)",
|
DicConsole.Write("\rConverting tag {4} for sectors {0} to {1} in track {3} ({2:P2} done)",
|
||||||
inputFormat.Info.Sectors, inputFormat.Info.Sectors, 1.0,
|
inputFormat.Info.Sectors, inputFormat.Info.Sectors, 1.0,
|
||||||
inputOptical.Tracks.Count, tag);
|
inputOptical.Tracks.Count, tag);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -636,6 +722,7 @@ namespace DiscImageChef.Commands
|
|||||||
DicConsole.WriteLine("Setting geometry to {0} cylinders, {1} heads and {2} sectors per track",
|
DicConsole.WriteLine("Setting geometry to {0} cylinders, {1} heads and {2} sectors per track",
|
||||||
inputFormat.Info.Cylinders, inputFormat.Info.Heads,
|
inputFormat.Info.Cylinders, inputFormat.Info.Heads,
|
||||||
inputFormat.Info.SectorsPerTrack);
|
inputFormat.Info.SectorsPerTrack);
|
||||||
|
|
||||||
if(!outputFormat.SetGeometry(inputFormat.Info.Cylinders, inputFormat.Info.Heads,
|
if(!outputFormat.SetGeometry(inputFormat.Info.Cylinders, inputFormat.Info.Heads,
|
||||||
inputFormat.Info.SectorsPerTrack))
|
inputFormat.Info.SectorsPerTrack))
|
||||||
DicConsole.ErrorWriteLine("Error {0} setting geometry, image may be incorrect, continuing...",
|
DicConsole.ErrorWriteLine("Error {0} setting geometry, image may be incorrect, continuing...",
|
||||||
@@ -646,15 +733,17 @@ namespace DiscImageChef.Commands
|
|||||||
byte[] sector;
|
byte[] sector;
|
||||||
|
|
||||||
uint sectorsToDo;
|
uint sectorsToDo;
|
||||||
if(inputFormat.Info.Sectors - doneSectors >= (ulong)count) sectorsToDo = (uint)count;
|
|
||||||
|
if(inputFormat.Info.Sectors - doneSectors >= (ulong)count)
|
||||||
|
sectorsToDo = (uint)count;
|
||||||
else
|
else
|
||||||
sectorsToDo =
|
sectorsToDo = (uint)(inputFormat.Info.Sectors - doneSectors);
|
||||||
(uint)(inputFormat.Info.Sectors - doneSectors);
|
|
||||||
|
|
||||||
DicConsole.Write("\rConverting sectors {0} to {1} ({2:P2} done)", doneSectors,
|
DicConsole.Write("\rConverting sectors {0} to {1} ({2:P2} done)", doneSectors,
|
||||||
doneSectors + sectorsToDo, doneSectors / (double)inputFormat.Info.Sectors);
|
doneSectors + sectorsToDo, doneSectors / (double)inputFormat.Info.Sectors);
|
||||||
|
|
||||||
bool result;
|
bool result;
|
||||||
|
|
||||||
if(useLong)
|
if(useLong)
|
||||||
if(sectorsToDo == 1)
|
if(sectorsToDo == 1)
|
||||||
{
|
{
|
||||||
@@ -688,7 +777,8 @@ namespace DiscImageChef.Commands
|
|||||||
{
|
{
|
||||||
DicConsole.ErrorWriteLine("Error {0} writing sector {1}, not continuing...",
|
DicConsole.ErrorWriteLine("Error {0} writing sector {1}, not continuing...",
|
||||||
outputFormat.ErrorMessage, doneSectors);
|
outputFormat.ErrorMessage, doneSectors);
|
||||||
return (int)ErrorNumber.WriteError;
|
|
||||||
|
return(int)ErrorNumber.WriteError;
|
||||||
}
|
}
|
||||||
|
|
||||||
doneSectors += sectorsToDo;
|
doneSectors += sectorsToDo;
|
||||||
@@ -696,11 +786,13 @@ namespace DiscImageChef.Commands
|
|||||||
|
|
||||||
DicConsole.Write("\rConverting sectors {0} to {1} ({2:P2} done)", inputFormat.Info.Sectors,
|
DicConsole.Write("\rConverting sectors {0} to {1} ({2:P2} done)", inputFormat.Info.Sectors,
|
||||||
inputFormat.Info.Sectors, 1.0);
|
inputFormat.Info.Sectors, 1.0);
|
||||||
|
|
||||||
DicConsole.WriteLine();
|
DicConsole.WriteLine();
|
||||||
|
|
||||||
foreach(SectorTagType tag in inputFormat.Info.ReadableSectorTags)
|
foreach(SectorTagType tag in inputFormat.Info.ReadableSectorTags)
|
||||||
{
|
{
|
||||||
if(!useLong) break;
|
if(!useLong)
|
||||||
|
break;
|
||||||
|
|
||||||
switch(tag)
|
switch(tag)
|
||||||
{
|
{
|
||||||
@@ -716,24 +808,28 @@ namespace DiscImageChef.Commands
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(force && !outputFormat.SupportedSectorTags.Contains(tag)) continue;
|
if(force && !outputFormat.SupportedSectorTags.Contains(tag))
|
||||||
|
continue;
|
||||||
|
|
||||||
doneSectors = 0;
|
doneSectors = 0;
|
||||||
|
|
||||||
while(doneSectors < inputFormat.Info.Sectors)
|
while(doneSectors < inputFormat.Info.Sectors)
|
||||||
{
|
{
|
||||||
byte[] sector;
|
byte[] sector;
|
||||||
|
|
||||||
uint sectorsToDo;
|
uint sectorsToDo;
|
||||||
if(inputFormat.Info.Sectors - doneSectors >= (ulong)count) sectorsToDo = (uint)count;
|
|
||||||
|
if(inputFormat.Info.Sectors - doneSectors >= (ulong)count)
|
||||||
|
sectorsToDo = (uint)count;
|
||||||
else
|
else
|
||||||
sectorsToDo =
|
sectorsToDo = (uint)(inputFormat.Info.Sectors - doneSectors);
|
||||||
(uint)(inputFormat.Info.Sectors - doneSectors);
|
|
||||||
|
|
||||||
DicConsole.Write("\rConverting tag {2} for sectors {0} to {1} ({2:P2} done)", doneSectors,
|
DicConsole.Write("\rConverting tag {2} for sectors {0} to {1} ({2:P2} done)", doneSectors,
|
||||||
doneSectors + sectorsToDo, doneSectors / (double)inputFormat.Info.Sectors,
|
doneSectors + sectorsToDo, doneSectors / (double)inputFormat.Info.Sectors,
|
||||||
tag);
|
tag);
|
||||||
|
|
||||||
bool result;
|
bool result;
|
||||||
|
|
||||||
if(sectorsToDo == 1)
|
if(sectorsToDo == 1)
|
||||||
{
|
{
|
||||||
sector = inputFormat.ReadSectorTag(doneSectors, tag);
|
sector = inputFormat.ReadSectorTag(doneSectors, tag);
|
||||||
@@ -753,7 +849,8 @@ namespace DiscImageChef.Commands
|
|||||||
{
|
{
|
||||||
DicConsole.ErrorWriteLine("Error {0} writing sector {1}, not continuing...",
|
DicConsole.ErrorWriteLine("Error {0} writing sector {1}, not continuing...",
|
||||||
outputFormat.ErrorMessage, doneSectors);
|
outputFormat.ErrorMessage, doneSectors);
|
||||||
return (int)ErrorNumber.WriteError;
|
|
||||||
|
return(int)ErrorNumber.WriteError;
|
||||||
}
|
}
|
||||||
|
|
||||||
doneSectors += sectorsToDo;
|
doneSectors += sectorsToDo;
|
||||||
@@ -761,24 +858,37 @@ namespace DiscImageChef.Commands
|
|||||||
|
|
||||||
DicConsole.Write("\rConverting tag {2} for sectors {0} to {1} ({2:P2} done)",
|
DicConsole.Write("\rConverting tag {2} for sectors {0} to {1} ({2:P2} done)",
|
||||||
inputFormat.Info.Sectors, inputFormat.Info.Sectors, 1.0, tag);
|
inputFormat.Info.Sectors, inputFormat.Info.Sectors, 1.0, tag);
|
||||||
|
|
||||||
DicConsole.WriteLine();
|
DicConsole.WriteLine();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
if(resume != null || dumpHardware != null)
|
|
||||||
|
if(resume != null ||
|
||||||
|
dumpHardware != null)
|
||||||
{
|
{
|
||||||
if(resume != null) ret = outputFormat.SetDumpHardware(resume.Tries);
|
if(resume != null)
|
||||||
else if(dumpHardware != null) ret = outputFormat.SetDumpHardware(dumpHardware);
|
ret = outputFormat.SetDumpHardware(resume.Tries);
|
||||||
if(ret) DicConsole.WriteLine("Written dump hardware list to output image.");
|
else if(dumpHardware != null)
|
||||||
|
ret = outputFormat.SetDumpHardware(dumpHardware);
|
||||||
|
|
||||||
|
if(ret)
|
||||||
|
DicConsole.WriteLine("Written dump hardware list to output image.");
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = false;
|
ret = false;
|
||||||
if(sidecar != null || cicmMetadata != null)
|
|
||||||
|
if(sidecar != null ||
|
||||||
|
cicmMetadata != null)
|
||||||
{
|
{
|
||||||
if(sidecar != null) ret = outputFormat.SetCicmMetadata(sidecar);
|
if(sidecar != null)
|
||||||
else if(cicmMetadata != null) ret = outputFormat.SetCicmMetadata(cicmMetadata);
|
ret = outputFormat.SetCicmMetadata(sidecar);
|
||||||
if(ret) DicConsole.WriteLine("Written CICM XML metadata to output image.");
|
else if(cicmMetadata != null)
|
||||||
|
ret = outputFormat.SetCicmMetadata(cicmMetadata);
|
||||||
|
|
||||||
|
if(ret)
|
||||||
|
DicConsole.WriteLine("Written CICM XML metadata to output image.");
|
||||||
}
|
}
|
||||||
|
|
||||||
DicConsole.WriteLine("Closing output image.");
|
DicConsole.WriteLine("Closing output image.");
|
||||||
@@ -790,7 +900,7 @@ namespace DiscImageChef.Commands
|
|||||||
DicConsole.WriteLine();
|
DicConsole.WriteLine();
|
||||||
DicConsole.WriteLine("Conversion done.");
|
DicConsole.WriteLine("Conversion done.");
|
||||||
|
|
||||||
return (int)ErrorNumber.NoError;
|
return(int)ErrorNumber.NoError;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -32,6 +32,8 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.CommandLine;
|
||||||
|
using System.CommandLine.Invocation;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
@@ -41,109 +43,109 @@ using DiscImageChef.CommonTypes.Enums;
|
|||||||
using DiscImageChef.CommonTypes.Interfaces;
|
using DiscImageChef.CommonTypes.Interfaces;
|
||||||
using DiscImageChef.Console;
|
using DiscImageChef.Console;
|
||||||
using DiscImageChef.Core;
|
using DiscImageChef.Core;
|
||||||
using Mono.Options;
|
|
||||||
using Schemas;
|
using Schemas;
|
||||||
|
|
||||||
namespace DiscImageChef.Commands
|
namespace DiscImageChef.Commands
|
||||||
{
|
{
|
||||||
class CreateSidecarCommand : Command
|
internal class CreateSidecarCommand : Command
|
||||||
{
|
{
|
||||||
uint blockSize;
|
|
||||||
string encodingName;
|
|
||||||
string inputFile;
|
|
||||||
bool showHelp;
|
|
||||||
bool tape;
|
|
||||||
|
|
||||||
public CreateSidecarCommand() : base("create-sidecar", "Creates CICM Metadata XML sidecar.")
|
public CreateSidecarCommand() : base("create-sidecar", "Creates CICM Metadata XML sidecar.")
|
||||||
{
|
{
|
||||||
Options = new OptionSet
|
Add(new Option(new[]
|
||||||
{
|
{
|
||||||
$"{MainClass.AssemblyTitle} {MainClass.AssemblyVersion?.InformationalVersion}",
|
"--block-size", "-b"
|
||||||
$"{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.",
|
|
||||||
(uint i) => blockSize = i
|
|
||||||
},
|
},
|
||||||
{"encoding|e=", "Name of character encoding to use.", s => encodingName = s},
|
"Only used for tapes, indicates block size. Files in the folder whose size is not a multiple of this value will simply be ignored.")
|
||||||
{
|
{
|
||||||
"tape|t",
|
Argument = new Argument<int>(() => 512), Required = false
|
||||||
"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
|
|
||||||
|
Add(new Option(new[]
|
||||||
|
{
|
||||||
|
"--encoding", "-e"
|
||||||
|
}, "Name of character encoding to use.")
|
||||||
|
{
|
||||||
|
Argument = new Argument<string>(() => null), Required = false
|
||||||
|
});
|
||||||
|
|
||||||
|
Add(new Option(new[]
|
||||||
|
{
|
||||||
|
"--encoding", "-e"
|
||||||
|
}, "Name of character encoding to use.")
|
||||||
|
{
|
||||||
|
Argument = new Argument<string>(() => null), Required = false
|
||||||
|
});
|
||||||
|
|
||||||
|
Add(new Option(new[]
|
||||||
|
{
|
||||||
|
"--tape", "-t"
|
||||||
},
|
},
|
||||||
{"help|h|?", "Show this message and exit.", v => showHelp = v != null}
|
"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).")
|
||||||
};
|
{
|
||||||
|
Argument = new Argument<bool>(() => false), Required = false
|
||||||
|
});
|
||||||
|
|
||||||
|
AddArgument(new Argument<string>
|
||||||
|
{
|
||||||
|
Arity = ArgumentArity.ExactlyOne, Description = "Media image path", Name = "image-path"
|
||||||
|
});
|
||||||
|
|
||||||
|
Handler = CommandHandler.Create(GetType().GetMethod(nameof(Invoke)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override int Invoke(IEnumerable<string> arguments)
|
static int Invoke(bool debug, bool verbose, uint blockSize, string encodingName, string imagePath, bool tape)
|
||||||
{
|
{
|
||||||
List<string> extra = Options.Parse(arguments);
|
|
||||||
|
|
||||||
if(showHelp)
|
|
||||||
{
|
|
||||||
Options.WriteOptionDescriptions(CommandSet.Out);
|
|
||||||
return (int)ErrorNumber.HelpRequested;
|
|
||||||
}
|
|
||||||
|
|
||||||
MainClass.PrintCopyright();
|
MainClass.PrintCopyright();
|
||||||
if(MainClass.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
|
||||||
if(MainClass.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
if(debug)
|
||||||
|
DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
||||||
|
|
||||||
|
if(verbose)
|
||||||
|
DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
||||||
|
|
||||||
Statistics.AddCommand("create-sidecar");
|
Statistics.AddCommand("create-sidecar");
|
||||||
|
|
||||||
if(extra.Count > 1)
|
|
||||||
{
|
|
||||||
DicConsole.ErrorWriteLine("Too many arguments.");
|
|
||||||
return (int)ErrorNumber.UnexpectedArgumentCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(extra.Count == 0)
|
|
||||||
{
|
|
||||||
DicConsole.ErrorWriteLine("Missing input image.");
|
|
||||||
return (int)ErrorNumber.MissingArgument;
|
|
||||||
}
|
|
||||||
|
|
||||||
inputFile = extra[0];
|
|
||||||
|
|
||||||
DicConsole.DebugWriteLine("Create sidecar command", "--block-size={0}", blockSize);
|
DicConsole.DebugWriteLine("Create sidecar command", "--block-size={0}", blockSize);
|
||||||
DicConsole.DebugWriteLine("Create sidecar command", "--debug={0}", MainClass.Debug);
|
DicConsole.DebugWriteLine("Create sidecar command", "--debug={0}", debug);
|
||||||
DicConsole.DebugWriteLine("Create sidecar command", "--encoding={0}", encodingName);
|
DicConsole.DebugWriteLine("Create sidecar command", "--encoding={0}", encodingName);
|
||||||
DicConsole.DebugWriteLine("Create sidecar command", "--input={0}", inputFile);
|
DicConsole.DebugWriteLine("Create sidecar command", "--input={0}", imagePath);
|
||||||
DicConsole.DebugWriteLine("Create sidecar command", "--tape={0}", tape);
|
DicConsole.DebugWriteLine("Create sidecar command", "--tape={0}", tape);
|
||||||
DicConsole.DebugWriteLine("Create sidecar command", "--verbose={0}", MainClass.Verbose);
|
DicConsole.DebugWriteLine("Create sidecar command", "--verbose={0}", verbose);
|
||||||
|
|
||||||
Encoding encoding = null;
|
Encoding encodingClass = null;
|
||||||
|
|
||||||
if(encodingName != null)
|
if(encodingName != null)
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
encoding = Claunia.Encoding.Encoding.GetEncoding(encodingName);
|
encodingClass = Claunia.Encoding.Encoding.GetEncoding(encodingName);
|
||||||
if(MainClass.Verbose) DicConsole.VerboseWriteLine("Using encoding for {0}.", encoding.EncodingName);
|
|
||||||
|
if(verbose)
|
||||||
|
DicConsole.VerboseWriteLine("Using encoding for {0}.", encodingClass.EncodingName);
|
||||||
}
|
}
|
||||||
catch(ArgumentException)
|
catch(ArgumentException)
|
||||||
{
|
{
|
||||||
DicConsole.ErrorWriteLine("Specified encoding is not supported.");
|
DicConsole.ErrorWriteLine("Specified encoding is not supported.");
|
||||||
return (int)ErrorNumber.EncodingUnknown;
|
|
||||||
|
return(int)ErrorNumber.EncodingUnknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(File.Exists(inputFile))
|
if(File.Exists(imagePath))
|
||||||
{
|
{
|
||||||
if(tape)
|
if(tape)
|
||||||
{
|
{
|
||||||
DicConsole.ErrorWriteLine("You cannot use --tape option when input is a file.");
|
DicConsole.ErrorWriteLine("You cannot use --tape option when input is a file.");
|
||||||
return (int)ErrorNumber.ExpectedDirectory;
|
|
||||||
|
return(int)ErrorNumber.ExpectedDirectory;
|
||||||
}
|
}
|
||||||
|
|
||||||
FiltersList filtersList = new FiltersList();
|
var filtersList = new FiltersList();
|
||||||
IFilter inputFilter = filtersList.GetFilter(inputFile);
|
IFilter inputFilter = filtersList.GetFilter(imagePath);
|
||||||
|
|
||||||
if(inputFilter == null)
|
if(inputFilter == null)
|
||||||
{
|
{
|
||||||
DicConsole.ErrorWriteLine("Cannot open specified file.");
|
DicConsole.ErrorWriteLine("Cannot open specified file.");
|
||||||
return (int)ErrorNumber.CannotOpenFile;
|
|
||||||
|
return(int)ErrorNumber.CannotOpenFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
@@ -153,13 +155,15 @@ namespace DiscImageChef.Commands
|
|||||||
if(imageFormat == null)
|
if(imageFormat == null)
|
||||||
{
|
{
|
||||||
DicConsole.WriteLine("Image format not identified, not proceeding with analysis.");
|
DicConsole.WriteLine("Image format not identified, not proceeding with analysis.");
|
||||||
return (int)ErrorNumber.UnrecognizedFormat;
|
|
||||||
|
return(int)ErrorNumber.UnrecognizedFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(MainClass.Verbose)
|
if(verbose)
|
||||||
DicConsole.VerboseWriteLine("Image format identified by {0} ({1}).", imageFormat.Name,
|
DicConsole.VerboseWriteLine("Image format identified by {0} ({1}).", imageFormat.Name,
|
||||||
imageFormat.Id);
|
imageFormat.Id);
|
||||||
else DicConsole.WriteLine("Image format identified by {0}.", imageFormat.Name);
|
else
|
||||||
|
DicConsole.WriteLine("Image format identified by {0}.", imageFormat.Name);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -167,7 +171,8 @@ namespace DiscImageChef.Commands
|
|||||||
{
|
{
|
||||||
DicConsole.WriteLine("Unable to open image format");
|
DicConsole.WriteLine("Unable to open image format");
|
||||||
DicConsole.WriteLine("No error given");
|
DicConsole.WriteLine("No error given");
|
||||||
return (int)ErrorNumber.CannotOpenFormat;
|
|
||||||
|
return(int)ErrorNumber.CannotOpenFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
DicConsole.DebugWriteLine("Analyze command", "Correctly opened image file.");
|
DicConsole.DebugWriteLine("Analyze command", "Correctly opened image file.");
|
||||||
@@ -176,13 +181,14 @@ namespace DiscImageChef.Commands
|
|||||||
{
|
{
|
||||||
DicConsole.ErrorWriteLine("Unable to open image format");
|
DicConsole.ErrorWriteLine("Unable to open image format");
|
||||||
DicConsole.ErrorWriteLine("Error: {0}", ex.Message);
|
DicConsole.ErrorWriteLine("Error: {0}", ex.Message);
|
||||||
return (int)ErrorNumber.CannotOpenFormat;
|
|
||||||
|
return(int)ErrorNumber.CannotOpenFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
Statistics.AddMediaFormat(imageFormat.Format);
|
Statistics.AddMediaFormat(imageFormat.Format);
|
||||||
Statistics.AddFilter(inputFilter.Name);
|
Statistics.AddFilter(inputFilter.Name);
|
||||||
|
|
||||||
Sidecar sidecarClass = new Sidecar(imageFormat, inputFile, inputFilter.Id, encoding);
|
var sidecarClass = new Sidecar(imageFormat, imagePath, inputFilter.Id, encodingClass);
|
||||||
sidecarClass.InitProgressEvent += Progress.InitProgress;
|
sidecarClass.InitProgressEvent += Progress.InitProgress;
|
||||||
sidecarClass.UpdateProgressEvent += Progress.UpdateProgress;
|
sidecarClass.UpdateProgressEvent += Progress.UpdateProgress;
|
||||||
sidecarClass.EndProgressEvent += Progress.EndProgress;
|
sidecarClass.EndProgressEvent += Progress.EndProgress;
|
||||||
@@ -190,21 +196,23 @@ namespace DiscImageChef.Commands
|
|||||||
sidecarClass.UpdateProgressEvent2 += Progress.UpdateProgress2;
|
sidecarClass.UpdateProgressEvent2 += Progress.UpdateProgress2;
|
||||||
sidecarClass.EndProgressEvent2 += Progress.EndProgress2;
|
sidecarClass.EndProgressEvent2 += Progress.EndProgress2;
|
||||||
sidecarClass.UpdateStatusEvent += Progress.UpdateStatus;
|
sidecarClass.UpdateStatusEvent += Progress.UpdateStatus;
|
||||||
|
|
||||||
System.Console.CancelKeyPress += (sender, e) =>
|
System.Console.CancelKeyPress += (sender, e) =>
|
||||||
{
|
{
|
||||||
e.Cancel = true;
|
e.Cancel = true;
|
||||||
sidecarClass.Abort();
|
sidecarClass.Abort();
|
||||||
};
|
};
|
||||||
|
|
||||||
CICMMetadataType sidecar = sidecarClass.Create();
|
CICMMetadataType sidecar = sidecarClass.Create();
|
||||||
|
|
||||||
DicConsole.WriteLine("Writing metadata sidecar");
|
DicConsole.WriteLine("Writing metadata sidecar");
|
||||||
|
|
||||||
FileStream xmlFs =
|
var xmlFs =
|
||||||
new
|
new
|
||||||
FileStream(Path.Combine(Path.GetDirectoryName(inputFile) ?? throw new InvalidOperationException(), Path.GetFileNameWithoutExtension(inputFile) + ".cicm.xml"),
|
FileStream(Path.Combine(Path.GetDirectoryName(imagePath) ?? throw new InvalidOperationException(), Path.GetFileNameWithoutExtension(imagePath) + ".cicm.xml"),
|
||||||
FileMode.CreateNew);
|
FileMode.CreateNew);
|
||||||
|
|
||||||
XmlSerializer xmlSer = new XmlSerializer(typeof(CICMMetadataType));
|
var xmlSer = new XmlSerializer(typeof(CICMMetadataType));
|
||||||
xmlSer.Serialize(xmlFs, sidecar);
|
xmlSer.Serialize(xmlFs, sidecar);
|
||||||
xmlFs.Close();
|
xmlFs.Close();
|
||||||
}
|
}
|
||||||
@@ -212,23 +220,25 @@ namespace DiscImageChef.Commands
|
|||||||
{
|
{
|
||||||
DicConsole.ErrorWriteLine($"Error reading file: {ex.Message}");
|
DicConsole.ErrorWriteLine($"Error reading file: {ex.Message}");
|
||||||
DicConsole.DebugWriteLine("Analyze command", ex.StackTrace);
|
DicConsole.DebugWriteLine("Analyze command", ex.StackTrace);
|
||||||
return (int)ErrorNumber.UnexpectedException;
|
|
||||||
|
return(int)ErrorNumber.UnexpectedException;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(Directory.Exists(inputFile))
|
else if(Directory.Exists(imagePath))
|
||||||
{
|
{
|
||||||
if(!tape)
|
if(!tape)
|
||||||
{
|
{
|
||||||
DicConsole.ErrorWriteLine("Cannot create a sidecar from a directory.");
|
DicConsole.ErrorWriteLine("Cannot create a sidecar from a directory.");
|
||||||
return (int)ErrorNumber.ExpectedFile;
|
|
||||||
|
return(int)ErrorNumber.ExpectedFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
string[] contents = Directory.GetFiles(inputFile, "*", SearchOption.TopDirectoryOnly);
|
string[] contents = Directory.GetFiles(imagePath, "*", SearchOption.TopDirectoryOnly);
|
||||||
List<string> files = contents.Where(file => new FileInfo(file).Length % blockSize == 0).ToList();
|
List<string> files = contents.Where(file => new FileInfo(file).Length % blockSize == 0).ToList();
|
||||||
|
|
||||||
files.Sort(StringComparer.CurrentCultureIgnoreCase);
|
files.Sort(StringComparer.CurrentCultureIgnoreCase);
|
||||||
|
|
||||||
Sidecar sidecarClass = new Sidecar();
|
var sidecarClass = new Sidecar();
|
||||||
sidecarClass.InitProgressEvent += Progress.InitProgress;
|
sidecarClass.InitProgressEvent += Progress.InitProgress;
|
||||||
sidecarClass.UpdateProgressEvent += Progress.UpdateProgress;
|
sidecarClass.UpdateProgressEvent += Progress.UpdateProgress;
|
||||||
sidecarClass.EndProgressEvent += Progress.EndProgress;
|
sidecarClass.EndProgressEvent += Progress.EndProgress;
|
||||||
@@ -236,22 +246,23 @@ namespace DiscImageChef.Commands
|
|||||||
sidecarClass.UpdateProgressEvent2 += Progress.UpdateProgress2;
|
sidecarClass.UpdateProgressEvent2 += Progress.UpdateProgress2;
|
||||||
sidecarClass.EndProgressEvent2 += Progress.EndProgress2;
|
sidecarClass.EndProgressEvent2 += Progress.EndProgress2;
|
||||||
sidecarClass.UpdateStatusEvent += Progress.UpdateStatus;
|
sidecarClass.UpdateStatusEvent += Progress.UpdateStatus;
|
||||||
CICMMetadataType sidecar = sidecarClass.BlockTape(Path.GetFileName(inputFile), files, blockSize);
|
CICMMetadataType sidecar = sidecarClass.BlockTape(Path.GetFileName(imagePath), files, blockSize);
|
||||||
|
|
||||||
DicConsole.WriteLine("Writing metadata sidecar");
|
DicConsole.WriteLine("Writing metadata sidecar");
|
||||||
|
|
||||||
FileStream xmlFs =
|
var xmlFs =
|
||||||
new
|
new
|
||||||
FileStream(Path.Combine(Path.GetDirectoryName(inputFile) ?? throw new InvalidOperationException(), Path.GetFileNameWithoutExtension(inputFile) + ".cicm.xml"),
|
FileStream(Path.Combine(Path.GetDirectoryName(imagePath) ?? throw new InvalidOperationException(), Path.GetFileNameWithoutExtension(imagePath) + ".cicm.xml"),
|
||||||
FileMode.CreateNew);
|
FileMode.CreateNew);
|
||||||
|
|
||||||
XmlSerializer xmlSer = new XmlSerializer(typeof(CICMMetadataType));
|
var xmlSer = new XmlSerializer(typeof(CICMMetadataType));
|
||||||
xmlSer.Serialize(xmlFs, sidecar);
|
xmlSer.Serialize(xmlFs, sidecar);
|
||||||
xmlFs.Close();
|
xmlFs.Close();
|
||||||
}
|
}
|
||||||
else DicConsole.ErrorWriteLine("The specified input file cannot be found.");
|
else
|
||||||
|
DicConsole.ErrorWriteLine("The specified input file cannot be found.");
|
||||||
|
|
||||||
return (int)ErrorNumber.NoError;
|
return(int)ErrorNumber.NoError;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -30,7 +30,8 @@
|
|||||||
// Copyright © 2011-2019 Natalia Portillo
|
// Copyright © 2011-2019 Natalia Portillo
|
||||||
// ****************************************************************************/
|
// ****************************************************************************/
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.CommandLine;
|
||||||
|
using System.CommandLine.Invocation;
|
||||||
using DiscImageChef.CommonTypes;
|
using DiscImageChef.CommonTypes;
|
||||||
using DiscImageChef.CommonTypes.Enums;
|
using DiscImageChef.CommonTypes.Enums;
|
||||||
using DiscImageChef.CommonTypes.Interfaces;
|
using DiscImageChef.CommonTypes.Interfaces;
|
||||||
@@ -39,81 +40,82 @@ using DiscImageChef.Core;
|
|||||||
using DiscImageChef.Decoders.ATA;
|
using DiscImageChef.Decoders.ATA;
|
||||||
using DiscImageChef.Decoders.CD;
|
using DiscImageChef.Decoders.CD;
|
||||||
using DiscImageChef.Decoders.SCSI;
|
using DiscImageChef.Decoders.SCSI;
|
||||||
using Mono.Options;
|
|
||||||
|
|
||||||
namespace DiscImageChef.Commands
|
namespace DiscImageChef.Commands
|
||||||
{
|
{
|
||||||
class DecodeCommand : Command
|
internal class DecodeCommand : Command
|
||||||
{
|
{
|
||||||
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.")
|
public DecodeCommand() : base("decode", "Decodes and pretty prints disk and/or sector tags.")
|
||||||
{
|
{
|
||||||
Options = new OptionSet
|
Add(new Option(new[]
|
||||||
{
|
{
|
||||||
$"{MainClass.AssemblyTitle} {MainClass.AssemblyVersion?.InformationalVersion}",
|
"--disk-tags", "-f"
|
||||||
$"{MainClass.AssemblyCopyright}",
|
}, "Decode disk tags.")
|
||||||
"",
|
{
|
||||||
$"usage: DiscImageChef {Name} [OPTIONS] imagefile",
|
Argument = new Argument<bool>(() => true), Required = false
|
||||||
"",
|
});
|
||||||
Help,
|
|
||||||
{"disk-tags|f", "Decode disk tags.", b => diskTags = b != null},
|
Add(new Option(new[]
|
||||||
{"length|l=", "How many sectors to decode, or \"all\".", s => length = s},
|
{
|
||||||
{"sector-tags|p", "Decode sector tags.", b => sectorTags = b != null},
|
"--length", "-l"
|
||||||
{"start|s=", "Name of character encoding to use.", (ulong ul) => startSector = ul},
|
}, "How many sectors to decode, or \"all\".")
|
||||||
{"help|h|?", "Show this message and exit.", v => showHelp = v != null}
|
{
|
||||||
};
|
Argument = new Argument<string>(() => "all"), Required = false
|
||||||
|
});
|
||||||
|
|
||||||
|
Add(new Option(new[]
|
||||||
|
{
|
||||||
|
"--sector-tags", "-p"
|
||||||
|
}, "Decode sector tags.")
|
||||||
|
{
|
||||||
|
Argument = new Argument<bool>(() => true), Required = false
|
||||||
|
});
|
||||||
|
|
||||||
|
Add(new Option(new[]
|
||||||
|
{
|
||||||
|
"--start", "-s"
|
||||||
|
}, "Sector to start decoding from.")
|
||||||
|
{
|
||||||
|
Argument = new Argument<ulong>(() => 0), Required = false
|
||||||
|
});
|
||||||
|
|
||||||
|
AddArgument(new Argument<string>
|
||||||
|
{
|
||||||
|
Arity = ArgumentArity.ExactlyOne, Description = "Media image path", Name = "image-path"
|
||||||
|
});
|
||||||
|
|
||||||
|
Handler = CommandHandler.Create(GetType().GetMethod(nameof(Invoke)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override int Invoke(IEnumerable<string> arguments)
|
static int Invoke(bool verbose, bool debug, bool diskTags, string imagePath, string length, bool sectorTags,
|
||||||
|
ulong startSector)
|
||||||
{
|
{
|
||||||
List<string> extra = Options.Parse(arguments);
|
|
||||||
|
|
||||||
if(showHelp)
|
|
||||||
{
|
|
||||||
Options.WriteOptionDescriptions(CommandSet.Out);
|
|
||||||
return (int)ErrorNumber.HelpRequested;
|
|
||||||
}
|
|
||||||
|
|
||||||
MainClass.PrintCopyright();
|
MainClass.PrintCopyright();
|
||||||
if(MainClass.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
|
||||||
if(MainClass.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
if(debug)
|
||||||
|
DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
||||||
|
|
||||||
|
if(verbose)
|
||||||
|
DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
||||||
|
|
||||||
Statistics.AddCommand("decode");
|
Statistics.AddCommand("decode");
|
||||||
|
|
||||||
if(extra.Count > 1)
|
DicConsole.DebugWriteLine("Decode command", "--debug={0}", debug);
|
||||||
{
|
|
||||||
DicConsole.ErrorWriteLine("Too many arguments.");
|
|
||||||
return (int)ErrorNumber.UnexpectedArgumentCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(extra.Count == 0)
|
|
||||||
{
|
|
||||||
DicConsole.ErrorWriteLine("Missing input image.");
|
|
||||||
return (int)ErrorNumber.MissingArgument;
|
|
||||||
}
|
|
||||||
|
|
||||||
inputFile = extra[0];
|
|
||||||
|
|
||||||
DicConsole.DebugWriteLine("Decode command", "--debug={0}", MainClass.Debug);
|
|
||||||
DicConsole.DebugWriteLine("Decode command", "--disk-tags={0}", diskTags);
|
DicConsole.DebugWriteLine("Decode command", "--disk-tags={0}", diskTags);
|
||||||
DicConsole.DebugWriteLine("Decode command", "--input={0}", inputFile);
|
DicConsole.DebugWriteLine("Decode command", "--input={0}", imagePath);
|
||||||
DicConsole.DebugWriteLine("Decode command", "--length={0}", length);
|
DicConsole.DebugWriteLine("Decode command", "--length={0}", length);
|
||||||
DicConsole.DebugWriteLine("Decode command", "--sector-tags={0}", sectorTags);
|
DicConsole.DebugWriteLine("Decode command", "--sector-tags={0}", sectorTags);
|
||||||
DicConsole.DebugWriteLine("Decode command", "--start={0}", startSector);
|
DicConsole.DebugWriteLine("Decode command", "--start={0}", startSector);
|
||||||
DicConsole.DebugWriteLine("Decode command", "--verbose={0}", MainClass.Verbose);
|
DicConsole.DebugWriteLine("Decode command", "--verbose={0}", verbose);
|
||||||
|
|
||||||
FiltersList filtersList = new FiltersList();
|
var filtersList = new FiltersList();
|
||||||
IFilter inputFilter = filtersList.GetFilter(inputFile);
|
IFilter inputFilter = filtersList.GetFilter(imagePath);
|
||||||
|
|
||||||
if(inputFilter == null)
|
if(inputFilter == null)
|
||||||
{
|
{
|
||||||
DicConsole.ErrorWriteLine("Cannot open specified file.");
|
DicConsole.ErrorWriteLine("Cannot open specified file.");
|
||||||
return (int)ErrorNumber.CannotOpenFile;
|
|
||||||
|
return(int)ErrorNumber.CannotOpenFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
IMediaImage inputFormat = ImageFormat.Detect(inputFilter);
|
IMediaImage inputFormat = ImageFormat.Detect(inputFilter);
|
||||||
@@ -121,7 +123,8 @@ namespace DiscImageChef.Commands
|
|||||||
if(inputFormat == null)
|
if(inputFormat == null)
|
||||||
{
|
{
|
||||||
DicConsole.ErrorWriteLine("Unable to recognize image format, not decoding");
|
DicConsole.ErrorWriteLine("Unable to recognize image format, not decoding");
|
||||||
return (int)ErrorNumber.UnrecognizedFormat;
|
|
||||||
|
return(int)ErrorNumber.UnrecognizedFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
inputFormat.Open(inputFilter);
|
inputFormat.Open(inputFilter);
|
||||||
@@ -139,16 +142,20 @@ namespace DiscImageChef.Commands
|
|||||||
case MediaTagType.SCSI_INQUIRY:
|
case MediaTagType.SCSI_INQUIRY:
|
||||||
{
|
{
|
||||||
byte[] inquiry = inputFormat.ReadDiskTag(MediaTagType.SCSI_INQUIRY);
|
byte[] inquiry = inputFormat.ReadDiskTag(MediaTagType.SCSI_INQUIRY);
|
||||||
|
|
||||||
if(inquiry == null)
|
if(inquiry == null)
|
||||||
DicConsole.WriteLine("Error reading SCSI INQUIRY response from disc image");
|
DicConsole.WriteLine("Error reading SCSI INQUIRY response from disc image");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DicConsole.WriteLine("SCSI INQUIRY command response:");
|
DicConsole.WriteLine("SCSI INQUIRY command response:");
|
||||||
DicConsole
|
|
||||||
.WriteLine("================================================================================");
|
DicConsole.
|
||||||
|
WriteLine("================================================================================");
|
||||||
|
|
||||||
DicConsole.WriteLine(Inquiry.Prettify(inquiry));
|
DicConsole.WriteLine(Inquiry.Prettify(inquiry));
|
||||||
DicConsole
|
|
||||||
.WriteLine("================================================================================");
|
DicConsole.
|
||||||
|
WriteLine("================================================================================");
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -156,16 +163,20 @@ namespace DiscImageChef.Commands
|
|||||||
case MediaTagType.ATA_IDENTIFY:
|
case MediaTagType.ATA_IDENTIFY:
|
||||||
{
|
{
|
||||||
byte[] identify = inputFormat.ReadDiskTag(MediaTagType.ATA_IDENTIFY);
|
byte[] identify = inputFormat.ReadDiskTag(MediaTagType.ATA_IDENTIFY);
|
||||||
|
|
||||||
if(identify == null)
|
if(identify == null)
|
||||||
DicConsole.WriteLine("Error reading ATA IDENTIFY DEVICE response from disc image");
|
DicConsole.WriteLine("Error reading ATA IDENTIFY DEVICE response from disc image");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DicConsole.WriteLine("ATA IDENTIFY DEVICE command response:");
|
DicConsole.WriteLine("ATA IDENTIFY DEVICE command response:");
|
||||||
DicConsole
|
|
||||||
.WriteLine("================================================================================");
|
DicConsole.
|
||||||
|
WriteLine("================================================================================");
|
||||||
|
|
||||||
DicConsole.WriteLine(Identify.Prettify(identify));
|
DicConsole.WriteLine(Identify.Prettify(identify));
|
||||||
DicConsole
|
|
||||||
.WriteLine("================================================================================");
|
DicConsole.
|
||||||
|
WriteLine("================================================================================");
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -173,17 +184,21 @@ namespace DiscImageChef.Commands
|
|||||||
case MediaTagType.ATAPI_IDENTIFY:
|
case MediaTagType.ATAPI_IDENTIFY:
|
||||||
{
|
{
|
||||||
byte[] identify = inputFormat.ReadDiskTag(MediaTagType.ATAPI_IDENTIFY);
|
byte[] identify = inputFormat.ReadDiskTag(MediaTagType.ATAPI_IDENTIFY);
|
||||||
|
|
||||||
if(identify == null)
|
if(identify == null)
|
||||||
DicConsole
|
DicConsole.
|
||||||
.WriteLine("Error reading ATA IDENTIFY PACKET DEVICE response from disc image");
|
WriteLine("Error reading ATA IDENTIFY PACKET DEVICE response from disc image");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DicConsole.WriteLine("ATA IDENTIFY PACKET DEVICE command response:");
|
DicConsole.WriteLine("ATA IDENTIFY PACKET DEVICE command response:");
|
||||||
DicConsole
|
|
||||||
.WriteLine("================================================================================");
|
DicConsole.
|
||||||
|
WriteLine("================================================================================");
|
||||||
|
|
||||||
DicConsole.WriteLine(Identify.Prettify(identify));
|
DicConsole.WriteLine(Identify.Prettify(identify));
|
||||||
DicConsole
|
|
||||||
.WriteLine("================================================================================");
|
DicConsole.
|
||||||
|
WriteLine("================================================================================");
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -191,31 +206,41 @@ namespace DiscImageChef.Commands
|
|||||||
case MediaTagType.CD_ATIP:
|
case MediaTagType.CD_ATIP:
|
||||||
{
|
{
|
||||||
byte[] atip = inputFormat.ReadDiskTag(MediaTagType.CD_ATIP);
|
byte[] atip = inputFormat.ReadDiskTag(MediaTagType.CD_ATIP);
|
||||||
if(atip == null) DicConsole.WriteLine("Error reading CD ATIP from disc image");
|
|
||||||
|
if(atip == null)
|
||||||
|
DicConsole.WriteLine("Error reading CD ATIP from disc image");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DicConsole.WriteLine("CD ATIP:");
|
DicConsole.WriteLine("CD ATIP:");
|
||||||
DicConsole
|
|
||||||
.WriteLine("================================================================================");
|
DicConsole.
|
||||||
|
WriteLine("================================================================================");
|
||||||
|
|
||||||
DicConsole.WriteLine(ATIP.Prettify(atip));
|
DicConsole.WriteLine(ATIP.Prettify(atip));
|
||||||
DicConsole
|
|
||||||
.WriteLine("================================================================================");
|
DicConsole.
|
||||||
|
WriteLine("================================================================================");
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MediaTagType.CD_FullTOC:
|
case MediaTagType.CD_FullTOC:
|
||||||
{
|
{
|
||||||
byte[] fulltoc = inputFormat.ReadDiskTag(MediaTagType.CD_FullTOC);
|
byte[] fullToc = inputFormat.ReadDiskTag(MediaTagType.CD_FullTOC);
|
||||||
if(fulltoc == null) DicConsole.WriteLine("Error reading CD full TOC from disc image");
|
|
||||||
|
if(fullToc == null)
|
||||||
|
DicConsole.WriteLine("Error reading CD full TOC from disc image");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DicConsole.WriteLine("CD full TOC:");
|
DicConsole.WriteLine("CD full TOC:");
|
||||||
DicConsole
|
|
||||||
.WriteLine("================================================================================");
|
DicConsole.
|
||||||
DicConsole.WriteLine(FullTOC.Prettify(fulltoc));
|
WriteLine("================================================================================");
|
||||||
DicConsole
|
|
||||||
.WriteLine("================================================================================");
|
DicConsole.WriteLine(FullTOC.Prettify(fullToc));
|
||||||
|
|
||||||
|
DicConsole.
|
||||||
|
WriteLine("================================================================================");
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -223,48 +248,62 @@ namespace DiscImageChef.Commands
|
|||||||
case MediaTagType.CD_PMA:
|
case MediaTagType.CD_PMA:
|
||||||
{
|
{
|
||||||
byte[] pma = inputFormat.ReadDiskTag(MediaTagType.CD_PMA);
|
byte[] pma = inputFormat.ReadDiskTag(MediaTagType.CD_PMA);
|
||||||
if(pma == null) DicConsole.WriteLine("Error reading CD PMA from disc image");
|
|
||||||
|
if(pma == null)
|
||||||
|
DicConsole.WriteLine("Error reading CD PMA from disc image");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DicConsole.WriteLine("CD PMA:");
|
DicConsole.WriteLine("CD PMA:");
|
||||||
DicConsole
|
|
||||||
.WriteLine("================================================================================");
|
DicConsole.
|
||||||
|
WriteLine("================================================================================");
|
||||||
|
|
||||||
DicConsole.WriteLine(PMA.Prettify(pma));
|
DicConsole.WriteLine(PMA.Prettify(pma));
|
||||||
DicConsole
|
|
||||||
.WriteLine("================================================================================");
|
DicConsole.
|
||||||
|
WriteLine("================================================================================");
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MediaTagType.CD_SessionInfo:
|
case MediaTagType.CD_SessionInfo:
|
||||||
{
|
{
|
||||||
byte[] sessioninfo = inputFormat.ReadDiskTag(MediaTagType.CD_SessionInfo);
|
byte[] sessionInfo = inputFormat.ReadDiskTag(MediaTagType.CD_SessionInfo);
|
||||||
if(sessioninfo == null)
|
|
||||||
|
if(sessionInfo == null)
|
||||||
DicConsole.WriteLine("Error reading CD session information from disc image");
|
DicConsole.WriteLine("Error reading CD session information from disc image");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DicConsole.WriteLine("CD session information:");
|
DicConsole.WriteLine("CD session information:");
|
||||||
DicConsole
|
|
||||||
.WriteLine("================================================================================");
|
DicConsole.
|
||||||
DicConsole.WriteLine(Session.Prettify(sessioninfo));
|
WriteLine("================================================================================");
|
||||||
DicConsole
|
|
||||||
.WriteLine("================================================================================");
|
DicConsole.WriteLine(Session.Prettify(sessionInfo));
|
||||||
|
|
||||||
|
DicConsole.
|
||||||
|
WriteLine("================================================================================");
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MediaTagType.CD_TEXT:
|
case MediaTagType.CD_TEXT:
|
||||||
{
|
{
|
||||||
byte[] cdtext = inputFormat.ReadDiskTag(MediaTagType.CD_TEXT);
|
byte[] cdText = inputFormat.ReadDiskTag(MediaTagType.CD_TEXT);
|
||||||
if(cdtext == null) DicConsole.WriteLine("Error reading CD-TEXT from disc image");
|
|
||||||
|
if(cdText == null)
|
||||||
|
DicConsole.WriteLine("Error reading CD-TEXT from disc image");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DicConsole.WriteLine("CD-TEXT:");
|
DicConsole.WriteLine("CD-TEXT:");
|
||||||
DicConsole
|
|
||||||
.WriteLine("================================================================================");
|
DicConsole.
|
||||||
DicConsole.WriteLine(CDTextOnLeadIn.Prettify(cdtext));
|
WriteLine("================================================================================");
|
||||||
DicConsole
|
|
||||||
.WriteLine("================================================================================");
|
DicConsole.WriteLine(CDTextOnLeadIn.Prettify(cdText));
|
||||||
|
|
||||||
|
DicConsole.
|
||||||
|
WriteLine("================================================================================");
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -272,15 +311,20 @@ namespace DiscImageChef.Commands
|
|||||||
case MediaTagType.CD_TOC:
|
case MediaTagType.CD_TOC:
|
||||||
{
|
{
|
||||||
byte[] toc = inputFormat.ReadDiskTag(MediaTagType.CD_TOC);
|
byte[] toc = inputFormat.ReadDiskTag(MediaTagType.CD_TOC);
|
||||||
if(toc == null) DicConsole.WriteLine("Error reading CD TOC from disc image");
|
|
||||||
|
if(toc == null)
|
||||||
|
DicConsole.WriteLine("Error reading CD TOC from disc image");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DicConsole.WriteLine("CD TOC:");
|
DicConsole.WriteLine("CD TOC:");
|
||||||
DicConsole
|
|
||||||
.WriteLine("================================================================================");
|
DicConsole.
|
||||||
|
WriteLine("================================================================================");
|
||||||
|
|
||||||
DicConsole.WriteLine(TOC.Prettify(toc));
|
DicConsole.WriteLine(TOC.Prettify(toc));
|
||||||
DicConsole
|
|
||||||
.WriteLine("================================================================================");
|
DicConsole.
|
||||||
|
WriteLine("================================================================================");
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -288,6 +332,7 @@ namespace DiscImageChef.Commands
|
|||||||
default:
|
default:
|
||||||
DicConsole.WriteLine("Decoder for disk tag type \"{0}\" not yet implemented, sorry.",
|
DicConsole.WriteLine("Decoder for disk tag type \"{0}\" not yet implemented, sorry.",
|
||||||
tag);
|
tag);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -300,6 +345,7 @@ namespace DiscImageChef.Commands
|
|||||||
{
|
{
|
||||||
DicConsole.WriteLine("Value \"{0}\" is not a valid number for length.", length);
|
DicConsole.WriteLine("Value \"{0}\" is not a valid number for length.", length);
|
||||||
DicConsole.WriteLine("Not decoding sectors tags");
|
DicConsole.WriteLine("Not decoding sectors tags");
|
||||||
|
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -313,13 +359,14 @@ namespace DiscImageChef.Commands
|
|||||||
default:
|
default:
|
||||||
DicConsole.WriteLine("Decoder for disk tag type \"{0}\" not yet implemented, sorry.",
|
DicConsole.WriteLine("Decoder for disk tag type \"{0}\" not yet implemented, sorry.",
|
||||||
tag);
|
tag);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Not implemented
|
// TODO: Not implemented
|
||||||
}
|
}
|
||||||
|
|
||||||
return (int)ErrorNumber.NoError;
|
return(int)ErrorNumber.NoError;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -31,6 +31,8 @@
|
|||||||
// ****************************************************************************/
|
// ****************************************************************************/
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.CommandLine;
|
||||||
|
using System.CommandLine.Invocation;
|
||||||
using DiscImageChef.CommonTypes.Enums;
|
using DiscImageChef.CommonTypes.Enums;
|
||||||
using DiscImageChef.Console;
|
using DiscImageChef.Console;
|
||||||
using DiscImageChef.Core;
|
using DiscImageChef.Core;
|
||||||
@@ -40,72 +42,46 @@ using DiscImageChef.Decoders.SCSI;
|
|||||||
using DiscImageChef.Decoders.SCSI.MMC;
|
using DiscImageChef.Decoders.SCSI.MMC;
|
||||||
using DiscImageChef.Decoders.SCSI.SSC;
|
using DiscImageChef.Decoders.SCSI.SSC;
|
||||||
using DiscImageChef.Devices;
|
using DiscImageChef.Devices;
|
||||||
using Mono.Options;
|
|
||||||
using DeviceInfo = DiscImageChef.Core.Devices.Info.DeviceInfo;
|
using DeviceInfo = DiscImageChef.Core.Devices.Info.DeviceInfo;
|
||||||
|
|
||||||
namespace DiscImageChef.Commands
|
namespace DiscImageChef.Commands
|
||||||
{
|
{
|
||||||
internal class DeviceInfoCommand : Command
|
internal class DeviceInfoCommand : Command
|
||||||
{
|
{
|
||||||
string devicePath;
|
public DeviceInfoCommand() : base("device-info", "Gets information about a device.")
|
||||||
string outputPrefix;
|
|
||||||
|
|
||||||
bool showHelp;
|
|
||||||
|
|
||||||
public DeviceInfoCommand() : base("device-info", "Gets information about a device.") => Options = new OptionSet
|
|
||||||
{
|
{
|
||||||
$"{MainClass.AssemblyTitle} {MainClass.AssemblyVersion?.InformationalVersion}",
|
Add(new Option(new[]
|
||||||
$"{MainClass.AssemblyCopyright}", "", $"usage: DiscImageChef {Name} [OPTIONS] devicepath", "",
|
|
||||||
Help,
|
|
||||||
{
|
{
|
||||||
"output-prefix|w=", "Name of character encoding to use.", s => outputPrefix = s
|
"--output-prefix", "-w"
|
||||||
},
|
}, "Prefix for saving binary information from device.")
|
||||||
{
|
{
|
||||||
"help|h|?", "Show this message and exit.", v => showHelp = v != null
|
Argument = new Argument<string>(() => null), Required = false
|
||||||
}
|
});
|
||||||
};
|
|
||||||
|
|
||||||
public override int Invoke(IEnumerable<string> arguments)
|
AddArgument(new Argument<string>
|
||||||
{
|
{
|
||||||
List<string> extra = Options.Parse(arguments);
|
Arity = ArgumentArity.ExactlyOne, Description = "Device path", Name = "device-path"
|
||||||
|
});
|
||||||
|
|
||||||
if(showHelp)
|
Handler = CommandHandler.Create(GetType().GetMethod(nameof(Invoke)));
|
||||||
{
|
|
||||||
Options.WriteOptionDescriptions(CommandSet.Out);
|
|
||||||
|
|
||||||
return(int)ErrorNumber.HelpRequested;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int Invoke(bool debug, bool verbose, string devicePath, string outputPrefix)
|
||||||
|
{
|
||||||
MainClass.PrintCopyright();
|
MainClass.PrintCopyright();
|
||||||
|
|
||||||
if(MainClass.Debug)
|
if(debug)
|
||||||
DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
||||||
|
|
||||||
if(MainClass.Verbose)
|
if(verbose)
|
||||||
DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
||||||
|
|
||||||
Statistics.AddCommand("device-info");
|
Statistics.AddCommand("device-info");
|
||||||
|
|
||||||
if(extra.Count > 1)
|
DicConsole.DebugWriteLine("Device-Info command", "--debug={0}", debug);
|
||||||
{
|
|
||||||
DicConsole.ErrorWriteLine("Too many arguments.");
|
|
||||||
|
|
||||||
return(int)ErrorNumber.UnexpectedArgumentCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(extra.Count == 0)
|
|
||||||
{
|
|
||||||
DicConsole.ErrorWriteLine("Missing device path.");
|
|
||||||
|
|
||||||
return(int)ErrorNumber.MissingArgument;
|
|
||||||
}
|
|
||||||
|
|
||||||
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", "--device={0}", devicePath);
|
||||||
DicConsole.DebugWriteLine("Device-Info command", "--output-prefix={0}", outputPrefix);
|
DicConsole.DebugWriteLine("Device-Info command", "--output-prefix={0}", outputPrefix);
|
||||||
DicConsole.DebugWriteLine("Device-Info command", "--verbose={0}", MainClass.Verbose);
|
DicConsole.DebugWriteLine("Device-Info command", "--verbose={0}", verbose);
|
||||||
|
|
||||||
if(devicePath.Length == 2 &&
|
if(devicePath.Length == 2 &&
|
||||||
devicePath[1] == ':' &&
|
devicePath[1] == ':' &&
|
||||||
@@ -932,7 +908,7 @@ namespace DiscImageChef.Commands
|
|||||||
DicConsole.WriteLine("\tCan do challenge/response with Xbox discs");
|
DicConsole.WriteLine("\tCan do challenge/response with Xbox discs");
|
||||||
|
|
||||||
if(devInfo.KreonFeatures.HasFlag(KreonFeatures.DecryptSs))
|
if(devInfo.KreonFeatures.HasFlag(KreonFeatures.DecryptSs))
|
||||||
DicConsole.WriteLine("\tCan read and descrypt SS from Xbox discs");
|
DicConsole.WriteLine("\tCan read and decrypt SS from Xbox discs");
|
||||||
|
|
||||||
if(devInfo.KreonFeatures.HasFlag(KreonFeatures.XtremeUnlock))
|
if(devInfo.KreonFeatures.HasFlag(KreonFeatures.XtremeUnlock))
|
||||||
DicConsole.WriteLine("\tCan set xtreme unlock state with Xbox discs");
|
DicConsole.WriteLine("\tCan set xtreme unlock state with Xbox discs");
|
||||||
@@ -944,7 +920,7 @@ namespace DiscImageChef.Commands
|
|||||||
DicConsole.WriteLine("\tCan do challenge/response with Xbox 360 discs");
|
DicConsole.WriteLine("\tCan do challenge/response with Xbox 360 discs");
|
||||||
|
|
||||||
if(devInfo.KreonFeatures.HasFlag(KreonFeatures.DecryptSs360))
|
if(devInfo.KreonFeatures.HasFlag(KreonFeatures.DecryptSs360))
|
||||||
DicConsole.WriteLine("\tCan read and descrypt SS from Xbox 360 discs");
|
DicConsole.WriteLine("\tCan read and decrypt SS from Xbox 360 discs");
|
||||||
|
|
||||||
if(devInfo.KreonFeatures.HasFlag(KreonFeatures.XtremeUnlock360))
|
if(devInfo.KreonFeatures.HasFlag(KreonFeatures.XtremeUnlock360))
|
||||||
DicConsole.WriteLine("\tCan set xtreme unlock state with Xbox 360 discs");
|
DicConsole.WriteLine("\tCan set xtreme unlock state with Xbox 360 discs");
|
||||||
|
|||||||
@@ -32,6 +32,8 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.CommandLine;
|
||||||
|
using System.CommandLine.Invocation;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using DiscImageChef.CommonTypes.Enums;
|
using DiscImageChef.CommonTypes.Enums;
|
||||||
@@ -44,9 +46,8 @@ using DiscImageChef.Database.Models;
|
|||||||
using DiscImageChef.Decoders.ATA;
|
using DiscImageChef.Decoders.ATA;
|
||||||
using DiscImageChef.Decoders.SCSI;
|
using DiscImageChef.Decoders.SCSI;
|
||||||
using DiscImageChef.Devices;
|
using DiscImageChef.Devices;
|
||||||
using Mono.Options;
|
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Command = Mono.Options.Command;
|
using Command = System.CommandLine.Command;
|
||||||
using Device = DiscImageChef.Devices.Device;
|
using Device = DiscImageChef.Devices.Device;
|
||||||
using DeviceReport = DiscImageChef.Core.Devices.Report.DeviceReport;
|
using DeviceReport = DiscImageChef.Core.Devices.Report.DeviceReport;
|
||||||
|
|
||||||
@@ -54,73 +55,44 @@ namespace DiscImageChef.Commands
|
|||||||
{
|
{
|
||||||
internal class DeviceReportCommand : Command
|
internal class DeviceReportCommand : Command
|
||||||
{
|
{
|
||||||
string _devicePath;
|
|
||||||
bool _showHelp;
|
|
||||||
|
|
||||||
public DeviceReportCommand() : base("device-report",
|
public DeviceReportCommand() : base("device-report",
|
||||||
"Tests the device capabilities and creates an JSON report of them.") =>
|
"Tests the device capabilities and creates an JSON report of them.")
|
||||||
Options = new OptionSet
|
|
||||||
{
|
{
|
||||||
$"{MainClass.AssemblyTitle} {MainClass.AssemblyVersion?.InformationalVersion}",
|
AddArgument(new Argument<string>
|
||||||
$"{MainClass.AssemblyCopyright}", "", $"usage: DiscImageChef {Name} devicepath", "",
|
|
||||||
Help,
|
|
||||||
{
|
{
|
||||||
"help|h|?", "Show this message and exit.", v => _showHelp = v != null
|
Arity = ArgumentArity.ExactlyOne, Description = "Device path", Name = "device-path"
|
||||||
}
|
});
|
||||||
};
|
|
||||||
|
|
||||||
public override int Invoke(IEnumerable<string> arguments)
|
Handler = CommandHandler.Create(GetType().GetMethod(nameof(Invoke)));
|
||||||
{
|
|
||||||
List<string> extra = Options.Parse(arguments);
|
|
||||||
|
|
||||||
if(_showHelp)
|
|
||||||
{
|
|
||||||
Options.WriteOptionDescriptions(CommandSet.Out);
|
|
||||||
|
|
||||||
return(int)ErrorNumber.HelpRequested;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int Invoke(bool debug, bool verbose, string devicePath)
|
||||||
|
{
|
||||||
MainClass.PrintCopyright();
|
MainClass.PrintCopyright();
|
||||||
|
|
||||||
if(MainClass.Debug)
|
if(debug)
|
||||||
DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
||||||
|
|
||||||
if(MainClass.Verbose)
|
if(verbose)
|
||||||
DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
||||||
|
|
||||||
Statistics.AddCommand("device-report");
|
Statistics.AddCommand("device-report");
|
||||||
|
|
||||||
if(extra.Count > 1)
|
DicConsole.DebugWriteLine("Device-Report command", "--debug={0}", debug);
|
||||||
{
|
DicConsole.DebugWriteLine("Device-Report command", "--device={0}", devicePath);
|
||||||
DicConsole.ErrorWriteLine("Too many arguments.");
|
DicConsole.DebugWriteLine("Device-Report command", "--verbose={0}", verbose);
|
||||||
|
|
||||||
return(int)ErrorNumber.UnexpectedArgumentCount;
|
if(devicePath.Length == 2 &&
|
||||||
}
|
devicePath[1] == ':' &&
|
||||||
|
devicePath[0] != '/' &&
|
||||||
if(extra.Count == 0)
|
char.IsLetter(devicePath[0]))
|
||||||
{
|
devicePath = "\\\\.\\" + char.ToUpper(devicePath[0]) + ':';
|
||||||
DicConsole.ErrorWriteLine("Missing device path.");
|
|
||||||
|
|
||||||
return(int)ErrorNumber.MissingArgument;
|
|
||||||
}
|
|
||||||
|
|
||||||
_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(_devicePath.Length == 2 &&
|
|
||||||
_devicePath[1] == ':' &&
|
|
||||||
_devicePath[0] != '/' &&
|
|
||||||
char.IsLetter(_devicePath[0]))
|
|
||||||
_devicePath = "\\\\.\\" + char.ToUpper(_devicePath[0]) + ':';
|
|
||||||
|
|
||||||
Device dev;
|
Device dev;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
dev = new Device(_devicePath);
|
dev = new Device(devicePath);
|
||||||
|
|
||||||
if(dev.IsRemote)
|
if(dev.IsRemote)
|
||||||
Statistics.AddRemote(dev.RemoteApplication, dev.RemoteVersion, dev.RemoteOperatingSystem,
|
Statistics.AddRemote(dev.RemoteApplication, dev.RemoteVersion, dev.RemoteOperatingSystem,
|
||||||
|
|||||||
@@ -32,6 +32,8 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.CommandLine;
|
||||||
|
using System.CommandLine.Invocation;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
@@ -39,173 +41,195 @@ using System.Xml.Serialization;
|
|||||||
using DiscImageChef.CommonTypes;
|
using DiscImageChef.CommonTypes;
|
||||||
using DiscImageChef.CommonTypes.Enums;
|
using DiscImageChef.CommonTypes.Enums;
|
||||||
using DiscImageChef.CommonTypes.Interfaces;
|
using DiscImageChef.CommonTypes.Interfaces;
|
||||||
using DiscImageChef.CommonTypes.Interop;
|
|
||||||
using DiscImageChef.CommonTypes.Metadata;
|
using DiscImageChef.CommonTypes.Metadata;
|
||||||
using DiscImageChef.Console;
|
using DiscImageChef.Console;
|
||||||
using DiscImageChef.Core;
|
using DiscImageChef.Core;
|
||||||
using DiscImageChef.Core.Devices.Dumping;
|
using DiscImageChef.Core.Devices.Dumping;
|
||||||
using DiscImageChef.Core.Logging;
|
using DiscImageChef.Core.Logging;
|
||||||
using DiscImageChef.Devices;
|
using DiscImageChef.Devices;
|
||||||
using Mono.Options;
|
|
||||||
using Schemas;
|
using Schemas;
|
||||||
using PlatformID = DiscImageChef.CommonTypes.Interop.PlatformID;
|
|
||||||
|
|
||||||
namespace DiscImageChef.Commands
|
namespace DiscImageChef.Commands
|
||||||
{
|
{
|
||||||
// TODO: Add raw dumping
|
// TODO: Add raw dumping
|
||||||
internal class DumpMediaCommand : Command
|
internal class DumpMediaCommand : Command
|
||||||
{
|
{
|
||||||
string _cicmXml;
|
|
||||||
string _devicePath;
|
|
||||||
bool _doResume = true;
|
|
||||||
string _encodingName;
|
|
||||||
bool _firstTrackPregap;
|
|
||||||
bool _fixOffset = true;
|
|
||||||
bool _force;
|
|
||||||
bool _noMetadata;
|
|
||||||
bool _noTrim;
|
|
||||||
string _outputFile;
|
|
||||||
string _outputOptions;
|
|
||||||
bool _persistent;
|
|
||||||
ushort _retryPasses = 5;
|
|
||||||
bool _showHelp;
|
|
||||||
int _skip = 512;
|
|
||||||
int _speed;
|
|
||||||
bool _stopOnError;
|
|
||||||
string _wantedOutputFormat;
|
|
||||||
string _wantedSubchannel;
|
|
||||||
|
|
||||||
public DumpMediaCommand() : base("dump-media", "Dumps the media inserted on a device to a media image.")
|
public DumpMediaCommand() : base("dump-media", "Dumps the media inserted on a device to a media image.")
|
||||||
{
|
{
|
||||||
Options = new OptionSet
|
Add(new Option(new[]
|
||||||
{
|
{
|
||||||
$"{MainClass.AssemblyTitle} {MainClass.AssemblyVersion?.InformationalVersion}",
|
"--cicm-xml", "-x"
|
||||||
$"{MainClass.AssemblyCopyright}", "", $"usage: DiscImageChef {Name} [OPTIONS] device_path output_image",
|
}, "Take metadata from existing CICM XML sidecar.")
|
||||||
"", Help,
|
|
||||||
{
|
{
|
||||||
"cicm-xml|x=", "Take metadata from existing CICM XML sidecar.", s => _cicmXml = s
|
Argument = new Argument<string>(() => null), Required = false
|
||||||
|
});
|
||||||
|
|
||||||
|
Add(new Option(new[]
|
||||||
|
{
|
||||||
|
"--encoding", "-e"
|
||||||
|
}, "Name of character encoding to use.")
|
||||||
|
{
|
||||||
|
Argument = new Argument<string>(() => null), Required = false
|
||||||
|
});
|
||||||
|
|
||||||
|
Add(new Option("--first-pregap", "Try to read first track pregap. Only applicable to CD/DDCD/GD.")
|
||||||
|
{
|
||||||
|
Argument = new Argument<bool>(() => false), Required = false
|
||||||
|
});
|
||||||
|
|
||||||
|
Add(new Option("--fix-offset", "Fix audio tracks offset. Only applicable to CD/GD.")
|
||||||
|
{
|
||||||
|
Argument = new Argument<bool>(() => true), Required = false
|
||||||
|
});
|
||||||
|
|
||||||
|
Add(new Option(new[]
|
||||||
|
{
|
||||||
|
"--force", "-f"
|
||||||
|
}, "Continue dump whatever happens.")
|
||||||
|
{
|
||||||
|
Argument = new Argument<bool>(() => false), Required = false
|
||||||
|
});
|
||||||
|
|
||||||
|
Add(new Option(new[]
|
||||||
|
{
|
||||||
|
"--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.")
|
||||||
{
|
{
|
||||||
"encoding|e=", "Name of character encoding to use.", s => _encodingName = s
|
Argument = new Argument<string>(() => null), Required = false
|
||||||
}
|
});
|
||||||
};
|
|
||||||
|
|
||||||
if(DetectOS.GetRealPlatformID() != PlatformID.FreeBSD)
|
Add(new Option("--no-metadata", "Disables creating CICM XML sidecar.")
|
||||||
Options.Add("first-pregap", "Try to read first track pregap. Only applicable to CD/DDCD/GD.",
|
{
|
||||||
b => _firstTrackPregap = b != null);
|
Argument = new Argument<bool>(() => false), Required = false
|
||||||
|
});
|
||||||
|
|
||||||
Options.Add("fix-offset", "Fix audio tracks offset. Only applicable to CD/GD.",
|
Add(new Option("--no-trim", "Disables trimming errored from skipped sectors.")
|
||||||
b => _fixOffset = b != null);
|
{
|
||||||
|
Argument = new Argument<bool>(() => false), Required = false
|
||||||
|
});
|
||||||
|
|
||||||
Options.Add("force|f", "Continue dump whatever happens.", b => _force = b != null);
|
Add(new Option(new[]
|
||||||
|
{
|
||||||
|
"--options", "-O"
|
||||||
|
}, "Comma separated name=value pairs of options to pass to output image plugin.")
|
||||||
|
{
|
||||||
|
Argument = new Argument<string>(() => null), Required = false
|
||||||
|
});
|
||||||
|
|
||||||
Options.Add("format|t=",
|
Add(new Option("--persistent", "Try to recover partial or incorrect data.")
|
||||||
"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);
|
Argument = new Argument<bool>(() => false), Required = false
|
||||||
|
});
|
||||||
|
|
||||||
Options.Add("no-metadata", "Disables creating CICM XML sidecar.", b => _noMetadata = b != null);
|
Add(new Option(new[]
|
||||||
Options.Add("no-trim", "Disables trimming errored from skipped sectors.", b => _noTrim = b != null);
|
{
|
||||||
|
"--resume", "-r"
|
||||||
|
}, "Create/use resume mapfile.")
|
||||||
|
{
|
||||||
|
Argument = new Argument<bool>(() => true), Required = false
|
||||||
|
});
|
||||||
|
|
||||||
Options.Add("options|O=", "Comma separated name=value pairs of options to pass to output image plugin.",
|
Add(new Option(new[]
|
||||||
s => _outputOptions = s);
|
{
|
||||||
|
"--retry-passes", "-p"
|
||||||
|
}, "How many retry passes to do.")
|
||||||
|
{
|
||||||
|
Argument = new Argument<ushort>(() => 5), Required = false
|
||||||
|
});
|
||||||
|
|
||||||
Options.Add("persistent", "Try to recover partial or incorrect data.", b => _persistent = b != null);
|
Add(new Option(new[]
|
||||||
|
{
|
||||||
|
"--skip", "-k"
|
||||||
|
}, "When an unreadable sector is found skip this many sectors.")
|
||||||
|
{
|
||||||
|
Argument = new Argument<uint>(() => 512), Required = false
|
||||||
|
});
|
||||||
|
|
||||||
Options.Add("resume|r", "Create/use resume mapfile.", b => _doResume = b != null);
|
Add(new Option(new[]
|
||||||
|
{
|
||||||
|
"--stop-on-error", "-s"
|
||||||
|
}, "Stop media dump on first error.")
|
||||||
|
{
|
||||||
|
Argument = new Argument<bool>(() => false), Required = false
|
||||||
|
});
|
||||||
|
|
||||||
Options.Add("retry-passes|p=", "How many retry passes to do.", (ushort us) => _retryPasses = us);
|
Add(new Option("--subchannel",
|
||||||
Options.Add("skip|k=", "When an unreadable sector is found skip this many sectors.", (int i) => _skip = i);
|
"Subchannel to dump. Only applicable to CD/GD. Values: any, rw, rw-or-pq, pq, none.")
|
||||||
|
{
|
||||||
|
Argument = new Argument<string>(() => "any"), Required = false
|
||||||
|
});
|
||||||
|
|
||||||
Options.Add("stop-on-error|s", "Stop media dump on first error.", b => _stopOnError = b != null);
|
Add(new Option("--speed", "Speed to dump. Only applicable to optical drives, 0 for maximum.")
|
||||||
|
{
|
||||||
|
Argument = new Argument<byte>(() => 0), Required = false
|
||||||
|
});
|
||||||
|
|
||||||
Options.Add("help|h|?", "Show this message and exit.", v => _showHelp = v != null);
|
AddArgument(new Argument<string>
|
||||||
|
{
|
||||||
|
Arity = ArgumentArity.ExactlyOne, Description = "Device path", Name = "device-path"
|
||||||
|
});
|
||||||
|
|
||||||
Options.Add("subchannel",
|
AddArgument(new Argument<string>
|
||||||
"Subchannel to dump. Only applicable to CD/GD. Values: any, rw, rw-or-pq, pq, none",
|
{
|
||||||
s => _wantedSubchannel = s);
|
Arity = ArgumentArity.ExactlyOne, Description = "Output image path", Name = "output-path"
|
||||||
|
});
|
||||||
|
|
||||||
Options.Add("speed", "Speed to dump. Only applicable to optical drives, 0 for maximum",
|
Handler = CommandHandler.Create(GetType().GetMethod(nameof(Invoke)));
|
||||||
(int i) => _speed = i);
|
|
||||||
|
|
||||||
/* TODO: Disabled temporarily
|
|
||||||
Options.Add("raw|r", "Dump sectors with tags included. For optical media, dump scrambled sectors.", (b) => raw = b != null);*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override int Invoke(IEnumerable<string> arguments)
|
static int Invoke(bool debug, bool verbose, string cicmXml, string devicePath, bool resume, string encoding,
|
||||||
|
bool firstTrackPregap, bool fixOffset, bool force, bool noMetadata, bool noTrim,
|
||||||
|
string outputPath, string options, bool persistent, ushort retryPasses, int skip,
|
||||||
|
int speed, bool stopOnError, string format, string subchannel)
|
||||||
{
|
{
|
||||||
List<string> extra = Options.Parse(arguments);
|
|
||||||
|
|
||||||
if(_showHelp)
|
|
||||||
{
|
|
||||||
Options.WriteOptionDescriptions(CommandSet.Out);
|
|
||||||
|
|
||||||
return(int)ErrorNumber.HelpRequested;
|
|
||||||
}
|
|
||||||
|
|
||||||
MainClass.PrintCopyright();
|
MainClass.PrintCopyright();
|
||||||
|
|
||||||
if(MainClass.Debug)
|
if(debug)
|
||||||
DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
||||||
|
|
||||||
if(MainClass.Verbose)
|
if(verbose)
|
||||||
DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
||||||
|
|
||||||
Statistics.AddCommand("dump-media");
|
Statistics.AddCommand("dump-media");
|
||||||
|
|
||||||
if(extra.Count > 2)
|
DicConsole.DebugWriteLine("Dump-Media command", "--cicm-xml={0}", cicmXml);
|
||||||
{
|
DicConsole.DebugWriteLine("Dump-Media command", "--debug={0}", debug);
|
||||||
DicConsole.ErrorWriteLine("Too many arguments.");
|
DicConsole.DebugWriteLine("Dump-Media command", "--device={0}", devicePath);
|
||||||
|
DicConsole.DebugWriteLine("Dump-Media command", "--encoding={0}", encoding);
|
||||||
return(int)ErrorNumber.UnexpectedArgumentCount;
|
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);
|
||||||
if(extra.Count <= 1)
|
DicConsole.DebugWriteLine("Dump-Media command", "--format={0}", format);
|
||||||
{
|
DicConsole.DebugWriteLine("Dump-Media command", "--no-metadata={0}", noMetadata);
|
||||||
DicConsole.ErrorWriteLine("Missing paths.");
|
DicConsole.DebugWriteLine("Dump-Media command", "--options={0}", options);
|
||||||
|
DicConsole.DebugWriteLine("Dump-Media command", "--output={0}", outputPath);
|
||||||
return(int)ErrorNumber.MissingArgument;
|
DicConsole.DebugWriteLine("Dump-Media command", "--persistent={0}", persistent);
|
||||||
}
|
DicConsole.DebugWriteLine("Dump-Media command", "--resume={0}", resume);
|
||||||
|
DicConsole.DebugWriteLine("Dump-Media command", "--retry-passes={0}", retryPasses);
|
||||||
_devicePath = extra[0];
|
DicConsole.DebugWriteLine("Dump-Media command", "--skip={0}", skip);
|
||||||
_outputFile = extra[1];
|
DicConsole.DebugWriteLine("Dump-Media command", "--stop-on-error={0}", stopOnError);
|
||||||
|
DicConsole.DebugWriteLine("Dump-Media command", "--verbose={0}", verbose);
|
||||||
DicConsole.DebugWriteLine("Dump-Media command", "--cicm-xml={0}", _cicmXml);
|
DicConsole.DebugWriteLine("Dump-Media command", "--subchannel={0}", subchannel);
|
||||||
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}", _wantedOutputFormat);
|
|
||||||
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);
|
|
||||||
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);
|
|
||||||
DicConsole.DebugWriteLine("Dump-Media command", "--subchannel={0}", _wantedSubchannel);
|
|
||||||
|
|
||||||
// TODO: Disabled temporarily
|
// TODO: Disabled temporarily
|
||||||
//DicConsole.DebugWriteLine("Dump-Media command", "--raw={0}", raw);
|
//DicConsole.DebugWriteLine("Dump-Media command", "--raw={0}", raw);
|
||||||
|
|
||||||
Dictionary<string, string> parsedOptions = Core.Options.Parse(_outputOptions);
|
Dictionary<string, string> parsedOptions = Core.Options.Parse(options);
|
||||||
DicConsole.DebugWriteLine("Dump-Media command", "Parsed options:");
|
DicConsole.DebugWriteLine("Dump-Media command", "Parsed options:");
|
||||||
|
|
||||||
foreach(KeyValuePair<string, string> parsedOption in parsedOptions)
|
foreach(KeyValuePair<string, string> parsedOption in parsedOptions)
|
||||||
DicConsole.DebugWriteLine("Dump-Media command", "{0} = {1}", parsedOption.Key, parsedOption.Value);
|
DicConsole.DebugWriteLine("Dump-Media command", "{0} = {1}", parsedOption.Key, parsedOption.Value);
|
||||||
|
|
||||||
Encoding encoding = null;
|
Encoding encodingClass = null;
|
||||||
|
|
||||||
if(_encodingName != null)
|
if(encoding != null)
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
encoding = Claunia.Encoding.Encoding.GetEncoding(_encodingName);
|
encodingClass = Claunia.Encoding.Encoding.GetEncoding(encoding);
|
||||||
|
|
||||||
if(MainClass.Verbose)
|
if(verbose)
|
||||||
DicConsole.VerboseWriteLine("Using encoding for {0}.", encoding.EncodingName);
|
DicConsole.VerboseWriteLine("Using encoding for {0}.", encodingClass.EncodingName);
|
||||||
}
|
}
|
||||||
catch(ArgumentException)
|
catch(ArgumentException)
|
||||||
{
|
{
|
||||||
@@ -214,48 +238,48 @@ namespace DiscImageChef.Commands
|
|||||||
return(int)ErrorNumber.EncodingUnknown;
|
return(int)ErrorNumber.EncodingUnknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
DumpSubchannel subchannel = DumpSubchannel.Any;
|
DumpSubchannel wantedSubchannel = DumpSubchannel.Any;
|
||||||
|
|
||||||
switch(_wantedSubchannel?.ToLowerInvariant())
|
switch(subchannel?.ToLowerInvariant())
|
||||||
{
|
{
|
||||||
case"any":
|
case"any":
|
||||||
case null:
|
case null:
|
||||||
subchannel = DumpSubchannel.Any;
|
wantedSubchannel = DumpSubchannel.Any;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case"rw":
|
case"rw":
|
||||||
subchannel = DumpSubchannel.Rw;
|
wantedSubchannel = DumpSubchannel.Rw;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case"rw-or-pq":
|
case"rw-or-pq":
|
||||||
subchannel = DumpSubchannel.RwOrPq;
|
wantedSubchannel = DumpSubchannel.RwOrPq;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case"pq":
|
case"pq":
|
||||||
subchannel = DumpSubchannel.Pq;
|
wantedSubchannel = DumpSubchannel.Pq;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case"none":
|
case"none":
|
||||||
subchannel = DumpSubchannel.None;
|
wantedSubchannel = DumpSubchannel.None;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
DicConsole.WriteLine("Incorrect subchannel type \"{0}\" requested.", _wantedSubchannel);
|
DicConsole.WriteLine("Incorrect subchannel type \"{0}\" requested.", subchannel);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_devicePath.Length == 2 &&
|
if(devicePath.Length == 2 &&
|
||||||
_devicePath[1] == ':' &&
|
devicePath[1] == ':' &&
|
||||||
_devicePath[0] != '/' &&
|
devicePath[0] != '/' &&
|
||||||
char.IsLetter(_devicePath[0]))
|
char.IsLetter(devicePath[0]))
|
||||||
_devicePath = "\\\\.\\" + char.ToUpper(_devicePath[0]) + ':';
|
devicePath = "\\\\.\\" + char.ToUpper(devicePath[0]) + ':';
|
||||||
|
|
||||||
Device dev;
|
Device dev;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
dev = new Device(_devicePath);
|
dev = new Device(devicePath);
|
||||||
|
|
||||||
if(dev.IsRemote)
|
if(dev.IsRemote)
|
||||||
Statistics.AddRemote(dev.RemoteApplication, dev.RemoteVersion, dev.RemoteOperatingSystem,
|
Statistics.AddRemote(dev.RemoteApplication, dev.RemoteVersion, dev.RemoteOperatingSystem,
|
||||||
@@ -277,17 +301,17 @@ namespace DiscImageChef.Commands
|
|||||||
|
|
||||||
Statistics.AddDevice(dev);
|
Statistics.AddDevice(dev);
|
||||||
|
|
||||||
string outputPrefix = Path.Combine(Path.GetDirectoryName(_outputFile),
|
string outputPrefix = Path.Combine(Path.GetDirectoryName(outputPath),
|
||||||
Path.GetFileNameWithoutExtension(_outputFile));
|
Path.GetFileNameWithoutExtension(outputPath));
|
||||||
|
|
||||||
Resume resume = null;
|
Resume resumeClass = null;
|
||||||
var xs = new XmlSerializer(typeof(Resume));
|
var xs = new XmlSerializer(typeof(Resume));
|
||||||
|
|
||||||
if(File.Exists(outputPrefix + ".resume.xml") && _doResume)
|
if(File.Exists(outputPrefix + ".resume.xml") && resume)
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var sr = new StreamReader(outputPrefix + ".resume.xml");
|
var sr = new StreamReader(outputPrefix + ".resume.xml");
|
||||||
resume = (Resume)xs.Deserialize(sr);
|
resumeClass = (Resume)xs.Deserialize(sr);
|
||||||
sr.Close();
|
sr.Close();
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
@@ -297,10 +321,10 @@ namespace DiscImageChef.Commands
|
|||||||
return(int)ErrorNumber.InvalidResume;
|
return(int)ErrorNumber.InvalidResume;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(resume != null &&
|
if(resumeClass != null &&
|
||||||
resume.NextBlock > resume.LastBlock &&
|
resumeClass.NextBlock > resumeClass.LastBlock &&
|
||||||
resume.BadBlocks.Count == 0 &&
|
resumeClass.BadBlocks.Count == 0 &&
|
||||||
!resume.Tape)
|
!resumeClass.Tape)
|
||||||
{
|
{
|
||||||
DicConsole.WriteLine("Media already dumped correctly, not continuing...");
|
DicConsole.WriteLine("Media already dumped correctly, not continuing...");
|
||||||
|
|
||||||
@@ -310,12 +334,12 @@ namespace DiscImageChef.Commands
|
|||||||
CICMMetadataType sidecar = null;
|
CICMMetadataType sidecar = null;
|
||||||
var sidecarXs = new XmlSerializer(typeof(CICMMetadataType));
|
var sidecarXs = new XmlSerializer(typeof(CICMMetadataType));
|
||||||
|
|
||||||
if(_cicmXml != null)
|
if(cicmXml != null)
|
||||||
if(File.Exists(_cicmXml))
|
if(File.Exists(cicmXml))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var sr = new StreamReader(_cicmXml);
|
var sr = new StreamReader(cicmXml);
|
||||||
sidecar = (CICMMetadataType)sidecarXs.Deserialize(sr);
|
sidecar = (CICMMetadataType)sidecarXs.Deserialize(sr);
|
||||||
sr.Close();
|
sr.Close();
|
||||||
}
|
}
|
||||||
@@ -337,19 +361,18 @@ namespace DiscImageChef.Commands
|
|||||||
List<IWritableImage> candidates = new List<IWritableImage>();
|
List<IWritableImage> candidates = new List<IWritableImage>();
|
||||||
|
|
||||||
// Try extension
|
// Try extension
|
||||||
if(string.IsNullOrEmpty(_wantedOutputFormat))
|
if(string.IsNullOrEmpty(format))
|
||||||
candidates.AddRange(plugins.WritableImages.Values.Where(t =>
|
candidates.AddRange(plugins.WritableImages.Values.Where(t =>
|
||||||
t.KnownExtensions.
|
t.KnownExtensions.
|
||||||
Contains(Path.
|
Contains(Path.GetExtension(outputPath))));
|
||||||
GetExtension(_outputFile))));
|
|
||||||
|
|
||||||
// Try Id
|
// Try Id
|
||||||
else if(Guid.TryParse(_wantedOutputFormat, out Guid outId))
|
else if(Guid.TryParse(format, out Guid outId))
|
||||||
candidates.AddRange(plugins.WritableImages.Values.Where(t => t.Id.Equals(outId)));
|
candidates.AddRange(plugins.WritableImages.Values.Where(t => t.Id.Equals(outId)));
|
||||||
|
|
||||||
// Try name
|
// Try name
|
||||||
else
|
else
|
||||||
candidates.AddRange(plugins.WritableImages.Values.Where(t => string.Equals(t.Name, _wantedOutputFormat,
|
candidates.AddRange(plugins.WritableImages.Values.Where(t => string.Equals(t.Name, format,
|
||||||
StringComparison.
|
StringComparison.
|
||||||
InvariantCultureIgnoreCase)));
|
InvariantCultureIgnoreCase)));
|
||||||
|
|
||||||
@@ -371,7 +394,7 @@ namespace DiscImageChef.Commands
|
|||||||
|
|
||||||
var dumpLog = new DumpLog(outputPrefix + ".log", dev);
|
var dumpLog = new DumpLog(outputPrefix + ".log", dev);
|
||||||
|
|
||||||
if(MainClass.Verbose)
|
if(verbose)
|
||||||
{
|
{
|
||||||
dumpLog.WriteLine("Output image format: {0} ({1}).", outputFormat.Name, outputFormat.Id);
|
dumpLog.WriteLine("Output image format: {0} ({1}).", outputFormat.Name, outputFormat.Id);
|
||||||
DicConsole.VerboseWriteLine("Output image format: {0} ({1}).", outputFormat.Name, outputFormat.Id);
|
DicConsole.VerboseWriteLine("Output image format: {0} ({1}).", outputFormat.Name, outputFormat.Id);
|
||||||
@@ -382,10 +405,10 @@ namespace DiscImageChef.Commands
|
|||||||
DicConsole.WriteLine("Output image format: {0}.", outputFormat.Name);
|
DicConsole.WriteLine("Output image format: {0}.", outputFormat.Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
var dumper = new Dump(_doResume, dev, _devicePath, outputFormat, _retryPasses, _force, false, _persistent,
|
var dumper = new Dump(resume, dev, devicePath, outputFormat, retryPasses, force, false, persistent,
|
||||||
_stopOnError, resume, dumpLog, encoding, outputPrefix, _outputFile, parsedOptions,
|
stopOnError, resumeClass, dumpLog, encodingClass, outputPrefix, outputPath,
|
||||||
sidecar, (uint)_skip, _noMetadata, _noTrim, _firstTrackPregap, _fixOffset,
|
parsedOptions, sidecar, (uint)skip, noMetadata, noTrim, firstTrackPregap, fixOffset,
|
||||||
MainClass.Debug, subchannel, _speed);
|
debug, wantedSubchannel, speed);
|
||||||
|
|
||||||
dumper.UpdateStatus += Progress.UpdateStatus;
|
dumper.UpdateStatus += Progress.UpdateStatus;
|
||||||
dumper.ErrorMessage += Progress.ErrorMessage;
|
dumper.ErrorMessage += Progress.ErrorMessage;
|
||||||
|
|||||||
@@ -30,92 +30,80 @@
|
|||||||
// Copyright © 2011-2019 Natalia Portillo
|
// Copyright © 2011-2019 Natalia Portillo
|
||||||
// ****************************************************************************/
|
// ****************************************************************************/
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.CommandLine;
|
||||||
|
using System.CommandLine.Invocation;
|
||||||
using DiscImageChef.CommonTypes;
|
using DiscImageChef.CommonTypes;
|
||||||
using DiscImageChef.CommonTypes.Enums;
|
using DiscImageChef.CommonTypes.Enums;
|
||||||
using DiscImageChef.CommonTypes.Interfaces;
|
using DiscImageChef.CommonTypes.Interfaces;
|
||||||
using DiscImageChef.Console;
|
using DiscImageChef.Console;
|
||||||
using DiscImageChef.Core;
|
using DiscImageChef.Core;
|
||||||
using Mono.Options;
|
|
||||||
|
|
||||||
namespace DiscImageChef.Commands
|
namespace DiscImageChef.Commands
|
||||||
{
|
{
|
||||||
class EntropyCommand : Command
|
internal class EntropyCommand : Command
|
||||||
{
|
{
|
||||||
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.")
|
public EntropyCommand() : base("entropy", "Calculates entropy and/or duplicated sectors of an image.")
|
||||||
{
|
{
|
||||||
Options = new OptionSet
|
Add(new Option(new[]
|
||||||
{
|
{
|
||||||
$"{MainClass.AssemblyTitle} {MainClass.AssemblyVersion?.InformationalVersion}",
|
"--duplicated-sectors", "-p"
|
||||||
$"{MainClass.AssemblyCopyright}",
|
}, "Calculates how many sectors are duplicated (have same exact data in user area).")
|
||||||
"",
|
|
||||||
$"usage: DiscImageChef {Name} [OPTIONS] imagefile",
|
|
||||||
"",
|
|
||||||
Help,
|
|
||||||
{
|
{
|
||||||
"duplicated-sectors|p",
|
Argument = new Argument<bool>(() => true), Required = false
|
||||||
"Calculates how many sectors are duplicated (have same exact data in user area).",
|
});
|
||||||
b => duplicatedSectors = b != null
|
|
||||||
},
|
Add(new Option(new[]
|
||||||
{
|
{
|
||||||
"separated-tracks|t", "Calculates entropy for each track separately.",
|
"--separated-tracks", "-t"
|
||||||
b => separatedTracks = b != null
|
}, "Calculates entropy for each track separately.")
|
||||||
},
|
{
|
||||||
{"whole-disc|w", "Calculates entropy for the whole disc.", b => wholeDisc = b != null},
|
Argument = new Argument<bool>(() => true), Required = false
|
||||||
{"help|h|?", "Show this message and exit.", v => showHelp = v != null}
|
});
|
||||||
};
|
|
||||||
|
Add(new Option(new[]
|
||||||
|
{
|
||||||
|
"--whole-disc", "-w"
|
||||||
|
}, "Calculates entropy for the whole disc.")
|
||||||
|
{
|
||||||
|
Argument = new Argument<bool>(() => true), Required = false
|
||||||
|
});
|
||||||
|
|
||||||
|
AddArgument(new Argument<string>
|
||||||
|
{
|
||||||
|
Arity = ArgumentArity.ExactlyOne, Description = "Media image path", Name = "image-path"
|
||||||
|
});
|
||||||
|
|
||||||
|
Handler = CommandHandler.Create(GetType().GetMethod(nameof(Invoke)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override int Invoke(IEnumerable<string> arguments)
|
static int Invoke(bool debug, bool verbose, bool duplicatedSectors, string imagePath, bool separatedTracks,
|
||||||
|
bool wholeDisc)
|
||||||
{
|
{
|
||||||
List<string> extra = Options.Parse(arguments);
|
|
||||||
|
|
||||||
if(showHelp)
|
|
||||||
{
|
|
||||||
Options.WriteOptionDescriptions(CommandSet.Out);
|
|
||||||
return (int)ErrorNumber.HelpRequested;
|
|
||||||
}
|
|
||||||
|
|
||||||
MainClass.PrintCopyright();
|
MainClass.PrintCopyright();
|
||||||
if(MainClass.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
|
||||||
if(MainClass.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
if(debug)
|
||||||
|
DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
||||||
|
|
||||||
|
if(verbose)
|
||||||
|
DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
||||||
|
|
||||||
Statistics.AddCommand("entropy");
|
Statistics.AddCommand("entropy");
|
||||||
|
|
||||||
if(extra.Count > 1)
|
DicConsole.DebugWriteLine("Entropy command", "--debug={0}", debug);
|
||||||
{
|
|
||||||
DicConsole.ErrorWriteLine("Too many arguments.");
|
|
||||||
return (int)ErrorNumber.UnexpectedArgumentCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(extra.Count == 0)
|
|
||||||
{
|
|
||||||
DicConsole.ErrorWriteLine("Missing input image.");
|
|
||||||
return (int)ErrorNumber.MissingArgument;
|
|
||||||
}
|
|
||||||
|
|
||||||
inputFile = extra[0];
|
|
||||||
|
|
||||||
DicConsole.DebugWriteLine("Entropy command", "--debug={0}", MainClass.Debug);
|
|
||||||
DicConsole.DebugWriteLine("Entropy command", "--duplicated-sectors={0}", duplicatedSectors);
|
DicConsole.DebugWriteLine("Entropy command", "--duplicated-sectors={0}", duplicatedSectors);
|
||||||
DicConsole.DebugWriteLine("Entropy command", "--input={0}", inputFile);
|
DicConsole.DebugWriteLine("Entropy command", "--input={0}", imagePath);
|
||||||
DicConsole.DebugWriteLine("Entropy command", "--separated-tracks={0}", separatedTracks);
|
DicConsole.DebugWriteLine("Entropy command", "--separated-tracks={0}", separatedTracks);
|
||||||
DicConsole.DebugWriteLine("Entropy command", "--verbose={0}", MainClass.Verbose);
|
DicConsole.DebugWriteLine("Entropy command", "--verbose={0}", verbose);
|
||||||
DicConsole.DebugWriteLine("Entropy command", "--whole-disc={0}", wholeDisc);
|
DicConsole.DebugWriteLine("Entropy command", "--whole-disc={0}", wholeDisc);
|
||||||
|
|
||||||
FiltersList filtersList = new FiltersList();
|
var filtersList = new FiltersList();
|
||||||
IFilter inputFilter = filtersList.GetFilter(inputFile);
|
IFilter inputFilter = filtersList.GetFilter(imagePath);
|
||||||
|
|
||||||
if(inputFilter == null)
|
if(inputFilter == null)
|
||||||
{
|
{
|
||||||
DicConsole.ErrorWriteLine("Cannot open specified file.");
|
DicConsole.ErrorWriteLine("Cannot open specified file.");
|
||||||
return (int)ErrorNumber.CannotOpenFile;
|
|
||||||
|
return(int)ErrorNumber.CannotOpenFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
IMediaImage inputFormat = ImageFormat.Detect(inputFilter);
|
IMediaImage inputFormat = ImageFormat.Detect(inputFilter);
|
||||||
@@ -123,7 +111,8 @@ namespace DiscImageChef.Commands
|
|||||||
if(inputFormat == null)
|
if(inputFormat == null)
|
||||||
{
|
{
|
||||||
DicConsole.ErrorWriteLine("Unable to recognize image format, not checksumming");
|
DicConsole.ErrorWriteLine("Unable to recognize image format, not checksumming");
|
||||||
return (int)ErrorNumber.UnrecognizedFormat;
|
|
||||||
|
return(int)ErrorNumber.UnrecognizedFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
inputFormat.Open(inputFilter);
|
inputFormat.Open(inputFilter);
|
||||||
@@ -131,7 +120,7 @@ namespace DiscImageChef.Commands
|
|||||||
Statistics.AddMedia(inputFormat.Info.MediaType, false);
|
Statistics.AddMedia(inputFormat.Info.MediaType, false);
|
||||||
Statistics.AddFilter(inputFilter.Name);
|
Statistics.AddFilter(inputFilter.Name);
|
||||||
|
|
||||||
Entropy entropyCalculator = new Entropy(MainClass.Debug, MainClass.Verbose, inputFormat);
|
var entropyCalculator = new Entropy(debug, verbose, inputFormat);
|
||||||
entropyCalculator.InitProgressEvent += Progress.InitProgress;
|
entropyCalculator.InitProgressEvent += Progress.InitProgress;
|
||||||
entropyCalculator.InitProgress2Event += Progress.InitProgress2;
|
entropyCalculator.InitProgress2Event += Progress.InitProgress2;
|
||||||
entropyCalculator.UpdateProgressEvent += Progress.UpdateProgress;
|
entropyCalculator.UpdateProgressEvent += Progress.UpdateProgress;
|
||||||
@@ -142,9 +131,11 @@ namespace DiscImageChef.Commands
|
|||||||
if(separatedTracks)
|
if(separatedTracks)
|
||||||
{
|
{
|
||||||
EntropyResults[] tracksEntropy = entropyCalculator.CalculateTracksEntropy(duplicatedSectors);
|
EntropyResults[] tracksEntropy = entropyCalculator.CalculateTracksEntropy(duplicatedSectors);
|
||||||
|
|
||||||
foreach(EntropyResults trackEntropy in tracksEntropy)
|
foreach(EntropyResults trackEntropy in tracksEntropy)
|
||||||
{
|
{
|
||||||
DicConsole.WriteLine("Entropy for track {0} is {1:F4}.", trackEntropy.Track, trackEntropy.Entropy);
|
DicConsole.WriteLine("Entropy for track {0} is {1:F4}.", trackEntropy.Track, trackEntropy.Entropy);
|
||||||
|
|
||||||
if(trackEntropy.UniqueSectors != null)
|
if(trackEntropy.UniqueSectors != null)
|
||||||
DicConsole.WriteLine("Track {0} has {1} unique sectors ({2:P3})", trackEntropy.Track,
|
DicConsole.WriteLine("Track {0} has {1} unique sectors ({2:P3})", trackEntropy.Track,
|
||||||
trackEntropy.UniqueSectors,
|
trackEntropy.UniqueSectors,
|
||||||
@@ -152,16 +143,18 @@ namespace DiscImageChef.Commands
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!wholeDisc) return (int)ErrorNumber.NoError;
|
if(!wholeDisc)
|
||||||
|
return(int)ErrorNumber.NoError;
|
||||||
|
|
||||||
EntropyResults entropy = entropyCalculator.CalculateMediaEntropy(duplicatedSectors);
|
EntropyResults entropy = entropyCalculator.CalculateMediaEntropy(duplicatedSectors);
|
||||||
|
|
||||||
DicConsole.WriteLine("Entropy for disk is {0:F4}.", entropy.Entropy);
|
DicConsole.WriteLine("Entropy for disk is {0:F4}.", entropy.Entropy);
|
||||||
|
|
||||||
if(entropy.UniqueSectors != null)
|
if(entropy.UniqueSectors != null)
|
||||||
DicConsole.WriteLine("Disk has {0} unique sectors ({1:P3})", entropy.UniqueSectors,
|
DicConsole.WriteLine("Disk has {0} unique sectors ({1:P3})", entropy.UniqueSectors,
|
||||||
(double)entropy.UniqueSectors / (double)entropy.Sectors);
|
(double)entropy.UniqueSectors / (double)entropy.Sectors);
|
||||||
|
|
||||||
return (int)ErrorNumber.NoError;
|
return(int)ErrorNumber.NoError;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -32,6 +32,8 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.CommandLine;
|
||||||
|
using System.CommandLine.Invocation;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using DiscImageChef.CommonTypes;
|
using DiscImageChef.CommonTypes;
|
||||||
@@ -40,110 +42,115 @@ using DiscImageChef.CommonTypes.Interfaces;
|
|||||||
using DiscImageChef.CommonTypes.Structs;
|
using DiscImageChef.CommonTypes.Structs;
|
||||||
using DiscImageChef.Console;
|
using DiscImageChef.Console;
|
||||||
using DiscImageChef.Core;
|
using DiscImageChef.Core;
|
||||||
using Mono.Options;
|
|
||||||
using FileAttributes = DiscImageChef.CommonTypes.Structs.FileAttributes;
|
using FileAttributes = DiscImageChef.CommonTypes.Structs.FileAttributes;
|
||||||
|
|
||||||
namespace DiscImageChef.Commands
|
namespace DiscImageChef.Commands
|
||||||
{
|
{
|
||||||
class ExtractFilesCommand : Command
|
internal class ExtractFilesCommand : Command
|
||||||
{
|
{
|
||||||
string encodingName;
|
|
||||||
bool extractXattrs;
|
|
||||||
string inputFile;
|
|
||||||
string @namespace;
|
|
||||||
string outputDir;
|
|
||||||
string pluginOptions;
|
|
||||||
bool showHelp;
|
|
||||||
|
|
||||||
public ExtractFilesCommand() : base("extract-files", "Extracts all files in disc image.")
|
public ExtractFilesCommand() : base("extract-files", "Extracts all files in disc image.")
|
||||||
{
|
{
|
||||||
Options = new OptionSet
|
Add(new Option(new[]
|
||||||
{
|
{
|
||||||
$"{MainClass.AssemblyTitle} {MainClass.AssemblyVersion?.InformationalVersion}",
|
"--encoding", "-e"
|
||||||
$"{MainClass.AssemblyCopyright}",
|
}, "Name of character encoding to use.")
|
||||||
"",
|
|
||||||
$"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.",
|
Argument = new Argument<string>(() => null), Required = false
|
||||||
s => pluginOptions = s
|
});
|
||||||
},
|
|
||||||
|
Add(new Option(new[]
|
||||||
{
|
{
|
||||||
"output|o=", "Directory where extracted files will be created. Will abort if it exists.",
|
"--options", "-O"
|
||||||
s => outputDir = s
|
}, "Comma separated name=value pairs of options to pass to filesystem plugin.")
|
||||||
},
|
{
|
||||||
{"xattrs|x", "Extract extended attributes if present.", b => extractXattrs = b != null},
|
Argument = new Argument<string>(() => null), Required = false
|
||||||
{"namespace|n=", "Namespace to use for filenames.", s => @namespace = s},
|
});
|
||||||
{"help|h|?", "Show this message and exit.", v => showHelp = v != null}
|
|
||||||
};
|
Add(new Option(new[]
|
||||||
|
{
|
||||||
|
"--xattrs", "-x"
|
||||||
|
}, "Extract extended attributes if present.")
|
||||||
|
{
|
||||||
|
Argument = new Argument<bool>(() => false), Required = false
|
||||||
|
});
|
||||||
|
|
||||||
|
Add(new Option(new[]
|
||||||
|
{
|
||||||
|
"--namespace", "-n"
|
||||||
|
}, "Namespace to use for filenames.")
|
||||||
|
{
|
||||||
|
Argument = new Argument<string>(() => null), Required = false
|
||||||
|
});
|
||||||
|
|
||||||
|
AddArgument(new Argument<string>
|
||||||
|
{
|
||||||
|
Arity = ArgumentArity.ExactlyOne, Description = "Disc image path", Name = "image-path"
|
||||||
|
});
|
||||||
|
|
||||||
|
AddArgument(new Argument<string>
|
||||||
|
{
|
||||||
|
Arity = ArgumentArity.ExactlyOne,
|
||||||
|
Description = "Directory where extracted files will be created. Will abort if it exists",
|
||||||
|
Name = "output-dir"
|
||||||
|
});
|
||||||
|
|
||||||
|
Handler = CommandHandler.Create(GetType().GetMethod(nameof(Invoke)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override int Invoke(IEnumerable<string> arguments)
|
static int Invoke(bool debug, bool verbose, string encoding, bool xattrs, string imagePath, string @namespace,
|
||||||
|
string outputDir, string options)
|
||||||
{
|
{
|
||||||
List<string> extra = Options.Parse(arguments);
|
|
||||||
|
|
||||||
if(showHelp)
|
|
||||||
{
|
|
||||||
Options.WriteOptionDescriptions(CommandSet.Out);
|
|
||||||
return (int)ErrorNumber.HelpRequested;
|
|
||||||
}
|
|
||||||
|
|
||||||
MainClass.PrintCopyright();
|
MainClass.PrintCopyright();
|
||||||
if(MainClass.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
|
||||||
if(MainClass.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
if(debug)
|
||||||
|
DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
||||||
|
|
||||||
|
if(verbose)
|
||||||
|
DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
||||||
|
|
||||||
Statistics.AddCommand("extract-files");
|
Statistics.AddCommand("extract-files");
|
||||||
|
|
||||||
if(extra.Count > 1)
|
DicConsole.DebugWriteLine("Extract-Files command", "--debug={0}", debug);
|
||||||
{
|
DicConsole.DebugWriteLine("Extract-Files command", "--encoding={0}", encoding);
|
||||||
DicConsole.ErrorWriteLine("Too many arguments.");
|
DicConsole.DebugWriteLine("Extract-Files command", "--input={0}", imagePath);
|
||||||
return (int)ErrorNumber.UnexpectedArgumentCount;
|
DicConsole.DebugWriteLine("Extract-Files command", "--options={0}", options);
|
||||||
}
|
|
||||||
|
|
||||||
if(extra.Count == 0)
|
|
||||||
{
|
|
||||||
DicConsole.ErrorWriteLine("Missing input image.");
|
|
||||||
return (int)ErrorNumber.MissingArgument;
|
|
||||||
}
|
|
||||||
|
|
||||||
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", "--output={0}", outputDir);
|
||||||
DicConsole.DebugWriteLine("Extract-Files command", "--verbose={0}", MainClass.Verbose);
|
DicConsole.DebugWriteLine("Extract-Files command", "--verbose={0}", verbose);
|
||||||
DicConsole.DebugWriteLine("Extract-Files command", "--xattrs={0}", extractXattrs);
|
DicConsole.DebugWriteLine("Extract-Files command", "--xattrs={0}", xattrs);
|
||||||
|
|
||||||
FiltersList filtersList = new FiltersList();
|
var filtersList = new FiltersList();
|
||||||
IFilter inputFilter = filtersList.GetFilter(inputFile);
|
IFilter inputFilter = filtersList.GetFilter(imagePath);
|
||||||
|
|
||||||
Dictionary<string, string> parsedOptions = Core.Options.Parse(pluginOptions);
|
Dictionary<string, string> parsedOptions = Core.Options.Parse(options);
|
||||||
DicConsole.DebugWriteLine("Extract-Files command", "Parsed options:");
|
DicConsole.DebugWriteLine("Extract-Files command", "Parsed options:");
|
||||||
|
|
||||||
foreach(KeyValuePair<string, string> parsedOption in parsedOptions)
|
foreach(KeyValuePair<string, string> parsedOption in parsedOptions)
|
||||||
DicConsole.DebugWriteLine("Extract-Files command", "{0} = {1}", parsedOption.Key, parsedOption.Value);
|
DicConsole.DebugWriteLine("Extract-Files command", "{0} = {1}", parsedOption.Key, parsedOption.Value);
|
||||||
parsedOptions.Add("debug", MainClass.Debug.ToString());
|
|
||||||
|
parsedOptions.Add("debug", debug.ToString());
|
||||||
|
|
||||||
if(inputFilter == null)
|
if(inputFilter == null)
|
||||||
{
|
{
|
||||||
DicConsole.ErrorWriteLine("Cannot open specified file.");
|
DicConsole.ErrorWriteLine("Cannot open specified file.");
|
||||||
return (int)ErrorNumber.CannotOpenFile;
|
|
||||||
|
return(int)ErrorNumber.CannotOpenFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
Encoding encoding = null;
|
Encoding encodingClass = null;
|
||||||
|
|
||||||
if(encodingName != null)
|
if(encoding != null)
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
encoding = Claunia.Encoding.Encoding.GetEncoding(encodingName);
|
encodingClass = Claunia.Encoding.Encoding.GetEncoding(encoding);
|
||||||
if(MainClass.Verbose) DicConsole.VerboseWriteLine("Using encoding for {0}.", encoding.EncodingName);
|
|
||||||
|
if(verbose)
|
||||||
|
DicConsole.VerboseWriteLine("Using encoding for {0}.", encodingClass.EncodingName);
|
||||||
}
|
}
|
||||||
catch(ArgumentException)
|
catch(ArgumentException)
|
||||||
{
|
{
|
||||||
DicConsole.ErrorWriteLine("Specified encoding is not supported.");
|
DicConsole.ErrorWriteLine("Specified encoding is not supported.");
|
||||||
return (int)ErrorNumber.EncodingUnknown;
|
|
||||||
|
return(int)ErrorNumber.EncodingUnknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
PluginBase plugins = GetPluginBase.Instance;
|
PluginBase plugins = GetPluginBase.Instance;
|
||||||
@@ -155,24 +162,29 @@ namespace DiscImageChef.Commands
|
|||||||
if(imageFormat == null)
|
if(imageFormat == null)
|
||||||
{
|
{
|
||||||
DicConsole.WriteLine("Image format not identified, not proceeding with analysis.");
|
DicConsole.WriteLine("Image format not identified, not proceeding with analysis.");
|
||||||
return (int)ErrorNumber.UnrecognizedFormat;
|
|
||||||
|
return(int)ErrorNumber.UnrecognizedFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(MainClass.Verbose)
|
if(verbose)
|
||||||
DicConsole.VerboseWriteLine("Image format identified by {0} ({1}).", imageFormat.Name,
|
DicConsole.VerboseWriteLine("Image format identified by {0} ({1}).", imageFormat.Name,
|
||||||
imageFormat.Id);
|
imageFormat.Id);
|
||||||
else DicConsole.WriteLine("Image format identified by {0}.", imageFormat.Name);
|
else
|
||||||
|
DicConsole.WriteLine("Image format identified by {0}.", imageFormat.Name);
|
||||||
|
|
||||||
if (outputDir == null)
|
if(outputDir == null)
|
||||||
{
|
{
|
||||||
DicConsole.WriteLine("Output directory missing.");
|
DicConsole.WriteLine("Output directory missing.");
|
||||||
return (int)ErrorNumber.MissingArgument;
|
|
||||||
|
return(int)ErrorNumber.MissingArgument;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Directory.Exists(outputDir) || File.Exists(outputDir))
|
if(Directory.Exists(outputDir) ||
|
||||||
|
File.Exists(outputDir))
|
||||||
{
|
{
|
||||||
DicConsole.ErrorWriteLine("Destination exists, aborting.");
|
DicConsole.ErrorWriteLine("Destination exists, aborting.");
|
||||||
return (int)ErrorNumber.DestinationExists;
|
|
||||||
|
return(int)ErrorNumber.DestinationExists;
|
||||||
}
|
}
|
||||||
|
|
||||||
Directory.CreateDirectory(outputDir);
|
Directory.CreateDirectory(outputDir);
|
||||||
@@ -183,14 +195,18 @@ namespace DiscImageChef.Commands
|
|||||||
{
|
{
|
||||||
DicConsole.WriteLine("Unable to open image format");
|
DicConsole.WriteLine("Unable to open image format");
|
||||||
DicConsole.WriteLine("No error given");
|
DicConsole.WriteLine("No error given");
|
||||||
return (int)ErrorNumber.CannotOpenFormat;
|
|
||||||
|
return(int)ErrorNumber.CannotOpenFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
DicConsole.DebugWriteLine("Extract-Files command", "Correctly opened image file.");
|
DicConsole.DebugWriteLine("Extract-Files command", "Correctly opened image file.");
|
||||||
|
|
||||||
DicConsole.DebugWriteLine("Extract-Files command", "Image without headers is {0} bytes.",
|
DicConsole.DebugWriteLine("Extract-Files command", "Image without headers is {0} bytes.",
|
||||||
imageFormat.Info.ImageSize);
|
imageFormat.Info.ImageSize);
|
||||||
|
|
||||||
DicConsole.DebugWriteLine("Extract-Files command", "Image has {0} sectors.",
|
DicConsole.DebugWriteLine("Extract-Files command", "Image has {0} sectors.",
|
||||||
imageFormat.Info.Sectors);
|
imageFormat.Info.Sectors);
|
||||||
|
|
||||||
DicConsole.DebugWriteLine("Extract-Files command", "Image identifies disk type as {0}.",
|
DicConsole.DebugWriteLine("Extract-Files command", "Image identifies disk type as {0}.",
|
||||||
imageFormat.Info.MediaType);
|
imageFormat.Info.MediaType);
|
||||||
|
|
||||||
@@ -202,7 +218,8 @@ namespace DiscImageChef.Commands
|
|||||||
{
|
{
|
||||||
DicConsole.ErrorWriteLine("Unable to open image format");
|
DicConsole.ErrorWriteLine("Unable to open image format");
|
||||||
DicConsole.ErrorWriteLine("Error: {0}", ex.Message);
|
DicConsole.ErrorWriteLine("Error: {0}", ex.Message);
|
||||||
return (int)ErrorNumber.CannotOpenFormat;
|
|
||||||
|
return(int)ErrorNumber.CannotOpenFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Partition> partitions = Core.Partitions.GetAll(imageFormat);
|
List<Partition> partitions = Core.Partitions.GetAll(imageFormat);
|
||||||
@@ -211,7 +228,9 @@ namespace DiscImageChef.Commands
|
|||||||
List<string> idPlugins;
|
List<string> idPlugins;
|
||||||
IReadOnlyFilesystem plugin;
|
IReadOnlyFilesystem plugin;
|
||||||
Errno error;
|
Errno error;
|
||||||
if(partitions.Count == 0) DicConsole.DebugWriteLine("Extract-Files command", "No partitions found");
|
|
||||||
|
if(partitions.Count == 0)
|
||||||
|
DicConsole.DebugWriteLine("Extract-Files command", "No partitions found");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DicConsole.WriteLine("{0} partitions found.", partitions.Count);
|
DicConsole.WriteLine("{0} partitions found.", partitions.Count);
|
||||||
@@ -224,7 +243,9 @@ namespace DiscImageChef.Commands
|
|||||||
DicConsole.WriteLine("Identifying filesystem on partition");
|
DicConsole.WriteLine("Identifying filesystem on partition");
|
||||||
|
|
||||||
Core.Filesystems.Identify(imageFormat, out idPlugins, partitions[i]);
|
Core.Filesystems.Identify(imageFormat, out idPlugins, partitions[i]);
|
||||||
if(idPlugins.Count == 0) DicConsole.WriteLine("Filesystem not identified");
|
|
||||||
|
if(idPlugins.Count == 0)
|
||||||
|
DicConsole.WriteLine("Filesystem not identified");
|
||||||
else if(idPlugins.Count > 1)
|
else if(idPlugins.Count > 1)
|
||||||
{
|
{
|
||||||
DicConsole.WriteLine($"Identified by {idPlugins.Count} plugins");
|
DicConsole.WriteLine($"Identified by {idPlugins.Count} plugins");
|
||||||
@@ -233,20 +254,22 @@ namespace DiscImageChef.Commands
|
|||||||
if(plugins.ReadOnlyFilesystems.TryGetValue(pluginName, out plugin))
|
if(plugins.ReadOnlyFilesystems.TryGetValue(pluginName, out plugin))
|
||||||
{
|
{
|
||||||
DicConsole.WriteLine($"As identified by {plugin.Name}.");
|
DicConsole.WriteLine($"As identified by {plugin.Name}.");
|
||||||
IReadOnlyFilesystem fs = (IReadOnlyFilesystem)plugin
|
|
||||||
.GetType()
|
|
||||||
.GetConstructor(Type.EmptyTypes)
|
|
||||||
?.Invoke(new object[] { });
|
|
||||||
|
|
||||||
error = fs.Mount(imageFormat, partitions[i], encoding, parsedOptions, @namespace);
|
var fs = (IReadOnlyFilesystem)plugin.
|
||||||
|
GetType().GetConstructor(Type.EmptyTypes)?.
|
||||||
|
Invoke(new object[]
|
||||||
|
{ });
|
||||||
|
|
||||||
|
error = fs.Mount(imageFormat, partitions[i], encodingClass, parsedOptions,
|
||||||
|
@namespace);
|
||||||
|
|
||||||
if(error == Errno.NoError)
|
if(error == Errno.NoError)
|
||||||
{
|
{
|
||||||
string volumeName =
|
string volumeName =
|
||||||
string.IsNullOrEmpty(fs.XmlFsType.VolumeName)
|
string.IsNullOrEmpty(fs.XmlFsType.VolumeName) ? "NO NAME"
|
||||||
? "NO NAME"
|
|
||||||
: fs.XmlFsType.VolumeName;
|
: fs.XmlFsType.VolumeName;
|
||||||
|
|
||||||
ExtractFilesInDir("/", fs, volumeName);
|
ExtractFilesInDir("/", fs, volumeName, outputDir, xattrs);
|
||||||
|
|
||||||
Statistics.AddFilesystem(fs.XmlFsType.Type);
|
Statistics.AddFilesystem(fs.XmlFsType.Type);
|
||||||
}
|
}
|
||||||
@@ -259,34 +282,38 @@ namespace DiscImageChef.Commands
|
|||||||
{
|
{
|
||||||
plugins.ReadOnlyFilesystems.TryGetValue(idPlugins[0], out plugin);
|
plugins.ReadOnlyFilesystems.TryGetValue(idPlugins[0], out plugin);
|
||||||
DicConsole.WriteLine($"Identified by {plugin.Name}.");
|
DicConsole.WriteLine($"Identified by {plugin.Name}.");
|
||||||
IReadOnlyFilesystem fs = (IReadOnlyFilesystem)plugin
|
|
||||||
.GetType().GetConstructor(Type.EmptyTypes)
|
var fs = (IReadOnlyFilesystem)plugin.
|
||||||
?.Invoke(new object[] { });
|
GetType().GetConstructor(Type.EmptyTypes)?.Invoke(new object[]
|
||||||
error = fs.Mount(imageFormat, partitions[i], encoding, parsedOptions, @namespace);
|
{ });
|
||||||
|
|
||||||
|
error = fs.Mount(imageFormat, partitions[i], encodingClass, parsedOptions, @namespace);
|
||||||
|
|
||||||
if(error == Errno.NoError)
|
if(error == Errno.NoError)
|
||||||
{
|
{
|
||||||
string volumeName = string.IsNullOrEmpty(fs.XmlFsType.VolumeName)
|
string volumeName = string.IsNullOrEmpty(fs.XmlFsType.VolumeName) ? "NO NAME"
|
||||||
? "NO NAME"
|
|
||||||
: fs.XmlFsType.VolumeName;
|
: fs.XmlFsType.VolumeName;
|
||||||
|
|
||||||
ExtractFilesInDir("/", fs, volumeName);
|
ExtractFilesInDir("/", fs, volumeName, outputDir, xattrs);
|
||||||
|
|
||||||
Statistics.AddFilesystem(fs.XmlFsType.Type);
|
Statistics.AddFilesystem(fs.XmlFsType.Type);
|
||||||
}
|
}
|
||||||
else DicConsole.ErrorWriteLine("Unable to mount device, error {0}", error.ToString());
|
else
|
||||||
|
DicConsole.ErrorWriteLine("Unable to mount device, error {0}", error.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Partition wholePart = new Partition
|
var wholePart = new Partition
|
||||||
{
|
{
|
||||||
Name = "Whole device",
|
Name = "Whole device", Length = imageFormat.Info.Sectors,
|
||||||
Length = imageFormat.Info.Sectors,
|
|
||||||
Size = imageFormat.Info.Sectors * imageFormat.Info.SectorSize
|
Size = imageFormat.Info.Sectors * imageFormat.Info.SectorSize
|
||||||
};
|
};
|
||||||
|
|
||||||
Core.Filesystems.Identify(imageFormat, out idPlugins, wholePart);
|
Core.Filesystems.Identify(imageFormat, out idPlugins, wholePart);
|
||||||
if(idPlugins.Count == 0) DicConsole.WriteLine("Filesystem not identified");
|
|
||||||
|
if(idPlugins.Count == 0)
|
||||||
|
DicConsole.WriteLine("Filesystem not identified");
|
||||||
else if(idPlugins.Count > 1)
|
else if(idPlugins.Count > 1)
|
||||||
{
|
{
|
||||||
DicConsole.WriteLine($"Identified by {idPlugins.Count} plugins");
|
DicConsole.WriteLine($"Identified by {idPlugins.Count} plugins");
|
||||||
@@ -295,67 +322,79 @@ namespace DiscImageChef.Commands
|
|||||||
if(plugins.ReadOnlyFilesystems.TryGetValue(pluginName, out plugin))
|
if(plugins.ReadOnlyFilesystems.TryGetValue(pluginName, out plugin))
|
||||||
{
|
{
|
||||||
DicConsole.WriteLine($"As identified by {plugin.Name}.");
|
DicConsole.WriteLine($"As identified by {plugin.Name}.");
|
||||||
IReadOnlyFilesystem fs = (IReadOnlyFilesystem)plugin
|
|
||||||
.GetType().GetConstructor(Type.EmptyTypes)
|
var fs = (IReadOnlyFilesystem)plugin.
|
||||||
?.Invoke(new object[] { });
|
GetType().GetConstructor(Type.EmptyTypes)?.Invoke(new object[]
|
||||||
error = fs.Mount(imageFormat, wholePart, encoding, parsedOptions, @namespace);
|
{ });
|
||||||
|
|
||||||
|
error = fs.Mount(imageFormat, wholePart, encodingClass, parsedOptions, @namespace);
|
||||||
|
|
||||||
if(error == Errno.NoError)
|
if(error == Errno.NoError)
|
||||||
{
|
{
|
||||||
string volumeName = string.IsNullOrEmpty(fs.XmlFsType.VolumeName)
|
string volumeName = string.IsNullOrEmpty(fs.XmlFsType.VolumeName) ? "NO NAME"
|
||||||
? "NO NAME"
|
|
||||||
: fs.XmlFsType.VolumeName;
|
: fs.XmlFsType.VolumeName;
|
||||||
|
|
||||||
ExtractFilesInDir("/", fs, volumeName);
|
ExtractFilesInDir("/", fs, volumeName, outputDir, xattrs);
|
||||||
|
|
||||||
Statistics.AddFilesystem(fs.XmlFsType.Type);
|
Statistics.AddFilesystem(fs.XmlFsType.Type);
|
||||||
}
|
}
|
||||||
else DicConsole.ErrorWriteLine("Unable to mount device, error {0}", error.ToString());
|
else
|
||||||
|
DicConsole.ErrorWriteLine("Unable to mount device, error {0}", error.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
plugins.ReadOnlyFilesystems.TryGetValue(idPlugins[0], out plugin);
|
plugins.ReadOnlyFilesystems.TryGetValue(idPlugins[0], out plugin);
|
||||||
DicConsole.WriteLine($"Identified by {plugin.Name}.");
|
DicConsole.WriteLine($"Identified by {plugin.Name}.");
|
||||||
IReadOnlyFilesystem fs =
|
|
||||||
(IReadOnlyFilesystem)plugin.GetType().GetConstructor(Type.EmptyTypes)?.Invoke(new object[] { });
|
var fs = (IReadOnlyFilesystem)plugin.GetType().GetConstructor(Type.EmptyTypes)?.Invoke(new object[]
|
||||||
error = fs.Mount(imageFormat, wholePart, encoding, parsedOptions, @namespace);
|
{ });
|
||||||
|
|
||||||
|
error = fs.Mount(imageFormat, wholePart, encodingClass, parsedOptions, @namespace);
|
||||||
|
|
||||||
if(error == Errno.NoError)
|
if(error == Errno.NoError)
|
||||||
{
|
{
|
||||||
string volumeName = string.IsNullOrEmpty(fs.XmlFsType.VolumeName)
|
string volumeName = string.IsNullOrEmpty(fs.XmlFsType.VolumeName) ? "NO NAME"
|
||||||
? "NO NAME"
|
|
||||||
: fs.XmlFsType.VolumeName;
|
: fs.XmlFsType.VolumeName;
|
||||||
|
|
||||||
ExtractFilesInDir("/", fs, volumeName);
|
ExtractFilesInDir("/", fs, volumeName, outputDir, xattrs);
|
||||||
|
|
||||||
Statistics.AddFilesystem(fs.XmlFsType.Type);
|
Statistics.AddFilesystem(fs.XmlFsType.Type);
|
||||||
}
|
}
|
||||||
else DicConsole.ErrorWriteLine("Unable to mount device, error {0}", error.ToString());
|
else
|
||||||
|
DicConsole.ErrorWriteLine("Unable to mount device, error {0}", error.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch(Exception ex)
|
catch(Exception ex)
|
||||||
{
|
{
|
||||||
DicConsole.ErrorWriteLine($"Error reading file: {ex.Message}");
|
DicConsole.ErrorWriteLine($"Error reading file: {ex.Message}");
|
||||||
DicConsole.DebugWriteLine("Extract-Files command", ex.StackTrace);
|
DicConsole.DebugWriteLine("Extract-Files command", ex.StackTrace);
|
||||||
return (int)ErrorNumber.UnexpectedException;
|
|
||||||
|
return(int)ErrorNumber.UnexpectedException;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (int)ErrorNumber.NoError;
|
return(int)ErrorNumber.NoError;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExtractFilesInDir(string path, IReadOnlyFilesystem fs, string volumeName)
|
static void ExtractFilesInDir(string path, IReadOnlyFilesystem fs, string volumeName, string outputDir,
|
||||||
|
bool doXattrs)
|
||||||
{
|
{
|
||||||
if(path.StartsWith("/")) path = path.Substring(1);
|
if(path.StartsWith("/"))
|
||||||
|
path = path.Substring(1);
|
||||||
|
|
||||||
Errno error = fs.ReadDir(path, out List<string> directory);
|
Errno error = fs.ReadDir(path, out List<string> directory);
|
||||||
|
|
||||||
if(error != Errno.NoError)
|
if(error != Errno.NoError)
|
||||||
{
|
{
|
||||||
DicConsole.ErrorWriteLine("Error {0} reading root directory {0}", error.ToString());
|
DicConsole.ErrorWriteLine("Error {0} reading root directory {0}", error.ToString());
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach(string entry in directory)
|
foreach(string entry in directory)
|
||||||
{
|
{
|
||||||
error = fs.Stat(path + "/" + entry, out FileEntryInfo stat);
|
error = fs.Stat(path + "/" + entry, out FileEntryInfo stat);
|
||||||
|
|
||||||
if(error == Errno.NoError)
|
if(error == Errno.NoError)
|
||||||
{
|
{
|
||||||
string outputPath;
|
string outputPath;
|
||||||
@@ -370,14 +409,15 @@ namespace DiscImageChef.Commands
|
|||||||
|
|
||||||
DicConsole.WriteLine("Created subdirectory at {0}", outputPath);
|
DicConsole.WriteLine("Created subdirectory at {0}", outputPath);
|
||||||
|
|
||||||
ExtractFilesInDir(path + "/" + entry, fs, volumeName);
|
ExtractFilesInDir(path + "/" + entry, fs, volumeName, outputDir, doXattrs);
|
||||||
|
|
||||||
DirectoryInfo di = new DirectoryInfo(outputPath);
|
var di = new DirectoryInfo(outputPath);
|
||||||
|
|
||||||
#pragma warning disable RECS0022 // A catch clause that catches System.Exception and has an empty body
|
#pragma warning disable RECS0022 // A catch clause that catches System.Exception and has an empty body
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if(stat.CreationTimeUtc.HasValue) di.CreationTimeUtc = stat.CreationTimeUtc.Value;
|
if(stat.CreationTimeUtc.HasValue)
|
||||||
|
di.CreationTimeUtc = stat.CreationTimeUtc.Value;
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
@@ -386,7 +426,8 @@ namespace DiscImageChef.Commands
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if(stat.LastWriteTimeUtc.HasValue) di.LastWriteTimeUtc = stat.LastWriteTimeUtc.Value;
|
if(stat.LastWriteTimeUtc.HasValue)
|
||||||
|
di.LastWriteTimeUtc = stat.LastWriteTimeUtc.Value;
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
@@ -395,7 +436,8 @@ namespace DiscImageChef.Commands
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if(stat.AccessTimeUtc.HasValue) di.LastAccessTimeUtc = stat.AccessTimeUtc.Value;
|
if(stat.AccessTimeUtc.HasValue)
|
||||||
|
di.LastAccessTimeUtc = stat.AccessTimeUtc.Value;
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
@@ -407,15 +449,19 @@ namespace DiscImageChef.Commands
|
|||||||
}
|
}
|
||||||
|
|
||||||
FileStream outputFile;
|
FileStream outputFile;
|
||||||
if(extractXattrs)
|
|
||||||
|
if(doXattrs)
|
||||||
{
|
{
|
||||||
error = fs.ListXAttr(path + "/" + entry, out List<string> xattrs);
|
error = fs.ListXAttr(path + "/" + entry, out List<string> xattrs);
|
||||||
|
|
||||||
if(error == Errno.NoError)
|
if(error == Errno.NoError)
|
||||||
foreach(string xattr in xattrs)
|
foreach(string xattr in xattrs)
|
||||||
{
|
{
|
||||||
byte[] xattrBuf = new byte[0];
|
byte[] xattrBuf = new byte[0];
|
||||||
error = fs.GetXattr(path + "/" + entry, xattr, ref xattrBuf);
|
error = fs.GetXattr(path + "/" + entry, xattr, ref xattrBuf);
|
||||||
if(error != Errno.NoError) continue;
|
|
||||||
|
if(error != Errno.NoError)
|
||||||
|
continue;
|
||||||
|
|
||||||
Directory.CreateDirectory(Path.Combine(outputDir, fs.XmlFsType.Type, volumeName,
|
Directory.CreateDirectory(Path.Combine(outputDir, fs.XmlFsType.Type, volumeName,
|
||||||
".xattrs", xattr));
|
".xattrs", xattr));
|
||||||
@@ -427,9 +473,10 @@ namespace DiscImageChef.Commands
|
|||||||
{
|
{
|
||||||
outputFile = new FileStream(outputPath, FileMode.CreateNew, FileAccess.ReadWrite,
|
outputFile = new FileStream(outputPath, FileMode.CreateNew, FileAccess.ReadWrite,
|
||||||
FileShare.None);
|
FileShare.None);
|
||||||
|
|
||||||
outputFile.Write(xattrBuf, 0, xattrBuf.Length);
|
outputFile.Write(xattrBuf, 0, xattrBuf.Length);
|
||||||
outputFile.Close();
|
outputFile.Close();
|
||||||
FileInfo fi = new FileInfo(outputPath);
|
var fi = new FileInfo(outputPath);
|
||||||
#pragma warning disable RECS0022 // A catch clause that catches System.Exception and has an empty body
|
#pragma warning disable RECS0022 // A catch clause that catches System.Exception and has an empty body
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -453,7 +500,8 @@ namespace DiscImageChef.Commands
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if(stat.AccessTimeUtc.HasValue) fi.LastAccessTimeUtc = stat.AccessTimeUtc.Value;
|
if(stat.AccessTimeUtc.HasValue)
|
||||||
|
fi.LastAccessTimeUtc = stat.AccessTimeUtc.Value;
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
@@ -483,13 +531,15 @@ namespace DiscImageChef.Commands
|
|||||||
{
|
{
|
||||||
outputFile = new FileStream(outputPath, FileMode.CreateNew, FileAccess.ReadWrite,
|
outputFile = new FileStream(outputPath, FileMode.CreateNew, FileAccess.ReadWrite,
|
||||||
FileShare.None);
|
FileShare.None);
|
||||||
|
|
||||||
outputFile.Write(outBuf, 0, outBuf.Length);
|
outputFile.Write(outBuf, 0, outBuf.Length);
|
||||||
outputFile.Close();
|
outputFile.Close();
|
||||||
FileInfo fi = new FileInfo(outputPath);
|
var fi = new FileInfo(outputPath);
|
||||||
#pragma warning disable RECS0022 // A catch clause that catches System.Exception and has an empty body
|
#pragma warning disable RECS0022 // A catch clause that catches System.Exception and has an empty body
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if(stat.CreationTimeUtc.HasValue) fi.CreationTimeUtc = stat.CreationTimeUtc.Value;
|
if(stat.CreationTimeUtc.HasValue)
|
||||||
|
fi.CreationTimeUtc = stat.CreationTimeUtc.Value;
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
@@ -498,7 +548,8 @@ namespace DiscImageChef.Commands
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if(stat.LastWriteTimeUtc.HasValue) fi.LastWriteTimeUtc = stat.LastWriteTimeUtc.Value;
|
if(stat.LastWriteTimeUtc.HasValue)
|
||||||
|
fi.LastWriteTimeUtc = stat.LastWriteTimeUtc.Value;
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
@@ -507,7 +558,8 @@ namespace DiscImageChef.Commands
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if(stat.AccessTimeUtc.HasValue) fi.LastAccessTimeUtc = stat.AccessTimeUtc.Value;
|
if(stat.AccessTimeUtc.HasValue)
|
||||||
|
fi.LastAccessTimeUtc = stat.AccessTimeUtc.Value;
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
@@ -517,11 +569,14 @@ namespace DiscImageChef.Commands
|
|||||||
DicConsole.WriteLine("Written {0} bytes of file {1} to {2}", outBuf.Length, entry,
|
DicConsole.WriteLine("Written {0} bytes of file {1} to {2}", outBuf.Length, entry,
|
||||||
outputPath);
|
outputPath);
|
||||||
}
|
}
|
||||||
else DicConsole.ErrorWriteLine("Error {0} reading file {1}", error, entry);
|
else
|
||||||
|
DicConsole.ErrorWriteLine("Error {0} reading file {1}", error, entry);
|
||||||
}
|
}
|
||||||
else DicConsole.ErrorWriteLine("Cannot write file {0}, output exists", entry);
|
else
|
||||||
|
DicConsole.ErrorWriteLine("Cannot write file {0}, output exists", entry);
|
||||||
}
|
}
|
||||||
else DicConsole.ErrorWriteLine("Error reading file {0}", entry);
|
else
|
||||||
|
DicConsole.ErrorWriteLine("Error reading file {0}", entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,6 +31,8 @@
|
|||||||
// ****************************************************************************/
|
// ****************************************************************************/
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.CommandLine;
|
||||||
|
using System.CommandLine.Invocation;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using DiscImageChef.CommonTypes;
|
using DiscImageChef.CommonTypes;
|
||||||
using DiscImageChef.CommonTypes.Enums;
|
using DiscImageChef.CommonTypes.Enums;
|
||||||
@@ -38,123 +40,121 @@ using DiscImageChef.CommonTypes.Interfaces;
|
|||||||
using DiscImageChef.Console;
|
using DiscImageChef.Console;
|
||||||
using DiscImageChef.Core;
|
using DiscImageChef.Core;
|
||||||
using DiscImageChef.Partitions;
|
using DiscImageChef.Partitions;
|
||||||
using Mono.Options;
|
|
||||||
|
|
||||||
namespace DiscImageChef.Commands
|
namespace DiscImageChef.Commands
|
||||||
{
|
{
|
||||||
class FormatsCommand : Command
|
internal class FormatsCommand : Command
|
||||||
{
|
{
|
||||||
bool showHelp;
|
|
||||||
|
|
||||||
public FormatsCommand() : base("formats",
|
public FormatsCommand() : base("formats",
|
||||||
"Lists all supported disc images, partition schemes and file systems.")
|
"Lists all supported disc images, partition schemes and file systems.") =>
|
||||||
{
|
Handler = CommandHandler.Create(GetType().GetMethod(nameof(Invoke)));
|
||||||
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)
|
static int Invoke(bool verbose, bool debug)
|
||||||
{
|
{
|
||||||
List<string> extra = Options.Parse(arguments);
|
|
||||||
|
|
||||||
if(showHelp)
|
|
||||||
{
|
|
||||||
Options.WriteOptionDescriptions(CommandSet.Out);
|
|
||||||
return (int)ErrorNumber.HelpRequested;
|
|
||||||
}
|
|
||||||
|
|
||||||
MainClass.PrintCopyright();
|
MainClass.PrintCopyright();
|
||||||
if(MainClass.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
|
||||||
if(MainClass.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
if(debug)
|
||||||
|
DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
||||||
|
|
||||||
|
if(verbose)
|
||||||
|
DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
||||||
|
|
||||||
Statistics.AddCommand("formats");
|
Statistics.AddCommand("formats");
|
||||||
|
|
||||||
if(extra.Count > 0)
|
DicConsole.DebugWriteLine("Formats command", "--debug={0}", debug);
|
||||||
{
|
DicConsole.DebugWriteLine("Formats command", "--verbose={0}", verbose);
|
||||||
DicConsole.ErrorWriteLine("Too many arguments.");
|
|
||||||
return (int)ErrorNumber.UnexpectedArgumentCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
DicConsole.DebugWriteLine("Formats command", "--debug={0}", MainClass.Debug);
|
|
||||||
DicConsole.DebugWriteLine("Formats command", "--verbose={0}", MainClass.Verbose);
|
|
||||||
|
|
||||||
PluginBase plugins = GetPluginBase.Instance;
|
PluginBase plugins = GetPluginBase.Instance;
|
||||||
FiltersList filtersList = new FiltersList();
|
var filtersList = new FiltersList();
|
||||||
|
|
||||||
DicConsole.WriteLine("Supported filters ({0}):", filtersList.Filters.Count);
|
DicConsole.WriteLine("Supported filters ({0}):", filtersList.Filters.Count);
|
||||||
if(MainClass.Verbose) DicConsole.VerboseWriteLine("GUID\t\t\t\t\tFilter");
|
|
||||||
|
if(verbose)
|
||||||
|
DicConsole.VerboseWriteLine("GUID\t\t\t\t\tFilter");
|
||||||
|
|
||||||
foreach(KeyValuePair<string, IFilter> kvp in filtersList.Filters)
|
foreach(KeyValuePair<string, IFilter> kvp in filtersList.Filters)
|
||||||
if(MainClass.Verbose)
|
if(verbose)
|
||||||
DicConsole.VerboseWriteLine("{0}\t{1}", kvp.Value.Id, kvp.Value.Name);
|
DicConsole.VerboseWriteLine("{0}\t{1}", kvp.Value.Id, kvp.Value.Name);
|
||||||
else
|
else
|
||||||
DicConsole.WriteLine(kvp.Value.Name);
|
DicConsole.WriteLine(kvp.Value.Name);
|
||||||
|
|
||||||
DicConsole.WriteLine();
|
DicConsole.WriteLine();
|
||||||
|
|
||||||
DicConsole.WriteLine("Read-only media image formats ({0}):",
|
DicConsole.WriteLine("Read-only media image formats ({0}):",
|
||||||
plugins.ImagePluginsList.Count(t => !t.Value.GetType().GetInterfaces()
|
plugins.ImagePluginsList.Count(t => !t.Value.GetType().GetInterfaces().
|
||||||
.Contains(typeof(IWritableImage))));
|
Contains(typeof(IWritableImage))));
|
||||||
if(MainClass.Verbose) DicConsole.VerboseWriteLine("GUID\t\t\t\t\tPlugin");
|
|
||||||
foreach(KeyValuePair<string, IMediaImage> kvp in plugins.ImagePluginsList.Where(t => !t.Value.GetType()
|
if(verbose)
|
||||||
.GetInterfaces()
|
DicConsole.VerboseWriteLine("GUID\t\t\t\t\tPlugin");
|
||||||
.Contains(typeof(
|
|
||||||
|
foreach(KeyValuePair<string, IMediaImage> kvp in plugins.ImagePluginsList.Where(t => !t.Value.GetType().
|
||||||
|
GetInterfaces().
|
||||||
|
Contains(typeof(
|
||||||
IWritableImage
|
IWritableImage
|
||||||
))))
|
))))
|
||||||
if(MainClass.Verbose)
|
if(verbose)
|
||||||
DicConsole.VerboseWriteLine("{0}\t{1}", kvp.Value.Id, kvp.Value.Name);
|
DicConsole.VerboseWriteLine("{0}\t{1}", kvp.Value.Id, kvp.Value.Name);
|
||||||
else
|
else
|
||||||
DicConsole.WriteLine(kvp.Value.Name);
|
DicConsole.WriteLine(kvp.Value.Name);
|
||||||
|
|
||||||
DicConsole.WriteLine();
|
DicConsole.WriteLine();
|
||||||
DicConsole.WriteLine("Read/write media image formats ({0}):", plugins.WritableImages.Count);
|
DicConsole.WriteLine("Read/write media image formats ({0}):", plugins.WritableImages.Count);
|
||||||
if(MainClass.Verbose) DicConsole.VerboseWriteLine("GUID\t\t\t\t\tPlugin");
|
|
||||||
|
if(verbose)
|
||||||
|
DicConsole.VerboseWriteLine("GUID\t\t\t\t\tPlugin");
|
||||||
|
|
||||||
foreach(KeyValuePair<string, IWritableImage> kvp in plugins.WritableImages)
|
foreach(KeyValuePair<string, IWritableImage> kvp in plugins.WritableImages)
|
||||||
if(MainClass.Verbose)
|
if(verbose)
|
||||||
DicConsole.VerboseWriteLine("{0}\t{1}", kvp.Value.Id, kvp.Value.Name);
|
DicConsole.VerboseWriteLine("{0}\t{1}", kvp.Value.Id, kvp.Value.Name);
|
||||||
else
|
else
|
||||||
DicConsole.WriteLine(kvp.Value.Name);
|
DicConsole.WriteLine(kvp.Value.Name);
|
||||||
|
|
||||||
DicConsole.WriteLine();
|
DicConsole.WriteLine();
|
||||||
|
|
||||||
DicConsole.WriteLine("Supported filesystems for identification and information only ({0}):",
|
DicConsole.WriteLine("Supported filesystems for identification and information only ({0}):",
|
||||||
plugins.PluginsList.Count(t => !t.Value.GetType().GetInterfaces()
|
plugins.PluginsList.Count(t => !t.Value.GetType().GetInterfaces().
|
||||||
.Contains(typeof(IReadOnlyFilesystem))));
|
Contains(typeof(IReadOnlyFilesystem))));
|
||||||
if(MainClass.Verbose) DicConsole.VerboseWriteLine("GUID\t\t\t\t\tPlugin");
|
|
||||||
foreach(KeyValuePair<string, IFilesystem> kvp in plugins.PluginsList.Where(t => !t.Value.GetType()
|
if(verbose)
|
||||||
.GetInterfaces()
|
DicConsole.VerboseWriteLine("GUID\t\t\t\t\tPlugin");
|
||||||
.Contains(typeof(
|
|
||||||
|
foreach(KeyValuePair<string, IFilesystem> kvp in plugins.PluginsList.Where(t => !t.Value.GetType().
|
||||||
|
GetInterfaces().
|
||||||
|
Contains(typeof(
|
||||||
IReadOnlyFilesystem
|
IReadOnlyFilesystem
|
||||||
))))
|
))))
|
||||||
if(MainClass.Verbose)
|
if(verbose)
|
||||||
DicConsole.VerboseWriteLine("{0}\t{1}", kvp.Value.Id, kvp.Value.Name);
|
DicConsole.VerboseWriteLine("{0}\t{1}", kvp.Value.Id, kvp.Value.Name);
|
||||||
else
|
else
|
||||||
DicConsole.WriteLine(kvp.Value.Name);
|
DicConsole.WriteLine(kvp.Value.Name);
|
||||||
|
|
||||||
DicConsole.WriteLine();
|
DicConsole.WriteLine();
|
||||||
|
|
||||||
DicConsole.WriteLine("Supported filesystems that can read their contents ({0}):",
|
DicConsole.WriteLine("Supported filesystems that can read their contents ({0}):",
|
||||||
plugins.ReadOnlyFilesystems.Count);
|
plugins.ReadOnlyFilesystems.Count);
|
||||||
if(MainClass.Verbose) DicConsole.VerboseWriteLine("GUID\t\t\t\t\tPlugin");
|
|
||||||
|
if(verbose)
|
||||||
|
DicConsole.VerboseWriteLine("GUID\t\t\t\t\tPlugin");
|
||||||
|
|
||||||
foreach(KeyValuePair<string, IReadOnlyFilesystem> kvp in plugins.ReadOnlyFilesystems)
|
foreach(KeyValuePair<string, IReadOnlyFilesystem> kvp in plugins.ReadOnlyFilesystems)
|
||||||
if(MainClass.Verbose)
|
if(verbose)
|
||||||
DicConsole.VerboseWriteLine("{0}\t{1}", kvp.Value.Id, kvp.Value.Name);
|
DicConsole.VerboseWriteLine("{0}\t{1}", kvp.Value.Id, kvp.Value.Name);
|
||||||
else
|
else
|
||||||
DicConsole.WriteLine(kvp.Value.Name);
|
DicConsole.WriteLine(kvp.Value.Name);
|
||||||
|
|
||||||
DicConsole.WriteLine();
|
DicConsole.WriteLine();
|
||||||
DicConsole.WriteLine("Supported partitioning schemes ({0}):", plugins.PartPluginsList.Count);
|
DicConsole.WriteLine("Supported partitioning schemes ({0}):", plugins.PartPluginsList.Count);
|
||||||
if(MainClass.Verbose) DicConsole.VerboseWriteLine("GUID\t\t\t\t\tPlugin");
|
|
||||||
|
if(verbose)
|
||||||
|
DicConsole.VerboseWriteLine("GUID\t\t\t\t\tPlugin");
|
||||||
|
|
||||||
foreach(KeyValuePair<string, IPartition> kvp in plugins.PartPluginsList)
|
foreach(KeyValuePair<string, IPartition> kvp in plugins.PartPluginsList)
|
||||||
if(MainClass.Verbose)
|
if(verbose)
|
||||||
DicConsole.VerboseWriteLine("{0}\t{1}", kvp.Value.Id, kvp.Value.Name);
|
DicConsole.VerboseWriteLine("{0}\t{1}", kvp.Value.Id, kvp.Value.Name);
|
||||||
else
|
else
|
||||||
DicConsole.WriteLine(kvp.Value.Name);
|
DicConsole.WriteLine(kvp.Value.Name);
|
||||||
|
|
||||||
return (int)ErrorNumber.NoError;
|
return(int)ErrorNumber.NoError;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -31,77 +31,53 @@
|
|||||||
// ****************************************************************************/
|
// ****************************************************************************/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.CommandLine;
|
||||||
|
using System.CommandLine.Invocation;
|
||||||
using DiscImageChef.CommonTypes;
|
using DiscImageChef.CommonTypes;
|
||||||
using DiscImageChef.CommonTypes.Enums;
|
using DiscImageChef.CommonTypes.Enums;
|
||||||
using DiscImageChef.CommonTypes.Interfaces;
|
using DiscImageChef.CommonTypes.Interfaces;
|
||||||
using DiscImageChef.Console;
|
using DiscImageChef.Console;
|
||||||
using DiscImageChef.Core;
|
using DiscImageChef.Core;
|
||||||
using Mono.Options;
|
|
||||||
|
|
||||||
namespace DiscImageChef.Commands
|
namespace DiscImageChef.Commands
|
||||||
{
|
{
|
||||||
class ImageInfoCommand : Command
|
internal class ImageInfoCommand : Command
|
||||||
{
|
{
|
||||||
string inputFile;
|
|
||||||
|
|
||||||
bool showHelp;
|
|
||||||
|
|
||||||
public ImageInfoCommand() : base("image-info",
|
public ImageInfoCommand() : base("image-info",
|
||||||
"Opens a media image and shows information about the media it represents and metadata.")
|
"Opens a media image and shows information about the media it represents and metadata.")
|
||||||
{
|
{
|
||||||
Options = new OptionSet
|
AddArgument(new Argument<string>
|
||||||
{
|
{
|
||||||
$"{MainClass.AssemblyTitle} {MainClass.AssemblyVersion?.InformationalVersion}",
|
Arity = ArgumentArity.ExactlyOne, Description = "Media image path", Name = "image-path"
|
||||||
$"{MainClass.AssemblyCopyright}",
|
});
|
||||||
"",
|
|
||||||
$"usage: DiscImageChef {Name} imagefile",
|
Handler = CommandHandler.Create(GetType().GetMethod(nameof(Invoke)));
|
||||||
"",
|
|
||||||
Help,
|
|
||||||
{"help|h|?", "Show this message and exit.", v => showHelp = v != null}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override int Invoke(IEnumerable<string> arguments)
|
static int Invoke(bool debug, bool verbose, string imagePath)
|
||||||
{
|
{
|
||||||
List<string> extra = Options.Parse(arguments);
|
|
||||||
|
|
||||||
if(showHelp)
|
|
||||||
{
|
|
||||||
Options.WriteOptionDescriptions(CommandSet.Out);
|
|
||||||
return (int)ErrorNumber.HelpRequested;
|
|
||||||
}
|
|
||||||
|
|
||||||
MainClass.PrintCopyright();
|
MainClass.PrintCopyright();
|
||||||
if(MainClass.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
|
||||||
if(MainClass.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
if(debug)
|
||||||
|
DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
||||||
|
|
||||||
|
if(verbose)
|
||||||
|
DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
||||||
|
|
||||||
Statistics.AddCommand("image-info");
|
Statistics.AddCommand("image-info");
|
||||||
|
|
||||||
if(extra.Count > 1)
|
DicConsole.DebugWriteLine("Analyze command", "--debug={0}", debug);
|
||||||
{
|
DicConsole.DebugWriteLine("Analyze command", "--input={0}", imagePath);
|
||||||
DicConsole.ErrorWriteLine("Too many arguments.");
|
DicConsole.DebugWriteLine("Analyze command", "--verbose={0}", verbose);
|
||||||
return (int)ErrorNumber.UnexpectedArgumentCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(extra.Count == 0)
|
var filtersList = new FiltersList();
|
||||||
{
|
IFilter inputFilter = filtersList.GetFilter(imagePath);
|
||||||
DicConsole.ErrorWriteLine("Missing input image.");
|
|
||||||
return (int)ErrorNumber.MissingArgument;
|
|
||||||
}
|
|
||||||
|
|
||||||
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(inputFile);
|
|
||||||
|
|
||||||
if(inputFilter == null)
|
if(inputFilter == null)
|
||||||
{
|
{
|
||||||
DicConsole.ErrorWriteLine("Cannot open specified file.");
|
DicConsole.ErrorWriteLine("Cannot open specified file.");
|
||||||
return (int)ErrorNumber.CannotOpenFile;
|
|
||||||
|
return(int)ErrorNumber.CannotOpenFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
@@ -111,7 +87,8 @@ namespace DiscImageChef.Commands
|
|||||||
if(imageFormat == null)
|
if(imageFormat == null)
|
||||||
{
|
{
|
||||||
DicConsole.WriteLine("Image format not identified.");
|
DicConsole.WriteLine("Image format not identified.");
|
||||||
return (int)ErrorNumber.UnrecognizedFormat;
|
|
||||||
|
return(int)ErrorNumber.UnrecognizedFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
DicConsole.WriteLine("Image format identified by {0} ({1}).", imageFormat.Name, imageFormat.Id);
|
DicConsole.WriteLine("Image format identified by {0} ({1}).", imageFormat.Name, imageFormat.Id);
|
||||||
@@ -123,7 +100,8 @@ namespace DiscImageChef.Commands
|
|||||||
{
|
{
|
||||||
DicConsole.WriteLine("Unable to open image format");
|
DicConsole.WriteLine("Unable to open image format");
|
||||||
DicConsole.WriteLine("No error given");
|
DicConsole.WriteLine("No error given");
|
||||||
return (int)ErrorNumber.CannotOpenFormat;
|
|
||||||
|
return(int)ErrorNumber.CannotOpenFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageInfo.PrintImageInfo(imageFormat);
|
ImageInfo.PrintImageInfo(imageFormat);
|
||||||
@@ -137,17 +115,19 @@ namespace DiscImageChef.Commands
|
|||||||
DicConsole.ErrorWriteLine("Unable to open image format");
|
DicConsole.ErrorWriteLine("Unable to open image format");
|
||||||
DicConsole.ErrorWriteLine("Error: {0}", ex.Message);
|
DicConsole.ErrorWriteLine("Error: {0}", ex.Message);
|
||||||
DicConsole.DebugWriteLine("Image-info command", "Stack trace: {0}", ex.StackTrace);
|
DicConsole.DebugWriteLine("Image-info command", "Stack trace: {0}", ex.StackTrace);
|
||||||
return (int)ErrorNumber.CannotOpenFormat;
|
|
||||||
|
return(int)ErrorNumber.CannotOpenFormat;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch(Exception ex)
|
catch(Exception ex)
|
||||||
{
|
{
|
||||||
DicConsole.ErrorWriteLine($"Error reading file: {ex.Message}");
|
DicConsole.ErrorWriteLine($"Error reading file: {ex.Message}");
|
||||||
DicConsole.DebugWriteLine("Image-info command", ex.StackTrace);
|
DicConsole.DebugWriteLine("Image-info command", ex.StackTrace);
|
||||||
return (int)ErrorNumber.UnexpectedException;
|
|
||||||
|
return(int)ErrorNumber.UnexpectedException;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (int)ErrorNumber.NoError;
|
return(int)ErrorNumber.NoError;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -30,70 +30,47 @@
|
|||||||
// Copyright © 2011-2019 Natalia Portillo
|
// Copyright © 2011-2019 Natalia Portillo
|
||||||
// ****************************************************************************/
|
// ****************************************************************************/
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.CommandLine;
|
||||||
|
using System.CommandLine.Invocation;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using DiscImageChef.CommonTypes.Enums;
|
using DiscImageChef.CommonTypes.Enums;
|
||||||
using DiscImageChef.Console;
|
using DiscImageChef.Console;
|
||||||
using DiscImageChef.Core;
|
using DiscImageChef.Core;
|
||||||
using DiscImageChef.Devices;
|
using DiscImageChef.Devices;
|
||||||
using Mono.Options;
|
|
||||||
|
|
||||||
namespace DiscImageChef.Commands
|
namespace DiscImageChef.Commands
|
||||||
{
|
{
|
||||||
internal class ListDevicesCommand : Command
|
internal class ListDevicesCommand : Command
|
||||||
{
|
{
|
||||||
bool showHelp;
|
public ListDevicesCommand() : base("list-devices", "Lists all connected devices.")
|
||||||
|
|
||||||
public ListDevicesCommand() : base("list-devices", "Lists all connected devices.") => Options = new OptionSet
|
|
||||||
{
|
{
|
||||||
$"{MainClass.AssemblyTitle} {MainClass.AssemblyVersion?.InformationalVersion}",
|
AddArgument(new Argument<string>
|
||||||
$"{MainClass.AssemblyCopyright}", "", $"usage: DiscImageChef {Name} [dic-remote-host]", "",
|
|
||||||
Help,
|
|
||||||
{
|
{
|
||||||
"help|h|?", "Show this message and exit.", v => showHelp = v != null
|
Arity = ArgumentArity.ZeroOrOne, Description = "dicremote host", Name = "dic-remote-host"
|
||||||
}
|
});
|
||||||
};
|
|
||||||
|
|
||||||
public override int Invoke(IEnumerable<string> arguments)
|
Handler = CommandHandler.Create(GetType().GetMethod(nameof(Invoke)));
|
||||||
{
|
|
||||||
List<string> extra = Options.Parse(arguments);
|
|
||||||
|
|
||||||
if(showHelp)
|
|
||||||
{
|
|
||||||
Options.WriteOptionDescriptions(CommandSet.Out);
|
|
||||||
|
|
||||||
return(int)ErrorNumber.HelpRequested;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int Invoke(bool debug, bool verbose, string dicRemoteHost)
|
||||||
|
{
|
||||||
MainClass.PrintCopyright();
|
MainClass.PrintCopyright();
|
||||||
|
|
||||||
if(MainClass.Debug)
|
if(debug)
|
||||||
DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
||||||
|
|
||||||
if(MainClass.Verbose)
|
if(verbose)
|
||||||
DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
||||||
|
|
||||||
Statistics.AddCommand("list-devices");
|
Statistics.AddCommand("list-devices");
|
||||||
|
|
||||||
string dicRemote = null;
|
DicConsole.DebugWriteLine("List-Devices command", "--debug={0}", debug);
|
||||||
|
DicConsole.DebugWriteLine("List-Devices command", "--verbose={0}", verbose);
|
||||||
if(extra.Count > 1)
|
|
||||||
{
|
|
||||||
DicConsole.ErrorWriteLine("Too many arguments.");
|
|
||||||
|
|
||||||
return(int)ErrorNumber.UnexpectedArgumentCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(extra.Count == 1)
|
|
||||||
dicRemote = extra[0];
|
|
||||||
|
|
||||||
DicConsole.DebugWriteLine("List-Devices command", "--debug={0}", MainClass.Debug);
|
|
||||||
DicConsole.DebugWriteLine("List-Devices command", "--verbose={0}", MainClass.Verbose);
|
|
||||||
|
|
||||||
DeviceInfo[] devices = Device.ListDevices(out bool isRemote, out string serverApplication,
|
DeviceInfo[] devices = Device.ListDevices(out bool isRemote, out string serverApplication,
|
||||||
out string serverVersion, out string serverOperatingSystem,
|
out string serverVersion, out string serverOperatingSystem,
|
||||||
out string serverOperatingSystemVersion,
|
out string serverOperatingSystemVersion,
|
||||||
out string serverArchitecture, dicRemote);
|
out string serverArchitecture, dicRemoteHost);
|
||||||
|
|
||||||
if(isRemote)
|
if(isRemote)
|
||||||
{
|
{
|
||||||
@@ -110,7 +87,7 @@ namespace DiscImageChef.Commands
|
|||||||
{
|
{
|
||||||
devices = devices.OrderBy(d => d.Path).ToArray();
|
devices = devices.OrderBy(d => d.Path).ToArray();
|
||||||
|
|
||||||
if(dicRemote is null)
|
if(dicRemoteHost is null)
|
||||||
{
|
{
|
||||||
DicConsole.WriteLine("{0,-22}|{1,-16}|{2,-24}|{3,-24}|{4,-10}|{5,-10}", "Path", "Vendor", "Model",
|
DicConsole.WriteLine("{0,-22}|{1,-16}|{2,-24}|{3,-24}|{4,-10}|{5,-10}", "Path", "Vendor", "Model",
|
||||||
"Serial", "Bus", "Supported?");
|
"Serial", "Bus", "Supported?");
|
||||||
|
|||||||
@@ -31,66 +31,42 @@
|
|||||||
// ****************************************************************************/
|
// ****************************************************************************/
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.CommandLine;
|
||||||
|
using System.CommandLine.Invocation;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using DiscImageChef.CommonTypes.Enums;
|
using DiscImageChef.CommonTypes.Enums;
|
||||||
using DiscImageChef.Console;
|
using DiscImageChef.Console;
|
||||||
using DiscImageChef.Core;
|
using DiscImageChef.Core;
|
||||||
using Mono.Options;
|
|
||||||
|
|
||||||
namespace DiscImageChef.Commands
|
namespace DiscImageChef.Commands
|
||||||
{
|
{
|
||||||
class ListEncodingsCommand : Command
|
internal class ListEncodingsCommand : Command
|
||||||
{
|
{
|
||||||
bool showHelp;
|
public ListEncodingsCommand() : base("list-encodings", "Lists all supported text encodings and code pages.") =>
|
||||||
|
Handler = CommandHandler.Create(GetType().GetMethod(nameof(Invoke)));
|
||||||
|
|
||||||
public ListEncodingsCommand() : base("list-encodings", "Lists all supported text encodings and code pages.")
|
static int Invoke(bool debug, bool verbose)
|
||||||
{
|
{
|
||||||
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 (int)ErrorNumber.HelpRequested;
|
|
||||||
}
|
|
||||||
|
|
||||||
MainClass.PrintCopyright();
|
MainClass.PrintCopyright();
|
||||||
if(MainClass.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
|
||||||
if(MainClass.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
if(debug)
|
||||||
|
DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
||||||
|
|
||||||
|
if(verbose)
|
||||||
|
DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
||||||
|
|
||||||
Statistics.AddCommand("list-encodings");
|
Statistics.AddCommand("list-encodings");
|
||||||
|
|
||||||
if(extra.Count > 0)
|
DicConsole.DebugWriteLine("List-Encodings command", "--debug={0}", debug);
|
||||||
{
|
DicConsole.DebugWriteLine("List-Encodings command", "--verbose={0}", verbose);
|
||||||
DicConsole.ErrorWriteLine("Too many arguments.");
|
|
||||||
return (int)ErrorNumber.UnexpectedArgumentCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
DicConsole.DebugWriteLine("List-Encodings command", "--debug={0}", MainClass.Debug);
|
List<CommonEncodingInfo> encodings = Encoding.GetEncodings().Select(info => new CommonEncodingInfo
|
||||||
DicConsole.DebugWriteLine("List-Encodings command", "--verbose={0}", MainClass.Verbose);
|
|
||||||
|
|
||||||
List<CommonEncodingInfo> encodings = Encoding
|
|
||||||
.GetEncodings().Select(info => new CommonEncodingInfo
|
|
||||||
{
|
{
|
||||||
Name = info.Name,
|
Name = info.Name, DisplayName = info.GetEncoding().EncodingName
|
||||||
DisplayName =
|
|
||||||
info.GetEncoding().EncodingName
|
|
||||||
}).ToList();
|
}).ToList();
|
||||||
encodings.AddRange(Claunia.Encoding.Encoding.GetEncodings()
|
|
||||||
.Select(info => new CommonEncodingInfo
|
encodings.AddRange(Claunia.Encoding.Encoding.GetEncodings().Select(info => new CommonEncodingInfo
|
||||||
{
|
{
|
||||||
Name = info.Name, DisplayName = info.DisplayName
|
Name = info.Name, DisplayName = info.DisplayName
|
||||||
}));
|
}));
|
||||||
@@ -100,7 +76,7 @@ namespace DiscImageChef.Commands
|
|||||||
foreach(CommonEncodingInfo info in encodings.OrderBy(t => t.DisplayName))
|
foreach(CommonEncodingInfo info in encodings.OrderBy(t => t.DisplayName))
|
||||||
DicConsole.WriteLine("{0,-16} {1,-8}", info.Name, info.DisplayName);
|
DicConsole.WriteLine("{0,-16} {1,-8}", info.Name, info.DisplayName);
|
||||||
|
|
||||||
return (int)ErrorNumber.NoError;
|
return(int)ErrorNumber.NoError;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct CommonEncodingInfo
|
struct CommonEncodingInfo
|
||||||
|
|||||||
@@ -31,73 +31,54 @@
|
|||||||
// ****************************************************************************/
|
// ****************************************************************************/
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.CommandLine;
|
||||||
|
using System.CommandLine.Invocation;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using DiscImageChef.CommonTypes;
|
using DiscImageChef.CommonTypes;
|
||||||
using DiscImageChef.CommonTypes.Enums;
|
using DiscImageChef.CommonTypes.Enums;
|
||||||
using DiscImageChef.CommonTypes.Interfaces;
|
using DiscImageChef.CommonTypes.Interfaces;
|
||||||
using DiscImageChef.Console;
|
using DiscImageChef.Console;
|
||||||
using DiscImageChef.Core;
|
using DiscImageChef.Core;
|
||||||
using Mono.Options;
|
|
||||||
|
|
||||||
namespace DiscImageChef.Commands
|
namespace DiscImageChef.Commands
|
||||||
{
|
{
|
||||||
class ListNamespacesCommand : Command
|
internal class ListNamespacesCommand : Command
|
||||||
{
|
{
|
||||||
bool showHelp;
|
|
||||||
|
|
||||||
public ListNamespacesCommand() : base("list-namespaces",
|
public ListNamespacesCommand() : base("list-namespaces",
|
||||||
"Lists all namespaces supported by read-only filesystems.")
|
"Lists all namespaces supported by read-only filesystems.") =>
|
||||||
{
|
Handler = CommandHandler.Create(GetType().GetMethod(nameof(Invoke)));
|
||||||
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)
|
static int Invoke(bool debug, bool verbose)
|
||||||
{
|
{
|
||||||
List<string> extra = Options.Parse(arguments);
|
|
||||||
|
|
||||||
if(showHelp)
|
|
||||||
{
|
|
||||||
Options.WriteOptionDescriptions(CommandSet.Out);
|
|
||||||
return (int)ErrorNumber.HelpRequested;
|
|
||||||
}
|
|
||||||
|
|
||||||
MainClass.PrintCopyright();
|
MainClass.PrintCopyright();
|
||||||
if(MainClass.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
|
||||||
if(MainClass.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
|
||||||
|
|
||||||
if(extra.Count > 0)
|
if(debug)
|
||||||
{
|
DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
||||||
DicConsole.ErrorWriteLine("Too many arguments.");
|
|
||||||
return (int)ErrorNumber.UnexpectedArgumentCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
DicConsole.DebugWriteLine("List-Namespaces command", "--debug={0}", MainClass.Debug);
|
if(verbose)
|
||||||
DicConsole.DebugWriteLine("List-Namespaces command", "--verbose={0}", MainClass.Verbose);
|
DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
||||||
|
|
||||||
|
DicConsole.DebugWriteLine("List-Namespaces command", "--debug={0}", debug);
|
||||||
|
DicConsole.DebugWriteLine("List-Namespaces command", "--verbose={0}", verbose);
|
||||||
Statistics.AddCommand("list-namespaces");
|
Statistics.AddCommand("list-namespaces");
|
||||||
|
|
||||||
PluginBase plugins = GetPluginBase.Instance;
|
PluginBase plugins = GetPluginBase.Instance;
|
||||||
|
|
||||||
foreach(KeyValuePair<string, IReadOnlyFilesystem> kvp in plugins.ReadOnlyFilesystems)
|
foreach(KeyValuePair<string, IReadOnlyFilesystem> kvp in plugins.ReadOnlyFilesystems)
|
||||||
{
|
{
|
||||||
if(kvp.Value.Namespaces is null) continue;
|
if(kvp.Value.Namespaces is null)
|
||||||
|
continue;
|
||||||
|
|
||||||
DicConsole.WriteLine("\tNamespaces for {0}:", kvp.Value.Name);
|
DicConsole.WriteLine("\tNamespaces for {0}:", kvp.Value.Name);
|
||||||
DicConsole.WriteLine("\t\t{0,-16} {1,-16}", "Namespace", "Description");
|
DicConsole.WriteLine("\t\t{0,-16} {1,-16}", "Namespace", "Description");
|
||||||
|
|
||||||
foreach(KeyValuePair<string, string> @namespace in kvp.Value.Namespaces.OrderBy(t => t.Key))
|
foreach(KeyValuePair<string, string> @namespace in kvp.Value.Namespaces.OrderBy(t => t.Key))
|
||||||
DicConsole.WriteLine("\t\t{0,-16} {1,-16}", @namespace.Key, @namespace.Value);
|
DicConsole.WriteLine("\t\t{0,-16} {1,-16}", @namespace.Key, @namespace.Value);
|
||||||
|
|
||||||
DicConsole.WriteLine();
|
DicConsole.WriteLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
return (int)ErrorNumber.NoError;
|
return(int)ErrorNumber.NoError;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -32,109 +32,107 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.CommandLine;
|
||||||
|
using System.CommandLine.Invocation;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using DiscImageChef.CommonTypes;
|
using DiscImageChef.CommonTypes;
|
||||||
using DiscImageChef.CommonTypes.Enums;
|
using DiscImageChef.CommonTypes.Enums;
|
||||||
using DiscImageChef.CommonTypes.Interfaces;
|
using DiscImageChef.CommonTypes.Interfaces;
|
||||||
using DiscImageChef.Console;
|
using DiscImageChef.Console;
|
||||||
using DiscImageChef.Core;
|
using DiscImageChef.Core;
|
||||||
using Mono.Options;
|
|
||||||
|
|
||||||
namespace DiscImageChef.Commands
|
namespace DiscImageChef.Commands
|
||||||
{
|
{
|
||||||
class ListOptionsCommand : Command
|
internal class ListOptionsCommand : Command
|
||||||
{
|
{
|
||||||
bool showHelp;
|
|
||||||
|
|
||||||
public ListOptionsCommand() : base("list-options",
|
public ListOptionsCommand() : base("list-options",
|
||||||
"Lists all options supported by read-only filesystems and writable media images.")
|
"Lists all options supported by read-only filesystems and writable media images.") =>
|
||||||
{
|
Handler = CommandHandler.Create(GetType().GetMethod(nameof(Invoke)));
|
||||||
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)
|
static int Invoke(bool debug, bool verbose)
|
||||||
{
|
{
|
||||||
List<string> extra = Options.Parse(arguments);
|
|
||||||
|
|
||||||
if(showHelp)
|
|
||||||
{
|
|
||||||
Options.WriteOptionDescriptions(CommandSet.Out);
|
|
||||||
return (int)ErrorNumber.HelpRequested;
|
|
||||||
}
|
|
||||||
|
|
||||||
MainClass.PrintCopyright();
|
MainClass.PrintCopyright();
|
||||||
if(MainClass.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
|
||||||
if(MainClass.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
|
||||||
|
|
||||||
if(extra.Count > 0)
|
if(debug)
|
||||||
{
|
DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
||||||
DicConsole.ErrorWriteLine("Too many arguments.");
|
|
||||||
return (int)ErrorNumber.UnexpectedArgumentCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
DicConsole.DebugWriteLine("List-Options command", "--debug={0}", MainClass.Debug);
|
if(verbose)
|
||||||
DicConsole.DebugWriteLine("List-Options command", "--verbose={0}", MainClass.Verbose);
|
DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
||||||
|
|
||||||
|
DicConsole.DebugWriteLine("List-Options command", "--debug={0}", debug);
|
||||||
|
DicConsole.DebugWriteLine("List-Options command", "--verbose={0}", verbose);
|
||||||
Statistics.AddCommand("list-options");
|
Statistics.AddCommand("list-options");
|
||||||
|
|
||||||
PluginBase plugins = GetPluginBase.Instance;
|
PluginBase plugins = GetPluginBase.Instance;
|
||||||
|
|
||||||
DicConsole.WriteLine("Read-only filesystems options:");
|
DicConsole.WriteLine("Read-only filesystems options:");
|
||||||
|
|
||||||
foreach(KeyValuePair<string, IReadOnlyFilesystem> kvp in plugins.ReadOnlyFilesystems)
|
foreach(KeyValuePair<string, IReadOnlyFilesystem> kvp in plugins.ReadOnlyFilesystems)
|
||||||
{
|
{
|
||||||
List<(string name, Type type, string description)> options = kvp.Value.SupportedOptions.ToList();
|
List<(string name, Type type, string description)> options = kvp.Value.SupportedOptions.ToList();
|
||||||
if(options.Count == 0) continue;
|
|
||||||
|
if(options.Count == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
DicConsole.WriteLine("\tOptions for {0}:", kvp.Value.Name);
|
DicConsole.WriteLine("\tOptions for {0}:", kvp.Value.Name);
|
||||||
DicConsole.WriteLine("\t\t{0,-16} {1,-16} {2,-8}", "Name", "Type", "Description");
|
DicConsole.WriteLine("\t\t{0,-16} {1,-16} {2,-8}", "Name", "Type", "Description");
|
||||||
|
|
||||||
foreach((string name, Type type, string description) option in options.OrderBy(t => t.name))
|
foreach((string name, Type type, string description) option in options.OrderBy(t => t.name))
|
||||||
DicConsole.WriteLine("\t\t{0,-16} {1,-16} {2,-8}", option.name, TypeToString(option.type),
|
DicConsole.WriteLine("\t\t{0,-16} {1,-16} {2,-8}", option.name, TypeToString(option.type),
|
||||||
option.description);
|
option.description);
|
||||||
|
|
||||||
DicConsole.WriteLine();
|
DicConsole.WriteLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
DicConsole.WriteLine();
|
DicConsole.WriteLine();
|
||||||
|
|
||||||
DicConsole.WriteLine("Read/Write media images options:");
|
DicConsole.WriteLine("Read/Write media images options:");
|
||||||
|
|
||||||
foreach(KeyValuePair<string, IWritableImage> kvp in plugins.WritableImages)
|
foreach(KeyValuePair<string, IWritableImage> kvp in plugins.WritableImages)
|
||||||
{
|
{
|
||||||
List<(string name, Type type, string description, object @default)> options =
|
List<(string name, Type type, string description, object @default)> options =
|
||||||
kvp.Value.SupportedOptions.ToList();
|
kvp.Value.SupportedOptions.ToList();
|
||||||
if(options.Count == 0) continue;
|
|
||||||
|
if(options.Count == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
DicConsole.WriteLine("\tOptions for {0}:", kvp.Value.Name);
|
DicConsole.WriteLine("\tOptions for {0}:", kvp.Value.Name);
|
||||||
DicConsole.WriteLine("\t\t{0,-20} {1,-10} {2,-12} {3,-8}", "Name", "Type", "Default", "Description");
|
DicConsole.WriteLine("\t\t{0,-20} {1,-10} {2,-12} {3,-8}", "Name", "Type", "Default", "Description");
|
||||||
|
|
||||||
foreach((string name, Type type, string description, object @default) option in
|
foreach((string name, Type type, string description, object @default) option in
|
||||||
options.OrderBy(t => t.name))
|
options.OrderBy(t => t.name))
|
||||||
DicConsole.WriteLine("\t\t{0,-20} {1,-10} {2,-12} {3,-8}", option.name, TypeToString(option.type),
|
DicConsole.WriteLine("\t\t{0,-20} {1,-10} {2,-12} {3,-8}", option.name, TypeToString(option.type),
|
||||||
option.@default, option.description);
|
option.@default, option.description);
|
||||||
|
|
||||||
DicConsole.WriteLine();
|
DicConsole.WriteLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
return (int)ErrorNumber.NoError;
|
return(int)ErrorNumber.NoError;
|
||||||
}
|
}
|
||||||
|
|
||||||
static string TypeToString(Type type)
|
static string TypeToString(Type type)
|
||||||
{
|
{
|
||||||
if(type == typeof(bool)) return "boolean";
|
if(type == typeof(bool))
|
||||||
|
return"boolean";
|
||||||
|
|
||||||
if(type == typeof(sbyte) || type == typeof(short) || type == typeof(int) || type == typeof(long))
|
if(type == typeof(sbyte) ||
|
||||||
return "signed number";
|
type == typeof(short) ||
|
||||||
|
type == typeof(int) ||
|
||||||
|
type == typeof(long))
|
||||||
|
return"signed number";
|
||||||
|
|
||||||
if(type == typeof(byte) || type == typeof(ushort) || type == typeof(uint) || type == typeof(ulong))
|
if(type == typeof(byte) ||
|
||||||
return "number";
|
type == typeof(ushort) ||
|
||||||
|
type == typeof(uint) ||
|
||||||
|
type == typeof(ulong))
|
||||||
|
return"number";
|
||||||
|
|
||||||
if(type == typeof(float) || type == typeof(double)) return "float number";
|
if(type == typeof(float) ||
|
||||||
|
type == typeof(double))
|
||||||
|
return"float number";
|
||||||
|
|
||||||
if(type == typeof(Guid)) return "uuid";
|
if(type == typeof(Guid))
|
||||||
|
return"uuid";
|
||||||
|
|
||||||
return type == typeof(string) ? "string" : type.ToString();
|
return type == typeof(string) ? "string" : type.ToString();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,6 +32,8 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.CommandLine;
|
||||||
|
using System.CommandLine.Invocation;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using DiscImageChef.CommonTypes;
|
using DiscImageChef.CommonTypes;
|
||||||
@@ -40,102 +42,104 @@ using DiscImageChef.CommonTypes.Interfaces;
|
|||||||
using DiscImageChef.CommonTypes.Structs;
|
using DiscImageChef.CommonTypes.Structs;
|
||||||
using DiscImageChef.Console;
|
using DiscImageChef.Console;
|
||||||
using DiscImageChef.Core;
|
using DiscImageChef.Core;
|
||||||
using Mono.Options;
|
|
||||||
|
|
||||||
namespace DiscImageChef.Commands
|
namespace DiscImageChef.Commands
|
||||||
{
|
{
|
||||||
class LsCommand : Command
|
internal class LsCommand : Command
|
||||||
{
|
{
|
||||||
string encodingName;
|
|
||||||
string inputFile;
|
|
||||||
bool longFormat;
|
|
||||||
string @namespace;
|
|
||||||
string pluginOptions;
|
|
||||||
bool showHelp;
|
|
||||||
|
|
||||||
public LsCommand() : base("ls", "Lists files in disc image.")
|
public LsCommand() : base("ls", "Lists files in disc image.")
|
||||||
{
|
{
|
||||||
Options = new OptionSet
|
Add(new Option(new[]
|
||||||
{
|
{
|
||||||
$"{MainClass.AssemblyTitle} {MainClass.AssemblyVersion?.InformationalVersion}",
|
"--encoding", "-e"
|
||||||
$"{MainClass.AssemblyCopyright}",
|
}, "Name of character encoding to use.")
|
||||||
"",
|
|
||||||
$"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.",
|
Argument = new Argument<string>(() => null), Required = false
|
||||||
s => pluginOptions = s
|
});
|
||||||
},
|
|
||||||
{"namespace|n=", "Namespace to use for filenames.", s => @namespace = s},
|
Add(new Option(new[]
|
||||||
{"help|h|?", "Show this message and exit.", v => showHelp = v != null}
|
{
|
||||||
};
|
"--long-format", "-l"
|
||||||
|
}, "Uses long format.")
|
||||||
|
{
|
||||||
|
Argument = new Argument<bool>(() => true), Required = false
|
||||||
|
});
|
||||||
|
|
||||||
|
Add(new Option(new[]
|
||||||
|
{
|
||||||
|
"--options", "-O"
|
||||||
|
}, "Comma separated name=value pairs of options to pass to filesystem plugin.")
|
||||||
|
{
|
||||||
|
Argument = new Argument<string>(() => null), Required = false
|
||||||
|
});
|
||||||
|
|
||||||
|
Add(new Option(new[]
|
||||||
|
{
|
||||||
|
"--namespace", "-n"
|
||||||
|
}, "Namespace to use for filenames.")
|
||||||
|
{
|
||||||
|
Argument = new Argument<string>(() => null), Required = false
|
||||||
|
});
|
||||||
|
|
||||||
|
AddArgument(new Argument<string>
|
||||||
|
{
|
||||||
|
Arity = ArgumentArity.ExactlyOne, Description = "Media image path", Name = "image-path"
|
||||||
|
});
|
||||||
|
|
||||||
|
Handler = CommandHandler.Create(GetType().GetMethod(nameof(Invoke)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override int Invoke(IEnumerable<string> arguments)
|
static int Invoke(bool debug, bool verbose, string encoding, string imagePath, bool longFormat,
|
||||||
|
string @namespace, string options)
|
||||||
{
|
{
|
||||||
List<string> extra = Options.Parse(arguments);
|
|
||||||
|
|
||||||
if(showHelp)
|
|
||||||
{
|
|
||||||
Options.WriteOptionDescriptions(CommandSet.Out);
|
|
||||||
return (int)ErrorNumber.HelpRequested;
|
|
||||||
}
|
|
||||||
|
|
||||||
MainClass.PrintCopyright();
|
MainClass.PrintCopyright();
|
||||||
if(MainClass.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
|
||||||
if(MainClass.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
|
||||||
|
|
||||||
if(extra.Count > 1)
|
if(debug)
|
||||||
{
|
DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
||||||
DicConsole.ErrorWriteLine("Too many arguments.");
|
|
||||||
return (int)ErrorNumber.UnexpectedArgumentCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(extra.Count == 0)
|
if(verbose)
|
||||||
{
|
DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
||||||
DicConsole.ErrorWriteLine("Missing input image.");
|
|
||||||
return (int)ErrorNumber.MissingArgument;
|
|
||||||
}
|
|
||||||
|
|
||||||
inputFile = extra[0];
|
DicConsole.DebugWriteLine("Ls command", "--debug={0}", debug);
|
||||||
|
DicConsole.DebugWriteLine("Ls command", "--encoding={0}", encoding);
|
||||||
DicConsole.DebugWriteLine("Ls command", "--debug={0}", MainClass.Debug);
|
DicConsole.DebugWriteLine("Ls command", "--input={0}", imagePath);
|
||||||
DicConsole.DebugWriteLine("Ls command", "--encoding={0}", encodingName);
|
DicConsole.DebugWriteLine("Ls command", "--options={0}", options);
|
||||||
DicConsole.DebugWriteLine("Ls command", "--input={0}", inputFile);
|
DicConsole.DebugWriteLine("Ls command", "--verbose={0}", verbose);
|
||||||
DicConsole.DebugWriteLine("Ls command", "--options={0}", pluginOptions);
|
|
||||||
DicConsole.DebugWriteLine("Ls command", "--verbose={0}", MainClass.Verbose);
|
|
||||||
Statistics.AddCommand("ls");
|
Statistics.AddCommand("ls");
|
||||||
|
|
||||||
FiltersList filtersList = new FiltersList();
|
var filtersList = new FiltersList();
|
||||||
IFilter inputFilter = filtersList.GetFilter(inputFile);
|
IFilter inputFilter = filtersList.GetFilter(imagePath);
|
||||||
|
|
||||||
Dictionary<string, string> parsedOptions = Core.Options.Parse(pluginOptions);
|
Dictionary<string, string> parsedOptions = Core.Options.Parse(options);
|
||||||
DicConsole.DebugWriteLine("Ls command", "Parsed options:");
|
DicConsole.DebugWriteLine("Ls command", "Parsed options:");
|
||||||
|
|
||||||
foreach(KeyValuePair<string, string> parsedOption in parsedOptions)
|
foreach(KeyValuePair<string, string> parsedOption in parsedOptions)
|
||||||
DicConsole.DebugWriteLine("Ls command", "{0} = {1}", parsedOption.Key, parsedOption.Value);
|
DicConsole.DebugWriteLine("Ls command", "{0} = {1}", parsedOption.Key, parsedOption.Value);
|
||||||
parsedOptions.Add("debug", MainClass.Debug.ToString());
|
|
||||||
|
parsedOptions.Add("debug", debug.ToString());
|
||||||
|
|
||||||
if(inputFilter == null)
|
if(inputFilter == null)
|
||||||
{
|
{
|
||||||
DicConsole.ErrorWriteLine("Cannot open specified file.");
|
DicConsole.ErrorWriteLine("Cannot open specified file.");
|
||||||
return (int)ErrorNumber.CannotOpenFile;
|
|
||||||
|
return(int)ErrorNumber.CannotOpenFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
Encoding encoding = null;
|
Encoding encodingClass = null;
|
||||||
|
|
||||||
if(encodingName != null)
|
if(encoding != null)
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
encoding = Claunia.Encoding.Encoding.GetEncoding(encodingName);
|
encodingClass = Claunia.Encoding.Encoding.GetEncoding(encoding);
|
||||||
if(MainClass.Verbose) DicConsole.VerboseWriteLine("Using encoding for {0}.", encoding.EncodingName);
|
|
||||||
|
if(verbose)
|
||||||
|
DicConsole.VerboseWriteLine("Using encoding for {0}.", encodingClass.EncodingName);
|
||||||
}
|
}
|
||||||
catch(ArgumentException)
|
catch(ArgumentException)
|
||||||
{
|
{
|
||||||
DicConsole.ErrorWriteLine("Specified encoding is not supported.");
|
DicConsole.ErrorWriteLine("Specified encoding is not supported.");
|
||||||
return (int)ErrorNumber.EncodingUnknown;
|
|
||||||
|
return(int)ErrorNumber.EncodingUnknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
PluginBase plugins = GetPluginBase.Instance;
|
PluginBase plugins = GetPluginBase.Instance;
|
||||||
@@ -147,13 +151,15 @@ namespace DiscImageChef.Commands
|
|||||||
if(imageFormat == null)
|
if(imageFormat == null)
|
||||||
{
|
{
|
||||||
DicConsole.WriteLine("Image format not identified, not proceeding with analysis.");
|
DicConsole.WriteLine("Image format not identified, not proceeding with analysis.");
|
||||||
return (int)ErrorNumber.UnrecognizedFormat;
|
|
||||||
|
return(int)ErrorNumber.UnrecognizedFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(MainClass.Verbose)
|
if(verbose)
|
||||||
DicConsole.VerboseWriteLine("Image format identified by {0} ({1}).", imageFormat.Name,
|
DicConsole.VerboseWriteLine("Image format identified by {0} ({1}).", imageFormat.Name,
|
||||||
imageFormat.Id);
|
imageFormat.Id);
|
||||||
else DicConsole.WriteLine("Image format identified by {0}.", imageFormat.Name);
|
else
|
||||||
|
DicConsole.WriteLine("Image format identified by {0}.", imageFormat.Name);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -161,13 +167,17 @@ namespace DiscImageChef.Commands
|
|||||||
{
|
{
|
||||||
DicConsole.WriteLine("Unable to open image format");
|
DicConsole.WriteLine("Unable to open image format");
|
||||||
DicConsole.WriteLine("No error given");
|
DicConsole.WriteLine("No error given");
|
||||||
return (int)ErrorNumber.CannotOpenFormat;
|
|
||||||
|
return(int)ErrorNumber.CannotOpenFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
DicConsole.DebugWriteLine("Ls command", "Correctly opened image file.");
|
DicConsole.DebugWriteLine("Ls command", "Correctly opened image file.");
|
||||||
|
|
||||||
DicConsole.DebugWriteLine("Ls command", "Image without headers is {0} bytes.",
|
DicConsole.DebugWriteLine("Ls command", "Image without headers is {0} bytes.",
|
||||||
imageFormat.Info.ImageSize);
|
imageFormat.Info.ImageSize);
|
||||||
|
|
||||||
DicConsole.DebugWriteLine("Ls command", "Image has {0} sectors.", imageFormat.Info.Sectors);
|
DicConsole.DebugWriteLine("Ls command", "Image has {0} sectors.", imageFormat.Info.Sectors);
|
||||||
|
|
||||||
DicConsole.DebugWriteLine("Ls command", "Image identifies disk type as {0}.",
|
DicConsole.DebugWriteLine("Ls command", "Image identifies disk type as {0}.",
|
||||||
imageFormat.Info.MediaType);
|
imageFormat.Info.MediaType);
|
||||||
|
|
||||||
@@ -179,7 +189,8 @@ namespace DiscImageChef.Commands
|
|||||||
{
|
{
|
||||||
DicConsole.ErrorWriteLine("Unable to open image format");
|
DicConsole.ErrorWriteLine("Unable to open image format");
|
||||||
DicConsole.ErrorWriteLine("Error: {0}", ex.Message);
|
DicConsole.ErrorWriteLine("Error: {0}", ex.Message);
|
||||||
return (int)ErrorNumber.CannotOpenFormat;
|
|
||||||
|
return(int)ErrorNumber.CannotOpenFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Partition> partitions = Core.Partitions.GetAll(imageFormat);
|
List<Partition> partitions = Core.Partitions.GetAll(imageFormat);
|
||||||
@@ -188,7 +199,9 @@ namespace DiscImageChef.Commands
|
|||||||
List<string> idPlugins;
|
List<string> idPlugins;
|
||||||
IReadOnlyFilesystem plugin;
|
IReadOnlyFilesystem plugin;
|
||||||
Errno error;
|
Errno error;
|
||||||
if(partitions.Count == 0) DicConsole.DebugWriteLine("Ls command", "No partitions found");
|
|
||||||
|
if(partitions.Count == 0)
|
||||||
|
DicConsole.DebugWriteLine("Ls command", "No partitions found");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DicConsole.WriteLine("{0} partitions found.", partitions.Count);
|
DicConsole.WriteLine("{0} partitions found.", partitions.Count);
|
||||||
@@ -201,7 +214,9 @@ namespace DiscImageChef.Commands
|
|||||||
DicConsole.WriteLine("Identifying filesystem on partition");
|
DicConsole.WriteLine("Identifying filesystem on partition");
|
||||||
|
|
||||||
Core.Filesystems.Identify(imageFormat, out idPlugins, partitions[i]);
|
Core.Filesystems.Identify(imageFormat, out idPlugins, partitions[i]);
|
||||||
if(idPlugins.Count == 0) DicConsole.WriteLine("Filesystem not identified");
|
|
||||||
|
if(idPlugins.Count == 0)
|
||||||
|
DicConsole.WriteLine("Filesystem not identified");
|
||||||
else if(idPlugins.Count > 1)
|
else if(idPlugins.Count > 1)
|
||||||
{
|
{
|
||||||
DicConsole.WriteLine($"Identified by {idPlugins.Count} plugins");
|
DicConsole.WriteLine($"Identified by {idPlugins.Count} plugins");
|
||||||
@@ -210,17 +225,21 @@ namespace DiscImageChef.Commands
|
|||||||
if(plugins.ReadOnlyFilesystems.TryGetValue(pluginName, out plugin))
|
if(plugins.ReadOnlyFilesystems.TryGetValue(pluginName, out plugin))
|
||||||
{
|
{
|
||||||
DicConsole.WriteLine($"As identified by {plugin.Name}.");
|
DicConsole.WriteLine($"As identified by {plugin.Name}.");
|
||||||
IReadOnlyFilesystem fs = (IReadOnlyFilesystem)plugin
|
|
||||||
.GetType()
|
|
||||||
.GetConstructor(Type.EmptyTypes)
|
|
||||||
?.Invoke(new object[] { });
|
|
||||||
|
|
||||||
if(fs == null) continue;
|
var fs = (IReadOnlyFilesystem)plugin.
|
||||||
|
GetType().GetConstructor(Type.EmptyTypes)?.
|
||||||
|
Invoke(new object[]
|
||||||
|
{ });
|
||||||
|
|
||||||
|
if(fs == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
error = fs.Mount(imageFormat, partitions[i], encodingClass, parsedOptions,
|
||||||
|
@namespace);
|
||||||
|
|
||||||
error = fs.Mount(imageFormat, partitions[i], encoding, parsedOptions, @namespace);
|
|
||||||
if(error == Errno.NoError)
|
if(error == Errno.NoError)
|
||||||
{
|
{
|
||||||
ListFilesInDir("/", fs);
|
ListFilesInDir("/", fs, longFormat);
|
||||||
|
|
||||||
Statistics.AddFilesystem(fs.XmlFsType.Type);
|
Statistics.AddFilesystem(fs.XmlFsType.Type);
|
||||||
}
|
}
|
||||||
@@ -232,35 +251,43 @@ namespace DiscImageChef.Commands
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
plugins.ReadOnlyFilesystems.TryGetValue(idPlugins[0], out plugin);
|
plugins.ReadOnlyFilesystems.TryGetValue(idPlugins[0], out plugin);
|
||||||
if(plugin == null) continue;
|
|
||||||
|
if(plugin == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
DicConsole.WriteLine($"Identified by {plugin.Name}.");
|
DicConsole.WriteLine($"Identified by {plugin.Name}.");
|
||||||
IReadOnlyFilesystem fs = (IReadOnlyFilesystem)plugin
|
|
||||||
.GetType().GetConstructor(Type.EmptyTypes)
|
|
||||||
?.Invoke(new object[] { });
|
|
||||||
if(fs == null) continue;
|
|
||||||
|
|
||||||
error = fs.Mount(imageFormat, partitions[i], encoding, parsedOptions, @namespace);
|
var fs = (IReadOnlyFilesystem)plugin.
|
||||||
|
GetType().GetConstructor(Type.EmptyTypes)?.Invoke(new object[]
|
||||||
|
{ });
|
||||||
|
|
||||||
|
if(fs == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
error = fs.Mount(imageFormat, partitions[i], encodingClass, parsedOptions, @namespace);
|
||||||
|
|
||||||
if(error == Errno.NoError)
|
if(error == Errno.NoError)
|
||||||
{
|
{
|
||||||
ListFilesInDir("/", fs);
|
ListFilesInDir("/", fs, longFormat);
|
||||||
|
|
||||||
Statistics.AddFilesystem(fs.XmlFsType.Type);
|
Statistics.AddFilesystem(fs.XmlFsType.Type);
|
||||||
}
|
}
|
||||||
else DicConsole.ErrorWriteLine("Unable to mount device, error {0}", error.ToString());
|
else
|
||||||
|
DicConsole.ErrorWriteLine("Unable to mount device, error {0}", error.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Partition wholePart = new Partition
|
var wholePart = new Partition
|
||||||
{
|
{
|
||||||
Name = "Whole device",
|
Name = "Whole device", Length = imageFormat.Info.Sectors,
|
||||||
Length = imageFormat.Info.Sectors,
|
|
||||||
Size = imageFormat.Info.Sectors * imageFormat.Info.SectorSize
|
Size = imageFormat.Info.Sectors * imageFormat.Info.SectorSize
|
||||||
};
|
};
|
||||||
|
|
||||||
Core.Filesystems.Identify(imageFormat, out idPlugins, wholePart);
|
Core.Filesystems.Identify(imageFormat, out idPlugins, wholePart);
|
||||||
if(idPlugins.Count == 0) DicConsole.WriteLine("Filesystem not identified");
|
|
||||||
|
if(idPlugins.Count == 0)
|
||||||
|
DicConsole.WriteLine("Filesystem not identified");
|
||||||
else if(idPlugins.Count > 1)
|
else if(idPlugins.Count > 1)
|
||||||
{
|
{
|
||||||
DicConsole.WriteLine($"Identified by {idPlugins.Count} plugins");
|
DicConsole.WriteLine($"Identified by {idPlugins.Count} plugins");
|
||||||
@@ -269,40 +296,50 @@ namespace DiscImageChef.Commands
|
|||||||
if(plugins.ReadOnlyFilesystems.TryGetValue(pluginName, out plugin))
|
if(plugins.ReadOnlyFilesystems.TryGetValue(pluginName, out plugin))
|
||||||
{
|
{
|
||||||
DicConsole.WriteLine($"As identified by {plugin.Name}.");
|
DicConsole.WriteLine($"As identified by {plugin.Name}.");
|
||||||
IReadOnlyFilesystem fs = (IReadOnlyFilesystem)plugin
|
|
||||||
.GetType().GetConstructor(Type.EmptyTypes)
|
|
||||||
?.Invoke(new object[] { });
|
|
||||||
if(fs == null) continue;
|
|
||||||
|
|
||||||
error = fs.Mount(imageFormat, wholePart, encoding, parsedOptions, @namespace);
|
var fs = (IReadOnlyFilesystem)plugin.
|
||||||
|
GetType().GetConstructor(Type.EmptyTypes)?.Invoke(new object[]
|
||||||
|
{ });
|
||||||
|
|
||||||
|
if(fs == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
error = fs.Mount(imageFormat, wholePart, encodingClass, parsedOptions, @namespace);
|
||||||
|
|
||||||
if(error == Errno.NoError)
|
if(error == Errno.NoError)
|
||||||
{
|
{
|
||||||
ListFilesInDir("/", fs);
|
ListFilesInDir("/", fs, longFormat);
|
||||||
|
|
||||||
Statistics.AddFilesystem(fs.XmlFsType.Type);
|
Statistics.AddFilesystem(fs.XmlFsType.Type);
|
||||||
}
|
}
|
||||||
else DicConsole.ErrorWriteLine("Unable to mount device, error {0}", error.ToString());
|
else
|
||||||
|
DicConsole.ErrorWriteLine("Unable to mount device, error {0}", error.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
plugins.ReadOnlyFilesystems.TryGetValue(idPlugins[0], out plugin);
|
plugins.ReadOnlyFilesystems.TryGetValue(idPlugins[0], out plugin);
|
||||||
|
|
||||||
if(plugin != null)
|
if(plugin != null)
|
||||||
{
|
{
|
||||||
DicConsole.WriteLine($"Identified by {plugin.Name}.");
|
DicConsole.WriteLine($"Identified by {plugin.Name}.");
|
||||||
IReadOnlyFilesystem fs =
|
|
||||||
(IReadOnlyFilesystem)plugin
|
var fs = (IReadOnlyFilesystem)plugin.
|
||||||
.GetType().GetConstructor(Type.EmptyTypes)?.Invoke(new object[] { });
|
GetType().GetConstructor(Type.EmptyTypes)?.Invoke(new object[]
|
||||||
|
{ });
|
||||||
|
|
||||||
if(fs != null)
|
if(fs != null)
|
||||||
{
|
{
|
||||||
error = fs.Mount(imageFormat, wholePart, encoding, parsedOptions, @namespace);
|
error = fs.Mount(imageFormat, wholePart, encodingClass, parsedOptions, @namespace);
|
||||||
|
|
||||||
if(error == Errno.NoError)
|
if(error == Errno.NoError)
|
||||||
{
|
{
|
||||||
ListFilesInDir("/", fs);
|
ListFilesInDir("/", fs, longFormat);
|
||||||
|
|
||||||
Statistics.AddFilesystem(fs.XmlFsType.Type);
|
Statistics.AddFilesystem(fs.XmlFsType.Type);
|
||||||
}
|
}
|
||||||
else DicConsole.ErrorWriteLine("Unable to mount device, error {0}", error.ToString());
|
else
|
||||||
|
DicConsole.ErrorWriteLine("Unable to mount device, error {0}", error.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -311,15 +348,17 @@ namespace DiscImageChef.Commands
|
|||||||
{
|
{
|
||||||
DicConsole.ErrorWriteLine($"Error reading file: {ex.Message}");
|
DicConsole.ErrorWriteLine($"Error reading file: {ex.Message}");
|
||||||
DicConsole.DebugWriteLine("Ls command", ex.StackTrace);
|
DicConsole.DebugWriteLine("Ls command", ex.StackTrace);
|
||||||
return (int)ErrorNumber.UnexpectedException;
|
|
||||||
|
return(int)ErrorNumber.UnexpectedException;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (int)ErrorNumber.NoError;
|
return(int)ErrorNumber.NoError;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ListFilesInDir(string path, IReadOnlyFilesystem fs)
|
static void ListFilesInDir(string path, IReadOnlyFilesystem fs, bool longFormat)
|
||||||
{
|
{
|
||||||
if(path.StartsWith("/")) path = path.Substring(1);
|
if(path.StartsWith("/"))
|
||||||
|
path = path.Substring(1);
|
||||||
|
|
||||||
DicConsole.WriteLine(string.IsNullOrEmpty(path) ? "Root directory" : $"Directory: {path}");
|
DicConsole.WriteLine(string.IsNullOrEmpty(path) ? "Root directory" : $"Directory: {path}");
|
||||||
|
|
||||||
@@ -328,6 +367,7 @@ namespace DiscImageChef.Commands
|
|||||||
if(error != Errno.NoError)
|
if(error != Errno.NoError)
|
||||||
{
|
{
|
||||||
DicConsole.ErrorWriteLine("Error {0} reading root directory {1}", error.ToString(), path);
|
DicConsole.ErrorWriteLine("Error {0} reading root directory {1}", error.ToString(), path);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -335,7 +375,7 @@ namespace DiscImageChef.Commands
|
|||||||
|
|
||||||
foreach(string entry in directory)
|
foreach(string entry in directory)
|
||||||
{
|
{
|
||||||
error = fs.Stat(path + "/" + entry, out FileEntryInfo stat);
|
fs.Stat(path + "/" + entry, out FileEntryInfo stat);
|
||||||
|
|
||||||
stats.Add(entry, stat);
|
stats.Add(entry, stat);
|
||||||
}
|
}
|
||||||
@@ -355,30 +395,36 @@ namespace DiscImageChef.Commands
|
|||||||
entry.Key);
|
entry.Key);
|
||||||
|
|
||||||
error = fs.ListXAttr(path + "/" + entry.Key, out List<string> xattrs);
|
error = fs.ListXAttr(path + "/" + entry.Key, out List<string> xattrs);
|
||||||
if(error != Errno.NoError) continue;
|
|
||||||
|
if(error != Errno.NoError)
|
||||||
|
continue;
|
||||||
|
|
||||||
foreach(string xattr in xattrs)
|
foreach(string xattr in xattrs)
|
||||||
{
|
{
|
||||||
byte[] xattrBuf = new byte[0];
|
byte[] xattrBuf = new byte[0];
|
||||||
error = fs.GetXattr(path + "/" + entry.Key, xattr, ref xattrBuf);
|
error = fs.GetXattr(path + "/" + entry.Key, xattr, ref xattrBuf);
|
||||||
|
|
||||||
if(error == Errno.NoError)
|
if(error == Errno.NoError)
|
||||||
DicConsole.WriteLine("\t\t{0}\t{1:##,#}", xattr, xattrBuf.Length);
|
DicConsole.WriteLine("\t\t{0}\t{1:##,#}", xattr, xattrBuf.Length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else DicConsole.WriteLine("{0, 47}{1}", string.Empty, entry.Key);
|
else
|
||||||
|
DicConsole.WriteLine("{0, 47}{1}", string.Empty, entry.Key);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(entry.Value != null && entry.Value.Attributes.HasFlag(FileAttributes.Directory))
|
if(entry.Value != null &&
|
||||||
|
entry.Value.Attributes.HasFlag(FileAttributes.Directory))
|
||||||
DicConsole.WriteLine("{0}/", entry.Key);
|
DicConsole.WriteLine("{0}/", entry.Key);
|
||||||
else DicConsole.WriteLine("{0}", entry.Key);
|
else
|
||||||
|
DicConsole.WriteLine("{0}", entry.Key);
|
||||||
}
|
}
|
||||||
|
|
||||||
DicConsole.WriteLine();
|
DicConsole.WriteLine();
|
||||||
|
|
||||||
foreach(KeyValuePair<string, FileEntryInfo> subdirectory in
|
foreach(KeyValuePair<string, FileEntryInfo> subdirectory in
|
||||||
stats.Where(e => e.Value?.Attributes.HasFlag(FileAttributes.Directory) == true))
|
stats.Where(e => e.Value?.Attributes.HasFlag(FileAttributes.Directory) == true))
|
||||||
ListFilesInDir(path + "/" + subdirectory.Key, fs);
|
ListFilesInDir(path + "/" + subdirectory.Key, fs, longFormat);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -32,6 +32,8 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.CommandLine;
|
||||||
|
using System.CommandLine.Invocation;
|
||||||
using DiscImageChef.CommonTypes.Enums;
|
using DiscImageChef.CommonTypes.Enums;
|
||||||
using DiscImageChef.Console;
|
using DiscImageChef.Console;
|
||||||
using DiscImageChef.Core;
|
using DiscImageChef.Core;
|
||||||
@@ -44,7 +46,6 @@ using DiscImageChef.Decoders.SCSI.MMC;
|
|||||||
using DiscImageChef.Decoders.SCSI.SSC;
|
using DiscImageChef.Decoders.SCSI.SSC;
|
||||||
using DiscImageChef.Decoders.Xbox;
|
using DiscImageChef.Decoders.Xbox;
|
||||||
using DiscImageChef.Devices;
|
using DiscImageChef.Devices;
|
||||||
using Mono.Options;
|
|
||||||
using BCA = DiscImageChef.Decoders.Bluray.BCA;
|
using BCA = DiscImageChef.Decoders.Bluray.BCA;
|
||||||
using Cartridge = DiscImageChef.Decoders.DVD.Cartridge;
|
using Cartridge = DiscImageChef.Decoders.DVD.Cartridge;
|
||||||
using DDS = DiscImageChef.Decoders.DVD.DDS;
|
using DDS = DiscImageChef.Decoders.DVD.DDS;
|
||||||
@@ -55,65 +56,40 @@ namespace DiscImageChef.Commands
|
|||||||
{
|
{
|
||||||
internal class MediaInfoCommand : Command
|
internal class MediaInfoCommand : Command
|
||||||
{
|
{
|
||||||
string devicePath;
|
public MediaInfoCommand() : base("media-info", "Gets information about the media inserted on a device.")
|
||||||
string outputPrefix;
|
{
|
||||||
bool showHelp;
|
Add(new Option(new[]
|
||||||
|
{
|
||||||
|
"--output-prefix", "-w"
|
||||||
|
}, "Write binary responses from device with that prefix.")
|
||||||
|
{
|
||||||
|
Argument = new Argument<string>(() => null), Required = false
|
||||||
|
});
|
||||||
|
|
||||||
public MediaInfoCommand() : base("media-info", "Gets information about the media inserted on a device.") =>
|
AddArgument(new Argument<string>
|
||||||
Options = new OptionSet
|
|
||||||
{
|
{
|
||||||
$"{MainClass.AssemblyTitle} {MainClass.AssemblyVersion?.InformationalVersion}",
|
Arity = ArgumentArity.ExactlyOne, Description = "Device path", Name = "device-path"
|
||||||
$"{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
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public override int Invoke(IEnumerable<string> arguments)
|
Handler = CommandHandler.Create(GetType().GetMethod(nameof(Invoke)));
|
||||||
{
|
|
||||||
List<string> extra = Options.Parse(arguments);
|
|
||||||
|
|
||||||
if(showHelp)
|
|
||||||
{
|
|
||||||
Options.WriteOptionDescriptions(CommandSet.Out);
|
|
||||||
|
|
||||||
return(int)ErrorNumber.HelpRequested;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int Invoke(bool debug, bool verbose, string devicePath, string outputPrefix)
|
||||||
|
{
|
||||||
MainClass.PrintCopyright();
|
MainClass.PrintCopyright();
|
||||||
|
|
||||||
if(MainClass.Debug)
|
if(debug)
|
||||||
DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
||||||
|
|
||||||
if(MainClass.Verbose)
|
if(verbose)
|
||||||
DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
||||||
|
|
||||||
Statistics.AddCommand("media-info");
|
Statistics.AddCommand("media-info");
|
||||||
|
|
||||||
if(extra.Count > 1)
|
DicConsole.DebugWriteLine("Media-Info command", "--debug={0}", debug);
|
||||||
{
|
|
||||||
DicConsole.ErrorWriteLine("Too many arguments.");
|
|
||||||
|
|
||||||
return(int)ErrorNumber.UnexpectedArgumentCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(extra.Count == 0)
|
|
||||||
{
|
|
||||||
DicConsole.ErrorWriteLine("Missing device path.");
|
|
||||||
|
|
||||||
return(int)ErrorNumber.MissingArgument;
|
|
||||||
}
|
|
||||||
|
|
||||||
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", "--device={0}", devicePath);
|
||||||
DicConsole.DebugWriteLine("Media-Info command", "--output-prefix={0}", outputPrefix);
|
DicConsole.DebugWriteLine("Media-Info command", "--output-prefix={0}", outputPrefix);
|
||||||
DicConsole.DebugWriteLine("Media-Info command", "--verbose={0}", MainClass.Verbose);
|
DicConsole.DebugWriteLine("Media-Info command", "--verbose={0}", verbose);
|
||||||
|
|
||||||
if(devicePath.Length == 2 &&
|
if(devicePath.Length == 2 &&
|
||||||
devicePath[1] == ':' &&
|
devicePath[1] == ':' &&
|
||||||
|
|||||||
@@ -30,82 +30,61 @@
|
|||||||
// Copyright © 2011-2019 Natalia Portillo
|
// Copyright © 2011-2019 Natalia Portillo
|
||||||
// ****************************************************************************/
|
// ****************************************************************************/
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.CommandLine;
|
||||||
|
using System.CommandLine.Invocation;
|
||||||
using DiscImageChef.CommonTypes.Enums;
|
using DiscImageChef.CommonTypes.Enums;
|
||||||
using DiscImageChef.Console;
|
using DiscImageChef.Console;
|
||||||
using DiscImageChef.Core;
|
using DiscImageChef.Core;
|
||||||
using DiscImageChef.Core.Devices.Scanning;
|
using DiscImageChef.Core.Devices.Scanning;
|
||||||
using DiscImageChef.Devices;
|
using DiscImageChef.Devices;
|
||||||
using Mono.Options;
|
|
||||||
|
|
||||||
namespace DiscImageChef.Commands
|
namespace DiscImageChef.Commands
|
||||||
{
|
{
|
||||||
internal class MediaScanCommand : Command
|
internal class MediaScanCommand : Command
|
||||||
{
|
{
|
||||||
string devicePath;
|
public MediaScanCommand() : base("media-scan", "Scans the media inserted on a device.")
|
||||||
string ibgLogPath;
|
{
|
||||||
string mhddLogPath;
|
Add(new Option(new[]
|
||||||
bool showHelp;
|
{
|
||||||
|
"--mhdd-log", "-m"
|
||||||
|
}, "Write a log of the scan in the format used by MHDD.")
|
||||||
|
{
|
||||||
|
Argument = new Argument<string>(() => null), Required = false
|
||||||
|
});
|
||||||
|
|
||||||
public MediaScanCommand() : base("media-scan", "Scans the media inserted on a device.") =>
|
Add(new Option(new[]
|
||||||
Options = new OptionSet
|
|
||||||
{
|
{
|
||||||
$"{MainClass.AssemblyTitle} {MainClass.AssemblyVersion?.InformationalVersion}",
|
"--ibg-log", "-b"
|
||||||
$"{MainClass.AssemblyCopyright}", "", $"usage: DiscImageChef {Name} [OPTIONS] devicepath", "",
|
}, "Write a log of the scan in the format used by ImgBurn.")
|
||||||
Help,
|
|
||||||
{
|
{
|
||||||
"mhdd-log|mw=", "Write a log of the scan in the format used by MHDD.", s => mhddLogPath = s
|
Argument = new Argument<bool>(() => true), Required = false
|
||||||
},
|
});
|
||||||
{
|
|
||||||
"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
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public override int Invoke(IEnumerable<string> arguments)
|
AddArgument(new Argument<string>
|
||||||
{
|
{
|
||||||
List<string> extra = Options.Parse(arguments);
|
Arity = ArgumentArity.ExactlyOne, Description = "Device path", Name = "device-path"
|
||||||
|
});
|
||||||
|
|
||||||
if(showHelp)
|
Handler = CommandHandler.Create(GetType().GetMethod(nameof(Invoke)));
|
||||||
{
|
|
||||||
Options.WriteOptionDescriptions(CommandSet.Out);
|
|
||||||
|
|
||||||
return(int)ErrorNumber.HelpRequested;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int Invoke(bool debug, bool verbose, string devicePath, string ibgLog, string mhddLog)
|
||||||
|
{
|
||||||
MainClass.PrintCopyright();
|
MainClass.PrintCopyright();
|
||||||
|
|
||||||
if(MainClass.Debug)
|
if(debug)
|
||||||
DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
||||||
|
|
||||||
if(MainClass.Verbose)
|
if(verbose)
|
||||||
DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
||||||
|
|
||||||
Statistics.AddCommand("media-scan");
|
Statistics.AddCommand("media-scan");
|
||||||
|
|
||||||
if(extra.Count > 1)
|
DicConsole.DebugWriteLine("Media-Scan command", "--debug={0}", debug);
|
||||||
{
|
|
||||||
DicConsole.ErrorWriteLine("Too many arguments.");
|
|
||||||
|
|
||||||
return(int)ErrorNumber.UnexpectedArgumentCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(extra.Count == 0)
|
|
||||||
{
|
|
||||||
DicConsole.ErrorWriteLine("Missing device path.");
|
|
||||||
|
|
||||||
return(int)ErrorNumber.MissingArgument;
|
|
||||||
}
|
|
||||||
|
|
||||||
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", "--device={0}", devicePath);
|
||||||
DicConsole.DebugWriteLine("Media-Scan command", "--ibg-log={0}", ibgLogPath);
|
DicConsole.DebugWriteLine("Media-Scan command", "--ibg-log={0}", ibgLog);
|
||||||
DicConsole.DebugWriteLine("Media-Scan command", "--mhdd-log={0}", mhddLogPath);
|
DicConsole.DebugWriteLine("Media-Scan command", "--mhdd-log={0}", mhddLog);
|
||||||
DicConsole.DebugWriteLine("Media-Scan command", "--verbose={0}", MainClass.Verbose);
|
DicConsole.DebugWriteLine("Media-Scan command", "--verbose={0}", verbose);
|
||||||
|
|
||||||
if(devicePath.Length == 2 &&
|
if(devicePath.Length == 2 &&
|
||||||
devicePath[1] == ':' &&
|
devicePath[1] == ':' &&
|
||||||
@@ -139,7 +118,7 @@ namespace DiscImageChef.Commands
|
|||||||
|
|
||||||
Statistics.AddDevice(dev);
|
Statistics.AddDevice(dev);
|
||||||
|
|
||||||
var scanner = new MediaScan(mhddLogPath, ibgLogPath, devicePath, dev);
|
var scanner = new MediaScan(mhddLog, ibgLog, devicePath, dev);
|
||||||
scanner.UpdateStatus += Progress.UpdateStatus;
|
scanner.UpdateStatus += Progress.UpdateStatus;
|
||||||
scanner.StoppingErrorMessage += Progress.ErrorMessage;
|
scanner.StoppingErrorMessage += Progress.ErrorMessage;
|
||||||
scanner.UpdateProgress += Progress.UpdateProgress;
|
scanner.UpdateProgress += Progress.UpdateProgress;
|
||||||
@@ -177,9 +156,13 @@ namespace DiscImageChef.Commands
|
|||||||
DicConsole.WriteLine();
|
DicConsole.WriteLine();
|
||||||
|
|
||||||
#pragma warning disable RECS0018 // Comparison of floating point numbers with equality operator
|
#pragma warning disable RECS0018 // Comparison of floating point numbers with equality operator
|
||||||
|
|
||||||
|
// ReSharper disable CompareOfFloatsByEqualityOperator
|
||||||
if(results.SeekTotal != 0 ||
|
if(results.SeekTotal != 0 ||
|
||||||
results.SeekMin != double.MaxValue ||
|
results.SeekMin != double.MaxValue ||
|
||||||
results.SeekMax != double.MinValue)
|
results.SeekMax != double.MinValue)
|
||||||
|
|
||||||
|
// ReSharper restore CompareOfFloatsByEqualityOperator
|
||||||
#pragma warning restore RECS0018 // Comparison of floating point numbers with equality operator
|
#pragma warning restore RECS0018 // Comparison of floating point numbers with equality operator
|
||||||
DicConsole.WriteLine("Testing {0} seeks, longest seek took {1:F3} ms, fastest one took {2:F3} ms. ({3:F3} ms average)",
|
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);
|
results.SeekTimes, results.SeekMax, results.SeekMin, results.SeekTotal / 1000);
|
||||||
|
|||||||
@@ -30,93 +30,89 @@
|
|||||||
// Copyright © 2011-2019 Natalia Portillo
|
// Copyright © 2011-2019 Natalia Portillo
|
||||||
// ****************************************************************************/
|
// ****************************************************************************/
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.CommandLine;
|
||||||
|
using System.CommandLine.Invocation;
|
||||||
using DiscImageChef.CommonTypes;
|
using DiscImageChef.CommonTypes;
|
||||||
using DiscImageChef.CommonTypes.Enums;
|
using DiscImageChef.CommonTypes.Enums;
|
||||||
using DiscImageChef.CommonTypes.Interfaces;
|
using DiscImageChef.CommonTypes.Interfaces;
|
||||||
using DiscImageChef.Console;
|
using DiscImageChef.Console;
|
||||||
using DiscImageChef.Core;
|
using DiscImageChef.Core;
|
||||||
using Mono.Options;
|
|
||||||
|
|
||||||
namespace DiscImageChef.Commands
|
namespace DiscImageChef.Commands
|
||||||
{
|
{
|
||||||
class PrintHexCommand : Command
|
internal class PrintHexCommand : Command
|
||||||
{
|
{
|
||||||
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.")
|
public PrintHexCommand() : base("printhex", "Prints a sector, in hexadecimal values, to the console.")
|
||||||
{
|
{
|
||||||
Options = new OptionSet
|
Add(new Option(new[]
|
||||||
{
|
{
|
||||||
$"{MainClass.AssemblyTitle} {MainClass.AssemblyVersion?.InformationalVersion}",
|
"--length", "-l"
|
||||||
$"{MainClass.AssemblyCopyright}",
|
}, "How many sectors to print.")
|
||||||
"",
|
{
|
||||||
$"usage: DiscImageChef {Name} [OPTIONS] imagefile",
|
Argument = new Argument<ulong>(() => 1), Required = false
|
||||||
"",
|
});
|
||||||
Help,
|
|
||||||
{"length|l=", "How many sectors to print.", (ulong ul) => length = ul},
|
Add(new Option(new[]
|
||||||
{"long-sectors|r", "Print sectors with tags included.", b => longSectors = b != null},
|
{
|
||||||
{"start|s=", "Name of character encoding to use.", (ulong ul) => startSector = ul},
|
"--long-sectors", "-r"
|
||||||
{"width|w=", "How many bytes to print per line.", (ushort us) => widthBytes = us},
|
}, "Print sectors with tags included.")
|
||||||
{"help|h|?", "Show this message and exit.", v => showHelp = v != null}
|
{
|
||||||
};
|
Argument = new Argument<bool>(() => false), Required = false
|
||||||
|
});
|
||||||
|
|
||||||
|
Add(new Option(new[]
|
||||||
|
{
|
||||||
|
"--start", "-s"
|
||||||
|
}, "Starting sector.")
|
||||||
|
{
|
||||||
|
Argument = new Argument<ulong>(), Required = true
|
||||||
|
});
|
||||||
|
|
||||||
|
Add(new Option(new[]
|
||||||
|
{
|
||||||
|
"--width", "-w"
|
||||||
|
}, "How many bytes to print per line.")
|
||||||
|
{
|
||||||
|
Argument = new Argument<ushort>(() => 32), Required = false
|
||||||
|
});
|
||||||
|
|
||||||
|
AddArgument(new Argument<string>
|
||||||
|
{
|
||||||
|
Arity = ArgumentArity.ExactlyOne, Description = "Media image path", Name = "image-path"
|
||||||
|
});
|
||||||
|
|
||||||
|
Handler = CommandHandler.Create(GetType().GetMethod(nameof(Invoke)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override int Invoke(IEnumerable<string> arguments)
|
static int Invoke(bool debug, bool verbose, string imagePath, ulong length, bool longSectors, ulong startSector,
|
||||||
|
ushort widthBytes)
|
||||||
{
|
{
|
||||||
List<string> extra = Options.Parse(arguments);
|
|
||||||
|
|
||||||
if(showHelp)
|
|
||||||
{
|
|
||||||
Options.WriteOptionDescriptions(CommandSet.Out);
|
|
||||||
return (int)ErrorNumber.HelpRequested;
|
|
||||||
}
|
|
||||||
|
|
||||||
MainClass.PrintCopyright();
|
MainClass.PrintCopyright();
|
||||||
if(MainClass.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
|
||||||
if(MainClass.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
if(debug)
|
||||||
|
DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
||||||
|
|
||||||
|
if(verbose)
|
||||||
|
DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
||||||
|
|
||||||
Statistics.AddCommand("print-hex");
|
Statistics.AddCommand("print-hex");
|
||||||
|
|
||||||
if(extra.Count > 1)
|
DicConsole.DebugWriteLine("PrintHex command", "--debug={0}", debug);
|
||||||
{
|
DicConsole.DebugWriteLine("PrintHex command", "--input={0}", imagePath);
|
||||||
DicConsole.ErrorWriteLine("Too many arguments.");
|
|
||||||
return (int)ErrorNumber.UnexpectedArgumentCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(extra.Count == 0)
|
|
||||||
{
|
|
||||||
DicConsole.ErrorWriteLine("Missing input image.");
|
|
||||||
return (int)ErrorNumber.MissingArgument;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(startSector is null)
|
|
||||||
{
|
|
||||||
DicConsole.ErrorWriteLine("Missing starting sector.");
|
|
||||||
return (int)ErrorNumber.MissingArgument;
|
|
||||||
}
|
|
||||||
|
|
||||||
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", "--length={0}", length);
|
||||||
DicConsole.DebugWriteLine("PrintHex command", "--long-sectors={0}", longSectors);
|
DicConsole.DebugWriteLine("PrintHex command", "--long-sectors={0}", longSectors);
|
||||||
DicConsole.DebugWriteLine("PrintHex command", "--start={0}", startSector);
|
DicConsole.DebugWriteLine("PrintHex command", "--start={0}", startSector);
|
||||||
DicConsole.DebugWriteLine("PrintHex command", "--verbose={0}", MainClass.Verbose);
|
DicConsole.DebugWriteLine("PrintHex command", "--verbose={0}", verbose);
|
||||||
DicConsole.DebugWriteLine("PrintHex command", "--WidthBytes={0}", widthBytes);
|
DicConsole.DebugWriteLine("PrintHex command", "--WidthBytes={0}", widthBytes);
|
||||||
|
|
||||||
FiltersList filtersList = new FiltersList();
|
var filtersList = new FiltersList();
|
||||||
IFilter inputFilter = filtersList.GetFilter(inputFile);
|
IFilter inputFilter = filtersList.GetFilter(imagePath);
|
||||||
|
|
||||||
if(inputFilter == null)
|
if(inputFilter == null)
|
||||||
{
|
{
|
||||||
DicConsole.ErrorWriteLine("Cannot open specified file.");
|
DicConsole.ErrorWriteLine("Cannot open specified file.");
|
||||||
return (int)ErrorNumber.CannotOpenFile;
|
|
||||||
|
return(int)ErrorNumber.CannotOpenFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
IMediaImage inputFormat = ImageFormat.Detect(inputFilter);
|
IMediaImage inputFormat = ImageFormat.Detect(inputFilter);
|
||||||
@@ -124,7 +120,8 @@ namespace DiscImageChef.Commands
|
|||||||
if(inputFormat == null)
|
if(inputFormat == null)
|
||||||
{
|
{
|
||||||
DicConsole.ErrorWriteLine("Unable to recognize image format, not verifying");
|
DicConsole.ErrorWriteLine("Unable to recognize image format, not verifying");
|
||||||
return (int)ErrorNumber.UnrecognizedFormat;
|
|
||||||
|
return(int)ErrorNumber.UnrecognizedFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
inputFormat.Open(inputFilter);
|
inputFormat.Open(inputFilter);
|
||||||
@@ -135,28 +132,29 @@ namespace DiscImageChef.Commands
|
|||||||
|
|
||||||
if(inputFormat.Info.ReadableSectorTags == null)
|
if(inputFormat.Info.ReadableSectorTags == null)
|
||||||
{
|
{
|
||||||
DicConsole
|
DicConsole.
|
||||||
.WriteLine("Requested sectors with tags, unsupported by underlying image format, printing only user data.");
|
WriteLine("Requested sectors with tags, unsupported by underlying image format, printing only user data.");
|
||||||
|
|
||||||
longSectors = false;
|
longSectors = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(inputFormat.Info.ReadableSectorTags.Count == 0)
|
if(inputFormat.Info.ReadableSectorTags.Count == 0)
|
||||||
{
|
{
|
||||||
DicConsole
|
DicConsole.
|
||||||
.WriteLine("Requested sectors with tags, unsupported by underlying image format, printing only user data.");
|
WriteLine("Requested sectors with tags, unsupported by underlying image format, printing only user data.");
|
||||||
|
|
||||||
longSectors = false;
|
longSectors = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
byte[] sector = longSectors
|
byte[] sector = longSectors ? inputFormat.ReadSectorLong(startSector + i)
|
||||||
? inputFormat.ReadSectorLong(startSector.Value + i)
|
: inputFormat.ReadSector(startSector + i);
|
||||||
: inputFormat.ReadSector(startSector.Value + i);
|
|
||||||
|
|
||||||
PrintHex.PrintHexArray(sector, widthBytes);
|
PrintHex.PrintHexArray(sector, widthBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (int)ErrorNumber.NoError;
|
return(int)ErrorNumber.NoError;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -33,71 +33,42 @@
|
|||||||
// TODO: Fix errors returned
|
// TODO: Fix errors returned
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.CommandLine;
|
||||||
|
using System.CommandLine.Invocation;
|
||||||
using DiscImageChef.CommonTypes.Enums;
|
using DiscImageChef.CommonTypes.Enums;
|
||||||
using DiscImageChef.Console;
|
using DiscImageChef.Console;
|
||||||
using DiscImageChef.Core;
|
using DiscImageChef.Core;
|
||||||
using Mono.Options;
|
|
||||||
using Remote = DiscImageChef.Devices.Remote.Remote;
|
using Remote = DiscImageChef.Devices.Remote.Remote;
|
||||||
|
|
||||||
namespace DiscImageChef.Commands
|
namespace DiscImageChef.Commands
|
||||||
{
|
{
|
||||||
internal class RemoteCommand : Command
|
internal class RemoteCommand : Command
|
||||||
{
|
{
|
||||||
string host;
|
public RemoteCommand() : base("remote", "Tests connection to a DiscImageChef Remote Server.")
|
||||||
bool showHelp;
|
|
||||||
|
|
||||||
public RemoteCommand() : base("remote", "Tests connection to a DiscImageChef Remote Server.") =>
|
|
||||||
Options = new OptionSet
|
|
||||||
{
|
{
|
||||||
$"{MainClass.AssemblyTitle} {MainClass.AssemblyVersion?.InformationalVersion}",
|
AddArgument(new Argument<string>
|
||||||
$"{MainClass.AssemblyCopyright}", "", $"usage: DiscImageChef {Name} [OPTIONS] host", "",
|
|
||||||
Help,
|
|
||||||
{
|
{
|
||||||
"help|h|?", "Show this message and exit.", v => showHelp = v != null
|
Arity = ArgumentArity.ExactlyOne, Description = "dicremote host", Name = "host"
|
||||||
}
|
});
|
||||||
};
|
|
||||||
|
|
||||||
public override int Invoke(IEnumerable<string> arguments)
|
Handler = CommandHandler.Create(GetType().GetMethod(nameof(Invoke)));
|
||||||
{
|
|
||||||
List<string> extra = Options.Parse(arguments);
|
|
||||||
|
|
||||||
if(showHelp)
|
|
||||||
{
|
|
||||||
Options.WriteOptionDescriptions(CommandSet.Out);
|
|
||||||
|
|
||||||
return(int)ErrorNumber.HelpRequested;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int Invoke(bool debug, bool verbose, string host)
|
||||||
|
{
|
||||||
MainClass.PrintCopyright();
|
MainClass.PrintCopyright();
|
||||||
|
|
||||||
if(MainClass.Debug)
|
if(debug)
|
||||||
DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
||||||
|
|
||||||
if(MainClass.Verbose)
|
if(verbose)
|
||||||
DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
||||||
|
|
||||||
// Statistics.AddCommand("remote");
|
Statistics.AddCommand("remote");
|
||||||
|
|
||||||
if(extra.Count > 1)
|
DicConsole.DebugWriteLine("Remote command", "--debug={0}", debug);
|
||||||
{
|
|
||||||
DicConsole.ErrorWriteLine("Too many arguments.");
|
|
||||||
|
|
||||||
return(int)ErrorNumber.UnexpectedArgumentCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(extra.Count == 0)
|
|
||||||
{
|
|
||||||
DicConsole.ErrorWriteLine("Missing input image.");
|
|
||||||
|
|
||||||
return(int)ErrorNumber.MissingArgument;
|
|
||||||
}
|
|
||||||
|
|
||||||
host = extra[0];
|
|
||||||
|
|
||||||
DicConsole.DebugWriteLine("Remote command", "--debug={0}", MainClass.Debug);
|
|
||||||
DicConsole.DebugWriteLine("Remote command", "--host={0}", host);
|
DicConsole.DebugWriteLine("Remote command", "--host={0}", host);
|
||||||
DicConsole.DebugWriteLine("Remote command", "--verbose={0}", MainClass.Verbose);
|
DicConsole.DebugWriteLine("Remote command", "--verbose={0}", verbose);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -30,62 +30,44 @@
|
|||||||
// Copyright © 2011-2019 Natalia Portillo
|
// Copyright © 2011-2019 Natalia Portillo
|
||||||
// ****************************************************************************/
|
// ****************************************************************************/
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.CommandLine.Invocation;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using DiscImageChef.CommonTypes.Enums;
|
using DiscImageChef.CommonTypes.Enums;
|
||||||
using DiscImageChef.Console;
|
using DiscImageChef.Console;
|
||||||
using DiscImageChef.Database;
|
using DiscImageChef.Database;
|
||||||
using DiscImageChef.Database.Models;
|
using DiscImageChef.Database.Models;
|
||||||
using Mono.Options;
|
using Command = System.CommandLine.Command;
|
||||||
using Command = Mono.Options.Command;
|
|
||||||
|
|
||||||
namespace DiscImageChef.Commands
|
namespace DiscImageChef.Commands
|
||||||
{
|
{
|
||||||
class StatisticsCommand : Command
|
internal class StatisticsCommand : Command
|
||||||
{
|
{
|
||||||
bool showHelp;
|
public StatisticsCommand() : base("stats", "Shows statistics.") =>
|
||||||
|
Handler = CommandHandler.Create(GetType().GetMethod(nameof(Invoke)));
|
||||||
|
|
||||||
public StatisticsCommand() : base("stats", "Shows statistics.")
|
static int Invoke(bool debug, bool verbose)
|
||||||
{
|
{
|
||||||
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 (int)ErrorNumber.HelpRequested;
|
|
||||||
}
|
|
||||||
|
|
||||||
MainClass.PrintCopyright();
|
MainClass.PrintCopyright();
|
||||||
if(MainClass.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
|
||||||
if(MainClass.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
|
||||||
|
|
||||||
if(extra.Count > 0)
|
if(debug)
|
||||||
{
|
DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
||||||
DicConsole.ErrorWriteLine("Too many arguments.");
|
|
||||||
return (int)ErrorNumber.UnexpectedArgumentCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
DicContext ctx = DicContext.Create(Settings.Settings.LocalDbPath);
|
if(verbose)
|
||||||
|
DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
||||||
|
|
||||||
if(!ctx.Commands.Any() && !ctx.Filesystems.Any() && !ctx.Filters.Any() && !ctx.MediaFormats.Any() &&
|
var ctx = DicContext.Create(Settings.Settings.LocalDbPath);
|
||||||
!ctx.Medias.Any() && !ctx.Partitions.Any() && !ctx.SeenDevices.Any())
|
|
||||||
|
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.");
|
DicConsole.WriteLine("There are no statistics.");
|
||||||
return (int)ErrorNumber.NothingFound;
|
|
||||||
|
return(int)ErrorNumber.NothingFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool thereAreStats = false;
|
bool thereAreStats = false;
|
||||||
@@ -97,11 +79,13 @@ namespace DiscImageChef.Commands
|
|||||||
|
|
||||||
foreach(string command in ctx.Commands.OrderBy(c => c.Name).Select(c => c.Name).Distinct())
|
foreach(string command in ctx.Commands.OrderBy(c => c.Name).Select(c => c.Name).Distinct())
|
||||||
{
|
{
|
||||||
ulong count = ctx.Commands.Where(c => c.Name == command && c.Synchronized).Select(c => c.Count)
|
ulong count = ctx.Commands.Where(c => c.Name == command && c.Synchronized).Select(c => c.Count).
|
||||||
.FirstOrDefault();
|
FirstOrDefault();
|
||||||
|
|
||||||
count += (ulong)ctx.Commands.LongCount(c => c.Name == command && !c.Synchronized);
|
count += (ulong)ctx.Commands.LongCount(c => c.Name == command && !c.Synchronized);
|
||||||
|
|
||||||
if(count == 0) continue;
|
if(count == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
DicConsole.WriteLine("You have called the {0} command {1} times.", command, count);
|
DicConsole.WriteLine("You have called the {0} command {1} times.", command, count);
|
||||||
thereAreStats = true;
|
thereAreStats = true;
|
||||||
@@ -117,11 +101,13 @@ namespace DiscImageChef.Commands
|
|||||||
|
|
||||||
foreach(string filter in ctx.Filters.OrderBy(c => c.Name).Select(c => c.Name).Distinct())
|
foreach(string filter in ctx.Filters.OrderBy(c => c.Name).Select(c => c.Name).Distinct())
|
||||||
{
|
{
|
||||||
ulong count = ctx.Filters.Where(c => c.Name == filter && c.Synchronized).Select(c => c.Count)
|
ulong count = ctx.Filters.Where(c => c.Name == filter && c.Synchronized).Select(c => c.Count).
|
||||||
.FirstOrDefault();
|
FirstOrDefault();
|
||||||
|
|
||||||
count += (ulong)ctx.Filters.LongCount(c => c.Name == filter && !c.Synchronized);
|
count += (ulong)ctx.Filters.LongCount(c => c.Name == filter && !c.Synchronized);
|
||||||
|
|
||||||
if(count == 0) continue;
|
if(count == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
DicConsole.WriteLine("Filter {0} has been found {1} times.", filter, count);
|
DicConsole.WriteLine("Filter {0} has been found {1} times.", filter, count);
|
||||||
thereAreStats = true;
|
thereAreStats = true;
|
||||||
@@ -137,11 +123,13 @@ namespace DiscImageChef.Commands
|
|||||||
|
|
||||||
foreach(string format in ctx.MediaFormats.OrderBy(c => c.Name).Select(c => c.Name).Distinct())
|
foreach(string format in ctx.MediaFormats.OrderBy(c => c.Name).Select(c => c.Name).Distinct())
|
||||||
{
|
{
|
||||||
ulong count = ctx.MediaFormats.Where(c => c.Name == format && c.Synchronized).Select(c => c.Count)
|
ulong count = ctx.MediaFormats.Where(c => c.Name == format && c.Synchronized).Select(c => c.Count).
|
||||||
.FirstOrDefault();
|
FirstOrDefault();
|
||||||
|
|
||||||
count += (ulong)ctx.MediaFormats.LongCount(c => c.Name == format && !c.Synchronized);
|
count += (ulong)ctx.MediaFormats.LongCount(c => c.Name == format && !c.Synchronized);
|
||||||
|
|
||||||
if(count == 0) continue;
|
if(count == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
DicConsole.WriteLine("Format {0} has been found {1} times.", format, count);
|
DicConsole.WriteLine("Format {0} has been found {1} times.", format, count);
|
||||||
thereAreStats = true;
|
thereAreStats = true;
|
||||||
@@ -157,11 +145,13 @@ namespace DiscImageChef.Commands
|
|||||||
|
|
||||||
foreach(string partition in ctx.Partitions.OrderBy(c => c.Name).Select(c => c.Name).Distinct())
|
foreach(string partition in ctx.Partitions.OrderBy(c => c.Name).Select(c => c.Name).Distinct())
|
||||||
{
|
{
|
||||||
ulong count = ctx.Partitions.Where(c => c.Name == partition && c.Synchronized).Select(c => c.Count)
|
ulong count = ctx.Partitions.Where(c => c.Name == partition && c.Synchronized).Select(c => c.Count).
|
||||||
.FirstOrDefault();
|
FirstOrDefault();
|
||||||
|
|
||||||
count += (ulong)ctx.Partitions.LongCount(c => c.Name == partition && !c.Synchronized);
|
count += (ulong)ctx.Partitions.LongCount(c => c.Name == partition && !c.Synchronized);
|
||||||
|
|
||||||
if(count == 0) continue;
|
if(count == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
DicConsole.WriteLine("Partitioning scheme {0} has been found {1} times.", partition, count);
|
DicConsole.WriteLine("Partitioning scheme {0} has been found {1} times.", partition, count);
|
||||||
thereAreStats = true;
|
thereAreStats = true;
|
||||||
@@ -177,11 +167,13 @@ namespace DiscImageChef.Commands
|
|||||||
|
|
||||||
foreach(string filesystem in ctx.Filesystems.OrderBy(c => c.Name).Select(c => c.Name).Distinct())
|
foreach(string filesystem in ctx.Filesystems.OrderBy(c => c.Name).Select(c => c.Name).Distinct())
|
||||||
{
|
{
|
||||||
ulong count = ctx.Filesystems.Where(c => c.Name == filesystem && c.Synchronized)
|
ulong count = ctx.Filesystems.Where(c => c.Name == filesystem && c.Synchronized).
|
||||||
.Select(c => c.Count).FirstOrDefault();
|
Select(c => c.Count).FirstOrDefault();
|
||||||
|
|
||||||
count += (ulong)ctx.Filesystems.LongCount(c => c.Name == filesystem && !c.Synchronized);
|
count += (ulong)ctx.Filesystems.LongCount(c => c.Name == filesystem && !c.Synchronized);
|
||||||
|
|
||||||
if(count == 0) continue;
|
if(count == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
DicConsole.WriteLine("Filesystem {0} has been found {1} times.", filesystem, count);
|
DicConsole.WriteLine("Filesystem {0} has been found {1} times.", filesystem, count);
|
||||||
thereAreStats = true;
|
thereAreStats = true;
|
||||||
@@ -195,10 +187,10 @@ namespace DiscImageChef.Commands
|
|||||||
DicConsole.WriteLine("Device statistics");
|
DicConsole.WriteLine("Device statistics");
|
||||||
DicConsole.WriteLine("=================");
|
DicConsole.WriteLine("=================");
|
||||||
|
|
||||||
foreach(DeviceStat ds in ctx.SeenDevices.OrderBy(ds => ds.Manufacturer).ThenBy(ds => ds.Model)
|
foreach(DeviceStat ds in ctx.SeenDevices.OrderBy(ds => ds.Manufacturer).ThenBy(ds => ds.Model).
|
||||||
.ThenBy(ds => ds.Revision).ThenBy(ds => ds.Bus))
|
ThenBy(ds => ds.Revision).ThenBy(ds => ds.Bus))
|
||||||
DicConsole
|
DicConsole.
|
||||||
.WriteLine("Device model {0}, manufactured by {1}, with revision {2} and attached via {3}.",
|
WriteLine("Device model {0}, manufactured by {1}, with revision {2} and attached via {3}.",
|
||||||
ds.Model, ds.Manufacturer, ds.Revision, ds.Bus);
|
ds.Model, ds.Manufacturer, ds.Revision, ds.Bus);
|
||||||
|
|
||||||
DicConsole.WriteLine();
|
DicConsole.WriteLine();
|
||||||
@@ -212,8 +204,9 @@ namespace DiscImageChef.Commands
|
|||||||
|
|
||||||
foreach(string media in ctx.Medias.OrderBy(ms => ms.Type).Select(ms => ms.Type).Distinct())
|
foreach(string media in ctx.Medias.OrderBy(ms => ms.Type).Select(ms => ms.Type).Distinct())
|
||||||
{
|
{
|
||||||
ulong count = ctx.Medias.Where(c => c.Type == media && c.Synchronized && c.Real)
|
ulong count = ctx.Medias.Where(c => c.Type == media && c.Synchronized && c.Real).
|
||||||
.Select(c => c.Count).FirstOrDefault();
|
Select(c => c.Count).FirstOrDefault();
|
||||||
|
|
||||||
count += (ulong)ctx.Medias.LongCount(c => c.Type == media && !c.Synchronized && c.Real);
|
count += (ulong)ctx.Medias.LongCount(c => c.Type == media && !c.Synchronized && c.Real);
|
||||||
|
|
||||||
if(count > 0)
|
if(count > 0)
|
||||||
@@ -222,11 +215,13 @@ namespace DiscImageChef.Commands
|
|||||||
thereAreStats = true;
|
thereAreStats = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
count = ctx.Medias.Where(c => c.Type == media && c.Synchronized && !c.Real).Select(c => c.Count)
|
count = ctx.Medias.Where(c => c.Type == media && c.Synchronized && !c.Real).Select(c => c.Count).
|
||||||
.FirstOrDefault();
|
FirstOrDefault();
|
||||||
|
|
||||||
count += (ulong)ctx.Medias.LongCount(c => c.Type == media && !c.Synchronized && !c.Real);
|
count += (ulong)ctx.Medias.LongCount(c => c.Type == media && !c.Synchronized && !c.Real);
|
||||||
|
|
||||||
if(count == 0) continue;
|
if(count == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
DicConsole.WriteLine("Media type {0} has been found {1} times in a media image.", media, count);
|
DicConsole.WriteLine("Media type {0} has been found {1} times in a media image.", media, count);
|
||||||
thereAreStats = true;
|
thereAreStats = true;
|
||||||
@@ -235,8 +230,10 @@ namespace DiscImageChef.Commands
|
|||||||
DicConsole.WriteLine();
|
DicConsole.WriteLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!thereAreStats) DicConsole.WriteLine("There are no statistics.");
|
if(!thereAreStats)
|
||||||
return (int)ErrorNumber.NoError;
|
DicConsole.WriteLine("There are no statistics.");
|
||||||
|
|
||||||
|
return(int)ErrorNumber.NoError;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -30,62 +30,44 @@
|
|||||||
// Copyright © 2011-2019 Natalia Portillo
|
// Copyright © 2011-2019 Natalia Portillo
|
||||||
// ****************************************************************************/
|
// ****************************************************************************/
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.CommandLine;
|
||||||
|
using System.CommandLine.Invocation;
|
||||||
using DiscImageChef.CommonTypes.Enums;
|
using DiscImageChef.CommonTypes.Enums;
|
||||||
using DiscImageChef.Console;
|
using DiscImageChef.Console;
|
||||||
using DiscImageChef.Core;
|
using DiscImageChef.Core;
|
||||||
using Mono.Options;
|
|
||||||
|
|
||||||
namespace DiscImageChef.Commands
|
namespace DiscImageChef.Commands
|
||||||
{
|
{
|
||||||
class UpdateCommand : Command
|
internal class UpdateCommand : Command
|
||||||
{
|
{
|
||||||
readonly bool masterDbUpdate;
|
readonly bool _masterDbUpdate;
|
||||||
bool showHelp;
|
|
||||||
|
|
||||||
public UpdateCommand(bool masterDbUpdate) : base("update", "Updates the database.")
|
public UpdateCommand(bool masterDbUpdate) : base("update", "Updates the database.")
|
||||||
{
|
{
|
||||||
this.masterDbUpdate = masterDbUpdate;
|
_masterDbUpdate = masterDbUpdate;
|
||||||
Options = new OptionSet
|
|
||||||
{
|
Handler = CommandHandler.Create(GetType().GetMethod(nameof(Invoke)));
|
||||||
$"{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)
|
int Invoke(bool debug, bool verbose)
|
||||||
{
|
{
|
||||||
if(masterDbUpdate) return (int)ErrorNumber.NoError;
|
if(_masterDbUpdate)
|
||||||
|
return(int)ErrorNumber.NoError;
|
||||||
List<string> extra = Options.Parse(arguments);
|
|
||||||
|
|
||||||
if(showHelp)
|
|
||||||
{
|
|
||||||
Options.WriteOptionDescriptions(CommandSet.Out);
|
|
||||||
return (int)ErrorNumber.HelpRequested;
|
|
||||||
}
|
|
||||||
|
|
||||||
MainClass.PrintCopyright();
|
MainClass.PrintCopyright();
|
||||||
if(MainClass.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
|
||||||
if(MainClass.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
|
||||||
|
|
||||||
if(extra.Count > 0)
|
if(debug)
|
||||||
{
|
DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
||||||
DicConsole.ErrorWriteLine("Too many arguments.");
|
|
||||||
return (int)ErrorNumber.UnexpectedArgumentCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
DicConsole.DebugWriteLine("Update command", "--debug={0}", MainClass.Debug);
|
if(verbose)
|
||||||
DicConsole.DebugWriteLine("Update command", "--verbose={0}", MainClass.Verbose);
|
DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
||||||
|
|
||||||
|
DicConsole.DebugWriteLine("Update command", "--debug={0}", debug);
|
||||||
|
DicConsole.DebugWriteLine("Update command", "--verbose={0}", verbose);
|
||||||
|
|
||||||
DoUpdate(false);
|
DoUpdate(false);
|
||||||
|
|
||||||
return (int)ErrorNumber.NoError;
|
return(int)ErrorNumber.NoError;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void DoUpdate(bool create)
|
internal static void DoUpdate(bool create)
|
||||||
|
|||||||
@@ -32,81 +32,71 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.CommandLine;
|
||||||
|
using System.CommandLine.Invocation;
|
||||||
using DiscImageChef.CommonTypes;
|
using DiscImageChef.CommonTypes;
|
||||||
using DiscImageChef.CommonTypes.Enums;
|
using DiscImageChef.CommonTypes.Enums;
|
||||||
using DiscImageChef.CommonTypes.Interfaces;
|
using DiscImageChef.CommonTypes.Interfaces;
|
||||||
using DiscImageChef.CommonTypes.Structs;
|
using DiscImageChef.CommonTypes.Structs;
|
||||||
using DiscImageChef.Console;
|
using DiscImageChef.Console;
|
||||||
using DiscImageChef.Core;
|
using DiscImageChef.Core;
|
||||||
using Mono.Options;
|
|
||||||
|
|
||||||
namespace DiscImageChef.Commands
|
namespace DiscImageChef.Commands
|
||||||
{
|
{
|
||||||
class VerifyCommand : Command
|
internal class VerifyCommand : Command
|
||||||
{
|
{
|
||||||
string inputFile;
|
|
||||||
bool showHelp;
|
|
||||||
bool verifyDisc = true;
|
|
||||||
bool verifySectors = true;
|
|
||||||
|
|
||||||
public VerifyCommand() : base("verify", "Verifies a disc image integrity, and if supported, sector integrity.")
|
public VerifyCommand() : base("verify", "Verifies a disc image integrity, and if supported, sector integrity.")
|
||||||
{
|
{
|
||||||
Options = new OptionSet
|
Add(new Option(new[]
|
||||||
{
|
{
|
||||||
$"{MainClass.AssemblyTitle} {MainClass.AssemblyVersion?.InformationalVersion}",
|
"--verify-disc", "-w"
|
||||||
$"{MainClass.AssemblyCopyright}",
|
}, "Verify disc image if supported.")
|
||||||
"",
|
{
|
||||||
$"usage: DiscImageChef {Name} [OPTIONS] imagefile",
|
Argument = new Argument<bool>(() => true), Required = false
|
||||||
"",
|
});
|
||||||
Help,
|
|
||||||
{"verify-disc|w", "Verify disc image if supported.", b => verifyDisc = b != null},
|
Add(new Option(new[]
|
||||||
{"verify-sectors|s", "Verify all sectors if supported.", b => verifySectors = b != null},
|
{
|
||||||
{"help|h|?", "Show this message and exit.", v => showHelp = v != null}
|
"--verify-sectors", "-s"
|
||||||
};
|
}, "Verify all sectors if supported.")
|
||||||
|
{
|
||||||
|
Argument = new Argument<bool>(() => true), Required = false
|
||||||
|
});
|
||||||
|
|
||||||
|
AddArgument(new Argument<string>
|
||||||
|
{
|
||||||
|
Arity = ArgumentArity.ExactlyOne, Description = "Disc image path", Name = "image-path"
|
||||||
|
});
|
||||||
|
|
||||||
|
Handler = CommandHandler.Create(GetType().GetMethod(nameof(Invoke)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override int Invoke(IEnumerable<string> arguments)
|
static int Invoke(bool debug, bool verbose, string imagePath, bool verifyDisc = true, bool verifySectors = true)
|
||||||
{
|
{
|
||||||
List<string> extra = Options.Parse(arguments);
|
|
||||||
|
|
||||||
if(showHelp)
|
|
||||||
{
|
|
||||||
Options.WriteOptionDescriptions(CommandSet.Out);
|
|
||||||
return (int)ErrorNumber.HelpRequested;
|
|
||||||
}
|
|
||||||
|
|
||||||
MainClass.PrintCopyright();
|
MainClass.PrintCopyright();
|
||||||
if(MainClass.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
|
||||||
if(MainClass.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
if(debug)
|
||||||
|
DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine;
|
||||||
|
|
||||||
|
if(verbose)
|
||||||
|
DicConsole.VerboseWriteLineEvent += System.Console.WriteLine;
|
||||||
|
|
||||||
Statistics.AddCommand("verify");
|
Statistics.AddCommand("verify");
|
||||||
|
|
||||||
if(extra.Count > 1)
|
DicConsole.DebugWriteLine("Verify command", "--debug={0}", debug);
|
||||||
{
|
DicConsole.DebugWriteLine("Verify command", "--input={0}", imagePath);
|
||||||
DicConsole.ErrorWriteLine("Too many arguments.");
|
DicConsole.DebugWriteLine("Verify command", "--verbose={0}", verbose);
|
||||||
return (int)ErrorNumber.UnexpectedArgumentCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(extra.Count == 0)
|
|
||||||
{
|
|
||||||
DicConsole.ErrorWriteLine("Missing input image.");
|
|
||||||
return (int)ErrorNumber.MissingArgument;
|
|
||||||
}
|
|
||||||
|
|
||||||
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-disc={0}", verifyDisc);
|
||||||
DicConsole.DebugWriteLine("Verify command", "--verify-sectors={0}", verifySectors);
|
DicConsole.DebugWriteLine("Verify command", "--verify-sectors={0}", verifySectors);
|
||||||
|
|
||||||
FiltersList filtersList = new FiltersList();
|
var filtersList = new FiltersList();
|
||||||
IFilter inputFilter = filtersList.GetFilter(inputFile);
|
IFilter inputFilter = filtersList.GetFilter(imagePath);
|
||||||
|
|
||||||
if(inputFilter == null)
|
if(inputFilter == null)
|
||||||
{
|
{
|
||||||
DicConsole.ErrorWriteLine("Cannot open specified file.");
|
DicConsole.ErrorWriteLine("Cannot open specified file.");
|
||||||
return (int)ErrorNumber.CannotOpenFile;
|
|
||||||
|
return(int)ErrorNumber.CannotOpenFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
IMediaImage inputFormat = ImageFormat.Detect(inputFilter);
|
IMediaImage inputFormat = ImageFormat.Detect(inputFilter);
|
||||||
@@ -114,7 +104,8 @@ namespace DiscImageChef.Commands
|
|||||||
if(inputFormat == null)
|
if(inputFormat == null)
|
||||||
{
|
{
|
||||||
DicConsole.ErrorWriteLine("Unable to recognize image format, not verifying");
|
DicConsole.ErrorWriteLine("Unable to recognize image format, not verifying");
|
||||||
return (int)ErrorNumber.FormatNotFound;
|
|
||||||
|
return(int)ErrorNumber.FormatNotFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
inputFormat.Open(inputFilter);
|
inputFormat.Open(inputFilter);
|
||||||
@@ -123,18 +114,19 @@ namespace DiscImageChef.Commands
|
|||||||
Statistics.AddFilter(inputFilter.Name);
|
Statistics.AddFilter(inputFilter.Name);
|
||||||
|
|
||||||
bool? correctImage = null;
|
bool? correctImage = null;
|
||||||
long totalSectors = 0;
|
|
||||||
long errorSectors = 0;
|
long errorSectors = 0;
|
||||||
bool? correctSectors = null;
|
bool? correctSectors = null;
|
||||||
long unknownSectors = 0;
|
long unknownSectors = 0;
|
||||||
|
|
||||||
IVerifiableImage verifiableImage = inputFormat as IVerifiableImage;
|
var verifiableImage = inputFormat as IVerifiableImage;
|
||||||
IVerifiableSectorsImage verifiableSectorsImage = inputFormat as IVerifiableSectorsImage;
|
var verifiableSectorsImage = inputFormat as IVerifiableSectorsImage;
|
||||||
|
|
||||||
if(verifiableImage is null && verifiableSectorsImage is null)
|
if(verifiableImage is null &&
|
||||||
|
verifiableSectorsImage is null)
|
||||||
{
|
{
|
||||||
DicConsole.ErrorWriteLine("The specified image does not support any kind of verification");
|
DicConsole.ErrorWriteLine("The specified image does not support any kind of verification");
|
||||||
return (int)ErrorNumber.NotVerificable;
|
|
||||||
|
return(int)ErrorNumber.NotVerificable;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(verifyDisc && verifiableImage != null)
|
if(verifyDisc && verifiableImage != null)
|
||||||
@@ -149,12 +141,15 @@ namespace DiscImageChef.Commands
|
|||||||
{
|
{
|
||||||
case true:
|
case true:
|
||||||
DicConsole.WriteLine("Disc image checksums are correct");
|
DicConsole.WriteLine("Disc image checksums are correct");
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case false:
|
case false:
|
||||||
DicConsole.WriteLine("Disc image checksums are incorrect");
|
DicConsole.WriteLine("Disc image checksums are incorrect");
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case null:
|
case null:
|
||||||
DicConsole.WriteLine("Disc image does not contain checksums");
|
DicConsole.WriteLine("Disc image does not contain checksums");
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -175,6 +170,7 @@ namespace DiscImageChef.Commands
|
|||||||
ulong currentSectorAll = 0;
|
ulong currentSectorAll = 0;
|
||||||
|
|
||||||
startCheck = DateTime.UtcNow;
|
startCheck = DateTime.UtcNow;
|
||||||
|
|
||||||
foreach(Track currentTrack in inputTracks)
|
foreach(Track currentTrack in inputTracks)
|
||||||
{
|
{
|
||||||
ulong remainingSectors = currentTrack.TrackEndSector - currentTrack.TrackStartSector;
|
ulong remainingSectors = currentTrack.TrackEndSector - currentTrack.TrackStartSector;
|
||||||
@@ -185,20 +181,20 @@ namespace DiscImageChef.Commands
|
|||||||
DicConsole.Write("\rChecking sector {0} of {1}, on track {2}", currentSectorAll,
|
DicConsole.Write("\rChecking sector {0} of {1}, on track {2}", currentSectorAll,
|
||||||
inputFormat.Info.Sectors, currentTrack.TrackSequence);
|
inputFormat.Info.Sectors, currentTrack.TrackSequence);
|
||||||
|
|
||||||
List<ulong> tempfailingLbas;
|
List<ulong> tempFailingLbas;
|
||||||
List<ulong> tempunknownLbas;
|
List<ulong> tempUnknownLbas;
|
||||||
|
|
||||||
if(remainingSectors < 512)
|
if(remainingSectors < 512)
|
||||||
opticalMediaImage.VerifySectors(currentSector, (uint)remainingSectors,
|
opticalMediaImage.VerifySectors(currentSector, (uint)remainingSectors,
|
||||||
currentTrack.TrackSequence, out tempfailingLbas,
|
currentTrack.TrackSequence, out tempFailingLbas,
|
||||||
out tempunknownLbas);
|
out tempUnknownLbas);
|
||||||
else
|
else
|
||||||
opticalMediaImage.VerifySectors(currentSector, 512, currentTrack.TrackSequence,
|
opticalMediaImage.VerifySectors(currentSector, 512, currentTrack.TrackSequence,
|
||||||
out tempfailingLbas, out tempunknownLbas);
|
out tempFailingLbas, out tempUnknownLbas);
|
||||||
|
|
||||||
failingLbas.AddRange(tempfailingLbas);
|
failingLbas.AddRange(tempFailingLbas);
|
||||||
|
|
||||||
unknownLbas.AddRange(tempunknownLbas);
|
unknownLbas.AddRange(tempUnknownLbas);
|
||||||
|
|
||||||
if(remainingSectors < 512)
|
if(remainingSectors < 512)
|
||||||
{
|
{
|
||||||
@@ -223,23 +219,24 @@ namespace DiscImageChef.Commands
|
|||||||
ulong currentSector = 0;
|
ulong currentSector = 0;
|
||||||
|
|
||||||
startCheck = DateTime.UtcNow;
|
startCheck = DateTime.UtcNow;
|
||||||
|
|
||||||
while(remainingSectors > 0)
|
while(remainingSectors > 0)
|
||||||
{
|
{
|
||||||
DicConsole.Write("\rChecking sector {0} of {1}", currentSector, inputFormat.Info.Sectors);
|
DicConsole.Write("\rChecking sector {0} of {1}", currentSector, inputFormat.Info.Sectors);
|
||||||
|
|
||||||
List<ulong> tempfailingLbas;
|
List<ulong> tempFailingLbas;
|
||||||
List<ulong> tempunknownLbas;
|
List<ulong> tempUnknownLbas;
|
||||||
|
|
||||||
if(remainingSectors < 512)
|
if(remainingSectors < 512)
|
||||||
verifiableSectorsImage.VerifySectors(currentSector, (uint)remainingSectors,
|
verifiableSectorsImage.VerifySectors(currentSector, (uint)remainingSectors,
|
||||||
out tempfailingLbas, out tempunknownLbas);
|
out tempFailingLbas, out tempUnknownLbas);
|
||||||
else
|
else
|
||||||
verifiableSectorsImage.VerifySectors(currentSector, 512, out tempfailingLbas,
|
verifiableSectorsImage.VerifySectors(currentSector, 512, out tempFailingLbas,
|
||||||
out tempunknownLbas);
|
out tempUnknownLbas);
|
||||||
|
|
||||||
failingLbas.AddRange(tempfailingLbas);
|
failingLbas.AddRange(tempFailingLbas);
|
||||||
|
|
||||||
unknownLbas.AddRange(tempunknownLbas);
|
unknownLbas.AddRange(tempUnknownLbas);
|
||||||
|
|
||||||
if(remainingSectors < 512)
|
if(remainingSectors < 512)
|
||||||
{
|
{
|
||||||
@@ -262,15 +259,20 @@ namespace DiscImageChef.Commands
|
|||||||
|
|
||||||
if(unknownSectors > 0)
|
if(unknownSectors > 0)
|
||||||
DicConsole.WriteLine("There is at least one sector that does not contain a checksum");
|
DicConsole.WriteLine("There is at least one sector that does not contain a checksum");
|
||||||
|
|
||||||
if(errorSectors > 0)
|
if(errorSectors > 0)
|
||||||
DicConsole.WriteLine("There is at least one sector with incorrect checksum or errors");
|
DicConsole.WriteLine("There is at least one sector with incorrect checksum or errors");
|
||||||
if(unknownSectors == 0 && errorSectors == 0) DicConsole.WriteLine("All sector checksums are correct");
|
|
||||||
|
if(unknownSectors == 0 &&
|
||||||
|
errorSectors == 0)
|
||||||
|
DicConsole.WriteLine("All sector checksums are correct");
|
||||||
|
|
||||||
DicConsole.VerboseWriteLine("Checking sector checksums took {0} seconds", checkTime.TotalSeconds);
|
DicConsole.VerboseWriteLine("Checking sector checksums took {0} seconds", checkTime.TotalSeconds);
|
||||||
|
|
||||||
if(MainClass.Verbose)
|
if(verbose)
|
||||||
{
|
{
|
||||||
DicConsole.VerboseWriteLine("LBAs with error:");
|
DicConsole.VerboseWriteLine("LBAs with error:");
|
||||||
|
|
||||||
if(failingLbas.Count == (int)inputFormat.Info.Sectors)
|
if(failingLbas.Count == (int)inputFormat.Info.Sectors)
|
||||||
DicConsole.VerboseWriteLine("\tall sectors.");
|
DicConsole.VerboseWriteLine("\tall sectors.");
|
||||||
else
|
else
|
||||||
@@ -278,6 +280,7 @@ namespace DiscImageChef.Commands
|
|||||||
DicConsole.VerboseWriteLine("\t{0}", t);
|
DicConsole.VerboseWriteLine("\t{0}", t);
|
||||||
|
|
||||||
DicConsole.WriteLine("LBAs without checksum:");
|
DicConsole.WriteLine("LBAs without checksum:");
|
||||||
|
|
||||||
if(unknownLbas.Count == (int)inputFormat.Info.Sectors)
|
if(unknownLbas.Count == (int)inputFormat.Info.Sectors)
|
||||||
DicConsole.VerboseWriteLine("\tall sectors.");
|
DicConsole.VerboseWriteLine("\tall sectors.");
|
||||||
else
|
else
|
||||||
@@ -290,27 +293,26 @@ namespace DiscImageChef.Commands
|
|||||||
DicConsole.WriteLine("Total unknowns.......... {0}", unknownLbas.Count);
|
DicConsole.WriteLine("Total unknowns.......... {0}", unknownLbas.Count);
|
||||||
DicConsole.WriteLine("Total errors+unknowns... {0}", failingLbas.Count + unknownLbas.Count);
|
DicConsole.WriteLine("Total errors+unknowns... {0}", failingLbas.Count + unknownLbas.Count);
|
||||||
|
|
||||||
totalSectors = (long)inputFormat.Info.Sectors;
|
if(failingLbas.Count > 0)
|
||||||
errorSectors = failingLbas.Count;
|
correctSectors = false;
|
||||||
unknownSectors = unknownLbas.Count;
|
else if((ulong)unknownLbas.Count < inputFormat.Info.Sectors)
|
||||||
if(failingLbas.Count > 0) correctSectors = false;
|
correctSectors = true;
|
||||||
else if((ulong)unknownLbas.Count < inputFormat.Info.Sectors) correctSectors = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(correctImage)
|
switch(correctImage)
|
||||||
{
|
{
|
||||||
case null when correctSectors is null: return (int)ErrorNumber.NotVerificable;
|
case null when correctSectors is null: return(int)ErrorNumber.NotVerificable;
|
||||||
case null when correctSectors == false: return (int)ErrorNumber.BadSectorsImageNotVerified;
|
case null when correctSectors == false: return(int)ErrorNumber.BadSectorsImageNotVerified;
|
||||||
case null when correctSectors == true: return (int)ErrorNumber.CorrectSectorsImageNotVerified;
|
case null when correctSectors == true: return(int)ErrorNumber.CorrectSectorsImageNotVerified;
|
||||||
case false when correctSectors is null: return (int)ErrorNumber.BadImageSectorsNotVerified;
|
case false when correctSectors is null: return(int)ErrorNumber.BadImageSectorsNotVerified;
|
||||||
case false when correctSectors == false: return (int)ErrorNumber.BadImageBadSectors;
|
case false when correctSectors == false: return(int)ErrorNumber.BadImageBadSectors;
|
||||||
case false when correctSectors == true: return (int)ErrorNumber.CorrectSectorsBadImage;
|
case false when correctSectors == true: return(int)ErrorNumber.CorrectSectorsBadImage;
|
||||||
case true when correctSectors is null: return (int)ErrorNumber.CorrectImageSectorsNotVerified;
|
case true when correctSectors is null: return(int)ErrorNumber.CorrectImageSectorsNotVerified;
|
||||||
case true when correctSectors == false: return (int)ErrorNumber.CorrectImageBadSectors;
|
case true when correctSectors == false: return(int)ErrorNumber.CorrectImageBadSectors;
|
||||||
case true when correctSectors == true: return (int)ErrorNumber.NoError;
|
case true when correctSectors == true: return(int)ErrorNumber.NoError;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (int)ErrorNumber.NoError;
|
return(int)ErrorNumber.NoError;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -264,8 +264,8 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.6" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.6" />
|
||||||
<PackageReference Include="Mono.Options" Version="5.3.0.1" />
|
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
|
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
|
||||||
|
<PackageReference Include="System.CommandLine.Experimental" Version="0.3.0-alpha.19577.1" />
|
||||||
<PackageReference Include="System.Text.Encoding.CodePages" Version="4.5.1" />
|
<PackageReference Include="System.Text.Encoding.CodePages" Version="4.5.1" />
|
||||||
<PackageReference Include="System.ValueTuple" Version="4.5.0" />
|
<PackageReference Include="System.ValueTuple" Version="4.5.0" />
|
||||||
<PackageReference Include="Unclassified.NetRevisionTask" Version="0.3.0" />
|
<PackageReference Include="Unclassified.NetRevisionTask" Version="0.3.0" />
|
||||||
|
|||||||
@@ -31,41 +31,40 @@
|
|||||||
// ****************************************************************************/
|
// ****************************************************************************/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.CommandLine;
|
||||||
|
using System.CommandLine.Invocation;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using DiscImageChef.Commands;
|
using DiscImageChef.Commands;
|
||||||
using DiscImageChef.CommonTypes.Interop;
|
|
||||||
using DiscImageChef.Console;
|
using DiscImageChef.Console;
|
||||||
using DiscImageChef.Core;
|
using DiscImageChef.Core;
|
||||||
using DiscImageChef.Database;
|
using DiscImageChef.Database;
|
||||||
using DiscImageChef.Settings;
|
using DiscImageChef.Settings;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Mono.Options;
|
|
||||||
using PlatformID = DiscImageChef.CommonTypes.Interop.PlatformID;
|
|
||||||
|
|
||||||
namespace DiscImageChef
|
namespace DiscImageChef
|
||||||
{
|
{
|
||||||
internal class MainClass
|
internal class MainClass
|
||||||
{
|
{
|
||||||
internal static bool Verbose;
|
static string _assemblyCopyright;
|
||||||
internal static bool Debug;
|
static string _assemblyTitle;
|
||||||
internal static string AssemblyCopyright;
|
static AssemblyInformationalVersionAttribute _assemblyVersion;
|
||||||
internal static string AssemblyTitle;
|
|
||||||
internal static AssemblyInformationalVersionAttribute AssemblyVersion;
|
|
||||||
|
|
||||||
[STAThread]
|
[STAThread]
|
||||||
public static int Main(string[] args)
|
public static int Main(string[] args)
|
||||||
{
|
{
|
||||||
var attributes = typeof(MainClass).Assembly.GetCustomAttributes(typeof(AssemblyTitleAttribute), false);
|
object[] attributes = typeof(MainClass).Assembly.GetCustomAttributes(typeof(AssemblyTitleAttribute), false);
|
||||||
AssemblyTitle = ((AssemblyTitleAttribute) attributes[0]).Title;
|
_assemblyTitle = ((AssemblyTitleAttribute)attributes[0]).Title;
|
||||||
attributes = typeof(MainClass).Assembly.GetCustomAttributes(typeof(AssemblyCopyrightAttribute), false);
|
attributes = typeof(MainClass).Assembly.GetCustomAttributes(typeof(AssemblyCopyrightAttribute), false);
|
||||||
AssemblyVersion =
|
|
||||||
|
_assemblyVersion =
|
||||||
Attribute.GetCustomAttribute(typeof(MainClass).Assembly, typeof(AssemblyInformationalVersionAttribute))
|
Attribute.GetCustomAttribute(typeof(MainClass).Assembly, typeof(AssemblyInformationalVersionAttribute))
|
||||||
as AssemblyInformationalVersionAttribute;
|
as AssemblyInformationalVersionAttribute;
|
||||||
AssemblyCopyright = ((AssemblyCopyrightAttribute) attributes[0]).Copyright;
|
|
||||||
|
_assemblyCopyright = ((AssemblyCopyrightAttribute)attributes[0]).Copyright;
|
||||||
|
|
||||||
DicConsole.WriteLineEvent += System.Console.WriteLine;
|
DicConsole.WriteLineEvent += System.Console.WriteLine;
|
||||||
DicConsole.WriteEvent += System.Console.Write;
|
DicConsole.WriteEvent += System.Console.Write;
|
||||||
@@ -77,16 +76,17 @@ namespace DiscImageChef
|
|||||||
ctx.Database.Migrate();
|
ctx.Database.Migrate();
|
||||||
ctx.SaveChanges();
|
ctx.SaveChanges();
|
||||||
|
|
||||||
var masterDbUpdate = false;
|
bool masterDbUpdate = false;
|
||||||
if (!File.Exists(Settings.Settings.MasterDbPath))
|
|
||||||
|
if(!File.Exists(Settings.Settings.MasterDbPath))
|
||||||
{
|
{
|
||||||
masterDbUpdate = true;
|
masterDbUpdate = true;
|
||||||
UpdateCommand.DoUpdate(true);
|
UpdateCommand.DoUpdate(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
var mctx = DicContext.Create(Settings.Settings.MasterDbPath);
|
var masterContext = DicContext.Create(Settings.Settings.MasterDbPath);
|
||||||
|
|
||||||
if(mctx.Database.GetPendingMigrations().Any())
|
if(masterContext.Database.GetPendingMigrations().Any())
|
||||||
{
|
{
|
||||||
DicConsole.WriteLine("New database version, updating...");
|
DicConsole.WriteLine("New database version, updating...");
|
||||||
|
|
||||||
@@ -103,84 +103,76 @@ namespace DiscImageChef
|
|||||||
UpdateCommand.DoUpdate(true);
|
UpdateCommand.DoUpdate(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((args.Length < 1 || args[0].ToLowerInvariant() != "gui") &&
|
if((args.Length < 1 || args[0].ToLowerInvariant() != "gui") &&
|
||||||
Settings.Settings.Current.GdprCompliance < DicSettings.GdprLevel)
|
Settings.Settings.Current.GdprCompliance < DicSettings.GdprLevel)
|
||||||
new ConfigureCommand(true, true).Invoke(args);
|
new ConfigureCommand(true, true).Invoke(args);
|
||||||
Statistics.LoadStats();
|
|
||||||
if (Settings.Settings.Current.Stats != null && Settings.Settings.Current.Stats.ShareStats)
|
|
||||||
Task.Run(() => { Statistics.SubmitStats(); });
|
|
||||||
|
|
||||||
var currentPlatform = DetectOS.GetRealPlatformID();
|
Statistics.LoadStats();
|
||||||
|
|
||||||
|
if(Settings.Settings.Current.Stats != null &&
|
||||||
|
Settings.Settings.Current.Stats.ShareStats)
|
||||||
|
Task.Run(Statistics.SubmitStats);
|
||||||
|
|
||||||
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
|
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
|
||||||
|
|
||||||
var commands = new CommandSet("DiscImageChef")
|
|
||||||
{
|
|
||||||
$"{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, false),
|
|
||||||
new ConvertImageCommand(),
|
|
||||||
new CreateSidecarCommand(),
|
|
||||||
new DecodeCommand()
|
|
||||||
};
|
|
||||||
|
|
||||||
if (currentPlatform == PlatformID.FreeBSD || currentPlatform == PlatformID.Linux ||
|
|
||||||
currentPlatform == PlatformID.Win32NT)
|
|
||||||
{
|
|
||||||
commands.Add(new DeviceInfoCommand());
|
|
||||||
commands.Add(new DeviceReportCommand());
|
|
||||||
commands.Add(new DumpMediaCommand());
|
|
||||||
}
|
|
||||||
|
|
||||||
commands.Add(new EntropyCommand());
|
|
||||||
commands.Add(new ExtractFilesCommand());
|
|
||||||
commands.Add(new FormatsCommand());
|
|
||||||
commands.Add(new ImageInfoCommand());
|
|
||||||
|
|
||||||
if (currentPlatform == PlatformID.FreeBSD || currentPlatform == PlatformID.Linux ||
|
|
||||||
currentPlatform == PlatformID.Win32NT) commands.Add(new ListDevicesCommand());
|
|
||||||
|
|
||||||
commands.Add(new ListEncodingsCommand());
|
|
||||||
commands.Add(new ListNamespacesCommand());
|
|
||||||
commands.Add(new ListOptionsCommand());
|
|
||||||
commands.Add(new LsCommand());
|
|
||||||
|
|
||||||
if (currentPlatform == PlatformID.FreeBSD || currentPlatform == PlatformID.Linux ||
|
|
||||||
currentPlatform == PlatformID.Win32NT)
|
|
||||||
{
|
|
||||||
commands.Add(new MediaInfoCommand());
|
|
||||||
commands.Add(new MediaScanCommand());
|
|
||||||
}
|
|
||||||
|
|
||||||
commands.Add(new PrintHexCommand());
|
|
||||||
commands.Add(new StatisticsCommand());
|
|
||||||
commands.Add(new UpdateCommand(masterDbUpdate));
|
|
||||||
commands.Add(new VerifyCommand());
|
|
||||||
commands.Add(new RemoteCommand());
|
|
||||||
|
|
||||||
var ret = commands.Run(args);
|
|
||||||
|
|
||||||
Statistics.SaveStats();
|
Statistics.SaveStats();
|
||||||
|
|
||||||
return ret;
|
var rootCommand = new RootCommand
|
||||||
|
{
|
||||||
|
new Option(new[]
|
||||||
|
{
|
||||||
|
"--verbose", "-v"
|
||||||
|
}, "Shows verbose output.")
|
||||||
|
{
|
||||||
|
Argument = new Argument<bool>(() => false)
|
||||||
|
},
|
||||||
|
new Option(new[]
|
||||||
|
{
|
||||||
|
"--debug", "-d"
|
||||||
|
}, "Shows debug output from plugins.")
|
||||||
|
{
|
||||||
|
Argument = new Argument<bool>(() => false)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
rootCommand.Description =
|
||||||
|
$"{_assemblyTitle} {_assemblyVersion?.InformationalVersion}\n{_assemblyCopyright}";
|
||||||
|
|
||||||
|
rootCommand.AddCommand(new AnalyzeCommand());
|
||||||
|
rootCommand.AddCommand(new BenchmarkCommand());
|
||||||
|
rootCommand.AddCommand(new ChecksumCommand());
|
||||||
|
rootCommand.AddCommand(new CompareCommand());
|
||||||
|
rootCommand.AddCommand(new ConfigureCommand(false, false));
|
||||||
|
rootCommand.AddCommand(new ConvertImageCommand());
|
||||||
|
rootCommand.AddCommand(new CreateSidecarCommand());
|
||||||
|
rootCommand.AddCommand(new DecodeCommand());
|
||||||
|
rootCommand.AddCommand(new DeviceInfoCommand());
|
||||||
|
rootCommand.AddCommand(new DeviceReportCommand());
|
||||||
|
rootCommand.AddCommand(new DumpMediaCommand());
|
||||||
|
rootCommand.AddCommand(new EntropyCommand());
|
||||||
|
rootCommand.AddCommand(new ExtractFilesCommand());
|
||||||
|
rootCommand.AddCommand(new FormatsCommand());
|
||||||
|
rootCommand.AddCommand(new ImageInfoCommand());
|
||||||
|
rootCommand.AddCommand(new ListDevicesCommand());
|
||||||
|
rootCommand.AddCommand(new ListEncodingsCommand());
|
||||||
|
rootCommand.AddCommand(new ListNamespacesCommand());
|
||||||
|
rootCommand.AddCommand(new ListOptionsCommand());
|
||||||
|
rootCommand.AddCommand(new LsCommand());
|
||||||
|
rootCommand.AddCommand(new MediaInfoCommand());
|
||||||
|
rootCommand.AddCommand(new MediaScanCommand());
|
||||||
|
rootCommand.AddCommand(new PrintHexCommand());
|
||||||
|
rootCommand.AddCommand(new StatisticsCommand());
|
||||||
|
rootCommand.AddCommand(new UpdateCommand(masterDbUpdate));
|
||||||
|
rootCommand.AddCommand(new VerifyCommand());
|
||||||
|
rootCommand.AddCommand(new RemoteCommand());
|
||||||
|
|
||||||
|
return rootCommand.Invoke(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void PrintCopyright()
|
internal static void PrintCopyright()
|
||||||
{
|
{
|
||||||
DicConsole.WriteLine("{0} {1}", AssemblyTitle, AssemblyVersion?.InformationalVersion);
|
DicConsole.WriteLine("{0} {1}", _assemblyTitle, _assemblyVersion?.InformationalVersion);
|
||||||
DicConsole.WriteLine("{0}", AssemblyCopyright);
|
DicConsole.WriteLine("{0}", _assemblyCopyright);
|
||||||
DicConsole.WriteLine();
|
DicConsole.WriteLine();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user