Advertisement
Guest User

Untitled

a guest
May 30th, 2016
142
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 20.67 KB | None | 0 0
  1. using DokanNet;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Globalization;
  5. using System.IO;
  6. using System.Linq;
  7. using System.Runtime.InteropServices;
  8. using System.Security.AccessControl;
  9. using FileAccess = DokanNet.FileAccess;
  10.  
  11. namespace Kursach
  12. {
  13. internal class Thome : IDokanOperations
  14. {
  15. private readonly string path;
  16.  
  17. private const FileAccess DataAccess = FileAccess.ReadData | FileAccess.WriteData | FileAccess.AppendData |
  18. FileAccess.Execute |
  19. FileAccess.GenericExecute | FileAccess.GenericWrite | FileAccess.GenericRead;
  20.  
  21. private const FileAccess DataWriteAccess = FileAccess.WriteData | FileAccess.AppendData |
  22. FileAccess.Delete |
  23. FileAccess.GenericWrite;
  24. /*
  25. public Thome(string path)
  26. {
  27. this.path = path;
  28. }*/
  29.  
  30. public Thome(string path)
  31. {
  32. if (!Directory.Exists(path))
  33. throw new ArgumentException("path");
  34. this.path = path;
  35. }
  36.  
  37. private string GetPath(string fileName)
  38. {
  39. return path + fileName;
  40. }
  41.  
  42. private string ToTrace(DokanFileInfo info)
  43. {
  44. var context = info.Context != null ? "<" + info.Context.GetType().Name + ">" : "<null>";
  45.  
  46. return string.Format(CultureInfo.InvariantCulture, "{{{0}, {1}, {2}, {3}, {4}, #{5}, {6}, {7}}}",
  47. context, info.DeleteOnClose, info.IsDirectory, info.NoCache, info.PagingIo, info.ProcessId, info.SynchronousIo, info.WriteToEndOfFile);
  48. }
  49.  
  50. private string ToTrace(DateTime? date)
  51. {
  52. return date.HasValue ? date.Value.ToString(CultureInfo.CurrentCulture) : "<null>";
  53. }
  54.  
  55. private NtStatus Trace(string method, string fileName, DokanFileInfo info, NtStatus result, params string[] parameters)
  56. {
  57. var extraParameters = parameters != null && parameters.Length > 0 ? ", " + string.Join(", ", parameters) : string.Empty;
  58.  
  59. return result;
  60. }
  61.  
  62. private NtStatus Trace(string method, string fileName, DokanFileInfo info,
  63. FileAccess access, FileShare share, FileMode mode, FileOptions options, FileAttributes attributes,
  64. NtStatus result)
  65. {
  66.  
  67. return result;
  68. }
  69.  
  70. #region Implementation of IDokanOperations
  71.  
  72. public NtStatus CreateFile(string fileName, FileAccess access, FileShare share, FileMode mode, FileOptions options, FileAttributes attributes,
  73. DokanFileInfo info)
  74. {
  75.  
  76.  
  77. var path = GetPath(fileName);
  78.  
  79. if (info.IsDirectory)
  80. {
  81. try
  82. {
  83. switch (mode)
  84. {
  85. case FileMode.Open:
  86. if (!Directory.Exists(path))
  87. {
  88. try
  89. {
  90. if (!File.GetAttributes(path).HasFlag(FileAttributes.Directory))
  91. return Trace("CreateFile", fileName, info, access, share, mode, options, attributes, NtStatus.Abandoned);
  92. }
  93. catch (Exception)
  94. {
  95. return Trace("CreateFile", fileName, info, access, share, mode, options, attributes, DokanResult.FileNotFound);
  96. }
  97. return Trace("CreateFile", fileName, info, access, share, mode, options, attributes, DokanResult.PathNotFound);
  98. }
  99.  
  100. new DirectoryInfo(path).EnumerateFileSystemInfos().Any(); // you can't list the directory
  101. break;
  102.  
  103. case FileMode.CreateNew:
  104. if (Directory.Exists(path))
  105. return Trace("CreateFile", fileName, info, access, share, mode, options, attributes, DokanResult.FileExists);
  106.  
  107. try
  108. {
  109. File.GetAttributes(path).HasFlag(FileAttributes.Directory);
  110. return Trace("CreateFile", fileName, info, access, share, mode, options, attributes, DokanResult.AlreadyExists);
  111. }
  112. catch (IOException) { }
  113.  
  114. Directory.CreateDirectory(GetPath(fileName));
  115. break;
  116. }
  117. }
  118. catch (UnauthorizedAccessException)
  119. {
  120. return Trace("CreateFile", fileName, info, access, share, mode, options, attributes, DokanResult.AccessDenied);
  121. }
  122. }
  123. else
  124. {
  125. bool pathExists = true;
  126. bool pathIsDirectory = false;
  127.  
  128. bool readWriteAttributes = (access & DataAccess) == 0;
  129. bool readAccess = (access & DataWriteAccess) == 0;
  130.  
  131. try
  132. {
  133. pathExists = (Directory.Exists(path) || File.Exists(path));
  134. pathIsDirectory = File.GetAttributes(path).HasFlag(FileAttributes.Directory);
  135. }
  136. catch (IOException) { }
  137.  
  138. switch (mode)
  139. {
  140. case FileMode.Open:
  141.  
  142. if (pathExists)
  143. {
  144. if (readWriteAttributes || pathIsDirectory)
  145. // check if driver only wants to read attributes, security info, or open directory
  146. {
  147. if (pathIsDirectory && (access & FileAccess.Delete) == FileAccess.Delete
  148. && (access & FileAccess.Synchronize) != FileAccess.Synchronize) //It is a DeleteFile request on a directory
  149. return Trace("CreateFile", fileName, info, access, share, mode, options, attributes, DokanResult.AccessDenied);
  150.  
  151. info.IsDirectory = pathIsDirectory;
  152. info.Context = new object();
  153. // must set it to someting if you return DokanError.Success
  154.  
  155. return Trace("CreateFile", fileName, info, access, share, mode, options, attributes, DokanResult.Success);
  156. }
  157. }
  158. else
  159. {
  160. return Trace("CreateFile", fileName, info, access, share, mode, options, attributes, DokanResult.FileNotFound);
  161. }
  162. break;
  163.  
  164. case FileMode.CreateNew:
  165. if (pathExists)
  166. return Trace("CreateFile", fileName, info, access, share, mode, options, attributes, DokanResult.FileExists);
  167. break;
  168.  
  169. case FileMode.Truncate:
  170. if (!pathExists)
  171. return Trace("CreateFile", fileName, info, access, share, mode, options, attributes, DokanResult.FileNotFound);
  172. break;
  173.  
  174. default:
  175. break;
  176. }
  177.  
  178. try
  179. {
  180. info.Context = new FileStream(path, mode, readAccess ? System.IO.FileAccess.Read : System.IO.FileAccess.ReadWrite, share, 4096, options);
  181.  
  182. if (mode == FileMode.CreateNew
  183. || mode == FileMode.Create) //Files are always created as Archive
  184. attributes |= FileAttributes.Archive;
  185. File.SetAttributes(path, attributes);
  186. }
  187. catch (UnauthorizedAccessException) // don't have access rights
  188. {
  189. return Trace("CreateFile", fileName, info, access, share, mode, options, attributes, DokanResult.AccessDenied);
  190. }
  191. catch (DirectoryNotFoundException)
  192. {
  193. return Trace("CreateFile", fileName, info, access, share, mode, options, attributes, DokanResult.PathNotFound);
  194. }
  195. catch (Exception ex)
  196. {
  197. uint hr = (uint)Marshal.GetHRForException(ex);
  198. switch (hr)
  199. {
  200. case 0x80070020: //Sharing violation
  201. return Trace("CreateFile", fileName, info, access, share, mode, options, attributes, DokanResult.SharingViolation);
  202. default:
  203. throw ex;
  204. }
  205. }
  206. }
  207. return Trace("CreateFile", fileName, info, access, share, mode, options, attributes, DokanResult.Success);
  208.  
  209. }
  210.  
  211. public void Cleanup(string fileName, DokanFileInfo info)
  212. {
  213. #if TRACE
  214. if (info.Context != null)
  215. Console.WriteLine(string.Format(CultureInfo.CurrentCulture, "{0}('{1}', {2} - entering",
  216. "Cleanup", fileName, ToTrace(info)));
  217. #endif
  218.  
  219. if (info.Context != null && info.Context is FileStream)
  220. {
  221. (info.Context as FileStream).Dispose();
  222. }
  223. info.Context = null;
  224.  
  225. if (info.DeleteOnClose)
  226. {
  227. if (info.IsDirectory)
  228. {
  229. Directory.Delete(GetPath(fileName));
  230. }
  231. else
  232. {
  233. File.Delete(GetPath(fileName));
  234. }
  235. }
  236. Trace("Cleanup", fileName, info, DokanResult.Success);
  237. }
  238.  
  239. public void CloseFile(string fileName, DokanFileInfo info)
  240. {
  241. #if TRACE
  242. if (info.Context != null)
  243. Console.WriteLine(string.Format(CultureInfo.CurrentCulture, "{0}('{1}', {2} - entering",
  244. "CloseFile", fileName, ToTrace(info)));
  245. #endif
  246.  
  247. if (info.Context != null && info.Context is FileStream)
  248. {
  249. (info.Context as FileStream).Dispose();
  250. }
  251. info.Context = null;
  252. Trace("CloseFile", fileName, info, DokanResult.Success); // could recreate cleanup code here but this is not called sometimes
  253. }
  254.  
  255. public NtStatus ReadFile(string fileName, byte[] buffer, out int bytesRead, long offset, DokanFileInfo info)
  256. {
  257. if (info.Context == null) // memory mapped read
  258. {
  259. using (var stream = new FileStream(GetPath(fileName), FileMode.Open, System.IO.FileAccess.Read))
  260. {
  261. stream.Position = offset;
  262. bytesRead = stream.Read(buffer, 0, buffer.Length);
  263. }
  264. }
  265. else // normal read
  266. {
  267. var stream = info.Context as FileStream;
  268. lock (stream) //Protect from overlapped read
  269. {
  270. stream.Position = offset;
  271. bytesRead = stream.Read(buffer, 0, buffer.Length);
  272. }
  273. }
  274. return Trace("ReadFile", fileName, info, DokanResult.Success, "out " + bytesRead.ToString(), offset.ToString(CultureInfo.InvariantCulture));
  275. }
  276.  
  277. public NtStatus WriteFile(string fileName, byte[] buffer, out int bytesWritten, long offset, DokanFileInfo info)
  278. {
  279. if (info.Context == null)
  280. {
  281. using (var stream = new FileStream(GetPath(fileName), FileMode.Open, System.IO.FileAccess.Write))
  282. {
  283. stream.Position = offset;
  284. stream.Write(buffer, 0, buffer.Length);
  285. bytesWritten = buffer.Length;
  286. }
  287. }
  288. else
  289. {
  290. var stream = info.Context as FileStream;
  291. lock (stream) //Protect from overlapped write
  292. {
  293. stream.Position = offset;
  294. stream.Write(buffer, 0, buffer.Length);
  295. }
  296. bytesWritten = buffer.Length;
  297. }
  298. return Trace("WriteFile", fileName, info, DokanResult.Success, "out " + bytesWritten.ToString(), offset.ToString(CultureInfo.InvariantCulture));
  299. }
  300.  
  301. public NtStatus FlushFileBuffers(string fileName, DokanFileInfo info)
  302. {
  303. try
  304. {
  305. ((FileStream)(info.Context)).Flush();
  306. return Trace("FlushFileBuffers", fileName, info, DokanResult.Success);
  307. }
  308. catch (IOException)
  309. {
  310. return Trace("FlushFileBuffers", fileName, info, DokanResult.DiskFull);
  311. }
  312. }
  313.  
  314. public NtStatus GetFileInformation(string fileName, out FileInformation fileInfo, DokanFileInfo info)
  315. {
  316. // may be called with info.Context == null, but usually it isn't
  317. string path = GetPath(fileName);
  318. FileSystemInfo finfo = new FileInfo(path);
  319. if (!finfo.Exists)
  320. finfo = new DirectoryInfo(path);
  321.  
  322. fileInfo = new FileInformation
  323. {
  324. FileName = fileName,
  325. Attributes = finfo.Attributes,
  326. CreationTime = finfo.CreationTime,
  327. LastAccessTime = finfo.LastAccessTime,
  328. LastWriteTime = finfo.LastWriteTime,
  329. Length = (finfo is FileInfo) ? ((FileInfo)finfo).Length : 0,
  330. };
  331. return Trace("GetFileInformation", fileName, info, DokanResult.Success);
  332. }
  333.  
  334. public NtStatus FindFiles(string fileName, out IList<FileInformation> files, DokanFileInfo info)
  335. {
  336. //This fonction is not called because FindFilesWithPattern is implemented
  337. // Return DokanResult.NotImplemented in FindFilesWithPattern to make FindFiles called
  338. files = files = FindFilesHelper(fileName, "*");
  339.  
  340. return Trace("FindFiles", fileName, info, DokanResult.Success);
  341. }
  342.  
  343. public NtStatus SetFileAttributes(string fileName, FileAttributes attributes, DokanFileInfo info)
  344. {
  345. try
  346. {
  347. File.SetAttributes(GetPath(fileName), attributes);
  348. return Trace("SetFileAttributes", fileName, info, DokanResult.Success, attributes.ToString());
  349. }
  350. catch (UnauthorizedAccessException)
  351. {
  352. return Trace("SetFileAttributes", fileName, info, DokanResult.AccessDenied, attributes.ToString());
  353. }
  354. catch (FileNotFoundException)
  355. {
  356. return Trace("SetFileAttributes", fileName, info, DokanResult.FileNotFound, attributes.ToString());
  357. }
  358. catch (DirectoryNotFoundException)
  359. {
  360. return Trace("SetFileAttributes", fileName, info, DokanResult.PathNotFound, attributes.ToString());
  361. }
  362. }
  363.  
  364. public NtStatus SetFileTime(string fileName, DateTime? creationTime, DateTime? lastAccessTime, DateTime? lastWriteTime, DokanFileInfo info)
  365. {
  366. try
  367. {
  368. string path = GetPath(fileName);
  369. if (creationTime.HasValue)
  370. File.SetCreationTime(path, creationTime.Value);
  371.  
  372. if (lastAccessTime.HasValue)
  373. File.SetLastAccessTime(path, lastAccessTime.Value);
  374.  
  375. if (lastWriteTime.HasValue)
  376. File.SetLastWriteTime(path, lastWriteTime.Value);
  377.  
  378. return Trace("SetFileTime", fileName, info, DokanResult.Success, ToTrace(creationTime), ToTrace(lastAccessTime), ToTrace(lastWriteTime));
  379. }
  380. catch (UnauthorizedAccessException)
  381. {
  382. return Trace("SetFileTime", fileName, info, DokanResult.AccessDenied, ToTrace(creationTime), ToTrace(lastAccessTime), ToTrace(lastWriteTime));
  383. }
  384. catch (FileNotFoundException)
  385. {
  386. return Trace("SetFileTime", fileName, info, DokanResult.FileNotFound, ToTrace(creationTime), ToTrace(lastAccessTime), ToTrace(lastWriteTime));
  387. }
  388. }
  389.  
  390. public NtStatus DeleteFile(string fileName, DokanFileInfo info)
  391. {
  392. var path = GetPath(fileName);
  393.  
  394. if (!File.Exists(path))
  395. return Trace("DeleteFile", fileName, info, DokanResult.FileNotFound);
  396.  
  397. if (File.GetAttributes(path).HasFlag(FileAttributes.Directory))
  398. return Trace("DeleteFile", fileName, info, DokanResult.AccessDenied);
  399.  
  400. return Trace("DeleteFile", fileName, info, DokanResult.Success);
  401. // we just check here if we could delete the file - the true deletion is in Cleanup
  402. }
  403.  
  404. public NtStatus DeleteDirectory(string fileName, DokanFileInfo info)
  405. {
  406. return Trace("DeleteDirectory", fileName, info, Directory.EnumerateFileSystemEntries(GetPath(fileName)).Any() ? DokanResult.DirectoryNotEmpty : DokanResult.Success);
  407. // if dir is not empty it can't be deleted
  408. }
  409.  
  410. public NtStatus MoveFile(string oldName, string newName, bool replace, DokanFileInfo info)
  411. {
  412. string oldpath = GetPath(oldName);
  413. string newpath = GetPath(newName);
  414.  
  415. if (info.Context != null && info.Context is FileStream)
  416. {
  417. (info.Context as FileStream).Dispose();
  418. }
  419. info.Context = null;
  420.  
  421. bool exist = false;
  422. if (info.IsDirectory)
  423. exist = Directory.Exists(newpath);
  424. else
  425. exist = File.Exists(newpath);
  426.  
  427. if (!exist)
  428. {
  429. info.Context = null;
  430. if (info.IsDirectory)
  431. Directory.Move(oldpath, newpath);
  432. else
  433. File.Move(oldpath, newpath);
  434. return Trace("MoveFile", oldName, info, DokanResult.Success, newName, replace.ToString(CultureInfo.InvariantCulture));
  435. }
  436. else if (replace)
  437. {
  438. info.Context = null;
  439.  
  440. if (info.IsDirectory) //Cannot replace directory destination - See MOVEFILE_REPLACE_EXISTING
  441. return Trace("MoveFile", oldName, info, DokanResult.AccessDenied, newName, replace.ToString(CultureInfo.InvariantCulture));
  442.  
  443. File.Delete(newpath);
  444. File.Move(oldpath, newpath);
  445. return Trace("MoveFile", oldName, info, DokanResult.Success, newName, replace.ToString(CultureInfo.InvariantCulture));
  446. }
  447. return Trace("MoveFile", oldName, info, DokanResult.FileExists, newName, replace.ToString(CultureInfo.InvariantCulture));
  448. }
  449.  
  450. public NtStatus SetEndOfFile(string fileName, long length, DokanFileInfo info)
  451. {
  452. try
  453. {
  454. ((FileStream)(info.Context)).SetLength(length);
  455. return Trace("SetEndOfFile", fileName, info, DokanResult.Success, length.ToString(CultureInfo.InvariantCulture));
  456. }
  457. catch (IOException)
  458. {
  459. return Trace("SetEndOfFile", fileName, info, DokanResult.DiskFull, length.ToString(CultureInfo.InvariantCulture));
  460. }
  461. }
  462.  
  463. public NtStatus SetAllocationSize(string fileName, long length, DokanFileInfo info)
  464. {
  465. try
  466. {
  467. ((FileStream)(info.Context)).SetLength(length);
  468. return Trace("SetAllocationSize", fileName, info, DokanResult.Success, length.ToString(CultureInfo.InvariantCulture));
  469. }
  470. catch (IOException)
  471. {
  472. return Trace("SetAllocationSize", fileName, info, DokanResult.DiskFull, length.ToString(CultureInfo.InvariantCulture));
  473. }
  474. }
  475.  
  476. public NtStatus LockFile(string fileName, long offset, long length, DokanFileInfo info)
  477. {
  478. try
  479. {
  480. ((FileStream)(info.Context)).Lock(offset, length);
  481. return Trace("LockFile", fileName, info, DokanResult.Success, offset.ToString(CultureInfo.InvariantCulture), length.ToString(CultureInfo.InvariantCulture));
  482. }
  483. catch (IOException)
  484. {
  485. return Trace("LockFile", fileName, info, DokanResult.AccessDenied, offset.ToString(CultureInfo.InvariantCulture), length.ToString(CultureInfo.InvariantCulture));
  486. }
  487. }
  488.  
  489. public NtStatus UnlockFile(string fileName, long offset, long length, DokanFileInfo info)
  490. {
  491. try
  492. {
  493. ((FileStream)(info.Context)).Unlock(offset, length);
  494. return Trace("UnlockFile", fileName, info, DokanResult.Success, offset.ToString(CultureInfo.InvariantCulture), length.ToString(CultureInfo.InvariantCulture));
  495. }
  496. catch (IOException)
  497. {
  498. return Trace("UnlockFile", fileName, info, DokanResult.AccessDenied, offset.ToString(CultureInfo.InvariantCulture), length.ToString(CultureInfo.InvariantCulture));
  499. }
  500. }
  501.  
  502. public NtStatus GetDiskFreeSpace(out long free, out long total, out long used, DokanFileInfo info)
  503. {
  504. var dinfo = DriveInfo.GetDrives().Where(di => di.RootDirectory.Name == Path.GetPathRoot(path + "\\")).Single();
  505.  
  506. used = dinfo.AvailableFreeSpace;
  507. total = dinfo.TotalSize;
  508. free = dinfo.TotalFreeSpace;
  509. return Trace("GetDiskFreeSpace", null, info, DokanResult.Success, "out " + free.ToString(), "out " + total.ToString(), "out " + used.ToString());
  510. }
  511.  
  512. public NtStatus GetVolumeInformation(out string volumeLabel, out FileSystemFeatures features,
  513. out string fileSystemName, DokanFileInfo info)
  514. {
  515. volumeLabel = "DOKAN";
  516. fileSystemName = "NTFS";
  517.  
  518. features = FileSystemFeatures.CasePreservedNames | FileSystemFeatures.CaseSensitiveSearch |
  519. FileSystemFeatures.PersistentAcls | FileSystemFeatures.SupportsRemoteStorage |
  520. FileSystemFeatures.UnicodeOnDisk;
  521.  
  522. return Trace("GetVolumeInformation", null, info, DokanResult.Success, "out " + volumeLabel, "out " + features.ToString(), "out " + fileSystemName);
  523. }
  524.  
  525. public NtStatus GetFileSecurity(string fileName, out FileSystemSecurity security, AccessControlSections sections, DokanFileInfo info)
  526. {
  527. try
  528. {
  529. security = info.IsDirectory
  530. ? (FileSystemSecurity)Directory.GetAccessControl(GetPath(fileName))
  531. : File.GetAccessControl(GetPath(fileName));
  532. return Trace("GetFileSecurity", fileName, info, DokanResult.Success, sections.ToString());
  533. }
  534. catch (UnauthorizedAccessException)
  535. {
  536. security = null;
  537. return Trace("GetFileSecurity", fileName, info, DokanResult.AccessDenied, sections.ToString());
  538. }
  539. }
  540.  
  541. public NtStatus SetFileSecurity(string fileName, FileSystemSecurity security, AccessControlSections sections, DokanFileInfo info)
  542. {
  543. try
  544. {
  545. if (info.IsDirectory)
  546. {
  547. Directory.SetAccessControl(GetPath(fileName), (DirectorySecurity)security);
  548. }
  549. else
  550. {
  551. File.SetAccessControl(GetPath(fileName), (FileSecurity)security);
  552. }
  553. return Trace("SetFileSecurity", fileName, info, DokanResult.Success, sections.ToString());
  554. }
  555. catch (UnauthorizedAccessException)
  556. {
  557. return Trace("SetFileSecurity", fileName, info, DokanResult.AccessDenied, sections.ToString());
  558. }
  559. }
  560.  
  561. public NtStatus Mounted(DokanFileInfo info)
  562. {
  563. return Trace("Mount", null, info, DokanResult.Success);
  564. }
  565.  
  566. public NtStatus Unmounted(DokanFileInfo info)
  567. {
  568. return Trace("Unmount", null, info, DokanResult.Success);
  569. }
  570.  
  571. public NtStatus FindStreams(string fileName, IntPtr enumContext, out string streamName, out long streamSize, DokanFileInfo info)
  572. {
  573. streamName = String.Empty;
  574. streamSize = 0;
  575. return Trace("EnumerateNamedStreams", fileName, info, DokanResult.NotImplemented, enumContext.ToString(), "out " + streamName, "out " + streamSize.ToString());
  576. }
  577.  
  578. public NtStatus FindStreams(string fileName, out IList<FileInformation> streams, DokanFileInfo info)
  579. {
  580. streams = new FileInformation[0];
  581. return Trace("EnumerateNamedStreams", fileName, info, DokanResult.NotImplemented);
  582. }
  583.  
  584. public IList<FileInformation> FindFilesHelper(string fileName, string searchPattern)
  585. {
  586. IList<FileInformation> files = new DirectoryInfo(GetPath(fileName))
  587. .GetFileSystemInfos(searchPattern)
  588. .Select(finfo => new FileInformation
  589. {
  590. Attributes = finfo.Attributes,
  591. CreationTime = finfo.CreationTime,
  592. LastAccessTime = finfo.LastAccessTime,
  593. LastWriteTime = finfo.LastWriteTime,
  594. Length = (finfo is FileInfo) ? ((FileInfo)finfo).Length : 0,
  595. FileName = finfo.Name
  596. }).ToArray();
  597.  
  598. return files;
  599. }
  600.  
  601. public NtStatus FindFilesWithPattern(string fileName, string searchPattern, out IList<FileInformation> files, DokanFileInfo info)
  602. {
  603. files = FindFilesHelper(fileName, searchPattern);
  604.  
  605. return Trace("FindFilesWithPattern", fileName, info, DokanResult.Success);
  606. }
  607.  
  608. #endregion Implementation of IDokanOperations
  609. }
  610. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement