public static void Delete(String path, bool recursive) { String fullPath = PathHelpers.GetFullPathInternal(path); FileSystem.Current.RemoveDirectory(fullPath, recursive); }
public static void SetLastAccessTime(String path, DateTime lastAccessTime) { String fullPath = PathHelpers.GetFullPathInternal(path); FileSystem.Current.SetLastAccessTime(fullPath, lastAccessTime, asDirectory: true); }
public static void SetLastAccessTimeUtc(String path, DateTime lastAccessTimeUtc) { String fullPath = PathHelpers.GetFullPathInternal(path); FileSystem.Current.SetLastAccessTime(fullPath, File.GetUtcDateTimeOffset(lastAccessTimeUtc), asDirectory: true); }
public static void SetAttributes(String path, FileAttributes fileAttributes) { String fullPath = PathHelpers.GetFullPathInternal(path); FileSystem.Current.SetAttributes(fullPath, fileAttributes); }
public static void SetCreationTime(String path, DateTime creationTime) { String fullPath = PathHelpers.GetFullPathInternal(path); FileSystem.Current.SetCreationTime(fullPath, creationTime, asDirectory: true); }
private async Task <FileStreamBase> OpenAsync(string fullPath, FileMode mode, FileAccess access, FileShare share, int bufferSize, FileOptions options, FileStream parent) { // Win32 CreateFile returns ERROR_PATH_NOT_FOUND when given a path that ends with '\' if (PathHelpers.EndsInDirectorySeparator(fullPath)) { throw Win32Marshal.GetExceptionForWin32Error(Interop.mincore.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)); }
public void MoveTo(String destDirName) { if (destDirName == null) { throw new ArgumentNullException("destDirName"); } if (destDirName.Length == 0) { throw new ArgumentException(SR.Argument_EmptyFileName, "destDirName"); } Contract.EndContractBlock(); String fullDestDirName = PathHelpers.GetFullPathInternal(destDirName); if (fullDestDirName[fullDestDirName.Length - 1] != Path.DirectorySeparatorChar) { fullDestDirName = fullDestDirName + PathHelpers.DirectorySeparatorCharAsString; } String fullSourcePath; if (FullPath.Length > 0 && FullPath[FullPath.Length - 1] == Path.DirectorySeparatorChar) { fullSourcePath = FullPath; } else { fullSourcePath = FullPath + PathHelpers.DirectorySeparatorCharAsString; } if (PathInternal.IsDirectoryTooLong(fullSourcePath)) { throw new PathTooLongException(SR.IO_PathTooLong); } if (PathInternal.IsDirectoryTooLong(fullDestDirName)) { throw new PathTooLongException(SR.IO_PathTooLong); } StringComparison pathComparison = PathInternal.StringComparison; if (String.Equals(fullSourcePath, fullDestDirName, pathComparison)) { throw new IOException(SR.IO_SourceDestMustBeDifferent); } String sourceRoot = Path.GetPathRoot(fullSourcePath); String destinationRoot = Path.GetPathRoot(fullDestDirName); if (!String.Equals(sourceRoot, destinationRoot, pathComparison)) { throw new IOException(SR.IO_SourceDestMustHaveSameRoot); } FileSystem.Current.MoveDirectory(FullPath, fullDestDirName); FullPath = fullDestDirName; OriginalPath = destDirName; DisplayPath = GetDisplayName(OriginalPath, FullPath); // Flush any cached information about the directory. Invalidate(); }
public static DateTime GetCreationTime(String path) { String fullPath = PathHelpers.GetFullPathInternal(path); return(FileSystem.Current.GetCreationTime(fullPath).DateTime); }
public static void SetLastWriteTimeUtc(String path, DateTime lastWriteTime) { String fullPath = PathHelpers.GetFullPathInternal(path); FileSystem.Current.SetLastWriteTime(fullPath, GetUtcDateTimeOffset(lastWriteTime), asDirectory: false); }
public override void CreateDirectory(string fullPath) { // NOTE: This logic is primarily just carried forward from Win32FileSystem.CreateDirectory. int length = fullPath.Length; // We need to trim the trailing slash or the code will try to create 2 directories of the same name. if (length >= 2 && PathHelpers.EndsInDirectorySeparator(fullPath)) { length--; } // For paths that are only // or /// if (length == 2 && PathInternal.IsDirectorySeparator(fullPath[1])) { throw new IOException(SR.Format(SR.IO_CannotCreateDirectory, fullPath)); } // We can save a bunch of work if the directory we want to create already exists. if (DirectoryExists(fullPath)) { return; } // Attempt to figure out which directories don't exist, and only create the ones we need. bool somepathexists = false; Stack <string> stackDir = new Stack <string>(); int lengthRoot = PathInternal.GetRootLength(fullPath); if (length > lengthRoot) { int i = length - 1; while (i >= lengthRoot && !somepathexists) { string dir = fullPath.Substring(0, i + 1); if (!DirectoryExists(dir)) // Create only the ones missing { stackDir.Push(dir); } else { somepathexists = true; } while (i > lengthRoot && !PathInternal.IsDirectorySeparator(fullPath[i])) { i--; } i--; } } int count = stackDir.Count; if (count == 0 && !somepathexists) { string root = Directory.InternalGetDirectoryRoot(fullPath); if (!DirectoryExists(root)) { throw Interop.GetExceptionForIoErrno(Interop.Error.ENOENT.Info(), fullPath, isDirectory: true); } return; } // Create all the directories int result = 0; Interop.ErrorInfo firstError = default(Interop.ErrorInfo); string errorString = fullPath; while (stackDir.Count > 0) { string name = stackDir.Pop(); if (name.Length >= MaxDirectoryPath) { throw new PathTooLongException(SR.IO_PathTooLong); } result = Interop.Sys.MkDir(name, (int)Interop.Sys.Permissions.S_IRWXU); if (result < 0 && firstError.Error == 0) { Interop.ErrorInfo errorInfo = Interop.Sys.GetLastErrorInfo(); // While we tried to avoid creating directories that don't // exist above, there are a few cases that can fail, e.g. // a race condition where another process or thread creates // the directory first, or there's a file at the location. if (errorInfo.Error != Interop.Error.EEXIST) { firstError = errorInfo; } else if (FileExists(name) || (!DirectoryExists(name, out errorInfo) && errorInfo.Error == Interop.Error.EACCES)) { // If there's a file in this directory's place, or if we have ERROR_ACCESS_DENIED when checking if the directory already exists throw. firstError = errorInfo; errorString = name; } } } // Only throw an exception if creating the exact directory we wanted failed to work correctly. if (result < 0 && firstError.Error != 0) { throw Interop.GetExceptionForIoErrno(firstError, errorString, isDirectory: true); } }
public DirectoryInfo(string path) { Init(originalPath: PathHelpers.ShouldReviseDirectoryPathToCurrent(path) ? "." : path, fullPath: Path.GetFullPath(path), isNormalized: true); }
internal FileSystemEnumerable( string userPath, string searchPattern, SearchOption searchOption, SearchTarget searchTarget, Func <string, bool, T> translateResult) { // Basic validation of the input path if (userPath == null) { throw new ArgumentNullException("path"); } if (string.IsNullOrWhiteSpace(userPath)) { throw new ArgumentException(SR.Argument_EmptyPath, "path"); } // Validate and normalize the search pattern. If after doing so it's empty, // matching Win32 behavior we can skip all additional validation and effectively // return an empty enumerable. searchPattern = NormalizeSearchPattern(searchPattern); if (searchPattern.Length > 0) { PathHelpers.CheckSearchPattern(searchPattern); PathHelpers.ThrowIfEmptyOrRootedPath(searchPattern); // If the search pattern contains any paths, make sure we factor those into // the user path, and then trim them off. int lastSlash = searchPattern.LastIndexOf(Path.DirectorySeparatorChar); if (lastSlash >= 0) { if (lastSlash >= 1) { userPath = Path.Combine(userPath, searchPattern.Substring(0, lastSlash)); } searchPattern = searchPattern.Substring(lastSlash + 1); } // Typically we shouldn't see either of these cases, an upfront check is much faster foreach (char c in searchPattern) { if (c == '\\' || c == '[') { // We need to escape any escape characters in the search pattern searchPattern = searchPattern.Replace(@"\", @"\\"); // And then escape '[' to prevent it being picked up as a wildcard searchPattern = searchPattern.Replace(@"[", @"\["); break; } } string fullPath = Path.GetFullPath(userPath); // Store everything for the enumerator _initialDirectory = new PathPair(userPath, fullPath); _searchPattern = searchPattern; _searchOption = searchOption; _includeFiles = (searchTarget & SearchTarget.Files) != 0; _includeDirectories = (searchTarget & SearchTarget.Directories) != 0; _translateResult = translateResult; } // Open the first enumerator so that any errors are propagated synchronously. _firstEnumerator = Enumerate(); }
private void EnsureStatInitialized() { if (_fileinfoInitialized == -1) { Refresh(); } if (_fileinfoInitialized != 0) { int errno = _fileinfoInitialized; _fileinfoInitialized = -1; var errorInfo = new Interop.ErrorInfo(errno); // Windows distinguishes between whether the directory or the file isn't found, // and throws a different exception in these cases. We attempt to approximate that // here; there is a race condition here, where something could change between // when the error occurs and our checks, but it's the best we can do, and the // worst case in such a race condition (which could occur if the file system is // being manipulated concurrently with these checks) is that we throw a // FileNotFoundException instead of DirectoryNotFoundexception. // directoryError is true only if a FileNotExists error was provided and the parent // directory of the file represented by _fullPath is nonexistent bool directoryError = (errorInfo.Error == Interop.Error.ENOENT && !Directory.Exists(Path.GetDirectoryName(PathHelpers.TrimEndingDirectorySeparator(_fullPath)))); // The destFile's path is invalid throw Interop.GetExceptionForIoErrno(errorInfo, _fullPath, directoryError); } }
public static DateTime GetLastAccessTime(String path) { String fullPath = PathHelpers.GetFullPathInternal(path); return(FileSystem.Current.GetLastAccessTime(fullPath).LocalDateTime); }
private void Init(String path, FileMode mode, FileAccess access, FileShare share, int bufferSize, FileOptions options) { if (path == null) { throw new ArgumentNullException("path", SR.ArgumentNull_Path); } if (path.Length == 0) { throw new ArgumentException(SR.Argument_EmptyPath, "path"); } // don't include inheritable in our bounds check for share FileShare tempshare = share & ~FileShare.Inheritable; String badArg = null; if (mode < FileMode.CreateNew || mode > FileMode.Append) { badArg = "mode"; } else if (access < FileAccess.Read || access > FileAccess.ReadWrite) { badArg = "access"; } else if (tempshare < FileShare.None || tempshare > (FileShare.ReadWrite | FileShare.Delete)) { badArg = "share"; } if (badArg != null) { throw new ArgumentOutOfRangeException(badArg, SR.ArgumentOutOfRange_Enum); } // NOTE: any change to FileOptions enum needs to be matched here in the error validation if (options != FileOptions.None && (options & ~(FileOptions.WriteThrough | FileOptions.Asynchronous | FileOptions.RandomAccess | FileOptions.DeleteOnClose | FileOptions.SequentialScan | FileOptions.Encrypted | (FileOptions)0x20000000 /* NoBuffering */)) != 0) { throw new ArgumentOutOfRangeException("options", SR.ArgumentOutOfRange_Enum); } if (bufferSize <= 0) { throw new ArgumentOutOfRangeException("bufferSize", SR.ArgumentOutOfRange_NeedPosNum); } // Write access validation if ((access & FileAccess.Write) == 0) { if (mode == FileMode.Truncate || mode == FileMode.CreateNew || mode == FileMode.Create || mode == FileMode.Append) { // No write access throw new ArgumentException(SR.Format(SR.Argument_InvalidFileModeAndAccessCombo, mode, access)); } } string fullPath = PathHelpers.GetFullPathInternal(path); // Prevent access to your disk drives as raw block devices. if (fullPath.StartsWith("\\\\.\\", StringComparison.Ordinal)) { throw new ArgumentException(SR.Arg_DevicesNotSupported); } #if !PLATFORM_UNIX // Check for additional invalid characters. Most invalid characters were checked above // in our call to Path.GetFullPath(path); if (HasAdditionalInvalidCharacters(fullPath)) { throw new ArgumentException(SR.Argument_InvalidPathChars); } if (fullPath.IndexOf(':', 2) != -1) { throw new NotSupportedException(SR.Argument_PathFormatNotSupported); } #endif if ((access & FileAccess.Read) != 0 && mode == FileMode.Append) { throw new ArgumentException(SR.Argument_InvalidAppendMode); } this._innerStream = FileSystem.Current.Open(fullPath, mode, access, share, bufferSize, options, this); }
[System.Security.SecuritySafeCritical] // auto-generated public static DateTime GetLastWriteTimeUtc(String path) { String fullPath = PathHelpers.GetFullPathInternal(path); return(FileSystem.Current.GetLastWriteTime(fullPath).UtcDateTime); }
public override void CreateDirectory(string fullPath) { if (PathInternal.IsDirectoryTooLong(fullPath)) { throw new PathTooLongException(SR.IO_PathTooLong); } // We can save a bunch of work if the directory we want to create already exists. This also // saves us in the case where sub paths are inaccessible (due to ERROR_ACCESS_DENIED) but the // final path is accessible and the directory already exists. For example, consider trying // to create c:\Foo\Bar\Baz, where everything already exists but ACLS prevent access to c:\Foo // and c:\Foo\Bar. In that case, this code will think it needs to create c:\Foo, and c:\Foo\Bar // and fail to due so, causing an exception to be thrown. This is not what we want. if (DirectoryExists(fullPath)) { return; } List <string> stackDir = new List <string>(); // Attempt to figure out which directories don't exist, and only // create the ones we need. Note that InternalExists may fail due // to Win32 ACL's preventing us from seeing a directory, and this // isn't threadsafe. bool somepathexists = false; int length = fullPath.Length; // We need to trim the trailing slash or the code will try to create 2 directories of the same name. if (length >= 2 && PathHelpers.EndsInDirectorySeparator(fullPath)) { length--; } int lengthRoot = PathInternal.GetRootLength(fullPath); if (length > lengthRoot) { // Special case root (fullpath = X:\\) int i = length - 1; while (i >= lengthRoot && !somepathexists) { String dir = fullPath.Substring(0, i + 1); if (!DirectoryExists(dir)) // Create only the ones missing { stackDir.Add(dir); } else { somepathexists = true; } while (i > lengthRoot && !PathInternal.IsDirectorySeparator(fullPath[i])) { i--; } i--; } } int count = stackDir.Count; // If we were passed a DirectorySecurity, convert it to a security // descriptor and set it in he call to CreateDirectory. Interop.Kernel32.SECURITY_ATTRIBUTES secAttrs = default(Interop.Kernel32.SECURITY_ATTRIBUTES); bool r = true; int firstError = 0; String errorString = fullPath; // If all the security checks succeeded create all the directories while (stackDir.Count > 0) { String name = stackDir[stackDir.Count - 1]; stackDir.RemoveAt(stackDir.Count - 1); r = Interop.Kernel32.CreateDirectory(name, ref secAttrs); if (!r && (firstError == 0)) { int currentError = Marshal.GetLastWin32Error(); // While we tried to avoid creating directories that don't // exist above, there are at least two cases that will // cause us to see ERROR_ALREADY_EXISTS here. InternalExists // can fail because we didn't have permission to the // directory. Secondly, another thread or process could // create the directory between the time we check and the // time we try using the directory. Thirdly, it could // fail because the target does exist, but is a file. if (currentError != Interop.Errors.ERROR_ALREADY_EXISTS) { firstError = currentError; } else { // If there's a file in this directory's place, or if we have ERROR_ACCESS_DENIED when checking if the directory already exists throw. if (File.InternalExists(name) || (!DirectoryExists(name, out currentError) && currentError == Interop.Errors.ERROR_ACCESS_DENIED)) { firstError = currentError; errorString = name; } } } } // We need this check to mask OS differences // Handle CreateDirectory("X:\\") when X: doesn't exist. Similarly for n/w paths. if ((count == 0) && !somepathexists) { String root = Directory.InternalGetDirectoryRoot(fullPath); if (!DirectoryExists(root)) { throw Win32Marshal.GetExceptionForWin32Error(Interop.Errors.ERROR_PATH_NOT_FOUND, root); } return; } // Only throw an exception if creating the exact directory we // wanted failed to work correctly. if (!r && (firstError != 0)) { throw Win32Marshal.GetExceptionForWin32Error(firstError, errorString); } }
public static FileAttributes GetAttributes(String path) { String fullPath = PathHelpers.GetFullPathInternal(path); return(FileSystem.Current.GetAttributes(fullPath)); }
private static bool ShouldUseWinRT(string fullPath, bool isCreate) { // The purpose of this method is to determine if we can access a path // via Win32 or if we need to fallback to WinRT. // We prefer Win32 since it is faster, WinRT's APIs eventually just // call into Win32 after all, but it doesn't provide access to, // brokered paths (like Pictures or Documents) nor does it handle // placeholder files. So we'd like to fall back to WinRT whenever // we can't access a path, or if it known to be a placeholder file. bool useWinRt = false; do { // first use GetFileAttributesEx as it is faster than FindFirstFile and requires minimum permissions Interop.mincore.WIN32_FILE_ATTRIBUTE_DATA data = new Interop.mincore.WIN32_FILE_ATTRIBUTE_DATA(); if (Interop.mincore.GetFileAttributesEx(fullPath, Interop.mincore.GET_FILEEX_INFO_LEVELS.GetFileExInfoStandard, ref data)) { // got the attributes if ((data.fileAttributes & Interop.mincore.FileAttributes.FILE_ATTRIBUTE_DIRECTORY) != 0 || (data.fileAttributes & Interop.mincore.FileAttributes.FILE_ATTRIBUTE_REPARSE_POINT) == 0) { // we have a directory or a file that is not a reparse point // useWinRt = false; break; } else { // we need to get the find data to determine if it is a placeholder file Interop.mincore.WIN32_FIND_DATA findData = new Interop.mincore.WIN32_FIND_DATA(); using (SafeFindHandle handle = Interop.mincore.FindFirstFile(fullPath, ref findData)) { if (!handle.IsInvalid) { // got the find data, use WinRT for placeholder files Debug.Assert((findData.dwFileAttributes & Interop.mincore.FileAttributes.FILE_ATTRIBUTE_DIRECTORY) == 0); Debug.Assert((findData.dwFileAttributes & Interop.mincore.FileAttributes.FILE_ATTRIBUTE_REPARSE_POINT) != 0); useWinRt = findData.dwReserved0 == Interop.mincore.IOReparseOptions.IO_REPARSE_TAG_FILE_PLACEHOLDER; break; } } } } int error = Marshal.GetLastWin32Error(); Debug.Assert(error != Interop.mincore.Errors.ERROR_SUCCESS); if (error == Interop.mincore.Errors.ERROR_ACCESS_DENIED) { // The path was not accessible with Win32, so try WinRT useWinRt = true; break; } else if (error != Interop.mincore.Errors.ERROR_PATH_NOT_FOUND && error != Interop.mincore.Errors.ERROR_FILE_NOT_FOUND) { // We hit some error other than ACCESS_DENIED or NOT_FOUND, // Default to Win32 to provide most accurate error behavior break; } // error was ERROR_PATH_NOT_FOUND or ERROR_FILE_NOT_FOUND // if we are creating a file/directory we cannot assume that Win32 will have access to // the parent directory, so we walk up the path. fullPath = PathHelpers.GetDirectoryNameInternal(fullPath); // only walk up the path if we are creating a file/directory and not at the root } while (isCreate && !String.IsNullOrEmpty(fullPath)); return(useWinRt); }
private void Init(String path, FileMode mode, FileAccess access, FileShare share, int bufferSize, FileOptions options) { if (path == null) { throw new ArgumentNullException("path", SR.ArgumentNull_Path); } if (path.Length == 0) { throw new ArgumentException(SR.Argument_EmptyPath, "path"); } // don't include inheritable in our bounds check for share FileShare tempshare = share & ~FileShare.Inheritable; String badArg = null; if (mode < FileMode.CreateNew || mode > FileMode.Append) { badArg = "mode"; } else if (access < FileAccess.Read || access > FileAccess.ReadWrite) { badArg = "access"; } else if (tempshare < FileShare.None || tempshare > (FileShare.ReadWrite | FileShare.Delete)) { badArg = "share"; } if (badArg != null) { throw new ArgumentOutOfRangeException(badArg, SR.ArgumentOutOfRange_Enum); } // NOTE: any change to FileOptions enum needs to be matched here in the error validation if (options != FileOptions.None && (options & ~(FileOptions.WriteThrough | FileOptions.Asynchronous | FileOptions.RandomAccess | FileOptions.DeleteOnClose | FileOptions.SequentialScan | FileOptions.Encrypted | (FileOptions)0x20000000 /* NoBuffering */)) != 0) { throw new ArgumentOutOfRangeException("options", SR.ArgumentOutOfRange_Enum); } if (bufferSize <= 0) { throw new ArgumentOutOfRangeException("bufferSize", SR.ArgumentOutOfRange_NeedPosNum); } // Write access validation if ((access & FileAccess.Write) == 0) { if (mode == FileMode.Truncate || mode == FileMode.CreateNew || mode == FileMode.Create || mode == FileMode.Append) { // No write access, mode and access disagree but flag access since mode comes first throw new ArgumentException(SR.Format(SR.Argument_InvalidFileModeAndAccessCombo, mode, access), "access"); } } string fullPath = PathHelpers.GetFullPathInternal(path); ValidatePath(fullPath, "path"); if ((access & FileAccess.Read) != 0 && mode == FileMode.Append) { throw new ArgumentException(SR.Argument_InvalidAppendMode, "access"); } this._innerStream = FileSystem.Current.Open(fullPath, mode, access, share, bufferSize, options, this); }