示例#1
0
        public static void Delete(string path, bool recursive)
        {
            path = Path.GetFullPath(path);

            var record = FileSystemManager.LockDirectory(path);
            var drive  = DriveInfo.GetForPath(path);

            try {
                var attributes = drive.GetAttributes(path);

                if ((uint)attributes == 0xFFFFFFFF)
                {
                    throw new IOException("", (int)IOException.IOExceptionErrorCode.DirectoryNotFound);
                }

                if (((attributes & (FileAttributes.Directory)) == 0) ||
                    ((attributes & (FileAttributes.ReadOnly)) != 0))
                {
                    /// it's readonly or not a directory
                    throw new IOException("", (int)IOException.IOExceptionErrorCode.UnauthorizedAccess);
                }

                if (!Exists(path)) // make sure it is indeed a directory (and not a file)
                {
                    throw new IOException("", (int)IOException.IOExceptionErrorCode.DirectoryNotFound);
                }

                if (!recursive)
                {
                    var ff = drive.Find(path, "*");

                    try {
                        if (ff.GetNext() != null)
                        {
                            throw new IOException("", (int)IOException.IOExceptionErrorCode.DirectoryNotEmpty);
                        }
                    }
                    finally {
                        ff.Close();
                    }
                }

                drive.Delete(path);
            }
            finally {
                // regardless of what happened, we need to release the directory when we're done
                FileSystemManager.UnlockDirectory(record);
            }
        }
示例#2
0
        private static void RecursiveCopyAndDelete(String sourceDirName, String destDirName)
        {
            String[] files;
            int      filesCount, i;
            int      relativePathIndex = sourceDirName.Length + 1; // relative path starts after the sourceDirName and a path seperator
            // We have to make sure no one else can modify it (for example, delete the directory and
            // create a file of the same name) while we're moving
            Object recordSrc = FileSystemManager.AddToOpenList(sourceDirName);

            try
            {
                // Make sure sourceDir is actually a directory
                if (!Exists(sourceDirName))
                {
                    throw new IOException("", (int)IOException.IOExceptionErrorCode.DirectoryNotFound);
                }

                // Make sure destDir does not yet exist
                if (Exists(destDirName))
                {
                    throw new IOException("", (int)IOException.IOExceptionErrorCode.PathAlreadyExists);
                }

                NativeIO.CreateDirectory(destDirName);

                files      = Directory.GetFiles(sourceDirName);
                filesCount = files.Length;

                for (i = 0; i < filesCount; i++)
                {
                    File.Copy(files[i], Path.Combine(destDirName, files[i].Substring(relativePathIndex)), false, true);
                }

                files      = Directory.GetDirectories(sourceDirName);
                filesCount = files.Length;

                for (i = 0; i < filesCount; i++)
                {
                    RecursiveCopyAndDelete(files[i], Path.Combine(destDirName, files[i].Substring(relativePathIndex)));
                }

                NativeIO.Delete(sourceDirName);
            }
            finally
            {
                FileSystemManager.RemoveFromOpenList(recordSrc);
            }
        }
示例#3
0
        protected virtual void Dispose(bool disposing)
        {
            if (this.m_findFile != null)
            {
                this.m_findFile.Close();
                this.m_findFile = null;
            }

            if (this.m_openForReadHandle != null)
            {
                FileSystemManager.RemoveFromOpenList(this.m_openForReadHandle);
                this.m_openForReadHandle = null;
            }

            this.m_disposed = true;
        }
示例#4
0
        public void Reset()
        {
            if (this.m_disposed)
            {
                throw new ObjectDisposedException();
            }

            if (this.m_findFile != null)
            {
                this.m_findFile.Close();
            }

            if (this.m_openForReadHandle == null)
            {
                this.m_openForReadHandle = FileSystemManager.AddToOpenListForRead(this.m_path);
            }

            this.m_findFile = DriveInfo.GetForPath(this.m_path).Find(this.m_path, "*");
        }
示例#5
0
        public void Refresh()
        {
            var record = FileSystemManager.AddToOpenListForRead(this.m_fullPath);

            try
            {
                this._nativeFileInfo = DriveInfo.GetForPath(this.m_fullPath).GetFileSystemEntry(this.m_fullPath);

                if (this._nativeFileInfo == null)
                {
                    var errorCode = (this is FileInfo) ? IOException.IOExceptionErrorCode.FileNotFound : IOException.IOExceptionErrorCode.DirectoryNotFound;
                    throw new IOException("", (int)errorCode);
                }
            }
            finally
            {
                FileSystemManager.RemoveFromOpenList(record);
            }
        }
示例#6
0
        public void Refresh()
        {
            Object record = FileSystemManager.AddToOpenListForRead(m_fullPath);

            try
            {
                _nativeFileInfo = NativeFindFile.GetFileInfo(m_fullPath);

                if (_nativeFileInfo == null)
                {
                    IOException.IOExceptionErrorCode errorCode = (this is FileInfo) ? IOException.IOExceptionErrorCode.FileNotFound : IOException.IOExceptionErrorCode.DirectoryNotFound;
                    throw new IOException("", (int)errorCode);
                }
            }
            finally
            {
                FileSystemManager.RemoveFromOpenList(record);
            }
        }
示例#7
0
        public void Reset()
        {
            if (m_disposed)
            {
                throw new ObjectDisposedException();
            }

            if (m_findFile != null)
            {
                m_findFile.Close();
            }

            if (m_openForReadHandle == null)
            {
                m_openForReadHandle = FileSystemManager.AddToOpenListForRead(m_path);
            }

            m_findFile = new NativeFindFile(m_path, "*");
        }
示例#8
0
        public bool MoveNext()
        {
            if (this.m_disposed)
            {
                throw new ObjectDisposedException();
            }

            var fileinfo = this.m_findFile.GetNext();

            while (fileinfo != null)
            {
                if (this.m_flags != FileEnumFlags.FilesAndDirectories)
                {
                    var targetAttribute = (0 != (this.m_flags & FileEnumFlags.Directories) ? FileAttributes.Directory : 0);

                    if ((fileinfo.Attributes & FileAttributes.Directory) == targetAttribute)
                    {
                        this.m_currentFile = fileinfo;
                        break;
                    }
                }
                else
                {
                    this.m_currentFile = fileinfo;
                    break;
                }

                fileinfo = this.m_findFile.GetNext();
            }

            if (fileinfo == null)
            {
                this.m_findFile.Close();
                this.m_findFile = null;

                FileSystemManager.RemoveFromOpenList(this.m_openForReadHandle);
                this.m_openForReadHandle = null;
            }

            return(fileinfo != null);
        }
示例#9
0
        // Deletes a file. The file specified by the designated path is deleted.
        // If the file does not exist, Delete succeeds without throwing
        // an exception.
        //
        // On NT, Delete will fail for a file that is open for normal I/O
        // or a file that is memory mapped.  On Win95, the file will be
        // deleted irregardless of whether the file is being used.
        //
        // Your application must have Delete permission to the target file.
        //
        public static void Delete(String path)
        {
            // path validation in Path.GetFullPath()

            path = Path.GetFullPath(path);
            string folderPath = Path.GetDirectoryName(path);

            // We have to make sure no one else has the file opened, and no one else can modify it when we're deleting
            Object record = FileSystemManager.AddToOpenList(path);

            try
            {
                uint attributes = NativeIO.GetAttributes(folderPath);
                /// If the folder does not exist or invalid we throw DirNotFound Exception (same as desktop).
                if (attributes == 0xFFFFFFFF)
                {
                    throw new IOException("", (int)IOException.IOExceptionErrorCode.DirectoryNotFound);
                }

                /// Folder exists, lets verify whether the file itself exists.
                attributes = NativeIO.GetAttributes(path);
                if (attributes == 0xFFFFFFFF)
                {
                    // No-op on file not found
                    return;
                }

                if ((attributes & (uint)(FileAttributes.Directory | FileAttributes.ReadOnly)) != 0)
                {
                    /// it's a readonly file or an directory
                    throw new IOException("", (int)IOException.IOExceptionErrorCode.UnauthorizedAccess);
                }

                NativeIO.Delete(path);
            }
            finally
            {
                // regardless of what happened, we need to release the file when we're done
                FileSystemManager.RemoveFromOpenList(record);
            }
        }
示例#10
0
        protected override void Dispose(bool disposing)
        {
            if (!this._disposed)
            {
                try {
                    if (this._nativeFileStream != null)
                    {
                        this._nativeFileStream.Close();
                    }
                }
                finally {
                    if (this._fileRecord != null)
                    {
                        FileSystemManager.RemoveFromOpenList(this._fileRecord);
                        this._fileRecord = null;
                    }

                    this._nativeFileStream = null;
                    this._disposed         = true;
                }
            }
        }
示例#11
0
        public static void SetCurrentDirectory(string path)
        {
            // path validation in Path.GetFullPath()

            path = Path.GetFullPath(path);

            // We lock the directory for read-access first, to ensure path won't get deleted
            var record = FileSystemManager.AddToOpenListForRead(path);

            try {
                if (!Directory.Exists(path))
                {
                    throw new IOException("", (int)IOException.IOExceptionErrorCode.DirectoryNotFound);
                }

                // This will put the actual lock on path. (also read-access)
                FileSystemManager.SetCurrentDirectory(path);
            }
            finally {
                // We take our lock off.
                FileSystemManager.RemoveFromOpenList(record);
            }
        }
示例#12
0
        public FileStream(String path, FileMode mode, FileAccess access, FileShare share, int bufferSize)
        {
            // This will perform validation on path
            _fileName = Path.GetFullPath(path);

            // make sure mode, access, and share are within range
            if (mode < FileMode.CreateNew || mode > FileMode.Append ||
                access < FileAccess.Read || access > FileAccess.ReadWrite ||
                share < FileShare.None || share > FileShare.ReadWrite)
            {
                throw new ArgumentOutOfRangeException();
            }

            // Get wantsRead and wantsWrite from access, note that they cannot both be false
            bool wantsRead  = (access & FileAccess.Read) == FileAccess.Read;
            bool wantsWrite = (access & FileAccess.Write) == FileAccess.Write;

            // You can't open for readonly access (wantsWrite == false) when
            // mode is CreateNew, Create, Truncate or Append (when it's not Open or OpenOrCreate)
            if (mode != FileMode.Open && mode != FileMode.OpenOrCreate && !wantsWrite)
            {
                throw new ArgumentException();
            }

            // We need to register the share information prior to the actual file open call (the NativeFileStream ctor)
            // so subsequent file operation on the same file will behave correctly
            _fileRecord = FileSystemManager.AddToOpenList(_fileName, (int)access, (int)share);

            try
            {
                uint attributes = NativeIO.GetAttributes(_fileName);
                bool exists     = (attributes != 0xFFFFFFFF);
                bool isReadOnly = (exists) ? (((FileAttributes)attributes) & FileAttributes.ReadOnly) == FileAttributes.ReadOnly : false;

                // If the path specified is an existing directory, fail
                if (exists && ((((FileAttributes)attributes) & FileAttributes.Directory) == FileAttributes.Directory))
                {
                    throw new IOException("", (int)IOException.IOExceptionErrorCode.UnauthorizedAccess);
                }

                // The seek limit is 0 (the beginning of the file) for all modes except Append
                _seekLimit = 0;

                switch (mode)
                {
                case FileMode.CreateNew:     // if the file exists, IOException is thrown
                    if (exists)
                    {
                        throw new IOException("", (int)IOException.IOExceptionErrorCode.PathAlreadyExists);
                    }
                    _nativeFileStream = new NativeFileStream(_fileName, bufferSize);
                    break;

                case FileMode.Create:     // if the file exists, it should be overwritten
                    _nativeFileStream = new NativeFileStream(_fileName, bufferSize);
                    if (exists)
                    {
                        _nativeFileStream.SetLength(0);
                    }
                    break;

                case FileMode.Open:     // if the file does not exist, IOException/FileNotFound is thrown
                    if (!exists)
                    {
                        throw new IOException("", (int)IOException.IOExceptionErrorCode.FileNotFound);
                    }
                    _nativeFileStream = new NativeFileStream(_fileName, bufferSize);
                    break;

                case FileMode.OpenOrCreate:     // if the file does not exist, it is created
                    _nativeFileStream = new NativeFileStream(_fileName, bufferSize);
                    break;

                case FileMode.Truncate:     // the file would be overwritten. if the file does not exist, IOException/FileNotFound is thrown
                    if (!exists)
                    {
                        throw new IOException("", (int)IOException.IOExceptionErrorCode.FileNotFound);
                    }
                    _nativeFileStream = new NativeFileStream(_fileName, bufferSize);
                    _nativeFileStream.SetLength(0);
                    break;

                case FileMode.Append:     // Opens the file if it exists and seeks to the end of the file. Append can only be used in conjunction with FileAccess.Write
                    // Attempting to seek to a position before the end of the file will throw an IOException and any attempt to read fails and throws an NotSupportedException
                    if (access != FileAccess.Write)
                    {
                        throw new ArgumentException();
                    }
                    _nativeFileStream = new NativeFileStream(_fileName, bufferSize);
                    _seekLimit        = _nativeFileStream.Seek(0, (uint)SeekOrigin.End);
                    break;

                    // We've already checked the mode value previously, so no need for default
                    //default:
                    //    throw new ArgumentOutOfRangeException();
                }

                // Now that we have a valid NativeFileStream, we add it to the FileRecord, so it could gets clean up
                // in case an eject or force format
                _fileRecord.NativeFileStream = _nativeFileStream;

                // Retrive the filesystem capabilities
                _nativeFileStream.GetStreamProperties(out _canRead, out _canWrite, out _canSeek);

                // If the file is readonly, regardless of the filesystem capability, we'll turn off write
                if (isReadOnly)
                {
                    _canWrite = false;
                }

                // Make sure the requests (wantsRead / wantsWrite) matches the filesystem capabilities (canRead / canWrite)
                if ((wantsRead && !_canRead) || (wantsWrite && !_canWrite))
                {
                    throw new IOException("", (int)IOException.IOExceptionErrorCode.UnauthorizedAccess);
                }

                // finally, adjust the _canRead / _canWrite to match the requests
                if (!wantsWrite)
                {
                    _canWrite = false;
                }
                else if (!wantsRead)
                {
                    _canRead = false;
                }
            }
            catch
            {
                // something went wrong, clean up and re-throw the exception
                if (_nativeFileStream != null)
                {
                    _nativeFileStream.Close();
                }

                FileSystemManager.RemoveFromOpenList(_fileRecord);

                throw;
            }
        }
示例#13
0
 public FixedFileSystemManager()
 {
     _fsm = new FileSystemManager(Guid.NewGuid().ToString());
 }
示例#14
0
        private static string[] GetChildren(string path, string searchPattern, bool isDirectory)
        {
            // path and searchPattern validation in Path.GetFullPath() and Path.NormalizePath()

            path = Path.GetFullPath(path);

            if (!Directory.Exists(path))
            {
                throw new IOException("", (int)IOException.IOExceptionErrorCode.DirectoryNotFound);
            }

            Path.NormalizePath(searchPattern, true);

            var fileNames = new ArrayList();

            var root = Path.GetPathRoot(path);

            if (false && string.Equals(root, path))   //TODO check to see it always go here
            /// This is special case. Return all the volumes.
            /// Note this will not work, once we start having \\server\share like paths.

            {
                if (isDirectory)
                {
                    var volumes = DriveInfo.GetDrives();
                    var count   = volumes.Length;
                    for (var i = 0; i < count; i++)
                    {
                        fileNames.Add(volumes[i].RootDirectory.Name);
                    }
                }
            }
            else
            {
                var record = FileSystemManager.AddToOpenListForRead(path);
                IFileSystemEntryFinder ff = null;
                try {
                    ff = DriveInfo.GetForPath(path).Find(path, searchPattern);

                    var targetAttribute = (isDirectory ? FileAttributes.Directory : 0);

                    var fileinfo = ff.GetNext();

                    while (fileinfo != null)
                    {
                        if ((fileinfo.Attributes & FileAttributes.Directory) == targetAttribute)
                        {
                            fileNames.Add(fileinfo.FileName);
                        }

                        fileinfo = ff.GetNext();
                    }
                }
                finally {
                    if (ff != null)
                    {
                        ff.Close();
                    }
                    FileSystemManager.RemoveFromOpenList(record);
                }
            }

            return((string[])fileNames.ToArray(typeof(string)));
        }
示例#15
0
        private static string[] GetChildren(string path, string searchPattern, bool isDirectory)
        {
            // path and searchPattern validation in Path.GetFullPath() and Path.NormalizePath()

            path = Path.GetFullPath(path);

            if (!Directory.Exists(path))
            {
                throw new IOException("", (int)IOException.IOExceptionErrorCode.DirectoryNotFound);
            }

            Path.NormalizePath(searchPattern, true);

            ArrayList fileNames = new ArrayList();

            string root = Path.GetPathRoot(path);

            if (String.Equals(root, path))
            {
                /// This is special case. Return all the volumes.
                /// Note this will not work, once we start having \\server\share like paths.

                if (isDirectory)
                {
                    VolumeInfo[] volumes = VolumeInfo.GetVolumes();
                    int          count   = volumes.Length;
                    for (int i = 0; i < count; i++)
                    {
                        fileNames.Add(volumes[i].RootDirectory);
                    }
                }
            }
            else
            {
                Object         record = FileSystemManager.AddToOpenListForRead(path);
                NativeFindFile ff     = null;
                try
                {
                    ff = new NativeFindFile(path, searchPattern);

                    uint targetAttribute = (isDirectory ? (uint)FileAttributes.Directory : 0);

                    NativeFileInfo fileinfo = ff.GetNext();

                    while (fileinfo != null)
                    {
                        if ((fileinfo.Attributes & (uint)FileAttributes.Directory) == targetAttribute)
                        {
                            fileNames.Add(fileinfo.FileName);
                        }

                        fileinfo = ff.GetNext();
                    }
                }
                finally
                {
                    if (ff != null)
                    {
                        ff.Close();
                    }
                    FileSystemManager.RemoveFromOpenList(record);
                }
            }

            return((String[])fileNames.ToArray(typeof(String)));
        }