mirror of
https://github.com/aaru-dps/Aaru.git
synced 2025-12-16 19:24:25 +00:00
[Aaru] Reformat and cleanup.
This commit is contained in:
@@ -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>
|
||||||
|
|||||||
@@ -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");
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|
||||||
|
|||||||
@@ -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 =>
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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");
|
||||||
|
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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}");
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
@@ -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);
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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}:[/]");
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|
||||||
|
|||||||
@@ -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");
|
||||||
|
|
||||||
|
|||||||
27
Aaru/Main.cs
27
Aaru/Main.cs
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -3,8 +3,8 @@
|
|||||||
"Aaru": {
|
"Aaru": {
|
||||||
"commandName": "Project"
|
"commandName": "Project"
|
||||||
},
|
},
|
||||||
"GUI" : {
|
"GUI": {
|
||||||
"commandName" : "Project",
|
"commandName": "Project",
|
||||||
"commandLineArgs": "gui -d"
|
"commandLineArgs": "gui -d"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
48
Changelog.md
48
Changelog.md
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user