Files
Aaru/Aaru.Gui/ViewModels/Panels/MediaInfoViewModel.cs

386 lines
18 KiB
C#
Raw Normal View History

2020-04-17 21:45:50 +01:00
// /***************************************************************************
// Aaru Data Preservation Suite
// ----------------------------------------------------------------------------
//
// Filename : MediaInfoViewModel.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : GUI view models.
//
// --[ Description ] ----------------------------------------------------------
//
// View model and code for the media information panel.
//
// --[ 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.IO;
using System.Text;
using System.Threading.Tasks;
2025-08-20 21:19:43 +01:00
using System.Windows.Input;
2020-04-16 20:40:25 +01:00
using Aaru.Gui.ViewModels.Tabs;
using Aaru.Gui.ViewModels.Windows;
using Aaru.Gui.Views.Tabs;
using Aaru.Gui.Views.Windows;
using Aaru.Localization;
using Avalonia.Controls;
using Avalonia.Media.Imaging;
using Avalonia.Platform;
using Avalonia.Platform.Storage;
2025-08-20 21:19:43 +01:00
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
2023-09-26 01:29:40 +01:00
using Humanizer.Bytes;
2023-09-26 01:29:07 +01:00
using MsBox.Avalonia;
using MsBox.Avalonia.Enums;
2020-04-16 21:29:40 +01:00
using ScsiInfo = Aaru.Core.Media.Info.ScsiInfo;
namespace Aaru.Gui.ViewModels.Panels;
2025-08-20 21:19:43 +01:00
public sealed partial class MediaInfoViewModel : ViewModelBase
{
2022-03-06 13:29:38 +00:00
readonly string _devicePath;
readonly ScsiInfo _scsiInfo;
readonly Window _view;
2025-08-20 21:19:43 +01:00
[ObservableProperty]
BlurayInfo _blurayInfo;
[ObservableProperty]
CompactDiscInfo _compactDiscInfo;
[ObservableProperty]
string _densitySupport;
[ObservableProperty]
DvdInfo _dvdInfo;
[ObservableProperty]
DvdWritableInfo _dvdWritableInfo;
[ObservableProperty]
string _generalVisible;
[ObservableProperty]
Bitmap _mediaLogo;
[ObservableProperty]
string _mediaSerial;
[ObservableProperty]
string _mediaSize;
[ObservableProperty]
string _mediaType;
[ObservableProperty]
string _mediumSupport;
[ObservableProperty]
bool _mmcVisible;
[ObservableProperty]
bool _saveDensitySupportVisible;
[ObservableProperty]
bool _saveGetConfigurationVisible;
[ObservableProperty]
bool _saveMediumSupportVisible;
[ObservableProperty]
bool _saveReadCapacity16Visible;
[ObservableProperty]
bool _saveReadCapacityVisible;
[ObservableProperty]
bool _saveReadMediaSerialVisible;
[ObservableProperty]
bool _saveRecognizedFormatLayersVisible;
[ObservableProperty]
bool _saveWriteProtectionStatusVisible;
[ObservableProperty]
bool _sscVisible;
[ObservableProperty]
XboxInfo _xboxInfo;
2022-03-06 13:29:38 +00:00
public MediaInfoViewModel(ScsiInfo scsiInfo, string devicePath, Window view)
{
2022-03-06 13:29:38 +00:00
_view = view;
2025-08-20 21:19:43 +01:00
SaveReadMediaSerialCommand = new AsyncRelayCommand(SaveReadMediaSerial);
SaveReadCapacityCommand = new AsyncRelayCommand(SaveReadCapacity);
SaveReadCapacity16Command = new AsyncRelayCommand(SaveReadCapacity16);
SaveGetConfigurationCommand = new AsyncRelayCommand(SaveGetConfiguration);
SaveRecognizedFormatLayersCommand = new AsyncRelayCommand(SaveRecognizedFormatLayers);
SaveWriteProtectionStatusCommand = new AsyncRelayCommand(SaveWriteProtectionStatus);
SaveDensitySupportCommand = new AsyncRelayCommand(SaveDensitySupport);
SaveMediumSupportCommand = new AsyncRelayCommand(SaveMediumSupport);
DumpCommand = new AsyncRelayCommand(DumpAsync);
ScanCommand = new AsyncRelayCommand(ScanAsync);
2023-10-03 23:27:57 +01:00
_devicePath = devicePath;
_scsiInfo = scsiInfo;
2022-03-06 13:29:38 +00:00
var mediaResource = new Uri($"avares://Aaru.Gui/Assets/Logos/Media/{scsiInfo.MediaType}.png");
2023-09-25 22:58:48 +01:00
MediaLogo = AssetLoader.Exists(mediaResource) ? new Bitmap(AssetLoader.Open(mediaResource)) : null;
2022-03-06 13:29:38 +00:00
MediaType = scsiInfo.MediaType.ToString();
if(scsiInfo.Blocks != 0 && scsiInfo.BlockSize != 0)
2023-10-03 23:27:57 +01:00
{
2023-09-26 01:29:40 +01:00
MediaSize = string.Format(Localization.Core.Media_has_0_blocks_of_1_bytes_each_for_a_total_of_2,
2024-05-01 04:05:22 +01:00
scsiInfo.Blocks,
scsiInfo.BlockSize,
2023-09-26 01:29:40 +01:00
ByteSize.FromBytes(scsiInfo.Blocks * scsiInfo.BlockSize).ToString("0.000"));
2023-10-03 23:27:57 +01:00
}
2022-03-06 13:29:38 +00:00
if(scsiInfo.MediaSerialNumber != null)
{
var sbSerial = new StringBuilder();
2025-08-20 21:19:43 +01:00
for(int i = 4; i < scsiInfo.MediaSerialNumber.Length; i++)
2023-10-04 08:16:21 +01:00
sbSerial.Append($"{scsiInfo.MediaSerialNumber[i]:X2}");
2022-03-06 13:29:38 +00:00
MediaSerial = sbSerial.ToString();
}
2022-03-06 13:29:38 +00:00
SaveReadMediaSerialVisible = scsiInfo.MediaSerialNumber != null;
SaveReadCapacityVisible = scsiInfo.ReadCapacity != null;
SaveReadCapacity16Visible = scsiInfo.ReadCapacity16 != null;
2022-03-06 13:29:38 +00:00
SaveGetConfigurationVisible = scsiInfo.MmcConfiguration != null;
SaveRecognizedFormatLayersVisible = scsiInfo.RecognizedFormatLayers != null;
SaveWriteProtectionStatusVisible = scsiInfo.WriteProtectionStatus != null;
MmcVisible = SaveGetConfigurationVisible ||
SaveRecognizedFormatLayersVisible ||
2022-03-06 13:29:38 +00:00
SaveWriteProtectionStatusVisible;
2022-03-06 13:29:38 +00:00
if(scsiInfo.DensitySupportHeader.HasValue)
DensitySupport = Decoders.SCSI.SSC.DensitySupport.PrettifyDensity(scsiInfo.DensitySupportHeader);
2022-03-06 13:29:38 +00:00
if(scsiInfo.MediaTypeSupportHeader.HasValue)
MediumSupport = Decoders.SCSI.SSC.DensitySupport.PrettifyMediumType(scsiInfo.MediaTypeSupportHeader);
2022-03-06 13:29:38 +00:00
SaveDensitySupportVisible = scsiInfo.DensitySupport != null;
SaveMediumSupportVisible = scsiInfo.MediaTypeSupport != null;
2022-03-06 13:29:38 +00:00
SscVisible = SaveDensitySupportVisible || SaveMediumSupportVisible;
2022-03-06 13:29:38 +00:00
CompactDiscInfo = new CompactDiscInfo
{
2024-05-01 04:05:22 +01:00
DataContext = new CompactDiscInfoViewModel(scsiInfo.Toc,
scsiInfo.Atip,
scsiInfo.DiscInformation,
scsiInfo.Session,
scsiInfo.RawToc,
scsiInfo.Pma,
scsiInfo.CdTextLeadIn,
scsiInfo.DecodedToc,
scsiInfo.DecodedAtip,
scsiInfo.DecodedSession,
scsiInfo.FullToc,
scsiInfo.DecodedCdTextLeadIn,
scsiInfo.DecodedDiscInformation,
scsiInfo.Mcn,
scsiInfo.Isrcs,
_view)
2022-03-06 13:29:38 +00:00
};
DvdInfo = new DvdInfo
{
2024-05-01 04:05:22 +01:00
DataContext = new DvdInfoViewModel(scsiInfo.DvdPfi,
scsiInfo.DvdDmi,
scsiInfo.DvdCmi,
scsiInfo.HddvdCopyrightInformation,
scsiInfo.DvdBca,
scsiInfo.DvdAacs,
scsiInfo.DecodedPfi,
_view)
2022-03-06 13:29:38 +00:00
};
2022-03-06 13:29:38 +00:00
XboxInfo = new XboxInfo
{
2024-05-01 04:05:22 +01:00
DataContext = new XboxInfoViewModel(scsiInfo.XgdInfo,
scsiInfo.DvdDmi,
scsiInfo.XboxSecuritySector,
scsiInfo.DecodedXboxSecuritySector,
_view)
2022-03-06 13:29:38 +00:00
};
2022-03-06 13:29:38 +00:00
DvdWritableInfo = new DvdWritableInfo
{
2024-05-01 04:05:22 +01:00
DataContext = new DvdWritableInfoViewModel(scsiInfo.DvdRamDds,
scsiInfo.DvdRamCartridgeStatus,
scsiInfo.DvdRamSpareArea,
scsiInfo.LastBorderOutRmd,
scsiInfo.DvdPreRecordedInfo,
scsiInfo.DvdrMediaIdentifier,
scsiInfo.DvdrPhysicalInformation,
scsiInfo.HddvdrMediumStatus,
scsiInfo.HddvdrLastRmd,
scsiInfo.DvdrLayerCapacity,
scsiInfo.DvdrDlMiddleZoneStart,
scsiInfo.DvdrDlJumpIntervalSize,
2022-03-06 13:29:38 +00:00
scsiInfo.DvdrDlManualLayerJumpStartLba,
2024-05-01 04:05:22 +01:00
scsiInfo.DvdrDlRemapAnchorPoint,
scsiInfo.DvdPlusAdip,
scsiInfo.DvdPlusDcb,
_view)
2022-03-06 13:29:38 +00:00
};
BlurayInfo = new BlurayInfo
{
2024-05-01 04:05:22 +01:00
DataContext = new BlurayInfoViewModel(scsiInfo.BlurayDiscInformation,
scsiInfo.BlurayBurstCuttingArea,
scsiInfo.BlurayDds,
scsiInfo.BlurayCartridgeStatus,
scsiInfo.BluraySpareAreaInformation,
scsiInfo.BlurayPowResources,
scsiInfo.BlurayTrackResources,
scsiInfo.BlurayRawDfl,
scsiInfo.BlurayPac,
_view)
2022-03-06 13:29:38 +00:00
};
}
2025-08-20 21:19:43 +01:00
public ICommand SaveReadMediaSerialCommand { get; }
public ICommand SaveReadCapacityCommand { get; }
public ICommand SaveReadCapacity16Command { get; }
public ICommand SaveGetConfigurationCommand { get; }
public ICommand SaveRecognizedFormatLayersCommand { get; }
public ICommand SaveWriteProtectionStatusCommand { get; }
public ICommand SaveDensitySupportCommand { get; }
public ICommand SaveMediumSupportCommand { get; }
public ICommand DumpCommand { get; }
public ICommand ScanCommand { get; }
public string MediaInformationLabel => UI.Title_Media_information;
public string GeneralLabel => UI.Title_General;
public string MediaTypeLabel => UI.Title_Media_type;
public string MediaSerialNumberLabel => UI.Title_Media_serial_number;
public string SaveReadMediaSerialLabel => UI.ButtonLabel_Save_READ_MEDIA_SERIAL_NUMBER_response;
public string SaveReadCapacityLabel => UI.ButtonLabel_Save_READ_CAPACITY_response;
public string SaveReadCapacity16Label => UI.ButtonLabel_Save_READ_CAPACITY_16_response;
public string MMCLabel => Localization.Core.Title_MMC;
public string SaveGetConfigurationLabel => UI.ButtonLabel_Save_GET_CONFIGURATION_response;
public string SaveRecognizedFormatLayersLabel => UI.ButtonLabel_Save_RECOGNIZED_FORMAT_LAYERS_response;
public string SaveWriteProtectionStatusLabel => UI.ButtonLabel_Save_WRITE_PROTECTION_STATUS_response;
2023-10-05 01:52:48 +01:00
public string SscLabel => Localization.Core.Title_SSC;
public string DensitySupportLabel => UI.Densities_supported_by_currently_inserted_media;
public string MediumSupportLabel => UI.Medium_types_currently_inserted_in_device;
public string SaveDensitySupportLabel => UI.ButtonLabel_Save_REPORT_DENSITY_SUPPORT_MEDIA_response;
public string SaveMediumSupportLabel => UI.ButtonLabel_Save_REPORT_DENSITY_SUPPORT_MEDIUM_MEDIA_response;
public string CompactDiscLabel => Localization.Core.Title_CompactDisc;
2023-10-05 01:52:48 +01:00
public string DvdLabel => Localization.Core.Title_DVD;
public string Dvd_R_WLabel => Localization.Core.Title_DVD_Plus_Dash_R_W;
public string XboxLabel => Localization.Core.Title_Xbox;
public string BluRayLabel => Localization.Core.Title_Blu_ray;
public string DumpLabel => UI.ButtonLabel_Dump_media_to_image;
public string ScanLabel => UI.ButtonLabel_Scan_media_surface;
2025-08-20 21:19:43 +01:00
async Task SaveElementAsync(byte[] data)
2022-03-06 13:29:38 +00:00
{
IStorageFile result = await _view.StorageProvider.SaveFilePickerAsync(new FilePickerSaveOptions
2022-03-06 13:29:38 +00:00
{
FileTypeChoices = new List<FilePickerFileType>
{
FilePickerFileTypes.Binary
}
2022-03-06 13:29:38 +00:00
});
2024-05-01 04:05:22 +01:00
if(result is null) return;
var saveFs = new FileStream(result.Path.AbsolutePath, FileMode.Create);
2022-03-06 13:29:38 +00:00
saveFs.Write(data, 0, data.Length);
2022-03-06 13:29:38 +00:00
saveFs.Close();
}
2025-08-20 21:19:43 +01:00
Task SaveReadMediaSerial() => SaveElementAsync(_scsiInfo.MediaSerialNumber);
2025-08-20 21:19:43 +01:00
Task SaveReadCapacity() => SaveElementAsync(_scsiInfo.ReadCapacity);
2025-08-20 21:19:43 +01:00
Task SaveReadCapacity16() => SaveElementAsync(_scsiInfo.ReadCapacity16);
2025-08-20 21:19:43 +01:00
Task SaveGetConfiguration() => SaveElementAsync(_scsiInfo.MmcConfiguration);
2025-08-20 21:19:43 +01:00
Task SaveRecognizedFormatLayers() => SaveElementAsync(_scsiInfo.RecognizedFormatLayers);
2025-08-20 21:19:43 +01:00
Task SaveWriteProtectionStatus() => SaveElementAsync(_scsiInfo.WriteProtectionStatus);
2025-08-20 21:19:43 +01:00
Task SaveDensitySupport() => SaveElementAsync(_scsiInfo.DensitySupport);
2025-08-20 21:19:43 +01:00
Task SaveMediumSupport() => SaveElementAsync(_scsiInfo.MediaTypeSupport);
2025-08-20 21:19:43 +01:00
async Task DumpAsync()
2022-03-06 13:29:38 +00:00
{
2022-11-13 19:38:03 +00:00
switch(_scsiInfo.MediaType)
{
2022-11-13 19:38:03 +00:00
case CommonTypes.MediaType.GDR or CommonTypes.MediaType.GDROM:
2024-05-01 04:05:22 +01:00
await MessageBoxManager
.GetMessageBoxStandard(UI.Title_Error,
Localization.Core.GD_ROM_dump_support_is_not_yet_implemented,
ButtonEnum.Ok,
Icon.Error)
.ShowWindowDialogAsync(_view);
2022-11-13 19:38:03 +00:00
return;
case CommonTypes.MediaType.XGD or CommonTypes.MediaType.XGD2 or CommonTypes.MediaType.XGD3
when _scsiInfo.DeviceInfo.ScsiInquiry?.KreonPresent != true:
2024-05-01 04:05:22 +01:00
await MessageBoxManager
.GetMessageBoxStandard(UI.Title_Error,
Localization.Core
.Dumping_Xbox_Game_Discs_requires_a_drive_with_Kreon_firmware,
ButtonEnum.Ok,
Icon.Error)
.ShowWindowDialogAsync(_view);
2022-11-13 19:38:03 +00:00
return;
2022-03-06 13:29:38 +00:00
}
var mediaDumpWindow = new MediaDump();
2022-03-06 13:29:38 +00:00
mediaDumpWindow.DataContext =
new MediaDumpViewModel(_devicePath, _scsiInfo.DeviceInfo, mediaDumpWindow, _scsiInfo);
2022-03-06 13:29:38 +00:00
mediaDumpWindow.Show();
}
2025-08-20 21:19:43 +01:00
async Task ScanAsync()
2022-03-06 13:29:38 +00:00
{
switch(_scsiInfo.MediaType)
{
// TODO: GD-ROM
case CommonTypes.MediaType.GDR:
case CommonTypes.MediaType.GDROM:
2024-05-01 04:05:22 +01:00
await MessageBoxManager
.GetMessageBoxStandard(UI.Title_Error,
Localization.Core.GD_ROM_scan_support_is_not_yet_implemented,
ButtonEnum.Ok,
Icon.Error)
.ShowWindowDialogAsync(_view);
2022-03-06 13:29:38 +00:00
return;
2022-03-06 13:29:38 +00:00
// TODO: Xbox
case CommonTypes.MediaType.XGD:
case CommonTypes.MediaType.XGD2:
case CommonTypes.MediaType.XGD3:
2023-09-26 01:29:07 +01:00
await MessageBoxManager.GetMessageBoxStandard(UI.Title_Error,
2024-05-01 04:05:22 +01:00
Localization.Core
.Scanning_Xbox_discs_is_not_yet_supported,
ButtonEnum.Ok,
Icon.Error)
.ShowWindowDialogAsync(_view);
2022-03-06 13:29:38 +00:00
return;
}
2022-03-06 13:29:38 +00:00
var mediaScanWindow = new MediaScan();
mediaScanWindow.DataContext = new MediaScanViewModel(_devicePath, mediaScanWindow);
mediaScanWindow.Show();
}
}