[Aaru] Reformat and cleanup.

This commit is contained in:
2023-10-03 22:04:36 +01:00
parent 29512a0a5f
commit ec9f5808e4
33 changed files with 3846 additions and 3279 deletions

View File

@@ -33,11 +33,11 @@
<NoWarn>CS1591;CS1574</NoWarn> <NoWarn>CS1591;CS1574</NoWarn>
</PropertyGroup> </PropertyGroup>
<ItemGroup Condition=" '$(Configuration)' == 'Debug' "> <ItemGroup Condition=" '$(Configuration)' == 'Debug' ">
<InternalsVisibleTo Include="Aaru.Tests" /> <InternalsVisibleTo Include="Aaru.Tests"/>
<InternalsVisibleTo Include="Aaru.Tests.Devices" /> <InternalsVisibleTo Include="Aaru.Tests.Devices"/>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Remove="Packaging.Targets" /> <None Remove="Packaging.Targets"/>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\README.md"> <None Include="..\README.md">
@@ -60,21 +60,21 @@
</None> </None>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Aaru.Checksums\Aaru.Checksums.csproj" /> <ProjectReference Include="..\Aaru.Checksums\Aaru.Checksums.csproj"/>
<ProjectReference Include="..\Aaru.Database\Aaru.Database.csproj" /> <ProjectReference Include="..\Aaru.Database\Aaru.Database.csproj"/>
<ProjectReference Include="..\Aaru.Gui\Aaru.Gui.csproj" /> <ProjectReference Include="..\Aaru.Gui\Aaru.Gui.csproj"/>
<ProjectReference Include="..\Aaru.Helpers\Aaru.Helpers.csproj" /> <ProjectReference Include="..\Aaru.Helpers\Aaru.Helpers.csproj"/>
<ProjectReference Include="..\Aaru.Images\Aaru.Images.csproj" /> <ProjectReference Include="..\Aaru.Images\Aaru.Images.csproj"/>
<ProjectReference Include="..\Aaru.CommonTypes\Aaru.CommonTypes.csproj" /> <ProjectReference Include="..\Aaru.CommonTypes\Aaru.CommonTypes.csproj"/>
<ProjectReference Include="..\Aaru.Localization\Aaru.Localization.csproj" /> <ProjectReference Include="..\Aaru.Localization\Aaru.Localization.csproj"/>
<ProjectReference Include="..\Aaru.Partitions\Aaru.Partitions.csproj" /> <ProjectReference Include="..\Aaru.Partitions\Aaru.Partitions.csproj"/>
<ProjectReference Include="..\Aaru.Filesystems\Aaru.Filesystems.csproj" /> <ProjectReference Include="..\Aaru.Filesystems\Aaru.Filesystems.csproj"/>
<ProjectReference Include="..\Aaru.Decoders\Aaru.Decoders.csproj" /> <ProjectReference Include="..\Aaru.Decoders\Aaru.Decoders.csproj"/>
<ProjectReference Include="..\Aaru.Devices\Aaru.Devices.csproj" /> <ProjectReference Include="..\Aaru.Devices\Aaru.Devices.csproj"/>
<ProjectReference Include="..\Aaru.Console\Aaru.Console.csproj" /> <ProjectReference Include="..\Aaru.Console\Aaru.Console.csproj"/>
<ProjectReference Include="..\Aaru.Settings\Aaru.Settings.csproj" /> <ProjectReference Include="..\Aaru.Settings\Aaru.Settings.csproj"/>
<ProjectReference Include="..\Aaru.Filters\Aaru.Filters.csproj" /> <ProjectReference Include="..\Aaru.Filters\Aaru.Filters.csproj"/>
<ProjectReference Include="..\Aaru.Core\Aaru.Core.csproj" /> <ProjectReference Include="..\Aaru.Core\Aaru.Core.csproj"/>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<EmbeddedResource Include="..\LICENSE.MIT"> <EmbeddedResource Include="..\LICENSE.MIT">
@@ -85,41 +85,41 @@
<Link>LICENSE.LGPL</Link> <Link>LICENSE.LGPL</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</EmbeddedResource> </EmbeddedResource>
<Folder Include="..\LICENSE" /> <Folder Include="..\LICENSE"/>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\.github\CODE_OF_CONDUCT.md" /> <None Include="..\.github\CODE_OF_CONDUCT.md"/>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Content Include="..\.github\PULL_REQUEST_TEMPLATE.md" /> <Content Include="..\.github\PULL_REQUEST_TEMPLATE.md"/>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Humanizer" Version="2.14.1" /> <PackageReference Include="Humanizer" Version="2.14.1"/>
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.0-rc.1.23419.6" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.0-rc.1.23419.6"/>
<PackageReference Include="Spectre.Console" Version="0.47.0" /> <PackageReference Include="Spectre.Console" Version="0.47.0"/>
<PackageReference Include="Spectre.Console.Analyzer" Version="0.47.0"> <PackageReference Include="Spectre.Console.Analyzer" Version="0.47.0">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>
<PackageReference Include="System.CommandLine" Version="2.0.0-beta4.22272.1" /> <PackageReference Include="System.CommandLine" Version="2.0.0-beta4.22272.1"/>
<PackageReference Include="System.CommandLine.NamingConventionBinder" Version="2.0.0-beta4.22272.1" /> <PackageReference Include="System.CommandLine.NamingConventionBinder" Version="2.0.0-beta4.22272.1"/>
<PackageReference Include="System.Text.Encoding.CodePages" Version="8.0.0-rc.1.23419.4" /> <PackageReference Include="System.Text.Encoding.CodePages" Version="8.0.0-rc.1.23419.4"/>
<PackageReference Include="System.Text.Json" Version="8.0.0-rc.1.23419.4" /> <PackageReference Include="System.Text.Json" Version="8.0.0-rc.1.23419.4"/>
<PackageReference Include="System.ValueTuple" Version="4.5.0" /> <PackageReference Include="System.ValueTuple" Version="4.5.0"/>
<PackageReference Include="Unclassified.NetRevisionTask" Version="0.4.3"> <PackageReference Include="Unclassified.NetRevisionTask" Version="0.4.3">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>
<PackageReference Include="System.Collections" Version="4.3.0" /> <PackageReference Include="System.Collections" Version="4.3.0"/>
<PackageReference Include="System.Diagnostics.Debug" Version="4.3.0" /> <PackageReference Include="System.Diagnostics.Debug" Version="4.3.0"/>
<PackageReference Include="System.IO.FileSystem.Primitives" Version="4.3.0" /> <PackageReference Include="System.IO.FileSystem.Primitives" Version="4.3.0"/>
<PackageReference Include="System.Runtime.Extensions" Version="4.3.1" /> <PackageReference Include="System.Runtime.Extensions" Version="4.3.1"/>
<PackageReference Include="System.Runtime.Handles" Version="4.3.0" /> <PackageReference Include="System.Runtime.Handles" Version="4.3.0"/>
<PackageReference Include="System.Runtime.InteropServices" Version="4.3.0" /> <PackageReference Include="System.Runtime.InteropServices" Version="4.3.0"/>
<PackageReference Include="System.Net.Primitives" Version="4.3.1" /> <PackageReference Include="System.Net.Primitives" Version="4.3.1"/>
<PackageReference Include="System.IO.FileSystem" Version="4.3.0" /> <PackageReference Include="System.IO.FileSystem" Version="4.3.0"/>
<PackageReference Update="Packaging.Targets" Version="0.1.220" /> <PackageReference Update="Packaging.Targets" Version="0.1.220"/>
<PackageReference Include="Packaging.Targets" Version="0.1.220" /> <PackageReference Include="Packaging.Targets" Version="0.1.220"/>
</ItemGroup> </ItemGroup>
<PropertyGroup> <PropertyGroup>
@@ -183,7 +183,7 @@
<PackageName>$(PackagePrefix)-$(PackageVersion)_windows_x86$(DebugPackage)</PackageName> <PackageName>$(PackagePrefix)-$(PackageVersion)_windows_x86$(DebugPackage)</PackageName>
</PropertyGroup> </PropertyGroup>
<!-- TODO: Distribution specific RIDs where removed in .NET 8.0. We need to detect packaging in another way <!-- TODO: Distribution specific RIDs where removed in .NET 8.0. We need to detect packaging in another way
<PropertyGroup Condition="'$(RuntimeIdentifier)' == 'debian-arm64'"> <PropertyGroup Condition="'$(RuntimeIdentifier)' == 'debian-arm64'">
<PackageName>$(PackagePrefix)_$(PackageVersion)_arm64$(DebugPackage)</PackageName> <PackageName>$(PackagePrefix)_$(PackageVersion)_arm64$(DebugPackage)</PackageName>
</PropertyGroup> </PropertyGroup>
@@ -207,5 +207,5 @@
<PropertyGroup Condition="'$(RuntimeIdentifier)' == 'sles-x64'"> <PropertyGroup Condition="'$(RuntimeIdentifier)' == 'sles-x64'">
<PackageName>$(PackagePrefix)-$(PackageVersion).sles.x86_64$(DebugPackage)</PackageName> <PackageName>$(PackagePrefix)-$(PackageVersion).sles.x86_64$(DebugPackage)</PackageName>
</PropertyGroup> </PropertyGroup>
--> -->
</Project> </Project>

View File

@@ -78,6 +78,7 @@ sealed class ArchiveInfoCommand : Command
} }
if(verbose) if(verbose)
{
AaruConsole.WriteEvent += (format, objects) => AaruConsole.WriteEvent += (format, objects) =>
{ {
if(objects is null) if(objects is null)
@@ -85,6 +86,7 @@ sealed class ArchiveInfoCommand : Command
else else
AnsiConsole.Markup(format, objects); AnsiConsole.Markup(format, objects);
}; };
}
Statistics.AddCommand("archive-info"); Statistics.AddCommand("archive-info");

View File

@@ -67,6 +67,7 @@ sealed class ConfigureCommand : Command
} }
if(verbose) if(verbose)
{
AaruConsole.WriteEvent += (format, objects) => AaruConsole.WriteEvent += (format, objects) =>
{ {
if(objects is null) if(objects is null)
@@ -74,6 +75,7 @@ sealed class ConfigureCommand : Command
else else
AnsiConsole.Markup(format, objects); AnsiConsole.Markup(format, objects);
}; };
}
return DoConfigure(false); return DoConfigure(false);
} }
@@ -101,6 +103,7 @@ sealed class ConfigureCommand : Command
AnsiConsole.Confirm($"[italic]{UI.Do_you_want_to_enable_decryption_of_copy_protected_media_Q}[/]"); AnsiConsole.Confirm($"[italic]{UI.Do_you_want_to_enable_decryption_of_copy_protected_media_Q}[/]");
#region Device reports #region Device reports
AaruConsole.WriteLine(); AaruConsole.WriteLine();
AaruConsole.WriteLine(UI.Configure_Device_Report_information_disclaimer); AaruConsole.WriteLine(UI.Configure_Device_Report_information_disclaimer);
@@ -114,9 +117,11 @@ sealed class ConfigureCommand : Command
Settings.Settings.Current.ShareReports = Settings.Settings.Current.ShareReports =
AnsiConsole.Confirm($"[italic]{UI.Do_you_want_to_share_your_device_reports_with_us_Q}[/]"); AnsiConsole.Confirm($"[italic]{UI.Do_you_want_to_share_your_device_reports_with_us_Q}[/]");
#endregion Device reports #endregion Device reports
#region Statistics #region Statistics
AaruConsole.WriteLine(); AaruConsole.WriteLine();
AaruConsole.WriteLine(UI.Statistics_disclaimer); AaruConsole.WriteLine(UI.Statistics_disclaimer);
@@ -151,6 +156,7 @@ sealed class ConfigureCommand : Command
} }
else else
Settings.Settings.Current.Stats = null; Settings.Settings.Current.Stats = null;
#endregion Statistics #endregion Statistics
Settings.Settings.Current.GdprCompliance = DicSettings.GDPR_LEVEL; Settings.Settings.Current.GdprCompliance = DicSettings.GDPR_LEVEL;

View File

@@ -68,6 +68,7 @@ sealed class StatisticsCommand : Command
} }
if(verbose) if(verbose)
{
AaruConsole.WriteEvent += (format, objects) => AaruConsole.WriteEvent += (format, objects) =>
{ {
if(objects is null) if(objects is null)
@@ -75,6 +76,7 @@ sealed class StatisticsCommand : Command
else else
AnsiConsole.Markup(format, objects); AnsiConsole.Markup(format, objects);
}; };
}
var ctx = AaruContext.Create(Settings.Settings.LocalDbPath); var ctx = AaruContext.Create(Settings.Settings.LocalDbPath);
@@ -91,7 +93,7 @@ sealed class StatisticsCommand : Command
return (int)ErrorNumber.NothingFound; return (int)ErrorNumber.NothingFound;
} }
bool thereAreStats = false; var thereAreStats = false;
Table table; Table table;
if(ctx.Commands.Any()) if(ctx.Commands.Any())
@@ -123,12 +125,14 @@ sealed class StatisticsCommand : Command
} }
if(count > 0) if(count > 0)
{
ctx.Commands.Add(new Aaru.Database.Models.Command ctx.Commands.Add(new Aaru.Database.Models.Command
{ {
Count = count, Count = count,
Name = "fs-info", Name = "fs-info",
Synchronized = true Synchronized = true
}); });
}
ctx.SaveChanges(); ctx.SaveChanges();
} }
@@ -281,8 +285,10 @@ sealed class StatisticsCommand : Command
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))
{
table.AddRow(Markup.Escape(ds.Manufacturer ?? ""), Markup.Escape(ds.Model ?? ""), table.AddRow(Markup.Escape(ds.Manufacturer ?? ""), Markup.Escape(ds.Model ?? ""),
Markup.Escape(ds.Revision ?? ""), Markup.Escape(ds.Bus ?? "")); Markup.Escape(ds.Revision ?? ""), Markup.Escape(ds.Bus ?? ""));
}
AnsiConsole.Write(table); AnsiConsole.Write(table);
AaruConsole.WriteLine(); AaruConsole.WriteLine();

View File

@@ -84,6 +84,7 @@ sealed class UpdateCommand : Command
} }
if(verbose) if(verbose)
{
AaruConsole.WriteEvent += (format, objects) => AaruConsole.WriteEvent += (format, objects) =>
{ {
if(objects is null) if(objects is null)
@@ -91,11 +92,13 @@ sealed class UpdateCommand : Command
else else
AnsiConsole.Markup(format, objects); AnsiConsole.Markup(format, objects);
}; };
}
AaruConsole.DebugWriteLine(MODULE_NAME, "--debug={0}", debug); AaruConsole.DebugWriteLine(MODULE_NAME, "--debug={0}", debug);
AaruConsole.DebugWriteLine(MODULE_NAME, "--verbose={0}", verbose); AaruConsole.DebugWriteLine(MODULE_NAME, "--verbose={0}", verbose);
if(clearAll) if(clearAll)
{
try try
{ {
File.Delete(Settings.Settings.LocalDbPath); File.Delete(Settings.Settings.LocalDbPath);
@@ -113,8 +116,10 @@ sealed class UpdateCommand : Command
return (int)ErrorNumber.CannotRemoveDatabase; return (int)ErrorNumber.CannotRemoveDatabase;
} }
}
if(clear || clearAll) if(clear || clearAll)
{
try try
{ {
File.Delete(Settings.Settings.MainDbPath); File.Delete(Settings.Settings.MainDbPath);
@@ -128,6 +133,7 @@ sealed class UpdateCommand : Command
return (int)ErrorNumber.CannotRemoveDatabase; return (int)ErrorNumber.CannotRemoveDatabase;
} }
}
DoUpdate(clear || clearAll); DoUpdate(clear || clearAll);

View File

@@ -70,10 +70,7 @@ sealed class DeviceReportCommand : Command
Name = "device-path" Name = "device-path"
}); });
Add(new Option<bool>(new[] Add(new Option<bool>(new[] { "--trap-disc", "-t" }, () => false, UI.Device_report_using_trap_disc));
{
"--trap-disc", "-t"
}, () => false, UI.Device_report_using_trap_disc));
Handler = CommandHandler.Create(GetType().GetMethod(nameof(Invoke))); Handler = CommandHandler.Create(GetType().GetMethod(nameof(Invoke)));
} }
@@ -99,6 +96,7 @@ sealed class DeviceReportCommand : Command
} }
if(verbose) if(verbose)
{
AaruConsole.WriteEvent += (format, objects) => AaruConsole.WriteEvent += (format, objects) =>
{ {
if(objects is null) if(objects is null)
@@ -106,6 +104,7 @@ sealed class DeviceReportCommand : Command
else else
AnsiConsole.Markup(format, objects); AnsiConsole.Markup(format, objects);
}; };
}
Statistics.AddCommand("device-report"); Statistics.AddCommand("device-report");
@@ -163,7 +162,7 @@ sealed class DeviceReportCommand : Command
Type = dev.Type Type = dev.Type
}; };
bool removable = false; var removable = false;
string jsonFile; string jsonFile;
switch(string.IsNullOrWhiteSpace(dev.Manufacturer)) switch(string.IsNullOrWhiteSpace(dev.Manufacturer))
@@ -199,11 +198,13 @@ sealed class DeviceReportCommand : Command
var reporter = new Core.Devices.Report.DeviceReport(dev); var reporter = new Core.Devices.Report.DeviceReport(dev);
if(dev.IsUsb) if(dev.IsUsb)
{
if(AnsiConsole.Confirm($"[italic]{UI.Is_the_device_natively_USB}[/]")) if(AnsiConsole.Confirm($"[italic]{UI.Is_the_device_natively_USB}[/]"))
{ {
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask(Localization.Core.Querying_USB_information).IsIndeterminate(); ctx.AddTask(Localization.Core.Querying_USB_information).
IsIndeterminate();
report.USB = reporter.UsbReport(); report.USB = reporter.UsbReport();
}); });
@@ -211,13 +212,16 @@ sealed class DeviceReportCommand : Command
removable = report.USB.RemovableMedia; removable = report.USB.RemovableMedia;
} }
}
if(dev.IsFireWire) if(dev.IsFireWire)
{
if(AnsiConsole.Confirm($"[italic]{UI.Is_the_device_natively_FireWire}[/]")) if(AnsiConsole.Confirm($"[italic]{UI.Is_the_device_natively_FireWire}[/]"))
{ {
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Querying FireWire information...").IsIndeterminate(); ctx.AddTask("Querying FireWire information...").
IsIndeterminate();
report.FireWire = reporter.FireWireReport(); report.FireWire = reporter.FireWireReport();
}); });
@@ -225,13 +229,17 @@ sealed class DeviceReportCommand : Command
removable = report.FireWire.RemovableMedia; removable = report.FireWire.RemovableMedia;
} }
}
if(dev.IsPcmcia) if(dev.IsPcmcia)
{
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask(Localization.Core.Querying_PCMCIA_information).IsIndeterminate(); ctx.AddTask(Localization.Core.Querying_PCMCIA_information).
IsIndeterminate();
report.PCMCIA = reporter.PcmciaReport(); report.PCMCIA = reporter.PcmciaReport();
}); });
}
byte[] buffer = Array.Empty<byte>(); byte[] buffer = Array.Empty<byte>();
string mediumTypeName; string mediumTypeName;
@@ -243,7 +251,8 @@ sealed class DeviceReportCommand : Command
{ {
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask(Localization.Core.Querying_ATA_IDENTIFY).IsIndeterminate(); ctx.AddTask(Localization.Core.Querying_ATA_IDENTIFY).
IsIndeterminate();
dev.AtaIdentify(out buffer, out _, dev.Timeout, out _); dev.AtaIdentify(out buffer, out _, dev.Timeout, out _);
}); });
@@ -276,7 +285,8 @@ sealed class DeviceReportCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask(Localization.Core.Querying_ATA_IDENTIFY).IsIndeterminate(); ctx.AddTask(Localization.Core.Querying_ATA_IDENTIFY).
IsIndeterminate();
dev.AtaIdentify(out buffer, out _, dev.Timeout, out _); dev.AtaIdentify(out buffer, out _, dev.Timeout, out _);
}); });
@@ -316,19 +326,23 @@ sealed class DeviceReportCommand : Command
report.SecureDigital = reporter.MmcSdReport(); report.SecureDigital = reporter.MmcSdReport();
break; break;
case DeviceType.NVMe: throw new NotImplementedException(Localization.Core.NVMe_devices_not_yet_supported); case DeviceType.NVMe:
throw new NotImplementedException(Localization.Core.NVMe_devices_not_yet_supported);
case DeviceType.ATAPI: case DeviceType.ATAPI:
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask(Localization.Core.Querying_ATAPI_IDENTIFY).IsIndeterminate(); ctx.AddTask(Localization.Core.Querying_ATAPI_IDENTIFY).
IsIndeterminate();
dev.AtapiIdentify(out buffer, out _, dev.Timeout, out _); dev.AtapiIdentify(out buffer, out _, dev.Timeout, out _);
}); });
if(Identify.Decode(buffer).HasValue) if(Identify.Decode(buffer).HasValue)
{
report.ATAPI = new Ata report.ATAPI = new Ata
{ {
Identify = Core.Devices.Report.DeviceReport.ClearIdentify(buffer) Identify = Core.Devices.Report.DeviceReport.ClearIdentify(buffer)
}; };
}
goto case DeviceType.SCSI; goto case DeviceType.SCSI;
case DeviceType.SCSI: case DeviceType.SCSI:
@@ -342,7 +356,8 @@ sealed class DeviceReportCommand : Command
case PeripheralDeviceTypes.BridgingExpander case PeripheralDeviceTypes.BridgingExpander
when dev.Model.StartsWith("MDM", StringComparison.Ordinal) || when dev.Model.StartsWith("MDM", StringComparison.Ordinal) ||
dev.Model.StartsWith("MDH", StringComparison.Ordinal): dev.Model.StartsWith("MDH", StringComparison.Ordinal):
case PeripheralDeviceTypes.SCSIZonedBlockDevice: break; case PeripheralDeviceTypes.SCSIZonedBlockDevice:
break;
default: default:
{ {
AaruConsole.ErrorWriteLine(UI.Unsupported_device_type_for_report); AaruConsole.ErrorWriteLine(UI.Unsupported_device_type_for_report);
@@ -373,7 +388,8 @@ sealed class DeviceReportCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask(UI.Asking_drive_to_unload_tape).IsIndeterminate(); ctx.AddTask(UI.Asking_drive_to_unload_tape).
IsIndeterminate();
dev.Unload(out buffer, dev.Timeout, out _); dev.Unload(out buffer, dev.Timeout, out _);
}); });
@@ -399,7 +415,7 @@ sealed class DeviceReportCommand : Command
string mediumManufacturer; string mediumManufacturer;
byte[] senseBuffer = Array.Empty<byte>(); byte[] senseBuffer = Array.Empty<byte>();
bool sense = true; var sense = true;
switch(dev.ScsiType) switch(dev.ScsiType)
{ {
@@ -453,10 +469,15 @@ sealed class DeviceReportCommand : Command
Features.Separate(report.SCSI.MultiMediaDevice.Features.BinaryData); Features.Separate(report.SCSI.MultiMediaDevice.Features.BinaryData);
if(ftr.Descriptors != null) if(ftr.Descriptors != null)
foreach(Profile prof in from desc in ftr.Descriptors where desc.Code == 0x0000 {
select Features.Decode_0000(desc.Data) into ftr0000 foreach(Profile prof in from desc in ftr.Descriptors
where ftr0000 != null from prof in ftr0000.Value.Profiles where desc.Code == 0x0000
select Features.Decode_0000(desc.Data)
into ftr0000
where ftr0000 != null
from prof in ftr0000.Value.Profiles
select prof) select prof)
{
switch(prof.Number) switch(prof.Number)
{ {
case ProfileNumber.CDROM: case ProfileNumber.CDROM:
@@ -542,6 +563,8 @@ sealed class DeviceReportCommand : Command
break; break;
} }
} }
}
}
if(cdromMode != null && if(cdromMode != null &&
!iomegaRev) !iomegaRev)
@@ -680,7 +703,10 @@ sealed class DeviceReportCommand : Command
mediaTypes = mediaTypes.Distinct().ToList(); mediaTypes = mediaTypes.Distinct().ToList();
mediaTypes.Sort(); mediaTypes.Sort();
bool tryPlextor = false, tryHldtst = false, tryPioneer = false, tryNec = false, bool tryPlextor = false,
tryHldtst = false,
tryPioneer = false,
tryNec = false,
tryMediaTekF106 = false; tryMediaTekF106 = false;
tryPlextor |= dev.Manufacturer.ToLowerInvariant() == "plextor"; tryPlextor |= dev.Manufacturer.ToLowerInvariant() == "plextor";
@@ -691,28 +717,36 @@ sealed class DeviceReportCommand : Command
if(!iomegaRev) if(!iomegaRev)
{ {
if(!tryPlextor) if(!tryPlextor)
{
tryPlextor |= tryPlextor |=
AnsiConsole. AnsiConsole.
Confirm($"[italic]{UI.Do_you_want_to_try_Plextor_commands} [red]{UI.This_is_dangerous}[/][/]", Confirm($"[italic]{UI.Do_you_want_to_try_Plextor_commands} [red]{UI.This_is_dangerous}[/][/]",
false); false);
}
if(!tryNec) if(!tryNec)
{
tryNec |= tryNec |=
AnsiConsole. AnsiConsole.
Confirm($"[italic]{UI.Do_you_want_to_try_NEC_commands} [red]{UI.This_is_dangerous}[/][/]", Confirm($"[italic]{UI.Do_you_want_to_try_NEC_commands} [red]{UI.This_is_dangerous}[/][/]",
false); false);
}
if(!tryPioneer) if(!tryPioneer)
{
tryPioneer |= tryPioneer |=
AnsiConsole. AnsiConsole.
Confirm($"[italic]{UI.Do_you_want_to_try_Pioneer_commands} [red]{UI.This_is_dangerous}[/][/]", Confirm($"[italic]{UI.Do_you_want_to_try_Pioneer_commands} [red]{UI.This_is_dangerous}[/][/]",
false); false);
}
if(!tryHldtst) if(!tryHldtst)
{
tryHldtst |= tryHldtst |=
AnsiConsole. AnsiConsole.
Confirm($"[italic]{UI.Do_you_want_to_try_HLDTST_commands} [red]{UI.This_is_dangerous}[/][/]", Confirm($"[italic]{UI.Do_you_want_to_try_HLDTST_commands} [red]{UI.This_is_dangerous}[/][/]",
false); false);
}
tryMediaTekF106 = tryMediaTekF106 =
AnsiConsole. AnsiConsole.
@@ -735,30 +769,39 @@ sealed class DeviceReportCommand : Command
System.Console.ReadKey(true); System.Console.ReadKey(true);
bool mediaIsRecognized = true; var mediaIsRecognized = true;
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask(Localization.Core.Waiting_for_drive_to_become_ready).IsIndeterminate(); ctx.AddTask(Localization.Core.
sense = dev.ScsiTestUnitReady(out senseBuffer, dev.Timeout, out _); Waiting_for_drive_to_become_ready).
IsIndeterminate();
sense = dev.ScsiTestUnitReady(out senseBuffer,
dev.Timeout, out _);
if(!sense) if(!sense)
return; return;
DecodedSense? decSense = Sense.Decode(senseBuffer); DecodedSense? decSense =
Sense.Decode(senseBuffer);
if(decSense.HasValue) if(decSense.HasValue)
{
switch(decSense.Value.ASC) switch(decSense.Value.ASC)
{ {
case 0x3A: case 0x3A:
{ {
int leftRetries = 50; var leftRetries = 50;
while(leftRetries > 0) while(leftRetries > 0)
{ {
Thread.Sleep(2000); Thread.Sleep(2000);
sense = dev.ScsiTestUnitReady(out senseBuffer, dev.Timeout, out _); sense =
dev.
ScsiTestUnitReady(out senseBuffer,
dev.Timeout,
out _);
if(!sense) if(!sense)
break; break;
@@ -774,15 +817,20 @@ sealed class DeviceReportCommand : Command
} }
// These should be trapped by the OS but seems in some cases they're not // These should be trapped by the OS but seems in some cases they're not
case 0x04 when decSense.Value.ASCQ == 0x01: case 0x04
when decSense.Value.ASCQ == 0x01:
{ {
int leftRetries = 50; var leftRetries = 50;
while(leftRetries > 0) while(leftRetries > 0)
{ {
Thread.Sleep(2000); Thread.Sleep(2000);
sense = dev.ScsiTestUnitReady(out senseBuffer, dev.Timeout, out _); sense =
dev.
ScsiTestUnitReady(out senseBuffer,
dev.Timeout,
out _);
if(!sense) if(!sense)
break; break;
@@ -798,13 +846,17 @@ sealed class DeviceReportCommand : Command
} }
case 0x28: case 0x28:
{ {
int leftRetries = 50; var leftRetries = 50;
while(leftRetries > 0) while(leftRetries > 0)
{ {
Thread.Sleep(2000); Thread.Sleep(2000);
sense = dev.ScsiTestUnitReady(out senseBuffer, dev.Timeout, out _); sense =
dev.
ScsiTestUnitReady(out senseBuffer,
dev.Timeout,
out _);
if(!sense) if(!sense)
break; break;
@@ -819,15 +871,19 @@ sealed class DeviceReportCommand : Command
break; break;
} }
default: default:
AaruConsole.DebugWriteLine(MODULE_NAME, AaruConsole.
Localization.Core.Device_not_ready_Sense, DebugWriteLine(MODULE_NAME,
decSense.Value.SenseKey, decSense.Value.ASC, Localization.Core.
Device_not_ready_Sense,
decSense.Value.SenseKey,
decSense.Value.ASC,
decSense.Value.ASCQ); decSense.Value.ASCQ);
mediaIsRecognized = false; mediaIsRecognized = false;
break; break;
} }
}
else else
{ {
AaruConsole.DebugWriteLine(MODULE_NAME, AaruConsole.DebugWriteLine(MODULE_NAME,
@@ -852,16 +908,18 @@ sealed class DeviceReportCommand : Command
mediaTest.LongBlockSize == mediaTest.BlockSize && mediaTest.LongBlockSize == mediaTest.BlockSize &&
AnsiConsole.Confirm($"[italic]{Localization.Core.Try_to_find_SCSI_READ_LONG_size AnsiConsole.Confirm($"[italic]{Localization.Core.Try_to_find_SCSI_READ_LONG_size
}[/]")) }[/]"))
{
AnsiConsole.Progress().AutoClear(true).HideCompleted(true). AnsiConsole.Progress().AutoClear(true).HideCompleted(true).
Columns(new TaskDescriptionColumn(), new ProgressBarColumn(), Columns(new TaskDescriptionColumn(), new ProgressBarColumn(),
new PercentageColumn()).Start(ctx => new PercentageColumn()).Start(ctx =>
{ {
ProgressTask task = ProgressTask task =
ctx.AddTask(Localization.Core.Trying_READ_LONG); ctx.AddTask(Localization.Core.
Trying_READ_LONG);
task.MaxValue = ushort.MaxValue; task.MaxValue = ushort.MaxValue;
for(ushort i = (ushort)mediaTest.BlockSize;; i++) for(var i = (ushort)mediaTest.BlockSize;; i++)
{ {
task.Description = task.Description =
string. string.
@@ -871,10 +929,14 @@ sealed class DeviceReportCommand : Command
task.Value = i; task.Value = i;
sense = mediaTest.SupportsReadLong16 == true sense = mediaTest.SupportsReadLong16 == true
? dev.ReadLong16(out buffer, out senseBuffer, ? dev.ReadLong16(out buffer,
false, 0, i, dev.Timeout, out _) out senseBuffer,
: dev.ReadLong10(out buffer, out senseBuffer, false, 0, i, dev.Timeout,
false, false, 0, i, dev.Timeout, out _)
: dev.ReadLong10(out buffer,
out senseBuffer,
false, false, 0, i,
dev.Timeout,
out _); out _);
if(!sense) if(!sense)
@@ -888,16 +950,24 @@ sealed class DeviceReportCommand : Command
break; break;
} }
}); });
}
if(mediaTest.SupportsReadLong == true && if(mediaTest.SupportsReadLong == true &&
mediaTest.LongBlockSize != mediaTest.BlockSize) mediaTest.LongBlockSize != mediaTest.BlockSize)
{ {
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask(Localization.Core.Trying_SCSI_READ_LONG_10).IsIndeterminate(); ctx.AddTask(Localization.Core.
Trying_SCSI_READ_LONG_10).
IsIndeterminate();
sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, sense =
(ushort)mediaTest.LongBlockSize, dev.Timeout, out _); dev.ReadLong10(out buffer,
out senseBuffer, false,
false, 0,
(ushort)mediaTest.
LongBlockSize,
dev.Timeout, out _);
}); });
if(!sense) if(!sense)
@@ -909,10 +979,16 @@ sealed class DeviceReportCommand : Command
{ {
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask(Localization.Core.Trying_SCSI_READ_LONG_16).IsIndeterminate(); ctx.AddTask(Localization.Core.
Trying_SCSI_READ_LONG_16).
IsIndeterminate();
sense = dev.ReadLong16(out buffer, out senseBuffer, false, 0, sense =
mediaTest.LongBlockSize.Value, dev.Timeout, out _); dev.ReadLong16(out buffer,
out senseBuffer, false, 0,
mediaTest.LongBlockSize.
Value, dev.Timeout,
out _);
}); });
if(!sense) if(!sense)
@@ -953,14 +1029,18 @@ sealed class DeviceReportCommand : Command
mediumModel = AnsiConsole.Ask<string>(Localization.Core.Please_write_media_model); mediumModel = AnsiConsole.Ask<string>(Localization.Core.Please_write_media_model);
bool mediaIsRecognized = true; var mediaIsRecognized = true;
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask(Localization.Core.Waiting_for_drive_to_become_ready).IsIndeterminate(); ctx.AddTask(Localization.Core.
Waiting_for_drive_to_become_ready).
IsIndeterminate();
sense = dev.ScsiTestUnitReady(out senseBuffer, dev.Timeout, out _); sense = dev.ScsiTestUnitReady(out senseBuffer,
AaruConsole.DebugWriteLine(MODULE_NAME, "sense = {0}", sense); dev.Timeout, out _);
AaruConsole.DebugWriteLine(MODULE_NAME,
"sense = {0}", sense);
if(!sense) if(!sense)
return; return;
@@ -968,17 +1048,21 @@ sealed class DeviceReportCommand : Command
DecodedSense? decSense = Sense.Decode(senseBuffer); DecodedSense? decSense = Sense.Decode(senseBuffer);
if(decSense.HasValue) if(decSense.HasValue)
{
switch(decSense.Value.ASC) switch(decSense.Value.ASC)
{ {
case 0x3A: case 0x3A:
{ {
int leftRetries = 50; var leftRetries = 50;
while(leftRetries > 0) while(leftRetries > 0)
{ {
Thread.Sleep(2000); Thread.Sleep(2000);
sense = dev.ScsiTestUnitReady(out senseBuffer, dev.Timeout, out _); sense =
dev.
ScsiTestUnitReady(out senseBuffer,
dev.Timeout, out _);
if(!sense) if(!sense)
break; break;
@@ -996,13 +1080,16 @@ sealed class DeviceReportCommand : Command
// These should be trapped by the OS but seems in some cases they're not // These should be trapped by the OS but seems in some cases they're not
case 0x04 when decSense.Value.ASCQ == 0x01: case 0x04 when decSense.Value.ASCQ == 0x01:
{ {
int leftRetries = 50; var leftRetries = 50;
while(leftRetries > 0) while(leftRetries > 0)
{ {
Thread.Sleep(2000); Thread.Sleep(2000);
sense = dev.ScsiTestUnitReady(out senseBuffer, dev.Timeout, out _); sense =
dev.
ScsiTestUnitReady(out senseBuffer,
dev.Timeout, out _);
if(!sense) if(!sense)
break; break;
@@ -1018,13 +1105,16 @@ sealed class DeviceReportCommand : Command
} }
case 0x28: case 0x28:
{ {
int leftRetries = 50; var leftRetries = 50;
while(leftRetries > 0) while(leftRetries > 0)
{ {
Thread.Sleep(2000); Thread.Sleep(2000);
sense = dev.ScsiTestUnitReady(out senseBuffer, dev.Timeout, out _); sense =
dev.
ScsiTestUnitReady(out senseBuffer,
dev.Timeout, out _);
if(!sense) if(!sense)
break; break;
@@ -1040,18 +1130,22 @@ sealed class DeviceReportCommand : Command
} }
default: default:
AaruConsole.DebugWriteLine(MODULE_NAME, AaruConsole.DebugWriteLine(MODULE_NAME,
Localization.Core.Device_not_ready_Sense, Localization.Core.
decSense.Value.SenseKey, decSense.Value.ASC, Device_not_ready_Sense,
decSense.Value.SenseKey,
decSense.Value.ASC,
decSense.Value.ASCQ); decSense.Value.ASCQ);
mediaIsRecognized = false; mediaIsRecognized = false;
break; break;
} }
}
else else
{ {
AaruConsole.DebugWriteLine(MODULE_NAME, AaruConsole.DebugWriteLine(MODULE_NAME,
Localization.Core.Got_sense_status_but_no_sense_buffer); Localization.Core.
Got_sense_status_but_no_sense_buffer);
mediaIsRecognized = false; mediaIsRecognized = false;
} }
@@ -1071,9 +1165,11 @@ sealed class DeviceReportCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask(UI.Asking_drive_to_unload_tape).IsIndeterminate(); ctx.AddTask(UI.Asking_drive_to_unload_tape).
IsIndeterminate();
dev.SpcAllowMediumRemoval(out buffer, dev.Timeout, out _); dev.SpcAllowMediumRemoval(out buffer, dev.Timeout,
out _);
dev.Unload(out buffer, dev.Timeout, out _); dev.Unload(out buffer, dev.Timeout, out _);
}); });
} }
@@ -1108,13 +1204,16 @@ sealed class DeviceReportCommand : Command
System.Console.ReadKey(true); System.Console.ReadKey(true);
bool mediaIsRecognized = true; var mediaIsRecognized = true;
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask(Localization.Core.Waiting_for_drive_to_become_ready).IsIndeterminate(); ctx.AddTask(Localization.Core.
Waiting_for_drive_to_become_ready).
IsIndeterminate();
sense = dev.ScsiTestUnitReady(out senseBuffer, dev.Timeout, out _); sense = dev.ScsiTestUnitReady(out senseBuffer,
dev.Timeout, out _);
if(!sense) if(!sense)
return; return;
@@ -1122,17 +1221,21 @@ sealed class DeviceReportCommand : Command
DecodedSense? decSense = Sense.Decode(senseBuffer); DecodedSense? decSense = Sense.Decode(senseBuffer);
if(decSense.HasValue) if(decSense.HasValue)
{
switch(decSense.Value.ASC) switch(decSense.Value.ASC)
{ {
case 0x3A: case 0x3A:
{ {
int leftRetries = 50; var leftRetries = 50;
while(leftRetries > 0) while(leftRetries > 0)
{ {
Thread.Sleep(2000); Thread.Sleep(2000);
sense = dev.ScsiTestUnitReady(out senseBuffer, dev.Timeout, out _); sense =
dev.
ScsiTestUnitReady(out senseBuffer,
dev.Timeout, out _);
if(!sense) if(!sense)
break; break;
@@ -1148,13 +1251,16 @@ sealed class DeviceReportCommand : Command
// These should be trapped by the OS but seems in some cases they're not // These should be trapped by the OS but seems in some cases they're not
case 0x04 when decSense.Value.ASCQ == 0x01: case 0x04 when decSense.Value.ASCQ == 0x01:
{ {
int leftRetries = 50; var leftRetries = 50;
while(leftRetries > 0) while(leftRetries > 0)
{ {
Thread.Sleep(2000); Thread.Sleep(2000);
sense = dev.ScsiTestUnitReady(out senseBuffer, dev.Timeout, out _); sense =
dev.
ScsiTestUnitReady(out senseBuffer,
dev.Timeout, out _);
if(!sense) if(!sense)
break; break;
@@ -1168,13 +1274,16 @@ sealed class DeviceReportCommand : Command
} }
case 0x28: case 0x28:
{ {
int leftRetries = 50; var leftRetries = 50;
while(leftRetries > 0) while(leftRetries > 0)
{ {
Thread.Sleep(2000); Thread.Sleep(2000);
sense = dev.ScsiTestUnitReady(out senseBuffer, dev.Timeout, out _); sense =
dev.
ScsiTestUnitReady(out senseBuffer,
dev.Timeout, out _);
if(!sense) if(!sense)
break; break;
@@ -1188,18 +1297,22 @@ sealed class DeviceReportCommand : Command
} }
default: default:
AaruConsole.DebugWriteLine(MODULE_NAME, AaruConsole.DebugWriteLine(MODULE_NAME,
Localization.Core.Device_not_ready_Sense, Localization.Core.
decSense.Value.SenseKey, decSense.Value.ASC, Device_not_ready_Sense,
decSense.Value.SenseKey,
decSense.Value.ASC,
decSense.Value.ASCQ); decSense.Value.ASCQ);
mediaIsRecognized = false; mediaIsRecognized = false;
break; break;
} }
}
else else
{ {
AaruConsole.DebugWriteLine(MODULE_NAME, AaruConsole.DebugWriteLine(MODULE_NAME,
Localization.Core.Got_sense_status_but_no_sense_buffer); Localization.Core.
Got_sense_status_but_no_sense_buffer);
mediaIsRecognized = false; mediaIsRecognized = false;
} }
@@ -1218,15 +1331,17 @@ sealed class DeviceReportCommand : Command
mediaTest.LongBlockSize == mediaTest.BlockSize && mediaTest.LongBlockSize == mediaTest.BlockSize &&
AnsiConsole.Confirm($"[italic]{Localization.Core.Try_to_find_SCSI_READ_LONG_size AnsiConsole.Confirm($"[italic]{Localization.Core.Try_to_find_SCSI_READ_LONG_size
}[/]")) }[/]"))
{
AnsiConsole.Progress().AutoClear(true).HideCompleted(true). AnsiConsole.Progress().AutoClear(true).HideCompleted(true).
Columns(new TaskDescriptionColumn(), new ProgressBarColumn(), Columns(new TaskDescriptionColumn(), new ProgressBarColumn(),
new PercentageColumn()).Start(ctx => new PercentageColumn()).Start(ctx =>
{ {
ProgressTask task = ctx.AddTask(Localization.Core.Trying_READ_LONG); ProgressTask task =
ctx.AddTask(Localization.Core.Trying_READ_LONG);
task.MaxValue = ushort.MaxValue; task.MaxValue = ushort.MaxValue;
for(ushort i = (ushort)mediaTest.BlockSize;; i++) for(var i = (ushort)mediaTest.BlockSize;; i++)
{ {
task.Value = i; task.Value = i;
@@ -1236,10 +1351,13 @@ sealed class DeviceReportCommand : Command
i); i);
sense = mediaTest.SupportsReadLong16 == true sense = mediaTest.SupportsReadLong16 == true
? dev.ReadLong16(out buffer, out senseBuffer, false, ? dev.ReadLong16(out buffer,
out senseBuffer, false,
0, i, dev.Timeout, out _) 0, i, dev.Timeout, out _)
: dev.ReadLong10(out buffer, out senseBuffer, false, : dev.ReadLong10(out buffer,
false, 0, i, dev.Timeout, out _); out senseBuffer, false,
false, 0, i, dev.Timeout,
out _);
if(!sense) if(!sense)
{ {
@@ -1254,16 +1372,23 @@ sealed class DeviceReportCommand : Command
AaruConsole.WriteLine(); AaruConsole.WriteLine();
}); });
}
if(mediaTest.SupportsReadLong == true && if(mediaTest.SupportsReadLong == true &&
mediaTest.LongBlockSize != mediaTest.BlockSize) mediaTest.LongBlockSize != mediaTest.BlockSize)
{ {
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask(Localization.Core.Trying_SCSI_READ_LONG_10).IsIndeterminate(); ctx.AddTask(Localization.Core.
Trying_SCSI_READ_LONG_10).
IsIndeterminate();
sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, sense =
(ushort)mediaTest.LongBlockSize, dev.Timeout, out _); dev.ReadLong10(out buffer,
out senseBuffer, false, false,
0,
(ushort)mediaTest.LongBlockSize,
dev.Timeout, out _);
}); });
if(!sense) if(!sense)
@@ -1275,10 +1400,15 @@ sealed class DeviceReportCommand : Command
{ {
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask(Localization.Core.Trying_SCSI_READ_LONG_16).IsIndeterminate(); ctx.AddTask(Localization.Core.
Trying_SCSI_READ_LONG_16).
IsIndeterminate();
sense = dev.ReadLong16(out buffer, out senseBuffer, false, 0, sense =
(ushort)mediaTest.LongBlockSize, dev.Timeout, out _); dev.ReadLong16(out buffer,
out senseBuffer, false, 0,
(ushort)mediaTest.LongBlockSize,
dev.Timeout, out _);
}); });
if(!sense) if(!sense)
@@ -1329,30 +1459,39 @@ sealed class DeviceReportCommand : Command
mediumModel = AnsiConsole.Ask<string>(Localization.Core.Please_write_media_model); mediumModel = AnsiConsole.Ask<string>(Localization.Core.Please_write_media_model);
bool mediaIsRecognized = true; var mediaIsRecognized = true;
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask(Localization.Core.Waiting_for_drive_to_become_ready).IsIndeterminate(); ctx.AddTask(Localization.Core.
sense = dev.ScsiTestUnitReady(out senseBuffer, dev.Timeout, out _); Waiting_for_drive_to_become_ready).
IsIndeterminate();
sense = dev.ScsiTestUnitReady(out senseBuffer,
dev.Timeout, out _);
if(!sense) if(!sense)
return; return;
DecodedSense? decSense = Sense.Decode(senseBuffer); DecodedSense? decSense =
Sense.Decode(senseBuffer);
if(decSense.HasValue) if(decSense.HasValue)
{
switch(decSense.Value.ASC) switch(decSense.Value.ASC)
{ {
case 0x3A: case 0x3A:
{ {
int leftRetries = 20; var leftRetries = 20;
while(leftRetries > 0) while(leftRetries > 0)
{ {
Thread.Sleep(2000); Thread.Sleep(2000);
sense = dev.ScsiTestUnitReady(out senseBuffer, dev.Timeout, out _); sense =
dev.
ScsiTestUnitReady(out senseBuffer,
dev.Timeout,
out _);
if(!sense) if(!sense)
break; break;
@@ -1364,15 +1503,20 @@ sealed class DeviceReportCommand : Command
break; break;
} }
case 0x04 when decSense.Value.ASCQ == 0x01: case 0x04
when decSense.Value.ASCQ == 0x01:
{ {
int leftRetries = 20; var leftRetries = 20;
while(leftRetries > 0) while(leftRetries > 0)
{ {
Thread.Sleep(2000); Thread.Sleep(2000);
sense = dev.ScsiTestUnitReady(out senseBuffer, dev.Timeout, out _); sense =
dev.
ScsiTestUnitReady(out senseBuffer,
dev.Timeout,
out _);
if(!sense) if(!sense)
break; break;
@@ -1389,6 +1533,7 @@ sealed class DeviceReportCommand : Command
break; break;
} }
}
else else
mediaIsRecognized = false; mediaIsRecognized = false;
}); });
@@ -1403,16 +1548,18 @@ sealed class DeviceReportCommand : Command
mediaTest.LongBlockSize == mediaTest.BlockSize && mediaTest.LongBlockSize == mediaTest.BlockSize &&
AnsiConsole.Confirm($"[italic]{Localization.Core.Try_to_find_SCSI_READ_LONG_size AnsiConsole.Confirm($"[italic]{Localization.Core.Try_to_find_SCSI_READ_LONG_size
}[/]")) }[/]"))
{
AnsiConsole.Progress().AutoClear(true).HideCompleted(true). AnsiConsole.Progress().AutoClear(true).HideCompleted(true).
Columns(new TaskDescriptionColumn(), new ProgressBarColumn(), Columns(new TaskDescriptionColumn(), new ProgressBarColumn(),
new PercentageColumn()).Start(ctx => new PercentageColumn()).Start(ctx =>
{ {
ProgressTask task = ProgressTask task =
ctx.AddTask(Localization.Core.Trying_READ_LONG); ctx.AddTask(Localization.Core.
Trying_READ_LONG);
task.MaxValue = ushort.MaxValue; task.MaxValue = ushort.MaxValue;
for(ushort i = (ushort)mediaTest.BlockSize;; i++) for(var i = (ushort)mediaTest.BlockSize;; i++)
{ {
task.Value = i; task.Value = i;
@@ -1422,10 +1569,14 @@ sealed class DeviceReportCommand : Command
i); i);
sense = mediaTest.SupportsReadLong16 == true sense = mediaTest.SupportsReadLong16 == true
? dev.ReadLong16(out buffer, out senseBuffer, ? dev.ReadLong16(out buffer,
false, 0, i, dev.Timeout, out _) out senseBuffer,
: dev.ReadLong10(out buffer, out senseBuffer, false, 0, i, dev.Timeout,
false, false, 0, i, dev.Timeout, out _)
: dev.ReadLong10(out buffer,
out senseBuffer,
false, false, 0, i,
dev.Timeout,
out _); out _);
if(!sense) if(!sense)
@@ -1441,16 +1592,24 @@ sealed class DeviceReportCommand : Command
AaruConsole.WriteLine(); AaruConsole.WriteLine();
}); });
}
if(mediaTest.SupportsReadLong == true && if(mediaTest.SupportsReadLong == true &&
mediaTest.LongBlockSize != mediaTest.BlockSize) mediaTest.LongBlockSize != mediaTest.BlockSize)
{ {
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask(Localization.Core.Trying_SCSI_READ_LONG_10).IsIndeterminate(); ctx.AddTask(Localization.Core.
Trying_SCSI_READ_LONG_10).
IsIndeterminate();
sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, sense =
(ushort)mediaTest.LongBlockSize, dev.Timeout, out _); dev.ReadLong10(out buffer,
out senseBuffer, false,
false, 0,
(ushort)mediaTest.
LongBlockSize,
dev.Timeout, out _);
}); });
if(!sense) if(!sense)
@@ -1462,10 +1621,16 @@ sealed class DeviceReportCommand : Command
{ {
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask(Localization.Core.Trying_SCSI_READ_LONG_16).IsIndeterminate(); ctx.AddTask(Localization.Core.
Trying_SCSI_READ_LONG_16).
IsIndeterminate();
sense = dev.ReadLong16(out buffer, out senseBuffer, false, 0, sense =
(ushort)mediaTest.LongBlockSize, dev.Timeout, out _); dev.ReadLong16(out buffer,
out senseBuffer, false, 0,
(ushort)mediaTest.
LongBlockSize,
dev.Timeout, out _);
}); });
if(!sense) if(!sense)
@@ -1493,17 +1658,22 @@ sealed class DeviceReportCommand : Command
if((report.SCSI.ReadCapabilities.SupportsReadLong == true || if((report.SCSI.ReadCapabilities.SupportsReadLong == true ||
report.SCSI.ReadCapabilities.SupportsReadLong16 == true) && report.SCSI.ReadCapabilities.SupportsReadLong16 == true) &&
report.SCSI.ReadCapabilities.LongBlockSize == report.SCSI.ReadCapabilities.BlockSize) report.SCSI.ReadCapabilities.LongBlockSize == report.SCSI.ReadCapabilities.BlockSize)
{
if(AnsiConsole.Confirm($"[italic]{Localization.Core.Try_to_find_SCSI_READ_LONG_size if(AnsiConsole.Confirm($"[italic]{Localization.Core.Try_to_find_SCSI_READ_LONG_size
}[/]")) }[/]"))
{
AnsiConsole.Progress().AutoClear(true).HideCompleted(true). AnsiConsole.Progress().AutoClear(true).HideCompleted(true).
Columns(new TaskDescriptionColumn(), new ProgressBarColumn(), Columns(new TaskDescriptionColumn(), new ProgressBarColumn(),
new PercentageColumn()).Start(ctx => new PercentageColumn()).Start(ctx =>
{ {
ProgressTask task = ctx.AddTask(Localization.Core.Trying_READ_LONG); ProgressTask task =
ctx.AddTask(Localization.Core.Trying_READ_LONG);
task.MaxValue = ushort.MaxValue; task.MaxValue = ushort.MaxValue;
for(ushort i = (ushort)report.SCSI.ReadCapabilities.BlockSize;; i++) for(var i = (ushort)report.SCSI.ReadCapabilities.
BlockSize;;
i++)
{ {
task.Value = i; task.Value = i;
@@ -1512,11 +1682,15 @@ sealed class DeviceReportCommand : Command
Format(Localization.Core.Trying_READ_LONG_with_size_0, Format(Localization.Core.Trying_READ_LONG_with_size_0,
i); i);
sense = report.SCSI.ReadCapabilities.SupportsReadLong16 == true sense = report.SCSI.ReadCapabilities.
? dev.ReadLong16(out buffer, out senseBuffer, false, SupportsReadLong16 == true
? dev.ReadLong16(out buffer,
out senseBuffer, false,
0, i, dev.Timeout, out _) 0, i, dev.Timeout, out _)
: dev.ReadLong10(out buffer, out senseBuffer, false, : dev.ReadLong10(out buffer,
false, 0, i, dev.Timeout, out _); out senseBuffer, false,
false, 0, i, dev.Timeout,
out _);
if(!sense) if(!sense)
{ {
@@ -1531,16 +1705,23 @@ sealed class DeviceReportCommand : Command
AaruConsole.WriteLine(); AaruConsole.WriteLine();
}); });
}
}
if(report.SCSI.ReadCapabilities.SupportsReadLong == true && if(report.SCSI.ReadCapabilities.SupportsReadLong == true &&
report.SCSI.ReadCapabilities.LongBlockSize != report.SCSI.ReadCapabilities.BlockSize) report.SCSI.ReadCapabilities.LongBlockSize != report.SCSI.ReadCapabilities.BlockSize)
{ {
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask(Localization.Core.Trying_SCSI_READ_LONG_10).IsIndeterminate(); ctx.AddTask(Localization.Core.
Trying_SCSI_READ_LONG_10).
IsIndeterminate();
sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, sense =
(ushort)report.SCSI.ReadCapabilities.LongBlockSize, dev.ReadLong10(out buffer, out senseBuffer,
false, false, 0,
(ushort)report.SCSI.
ReadCapabilities.LongBlockSize,
dev.Timeout, out _); dev.Timeout, out _);
}); });
@@ -1553,10 +1734,15 @@ sealed class DeviceReportCommand : Command
{ {
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask(Localization.Core.Trying_SCSI_READ_LONG_16).IsIndeterminate(); ctx.AddTask(Localization.Core.
Trying_SCSI_READ_LONG_16).
IsIndeterminate();
sense = dev.ReadLong16(out buffer, out senseBuffer, false, 0, sense =
report.SCSI.ReadCapabilities.LongBlockSize.Value, dev.ReadLong16(out buffer, out senseBuffer,
false, 0,
report.SCSI.ReadCapabilities.
LongBlockSize.Value,
dev.Timeout, out _); dev.Timeout, out _);
}); });
@@ -1570,7 +1756,8 @@ sealed class DeviceReportCommand : Command
} }
break; break;
default: throw new NotSupportedException(Localization.Core.Unknown_device_type); default:
throw new NotSupportedException(Localization.Core.Unknown_device_type);
} }
var jsonFs = new FileStream(jsonFile, FileMode.Create); var jsonFs = new FileStream(jsonFile, FileMode.Create);

View File

@@ -68,10 +68,7 @@ sealed class DeviceInfoCommand : Command
public DeviceInfoCommand() : base("info", UI.Device_Info_Command_Description) public DeviceInfoCommand() : base("info", UI.Device_Info_Command_Description)
{ {
Add(new Option<string>(new[] Add(new Option<string>(new[] { "--output-prefix", "-w" }, () => null, UI.Prefix_for_saving_binary_information));
{
"--output-prefix", "-w"
}, () => null, UI.Prefix_for_saving_binary_information));
AddArgument(new Argument<string> AddArgument(new Argument<string>
{ {
@@ -104,6 +101,7 @@ sealed class DeviceInfoCommand : Command
} }
if(verbose) if(verbose)
{
AaruConsole.WriteEvent += (format, objects) => AaruConsole.WriteEvent += (format, objects) =>
{ {
if(objects is null) if(objects is null)
@@ -111,6 +109,7 @@ sealed class DeviceInfoCommand : Command
else else
AnsiConsole.Markup(format, objects); AnsiConsole.Markup(format, objects);
}; };
}
Statistics.AddCommand("device-info"); Statistics.AddCommand("device-info");
@@ -206,11 +205,14 @@ sealed class DeviceInfoCommand : Command
Tuple[] tuples = CIS.GetTuples(dev.Cis); Tuple[] tuples = CIS.GetTuples(dev.Cis);
if(tuples != null) if(tuples != null)
{
foreach(Tuple tuple in tuples) foreach(Tuple tuple in tuples)
{
switch(tuple.Code) switch(tuple.Code)
{ {
case TupleCodes.CISTPL_NULL: case TupleCodes.CISTPL_NULL:
case TupleCodes.CISTPL_END: break; case TupleCodes.CISTPL_END:
break;
case TupleCodes.CISTPL_DEVICEGEO: case TupleCodes.CISTPL_DEVICEGEO:
case TupleCodes.CISTPL_DEVICEGEO_A: case TupleCodes.CISTPL_DEVICEGEO_A:
AaruConsole.WriteLine("{0}", CIS.PrettifyDeviceGeometryTuple(tuple)); AaruConsole.WriteLine("{0}", CIS.PrettifyDeviceGeometryTuple(tuple));
@@ -268,6 +270,8 @@ sealed class DeviceInfoCommand : Command
break; break;
} }
}
}
else else
AaruConsole.DebugWriteLine(MODULE_NAME, Localization.Core.Could_not_get_tuples); AaruConsole.DebugWriteLine(MODULE_NAME, Localization.Core.Could_not_get_tuples);
} }
@@ -318,7 +322,7 @@ sealed class DeviceInfoCommand : Command
if((devInfo.AtaMcptError.Value.DeviceHead & 0x08) == 0x08) if((devInfo.AtaMcptError.Value.DeviceHead & 0x08) == 0x08)
AaruConsole.WriteLine(Localization.Core.Media_card_is_write_protected); AaruConsole.WriteLine(Localization.Core.Media_card_is_write_protected);
ushort specificData = (ushort)((devInfo.AtaMcptError.Value.CylinderHigh * 0x100) + var specificData = (ushort)(devInfo.AtaMcptError.Value.CylinderHigh * 0x100 +
devInfo.AtaMcptError.Value.CylinderLow); devInfo.AtaMcptError.Value.CylinderLow);
if(specificData != 0) if(specificData != 0)
@@ -332,8 +336,10 @@ sealed class DeviceInfoCommand : Command
ulong blocks; ulong blocks;
if(ataid is { CurrentCylinders: > 0, CurrentHeads: > 0, CurrentSectorsPerTrack: > 0 }) if(ataid is { CurrentCylinders: > 0, CurrentHeads: > 0, CurrentSectorsPerTrack: > 0 })
{
blocks = (ulong)Math.Max(ataid.CurrentCylinders * ataid.CurrentHeads * ataid.CurrentSectorsPerTrack, blocks = (ulong)Math.Max(ataid.CurrentCylinders * ataid.CurrentHeads * ataid.CurrentSectorsPerTrack,
ataid.CurrentSectors); ataid.CurrentSectors);
}
else else
blocks = (ulong)(ataid.Cylinders * ataid.Heads * ataid.SectorsPerTrack); blocks = (ulong)(ataid.Cylinders * ataid.Heads * ataid.SectorsPerTrack);
@@ -375,7 +381,9 @@ sealed class DeviceInfoCommand : Command
AaruConsole.WriteLine(Inquiry.Prettify(devInfo.ScsiInquiry)); AaruConsole.WriteLine(Inquiry.Prettify(devInfo.ScsiInquiry));
if(devInfo.ScsiEvpdPages != null) if(devInfo.ScsiEvpdPages != null)
{
foreach(KeyValuePair<byte, byte[]> page in devInfo.ScsiEvpdPages) foreach(KeyValuePair<byte, byte[]> page in devInfo.ScsiEvpdPages)
{
switch(page.Key) switch(page.Key)
{ {
case >= 0x01 and <= 0x7F: case >= 0x01 and <= 0x7F:
@@ -563,19 +571,27 @@ sealed class DeviceInfoCommand : Command
break; break;
} }
} }
}
}
if(devInfo.ScsiModeSense6 != null) if(devInfo.ScsiModeSense6 != null)
{
DataFile.WriteTo(MODULE_NAME, outputPrefix, "_scsi_modesense6.bin", "SCSI MODE SENSE", DataFile.WriteTo(MODULE_NAME, outputPrefix, "_scsi_modesense6.bin", "SCSI MODE SENSE",
devInfo.ScsiModeSense6); devInfo.ScsiModeSense6);
}
if(devInfo.ScsiModeSense10 != null) if(devInfo.ScsiModeSense10 != null)
{
DataFile.WriteTo(MODULE_NAME, outputPrefix, "_scsi_modesense10.bin", "SCSI MODE SENSE", DataFile.WriteTo(MODULE_NAME, outputPrefix, "_scsi_modesense10.bin", "SCSI MODE SENSE",
devInfo.ScsiModeSense10); devInfo.ScsiModeSense10);
}
if(devInfo.ScsiMode.HasValue) if(devInfo.ScsiMode.HasValue)
{
PrintScsiModePages.Print(devInfo.ScsiMode.Value, PrintScsiModePages.Print(devInfo.ScsiMode.Value,
(PeripheralDeviceTypes)devInfo.ScsiInquiry.Value.PeripheralDeviceType, (PeripheralDeviceTypes)devInfo.ScsiInquiry.Value.PeripheralDeviceType,
devInfo.ScsiInquiry.Value.VendorIdentification); devInfo.ScsiInquiry.Value.VendorIdentification);
}
if(devInfo.MmcConfiguration != null) if(devInfo.MmcConfiguration != null)
{ {
@@ -841,9 +857,11 @@ sealed class DeviceInfoCommand : Command
} }
} }
else else
{
AaruConsole.DebugWriteLine(MODULE_NAME, AaruConsole.DebugWriteLine(MODULE_NAME,
Localization.Core.GET_CONFIGURATION_returned_no_feature_descriptors); Localization.Core.GET_CONFIGURATION_returned_no_feature_descriptors);
} }
}
if(devInfo.RPC != null) if(devInfo.RPC != null)
AaruConsole.WriteLine(CSS_CPRM.PrettifyRegionalPlaybackControlState(devInfo.RPC)); AaruConsole.WriteLine(CSS_CPRM.PrettifyRegionalPlaybackControlState(devInfo.RPC));
@@ -879,27 +897,35 @@ sealed class DeviceInfoCommand : Command
if(devInfo.PlextorFeatures.PoweRecEnabled) if(devInfo.PlextorFeatures.PoweRecEnabled)
{ {
if(devInfo.PlextorFeatures.PoweRecRecommendedSpeed > 0) if(devInfo.PlextorFeatures.PoweRecRecommendedSpeed > 0)
{
AaruConsole.WriteLine(Localization.Core.Drive_supports_PoweRec_is_enabled_and_recommends_0, AaruConsole.WriteLine(Localization.Core.Drive_supports_PoweRec_is_enabled_and_recommends_0,
devInfo.PlextorFeatures.PoweRecRecommendedSpeed); devInfo.PlextorFeatures.PoweRecRecommendedSpeed);
}
else else
AaruConsole.WriteLine(Localization.Core.Drive_supports_PoweRec_and_has_it_enabled); AaruConsole.WriteLine(Localization.Core.Drive_supports_PoweRec_and_has_it_enabled);
if(devInfo.PlextorFeatures.PoweRecSelected > 0) if(devInfo.PlextorFeatures.PoweRecSelected > 0)
{
AaruConsole. AaruConsole.
WriteLine(Localization.Core.Selected_PoweRec_speed_for_currently_inserted_media_is_0_1, WriteLine(Localization.Core.Selected_PoweRec_speed_for_currently_inserted_media_is_0_1,
devInfo.PlextorFeatures.PoweRecSelected, devInfo.PlextorFeatures.PoweRecSelected,
devInfo.PlextorFeatures.PoweRecSelected / 177); devInfo.PlextorFeatures.PoweRecSelected / 177);
}
if(devInfo.PlextorFeatures.PoweRecMax > 0) if(devInfo.PlextorFeatures.PoweRecMax > 0)
{
AaruConsole. AaruConsole.
WriteLine(Localization.Core.Maximum_PoweRec_speed_for_currently_inserted_media_is_0_1, WriteLine(Localization.Core.Maximum_PoweRec_speed_for_currently_inserted_media_is_0_1,
devInfo.PlextorFeatures.PoweRecMax, devInfo.PlextorFeatures.PoweRecMax / 177); devInfo.PlextorFeatures.PoweRecMax, devInfo.PlextorFeatures.PoweRecMax / 177);
}
if(devInfo.PlextorFeatures.PoweRecLast > 0) if(devInfo.PlextorFeatures.PoweRecLast > 0)
{
AaruConsole.WriteLine(Localization.Core.Last_used_PoweRec_was_0_1, AaruConsole.WriteLine(Localization.Core.Last_used_PoweRec_was_0_1,
devInfo.PlextorFeatures.PoweRecLast, devInfo.PlextorFeatures.PoweRecLast,
devInfo.PlextorFeatures.PoweRecLast / 177); devInfo.PlextorFeatures.PoweRecLast / 177);
} }
}
else else
AaruConsole.WriteLine(Localization.Core.Drive_supports_PoweRec_and_has_it_disabled); AaruConsole.WriteLine(Localization.Core.Drive_supports_PoweRec_and_has_it_disabled);
} }
@@ -917,19 +943,25 @@ sealed class DeviceInfoCommand : Command
: Localization.Core.Access_time_is_fast)); : Localization.Core.Access_time_is_fast));
if(devInfo.PlextorFeatures.CdReadSpeedLimit > 0) if(devInfo.PlextorFeatures.CdReadSpeedLimit > 0)
{
AaruConsole.WriteLine("\t" + Localization.Core.CD_read_speed_limited_to_0, AaruConsole.WriteLine("\t" + Localization.Core.CD_read_speed_limited_to_0,
devInfo.PlextorFeatures.CdReadSpeedLimit); devInfo.PlextorFeatures.CdReadSpeedLimit);
}
if(devInfo.PlextorFeatures.DvdReadSpeedLimit > 0 && if(devInfo.PlextorFeatures.DvdReadSpeedLimit > 0 &&
devInfo.PlextorFeatures.IsDvd) devInfo.PlextorFeatures.IsDvd)
{
AaruConsole.WriteLine("\t" + Localization.Core.DVD_read_speed_limited_to_0, AaruConsole.WriteLine("\t" + Localization.Core.DVD_read_speed_limited_to_0,
devInfo.PlextorFeatures.DvdReadSpeedLimit); devInfo.PlextorFeatures.DvdReadSpeedLimit);
}
if(devInfo.PlextorFeatures.CdWriteSpeedLimit > 0) if(devInfo.PlextorFeatures.CdWriteSpeedLimit > 0)
{
AaruConsole.WriteLine("\t" + Localization.Core.CD_write_speed_limited_to_0, AaruConsole.WriteLine("\t" + Localization.Core.CD_write_speed_limited_to_0,
devInfo.PlextorFeatures.CdWriteSpeedLimit); devInfo.PlextorFeatures.CdWriteSpeedLimit);
} }
} }
}
if(devInfo.PlextorFeatures?.GigaRec == true) if(devInfo.PlextorFeatures?.GigaRec == true)
AaruConsole.WriteLine(Localization.Core.Drive_supports_Plextor_GigaRec); AaruConsole.WriteLine(Localization.Core.Drive_supports_Plextor_GigaRec);
@@ -938,9 +970,11 @@ sealed class DeviceInfoCommand : Command
AaruConsole.WriteLine(Localization.Core.Drive_supports_Plextor_SecuRec); AaruConsole.WriteLine(Localization.Core.Drive_supports_Plextor_SecuRec);
if(devInfo.PlextorFeatures?.SpeedRead == true) if(devInfo.PlextorFeatures?.SpeedRead == true)
{
AaruConsole.WriteLine(devInfo.PlextorFeatures.SpeedReadEnabled AaruConsole.WriteLine(devInfo.PlextorFeatures.SpeedReadEnabled
? Localization.Core.Drive_supports_Plextor_SpeedRead_and_has_it_enabled ? Localization.Core.Drive_supports_Plextor_SpeedRead_and_has_it_enabled
: Localization.Core.Drive_supports_Plextor_SpeedRead); : Localization.Core.Drive_supports_Plextor_SpeedRead);
}
if(devInfo.PlextorFeatures?.Hiding == true) if(devInfo.PlextorFeatures?.Hiding == true)
{ {
@@ -1046,7 +1080,7 @@ sealed class DeviceInfoCommand : Command
{ {
case DeviceType.MMC: case DeviceType.MMC:
{ {
bool noInfo = true; var noInfo = true;
if(devInfo.CID != null) if(devInfo.CID != null)
{ {
@@ -1086,7 +1120,7 @@ sealed class DeviceInfoCommand : Command
break; break;
case DeviceType.SecureDigital: case DeviceType.SecureDigital:
{ {
bool noInfo = true; var noInfo = true;
if(devInfo.CID != null) if(devInfo.CID != null)
{ {
@@ -1166,7 +1200,8 @@ sealed class DeviceInfoCommand : Command
d.Manufacturer == dev.Manufacturer.Replace('/', '-')) && d.Manufacturer == dev.Manufacturer.Replace('/', '-')) &&
(d.Model == dev.Model || d.Model == dev.Model.Replace('/', '-'))); (d.Model == dev.Model || d.Model == dev.Model.Replace('/', '-')));
AaruConsole.WriteLine(cdOffset is null ? "CD reading offset not found in database." AaruConsole.WriteLine(cdOffset is null
? "CD reading offset not found in database."
: $"CD reading offset is {cdOffset.Offset} samples ({cdOffset.Offset * 4} bytes)."); : $"CD reading offset is {cdOffset.Offset} samples ({cdOffset.Offset * 4} bytes).");
return (int)ErrorNumber.NoError; return (int)ErrorNumber.NoError;

View File

@@ -80,6 +80,7 @@ sealed class ListDevicesCommand : Command
} }
if(verbose) if(verbose)
{
AaruConsole.WriteEvent += (format, objects) => AaruConsole.WriteEvent += (format, objects) =>
{ {
if(objects is null) if(objects is null)
@@ -87,6 +88,7 @@ sealed class ListDevicesCommand : Command
else else
AnsiConsole.Markup(format, objects); AnsiConsole.Markup(format, objects);
}; };
}
Statistics.AddCommand("list-devices"); Statistics.AddCommand("list-devices");
@@ -99,8 +101,10 @@ sealed class ListDevicesCommand : Command
out string serverArchitecture, aaruRemoteHost); out string serverArchitecture, aaruRemoteHost);
if(isRemote) if(isRemote)
{
Statistics.AddRemote(serverApplication, serverVersion, serverOperatingSystem, serverOperatingSystemVersion, Statistics.AddRemote(serverApplication, serverVersion, serverOperatingSystem, serverOperatingSystemVersion,
serverArchitecture); serverArchitecture);
}
if(devices == null || if(devices == null ||
devices.Length == 0) devices.Length == 0)
@@ -116,9 +120,11 @@ sealed class ListDevicesCommand : Command
table.AddColumn(UI.Supported_Question); table.AddColumn(UI.Supported_Question);
foreach(DeviceInfo dev in devices.OrderBy(d => d.Path)) foreach(DeviceInfo dev in devices.OrderBy(d => d.Path))
{
table.AddRow(Markup.Escape(dev.Path ?? ""), Markup.Escape(dev.Vendor ?? ""), table.AddRow(Markup.Escape(dev.Path ?? ""), Markup.Escape(dev.Vendor ?? ""),
Markup.Escape(dev.Model ?? ""), Markup.Escape(dev.Serial ?? ""), Markup.Escape(dev.Model ?? ""), Markup.Escape(dev.Serial ?? ""),
Markup.Escape(dev.Bus ?? ""), dev.Supported ? "[green]✓[/]" : "[red]✗[/]"); Markup.Escape(dev.Bus ?? ""), dev.Supported ? "[green]✓[/]" : "[red]✗[/]");
}
AnsiConsole.Write(table); AnsiConsole.Write(table);
} }

View File

@@ -57,25 +57,14 @@ sealed class ExtractFilesCommand : Command
public ExtractFilesCommand() : base("extract", UI.Filesystem_Extract_Command_Description) public ExtractFilesCommand() : base("extract", UI.Filesystem_Extract_Command_Description)
{ {
Add(new Option<string>(new[] Add(new Option<string>(new[] { "--encoding", "-e" }, () => null, UI.Name_of_character_encoding_to_use));
{
"--encoding", "-e"
}, () => null, UI.Name_of_character_encoding_to_use));
Add(new Option<string>(new[] Add(new Option<string>(new[] { "--options", "-O" }, () => null,
{ UI.Comma_separated_name_value_pairs_of_filesystem_options));
"--options", "-O"
}, () => null, UI.Comma_separated_name_value_pairs_of_filesystem_options));
Add(new Option<bool>(new[] Add(new Option<bool>(new[] { "--xattrs", "-x" }, () => false, UI.Extract_extended_attributes_if_present));
{
"--xattrs", "-x"
}, () => false, UI.Extract_extended_attributes_if_present));
Add(new Option<string>(new[] Add(new Option<string>(new[] { "--namespace", "-n" }, () => null, UI.Namespace_to_use_for_filenames));
{
"--namespace", "-n"
}, () => null, UI.Namespace_to_use_for_filenames));
AddArgument(new Argument<string> AddArgument(new Argument<string>
{ {
@@ -116,6 +105,7 @@ sealed class ExtractFilesCommand : Command
} }
if(verbose) if(verbose)
{
AaruConsole.WriteEvent += (format, objects) => AaruConsole.WriteEvent += (format, objects) =>
{ {
if(objects is null) if(objects is null)
@@ -123,6 +113,7 @@ sealed class ExtractFilesCommand : Command
else else
AnsiConsole.Markup(format, objects); AnsiConsole.Markup(format, objects);
}; };
}
Statistics.AddCommand("extract-files"); Statistics.AddCommand("extract-files");
@@ -161,6 +152,7 @@ sealed class ExtractFilesCommand : Command
Encoding encodingClass = null; Encoding encodingClass = null;
if(encoding != null) if(encoding != null)
{
try try
{ {
encodingClass = Claunia.Encoding.Encoding.GetEncoding(encoding); encodingClass = Claunia.Encoding.Encoding.GetEncoding(encoding);
@@ -174,6 +166,7 @@ sealed class ExtractFilesCommand : Command
return (int)ErrorNumber.EncodingUnknown; return (int)ErrorNumber.EncodingUnknown;
} }
}
PluginBase plugins = PluginBase.Singleton; PluginBase plugins = PluginBase.Singleton;
@@ -292,7 +285,7 @@ sealed class ExtractFilesCommand : Command
AaruConsole.WriteLine(UI._0_partitions_found, partitions.Count); AaruConsole.WriteLine(UI._0_partitions_found, partitions.Count);
for(int i = 0; i < partitions.Count; i++) for(var i = 0; i < partitions.Count; i++)
{ {
AaruConsole.WriteLine(); AaruConsole.WriteLine();
AaruConsole.WriteLine($"[bold]{string.Format(UI.Partition_0, partitions[i].Sequence)}[/]"); AaruConsole.WriteLine($"[bold]{string.Format(UI.Partition_0, partitions[i].Sequence)}[/]");
@@ -301,8 +294,10 @@ sealed class ExtractFilesCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask(UI.Identifying_filesystems_on_partition).IsIndeterminate(); ctx.AddTask(UI.Identifying_filesystems_on_partition).
Core.Filesystems.Identify(imageFormat, out idPlugins, partitions[i]); IsIndeterminate();
Core.Filesystems.Identify(imageFormat, out idPlugins,
partitions[i]);
}); });
if(idPlugins.Count == 0) if(idPlugins.Count == 0)
@@ -318,6 +313,7 @@ sealed class ExtractFilesCommand : Command
}[/]"); }[/]");
foreach(string pluginName in idPlugins) foreach(string pluginName in idPlugins)
{
if(plugins.ReadOnlyFilesystems.TryGetValue(pluginName, out pluginType)) if(plugins.ReadOnlyFilesystems.TryGetValue(pluginName, out pluginType))
{ {
AaruConsole.WriteLine($"[bold]{string.Format(UI.As_identified_by_0, pluginType.Name) AaruConsole.WriteLine($"[bold]{string.Format(UI.As_identified_by_0, pluginType.Name)
@@ -328,15 +324,18 @@ sealed class ExtractFilesCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask(UI.Mounting_filesystem).IsIndeterminate(); ctx.AddTask(UI.Mounting_filesystem).
IsIndeterminate();
error = fs.Mount(imageFormat, partitions[i], encodingClass, parsedOptions, error = fs.Mount(imageFormat, partitions[i],
encodingClass, parsedOptions,
@namespace); @namespace);
}); });
if(error == ErrorNumber.NoError) if(error == ErrorNumber.NoError)
{ {
string volumeName = string.IsNullOrEmpty(fs.Metadata.VolumeName) ? "NO NAME" string volumeName = string.IsNullOrEmpty(fs.Metadata.VolumeName)
? "NO NAME"
: fs.Metadata.VolumeName; : fs.Metadata.VolumeName;
ExtractFilesInDir("/", fs, volumeName, outputDir, xattrs); ExtractFilesInDir("/", fs, volumeName, outputDir, xattrs);
@@ -347,6 +346,7 @@ sealed class ExtractFilesCommand : Command
AaruConsole.ErrorWriteLine(UI.Unable_to_mount_volume_error_0, error.ToString()); AaruConsole.ErrorWriteLine(UI.Unable_to_mount_volume_error_0, error.ToString());
} }
} }
}
else else
{ {
plugins.ReadOnlyFilesystems.TryGetValue(idPlugins[0], out pluginType); plugins.ReadOnlyFilesystems.TryGetValue(idPlugins[0], out pluginType);
@@ -360,12 +360,15 @@ sealed class ExtractFilesCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask(UI.Mounting_filesystem).IsIndeterminate(); ctx.AddTask(UI.Mounting_filesystem).IsIndeterminate();
error = fs.Mount(imageFormat, partitions[i], encodingClass, parsedOptions, @namespace); error = fs.Mount(imageFormat, partitions[i],
encodingClass, parsedOptions,
@namespace);
}); });
if(error == ErrorNumber.NoError) if(error == ErrorNumber.NoError)
{ {
string volumeName = string.IsNullOrEmpty(fs.Metadata.VolumeName) ? "NO NAME" string volumeName = string.IsNullOrEmpty(fs.Metadata.VolumeName)
? "NO NAME"
: fs.Metadata.VolumeName; : fs.Metadata.VolumeName;
ExtractFilesInDir("/", fs, volumeName, outputDir, xattrs); ExtractFilesInDir("/", fs, volumeName, outputDir, xattrs);
@@ -424,9 +427,11 @@ sealed class ExtractFilesCommand : Command
outputPath = Path.Combine(outputDir, fs.Metadata.Type, volumeName, path, entry); outputPath = Path.Combine(outputDir, fs.Metadata.Type, volumeName, path, entry);
if(RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) if(RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
outputPath = outputPath.Replace('<', '\uFF1C').Replace('>', '\uFF1E').Replace(':', '\uFF1A'). outputPath = outputPath.Replace('<', '\uFF1C').Replace('>', '\uFF1E').Replace(':', '\uFF1A').
Replace('\"', '\uFF02').Replace('|', '\uFF5C').Replace('?', '\uFF1F'). Replace('\"', '\uFF02').Replace('|', '\uFF5C').Replace('?', '\uFF1F').
Replace('*', '\uFF0A').Replace('/', '\\'); Replace('*', '\uFF0A').Replace('/', '\\');
}
Directory.CreateDirectory(outputPath); Directory.CreateDirectory(outputPath);
@@ -479,19 +484,23 @@ sealed class ExtractFilesCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask(UI.Listing_extended_attributes).IsIndeterminate(); ctx.AddTask(UI.Listing_extended_attributes).
IsIndeterminate();
error = fs.ListXAttr(path + "/" + entry, out xattrs); error = fs.ListXAttr(path + "/" + entry, out xattrs);
}); });
if(error == ErrorNumber.NoError) if(error == ErrorNumber.NoError)
{
foreach(string xattr in xattrs) foreach(string xattr in xattrs)
{ {
byte[] xattrBuf = Array.Empty<byte>(); byte[] xattrBuf = Array.Empty<byte>();
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask(UI.Reading_extended_attribute).IsIndeterminate(); ctx.AddTask(UI.Reading_extended_attribute).
error = fs.GetXattr(path + "/" + entry, xattr, ref xattrBuf); IsIndeterminate();
error = fs.GetXattr(path + "/" + entry, xattr,
ref xattrBuf);
}); });
if(error != ErrorNumber.NoError) if(error != ErrorNumber.NoError)
@@ -500,10 +509,12 @@ sealed class ExtractFilesCommand : Command
outputPath = Path.Combine(outputDir, fs.Metadata.Type, volumeName, ".xattrs", path, xattr); outputPath = Path.Combine(outputDir, fs.Metadata.Type, volumeName, ".xattrs", path, xattr);
if(RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) if(RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
outputPath = outputPath.Replace('<', '\uFF1C').Replace('>', '\uFF1E'). outputPath = outputPath.Replace('<', '\uFF1C').Replace('>', '\uFF1E').
Replace(':', '\uFF1A').Replace('\"', '\uFF02'). Replace(':', '\uFF1A').Replace('\"', '\uFF02').
Replace('|', '\uFF5C').Replace('?', '\uFF1F'). Replace('|', '\uFF5C').Replace('?', '\uFF1F').
Replace('*', '\uFF0A').Replace('/', '\\'); Replace('*', '\uFF0A').Replace('/', '\\');
}
Directory.CreateDirectory(outputPath); Directory.CreateDirectory(outputPath);
@@ -513,18 +524,24 @@ sealed class ExtractFilesCommand : Command
: Path.Combine(outputPath, entry); : Path.Combine(outputPath, entry);
if(RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) if(RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
outputPath = outputPath.Replace('<', '\uFF1C').Replace('>', '\uFF1E'). outputPath = outputPath.Replace('<', '\uFF1C').Replace('>', '\uFF1E').
Replace(':', '\uFF1A').Replace('\"', '\uFF02'). Replace(':', '\uFF1A').Replace('\"', '\uFF02').
Replace('|', '\uFF5C').Replace('?', '\uFF1F'). Replace('|', '\uFF5C').Replace('?', '\uFF1F').
Replace('*', '\uFF0A').Replace('/', '\\'); Replace('*', '\uFF0A').Replace('/', '\\');
}
if(!File.Exists(outputPath)) if(!File.Exists(outputPath))
{ {
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask(UI.Writing_extended_attribute).IsIndeterminate(); ctx.AddTask(UI.Writing_extended_attribute).
IsIndeterminate();
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);
@@ -570,13 +587,16 @@ sealed class ExtractFilesCommand : Command
AaruConsole.ErrorWriteLine(UI.Cannot_write_xattr_0_for_1_output_exists, xattr, entry); AaruConsole.ErrorWriteLine(UI.Cannot_write_xattr_0_for_1_output_exists, xattr, entry);
} }
} }
}
outputPath = Path.Combine(outputDir, fs.Metadata.Type, volumeName, path); outputPath = Path.Combine(outputDir, fs.Metadata.Type, volumeName, path);
if(RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) if(RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
outputPath = outputPath.Replace('<', '\uFF1C').Replace('>', '\uFF1E').Replace(':', '\uFF1A'). outputPath = outputPath.Replace('<', '\uFF1C').Replace('>', '\uFF1E').Replace(':', '\uFF1A').
Replace('\"', '\uFF02').Replace('|', '\uFF5C').Replace('?', '\uFF1F'). Replace('\"', '\uFF02').Replace('|', '\uFF5C').Replace('?', '\uFF1F').
Replace('*', '\uFF0A').Replace('/', '\\'); Replace('*', '\uFF0A').Replace('/', '\\');
}
Directory.CreateDirectory(outputPath); Directory.CreateDirectory(outputPath);
@@ -585,9 +605,11 @@ sealed class ExtractFilesCommand : Command
: Path.Combine(outputPath, entry); : Path.Combine(outputPath, entry);
if(RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) if(RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
outputPath = outputPath.Replace('<', '\uFF1C').Replace('>', '\uFF1E').Replace(':', '\uFF1A'). outputPath = outputPath.Replace('<', '\uFF1C').Replace('>', '\uFF1E').Replace(':', '\uFF1A').
Replace('\"', '\uFF02').Replace('|', '\uFF5C').Replace('?', '\uFF1F'). Replace('\"', '\uFF02').Replace('|', '\uFF5C').Replace('?', '\uFF1F').
Replace('*', '\uFF0A').Replace('/', '\\'); Replace('*', '\uFF0A').Replace('/', '\\');
}
if(!File.Exists(outputPath)) if(!File.Exists(outputPath))
{ {
@@ -603,7 +625,7 @@ sealed class ExtractFilesCommand : Command
ctx.AddTask(string.Format(UI.Reading_file_0, Markup.Escape(entry))); ctx.AddTask(string.Format(UI.Reading_file_0, Markup.Escape(entry)));
task.MaxValue = stat.Length; task.MaxValue = stat.Length;
byte[] outBuf = new byte[BUFFER_SIZE]; var outBuf = new byte[BUFFER_SIZE];
error = fs.OpenFile(path + "/" + entry, out IFileNode fileNode); error = fs.OpenFile(path + "/" + entry, out IFileNode fileNode);
if(error == ErrorNumber.NoError) if(error == ErrorNumber.NoError)
@@ -617,13 +639,15 @@ sealed class ExtractFilesCommand : Command
else else
bytesToRead = stat.Length - position; bytesToRead = stat.Length - position;
error = fs.ReadFile(fileNode, bytesToRead, outBuf, out long bytesRead); error = fs.ReadFile(fileNode, bytesToRead, outBuf,
out long bytesRead);
if(error == ErrorNumber.NoError) if(error == ErrorNumber.NoError)
outputFile.Write(outBuf, 0, (int)bytesRead); outputFile.Write(outBuf, 0, (int)bytesRead);
else else
{ {
AaruConsole.ErrorWriteLine(UI.Error_0_reading_file_1, error, entry); AaruConsole.ErrorWriteLine(UI.Error_0_reading_file_1, error,
entry);
break; break;
} }

View File

@@ -53,20 +53,12 @@ sealed class FilesystemInfoCommand : Command
public FilesystemInfoCommand() : base("info", UI.Filesystem_Info_Command_Description) public FilesystemInfoCommand() : base("info", UI.Filesystem_Info_Command_Description)
{ {
Add(new Option<string>(new[] Add(new Option<string>(new[] { "--encoding", "-e" }, () => null, UI.Name_of_character_encoding_to_use));
{
"--encoding", "-e"
}, () => null, UI.Name_of_character_encoding_to_use));
Add(new Option<bool>(new[] Add(new Option<bool>(new[] { "--filesystems", "-f" }, () => true,
{ UI.Searches_and_prints_information_about_filesystems));
"--filesystems", "-f"
}, () => true, UI.Searches_and_prints_information_about_filesystems));
Add(new Option<bool>(new[] Add(new Option<bool>(new[] { "--partitions", "-p" }, () => true, UI.Searches_and_interprets_partitions));
{
"--partitions", "-p"
}, () => true, UI.Searches_and_interprets_partitions));
AddArgument(new Argument<string> AddArgument(new Argument<string>
{ {
@@ -100,6 +92,7 @@ sealed class FilesystemInfoCommand : Command
} }
if(verbose) if(verbose)
{
AaruConsole.WriteEvent += (format, objects) => AaruConsole.WriteEvent += (format, objects) =>
{ {
if(objects is null) if(objects is null)
@@ -107,6 +100,7 @@ sealed class FilesystemInfoCommand : Command
else else
AnsiConsole.Markup(format, objects); AnsiConsole.Markup(format, objects);
}; };
}
Statistics.AddCommand("fs-info"); Statistics.AddCommand("fs-info");
@@ -136,6 +130,7 @@ sealed class FilesystemInfoCommand : Command
Encoding encodingClass = null; Encoding encodingClass = null;
if(encoding != null) if(encoding != null)
{
try try
{ {
encodingClass = Claunia.Encoding.Encoding.GetEncoding(encoding); encodingClass = Claunia.Encoding.Encoding.GetEncoding(encoding);
@@ -149,10 +144,11 @@ sealed class FilesystemInfoCommand : Command
return (int)ErrorNumber.EncodingUnknown; return (int)ErrorNumber.EncodingUnknown;
} }
}
PluginBase plugins = PluginBase.Singleton; PluginBase plugins = PluginBase.Singleton;
bool checkRaw = false; var checkRaw = false;
try try
{ {
@@ -257,7 +253,7 @@ sealed class FilesystemInfoCommand : Command
{ {
AaruConsole.WriteLine(UI._0_partitions_found, partitionsList.Count); AaruConsole.WriteLine(UI._0_partitions_found, partitionsList.Count);
for(int i = 0; i < partitionsList.Count; i++) for(var i = 0; i < partitionsList.Count; i++)
{ {
Table table = new() Table table = new()
{ {
@@ -289,8 +285,10 @@ sealed class FilesystemInfoCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask(UI.Identifying_filesystems_on_partition).IsIndeterminate(); ctx.AddTask(UI.Identifying_filesystems_on_partition).
Core.Filesystems.Identify(imageFormat, out idPlugins, partitionsList[i]); IsIndeterminate();
Core.Filesystems.Identify(imageFormat, out idPlugins,
partitionsList[i]);
}); });
switch(idPlugins.Count) switch(idPlugins.Count)
@@ -305,6 +303,7 @@ sealed class FilesystemInfoCommand : Command
idPlugins.Count)}[/]"); idPlugins.Count)}[/]");
foreach(string pluginName in idPlugins) foreach(string pluginName in idPlugins)
{
if(plugins.Filesystems.TryGetValue(pluginName, out pluginType)) if(plugins.Filesystems.TryGetValue(pluginName, out pluginType))
{ {
if(Activator.CreateInstance(pluginType) is not IFilesystem fs) if(Activator.CreateInstance(pluginType) is not IFilesystem fs)
@@ -319,6 +318,7 @@ sealed class FilesystemInfoCommand : Command
AaruConsole.Write(information); AaruConsole.Write(information);
Statistics.AddFilesystem(fsMetadata.Type); Statistics.AddFilesystem(fsMetadata.Type);
} }
}
break; break;
} }
@@ -374,6 +374,7 @@ sealed class FilesystemInfoCommand : Command
}[/]"); }[/]");
foreach(string pluginName in idPlugins) foreach(string pluginName in idPlugins)
{
if(plugins.Filesystems.TryGetValue(pluginName, out pluginType)) if(plugins.Filesystems.TryGetValue(pluginName, out pluginType))
{ {
if(Activator.CreateInstance(pluginType) is not IFilesystem fs) if(Activator.CreateInstance(pluginType) is not IFilesystem fs)
@@ -387,6 +388,7 @@ sealed class FilesystemInfoCommand : Command
AaruConsole.Write(information); AaruConsole.Write(information);
Statistics.AddFilesystem(fsMetadata.Type); Statistics.AddFilesystem(fsMetadata.Type);
} }
}
break; break;
} }

View File

@@ -56,25 +56,14 @@ sealed class LsCommand : Command
{ {
AddAlias("ls"); AddAlias("ls");
Add(new Option<string>(new[] Add(new Option<string>(new[] { "--encoding", "-e" }, () => null, UI.Name_of_character_encoding_to_use));
{
"--encoding", "-e"
}, () => null, UI.Name_of_character_encoding_to_use));
Add(new Option<bool>(new[] Add(new Option<bool>(new[] { "--long-format", "-l" }, () => true, UI.Use_long_format));
{
"--long-format", "-l"
}, () => true, UI.Use_long_format));
Add(new Option<string>(new[] Add(new Option<string>(new[] { "--options", "-O" }, () => null,
{ UI.Comma_separated_name_value_pairs_of_filesystem_options));
"--options", "-O"
}, () => null, UI.Comma_separated_name_value_pairs_of_filesystem_options));
Add(new Option<string>(new[] Add(new Option<string>(new[] { "--namespace", "-n" }, () => null, UI.Namespace_to_use_for_filenames));
{
"--namespace", "-n"
}, () => null, UI.Namespace_to_use_for_filenames));
AddArgument(new Argument<string> AddArgument(new Argument<string>
{ {
@@ -108,6 +97,7 @@ sealed class LsCommand : Command
} }
if(verbose) if(verbose)
{
AaruConsole.WriteEvent += (format, objects) => AaruConsole.WriteEvent += (format, objects) =>
{ {
if(objects is null) if(objects is null)
@@ -115,6 +105,7 @@ sealed class LsCommand : Command
else else
AnsiConsole.Markup(format, objects); AnsiConsole.Markup(format, objects);
}; };
}
AaruConsole.DebugWriteLine(MODULE_NAME, "--debug={0}", debug); AaruConsole.DebugWriteLine(MODULE_NAME, "--debug={0}", debug);
AaruConsole.DebugWriteLine(MODULE_NAME, "--encoding={0}", encoding); AaruConsole.DebugWriteLine(MODULE_NAME, "--encoding={0}", encoding);
@@ -150,6 +141,7 @@ sealed class LsCommand : Command
Encoding encodingClass = null; Encoding encodingClass = null;
if(encoding != null) if(encoding != null)
{
try try
{ {
encodingClass = Claunia.Encoding.Encoding.GetEncoding(encoding); encodingClass = Claunia.Encoding.Encoding.GetEncoding(encoding);
@@ -163,6 +155,7 @@ sealed class LsCommand : Command
return (int)ErrorNumber.EncodingUnknown; return (int)ErrorNumber.EncodingUnknown;
} }
}
PluginBase plugins = PluginBase.Singleton; PluginBase plugins = PluginBase.Singleton;
@@ -264,7 +257,7 @@ sealed class LsCommand : Command
AaruConsole.WriteLine(UI._0_partitions_found, partitions.Count); AaruConsole.WriteLine(UI._0_partitions_found, partitions.Count);
for(int i = 0; i < partitions.Count; i++) for(var i = 0; i < partitions.Count; i++)
{ {
AaruConsole.WriteLine(); AaruConsole.WriteLine();
AaruConsole.WriteLine($"[bold]{string.Format(UI.Partition_0, partitions[i].Sequence)}[/]"); AaruConsole.WriteLine($"[bold]{string.Format(UI.Partition_0, partitions[i].Sequence)}[/]");
@@ -273,8 +266,10 @@ sealed class LsCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask(UI.Identifying_filesystems_on_partition).IsIndeterminate(); ctx.AddTask(UI.Identifying_filesystems_on_partition).
Core.Filesystems.Identify(imageFormat, out idPlugins, partitions[i]); IsIndeterminate();
Core.Filesystems.Identify(imageFormat, out idPlugins,
partitions[i]);
}); });
if(idPlugins.Count == 0) if(idPlugins.Count == 0)
@@ -290,6 +285,7 @@ sealed class LsCommand : Command
}[/]"); }[/]");
foreach(string pluginName in idPlugins) foreach(string pluginName in idPlugins)
{
if(plugins.ReadOnlyFilesystems.TryGetValue(pluginName, out pluginType)) if(plugins.ReadOnlyFilesystems.TryGetValue(pluginName, out pluginType))
{ {
if(Activator.CreateInstance(pluginType) is not IReadOnlyFilesystem fs) if(Activator.CreateInstance(pluginType) is not IReadOnlyFilesystem fs)
@@ -299,9 +295,11 @@ sealed class LsCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask(UI.Mounting_filesystem).IsIndeterminate(); ctx.AddTask(UI.Mounting_filesystem).
IsIndeterminate();
error = fs.Mount(imageFormat, partitions[i], encodingClass, parsedOptions, error = fs.Mount(imageFormat, partitions[i],
encodingClass, parsedOptions,
@namespace); @namespace);
}); });
@@ -315,6 +313,7 @@ sealed class LsCommand : Command
AaruConsole.ErrorWriteLine(UI.Unable_to_mount_volume_error_0, error.ToString()); AaruConsole.ErrorWriteLine(UI.Unable_to_mount_volume_error_0, error.ToString());
} }
} }
}
else else
{ {
plugins.ReadOnlyFilesystems.TryGetValue(idPlugins[0], out pluginType); plugins.ReadOnlyFilesystems.TryGetValue(idPlugins[0], out pluginType);
@@ -327,7 +326,9 @@ sealed class LsCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask(UI.Mounting_filesystem).IsIndeterminate(); ctx.AddTask(UI.Mounting_filesystem).IsIndeterminate();
error = fs.Mount(imageFormat, partitions[i], encodingClass, parsedOptions, @namespace); error = fs.Mount(imageFormat, partitions[i],
encodingClass, parsedOptions,
@namespace);
}); });
if(error == ErrorNumber.NoError) if(error == ErrorNumber.NoError)
@@ -361,7 +362,8 @@ sealed class LsCommand : Command
if(path.StartsWith('/')) if(path.StartsWith('/'))
path = path[1..]; path = path[1..];
AaruConsole.WriteLine(string.IsNullOrEmpty(path) ? UI.Root_directory AaruConsole.WriteLine(string.IsNullOrEmpty(path)
? UI.Root_directory
: string.Format(UI.Directory_0, Markup.Escape(path))); : string.Format(UI.Directory_0, Markup.Escape(path)));
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
@@ -396,16 +398,21 @@ sealed class LsCommand : Command
foreach(KeyValuePair<string, FileEntryInfo> entry in foreach(KeyValuePair<string, FileEntryInfo> entry in
stats.OrderBy(e => e.Value?.Attributes.HasFlag(FileAttributes.Directory) == false)) stats.OrderBy(e => e.Value?.Attributes.HasFlag(FileAttributes.Directory) == false))
{
if(longFormat) if(longFormat)
{ {
if(entry.Value != null) if(entry.Value != null)
{ {
if(entry.Value.Attributes.HasFlag(FileAttributes.Directory)) if(entry.Value.Attributes.HasFlag(FileAttributes.Directory))
{
AaruConsole.WriteLine("{0, 10:d} {0, 12:T} {1, -20} {2}", entry.Value.CreationTimeUtc, AaruConsole.WriteLine("{0, 10:d} {0, 12:T} {1, -20} {2}", entry.Value.CreationTimeUtc,
UI.Directory_abbreviation, Markup.Escape(entry.Key)); UI.Directory_abbreviation, Markup.Escape(entry.Key));
}
else else
{
AaruConsole.WriteLine("{0, 10:d} {0, 12:T} {1, 6}{2, 14:N0} {3}", entry.Value.CreationTimeUtc, 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)); entry.Value.Inode, entry.Value.Length, Markup.Escape(entry.Key));
}
error = fs.ListXAttr(path + "/" + entry.Key, out List<string> xattrs); error = fs.ListXAttr(path + "/" + entry.Key, out List<string> xattrs);
@@ -425,9 +432,12 @@ sealed class LsCommand : Command
AaruConsole.WriteLine("{0, 47}{1}", string.Empty, Markup.Escape(entry.Key)); AaruConsole.WriteLine("{0, 47}{1}", string.Empty, Markup.Escape(entry.Key));
} }
else else
{
AaruConsole. AaruConsole.
WriteLine(entry.Value?.Attributes.HasFlag(FileAttributes.Directory) == true ? "{0}/" : "{0}", WriteLine(entry.Value?.Attributes.HasFlag(FileAttributes.Directory) == true ? "{0}/" : "{0}",
entry.Key); entry.Key);
}
}
AaruConsole.WriteLine(); AaruConsole.WriteLine();

View File

@@ -73,6 +73,7 @@ sealed class ListOptionsCommand : Command
} }
if(verbose) if(verbose)
{
AaruConsole.WriteEvent += (format, objects) => AaruConsole.WriteEvent += (format, objects) =>
{ {
if(objects is null) if(objects is null)
@@ -80,6 +81,7 @@ sealed class ListOptionsCommand : Command
else else
AnsiConsole.Markup(format, objects); AnsiConsole.Markup(format, objects);
}; };
}
AaruConsole.DebugWriteLine(MODULE_NAME, "--debug={0}", debug); AaruConsole.DebugWriteLine(MODULE_NAME, "--debug={0}", debug);
AaruConsole.DebugWriteLine(MODULE_NAME, "--verbose={0}", verbose); AaruConsole.DebugWriteLine(MODULE_NAME, "--verbose={0}", verbose);
@@ -94,7 +96,7 @@ sealed class ListOptionsCommand : Command
if(Activator.CreateInstance(kvp.Value) is not IReadOnlyFilesystem fs) if(Activator.CreateInstance(kvp.Value) is not IReadOnlyFilesystem fs)
continue; continue;
List<(string name, Type type, string description)> options = fs.SupportedOptions.ToList(); var options = fs.SupportedOptions.ToList();
if(options.Count == 0) if(options.Count == 0)
continue; continue;
@@ -109,8 +111,10 @@ sealed class ListOptionsCommand : Command
table.AddColumn(UI.Title_Description); table.AddColumn(UI.Title_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))
{
table.AddRow(Markup.Escape(option.name), $"[italic]{TypeToString(option.type)}[/]", table.AddRow(Markup.Escape(option.name), $"[italic]{TypeToString(option.type)}[/]",
Markup.Escape(option.description)); Markup.Escape(option.description));
}
AnsiConsole.Write(table); AnsiConsole.Write(table);
AaruConsole.WriteLine(); AaruConsole.WriteLine();

View File

@@ -73,6 +73,7 @@ sealed class FormatsCommand : Command
} }
if(verbose) if(verbose)
{
AaruConsole.WriteEvent += (format, objects) => AaruConsole.WriteEvent += (format, objects) =>
{ {
if(objects is null) if(objects is null)
@@ -80,6 +81,7 @@ sealed class FormatsCommand : Command
else else
AnsiConsole.Markup(format, objects); AnsiConsole.Markup(format, objects);
}; };
}
Statistics.AddCommand("formats"); Statistics.AddCommand("formats");
@@ -100,10 +102,12 @@ sealed class FormatsCommand : Command
table.AddColumn(UI.Title_Filter); table.AddColumn(UI.Title_Filter);
foreach(KeyValuePair<string, IFilter> kvp in filtersList.Filters) foreach(KeyValuePair<string, IFilter> kvp in filtersList.Filters)
{
if(verbose) if(verbose)
table.AddRow(kvp.Value.Id.ToString(), Markup.Escape(kvp.Value.Name)); table.AddRow(kvp.Value.Id.ToString(), Markup.Escape(kvp.Value.Name));
else else
table.AddRow(Markup.Escape(kvp.Value.Name)); table.AddRow(Markup.Escape(kvp.Value.Name));
}
AnsiConsole.Write(table); AnsiConsole.Write(table);

View File

@@ -58,50 +58,29 @@ sealed class ChecksumCommand : Command
{ {
AddAlias("chk"); AddAlias("chk");
Add(new Option<bool>(new[] Add(new Option<bool>(new[] { "--adler32", "-a" }, () => false, UI.Calculates_Adler_32));
{
"--adler32", "-a"
}, () => false, UI.Calculates_Adler_32));
Add(new Option<bool>("--crc16", () => true, UI.Calculates_CRC16)); Add(new Option<bool>("--crc16", () => true, UI.Calculates_CRC16));
Add(new Option<bool>(new[] Add(new Option<bool>(new[] { "--crc32", "-c" }, () => true, UI.Calculates_CRC32));
{
"--crc32", "-c"
}, () => true, UI.Calculates_CRC32));
Add(new Option<bool>("--crc64", () => true, UI.Calculates_CRC64_ECMA)); Add(new Option<bool>("--crc64", () => true, UI.Calculates_CRC64_ECMA));
Add(new Option<bool>("--fletcher16", () => false, UI.Calculates_Fletcher_16)); Add(new Option<bool>("--fletcher16", () => false, UI.Calculates_Fletcher_16));
Add(new Option<bool>("--fletcher32", () => false, UI.Calculates_Fletcher_32)); Add(new Option<bool>("--fletcher32", () => false, UI.Calculates_Fletcher_32));
Add(new Option<bool>(new[] Add(new Option<bool>(new[] { "--md5", "-m" }, () => true, UI.Calculates_MD5));
{
"--md5", "-m"
}, () => true, UI.Calculates_MD5));
Add(new Option<bool>(new[] Add(new Option<bool>(new[] { "--separated-tracks", "-t" }, () => true, UI.Checksums_each_track_separately));
{
"--separated-tracks", "-t"
}, () => true, UI.Checksums_each_track_separately));
Add(new Option<bool>(new[] Add(new Option<bool>(new[] { "--sha1", "-s" }, () => true, UI.Calculates_SHA1));
{
"--sha1", "-s"
}, () => true, UI.Calculates_SHA1));
Add(new Option<bool>("--sha256", () => false, UI.Calculates_SHA256)); Add(new Option<bool>("--sha256", () => false, UI.Calculates_SHA256));
Add(new Option<bool>("--sha384", () => false, UI.Calculates_SHA384)); Add(new Option<bool>("--sha384", () => false, UI.Calculates_SHA384));
Add(new Option<bool>("--sha512", () => true, UI.Calculates_SHA512)); Add(new Option<bool>("--sha512", () => true, UI.Calculates_SHA512));
Add(new Option<bool>(new[] Add(new Option<bool>(new[] { "--spamsum", "-f" }, () => true, UI.Calculates_SpamSum_fuzzy_hash));
{
"--spamsum", "-f"
}, () => true, UI.Calculates_SpamSum_fuzzy_hash));
Add(new Option<bool>(new[] Add(new Option<bool>(new[] { "--whole-disc", "-w" }, () => true, UI.Checksums_the_whole_disc));
{
"--whole-disc", "-w"
}, () => true, UI.Checksums_the_whole_disc));
AddArgument(new Argument<string> AddArgument(new Argument<string>
{ {
@@ -136,6 +115,7 @@ sealed class ChecksumCommand : Command
} }
if(verbose) if(verbose)
{
AaruConsole.WriteEvent += (format, objects) => AaruConsole.WriteEvent += (format, objects) =>
{ {
if(objects is null) if(objects is null)
@@ -143,6 +123,7 @@ sealed class ChecksumCommand : Command
else else
AnsiConsole.Markup(format, objects); AnsiConsole.Markup(format, objects);
}; };
}
Statistics.AddCommand("checksum"); Statistics.AddCommand("checksum");
@@ -258,7 +239,7 @@ sealed class ChecksumCommand : Command
switch(inputFormat) switch(inputFormat)
{ {
case IOpticalMediaImage { Tracks: {} } opticalInput: case IOpticalMediaImage { Tracks: not null } opticalInput:
try try
{ {
Checksum trackChecksum = null; Checksum trackChecksum = null;
@@ -296,8 +277,10 @@ sealed class ChecksumCommand : Command
*/ */
AaruConsole.DebugWriteLine(MODULE_NAME, AaruConsole.DebugWriteLine(MODULE_NAME,
UI.Track_0_starts_at_sector_1_and_ends_at_sector_2, UI.
currentTrack.Sequence, currentTrack.StartSector, Track_0_starts_at_sector_1_and_ends_at_sector_2,
currentTrack.Sequence,
currentTrack.StartSector,
currentTrack.EndSector); currentTrack.EndSector);
if(separatedTracks) if(separatedTracks)
@@ -319,8 +302,10 @@ sealed class ChecksumCommand : Command
currentTrack.Sequence, out sector); currentTrack.Sequence, out sector);
trackTask.Description = trackTask.Description =
string.Format(UI.Hashing_sectors_0_to_2_of_track_1, doneSectors, string.Format(UI.Hashing_sectors_0_to_2_of_track_1,
currentTrack.Sequence, doneSectors + SECTORS_TO_READ); doneSectors,
currentTrack.Sequence,
doneSectors + SECTORS_TO_READ);
if(errno != ErrorNumber.NoError) if(errno != ErrorNumber.NoError)
{ {
@@ -342,7 +327,8 @@ sealed class ChecksumCommand : Command
out sector); out sector);
trackTask.Description = trackTask.Description =
string.Format(UI.Hashing_sectors_0_to_2_of_track_1, doneSectors, string.Format(UI.Hashing_sectors_0_to_2_of_track_1,
doneSectors,
currentTrack.Sequence, currentTrack.Sequence,
doneSectors + (sectors - doneSectors)); doneSectors + (sectors - doneSectors));
@@ -379,8 +365,11 @@ sealed class ChecksumCommand : Command
continue; continue;
foreach(CommonTypes.AaruMetadata.Checksum chk in trackChecksum.End()) foreach(CommonTypes.AaruMetadata.Checksum chk in trackChecksum.End())
AaruConsole.WriteLine($"[bold]{string.Format(UI.Checksums_Track_0_has_1, {
AaruConsole.
WriteLine($"[bold]{string.Format(UI.Checksums_Track_0_has_1,
currentTrack.Sequence, chk.Type)}[/] {chk.Value}"); currentTrack.Sequence, chk.Type)}[/] {chk.Value}");
}
discTask.Increment(1); discTask.Increment(1);
} }
@@ -405,8 +394,11 @@ sealed class ChecksumCommand : Command
AaruConsole.WriteLine(); AaruConsole.WriteLine();
foreach(CommonTypes.AaruMetadata.Checksum chk in mediaChecksum.End()) foreach(CommonTypes.AaruMetadata.Checksum chk in mediaChecksum.End())
AaruConsole.WriteLine($"[bold]{string.Format(UI.Checksums_Disc_has_0, chk.Type) {
AaruConsole.
WriteLine($"[bold]{string.Format(UI.Checksums_Disc_has_0, chk.Type)
}:[/] {chk.Value}"); }:[/] {chk.Value}");
}
}); });
if(errno != ErrorNumber.NoError) if(errno != ErrorNumber.NoError)
@@ -441,7 +433,8 @@ sealed class ChecksumCommand : Command
foreach(TapeFile currentFile in tapeImage.Files) foreach(TapeFile currentFile in tapeImage.Files)
{ {
tapeTask.Description = tapeTask.Description =
string.Format(UI.Hashing_file_0_of_1, currentFile.File, tapeImage.Files.Count); string.Format(UI.Hashing_file_0_of_1, currentFile.File,
tapeImage.Files.Count);
if(currentFile.FirstBlock - previousFileEnd != 0 && wholeDisc) if(currentFile.FirstBlock - previousFileEnd != 0 && wholeDisc)
{ {
@@ -450,7 +443,8 @@ sealed class ChecksumCommand : Command
for(ulong i = previousFileEnd + 1; i < currentFile.FirstBlock; i++) for(ulong i = previousFileEnd + 1; i < currentFile.FirstBlock; i++)
{ {
preFileTask.Description = string.Format(UI.Hashing_file_less_block_0, i); preFileTask.Description =
string.Format(UI.Hashing_file_less_block_0, i);
errno = tapeImage.ReadSector(i, out byte[] hiddenSector); errno = tapeImage.ReadSector(i, out byte[] hiddenSector);
@@ -499,7 +493,8 @@ sealed class ChecksumCommand : Command
ErrorWriteLine(string. ErrorWriteLine(string.
Format(UI.Error_0_while_reading_1_sectors_from_sector_2, Format(UI.Error_0_while_reading_1_sectors_from_sector_2,
errno, SECTORS_TO_READ, errno, SECTORS_TO_READ,
doneSectors + currentFile.FirstBlock)); doneSectors +
currentFile.FirstBlock));
return; return;
} }
@@ -513,7 +508,8 @@ sealed class ChecksumCommand : Command
else else
{ {
errno = tapeImage.ReadSectors(doneSectors + currentFile.FirstBlock, errno = tapeImage.ReadSectors(doneSectors + currentFile.FirstBlock,
(uint)(sectors - doneSectors), out sector); (uint)(sectors - doneSectors),
out sector);
if(errno != ErrorNumber.NoError) if(errno != ErrorNumber.NoError)
{ {
@@ -521,14 +517,16 @@ sealed class ChecksumCommand : Command
ErrorWriteLine(string. ErrorWriteLine(string.
Format(UI.Error_0_while_reading_1_sectors_from_sector_2, Format(UI.Error_0_while_reading_1_sectors_from_sector_2,
errno, sectors - doneSectors, errno, sectors - doneSectors,
doneSectors + currentFile.FirstBlock)); doneSectors +
currentFile.FirstBlock));
return; return;
} }
fileTask.Description = fileTask.Description =
string.Format(UI.Hashing_blocks_0_to_2_of_file_1, doneSectors, string.Format(UI.Hashing_blocks_0_to_2_of_file_1, doneSectors,
currentFile.File, doneSectors + (sectors - doneSectors)); currentFile.File,
doneSectors + (sectors - doneSectors));
doneSectors += sectors - doneSectors; doneSectors += sectors - doneSectors;
} }
@@ -546,10 +544,17 @@ sealed class ChecksumCommand : Command
AaruConsole.WriteLine(); AaruConsole.WriteLine();
if(separatedTracks) if(separatedTracks)
{
if(trackChecksum != null) if(trackChecksum != null)
{
foreach(CommonTypes.AaruMetadata.Checksum chk in trackChecksum.End()) foreach(CommonTypes.AaruMetadata.Checksum chk in trackChecksum.End())
AaruConsole.WriteLine($"[bold]{string.Format(UI.Checksums_File_0_has_1, {
AaruConsole.
WriteLine($"[bold]{string.Format(UI.Checksums_File_0_has_1,
currentFile.File, chk.Type)}[/]: {chk.Value}"); currentFile.File, chk.Type)}[/]: {chk.Value}");
}
}
}
previousFileEnd = currentFile.LastBlock; previousFileEnd = currentFile.LastBlock;
@@ -590,9 +595,11 @@ sealed class ChecksumCommand : Command
AaruConsole.WriteLine(); AaruConsole.WriteLine();
foreach(CommonTypes.AaruMetadata.Checksum chk in mediaChecksum.End()) foreach(CommonTypes.AaruMetadata.Checksum chk in mediaChecksum.End())
{
AaruConsole.WriteLine($"[bold]{string.Format(UI.Checksums_Tape_has_0, chk.Type)}[/] {chk.Value AaruConsole.WriteLine($"[bold]{string.Format(UI.Checksums_Tape_has_0, chk.Type)}[/] {chk.Value
}"); }");
} }
}
break; break;
} }
@@ -609,7 +616,7 @@ sealed class ChecksumCommand : Command
ulong length = byteAddressableImage.Info.Sectors; ulong length = byteAddressableImage.Info.Sectors;
imageTask.MaxValue = length; imageTask.MaxValue = length;
ulong doneBytes = 0; ulong doneBytes = 0;
byte[] data = new byte[BYTES_TO_READ]; var data = new byte[BYTES_TO_READ];
while(doneBytes < length) while(doneBytes < length)
{ {
@@ -617,12 +624,14 @@ sealed class ChecksumCommand : Command
if(length - doneBytes >= BYTES_TO_READ) if(length - doneBytes >= BYTES_TO_READ)
{ {
errno = byteAddressableImage.ReadBytes(data, 0, BYTES_TO_READ, out bytesRead); errno = byteAddressableImage.ReadBytes(data, 0, BYTES_TO_READ,
out bytesRead);
if(errno != ErrorNumber.NoError) if(errno != ErrorNumber.NoError)
{ {
AaruConsole. AaruConsole.
ErrorWriteLine(string.Format(UI.Error_0_while_reading_1_bytes_from_2, ErrorWriteLine(string.
Format(UI.Error_0_while_reading_1_bytes_from_2,
errno, BYTES_TO_READ, doneBytes)); errno, BYTES_TO_READ, doneBytes));
return; return;
@@ -645,8 +654,10 @@ sealed class ChecksumCommand : Command
if(errno != ErrorNumber.NoError) if(errno != ErrorNumber.NoError)
{ {
AaruConsole. AaruConsole.
ErrorWriteLine(string.Format(UI.Error_0_while_reading_1_bytes_from_2, ErrorWriteLine(string.
errno, length - doneBytes, doneBytes)); Format(UI.Error_0_while_reading_1_bytes_from_2,
errno, length - doneBytes,
doneBytes));
return; return;
} }
@@ -701,7 +712,8 @@ sealed class ChecksumCommand : Command
AaruConsole. AaruConsole.
ErrorWriteLine(string. ErrorWriteLine(string.
Format(UI.Error_0_while_reading_1_sectors_from_sector_2, Format(UI.Error_0_while_reading_1_sectors_from_sector_2,
errno, SECTORS_TO_READ, doneSectors)); errno, SECTORS_TO_READ,
doneSectors));
return; return;
} }
@@ -722,7 +734,8 @@ sealed class ChecksumCommand : Command
AaruConsole. AaruConsole.
ErrorWriteLine(string. ErrorWriteLine(string.
Format(UI.Error_0_while_reading_1_sectors_from_sector_2, Format(UI.Error_0_while_reading_1_sectors_from_sector_2,
errno, sectors - doneSectors, doneSectors)); errno, sectors - doneSectors,
doneSectors));
return; return;
} }

View File

@@ -95,6 +95,7 @@ sealed class CompareCommand : Command
} }
if(verbose) if(verbose)
{
AaruConsole.WriteEvent += (format, objects) => AaruConsole.WriteEvent += (format, objects) =>
{ {
if(objects is null) if(objects is null)
@@ -102,6 +103,7 @@ sealed class CompareCommand : Command
else else
AnsiConsole.Markup(format, objects); AnsiConsole.Markup(format, objects);
}; };
}
Statistics.AddCommand("compare"); Statistics.AddCommand("compare");
@@ -165,8 +167,10 @@ sealed class CompareCommand : Command
} }
if(verbose) if(verbose)
{
AaruConsole.VerboseWriteLine(UI.First_input_file_format_identified_by_0_1, input1Format.Name, AaruConsole.VerboseWriteLine(UI.First_input_file_format_identified_by_0_1, input1Format.Name,
input1Format.Id); input1Format.Id);
}
else else
AaruConsole.WriteLine(UI.First_input_file_format_identified_by_0, input1Format.Name); AaruConsole.WriteLine(UI.First_input_file_format_identified_by_0, input1Format.Name);
@@ -178,8 +182,10 @@ sealed class CompareCommand : Command
} }
if(verbose) if(verbose)
{
AaruConsole.VerboseWriteLine(UI.Second_input_file_format_identified_by_0_1, input2Format.Name, AaruConsole.VerboseWriteLine(UI.Second_input_file_format_identified_by_0_1, input2Format.Name,
input2Format.Id); input2Format.Id);
}
else else
AaruConsole.WriteLine(UI.Second_input_file_format_identified_by_0, input2Format.Name); AaruConsole.WriteLine(UI.Second_input_file_format_identified_by_0, input2Format.Name);
@@ -239,7 +245,7 @@ sealed class CompareCommand : Command
sb.AppendFormat($"[bold]{UI.Title_Second_Media_image}:[/] {imagePath2}").AppendLine(); sb.AppendFormat($"[bold]{UI.Title_Second_Media_image}:[/] {imagePath2}").AppendLine();
} }
bool imagesDiffer = false; var imagesDiffer = false;
ErrorNumber errno; ErrorNumber errno;
ImageInfo image1Info = input1Format.Info; ImageInfo image1Info = input1Format.Info;
@@ -250,6 +256,7 @@ sealed class CompareCommand : Command
var input2MediaImage = input2Format as IMediaImage; var input2MediaImage = input2Format as IMediaImage;
if(input1MediaImage != null) if(input1MediaImage != null)
{
foreach(MediaTagType diskTag in Enum.GetValues(typeof(MediaTagType))) foreach(MediaTagType diskTag in Enum.GetValues(typeof(MediaTagType)))
{ {
errno = input1MediaImage.ReadMediaTag(diskTag, out byte[] tempArray); errno = input1MediaImage.ReadMediaTag(diskTag, out byte[] tempArray);
@@ -257,8 +264,10 @@ sealed class CompareCommand : Command
if(errno == ErrorNumber.NoError) if(errno == ErrorNumber.NoError)
image1DiskTags.Add(diskTag, tempArray); image1DiskTags.Add(diskTag, tempArray);
} }
}
if(input2MediaImage != null) if(input2MediaImage != null)
{
foreach(MediaTagType diskTag in Enum.GetValues(typeof(MediaTagType))) foreach(MediaTagType diskTag in Enum.GetValues(typeof(MediaTagType)))
{ {
errno = input2MediaImage.ReadMediaTag(diskTag, out byte[] tempArray); errno = input2MediaImage.ReadMediaTag(diskTag, out byte[] tempArray);
@@ -266,6 +275,7 @@ sealed class CompareCommand : Command
if(errno == ErrorNumber.NoError) if(errno == ErrorNumber.NoError)
image2DiskTags.Add(diskTag, tempArray); image2DiskTags.Add(diskTag, tempArray);
} }
}
if(verbose) if(verbose)
{ {
@@ -335,10 +345,12 @@ sealed class CompareCommand : Command
foreach(MediaTagType diskTag in foreach(MediaTagType diskTag in
(Enum.GetValues(typeof(MediaTagType)) as MediaTagType[]).OrderBy(e => e.ToString())) (Enum.GetValues(typeof(MediaTagType)) as MediaTagType[]).OrderBy(e => e.ToString()))
{
table.AddRow(string.Format(UI.Has_tag_0_Question, diskTag), table.AddRow(string.Format(UI.Has_tag_0_Question, diskTag),
image1DiskTags.ContainsKey(diskTag).ToString(), image1DiskTags.ContainsKey(diskTag).ToString(),
image2DiskTags.ContainsKey(diskTag).ToString()); image2DiskTags.ContainsKey(diskTag).ToString());
} }
}
ulong leastSectors = 0; ulong leastSectors = 0;
@@ -427,6 +439,7 @@ sealed class CompareCommand : Command
if(input1MediaImage is not null && if(input1MediaImage is not null &&
input2MediaImage is not null) input2MediaImage is not null)
{
AnsiConsole.Progress().AutoClear(true).HideCompleted(true). AnsiConsole.Progress().AutoClear(true).HideCompleted(true).
Columns(new TaskDescriptionColumn(), new ProgressBarColumn(), new PercentageColumn()). Columns(new TaskDescriptionColumn(), new ProgressBarColumn(), new PercentageColumn()).
Start(ctx => Start(ctx =>
@@ -437,23 +450,30 @@ sealed class CompareCommand : Command
for(ulong sector = 0; sector < leastSectors; sector++) for(ulong sector = 0; sector < leastSectors; sector++)
{ {
task.Value = sector; task.Value = sector;
task.Description = string.Format(UI.Comparing_sector_0_of_1, sector + 1, leastSectors); task.Description =
string.Format(UI.Comparing_sector_0_of_1, sector + 1, leastSectors);
try try
{ {
errno = input1MediaImage.ReadSector(sector, out byte[] image1Sector); errno = input1MediaImage.ReadSector(sector, out byte[] image1Sector);
if(errno != ErrorNumber.NoError) if(errno != ErrorNumber.NoError)
{
AaruConsole. AaruConsole.
ErrorWriteLine(string.Format(UI.Error_0_reading_sector_1_from_first_image, ErrorWriteLine(string.
Format(UI.Error_0_reading_sector_1_from_first_image,
errno, sector)); errno, sector));
}
errno = input2MediaImage.ReadSector(sector, out byte[] image2Sector); errno = input2MediaImage.ReadSector(sector, out byte[] image2Sector);
if(errno != ErrorNumber.NoError) if(errno != ErrorNumber.NoError)
{
AaruConsole. AaruConsole.
ErrorWriteLine(string.Format(UI.Error_0_reading_sector_1_from_second_image, ErrorWriteLine(string.
Format(UI.Error_0_reading_sector_1_from_second_image,
errno, sector)); errno, sector));
}
ArrayHelpers.CompareBytes(out bool different, out bool sameSize, image1Sector, ArrayHelpers.CompareBytes(out bool different, out bool sameSize, image1Sector,
image2Sector); image2Sector);
@@ -476,9 +496,11 @@ sealed class CompareCommand : Command
#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(input1ByteAddressable is not null && if(input1ByteAddressable is not null &&
input2ByteAddressable is not null) input2ByteAddressable is not null)
{
AnsiConsole.Progress().AutoClear(true).HideCompleted(true). AnsiConsole.Progress().AutoClear(true).HideCompleted(true).
Columns(new TaskDescriptionColumn(), new ProgressBarColumn(), new PercentageColumn()). Columns(new TaskDescriptionColumn(), new ProgressBarColumn(), new PercentageColumn()).
Start(ctx => Start(ctx =>
@@ -486,8 +508,8 @@ sealed class CompareCommand : Command
ProgressTask task = ctx.AddTask(UI.Comparing_images); ProgressTask task = ctx.AddTask(UI.Comparing_images);
task.IsIndeterminate = true; task.IsIndeterminate = true;
byte[] data1 = new byte[input1ByteAddressable.Info.Sectors]; var data1 = new byte[input1ByteAddressable.Info.Sectors];
byte[] data2 = new byte[input2ByteAddressable.Info.Sectors]; var data2 = new byte[input2ByteAddressable.Info.Sectors];
byte[] tmp; byte[] tmp;
input1ByteAddressable.ReadBytes(data1, 0, data1.Length, out int bytesRead); input1ByteAddressable.ReadBytes(data1, 0, data1.Length, out int bytesRead);
@@ -515,6 +537,7 @@ sealed class CompareCommand : Command
else if(!sameSize) else if(!sameSize)
imagesDiffer = true; imagesDiffer = true;
}); });
}
AaruConsole.WriteLine(); AaruConsole.WriteLine();

View File

@@ -69,17 +69,12 @@ sealed class ConvertImageCommand : Command
public ConvertImageCommand() : base("convert", UI.Image_Convert_Command_Description) public ConvertImageCommand() : base("convert", UI.Image_Convert_Command_Description)
{ {
Add(new Option<string>(new[] Add(new Option<string>(new[] { "--cicm-xml", "-x" }, () => null,
{ UI.Take_metadata_from_existing_CICM_XML_sidecar));
"--cicm-xml", "-x"
}, () => null, UI.Take_metadata_from_existing_CICM_XML_sidecar));
Add(new Option<string>("--comments", () => null, UI.Image_comments)); Add(new Option<string>("--comments", () => null, UI.Image_comments));
Add(new Option<int>(new[] Add(new Option<int>(new[] { "--count", "-c" }, () => 64, UI.How_many_sectors_to_convert_at_once));
{
"--count", "-c"
}, () => 64, UI.How_many_sectors_to_convert_at_once));
Add(new Option<string>("--creator", () => null, UI.Who_person_created_the_image)); Add(new Option<string>("--creator", () => null, UI.Who_person_created_the_image));
@@ -91,15 +86,10 @@ sealed class ConvertImageCommand : Command
Add(new Option<string>("--drive-serial", () => null, UI.Serial_number_of_drive_read_the_media_by_image)); Add(new Option<string>("--drive-serial", () => null, UI.Serial_number_of_drive_read_the_media_by_image));
Add(new Option<bool>(new[] Add(new Option<bool>(new[] { "--force", "-f" }, UI.Continue_conversion_even_if_data_lost));
{
"--force", "-f"
}, UI.Continue_conversion_even_if_data_lost));
Add(new Option<string>(new[] Add(new Option<string>(new[] { "--format", "-p" }, () => null,
{ UI.Format_of_the_output_image_as_plugin_name_or_plugin_id));
"--format", "-p"
}, () => null, UI.Format_of_the_output_image_as_plugin_name_or_plugin_id));
Add(new Option<string>("--media-barcode", () => null, UI.Barcode_of_the_media_by_image)); Add(new Option<string>("--media-barcode", () => null, UI.Barcode_of_the_media_by_image));
@@ -113,50 +103,26 @@ sealed class ConvertImageCommand : Command
Add(new Option<string>("--media-serial", () => null, UI.Serial_number_of_media_by_image)); Add(new Option<string>("--media-serial", () => null, UI.Serial_number_of_media_by_image));
Add(new Option<string>("--media-title", () => null, UI.Title_of_media_represented_by_image)); Add(new Option<string>("--media-title", () => null, UI.Title_of_media_represented_by_image));
Add(new Option<string>(new[] Add(new Option<string>(new[] { "--options", "-O" }, () => null,
{ UI.Comma_separated_name_value_pairs_of_image_options));
"--options", "-O"
}, () => null, UI.Comma_separated_name_value_pairs_of_image_options));
Add(new Option<string>(new[] Add(new Option<string>(new[] { "--resume-file", "-r" }, () => null,
{ UI.Take_dump_hardware_from_existing_resume));
"--resume-file", "-r"
}, () => null, UI.Take_dump_hardware_from_existing_resume));
Add(new Option<string>(new[] Add(new Option<string>(new[] { "--geometry", "-g" }, () => null, UI.Force_geometry_help));
{
"--geometry", "-g"
}, () => null, UI.Force_geometry_help));
Add(new Option<bool>(new[] Add(new Option<bool>(new[] { "--fix-subchannel-position" }, () => true, UI.Fix_subchannel_position_help));
{
"--fix-subchannel-position"
}, () => true, UI.Fix_subchannel_position_help));
Add(new Option<bool>(new[] Add(new Option<bool>(new[] { "--fix-subchannel" }, () => false, UI.Fix_subchannel_help));
{
"--fix-subchannel"
}, () => false, UI.Fix_subchannel_help));
Add(new Option<bool>(new[] Add(new Option<bool>(new[] { "--fix-subchannel-crc" }, () => false, UI.Fix_subchannel_crc_help));
{
"--fix-subchannel-crc"
}, () => false, UI.Fix_subchannel_crc_help));
Add(new Option<bool>(new[] Add(new Option<bool>(new[] { "--generate-subchannels" }, () => false, UI.Generates_subchannels_help));
{
"--generate-subchannels"
}, () => false, UI.Generates_subchannels_help));
Add(new Option<bool>(new[] Add(new Option<bool>(new[] { "--decrypt" }, () => false, UI.Decrypt_sectors_help));
{
"--decrypt"
}, () => false, UI.Decrypt_sectors_help));
Add(new Option<string>(new[] Add(new Option<string>(new[] { "--aaru-metadata", "-m" }, () => null,
{ "Take metadata from existing Aaru Metadata sidecar."));
"--aaru-metadata", "-m"
}, () => null, "Take metadata from existing Aaru Metadata sidecar."));
AddArgument(new Argument<string> AddArgument(new Argument<string>
{ {
@@ -203,6 +169,7 @@ sealed class ConvertImageCommand : Command
} }
if(verbose) if(verbose)
{
AaruConsole.WriteEvent += (format, objects) => AaruConsole.WriteEvent += (format, objects) =>
{ {
if(objects is null) if(objects is null)
@@ -210,6 +177,7 @@ sealed class ConvertImageCommand : Command
else else
AnsiConsole.Markup(format, objects); AnsiConsole.Markup(format, objects);
}; };
}
if(fixSubchannelCrc) if(fixSubchannelCrc)
fixSubchannel = true; fixSubchannel = true;
@@ -313,7 +281,9 @@ sealed class ConvertImageCommand : Command
if(aaruMetadata != null) if(aaruMetadata != null)
{
if(File.Exists(aaruMetadata)) if(File.Exists(aaruMetadata))
{
try try
{ {
var fs = new FileStream(aaruMetadata, FileMode.Open); var fs = new FileStream(aaruMetadata, FileMode.Open);
@@ -331,15 +301,19 @@ sealed class ConvertImageCommand : Command
return (int)ErrorNumber.InvalidSidecar; return (int)ErrorNumber.InvalidSidecar;
} }
}
else else
{ {
AaruConsole.ErrorWriteLine(UI.Could_not_find_metadata_sidecar); AaruConsole.ErrorWriteLine(UI.Could_not_find_metadata_sidecar);
return (int)ErrorNumber.NoSuchFile; return (int)ErrorNumber.NoSuchFile;
} }
}
else if(cicmXml != null) else if(cicmXml != null)
{
if(File.Exists(cicmXml)) if(File.Exists(cicmXml))
{
try try
{ {
// Should be covered by virtue of being the same exact class as the JSON above // Should be covered by virtue of being the same exact class as the JSON above
@@ -363,12 +337,14 @@ sealed class ConvertImageCommand : Command
return (int)ErrorNumber.InvalidSidecar; return (int)ErrorNumber.InvalidSidecar;
} }
}
else else
{ {
AaruConsole.ErrorWriteLine(UI.Could_not_find_metadata_sidecar); AaruConsole.ErrorWriteLine(UI.Could_not_find_metadata_sidecar);
return (int)ErrorNumber.NoSuchFile; return (int)ErrorNumber.NoSuchFile;
} }
}
if(resumeFile != null) if(resumeFile != null)
{ {
@@ -530,24 +506,36 @@ sealed class ConvertImageCommand : Command
// Try extension // Try extension
if(string.IsNullOrEmpty(format)) if(string.IsNullOrEmpty(format))
{
candidates.AddRange(from pluginType in plugins.WritableImages.Values candidates.AddRange(from pluginType in plugins.WritableImages.Values
select Activator.CreateInstance(pluginType) as IBaseWritableImage into plugin select Activator.CreateInstance(pluginType) as IBaseWritableImage
into plugin
where plugin is not null where plugin is not null
where plugin.KnownExtensions.Contains(Path.GetExtension(outputPath)) select plugin); where plugin.KnownExtensions.Contains(Path.GetExtension(outputPath))
select plugin);
}
// Try Id // Try Id
else if(Guid.TryParse(format, out Guid outId)) else if(Guid.TryParse(format, out Guid outId))
{
candidates.AddRange(from pluginType in plugins.WritableImages.Values candidates.AddRange(from pluginType in plugins.WritableImages.Values
select Activator.CreateInstance(pluginType) as IBaseWritableImage into plugin select Activator.CreateInstance(pluginType) as IBaseWritableImage
where plugin is not null where plugin.Id.Equals(outId) select plugin); into plugin
where plugin is not null
where plugin.Id.Equals(outId)
select plugin);
}
// Try name // Try name
else else
{
candidates.AddRange(from pluginType in plugins.WritableImages.Values candidates.AddRange(from pluginType in plugins.WritableImages.Values
select Activator.CreateInstance(pluginType) as IBaseWritableImage into plugin select Activator.CreateInstance(pluginType) as IBaseWritableImage
into plugin
where plugin is not null where plugin is not null
where plugin.Name.Equals(format, StringComparison.InvariantCultureIgnoreCase) where plugin.Name.Equals(format, StringComparison.InvariantCultureIgnoreCase)
select plugin); select plugin);
}
switch(candidates.Count) switch(candidates.Count)
{ {
@@ -618,7 +606,7 @@ sealed class ConvertImageCommand : Command
return (int)ErrorNumber.UnsupportedMedia; return (int)ErrorNumber.UnsupportedMedia;
} }
bool ret = false; var ret = false;
if(inputTape?.IsTape == true && if(inputTape?.IsTape == true &&
outputTape != null) outputTape != null)
@@ -665,13 +653,14 @@ sealed class ConvertImageCommand : Command
AaruConsole.ErrorWriteLine("Output format does not support sessions, this will end in a loss of data, continuing...");*/ AaruConsole.ErrorWriteLine("Output format does not support sessions, this will end in a loss of data, continuing...");*/
} }
bool created = false; var created = false;
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask(UI.Invoke_Opening_image_file).IsIndeterminate(); ctx.AddTask(UI.Invoke_Opening_image_file).IsIndeterminate();
created = outputFormat.Create(outputPath, mediaType, parsedOptions, inputFormat.Info.Sectors, created = outputFormat.Create(outputPath, mediaType, parsedOptions,
inputFormat.Info.Sectors,
inputFormat.Info.SectorSize); inputFormat.Info.SectorSize);
}); });
@@ -725,7 +714,8 @@ sealed class ConvertImageCommand : Command
AnsiConsole.Progress().AutoClear(false).HideCompleted(false). AnsiConsole.Progress().AutoClear(false).HideCompleted(false).
Columns(new TaskDescriptionColumn(), new SpinnerColumn()).Start(ctx => Columns(new TaskDescriptionColumn(), new SpinnerColumn()).Start(ctx =>
{ {
ctx.AddTask(string.Format(UI.Converting_media_tag_0, Markup.Escape(mediaTag.ToString()))); ctx.AddTask(string.Format(UI.Converting_media_tag_0,
Markup.Escape(mediaTag.ToString())));
ErrorNumber errno = inputFormat.ReadMediaTag(mediaTag, out byte[] tag); ErrorNumber errno = inputFormat.ReadMediaTag(mediaTag, out byte[] tag);
if(errno != ErrorNumber.NoError) if(errno != ErrorNumber.NoError)
@@ -734,7 +724,8 @@ sealed class ConvertImageCommand : Command
AaruConsole.ErrorWriteLine(UI.Error_0_reading_media_tag, errno); AaruConsole.ErrorWriteLine(UI.Error_0_reading_media_tag, errno);
else else
{ {
AaruConsole.ErrorWriteLine(UI.Error_0_reading_media_tag_not_continuing, errno); AaruConsole.ErrorWriteLine(UI.Error_0_reading_media_tag_not_continuing,
errno);
errorNumber = errno; errorNumber = errno;
} }
@@ -746,7 +737,8 @@ sealed class ConvertImageCommand : Command
return; return;
if(force) if(force)
AaruConsole.ErrorWriteLine(UI.Error_0_writing_media_tag, outputFormat.ErrorMessage); AaruConsole.ErrorWriteLine(UI.Error_0_writing_media_tag,
outputFormat.ErrorMessage);
else else
{ {
AaruConsole.ErrorWriteLine(UI.Error_0_writing_media_tag_not_continuing, AaruConsole.ErrorWriteLine(UI.Error_0_writing_media_tag_not_continuing,
@@ -812,35 +804,42 @@ sealed class ConvertImageCommand : Command
trackTask.Description = trackTask.Description =
string.Format(UI.Converting_sectors_0_to_1_in_track_2, string.Format(UI.Converting_sectors_0_to_1_in_track_2,
doneSectors + track.StartSector, doneSectors + track.StartSector,
doneSectors + sectorsToDo + track.StartSector, track.Sequence); doneSectors + sectorsToDo + track.StartSector,
track.Sequence);
bool useNotLong = false; var useNotLong = false;
bool result = false; var result = false;
if(useLong) if(useLong)
{ {
errno = sectorsToDo == 1 errno = sectorsToDo == 1
? inputOptical.ReadSectorLong(doneSectors + track.StartSector, ? inputOptical.ReadSectorLong(doneSectors + track.StartSector,
out sector) out sector)
: inputOptical.ReadSectorsLong(doneSectors + track.StartSector, : inputOptical.
ReadSectorsLong(doneSectors + track.StartSector,
sectorsToDo, out sector); sectorsToDo, out sector);
if(errno == ErrorNumber.NoError) if(errno == ErrorNumber.NoError)
{
result = sectorsToDo == 1 result = sectorsToDo == 1
? outputOptical.WriteSectorLong(sector, ? outputOptical.WriteSectorLong(sector,
doneSectors + track.StartSector) doneSectors + track.StartSector)
: outputOptical.WriteSectorsLong(sector, : outputOptical.WriteSectorsLong(sector,
doneSectors + track.StartSector, sectorsToDo); doneSectors + track.StartSector, sectorsToDo);
}
else else
{ {
result = true; result = true;
if(force) if(force)
{
AaruConsole.ErrorWriteLine(UI.Error_0_reading_sector_1_continuing, AaruConsole.ErrorWriteLine(UI.Error_0_reading_sector_1_continuing,
errno, doneSectors + track.StartSector); errno, doneSectors + track.StartSector);
}
else else
{ {
AaruConsole.ErrorWriteLine(UI.Error_0_reading_sector_1_not_continuing, AaruConsole.
ErrorWriteLine(UI.Error_0_reading_sector_1_not_continuing,
errno, doneSectors + track.StartSector); errno, doneSectors + track.StartSector);
errno = ErrorNumber.WriteError; errno = ErrorNumber.WriteError;
@@ -877,7 +876,8 @@ sealed class ConvertImageCommand : Command
// TODO: Move to generic place when anything but CSS DVDs can be decrypted // TODO: Move to generic place when anything but CSS DVDs can be decrypted
if(inputOptical.Info.MediaType is MediaType.DVDROM or MediaType.DVDR if(inputOptical.Info.MediaType is MediaType.DVDROM or MediaType.DVDR
or MediaType.DVDRDL or MediaType.DVDPR or MediaType.DVDPRDL && decrypt) or MediaType.DVDRDL or MediaType.DVDPR or MediaType.DVDPRDL &&
decrypt)
{ {
// Only sectors which are MPEG packets can be encrypted. // Only sectors which are MPEG packets can be encrypted.
if(MPEG.ContainsMpegPackets(sector, sectorsToDo)) if(MPEG.ContainsMpegPackets(sector, sectorsToDo))
@@ -887,9 +887,11 @@ sealed class ConvertImageCommand : Command
if(sectorsToDo == 1) if(sectorsToDo == 1)
{ {
if(inputOptical.ReadSectorTag(doneSectors + track.StartSector, if(inputOptical.ReadSectorTag(doneSectors + track.StartSector,
SectorTagType.DvdSectorCmi, out cmi) == ErrorNumber.NoError && SectorTagType.DvdSectorCmi, out cmi) ==
ErrorNumber.NoError &&
inputOptical.ReadSectorTag(doneSectors + track.StartSector, inputOptical.ReadSectorTag(doneSectors + track.StartSector,
SectorTagType.DvdTitleKeyDecrypted, out titleKey) == SectorTagType.DvdTitleKeyDecrypted,
out titleKey) ==
ErrorNumber.NoError) ErrorNumber.NoError)
sector = CSS.DecryptSector(sector, titleKey, cmi); sector = CSS.DecryptSector(sector, titleKey, cmi);
else else
@@ -901,10 +903,13 @@ sealed class ConvertImageCommand : Command
partitions = partitions.FindAll(p => partitions = partitions.FindAll(p =>
{ {
Core.Filesystems.Identify(inputOptical, Core.Filesystems.
out List<string> idPlugins, p); Identify(inputOptical,
out List<string>
idPlugins, p);
return idPlugins.Contains("iso9660 filesystem"); return idPlugins.
Contains("iso9660 filesystem");
}); });
if(plugins.ReadOnlyFilesystems. if(plugins.ReadOnlyFilesystems.
@@ -914,27 +919,40 @@ sealed class ConvertImageCommand : Command
AaruConsole.DebugWriteLine(MODULE_NAME, AaruConsole.DebugWriteLine(MODULE_NAME,
UI.Generating_decryption_keys); UI.Generating_decryption_keys);
generatedTitleKeys = CSS.GenerateTitleKeys(inputOptical, generatedTitleKeys =
partitions, trackSectors, pluginType); CSS.GenerateTitleKeys(inputOptical,
partitions, trackSectors,
pluginType);
} }
} }
if(generatedTitleKeys != null) if(generatedTitleKeys != null)
{
sector = CSS.DecryptSector(sector, sector = CSS.DecryptSector(sector,
generatedTitleKeys. generatedTitleKeys.
Skip((int)(5 * (doneSectors + track.StartSector))). Skip((int)(5 * (doneSectors +
track.
StartSector))).
Take(5).ToArray(), null); Take(5).ToArray(), null);
} }
} }
}
else else
{ {
if(inputOptical.ReadSectorsTag(doneSectors + track.StartSector, if(inputOptical.
sectorsToDo, SectorTagType.DvdSectorCmi, out cmi) == ReadSectorsTag(doneSectors + track.StartSector,
sectorsToDo,
SectorTagType.DvdSectorCmi,
out cmi) ==
ErrorNumber.NoError && ErrorNumber.NoError &&
inputOptical.ReadSectorsTag(doneSectors + track.StartSector, inputOptical.
sectorsToDo, SectorTagType.DvdTitleKeyDecrypted, ReadSectorsTag(doneSectors + track.StartSector,
out titleKey) == ErrorNumber.NoError) sectorsToDo,
sector = CSS.DecryptSector(sector, titleKey, cmi, sectorsToDo); SectorTagType.DvdTitleKeyDecrypted,
out titleKey) ==
ErrorNumber.NoError)
sector = CSS.DecryptSector(sector, titleKey, cmi,
sectorsToDo);
else else
{ {
if(generatedTitleKeys == null) if(generatedTitleKeys == null)
@@ -944,10 +962,13 @@ sealed class ConvertImageCommand : Command
partitions = partitions.FindAll(p => partitions = partitions.FindAll(p =>
{ {
Core.Filesystems.Identify(inputOptical, Core.Filesystems.
out List<string> idPlugins, p); Identify(inputOptical,
out List<string>
idPlugins, p);
return idPlugins.Contains("iso9660 filesystem"); return idPlugins.
Contains("iso9660 filesystem");
}); });
if(plugins.ReadOnlyFilesystems. if(plugins.ReadOnlyFilesystems.
@@ -957,38 +978,50 @@ sealed class ConvertImageCommand : Command
AaruConsole.DebugWriteLine(MODULE_NAME, AaruConsole.DebugWriteLine(MODULE_NAME,
UI.Generating_decryption_keys); UI.Generating_decryption_keys);
generatedTitleKeys = CSS.GenerateTitleKeys(inputOptical, generatedTitleKeys =
partitions, trackSectors, pluginType); CSS.GenerateTitleKeys(inputOptical,
partitions, trackSectors,
pluginType);
} }
} }
if(generatedTitleKeys != null) if(generatedTitleKeys != null)
{
sector = CSS.DecryptSector(sector, sector = CSS.DecryptSector(sector,
generatedTitleKeys. generatedTitleKeys.
Skip((int)(5 * (doneSectors + track.StartSector))). Skip((int)(5 * (doneSectors +
Take((int)(5 * sectorsToDo)).ToArray(), null, track.
StartSector))).
Take((int)(5 * sectorsToDo)).ToArray(),
null,
sectorsToDo); sectorsToDo);
} }
} }
} }
} }
}
if(errno == ErrorNumber.NoError) if(errno == ErrorNumber.NoError)
{
result = sectorsToDo == 1 result = sectorsToDo == 1
? outputOptical.WriteSector(sector, ? outputOptical.WriteSector(sector,
doneSectors + track.StartSector) doneSectors + track.StartSector)
: outputOptical.WriteSectors(sector, : outputOptical.WriteSectors(sector,
doneSectors + track.StartSector, sectorsToDo); doneSectors + track.StartSector, sectorsToDo);
}
else else
{ {
result = true; result = true;
if(force) if(force)
{
AaruConsole.ErrorWriteLine(UI.Error_0_reading_sector_1_continuing, AaruConsole.ErrorWriteLine(UI.Error_0_reading_sector_1_continuing,
errno, doneSectors + track.StartSector); errno, doneSectors + track.StartSector);
}
else else
{ {
AaruConsole.ErrorWriteLine(UI.Error_0_reading_sector_1_not_continuing, AaruConsole.
ErrorWriteLine(UI.Error_0_reading_sector_1_not_continuing,
errno, doneSectors + track.StartSector); errno, doneSectors + track.StartSector);
errno = ErrorNumber.WriteError; errno = ErrorNumber.WriteError;
@@ -999,10 +1032,13 @@ sealed class ConvertImageCommand : Command
} }
if(!result) if(!result)
{
if(force) if(force)
{
AaruConsole.ErrorWriteLine(UI.Error_0_writing_sector_1_continuing, AaruConsole.ErrorWriteLine(UI.Error_0_writing_sector_1_continuing,
outputOptical.ErrorMessage, outputOptical.ErrorMessage,
doneSectors + track.StartSector); doneSectors + track.StartSector);
}
else else
{ {
AaruConsole.ErrorWriteLine(UI.Error_0_writing_sector_1_not_continuing, AaruConsole.ErrorWriteLine(UI.Error_0_writing_sector_1_not_continuing,
@@ -1013,6 +1049,7 @@ sealed class ConvertImageCommand : Command
return; return;
} }
}
doneSectors += sectorsToDo; doneSectors += sectorsToDo;
trackTask.Value += sectorsToDo; trackTask.Value += sectorsToDo;
@@ -1031,9 +1068,9 @@ sealed class ConvertImageCommand : Command
string mcn = null; string mcn = null;
HashSet<int> subchannelExtents = new(); HashSet<int> subchannelExtents = new();
Dictionary<byte, int> smallestPregapLbaPerTrack = new(); Dictionary<byte, int> smallestPregapLbaPerTrack = new();
Track[] tracks = new Track[inputOptical.Tracks.Count]; var tracks = new Track[inputOptical.Tracks.Count];
for(int i = 0; i < tracks.Length; i++) for(var i = 0; i < tracks.Length; i++)
{ {
tracks[i] = new Track tracks[i] = new Track
{ {
@@ -1148,20 +1185,23 @@ sealed class ConvertImageCommand : Command
continue; continue;
case ErrorNumber.NoError: case ErrorNumber.NoError:
result = outputOptical.WriteSectorTag(sector, track.Sequence, tag); result = outputOptical.WriteSectorTag(sector, track.Sequence,
tag);
break; break;
default: default:
{ {
if(force) if(force)
{ {
AaruConsole.ErrorWriteLine(UI.Error_0_writing_tag_continuing, AaruConsole.
ErrorWriteLine(UI.Error_0_writing_tag_continuing,
outputOptical.ErrorMessage); outputOptical.ErrorMessage);
continue; continue;
} }
AaruConsole.ErrorWriteLine(UI.Error_0_writing_tag_not_continuing, AaruConsole.
ErrorWriteLine(UI.Error_0_writing_tag_not_continuing,
outputOptical.ErrorMessage); outputOptical.ErrorMessage);
errno = ErrorNumber.WriteError; errno = ErrorNumber.WriteError;
@@ -1171,18 +1211,23 @@ sealed class ConvertImageCommand : Command
} }
if(!result) if(!result)
{
if(force) if(force)
{
AaruConsole.ErrorWriteLine(UI.Error_0_writing_tag_continuing, AaruConsole.ErrorWriteLine(UI.Error_0_writing_tag_continuing,
outputOptical.ErrorMessage); outputOptical.ErrorMessage);
}
else else
{ {
AaruConsole.ErrorWriteLine(UI.Error_0_writing_tag_not_continuing, AaruConsole.
ErrorWriteLine(UI.Error_0_writing_tag_not_continuing,
outputOptical.ErrorMessage); outputOptical.ErrorMessage);
errno = ErrorNumber.WriteError; errno = ErrorNumber.WriteError;
return; return;
} }
}
continue; continue;
} }
@@ -1202,12 +1247,14 @@ sealed class ConvertImageCommand : Command
trackTask.Description = trackTask.Description =
string.Format(UI.Converting_tag_3_for_sectors_0_to_1_in_track_2, string.Format(UI.Converting_tag_3_for_sectors_0_to_1_in_track_2,
doneSectors + track.StartSector, doneSectors + track.StartSector,
doneSectors + sectorsToDo + track.StartSector, track.Sequence, doneSectors + sectorsToDo + track.StartSector,
track.Sequence,
tag); tag);
if(sectorsToDo == 1) if(sectorsToDo == 1)
{ {
errno = inputOptical.ReadSectorTag(doneSectors + track.StartSector, tag, errno = inputOptical.ReadSectorTag(doneSectors + track.StartSector,
tag,
out sector); out sector);
if(errno == ErrorNumber.NoError) if(errno == ErrorNumber.NoError)
@@ -1220,7 +1267,8 @@ sealed class ConvertImageCommand : Command
doneSectors + track.StartSector, 1, null, isrcs, doneSectors + track.StartSector, 1, null, isrcs,
(byte)track.Sequence, ref mcn, tracks, (byte)track.Sequence, ref mcn, tracks,
subchannelExtents, fixSubchannelPosition, subchannelExtents, fixSubchannelPosition,
outputOptical, fixSubchannel, fixSubchannelCrc, null, outputOptical, fixSubchannel, fixSubchannelCrc,
null,
null, smallestPregapLbaPerTrack, false, out _); null, smallestPregapLbaPerTrack, false, out _);
if(indexesChanged) if(indexesChanged)
@@ -1229,18 +1277,22 @@ sealed class ConvertImageCommand : Command
result = true; result = true;
} }
else else
{
result = result =
outputOptical.WriteSectorTag(sector, outputOptical.WriteSectorTag(sector,
doneSectors + track.StartSector, tag); doneSectors + track.StartSector, tag);
} }
}
else else
{ {
result = true; result = true;
if(force) if(force)
{
AaruConsole. AaruConsole.
ErrorWriteLine(UI.Error_0_reading_tag_for_sector_1_continuing, ErrorWriteLine(UI.Error_0_reading_tag_for_sector_1_continuing,
errno, doneSectors + track.StartSector); errno, doneSectors + track.StartSector);
}
else else
{ {
AaruConsole. AaruConsole.
@@ -1263,10 +1315,12 @@ sealed class ConvertImageCommand : Command
bool indexesChanged = bool indexesChanged =
CompactDisc.WriteSubchannelToImage(MmcSubchannel.Raw, CompactDisc.WriteSubchannelToImage(MmcSubchannel.Raw,
MmcSubchannel.Raw, sector, MmcSubchannel.Raw, sector,
doneSectors + track.StartSector, sectorsToDo, null, doneSectors + track.StartSector, sectorsToDo,
null,
isrcs, (byte)track.Sequence, ref mcn, tracks, isrcs, (byte)track.Sequence, ref mcn, tracks,
subchannelExtents, fixSubchannelPosition, subchannelExtents, fixSubchannelPosition,
outputOptical, fixSubchannel, fixSubchannelCrc, null, outputOptical, fixSubchannel, fixSubchannelCrc,
null,
null, smallestPregapLbaPerTrack, false, out _); null, smallestPregapLbaPerTrack, false, out _);
if(indexesChanged) if(indexesChanged)
@@ -1275,18 +1329,23 @@ sealed class ConvertImageCommand : Command
result = true; result = true;
} }
else else
{
result = result =
outputOptical.WriteSectorsTag(sector, outputOptical.WriteSectorsTag(sector,
doneSectors + track.StartSector, sectorsToDo, tag); doneSectors + track.StartSector, sectorsToDo,
tag);
}
} }
else else
{ {
result = true; result = true;
if(force) if(force)
{
AaruConsole. AaruConsole.
ErrorWriteLine(UI.Error_0_reading_tag_for_sector_1_continuing, ErrorWriteLine(UI.Error_0_reading_tag_for_sector_1_continuing,
errno, doneSectors + track.StartSector); errno, doneSectors + track.StartSector);
}
else else
{ {
AaruConsole. AaruConsole.
@@ -1299,11 +1358,14 @@ sealed class ConvertImageCommand : Command
} }
if(!result) if(!result)
{
if(force) if(force)
{
AaruConsole. AaruConsole.
ErrorWriteLine(UI.Error_0_writing_tag_for_sector_1_continuing, ErrorWriteLine(UI.Error_0_writing_tag_for_sector_1_continuing,
outputOptical.ErrorMessage, outputOptical.ErrorMessage,
doneSectors + track.StartSector); doneSectors + track.StartSector);
}
else else
{ {
AaruConsole. AaruConsole.
@@ -1315,6 +1377,7 @@ sealed class ConvertImageCommand : Command
return; return;
} }
}
doneSectors += sectorsToDo; doneSectors += sectorsToDo;
trackTask.Value += sectorsToDo; trackTask.Value += sectorsToDo;
@@ -1331,38 +1394,54 @@ sealed class ConvertImageCommand : Command
} }
if(isrcs.Count > 0) if(isrcs.Count > 0)
{
foreach(KeyValuePair<byte, string> isrc in isrcs) foreach(KeyValuePair<byte, string> isrc in isrcs)
{
outputOptical.WriteSectorTag(Encoding.UTF8.GetBytes(isrc.Value), isrc.Key, outputOptical.WriteSectorTag(Encoding.UTF8.GetBytes(isrc.Value), isrc.Key,
SectorTagType.CdTrackIsrc); SectorTagType.CdTrackIsrc);
}
}
if(trackFlags.Count > 0) if(trackFlags.Count > 0)
foreach((byte track, byte flags) in trackFlags)
outputOptical.WriteSectorTag(new[]
{ {
flags foreach((byte track, byte flags) in trackFlags)
}, track, SectorTagType.CdTrackFlags); {
outputOptical.WriteSectorTag(new[] { flags }, track, SectorTagType.CdTrackFlags);
}
}
if(mcn != null) if(mcn != null)
outputOptical.WriteMediaTag(Encoding.UTF8.GetBytes(mcn), MediaTagType.CD_MCN); outputOptical.WriteMediaTag(Encoding.UTF8.GetBytes(mcn), MediaTagType.CD_MCN);
// TODO: Progress // TODO: Progress
if(inputOptical.Info.MediaType is MediaType.CD or MediaType.CDDA or MediaType.CDG or MediaType.CDEG if(inputOptical.Info.MediaType is MediaType.CD or MediaType.CDDA or MediaType.CDG or MediaType.CDEG
or MediaType.CDI or MediaType.CDROM or MediaType.CDROMXA or MediaType.CDPLUS or MediaType.CDMO or MediaType.CDI or MediaType.CDROM or MediaType.CDROMXA or MediaType.CDPLUS
or MediaType.CDR or MediaType.CDRW or MediaType.CDMRW or MediaType.VCD or MediaType.SVCD or MediaType.CDMO
or MediaType.PCD or MediaType.DTSCD or MediaType.CDMIDI or MediaType.CDV or MediaType.CDIREADY or MediaType.CDR or MediaType.CDRW or MediaType.CDMRW or MediaType.VCD
or MediaType.FMTOWNS or MediaType.PS1CD or MediaType.PS2CD or MediaType.MEGACD or MediaType.SATURNCD or MediaType.SVCD
or MediaType.GDROM or MediaType.GDR or MediaType.MilCD or MediaType.SuperCDROM2 or MediaType.JaguarCD or MediaType.PCD or MediaType.DTSCD or MediaType.CDMIDI or MediaType.CDV
or MediaType.ThreeDO or MediaType.PCFX or MediaType.NeoGeoCD or MediaType.CDTV or MediaType.CD32 or MediaType.CDIREADY
or MediaType.Playdia or MediaType.Pippin or MediaType.VideoNow or MediaType.VideoNowColor or MediaType.FMTOWNS or MediaType.PS1CD or MediaType.PS2CD
or MediaType.MEGACD or MediaType.SATURNCD
or MediaType.GDROM or MediaType.GDR or MediaType.MilCD
or MediaType.SuperCDROM2 or MediaType.JaguarCD
or MediaType.ThreeDO or MediaType.PCFX or MediaType.NeoGeoCD
or MediaType.CDTV or MediaType.CD32
or MediaType.Playdia or MediaType.Pippin or MediaType.VideoNow
or MediaType.VideoNowColor
or MediaType.VideoNowXp or MediaType.CVD && generateSubchannels) or MediaType.VideoNowXp or MediaType.CVD && generateSubchannels)
{
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask(Localization.Core.Generating_subchannels).IsIndeterminate(); ctx.AddTask(Localization.Core.Generating_subchannels).
IsIndeterminate();
CompactDisc.GenerateSubchannels(subchannelExtents, tracks, trackFlags, inputOptical.Info.Sectors, CompactDisc.GenerateSubchannels(subchannelExtents, tracks,
trackFlags, inputOptical.Info.Sectors,
null, null, null, null, null, outputOptical); null, null, null, null, null, outputOptical);
}); });
} }
}
else else
{ {
var outputMedia = outputFormat as IWritableImage; var outputMedia = outputFormat as IWritableImage;
@@ -1380,9 +1459,11 @@ sealed class ConvertImageCommand : Command
chs.heads, chs.sectors); chs.heads, chs.sectors);
if(!outputMedia.SetGeometry(chs.cylinders, chs.heads, chs.sectors)) if(!outputMedia.SetGeometry(chs.cylinders, chs.heads, chs.sectors))
{
AaruConsole.ErrorWriteLine(UI.Error_0_setting_geometry_image_may_be_incorrect_continuing, AaruConsole.ErrorWriteLine(UI.Error_0_setting_geometry_image_may_be_incorrect_continuing,
outputMedia.ErrorMessage); outputMedia.ErrorMessage);
} }
}
ErrorNumber errno = ErrorNumber.NoError; ErrorNumber errno = ErrorNumber.NoError;
@@ -1407,25 +1488,35 @@ sealed class ConvertImageCommand : Command
sectorsToDo = (uint)(inputFormat.Info.Sectors - doneSectors); sectorsToDo = (uint)(inputFormat.Info.Sectors - doneSectors);
mediaTask.Description = mediaTask.Description =
string.Format(UI.Converting_sectors_0_to_1, doneSectors, doneSectors + sectorsToDo); string.Format(UI.Converting_sectors_0_to_1, doneSectors,
doneSectors + sectorsToDo);
bool result; bool result;
if(useLong) if(useLong)
{ {
errno = sectorsToDo == 1 ? inputFormat.ReadSectorLong(doneSectors, out sector) errno = sectorsToDo == 1
: inputFormat.ReadSectorsLong(doneSectors, sectorsToDo, out sector); ? inputFormat.ReadSectorLong(doneSectors, out sector)
: inputFormat.ReadSectorsLong(doneSectors, sectorsToDo,
out sector);
if(errno == ErrorNumber.NoError) if(errno == ErrorNumber.NoError)
result = sectorsToDo == 1 ? outputMedia.WriteSectorLong(sector, doneSectors) {
: outputMedia.WriteSectorsLong(sector, doneSectors, sectorsToDo); result = sectorsToDo == 1
? outputMedia.WriteSectorLong(sector, doneSectors)
: outputMedia.WriteSectorsLong(sector, doneSectors,
sectorsToDo);
}
else else
{ {
result = true; result = true;
if(force) if(force)
AaruConsole.ErrorWriteLine(UI.Error_0_reading_sector_1_continuing, errno, {
AaruConsole.ErrorWriteLine(UI.Error_0_reading_sector_1_continuing,
errno,
doneSectors); doneSectors);
}
else else
{ {
AaruConsole.ErrorWriteLine(UI.Error_0_reading_sector_1_not_continuing, AaruConsole.ErrorWriteLine(UI.Error_0_reading_sector_1_not_continuing,
@@ -1437,19 +1528,26 @@ sealed class ConvertImageCommand : Command
} }
else else
{ {
errno = sectorsToDo == 1 ? inputFormat.ReadSector(doneSectors, out sector) errno = sectorsToDo == 1
? inputFormat.ReadSector(doneSectors, out sector)
: inputFormat.ReadSectors(doneSectors, sectorsToDo, out sector); : inputFormat.ReadSectors(doneSectors, sectorsToDo, out sector);
if(errno == ErrorNumber.NoError) if(errno == ErrorNumber.NoError)
result = sectorsToDo == 1 ? outputMedia.WriteSector(sector, doneSectors) {
result = sectorsToDo == 1
? outputMedia.WriteSector(sector, doneSectors)
: outputMedia.WriteSectors(sector, doneSectors, sectorsToDo); : outputMedia.WriteSectors(sector, doneSectors, sectorsToDo);
}
else else
{ {
result = true; result = true;
if(force) if(force)
AaruConsole.ErrorWriteLine(UI.Error_0_reading_sector_1_continuing, errno, {
AaruConsole.ErrorWriteLine(UI.Error_0_reading_sector_1_continuing,
errno,
doneSectors); doneSectors);
}
else else
{ {
AaruConsole.ErrorWriteLine(UI.Error_0_reading_sector_1_not_continuing, AaruConsole.ErrorWriteLine(UI.Error_0_reading_sector_1_not_continuing,
@@ -1461,9 +1559,12 @@ sealed class ConvertImageCommand : Command
} }
if(!result) if(!result)
{
if(force) if(force)
{
AaruConsole.ErrorWriteLine(UI.Error_0_writing_sector_1_continuing, AaruConsole.ErrorWriteLine(UI.Error_0_writing_sector_1_continuing,
outputMedia.ErrorMessage, doneSectors); outputMedia.ErrorMessage, doneSectors);
}
else else
{ {
AaruConsole.ErrorWriteLine(UI.Error_0_writing_sector_1_not_continuing, AaruConsole.ErrorWriteLine(UI.Error_0_writing_sector_1_not_continuing,
@@ -1473,6 +1574,7 @@ sealed class ConvertImageCommand : Command
return; return;
} }
}
doneSectors += sectorsToDo; doneSectors += sectorsToDo;
mediaTask.Value += sectorsToDo; mediaTask.Value += sectorsToDo;
@@ -1480,7 +1582,8 @@ sealed class ConvertImageCommand : Command
mediaTask.StopTask(); mediaTask.StopTask();
foreach(SectorTagType tag in inputFormat.Info.ReadableSectorTags.TakeWhile(_ => useLong)) foreach(SectorTagType tag in
inputFormat.Info.ReadableSectorTags.TakeWhile(_ => useLong))
{ {
switch(tag) switch(tag)
{ {
@@ -1521,19 +1624,27 @@ sealed class ConvertImageCommand : Command
errno = sectorsToDo == 1 errno = sectorsToDo == 1
? inputFormat.ReadSectorTag(doneSectors, tag, out byte[] sector) ? inputFormat.ReadSectorTag(doneSectors, tag, out byte[] sector)
: inputFormat.ReadSectorsTag(doneSectors, sectorsToDo, tag, out sector); : inputFormat.ReadSectorsTag(doneSectors, sectorsToDo, tag,
out sector);
if(errno == ErrorNumber.NoError) if(errno == ErrorNumber.NoError)
result = sectorsToDo == 1 ? outputMedia.WriteSectorTag(sector, doneSectors, tag) {
: outputMedia.WriteSectorsTag(sector, doneSectors, sectorsToDo, result = sectorsToDo == 1
? outputMedia.WriteSectorTag(sector, doneSectors, tag)
: outputMedia.WriteSectorsTag(sector, doneSectors,
sectorsToDo,
tag); tag);
}
else else
{ {
result = true; result = true;
if(force) if(force)
AaruConsole.ErrorWriteLine(UI.Error_0_reading_sector_1_continuing, errno, {
AaruConsole.ErrorWriteLine(UI.Error_0_reading_sector_1_continuing,
errno,
doneSectors); doneSectors);
}
else else
{ {
AaruConsole.ErrorWriteLine(UI.Error_0_reading_sector_1_not_continuing, AaruConsole.ErrorWriteLine(UI.Error_0_reading_sector_1_not_continuing,
@@ -1544,9 +1655,12 @@ sealed class ConvertImageCommand : Command
} }
if(!result) if(!result)
{
if(force) if(force)
{
AaruConsole.ErrorWriteLine(UI.Error_0_writing_sector_1_continuing, AaruConsole.ErrorWriteLine(UI.Error_0_writing_sector_1_continuing,
outputMedia.ErrorMessage, doneSectors); outputMedia.ErrorMessage, doneSectors);
}
else else
{ {
AaruConsole.ErrorWriteLine(UI.Error_0_writing_sector_1_not_continuing, AaruConsole.ErrorWriteLine(UI.Error_0_writing_sector_1_not_continuing,
@@ -1556,6 +1670,7 @@ sealed class ConvertImageCommand : Command
return; return;
} }
}
doneSectors += sectorsToDo; doneSectors += sectorsToDo;
tagsTask.Value += sectorsToDo; tagsTask.Value += sectorsToDo;
@@ -1571,7 +1686,8 @@ sealed class ConvertImageCommand : Command
{ {
for(uint head = 0; head < inputFlux.Info.Heads; head++) for(uint head = 0; head < inputFlux.Info.Heads; head++)
{ {
ErrorNumber error = inputFlux.SubTrackLength(head, track, out byte subTrackLen); ErrorNumber error =
inputFlux.SubTrackLength(head, track, out byte subTrackLen);
if(error != ErrorNumber.NoError) if(error != ErrorNumber.NoError)
continue; continue;
@@ -1586,7 +1702,8 @@ sealed class ConvertImageCommand : Command
for(uint captureIndex = 0; captureIndex < capturesLen; captureIndex++) for(uint captureIndex = 0; captureIndex < capturesLen; captureIndex++)
{ {
inputFlux.ReadFluxCapture(head, track, subTrackIndex, captureIndex, inputFlux.ReadFluxCapture(head, track, subTrackIndex,
captureIndex,
out ulong indexResolution, out ulong indexResolution,
out ulong dataResolution, out ulong dataResolution,
out byte[] indexBuffer, out byte[] indexBuffer,
@@ -1675,7 +1792,7 @@ sealed class ConvertImageCommand : Command
AaruConsole.WriteLine(UI.Written_Aaru_Metadata_to_output_image); AaruConsole.WriteLine(UI.Written_Aaru_Metadata_to_output_image);
} }
bool closed = false; var closed = false;
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {

View File

@@ -31,7 +31,6 @@
// ****************************************************************************/ // ****************************************************************************/
using System; using System;
using System.Collections.Generic;
using System.CommandLine; using System.CommandLine;
using System.CommandLine.NamingConventionBinder; using System.CommandLine.NamingConventionBinder;
using System.IO; using System.IO;
@@ -60,20 +59,11 @@ sealed class CreateSidecarCommand : Command
public CreateSidecarCommand() : base("create-sidecar", UI.Image_Create_Sidecar_Command_Description) public CreateSidecarCommand() : base("create-sidecar", UI.Image_Create_Sidecar_Command_Description)
{ {
Add(new Option<int>(new[] Add(new Option<int>(new[] { "--block-size", "-b" }, () => 512, UI.Tape_block_size_argument_help));
{
"--block-size", "-b"
}, () => 512, UI.Tape_block_size_argument_help));
Add(new Option<string>(new[] Add(new Option<string>(new[] { "--encoding", "-e" }, () => null, UI.Name_of_character_encoding_to_use));
{
"--encoding", "-e"
}, () => null, UI.Name_of_character_encoding_to_use));
Add(new Option<bool>(new[] Add(new Option<bool>(new[] { "--tape", "-t" }, () => false, UI.Tape_argument_input_help));
{
"--tape", "-t"
}, () => false, UI.Tape_argument_input_help));
AddArgument(new Argument<string> AddArgument(new Argument<string>
{ {
@@ -107,6 +97,7 @@ sealed class CreateSidecarCommand : Command
} }
if(verbose) if(verbose)
{
AaruConsole.WriteEvent += (format, objects) => AaruConsole.WriteEvent += (format, objects) =>
{ {
if(objects is null) if(objects is null)
@@ -114,6 +105,7 @@ sealed class CreateSidecarCommand : Command
else else
AnsiConsole.Markup(format, objects); AnsiConsole.Markup(format, objects);
}; };
}
Statistics.AddCommand("create-sidecar"); Statistics.AddCommand("create-sidecar");
@@ -127,6 +119,7 @@ sealed class CreateSidecarCommand : Command
Encoding encodingClass = null; Encoding encodingClass = null;
if(encodingName != null) if(encodingName != null)
{
try try
{ {
encodingClass = Claunia.Encoding.Encoding.GetEncoding(encodingName); encodingClass = Claunia.Encoding.Encoding.GetEncoding(encodingName);
@@ -140,6 +133,7 @@ sealed class CreateSidecarCommand : Command
return (int)ErrorNumber.EncodingUnknown; return (int)ErrorNumber.EncodingUnknown;
} }
}
if(File.Exists(imagePath)) if(File.Exists(imagePath))
{ {
@@ -238,16 +232,20 @@ sealed class CreateSidecarCommand : Command
sidecarClass.UpdateProgressEvent += (text, current, maximum) => sidecarClass.UpdateProgressEvent += (text, current, maximum) =>
{ {
_progressTask1 ??= ctx.AddTask("Progress"); _progressTask1 ??=
_progressTask1.Description = Markup.Escape(text); ctx.AddTask("Progress");
_progressTask1.Description =
Markup.Escape(text);
_progressTask1.Value = current; _progressTask1.Value = current;
_progressTask1.MaxValue = maximum; _progressTask1.MaxValue = maximum;
}; };
sidecarClass.UpdateProgressEvent2 += (text, current, maximum) => sidecarClass.UpdateProgressEvent2 += (text, current, maximum) =>
{ {
_progressTask2 ??= ctx.AddTask("Progress"); _progressTask2 ??=
_progressTask2.Description = Markup.Escape(text); ctx.AddTask("Progress");
_progressTask2.Description =
Markup.Escape(text);
_progressTask2.Value = current; _progressTask2.Value = current;
_progressTask2.MaxValue = maximum; _progressTask2.MaxValue = maximum;
}; };
@@ -280,7 +278,8 @@ sealed class CreateSidecarCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask(Localization.Core.Writing_metadata_sidecar).IsIndeterminate(); ctx.AddTask(Localization.Core.Writing_metadata_sidecar).
IsIndeterminate();
var jsonFs = var jsonFs =
new new
@@ -313,7 +312,7 @@ sealed class CreateSidecarCommand : Command
} }
string[] contents = Directory.GetFiles(imagePath, "*", SearchOption.TopDirectoryOnly); string[] contents = Directory.GetFiles(imagePath, "*", SearchOption.TopDirectoryOnly);
List<string> files = contents.Where(file => new FileInfo(file).Length % blockSize == 0).ToList(); var files = contents.Where(file => new FileInfo(file).Length % blockSize == 0).ToList();
files.Sort(StringComparer.CurrentCultureIgnoreCase); files.Sort(StringComparer.CurrentCultureIgnoreCase);
@@ -324,10 +323,7 @@ sealed class CreateSidecarCommand : Command
Columns(new TaskDescriptionColumn(), new ProgressBarColumn(), new PercentageColumn()). Columns(new TaskDescriptionColumn(), new ProgressBarColumn(), new PercentageColumn()).
Start(ctx => Start(ctx =>
{ {
sidecarClass.InitProgressEvent += () => sidecarClass.InitProgressEvent += () => { _progressTask1 = ctx.AddTask("Progress"); };
{
_progressTask1 = ctx.AddTask("Progress");
};
sidecarClass.InitProgressEvent2 += () => sidecarClass.InitProgressEvent2 += () =>
{ {
@@ -337,7 +333,8 @@ sealed class CreateSidecarCommand : Command
sidecarClass.UpdateProgressEvent += (text, current, maximum) => sidecarClass.UpdateProgressEvent += (text, current, maximum) =>
{ {
_progressTask1 ??= ctx.AddTask("Progress"); _progressTask1 ??= ctx.AddTask("Progress");
_progressTask1.Description = Markup.Escape(text); _progressTask1.Description =
Markup.Escape(text);
_progressTask1.Value = current; _progressTask1.Value = current;
_progressTask1.MaxValue = maximum; _progressTask1.MaxValue = maximum;
}; };
@@ -345,7 +342,8 @@ sealed class CreateSidecarCommand : Command
sidecarClass.UpdateProgressEvent2 += (text, current, maximum) => sidecarClass.UpdateProgressEvent2 += (text, current, maximum) =>
{ {
_progressTask2 ??= ctx.AddTask("Progress"); _progressTask2 ??= ctx.AddTask("Progress");
_progressTask2.Description = Markup.Escape(text); _progressTask2.Description =
Markup.Escape(text);
_progressTask2.Value = current; _progressTask2.Value = current;
_progressTask2.MaxValue = maximum; _progressTask2.MaxValue = maximum;
}; };
@@ -378,7 +376,8 @@ sealed class CreateSidecarCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask(Localization.Core.Writing_metadata_sidecar).IsIndeterminate(); ctx.AddTask(Localization.Core.Writing_metadata_sidecar).
IsIndeterminate();
var jsonFs = var jsonFs =
new new

View File

@@ -52,25 +52,14 @@ sealed class DecodeCommand : Command
public DecodeCommand() : base("decode", UI.Image_Decode_Command_Description) public DecodeCommand() : base("decode", UI.Image_Decode_Command_Description)
{ {
Add(new Option<bool>(new[] Add(new Option<bool>(new[] { "--disk-tags", "-f" }, () => true, UI.Decode_media_tags));
{
"--disk-tags", "-f"
}, () => true, UI.Decode_media_tags));
Add(new Option<string>(new[] Add(new Option<string>(new[] { "--length", "-l" }, () => UI.Parameter_response_all_sectors,
{ UI.How_many_sectors_to_decode_or_all));
"--length", "-l"
}, () => UI.Parameter_response_all_sectors, UI.How_many_sectors_to_decode_or_all));
Add(new Option<bool>(new[] Add(new Option<bool>(new[] { "--sector-tags", "-p" }, () => true, UI.Decode_sector_tags));
{
"--sector-tags", "-p"
}, () => true, UI.Decode_sector_tags));
Add(new Option<ulong>(new[] Add(new Option<ulong>(new[] { "--start", "-s" }, () => 0, UI.Sector_to_start_decoding_from));
{
"--start", "-s"
}, () => 0, UI.Sector_to_start_decoding_from));
AddArgument(new Argument<string> AddArgument(new Argument<string>
{ {
@@ -104,6 +93,7 @@ sealed class DecodeCommand : Command
} }
if(verbose) if(verbose)
{
AaruConsole.WriteEvent += (format, objects) => AaruConsole.WriteEvent += (format, objects) =>
{ {
if(objects is null) if(objects is null)
@@ -111,6 +101,7 @@ sealed class DecodeCommand : Command
else else
AnsiConsole.Markup(format, objects); AnsiConsole.Markup(format, objects);
}; };
}
Statistics.AddCommand("decode"); Statistics.AddCommand("decode");
@@ -184,10 +175,13 @@ sealed class DecodeCommand : Command
ErrorNumber errno; ErrorNumber errno;
if(diskTags) if(diskTags)
{
if(inputFormat.Info.ReadableMediaTags.Count == 0) if(inputFormat.Info.ReadableMediaTags.Count == 0)
AaruConsole.WriteLine(UI.There_are_no_media_tags_in_chosen_disc_image); AaruConsole.WriteLine(UI.There_are_no_media_tags_in_chosen_disc_image);
else else
{
foreach(MediaTagType tag in inputFormat.Info.ReadableMediaTags) foreach(MediaTagType tag in inputFormat.Info.ReadableMediaTags)
{
switch(tag) switch(tag)
{ {
case MediaTagType.SCSI_INQUIRY: case MediaTagType.SCSI_INQUIRY:
@@ -216,8 +210,10 @@ sealed class DecodeCommand : Command
errno = inputFormat.ReadMediaTag(MediaTagType.ATA_IDENTIFY, out byte[] identify); errno = inputFormat.ReadMediaTag(MediaTagType.ATA_IDENTIFY, out byte[] identify);
if(errno != ErrorNumber.NoError) if(errno != ErrorNumber.NoError)
{
AaruConsole.WriteLine(UI.Error_0_reading_ATA_IDENTIFY_DEVICE_response_from_disc_image, AaruConsole.WriteLine(UI.Error_0_reading_ATA_IDENTIFY_DEVICE_response_from_disc_image,
errno); errno);
}
else else
{ {
AaruConsole.WriteLine($"[bold]{UI.ATA_IDENTIFY_DEVICE_command_response}[/]"); AaruConsole.WriteLine($"[bold]{UI.ATA_IDENTIFY_DEVICE_command_response}[/]");
@@ -238,9 +234,11 @@ sealed class DecodeCommand : Command
errno = inputFormat.ReadMediaTag(MediaTagType.ATAPI_IDENTIFY, out byte[] identify); errno = inputFormat.ReadMediaTag(MediaTagType.ATAPI_IDENTIFY, out byte[] identify);
if(identify == null) if(identify == null)
{
AaruConsole. AaruConsole.
WriteLine(UI.Error_0_reading_ATA_IDENTIFY_PACKET_DEVICE_response_from_disc_image, WriteLine(UI.Error_0_reading_ATA_IDENTIFY_PACKET_DEVICE_response_from_disc_image,
errno); errno);
}
else else
{ {
AaruConsole.WriteLine($"[bold]{UI.ATA_IDENTIFY_PACKET_DEVICE_command_response}[/]"); AaruConsole.WriteLine($"[bold]{UI.ATA_IDENTIFY_PACKET_DEVICE_command_response}[/]");
@@ -388,6 +386,9 @@ sealed class DecodeCommand : Command
break; break;
} }
}
}
}
if(!sectorTags) if(!sectorTags)
return (int)ErrorNumber.NoError; return (int)ErrorNumber.NoError;
@@ -407,7 +408,9 @@ sealed class DecodeCommand : Command
if(inputFormat.Info.ReadableSectorTags.Count == 0) if(inputFormat.Info.ReadableSectorTags.Count == 0)
AaruConsole.WriteLine(UI.There_are_no_sector_tags_in_chosen_disc_image); AaruConsole.WriteLine(UI.There_are_no_sector_tags_in_chosen_disc_image);
else else
{
foreach(SectorTagType tag in inputFormat.Info.ReadableSectorTags) foreach(SectorTagType tag in inputFormat.Info.ReadableSectorTags)
{
switch(tag) switch(tag)
{ {
default: default:
@@ -415,6 +418,8 @@ sealed class DecodeCommand : Command
break; break;
} }
}
}
// TODO: Not implemented // TODO: Not implemented

View File

@@ -50,20 +50,13 @@ sealed class EntropyCommand : Command
public EntropyCommand() : base("entropy", UI.Image_Entropy_Command_Description) public EntropyCommand() : base("entropy", UI.Image_Entropy_Command_Description)
{ {
Add(new Option<bool>(new[] Add(new Option<bool>(new[] { "--duplicated-sectors", "-p" }, () => true,
{ UI.Calculates_how_many_sectors_are_duplicated));
"--duplicated-sectors", "-p"
}, () => true, UI.Calculates_how_many_sectors_are_duplicated));
Add(new Option<bool>(new[] Add(new Option<bool>(new[] { "--separated-tracks", "-t" }, () => true,
{ UI.Calculates_entropy_for_each_track_separately));
"--separated-tracks", "-t"
}, () => true, UI.Calculates_entropy_for_each_track_separately));
Add(new Option<bool>(new[] Add(new Option<bool>(new[] { "--whole-disc", "-w" }, () => true, UI.Calculates_entropy_for_the_whole_disc));
{
"--whole-disc", "-w"
}, () => true, UI.Calculates_entropy_for_the_whole_disc));
AddArgument(new Argument<string> AddArgument(new Argument<string>
{ {
@@ -97,6 +90,7 @@ sealed class EntropyCommand : Command
} }
if(verbose) if(verbose)
{
AaruConsole.WriteEvent += (format, objects) => AaruConsole.WriteEvent += (format, objects) =>
{ {
if(objects is null) if(objects is null)
@@ -104,6 +98,7 @@ sealed class EntropyCommand : Command
else else
AnsiConsole.Markup(format, objects); AnsiConsole.Markup(format, objects);
}; };
}
Statistics.AddCommand("entropy"); Statistics.AddCommand("entropy");
@@ -172,26 +167,32 @@ sealed class EntropyCommand : Command
{ {
entropyCalculator.InitProgressEvent += () => entropyCalculator.InitProgressEvent += () =>
{ {
_progressTask1 = ctx.AddTask("Progress"); _progressTask1 =
ctx.AddTask("Progress");
}; };
entropyCalculator.InitProgress2Event += () => entropyCalculator.InitProgress2Event += () =>
{ {
_progressTask2 = ctx.AddTask("Progress"); _progressTask2 =
ctx.AddTask("Progress");
}; };
entropyCalculator.UpdateProgressEvent += (text, current, maximum) => entropyCalculator.UpdateProgressEvent += (text, current, maximum) =>
{ {
_progressTask1 ??= ctx.AddTask("Progress"); _progressTask1 ??=
_progressTask1.Description = Markup.Escape(text); ctx.AddTask("Progress");
_progressTask1.Description =
Markup.Escape(text);
_progressTask1.Value = current; _progressTask1.Value = current;
_progressTask1.MaxValue = maximum; _progressTask1.MaxValue = maximum;
}; };
entropyCalculator.UpdateProgress2Event += (text, current, maximum) => entropyCalculator.UpdateProgress2Event += (text, current, maximum) =>
{ {
_progressTask2 ??= ctx.AddTask("Progress"); _progressTask2 ??=
_progressTask2.Description = Markup.Escape(text); ctx.AddTask("Progress");
_progressTask2.Description =
Markup.Escape(text);
_progressTask2.Value = current; _progressTask2.Value = current;
_progressTask2.MaxValue = maximum; _progressTask2.MaxValue = maximum;
}; };
@@ -233,24 +234,31 @@ sealed class EntropyCommand : Command
trackEntropy.Entropy); trackEntropy.Entropy);
if(trackEntropy.UniqueSectors != null) if(trackEntropy.UniqueSectors != null)
AaruConsole.WriteLine(UI.Track_0_has_1_unique_sectors_2, trackEntropy.Track, {
AaruConsole.WriteLine(UI.Track_0_has_1_unique_sectors_2,
trackEntropy.Track,
trackEntropy.UniqueSectors, trackEntropy.UniqueSectors,
(double)trackEntropy.UniqueSectors / trackEntropy.Sectors); (double)trackEntropy.UniqueSectors /
trackEntropy.Sectors);
}
} }
} }
if(!wholeDisc) if(!wholeDisc)
return; return;
EntropyResults entropy = inputFormat.Info.MetadataMediaType == MetadataMediaType.LinearMedia EntropyResults entropy =
inputFormat.Info.MetadataMediaType == MetadataMediaType.LinearMedia
? entropyCalculator.CalculateLinearMediaEntropy() ? entropyCalculator.CalculateLinearMediaEntropy()
: entropyCalculator.CalculateMediaEntropy(duplicatedSectors); : entropyCalculator.CalculateMediaEntropy(duplicatedSectors);
AaruConsole.WriteLine(UI.Entropy_for_disk_is_0, entropy.Entropy); AaruConsole.WriteLine(UI.Entropy_for_disk_is_0, entropy.Entropy);
if(entropy.UniqueSectors != null) if(entropy.UniqueSectors != null)
{
AaruConsole.WriteLine(UI.Disk_has_0_unique_sectors_1, entropy.UniqueSectors, AaruConsole.WriteLine(UI.Disk_has_0_unique_sectors_1, entropy.UniqueSectors,
(double)entropy.UniqueSectors / entropy.Sectors); (double)entropy.UniqueSectors / entropy.Sectors);
}
}); });
return (int)ErrorNumber.NoError; return (int)ErrorNumber.NoError;

View File

@@ -80,6 +80,7 @@ sealed class ImageInfoCommand : Command
} }
if(verbose) if(verbose)
{
AaruConsole.WriteEvent += (format, objects) => AaruConsole.WriteEvent += (format, objects) =>
{ {
if(objects is null) if(objects is null)
@@ -87,6 +88,7 @@ sealed class ImageInfoCommand : Command
else else
AnsiConsole.Markup(format, objects); AnsiConsole.Markup(format, objects);
}; };
}
Statistics.AddCommand("image-info"); Statistics.AddCommand("image-info");

View File

@@ -73,6 +73,7 @@ sealed class ListOptionsCommand : Command
} }
if(verbose) if(verbose)
{
AaruConsole.WriteEvent += (format, objects) => AaruConsole.WriteEvent += (format, objects) =>
{ {
if(objects is null) if(objects is null)
@@ -80,6 +81,7 @@ sealed class ListOptionsCommand : Command
else else
AnsiConsole.Markup(format, objects); AnsiConsole.Markup(format, objects);
}; };
}
AaruConsole.DebugWriteLine(MODULE_NAME, "--debug={0}", debug); AaruConsole.DebugWriteLine(MODULE_NAME, "--debug={0}", debug);
AaruConsole.DebugWriteLine(MODULE_NAME, "--verbose={0}", verbose); AaruConsole.DebugWriteLine(MODULE_NAME, "--verbose={0}", verbose);
@@ -94,7 +96,7 @@ sealed class ListOptionsCommand : Command
if(Activator.CreateInstance(kvp.Value) is not IBaseWritableImage plugin) if(Activator.CreateInstance(kvp.Value) is not IBaseWritableImage plugin)
continue; continue;
List<(string name, Type type, string description, object @default)> options = var options =
plugin.SupportedOptions.ToList(); plugin.SupportedOptions.ToList();
if(options.Count == 0) if(options.Count == 0)
@@ -112,8 +114,10 @@ sealed class ListOptionsCommand : Command
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))
{
table.AddRow(Markup.Escape(option.name), TypeToString(option.type), option.@default?.ToString() ?? "", table.AddRow(Markup.Escape(option.name), TypeToString(option.type), option.@default?.ToString() ?? "",
Markup.Escape(option.description)); Markup.Escape(option.description));
}
AnsiConsole.Write(table); AnsiConsole.Write(table);
AaruConsole.WriteLine(); AaruConsole.WriteLine();

View File

@@ -50,25 +50,13 @@ sealed class PrintHexCommand : Command
public PrintHexCommand() : base("print", UI.Image_Print_Command_Description) public PrintHexCommand() : base("print", UI.Image_Print_Command_Description)
{ {
Add(new Option<ulong>(new[] Add(new Option<ulong>(new[] { "--length", "-l" }, () => 1, UI.How_many_sectors_to_print));
{
"--length", "-l"
}, () => 1, UI.How_many_sectors_to_print));
Add(new Option<bool>(new[] Add(new Option<bool>(new[] { "--long-sectors", "-r" }, () => false, UI.Print_sectors_with_tags_included));
{
"--long-sectors", "-r"
}, () => false, UI.Print_sectors_with_tags_included));
Add(new Option<ulong>(new[] Add(new Option<ulong>(new[] { "--start", "-s" }, UI.Starting_sector));
{
"--start", "-s"
}, UI.Starting_sector));
Add(new Option<ushort>(new[] Add(new Option<ushort>(new[] { "--width", "-w" }, () => 32, UI.How_many_bytes_to_print_per_line));
{
"--width", "-w"
}, () => 32, UI.How_many_bytes_to_print_per_line));
AddArgument(new Argument<string> AddArgument(new Argument<string>
{ {
@@ -102,6 +90,7 @@ sealed class PrintHexCommand : Command
} }
if(verbose) if(verbose)
{
AaruConsole.WriteEvent += (format, objects) => AaruConsole.WriteEvent += (format, objects) =>
{ {
if(objects is null) if(objects is null)
@@ -109,6 +98,7 @@ sealed class PrintHexCommand : Command
else else
AnsiConsole.Markup(format, objects); AnsiConsole.Markup(format, objects);
}; };
}
Statistics.AddCommand("print-hex"); Statistics.AddCommand("print-hex");
@@ -173,22 +163,23 @@ sealed class PrintHexCommand : Command
AaruConsole.WriteLine($"[bold][italic]{string.Format(UI.Start_0_as_in_sector_start, start)}[/][/]"); AaruConsole.WriteLine($"[bold][italic]{string.Format(UI.Start_0_as_in_sector_start, start)}[/][/]");
byte[] data = new byte[length]; var data = new byte[length];
ErrorNumber errno = ErrorNumber.NoError; ErrorNumber errno = ErrorNumber.NoError;
int bytesRead = 0; var bytesRead = 0;
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask(UI.Reading_data).IsIndeterminate(); ctx.AddTask(UI.Reading_data).IsIndeterminate();
errno = byteAddressableImage?.ReadBytesAt((long)start, data, 0, (int)length, out bytesRead) ?? errno = byteAddressableImage?.ReadBytesAt((long)start, data, 0,
(int)length, out bytesRead) ??
ErrorNumber.InvalidArgument; ErrorNumber.InvalidArgument;
}); });
// TODO: Span // TODO: Span
if(bytesRead != (int)length) if(bytesRead != (int)length)
{ {
byte[] tmp = new byte[bytesRead]; var tmp = new byte[bytesRead];
Array.Copy(data, 0, tmp, 0, bytesRead); Array.Copy(data, 0, tmp, 0, bytesRead);
data = tmp; data = tmp;
} }
@@ -199,6 +190,7 @@ sealed class PrintHexCommand : Command
AaruConsole.ErrorWriteLine(string.Format(UI.Error_0_reading_data_from_1, errno, start)); AaruConsole.ErrorWriteLine(string.Format(UI.Error_0_reading_data_from_1, errno, start));
} }
else else
{
for(ulong i = 0; i < length; i++) for(ulong i = 0; i < length; i++)
{ {
if(inputFormat is not IMediaImage blockImage) if(inputFormat is not IMediaImage blockImage)
@@ -234,7 +226,8 @@ sealed class PrintHexCommand : Command
{ {
ctx.AddTask(UI.Reading_sector).IsIndeterminate(); ctx.AddTask(UI.Reading_sector).IsIndeterminate();
errno = longSectors ? blockImage.ReadSectorLong(start + i, out sector) errno = longSectors
? blockImage.ReadSectorLong(start + i, out sector)
: blockImage.ReadSector(start + i, out sector); : blockImage.ReadSector(start + i, out sector);
}); });
@@ -243,6 +236,7 @@ sealed class PrintHexCommand : Command
else else
AaruConsole.ErrorWriteLine(string.Format(UI.Error_0_reading_sector_1, errno, start + i)); AaruConsole.ErrorWriteLine(string.Format(UI.Error_0_reading_sector_1, errno, start + i));
} }
}
return (int)ErrorNumber.NoError; return (int)ErrorNumber.NoError;
} }

View File

@@ -55,25 +55,13 @@ sealed class VerifyCommand : Command
public VerifyCommand() : base("verify", UI.Image_Verify_Command_Description) public VerifyCommand() : base("verify", UI.Image_Verify_Command_Description)
{ {
Add(new Option<bool>(new[] Add(new Option<bool>(new[] { "--verify-disc", "-w" }, () => true, UI.Verify_media_image_if_supported));
{
"--verify-disc", "-w"
}, () => true, UI.Verify_media_image_if_supported));
Add(new Option<bool>(new[] Add(new Option<bool>(new[] { "--verify-sectors", "-s" }, () => true, UI.Verify_all_sectors_if_supported));
{
"--verify-sectors", "-s"
}, () => true, UI.Verify_all_sectors_if_supported));
Add(new Option<bool>(new[] Add(new Option<bool>(new[] { "--create-graph", "-g" }, () => true, UI.Create_graph_of_verified_disc));
{
"--create-graph", "-g"
}, () => true, UI.Create_graph_of_verified_disc));
Add(new Option<uint>(new[] Add(new Option<uint>(new[] { "--dimensions" }, () => 1080, UI.Verify_dimensions_paramater_help));
{
"--dimensions"
}, () => 1080, UI.Verify_dimensions_paramater_help));
AddArgument(new Argument<string> AddArgument(new Argument<string>
{ {
@@ -107,6 +95,7 @@ sealed class VerifyCommand : Command
} }
if(verbose) if(verbose)
{
AaruConsole.WriteEvent += (format, objects) => AaruConsole.WriteEvent += (format, objects) =>
{ {
if(objects is null) if(objects is null)
@@ -114,6 +103,7 @@ sealed class VerifyCommand : Command
else else
AnsiConsole.Markup(format, objects); AnsiConsole.Markup(format, objects);
}; };
}
Statistics.AddCommand("verify"); Statistics.AddCommand("verify");
@@ -228,19 +218,21 @@ sealed class VerifyCommand : Command
} }
if(!verifySectors) if(!verifySectors)
{
return correctImage switch return correctImage switch
{ {
null => (int)ErrorNumber.NotVerifiable, null => (int)ErrorNumber.NotVerifiable,
false => (int)ErrorNumber.BadImageSectorsNotVerified, false => (int)ErrorNumber.BadImageSectorsNotVerified,
true => (int)ErrorNumber.CorrectImageSectorsNotVerified true => (int)ErrorNumber.CorrectImageSectorsNotVerified
}; };
}
var stopwatch = new Stopwatch(); var stopwatch = new Stopwatch();
List<ulong> failingLbas = new(); List<ulong> failingLbas = new();
List<ulong> unknownLbas = new(); List<ulong> unknownLbas = new();
IMediaGraph mediaGraph = null; IMediaGraph mediaGraph = null;
if(verifiableSectorsImage is IOpticalMediaImage { Tracks: {} } opticalMediaImage) if(verifiableSectorsImage is IOpticalMediaImage { Tracks: not null } opticalMediaImage)
{ {
Spiral.DiscParameters spiralParameters = null; Spiral.DiscParameters spiralParameters = null;
@@ -248,8 +240,10 @@ sealed class VerifyCommand : Command
spiralParameters = Spiral.DiscParametersFromMediaType(opticalMediaImage.Info.MediaType); spiralParameters = Spiral.DiscParametersFromMediaType(opticalMediaImage.Info.MediaType);
if(spiralParameters is not null) if(spiralParameters is not null)
{
mediaGraph = new Spiral((int)dimensions, (int)dimensions, spiralParameters, mediaGraph = new Spiral((int)dimensions, (int)dimensions, spiralParameters,
opticalMediaImage.Info.Sectors); opticalMediaImage.Info.Sectors);
}
else if(createGraph) else if(createGraph)
mediaGraph = new BlockMap((int)dimensions, (int)dimensions, opticalMediaImage.Info.Sectors); mediaGraph = new BlockMap((int)dimensions, (int)dimensions, opticalMediaImage.Info.Sectors);
@@ -268,7 +262,8 @@ sealed class VerifyCommand : Command
foreach(Track currentTrack in inputTracks) foreach(Track currentTrack in inputTracks)
{ {
discTask.Description = discTask.Description =
string.Format(UI.Checking_track_0_of_1, discTask.Value + 1, inputTracks.Count); string.Format(UI.Checking_track_0_of_1, discTask.Value + 1,
inputTracks.Count);
ulong remainingSectors = currentTrack.EndSector - currentTrack.StartSector + 1; ulong remainingSectors = currentTrack.EndSector - currentTrack.StartSector + 1;
@@ -287,18 +282,25 @@ sealed class VerifyCommand : Command
List<ulong> tempUnknownLbas; List<ulong> tempUnknownLbas;
if(remainingSectors < 512) if(remainingSectors < 512)
{
opticalMediaImage.VerifySectors(currentSector, (uint)remainingSectors, opticalMediaImage.VerifySectors(currentSector, (uint)remainingSectors,
currentTrack.Sequence, out tempFailingLbas, currentTrack.Sequence,
out tempFailingLbas,
out tempUnknownLbas); out tempUnknownLbas);
}
else else
{
opticalMediaImage.VerifySectors(currentSector, 512, currentTrack.Sequence, opticalMediaImage.VerifySectors(currentSector, 512, currentTrack.Sequence,
out tempFailingLbas, out tempUnknownLbas); out tempFailingLbas, out tempUnknownLbas);
}
if(mediaGraph != null) if(mediaGraph != null)
{ {
List<ulong> tempCorrectLbas = new(); List<ulong> tempCorrectLbas = new();
for(ulong l = 0; l < (remainingSectors < 512 ? remainingSectors : 512); l++) for(ulong l = 0;
l < (remainingSectors < 512 ? remainingSectors : 512);
l++)
tempCorrectLbas.Add(currentSector + l); tempCorrectLbas.Add(currentSector + l);
foreach(ulong f in tempFailingLbas) foreach(ulong f in tempFailingLbas)
@@ -361,17 +363,23 @@ sealed class VerifyCommand : Command
while(remainingSectors > 0) while(remainingSectors > 0)
{ {
diskTask.Description = diskTask.Description =
string.Format(UI.Checking_sector_0_of_1, currentSector, inputFormat.Info.Sectors); string.Format(UI.Checking_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);
@@ -433,17 +441,21 @@ sealed class VerifyCommand : Command
if(failingLbas.Count == (int)inputFormat.Info.Sectors) if(failingLbas.Count == (int)inputFormat.Info.Sectors)
AaruConsole.VerboseWriteLine($"\t[red]{UI.all_sectors}[/]"); AaruConsole.VerboseWriteLine($"\t[red]{UI.all_sectors}[/]");
else else
{
foreach(ulong t in failingLbas) foreach(ulong t in failingLbas)
AaruConsole.VerboseWriteLine("\t{0}", t); AaruConsole.VerboseWriteLine("\t{0}", t);
}
AaruConsole.WriteLine($"[yellow3_1]{UI.LBAs_without_checksum}[/]"); AaruConsole.WriteLine($"[yellow3_1]{UI.LBAs_without_checksum}[/]");
if(unknownLbas.Count == (int)inputFormat.Info.Sectors) if(unknownLbas.Count == (int)inputFormat.Info.Sectors)
AaruConsole.VerboseWriteLine($"\t[yellow3_1]{UI.all_sectors}[/]"); AaruConsole.VerboseWriteLine($"\t[yellow3_1]{UI.all_sectors}[/]");
else else
{
foreach(ulong t in unknownLbas) foreach(ulong t in unknownLbas)
AaruConsole.VerboseWriteLine("\t{0}", t); AaruConsole.VerboseWriteLine("\t{0}", t);
} }
}
// TODO: Convert to table // TODO: Convert to table
AaruConsole.WriteLine($"[italic]{UI.Total_sectors}[/] {inputFormat.Info.Sectors}"); AaruConsole.WriteLine($"[italic]{UI.Total_sectors}[/] {inputFormat.Info.Sectors}");

View File

@@ -30,7 +30,6 @@
// Copyright © 2011-2023 Natalia Portillo // Copyright © 2011-2023 Natalia Portillo
// ****************************************************************************/ // ****************************************************************************/
using System.Collections.Generic;
using System.CommandLine; using System.CommandLine;
using System.CommandLine.NamingConventionBinder; using System.CommandLine.NamingConventionBinder;
using System.Linq; using System.Linq;
@@ -71,6 +70,7 @@ sealed class ListEncodingsCommand : Command
} }
if(verbose) if(verbose)
{
AaruConsole.WriteEvent += (format, objects) => AaruConsole.WriteEvent += (format, objects) =>
{ {
if(objects is null) if(objects is null)
@@ -78,13 +78,14 @@ sealed class ListEncodingsCommand : Command
else else
AnsiConsole.Markup(format, objects); AnsiConsole.Markup(format, objects);
}; };
}
Statistics.AddCommand("list-encodings"); Statistics.AddCommand("list-encodings");
AaruConsole.DebugWriteLine(MODULE_NAME, "--debug={0}", debug); AaruConsole.DebugWriteLine(MODULE_NAME, "--debug={0}", debug);
AaruConsole.DebugWriteLine(MODULE_NAME, "--verbose={0}", verbose); AaruConsole.DebugWriteLine(MODULE_NAME, "--verbose={0}", verbose);
List<CommonEncodingInfo> encodings = Encoding.GetEncodings().Select(info => new CommonEncodingInfo var encodings = Encoding.GetEncodings().Select(info => new CommonEncodingInfo
{ {
Name = info.Name, Name = info.Name,
DisplayName = info.GetEncoding().EncodingName DisplayName = info.GetEncoding().EncodingName
@@ -108,9 +109,13 @@ sealed class ListEncodingsCommand : Command
return (int)ErrorNumber.NoError; return (int)ErrorNumber.NoError;
} }
#region Nested type: CommonEncodingInfo
struct CommonEncodingInfo struct CommonEncodingInfo
{ {
public string Name; public string Name;
public string DisplayName; public string DisplayName;
} }
#endregion
} }

View File

@@ -72,6 +72,7 @@ sealed class ListNamespacesCommand : Command
} }
if(verbose) if(verbose)
{
AaruConsole.WriteEvent += (format, objects) => AaruConsole.WriteEvent += (format, objects) =>
{ {
if(objects is null) if(objects is null)
@@ -79,6 +80,7 @@ sealed class ListNamespacesCommand : Command
else else
AnsiConsole.Markup(format, objects); AnsiConsole.Markup(format, objects);
}; };
}
AaruConsole.DebugWriteLine(MODULE_NAME, "--debug={0}", debug); AaruConsole.DebugWriteLine(MODULE_NAME, "--debug={0}", debug);
AaruConsole.DebugWriteLine(MODULE_NAME, "--verbose={0}", verbose); AaruConsole.DebugWriteLine(MODULE_NAME, "--verbose={0}", verbose);

View File

@@ -71,60 +71,37 @@ sealed class DumpMediaCommand : Command
public DumpMediaCommand() : base("dump", UI.Media_Dump_Command_Description) public DumpMediaCommand() : base("dump", UI.Media_Dump_Command_Description)
{ {
Add(new Option<string>(new[] Add(new Option<string>(new[] { "--cicm-xml", "-x" }, () => null,
{ UI.Take_metadata_from_existing_CICM_XML_sidecar));
"--cicm-xml", "-x"
}, () => null, UI.Take_metadata_from_existing_CICM_XML_sidecar));
Add(new Option<string>(new[] Add(new Option<string>(new[] { "--encoding", "-e" }, () => null, UI.Name_of_character_encoding_to_use));
{
"--encoding", "-e"
}, () => null, UI.Name_of_character_encoding_to_use));
Add(new Option<bool>("--first-pregap", () => false, UI.Try_to_read_first_track_pregap)); Add(new Option<bool>("--first-pregap", () => false, UI.Try_to_read_first_track_pregap));
Add(new Option<bool>("--fix-offset", () => true, UI.Fix_audio_tracks_offset)); Add(new Option<bool>("--fix-offset", () => true, UI.Fix_audio_tracks_offset));
Add(new Option<bool>(new[] Add(new Option<bool>(new[] { "--force", "-f" }, () => false, UI.Continue_dumping_whatever_happens));
{
"--force", "-f"
}, () => false, UI.Continue_dumping_whatever_happens));
Add(new Option<string>(new[] Add(new Option<string>(new[] { "--format", "-t" }, () => null,
{ UI.Format_of_the_output_image_as_plugin_name_or_plugin_id));
"--format", "-t"
}, () => null, UI.Format_of_the_output_image_as_plugin_name_or_plugin_id));
Add(new Option<bool>("--metadata", () => true, UI.Enables_creating_Aaru_Metadata_sidecar)); Add(new Option<bool>("--metadata", () => true, UI.Enables_creating_Aaru_Metadata_sidecar));
Add(new Option<bool>("--trim", () => true, UI.Enables_trimming_errored_from_skipped_sectors)); Add(new Option<bool>("--trim", () => true, UI.Enables_trimming_errored_from_skipped_sectors));
Add(new Option<string>(new[] Add(new Option<string>(new[] { "--options", "-O" }, () => null,
{ UI.Comma_separated_name_value_pairs_of_image_options));
"--options", "-O"
}, () => null, UI.Comma_separated_name_value_pairs_of_image_options));
Add(new Option<bool>("--persistent", () => false, UI.Try_to_recover_partial_or_incorrect_data)); Add(new Option<bool>("--persistent", () => false, UI.Try_to_recover_partial_or_incorrect_data));
Add(new Option<bool>(new[] Add(new Option<bool>(new[] { "--resume", "-r" }, () => true, UI.Create_or_use_resume_mapfile));
{
"--resume", "-r"
}, () => true, UI.Create_or_use_resume_mapfile));
Add(new Option<ushort>(new[] Add(new Option<ushort>(new[] { "--retry-passes", "-p" }, () => 5, UI.How_many_retry_passes_to_do));
{
"--retry-passes", "-p"
}, () => 5, UI.How_many_retry_passes_to_do));
Add(new Option<uint>(new[] Add(new Option<uint>(new[] { "--skip", "-k" }, () => 512,
{ UI.When_an_unreadable_sector_is_found_skip_this_many_sectors));
"--skip", "-k"
}, () => 512, UI.When_an_unreadable_sector_is_found_skip_this_many_sectors));
Add(new Option<bool>(new[] Add(new Option<bool>(new[] { "--stop-on-error", "-s" }, () => false, UI.Stop_media_dump_on_first_error));
{
"--stop-on-error", "-s"
}, () => false, UI.Stop_media_dump_on_first_error));
Add(new Option<string>("--subchannel", () => UI.Subchannel_name_any, UI.Subchannel_to_dump_help)); Add(new Option<string>("--subchannel", () => UI.Subchannel_name_any, UI.Subchannel_to_dump_help));
@@ -144,85 +121,40 @@ sealed class DumpMediaCommand : Command
Name = "output-path" Name = "output-path"
}); });
Add(new Option<bool>(new[] Add(new Option<bool>(new[] { "--private" }, () => false,
{ UI.Do_not_store_paths_and_serial_numbers_in_log_or_metadata));
"--private"
}, () => false, UI.Do_not_store_paths_and_serial_numbers_in_log_or_metadata));
Add(new Option<bool>(new[] Add(new Option<bool>(new[] { "--fix-subchannel-position" }, () => true, UI.Fix_subchannel_position_help));
{
"--fix-subchannel-position"
}, () => true, UI.Fix_subchannel_position_help));
Add(new Option<bool>(new[] Add(new Option<bool>(new[] { "--retry-subchannel" }, () => true, UI.Retry_subchannel_help));
{
"--retry-subchannel"
}, () => true, UI.Retry_subchannel_help));
Add(new Option<bool>(new[] Add(new Option<bool>(new[] { "--fix-subchannel" }, () => false, UI.Fix_subchannel_help));
{
"--fix-subchannel"
}, () => false, UI.Fix_subchannel_help));
Add(new Option<bool>(new[] Add(new Option<bool>(new[] { "--fix-subchannel-crc" }, () => false, UI.Fix_subchannel_crc_help));
{
"--fix-subchannel-crc"
}, () => false, UI.Fix_subchannel_crc_help));
Add(new Option<bool>(new[] Add(new Option<bool>(new[] { "--generate-subchannels" }, () => false, UI.Generate_subchannels_dump_help));
{
"--generate-subchannels"
}, () => false, UI.Generate_subchannels_dump_help));
Add(new Option<bool>(new[] Add(new Option<bool>(new[] { "--skip-cdiready-hole" }, () => true, UI.Skip_CDi_Ready_hole_help));
{
"--skip-cdiready-hole"
}, () => true, UI.Skip_CDi_Ready_hole_help));
Add(new Option<bool>(new[] Add(new Option<bool>(new[] { "--eject" }, () => false, UI.Eject_media_after_dump_finishes));
{
"--eject"
}, () => false, UI.Eject_media_after_dump_finishes));
Add(new Option<uint>(new[] Add(new Option<uint>(new[] { "--max-blocks" }, () => 64, UI.Maximum_number_of_blocks_to_read_at_once));
{
"--max-blocks"
}, () => 64, UI.Maximum_number_of_blocks_to_read_at_once));
Add(new Option<bool>(new[] Add(new Option<bool>(new[] { "--use-buffered-reads" }, () => true, UI.OS_buffered_reads_help));
{
"--use-buffered-reads"
}, () => true, UI.OS_buffered_reads_help));
Add(new Option<bool>(new[] Add(new Option<bool>(new[] { "--store-encrypted" }, () => true, UI.Store_encrypted_data_as_is));
{
"--store-encrypted"
}, () => true, UI.Store_encrypted_data_as_is));
Add(new Option<bool>(new[] Add(new Option<bool>(new[] { "--title-keys" }, () => true, UI.Try_to_read_the_title_keys_from_CSS_DVDs));
{
"--title-keys"
}, () => true, UI.Try_to_read_the_title_keys_from_CSS_DVDs));
Add(new Option<uint>(new[] Add(new Option<uint>(new[] { "--ignore-cdr-runouts" }, () => 10,
{ UI.How_many_CDRW_run_out_sectors_to_ignore_and_regenerate));
"--ignore-cdr-runouts"
}, () => 10, UI.How_many_CDRW_run_out_sectors_to_ignore_and_regenerate));
Add(new Option<bool>(new[] Add(new Option<bool>(new[] { "--create-graph", "-g" }, () => true, UI.Create_graph_of_dumped_media));
{
"--create-graph", "-g"
}, () => true, UI.Create_graph_of_dumped_media));
Add(new Option<uint>(new[] Add(new Option<uint>(new[] { "--dimensions" }, () => 1080, UI.Dump_graph_dimensions_argument_help));
{
"--dimensions"
}, () => 1080, UI.Dump_graph_dimensions_argument_help));
Add(new Option<string>(new[] Add(new Option<string>(new[] { "--aaru-metadata", "-m" }, () => null,
{ "Take metadata from existing Aaru Metadata sidecar."));
"--aaru-metadata", "-m"
}, () => null, "Take metadata from existing Aaru Metadata sidecar."));
Handler = CommandHandler.Create(GetType().GetMethod(nameof(Invoke))); Handler = CommandHandler.Create(GetType().GetMethod(nameof(Invoke)));
} }
@@ -255,6 +187,7 @@ sealed class DumpMediaCommand : Command
} }
if(verbose) if(verbose)
{
AaruConsole.WriteEvent += (format, objects) => AaruConsole.WriteEvent += (format, objects) =>
{ {
if(objects is null) if(objects is null)
@@ -262,6 +195,7 @@ sealed class DumpMediaCommand : Command
else else
AnsiConsole.Markup(format, objects); AnsiConsole.Markup(format, objects);
}; };
}
fixSubchannel |= fixSubchannelCrc; fixSubchannel |= fixSubchannelCrc;
fixSubchannelPosition |= retrySubchannel || fixSubchannel; fixSubchannelPosition |= retrySubchannel || fixSubchannel;
@@ -319,6 +253,7 @@ sealed class DumpMediaCommand : Command
Encoding encodingClass = null; Encoding encodingClass = null;
if(encoding != null) if(encoding != null)
{
try try
{ {
encodingClass = Claunia.Encoding.Encoding.GetEncoding(encoding); encodingClass = Claunia.Encoding.Encoding.GetEncoding(encoding);
@@ -332,6 +267,7 @@ sealed class DumpMediaCommand : Command
return (int)ErrorNumber.EncodingUnknown; return (int)ErrorNumber.EncodingUnknown;
} }
}
DumpSubchannel wantedSubchannel = DumpSubchannel.Any; DumpSubchannel wantedSubchannel = DumpSubchannel.Any;
@@ -358,8 +294,10 @@ sealed class DumpMediaCommand : Command
TextReader resReader; TextReader resReader;
if(isResponse) if(isResponse)
{
resReader = new StreamReader(Path.Combine(Path.GetDirectoryName(outputPath), resReader = new StreamReader(Path.Combine(Path.GetDirectoryName(outputPath),
Path.GetFileNameWithoutExtension(outputPath))); Path.GetFileNameWithoutExtension(outputPath)));
}
else else
resReader = new StringReader(Path.GetFileNameWithoutExtension(outputPath)); resReader = new StringReader(Path.GetFileNameWithoutExtension(outputPath));
@@ -372,24 +310,36 @@ sealed class DumpMediaCommand : Command
// Try extension // Try extension
if(string.IsNullOrEmpty(format)) if(string.IsNullOrEmpty(format))
{
candidates.AddRange(from pluginType in plugins.WritableImages.Values candidates.AddRange(from pluginType in plugins.WritableImages.Values
select Activator.CreateInstance(pluginType) as IBaseWritableImage into plugin select Activator.CreateInstance(pluginType) as IBaseWritableImage
where plugin is not null where plugin.KnownExtensions.Contains(extension) into plugin
where plugin is not null
where plugin.KnownExtensions.Contains(extension)
select plugin); select plugin);
}
// Try Id // Try Id
else if(Guid.TryParse(format, out Guid outId)) else if(Guid.TryParse(format, out Guid outId))
{
candidates.AddRange(from pluginType in plugins.WritableImages.Values candidates.AddRange(from pluginType in plugins.WritableImages.Values
select Activator.CreateInstance(pluginType) as IBaseWritableImage into plugin select Activator.CreateInstance(pluginType) as IBaseWritableImage
where plugin is not null where plugin.Id.Equals(outId) select plugin); into plugin
where plugin is not null
where plugin.Id.Equals(outId)
select plugin);
}
// Try name // Try name
else else
{
candidates.AddRange(from pluginType in plugins.WritableImages.Values candidates.AddRange(from pluginType in plugins.WritableImages.Values
select Activator.CreateInstance(pluginType) as IBaseWritableImage into plugin select Activator.CreateInstance(pluginType) as IBaseWritableImage
into plugin
where plugin is not null where plugin is not null
where plugin.Name.Equals(format, StringComparison.InvariantCultureIgnoreCase) where plugin.Name.Equals(format, StringComparison.InvariantCultureIgnoreCase)
select plugin); select plugin);
}
switch(candidates.Count) switch(candidates.Count)
{ {
@@ -429,9 +379,11 @@ sealed class DumpMediaCommand : Command
// Replace Windows forbidden filename characters with Japanese equivalents that are visually the same, but bigger. // Replace Windows forbidden filename characters with Japanese equivalents that are visually the same, but bigger.
if(DetectOS.IsWindows) if(DetectOS.IsWindows)
{
responseLine = responseLine.Replace('<', '\uFF1C').Replace('>', '\uFF1E').Replace(':', '\uFF1A'). responseLine = responseLine.Replace('<', '\uFF1C').Replace('>', '\uFF1E').Replace(':', '\uFF1A').
Replace('"', '\u2033').Replace('\\', '').Replace('|', ''). Replace('"', '\u2033').Replace('\\', '').Replace('|', '').
Replace('?', '').Replace('*', ''); Replace('?', '').Replace('*', '');
}
if(devicePath.Length == 2 && if(devicePath.Length == 2 &&
devicePath[1] == ':' && devicePath[1] == ':' &&
@@ -545,7 +497,9 @@ sealed class DumpMediaCommand : Command
Metadata sidecar = null; Metadata sidecar = null;
if(aaruMetadata != null) if(aaruMetadata != null)
{
if(File.Exists(aaruMetadata)) if(File.Exists(aaruMetadata))
{
try try
{ {
var fs = new FileStream(aaruMetadata, FileMode.Open); var fs = new FileStream(aaruMetadata, FileMode.Open);
@@ -565,6 +519,7 @@ sealed class DumpMediaCommand : Command
return (int)ErrorNumber.InvalidSidecar; return (int)ErrorNumber.InvalidSidecar;
} }
}
else else
{ {
AaruConsole.ErrorWriteLine(UI.Could_not_find_metadata_sidecar); AaruConsole.ErrorWriteLine(UI.Could_not_find_metadata_sidecar);
@@ -574,8 +529,11 @@ sealed class DumpMediaCommand : Command
return (int)ErrorNumber.NoSuchFile; return (int)ErrorNumber.NoSuchFile;
} }
}
else if(cicmXml != null) else if(cicmXml != null)
{
if(File.Exists(cicmXml)) if(File.Exists(cicmXml))
{
try try
{ {
var sr = new StreamReader(cicmXml); var sr = new StreamReader(cicmXml);
@@ -601,6 +559,7 @@ sealed class DumpMediaCommand : Command
return (int)ErrorNumber.InvalidSidecar; return (int)ErrorNumber.InvalidSidecar;
} }
}
else else
{ {
AaruConsole.ErrorWriteLine(UI.Could_not_find_metadata_sidecar); AaruConsole.ErrorWriteLine(UI.Could_not_find_metadata_sidecar);
@@ -610,30 +569,43 @@ sealed class DumpMediaCommand : Command
return (int)ErrorNumber.NoSuchFile; return (int)ErrorNumber.NoSuchFile;
} }
}
plugins = PluginBase.Singleton; plugins = PluginBase.Singleton;
candidates = new List<IBaseWritableImage>(); candidates = new List<IBaseWritableImage>();
// Try extension // Try extension
if(string.IsNullOrEmpty(format)) if(string.IsNullOrEmpty(format))
{
candidates.AddRange(from pluginType in plugins.WritableImages.Values candidates.AddRange(from pluginType in plugins.WritableImages.Values
select Activator.CreateInstance(pluginType) as IBaseWritableImage into plugin select Activator.CreateInstance(pluginType) as IBaseWritableImage
into plugin
where plugin is not null where plugin is not null
where plugin.KnownExtensions.Contains(Path.GetExtension(outputPath)) select plugin); where plugin.KnownExtensions.Contains(Path.GetExtension(outputPath))
select plugin);
}
// Try Id // Try Id
else if(Guid.TryParse(format, out Guid outId)) else if(Guid.TryParse(format, out Guid outId))
{
candidates.AddRange(from pluginType in plugins.WritableImages.Values candidates.AddRange(from pluginType in plugins.WritableImages.Values
select Activator.CreateInstance(pluginType) as IBaseWritableImage into plugin select Activator.CreateInstance(pluginType) as IBaseWritableImage
where plugin is not null where plugin.Id.Equals(outId) select plugin); into plugin
where plugin is not null
where plugin.Id.Equals(outId)
select plugin);
}
// Try name // Try name
else else
{
candidates.AddRange(from pluginType in plugins.WritableImages.Values candidates.AddRange(from pluginType in plugins.WritableImages.Values
select Activator.CreateInstance(pluginType) as IBaseWritableImage into plugin select Activator.CreateInstance(pluginType) as IBaseWritableImage
into plugin
where plugin is not null where plugin is not null
where plugin.Name.Equals(format, StringComparison.InvariantCultureIgnoreCase) where plugin.Name.Equals(format, StringComparison.InvariantCultureIgnoreCase)
select plugin); select plugin);
}
IBaseWritableImage outputFormat = candidates[0]; IBaseWritableImage outputFormat = candidates[0];
@@ -664,19 +636,18 @@ sealed class DumpMediaCommand : Command
Columns(new TaskDescriptionColumn(), new ProgressBarColumn(), new PercentageColumn()). Columns(new TaskDescriptionColumn(), new ProgressBarColumn(), new PercentageColumn()).
Start(ctx => Start(ctx =>
{ {
dumper.UpdateStatus += text => dumper.UpdateStatus += text => { AaruConsole.WriteLine(Markup.Escape(text)); };
{
AaruConsole.WriteLine(Markup.Escape(text));
};
dumper.ErrorMessage += text => dumper.ErrorMessage += text =>
{ {
AaruConsole.ErrorWriteLine($"[red]{Markup.Escape(text)}[/]"); AaruConsole.
ErrorWriteLine($"[red]{Markup.Escape(text)}[/]");
}; };
dumper.StoppingErrorMessage += text => dumper.StoppingErrorMessage += text =>
{ {
AaruConsole.ErrorWriteLine($"[red]{Markup.Escape(text)}[/]"); AaruConsole.
ErrorWriteLine($"[red]{Markup.Escape(text)}[/]");
}; };
dumper.UpdateProgress += (text, current, maximum) => dumper.UpdateProgress += (text, current, maximum) =>
@@ -698,10 +669,7 @@ sealed class DumpMediaCommand : Command
} }
}; };
dumper.InitProgress += () => dumper.InitProgress += () => { _progressTask1 = ctx.AddTask("Progress"); };
{
_progressTask1 = ctx.AddTask("Progress");
};
dumper.EndProgress += () => dumper.EndProgress += () =>
{ {
@@ -709,10 +677,7 @@ sealed class DumpMediaCommand : Command
_progressTask1 = null; _progressTask1 = null;
}; };
dumper.InitProgress2 += () => dumper.InitProgress2 += () => { _progressTask2 = ctx.AddTask("Progress"); };
{
_progressTask2 = ctx.AddTask("Progress");
};
dumper.EndProgress2 += () => dumper.EndProgress2 += () =>
{ {
@@ -738,6 +703,7 @@ sealed class DumpMediaCommand : Command
}); });
if(eject && dev.IsRemovable) if(eject && dev.IsRemovable)
{
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask(UI.Ejecting_media).IsIndeterminate(); ctx.AddTask(UI.Ejecting_media).IsIndeterminate();
@@ -759,18 +725,22 @@ sealed class DumpMediaCommand : Command
case PeripheralDeviceTypes.WriteOnceDevice: case PeripheralDeviceTypes.WriteOnceDevice:
case PeripheralDeviceTypes.OpticalDevice: case PeripheralDeviceTypes.OpticalDevice:
case PeripheralDeviceTypes.OCRWDevice: case PeripheralDeviceTypes.OCRWDevice:
dev.SpcAllowMediumRemoval(out _, dev.Timeout, out _); dev.SpcAllowMediumRemoval(out _, dev.Timeout,
out _);
dev.EjectTray(out _, dev.Timeout, out _); dev.EjectTray(out _, dev.Timeout, out _);
break; break;
case PeripheralDeviceTypes.MultiMediaDevice: case PeripheralDeviceTypes.MultiMediaDevice:
dev.AllowMediumRemoval(out _, dev.Timeout, out _); dev.AllowMediumRemoval(out _, dev.Timeout,
out _);
dev.EjectTray(out _, dev.Timeout, out _); dev.EjectTray(out _, dev.Timeout, out _);
break; break;
case PeripheralDeviceTypes.SequentialAccess: case PeripheralDeviceTypes.SequentialAccess:
dev.SpcAllowMediumRemoval(out _, dev.Timeout, out _); dev.SpcAllowMediumRemoval(out _, dev.Timeout,
dev.LoadUnload(out _, true, false, false, false, false, dev.Timeout, out _); out _);
dev.LoadUnload(out _, true, false, false, false,
false, dev.Timeout, out _);
break; break;
} }
@@ -778,6 +748,7 @@ sealed class DumpMediaCommand : Command
break; break;
} }
}); });
}
dev.Close(); dev.Close();
} }

View File

@@ -69,10 +69,7 @@ sealed class MediaInfoCommand : Command
public MediaInfoCommand() : base("info", UI.Media_Info_Command_Description) public MediaInfoCommand() : base("info", UI.Media_Info_Command_Description)
{ {
Add(new Option<string>(new[] Add(new Option<string>(new[] { "--output-prefix", "-w" }, () => null, UI.Prefix_for_saving_binary_information));
{
"--output-prefix", "-w"
}, () => null, UI.Prefix_for_saving_binary_information));
AddArgument(new Argument<string> AddArgument(new Argument<string>
{ {
@@ -105,6 +102,7 @@ sealed class MediaInfoCommand : Command
} }
if(verbose) if(verbose)
{
AaruConsole.WriteEvent += (format, objects) => AaruConsole.WriteEvent += (format, objects) =>
{ {
if(objects is null) if(objects is null)
@@ -112,6 +110,7 @@ sealed class MediaInfoCommand : Command
else else
AnsiConsole.Markup(format, objects); AnsiConsole.Markup(format, objects);
}; };
}
Statistics.AddCommand("media-info"); Statistics.AddCommand("media-info");
@@ -178,7 +177,8 @@ sealed class MediaInfoCommand : Command
DoScsiMediaInfo(debug, outputPrefix, dev); DoScsiMediaInfo(debug, outputPrefix, dev);
break; break;
default: throw new NotSupportedException(Localization.Core.Unknown_device_type); default:
throw new NotSupportedException(Localization.Core.Unknown_device_type);
} }
return (int)ErrorNumber.NoError; return (int)ErrorNumber.NoError;
@@ -205,12 +205,16 @@ sealed class MediaInfoCommand : Command
return; return;
if(scsiInfo.DeviceInfo.ScsiModeSense6 != null) if(scsiInfo.DeviceInfo.ScsiModeSense6 != null)
{
DataFile.WriteTo(MODULE_NAME, outputPrefix, "_scsi_modesense6.bin", "SCSI MODE SENSE (6)", DataFile.WriteTo(MODULE_NAME, outputPrefix, "_scsi_modesense6.bin", "SCSI MODE SENSE (6)",
scsiInfo.DeviceInfo.ScsiModeSense6); scsiInfo.DeviceInfo.ScsiModeSense6);
}
if(scsiInfo.DeviceInfo.ScsiModeSense10 != null) if(scsiInfo.DeviceInfo.ScsiModeSense10 != null)
{
DataFile.WriteTo(MODULE_NAME, outputPrefix, "_scsi_modesense10.bin", "SCSI MODE SENSE (10)", DataFile.WriteTo(MODULE_NAME, outputPrefix, "_scsi_modesense10.bin", "SCSI MODE SENSE (10)",
scsiInfo.DeviceInfo.ScsiModeSense10); scsiInfo.DeviceInfo.ScsiModeSense10);
}
switch(dev.ScsiType) switch(dev.ScsiType)
{ {
@@ -223,18 +227,24 @@ sealed class MediaInfoCommand : Command
case PeripheralDeviceTypes.BridgingExpander when dev.Model.StartsWith("MDM", StringComparison.Ordinal) || case PeripheralDeviceTypes.BridgingExpander when dev.Model.StartsWith("MDM", StringComparison.Ordinal) ||
dev.Model.StartsWith("MDH", StringComparison.Ordinal): dev.Model.StartsWith("MDH", StringComparison.Ordinal):
if(scsiInfo.ReadCapacity != null) if(scsiInfo.ReadCapacity != null)
{
DataFile.WriteTo(MODULE_NAME, outputPrefix, "_readcapacity.bin", "SCSI READ CAPACITY", DataFile.WriteTo(MODULE_NAME, outputPrefix, "_readcapacity.bin", "SCSI READ CAPACITY",
scsiInfo.ReadCapacity); scsiInfo.ReadCapacity);
}
if(scsiInfo.ReadCapacity16 != null) if(scsiInfo.ReadCapacity16 != null)
{
DataFile.WriteTo(MODULE_NAME, outputPrefix, "_readcapacity16.bin", DataFile.WriteTo(MODULE_NAME, outputPrefix, "_readcapacity16.bin",
"SCSI READ CAPACITY(16)", scsiInfo.ReadCapacity16); "SCSI READ CAPACITY(16)", scsiInfo.ReadCapacity16);
}
if(scsiInfo.Blocks != 0 && if(scsiInfo.Blocks != 0 &&
scsiInfo.BlockSize != 0) scsiInfo.BlockSize != 0)
{
AaruConsole.WriteLine(Localization.Core.Media_has_0_blocks_of_1_bytes_each_for_a_total_of_2, AaruConsole.WriteLine(Localization.Core.Media_has_0_blocks_of_1_bytes_each_for_a_total_of_2,
scsiInfo.Blocks, scsiInfo.BlockSize, scsiInfo.Blocks, scsiInfo.BlockSize,
ByteSize.FromBytes(scsiInfo.Blocks * scsiInfo.BlockSize).ToString("0.000")); ByteSize.FromBytes(scsiInfo.Blocks * scsiInfo.BlockSize).ToString("0.000"));
}
break; break;
case PeripheralDeviceTypes.SequentialAccess: case PeripheralDeviceTypes.SequentialAccess:
@@ -270,16 +280,22 @@ sealed class MediaInfoCommand : Command
if(dev.ScsiType == PeripheralDeviceTypes.MultiMediaDevice) if(dev.ScsiType == PeripheralDeviceTypes.MultiMediaDevice)
{ {
if(scsiInfo.MmcConfiguration != null) if(scsiInfo.MmcConfiguration != null)
{
DataFile.WriteTo(MODULE_NAME, outputPrefix, "_getconfiguration_current.bin", DataFile.WriteTo(MODULE_NAME, outputPrefix, "_getconfiguration_current.bin",
"SCSI GET CONFIGURATION", scsiInfo.MmcConfiguration); "SCSI GET CONFIGURATION", scsiInfo.MmcConfiguration);
}
if(scsiInfo.RecognizedFormatLayers != null) if(scsiInfo.RecognizedFormatLayers != null)
{
DataFile.WriteTo(MODULE_NAME, outputPrefix, "_readdiscstructure_formatlayers.bin", DataFile.WriteTo(MODULE_NAME, outputPrefix, "_readdiscstructure_formatlayers.bin",
"SCSI READ DISC STRUCTURE", scsiInfo.RecognizedFormatLayers); "SCSI READ DISC STRUCTURE", scsiInfo.RecognizedFormatLayers);
}
if(scsiInfo.WriteProtectionStatus != null) if(scsiInfo.WriteProtectionStatus != null)
{
DataFile.WriteTo(MODULE_NAME, outputPrefix, "_readdiscstructure_writeprotection.bin", DataFile.WriteTo(MODULE_NAME, outputPrefix, "_readdiscstructure_writeprotection.bin",
"SCSI READ DISC STRUCTURE", scsiInfo.WriteProtectionStatus); "SCSI READ DISC STRUCTURE", scsiInfo.WriteProtectionStatus);
}
if(scsiInfo.DvdPfi != null) if(scsiInfo.DvdPfi != null)
{ {
@@ -296,12 +312,16 @@ sealed class MediaInfoCommand : Command
"SCSI READ DISC STRUCTURE", scsiInfo.DvdDmi); "SCSI READ DISC STRUCTURE", scsiInfo.DvdDmi);
if(DMI.IsXbox(scsiInfo.DvdDmi)) if(DMI.IsXbox(scsiInfo.DvdDmi))
{
AaruConsole.WriteLine($"[bold]{Localization.Core.Xbox_DMI}:[/]", AaruConsole.WriteLine($"[bold]{Localization.Core.Xbox_DMI}:[/]",
$"\n{Markup.Escape(DMI.PrettifyXbox(scsiInfo.DvdDmi))}"); $"\n{Markup.Escape(DMI.PrettifyXbox(scsiInfo.DvdDmi))}");
}
else if(DMI.IsXbox360(scsiInfo.DvdDmi)) else if(DMI.IsXbox360(scsiInfo.DvdDmi))
{
AaruConsole.WriteLine($"[bold]{Localization.Core.Xbox_360_DMI}:[/]", AaruConsole.WriteLine($"[bold]{Localization.Core.Xbox_360_DMI}:[/]",
$"\n{Markup.Escape(DMI.PrettifyXbox360(scsiInfo.DvdDmi))}"); $"\n{Markup.Escape(DMI.PrettifyXbox360(scsiInfo.DvdDmi))}");
} }
}
if(scsiInfo.DvdCmi != null) if(scsiInfo.DvdCmi != null)
{ {
@@ -313,20 +333,28 @@ sealed class MediaInfoCommand : Command
} }
if(scsiInfo.DvdDiscKey != null) if(scsiInfo.DvdDiscKey != null)
{
DataFile.WriteTo(MODULE_NAME, outputPrefix, "_readdiscstructure_dvd_disckey.bin", DataFile.WriteTo(MODULE_NAME, outputPrefix, "_readdiscstructure_dvd_disckey.bin",
"SCSI READ DISC STRUCTURE", scsiInfo.DvdDiscKey); "SCSI READ DISC STRUCTURE", scsiInfo.DvdDiscKey);
}
if(scsiInfo.DvdSectorCmi != null) if(scsiInfo.DvdSectorCmi != null)
{
DataFile.WriteTo(MODULE_NAME, outputPrefix, "_readdiscstructure_dvd_sectorcmi.bin", DataFile.WriteTo(MODULE_NAME, outputPrefix, "_readdiscstructure_dvd_sectorcmi.bin",
"SCSI READ DISC STRUCTURE", scsiInfo.DvdSectorCmi); "SCSI READ DISC STRUCTURE", scsiInfo.DvdSectorCmi);
}
if(scsiInfo.DvdBca != null) if(scsiInfo.DvdBca != null)
{
DataFile.WriteTo(MODULE_NAME, outputPrefix, "_readdiscstructure_dvd_bca.bin", DataFile.WriteTo(MODULE_NAME, outputPrefix, "_readdiscstructure_dvd_bca.bin",
"SCSI READ DISC STRUCTURE", scsiInfo.DvdBca); "SCSI READ DISC STRUCTURE", scsiInfo.DvdBca);
}
if(scsiInfo.DvdAacs != null) if(scsiInfo.DvdAacs != null)
{
DataFile.WriteTo(MODULE_NAME, outputPrefix, "_readdiscstructure_dvd_aacs.bin", DataFile.WriteTo(MODULE_NAME, outputPrefix, "_readdiscstructure_dvd_aacs.bin",
"SCSI READ DISC STRUCTURE", scsiInfo.DvdAacs); "SCSI READ DISC STRUCTURE", scsiInfo.DvdAacs);
}
if(scsiInfo.DvdRamDds != null) if(scsiInfo.DvdRamDds != null)
{ {
@@ -356,8 +384,10 @@ sealed class MediaInfoCommand : Command
} }
if(scsiInfo.LastBorderOutRmd != null) if(scsiInfo.LastBorderOutRmd != null)
{
DataFile.WriteTo(MODULE_NAME, outputPrefix, "_readdiscstructure_dvd_lastrmd.bin", DataFile.WriteTo(MODULE_NAME, outputPrefix, "_readdiscstructure_dvd_lastrmd.bin",
"SCSI READ DISC STRUCTURE", scsiInfo.LastBorderOutRmd); "SCSI READ DISC STRUCTURE", scsiInfo.LastBorderOutRmd);
}
if(scsiInfo.DvdPreRecordedInfo != null) if(scsiInfo.DvdPreRecordedInfo != null)
{ {
@@ -365,13 +395,17 @@ sealed class MediaInfoCommand : Command
"SCSI READ DISC STRUCTURE", scsiInfo.DvdPreRecordedInfo); "SCSI READ DISC STRUCTURE", scsiInfo.DvdPreRecordedInfo);
if(scsiInfo.DecodedDvdPrePitInformation.HasValue) if(scsiInfo.DecodedDvdPrePitInformation.HasValue)
{
AaruConsole.WriteLine($"[bold]{Localization.Core.DVD_RW_Pre_Recorded_Information}:[/]", AaruConsole.WriteLine($"[bold]{Localization.Core.DVD_RW_Pre_Recorded_Information}:[/]",
$"\n{Markup.Escape(PRI.Prettify(scsiInfo.DecodedDvdPrePitInformation))}"); $"\n{Markup.Escape(PRI.Prettify(scsiInfo.DecodedDvdPrePitInformation))}");
} }
}
if(scsiInfo.DvdrMediaIdentifier != null) if(scsiInfo.DvdrMediaIdentifier != null)
{
DataFile.WriteTo(MODULE_NAME, outputPrefix, "_readdiscstructure_dvdr_mediaid.bin", DataFile.WriteTo(MODULE_NAME, outputPrefix, "_readdiscstructure_dvdr_mediaid.bin",
"SCSI READ DISC STRUCTURE", scsiInfo.DvdrMediaIdentifier); "SCSI READ DISC STRUCTURE", scsiInfo.DvdrMediaIdentifier);
}
if(scsiInfo.DvdrPhysicalInformation != null) if(scsiInfo.DvdrPhysicalInformation != null)
{ {
@@ -379,49 +413,71 @@ sealed class MediaInfoCommand : Command
"SCSI READ DISC STRUCTURE", scsiInfo.DvdrPhysicalInformation); "SCSI READ DISC STRUCTURE", scsiInfo.DvdrPhysicalInformation);
if(scsiInfo.DecodedDvdrPfi.HasValue) if(scsiInfo.DecodedDvdrPfi.HasValue)
{
AaruConsole.WriteLine($"[bold]{Localization.Core.DVD_RW_PFI}:[/]", AaruConsole.WriteLine($"[bold]{Localization.Core.DVD_RW_PFI}:[/]",
$"\n{Markup.Escape(PFI.Prettify(scsiInfo.DecodedDvdrPfi))}"); $"\n{Markup.Escape(PFI.Prettify(scsiInfo.DecodedDvdrPfi))}");
} }
}
if(scsiInfo.DvdPlusAdip != null) if(scsiInfo.DvdPlusAdip != null)
{
DataFile.WriteTo(MODULE_NAME, outputPrefix, "_readdiscstructure_dvd+_adip.bin", DataFile.WriteTo(MODULE_NAME, outputPrefix, "_readdiscstructure_dvd+_adip.bin",
"SCSI READ DISC STRUCTURE", scsiInfo.DvdPlusAdip); "SCSI READ DISC STRUCTURE", scsiInfo.DvdPlusAdip);
}
if(scsiInfo.DvdPlusDcb != null) if(scsiInfo.DvdPlusDcb != null)
{
DataFile.WriteTo(MODULE_NAME, outputPrefix, "_readdiscstructure_dvd+_dcb.bin", DataFile.WriteTo(MODULE_NAME, outputPrefix, "_readdiscstructure_dvd+_dcb.bin",
"SCSI READ DISC STRUCTURE", scsiInfo.DvdPlusDcb); "SCSI READ DISC STRUCTURE", scsiInfo.DvdPlusDcb);
}
if(scsiInfo.HddvdCopyrightInformation != null) if(scsiInfo.HddvdCopyrightInformation != null)
{
DataFile.WriteTo(MODULE_NAME, outputPrefix, "_readdiscstructure_hddvd_cmi.bin", DataFile.WriteTo(MODULE_NAME, outputPrefix, "_readdiscstructure_hddvd_cmi.bin",
"SCSI READ DISC STRUCTURE", scsiInfo.HddvdCopyrightInformation); "SCSI READ DISC STRUCTURE", scsiInfo.HddvdCopyrightInformation);
}
if(scsiInfo.HddvdrMediumStatus != null) if(scsiInfo.HddvdrMediumStatus != null)
{
DataFile.WriteTo(MODULE_NAME, outputPrefix, "_readdiscstructure_hddvdr_status.bin", DataFile.WriteTo(MODULE_NAME, outputPrefix, "_readdiscstructure_hddvdr_status.bin",
"SCSI READ DISC STRUCTURE", scsiInfo.HddvdrMediumStatus); "SCSI READ DISC STRUCTURE", scsiInfo.HddvdrMediumStatus);
}
if(scsiInfo.HddvdrLastRmd != null) if(scsiInfo.HddvdrLastRmd != null)
{
DataFile.WriteTo(MODULE_NAME, outputPrefix, "_readdiscstructure_hddvdr_lastrmd.bin", DataFile.WriteTo(MODULE_NAME, outputPrefix, "_readdiscstructure_hddvdr_lastrmd.bin",
"SCSI READ DISC STRUCTURE", scsiInfo.HddvdrLastRmd); "SCSI READ DISC STRUCTURE", scsiInfo.HddvdrLastRmd);
}
if(scsiInfo.DvdrLayerCapacity != null) if(scsiInfo.DvdrLayerCapacity != null)
{
DataFile.WriteTo(MODULE_NAME, outputPrefix, "_readdiscstructure_dvdr_layercap.bin", DataFile.WriteTo(MODULE_NAME, outputPrefix, "_readdiscstructure_dvdr_layercap.bin",
"SCSI READ DISC STRUCTURE", scsiInfo.DvdrLayerCapacity); "SCSI READ DISC STRUCTURE", scsiInfo.DvdrLayerCapacity);
}
if(scsiInfo.DvdrDlMiddleZoneStart != null) if(scsiInfo.DvdrDlMiddleZoneStart != null)
{
DataFile.WriteTo(MODULE_NAME, outputPrefix, "_readdiscstructure_dvd_mzs.bin", DataFile.WriteTo(MODULE_NAME, outputPrefix, "_readdiscstructure_dvd_mzs.bin",
"SCSI READ DISC STRUCTURE", scsiInfo.DvdrDlMiddleZoneStart); "SCSI READ DISC STRUCTURE", scsiInfo.DvdrDlMiddleZoneStart);
}
if(scsiInfo.DvdrDlJumpIntervalSize != null) if(scsiInfo.DvdrDlJumpIntervalSize != null)
{
DataFile.WriteTo(MODULE_NAME, outputPrefix, "_readdiscstructure_dvd_jis.bin", DataFile.WriteTo(MODULE_NAME, outputPrefix, "_readdiscstructure_dvd_jis.bin",
"SCSI READ DISC STRUCTURE", scsiInfo.DvdrDlJumpIntervalSize); "SCSI READ DISC STRUCTURE", scsiInfo.DvdrDlJumpIntervalSize);
}
if(scsiInfo.DvdrDlManualLayerJumpStartLba != null) if(scsiInfo.DvdrDlManualLayerJumpStartLba != null)
{
DataFile.WriteTo(MODULE_NAME, outputPrefix, "_readdiscstructure_dvd_manuallj.bin", DataFile.WriteTo(MODULE_NAME, outputPrefix, "_readdiscstructure_dvd_manuallj.bin",
"SCSI READ DISC STRUCTURE", scsiInfo.DvdrDlManualLayerJumpStartLba); "SCSI READ DISC STRUCTURE", scsiInfo.DvdrDlManualLayerJumpStartLba);
}
if(scsiInfo.DvdrDlRemapAnchorPoint != null) if(scsiInfo.DvdrDlRemapAnchorPoint != null)
{
DataFile.WriteTo(MODULE_NAME, outputPrefix, "_readdiscstructure_dvd_remapanchor.bin", DataFile.WriteTo(MODULE_NAME, outputPrefix, "_readdiscstructure_dvd_remapanchor.bin",
"SCSI READ DISC STRUCTURE", scsiInfo.DvdrDlRemapAnchorPoint); "SCSI READ DISC STRUCTURE", scsiInfo.DvdrDlRemapAnchorPoint);
}
if(scsiInfo.BlurayDiscInformation != null) if(scsiInfo.BlurayDiscInformation != null)
{ {
@@ -433,8 +489,10 @@ sealed class MediaInfoCommand : Command
} }
if(scsiInfo.BlurayPac != null) if(scsiInfo.BlurayPac != null)
{
DataFile.WriteTo(MODULE_NAME, outputPrefix, "_readdiscstructure_bd_pac.bin", DataFile.WriteTo(MODULE_NAME, outputPrefix, "_readdiscstructure_bd_pac.bin",
"SCSI READ DISC STRUCTURE", scsiInfo.BlurayPac); "SCSI READ DISC STRUCTURE", scsiInfo.BlurayPac);
}
if(scsiInfo.BlurayBurstCuttingArea != null) if(scsiInfo.BlurayBurstCuttingArea != null)
{ {
@@ -475,8 +533,10 @@ sealed class MediaInfoCommand : Command
} }
if(scsiInfo.BlurayRawDfl != null) if(scsiInfo.BlurayRawDfl != null)
{
DataFile.WriteTo(MODULE_NAME, outputPrefix, "_readdiscstructure_bd_dfl.bin", DataFile.WriteTo(MODULE_NAME, outputPrefix, "_readdiscstructure_bd_dfl.bin",
"SCSI READ DISC STRUCTURE", scsiInfo.BlurayRawDfl); "SCSI READ DISC STRUCTURE", scsiInfo.BlurayRawDfl);
}
if(scsiInfo.BlurayTrackResources != null) if(scsiInfo.BlurayTrackResources != null)
{ {
@@ -502,9 +562,11 @@ sealed class MediaInfoCommand : Command
scsiInfo.Toc); scsiInfo.Toc);
if(scsiInfo.DecodedToc.HasValue) if(scsiInfo.DecodedToc.HasValue)
{
AaruConsole.WriteLine($"[bold]{UI.Title_TOC}:[/]", AaruConsole.WriteLine($"[bold]{UI.Title_TOC}:[/]",
$"\n{Markup.Escape(TOC.Prettify(scsiInfo.DecodedToc))}"); $"\n{Markup.Escape(TOC.Prettify(scsiInfo.DecodedToc))}");
} }
}
if(scsiInfo.Atip != null) if(scsiInfo.Atip != null)
{ {
@@ -512,9 +574,11 @@ sealed class MediaInfoCommand : Command
scsiInfo.Atip); scsiInfo.Atip);
if(scsiInfo.DecodedAtip != null) if(scsiInfo.DecodedAtip != null)
{
AaruConsole.WriteLine($"[bold]{UI.Title_ATIP}:[/]", AaruConsole.WriteLine($"[bold]{UI.Title_ATIP}:[/]",
$"\n{Markup.Escape(ATIP.Prettify(scsiInfo.DecodedAtip))}"); $"\n{Markup.Escape(ATIP.Prettify(scsiInfo.DecodedAtip))}");
} }
}
if(scsiInfo.DiscInformation != null) if(scsiInfo.DiscInformation != null)
{ {
@@ -522,10 +586,12 @@ sealed class MediaInfoCommand : Command
"SCSI READ DISC INFORMATION", scsiInfo.DiscInformation); "SCSI READ DISC INFORMATION", scsiInfo.DiscInformation);
if(scsiInfo.DecodedDiscInformation.HasValue) if(scsiInfo.DecodedDiscInformation.HasValue)
{
AaruConsole.WriteLine($"[bold]{Localization.Core.Standard_Disc_Information}:[/]", AaruConsole.WriteLine($"[bold]{Localization.Core.Standard_Disc_Information}:[/]",
$"\n{Markup.Escape(DiscInformation.Prettify000b(scsiInfo. $"\n{Markup.Escape(DiscInformation.Prettify000b(scsiInfo.
DecodedDiscInformation))}"); DecodedDiscInformation))}");
} }
}
if(scsiInfo.Session != null) if(scsiInfo.Session != null)
{ {
@@ -533,9 +599,11 @@ sealed class MediaInfoCommand : Command
scsiInfo.Session); scsiInfo.Session);
if(scsiInfo.DecodedSession.HasValue) if(scsiInfo.DecodedSession.HasValue)
{
AaruConsole.WriteLine($"[bold]{Localization.Core.Session_information}:[/]", AaruConsole.WriteLine($"[bold]{Localization.Core.Session_information}:[/]",
$"\n{Markup.Escape(Session.Prettify(scsiInfo.DecodedSession))}"); $"\n{Markup.Escape(Session.Prettify(scsiInfo.DecodedSession))}");
} }
}
if(scsiInfo.RawToc != null) if(scsiInfo.RawToc != null)
{ {
@@ -543,9 +611,11 @@ sealed class MediaInfoCommand : Command
scsiInfo.RawToc); scsiInfo.RawToc);
if(scsiInfo.FullToc.HasValue) if(scsiInfo.FullToc.HasValue)
{
AaruConsole.WriteLine($"[bold]{Localization.Core.Raw_TOC}:[/]", AaruConsole.WriteLine($"[bold]{Localization.Core.Raw_TOC}:[/]",
$"\n{Markup.Escape(FullTOC.Prettify(scsiInfo.RawToc))}"); $"\n{Markup.Escape(FullTOC.Prettify(scsiInfo.RawToc))}");
} }
}
if(scsiInfo.Pma != null) if(scsiInfo.Pma != null)
{ {
@@ -562,25 +632,35 @@ sealed class MediaInfoCommand : Command
scsiInfo.CdTextLeadIn); scsiInfo.CdTextLeadIn);
if(scsiInfo.DecodedCdTextLeadIn.HasValue) if(scsiInfo.DecodedCdTextLeadIn.HasValue)
{
AaruConsole.WriteLine($"[bold]{Localization.Core.CD_TEXT_on_Lead_In}:[/]", AaruConsole.WriteLine($"[bold]{Localization.Core.CD_TEXT_on_Lead_In}:[/]",
$"\n{Markup.Escape(CDTextOnLeadIn.Prettify(scsiInfo.DecodedCdTextLeadIn))}"); $"\n{Markup.Escape(CDTextOnLeadIn.Prettify(scsiInfo.DecodedCdTextLeadIn))}");
} }
}
if(!string.IsNullOrEmpty(scsiInfo.Mcn)) if(!string.IsNullOrEmpty(scsiInfo.Mcn))
AaruConsole.WriteLine($"[bold]{Localization.Core.MCN}:[/]", $" {Markup.Escape(scsiInfo.Mcn)}"); AaruConsole.WriteLine($"[bold]{Localization.Core.MCN}:[/]", $" {Markup.Escape(scsiInfo.Mcn)}");
if(scsiInfo.Isrcs != null) if(scsiInfo.Isrcs != null)
{
foreach(KeyValuePair<byte, string> isrc in scsiInfo.Isrcs) foreach(KeyValuePair<byte, string> isrc in scsiInfo.Isrcs)
{
AaruConsole.WriteLine($"[bold]{string.Format(Localization.Core.Tracks_0_ISRC, isrc.Key)}:[/] { AaruConsole.WriteLine($"[bold]{string.Format(Localization.Core.Tracks_0_ISRC, isrc.Key)}:[/] {
Markup.Escape(isrc.Value)}"); Markup.Escape(isrc.Value)}");
}
}
if(scsiInfo.XboxSecuritySector != null) if(scsiInfo.XboxSecuritySector != null)
{
DataFile.WriteTo(MODULE_NAME, outputPrefix, "_xbox_ss.bin", "KREON EXTRACT SS", DataFile.WriteTo(MODULE_NAME, outputPrefix, "_xbox_ss.bin", "KREON EXTRACT SS",
scsiInfo.XboxSecuritySector); scsiInfo.XboxSecuritySector);
}
if(scsiInfo.DecodedXboxSecuritySector.HasValue) if(scsiInfo.DecodedXboxSecuritySector.HasValue)
{
AaruConsole.WriteLine($"[bold]{Localization.Core.Xbox_Security_Sector}:[/]", AaruConsole.WriteLine($"[bold]{Localization.Core.Xbox_Security_Sector}:[/]",
$"\n{Markup.Escape(SS.Prettify(scsiInfo.DecodedXboxSecuritySector))}"); $"\n{Markup.Escape(SS.Prettify(scsiInfo.DecodedXboxSecuritySector))}");
}
if(scsiInfo.XgdInfo != null) if(scsiInfo.XgdInfo != null)
{ {
@@ -612,7 +692,7 @@ sealed class MediaInfoCommand : Command
AaruConsole.Write($"[bold]{Localization.Core.Media_Serial_Number}:[/] "); AaruConsole.Write($"[bold]{Localization.Core.Media_Serial_Number}:[/] ");
for(int i = 4; i < scsiInfo.MediaSerialNumber.Length; i++) for(var i = 4; i < scsiInfo.MediaSerialNumber.Length; i++)
AaruConsole.Write("{0:X2}", scsiInfo.MediaSerialNumber[i]); AaruConsole.Write("{0:X2}", scsiInfo.MediaSerialNumber[i]);
AaruConsole.WriteLine(); AaruConsole.WriteLine();
@@ -629,7 +709,7 @@ sealed class MediaInfoCommand : Command
if(tracks != null) if(tracks != null)
{ {
uint firstLba = (uint)tracks.Min(t => t.StartSector); var firstLba = (uint)tracks.Min(t => t.StartSector);
bool supportsPqSubchannel = Dump.SupportsPqSubchannel(dev, null, null, firstLba); bool supportsPqSubchannel = Dump.SupportsPqSubchannel(dev, null, null, firstLba);
bool supportsRwSubchannel = Dump.SupportsRwSubchannel(dev, null, null, firstLba); bool supportsRwSubchannel = Dump.SupportsRwSubchannel(dev, null, null, firstLba);
@@ -645,7 +725,7 @@ sealed class MediaInfoCommand : Command
Dump.SolveTrackPregaps(dev, null, null, tracks, supportsPqSubchannel, supportsRwSubchannel, dbDev, Dump.SolveTrackPregaps(dev, null, null, tracks, supportsPqSubchannel, supportsRwSubchannel, dbDev,
out bool inexactPositioning, false); out bool inexactPositioning, false);
for(int t = 1; t < tracks.Length; t++) for(var t = 1; t < tracks.Length; t++)
tracks[t - 1].EndSector = tracks[t].StartSector - 1; tracks[t - 1].EndSector = tracks[t].StartSector - 1;
tracks[^1].EndSector = (ulong)lastSector; tracks[^1].EndSector = (ulong)lastSector;
@@ -654,17 +734,21 @@ sealed class MediaInfoCommand : Command
AaruConsole.WriteLine($"[bold]{Localization.Core.Track_calculations}:[/]"); AaruConsole.WriteLine($"[bold]{Localization.Core.Track_calculations}:[/]");
if(inexactPositioning) if(inexactPositioning)
{
AaruConsole.WriteLine($"[yellow]{Localization.Core. AaruConsole.WriteLine($"[yellow]{Localization.Core.
The_drive_has_returned_incorrect_Q_positioning_calculating_pregaps The_drive_has_returned_incorrect_Q_positioning_calculating_pregaps
}[/]"); }[/]");
}
if(firstLba > 0) if(firstLba > 0)
AaruConsole.WriteLine(UI.Hidden_track_starts_at_LBA_0_ends_at_LBA_1, 0, firstLba - 1); AaruConsole.WriteLine(UI.Hidden_track_starts_at_LBA_0_ends_at_LBA_1, 0, firstLba - 1);
foreach(Track track in tracks) foreach(Track track in tracks)
{
AaruConsole. AaruConsole.
WriteLine(UI.Track_0_starts_at_LBA_1_ends_at_LBA_2_has_a_pregap_of_3_sectors_and_is_of_type_4, WriteLine(UI.Track_0_starts_at_LBA_1_ends_at_LBA_2_has_a_pregap_of_3_sectors_and_is_of_type_4,
track.Sequence, track.StartSector, track.EndSector, track.Pregap, track.Type); track.Sequence, track.StartSector, track.EndSector, track.Pregap, track.Type);
}
AaruConsole.WriteLine(); AaruConsole.WriteLine();
AaruConsole.WriteLine($"[bold]{Localization.Core.Offsets}:[/]"); AaruConsole.WriteLine($"[bold]{Localization.Core.Offsets}:[/]");

View File

@@ -51,20 +51,13 @@ sealed class MediaScanCommand : Command
public MediaScanCommand() : base("scan", UI.Media_Scan_Command_Description) public MediaScanCommand() : base("scan", UI.Media_Scan_Command_Description)
{ {
Add(new Option<string>(new[] Add(new Option<string>(new[] { "--mhdd-log", "-m" }, () => null,
{ UI.Write_a_log_of_the_scan_in_the_format_used_by_MHDD));
"--mhdd-log", "-m"
}, () => null, UI.Write_a_log_of_the_scan_in_the_format_used_by_MHDD));
Add(new Option<string>(new[] Add(new Option<string>(new[] { "--ibg-log", "-b" }, () => null,
{ UI.Write_a_log_of_the_scan_in_the_format_used_by_ImgBurn));
"--ibg-log", "-b"
}, () => null, UI.Write_a_log_of_the_scan_in_the_format_used_by_ImgBurn));
Add(new Option<bool>(new[] Add(new Option<bool>(new[] { "--use-buffered-reads" }, () => true, UI.OS_buffered_reads_help));
{
"--use-buffered-reads"
}, () => true, UI.OS_buffered_reads_help));
AddArgument(new Argument<string> AddArgument(new Argument<string>
{ {
@@ -98,6 +91,7 @@ sealed class MediaScanCommand : Command
} }
if(verbose) if(verbose)
{
AaruConsole.WriteEvent += (format, objects) => AaruConsole.WriteEvent += (format, objects) =>
{ {
if(objects is null) if(objects is null)
@@ -105,6 +99,7 @@ sealed class MediaScanCommand : Command
else else
AnsiConsole.Markup(format, objects); AnsiConsole.Markup(format, objects);
}; };
}
Statistics.AddCommand("media-scan"); Statistics.AddCommand("media-scan");
@@ -159,14 +154,12 @@ sealed class MediaScanCommand : Command
AnsiConsole.Progress().AutoClear(true).HideCompleted(true). AnsiConsole.Progress().AutoClear(true).HideCompleted(true).
Columns(new TaskDescriptionColumn(), new ProgressBarColumn(), new PercentageColumn()).Start(ctx => Columns(new TaskDescriptionColumn(), new ProgressBarColumn(), new PercentageColumn()).Start(ctx =>
{ {
scanner.UpdateStatus += text => scanner.UpdateStatus += text => { AaruConsole.WriteLine(Markup.Escape(text)); };
{
AaruConsole.WriteLine(Markup.Escape(text));
};
scanner.StoppingErrorMessage += text => scanner.StoppingErrorMessage += text =>
{ {
AaruConsole.ErrorWriteLine($"[red]{Markup.Escape(text)}[/]"); AaruConsole.
ErrorWriteLine($"[red]{Markup.Escape(text)}[/]");
}; };
scanner.UpdateProgress += (text, current, maximum) => scanner.UpdateProgress += (text, current, maximum) =>
@@ -180,7 +173,8 @@ sealed class MediaScanCommand : Command
scanner.PulseProgress += text => scanner.PulseProgress += text =>
{ {
if(_progressTask1 is null) if(_progressTask1 is null)
ctx.AddTask(Markup.Escape(text)).IsIndeterminate(); ctx.AddTask(Markup.Escape(text)).
IsIndeterminate();
else else
{ {
_progressTask1.Description = Markup.Escape(text); _progressTask1.Description = Markup.Escape(text);
@@ -188,10 +182,7 @@ sealed class MediaScanCommand : Command
} }
}; };
scanner.InitProgress += () => scanner.InitProgress += () => { _progressTask1 = ctx.AddTask("Progress"); };
{
_progressTask1 = ctx.AddTask("Progress");
};
scanner.EndProgress += () => scanner.EndProgress += () =>
{ {
@@ -244,8 +235,10 @@ sealed class MediaScanCommand : Command
results.UnreadableSectors.Count)}[/]"); results.UnreadableSectors.Count)}[/]");
if(results.UnreadableSectors.Count > 0) if(results.UnreadableSectors.Count > 0)
{
foreach(ulong bad in results.UnreadableSectors) foreach(ulong bad in results.UnreadableSectors)
AaruConsole.WriteLine(Localization.Core.Sector_0_could_not_be_read, bad); AaruConsole.WriteLine(Localization.Core.Sector_0_could_not_be_read, bad);
}
AaruConsole.WriteLine(); AaruConsole.WriteLine();
@@ -253,9 +246,11 @@ sealed class MediaScanCommand : Command
results.SeekMin < double.MaxValue || results.SeekMin < double.MaxValue ||
results.SeekMax > double.MinValue) results.SeekMax > double.MinValue)
{
AaruConsole. AaruConsole.
WriteLine(Localization.Core.Testing_0_seeks_longest_seek_took_1_ms_fastest_one_took_2_ms_3_ms_average, WriteLine(Localization.Core.Testing_0_seeks_longest_seek_took_1_ms_fastest_one_took_2_ms_3_ms_average,
results.SeekTimes, results.SeekMax, results.SeekMin, results.SeekTotal / 1000); results.SeekTimes, results.SeekMax, results.SeekMin, results.SeekTotal / 1000);
}
dev.Close(); dev.Close();

View File

@@ -81,6 +81,7 @@ sealed class RemoteCommand : Command
} }
if(verbose) if(verbose)
{
AaruConsole.WriteEvent += (format, objects) => AaruConsole.WriteEvent += (format, objects) =>
{ {
if(objects is null) if(objects is null)
@@ -88,6 +89,7 @@ sealed class RemoteCommand : Command
else else
AnsiConsole.Markup(format, objects); AnsiConsole.Markup(format, objects);
}; };
}
Statistics.AddCommand("remote"); Statistics.AddCommand("remote");

View File

@@ -136,9 +136,11 @@ class MainClass
ExecuteSqlRaw("CREATE TABLE IF NOT EXISTS \"__EFMigrationsHistory\" (\"MigrationId\" TEXT PRIMARY KEY, \"ProductVersion\" TEXT)"); ExecuteSqlRaw("CREATE TABLE IF NOT EXISTS \"__EFMigrationsHistory\" (\"MigrationId\" TEXT PRIMARY KEY, \"ProductVersion\" TEXT)");
foreach(string migration in ctx.Database.GetPendingMigrations()) foreach(string migration in ctx.Database.GetPendingMigrations())
{
ctx.Database. ctx.Database.
ExecuteSqlRaw($"INSERT INTO \"__EFMigrationsHistory\" (MigrationId, ProductVersion) VALUES ('{ ExecuteSqlRaw($"INSERT INTO \"__EFMigrationsHistory\" (MigrationId, ProductVersion) VALUES ('{
migration}', '0.0.0')"); migration}', '0.0.0')");
}
ctx.SaveChanges(); ctx.SaveChanges();
} }
@@ -151,16 +153,18 @@ class MainClass
a.Revision, a.Revision,
a.Bus a.Bus
}).Where(a => a.Count() > 1).Distinct().Select(a => a.Key)) }).Where(a => a.Count() > 1).Distinct().Select(a => a.Key))
{
ctx.RemoveRange(ctx.SeenDevices. ctx.RemoveRange(ctx.SeenDevices.
Where(d => d.Manufacturer == duplicate.Manufacturer && d.Model == duplicate.Model && Where(d => d.Manufacturer == duplicate.Manufacturer && d.Model == duplicate.Model &&
d.Revision == duplicate.Revision && d.Bus == duplicate.Bus).Skip(1)); d.Revision == duplicate.Revision && d.Bus == duplicate.Bus).Skip(1));
}
// Remove nulls // Remove nulls
ctx.RemoveRange(ctx.SeenDevices.Where(d => d.Manufacturer == null && d.Model == null && d.Revision == null)); ctx.RemoveRange(ctx.SeenDevices.Where(d => d.Manufacturer == null && d.Model == null && d.Revision == null));
ctx.SaveChanges(); ctx.SaveChanges();
bool mainDbUpdate = false; var mainDbUpdate = false;
if(!File.Exists(Settings.Settings.MainDbPath)) if(!File.Exists(Settings.Settings.MainDbPath))
{ {
@@ -193,8 +197,8 @@ class MainClass
// GDPR level compliance does not match and there are no arguments or the arguments are neither GUI neither configure. // GDPR level compliance does not match and there are no arguments or the arguments are neither GUI neither configure.
if(Settings.Settings.Current.GdprCompliance < DicSettings.GDPR_LEVEL && if(Settings.Settings.Current.GdprCompliance < DicSettings.GDPR_LEVEL &&
(args.Length < 1 || (args.Length >= 1 && args[0].ToLowerInvariant() != "gui" && (args.Length < 1 || args.Length >= 1 && args[0].ToLowerInvariant() != "gui" &&
args[0].ToLowerInvariant() != "configure"))) args[0].ToLowerInvariant() != "configure"))
new ConfigureCommand().DoConfigure(true); new ConfigureCommand().DoConfigure(true);
Statistics.LoadStats(); Statistics.LoadStats();
@@ -203,20 +207,13 @@ class MainClass
var rootCommand = new RootCommand(); var rootCommand = new RootCommand();
rootCommand.AddGlobalOption(new Option<bool>(new[] rootCommand.AddGlobalOption(new Option<bool>(new[] { "--verbose", "-v" }, () => false,
{ UI.Shows_verbose_output));
"--verbose", "-v"
}, () => false, UI.Shows_verbose_output));
rootCommand.AddGlobalOption(new Option<bool>(new[] rootCommand.AddGlobalOption(new Option<bool>(new[] { "--debug", "-d" }, () => false,
{ UI.Shows_debug_output_from_plugins));
"--debug", "-d"
}, () => false, UI.Shows_debug_output_from_plugins));
Option<bool> pauseOption = new(new[] Option<bool> pauseOption = new(new[] { "--pause" }, () => false, UI.Pauses_before_exiting);
{
"--pause"
}, () => false, UI.Pauses_before_exiting);
rootCommand.AddGlobalOption(pauseOption); rootCommand.AddGlobalOption(pauseOption);

View File

@@ -3,8 +3,8 @@
"Aaru": { "Aaru": {
"commandName": "Project" "commandName": "Project"
}, },
"GUI" : { "GUI": {
"commandName" : "Project", "commandName": "Project",
"commandLineArgs": "gui -d" "commandLineArgs": "gui -d"
} }
} }

View File

@@ -3,76 +3,96 @@
## Added ## Added
### - Adler checksum ### - Adler checksum
- SSSE3 implementation if supported by running host. - SSSE3 implementation if supported by running host.
### - Apple Data Compression algorithm ### - Apple Data Compression algorithm
- Use faster native library if supported by running host. - Use faster native library if supported by running host.
### - Apple RLE compression algorithm ### - Apple RLE compression algorithm
- Use faster native library if supported by running host. - Use faster native library if supported by running host.
### - Apple Universal Disk Image Format ### - Apple Universal Disk Image Format
- Support for LZFSE compressed images (ULFO). - Support for LZFSE compressed images (ULFO).
- Support for XZ compressed images (ULMO). - Support for XZ compressed images (ULMO).
### - Atari Lynx cartridge dumps ### - Atari Lynx cartridge dumps
- Dumping by supported hardware. - Dumping by supported hardware.
- Support by `print`, `convert`, `info`, `entropy`, `checksum`, `compare` and `create sidecar` commands. - Support by `print`, `convert`, `info`, `entropy`, `checksum`, `compare` and `create sidecar` commands.
### - BZIP2 compression algorithm ### - BZIP2 compression algorithm
- Faster non-native implementation. - Faster non-native implementation.
- Use faster native library if supported by running host. - Use faster native library if supported by running host.
### - Console ### - Console
- Use new console system that allows to show colors, tables and progress bars in command line. - Use new console system that allows to show colors, tables and progress bars in command line.
### - CRC32 checksum ### - CRC32 checksum
- ARM specific instructions if supported by running host. - ARM specific instructions if supported by running host.
- PCLMUL implementation if supported by running host. - PCLMUL implementation if supported by running host.
### - CRC64 checksum ### - CRC64 checksum
- PCLMUL implementation if supported by running host. - PCLMUL implementation if supported by running host.
### - Dumping ### - Dumping
- Draw the MHDD log as an image. - Draw the MHDD log as an image.
- For most spiral media (CD/DVD/BD) draw a graph with the dump status. - For most spiral media (CD/DVD/BD) draw a graph with the dump status.
- For non-spiral media draw a block map. - For non-spiral media draw a block map.
### - FLAC compression algorithm ### - FLAC compression algorithm
- Use faster native library if supported by running host. - Use faster native library if supported by running host.
### - LZFSE compression algorithm ### - LZFSE compression algorithm
- Now available if native library is supported by running host. - Now available if native library is supported by running host.
### - LZMA compression algorithm ### - LZMA compression algorithm
- Use faster native library if supported by running host. - Use faster native library if supported by running host.
### - LZIP compression algorithm ### - LZIP compression algorithm
- Use faster native library if supported by running host. - Use faster native library if supported by running host.
### - NES / Famicom cartridge dumps ### - NES / Famicom cartridge dumps
- Dumping by supported hardware. - Dumping by supported hardware.
- Support by `print`, `convert`, `info`, `entropy`, `checksum`, `compare` and `create sidecar` commands. - Support by `print`, `convert`, `info`, `entropy`, `checksum`, `compare` and `create sidecar` commands.
- Support for iNES and NES 2.0 formats - Support for iNES and NES 2.0 formats
### - Nintendo 64 cartridge dumps ### - Nintendo 64 cartridge dumps
- Dumping by supported hardware. - Dumping by supported hardware.
- Support by `print`, `convert`, `info`, `entropy`, `checksum`, `compare` and `create sidecar` commands. - Support by `print`, `convert`, `info`, `entropy`, `checksum`, `compare` and `create sidecar` commands.
- Support for `z64` and `n64` formats. - Support for `z64` and `n64` formats.
### - Nintendo Game Boy cartridge dumps ### - Nintendo Game Boy cartridge dumps
- Dumping by supported hardware. - Dumping by supported hardware.
- Support by `print`, `convert`, `info`, `entropy`, `checksum`, `compare` and `create sidecar` commands. - Support by `print`, `convert`, `info`, `entropy`, `checksum`, `compare` and `create sidecar` commands.
### - Nintendo Game Boy Advance cartridge dumps ### - Nintendo Game Boy Advance cartridge dumps
- Dumping by supported hardware. - Dumping by supported hardware.
- Support by `print`, `convert`, `info`, `entropy`, `checksum`, `compare` and `create sidecar` commands. - Support by `print`, `convert`, `info`, `entropy`, `checksum`, `compare` and `create sidecar` commands.
### - Nintendo Game Boy Color cartridge dumps ### - Nintendo Game Boy Color cartridge dumps
- Dumping by supported hardware. - Dumping by supported hardware.
- Support by `print`, `convert`, `info`, `entropy`, `checksum`, `compare` and `create sidecar` commands. - Support by `print`, `convert`, `info`, `entropy`, `checksum`, `compare` and `create sidecar` commands.
### - Retrode cartridge dumping hardware ### - Retrode cartridge dumping hardware
- Dumping Nintendo 64 cartridges. - Dumping Nintendo 64 cartridges.
- Dumping Nintendo Game Boy cartridges. - Dumping Nintendo Game Boy cartridges.
- Dumping Nintendo Game Boy Advance cartridges. - Dumping Nintendo Game Boy Advance cartridges.
@@ -83,34 +103,42 @@
- Dumping Super Nintendo / Super Famicom cartridges. - Dumping Super Nintendo / Super Famicom cartridges.
### - Sega 32X cartridge dumps ### - Sega 32X cartridge dumps
- Support by `print`, `convert`, `info`, `entropy`, `checksum`, `compare` and `create sidecar` commands. - Support by `print`, `convert`, `info`, `entropy`, `checksum`, `compare` and `create sidecar` commands.
- Dumping by supported hardware. - Dumping by supported hardware.
### - Sega Game Gear cartridge dumps ### - Sega Game Gear cartridge dumps
- Support by `print`, `convert`, `info`, `entropy`, `checksum`, `compare` and `create sidecar` commands. - Support by `print`, `convert`, `info`, `entropy`, `checksum`, `compare` and `create sidecar` commands.
- Dumping by supported hardware. - Dumping by supported hardware.
### - Sega Master System / Mark III cartridge dumps ### - Sega Master System / Mark III cartridge dumps
- Support by `print`, `convert`, `info`, `entropy`, `checksum`, `compare` and `create sidecar` commands. - Support by `print`, `convert`, `info`, `entropy`, `checksum`, `compare` and `create sidecar` commands.
- Dumping by supported hardware. - Dumping by supported hardware.
### - Sega Mega Drive / Genesis cartridge dumps ### - Sega Mega Drive / Genesis cartridge dumps
- Full support for converting between `smd` and `bin` formats. - Full support for converting between `smd` and `bin` formats.
- Support by `print`, `convert`, `info`, `entropy`, `checksum`, `compare` and `create sidecar` commands. - Support by `print`, `convert`, `info`, `entropy`, `checksum`, `compare` and `create sidecar` commands.
- Dumping by supported hardware. - Dumping by supported hardware.
### - Sega Pico cartridge dumps ### - Sega Pico cartridge dumps
- Support by `print`, `convert`, `info`, `entropy`, `checksum`, `compare` and `create sidecar` commands. - Support by `print`, `convert`, `info`, `entropy`, `checksum`, `compare` and `create sidecar` commands.
- Dumping by supported hardware. - Dumping by supported hardware.
### - Super Nintendo / Super Famicom cartridge dumps ### - Super Nintendo / Super Famicom cartridge dumps
- Support by `print`, `convert`, `info`, `entropy`, `checksum`, `compare` and `create sidecar` commands. - Support by `print`, `convert`, `info`, `entropy`, `checksum`, `compare` and `create sidecar` commands.
- Dumping by supported hardware. - Dumping by supported hardware.
### - ZSTD compression algorithm ### - ZSTD compression algorithm
- Now available if native library is supported by running host. - Now available if native library is supported by running host.
## Changes ## Changes
- All used checksums now call a much faster native library if supported. - All used checksums now call a much faster native library if supported.
- CICM metadata XML sidecars are deprecated, new more complete JSON format is used instead. - CICM metadata XML sidecars are deprecated, new more complete JSON format is used instead.
- Remove FreeBSD support code. Use `aaruremote` for dumping devices connected to FreeBSD systems. - Remove FreeBSD support code. Use `aaruremote` for dumping devices connected to FreeBSD systems.
@@ -122,45 +150,57 @@
## Fixed ## Fixed
### - Aaru Image Format ### - Aaru Image Format
- DDT verification when its size on-image is bigger than 1MiB. - DDT verification when its size on-image is bigger than 1MiB.
- Parent block identifier in AaruFormat. - Parent block identifier in AaruFormat.
- Track indexes in when a disc contains a hidden track. - Track indexes in when a disc contains a hidden track.
### - Apple DOS filesystem ### - Apple DOS filesystem
- Calculation of file sizes - Calculation of file sizes
### - Apple Macintosh filesystem ### - Apple Macintosh filesystem
- Calculation of file sizes - Calculation of file sizes
### - BlindWrite 5/6/7 disc images ### - BlindWrite 5/6/7 disc images
- Opening split images in Windows - Opening split images in Windows
### - CDRWin cuesheet disc images ### - CDRWin cuesheet disc images
- Do not report ISRC as present if no tracks contain ISRC data. - Do not report ISRC as present if no tracks contain ISRC data.
### - Device report ### - Device report
- Add workaround for device report the AccessTek/Optorite DD0203 drive. - Add workaround for device report the AccessTek/Optorite DD0203 drive.
### - Devices ### - Devices
- Add transfer size to ATA(PI) IDENTIFY (PACKET) DEVICE commands as required by a recent change in the Linux kernel API. - Add transfer size to ATA(PI) IDENTIFY (PACKET) DEVICE commands as required by a recent change in the Linux kernel API.
### - Dumping ### - Dumping
- Correct offset fixing when trimming or re-reading errored audio sectors. - Correct offset fixing when trimming or re-reading errored audio sectors.
- Do not set INDEX 1 to a value higher than what the TOC already said. - Do not set INDEX 1 to a value higher than what the TOC already said.
### - FAT filesystem ### - FAT filesystem
- Fix that first 2 FAT entries are not considered part of the allocation ones, allocating two more. - Fix that first 2 FAT entries are not considered part of the allocation ones, allocating two more.
- Return current clusters when a file overflows the FAT. - Return current clusters when a file overflows the FAT.
### - ISO9660 filesystem ### - ISO9660 filesystem
- Do not try to interpret an 0-length Continuation Area. - Do not try to interpret an 0-length Continuation Area.
### - SGI Volume Header ### - SGI Volume Header
- Partition types not properly interpreted. - Partition types not properly interpreted.
## Changes ## Changes
- Do not allow dumping or converting to image formats that do not properly support hidden tracks when there is a hidden track in the media. - Do not allow dumping or converting to image formats that do not properly support hidden tracks when there is a hidden
track in the media.
- Update Newtonson.Json dependency due to security issues. - Update Newtonson.Json dependency due to security issues.
# [5.3.1] - 2022-03-06 # [5.3.1] - 2022-03-06
@@ -192,11 +232,13 @@
### - Dumping ### - Dumping
- Fix detecting errors from OS buffered reads in Linux. - Fix detecting errors from OS buffered reads in Linux.
- When dumping an SD/MMC card try to detect if OS buffered reads are failing, and max readable blocks using sequential commands, and downgrade accordingly. Now also detects cards that are totally unreadable. - When dumping an SD/MMC card try to detect if OS buffered reads are failing, and max readable blocks using sequential
commands, and downgrade accordingly. Now also detects cards that are totally unreadable.
### - ISO9660 filesystem ### - ISO9660 filesystem
- Do not break when an ISO9660/HighSierra/CD-i directory spans several sectors if we only have a partial last sector read. - Do not break when an ISO9660/HighSierra/CD-i directory spans several sectors if we only have a partial last sector
read.
- Do not try to decode empty path table in ISO9660/CD-i/HighSierra. - Do not try to decode empty path table in ISO9660/CD-i/HighSierra.
### - Media detection ### - Media detection