示例#1
0
        internal FileStreamImpl(string path, FileMode mode, FileAccess access, FileShare share, int bufferSize, FileOptions options)
        {
            _deleteOnClose = options.HasFlag(FileOptions.DeleteOnClose);
            _fileName      = path;        //_deleteOnClose ? path : null;
            _fd            = -1;

            if (options.HasFlag((FileOptions.Asynchronous | FileOptions.Encrypted)))
            {
                throw new NotImplementedException($"options: {options}");
            }

            int flags = 0;

            if ((int)mode < 1 || (int)mode > 6)
            {
                throw new ArgumentException($"mode: {mode}?");
            }

            if ((int)access < 1 || (int)access > 3)
            {
                throw new ArgumentException($"access: {access}?");
            }

            if (mode == FileMode.Append && access != FileAccess.Write)
            {
                throw new ArgumentException($"mode: Append, access: {access}?");
            }

            // Arrays treated as 1-based
            flags = ModeFlags[(int)mode - 1] | AccessFlags[(int)access - 1];

            // We never modify our file on open, truncation is done separately, in order to not damage the file if it turns out to be locked
            int fd = Check("open", open(path, flags & ~O_TRUNC, Convert.ToInt32("777", 8)));

            try
            {
                LockFd(fd, share, path);
                // If the lock is taken and the file is opened, try to truncate, if necessary
                if (0 != (flags & O_TRUNC))
                {
                    Check("lseek", lseek(fd, 0, 0));
                    Check("ftruncate", ftruncate(fd, 0));
                }

                _fd = fd;
            }
            catch
            {
                // On error, close file/lock and rethrow
                close(fd);
                GC.SuppressFinalize(this);
                throw;
            }
        }
        private static void ApplyOptions([NotNull] FileEntry file, FileOptions options)
        {
            if (options.HasFlag(FileOptions.Encrypted))
            {
                file.SetEncrypted();
            }

            if (options.HasFlag(FileOptions.DeleteOnClose))
            {
                file.EnableDeleteOnClose();
            }
        }
示例#3
0
        private void OnClose()
        {
            if (options.HasFlag(FileOptions.DeleteOnClose) && mockFileDataAccessor.FileExists(path))
            {
                mockFileDataAccessor.RemoveFile(path);
            }

            if (options.HasFlag(FileOptions.Encrypted) && mockFileDataAccessor.FileExists(path))
            {
                mockFileDataAccessor.FileInfo.FromFileName(path).Encrypt();
            }
        }
示例#4
0
        private static NativeTypes.FABRIC_FILE_ATTRIBUTES ToNative(FileOptions options)
        {
            NativeTypes.FABRIC_FILE_ATTRIBUTES attributes = NativeTypes.FABRIC_FILE_ATTRIBUTES.FABRIC_FILE_ATTRIBUTES_NORMAL;

            if (options.HasFlag(FileOptions.Asynchronous))
            {
                attributes |= NativeTypes.FABRIC_FILE_ATTRIBUTES.FABRIC_FILE_ATTRIBUTES_OVERLAPPED;
            }
            if (options.HasFlag(FileOptions.DeleteOnClose))
            {
                attributes |= NativeTypes.FABRIC_FILE_ATTRIBUTES.FABRIC_FILE_ATTRIBUTES_DELETE_ON_CLOSE;
            }
            if (options.HasFlag(FileOptions.Encrypted))
            {
                attributes |= NativeTypes.FABRIC_FILE_ATTRIBUTES.FABRIC_FILE_ATTRIBUTES_ENCRYPTED;
            }
            if (options.HasFlag(FileOptions.RandomAccess))
            {
                attributes |= NativeTypes.FABRIC_FILE_ATTRIBUTES.FABRIC_FILE_ATTRIBUTES_RANDOM_ACCESS;
            }
            if (options.HasFlag(FileOptions.SequentialScan))
            {
                attributes |= NativeTypes.FABRIC_FILE_ATTRIBUTES.FABRIC_FILE_ATTRIBUTES_SEQUENTIAL_SCAN;
            }
            if (options.HasFlag(FileOptions.WriteThrough))
            {
                attributes |= NativeTypes.FABRIC_FILE_ATTRIBUTES.FABRIC_FILE_ATTRIBUTES_WRITE_THROUGH;
            }

            return(attributes);
        }
示例#5
0
            private static bool ShouldCreateFileStream(IAppDataFileProvider fileProvider, FileAccess fileAccess, FileOptions options)
            {
                if (fileProvider.IsWriteEnabled)
                {
                    return(true);
                }

                if (fileAccess.HasFlag(FileAccess.Write))
                {
                    return(false);
                }

                if (options.HasFlag(FileOptions.DeleteOnClose))
                {
                    return(false);
                }

                return(true);
            }
示例#6
0
 public AdsFileStream(string path, string streamName, FileMode mode, FileAccess access, FileShare share, int bufferSize, FileOptions options, FileSecurity fileSecurity)
     : base(CreateHandle(path, streamName, mode, access, share, options, fileSecurity), access, bufferSize, options.HasFlag(FileOptions.Asynchronous))
 {
 }
示例#7
0
        DokanError IDokanOperations.CreateFile(string fileName, FileAccess access, FileShare share,
            FileMode mode, FileOptions options,
            FileAttributes attributes, DokanFileInfo info)
        {
            if (fileName.EndsWith("desktop.ini", StringComparison.OrdinalIgnoreCase) ||
                fileName.EndsWith("autorun.inf", StringComparison.OrdinalIgnoreCase)) //....
            {
                return DokanError.ErrorFileNotFound;
            }

            LogFSActionInit("OpenFile", fileName, (SftpContext)info.Context, "Mode:{0} Options:{1}", mode,options);

            string path = GetUnixPath(fileName);
            //  var  sftpFileAttributes = GetAttributes(path);
            //var sftpFileAttributes = _cache.Get(path) as SftpFileAttributes;
            var sftpFileAttributes = this.CacheGetAttr(path);

            if (sftpFileAttributes == null)
            {
                //Log("cache miss");

                sftpFileAttributes = GetAttributes(path);
                if (sftpFileAttributes != null)
                    //_cache.Add(path, sftpFileAttributes, DateTimeOffset.UtcNow.AddSeconds(_attributeCacheTimeout));
                    CacheAddAttr(path, sftpFileAttributes, DateTimeOffset.UtcNow.AddSeconds(_attributeCacheTimeout));
                else
                {
                    LogFSActionOther("OpenFile", fileName, (SftpContext)info.Context, "get attributes failed");
                }
            }
            /*Log("Open| Name:{0},\n Mode:{1},\n Share{2},\n Disp:{3},\n Flags{4},\n Attr:{5},\nPagingIO:{6} NoCache:{7} SynIO:{8}\n", fileName, access,
                share, mode, options, attributes, info.PagingIo, info.NoCache, info.SynchronousIo);*/

            switch (mode)
            {
                case FileMode.Open:
                    if (sftpFileAttributes != null)
                    {
                        if (((uint)access & 0xe0000027) == 0 || sftpFileAttributes.IsDirectory)
                        //check if only wants to read attributes,security info or open directory
                        {
                            //Log("JustInfo:{0},{1}", fileName, sftpFileAttributes.IsDirectory);
                            info.IsDirectory = sftpFileAttributes.IsDirectory;

                            if (options.HasFlag(FileOptions.DeleteOnClose))
                            {
                                return DokanError.ErrorError;//this will result in calling DeleteFile in Windows Explorer
                            }
                            info.Context = new SftpContext(sftpFileAttributes, false);

                            LogFSActionOther("OpenFile", fileName, (SftpContext)info.Context, "Dir open or get attrs");
                            return DokanError.ErrorSuccess;
                        }
                    }
                    else
                    {
                        LogFSActionError("OpenFile", fileName, (SftpContext)info.Context, "File not found");
                        return DokanError.ErrorFileNotFound;
                    }
                    break;
                case FileMode.CreateNew:
                    if (sftpFileAttributes != null)
                        return DokanError.ErrorAlreadyExists;

                    CacheResetParent(path);
                    break;
                case FileMode.Truncate:
                    if (sftpFileAttributes == null)
                        return DokanError.ErrorFileNotFound;
                    CacheResetParent(path);
                    //_cache.Remove(path);
                    this.CacheReset(path);
                    break;
                default:

                    CacheResetParent(path);
                    break;
            }
            //Log("NotJustInfo:{0}-{1}", info.Context, mode);
            try
            {
                info.Context = new SftpContext(_sftpSession, path, mode,
                                               ((ulong) access & 0x40010006) == 0
                                                   ? System.IO.FileAccess.Read
                                                   : System.IO.FileAccess.ReadWrite, sftpFileAttributes);
            }
            catch (SshException ex) // Don't have access rights or try to read broken symlink
            {
                var ownerpath = path.Substring(0, path.LastIndexOf('/'));
                //var sftpPathAttributes = _cache.Get(ownerpath) as SftpFileAttributes;
                var sftpPathAttributes = CacheGetAttr(ownerpath);

                if (sftpPathAttributes == null)
                {
                    //Log("cache miss");

                    sftpPathAttributes = GetAttributes(ownerpath);
                    if (sftpPathAttributes != null)
                        //_cache.Add(path, sftpFileAttributes, DateTimeOffset.UtcNow.AddSeconds(_attributeCacheTimeout));
                        CacheAddAttr(path, sftpFileAttributes, DateTimeOffset.UtcNow.AddSeconds(_attributeCacheTimeout));
                    else
                    {
                        //Log("Up directory must be created");
                        LogFSActionError("OpenFile", fileName, (SftpContext)info.Context, "Up directory mising:{0}", ownerpath);
                        return DokanError.ErrorPathNotFound;
                    }
                }
                LogFSActionError("OpenFile", fileName, (SftpContext)info.Context, "Access denied");
                return DokanError.ErrorAccessDenied;
            }

            LogFSActionSuccess("OpenFile", fileName, (SftpContext)info.Context, "Mode:{0}", mode);
            return DokanError.ErrorSuccess;
        }
示例#8
0
        private static FileStream OpenHelper(string path, FileMode fileMode, FileAccess fileAccess, FileShare fileShare, int cacheSize, FileOptions fileOptions)
        {
            using (var pin = new PinCollection())
            {
#if DotNetCoreClrLinux
                FileStream fs = new FileStream(path, fileMode);
                UpdateFilePermission(path);
                return(fs);
#else
                IntPtr handle;
                NativeCommon.FabricFileOpenEx(
                    pin.AddBlittable(path),
                    ToNative(fileMode),
                    ToNative(fileAccess),
                    ToNative(fileShare),
                    ToNative(fileOptions),
                    out handle);
                return(new FileStream(new SafeFileHandle(handle, true), fileAccess, cacheSize, fileOptions.HasFlag(FileOptions.Asynchronous)));
#endif
            }
        }
示例#9
0
        /// <summary>
        /// Opens a <see cref="Open(string,System.IO.FileMode,System.IO.FileAccess)"/> on the specified path, having the specified mode with read, write, or read/write access and the specified sharing option.
        /// </summary>
        /// <param name="path">The file to open.</param>
        /// <param name="mode">A <see cref="FileMode"/> value that specifies whether a file is created if one does not exist, and determines whether the contents of existing files are retained or overwritten.</param>
        /// <param name="access">A <see cref="FileAccess"/> value that specifies the operations that can be performed on the file.</param>
        /// <param name="share">A <see cref="FileShare"/> value specifying the type of access other threads have to the file.</param>
        /// <param name="bufferSize">The number of bytes buffered for reads and writes to the file.</param>
        /// <param name="options">One of the <see cref="FileOptions"/> values that describes how to create or overwrite the file.</param>
        /// <returns>A <see cref="FileStream"/> on the specified path, having the specified mode with read, write, or read/write access and the specified sharing option.</returns>
        /// <exception cref="UnauthorizedAccessException">
        /// The caller does not have the required permission.
        ///     <para>-or-</para>
        /// <paramref name="path"/> specified a file that is read-only.
        ///     <para>-or-</para>
        /// <see cref="FileOptions.Encrypted"/> is specified for options and file encryption is not supported on the current platform.
        /// </exception>
        /// <exception cref="ArgumentException"><paramref name="path"/> is a zero-length string, contains only white space, or contains one or more invalid characters as defined by <see cref="Path.GetInvalidPathChars"/>.</exception>
        /// <exception cref="ArgumentNullException"><paramref name="path"/> is <see langword="null"/>.</exception>
        /// <exception cref="PathTooLongException">The specified path, file name, or both exceed the system-defined maximum length.</exception>
        /// <exception cref="DirectoryNotFoundException">The specified path is invalid (for example, it is on an unmapped drive.</exception>
        /// <exception cref="IOException">An I/O error occurred while creating the file.</exception>
        /// <exception cref="NotSupportedException"><paramref name="path"/> is in an invalid format.</exception>
        private static FileStream Open(string path, FileMode mode, FileAccess access, FileShare share, int bufferSize, FileOptions options)
        {
            if (path == null)
            {
                throw new ArgumentNullException(nameof(path));
            }

            if (bufferSize <= 0)
            {
                bufferSize = LongPathFile.DefaultBufferSize;
            }

            string normalizedPath = LongPathCommon.NormalizePath(path);

            SafeFileHandle handle = LongPathFile.GetFileHandle(normalizedPath, mode, access, share, options);
            return new FileStream(handle, access, bufferSize, options.HasFlag(FileOptions.Asynchronous));
        }