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); }
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); }