using DiscUtils; using DiscUtils.Ntfs; using DiscUtils.Partitions; using DiscUtils.Streams; using SvdCli.Storage; using System; using System.IO; namespace SvdCli.DiskUtils { internal static class FsMaker { public static void MakeNtfsRamDisk(ISvdStorage storage, bool createTempFolder) { storage.Init(); using var sss = new SvdStorageStream(storage); using VirtualDisk disk = new DiscUtils.Raw.Disk(sss, Ownership.None); BiosPartitionTable.Initialize(disk, WellKnownPartitionType.WindowsNtfs); var volMgr = new VolumeManager(disk); using var destNtfs = NtfsFileSystem.Format(volMgr.GetLogicalVolumes()[0], "RamDIsk", new NtfsFormatOptions()); if (createTempFolder) destNtfs.CreateDirectory("Temp"); } private class SvdStorageStream : Stream { private readonly ISvdStorage _storage; public SvdStorageStream(ISvdStorage storage) => _storage = storage; public override int Read(byte[] buffer, int offset, int count) { var read = _storage.Read(buffer, Position, offset, count); Position += read; return read; } public override void Write(byte[] buffer, int offset, int count) { _storage.Write(buffer, Position, offset, count); Position += count; } public override void Flush() => _storage.Flush(); public override long Seek(long offset, SeekOrigin origin) { switch (origin) { case SeekOrigin.Begin: Position = offset; break; case SeekOrigin.Current: Position += offset; break; case SeekOrigin.End: Position = Length + offset; break; default: throw new ArgumentOutOfRangeException(nameof(origin), origin, null); } return Position; } public override void SetLength(long value) { } public override bool CanRead => true; public override bool CanSeek => true; public override bool CanWrite => true; public override long Length => _storage.BlockSize * (long)_storage.BlockCount; public override long Position { get; set; } } } }