1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
/*********************************************************/
/* ptycon: a pty-console bridge */
/* Copyright (C) 2016--2017 SysDeer Technologies, LLC */
/* Released under GPLv2 and GPLv3; see COPYING.PTYCON. */
/*********************************************************/
#include <psxtypes/psxtypes.h>
#include <ntapi/ntapi.h>
#include <ptycon/ptycon.h>
#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;
}
|