public NtStatus CreateFile( string filename, FileAccess access, FileShare share, FileMode mode, FileOptions options, FileAttributes attributes, IDokanFileInfo info) { // don't allow user to create new files or directories - this fake volume is read only if (mode != FileMode.Open && mode != FileMode.OpenOrCreate) { return(DokanResult.AccessDenied); } // check if the file/directory exists try { var fi = VirtualFileSystemProvider.QueryItem(filename); if (info.IsDirectory && !fi.Attributes.HasFlag(FileAttributes.Directory)) { return(DokanResult.NotADirectory); } if (!info.IsDirectory && access.HasFlag(FileAccess.GenericRead)) { // set the memory stream on the context info.Context = VirtualFileSystemProvider.GetFileStream(filename); } } catch (FileNotFoundException) { return(info.IsDirectory ? DokanResult.PathNotFound : DokanResult.FileNotFound); } catch (Exception e) { log.Error(e.Message); return(DokanResult.Error); } return(DokanResult.Success); }
public NtStatus CreateFile(string fileName, FileAccess access, FileShare share, FileMode mode, FileOptions options, FileAttributes attributes, DokanFileInfo info) { if (info == null) { throw new ArgumentNullException(nameof(info)); } // HACK: Fix for Bug in Dokany related to a missing trailing slash for directory names if (string.IsNullOrEmpty(fileName)) { fileName = @"\"; } // HACK: Fix for Bug in Dokany related to a call to CreateFile with a fileName of '\*' else if (fileName == @"\*" && access == FileAccess.ReadAttributes) { return(AsTrace(nameof(CreateFile), fileName, info, access, share, mode, options, attributes, DokanResult.Success)); } if (fileName == @"\") { info.IsDirectory = true; return(AsTrace(nameof(CreateFile), fileName, info, access, share, mode, options, attributes, DokanResult.Success)); } fileName = fileName.TrimEnd(Path.DirectorySeparatorChar); var parent = GetItem(Path.GetDirectoryName(fileName)) as CloudDirectoryNode; if (parent == null) { return(AsDebug(nameof(CreateFile), fileName, info, access, share, mode, options, attributes, DokanResult.PathNotFound)); } var itemName = Path.GetFileName(fileName); var item = parent.GetChildItemByName(_drive, itemName); CloudFileNode fileItem; switch (mode) { case FileMode.Create: fileItem = item as CloudFileNode; if (fileItem != null) { fileItem.Truncate(_drive); } else { fileItem = parent.NewFileItem(_drive, itemName); } info.Context = new StreamContext(fileItem, FileAccess.WriteData); return(AsTrace(nameof(CreateFile), fileName, info, access, share, mode, options, attributes, DokanResult.Success)); case FileMode.Open: fileItem = item as CloudFileNode; if (fileItem != null) { if (access.HasFlag(FileAccess.ReadData) || access.HasFlag(FileAccess.GenericRead) || access.HasFlag(FileAccess.ReadAttributes)) { info.Context = new StreamContext(fileItem, FileAccess.ReadData); } else if (access.HasFlag(FileAccess.WriteData)) { info.Context = new StreamContext(fileItem, FileAccess.WriteData); } else if (access.HasFlag(FileAccess.Delete)) { info.Context = new StreamContext(fileItem, FileAccess.Delete); } // else if (!access.HasFlag(FileAccess.ReadAttributes)) else if (!access.HasFlag(FileAccess.ReadAttributes) && !access.HasFlag(FileAccess.ReadPermissions)) { return(AsDebug(nameof(CreateFile), fileName, info, access, share, mode, options, attributes, DokanResult.NotImplemented)); } } else { info.IsDirectory = item != null; } if (item != null) { return(AsTrace(nameof(CreateFile), fileName, info, access, share, mode, options, attributes, DokanResult.Success)); } else { return(AsError(nameof(CreateFile), fileName, info, access, share, mode, options, attributes, DokanResult.FileNotFound)); } case FileMode.OpenOrCreate: fileItem = item as CloudFileNode ?? parent.NewFileItem(_drive, itemName); if (access.HasFlag(FileAccess.ReadData) && !access.HasFlag(FileAccess.WriteData)) { info.Context = new StreamContext(fileItem, FileAccess.ReadData); } else { info.Context = new StreamContext(fileItem, FileAccess.WriteData); } return(AsTrace(nameof(CreateFile), fileName, info, access, share, mode, options, attributes, DokanResult.Success)); case FileMode.CreateNew: if (item != null) { return(AsDebug(nameof(CreateFile), fileName, info, access, share, mode, options, attributes, info.IsDirectory ? DokanResult.AlreadyExists : DokanResult.FileExists)); } if (info.IsDirectory) { parent.NewDirectoryItem(_drive, itemName); } else { fileItem = parent.NewFileItem(_drive, itemName); info.Context = new StreamContext(fileItem, FileAccess.WriteData); } return(AsTrace(nameof(CreateFile), fileName, info, access, share, mode, options, attributes, DokanResult.Success)); case FileMode.Append: return(AsError(nameof(CreateFile), fileName, info, access, share, mode, options, attributes, DokanResult.NotImplemented)); case FileMode.Truncate: fileItem = item as CloudFileNode; if (fileItem == null) { return(AsDebug(nameof(CreateFile), fileName, info, access, share, mode, options, attributes, DokanResult.FileNotFound)); } fileItem.Truncate(_drive); info.Context = new StreamContext(fileItem, FileAccess.WriteData); return(AsTrace(nameof(CreateFile), fileName, info, access, share, mode, options, attributes, DokanResult.Success)); //return AsError(nameof(CreateFile), fileName, info, access, share, mode, options, attributes, DokanResult.NotImplemented); default: return(AsError(nameof(CreateFile), fileName, info, access, share, mode, options, attributes, DokanResult.NotImplemented)); } }
public NtStatus CreateFile([NotNull] string fileName, FileAccess access, FileShare share, FileMode mode, FileOptions options, FileAttributes attributes, [NotNull] IDokanFileInfo info) { NtStatus result = DokanResult.Success; string filePath = GetMinePath(fileName); if (info.IsDirectory) { try { switch (mode) { case FileMode.Open: { if (!Directory.Exists(filePath)) { try { if (!File.GetAttributes(filePath).HasFlag(FileAttributes.Directory)) { return(DokanResult.NotADirectory); } } catch (Exception) { return(DokanResult.FileNotFound); } return(DokanResult.PathNotFound); } // ReSharper disable once ReturnValueOfPureMethodIsNotUsed new DirectoryInfo(filePath).EnumerateFileSystemInfos().Any(); // you can't list the directory break; } case FileMode.CreateNew: { if (Directory.Exists(filePath)) { return(DokanResult.FileExists); } try { // ReSharper disable once ReturnValueOfPureMethodIsNotUsed File.GetAttributes(filePath).HasFlag(FileAttributes.Directory); return(DokanResult.AlreadyExists); } catch (IOException) { } Directory.CreateDirectory(GetMinePath(fileName)); break; } } } catch (UnauthorizedAccessException) { return(DokanResult.AccessDenied); } } else { bool pathExists = true; bool pathIsDirectory = false; bool readWriteAttributes = (access & DataAccess) == 0; bool readAccess = (access & DataWriteAccess) == 0; try { pathExists = Directory.Exists(filePath) || File.Exists(filePath); pathIsDirectory = pathExists && File.GetAttributes(filePath).HasFlag(FileAttributes.Directory); } catch (IOException) { } switch (mode) { case FileMode.Open: { if (pathExists) { // check if driver only wants to read attributes, security info, or open directory if (readWriteAttributes || pathIsDirectory) { if (pathIsDirectory && access.HasFlag(FileAccess.Delete) && !access.HasFlag(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 OnBeforeReadFile(fileName); 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 { _WriteFile.Add(fileName); OnBeforeWriteFile(fileName); if (pathExists && (mode == FileMode.OpenOrCreate || mode == FileMode.Create)) { result = DokanResult.AlreadyExists; } info.Context = new FileStream(filePath, mode, readAccess ? System.IO.FileAccess.Read : System.IO.FileAccess.ReadWrite, share, 4096, options); bool fileCreated = mode == FileMode.CreateNew || mode == FileMode.Create || !pathExists && mode == FileMode.OpenOrCreate; if (fileCreated) { FileAttributes newAttributes = attributes; newAttributes |= FileAttributes.Archive; // Files are always created as Archive // FILE_ATTRIBUTE_NORMAL is override if any other attribute is set. newAttributes &= ~FileAttributes.Normal; File.SetAttributes(filePath, newAttributes); } } catch (UnauthorizedAccessException) { // don't have access rights if (info.Context is FileStream fileStream) { // returning AccessDenied cleanup and close won't be called, // so we have to take care of the stream now fileStream.Dispose(); info.Context = null; } return(DokanResult.AccessDenied); } catch (DirectoryNotFoundException) { return(DokanResult.PathNotFound); } catch (Exception ex) { uint hr = (uint)Marshal.GetHRForException(ex); switch (hr) { case 0x80070020: return(DokanResult.SharingViolation); default: throw; } } } return(result); }
/// <inheritdoc/> public override NtStatus CreateFileHandle(string path, DokanNet.FileAccess access, FileShare share, FileMode mode, FileOptions options, FileAttributes attributes, LVFSContextInfo info) { var controlsFile = ControlsFile(path); if (!controlsFile && PredecessorHasFile(path)) { return(PredecessorCreateFileHandle(path, access, share, mode, options, attributes, info)); } var convertedPath = ConvertPath(path); var directoryExists = Directory.Exists(convertedPath); var fileExists = File.Exists(convertedPath); if (info.IsDirectory) { try { switch (mode) { case FileMode.Open: { if (directoryExists) { return(DokanResult.Success); } else if (fileExists) { return(NtStatus.NotADirectory); } else { return(PredecessorCreateFileHandle(path, access, share, mode, options, attributes, info)); } } case FileMode.CreateNew: { if (directoryExists) { return(DokanResult.AlreadyExists); } else if (fileExists) { return(DokanResult.FileExists); } else if (PredecessorHasFile(path)) { return(DokanResult.AlreadyExists); } else { Directory.CreateDirectory(convertedPath); return(DokanResult.Success); } } case FileMode.OpenOrCreate: { if (directoryExists) { return(DokanResult.Success); } else if (fileExists) { return(NtStatus.NotADirectory); } else if (PredecessorHasFile(path)) { return(PredecessorCreateFileHandle(path, access, share, mode, options, attributes, info)); } else { Directory.CreateDirectory(convertedPath); return(DokanResult.Success); } } default: { // I don't think any other file modes can actually used with directories, so we should be free to die in any arbitrary way here. In fact, I don't think OpenOrCreate can actually be used with directories either, but the associated behaviour was simple enough, so I implemented it anyway. return(DokanResult.NotImplemented); } } } catch (UnauthorizedAccessException) { return(DokanResult.AccessDenied); } } else { switch (mode) { case FileMode.Open: { if (fileExists || directoryExists) { var dataAccess = DokanNet.FileAccess.ReadData | DokanNet.FileAccess.WriteData | DokanNet.FileAccess.AppendData | DokanNet.FileAccess.Execute | DokanNet.FileAccess.GenericExecute | DokanNet.FileAccess.GenericWrite | DokanNet.FileAccess.GenericRead; var readWriteOnlyAttributes = (access & dataAccess) == 0; if (directoryExists || readWriteOnlyAttributes) { if (directoryExists && access.HasFlag(DokanNet.FileAccess.Delete) && !access.HasFlag(DokanNet.FileAccess.Synchronize)) { // Delete request on (potentially) non-empty directory return(DokanResult.AccessDenied); } info.IsDirectory = directoryExists; return(DokanResult.Success); } else { // Go to the regular handler break; } } else { return(PredecessorCreateFileHandle(path, access, share, mode, options, attributes, info)); } } case FileMode.OpenOrCreate: case FileMode.Create: case FileMode.Append: { if (fileExists || directoryExists) { // Go to the regular handler break; } else if (PredecessorHasFile(path)) { return(PredecessorCreateFileHandle(path, access, share, mode, options, attributes, info)); } else { // Go to the regular handler break; } } case FileMode.CreateNew: { if (fileExists || directoryExists || PredecessorHasFile(path)) { return(DokanResult.AlreadyExists); } else { // Go to the regular handler break; } } case FileMode.Truncate: { if (fileExists || directoryExists) { // Go to the regular handler break; } else if (PredecessorHasFile(path)) { return(PredecessorCreateFileHandle(path, access, share, mode, options, attributes, info)); } else { return(DokanResult.FileNotFound); } } default: // This code should never be reached throw new ArgumentException("Unknown file mode: " + mode, nameof(mode)); } var dataWriteAccess = DokanNet.FileAccess.WriteData | DokanNet.FileAccess.AppendData | DokanNet.FileAccess.Delete | DokanNet.FileAccess.GenericWrite; var readAccessOnly = (access & dataWriteAccess) == 0; try { var result = DokanResult.Success; if (!Directory.Exists(Path.GetDirectoryName(convertedPath))) { if (PredecessorHasDirectory(Path.GetDirectoryName(path))) { Directory.CreateDirectory(Path.GetDirectoryName(convertedPath)); } else { return(DokanResult.PathNotFound); } } info.Context[this] = new FileStream(convertedPath, mode, readAccessOnly ? System.IO.FileAccess.Read : System.IO.FileAccess.ReadWrite, share, 4096, options); if ((fileExists || directoryExists) && (mode == FileMode.OpenOrCreate || mode == FileMode.Create)) { result = DokanResult.AlreadyExists; } if (mode == FileMode.CreateNew || mode == FileMode.Create) { attributes |= FileAttributes.Archive; } File.SetAttributes(convertedPath, attributes); return(result); } catch (UnauthorizedAccessException) { return(DokanResult.AccessDenied); } catch (DirectoryNotFoundException) { return(DokanResult.PathNotFound); } catch (Exception ex) { var hr = (uint)System.Runtime.InteropServices.Marshal.GetHRForException(ex); switch (hr) { case 0x80070020: //Sharing violation return(DokanResult.SharingViolation); default: throw; } } } }
public NtStatus CreateFile(string fileName, FileAccess access, FileShare share, FileMode mode, FileOptions options, FileAttributes attributes, DokanFileInfo info) { // HACK: Fix for Bug in Dokany related to a missing trailing slash for directory names if (string.IsNullOrEmpty(fileName)) fileName = @"\"; if (fileName == @"\") { info.IsDirectory = true; return Trace(nameof(CreateFile), fileName, info, access, share, mode, options, attributes, DokanResult.Success); } fileName = fileName.TrimEnd(Path.DirectorySeparatorChar); var parent = GetItem(Path.GetDirectoryName(fileName)) as CloudDirectoryNode; if (parent == null) return Trace(nameof(CreateFile), fileName, info, access, share, mode, options, attributes, DokanResult.PathNotFound); var itemName = Path.GetFileName(fileName); var item = parent.GetChildItemByName(drive, itemName); var fileItem = default(CloudFileNode); switch (mode) { case FileMode.Create: fileItem = item as CloudFileNode; if (fileItem != null) fileItem.Truncate(drive); else fileItem = parent.NewFileItem(drive, itemName); info.Context = new StreamContext(fileItem, FileAccess.WriteData); return Trace(nameof(CreateFile), fileName, info, access, share, mode, options, attributes, DokanResult.Success); case FileMode.Open: fileItem = item as CloudFileNode; if (fileItem != null) { if (access.HasFlag(FileAccess.ReadData)) info.Context = new StreamContext(fileItem, FileAccess.ReadData) { Stream = Stream.Synchronized(fileItem.GetContent(drive)) }; else if (access.HasFlag(FileAccess.WriteData)) info.Context = new StreamContext(fileItem, FileAccess.WriteData); else if (access.HasFlag(FileAccess.Delete)) info.Context = new StreamContext(fileItem, FileAccess.Delete); } else { info.IsDirectory = item != null; } return Trace(nameof(CreateFile), fileName, info, access, share, mode, options, attributes, item != null ? DokanResult.Success : DokanResult.FileNotFound); case FileMode.OpenOrCreate: fileItem = item as CloudFileNode ?? parent.NewFileItem(drive, itemName); if (access.HasFlag(FileAccess.ReadData) && !access.HasFlag(FileAccess.WriteData)) info.Context = new StreamContext(fileItem, FileAccess.ReadData) { Stream = Stream.Synchronized(fileItem.GetContent(drive)) }; else info.Context = new StreamContext(fileItem, FileAccess.WriteData); return Trace(nameof(CreateFile), fileName, info, access, share, mode, options, attributes, DokanResult.Success); case FileMode.CreateNew: if (item != null) return Trace(nameof(CreateFile), fileName, info, access, share, mode, options, attributes, info.IsDirectory ? DokanResult.AlreadyExists : DokanResult.FileExists); if (info.IsDirectory) { parent.NewDirectoryItem(drive, itemName); } else { fileItem = parent.NewFileItem(drive, itemName); info.Context = new StreamContext(fileItem, FileAccess.WriteData); } return Trace(nameof(CreateFile), fileName, info, access, share, mode, options, attributes, DokanResult.Success); case FileMode.Append: return Trace(nameof(CreateFile), fileName, info, access, share, mode, options, attributes, DokanResult.NotImplemented); case FileMode.Truncate: fileItem = item as CloudFileNode; if (fileItem == null) return Trace(nameof(CreateFile), fileName, info, access, share, mode, options, attributes, DokanResult.FileNotFound); fileItem.Truncate(drive); info.Context = new StreamContext(fileItem, FileAccess.WriteData); return Trace(nameof(CreateFile), fileName, info, access, share, mode, options, attributes, DokanResult.Success); default: return Trace(nameof(CreateFile), fileName, info, access, share, mode, options, attributes, DokanResult.NotImplemented); } }
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); }
/// <inheritdoc/> public override NtStatus CreateFileHandle(string path, DokanNet.FileAccess access, FileShare share, FileMode mode, FileOptions options, FileAttributes attributes, LVFSContextInfo info) { var filePath = ConvertPath(path); var isDirectory = Directory.Exists(filePath); var pathExists = isDirectory || File.Exists(filePath); // Check this first for performance reasons. Keep checking it later in case anything's been meddled with if (!pathExists) { return(PredecessorCreateFileHandle(path, access, share, mode, options, attributes, info)); } if (info.IsDirectory) { try { switch (mode) { case FileMode.Open: if (Directory.Exists(filePath)) { // The original Dokan mirror this is based on called new DirectoryInfo(filePath).EnumerateFileSystemInfos().Any();, but did nothing with its result at this point return(DokanResult.Success); } else if (File.Exists(filePath)) { return(NtStatus.NotADirectory); } else { return(PredecessorCreateFileHandle(path, access, share, mode, options, attributes, info)); } case FileMode.OpenOrCreate: if (Directory.Exists(filePath)) { return(DokanResult.Success); } else if (File.Exists(filePath)) { return(DokanResult.FileExists); } else { return(PredecessorCreateFileHandle(path, access, share, mode, options, attributes, info)); } case FileMode.CreateNew: if (Directory.Exists(filePath)) { return(DokanResult.AlreadyExists); } else if (File.Exists(filePath)) { return(DokanResult.FileExists); } else { return(PredecessorCreateFileHandle(path, access, share, mode, options, attributes, info)); } default: if (Directory.Exists(filePath) || File.Exists(filePath)) { return(DokanResult.AccessDenied); } else { return(PredecessorCreateFileHandle(path, access, share, mode, options, attributes, info)); } } } catch (UnauthorizedAccessException) { return(DokanResult.AccessDenied); } } else { switch (mode) { case FileMode.Open: if (pathExists) { var dataAccess = DokanNet.FileAccess.ReadData | DokanNet.FileAccess.WriteData | DokanNet.FileAccess.AppendData | DokanNet.FileAccess.Execute | DokanNet.FileAccess.GenericExecute | DokanNet.FileAccess.GenericWrite | DokanNet.FileAccess.GenericRead; var readWriteOnlyAttributes = (access & dataAccess) == 0; if (isDirectory || readWriteOnlyAttributes) { if (isDirectory && access.HasFlag(DokanNet.FileAccess.Delete) && !access.HasFlag(DokanNet.FileAccess.Synchronize)) { // It's a delete request on a directory. return(DokanResult.AccessDenied); } info.IsDirectory = isDirectory; return(DokanResult.Success); } else { // Go to the regular handler break; } } else { return(PredecessorCreateFileHandle(path, access, share, mode, options, attributes, info)); } case FileMode.OpenOrCreate: if (pathExists) { // Go to the regular handler break; } else { return(PredecessorCreateFileHandle(path, access, share, mode, options, attributes, info)); } case FileMode.CreateNew: if (pathExists) { return(DokanResult.FileExists); } else { return(PredecessorCreateFileHandle(path, access, share, mode, options, attributes, info)); } case FileMode.Truncate: if (pathExists) { return(DokanResult.AccessDenied); } else { return(PredecessorCreateFileHandle(path, access, share, mode, options, attributes, info)); } case FileMode.Create: if (pathExists) { return(DokanResult.AccessDenied); } else { return(PredecessorCreateFileHandle(path, access, share, mode, options, attributes, info)); } case FileMode.Append: if (pathExists) { return(DokanResult.AccessDenied); } else { return(PredecessorCreateFileHandle(path, access, share, mode, options, attributes, info)); } default: // This code should never be reached throw new ArgumentException("Unknown file mode: " + mode, nameof(mode)); } try { info.Context[this] = new FileStream(filePath, mode, System.IO.FileAccess.Read, share, 4096, options); if (mode == FileMode.Open) { return(DokanResult.Success); } else { return(DokanResult.AlreadyExists); } } catch (UnauthorizedAccessException) { return(DokanResult.AccessDenied); } catch (DirectoryNotFoundException) { return(DokanResult.PathNotFound); } catch (Exception ex) { var hr = (uint)System.Runtime.InteropServices.Marshal.GetHRForException(ex); switch (hr) { case 0x80070020: //Sharing violation return(DokanResult.SharingViolation); default: throw; } } } }