public IpcRequest(Switch device, KThread thread, KClientSession session, ulong messagePtr, ulong messageSize) { Device = device; Thread = thread; Session = session; MessagePtr = messagePtr; MessageSize = messageSize; }
public HleIpcMessage( KThread thread, KClientSession session, IpcMessage message, long messagePtr) { Thread = thread; Session = session; Message = message; MessagePtr = messagePtr; }
private KernelResult SendSyncRequest_(int handle) { KProcess currentProcess = _system.Scheduler.GetCurrentProcess(); KClientSession session = currentProcess.HandleTable.GetObject <KClientSession>(handle); if (session == null) { return(KernelResult.InvalidHandle); } return(session.SendSyncRequest()); }
private KernelResult SendSyncRequest(ulong messagePtr, ulong size, int handle) { byte[] messageData = _process.CpuMemory.ReadBytes((long)messagePtr, (long)size); KClientSession clientSession = _process.HandleTable.GetObject <KClientSession>(handle); if (clientSession == null || clientSession.Service == null) { return(SendSyncRequest_(handle)); } if (clientSession != null) { _system.CriticalSection.Enter(); KThread currentThread = _system.Scheduler.GetCurrentThread(); currentThread.SignaledObj = null; currentThread.ObjSyncResult = KernelResult.Success; currentThread.Reschedule(ThreadSchedState.Paused); IpcMessage message = new IpcMessage(messageData, (long)messagePtr); ThreadPool.QueueUserWorkItem(ProcessIpcRequest, new HleIpcMessage( currentThread, clientSession, message, (long)messagePtr)); _system.ThreadCounter.AddCount(); _system.CriticalSection.Leave(); return(currentThread.ObjSyncResult); } else { Logger.PrintWarning(LogClass.KernelSvc, $"Invalid session handle 0x{handle:x8}!"); return(KernelResult.InvalidHandle); } }
protected static T GetObject <T>(ServiceCtx context, int index) where T : IpcService { IpcService service = context.Session.Service; if (!service._isDomain) { int handle = context.Request.HandleDesc.ToMove[index]; KClientSession session = context.Process.HandleTable.GetObject <KClientSession>(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); }
public ServiceCtx( Switch device, KProcess process, MemoryManager memory, KClientSession session, IpcMessage request, IpcMessage response, BinaryReader requestData, BinaryWriter responseData) { Device = device; Process = process; Memory = memory; Session = session; Request = request; Response = response; RequestData = requestData; ResponseData = responseData; }
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); }
public void PushMessage(Switch device, KThread thread, KClientSession session, ulong messagePtr, ulong messageSize) { _ipcProcessor.Add(new IpcRequest(device, thread, session, messagePtr, messageSize)); }