internal static void CreateSymbolicLinkCore(KernelTransaction transaction, string symlinkFileName, string targetFileName, SymbolicLinkTarget targetType, PathFormat pathFormat)
        {
            if (!NativeMethods.IsAtLeastWindowsVista)
            {
                throw new PlatformNotSupportedException(Resources.Requires_Windows_Vista_Or_Higher);
            }

            const GetFullPathOptions options = GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.FullCheck;

            string symlinkFileNameLp = Path.GetExtendedLengthPathCore(transaction, symlinkFileName, pathFormat, options);
            string targetFileNameRp  = Path.GetExtendedLengthPathCore(transaction, targetFileName, pathFormat, options);

            // Don't use long path notation, as it will be empty upon creation.
            targetFileNameRp = Path.GetRegularPathCore(targetFileNameRp, GetFullPathOptions.None, false);


            if (!(transaction == null

                  // CreateSymbolicLink() / CreateSymbolicLinkTransacted()
                  // In the ANSI version of this function, the name is limited to MAX_PATH characters.
                  // To extend this limit to 32,767 wide characters, call the Unicode version of the function and prepend "\\?\" to the path.
                  // 2014-02-14: MSDN does not confirm LongPath usage but a Unicode version of this function exists.
                  // 2015-07-17: This function does not support long paths.

            ? NativeMethods.CreateSymbolicLink(symlinkFileNameLp, targetFileNameRp, targetType)
            : NativeMethods.CreateSymbolicLinkTransacted(symlinkFileNameLp, targetFileNameRp, targetType, transaction.SafeHandle)))
            {
                var lastError = Marshal.GetLastWin32Error();
                if (lastError != 0)
                {
                    NativeError.ThrowException(lastError, symlinkFileNameLp, targetFileNameRp);
                }
            }
        }
Beispiel #2
0
        /// <summary>Applies the <seealso cref="GetFullPathOptions"/> to <paramref name="path"/>.</summary>
        /// <returns><paramref name="path"/> with applied <paramref name="options"/>.</returns>
        /// <exception cref="ArgumentException"/>
        /// <exception cref="ArgumentNullException"/>
        /// <param name="path"></param>
        /// <param name="options"></param>
        private static string ApplyFullPathOptions(string path, GetFullPathOptions options)
        {
            if ((options & GetFullPathOptions.TrimEnd) != 0)
            {
                if ((options & GetFullPathOptions.KeepDotOrSpace) == 0)
                {
                    path = path.TrimEnd();
                }
            }

            if ((options & GetFullPathOptions.AddTrailingDirectorySeparator) != 0)
            {
                path = AddTrailingDirectorySeparator(path, false);
            }

            if ((options & GetFullPathOptions.RemoveTrailingDirectorySeparator) != 0)
            {
                path = RemoveTrailingDirectorySeparator(path);
            }

            if ((options & GetFullPathOptions.CheckInvalidPathChars) != 0)
            {
                CheckInvalidPathChars(path, (options & GetFullPathOptions.CheckAdditional) != 0, false);
            }


            // Trim leading whitespace.
            if ((options & GetFullPathOptions.KeepDotOrSpace) == 0)
            {
                path = path.TrimStart();
            }

            return(path);
        }
Beispiel #3
0
        internal static string GetRegularPathCore(string path, GetFullPathOptions options)
        {
            if (path == null)
            {
                throw new ArgumentNullException("path");
            }

            if (path.Length == 0 || Utils.IsNullOrWhiteSpace(path))
            {
                throw new ArgumentException(Resources.Path_Is_Zero_Length_Or_Only_White_Space, "path");
            }

            if (options != GetFullPathOptions.None)
            {
                path = ApplyFullPathOptions(path, options);
            }

            return(path.StartsWith(GlobalRootPrefix, StringComparison.OrdinalIgnoreCase) ||
                   path.StartsWith(VolumePrefix, StringComparison.OrdinalIgnoreCase) ||
                   !path.StartsWith(LongPathPrefix, StringComparison.OrdinalIgnoreCase)
            ? path
            : (path.StartsWith(LongPathUncPrefix, StringComparison.OrdinalIgnoreCase)
               ? UncPrefix + path.Substring(LongPathUncPrefix.Length)
               : path.Substring(LongPathPrefix.Length)));
        }
        internal static void CreateHardlinkCore(KernelTransaction transaction, string fileName, string existingFileName, PathFormat pathFormat)
        {
            const GetFullPathOptions options = GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.FullCheck;

            string fileNameLp         = Path.GetExtendedLengthPathCore(transaction, fileName, pathFormat, options);
            string existingFileNameLp = Path.GetExtendedLengthPathCore(transaction, existingFileName, pathFormat, options);

            if (!(transaction == null || !NativeMethods.IsAtLeastWindowsVista

                  // CreateHardLink() / CreateHardLinkTransacted()
                  // In the ANSI version of this function, the name is limited to MAX_PATH characters.
                  // To extend this limit to 32,767 wide characters, call the Unicode version of the function and prepend "\\?\" to the path.
                  // 2013-01-13: MSDN does not confirm LongPath usage but a Unicode version of this function exists.

            ? NativeMethods.CreateHardLink(fileNameLp, existingFileNameLp, IntPtr.Zero)
            : NativeMethods.CreateHardLinkTransacted(fileNameLp, existingFileNameLp, IntPtr.Zero, transaction.SafeHandle)))
            {
                int lastError = Marshal.GetLastWin32Error();
                switch ((uint)lastError)
                {
                case Win32Errors.ERROR_INVALID_FUNCTION:
                    throw new NotSupportedException(Resources.HardLinks_Not_Supported);

                default:
                    NativeError.ThrowException(lastError, fileNameLp, existingFileName);
                    break;
                }
            }
        }
Beispiel #5
0
        internal static void ReplaceCore(string sourceFileName, string destinationFileName, string destinationBackupFileName, bool ignoreMetadataErrors, PathFormat pathFormat)
        {
            const GetFullPathOptions options = GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.FullCheck;

            string sourceFileNameLp      = Path.GetExtendedLengthPathCore(null, sourceFileName, pathFormat, options);
            string destinationFileNameLp = Path.GetExtendedLengthPathCore(null, destinationFileName, pathFormat, options);

            // Pass null to the destinationBackupFileName parameter if you do not want to create a backup of the file being replaced.
            string destinationBackupFileNameLp = destinationBackupFileName == null
            ? null
            : Path.GetExtendedLengthPathCore(null, destinationBackupFileName, pathFormat, options);

            const int replacefileWriteThrough      = 1;
            const int replacefileIgnoreMergeErrors = 2;

            FileSystemRights dwReplaceFlags = (FileSystemRights)replacefileWriteThrough;

            if (ignoreMetadataErrors)
            {
                dwReplaceFlags |= (FileSystemRights)replacefileIgnoreMergeErrors;
            }

            // ReplaceFile()
            // In the ANSI version of this function, the name is limited to MAX_PATH characters.
            // To extend this limit to 32,767 wide characters, call the Unicode version of the function and prepend "\\?\" to the path.
            // 2013-01-13: MSDN does not confirm LongPath usage but a Unicode version of this function exists.

            if (!NativeMethods.ReplaceFile(destinationFileNameLp, sourceFileNameLp, destinationBackupFileNameLp, dwReplaceFlags, IntPtr.Zero, IntPtr.Zero))
            {
                NativeError.ThrowException(Marshal.GetLastWin32Error(), sourceFileNameLp, destinationFileNameLp);
            }
        }
Beispiel #6
0
        internal static void CreateHardlinkCore(KernelTransaction transaction, string fileName, string existingFileName, PathFormat pathFormat)
        {
            if (pathFormat != PathFormat.LongFullPath)
            {
                const GetFullPathOptions options = GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.FullCheck;

                fileName         = Path.GetExtendedLengthPathCore(transaction, fileName, pathFormat, options);
                existingFileName = Path.GetExtendedLengthPathCore(transaction, existingFileName, pathFormat, options);
            }


            if (!(transaction == null || !NativeMethods.IsAtLeastWindowsVista

                  // CreateHardLink() / CreateHardLinkTransacted()
                  // 2013-01-13: MSDN does not confirm LongPath usage but a Unicode version of this function exists.
                  // 2017-05-30: CreateHardLink() MSDN confirms LongPath usage: Starting with Windows 10, version 1607

            ? NativeMethods.CreateHardLink(fileName, existingFileName, IntPtr.Zero)
            : NativeMethods.CreateHardLinkTransacted(fileName, existingFileName, IntPtr.Zero, transaction.SafeHandle)))
            {
                var lastError = (uint)Marshal.GetLastWin32Error();

                switch (lastError)
                {
                case Win32Errors.ERROR_INVALID_FUNCTION:
                    throw new NotSupportedException(Resources.HardLinks_Not_Supported);

                default:
                    NativeError.ThrowException(lastError, existingFileName, fileName);
                    break;
                }
            }
        }
Beispiel #7
0
        internal static string GetLongPathCore(string path, GetFullPathOptions options)
        {
            if (null == path)
            {
                throw new ArgumentNullException("path");
            }


            if (path.Length == 0 || Utils.IsNullOrWhiteSpace(path))
            {
                throw new ArgumentException(Resources.Path_Is_Zero_Length_Or_Only_White_Space, "path");
            }


            if (options != GetFullPathOptions.None)
            {
                path = ApplyFullPathOptions(path, options);
            }


            // ".", "C:"
            if (path.Length <= 2 || path.StartsWith(LongPathPrefix, StringComparison.Ordinal) || path.StartsWith(LogicalDrivePrefix, StringComparison.Ordinal) || path.StartsWith(NonInterpretedPathPrefix, StringComparison.Ordinal))
            {
                return(path);
            }


            if (path.StartsWith(UncPrefix, StringComparison.Ordinal))
            {
                return(LongPathUncPrefix + path.Substring(UncPrefix.Length));
            }


            return(IsPathRooted(path, false) && IsLogicalDriveCore(path, false, PathFormat.LongFullPath) ? LongPathPrefix + path : path);
        }
        internal static void CreateSymbolicLinkCore(KernelTransaction transaction, string symlinkFileName, string targetFileName, SymbolicLinkTarget targetType, PathFormat pathFormat)
        {
            if (!NativeMethods.IsAtLeastWindowsVista)
            {
                throw new PlatformNotSupportedException(new Win32Exception((int)Win32Errors.ERROR_OLD_WIN_VERSION).Message);
            }


            if (pathFormat != PathFormat.LongFullPath)
            {
                const GetFullPathOptions options = GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.FullCheck;

                symlinkFileName = Path.GetExtendedLengthPathCore(transaction, symlinkFileName, pathFormat, options);
                targetFileName  = Path.GetExtendedLengthPathCore(transaction, targetFileName, pathFormat, options);
            }


            // Don't use long path notation, as it will be empty upon creation.
            targetFileName = Path.GetRegularPathCore(targetFileName, GetFullPathOptions.None, false);


            if (targetType == SymbolicLinkTarget.Directory)
            {
                ThrowIOExceptionIfFsoExist(transaction, false, targetFileName, pathFormat);
                ThrowIOExceptionIfFsoExist(transaction, false, symlinkFileName, pathFormat);
            }

            else
            {
                ThrowIOExceptionIfFsoExist(transaction, true, targetFileName, pathFormat);
                ThrowIOExceptionIfFsoExist(transaction, true, symlinkFileName, pathFormat);
            }


            var success = null == transaction

                          // CreateSymbolicLink() / CreateSymbolicLinkTransacted()
                          // 2014-02-14: MSDN does not confirm LongPath usage but a Unicode version of this function exists.
                          // 2015-07-17: This function does not support long paths.
                          // 2017-05-30: CreateSymbolicLink() MSDN confirms LongPath usage: Starting with Windows 10, version 1607

            ? NativeMethods.CreateSymbolicLink(symlinkFileName, targetFileName, targetType)
            : NativeMethods.CreateSymbolicLinkTransacted(symlinkFileName, targetFileName, targetType, transaction.SafeHandle);


            var lastError = (uint)Marshal.GetLastWin32Error();

            if (!success)
            {
                NativeError.ThrowException(lastError, targetFileName, symlinkFileName);
            }
        }
Beispiel #9
0
        public FileInfo Replace(string destinationFileName, string destinationBackupFileName, PathFormat pathFormat)
        {
            const GetFullPathOptions options = GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.FullCheck;

            string destinationFileNameLp       = Path.GetExtendedLengthPathCore(Transaction, destinationFileName, pathFormat, options);
            string destinationBackupFileNameLp = destinationBackupFileName != null
            ? Path.GetExtendedLengthPathCore(Transaction, destinationBackupFileName, pathFormat, options)
            : null;

            File.ReplaceCore(LongFullName, destinationFileNameLp, destinationBackupFileNameLp, false, PathFormat.LongFullPath);

            return(new FileInfo(Transaction, destinationFileNameLp, PathFormat.LongFullPath));
        }
Beispiel #10
0
        internal static string GetLongPathInternal(string path, GetFullPathOptions options)
        {
            if (path == null)
            {
                throw new ArgumentNullException("path");
            }

            if (path.Length == 0 || Utils.IsNullOrWhiteSpace(path))
            {
                throw new ArgumentException(Resources.PathIsZeroLengthOrOnlyWhiteSpace, "path");
            }

            if (options != GetFullPathOptions.None)
            {
                if ((options & GetFullPathOptions.TrimEnd) != 0)
                {
                    path = path.TrimEnd();
                }

                if ((options & GetFullPathOptions.AddTrailingDirectorySeparator) != 0)
                {
                    path = AddTrailingDirectorySeparator(path, false);
                }

                if ((options & GetFullPathOptions.RemoveTrailingDirectorySeparator) != 0)
                {
                    path = RemoveTrailingDirectorySeparator(path, false);
                }

                if ((options & GetFullPathOptions.CheckInvalidPathChars) != 0)
                {
                    CheckInvalidPathChars(path, false);
                }
            }


            if (path.StartsWith(LongPathPrefix, StringComparison.OrdinalIgnoreCase) ||
                path.StartsWith(LogicalDrivePrefix, StringComparison.OrdinalIgnoreCase))
            {
                return(path);
            }

            // ".", "C:"
            return(path.Length > 2 && (IsLocalPath(path, false) || IsUncPath(path, false))
            ? path.StartsWith(UncPrefix, StringComparison.OrdinalIgnoreCase)
               ? LongPathUncPrefix + path.Substring(UncPrefix.Length)
               : LongPathPrefix + path
            : path);
            // 2015-01-11 Issue #50: Path.GetLongPath() does not prefix on "C:", should it?
        }
Beispiel #11
0
        internal static void ReplaceCore(string sourceFileName, string destinationFileName, string destinationBackupFileName, bool ignoreMetadataErrors, PathFormat pathFormat)
        {
            const GetFullPathOptions options = GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.FullCheck;

            var sourceFileNameLp      = sourceFileName;
            var destinationFileNameLp = destinationFileName;


            if (pathFormat != PathFormat.LongFullPath)
            {
                sourceFileNameLp      = Path.GetExtendedLengthPathCore(null, sourceFileName, pathFormat, options);
                destinationFileNameLp = Path.GetExtendedLengthPathCore(null, destinationFileName, pathFormat, options);
            }


            // Pass null to the destinationBackupFileName parameter if you do not want to create a backup of the file being replaced.
            var destinationBackupFileNameLp = null == destinationBackupFileName
            ? null
            : Path.GetExtendedLengthPathCore(null, destinationBackupFileName, pathFormat, options);


            const int replacefileWriteThrough      = 1;
            const int replacefileIgnoreMergeErrors = 2;


            var dwReplaceFlags = (FileSystemRights)replacefileWriteThrough;

            if (ignoreMetadataErrors)
            {
                dwReplaceFlags |= (FileSystemRights)replacefileIgnoreMergeErrors;
            }


            // ReplaceFile()
            // 2013-01-13: MSDN does not confirm LongPath usage but a Unicode version of this function exists.
            // 2017-05-30: MSDN confirms LongPath usage: Starting with Windows 10, version 1607

            var success = NativeMethods.ReplaceFile(destinationFileNameLp, sourceFileNameLp, destinationBackupFileNameLp, dwReplaceFlags, IntPtr.Zero, IntPtr.Zero);

            var lastError = (uint)Marshal.GetLastWin32Error();

            if (!success)
            {
                NativeError.ThrowException(lastError, sourceFileNameLp, destinationFileNameLp);
            }
        }
Beispiel #12
0
        internal static string GetRegularPathInternal(string path, GetFullPathOptions options)
        {
            if (path == null)
            {
                throw new ArgumentNullException("path");
            }

            if (path.Length == 0 || Utils.IsNullOrWhiteSpace(path))
            {
                throw new ArgumentException(Resources.PathIsZeroLengthOrOnlyWhiteSpace, "path");
            }

            if (options != GetFullPathOptions.None)
            {
                if ((options & GetFullPathOptions.TrimEnd) != 0)
                {
                    path = path.TrimEnd();
                }

                if ((options & GetFullPathOptions.AddTrailingDirectorySeparator) != 0)
                {
                    path = AddTrailingDirectorySeparator(path, false);
                }

                if ((options & GetFullPathOptions.RemoveTrailingDirectorySeparator) != 0)
                {
                    path = RemoveTrailingDirectorySeparator(path, false);
                }

                if ((options & GetFullPathOptions.CheckInvalidPathChars) != 0)
                {
                    CheckInvalidPathChars(path, false);
                }
            }


            if (!path.StartsWith(LongPathPrefix, StringComparison.OrdinalIgnoreCase))
            {
                return(path);
            }

            return(path.StartsWith(LongPathUncPrefix, StringComparison.OrdinalIgnoreCase)
            ? UncPrefix + path.Substring(LongPathUncPrefix.Length)
            : path.Substring(LongPathPrefix.Length));
        }
Beispiel #13
0
        internal static string GetLongPathCore(string path, GetFullPathOptions options)
        {
            if (path == null)
            {
                throw new ArgumentNullException("path");
            }

            if (path.Length == 0 || Utils.IsNullOrWhiteSpace(path))
            {
                throw new ArgumentException(Resources.Path_Is_Zero_Length_Or_Only_White_Space, "path");
            }

            if (options != GetFullPathOptions.None)
            {
                path = ApplyFullPathOptions(path, options);
            }

            // ".", "C:"
            if (path.Length <= 2 ||
                path.StartsWith(LongPathPrefix, StringComparison.OrdinalIgnoreCase) ||
                path.StartsWith(LogicalDrivePrefix, StringComparison.OrdinalIgnoreCase))
            {
                return(path);
            }

            if (path.StartsWith(UncPrefix, StringComparison.OrdinalIgnoreCase))
            {
                return(LongPathUncPrefix + path.Substring(UncPrefix.Length));
            }

            // Don't use char.IsLetter() here as that can be misleading.
            // The only valid drive letters are: a-z and A-Z.
            char c = path[0];

            return(IsPathRooted(path, false) && ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
            ? LongPathPrefix + path
            : path);
        }
        /// <summary>Applies the <seealso cref="GetFullPathOptions"/> to <paramref name="path"/></summary>
        /// <returns><paramref name="path"/> with applied <paramref name="options"/>.</returns>
        /// <exception cref="ArgumentNullException"/>
        /// <exception cref="ArgumentException"/>
        /// <param name="path"></param>
        /// <param name="options"></param>
        private static string ApplyFullPathOptions(string path, GetFullPathOptions options)
        {
            if ((options & GetFullPathOptions.TrimEnd) != 0)
            {
                path = path.TrimEnd();
            }

            if ((options & GetFullPathOptions.AddTrailingDirectorySeparator) != 0)
            {
                path = AddTrailingDirectorySeparator(path, false);
            }

            if ((options & GetFullPathOptions.RemoveTrailingDirectorySeparator) != 0)
            {
                path = RemoveTrailingDirectorySeparator(path, false);
            }

            if ((options & GetFullPathOptions.CheckInvalidPathChars) != 0)
            {
                CheckInvalidPathChars(path, (options & GetFullPathOptions.CheckAdditional) != 0);
            }

            return(path);
        }
Beispiel #15
0
 public static string GetFullPathTransacted(KernelTransaction transaction, string path, GetFullPathOptions options)
 {
     return(GetFullPathTackleCore(transaction, path, options));
 }
Beispiel #16
0
        /// <summary>Gets the path as a long full path.</summary>
        /// <returns>The path as an extended length path.</returns>
        /// <exception cref="ArgumentException"/>
        /// <param name="transaction">The transaction.</param>
        /// <param name="sourcePath">Full pathname of the source path to convert.</param>
        /// <param name="pathFormat">The path format to use.</param>
        /// <param name="options">Options for controlling the operation. Note that on .NET 3.5 the TrimEnd option has no effect.</param>
        internal static string GetExtendedLengthPathCore(KernelTransaction transaction, string sourcePath, PathFormat pathFormat, GetFullPathOptions options)
        {
            switch (pathFormat)
            {
            case PathFormat.LongFullPath:
                return(sourcePath);

            case PathFormat.FullPath:
                return(GetLongPathCore(sourcePath, GetFullPathOptions.None));

            case PathFormat.RelativePath:
#if NET35
                // .NET 3.5 the TrimEnd option has no effect.
                options = options & ~GetFullPathOptions.TrimEnd;
#endif
                return(GetFullPathCore(transaction, sourcePath, GetFullPathOptions.AsLongPath | options));

            default:
                throw new ArgumentException("Invalid value for " + typeof(PathFormat).Name + ": " + pathFormat);
            }
        }
        internal static string GetFullPathCore(KernelTransaction transaction, string path, GetFullPathOptions options)
        {
            if (path != null)
            {
                if (path.StartsWith(GlobalRootPrefix, StringComparison.OrdinalIgnoreCase) ||
                    path.StartsWith(VolumePrefix, StringComparison.OrdinalIgnoreCase))
                {
                    return(path);
                }
            }

            if (options != GetFullPathOptions.None)
            {
                if ((options & GetFullPathOptions.CheckInvalidPathChars) != 0)
                {
                    bool checkAdditional = (options & GetFullPathOptions.CheckAdditional) != 0;

                    CheckInvalidPathChars(path, checkAdditional);

                    // Prevent duplicate checks.
                    options &= ~GetFullPathOptions.CheckInvalidPathChars;

                    if (checkAdditional)
                    {
                        options &= ~GetFullPathOptions.CheckAdditional;
                    }
                }

                // Do not remove trailing directory separator when path points to a drive like: "C:\"
                // Doing so makes path point to the current directory.

                if (path == null || path.Length <= 3 || (!path.StartsWith(LongPathPrefix, StringComparison.OrdinalIgnoreCase) && path[1] != VolumeSeparatorChar))
                {
                    options &= ~GetFullPathOptions.RemoveTrailingDirectorySeparator;
                }
            }


            string pathLp = GetLongPathCore(path, options);

            uint bufferSize = NativeMethods.MaxPathUnicode;


            // ChangeErrorMode is for the Win32 SetThreadErrorMode() method, used to suppress possible pop-ups.
            using (new NativeMethods.ChangeErrorMode(NativeMethods.ErrorMode.FailCriticalErrors))
            {
startGetFullPathName:

                var buffer = new StringBuilder((int)bufferSize);
                uint returnLength = (transaction == null || !NativeMethods.IsAtLeastWindowsVista

                                     // GetFullPathName() / GetFullPathNameTransacted()
                                     // In the ANSI version of this function, the name is limited to MAX_PATH characters.
                                     // To extend this limit to 32,767 wide characters, call the Unicode version of the function and prepend "\\?\" to the path.
                                     // 2013-04-15: MSDN confirms LongPath usage.

               ? NativeMethods.GetFullPathName(pathLp, bufferSize, buffer, IntPtr.Zero)
               : NativeMethods.GetFullPathNameTransacted(pathLp, bufferSize, buffer, IntPtr.Zero, transaction.SafeHandle));

                if (returnLength != Win32Errors.NO_ERROR)
                {
                    if (returnLength > bufferSize)
                    {
                        bufferSize = returnLength;
                        goto startGetFullPathName;
                    }
                }
                else
                {
                    if ((options & GetFullPathOptions.ContinueOnNonExist) != 0)
                    {
                        return(null);
                    }

                    NativeError.ThrowException(pathLp);
                }

                return((options & GetFullPathOptions.AsLongPath) != 0
               ? GetLongPathCore(buffer.ToString(), GetFullPathOptions.None)
               : GetRegularPathCore(buffer.ToString(), GetFullPathOptions.None));
            }
        }
        private static string NormalizePath(string path, GetFullPathOptions options)
        {
            var  newBuffer = new StringBuilder(NativeMethods.MaxPathUnicode);
            var  index     = 0;
            uint numSpaces = 0;
            uint numDots   = 0;
            var  fixupDirectorySeparator = false;

            // Number of significant chars other than potentially suppressible
            // dots and spaces since the last directory or volume separator char
            uint numSigChars = 0;

            var lastSigChar = -1; // Index of last significant character.

            // Whether this segment of the path (not the complete path) started
            // with a volume separator char.  Reject "c:...".
            var startedWithVolumeSeparator = false;
            var firstSegment = true;
            var lastDirectorySeparatorPos = 0;

            // LEGACY: This code is here for backwards compatibility reasons. It
            // ensures that \\foo.cs\bar.cs stays \\foo.cs\bar.cs instead of being
            // turned into \foo.cs\bar.cs.
            if (path.Length > 0 && (path[0] == DirectorySeparatorChar || path[0] == AltDirectorySeparatorChar))
            {
                newBuffer.Append(DirectorySeparatorChar);
                index++;
                lastSigChar = 0;
            }

            // Normalize the string, stripping out redundant dots, spaces, and slashes.
            while (index < path.Length)
            {
                var currentChar = path[index];

                // We handle both directory separators and dots specially.  For
                // directory separators, we consume consecutive appearances.
                // For dots, we consume all dots beyond the second in
                // succession.  All other characters are added as is.  In
                // addition we consume all spaces after the last other char
                // in a directory name up until the directory separator.

                if (currentChar == DirectorySeparatorChar || currentChar == AltDirectorySeparatorChar)
                {
                    // If we have a path like "123.../foo", remove the trailing dots.
                    // However, if we found "c:\temp\..\bar" or "c:\temp\...\bar", don't.
                    // Also remove trailing spaces from both files & directory names.
                    // This was agreed on with the OS team to fix undeletable directory
                    // names ending in spaces.

                    // If we saw a '\' as the previous last significant character and
                    // are simply going to write out dots, suppress them.
                    // If we only contain dots and slashes though, only allow
                    // a string like [dot]+ [space]*.  Ignore everything else.
                    // Legal: "\.. \", "\...\", "\. \"
                    // Illegal: "\.. .\", "\. .\", "\ .\"

                    if (numSigChars == 0)
                    {
                        // Dot and space handling
                        if (numDots > 0)
                        {
                            // Look for ".[space]*" or "..[space]*"
                            var start = lastSigChar + 1;
                            if (path[start] != CurrentDirectoryPrefixChar)
                            {
                                throw new ArgumentException(path, "path");
                            }

                            // Only allow "[dot]+[space]*", and normalize the legal ones to "." or ".."
                            if (numDots >= 2)
                            {
                                // Reject "C:..."
                                if (startedWithVolumeSeparator && numDots > 2)
                                {
                                    throw new ArgumentException(path, "path");
                                }


                                if (path[start + 1] == CurrentDirectoryPrefixChar)
                                {
                                    // Search for a space in the middle of the dots and throw
                                    for (var i = start + 2; i < start + numDots; i++)
                                    {
                                        if (path[i] != CurrentDirectoryPrefixChar)
                                        {
                                            throw new ArgumentException(path, "path");
                                        }
                                    }

                                    numDots = 2;
                                }

                                else
                                {
                                    if (numDots > 1)
                                    {
                                        throw new ArgumentException(path, "path");
                                    }

                                    numDots = 1;
                                }
                            }


                            if (numDots == 2)
                            {
                                newBuffer.Append(CurrentDirectoryPrefixChar);
                            }


                            newBuffer.Append(CurrentDirectoryPrefixChar);
                            fixupDirectorySeparator = false;

                            // Continue in this case, potentially writing out '\'.
                        }


                        if (numSpaces > 0 && firstSegment)
                        {
                            // Handle strings like " \\server\share".
                            if (index + 1 < path.Length && (path[index + 1] == DirectorySeparatorChar || path[index + 1] == AltDirectorySeparatorChar))
                            {
                                newBuffer.Append(DirectorySeparatorChar);
                            }
                        }
                    }


                    numDots   = 0;
                    numSpaces = 0; // Suppress trailing spaces

                    if (!fixupDirectorySeparator)
                    {
                        fixupDirectorySeparator = true;
                        newBuffer.Append(DirectorySeparatorChar);
                    }

                    numSigChars = 0;
                    lastSigChar = index;
                    startedWithVolumeSeparator = false;
                    firstSegment = false;


                    var thisPos = newBuffer.Length - 1;
                    if (thisPos - lastDirectorySeparatorPos > NativeMethods.MaxDirectoryLength)
                    {
                        throw new PathTooLongException(path);
                    }

                    lastDirectorySeparatorPos = thisPos;
                } // if (Found directory separator)

                else if (currentChar == CurrentDirectoryPrefixChar)
                {
                    // Reduce only multiple .'s only after slash to 2 dots. For
                    // instance a...b is a valid file name.
                    numDots++;
                    // Don't flush out non-terminal spaces here, because they may in
                    // the end not be significant.  Turn "c:\ . .\foo" -> "c:\foo"
                    // which is the conclusion of removing trailing dots & spaces,
                    // as well as folding multiple '\' characters.
                }

                else if (currentChar == ' ')
                {
                    numSpaces++;
                }

                else
                { // Normal character logic
                    fixupDirectorySeparator = false;

                    // To reject strings like "C:...\foo" and "C  :\foo"
                    if (firstSegment && currentChar == VolumeSeparatorChar)
                    {
                        // Only accept "C:", not "c :" or ":"
                        // Get a drive letter or ' ' if index is 0.
                        var driveLetter = index > 0 ? path[index - 1] : ' ';

                        var validPath = numDots == 0 && numSigChars >= 1 && driveLetter != ' ';
                        if (!validPath)
                        {
                            throw new ArgumentException(path, "path");
                        }

                        startedWithVolumeSeparator = true;
                        // We need special logic to make " c:" work, we should not fix paths like "  foo::$DATA"
                        if (numSigChars > 1)
                        {
                            // Common case, simply do nothing
                            var spaceCount = 0; // How many spaces did we write out, numSpaces has already been reset.
                            while (spaceCount < newBuffer.Length && newBuffer[spaceCount] == ' ')
                            {
                                spaceCount++;
                            }

                            if (numSigChars - spaceCount == 1)
                            {
                                //Safe to update stack ptr directly
                                newBuffer.Length = 0;
                                newBuffer.Append(driveLetter);
                                // Overwrite spaces, we need a special case to not break "  foo" as a relative path.
                            }
                        }

                        numSigChars = 0;
                    }

                    else
                    {
                        numSigChars += 1 + numDots + numSpaces;
                    }

                    // Copy any spaces & dots since the last significant character
                    // to here.  Note we only counted the number of dots & spaces,
                    // and don't know what order they're in.  Hence the copy.
                    if (numDots > 0 || numSpaces > 0)
                    {
                        var numCharsToCopy = lastSigChar >= 0 ? index - lastSigChar - 1 : index;

                        if (numCharsToCopy > 0)
                        {
                            for (var i = 0; i < numCharsToCopy; i++)
                            {
                                newBuffer.Append(path[lastSigChar + 1 + i]);
                            }
                        }

                        numDots   = 0;
                        numSpaces = 0;
                    }

                    newBuffer.Append(currentChar);
                    lastSigChar = index;
                }

                index++;
            }


            if (newBuffer.Length - 1 - lastDirectorySeparatorPos > NativeMethods.MaxDirectoryLength)
            {
                throw new PathTooLongException(path);
            }


            // Drop any trailing dots and spaces from file & directory names, EXCEPT
            // we MUST make sure that "C:\foo\.." is correctly handled.
            // Also handle "C:\foo\." -> "C:\foo", while "C:\." -> "C:\"
            if (numSigChars == 0)
            {
                if (numDots > 0)
                {
                    // Look for ".[space]*" or "..[space]*"
                    var start = lastSigChar + 1;

                    if (path[start] != CurrentDirectoryPrefixChar)
                    {
                        throw new ArgumentException(path, "path");
                    }


                    // Only allow "[dot]+[space]*", and normalize the legal ones to "." or ".."
                    if (numDots >= 2)
                    {
                        // Reject "C:..."
                        if (startedWithVolumeSeparator && numDots > 2)
                        {
                            throw new ArgumentException(path, "path");
                        }


                        if (path[start + 1] == CurrentDirectoryPrefixChar)
                        {
                            // Search for a space in the middle of the dots and throw
                            for (var i = start + 2; i < start + numDots; i++)
                            {
                                if (path[i] != CurrentDirectoryPrefixChar)
                                {
                                    throw new ArgumentException(path, "path");
                                }
                            }

                            numDots = 2;
                        }

                        else
                        {
                            if (numDots > 1)
                            {
                                throw new ArgumentException(path, "path");
                            }

                            numDots = 1;
                        }
                    }

                    if (numDots == 2)
                    {
                        newBuffer.Append(CurrentDirectoryPrefixChar);
                    }

                    newBuffer.Append(CurrentDirectoryPrefixChar);
                }
            }


            // If we ended up eating all the characters, bail out.
            if (newBuffer.Length == 0)
            {
                throw new ArgumentException(path, "path");
            }


            // Disallow URL's here.  Some of our other Win32 API calls will reject
            // them later, so we might be better off rejecting them here.
            // Note we've probably turned them into "file:\D:\foo.tmp" by now.
            // But for compatibility, ensure that callers that aren't doing a
            // full check aren't rejected here.
            if ((options & GetFullPathOptions.FullCheck) != 0)
            {
                var newBufferString = newBuffer.ToString();
                if (newBufferString.StartsWith(Uri.UriSchemeHttp + ":", StringComparison.OrdinalIgnoreCase) || newBufferString.StartsWith(Uri.UriSchemeFile + ":", StringComparison.OrdinalIgnoreCase))
                {
                    throw new ArgumentException(path, "path");
                }
            }


            // Call the Win32 API to do the final canonicalization step.
            const int result = 1;

            /* Throw an ArgumentException for paths like \\, \\server, \\server\
            *  This check can only be properly done after normalizing, so
            \\foo\.. will be properly rejected.  Also, reject \\?\GLOBALROOT\
            *  (an internal kernel path) because it provides aliases for drives. */

            if (newBuffer.Length > 1 && newBuffer[0] == DirectorySeparatorChar && newBuffer[1] == DirectorySeparatorChar)
            {
                var startIndex = 2;
                while (startIndex < result)
                {
                    if (newBuffer[startIndex] == DirectorySeparatorChar)
                    {
                        startIndex++;
                        break;
                    }

                    startIndex++;
                }

                if (startIndex == result)
                {
                    throw new ArgumentException(path, "path");
                }
            }


            return(newBuffer.ToString());
        }
      internal static string GetRegularPathInternal(string path, GetFullPathOptions options)
      {
         if (path == null)
            throw new ArgumentNullException("path");

         if (path.Length == 0 || Utils.IsNullOrWhiteSpace(path))
            throw new ArgumentException(Resources.PathIsZeroLengthOrOnlyWhiteSpace, "path");

         if (options != GetFullPathOptions.None)
         {
            if ((options & GetFullPathOptions.TrimEnd) != 0)
               path = path.TrimEnd();

            if ((options & GetFullPathOptions.AddTrailingDirectorySeparator) != 0)
               path = AddTrailingDirectorySeparator(path, false);

            if ((options & GetFullPathOptions.RemoveTrailingDirectorySeparator) != 0)
               path = RemoveTrailingDirectorySeparator(path, false);

            if ((options & GetFullPathOptions.CheckInvalidPathChars) != 0)
               CheckInvalidPathChars(path, false);
         }

         
         if (!path.StartsWith(LongPathPrefix, StringComparison.OrdinalIgnoreCase))
            return path;

         return path.StartsWith(LongPathUncPrefix, StringComparison.OrdinalIgnoreCase)
            ? UncPrefix + path.Substring(LongPathUncPrefix.Length)
            : path.Substring(LongPathPrefix.Length);
      }
        internal static string GetHashCore(KernelTransaction transaction, string fileFullPath, HashType hashType, PathFormat pathFormat)
        {
            const GetFullPathOptions options = GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.FullCheck;
            var fileNameLp = Path.GetExtendedLengthPathCore(transaction, fileFullPath, pathFormat, options);

            byte[] hash = null;


            using (var fs = OpenCore(transaction, fileNameLp, FileMode.Open, FileAccess.Read, FileShare.Read, ExtendedFileAttributes.Normal, null, null, PathFormat.LongFullPath))
            {
                switch (hashType)
                {
                case HashType.CRC32:
                    using (var hType = new Crc32())
                        hash = hType.ComputeHash(fs);
                    break;


                case HashType.CRC64ISO3309:
                    using (var hType = new Crc64())
                        hash = hType.ComputeHash(fs);
                    break;


                case HashType.MD5:
                    using (var hType = MD5.Create())
                        hash = hType.ComputeHash(fs);
                    break;


                case HashType.RIPEMD160:
                    using (var hType = RIPEMD160.Create())
                        hash = hType.ComputeHash(fs);
                    break;


                case HashType.SHA1:
                    using (var hType = SHA1.Create())
                        hash = hType.ComputeHash(fs);
                    break;


                case HashType.SHA256:
                    using (var hType = SHA256.Create())
                        hash = hType.ComputeHash(fs);
                    break;


                case HashType.SHA384:
                    using (var hType = SHA384.Create())
                        hash = hType.ComputeHash(fs);
                    break;


                case HashType.SHA512:
                    using (var hType = SHA512.Create())
                        hash = hType.ComputeHash(fs);
                    break;
                }
            }


            if (null != hash)
            {
                var sb = new StringBuilder(hash.Length);

                foreach (var b in hash)
                {
                    sb.Append(b.ToString("X2", CultureInfo.InvariantCulture));
                }

                return(sb.ToString().ToUpperInvariant());
            }

            return(string.Empty);
        }
      internal static string GetLongPathInternal(string path, GetFullPathOptions options)
      {
         if (path == null)
            throw new ArgumentNullException("path");

         if (path.Length == 0 || Utils.IsNullOrWhiteSpace(path))
            throw new ArgumentException(Resources.PathIsZeroLengthOrOnlyWhiteSpace, "path");

         if (options != GetFullPathOptions.None)
         {
            if ((options & GetFullPathOptions.TrimEnd) != 0)
               path = path.TrimEnd();

            if ((options & GetFullPathOptions.AddTrailingDirectorySeparator) != 0)
               path = AddTrailingDirectorySeparator(path, false);

            if ((options & GetFullPathOptions.RemoveTrailingDirectorySeparator) != 0)
               path = RemoveTrailingDirectorySeparator(path, false);

            if ((options & GetFullPathOptions.CheckInvalidPathChars) != 0)
               CheckInvalidPathChars(path, false);
         }

         
         if (path.StartsWith(LongPathPrefix, StringComparison.OrdinalIgnoreCase) ||
             path.StartsWith(LogicalDrivePrefix, StringComparison.OrdinalIgnoreCase))
            return path;

         // ".", "C:"
         return path.Length > 2 && (IsLocalPath(path, false) || IsUncPath(path, false))
            ? path.StartsWith(UncPrefix, StringComparison.OrdinalIgnoreCase)
               ? LongPathUncPrefix + path.Substring(UncPrefix.Length)
               : LongPathPrefix + path
            : path;
         // 2015-01-11 Issue #50: Path.GetLongPath() does not prefix on "C:", should it?
      }
 public static string LocalToUnc(string localPath, PathFormat pathFormat, GetFullPathOptions fullPathOptions)
 {
     return(LocalToUncCore(localPath, pathFormat, fullPathOptions));
 }
        internal static string LocalToUncCore(string localPath, PathFormat pathFormat, GetFullPathOptions fullPathOptions)
        {
            if (Utils.IsNullOrWhiteSpace(localPath))
            {
                return(null);
            }

            if (pathFormat == PathFormat.RelativePath)
            {
                CheckSupportedPathFormat(localPath, true, true);
            }


            var addTrailingDirectorySeparator    = (fullPathOptions & GetFullPathOptions.AddTrailingDirectorySeparator) != 0;
            var removeTrailingDirectorySeparator = (fullPathOptions & GetFullPathOptions.RemoveTrailingDirectorySeparator) != 0;

            if (addTrailingDirectorySeparator && removeTrailingDirectorySeparator)
            {
                throw new ArgumentException(Resources.GetFullPathOptions_Add_And_Remove_DirectorySeparator_Invalid, "fullPathOptions");
            }


            if (!removeTrailingDirectorySeparator && !addTrailingDirectorySeparator)
            {
                // Add a trailing backslash when "localPath" ends with a backslash.
                if (localPath.EndsWith(DirectorySeparator, StringComparison.Ordinal))
                {
                    fullPathOptions &= ~GetFullPathOptions.RemoveTrailingDirectorySeparator; // Remove removal of trailing backslash.
                    fullPathOptions |= GetFullPathOptions.AddTrailingDirectorySeparator;     // Add adding trailing backslash.
                }
            }


            var getAsLongPath = (fullPathOptions & GetFullPathOptions.AsLongPath) != 0;

            var returnUncPath = GetRegularPathCore(localPath, fullPathOptions | GetFullPathOptions.CheckInvalidPathChars, false);


            if (!IsUncPathCore(returnUncPath, true, false))
            {
                if (returnUncPath[0] == CurrentDirectoryPrefixChar || !IsPathRooted(returnUncPath, false))
                {
                    returnUncPath = GetFullPathCore(null, returnUncPath, GetFullPathOptions.None);
                }


                var drive = GetPathRoot(returnUncPath, false);

                if (Utils.IsNullOrWhiteSpace(drive))
                {
                    return(returnUncPath);
                }


                var remoteInfo = Host.GetRemoteNameInfoCore(returnUncPath, true);


                // Network share.
                if (!Utils.IsNullOrWhiteSpace(remoteInfo.lpUniversalName))
                {
                    return(getAsLongPath ? GetLongPathCore(remoteInfo.lpUniversalName, fullPathOptions) : GetRegularPathCore(remoteInfo.lpUniversalName, fullPathOptions, false));
                }


                // Network root.
                if (!Utils.IsNullOrWhiteSpace(remoteInfo.lpConnectionName))
                {
                    return(getAsLongPath ? GetLongPathCore(remoteInfo.lpConnectionName, fullPathOptions) : GetRegularPathCore(remoteInfo.lpConnectionName, fullPathOptions, false));
                }


                // Split: localDrive[0] = "C", localDrive[1] = "\Windows"
                var localDrive = returnUncPath.Split(VolumeSeparatorChar);

                // Return: "\\localhost\C$\Windows"
                returnUncPath = string.Format(CultureInfo.InvariantCulture, "{0}{1}{2}{3}{4}", Host.GetUncName(), DirectorySeparator, localDrive[0], NetworkDriveSeparator, localDrive[1]);
            }


            return(getAsLongPath ? GetLongPathCore(returnUncPath, fullPathOptions) : GetRegularPathCore(returnUncPath, fullPathOptions, false));
        }
Beispiel #24
0
      internal static string GetFullPathInternal(KernelTransaction transaction, string path, GetFullPathOptions options)
      {
         if (path != null)
            if (path.StartsWith(GlobalRootPrefix, StringComparison.OrdinalIgnoreCase) ||
                path.StartsWith(VolumePrefix, StringComparison.OrdinalIgnoreCase))
               return path;

         if (options != GetFullPathOptions.None)
         {
            if ((options & GetFullPathOptions.CheckInvalidPathChars) != 0)
            {
               bool checkAdditional = (options & GetFullPathOptions.CheckAdditional) != 0;

               CheckInvalidPathChars(path, checkAdditional);

               // Prevent duplicate checks.
               options &= ~GetFullPathOptions.CheckInvalidPathChars;

               if (checkAdditional)
                  options &= ~GetFullPathOptions.CheckAdditional;
            }

            // Do not remove trailing directory separator when path points to a drive like: "C:\"
            // Doing so makes path point to the current directory.

            if (path == null || path.Length <= 3 || (!path.StartsWith(LongPathPrefix, StringComparison.OrdinalIgnoreCase) && path[1] != VolumeSeparatorChar))
               options &= ~GetFullPathOptions.RemoveTrailingDirectorySeparator;
         }


         string pathLp = GetLongPathInternal(path, options);

         uint bufferSize = NativeMethods.MaxPathUnicode;


         // ChangeErrorMode is for the Win32 SetThreadErrorMode() method, used to suppress possible pop-ups.
         using (new NativeMethods.ChangeErrorMode(NativeMethods.ErrorMode.FailCriticalErrors))
         {
         startGetFullPathName:

            var buffer = new StringBuilder((int)bufferSize);
            uint returnLength = (transaction == null || !NativeMethods.IsAtLeastWindowsVista

               // GetFullPathName() / GetFullPathNameTransacted()
               // In the ANSI version of this function, the name is limited to MAX_PATH characters.
               // To extend this limit to 32,767 wide characters, call the Unicode version of the function and prepend "\\?\" to the path.
               // 2013-04-15: MSDN confirms LongPath usage.

               ? NativeMethods.GetFullPathName(pathLp, bufferSize, buffer, IntPtr.Zero)
               : NativeMethods.GetFullPathNameTransacted(pathLp, bufferSize, buffer, IntPtr.Zero, transaction.SafeHandle));

            if (returnLength != Win32Errors.NO_ERROR)
            {
               if (returnLength > bufferSize)
               {
                  bufferSize = returnLength;
                  goto startGetFullPathName;
               }
            }
            else
            {
               if ((options & GetFullPathOptions.ContinueOnNonExist) != 0)
                  return null;

               NativeError.ThrowException(pathLp);
            }

            return (options & GetFullPathOptions.AsLongPath) != 0
               ? GetLongPathInternal(buffer.ToString(), GetFullPathOptions.None)
               : GetRegularPathInternal(buffer.ToString(), GetFullPathOptions.None);
         }
      }
Beispiel #25
0
        internal static string GetFullPathCore(KernelTransaction transaction, string path, GetFullPathOptions options)
        {
            // Skip the special paths recognised by Windows kernel only.

            if (null != path)
            {
                if (path.StartsWith(GlobalRootPrefix, StringComparison.OrdinalIgnoreCase) ||
                    path.StartsWith(VolumePrefix, StringComparison.OrdinalIgnoreCase) ||
                    path.StartsWith(NonInterpretedPathPrefix, StringComparison.Ordinal))
                {
                    return(path);
                }
            }


            if (options != GetFullPathOptions.None)
            {
                if ((options & GetFullPathOptions.CheckInvalidPathChars) != 0)
                {
                    var checkAdditional = (options & GetFullPathOptions.CheckAdditional) != 0;

                    CheckInvalidPathChars(path, checkAdditional, false);

                    // Prevent duplicate checks.
                    options &= ~GetFullPathOptions.CheckInvalidPathChars;

                    if (checkAdditional)
                    {
                        options &= ~GetFullPathOptions.CheckAdditional;
                    }
                }

                // Do not remove trailing directory separator when path points to a drive like: "C:\"
                // Doing so makes path point to the current directory.

                // ".", "C:", "C:\"
                if (null == path || path.Length <= 3 || !path.StartsWith(LongPathPrefix, StringComparison.Ordinal) && path[1] != VolumeSeparatorChar)
                {
                    options &= ~GetFullPathOptions.RemoveTrailingDirectorySeparator;
                }
            }


            var  pathLp     = GetLongPathCore(path, options);
            uint bufferSize = NativeMethods.MaxPathUnicode;

            using (new NativeMethods.ChangeErrorMode(NativeMethods.ErrorMode.FailCriticalErrors))
            {
startGetFullPathName:

                var buffer = new StringBuilder((int)bufferSize);
                var returnLength = null == transaction || !NativeMethods.IsAtLeastWindowsVista

                                   // GetFullPathName() / GetFullPathNameTransacted()
                                   // 2013-04-15: MSDN confirms LongPath usage.

               ? NativeMethods.GetFullPathName(pathLp, bufferSize, buffer, IntPtr.Zero)
               : NativeMethods.GetFullPathNameTransacted(pathLp, bufferSize, buffer, IntPtr.Zero, transaction.SafeHandle);


                if (returnLength != Win32Errors.NO_ERROR)
                {
                    if (returnLength > bufferSize)
                    {
                        bufferSize = returnLength;
                        goto startGetFullPathName;
                    }
                }
                else
                {
                    if ((options & GetFullPathOptions.ContinueOnNonExist) != 0)
                    {
                        return(null);
                    }

                    NativeError.ThrowException(returnLength, pathLp);
                }


                var finalFullPath = (options & GetFullPathOptions.AsLongPath) != 0 ? GetLongPathCore(buffer.ToString(), GetFullPathOptions.None) : GetRegularPathCore(buffer.ToString(), GetFullPathOptions.None, false);


                finalFullPath = NormalizePath(finalFullPath, options);


                if ((options & GetFullPathOptions.KeepDotOrSpace) != 0)
                {
                    if (pathLp.EndsWith(CurrentDirectoryPrefix, StringComparison.Ordinal))
                    {
                        finalFullPath += CurrentDirectoryPrefix;
                    }

                    var lastChar = pathLp[pathLp.Length - 1];
                    if (char.IsWhiteSpace(lastChar))
                    {
                        finalFullPath += lastChar;
                    }
                }


                return(finalFullPath);
            }
        }
Beispiel #26
0
        private static string GetFullPathTackleCore(KernelTransaction transaction, string path, GetFullPathOptions options)
        {
            if (path != null)
            {
                if (path.StartsWith(GlobalRootPrefix, StringComparison.OrdinalIgnoreCase) || path.StartsWith(VolumePrefix, StringComparison.OrdinalIgnoreCase))
                {
                    return(path);
                }

                CheckInvalidUncPath(path);
            }

            CheckSupportedPathFormat(path, true, true);

            return(GetFullPathCore(transaction, path, options));
        }
Beispiel #27
0
        internal static string GetExtendedLengthPathCore(KernelTransaction transaction, string path, PathFormat pathFormat, GetFullPathOptions options)
        {
            if (null == path)
            {
                return(null);
            }


            switch (pathFormat)
            {
            case PathFormat.LongFullPath:
                if (options != GetFullPathOptions.None)
                {
                    // If pathFormat equals LongFullPath it is possible that the trailing backslashg ('\') is not added or removed.
                    // Prevent that.

                    options &= ~GetFullPathOptions.CheckAdditional;
                    options &= ~GetFullPathOptions.CheckInvalidPathChars;
                    options &= ~GetFullPathOptions.FullCheck;
                    options &= ~GetFullPathOptions.TrimEnd;

                    path = ApplyFullPathOptions(path, options);
                }

                return(path);


            case PathFormat.FullPath:
                return(GetLongPathCore(path, GetFullPathOptions.None));

            case PathFormat.RelativePath:
#if NET35
                // .NET 3.5 the TrimEnd option has no effect.
                options = options & ~GetFullPathOptions.TrimEnd;
#endif
                return(GetFullPathCore(transaction, path, GetFullPathOptions.AsLongPath | options));

            default:
                throw new ArgumentException("Invalid value: " + pathFormat, "pathFormat");
            }
        }
Beispiel #28
0
 public static string GetFullPath(string path, GetFullPathOptions options)
 {
     return(GetFullPathTackleCore(null, path, options));
 }
      /// <summary>Gets the path as a long full path.</summary>
      /// <returns>The path as an extended length path.</returns>
      /// <exception cref="ArgumentException">Thrown when one or more arguments have unsupported or illegal values.</exception>
      /// <param name="transaction">The transaction.</param>
      /// <param name="sourcePath">Full pathname of the source path to convert.</param>
      /// <param name="pathFormat">The path format to use.</param>
      /// <param name="options">Options for controlling the operation. Note that on .NET 3.5 the TrimEnd option has no effect.</param>
      internal static string GetExtendedLengthPathInternal(KernelTransaction transaction, string sourcePath, PathFormat pathFormat, GetFullPathOptions options)
      {
         switch (pathFormat)
         {
            case PathFormat.LongFullPath:
               return sourcePath;

            case PathFormat.FullPath:
               return GetLongPathInternal(sourcePath, GetFullPathOptions.None);

            case PathFormat.RelativePath:
#if NET35
               // .NET 3.5 the TrimEnd option has no effect.
               options = options & ~GetFullPathOptions.TrimEnd;
#endif
               return GetFullPathInternal(transaction, sourcePath, GetFullPathOptions.AsLongPath | options);

            default:
               throw new ArgumentException("Invalid value for " + typeof(PathFormat).Name + ": " + pathFormat);
         }
      }