Swap in the new fsa code except for some access log calls

This commit is contained in:
Alex Barney 2021-02-21 00:00:59 -07:00
parent 0dc433d8a2
commit 684fcd460f
39 changed files with 123 additions and 827 deletions

View File

@ -3,6 +3,7 @@ using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using LibHac.Common;
using LibHac.Fs;
using LibHac.Fs.Fsa;
namespace LibHac.Bcat.Detail.Service.Core
{

View File

@ -3,6 +3,7 @@ using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using LibHac.Common;
using LibHac.Fs;
using LibHac.Fs.Fsa;
using LibHac.Util;
namespace LibHac.Bcat.Detail.Service.Core

View File

@ -2,6 +2,7 @@
using System.Diagnostics;
using LibHac.Common;
using LibHac.Fs;
using LibHac.Fs.Fsa;
using LibHac.Fs.Shim;
using static LibHac.Fs.StringTraits;

View File

@ -3,6 +3,7 @@ using LibHac.Bcat.Detail.Ipc;
using LibHac.Bcat.Detail.Service.Core;
using LibHac.Common;
using LibHac.Fs;
using LibHac.Fs.Fsa;
namespace LibHac.Bcat.Detail.Service
{

View File

@ -29,6 +29,7 @@ namespace LibHac.Diag
if (condition)
return;
result.Log();
DoAbort(result, message);
}

View File

@ -293,13 +293,13 @@ namespace LibHac.Fs.Impl
}
public static void OutputAccessLog(this FileSystemClientImpl fs, Result result, Tick start, Tick end,
FileHandle2 handle, U8Span message, [CallerMemberName] string functionName = "")
FileHandle handle, U8Span message, [CallerMemberName] string functionName = "")
{
throw new NotImplementedException();
}
public static void OutputAccessLog(this FileSystemClientImpl fs, Result result, Tick start, Tick end,
DirectoryHandle2 handle, U8Span message, [CallerMemberName] string functionName = "")
DirectoryHandle handle, U8Span message, [CallerMemberName] string functionName = "")
{
throw new NotImplementedException();
}
@ -322,13 +322,13 @@ namespace LibHac.Fs.Impl
}
public static void OutputAccessLogUnlessResultSuccess(this FileSystemClientImpl fs, Result result, Tick start,
Tick end, FileHandle2 handle, U8Span message, [CallerMemberName] string functionName = "")
Tick end, FileHandle handle, U8Span message, [CallerMemberName] string functionName = "")
{
throw new NotImplementedException();
}
public static void OutputAccessLogUnlessResultSuccess(this FileSystemClientImpl fs, Result result, Tick start,
Tick end, DirectoryHandle2 handle, U8Span message, [CallerMemberName] string functionName = "")
Tick end, DirectoryHandle handle, U8Span message, [CallerMemberName] string functionName = "")
{
throw new NotImplementedException();
}
@ -383,7 +383,7 @@ namespace LibHac.Fs.Impl
return fs.IsEnabledAccessLog(AccessLogTarget.All);
}
public static bool IsEnabledHandleAccessLog(this FileSystemClientImpl _, FileHandle2 handle)
public static bool IsEnabledHandleAccessLog(this FileSystemClientImpl _, FileHandle handle)
{
if (handle.File is null)
return true;
@ -392,7 +392,7 @@ namespace LibHac.Fs.Impl
return fsAccessor is not null && fsAccessor.IsEnabledAccessLog();
}
public static bool IsEnabledHandleAccessLog(this FileSystemClientImpl _, DirectoryHandle2 handle)
public static bool IsEnabledHandleAccessLog(this FileSystemClientImpl _, DirectoryHandle handle)
{
if (handle.Directory is null)
return true;

View File

@ -1,30 +1,12 @@
using System;
using LibHac.Fs.Accessors;
namespace LibHac.Fs
namespace LibHac.Fs
{
public struct DirectoryHandle : IDisposable
{
internal readonly DirectoryAccessor Directory;
internal DirectoryHandle(DirectoryAccessor directory)
{
Directory = directory;
}
public int GetId() => Directory?.GetHashCode() ?? 0;
public void Dispose()
{
Directory.Parent.FsClient.CloseDirectory(this);
}
}
public readonly struct DirectoryHandle2
public readonly struct DirectoryHandle
{
internal readonly Impl.DirectoryAccessor Directory;
internal DirectoryHandle2(Impl.DirectoryAccessor directory)
public bool IsValid => Directory is not null;
internal DirectoryHandle(Impl.DirectoryAccessor directory)
{
Directory = directory;
}

View File

@ -1,30 +1,12 @@
using System;
using LibHac.Fs.Accessors;
namespace LibHac.Fs
namespace LibHac.Fs
{
public struct FileHandle : IDisposable
{
internal readonly FileAccessor File;
internal FileHandle(FileAccessor file)
{
File = file;
}
public int GetId() => File?.GetHashCode() ?? 0;
public void Dispose()
{
File.Parent.FsClient.CloseFile(this);
}
}
public readonly struct FileHandle2
public readonly struct FileHandle
{
internal readonly Impl.FileAccessor File;
internal FileHandle2(Impl.FileAccessor file)
public bool IsValid => File is not null;
internal FileHandle(Impl.FileAccessor file)
{
File = file;
}

View File

@ -1,4 +1,5 @@
using System;
using LibHac.Fs.Fsa;
namespace LibHac.Fs
{
@ -12,13 +13,13 @@ namespace LibHac.Fs
private long FileSize { get; set; } = InvalidSize;
private bool CloseHandle { get; }
public FileHandleStorage(FileHandle handle) : this(handle, false) { }
public FileHandleStorage(FileSystemClient fsClient, FileHandle handle) : this(fsClient, handle, false) { }
public FileHandleStorage(FileHandle handle, bool closeHandleOnDispose)
public FileHandleStorage(FileSystemClient fsClient, FileHandle handle, bool closeHandleOnDispose)
{
FsClient = fsClient;
Handle = handle;
CloseHandle = closeHandleOnDispose;
FsClient = Handle.File.Parent.FsClient;
}
protected override Result DoRead(long offset, Span<byte> destination)
@ -47,7 +48,7 @@ namespace LibHac.Fs
if (!IsRangeValid(offset, source.Length, FileSize)) return ResultFs.OutOfRange.Log();
return FsClient.WriteFile(Handle, offset, source);
return FsClient.WriteFile(Handle, offset, source, WriteOption.None);
}
}

View File

@ -73,21 +73,6 @@ namespace LibHac.Fs
}
internal bool IsEnabledAccessLog()
{
return IsEnabledAccessLog(AccessLogTarget.All);
}
internal bool IsEnabledFileSystemAccessorAccessLog(U8Span mountName)
{
if (MountTable.Find(mountName.ToString(), out FileSystemAccessor accessor).IsFailure())
{
return true;
}
return accessor.IsAccessLogEnabled;
}
internal void EnableFileSystemAccessorAccessLog(U8Span mountName)
{
if (MountTable.Find(mountName.ToString(), out FileSystemAccessor accessor).IsFailure())
@ -98,31 +83,11 @@ namespace LibHac.Fs
accessor.IsAccessLogEnabled = true;
}
internal bool IsEnabledHandleAccessLog(FileHandle handle)
{
return handle.File.Parent.IsAccessLogEnabled;
}
internal bool IsEnabledHandleAccessLog(DirectoryHandle handle)
{
return handle.Directory.Parent.IsAccessLogEnabled;
}
internal void OutputAccessLog(Result result, System.TimeSpan startTime, System.TimeSpan endTime, string message, [CallerMemberName] string caller = "")
{
OutputAccessLogImpl(result, startTime, endTime, 0, message, caller);
}
internal void OutputAccessLog(Result result, System.TimeSpan startTime, System.TimeSpan endTime, FileHandle handle, string message, [CallerMemberName] string caller = "")
{
OutputAccessLogImpl(result, startTime, endTime, handle.GetId(), message, caller);
}
internal void OutputAccessLog(Result result, System.TimeSpan startTime, System.TimeSpan endTime, DirectoryHandle handle, string message, [CallerMemberName] string caller = "")
{
OutputAccessLogImpl(result, startTime, endTime, handle.GetId(), message, caller);
}
internal void OutputAccessLogUnlessResultSuccess(Result result, System.TimeSpan startTime, System.TimeSpan endTime, string message, [CallerMemberName] string caller = "")
{
if (result.IsFailure())
@ -131,22 +96,6 @@ namespace LibHac.Fs
}
}
internal void OutputAccessLogUnlessResultSuccess(Result result, System.TimeSpan startTime, System.TimeSpan endTime, FileHandle handle, string message, [CallerMemberName] string caller = "")
{
if (result.IsFailure())
{
OutputAccessLogImpl(result, startTime, endTime, handle.GetId(), message, caller);
}
}
internal void OutputAccessLogUnlessResultSuccess(Result result, System.TimeSpan startTime, System.TimeSpan endTime, DirectoryHandle handle, string message, [CallerMemberName] string caller = "")
{
if (result.IsFailure())
{
OutputAccessLogImpl(result, startTime, endTime, handle.GetId(), message, caller);
}
}
internal void OutputAccessLogImpl(Result result, System.TimeSpan startTime, System.TimeSpan endTime, int handleId,
string message, [CallerMemberName] string caller = "")
{
@ -185,27 +134,6 @@ namespace LibHac.Fs
return rc;
}
public Result RunOperationWithAccessLog(AccessLogTarget logTarget, FileHandle handle, Func<Result> operation,
Func<string> textGenerator, [CallerMemberName] string caller = "")
{
Result rc;
if (IsEnabledAccessLog(logTarget) && handle.File.Parent.IsAccessLogEnabled)
{
System.TimeSpan startTime = Time.GetCurrent();
rc = operation();
System.TimeSpan endTime = Time.GetCurrent();
OutputAccessLog(rc, startTime, endTime, handle, textGenerator(), caller);
}
else
{
rc = operation();
}
return rc;
}
public Result RunOperationWithAccessLogOnFailure(AccessLogTarget logTarget, Func<Result> operation,
Func<string> textGenerator, [CallerMemberName] string caller = "")
{

View File

@ -1,48 +0,0 @@
using System;
namespace LibHac.Fs
{
public partial class FileSystemClient
{
public Result GetDirectoryEntryCount(out long count, DirectoryHandle handle)
{
return handle.Directory.GetEntryCount(out count);
}
public Result ReadDirectory(out long entriesRead, Span<DirectoryEntry> entryBuffer, DirectoryHandle handle)
{
Result rc;
if (IsEnabledAccessLog() && IsEnabledHandleAccessLog(handle))
{
System.TimeSpan startTime = Time.GetCurrent();
rc = handle.Directory.Read(out entriesRead, entryBuffer);
System.TimeSpan endTime = Time.GetCurrent();
OutputAccessLog(rc, startTime, endTime, handle, string.Empty);
}
else
{
rc = handle.Directory.Read(out entriesRead, entryBuffer);
}
return rc;
}
public void CloseDirectory(DirectoryHandle handle)
{
if (IsEnabledAccessLog() && IsEnabledHandleAccessLog(handle))
{
System.TimeSpan startTime = Time.GetCurrent();
handle.Directory.Dispose();
System.TimeSpan endTime = Time.GetCurrent();
OutputAccessLog(Result.Success, startTime, endTime, handle, string.Empty);
}
else
{
handle.Directory.Dispose();
}
}
}
}

View File

@ -1,110 +0,0 @@
using System;
using LibHac.Fs.Impl;
namespace LibHac.Fs
{
public partial class FileSystemClient
{
public Result ReadFile(FileHandle handle, long offset, Span<byte> destination)
{
return ReadFile(handle, offset, destination, ReadOption.None);
}
public Result ReadFile(FileHandle handle, long offset, Span<byte> destination, in ReadOption option)
{
Result rc = ReadFile(out long bytesRead, handle, offset, destination, option);
if (rc.IsFailure()) return rc;
if (bytesRead == destination.Length) return Result.Success;
return ResultFs.OutOfRange.Log();
}
public Result ReadFile(out long bytesRead, FileHandle handle, long offset, Span<byte> destination)
{
return ReadFile(out bytesRead, handle, offset, destination, ReadOption.None);
}
public Result ReadFile(out long bytesRead, FileHandle handle, long offset, Span<byte> destination, in ReadOption option)
{
Result rc;
if (IsEnabledAccessLog() && IsEnabledHandleAccessLog(handle))
{
System.TimeSpan startTime = Time.GetCurrent();
rc = handle.File.Read(out bytesRead, offset, destination, in option);
System.TimeSpan endTime = Time.GetCurrent();
OutputAccessLog(rc, startTime, endTime, handle, $", offset: {offset}, size: {destination.Length}");
}
else
{
rc = handle.File.Read(out bytesRead, offset, destination, in option);
}
return rc;
}
public Result WriteFile(FileHandle handle, long offset, ReadOnlySpan<byte> source)
{
return WriteFile(handle, offset, source, WriteOption.None);
}
public Result WriteFile(FileHandle handle, long offset, ReadOnlySpan<byte> source, in WriteOption option)
{
Result rc;
if (IsEnabledAccessLog() && IsEnabledHandleAccessLog(handle))
{
System.TimeSpan startTime = Time.GetCurrent();
rc = handle.File.Write(offset, source, in option);
System.TimeSpan endTime = Time.GetCurrent();
string optionString = option.HasFlushFlag() ? "" : $", write_option: {option}";
OutputAccessLog(rc, startTime, endTime, handle, $", offset: {offset}, size: {source.Length}{optionString}");
}
else
{
rc = handle.File.Write(offset, source, in option);
}
return rc;
}
public Result FlushFile(FileHandle handle)
{
return RunOperationWithAccessLog(AccessLogTarget.All, handle,
() => handle.File.Flush(),
() => string.Empty);
}
public Result GetFileSize(out long fileSize, FileHandle handle)
{
return handle.File.GetSize(out fileSize);
}
public Result SetFileSize(FileHandle handle, long size)
{
return RunOperationWithAccessLog(AccessLogTarget.All, handle,
() => handle.File.SetSize(size),
() => $", size: {size}");
}
public OpenMode GetFileOpenMode(FileHandle handle)
{
return handle.File.OpenMode;
}
public void CloseFile(FileHandle handle)
{
RunOperationWithAccessLog(AccessLogTarget.All, handle,
() =>
{
handle.File.Dispose();
return Result.Success;
},
() => string.Empty);
}
}
}

View File

@ -1,322 +0,0 @@
using LibHac.Common;
using LibHac.Fs.Accessors;
using LibHac.Fs.Fsa;
namespace LibHac.Fs
{
public partial class FileSystemClient
{
public Result CreateDirectory(U8Span path)
{
Result rc = FindFileSystem(out FileSystemAccessor fileSystem, out U8Span subPath, path);
if (rc.IsFailure()) return rc;
if (IsEnabledAccessLog() && fileSystem.IsAccessLogEnabled)
{
System.TimeSpan startTime = Time.GetCurrent();
rc = fileSystem.CreateDirectory(subPath);
System.TimeSpan endTime = Time.GetCurrent();
OutputAccessLog(rc, startTime, endTime, $", path: \"{path.ToString()}\"");
}
else
{
rc = fileSystem.CreateDirectory(subPath);
}
return rc;
}
public Result CreateFile(U8Span path, long size)
{
return CreateFile(path, size, CreateFileOptions.None);
}
public Result CreateFile(U8Span path, long size, CreateFileOptions options)
{
Result rc = FindFileSystem(out FileSystemAccessor fileSystem, out U8Span subPath, path);
if (rc.IsFailure()) return rc;
if (IsEnabledAccessLog() && fileSystem.IsAccessLogEnabled)
{
System.TimeSpan startTime = Time.GetCurrent();
rc = fileSystem.CreateFile(subPath, size, options);
System.TimeSpan endTime = Time.GetCurrent();
OutputAccessLog(rc, startTime, endTime, $", path: \"{path.ToString()}\", size: {size}");
}
else
{
rc = fileSystem.CreateFile(subPath, size, options);
}
return rc;
}
public Result DeleteDirectory(U8Span path)
{
Result rc = FindFileSystem(out FileSystemAccessor fileSystem, out U8Span subPath, path);
if (rc.IsFailure()) return rc;
if (IsEnabledAccessLog() && fileSystem.IsAccessLogEnabled)
{
System.TimeSpan startTime = Time.GetCurrent();
rc = fileSystem.DeleteDirectory(subPath);
System.TimeSpan endTime = Time.GetCurrent();
OutputAccessLog(rc, startTime, endTime, $", path: \"{path.ToString()}\"");
}
else
{
rc = fileSystem.DeleteDirectory(subPath);
}
return rc;
}
public Result DeleteDirectoryRecursively(U8Span path)
{
Result rc = FindFileSystem(out FileSystemAccessor fileSystem, out U8Span subPath, path);
if (rc.IsFailure()) return rc;
if (IsEnabledAccessLog() && fileSystem.IsAccessLogEnabled)
{
System.TimeSpan startTime = Time.GetCurrent();
rc = fileSystem.DeleteDirectoryRecursively(subPath);
System.TimeSpan endTime = Time.GetCurrent();
OutputAccessLog(rc, startTime, endTime, $", path: \"{path.ToString()}\"");
}
else
{
rc = fileSystem.DeleteDirectoryRecursively(subPath);
}
return rc;
}
public Result CleanDirectoryRecursively(U8Span path)
{
Result rc = FindFileSystem(out FileSystemAccessor fileSystem, out U8Span subPath, path);
if (rc.IsFailure()) return rc;
if (IsEnabledAccessLog() && fileSystem.IsAccessLogEnabled)
{
System.TimeSpan startTime = Time.GetCurrent();
rc = fileSystem.CleanDirectoryRecursively(subPath);
System.TimeSpan endTime = Time.GetCurrent();
OutputAccessLog(rc, startTime, endTime, $", path: \"{path.ToString()}\"");
}
else
{
rc = fileSystem.CleanDirectoryRecursively(subPath);
}
return rc;
}
public Result DeleteFile(U8Span path)
{
Result rc = FindFileSystem(out FileSystemAccessor fileSystem, out U8Span subPath, path);
if (rc.IsFailure()) return rc;
if (IsEnabledAccessLog() && fileSystem.IsAccessLogEnabled)
{
System.TimeSpan startTime = Time.GetCurrent();
rc = fileSystem.DeleteFile(subPath);
System.TimeSpan endTime = Time.GetCurrent();
OutputAccessLog(rc, startTime, endTime, $", path: \"{path.ToString()}\"");
}
else
{
rc = fileSystem.DeleteFile(subPath);
}
return rc;
}
public Result RenameDirectory(U8Span oldPath, U8Span newPath)
{
Result rc = FindFileSystem(out FileSystemAccessor oldFileSystem, out U8Span oldSubPath, oldPath);
if (rc.IsFailure()) return rc;
rc = FindFileSystem(out FileSystemAccessor newFileSystem, out U8Span newSubPath, newPath);
if (rc.IsFailure()) return rc;
if (oldFileSystem != newFileSystem)
{
return ResultFs.RenameToOtherFileSystem.Log();
}
if (IsEnabledAccessLog() && oldFileSystem.IsAccessLogEnabled)
{
System.TimeSpan startTime = Time.GetCurrent();
rc = oldFileSystem.RenameDirectory(oldSubPath, newSubPath);
System.TimeSpan endTime = Time.GetCurrent();
OutputAccessLog(rc, startTime, endTime, $", path: \"{oldPath.ToString()}\", new_path: \"{newPath.ToString()}\"");
}
else
{
rc = oldFileSystem.RenameDirectory(oldSubPath, newSubPath);
}
return rc;
}
public Result RenameFile(U8Span oldPath, U8Span newPath)
{
Result rc = FindFileSystem(out FileSystemAccessor oldFileSystem, out U8Span oldSubPath, oldPath);
if (rc.IsFailure()) return rc;
rc = FindFileSystem(out FileSystemAccessor newFileSystem, out U8Span newSubPath, newPath);
if (rc.IsFailure()) return rc;
if (oldFileSystem != newFileSystem)
{
return ResultFs.RenameToOtherFileSystem.Log();
}
if (IsEnabledAccessLog() && oldFileSystem.IsAccessLogEnabled)
{
System.TimeSpan startTime = Time.GetCurrent();
rc = oldFileSystem.RenameFile(oldSubPath, newSubPath);
System.TimeSpan endTime = Time.GetCurrent();
OutputAccessLog(rc, startTime, endTime, $", path: \"{oldPath.ToString()}\", new_path: \"{newPath.ToString()}\"");
}
else
{
rc = oldFileSystem.RenameFile(oldSubPath, newSubPath);
}
return rc;
}
public Result GetEntryType(out DirectoryEntryType type, U8Span path)
{
type = default;
Result rc = FindFileSystem(out FileSystemAccessor fileSystem, out U8Span subPath, path);
if (rc.IsFailure()) return rc;
if (IsEnabledAccessLog() && fileSystem.IsAccessLogEnabled)
{
System.TimeSpan startTime = Time.GetCurrent();
rc = fileSystem.GetEntryType(out type, subPath);
System.TimeSpan endTime = Time.GetCurrent();
OutputAccessLog(rc, startTime, endTime, $", path: \"{path.ToString()}\"");
}
else
{
rc = fileSystem.GetEntryType(out type, subPath);
}
return rc;
}
public Result OpenFile(out FileHandle handle, U8Span path, OpenMode mode)
{
handle = default;
Result rc = FindFileSystem(out FileSystemAccessor fileSystem, out U8Span subPath, path);
if (rc.IsFailure()) return rc;
if (IsEnabledAccessLog() && fileSystem.IsAccessLogEnabled)
{
System.TimeSpan startTime = Time.GetCurrent();
rc = fileSystem.OpenFile(out FileAccessor file, subPath, mode);
handle = new FileHandle(file);
System.TimeSpan endTime = Time.GetCurrent();
OutputAccessLog(rc, startTime, endTime, handle, $", path: \"{path.ToString()}\", open_mode: {mode}");
}
else
{
rc = fileSystem.OpenFile(out FileAccessor file, subPath, mode);
handle = new FileHandle(file);
}
return rc;
}
public Result OpenDirectory(out DirectoryHandle handle, U8Span path, OpenDirectoryMode mode)
{
handle = default;
Result rc = FindFileSystem(out FileSystemAccessor fileSystem, out U8Span subPath, path);
if (rc.IsFailure()) return rc;
if (IsEnabledAccessLog() && fileSystem.IsAccessLogEnabled)
{
System.TimeSpan startTime = Time.GetCurrent();
rc = fileSystem.OpenDirectory(out DirectoryAccessor dir, subPath, mode);
handle = new DirectoryHandle(dir);
System.TimeSpan endTime = Time.GetCurrent();
OutputAccessLog(rc, startTime, endTime, handle, $", path: \"{path.ToString()}\", open_mode: {mode}");
}
else
{
rc = fileSystem.OpenDirectory(out DirectoryAccessor dir, subPath, mode);
handle = new DirectoryHandle(dir);
}
return rc;
}
public Result GetFreeSpaceSize(out long freeSpace, U8Span path)
{
freeSpace = default;
Result rc = FindFileSystem(out FileSystemAccessor fileSystem, out U8Span subPath, path);
if (rc.IsFailure()) return rc;
return fileSystem.GetFreeSpaceSize(out freeSpace, subPath);
}
public Result GetTotalSpaceSize(out long totalSpace, U8Span path)
{
totalSpace = default;
Result rc = FindFileSystem(out FileSystemAccessor fileSystem, out U8Span subPath, path);
if (rc.IsFailure()) return rc;
return fileSystem.GetTotalSpaceSize(out totalSpace, subPath);
}
public Result GetFileTimeStamp(out FileTimeStampRaw timeStamp, U8Span path)
{
timeStamp = default;
Result rc = FindFileSystem(out FileSystemAccessor fileSystem, out U8Span subPath, path);
if (rc.IsFailure()) return rc;
return fileSystem.GetFileTimeStampRaw(out timeStamp, subPath);
}
public Result Commit(U8Span mountName)
{
Result rc = MountTable.Find(mountName.ToString(), out FileSystemAccessor fileSystem);
if (rc.IsFailure()) return rc;
if (IsEnabledAccessLog() && fileSystem.IsAccessLogEnabled)
{
System.TimeSpan startTime = Time.GetCurrent();
rc = fileSystem.Commit();
System.TimeSpan endTime = Time.GetCurrent();
OutputAccessLog(rc, startTime, endTime, $", name: \"{mountName.ToString()}\"");
}
else
{
rc = fileSystem.Commit();
}
return rc;
}
}
}

View File

@ -6,9 +6,6 @@ using LibHac.Diag;
using LibHac.Fs.Accessors;
using LibHac.Fs.Fsa;
using LibHac.Fs.Shim;
using LibHac.FsSystem;
using LibHac.Util;
using IFileSystem = LibHac.Fs.Fsa.IFileSystem;
namespace LibHac.Fs
{
@ -71,121 +68,6 @@ namespace LibHac.Fs
{
return Hos != null;
}
public Result Register(U8Span mountName, IFileSystem fileSystem)
{
return Register(mountName, fileSystem, null);
}
public Result Register(U8Span mountName, IFileSystem fileSystem, ICommonMountNameGenerator nameGenerator)
{
return Register(mountName, null, fileSystem, nameGenerator);
}
public Result Register(U8Span mountName, IMultiCommitTarget multiCommitTarget, IFileSystem fileSystem,
ICommonMountNameGenerator nameGenerator)
{
var accessor = new FileSystemAccessor(mountName, multiCommitTarget, fileSystem, this, nameGenerator);
Result rc = MountTable.Mount(accessor);
if (rc.IsFailure()) return rc;
accessor.IsAccessLogEnabled = IsEnabledAccessLog();
return Result.Success;
}
public void Unmount(U8Span mountName)
{
Result rc;
string mountNameStr = mountName.ToString();
if (IsEnabledAccessLog() && IsEnabledFileSystemAccessorAccessLog(mountName))
{
System.TimeSpan startTime = Time.GetCurrent();
rc = MountTable.Unmount(mountNameStr);
System.TimeSpan endTime = Time.GetCurrent();
OutputAccessLog(rc, startTime, endTime, $", name: \"{mountNameStr}\"");
}
else
{
rc = MountTable.Unmount(mountNameStr);
}
rc.ThrowIfFailure();
}
internal Result FindFileSystem(out FileSystemAccessor fileSystem, out U8Span subPath, U8Span path)
{
fileSystem = default;
subPath = default;
if (path.IsNull())
return ResultFs.NullptrArgument.Log();
int hostMountNameLen = StringUtils.GetLength(CommonPaths.HostRootFileSystemMountName);
if (StringUtils.Compare(path, CommonPaths.HostRootFileSystemMountName, hostMountNameLen) == 0)
{
return ResultFs.NotMounted.Log();
}
Result rc = GetMountNameAndSubPath(out MountName mountName, out subPath, path);
if (rc.IsFailure()) return rc;
rc = MountTable.Find(StringUtils.Utf8ZToString(mountName.Name), out fileSystem);
if (rc.IsFailure()) return rc;
return Result.Success;
}
internal static Result GetMountNameAndSubPath(out MountName mountName, out U8Span subPath, U8Span path)
{
int mountLen = 0;
int maxMountLen = Math.Min(path.Length, PathTools.MountNameLengthMax);
if (PathUtility.IsWindowsDrive(path) || PathUtility.IsUnc(path))
{
StringUtils.Copy(mountName.Name, CommonPaths.HostRootFileSystemMountName);
mountName.Name[PathTools.MountNameLengthMax] = StringTraits.NullTerminator;
subPath = path;
return Result.Success;
}
for (int i = 0; i <= maxMountLen; i++)
{
if (path[i] == PathTools.MountSeparator)
{
mountLen = i;
break;
}
}
if (mountLen == 0 || mountLen > maxMountLen)
{
mountName = default;
subPath = default;
return ResultFs.InvalidMountName.Log();
}
U8Span subPathTemp = path.Slice(mountLen + 1);
if (subPathTemp.Length == 0 || !PathTool.IsAnySeparator(subPathTemp[0]))
{
mountName = default;
subPath = default;
return ResultFs.InvalidPathFormat.Log();
}
path.Value.Slice(0, mountLen).CopyTo(mountName.Name);
mountName.Name[mountLen] = StringTraits.NullTerminator;
subPath = subPathTemp;
return Result.Success;
}
}
[StructLayout(LayoutKind.Sequential, Size = 16)]

View File

@ -16,7 +16,7 @@ namespace LibHac.Fs
Result rc = fs.OpenDirectory(out DirectoryHandle sourceHandle, sourcePath.ToU8Span(), OpenDirectoryMode.All);
if (rc.IsFailure()) return rc;
using (sourceHandle)
try
{
foreach (DirectoryEntryEx entry in fs.EnumerateEntries(sourcePath, "*", SearchOptions.Default))
{
@ -41,6 +41,11 @@ namespace LibHac.Fs
}
}
}
finally
{
if (sourceHandle.IsValid)
fs.CloseDirectory(sourceHandle);
}
return Result.Success;
}
@ -50,12 +55,13 @@ namespace LibHac.Fs
Result rc = fs.OpenFile(out FileHandle sourceHandle, sourcePath.ToU8Span(), OpenMode.Read);
if (rc.IsFailure()) return rc;
using (sourceHandle)
try
{
rc = fs.OpenFile(out FileHandle destHandle, destPath.ToU8Span(), OpenMode.Write | OpenMode.AllowAppend);
rc = fs.OpenFile(out FileHandle destHandle, destPath.ToU8Span(),
OpenMode.Write | OpenMode.AllowAppend);
if (rc.IsFailure()) return rc;
using (destHandle)
try
{
const int maxBufferSize = 0x10000;
@ -77,7 +83,7 @@ namespace LibHac.Fs
rc = fs.ReadFile(out long _, sourceHandle, offset, buf);
if (rc.IsFailure()) return rc;
rc = fs.WriteFile(destHandle, offset, buf);
rc = fs.WriteFile(destHandle, offset, buf, WriteOption.None);
if (rc.IsFailure()) return rc;
logger?.ReportAdd(toRead);
@ -92,6 +98,16 @@ namespace LibHac.Fs
rc = fs.FlushFile(destHandle);
if (rc.IsFailure()) return rc;
}
finally
{
if (destHandle.IsValid)
fs.CloseFile(destHandle);
}
}
finally
{
if (sourceHandle.IsValid)
fs.CloseFile(sourceHandle);
}
return Result.Success;
@ -114,7 +130,7 @@ namespace LibHac.Fs
fs.OpenDirectory(out DirectoryHandle sourceHandle, path.ToU8Span(), OpenDirectoryMode.All).ThrowIfFailure();
using (sourceHandle)
try
{
while (true)
{
@ -141,6 +157,11 @@ namespace LibHac.Fs
}
}
}
finally
{
if (sourceHandle.IsValid)
fs.CloseDirectory(sourceHandle);
}
}
public static bool DirectoryExists(this FileSystemClient fs, string path)

View File

@ -59,10 +59,10 @@ namespace LibHac.Fs.Impl
using (ScopedLock.Lock(ref _openListLock))
{
Abort.DoAbortUnless(_openFiles.Count == 0, ResultFs.FileNotClosed.Log(),
Abort.DoAbortUnless(_openFiles.Count == 0, ResultFs.FileNotClosed.Value,
"All files must be closed before unmounting.");
Abort.DoAbortUnless(_openDirectories.Count == 0, ResultFs.DirectoryNotClosed.Log(),
Abort.DoAbortUnless(_openDirectories.Count == 0, ResultFs.DirectoryNotClosed.Value,
"All directories must be closed before unmounting.");
if (_isPathCacheAttached)
@ -150,7 +150,7 @@ namespace LibHac.Fs.Impl
Result rc = CheckPath(new U8Span(_mountName.Name), path);
if (rc.IsFailure()) return rc;
return _fileSystem.DeleteDirectory(path);
return _fileSystem.DeleteFile(path);
}
public Result CreateDirectory(U8Span path)

View File

@ -17,11 +17,12 @@ namespace LibHac.Fs.Impl
{
_fileSystemList = new LinkedList<FileSystemAccessor>();
_mutex = new SdkMutexType();
_mutex.Initialize();
}
public Result Mount(FileSystemAccessor fileSystem)
{
ScopedLock.Lock(ref _mutex);
using ScopedLock<SdkMutexType> lk = ScopedLock.Lock(ref _mutex);
if (!CanAcceptMountName(fileSystem.GetName()))
return ResultFs.MountNameAlreadyExists.Log();
@ -33,7 +34,7 @@ namespace LibHac.Fs.Impl
public Result Find(out FileSystemAccessor accessor, U8Span name)
{
accessor = default;
ScopedLock.Lock(ref _mutex);
using ScopedLock<SdkMutexType> lk = ScopedLock.Lock(ref _mutex);
for (LinkedListNode<FileSystemAccessor> currentNode = _fileSystemList.First;
currentNode is not null;
@ -49,7 +50,7 @@ namespace LibHac.Fs.Impl
public void Unmount(U8Span name)
{
ScopedLock.Lock(ref _mutex);
using ScopedLock<SdkMutexType> lk = ScopedLock.Lock(ref _mutex);
LinkedListNode<FileSystemAccessor> currentNode;
for (currentNode = _fileSystemList.First; currentNode is not null; currentNode = currentNode.Next)

View File

@ -14,7 +14,7 @@ namespace LibHac.Fs.Fsa
Result GetSaveDataAttribute(out SaveDataAttribute attribute);
}
internal static class Registrar
public static class Registrar
{
public static Result Register(this FileSystemClient fs, U8Span name, IFileSystem fileSystem)
{

View File

@ -9,13 +9,13 @@ namespace LibHac.Fs.Fsa
[SkipLocalsInit]
public static class UserDirectory
{
private static DirectoryAccessor Get(DirectoryHandle2 handle)
private static DirectoryAccessor Get(DirectoryHandle handle)
{
return handle.Directory;
}
public static Result ReadDirectory(this FileSystemClient fs, out long entriesRead,
Span<DirectoryEntry> entryBuffer, DirectoryHandle2 handle)
Span<DirectoryEntry> entryBuffer, DirectoryHandle handle)
{
Result rc;
@ -41,7 +41,7 @@ namespace LibHac.Fs.Fsa
return rc;
}
public static Result GetDirectoryEntryCount(this FileSystemClient fs, out long count, DirectoryHandle2 handle)
public static Result GetDirectoryEntryCount(this FileSystemClient fs, out long count, DirectoryHandle handle)
{
Result rc;
@ -66,7 +66,7 @@ namespace LibHac.Fs.Fsa
return rc;
}
public static void CloseDirectory(this FileSystemClient fs, DirectoryHandle2 handle)
public static void CloseDirectory(this FileSystemClient fs, DirectoryHandle handle)
{
if (fs.Impl.IsEnabledAccessLog() && fs.Impl.IsEnabledHandleAccessLog(handle))
{

View File

@ -9,18 +9,18 @@ namespace LibHac.Fs.Fsa
[SkipLocalsInit]
public static class UserFile
{
private static FileAccessor Get(FileHandle2 handle)
private static FileAccessor Get(FileHandle handle)
{
return handle.File;
}
private static Result ReadFileImpl(FileSystemClient fs, out long bytesRead, FileHandle2 handle, long offset,
private static Result ReadFileImpl(FileSystemClient fs, out long bytesRead, FileHandle handle, long offset,
Span<byte> destination, in ReadOption option)
{
return Get(handle).Read(out bytesRead, offset, destination, in option);
}
public static Result ReadFile(this FileSystemClient fs, FileHandle2 handle, long offset, Span<byte> destination,
public static Result ReadFile(this FileSystemClient fs, FileHandle handle, long offset, Span<byte> destination,
in ReadOption option)
{
Result rc = ReadFileImpl(fs, out long bytesRead, handle, offset, destination, in option);
@ -35,7 +35,7 @@ namespace LibHac.Fs.Fsa
return rc;
}
public static Result ReadFile(this FileSystemClient fs, FileHandle2 handle, long offset, Span<byte> destination)
public static Result ReadFile(this FileSystemClient fs, FileHandle handle, long offset, Span<byte> destination)
{
Result rc = ReadFileImpl(fs, out long bytesRead, handle, offset, destination, ReadOption.None);
fs.Impl.AbortIfNeeded(rc);
@ -49,7 +49,7 @@ namespace LibHac.Fs.Fsa
return rc;
}
public static Result ReadFile(this FileSystemClient fs, out long bytesRead, FileHandle2 handle, long offset,
public static Result ReadFile(this FileSystemClient fs, out long bytesRead, FileHandle handle, long offset,
Span<byte> destination, in ReadOption option)
{
Result rc = ReadFileImpl(fs, out bytesRead, handle, offset, destination, in option);
@ -57,7 +57,7 @@ namespace LibHac.Fs.Fsa
return rc;
}
public static Result ReadFile(this FileSystemClient fs, out long bytesRead, FileHandle2 handle, long offset,
public static Result ReadFile(this FileSystemClient fs, out long bytesRead, FileHandle handle, long offset,
Span<byte> destination)
{
Result rc = ReadFileImpl(fs, out bytesRead, handle, offset, destination, ReadOption.None);
@ -65,7 +65,7 @@ namespace LibHac.Fs.Fsa
return rc;
}
public static Result WriteFile(this FileSystemClient fs, FileHandle2 handle, long offset,
public static Result WriteFile(this FileSystemClient fs, FileHandle handle, long offset,
ReadOnlySpan<byte> source, in WriteOption option)
{
Result rc;
@ -96,7 +96,7 @@ namespace LibHac.Fs.Fsa
return rc;
}
public static Result FlushFile(this FileSystemClient fs, FileHandle2 handle)
public static Result FlushFile(this FileSystemClient fs, FileHandle handle)
{
Result rc;
@ -117,7 +117,7 @@ namespace LibHac.Fs.Fsa
return rc;
}
public static Result SetFileSize(this FileSystemClient fs, FileHandle2 handle, long size)
public static Result SetFileSize(this FileSystemClient fs, FileHandle handle, long size)
{
Result rc;
@ -142,7 +142,7 @@ namespace LibHac.Fs.Fsa
return rc;
}
public static Result GetFileSize(this FileSystemClient fs, out long size, FileHandle2 handle)
public static Result GetFileSize(this FileSystemClient fs, out long size, FileHandle handle)
{
Result rc;
@ -167,7 +167,7 @@ namespace LibHac.Fs.Fsa
return rc;
}
public static OpenMode GetFileOpenMode(this FileSystemClient fs, FileHandle2 handle)
public static OpenMode GetFileOpenMode(this FileSystemClient fs, FileHandle handle)
{
OpenMode mode = Get(handle).GetOpenMode();
@ -186,7 +186,7 @@ namespace LibHac.Fs.Fsa
return mode;
}
public static void CloseFile(this FileSystemClient fs, FileHandle2 handle)
public static void CloseFile(this FileSystemClient fs, FileHandle handle)
{
if (fs.Impl.IsEnabledAccessLog() && fs.Impl.IsEnabledHandleAccessLog(handle))
{
@ -202,7 +202,7 @@ namespace LibHac.Fs.Fsa
}
}
public static Result QueryRange(this FileSystemClient fs, out QueryRangeInfo rangeInfo, FileHandle2 handle,
public static Result QueryRange(this FileSystemClient fs, out QueryRangeInfo rangeInfo, FileHandle handle,
long offset, long size)
{
Unsafe.SkipInit(out rangeInfo);
@ -214,7 +214,7 @@ namespace LibHac.Fs.Fsa
return rc;
}
public static Result InvalidateCache(this FileSystemClient fs, FileHandle2 handle, long offset, long size)
public static Result InvalidateCache(this FileSystemClient fs, FileHandle handle, long offset, long size)
{
Result rc = Get(handle).OperateRange(Span<byte>.Empty, OperationId.InvalidateCache, offset, size,
ReadOnlySpan<byte>.Empty);

View File

@ -479,7 +479,7 @@ namespace LibHac.Fs.Fsa
return rc;
}
public static Result OpenFile(this FileSystemClient fs, out FileHandle2 handle, U8Span path, OpenMode mode)
public static Result OpenFile(this FileSystemClient fs, out FileHandle handle, U8Span path, OpenMode mode)
{
handle = default;
@ -523,19 +523,19 @@ namespace LibHac.Fs.Fsa
fs.Impl.AbortIfNeeded(rc);
if (rc.IsFailure()) return rc;
handle = new FileHandle2(accessor);
handle = new FileHandle(accessor);
return Result.Success;
}
public static Result OpenFile(this FileSystemClient fs, out FileHandle2 handle, IFile file, OpenMode mode)
public static Result OpenFile(this FileSystemClient fs, out FileHandle handle, IFile file, OpenMode mode)
{
var accessor = new FileAccessor(ref file, null, mode);
handle = new FileHandle2(accessor);
handle = new FileHandle(accessor);
return Result.Success;
}
public static Result OpenDirectory(this FileSystemClient fs, out DirectoryHandle2 handle, U8Span path,
public static Result OpenDirectory(this FileSystemClient fs, out DirectoryHandle handle, U8Span path,
OpenDirectoryMode mode)
{
handle = default;
@ -580,7 +580,7 @@ namespace LibHac.Fs.Fsa
fs.Impl.AbortIfNeeded(rc);
if (rc.IsFailure()) return rc;
handle = new DirectoryHandle2(accessor);
handle = new DirectoryHandle(accessor);
return Result.Success;
}

View File

@ -1,4 +1,5 @@
using LibHac.Common;
using LibHac.Fs.Fsa;
using LibHac.Fs.Impl;
using LibHac.FsSrv.Sf;
using IFileSystemSf = LibHac.FsSrv.Sf.IFileSystem;

View File

@ -1,4 +1,5 @@
using LibHac.Common;
using LibHac.Fs.Fsa;
using LibHac.Fs.Impl;
using LibHac.FsSrv.Sf;
using IFileSystemSf = LibHac.FsSrv.Sf.IFileSystem;

View File

@ -1,5 +1,6 @@
using System.Runtime.CompilerServices;
using LibHac.Common;
using LibHac.Fs.Fsa;
using LibHac.Fs.Impl;
using LibHac.FsSrv.Sf;
using LibHac.Ncm;

View File

@ -1,5 +1,6 @@
using System;
using LibHac.Common;
using LibHac.Fs.Fsa;
using LibHac.Fs.Impl;
using LibHac.FsSrv.Sf;
using LibHac.Ncm;

View File

@ -1,6 +1,7 @@
using System;
using LibHac.Common;
using LibHac.Diag;
using LibHac.Fs.Fsa;
using LibHac.Fs.Impl;
using LibHac.FsSrv.Sf;
using IFileSystemSf = LibHac.FsSrv.Sf.IFileSystem;

View File

@ -1,4 +1,5 @@
using LibHac.Common;
using LibHac.Fs.Fsa;
using LibHac.Fs.Impl;
using LibHac.FsSrv.Sf;
using LibHac.Ncm;
@ -210,7 +211,7 @@ namespace LibHac.Fs.Shim
var fileSystemAdapter = new FileSystemServiceObjectAdapter(saveFs);
return fs.Register(mountName, fileSystemAdapter, fileSystemAdapter, null);
return fs.Register(mountName, fileSystemAdapter, fileSystemAdapter, null, false, false);
}
finally
{

View File

@ -1,4 +1,5 @@
using LibHac.Common;
using LibHac.Fs.Fsa;
using LibHac.Fs.Impl;
using LibHac.FsSrv.Sf;
using IFileSystemSf = LibHac.FsSrv.Sf.IFileSystem;

View File

@ -1,4 +1,5 @@
using LibHac.Common;
using LibHac.Fs.Fsa;
using LibHac.Fs.Impl;
using LibHac.FsSrv.Sf;
using LibHac.Ncm;

View File

@ -1,55 +0,0 @@
using System;
using LibHac.Common;
using LibHac.Fs.Accessors;
using LibHac.FsSrv.Sf;
using IFileSystemSf = LibHac.FsSrv.Sf.IFileSystem;
namespace LibHac.Fs.Shim
{
public static class UserFileSystem
{
public static Result Commit(this FileSystemClient fs, ReadOnlySpan<U8String> mountNames)
{
// Todo: Add access log
if (mountNames.Length > 10)
return ResultFs.InvalidCommitNameCount.Log();
if (mountNames.Length == 0)
return Result.Success;
ReferenceCountedDisposable<IMultiCommitManager> commitManager = null;
ReferenceCountedDisposable<IFileSystemSf> fileSystem = null;
try
{
using ReferenceCountedDisposable<IFileSystemProxy> fsProxy = fs.Impl.GetFileSystemProxyServiceObject();
Result rc = fsProxy.Target.OpenMultiCommitManager(out commitManager);
if (rc.IsFailure()) return rc;
for (int i = 0; i < mountNames.Length; i++)
{
rc = fs.MountTable.Find(mountNames[i].ToString(), out FileSystemAccessor accessor);
if (rc.IsFailure()) return rc;
fileSystem = accessor.GetMultiCommitTarget();
if (fileSystem is null)
return ResultFs.UnsupportedCommitTarget.Log();
rc = commitManager.Target.Add(fileSystem);
if (rc.IsFailure()) return rc;
}
rc = commitManager.Target.Commit();
if (rc.IsFailure()) return rc;
return Result.Success;
}
finally
{
commitManager?.Dispose();
fileSystem?.Dispose();
}
}
}
}

View File

@ -107,7 +107,7 @@ namespace LibHac.FsSrv.Impl
var normalizer = new PathNormalizer(new U8Span(path.Str), GetPathNormalizerOption());
if (normalizer.Result.IsFailure()) return normalizer.Result;
if (StringUtils.Compare(RootDir, normalizer.Path) != 0)
if (StringUtils.Compare(RootDir, normalizer.Path) == 0)
return ResultFs.PathAlreadyExists.Log();
return BaseFileSystem.Target.CreateDirectory(normalizer.Path);
@ -118,7 +118,7 @@ namespace LibHac.FsSrv.Impl
var normalizer = new PathNormalizer(new U8Span(path.Str), GetPathNormalizerOption());
if (normalizer.Result.IsFailure()) return normalizer.Result;
if (StringUtils.Compare(RootDir, normalizer.Path) != 0)
if (StringUtils.Compare(RootDir, normalizer.Path) == 0)
return ResultFs.DirectoryNotDeletable.Log();
return BaseFileSystem.Target.DeleteDirectory(normalizer.Path);
@ -129,7 +129,7 @@ namespace LibHac.FsSrv.Impl
var normalizer = new PathNormalizer(new U8Span(path.Str), GetPathNormalizerOption());
if (normalizer.Result.IsFailure()) return normalizer.Result;
if (StringUtils.Compare(RootDir, normalizer.Path) != 0)
if (StringUtils.Compare(RootDir, normalizer.Path) == 0)
return ResultFs.DirectoryNotDeletable.Log();
return BaseFileSystem.Target.DeleteDirectoryRecursively(normalizer.Path);

View File

@ -7,6 +7,7 @@ using System.Runtime.InteropServices;
using LibHac.Common;
using LibHac.Diag;
using LibHac.Fs;
using LibHac.Fs.Fsa;
using LibHac.Fs.Shim;
using LibHac.FsSrv.Sf;
using LibHac.Kvdb;

View File

@ -4,6 +4,7 @@ using System.Runtime.InteropServices;
using LibHac.Common;
using LibHac.Diag;
using LibHac.Fs;
using LibHac.Fs.Fsa;
namespace LibHac.Kvdb
{

View File

@ -56,7 +56,7 @@ namespace LibHac.Os
public void Unlock()
{
Abort.DoAbortUnless(!IsLockedByCurrentThread());
Abort.DoAbortUnless(IsLockedByCurrentThread());
_cs.Leave();
}

View File

@ -34,7 +34,7 @@ namespace hactoolnet
Result rc = fs.OpenDirectory(out DirectoryHandle sourceHandle, sourcePath, OpenDirectoryMode.All);
if (rc.IsFailure()) return rc;
using (sourceHandle)
try
{
foreach (DirectoryEntryEx entry in fs.EnumerateEntries(sourcePathStr, "*", SearchOptions.Default))
{
@ -61,6 +61,11 @@ namespace hactoolnet
}
}
}
finally
{
if (sourceHandle.IsValid)
fs.CloseDirectory(sourceHandle);
}
return Result.Success;
}
@ -82,12 +87,12 @@ namespace hactoolnet
Result rc = fs.OpenFile(out FileHandle sourceHandle, sourcePath, OpenMode.Read);
if (rc.IsFailure()) return rc;
using (sourceHandle)
try
{
rc = fs.OpenFile(out FileHandle destHandle, destPath, OpenMode.Write | OpenMode.AllowAppend);
if (rc.IsFailure()) return rc;
using (destHandle)
try
{
const int maxBufferSize = 1024 * 1024;
@ -107,7 +112,7 @@ namespace hactoolnet
rc = fs.ReadFile(out long _, sourceHandle, offset, buf);
if (rc.IsFailure()) return rc;
rc = fs.WriteFile(destHandle, offset, buf);
rc = fs.WriteFile(destHandle, offset, buf, WriteOption.None);
if (rc.IsFailure()) return rc;
logger?.ReportAdd(toRead);
@ -121,6 +126,16 @@ namespace hactoolnet
rc = fs.FlushFile(destHandle);
if (rc.IsFailure()) return rc;
}
finally
{
if (destHandle.IsValid)
fs.CloseFile(destHandle);
}
}
finally
{
if (sourceHandle.IsValid)
fs.CloseFile(sourceHandle);
}
return Result.Success;

View File

@ -1,5 +1,6 @@
using LibHac.Common;
using LibHac.Fs;
using LibHac.Fs.Fsa;
using LibHac.Fs.Shim;
using Xunit;

View File

@ -1,5 +1,6 @@
using LibHac.Common;
using LibHac.Fs;
using LibHac.Fs.Fsa;
using LibHac.Fs.Shim;
using Xunit;

View File

@ -1,6 +1,7 @@
using System.Collections.Generic;
using LibHac.Common;
using LibHac.Fs;
using LibHac.Fs.Fsa;
using LibHac.Fs.Shim;
using LibHac.Tests.Fs.FileSystemClientTests;
using Xunit;

View File

@ -1,6 +1,7 @@
using System;
using LibHac.Common;
using LibHac.Fs;
using LibHac.Fs.Fsa;
using LibHac.Kvdb;
using LibHac.Tests.Fs.FileSystemClientTests;
using Xunit;