using System; using System.Linq; using Spd; using Spd.Interop; using SvdCli.Storage; namespace SvdCli.DriverAdapt { public class VirtualDrive { private readonly IStorage _storage; private readonly SpdImplement _spdImplement; private readonly StorageUnitHost _host; public long Size { get; } public VirtualDrive(IStorage storage) { _storage = storage; _spdImplement = new SpdImplement(_storage); _host = new StorageUnitHost(_spdImplement) { ProductId = storage.ProductId, ProductRevisionLevel = storage.ProductVersion, WriteProtected = storage.WriteProtect, UnmapSupported = storage.SupportTrim, BlockCount = storage.BlockCount, BlockLength = storage.BlockSize, MaxTransferLength = storage.MaxTransferLength, CacheSupported = true, EjectDisabled = false, Guid = Guid.NewGuid(), }; Size = storage.BlockSize * storage.BlockSize; } public void Attach() { _storage.Init(); _host.Start(); } public void Detach() { _host.Shutdown(); _storage.Exit(); } private class SpdImplement : StorageUnitBase { private readonly IStorage _storage; public SpdImplement(IStorage storage) => _storage = storage; public override void Read(byte[] buffer, ulong blockAddress, uint blockCount, bool flush, ref StorageUnitStatus status) { if (flush) _storage.Flush(); _storage.Read(buffer, blockAddress, blockCount); } public override void Write(byte[] buffer, ulong blockAddress, uint blockCount, bool flush, ref StorageUnitStatus status) { _storage.Write(buffer, blockAddress, blockCount); if (flush) _storage.Flush(); } public override void Flush(ulong blockAddress, uint blockCount, ref StorageUnitStatus status) { _storage.Flush(); } public override void Unmap(UnmapDescriptor[] descriptors, ref StorageUnitStatus status) { _storage.Trim(descriptors.Select(p => new TrimDescriptor(p.BlockAddress, p.BlockCount)).ToArray()); } } } }