示例#1
0
        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);
            }
        }
示例#2
0
        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);
        }
示例#3
0
        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);
            }
        }