mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2024-11-14 10:49:41 +01:00
Add functions to ProgramRegistryService
Adds RegisterProgramIndexMapInfo and GetProgramIndexForAccessLog to both FileSystemProxy and ProgramRegistryService
This commit is contained in:
parent
0b050d2189
commit
deaf111ac3
10 changed files with 153 additions and 80 deletions
|
@ -37,7 +37,7 @@ namespace LibHac.FsSrv
|
|||
|
||||
private ProgramRegistryService GetProgramRegistryService()
|
||||
{
|
||||
return new ProgramRegistryService(FsProxyCore.Config.ProgramRegistryService, CurrentProcess);
|
||||
return new ProgramRegistryService(FsProxyCore.Config.ProgramRegistryServiceImpl, CurrentProcess);
|
||||
}
|
||||
|
||||
public Result OpenFileSystemWithId(out IFileSystem fileSystem, ref FsPath path, ulong id, FileSystemProxyType type)
|
||||
|
@ -649,6 +649,11 @@ namespace LibHac.FsSrv
|
|||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Result RegisterProgramIndexMapInfo(ReadOnlySpan<byte> programIndexMapInfoBuffer, int programCount)
|
||||
{
|
||||
return GetProgramRegistryService().RegisterProgramIndexMapInfo(programIndexMapInfoBuffer, programCount);
|
||||
}
|
||||
|
||||
public Result SetBisRootForHost(BisPartitionId partitionId, ref FsPath path)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
|
@ -1087,7 +1092,7 @@ namespace LibHac.FsSrv
|
|||
|
||||
public Result GetProgramIndexForAccessLog(out int programIndex, out int programCount)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
return GetProgramRegistryService().GetProgramIndexForAccessLog(out programIndex, out programCount);
|
||||
}
|
||||
|
||||
public Result OutputAccessLogToSdCard(U8Span logString)
|
||||
|
@ -1188,6 +1193,11 @@ namespace LibHac.FsSrv
|
|||
}
|
||||
}
|
||||
|
||||
private Result GetProgramInfo(out ProgramInfo programInfo)
|
||||
{
|
||||
return FsProxyCore.ProgramRegistry.GetProgramInfo(out programInfo, CurrentProcess);
|
||||
}
|
||||
|
||||
private static bool IsSystemSaveDataId(ulong id)
|
||||
{
|
||||
return (long)id < 0;
|
||||
|
|
|
@ -5,6 +5,6 @@ namespace LibHac.FsSrv
|
|||
public class FileSystemProxyConfiguration
|
||||
{
|
||||
public FileSystemCreators FsCreatorInterfaces { get; set; }
|
||||
public ProgramRegistryServiceImpl ProgramRegistryService { get; set; }
|
||||
public ProgramRegistryServiceImpl ProgramRegistryServiceImpl { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ namespace LibHac.FsSrv
|
|||
public FileSystemProxyCore(FileSystemProxyConfiguration config, ExternalKeySet externalKeys, IDeviceOperator deviceOperator)
|
||||
{
|
||||
Config = config;
|
||||
ProgramRegistry = new ProgramRegistryImpl(Config.ProgramRegistryService);
|
||||
ProgramRegistry = new ProgramRegistryImpl(Config.ProgramRegistryServiceImpl);
|
||||
ExternalKeys = externalKeys ?? new ExternalKeySet();
|
||||
DeviceOperator = deviceOperator;
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ namespace LibHac.FsSrv
|
|||
var fspConfig = new FileSystemProxyConfiguration
|
||||
{
|
||||
FsCreatorInterfaces = config.FsCreators,
|
||||
ProgramRegistryService = new ProgramRegistryServiceImpl(this)
|
||||
ProgramRegistryServiceImpl = new ProgramRegistryServiceImpl(this)
|
||||
};
|
||||
|
||||
FsProxyCore = new FileSystemProxyCore(fspConfig, externalKeySet, config.DeviceOperator);
|
||||
|
|
|
@ -88,6 +88,7 @@ namespace LibHac.FsSrv
|
|||
Result SetSdCardAccessibility(bool isAccessible);
|
||||
Result IsSdCardAccessible(out bool isAccessible);
|
||||
|
||||
Result RegisterProgramIndexMapInfo(ReadOnlySpan<byte> programIndexMapInfoBuffer, int programCount);
|
||||
Result SetBisRootForHost(BisPartitionId partitionId, ref FsPath path);
|
||||
Result SetSaveDataSize(long saveDataSize, long saveDataJournalSize);
|
||||
Result SetSaveDataRootPath(ref FsPath path);
|
||||
|
|
|
@ -37,7 +37,7 @@ namespace LibHac.FsSrv.Impl
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers a program with information about the program in the program registry.
|
||||
/// Registers a program with information about that program in the program registry.
|
||||
/// </summary>
|
||||
/// <param name="processId">The process ID of the program.</param>
|
||||
/// <param name="programId">The <see cref="ProgramId"/> of the program.</param>
|
||||
|
|
|
@ -5,30 +5,36 @@ using LibHac.Ncm;
|
|||
|
||||
namespace LibHac.FsSrv
|
||||
{
|
||||
/// <summary>
|
||||
/// Keeps track of the program IDs and program indexes of each program in a multi-program application.
|
||||
/// </summary>
|
||||
public class ProgramIndexMapInfoManager
|
||||
{
|
||||
private LinkedList<ProgramIndexMapInfo> MapEntries { get; } = new LinkedList<ProgramIndexMapInfo>();
|
||||
|
||||
/// <summary>
|
||||
/// Clears any existing
|
||||
/// Unregisters any previously registered program index map info and registers the provided map info.
|
||||
/// </summary>
|
||||
/// <param name="entries">The entries </param>
|
||||
/// <param name="programIndexMapInfo">The program map info entries to register.</param>
|
||||
/// <returns><see cref="Result.Success"/>: The operation was successful.</returns>
|
||||
public Result Reset(ReadOnlySpan<ProgramIndexMapInfo> entries)
|
||||
public Result Reset(ReadOnlySpan<ProgramIndexMapInfo> programIndexMapInfo)
|
||||
{
|
||||
lock (MapEntries)
|
||||
{
|
||||
ClearImpl();
|
||||
|
||||
for (int i = 0; i < entries.Length; i++)
|
||||
for (int i = 0; i < programIndexMapInfo.Length; i++)
|
||||
{
|
||||
MapEntries.AddLast(entries[i]);
|
||||
MapEntries.AddLast(programIndexMapInfo[i]);
|
||||
}
|
||||
|
||||
return Result.Success;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unregisters all currently registered program index map info.
|
||||
/// </summary>
|
||||
public void Clear()
|
||||
{
|
||||
lock (MapEntries)
|
||||
|
@ -37,6 +43,12 @@ namespace LibHac.FsSrv
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="ProgramIndexMapInfo"/> associated with the specified program ID.
|
||||
/// </summary>
|
||||
/// <param name="programId">The program ID of the map info to get.</param>
|
||||
/// <returns>If the program ID was found, the <see cref="ProgramIndexMapInfo"/> associated
|
||||
/// with that ID; otherwise, <see langword="null"/>.</returns>
|
||||
public ProgramIndexMapInfo? Get(ProgramId programId)
|
||||
{
|
||||
lock (MapEntries)
|
||||
|
@ -72,6 +84,10 @@ namespace LibHac.FsSrv
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of currently registered programs,
|
||||
/// </summary>
|
||||
/// <returns>The number of registered programs.</returns>
|
||||
public int GetProgramCount()
|
||||
{
|
||||
lock (MapEntries)
|
||||
|
|
|
@ -8,6 +8,8 @@ namespace LibHac.FsSrv
|
|||
internal class ProgramRegistryImpl
|
||||
{
|
||||
private ulong _processId;
|
||||
|
||||
// Note: FS keeps this object as a global variable
|
||||
private readonly ProgramRegistryServiceImpl _registryService;
|
||||
|
||||
public ProgramRegistryImpl(ProgramRegistryServiceImpl registryService)
|
||||
|
@ -22,17 +24,10 @@ namespace LibHac.FsSrv
|
|||
_registryService = registryService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers a program with information about the program in the program registry.
|
||||
/// </summary>
|
||||
/// <param name="processId">The process ID of the program.</param>
|
||||
/// <param name="programId">The <see cref="ProgramId"/> of the program.</param>
|
||||
/// <param name="storageId">The <see cref="StorageId"/> where the program is located.</param>
|
||||
/// <param name="accessControlData">The FS access control data header located in the program's ACI.</param>
|
||||
/// <param name="accessControlDescriptor">The FS access control descriptor located in the program's ACID.</param>
|
||||
/// <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>
|
||||
/// <inheritdoc cref="ProgramRegistryManager.RegisterProgram"/>
|
||||
public Result RegisterProgram(ulong processId, ProgramId programId, StorageId storageId,
|
||||
ReadOnlySpan<byte> accessControlData, ReadOnlySpan<byte> accessControlDescriptor)
|
||||
{
|
||||
|
@ -43,13 +38,10 @@ namespace LibHac.FsSrv
|
|||
accessControlDescriptor);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unregisters the program with the specified process ID.
|
||||
/// </summary>
|
||||
/// <param name="processId">The process ID of the program to unregister.</param>
|
||||
/// <returns><see cref="Result.Success"/>: The operation was successful.<br/>
|
||||
/// <see cref="ResultFs.InvalidArgument"/>: The process ID is not registered.<br/>
|
||||
/// <see cref="ResultFs.PermissionDenied"/>: Insufficient permissions.</returns>
|
||||
/// <inheritdoc cref="ProgramRegistryManager.UnregisterProgram" />
|
||||
public Result UnregisterProgram(ulong processId)
|
||||
{
|
||||
if (!ProgramInfo.IsInitialProgram(_processId))
|
||||
|
@ -58,27 +50,13 @@ namespace LibHac.FsSrv
|
|||
return _registryService.UnregisterProgram(processId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="ProgramInfo"/> associated with the specified process ID.
|
||||
/// </summary>
|
||||
/// <param name="programInfo">If the method returns successfully, contains the <see cref="ProgramInfo"/>
|
||||
/// associated with the specified process ID.</param>
|
||||
/// <param name="processId">The process ID of the <see cref="ProgramInfo"/> to get.</param>
|
||||
/// <returns><see cref="Result.Success"/>: The operation was successful.<br/>
|
||||
/// <see cref="ResultFs.TargetProgramNotFound"/>: The <see cref="ProgramInfo"/> was not found.</returns>
|
||||
/// <inheritdoc cref="ProgramRegistryManager.GetProgramInfo"/>
|
||||
public Result GetProgramInfo(out ProgramInfo programInfo, ulong processId)
|
||||
{
|
||||
return _registryService.GetProgramInfo(out programInfo, processId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="ProgramInfo"/> associated with the specified program ID.
|
||||
/// </summary>
|
||||
/// <param name="programInfo">If the method returns successfully, contains the <see cref="ProgramInfo"/>
|
||||
/// associated with the specified program ID.</param>
|
||||
/// <param name="programId">The program ID of the <see cref="ProgramInfo"/> to get.</param>
|
||||
/// <returns><see cref="Result.Success"/>: The operation was successful.<br/>
|
||||
/// <see cref="ResultFs.TargetProgramNotFound"/>: The <see cref="ProgramInfo"/> was not found.</returns>
|
||||
/// <inheritdoc cref="ProgramRegistryManager.GetProgramInfoByProgramId"/>
|
||||
public Result GetProgramInfoByProgramId(out ProgramInfo programInfo, ulong programId)
|
||||
{
|
||||
return _registryService.GetProgramInfoByProgramId(out programInfo, programId);
|
||||
|
|
|
@ -1,4 +1,10 @@
|
|||
namespace LibHac.FsSrv
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using LibHac.Fs;
|
||||
using LibHac.FsSrv.Impl;
|
||||
|
||||
namespace LibHac.FsSrv
|
||||
{
|
||||
internal readonly struct ProgramRegistryService
|
||||
{
|
||||
|
@ -10,5 +16,78 @@
|
|||
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(ReadOnlySpan<byte> 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);
|
||||
|
||||
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.TargetProgramNotFound"/>: The calling program was not found
|
||||
/// in the program registry. Something's wrong with Loader if this happens.</returns>
|
||||
public Result GetProgramIndexForAccessLog(out int programIndex, out int programCount)
|
||||
{
|
||||
Unsafe.SkipInit(out programIndex);
|
||||
Unsafe.SkipInit(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
|
||||
ProgramIndexMapInfo? mapInfo = ServiceImpl.GetProgramIndexMapInfo(programInfo.ProgramId);
|
||||
|
||||
// Set the output program index if map info was found
|
||||
programIndex = mapInfo?.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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,9 @@ using LibHac.Ncm;
|
|||
|
||||
namespace LibHac.FsSrv
|
||||
{
|
||||
/// <summary>
|
||||
/// Manages the main program registry and the multi-program registry.
|
||||
/// </summary>
|
||||
public class ProgramRegistryServiceImpl
|
||||
{
|
||||
private ProgramRegistryManager RegistryManager { get; }
|
||||
|
@ -16,16 +19,7 @@ namespace LibHac.FsSrv
|
|||
ProgramIndexManager = new ProgramIndexMapInfoManager();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers a program with information about the program in the program registry.
|
||||
/// </summary>
|
||||
/// <param name="processId">The process ID of the program.</param>
|
||||
/// <param name="programId">The <see cref="ProgramId"/> of the program.</param>
|
||||
/// <param name="storageId">The <see cref="StorageId"/> where the program is located.</param>
|
||||
/// <param name="accessControlData">The FS access control data header located in the program's ACI.</param>
|
||||
/// <param name="accessControlDescriptor">The FS access control descriptor located in the program's ACID.</param>
|
||||
/// <returns><see cref="Result.Success"/>: The operation was successful.<br/>
|
||||
/// <see cref="ResultFs.InvalidArgument"/>: The process ID is already registered.</returns>
|
||||
/// <inheritdoc cref="ProgramRegistryManager.RegisterProgram"/>
|
||||
public Result RegisterProgram(ulong processId, ProgramId programId, StorageId storageId,
|
||||
ReadOnlySpan<byte> accessControlData, ReadOnlySpan<byte> accessControlDescriptor)
|
||||
{
|
||||
|
@ -33,54 +27,49 @@ namespace LibHac.FsSrv
|
|||
accessControlDescriptor);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unregisters the program with the specified process ID.
|
||||
/// </summary>
|
||||
/// <param name="processId">The process ID of the program to unregister.</param>
|
||||
/// <returns><see cref="Result.Success"/>: The operation was successful.<br/>
|
||||
/// <see cref="ResultFs.InvalidArgument"/>: The process ID is not registered.</returns>
|
||||
/// <inheritdoc cref="ProgramRegistryManager.UnregisterProgram" />
|
||||
public Result UnregisterProgram(ulong processId)
|
||||
{
|
||||
return RegistryManager.UnregisterProgram(processId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="ProgramInfo"/> associated with the specified process ID.
|
||||
/// </summary>
|
||||
/// <param name="programInfo">If the method returns successfully, contains the <see cref="ProgramInfo"/>
|
||||
/// associated with the specified process ID.</param>
|
||||
/// <param name="processId">The process ID of the <see cref="ProgramInfo"/> to get.</param>
|
||||
/// <returns><see cref="Result.Success"/>: The operation was successful.<br/>
|
||||
/// <see cref="ResultFs.TargetProgramNotFound"/>: The <see cref="ProgramInfo"/> was not found.</returns>
|
||||
/// <inheritdoc cref="ProgramRegistryManager.GetProgramInfo"/>
|
||||
public Result GetProgramInfo(out ProgramInfo programInfo, ulong processId)
|
||||
{
|
||||
return RegistryManager.GetProgramInfo(out programInfo, processId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="ProgramInfo"/> associated with the specified program ID.
|
||||
/// </summary>
|
||||
/// <param name="programInfo">If the method returns successfully, contains the <see cref="ProgramInfo"/>
|
||||
/// associated with the specified program ID.</param>
|
||||
/// <param name="programId">The program ID of the <see cref="ProgramInfo"/> to get.</param>
|
||||
/// <returns><see cref="Result.Success"/>: The operation was successful.<br/>
|
||||
/// <see cref="ResultFs.TargetProgramNotFound"/>: The <see cref="ProgramInfo"/> was not found.</returns>
|
||||
/// <inheritdoc cref="ProgramRegistryManager.GetProgramInfoByProgramId"/>
|
||||
public Result GetProgramInfoByProgramId(out ProgramInfo programInfo, ulong programId)
|
||||
{
|
||||
return RegistryManager.GetProgramInfoByProgramId(out programInfo, programId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="ProgramId"/> of the program with index <paramref name="programIndex"/> in the
|
||||
/// multi-program app <paramref name="programId"/> is part of.
|
||||
/// </summary>
|
||||
/// <param name="programId">A program ID in the multi-program app to query.</param>
|
||||
/// <param name="programIndex">The index of the program to get.</param>
|
||||
/// <returns>If the program exists, the ID of the program with the specified index,
|
||||
/// otherwise <see cref="ProgramId.InvalidId"/></returns>
|
||||
/// <inheritdoc cref="ProgramIndexMapInfoManager.GetProgramId"/>
|
||||
public ProgramId GetProgramId(ProgramId programId, byte programIndex)
|
||||
{
|
||||
return ProgramIndexManager.GetProgramId(programId, programIndex);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="ProgramIndexMapInfoManager.Get"/>
|
||||
public 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue