コード例 #1
0
        private static unsafe void GetFullPathName(string path, ref StringBuffer fullPath)
        {
            // If the string starts with an extended prefix we would need to remove it from the path before we call GetFullPathName as
            // it doesn't root extended paths correctly. We don't currently resolve extended paths, so we'll just assert here.
            Debug.Assert(PathInternal.IsPartiallyQualified(path) || !PathInternal.IsExtended(path));

            // Historically we would skip leading spaces *only* if the path started with a drive " C:" or a UNC " \\"
            int startIndex = PathInternal.PathStartSkip(path);

            fixed(char *pathStart = path)
            {
                uint result = 0;

                while ((result = Interop.Kernel32.GetFullPathNameW(pathStart + startIndex, (uint)fullPath.Capacity, fullPath.UnderlyingArray, IntPtr.Zero)) > fullPath.Capacity)
                {
                    // Reported size is greater than the buffer size. Increase the capacity.
                    fullPath.EnsureCapacity(checked ((int)result));
                }

                if (result == 0)
                {
                    // Failure, get the error and throw
                    int errorCode = Marshal.GetLastWin32Error();
                    if (errorCode == 0)
                    {
                        errorCode = Interop.Errors.ERROR_BAD_PATHNAME;
                    }
                    throw Win32Marshal.GetExceptionForWin32Error(errorCode, path);
                }

                fullPath.Length = checked ((int)result);
            }
        }
コード例 #2
0
        unsafe private static void GetFullPathName(string path, StringBuffer fullPath)
        {
            // If the string starts with an extended prefix we would need to remove it from the path before we call GetFullPathName as
            // it doesn't root extended paths correctly. We don't currently resolve extended paths, so we'll just assert here.
            Contract.Assert(PathInternal.IsPartiallyQualified(path) || !PathInternal.IsExtended(path));

            // Historically we would skip leading spaces *only* if the path started with a drive " C:" or a UNC " \\"
            int startIndex = PathInternal.PathStartSkip(path);

            fixed(char *pathStart = path)
            {
                uint result = 0;

                while ((result = Win32Native.GetFullPathNameW(pathStart + startIndex, fullPath.CharCapacity, fullPath.GetHandle(), IntPtr.Zero)) > fullPath.CharCapacity)
                {
                    // Reported size (which does not include the null) is greater than the buffer size. Increase the capacity.
                    fullPath.EnsureCharCapacity(result);
                }

                if (result == 0)
                {
                    // Failure, get the error and throw
                    int errorCode = Marshal.GetLastWin32Error();
                    if (errorCode == 0)
                    {
                        errorCode = Win32Native.ERROR_BAD_PATHNAME;
                    }
                    __Error.WinIOError(errorCode, path);
                }

                fullPath.Length = result;
            }
        }
コード例 #3
0
        private unsafe static void GetFullPathName(string path, StringBuffer fullPath)
        {
            int num = PathInternal.PathStartSkip(path);

            fixed(string text = path)
            {
                char *ptr = text;

                if (ptr != null)
                {
                    ptr += RuntimeHelpers.OffsetToStringData / 2;
                }
                uint fullPathNameW;

                while ((fullPathNameW = Win32Native.GetFullPathNameW(ptr + num, fullPath.CharCapacity, fullPath.GetHandle(), IntPtr.Zero)) > fullPath.CharCapacity)
                {
                    fullPath.EnsureCharCapacity(fullPathNameW);
                }
                if (fullPathNameW == 0U)
                {
                    int num2 = Marshal.GetLastWin32Error();
                    if (num2 == 0)
                    {
                        num2 = 161;
                    }
                    __Error.WinIOError(num2, path);
                }
                fullPath.Length = fullPathNameW;
            }
        }
コード例 #4
0
        // Token: 0x0600195D RID: 6493 RVA: 0x000546C8 File Offset: 0x000528C8
        internal static string NormalizeDirectorySeparators(string path)
        {
            if (string.IsNullOrEmpty(path))
            {
                return(path);
            }
            int num = PathInternal.PathStartSkip(path);

            if (num == 0)
            {
                bool flag = true;
                for (int i = 0; i < path.Length; i++)
                {
                    char c = path[i];
                    if (PathInternal.IsDirectorySeparator(c) && (c != Path.DirectorySeparatorChar || (i > 0 && i + 1 < path.Length && PathInternal.IsDirectorySeparator(path[i + 1]))))
                    {
                        flag = false;
                        break;
                    }
                }
                if (flag)
                {
                    return(path);
                }
            }
            StringBuilder stringBuilder = StringBuilderCache.Acquire(path.Length);

            if (PathInternal.IsDirectorySeparator(path[num]))
            {
                num++;
                stringBuilder.Append(Path.DirectorySeparatorChar);
            }
            int j = num;

            while (j < path.Length)
            {
                char c = path[j];
                if (!PathInternal.IsDirectorySeparator(c))
                {
                    goto IL_D2;
                }
                if (j + 1 >= path.Length || !PathInternal.IsDirectorySeparator(path[j + 1]))
                {
                    c = Path.DirectorySeparatorChar;
                    goto IL_D2;
                }
IL_DA:
                j++;
                continue;
IL_D2:
                stringBuilder.Append(c);
                goto IL_DA;
            }
            return(StringBuilderCache.GetStringAndRelease(stringBuilder));
        }
コード例 #5
0
        private static string NormalizePath(string path, bool fullCheck = true, bool expandShortPaths = true)
        {
            Debug.Assert(path != null, "path can't be null");

            bool isExtended = PathInternal.IsExtended(path);

            if (fullCheck)
            {
                // Embedded null characters are the only invalid character case we want to check up front.
                // This is because the nulls will signal the end of the string to Win32 and therefore have
                // unpredictable results. Other invalid characters we give a chance to be normalized out.
                if (path.IndexOf('\0') != -1)
                {
                    throw new ArgumentException(SR.Argument_InvalidPathChars, "path");
                }

                // Toss out paths with colons that aren't a valid drive specifier.
                // Cannot start with a colon and can only be of the form "C:" or "\\?\C:".
                // (Note that we used to explicitly check "http:" and "file:"- these are caught by this check now.)
                int startIndex = PathInternal.PathStartSkip(path) + 2;
                if (isExtended)
                {
                    startIndex += PathInternal.ExtendedPathPrefix.Length;
                }

                if ((path.Length > 0 && path[0] == VolumeSeparatorChar) ||
                    (path.Length >= startIndex && path[startIndex - 1] == VolumeSeparatorChar && !PathInternal.IsValidDriveChar(path[startIndex - 2])) ||
                    (path.Length > startIndex && path.IndexOf(VolumeSeparatorChar, startIndex) != -1))
                {
                    throw new NotSupportedException(SR.Argument_PathFormatNotSupported);
                }
            }

            if (isExtended)
            {
                return(NormalizeExtendedPath(path, fullCheck));
            }
            else
            {
                // Technically this doesn't matter but we used to throw for this case
                if (String.IsNullOrWhiteSpace(path))
                {
                    throw new ArgumentException(SR.Arg_PathIllegal);
                }

                return(PathHelper.Normalize(path, fullCheck, expandShortPaths));
            }
        }
コード例 #6
0
        private StringBuilder GetFullPathName(string path)
        {
            // Historically we would skip leading spaces *only* if the path started with a drive " C:" or a UNC " \\"
            int startIndex = PathInternal.PathStartSkip(path);
            int capacity   = path.Length;

            if (PathInternal.IsRelative(path))
            {
                // If the initial path is relative the final path will likely be no more than the current directory length (which can only
                // be MaxPath) so we'll pick that as a reasonable start.
                capacity += PathInternal.MaxShortPath;
            }
            else
            {
                // If the string starts with an extended prefix we would need to remove it from the path before we call GetFullPathName as
                // it doesn't root extended paths correctly. We don't currently resolve extended paths, so we'll just assert here.
                Debug.Assert(!PathInternal.IsExtended(path));
            }

            StringBuilder outputBuffer = this.GetOutputBuffer(capacity);

            fixed(char *pathStart = path)
            {
                int result = 0;

                while ((result = Interop.mincore.GetFullPathNameW(pathStart + startIndex, outputBuffer.Capacity + 1, outputBuffer, IntPtr.Zero)) > outputBuffer.Capacity)
                {
                    // Reported size (which does not include the null) is greater than the buffer size. Increase the capacity.
                    outputBuffer.Capacity = result;
                }

                if (result == 0)
                {
                    // Failure, get the error and throw
                    int errorCode = Marshal.GetLastWin32Error();
                    if (errorCode == 0)
                    {
                        errorCode = Interop.mincore.Errors.ERROR_BAD_PATHNAME;
                    }
                    throw Win32Marshal.GetExceptionForWin32Error(errorCode, path);
                }
            }

            return(outputBuffer);
        }
コード例 #7
0
ファイル: Path.Windows.cs プロジェクト: vehar/coreclr
        // Expands the given path to a fully qualified path.
        public static string GetFullPath(string path)
        {
            if (path == null)
            {
                throw new ArgumentNullException(nameof(path));
            }

            // Embedded null characters are the only invalid character case we want to check up front.
            // This is because the nulls will signal the end of the string to Win32 and therefore have
            // unpredictable results. Other invalid characters we give a chance to be normalized out.
            if (path.IndexOf('\0') != -1)
            {
                throw new ArgumentException(SR.Argument_InvalidPathChars, nameof(path));
            }

            if (PathInternal.IsExtended(path))
            {
                // We can't really know what is valid for all cases of extended paths.
                //
                //  - object names can include other characters as well (':', '/', etc.)
                //  - even file objects have different rules (pipe names can contain most characters)
                //
                // As such we will do no further analysis of extended paths to avoid blocking known and unknown
                // scenarios as well as minimizing compat breaks should we block now and need to unblock later.
                return(path);
            }

            bool isDevice = PathInternal.IsDevice(path);

            if (!isDevice)
            {
                // Toss out paths with colons that aren't a valid drive specifier.
                // Cannot start with a colon and can only be of the form "C:".
                // (Note that we used to explicitly check "http:" and "file:"- these are caught by this check now.)
                int startIndex = PathInternal.PathStartSkip(path);

                // Move past the colon
                startIndex += 2;

                if ((path.Length > 0 && path[0] == PathInternal.VolumeSeparatorChar) ||
                    (path.Length >= startIndex && path[startIndex - 1] == PathInternal.VolumeSeparatorChar && !PathInternal.IsValidDriveChar(path[startIndex - 2])) ||
                    (path.Length > startIndex && path.IndexOf(PathInternal.VolumeSeparatorChar, startIndex) != -1))
                {
                    throw new NotSupportedException(SR.Format(SR.Argument_PathFormatNotSupported_Path, path));
                }
            }

            // Technically this doesn't matter but we used to throw for this case
            if (PathInternal.IsEffectivelyEmpty(path))
            {
                throw new ArgumentException(SR.Arg_PathEmpty, nameof(path));
            }

            // We don't want to check invalid characters for device format- see comments for extended above
            string fullPath = PathHelper.Normalize(path, checkInvalidCharacters: !isDevice, expandShortPaths: true);

            if (!isDevice)
            {
                // Emulate FileIOPermissions checks, retained for compatibility (normal invalid characters have already been checked)
                if (PathInternal.HasWildCardCharacters(fullPath))
                {
                    throw new ArgumentException(SR.Argument_InvalidPathChars, nameof(path));
                }
            }

            return(fullPath);
        }
コード例 #8
0
        // Token: 0x06001941 RID: 6465 RVA: 0x00053E6C File Offset: 0x0005206C
        internal static bool HasInvalidVolumeSeparator(string path)
        {
            int num = (!AppContextSwitches.UseLegacyPathHandling && PathInternal.IsExtended(path)) ? "\\\\?\\".Length : PathInternal.PathStartSkip(path);

            return((path.Length > num && path[num] == Path.VolumeSeparatorChar) || (path.Length >= num + 2 && path[num + 1] == Path.VolumeSeparatorChar && !PathInternal.IsValidDriveChar(path[num])) || (path.Length > num + 2 && path.IndexOf(Path.VolumeSeparatorChar, num + 2) != -1));
        }
コード例 #9
0
        /// <summary>
        /// Normalize the path and check for bad characters or other invalid syntax.
        /// </summary>
        /// <remarks>
        /// The legacy NormalizePath
        /// </remarks>
        private static string NormalizeAndValidatePath(string path)
        {
            Debug.Assert(path != null, "path can't be null");

            // Embedded null characters are the only invalid character case we want to check up front.
            // This is because the nulls will signal the end of the string to Win32 and therefore have
            // unpredictable results. Other invalid characters we give a chance to be normalized out.
            if (path.IndexOf('\0') != -1)
            {
                throw new ArgumentException(SR.Argument_InvalidPathChars, "path");
            }

            // Toss out paths with colons that aren't a valid drive specifier.
            // Cannot start with a colon and can only be of the form "C:" or "\\?\C:".
            // (Note that we used to explicitly check "http:" and "file:"- these are caught by this check now.)
            int  startIndex = PathInternal.PathStartSkip(path);
            bool isExtended = path.Length >= PathInternal.ExtendedPathPrefix.Length + startIndex &&
                              path.IndexOf(PathInternal.ExtendedPathPrefix, startIndex, PathInternal.ExtendedPathPrefix.Length, StringComparison.Ordinal) >= 0;

            if (isExtended)
            {
                startIndex += PathInternal.ExtendedPathPrefix.Length;
            }

            // Move past the colon
            startIndex += 2;

            if ((path.Length > 0 && path[0] == VolumeSeparatorChar) ||
                (path.Length >= startIndex && path[startIndex - 1] == VolumeSeparatorChar && !PathInternal.IsValidDriveChar(path[startIndex - 2])) ||
                (path.Length > startIndex && path.IndexOf(VolumeSeparatorChar, startIndex) != -1))
            {
                throw new NotSupportedException(SR.Argument_PathFormatNotSupported);
            }

            if (isExtended)
            {
                // If the path is in extended syntax, we don't need to normalize, but we still do some basic validity checks
                if (!ValidateExtendedPath(path))
                {
                    throw new ArgumentException(SR.Arg_PathIllegal);
                }

                // \\?\GLOBALROOT gives access to devices out of the scope of the current user, we
                // don't want to allow this for security reasons.
                // https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247.aspx#nt_namespaces
                if (path.StartsWith(@"\\?\globalroot", StringComparison.OrdinalIgnoreCase))
                {
                    throw new ArgumentException(SR.Arg_PathGlobalRoot);
                }


                // Look for illegal path characters.
                PathInternal.CheckInvalidPathChars(path);

                return(path);
            }
            else
            {
                // Technically this doesn't matter but we used to throw for this case
                if (String.IsNullOrWhiteSpace(path))
                {
                    throw new ArgumentException(SR.Arg_PathIllegal);
                }

                return(PathHelper.Normalize(path, checkInvalidCharacters: true, expandShortPaths: true));
            }
        }