RamfsFileSystem.cs 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. using SMBLibrary;
  2. using SmbSvr.Ramfs.Inters;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.IO;
  6. using System.Linq;
  7. using Utilities;
  8. namespace SmbSvr.Ramfs
  9. {
  10. internal class RamfsFileSystem : FileSystem
  11. {
  12. private readonly RamfsDirEntry _root = new RamfsDirEntry();
  13. public RamfsFileSystem()
  14. {
  15. _root.Entries.Add(new RamfsDirEntry
  16. {
  17. Name = "temp",
  18. ParentDir = _root
  19. });
  20. }
  21. public override IFileSystemEntry GetEntry(string path)
  22. {
  23. if (path == "\\") return _root;
  24. var seg = path.Split(new[] { '\\' }, StringSplitOptions.RemoveEmptyEntries);
  25. RamfsFileSystemEntry ptr = _root;
  26. foreach (var s in seg)
  27. {
  28. if (!ptr.IsDirectory) { ptr = null; break; }
  29. ptr = ((RamfsDirEntry)ptr).Entries.FirstOrDefault(p => p.Name == s);
  30. if (ptr == null) break;
  31. }
  32. return ptr;
  33. }
  34. private RamfsFileSystemEntry GetFsEntry(string path) => GetEntry(path) as RamfsFileSystemEntry ?? throw new FileNotFoundException();
  35. private RamfsDirEntry GetDirEntry(string path) => GetEntry(path) as RamfsDirEntry ?? throw new DirectoryNotFoundException();
  36. private RamfsFileEntry GetFileEntry(string path) => GetEntry(path) as RamfsFileEntry ?? throw new FileNotFoundException();
  37. public override List<IFileSystemEntry> ListEntriesInDirectory(string path) => GetDirEntry(path).Entries.Cast<IFileSystemEntry>().ToList();
  38. public override IFileSystemEntry CreateDirectory(string path)
  39. {
  40. var dir = GetDirEntry(Path.GetDirectoryName(path));
  41. var n = Path.GetFileName(path);
  42. if (dir.Entries.Any(p => p.Name == n)) throw new IOException("", (int)Win32Error.ERROR_ALREADY_EXISTS);
  43. var nd = new RamfsDirEntry
  44. {
  45. Name = n,
  46. ParentDir = dir
  47. };
  48. dir.Entries.Add(nd);
  49. return nd;
  50. }
  51. public override IFileSystemEntry CreateFile(string path)
  52. {
  53. var dir = GetDirEntry(Path.GetDirectoryName(path));
  54. var n = Path.GetFileName(path);
  55. if (dir.Entries.Any(p => p.Name == n)) throw new IOException("", (int)Win32Error.ERROR_ALREADY_EXISTS);
  56. var nf = new RamfsFileEntry
  57. {
  58. Name = n,
  59. ParentDir = dir
  60. };
  61. dir.Entries.Add(nf);
  62. return nf;
  63. }
  64. public override void Move(string source, string destination)
  65. {
  66. var destEntry = GetEntry(destination);
  67. if (destEntry != null) throw new IOException("", (int)Win32Error.ERROR_ALREADY_EXISTS);
  68. var destDir = GetDirEntry(Path.GetDirectoryName(destination));
  69. var nn = Path.GetFileName(destination);
  70. if (destDir.Entries.Any(p => p.Name == nn)) throw new IOException("", (int)Win32Error.ERROR_ALREADY_EXISTS);
  71. var sourceEntry = GetFsEntry(source);
  72. //remove from source dir
  73. //change name
  74. //add to dest dir
  75. sourceEntry.ParentDir.Entries.Remove(sourceEntry);
  76. sourceEntry.Name = nn;
  77. sourceEntry.ParentDir = destDir;
  78. destDir.Entries.Add(sourceEntry);
  79. }
  80. public override void Delete(string path)
  81. {
  82. var entry = GetFsEntry(path);
  83. entry.ParentDir.Entries.Remove(entry);
  84. entry.Dispose();
  85. }
  86. public override Stream OpenFile(string path, FileMode mode, FileAccess access, FileShare share, FileOptions options)
  87. {
  88. var file = GetFileEntry(path);
  89. var s = new StreamWrap(file.MemoryStream);
  90. if (mode == FileMode.Append) s.Position = s.Length;
  91. //if (options.HasFlag(FileOptions.DeleteOnClose)) s.Closed += delegate { Delete(path); };
  92. return s;
  93. }
  94. public override void SetAttributes(string path, bool? isHidden, bool? isReadonly, bool? isArchived)
  95. {
  96. var entry = GetFsEntry(path);
  97. if (isHidden.HasValue) entry.IsHidden = isHidden.Value;
  98. if (isReadonly.HasValue) entry.IsHidden = isReadonly.Value;
  99. if (isArchived.HasValue) entry.IsHidden = isArchived.Value;
  100. }
  101. public override void SetDates(string path, DateTime? creationDT, DateTime? lastWriteDT, DateTime? lastAccessDT)
  102. {
  103. var entry = GetFsEntry(path);
  104. if (creationDT.HasValue) entry.CreationTime = creationDT.Value;
  105. if (lastWriteDT.HasValue) entry.CreationTime = lastWriteDT.Value;
  106. if (lastAccessDT.HasValue) entry.CreationTime = lastAccessDT.Value;
  107. }
  108. public override string Name => "RAMFS";
  109. public override long Size => long.MaxValue;
  110. public override long FreeSpace => long.MaxValue;
  111. }
  112. internal abstract class RamfsFileSystemEntry : FileSystemEntry, IDisposable
  113. {
  114. protected RamfsFileSystemEntry()
  115. {
  116. CreationTime =
  117. LastAccessTime =
  118. LastWriteTime = DateTime.Now;
  119. }
  120. public RamfsDirEntry ParentDir { get; set; }
  121. public abstract void Dispose();
  122. }
  123. internal class RamfsFileEntry : RamfsFileSystemEntry
  124. {
  125. public override bool IsDirectory => false;
  126. public MemoryStream MemoryStream { get; set; } = new MemoryStream();
  127. public override ulong Size => (ulong)MemoryStream.Length;
  128. public override void Dispose()
  129. {
  130. MemoryStream.Dispose();
  131. }
  132. }
  133. internal class RamfsDirEntry : RamfsFileSystemEntry
  134. {
  135. public override bool IsDirectory => true;
  136. public List<RamfsFileSystemEntry> Entries { get; } = new List<RamfsFileSystemEntry>();
  137. public override ulong Size => (ulong)Entries.Sum(p => (long)p.Size);
  138. public override void Dispose()
  139. {
  140. foreach (var entry in Entries.ToArray())
  141. {
  142. Entries.Remove(entry);
  143. entry.Dispose();
  144. }
  145. }
  146. }
  147. }