diff --git a/src/LibHac/FsSrv/AccessLogService.cs b/src/LibHac/FsSrv/AccessLogService.cs new file mode 100644 index 00000000..8f2bf4e5 --- /dev/null +++ b/src/LibHac/FsSrv/AccessLogService.cs @@ -0,0 +1,66 @@ +using System; +using LibHac.Fs; +using LibHac.FsSrv.Impl; +using LibHac.Sf; + +namespace LibHac.FsSrv +{ + internal readonly struct AccessLogService + { + private readonly AccessLogServiceImpl _serviceImpl; + private readonly ulong _processId; + + public AccessLogService(AccessLogServiceImpl serviceImpl, ulong processId) + { + _serviceImpl = serviceImpl; + _processId = processId; + } + + public Result SetAccessLogMode(GlobalAccessLogMode mode) + { + Result rc = GetProgramInfo(out ProgramInfo programInfo); + if (rc.IsFailure()) return rc; + + if (!programInfo.AccessControl.CanCall(OperationType.SetGlobalAccessLogMode)) + return ResultFs.PermissionDenied.Log(); + + _serviceImpl.SetAccessLogMode(mode); + return Result.Success; + } + + public Result GetAccessLogMode(out GlobalAccessLogMode mode) + { + mode = _serviceImpl.GetAccessLogMode(); + return Result.Success; + } + + public Result OutputAccessLogToSdCard(InBuffer textBuffer) + { + Result rc = GetProgramInfo(out ProgramInfo programInfo); + if (rc.IsFailure()) return rc; + + return _serviceImpl.OutputAccessLogToSdCard(textBuffer.Buffer, programInfo.ProgramIdValue, _processId); + } + + public Result OutputMultiProgramTagAccessLog() + { + _serviceImpl.OutputAccessLogToSdCard(MultiProgramTag, _processId).IgnoreResult(); + return Result.Success; + } + + private Result GetProgramInfo(out ProgramInfo programInfo) + { + return _serviceImpl.GetProgramInfo(out programInfo, _processId); + } + + private static ReadOnlySpan MultiProgramTag => // FS_ACCESS: { multi_program_tag: true }\n + new[] + { + (byte) 'F', (byte) 'S', (byte) '_', (byte) 'A', (byte) 'C', (byte) 'C', (byte) 'E', (byte) 'S', + (byte) 'S', (byte) ':', (byte) ' ', (byte) '{', (byte) ' ', (byte) 'm', (byte) 'u', (byte) 'l', + (byte) 't', (byte) 'i', (byte) '_', (byte) 'p', (byte) 'r', (byte) 'o', (byte) 'g', (byte) 'r', + (byte) 'a', (byte) 'm', (byte) '_', (byte) 't', (byte) 'a', (byte) 'g', (byte) ':', (byte) ' ', + (byte) 't', (byte) 'r', (byte) 'u', (byte) 'e', (byte) ' ', (byte) '}', (byte) '\n' + }; + } +} diff --git a/src/LibHac/FsSrv/AccessLogServiceImpl.cs b/src/LibHac/FsSrv/AccessLogServiceImpl.cs new file mode 100644 index 00000000..378610fd --- /dev/null +++ b/src/LibHac/FsSrv/AccessLogServiceImpl.cs @@ -0,0 +1,56 @@ +using System; +using LibHac.Fs; +using LibHac.FsSrv.Impl; + +namespace LibHac.FsSrv +{ + public class AccessLogServiceImpl : IDisposable + { + private Configuration _config; + private GlobalAccessLogMode _accessLogMode; + + public AccessLogServiceImpl(in Configuration configuration) + { + _config = configuration; + } + + public void Dispose() + { + + } + + public struct Configuration + { + public ulong MinimumProgramIdForSdCardLog; + + // LibHac additions + public HorizonClient HorizonClient; + public ProgramRegistryImpl ProgramRegistry; + } + + public void SetAccessLogMode(GlobalAccessLogMode mode) + { + _accessLogMode = mode; + } + + public GlobalAccessLogMode GetAccessLogMode() + { + return _accessLogMode; + } + + public Result OutputAccessLogToSdCard(ReadOnlySpan text, ulong processId) + { + throw new NotImplementedException(); + } + + public Result OutputAccessLogToSdCard(ReadOnlySpan text, ulong programId, ulong processId) + { + throw new NotImplementedException(); + } + + internal Result GetProgramInfo(out ProgramInfo programInfo, ulong processId) + { + return _config.ProgramRegistry.GetProgramInfo(out programInfo, processId); + } + } +} diff --git a/src/LibHac/FsSrv/FileSystemProxyConfiguration.cs b/src/LibHac/FsSrv/FileSystemProxyConfiguration.cs index 72cf7137..d203475c 100644 --- a/src/LibHac/FsSrv/FileSystemProxyConfiguration.cs +++ b/src/LibHac/FsSrv/FileSystemProxyConfiguration.cs @@ -9,5 +9,6 @@ namespace LibHac.FsSrv public NcaFileSystemServiceImpl NcaFileSystemService { get; set; } public SaveDataFileSystemServiceImpl SaveDataFileSystemService { get; set; } public ProgramRegistryServiceImpl ProgramRegistryService { get; set; } + public AccessLogServiceImpl AccessLogService { get; set; } } } diff --git a/src/LibHac/FsSrv/FileSystemProxyImpl.cs b/src/LibHac/FsSrv/FileSystemProxyImpl.cs index f468d307..a81df2ca 100644 --- a/src/LibHac/FsSrv/FileSystemProxyImpl.cs +++ b/src/LibHac/FsSrv/FileSystemProxyImpl.cs @@ -888,14 +888,13 @@ namespace LibHac.FsSrv public Result SetGlobalAccessLogMode(GlobalAccessLogMode mode) { - // Missing permission check + return GetAccessLogService().SetAccessLogMode(mode); - return FsProxyCore.SetGlobalAccessLogMode(mode); } public Result GetGlobalAccessLogMode(out GlobalAccessLogMode mode) { - return FsProxyCore.GetGlobalAccessLogMode(out mode); + return GetAccessLogService().GetAccessLogMode(out mode); } public Result GetProgramIndexForAccessLog(out int programIndex, out int programCount) @@ -903,9 +902,14 @@ namespace LibHac.FsSrv return GetProgramIndexRegistryService().GetProgramIndex(out programIndex, out programCount); } - public Result OutputAccessLogToSdCard(InBuffer logString) + public Result OutputAccessLogToSdCard(InBuffer textBuffer) { - throw new NotImplementedException(); + return GetAccessLogService().OutputAccessLogToSdCard(textBuffer); + } + + public Result OutputMultiProgramTagAccessLog() + { + return GetAccessLogService().OutputMultiProgramTagAccessLog(); } public Result RegisterUpdatePartition() @@ -928,7 +932,7 @@ namespace LibHac.FsSrv return ncaFsService.OpenRegisteredUpdatePartition(out fileSystem); } - public Result OverrideSaveDataTransferTokenSignVerificationKey(ReadOnlySpan key) + public Result OverrideSaveDataTransferTokenSignVerificationKey(InBuffer key) { throw new NotImplementedException(); } @@ -1000,5 +1004,10 @@ namespace LibHac.FsSrv saveFsService = SaveFsService.Target; return Result.Success; } + + private AccessLogService GetAccessLogService() + { + return new AccessLogService(FsProxyCore.Config.AccessLogService, CurrentProcess); + } } } diff --git a/src/LibHac/FsSrv/FileSystemServer.cs b/src/LibHac/FsSrv/FileSystemServer.cs index 265d5e79..6bf841ea 100644 --- a/src/LibHac/FsSrv/FileSystemServer.cs +++ b/src/LibHac/FsSrv/FileSystemServer.cs @@ -136,13 +136,20 @@ namespace LibHac.FsSrv var saveFsService = new SaveDataFileSystemServiceImpl(in saveFsServiceConfig); + var accessLogServiceConfig = new AccessLogServiceImpl.Configuration(); + accessLogServiceConfig.MinimumProgramIdForSdCardLog = 0x0100000000003000; + accessLogServiceConfig.HorizonClient = Hos; + accessLogServiceConfig.ProgramRegistry = programRegistry; + var accessLogService = new AccessLogServiceImpl(in accessLogServiceConfig); + var fspConfig = new FileSystemProxyConfiguration { FsCreatorInterfaces = config.FsCreators, BaseFileSystemService = baseFsService, NcaFileSystemService = ncaFsService, SaveDataFileSystemService = saveFsService, - ProgramRegistryService = programRegistryService + ProgramRegistryService = programRegistryService, + AccessLogService = accessLogService }; return fspConfig; diff --git a/src/LibHac/FsSrv/IFileSystemProxy.cs b/src/LibHac/FsSrv/IFileSystemProxy.cs index 580bf5dd..56b72f81 100644 --- a/src/LibHac/FsSrv/IFileSystemProxy.cs +++ b/src/LibHac/FsSrv/IFileSystemProxy.cs @@ -104,13 +104,14 @@ namespace LibHac.FsSrv Result DisableAutoSaveDataCreation(); Result SetGlobalAccessLogMode(GlobalAccessLogMode mode); Result GetGlobalAccessLogMode(out GlobalAccessLogMode mode); - Result OutputAccessLogToSdCard(InBuffer logString); + Result OutputAccessLogToSdCard(InBuffer textBuffer); Result RegisterUpdatePartition(); Result OpenRegisteredUpdatePartition(out ReferenceCountedDisposable fileSystem); Result GetProgramIndexForAccessLog(out int programIndex, out int programCount); Result UnsetSaveDataRootPath(); - Result OverrideSaveDataTransferTokenSignVerificationKey(ReadOnlySpan key); + Result OutputMultiProgramTagAccessLog(); + Result OverrideSaveDataTransferTokenSignVerificationKey(InBuffer key); Result CorruptSaveDataFileSystemByOffset(SaveDataSpaceId spaceId, ulong saveDataId, long offset); Result OpenMultiCommitManager(out ReferenceCountedDisposable commitManager); Result OpenBisWiper(out ReferenceCountedDisposable bisWiper, NativeHandle transferMemoryHandle, ulong transferMemorySize);