Esempio n. 1
0
        private void Process(IpcRequest message)
        {
            byte[] reqData = new byte[message.MessageSize];

            message.Process.CpuMemory.Read(message.MessagePtr, reqData);

            IpcMessage request  = new IpcMessage(reqData, (long)message.MessagePtr);
            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(
                            message.Device,
                            message.Process,
                            message.Process.CpuMemory,
                            message.Thread,
                            message.Session,
                            request,
                            response,
                            reqReader,
                            resWriter);

                        message.Session.Service.CallMethod(context);

                        response.RawData = resMs.ToArray();
                    }
                }
                else if (request.Type == IpcMessageType.Control ||
                         request.Type == IpcMessageType.ControlWithContext)
                {
                    uint magic = (uint)reqReader.ReadUInt64();
                    uint cmdId = (uint)reqReader.ReadUInt64();

                    switch (cmdId)
                    {
                    case 0:
                        request = FillResponse(response, 0, message.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 (message.Process.HandleTable.GenerateHandle(message.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)
                {
                    message.SignalDone(KernelResult.PortRemoteClosed);
                    return;
                }
                else
                {
                    throw new NotImplementedException(request.Type.ToString());
                }

                message.Process.CpuMemory.Write(message.MessagePtr, response.GetBytes((long)message.MessagePtr));
            }

            message.SignalDone(KernelResult.Success);
        }