Files
Aaru/Aaru.Gui/ViewModels/Windows/ImageConvertViewModel.cs

1948 lines
88 KiB
C#
Raw Normal View History

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
// ****************************************************************************/
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
2022-11-15 01:35:06 +00:00
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
2025-08-20 21:19:43 +01:00
using System.Windows.Input;
using Aaru.CommonTypes;
using Aaru.CommonTypes.AaruMetadata;
using Aaru.CommonTypes.Enums;
using Aaru.CommonTypes.Interfaces;
using Aaru.CommonTypes.Metadata;
using Aaru.Core;
using Aaru.Core.Media;
using Aaru.Devices;
using Aaru.Gui.Models;
using Aaru.Localization;
using Aaru.Logging;
using Avalonia.Controls;
using Avalonia.Platform.Storage;
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;
using ImageInfo = Aaru.CommonTypes.Structs.ImageInfo;
using Track = Aaru.CommonTypes.Structs.Track;
using Version = Aaru.CommonTypes.Interop.Version;
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
{
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);
PluginRegister plugins = PluginRegister.Singleton;
2022-03-06 13:29:38 +00:00
foreach(IBaseWritableImage plugin in plugins.WritableImages.Values)
{
2024-05-01 04:05:22 +01:00
if(plugin is null) continue;
if(plugin.SupportedMediaTypes.Contains(inputFormat.Info.MediaType))
2023-10-03 23:27:57 +01:00
{
PluginsList.Add(new ImagePluginModel
{
Plugin = plugin
});
2023-10-03 23:27:57 +01:00
}
}
AaruMetadataFromImageVisible = inputFormat.AaruMetadata != null;
ResumeFileFromImageVisible = inputFormat.DumpHardware?.Any() == true;
_aaruMetadata = inputFormat.AaruMetadata;
2022-03-06 13:29:38 +00:00
_dumpHardware = inputFormat.DumpHardware?.Any() == true ? inputFormat.DumpHardware : null;
MetadataJsonText = _aaruMetadata == null ? "" : UI._From_image_;
ResumeFileText = _dumpHardware == null ? "" : UI._From_image_;
2022-03-06 13:29:38 +00:00
}
2025-10-25 12:53:52 +01:00
public ObservableCollection<ImagePluginModel> PluginsList { get; }
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; }
2025-08-20 21:19:43 +01:00
async Task StartAsync()
2022-03-06 13:29:38 +00:00
{
if(SelectedPlugin is null)
{
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;
}
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)
{
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)
{
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;
}
2022-03-06 13:29:38 +00:00
var inputOptical = _inputFormat as IOpticalMediaImage;
var outputOptical = outputFormat as IWritableOpticalImage;
List<Track> tracks;
try
{
2022-03-06 13:29:38 +00:00
tracks = inputOptical?.Tracks;
}
2025-08-20 18:51:05 +01:00
catch(Exception ex)
{
2025-08-20 18:51:05 +01:00
SentrySdk.CaptureException(ex);
2022-03-06 13:29:38 +00:00
tracks = null;
}
2022-03-06 13:29:38 +00:00
// Prepare UI
await Dispatcher.UIThread.InvokeAsync(() =>
{
2022-03-06 13:29:38 +00:00
CloseVisible = false;
StartVisible = false;
StopVisible = true;
ProgressVisible = true;
OptionsVisible = false;
StopEnabled = true;
FormatReadOnly = true;
DestinationVisible = false;
2022-03-06 13:29:38 +00:00
ProgressMaxValue = 1d;
ProgressMaxValue += _inputFormat.Info.ReadableMediaTags.Count;
ProgressMaxValue++;
2024-05-01 04:05:22 +01:00
if(tracks != null) ProgressMaxValue++;
2022-03-06 13:29:38 +00:00
if(tracks == null)
{
2022-03-06 13:29:38 +00:00
ProgressMaxValue += 2;
2022-03-06 13:29:38 +00:00
foreach(SectorTagType tag in _inputFormat.Info.ReadableSectorTags)
{
switch(tag)
{
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;
}
2024-05-01 04:05:22 +01:00
if(ForceChecked && !outputFormat.SupportedSectorTags.Contains(tag)) continue;
2022-03-06 13:29:38 +00:00
ProgressMaxValue++;
}
}
2022-03-06 13:29:38 +00:00
else
{
2022-03-06 13:29:38 +00:00
ProgressMaxValue += tracks.Count;
2022-03-06 13:29:38 +00:00
foreach(SectorTagType tag in _inputFormat.Info.ReadableSectorTags.OrderBy(t => t))
{
2022-03-06 13:29:38 +00:00
switch(tag)
{
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;
}
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
ProgressMaxValue += tracks.Count;
2022-03-06 13:29:38 +00:00
}
}
2024-05-01 04:05:22 +01:00
if(_dumpHardware != null) ProgressMaxValue++;
2024-05-01 04:05:22 +01:00
if(_aaruMetadata != null) ProgressMaxValue++;
2022-03-06 13:29:38 +00:00
ProgressMaxValue++;
});
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));
2022-03-06 13:29:38 +00:00
return;
}
2022-03-06 13:29:38 +00:00
bool useLong = _inputFormat.Info.ReadableSectorTags.Count != 0;
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)
{
2022-03-06 13:29:38 +00:00
if(sectorTag != SectorTagType.CdTrackFlags &&
sectorTag != SectorTagType.CdTrackIsrc &&
sectorTag != SectorTagType.CdSectorSubchannel)
useLong = false;
2022-03-06 13:29:38 +00:00
continue;
}
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));
2022-03-06 13:29:38 +00:00
return;
}
2022-03-06 13:29:38 +00:00
Dictionary<string, string> parsedOptions = new();
2022-03-06 13:29:38 +00:00
/* TODO:
if(grpOptions.Content is StackLayout stkImageOptions)
foreach(Control option in stkImageOptions.Children)
{
if(cancel)
break;
2022-03-06 13:29:38 +00:00
string value;
2022-03-06 13:29:38 +00:00
switch(option)
{
2022-03-06 13:29:38 +00:00
case CheckBox optBoolean:
value = optBooleanChecked?.ToString();
break;
2022-03-06 13:29:38 +00:00
case NumericStepper optNumber:
value = optNumber.Value.ToString(CultureInfo.CurrentCulture);
2022-03-06 13:29:38 +00:00
break;
case TextBox optString:
value = optString.Text;
2022-03-06 13:29:38 +00:00
break;
default: continue;
}
2022-03-06 13:29:38 +00:00
string key = option.ID.Substring(3);
2022-03-06 13:29:38 +00:00
parsedOptions.Add(key, value);
}
*/
await Dispatcher.UIThread.InvokeAsync(() =>
{
ProgressText = UI.Creating_output_image;
2022-03-06 13:29:38 +00:00
Progress2Text = "";
Progress2Indeterminate = true;
});
// 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,
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,
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(() =>
{
ProgressText = UI.Setting_image_metadata;
2022-03-06 13:29:38 +00:00
ProgressValue++;
Progress2Text = "";
Progress2Indeterminate = true;
});
var metadata = new ImageInfo
{
Application = "Aaru",
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
{
if(!outputFormat.SetImageInfo(metadata))
2022-03-06 13:29:38 +00: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));
2025-08-17 06:11:22 +01:00
AaruLogging.Error(UI.Error_0_setting_metadata_not_continuing, outputFormat.ErrorMessage);
2022-03-06 13:29:38 +00:00
return;
}
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
if(tracks != null && !_cancel && outputOptical != null)
2022-03-06 13:29:38 +00:00
{
await Dispatcher.UIThread.InvokeAsync(() =>
{
ProgressText = UI.Setting_tracks_list;
2022-03-06 13:29:38 +00:00
ProgressValue++;
Progress2Text = "";
Progress2Indeterminate = true;
});
2022-03-06 13:29:38 +00:00
if(!outputOptical.SetTracks(tracks))
{
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));
2025-08-17 06:11:22 +01:00
AaruLogging.Error(UI.Error_0_sending_tracks_list_to_output_image, outputFormat.ErrorMessage);
return;
}
2022-03-06 13:29:38 +00:00
}
ErrorNumber errno;
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
{
await Dispatcher.UIThread.InvokeAsync(() =>
{
ProgressText = string.Format(UI.Converting_media_tag_0, mediaTag);
ProgressValue++;
Progress2Text = "";
Progress2Indeterminate = true;
});
2024-05-01 04:05:22 +01:00
if(ForceChecked && !outputFormat.SupportedMediaTags.Contains(mediaTag)) continue;
2022-03-06 13:29:38 +00:00
errno = _inputFormat.ReadMediaTag(mediaTag, out byte[] tag);
2024-05-01 04:05:22 +01:00
if(errno == ErrorNumber.NoError && outputFormat.WriteMediaTag(tag, mediaTag)) continue;
2022-03-06 13:29:38 +00:00
if(ForceChecked)
{
2022-03-06 13:29:38 +00:00
warning = true;
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);
}
2022-03-06 13:29:38 +00:00
else
{
2022-03-06 13:29:38 +00:00
if(errno == ErrorNumber.NoError)
{
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));
2025-08-17 06:11:22 +01:00
AaruLogging.Error(UI.Error_0_writing_media_tag_not_continuing, outputFormat.ErrorMessage);
}
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,
errno),
2024-05-01 04:05:22 +01:00
icon: Icon.Error)
.ShowWindowDialogAsync(_view));
2025-08-17 06:11:22 +01:00
AaruLogging.Error(UI.Error_0_reading_media_tag_not_continuing, errno);
}
2022-03-06 13:29:38 +00:00
return;
}
2022-03-06 13:29:38 +00:00
}
2022-03-06 13:29:38 +00:00
ulong doneSectors = 0;
if(tracks == null && !_cancel)
2022-03-06 13:29:38 +00:00
{
await Dispatcher.UIThread.InvokeAsync(() =>
{
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,
_inputFormat.Info.SectorsPerTrack);
2022-03-06 13:29:38 +00:00
ProgressValue++;
Progress2Text = "";
Progress2Indeterminate = true;
});
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;
2025-08-17 06:11:22 +01:00
AaruLogging.Error(UI.Error_0_setting_geometry_image_may_be_incorrect_continuing,
outputFormat.ErrorMessage);
2022-03-06 13:29:38 +00:00
}
2022-03-06 13:29:38 +00:00
await Dispatcher.UIThread.InvokeAsync(() =>
{
ProgressText = UI.Converting_sectors;
2022-03-06 13:29:38 +00:00
ProgressValue++;
Progress2Text = "";
Progress2Indeterminate = false;
Progress2MaxValue = (int)(_inputFormat.Info.Sectors / SectorsValue);
});
2022-03-06 13:29:38 +00:00
while(doneSectors < _inputFormat.Info.Sectors)
{
2024-05-01 04:05:22 +01:00
if(_cancel) break;
2022-03-06 13:29:38 +00:00
byte[] sector;
2022-03-06 13:29:38 +00:00
uint sectorsToDo;
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);
2022-03-06 13:29:38 +00:00
ulong sectors = doneSectors;
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,
sectors / (double)_inputFormat.Info.Sectors);
2022-03-06 13:29:38 +00:00
Progress2Value = (int)(sectors / SectorsValue);
});
bool result;
SectorStatus sectorStatus = SectorStatus.NotDumped;
var sectorStatusArray = new SectorStatus[1];
2022-03-06 13:29:38 +00:00
if(useLong)
{
2023-10-03 23:27:57 +01:00
errno = sectorsToDo == 1
? _inputFormat.ReadSectorLong(doneSectors, false, out sector, out sectorStatus)
: _inputFormat.ReadSectorsLong(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
? outputFormat.WriteSectorLong(sector, doneSectors, false, sectorStatus)
: outputFormat.WriteSectorsLong(sector,
doneSectors,
false,
sectorsToDo,
sectorStatusArray);
2023-10-03 23:27:57 +01:00
}
2022-03-06 13:29:38 +00:00
else
{
2022-03-06 13:29:38 +00:00
result = true;
2022-03-06 13:29:38 +00:00
if(ForceChecked)
{
2022-03-06 13:29:38 +00:00
warning = true;
2025-08-17 06:11:22 +01:00
AaruLogging.Error(UI.Error_0_reading_sector_1_continuing, errno, doneSectors);
}
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),
2024-05-01 04:05:22 +01:00
icon: Icon.Error)
.ShowWindowDialogAsync(_view));
2025-08-17 06:11:22 +01:00
AaruLogging.Error(UI.Error_0_reading_sector_1_not_continuing, errno, doneSectors);
2022-03-06 13:29:38 +00:00
return;
}
}
2022-03-06 13:29:38 +00:00
}
else
{
2023-10-03 23:27:57 +01:00
errno = sectorsToDo == 1
? _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
? 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;
if(ForceChecked)
{
warning = true;
2025-08-17 06:11:22 +01:00
AaruLogging.Error(UI.Error_0_reading_sector_1_continuing, errno, doneSectors);
}
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),
2024-05-01 04:05:22 +01:00
icon: Icon.Error)
.ShowWindowDialogAsync(_view));
2025-08-17 06:11:22 +01:00
AaruLogging.Error(UI.Error_0_reading_sector_1_not_continuing, errno, doneSectors);
return;
}
2022-03-06 13:29:38 +00: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;
2025-08-17 06:11:22 +01:00
AaruLogging.Error(UI.Error_0_writing_sector_1_continuing,
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));
2025-08-17 06:11:22 +01:00
AaruLogging.Error(UI.Error_0_writing_sector_1_not_continuing,
outputFormat.ErrorMessage,
doneSectors);
2022-03-06 13:29:38 +00:00
return;
}
2023-10-03 23:27:57 +01:00
}
2022-03-06 13:29:38 +00:00
doneSectors += sectorsToDo;
}
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);
2022-03-06 13:29:38 +00:00
Progress2Value = Progress2MaxValue;
});
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)
{
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;
2022-03-06 13:29:38 +00:00
isrcs[(byte)track.Sequence] = Encoding.UTF8.GetString(isrc);
}
2022-03-06 13:29:38 +00: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)
{
errno = _inputFormat.ReadSectorTag(track.Sequence, false, tag, out byte[] flags);
2024-05-01 04:05:22 +01:00
if(errno != ErrorNumber.NoError) continue;
2022-03-06 13:29:38 +00:00
trackFlags[(byte)track.Sequence] = flags[0];
}
}
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;
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)
{
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;
}
2024-05-01 04:05:22 +01:00
if(ForceChecked && !outputFormat.SupportedSectorTags.Contains(tag)) continue;
2022-03-06 13:29:38 +00:00
await Dispatcher.UIThread.InvokeAsync(() =>
{
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);
});
2022-03-06 13:29:38 +00:00
doneSectors = 0;
2022-03-06 13:29:38 +00:00
while(doneSectors < _inputFormat.Info.Sectors)
{
2024-05-01 04:05:22 +01:00
if(_cancel) break;
2022-03-06 13:29:38 +00:00
byte[] sector;
2022-03-06 13:29:38 +00:00
uint sectorsToDo;
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);
2022-03-06 13:29:38 +00:00
ulong sectors = doneSectors;
2022-03-06 13:29:38 +00:00
await Dispatcher.UIThread.InvokeAsync(() =>
{
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,
sectors + sectorsToDo,
sectors / (double)_inputFormat.Info.Sectors);
2022-03-06 13:29:38 +00:00
Progress2Value = (int)(sectors / SectorsValue);
});
2022-03-06 13:29:38 +00:00
bool result;
2022-03-06 13:29:38 +00:00
if(sectorsToDo == 1)
{
errno = _inputFormat.ReadSectorTag(doneSectors, false, tag, out sector);
2022-03-06 13:29:38 +00:00
if(errno == ErrorNumber.NoError)
{
Track track = tracks.LastOrDefault(t => t.StartSector >= doneSectors);
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());
2022-03-06 13:29:38 +00:00
result = true;
}
2022-03-06 13:29:38 +00:00
else
result = outputFormat.WriteSectorTag(sector, doneSectors, false, tag);
}
else
{
2022-03-06 13:29:38 +00:00
result = true;
2022-03-06 13:29:38 +00:00
if(ForceChecked)
{
2022-03-06 13:29:38 +00:00
warning = true;
2025-08-17 06:11:22 +01:00
AaruLogging.Error(UI.Error_0_reading_sector_1_continuing, errno, doneSectors);
}
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));
AaruLogging.Error(UI.Error_0_reading_sector_1_not_continuing, errno, doneSectors);
2022-03-06 13:29:38 +00:00
return;
}
}
}
else
{
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);
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,
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;
}
2022-03-06 13:29:38 +00:00
else
result = outputFormat.WriteSectorsTag(sector, doneSectors, false, sectorsToDo, tag);
}
2022-03-06 13:29:38 +00:00
else
{
result = true;
if(ForceChecked)
{
warning = true;
2025-08-17 06:11:22 +01:00
AaruLogging.Error(UI.Error_0_reading_sector_1_continuing, errno, doneSectors);
}
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));
AaruLogging.Error(UI.Error_0_reading_sector_1_not_continuing, errno, doneSectors);
return;
}
2022-03-06 13:29:38 +00: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;
2025-08-17 06:11:22 +01:00
AaruLogging.Error(UI.Error_0_writing_sector_1_continuing,
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));
2025-08-17 06:11:22 +01:00
AaruLogging.Error(UI.Error_0_writing_sector_1_not_continuing,
outputFormat.ErrorMessage,
doneSectors);
2022-03-06 13:29:38 +00:00
return;
}
2023-10-03 23:27:57 +01:00
}
2022-03-06 13:29:38 +00:00
doneSectors += sectorsToDo;
}
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_3_done,
tag,
_inputFormat.Info.Sectors,
_inputFormat.Info.Sectors,
1.0);
2022-03-06 13:29:38 +00:00
Progress2Value = Progress2MaxValue;
});
foreach(KeyValuePair<byte, string> isrc in isrcs)
2023-10-03 23:27:57 +01:00
{
outputOptical.WriteSectorTag(Encoding.UTF8.GetBytes(isrc.Value),
isrc.Key,
false,
SectorTagType.CdTrackIsrc);
2023-10-03 23:27:57 +01:00
}
foreach(KeyValuePair<byte, byte> flags in trackFlags)
outputOptical.WriteSectorTag([flags.Value], flags.Key, false, SectorTagType.CdTrackFlags);
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;
2022-03-06 13:29:38 +00:00
await Dispatcher.UIThread.InvokeAsync(() =>
{
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);
});
2022-03-06 13:29:38 +00:00
while(doneSectors < trackSectors)
{
2024-05-01 04:05:22 +01:00
if(_cancel) break;
2022-03-06 13:29:38 +00:00
byte[] sector;
2022-03-06 13:29:38 +00:00
uint sectorsToDo;
2022-03-06 13:29:38 +00:00
if(trackSectors - doneSectors >= (ulong)SectorsValue)
sectorsToDo = (uint)SectorsValue;
else
sectorsToDo = (uint)(trackSectors - doneSectors);
2022-03-06 13:29:38 +00:00
ulong sectors = doneSectors;
2022-03-06 13:29:38 +00:00
await Dispatcher.UIThread.InvokeAsync(() =>
{
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,
(sectors + track.StartSector) /
(double)_inputFormat.Info.Sectors);
2022-03-06 13:29:38 +00:00
Progress2Value = (int)(sectors / SectorsValue);
});
bool result;
SectorStatus sectorStatus = SectorStatus.NotDumped;
var sectorStatusArray = new SectorStatus[1];
2022-03-06 13:29:38 +00:00
if(useLong)
{
errno = sectorsToDo == 1
? _inputFormat.ReadSectorLong(doneSectors + track.StartSector,
false,
out sector,
out sectorStatus)
2024-05-01 04:05:22 +01:00
: _inputFormat.ReadSectorsLong(doneSectors + track.StartSector,
false,
2024-05-01 04:05:22 +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
{
2022-03-06 13:29:38 +00:00
result = sectorsToDo == 1
? outputFormat.WriteSectorLong(sector,
doneSectors + track.StartSector,
false,
sectorStatus)
2024-05-01 04:05:22 +01:00
: outputFormat.WriteSectorsLong(sector,
doneSectors + track.StartSector,
false,
sectorsToDo,
sectorStatusArray);
2023-10-03 23:27:57 +01:00
}
2022-03-06 13:29:38 +00:00
else
{
result = true;
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_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));
2022-03-06 13:29:38 +00:00
return;
}
}
2022-03-06 13:29:38 +00:00
}
else
{
2023-10-03 23:27:57 +01:00
errno = sectorsToDo == 1
? _inputFormat.ReadSector(doneSectors + track.StartSector,
false,
out sector,
out sectorStatus)
2024-05-01 04:05:22 +01:00
: _inputFormat.ReadSectors(doneSectors + track.StartSector,
false,
2024-05-01 04:05:22 +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
{
2022-03-06 13:29:38 +00:00
result = sectorsToDo == 1
? outputFormat.WriteSector(sector,
doneSectors + track.StartSector,
false,
sectorStatus)
2024-05-01 04:05:22 +01:00
: outputFormat.WriteSectors(sector,
doneSectors + track.StartSector,
false,
sectorsToDo,
sectorStatusArray);
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-17 06:11:22 +01:00
AaruLogging.Error(UI.Error_0_reading_sector_1_continuing, errno, doneSectors);
}
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));
return;
}
2022-03-06 13:29:38 +00: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)
{
2022-03-06 13:29:38 +00:00
warning = true;
2025-08-17 06:11:22 +01:00
AaruLogging.Error(UI.Error_0_writing_sector_1_continuing,
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));
2022-03-06 13:29:38 +00:00
return;
}
2023-10-03 23:27:57 +01:00
}
2022-03-06 13:29:38 +00:00
doneSectors += sectorsToDo;
}
}
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);
2022-03-06 13:29:38 +00:00
Progress2Value = Progress2MaxValue;
});
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)
{
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;
}
2024-05-01 04:05:22 +01:00
if(ForceChecked && !outputFormat.SupportedSectorTags.Contains(tag)) continue;
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;
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);
});
2022-03-06 13:29:38 +00:00
switch(tag)
{
case SectorTagType.CdTrackFlags:
case SectorTagType.CdTrackIsrc:
errno = _inputFormat.ReadSectorTag(track.Sequence, false, tag, out sector);
if(errno == ErrorNumber.NoError)
result = outputFormat.WriteSectorTag(sector, track.Sequence, false, tag);
else
{
if(ForceChecked)
{
warning = true;
2025-08-17 06:11:22 +01:00
AaruLogging.Error(UI.Error_0_reading_media_tag, errno);
}
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,
errno),
2024-05-01 04:05:22 +01:00
icon: Icon.Error)
.ShowWindowDialogAsync(_view));
return;
}
2022-03-06 13:29:38 +00:00
continue;
}
if(!result)
2023-10-03 23:27:57 +01:00
{
if(ForceChecked)
{
warning = true;
AaruLogging.Error(UI.Error_0_writing_tag_continuing, outputFormat.ErrorMessage);
}
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));
return;
}
2023-10-03 23:27:57 +01:00
}
2022-03-06 13:29:38 +00:00
continue;
}
2022-03-06 13:29:38 +00:00
while(doneSectors < trackSectors)
{
2024-05-01 04:05:22 +01:00
if(_cancel) break;
2022-03-06 13:29:38 +00:00
uint sectorsToDo;
2022-03-06 13:29:38 +00:00
if(trackSectors - doneSectors >= (ulong)SectorsValue)
sectorsToDo = (uint)SectorsValue;
else
sectorsToDo = (uint)(trackSectors - doneSectors);
2022-03-06 13:29:38 +00:00
ulong sectors = doneSectors;
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,
sectors + track.StartSector,
2024-05-01 04:05:22 +01:00
sectors + sectorsToDo + track.StartSector,
track.Sequence,
(sectors + track.StartSector) /
(double)_inputFormat.Info.Sectors);
2022-03-06 13:29:38 +00:00
Progress2Value = (int)(sectors / SectorsValue);
});
2022-03-06 13:29:38 +00:00
errno = sectorsToDo == 1
? _inputFormat.ReadSectorTag(doneSectors + track.StartSector,
false,
tag,
out sector)
2024-05-01 04:05:22 +01:00
: _inputFormat.ReadSectorsTag(doneSectors + track.StartSector,
false,
2024-05-01 04:05:22 +01:00
sectorsToDo,
tag,
2022-03-06 13:29:38 +00:00
out sector);
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
? outputFormat.WriteSectorTag(sector,
doneSectors + track.StartSector,
false,
tag)
2024-05-01 04:05:22 +01:00
: outputFormat.WriteSectorsTag(sector,
doneSectors + track.StartSector,
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;
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,
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,
doneSectors),
2024-05-01 04:05:22 +01:00
icon: Icon.Error)
.ShowWindowDialogAsync(_view));
2022-03-06 13:29:38 +00:00
return;
}
2023-10-03 23:27:57 +01:00
}
2022-03-06 13:29:38 +00:00
doneSectors += sectorsToDo;
}
}
}
2022-03-06 13:29:38 +00:00
}
await Dispatcher.UIThread.InvokeAsync(() =>
{
Progress2Visible = false;
Progress2Visible = false;
});
bool ret;
if(_dumpHardware != null && !_cancel)
2022-03-06 13:29:38 +00:00
{
await Dispatcher.UIThread.InvokeAsync(() =>
{
ProgressText = UI.Writing_dump_hardware_list;
2022-03-06 13:29:38 +00:00
ProgressValue++;
});
2022-03-06 13:29:38 +00:00
ret = outputFormat.SetDumpHardware(_dumpHardware);
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
}
2022-03-06 13:29:38 +00:00
ret = false;
if(_aaruMetadata != null && !_cancel)
2022-03-06 13:29:38 +00:00
{
await Dispatcher.UIThread.InvokeAsync(() =>
{
ProgressText = UI.Writing_Aaru_Metadata_to_output_image;
2022-03-06 13:29:38 +00:00
ProgressValue++;
});
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
}
2022-03-06 13:29:38 +00:00
await Dispatcher.UIThread.InvokeAsync(() =>
{
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 () =>
{
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);
CloseVisible = true;
StopVisible = false;
ProgressVisible = false;
});
2022-03-06 13:29:38 +00:00
return;
}
2022-03-06 13:29:38 +00:00
if(!outputFormat.Close())
{
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,
outputFormat.ErrorMessage),
2024-05-01 04:05:22 +01:00
icon: Icon.Error)
.ShowWindowDialogAsync(_view));
2022-03-06 13:29:38 +00:00
return;
}
2023-09-25 22:58:48 +01:00
await Dispatcher.UIThread.InvokeAsync(async () =>
2022-03-06 13:29:38 +00: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);
2022-03-06 13:29:38 +00:00
CloseVisible = true;
StopVisible = false;
ProgressVisible = false;
});
2022-03-06 13:29:38 +00:00
Statistics.AddCommand("convert-image");
}
2025-08-20 21:19:43 +01:00
void Close() => _view.Close();
2025-08-20 21:19:43 +01:00
internal void Stop()
2022-03-06 13:29:38 +00:00
{
_cancel = true;
StopEnabled = false;
}
2022-03-06 13:29:38 +00:00
/* TODO
void OnCmbFormatSelectedIndexChanged()
{
txtDestination.Text = "";
2022-03-06 13:29:38 +00:00
if(!(cmbFormat.SelectedValue is IWritableImage plugin))
{
grpOptions.Visible = false;
btnDestination.Enabled = false;
2022-03-06 13:29:38 +00:00
return;
}
2022-03-06 13:29:38 +00:00
btnDestination.Enabled = true;
2022-03-06 13:29:38 +00:00
if(!plugin.SupportedOptions.Any())
{
grpOptions.Content = null;
grpOptions.Visible = false;
2022-03-06 13:29:38 +00:00
return;
}
2022-03-06 13:29:38 +00:00
chkForce.Visible = false;
2022-03-06 13:29:38 +00:00
foreach(MediaTagType mediaTag in inputFormat.Info.ReadableMediaTags)
{
if(plugin.SupportedMediaTags.Contains(mediaTag))
continue;
2022-03-06 13:29:38 +00:00
chkForce.Visible = true;
ForceChecked = true;
2022-03-06 13:29:38 +00:00
break;
}
2022-03-06 13:29:38 +00:00
foreach(SectorTagType sectorTag in inputFormat.Info.ReadableSectorTags)
{
if(plugin.SupportedSectorTags.Contains(sectorTag))
continue;
2022-03-06 13:29:38 +00:00
chkForce.Visible = true;
ForceChecked = true;
break;
}
2022-03-06 13:29:38 +00:00
grpOptions.Visible = true;
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);
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);
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);
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;
}
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
IStorageFile result = await _view.StorageProvider.SaveFilePickerAsync(new FilePickerSaveOptions
2022-03-06 13:29:38 +00: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
});
if(result is null)
2022-03-06 13:29:38 +00:00
{
DestinationText = "";
2022-03-06 13:29:38 +00:00
return;
}
DestinationText = result.Path.AbsolutePath;
if(string.IsNullOrEmpty(Path.GetExtension(DestinationText)))
DestinationText += SelectedPlugin.Plugin.KnownExtensions.First();
2022-03-06 13:29:38 +00:00
}
2025-08-20 21:19:43 +01:00
void Creator() => CreatorText = _inputFormat.Info.Creator;
2025-08-20 21:19:43 +01:00
void MediaTitle() => MediaTitleText = _inputFormat.Info.MediaTitle;
2025-08-20 21:19:43 +01:00
void Comments() => CommentsText = _inputFormat.Info.Comments;
2025-08-20 21:19:43 +01:00
void MediaManufacturer() => MediaManufacturerText = _inputFormat.Info.MediaManufacturer;
2025-08-20 21:19:43 +01:00
void MediaModel() => MediaModelText = _inputFormat.Info.MediaModel;
2025-08-20 21:19:43 +01:00
void MediaSerialNumber() => MediaSerialNumberText = _inputFormat.Info.MediaSerialNumber;
2025-08-20 21:19:43 +01:00
void MediaBarcode() => MediaBarcodeText = _inputFormat.Info.MediaBarcode;
2025-08-20 21:19:43 +01:00
void MediaPartNumber() => MediaPartNumberText = _inputFormat.Info.MediaPartNumber;
2025-08-20 21:19:43 +01:00
void MediaSequence() => MediaSequenceValue = _inputFormat.Info.MediaSequence;
2025-08-20 21:19:43 +01:00
void LastMediaSequence() => LastMediaSequenceValue = _inputFormat.Info.LastMediaSequence;
2025-08-20 21:19:43 +01:00
void DriveManufacturer() => DriveManufacturerText = _inputFormat.Info.DriveManufacturer;
2025-08-20 21:19:43 +01:00
void DriveModel() => DriveModelText = _inputFormat.Info.DriveModel;
2025-08-20 21:19:43 +01:00
void DriveSerialNumber() => DriveSerialNumberText = _inputFormat.Info.DriveSerialNumber;
2025-08-20 21:19:43 +01:00
void DriveFirmwareRevision() => DriveFirmwareRevisionText = _inputFormat.Info.DriveFirmwareRevision;
2025-08-20 21:19:43 +01:00
void AaruMetadataFromImage()
2022-03-06 13:29:38 +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
{
_aaruMetadata = null;
MetadataJsonText = "";
2022-03-06 13:29:38 +00: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;
if(result.Count != 1) return;
2022-03-06 13:29:38 +00:00
try
{
var fs = new FileStream(result[0].Path.AbsolutePath, FileMode.Open);
_aaruMetadata =
(await JsonSerializer.DeserializeAsync(fs, typeof(MetadataJson), MetadataJsonContext.Default) as
MetadataJson)?.AaruMetadata;
fs.Close();
MetadataJsonText = result[0].Path.AbsolutePath;
}
2025-08-20 18:51:05 +01:00
catch(Exception ex)
{
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);
}
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
{
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 = "";
IReadOnlyList<IStorageFile> result = _view.StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
{
Title = UI.Dialog_Choose_existing_resume_file,
AllowMultiple = false,
FileTypeFilter = new List<FilePickerFileType>
{
FilePickerFileTypes.AaruResumeFile
}
})
.Result;
if(result.Count != 1) return;
2022-03-06 13:29:38 +00:00
try
{
var fs = new FileStream(result[0].Path.AbsolutePath, FileMode.Open);
Resume resume =
2024-05-01 04:05:22 +01:00
(await JsonSerializer.DeserializeAsync(fs, typeof(ResumeJson), ResumeJsonContext.Default) as ResumeJson)
?.Resume;
fs.Close();
2022-03-17 00:46:26 +00:00
if(resume?.Tries?.Any() == false)
{
2022-03-06 13:29:38 +00:00
_dumpHardware = resume.Tries;
ResumeFileText = result[0].Path.AbsolutePath;
}
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);
}
}
}