diff --git a/src/Ryujinx.HLE/HOS/Horizon.cs b/src/Ryujinx.HLE/HOS/Horizon.cs index 34ab0d39..1639532e 100644 --- a/src/Ryujinx.HLE/HOS/Horizon.cs +++ b/src/Ryujinx.HLE/HOS/Horizon.cs @@ -327,7 +327,7 @@ namespace Ryujinx.HLE.HOS private void StartNewServices() { ServiceTable = new ServiceTable(); - var services = ServiceTable.GetServices(new HorizonOptions(Device.Configuration.IgnoreMissingServices, LibHacHorizonManager.BcatClient)); + var services = ServiceTable.GetServices(new HorizonOptions(Device.Configuration.IgnoreMissingServices)); foreach (var service in services) { diff --git a/src/Ryujinx.HLE/HOS/Services/Bcat/IServiceCreator.cs b/src/Ryujinx.HLE/HOS/Services/Bcat/IServiceCreator.cs new file mode 100644 index 00000000..1437a8e1 --- /dev/null +++ b/src/Ryujinx.HLE/HOS/Services/Bcat/IServiceCreator.cs @@ -0,0 +1,85 @@ +using LibHac; +using LibHac.Common; +using Ryujinx.Common; +using Ryujinx.HLE.HOS.Services.Arp; +using Ryujinx.HLE.HOS.Services.Bcat.ServiceCreator; + +namespace Ryujinx.HLE.HOS.Services.Bcat +{ + [Service("bcat:a", "bcat:a")] + [Service("bcat:m", "bcat:m")] + [Service("bcat:u", "bcat:u")] + [Service("bcat:s", "bcat:s")] + class IServiceCreator : DisposableIpcService + { + private SharedRef _base; + + public IServiceCreator(ServiceCtx context, string serviceName) + { + var applicationClient = context.Device.System.LibHacHorizonManager.ApplicationClient; + applicationClient.Sm.GetService(ref _base, serviceName).ThrowIfFailure(); + } + + protected override void Dispose(bool isDisposing) + { + if (isDisposing) + { + _base.Destroy(); + } + } + + [CommandCmif(0)] + // CreateBcatService(pid) -> object + public ResultCode CreateBcatService(ServiceCtx context) + { + // TODO: Call arp:r GetApplicationLaunchProperty with the pid to get the TitleId. + // Add an instance of nn::bcat::detail::service::core::PassphraseManager. + // Add an instance of nn::bcat::detail::service::ServiceMemoryManager. + // Add an instance of nn::bcat::detail::service::core::TaskManager who load "bcat-sys:/" system save data and open "dc/task.bin". + // If the file don't exist, create a new one (size of 0x800) and write 2 empty struct with a size of 0x400. + + MakeObject(context, new IBcatService(ApplicationLaunchProperty.GetByPid(context))); + + // NOTE: If the IBcatService is null this error is returned, Doesn't occur in our case. + // return ResultCode.NullObject; + + return ResultCode.Success; + } + + [CommandCmif(1)] + // CreateDeliveryCacheStorageService(pid) -> object + public ResultCode CreateDeliveryCacheStorageService(ServiceCtx context) + { + ulong pid = context.RequestData.ReadUInt64(); + + using var serv = new SharedRef(); + + Result rc = _base.Get.CreateDeliveryCacheStorageService(ref serv.Ref, pid); + + if (rc.IsSuccess()) + { + MakeObject(context, new IDeliveryCacheStorageService(context, ref serv.Ref)); + } + + return (ResultCode)rc.Value; + } + + [CommandCmif(2)] + // CreateDeliveryCacheStorageServiceWithApplicationId(nn::ApplicationId) -> object + public ResultCode CreateDeliveryCacheStorageServiceWithApplicationId(ServiceCtx context) + { + ApplicationId applicationId = context.RequestData.ReadStruct(); + + using var service = new SharedRef(); + + Result rc = _base.Get.CreateDeliveryCacheStorageServiceWithApplicationId(ref service.Ref, applicationId); + + if (rc.IsSuccess()) + { + MakeObject(context, new IDeliveryCacheStorageService(context, ref service.Ref)); + } + + return (ResultCode)rc.Value; + } + } +} diff --git a/src/Ryujinx.HLE/HOS/Services/Bcat/ResultCode.cs b/src/Ryujinx.HLE/HOS/Services/Bcat/ResultCode.cs new file mode 100644 index 00000000..7f1b313e --- /dev/null +++ b/src/Ryujinx.HLE/HOS/Services/Bcat/ResultCode.cs @@ -0,0 +1,29 @@ +namespace Ryujinx.HLE.HOS.Services.Bcat +{ + enum ResultCode + { + ModuleId = 122, + ErrorCodeShift = 9, + + Success = 0, + + InvalidArgument = (1 << ErrorCodeShift) | ModuleId, + NotFound = (2 << ErrorCodeShift) | ModuleId, + TargetLocked = (3 << ErrorCodeShift) | ModuleId, + TargetAlreadyMounted = (4 << ErrorCodeShift) | ModuleId, + TargetNotMounted = (5 << ErrorCodeShift) | ModuleId, + AlreadyOpen = (6 << ErrorCodeShift) | ModuleId, + NotOpen = (7 << ErrorCodeShift) | ModuleId, + InternetRequestDenied = (8 << ErrorCodeShift) | ModuleId, + ServiceOpenLimitReached = (9 << ErrorCodeShift) | ModuleId, + SaveDataNotFound = (10 << ErrorCodeShift) | ModuleId, + NetworkServiceAccountNotAvailable = (31 << ErrorCodeShift) | ModuleId, + PassphrasePathNotFound = (80 << ErrorCodeShift) | ModuleId, + DataVerificationFailed = (81 << ErrorCodeShift) | ModuleId, + PermissionDenied = (90 << ErrorCodeShift) | ModuleId, + AllocationFailed = (91 << ErrorCodeShift) | ModuleId, + InvalidOperation = (98 << ErrorCodeShift) | ModuleId, + InvalidDeliveryCacheStorageFile = (204 << ErrorCodeShift) | ModuleId, + StorageOpenLimitReached = (205 << ErrorCodeShift) | ModuleId + } +} diff --git a/src/Ryujinx.HLE/HOS/Services/Bcat/ServiceCreator/IBcatService.cs b/src/Ryujinx.HLE/HOS/Services/Bcat/ServiceCreator/IBcatService.cs new file mode 100644 index 00000000..fb11ceda --- /dev/null +++ b/src/Ryujinx.HLE/HOS/Services/Bcat/ServiceCreator/IBcatService.cs @@ -0,0 +1,18 @@ +using Ryujinx.HLE.HOS.Services.Arp; + +namespace Ryujinx.HLE.HOS.Services.Bcat.ServiceCreator +{ + class IBcatService : IpcService + { + public IBcatService(ApplicationLaunchProperty applicationLaunchProperty) { } + + [CommandCmif(10100)] + // RequestSyncDeliveryCache() -> object + public ResultCode RequestSyncDeliveryCache(ServiceCtx context) + { + MakeObject(context, new IDeliveryCacheProgressService(context)); + + return ResultCode.Success; + } + } +} \ No newline at end of file diff --git a/src/Ryujinx.HLE/HOS/Services/Bcat/ServiceCreator/IDeliveryCacheDirectoryService.cs b/src/Ryujinx.HLE/HOS/Services/Bcat/ServiceCreator/IDeliveryCacheDirectoryService.cs new file mode 100644 index 00000000..57544977 --- /dev/null +++ b/src/Ryujinx.HLE/HOS/Services/Bcat/ServiceCreator/IDeliveryCacheDirectoryService.cs @@ -0,0 +1,65 @@ +using LibHac; +using LibHac.Bcat; +using LibHac.Common; +using Ryujinx.Common; +using System.Runtime.InteropServices; + +namespace Ryujinx.HLE.HOS.Services.Bcat.ServiceCreator +{ + class IDeliveryCacheDirectoryService : DisposableIpcService + { + private SharedRef _base; + + public IDeliveryCacheDirectoryService(ref SharedRef baseService) + { + _base = SharedRef.CreateMove(ref baseService); + } + + protected override void Dispose(bool isDisposing) + { + if (isDisposing) + { + _base.Destroy(); + } + } + + [CommandCmif(0)] + // Open(nn::bcat::DirectoryName) + public ResultCode Open(ServiceCtx context) + { + DirectoryName directoryName = context.RequestData.ReadStruct(); + + Result result = _base.Get.Open(ref directoryName); + + return (ResultCode)result.Value; + } + + [CommandCmif(1)] + // Read() -> (u32, buffer) + public ResultCode Read(ServiceCtx context) + { + ulong bufferAddress = context.Request.ReceiveBuff[0].Position; + ulong bufferLen = context.Request.ReceiveBuff[0].Size; + + using (var region = context.Memory.GetWritableRegion(bufferAddress, (int)bufferLen, true)) + { + Result result = _base.Get.Read(out int entriesRead, MemoryMarshal.Cast(region.Memory.Span)); + + context.ResponseData.Write(entriesRead); + + return (ResultCode)result.Value; + } + } + + [CommandCmif(2)] + // GetCount() -> u32 + public ResultCode GetCount(ServiceCtx context) + { + Result result = _base.Get.GetCount(out int count); + + context.ResponseData.Write(count); + + return (ResultCode)result.Value; + } + } +} diff --git a/src/Ryujinx.HLE/HOS/Services/Bcat/ServiceCreator/IDeliveryCacheFileService.cs b/src/Ryujinx.HLE/HOS/Services/Bcat/ServiceCreator/IDeliveryCacheFileService.cs new file mode 100644 index 00000000..5a9110e6 --- /dev/null +++ b/src/Ryujinx.HLE/HOS/Services/Bcat/ServiceCreator/IDeliveryCacheFileService.cs @@ -0,0 +1,78 @@ +using LibHac; +using LibHac.Bcat; +using LibHac.Common; +using Ryujinx.Common; + +namespace Ryujinx.HLE.HOS.Services.Bcat.ServiceCreator +{ + class IDeliveryCacheFileService : DisposableIpcService + { + private SharedRef _base; + + public IDeliveryCacheFileService(ref SharedRef baseService) + { + _base = SharedRef.CreateMove(ref baseService); + } + + protected override void Dispose(bool isDisposing) + { + if (isDisposing) + { + _base.Destroy(); + } + } + + [CommandCmif(0)] + // Open(nn::bcat::DirectoryName, nn::bcat::FileName) + public ResultCode Open(ServiceCtx context) + { + DirectoryName directoryName = context.RequestData.ReadStruct(); + FileName fileName = context.RequestData.ReadStruct(); + + Result result = _base.Get.Open(ref directoryName, ref fileName); + + return (ResultCode)result.Value; + } + + [CommandCmif(1)] + // Read(u64) -> (u64, buffer) + public ResultCode Read(ServiceCtx context) + { + ulong bufferAddress = context.Request.ReceiveBuff[0].Position; + ulong bufferLen = context.Request.ReceiveBuff[0].Size; + + long offset = context.RequestData.ReadInt64(); + + using (var region = context.Memory.GetWritableRegion(bufferAddress, (int)bufferLen, true)) + { + Result result = _base.Get.Read(out long bytesRead, offset, region.Memory.Span); + + context.ResponseData.Write(bytesRead); + + return (ResultCode)result.Value; + } + } + + [CommandCmif(2)] + // GetSize() -> u64 + public ResultCode GetSize(ServiceCtx context) + { + Result result = _base.Get.GetSize(out long size); + + context.ResponseData.Write(size); + + return (ResultCode)result.Value; + } + + [CommandCmif(3)] + // GetDigest() -> nn::bcat::Digest + public ResultCode GetDigest(ServiceCtx context) + { + Result result = _base.Get.GetDigest(out Digest digest); + + context.ResponseData.WriteStruct(digest); + + return (ResultCode)result.Value; + } + } +} diff --git a/src/Ryujinx.HLE/HOS/Services/Bcat/ServiceCreator/IDeliveryCacheProgressService.cs b/src/Ryujinx.HLE/HOS/Services/Bcat/ServiceCreator/IDeliveryCacheProgressService.cs new file mode 100644 index 00000000..1555f170 --- /dev/null +++ b/src/Ryujinx.HLE/HOS/Services/Bcat/ServiceCreator/IDeliveryCacheProgressService.cs @@ -0,0 +1,63 @@ +using Ryujinx.Common.Logging; +using Ryujinx.Cpu; +using Ryujinx.HLE.HOS.Ipc; +using Ryujinx.HLE.HOS.Kernel.Threading; +using Ryujinx.HLE.HOS.Services.Bcat.ServiceCreator.Types; +using Ryujinx.Horizon.Common; +using System; + +namespace Ryujinx.HLE.HOS.Services.Bcat.ServiceCreator +{ + class IDeliveryCacheProgressService : IpcService + { + private KEvent _event; + private int _eventHandle; + + public IDeliveryCacheProgressService(ServiceCtx context) + { + _event = new KEvent(context.Device.System.KernelContext); + } + + [CommandCmif(0)] + // GetEvent() -> handle + public ResultCode GetEvent(ServiceCtx context) + { + if (_eventHandle == 0) + { + if (context.Process.HandleTable.GenerateHandle(_event.ReadableEvent, out _eventHandle) != Result.Success) + { + throw new InvalidOperationException("Out of handles!"); + } + } + + context.Response.HandleDesc = IpcHandleDesc.MakeCopy(_eventHandle); + + Logger.Stub?.PrintStub(LogClass.ServiceBcat); + + return ResultCode.Success; + } + + [CommandCmif(1)] + // GetImpl() -> buffer + public ResultCode GetImpl(ServiceCtx context) + { + DeliveryCacheProgressImpl deliveryCacheProgress = new DeliveryCacheProgressImpl + { + State = DeliveryCacheProgressImpl.Status.Done, + Result = 0 + }; + + ulong dcpSize = WriteDeliveryCacheProgressImpl(context, context.Request.RecvListBuff[0], deliveryCacheProgress); + context.Response.PtrBuff[0] = context.Response.PtrBuff[0].WithSize(dcpSize); + + Logger.Stub?.PrintStub(LogClass.ServiceBcat); + + return ResultCode.Success; + } + + private ulong WriteDeliveryCacheProgressImpl(ServiceCtx context, IpcRecvListBuffDesc ipcDesc, DeliveryCacheProgressImpl deliveryCacheProgress) + { + return MemoryHelper.Write(context.Memory, ipcDesc.Position, deliveryCacheProgress); + } + } +} \ No newline at end of file diff --git a/src/Ryujinx.HLE/HOS/Services/Bcat/ServiceCreator/IDeliveryCacheStorageService.cs b/src/Ryujinx.HLE/HOS/Services/Bcat/ServiceCreator/IDeliveryCacheStorageService.cs new file mode 100644 index 00000000..be77226c --- /dev/null +++ b/src/Ryujinx.HLE/HOS/Services/Bcat/ServiceCreator/IDeliveryCacheStorageService.cs @@ -0,0 +1,74 @@ +using LibHac; +using LibHac.Bcat; +using LibHac.Common; +using System.Runtime.InteropServices; + +namespace Ryujinx.HLE.HOS.Services.Bcat.ServiceCreator +{ + class IDeliveryCacheStorageService : DisposableIpcService + { + private SharedRef _base; + + public IDeliveryCacheStorageService(ServiceCtx context, ref SharedRef baseService) + { + _base = SharedRef.CreateMove(ref baseService); + } + + [CommandCmif(0)] + // CreateFileService() -> object + public ResultCode CreateFileService(ServiceCtx context) + { + using var service = new SharedRef(); + + Result result = _base.Get.CreateFileService(ref service.Ref); + + if (result.IsSuccess()) + { + MakeObject(context, new IDeliveryCacheFileService(ref service.Ref)); + } + + return (ResultCode)result.Value; + } + + [CommandCmif(1)] + // CreateDirectoryService() -> object + public ResultCode CreateDirectoryService(ServiceCtx context) + { + using var service = new SharedRef(); + + Result result = _base.Get.CreateDirectoryService(ref service.Ref); + + if (result.IsSuccess()) + { + MakeObject(context, new IDeliveryCacheDirectoryService(ref service.Ref)); + } + + return (ResultCode)result.Value; + } + + [CommandCmif(10)] + // EnumerateDeliveryCacheDirectory() -> (u32, buffer) + public ResultCode EnumerateDeliveryCacheDirectory(ServiceCtx context) + { + ulong bufferAddress = context.Request.ReceiveBuff[0].Position; + ulong bufferLen = context.Request.ReceiveBuff[0].Size; + + using (var region = context.Memory.GetWritableRegion(bufferAddress, (int)bufferLen, true)) + { + Result result = _base.Get.EnumerateDeliveryCacheDirectory(out int count, MemoryMarshal.Cast(region.Memory.Span)); + + context.ResponseData.Write(count); + + return (ResultCode)result.Value; + } + } + + protected override void Dispose(bool isDisposing) + { + if (isDisposing) + { + _base.Destroy(); + } + } + } +} diff --git a/src/Ryujinx.Horizon/Bcat/Ipc/ServiceCreator/Types/DeliveryCacheProgressImpl.cs b/src/Ryujinx.HLE/HOS/Services/Bcat/ServiceCreator/Types/DeliveryCacheProgressImpl.cs similarity index 86% rename from src/Ryujinx.Horizon/Bcat/Ipc/ServiceCreator/Types/DeliveryCacheProgressImpl.cs rename to src/Ryujinx.HLE/HOS/Services/Bcat/ServiceCreator/Types/DeliveryCacheProgressImpl.cs index 10e0b54f..fb9a67be 100644 --- a/src/Ryujinx.Horizon/Bcat/Ipc/ServiceCreator/Types/DeliveryCacheProgressImpl.cs +++ b/src/Ryujinx.HLE/HOS/Services/Bcat/ServiceCreator/Types/DeliveryCacheProgressImpl.cs @@ -1,6 +1,6 @@ using System.Runtime.InteropServices; -namespace Ryujinx.Horizon.Bcat.Ipc.Types +namespace Ryujinx.HLE.HOS.Services.Bcat.ServiceCreator.Types { [StructLayout(LayoutKind.Sequential, Size = 0x200)] public struct DeliveryCacheProgressImpl diff --git a/src/Ryujinx.Horizon/Bcat/BcatIpcServer.cs b/src/Ryujinx.Horizon/Bcat/BcatIpcServer.cs deleted file mode 100644 index 4a5378af..00000000 --- a/src/Ryujinx.Horizon/Bcat/BcatIpcServer.cs +++ /dev/null @@ -1,48 +0,0 @@ -using Ryujinx.Horizon.Bcat.Ipc; -using Ryujinx.Horizon.Bcat.Types; -using Ryujinx.Horizon.Sdk.Sf.Hipc; -using Ryujinx.Horizon.Sdk.Sm; - -namespace Ryujinx.Horizon.Bcat -{ - internal class BcatIpcServer - { - private const int BcatMaxSessionsCount = 8; - private const int BcatTotalMaxSessionsCount = BcatMaxSessionsCount * 4; - - private const int PointerBufferSize = 0x400; - private const int MaxDomains = 64; - private const int MaxDomainObjects = 64; - private const int MaxPortsCount = 4; - - private SmApi _sm; - private BcatServerManager _serverManager; - - private static readonly ManagerOptions _bcatManagerOptions = new(PointerBufferSize, MaxDomains, MaxDomainObjects, false); - - internal void Initialize() - { - HeapAllocator allocator = new(); - - _sm = new SmApi(); - _sm.Initialize().AbortOnFailure(); - - _serverManager = new BcatServerManager(allocator, _sm, MaxPortsCount, _bcatManagerOptions, BcatTotalMaxSessionsCount); - - _serverManager.RegisterServer((int)BcatPortIndex.Admin, ServiceName.Encode("bcat:a"), BcatMaxSessionsCount); - _serverManager.RegisterServer((int)BcatPortIndex.Manager, ServiceName.Encode("bcat:m"), BcatMaxSessionsCount); - _serverManager.RegisterServer((int)BcatPortIndex.User, ServiceName.Encode("bcat:u"), BcatMaxSessionsCount); - _serverManager.RegisterServer((int)BcatPortIndex.System, ServiceName.Encode("bcat:s"), BcatMaxSessionsCount); - } - - public void ServiceRequests() - { - _serverManager.ServiceRequests(); - } - - public void Shutdown() - { - _serverManager.Dispose(); - } - } -} diff --git a/src/Ryujinx.Horizon/Bcat/BcatMain.cs b/src/Ryujinx.Horizon/Bcat/BcatMain.cs deleted file mode 100644 index d4166fb1..00000000 --- a/src/Ryujinx.Horizon/Bcat/BcatMain.cs +++ /dev/null @@ -1,24 +0,0 @@ -using Ryujinx.Horizon.LogManager; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Ryujinx.Horizon.Bcat -{ - internal class BcatMain : IService - { - public static void Main(ServiceTable serviceTable) - { - BcatIpcServer ipcServer = new(); - - ipcServer.Initialize(); - - serviceTable.SignalServiceReady(); - - ipcServer.ServiceRequests(); - ipcServer.Shutdown(); - } - } -} diff --git a/src/Ryujinx.Horizon/Bcat/BcatResult.cs b/src/Ryujinx.Horizon/Bcat/BcatResult.cs deleted file mode 100644 index 014c52e7..00000000 --- a/src/Ryujinx.Horizon/Bcat/BcatResult.cs +++ /dev/null @@ -1,29 +0,0 @@ -using Ryujinx.Horizon.Common; - -namespace Ryujinx.Horizon.Bcat -{ - class BcatResult - { - private const int ModuleId = 122; - - public static Result Success => new(ModuleId, 0); - public static Result InvalidArgument => new(ModuleId, 1); - public static Result NotFound => new(ModuleId, 2); - public static Result TargetLocked => new(ModuleId, 3); - public static Result TargetAlreadyMounted => new(ModuleId, 4); - public static Result TargetNotMounted => new(ModuleId, 5); - public static Result AlreadyOpen => new(ModuleId, 6); - public static Result NotOpen => new(ModuleId, 7); - public static Result InternetRequestDenied => new(ModuleId, 8); - public static Result ServiceOpenLimitReached => new(ModuleId, 9); - public static Result SaveDataNotFound => new(ModuleId, 10); - public static Result NetworkServiceAccountNotAvailable => new(ModuleId, 31); - public static Result PassphrasePathNotFound => new(ModuleId, 80); - public static Result DataVerificationFailed => new(ModuleId, 81); - public static Result PermissionDenied => new(ModuleId, 90); - public static Result AllocationFailed => new(ModuleId, 91); - public static Result InvalidOperation => new(ModuleId, 98); - public static Result InvalidDeliveryCacheStorageFile => new(ModuleId, 204); - public static Result StorageOpenLimitReached => new(ModuleId, 205); - } -} diff --git a/src/Ryujinx.Horizon/Bcat/BcatServerManager.cs b/src/Ryujinx.Horizon/Bcat/BcatServerManager.cs deleted file mode 100644 index 953f6a22..00000000 --- a/src/Ryujinx.Horizon/Bcat/BcatServerManager.cs +++ /dev/null @@ -1,28 +0,0 @@ -using Ryujinx.Horizon.Bcat.Ipc; -using Ryujinx.Horizon.Bcat.Types; -using Ryujinx.Horizon.Common; -using Ryujinx.Horizon.Sdk.Sf.Hipc; -using Ryujinx.Horizon.Sdk.Sm; -using System; - -namespace Ryujinx.Horizon.Bcat -{ - class BcatServerManager : ServerManager - { - public BcatServerManager(HeapAllocator allocator, SmApi sm, int maxPorts, ManagerOptions options, int maxSessions) : base(allocator, sm, maxPorts, options, maxSessions) - { - } - - protected override Result OnNeedsToAccept(int portIndex, Server server) - { - return (BcatPortIndex)portIndex switch - { - BcatPortIndex.Admin => AcceptImpl(server, new BcatService(BcatServicePermissionLevel.Admin)), - BcatPortIndex.Manager => AcceptImpl(server, new BcatService(BcatServicePermissionLevel.Manager)), - BcatPortIndex.User => AcceptImpl(server, new BcatService(BcatServicePermissionLevel.User)), - BcatPortIndex.System => AcceptImpl(server, new BcatService(BcatServicePermissionLevel.System)), - _ => throw new ArgumentOutOfRangeException(nameof(portIndex)), - }; - } - } -} \ No newline at end of file diff --git a/src/Ryujinx.Horizon/Bcat/Ipc/ServiceCreator.cs b/src/Ryujinx.Horizon/Bcat/Ipc/ServiceCreator.cs deleted file mode 100644 index d1610f7d..00000000 --- a/src/Ryujinx.Horizon/Bcat/Ipc/ServiceCreator.cs +++ /dev/null @@ -1,82 +0,0 @@ -using LibHac.Common; -using Ryujinx.Horizon.Common; -using Ryujinx.Horizon.Sdk.Bcat; -using Ryujinx.Horizon.Sdk.Sf; -using System; -using System.Threading; -using ApplicationId = Ryujinx.Horizon.Sdk.Ncm.ApplicationId; - -namespace Ryujinx.Horizon.Bcat.Ipc -{ - partial class ServiceCreator : IServiceCreator, IDisposable - { - private SharedRef _libHacService; - - private int _disposalState; - - public ServiceCreator(string serviceName) - { - HorizonStatic.Options.BcatClient.Sm.GetService(ref _libHacService, serviceName).ThrowIfFailure(); - } - - [CmifCommand(0)] - public Result CreateBcatService(out IBcatService bcatService, [ClientProcessId] ulong pid) - { - // TODO: Call arp:r GetApplicationLaunchProperty with the pid to get the TitleId. - // Add an instance of nn::bcat::detail::service::core::PassphraseManager. - // Add an instance of nn::bcat::detail::service::ServiceMemoryManager. - // Add an instance of nn::bcat::detail::service::core::TaskManager who loads "bcat-sys:/" system save data and opens "dc/task.bin". - // If the file don't exist, create a new one (with a size of 0x800 bytes) and write 2 empty structs with a size of 0x400 bytes. - - bcatService = new BcatService(Bcat.Types.BcatServicePermissionLevel.User); - - return Result.Success; - } - - [CmifCommand(1)] - public Result CreateDeliveryCacheStorageService(out IDeliveryCacheStorageService service, [ClientProcessId] ulong pid) - { - using var libHacService = new SharedRef(); - - var resultCode = _libHacService.Get.CreateDeliveryCacheStorageService(ref libHacService.Ref, pid); - - if (resultCode.IsSuccess()) - { - service = new DeliveryCacheStorageService(ref libHacService.Ref); - } - else - { - service = null; - } - - return resultCode.ToHorizonResult(); - } - - [CmifCommand(2)] - public Result CreateDeliveryCacheStorageServiceWithApplicationId(out IDeliveryCacheStorageService service, ApplicationId applicationId) - { - using var libHacService = new SharedRef(); - - var resultCode = _libHacService.Get.CreateDeliveryCacheStorageServiceWithApplicationId(ref libHacService.Ref, new LibHac.ApplicationId(applicationId.Id)); - - if (resultCode.IsSuccess()) - { - service = new DeliveryCacheStorageService(ref libHacService.Ref); - } - else - { - service = null; - } - - return resultCode.ToHorizonResult(); - } - - public void Dispose() - { - if (Interlocked.Exchange(ref _disposalState, 1) == 0) - { - _libHacService.Destroy(); - } - } - } -} diff --git a/src/Ryujinx.Horizon/Bcat/Ipc/ServiceCreator/BcatService.cs b/src/Ryujinx.Horizon/Bcat/Ipc/ServiceCreator/BcatService.cs deleted file mode 100644 index e82f597e..00000000 --- a/src/Ryujinx.Horizon/Bcat/Ipc/ServiceCreator/BcatService.cs +++ /dev/null @@ -1,25 +0,0 @@ -using Ryujinx.Horizon.Bcat.Types; -using Ryujinx.Horizon.Common; -using Ryujinx.Horizon.Sdk.Bcat; -using Ryujinx.Horizon.Sdk.Sf; - -namespace Ryujinx.Horizon.Bcat.Ipc -{ - partial class BcatService : IBcatService - { - private readonly BcatServicePermissionLevel _permissionLevel; - - public BcatService(BcatServicePermissionLevel permissionLevel) - { - _permissionLevel = permissionLevel; - } - - [CmifCommand(10100)] - public Result RequestSyncDeliveryCache(out IDeliveryCacheProgressService deliveryCacheProgressService) - { - deliveryCacheProgressService = new DeliveryCacheProgressService(); - - return Result.Success; - } - } -} diff --git a/src/Ryujinx.Horizon/Bcat/Ipc/ServiceCreator/DeliveryCacheDirectoryService.cs b/src/Ryujinx.Horizon/Bcat/Ipc/ServiceCreator/DeliveryCacheDirectoryService.cs deleted file mode 100644 index dd13eefb..00000000 --- a/src/Ryujinx.Horizon/Bcat/Ipc/ServiceCreator/DeliveryCacheDirectoryService.cs +++ /dev/null @@ -1,48 +0,0 @@ -using LibHac.Bcat; -using LibHac.Common; -using Ryujinx.Horizon.Common; -using Ryujinx.Horizon.Sdk.Bcat; -using Ryujinx.Horizon.Sdk.Sf; -using Ryujinx.Horizon.Sdk.Sf.Hipc; -using System; -using System.Threading; - -namespace Ryujinx.Horizon.Bcat.Ipc -{ - partial class DeliveryCacheDirectoryService : IDeliveryCacheDirectoryService, IDisposable - { - private SharedRef _libHacService; - private int _disposalState; - - public DeliveryCacheDirectoryService(ref SharedRef libHacService) - { - _libHacService = SharedRef.CreateMove(ref libHacService); - } - - [CmifCommand(0)] - public Result Open(DirectoryName directoryName) - { - return _libHacService.Get.Open(ref directoryName).ToHorizonResult(); - } - - [CmifCommand(1)] - public Result Read(out int entriesRead, [Buffer(Sdk.Sf.Hipc.HipcBufferFlags.Out | HipcBufferFlags.MapAlias)] Span entriesBuffer) - { - return _libHacService.Get.Read(out entriesRead, entriesBuffer).ToHorizonResult(); - } - - [CmifCommand(2)] - public Result GetCount(out int count) - { - return _libHacService.Get.GetCount(out count).ToHorizonResult(); - } - - public void Dispose() - { - if (Interlocked.Exchange(ref _disposalState, 1) == 0) - { - _libHacService.Destroy(); - } - } - } -} diff --git a/src/Ryujinx.Horizon/Bcat/Ipc/ServiceCreator/DeliveryCacheFileService.cs b/src/Ryujinx.Horizon/Bcat/Ipc/ServiceCreator/DeliveryCacheFileService.cs deleted file mode 100644 index d23f5f41..00000000 --- a/src/Ryujinx.Horizon/Bcat/Ipc/ServiceCreator/DeliveryCacheFileService.cs +++ /dev/null @@ -1,54 +0,0 @@ -using LibHac.Bcat; -using LibHac.Common; -using Ryujinx.Horizon.Common; -using Ryujinx.Horizon.Sdk.Bcat; -using Ryujinx.Horizon.Sdk.Sf; -using Ryujinx.Horizon.Sdk.Sf.Hipc; -using System; -using System.Threading; - -namespace Ryujinx.Horizon.Bcat.Ipc -{ - partial class DeliveryCacheFileService : IDeliveryCacheFileService, IDisposable - { - private SharedRef _libHacService; - private int _disposalState; - - public DeliveryCacheFileService(ref SharedRef libHacService) - { - _libHacService = SharedRef.CreateMove(ref libHacService); - } - - [CmifCommand(0)] - public Result Open(DirectoryName directoryName, FileName fileName) - { - return _libHacService.Get.Open(ref directoryName, ref fileName).ToHorizonResult(); - } - - [CmifCommand(1)] - public Result Read(long offset, out long bytesRead, [Buffer(HipcBufferFlags.Out | HipcBufferFlags.MapAlias)] Span data) - { - return _libHacService.Get.Read(out bytesRead, offset, data).ToHorizonResult(); - } - - [CmifCommand(2)] - public Result GetSize(out long size) - { - return _libHacService.Get.GetSize(out size).ToHorizonResult(); - } - - [CmifCommand(3)] - public Result GetDigest(out Digest digest) - { - return _libHacService.Get.GetDigest(out digest).ToHorizonResult(); - } - - public void Dispose() - { - if (Interlocked.Exchange(ref _disposalState, 1) == 0) - { - _libHacService.Destroy(); - } - } - } -} diff --git a/src/Ryujinx.Horizon/Bcat/Ipc/ServiceCreator/DeliveryCacheProgressService.cs b/src/Ryujinx.Horizon/Bcat/Ipc/ServiceCreator/DeliveryCacheProgressService.cs deleted file mode 100644 index 91aa2686..00000000 --- a/src/Ryujinx.Horizon/Bcat/Ipc/ServiceCreator/DeliveryCacheProgressService.cs +++ /dev/null @@ -1,58 +0,0 @@ -using Ryujinx.Common.Logging; -using Ryujinx.Horizon.Bcat.Ipc.Types; -using Ryujinx.Horizon.Common; -using Ryujinx.Horizon.Sdk.Bcat; -using Ryujinx.Horizon.Sdk.OsTypes; -using Ryujinx.Horizon.Sdk.Sf; -using Ryujinx.Horizon.Sdk.Sf.Hipc; -using System; -using System.Threading; - -namespace Ryujinx.Horizon.Bcat.Ipc -{ - partial class DeliveryCacheProgressService : IDeliveryCacheProgressService, IDisposable - { - private int _handle; - private SystemEventType _systemEvent; - private int _disposalState; - - [CmifCommand(0)] - public Result GetEvent([CopyHandle] out int handle) - { - if (_handle == 0) - { - Os.CreateSystemEvent(out _systemEvent, EventClearMode.ManualClear, true).AbortOnFailure(); - - _handle = Os.GetReadableHandleOfSystemEvent(ref _systemEvent); - } - - handle = _handle; - - Logger.Stub?.PrintStub(LogClass.ServiceBcat); - - return Result.Success; - } - - [CmifCommand(1)] - public Result GetImpl([Buffer(HipcBufferFlags.Out | HipcBufferFlags.Pointer, 0x200)] out DeliveryCacheProgressImpl deliveryCacheProgressImpl) - { - deliveryCacheProgressImpl = new DeliveryCacheProgressImpl - { - State = DeliveryCacheProgressImpl.Status.Done, - Result = 0 - }; - - Logger.Stub?.PrintStub(LogClass.ServiceBcat); - - return Result.Success; - } - - public void Dispose() - { - if (_handle != 0 && Interlocked.Exchange(ref _disposalState, 1) == 0) - { - Os.DestroySystemEvent(ref _systemEvent); - } - } - } -} diff --git a/src/Ryujinx.Horizon/Bcat/Ipc/ServiceCreator/DeliveryCacheStorageService.cs b/src/Ryujinx.Horizon/Bcat/Ipc/ServiceCreator/DeliveryCacheStorageService.cs deleted file mode 100644 index 9507a8a0..00000000 --- a/src/Ryujinx.Horizon/Bcat/Ipc/ServiceCreator/DeliveryCacheStorageService.cs +++ /dev/null @@ -1,74 +0,0 @@ -using LibHac.Bcat; -using LibHac.Common; -using Ryujinx.Horizon.Common; -using Ryujinx.Horizon.Sdk.Bcat; -using Ryujinx.Horizon.Sdk.Sf; -using Ryujinx.Horizon.Sdk.Sf.Hipc; -using System; -using System.Threading; - -namespace Ryujinx.Horizon.Bcat.Ipc -{ - partial class DeliveryCacheStorageService : IDeliveryCacheStorageService, IDisposable - { - private SharedRef _libHacService; - private int _disposalState; - - public DeliveryCacheStorageService(ref SharedRef libHacService) - { - _libHacService = SharedRef.CreateMove(ref libHacService); - } - - [CmifCommand(0)] - public Result CreateFileService(out IDeliveryCacheFileService service) - { - using var libHacService = new SharedRef(); - - var resultCode = _libHacService.Get.CreateFileService(ref libHacService.Ref); - - if (resultCode.IsSuccess()) - { - service = new DeliveryCacheFileService(ref libHacService.Ref); - } - else - { - service = null; - } - - return resultCode.ToHorizonResult(); - } - - [CmifCommand(1)] - public Result CreateDirectoryService(out IDeliveryCacheDirectoryService service) - { - using var libHacService = new SharedRef(); - - var resultCode = _libHacService.Get.CreateDirectoryService(ref libHacService.Ref); - - if (resultCode.IsSuccess()) - { - service = new DeliveryCacheDirectoryService(ref libHacService.Ref); - } - else - { - service = null; - } - - return resultCode.ToHorizonResult(); - } - - [CmifCommand(10)] - public Result EnumerateDeliveryCacheDirectory(out int count, [Buffer(HipcBufferFlags.Out | HipcBufferFlags.MapAlias)] Span directoryNames) - { - return _libHacService.Get.EnumerateDeliveryCacheDirectory(out count, directoryNames).ToHorizonResult(); - } - - public void Dispose() - { - if (Interlocked.Exchange(ref _disposalState, 1) == 0) - { - _libHacService.Destroy(); - } - } - } -} diff --git a/src/Ryujinx.Horizon/Bcat/Types/BcatPortIndex.cs b/src/Ryujinx.Horizon/Bcat/Types/BcatPortIndex.cs deleted file mode 100644 index e448dfdc..00000000 --- a/src/Ryujinx.Horizon/Bcat/Types/BcatPortIndex.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Ryujinx.Horizon.Bcat.Types -{ - enum BcatPortIndex - { - Admin, - Manager, - User, - System - } -} diff --git a/src/Ryujinx.Horizon/Bcat/Types/BcatServicePermissionLevel.cs b/src/Ryujinx.Horizon/Bcat/Types/BcatServicePermissionLevel.cs deleted file mode 100644 index 54d7461a..00000000 --- a/src/Ryujinx.Horizon/Bcat/Types/BcatServicePermissionLevel.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Ryujinx.Horizon.Bcat.Types -{ - enum BcatServicePermissionLevel - { - Admin = -1, - User = 1, - System = 2, - Manager = 6 - } -} \ No newline at end of file diff --git a/src/Ryujinx.Horizon/HorizonOptions.cs b/src/Ryujinx.Horizon/HorizonOptions.cs index 1ec56bfa..6d580e8b 100644 --- a/src/Ryujinx.Horizon/HorizonOptions.cs +++ b/src/Ryujinx.Horizon/HorizonOptions.cs @@ -1,5 +1,3 @@ -using LibHac; - namespace Ryujinx.Horizon { public struct HorizonOptions @@ -7,13 +5,10 @@ namespace Ryujinx.Horizon public bool IgnoreMissingServices { get; } public bool ThrowOnInvalidCommandIds { get; } - public HorizonClient BcatClient { get; } - - public HorizonOptions(bool ignoreMissingServices, HorizonClient bcatClient) + public HorizonOptions(bool ignoreMissingServices) { IgnoreMissingServices = ignoreMissingServices; ThrowOnInvalidCommandIds = true; - BcatClient = bcatClient; } } } diff --git a/src/Ryujinx.Horizon/LibHacResultExtensions.cs b/src/Ryujinx.Horizon/LibHacResultExtensions.cs deleted file mode 100644 index 01d18164..00000000 --- a/src/Ryujinx.Horizon/LibHacResultExtensions.cs +++ /dev/null @@ -1,12 +0,0 @@ -using Ryujinx.Horizon.Common; - -namespace Ryujinx.Horizon -{ - internal static class LibHacResultExtensions - { - public static Result ToHorizonResult(this LibHac.Result result) - { - return new Result((int)result.Module, (int)result.Description); - } - } -} diff --git a/src/Ryujinx.Horizon/Prepo/PrepoIpcServer.cs b/src/Ryujinx.Horizon/Prepo/PrepoIpcServer.cs index b80399ea..ba19ff6f 100644 --- a/src/Ryujinx.Horizon/Prepo/PrepoIpcServer.cs +++ b/src/Ryujinx.Horizon/Prepo/PrepoIpcServer.cs @@ -9,12 +9,12 @@ namespace Ryujinx.Horizon.Prepo private const int PrepoMaxSessionsCount = 12; private const int PrepoTotalMaxSessionsCount = PrepoMaxSessionsCount * 6; - private const int PointerBufferSize = 0x80; + private const int PointerBufferSize = 0x3800; private const int MaxDomains = 64; private const int MaxDomainObjects = 16; private const int MaxPortsCount = 6; - private static readonly ManagerOptions _prepoManagerOptions = new(PointerBufferSize, MaxDomains, MaxDomainObjects, false); + private static readonly ManagerOptions _logManagerOptions = new(PointerBufferSize, MaxDomains, MaxDomainObjects, false); private SmApi _sm; private PrepoServerManager _serverManager; @@ -26,7 +26,7 @@ namespace Ryujinx.Horizon.Prepo _sm = new SmApi(); _sm.Initialize().AbortOnFailure(); - _serverManager = new PrepoServerManager(allocator, _sm, MaxPortsCount, _prepoManagerOptions, PrepoTotalMaxSessionsCount); + _serverManager = new PrepoServerManager(allocator, _sm, MaxPortsCount, _logManagerOptions, PrepoTotalMaxSessionsCount); _serverManager.RegisterServer((int)PrepoPortIndex.Admin, ServiceName.Encode("prepo:a"), PrepoMaxSessionsCount); // 1.0.0-5.1.0 _serverManager.RegisterServer((int)PrepoPortIndex.Admin2, ServiceName.Encode("prepo:a2"), PrepoMaxSessionsCount); // 6.0.0+ diff --git a/src/Ryujinx.Horizon/Sdk/Bcat/IBcatService.cs b/src/Ryujinx.Horizon/Sdk/Bcat/IBcatService.cs deleted file mode 100644 index f6c8e6dd..00000000 --- a/src/Ryujinx.Horizon/Sdk/Bcat/IBcatService.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Ryujinx.Horizon.Common; -using Ryujinx.Horizon.Sdk.Sf; - -namespace Ryujinx.Horizon.Sdk.Bcat -{ - internal interface IBcatService : IServiceObject - { - Result RequestSyncDeliveryCache(out IDeliveryCacheProgressService deliveryCacheProgressService); - } -} diff --git a/src/Ryujinx.Horizon/Sdk/Bcat/IDeliveryCacheDirectoryService.cs b/src/Ryujinx.Horizon/Sdk/Bcat/IDeliveryCacheDirectoryService.cs deleted file mode 100644 index 23a740c3..00000000 --- a/src/Ryujinx.Horizon/Sdk/Bcat/IDeliveryCacheDirectoryService.cs +++ /dev/null @@ -1,14 +0,0 @@ -using LibHac.Bcat; -using Ryujinx.Horizon.Common; -using Ryujinx.Horizon.Sdk.Sf; -using System; - -namespace Ryujinx.Horizon.Sdk.Bcat -{ - internal interface IDeliveryCacheDirectoryService : IServiceObject - { - Result GetCount(out int count); - Result Open(DirectoryName directoryName); - Result Read(out int entriesRead, Span entriesBuffer); - } -} diff --git a/src/Ryujinx.Horizon/Sdk/Bcat/IDeliveryCacheFileService.cs b/src/Ryujinx.Horizon/Sdk/Bcat/IDeliveryCacheFileService.cs deleted file mode 100644 index a1e5d43b..00000000 --- a/src/Ryujinx.Horizon/Sdk/Bcat/IDeliveryCacheFileService.cs +++ /dev/null @@ -1,15 +0,0 @@ -using LibHac.Bcat; -using Ryujinx.Horizon.Common; -using Ryujinx.Horizon.Sdk.Sf; -using System; - -namespace Ryujinx.Horizon.Sdk.Bcat -{ - internal interface IDeliveryCacheFileService : IServiceObject - { - Result GetDigest(out Digest digest); - Result GetSize(out long size); - Result Open(DirectoryName directoryName, FileName fileName); - Result Read(long offset, out long bytesRead, Span data); - } -} diff --git a/src/Ryujinx.Horizon/Sdk/Bcat/IDeliveryCacheProgressService.cs b/src/Ryujinx.Horizon/Sdk/Bcat/IDeliveryCacheProgressService.cs deleted file mode 100644 index 07a796f8..00000000 --- a/src/Ryujinx.Horizon/Sdk/Bcat/IDeliveryCacheProgressService.cs +++ /dev/null @@ -1,12 +0,0 @@ -using Ryujinx.Horizon.Bcat.Ipc.Types; -using Ryujinx.Horizon.Common; -using Ryujinx.Horizon.Sdk.Sf; - -namespace Ryujinx.Horizon.Sdk.Bcat -{ - internal interface IDeliveryCacheProgressService : IServiceObject - { - Result GetEvent(out int handle); - Result GetImpl(out DeliveryCacheProgressImpl deliveryCacheProgressImpl); - } -} diff --git a/src/Ryujinx.Horizon/Sdk/Bcat/IDeliveryCacheStorageService.cs b/src/Ryujinx.Horizon/Sdk/Bcat/IDeliveryCacheStorageService.cs deleted file mode 100644 index 5638f074..00000000 --- a/src/Ryujinx.Horizon/Sdk/Bcat/IDeliveryCacheStorageService.cs +++ /dev/null @@ -1,14 +0,0 @@ -using LibHac.Bcat; -using Ryujinx.Horizon.Common; -using Ryujinx.Horizon.Sdk.Sf; -using System; - -namespace Ryujinx.Horizon.Sdk.Bcat -{ - internal interface IDeliveryCacheStorageService : IServiceObject - { - Result CreateDirectoryService(out IDeliveryCacheDirectoryService service); - Result CreateFileService(out IDeliveryCacheFileService service); - Result EnumerateDeliveryCacheDirectory(out int count, Span directoryNames); - } -} diff --git a/src/Ryujinx.Horizon/Sdk/Bcat/IServiceCreator.cs b/src/Ryujinx.Horizon/Sdk/Bcat/IServiceCreator.cs deleted file mode 100644 index edc52590..00000000 --- a/src/Ryujinx.Horizon/Sdk/Bcat/IServiceCreator.cs +++ /dev/null @@ -1,12 +0,0 @@ -using Ryujinx.Horizon.Common; -using Ryujinx.Horizon.Sdk.Sf; - -namespace Ryujinx.Horizon.Sdk.Bcat -{ - internal interface IServiceCreator : IServiceObject - { - Result CreateBcatService(out IBcatService service, ulong pid); - Result CreateDeliveryCacheStorageService(out IDeliveryCacheStorageService service, ulong pid); - Result CreateDeliveryCacheStorageServiceWithApplicationId(out IDeliveryCacheStorageService service, Ncm.ApplicationId applicationId); - } -} diff --git a/src/Ryujinx.Horizon/ServiceTable.cs b/src/Ryujinx.Horizon/ServiceTable.cs index d97457d9..2edc6ea1 100644 --- a/src/Ryujinx.Horizon/ServiceTable.cs +++ b/src/Ryujinx.Horizon/ServiceTable.cs @@ -1,4 +1,3 @@ -using Ryujinx.Horizon.Bcat; using Ryujinx.Horizon.LogManager; using Ryujinx.Horizon.Prepo; using System.Collections.Generic; @@ -24,7 +23,6 @@ namespace Ryujinx.Horizon RegisterService(); RegisterService(); - RegisterService(); _totalServices = entries.Count;