Exemplo n.º 1
0
        public static void Move(string sourceDirName, string destDirName)
        {
            // sourceDirName and destDirName validation in Path.GetFullPath()

            sourceDirName = Path.GetFullPath(sourceDirName);
            destDirName   = Path.GetFullPath(destDirName);

            bool   tryCopyAndDelete = false;
            Object srcRecord        = FileSystemManager.AddToOpenList(sourceDirName);

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

                // If Move() returns false, we'll try doing copy and delete to accomplish the move
                tryCopyAndDelete = !NativeIO.Move(sourceDirName, destDirName);
            }
            finally
            {
                FileSystemManager.RemoveFromOpenList(srcRecord);
            }

            if (tryCopyAndDelete)
            {
                RecursiveCopyAndDelete(sourceDirName, destDirName);
            }
        }
Exemplo n.º 2
0
        // Moves a specified file to a new location and potentially a new file name.
        // This method does work across volumes.
        //
        // The caller must have certain FileIOPermissions.  The caller must
        // have Read and Write permission to
        // sourceFileName and Write
        // permissions to destFileName.
        //
        public static void Move(String sourceFileName, String destFileName)
        {
            // sourceFileName and destFileName validation in Path.GetFullPath()

            sourceFileName = Path.GetFullPath(sourceFileName);
            destFileName   = Path.GetFullPath(destFileName);

            bool tryCopyAndDelete = false;

            // We only need to lock the source, not the dest because if dest is taken
            // Move() will failed at the driver's level anyway. (there will be no conflict even if
            // another thread is creating dest, as only one of the operations will succeed --
            // the native calls are atomic)
            Object srcRecord = FileSystemManager.AddToOpenList(sourceFileName);

            try
            {
                if (!Exists(sourceFileName))
                {
                    throw new IOException("", (int)IOException.IOExceptionErrorCode.FileNotFound);
                }

                //We'll try copy and deleting if Move returns false
                tryCopyAndDelete = !NativeIO.Move(sourceFileName, destFileName);
            }
            finally
            {
                FileSystemManager.RemoveFromOpenList(srcRecord);
            }

            if (tryCopyAndDelete)
            {
                Copy(sourceFileName, destFileName, false, true);
            }
        }
Exemplo n.º 3
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);
            }
        }
Exemplo n.º 4
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);
            }
        }
Exemplo n.º 5
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;
            }
        }