mirror of
https://github.com/aaru-dps/Aaru.git
synced 2025-12-16 19:24:25 +00:00
Add support for byte addressable images to detection.
This commit is contained in:
@@ -636,7 +636,7 @@ namespace Aaru.Core.Devices.Dumping
|
||||
UpdateStatus?.Invoke("Creating sidecar.");
|
||||
var filters = new FiltersList();
|
||||
IFilter filter = filters.GetFilter(_outputPath);
|
||||
IMediaImage inputPlugin = ImageFormat.Detect(filter);
|
||||
IMediaImage inputPlugin = ImageFormat.Detect(filter) as IMediaImage;
|
||||
ErrorNumber opened = inputPlugin.Open(filter);
|
||||
|
||||
if(opened != ErrorNumber.NoError)
|
||||
|
||||
@@ -62,7 +62,7 @@ namespace Aaru.Core.Devices.Dumping
|
||||
_dumpLog.WriteLine("Creating sidecar.");
|
||||
var filters = new FiltersList();
|
||||
IFilter filter = filters.GetFilter(_outputPath);
|
||||
IMediaImage inputPlugin = ImageFormat.Detect(filter);
|
||||
IMediaImage inputPlugin = ImageFormat.Detect(filter) as IMediaImage;
|
||||
totalChkDuration = 0;
|
||||
ErrorNumber opened = inputPlugin.Open(filter);
|
||||
|
||||
|
||||
@@ -693,7 +693,7 @@ namespace Aaru.Core.Devices.Dumping
|
||||
_dumpLog.WriteLine("Creating sidecar.");
|
||||
var filters = new FiltersList();
|
||||
IFilter filter = filters.GetFilter(_outputPath);
|
||||
IMediaImage inputPlugin = ImageFormat.Detect(filter);
|
||||
IMediaImage inputPlugin = ImageFormat.Detect(filter) as IMediaImage;
|
||||
ErrorNumber opened = inputPlugin.Open(filter);
|
||||
|
||||
if(opened != ErrorNumber.NoError)
|
||||
|
||||
@@ -561,7 +561,7 @@ namespace Aaru.Core.Devices.Dumping
|
||||
_dumpLog.WriteLine("Creating sidecar.");
|
||||
var filters = new FiltersList();
|
||||
IFilter filter = filters.GetFilter(_outputPath);
|
||||
IMediaImage inputPlugin = ImageFormat.Detect(filter);
|
||||
IMediaImage inputPlugin = ImageFormat.Detect(filter) as IMediaImage;
|
||||
ErrorNumber opened = inputPlugin.Open(filter);
|
||||
|
||||
if(opened != ErrorNumber.NoError)
|
||||
|
||||
@@ -1314,7 +1314,7 @@ namespace Aaru.Core.Devices.Dumping
|
||||
_dumpLog.WriteLine("Creating sidecar.");
|
||||
var filters = new FiltersList();
|
||||
IFilter filter = filters.GetFilter(_outputPath);
|
||||
IMediaImage inputPlugin = ImageFormat.Detect(filter);
|
||||
IMediaImage inputPlugin = ImageFormat.Detect(filter) as IMediaImage;
|
||||
ErrorNumber opened = inputPlugin.Open(filter);
|
||||
|
||||
if(opened != ErrorNumber.NoError)
|
||||
|
||||
@@ -985,7 +985,7 @@ namespace Aaru.Core.Devices.Dumping
|
||||
_dumpLog.WriteLine("Creating sidecar.");
|
||||
var filters = new FiltersList();
|
||||
IFilter filter = filters.GetFilter(_outputPath);
|
||||
IMediaImage inputPlugin = ImageFormat.Detect(filter);
|
||||
IMediaImage inputPlugin = ImageFormat.Detect(filter) as IMediaImage;
|
||||
ErrorNumber opened = inputPlugin.Open(filter);
|
||||
|
||||
if(opened != ErrorNumber.NoError)
|
||||
|
||||
@@ -782,7 +782,7 @@ namespace Aaru.Core.Devices.Dumping
|
||||
_dumpLog.WriteLine("Creating sidecar.");
|
||||
var filters = new FiltersList();
|
||||
IFilter filter = filters.GetFilter(_outputPath);
|
||||
IMediaImage inputPlugin = ImageFormat.Detect(filter);
|
||||
IMediaImage inputPlugin = ImageFormat.Detect(filter) as IMediaImage;
|
||||
ErrorNumber opened = inputPlugin.Open(filter);
|
||||
|
||||
if(opened != ErrorNumber.NoError)
|
||||
|
||||
@@ -36,72 +36,94 @@ using Aaru.CommonTypes;
|
||||
using Aaru.CommonTypes.Interfaces;
|
||||
using Aaru.Console;
|
||||
|
||||
namespace Aaru.Core
|
||||
namespace Aaru.Core;
|
||||
|
||||
/// <summary>Core media image format operations</summary>
|
||||
public static class ImageFormat
|
||||
{
|
||||
/// <summary>Core media image format operations</summary>
|
||||
public static class ImageFormat
|
||||
/// <summary>Detects the image plugin that recognizes the data inside a filter</summary>
|
||||
/// <param name="imageFilter">Filter</param>
|
||||
/// <returns>Detected image plugin</returns>
|
||||
public static IBaseImage Detect(IFilter imageFilter)
|
||||
{
|
||||
/// <summary>Detects the image plugin that recognizes the data inside a filter</summary>
|
||||
/// <param name="imageFilter">Filter</param>
|
||||
/// <returns>Detected image plugin</returns>
|
||||
public static IMediaImage Detect(IFilter imageFilter)
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
PluginBase plugins = GetPluginBase.Instance;
|
||||
PluginBase plugins = GetPluginBase.Instance;
|
||||
|
||||
IMediaImage imageFormat = null;
|
||||
IBaseImage imageFormat = null;
|
||||
|
||||
// Check all but RAW plugin
|
||||
foreach(IMediaImage imagePlugin in plugins.ImagePluginsList.Values.Where(imagePlugin =>
|
||||
imagePlugin.Id != new Guid("12345678-AAAA-BBBB-CCCC-123456789000")))
|
||||
try
|
||||
{
|
||||
AaruConsole.DebugWriteLine("Format detection", "Trying plugin {0}", imagePlugin.Name);
|
||||
// Check all but RAW plugin
|
||||
foreach(IMediaImage imagePlugin in plugins.ImagePluginsList.Values.Where(imagePlugin =>
|
||||
imagePlugin.Id != new Guid("12345678-AAAA-BBBB-CCCC-123456789000")))
|
||||
try
|
||||
{
|
||||
AaruConsole.DebugWriteLine("Format detection", "Trying plugin {0}", imagePlugin.Name);
|
||||
|
||||
if(!imagePlugin.Identify(imageFilter))
|
||||
continue;
|
||||
if(!imagePlugin.Identify(imageFilter))
|
||||
continue;
|
||||
|
||||
imageFormat = imagePlugin;
|
||||
imageFormat = imagePlugin;
|
||||
|
||||
break;
|
||||
}
|
||||
#pragma warning disable RECS0022 // A catch clause that catches System.Exception and has an empty body
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
break;
|
||||
}
|
||||
#pragma warning disable RECS0022 // A catch clause that catches System.Exception and has an empty body
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
|
||||
if(imageFormat != null)
|
||||
return imageFormat;
|
||||
|
||||
// Check only RAW plugin
|
||||
foreach(IMediaImage imagePlugin in plugins.ImagePluginsList.Values.Where(imagePlugin =>
|
||||
imagePlugin.Id == new Guid("12345678-AAAA-BBBB-CCCC-123456789000")))
|
||||
try
|
||||
{
|
||||
AaruConsole.DebugWriteLine("Format detection", "Trying plugin {0}", imagePlugin.Name);
|
||||
|
||||
if(!imagePlugin.Identify(imageFilter))
|
||||
continue;
|
||||
|
||||
imageFormat = imagePlugin;
|
||||
|
||||
break;
|
||||
}
|
||||
#pragma warning disable RECS0022 // A catch clause that catches System.Exception and has an empty body
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
|
||||
// Still not recognized
|
||||
if(imageFormat != null)
|
||||
return imageFormat;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// Check all but RAW plugin
|
||||
foreach(IByteAddressableImage imagePlugin in plugins.ByteAddressableImages.Values.Where(imagePlugin =>
|
||||
imagePlugin.Id != new Guid("12345678-AAAA-BBBB-CCCC-123456789000")))
|
||||
try
|
||||
{
|
||||
AaruConsole.DebugWriteLine("Format detection", "Trying plugin {0}", imagePlugin.Name);
|
||||
|
||||
if(!imagePlugin.Identify(imageFilter))
|
||||
continue;
|
||||
|
||||
imageFormat = imagePlugin;
|
||||
|
||||
break;
|
||||
}
|
||||
#pragma warning disable RECS0022 // A catch clause that catches System.Exception and has an empty body
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
|
||||
if(imageFormat != null)
|
||||
return imageFormat;
|
||||
|
||||
// Check only RAW plugin
|
||||
foreach(IMediaImage imagePlugin in plugins.ImagePluginsList.Values.Where(imagePlugin =>
|
||||
imagePlugin.Id == new Guid("12345678-AAAA-BBBB-CCCC-123456789000")))
|
||||
try
|
||||
{
|
||||
AaruConsole.DebugWriteLine("Format detection", "Trying plugin {0}", imagePlugin.Name);
|
||||
|
||||
if(!imagePlugin.Identify(imageFilter))
|
||||
continue;
|
||||
|
||||
imageFormat = imagePlugin;
|
||||
|
||||
break;
|
||||
}
|
||||
#pragma warning disable RECS0022 // A catch clause that catches System.Exception and has an empty body
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
|
||||
// Still not recognized
|
||||
return imageFormat;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -523,7 +523,7 @@ namespace Aaru.Gui.ViewModels.Windows
|
||||
|
||||
try
|
||||
{
|
||||
IMediaImage imageFormat = ImageFormat.Detect(inputFilter);
|
||||
IMediaImage imageFormat = ImageFormat.Detect(inputFilter) as IMediaImage;
|
||||
|
||||
if(imageFormat == null)
|
||||
{
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace Aaru.Tests.Filesystems
|
||||
|
||||
Assert.IsNotNull(inputFilter, $"Filter: {testFile}");
|
||||
|
||||
IMediaImage image = ImageFormat.Detect(inputFilter);
|
||||
IMediaImage image = ImageFormat.Detect(inputFilter) as IMediaImage;
|
||||
|
||||
Assert.IsNotNull(image, $"Image format: {testFile}");
|
||||
|
||||
@@ -123,7 +123,7 @@ namespace Aaru.Tests.Filesystems
|
||||
|
||||
Assert.IsNotNull(inputFilter, $"Filter: {testFile}");
|
||||
|
||||
IMediaImage image = ImageFormat.Detect(inputFilter);
|
||||
IMediaImage image = ImageFormat.Detect(inputFilter) as IMediaImage;
|
||||
|
||||
Assert.IsNotNull(image, $"Image format: {testFile}");
|
||||
|
||||
@@ -162,7 +162,7 @@ namespace Aaru.Tests.Filesystems
|
||||
|
||||
Assert.IsNotNull(inputFilter, $"Filter: {testFile}");
|
||||
|
||||
IMediaImage image = ImageFormat.Detect(inputFilter);
|
||||
IMediaImage image = ImageFormat.Detect(inputFilter) as IMediaImage;
|
||||
|
||||
Assert.IsNotNull(image, $"Image format: {testFile}");
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ namespace Aaru.Tests.Filesystems
|
||||
|
||||
Assert.IsNotNull(inputFilter, $"Filter: {testFile}");
|
||||
|
||||
IMediaImage image = ImageFormat.Detect(inputFilter);
|
||||
IMediaImage image = ImageFormat.Detect(inputFilter) as IMediaImage;
|
||||
|
||||
Assert.IsNotNull(image, $"Image format: {testFile}");
|
||||
|
||||
@@ -163,7 +163,7 @@ namespace Aaru.Tests.Filesystems
|
||||
|
||||
var filtersList = new FiltersList();
|
||||
IFilter inputFilter = filtersList.GetFilter(testFile);
|
||||
IMediaImage image = ImageFormat.Detect(inputFilter);
|
||||
IMediaImage image = ImageFormat.Detect(inputFilter) as IMediaImage;
|
||||
ErrorNumber opened = image.Open(inputFilter);
|
||||
|
||||
if(opened != ErrorNumber.NoError)
|
||||
|
||||
@@ -48,7 +48,7 @@ namespace Aaru.Tests.Issues
|
||||
|
||||
PluginBase plugins = GetPluginBase.Instance;
|
||||
|
||||
IMediaImage imageFormat = ImageFormat.Detect(inputFilter);
|
||||
IMediaImage imageFormat = ImageFormat.Detect(inputFilter) as IMediaImage;
|
||||
|
||||
Assert.NotNull(imageFormat, "Image format not identified, not proceeding with analysis.");
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ namespace Aaru.Tests.Issues
|
||||
|
||||
PluginBase plugins = GetPluginBase.Instance;
|
||||
|
||||
IMediaImage imageFormat = ImageFormat.Detect(inputFilter);
|
||||
IMediaImage imageFormat = ImageFormat.Detect(inputFilter) as IMediaImage;
|
||||
|
||||
Assert.NotNull(imageFormat, "Image format not identified, not proceeding with analysis.");
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace Aaru.Tests.Issues
|
||||
|
||||
Assert.IsNotNull(inputFilter, "Filter for test file is not detected");
|
||||
|
||||
IMediaImage image = ImageFormat.Detect(inputFilter);
|
||||
IMediaImage image = ImageFormat.Detect(inputFilter) as IMediaImage;
|
||||
|
||||
Assert.IsNotNull(image, "Image format for test file is not detected");
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ namespace Aaru.Tests.Issues
|
||||
|
||||
Assert.IsFalse(File.Exists(outputPath), "Output file already exists, not continuing.");
|
||||
|
||||
IMediaImage inputFormat = ImageFormat.Detect(inputFilter);
|
||||
IMediaImage inputFormat = ImageFormat.Detect(inputFilter) as IMediaImage;
|
||||
|
||||
Assert.IsNotNull(inputFormat, "Input image format not identified, not proceeding with conversion.");
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace Aaru.Tests.Issues
|
||||
|
||||
Assert.IsNotNull(inputFilter, "Filter for test file is not detected");
|
||||
|
||||
IMediaImage image = ImageFormat.Detect(inputFilter);
|
||||
IMediaImage image = ImageFormat.Detect(inputFilter) as IMediaImage;
|
||||
|
||||
Assert.IsNotNull(image, "Image format for test file is not detected");
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace Aaru.Tests.Partitions
|
||||
|
||||
Assert.IsNotNull(inputFilter, $"Filter: {testFile}");
|
||||
|
||||
IMediaImage image = ImageFormat.Detect(inputFilter);
|
||||
IMediaImage image = ImageFormat.Detect(inputFilter) as IMediaImage;
|
||||
|
||||
Assert.IsNotNull(image, $"Image format: {testFile}");
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -42,339 +42,345 @@ using Aaru.Console;
|
||||
using Aaru.Core;
|
||||
using Spectre.Console;
|
||||
|
||||
namespace Aaru.Commands.Filesystem
|
||||
namespace Aaru.Commands.Filesystem;
|
||||
|
||||
internal sealed class FilesystemInfoCommand : Command
|
||||
{
|
||||
internal sealed class FilesystemInfoCommand : Command
|
||||
public FilesystemInfoCommand() : base("info",
|
||||
"Opens a disc image and prints info on the found partitions and/or filesystems.")
|
||||
{
|
||||
public FilesystemInfoCommand() : base("info",
|
||||
"Opens a disc image and prints info on the found partitions and/or filesystems.")
|
||||
{
|
||||
Add(new Option(new[]
|
||||
{
|
||||
"--encoding", "-e"
|
||||
}, "Name of character encoding to use.")
|
||||
{
|
||||
Argument = new Argument<string>(() => null),
|
||||
Required = false
|
||||
});
|
||||
|
||||
Add(new Option(new[]
|
||||
{
|
||||
"--filesystems", "-f"
|
||||
}, "Searches and prints information about 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>
|
||||
Add(new Option(new[]
|
||||
{
|
||||
Arity = ArgumentArity.ExactlyOne,
|
||||
Description = "Media image path",
|
||||
Name = "image-path"
|
||||
"--encoding", "-e"
|
||||
}, "Name of character encoding to use.")
|
||||
{
|
||||
Argument = new Argument<string>(() => null),
|
||||
Required = false
|
||||
});
|
||||
|
||||
Handler = CommandHandler.Create(typeof(FilesystemInfoCommand).GetMethod(nameof(Invoke)));
|
||||
Add(new Option(new[]
|
||||
{
|
||||
"--filesystems", "-f"
|
||||
}, "Searches and prints information about 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 = "Media image path",
|
||||
Name = "image-path"
|
||||
});
|
||||
|
||||
Handler = CommandHandler.Create(typeof(FilesystemInfoCommand).GetMethod(nameof(Invoke)));
|
||||
}
|
||||
|
||||
public static int Invoke(bool verbose, bool debug, string encoding, bool filesystems, bool partitions,
|
||||
string imagePath)
|
||||
{
|
||||
MainClass.PrintCopyright();
|
||||
|
||||
if(debug)
|
||||
{
|
||||
IAnsiConsole stderrConsole = AnsiConsole.Create(new AnsiConsoleSettings
|
||||
{
|
||||
Out = new AnsiConsoleOutput(System.Console.Error)
|
||||
});
|
||||
|
||||
AaruConsole.DebugWriteLineEvent += (format, objects) =>
|
||||
{
|
||||
if(objects is null)
|
||||
stderrConsole.MarkupLine(format);
|
||||
else
|
||||
stderrConsole.MarkupLine(format, objects);
|
||||
};
|
||||
}
|
||||
|
||||
public static int Invoke(bool verbose, bool debug, string encoding, bool filesystems, bool partitions,
|
||||
string imagePath)
|
||||
{
|
||||
MainClass.PrintCopyright();
|
||||
|
||||
if(debug)
|
||||
if(verbose)
|
||||
AaruConsole.WriteEvent += (format, objects) =>
|
||||
{
|
||||
IAnsiConsole stderrConsole = AnsiConsole.Create(new AnsiConsoleSettings
|
||||
{
|
||||
Out = new AnsiConsoleOutput(System.Console.Error)
|
||||
});
|
||||
if(objects is null)
|
||||
AnsiConsole.Markup(format);
|
||||
else
|
||||
AnsiConsole.Markup(format, objects);
|
||||
};
|
||||
|
||||
AaruConsole.DebugWriteLineEvent += (format, objects) =>
|
||||
{
|
||||
if(objects is null)
|
||||
stderrConsole.MarkupLine(format);
|
||||
else
|
||||
stderrConsole.MarkupLine(format, objects);
|
||||
};
|
||||
Statistics.AddCommand("fs-info");
|
||||
|
||||
AaruConsole.DebugWriteLine("Fs-info command", "--debug={0}", debug);
|
||||
AaruConsole.DebugWriteLine("Fs-info command", "--encoding={0}", encoding);
|
||||
AaruConsole.DebugWriteLine("Fs-info command", "--filesystems={0}", filesystems);
|
||||
AaruConsole.DebugWriteLine("Fs-info command", "--input={0}", imagePath);
|
||||
AaruConsole.DebugWriteLine("Fs-info command", "--partitions={0}", partitions);
|
||||
AaruConsole.DebugWriteLine("Fs-info command", "--verbose={0}", verbose);
|
||||
|
||||
var filtersList = new FiltersList();
|
||||
IFilter inputFilter = null;
|
||||
|
||||
Core.Spectre.ProgressSingleSpinner(ctx =>
|
||||
{
|
||||
ctx.AddTask("Identifying file filter...").IsIndeterminate();
|
||||
inputFilter = filtersList.GetFilter(imagePath);
|
||||
});
|
||||
|
||||
if(inputFilter == null)
|
||||
{
|
||||
AaruConsole.ErrorWriteLine("Cannot open specified file.");
|
||||
|
||||
return (int)ErrorNumber.CannotOpenFile;
|
||||
}
|
||||
|
||||
Encoding encodingClass = null;
|
||||
|
||||
if(encoding != null)
|
||||
try
|
||||
{
|
||||
encodingClass = Claunia.Encoding.Encoding.GetEncoding(encoding);
|
||||
|
||||
if(verbose)
|
||||
AaruConsole.VerboseWriteLine("Using encoding for {0}.", encodingClass.EncodingName);
|
||||
}
|
||||
catch(ArgumentException)
|
||||
{
|
||||
AaruConsole.ErrorWriteLine("Specified encoding is not supported.");
|
||||
|
||||
return (int)ErrorNumber.EncodingUnknown;
|
||||
}
|
||||
|
||||
if(verbose)
|
||||
AaruConsole.WriteEvent += (format, objects) =>
|
||||
{
|
||||
if(objects is null)
|
||||
AnsiConsole.Markup(format);
|
||||
else
|
||||
AnsiConsole.Markup(format, objects);
|
||||
};
|
||||
PluginBase plugins = GetPluginBase.Instance;
|
||||
|
||||
Statistics.AddCommand("fs-info");
|
||||
bool checkRaw = false;
|
||||
|
||||
AaruConsole.DebugWriteLine("Fs-info command", "--debug={0}", debug);
|
||||
AaruConsole.DebugWriteLine("Fs-info command", "--encoding={0}", encoding);
|
||||
AaruConsole.DebugWriteLine("Fs-info command", "--filesystems={0}", filesystems);
|
||||
AaruConsole.DebugWriteLine("Fs-info command", "--input={0}", imagePath);
|
||||
AaruConsole.DebugWriteLine("Fs-info command", "--partitions={0}", partitions);
|
||||
AaruConsole.DebugWriteLine("Fs-info command", "--verbose={0}", verbose);
|
||||
|
||||
var filtersList = new FiltersList();
|
||||
IFilter inputFilter = null;
|
||||
try
|
||||
{
|
||||
IMediaImage imageFormat = null;
|
||||
IBaseImage baseImage = null;
|
||||
|
||||
Core.Spectre.ProgressSingleSpinner(ctx =>
|
||||
{
|
||||
ctx.AddTask("Identifying file filter...").IsIndeterminate();
|
||||
inputFilter = filtersList.GetFilter(imagePath);
|
||||
ctx.AddTask("Identifying image format...").IsIndeterminate();
|
||||
baseImage = ImageFormat.Detect(inputFilter);
|
||||
imageFormat = baseImage as IMediaImage;
|
||||
});
|
||||
|
||||
if(inputFilter == null)
|
||||
if(baseImage == null)
|
||||
{
|
||||
AaruConsole.ErrorWriteLine("Cannot open specified file.");
|
||||
AaruConsole.WriteLine("Image format not identified, not proceeding with analysis.");
|
||||
|
||||
return (int)ErrorNumber.CannotOpenFile;
|
||||
return (int)ErrorNumber.UnrecognizedFormat;
|
||||
}
|
||||
|
||||
Encoding encodingClass = null;
|
||||
if(imageFormat == null)
|
||||
{
|
||||
AaruConsole.WriteLine("Command not supported for this image type.");
|
||||
|
||||
if(encoding != null)
|
||||
try
|
||||
{
|
||||
encodingClass = Claunia.Encoding.Encoding.GetEncoding(encoding);
|
||||
return (int)ErrorNumber.InvalidArgument;
|
||||
}
|
||||
|
||||
if(verbose)
|
||||
AaruConsole.VerboseWriteLine("Using encoding for {0}.", encodingClass.EncodingName);
|
||||
}
|
||||
catch(ArgumentException)
|
||||
{
|
||||
AaruConsole.ErrorWriteLine("Specified encoding is not supported.");
|
||||
if(verbose)
|
||||
AaruConsole.VerboseWriteLine("Image format identified by {0} ({1}).", imageFormat.Name, imageFormat.Id);
|
||||
else
|
||||
AaruConsole.WriteLine("Image format identified by {0}.", imageFormat.Name);
|
||||
|
||||
return (int)ErrorNumber.EncodingUnknown;
|
||||
}
|
||||
|
||||
PluginBase plugins = GetPluginBase.Instance;
|
||||
|
||||
bool checkRaw = false;
|
||||
AaruConsole.WriteLine();
|
||||
|
||||
try
|
||||
{
|
||||
IMediaImage imageFormat = null;
|
||||
ErrorNumber opened = ErrorNumber.NoData;
|
||||
|
||||
Core.Spectre.ProgressSingleSpinner(ctx =>
|
||||
{
|
||||
ctx.AddTask("Identifying image format...").IsIndeterminate();
|
||||
imageFormat = ImageFormat.Detect(inputFilter);
|
||||
ctx.AddTask("Opening image file...").IsIndeterminate();
|
||||
opened = imageFormat.Open(inputFilter);
|
||||
});
|
||||
|
||||
if(imageFormat == null)
|
||||
if(opened != ErrorNumber.NoError)
|
||||
{
|
||||
AaruConsole.WriteLine("Image format not identified, not proceeding with analysis.");
|
||||
AaruConsole.WriteLine("Unable to open image format");
|
||||
AaruConsole.WriteLine("Error {0}", opened);
|
||||
|
||||
return (int)ErrorNumber.UnrecognizedFormat;
|
||||
return (int)opened;
|
||||
}
|
||||
|
||||
if(verbose)
|
||||
AaruConsole.VerboseWriteLine("Image format identified by {0} ({1}).", imageFormat.Name,
|
||||
imageFormat.Id);
|
||||
{
|
||||
ImageInfo.PrintImageInfo(imageFormat);
|
||||
AaruConsole.WriteLine();
|
||||
}
|
||||
|
||||
Statistics.AddMediaFormat(imageFormat.Format);
|
||||
Statistics.AddMedia(imageFormat.Info.MediaType, false);
|
||||
Statistics.AddFilter(inputFilter.Name);
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
AaruConsole.ErrorWriteLine("Unable to open image format");
|
||||
AaruConsole.ErrorWriteLine("Error: {0}", ex.Message);
|
||||
AaruConsole.DebugWriteLine("Fs-info command", "Stack trace: {0}", ex.StackTrace);
|
||||
|
||||
return (int)ErrorNumber.CannotOpenFormat;
|
||||
}
|
||||
|
||||
List<string> idPlugins = null;
|
||||
IFilesystem plugin;
|
||||
string information;
|
||||
|
||||
if(partitions)
|
||||
{
|
||||
List<Partition> partitionsList = null;
|
||||
|
||||
Core.Spectre.ProgressSingleSpinner(ctx =>
|
||||
{
|
||||
ctx.AddTask("Enumerating partitions...").IsIndeterminate();
|
||||
partitionsList = Core.Partitions.GetAll(imageFormat);
|
||||
});
|
||||
|
||||
Core.Partitions.AddSchemesToStats(partitionsList);
|
||||
|
||||
if(partitionsList.Count == 0)
|
||||
{
|
||||
AaruConsole.DebugWriteLine("Fs-info command", "No partitions found");
|
||||
|
||||
if(!filesystems)
|
||||
{
|
||||
AaruConsole.WriteLine("No partitions founds, not searching for filesystems");
|
||||
|
||||
return (int)ErrorNumber.NothingFound;
|
||||
}
|
||||
|
||||
checkRaw = true;
|
||||
}
|
||||
else
|
||||
AaruConsole.WriteLine("Image format identified by {0}.", imageFormat.Name);
|
||||
|
||||
AaruConsole.WriteLine();
|
||||
|
||||
try
|
||||
{
|
||||
ErrorNumber opened = ErrorNumber.NoData;
|
||||
AaruConsole.WriteLine("{0} partitions found.", partitionsList.Count);
|
||||
|
||||
Core.Spectre.ProgressSingleSpinner(ctx =>
|
||||
for(int i = 0; i < partitionsList.Count; i++)
|
||||
{
|
||||
ctx.AddTask("Opening image file...").IsIndeterminate();
|
||||
opened = imageFormat.Open(inputFilter);
|
||||
});
|
||||
Table table = new();
|
||||
table.Title = new TableTitle($"Partition {partitionsList[i].Sequence}:");
|
||||
table.AddColumn("");
|
||||
table.AddColumn("");
|
||||
table.HideHeaders();
|
||||
|
||||
if(opened != ErrorNumber.NoError)
|
||||
{
|
||||
AaruConsole.WriteLine("Unable to open image format");
|
||||
AaruConsole.WriteLine("Error {0}", opened);
|
||||
table.AddRow("Name", Markup.Escape(partitionsList[i].Name ?? ""));
|
||||
table.AddRow("Type", Markup.Escape(partitionsList[i].Type ?? ""));
|
||||
table.AddRow("Start", $"sector {partitionsList[i].Start}, byte {partitionsList[i].Offset}");
|
||||
|
||||
return (int)opened;
|
||||
}
|
||||
table.AddRow("Length", $"{partitionsList[i].Length} sectors, {partitionsList[i].Size} bytes");
|
||||
|
||||
if(verbose)
|
||||
{
|
||||
ImageInfo.PrintImageInfo(imageFormat);
|
||||
AaruConsole.WriteLine();
|
||||
}
|
||||
table.AddRow("Scheme", Markup.Escape(partitionsList[i].Scheme ?? ""));
|
||||
table.AddRow("Description", Markup.Escape(partitionsList[i].Description ?? ""));
|
||||
|
||||
Statistics.AddMediaFormat(imageFormat.Format);
|
||||
Statistics.AddMedia(imageFormat.Info.MediaType, false);
|
||||
Statistics.AddFilter(inputFilter.Name);
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
AaruConsole.ErrorWriteLine("Unable to open image format");
|
||||
AaruConsole.ErrorWriteLine("Error: {0}", ex.Message);
|
||||
AaruConsole.DebugWriteLine("Fs-info command", "Stack trace: {0}", ex.StackTrace);
|
||||
|
||||
return (int)ErrorNumber.CannotOpenFormat;
|
||||
}
|
||||
|
||||
List<string> idPlugins = null;
|
||||
IFilesystem plugin;
|
||||
string information;
|
||||
|
||||
if(partitions)
|
||||
{
|
||||
List<Partition> partitionsList = null;
|
||||
|
||||
Core.Spectre.ProgressSingleSpinner(ctx =>
|
||||
{
|
||||
ctx.AddTask("Enumerating partitions...").IsIndeterminate();
|
||||
partitionsList = Core.Partitions.GetAll(imageFormat);
|
||||
});
|
||||
|
||||
Core.Partitions.AddSchemesToStats(partitionsList);
|
||||
|
||||
if(partitionsList.Count == 0)
|
||||
{
|
||||
AaruConsole.DebugWriteLine("Fs-info command", "No partitions found");
|
||||
AnsiConsole.Render(table);
|
||||
|
||||
if(!filesystems)
|
||||
{
|
||||
AaruConsole.WriteLine("No partitions founds, not searching for filesystems");
|
||||
continue;
|
||||
|
||||
return (int)ErrorNumber.NothingFound;
|
||||
Core.Spectre.ProgressSingleSpinner(ctx =>
|
||||
{
|
||||
ctx.AddTask("Identifying filesystems on partition...").IsIndeterminate();
|
||||
Core.Filesystems.Identify(imageFormat, out idPlugins, partitionsList[i]);
|
||||
});
|
||||
|
||||
if(idPlugins.Count == 0)
|
||||
AaruConsole.WriteLine("[bold]Filesystem not identified[/]");
|
||||
else if(idPlugins.Count > 1)
|
||||
{
|
||||
AaruConsole.WriteLine($"[italic]Identified by {idPlugins.Count} plugins[/]");
|
||||
|
||||
foreach(string pluginName in idPlugins)
|
||||
if(plugins.PluginsList.TryGetValue(pluginName, out plugin))
|
||||
{
|
||||
AaruConsole.WriteLine($"[bold]As identified by {plugin.Name}.[/]");
|
||||
|
||||
plugin.GetInformation(imageFormat, partitionsList[i], out information,
|
||||
encodingClass);
|
||||
|
||||
AaruConsole.Write(information);
|
||||
Statistics.AddFilesystem(plugin.XmlFsType.Type);
|
||||
}
|
||||
}
|
||||
|
||||
checkRaw = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
AaruConsole.WriteLine("{0} partitions found.", partitionsList.Count);
|
||||
|
||||
for(int i = 0; i < partitionsList.Count; i++)
|
||||
else
|
||||
{
|
||||
Table table = new();
|
||||
table.Title = new TableTitle($"Partition {partitionsList[i].Sequence}:");
|
||||
table.AddColumn("");
|
||||
table.AddColumn("");
|
||||
table.HideHeaders();
|
||||
plugins.PluginsList.TryGetValue(idPlugins[0], out plugin);
|
||||
|
||||
table.AddRow("Name", Markup.Escape(partitionsList[i].Name ?? ""));
|
||||
table.AddRow("Type", Markup.Escape(partitionsList[i].Type ?? ""));
|
||||
table.AddRow("Start", $"sector {partitionsList[i].Start}, byte {partitionsList[i].Offset}");
|
||||
|
||||
table.AddRow("Length",
|
||||
$"{partitionsList[i].Length} sectors, {partitionsList[i].Size} bytes");
|
||||
|
||||
table.AddRow("Scheme", Markup.Escape(partitionsList[i].Scheme ?? ""));
|
||||
table.AddRow("Description", Markup.Escape(partitionsList[i].Description ?? ""));
|
||||
|
||||
AnsiConsole.Render(table);
|
||||
|
||||
if(!filesystems)
|
||||
if(plugin == null)
|
||||
continue;
|
||||
|
||||
Core.Spectre.ProgressSingleSpinner(ctx =>
|
||||
{
|
||||
ctx.AddTask("Identifying filesystems on partition...").IsIndeterminate();
|
||||
Core.Filesystems.Identify(imageFormat, out idPlugins, partitionsList[i]);
|
||||
});
|
||||
|
||||
if(idPlugins.Count == 0)
|
||||
AaruConsole.WriteLine("[bold]Filesystem not identified[/]");
|
||||
else if(idPlugins.Count > 1)
|
||||
{
|
||||
AaruConsole.WriteLine($"[italic]Identified by {idPlugins.Count} plugins[/]");
|
||||
|
||||
foreach(string pluginName in idPlugins)
|
||||
if(plugins.PluginsList.TryGetValue(pluginName, out plugin))
|
||||
{
|
||||
AaruConsole.WriteLine($"[bold]As identified by {plugin.Name}.[/]");
|
||||
|
||||
plugin.GetInformation(imageFormat, partitionsList[i], out information,
|
||||
encodingClass);
|
||||
|
||||
AaruConsole.Write(information);
|
||||
Statistics.AddFilesystem(plugin.XmlFsType.Type);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
plugins.PluginsList.TryGetValue(idPlugins[0], out plugin);
|
||||
|
||||
if(plugin == null)
|
||||
continue;
|
||||
|
||||
AaruConsole.WriteLine($"[bold]Identified by {plugin.Name}.[/]");
|
||||
plugin.GetInformation(imageFormat, partitionsList[i], out information, encodingClass);
|
||||
AaruConsole.Write("{0}", information);
|
||||
Statistics.AddFilesystem(plugin.XmlFsType.Type);
|
||||
}
|
||||
|
||||
AaruConsole.WriteLine();
|
||||
AaruConsole.WriteLine($"[bold]Identified by {plugin.Name}.[/]");
|
||||
plugin.GetInformation(imageFormat, partitionsList[i], out information, encodingClass);
|
||||
AaruConsole.Write("{0}", information);
|
||||
Statistics.AddFilesystem(plugin.XmlFsType.Type);
|
||||
}
|
||||
|
||||
AaruConsole.WriteLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(checkRaw)
|
||||
if(checkRaw)
|
||||
{
|
||||
var wholePart = new Partition
|
||||
{
|
||||
var wholePart = new Partition
|
||||
{
|
||||
Name = "Whole device",
|
||||
Length = imageFormat.Info.Sectors,
|
||||
Size = imageFormat.Info.Sectors * imageFormat.Info.SectorSize
|
||||
};
|
||||
Name = "Whole device",
|
||||
Length = imageFormat.Info.Sectors,
|
||||
Size = imageFormat.Info.Sectors * imageFormat.Info.SectorSize
|
||||
};
|
||||
|
||||
Core.Spectre.ProgressSingleSpinner(ctx =>
|
||||
{
|
||||
ctx.AddTask("Identifying filesystems...").IsIndeterminate();
|
||||
Core.Filesystems.Identify(imageFormat, out idPlugins, wholePart);
|
||||
});
|
||||
Core.Spectre.ProgressSingleSpinner(ctx =>
|
||||
{
|
||||
ctx.AddTask("Identifying filesystems...").IsIndeterminate();
|
||||
Core.Filesystems.Identify(imageFormat, out idPlugins, wholePart);
|
||||
});
|
||||
|
||||
if(idPlugins.Count == 0)
|
||||
AaruConsole.WriteLine("[bold]Filesystem not identified[/]");
|
||||
else if(idPlugins.Count > 1)
|
||||
{
|
||||
AaruConsole.WriteLine($"[italic]Identified by {idPlugins.Count} plugins[/]");
|
||||
if(idPlugins.Count == 0)
|
||||
AaruConsole.WriteLine("[bold]Filesystem not identified[/]");
|
||||
else if(idPlugins.Count > 1)
|
||||
{
|
||||
AaruConsole.WriteLine($"[italic]Identified by {idPlugins.Count} plugins[/]");
|
||||
|
||||
foreach(string pluginName in idPlugins)
|
||||
if(plugins.PluginsList.TryGetValue(pluginName, out plugin))
|
||||
{
|
||||
AaruConsole.WriteLine($"[bold]As identified by {plugin.Name}.[/]");
|
||||
plugin.GetInformation(imageFormat, wholePart, out information, encodingClass);
|
||||
AaruConsole.Write(information);
|
||||
Statistics.AddFilesystem(plugin.XmlFsType.Type);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
plugins.PluginsList.TryGetValue(idPlugins[0], out plugin);
|
||||
|
||||
if(plugin != null)
|
||||
foreach(string pluginName in idPlugins)
|
||||
if(plugins.PluginsList.TryGetValue(pluginName, out plugin))
|
||||
{
|
||||
AaruConsole.WriteLine($"[bold]Identified by {plugin.Name}.[/]");
|
||||
AaruConsole.WriteLine($"[bold]As identified by {plugin.Name}.[/]");
|
||||
plugin.GetInformation(imageFormat, wholePart, out information, encodingClass);
|
||||
AaruConsole.Write(information);
|
||||
Statistics.AddFilesystem(plugin.XmlFsType.Type);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
plugins.PluginsList.TryGetValue(idPlugins[0], out plugin);
|
||||
|
||||
if(plugin != null)
|
||||
{
|
||||
AaruConsole.WriteLine($"[bold]Identified by {plugin.Name}.[/]");
|
||||
plugin.GetInformation(imageFormat, wholePart, out information, encodingClass);
|
||||
AaruConsole.Write(information);
|
||||
Statistics.AddFilesystem(plugin.XmlFsType.Type);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
AaruConsole.ErrorWriteLine($"Error reading file: {ex.Message}");
|
||||
AaruConsole.DebugWriteLine("Fs-info command", ex.StackTrace);
|
||||
|
||||
return (int)ErrorNumber.UnexpectedException;
|
||||
}
|
||||
|
||||
return (int)ErrorNumber.NoError;
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
AaruConsole.ErrorWriteLine($"Error reading file: {ex.Message}");
|
||||
AaruConsole.DebugWriteLine("Fs-info command", ex.StackTrace);
|
||||
|
||||
return (int)ErrorNumber.UnexpectedException;
|
||||
}
|
||||
|
||||
return (int)ErrorNumber.NoError;
|
||||
}
|
||||
}
|
||||
@@ -45,414 +45,418 @@ using Aaru.Core;
|
||||
using JetBrains.Annotations;
|
||||
using Spectre.Console;
|
||||
|
||||
namespace Aaru.Commands.Filesystem
|
||||
namespace Aaru.Commands.Filesystem;
|
||||
|
||||
internal sealed class LsCommand : Command
|
||||
{
|
||||
internal sealed class LsCommand : Command
|
||||
public LsCommand() : base("list", "Lists files in disc image.")
|
||||
{
|
||||
public LsCommand() : base("list", "Lists files in disc image.")
|
||||
{
|
||||
AddAlias("ls");
|
||||
AddAlias("ls");
|
||||
|
||||
Add(new Option(new[]
|
||||
{
|
||||
"--encoding", "-e"
|
||||
}, "Name of character encoding to use.")
|
||||
{
|
||||
Argument = new Argument<string>(() => null),
|
||||
Required = false
|
||||
});
|
||||
|
||||
Add(new Option(new[]
|
||||
{
|
||||
"--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>
|
||||
Add(new Option(new[]
|
||||
{
|
||||
Arity = ArgumentArity.ExactlyOne,
|
||||
Description = "Media image path",
|
||||
Name = "image-path"
|
||||
"--encoding", "-e"
|
||||
}, "Name of character encoding to use.")
|
||||
{
|
||||
Argument = new Argument<string>(() => null),
|
||||
Required = false
|
||||
});
|
||||
|
||||
Handler = CommandHandler.Create(GetType().GetMethod(nameof(Invoke)));
|
||||
Add(new Option(new[]
|
||||
{
|
||||
"--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 static int Invoke(bool debug, bool verbose, string encoding, string imagePath, bool longFormat,
|
||||
string @namespace, string options)
|
||||
{
|
||||
MainClass.PrintCopyright();
|
||||
|
||||
if(debug)
|
||||
{
|
||||
IAnsiConsole stderrConsole = AnsiConsole.Create(new AnsiConsoleSettings
|
||||
{
|
||||
Out = new AnsiConsoleOutput(System.Console.Error)
|
||||
});
|
||||
|
||||
AaruConsole.DebugWriteLineEvent += (format, objects) =>
|
||||
{
|
||||
if(objects is null)
|
||||
stderrConsole.MarkupLine(format);
|
||||
else
|
||||
stderrConsole.MarkupLine(format, objects);
|
||||
};
|
||||
}
|
||||
|
||||
public static int Invoke(bool debug, bool verbose, string encoding, string imagePath, bool longFormat,
|
||||
string @namespace, string options)
|
||||
{
|
||||
MainClass.PrintCopyright();
|
||||
|
||||
if(debug)
|
||||
if(verbose)
|
||||
AaruConsole.WriteEvent += (format, objects) =>
|
||||
{
|
||||
IAnsiConsole stderrConsole = AnsiConsole.Create(new AnsiConsoleSettings
|
||||
{
|
||||
Out = new AnsiConsoleOutput(System.Console.Error)
|
||||
});
|
||||
if(objects is null)
|
||||
AnsiConsole.Markup(format);
|
||||
else
|
||||
AnsiConsole.Markup(format, objects);
|
||||
};
|
||||
|
||||
AaruConsole.DebugWriteLineEvent += (format, objects) =>
|
||||
{
|
||||
if(objects is null)
|
||||
stderrConsole.MarkupLine(format);
|
||||
else
|
||||
stderrConsole.MarkupLine(format, objects);
|
||||
};
|
||||
AaruConsole.DebugWriteLine("Ls command", "--debug={0}", debug);
|
||||
AaruConsole.DebugWriteLine("Ls command", "--encoding={0}", encoding);
|
||||
AaruConsole.DebugWriteLine("Ls command", "--input={0}", imagePath);
|
||||
AaruConsole.DebugWriteLine("Ls command", "--options={0}", options);
|
||||
AaruConsole.DebugWriteLine("Ls command", "--verbose={0}", verbose);
|
||||
Statistics.AddCommand("ls");
|
||||
|
||||
var filtersList = new FiltersList();
|
||||
IFilter inputFilter = null;
|
||||
|
||||
Core.Spectre.ProgressSingleSpinner(ctx =>
|
||||
{
|
||||
ctx.AddTask("Identifying file filter...").IsIndeterminate();
|
||||
inputFilter = filtersList.GetFilter(imagePath);
|
||||
});
|
||||
|
||||
Dictionary<string, string> parsedOptions = Core.Options.Parse(options);
|
||||
AaruConsole.DebugWriteLine("Ls command", "Parsed options:");
|
||||
|
||||
foreach(KeyValuePair<string, string> parsedOption in parsedOptions)
|
||||
AaruConsole.DebugWriteLine("Ls command", "{0} = {1}", parsedOption.Key, parsedOption.Value);
|
||||
|
||||
parsedOptions.Add("debug", debug.ToString());
|
||||
|
||||
if(inputFilter == null)
|
||||
{
|
||||
AaruConsole.ErrorWriteLine("Cannot open specified file.");
|
||||
|
||||
return (int)ErrorNumber.CannotOpenFile;
|
||||
}
|
||||
|
||||
Encoding encodingClass = null;
|
||||
|
||||
if(encoding != null)
|
||||
try
|
||||
{
|
||||
encodingClass = Claunia.Encoding.Encoding.GetEncoding(encoding);
|
||||
|
||||
if(verbose)
|
||||
AaruConsole.VerboseWriteLine("Using encoding for {0}.", encodingClass.EncodingName);
|
||||
}
|
||||
catch(ArgumentException)
|
||||
{
|
||||
AaruConsole.ErrorWriteLine("Specified encoding is not supported.");
|
||||
|
||||
return (int)ErrorNumber.EncodingUnknown;
|
||||
}
|
||||
|
||||
PluginBase plugins = GetPluginBase.Instance;
|
||||
|
||||
try
|
||||
{
|
||||
IMediaImage imageFormat = null;
|
||||
IBaseImage baseImage = null;
|
||||
|
||||
Core.Spectre.ProgressSingleSpinner(ctx =>
|
||||
{
|
||||
ctx.AddTask("Identifying image format...").IsIndeterminate();
|
||||
baseImage = ImageFormat.Detect(inputFilter);
|
||||
imageFormat = baseImage as IMediaImage;
|
||||
});
|
||||
|
||||
if(baseImage == null)
|
||||
{
|
||||
AaruConsole.WriteLine("Image format not identified, not proceeding with analysis.");
|
||||
|
||||
return (int)ErrorNumber.UnrecognizedFormat;
|
||||
}
|
||||
|
||||
if(imageFormat == null)
|
||||
{
|
||||
AaruConsole.WriteLine("Command not supported for this image type.");
|
||||
|
||||
return (int)ErrorNumber.InvalidArgument;
|
||||
}
|
||||
|
||||
if(verbose)
|
||||
AaruConsole.WriteEvent += (format, objects) =>
|
||||
{
|
||||
if(objects is null)
|
||||
AnsiConsole.Markup(format);
|
||||
else
|
||||
AnsiConsole.Markup(format, objects);
|
||||
};
|
||||
|
||||
AaruConsole.DebugWriteLine("Ls command", "--debug={0}", debug);
|
||||
AaruConsole.DebugWriteLine("Ls command", "--encoding={0}", encoding);
|
||||
AaruConsole.DebugWriteLine("Ls command", "--input={0}", imagePath);
|
||||
AaruConsole.DebugWriteLine("Ls command", "--options={0}", options);
|
||||
AaruConsole.DebugWriteLine("Ls command", "--verbose={0}", verbose);
|
||||
Statistics.AddCommand("ls");
|
||||
|
||||
var filtersList = new FiltersList();
|
||||
IFilter inputFilter = null;
|
||||
|
||||
Core.Spectre.ProgressSingleSpinner(ctx =>
|
||||
{
|
||||
ctx.AddTask("Identifying file filter...").IsIndeterminate();
|
||||
inputFilter = filtersList.GetFilter(imagePath);
|
||||
});
|
||||
|
||||
Dictionary<string, string> parsedOptions = Core.Options.Parse(options);
|
||||
AaruConsole.DebugWriteLine("Ls command", "Parsed options:");
|
||||
|
||||
foreach(KeyValuePair<string, string> parsedOption in parsedOptions)
|
||||
AaruConsole.DebugWriteLine("Ls command", "{0} = {1}", parsedOption.Key, parsedOption.Value);
|
||||
|
||||
parsedOptions.Add("debug", debug.ToString());
|
||||
|
||||
if(inputFilter == null)
|
||||
{
|
||||
AaruConsole.ErrorWriteLine("Cannot open specified file.");
|
||||
|
||||
return (int)ErrorNumber.CannotOpenFile;
|
||||
}
|
||||
|
||||
Encoding encodingClass = null;
|
||||
|
||||
if(encoding != null)
|
||||
try
|
||||
{
|
||||
encodingClass = Claunia.Encoding.Encoding.GetEncoding(encoding);
|
||||
|
||||
if(verbose)
|
||||
AaruConsole.VerboseWriteLine("Using encoding for {0}.", encodingClass.EncodingName);
|
||||
}
|
||||
catch(ArgumentException)
|
||||
{
|
||||
AaruConsole.ErrorWriteLine("Specified encoding is not supported.");
|
||||
|
||||
return (int)ErrorNumber.EncodingUnknown;
|
||||
}
|
||||
|
||||
PluginBase plugins = GetPluginBase.Instance;
|
||||
AaruConsole.VerboseWriteLine("Image format identified by {0} ({1}).", imageFormat.Name, imageFormat.Id);
|
||||
else
|
||||
AaruConsole.WriteLine("Image format identified by {0}.", imageFormat.Name);
|
||||
|
||||
try
|
||||
{
|
||||
IMediaImage imageFormat = null;
|
||||
ErrorNumber opened = ErrorNumber.NoData;
|
||||
|
||||
Core.Spectre.ProgressSingleSpinner(ctx =>
|
||||
{
|
||||
ctx.AddTask("Identifying image format...").IsIndeterminate();
|
||||
imageFormat = ImageFormat.Detect(inputFilter);
|
||||
ctx.AddTask("Opening image file...").IsIndeterminate();
|
||||
opened = imageFormat.Open(inputFilter);
|
||||
});
|
||||
|
||||
if(imageFormat == null)
|
||||
if(opened != ErrorNumber.NoError)
|
||||
{
|
||||
AaruConsole.WriteLine("Image format not identified, not proceeding with analysis.");
|
||||
AaruConsole.WriteLine("Unable to open image format");
|
||||
AaruConsole.WriteLine("Error {0}", opened);
|
||||
|
||||
return (int)ErrorNumber.UnrecognizedFormat;
|
||||
return (int)opened;
|
||||
}
|
||||
|
||||
if(verbose)
|
||||
AaruConsole.VerboseWriteLine("Image format identified by {0} ({1}).", imageFormat.Name,
|
||||
imageFormat.Id);
|
||||
else
|
||||
AaruConsole.WriteLine("Image format identified by {0}.", imageFormat.Name);
|
||||
AaruConsole.DebugWriteLine("Ls command", "Correctly opened image file.");
|
||||
|
||||
try
|
||||
{
|
||||
ErrorNumber opened = ErrorNumber.NoData;
|
||||
AaruConsole.DebugWriteLine("Ls command", "Image without headers is {0} bytes.",
|
||||
imageFormat.Info.ImageSize);
|
||||
|
||||
Core.Spectre.ProgressSingleSpinner(ctx =>
|
||||
{
|
||||
ctx.AddTask("Opening image file...").IsIndeterminate();
|
||||
opened = imageFormat.Open(inputFilter);
|
||||
});
|
||||
AaruConsole.DebugWriteLine("Ls command", "Image has {0} sectors.", imageFormat.Info.Sectors);
|
||||
|
||||
if(opened != ErrorNumber.NoError)
|
||||
{
|
||||
AaruConsole.WriteLine("Unable to open image format");
|
||||
AaruConsole.WriteLine("Error {0}", opened);
|
||||
AaruConsole.DebugWriteLine("Ls command", "Image identifies disk type as {0}.",
|
||||
imageFormat.Info.MediaType);
|
||||
|
||||
return (int)opened;
|
||||
}
|
||||
|
||||
AaruConsole.DebugWriteLine("Ls command", "Correctly opened image file.");
|
||||
|
||||
AaruConsole.DebugWriteLine("Ls command", "Image without headers is {0} bytes.",
|
||||
imageFormat.Info.ImageSize);
|
||||
|
||||
AaruConsole.DebugWriteLine("Ls command", "Image has {0} sectors.", imageFormat.Info.Sectors);
|
||||
|
||||
AaruConsole.DebugWriteLine("Ls command", "Image identifies disk type as {0}.",
|
||||
imageFormat.Info.MediaType);
|
||||
|
||||
Statistics.AddMediaFormat(imageFormat.Format);
|
||||
Statistics.AddMedia(imageFormat.Info.MediaType, false);
|
||||
Statistics.AddFilter(inputFilter.Name);
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
AaruConsole.ErrorWriteLine("Unable to open image format");
|
||||
AaruConsole.ErrorWriteLine("Error: {0}", ex.Message);
|
||||
|
||||
return (int)ErrorNumber.CannotOpenFormat;
|
||||
}
|
||||
|
||||
List<Partition> partitions = null;
|
||||
|
||||
Core.Spectre.ProgressSingleSpinner(ctx =>
|
||||
{
|
||||
ctx.AddTask("Enumerating partitions...").IsIndeterminate();
|
||||
partitions = Core.Partitions.GetAll(imageFormat);
|
||||
});
|
||||
|
||||
Core.Partitions.AddSchemesToStats(partitions);
|
||||
|
||||
if(partitions.Count == 0)
|
||||
{
|
||||
AaruConsole.DebugWriteLine("Ls command", "No partitions found");
|
||||
|
||||
partitions.Add(new Partition
|
||||
{
|
||||
Description = "Whole device",
|
||||
Length = imageFormat.Info.Sectors,
|
||||
Offset = 0,
|
||||
Size = imageFormat.Info.SectorSize * imageFormat.Info.Sectors,
|
||||
Sequence = 1,
|
||||
Start = 0
|
||||
});
|
||||
}
|
||||
|
||||
AaruConsole.WriteLine("{0} partitions found.", partitions.Count);
|
||||
|
||||
for(int i = 0; i < partitions.Count; i++)
|
||||
{
|
||||
AaruConsole.WriteLine();
|
||||
AaruConsole.WriteLine("[bold]Partition {0}:[/]", partitions[i].Sequence);
|
||||
|
||||
List<string> idPlugins = null;
|
||||
|
||||
Core.Spectre.ProgressSingleSpinner(ctx =>
|
||||
{
|
||||
ctx.AddTask("Identifying filesystems on partition...").IsIndeterminate();
|
||||
Core.Filesystems.Identify(imageFormat, out idPlugins, partitions[i]);
|
||||
});
|
||||
|
||||
if(idPlugins.Count == 0)
|
||||
AaruConsole.WriteLine("Filesystem not identified");
|
||||
else
|
||||
{
|
||||
IReadOnlyFilesystem plugin;
|
||||
ErrorNumber error = ErrorNumber.InvalidArgument;
|
||||
|
||||
if(idPlugins.Count > 1)
|
||||
{
|
||||
AaruConsole.WriteLine($"[italic]Identified by {idPlugins.Count} plugins[/]");
|
||||
|
||||
foreach(string pluginName in idPlugins)
|
||||
if(plugins.ReadOnlyFilesystems.TryGetValue(pluginName, out plugin))
|
||||
{
|
||||
AaruConsole.WriteLine($"[bold]As identified by {plugin.Name}.[/]");
|
||||
|
||||
var fs = (IReadOnlyFilesystem)plugin.GetType().GetConstructor(Type.EmptyTypes)?.
|
||||
Invoke(new object[]
|
||||
{});
|
||||
|
||||
if(fs == null)
|
||||
continue;
|
||||
|
||||
Core.Spectre.ProgressSingleSpinner(ctx =>
|
||||
{
|
||||
ctx.AddTask("Mounting filesystem...").IsIndeterminate();
|
||||
|
||||
error = fs.Mount(imageFormat, partitions[i], encodingClass, parsedOptions,
|
||||
@namespace);
|
||||
});
|
||||
|
||||
if(error == ErrorNumber.NoError)
|
||||
{
|
||||
ListFilesInDir("/", fs, longFormat);
|
||||
|
||||
Statistics.AddFilesystem(fs.XmlFsType.Type);
|
||||
}
|
||||
else
|
||||
AaruConsole.ErrorWriteLine("Unable to mount device, error {0}",
|
||||
error.ToString());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
plugins.ReadOnlyFilesystems.TryGetValue(idPlugins[0], out plugin);
|
||||
|
||||
if(plugin == null)
|
||||
continue;
|
||||
|
||||
AaruConsole.WriteLine($"[bold]Identified by {plugin.Name}.[/]");
|
||||
|
||||
var fs = (IReadOnlyFilesystem)plugin.GetType().GetConstructor(Type.EmptyTypes)?.
|
||||
Invoke(new object[]
|
||||
{});
|
||||
|
||||
if(fs == null)
|
||||
continue;
|
||||
|
||||
Core.Spectre.ProgressSingleSpinner(ctx =>
|
||||
{
|
||||
ctx.AddTask("Mounting filesystem...").IsIndeterminate();
|
||||
error = fs.Mount(imageFormat, partitions[i], encodingClass, parsedOptions, @namespace);
|
||||
});
|
||||
|
||||
if(error == ErrorNumber.NoError)
|
||||
{
|
||||
ListFilesInDir("/", fs, longFormat);
|
||||
|
||||
Statistics.AddFilesystem(fs.XmlFsType.Type);
|
||||
}
|
||||
else
|
||||
AaruConsole.ErrorWriteLine("Unable to mount device, error {0}", error.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
Statistics.AddMediaFormat(imageFormat.Format);
|
||||
Statistics.AddMedia(imageFormat.Info.MediaType, false);
|
||||
Statistics.AddFilter(inputFilter.Name);
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
AaruConsole.ErrorWriteLine($"Error reading file: {ex.Message}");
|
||||
AaruConsole.DebugWriteLine("Ls command", ex.StackTrace);
|
||||
AaruConsole.ErrorWriteLine("Unable to open image format");
|
||||
AaruConsole.ErrorWriteLine("Error: {0}", ex.Message);
|
||||
|
||||
return (int)ErrorNumber.UnexpectedException;
|
||||
return (int)ErrorNumber.CannotOpenFormat;
|
||||
}
|
||||
|
||||
return (int)ErrorNumber.NoError;
|
||||
}
|
||||
|
||||
static void ListFilesInDir(string path, [NotNull] IReadOnlyFilesystem fs, bool longFormat)
|
||||
{
|
||||
ErrorNumber error = ErrorNumber.InvalidArgument;
|
||||
List<string> directory = new();
|
||||
|
||||
if(path.StartsWith('/'))
|
||||
path = path.Substring(1);
|
||||
|
||||
AaruConsole.WriteLine(string.IsNullOrEmpty(path) ? "Root directory" : $"Directory: {Markup.Escape(path)}");
|
||||
List<Partition> partitions = null;
|
||||
|
||||
Core.Spectre.ProgressSingleSpinner(ctx =>
|
||||
{
|
||||
ctx.AddTask("Reading directory...").IsIndeterminate();
|
||||
error = fs.ReadDir(path, out directory);
|
||||
ctx.AddTask("Enumerating partitions...").IsIndeterminate();
|
||||
partitions = Core.Partitions.GetAll(imageFormat);
|
||||
});
|
||||
|
||||
if(error != ErrorNumber.NoError)
|
||||
{
|
||||
AaruConsole.ErrorWriteLine("Error {0} reading root directory {1}", error.ToString(), path);
|
||||
Core.Partitions.AddSchemesToStats(partitions);
|
||||
|
||||
return;
|
||||
if(partitions.Count == 0)
|
||||
{
|
||||
AaruConsole.DebugWriteLine("Ls command", "No partitions found");
|
||||
|
||||
partitions.Add(new Partition
|
||||
{
|
||||
Description = "Whole device",
|
||||
Length = imageFormat.Info.Sectors,
|
||||
Offset = 0,
|
||||
Size = imageFormat.Info.SectorSize * imageFormat.Info.Sectors,
|
||||
Sequence = 1,
|
||||
Start = 0
|
||||
});
|
||||
}
|
||||
|
||||
Dictionary<string, FileEntryInfo> stats = new();
|
||||
AaruConsole.WriteLine("{0} partitions found.", partitions.Count);
|
||||
|
||||
AnsiConsole.Progress().AutoClear(true).HideCompleted(true).
|
||||
Columns(new TaskDescriptionColumn(), new ProgressBarColumn(), new PercentageColumn()).
|
||||
Start(ctx =>
|
||||
{
|
||||
ProgressTask task = ctx.AddTask("Retrieving file information...");
|
||||
task.MaxValue = directory.Count;
|
||||
for(int i = 0; i < partitions.Count; i++)
|
||||
{
|
||||
AaruConsole.WriteLine();
|
||||
AaruConsole.WriteLine("[bold]Partition {0}:[/]", partitions[i].Sequence);
|
||||
|
||||
foreach(string entry in directory)
|
||||
{
|
||||
task.Increment(1);
|
||||
fs.Stat(path + "/" + entry, out FileEntryInfo stat);
|
||||
List<string> idPlugins = null;
|
||||
|
||||
stats.Add(entry, stat);
|
||||
}
|
||||
});
|
||||
|
||||
foreach(KeyValuePair<string, FileEntryInfo> entry in
|
||||
stats.OrderBy(e => e.Value?.Attributes.HasFlag(FileAttributes.Directory) == false))
|
||||
if(longFormat)
|
||||
Core.Spectre.ProgressSingleSpinner(ctx =>
|
||||
{
|
||||
if(entry.Value != null)
|
||||
{
|
||||
if(entry.Value.Attributes.HasFlag(FileAttributes.Directory))
|
||||
AaruConsole.WriteLine("{0, 10:d} {0, 12:T} {1, -20} {2}", entry.Value.CreationTimeUtc,
|
||||
"<DIR>", Markup.Escape(entry.Key));
|
||||
else
|
||||
AaruConsole.WriteLine("{0, 10:d} {0, 12:T} {1, 6}{2, 14:N0} {3}",
|
||||
entry.Value.CreationTimeUtc, entry.Value.Inode, entry.Value.Length,
|
||||
Markup.Escape(entry.Key));
|
||||
ctx.AddTask("Identifying filesystems on partition...").IsIndeterminate();
|
||||
Core.Filesystems.Identify(imageFormat, out idPlugins, partitions[i]);
|
||||
});
|
||||
|
||||
error = fs.ListXAttr(path + "/" + entry.Key, out List<string> xattrs);
|
||||
|
||||
if(error != ErrorNumber.NoError)
|
||||
continue;
|
||||
|
||||
foreach(string xattr in xattrs)
|
||||
{
|
||||
byte[] xattrBuf = Array.Empty<byte>();
|
||||
error = fs.GetXattr(path + "/" + entry.Key, xattr, ref xattrBuf);
|
||||
|
||||
if(error == ErrorNumber.NoError)
|
||||
AaruConsole.WriteLine("\t\t{0}\t{1:##,#}", Markup.Escape(xattr), xattrBuf.Length);
|
||||
}
|
||||
}
|
||||
else
|
||||
AaruConsole.WriteLine("{0, 47}{1}", string.Empty, Markup.Escape(entry.Key));
|
||||
}
|
||||
if(idPlugins.Count == 0)
|
||||
AaruConsole.WriteLine("Filesystem not identified");
|
||||
else
|
||||
{
|
||||
AaruConsole.
|
||||
WriteLine(entry.Value?.Attributes.HasFlag(FileAttributes.Directory) == true ? "{0}/" : "{0}",
|
||||
entry.Key);
|
||||
IReadOnlyFilesystem plugin;
|
||||
ErrorNumber error = ErrorNumber.InvalidArgument;
|
||||
|
||||
if(idPlugins.Count > 1)
|
||||
{
|
||||
AaruConsole.WriteLine($"[italic]Identified by {idPlugins.Count} plugins[/]");
|
||||
|
||||
foreach(string pluginName in idPlugins)
|
||||
if(plugins.ReadOnlyFilesystems.TryGetValue(pluginName, out plugin))
|
||||
{
|
||||
AaruConsole.WriteLine($"[bold]As identified by {plugin.Name}.[/]");
|
||||
|
||||
var fs = (IReadOnlyFilesystem)plugin.GetType().GetConstructor(Type.EmptyTypes)?.
|
||||
Invoke(new object[]
|
||||
{});
|
||||
|
||||
if(fs == null)
|
||||
continue;
|
||||
|
||||
Core.Spectre.ProgressSingleSpinner(ctx =>
|
||||
{
|
||||
ctx.AddTask("Mounting filesystem...").IsIndeterminate();
|
||||
|
||||
error = fs.Mount(imageFormat, partitions[i], encodingClass, parsedOptions,
|
||||
@namespace);
|
||||
});
|
||||
|
||||
if(error == ErrorNumber.NoError)
|
||||
{
|
||||
ListFilesInDir("/", fs, longFormat);
|
||||
|
||||
Statistics.AddFilesystem(fs.XmlFsType.Type);
|
||||
}
|
||||
else
|
||||
AaruConsole.ErrorWriteLine("Unable to mount device, error {0}", error.ToString());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
plugins.ReadOnlyFilesystems.TryGetValue(idPlugins[0], out plugin);
|
||||
|
||||
if(plugin == null)
|
||||
continue;
|
||||
|
||||
AaruConsole.WriteLine($"[bold]Identified by {plugin.Name}.[/]");
|
||||
|
||||
var fs = (IReadOnlyFilesystem)plugin.GetType().GetConstructor(Type.EmptyTypes)?.
|
||||
Invoke(new object[]
|
||||
{});
|
||||
|
||||
if(fs == null)
|
||||
continue;
|
||||
|
||||
Core.Spectre.ProgressSingleSpinner(ctx =>
|
||||
{
|
||||
ctx.AddTask("Mounting filesystem...").IsIndeterminate();
|
||||
error = fs.Mount(imageFormat, partitions[i], encodingClass, parsedOptions, @namespace);
|
||||
});
|
||||
|
||||
if(error == ErrorNumber.NoError)
|
||||
{
|
||||
ListFilesInDir("/", fs, longFormat);
|
||||
|
||||
Statistics.AddFilesystem(fs.XmlFsType.Type);
|
||||
}
|
||||
else
|
||||
AaruConsole.ErrorWriteLine("Unable to mount device, error {0}", error.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
AaruConsole.WriteLine();
|
||||
|
||||
foreach(KeyValuePair<string, FileEntryInfo> subdirectory in
|
||||
stats.Where(e => e.Value?.Attributes.HasFlag(FileAttributes.Directory) == true))
|
||||
ListFilesInDir(path + "/" + subdirectory.Key, fs, longFormat);
|
||||
}
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
AaruConsole.ErrorWriteLine($"Error reading file: {ex.Message}");
|
||||
AaruConsole.DebugWriteLine("Ls command", ex.StackTrace);
|
||||
|
||||
return (int)ErrorNumber.UnexpectedException;
|
||||
}
|
||||
|
||||
return (int)ErrorNumber.NoError;
|
||||
}
|
||||
|
||||
static void ListFilesInDir(string path, [NotNull] IReadOnlyFilesystem fs, bool longFormat)
|
||||
{
|
||||
ErrorNumber error = ErrorNumber.InvalidArgument;
|
||||
List<string> directory = new();
|
||||
|
||||
if(path.StartsWith('/'))
|
||||
path = path.Substring(1);
|
||||
|
||||
AaruConsole.WriteLine(string.IsNullOrEmpty(path) ? "Root directory" : $"Directory: {Markup.Escape(path)}");
|
||||
|
||||
Core.Spectre.ProgressSingleSpinner(ctx =>
|
||||
{
|
||||
ctx.AddTask("Reading directory...").IsIndeterminate();
|
||||
error = fs.ReadDir(path, out directory);
|
||||
});
|
||||
|
||||
if(error != ErrorNumber.NoError)
|
||||
{
|
||||
AaruConsole.ErrorWriteLine("Error {0} reading root directory {1}", error.ToString(), path);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Dictionary<string, FileEntryInfo> stats = new();
|
||||
|
||||
AnsiConsole.Progress().AutoClear(true).HideCompleted(true).
|
||||
Columns(new TaskDescriptionColumn(), new ProgressBarColumn(), new PercentageColumn()).Start(ctx =>
|
||||
{
|
||||
ProgressTask task = ctx.AddTask("Retrieving file information...");
|
||||
task.MaxValue = directory.Count;
|
||||
|
||||
foreach(string entry in directory)
|
||||
{
|
||||
task.Increment(1);
|
||||
fs.Stat(path + "/" + entry, out FileEntryInfo stat);
|
||||
|
||||
stats.Add(entry, stat);
|
||||
}
|
||||
});
|
||||
|
||||
foreach(KeyValuePair<string, FileEntryInfo> entry in
|
||||
stats.OrderBy(e => e.Value?.Attributes.HasFlag(FileAttributes.Directory) == false))
|
||||
if(longFormat)
|
||||
{
|
||||
if(entry.Value != null)
|
||||
{
|
||||
if(entry.Value.Attributes.HasFlag(FileAttributes.Directory))
|
||||
AaruConsole.WriteLine("{0, 10:d} {0, 12:T} {1, -20} {2}", entry.Value.CreationTimeUtc,
|
||||
"<DIR>", Markup.Escape(entry.Key));
|
||||
else
|
||||
AaruConsole.WriteLine("{0, 10:d} {0, 12:T} {1, 6}{2, 14:N0} {3}", entry.Value.CreationTimeUtc,
|
||||
entry.Value.Inode, entry.Value.Length, Markup.Escape(entry.Key));
|
||||
|
||||
error = fs.ListXAttr(path + "/" + entry.Key, out List<string> xattrs);
|
||||
|
||||
if(error != ErrorNumber.NoError)
|
||||
continue;
|
||||
|
||||
foreach(string xattr in xattrs)
|
||||
{
|
||||
byte[] xattrBuf = Array.Empty<byte>();
|
||||
error = fs.GetXattr(path + "/" + entry.Key, xattr, ref xattrBuf);
|
||||
|
||||
if(error == ErrorNumber.NoError)
|
||||
AaruConsole.WriteLine("\t\t{0}\t{1:##,#}", Markup.Escape(xattr), xattrBuf.Length);
|
||||
}
|
||||
}
|
||||
else
|
||||
AaruConsole.WriteLine("{0, 47}{1}", string.Empty, Markup.Escape(entry.Key));
|
||||
}
|
||||
else
|
||||
{
|
||||
AaruConsole.
|
||||
WriteLine(entry.Value?.Attributes.HasFlag(FileAttributes.Directory) == true ? "{0}/" : "{0}",
|
||||
entry.Key);
|
||||
}
|
||||
|
||||
AaruConsole.WriteLine();
|
||||
|
||||
foreach(KeyValuePair<string, FileEntryInfo> subdirectory in
|
||||
stats.Where(e => e.Value?.Attributes.HasFlag(FileAttributes.Directory) == true))
|
||||
ListFilesInDir(path + "/" + subdirectory.Key, fs, longFormat);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -42,389 +42,393 @@ using Aaru.Decoders.CD;
|
||||
using Aaru.Decoders.SCSI;
|
||||
using Spectre.Console;
|
||||
|
||||
namespace Aaru.Commands.Image
|
||||
namespace Aaru.Commands.Image;
|
||||
|
||||
internal sealed class DecodeCommand : Command
|
||||
{
|
||||
internal sealed class DecodeCommand : Command
|
||||
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.")
|
||||
{
|
||||
Add(new Option(new[]
|
||||
{
|
||||
"--disk-tags", "-f"
|
||||
}, "Decode disk tags.")
|
||||
{
|
||||
Argument = new Argument<bool>(() => true),
|
||||
Required = false
|
||||
});
|
||||
|
||||
Add(new Option(new[]
|
||||
{
|
||||
"--length", "-l"
|
||||
}, "How many sectors to decode, or \"all\".")
|
||||
{
|
||||
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>
|
||||
Add(new Option(new[]
|
||||
{
|
||||
Arity = ArgumentArity.ExactlyOne,
|
||||
Description = "Media image path",
|
||||
Name = "image-path"
|
||||
"--disk-tags", "-f"
|
||||
}, "Decode disk tags.")
|
||||
{
|
||||
Argument = new Argument<bool>(() => true),
|
||||
Required = false
|
||||
});
|
||||
|
||||
Handler = CommandHandler.Create(GetType().GetMethod(nameof(Invoke)));
|
||||
Add(new Option(new[]
|
||||
{
|
||||
"--length", "-l"
|
||||
}, "How many sectors to decode, or \"all\".")
|
||||
{
|
||||
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 static int Invoke(bool verbose, bool debug, bool diskTags, string imagePath, string length, bool sectorTags,
|
||||
ulong startSector)
|
||||
{
|
||||
MainClass.PrintCopyright();
|
||||
|
||||
if(debug)
|
||||
{
|
||||
IAnsiConsole stderrConsole = AnsiConsole.Create(new AnsiConsoleSettings
|
||||
{
|
||||
Out = new AnsiConsoleOutput(System.Console.Error)
|
||||
});
|
||||
|
||||
AaruConsole.DebugWriteLineEvent += (format, objects) =>
|
||||
{
|
||||
if(objects is null)
|
||||
stderrConsole.MarkupLine(format);
|
||||
else
|
||||
stderrConsole.MarkupLine(format, objects);
|
||||
};
|
||||
}
|
||||
|
||||
public static int Invoke(bool verbose, bool debug, bool diskTags, string imagePath, string length,
|
||||
bool sectorTags, ulong startSector)
|
||||
if(verbose)
|
||||
AaruConsole.WriteEvent += (format, objects) =>
|
||||
{
|
||||
if(objects is null)
|
||||
AnsiConsole.Markup(format);
|
||||
else
|
||||
AnsiConsole.Markup(format, objects);
|
||||
};
|
||||
|
||||
Statistics.AddCommand("decode");
|
||||
|
||||
AaruConsole.DebugWriteLine("Decode command", "--debug={0}", debug);
|
||||
AaruConsole.DebugWriteLine("Decode command", "--disk-tags={0}", diskTags);
|
||||
AaruConsole.DebugWriteLine("Decode command", "--input={0}", imagePath);
|
||||
AaruConsole.DebugWriteLine("Decode command", "--length={0}", length);
|
||||
AaruConsole.DebugWriteLine("Decode command", "--sector-tags={0}", sectorTags);
|
||||
AaruConsole.DebugWriteLine("Decode command", "--start={0}", startSector);
|
||||
AaruConsole.DebugWriteLine("Decode command", "--verbose={0}", verbose);
|
||||
|
||||
var filtersList = new FiltersList();
|
||||
IFilter inputFilter = null;
|
||||
|
||||
Core.Spectre.ProgressSingleSpinner(ctx =>
|
||||
{
|
||||
MainClass.PrintCopyright();
|
||||
|
||||
if(debug)
|
||||
{
|
||||
IAnsiConsole stderrConsole = AnsiConsole.Create(new AnsiConsoleSettings
|
||||
{
|
||||
Out = new AnsiConsoleOutput(System.Console.Error)
|
||||
});
|
||||
|
||||
AaruConsole.DebugWriteLineEvent += (format, objects) =>
|
||||
{
|
||||
if(objects is null)
|
||||
stderrConsole.MarkupLine(format);
|
||||
else
|
||||
stderrConsole.MarkupLine(format, objects);
|
||||
};
|
||||
}
|
||||
|
||||
if(verbose)
|
||||
AaruConsole.WriteEvent += (format, objects) =>
|
||||
{
|
||||
if(objects is null)
|
||||
AnsiConsole.Markup(format);
|
||||
else
|
||||
AnsiConsole.Markup(format, objects);
|
||||
};
|
||||
|
||||
Statistics.AddCommand("decode");
|
||||
|
||||
AaruConsole.DebugWriteLine("Decode command", "--debug={0}", debug);
|
||||
AaruConsole.DebugWriteLine("Decode command", "--disk-tags={0}", diskTags);
|
||||
AaruConsole.DebugWriteLine("Decode command", "--input={0}", imagePath);
|
||||
AaruConsole.DebugWriteLine("Decode command", "--length={0}", length);
|
||||
AaruConsole.DebugWriteLine("Decode command", "--sector-tags={0}", sectorTags);
|
||||
AaruConsole.DebugWriteLine("Decode command", "--start={0}", startSector);
|
||||
AaruConsole.DebugWriteLine("Decode command", "--verbose={0}", verbose);
|
||||
|
||||
var filtersList = new FiltersList();
|
||||
IFilter inputFilter = null;
|
||||
|
||||
Core.Spectre.ProgressSingleSpinner(ctx =>
|
||||
{
|
||||
ctx.AddTask("Identifying file filter...").IsIndeterminate();
|
||||
inputFilter = filtersList.GetFilter(imagePath);
|
||||
});
|
||||
|
||||
if(inputFilter == null)
|
||||
{
|
||||
AaruConsole.ErrorWriteLine("Cannot open specified file.");
|
||||
|
||||
return (int)ErrorNumber.CannotOpenFile;
|
||||
}
|
||||
|
||||
IMediaImage inputFormat = null;
|
||||
|
||||
Core.Spectre.ProgressSingleSpinner(ctx =>
|
||||
{
|
||||
ctx.AddTask("Identifying image format...").IsIndeterminate();
|
||||
inputFormat = ImageFormat.Detect(inputFilter);
|
||||
});
|
||||
|
||||
if(inputFormat == null)
|
||||
{
|
||||
AaruConsole.ErrorWriteLine("Unable to recognize image format, not decoding");
|
||||
|
||||
return (int)ErrorNumber.UnrecognizedFormat;
|
||||
}
|
||||
|
||||
ErrorNumber opened = ErrorNumber.NoData;
|
||||
|
||||
Core.Spectre.ProgressSingleSpinner(ctx =>
|
||||
{
|
||||
ctx.AddTask("Opening image file...").IsIndeterminate();
|
||||
opened = inputFormat.Open(inputFilter);
|
||||
});
|
||||
|
||||
if(opened != ErrorNumber.NoError)
|
||||
{
|
||||
AaruConsole.WriteLine("Error {opened} opening image format");
|
||||
|
||||
return (int)opened;
|
||||
}
|
||||
|
||||
Statistics.AddMediaFormat(inputFormat.Format);
|
||||
Statistics.AddMedia(inputFormat.Info.MediaType, false);
|
||||
Statistics.AddFilter(inputFilter.Name);
|
||||
ErrorNumber errno;
|
||||
|
||||
if(diskTags)
|
||||
if(inputFormat.Info.ReadableMediaTags.Count == 0)
|
||||
AaruConsole.WriteLine("There are no disk tags in chosen disc image.");
|
||||
else
|
||||
foreach(MediaTagType tag in inputFormat.Info.ReadableMediaTags)
|
||||
switch(tag)
|
||||
{
|
||||
case MediaTagType.SCSI_INQUIRY:
|
||||
{
|
||||
errno = inputFormat.ReadMediaTag(MediaTagType.SCSI_INQUIRY, out byte[] inquiry);
|
||||
|
||||
if(inquiry == null)
|
||||
AaruConsole.WriteLine("Error {0} reading SCSI INQUIRY response from disc image",
|
||||
errno);
|
||||
else
|
||||
{
|
||||
AaruConsole.WriteLine("[bold]SCSI INQUIRY command response:[/]");
|
||||
|
||||
AaruConsole.
|
||||
WriteLine("================================================================================");
|
||||
|
||||
AaruConsole.WriteLine(Inquiry.Prettify(inquiry));
|
||||
|
||||
AaruConsole.
|
||||
WriteLine("================================================================================");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case MediaTagType.ATA_IDENTIFY:
|
||||
{
|
||||
errno = inputFormat.ReadMediaTag(MediaTagType.ATA_IDENTIFY, out byte[] identify);
|
||||
|
||||
if(errno != ErrorNumber.NoError)
|
||||
AaruConsole.
|
||||
WriteLine("Error {0} reading ATA IDENTIFY DEVICE response from disc image",
|
||||
errno);
|
||||
else
|
||||
{
|
||||
AaruConsole.WriteLine("[bold]ATA IDENTIFY DEVICE command response:[/]");
|
||||
|
||||
AaruConsole.
|
||||
WriteLine("================================================================================");
|
||||
|
||||
AaruConsole.WriteLine(Identify.Prettify(identify));
|
||||
|
||||
AaruConsole.
|
||||
WriteLine("================================================================================");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case MediaTagType.ATAPI_IDENTIFY:
|
||||
{
|
||||
errno = inputFormat.ReadMediaTag(MediaTagType.ATAPI_IDENTIFY, out byte[] identify);
|
||||
|
||||
if(identify == null)
|
||||
AaruConsole.
|
||||
WriteLine("Error {0} reading ATA IDENTIFY PACKET DEVICE response from disc image",
|
||||
errno);
|
||||
else
|
||||
{
|
||||
AaruConsole.WriteLine("[bold]ATA IDENTIFY PACKET DEVICE command response:[/]");
|
||||
|
||||
AaruConsole.
|
||||
WriteLine("================================================================================");
|
||||
|
||||
AaruConsole.WriteLine(Identify.Prettify(identify));
|
||||
|
||||
AaruConsole.
|
||||
WriteLine("================================================================================");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case MediaTagType.CD_ATIP:
|
||||
{
|
||||
errno = inputFormat.ReadMediaTag(MediaTagType.CD_ATIP, out byte[] atip);
|
||||
|
||||
if(errno != ErrorNumber.NoError)
|
||||
AaruConsole.WriteLine("Error {0} reading CD ATIP from disc image", errno);
|
||||
else
|
||||
{
|
||||
AaruConsole.WriteLine("[bold]CD ATIP:[/]");
|
||||
|
||||
AaruConsole.
|
||||
WriteLine("================================================================================");
|
||||
|
||||
AaruConsole.WriteLine(ATIP.Prettify(atip));
|
||||
|
||||
AaruConsole.
|
||||
WriteLine("================================================================================");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case MediaTagType.CD_FullTOC:
|
||||
{
|
||||
errno = inputFormat.ReadMediaTag(MediaTagType.CD_FullTOC, out byte[] fullToc);
|
||||
|
||||
if(errno != ErrorNumber.NoError)
|
||||
AaruConsole.WriteLine("Error {0} reading CD full TOC from disc image", errno);
|
||||
else
|
||||
{
|
||||
AaruConsole.WriteLine("[bold]CD full TOC:[/]");
|
||||
|
||||
AaruConsole.
|
||||
WriteLine("================================================================================");
|
||||
|
||||
AaruConsole.WriteLine(FullTOC.Prettify(fullToc));
|
||||
|
||||
AaruConsole.
|
||||
WriteLine("================================================================================");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case MediaTagType.CD_PMA:
|
||||
{
|
||||
errno = inputFormat.ReadMediaTag(MediaTagType.CD_PMA, out byte[] pma);
|
||||
|
||||
if(errno != ErrorNumber.NoError)
|
||||
AaruConsole.WriteLine("Error {0} reading CD PMA from disc image", errno);
|
||||
else
|
||||
{
|
||||
AaruConsole.WriteLine("[bold]CD PMA:[/]");
|
||||
|
||||
AaruConsole.
|
||||
WriteLine("================================================================================");
|
||||
|
||||
AaruConsole.WriteLine(PMA.Prettify(pma));
|
||||
|
||||
AaruConsole.
|
||||
WriteLine("================================================================================");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case MediaTagType.CD_SessionInfo:
|
||||
{
|
||||
errno = inputFormat.ReadMediaTag(MediaTagType.CD_SessionInfo, out byte[] sessionInfo);
|
||||
|
||||
if(errno != ErrorNumber.NoError)
|
||||
AaruConsole.WriteLine("Error {0} reading CD session information from disc image",
|
||||
errno);
|
||||
else
|
||||
{
|
||||
AaruConsole.WriteLine("[bold]CD session information:[/]");
|
||||
|
||||
AaruConsole.
|
||||
WriteLine("================================================================================");
|
||||
|
||||
AaruConsole.WriteLine(Session.Prettify(sessionInfo));
|
||||
|
||||
AaruConsole.
|
||||
WriteLine("================================================================================");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case MediaTagType.CD_TEXT:
|
||||
{
|
||||
errno = inputFormat.ReadMediaTag(MediaTagType.CD_TEXT, out byte[] cdText);
|
||||
|
||||
if(errno != ErrorNumber.NoError)
|
||||
AaruConsole.WriteLine("Error reading CD-TEXT from disc image");
|
||||
else
|
||||
{
|
||||
AaruConsole.WriteLine("[bold]CD-TEXT:[/]");
|
||||
|
||||
AaruConsole.
|
||||
WriteLine("================================================================================");
|
||||
|
||||
AaruConsole.WriteLine(CDTextOnLeadIn.Prettify(cdText));
|
||||
|
||||
AaruConsole.
|
||||
WriteLine("================================================================================");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case MediaTagType.CD_TOC:
|
||||
{
|
||||
errno = inputFormat.ReadMediaTag(MediaTagType.CD_TOC, out byte[] toc);
|
||||
|
||||
if(toc == null)
|
||||
AaruConsole.WriteLine("Error reading CD TOC from disc image");
|
||||
else
|
||||
{
|
||||
AaruConsole.WriteLine("[bold]CD TOC:[/]");
|
||||
|
||||
AaruConsole.
|
||||
WriteLine("================================================================================");
|
||||
|
||||
AaruConsole.WriteLine(TOC.Prettify(toc));
|
||||
|
||||
AaruConsole.
|
||||
WriteLine("================================================================================");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
AaruConsole.WriteLine("Decoder for disk tag type \"{0}\" not yet implemented, sorry.",
|
||||
tag);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if(sectorTags)
|
||||
{
|
||||
if(length.ToLowerInvariant() == "all") {}
|
||||
else
|
||||
{
|
||||
if(!ulong.TryParse(length, out ulong _))
|
||||
ctx.AddTask("Identifying file filter...").IsIndeterminate();
|
||||
inputFilter = filtersList.GetFilter(imagePath);
|
||||
});
|
||||
|
||||
if(inputFilter == null)
|
||||
{
|
||||
AaruConsole.ErrorWriteLine("Cannot open specified file.");
|
||||
|
||||
return (int)ErrorNumber.CannotOpenFile;
|
||||
}
|
||||
|
||||
IMediaImage inputFormat = null;
|
||||
IBaseImage baseImage = null;
|
||||
|
||||
Core.Spectre.ProgressSingleSpinner(ctx =>
|
||||
{
|
||||
ctx.AddTask("Identifying image format...").IsIndeterminate();
|
||||
baseImage = ImageFormat.Detect(inputFilter);
|
||||
inputFormat = baseImage as IMediaImage;
|
||||
});
|
||||
|
||||
if(baseImage == null)
|
||||
{
|
||||
AaruConsole.ErrorWriteLine("Unable to recognize image format, not decoding");
|
||||
|
||||
return (int)ErrorNumber.UnrecognizedFormat;
|
||||
}
|
||||
|
||||
if(inputFormat == null)
|
||||
{
|
||||
AaruConsole.WriteLine("Command not supported for this image type.");
|
||||
|
||||
return (int)ErrorNumber.InvalidArgument;
|
||||
}
|
||||
|
||||
ErrorNumber opened = ErrorNumber.NoData;
|
||||
|
||||
Core.Spectre.ProgressSingleSpinner(ctx =>
|
||||
{
|
||||
ctx.AddTask("Opening image file...").IsIndeterminate();
|
||||
opened = inputFormat.Open(inputFilter);
|
||||
});
|
||||
|
||||
if(opened != ErrorNumber.NoError)
|
||||
{
|
||||
AaruConsole.WriteLine("Error {opened} opening image format");
|
||||
|
||||
return (int)opened;
|
||||
}
|
||||
|
||||
Statistics.AddMediaFormat(inputFormat.Format);
|
||||
Statistics.AddMedia(inputFormat.Info.MediaType, false);
|
||||
Statistics.AddFilter(inputFilter.Name);
|
||||
ErrorNumber errno;
|
||||
|
||||
if(diskTags)
|
||||
if(inputFormat.Info.ReadableMediaTags.Count == 0)
|
||||
AaruConsole.WriteLine("There are no disk tags in chosen disc image.");
|
||||
else
|
||||
foreach(MediaTagType tag in inputFormat.Info.ReadableMediaTags)
|
||||
switch(tag)
|
||||
{
|
||||
AaruConsole.WriteLine("Value \"{0}\" is not a valid number for length.", length);
|
||||
AaruConsole.WriteLine("Not decoding sectors tags");
|
||||
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
if(inputFormat.Info.ReadableSectorTags.Count == 0)
|
||||
AaruConsole.WriteLine("There are no sector tags in chosen disc image.");
|
||||
else
|
||||
foreach(SectorTagType tag in inputFormat.Info.ReadableSectorTags)
|
||||
switch(tag)
|
||||
case MediaTagType.SCSI_INQUIRY:
|
||||
{
|
||||
default:
|
||||
AaruConsole.WriteLine("Decoder for disk tag type \"{0}\" not yet implemented, sorry.",
|
||||
tag);
|
||||
errno = inputFormat.ReadMediaTag(MediaTagType.SCSI_INQUIRY, out byte[] inquiry);
|
||||
|
||||
break;
|
||||
if(inquiry == null)
|
||||
AaruConsole.WriteLine("Error {0} reading SCSI INQUIRY response from disc image", errno);
|
||||
else
|
||||
{
|
||||
AaruConsole.WriteLine("[bold]SCSI INQUIRY command response:[/]");
|
||||
|
||||
AaruConsole.
|
||||
WriteLine("================================================================================");
|
||||
|
||||
AaruConsole.WriteLine(Inquiry.Prettify(inquiry));
|
||||
|
||||
AaruConsole.
|
||||
WriteLine("================================================================================");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case MediaTagType.ATA_IDENTIFY:
|
||||
{
|
||||
errno = inputFormat.ReadMediaTag(MediaTagType.ATA_IDENTIFY, out byte[] identify);
|
||||
|
||||
// TODO: Not implemented
|
||||
if(errno != ErrorNumber.NoError)
|
||||
AaruConsole.WriteLine("Error {0} reading ATA IDENTIFY DEVICE response from disc image",
|
||||
errno);
|
||||
else
|
||||
{
|
||||
AaruConsole.WriteLine("[bold]ATA IDENTIFY DEVICE command response:[/]");
|
||||
|
||||
AaruConsole.
|
||||
WriteLine("================================================================================");
|
||||
|
||||
AaruConsole.WriteLine(Identify.Prettify(identify));
|
||||
|
||||
AaruConsole.
|
||||
WriteLine("================================================================================");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case MediaTagType.ATAPI_IDENTIFY:
|
||||
{
|
||||
errno = inputFormat.ReadMediaTag(MediaTagType.ATAPI_IDENTIFY, out byte[] identify);
|
||||
|
||||
if(identify == null)
|
||||
AaruConsole.
|
||||
WriteLine("Error {0} reading ATA IDENTIFY PACKET DEVICE response from disc image",
|
||||
errno);
|
||||
else
|
||||
{
|
||||
AaruConsole.WriteLine("[bold]ATA IDENTIFY PACKET DEVICE command response:[/]");
|
||||
|
||||
AaruConsole.
|
||||
WriteLine("================================================================================");
|
||||
|
||||
AaruConsole.WriteLine(Identify.Prettify(identify));
|
||||
|
||||
AaruConsole.
|
||||
WriteLine("================================================================================");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case MediaTagType.CD_ATIP:
|
||||
{
|
||||
errno = inputFormat.ReadMediaTag(MediaTagType.CD_ATIP, out byte[] atip);
|
||||
|
||||
if(errno != ErrorNumber.NoError)
|
||||
AaruConsole.WriteLine("Error {0} reading CD ATIP from disc image", errno);
|
||||
else
|
||||
{
|
||||
AaruConsole.WriteLine("[bold]CD ATIP:[/]");
|
||||
|
||||
AaruConsole.
|
||||
WriteLine("================================================================================");
|
||||
|
||||
AaruConsole.WriteLine(ATIP.Prettify(atip));
|
||||
|
||||
AaruConsole.
|
||||
WriteLine("================================================================================");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case MediaTagType.CD_FullTOC:
|
||||
{
|
||||
errno = inputFormat.ReadMediaTag(MediaTagType.CD_FullTOC, out byte[] fullToc);
|
||||
|
||||
if(errno != ErrorNumber.NoError)
|
||||
AaruConsole.WriteLine("Error {0} reading CD full TOC from disc image", errno);
|
||||
else
|
||||
{
|
||||
AaruConsole.WriteLine("[bold]CD full TOC:[/]");
|
||||
|
||||
AaruConsole.
|
||||
WriteLine("================================================================================");
|
||||
|
||||
AaruConsole.WriteLine(FullTOC.Prettify(fullToc));
|
||||
|
||||
AaruConsole.
|
||||
WriteLine("================================================================================");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case MediaTagType.CD_PMA:
|
||||
{
|
||||
errno = inputFormat.ReadMediaTag(MediaTagType.CD_PMA, out byte[] pma);
|
||||
|
||||
if(errno != ErrorNumber.NoError)
|
||||
AaruConsole.WriteLine("Error {0} reading CD PMA from disc image", errno);
|
||||
else
|
||||
{
|
||||
AaruConsole.WriteLine("[bold]CD PMA:[/]");
|
||||
|
||||
AaruConsole.
|
||||
WriteLine("================================================================================");
|
||||
|
||||
AaruConsole.WriteLine(PMA.Prettify(pma));
|
||||
|
||||
AaruConsole.
|
||||
WriteLine("================================================================================");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case MediaTagType.CD_SessionInfo:
|
||||
{
|
||||
errno = inputFormat.ReadMediaTag(MediaTagType.CD_SessionInfo, out byte[] sessionInfo);
|
||||
|
||||
if(errno != ErrorNumber.NoError)
|
||||
AaruConsole.WriteLine("Error {0} reading CD session information from disc image",
|
||||
errno);
|
||||
else
|
||||
{
|
||||
AaruConsole.WriteLine("[bold]CD session information:[/]");
|
||||
|
||||
AaruConsole.
|
||||
WriteLine("================================================================================");
|
||||
|
||||
AaruConsole.WriteLine(Session.Prettify(sessionInfo));
|
||||
|
||||
AaruConsole.
|
||||
WriteLine("================================================================================");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case MediaTagType.CD_TEXT:
|
||||
{
|
||||
errno = inputFormat.ReadMediaTag(MediaTagType.CD_TEXT, out byte[] cdText);
|
||||
|
||||
if(errno != ErrorNumber.NoError)
|
||||
AaruConsole.WriteLine("Error reading CD-TEXT from disc image");
|
||||
else
|
||||
{
|
||||
AaruConsole.WriteLine("[bold]CD-TEXT:[/]");
|
||||
|
||||
AaruConsole.
|
||||
WriteLine("================================================================================");
|
||||
|
||||
AaruConsole.WriteLine(CDTextOnLeadIn.Prettify(cdText));
|
||||
|
||||
AaruConsole.
|
||||
WriteLine("================================================================================");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case MediaTagType.CD_TOC:
|
||||
{
|
||||
errno = inputFormat.ReadMediaTag(MediaTagType.CD_TOC, out byte[] toc);
|
||||
|
||||
if(toc == null)
|
||||
AaruConsole.WriteLine("Error reading CD TOC from disc image");
|
||||
else
|
||||
{
|
||||
AaruConsole.WriteLine("[bold]CD TOC:[/]");
|
||||
|
||||
AaruConsole.
|
||||
WriteLine("================================================================================");
|
||||
|
||||
AaruConsole.WriteLine(TOC.Prettify(toc));
|
||||
|
||||
AaruConsole.
|
||||
WriteLine("================================================================================");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
AaruConsole.WriteLine("Decoder for disk tag type \"{0}\" not yet implemented, sorry.", tag);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if(sectorTags)
|
||||
{
|
||||
if(length.ToLowerInvariant() == "all") {}
|
||||
else
|
||||
{
|
||||
if(!ulong.TryParse(length, out ulong _))
|
||||
{
|
||||
AaruConsole.WriteLine("Value \"{0}\" is not a valid number for length.", length);
|
||||
AaruConsole.WriteLine("Not decoding sectors tags");
|
||||
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
return (int)ErrorNumber.NoError;
|
||||
if(inputFormat.Info.ReadableSectorTags.Count == 0)
|
||||
AaruConsole.WriteLine("There are no sector tags in chosen disc image.");
|
||||
else
|
||||
foreach(SectorTagType tag in inputFormat.Info.ReadableSectorTags)
|
||||
switch(tag)
|
||||
{
|
||||
default:
|
||||
AaruConsole.WriteLine("Decoder for disk tag type \"{0}\" not yet implemented, sorry.", tag);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// TODO: Not implemented
|
||||
}
|
||||
|
||||
return (int)ErrorNumber.NoError;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user