|
|
@@ -35,10 +35,10 @@ namespace Ryujinx.HLE.HOS.Services
|
|
|
private readonly List<int> _sessionHandles = new List<int>();
|
|
|
private readonly List<int> _portHandles = new List<int>();
|
|
|
private readonly Dictionary<int, IpcService> _sessions = new Dictionary<int, IpcService>();
|
|
|
- private readonly Dictionary<int, IpcService> _ports = new Dictionary<int, IpcService>();
|
|
|
+ private readonly Dictionary<int, Func<IpcService>> _ports = new Dictionary<int, Func<IpcService>>();
|
|
|
|
|
|
public ManualResetEvent InitDone { get; }
|
|
|
- public IpcService SmObject { get; set; }
|
|
|
+ public Func<IpcService> SmObjectFactory { get; set; }
|
|
|
public string Name { get; }
|
|
|
|
|
|
public ServerBase(KernelContext context, string name)
|
|
|
@@ -58,10 +58,10 @@ namespace Ryujinx.HLE.HOS.Services
|
|
|
KernelStatic.StartInitialProcess(context, creationInfo, DefaultCapabilities, 44, ServerLoop);
|
|
|
}
|
|
|
|
|
|
- private void AddPort(int serverPortHandle, IpcService obj)
|
|
|
+ private void AddPort(int serverPortHandle, Func<IpcService> objectFactory)
|
|
|
{
|
|
|
_portHandles.Add(serverPortHandle);
|
|
|
- _ports.Add(serverPortHandle, obj);
|
|
|
+ _ports.Add(serverPortHandle, objectFactory);
|
|
|
}
|
|
|
|
|
|
public void AddSessionObj(KServerSession serverSession, IpcService obj)
|
|
|
@@ -80,11 +80,11 @@ namespace Ryujinx.HLE.HOS.Services
|
|
|
{
|
|
|
_selfProcess = KernelStatic.GetCurrentProcess();
|
|
|
|
|
|
- if (SmObject != null)
|
|
|
+ if (SmObjectFactory != null)
|
|
|
{
|
|
|
_context.Syscall.ManageNamedPort("sm:", 50, out int serverPortHandle);
|
|
|
|
|
|
- AddPort(serverPortHandle, SmObject);
|
|
|
+ AddPort(serverPortHandle, SmObjectFactory);
|
|
|
|
|
|
InitDone.Set();
|
|
|
}
|
|
|
@@ -141,7 +141,9 @@ namespace Ryujinx.HLE.HOS.Services
|
|
|
// We got a new connection, accept the session to allow servicing future requests.
|
|
|
if (_context.Syscall.AcceptSession(handles[signaledIndex], out int serverSessionHandle) == KernelResult.Success)
|
|
|
{
|
|
|
- AddSessionObj(serverSessionHandle, _ports[handles[signaledIndex]]);
|
|
|
+ IpcService obj = _ports[handles[signaledIndex]].Invoke();
|
|
|
+
|
|
|
+ AddSessionObj(serverSessionHandle, obj);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -191,6 +193,7 @@ namespace Ryujinx.HLE.HOS.Services
|
|
|
}
|
|
|
|
|
|
bool shouldReply = true;
|
|
|
+ bool isTipcCommunication = false;
|
|
|
|
|
|
using (MemoryStream raw = new MemoryStream(request.RawData))
|
|
|
{
|
|
|
@@ -269,6 +272,8 @@ namespace Ryujinx.HLE.HOS.Services
|
|
|
// If the type is past 0xF, we are using TIPC
|
|
|
else if (request.Type > IpcMessageType.TipcCloseSession)
|
|
|
{
|
|
|
+ isTipcCommunication = true;
|
|
|
+
|
|
|
// Response type is always the same as request on TIPC.
|
|
|
response.Type = request.Type;
|
|
|
|
|
|
@@ -290,13 +295,19 @@ namespace Ryujinx.HLE.HOS.Services
|
|
|
|
|
|
response.RawData = resMs.ToArray();
|
|
|
}
|
|
|
+
|
|
|
+ process.CpuMemory.Write(messagePtr, response.GetBytesTipc());
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
throw new NotImplementedException(request.Type.ToString());
|
|
|
}
|
|
|
|
|
|
- process.CpuMemory.Write(messagePtr, response.GetBytes((long)messagePtr, recvListAddr | ((ulong)PointerBufferSize << 48)));
|
|
|
+ if (!isTipcCommunication)
|
|
|
+ {
|
|
|
+ process.CpuMemory.Write(messagePtr, response.GetBytes((long)messagePtr, recvListAddr | ((ulong)PointerBufferSize << 48)));
|
|
|
+ }
|
|
|
+
|
|
|
return shouldReply;
|
|
|
}
|
|
|
}
|