PageRenderTime 36ms CodeModel.GetById 13ms RepoModel.GetById 1ms app.codeStats 0ms

/JadeFS/JadeFS.cs

https://gitlab.com/tim-m89/JadeFS
C# | 381 lines | 368 code | 10 blank | 3 comment | 1 complexity | 2cf8784b3a0fdf42bfb2ee384c260dec MD5 | raw file
  1. /* -----------------------------------------------------------------------------
  2. * Copyright (c). See file: LICENSE
  3. * ---------------------------------------------------------------------------*/
  4. using System;
  5. using System.Collections.Concurrent;
  6. using System.Collections.Generic;
  7. using System.IO;
  8. using System.Security.AccessControl;
  9. using System.Text.RegularExpressions;
  10. using System.Threading;
  11. using DokanNet;
  12. using JadeSoftware.Joob.Client;
  13. using JadeSoftware.Joob.MetaSchema;
  14. namespace JadeFileSystem
  15. {
  16. public class JadeFS : DokanNet.IDokanOperations
  17. {
  18. private ThreadLocal<JoobContext> context = new ThreadLocal<JoobContext>(() =>
  19. {
  20. JoobConnection conn = new JoobConnection();
  21. conn.Open();
  22. JoobContext ctx = new JoobContext(conn);
  23. return ctx;
  24. }, true);
  25. private ConcurrentDictionary<string, Schema> schemasByName = new ConcurrentDictionary<string, Schema>();
  26. private ConcurrentDictionary<string, Class> classesByName = new ConcurrentDictionary<string, Class>();
  27. private static IEnumerable<View> YieldAllViews()
  28. {
  29. yield return new AllSchemasView();
  30. yield return new SchemaView();
  31. yield return new TypeView();
  32. yield return new ClassMethodsView();
  33. yield return new MethodView();
  34. yield return new DesktopIniView();
  35. }
  36. private static IEnumerable<KeyValuePair<string, View>> YieldAllViewsByPattern()
  37. {
  38. foreach(View view in YieldAllViews())
  39. yield return new KeyValuePair<string, View>(view.Pattern, view);
  40. }
  41. private ConcurrentBag<View> views = new ConcurrentBag<View>(YieldAllViews());
  42. public static string GetMountPoint()
  43. {
  44. return "C:\\JadeFS\\mount-point\\";
  45. }
  46. public void Cleanup(string fileName, DokanFileInfo info)
  47. {
  48. }
  49. public void CloseFile(string fileName, DokanFileInfo info)
  50. {
  51. try
  52. {
  53. JoobContext ctx = this.context.Value;
  54. foreach (View view in this.views)
  55. {
  56. Match match = Regex.Match(fileName, view.Pattern);
  57. if (match.Success)
  58. {
  59. view.CloseFile(ctx, fileName, info, match);
  60. return;
  61. }
  62. }
  63. }
  64. catch (Exception ex)
  65. {
  66. Console.WriteLine("Error " + ex.ToString());
  67. }
  68. }
  69. public NtStatus CreateFile(string fileName, DokanNet.FileAccess access, FileShare share, FileMode mode, FileOptions options, FileAttributes attributes, DokanFileInfo info)
  70. {
  71. try
  72. {
  73. //Console.WriteLine("CreateFile called on " + fileName + " mode = " + mode.ToString() + " options = " + options.ToString());
  74. JoobContext ctx = this.context.Value;
  75. foreach(View view in this.views)
  76. {
  77. Match match = Regex.Match(fileName, view.Pattern);
  78. if (match.Success)
  79. {
  80. //Console.WriteLine("CreateFile called on " + view.ToString() + " for file " + fileName);
  81. return view.CreateFile(ctx, fileName, access, share, mode, options, attributes, info, match);
  82. }
  83. }
  84. Console.WriteLine("unhandled pattern within CreateFile. fileName = " + fileName);
  85. return NtStatus.ObjectNameNotFound;
  86. }
  87. catch (Exception ex)
  88. {
  89. Console.WriteLine("Error " + ex.ToString());
  90. return NtStatus.Error;
  91. }
  92. }
  93. public NtStatus DeleteDirectory(string fileName, DokanFileInfo info)
  94. {
  95. Console.WriteLine("DeleteDirectory called on " + fileName);
  96. return NtStatus.NotImplemented;
  97. }
  98. public NtStatus DeleteFile(string fileName, DokanFileInfo info)
  99. {
  100. try
  101. {
  102. Console.WriteLine("DeleteFile called on " + fileName);
  103. JoobContext ctx = this.context.Value;
  104. foreach (View view in this.views)
  105. {
  106. Match match = Regex.Match(fileName, view.Pattern);
  107. if (match.Success)
  108. return view.DeleteFile(ctx, fileName, info, match);
  109. }
  110. return NtStatus.Error;
  111. }
  112. catch (Exception ex)
  113. {
  114. Console.WriteLine("Error " + ex.ToString());
  115. return NtStatus.Error;
  116. }
  117. }
  118. public NtStatus FindFiles(string fileName, out IList<FileInformation> files, DokanFileInfo info)
  119. {
  120. try
  121. {
  122. JoobContext ctx = this.context.Value;
  123. foreach (View view in this.views)
  124. {
  125. Match match = Regex.Match(fileName, view.Pattern);
  126. if (match.Success)
  127. return view.FindFiles(ctx, fileName, out files, info, match);
  128. }
  129. Console.WriteLine("unhandled pattern within FindFiles. fileName = " + fileName);
  130. files = null;
  131. return NtStatus.ObjectNameNotFound;
  132. }
  133. catch (Exception ex)
  134. {
  135. Console.WriteLine("Error " + ex.ToString());
  136. files = null;
  137. return NtStatus.Error;
  138. }
  139. }
  140. public NtStatus FindStreams(string fileName, out IList<FileInformation> streams, DokanFileInfo info)
  141. {
  142. //Console.WriteLine("FindStreams " + fileName);
  143. streams = null;
  144. return NtStatus.NotImplemented;
  145. }
  146. public NtStatus FlushFileBuffers(string fileName, DokanFileInfo info)
  147. {
  148. Console.WriteLine("FlushFileBuffers " + fileName);
  149. return NtStatus.NotImplemented;
  150. }
  151. public NtStatus GetDiskFreeSpace(out long freeBytesAvailable, out long totalNumberOfBytes, out long totalNumberOfFreeBytes, DokanFileInfo info)
  152. {
  153. Console.WriteLine("GetDiskFreeSpace ");
  154. freeBytesAvailable = 100;
  155. totalNumberOfBytes = 200;
  156. totalNumberOfFreeBytes = 100;
  157. return NtStatus.Success;
  158. }
  159. public NtStatus GetFileInformation(string fileName, out FileInformation fileInfo, DokanFileInfo info)
  160. {
  161. //Console.WriteLine("GetFileInformation " + fileName);
  162. try
  163. {
  164. JoobContext ctx = this.context.Value;
  165. foreach (View view in this.views)
  166. {
  167. Match match = Regex.Match(fileName, view.Pattern);
  168. if (match.Success)
  169. return view.GetFileInformation(ctx, fileName, out fileInfo, info, match);
  170. }
  171. Console.WriteLine("unhandled pattern within GetFileInformation. fileName = " + fileName);
  172. fileInfo = new FileInformation();
  173. fileInfo.FileName = fileName;
  174. return NtStatus.ObjectNameNotFound;
  175. }
  176. catch (Exception ex)
  177. {
  178. Console.WriteLine("GetFileInformation error on file " + fileName + " " + ex.ToString());
  179. fileInfo = new FileInformation();
  180. fileInfo.FileName = fileName;
  181. return NtStatus.Error;
  182. }
  183. }
  184. public NtStatus GetFileSecurity(string fileName, out FileSystemSecurity security, AccessControlSections sections, DokanFileInfo info)
  185. {
  186. try
  187. {
  188. //Console.WriteLine("GetFileSecurity called on " + fileName);
  189. JoobContext ctx = this.context.Value;
  190. foreach (View view in this.views)
  191. {
  192. Match match = Regex.Match(fileName, view.Pattern);
  193. if (match.Success)
  194. return view.GetFileSecurity(ctx, fileName, out security, sections, info, match);
  195. }
  196. Console.WriteLine("unhandled pattern within GetFileSecurity. fileName = " + fileName);
  197. security = null;
  198. return NtStatus.ObjectNameNotFound;
  199. }
  200. catch (Exception ex)
  201. {
  202. Console.WriteLine("GetFileSecurity error on file " + fileName + " " + ex.ToString());
  203. security = null;
  204. return NtStatus.Error;
  205. }
  206. }
  207. public NtStatus GetVolumeInformation(out string volumeLabel, out FileSystemFeatures features, out string fileSystemName, DokanFileInfo info)
  208. {
  209. Console.WriteLine("GetVolumeInformation");
  210. volumeLabel = "JadeFS";
  211. features = FileSystemFeatures.CasePreservedNames | FileSystemFeatures.CaseSensitiveSearch;
  212. fileSystemName = "JadeFS";
  213. return NtStatus.Success;
  214. }
  215. public NtStatus LockFile(string fileName, long offset, long length, DokanFileInfo info)
  216. {
  217. Console.WriteLine("LockFile called on " + fileName);
  218. return NtStatus.NotImplemented;
  219. }
  220. public NtStatus Mounted(DokanFileInfo info)
  221. {
  222. return NtStatus.NotImplemented;
  223. }
  224. public NtStatus MoveFile(string oldName, string newName, bool replace, DokanFileInfo info)
  225. {
  226. Console.WriteLine("MoveFile called on " + oldName);
  227. return NtStatus.NotImplemented;
  228. }
  229. public NtStatus ReadFile(string fileName, byte[] buffer, out int bytesRead, long offset, DokanFileInfo info)
  230. {
  231. try
  232. {
  233. Console.WriteLine("ReadFile called on " + fileName + " offset = " + offset.ToString());
  234. JoobContext ctx = this.context.Value;
  235. foreach (View view in this.views)
  236. {
  237. Match match = Regex.Match(fileName, view.Pattern);
  238. if (match.Success)
  239. return view.ReadFile(ctx, fileName, buffer, out bytesRead, offset, info, match);
  240. }
  241. Console.WriteLine("unhandled pattern within ReadFile. fileName = " + fileName);
  242. bytesRead = 0;
  243. return NtStatus.ObjectNameNotFound;
  244. }
  245. catch (Exception ex)
  246. {
  247. Console.WriteLine("ReadFile error on file " + fileName + " " + ex.ToString());
  248. bytesRead = 0;
  249. return NtStatus.Error;
  250. }
  251. }
  252. public NtStatus SetAllocationSize(string fileName, long length, DokanFileInfo info)
  253. {
  254. Console.WriteLine("SetAllocationSize called on " + fileName);
  255. return NtStatus.NotImplemented;
  256. }
  257. public NtStatus SetEndOfFile(string fileName, long length, DokanFileInfo info)
  258. {
  259. Console.WriteLine("SetEndOfFile called on " + fileName);
  260. return NtStatus.NotImplemented;
  261. }
  262. public NtStatus SetFileAttributes(string fileName, FileAttributes attributes, DokanFileInfo info)
  263. {
  264. Console.WriteLine("SetFileAttributes called on " + fileName);
  265. return NtStatus.NotImplemented;
  266. }
  267. public NtStatus SetFileSecurity(string fileName, FileSystemSecurity security, AccessControlSections sections, DokanFileInfo info)
  268. {
  269. Console.WriteLine("SetFileSecurity called on " + fileName);
  270. return NtStatus.NotImplemented;
  271. }
  272. public NtStatus SetFileTime(string fileName, DateTime? creationTime, DateTime? lastAccessTime, DateTime? lastWriteTime, DokanFileInfo info)
  273. {
  274. Console.WriteLine("SetFileTime called on " + fileName);
  275. return NtStatus.NotImplemented;
  276. }
  277. public NtStatus UnlockFile(string fileName, long offset, long length, DokanFileInfo info)
  278. {
  279. Console.WriteLine("UnlockFile called on " + fileName);
  280. return NtStatus.NotImplemented;
  281. }
  282. public NtStatus Unmounted(DokanFileInfo info)
  283. {
  284. foreach(JoobContext ctx in this.context.Values)
  285. {
  286. JoobConnection conn = ctx.Connection;
  287. ctx.Dispose();
  288. conn.Dispose();
  289. }
  290. return NtStatus.Success;
  291. }
  292. public NtStatus WriteFile(string fileName, byte[] buffer, out int bytesWritten, long offset, DokanFileInfo info)
  293. {
  294. try
  295. {
  296. Console.WriteLine("WriteFile called on " + fileName);
  297. JoobContext ctx = this.context.Value;
  298. foreach (View view in this.views)
  299. {
  300. Match match = Regex.Match(fileName, view.Pattern);
  301. if (match.Success)
  302. return view.WriteFile(ctx, fileName, buffer, out bytesWritten, offset, info, match);
  303. }
  304. bytesWritten = 0;
  305. return NtStatus.ObjectNameInvalid;
  306. }
  307. catch (Exception ex)
  308. {
  309. Console.WriteLine("error within WriteFile on fileName = " + fileName + " " + ex.ToString());
  310. bytesWritten = 0;
  311. return NtStatus.Error;
  312. }
  313. }
  314. }
  315. }