private void Initialize(BinaryReader reader, long cmdPtr) { int word0 = reader.ReadInt32(); int word1 = reader.ReadInt32(); Type = (IpcMessageType)(word0 & 0xffff); int ptrBuffCount = (word0 >> 16) & 0xf; int sendBuffCount = (word0 >> 20) & 0xf; int recvBuffCount = (word0 >> 24) & 0xf; int xchgBuffCount = (word0 >> 28) & 0xf; int rawDataSize = (word1 >> 0) & 0x3ff; int recvListFlags = (word1 >> 10) & 0xf; bool hndDescEnable = ((word1 >> 31) & 0x1) != 0; if (hndDescEnable) { HandleDesc = new IpcHandleDesc(reader); } for (int index = 0; index < ptrBuffCount; index++) { PtrBuff.Add(new IpcPtrBuffDesc(reader)); } void ReadBuff(List <IpcBuffDesc> buff, int count) { for (int index = 0; index < count; index++) { buff.Add(new IpcBuffDesc(reader)); } } ReadBuff(SendBuff, sendBuffCount); ReadBuff(ReceiveBuff, recvBuffCount); ReadBuff(ExchangeBuff, xchgBuffCount); rawDataSize *= 4; long recvListPos = reader.BaseStream.Position + rawDataSize; // only HIPC have the padding requirements. if (Type < IpcMessageType.TipcCloseSession) { long pad0 = GetPadSize16(reader.BaseStream.Position + cmdPtr); if (rawDataSize != 0) { rawDataSize -= (int)pad0; } reader.BaseStream.Seek(pad0, SeekOrigin.Current); } int recvListCount = recvListFlags - 2; if (recvListCount == 0) { recvListCount = 1; } else if (recvListCount < 0) { recvListCount = 0; } RawData = reader.ReadBytes(rawDataSize); reader.BaseStream.Seek(recvListPos, SeekOrigin.Begin); for (int index = 0; index < recvListCount; index++) { RecvListBuff.Add(new IpcRecvListBuffDesc(reader)); } }
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); }
private void Initialize(BinaryReader Reader, long CmdPtr) { int Word0 = Reader.ReadInt32(); int Word1 = Reader.ReadInt32(); Type = (IpcMessageType)(Word0 & 0xffff); int PtrBuffCount = (Word0 >> 16) & 0xf; int SendBuffCount = (Word0 >> 20) & 0xf; int RecvBuffCount = (Word0 >> 24) & 0xf; int XchgBuffCount = (Word0 >> 28) & 0xf; int RawDataSize = (Word1 >> 0) & 0x3ff; int RecvListFlags = (Word1 >> 10) & 0xf; bool HndDescEnable = ((Word1 >> 31) & 0x1) != 0; if (HndDescEnable) { HandleDesc = new IpcHandleDesc(Reader); } for (int Index = 0; Index < PtrBuffCount; Index++) { PtrBuff.Add(new IpcPtrBuffDesc(Reader)); } void ReadBuff(List <IpcBuffDesc> Buff, int Count) { for (int Index = 0; Index < Count; Index++) { Buff.Add(new IpcBuffDesc(Reader)); } } ReadBuff(SendBuff, SendBuffCount); ReadBuff(ReceiveBuff, RecvBuffCount); ReadBuff(ExchangeBuff, XchgBuffCount); RawDataSize *= 4; long RecvListPos = Reader.BaseStream.Position + RawDataSize; long Pad0 = GetPadSize16(Reader.BaseStream.Position + CmdPtr); Reader.BaseStream.Seek(Pad0, SeekOrigin.Current); int RecvListCount = RecvListFlags - 2; if (RecvListCount == 0) { RecvListCount = 1; } else if (RecvListCount < 0) { RecvListCount = 0; } RawData = Reader.ReadBytes(RawDataSize); Reader.BaseStream.Seek(RecvListPos, SeekOrigin.Begin); for (int Index = 0; Index < RecvListCount; Index++) { RecvListBuff.Add(new IpcRecvListBuffDesc(Reader)); } }
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); }