Move FileSystemManager into FileSystemClient

This commit is contained in:
Alex Barney 2019-09-25 17:50:07 -05:00
parent 955fff8efc
commit 00eb988793
14 changed files with 564 additions and 729 deletions

View file

@ -10,7 +10,7 @@ namespace LibHac.Fs.Accessors
public string Name { get; }
private IFileSystem FileSystem { get; }
internal FileSystemManager FsManager { get; }
internal FileSystemClient FsClient { get; }
private ICommonMountNameGenerator MountNameGenerator { get; }
private HashSet<FileAccessor> OpenFiles { get; } = new HashSet<FileAccessor>();
@ -20,11 +20,11 @@ namespace LibHac.Fs.Accessors
internal bool IsAccessLogEnabled { get; set; }
public FileSystemAccessor(string name, IFileSystem baseFileSystem, FileSystemManager fsManager, ICommonMountNameGenerator nameGenerator)
public FileSystemAccessor(string name, IFileSystem baseFileSystem, FileSystemClient fsClient, ICommonMountNameGenerator nameGenerator)
{
Name = name;
FileSystem = baseFileSystem;
FsManager = fsManager;
FsClient = fsClient;
MountNameGenerator = nameGenerator;
}

View file

@ -16,7 +16,7 @@ namespace LibHac.Fs
public void Dispose()
{
Directory.Parent.FsManager.CloseDirectory(this);
Directory.Parent.FsClient.CloseDirectory(this);
}
}
}

View file

@ -16,7 +16,7 @@ namespace LibHac.Fs
public void Dispose()
{
File.Parent.FsManager.CloseFile(this);
File.Parent.FsClient.CloseFile(this);
}
}
}

View file

@ -7,7 +7,7 @@ namespace LibHac.Fs
private const long InvalidSize = -1;
private readonly object _locker = new object();
private FileSystemManager FsManager { get; }
private FileSystemClient FsClient { get; }
private FileHandle Handle { get; }
private long FileSize { get; set; } = InvalidSize;
private bool CloseHandle { get; }
@ -18,7 +18,7 @@ namespace LibHac.Fs
{
Handle = handle;
CloseHandle = closeHandleOnDispose;
FsManager = Handle.File.Parent.FsManager;
FsClient = Handle.File.Parent.FsClient;
}
public override Result Read(long offset, Span<byte> destination)
@ -33,7 +33,7 @@ namespace LibHac.Fs
if (destination.Length < 0 || offset < 0) return ResultFs.ValueOutOfRange.Log();
if (!IsRangeValid(offset, destination.Length, FileSize)) return ResultFs.ValueOutOfRange.Log();
return FsManager.ReadFile(Handle, offset, destination);
return FsClient.ReadFile(Handle, offset, destination);
}
}
@ -49,20 +49,20 @@ namespace LibHac.Fs
if (source.Length < 0 || offset < 0) return ResultFs.ValueOutOfRange.Log();
if (!IsRangeValid(offset, source.Length, FileSize)) return ResultFs.ValueOutOfRange.Log();
return FsManager.WriteFile(Handle, offset, source);
return FsClient.WriteFile(Handle, offset, source);
}
}
public override Result Flush()
{
return FsManager.FlushFile(Handle);
return FsClient.FlushFile(Handle);
}
public override Result SetSize(long size)
{
FileSize = InvalidSize;
return FsManager.SetFileSize(Handle, size);
return FsClient.SetFileSize(Handle, size);
}
public override Result GetSize(out long size)
@ -80,7 +80,7 @@ namespace LibHac.Fs
{
if (FileSize != InvalidSize) return Result.Success;
Result rc = FsManager.GetFileSize(out long fileSize, Handle);
Result rc = FsClient.GetFileSize(out long fileSize, Handle);
if (rc.IsFailure()) return rc;
FileSize = fileSize;
@ -91,7 +91,7 @@ namespace LibHac.Fs
{
if (CloseHandle)
{
FsManager.CloseFile(Handle);
FsClient.CloseFile(Handle);
}
}
}

View file

@ -6,17 +6,43 @@ namespace LibHac.Fs
{
public Result GetDirectoryEntryCount(out long count, DirectoryHandle handle)
{
return FsManager.GetDirectoryEntryCount(out count, handle);
return handle.Directory.GetEntryCount(out count);
}
public Result ReadDirectory(out long entriesRead, Span<DirectoryEntry> entryBuffer, DirectoryHandle handle)
{
return FsManager.ReadDirectory(out entriesRead, entryBuffer, handle);
Result rc;
if (IsEnabledAccessLog() && IsEnabledHandleAccessLog(handle))
{
TimeSpan startTime = Time.GetCurrent();
rc = handle.Directory.Read(out entriesRead, entryBuffer);
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)
{
FsManager.CloseDirectory(handle);
if (IsEnabledAccessLog() && IsEnabledHandleAccessLog(handle))
{
TimeSpan startTime = Time.GetCurrent();
handle.Directory.Dispose();
TimeSpan endTime = Time.GetCurrent();
OutputAccessLog(Result.Success, startTime, endTime, handle, string.Empty);
}
else
{
handle.Directory.Dispose();
}
}
}
}

View file

@ -6,52 +6,135 @@ namespace LibHac.Fs
{
public Result ReadFile(FileHandle handle, long offset, Span<byte> destination)
{
return FsManager.ReadFile(handle, offset, destination);
return ReadFile(handle, offset, destination, ReadOption.None);
}
public Result ReadFile(FileHandle handle, long offset, Span<byte> destination, ReadOption options)
public Result ReadFile(FileHandle handle, long offset, Span<byte> destination, ReadOption option)
{
return FsManager.ReadFile(handle, offset, destination, options);
Result rc = ReadFile(out long bytesRead, handle, offset, destination, option);
if (rc.IsFailure()) return rc;
if (bytesRead == destination.Length) return Result.Success;
return ResultFs.ValueOutOfRange.Log();
}
public Result ReadFile(out long bytesRead, FileHandle handle, long offset, Span<byte> destination)
{
return FsManager.ReadFile(out bytesRead, handle, offset, destination);
return ReadFile(out bytesRead, handle, offset, destination, ReadOption.None);
}
public Result ReadFile(out long bytesRead, FileHandle handle, long offset, Span<byte> destination, ReadOption options)
public Result ReadFile(out long bytesRead, FileHandle handle, long offset, Span<byte> destination, ReadOption option)
{
return FsManager.ReadFile(out bytesRead, handle, offset, destination, options);
Result rc;
if (IsEnabledAccessLog() && IsEnabledHandleAccessLog(handle))
{
TimeSpan startTime = Time.GetCurrent();
rc = handle.File.Read(out bytesRead, offset, destination, option);
TimeSpan endTime = Time.GetCurrent();
OutputAccessLog(rc, startTime, endTime, handle, $", offset: {offset}, size: {destination.Length}");
}
else
{
rc = handle.File.Read(out bytesRead, offset, destination, option);
}
return rc;
}
public Result WriteFile(FileHandle handle, long offset, ReadOnlySpan<byte> source, WriteOption options)
public Result WriteFile(FileHandle handle, long offset, ReadOnlySpan<byte> source)
{
return FsManager.WriteFile(handle, offset, source, options);
return WriteFile(handle, offset, source, WriteOption.None);
}
public Result WriteFile(FileHandle handle, long offset, ReadOnlySpan<byte> source, WriteOption option)
{
Result rc;
if (IsEnabledAccessLog() && IsEnabledHandleAccessLog(handle))
{
TimeSpan startTime = Time.GetCurrent();
rc = handle.File.Write(offset, source, option);
TimeSpan endTime = Time.GetCurrent();
string optionString = (option & WriteOption.Flush) == 0 ? "" : $", write_option: {option}";
OutputAccessLog(rc, startTime, endTime, handle, $", offset: {offset}, size: {source.Length}{optionString}");
}
else
{
rc = handle.File.Write(offset, source, option);
}
return rc;
}
public Result FlushFile(FileHandle handle)
{
return FsManager.FlushFile(handle);
Result rc;
if (IsEnabledAccessLog() && IsEnabledHandleAccessLog(handle))
{
TimeSpan startTime = Time.GetCurrent();
rc = handle.File.Flush();
TimeSpan endTime = Time.GetCurrent();
OutputAccessLog(rc, startTime, endTime, handle, string.Empty);
}
else
{
rc = handle.File.Flush();
}
return rc;
}
public Result GetFileSize(out long fileSize, FileHandle handle)
{
return FsManager.GetFileSize(out fileSize, handle);
return handle.File.GetSize(out fileSize);
}
public Result SetFileSize(FileHandle handle, long size)
{
return FsManager.SetFileSize(handle, size);
Result rc;
if (IsEnabledAccessLog() && IsEnabledHandleAccessLog(handle))
{
TimeSpan startTime = Time.GetCurrent();
rc = handle.File.SetSize(size);
TimeSpan endTime = Time.GetCurrent();
OutputAccessLog(rc, startTime, endTime, handle, $", size: {size}");
}
else
{
rc = handle.File.SetSize(size);
}
return rc;
}
public OpenMode GetFileOpenMode(FileHandle handle)
{
return FsManager.GetFileOpenMode(handle);
return handle.File.OpenMode;
}
public void CloseFile(FileHandle handle)
{
FsManager.CloseFile(handle);
if (IsEnabledAccessLog() && IsEnabledHandleAccessLog(handle))
{
TimeSpan startTime = Time.GetCurrent();
handle.File.Dispose();
TimeSpan endTime = Time.GetCurrent();
OutputAccessLog(Result.Success, startTime, endTime, handle, string.Empty);
}
else
{
handle.File.Dispose();
}
}
}
}

View file

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

View file

@ -1,5 +1,9 @@
using LibHac.Common;
using System;
using System.Runtime.CompilerServices;
using LibHac.Common;
using LibHac.Fs.Accessors;
using LibHac.FsService;
using LibHac.FsSystem;
namespace LibHac.Fs
{
@ -7,14 +11,24 @@ namespace LibHac.Fs
{
private FileSystemServer FsSrv { get; }
private IFileSystemProxy FsProxy { get; set; }
private FileSystemManager FsManager { get; }
private readonly object _fspInitLocker = new object();
internal ITimeSpanGenerator Time { get; }
private IAccessLog AccessLog { get; set; }
private bool AccessLogEnabled { get; set; }
internal MountTable MountTable { get; } = new MountTable();
public FileSystemClient(ITimeSpanGenerator timer)
{
Time = timer;
}
public FileSystemClient(FileSystemServer fsServer, ITimeSpanGenerator timer)
{
FsSrv = fsServer;
FsManager = new FileSystemManager(timer);
Time = timer;
}
public IFileSystemProxy GetFileSystemProxyServiceObject()
@ -25,6 +39,11 @@ namespace LibHac.Fs
{
if (FsProxy != null) return FsProxy;
if (FsSrv == null)
{
throw new InvalidOperationException("Client was not initialized with a server object.");
}
FsProxy = FsSrv.CreateFileSystemProxyService();
return FsProxy;
@ -33,12 +52,135 @@ namespace LibHac.Fs
public Result Register(U8Span mountName, IFileSystem fileSystem)
{
return FsManager.Register(mountName, fileSystem);
return Register(mountName, fileSystem, null);
}
public Result Register(U8Span mountName, IFileSystem fileSystem, ICommonMountNameGenerator nameGenerator)
{
return FsManager.Register(mountName, fileSystem, nameGenerator);
var accessor = new FileSystemAccessor(mountName.ToString(), fileSystem, this, nameGenerator);
Result rc = MountTable.Mount(accessor);
if (rc.IsFailure()) return rc;
accessor.IsAccessLogEnabled = IsEnabledAccessLog();
return Result.Success;
}
public void Unmount(string mountName)
{
Result rc;
if (IsEnabledAccessLog() && IsEnabledFileSystemAccessorAccessLog(mountName))
{
TimeSpan startTime = Time.GetCurrent();
rc = MountTable.Unmount(mountName);
TimeSpan endTime = Time.GetCurrent();
OutputAccessLog(rc, startTime, endTime, $", name: \"{mountName}\"");
}
else
{
rc = MountTable.Unmount(mountName);
}
rc.ThrowIfFailure();
}
public void SetAccessLog(bool isEnabled, IAccessLog accessLog = null)
{
AccessLogEnabled = isEnabled;
if (accessLog != null) AccessLog = accessLog;
}
internal Result FindFileSystem(ReadOnlySpan<char> path, out FileSystemAccessor fileSystem, out ReadOnlySpan<char> subPath)
{
fileSystem = default;
Result rc = GetMountName(path, out ReadOnlySpan<char> mountName, out subPath);
if (rc.IsFailure()) return rc;
rc = MountTable.Find(mountName.ToString(), out fileSystem);
if (rc.IsFailure()) return rc;
return Result.Success;
}
internal static Result GetMountName(ReadOnlySpan<char> path, out ReadOnlySpan<char> mountName, out ReadOnlySpan<char> subPath)
{
int mountLen = 0;
int maxMountLen = Math.Min(path.Length, PathTools.MountNameLength);
for (int i = 0; i < maxMountLen; i++)
{
if (path[i] == PathTools.MountSeparator)
{
mountLen = i;
break;
}
}
if (mountLen == 0)
{
mountName = default;
subPath = default;
return ResultFs.InvalidMountName;
}
mountName = path.Slice(0, mountLen);
if (mountLen + 1 < path.Length)
{
subPath = path.Slice(mountLen + 1);
}
else
{
subPath = default;
}
return Result.Success;
}
internal bool IsEnabledAccessLog()
{
return AccessLogEnabled && AccessLog != null && Time != null;
}
internal bool IsEnabledFileSystemAccessorAccessLog(string mountName)
{
if (MountTable.Find(mountName, out FileSystemAccessor accessor).IsFailure())
{
return true;
}
return accessor.IsAccessLogEnabled;
}
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, TimeSpan startTime, TimeSpan endTime, string message, [CallerMemberName] string caller = "")
{
AccessLog.Log(result, startTime, endTime, 0, message, caller);
}
internal void OutputAccessLog(Result result, TimeSpan startTime, TimeSpan endTime, FileHandle handle, string message, [CallerMemberName] string caller = "")
{
AccessLog.Log(result, startTime, endTime, handle.GetId(), message, caller);
}
internal void OutputAccessLog(Result result, TimeSpan startTime, TimeSpan endTime, DirectoryHandle handle, string message, [CallerMemberName] string caller = "")
{
AccessLog.Log(result, startTime, endTime, handle.GetId(), message, caller);
}
}
}

View file

@ -7,9 +7,9 @@ using LibHac.FsSystem;
namespace LibHac.Fs
{
public static class FileSystemManagerUtils
public static class FileSystemClientUtils
{
public static Result CopyDirectory(this FileSystemManager fs, string sourcePath, string destPath,
public static Result CopyDirectory(this FileSystemClient fs, string sourcePath, string destPath,
CreateFileOptions options = CreateFileOptions.None, IProgressReport logger = null)
{
Result rc = fs.OpenDirectory(out DirectoryHandle sourceHandle, sourcePath, OpenDirectoryMode.All);
@ -44,7 +44,7 @@ namespace LibHac.Fs
return Result.Success;
}
public static Result CopyFile(this FileSystemManager fs, string sourcePath, string destPath, IProgressReport logger = null)
public static Result CopyFile(this FileSystemClient fs, string sourcePath, string destPath, IProgressReport logger = null)
{
Result rc = fs.OpenFile(out FileHandle sourceHandle, sourcePath, OpenMode.Read);
if (rc.IsFailure()) return rc;
@ -96,17 +96,17 @@ namespace LibHac.Fs
return Result.Success;
}
public static IEnumerable<DirectoryEntryEx> EnumerateEntries(this FileSystemManager fs, string path)
public static IEnumerable<DirectoryEntryEx> EnumerateEntries(this FileSystemClient fs, string path)
{
return fs.EnumerateEntries(path, "*");
}
public static IEnumerable<DirectoryEntryEx> EnumerateEntries(this FileSystemManager fs, string path, string searchPattern)
public static IEnumerable<DirectoryEntryEx> EnumerateEntries(this FileSystemClient fs, string path, string searchPattern)
{
return fs.EnumerateEntries(path, searchPattern, SearchOptions.RecurseSubdirectories);
}
public static IEnumerable<DirectoryEntryEx> EnumerateEntries(this FileSystemManager fs, string path, string searchPattern, SearchOptions searchOptions)
public static IEnumerable<DirectoryEntryEx> EnumerateEntries(this FileSystemClient fs, string path, string searchPattern, SearchOptions searchOptions)
{
bool ignoreCase = searchOptions.HasFlag(SearchOptions.CaseInsensitive);
bool recurse = searchOptions.HasFlag(SearchOptions.RecurseSubdirectories);
@ -141,21 +141,21 @@ namespace LibHac.Fs
}
}
public static bool DirectoryExists(this FileSystemManager fs, string path)
public static bool DirectoryExists(this FileSystemClient fs, string path)
{
Result rc = fs.GetEntryType(out DirectoryEntryType type, path);
return (rc.IsSuccess() && type == DirectoryEntryType.Directory);
}
public static bool FileExists(this FileSystemManager fs, string path)
public static bool FileExists(this FileSystemClient fs, string path)
{
Result rc = fs.GetEntryType(out DirectoryEntryType type, path);
return (rc.IsSuccess() && type == DirectoryEntryType.File);
}
public static void EnsureDirectoryExists(this FileSystemManager fs, string path)
public static void EnsureDirectoryExists(this FileSystemClient fs, string path)
{
path = PathTools.Normalize(path);
if (fs.DirectoryExists(path)) return;
@ -195,12 +195,12 @@ namespace LibHac.Fs
fs.CreateDirectory(path);
}
public static void CreateOrOverwriteFile(this FileSystemManager fs, string path, long size)
public static void CreateOrOverwriteFile(this FileSystemClient fs, string path, long size)
{
fs.CreateOrOverwriteFile(path, size, CreateFileOptions.None);
}
public static void CreateOrOverwriteFile(this FileSystemManager fs, string path, long size, CreateFileOptions options)
public static void CreateOrOverwriteFile(this FileSystemClient fs, string path, long size, CreateFileOptions options)
{
path = PathTools.Normalize(path);
@ -209,7 +209,7 @@ namespace LibHac.Fs
fs.CreateFile(path, size, CreateFileOptions.None);
}
internal static bool IsEnabledFileSystemAccessorAccessLog(this FileSystemManager fs, string mountName)
internal static bool IsEnabledFileSystemAccessorAccessLog(this FileSystemClient fs, string mountName)
{
if (fs.MountTable.Find(mountName, out FileSystemAccessor accessor).IsFailure())
{

View file

@ -1,652 +0,0 @@
using System;
using System.Runtime.CompilerServices;
using LibHac.Common;
using LibHac.Fs.Accessors;
using LibHac.FsSystem;
namespace LibHac.Fs
{
// Todo: Access log for FindFileSystem
public class FileSystemManager
{
internal Horizon Os { get; }
internal ITimeSpanGenerator Time { get; }
private IAccessLog AccessLog { get; set; }
internal MountTable MountTable { get; } = new MountTable();
private bool AccessLogEnabled { get; set; }
public FileSystemManager(Horizon os)
{
Os = os;
}
public FileSystemManager(Horizon os, ITimeSpanGenerator timer)
{
Os = os;
Time = timer;
}
public FileSystemManager(ITimeSpanGenerator timer)
{
Time = timer;
}
public Result Register(U8Span mountName, IFileSystem fileSystem)
{
return Register(mountName, fileSystem, null);
}
public Result Register(U8Span mountName, IFileSystem fileSystem, ICommonMountNameGenerator nameGenerator)
{
var accessor = new FileSystemAccessor(mountName.ToString(), fileSystem, this, nameGenerator);
Result rc = MountTable.Mount(accessor);
if (rc.IsFailure()) return rc;
accessor.IsAccessLogEnabled = IsEnabledAccessLog();
return Result.Success;
}
public void Unmount(string mountName)
{
Result rc;
if (IsEnabledAccessLog() && this.IsEnabledFileSystemAccessorAccessLog(mountName))
{
TimeSpan startTime = Time.GetCurrent();
rc = MountTable.Unmount(mountName);
TimeSpan endTime = Time.GetCurrent();
OutputAccessLog(rc, startTime, endTime, $", name: \"{mountName}\"");
}
else
{
rc = MountTable.Unmount(mountName);
}
rc.ThrowIfFailure();
}
public void SetAccessLog(bool isEnabled, IAccessLog accessLog = null)
{
AccessLogEnabled = isEnabled;
if (accessLog != null) AccessLog = accessLog;
}
public Result CreateDirectory(string path)
{
Result rc = FindFileSystem(path.AsSpan(), out FileSystemAccessor fileSystem, out ReadOnlySpan<char> subPath);
if (rc.IsFailure()) return rc;
if (IsEnabledAccessLog() && fileSystem.IsAccessLogEnabled)
{
TimeSpan startTime = Time.GetCurrent();
rc = fileSystem.CreateDirectory(subPath.ToString());
TimeSpan endTime = Time.GetCurrent();
OutputAccessLog(rc, startTime, endTime, $", path: \"{path}\"");
}
else
{
rc = fileSystem.CreateDirectory(subPath.ToString());
}
return rc;
}
public Result CreateFile(string path, long size)
{
return CreateFile(path, size, CreateFileOptions.None);
}
public Result CreateFile(string path, long size, CreateFileOptions options)
{
Result rc = FindFileSystem(path.AsSpan(), out FileSystemAccessor fileSystem, out ReadOnlySpan<char> subPath);
if (rc.IsFailure()) return rc;
if (IsEnabledAccessLog() && fileSystem.IsAccessLogEnabled)
{
TimeSpan startTime = Time.GetCurrent();
rc = fileSystem.CreateFile(subPath.ToString(), size, options);
TimeSpan endTime = Time.GetCurrent();
OutputAccessLog(rc, startTime, endTime, $", path: \"{path}\", size: {size}");
}
else
{
rc = fileSystem.CreateFile(subPath.ToString(), size, options);
}
return rc;
}
public Result DeleteDirectory(string path)
{
Result rc = FindFileSystem(path.AsSpan(), out FileSystemAccessor fileSystem, out ReadOnlySpan<char> subPath);
if (rc.IsFailure()) return rc;
if (IsEnabledAccessLog() && fileSystem.IsAccessLogEnabled)
{
TimeSpan startTime = Time.GetCurrent();
rc = fileSystem.DeleteDirectory(subPath.ToString());
TimeSpan endTime = Time.GetCurrent();
OutputAccessLog(rc, startTime, endTime, $", path: \"{path}\"");
}
else
{
rc = fileSystem.DeleteDirectory(subPath.ToString());
}
return rc;
}
public Result DeleteDirectoryRecursively(string path)
{
Result rc = FindFileSystem(path.AsSpan(), out FileSystemAccessor fileSystem, out ReadOnlySpan<char> subPath);
if (rc.IsFailure()) return rc;
if (IsEnabledAccessLog() && fileSystem.IsAccessLogEnabled)
{
TimeSpan startTime = Time.GetCurrent();
rc = fileSystem.DeleteDirectoryRecursively(subPath.ToString());
TimeSpan endTime = Time.GetCurrent();
OutputAccessLog(rc, startTime, endTime, $", path: \"{path}\"");
}
else
{
rc = fileSystem.DeleteDirectoryRecursively(subPath.ToString());
}
return rc;
}
public Result CleanDirectoryRecursively(string path)
{
Result rc = FindFileSystem(path.AsSpan(), out FileSystemAccessor fileSystem, out ReadOnlySpan<char> subPath);
if (rc.IsFailure()) return rc;
if (IsEnabledAccessLog() && fileSystem.IsAccessLogEnabled)
{
TimeSpan startTime = Time.GetCurrent();
rc = fileSystem.CleanDirectoryRecursively(subPath.ToString());
TimeSpan endTime = Time.GetCurrent();
OutputAccessLog(rc, startTime, endTime, $", path: \"{path}\"");
}
else
{
rc = fileSystem.CleanDirectoryRecursively(subPath.ToString());
}
return rc;
}
public Result DeleteFile(string path)
{
Result rc = FindFileSystem(path.AsSpan(), out FileSystemAccessor fileSystem, out ReadOnlySpan<char> subPath);
if (rc.IsFailure()) return rc;
if (IsEnabledAccessLog() && fileSystem.IsAccessLogEnabled)
{
TimeSpan startTime = Time.GetCurrent();
rc = fileSystem.DeleteFile(subPath.ToString());
TimeSpan endTime = Time.GetCurrent();
OutputAccessLog(rc, startTime, endTime, $", path: \"{path}\"");
}
else
{
rc = fileSystem.DeleteFile(subPath.ToString());
}
return rc;
}
public Result RenameDirectory(string oldPath, string newPath)
{
Result rc = FindFileSystem(oldPath.AsSpan(), out FileSystemAccessor oldFileSystem, out ReadOnlySpan<char> oldSubPath);
if (rc.IsFailure()) return rc;
rc = FindFileSystem(newPath.AsSpan(), out FileSystemAccessor newFileSystem, out ReadOnlySpan<char> newSubPath);
if (rc.IsFailure()) return rc;
if (oldFileSystem != newFileSystem)
{
return ResultFs.DifferentDestFileSystem.Log();
}
if (IsEnabledAccessLog() && oldFileSystem.IsAccessLogEnabled)
{
TimeSpan startTime = Time.GetCurrent();
rc = oldFileSystem.RenameDirectory(oldSubPath.ToString(), newSubPath.ToString());
TimeSpan endTime = Time.GetCurrent();
OutputAccessLog(rc, startTime, endTime, $", path: \"{oldPath}\", new_path: \"{newPath}\"");
}
else
{
rc = oldFileSystem.RenameDirectory(oldSubPath.ToString(), newSubPath.ToString());
}
return rc;
}
public Result RenameFile(string oldPath, string newPath)
{
Result rc = FindFileSystem(oldPath.AsSpan(), out FileSystemAccessor oldFileSystem, out ReadOnlySpan<char> oldSubPath);
if (rc.IsFailure()) return rc;
rc = FindFileSystem(newPath.AsSpan(), out FileSystemAccessor newFileSystem, out ReadOnlySpan<char> newSubPath);
if (rc.IsFailure()) return rc;
if (oldFileSystem != newFileSystem)
{
return ResultFs.DifferentDestFileSystem.Log();
}
if (IsEnabledAccessLog() && oldFileSystem.IsAccessLogEnabled)
{
TimeSpan startTime = Time.GetCurrent();
rc = oldFileSystem.RenameFile(oldSubPath.ToString(), newSubPath.ToString());
TimeSpan endTime = Time.GetCurrent();
OutputAccessLog(rc, startTime, endTime, $", path: \"{oldPath}\", new_path: \"{newPath}\"");
}
else
{
rc = oldFileSystem.RenameFile(oldSubPath.ToString(), newSubPath.ToString());
}
return rc;
}
public Result GetEntryType(out DirectoryEntryType type, string path)
{
type = default;
Result rc = FindFileSystem(path.AsSpan(), out FileSystemAccessor fileSystem, out ReadOnlySpan<char> subPath);
if (rc.IsFailure()) return rc;
if (IsEnabledAccessLog() && fileSystem.IsAccessLogEnabled)
{
TimeSpan startTime = Time.GetCurrent();
rc = fileSystem.GetEntryType(out type, subPath.ToString());
TimeSpan endTime = Time.GetCurrent();
OutputAccessLog(rc, startTime, endTime, $", path: \"{path}\"");
}
else
{
rc = fileSystem.GetEntryType(out type, subPath.ToString());
}
return rc;
}
public Result OpenFile(out FileHandle handle, string path, OpenMode mode)
{
handle = default;
Result rc = FindFileSystem(path.AsSpan(), out FileSystemAccessor fileSystem, out ReadOnlySpan<char> subPath);
if (rc.IsFailure()) return rc;
if (IsEnabledAccessLog() && fileSystem.IsAccessLogEnabled)
{
TimeSpan startTime = Time.GetCurrent();
rc = fileSystem.OpenFile(out FileAccessor file, subPath.ToString(), mode);
handle = new FileHandle(file);
TimeSpan endTime = Time.GetCurrent();
OutputAccessLog(rc, startTime, endTime, handle, $", path: \"{path}\", open_mode: {mode}");
}
else
{
rc = fileSystem.OpenFile(out FileAccessor file, subPath.ToString(), mode);
handle = new FileHandle(file);
}
return rc;
}
public Result OpenDirectory(out DirectoryHandle handle, string path, OpenDirectoryMode mode)
{
handle = default;
Result rc = FindFileSystem(path.AsSpan(), out FileSystemAccessor fileSystem, out ReadOnlySpan<char> subPath);
if (rc.IsFailure()) return rc;
if (IsEnabledAccessLog() && fileSystem.IsAccessLogEnabled)
{
TimeSpan startTime = Time.GetCurrent();
rc = fileSystem.OpenDirectory(out DirectoryAccessor dir, subPath.ToString(), mode);
handle = new DirectoryHandle(dir);
TimeSpan endTime = Time.GetCurrent();
OutputAccessLog(rc, startTime, endTime, handle, $", path: \"{path}\", open_mode: {mode}");
}
else
{
rc = fileSystem.OpenDirectory(out DirectoryAccessor dir, subPath.ToString(), mode);
handle = new DirectoryHandle(dir);
}
return rc;
}
public Result GetFreeSpaceSize(out long freeSpace, string path)
{
freeSpace = default;
Result rc = FindFileSystem(path.AsSpan(), out FileSystemAccessor fileSystem, out ReadOnlySpan<char> subPath);
if (rc.IsFailure()) return rc;
return fileSystem.GetFreeSpaceSize(out freeSpace, subPath.ToString());
}
public Result GetTotalSpaceSize(out long totalSpace, string path)
{
totalSpace = default;
Result rc = FindFileSystem(path.AsSpan(), out FileSystemAccessor fileSystem, out ReadOnlySpan<char> subPath);
if (rc.IsFailure()) return rc;
return fileSystem.GetTotalSpaceSize(out totalSpace, subPath.ToString());
}
public Result GetFileTimeStamp(out FileTimeStampRaw timeStamp, string path)
{
timeStamp = default;
Result rc = FindFileSystem(path.AsSpan(), out FileSystemAccessor fileSystem, out ReadOnlySpan<char> subPath);
if (rc.IsFailure()) return rc;
return fileSystem.GetFileTimeStampRaw(out timeStamp, subPath.ToString());
}
public Result Commit(string mountName)
{
Result rc = MountTable.Find(mountName, out FileSystemAccessor fileSystem);
if (rc.IsFailure()) return rc;
if (IsEnabledAccessLog() && fileSystem.IsAccessLogEnabled)
{
TimeSpan startTime = Time.GetCurrent();
rc = fileSystem.Commit();
TimeSpan endTime = Time.GetCurrent();
OutputAccessLog(rc, startTime, endTime, $", name: \"{mountName}\"");
}
else
{
rc = fileSystem.Commit();
}
return rc;
}
// ==========================
// Operations on file handles
// ==========================
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, 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.ValueOutOfRange.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, ReadOption option)
{
Result rc;
if (IsEnabledAccessLog() && IsEnabledHandleAccessLog(handle))
{
TimeSpan startTime = Time.GetCurrent();
rc = handle.File.Read(out bytesRead, offset, destination, option);
TimeSpan endTime = Time.GetCurrent();
OutputAccessLog(rc, startTime, endTime, handle, $", offset: {offset}, size: {destination.Length}");
}
else
{
rc = handle.File.Read(out bytesRead, offset, destination, 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, WriteOption option)
{
Result rc;
if (IsEnabledAccessLog() && IsEnabledHandleAccessLog(handle))
{
TimeSpan startTime = Time.GetCurrent();
rc = handle.File.Write(offset, source, option);
TimeSpan endTime = Time.GetCurrent();
string optionString = (option & WriteOption.Flush) == 0 ? "" : $", write_option: {option}";
OutputAccessLog(rc, startTime, endTime, handle, $", offset: {offset}, size: {source.Length}{optionString}");
}
else
{
rc = handle.File.Write(offset, source, option);
}
return rc;
}
public Result FlushFile(FileHandle handle)
{
Result rc;
if (IsEnabledAccessLog() && IsEnabledHandleAccessLog(handle))
{
TimeSpan startTime = Time.GetCurrent();
rc = handle.File.Flush();
TimeSpan endTime = Time.GetCurrent();
OutputAccessLog(rc, startTime, endTime, handle, string.Empty);
}
else
{
rc = handle.File.Flush();
}
return rc;
}
public Result GetFileSize(out long fileSize, FileHandle handle)
{
return handle.File.GetSize(out fileSize);
}
public Result SetFileSize(FileHandle handle, long size)
{
Result rc;
if (IsEnabledAccessLog() && IsEnabledHandleAccessLog(handle))
{
TimeSpan startTime = Time.GetCurrent();
rc = handle.File.SetSize(size);
TimeSpan endTime = Time.GetCurrent();
OutputAccessLog(rc, startTime, endTime, handle, $", size: {size}");
}
else
{
rc = handle.File.SetSize(size);
}
return rc;
}
public OpenMode GetFileOpenMode(FileHandle handle)
{
return handle.File.OpenMode;
}
public void CloseFile(FileHandle handle)
{
if (IsEnabledAccessLog() && IsEnabledHandleAccessLog(handle))
{
TimeSpan startTime = Time.GetCurrent();
handle.File.Dispose();
TimeSpan endTime = Time.GetCurrent();
OutputAccessLog(Result.Success, startTime, endTime, handle, string.Empty);
}
else
{
handle.File.Dispose();
}
}
// ==========================
// Operations on directory handles
// ==========================
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))
{
TimeSpan startTime = Time.GetCurrent();
rc = handle.Directory.Read(out entriesRead, entryBuffer);
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))
{
TimeSpan startTime = Time.GetCurrent();
handle.Directory.Dispose();
TimeSpan endTime = Time.GetCurrent();
OutputAccessLog(Result.Success, startTime, endTime, handle, string.Empty);
}
else
{
handle.Directory.Dispose();
}
}
internal Result FindFileSystem(ReadOnlySpan<char> path, out FileSystemAccessor fileSystem, out ReadOnlySpan<char> subPath)
{
fileSystem = default;
Result rc = GetMountName(path, out ReadOnlySpan<char> mountName, out subPath);
if (rc.IsFailure()) return rc;
rc = MountTable.Find(mountName.ToString(), out fileSystem);
if (rc.IsFailure()) return rc;
return Result.Success;
}
internal static Result GetMountName(ReadOnlySpan<char> path, out ReadOnlySpan<char> mountName, out ReadOnlySpan<char> subPath)
{
int mountLen = 0;
int maxMountLen = Math.Min(path.Length, PathTools.MountNameLength);
for (int i = 0; i < maxMountLen; i++)
{
if (path[i] == PathTools.MountSeparator)
{
mountLen = i;
break;
}
}
if (mountLen == 0)
{
mountName = default;
subPath = default;
return ResultFs.InvalidMountName;
}
mountName = path.Slice(0, mountLen);
if (mountLen + 1 < path.Length)
{
subPath = path.Slice(mountLen + 1);
}
else
{
subPath = default;
}
return Result.Success;
}
internal bool IsEnabledAccessLog()
{
return AccessLogEnabled && AccessLog != null && Time != null;
}
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, TimeSpan startTime, TimeSpan endTime, string message, [CallerMemberName] string caller = "")
{
AccessLog.Log(result, startTime, endTime, 0, message, caller);
}
internal void OutputAccessLog(Result result, TimeSpan startTime, TimeSpan endTime, FileHandle handle, string message, [CallerMemberName] string caller = "")
{
AccessLog.Log(result, startTime, endTime, handle.GetId(), message, caller);
}
internal void OutputAccessLog(Result result, TimeSpan startTime, TimeSpan endTime, DirectoryHandle handle, string message, [CallerMemberName] string caller = "")
{
AccessLog.Log(result, startTime, endTime, handle.GetId(), message, caller);
}
}
}

View file

@ -8,21 +8,16 @@ namespace LibHac
{
internal ITimeSpanGenerator Time { get; }
public FileSystemManager Fs { get; }
public FileSystemClient Fs { get; }
public FileSystemServer FsSrv { get; private set; }
private readonly object _initLocker = new object();
public Horizon()
{
Fs = new FileSystemManager(this);
}
public Horizon(ITimeSpanGenerator timer)
{
Time = timer;
Fs = new FileSystemManager(this, timer);
Fs = new FileSystemClient(timer);
}
public void InitializeFileSystemServer(FileSystemCreators fsCreators)

View file

@ -8,7 +8,7 @@ namespace hactoolnet
{
public static class FsUtils
{
public static void CopyDirectoryWithProgress(FileSystemManager fs, string sourcePath, string destPath,
public static void CopyDirectoryWithProgress(FileSystemClient fs, string sourcePath, string destPath,
CreateFileOptions options = CreateFileOptions.None, IProgressReport logger = null)
{
try
@ -23,7 +23,7 @@ namespace hactoolnet
}
}
private static void CopyDirectoryWithProgressInternal(FileSystemManager fs, string sourcePath, string destPath,
private static void CopyDirectoryWithProgressInternal(FileSystemClient fs, string sourcePath, string destPath,
CreateFileOptions options, IProgressReport logger)
{
fs.OpenDirectory(out DirectoryHandle sourceHandle, sourcePath, OpenDirectoryMode.All).ThrowIfFailure();
@ -53,7 +53,7 @@ namespace hactoolnet
}
}
public static long GetTotalSize(FileSystemManager fs, string path, string searchPattern = "*")
public static long GetTotalSize(FileSystemClient fs, string path, string searchPattern = "*")
{
long size = 0;
@ -65,7 +65,7 @@ namespace hactoolnet
return size;
}
public static Result CopyFileWithProgress(FileSystemManager fs, string sourcePath, string destPath, IProgressReport logger = null)
public static Result CopyFileWithProgress(FileSystemClient fs, string sourcePath, string destPath, IProgressReport logger = null)
{
Result rc = fs.OpenFile(out FileHandle sourceHandle, sourcePath, OpenMode.Read);
if (rc.IsFailure()) return rc;
@ -95,7 +95,7 @@ namespace hactoolnet
rc = fs.ReadFile(out long _, sourceHandle, offset, buf);
if (rc.IsFailure()) return rc;
rc = fs.WriteFile(destHandle, buf, offset);
rc = fs.WriteFile(destHandle, offset, buf);
if (rc.IsFailure()) return rc;
logger?.ReportAdd(toRead);

View file

@ -44,7 +44,7 @@ namespace hactoolnet
if (ctx.Options.SectionOutDir[i] != null)
{
FileSystemManager fs = ctx.Horizon.Fs;
FileSystemClient fs = ctx.Horizon.Fs;
string mountName = $"section{i}";
@ -95,7 +95,7 @@ namespace hactoolnet
if (ctx.Options.RomfsOutDir != null)
{
FileSystemManager fs = ctx.Horizon.Fs;
FileSystemClient fs = ctx.Horizon.Fs;
fs.Register("rom".AsU8Span(), OpenFileSystemByType(NcaSectionType.Data));
fs.Register("output".AsU8Span(), new LocalFileSystem(ctx.Options.RomfsOutDir));
@ -152,7 +152,7 @@ namespace hactoolnet
if (ctx.Options.ExefsOutDir != null)
{
FileSystemManager fs = ctx.Horizon.Fs;
FileSystemClient fs = ctx.Horizon.Fs;
fs.Register("code".AsU8Span(), OpenFileSystemByType(NcaSectionType.Code));
fs.Register("output".AsU8Span(), new LocalFileSystem(ctx.Options.ExefsOutDir));

View file

@ -29,7 +29,7 @@ namespace hactoolnet
bool signNeeded = ctx.Options.SignSave;
var save = new SaveDataFileSystem(ctx.Keyset, file, ctx.Options.IntegrityLevel, true);
FileSystemManager fs = ctx.Horizon.Fs;
FileSystemClient fs = ctx.Horizon.Fs;
fs.Register("save".AsU8Span(), save);