Exemplo n.º 1
0
        // 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()));
        }
Exemplo n.º 2
0
        /// <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);
                }
            }
        }
Exemplo n.º 3
0
        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));
        }
Exemplo n.º 4
0
        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);
        }
Exemplo n.º 5
0
        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);
                }
            }
        }