/*********************************************************/ /* ptycon: a pty-console bridge */ /* Copyright (C) 2016--2017 SysDeer Technologies, LLC */ /* Released under GPLv2 and GPLv3; see COPYING.PTYCON. */ /*********************************************************/ #include #include #include #include "ptycon_daemon_impl.h" #include "ptycon_driver_impl.h" #define PTYC_VTBL_ELEMENTS PTYC_DAEMON_OPCODE_CAP - PTYC_DAEMON_OPCODE_BASE static ptyc_daemon_routine * ptyc_daemon_vtbl[PTYC_VTBL_ELEMENTS] = { ptyc_daemon_connect, 0, ptyc_daemon_signal, 0, 0, 0 }; int32_t __stdcall ptyc_daemon_loop(void * ctx) { struct ptyc_daemon_ctx * dctx; nt_rtdata * rtdata; nt_tty_port_msg inbuf; nt_tty_port_msg outbuf; nt_tty_port_msg * request; nt_tty_port_msg * reply; intptr_t port_id; int32_t opcode; if (ntapi->tt_get_runtime_data(&rtdata,0)) return NT_STATUS_INTERNAL_ERROR; dctx = (struct ptyc_daemon_ctx *)ctx; /* init */ request = &inbuf; ntapi->tt_aligned_block_memset( request,0,sizeof(*request)); /* get first message */ ntapi->zw_reply_wait_receive_port( dctx->hport_daemon, &port_id, 0,(nt_port_message *)request); /* message loop */ do { switch (request->header.msg_type) { case NT_LPC_REQUEST: case NT_LPC_DATAGRAM: opcode = request->ttyinfo.opcode; break; case NT_LPC_CONNECTION_REQUEST: opcode = PTYC_DAEMON_CONNECT; break; default: opcode = -1; break; } /* dispatch */ reply = &outbuf; ntapi->tt_aligned_block_memcpy( (uintptr_t *)reply, (uintptr_t *)request, sizeof(*reply)); reply->header.msg_type = NT_LPC_REPLY; if ((opcode >= PTYC_DAEMON_OPCODE_BASE) && (opcode < PTYC_DAEMON_OPCODE_CAP)) { reply->ttyinfo.exarg = (void *)request->header.client_id.process_id; opcode -= PTYC_DAEMON_OPCODE_BASE; if (ptyc_daemon_vtbl[opcode]) reply->ttyinfo.status = ptyc_daemon_vtbl[opcode](reply); else reply->ttyinfo.status = NT_STATUS_NOT_IMPLEMENTED; } else { reply->ttyinfo.exarg = NT_INVALID_HANDLE_VALUE; reply->ttyinfo.status = NT_STATUS_LPC_INVALID_CONNECTION_USAGE; } ntapi->tt_aligned_block_memset( request,0,sizeof(*request)); reply = reply->ttyinfo.exarg ? &outbuf : 0; if (!reply) ntapi->zw_reply_wait_receive_port( dctx->hport_daemon, &port_id, 0,&request->header); else if (reply->header.client_id.process_id == rtdata->cid_self.process_id) ntapi->zw_reply_wait_receive_port( dctx->hport_daemon, &port_id, &reply->header, &request->header); else { ntapi->zw_reply_port( dctx->hport_daemon, &reply->header); ntapi->zw_reply_wait_receive_port( dctx->hport_daemon, &port_id, 0,&request->header); } } while (request->header.msg_id); return NT_STATUS_INTERNAL_ERROR; }