Add FileSystemProxyServiceObject for the FileSystemClient

Moves all the Get*ServiceObject functions to their own file.
Adds InitializeDfcFileSystemProxyServiceObject.
This commit is contained in:
Alex Barney 2021-02-06 00:29:47 -07:00
parent 58e94e99a9
commit e3c14dfa4f
27 changed files with 302 additions and 210 deletions

View file

@ -2,6 +2,7 @@
using System.Runtime.CompilerServices;
using LibHac.Common;
using LibHac.Fs.Accessors;
using LibHac.Fs.Shim;
using LibHac.FsSrv.Sf;
using LibHac.Sf;
@ -19,9 +20,9 @@ namespace LibHac.Fs
{
if (HasFileSystemServer())
{
IFileSystemProxy fsProxy = GetFileSystemProxyServiceObject();
using ReferenceCountedDisposable<IFileSystemProxy> fsProxy = this.GetFileSystemProxyServiceObject();
return fsProxy.GetGlobalAccessLogMode(out mode);
return fsProxy.Target.GetGlobalAccessLogMode(out mode);
}
mode = GlobalAccessLogMode;
@ -32,9 +33,9 @@ namespace LibHac.Fs
{
if (HasFileSystemServer())
{
IFileSystemProxy fsProxy = GetFileSystemProxyServiceObject();
using ReferenceCountedDisposable<IFileSystemProxy> fsProxy = this.GetFileSystemProxyServiceObject();
return fsProxy.SetGlobalAccessLogMode(mode);
return fsProxy.Target.SetGlobalAccessLogMode(mode);
}
GlobalAccessLogMode = mode;
@ -69,9 +70,10 @@ namespace LibHac.Fs
{
if (HasFileSystemServer())
{
IFileSystemProxy fsProxy = GetFileSystemProxyServiceObject();
using ReferenceCountedDisposable<IFileSystemProxy> fsProxy =
this.GetFileSystemProxyServiceObject();
Result rc = fsProxy.GetGlobalAccessLogMode(out GlobalAccessLogMode globalMode);
Result rc = fsProxy.Target.GetGlobalAccessLogMode(out GlobalAccessLogMode globalMode);
GlobalAccessLogMode = globalMode;
if (rc.IsFailure())
@ -187,8 +189,8 @@ namespace LibHac.Fs
{
string logString = AccessLogHelpers.BuildDefaultLogLine(result, startTime, endTime, handleId, message, caller);
IFileSystemProxy fsProxy = GetFileSystemProxyServiceObject();
fsProxy.OutputAccessLogToSdCard(new InBuffer(logString.ToU8Span())).IgnoreResult();
using ReferenceCountedDisposable<IFileSystemProxy> fsProxy = this.GetFileSystemProxyServiceObject();
fsProxy.Target.OutputAccessLogToSdCard(new InBuffer(logString.ToU8Span())).IgnoreResult();
}
}

View file

@ -5,7 +5,7 @@ using LibHac.Common;
using LibHac.Diag;
using LibHac.Fs.Accessors;
using LibHac.Fs.Fsa;
using LibHac.FsSrv.Sf;
using LibHac.Fs.Shim;
using LibHac.FsSystem;
using LibHac.Util;
using IFileSystem = LibHac.Fs.Fsa.IFileSystem;
@ -14,16 +14,9 @@ namespace LibHac.Fs
{
public partial class FileSystemClient
{
internal HorizonClient Hos { get; }
internal FileSystemClientGlobals Globals;
private IFileSystemProxy FsProxy { get; set; }
private readonly object _fspInitLocker = new object();
private IFileSystemProxyForLoader FsProxyForLoader { get; set; }
private readonly object _fsplInitLocker = new object();
private IProgramRegistry ProgramRegistry { get; set; }
private readonly object _progRegInitLocker = new object();
internal HorizonClient Hos => Globals.Hos;
internal ITimeSpanGenerator Time { get; }
private IAccessLog AccessLog { get; set; }
@ -37,96 +30,26 @@ namespace LibHac.Fs
public FileSystemClient(HorizonClient horizonClient)
{
Hos = horizonClient;
Time = horizonClient.Time;
Globals.Hos = horizonClient;
Globals.InitMutex = new object();
Assert.NotNull(Time);
}
internal struct FileSystemClientGlobals
{
public HorizonClient Hos;
public object InitMutex;
public FileSystemProxyServiceObjectGlobals FileSystemProxyServiceObject;
}
public bool HasFileSystemServer()
{
return Hos != null;
}
public IFileSystemProxy GetFileSystemProxyServiceObject()
{
if (FsProxy != null) return FsProxy;
lock (_fsplInitLocker)
{
if (FsProxy != null) return FsProxy;
if (!HasFileSystemServer())
{
throw new InvalidOperationException("Client was not initialized with a server object.");
}
Result rc = Hos.Sm.GetService(out IFileSystemProxy fsProxy, "fsp-srv");
if (rc.IsFailure())
{
throw new HorizonResultException(rc, "Failed to get file system proxy service object.");
}
fsProxy.SetCurrentProcess(Hos.Os.GetCurrentProcessId().Value).IgnoreResult();
FsProxy = fsProxy;
return FsProxy;
}
}
public IFileSystemProxyForLoader GetFileSystemProxyForLoaderServiceObject()
{
if (FsProxyForLoader != null) return FsProxyForLoader;
lock (_fspInitLocker)
{
if (FsProxyForLoader != null) return FsProxyForLoader;
if (!HasFileSystemServer())
{
throw new InvalidOperationException("Client was not initialized with a server object.");
}
Result rc = Hos.Sm.GetService(out IFileSystemProxyForLoader fsProxy, "fsp-ldr");
if (rc.IsFailure())
{
throw new HorizonResultException(rc, "Failed to get file system proxy service object.");
}
fsProxy.SetCurrentProcess(Hos.Os.GetCurrentProcessId().Value).IgnoreResult();
FsProxyForLoader = fsProxy;
return FsProxyForLoader;
}
}
public IProgramRegistry GetProgramRegistryServiceObject()
{
if (ProgramRegistry != null) return ProgramRegistry;
lock (_progRegInitLocker)
{
if (ProgramRegistry != null) return ProgramRegistry;
if (!HasFileSystemServer())
{
throw new InvalidOperationException("Client was not initialized with a server object.");
}
Result rc = Hos.Sm.GetService(out IProgramRegistry registry, "fsp-pr");
if (rc.IsFailure())
{
throw new HorizonResultException(rc, "Failed to get registry service object.");
}
ProgramRegistry = registry;
return ProgramRegistry;
}
}
public Result Register(U8Span mountName, IFileSystem fileSystem)
{
return Register(mountName, fileSystem, null);

View file

@ -41,10 +41,10 @@ namespace LibHac.Fs.Shim
FspPath.FromSpan(out FspPath sfPath, path);
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
using ReferenceCountedDisposable<IFileSystemProxy> fsProxy = fs.GetFileSystemProxyServiceObject();
rc = fsProxy.OpenFileSystemWithId(out ReferenceCountedDisposable<IFileSystemSf> fileSystem, in sfPath,
default, FileSystemProxyType.Package);
rc = fsProxy.Target.OpenFileSystemWithId(out ReferenceCountedDisposable<IFileSystemSf> fileSystem,
in sfPath, default, FileSystemProxyType.Package);
if (rc.IsFailure()) return rc;
using (fileSystem)

View file

@ -41,7 +41,7 @@ namespace LibHac.Fs.Shim
Result rc = MountHelpers.CheckMountName(mountName);
if (rc.IsFailure()) return rc;
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
using ReferenceCountedDisposable<IFileSystemProxy> fsProxy = fs.GetFileSystemProxyServiceObject();
var attribute = new SaveDataAttribute(applicationId, SaveDataType.Bcat, UserId.InvalidId, 0);
@ -49,7 +49,7 @@ namespace LibHac.Fs.Shim
try
{
rc = fsProxy.OpenSaveDataFileSystem(out saveFs, SaveDataSpaceId.User, in attribute);
rc = fsProxy.Target.OpenSaveDataFileSystem(out saveFs, SaveDataSpaceId.User, in attribute);
if (rc.IsFailure()) return rc;
var fileSystemAdapter = new FileSystemServiceObjectAdapter(saveFs);

View file

@ -89,12 +89,12 @@ namespace LibHac.Fs.Shim
Result rc = MountHelpers.CheckMountNameAcceptingReservedMountName(mountName);
if (rc.IsFailure()) return rc;
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
using ReferenceCountedDisposable<IFileSystemProxy> fsProxy = fs.GetFileSystemProxyServiceObject();
// Nintendo doesn't use the provided rootPath
FspPath.CreateEmpty(out FspPath sfPath);
rc = fsProxy.OpenBisFileSystem(out ReferenceCountedDisposable<IFileSystemSf> fileSystem, in sfPath,
rc = fsProxy.Target.OpenBisFileSystem(out ReferenceCountedDisposable<IFileSystemSf> fileSystem, in sfPath,
partitionId);
if (rc.IsFailure()) return rc;
@ -163,9 +163,9 @@ namespace LibHac.Fs.Shim
FspPath.FromSpan(out FspPath sfPath, path.Str);
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
using ReferenceCountedDisposable<IFileSystemProxy> fsProxy = fs.GetFileSystemProxyServiceObject();
return fsProxy.SetBisRootForHost(partitionId, in sfPath);
return fsProxy.Target.SetBisRootForHost(partitionId, in sfPath);
}
public static Result OpenBisPartition(this FileSystemClient fs, out IStorage partitionStorage,
@ -173,8 +173,8 @@ namespace LibHac.Fs.Shim
{
partitionStorage = default;
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
Result rc = fsProxy.OpenBisStorage(out ReferenceCountedDisposable<IStorageSf> storage, partitionId);
using ReferenceCountedDisposable<IFileSystemProxy> fsProxy = fs.GetFileSystemProxyServiceObject();
Result rc = fsProxy.Target.OpenBisStorage(out ReferenceCountedDisposable<IStorageSf> storage, partitionId);
if (rc.IsFailure()) return rc;
using (storage)
@ -188,8 +188,8 @@ namespace LibHac.Fs.Shim
public static Result InvalidateBisCache(this FileSystemClient fs)
{
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
return fsProxy.InvalidateBisCache();
using ReferenceCountedDisposable<IFileSystemProxy> fsProxy = fs.GetFileSystemProxyServiceObject();
return fsProxy.Target.InvalidateBisCache();
}
}
}

View file

@ -47,10 +47,11 @@ namespace LibHac.Fs.Shim
rc = FspPath.FromSpan(out FspPath fsPath, path);
if (rc.IsFailure()) return rc;
IFileSystemProxyForLoader fsProxy = fs.GetFileSystemProxyForLoaderServiceObject();
using ReferenceCountedDisposable<IFileSystemProxyForLoader> fsProxy =
fs.GetFileSystemProxyForLoaderServiceObject();
rc = fsProxy.OpenCodeFileSystem(out ReferenceCountedDisposable<IFileSystemSf> codeFs, out verificationData,
in fsPath, programId);
rc = fsProxy.Target.OpenCodeFileSystem(out ReferenceCountedDisposable<IFileSystemSf> codeFs,
out verificationData, in fsPath, programId);
if (rc.IsFailure()) return rc;
using (codeFs)

View file

@ -25,10 +25,10 @@ namespace LibHac.Fs.Shim
FileSystemProxyType fspType = ConvertToFileSystemProxyType(type);
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
using ReferenceCountedDisposable<IFileSystemProxy> fsProxy = fs.GetFileSystemProxyServiceObject();
rc = fsProxy.OpenFileSystemWithPatch(out ReferenceCountedDisposable<IFileSystemSf> fileSystem, programId,
fspType);
rc = fsProxy.Target.OpenFileSystemWithPatch(out ReferenceCountedDisposable<IFileSystemSf> fileSystem,
programId, fspType);
if (rc.IsFailure()) return rc;
using (fileSystem)
@ -63,10 +63,10 @@ namespace LibHac.Fs.Shim
{
FspPath.FromSpan(out FspPath fsPath, path);
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
using ReferenceCountedDisposable<IFileSystemProxy> fsProxy = fs.GetFileSystemProxyServiceObject();
Result rc = fsProxy.OpenFileSystemWithId(out ReferenceCountedDisposable<IFileSystemSf> fileSystem, in fsPath,
id, type);
Result rc = fsProxy.Target.OpenFileSystemWithId(out ReferenceCountedDisposable<IFileSystemSf> fileSystem,
in fsPath, id, type);
if (rc.IsFailure()) return rc;
using (fileSystem)

View file

@ -19,9 +19,10 @@ namespace LibHac.Fs.Shim
Result rc = MountHelpers.CheckMountNameAcceptingReservedMountName(mountName);
if (rc.IsFailure()) return rc;
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
using ReferenceCountedDisposable<IFileSystemProxy> fsProxy = fs.GetFileSystemProxyServiceObject();
rc = fsProxy.OpenContentStorageFileSystem(out ReferenceCountedDisposable<IFileSystemSf> contentFs, storageId);
rc = fsProxy.Target.OpenContentStorageFileSystem(out ReferenceCountedDisposable<IFileSystemSf> contentFs,
storageId);
if (rc.IsFailure()) return rc;
using (contentFs)

View file

@ -17,9 +17,9 @@ namespace LibHac.Fs.Shim
ReferenceCountedDisposable<IFileSystemSf> customFs = null;
try
{
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
using ReferenceCountedDisposable<IFileSystemProxy> fsProxy = fs.GetFileSystemProxyServiceObject();
rc = fsProxy.OpenCustomStorageFileSystem(out customFs, storageId);
rc = fsProxy.Target.OpenCustomStorageFileSystem(out customFs, storageId);
if (rc.IsFailure()) return rc;
var adapter = new FileSystemServiceObjectAdapter(customFs);

View file

@ -0,0 +1,149 @@
using System;
using LibHac.Common;
using LibHac.FsSrv.Sf;
namespace LibHac.Fs.Shim
{
internal struct FileSystemProxyServiceObjectGlobals
{
public nint FileSystemProxyServiceObjectInitGuard;
public ReferenceCountedDisposable<IFileSystemProxy> FileSystemProxyServiceObject;
public nint FileSystemProxyForLoaderServiceObjectInitGuard;
public ReferenceCountedDisposable<IFileSystemProxyForLoader> FileSystemProxyForLoaderServiceObject;
public nint ProgramRegistryServiceObjectInitGuard;
public ReferenceCountedDisposable<IProgramRegistry> ProgramRegistryServiceObject;
public ReferenceCountedDisposable<IFileSystemProxy> DfcFileSystemProxyServiceObject;
}
public static class FileSystemProxyServiceObject
{
private static bool HasFileSystemServer(FileSystemClient fs)
{
return fs.Hos is not null;
}
public static ReferenceCountedDisposable<IFileSystemProxy> GetFileSystemProxyServiceObject(
this FileSystemClient fs)
{
ref FileSystemProxyServiceObjectGlobals g = ref fs.Globals.FileSystemProxyServiceObject;
using var guard = new InitializationGuard(ref g.FileSystemProxyServiceObjectInitGuard,
fs.Globals.InitMutex);
if (!guard.IsInitialized)
{
g.FileSystemProxyServiceObject = GetFileSystemProxyServiceObjectImpl(fs);
}
return g.FileSystemProxyServiceObject.AddReference();
}
private static ReferenceCountedDisposable<IFileSystemProxy> GetFileSystemProxyServiceObjectImpl(
FileSystemClient fs)
{
ReferenceCountedDisposable<IFileSystemProxy> dfcServiceObject =
fs.Globals.FileSystemProxyServiceObject.DfcFileSystemProxyServiceObject;
if (dfcServiceObject is not null)
return dfcServiceObject.AddReference();
if (!HasFileSystemServer(fs))
{
throw new InvalidOperationException("Client was not initialized with a server object.");
}
Result rc = fs.Hos.Sm.GetService(out IFileSystemProxy fsProxy, "fsp-srv");
if (rc.IsFailure())
{
throw new HorizonResultException(rc, "Failed to get file system proxy service object.");
}
fsProxy.SetCurrentProcess(fs.Hos.Os.GetCurrentProcessId().Value).IgnoreResult();
return new ReferenceCountedDisposable<IFileSystemProxy>(fsProxy);
}
public static ReferenceCountedDisposable<IFileSystemProxyForLoader> GetFileSystemProxyForLoaderServiceObject(
this FileSystemClient fs)
{
ref FileSystemProxyServiceObjectGlobals g = ref fs.Globals.FileSystemProxyServiceObject;
using var guard = new InitializationGuard(ref g.FileSystemProxyForLoaderServiceObjectInitGuard,
fs.Globals.InitMutex);
if (!guard.IsInitialized)
{
g.FileSystemProxyForLoaderServiceObject = GetFileSystemProxyForLoaderServiceObjectImpl(fs);
}
return g.FileSystemProxyForLoaderServiceObject.AddReference();
}
private static ReferenceCountedDisposable<IFileSystemProxyForLoader>
GetFileSystemProxyForLoaderServiceObjectImpl(FileSystemClient fs)
{
if (!HasFileSystemServer(fs))
{
throw new InvalidOperationException("Client was not initialized with a server object.");
}
Result rc = fs.Hos.Sm.GetService(out IFileSystemProxyForLoader fsProxy, "fsp-ldr");
if (rc.IsFailure())
{
throw new HorizonResultException(rc, "Failed to get file system proxy service object.");
}
fsProxy.SetCurrentProcess(fs.Hos.Os.GetCurrentProcessId().Value).IgnoreResult();
return new ReferenceCountedDisposable<IFileSystemProxyForLoader>(fsProxy);
}
public static ReferenceCountedDisposable<IProgramRegistry> GetProgramRegistryServiceObject(
this FileSystemClient fs)
{
ref FileSystemProxyServiceObjectGlobals g = ref fs.Globals.FileSystemProxyServiceObject;
using var guard = new InitializationGuard(ref g.ProgramRegistryServiceObjectInitGuard,
fs.Globals.InitMutex);
if (!guard.IsInitialized)
{
g.ProgramRegistryServiceObject = GetProgramRegistryServiceObjectImpl(fs);
}
return g.ProgramRegistryServiceObject.AddReference();
}
private static ReferenceCountedDisposable<IProgramRegistry> GetProgramRegistryServiceObjectImpl(
FileSystemClient fs)
{
if (!HasFileSystemServer(fs))
{
throw new InvalidOperationException("Client was not initialized with a server object.");
}
Result rc = fs.Hos.Sm.GetService(out IProgramRegistry registry, "fsp-pr");
if (rc.IsFailure())
{
throw new HorizonResultException(rc, "Failed to get registry service object.");
}
registry.SetCurrentProcess(fs.Hos.Os.GetCurrentProcessId().Value).IgnoreResult();
return new ReferenceCountedDisposable<IProgramRegistry>(registry);
}
/// <summary>
/// Sets a <see cref="IFileSystemProxy"/> service object to use for direct function calls
/// instead of going over IPC. If using a DFC service object, this function should be
/// called before calling <see cref="GetFileSystemProxyServiceObject"/>.
/// </summary>
/// <param name="fs">The <see cref="FileSystemClient"/> to use.</param>
/// <param name="serviceObject">The service object this <see cref="FileSystemClient"/> will use.</param>
public static void InitializeDfcFileSystemProxyServiceObject(this FileSystemClient fs,
ReferenceCountedDisposable<IFileSystemProxy> serviceObject)
{
fs.Globals.FileSystemProxyServiceObject.DfcFileSystemProxyServiceObject = serviceObject.AddReference();
}
}
}

View file

@ -17,9 +17,9 @@ namespace LibHac.Fs.Shim
ReferenceCountedDisposable<IDeviceOperator> deviceOperator = null;
try
{
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
using ReferenceCountedDisposable<IFileSystemProxy> fsProxy = fs.GetFileSystemProxyServiceObject();
Result rc = fsProxy.OpenDeviceOperator(out deviceOperator);
Result rc = fsProxy.Target.OpenDeviceOperator(out deviceOperator);
if (rc.IsFailure()) return rc;
return deviceOperator.Target.GetGameCardHandle(out handle);
@ -35,9 +35,9 @@ namespace LibHac.Fs.Shim
ReferenceCountedDisposable<IDeviceOperator> deviceOperator = null;
try
{
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
using ReferenceCountedDisposable<IFileSystemProxy> fsProxy = fs.GetFileSystemProxyServiceObject();
Result rc = fsProxy.OpenDeviceOperator(out deviceOperator);
Result rc = fsProxy.Target.OpenDeviceOperator(out deviceOperator);
if (rc.IsFailure()) throw new LibHacException("Abort");
rc = deviceOperator.Target.IsGameCardInserted(out bool isInserted);
@ -59,9 +59,9 @@ namespace LibHac.Fs.Shim
ReferenceCountedDisposable<IStorageSf> sfStorage = null;
try
{
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
using ReferenceCountedDisposable<IFileSystemProxy> fsProxy = fs.GetFileSystemProxyServiceObject();
Result rc = fsProxy.OpenGameCardStorage(out sfStorage, handle, partitionType);
Result rc = fsProxy.Target.OpenGameCardStorage(out sfStorage, handle, partitionType);
if (rc.IsFailure()) return rc;
storage = new StorageServiceObjectAdapter(sfStorage);
@ -79,9 +79,10 @@ namespace LibHac.Fs.Shim
Result rc = MountHelpers.CheckMountNameAcceptingReservedMountName(mountName);
if (rc.IsFailure()) return rc;
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
using ReferenceCountedDisposable<IFileSystemProxy> fsProxy = fs.GetFileSystemProxyServiceObject();
rc = fsProxy.OpenGameCardFileSystem(out ReferenceCountedDisposable<IFileSystemSf> cardFs, handle, partitionId);
rc = fsProxy.Target.OpenGameCardFileSystem(out ReferenceCountedDisposable<IFileSystemSf> cardFs, handle,
partitionId);
if (rc.IsFailure()) return rc;
using (cardFs)

View file

@ -358,19 +358,19 @@ namespace LibHac.Fs.Shim
{
fileSystem = default;
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
using ReferenceCountedDisposable<IFileSystemProxy> fsProxy = fs.GetFileSystemProxyServiceObject();
ReferenceCountedDisposable<IFileSystemSf> hostFs = null;
try
{
if (option == MountHostOption.None)
{
Result rc = fsProxy.OpenHostFileSystem(out hostFs, in path);
Result rc = fsProxy.Target.OpenHostFileSystem(out hostFs, in path);
if (rc.IsFailure()) return rc;
}
else
{
Result rc = fsProxy.OpenHostFileSystemWithOption(out hostFs, in path, option);
Result rc = fsProxy.Target.OpenHostFileSystemWithOption(out hostFs, in path, option);
if (rc.IsFailure()) return rc;
}

View file

@ -7,9 +7,10 @@ namespace LibHac.Fs.Shim
{
public static Result IsArchivedProgram(this FileSystemClient fs, out bool isArchived, ProcessId processId)
{
IFileSystemProxyForLoader fsProxy = fs.GetFileSystemProxyForLoaderServiceObject();
using ReferenceCountedDisposable<IFileSystemProxyForLoader> fsProxy =
fs.GetFileSystemProxyForLoaderServiceObject();
return fsProxy.IsArchivedProgram(out isArchived, processId.Value);
return fsProxy.Target.IsArchivedProgram(out isArchived, processId.Value);
}
}
}

View file

@ -20,11 +20,11 @@ namespace LibHac.Fs.Shim
if (mapInfo.IsEmpty)
return Result.Success;
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
using ReferenceCountedDisposable<IFileSystemProxy> fsProxy = fs.GetFileSystemProxyServiceObject();
var mapInfoBuffer = new InBuffer(MemoryMarshal.Cast<ProgramIndexMapInfo, byte>(mapInfo));
return fsProxy.RegisterProgramIndexMapInfo(mapInfoBuffer, mapInfo.Length);
return fsProxy.Target.RegisterProgramIndexMapInfo(mapInfoBuffer, mapInfo.Length);
}
}
}

View file

@ -12,24 +12,24 @@ namespace LibHac.Fs.Shim
public static Result RegisterProgram(this FileSystemClient fs, ulong processId, ProgramId programId,
StorageId storageId, ReadOnlySpan<byte> accessControlData, ReadOnlySpan<byte> accessControlDescriptor)
{
IProgramRegistry registry = fs.GetProgramRegistryServiceObject();
using ReferenceCountedDisposable<IProgramRegistry> registry = fs.GetProgramRegistryServiceObject();
Result rc = registry.SetCurrentProcess(fs.Hos.ProcessId.Value);
Result rc = registry.Target.SetCurrentProcess(fs.Hos.ProcessId.Value);
if (rc.IsFailure()) return rc;
return registry.RegisterProgram(processId, programId, storageId, new InBuffer(accessControlData),
return registry.Target.RegisterProgram(processId, programId, storageId, new InBuffer(accessControlData),
new InBuffer(accessControlDescriptor));
}
/// <inheritdoc cref="ProgramRegistryImpl.UnregisterProgram"/>
public static Result UnregisterProgram(this FileSystemClient fs, ulong processId)
{
IProgramRegistry registry = fs.GetProgramRegistryServiceObject();
using ReferenceCountedDisposable<IProgramRegistry> registry = fs.GetProgramRegistryServiceObject();
Result rc = registry.SetCurrentProcess(fs.Hos.ProcessId.Value);
Result rc = registry.Target.SetCurrentProcess(fs.Hos.ProcessId.Value);
if (rc.IsFailure()) return rc;
return registry.UnregisterProgram(processId);
return registry.Target.UnregisterProgram(processId);
}
}
}

View file

@ -11,21 +11,21 @@ namespace LibHac.Fs.Shim
public static Result GetRightsId(this FileSystemClient fs, out FsRightsId rightsId, ProgramId programId,
StorageId storageId)
{
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
using ReferenceCountedDisposable<IFileSystemProxy> fsProxy = fs.GetFileSystemProxyServiceObject();
return fsProxy.GetRightsId(out rightsId, programId, storageId);
return fsProxy.Target.GetRightsId(out rightsId, programId, storageId);
}
public static Result GetRightsId(this FileSystemClient fs, out FsRightsId rightsId, U8Span path)
{
rightsId = default;
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
using ReferenceCountedDisposable<IFileSystemProxy> fsProxy = fs.GetFileSystemProxyServiceObject();
Result rc = FspPath.FromSpan(out FspPath sfPath, path);
if (rc.IsFailure()) return rc;
return fsProxy.GetRightsIdByPath(out rightsId, in sfPath);
return fsProxy.Target.GetRightsIdByPath(out rightsId, in sfPath);
}
public static Result GetRightsId(this FileSystemClient fs, out FsRightsId rightsId, out byte keyGeneration, U8Span path)
@ -33,33 +33,33 @@ namespace LibHac.Fs.Shim
rightsId = default;
keyGeneration = default;
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
using ReferenceCountedDisposable<IFileSystemProxy> fsProxy = fs.GetFileSystemProxyServiceObject();
Result rc = FspPath.FromSpan(out FspPath sfPath, path);
if (rc.IsFailure()) return rc;
return fsProxy.GetRightsIdAndKeyGenerationByPath(out rightsId, out keyGeneration, in sfPath);
return fsProxy.Target.GetRightsIdAndKeyGenerationByPath(out rightsId, out keyGeneration, in sfPath);
}
public static Result RegisterExternalKey(this FileSystemClient fs, in FsRightsId rightsId, in AccessKey key)
{
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
using ReferenceCountedDisposable<IFileSystemProxy> fsProxy = fs.GetFileSystemProxyServiceObject();
return fsProxy.RegisterExternalKey(in rightsId, in key);
return fsProxy.Target.RegisterExternalKey(in rightsId, in key);
}
public static Result UnregisterExternalKey(this FileSystemClient fs, ref FsRightsId rightsId)
{
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
using ReferenceCountedDisposable<IFileSystemProxy> fsProxy = fs.GetFileSystemProxyServiceObject();
return fsProxy.UnregisterExternalKey(in rightsId);
return fsProxy.Target.UnregisterExternalKey(in rightsId);
}
public static Result UnregisterAllExternalKey(this FileSystemClient fs)
{
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
using ReferenceCountedDisposable<IFileSystemProxy> fsProxy = fs.GetFileSystemProxyServiceObject();
return fsProxy.UnregisterAllExternalKey();
return fsProxy.Target.UnregisterAllExternalKey();
}
}
}

View file

@ -189,7 +189,7 @@ namespace LibHac.Fs.Shim
Result rc = MountHelpers.CheckMountName(mountName);
if (rc.IsFailure()) return rc;
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
using ReferenceCountedDisposable<IFileSystemProxy> fsProxy = fs.GetFileSystemProxyServiceObject();
var attribute = new SaveDataAttribute(programId, type, userId, 0, index);
@ -199,11 +199,11 @@ namespace LibHac.Fs.Shim
{
if (openReadOnly)
{
rc = fsProxy.OpenReadOnlySaveDataFileSystem(out saveFs, spaceId, in attribute);
rc = fsProxy.Target.OpenReadOnlySaveDataFileSystem(out saveFs, spaceId, in attribute);
}
else
{
rc = fsProxy.OpenSaveDataFileSystem(out saveFs, spaceId, in attribute);
rc = fsProxy.Target.OpenSaveDataFileSystem(out saveFs, spaceId, in attribute);
}
if (rc.IsFailure()) return rc;

View file

@ -15,7 +15,7 @@ namespace LibHac.Fs.Shim
return fs.RunOperationWithAccessLog(AccessLogTarget.System,
() =>
{
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
using ReferenceCountedDisposable<IFileSystemProxy> fsProxy = fs.GetFileSystemProxyServiceObject();
var attribute = new SaveDataAttribute(applicationId, SaveDataType.Account, userId, 0);
@ -35,7 +35,7 @@ namespace LibHac.Fs.Shim
Size = 0x40060
};
return fsProxy.CreateSaveDataFileSystem(in attribute, in createInfo, in metaInfo);
return fsProxy.Target.CreateSaveDataFileSystem(in attribute, in createInfo, in metaInfo);
},
() =>
$", applicationid: 0x{applicationId.Value:X}, userid: 0x{userId}, save_data_owner_id: 0x{ownerId:X}, save_data_size: {size}, save_data_journal_size: {journalSize}, save_data_flags: 0x{(int)flags:X8}");
@ -47,7 +47,7 @@ namespace LibHac.Fs.Shim
return fs.RunOperationWithAccessLog(AccessLogTarget.System,
() =>
{
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
using ReferenceCountedDisposable<IFileSystemProxy> fsProxy = fs.GetFileSystemProxyServiceObject();
var attribute = new SaveDataAttribute(applicationId, SaveDataType.Account, userId, 0);
@ -67,7 +67,7 @@ namespace LibHac.Fs.Shim
Size = 0x40060
};
return fsProxy.CreateSaveDataFileSystemWithHashSalt(in attribute, in createInfo, in metaInfo,
return fsProxy.Target.CreateSaveDataFileSystemWithHashSalt(in attribute, in createInfo, in metaInfo,
in hashSalt);
},
() =>
@ -79,7 +79,7 @@ namespace LibHac.Fs.Shim
return fs.RunOperationWithAccessLog(AccessLogTarget.System,
() =>
{
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
using ReferenceCountedDisposable<IFileSystemProxy> fsProxy = fs.GetFileSystemProxyServiceObject();
var attribute = new SaveDataAttribute(applicationId, SaveDataType.Bcat, UserId.InvalidId, 0);
@ -95,7 +95,7 @@ namespace LibHac.Fs.Shim
var metaInfo = new SaveDataMetaInfo();
return fsProxy.CreateSaveDataFileSystem(in attribute, in createInfo, in metaInfo);
return fsProxy.Target.CreateSaveDataFileSystem(in attribute, in createInfo, in metaInfo);
},
() => $", applicationid: 0x{applicationId.Value:X}, save_data_size: {size}");
}
@ -106,7 +106,7 @@ namespace LibHac.Fs.Shim
return fs.RunOperationWithAccessLog(AccessLogTarget.System,
() =>
{
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
using ReferenceCountedDisposable<IFileSystemProxy> fsProxy = fs.GetFileSystemProxyServiceObject();
var attribute = new SaveDataAttribute(applicationId, SaveDataType.Device, UserId.InvalidId, 0);
@ -122,7 +122,7 @@ namespace LibHac.Fs.Shim
var metaInfo = new SaveDataMetaInfo();
return fsProxy.CreateSaveDataFileSystem(in attribute, in createInfo, in metaInfo);
return fsProxy.Target.CreateSaveDataFileSystem(in attribute, in createInfo, in metaInfo);
},
() => $", applicationid: 0x{applicationId.Value:X}, save_data_owner_id: 0x{ownerId:X}, save_data_size: {size}, save_data_journal_size: {journalSize}, save_data_flags: 0x{(int)flags:X8}");
}
@ -132,7 +132,7 @@ namespace LibHac.Fs.Shim
return fs.RunOperationWithAccessLog(AccessLogTarget.System,
() =>
{
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
using ReferenceCountedDisposable<IFileSystemProxy> fsProxy = fs.GetFileSystemProxyServiceObject();
var attribute = new SaveDataAttribute(applicationId, SaveDataType.Temporary, UserId.InvalidId, 0);
@ -147,7 +147,7 @@ namespace LibHac.Fs.Shim
var metaInfo = new SaveDataMetaInfo();
return fsProxy.CreateSaveDataFileSystem(in attribute, in createInfo, in metaInfo);
return fsProxy.Target.CreateSaveDataFileSystem(in attribute, in createInfo, in metaInfo);
},
() => $", applicationid: 0x{applicationId.Value:X}, save_data_owner_id: 0x{ownerId:X}, save_data_size: {size}, save_data_flags: 0x{(int)flags:X8}");
}
@ -158,7 +158,7 @@ namespace LibHac.Fs.Shim
return fs.RunOperationWithAccessLog(AccessLogTarget.System,
() =>
{
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
using ReferenceCountedDisposable<IFileSystemProxy> fsProxy = fs.GetFileSystemProxyServiceObject();
var attribute = new SaveDataAttribute(applicationId, SaveDataType.Cache, UserId.InvalidId, 0, index);
@ -174,7 +174,7 @@ namespace LibHac.Fs.Shim
var metaInfo = new SaveDataMetaInfo();
return fsProxy.CreateSaveDataFileSystem(in attribute, in creationInfo, in metaInfo);
return fsProxy.Target.CreateSaveDataFileSystem(in attribute, in creationInfo, in metaInfo);
},
() => $", applicationid: 0x{applicationId.Value:X}, savedataspaceid: {spaceId}, save_data_owner_id: 0x{ownerId:X}, save_data_size: {size}, save_data_journal_size: {journalSize}, save_data_flags: 0x{(int)flags:X8}");
}
@ -197,7 +197,7 @@ namespace LibHac.Fs.Shim
return fs.RunOperationWithAccessLog(AccessLogTarget.System,
() =>
{
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
using ReferenceCountedDisposable<IFileSystemProxy> fsProxy = fs.GetFileSystemProxyServiceObject();
var attribute = new SaveDataAttribute(ProgramId.InvalidId, SaveDataType.System, userId, saveDataId);
@ -211,7 +211,7 @@ namespace LibHac.Fs.Shim
SpaceId = spaceId
};
return fsProxy.CreateSaveDataFileSystemBySystemSaveDataId(in attribute, in createInfo);
return fsProxy.Target.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}");
}
@ -251,8 +251,8 @@ namespace LibHac.Fs.Shim
return fs.RunOperationWithAccessLog(AccessLogTarget.System,
() =>
{
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
return fsProxy.DeleteSaveDataFileSystem(saveDataId);
using ReferenceCountedDisposable<IFileSystemProxy> fsProxy = fs.GetFileSystemProxyServiceObject();
return fsProxy.Target.DeleteSaveDataFileSystem(saveDataId);
},
() => $", savedataid: 0x{saveDataId:X}");
}
@ -262,8 +262,8 @@ namespace LibHac.Fs.Shim
return fs.RunOperationWithAccessLog(AccessLogTarget.System,
() =>
{
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
return fsProxy.DeleteSaveDataFileSystemBySaveDataSpaceId(spaceId, saveDataId);
using ReferenceCountedDisposable<IFileSystemProxy> fsProxy = fs.GetFileSystemProxyServiceObject();
return fsProxy.Target.DeleteSaveDataFileSystemBySaveDataSpaceId(spaceId, saveDataId);
},
() => $", savedataspaceid: {spaceId}, savedataid: 0x{saveDataId:X}");
}
@ -279,12 +279,12 @@ namespace LibHac.Fs.Shim
Result result = fs.RunOperationWithAccessLog(AccessLogTarget.System,
() =>
{
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
using ReferenceCountedDisposable<IFileSystemProxy> fsProxy = fs.GetFileSystemProxyServiceObject();
tempInfo = new SaveDataInfo();
Result rc = fsProxy.FindSaveDataWithFilter(out long count, OutBuffer.FromStruct(ref tempInfo),
spaceId, in tempFilter);
Result rc = fsProxy.Target.FindSaveDataWithFilter(out long count,
OutBuffer.FromStruct(ref tempInfo), spaceId, in tempFilter);
if (rc.IsFailure()) return rc;
if (count == 0)
@ -311,9 +311,9 @@ namespace LibHac.Fs.Shim
Result result = fs.RunOperationWithAccessLog(AccessLogTarget.System,
() =>
{
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
using ReferenceCountedDisposable<IFileSystemProxy> fsProxy = fs.GetFileSystemProxyServiceObject();
return fsProxy.QuerySaveDataTotalSize(out totalSizeTemp, size, journalSize);
return fsProxy.Target.QuerySaveDataTotalSize(out totalSizeTemp, size, journalSize);
},
() => $", save_data_size: {size}, save_data_journal_size: {journalSize}");
@ -334,9 +334,9 @@ namespace LibHac.Fs.Shim
Result result = fs.RunOperationWithAccessLog(AccessLogTarget.System,
() =>
{
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
using ReferenceCountedDisposable<IFileSystemProxy> fsProxy = fs.GetFileSystemProxyServiceObject();
Result rc = fsProxy.OpenSaveDataInfoReaderBySaveDataSpaceId(
Result rc = fsProxy.Target.OpenSaveDataInfoReaderBySaveDataSpaceId(
out ReferenceCountedDisposable<ISaveDataInfoReader> reader, spaceId);
if (rc.IsFailure()) return rc;
@ -368,9 +368,9 @@ namespace LibHac.Fs.Shim
Result result = fs.RunOperationWithAccessLog(AccessLogTarget.System,
() =>
{
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
using ReferenceCountedDisposable<IFileSystemProxy> fsProxy = fs.GetFileSystemProxyServiceObject();
Result rc = fsProxy.OpenSaveDataInfoReaderWithFilter(out reader, spaceId, in tempFilter);
Result rc = fsProxy.Target.OpenSaveDataInfoReaderWithFilter(out reader, spaceId, in tempFilter);
if (rc.IsFailure()) return rc;
tempIterator = new SaveDataIterator(fs, reader);
@ -391,9 +391,9 @@ namespace LibHac.Fs.Shim
public static void DisableAutoSaveDataCreation(this FileSystemClient fsClient)
{
IFileSystemProxy fsProxy = fsClient.GetFileSystemProxyServiceObject();
using ReferenceCountedDisposable<IFileSystemProxy> fsProxy = fsClient.GetFileSystemProxyServiceObject();
Result rc = fsProxy.DisableAutoSaveDataCreation();
Result rc = fsProxy.Target.DisableAutoSaveDataCreation();
if (rc.IsFailure())
{

View file

@ -39,9 +39,9 @@ namespace LibHac.Fs.Shim
Result rc = MountHelpers.CheckMountName(mountName);
if (rc.IsFailure()) return rc;
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
using ReferenceCountedDisposable<IFileSystemProxy> fsProxy = fs.GetFileSystemProxyServiceObject();
rc = fsProxy.OpenSdCardFileSystem(out ReferenceCountedDisposable<IFileSystemSf> fileSystem);
rc = fsProxy.Target.OpenSdCardFileSystem(out ReferenceCountedDisposable<IFileSystemSf> fileSystem);
if (rc.IsFailure()) return rc;
using (fileSystem)
@ -58,9 +58,9 @@ namespace LibHac.Fs.Shim
ReferenceCountedDisposable<IDeviceOperator> deviceOperator = null;
try
{
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
using ReferenceCountedDisposable<IFileSystemProxy> fsProxy = fs.GetFileSystemProxyServiceObject();
Result rc = fsProxy.OpenDeviceOperator(out deviceOperator);
Result rc = fsProxy.Target.OpenDeviceOperator(out deviceOperator);
if (rc.IsFailure()) throw new HorizonResultException(rc, "Abort");
rc = deviceOperator.Target.IsSdCardInserted(out bool isInserted);
@ -76,9 +76,9 @@ namespace LibHac.Fs.Shim
public static Result SetSdCardEncryptionSeed(this FileSystemClient fs, in EncryptionSeed seed)
{
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
using ReferenceCountedDisposable<IFileSystemProxy> fsProxy = fs.GetFileSystemProxyServiceObject();
Result rc = fsProxy.SetSdCardEncryptionSeed(in seed);
Result rc = fsProxy.Target.SetSdCardEncryptionSeed(in seed);
if (rc.IsFailure()) throw new HorizonResultException(rc, "Abort");
return Result.Success;
@ -86,17 +86,17 @@ namespace LibHac.Fs.Shim
public static void SetSdCardAccessibility(this FileSystemClient fs, bool isAccessible)
{
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
using ReferenceCountedDisposable<IFileSystemProxy> fsProxy = fs.GetFileSystemProxyServiceObject();
Result rc = fsProxy.SetSdCardAccessibility(isAccessible);
Result rc = fsProxy.Target.SetSdCardAccessibility(isAccessible);
if (rc.IsFailure()) throw new HorizonResultException(rc, "Abort");
}
public static bool IsSdCardAccessible(this FileSystemClient fs)
{
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
using ReferenceCountedDisposable<IFileSystemProxy> fsProxy = fs.GetFileSystemProxyServiceObject();
Result rc = fsProxy.IsSdCardAccessible(out bool isAccessible);
Result rc = fsProxy.Target.IsSdCardAccessible(out bool isAccessible);
if (rc.IsFailure()) throw new HorizonResultException(rc, "Abort");
return isAccessible;

View file

@ -20,7 +20,7 @@ namespace LibHac.Fs.Shim
Result rc = MountHelpers.CheckMountName(mountName);
if (rc.IsFailure()) return rc;
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
using ReferenceCountedDisposable<IFileSystemProxy> fsProxy = fs.GetFileSystemProxyServiceObject();
var attribute = new SaveDataAttribute(ProgramId.InvalidId, SaveDataType.System, userId, saveDataId);
@ -28,7 +28,7 @@ namespace LibHac.Fs.Shim
try
{
rc = fsProxy.OpenSaveDataFileSystemBySystemSaveDataId(out saveFs, spaceId, in attribute);
rc = fsProxy.Target.OpenSaveDataFileSystemBySystemSaveDataId(out saveFs, spaceId, in attribute);
if (rc.IsFailure()) return rc;
var fileSystemAdapter = new FileSystemServiceObjectAdapter(saveFs);

View file

@ -22,7 +22,9 @@ namespace LibHac.Fs.Shim
ReferenceCountedDisposable<IFileSystemSf> fileSystem = null;
try
{
Result rc = fs.GetFileSystemProxyServiceObject().OpenMultiCommitManager(out commitManager);
using ReferenceCountedDisposable<IFileSystemProxy> fsProxy = fs.GetFileSystemProxyServiceObject();
Result rc = fsProxy.Target.OpenMultiCommitManager(out commitManager);
if (rc.IsFailure()) return rc;
for (int i = 0; i < mountNames.Length; i++)

View file

@ -69,6 +69,12 @@ namespace LibHac.FsSrv
CurrentProcess = ulong.MaxValue;
}
public void Dispose()
{
NcaFsService?.Dispose();
SaveFsService?.Dispose();
}
private Result GetProgramInfo(out ProgramInfo programInfo)
{
var registry = new ProgramRegistryImpl(FsServer);

View file

@ -41,6 +41,8 @@ namespace LibHac.FsSrv
_processId = ulong.MaxValue;
}
public void Dispose() { }
/// <returns><see cref="Result.Success"/>: The operation was successful.<br/>
/// <see cref="ResultFs.InvalidArgument"/>: The process ID is already registered.<br/>
/// <see cref="ResultFs.PermissionDenied"/>: Insufficient permissions.</returns>

View file

@ -1,4 +1,5 @@
using LibHac.Fs;
using System;
using LibHac.Fs;
using LibHac.Ncm;
using LibHac.Sf;
using LibHac.Spl;
@ -8,7 +9,7 @@ using IStorageSf = LibHac.FsSrv.Sf.IStorage;
namespace LibHac.FsSrv.Sf
{
public interface IFileSystemProxy
public interface IFileSystemProxy : IDisposable
{
Result SetCurrentProcess(ulong processId);
Result OpenDataFileSystemByCurrentProcess(out ReferenceCountedDisposable<IFileSystemSf> fileSystem);

View file

@ -1,10 +1,11 @@
using LibHac.Fs;
using System;
using LibHac.Fs;
using LibHac.Ncm;
using IFileSystemSf = LibHac.FsSrv.Sf.IFileSystem;
namespace LibHac.FsSrv.Sf
{
public interface IFileSystemProxyForLoader
public interface IFileSystemProxyForLoader : IDisposable
{
Result OpenCodeFileSystem(out ReferenceCountedDisposable<IFileSystemSf> fileSystem,
out CodeVerificationData verificationData, in FspPath path, ProgramId programId);

View file

@ -1,9 +1,10 @@
using LibHac.Ncm;
using System;
using LibHac.Ncm;
using LibHac.Sf;
namespace LibHac.FsSrv.Sf
{
public interface IProgramRegistry
public interface IProgramRegistry : IDisposable
{
Result RegisterProgram(ulong processId, ProgramId programId, StorageId storageId,
InBuffer accessControlData, InBuffer accessControlDescriptor);

View file

@ -40,8 +40,9 @@ namespace LibHac.Tests.FsSrv
for (int i = 0; i < programs.Length; i++)
{
Assert.Success(programs[i].Fs.GetFileSystemProxyServiceObject()
.GetProgramIndexForAccessLog(out int programIndex, out int programCount));
using ReferenceCountedDisposable<LibHac.FsSrv.Sf.IFileSystemProxy> fsProxy =
programs[i].Fs.GetFileSystemProxyServiceObject();
Assert.Success(fsProxy.Target.GetProgramIndexForAccessLog(out int programIndex, out int programCount));
Assert.Equal(i, programIndex);
Assert.Equal(count, programCount);