diff options
Diffstat (limited to 'src/daemon')
-rw-r--r-- | src/daemon/ptyc_daemon_loop.c | 111 |
1 files changed, 109 insertions, 2 deletions
diff --git a/src/daemon/ptyc_daemon_loop.c b/src/daemon/ptyc_daemon_loop.c index 954ed8c..27ed0e5 100644 --- a/src/daemon/ptyc_daemon_loop.c +++ b/src/daemon/ptyc_daemon_loop.c @@ -11,8 +11,115 @@ #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, + 0, + 0, + 0, + 0 +}; + int32_t __stdcall ptyc_daemon_loop(void * ctx) { - (void)ctx; - return ntapi->tt_wait_for_dummy_event(); + 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.reserved = (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.reserved = 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.reserved + ? &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; } |