예제 #1
0
        private static SafeFileHandle CreateFileInternal(string path, uint access, FileShare share, FileMode mode, uint attributes)
        {
            var securityAttributes = new SecurityAttributes();

            securityAttributes.Length             = Marshal.SizeOf(securityAttributes);
            securityAttributes.SecurityDescriptor = IntPtr.Zero;
            securityAttributes.InheritHandle      = false;

            if (share.HasFlag(FileShare.Inheritable))
            {
                share &= ~FileShare.Inheritable;
                securityAttributes.InheritHandle = true;
            }

            SafeFileHandle fileHandle = CreateFileNative(path, access, share, ref securityAttributes, mode, attributes, IntPtr.Zero);

            if (fileHandle.IsInvalid)
            {
                fileHandle.Close();

                int hResult = Marshal.GetHRForLastWin32Error();
                Marshal.ThrowExceptionForHR(hResult);
            }

            return(fileHandle);
        }
        public bool CheckShareRuleIsPermit(FileLockItem otherRule)
        {
            if (pIsDirectory != otherRule.IsDirectory)
            {
                return(false);
            }
            if (this.pIsDirectory)
            {
                return(true); // As long as CreateDirectory and OpenDirectory do not return correct FileShare/FileAccess values, this workaround must remain active.
            }

            if (this.pIsOpLock || otherRule.IsOpLock)
            {
                return(CheckShareOPLockIsPermit(otherRule));
            }

            FileShare shareO = otherRule.Share;

            bool shareReadT  = false;
            bool shareWriteT = false;

            bool shareReadO  = false;
            bool shareWriteO = false;

            if (pShare.HasFlag(FileShare.Read))
            {
                shareReadT = true;
            }
            if (pShare.HasFlag(FileShare.Write))
            {
                shareWriteT = true;
            }
            if (pShare.HasFlag(FileShare.ReadWrite))
            {
                shareReadT = true; shareWriteT = true;
            }

            if (shareO.HasFlag(FileShare.Read))
            {
                shareReadO = true;
            }
            if (shareO.HasFlag(FileShare.Write))
            {
                shareWriteO = true;
            }
            if (shareO.HasFlag(FileShare.ReadWrite))
            {
                shareReadO = true; shareWriteO = true;
            }

            if (shareReadT == false && shareWriteT == false)
            {
                if (otherRule.AccessModeWrite || otherRule.AccessModeRead)
                {
                    return(false); // Authorised Share: none
                }
            }
            if (shareReadO == false && shareWriteO == false)
            {
                if (this.AccessModeWrite || this.AccessModeRead)
                {
                    return(false); // Authorised Share: none
                }
            }


            if (shareReadT == true && shareWriteT == false)
            {
                if (otherRule.AccessModeWrite == true)
                {
                    return(false);
                }
            }
            if (shareReadO == true && shareWriteO == false)
            {
                if (this.AccessModeWrite == true)
                {
                    return(false);
                }
            }


            if (shareReadT == false && shareWriteT == true)
            {
                if (otherRule.AccessModeRead == true)
                {
                    return(false);
                }
            }
            if (shareReadO == false && shareWriteO == true)
            {
                if (this.AccessModeRead == true)
                {
                    return(false);
                }
            }


            if (shareReadT == true && shareWriteT == true)
            {
            }
            if (shareReadO == true && shareWriteO == true)
            {
            }


            return(true);
        }
예제 #3
0
        public NtStatus CreateFile(string fileName, FileAccess access, FileShare share, FileMode mode, FileOptions options,
                                   FileAttributes attributes, IDokanFileInfo info)
        {
            var result   = NtStatus.Success;
            var filePath = GetPath(fileName);

            if (info.IsDirectory)
            {
                try
                {
                    switch (mode)
                    {
                    case FileMode.Open:
                        if (!Directory.Exists(filePath))
                        {
                            try
                            {
                                if (!File.GetAttributes(filePath).HasFlag(FileAttributes.Directory))
                                {
                                    return(NtStatus.NotADirectory);
                                }
                            }
                            catch (Exception)
                            {
                                return(DokanResult.FileNotFound);
                            }
                            return(DokanResult.PathNotFound);
                        }

                        new DirectoryInfo(filePath).EnumerateFileSystemInfos().Any();
                        // you can't list the directory
                        break;

                    case FileMode.CreateNew:
                        if (Directory.Exists(filePath))
                        {
                            return(DokanResult.FileExists);
                        }

                        try
                        {
                            File.GetAttributes(filePath).HasFlag(FileAttributes.Directory);
                            return(DokanResult.AlreadyExists);
                        }
                        catch (IOException)
                        {
                        }

                        Directory.CreateDirectory(GetPath(fileName));
                        break;
                    }
                }
                catch (UnauthorizedAccessException)
                {
                    return(DokanResult.AccessDenied);
                }
            }
            else
            {
                var pathExists      = true;
                var pathIsDirectory = false;

                var readWriteAttributes = (access & DataAccess) == 0;
                var readAccess          = (access & DataWriteAccess) == 0;

                try
                {
                    pathExists      = (Directory.Exists(filePath) || File.Exists(filePath));
                    pathIsDirectory = File.GetAttributes(filePath).HasFlag(FileAttributes.Directory);
                }
                catch (IOException)
                {
                }

                switch (mode)
                {
                case FileMode.Open:
                {
                    // Scan file before open
                    if ((access != FileAccess.Delete) && (access != FileAccess.ReadAttributes))
                    {
                        if (File.Exists(filePath))
                        {
                            try
                            {
                                bool executing = access.HasFlag(FileAccess.ReadData) &&
                                                 access.HasFlag(FileAccess.Execute) &&
                                                 access.HasFlag(FileAccess.ReadAttributes) &&
                                                 access.HasFlag(FileAccess.Synchronize) &&
                                                 share.HasFlag(FileShare.Read) &&
                                                 share.HasFlag(FileShare.Delete) &&
                                                 attributes.HasFlag(FileAttributes.Normal);

                                if (executing)
                                {
                                    return(OnRequestFileOpen?.Invoke(filePath) ?? DokanResult.Success);
                                }
                            }
                            catch (Exception ex)
                            {
                                //ex.Log();
                            }
                        }
                    }

                    if (pathExists)
                    {
                        // check if driver only wants to read attributes, security info, or open directory
                        if (readWriteAttributes || pathIsDirectory)
                        {
                            if (pathIsDirectory && (access & FileAccess.Delete) == FileAccess.Delete &&
                                (access & FileAccess.Synchronize) != FileAccess.Synchronize)
                            {
                                //It is a DeleteFile request on a directory
                                return(DokanResult.AccessDenied);
                            }

                            info.IsDirectory = pathIsDirectory;
                            info.Context     = new object();
                            // must set it to someting if you return DokanError.Success

                            return(DokanResult.Success);
                        }
                    }
                    else
                    {
                        return(DokanResult.FileNotFound);
                    }
                }
                break;

                case FileMode.CreateNew:
                    if (pathExists)
                    {
                        return(DokanResult.FileExists);
                    }
                    break;

                case FileMode.Truncate:
                    if (!pathExists)
                    {
                        return(DokanResult.FileNotFound);
                    }
                    break;
                }

                try
                {
                    info.Context = new FileStream(filePath, mode,
                                                  readAccess ? System.IO.FileAccess.Read : System.IO.FileAccess.ReadWrite, share, 4096, options);

                    if (pathExists && (mode == FileMode.OpenOrCreate ||
                                       mode == FileMode.Create))
                    {
                        result = DokanResult.AlreadyExists;
                    }

                    if (mode == FileMode.CreateNew || mode == FileMode.Create) //Files are always created as Archive
                    {
                        attributes |= FileAttributes.Archive;
                    }
                    File.SetAttributes(filePath, attributes);
                }
                catch (UnauthorizedAccessException) // don't have access rights
                {
                    return(DokanResult.AccessDenied);
                }
                catch (DirectoryNotFoundException)
                {
                    return(DokanResult.PathNotFound);
                }
                catch (Exception ex)
                {
                    var hr = (uint)Marshal.GetHRForException(ex);
                    switch (hr)
                    {
                    case 0x80070020:     //Sharing violation
                        return(DokanResult.SharingViolation);

                    default:
                        throw;
                    }
                }
            }
            return(result);
        }