Beispiel #1
0
        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);
        }
Beispiel #2
0
        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);