Exemple #1
0
        private async Task MoveDirectoryAsync(string sourceFullPath, string destFullPath)
        {
            StorageFolder sourceFolder = await StorageFolder.GetFolderFromPathAsync(sourceFullPath).TranslateWinRTTask(sourceFullPath, isDirectory: true);

            // WinRT doesn't support move, only rename
            // If parents are the same, just rename.
            string sourceParent, sourceFolderName, destParent, destFolderName;

            PathHelpers.SplitDirectoryFile(sourceFullPath, out sourceParent, out sourceFolderName);
            PathHelpers.SplitDirectoryFile(destFullPath, out destParent, out destFolderName);

            // same parent folder
            if (String.Equals(sourceParent, destParent, StringComparison.OrdinalIgnoreCase))
            {
                // not the same subfolder
                if (!String.Equals(sourceFolderName, destFolderName, StringComparison.OrdinalIgnoreCase))
                {
                    await sourceFolder.RenameAsync(destFolderName).TranslateWinRTTask(destFullPath, isDirectory: true);
                }
                // else : nothing to do
            }
            else
            {
                // Otherwise, create the destination and move each item recursively.
                // We could do a copy, which would be safer in case of a failure
                // We do a move because it has the perf characteristics that match the win32 move
                StorageFolder destFolder = await CreateDirectoryAsync(destFullPath, failIfExists : true).ConfigureAwait(false);

                await MoveDirectoryAsync(sourceFolder, destFolder).ConfigureAwait(false);
            }
        }
Exemple #2
0
        private async Task <StorageFolder> CreateDirectoryAsync(string fullPath, bool failIfExists)
        {
            if (fullPath.Length >= Interop.Kernel32.MAX_DIRECTORY_PATH)
            {
                throw new PathTooLongException(SR.IO_PathTooLong);
            }

            Stack <string> stackDir      = new Stack <string>();
            StorageFolder  workingFolder = null;
            string         workingPath   = fullPath;

            // walk up the path until we can get a directory
            while (workingFolder == null)
            {
                try
                {
                    workingFolder = await StorageFolder.GetFolderFromPathAsync(workingPath).TranslateWinRTTask(workingPath, isDirectory: true);
                }
                catch (IOException) { }
                catch (UnauthorizedAccessException) { }

                if (workingFolder == null)
                {
                    // we couldn't get the directory, we'll need to create it
                    string folderName = null;
                    PathHelpers.SplitDirectoryFile(workingPath, out workingPath, out folderName);

                    if (String.IsNullOrEmpty(folderName))
                    {
                        // we reached the root and it did not exist.  we can't create roots.
                        throw Win32Marshal.GetExceptionForWin32Error(Interop.Errors.ERROR_PATH_NOT_FOUND, workingPath);
                    }

                    stackDir.Push(folderName);
                    Debug.Assert(!String.IsNullOrEmpty(workingPath));
                }
            }

            Debug.Assert(workingFolder != null);

            if (failIfExists && (stackDir.Count == 0))
            {
                throw Win32Marshal.GetExceptionForWin32Error(Interop.Errors.ERROR_ALREADY_EXISTS, fullPath);
            }

            // we have work to do.  if stackDir is empty it means we were passed a path to an existing directory.
            while (stackDir.Count > 0)
            {
                // use CreationCollisionOption.OpenIfExists to address a race conditions when creating directories
                workingFolder = await workingFolder.CreateFolderAsync(stackDir.Pop(), CreationCollisionOption.OpenIfExists).TranslateWinRTTask(fullPath, isDirectory: true);
            }

            return(workingFolder);
        }
Exemple #3
0
        private async Task CopyFileAsync(string sourceFullPath, string destFullPath, bool overwrite)
        {
            StorageFile file = await StorageFile.GetFileFromPathAsync(sourceFullPath).TranslateWinRTTask(sourceFullPath);

            string destDirectory, destFileName;

            PathHelpers.SplitDirectoryFile(destFullPath, out destDirectory, out destFileName);

            StorageFolder destFolder = await StorageFolder.GetFolderFromPathAsync(destDirectory).TranslateWinRTTask(destDirectory, isDirectory: true);

            await file.CopyAsync(destFolder, destFileName, overwrite?NameCollisionOption.ReplaceExisting : NameCollisionOption.FailIfExists).TranslateWinRTTask(sourceFullPath);
        }
Exemple #4
0
        private static async Task <IStorageItem> GetStorageItemAsync(string fullPath)
        {
            string directoryPath, itemName;

            PathHelpers.SplitDirectoryFile(fullPath, out directoryPath, out itemName);

            StorageFolder parent = await StorageFolder.GetFolderFromPathAsync(directoryPath).TranslateWinRTTask(directoryPath, isDirectory: true);

            if (String.IsNullOrEmpty(itemName))
            {
                return(parent);
            }

            return(await parent.GetItemAsync(itemName).TranslateWinRTTask(fullPath));
        }
Exemple #5
0
        private async Task <bool> DirectoryExistsAsync(string fullPath)
        {
            string directoryPath = null, fileName = null;

            PathHelpers.SplitDirectoryFile(fullPath, out directoryPath, out fileName);

            // Rather than call await StorageFolder.GetFolderFromPathAsync(fullPath); and catch FileNotFoundException
            // we try to avoid the exception by calling TryGetItemAsync.
            // We can still hit an exception if the parent directory doesn't exist but it does provide better performance
            // for the existing parent/non-existing directory case and avoids a first chance exception which is a developer
            // pain point.

            StorageFolder parent = null;

            try
            {
                parent = await StorageFolder.GetFolderFromPathAsync(directoryPath).TranslateWinRTTask(directoryPath, isDirectory: true);
            }
            catch (IOException) { }
            catch (UnauthorizedAccessException) { }

            if (String.IsNullOrEmpty(fileName))
            {
                // we were given a root
                return(parent != null);
            }

            if (parent != null)
            {
                StorageFolder folder = await parent.TryGetItemAsync(fileName).TranslateWinRTTask(fullPath, isDirectory: true) as StorageFolder;

                return(folder != null);
            }
            else
            {
                // it's possible we don't have access to the parent but do have access to this folder
                try
                {
                    StorageFolder folder = await StorageFolder.GetFolderFromPathAsync(fullPath).TranslateWinRTTask(fullPath, isDirectory: true);

                    return(folder != null);
                }
                catch (IOException) { }
                catch (UnauthorizedAccessException) { }
            }

            return(false);
        }
Exemple #6
0
        private async Task <bool> FileExistsAsync(string fullPath)
        {
            string directoryPath = null, fileName = null;

            PathHelpers.SplitDirectoryFile(fullPath, out directoryPath, out fileName);

            if (String.IsNullOrEmpty(fileName))
            {
                // No filename was provided
                return(false);
            }

            // Rather than call await StorageFile.GetFileFromPathAsync(fullPath); and catch FileNotFoundException
            // we try to avoid the exception by calling TryGetItemAsync.
            // We can still hit an exception if the directory doesn't exist but it does provide better performance
            // for the existing folder/non-existing file case and avoids a first chance exception which is a developer
            // pain point.

            StorageFolder parent = null;

            try
            {
                parent = await StorageFolder.GetFolderFromPathAsync(directoryPath).TranslateWinRTTask(directoryPath);
            }
            catch (IOException) { }
            catch (UnauthorizedAccessException) { }

            StorageFile file = null;

            if (parent != null)
            {
                // The expectation is that this API will never throw, thus it is missing TranslateWinRTTask
                file = await parent.TryGetItemAsync(fileName).TranslateWinRTTask(fullPath) as StorageFile;
            }
            else
            {
                // it's possible we don't have access to the parent but do have access to this file
                try
                {
                    file = await StorageFile.GetFileFromPathAsync(fullPath).TranslateWinRTTask(fullPath);
                }
                catch (IOException) { }
                catch (UnauthorizedAccessException) { }
            }

            return((file != null) ? file.IsAvailable : false);
        }
Exemple #7
0
        private async Task MoveFileAsync(string sourceFullPath, string destFullPath)
        {
            StorageFile file = await StorageFile.GetFileFromPathAsync(sourceFullPath).TranslateWinRTTask(sourceFullPath);

            string destDirectory, destFileName;

            PathHelpers.SplitDirectoryFile(destFullPath, out destDirectory, out destFileName);

            // Win32 MoveFileEx will return success if source and destination are the same.
            // Comparison is safe here as the caller has normalized both paths.
            if (!sourceFullPath.Equals(destFullPath, StringComparison.OrdinalIgnoreCase))
            {
                StorageFolder destFolder = await StorageFolder.GetFolderFromPathAsync(destDirectory).TranslateWinRTTask(destDirectory, isDirectory: true);

                await file.MoveAsync(destFolder, destFileName, NameCollisionOption.FailIfExists).TranslateWinRTTask(sourceFullPath);
            }
        }
            // Similar to WinRTFileSystem.TryGetStorageItemAsync but we only
            // want to capture exceptions that are not related to file not
            // found.  This matches the behavior of the Win32 implementation.
            private async Task RefreshAsync()
            {
                string directoryPath, itemName;

                _item = null;
                _initializationException = null;

                try
                {
                    PathHelpers.SplitDirectoryFile(_fullPath, out directoryPath, out itemName);

                    StorageFolder parent = null;

                    try
                    {
                        parent = await StorageFolder.GetFolderFromPathAsync(directoryPath).TranslateWinRTTask(directoryPath, isDirectory: true);
                    }
                    catch (DirectoryNotFoundException)
                    {
                        // Ignore DirectoryNotFound, in this case we just return null;
                    }

                    if (String.IsNullOrEmpty(itemName) || null == parent)
                    {
                        _item = parent;
                    }
                    else
                    {
                        _item = await parent.TryGetItemAsync(itemName).TranslateWinRTTask(_fullPath);
                    }
                }
                catch (Exception e)
                {
                    _initializationException = ExceptionDispatchInfo.Capture(e);
                }
            }
Exemple #9
0
        private async Task <FileStreamBase> OpenAsync(string fullPath, FileMode mode, FileAccess access, FileShare share, int bufferSize, FileOptions options, FileStream parent)
        {
            // When trying to open the root directory, we need to throw an Access Denied
            if (PathInternal.GetRootLength(fullPath) == fullPath.Length)
            {
                throw Win32Marshal.GetExceptionForWin32Error(Interop.Errors.ERROR_ACCESS_DENIED, fullPath);
            }

            // Win32 CreateFile returns ERROR_PATH_NOT_FOUND when given a path that ends with '\'
            if (PathHelpers.EndsInDirectorySeparator(fullPath))
            {
                throw Win32Marshal.GetExceptionForWin32Error(Interop.Errors.ERROR_PATH_NOT_FOUND, fullPath);
            }

            StorageFile file = null;

            // FileMode
            if (mode == FileMode.Open || mode == FileMode.Truncate)
            {
                file = await StorageFile.GetFileFromPathAsync(fullPath).TranslateWinRTTask(fullPath);
            }
            else
            {
                CreationCollisionOption collisionOptions;

                switch (mode)
                {
                case FileMode.Create:
                    collisionOptions = CreationCollisionOption.ReplaceExisting;
                    break;

                case FileMode.CreateNew:
                    collisionOptions = CreationCollisionOption.FailIfExists;
                    break;

                case FileMode.Append:
                case FileMode.OpenOrCreate:
                default:
                    collisionOptions = CreationCollisionOption.OpenIfExists;
                    break;
                }

                string directoryPath, fileName;
                PathHelpers.SplitDirectoryFile(fullPath, out directoryPath, out fileName);

                StorageFolder directory = await StorageFolder.GetFolderFromPathAsync(directoryPath).TranslateWinRTTask(directoryPath, isDirectory: true);

                file = await directory.CreateFileAsync(fileName, collisionOptions).TranslateWinRTTask(fullPath);
            }

            // FileAccess: WinRT doesn't support FileAccessMode.Write so we upgrade to ReadWrite
            FileAccessMode accessMode = ((access & FileAccess.Write) != 0) ? FileAccessMode.ReadWrite : FileAccessMode.Read;

            // FileShare: cannot translate StorageFile uses a different sharing model (oplocks) that is controlled via FileAccessMode

            // FileOptions: ignore most values of FileOptions as they are hints and are not supported by WinRT.
            // FileOptions.Encrypted is not a hint, and not supported by WinRT, but there is precedent for ignoring this (FAT).
            // FileOptions.DeleteOnClose should result in an UnauthorizedAccessException when
            //   opening a file that can only be read, but we cannot safely reproduce that behavior
            //   in WinRT without actually deleting the file.
            //   Instead the failure will occur in the finalizer for WinRTFileStream and be ignored.

            // open our stream
            Stream stream = (await file.OpenAsync(accessMode).TranslateWinRTTask(fullPath)).AsStream(bufferSize);

            if (mode == FileMode.Append)
            {
                // seek to end.
                stream.Seek(0, SeekOrigin.End);
            }
            else if (mode == FileMode.Truncate)
            {
                // truncate stream to 0
                stream.SetLength(0);
            }

            return(new WinRTFileStream(stream, file, access, options, parent));
        }