mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2025-02-09 13:14:46 +01:00
Swap in the new fsa code except for some access log calls
This commit is contained in:
parent
0dc433d8a2
commit
684fcd460f
@ -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
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -29,6 +29,7 @@ namespace LibHac.Diag
|
||||
if (condition)
|
||||
return;
|
||||
|
||||
result.Log();
|
||||
DoAbort(result, message);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 = "")
|
||||
{
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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)]
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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))
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs.Fsa;
|
||||
using LibHac.Fs.Impl;
|
||||
using LibHac.FsSrv.Sf;
|
||||
using LibHac.Ncm;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -1,4 +1,5 @@
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs.Fsa;
|
||||
using LibHac.Fs.Impl;
|
||||
using LibHac.FsSrv.Sf;
|
||||
using LibHac.Ncm;
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -4,6 +4,7 @@ using System.Runtime.InteropServices;
|
||||
using LibHac.Common;
|
||||
using LibHac.Diag;
|
||||
using LibHac.Fs;
|
||||
using LibHac.Fs.Fsa;
|
||||
|
||||
namespace LibHac.Kvdb
|
||||
{
|
||||
|
@ -56,7 +56,7 @@ namespace LibHac.Os
|
||||
|
||||
public void Unlock()
|
||||
{
|
||||
Abort.DoAbortUnless(!IsLockedByCurrentThread());
|
||||
Abort.DoAbortUnless(IsLockedByCurrentThread());
|
||||
_cs.Leave();
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -1,5 +1,6 @@
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
using LibHac.Fs.Fsa;
|
||||
using LibHac.Fs.Shim;
|
||||
using Xunit;
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
using LibHac.Fs.Fsa;
|
||||
using LibHac.Fs.Shim;
|
||||
using Xunit;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user