public static long IpcCall( Switch Ns, Process Process, MemoryManager Memory, KSession Session, IpcMessage Request, long CmdPtr) { IpcMessage Response = new IpcMessage(); using (MemoryStream Raw = new MemoryStream(Request.RawData)) { BinaryReader ReqReader = new BinaryReader(Raw); if (Request.Type == IpcMessageType.Request || Request.Type == IpcMessageType.RequestWithContext) { Response.Type = IpcMessageType.Response; using (MemoryStream ResMS = new MemoryStream()) { BinaryWriter ResWriter = new BinaryWriter(ResMS); ServiceCtx Context = new ServiceCtx( Ns, Process, Memory, Session, Request, Response, ReqReader, ResWriter); Session.Service.CallMethod(Context); Response.RawData = ResMS.ToArray(); } } else if (Request.Type == IpcMessageType.Control || Request.Type == IpcMessageType.ControlWithContext) { long Magic = ReqReader.ReadInt64(); long CmdId = ReqReader.ReadInt64(); switch (CmdId) { case 0: { Request = FillResponse(Response, 0, Session.Service.ConvertToDomain()); break; } case 3: { Request = FillResponse(Response, 0, 0x500); break; } //TODO: Whats the difference between IpcDuplicateSession/Ex? case 2: case 4: { int Unknown = ReqReader.ReadInt32(); if (Process.HandleTable.GenerateHandle(Session, out int Handle) != KernelResult.Success) { throw new InvalidOperationException("Out of handles!"); } Response.HandleDesc = IpcHandleDesc.MakeMove(Handle); Request = FillResponse(Response, 0); break; } default: throw new NotImplementedException(CmdId.ToString()); } } else if (Request.Type == IpcMessageType.CloseSession) { //TODO } else { throw new NotImplementedException(Request.Type.ToString()); } Memory.WriteBytes(CmdPtr, Response.GetBytes(CmdPtr)); } return(0); }
public static KernelResult IpcCall( Switch device, KProcess process, MemoryManager memory, KThread thread, KClientSession session, IpcMessage request, long cmdPtr) { IpcMessage response = new IpcMessage(); using (MemoryStream raw = new MemoryStream(request.RawData)) { BinaryReader reqReader = new BinaryReader(raw); if (request.Type == IpcMessageType.Request || request.Type == IpcMessageType.RequestWithContext) { response.Type = IpcMessageType.Response; using (MemoryStream resMs = new MemoryStream()) { BinaryWriter resWriter = new BinaryWriter(resMs); ServiceCtx context = new ServiceCtx( device, process, memory, thread, session, request, response, reqReader, resWriter); session.Service.CallMethod(context); response.RawData = resMs.ToArray(); } } else if (request.Type == IpcMessageType.Control || request.Type == IpcMessageType.ControlWithContext) { long magic = reqReader.ReadInt64(); long cmdId = reqReader.ReadInt64(); switch (cmdId) { case 0: { request = FillResponse(response, 0, session.Service.ConvertToDomain()); break; } case 3: { request = FillResponse(response, 0, 0x1000); break; } // TODO: Whats the difference between IpcDuplicateSession/Ex? case 2: case 4: { int unknown = reqReader.ReadInt32(); if (process.HandleTable.GenerateHandle(session, out int handle) != KernelResult.Success) { throw new InvalidOperationException("Out of handles!"); } response.HandleDesc = IpcHandleDesc.MakeMove(handle); request = FillResponse(response, 0); break; } default: throw new NotImplementedException(cmdId.ToString()); } } else if (request.Type == IpcMessageType.CloseSession) { // TODO return(KernelResult.PortRemoteClosed); } else { throw new NotImplementedException(request.Type.ToString()); } memory.WriteBytes(cmdPtr, response.GetBytes(cmdPtr)); } return(KernelResult.Success); }