public static void files_can_be_created_and_written_and_read_and_copied_in_very_long_paths() { // Create a >255 length path const string path = TempRoot + "\\QIO\\Pseudopseudohypoparathyroidism\\Pneumonoultramicroscopicsilicovolcanoconiosis\\Floccinaucinihilipilification\\Antidisestablishmentarianism\\Honorificabilitudinitatibus\\Donaudampfschiffahrtselektrizitätenhauptbetriebswerkbauunterbeamtengesellschaft"; NativeIO.CreateDirectory(new PathInfo(path), recursive: true); var sampleData = new byte[]{1,2,3,4,5,6,7,8}; var srcFile = new PathInfo(path + "\\example.file.txt"); var dstFile = new PathInfo(path + "\\example.copy.txt"); // write a file using (var fs = NativeIO.OpenFileStream(srcFile, FileAccess.Write, FileMode.Create, FileShare.None)) { fs.Write(sampleData, 4, 4); fs.Write(sampleData, 0, 4); fs.Flush(); } // copy the file elsewhere Assert.True(NativeIO.Exists(srcFile), "Source file can't be found (didn't write correctly?)"); Assert.True(NativeIO.CopyFile(srcFile, dstFile), "Failed to copy file"); Assert.True(NativeIO.Exists(dstFile), "Target file can't be found"); // Check the contents using (var fs = NativeIO.OpenFileStream(srcFile, FileAccess.Read)) { var buf = new byte[8]; var length = fs.Read(buf, 0, 8); Assert.That(length, Is.EqualTo(8)); Assert.That(buf, Is.EquivalentTo(new byte[] { 5, 6, 7, 8, 1, 2, 3, 4 })); } // cleanup NativeIO.DeleteDirectory(new DirectoryDetail(TempRoot + "\\QIO"), recursive: true); }
/// <summary> /// Creates a new directory. If <paramref name="recursive" /> is false, the parent directory must exists. /// </summary> /// <param name="pathInfo"> /// Complete path to create /// </param> /// <param name="recursive">If <paramref name="recursive" /> is false, the parent directory must exist.</param> public static void CreateDirectory(PathInfo pathInfo, bool recursive = false) { if (recursive) { var parent = pathInfo.Parent; if (parent.IsRoot) { // Root if (!parent.Exists) { throw new Exception("Root path does not exists. You cannot create a root this way. " + parent.FullName); } } else if (!parent.Exists) { CreateDirectory(parent, true); } } if (pathInfo.Exists) { return; } bool created = Win32SafeNativeMethods.CreateDirectory(pathInfo.FullNameUnc, IntPtr.Zero); int win32Error = Marshal.GetLastWin32Error(); if (!created) { NativeExceptionMapping(pathInfo.FullName, win32Error); } }
/// <summary> /// Creates the folder information on the basis of the path and the handles /// </summary> /// <param name="pathInfo"><see cref="PathInfo"/></param> /// <param name="win32FindData"><see cref="Win32FindData"/></param> internal DirectoryDetail(PathInfo pathInfo, Win32FindData win32FindData) : base(pathInfo, win32FindData) { if (win32FindData != null) { RetriveDateTimeInformation(win32FindData); } }
/// <summary> /// Adds a file attribute /// </summary> /// <param name="pathInfo">Affected target</param> /// <param name="attribute">Attribute to add</param> /// <returns>true if added. false if already exists in attributes</returns> public static Boolean AddAttribute(PathInfo pathInfo, FileAttributes attribute) { if ((pathInfo.Attributes & attribute) == attribute) { return false; } var attributes = pathInfo.Attributes; attributes |= attribute; SetAttributes(pathInfo, attributes); return true; }
/// <summary> /// Copies a file and overwrite existing files if desired. /// </summary> /// <param name="sourceFilePath">Full source path</param> /// <param name="targetFilePath">Full target path</param> /// <param name="overwrite">true to overwrite existing files</param> /// <returns>True if copy succeeded, false if not. Check last Win32 Error to get further information.</returns> public static bool CopyFile(PathInfo sourceFilePath, PathInfo targetFilePath, bool overwrite = false) { bool failOnExists = !overwrite; bool result = Win32SafeNativeMethods.CopyFile(sourceFilePath.FullNameUnc, targetFilePath.FullNameUnc, failOnExists); if (!result) { int win32Error = Marshal.GetLastWin32Error(); NativeExceptionMapping(sourceFilePath.FullName, win32Error); } return result; }
/// <summary> /// Supply the path to the file or directory and a user or group. /// Access checks are done /// during instantiation to ensure we always have a valid object /// </summary> /// <param name="pathInfo"></param> /// <param name="principal"></param> public FileSecurity(PathInfo pathInfo, WindowsIdentity principal) { if (pathInfo == null) { throw new ArgumentNullException("pathInfo"); } if (principal == null) { throw new ArgumentNullException("principal"); } PathInfo = pathInfo; WindowsIdentity = principal; Refresh(); }
public static void directory_paths_with_more_than_255_characters_are_supported() { var sb = new StringBuilder(TempRoot + "\\QIO"); for (int i = 0; i < 35; i++) { sb.Append("\\Deeper"); sb.Append(i); } var deepPath = new PathInfo(sb.ToString()); Assert.That(deepPath.FullName.Length, Is.GreaterThan(255)); NativeIO.CreateDirectory(deepPath, recursive: true); Assert.IsTrue(NativeIO.Exists(deepPath), "New directory was not created or could not be found"); NativeIO.DeleteDirectory(new DirectoryDetail(TempRoot + "\\QIO"), recursive: true); }
/// <summary> /// Opens a <see cref="FileStream"/> for access at the given path. Ensure stream is correctly disposed. /// </summary> public static FileStream OpenFileStream(PathInfo pathInfo, FileAccess fileAccess, FileMode fileOption = FileMode.Open, FileShare shareMode = FileShare.Read, Int32 buffer = 0) { var fileHandle = Win32SafeNativeMethods.CreateFile(pathInfo.FullNameUnc, fileAccess, shareMode, IntPtr.Zero, fileOption, 0, IntPtr.Zero); var win32Error = Marshal.GetLastWin32Error(); if (fileHandle.IsInvalid) { NativeExceptionMapping(pathInfo.FullName, win32Error); // Throws an exception } return buffer > 0 ? new FileStream(fileHandle, fileAccess, buffer) : new FileStream(fileHandle, fileAccess); }
/// <summary> /// Returns the <see cref="Win32FindData" /> from specified <paramref name="pathInfo" /> /// </summary> /// <param name="pathInfo">Path to the file system entry</param> /// <returns> /// <see cref="Win32FindData" /> /// </returns> public static Win32FindData GetFindDataFromPath(PathInfo pathInfo) { var win32FindData = new Win32FindData(); int win32Error; using (var fileHandle = FindFirstSafeFileHandle(pathInfo.FullNameUnc, win32FindData, out win32Error)) { // Take care of invalid handles if (fileHandle.IsInvalid) { NativeExceptionMapping(pathInfo.FullName, win32Error); } // Ignore . and .. directories if (!IsSystemDirectoryEntry(win32FindData)) { return win32FindData; } } throw new Exception("PathNotFound " + pathInfo.FullName); }
/// <summary> /// Moves a file /// </summary> /// <param name="sourceFilePath">Full source path</param> /// <param name="targetFilePath">Full target path</param> public static void MoveFile(PathInfo sourceFilePath, PathInfo targetFilePath) { if (Win32SafeNativeMethods.MoveFile(sourceFilePath.FullNameUnc, targetFilePath.FullNameUnc)) { return; } int win32Error = Marshal.GetLastWin32Error(); NativeExceptionMapping(sourceFilePath.FullName, win32Error); }
/// <summary> /// Removes a file. /// </summary> /// <param name="pathInfo">PathInfo of 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(PathInfo pathInfo) { RemoveAttribute(pathInfo, FileAttributes.ReadOnly); DeleteFileUnc(pathInfo.FullNameUnc); }
/// <summary> /// Reurns true if passed path exists /// </summary> /// <param name="pathInfo">Path to check</param> public static Boolean Exists(PathInfo pathInfo) { uint attributes = Win32SafeNativeMethods.GetFileAttributes(pathInfo.FullNameUnc); return !Equals(attributes, 0xffffffff); }
/// <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(PathInfo pathInfo, DateTime creationTimeUtc, DateTime lastAccessTimeUtc, DateTime lastWriteTimeUtc) { 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) { return; } int win32Error = Marshal.GetLastWin32Error(); NativeExceptionMapping(pathInfo.FullName, win32Error); } }
/// <summary> /// Initializes a new instance of the QuickIOAbstractBase class, which acts as a wrapper for a file path. /// </summary> /// <param name="pathInfo"><see cref="Minimal.PathInfo"/></param> /// <param name="findData"><see cref="Win32FindData"/></param> internal FileDetailBase(PathInfo pathInfo, Win32FindData findData) { FindData = findData; PathInfo = pathInfo; if (findData != null) { Attributes = findData.dwFileAttributes; } }
/// <summary> /// Sets the time at which the file or directory was last written 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 SetLastWriteTimeUtc(PathInfo pathInfo, DateTime utcTime) { long longTime = utcTime.ToFileTime(); using (SafeFileHandle fileHandle = OpenReadWriteFileSystemEntryHandle(pathInfo.FullNameUnc)) { if (Win32SafeNativeMethods.SetLastWriteFileTime(fileHandle, IntPtr.Zero, IntPtr.Zero, ref longTime)) { return; } int win32Error = Marshal.GetLastWin32Error(); NativeExceptionMapping(pathInfo.FullName, win32Error); } }
internal static FileOrDirectory DetermineFileSystemEntry(PathInfo pathInfo) { var findData = GetFindDataFromPath(pathInfo); return !ContainsFileAttribute(findData.dwFileAttributes, FileAttributes.Directory) ? FileOrDirectory.File : FileOrDirectory.Directory; }
/// <summary> /// Creates the file information on the basis of the path and <see cref="Win32FindData"/> /// </summary> /// <param name="pathInfo">Full path to the file</param> /// <param name="win32FindData"><see cref="Win32FindData"/></param> internal FileDetail(PathInfo pathInfo, Win32FindData win32FindData) : base(pathInfo, win32FindData) { RetriveDateTimeInformation(win32FindData); CalculateSize(win32FindData); }
/// <summary> /// Creates new instance of <see cref="FileSecurity"/> for specified path. /// Current Windows Identtiy is used. /// </summary> /// <param name="pathInfo"></param> public FileSecurity(PathInfo pathInfo) : this(pathInfo, WindowsIdentity.GetCurrent()) { }
/// <summary> /// Create new instance of <see cref="FileDetail"/> /// </summary> public FileDetail(PathInfo pathInfo) : this(pathInfo, NativeIO.GetFindDataFromPath(pathInfo)) { }
/// <summary> /// Create new instance of <see cref="DirectoryDetail"/> /// </summary> public DirectoryDetail(PathInfo pathInfo) : this(pathInfo, pathInfo.IsRoot ? null : NativeIO.GetFindDataFromPath(pathInfo)) { }
/// <summary> /// Loads a file from specified path /// </summary> /// <param name="pathInfo">Full path</param> /// <returns> /// <see cref="FileDetail" /> /// </returns> public static FileDetail ReadFileDetails(PathInfo pathInfo) { Win32FindData findData; if (!TryGetFindDataFromPath(pathInfo, out findData)) { throw new Exception("PathNotFound " + pathInfo.FullName); } if (DetermineFileSystemEntry(findData) != FileOrDirectory.File) { throw new Exception("UnmatchedFileSystemEntryType " + FileOrDirectory.File + ", " + FileOrDirectory.Directory + ", " + pathInfo.FullName); } return new FileDetail(pathInfo, findData); }
/// <summary> /// Sets the owner /// </summary> public void SetOwner(IdentityReference newOwersIdentityReference) { PathInfo.SetOwner(newOwersIdentityReference); }
/// <summary> /// Sets the specified <see cref="FileAttributes" /> of the entry on the specified path. /// </summary> /// <param name="pathInfo">The path to the entry.</param> /// <param name="attributes">A bitwise combination of the enumeration values.</param> /// <exception cref="Win32Exception">Unmatched Exception</exception> public static void SetAttributes(PathInfo pathInfo, FileAttributes attributes) { if (Win32SafeNativeMethods.SetFileAttributes(pathInfo.FullNameUnc, (uint)attributes)) { return; } int win32Error = Marshal.GetLastWin32Error(); NativeExceptionMapping(pathInfo.FullName, win32Error); }
public FileSecurity GetFileSystemSecurity() { return(PathInfo.GetFileSystemSecurity()); }
/// <summary> /// Gets the <see cref="Win32FindData" /> from the passed path. /// </summary> /// <param name="pathInfo">Path</param> /// <param name="pathFindData"><seealso cref="Win32FindData" />. Will be null if path does not exist.</param> /// <returns>true if path is valid and <see cref="Win32FindData" /> is set</returns> /// <remarks> /// <see> /// <cref>QuickIOCommon.NativeExceptionMapping</cref> /// </see> /// if invalid handle found. /// </remarks> public static bool TryGetFindDataFromPath(PathInfo pathInfo, out Win32FindData pathFindData) { var win32FindData = new Win32FindData(); int win32Error; using (var fileHandle = FindFirstSafeFileHandle(pathInfo.FullNameUnc, win32FindData, out win32Error)) { // Take care of invalid handles if (fileHandle.IsInvalid) { NativeExceptionMapping(pathInfo.FullName, win32Error); } // Ignore . and .. directories if (!IsSystemDirectoryEntry(win32FindData)) { pathFindData = win32FindData; return true; } } pathFindData = null; return false; }
/// <summary> /// Determines the owner /// </summary> /// <returns><see cref="IdentityReference"/></returns> public IdentityReference GetOwnerIdentifier() { return(PathInfo.GetOwnerIdentifier()); }
/// <summary> /// Determined all subfolders of a directory /// </summary> /// <param name="pathInfo">Path of the directory</param> /// <param name="pattern">Search pattern. Uses Win32 native filtering.</param> /// <param name="searchOption"> /// <see cref="SearchOption" /> /// </param> /// <param name="enumerateOptions">The enumeration options for exception handling</param> /// <returns><see cref="DirectoryDetail" /> collection of subfolders</returns> internal static IEnumerable<DirectoryDetail> EnumerateDirectories(PathInfo pathInfo, String pattern = "*", SearchOption searchOption = SearchOption.TopDirectoryOnly, SuppressExceptions enumerateOptions = SuppressExceptions.None) { // Match for start of search string currentPath = PathTools.Combine(pathInfo.FullNameUnc, pattern); // Find First file var win32FindData = new Win32FindData(); int win32Error; using (var fileHandle = FindFirstSafeFileHandle(currentPath, win32FindData, out win32Error)) { // Take care of invalid handles if (fileHandle.IsInvalid) { if (win32Error != ERROR_NO_MORE_FILES) { NativeExceptionMapping(pathInfo.FullName, win32Error); } if (EnumerationHandleInvalidFileHandle(pathInfo.FullName, enumerateOptions, win32Error)) { yield return null; } } do { // Ignore . and .. directories if (IsSystemDirectoryEntry(win32FindData)) { continue; } // Create hit for current search result string resultPath = PathTools.Combine(pathInfo.FullName, win32FindData.cFileName); // Check for Directory if (ContainsFileAttribute(win32FindData.dwFileAttributes, FileAttributes.Directory)) { yield return new DirectoryDetail(new PathInfo(resultPath), win32FindData); // SubFolders?! if (searchOption == SearchOption.AllDirectories) { foreach (var match in EnumerateDirectories(new PathInfo(resultPath, win32FindData.cFileName), pattern, searchOption, enumerateOptions)) { yield return match; } } } // Create new FindData object for next result win32FindData = new Win32FindData(); } // Search for next entry while (Win32SafeNativeMethods.FindNextFile(fileHandle, win32FindData)); } }
/// <summary> /// Determines the owner /// </summary> /// <returns><see cref="NTAccount"/></returns> public NTAccount GetOwner() { return(PathInfo.GetOwner()); }
/// <summary> /// Determines the owner /// </summary> /// <returns><see cref="IdentityReference"/></returns> public void SetOwner(NTAccount newOwner) { PathInfo.SetOwner(newOwner); }