mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2024-11-14 10:49:41 +01:00
Fix method signatures in IFileSystemProxy
This commit is contained in:
parent
882e6bc937
commit
a3220cc8df
20 changed files with 404 additions and 208 deletions
|
@ -3,6 +3,7 @@ using System.Runtime.CompilerServices;
|
||||||
using LibHac.Common;
|
using LibHac.Common;
|
||||||
using LibHac.Fs.Accessors;
|
using LibHac.Fs.Accessors;
|
||||||
using LibHac.FsSrv;
|
using LibHac.FsSrv;
|
||||||
|
using LibHac.Sf;
|
||||||
|
|
||||||
namespace LibHac.Fs
|
namespace LibHac.Fs
|
||||||
{
|
{
|
||||||
|
@ -187,7 +188,7 @@ namespace LibHac.Fs
|
||||||
string logString = AccessLogHelpers.BuildDefaultLogLine(result, startTime, endTime, handleId, message, caller);
|
string logString = AccessLogHelpers.BuildDefaultLogLine(result, startTime, endTime, handleId, message, caller);
|
||||||
|
|
||||||
IFileSystemProxy fsProxy = GetFileSystemProxyServiceObject();
|
IFileSystemProxy fsProxy = GetFileSystemProxyServiceObject();
|
||||||
fsProxy.OutputAccessLogToSdCard(logString.ToU8Span());
|
fsProxy.OutputAccessLogToSdCard(new InBuffer(logString.ToU8Span())).IgnoreResult();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
using LibHac.Common;
|
using LibHac.Common;
|
||||||
using LibHac.Fs.Impl;
|
using LibHac.Fs.Impl;
|
||||||
using LibHac.FsSrv;
|
using LibHac.FsSrv;
|
||||||
|
@ -137,8 +138,7 @@ namespace LibHac.Fs.Shim
|
||||||
// todo: Decide how to handle SetBisRootForHost since it allows mounting any directory on the user's computer
|
// todo: Decide how to handle SetBisRootForHost since it allows mounting any directory on the user's computer
|
||||||
public static Result SetBisRootForHost(this FileSystemClient fs, BisPartitionId partitionId, U8Span rootPath)
|
public static Result SetBisRootForHost(this FileSystemClient fs, BisPartitionId partitionId, U8Span rootPath)
|
||||||
{
|
{
|
||||||
FsPath sfPath;
|
Unsafe.SkipInit(out FsPath path);
|
||||||
unsafe { _ = &sfPath; } // workaround for CS0165
|
|
||||||
|
|
||||||
int pathLen = StringUtils.GetLength(rootPath, PathTools.MaxPathLength + 1);
|
int pathLen = StringUtils.GetLength(rootPath, PathTools.MaxPathLength + 1);
|
||||||
if (pathLen > PathTools.MaxPathLength)
|
if (pathLen > PathTools.MaxPathLength)
|
||||||
|
@ -150,18 +150,20 @@ namespace LibHac.Fs.Shim
|
||||||
? StringTraits.NullTerminator
|
? StringTraits.NullTerminator
|
||||||
: StringTraits.DirectorySeparator;
|
: StringTraits.DirectorySeparator;
|
||||||
|
|
||||||
var sb = new U8StringBuilder(sfPath.Str);
|
var sb = new U8StringBuilder(path.Str);
|
||||||
Result rc = sb.Append(rootPath).Append(endingSeparator).ToSfPath();
|
Result rc = sb.Append(rootPath).Append(endingSeparator).ToSfPath();
|
||||||
if (rc.IsFailure()) return rc;
|
if (rc.IsFailure()) return rc;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sfPath.Str[0] = StringTraits.NullTerminator;
|
path.Str[0] = StringTraits.NullTerminator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FspPath.FromSpan(out FspPath sfPath, path.Str);
|
||||||
|
|
||||||
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
|
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
|
||||||
|
|
||||||
return fsProxy.SetBisRootForHost(partitionId, ref sfPath);
|
return fsProxy.SetBisRootForHost(partitionId, in sfPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Result OpenBisPartition(this FileSystemClient fs, out IStorage partitionStorage, BisPartitionId partitionId)
|
public static Result OpenBisPartition(this FileSystemClient fs, out IStorage partitionStorage, BisPartitionId partitionId)
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
using System;
|
using System;
|
||||||
using LibHac.Common;
|
using LibHac.Common;
|
||||||
using LibHac.Fs.Fsa;
|
using LibHac.Fs.Impl;
|
||||||
using LibHac.FsSrv;
|
using LibHac.FsSrv;
|
||||||
|
using LibHac.FsSrv.Sf;
|
||||||
|
|
||||||
namespace LibHac.Fs.Shim
|
namespace LibHac.Fs.Shim
|
||||||
{
|
{
|
||||||
|
@ -12,12 +13,22 @@ namespace LibHac.Fs.Shim
|
||||||
Result rc = MountHelpers.CheckMountName(mountName);
|
Result rc = MountHelpers.CheckMountName(mountName);
|
||||||
if (rc.IsFailure()) return rc;
|
if (rc.IsFailure()) return rc;
|
||||||
|
|
||||||
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
|
ReferenceCountedDisposable<IFileSystemSf> customFs = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
|
||||||
|
|
||||||
rc = fsProxy.OpenCustomStorageFileSystem(out IFileSystem customFs, storageId);
|
rc = fsProxy.OpenCustomStorageFileSystem(out customFs, storageId);
|
||||||
if (rc.IsFailure()) return rc;
|
if (rc.IsFailure()) return rc;
|
||||||
|
|
||||||
return fs.Register(mountName, customFs);
|
var adapter = new FileSystemServiceObjectAdapter(customFs);
|
||||||
|
|
||||||
|
return fs.Register(mountName, adapter);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
customFs?.Dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string GetCustomStorageDirectoryName(CustomStorageId storageId)
|
public static string GetCustomStorageDirectoryName(CustomStorageId storageId)
|
||||||
|
|
|
@ -12,33 +12,63 @@ namespace LibHac.Fs.Shim
|
||||||
{
|
{
|
||||||
handle = default;
|
handle = default;
|
||||||
|
|
||||||
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
|
ReferenceCountedDisposable<IDeviceOperator> deviceOperator = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
|
||||||
|
|
||||||
Result rc = fsProxy.OpenDeviceOperator(out IDeviceOperator deviceOperator);
|
Result rc = fsProxy.OpenDeviceOperator(out deviceOperator);
|
||||||
if (rc.IsFailure()) return rc;
|
if (rc.IsFailure()) return rc;
|
||||||
|
|
||||||
return deviceOperator.GetGameCardHandle(out handle);
|
return deviceOperator.Target.GetGameCardHandle(out handle);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
deviceOperator?.Dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool IsGameCardInserted(this FileSystemClient fs)
|
public static bool IsGameCardInserted(this FileSystemClient fs)
|
||||||
{
|
{
|
||||||
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
|
ReferenceCountedDisposable<IDeviceOperator> deviceOperator = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
|
||||||
|
|
||||||
Result rc = fsProxy.OpenDeviceOperator(out IDeviceOperator deviceOperator);
|
Result rc = fsProxy.OpenDeviceOperator(out deviceOperator);
|
||||||
if (rc.IsFailure()) throw new LibHacException("Abort");
|
if (rc.IsFailure()) throw new LibHacException("Abort");
|
||||||
|
|
||||||
rc = deviceOperator.IsGameCardInserted(out bool isInserted);
|
rc = deviceOperator.Target.IsGameCardInserted(out bool isInserted);
|
||||||
if (rc.IsFailure()) throw new LibHacException("Abort");
|
if (rc.IsFailure()) throw new LibHacException("Abort");
|
||||||
|
|
||||||
return isInserted;
|
return isInserted;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
deviceOperator?.Dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Result OpenGameCardPartition(this FileSystemClient fs, out IStorage storage,
|
public static Result OpenGameCardPartition(this FileSystemClient fs, out IStorage storage,
|
||||||
GameCardHandle handle, GameCardPartitionRaw partitionType)
|
GameCardHandle handle, GameCardPartitionRaw partitionType)
|
||||||
{
|
{
|
||||||
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
|
storage = default;
|
||||||
|
|
||||||
return fsProxy.OpenGameCardStorage(out storage, handle, partitionType);
|
ReferenceCountedDisposable<IStorageSf> sfStorage = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
|
||||||
|
|
||||||
|
Result rc = fsProxy.OpenGameCardStorage(out sfStorage, handle, partitionType);
|
||||||
|
if (rc.IsFailure()) return rc;
|
||||||
|
|
||||||
|
storage = new StorageServiceObjectAdapter(sfStorage);
|
||||||
|
return Result.Success;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
sfStorage?.Dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Result MountGameCardPartition(this FileSystemClient fs, U8Span mountName, GameCardHandle handle,
|
public static Result MountGameCardPartition(this FileSystemClient fs, U8Span mountName, GameCardHandle handle,
|
||||||
|
|
|
@ -3,7 +3,9 @@ using System.Diagnostics;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using LibHac.Common;
|
using LibHac.Common;
|
||||||
using LibHac.Fs.Fsa;
|
using LibHac.Fs.Fsa;
|
||||||
|
using LibHac.Fs.Impl;
|
||||||
using LibHac.FsSrv;
|
using LibHac.FsSrv;
|
||||||
|
using LibHac.FsSrv.Sf;
|
||||||
using LibHac.FsSystem;
|
using LibHac.FsSystem;
|
||||||
using LibHac.Util;
|
using LibHac.Util;
|
||||||
using static LibHac.Fs.CommonPaths;
|
using static LibHac.Fs.CommonPaths;
|
||||||
|
@ -76,12 +78,11 @@ namespace LibHac.Fs.Shim
|
||||||
public static Result MountHostRoot(this FileSystemClient fs)
|
public static Result MountHostRoot(this FileSystemClient fs)
|
||||||
{
|
{
|
||||||
IFileSystem hostFileSystem = default;
|
IFileSystem hostFileSystem = default;
|
||||||
var path = new FsPath();
|
FspPath.CreateEmpty(out FspPath path);
|
||||||
path.Str[0] = 0;
|
|
||||||
|
|
||||||
static string LogMessageGenerator() => $", name: \"{HostRootFileSystemMountName.ToString()}\"";
|
static string LogMessageGenerator() => $", name: \"{HostRootFileSystemMountName.ToString()}\"";
|
||||||
|
|
||||||
Result OpenHostFs() => OpenHostFileSystemImpl(fs, out hostFileSystem, ref path, MountHostOption.None);
|
Result OpenHostFs() => OpenHostFileSystemImpl(fs, out hostFileSystem, in path, MountHostOption.None);
|
||||||
|
|
||||||
Result MountHostFs() => fs.Register(HostRootFileSystemMountName, hostFileSystem,
|
Result MountHostFs() => fs.Register(HostRootFileSystemMountName, hostFileSystem,
|
||||||
new HostRootCommonMountNameGenerator());
|
new HostRootCommonMountNameGenerator());
|
||||||
|
@ -110,13 +111,12 @@ namespace LibHac.Fs.Shim
|
||||||
public static Result MountHostRoot(this FileSystemClient fs, MountHostOption option)
|
public static Result MountHostRoot(this FileSystemClient fs, MountHostOption option)
|
||||||
{
|
{
|
||||||
IFileSystem hostFileSystem = default;
|
IFileSystem hostFileSystem = default;
|
||||||
var path = new FsPath();
|
FspPath.CreateEmpty(out FspPath path);
|
||||||
path.Str[0] = 0;
|
|
||||||
|
|
||||||
string LogMessageGenerator() =>
|
string LogMessageGenerator() =>
|
||||||
$", name: \"{HostRootFileSystemMountName.ToString()}, mount_host_option: {option}\"";
|
$", name: \"{HostRootFileSystemMountName.ToString()}, mount_host_option: {option}\"";
|
||||||
|
|
||||||
Result OpenHostFs() => OpenHostFileSystemImpl(fs, out hostFileSystem, ref path, option);
|
Result OpenHostFs() => OpenHostFileSystemImpl(fs, out hostFileSystem, in path, option);
|
||||||
|
|
||||||
Result MountHostFs() => fs.Register(HostRootFileSystemMountName, hostFileSystem,
|
Result MountHostFs() => fs.Register(HostRootFileSystemMountName, hostFileSystem,
|
||||||
new HostRootCommonMountNameGenerator());
|
new HostRootCommonMountNameGenerator());
|
||||||
|
@ -318,8 +318,7 @@ namespace LibHac.Fs.Shim
|
||||||
if (pathLength + 1 > PathTools.MaxPathLength)
|
if (pathLength + 1 > PathTools.MaxPathLength)
|
||||||
return ResultFs.TooLongPath.Log();
|
return ResultFs.TooLongPath.Log();
|
||||||
|
|
||||||
FsPath fullPath;
|
Unsafe.SkipInit(out FsPath fullPath);
|
||||||
unsafe { _ = &fullPath; } // workaround for CS0165
|
|
||||||
|
|
||||||
var sb = new U8StringBuilder(fullPath.Str);
|
var sb = new U8StringBuilder(fullPath.Str);
|
||||||
sb.Append(StringTraits.DirectorySeparator).Append(path);
|
sb.Append(StringTraits.DirectorySeparator).Append(path);
|
||||||
|
@ -341,7 +340,9 @@ namespace LibHac.Fs.Shim
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return OpenHostFileSystemImpl(fs, out fileSystem, ref fullPath, option);
|
FspPath.FromSpan(out FspPath sfPath, fullPath.Str);
|
||||||
|
|
||||||
|
return OpenHostFileSystemImpl(fs, out fileSystem, in sfPath, option);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -352,26 +353,34 @@ namespace LibHac.Fs.Shim
|
||||||
/// <param name="path">The path on the host computer to open. e.g. /C:\Windows\System32/</param>
|
/// <param name="path">The path on the host computer to open. e.g. /C:\Windows\System32/</param>
|
||||||
/// <param name="option">Options for opening the host file system.</param>
|
/// <param name="option">Options for opening the host file system.</param>
|
||||||
/// <returns>The <see cref="Result"/> of the operation.</returns>
|
/// <returns>The <see cref="Result"/> of the operation.</returns>
|
||||||
private static Result OpenHostFileSystemImpl(FileSystemClient fs, out IFileSystem fileSystem, ref FsPath path, MountHostOption option)
|
private static Result OpenHostFileSystemImpl(FileSystemClient fs, out IFileSystem fileSystem, in FspPath path,
|
||||||
|
MountHostOption option)
|
||||||
{
|
{
|
||||||
fileSystem = default;
|
fileSystem = default;
|
||||||
|
|
||||||
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
|
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
|
||||||
IFileSystem hostFs;
|
ReferenceCountedDisposable<IFileSystemSf> hostFs = null;
|
||||||
|
|
||||||
if (option == MountHostOption.None)
|
try
|
||||||
{
|
{
|
||||||
Result rc = fsProxy.OpenHostFileSystem(out hostFs, ref path);
|
if (option == MountHostOption.None)
|
||||||
if (rc.IsFailure()) return rc;
|
{
|
||||||
}
|
Result rc = fsProxy.OpenHostFileSystem(out hostFs, in path);
|
||||||
else
|
if (rc.IsFailure()) return rc;
|
||||||
{
|
}
|
||||||
Result rc = fsProxy.OpenHostFileSystemWithOption(out hostFs, ref path, option);
|
else
|
||||||
if (rc.IsFailure()) return rc;
|
{
|
||||||
}
|
Result rc = fsProxy.OpenHostFileSystemWithOption(out hostFs, in path, option);
|
||||||
|
if (rc.IsFailure()) return rc;
|
||||||
|
}
|
||||||
|
|
||||||
fileSystem = hostFs;
|
fileSystem = new FileSystemServiceObjectAdapter(hostFs);
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
hostFs?.Dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -212,7 +212,7 @@ namespace LibHac.Fs.Shim
|
||||||
SpaceId = spaceId
|
SpaceId = spaceId
|
||||||
};
|
};
|
||||||
|
|
||||||
return fsProxy.CreateSaveDataFileSystemBySystemSaveDataId(ref attribute, ref createInfo);
|
return fsProxy.CreateSaveDataFileSystemBySystemSaveDataId(in attribute, in createInfo);
|
||||||
},
|
},
|
||||||
() => $", savedataspaceid: {spaceId}, savedataid: 0x{saveDataId:X}, userid: 0x{userId.Id.High:X16}{userId.Id.Low:X16}, save_data_owner_id: 0x{ownerId:X}, save_data_size: {size}, save_data_journal_size: {journalSize}, save_data_flags: 0x{(int)flags:x8}");
|
() => $", savedataspaceid: {spaceId}, savedataid: 0x{saveDataId:X}, userid: 0x{userId.Id.High:X16}{userId.Id.Low:X16}, save_data_owner_id: 0x{ownerId:X}, save_data_size: {size}, save_data_journal_size: {journalSize}, save_data_flags: 0x{(int)flags:x8}");
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,15 +56,23 @@ namespace LibHac.Fs.Shim
|
||||||
|
|
||||||
public static bool IsSdCardInserted(this FileSystemClient fs)
|
public static bool IsSdCardInserted(this FileSystemClient fs)
|
||||||
{
|
{
|
||||||
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
|
ReferenceCountedDisposable<IDeviceOperator> deviceOperator = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
|
||||||
|
|
||||||
Result rc = fsProxy.OpenDeviceOperator(out IDeviceOperator deviceOperator);
|
Result rc = fsProxy.OpenDeviceOperator(out deviceOperator);
|
||||||
if (rc.IsFailure()) throw new HorizonResultException(rc, "Abort");
|
if (rc.IsFailure()) throw new HorizonResultException(rc, "Abort");
|
||||||
|
|
||||||
rc = deviceOperator.IsSdCardInserted(out bool isInserted);
|
rc = deviceOperator.Target.IsSdCardInserted(out bool isInserted);
|
||||||
if (rc.IsFailure()) throw new HorizonResultException(rc, "Abort");
|
if (rc.IsFailure()) throw new HorizonResultException(rc, "Abort");
|
||||||
|
|
||||||
return isInserted;
|
return isInserted;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
deviceOperator?.Dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Result SetSdCardEncryptionSeed(this FileSystemClient fs, in EncryptionSeed seed)
|
public static Result SetSdCardEncryptionSeed(this FileSystemClient fs, in EncryptionSeed seed)
|
||||||
|
|
|
@ -110,12 +110,12 @@ namespace LibHac.FsSrv.Creators
|
||||||
var partitionPath = GetPartitionPath(partitionId).ToU8String();
|
var partitionPath = GetPartitionPath(partitionId).ToU8String();
|
||||||
|
|
||||||
ReferenceCountedDisposable<IFileSystem> partitionFileSystem = null;
|
ReferenceCountedDisposable<IFileSystem> partitionFileSystem = null;
|
||||||
|
ReferenceCountedDisposable<IFileSystem> sharedRootFs = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Todo: Store shared file systems
|
sharedRootFs = new ReferenceCountedDisposable<IFileSystem>(Config.RootFileSystem);
|
||||||
using var sharedRootFs = new ReferenceCountedDisposable<IFileSystem>(Config.RootFileSystem);
|
|
||||||
|
|
||||||
Result rc = Utility.WrapSubDirectory(out partitionFileSystem, sharedRootFs, partitionPath, true);
|
Result rc = Utility.WrapSubDirectory(out partitionFileSystem, ref sharedRootFs, partitionPath, true);
|
||||||
|
|
||||||
if (rc.IsFailure()) return rc;
|
if (rc.IsFailure()) return rc;
|
||||||
|
|
||||||
|
@ -125,11 +125,12 @@ namespace LibHac.FsSrv.Creators
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Utility.CreateSubDirectoryFileSystem(out fileSystem, partitionFileSystem, rootPath);
|
return Utility.CreateSubDirectoryFileSystem(out fileSystem, ref partitionFileSystem, rootPath);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
partitionFileSystem?.Dispose();
|
partitionFileSystem?.Dispose();
|
||||||
|
sharedRootFs?.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,11 +5,7 @@ namespace LibHac.FsSrv.Creators
|
||||||
{
|
{
|
||||||
public interface ISubDirectoryFileSystemCreator
|
public interface ISubDirectoryFileSystemCreator
|
||||||
{
|
{
|
||||||
// Todo: Remove the raw IFileSystem overloads
|
Result Create(out ReferenceCountedDisposable<IFileSystem> subDirFileSystem, ref ReferenceCountedDisposable<IFileSystem> baseFileSystem, U8Span path);
|
||||||
Result Create(out IFileSystem subDirFileSystem, IFileSystem baseFileSystem, U8Span path);
|
Result Create(out ReferenceCountedDisposable<IFileSystem> subDirFileSystem, ref ReferenceCountedDisposable<IFileSystem> baseFileSystem, U8Span path, bool preserveUnc);
|
||||||
Result Create(out IFileSystem subDirFileSystem, IFileSystem baseFileSystem, U8Span path, bool preserveUnc);
|
|
||||||
|
|
||||||
Result Create(out ReferenceCountedDisposable<IFileSystem> subDirFileSystem, ReferenceCountedDisposable<IFileSystem> baseFileSystem, U8Span path);
|
|
||||||
Result Create(out ReferenceCountedDisposable<IFileSystem> subDirFileSystem, ReferenceCountedDisposable<IFileSystem> baseFileSystem, U8Span path, bool preserveUnc);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -6,31 +6,14 @@ namespace LibHac.FsSrv.Creators
|
||||||
{
|
{
|
||||||
public class SubDirectoryFileSystemCreator : ISubDirectoryFileSystemCreator
|
public class SubDirectoryFileSystemCreator : ISubDirectoryFileSystemCreator
|
||||||
{
|
{
|
||||||
public Result Create(out IFileSystem subDirFileSystem, IFileSystem baseFileSystem, U8Span path)
|
public Result Create(out ReferenceCountedDisposable<IFileSystem> subDirFileSystem,
|
||||||
|
ref ReferenceCountedDisposable<IFileSystem> baseFileSystem, U8Span path)
|
||||||
{
|
{
|
||||||
return Create(out subDirFileSystem, baseFileSystem, path, false);
|
return Create(out subDirFileSystem, ref baseFileSystem, path, false);
|
||||||
}
|
|
||||||
|
|
||||||
public Result Create(out IFileSystem subDirFileSystem, IFileSystem baseFileSystem, U8Span path, bool preserveUnc)
|
|
||||||
{
|
|
||||||
subDirFileSystem = default;
|
|
||||||
|
|
||||||
Result rc = baseFileSystem.OpenDirectory(out IDirectory _, path, OpenDirectoryMode.Directory);
|
|
||||||
if (rc.IsFailure()) return rc;
|
|
||||||
|
|
||||||
rc = SubdirectoryFileSystem.CreateNew(out SubdirectoryFileSystem fs, baseFileSystem, path.ToU8String(), preserveUnc);
|
|
||||||
subDirFileSystem = fs;
|
|
||||||
return rc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result Create(out ReferenceCountedDisposable<IFileSystem> subDirFileSystem,
|
public Result Create(out ReferenceCountedDisposable<IFileSystem> subDirFileSystem,
|
||||||
ReferenceCountedDisposable<IFileSystem> baseFileSystem, U8Span path)
|
ref ReferenceCountedDisposable<IFileSystem> baseFileSystem, U8Span path, bool preserveUnc)
|
||||||
{
|
|
||||||
return Create(out subDirFileSystem, baseFileSystem, path, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Result Create(out ReferenceCountedDisposable<IFileSystem> subDirFileSystem,
|
|
||||||
ReferenceCountedDisposable<IFileSystem> baseFileSystem, U8Span path, bool preserveUnc)
|
|
||||||
{
|
{
|
||||||
subDirFileSystem = default;
|
subDirFileSystem = default;
|
||||||
|
|
||||||
|
@ -39,7 +22,7 @@ namespace LibHac.FsSrv.Creators
|
||||||
if (rc.IsFailure()) return rc;
|
if (rc.IsFailure()) return rc;
|
||||||
|
|
||||||
// Initialize the SubdirectoryFileSystem
|
// Initialize the SubdirectoryFileSystem
|
||||||
var subDir = new SubdirectoryFileSystem(baseFileSystem, preserveUnc);
|
var subDir = new SubdirectoryFileSystem(ref baseFileSystem, preserveUnc);
|
||||||
using var subDirShared = new ReferenceCountedDisposable<SubdirectoryFileSystem>(subDir);
|
using var subDirShared = new ReferenceCountedDisposable<SubdirectoryFileSystem>(subDir);
|
||||||
|
|
||||||
rc = subDirShared.Target.Initialize(path);
|
rc = subDirShared.Target.Initialize(path);
|
||||||
|
|
|
@ -13,6 +13,8 @@ namespace LibHac.FsSrv
|
||||||
SdCard = sdCard;
|
SdCard = sdCard;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Dispose() { }
|
||||||
|
|
||||||
public Result IsSdCardInserted(out bool isInserted)
|
public Result IsSdCardInserted(out bool isInserted)
|
||||||
{
|
{
|
||||||
isInserted = SdCard.IsSdCardInserted();
|
isInserted = SdCard.IsSdCardInserted();
|
||||||
|
|
|
@ -4,6 +4,8 @@ using LibHac.Fs;
|
||||||
using LibHac.Fs.Fsa;
|
using LibHac.Fs.Fsa;
|
||||||
using LibHac.Fs.Shim;
|
using LibHac.Fs.Shim;
|
||||||
using LibHac.FsSrv.Creators;
|
using LibHac.FsSrv.Creators;
|
||||||
|
using LibHac.FsSrv.Impl;
|
||||||
|
using LibHac.FsSrv.Sf;
|
||||||
|
|
||||||
namespace LibHac.FsSrv
|
namespace LibHac.FsSrv
|
||||||
{
|
{
|
||||||
|
@ -13,7 +15,7 @@ namespace LibHac.FsSrv
|
||||||
private FileSystemCreators FsCreators => Config.FsCreatorInterfaces;
|
private FileSystemCreators FsCreators => Config.FsCreatorInterfaces;
|
||||||
internal ProgramRegistryImpl ProgramRegistry { get; }
|
internal ProgramRegistryImpl ProgramRegistry { get; }
|
||||||
|
|
||||||
private IDeviceOperator DeviceOperator { get; }
|
private ReferenceCountedDisposable<IDeviceOperator> DeviceOperator { get; }
|
||||||
|
|
||||||
private byte[] SdEncryptionSeed { get; } = new byte[0x10];
|
private byte[] SdEncryptionSeed { get; } = new byte[0x10];
|
||||||
|
|
||||||
|
@ -27,31 +29,57 @@ namespace LibHac.FsSrv
|
||||||
{
|
{
|
||||||
Config = config;
|
Config = config;
|
||||||
ProgramRegistry = new ProgramRegistryImpl(Config.ProgramRegistryService);
|
ProgramRegistry = new ProgramRegistryImpl(Config.ProgramRegistryService);
|
||||||
DeviceOperator = deviceOperator;
|
DeviceOperator = new ReferenceCountedDisposable<IDeviceOperator>(deviceOperator);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result OpenGameCardStorage(out IStorage storage, GameCardHandle handle, GameCardPartitionRaw partitionId)
|
public Result OpenGameCardStorage(out ReferenceCountedDisposable<IStorageSf> storage, GameCardHandle handle,
|
||||||
|
GameCardPartitionRaw partitionId)
|
||||||
{
|
{
|
||||||
switch (partitionId)
|
storage = default;
|
||||||
|
|
||||||
|
Result rc;
|
||||||
|
IStorage gcStorage = null;
|
||||||
|
ReferenceCountedDisposable<IStorage> sharedGcStorage = null;
|
||||||
|
try
|
||||||
{
|
{
|
||||||
case GameCardPartitionRaw.NormalReadOnly:
|
switch (partitionId)
|
||||||
return FsCreators.GameCardStorageCreator.CreateNormal(handle, out storage);
|
{
|
||||||
case GameCardPartitionRaw.SecureReadOnly:
|
case GameCardPartitionRaw.NormalReadOnly:
|
||||||
return FsCreators.GameCardStorageCreator.CreateSecure(handle, out storage);
|
rc = FsCreators.GameCardStorageCreator.CreateNormal(handle, out gcStorage);
|
||||||
case GameCardPartitionRaw.RootWriteOnly:
|
break;
|
||||||
return FsCreators.GameCardStorageCreator.CreateWritable(handle, out storage);
|
case GameCardPartitionRaw.SecureReadOnly:
|
||||||
default:
|
rc = FsCreators.GameCardStorageCreator.CreateSecure(handle, out gcStorage);
|
||||||
throw new ArgumentOutOfRangeException(nameof(partitionId), partitionId, null);
|
break;
|
||||||
|
case GameCardPartitionRaw.RootWriteOnly:
|
||||||
|
rc = FsCreators.GameCardStorageCreator.CreateWritable(handle, out gcStorage);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(partitionId), partitionId, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rc.IsFailure()) return rc;
|
||||||
|
|
||||||
|
sharedGcStorage = new ReferenceCountedDisposable<IStorage>(gcStorage);
|
||||||
|
gcStorage = null;
|
||||||
|
|
||||||
|
storage = StorageInterfaceAdapter.CreateShared(ref sharedGcStorage);
|
||||||
|
return Result.Success;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
gcStorage?.Dispose();
|
||||||
|
sharedGcStorage?.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result OpenDeviceOperator(out IDeviceOperator deviceOperator)
|
public Result OpenDeviceOperator(out ReferenceCountedDisposable<IDeviceOperator> deviceOperator)
|
||||||
{
|
{
|
||||||
deviceOperator = DeviceOperator;
|
deviceOperator = DeviceOperator.AddReference();
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result OpenCustomStorageFileSystem(out IFileSystem fileSystem, CustomStorageId storageId)
|
public Result OpenCustomStorageFileSystem(out ReferenceCountedDisposable<IFileSystem> fileSystem,
|
||||||
|
CustomStorageId storageId)
|
||||||
{
|
{
|
||||||
fileSystem = default;
|
fileSystem = default;
|
||||||
|
|
||||||
|
@ -72,7 +100,7 @@ namespace LibHac.FsSrv
|
||||||
EncryptedFsKeyId.CustomStorage, SdEncryptionSeed);
|
EncryptedFsKeyId.CustomStorage, SdEncryptionSeed);
|
||||||
if (rc.IsFailure()) return rc;
|
if (rc.IsFailure()) return rc;
|
||||||
|
|
||||||
fileSystem = encryptedFs;
|
fileSystem = new ReferenceCountedDisposable<IFileSystem>(encryptedFs);
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
}
|
}
|
||||||
case CustomStorageId.System:
|
case CustomStorageId.System:
|
||||||
|
@ -87,7 +115,8 @@ namespace LibHac.FsSrv
|
||||||
rc = Util.CreateSubFileSystem(out IFileSystem subFs, userFs, subDirName, true);
|
rc = Util.CreateSubFileSystem(out IFileSystem subFs, userFs, subDirName, true);
|
||||||
if (rc.IsFailure()) return rc;
|
if (rc.IsFailure()) return rc;
|
||||||
|
|
||||||
fileSystem = subFs;
|
// Todo: Get shared object from earlier functions
|
||||||
|
fileSystem = new ReferenceCountedDisposable<IFileSystem>(subFs);
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -95,7 +124,8 @@ namespace LibHac.FsSrv
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result OpenHostFileSystem(out IFileSystem fileSystem, U8Span path, bool openCaseSensitive)
|
public Result OpenHostFileSystem(out ReferenceCountedDisposable<IFileSystem> fileSystem, U8Span path,
|
||||||
|
bool openCaseSensitive)
|
||||||
{
|
{
|
||||||
fileSystem = default;
|
fileSystem = default;
|
||||||
Result rc;
|
Result rc;
|
||||||
|
@ -106,27 +136,42 @@ namespace LibHac.FsSrv
|
||||||
if (rc.IsFailure()) return rc;
|
if (rc.IsFailure()) return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Todo: Return shared fs from Create
|
||||||
rc = FsCreators.TargetManagerFileSystemCreator.Create(out IFileSystem hostFs, openCaseSensitive);
|
rc = FsCreators.TargetManagerFileSystemCreator.Create(out IFileSystem hostFs, openCaseSensitive);
|
||||||
if (rc.IsFailure()) return rc;
|
if (rc.IsFailure()) return rc;
|
||||||
|
|
||||||
if (path.IsEmpty())
|
ReferenceCountedDisposable<IFileSystem> sharedHostFs = null;
|
||||||
|
ReferenceCountedDisposable<IFileSystem> subDirFs = null;
|
||||||
|
|
||||||
|
try
|
||||||
{
|
{
|
||||||
ReadOnlySpan<byte> rootHostPath = new[] { (byte)'C', (byte)':', (byte)'/' };
|
sharedHostFs = new ReferenceCountedDisposable<IFileSystem>(hostFs);
|
||||||
rc = hostFs.GetEntryType(out _, new U8Span(rootHostPath));
|
|
||||||
|
|
||||||
// Nintendo ignores all results other than this one
|
if (path.IsEmpty())
|
||||||
if (ResultFs.TargetNotFound.Includes(rc))
|
{
|
||||||
return rc;
|
ReadOnlySpan<byte> rootHostPath = new[] { (byte)'C', (byte)':', (byte)'/' };
|
||||||
|
rc = sharedHostFs.Target.GetEntryType(out _, new U8Span(rootHostPath));
|
||||||
|
|
||||||
fileSystem = hostFs;
|
// Nintendo ignores all results other than this one
|
||||||
|
if (ResultFs.TargetNotFound.Includes(rc))
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
Shared.Move(out fileSystem, ref sharedHostFs);
|
||||||
|
return Result.Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = FsCreators.SubDirectoryFileSystemCreator.Create(out subDirFs, ref sharedHostFs, path,
|
||||||
|
preserveUnc: true);
|
||||||
|
if (rc.IsFailure()) return rc;
|
||||||
|
|
||||||
|
fileSystem = subDirFs;
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
rc = FsCreators.SubDirectoryFileSystemCreator.Create(out IFileSystem subDirFs, hostFs, path, preserveUnc: true);
|
{
|
||||||
if (rc.IsFailure()) return rc;
|
sharedHostFs?.Dispose();
|
||||||
|
subDirFs?.Dispose();
|
||||||
fileSystem = subDirFs;
|
}
|
||||||
return Result.Success;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result SetSdCardEncryptionSeed(in EncryptionSeed seed)
|
public Result SetSdCardEncryptionSeed(in EncryptionSeed seed)
|
||||||
|
@ -139,7 +184,7 @@ namespace LibHac.FsSrv
|
||||||
|
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result SetGlobalAccessLogMode(GlobalAccessLogMode mode)
|
public Result SetGlobalAccessLogMode(GlobalAccessLogMode mode)
|
||||||
{
|
{
|
||||||
LogMode = mode;
|
LogMode = mode;
|
||||||
|
|
|
@ -254,8 +254,8 @@ namespace LibHac.FsSrv
|
||||||
in hashSalt);
|
in hashSalt);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result CreateSaveDataFileSystemBySystemSaveDataId(ref SaveDataAttribute attribute,
|
public Result CreateSaveDataFileSystemBySystemSaveDataId(in SaveDataAttribute attribute,
|
||||||
ref SaveDataCreationInfo creationInfo)
|
in SaveDataCreationInfo creationInfo)
|
||||||
{
|
{
|
||||||
Result rc = GetSaveDataFileSystemService(out SaveDataFileSystemService saveFsService);
|
Result rc = GetSaveDataFileSystemService(out SaveDataFileSystemService saveFsService);
|
||||||
if (rc.IsFailure()) return rc;
|
if (rc.IsFailure()) return rc;
|
||||||
|
@ -399,17 +399,44 @@ namespace LibHac.FsSrv
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result OpenHostFileSystem(out IFileSystem fileSystem, ref FsPath path)
|
public Result OpenHostFileSystem(out ReferenceCountedDisposable<IFileSystemSf> fileSystem, in FspPath path)
|
||||||
{
|
{
|
||||||
return OpenHostFileSystemWithOption(out fileSystem, ref path, MountHostOption.None);
|
return OpenHostFileSystemWithOption(out fileSystem, in path, MountHostOption.None);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result OpenHostFileSystemWithOption(out IFileSystem fileSystem, ref FsPath path, MountHostOption option)
|
public Result OpenHostFileSystemWithOption(out ReferenceCountedDisposable<IFileSystemSf> fileSystem,
|
||||||
|
in FspPath path, MountHostOption option)
|
||||||
{
|
{
|
||||||
// Missing permission check
|
fileSystem = default;
|
||||||
|
|
||||||
return FsProxyCore.OpenHostFileSystem(out fileSystem, new U8Span(path.Str),
|
Result rc = GetProgramInfo(out ProgramInfo programInfo);
|
||||||
option.HasFlag(MountHostOption.PseudoCaseSensitive));
|
if (rc.IsFailure()) return rc;
|
||||||
|
|
||||||
|
Accessibility accessibility = programInfo.AccessControl.GetAccessibilityFor(AccessibilityType.MountHost);
|
||||||
|
|
||||||
|
if (!accessibility.CanRead || !accessibility.CanWrite)
|
||||||
|
return ResultFs.PermissionDenied.Log();
|
||||||
|
|
||||||
|
ReferenceCountedDisposable<IFileSystem> hostFs = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
rc = FsProxyCore.OpenHostFileSystem(out hostFs, new U8Span(path.Str),
|
||||||
|
option.HasFlag(MountHostOption.PseudoCaseSensitive));
|
||||||
|
if (rc.IsFailure()) return rc;
|
||||||
|
|
||||||
|
bool isRootPath = path.Str[0] == 0;
|
||||||
|
|
||||||
|
fileSystem = FileSystemInterfaceAdapter.CreateShared(ref hostFs, isRootPath);
|
||||||
|
|
||||||
|
if (fileSystem is null)
|
||||||
|
return ResultFs.AllocationFailureInCreateShared.Log();
|
||||||
|
|
||||||
|
return Result.Success;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
hostFs?.Dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result OpenSdCardFileSystem(out ReferenceCountedDisposable<IFileSystemSf> fileSystem)
|
public Result OpenSdCardFileSystem(out ReferenceCountedDisposable<IFileSystemSf> fileSystem)
|
||||||
|
@ -432,20 +459,31 @@ namespace LibHac.FsSrv
|
||||||
return GetBaseFileSystemService().IsExFatSupported(out isSupported);
|
return GetBaseFileSystemService().IsExFatSupported(out isSupported);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result OpenGameCardStorage(out IStorage storage, GameCardHandle handle, GameCardPartitionRaw partitionId)
|
public Result OpenGameCardStorage(out ReferenceCountedDisposable<IStorageSf> storage, GameCardHandle handle,
|
||||||
|
GameCardPartitionRaw partitionId)
|
||||||
{
|
{
|
||||||
// Missing permission check and StorageInterfaceAdapter
|
// Missing permission check and StorageInterfaceAdapter
|
||||||
|
|
||||||
return FsProxyCore.OpenGameCardStorage(out storage, handle, partitionId);
|
return FsProxyCore.OpenGameCardStorage(out storage, handle, partitionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result OpenDeviceOperator(out IDeviceOperator deviceOperator)
|
public Result OpenDeviceOperator(out ReferenceCountedDisposable<IDeviceOperator> deviceOperator)
|
||||||
{
|
{
|
||||||
// Missing permission check
|
// Missing permission check
|
||||||
|
|
||||||
return FsProxyCore.OpenDeviceOperator(out deviceOperator);
|
return FsProxyCore.OpenDeviceOperator(out deviceOperator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Result OpenSdCardDetectionEventNotifier(out ReferenceCountedDisposable<IEventNotifier> eventNotifier)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Result OpenGameCardDetectionEventNotifier(out ReferenceCountedDisposable<IEventNotifier> eventNotifier)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
public Result OpenSystemDataUpdateEventNotifier(out ReferenceCountedDisposable<IEventNotifier> eventNotifier)
|
public Result OpenSystemDataUpdateEventNotifier(out ReferenceCountedDisposable<IEventNotifier> eventNotifier)
|
||||||
{
|
{
|
||||||
Result rc = GetNcaFileSystemService(out NcaFileSystemService ncaFsService);
|
Result rc = GetNcaFileSystemService(out NcaFileSystemService ncaFsService);
|
||||||
|
@ -659,11 +697,37 @@ namespace LibHac.FsSrv
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result OpenCustomStorageFileSystem(out IFileSystem fileSystem, CustomStorageId storageId)
|
public Result OpenCustomStorageFileSystem(out ReferenceCountedDisposable<IFileSystemSf> fileSystem, CustomStorageId storageId)
|
||||||
{
|
{
|
||||||
// Missing permission check, speed emulation storage type wrapper, and FileSystemInterfaceAdapter
|
fileSystem = default;
|
||||||
|
var storageFlag = StorageType.NonGameCard;
|
||||||
|
using var scopedLayoutType = new ScopedStorageLayoutTypeSetter(storageFlag);
|
||||||
|
|
||||||
return FsProxyCore.OpenCustomStorageFileSystem(out fileSystem, storageId);
|
Result rc = GetProgramInfo(out ProgramInfo programInfo);
|
||||||
|
if (rc.IsFailure()) return rc;
|
||||||
|
|
||||||
|
AccessibilityType accessType = storageId > CustomStorageId.SdCard
|
||||||
|
? AccessibilityType.NotMount
|
||||||
|
: AccessibilityType.MountCustomStorage;
|
||||||
|
|
||||||
|
Accessibility accessibility = programInfo.AccessControl.GetAccessibilityFor(accessType);
|
||||||
|
|
||||||
|
if (!accessibility.CanRead || !accessibility.CanWrite)
|
||||||
|
return ResultFs.PermissionDenied.Log();
|
||||||
|
|
||||||
|
ReferenceCountedDisposable<IFileSystem> customFs = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
customFs = StorageLayoutTypeSetFileSystem.CreateShared(ref customFs, storageFlag);
|
||||||
|
customFs = AsynchronousAccessFileSystem.CreateShared(ref customFs);
|
||||||
|
fileSystem = FileSystemInterfaceAdapter.CreateShared(ref customFs);
|
||||||
|
|
||||||
|
return Result.Success;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
customFs?.Dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result OpenGameCardFileSystem(out ReferenceCountedDisposable<IFileSystemSf> fileSystem,
|
public Result OpenGameCardFileSystem(out ReferenceCountedDisposable<IFileSystemSf> fileSystem,
|
||||||
|
@ -766,7 +830,7 @@ namespace LibHac.FsSrv
|
||||||
.RegisterProgramIndexMapInfo(programIndexMapInfoBuffer, programCount);
|
.RegisterProgramIndexMapInfo(programIndexMapInfoBuffer, programCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result SetBisRootForHost(BisPartitionId partitionId, ref FsPath path)
|
public Result SetBisRootForHost(BisPartitionId partitionId, in FspPath path)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
@ -839,7 +903,7 @@ namespace LibHac.FsSrv
|
||||||
return GetProgramIndexRegistryService().GetProgramIndex(out programIndex, out programCount);
|
return GetProgramIndexRegistryService().GetProgramIndex(out programIndex, out programCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result OutputAccessLogToSdCard(U8Span logString)
|
public Result OutputAccessLogToSdCard(InBuffer logString)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
namespace LibHac.FsSrv
|
using System;
|
||||||
|
|
||||||
|
namespace LibHac.FsSrv
|
||||||
{
|
{
|
||||||
public interface IDeviceOperator
|
public interface IDeviceOperator : IDisposable
|
||||||
{
|
{
|
||||||
Result IsSdCardInserted(out bool isInserted);
|
Result IsSdCardInserted(out bool isInserted);
|
||||||
Result IsGameCardInserted(out bool isInserted);
|
Result IsGameCardInserted(out bool isInserted);
|
||||||
|
|
|
@ -20,24 +20,24 @@ namespace LibHac.FsSrv
|
||||||
Result OpenBisFileSystem(out ReferenceCountedDisposable<IFileSystemSf> fileSystem, in FspPath rootPath, BisPartitionId partitionId);
|
Result OpenBisFileSystem(out ReferenceCountedDisposable<IFileSystemSf> fileSystem, in FspPath rootPath, BisPartitionId partitionId);
|
||||||
Result OpenBisStorage(out ReferenceCountedDisposable<IStorageSf> storage, BisPartitionId partitionId);
|
Result OpenBisStorage(out ReferenceCountedDisposable<IStorageSf> storage, BisPartitionId partitionId);
|
||||||
Result InvalidateBisCache();
|
Result InvalidateBisCache();
|
||||||
Result OpenHostFileSystemWithOption(out IFileSystem fileSystem, ref FsPath path, MountHostOption option);
|
Result OpenHostFileSystem(out ReferenceCountedDisposable<IFileSystemSf> fileSystem, in FspPath path);
|
||||||
Result OpenHostFileSystem(out IFileSystem fileSystem, ref FsPath path);
|
|
||||||
Result OpenSdCardFileSystem(out ReferenceCountedDisposable<IFileSystemSf> fileSystem);
|
Result OpenSdCardFileSystem(out ReferenceCountedDisposable<IFileSystemSf> fileSystem);
|
||||||
Result FormatSdCardFileSystem();
|
Result FormatSdCardFileSystem();
|
||||||
Result DeleteSaveDataFileSystem(ulong saveDataId);
|
Result DeleteSaveDataFileSystem(ulong saveDataId);
|
||||||
Result CreateSaveDataFileSystem(in SaveDataAttribute attribute, in SaveDataCreationInfo creationInfo, in SaveDataMetaInfo metaInfo);
|
Result CreateSaveDataFileSystem(in SaveDataAttribute attribute, in SaveDataCreationInfo creationInfo, in SaveDataMetaInfo metaInfo);
|
||||||
Result CreateSaveDataFileSystemBySystemSaveDataId(ref SaveDataAttribute attribute, ref SaveDataCreationInfo creationInfo);
|
Result CreateSaveDataFileSystemBySystemSaveDataId(in SaveDataAttribute attribute, in SaveDataCreationInfo creationInfo);
|
||||||
Result RegisterSaveDataFileSystemAtomicDeletion(InBuffer saveDataIds);
|
Result RegisterSaveDataFileSystemAtomicDeletion(InBuffer saveDataIds);
|
||||||
Result DeleteSaveDataFileSystemBySaveDataSpaceId(SaveDataSpaceId spaceId, ulong saveDataId);
|
Result DeleteSaveDataFileSystemBySaveDataSpaceId(SaveDataSpaceId spaceId, ulong saveDataId);
|
||||||
Result FormatSdCardDryRun();
|
Result FormatSdCardDryRun();
|
||||||
Result IsExFatSupported(out bool isSupported);
|
Result IsExFatSupported(out bool isSupported);
|
||||||
Result DeleteSaveDataFileSystemBySaveDataAttribute(SaveDataSpaceId spaceId, in SaveDataAttribute attribute);
|
Result DeleteSaveDataFileSystemBySaveDataAttribute(SaveDataSpaceId spaceId, in SaveDataAttribute attribute);
|
||||||
Result OpenGameCardStorage(out IStorage storage, GameCardHandle handle, GameCardPartitionRaw partitionId);
|
Result OpenGameCardStorage(out ReferenceCountedDisposable<IStorageSf> storage, GameCardHandle handle, GameCardPartitionRaw partitionId);
|
||||||
Result OpenGameCardFileSystem(out ReferenceCountedDisposable<IFileSystemSf> fileSystem, GameCardHandle handle, GameCardPartition partitionId);
|
Result OpenGameCardFileSystem(out ReferenceCountedDisposable<IFileSystemSf> fileSystem, GameCardHandle handle, GameCardPartition partitionId);
|
||||||
Result ExtendSaveDataFileSystem(SaveDataSpaceId spaceId, ulong saveDataId, long dataSize, long journalSize);
|
Result ExtendSaveDataFileSystem(SaveDataSpaceId spaceId, ulong saveDataId, long dataSize, long journalSize);
|
||||||
Result DeleteCacheStorage(ushort index);
|
Result DeleteCacheStorage(ushort index);
|
||||||
Result GetCacheStorageSize(out long dataSize, out long journalSize, ushort index);
|
Result GetCacheStorageSize(out long dataSize, out long journalSize, ushort index);
|
||||||
Result CreateSaveDataFileSystemWithHashSalt(in SaveDataAttribute attribute, in SaveDataCreationInfo creationInfo, in SaveDataMetaInfo metaInfo, in HashSalt hashSalt);
|
Result CreateSaveDataFileSystemWithHashSalt(in SaveDataAttribute attribute, in SaveDataCreationInfo creationInfo, in SaveDataMetaInfo metaInfo, in HashSalt hashSalt);
|
||||||
|
Result OpenHostFileSystemWithOption(out ReferenceCountedDisposable<IFileSystemSf> fileSystem, in FspPath path, MountHostOption option);
|
||||||
Result OpenSaveDataFileSystem(out ReferenceCountedDisposable<IFileSystemSf> fileSystem, SaveDataSpaceId spaceId, in SaveDataAttribute attribute);
|
Result OpenSaveDataFileSystem(out ReferenceCountedDisposable<IFileSystemSf> fileSystem, SaveDataSpaceId spaceId, in SaveDataAttribute attribute);
|
||||||
Result OpenSaveDataFileSystemBySystemSaveDataId(out ReferenceCountedDisposable<IFileSystemSf> fileSystem, SaveDataSpaceId spaceId, in SaveDataAttribute attribute);
|
Result OpenSaveDataFileSystemBySystemSaveDataId(out ReferenceCountedDisposable<IFileSystemSf> fileSystem, SaveDataSpaceId spaceId, in SaveDataAttribute attribute);
|
||||||
Result OpenReadOnlySaveDataFileSystem(out ReferenceCountedDisposable<IFileSystemSf> fileSystem, SaveDataSpaceId spaceId, in SaveDataAttribute attribute);
|
Result OpenReadOnlySaveDataFileSystem(out ReferenceCountedDisposable<IFileSystemSf> fileSystem, SaveDataSpaceId spaceId, in SaveDataAttribute attribute);
|
||||||
|
@ -62,15 +62,17 @@ namespace LibHac.FsSrv
|
||||||
Result OpenImageDirectoryFileSystem(out ReferenceCountedDisposable<IFileSystemSf> fileSystem, ImageDirectoryId directoryId);
|
Result OpenImageDirectoryFileSystem(out ReferenceCountedDisposable<IFileSystemSf> fileSystem, ImageDirectoryId directoryId);
|
||||||
Result OpenContentStorageFileSystem(out ReferenceCountedDisposable<IFileSystemSf> fileSystem, ContentStorageId storageId);
|
Result OpenContentStorageFileSystem(out ReferenceCountedDisposable<IFileSystemSf> fileSystem, ContentStorageId storageId);
|
||||||
Result OpenCloudBackupWorkStorageFileSystem(out ReferenceCountedDisposable<IFileSystemSf> fileSystem, CloudBackupWorkStorageId storageId);
|
Result OpenCloudBackupWorkStorageFileSystem(out ReferenceCountedDisposable<IFileSystemSf> fileSystem, CloudBackupWorkStorageId storageId);
|
||||||
Result OpenCustomStorageFileSystem(out IFileSystem fileSystem, CustomStorageId storageId);
|
Result OpenCustomStorageFileSystem(out ReferenceCountedDisposable<IFileSystemSf> fileSystem, CustomStorageId storageId);
|
||||||
Result OpenDataStorageByCurrentProcess(out ReferenceCountedDisposable<IStorageSf> storage);
|
Result OpenDataStorageByCurrentProcess(out ReferenceCountedDisposable<IStorageSf> storage);
|
||||||
Result OpenDataStorageByProgramId(out ReferenceCountedDisposable<IStorageSf> storage, ProgramId programId);
|
Result OpenDataStorageByProgramId(out ReferenceCountedDisposable<IStorageSf> storage, ProgramId programId);
|
||||||
Result OpenDataStorageByDataId(out ReferenceCountedDisposable<IStorageSf> storage, DataId dataId, StorageId storageId);
|
Result OpenDataStorageByDataId(out ReferenceCountedDisposable<IStorageSf> storage, DataId dataId, StorageId storageId);
|
||||||
Result OpenPatchDataStorageByCurrentProcess(out ReferenceCountedDisposable<IStorageSf> storage);
|
Result OpenPatchDataStorageByCurrentProcess(out ReferenceCountedDisposable<IStorageSf> storage);
|
||||||
Result OpenDataFileSystemWithProgramIndex(out ReferenceCountedDisposable<IFileSystemSf> fileSystem, byte programIndex);
|
Result OpenDataFileSystemWithProgramIndex(out ReferenceCountedDisposable<IFileSystemSf> fileSystem, byte programIndex);
|
||||||
Result OpenDataStorageWithProgramIndex(out ReferenceCountedDisposable<IStorageSf> storage, byte programIndex);
|
Result OpenDataStorageWithProgramIndex(out ReferenceCountedDisposable<IStorageSf> storage, byte programIndex);
|
||||||
Result OpenDeviceOperator(out IDeviceOperator deviceOperator);
|
Result OpenDeviceOperator(out ReferenceCountedDisposable<IDeviceOperator> deviceOperator);
|
||||||
|
|
||||||
|
Result OpenSdCardDetectionEventNotifier(out ReferenceCountedDisposable<IEventNotifier> eventNotifier);
|
||||||
|
Result OpenGameCardDetectionEventNotifier(out ReferenceCountedDisposable<IEventNotifier> eventNotifier);
|
||||||
Result OpenSystemDataUpdateEventNotifier(out ReferenceCountedDisposable<IEventNotifier> eventNotifier);
|
Result OpenSystemDataUpdateEventNotifier(out ReferenceCountedDisposable<IEventNotifier> eventNotifier);
|
||||||
Result NotifySystemDataUpdateEvent();
|
Result NotifySystemDataUpdateEvent();
|
||||||
|
|
||||||
|
@ -96,13 +98,13 @@ namespace LibHac.FsSrv
|
||||||
Result IsSdCardAccessible(out bool isAccessible);
|
Result IsSdCardAccessible(out bool isAccessible);
|
||||||
|
|
||||||
Result RegisterProgramIndexMapInfo(InBuffer programIndexMapInfoBuffer, int programCount);
|
Result RegisterProgramIndexMapInfo(InBuffer programIndexMapInfoBuffer, int programCount);
|
||||||
Result SetBisRootForHost(BisPartitionId partitionId, ref FsPath path);
|
Result SetBisRootForHost(BisPartitionId partitionId, in FspPath path);
|
||||||
Result SetSaveDataSize(long saveDataSize, long saveDataJournalSize);
|
Result SetSaveDataSize(long saveDataSize, long saveDataJournalSize);
|
||||||
Result SetSaveDataRootPath(in FspPath path);
|
Result SetSaveDataRootPath(in FspPath path);
|
||||||
Result DisableAutoSaveDataCreation();
|
Result DisableAutoSaveDataCreation();
|
||||||
Result SetGlobalAccessLogMode(GlobalAccessLogMode mode);
|
Result SetGlobalAccessLogMode(GlobalAccessLogMode mode);
|
||||||
Result GetGlobalAccessLogMode(out GlobalAccessLogMode mode);
|
Result GetGlobalAccessLogMode(out GlobalAccessLogMode mode);
|
||||||
Result OutputAccessLogToSdCard(U8Span logString);
|
Result OutputAccessLogToSdCard(InBuffer logString);
|
||||||
Result RegisterUpdatePartition();
|
Result RegisterUpdatePartition();
|
||||||
Result OpenRegisteredUpdatePartition(out ReferenceCountedDisposable<IFileSystemSf> fileSystem);
|
Result OpenRegisteredUpdatePartition(out ReferenceCountedDisposable<IFileSystemSf> fileSystem);
|
||||||
|
|
||||||
|
|
|
@ -10,9 +10,21 @@ namespace LibHac.FsSrv.Impl
|
||||||
{
|
{
|
||||||
private ReferenceCountedDisposable<IStorage> BaseStorage { get; }
|
private ReferenceCountedDisposable<IStorage> BaseStorage { get; }
|
||||||
|
|
||||||
public StorageInterfaceAdapter(ReferenceCountedDisposable<IStorage> baseStorage)
|
private StorageInterfaceAdapter(ref ReferenceCountedDisposable<IStorage> baseStorage)
|
||||||
{
|
{
|
||||||
BaseStorage = baseStorage.AddReference();
|
BaseStorage = Shared.Move(ref baseStorage);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ReferenceCountedDisposable<IStorageSf> CreateShared(
|
||||||
|
ref ReferenceCountedDisposable<IStorage> baseStorage)
|
||||||
|
{
|
||||||
|
var adapter = new StorageInterfaceAdapter(ref baseStorage);
|
||||||
|
return new ReferenceCountedDisposable<IStorageSf>(adapter);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
BaseStorage?.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result Read(long offset, Span<byte> destination)
|
public Result Read(long offset, Span<byte> destination)
|
||||||
|
@ -47,7 +59,7 @@ namespace LibHac.FsSrv.Impl
|
||||||
if (source.Length < 0)
|
if (source.Length < 0)
|
||||||
return ResultFs.InvalidSize.Log();
|
return ResultFs.InvalidSize.Log();
|
||||||
|
|
||||||
// Note: Thread priority is temporarily when writing in FS
|
// Note: Thread priority is temporarily increased when writing in FS
|
||||||
|
|
||||||
return BaseStorage.Target.Write(offset, source);
|
return BaseStorage.Target.Write(offset, source);
|
||||||
}
|
}
|
||||||
|
@ -93,9 +105,5 @@ namespace LibHac.FsSrv.Impl
|
||||||
|
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
}
|
}
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
BaseStorage?.Dispose();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -122,7 +122,7 @@ namespace LibHac.FsSrv.Impl
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Result CreateSubDirectoryFileSystem(out ReferenceCountedDisposable<IFileSystem> subDirFileSystem,
|
public static Result CreateSubDirectoryFileSystem(out ReferenceCountedDisposable<IFileSystem> subDirFileSystem,
|
||||||
ReferenceCountedDisposable<IFileSystem> baseFileSystem, U8Span subPath, bool preserveUnc = false)
|
ref ReferenceCountedDisposable<IFileSystem> baseFileSystem, U8Span subPath, bool preserveUnc = false)
|
||||||
{
|
{
|
||||||
subDirFileSystem = default;
|
subDirFileSystem = default;
|
||||||
|
|
||||||
|
@ -132,7 +132,7 @@ namespace LibHac.FsSrv.Impl
|
||||||
|
|
||||||
dir.Dispose();
|
dir.Dispose();
|
||||||
|
|
||||||
var fs = new SubdirectoryFileSystem(baseFileSystem, preserveUnc);
|
var fs = new SubdirectoryFileSystem(ref baseFileSystem, preserveUnc);
|
||||||
using (var subDirFs = new ReferenceCountedDisposable<SubdirectoryFileSystem>(fs))
|
using (var subDirFs = new ReferenceCountedDisposable<SubdirectoryFileSystem>(fs))
|
||||||
{
|
{
|
||||||
rc = subDirFs.Target.Initialize(subPath);
|
rc = subDirFs.Target.Initialize(subPath);
|
||||||
|
@ -144,7 +144,7 @@ namespace LibHac.FsSrv.Impl
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Result WrapSubDirectory(out ReferenceCountedDisposable<IFileSystem> fileSystem,
|
public static Result WrapSubDirectory(out ReferenceCountedDisposable<IFileSystem> fileSystem,
|
||||||
ReferenceCountedDisposable<IFileSystem> baseFileSystem, U8Span path, bool createIfMissing)
|
ref ReferenceCountedDisposable<IFileSystem> baseFileSystem, U8Span path, bool createIfMissing)
|
||||||
{
|
{
|
||||||
fileSystem = default;
|
fileSystem = default;
|
||||||
|
|
||||||
|
@ -159,7 +159,7 @@ namespace LibHac.FsSrv.Impl
|
||||||
Result rc = EnsureDirectory(baseFileSystem.Target, path);
|
Result rc = EnsureDirectory(baseFileSystem.Target, path);
|
||||||
if (rc.IsFailure()) return rc;
|
if (rc.IsFailure()) return rc;
|
||||||
|
|
||||||
return CreateSubDirectoryFileSystem(out fileSystem, baseFileSystem, path);
|
return CreateSubDirectoryFileSystem(out fileSystem, ref baseFileSystem, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ReadOnlySpan<byte> FileSystemRootPath => // /
|
private static ReadOnlySpan<byte> FileSystemRootPath => // /
|
||||||
|
|
|
@ -100,17 +100,29 @@ namespace LibHac.FsSrv
|
||||||
|
|
||||||
if (type == FileSystemProxyType.Manual)
|
if (type == FileSystemProxyType.Manual)
|
||||||
{
|
{
|
||||||
rc = TryOpenCaseSensitiveContentDirectory(
|
ReferenceCountedDisposable<IFileSystem> manualFileSystem = null;
|
||||||
out ReferenceCountedDisposable<IFileSystem> manualFileSystem, baseFileSystem, currentPath);
|
ReferenceCountedDisposable<IFileSystem> readOnlyFileSystem = null;
|
||||||
if (rc.IsFailure()) return rc;
|
try
|
||||||
|
{
|
||||||
|
rc = TryOpenCaseSensitiveContentDirectory(out manualFileSystem, ref baseFileSystem,
|
||||||
|
currentPath);
|
||||||
|
if (rc.IsFailure()) return rc;
|
||||||
|
|
||||||
var readOnlyFs = new ReadOnlyFileSystem(manualFileSystem);
|
readOnlyFileSystem = ReadOnlyFileSystem.CreateShared(ref manualFileSystem);
|
||||||
fileSystem = new ReferenceCountedDisposable<IFileSystem>(readOnlyFs);
|
if (readOnlyFileSystem?.Target is null)
|
||||||
|
return ResultFs.AllocationFailureInAllocateShared.Log();
|
||||||
|
|
||||||
return Result.Success;
|
Shared.Move(out fileSystem, ref readOnlyFileSystem);
|
||||||
|
return Result.Success;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
manualFileSystem?.Dispose();
|
||||||
|
readOnlyFileSystem?.Dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return TryOpenContentDirectory(currentPath, out fileSystem, baseFileSystem, type, true);
|
return TryOpenContentDirectory(currentPath, out fileSystem, ref baseFileSystem, type, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = TryOpenNsp(ref currentPath, out ReferenceCountedDisposable<IFileSystem> nspFileSystem, baseFileSystem);
|
rc = TryOpenNsp(ref currentPath, out ReferenceCountedDisposable<IFileSystem> nspFileSystem, baseFileSystem);
|
||||||
|
@ -371,20 +383,27 @@ namespace LibHac.FsSrv
|
||||||
|
|
||||||
private Result TryOpenContentDirectory(U8Span path,
|
private Result TryOpenContentDirectory(U8Span path,
|
||||||
out ReferenceCountedDisposable<IFileSystem> contentFileSystem,
|
out ReferenceCountedDisposable<IFileSystem> contentFileSystem,
|
||||||
ReferenceCountedDisposable<IFileSystem> baseFileSystem, FileSystemProxyType fsType, bool preserveUnc)
|
ref ReferenceCountedDisposable<IFileSystem> baseFileSystem, FileSystemProxyType fsType, bool preserveUnc)
|
||||||
{
|
{
|
||||||
contentFileSystem = default;
|
contentFileSystem = default;
|
||||||
|
|
||||||
Result rc = _config.SubDirectoryFsCreator.Create(out ReferenceCountedDisposable<IFileSystem> subDirFs,
|
ReferenceCountedDisposable<IFileSystem> subDirFs = null;
|
||||||
baseFileSystem, path, preserveUnc);
|
try
|
||||||
if (rc.IsFailure()) return rc;
|
{
|
||||||
|
Result rc = _config.SubDirectoryFsCreator.Create(out subDirFs, ref baseFileSystem, path, preserveUnc);
|
||||||
|
if (rc.IsFailure()) return rc;
|
||||||
|
|
||||||
return OpenSubDirectoryForFsType(out contentFileSystem, subDirFs, fsType);
|
return OpenSubDirectoryForFsType(out contentFileSystem, ref subDirFs, fsType);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
subDirFs?.Dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Result TryOpenCaseSensitiveContentDirectory(
|
private Result TryOpenCaseSensitiveContentDirectory(
|
||||||
out ReferenceCountedDisposable<IFileSystem> contentFileSystem,
|
out ReferenceCountedDisposable<IFileSystem> contentFileSystem,
|
||||||
ReferenceCountedDisposable<IFileSystem> baseFileSystem, U8Span path)
|
ref ReferenceCountedDisposable<IFileSystem> baseFileSystem, U8Span path)
|
||||||
{
|
{
|
||||||
contentFileSystem = default;
|
contentFileSystem = default;
|
||||||
Unsafe.SkipInit(out FsPath fullPath);
|
Unsafe.SkipInit(out FsPath fullPath);
|
||||||
|
@ -408,11 +427,11 @@ namespace LibHac.FsSrv
|
||||||
if (rc.IsFailure()) return rc;
|
if (rc.IsFailure()) return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
return _config.SubDirectoryFsCreator.Create(out contentFileSystem, baseFileSystem, fullPath);
|
return _config.SubDirectoryFsCreator.Create(out contentFileSystem, ref baseFileSystem, fullPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Result OpenSubDirectoryForFsType(out ReferenceCountedDisposable<IFileSystem> fileSystem,
|
private Result OpenSubDirectoryForFsType(out ReferenceCountedDisposable<IFileSystem> fileSystem,
|
||||||
ReferenceCountedDisposable<IFileSystem> baseFileSystem, FileSystemProxyType fsType)
|
ref ReferenceCountedDisposable<IFileSystem> baseFileSystem, FileSystemProxyType fsType)
|
||||||
{
|
{
|
||||||
fileSystem = default;
|
fileSystem = default;
|
||||||
ReadOnlySpan<byte> dirName;
|
ReadOnlySpan<byte> dirName;
|
||||||
|
@ -442,19 +461,26 @@ namespace LibHac.FsSrv
|
||||||
return ResultFs.InvalidArgument.Log();
|
return ResultFs.InvalidArgument.Log();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Open the subdirectory filesystem
|
ReferenceCountedDisposable<IFileSystem> subDirFs = null;
|
||||||
Result rc = _config.SubDirectoryFsCreator.Create(out ReferenceCountedDisposable<IFileSystem> subDirFs,
|
try
|
||||||
baseFileSystem, new U8Span(dirName));
|
|
||||||
if (rc.IsFailure()) return rc;
|
|
||||||
|
|
||||||
if (fsType == FileSystemProxyType.Code)
|
|
||||||
{
|
{
|
||||||
rc = _config.StorageOnNcaCreator.VerifyAcidSignature(subDirFs.Target, null);
|
// Open the subdirectory filesystem
|
||||||
|
Result rc = _config.SubDirectoryFsCreator.Create(out subDirFs, ref baseFileSystem, new U8Span(dirName));
|
||||||
if (rc.IsFailure()) return rc;
|
if (rc.IsFailure()) return rc;
|
||||||
}
|
|
||||||
|
|
||||||
fileSystem = subDirFs;
|
if (fsType == FileSystemProxyType.Code)
|
||||||
return Result.Success;
|
{
|
||||||
|
rc = _config.StorageOnNcaCreator.VerifyAcidSignature(subDirFs.Target, null);
|
||||||
|
if (rc.IsFailure()) return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
Shared.Move(out fileSystem, ref subDirFs);
|
||||||
|
return Result.Success;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
subDirFs?.Dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Result TryOpenNsp(ref U8Span path, out ReferenceCountedDisposable<IFileSystem> fileSystem,
|
private Result TryOpenNsp(ref U8Span path, out ReferenceCountedDisposable<IFileSystem> fileSystem,
|
||||||
|
@ -659,29 +685,37 @@ namespace LibHac.FsSrv
|
||||||
if (rc.IsFailure()) return rc;
|
if (rc.IsFailure()) return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = _config.TargetManagerFsCreator.Create(out ReferenceCountedDisposable<IFileSystem> hostFs,
|
ReferenceCountedDisposable<IFileSystem> hostFs = null;
|
||||||
openCaseSensitive);
|
ReferenceCountedDisposable<IFileSystem> subDirFs = null;
|
||||||
if (rc.IsFailure()) return rc;
|
try
|
||||||
|
|
||||||
if (path.IsEmpty())
|
|
||||||
{
|
{
|
||||||
ReadOnlySpan<byte> rootHostPath = new[] { (byte)'C', (byte)':', (byte)'/' };
|
rc = _config.TargetManagerFsCreator.Create(out hostFs, openCaseSensitive);
|
||||||
rc = hostFs.Target.GetEntryType(out _, new U8Span(rootHostPath));
|
if (rc.IsFailure()) return rc;
|
||||||
|
|
||||||
// Nintendo ignores all results other than this one
|
if (path.IsEmpty())
|
||||||
if (ResultFs.TargetNotFound.Includes(rc))
|
{
|
||||||
return rc;
|
ReadOnlySpan<byte> rootHostPath = new[] { (byte)'C', (byte)':', (byte)'/' };
|
||||||
|
rc = hostFs.Target.GetEntryType(out _, new U8Span(rootHostPath));
|
||||||
|
|
||||||
fileSystem = hostFs;
|
// Nintendo ignores all results other than this one
|
||||||
|
if (ResultFs.TargetNotFound.Includes(rc))
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
Shared.Move(out fileSystem, ref hostFs);
|
||||||
|
return Result.Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = _config.SubDirectoryFsCreator.Create(out subDirFs, ref hostFs, path, preserveUnc: true);
|
||||||
|
if (rc.IsFailure()) return rc;
|
||||||
|
|
||||||
|
Shared.Move(out fileSystem, ref subDirFs);
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
rc = _config.SubDirectoryFsCreator.Create(out ReferenceCountedDisposable<IFileSystem> subDirFs, hostFs,
|
{
|
||||||
path, preserveUnc: true);
|
hostFs?.Dispose();
|
||||||
if (rc.IsFailure()) return rc;
|
subDirFs?.Dispose();
|
||||||
|
}
|
||||||
fileSystem = subDirFs;
|
|
||||||
return Result.Success;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result OpenFileSystemWithPatch(out ReferenceCountedDisposable<IFileSystem> fileSystem,
|
public Result OpenFileSystemWithPatch(out ReferenceCountedDisposable<IFileSystem> fileSystem,
|
||||||
|
@ -746,7 +780,7 @@ namespace LibHac.FsSrv
|
||||||
rc = Utility.EnsureDirectory(baseFileSystem.Target, new U8Span(contentStoragePath));
|
rc = Utility.EnsureDirectory(baseFileSystem.Target, new U8Span(contentStoragePath));
|
||||||
if (rc.IsFailure()) return rc;
|
if (rc.IsFailure()) return rc;
|
||||||
|
|
||||||
rc = _config.SubDirectoryFsCreator.Create(out subDirFileSystem, baseFileSystem,
|
rc = _config.SubDirectoryFsCreator.Create(out subDirFileSystem, ref baseFileSystem,
|
||||||
new U8Span(contentStoragePath));
|
new U8Span(contentStoragePath));
|
||||||
if (rc.IsFailure()) return rc;
|
if (rc.IsFailure()) return rc;
|
||||||
|
|
||||||
|
@ -754,8 +788,7 @@ namespace LibHac.FsSrv
|
||||||
if (contentStorageId != ContentStorageId.SdCard)
|
if (contentStorageId != ContentStorageId.SdCard)
|
||||||
{
|
{
|
||||||
// Move the shared reference to the out variable
|
// Move the shared reference to the out variable
|
||||||
fileSystem = subDirFileSystem;
|
Shared.Move(out fileSystem, ref subDirFileSystem);
|
||||||
subDirFileSystem = null;
|
|
||||||
|
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
}
|
}
|
||||||
|
@ -765,8 +798,7 @@ namespace LibHac.FsSrv
|
||||||
EncryptedFsKeyId.Content, in _encryptionSeed);
|
EncryptedFsKeyId.Content, in _encryptionSeed);
|
||||||
if (rc.IsFailure()) return rc;
|
if (rc.IsFailure()) return rc;
|
||||||
|
|
||||||
fileSystem = encryptedFileSystem;
|
Shared.Move(out fileSystem, ref encryptedFileSystem);
|
||||||
encryptedFileSystem = null;
|
|
||||||
|
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
}
|
}
|
||||||
|
|
|
@ -437,7 +437,7 @@ namespace LibHac.FsSrv
|
||||||
rc = _config.TargetManagerFsCreator.Create(out tmFs, isTargetFsCaseSensitive);
|
rc = _config.TargetManagerFsCreator.Create(out tmFs, isTargetFsCaseSensitive);
|
||||||
if (rc.IsFailure()) return rc;
|
if (rc.IsFailure()) return rc;
|
||||||
|
|
||||||
return Utility.CreateSubDirectoryFileSystem(out fileSystem, tmFs, new U8Span(path.Str), true);
|
return Utility.CreateSubDirectoryFileSystem(out fileSystem, ref tmFs, new U8Span(path.Str), true);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
@ -482,14 +482,14 @@ namespace LibHac.FsSrv
|
||||||
rc = _config.BaseFsService.OpenBisFileSystem(out tempFs, U8Span.Empty, BisPartitionId.System, true);
|
rc = _config.BaseFsService.OpenBisFileSystem(out tempFs, U8Span.Empty, BisPartitionId.System, true);
|
||||||
if (rc.IsFailure()) return rc;
|
if (rc.IsFailure()) return rc;
|
||||||
|
|
||||||
return Utility.WrapSubDirectory(out fileSystem, tempFs, basePath, createIfMissing);
|
return Utility.WrapSubDirectory(out fileSystem, ref tempFs, basePath, createIfMissing);
|
||||||
|
|
||||||
case SaveDataSpaceId.User:
|
case SaveDataSpaceId.User:
|
||||||
case SaveDataSpaceId.Temporary:
|
case SaveDataSpaceId.Temporary:
|
||||||
rc = _config.BaseFsService.OpenBisFileSystem(out tempFs, U8Span.Empty, BisPartitionId.User, true);
|
rc = _config.BaseFsService.OpenBisFileSystem(out tempFs, U8Span.Empty, BisPartitionId.User, true);
|
||||||
if (rc.IsFailure()) return rc;
|
if (rc.IsFailure()) return rc;
|
||||||
|
|
||||||
return Utility.WrapSubDirectory(out fileSystem, tempFs, basePath, createIfMissing);
|
return Utility.WrapSubDirectory(out fileSystem, ref tempFs, basePath, createIfMissing);
|
||||||
|
|
||||||
case SaveDataSpaceId.SdSystem:
|
case SaveDataSpaceId.SdSystem:
|
||||||
case SaveDataSpaceId.SdCache:
|
case SaveDataSpaceId.SdCache:
|
||||||
|
@ -503,7 +503,7 @@ namespace LibHac.FsSrv
|
||||||
.Append((byte)'/')
|
.Append((byte)'/')
|
||||||
.Append(CommonPaths.SdCardNintendoRootDirectoryName);
|
.Append(CommonPaths.SdCardNintendoRootDirectoryName);
|
||||||
|
|
||||||
rc = Utility.WrapSubDirectory(out tempSubFs, tempFs, path, createIfMissing);
|
rc = Utility.WrapSubDirectory(out tempSubFs, ref tempFs, path, createIfMissing);
|
||||||
if (rc.IsFailure()) return rc;
|
if (rc.IsFailure()) return rc;
|
||||||
|
|
||||||
return _config.EncryptedFsCreator.Create(out fileSystem, tempSubFs, EncryptedFsKeyId.Save,
|
return _config.EncryptedFsCreator.Create(out fileSystem, tempSubFs, EncryptedFsKeyId.Save,
|
||||||
|
@ -513,13 +513,13 @@ namespace LibHac.FsSrv
|
||||||
rc = _config.BaseFsService.OpenBisFileSystem(out tempFs, U8Span.Empty, BisPartitionId.SystemProperPartition, true);
|
rc = _config.BaseFsService.OpenBisFileSystem(out tempFs, U8Span.Empty, BisPartitionId.SystemProperPartition, true);
|
||||||
if (rc.IsFailure()) return rc;
|
if (rc.IsFailure()) return rc;
|
||||||
|
|
||||||
return Utility.WrapSubDirectory(out fileSystem, tempFs, basePath, createIfMissing);
|
return Utility.WrapSubDirectory(out fileSystem, ref tempFs, basePath, createIfMissing);
|
||||||
|
|
||||||
case SaveDataSpaceId.SafeMode:
|
case SaveDataSpaceId.SafeMode:
|
||||||
rc = _config.BaseFsService.OpenBisFileSystem(out tempFs, U8Span.Empty, BisPartitionId.SafeMode, true);
|
rc = _config.BaseFsService.OpenBisFileSystem(out tempFs, U8Span.Empty, BisPartitionId.SafeMode, true);
|
||||||
if (rc.IsFailure()) return rc;
|
if (rc.IsFailure()) return rc;
|
||||||
|
|
||||||
return Utility.WrapSubDirectory(out fileSystem, tempFs, basePath, createIfMissing);
|
return Utility.WrapSubDirectory(out fileSystem, ref tempFs, basePath, createIfMissing);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return ResultFs.InvalidArgument.Log();
|
return ResultFs.InvalidArgument.Log();
|
||||||
|
|
|
@ -36,9 +36,9 @@ namespace LibHac.FsSystem
|
||||||
PreserveUnc = preserveUnc;
|
PreserveUnc = preserveUnc;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SubdirectoryFileSystem(ReferenceCountedDisposable<IFileSystem> baseFileSystem, bool preserveUnc = false)
|
public SubdirectoryFileSystem(ref ReferenceCountedDisposable<IFileSystem> baseFileSystem, bool preserveUnc = false)
|
||||||
{
|
{
|
||||||
BaseFileSystemShared = baseFileSystem.AddReference();
|
BaseFileSystemShared = Shared.Move(ref baseFileSystem);
|
||||||
BaseFileSystem = BaseFileSystemShared.Target;
|
BaseFileSystem = BaseFileSystemShared.Target;
|
||||||
PreserveUnc = preserveUnc;
|
PreserveUnc = preserveUnc;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue