public NtStatus DeleteDirectory(string fileName, DokanFileInfo info) { LayeredDirectoryContext context = info.Context as LayeredDirectoryContext; if (!context.IsWritable) { return(DokanResult.AccessDenied); } else { IList <FileInformation> list; FindFiles(fileName, out list, info); if (list.Count > 0) { return(DokanResult.DirectoryNotEmpty); } return(DokanResult.Success); } }
public NtStatus FindFilesWithPattern(string fileName, string searchPattern, out IList <FileInformation> files, DokanFileInfo info) { if (null != searchPattern) { searchPattern = searchPattern.Replace('<', '*').Replace('>', '?').Replace('"', '.'); } else { searchPattern = "*"; } LayeredDirectoryContext context = info.Context as LayeredDirectoryContext; SortedList <string, FileSystemInfo> list = new SortedList <string, FileSystemInfo>(); if (context.WriteDirInfo != null) { IEnumerable e = context.WriteDirInfo.EnumerateFileSystemInfos(searchPattern); foreach (FileSystemInfo fsi in e) { list.Add(fsi.Name, fsi); } } if (context.ReadOnlyDirInfo != null) { IEnumerable e = context.ReadOnlyDirInfo.EnumerateFileSystemInfos(searchPattern); foreach (FileSystemInfo fsi in e) { if (!list.ContainsKey(fsi.Name)) { list.Add(fsi.Name, fsi); } } } files = list.Values.Select(fsinfo => Utils.CreateFileInformation(fsinfo)).ToArray(); return(DokanResult.Success); }
public NtStatus UnsafeCreateFile(string fileName, DokanNet.FileAccess access, FileShare share, FileMode mode, FileOptions options, FileAttributes attributes, DokanFileInfo info) { string writePath = GetWritePath(fileName); string readOnlyPath = GetReadOnlyPath(fileName); if (info.IsDirectory) { if (mode == FileMode.CreateNew) { if (Directory.Exists(writePath)) { return(DokanResult.FileExists); } else if (File.Exists(writePath)) { return(DokanResult.AlreadyExists); } else if (Directory.Exists(readOnlyPath)) { return(DokanResult.FileExists); } else if (File.Exists(readOnlyPath)) { return(DokanResult.AlreadyExists); } info.Context = new LayeredDirectoryContext(fileName) { WriteDirInfo = Directory.CreateDirectory(writePath) }; return(DokanResult.Success); } else if (mode == FileMode.Open) { var context = new LayeredDirectoryContext(fileName); if (Directory.Exists(writePath)) { context.WriteDirInfo = new DirectoryInfo(writePath); } else if (File.Exists(writePath)) { return(DokanResult.NotADirectory); } if (Directory.Exists(readOnlyPath)) { context.ReadOnlyDirInfo = new DirectoryInfo(readOnlyPath); } else if (context.WriteDirInfo == null) { if (File.Exists(readOnlyPath)) { return(DokanResult.NotADirectory); } else { return(DokanResult.PathNotFound); } } info.Context = context; return(DokanResult.Success); } else { // unkown operation return(DokanResult.Unsuccessful); } } else { var writable = false; var pathExists = false; var pathIsDirectory = Directory.Exists(writePath); if (pathIsDirectory) { pathExists = true; } else if (File.Exists(writePath)) { writable = true; pathExists = true; } else { if (pathIsDirectory = Directory.Exists(readOnlyPath)) { pathExists = true; pathIsDirectory = true; } else { pathExists = File.Exists(readOnlyPath); } } var readAttributes = (access & ReadAttributes) == 0; var readAccess = (access & DataWriteAccess) == 0; switch (mode) { case FileMode.Open: if (!pathExists) { return(DokanResult.FileNotFound); } else { if (pathIsDirectory) { info.IsDirectory = true; if ((access & FileAccess.Delete) == FileAccess.Delete && (access & FileAccess.Synchronize) != FileAccess.Synchronize) { // it is a DeleteFile request on a directory return(DokanResult.AccessDenied); } // call it again, with the IsDirectory set to true return(UnsafeCreateFile(fileName, access, share, mode, options, attributes, info)); } else if (readAttributes) { info.Context = new LayeredReadAttributesContext(fileName, writable ? writePath : readOnlyPath, pathIsDirectory); return(DokanResult.Success); } } break; case FileMode.CreateNew: if (writable) { if (pathExists) { return(DokanResult.FileExists); } } writable = true; break; case FileMode.Create: writable = true; break; case FileMode.Truncate: if (!pathExists) { return(DokanResult.FileNotFound); } break; case FileMode.OpenOrCreate: if (!pathExists) { writable = true; } break; default: throw new Exception($"Unhandled FileMode {mode.ToString("g")}"); } if (writable) { var path = Path.GetDirectoryName(writePath); if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } } else if (!readAccess) { var path = Path.GetDirectoryName(writePath); if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } File.Copy(readOnlyPath, writePath, true); FileInfo finfo = new FileInfo(readOnlyPath); File.SetCreationTime(writePath, finfo.CreationTime); File.SetLastAccessTime(writePath, finfo.LastAccessTime); File.SetLastWriteTime(writePath, finfo.LastWriteTime); writable = true; } LayeredFileContext context = new LayeredFileContext(fileName, writable ? writePath : readOnlyPath, writable); info.Context = context; try { context.Stream = new FileStream(writable ? writePath : readOnlyPath, mode, readAccess ? System.IO.FileAccess.Read : System.IO.FileAccess.ReadWrite, share, 4096, options); } catch (Exception ex) { var hr = (uint)Marshal.GetHRForException(ex); switch (hr) { case 0x80070020: //Sharing violation return(DokanResult.SharingViolation); default: throw; } } if (mode == FileMode.CreateNew || mode == FileMode.Create) // files are always created as Archive { attributes |= FileAttributes.Archive; context.SetAttributes(attributes); } return(DokanResult.Success); } }