2020-04-17 21:45:50 +01:00
|
|
|
// /***************************************************************************
|
|
|
|
|
// Aaru Data Preservation Suite
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
//
|
|
|
|
|
// Filename : ImageConvertViewModel.cs
|
|
|
|
|
// Author(s) : Natalia Portillo <claunia@claunia.com>
|
|
|
|
|
//
|
|
|
|
|
// Component : GUI view models.
|
|
|
|
|
//
|
|
|
|
|
// --[ Description ] ----------------------------------------------------------
|
|
|
|
|
//
|
|
|
|
|
// View model and code for the image conversion window.
|
|
|
|
|
//
|
|
|
|
|
// --[ License ] --------------------------------------------------------------
|
|
|
|
|
//
|
|
|
|
|
// This program is free software: you can redistribute it and/or modify
|
|
|
|
|
// it under the terms of the GNU General public License as
|
|
|
|
|
// published by the Free Software Foundation, either version 3 of the
|
|
|
|
|
// License, or (at your option) any later version.
|
|
|
|
|
//
|
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
// GNU General public License for more details.
|
|
|
|
|
//
|
|
|
|
|
// You should have received a copy of the GNU General public License
|
|
|
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
//
|
|
|
|
|
// ----------------------------------------------------------------------------
|
2024-12-19 10:45:18 +00:00
|
|
|
// Copyright © 2011-2025 Natalia Portillo
|
2020-04-17 21:45:50 +01:00
|
|
|
// ****************************************************************************/
|
|
|
|
|
|
2020-04-13 04:40:35 +01:00
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Collections.ObjectModel;
|
2022-11-15 01:35:06 +00:00
|
|
|
using System.Diagnostics.CodeAnalysis;
|
2020-04-13 04:40:35 +01:00
|
|
|
using System.IO;
|
|
|
|
|
using System.Linq;
|
2020-07-14 02:16:53 +01:00
|
|
|
using System.Text;
|
2022-12-16 03:05:50 +00:00
|
|
|
using System.Text.Json;
|
2020-04-13 04:40:35 +01:00
|
|
|
using System.Threading;
|
2022-03-26 16:52:00 +00:00
|
|
|
using System.Threading.Tasks;
|
2025-08-20 21:19:43 +01:00
|
|
|
using System.Windows.Input;
|
2023-10-05 13:47:59 +01:00
|
|
|
using Aaru.CommonTypes;
|
2022-12-15 22:21:07 +00:00
|
|
|
using Aaru.CommonTypes.AaruMetadata;
|
2020-04-13 04:40:35 +01:00
|
|
|
using Aaru.CommonTypes.Enums;
|
|
|
|
|
using Aaru.CommonTypes.Interfaces;
|
|
|
|
|
using Aaru.CommonTypes.Metadata;
|
|
|
|
|
using Aaru.Core;
|
2020-07-14 02:16:53 +01:00
|
|
|
using Aaru.Core.Media;
|
|
|
|
|
using Aaru.Devices;
|
2020-04-13 04:40:35 +01:00
|
|
|
using Aaru.Gui.Models;
|
2022-11-19 21:10:41 +00:00
|
|
|
using Aaru.Localization;
|
2025-08-17 05:50:25 +01:00
|
|
|
using Aaru.Logging;
|
2020-04-13 04:40:35 +01:00
|
|
|
using Avalonia.Controls;
|
2024-05-02 00:50:34 +01:00
|
|
|
using Avalonia.Platform.Storage;
|
2020-04-13 04:40:35 +01:00
|
|
|
using Avalonia.Threading;
|
2025-08-20 21:19:43 +01:00
|
|
|
using CommunityToolkit.Mvvm.ComponentModel;
|
|
|
|
|
using CommunityToolkit.Mvvm.Input;
|
2023-09-26 01:29:07 +01:00
|
|
|
using MsBox.Avalonia;
|
|
|
|
|
using MsBox.Avalonia.Enums;
|
2025-08-20 18:51:05 +01:00
|
|
|
using Sentry;
|
2020-04-13 04:40:35 +01:00
|
|
|
using ImageInfo = Aaru.CommonTypes.Structs.ImageInfo;
|
2022-12-15 22:21:07 +00:00
|
|
|
using Track = Aaru.CommonTypes.Structs.Track;
|
2020-04-13 04:40:35 +01:00
|
|
|
using Version = Aaru.CommonTypes.Interop.Version;
|
|
|
|
|
|
2022-11-15 15:58:43 +00:00
|
|
|
namespace Aaru.Gui.ViewModels.Windows;
|
|
|
|
|
|
2022-11-15 01:35:06 +00:00
|
|
|
[SuppressMessage("ReSharper", "AsyncVoidLambda")]
|
2025-08-20 21:19:43 +01:00
|
|
|
public sealed partial class ImageConvertViewModel : ViewModelBase
|
2020-04-13 04:40:35 +01:00
|
|
|
{
|
2022-12-15 22:21:07 +00:00
|
|
|
readonly IMediaImage _inputFormat;
|
|
|
|
|
readonly Window _view;
|
2025-08-20 21:19:43 +01:00
|
|
|
[ObservableProperty]
|
|
|
|
|
Metadata _aaruMetadata;
|
|
|
|
|
[ObservableProperty]
|
|
|
|
|
bool _aaruMetadataFromImageVisible;
|
|
|
|
|
[ObservableProperty]
|
|
|
|
|
bool _cancel;
|
|
|
|
|
[ObservableProperty]
|
|
|
|
|
bool _closeVisible;
|
|
|
|
|
[ObservableProperty]
|
|
|
|
|
string _commentsText;
|
|
|
|
|
[ObservableProperty]
|
|
|
|
|
bool _commentsVisible;
|
|
|
|
|
[ObservableProperty]
|
|
|
|
|
string _creatorText;
|
|
|
|
|
[ObservableProperty]
|
|
|
|
|
bool _creatorVisible;
|
|
|
|
|
[ObservableProperty]
|
|
|
|
|
bool _destinationEnabled;
|
|
|
|
|
[ObservableProperty]
|
|
|
|
|
string _destinationText;
|
|
|
|
|
[ObservableProperty]
|
|
|
|
|
bool _destinationVisible;
|
|
|
|
|
[ObservableProperty]
|
|
|
|
|
string _driveFirmwareRevisionText;
|
|
|
|
|
[ObservableProperty]
|
|
|
|
|
bool _driveFirmwareRevisionVisible;
|
|
|
|
|
[ObservableProperty]
|
|
|
|
|
string _driveManufacturerText;
|
|
|
|
|
[ObservableProperty]
|
|
|
|
|
bool _driveManufacturerVisible;
|
|
|
|
|
[ObservableProperty]
|
|
|
|
|
string _driveModelText;
|
|
|
|
|
[ObservableProperty]
|
|
|
|
|
bool _driveModelVisible;
|
|
|
|
|
[ObservableProperty]
|
|
|
|
|
string _driveSerialNumberText;
|
|
|
|
|
[ObservableProperty]
|
|
|
|
|
bool _driveSerialNumberVisible;
|
|
|
|
|
[ObservableProperty]
|
|
|
|
|
List<DumpHardware> _dumpHardware;
|
|
|
|
|
[ObservableProperty]
|
|
|
|
|
bool _forceChecked;
|
|
|
|
|
[ObservableProperty]
|
|
|
|
|
bool _formatReadOnly;
|
|
|
|
|
[ObservableProperty]
|
|
|
|
|
double _lastMediaSequenceValue;
|
|
|
|
|
[ObservableProperty]
|
|
|
|
|
bool _lastMediaSequenceVisible;
|
|
|
|
|
[ObservableProperty]
|
|
|
|
|
string _mediaBarcodeText;
|
|
|
|
|
[ObservableProperty]
|
|
|
|
|
bool _mediaBarcodeVisible;
|
|
|
|
|
[ObservableProperty]
|
|
|
|
|
string _mediaManufacturerText;
|
|
|
|
|
[ObservableProperty]
|
|
|
|
|
bool _mediaManufacturerVisible;
|
|
|
|
|
[ObservableProperty]
|
|
|
|
|
string _mediaModelText;
|
|
|
|
|
[ObservableProperty]
|
|
|
|
|
bool _mediaModelVisible;
|
|
|
|
|
[ObservableProperty]
|
|
|
|
|
string _mediaPartNumberText;
|
|
|
|
|
[ObservableProperty]
|
|
|
|
|
bool _mediaPartNumberVisible;
|
|
|
|
|
[ObservableProperty]
|
|
|
|
|
double _mediaSequenceValue;
|
|
|
|
|
[ObservableProperty]
|
|
|
|
|
bool _mediaSequenceVisible;
|
|
|
|
|
[ObservableProperty]
|
|
|
|
|
string _mediaSerialNumberText;
|
|
|
|
|
[ObservableProperty]
|
|
|
|
|
bool _mediaSerialNumberVisible;
|
|
|
|
|
[ObservableProperty]
|
|
|
|
|
string _mediaTitleText;
|
|
|
|
|
[ObservableProperty]
|
|
|
|
|
bool _mediaTitleVisible;
|
|
|
|
|
[ObservableProperty]
|
|
|
|
|
string _metadataJsonText;
|
|
|
|
|
[ObservableProperty]
|
|
|
|
|
bool _optionsVisible;
|
|
|
|
|
[ObservableProperty]
|
|
|
|
|
bool _progress1Visible;
|
|
|
|
|
[ObservableProperty]
|
|
|
|
|
bool _progress2Indeterminate;
|
|
|
|
|
[ObservableProperty]
|
|
|
|
|
double _progress2MaxValue;
|
|
|
|
|
[ObservableProperty]
|
|
|
|
|
string _progress2Text;
|
|
|
|
|
[ObservableProperty]
|
|
|
|
|
double _progress2Value;
|
|
|
|
|
[ObservableProperty]
|
|
|
|
|
bool _progress2Visible;
|
|
|
|
|
[ObservableProperty]
|
|
|
|
|
bool _progressIndeterminate;
|
|
|
|
|
[ObservableProperty]
|
|
|
|
|
double _progressMaxValue;
|
|
|
|
|
[ObservableProperty]
|
|
|
|
|
string _progressText;
|
|
|
|
|
[ObservableProperty]
|
|
|
|
|
double _progressValue;
|
|
|
|
|
[ObservableProperty]
|
|
|
|
|
bool _progressVisible;
|
|
|
|
|
[ObservableProperty]
|
|
|
|
|
bool _resumeFileFromImageVisible;
|
|
|
|
|
[ObservableProperty]
|
|
|
|
|
string _resumeFileText;
|
|
|
|
|
[ObservableProperty]
|
|
|
|
|
double _sectorsValue;
|
|
|
|
|
[ObservableProperty]
|
|
|
|
|
ImagePluginModel _selectedPlugin;
|
|
|
|
|
[ObservableProperty]
|
|
|
|
|
string _sourceText;
|
|
|
|
|
[ObservableProperty]
|
|
|
|
|
bool _startVisible;
|
|
|
|
|
[ObservableProperty]
|
|
|
|
|
bool _stopEnabled;
|
|
|
|
|
[ObservableProperty]
|
|
|
|
|
bool _stopVisible;
|
|
|
|
|
[ObservableProperty]
|
|
|
|
|
string _title;
|
2022-03-06 13:29:38 +00:00
|
|
|
|
2022-11-15 01:35:06 +00:00
|
|
|
public ImageConvertViewModel([JetBrains.Annotations.NotNull] IMediaImage inputFormat, string imageSource,
|
2023-10-03 23:27:57 +01:00
|
|
|
Window view)
|
2022-03-06 13:29:38 +00:00
|
|
|
{
|
|
|
|
|
_view = view;
|
|
|
|
|
_inputFormat = inputFormat;
|
|
|
|
|
_cancel = false;
|
2025-08-20 21:19:43 +01:00
|
|
|
DestinationCommand = new AsyncRelayCommand(DestinationAsync);
|
|
|
|
|
CreatorCommand = new RelayCommand(Creator);
|
|
|
|
|
MediaTitleCommand = new RelayCommand(MediaTitle);
|
|
|
|
|
MediaManufacturerCommand = new RelayCommand(MediaManufacturer);
|
|
|
|
|
MediaModelCommand = new RelayCommand(MediaModel);
|
|
|
|
|
MediaSerialNumberCommand = new RelayCommand(MediaSerialNumber);
|
|
|
|
|
MediaBarcodeCommand = new RelayCommand(MediaBarcode);
|
|
|
|
|
MediaPartNumberCommand = new RelayCommand(MediaPartNumber);
|
|
|
|
|
MediaSequenceCommand = new RelayCommand(MediaSequence);
|
|
|
|
|
LastMediaSequenceCommand = new RelayCommand(LastMediaSequence);
|
|
|
|
|
DriveManufacturerCommand = new RelayCommand(DriveManufacturer);
|
|
|
|
|
DriveModelCommand = new RelayCommand(DriveModel);
|
|
|
|
|
DriveSerialNumberCommand = new RelayCommand(DriveSerialNumber);
|
|
|
|
|
DriveFirmwareRevisionCommand = new RelayCommand(DriveFirmwareRevision);
|
|
|
|
|
CommentsCommand = new RelayCommand(Comments);
|
|
|
|
|
AaruMetadataFromImageCommand = new RelayCommand(AaruMetadataFromImage);
|
|
|
|
|
AaruMetadataCommand = new AsyncRelayCommand(AaruMetadataAsync);
|
|
|
|
|
ResumeFileFromImageCommand = new RelayCommand(ResumeFileFromImage);
|
|
|
|
|
ResumeFileCommand = new AsyncRelayCommand(ResumeFileAsync);
|
|
|
|
|
StartCommand = new AsyncRelayCommand(StartAsync);
|
|
|
|
|
CloseCommand = new RelayCommand(Close);
|
|
|
|
|
StopCommand = new RelayCommand(Stop);
|
2022-03-06 13:29:38 +00:00
|
|
|
SourceText = imageSource;
|
|
|
|
|
CreatorVisible = !string.IsNullOrWhiteSpace(inputFormat.Info.Creator);
|
|
|
|
|
MediaTitleVisible = !string.IsNullOrWhiteSpace(inputFormat.Info.MediaTitle);
|
|
|
|
|
CommentsVisible = !string.IsNullOrWhiteSpace(inputFormat.Info.Comments);
|
|
|
|
|
MediaManufacturerVisible = !string.IsNullOrWhiteSpace(inputFormat.Info.MediaManufacturer);
|
|
|
|
|
MediaModelVisible = !string.IsNullOrWhiteSpace(inputFormat.Info.MediaModel);
|
|
|
|
|
MediaSerialNumberVisible = !string.IsNullOrWhiteSpace(inputFormat.Info.MediaSerialNumber);
|
|
|
|
|
MediaBarcodeVisible = !string.IsNullOrWhiteSpace(inputFormat.Info.MediaBarcode);
|
|
|
|
|
MediaPartNumberVisible = !string.IsNullOrWhiteSpace(inputFormat.Info.MediaPartNumber);
|
|
|
|
|
MediaSequenceVisible = inputFormat.Info.MediaSequence != 0 && inputFormat.Info.LastMediaSequence != 0;
|
|
|
|
|
LastMediaSequenceVisible = inputFormat.Info.MediaSequence != 0 && inputFormat.Info.LastMediaSequence != 0;
|
|
|
|
|
DriveManufacturerVisible = !string.IsNullOrWhiteSpace(inputFormat.Info.DriveManufacturer);
|
|
|
|
|
DriveModelVisible = !string.IsNullOrWhiteSpace(inputFormat.Info.DriveModel);
|
|
|
|
|
DriveSerialNumberVisible = !string.IsNullOrWhiteSpace(inputFormat.Info.DriveSerialNumber);
|
|
|
|
|
DriveFirmwareRevisionVisible = !string.IsNullOrWhiteSpace(inputFormat.Info.DriveFirmwareRevision);
|
|
|
|
|
|
2023-10-05 13:47:59 +01:00
|
|
|
PluginRegister plugins = PluginRegister.Singleton;
|
2022-03-06 13:29:38 +00:00
|
|
|
|
2023-10-06 00:40:44 +01:00
|
|
|
foreach(IBaseWritableImage plugin in plugins.WritableImages.Values)
|
2022-12-17 19:50:32 +00:00
|
|
|
{
|
2024-05-01 04:05:22 +01:00
|
|
|
if(plugin is null) continue;
|
2022-12-17 19:50:32 +00:00
|
|
|
|
|
|
|
|
if(plugin.SupportedMediaTypes.Contains(inputFormat.Info.MediaType))
|
2023-10-03 23:27:57 +01:00
|
|
|
{
|
2022-12-17 19:50:32 +00:00
|
|
|
PluginsList.Add(new ImagePluginModel
|
|
|
|
|
{
|
|
|
|
|
Plugin = plugin
|
|
|
|
|
});
|
2023-10-03 23:27:57 +01:00
|
|
|
}
|
2022-12-17 19:50:32 +00:00
|
|
|
}
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-12-15 22:21:07 +00:00
|
|
|
AaruMetadataFromImageVisible = inputFormat.AaruMetadata != null;
|
|
|
|
|
ResumeFileFromImageVisible = inputFormat.DumpHardware?.Any() == true;
|
|
|
|
|
_aaruMetadata = inputFormat.AaruMetadata;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
_dumpHardware = inputFormat.DumpHardware?.Any() == true ? inputFormat.DumpHardware : null;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-12-15 22:21:07 +00:00
|
|
|
MetadataJsonText = _aaruMetadata == null ? "" : UI._From_image_;
|
|
|
|
|
ResumeFileText = _dumpHardware == null ? "" : UI._From_image_;
|
2022-03-06 13:29:38 +00:00
|
|
|
}
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2025-08-20 21:19:43 +01:00
|
|
|
public string SourceImageLabel => UI.Source_image;
|
|
|
|
|
public string OutputFormatLabel => UI.Output_format;
|
|
|
|
|
public string ChooseLabel => UI.ButtonLabel_Choose;
|
|
|
|
|
public string SectorsLabel => UI.How_many_sectors_to_convert_at_once;
|
|
|
|
|
public string ForceLabel => UI.Continue_conversion_even_if_data_lost;
|
|
|
|
|
public string CreatorLabel => UI.Who_person_created_the_image;
|
|
|
|
|
public string GetFromSourceImageLabel => UI.ButtonLabel_Get_from_source_image;
|
|
|
|
|
public string MetadataLabel => UI.Title_Metadata;
|
|
|
|
|
public string MediaLabel => UI.Title_Media;
|
|
|
|
|
public string TitleLabel => UI.Title_Title;
|
|
|
|
|
public string ManufacturerLabel => UI.Title_Manufacturer;
|
|
|
|
|
public string ModelLabel => UI.Title_Model;
|
|
|
|
|
public string SerialNumberLabel => UI.Title_Serial_number;
|
|
|
|
|
public string BarcodeLabel => UI.Title_Barcode;
|
|
|
|
|
public string PartNumberLabel => UI.Title_Part_number;
|
|
|
|
|
public string NumberInSequenceLabel => UI.Title_Number_in_sequence;
|
|
|
|
|
public string LastMediaOfTheSequenceLabel => UI.Title_Last_media_of_the_sequence;
|
|
|
|
|
public string DriveLabel => UI.Title_Drive;
|
|
|
|
|
public string FirmwareRevisionLabel => UI.Title_Firmware_revision;
|
|
|
|
|
public string CommentsLabel => UI.Title_Comments;
|
|
|
|
|
public string AaruMetadataLabel => UI.Title_Existing_Aaru_Metadata_sidecar;
|
|
|
|
|
public string FromImageLabel => UI.Title_From_image;
|
|
|
|
|
public string ResumeFileLabel => UI.Title_Existing_resume_file;
|
|
|
|
|
public string StartLabel => UI.ButtonLabel_Start;
|
|
|
|
|
public string CloseLabel => UI.ButtonLabel_Close;
|
|
|
|
|
public string StopLabel => UI.ButtonLabel_Stop;
|
2022-03-06 13:29:38 +00:00
|
|
|
public ObservableCollection<ImagePluginModel> PluginsList { get; }
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2025-08-20 21:19:43 +01:00
|
|
|
public ICommand DestinationCommand { get; }
|
|
|
|
|
public ICommand CreatorCommand { get; }
|
|
|
|
|
public ICommand MediaTitleCommand { get; }
|
|
|
|
|
public ICommand MediaManufacturerCommand { get; }
|
|
|
|
|
public ICommand MediaModelCommand { get; }
|
|
|
|
|
public ICommand MediaSerialNumberCommand { get; }
|
|
|
|
|
public ICommand MediaBarcodeCommand { get; }
|
|
|
|
|
public ICommand MediaPartNumberCommand { get; }
|
|
|
|
|
public ICommand MediaSequenceCommand { get; }
|
|
|
|
|
public ICommand LastMediaSequenceCommand { get; }
|
|
|
|
|
public ICommand DriveManufacturerCommand { get; }
|
|
|
|
|
public ICommand DriveModelCommand { get; }
|
|
|
|
|
public ICommand DriveSerialNumberCommand { get; }
|
|
|
|
|
public ICommand DriveFirmwareRevisionCommand { get; }
|
|
|
|
|
public ICommand CommentsCommand { get; }
|
|
|
|
|
public ICommand AaruMetadataFromImageCommand { get; }
|
|
|
|
|
public ICommand AaruMetadataCommand { get; }
|
|
|
|
|
public ICommand ResumeFileFromImageCommand { get; }
|
|
|
|
|
public ICommand ResumeFileCommand { get; }
|
|
|
|
|
public ICommand StartCommand { get; }
|
|
|
|
|
public ICommand CloseCommand { get; }
|
|
|
|
|
public ICommand StopCommand { get; }
|
|
|
|
|
|
|
|
|
|
async Task StartAsync()
|
2022-03-06 13:29:38 +00:00
|
|
|
{
|
|
|
|
|
if(SelectedPlugin is null)
|
2020-04-13 04:40:35 +01:00
|
|
|
{
|
2024-05-01 04:05:22 +01:00
|
|
|
await MessageBoxManager
|
|
|
|
|
.GetMessageBoxStandard(UI.Title_Error, UI.Error_trying_to_find_selected_plugin, icon: Icon.Error)
|
|
|
|
|
.ShowWindowDialogAsync(_view);
|
2022-03-06 13:29:38 +00:00
|
|
|
|
|
|
|
|
return;
|
2020-04-13 04:40:35 +01:00
|
|
|
}
|
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
new Thread(DoWork).Start(SelectedPlugin.Plugin);
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-15 01:35:06 +00:00
|
|
|
[SuppressMessage("ReSharper", "AsyncVoidMethod")]
|
2022-03-06 13:29:38 +00:00
|
|
|
async void DoWork(object plugin)
|
|
|
|
|
{
|
2025-10-18 16:17:35 +01:00
|
|
|
var warning = false;
|
2022-03-06 13:29:38 +00:00
|
|
|
|
2022-11-14 01:20:28 +00:00
|
|
|
if(plugin is not IWritableImage outputFormat)
|
2020-04-13 04:40:35 +01:00
|
|
|
{
|
2024-05-01 04:05:22 +01:00
|
|
|
await MessageBoxManager
|
|
|
|
|
.GetMessageBoxStandard(UI.Title_Error, UI.Error_trying_to_find_selected_plugin, icon: Icon.Error)
|
|
|
|
|
.ShowWindowDialogAsync(_view);
|
2022-03-06 13:29:38 +00:00
|
|
|
|
|
|
|
|
return;
|
2020-04-13 04:40:35 +01:00
|
|
|
}
|
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
var inputOptical = _inputFormat as IOpticalMediaImage;
|
|
|
|
|
var outputOptical = outputFormat as IWritableOpticalImage;
|
|
|
|
|
|
|
|
|
|
List<Track> tracks;
|
|
|
|
|
|
|
|
|
|
try
|
2020-04-13 04:40:35 +01:00
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
tracks = inputOptical?.Tracks;
|
2020-04-13 04:40:35 +01:00
|
|
|
}
|
2025-08-20 18:51:05 +01:00
|
|
|
catch(Exception ex)
|
2020-04-13 04:40:35 +01:00
|
|
|
{
|
2025-08-20 18:51:05 +01:00
|
|
|
SentrySdk.CaptureException(ex);
|
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
tracks = null;
|
2020-04-13 04:40:35 +01:00
|
|
|
}
|
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
// Prepare UI
|
|
|
|
|
await Dispatcher.UIThread.InvokeAsync(() =>
|
2020-04-13 04:40:35 +01:00
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
CloseVisible = false;
|
|
|
|
|
StartVisible = false;
|
|
|
|
|
StopVisible = true;
|
|
|
|
|
ProgressVisible = true;
|
|
|
|
|
OptionsVisible = false;
|
|
|
|
|
StopEnabled = true;
|
|
|
|
|
FormatReadOnly = true;
|
|
|
|
|
DestinationVisible = false;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
ProgressMaxValue = 1d;
|
|
|
|
|
ProgressMaxValue += _inputFormat.Info.ReadableMediaTags.Count;
|
|
|
|
|
ProgressMaxValue++;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2024-05-01 04:05:22 +01:00
|
|
|
if(tracks != null) ProgressMaxValue++;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if(tracks == null)
|
2020-04-13 04:40:35 +01:00
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
ProgressMaxValue += 2;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
foreach(SectorTagType tag in _inputFormat.Info.ReadableSectorTags)
|
|
|
|
|
{
|
|
|
|
|
switch(tag)
|
|
|
|
|
{
|
2025-10-18 16:17:35 +01:00
|
|
|
case SectorTagType.AppleSonyTag:
|
|
|
|
|
case SectorTagType.AppleProfileTag:
|
|
|
|
|
case SectorTagType.PriamDataTowerTag:
|
2022-03-06 13:29:38 +00:00
|
|
|
case SectorTagType.CdSectorSync:
|
|
|
|
|
case SectorTagType.CdSectorHeader:
|
|
|
|
|
case SectorTagType.CdSectorSubHeader:
|
|
|
|
|
case SectorTagType.CdSectorEdc:
|
|
|
|
|
case SectorTagType.CdSectorEccP:
|
|
|
|
|
case SectorTagType.CdSectorEccQ:
|
|
|
|
|
case SectorTagType.CdSectorEcc:
|
|
|
|
|
// This tags are inline in long sector
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2024-05-01 04:05:22 +01:00
|
|
|
if(ForceChecked && !outputFormat.SupportedSectorTags.Contains(tag)) continue;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
ProgressMaxValue++;
|
|
|
|
|
}
|
2020-04-13 04:40:35 +01:00
|
|
|
}
|
2022-03-06 13:29:38 +00:00
|
|
|
else
|
2020-04-13 04:40:35 +01:00
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
ProgressMaxValue += tracks.Count;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
foreach(SectorTagType tag in _inputFormat.Info.ReadableSectorTags.OrderBy(t => t))
|
2020-04-13 04:40:35 +01:00
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
switch(tag)
|
2020-04-13 04:40:35 +01:00
|
|
|
{
|
2025-10-18 16:17:35 +01:00
|
|
|
case SectorTagType.AppleSonyTag:
|
|
|
|
|
case SectorTagType.AppleProfileTag:
|
|
|
|
|
case SectorTagType.PriamDataTowerTag:
|
2022-03-06 13:29:38 +00:00
|
|
|
case SectorTagType.CdSectorSync:
|
|
|
|
|
case SectorTagType.CdSectorHeader:
|
|
|
|
|
case SectorTagType.CdSectorSubHeader:
|
|
|
|
|
case SectorTagType.CdSectorEdc:
|
|
|
|
|
case SectorTagType.CdSectorEccP:
|
|
|
|
|
case SectorTagType.CdSectorEccQ:
|
|
|
|
|
case SectorTagType.CdSectorEcc:
|
|
|
|
|
// This tags are inline in long sector
|
2020-04-13 04:40:35 +01:00
|
|
|
continue;
|
|
|
|
|
}
|
2022-03-06 13:29:38 +00:00
|
|
|
|
2024-05-01 04:05:22 +01:00
|
|
|
if(ForceChecked && !outputFormat.SupportedSectorTags.Contains(tag)) continue;
|
2022-03-06 13:29:38 +00:00
|
|
|
|
2020-04-13 04:40:35 +01:00
|
|
|
ProgressMaxValue += tracks.Count;
|
2022-03-06 13:29:38 +00:00
|
|
|
}
|
|
|
|
|
}
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2024-05-01 04:05:22 +01:00
|
|
|
if(_dumpHardware != null) ProgressMaxValue++;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2024-05-01 04:05:22 +01:00
|
|
|
if(_aaruMetadata != null) ProgressMaxValue++;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
ProgressMaxValue++;
|
|
|
|
|
});
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
foreach(MediaTagType mediaTag in _inputFormat.Info.ReadableMediaTags.Where(mediaTag =>
|
2024-05-01 04:05:22 +01:00
|
|
|
!outputFormat.SupportedMediaTags.Contains(mediaTag) && !ForceChecked))
|
2022-03-06 13:29:38 +00:00
|
|
|
{
|
2024-05-01 04:05:22 +01:00
|
|
|
await Dispatcher.UIThread.InvokeAsync(async () => await MessageBoxManager
|
|
|
|
|
.GetMessageBoxStandard(UI.Title_Error,
|
|
|
|
|
string
|
|
|
|
|
.Format(UI
|
|
|
|
|
.Converting_image_will_lose_media_tag_0,
|
|
|
|
|
mediaTag),
|
|
|
|
|
icon: Icon.Error)
|
|
|
|
|
.ShowWindowDialogAsync(_view));
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
return;
|
|
|
|
|
}
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
bool useLong = _inputFormat.Info.ReadableSectorTags.Count != 0;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
foreach(SectorTagType sectorTag in _inputFormat.Info.ReadableSectorTags.Where(sectorTag =>
|
2024-05-01 04:05:22 +01:00
|
|
|
!outputFormat.SupportedSectorTags.Contains(sectorTag)))
|
2022-03-06 13:29:38 +00:00
|
|
|
{
|
|
|
|
|
if(ForceChecked)
|
2020-04-13 04:40:35 +01:00
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
if(sectorTag != SectorTagType.CdTrackFlags &&
|
|
|
|
|
sectorTag != SectorTagType.CdTrackIsrc &&
|
|
|
|
|
sectorTag != SectorTagType.CdSectorSubchannel)
|
|
|
|
|
useLong = false;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
continue;
|
2020-04-13 04:40:35 +01:00
|
|
|
}
|
|
|
|
|
|
2024-05-01 04:05:22 +01:00
|
|
|
await Dispatcher.UIThread.InvokeAsync(async () => await MessageBoxManager
|
|
|
|
|
.GetMessageBoxStandard(UI.Title_Error,
|
|
|
|
|
string
|
|
|
|
|
.Format(UI
|
|
|
|
|
.Converting_image_will_lose_sector_tag_0,
|
|
|
|
|
sectorTag),
|
|
|
|
|
icon: Icon.Error)
|
|
|
|
|
.ShowWindowDialogAsync(_view));
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
return;
|
|
|
|
|
}
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
Dictionary<string, string> parsedOptions = new();
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
/* TODO:
|
|
|
|
|
if(grpOptions.Content is StackLayout stkImageOptions)
|
|
|
|
|
foreach(Control option in stkImageOptions.Children)
|
|
|
|
|
{
|
|
|
|
|
if(cancel)
|
|
|
|
|
break;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
string value;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
switch(option)
|
2020-04-13 04:40:35 +01:00
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
case CheckBox optBoolean:
|
|
|
|
|
value = optBooleanChecked?.ToString();
|
|
|
|
|
|
2020-04-13 04:40:35 +01:00
|
|
|
break;
|
2022-03-06 13:29:38 +00:00
|
|
|
case NumericStepper optNumber:
|
|
|
|
|
value = optNumber.Value.ToString(CultureInfo.CurrentCulture);
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
break;
|
|
|
|
|
case TextBox optString:
|
|
|
|
|
value = optString.Text;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
break;
|
|
|
|
|
default: continue;
|
|
|
|
|
}
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
string key = option.ID.Substring(3);
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
parsedOptions.Add(key, value);
|
|
|
|
|
}
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
await Dispatcher.UIThread.InvokeAsync(() =>
|
|
|
|
|
{
|
2022-11-19 21:10:41 +00:00
|
|
|
ProgressText = UI.Creating_output_image;
|
2022-03-06 13:29:38 +00:00
|
|
|
Progress2Text = "";
|
|
|
|
|
Progress2Indeterminate = true;
|
|
|
|
|
});
|
|
|
|
|
|
2025-10-23 11:21:47 +01:00
|
|
|
// TODO: Get the source image number of negative and overflow sectors to convert them too
|
2024-05-01 04:05:22 +01:00
|
|
|
if(!outputFormat.Create(DestinationText,
|
|
|
|
|
_inputFormat.Info.MediaType,
|
|
|
|
|
parsedOptions,
|
|
|
|
|
_inputFormat.Info.Sectors,
|
2025-10-23 11:21:47 +01:00
|
|
|
0,
|
|
|
|
|
0,
|
2022-03-07 07:36:44 +00:00
|
|
|
_inputFormat.Info.SectorSize))
|
2022-03-06 13:29:38 +00:00
|
|
|
{
|
2024-05-01 04:05:22 +01:00
|
|
|
await Dispatcher.UIThread.InvokeAsync(async () => await MessageBoxManager
|
|
|
|
|
.GetMessageBoxStandard(UI.Title_Error,
|
|
|
|
|
string
|
|
|
|
|
.Format(UI.Error_0_creating_output_image,
|
2023-10-04 17:34:40 +01:00
|
|
|
outputFormat.ErrorMessage),
|
2024-05-01 04:05:22 +01:00
|
|
|
icon: Icon.Error)
|
|
|
|
|
.ShowWindowDialogAsync(_view));
|
2022-03-06 13:29:38 +00:00
|
|
|
|
2025-08-17 06:11:22 +01:00
|
|
|
AaruLogging.Error(UI.Error_0_creating_output_image, outputFormat.ErrorMessage);
|
2022-03-06 13:29:38 +00:00
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
await Dispatcher.UIThread.InvokeAsync(() =>
|
|
|
|
|
{
|
2022-11-19 21:10:41 +00:00
|
|
|
ProgressText = UI.Setting_image_metadata;
|
2022-03-06 13:29:38 +00:00
|
|
|
ProgressValue++;
|
|
|
|
|
Progress2Text = "";
|
|
|
|
|
Progress2Indeterminate = true;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
var metadata = new ImageInfo
|
|
|
|
|
{
|
|
|
|
|
Application = "Aaru",
|
2025-09-28 02:44:52 +01:00
|
|
|
ApplicationVersion = Version.GetInformationalVersion(),
|
2022-03-06 13:29:38 +00:00
|
|
|
Comments = CommentsText,
|
|
|
|
|
Creator = CreatorText,
|
|
|
|
|
DriveFirmwareRevision = DriveFirmwareRevisionText,
|
|
|
|
|
DriveManufacturer = DriveManufacturerText,
|
|
|
|
|
DriveModel = DriveModelText,
|
|
|
|
|
DriveSerialNumber = DriveSerialNumberText,
|
|
|
|
|
LastMediaSequence = (int)LastMediaSequenceValue,
|
|
|
|
|
MediaBarcode = MediaBarcodeText,
|
|
|
|
|
MediaManufacturer = MediaManufacturerText,
|
|
|
|
|
MediaModel = MediaModelText,
|
|
|
|
|
MediaPartNumber = MediaPartNumberText,
|
|
|
|
|
MediaSequence = (int)MediaSequenceValue,
|
|
|
|
|
MediaSerialNumber = MediaSerialNumberText,
|
|
|
|
|
MediaTitle = MediaTitleText
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if(!_cancel)
|
2023-10-03 23:27:57 +01:00
|
|
|
{
|
2022-12-15 22:21:07 +00:00
|
|
|
if(!outputFormat.SetImageInfo(metadata))
|
2022-03-06 13:29:38 +00:00
|
|
|
{
|
2025-08-17 05:50:25 +01:00
|
|
|
if(!ForceChecked)
|
2022-03-06 13:29:38 +00:00
|
|
|
{
|
2024-05-01 04:05:22 +01:00
|
|
|
await Dispatcher.UIThread.InvokeAsync(async () => await MessageBoxManager
|
|
|
|
|
.GetMessageBoxStandard(UI.Title_Error,
|
|
|
|
|
string
|
|
|
|
|
.Format(UI
|
|
|
|
|
.Error_0_setting_metadata_not_continuing,
|
|
|
|
|
outputFormat
|
|
|
|
|
.ErrorMessage),
|
|
|
|
|
icon: Icon.Error)
|
|
|
|
|
.ShowWindowDialogAsync(_view));
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2025-08-17 06:11:22 +01:00
|
|
|
AaruLogging.Error(UI.Error_0_setting_metadata_not_continuing, outputFormat.ErrorMessage);
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
return;
|
2020-04-13 04:40:35 +01:00
|
|
|
}
|
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
warning = true;
|
2025-08-17 06:11:22 +01:00
|
|
|
AaruLogging.Error(Localization.Core.Error_0_setting_metadata, outputFormat.ErrorMessage);
|
2022-03-06 13:29:38 +00:00
|
|
|
}
|
2023-10-03 23:27:57 +01:00
|
|
|
}
|
2022-03-06 13:29:38 +00:00
|
|
|
|
2023-10-04 17:34:40 +01:00
|
|
|
if(tracks != null && !_cancel && outputOptical != null)
|
2022-03-06 13:29:38 +00:00
|
|
|
{
|
2020-04-13 04:40:35 +01:00
|
|
|
await Dispatcher.UIThread.InvokeAsync(() =>
|
|
|
|
|
{
|
2022-11-19 21:10:41 +00:00
|
|
|
ProgressText = UI.Setting_tracks_list;
|
2022-03-06 13:29:38 +00:00
|
|
|
ProgressValue++;
|
2020-04-13 04:40:35 +01:00
|
|
|
Progress2Text = "";
|
|
|
|
|
Progress2Indeterminate = true;
|
|
|
|
|
});
|
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if(!outputOptical.SetTracks(tracks))
|
2020-04-13 04:40:35 +01:00
|
|
|
{
|
2024-05-01 04:05:22 +01:00
|
|
|
await Dispatcher.UIThread.InvokeAsync(async () => await MessageBoxManager
|
|
|
|
|
.GetMessageBoxStandard(UI.Title_Error,
|
|
|
|
|
string
|
|
|
|
|
.Format(UI
|
|
|
|
|
.Error_0_sending_tracks_list_to_output_image,
|
|
|
|
|
outputFormat
|
|
|
|
|
.ErrorMessage),
|
|
|
|
|
icon: Icon.Error)
|
|
|
|
|
.ShowWindowDialogAsync(_view));
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2025-08-17 06:11:22 +01:00
|
|
|
AaruLogging.Error(UI.Error_0_sending_tracks_list_to_output_image, outputFormat.ErrorMessage);
|
2020-04-13 04:40:35 +01:00
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
2022-03-06 13:29:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ErrorNumber errno;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-16 00:31:33 +00:00
|
|
|
foreach(MediaTagType mediaTag in _inputFormat.Info.ReadableMediaTags.TakeWhile(_ => !_cancel))
|
2022-03-06 13:29:38 +00:00
|
|
|
{
|
2020-04-13 04:40:35 +01:00
|
|
|
await Dispatcher.UIThread.InvokeAsync(() =>
|
|
|
|
|
{
|
2022-11-19 21:10:41 +00:00
|
|
|
ProgressText = string.Format(UI.Converting_media_tag_0, mediaTag);
|
2020-04-13 04:40:35 +01:00
|
|
|
ProgressValue++;
|
|
|
|
|
Progress2Text = "";
|
|
|
|
|
Progress2Indeterminate = true;
|
|
|
|
|
});
|
|
|
|
|
|
2024-05-01 04:05:22 +01:00
|
|
|
if(ForceChecked && !outputFormat.SupportedMediaTags.Contains(mediaTag)) continue;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
errno = _inputFormat.ReadMediaTag(mediaTag, out byte[] tag);
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2024-05-01 04:05:22 +01:00
|
|
|
if(errno == ErrorNumber.NoError && outputFormat.WriteMediaTag(tag, mediaTag)) continue;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if(ForceChecked)
|
2020-04-13 04:40:35 +01:00
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
warning = true;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if(errno == ErrorNumber.NoError)
|
2025-08-17 06:11:22 +01:00
|
|
|
AaruLogging.Error(UI.Error_0_writing_media_tag, outputFormat.ErrorMessage);
|
2022-03-06 13:29:38 +00:00
|
|
|
else
|
2025-08-17 06:11:22 +01:00
|
|
|
AaruLogging.Error(UI.Error_0_reading_media_tag, errno);
|
2020-04-13 04:40:35 +01:00
|
|
|
}
|
2022-03-06 13:29:38 +00:00
|
|
|
else
|
2020-04-13 04:40:35 +01:00
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
if(errno == ErrorNumber.NoError)
|
2020-04-13 04:40:35 +01:00
|
|
|
{
|
2024-05-01 04:05:22 +01:00
|
|
|
await Dispatcher.UIThread.InvokeAsync(async () => await MessageBoxManager
|
|
|
|
|
.GetMessageBoxStandard(UI.Title_Error,
|
|
|
|
|
string
|
|
|
|
|
.Format(UI
|
|
|
|
|
.Error_0_writing_media_tag_not_continuing,
|
|
|
|
|
outputFormat
|
|
|
|
|
.ErrorMessage),
|
|
|
|
|
icon: Icon.Error)
|
|
|
|
|
.ShowWindowDialogAsync(_view));
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2025-08-17 06:11:22 +01:00
|
|
|
AaruLogging.Error(UI.Error_0_writing_media_tag_not_continuing, outputFormat.ErrorMessage);
|
2020-04-13 04:40:35 +01:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2024-05-01 04:05:22 +01:00
|
|
|
await Dispatcher.UIThread.InvokeAsync(async () => await MessageBoxManager
|
|
|
|
|
.GetMessageBoxStandard(UI.Title_Error,
|
|
|
|
|
string
|
|
|
|
|
.Format(UI
|
|
|
|
|
.Error_0_reading_media_tag_not_continuing,
|
2023-10-04 17:34:40 +01:00
|
|
|
errno),
|
2024-05-01 04:05:22 +01:00
|
|
|
icon: Icon.Error)
|
|
|
|
|
.ShowWindowDialogAsync(_view));
|
2021-09-18 15:01:31 +01:00
|
|
|
|
2025-08-17 06:11:22 +01:00
|
|
|
AaruLogging.Error(UI.Error_0_reading_media_tag_not_continuing, errno);
|
2020-04-13 04:40:35 +01:00
|
|
|
}
|
2022-03-06 13:29:38 +00:00
|
|
|
|
|
|
|
|
return;
|
2020-04-13 04:40:35 +01:00
|
|
|
}
|
2022-03-06 13:29:38 +00:00
|
|
|
}
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
ulong doneSectors = 0;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2023-10-04 17:34:40 +01:00
|
|
|
if(tracks == null && !_cancel)
|
2022-03-06 13:29:38 +00:00
|
|
|
{
|
|
|
|
|
await Dispatcher.UIThread.InvokeAsync(() =>
|
2020-04-13 04:40:35 +01:00
|
|
|
{
|
2022-11-19 21:10:41 +00:00
|
|
|
ProgressText = string.Format(UI.Setting_geometry_to_0_cylinders_1_heads_and_2_sectors_per_track,
|
2024-05-01 04:05:22 +01:00
|
|
|
_inputFormat.Info.Cylinders,
|
|
|
|
|
_inputFormat.Info.Heads,
|
2022-11-19 21:10:41 +00:00
|
|
|
_inputFormat.Info.SectorsPerTrack);
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
ProgressValue++;
|
|
|
|
|
Progress2Text = "";
|
|
|
|
|
Progress2Indeterminate = true;
|
|
|
|
|
});
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2024-05-01 04:05:22 +01:00
|
|
|
if(!outputFormat.SetGeometry(_inputFormat.Info.Cylinders,
|
|
|
|
|
_inputFormat.Info.Heads,
|
2022-03-06 13:29:38 +00:00
|
|
|
_inputFormat.Info.SectorsPerTrack))
|
|
|
|
|
{
|
|
|
|
|
warning = true;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2025-08-17 06:11:22 +01:00
|
|
|
AaruLogging.Error(UI.Error_0_setting_geometry_image_may_be_incorrect_continuing,
|
2025-08-19 15:17:19 +01:00
|
|
|
outputFormat.ErrorMessage);
|
2022-03-06 13:29:38 +00:00
|
|
|
}
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
await Dispatcher.UIThread.InvokeAsync(() =>
|
|
|
|
|
{
|
2022-11-19 21:10:41 +00:00
|
|
|
ProgressText = UI.Converting_sectors;
|
2022-03-06 13:29:38 +00:00
|
|
|
ProgressValue++;
|
|
|
|
|
Progress2Text = "";
|
|
|
|
|
Progress2Indeterminate = false;
|
|
|
|
|
Progress2MaxValue = (int)(_inputFormat.Info.Sectors / SectorsValue);
|
|
|
|
|
});
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
while(doneSectors < _inputFormat.Info.Sectors)
|
|
|
|
|
{
|
2024-05-01 04:05:22 +01:00
|
|
|
if(_cancel) break;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
byte[] sector;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
uint sectorsToDo;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if(_inputFormat.Info.Sectors - doneSectors >= (ulong)SectorsValue)
|
|
|
|
|
sectorsToDo = (uint)SectorsValue;
|
|
|
|
|
else
|
|
|
|
|
sectorsToDo = (uint)(_inputFormat.Info.Sectors - doneSectors);
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
ulong sectors = doneSectors;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
await Dispatcher.UIThread.InvokeAsync(() =>
|
|
|
|
|
{
|
2024-05-01 04:05:22 +01:00
|
|
|
Progress2Text = string.Format(UI.Converting_sectors_0_to_1_2_done,
|
|
|
|
|
sectors,
|
|
|
|
|
sectors + sectorsToDo,
|
2022-11-19 21:10:41 +00:00
|
|
|
sectors / (double)_inputFormat.Info.Sectors);
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
Progress2Value = (int)(sectors / SectorsValue);
|
|
|
|
|
});
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2025-10-22 20:25:23 +01:00
|
|
|
bool result;
|
|
|
|
|
SectorStatus sectorStatus = SectorStatus.NotDumped;
|
|
|
|
|
var sectorStatusArray = new SectorStatus[1];
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if(useLong)
|
|
|
|
|
{
|
2023-10-03 23:27:57 +01:00
|
|
|
errno = sectorsToDo == 1
|
2025-10-23 03:07:43 +01:00
|
|
|
? _inputFormat.ReadSectorLong(doneSectors, false, out sector, out sectorStatus)
|
2025-10-22 20:25:23 +01:00
|
|
|
: _inputFormat.ReadSectorsLong(doneSectors,
|
2025-10-23 03:07:43 +01:00
|
|
|
false,
|
2025-10-22 20:25:23 +01:00
|
|
|
sectorsToDo,
|
|
|
|
|
out sector,
|
|
|
|
|
out sectorStatusArray);
|
2022-03-06 13:29:38 +00:00
|
|
|
|
|
|
|
|
if(errno == ErrorNumber.NoError)
|
2023-10-03 23:27:57 +01:00
|
|
|
{
|
|
|
|
|
result = sectorsToDo == 1
|
2025-10-23 03:07:43 +01:00
|
|
|
? outputFormat.WriteSectorLong(sector, doneSectors, false, sectorStatus)
|
2025-10-22 20:25:23 +01:00
|
|
|
: outputFormat.WriteSectorsLong(sector,
|
|
|
|
|
doneSectors,
|
2025-10-23 03:07:43 +01:00
|
|
|
false,
|
2025-10-22 20:25:23 +01:00
|
|
|
sectorsToDo,
|
|
|
|
|
sectorStatusArray);
|
2023-10-03 23:27:57 +01:00
|
|
|
}
|
2022-03-06 13:29:38 +00:00
|
|
|
else
|
2021-09-20 14:22:22 +01:00
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
result = true;
|
2021-09-20 14:22:22 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if(ForceChecked)
|
2020-04-13 04:40:35 +01:00
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
warning = true;
|
2021-09-20 14:22:22 +01:00
|
|
|
|
2025-08-17 06:11:22 +01:00
|
|
|
AaruLogging.Error(UI.Error_0_reading_sector_1_continuing, errno, doneSectors);
|
2020-04-13 04:40:35 +01:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2024-05-01 04:05:22 +01:00
|
|
|
await Dispatcher.UIThread.InvokeAsync(async () => await MessageBoxManager
|
|
|
|
|
.GetMessageBoxStandard(UI.Title_Error,
|
|
|
|
|
string
|
|
|
|
|
.Format(UI
|
|
|
|
|
.Error_0_reading_sector_1_not_continuing,
|
2023-10-04 17:34:40 +01:00
|
|
|
errno,
|
|
|
|
|
doneSectors),
|
2024-05-01 04:05:22 +01:00
|
|
|
icon: Icon.Error)
|
|
|
|
|
.ShowWindowDialogAsync(_view));
|
2021-09-19 21:16:47 +01:00
|
|
|
|
2025-08-17 06:11:22 +01:00
|
|
|
AaruLogging.Error(UI.Error_0_reading_sector_1_not_continuing, errno, doneSectors);
|
2021-09-19 21:16:47 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
return;
|
2020-04-13 04:40:35 +01:00
|
|
|
}
|
|
|
|
|
}
|
2022-03-06 13:29:38 +00:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2023-10-03 23:27:57 +01:00
|
|
|
errno = sectorsToDo == 1
|
2025-10-23 03:07:43 +01:00
|
|
|
? _inputFormat.ReadSector(doneSectors, false, out sector, out sectorStatus)
|
|
|
|
|
: _inputFormat.ReadSectors(doneSectors,
|
|
|
|
|
false,
|
|
|
|
|
sectorsToDo,
|
|
|
|
|
out sector,
|
|
|
|
|
out sectorStatusArray);
|
2022-03-06 13:29:38 +00:00
|
|
|
|
|
|
|
|
if(errno == ErrorNumber.NoError)
|
2023-10-03 23:27:57 +01:00
|
|
|
{
|
|
|
|
|
result = sectorsToDo == 1
|
2025-10-23 03:07:43 +01:00
|
|
|
? outputFormat.WriteSector(sector, doneSectors, false, sectorStatus)
|
|
|
|
|
: outputFormat.WriteSectors(sector,
|
|
|
|
|
doneSectors,
|
|
|
|
|
false,
|
|
|
|
|
sectorsToDo,
|
|
|
|
|
sectorStatusArray);
|
2023-10-03 23:27:57 +01:00
|
|
|
}
|
2022-03-06 13:29:38 +00:00
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
result = true;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
|
|
|
|
if(ForceChecked)
|
|
|
|
|
{
|
|
|
|
|
warning = true;
|
|
|
|
|
|
2025-08-17 06:11:22 +01:00
|
|
|
AaruLogging.Error(UI.Error_0_reading_sector_1_continuing, errno, doneSectors);
|
2020-04-13 04:40:35 +01:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2024-05-01 04:05:22 +01:00
|
|
|
await Dispatcher.UIThread.InvokeAsync(async () => await MessageBoxManager
|
|
|
|
|
.GetMessageBoxStandard(UI.Title_Error,
|
|
|
|
|
string
|
|
|
|
|
.Format(UI
|
|
|
|
|
.Error_0_reading_sector_1_not_continuing,
|
2023-10-04 17:34:40 +01:00
|
|
|
errno,
|
|
|
|
|
doneSectors),
|
2024-05-01 04:05:22 +01:00
|
|
|
icon: Icon.Error)
|
|
|
|
|
.ShowWindowDialogAsync(_view));
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2025-08-17 06:11:22 +01:00
|
|
|
AaruLogging.Error(UI.Error_0_reading_sector_1_not_continuing, errno, doneSectors);
|
2020-04-13 04:40:35 +01:00
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
2022-03-06 13:29:38 +00:00
|
|
|
}
|
2020-04-13 04:40:35 +01:00
|
|
|
}
|
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if(!result)
|
2023-10-03 23:27:57 +01:00
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
if(ForceChecked)
|
|
|
|
|
{
|
|
|
|
|
warning = true;
|
2020-07-14 02:16:53 +01:00
|
|
|
|
2025-08-17 06:11:22 +01:00
|
|
|
AaruLogging.Error(UI.Error_0_writing_sector_1_continuing,
|
2025-08-19 15:17:19 +01:00
|
|
|
outputFormat.ErrorMessage,
|
|
|
|
|
doneSectors);
|
2022-03-06 13:29:38 +00:00
|
|
|
}
|
|
|
|
|
else
|
2020-07-14 02:16:53 +01:00
|
|
|
{
|
2024-05-01 04:05:22 +01:00
|
|
|
await Dispatcher.UIThread.InvokeAsync(async () => await MessageBoxManager
|
|
|
|
|
.GetMessageBoxStandard(UI.Title_Error,
|
|
|
|
|
string
|
|
|
|
|
.Format(UI
|
|
|
|
|
.Error_0_writing_sector_1_not_continuing,
|
|
|
|
|
outputFormat
|
|
|
|
|
.ErrorMessage,
|
2023-10-03 23:27:57 +01:00
|
|
|
doneSectors),
|
2024-05-01 04:05:22 +01:00
|
|
|
icon: Icon.Error)
|
|
|
|
|
.ShowWindowDialogAsync(_view));
|
2022-11-19 21:10:41 +00:00
|
|
|
|
2025-08-17 06:11:22 +01:00
|
|
|
AaruLogging.Error(UI.Error_0_writing_sector_1_not_continuing,
|
2025-08-19 15:17:19 +01:00
|
|
|
outputFormat.ErrorMessage,
|
|
|
|
|
doneSectors);
|
2020-07-14 02:16:53 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
return;
|
2020-07-14 02:16:53 +01:00
|
|
|
}
|
2023-10-03 23:27:57 +01:00
|
|
|
}
|
2020-07-14 02:16:53 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
doneSectors += sectorsToDo;
|
|
|
|
|
}
|
2020-07-14 02:16:53 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
await Dispatcher.UIThread.InvokeAsync(() =>
|
|
|
|
|
{
|
2024-05-01 04:05:22 +01:00
|
|
|
Progress2Text = string.Format(UI.Converting_sectors_0_to_1_2_done,
|
|
|
|
|
_inputFormat.Info.Sectors,
|
|
|
|
|
_inputFormat.Info.Sectors,
|
|
|
|
|
1.0);
|
2020-07-14 02:16:53 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
Progress2Value = Progress2MaxValue;
|
|
|
|
|
});
|
2020-07-14 02:16:53 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
Dictionary<byte, string> isrcs = new();
|
|
|
|
|
Dictionary<byte, byte> trackFlags = new();
|
|
|
|
|
string mcn = null;
|
2024-05-01 04:39:38 +01:00
|
|
|
HashSet<int> subchannelExtents = [];
|
2022-03-06 13:29:38 +00:00
|
|
|
Dictionary<byte, int> smallestPregapLbaPerTrack = new();
|
|
|
|
|
|
2024-05-01 04:05:22 +01:00
|
|
|
foreach(SectorTagType tag in _inputFormat.Info.ReadableSectorTags.Where(t => t == SectorTagType.CdTrackIsrc)
|
|
|
|
|
.OrderBy(t => t))
|
2022-03-06 13:29:38 +00:00
|
|
|
{
|
|
|
|
|
foreach(Track track in inputOptical.Tracks)
|
2020-07-14 02:16:53 +01:00
|
|
|
{
|
2025-10-23 03:07:43 +01:00
|
|
|
errno = _inputFormat.ReadSectorTag(track.Sequence, false, tag, out byte[] isrc);
|
2022-03-06 13:29:38 +00:00
|
|
|
|
2024-05-01 04:05:22 +01:00
|
|
|
if(errno != ErrorNumber.NoError) continue;
|
2020-07-14 02:16:53 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
isrcs[(byte)track.Sequence] = Encoding.UTF8.GetString(isrc);
|
2020-07-14 02:16:53 +01:00
|
|
|
}
|
2022-03-06 13:29:38 +00:00
|
|
|
}
|
2020-07-14 02:16:53 +01:00
|
|
|
|
2024-05-01 04:05:22 +01:00
|
|
|
foreach(SectorTagType tag in _inputFormat.Info.ReadableSectorTags
|
|
|
|
|
.Where(t => t == SectorTagType.CdTrackFlags)
|
|
|
|
|
.OrderBy(t => t))
|
2022-03-06 13:29:38 +00:00
|
|
|
{
|
|
|
|
|
foreach(Track track in inputOptical.Tracks)
|
2020-04-13 04:40:35 +01:00
|
|
|
{
|
2025-10-23 03:07:43 +01:00
|
|
|
errno = _inputFormat.ReadSectorTag(track.Sequence, false, tag, out byte[] flags);
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2024-05-01 04:05:22 +01:00
|
|
|
if(errno != ErrorNumber.NoError) continue;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
trackFlags[(byte)track.Sequence] = flags[0];
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
for(ulong s = 0; s < _inputFormat.Info.Sectors; s++)
|
|
|
|
|
{
|
2024-05-01 04:05:22 +01:00
|
|
|
if(s > int.MaxValue) break;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
subchannelExtents.Add((int)s);
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-16 00:31:33 +00:00
|
|
|
foreach(SectorTagType tag in _inputFormat.Info.ReadableSectorTags.TakeWhile(_ => useLong && !_cancel))
|
2022-03-06 13:29:38 +00:00
|
|
|
{
|
|
|
|
|
switch(tag)
|
|
|
|
|
{
|
2025-10-18 16:17:35 +01:00
|
|
|
case SectorTagType.AppleSonyTag:
|
|
|
|
|
case SectorTagType.AppleProfileTag:
|
|
|
|
|
case SectorTagType.PriamDataTowerTag:
|
2022-03-06 13:29:38 +00:00
|
|
|
case SectorTagType.CdSectorSync:
|
|
|
|
|
case SectorTagType.CdSectorHeader:
|
|
|
|
|
case SectorTagType.CdSectorSubHeader:
|
|
|
|
|
case SectorTagType.CdSectorEdc:
|
|
|
|
|
case SectorTagType.CdSectorEccP:
|
|
|
|
|
case SectorTagType.CdSectorEccQ:
|
|
|
|
|
case SectorTagType.CdSectorEcc:
|
|
|
|
|
// This tags are inline in long sector
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2024-05-01 04:05:22 +01:00
|
|
|
if(ForceChecked && !outputFormat.SupportedSectorTags.Contains(tag)) continue;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
await Dispatcher.UIThread.InvokeAsync(() =>
|
|
|
|
|
{
|
2022-11-19 21:10:41 +00:00
|
|
|
ProgressText = string.Format(UI.Converting_tag_0, tag);
|
2022-03-06 13:29:38 +00:00
|
|
|
ProgressValue++;
|
|
|
|
|
Progress2Text = "";
|
|
|
|
|
Progress2Indeterminate = false;
|
|
|
|
|
Progress2MaxValue = (int)(_inputFormat.Info.Sectors / SectorsValue);
|
|
|
|
|
});
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
doneSectors = 0;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
while(doneSectors < _inputFormat.Info.Sectors)
|
|
|
|
|
{
|
2024-05-01 04:05:22 +01:00
|
|
|
if(_cancel) break;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
byte[] sector;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
uint sectorsToDo;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if(_inputFormat.Info.Sectors - doneSectors >= (ulong)SectorsValue)
|
|
|
|
|
sectorsToDo = (uint)SectorsValue;
|
|
|
|
|
else
|
|
|
|
|
sectorsToDo = (uint)(_inputFormat.Info.Sectors - doneSectors);
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
ulong sectors = doneSectors;
|
2020-07-14 02:16:53 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
await Dispatcher.UIThread.InvokeAsync(() =>
|
|
|
|
|
{
|
2022-11-19 21:10:41 +00:00
|
|
|
Progress2Text = string.Format(UI.Converting_tag_0_for_sectors_1_to_2_3_done,
|
2024-05-01 04:05:22 +01:00
|
|
|
sectors / (double)_inputFormat.Info.Sectors,
|
|
|
|
|
sectors,
|
2022-11-19 21:10:41 +00:00
|
|
|
sectors + sectorsToDo,
|
|
|
|
|
sectors / (double)_inputFormat.Info.Sectors);
|
2021-09-20 20:52:18 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
Progress2Value = (int)(sectors / SectorsValue);
|
|
|
|
|
});
|
2020-07-14 02:16:53 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
bool result;
|
2020-07-14 02:16:53 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if(sectorsToDo == 1)
|
|
|
|
|
{
|
2025-10-23 03:07:43 +01:00
|
|
|
errno = _inputFormat.ReadSectorTag(doneSectors, false, tag, out sector);
|
2021-09-20 20:52:18 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if(errno == ErrorNumber.NoError)
|
|
|
|
|
{
|
|
|
|
|
Track track = tracks.LastOrDefault(t => t.StartSector >= doneSectors);
|
2021-09-20 20:52:18 +01:00
|
|
|
|
2023-10-04 17:34:40 +01:00
|
|
|
if(tag == SectorTagType.CdSectorSubchannel && track != null)
|
2022-03-06 13:29:38 +00:00
|
|
|
{
|
|
|
|
|
bool indexesChanged = CompactDisc.WriteSubchannelToImage(MmcSubchannel.Raw,
|
2024-05-01 04:05:22 +01:00
|
|
|
MmcSubchannel.Raw,
|
|
|
|
|
sector,
|
|
|
|
|
doneSectors,
|
|
|
|
|
1,
|
|
|
|
|
null,
|
|
|
|
|
isrcs,
|
|
|
|
|
(byte)track.Sequence,
|
|
|
|
|
ref mcn,
|
|
|
|
|
tracks.ToArray(),
|
|
|
|
|
subchannelExtents,
|
|
|
|
|
false,
|
|
|
|
|
outputFormat as IWritableOpticalImage,
|
|
|
|
|
false,
|
|
|
|
|
false,
|
|
|
|
|
null,
|
|
|
|
|
smallestPregapLbaPerTrack,
|
|
|
|
|
false,
|
|
|
|
|
out _);
|
|
|
|
|
|
|
|
|
|
if(indexesChanged) outputOptical.SetTracks(tracks.ToList());
|
2021-09-20 20:52:18 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
result = true;
|
2021-09-20 20:52:18 +01:00
|
|
|
}
|
2022-03-06 13:29:38 +00:00
|
|
|
else
|
2025-10-23 03:07:43 +01:00
|
|
|
result = outputFormat.WriteSectorTag(sector, doneSectors, false, tag);
|
2020-04-13 04:40:35 +01:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
result = true;
|
2020-07-14 02:16:53 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if(ForceChecked)
|
2020-07-14 02:16:53 +01:00
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
warning = true;
|
2021-09-20 20:52:18 +01:00
|
|
|
|
2025-08-17 06:11:22 +01:00
|
|
|
AaruLogging.Error(UI.Error_0_reading_sector_1_continuing, errno, doneSectors);
|
2020-07-14 02:16:53 +01:00
|
|
|
}
|
|
|
|
|
else
|
2021-09-20 20:52:18 +01:00
|
|
|
{
|
2024-05-01 04:05:22 +01:00
|
|
|
await Dispatcher.UIThread.InvokeAsync(async () => await MessageBoxManager
|
|
|
|
|
.GetMessageBoxStandard(UI.Title_Error,
|
|
|
|
|
string
|
|
|
|
|
.Format(UI
|
|
|
|
|
.Error_0_reading_sector_1_not_continuing,
|
|
|
|
|
errno,
|
|
|
|
|
doneSectors),
|
|
|
|
|
icon: Icon.Error)
|
|
|
|
|
.ShowWindowDialogAsync(_view));
|
|
|
|
|
|
2025-08-19 15:17:19 +01:00
|
|
|
AaruLogging.Error(UI.Error_0_reading_sector_1_not_continuing, errno, doneSectors);
|
2021-09-20 20:52:18 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2025-10-23 03:07:43 +01:00
|
|
|
errno = _inputFormat.ReadSectorsTag(doneSectors, false, sectorsToDo, tag, out sector);
|
2022-03-06 13:29:38 +00:00
|
|
|
|
|
|
|
|
if(errno == ErrorNumber.NoError)
|
|
|
|
|
{
|
|
|
|
|
Track track = tracks.LastOrDefault(t => t.StartSector >= doneSectors);
|
2021-09-20 20:52:18 +01:00
|
|
|
|
2023-10-04 17:34:40 +01:00
|
|
|
if(tag == SectorTagType.CdSectorSubchannel && track != null)
|
2021-09-20 20:52:18 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
{
|
|
|
|
|
bool indexesChanged = CompactDisc.WriteSubchannelToImage(MmcSubchannel.Raw,
|
2024-05-01 04:05:22 +01:00
|
|
|
MmcSubchannel.Raw,
|
|
|
|
|
sector,
|
|
|
|
|
doneSectors,
|
|
|
|
|
sectorsToDo,
|
|
|
|
|
null,
|
|
|
|
|
isrcs,
|
|
|
|
|
(byte)track.Sequence,
|
|
|
|
|
ref mcn,
|
|
|
|
|
tracks.ToArray(),
|
|
|
|
|
subchannelExtents,
|
|
|
|
|
false,
|
|
|
|
|
outputFormat as IWritableOpticalImage,
|
|
|
|
|
false,
|
|
|
|
|
false,
|
|
|
|
|
null,
|
|
|
|
|
smallestPregapLbaPerTrack,
|
|
|
|
|
false,
|
|
|
|
|
out _);
|
|
|
|
|
|
|
|
|
|
if(indexesChanged) outputOptical.SetTracks(tracks.ToList());
|
2022-03-06 13:29:38 +00:00
|
|
|
|
|
|
|
|
result = true;
|
2021-09-20 20:52:18 +01:00
|
|
|
}
|
2022-03-06 13:29:38 +00:00
|
|
|
else
|
2025-10-23 03:07:43 +01:00
|
|
|
result = outputFormat.WriteSectorsTag(sector, doneSectors, false, sectorsToDo, tag);
|
2020-04-13 04:40:35 +01:00
|
|
|
}
|
2022-03-06 13:29:38 +00:00
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
result = true;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
|
|
|
|
if(ForceChecked)
|
|
|
|
|
{
|
|
|
|
|
warning = true;
|
|
|
|
|
|
2025-08-17 06:11:22 +01:00
|
|
|
AaruLogging.Error(UI.Error_0_reading_sector_1_continuing, errno, doneSectors);
|
2020-04-13 04:40:35 +01:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2024-05-01 04:05:22 +01:00
|
|
|
await Dispatcher.UIThread.InvokeAsync(async () => await MessageBoxManager
|
|
|
|
|
.GetMessageBoxStandard(UI.Title_Error,
|
|
|
|
|
string
|
|
|
|
|
.Format(UI
|
|
|
|
|
.Error_0_reading_sector_1_not_continuing,
|
|
|
|
|
errno,
|
|
|
|
|
doneSectors),
|
|
|
|
|
icon: Icon.Error)
|
|
|
|
|
.ShowWindowDialogAsync(_view));
|
|
|
|
|
|
2025-08-19 15:17:19 +01:00
|
|
|
AaruLogging.Error(UI.Error_0_reading_sector_1_not_continuing, errno, doneSectors);
|
2020-04-13 04:40:35 +01:00
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
2022-03-06 13:29:38 +00:00
|
|
|
}
|
2020-04-13 04:40:35 +01:00
|
|
|
}
|
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if(!result)
|
2023-10-03 23:27:57 +01:00
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
if(ForceChecked)
|
|
|
|
|
{
|
|
|
|
|
warning = true;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2025-08-17 06:11:22 +01:00
|
|
|
AaruLogging.Error(UI.Error_0_writing_sector_1_continuing,
|
2025-08-19 15:17:19 +01:00
|
|
|
outputFormat.ErrorMessage,
|
|
|
|
|
doneSectors);
|
2022-03-06 13:29:38 +00:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2024-05-01 04:05:22 +01:00
|
|
|
await Dispatcher.UIThread.InvokeAsync(async () => await MessageBoxManager
|
|
|
|
|
.GetMessageBoxStandard(UI.Title_Error,
|
|
|
|
|
string
|
|
|
|
|
.Format(UI
|
|
|
|
|
.Error_0_writing_sector_1_not_continuing,
|
|
|
|
|
outputFormat
|
|
|
|
|
.ErrorMessage,
|
2023-10-03 23:27:57 +01:00
|
|
|
doneSectors),
|
2024-05-01 04:05:22 +01:00
|
|
|
icon: Icon.Error)
|
|
|
|
|
.ShowWindowDialogAsync(_view));
|
2020-07-14 02:16:53 +01:00
|
|
|
|
2025-08-17 06:11:22 +01:00
|
|
|
AaruLogging.Error(UI.Error_0_writing_sector_1_not_continuing,
|
2025-08-19 15:17:19 +01:00
|
|
|
outputFormat.ErrorMessage,
|
|
|
|
|
doneSectors);
|
2020-07-14 02:16:53 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
return;
|
|
|
|
|
}
|
2023-10-03 23:27:57 +01:00
|
|
|
}
|
2020-07-14 02:16:53 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
doneSectors += sectorsToDo;
|
2020-04-13 04:40:35 +01:00
|
|
|
}
|
2022-03-06 13:29:38 +00:00
|
|
|
|
|
|
|
|
await Dispatcher.UIThread.InvokeAsync(() =>
|
2020-04-13 04:40:35 +01:00
|
|
|
{
|
2024-05-01 04:05:22 +01:00
|
|
|
Progress2Text = string.Format(UI.Converting_tag_0_for_sectors_1_to_2_3_done,
|
|
|
|
|
tag,
|
|
|
|
|
_inputFormat.Info.Sectors,
|
|
|
|
|
_inputFormat.Info.Sectors,
|
|
|
|
|
1.0);
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
Progress2Value = Progress2MaxValue;
|
|
|
|
|
});
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2024-05-06 04:34:43 +01:00
|
|
|
foreach(KeyValuePair<byte, string> isrc in isrcs)
|
2023-10-03 23:27:57 +01:00
|
|
|
{
|
2024-05-06 04:34:43 +01:00
|
|
|
outputOptical.WriteSectorTag(Encoding.UTF8.GetBytes(isrc.Value),
|
|
|
|
|
isrc.Key,
|
2025-10-23 03:07:43 +01:00
|
|
|
false,
|
2024-05-06 04:34:43 +01:00
|
|
|
SectorTagType.CdTrackIsrc);
|
2023-10-03 23:27:57 +01:00
|
|
|
}
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2024-05-06 04:34:43 +01:00
|
|
|
foreach(KeyValuePair<byte, byte> flags in trackFlags)
|
2025-10-23 03:07:43 +01:00
|
|
|
outputOptical.WriteSectorTag([flags.Value], flags.Key, false, SectorTagType.CdTrackFlags);
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2024-05-01 04:05:22 +01:00
|
|
|
if(mcn != null) outputOptical.WriteMediaTag(Encoding.UTF8.GetBytes(mcn), MediaTagType.CD_MCN);
|
2022-03-06 13:29:38 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2022-03-16 00:31:33 +00:00
|
|
|
foreach(Track track in tracks.TakeWhile(_ => !_cancel))
|
2022-03-06 13:29:38 +00:00
|
|
|
{
|
|
|
|
|
doneSectors = 0;
|
|
|
|
|
ulong trackSectors = track.EndSector - track.StartSector + 1;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
await Dispatcher.UIThread.InvokeAsync(() =>
|
|
|
|
|
{
|
2022-11-19 21:10:41 +00:00
|
|
|
ProgressText = string.Format(UI.Converting_sectors_in_track_0, track.Sequence);
|
2022-03-06 13:29:38 +00:00
|
|
|
ProgressValue++;
|
|
|
|
|
Progress2Text = "";
|
|
|
|
|
Progress2Indeterminate = false;
|
|
|
|
|
Progress2MaxValue = (int)(trackSectors / SectorsValue);
|
|
|
|
|
});
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
while(doneSectors < trackSectors)
|
|
|
|
|
{
|
2024-05-01 04:05:22 +01:00
|
|
|
if(_cancel) break;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
byte[] sector;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
uint sectorsToDo;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if(trackSectors - doneSectors >= (ulong)SectorsValue)
|
|
|
|
|
sectorsToDo = (uint)SectorsValue;
|
|
|
|
|
else
|
|
|
|
|
sectorsToDo = (uint)(trackSectors - doneSectors);
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
ulong sectors = doneSectors;
|
2021-09-20 14:22:22 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
await Dispatcher.UIThread.InvokeAsync(() =>
|
|
|
|
|
{
|
2022-11-19 21:10:41 +00:00
|
|
|
Progress2Text = string.Format(UI.Converting_sectors_0_to_1_in_track_2_3_done,
|
|
|
|
|
sectors + track.StartSector,
|
2024-05-01 04:05:22 +01:00
|
|
|
sectors + sectorsToDo + track.StartSector,
|
|
|
|
|
track.Sequence,
|
2022-11-19 21:10:41 +00:00
|
|
|
(sectors + track.StartSector) /
|
|
|
|
|
(double)_inputFormat.Info.Sectors);
|
2021-09-20 14:22:22 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
Progress2Value = (int)(sectors / SectorsValue);
|
|
|
|
|
});
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2025-10-22 20:25:23 +01:00
|
|
|
bool result;
|
|
|
|
|
SectorStatus sectorStatus = SectorStatus.NotDumped;
|
|
|
|
|
var sectorStatusArray = new SectorStatus[1];
|
2021-09-20 14:22:22 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if(useLong)
|
|
|
|
|
{
|
|
|
|
|
errno = sectorsToDo == 1
|
2025-10-22 20:25:23 +01:00
|
|
|
? _inputFormat.ReadSectorLong(doneSectors + track.StartSector,
|
2025-10-23 03:07:43 +01:00
|
|
|
false,
|
2025-10-22 20:25:23 +01:00
|
|
|
out sector,
|
|
|
|
|
out sectorStatus)
|
2024-05-01 04:05:22 +01:00
|
|
|
: _inputFormat.ReadSectorsLong(doneSectors + track.StartSector,
|
2025-10-23 03:07:43 +01:00
|
|
|
false,
|
2024-05-01 04:05:22 +01:00
|
|
|
sectorsToDo,
|
2025-10-22 14:28:58 +01:00
|
|
|
out sector,
|
2025-10-22 20:25:23 +01:00
|
|
|
out sectorStatusArray);
|
2021-09-19 21:16:47 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if(errno == ErrorNumber.NoError)
|
2023-10-03 23:27:57 +01:00
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
result = sectorsToDo == 1
|
2025-10-22 20:25:23 +01:00
|
|
|
? outputFormat.WriteSectorLong(sector,
|
|
|
|
|
doneSectors + track.StartSector,
|
2025-10-23 03:07:43 +01:00
|
|
|
false,
|
2025-10-22 20:25:23 +01:00
|
|
|
sectorStatus)
|
2024-05-01 04:05:22 +01:00
|
|
|
: outputFormat.WriteSectorsLong(sector,
|
|
|
|
|
doneSectors + track.StartSector,
|
2025-10-23 03:07:43 +01:00
|
|
|
false,
|
2025-10-22 20:25:23 +01:00
|
|
|
sectorsToDo,
|
|
|
|
|
sectorStatusArray);
|
2023-10-03 23:27:57 +01:00
|
|
|
}
|
2022-03-06 13:29:38 +00:00
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
result = true;
|
2021-09-19 21:16:47 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if(ForceChecked)
|
|
|
|
|
{
|
|
|
|
|
warning = true;
|
2021-09-19 21:16:47 +01:00
|
|
|
|
2025-08-17 06:11:22 +01:00
|
|
|
AaruLogging.Error(UI.Error_0_reading_sector_1_continuing, errno, doneSectors);
|
2022-03-06 13:29:38 +00:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2024-05-01 04:05:22 +01:00
|
|
|
await Dispatcher.UIThread.InvokeAsync(async () => await MessageBoxManager
|
|
|
|
|
.GetMessageBoxStandard(UI.Title_Error,
|
|
|
|
|
string
|
|
|
|
|
.Format(UI
|
|
|
|
|
.Error_0_reading_sector_1_not_continuing,
|
|
|
|
|
errno,
|
|
|
|
|
doneSectors),
|
|
|
|
|
icon: Icon.Error)
|
|
|
|
|
.ShowWindowDialogAsync(_view));
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
return;
|
2020-04-13 04:40:35 +01:00
|
|
|
}
|
|
|
|
|
}
|
2022-03-06 13:29:38 +00:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2023-10-03 23:27:57 +01:00
|
|
|
errno = sectorsToDo == 1
|
2025-10-22 20:25:23 +01:00
|
|
|
? _inputFormat.ReadSector(doneSectors + track.StartSector,
|
2025-10-23 03:07:43 +01:00
|
|
|
false,
|
2025-10-22 20:25:23 +01:00
|
|
|
out sector,
|
|
|
|
|
out sectorStatus)
|
2024-05-01 04:05:22 +01:00
|
|
|
: _inputFormat.ReadSectors(doneSectors + track.StartSector,
|
2025-10-23 03:07:43 +01:00
|
|
|
false,
|
2024-05-01 04:05:22 +01:00
|
|
|
sectorsToDo,
|
2025-10-22 14:28:58 +01:00
|
|
|
out sector,
|
2025-10-22 20:25:23 +01:00
|
|
|
out sectorStatusArray);
|
2022-03-06 13:29:38 +00:00
|
|
|
|
|
|
|
|
if(errno == ErrorNumber.NoError)
|
2023-10-03 23:27:57 +01:00
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
result = sectorsToDo == 1
|
2025-10-22 20:25:23 +01:00
|
|
|
? outputFormat.WriteSector(sector,
|
|
|
|
|
doneSectors + track.StartSector,
|
2025-10-23 03:07:43 +01:00
|
|
|
false,
|
2025-10-22 20:25:23 +01:00
|
|
|
sectorStatus)
|
2024-05-01 04:05:22 +01:00
|
|
|
: outputFormat.WriteSectors(sector,
|
|
|
|
|
doneSectors + track.StartSector,
|
2025-10-23 03:07:43 +01:00
|
|
|
false,
|
2025-10-22 20:25:23 +01:00
|
|
|
sectorsToDo,
|
|
|
|
|
sectorStatusArray);
|
2023-10-03 23:27:57 +01:00
|
|
|
}
|
2022-03-06 13:29:38 +00:00
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
result = true;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
|
|
|
|
if(ForceChecked)
|
|
|
|
|
{
|
|
|
|
|
warning = true;
|
|
|
|
|
|
2025-08-17 06:11:22 +01:00
|
|
|
AaruLogging.Error(UI.Error_0_reading_sector_1_continuing, errno, doneSectors);
|
2020-04-13 04:40:35 +01:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2024-05-01 04:05:22 +01:00
|
|
|
await Dispatcher.UIThread.InvokeAsync(async () => await MessageBoxManager
|
|
|
|
|
.GetMessageBoxStandard(UI.Title_Error,
|
|
|
|
|
string
|
|
|
|
|
.Format(UI
|
|
|
|
|
.Error_0_reading_sector_1_not_continuing,
|
|
|
|
|
errno,
|
|
|
|
|
doneSectors),
|
|
|
|
|
icon: Icon.Error)
|
|
|
|
|
.ShowWindowDialogAsync(_view));
|
2020-04-13 04:40:35 +01:00
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
2022-03-06 13:29:38 +00:00
|
|
|
}
|
2020-04-13 04:40:35 +01:00
|
|
|
}
|
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if(!result)
|
2023-10-03 23:27:57 +01:00
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
if(ForceChecked)
|
2020-04-13 04:40:35 +01:00
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
warning = true;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2025-08-17 06:11:22 +01:00
|
|
|
AaruLogging.Error(UI.Error_0_writing_sector_1_continuing,
|
2025-08-19 15:17:19 +01:00
|
|
|
outputFormat.ErrorMessage,
|
|
|
|
|
doneSectors);
|
2022-03-06 13:29:38 +00:00
|
|
|
}
|
|
|
|
|
else
|
2020-04-13 04:40:35 +01:00
|
|
|
{
|
2024-05-01 04:05:22 +01:00
|
|
|
await Dispatcher.UIThread.InvokeAsync(async () => await MessageBoxManager
|
|
|
|
|
.GetMessageBoxStandard(UI.Title_Error,
|
|
|
|
|
string
|
|
|
|
|
.Format(UI
|
|
|
|
|
.Error_0_writing_sector_1_not_continuing,
|
|
|
|
|
outputFormat
|
|
|
|
|
.ErrorMessage,
|
2023-10-03 23:27:57 +01:00
|
|
|
doneSectors),
|
2024-05-01 04:05:22 +01:00
|
|
|
icon: Icon.Error)
|
|
|
|
|
.ShowWindowDialogAsync(_view));
|
2021-09-20 20:52:18 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
return;
|
|
|
|
|
}
|
2023-10-03 23:27:57 +01:00
|
|
|
}
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
doneSectors += sectorsToDo;
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
await Dispatcher.UIThread.InvokeAsync(() =>
|
|
|
|
|
{
|
2024-05-01 04:05:22 +01:00
|
|
|
Progress2Text = string.Format(UI.Converting_sectors_0_to_1_in_track_2_3_done,
|
|
|
|
|
_inputFormat.Info.Sectors,
|
|
|
|
|
_inputFormat.Info.Sectors,
|
|
|
|
|
tracks.Count,
|
|
|
|
|
1.0);
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
Progress2Value = Progress2MaxValue;
|
|
|
|
|
});
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2024-05-01 04:05:22 +01:00
|
|
|
foreach(SectorTagType tag in _inputFormat.Info.ReadableSectorTags.OrderBy(t => t)
|
|
|
|
|
.TakeWhile(_ => useLong && !_cancel))
|
2022-03-06 13:29:38 +00:00
|
|
|
{
|
|
|
|
|
switch(tag)
|
|
|
|
|
{
|
2025-10-18 16:17:35 +01:00
|
|
|
case SectorTagType.AppleSonyTag:
|
|
|
|
|
case SectorTagType.AppleProfileTag:
|
|
|
|
|
case SectorTagType.PriamDataTowerTag:
|
2022-03-06 13:29:38 +00:00
|
|
|
case SectorTagType.CdSectorSync:
|
|
|
|
|
case SectorTagType.CdSectorHeader:
|
|
|
|
|
case SectorTagType.CdSectorSubHeader:
|
|
|
|
|
case SectorTagType.CdSectorEdc:
|
|
|
|
|
case SectorTagType.CdSectorEccP:
|
|
|
|
|
case SectorTagType.CdSectorEccQ:
|
|
|
|
|
case SectorTagType.CdSectorEcc:
|
|
|
|
|
// This tags are inline in long sector
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2024-05-01 04:05:22 +01:00
|
|
|
if(ForceChecked && !outputFormat.SupportedSectorTags.Contains(tag)) continue;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-16 00:31:33 +00:00
|
|
|
foreach(Track track in tracks.TakeWhile(_ => !_cancel))
|
2022-03-06 13:29:38 +00:00
|
|
|
{
|
|
|
|
|
doneSectors = 0;
|
|
|
|
|
ulong trackSectors = track.EndSector - track.StartSector + 1;
|
|
|
|
|
byte[] sector;
|
|
|
|
|
bool result;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
await Dispatcher.UIThread.InvokeAsync(() =>
|
|
|
|
|
{
|
|
|
|
|
ProgressText = $"Converting tag {tag} in track {track.Sequence}.";
|
|
|
|
|
ProgressValue++;
|
|
|
|
|
Progress2Text = "";
|
|
|
|
|
Progress2Indeterminate = false;
|
|
|
|
|
Progress2MaxValue = (int)(trackSectors / SectorsValue);
|
|
|
|
|
});
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
switch(tag)
|
|
|
|
|
{
|
|
|
|
|
case SectorTagType.CdTrackFlags:
|
|
|
|
|
case SectorTagType.CdTrackIsrc:
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2025-10-23 03:07:43 +01:00
|
|
|
errno = _inputFormat.ReadSectorTag(track.Sequence, false, tag, out sector);
|
2021-09-20 20:52:18 +01:00
|
|
|
|
|
|
|
|
if(errno == ErrorNumber.NoError)
|
2025-10-23 03:07:43 +01:00
|
|
|
result = outputFormat.WriteSectorTag(sector, track.Sequence, false, tag);
|
2020-04-13 04:40:35 +01:00
|
|
|
else
|
|
|
|
|
{
|
2021-09-20 20:52:18 +01:00
|
|
|
if(ForceChecked)
|
|
|
|
|
{
|
|
|
|
|
warning = true;
|
|
|
|
|
|
2025-08-17 06:11:22 +01:00
|
|
|
AaruLogging.Error(UI.Error_0_reading_media_tag, errno);
|
2021-09-20 20:52:18 +01:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2024-05-01 04:05:22 +01:00
|
|
|
await Dispatcher.UIThread.InvokeAsync(async () => await MessageBoxManager
|
|
|
|
|
.GetMessageBoxStandard(UI.Title_Error,
|
|
|
|
|
string
|
|
|
|
|
.Format(UI
|
|
|
|
|
.Error_0_reading_media_tag_not_continuing,
|
2023-10-04 17:34:40 +01:00
|
|
|
errno),
|
2024-05-01 04:05:22 +01:00
|
|
|
icon: Icon.Error)
|
|
|
|
|
.ShowWindowDialogAsync(_view));
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2021-09-20 20:52:18 +01:00
|
|
|
return;
|
|
|
|
|
}
|
2022-03-06 13:29:38 +00:00
|
|
|
|
|
|
|
|
continue;
|
2020-04-13 04:40:35 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(!result)
|
2023-10-03 23:27:57 +01:00
|
|
|
{
|
2020-04-13 04:40:35 +01:00
|
|
|
if(ForceChecked)
|
|
|
|
|
{
|
|
|
|
|
warning = true;
|
|
|
|
|
|
2025-08-19 15:17:19 +01:00
|
|
|
AaruLogging.Error(UI.Error_0_writing_tag_continuing, outputFormat.ErrorMessage);
|
2020-04-13 04:40:35 +01:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2024-05-01 04:05:22 +01:00
|
|
|
await Dispatcher.UIThread.InvokeAsync(async () => await MessageBoxManager
|
|
|
|
|
.GetMessageBoxStandard(UI.Title_Error,
|
|
|
|
|
string
|
|
|
|
|
.Format(UI
|
|
|
|
|
.Error_0_writing_tag_not_continuing,
|
|
|
|
|
outputFormat
|
|
|
|
|
.ErrorMessage),
|
|
|
|
|
icon: Icon.Error)
|
|
|
|
|
.ShowWindowDialogAsync(_view));
|
2020-04-13 04:40:35 +01:00
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
2023-10-03 23:27:57 +01:00
|
|
|
}
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
continue;
|
2020-04-13 04:40:35 +01:00
|
|
|
}
|
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
while(doneSectors < trackSectors)
|
|
|
|
|
{
|
2024-05-01 04:05:22 +01:00
|
|
|
if(_cancel) break;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
uint sectorsToDo;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if(trackSectors - doneSectors >= (ulong)SectorsValue)
|
|
|
|
|
sectorsToDo = (uint)SectorsValue;
|
|
|
|
|
else
|
|
|
|
|
sectorsToDo = (uint)(trackSectors - doneSectors);
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
ulong sectors = doneSectors;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
await Dispatcher.UIThread.InvokeAsync(() =>
|
|
|
|
|
{
|
2024-05-01 04:05:22 +01:00
|
|
|
Progress2Text = string.Format(UI.Converting_tag_0_for_sectors_1_to_2_in_track_3_4_done,
|
|
|
|
|
tag,
|
2022-11-19 21:10:41 +00:00
|
|
|
sectors + track.StartSector,
|
2024-05-01 04:05:22 +01:00
|
|
|
sectors + sectorsToDo + track.StartSector,
|
|
|
|
|
track.Sequence,
|
2022-11-19 21:10:41 +00:00
|
|
|
(sectors + track.StartSector) /
|
|
|
|
|
(double)_inputFormat.Info.Sectors);
|
2022-03-06 13:29:38 +00:00
|
|
|
|
|
|
|
|
Progress2Value = (int)(sectors / SectorsValue);
|
|
|
|
|
});
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
errno = sectorsToDo == 1
|
2025-10-23 03:07:43 +01:00
|
|
|
? _inputFormat.ReadSectorTag(doneSectors + track.StartSector,
|
|
|
|
|
false,
|
|
|
|
|
tag,
|
|
|
|
|
out sector)
|
2024-05-01 04:05:22 +01:00
|
|
|
: _inputFormat.ReadSectorsTag(doneSectors + track.StartSector,
|
2025-10-23 03:07:43 +01:00
|
|
|
false,
|
2024-05-01 04:05:22 +01:00
|
|
|
sectorsToDo,
|
|
|
|
|
tag,
|
2022-03-06 13:29:38 +00:00
|
|
|
out sector);
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if(errno == ErrorNumber.NoError)
|
2023-10-03 23:27:57 +01:00
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
result = sectorsToDo == 1
|
2025-10-23 03:07:43 +01:00
|
|
|
? outputFormat.WriteSectorTag(sector,
|
|
|
|
|
doneSectors + track.StartSector,
|
|
|
|
|
false,
|
|
|
|
|
tag)
|
2024-05-01 04:05:22 +01:00
|
|
|
: outputFormat.WriteSectorsTag(sector,
|
|
|
|
|
doneSectors + track.StartSector,
|
2025-10-23 03:07:43 +01:00
|
|
|
false,
|
2024-05-01 04:05:22 +01:00
|
|
|
sectorsToDo,
|
|
|
|
|
tag);
|
2023-10-03 23:27:57 +01:00
|
|
|
}
|
2022-03-06 13:29:38 +00:00
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
result = true;
|
|
|
|
|
|
|
|
|
|
if(ForceChecked)
|
|
|
|
|
{
|
|
|
|
|
warning = true;
|
|
|
|
|
|
2025-08-19 15:17:19 +01:00
|
|
|
AaruLogging.Error(UI.Error_0_reading_tag_for_sector_1_continuing, errno, doneSectors);
|
2022-03-06 13:29:38 +00:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2024-05-01 04:05:22 +01:00
|
|
|
await Dispatcher.UIThread.InvokeAsync(async () => await MessageBoxManager
|
|
|
|
|
.GetMessageBoxStandard(UI.Title_Error,
|
|
|
|
|
string
|
|
|
|
|
.Format(UI
|
|
|
|
|
.Error_0_reading_tag_for_sector_1_not_continuing,
|
|
|
|
|
errno,
|
|
|
|
|
doneSectors),
|
|
|
|
|
icon: Icon.Error)
|
|
|
|
|
.ShowWindowDialogAsync(_view));
|
2022-03-06 13:29:38 +00:00
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(!result)
|
2023-10-03 23:27:57 +01:00
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
if(ForceChecked)
|
|
|
|
|
{
|
|
|
|
|
warning = true;
|
|
|
|
|
|
2025-08-17 06:11:22 +01:00
|
|
|
AaruLogging.Error(UI.Error_0_writing_tag_for_sector_1_continuing,
|
2025-08-19 15:17:19 +01:00
|
|
|
outputFormat.ErrorMessage,
|
|
|
|
|
doneSectors);
|
2022-03-06 13:29:38 +00:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2024-05-01 04:05:22 +01:00
|
|
|
await Dispatcher.UIThread.InvokeAsync(async () => await MessageBoxManager
|
|
|
|
|
.GetMessageBoxStandard(UI.Title_Error,
|
|
|
|
|
string
|
|
|
|
|
.Format(UI
|
|
|
|
|
.Error_0_writing_tag_for_sector_1_not_continuing,
|
|
|
|
|
outputFormat
|
|
|
|
|
.ErrorMessage,
|
2022-11-19 21:10:41 +00:00
|
|
|
doneSectors),
|
2024-05-01 04:05:22 +01:00
|
|
|
icon: Icon.Error)
|
|
|
|
|
.ShowWindowDialogAsync(_view));
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
return;
|
|
|
|
|
}
|
2023-10-03 23:27:57 +01:00
|
|
|
}
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
doneSectors += sectorsToDo;
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-04-13 04:40:35 +01:00
|
|
|
}
|
2022-03-06 13:29:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
await Dispatcher.UIThread.InvokeAsync(() =>
|
|
|
|
|
{
|
|
|
|
|
Progress2Visible = false;
|
|
|
|
|
Progress2Visible = false;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
bool ret;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2023-10-04 17:34:40 +01:00
|
|
|
if(_dumpHardware != null && !_cancel)
|
2022-03-06 13:29:38 +00:00
|
|
|
{
|
2020-04-13 04:40:35 +01:00
|
|
|
await Dispatcher.UIThread.InvokeAsync(() =>
|
|
|
|
|
{
|
2022-11-19 21:10:41 +00:00
|
|
|
ProgressText = UI.Writing_dump_hardware_list;
|
2022-03-06 13:29:38 +00:00
|
|
|
ProgressValue++;
|
2020-04-13 04:40:35 +01:00
|
|
|
});
|
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
ret = outputFormat.SetDumpHardware(_dumpHardware);
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if(!ret)
|
2025-08-17 06:11:22 +01:00
|
|
|
AaruLogging.WriteLine(UI.Error_0_writing_dump_hardware_list_to_output_image, outputFormat.ErrorMessage);
|
2022-03-06 13:29:38 +00:00
|
|
|
}
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
ret = false;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2023-10-04 17:34:40 +01:00
|
|
|
if(_aaruMetadata != null && !_cancel)
|
2022-03-06 13:29:38 +00:00
|
|
|
{
|
|
|
|
|
await Dispatcher.UIThread.InvokeAsync(() =>
|
2020-04-13 04:40:35 +01:00
|
|
|
{
|
2022-12-15 22:21:07 +00:00
|
|
|
ProgressText = UI.Writing_Aaru_Metadata_to_output_image;
|
2022-03-06 13:29:38 +00:00
|
|
|
ProgressValue++;
|
|
|
|
|
});
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-12-15 22:21:07 +00:00
|
|
|
outputFormat.SetMetadata(_aaruMetadata);
|
2022-03-06 13:29:38 +00:00
|
|
|
|
2025-08-17 06:11:22 +01:00
|
|
|
if(!ret) AaruLogging.WriteLine(UI.Error_0_writing_Aaru_Metadata_to_output_image, outputFormat.ErrorMessage);
|
2022-03-06 13:29:38 +00:00
|
|
|
}
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
await Dispatcher.UIThread.InvokeAsync(() =>
|
|
|
|
|
{
|
2022-11-19 21:10:41 +00:00
|
|
|
ProgressText = UI.Closing_output_image;
|
2022-03-06 13:29:38 +00:00
|
|
|
ProgressIndeterminate = true;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if(_cancel)
|
|
|
|
|
{
|
2023-09-25 22:58:48 +01:00
|
|
|
await Dispatcher.UIThread.InvokeAsync(async () =>
|
2020-04-13 04:40:35 +01:00
|
|
|
{
|
2024-05-01 04:05:22 +01:00
|
|
|
await MessageBoxManager
|
|
|
|
|
.GetMessageBoxStandard(UI.Title_Error,
|
|
|
|
|
UI.Operation_canceled_the_output_file_is_not_correct,
|
|
|
|
|
icon: Icon.Error)
|
|
|
|
|
.ShowWindowDialogAsync(_view);
|
2020-04-13 04:40:35 +01:00
|
|
|
|
|
|
|
|
CloseVisible = true;
|
|
|
|
|
StopVisible = false;
|
|
|
|
|
ProgressVisible = false;
|
|
|
|
|
});
|
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
return;
|
2020-04-13 04:40:35 +01:00
|
|
|
}
|
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if(!outputFormat.Close())
|
2020-04-13 04:40:35 +01:00
|
|
|
{
|
2024-05-01 04:05:22 +01:00
|
|
|
await Dispatcher.UIThread.InvokeAsync(async () => await MessageBoxManager
|
|
|
|
|
.GetMessageBoxStandard(UI.Title_Error,
|
|
|
|
|
string
|
|
|
|
|
.Format(UI
|
|
|
|
|
.Error_0_closing_output_image_Contents_are_not_correct,
|
2023-10-04 17:34:40 +01:00
|
|
|
outputFormat.ErrorMessage),
|
2024-05-01 04:05:22 +01:00
|
|
|
icon: Icon.Error)
|
|
|
|
|
.ShowWindowDialogAsync(_view));
|
2022-03-06 13:29:38 +00:00
|
|
|
|
|
|
|
|
return;
|
2020-04-13 04:40:35 +01:00
|
|
|
}
|
|
|
|
|
|
2023-09-25 22:58:48 +01:00
|
|
|
await Dispatcher.UIThread.InvokeAsync(async () =>
|
2022-03-06 13:29:38 +00:00
|
|
|
{
|
2023-10-04 17:34:40 +01:00
|
|
|
await MessageBoxManager.GetMessageBoxStandard(warning ? UI.Title_Warning : UI.Title_Conversion_success,
|
|
|
|
|
warning
|
|
|
|
|
? UI.Some_warnings_happened_Check_console
|
|
|
|
|
: UI.Image_converted_successfully,
|
2024-05-01 04:05:22 +01:00
|
|
|
icon: warning ? Icon.Warning : Icon.Info)
|
|
|
|
|
.ShowWindowDialogAsync(_view);
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
CloseVisible = true;
|
|
|
|
|
StopVisible = false;
|
|
|
|
|
ProgressVisible = false;
|
|
|
|
|
});
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
Statistics.AddCommand("convert-image");
|
|
|
|
|
}
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2025-08-20 21:19:43 +01:00
|
|
|
void Close() => _view.Close();
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2025-08-20 21:19:43 +01:00
|
|
|
internal void Stop()
|
2022-03-06 13:29:38 +00:00
|
|
|
{
|
|
|
|
|
_cancel = true;
|
|
|
|
|
StopEnabled = false;
|
|
|
|
|
}
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
/* TODO
|
|
|
|
|
void OnCmbFormatSelectedIndexChanged()
|
|
|
|
|
{
|
|
|
|
|
txtDestination.Text = "";
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if(!(cmbFormat.SelectedValue is IWritableImage plugin))
|
|
|
|
|
{
|
|
|
|
|
grpOptions.Visible = false;
|
|
|
|
|
btnDestination.Enabled = false;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
return;
|
|
|
|
|
}
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
btnDestination.Enabled = true;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if(!plugin.SupportedOptions.Any())
|
|
|
|
|
{
|
|
|
|
|
grpOptions.Content = null;
|
|
|
|
|
grpOptions.Visible = false;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
return;
|
|
|
|
|
}
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
chkForce.Visible = false;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
foreach(MediaTagType mediaTag in inputFormat.Info.ReadableMediaTags)
|
|
|
|
|
{
|
|
|
|
|
if(plugin.SupportedMediaTags.Contains(mediaTag))
|
|
|
|
|
continue;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
chkForce.Visible = true;
|
|
|
|
|
ForceChecked = true;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
break;
|
|
|
|
|
}
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
foreach(SectorTagType sectorTag in inputFormat.Info.ReadableSectorTags)
|
|
|
|
|
{
|
|
|
|
|
if(plugin.SupportedSectorTags.Contains(sectorTag))
|
|
|
|
|
continue;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
chkForce.Visible = true;
|
|
|
|
|
ForceChecked = true;
|
|
|
|
|
|
|
|
|
|
break;
|
2020-04-13 04:40:35 +01:00
|
|
|
}
|
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
grpOptions.Visible = true;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
var stkImageOptions = new StackLayout
|
|
|
|
|
{
|
|
|
|
|
Orientation = Orientation.Vertical
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
foreach((string name, Type type, string description, object @default) option in plugin.SupportedOptions)
|
|
|
|
|
switch(option.type.ToString())
|
|
|
|
|
{
|
|
|
|
|
case "System.Boolean":
|
|
|
|
|
var optBoolean = new CheckBox();
|
|
|
|
|
optBoolean.ID = "opt" + option.name;
|
|
|
|
|
optBoolean.Text = option.description;
|
|
|
|
|
optBooleanChecked = (bool)option.@default;
|
|
|
|
|
stkImageOptions.Items.Add(optBoolean);
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
break;
|
|
|
|
|
case "System.SByte":
|
|
|
|
|
case "System.Int16":
|
|
|
|
|
case "System.Int32":
|
|
|
|
|
case "System.Int64":
|
|
|
|
|
var stkNumber = new StackLayout();
|
|
|
|
|
stkNumber.Orientation = Orientation.Horizontal;
|
|
|
|
|
var optNumber = new NumericStepper();
|
|
|
|
|
optNumber.ID = "opt" + option.name;
|
|
|
|
|
optNumber.Value = Convert.ToDouble(option.@default);
|
|
|
|
|
stkNumber.Items.Add(optNumber);
|
|
|
|
|
var lblNumber = new Label();
|
|
|
|
|
lblNumber.Text = option.description;
|
|
|
|
|
stkNumber.Items.Add(lblNumber);
|
|
|
|
|
stkImageOptions.Items.Add(stkNumber);
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
break;
|
|
|
|
|
case "System.Byte":
|
|
|
|
|
case "System.UInt16":
|
|
|
|
|
case "System.UInt32":
|
|
|
|
|
case "System.UInt64":
|
|
|
|
|
var stkUnsigned = new StackLayout();
|
|
|
|
|
stkUnsigned.Orientation = Orientation.Horizontal;
|
|
|
|
|
var optUnsigned = new NumericStepper();
|
|
|
|
|
optUnsigned.ID = "opt" + option.name;
|
|
|
|
|
optUnsigned.MinValue = 0;
|
|
|
|
|
optUnsigned.Value = Convert.ToDouble(option.@default);
|
|
|
|
|
stkUnsigned.Items.Add(optUnsigned);
|
|
|
|
|
var lblUnsigned = new Label();
|
|
|
|
|
lblUnsigned.Text = option.description;
|
|
|
|
|
stkUnsigned.Items.Add(lblUnsigned);
|
|
|
|
|
stkImageOptions.Items.Add(stkUnsigned);
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
break;
|
|
|
|
|
case "System.Single":
|
|
|
|
|
case "System.Double":
|
|
|
|
|
var stkFloat = new StackLayout();
|
|
|
|
|
stkFloat.Orientation = Orientation.Horizontal;
|
|
|
|
|
var optFloat = new NumericStepper();
|
|
|
|
|
optFloat.ID = "opt" + option.name;
|
|
|
|
|
optFloat.DecimalPlaces = 2;
|
|
|
|
|
optFloat.Value = Convert.ToDouble(option.@default);
|
|
|
|
|
stkFloat.Items.Add(optFloat);
|
|
|
|
|
var lblFloat = new Label();
|
|
|
|
|
lblFloat.Text = option.description;
|
|
|
|
|
stkFloat.Items.Add(lblFloat);
|
|
|
|
|
stkImageOptions.Items.Add(stkFloat);
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
case "System.Guid":
|
|
|
|
|
// TODO
|
|
|
|
|
break;
|
|
|
|
|
case "System.String":
|
|
|
|
|
var stkString = new StackLayout();
|
|
|
|
|
stkString.Orientation = Orientation.Horizontal;
|
|
|
|
|
var lblString = new Label();
|
|
|
|
|
lblString.Text = option.description;
|
|
|
|
|
stkString.Items.Add(lblString);
|
|
|
|
|
var optString = new TextBox();
|
|
|
|
|
optString.ID = "opt" + option.name;
|
|
|
|
|
optString.Text = (string)option.@default;
|
|
|
|
|
stkString.Items.Add(optString);
|
|
|
|
|
stkImageOptions.Items.Add(stkString);
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
grpOptions.Content = stkImageOptions;
|
2020-04-13 04:40:35 +01:00
|
|
|
}
|
2022-03-06 13:29:38 +00:00
|
|
|
*/
|
2025-08-20 21:19:43 +01:00
|
|
|
async Task DestinationAsync()
|
2022-03-06 13:29:38 +00:00
|
|
|
{
|
2024-05-01 04:05:22 +01:00
|
|
|
if(SelectedPlugin is null) return;
|
2022-03-06 13:29:38 +00:00
|
|
|
|
2024-05-02 00:50:34 +01:00
|
|
|
IStorageFile result = await _view.StorageProvider.SaveFilePickerAsync(new FilePickerSaveOptions
|
2022-03-06 13:29:38 +00:00
|
|
|
{
|
2024-05-02 00:50:34 +01:00
|
|
|
Title = UI.Dialog_Choose_destination_file,
|
|
|
|
|
FileTypeChoices = new List<FilePickerFileType>
|
|
|
|
|
{
|
|
|
|
|
new(SelectedPlugin.Plugin.Name)
|
|
|
|
|
{
|
|
|
|
|
Patterns = SelectedPlugin.Plugin.KnownExtensions.ToList()
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-03-06 13:29:38 +00:00
|
|
|
});
|
|
|
|
|
|
2024-05-02 00:50:34 +01:00
|
|
|
if(result is null)
|
2022-03-06 13:29:38 +00:00
|
|
|
{
|
|
|
|
|
DestinationText = "";
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
return;
|
2020-04-13 04:40:35 +01:00
|
|
|
}
|
|
|
|
|
|
2024-05-02 00:50:34 +01:00
|
|
|
DestinationText = result.Path.AbsolutePath;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2024-05-02 00:50:34 +01:00
|
|
|
if(string.IsNullOrEmpty(Path.GetExtension(DestinationText)))
|
|
|
|
|
DestinationText += SelectedPlugin.Plugin.KnownExtensions.First();
|
2022-03-06 13:29:38 +00:00
|
|
|
}
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2025-08-20 21:19:43 +01:00
|
|
|
void Creator() => CreatorText = _inputFormat.Info.Creator;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2025-08-20 21:19:43 +01:00
|
|
|
void MediaTitle() => MediaTitleText = _inputFormat.Info.MediaTitle;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2025-08-20 21:19:43 +01:00
|
|
|
void Comments() => CommentsText = _inputFormat.Info.Comments;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2025-08-20 21:19:43 +01:00
|
|
|
void MediaManufacturer() => MediaManufacturerText = _inputFormat.Info.MediaManufacturer;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2025-08-20 21:19:43 +01:00
|
|
|
void MediaModel() => MediaModelText = _inputFormat.Info.MediaModel;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2025-08-20 21:19:43 +01:00
|
|
|
void MediaSerialNumber() => MediaSerialNumberText = _inputFormat.Info.MediaSerialNumber;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2025-08-20 21:19:43 +01:00
|
|
|
void MediaBarcode() => MediaBarcodeText = _inputFormat.Info.MediaBarcode;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2025-08-20 21:19:43 +01:00
|
|
|
void MediaPartNumber() => MediaPartNumberText = _inputFormat.Info.MediaPartNumber;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2025-08-20 21:19:43 +01:00
|
|
|
void MediaSequence() => MediaSequenceValue = _inputFormat.Info.MediaSequence;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2025-08-20 21:19:43 +01:00
|
|
|
void LastMediaSequence() => LastMediaSequenceValue = _inputFormat.Info.LastMediaSequence;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2025-08-20 21:19:43 +01:00
|
|
|
void DriveManufacturer() => DriveManufacturerText = _inputFormat.Info.DriveManufacturer;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2025-08-20 21:19:43 +01:00
|
|
|
void DriveModel() => DriveModelText = _inputFormat.Info.DriveModel;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2025-08-20 21:19:43 +01:00
|
|
|
void DriveSerialNumber() => DriveSerialNumberText = _inputFormat.Info.DriveSerialNumber;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2025-08-20 21:19:43 +01:00
|
|
|
void DriveFirmwareRevision() => DriveFirmwareRevisionText = _inputFormat.Info.DriveFirmwareRevision;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2025-08-20 21:19:43 +01:00
|
|
|
void AaruMetadataFromImage()
|
2022-03-06 13:29:38 +00:00
|
|
|
{
|
2022-12-15 22:21:07 +00:00
|
|
|
MetadataJsonText = UI._From_image_;
|
|
|
|
|
_aaruMetadata = _inputFormat.AaruMetadata;
|
2022-03-06 13:29:38 +00:00
|
|
|
}
|
|
|
|
|
|
2025-08-20 21:19:43 +01:00
|
|
|
async Task AaruMetadataAsync()
|
2022-03-06 13:29:38 +00:00
|
|
|
{
|
2022-12-15 22:21:07 +00:00
|
|
|
_aaruMetadata = null;
|
|
|
|
|
MetadataJsonText = "";
|
2022-03-06 13:29:38 +00:00
|
|
|
|
2024-05-02 00:50:34 +01:00
|
|
|
IReadOnlyList<IStorageFile> result = _view.StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
|
|
|
|
|
{
|
|
|
|
|
Title = UI.Dialog_Choose_existing_metadata_sidecar,
|
|
|
|
|
AllowMultiple = false,
|
|
|
|
|
FileTypeFilter = new List<FilePickerFileType>
|
|
|
|
|
{
|
|
|
|
|
FilePickerFileTypes.AaruMetadata
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.Result;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2024-05-02 00:50:34 +01:00
|
|
|
if(result.Count != 1) return;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
try
|
|
|
|
|
{
|
2024-05-02 00:50:34 +01:00
|
|
|
var fs = new FileStream(result[0].Path.AbsolutePath, FileMode.Open);
|
2022-12-15 22:21:07 +00:00
|
|
|
|
2022-12-16 04:05:09 +00:00
|
|
|
_aaruMetadata =
|
|
|
|
|
(await JsonSerializer.DeserializeAsync(fs, typeof(MetadataJson), MetadataJsonContext.Default) as
|
|
|
|
|
MetadataJson)?.AaruMetadata;
|
2022-12-16 03:05:50 +00:00
|
|
|
|
|
|
|
|
fs.Close();
|
2024-05-02 00:50:34 +01:00
|
|
|
MetadataJsonText = result[0].Path.AbsolutePath;
|
2020-04-13 04:40:35 +01:00
|
|
|
}
|
2025-08-20 18:51:05 +01:00
|
|
|
catch(Exception ex)
|
2020-04-13 04:40:35 +01:00
|
|
|
{
|
2025-08-20 18:51:05 +01:00
|
|
|
SentrySdk.CaptureException(ex);
|
|
|
|
|
|
2024-05-01 04:05:22 +01:00
|
|
|
await MessageBoxManager
|
|
|
|
|
.GetMessageBoxStandard(UI.Title_Error, UI.Incorrect_metadata_sidecar_file, icon: Icon.Error)
|
|
|
|
|
.ShowWindowDialogAsync(_view);
|
2020-04-13 04:40:35 +01:00
|
|
|
}
|
2022-03-06 13:29:38 +00:00
|
|
|
}
|
|
|
|
|
|
2025-08-20 21:19:43 +01:00
|
|
|
void ResumeFileFromImage()
|
2022-03-06 13:29:38 +00:00
|
|
|
{
|
2022-11-19 21:10:41 +00:00
|
|
|
ResumeFileText = UI._From_image_;
|
2022-03-06 13:29:38 +00:00
|
|
|
_dumpHardware = _inputFormat.DumpHardware;
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-20 21:19:43 +01:00
|
|
|
async Task ResumeFileAsync()
|
2022-03-06 13:29:38 +00:00
|
|
|
{
|
|
|
|
|
_dumpHardware = null;
|
|
|
|
|
ResumeFileText = "";
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2024-05-02 00:50:34 +01:00
|
|
|
IReadOnlyList<IStorageFile> result = _view.StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
|
|
|
|
|
{
|
|
|
|
|
Title = UI.Dialog_Choose_existing_resume_file,
|
|
|
|
|
AllowMultiple = false,
|
|
|
|
|
FileTypeFilter = new List<FilePickerFileType>
|
|
|
|
|
{
|
|
|
|
|
FilePickerFileTypes.AaruResumeFile
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.Result;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2024-05-02 00:50:34 +01:00
|
|
|
if(result.Count != 1) return;
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
try
|
|
|
|
|
{
|
2024-05-02 00:50:34 +01:00
|
|
|
var fs = new FileStream(result[0].Path.AbsolutePath, FileMode.Open);
|
2022-12-16 18:01:11 +00:00
|
|
|
|
|
|
|
|
Resume resume =
|
2024-05-01 04:05:22 +01:00
|
|
|
(await JsonSerializer.DeserializeAsync(fs, typeof(ResumeJson), ResumeJsonContext.Default) as ResumeJson)
|
|
|
|
|
?.Resume;
|
2022-12-16 18:01:11 +00:00
|
|
|
|
|
|
|
|
fs.Close();
|
2020-04-13 04:40:35 +01:00
|
|
|
|
2022-03-17 00:46:26 +00:00
|
|
|
if(resume?.Tries?.Any() == false)
|
2020-04-13 04:40:35 +01:00
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
_dumpHardware = resume.Tries;
|
2024-05-02 00:50:34 +01:00
|
|
|
ResumeFileText = result[0].Path.AbsolutePath;
|
2020-04-13 04:40:35 +01:00
|
|
|
}
|
2022-03-06 13:29:38 +00:00
|
|
|
else
|
2023-10-03 23:27:57 +01:00
|
|
|
{
|
2024-05-01 04:05:22 +01:00
|
|
|
await MessageBoxManager
|
|
|
|
|
.GetMessageBoxStandard(UI.Title_Error,
|
|
|
|
|
UI.Resume_file_does_not_contain_dump_hardware_information,
|
|
|
|
|
icon: Icon.Error)
|
|
|
|
|
.ShowWindowDialogAsync(_view);
|
2023-10-03 23:27:57 +01:00
|
|
|
}
|
2022-03-06 13:29:38 +00:00
|
|
|
}
|
2025-08-20 18:51:05 +01:00
|
|
|
catch(Exception ex)
|
2022-03-06 13:29:38 +00:00
|
|
|
{
|
2025-08-20 18:51:05 +01:00
|
|
|
SentrySdk.CaptureException(ex);
|
|
|
|
|
|
2024-05-01 04:05:22 +01:00
|
|
|
await MessageBoxManager.GetMessageBoxStandard(UI.Title_Error, UI.Incorrect_resume_file, icon: Icon.Error)
|
|
|
|
|
.ShowWindowDialogAsync(_view);
|
2020-04-13 04:40:35 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|