public NtStatus CreateFile(string fileName, FileAccess access, FileShare share, FileMode mode, FileOptions options, FileAttributes attributes, DokanFileInfo info)
        {
            try
            {
                var res = Wait(MainCreateFile(fileName, access, share, mode, options, info));
#if TRACE
                var readWriteAttributes = (access & DataAccess) == 0;
                if (!(readWriteAttributes || info.IsDirectory) || (res != DokanResult.Success && !(lastFilePath == fileName && res == DokanResult.FileNotFound)))
                {
                    if (!(info.Context is IBlockStream))
                    {
                        Log.Trace($"{fileName}\r\n  Access:[{access}]\r\n  Share:[{share}]\r\n  Mode:[{mode}]\r\n  Options:[{options}]\r\n  Attr:[{attributes}]\r\nStatus:{res}");
                    }

                    lastFilePath = fileName;
                }
#endif
                return(res);
            }
            catch (Exception e) when(e.InnerException is FileNotFoundException)
            {
                Log.Error($"File not found: {fileName}\r\n  Access:[{access}]\r\n  Share:[{share}]\r\n  Mode:[{mode}]\r\n  Options:[{options}]\r\n  Attr:[{attributes}]", e);
                return(DokanResult.FileNotFound);
            }
            catch (Exception e) when(e.InnerException is TimeoutException)
            {
                Log.Error($"Timeout: {fileName}\r\n  Access:[{access}]\r\n  Share:[{share}]\r\n  Mode:[{mode}]\r\n  Options:[{options}]\r\n  Attr:[{attributes}]", e);
                return(NtStatus.Timeout);
            }
            catch (Exception e)
            {
                Log.Error($"Unexpected exception: {fileName}\r\n  Access:[{access}]\r\n  Share:[{share}]\r\n  Mode:[{mode}]\r\n  Options:[{options}]\r\n  Attr:[{attributes}]", e);
                return(DokanResult.Error);
            }
        }
        private async Task <NtStatus> MainOpenFile(string fileName, FileAccess access, FileShare share, FileMode mode, FileOptions options, DokanFileInfo info)
        {
            var readAccess  = (access & DataReadAccess) != 0;
            var writeAccess = (access & DataWriteAccess) != 0;

            if (writeAccess && ReadOnly)
            {
                return(DokanResult.AccessDenied);
            }

            var ioaccess = System.IO.FileAccess.Read;

            if (!readAccess && writeAccess)
            {
                ioaccess = System.IO.FileAccess.Write;
            }

            if (readAccess && writeAccess)
            {
                ioaccess = System.IO.FileAccess.ReadWrite;
            }

            var result = await provider.OpenFile(fileName, mode, ioaccess, share, options);

            if (result == null)
            {
                return(DokanResult.AccessDenied);
            }

            info.Context = result;
            return(DokanResult.Success);
        }
Beispiel #3
0
#pragma warning disable RECS0154 // Parameter is never used
        private async Task <NtStatus> MainOpenFile(string fileName, FileAccess access, FileShare share, FileMode mode, FileOptions options, FileAttributes attributes, DokanFileInfo info)
#pragma warning restore RECS0154 // Parameter is never used
        {
            bool readAccess  = (access & DataReadAccess) != 0;
            bool writeAccess = (access & DataWriteAccess) != 0;

            if (writeAccess && ReadOnly)
            {
                return(DokanResult.AccessDenied);
            }

            var ioaccess = System.IO.FileAccess.Read;

            if (!readAccess && writeAccess)
            {
                ioaccess = System.IO.FileAccess.Write;
            }

            if (readAccess && writeAccess)
            {
                ioaccess = System.IO.FileAccess.ReadWrite;
            }

            var result = await provider.OpenFile(fileName, mode, ioaccess, share, options);

            if (result == null)
            {
                return(DokanResult.AccessDenied);
            }

            info.Context = result;
            return(DokanResult.Success);
        }
        private async Task <NtStatus> MainCreateFile(string fileName, FileAccess access, FileShare share, FileMode mode, FileOptions options, DokanFileInfo info)
        {
            if (!HasAccess(info))
            {
                return(DokanResult.AccessDenied);
            }

            if (info.IsDirectory)
            {
                if (mode == FileMode.CreateNew)
                {
                    return(MainCreateDirectory(fileName));
                }

                if (mode == FileMode.Open && !await provider.Exists(fileName))
                {
                    return(DokanResult.PathNotFound);
                }

                if (access == FileAccess.Synchronize)
                {
                    info.Context = new object();
                    return(DokanResult.Success);
                }

                info.Context = new object();
                return(DokanResult.Success);
            }

            string streamName = null;

            fileName = fileName.Replace("\\:", ":");
            if (fileName.Contains(':'))
            {
                var names = fileName.Split(':');
                fileName   = names[0];
                streamName = names[1];
            }

            var item = await provider.FetchNode(fileName);

            if (streamName != null && item != null)
            {
                return(CheckStreams(fileName, mode, info, streamName, item));
            }

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

            switch (mode)
            {
            case FileMode.Open:
                if (item == null)
                {
                    return(DokanResult.FileNotFound);
                }

                // check if driver only wants to read attributes, security info, or open directory
                if (item.IsDir)
                {
                    info.IsDirectory = item.IsDir;
                    info.Context     = new object();

                    // must set it to something if you return DokanError.Success
                    return(DokanResult.Success);
                }

                break;

            case FileMode.CreateNew:
                if (item != null)
                {
                    return(DokanResult.FileExists);
                }

                break;

            case FileMode.Truncate:
                if (item == null)
                {
                    return(DokanResult.FileNotFound);
                }

                break;
            }

            if (readWriteAttributes)
            {
                info.Context = new object();
                return(DokanResult.Success);
            }

            return(await MainOpenFile(fileName, access, share, mode, options, info));
        }