mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2024-11-14 10:49:41 +01:00
Fixup ProgramRegistryManager and ProgramInfo
This commit is contained in:
parent
04a2e51cfa
commit
8ba258034b
7 changed files with 186 additions and 145 deletions
|
@ -29,6 +29,7 @@ internal struct FileSystemServerGlobals
|
||||||
public ProgramRegistryImplGlobals ProgramRegistryImpl;
|
public ProgramRegistryImplGlobals ProgramRegistryImpl;
|
||||||
public DeviceEventSimulatorGlobals DeviceEventSimulator;
|
public DeviceEventSimulatorGlobals DeviceEventSimulator;
|
||||||
public AccessControlGlobals AccessControl;
|
public AccessControlGlobals AccessControl;
|
||||||
|
public ProgramInfoGlobals ProgramInfo;
|
||||||
public StorageDeviceManagerFactoryGlobals StorageDeviceManagerFactory;
|
public StorageDeviceManagerFactoryGlobals StorageDeviceManagerFactory;
|
||||||
public SaveDataSharedFileStorageGlobals SaveDataSharedFileStorage;
|
public SaveDataSharedFileStorageGlobals SaveDataSharedFileStorage;
|
||||||
public MultiCommitManagerGlobals MultiCommitManager;
|
public MultiCommitManagerGlobals MultiCommitManager;
|
||||||
|
|
120
src/LibHac/FsSrv/Impl/ProgramInfo.cs
Normal file
120
src/LibHac/FsSrv/Impl/ProgramInfo.cs
Normal file
|
@ -0,0 +1,120 @@
|
||||||
|
using System;
|
||||||
|
using LibHac.Common;
|
||||||
|
using LibHac.Diag;
|
||||||
|
using LibHac.Ncm;
|
||||||
|
using LibHac.Os;
|
||||||
|
|
||||||
|
namespace LibHac.FsSrv.Impl;
|
||||||
|
|
||||||
|
public static class ProgramInfoGlobalMethods
|
||||||
|
{
|
||||||
|
public static bool IsInitialProgram(this FileSystemServer fsSrv, ulong processId)
|
||||||
|
{
|
||||||
|
ref ProgramInfoGlobals g = ref fsSrv.Globals.ProgramInfo;
|
||||||
|
using (var guard = new InitializationGuard(ref g.InitialProcessIdRangeInitGuard, fsSrv.Globals.InitMutex))
|
||||||
|
{
|
||||||
|
if (!guard.IsInitialized)
|
||||||
|
{
|
||||||
|
// Todo: We have no kernel to call into, so use hardcoded values for now
|
||||||
|
g.InitialProcessIdMin = OsState.InitialProcessCountMin;
|
||||||
|
g.InitialProcessIdMax = OsState.InitialProcessCountMax;
|
||||||
|
|
||||||
|
Abort.DoAbortUnless(0 < g.InitialProcessIdMin && g.InitialProcessIdMin <= g.InitialProcessIdMax,
|
||||||
|
"Invalid initial process ID range");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Abort.DoAbortUnless(g.InitialProcessIdMin != 0);
|
||||||
|
|
||||||
|
return g.InitialProcessIdMin <= processId && processId <= g.InitialProcessIdMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool IsCurrentProcess(this FileSystemServer fsSrv, ulong processId)
|
||||||
|
{
|
||||||
|
ref ProgramInfoGlobals g = ref fsSrv.Globals.ProgramInfo;
|
||||||
|
using (var guard = new InitializationGuard(ref g.CurrentProcessIdInitGuard, fsSrv.Globals.InitMutex))
|
||||||
|
{
|
||||||
|
if (!guard.IsInitialized)
|
||||||
|
{
|
||||||
|
g.CurrentProcessId = fsSrv.Hos.Os.GetCurrentProcessId().Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return g.CurrentProcessId == processId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal struct ProgramInfoGlobals
|
||||||
|
{
|
||||||
|
public nint CurrentProcessIdInitGuard;
|
||||||
|
public ulong CurrentProcessId;
|
||||||
|
|
||||||
|
public nint InitialProcessIdRangeInitGuard;
|
||||||
|
public ulong InitialProcessIdMin;
|
||||||
|
public ulong InitialProcessIdMax;
|
||||||
|
|
||||||
|
public nint ProgramInfoForInitialProcessInitGuard;
|
||||||
|
public ProgramInfo ProgramInfoForInitialProcess;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Contains the program ID, storage location and FS permissions of a running process.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>Based on FS 13.1.0 (nnSdk 13.4.0)</remarks>
|
||||||
|
public class ProgramInfo
|
||||||
|
{
|
||||||
|
private readonly ulong _processId;
|
||||||
|
public ProgramId ProgramId { get; }
|
||||||
|
public StorageId StorageId { get; }
|
||||||
|
public AccessControl AccessControl { get; }
|
||||||
|
|
||||||
|
public ulong ProgramIdValue => ProgramId.Value;
|
||||||
|
|
||||||
|
private ProgramInfo(FileSystemServer fsServer, ReadOnlySpan<byte> accessControlData,
|
||||||
|
ReadOnlySpan<byte> accessControlDescriptor)
|
||||||
|
{
|
||||||
|
_processId = 0;
|
||||||
|
AccessControl = new AccessControl(fsServer, accessControlData, accessControlDescriptor, ulong.MaxValue);
|
||||||
|
ProgramId = default;
|
||||||
|
StorageId = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProgramInfo(FileSystemServer fsServer, ulong processId, ProgramId programId, StorageId storageId,
|
||||||
|
ReadOnlySpan<byte> accessControlData, ReadOnlySpan<byte> accessControlDescriptor)
|
||||||
|
{
|
||||||
|
_processId = processId;
|
||||||
|
AccessControl = new AccessControl(fsServer, accessControlData, accessControlDescriptor);
|
||||||
|
ProgramId = programId;
|
||||||
|
StorageId = storageId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Contains(ulong processId) => _processId == processId;
|
||||||
|
|
||||||
|
public static ProgramInfo GetProgramInfoForInitialProcess(FileSystemServer fsSrv)
|
||||||
|
{
|
||||||
|
ref ProgramInfoGlobals g = ref fsSrv.Globals.ProgramInfo;
|
||||||
|
using (var guard = new InitializationGuard(ref g.ProgramInfoForInitialProcessInitGuard, fsSrv.Globals.InitMutex))
|
||||||
|
{
|
||||||
|
if (!guard.IsInitialized)
|
||||||
|
{
|
||||||
|
g.ProgramInfoForInitialProcess = new ProgramInfo(fsSrv, InitialProcessAccessControlDataHeader,
|
||||||
|
InitialProcessAccessControlDescriptor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return g.ProgramInfoForInitialProcess;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ReadOnlySpan<byte> InitialProcessAccessControlDataHeader => new byte[]
|
||||||
|
{
|
||||||
|
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x1C, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||||
|
};
|
||||||
|
|
||||||
|
private static ReadOnlySpan<byte> InitialProcessAccessControlDescriptor => new byte[]
|
||||||
|
{
|
||||||
|
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
|
||||||
|
};
|
||||||
|
}
|
|
@ -3,43 +3,31 @@ using System.Collections.Generic;
|
||||||
using LibHac.Common;
|
using LibHac.Common;
|
||||||
using LibHac.Fs;
|
using LibHac.Fs;
|
||||||
using LibHac.Ncm;
|
using LibHac.Ncm;
|
||||||
|
using LibHac.Os;
|
||||||
|
|
||||||
namespace LibHac.FsSrv.Impl;
|
namespace LibHac.FsSrv.Impl;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Handles adding, removing, and accessing <see cref="ProgramInfo"/> from the <see cref="ProgramRegistryImpl"/>.
|
/// Handles adding, removing, and accessing <see cref="ProgramInfo"/> from the <see cref="ProgramRegistryImpl"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>Based on FS 10.0.0 (nnSdk 10.4.0)</remarks>
|
/// <remarks>Based on FS 13.1.0 (nnSdk 13.4.0)</remarks>
|
||||||
internal class ProgramRegistryManager
|
internal class ProgramRegistryManager : IDisposable
|
||||||
{
|
{
|
||||||
// Note: FS keeps each ProgramInfo in a shared_ptr, but there aren't any non-memory resources
|
// Note: FS keeps each ProgramInfo in a shared_ptr, but there aren't any non-memory resources
|
||||||
// that need to be freed, so we use plain ProgramInfos
|
// that need to be freed, so we use plain ProgramInfos
|
||||||
private LinkedList<ProgramInfo> ProgramInfoList { get; }
|
private LinkedList<ProgramInfo> _programInfoList;
|
||||||
private FileSystemServer FsServer { get; }
|
private SdkMutexType _mutex;
|
||||||
|
|
||||||
// Note: This variable is global in FS. It's moved to ProgramRegistryManager here because it
|
private FileSystemServer _fsServer;
|
||||||
// relies on some state kept in FileSystemServer, and it's only used by ProgramRegistryManager
|
|
||||||
private ProgramInfo _programInfoForInitialProcess;
|
|
||||||
private readonly object _programInfoForInitialProcessGuard = new object();
|
|
||||||
|
|
||||||
public ProgramRegistryManager(FileSystemServer fsServer)
|
public ProgramRegistryManager(FileSystemServer fsServer)
|
||||||
{
|
{
|
||||||
ProgramInfoList = new LinkedList<ProgramInfo>();
|
_programInfoList = new LinkedList<ProgramInfo>();
|
||||||
FsServer = fsServer;
|
_mutex = new SdkMutexType();
|
||||||
|
_fsServer = fsServer;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ProgramInfo GetProgramInfoForInitialProcess()
|
public void Dispose() { }
|
||||||
{
|
|
||||||
if (_programInfoForInitialProcess == null)
|
|
||||||
{
|
|
||||||
lock (_programInfoForInitialProcessGuard)
|
|
||||||
{
|
|
||||||
_programInfoForInitialProcess ??= ProgramInfo.CreateProgramInfoForInitialProcess(FsServer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return _programInfoForInitialProcess;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Registers a program with information about that program in the program registry.
|
/// Registers a program with information about that program in the program registry.
|
||||||
|
@ -54,20 +42,19 @@ internal class ProgramRegistryManager
|
||||||
public Result RegisterProgram(ulong processId, ProgramId programId, StorageId storageId,
|
public Result RegisterProgram(ulong processId, ProgramId programId, StorageId storageId,
|
||||||
ReadOnlySpan<byte> accessControlData, ReadOnlySpan<byte> accessControlDescriptor)
|
ReadOnlySpan<byte> accessControlData, ReadOnlySpan<byte> accessControlDescriptor)
|
||||||
{
|
{
|
||||||
var programInfo = new ProgramInfo(FsServer, processId, programId, storageId, accessControlData,
|
var programInfo = new ProgramInfo(_fsServer, processId, programId, storageId, accessControlData,
|
||||||
accessControlDescriptor);
|
accessControlDescriptor);
|
||||||
|
|
||||||
lock (ProgramInfoList)
|
using ScopedLock<SdkMutexType> scopedLock = ScopedLock.Lock(ref _mutex);
|
||||||
{
|
|
||||||
foreach (ProgramInfo info in ProgramInfoList)
|
|
||||||
{
|
|
||||||
if (info.Contains(processId))
|
|
||||||
return ResultFs.InvalidArgument.Log();
|
|
||||||
}
|
|
||||||
|
|
||||||
ProgramInfoList.AddLast(programInfo);
|
foreach (ProgramInfo info in _programInfoList)
|
||||||
return Result.Success;
|
{
|
||||||
|
if (info.Contains(processId))
|
||||||
|
return ResultFs.InvalidArgument.Log();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_programInfoList.AddLast(programInfo);
|
||||||
|
return Result.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -78,19 +65,18 @@ internal class ProgramRegistryManager
|
||||||
/// <see cref="ResultFs.InvalidArgument"/>: The process ID is not registered.</returns>
|
/// <see cref="ResultFs.InvalidArgument"/>: The process ID is not registered.</returns>
|
||||||
public Result UnregisterProgram(ulong processId)
|
public Result UnregisterProgram(ulong processId)
|
||||||
{
|
{
|
||||||
lock (ProgramInfoList)
|
using ScopedLock<SdkMutexType> scopedLock = ScopedLock.Lock(ref _mutex);
|
||||||
{
|
|
||||||
for (LinkedListNode<ProgramInfo> node = ProgramInfoList.First; node != null; node = node.Next)
|
|
||||||
{
|
|
||||||
if (node.Value.Contains(processId))
|
|
||||||
{
|
|
||||||
ProgramInfoList.Remove(node);
|
|
||||||
return Result.Success;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ResultFs.InvalidArgument.Log();
|
for (LinkedListNode<ProgramInfo> node = _programInfoList.First; node != null; node = node.Next)
|
||||||
|
{
|
||||||
|
if (node.Value.Contains(processId))
|
||||||
|
{
|
||||||
|
_programInfoList.Remove(node);
|
||||||
|
return Result.Success;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return ResultFs.InvalidArgument.Log();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -103,26 +89,25 @@ internal class ProgramRegistryManager
|
||||||
/// <see cref="ResultFs.ProgramInfoNotFound"/>: The <see cref="ProgramInfo"/> was not found.</returns>
|
/// <see cref="ResultFs.ProgramInfoNotFound"/>: The <see cref="ProgramInfo"/> was not found.</returns>
|
||||||
public Result GetProgramInfo(out ProgramInfo programInfo, ulong processId)
|
public Result GetProgramInfo(out ProgramInfo programInfo, ulong processId)
|
||||||
{
|
{
|
||||||
lock (ProgramInfoList)
|
using ScopedLock<SdkMutexType> scopedLock = ScopedLock.Lock(ref _mutex);
|
||||||
|
|
||||||
|
if (_fsServer.IsInitialProgram(processId))
|
||||||
{
|
{
|
||||||
if (ProgramInfo.IsInitialProgram(processId))
|
programInfo = ProgramInfo.GetProgramInfoForInitialProcess(_fsServer);
|
||||||
|
return Result.Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (ProgramInfo info in _programInfoList)
|
||||||
|
{
|
||||||
|
if (info.Contains(processId))
|
||||||
{
|
{
|
||||||
programInfo = GetProgramInfoForInitialProcess();
|
programInfo = info;
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (ProgramInfo info in ProgramInfoList)
|
|
||||||
{
|
|
||||||
if (info.Contains(processId))
|
|
||||||
{
|
|
||||||
programInfo = info;
|
|
||||||
return Result.Success;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
UnsafeHelpers.SkipParamInit(out programInfo);
|
|
||||||
return ResultFs.ProgramInfoNotFound.Log();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UnsafeHelpers.SkipParamInit(out programInfo);
|
||||||
|
return ResultFs.ProgramInfoNotFound.Log();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -135,77 +120,18 @@ internal class ProgramRegistryManager
|
||||||
/// <see cref="ResultFs.ProgramInfoNotFound"/>: The <see cref="ProgramInfo"/> was not found.</returns>
|
/// <see cref="ResultFs.ProgramInfoNotFound"/>: The <see cref="ProgramInfo"/> was not found.</returns>
|
||||||
public Result GetProgramInfoByProgramId(out ProgramInfo programInfo, ulong programId)
|
public Result GetProgramInfoByProgramId(out ProgramInfo programInfo, ulong programId)
|
||||||
{
|
{
|
||||||
lock (ProgramInfoList)
|
using ScopedLock<SdkMutexType> scopedLock = ScopedLock.Lock(ref _mutex);
|
||||||
|
|
||||||
|
foreach (ProgramInfo info in _programInfoList)
|
||||||
{
|
{
|
||||||
foreach (ProgramInfo info in ProgramInfoList)
|
if (info.ProgramId.Value == programId)
|
||||||
{
|
{
|
||||||
if (info.ProgramId.Value == programId)
|
programInfo = info;
|
||||||
{
|
return Result.Success;
|
||||||
programInfo = info;
|
|
||||||
return Result.Success;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UnsafeHelpers.SkipParamInit(out programInfo);
|
|
||||||
return ResultFs.ProgramInfoNotFound.Log();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UnsafeHelpers.SkipParamInit(out programInfo);
|
||||||
|
return ResultFs.ProgramInfoNotFound.Log();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ProgramInfo
|
|
||||||
{
|
|
||||||
private ulong ProcessId { get; }
|
|
||||||
public ProgramId ProgramId { get; }
|
|
||||||
public StorageId StorageId { get; }
|
|
||||||
public AccessControl AccessControl { get; }
|
|
||||||
|
|
||||||
public ulong ProgramIdValue => ProgramId.Value;
|
|
||||||
|
|
||||||
public ProgramInfo(FileSystemServer fsServer, ulong processId, ProgramId programId, StorageId storageId,
|
|
||||||
ReadOnlySpan<byte> accessControlData, ReadOnlySpan<byte> accessControlDescriptor)
|
|
||||||
{
|
|
||||||
ProcessId = processId;
|
|
||||||
AccessControl = new AccessControl(fsServer, accessControlData, accessControlDescriptor);
|
|
||||||
ProgramId = programId;
|
|
||||||
StorageId = storageId;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ProgramInfo(FileSystemServer fsServer, ReadOnlySpan<byte> accessControlData,
|
|
||||||
ReadOnlySpan<byte> accessControlDescriptor)
|
|
||||||
{
|
|
||||||
ProcessId = 0;
|
|
||||||
AccessControl = new AccessControl(fsServer, accessControlData, accessControlDescriptor, ulong.MaxValue);
|
|
||||||
ProgramId = default;
|
|
||||||
StorageId = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Contains(ulong processId) => ProcessId == processId;
|
|
||||||
|
|
||||||
public static bool IsInitialProgram(ulong processId)
|
|
||||||
{
|
|
||||||
// Todo: We have no kernel to call into, so use hardcoded values for now
|
|
||||||
const int initialProcessIdLowerBound = 1;
|
|
||||||
const int initialProcessIdUpperBound = 0x50;
|
|
||||||
|
|
||||||
return initialProcessIdLowerBound <= processId && processId <= initialProcessIdUpperBound;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static ProgramInfo CreateProgramInfoForInitialProcess(FileSystemServer fsServer)
|
|
||||||
{
|
|
||||||
return new ProgramInfo(fsServer, InitialProcessAccessControlDataHeader,
|
|
||||||
InitialProcessAccessControlDescriptor);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static ReadOnlySpan<byte> InitialProcessAccessControlDataHeader => new byte[]
|
|
||||||
{
|
|
||||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x1C, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
|
||||||
};
|
|
||||||
|
|
||||||
private static ReadOnlySpan<byte> InitialProcessAccessControlDescriptor => new byte[]
|
|
||||||
{
|
|
||||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
|
@ -50,7 +50,7 @@ public class ProgramRegistryImpl : IProgramRegistry
|
||||||
public Result RegisterProgram(ulong processId, ProgramId programId, StorageId storageId,
|
public Result RegisterProgram(ulong processId, ProgramId programId, StorageId storageId,
|
||||||
InBuffer accessControlData, InBuffer accessControlDescriptor)
|
InBuffer accessControlData, InBuffer accessControlDescriptor)
|
||||||
{
|
{
|
||||||
if (!ProgramInfo.IsInitialProgram(_processId))
|
if (!_fsServer.IsInitialProgram(_processId))
|
||||||
return ResultFs.PermissionDenied.Log();
|
return ResultFs.PermissionDenied.Log();
|
||||||
|
|
||||||
return Globals.ServiceImpl.RegisterProgramInfo(processId, programId, storageId, accessControlData.Buffer,
|
return Globals.ServiceImpl.RegisterProgramInfo(processId, programId, storageId, accessControlData.Buffer,
|
||||||
|
@ -63,7 +63,7 @@ public class ProgramRegistryImpl : IProgramRegistry
|
||||||
/// <inheritdoc cref="ProgramRegistryManager.UnregisterProgram" />
|
/// <inheritdoc cref="ProgramRegistryManager.UnregisterProgram" />
|
||||||
public Result UnregisterProgram(ulong processId)
|
public Result UnregisterProgram(ulong processId)
|
||||||
{
|
{
|
||||||
if (!ProgramInfo.IsInitialProgram(_processId))
|
if (!_fsServer.IsInitialProgram(_processId))
|
||||||
return ResultFs.PermissionDenied.Log();
|
return ResultFs.PermissionDenied.Log();
|
||||||
|
|
||||||
return Globals.ServiceImpl.UnregisterProgramInfo(processId);
|
return Globals.ServiceImpl.UnregisterProgramInfo(processId);
|
||||||
|
|
|
@ -517,7 +517,7 @@ internal class SaveDataFileSystemService : ISaveDataTransferCoreInterface, ISave
|
||||||
// Only the FS process may delete the save indexer's save data.
|
// Only the FS process may delete the save indexer's save data.
|
||||||
if (saveDataId == SaveData.SaveIndexerId)
|
if (saveDataId == SaveData.SaveIndexerId)
|
||||||
{
|
{
|
||||||
if (!IsCurrentProcess(_processId))
|
if (!_serviceImpl.FsServer.IsCurrentProcess(_processId))
|
||||||
return ResultFs.PermissionDenied.Log();
|
return ResultFs.PermissionDenied.Log();
|
||||||
|
|
||||||
actualSpaceId = spaceId;
|
actualSpaceId = spaceId;
|
||||||
|
@ -2157,13 +2157,6 @@ internal class SaveDataFileSystemService : ISaveDataTransferCoreInterface, ISave
|
||||||
return _serviceImpl.GetProgramInfo(out programInfo, _processId);
|
return _serviceImpl.GetProgramInfo(out programInfo, _processId);
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool IsCurrentProcess(ulong processId)
|
|
||||||
{
|
|
||||||
ulong currentId = Hos.Os.GetCurrentProcessId().Value;
|
|
||||||
|
|
||||||
return processId == currentId;
|
|
||||||
}
|
|
||||||
|
|
||||||
private SaveDataSpaceId ConvertToRealSpaceId(SaveDataSpaceId spaceId)
|
private SaveDataSpaceId ConvertToRealSpaceId(SaveDataSpaceId spaceId)
|
||||||
{
|
{
|
||||||
return spaceId == SaveDataSpaceId.ProperSystem || spaceId == SaveDataSpaceId.SafeMode
|
return spaceId == SaveDataSpaceId.ProperSystem || spaceId == SaveDataSpaceId.SafeMode
|
||||||
|
|
|
@ -12,8 +12,6 @@ namespace LibHac;
|
||||||
|
|
||||||
public class Horizon
|
public class Horizon
|
||||||
{
|
{
|
||||||
private const int InitialProcessCountMax = 0x50;
|
|
||||||
|
|
||||||
internal ITickGenerator TickGenerator { get; }
|
internal ITickGenerator TickGenerator { get; }
|
||||||
internal ServiceManager ServiceManager { get; }
|
internal ServiceManager ServiceManager { get; }
|
||||||
private HorizonClient LoaderClient { get; }
|
private HorizonClient LoaderClient { get; }
|
||||||
|
@ -23,7 +21,7 @@ public class Horizon
|
||||||
|
|
||||||
public Horizon(HorizonConfiguration config)
|
public Horizon(HorizonConfiguration config)
|
||||||
{
|
{
|
||||||
_currentProcessId = InitialProcessCountMax;
|
_currentProcessId = OsState.InitialProcessCountMax + 1;
|
||||||
|
|
||||||
TickGenerator = config.TickGenerator ?? new DefaultTickGenerator();
|
TickGenerator = config.TickGenerator ?? new DefaultTickGenerator();
|
||||||
ServiceManager = new ServiceManager();
|
ServiceManager = new ServiceManager();
|
||||||
|
@ -35,7 +33,7 @@ public class Horizon
|
||||||
{
|
{
|
||||||
ulong processId = Interlocked.Increment(ref _currentInitialProcessId);
|
ulong processId = Interlocked.Increment(ref _currentInitialProcessId);
|
||||||
|
|
||||||
Abort.DoAbortUnless(processId <= InitialProcessCountMax, "Created too many privileged clients.");
|
Abort.DoAbortUnless(processId <= OsState.InitialProcessCountMax, "Created too many privileged clients.");
|
||||||
|
|
||||||
// Todo: Register process with FS
|
// Todo: Register process with FS
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,9 @@ namespace LibHac.Os;
|
||||||
|
|
||||||
public class OsState : IDisposable
|
public class OsState : IDisposable
|
||||||
{
|
{
|
||||||
|
internal const int InitialProcessCountMin = 1;
|
||||||
|
internal const int InitialProcessCountMax = 0x50;
|
||||||
|
|
||||||
public OsStateImpl Impl => new OsStateImpl(this);
|
public OsStateImpl Impl => new OsStateImpl(this);
|
||||||
internal HorizonClient Hos { get; }
|
internal HorizonClient Hos { get; }
|
||||||
internal OsResourceManager ResourceManager { get; }
|
internal OsResourceManager ResourceManager { get; }
|
||||||
|
|
Loading…
Reference in a new issue