// /*************************************************************************** // Aaru Data Preservation Suite // ---------------------------------------------------------------------------- // // Filename : DeviceInfoViewModel.cs // Author(s) : Natalia Portillo // // 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 . // // ---------------------------------------------------------------------------- // Copyright © 2011-2025 Natalia Portillo // ****************************************************************************/ using System; using System.Collections.Generic; using System.IO; using System.Threading.Tasks; using System.Windows.Input; using Aaru.Decoders.SCSI.SSC; using Aaru.Devices; using Aaru.Gui.ViewModels.Tabs; using Aaru.Gui.Views.Tabs; using Aaru.Localization; using Avalonia.Controls; using Avalonia.Platform.Storage; using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using Humanizer; using Humanizer.Localisation; using DeviceInfo = Aaru.Core.Devices.Info.DeviceInfo; namespace Aaru.Gui.ViewModels.Panels; public sealed partial class DeviceInfoViewModel : ViewModelBase { readonly DeviceInfo _devInfo; readonly Window _view; [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; public DeviceInfoViewModel(DeviceInfo devInfo, Window view) { SaveUsbDescriptorsCommand = new AsyncRelayCommand(SaveUsbDescriptorsAsync); _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) { UsbVisible = true; SaveUsbDescriptorsEnabled = devInfo.UsbDescriptors != null; UsbVendorId = $"{devInfo.UsbVendorId:X4}"; UsbProductId = $"{devInfo.UsbProductId:X4}"; UsbManufacturer = devInfo.UsbManufacturerString; UsbProduct = devInfo.UsbProductString; UsbSerial = devInfo.UsbSerialString; } 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) { PcmciaInfo = new PcmciaInfo { DataContext = new PcmciaInfoViewModel(devInfo.Cis, _view) }; } if(devInfo.AtaIdentify != null || devInfo.AtapiIdentify != null) { AtaInfo = new AtaInfo { DataContext = new AtaInfoViewModel(devInfo.AtaIdentify, devInfo.AtapiIdentify, devInfo.AtaMcptError, _view) }; } if(devInfo.ScsiInquiryData != null) { ScsiInfo = new ScsiInfo { DataContext = new ScsiInfoViewModel(devInfo.ScsiInquiryData, devInfo.ScsiInquiry, devInfo.ScsiEvpdPages, devInfo.ScsiMode, devInfo.ScsiType, devInfo.ScsiModeSense6, devInfo.ScsiModeSense10, devInfo.MmcConfiguration, _view) }; if(devInfo.PlextorFeatures != null) { PlextorVisible = true; if(devInfo.PlextorFeatures.Eeprom != null) { PlextorEepromVisible = true; PlextorDiscs = $"{devInfo.PlextorFeatures.Discs}"; PlextorCdReadTime = devInfo.PlextorFeatures.CdReadTime.Seconds().Humanize(minUnit: TimeUnit.Second); PlextorCdWriteTime = devInfo.PlextorFeatures.CdWriteTime.Seconds().Humanize(minUnit: TimeUnit.Second); if(devInfo.PlextorFeatures.IsDvd) { PlextorDvdTimesVisible = true; PlextorDvdReadTime = devInfo.PlextorFeatures.DvdReadTime.Seconds() .Humanize(minUnit: TimeUnit.Second); PlextorDvdWriteTime = devInfo.PlextorFeatures.DvdWriteTime.Seconds() .Humanize(minUnit: TimeUnit.Second); } } PlextorPoweRec = devInfo.PlextorFeatures.PoweRec; if(devInfo.PlextorFeatures.PoweRec) { PlextorPoweRecEnabled = devInfo.PlextorFeatures.PoweRecEnabled; if(devInfo.PlextorFeatures.PoweRecEnabled) { PlextorPoweRecEnabled = true; if(devInfo.PlextorFeatures.PoweRecRecommendedSpeed > 0) { PlextorPoweRecRecommendedVisible = true; PlextorPoweRecRecommended = string.Format(UI._0_Kb_sec, devInfo.PlextorFeatures.PoweRecRecommendedSpeed); } if(devInfo.PlextorFeatures.PoweRecSelected > 0) { PlextorPoweRecSelectedVisible = true; PlextorPoweRecSelected = string.Format(UI._0_Kb_sec, devInfo.PlextorFeatures.PoweRecSelected); } if(devInfo.PlextorFeatures.PoweRecMax > 0) { PlextorPoweRecMaxVisible = true; PlextorPoweRecMax = string.Format(UI._0_Kb_sec, devInfo.PlextorFeatures.PoweRecMax); } if(devInfo.PlextorFeatures.PoweRecLast > 0) { PlextorPoweRecLastVisible = true; PlextorPoweRecLast = string.Format(UI._0_Kb_sec, devInfo.PlextorFeatures.PoweRecLast); } } } PlextorSilentMode = devInfo.PlextorFeatures.SilentMode; if(devInfo.PlextorFeatures.SilentMode) { PlextorSilentModeEnabled = devInfo.PlextorFeatures.SilentModeEnabled; if(devInfo.PlextorFeatures.SilentModeEnabled) { PlextorSilentModeAccessTime = devInfo.PlextorFeatures.AccessTimeLimit == 2 ? Localization.Core.Access_time_is_slow : Localization.Core.Access_time_is_fast; PlextorSilentModeCdReadSpeedLimit = devInfo.PlextorFeatures.CdReadSpeedLimit > 0 ? $"{devInfo.PlextorFeatures.CdReadSpeedLimit}x" : UI.unlimited_as_in_speed; PlextorSilentModeCdWriteSpeedLimit = devInfo.PlextorFeatures.CdWriteSpeedLimit > 0 ? $"{devInfo.PlextorFeatures.CdReadSpeedLimit}x" : UI.unlimited_as_in_speed; if(devInfo.PlextorFeatures.IsDvd) { PlextorSilentModeDvdReadSpeedLimitVisible = true; PlextorSilentModeDvdReadSpeedLimit = devInfo.PlextorFeatures.DvdReadSpeedLimit > 0 ? $"{devInfo.PlextorFeatures.DvdReadSpeedLimit}x" : UI.unlimited_as_in_speed; } } } PlextorGigaRec = devInfo.PlextorFeatures.GigaRec; PlextorSecuRec = devInfo.PlextorFeatures.SecuRec; PlextorSpeedRead = devInfo.PlextorFeatures.SpeedRead; if(devInfo.PlextorFeatures.SpeedRead) PlextorSpeedEnabled = devInfo.PlextorFeatures.SpeedReadEnabled; PlextorHiding = devInfo.PlextorFeatures.Hiding; if(devInfo.PlextorFeatures.Hiding) { PlextorHidesRecordables = devInfo.PlextorFeatures.HidesRecordables; PlextorHidesSessions = devInfo.PlextorFeatures.HidesSessions; } PlextorVariRec = devInfo.PlextorFeatures.VariRec; if(devInfo.PlextorFeatures.IsDvd) { PlextorVariRecDvd = devInfo.PlextorFeatures.VariRecDvd; PlextorBitSetting = devInfo.PlextorFeatures.BitSetting; PlextorBitSettingDl = devInfo.PlextorFeatures.BitSettingDl; PlextorDvdPlusWriteTest = devInfo.PlextorFeatures.DvdPlusWriteTest; } } 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) { BlockLimits.BlockLimitsData? blockLimits = Decoders.SCSI.SSC.BlockLimits.Decode(devInfo.BlockLimits); if(blockLimits.HasValue) { Ssc = true; if(blockLimits.Value.minBlockLen == blockLimits.Value.maxBlockLen) { MinBlockSize = string.Format(Localization.Core.Device_block_size_is_fixed_at_0_bytes, blockLimits.Value.minBlockLen); } else { MaxBlockSize = blockLimits.Value.maxBlockLen > 0 ? string.Format(Localization.Core.Device_maximum_block_size_is_0_bytes, blockLimits.Value.maxBlockLen) : Localization.Core.Device_does_not_specify_a_maximum_block_size; MinBlockSize = string.Format(Localization.Core.Device_minimum_block_size_is_0_bytes, blockLimits.Value.minBlockLen); if(blockLimits.Value.granularity > 0) { 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)); } } } } if(devInfo.DensitySupport != null) { if(devInfo.DensitySupportHeader.HasValue) Densities = DensitySupport.PrettifyDensity(devInfo.DensitySupportHeader); } if(devInfo.MediumDensitySupport != null) { if(devInfo.MediaTypeSupportHeader.HasValue) MediumTypes = DensitySupport.PrettifyMediumType(devInfo.MediaTypeSupportHeader); MediumDensity = DensitySupport.PrettifyMediumType(devInfo.MediumDensitySupport); } } SdMmcInfo = new SdMmcInfo { DataContext = new SdMmcInfoViewModel(devInfo.Type, devInfo.CID, devInfo.CSD, devInfo.OCR, devInfo.ExtendedCSD, devInfo.SCR) }; } public ICommand SaveUsbDescriptorsCommand { get; } async Task SaveUsbDescriptorsAsync() { IStorageFile result = await _view.StorageProvider.SaveFilePickerAsync(new FilePickerSaveOptions { FileTypeChoices = new List { FilePickerFileTypes.Binary } }); if(result is null) return; var saveFs = new FileStream(result.Path.AbsolutePath, FileMode.Create); saveFs.Write(_devInfo.UsbDescriptors, 0, _devInfo.UsbDescriptors.Length); saveFs.Close(); } }