From 18131f2301a42d81a42f86b20be75aff7cf1d0ee Mon Sep 17 00:00:00 2001 From: Babib3l Date: Fri, 15 May 2026 16:29:55 +0200 Subject: [PATCH] HOS: Use ClientProcessId instead of Process.Pid for client process access --- src/Ryujinx.HLE/HOS/ServiceCtx.cs | 1 + .../Account/Acc/IAccountServiceForApplication.cs | 2 +- .../ILibraryAppletProxy.cs | 2 +- .../LibraryAppletProxy/ILibraryAppletSelfAccessor.cs | 4 ++-- .../ApplicationProxy/IApplicationFunctions.cs | 12 +++++++----- .../ApplicationProxyService/IApplicationProxy.cs | 2 +- .../HOS/Services/Arp/ApplicationLaunchProperty.cs | 7 ++++++- .../Services/Caps/IScreenShotApplicationService.cs | 6 +++--- src/Ryujinx.HLE/HOS/Services/Fs/IFileSystemProxy.cs | 2 +- .../IUserLocalCommunicationService.cs | 10 +++++----- .../HOS/Services/Ns/Aoc/IAddOnContentManager.cs | 2 +- .../HOS/Services/Ns/IApplicationManagerInterface.cs | 2 +- .../Ns/IReadOnlyApplicationControlDataInterface.cs | 2 +- .../IParentalControlService.cs | 2 +- .../Pdm/QueryService/QueryPlayStatisticsManager.cs | 2 +- 15 files changed, 33 insertions(+), 25 deletions(-) diff --git a/src/Ryujinx.HLE/HOS/ServiceCtx.cs b/src/Ryujinx.HLE/HOS/ServiceCtx.cs index ba27e12ea..200afaf5e 100644 --- a/src/Ryujinx.HLE/HOS/ServiceCtx.cs +++ b/src/Ryujinx.HLE/HOS/ServiceCtx.cs @@ -16,6 +16,7 @@ namespace Ryujinx.HLE.HOS public IpcMessage Response { get; } public BinaryReader RequestData { get; } public BinaryWriter ResponseData { get; } + public ulong ClientProcessId => Request.HandleDesc.HasPId ? Request.HandleDesc.PId : Process.Pid; public ServiceCtx( Switch device, diff --git a/src/Ryujinx.HLE/HOS/Services/Account/Acc/IAccountServiceForApplication.cs b/src/Ryujinx.HLE/HOS/Services/Account/Acc/IAccountServiceForApplication.cs index 05d7384e7..759613752 100644 --- a/src/Ryujinx.HLE/HOS/Services/Account/Acc/IAccountServiceForApplication.cs +++ b/src/Ryujinx.HLE/HOS/Services/Account/Acc/IAccountServiceForApplication.cs @@ -190,7 +190,7 @@ namespace Ryujinx.HLE.HOS.Services.Account.Acc // TODO: Account actually calls nn::arp::detail::IReader::GetApplicationControlProperty() with the current Pid and store the result (NACP file) internally. // But since we use LibHac and we load one Application at a time, it's not necessary. - context.ResponseData.Write((byte)context.Device.Processes.GetProcess(context.Process.Pid).ApplicationControlProperties.UserAccountSwitchLock); + context.ResponseData.Write((byte)context.Device.Processes.GetProcess(context.ClientProcessId).ApplicationControlProperties.UserAccountSwitchLock); Logger.Stub?.PrintStub(LogClass.ServiceAcc); diff --git a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/ILibraryAppletProxy.cs b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/ILibraryAppletProxy.cs index 7700cac09..cfd35111a 100644 --- a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/ILibraryAppletProxy.cs +++ b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/ILibraryAppletProxy.cs @@ -79,7 +79,7 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService // OpenLibraryAppletSelfAccessor() -> object public ResultCode OpenLibraryAppletSelfAccessor(ServiceCtx context) { - MakeObject(context, new ILibraryAppletSelfAccessor(context)); + MakeObject(context, new ILibraryAppletSelfAccessor(context, _pid)); return ResultCode.Success; } diff --git a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/LibraryAppletProxy/ILibraryAppletSelfAccessor.cs b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/LibraryAppletProxy/ILibraryAppletSelfAccessor.cs index 4216d2d12..50df65e44 100644 --- a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/LibraryAppletProxy/ILibraryAppletSelfAccessor.cs +++ b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/LibraryAppletProxy/ILibraryAppletSelfAccessor.cs @@ -8,9 +8,9 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.Lib { private readonly AppletStandalone _appletStandalone = new(); - public ILibraryAppletSelfAccessor(ServiceCtx context) + public ILibraryAppletSelfAccessor(ServiceCtx context, ulong pid) { - ulong programId = context.Device.Processes.GetProcess(context.Process.Pid).ProgramId; + ulong programId = context.Device.Processes.GetProcess(pid).ProgramId; if (programId == 0x0100000000001009) { diff --git a/src/Ryujinx.HLE/HOS/Services/Am/AppletOE/ApplicationProxyService/ApplicationProxy/IApplicationFunctions.cs b/src/Ryujinx.HLE/HOS/Services/Am/AppletOE/ApplicationProxyService/ApplicationProxy/IApplicationFunctions.cs index 2bc064a33..7f8858896 100644 --- a/src/Ryujinx.HLE/HOS/Services/Am/AppletOE/ApplicationProxyService/ApplicationProxy/IApplicationFunctions.cs +++ b/src/Ryujinx.HLE/HOS/Services/Am/AppletOE/ApplicationProxyService/ApplicationProxy/IApplicationFunctions.cs @@ -44,8 +44,9 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.Applicati private int _jitLoaded; private readonly LibHac.HorizonClient _horizon; + private readonly ulong _pid; - public IApplicationFunctions(Horizon system) + public IApplicationFunctions(Horizon system, ulong pid) { // TODO: Find where they are signaled. _gpuErrorDetectedSystemEvent = new KEvent(system.KernelContext); @@ -55,6 +56,7 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.Applicati _unknownEvent = new KEvent(system.KernelContext); _horizon = system.LibHacHorizonManager.AmClient; + _pid = pid; } [CommandCmif(1)] @@ -115,7 +117,7 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.Applicati public ResultCode EnsureSaveData(ServiceCtx context) { Uid userId = context.RequestData.ReadStruct().ToLibHacUid(); - var process = context.Device.Processes.GetProcess(context.Process.Pid); + var process = context.Device.Processes.GetProcess(_pid); // Mask out the low nibble of the program ID to get the application ID ApplicationId applicationId = new(process.Identity.ApplicationId); @@ -140,7 +142,7 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.Applicati // TODO: When above calls are implemented, switch to using ns:am long desiredLanguageCode = context.Device.System.State.DesiredLanguageCode; - int supportedLanguages = (int)context.Device.Processes.GetProcess(context.Process.Pid).ApplicationControlProperties.SupportedLanguageFlag; + int supportedLanguages = (int)context.Device.Processes.GetProcess(_pid).ApplicationControlProperties.SupportedLanguageFlag; int firstSupported = BitOperations.TrailingZeroCount(supportedLanguages); if (firstSupported > (int)TitleLanguage.BrazilianPortuguese) @@ -183,7 +185,7 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.Applicati public ResultCode GetDisplayVersion(ServiceCtx context) { // If an NACP isn't found, the buffer will be all '\0' which seems to be the correct implementation. - context.ResponseData.Write(context.Device.Processes.GetProcess(context.Process.Pid).ApplicationControlProperties.DisplayVersion); + context.ResponseData.Write(context.Device.Processes.GetProcess(_pid).ApplicationControlProperties.DisplayVersion); return ResultCode.Success; } @@ -236,7 +238,7 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.Applicati ushort index = (ushort)context.RequestData.ReadUInt64(); long saveSize = context.RequestData.ReadInt64(); long journalSize = context.RequestData.ReadInt64(); - var process = context.Device.Processes.GetProcess(context.Process.Pid); + var process = context.Device.Processes.GetProcess(_pid); // Mask out the low nibble of the program ID to get the application ID ApplicationId applicationId = new(process.Identity.ApplicationId); diff --git a/src/Ryujinx.HLE/HOS/Services/Am/AppletOE/ApplicationProxyService/IApplicationProxy.cs b/src/Ryujinx.HLE/HOS/Services/Am/AppletOE/ApplicationProxyService/IApplicationProxy.cs index b24e1bf4f..27a54a51e 100644 --- a/src/Ryujinx.HLE/HOS/Services/Am/AppletOE/ApplicationProxyService/IApplicationProxy.cs +++ b/src/Ryujinx.HLE/HOS/Services/Am/AppletOE/ApplicationProxyService/IApplicationProxy.cs @@ -70,7 +70,7 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService // GetApplicationFunctions() -> object public ResultCode GetApplicationFunctions(ServiceCtx context) { - MakeObject(context, new IApplicationFunctions(context.Device.System)); + MakeObject(context, new IApplicationFunctions(context.Device.System, _pid)); return ResultCode.Success; } diff --git a/src/Ryujinx.HLE/HOS/Services/Arp/ApplicationLaunchProperty.cs b/src/Ryujinx.HLE/HOS/Services/Arp/ApplicationLaunchProperty.cs index ac91b2959..b370c3d04 100644 --- a/src/Ryujinx.HLE/HOS/Services/Arp/ApplicationLaunchProperty.cs +++ b/src/Ryujinx.HLE/HOS/Services/Arp/ApplicationLaunchProperty.cs @@ -27,13 +27,18 @@ namespace Ryujinx.HLE.HOS.Services.Arp } public static ApplicationLaunchProperty GetByPid(ServiceCtx context) + { + return GetByPid(context, context.ClientProcessId); + } + + public static ApplicationLaunchProperty GetByPid(ServiceCtx context, ulong pid) { // TODO: Handle ApplicationLaunchProperty as array when pid will be supported and return the right item. // For now we can hardcode values, and fix it after GetApplicationLaunchProperty is implemented. return new ApplicationLaunchProperty { - TitleId = context.Device.Processes.GetProcess(context.Process.Pid).ProgramId, + TitleId = context.Device.Processes.GetProcess(pid).ProgramId, Version = 0x00, BaseGameStorageId = (byte)StorageId.BuiltInSystem, UpdateGameStorageId = (byte)StorageId.None, diff --git a/src/Ryujinx.HLE/HOS/Services/Caps/IScreenShotApplicationService.cs b/src/Ryujinx.HLE/HOS/Services/Caps/IScreenShotApplicationService.cs index f12cf0ea4..64e9eeca5 100644 --- a/src/Ryujinx.HLE/HOS/Services/Caps/IScreenShotApplicationService.cs +++ b/src/Ryujinx.HLE/HOS/Services/Caps/IScreenShotApplicationService.cs @@ -50,7 +50,7 @@ namespace Ryujinx.HLE.HOS.Services.Caps byte[] screenshotData = context.Memory.GetSpan(screenshotDataPosition, (int)screenshotDataSize, true).ToArray(); - ResultCode resultCode = context.Device.System.CaptureManager.SaveScreenShot(screenshotData, appletResourceUserId, context.Device.Processes.GetProcess(context.Process.Pid).ProgramId, out ApplicationAlbumEntry applicationAlbumEntry); + ResultCode resultCode = context.Device.System.CaptureManager.SaveScreenShot(screenshotData, appletResourceUserId, context.Device.Processes.GetProcess(context.ClientProcessId).ProgramId, out ApplicationAlbumEntry applicationAlbumEntry); context.ResponseData.WriteStruct(applicationAlbumEntry); @@ -98,7 +98,7 @@ namespace Ryujinx.HLE.HOS.Services.Caps byte[] screenshotData = context.Memory.GetSpan(screenshotDataPosition, (int)screenshotDataSize, true).ToArray(); - ResultCode resultCode = context.Device.System.CaptureManager.SaveScreenShot(screenshotData, appletResourceUserId, context.Device.Processes.GetProcess(context.Process.Pid).ProgramId, out ApplicationAlbumEntry applicationAlbumEntry); + ResultCode resultCode = context.Device.System.CaptureManager.SaveScreenShot(screenshotData, appletResourceUserId, context.Device.Processes.GetProcess(context.ClientProcessId).ProgramId, out ApplicationAlbumEntry applicationAlbumEntry); context.ResponseData.WriteStruct(applicationAlbumEntry); @@ -143,7 +143,7 @@ namespace Ryujinx.HLE.HOS.Services.Caps byte[] screenshotData = context.Memory.GetSpan(screenshotDataPosition, (int)screenshotDataSize, true).ToArray(); - ResultCode resultCode = context.Device.System.CaptureManager.SaveScreenShot(screenshotData, appletResourceUserId, context.Device.Processes.GetProcess(context.Process.Pid).ProgramId, out ApplicationAlbumEntry applicationAlbumEntry); + ResultCode resultCode = context.Device.System.CaptureManager.SaveScreenShot(screenshotData, appletResourceUserId, context.Device.Processes.GetProcess(context.ClientProcessId).ProgramId, out ApplicationAlbumEntry applicationAlbumEntry); context.ResponseData.WriteStruct(applicationAlbumEntry); diff --git a/src/Ryujinx.HLE/HOS/Services/Fs/IFileSystemProxy.cs b/src/Ryujinx.HLE/HOS/Services/Fs/IFileSystemProxy.cs index 40042af69..75d8edfb2 100644 --- a/src/Ryujinx.HLE/HOS/Services/Fs/IFileSystemProxy.cs +++ b/src/Ryujinx.HLE/HOS/Services/Fs/IFileSystemProxy.cs @@ -885,7 +885,7 @@ namespace Ryujinx.HLE.HOS.Services.Fs { byte programIndex = context.RequestData.ReadByte(); - if (context.Device.Processes.GetProcess(context.Process.Pid).Identity.ProgramIndex != programIndex) + if (context.Device.Processes.GetProcess(_pid).Identity.ProgramIndex != programIndex) { throw new NotImplementedException($"Accessing storage from other programs is not supported (program index = {programIndex})."); } diff --git a/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/IUserLocalCommunicationService.cs b/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/IUserLocalCommunicationService.cs index 699fe1f66..f5ca0fd82 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/IUserLocalCommunicationService.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/IUserLocalCommunicationService.cs @@ -60,7 +60,7 @@ namespace Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator private bool CheckLocalCommunicationIdPermission(ServiceCtx context, ulong localCommunicationIdChecked) { // TODO: Call nn::arp::GetApplicationControlProperty here when implemented. - ApplicationControlProperty controlProperty = context.Device.Processes.GetProcess(context.Process.Pid).ApplicationControlProperties; + ApplicationControlProperty controlProperty = context.Device.Processes.GetProcess(context.ClientProcessId).ApplicationControlProperties; foreach (ulong localCommunicationId in controlProperty.LocalCommunicationId) { @@ -438,7 +438,7 @@ namespace Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator if (scanFilter.NetworkId.IntentId.LocalCommunicationId == -1 && NetworkClient.NeedsRealId) { // TODO: Call nn::arp::GetApplicationControlProperty here when implemented. - ApplicationControlProperty controlProperty = context.Device.Processes.GetProcess(context.Process.Pid).ApplicationControlProperties; + ApplicationControlProperty controlProperty = context.Device.Processes.GetProcess(context.ClientProcessId).ApplicationControlProperties; scanFilter.NetworkId.IntentId.LocalCommunicationId = (long)controlProperty.LocalCommunicationId[0]; } @@ -613,7 +613,7 @@ namespace Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator if (networkConfig.IntentId.LocalCommunicationId == -1 && NetworkClient.NeedsRealId) { // TODO: Call nn::arp::GetApplicationControlProperty here when implemented. - ApplicationControlProperty controlProperty = context.Device.Processes.GetProcess(context.Process.Pid).ApplicationControlProperties; + ApplicationControlProperty controlProperty = context.Device.Processes.GetProcess(context.ClientProcessId).ApplicationControlProperties; networkConfig.IntentId.LocalCommunicationId = (long)controlProperty.LocalCommunicationId[0]; } @@ -948,7 +948,7 @@ namespace Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator if (networkInfo.NetworkId.IntentId.LocalCommunicationId == -1 && NetworkClient.NeedsRealId) { // TODO: Call nn::arp::GetApplicationControlProperty here when implemented. - ApplicationControlProperty controlProperty = context.Device.Processes.GetProcess(context.Process.Pid).ApplicationControlProperties; + ApplicationControlProperty controlProperty = context.Device.Processes.GetProcess(context.ClientProcessId).ApplicationControlProperties; networkInfo.NetworkId.IntentId.LocalCommunicationId = (long)controlProperty.LocalCommunicationId[0]; } @@ -1208,7 +1208,7 @@ namespace Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator } // TODO: Call nn::arp::GetApplicationLaunchProperty here when implemented. - NetworkClient.SetGameVersion(context.Device.Processes.GetProcess(context.Process.Pid).ApplicationControlProperties.DisplayVersion); + NetworkClient.SetGameVersion(context.Device.Processes.GetProcess(context.ClientProcessId).ApplicationControlProperties.DisplayVersion); resultCode = ResultCode.Success; _nifmResultCode = resultCode; diff --git a/src/Ryujinx.HLE/HOS/Services/Ns/Aoc/IAddOnContentManager.cs b/src/Ryujinx.HLE/HOS/Services/Ns/Aoc/IAddOnContentManager.cs index 4801c7150..2cb921500 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ns/Aoc/IAddOnContentManager.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ns/Aoc/IAddOnContentManager.cs @@ -310,7 +310,7 @@ namespace Ryujinx.HLE.HOS.Services.Ns.Aoc // NOTE: Service calls arp:r GetApplicationControlProperty to get AddOnContentBaseId using TitleId, // If the call fails, it returns ResultCode.InvalidPid. - _addOnContentBaseId = context.Device.Processes.GetProcess(context.Process.Pid).ApplicationControlProperties.AddOnContentBaseId; + _addOnContentBaseId = context.Device.Processes.GetProcess(context.ClientProcessId).ApplicationControlProperties.AddOnContentBaseId; if (_addOnContentBaseId == 0) { diff --git a/src/Ryujinx.HLE/HOS/Services/Ns/IApplicationManagerInterface.cs b/src/Ryujinx.HLE/HOS/Services/Ns/IApplicationManagerInterface.cs index 83dcb86af..a45054aba 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ns/IApplicationManagerInterface.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ns/IApplicationManagerInterface.cs @@ -19,7 +19,7 @@ namespace Ryujinx.HLE.HOS.Services.Ns ulong position = context.Request.ReceiveBuff[0].Position; - ApplicationControlProperty nacp = context.Device.Processes.GetProcess(context.Process.Pid).ApplicationControlProperties; + ApplicationControlProperty nacp = context.Device.Processes.GetProcess(context.ClientProcessId).ApplicationControlProperties; context.Memory.Write(position, SpanHelpers.AsByteSpan(ref nacp).ToArray()); diff --git a/src/Ryujinx.HLE/HOS/Services/Ns/IReadOnlyApplicationControlDataInterface.cs b/src/Ryujinx.HLE/HOS/Services/Ns/IReadOnlyApplicationControlDataInterface.cs index 1714d4729..971929298 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ns/IReadOnlyApplicationControlDataInterface.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ns/IReadOnlyApplicationControlDataInterface.cs @@ -18,7 +18,7 @@ namespace Ryujinx.HLE.HOS.Services.Ns ulong position = context.Request.ReceiveBuff[0].Position; - ApplicationControlProperty nacp = context.Device.Processes.GetProcess(context.Process.Pid).ApplicationControlProperties; + ApplicationControlProperty nacp = context.Device.Processes.GetProcess(context.ClientProcessId).ApplicationControlProperties; context.Memory.Write(position, SpanHelpers.AsByteSpan(ref nacp).ToArray()); diff --git a/src/Ryujinx.HLE/HOS/Services/Pctl/ParentalControlServiceFactory/IParentalControlService.cs b/src/Ryujinx.HLE/HOS/Services/Pctl/ParentalControlServiceFactory/IParentalControlService.cs index 392225812..5e4f415fb 100644 --- a/src/Ryujinx.HLE/HOS/Services/Pctl/ParentalControlServiceFactory/IParentalControlService.cs +++ b/src/Ryujinx.HLE/HOS/Services/Pctl/ParentalControlServiceFactory/IParentalControlService.cs @@ -48,7 +48,7 @@ namespace Ryujinx.HLE.HOS.Services.Pctl.ParentalControlServiceFactory { if ((_permissionFlag & 0x40) == 0) { - ulong titleId = ApplicationLaunchProperty.GetByPid(context).TitleId; + ulong titleId = ApplicationLaunchProperty.GetByPid(context, _pid).TitleId; if (titleId != 0) { diff --git a/src/Ryujinx.HLE/HOS/Services/Sdb/Pdm/QueryService/QueryPlayStatisticsManager.cs b/src/Ryujinx.HLE/HOS/Services/Sdb/Pdm/QueryService/QueryPlayStatisticsManager.cs index 0b05810fa..d4fe60765 100644 --- a/src/Ryujinx.HLE/HOS/Services/Sdb/Pdm/QueryService/QueryPlayStatisticsManager.cs +++ b/src/Ryujinx.HLE/HOS/Services/Sdb/Pdm/QueryService/QueryPlayStatisticsManager.cs @@ -31,7 +31,7 @@ namespace Ryujinx.HLE.HOS.Services.Sdb.Pdm.QueryService } } - var process = context.Device.Processes.GetProcess(context.Process.Pid); + var process = context.Device.Processes.GetProcess(context.ClientProcessId); PlayLogQueryCapability queryCapability = (PlayLogQueryCapability)process.ApplicationControlProperties.PlayLogQueryCapability; List titleIds = [];