// Normalizes path (can be longer than MAX_PATH) and adds \\?\ long path prefix internal static string NormalizeLongPath(string path, string parameterName) { if (path == null) { throw new ArgumentNullException(parameterName); } if (path.Length == 0) { throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, "'{0}' cannot be an empty string.", parameterName), parameterName); } StringBuilder buffer = new StringBuilder(path.Length + 1); // Add 1 for NULL uint length = NativeMethods.GetFullPathName(path, (uint)buffer.Capacity, buffer, IntPtr.Zero); if (length > buffer.Capacity) { // Resulting path longer than our buffer, so increase it buffer.Capacity = (int)length; length = NativeMethods.GetFullPathName(path, length, buffer, IntPtr.Zero); } if (length == 0) { throw LongPathCommon.GetExceptionFromLastWin32Error(parameterName); } if (length > NativeMethods.MAX_LONG_PATH) { throw LongPathCommon.GetExceptionFromWin32Error(NativeMethods.ERROR_FILENAME_EXCED_RANGE, parameterName); } return(AddLongPathPrefix(buffer.ToString())); }
/// <summary> /// Creates the specified directory. /// </summary> /// <param name="path"> /// A <see cref="String"/> containing the path of the directory to create. /// </param> /// <exception cref="ArgumentNullException"> /// <paramref name="path"/> is <see langword="null"/>. /// </exception> /// <exception cref="ArgumentException"> /// <paramref name="path"/> is an empty string (""), contains only white /// space, or contains one or more invalid characters as defined in /// <see cref="Path.GetInvalidPathChars()"/>. /// <para> /// -or- /// </para> /// <paramref name="path"/> contains one or more components that exceed /// the drive-defined maximum length. For example, on Windows-based /// platforms, components must not exceed 255 characters. /// </exception> /// <exception cref="PathTooLongException"> /// <paramref name="path"/> exceeds the system-defined maximum length. /// For example, on Windows-based platforms, paths must not exceed /// 32,000 characters. /// </exception> /// <exception cref="DirectoryNotFoundException"> /// <paramref name="path"/> contains one or more directories that could not be /// found. /// </exception> /// <exception cref="UnauthorizedAccessException"> /// The caller does not have the required access permissions. /// </exception> /// <exception cref="IOException"> /// <paramref name="path"/> is a file. /// <para> /// -or- /// </para> /// <paramref name="path"/> specifies a device that is not ready. /// </exception> /// <remarks> /// Note: Unlike <see cref="Directory.CreateDirectory(System.String)"/>, this method only creates /// the last directory in <paramref name="path"/>. /// </remarks> public static void Create(string path) { string normalizedPath = LongPathCommon.NormalizeLongPath(path); if (!NativeMethods.CreateDirectory(normalizedPath, IntPtr.Zero)) { // To mimic Directory.CreateDirectory, we don't throw if the directory (not a file) already exists int errorCode = Marshal.GetLastWin32Error(); if (errorCode != NativeMethods.ERROR_ALREADY_EXISTS || !LongPathDirectory.Exists(path)) { throw LongPathCommon.GetExceptionFromWin32Error(errorCode); } } }
private static IEnumerable <string> EnumerateFileSystemEntries(string path, string searchPattern, bool includeDirectories, bool includeFiles) { string normalizedSearchPattern = LongPathCommon.NormalizeSearchPattern(searchPattern); string normalizedPath = LongPathCommon.NormalizeLongPath(path); // First check whether the specified path refers to a directory and exists FileAttributes attributes; int errorCode = LongPathCommon.TryGetDirectoryAttributes(normalizedPath, out attributes); if (errorCode != 0) { throw LongPathCommon.GetExceptionFromWin32Error(errorCode); } return(EnumerateFileSystemIterator(normalizedPath, normalizedSearchPattern, includeDirectories, includeFiles)); }
private static SafeFindHandle BeginFind(string normalizedPathWithSearchPattern, out NativeMethods.WIN32_FIND_DATA findData) { SafeFindHandle handle = NativeMethods.FindFirstFile(normalizedPathWithSearchPattern, out findData); if (handle.IsInvalid) { int errorCode = Marshal.GetLastWin32Error(); if (errorCode != NativeMethods.ERROR_FILE_NOT_FOUND) { throw LongPathCommon.GetExceptionFromWin32Error(errorCode); } return(null); } return(handle); }
private static IEnumerable <string> EnumerateFileSystemIterator(string normalizedPath, string normalizedSearchPattern, bool includeDirectories, bool includeFiles) { // NOTE: Any exceptions thrown from this method are thrown on a call to IEnumerator<string>.MoveNext() string path = LongPathCommon.RemoveLongPathPrefix(normalizedPath); NativeMethods.WIN32_FIND_DATA findData; using (SafeFindHandle handle = BeginFind(Path.Combine(normalizedPath, normalizedSearchPattern), out findData)) { if (handle == null) { yield break; } do { string currentFileName = findData.cFileName; if (IsDirectory(findData.dwFileAttributes)) { if (includeDirectories && !IsCurrentOrParentDirectory(currentFileName)) { yield return(Path.Combine(path, currentFileName)); } } else { if (includeFiles) { yield return(Path.Combine(path, currentFileName)); } } } while (NativeMethods.FindNextFile(handle, out findData)); int errorCode = Marshal.GetLastWin32Error(); if (errorCode != NativeMethods.ERROR_NO_MORE_FILES) { throw LongPathCommon.GetExceptionFromWin32Error(errorCode); } } }