// /*************************************************************************** // Aaru Data Preservation Suite // ---------------------------------------------------------------------------- // // Filename : MediaScan.cs // Author(s) : Natalia Portillo // // Component : Core algorithms. // // --[ Description ] ---------------------------------------------------------- // // Scans media from devices. // // --[ 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.Diagnostics; using Aaru.CommonTypes; using Aaru.CommonTypes.Enums; using Aaru.Devices; using Humanizer; namespace Aaru.Core.Devices.Scanning; public sealed partial class MediaScan { const string MODULE_NAME = "Media scanning"; static readonly TimeSpan _oneSecond = 1.Seconds(); readonly Device _dev; readonly string _devicePath; readonly string _ibgLogPath; readonly string _mhddLogPath; readonly Stopwatch _scanStopwatch; readonly bool _seekTest; readonly Stopwatch _speedStopwatch; readonly bool _useBufferedReads; bool _aborted; /// Path to a MHDD log file /// Path to a IMGBurn log file /// Device path /// Device /// Enable seek test /// /// If MMC/SD does not support CMD23, use OS buffered reads instead of multiple single block /// commands /// public MediaScan(string mhddLogPath, string ibgLogPath, string devicePath, Device dev, bool useBufferedReads, bool seekTest = true) { _mhddLogPath = mhddLogPath; _ibgLogPath = ibgLogPath; _devicePath = devicePath; _dev = dev; _aborted = false; _seekTest = seekTest; _useBufferedReads = useBufferedReads; _scanStopwatch = new Stopwatch(); _speedStopwatch = new Stopwatch(); } /// Starts a media scan /// Media scan results /// Unknown device type public ScanResults Scan() { return _dev.Type switch { DeviceType.ATA => Ata(), DeviceType.MMC or DeviceType.SecureDigital => SecureDigital(), DeviceType.NVMe => Nvme(), DeviceType.ATAPI or DeviceType.SCSI => Scsi(), _ => throw new NotSupportedException(Localization.Core.Unknown_device_type) }; } /// Aborts the running media scan public void Abort() => _aborted = true; /// Event raised when the progress bar is not longer needed public event EndProgressHandler EndProgress; /// Event raised when a progress bar is needed public event InitProgressHandler InitProgress; /// Event raised to report status updates public event UpdateStatusHandler UpdateStatus; /// Event raised to report a fatal error that stops the dumping operation and should call user's attention public event ErrorMessageHandler StoppingErrorMessage; /// Event raised to update the values of a determinate progress bar public event UpdateProgressHandler UpdateProgress; /// Event raised to update the status of an indeterminate progress bar public event PulseProgressHandler PulseProgress; /// Updates lists of time taken on scanning from the specified sector public event ScanTimeHandler ScanTime; /// Specified a number of blocks could not be read on scan public event ScanUnreadableHandler ScanUnreadable; /// Initializes a block map that's going to be filled with a media scan public event InitBlockMapHandler InitBlockMap; /// Sends the speed of scanning a specific sector public event ScanSpeedHandler ScanSpeed; }