diff --git a/Ryujinx.HLE/OsHle/Ipc/IpcHandleDesc.cs b/Ryujinx.HLE/OsHle/Ipc/IpcHandleDesc.cs index 953cac764..609cc6e05 100644 --- a/Ryujinx.HLE/OsHle/Ipc/IpcHandleDesc.cs +++ b/Ryujinx.HLE/OsHle/Ipc/IpcHandleDesc.cs @@ -47,13 +47,15 @@ namespace Ryujinx.HLE.OsHle.Ipc HasPId = true; } - public static IpcHandleDesc MakeCopy(int Handle) => new IpcHandleDesc( - new int[] { Handle }, - new int[0]); + public static IpcHandleDesc MakeCopy(params int[] Handles) + { + return new IpcHandleDesc(Handles, new int[0]); + } - public static IpcHandleDesc MakeMove(int Handle) => new IpcHandleDesc( - new int[0], - new int[] { Handle }); + public static IpcHandleDesc MakeMove(params int[] Handles) + { + return new IpcHandleDesc(new int[0], Handles); + } public byte[] GetBytes() { diff --git a/Ryujinx.HLE/OsHle/Ipc/IpcMessage.cs b/Ryujinx.HLE/OsHle/Ipc/IpcMessage.cs index 4e648aec9..0a64a1642 100644 --- a/Ryujinx.HLE/OsHle/Ipc/IpcMessage.cs +++ b/Ryujinx.HLE/OsHle/Ipc/IpcMessage.cs @@ -15,7 +15,7 @@ namespace Ryujinx.HLE.OsHle.Ipc public List ExchangeBuff { get; private set; } public List RecvListBuff { get; private set; } - public List ResponseObjIds { get; private set; } + public List ObjectIds { get; private set; } public byte[] RawData { get; set; } @@ -27,7 +27,7 @@ namespace Ryujinx.HLE.OsHle.Ipc ExchangeBuff = new List(); RecvListBuff = new List(); - ResponseObjIds = new List(); + ObjectIds = new List(); } public IpcMessage(byte[] Data, long CmdPtr) : this() diff --git a/Ryujinx.HLE/OsHle/Services/IpcService.cs b/Ryujinx.HLE/OsHle/Services/IpcService.cs index 25fd56fec..3c1a136f1 100644 --- a/Ryujinx.HLE/OsHle/Services/IpcService.cs +++ b/Ryujinx.HLE/OsHle/Services/IpcService.cs @@ -50,9 +50,18 @@ namespace Ryujinx.HLE.OsHle.Services int DomainWord0 = Context.RequestData.ReadInt32(); int DomainObjId = Context.RequestData.ReadInt32(); - long Padding = Context.RequestData.ReadInt64(); + int DomainCmd = (DomainWord0 >> 0) & 0xff; + int InputObjCount = (DomainWord0 >> 8) & 0xff; + int DataPayloadSize = (DomainWord0 >> 16) & 0xffff; - int DomainCmd = DomainWord0 & 0xff; + Context.RequestData.BaseStream.Seek(0x10 + DataPayloadSize, SeekOrigin.Begin); + + for (int Index = 0; Index < InputObjCount; Index++) + { + Context.Request.ObjectIds.Add(Context.RequestData.ReadInt32()); + } + + Context.RequestData.BaseStream.Seek(0x10, SeekOrigin.Begin); if (DomainCmd == 1) { @@ -88,14 +97,14 @@ namespace Ryujinx.HLE.OsHle.Services if (IsDomain) { - foreach (int Id in Context.Response.ResponseObjIds) + foreach (int Id in Context.Response.ObjectIds) { Context.ResponseData.Write(Id); } Context.ResponseData.BaseStream.Seek(0, SeekOrigin.Begin); - Context.ResponseData.Write(Context.Response.ResponseObjIds.Count); + Context.ResponseData.Write(Context.Response.ObjectIds.Count); } Context.ResponseData.BaseStream.Seek(IsDomain ? 0x10 : 0, SeekOrigin.Begin); @@ -117,7 +126,7 @@ namespace Ryujinx.HLE.OsHle.Services if (Service.IsDomain) { - Context.Response.ResponseObjIds.Add(Service.Add(Obj)); + Context.Response.ObjectIds.Add(Service.Add(Obj)); } else { @@ -129,6 +138,26 @@ namespace Ryujinx.HLE.OsHle.Services } } + protected static T GetObject(ServiceCtx Context, int Index) where T : IpcService + { + IpcService Service = Context.Session.Service; + + if (!Service.IsDomain) + { + int Handle = Context.Request.HandleDesc.ToMove[Index]; + + KSession Session = Context.Process.HandleTable.GetData(Handle); + + return Session?.Service is T ? (T)Session.Service : null; + } + + int ObjId = Context.Request.ObjectIds[Index]; + + IIpcService Obj = Service.GetObject(ObjId); + + return Obj is T ? (T)Obj : null; + } + private int Add(IIpcService Obj) { return DomainObjects.Add(Obj); diff --git a/Ryujinx.HLE/OsHle/Services/Nifm/IRequest.cs b/Ryujinx.HLE/OsHle/Services/Nifm/IRequest.cs index c8c679c4c..2056187dd 100644 --- a/Ryujinx.HLE/OsHle/Services/Nifm/IRequest.cs +++ b/Ryujinx.HLE/OsHle/Services/Nifm/IRequest.cs @@ -12,7 +12,8 @@ namespace Ryujinx.HLE.OsHle.Services.Nifm public override IReadOnlyDictionary Commands => m_Commands; - private KEvent Event; + private KEvent Event0; + private KEvent Event1; public IRequest() { @@ -26,12 +27,13 @@ namespace Ryujinx.HLE.OsHle.Services.Nifm { 11, SetConnectionConfirmationOption } }; - Event = new KEvent(); + Event0 = new KEvent(); + Event1 = new KEvent(); } public long GetRequestState(ServiceCtx Context) { - Context.ResponseData.Write(0); + Context.ResponseData.Write(1); Context.Ns.Log.PrintStub(LogClass.ServiceNifm, "Stubbed."); @@ -45,13 +47,12 @@ namespace Ryujinx.HLE.OsHle.Services.Nifm return 0; } - //GetSystemEventReadableHandles() -> (KObject, KObject) public long GetSystemEventReadableHandles(ServiceCtx Context) { - //FIXME: Is this supposed to return 2 events? - int Handle = Context.Process.HandleTable.OpenHandle(Event); + int Handle0 = Context.Process.HandleTable.OpenHandle(Event0); + int Handle1 = Context.Process.HandleTable.OpenHandle(Event1); - Context.Response.HandleDesc = IpcHandleDesc.MakeMove(Handle); + Context.Response.HandleDesc = IpcHandleDesc.MakeCopy(Handle0, Handle1); return 0; } @@ -86,7 +87,8 @@ namespace Ryujinx.HLE.OsHle.Services.Nifm { if (Disposing) { - Event.Dispose(); + Event0.Dispose(); + Event1.Dispose(); } } }