public static Result ConvertToFspPath(out FspPath fspPath, ReadOnlySpan <byte> path) { UnsafeHelpers.SkipParamInit(out fspPath); int length = StringUtils.Copy(SpanHelpers.AsByteSpan(ref fspPath), path, PathTool.EntryNameLengthMax + 1); if (length >= PathTool.EntryNameLengthMax + 1) { return(ResultFs.TooLongPath.Log()); } Result rc = PathFormatter.SkipMountName(out ReadOnlySpan <byte> pathWithoutMountName, out _, new U8Span(path)); if (rc.IsFailure()) { return(rc); } if (!WindowsPath12.IsWindowsPath(pathWithoutMountName, true)) { Replace(SpanHelpers.AsByteSpan(ref fspPath).Slice(0, 0x300), AltDirectorySeparator, DirectorySeparator); } else if (fspPath.Str[0] == DirectorySeparator && fspPath.Str[1] == DirectorySeparator) { SpanHelpers.AsByteSpan(ref fspPath)[0] = AltDirectorySeparator; SpanHelpers.AsByteSpan(ref fspPath)[1] = AltDirectorySeparator; } return(Result.Success); }
private static Result ParseWindowsPathImpl(out ReadOnlySpan <byte> newPath, out int windowsPathLength, Span <byte> normalizeBuffer, ReadOnlySpan <byte> path, bool hasMountName) { Assert.SdkRequiresNotNull(path); UnsafeHelpers.SkipParamInit(out windowsPathLength); newPath = default; if (normalizeBuffer.Length != 0) { normalizeBuffer[0] = NullTerminator; } ReadOnlySpan <byte> currentPath = path; if (hasMountName && path.At(0) == DirectorySeparator) { if (path.At(1) == AltDirectorySeparator && path.At(2) == AltDirectorySeparator) { if (normalizeBuffer.Length == 0) { return(ResultFs.NotNormalized.Log()); } currentPath = path.Slice(1); } else if (path.Length != 0 && WindowsPath12.IsWindowsDrive(path.Slice(1))) { if (normalizeBuffer.Length == 0) { return(ResultFs.NotNormalized.Log()); } currentPath = path.Slice(1); } } if (WindowsPath12.IsWindowsDrive(currentPath)) { int winPathLength; for (winPathLength = 2; currentPath.At(winPathLength) != NullTerminator; winPathLength++) { if (currentPath[winPathLength] == DirectorySeparator || currentPath[winPathLength] == AltDirectorySeparator) { break; } } if (normalizeBuffer.IsEmpty) { for (int i = 0; i < winPathLength; i++) { if (currentPath[i] == '\\') { return(ResultFs.NotNormalized.Log()); } } } if (!normalizeBuffer.IsEmpty) { if (winPathLength >= normalizeBuffer.Length) { return(ResultFs.TooLongPath.Log()); } currentPath.Slice(0, winPathLength).CopyTo(normalizeBuffer); normalizeBuffer[winPathLength] = NullTerminator; PathUtility12.Replace(normalizeBuffer.Slice(0, winPathLength), AltDirectorySeparator, DirectorySeparator); } newPath = currentPath.Slice(winPathLength); windowsPathLength = winPathLength; return(Result.Success); } if (WindowsPath12.IsDosDevicePath(currentPath)) { int dosPathLength = WindowsPath12.GetDosDevicePathPrefixLength(); if (WindowsPath12.IsWindowsDrive(currentPath.Slice(dosPathLength))) { dosPathLength += 2; } else { dosPathLength--; } if (!normalizeBuffer.IsEmpty) { if (dosPathLength >= normalizeBuffer.Length) { return(ResultFs.TooLongPath.Log()); } currentPath.Slice(0, dosPathLength).CopyTo(normalizeBuffer); normalizeBuffer[dosPathLength] = NullTerminator; PathUtility12.Replace(normalizeBuffer.Slice(0, dosPathLength), DirectorySeparator, AltDirectorySeparator); } newPath = currentPath.Slice(dosPathLength); windowsPathLength = dosPathLength; return(Result.Success); } if (WindowsPath12.IsUncPath(currentPath, false, true)) { Result rc; ReadOnlySpan <byte> finalPath = currentPath; if (currentPath.At(2) == DirectorySeparator || currentPath.At(2) == AltDirectorySeparator) { return(ResultFs.InvalidPathFormat.Log()); } int currentComponentOffset = 0; int pos; for (pos = 2; currentPath.At(pos) != NullTerminator; pos++) { if (currentPath.At(pos) == DirectorySeparator || currentPath.At(pos) == AltDirectorySeparator) { if (currentComponentOffset != 0) { rc = CheckSharedName( currentPath.Slice(currentComponentOffset, pos - currentComponentOffset)); if (rc.IsFailure()) { return(rc); } finalPath = currentPath.Slice(pos); break; } if (currentPath.At(pos + 1) == DirectorySeparator || currentPath.At(pos + 1) == AltDirectorySeparator) { return(ResultFs.InvalidPathFormat.Log()); } rc = CheckHostName(currentPath.Slice(2, pos - 2)); if (rc.IsFailure()) { return(rc); } currentComponentOffset = pos + 1; } } if (currentComponentOffset == pos) { return(ResultFs.InvalidPathFormat.Log()); } if (currentComponentOffset != 0 && finalPath == currentPath) { rc = CheckSharedName(currentPath.Slice(currentComponentOffset, pos - currentComponentOffset)); if (rc.IsFailure()) { return(rc); } finalPath = currentPath.Slice(pos); } ref byte currentPathStart = ref MemoryMarshal.GetReference(currentPath); ref byte finalPathStart = ref MemoryMarshal.GetReference(finalPath);