diff --git a/src/LibHac/Fs/Common/DirectoryPathParser.cs b/src/LibHac/Fs/Common/DirectoryPathParser.cs index d59673fe..6eea2a3e 100644 --- a/src/LibHac/Fs/Common/DirectoryPathParser.cs +++ b/src/LibHac/Fs/Common/DirectoryPathParser.cs @@ -3,8 +3,13 @@ using LibHac.Common; using LibHac.Diag; using static LibHac.Fs.StringTraits; -namespace LibHac.Fs.Common; +// ReSharper disable once CheckNamespace +namespace LibHac.Fs; +/// +/// Iterates through each directory in a path beginning with the root directory. +/// +/// Based on FS 13.1.0 (nnSdk 13.4.0) [NonCopyableDisposable] public ref struct DirectoryPathParser { @@ -15,11 +20,26 @@ public ref struct DirectoryPathParser // Todo: Make private so we can use the GetCurrentPath method once lifetime tracking is better public Path CurrentPath; + public DirectoryPathParser() + { + _buffer = Span.Empty; + _replacedChar = 0; + _position = 0; + CurrentPath = new Path(); + } + public void Dispose() { CurrentPath.Dispose(); } + /// + /// Initializes this with a new . The + /// should not be a fixed path that was just initialized with + /// because we need it to have an allocated write buffer. + /// + /// The to iterate. Must have an allocated write buffer. + /// The of the operation. public Result Initialize(ref Path path) { Span pathBuffer = path.GetWriteBufferLength() != 0 ? path.GetWriteBuffer() : Span.Empty; @@ -116,4 +136,4 @@ public ref struct DirectoryPathParser _position = i; return entry; } -} +} \ No newline at end of file diff --git a/src/LibHac/Fs/Common/PathUtility.cs b/src/LibHac/Fs/Common/PathUtility.cs index e6f1f708..a3984590 100644 --- a/src/LibHac/Fs/Common/PathUtility.cs +++ b/src/LibHac/Fs/Common/PathUtility.cs @@ -1,6 +1,7 @@ using System; using LibHac.Common; using LibHac.Diag; +using LibHac.Fs.Impl; using LibHac.FsSrv.Sf; using LibHac.Util; using static LibHac.Fs.StringTraits; @@ -11,7 +12,7 @@ namespace LibHac.Fs; /// /// Contains various utility functions for working with paths. /// -/// Based on FS 12.1.0 (nnSdk 12.3.1) +/// Based on FS 13.1.0 (nnSdk 13.4.0) public static class PathUtility { public static void Replace(Span buffer, byte currentChar, byte newChar) @@ -46,16 +47,6 @@ public static class PathUtility (path.Length < 3 || path[2] == NullTerminator || path[2] == DirectorySeparator); } - public static bool IsSeparator(byte c) - { - return c == DirectorySeparator; - } - - public static bool IsNul(byte c) - { - return c == NullTerminator; - } - public static Result ConvertToFspPath(out FspPath fspPath, ReadOnlySpan path) { UnsafeHelpers.SkipParamInit(out fspPath); @@ -65,7 +56,7 @@ public static class PathUtility if (length >= PathTool.EntryNameLengthMax + 1) return ResultFs.TooLongPath.Log(); - Result rc = PathFormatter.SkipMountName(out ReadOnlySpan pathWithoutMountName, out _, + Result rc = PathFormatter.SkipMountName(out ReadOnlySpan pathWithoutMountName, out int skipLength, new U8Span(path)); if (rc.IsFailure()) return rc; @@ -73,10 +64,16 @@ public static class PathUtility { Replace(SpanHelpers.AsByteSpan(ref fspPath).Slice(0, 0x300), AltDirectorySeparator, DirectorySeparator); } - else if (fspPath.Str[0] == DirectorySeparator && fspPath.Str[1] == DirectorySeparator) + else { - SpanHelpers.AsByteSpan(ref fspPath)[0] = AltDirectorySeparator; - SpanHelpers.AsByteSpan(ref fspPath)[1] = AltDirectorySeparator; + bool isHostOrNoMountName = skipLength == 0 || StringUtils.Compare(path, CommonMountNames.HostRootFileSystemMountName, + CommonMountNames.HostRootFileSystemMountName.Length) == 0; + + if (isHostOrNoMountName && WindowsPath.IsUncPath(path.Slice(skipLength), true, false)) + { + SpanHelpers.AsByteSpan(ref fspPath)[skipLength] = AltDirectorySeparator; + SpanHelpers.AsByteSpan(ref fspPath)[skipLength + 1] = AltDirectorySeparator; + } } return Result.Success; @@ -245,4 +242,4 @@ public static class PathUtility { return IsCurrentDirectory(path) || IsParentDirectory(path); } -} +} \ No newline at end of file diff --git a/src/LibHac/Fs/Common/WindowsPath.cs b/src/LibHac/Fs/Common/WindowsPath.cs index a3bb2d63..57657537 100644 --- a/src/LibHac/Fs/Common/WindowsPath.cs +++ b/src/LibHac/Fs/Common/WindowsPath.cs @@ -10,7 +10,7 @@ namespace LibHac.Fs; /// /// Contains functions for working with Windows paths. /// -/// Based on FS 12.1.0 (nnSdk 12.3.1) +/// Based on FS 13.1.0 (nnSdk 13.4.0) public static class WindowsPath { private const int WindowsDriveLength = 2; @@ -254,4 +254,4 @@ public static class WindowsPath return Result.Success; } -} +} \ No newline at end of file diff --git a/src/LibHac/Fs/Fsa/MountUtility.cs b/src/LibHac/Fs/Fsa/MountUtility.cs index 38096e77..699b8914 100644 --- a/src/LibHac/Fs/Fsa/MountUtility.cs +++ b/src/LibHac/Fs/Fsa/MountUtility.cs @@ -22,7 +22,7 @@ public static class MountUtility if (WindowsPath.IsWindowsDrive(path) || WindowsPath.IsUncPath(path)) { StringUtils.Copy(mountName.Name, CommonPaths.HostRootFileSystemMountName); - mountName.Name[PathTool.MountNameLengthMax] = StringTraits.NullTerminator; + mountName.Name[PathTool.MountNameLengthMax] = NullTerminator; subPath = path; return Result.Success; @@ -30,7 +30,7 @@ public static class MountUtility for (int i = 0; i <= maxMountLen; i++) { - if (path[i] == StringTraits.DriveSeparator) + if (path[i] == DriveSeparator) { mountLen = i; break; @@ -53,7 +53,7 @@ public static class MountUtility return ResultFs.InvalidPathFormat.Log(); path.Value.Slice(0, mountLen).CopyTo(mountName.Name); - mountName.Name[mountLen] = StringTraits.NullTerminator; + mountName.Name[mountLen] = NullTerminator; subPath = subPathTemp; return Result.Success; diff --git a/src/LibHac/FsSystem/Utility.cs b/src/LibHac/FsSystem/Utility.cs index 0cc151bb..ebfcf855 100644 --- a/src/LibHac/FsSystem/Utility.cs +++ b/src/LibHac/FsSystem/Utility.cs @@ -1,7 +1,6 @@ using System; using LibHac.Common; using LibHac.Fs; -using LibHac.Fs.Common; using LibHac.Fs.Fsa; using LibHac.Os; @@ -423,4 +422,4 @@ internal static class Utility outUniqueLock.Set(ref uniqueLock.Ref()); return Result.Success; } -} +} \ No newline at end of file