mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2024-11-14 10:49:41 +01:00
Fixup program-registry-related classes
- IProgramRegistry - ProgramRegistryImpl - ProgramIndexRegistryService - ProgramRegistryServiceImpl
This commit is contained in:
parent
814ae34642
commit
ecb85269eb
10 changed files with 245 additions and 210 deletions
|
@ -20,7 +20,7 @@ public static class ProgramRegistry
|
||||||
if (rc.IsFailure()) return rc.Miss();
|
if (rc.IsFailure()) return rc.Miss();
|
||||||
|
|
||||||
rc = programRegistry.Get.RegisterProgram(processId, programId, storageId, new InBuffer(accessControlData),
|
rc = programRegistry.Get.RegisterProgram(processId, programId, storageId, new InBuffer(accessControlData),
|
||||||
new InBuffer(accessControlDescriptor));
|
accessControlData.Length, new InBuffer(accessControlDescriptor), accessControlDescriptor.Length);
|
||||||
|
|
||||||
fs.Impl.AbortIfNeeded(rc);
|
fs.Impl.AbortIfNeeded(rc);
|
||||||
if (rc.IsFailure()) return rc.Miss();
|
if (rc.IsFailure()) return rc.Miss();
|
||||||
|
@ -41,4 +41,4 @@ public static class ProgramRegistry
|
||||||
|
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -138,7 +138,7 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader
|
||||||
|
|
||||||
private ProgramIndexRegistryService GetProgramIndexRegistryService()
|
private ProgramIndexRegistryService GetProgramIndexRegistryService()
|
||||||
{
|
{
|
||||||
return new ProgramIndexRegistryService(Globals.ProgramRegistryServiceImpl, _currentProcess);
|
return new ProgramIndexRegistryService(_fsServer, Globals.ProgramRegistryServiceImpl, _currentProcess);
|
||||||
}
|
}
|
||||||
|
|
||||||
private AccessLogService GetAccessLogService()
|
private AccessLogService GetAccessLogService()
|
||||||
|
@ -1151,4 +1151,4 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader
|
||||||
{
|
{
|
||||||
return GetBaseFileSystemService().OpenBisWiper(ref outBisWiper, transferMemoryHandle, transferMemorySize);
|
return GetBaseFileSystemService().OpenBisWiper(ref outBisWiper, transferMemoryHandle, transferMemorySize);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -82,7 +82,7 @@ public static class FileSystemServerInitializer
|
||||||
|
|
||||||
var programRegistryService = new ProgramRegistryServiceImpl(in programRegistryConfig);
|
var programRegistryService = new ProgramRegistryServiceImpl(in programRegistryConfig);
|
||||||
|
|
||||||
server.InitializeProgramRegistryImpl(programRegistryService);
|
ProgramRegistryImpl.Initialize(server, programRegistryService);
|
||||||
|
|
||||||
var baseStorageConfig = new BaseStorageServiceImpl.Configuration();
|
var baseStorageConfig = new BaseStorageServiceImpl.Configuration();
|
||||||
baseStorageConfig.BisStorageCreator = config.FsCreators.BuiltInStorageCreator;
|
baseStorageConfig.BisStorageCreator = config.FsCreators.BuiltInStorageCreator;
|
||||||
|
@ -272,4 +272,4 @@ public class FileSystemServerConfig
|
||||||
/// If null, an empty set will be created.
|
/// If null, an empty set will be created.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ExternalKeySet ExternalKeySet { get; set; }
|
public ExternalKeySet ExternalKeySet { get; set; }
|
||||||
}
|
}
|
|
@ -66,7 +66,8 @@ public static class FileSystemProxyServiceObject
|
||||||
public void Dispose() { }
|
public void Dispose() { }
|
||||||
|
|
||||||
public Result RegisterProgram(ulong processId, ProgramId programId, StorageId storageId,
|
public Result RegisterProgram(ulong processId, ProgramId programId, StorageId storageId,
|
||||||
InBuffer accessControlData, InBuffer accessControlDescriptor)
|
InBuffer accessControlData, long accessControlDataSize, InBuffer accessControlDescriptor,
|
||||||
|
long accessControlDescriptorSize)
|
||||||
{
|
{
|
||||||
return ResultFs.PortAcceptableCountLimited.Log();
|
return ResultFs.PortAcceptableCountLimited.Log();
|
||||||
}
|
}
|
||||||
|
@ -81,4 +82,4 @@ public static class FileSystemProxyServiceObject
|
||||||
return ResultFs.PortAcceptableCountLimited.Log();
|
return ResultFs.PortAcceptableCountLimited.Log();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,6 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using LibHac.Common;
|
using LibHac.Common;
|
||||||
using LibHac.Diag;
|
using LibHac.Diag;
|
||||||
using LibHac.Fs;
|
using LibHac.Fs;
|
||||||
|
|
|
@ -1,99 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using LibHac.Common;
|
|
||||||
using LibHac.Fs;
|
|
||||||
using LibHac.FsSrv.Impl;
|
|
||||||
using LibHac.Sf;
|
|
||||||
using LibHac.Util;
|
|
||||||
|
|
||||||
namespace LibHac.FsSrv;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Used to perform operations on the program index registry.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>Appropriate methods calls on IFileSystemProxy are forwarded to this class
|
|
||||||
/// which then checks the calling process' permissions and performs the requested operation.
|
|
||||||
/// <br/>Based on FS 10.0.0 (nnSdk 10.4.0)</remarks>
|
|
||||||
internal readonly struct ProgramIndexRegistryService
|
|
||||||
{
|
|
||||||
private ProgramRegistryServiceImpl ServiceImpl { get; }
|
|
||||||
private ulong ProcessId { get; }
|
|
||||||
|
|
||||||
public ProgramIndexRegistryService(ProgramRegistryServiceImpl serviceImpl, ulong processId)
|
|
||||||
{
|
|
||||||
ServiceImpl = serviceImpl;
|
|
||||||
ProcessId = processId;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Unregisters any previously registered program index map info and registers the provided map info.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="programIndexMapInfo">A buffer containing the program map info to register.</param>
|
|
||||||
/// <param name="programCount">The number of programs to register. The provided buffer must be
|
|
||||||
/// large enough to hold this many <see cref="ProgramIndexMapInfo"/> entries.</param>
|
|
||||||
/// <returns><see cref="Result.Success"/>: The operation was successful.<br/>
|
|
||||||
/// <see cref="ResultFs.PermissionDenied"/>: Insufficient permissions.<br/>
|
|
||||||
/// <see cref="ResultFs.InvalidSize"/>: The buffer was too small to hold the specified
|
|
||||||
/// number of <see cref="ProgramIndexMapInfo"/> entries.</returns>
|
|
||||||
public Result RegisterProgramIndexMapInfo(InBuffer programIndexMapInfo, int programCount)
|
|
||||||
{
|
|
||||||
// Verify the caller's permissions
|
|
||||||
Result rc = GetProgramInfo(out ProgramInfo programInfo, ProcessId);
|
|
||||||
if (rc.IsFailure()) return rc;
|
|
||||||
|
|
||||||
if (!programInfo.AccessControl.CanCall(OperationType.RegisterProgramIndexMapInfo))
|
|
||||||
return ResultFs.PermissionDenied.Log();
|
|
||||||
|
|
||||||
// Return early if the program count is 0 so we leave any previously
|
|
||||||
// registered entries as they were
|
|
||||||
if (programCount == 0)
|
|
||||||
return Result.Success;
|
|
||||||
|
|
||||||
// Verify that the provided buffer is large enough to hold "programCount" entries
|
|
||||||
ReadOnlySpan<ProgramIndexMapInfo>
|
|
||||||
mapInfo = MemoryMarshal.Cast<byte, ProgramIndexMapInfo>(programIndexMapInfo.Buffer);
|
|
||||||
|
|
||||||
if (mapInfo.Length < programCount)
|
|
||||||
return ResultFs.InvalidSize.Log();
|
|
||||||
|
|
||||||
// Register the map info
|
|
||||||
return ServiceImpl.RegisterProgramIndexMapInfo(mapInfo.Slice(0, programCount));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the multi-program index of the calling process and the number of programs
|
|
||||||
/// in the current application.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="programIndex">When this method returns successfully, contains the
|
|
||||||
/// program index of the calling process.</param>
|
|
||||||
/// <param name="programCount">When this method returns successfully, contains the
|
|
||||||
/// number of programs in the current application.</param>
|
|
||||||
/// <returns><see cref="Result.Success"/>: The operation was successful.<br/>
|
|
||||||
/// <see cref="ResultFs.ProgramInfoNotFound"/>: The calling program was not found
|
|
||||||
/// in the program registry. Something's wrong with Loader if this happens.</returns>
|
|
||||||
public Result GetProgramIndex(out int programIndex, out int programCount)
|
|
||||||
{
|
|
||||||
UnsafeHelpers.SkipParamInit(out programIndex, out programCount);
|
|
||||||
|
|
||||||
// No permissions are needed to call this method
|
|
||||||
Result rc = GetProgramInfo(out ProgramInfo programInfo, ProcessId);
|
|
||||||
if (rc.IsFailure()) return rc;
|
|
||||||
|
|
||||||
// Try to get map info for this process
|
|
||||||
Optional<ProgramIndexMapInfo> mapInfo = ServiceImpl.GetProgramIndexMapInfo(programInfo.ProgramId);
|
|
||||||
|
|
||||||
// Set the output program index if map info was found
|
|
||||||
programIndex = mapInfo.HasValue ? mapInfo.ValueRo.ProgramIndex : 0;
|
|
||||||
|
|
||||||
// Set the number of programs in the current application
|
|
||||||
programCount = ServiceImpl.GetProgramIndexMapInfoCount();
|
|
||||||
|
|
||||||
return Result.Success;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc cref="ProgramRegistryServiceImpl.GetProgramInfo"/>
|
|
||||||
private Result GetProgramInfo(out ProgramInfo programInfo, ulong processId)
|
|
||||||
{
|
|
||||||
return ServiceImpl.GetProgramInfo(out programInfo, processId);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,4 +1,5 @@
|
||||||
using LibHac.Fs;
|
using LibHac.Diag;
|
||||||
|
using LibHac.Fs;
|
||||||
using LibHac.FsSrv.Impl;
|
using LibHac.FsSrv.Impl;
|
||||||
using LibHac.FsSrv.Sf;
|
using LibHac.FsSrv.Sf;
|
||||||
using LibHac.Ncm;
|
using LibHac.Ncm;
|
||||||
|
@ -6,15 +7,6 @@ using LibHac.Sf;
|
||||||
|
|
||||||
namespace LibHac.FsSrv;
|
namespace LibHac.FsSrv;
|
||||||
|
|
||||||
public static class ProgramRegistryImplGlobalMethods
|
|
||||||
{
|
|
||||||
public static void InitializeProgramRegistryImpl(this FileSystemServer fsSrv,
|
|
||||||
ProgramRegistryServiceImpl serviceImpl)
|
|
||||||
{
|
|
||||||
fsSrv.Globals.ProgramRegistryImpl.ServiceImpl = serviceImpl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal struct ProgramRegistryImplGlobals
|
internal struct ProgramRegistryImplGlobals
|
||||||
{
|
{
|
||||||
public ProgramRegistryServiceImpl ServiceImpl;
|
public ProgramRegistryServiceImpl ServiceImpl;
|
||||||
|
@ -27,12 +19,14 @@ internal struct ProgramRegistryImplGlobals
|
||||||
/// is stored in a <see cref="ProgramInfo"/> and includes the process' process ID, program ID,
|
/// is stored in a <see cref="ProgramInfo"/> and includes the process' process ID, program ID,
|
||||||
/// storage location and file system permissions. This allows FS to resolve the program ID and
|
/// storage location and file system permissions. This allows FS to resolve the program ID and
|
||||||
/// verify the permissions of any process calling it.
|
/// verify the permissions of any process calling it.
|
||||||
/// <br/>Based on FS 10.0.0 (nnSdk 10.4.0)</remarks>
|
/// <para>Based on FS 13.1.0 (nnSdk 13.4.0)</para></remarks>
|
||||||
public class ProgramRegistryImpl : IProgramRegistry
|
public class ProgramRegistryImpl : IProgramRegistry
|
||||||
{
|
{
|
||||||
private FileSystemServer _fsServer;
|
|
||||||
private ulong _processId;
|
private ulong _processId;
|
||||||
|
|
||||||
|
// LibHac addition
|
||||||
|
private FileSystemServer _fsServer;
|
||||||
|
|
||||||
private ref ProgramRegistryImplGlobals Globals => ref _fsServer.Globals.ProgramRegistryImpl;
|
private ref ProgramRegistryImplGlobals Globals => ref _fsServer.Globals.ProgramRegistryImpl;
|
||||||
|
|
||||||
public ProgramRegistryImpl(FileSystemServer server)
|
public ProgramRegistryImpl(FileSystemServer server)
|
||||||
|
@ -47,12 +41,20 @@ public class ProgramRegistryImpl : IProgramRegistry
|
||||||
/// <see cref="ResultFs.InvalidArgument"/>: The process ID is already registered.<br/>
|
/// <see cref="ResultFs.InvalidArgument"/>: The process ID is already registered.<br/>
|
||||||
/// <see cref="ResultFs.PermissionDenied"/>: Insufficient permissions.</returns>
|
/// <see cref="ResultFs.PermissionDenied"/>: Insufficient permissions.</returns>
|
||||||
/// <inheritdoc cref="ProgramRegistryManager.RegisterProgram"/>
|
/// <inheritdoc cref="ProgramRegistryManager.RegisterProgram"/>
|
||||||
public Result RegisterProgram(ulong processId, ProgramId programId, StorageId storageId,
|
public Result RegisterProgram(ulong processId, ProgramId programId, StorageId storageId, InBuffer accessControlData,
|
||||||
InBuffer accessControlData, InBuffer accessControlDescriptor)
|
long accessControlDataSize, InBuffer accessControlDescriptor, long accessControlDescriptorSize)
|
||||||
{
|
{
|
||||||
|
Assert.SdkRequiresNotNull(Globals.ServiceImpl);
|
||||||
|
|
||||||
if (!_fsServer.IsInitialProgram(_processId))
|
if (!_fsServer.IsInitialProgram(_processId))
|
||||||
return ResultFs.PermissionDenied.Log();
|
return ResultFs.PermissionDenied.Log();
|
||||||
|
|
||||||
|
if (accessControlDataSize > accessControlData.Size)
|
||||||
|
return ResultFs.InvalidSize.Log();
|
||||||
|
|
||||||
|
if (accessControlDescriptorSize > accessControlDescriptor.Size)
|
||||||
|
return ResultFs.InvalidSize.Log();
|
||||||
|
|
||||||
return Globals.ServiceImpl.RegisterProgramInfo(processId, programId, storageId, accessControlData.Buffer,
|
return Globals.ServiceImpl.RegisterProgramInfo(processId, programId, storageId, accessControlData.Buffer,
|
||||||
accessControlDescriptor.Buffer);
|
accessControlDescriptor.Buffer);
|
||||||
}
|
}
|
||||||
|
@ -63,6 +65,8 @@ public class ProgramRegistryImpl : IProgramRegistry
|
||||||
/// <inheritdoc cref="ProgramRegistryManager.UnregisterProgram" />
|
/// <inheritdoc cref="ProgramRegistryManager.UnregisterProgram" />
|
||||||
public Result UnregisterProgram(ulong processId)
|
public Result UnregisterProgram(ulong processId)
|
||||||
{
|
{
|
||||||
|
Assert.SdkRequiresNotNull(Globals.ServiceImpl);
|
||||||
|
|
||||||
if (!_fsServer.IsInitialProgram(_processId))
|
if (!_fsServer.IsInitialProgram(_processId))
|
||||||
return ResultFs.PermissionDenied.Log();
|
return ResultFs.PermissionDenied.Log();
|
||||||
|
|
||||||
|
@ -72,12 +76,16 @@ public class ProgramRegistryImpl : IProgramRegistry
|
||||||
/// <inheritdoc cref="ProgramRegistryManager.GetProgramInfo"/>
|
/// <inheritdoc cref="ProgramRegistryManager.GetProgramInfo"/>
|
||||||
public Result GetProgramInfo(out ProgramInfo programInfo, ulong processId)
|
public Result GetProgramInfo(out ProgramInfo programInfo, ulong processId)
|
||||||
{
|
{
|
||||||
|
Assert.SdkRequiresNotNull(Globals.ServiceImpl);
|
||||||
|
|
||||||
return Globals.ServiceImpl.GetProgramInfo(out programInfo, processId);
|
return Globals.ServiceImpl.GetProgramInfo(out programInfo, processId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc cref="ProgramRegistryManager.GetProgramInfoByProgramId"/>
|
/// <inheritdoc cref="ProgramRegistryManager.GetProgramInfoByProgramId"/>
|
||||||
public Result GetProgramInfoByProgramId(out ProgramInfo programInfo, ulong programId)
|
public Result GetProgramInfoByProgramId(out ProgramInfo programInfo, ulong programId)
|
||||||
{
|
{
|
||||||
|
Assert.SdkRequiresNotNull(Globals.ServiceImpl);
|
||||||
|
|
||||||
return Globals.ServiceImpl.GetProgramInfoByProgramId(out programInfo, programId);
|
return Globals.ServiceImpl.GetProgramInfoByProgramId(out programInfo, programId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,4 +99,22 @@ public class ProgramRegistryImpl : IProgramRegistry
|
||||||
_processId = processId;
|
_processId = processId;
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the <see cref="ProgramRegistryServiceImpl"/> used by the provided <see cref="FileSystemServer"/>.
|
||||||
|
/// This function must be called before calling functions on a <see cref="ProgramRegistryImpl"/>.
|
||||||
|
/// This function must not be called more than once.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fsServer">The <see cref="FileSystemServer"/> to initialize.</param>
|
||||||
|
/// <param name="serviceImpl">The <see cref="ProgramRegistryServiceImpl"/>
|
||||||
|
/// that <paramref name="fsServer"/> will use.</param>
|
||||||
|
public static void Initialize(FileSystemServer fsServer, ProgramRegistryServiceImpl serviceImpl)
|
||||||
|
{
|
||||||
|
ref ProgramRegistryImplGlobals globals = ref fsServer.Globals.ProgramRegistryImpl;
|
||||||
|
|
||||||
|
Assert.SdkRequiresNotNull(serviceImpl);
|
||||||
|
Assert.SdkRequiresNull(globals.ServiceImpl);
|
||||||
|
|
||||||
|
globals.ServiceImpl = serviceImpl;
|
||||||
|
}
|
||||||
}
|
}
|
193
src/LibHac/FsSrv/ProgramRegistryService.cs
Normal file
193
src/LibHac/FsSrv/ProgramRegistryService.cs
Normal file
|
@ -0,0 +1,193 @@
|
||||||
|
using System;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using LibHac.Common;
|
||||||
|
using LibHac.Fs;
|
||||||
|
using LibHac.FsSrv.Impl;
|
||||||
|
using LibHac.Ncm;
|
||||||
|
using LibHac.Sf;
|
||||||
|
using LibHac.Util;
|
||||||
|
|
||||||
|
namespace LibHac.FsSrv;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Used to perform operations on the program index registry.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>Appropriate methods calls on IFileSystemProxy are forwarded to this class
|
||||||
|
/// which then checks the calling process' permissions and performs the requested operation.
|
||||||
|
/// <para>Based on FS 13.1.0 (nnSdk 13.4.0)</para></remarks>
|
||||||
|
internal readonly struct ProgramIndexRegistryService
|
||||||
|
{
|
||||||
|
private readonly ProgramRegistryServiceImpl _serviceImpl;
|
||||||
|
private readonly ulong _processId;
|
||||||
|
|
||||||
|
// LibHac addition
|
||||||
|
private readonly FileSystemServer _fsServer;
|
||||||
|
|
||||||
|
public ProgramIndexRegistryService(FileSystemServer fsServer, ProgramRegistryServiceImpl serviceImpl,
|
||||||
|
ulong processId)
|
||||||
|
{
|
||||||
|
_serviceImpl = serviceImpl;
|
||||||
|
_processId = processId;
|
||||||
|
_fsServer = fsServer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Unregisters any previously registered program index map info and registers the provided map info.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="programIndexMapInfo">A buffer containing the program map info to register.</param>
|
||||||
|
/// <param name="programCount">The number of programs to register. The provided buffer must be
|
||||||
|
/// large enough to hold this many <see cref="ProgramIndexMapInfo"/> entries.</param>
|
||||||
|
/// <returns><see cref="Result.Success"/>: The operation was successful.<br/>
|
||||||
|
/// <see cref="ResultFs.PermissionDenied"/>: Insufficient permissions.<br/>
|
||||||
|
/// <see cref="ResultFs.InvalidSize"/>: The buffer was too small to hold the specified
|
||||||
|
/// number of <see cref="ProgramIndexMapInfo"/> entries.</returns>
|
||||||
|
public Result RegisterProgramIndexMapInfo(InBuffer programIndexMapInfo, int programCount)
|
||||||
|
{
|
||||||
|
// Verify the caller's permissions
|
||||||
|
using (var programRegistry = new ProgramRegistryImpl(_fsServer))
|
||||||
|
{
|
||||||
|
Result rc = programRegistry.GetProgramInfo(out ProgramInfo programInfo, _processId);
|
||||||
|
if (rc.IsFailure()) return rc;
|
||||||
|
|
||||||
|
if (!programInfo.AccessControl.CanCall(OperationType.RegisterProgramIndexMapInfo))
|
||||||
|
return ResultFs.PermissionDenied.Log();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return early if the program count is 0 so we leave any previously
|
||||||
|
// registered entries as they were
|
||||||
|
if (programCount == 0)
|
||||||
|
return Result.Success;
|
||||||
|
|
||||||
|
// Verify that the provided buffer is large enough to hold "programCount" entries
|
||||||
|
ReadOnlySpan<ProgramIndexMapInfo>
|
||||||
|
mapInfo = MemoryMarshal.Cast<byte, ProgramIndexMapInfo>(programIndexMapInfo.Buffer);
|
||||||
|
|
||||||
|
if (mapInfo.Length < programCount)
|
||||||
|
return ResultFs.InvalidSize.Log();
|
||||||
|
|
||||||
|
// Register the map info
|
||||||
|
return _serviceImpl.ResetProgramIndexMapInfo(mapInfo.Slice(0, programCount));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the multi-program index of the calling process and the number of programs
|
||||||
|
/// in the current application.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="programIndex">When this method returns successfully, contains the
|
||||||
|
/// program index of the calling process.</param>
|
||||||
|
/// <param name="programCount">When this method returns successfully, contains the
|
||||||
|
/// number of programs in the current application.</param>
|
||||||
|
/// <returns><see cref="Result.Success"/>: The operation was successful.<br/>
|
||||||
|
/// <see cref="ResultFs.ProgramInfoNotFound"/>: The calling program was not found
|
||||||
|
/// in the program registry. Something's wrong with Loader if this happens.</returns>
|
||||||
|
public Result GetProgramIndex(out int programIndex, out int programCount)
|
||||||
|
{
|
||||||
|
UnsafeHelpers.SkipParamInit(out programIndex, out programCount);
|
||||||
|
|
||||||
|
// No permissions are needed to call this method
|
||||||
|
Result rc = GetProgramInfo(out ProgramInfo programInfo, _processId);
|
||||||
|
if (rc.IsFailure()) return rc;
|
||||||
|
|
||||||
|
// Try to get map info for this process
|
||||||
|
Optional<ProgramIndexMapInfo> mapInfo = _serviceImpl.GetProgramIndexMapInfo(programInfo.ProgramId);
|
||||||
|
|
||||||
|
// Set the output program index if map info was found
|
||||||
|
programIndex = mapInfo.HasValue ? mapInfo.ValueRo.ProgramIndex : 0;
|
||||||
|
|
||||||
|
// Set the number of programs in the current application
|
||||||
|
programCount = _serviceImpl.GetProgramIndexMapInfoCount();
|
||||||
|
|
||||||
|
return Result.Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="ProgramRegistryServiceImpl.GetProgramInfo"/>
|
||||||
|
private Result GetProgramInfo(out ProgramInfo programInfo, ulong processId)
|
||||||
|
{
|
||||||
|
using var programRegistry = new ProgramRegistryImpl(_fsServer);
|
||||||
|
return programRegistry.GetProgramInfo(out programInfo, processId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Manages the main program registry and the multi-program registry.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>Based on FS 13.1.0 (nnSdk 13.4.0)</remarks>
|
||||||
|
public class ProgramRegistryServiceImpl : IDisposable
|
||||||
|
{
|
||||||
|
// ReSharper disable once PrivateFieldCanBeConvertedToLocalVariable
|
||||||
|
private Configuration _config;
|
||||||
|
private ProgramRegistryManager _registryManager;
|
||||||
|
private ProgramIndexMapInfoManager _programIndexManager;
|
||||||
|
|
||||||
|
public struct Configuration
|
||||||
|
{
|
||||||
|
// LibHac addition
|
||||||
|
public FileSystemServer FsServer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProgramRegistryServiceImpl(in Configuration config)
|
||||||
|
{
|
||||||
|
_config = config;
|
||||||
|
_registryManager = new ProgramRegistryManager(_config.FsServer);
|
||||||
|
_programIndexManager = new ProgramIndexMapInfoManager();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
_registryManager?.Dispose();
|
||||||
|
_programIndexManager?.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="ProgramRegistryManager.RegisterProgram"/>
|
||||||
|
public Result RegisterProgramInfo(ulong processId, ProgramId programId, StorageId storageId,
|
||||||
|
ReadOnlySpan<byte> accessControlData, ReadOnlySpan<byte> accessControlDescriptor)
|
||||||
|
{
|
||||||
|
return _registryManager.RegisterProgram(processId, programId, storageId, accessControlData,
|
||||||
|
accessControlDescriptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="ProgramRegistryManager.UnregisterProgram" />
|
||||||
|
public Result UnregisterProgramInfo(ulong processId)
|
||||||
|
{
|
||||||
|
return _registryManager.UnregisterProgram(processId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="ProgramRegistryManager.GetProgramInfo"/>
|
||||||
|
public Result GetProgramInfo(out ProgramInfo programInfo, ulong processId)
|
||||||
|
{
|
||||||
|
return _registryManager.GetProgramInfo(out programInfo, processId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="ProgramRegistryManager.GetProgramInfoByProgramId"/>
|
||||||
|
public Result GetProgramInfoByProgramId(out ProgramInfo programInfo, ulong programId)
|
||||||
|
{
|
||||||
|
return _registryManager.GetProgramInfoByProgramId(out programInfo, programId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="ProgramIndexMapInfoManager.Reset"/>
|
||||||
|
public Result ResetProgramIndexMapInfo(ReadOnlySpan<ProgramIndexMapInfo> programIndexMapInfo)
|
||||||
|
{
|
||||||
|
return _programIndexManager.Reset(programIndexMapInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="ProgramIndexMapInfoManager.GetProgramId"/>
|
||||||
|
public ProgramId GetProgramIdByIndex(ProgramId programId, byte programIndex)
|
||||||
|
{
|
||||||
|
return _programIndexManager.GetProgramId(programId, programIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="ProgramIndexMapInfoManager.Get"/>
|
||||||
|
public Optional<ProgramIndexMapInfo> GetProgramIndexMapInfo(ProgramId programId)
|
||||||
|
{
|
||||||
|
return _programIndexManager.Get(programId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the number of programs in the currently registered application.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The number of programs.</returns>
|
||||||
|
public int GetProgramIndexMapInfoCount()
|
||||||
|
{
|
||||||
|
return _programIndexManager.GetProgramCount();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,85 +0,0 @@
|
||||||
using System;
|
|
||||||
using LibHac.Fs;
|
|
||||||
using LibHac.FsSrv.Impl;
|
|
||||||
using LibHac.Ncm;
|
|
||||||
using LibHac.Util;
|
|
||||||
|
|
||||||
namespace LibHac.FsSrv;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Manages the main program registry and the multi-program registry.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>Based on FS 10.0.0 (nnSdk 10.4.0)</remarks>
|
|
||||||
public class ProgramRegistryServiceImpl
|
|
||||||
{
|
|
||||||
// ReSharper disable once PrivateFieldCanBeConvertedToLocalVariable
|
|
||||||
private Configuration _config;
|
|
||||||
private ProgramRegistryManager _registryManager;
|
|
||||||
private ProgramIndexMapInfoManager _programIndexManager;
|
|
||||||
|
|
||||||
public ProgramRegistryServiceImpl(in Configuration config)
|
|
||||||
{
|
|
||||||
_config = config;
|
|
||||||
_registryManager = new ProgramRegistryManager(_config.FsServer);
|
|
||||||
_programIndexManager = new ProgramIndexMapInfoManager();
|
|
||||||
}
|
|
||||||
|
|
||||||
public struct Configuration
|
|
||||||
{
|
|
||||||
// LibHac addition
|
|
||||||
public FileSystemServer FsServer;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc cref="ProgramRegistryManager.RegisterProgram"/>
|
|
||||||
public Result RegisterProgramInfo(ulong processId, ProgramId programId, StorageId storageId,
|
|
||||||
ReadOnlySpan<byte> accessControlData, ReadOnlySpan<byte> accessControlDescriptor)
|
|
||||||
{
|
|
||||||
return _registryManager.RegisterProgram(processId, programId, storageId, accessControlData,
|
|
||||||
accessControlDescriptor);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc cref="ProgramRegistryManager.UnregisterProgram" />
|
|
||||||
public Result UnregisterProgramInfo(ulong processId)
|
|
||||||
{
|
|
||||||
return _registryManager.UnregisterProgram(processId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc cref="ProgramRegistryManager.GetProgramInfo"/>
|
|
||||||
public Result GetProgramInfo(out ProgramInfo programInfo, ulong processId)
|
|
||||||
{
|
|
||||||
return _registryManager.GetProgramInfo(out programInfo, processId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc cref="ProgramRegistryManager.GetProgramInfoByProgramId"/>
|
|
||||||
public Result GetProgramInfoByProgramId(out ProgramInfo programInfo, ulong programId)
|
|
||||||
{
|
|
||||||
return _registryManager.GetProgramInfoByProgramId(out programInfo, programId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc cref="ProgramIndexMapInfoManager.GetProgramId"/>
|
|
||||||
public ProgramId GetProgramIdByIndex(ProgramId programId, byte programIndex)
|
|
||||||
{
|
|
||||||
return _programIndexManager.GetProgramId(programId, programIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc cref="ProgramIndexMapInfoManager.Get"/>
|
|
||||||
public Optional<ProgramIndexMapInfo> GetProgramIndexMapInfo(ProgramId programId)
|
|
||||||
{
|
|
||||||
return _programIndexManager.Get(programId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the number of programs in the currently registered application.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>The number of programs.</returns>
|
|
||||||
public int GetProgramIndexMapInfoCount()
|
|
||||||
{
|
|
||||||
return _programIndexManager.GetProgramCount();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc cref="ProgramIndexMapInfoManager.Reset"/>
|
|
||||||
public Result RegisterProgramIndexMapInfo(ReadOnlySpan<ProgramIndexMapInfo> programIndexMapInfo)
|
|
||||||
{
|
|
||||||
return _programIndexManager.Reset(programIndexMapInfo);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -6,9 +6,9 @@ namespace LibHac.FsSrv.Sf;
|
||||||
|
|
||||||
public interface IProgramRegistry : IDisposable
|
public interface IProgramRegistry : IDisposable
|
||||||
{
|
{
|
||||||
Result RegisterProgram(ulong processId, ProgramId programId, StorageId storageId,
|
Result RegisterProgram(ulong processId, ProgramId programId, StorageId storageId, InBuffer accessControlData,
|
||||||
InBuffer accessControlData, InBuffer accessControlDescriptor);
|
long accessControlDataSize, InBuffer accessControlDescriptor, long accessControlDescriptorSize);
|
||||||
|
|
||||||
Result UnregisterProgram(ulong processId);
|
Result UnregisterProgram(ulong processId);
|
||||||
Result SetCurrentProcess(ulong processId);
|
Result SetCurrentProcess(ulong processId);
|
||||||
}
|
}
|
Loading…
Reference in a new issue