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] == 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);
}
}
// Technically this doesn't matter but we used to throw for this case
if (string.IsNullOrWhiteSpace(path))
throw new ArgumentException(SR.Arg_PathIllegal);
// 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;
}