private static int GetDirectoryOrRootLength(string path, bool skipTrailingSlash = false) { int rootLength; PathFormat pathFormat = Paths.GetPathFormat(path, out rootLength); if (pathFormat == PathFormat.UnknownFormat) { return(-1); } int length = path.Length; if (rootLength == path.Length) { return(length); } if (skipTrailingSlash && EndsInDirectorySeparator(path)) { length--; } while (((length > rootLength) && (path[--length] != DirectorySeparator)) && (path[length] != AltDirectorySeparator)) { } return(length); }
/// <summary> /// Get the canonical volume root (e.g. the \\?\VolumeGuid format) for the given path. The path must not be relative. /// </summary> /// <exception cref="ArgumentException">Thrown if the path is relative or indeterminate.</exception> /// <exception cref="System.IO.IOException">Thrown if unable to get the root from the OS.</exception> public static string GetCanonicalRoot(this IExtendedFileService extendedFileService, IFileService fileService, string path) { if (Paths.IsPartiallyQualified(path)) { throw new ArgumentException(nameof(path)); } path = fileService.GetFullPath(path); int rootLength; var format = Paths.GetPathFormat(path, out rootLength); if (format == PathFormat.UnknownFormat) { throw new ArgumentException(nameof(format)); } string root = path.Substring(0, rootLength); string canonicalRoot = root; switch (format) { case PathFormat.UniformNamingConvention: if (Paths.IsDevice(path)) { canonicalRoot = @"\\" + root.Substring(Paths.ExtendedUncPrefix.Length); } break; case PathFormat.LocalFullyQualified: canonicalRoot = extendedFileService.GetVolumeName(root); break; } return(canonicalRoot); }
/// <summary> /// Gets the format and root length of the specified path. Returns -1 for the root length /// if the path format can't be determined. /// </summary> /// <remarks> /// Does not look for invalid characters beyond what makes for an indeterminate path. /// </remarks> public unsafe static PathFormat GetPathFormat(string path, out int rootLength) { if (path == null || path.Length == 0 || path[0] == ':') { rootLength = -1; return(PathFormat.UnknownFormat); } fixed(char *start = path) { return(Paths.GetPathFormat(start, path.Length, out rootLength)); } }
/// <summary> /// Get the canonical volume root (e.g. the \\?\VolumeGuid format) for the given path. The path must not be relative. /// </summary> /// <exception cref="ArgumentException">Thrown if the path is relative or indeterminate.</exception> /// <exception cref="System.IO.IOException">Thrown if unable to get the root from the OS.</exception> public static string GetCanonicalRoot(this IExtendedFileService extendedFileService, IFileService fileService, string path) { if (Paths.IsRelative(path)) { throw new ArgumentException(); } path = fileService.GetFullPath(path); int rootLength; var format = Paths.GetPathFormat(path, out rootLength); if (format == PathFormat.UnknownFormat) { throw new ArgumentException(); } string root = path.Substring(0, rootLength); string simpleRoot = root; string canonicalRoot = root; switch (format) { case PathFormat.UniformNamingConventionExtended: simpleRoot = @"\\" + root.Substring(Paths.ExtendedUncPrefix.Length); goto case PathFormat.UniformNamingConvention; case PathFormat.UniformNamingConvention: canonicalRoot = simpleRoot; break; case PathFormat.VolumeAbsoluteExtended: case PathFormat.DriveAbsolute: canonicalRoot = extendedFileService.GetVolumeName(root); simpleRoot = extendedFileService.GetMountPoint(root); break; } return(canonicalRoot); }