| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| 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; |
| |
| |
| request = &inbuf; |
| ntapi->tt_aligned_block_memset( |
| request,0,sizeof(*request)); |
| |
| |
| ntapi->zw_reply_wait_receive_port( |
| dctx->hport_daemon, |
| &port_id, |
| 0,(nt_port_message *)request); |
| |
| |
| 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; |
| } |
| |
| |
| 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; |
| } |