mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2025-02-09 13:14:46 +01:00
Add AccessFailureManagementService
This commit is contained in:
parent
e9f518ddc1
commit
e9918fa5aa
103
src/LibHac/FsSrv/AccessFailureManagementService.cs
Normal file
103
src/LibHac/FsSrv/AccessFailureManagementService.cs
Normal file
@ -0,0 +1,103 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
using LibHac.Fs;
|
||||
using LibHac.FsSrv.Impl;
|
||||
using LibHac.FsSrv.Sf;
|
||||
using LibHac.Sf;
|
||||
|
||||
namespace LibHac.FsSrv
|
||||
{
|
||||
public readonly struct AccessFailureManagementService
|
||||
{
|
||||
private readonly AccessFailureManagementServiceImpl _serviceImpl;
|
||||
private readonly ulong _processId;
|
||||
|
||||
public AccessFailureManagementService(AccessFailureManagementServiceImpl serviceImpl, ulong processId)
|
||||
{
|
||||
_serviceImpl = serviceImpl;
|
||||
_processId = processId;
|
||||
}
|
||||
|
||||
internal Result GetProgramInfo(out ProgramInfo programInfo)
|
||||
{
|
||||
return _serviceImpl.GetProgramInfo(out programInfo, _processId);
|
||||
}
|
||||
|
||||
public Result OpenAccessFailureDetectionEventNotifier(out ReferenceCountedDisposable<IEventNotifier> notifier,
|
||||
ulong processId, bool notifyOnDeepRetry)
|
||||
{
|
||||
notifier = default;
|
||||
|
||||
Result rc = GetProgramInfo(out ProgramInfo programInfo);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
if (!programInfo.AccessControl.CanCall(OperationType.OpenAccessFailureDetectionEventNotifier))
|
||||
return ResultFs.PermissionDenied.Log();
|
||||
|
||||
rc = _serviceImpl.CreateNotifier(out IEventNotifier tempNotifier, processId, notifyOnDeepRetry);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
notifier = new ReferenceCountedDisposable<IEventNotifier>(tempNotifier);
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public Result GetAccessFailureDetectionEvent(out NativeHandle eventHandle)
|
||||
{
|
||||
eventHandle = default;
|
||||
|
||||
Result rc = GetProgramInfo(out ProgramInfo programInfo);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
if (!programInfo.AccessControl.CanCall(OperationType.GetAccessFailureDetectionEvent))
|
||||
return ResultFs.PermissionDenied.Log();
|
||||
|
||||
Svc.Handle handle = _serviceImpl.GetEvent();
|
||||
eventHandle = new NativeHandle(_serviceImpl.HorizonClient.Os, handle, false);
|
||||
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public Result IsAccessFailureDetected(out bool isDetected, ulong processId)
|
||||
{
|
||||
Unsafe.SkipInit(out isDetected);
|
||||
|
||||
Result rc = GetProgramInfo(out ProgramInfo programInfo);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
if (!programInfo.AccessControl.CanCall(OperationType.IsAccessFailureDetected))
|
||||
return ResultFs.PermissionDenied.Log();
|
||||
|
||||
isDetected = _serviceImpl.IsAccessFailureDetectionNotified(processId);
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public Result ResolveAccessFailure(ulong processId)
|
||||
{
|
||||
Result rc = GetProgramInfo(out ProgramInfo programInfo);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
if (!programInfo.AccessControl.CanCall(OperationType.ResolveAccessFailure))
|
||||
return ResultFs.PermissionDenied.Log();
|
||||
|
||||
_serviceImpl.ResetAccessFailureDetection(processId);
|
||||
|
||||
// Todo: Modify ServiceContext
|
||||
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public Result AbandonAccessFailure(ulong processId)
|
||||
{
|
||||
Result rc = GetProgramInfo(out ProgramInfo programInfo);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
if (!programInfo.AccessControl.CanCall(OperationType.AbandonAccessFailure))
|
||||
return ResultFs.PermissionDenied.Log();
|
||||
|
||||
_serviceImpl.DisableAccessFailureDetection(processId);
|
||||
|
||||
// Todo: Modify ServiceContext
|
||||
|
||||
return Result.Success;
|
||||
}
|
||||
}
|
||||
}
|
61
src/LibHac/FsSrv/AccessFailureManagementServiceImpl.cs
Normal file
61
src/LibHac/FsSrv/AccessFailureManagementServiceImpl.cs
Normal file
@ -0,0 +1,61 @@
|
||||
using System;
|
||||
using LibHac.FsSrv.Impl;
|
||||
using LibHac.FsSrv.Sf;
|
||||
using LibHac.Svc;
|
||||
|
||||
namespace LibHac.FsSrv
|
||||
{
|
||||
public class AccessFailureManagementServiceImpl
|
||||
{
|
||||
private ProgramRegistryImpl _programRegistry;
|
||||
internal HorizonClient HorizonClient { get; }
|
||||
private AccessFailureDetectionEventManager _eventManager;
|
||||
|
||||
public AccessFailureManagementServiceImpl(ProgramRegistryImpl programRegistry, HorizonClient horizonClient)
|
||||
{
|
||||
_programRegistry = programRegistry;
|
||||
HorizonClient = horizonClient;
|
||||
_eventManager = new AccessFailureDetectionEventManager();
|
||||
}
|
||||
|
||||
internal Result GetProgramInfo(out ProgramInfo programInfo, ulong processId)
|
||||
{
|
||||
return _programRegistry.GetProgramInfo(out programInfo, processId);
|
||||
}
|
||||
|
||||
public Result CreateNotifier(out IEventNotifier notifier, ulong processId, bool notifyOnDeepRetry)
|
||||
{
|
||||
return _eventManager.CreateNotifier(out notifier, processId, notifyOnDeepRetry);
|
||||
}
|
||||
|
||||
public void ResetAccessFailureDetection(ulong processId)
|
||||
{
|
||||
_eventManager.ResetAccessFailureDetection(processId);
|
||||
}
|
||||
|
||||
public void DisableAccessFailureDetection(ulong processId)
|
||||
{
|
||||
_eventManager.DisableAccessFailureDetection(processId);
|
||||
}
|
||||
|
||||
public void NotifyAccessFailureDetection(ulong processId)
|
||||
{
|
||||
_eventManager.NotifyAccessFailureDetection(processId);
|
||||
}
|
||||
|
||||
public bool IsAccessFailureDetectionNotified(ulong processId)
|
||||
{
|
||||
return _eventManager.IsAccessFailureDetectionNotified(processId);
|
||||
}
|
||||
|
||||
public Handle GetEvent()
|
||||
{
|
||||
return _eventManager.GetEvent();
|
||||
}
|
||||
|
||||
public Result HandleResolubleAccessFailure(out bool wasDeferred, Result nonDeferredResult, ulong processId)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
@ -9,6 +9,7 @@ namespace LibHac.FsSrv
|
||||
public BaseFileSystemServiceImpl BaseFileSystemService { get; set; }
|
||||
public NcaFileSystemServiceImpl NcaFileSystemService { get; set; }
|
||||
public SaveDataFileSystemServiceImpl SaveDataFileSystemService { get; set; }
|
||||
public AccessFailureManagementServiceImpl AccessFailureManagementService { get; set; }
|
||||
public TimeServiceImpl TimeService { get; set; }
|
||||
public StatusReportServiceImpl StatusReportService { get; set; }
|
||||
public ProgramRegistryServiceImpl ProgramRegistryService { get; set; }
|
||||
|
@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.CompilerServices;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
using LibHac.FsSrv.Impl;
|
||||
@ -67,6 +66,12 @@ namespace LibHac.FsSrv
|
||||
return new BaseFileSystemService(FsProxyCore.Config.BaseFileSystemService, CurrentProcess);
|
||||
}
|
||||
|
||||
private AccessFailureManagementService GetAccessFailureManagementService()
|
||||
{
|
||||
return new AccessFailureManagementService(FsProxyCore.Config.AccessFailureManagementService,
|
||||
CurrentProcess);
|
||||
}
|
||||
|
||||
private TimeService GetTimeService()
|
||||
{
|
||||
return new TimeService(FsProxyCore.Config.TimeService, CurrentProcess);
|
||||
@ -128,16 +133,6 @@ namespace LibHac.FsSrv
|
||||
return ncaFsService.OpenCodeFileSystem(out fileSystem, out verificationData, in path, programId);
|
||||
}
|
||||
|
||||
public Result IsArchivedProgram(out bool isArchived, ulong processId)
|
||||
{
|
||||
Unsafe.SkipInit(out isArchived);
|
||||
|
||||
Result rc = GetNcaFileSystemService(out NcaFileSystemService ncaFsService);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
return ncaFsService.IsArchivedProgram(out isArchived, processId);
|
||||
}
|
||||
|
||||
public Result SetCurrentProcess(ulong processId)
|
||||
{
|
||||
CurrentProcess = processId;
|
||||
@ -145,7 +140,8 @@ namespace LibHac.FsSrv
|
||||
// Initialize the NCA file system service
|
||||
NcaFsService = NcaFileSystemService.CreateShared(FsProxyCore.Config.NcaFileSystemService, processId);
|
||||
|
||||
SaveFsService = SaveDataFileSystemService.CreateShared(FsProxyCore.Config.SaveDataFileSystemService, processId);
|
||||
SaveFsService =
|
||||
SaveDataFileSystemService.CreateShared(FsProxyCore.Config.SaveDataFileSystemService, processId);
|
||||
|
||||
return Result.Success;
|
||||
}
|
||||
@ -197,7 +193,8 @@ namespace LibHac.FsSrv
|
||||
return ncaFsService.OpenDataStorageByCurrentProcess(out storage);
|
||||
}
|
||||
|
||||
public Result OpenDataStorageByProgramId(out ReferenceCountedDisposable<IStorageSf> storage, ProgramId programId)
|
||||
public Result OpenDataStorageByProgramId(out ReferenceCountedDisposable<IStorageSf> storage,
|
||||
ProgramId programId)
|
||||
{
|
||||
Result rc = GetNcaFileSystemService(out NcaFileSystemService ncaFsService);
|
||||
if (rc.IsFailure())
|
||||
@ -209,7 +206,8 @@ namespace LibHac.FsSrv
|
||||
return ncaFsService.OpenDataStorageByProgramId(out storage, programId);
|
||||
}
|
||||
|
||||
public Result OpenDataStorageByDataId(out ReferenceCountedDisposable<IStorageSf> storage, DataId dataId, StorageId storageId)
|
||||
public Result OpenDataStorageByDataId(out ReferenceCountedDisposable<IStorageSf> storage, DataId dataId,
|
||||
StorageId storageId)
|
||||
{
|
||||
Result rc = GetNcaFileSystemService(out NcaFileSystemService ncaFsService);
|
||||
if (rc.IsFailure())
|
||||
@ -240,7 +238,8 @@ namespace LibHac.FsSrv
|
||||
return ncaFsService.OpenDataFileSystemWithProgramIndex(out fileSystem, programIndex);
|
||||
}
|
||||
|
||||
public Result OpenDataStorageWithProgramIndex(out ReferenceCountedDisposable<IStorageSf> storage, byte programIndex)
|
||||
public Result OpenDataStorageWithProgramIndex(out ReferenceCountedDisposable<IStorageSf> storage,
|
||||
byte programIndex)
|
||||
{
|
||||
Result rc = GetNcaFileSystemService(out NcaFileSystemService ncaFsService);
|
||||
if (rc.IsFailure())
|
||||
@ -276,7 +275,8 @@ namespace LibHac.FsSrv
|
||||
return saveFsService.DeleteSaveDataFileSystemBySaveDataSpaceId(spaceId, saveDataId);
|
||||
}
|
||||
|
||||
public Result DeleteSaveDataFileSystemBySaveDataAttribute(SaveDataSpaceId spaceId, in SaveDataAttribute attribute)
|
||||
public Result DeleteSaveDataFileSystemBySaveDataAttribute(SaveDataSpaceId spaceId,
|
||||
in SaveDataAttribute attribute)
|
||||
{
|
||||
Result rc = GetSaveDataFileSystemService(out SaveDataFileSystemService saveFsService);
|
||||
if (rc.IsFailure()) return rc;
|
||||
@ -797,7 +797,8 @@ namespace LibHac.FsSrv
|
||||
return saveFsService.UnsetSaveDataRootPath();
|
||||
}
|
||||
|
||||
public Result OpenContentStorageFileSystem(out ReferenceCountedDisposable<IFileSystemSf> fileSystem, ContentStorageId storageId)
|
||||
public Result OpenContentStorageFileSystem(out ReferenceCountedDisposable<IFileSystemSf> fileSystem,
|
||||
ContentStorageId storageId)
|
||||
{
|
||||
Result rc = GetNcaFileSystemService(out NcaFileSystemService ncaFsService);
|
||||
if (rc.IsFailure())
|
||||
@ -843,7 +844,8 @@ namespace LibHac.FsSrv
|
||||
}
|
||||
}
|
||||
|
||||
public Result OpenCustomStorageFileSystem(out ReferenceCountedDisposable<IFileSystemSf> fileSystem, CustomStorageId storageId)
|
||||
public Result OpenCustomStorageFileSystem(out ReferenceCountedDisposable<IFileSystemSf> fileSystem,
|
||||
CustomStorageId storageId)
|
||||
{
|
||||
fileSystem = default;
|
||||
var storageFlag = StorageType.NonGameCard;
|
||||
@ -885,6 +887,16 @@ namespace LibHac.FsSrv
|
||||
return GetBaseFileSystemService().OpenGameCardFileSystem(out fileSystem, handle, partitionId);
|
||||
}
|
||||
|
||||
public Result IsArchivedProgram(out bool isArchived, ulong processId)
|
||||
{
|
||||
Unsafe.SkipInit(out isArchived);
|
||||
|
||||
Result rc = GetNcaFileSystemService(out NcaFileSystemService ncaFsService);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
return ncaFsService.IsArchivedProgram(out isArchived, processId);
|
||||
}
|
||||
|
||||
public Result QuerySaveDataTotalSize(out long totalSize, long dataSize, long journalSize)
|
||||
{
|
||||
Unsafe.SkipInit(out totalSize);
|
||||
@ -1135,27 +1147,28 @@ namespace LibHac.FsSrv
|
||||
public Result OpenAccessFailureDetectionEventNotifier(out ReferenceCountedDisposable<IEventNotifier> notifier,
|
||||
ulong processId, bool notifyOnDeepRetry)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
return GetAccessFailureManagementService()
|
||||
.OpenAccessFailureDetectionEventNotifier(out notifier, processId, notifyOnDeepRetry);
|
||||
}
|
||||
|
||||
public Result GetAccessFailureDetectionEvent(out NativeHandle eventHandle)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
return GetAccessFailureManagementService().GetAccessFailureDetectionEvent(out eventHandle);
|
||||
}
|
||||
|
||||
public Result IsAccessFailureDetected(out bool isDetected, ulong processId)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
return GetAccessFailureManagementService().IsAccessFailureDetected(out isDetected, processId);
|
||||
}
|
||||
|
||||
public Result ResolveAccessFailure(ulong processId)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
return GetAccessFailureManagementService().ResolveAccessFailure(processId);
|
||||
}
|
||||
|
||||
public Result AbandonAccessFailure(ulong processId)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
return GetAccessFailureManagementService().AbandonAccessFailure(processId);
|
||||
}
|
||||
|
||||
public Result OpenMultiCommitManager(out ReferenceCountedDisposable<IMultiCommitManager> commitManager)
|
||||
|
@ -128,6 +128,8 @@ namespace LibHac.FsSrv
|
||||
baseFsServiceConfig.ProgramRegistry = programRegistry;
|
||||
var baseFsService = new BaseFileSystemServiceImpl(in baseFsServiceConfig);
|
||||
|
||||
var accessFailureManagementService = new AccessFailureManagementServiceImpl(programRegistry, Hos);
|
||||
|
||||
var ncaFsServiceConfig = new NcaFileSystemServiceImpl.Configuration();
|
||||
ncaFsServiceConfig.BaseFsService = baseFsService;
|
||||
ncaFsServiceConfig.HostFsCreator = config.FsCreators.HostFileSystemCreator;
|
||||
@ -186,6 +188,7 @@ namespace LibHac.FsSrv
|
||||
BaseFileSystemService = baseFsService,
|
||||
NcaFileSystemService = ncaFsService,
|
||||
SaveDataFileSystemService = saveFsService,
|
||||
AccessFailureManagementService = accessFailureManagementService,
|
||||
TimeService = timeService,
|
||||
StatusReportService = statusReportService,
|
||||
ProgramRegistryService = programRegistryService,
|
||||
|
39
src/LibHac/FsSrv/Impl/AccessFailureDetectionEventManager.cs
Normal file
39
src/LibHac/FsSrv/Impl/AccessFailureDetectionEventManager.cs
Normal file
@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using LibHac.FsSrv.Sf;
|
||||
using LibHac.Svc;
|
||||
|
||||
namespace LibHac.FsSrv.Impl
|
||||
{
|
||||
public class AccessFailureDetectionEventManager
|
||||
{
|
||||
public Result CreateNotifier(out IEventNotifier notifier, ulong processId, bool notifyOnDeepRetry)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void NotifyAccessFailureDetection(ulong processId)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void ResetAccessFailureDetection(ulong processId)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void DisableAccessFailureDetection(ulong processId)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool IsAccessFailureDetectionNotified(ulong processId)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Handle GetEvent()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
10
src/LibHac/Os/NativeHandle.cs
Normal file
10
src/LibHac/Os/NativeHandle.cs
Normal file
@ -0,0 +1,10 @@
|
||||
namespace LibHac.Os
|
||||
{
|
||||
public static class NativeHandleApi
|
||||
{
|
||||
public static void CloseNativeHandle(this OsState os, object handle)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -1,21 +1,31 @@
|
||||
namespace LibHac.Sf
|
||||
using System;
|
||||
using LibHac.Os;
|
||||
using LibHac.Svc;
|
||||
|
||||
namespace LibHac.Sf
|
||||
{
|
||||
// How should this be handled? Using a C# struct would be more accurate, but C#
|
||||
// doesn't have copy constructors or any way to prevent a struct from being copied.
|
||||
public class NativeHandle
|
||||
public class NativeHandle : IDisposable
|
||||
{
|
||||
public uint Handle { get; private set; }
|
||||
private OsState Os { get; }
|
||||
public Handle Handle { get; private set; }
|
||||
public bool IsManaged { get; private set; }
|
||||
|
||||
public NativeHandle(uint handle)
|
||||
public NativeHandle(OsState os, Handle handle)
|
||||
{
|
||||
Os = os;
|
||||
Handle = handle;
|
||||
}
|
||||
|
||||
public NativeHandle(uint handle, bool isManaged)
|
||||
public NativeHandle(OsState os, Handle handle, bool isManaged)
|
||||
{
|
||||
Handle = handle;
|
||||
IsManaged = isManaged;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (IsManaged)
|
||||
Os.CloseNativeHandle(Handle.Object);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
12
src/LibHac/Svc/Handle.cs
Normal file
12
src/LibHac/Svc/Handle.cs
Normal file
@ -0,0 +1,12 @@
|
||||
namespace LibHac.Svc
|
||||
{
|
||||
public readonly struct Handle
|
||||
{
|
||||
public readonly object Object;
|
||||
|
||||
public Handle(object obj)
|
||||
{
|
||||
Object = obj;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user