/// <summary> /// Copies an existing file. Overwrites an existing file if <paramref name="overwrite"/> is true /// </summary> /// <param name="source">The file to copy.</param> /// <param name="target">Target file</param> /// <param name="overwrite">true to overwrite existing files</param> /// <param name="createRecursive">Creates parent path if not exists. Decreases copy performance</param> /// <remarks>http://msdn.microsoft.com/en-us/library/c6cfw35a(v=vs.110).aspx</remarks> /// <exception cref="FileSystemIsBusyException">Filesystem is busy</exception> public static void Copy(string source, string target, Boolean overwrite = false, Boolean createRecursive = true) { Contract.Requires(!String.IsNullOrWhiteSpace(source)); Contract.Requires(!String.IsNullOrWhiteSpace(target)); if (String.IsNullOrWhiteSpace(source)) { throw new ArgumentNullException(nameof(source)); } if (String.IsNullOrWhiteSpace(target)) { throw new ArgumentNullException(nameof(target)); } if (createRecursive) { var targetDirectoryPath = QuickIOPath.GetDirectoryName(target); try { QuickIODirectory.Create(targetDirectoryPath, true); } catch (PathAlreadyExistsException) { // yay ignore this! } } int win32Error; if (!QuickIOEngine.CopyFile(source, target, out win32Error, overwrite)) { Win32ErrorCodes.NativeExceptionMapping(!Exists(source) ? target : target, win32Error); } }
///// <summary> ///// Returns the <see cref="Win32FindData"/> from specified <paramref name="fullUncPath"/> ///// </summary> ///// <param name="fullUncPath">Path to the file system entry</param> ///// <returns><see cref="Win32FindData"/></returns> ///// <exception cref="PathNotFoundException">This error is fired if the specified path or a part of them does not exist.</exception> /// /// <summary> /// Returns the <see cref="Win32FindData"/> from specified <paramref name="fullpath"/> /// </summary> /// <param name="fullpath">Path to the file system entry</param> /// <returns><see cref="Win32FindData"/></returns> public static Win32FindData SafeGetFindDataFromPath(string fullpath) { Contract.Requires(!String.IsNullOrWhiteSpace(fullpath)); Win32FindData win32FindData = new Win32FindData(); int win32Error; using (Win32FileHandle fileHandle = FindFirstSafeFileHandle(fullpath, win32FindData, out win32Error)) { // Take care of invalid handles if (fileHandle.IsInvalid) { Win32ErrorCodes.NativeExceptionMapping(fullpath, win32Error); } // Treffer auswerten // Ignore . and .. directories if (!win32FindData.IsSystemDirectoryEntry()) { return(win32FindData); } } return(null); }
/// <summary> /// Deletes the given directory. On request all contents, too. /// </summary> /// <param name="uncDirectoryPath">Path of directory to delete</param> /// <param name="recursive">If <paramref name="recursive"/> is true then all subfolders are also deleted.</param> /// <exception cref="PathNotFoundException">This error is fired if the specified path or a part of them does not exist.</exception> /// <exception cref="DirectoryNotEmptyException">The directory is not empty.</exception> /// <remarks>Function loads every file and attribute. Alls read-only flags will be removed before removing.</remarks> public static void DeleteDirectory(string uncDirectoryPath, bool recursive = false) { Contract.Requires(!String.IsNullOrEmpty(uncDirectoryPath)); // Contents if (recursive) { foreach (Win32FileSystemEntry systemEntry in new Win32FileHandleCollection(QuickIOPath.Combine(uncDirectoryPath, QuickIOPatterns.PathMatchAll))) { // Create hit for current search result var resultPath = QuickIOPath.Combine(uncDirectoryPath, systemEntry.Name); if (systemEntry.IsFile) { DeleteFile(resultPath); } else if (/*is directory here*/ recursive) { DeleteDirectory(resultPath, recursive); } } } // Remove specified if (!Win32SafeNativeMethods.RemoveDirectory(uncDirectoryPath)) { int errorCode = Marshal.GetLastWin32Error(); Win32ErrorCodes.NativeExceptionMapping(uncDirectoryPath, errorCode); } }
public static Boolean TryGetWin32ErrorCode(this HResult hr, out Win32ErrorCodes win32Code) { // Set `win32Code` anyway, just in case the HRESULT's Customer and Facility codes are wrong: UInt16 codeBits = GetCode(hr); win32Code = (Win32ErrorCodes)codeBits; if (IsValidHResult(hr)) { // But only return true or false if the flag bits are correct: if (GetCustomer(hr) == HResultCustomer.MicrosoftDefined) { if (GetFacility(hr) == HResultFacility.Win32) { Boolean hresultSeverityMatchesWin32Code = (GetSeverity(hr) == HResultSeverity.Success && win32Code == Win32ErrorCodes.Success) || (GetSeverity(hr) == HResultSeverity.Failure && win32Code != Win32ErrorCodes.Success); if (hresultSeverityMatchesWin32Code) { return(true); } } } } return(false); }
/// <summary>Creates a Win32 <see cref="HResult"/> value.</summary> public static HResult CreateWin32(Win32ErrorCodes code) { return(Create( isFailure: code != Win32ErrorCodes.Success, isCustomer: false, facility: HResultFacility.Win32, code: (UInt16)Win32ErrorCodes.ErrorCancelled )); }
/// <summary> /// Moves a file /// </summary> /// <param name="sourceFileName">Full source path</param> /// <param name="destFileName">Full target path</param> public static void MoveFile(string sourceFileName, string destFileName) { Contract.Requires(!String.IsNullOrWhiteSpace(sourceFileName)); Contract.Requires(!String.IsNullOrWhiteSpace(destFileName)); if (!Win32SafeNativeMethods.MoveFile(sourceFileName, destFileName)) { Win32ErrorCodes.NativeExceptionMapping(sourceFileName, Marshal.GetLastWin32Error()); } }
/// <summary> /// Gets the <see cref="FileAttributes"/> of the file on the entry. /// </summary> /// <param name="uncPath">The path to the entry. </param> /// <returns>The <see cref="FileAttributes"/> of the file on the entry.</returns> /// <exception cref="PathNotFoundException">This error is fired if the specified path or a part of them does not exist.</exception> internal static FileAttributes GetAttributes(String uncPath) { Contract.Requires(!String.IsNullOrWhiteSpace(uncPath)); int win32Error; var attrs = SafeGetAttributes(uncPath, out win32Error); Win32ErrorCodes.NativeExceptionMapping(uncPath, win32Error); return(( FileAttributes )attrs); }
/// <summary> /// Removes a file. /// </summary> /// <param name="path">Path to the file to remove</param> /// <exception cref="FileNotFoundException">This error is fired if the specified file to remove does not exist.</exception> public static void DeleteFile(String path) { Contract.Requires(!String.IsNullOrWhiteSpace(path)); // Remove all attributes RemoveAllFileAttributes(path); if (!Win32SafeNativeMethods.DeleteFile(path)) { Win32ErrorCodes.NativeExceptionMapping(path, Marshal.GetLastWin32Error()); } }
/// <summary> /// Sets the specified <see cref="FileAttributes"/> of the entry on the specified path. /// </summary> /// <param name="path">The path to the entry.</param> /// <param name="attributes">A bitwise combination of the enumeration values.</param> /// <exception cref="Win32Exception">Unmatched Exception</exception> /// <exception cref="PathNotFoundException">This error is fired if the specified path or a part of them does not exist.</exception> public static FileAttributes SetAttributes(String path, FileAttributes attributes) { Contract.Requires(!String.IsNullOrWhiteSpace(path)); if (!Win32SafeNativeMethods.SetFileAttributes(path, ( uint )attributes)) { var win32Error = Marshal.GetLastWin32Error(); Win32ErrorCodes.NativeExceptionMapping(path, win32Error); } return(attributes); }
/// <summary> /// Creates a new file. /// </summary> /// <exception cref="PathAlreadyExistsException">The specified path already exists.</exception> /// <exception cref="PathNotFoundException">This error is fired if the specified path or a part of them does not exist.</exception> public static void CreateFile(String path, FileAccess fileAccess = FileAccess.Write, FileShare fileShare = FileShare.None, FileMode fileMode = FileMode.Create, FileAttributes fileAttributes = 0) { Contract.Requires(!String.IsNullOrWhiteSpace(path)); using (var fileHandle = Win32SafeNativeMethods.CreateFile(path, fileAccess, fileShare, IntPtr.Zero, fileMode, fileAttributes, IntPtr.Zero)) { var win32Error = Marshal.GetLastWin32Error(); if (fileHandle.IsInvalid) { Win32ErrorCodes.NativeExceptionMapping(path, win32Error); } } }
/// <summary> /// Sets the time at which the file or directory was created (UTC) /// </summary> /// <param name="pathUnc">Affected file or directory</param> /// <param name="utcTime">The time that is to be used (UTC)</param> public static void SetCreationTimeUtc(string pathUnc, DateTime utcTime) { long longTime = utcTime.ToFileTime(); using (SafeFileHandle fileHandle = OpenReadWriteFileSystemEntryHandle(pathUnc)) { if (!Win32SafeNativeMethods.SetCreationFileTime(fileHandle, ref longTime, IntPtr.Zero, IntPtr.Zero)) { int win32Error = Marshal.GetLastWin32Error(); Win32ErrorCodes.NativeExceptionMapping(pathUnc, win32Error); } } }
/// <summary> /// Creates a new directory. If <paramref name="recursive"/> is false, the parent directory must exists. /// </summary> /// <param name="uncDirectoryPath">Directory path</param> /// <param name="recursive">If <paramref name="recursive"/> is false, the parent directory must exist.</param> /// <exception cref="PathAlreadyExistsException">The specified path already exists.</exception> /// <exception cref="PathNotFoundException">This error is fired if the specified path or a part of them does not exist.</exception> public static void CreateDirectory(string uncDirectoryPath, bool recursive = false) { Contract.Requires(!String.IsNullOrEmpty(uncDirectoryPath)); // cancel if path exists if (Exists(uncDirectoryPath)) { return; } // cancel if requested path is root if (QuickIOPath.IsRoot(uncDirectoryPath)) { throw new InvalidOperationException("A root directory cannot be created."); } // create parent directory if accepted if (recursive) { string parent = QuickIOPath.GetDirectoryName(uncDirectoryPath); if (parent == null) { throw new InvalidOperationException("Parent directory does not exists and cannot be created."); } Stack <string> stack = new Stack <string>(); stack.Push(parent); while (stack.Count > 0) { string currentDirectory = stack.Pop(); if (QuickIOPath.IsRoot(currentDirectory)) { if (!QuickIOPath.Exists(currentDirectory)) { throw new InvalidOperationException("A root directory cannot be created."); } } else { // no root path here if (!Win32SafeNativeMethods.CreateDirectory(currentDirectory, IntPtr.Zero)) { Win32ErrorCodes.NativeExceptionMapping(currentDirectory, Marshal.GetLastWin32Error()); } } } } }
/// <summary> /// Sets the dates and times of given directory or file. /// </summary> /// <param name="pathInfo">Affected file or directory</param> /// <param name="creationTimeUtc">The time that is to be used (UTC)</param> /// <param name="lastAccessTimeUtc">The time that is to be used (UTC)</param> /// <param name="lastWriteTimeUtc">The time that is to be used (UTC)</param> public static void SetAllFileTimes(string pathUnc, DateTime creationTimeUtc, DateTime lastAccessTimeUtc, DateTime lastWriteTimeUtc) { long longCreateTime = creationTimeUtc.ToFileTime(); long longAccessTime = lastAccessTimeUtc.ToFileTime(); long longWriteTime = lastWriteTimeUtc.ToFileTime(); using (SafeFileHandle fileHandle = OpenReadWriteFileSystemEntryHandle(pathUnc)) { if (Win32SafeNativeMethods.SetAllFileTimes(fileHandle, ref longCreateTime, ref longAccessTime, ref longWriteTime) == 0) { int win32Error = Marshal.GetLastWin32Error(); Win32ErrorCodes.NativeExceptionMapping(pathUnc, win32Error); } } }
/// <summary> /// Sets the time at which the file or directory was last accessed to (UTC) /// </summary> /// <param name="pathInfo">Affected file or directory</param> /// <param name="utcTime">The time that is to be used (UTC)</param> public static void SetLastAccessTimeUtc(QuickIOPathInfo pathInfo, DateTime utcTime) { Contract.Requires(pathInfo != null); long longTime = utcTime.ToFileTime(); using (SafeFileHandle fileHandle = OpenReadWriteFileSystemEntryHandle(pathInfo.FullNameUnc)) { if (!Win32SafeNativeMethods.SetLastAccessFileTime(fileHandle, IntPtr.Zero, ref longTime, IntPtr.Zero)) { int win32Error = Marshal.GetLastWin32Error(); Win32ErrorCodes.NativeExceptionMapping(pathInfo.FullName, win32Error); } } }
/// <summary> /// Opens a <see cref="FileStream"/> /// </summary> public static FileStream OpenFileStream(string path, FileAccess fileAccess, FileMode fileOption = FileMode.Open, FileShare shareMode = FileShare.Read, Int32 buffer = 0) { Contract.Requires(!String.IsNullOrWhiteSpace(path)); Contract.Ensures(Contract.Result <FileStream>() != null); var fileHandle = Win32SafeNativeMethods.CreateFile(path, fileAccess, shareMode, IntPtr.Zero, fileOption, 0, IntPtr.Zero); var win32Error = Marshal.GetLastWin32Error(); if (fileHandle.IsInvalid) { Win32ErrorCodes.NativeExceptionMapping(path, win32Error); // Throws an exception } return(buffer > 0 ? new FileStream(fileHandle, fileAccess, buffer) : new FileStream(fileHandle, fileAccess)); }
/// <summary> /// Moves a directory /// </summary> /// <param name="from">Fullname to move</param> /// <param name="to">Full targetname</param> /// <param name="overwrite">true to overwrite target</param> /// <exception cref="DirectoryAlreadyExistsException">Target exists</exception> public static void Move(String from, String to, bool overwrite = false) { Contract.Requires(!String.IsNullOrWhiteSpace(from)); Contract.Requires(!String.IsNullOrWhiteSpace(to)); if (!overwrite && Exists(to)) { throw new DirectoryAlreadyExistsException("Target directory already exists.", to); } if (!Win32SafeNativeMethods.MoveFile(from, to)) { int win32Error = Marshal.GetLastWin32Error(); Win32ErrorCodes.NativeExceptionMapping(from, win32Error); } }
/// <summary> /// Sets the dates and times of given directory or file. /// </summary> /// <param name="pathInfo">Affected file or directory</param> /// <param name="creationTimeUtc">The time that is to be used (UTC)</param> /// <param name="lastAccessTimeUtc">The time that is to be used (UTC)</param> /// <param name="lastWriteTimeUtc">The time that is to be used (UTC)</param> public static void SetAllFileTimes(QuickIOPathInfo pathInfo, DateTime creationTimeUtc, DateTime lastAccessTimeUtc, DateTime lastWriteTimeUtc) { Contract.Requires(pathInfo != null); long longCreateTime = creationTimeUtc.ToFileTime(); long longAccessTime = lastAccessTimeUtc.ToFileTime(); long longWriteTime = lastWriteTimeUtc.ToFileTime(); using (SafeFileHandle fileHandle = OpenReadWriteFileSystemEntryHandle(pathInfo.FullNameUnc)) { if (Win32SafeNativeMethods.SetAllFileTimes(fileHandle, ref longCreateTime, ref longAccessTime, ref longWriteTime) == 0) { int win32Error = Marshal.GetLastWin32Error(); Win32ErrorCodes.NativeExceptionMapping(pathInfo.FullName, win32Error); } } }
/// <summary> /// Determines metadata of network shares /// </summary> /// <param name="rootPath">Share to check</param> /// <returns><see cref="QuickIODiskInformation"/></returns> public static QuickIODiskInformation GetDiskInformation(String rootPath) { Contract.Requires(!String.IsNullOrWhiteSpace(rootPath)); Contract.Ensures(Contract.Result <QuickIODiskInformation>() != null); UInt64 freeBytes; UInt64 totalBytes; UInt64 totalFreeBytes; /* PInvoke request */ if (!Win32SafeNativeMethods.GetDiskFreeSpaceEx(rootPath, out freeBytes, out totalBytes, out totalFreeBytes)) { Win32ErrorCodes.NativeExceptionMapping(rootPath, Marshal.GetLastWin32Error()); } return(new QuickIODiskInformation(freeBytes, totalBytes, totalFreeBytes)); }
/// <summary> /// Gets the security information of specified handle from file system /// </summary> /// <param name="sidHandle">Handle to get file security information</param> /// <returns><see cref="CommonObjectSecurity"/>Result</returns> private CommonObjectSecurity ReceiveFileSystemSecurityInformation(out IntPtr sidHandle) { IntPtr zeroHandle = new IntPtr(); IntPtr pSecurityDescriptor = new IntPtr(); try { var namedSecInfoResult = Win32SafeNativeMethods.GetNamedSecurityInfo(PathInfo.FullNameUnc, Win32SecurityObjectType.SeFileObject, Win32FileSystemEntrySecurityInformation.OwnerSecurityInformation | Win32FileSystemEntrySecurityInformation.DaclSecurityInformation, out sidHandle, out zeroHandle, out zeroHandle, out zeroHandle, out pSecurityDescriptor); var win32Error = Marshal.GetLastWin32Error(); // Cancel if call failed if (namedSecInfoResult != 0) { Win32ErrorCodes.NativeExceptionMapping(PathInfo.FullName, win32Error); } var securityDescriptorLength = Win32SafeNativeMethods.GetSecurityDescriptorLength(pSecurityDescriptor); var securityDescriptorDataArray = new byte[securityDescriptorLength]; Marshal.Copy(pSecurityDescriptor, securityDescriptorDataArray, 0, ( int )securityDescriptorLength); CommonObjectSecurity securityInfo; if (PathInfo.Attributes.Contains(FileAttributes.Directory)) { securityInfo = new DirectorySecurity(); securityInfo.SetSecurityDescriptorBinaryForm(securityDescriptorDataArray); } else { securityInfo = new FileSecurity(); securityInfo.SetSecurityDescriptorBinaryForm(securityDescriptorDataArray); } return(securityInfo); } finally { Win32SafeNativeMethods.LocalFree(zeroHandle); Win32SafeNativeMethods.LocalFree(pSecurityDescriptor); } }