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

524 lines
19 KiB
C#
Raw Normal View History

2020-04-17 21:45:50 +01:00
// /***************************************************************************
// Aaru Data Preservation Suite
// ----------------------------------------------------------------------------
//
// Filename : DeviceInfoViewModel.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : GUI view models.
//
// --[ Description ] ----------------------------------------------------------
//
// View model and code for the device 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.Threading.Tasks;
2025-08-20 21:19:43 +01:00
using System.Windows.Input;
using Aaru.Decoders.SCSI.SSC;
using Aaru.Devices;
2020-04-16 20:40:25 +01:00
using Aaru.Gui.ViewModels.Tabs;
using Aaru.Gui.Views.Tabs;
using Aaru.Localization;
using Avalonia.Controls;
using Avalonia.Platform.Storage;
2025-08-20 21:19:43 +01:00
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
2023-09-26 03:39:10 +01:00
using Humanizer;
using Humanizer.Localisation;
using DeviceInfo = Aaru.Core.Devices.Info.DeviceInfo;
namespace Aaru.Gui.ViewModels.Panels;
2025-08-20 21:19:43 +01:00
public sealed partial class DeviceInfoViewModel : ViewModelBase
{
2022-03-06 13:29:38 +00:00
readonly DeviceInfo _devInfo;
readonly Window _view;
2025-08-20 21:19:43 +01:00
[ObservableProperty]
AtaInfo _ataInfo;
[ObservableProperty]
string _blockLimits;
[ObservableProperty]
string _blockSizeGranularity;
[ObservableProperty]
string _cid;
[ObservableProperty]
string _csd;
[ObservableProperty]
string _densities;
[ObservableProperty]
string _deviceType;
[ObservableProperty]
string _extendedCsd;
[ObservableProperty]
string _firewireGuid;
[ObservableProperty]
string _firewireManufacturer;
[ObservableProperty]
string _firewireModel;
[ObservableProperty]
string _firewireModelId;
[ObservableProperty]
string _firewireVendorId;
[ObservableProperty]
bool _firewireVisible;
[ObservableProperty]
bool _kreon;
[ObservableProperty]
bool _kreonChallengeResponse;
[ObservableProperty]
bool _kreonChallengeResponse360;
[ObservableProperty]
bool _kreonDecryptSs;
[ObservableProperty]
bool _kreonDecryptSs360;
[ObservableProperty]
bool _kreonErrorSkipping;
[ObservableProperty]
bool _kreonLock;
[ObservableProperty]
bool _kreonWxripperUnlock;
[ObservableProperty]
bool _kreonWxripperUnlock360;
[ObservableProperty]
bool _kreonXtremeUnlock;
[ObservableProperty]
bool _kreonXtremeUnlock360;
[ObservableProperty]
string _manufacturer;
[ObservableProperty]
string _maxBlockSize;
[ObservableProperty]
string _mediumDensity;
[ObservableProperty]
string _mediumTypes;
[ObservableProperty]
string _minBlockSize;
[ObservableProperty]
string _model;
[ObservableProperty]
string _ocr;
[ObservableProperty]
PcmciaInfo _pcmciaInfo;
[ObservableProperty]
bool _plextorBitSetting;
[ObservableProperty]
bool _plextorBitSettingDl;
[ObservableProperty]
string _plextorCdReadTime;
[ObservableProperty]
string _plextorCdWriteTime;
[ObservableProperty]
string _plextorDiscs;
[ObservableProperty]
string _plextorDvd;
[ObservableProperty]
bool _plextorDvdPlusWriteTest;
[ObservableProperty]
string _plextorDvdReadTime;
[ObservableProperty]
bool _plextorDvdTimesVisible;
[ObservableProperty]
string _plextorDvdWriteTime;
[ObservableProperty]
bool _plextorEepromVisible;
[ObservableProperty]
bool _plextorGigaRec;
[ObservableProperty]
bool _plextorHidesRecordables;
[ObservableProperty]
bool _plextorHidesSessions;
[ObservableProperty]
bool _plextorHiding;
[ObservableProperty]
bool _plextorPoweRec;
[ObservableProperty]
bool _plextorPoweRecEnabled;
[ObservableProperty]
string _plextorPoweRecLast;
[ObservableProperty]
bool _plextorPoweRecLastVisible;
[ObservableProperty]
string _plextorPoweRecMax;
[ObservableProperty]
bool _plextorPoweRecMaxVisible;
[ObservableProperty]
string _plextorPoweRecRecommended;
[ObservableProperty]
bool _plextorPoweRecRecommendedVisible;
[ObservableProperty]
string _plextorPoweRecSelected;
[ObservableProperty]
bool _plextorPoweRecSelectedVisible;
[ObservableProperty]
bool _plextorSecuRec;
[ObservableProperty]
bool _plextorSilentMode;
[ObservableProperty]
string _plextorSilentModeAccessTime;
[ObservableProperty]
string _plextorSilentModeCdReadSpeedLimit;
[ObservableProperty]
string _plextorSilentModeCdWriteSpeedLimit;
[ObservableProperty]
string _plextorSilentModeDvdReadSpeedLimit;
[ObservableProperty]
bool _plextorSilentModeDvdReadSpeedLimitVisible;
[ObservableProperty]
bool _plextorSilentModeEnabled;
[ObservableProperty]
bool _plextorSpeedEnabled;
[ObservableProperty]
bool _plextorSpeedRead;
[ObservableProperty]
bool _plextorVariRec;
[ObservableProperty]
bool _plextorVariRecDvd;
[ObservableProperty]
bool _plextorVisible;
[ObservableProperty]
bool _removable;
[ObservableProperty]
string _revision;
[ObservableProperty]
bool _saveUsbDescriptorsEnabled;
[ObservableProperty]
string _scr;
[ObservableProperty]
ScsiInfo _scsiInfo;
[ObservableProperty]
string _scsiType;
[ObservableProperty]
string _sdMm;
[ObservableProperty]
SdMmcInfo _sdMmcInfo;
[ObservableProperty]
string _secureDigital;
[ObservableProperty]
string _serial;
[ObservableProperty]
bool _ssc;
[ObservableProperty]
string _usbConnected;
[ObservableProperty]
string _usbManufacturer;
[ObservableProperty]
string _usbProduct;
[ObservableProperty]
string _usbProductId;
[ObservableProperty]
string _usbSerial;
[ObservableProperty]
string _usbVendorId;
[ObservableProperty]
bool _usbVisible;
2022-03-06 13:29:38 +00:00
public DeviceInfoViewModel(DeviceInfo devInfo, Window view)
{
2025-08-20 21:19:43 +01:00
SaveUsbDescriptorsCommand = new AsyncRelayCommand(SaveUsbDescriptorsAsync);
2022-03-06 13:29:38 +00:00
_view = view;
_devInfo = devInfo;
DeviceType = devInfo.Type.ToString();
Manufacturer = devInfo.Manufacturer;
Model = devInfo.Model;
Revision = devInfo.FirmwareRevision;
Serial = devInfo.Serial;
ScsiType = devInfo.ScsiType.ToString();
Removable = devInfo.IsRemovable;
UsbVisible = devInfo.IsUsb;
if(devInfo.IsUsb)
{
2022-03-06 13:29:38 +00:00
UsbVisible = true;
SaveUsbDescriptorsEnabled = devInfo.UsbDescriptors != null;
UsbVendorId = $"{devInfo.UsbVendorId:X4}";
UsbProductId = $"{devInfo.UsbProductId:X4}";
UsbManufacturer = devInfo.UsbManufacturerString;
UsbProduct = devInfo.UsbProductString;
UsbSerial = devInfo.UsbSerialString;
}
2022-03-06 13:29:38 +00:00
if(devInfo.IsFireWire)
{
FirewireVisible = true;
FirewireVendorId = $"{devInfo.FireWireVendor:X4}";
FirewireModelId = $"{devInfo.FireWireModel:X4}";
FirewireManufacturer = devInfo.FireWireVendorName;
FirewireModel = devInfo.FireWireModelName;
FirewireGuid = $"{devInfo.FireWireGuid:X16}";
}
if(devInfo.IsPcmcia)
2023-10-03 23:27:57 +01:00
{
2022-03-06 13:29:38 +00:00
PcmciaInfo = new PcmciaInfo
{
2022-03-06 13:29:38 +00:00
DataContext = new PcmciaInfoViewModel(devInfo.Cis, _view)
};
2023-10-03 23:27:57 +01:00
}
if(devInfo.AtaIdentify != null || devInfo.AtapiIdentify != null)
2023-10-03 23:27:57 +01:00
{
2022-03-06 13:29:38 +00:00
AtaInfo = new AtaInfo
{
2022-03-06 13:29:38 +00:00
DataContext =
new AtaInfoViewModel(devInfo.AtaIdentify, devInfo.AtapiIdentify, devInfo.AtaMcptError, _view)
};
2023-10-03 23:27:57 +01:00
}
2022-03-06 13:29:38 +00:00
if(devInfo.ScsiInquiryData != null)
{
ScsiInfo = new ScsiInfo
{
2024-05-01 04:05:22 +01:00
DataContext = new ScsiInfoViewModel(devInfo.ScsiInquiryData,
devInfo.ScsiInquiry,
devInfo.ScsiEvpdPages,
devInfo.ScsiMode,
devInfo.ScsiType,
devInfo.ScsiModeSense6,
devInfo.ScsiModeSense10,
devInfo.MmcConfiguration,
_view)
2022-03-06 13:29:38 +00:00
};
2022-03-06 13:29:38 +00:00
if(devInfo.PlextorFeatures != null)
{
2022-03-06 13:29:38 +00:00
PlextorVisible = true;
2022-03-06 13:29:38 +00:00
if(devInfo.PlextorFeatures.Eeprom != null)
{
2022-03-06 13:29:38 +00:00
PlextorEepromVisible = true;
2023-10-03 23:27:57 +01:00
PlextorDiscs = $"{devInfo.PlextorFeatures.Discs}";
2023-09-26 03:39:10 +01:00
PlextorCdReadTime = devInfo.PlextorFeatures.CdReadTime.Seconds().Humanize(minUnit: TimeUnit.Second);
2023-09-26 03:39:10 +01:00
PlextorCdWriteTime =
devInfo.PlextorFeatures.CdWriteTime.Seconds().Humanize(minUnit: TimeUnit.Second);
2022-03-06 13:29:38 +00:00
if(devInfo.PlextorFeatures.IsDvd)
{
PlextorDvdTimesVisible = true;
2024-05-01 04:05:22 +01:00
PlextorDvdReadTime = devInfo.PlextorFeatures.DvdReadTime.Seconds()
.Humanize(minUnit: TimeUnit.Second);
2024-05-01 04:05:22 +01:00
PlextorDvdWriteTime = devInfo.PlextorFeatures.DvdWriteTime.Seconds()
.Humanize(minUnit: TimeUnit.Second);
}
2022-03-06 13:29:38 +00:00
}
2022-03-06 13:29:38 +00:00
PlextorPoweRec = devInfo.PlextorFeatures.PoweRec;
2022-03-06 13:29:38 +00:00
if(devInfo.PlextorFeatures.PoweRec)
{
PlextorPoweRecEnabled = devInfo.PlextorFeatures.PoweRecEnabled;
if(devInfo.PlextorFeatures.PoweRecEnabled)
{
2022-03-06 13:29:38 +00:00
PlextorPoweRecEnabled = true;
2022-03-06 13:29:38 +00:00
if(devInfo.PlextorFeatures.PoweRecRecommendedSpeed > 0)
{
2022-03-06 13:29:38 +00:00
PlextorPoweRecRecommendedVisible = true;
PlextorPoweRecRecommended =
string.Format(UI._0_Kb_sec, devInfo.PlextorFeatures.PoweRecRecommendedSpeed);
2022-03-06 13:29:38 +00:00
}
2022-03-06 13:29:38 +00:00
if(devInfo.PlextorFeatures.PoweRecSelected > 0)
{
2022-03-06 13:29:38 +00:00
PlextorPoweRecSelectedVisible = true;
PlextorPoweRecSelected =
string.Format(UI._0_Kb_sec, devInfo.PlextorFeatures.PoweRecSelected);
2022-03-06 13:29:38 +00:00
}
2022-03-06 13:29:38 +00:00
if(devInfo.PlextorFeatures.PoweRecMax > 0)
{
PlextorPoweRecMaxVisible = true;
PlextorPoweRecMax = string.Format(UI._0_Kb_sec, devInfo.PlextorFeatures.PoweRecMax);
2022-03-06 13:29:38 +00:00
}
2022-03-06 13:29:38 +00:00
if(devInfo.PlextorFeatures.PoweRecLast > 0)
{
PlextorPoweRecLastVisible = true;
PlextorPoweRecLast = string.Format(UI._0_Kb_sec, devInfo.PlextorFeatures.PoweRecLast);
}
}
2022-03-06 13:29:38 +00:00
}
2022-03-06 13:29:38 +00:00
PlextorSilentMode = devInfo.PlextorFeatures.SilentMode;
if(devInfo.PlextorFeatures.SilentMode)
{
PlextorSilentModeEnabled = devInfo.PlextorFeatures.SilentModeEnabled;
2022-03-06 13:29:38 +00:00
if(devInfo.PlextorFeatures.SilentModeEnabled)
{
2022-03-06 13:29:38 +00:00
PlextorSilentModeAccessTime = devInfo.PlextorFeatures.AccessTimeLimit == 2
? Localization.Core.Access_time_is_slow
: Localization.Core.Access_time_is_fast;
2022-03-06 13:29:38 +00:00
PlextorSilentModeCdReadSpeedLimit =
devInfo.PlextorFeatures.CdReadSpeedLimit > 0
2023-10-03 23:27:57 +01:00
? $"{devInfo.PlextorFeatures.CdReadSpeedLimit}x"
: UI.unlimited_as_in_speed;
2022-03-06 13:29:38 +00:00
PlextorSilentModeCdWriteSpeedLimit =
devInfo.PlextorFeatures.CdWriteSpeedLimit > 0
2023-10-03 23:27:57 +01:00
? $"{devInfo.PlextorFeatures.CdReadSpeedLimit}x"
: UI.unlimited_as_in_speed;
2022-03-06 13:29:38 +00:00
if(devInfo.PlextorFeatures.IsDvd)
{
PlextorSilentModeDvdReadSpeedLimitVisible = true;
2022-03-06 13:29:38 +00:00
PlextorSilentModeDvdReadSpeedLimit =
devInfo.PlextorFeatures.DvdReadSpeedLimit > 0
2023-10-03 23:27:57 +01:00
? $"{devInfo.PlextorFeatures.DvdReadSpeedLimit}x"
: UI.unlimited_as_in_speed;
2022-03-06 13:29:38 +00:00
}
}
}
2022-03-06 13:29:38 +00:00
PlextorGigaRec = devInfo.PlextorFeatures.GigaRec;
PlextorSecuRec = devInfo.PlextorFeatures.SecuRec;
PlextorSpeedRead = devInfo.PlextorFeatures.SpeedRead;
2024-05-01 04:05:22 +01:00
if(devInfo.PlextorFeatures.SpeedRead) PlextorSpeedEnabled = devInfo.PlextorFeatures.SpeedReadEnabled;
2022-03-06 13:29:38 +00:00
PlextorHiding = devInfo.PlextorFeatures.Hiding;
2022-03-06 13:29:38 +00:00
if(devInfo.PlextorFeatures.Hiding)
{
PlextorHidesRecordables = devInfo.PlextorFeatures.HidesRecordables;
PlextorHidesSessions = devInfo.PlextorFeatures.HidesSessions;
}
2022-03-06 13:29:38 +00:00
PlextorVariRec = devInfo.PlextorFeatures.VariRec;
2022-03-06 13:29:38 +00:00
if(devInfo.PlextorFeatures.IsDvd)
{
PlextorVariRecDvd = devInfo.PlextorFeatures.VariRecDvd;
PlextorBitSetting = devInfo.PlextorFeatures.BitSetting;
PlextorBitSettingDl = devInfo.PlextorFeatures.BitSettingDl;
PlextorDvdPlusWriteTest = devInfo.PlextorFeatures.DvdPlusWriteTest;
}
2022-03-06 13:29:38 +00:00
}
2022-03-06 13:29:38 +00:00
if(devInfo.ScsiInquiry?.KreonPresent == true)
{
Kreon = true;
KreonChallengeResponse = devInfo.KreonFeatures.HasFlag(KreonFeatures.ChallengeResponse);
KreonDecryptSs = devInfo.KreonFeatures.HasFlag(KreonFeatures.DecryptSs);
KreonXtremeUnlock = devInfo.KreonFeatures.HasFlag(KreonFeatures.XtremeUnlock);
KreonWxripperUnlock = devInfo.KreonFeatures.HasFlag(KreonFeatures.WxripperUnlock);
KreonChallengeResponse360 = devInfo.KreonFeatures.HasFlag(KreonFeatures.ChallengeResponse360);
KreonDecryptSs360 = devInfo.KreonFeatures.HasFlag(KreonFeatures.DecryptSs360);
KreonXtremeUnlock360 = devInfo.KreonFeatures.HasFlag(KreonFeatures.XtremeUnlock360);
KreonWxripperUnlock360 = devInfo.KreonFeatures.HasFlag(KreonFeatures.WxripperUnlock360);
KreonLock = devInfo.KreonFeatures.HasFlag(KreonFeatures.Lock);
KreonErrorSkipping = devInfo.KreonFeatures.HasFlag(KreonFeatures.ErrorSkipping);
}
if(devInfo.BlockLimits != null)
{
2022-03-07 07:36:44 +00:00
BlockLimits.BlockLimitsData? blockLimits = Decoders.SCSI.SSC.BlockLimits.Decode(devInfo.BlockLimits);
2022-03-06 13:29:38 +00:00
if(blockLimits.HasValue)
{
2022-03-06 13:29:38 +00:00
Ssc = true;
if(blockLimits.Value.minBlockLen == blockLimits.Value.maxBlockLen)
2023-10-03 23:27:57 +01:00
{
MinBlockSize = string.Format(Localization.Core.Device_block_size_is_fixed_at_0_bytes,
blockLimits.Value.minBlockLen);
2023-10-03 23:27:57 +01:00
}
2022-03-06 13:29:38 +00:00
else
{
MaxBlockSize = blockLimits.Value.maxBlockLen > 0
? string.Format(Localization.Core.Device_maximum_block_size_is_0_bytes,
2023-10-03 23:27:57 +01:00
blockLimits.Value.maxBlockLen)
: Localization.Core.Device_does_not_specify_a_maximum_block_size;
2022-03-06 13:29:38 +00:00
MinBlockSize = string.Format(Localization.Core.Device_minimum_block_size_is_0_bytes,
blockLimits.Value.minBlockLen);
2022-03-06 13:29:38 +00:00
if(blockLimits.Value.granularity > 0)
2023-10-03 23:27:57 +01:00
{
BlockSizeGranularity =
string.Format(Localization.Core.Device_needs_a_block_size_granularity_of_pow_0_1_bytes,
blockLimits.Value.granularity,
Math.Pow(2, blockLimits.Value.granularity));
2023-10-03 23:27:57 +01:00
}
2022-03-06 13:29:38 +00:00
}
}
}
2022-03-06 13:29:38 +00:00
if(devInfo.DensitySupport != null)
2023-10-03 23:27:57 +01:00
{
2022-03-06 13:29:38 +00:00
if(devInfo.DensitySupportHeader.HasValue)
Densities = DensitySupport.PrettifyDensity(devInfo.DensitySupportHeader);
2023-10-03 23:27:57 +01:00
}
2022-03-06 13:29:38 +00:00
if(devInfo.MediumDensitySupport != null)
{
if(devInfo.MediaTypeSupportHeader.HasValue)
MediumTypes = DensitySupport.PrettifyMediumType(devInfo.MediaTypeSupportHeader);
2022-03-06 13:29:38 +00:00
MediumDensity = DensitySupport.PrettifyMediumType(devInfo.MediumDensitySupport);
}
}
2022-03-06 13:29:38 +00:00
SdMmcInfo = new SdMmcInfo
{
2024-05-01 04:05:22 +01:00
DataContext = new SdMmcInfoViewModel(devInfo.Type,
devInfo.CID,
devInfo.CSD,
devInfo.OCR,
devInfo.ExtendedCSD,
devInfo.SCR)
2022-03-06 13:29:38 +00:00
};
}
2025-08-20 21:19:43 +01:00
public ICommand SaveUsbDescriptorsCommand { get; }
2022-03-06 13:29:38 +00:00
2025-08-20 21:19:43 +01:00
async Task SaveUsbDescriptorsAsync()
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(_devInfo.UsbDescriptors, 0, _devInfo.UsbDescriptors.Length);
2022-03-06 13:29:38 +00:00
saveFs.Close();
}
}