mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2024-11-14 10:49:41 +01:00
Update lr client and LocationResolverSet
This commit is contained in:
parent
6db134cae4
commit
9a97e5ef3e
6 changed files with 286 additions and 172 deletions
|
@ -5,14 +5,44 @@ using LibHac.Fs;
|
|||
using LibHac.Lr;
|
||||
using LibHac.Ncm;
|
||||
using LibHac.Os;
|
||||
using Path = LibHac.Lr.Path;
|
||||
|
||||
namespace LibHac.FsSrv.Impl
|
||||
{
|
||||
public static class LocationResolverSetGlobalMethods
|
||||
{
|
||||
public static void InitializeLocationResolverSet(this FileSystemServer fsSrv)
|
||||
{
|
||||
ref LocationResolverSetGlobals globals = ref fsSrv.Globals.LocationResolverSet;
|
||||
using ScopedLock<SdkMutexType> scopedLock = ScopedLock.Lock(ref globals.Mutex);
|
||||
|
||||
if (!globals.IsLrInitialized)
|
||||
{
|
||||
fsSrv.Hos.Lr.Initialize();
|
||||
globals.IsLrInitialized = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal struct LocationResolverSetGlobals
|
||||
{
|
||||
public SdkMutexType Mutex;
|
||||
public bool IsLrInitialized;
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
Mutex.Initialize();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Manages resolving the location of NCAs via the <c>lr</c> service.
|
||||
/// </summary>
|
||||
/// <remarks>Based on FS 12.0.3 (nnSdk 12.3.1)</remarks>
|
||||
internal class LocationResolverSet : IDisposable
|
||||
{
|
||||
private const int LocationResolverCount = 5;
|
||||
|
||||
// Todo: Use Optional<T>
|
||||
private LocationResolver[] _resolvers;
|
||||
private AddOnContentLocationResolver _aocResolver;
|
||||
private SdkMutexType _mutex;
|
||||
|
@ -27,16 +57,49 @@ namespace LibHac.FsSrv.Impl
|
|||
_fsServer = fsServer;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
foreach (LocationResolver resolver in _resolvers)
|
||||
{
|
||||
resolver?.Dispose();
|
||||
}
|
||||
|
||||
_aocResolver?.Dispose();
|
||||
}
|
||||
|
||||
private static Result SetUpFsPath(ref Fs.Path outPath, in Lr.Path lrPath)
|
||||
{
|
||||
var pathFlags = new PathFlags();
|
||||
pathFlags.AllowMountName();
|
||||
|
||||
if (Utility.IsHostFsMountName(lrPath.Str))
|
||||
pathFlags.AllowWindowsPath();
|
||||
|
||||
Result rc = outPath.InitializeWithReplaceUnc(lrPath.Str);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
rc = outPath.Normalize(pathFlags);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
private Result GetLocationResolver(out LocationResolver resolver, StorageId storageId)
|
||||
{
|
||||
UnsafeHelpers.SkipParamInit(out resolver);
|
||||
|
||||
_fsServer.InitializeLocationResolverSet();
|
||||
|
||||
if (!IsValidStorageId(storageId))
|
||||
return ResultLr.LocationResolverNotFound.Log();
|
||||
|
||||
using ScopedLock<SdkMutexType> lk = ScopedLock.Lock(ref _mutex);
|
||||
|
||||
int index = GetResolverIndexFromStorageId(storageId);
|
||||
|
||||
if (index < 0)
|
||||
return ResultLr.LocationResolverNotFound.Log();
|
||||
|
||||
ref LocationResolver lr = ref _resolvers[index];
|
||||
|
||||
// Open the location resolver if it hasn't been already
|
||||
|
@ -64,6 +127,8 @@ namespace LibHac.FsSrv.Impl
|
|||
|
||||
private Result GetAddOnContentLocationResolver(out AddOnContentLocationResolver resolver)
|
||||
{
|
||||
_fsServer.InitializeLocationResolverSet();
|
||||
|
||||
using ScopedLock<SdkMutexType> lk = ScopedLock.Lock(ref _mutex);
|
||||
|
||||
if (_aocResolver is null)
|
||||
|
@ -82,108 +147,126 @@ namespace LibHac.FsSrv.Impl
|
|||
return Result.Success;
|
||||
}
|
||||
|
||||
public Result ResolveApplicationControlPath(out Path path, Ncm.ApplicationId applicationId, StorageId storageId)
|
||||
public Result ResolveApplicationControlPath(ref Fs.Path outPath, Ncm.ApplicationId applicationId, StorageId storageId)
|
||||
{
|
||||
Path.InitEmpty(out path);
|
||||
Result rc = GetLocationResolver(out LocationResolver resolver, storageId);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
rc = resolver.ResolveApplicationControlPath(out Lr.Path path, applicationId);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
return SetUpFsPath(ref outPath, in path);
|
||||
}
|
||||
|
||||
public Result ResolveApplicationHtmlDocumentPath(out bool isDirectory, ref Fs.Path outPath, Ncm.ApplicationId applicationId, StorageId storageId)
|
||||
{
|
||||
UnsafeHelpers.SkipParamInit(out isDirectory);
|
||||
|
||||
Result rc = GetLocationResolver(out LocationResolver resolver, storageId);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
rc = resolver.ResolveApplicationControlPath(out path, applicationId);
|
||||
rc = resolver.ResolveApplicationHtmlDocumentPath(out Lr.Path path, applicationId);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
PathUtility.Replace(path.StrMutable, (byte)'\\', (byte)'/');
|
||||
return Result.Success;
|
||||
isDirectory = PathUtility12.IsDirectoryPath(path.Str);
|
||||
|
||||
return SetUpFsPath(ref outPath, in path);
|
||||
}
|
||||
|
||||
public Result ResolveApplicationHtmlDocumentPath(out Path path, Ncm.ApplicationId applicationId, StorageId storageId)
|
||||
public Result ResolveProgramPath(out bool isDirectory, ref Fs.Path outPath, ProgramId programId, StorageId storageId)
|
||||
{
|
||||
Path.InitEmpty(out path);
|
||||
UnsafeHelpers.SkipParamInit(out isDirectory);
|
||||
|
||||
Result rc = GetLocationResolver(out LocationResolver resolver, storageId);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
rc = resolver.ResolveApplicationHtmlDocumentPath(out path, applicationId);
|
||||
rc = resolver.ResolveProgramPath(out Lr.Path path, programId);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
PathUtility.Replace(path.StrMutable, (byte)'\\', (byte)'/');
|
||||
return Result.Success;
|
||||
isDirectory = PathUtility12.IsDirectoryPath(path.Str);
|
||||
|
||||
return SetUpFsPath(ref outPath, in path);
|
||||
}
|
||||
|
||||
public virtual Result ResolveProgramPath(out Path path, ulong id, StorageId storageId)
|
||||
public Result ResolveRomPath(out bool isDirectory, ref Fs.Path outPath, ProgramId programId, StorageId storageId)
|
||||
{
|
||||
Path.InitEmpty(out path);
|
||||
UnsafeHelpers.SkipParamInit(out isDirectory);
|
||||
|
||||
Result rc = GetLocationResolver(out LocationResolver resolver, storageId);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
rc = resolver.ResolveProgramPath(out path, new ProgramId(id));
|
||||
rc = resolver.ResolveProgramPathForDebug(out Lr.Path path, programId);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
PathUtility.Replace(path.StrMutable, (byte)'\\', (byte)'/');
|
||||
return Result.Success;
|
||||
isDirectory = PathUtility12.IsDirectoryPath(path.Str);
|
||||
|
||||
return SetUpFsPath(ref outPath, in path);
|
||||
}
|
||||
|
||||
public Result ResolveRomPath(out Path path, ulong id, StorageId storageId)
|
||||
public Result ResolveAddOnContentPath(ref Fs.Path outPath, DataId dataId)
|
||||
{
|
||||
Path.InitEmpty(out path);
|
||||
|
||||
Result rc = GetLocationResolver(out LocationResolver resolver, storageId);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
rc = resolver.ResolveProgramPath(out path, new ProgramId(id));
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
PathUtility.Replace(path.StrMutable, (byte)'\\', (byte)'/');
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public Result ResolveAddOnContentPath(out Path path, DataId dataId)
|
||||
{
|
||||
Path.InitEmpty(out path);
|
||||
|
||||
Result rc = GetAddOnContentLocationResolver(out AddOnContentLocationResolver resolver);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
return resolver.ResolveAddOnContentPath(out path, dataId);
|
||||
rc = resolver.ResolveAddOnContentPath(out Lr.Path path, dataId);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
return SetUpFsPath(ref outPath, in path);
|
||||
}
|
||||
|
||||
public Result ResolveDataPath(out Path path, DataId dataId, StorageId storageId)
|
||||
public Result ResolveDataPath(ref Fs.Path outPath, DataId dataId, StorageId storageId)
|
||||
{
|
||||
Path.InitEmpty(out path);
|
||||
|
||||
if (storageId == StorageId.None)
|
||||
return ResultFs.InvalidAlignment.Log();
|
||||
|
||||
Result rc = GetLocationResolver(out LocationResolver resolver, storageId);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
return resolver.ResolveDataPath(out path, dataId);
|
||||
}
|
||||
|
||||
public Result ResolveRegisteredProgramPath(out Path path, ulong id)
|
||||
{
|
||||
Path.InitEmpty(out path);
|
||||
|
||||
Result rc = GetRegisteredLocationResolver(out RegisteredLocationResolver resolver);
|
||||
rc = resolver.ResolveDataPath(out Lr.Path path, dataId);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
using (resolver)
|
||||
return SetUpFsPath(ref outPath, in path);
|
||||
}
|
||||
|
||||
public Result ResolveRegisteredProgramPath(ref Fs.Path outPath, ulong id)
|
||||
{
|
||||
_fsServer.InitializeLocationResolverSet();
|
||||
|
||||
RegisteredLocationResolver resolver = null;
|
||||
try
|
||||
{
|
||||
return resolver.ResolveProgramPath(out path, new ProgramId(id));
|
||||
Result rc = GetRegisteredLocationResolver(out resolver);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
rc = resolver.ResolveProgramPath(out Lr.Path path, new ProgramId(id));
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
return SetUpFsPath(ref outPath, in path);
|
||||
}
|
||||
finally
|
||||
{
|
||||
resolver?.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public Result ResolveRegisteredHtmlDocumentPath(out Path path, ulong id)
|
||||
public Result ResolveRegisteredHtmlDocumentPath(ref Fs.Path outPath, ulong id)
|
||||
{
|
||||
Path.InitEmpty(out path);
|
||||
_fsServer.InitializeLocationResolverSet();
|
||||
|
||||
Result rc = GetRegisteredLocationResolver(out RegisteredLocationResolver resolver);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
using (resolver)
|
||||
RegisteredLocationResolver resolver = null;
|
||||
try
|
||||
{
|
||||
return resolver.ResolveHtmlDocumentPath(out path, new ProgramId(id));
|
||||
Result rc = GetRegisteredLocationResolver(out resolver);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
rc = resolver.ResolveHtmlDocumentPath(out Lr.Path path, new ProgramId(id));
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
return SetUpFsPath(ref outPath, in path);
|
||||
}
|
||||
finally
|
||||
{
|
||||
resolver?.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -210,15 +293,5 @@ namespace LibHac.FsSrv.Impl
|
|||
_ => -1
|
||||
};
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
foreach (LocationResolver resolver in _resolvers)
|
||||
{
|
||||
resolver?.Dispose();
|
||||
}
|
||||
|
||||
_aocResolver?.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using LibHac.Common;
|
||||
using LibHac.Ncm;
|
||||
using LibHac.Sf;
|
||||
|
||||
|
@ -8,9 +9,14 @@ namespace LibHac.Lr
|
|||
{
|
||||
private ReferenceCountedDisposable<IAddOnContentLocationResolver> _interface;
|
||||
|
||||
public AddOnContentLocationResolver(ReferenceCountedDisposable<IAddOnContentLocationResolver> baseInterface)
|
||||
public AddOnContentLocationResolver(ref ReferenceCountedDisposable<IAddOnContentLocationResolver> baseInterface)
|
||||
{
|
||||
_interface = baseInterface.AddReference();
|
||||
_interface = Shared.Move(ref baseInterface);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_interface?.Dispose();
|
||||
}
|
||||
|
||||
public Result ResolveAddOnContentPath(out Path path, DataId id) =>
|
||||
|
@ -27,10 +33,5 @@ namespace LibHac.Lr
|
|||
|
||||
public Result UnregisterApplicationAddOnContent(Ncm.ApplicationId id) =>
|
||||
_interface.Target.UnregisterApplicationAddOnContent(id);
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_interface?.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using LibHac.Common;
|
||||
using LibHac.Ncm;
|
||||
using LibHac.Sf;
|
||||
|
||||
|
@ -8,9 +9,14 @@ namespace LibHac.Lr
|
|||
{
|
||||
private ReferenceCountedDisposable<ILocationResolver> _interface;
|
||||
|
||||
public LocationResolver(ReferenceCountedDisposable<ILocationResolver> baseInterface)
|
||||
public LocationResolver(ref ReferenceCountedDisposable<ILocationResolver> baseInterface)
|
||||
{
|
||||
_interface = baseInterface.AddReference();
|
||||
_interface = Shared.Move(ref baseInterface);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_interface?.Dispose();
|
||||
}
|
||||
|
||||
public Result ResolveProgramPath(out Path path, ProgramId id) =>
|
||||
|
@ -72,10 +78,5 @@ namespace LibHac.Lr
|
|||
|
||||
public Result EraseProgramRedirectionForDebug(ProgramId id) =>
|
||||
_interface.Target.EraseProgramRedirectionForDebug(id);
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_interface?.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,103 +1,37 @@
|
|||
using System;
|
||||
using LibHac.Common;
|
||||
using LibHac.Ncm;
|
||||
|
||||
namespace LibHac.Lr
|
||||
{
|
||||
public class LrClient : IDisposable
|
||||
{
|
||||
private HorizonClient Hos { get; }
|
||||
|
||||
private ILocationResolverManager LrManager { get; set; }
|
||||
private readonly object _lrInitLocker = new object();
|
||||
internal LrClientGlobals Globals;
|
||||
internal HorizonClient Hos => Globals.Hos;
|
||||
|
||||
public LrClient(HorizonClient horizonClient)
|
||||
{
|
||||
Hos = horizonClient;
|
||||
}
|
||||
|
||||
public Result OpenLocationResolver(out LocationResolver resolver, StorageId storageId)
|
||||
{
|
||||
UnsafeHelpers.SkipParamInit(out resolver);
|
||||
EnsureInitialized();
|
||||
|
||||
Result rc = LrManager.OpenLocationResolver(out ReferenceCountedDisposable<ILocationResolver> baseResolver,
|
||||
storageId);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
using (baseResolver)
|
||||
{
|
||||
resolver = new LocationResolver(baseResolver);
|
||||
return Result.Success;
|
||||
}
|
||||
}
|
||||
|
||||
public Result OpenRegisteredLocationResolver(out RegisteredLocationResolver resolver)
|
||||
{
|
||||
UnsafeHelpers.SkipParamInit(out resolver);
|
||||
EnsureInitialized();
|
||||
|
||||
Result rc = LrManager.OpenRegisteredLocationResolver(
|
||||
out ReferenceCountedDisposable<IRegisteredLocationResolver> baseResolver);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
using (baseResolver)
|
||||
{
|
||||
resolver = new RegisteredLocationResolver(baseResolver);
|
||||
return Result.Success;
|
||||
}
|
||||
}
|
||||
|
||||
public Result OpenAddOnContentLocationResolver(out AddOnContentLocationResolver resolver)
|
||||
{
|
||||
UnsafeHelpers.SkipParamInit(out resolver);
|
||||
EnsureInitialized();
|
||||
|
||||
Result rc = LrManager.OpenAddOnContentLocationResolver(
|
||||
out ReferenceCountedDisposable<IAddOnContentLocationResolver> baseResolver);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
using (baseResolver)
|
||||
{
|
||||
resolver = new AddOnContentLocationResolver(baseResolver);
|
||||
return Result.Success;
|
||||
}
|
||||
}
|
||||
|
||||
public Result RefreshLocationResolver(StorageId storageId)
|
||||
{
|
||||
EnsureInitialized();
|
||||
|
||||
Result rc = LrManager.RefreshLocationResolver(storageId);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
private void EnsureInitialized()
|
||||
{
|
||||
if (LrManager != null)
|
||||
return;
|
||||
|
||||
lock (_lrInitLocker)
|
||||
{
|
||||
if (LrManager != null)
|
||||
return;
|
||||
|
||||
Result rc = Hos.Sm.GetService(out ILocationResolverManager manager, "lr");
|
||||
|
||||
if (rc.IsFailure())
|
||||
{
|
||||
throw new HorizonResultException(rc, "Failed to initialize lr client.");
|
||||
}
|
||||
|
||||
LrManager = manager;
|
||||
}
|
||||
Globals.Initialize(this, horizonClient);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
LrManager?.Dispose();
|
||||
Globals.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
internal struct LrClientGlobals
|
||||
{
|
||||
public HorizonClient Hos;
|
||||
public LrServiceGlobals LrService;
|
||||
|
||||
public void Initialize(LrClient lrClient, HorizonClient horizonClient)
|
||||
{
|
||||
Hos = horizonClient;
|
||||
LrService.Initialize();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
LrService.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
104
src/LibHac/Lr/LrService.cs
Normal file
104
src/LibHac/Lr/LrService.cs
Normal file
|
@ -0,0 +1,104 @@
|
|||
using LibHac.Common;
|
||||
using LibHac.Diag;
|
||||
using LibHac.Ncm;
|
||||
using LibHac.Os;
|
||||
|
||||
namespace LibHac.Lr
|
||||
{
|
||||
internal struct LrServiceGlobals
|
||||
{
|
||||
public ILocationResolverManager LocationResolver;
|
||||
public SdkMutex InitializationMutex;
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
LocationResolver = null;
|
||||
InitializationMutex.Initialize();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (LocationResolver is not null)
|
||||
{
|
||||
LocationResolver.Dispose();
|
||||
LocationResolver = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class LrService
|
||||
{
|
||||
public static void Initialize(this LrClient lr)
|
||||
{
|
||||
ref LrServiceGlobals globals = ref lr.Globals.LrService;
|
||||
Assert.SdkRequiresNotNull(globals.LocationResolver);
|
||||
|
||||
// The lock over getting the service object is a LibHac addition.
|
||||
using ScopedLock<SdkMutex> scopedLock = ScopedLock.Lock(ref lr.Globals.LrService.InitializationMutex);
|
||||
|
||||
if (globals.LocationResolver is not null)
|
||||
return;
|
||||
|
||||
ILocationResolverManager serviceObject = lr.GetLocationResolverManagerServiceObject();
|
||||
globals.LocationResolver = serviceObject;
|
||||
}
|
||||
|
||||
public static Result OpenLocationResolver(this LrClient lr, out LocationResolver resolver, StorageId storageId)
|
||||
{
|
||||
UnsafeHelpers.SkipParamInit(out resolver);
|
||||
|
||||
Result rc = lr.Globals.LrService.LocationResolver.OpenLocationResolver(
|
||||
out ReferenceCountedDisposable<ILocationResolver> baseResolver, storageId);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
resolver = new LocationResolver(ref baseResolver);
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public static Result OpenRegisteredLocationResolver(this LrClient lr, out RegisteredLocationResolver resolver)
|
||||
{
|
||||
UnsafeHelpers.SkipParamInit(out resolver);
|
||||
|
||||
Result rc = lr.Globals.LrService.LocationResolver.OpenRegisteredLocationResolver(
|
||||
out ReferenceCountedDisposable<IRegisteredLocationResolver> baseResolver);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
resolver = new RegisteredLocationResolver(ref baseResolver);
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public static Result OpenAddOnContentLocationResolver(this LrClient lr, out AddOnContentLocationResolver resolver)
|
||||
{
|
||||
UnsafeHelpers.SkipParamInit(out resolver);
|
||||
|
||||
Result rc = lr.Globals.LrService.LocationResolver.OpenAddOnContentLocationResolver(
|
||||
out ReferenceCountedDisposable<IAddOnContentLocationResolver> baseResolver);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
resolver = new AddOnContentLocationResolver(ref baseResolver);
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public static Result RefreshLocationResolver(this LrClient lr, StorageId storageId)
|
||||
{
|
||||
Result rc = lr.Globals.LrService.LocationResolver.RefreshLocationResolver(storageId);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
// Official lr puts this function along with memory allocation for
|
||||
// lr IPC objects into a separate file, LocationResolverManagerFactory.
|
||||
private static ILocationResolverManager GetLocationResolverManagerServiceObject(this LrClient lr)
|
||||
{
|
||||
Result rc = lr.Hos.Sm.GetService(out ILocationResolverManager manager, "lr");
|
||||
|
||||
if (rc.IsFailure())
|
||||
{
|
||||
throw new HorizonResultException(rc, "Failed to get lr service object.");
|
||||
}
|
||||
|
||||
return manager;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using LibHac.Common;
|
||||
using LibHac.Ncm;
|
||||
|
||||
namespace LibHac.Lr
|
||||
|
@ -7,9 +8,14 @@ namespace LibHac.Lr
|
|||
{
|
||||
private ReferenceCountedDisposable<IRegisteredLocationResolver> _interface;
|
||||
|
||||
public RegisteredLocationResolver(ReferenceCountedDisposable<IRegisteredLocationResolver> baseInterface)
|
||||
public RegisteredLocationResolver(ref ReferenceCountedDisposable<IRegisteredLocationResolver> baseInterface)
|
||||
{
|
||||
_interface = baseInterface.AddReference();
|
||||
_interface = Shared.Move(ref baseInterface);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_interface?.Dispose();
|
||||
}
|
||||
|
||||
public Result ResolveProgramPath(out Path path, ProgramId id) =>
|
||||
|
@ -41,10 +47,5 @@ namespace LibHac.Lr
|
|||
|
||||
public Result RefreshExcluding(ReadOnlySpan<ProgramId> ids) =>
|
||||
_interface.Target.RefreshExcluding(ids);
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_interface?.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue