123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177 |
- using SMBLibrary;
- using SmbSvr.Ramfs.Inters;
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Linq;
- using Utilities;
- namespace SmbSvr.Ramfs
- {
- internal class RamfsFileSystem : FileSystem
- {
- private readonly RamfsDirEntry _root = new RamfsDirEntry();
- public RamfsFileSystem()
- {
- _root.Entries.Add(new RamfsDirEntry
- {
- Name = "temp",
- ParentDir = _root
- });
- }
- public override IFileSystemEntry GetEntry(string path)
- {
- if (path == "\\") return _root;
- var seg = path.Split(new[] { '\\' }, StringSplitOptions.RemoveEmptyEntries);
- RamfsFileSystemEntry ptr = _root;
- foreach (var s in seg)
- {
- if (!ptr.IsDirectory) { ptr = null; break; }
- ptr = ((RamfsDirEntry)ptr).Entries.FirstOrDefault(p => p.Name == s);
- if (ptr == null) break;
- }
- return ptr;
- }
- private RamfsFileSystemEntry GetFsEntry(string path) => GetEntry(path) as RamfsFileSystemEntry ?? throw new FileNotFoundException();
- private RamfsDirEntry GetDirEntry(string path) => GetEntry(path) as RamfsDirEntry ?? throw new DirectoryNotFoundException();
- private RamfsFileEntry GetFileEntry(string path) => GetEntry(path) as RamfsFileEntry ?? throw new FileNotFoundException();
- public override List<IFileSystemEntry> ListEntriesInDirectory(string path) => GetDirEntry(path).Entries.Cast<IFileSystemEntry>().ToList();
- public override IFileSystemEntry CreateDirectory(string path)
- {
- var dir = GetDirEntry(Path.GetDirectoryName(path));
- var n = Path.GetFileName(path);
- if (dir.Entries.Any(p => p.Name == n)) throw new IOException("", (int)Win32Error.ERROR_ALREADY_EXISTS);
- var nd = new RamfsDirEntry
- {
- Name = n,
- ParentDir = dir
- };
- dir.Entries.Add(nd);
- return nd;
- }
- public override IFileSystemEntry CreateFile(string path)
- {
- var dir = GetDirEntry(Path.GetDirectoryName(path));
- var n = Path.GetFileName(path);
- if (dir.Entries.Any(p => p.Name == n)) throw new IOException("", (int)Win32Error.ERROR_ALREADY_EXISTS);
- var nf = new RamfsFileEntry
- {
- Name = n,
- ParentDir = dir
- };
- dir.Entries.Add(nf);
- return nf;
- }
- public override void Move(string source, string destination)
- {
- var destEntry = GetEntry(destination);
- if (destEntry != null) throw new IOException("", (int)Win32Error.ERROR_ALREADY_EXISTS);
- var destDir = GetDirEntry(Path.GetDirectoryName(destination));
- var nn = Path.GetFileName(destination);
- if (destDir.Entries.Any(p => p.Name == nn)) throw new IOException("", (int)Win32Error.ERROR_ALREADY_EXISTS);
- var sourceEntry = GetFsEntry(source);
- //remove from source dir
- //change name
- //add to dest dir
- sourceEntry.ParentDir.Entries.Remove(sourceEntry);
- sourceEntry.Name = nn;
- sourceEntry.ParentDir = destDir;
- destDir.Entries.Add(sourceEntry);
- }
- public override void Delete(string path)
- {
- var entry = GetFsEntry(path);
- entry.ParentDir.Entries.Remove(entry);
- entry.Dispose();
- }
- public override Stream OpenFile(string path, FileMode mode, FileAccess access, FileShare share, FileOptions options)
- {
- var file = GetFileEntry(path);
- var s = new StreamWrap(file.MemoryStream);
- if (mode == FileMode.Append) s.Position = s.Length;
- //if (options.HasFlag(FileOptions.DeleteOnClose)) s.Closed += delegate { Delete(path); };
- return s;
- }
- public override void SetAttributes(string path, bool? isHidden, bool? isReadonly, bool? isArchived)
- {
- var entry = GetFsEntry(path);
- if (isHidden.HasValue) entry.IsHidden = isHidden.Value;
- if (isReadonly.HasValue) entry.IsHidden = isReadonly.Value;
- if (isArchived.HasValue) entry.IsHidden = isArchived.Value;
- }
- public override void SetDates(string path, DateTime? creationDT, DateTime? lastWriteDT, DateTime? lastAccessDT)
- {
- var entry = GetFsEntry(path);
- if (creationDT.HasValue) entry.CreationTime = creationDT.Value;
- if (lastWriteDT.HasValue) entry.CreationTime = lastWriteDT.Value;
- if (lastAccessDT.HasValue) entry.CreationTime = lastAccessDT.Value;
- }
- public override string Name => "RAMFS";
- public override long Size => long.MaxValue;
- public override long FreeSpace => long.MaxValue;
- }
- internal abstract class RamfsFileSystemEntry : FileSystemEntry, IDisposable
- {
- protected RamfsFileSystemEntry()
- {
- CreationTime =
- LastAccessTime =
- LastWriteTime = DateTime.Now;
- }
- public RamfsDirEntry ParentDir { get; set; }
- public abstract void Dispose();
- }
- internal class RamfsFileEntry : RamfsFileSystemEntry
- {
- public override bool IsDirectory => false;
- public MemoryStream MemoryStream { get; set; } = new MemoryStream();
- public override ulong Size => (ulong)MemoryStream.Length;
- public override void Dispose()
- {
- MemoryStream.Dispose();
- }
- }
- internal class RamfsDirEntry : RamfsFileSystemEntry
- {
- public override bool IsDirectory => true;
- public List<RamfsFileSystemEntry> Entries { get; } = new List<RamfsFileSystemEntry>();
- public override ulong Size => (ulong)Entries.Sum(p => (long)p.Size);
- public override void Dispose()
- {
- foreach (var entry in Entries.ToArray())
- {
- Entries.Remove(entry);
- entry.Dispose();
- }
- }
- }
- }
|