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
126
127
128
|
/*********************************************************/
/* ptycon: a pty-console bridge */
/* Copyright (C) 2016--2017 Z. Gilboa */
/* Released under GPLv2 and GPLv3; see COPYING.PTYCON. */
/*********************************************************/
#include <psxtypes/psxtypes.h>
#include <ntapi/ntapi.h>
#include <ntapi/nt_atomic.h>
#include <ptycon/ptycon.h>
#include "ptycon_daemon_impl.h"
#include "ptycon_driver_impl.h"
static const nt_guid ptyc_daemon_guid = PTYC_PORT_GUID_DAEMON;
static int32_t ptyc_daemon_init_impl(struct ptyc_daemon_ctx * dctx, void * htty)
{
int32_t status;
nt_daemon_params dparams;
wchar16_t * port_name;
nt_port_name_keys * port_name_keys;
/* daemon attributes */
dctx->daemon_attr.type = NT_PORT_TYPE_DAEMON;
dctx->daemon_attr.subtype = NT_PORT_SUBTYPE_DEFAULT;
/* port guid */
ntapi->tt_guid_copy(
&dctx->daemon_attr.guid,
&ptyc_daemon_guid);
/* port keys */
if ((status = ntapi->tt_port_generate_keys(&dctx->daemon_attr.keys)))
return status;
/* port name */
ntapi->tt_port_name_from_attr(
&dctx->daemon_name,
&dctx->daemon_attr);
/* dparams */
ntapi->tt_aligned_block_memset(
&dparams,0,sizeof(dparams));
port_name = (wchar16_t *)&dctx->daemon_name;
port_name_keys = (nt_port_name_keys *)&dctx->daemon_name.port_name_keys;
dparams.port_keys = &dctx->daemon_keys;
dparams.port_name = port_name;
dparams.port_name_keys = port_name_keys;
dparams.port_msg_size = sizeof(nt_tty_port_msg);
dparams.flags = NT_DSR_INIT_DEFAULT;
dparams.daemon_once_routine = 0;
dparams.daemon_loop_routine = ptyc_daemon_loop;
dparams.daemon_loop_context = dctx;
dparams.pport_daemon = &dctx->hport_daemon;
dparams.pport_internal_client = &dctx->hport_internal_client;
dparams.pevent_daemon_ready = &dctx->hevent_daemon_ready;
dparams.pevent_internal_client_ready = &dctx->hevent_internal_client_ready;
dparams.stack_size_commit = 8192;
dparams.stack_size_reserve = 8192;
if ((status = ntapi->dsr_init(&dparams)))
return status;
return ntapi->tty_request_peer(
htty,
PTYC_DAEMON_TTYSIGNAL,
0,&(nt_guid)TTY_PTS_GUID,
&dctx->daemon_attr);
}
static int32_t ptyc_daemon_once = 0;
int32_t __stdcall ptyc_daemon_init(struct ptyc_daemon_ctx * dctx, uint64_t drvflags)
{
int32_t status;
nt_timeout timeout;
nt_runtime_data * rtdata;
/* rtdata */
if ((status = ntapi->tt_get_runtime_data(&rtdata,0)))
return status;
/* needed? */
if (drvflags & PTYC_DRIVER_DAEMON_NEVER)
return 0;
if (!(drvflags & PTYC_DRIVER_DAEMON_ALWAYS))
if (ntapi->tt_guid_compare(&rtdata->srv_guid,&ptyc_daemon_guid))
return 0;
/* once */
switch (at_locked_cas_32(&ptyc_daemon_once,0,1)) {
case 0:
if ((status = ptyc_daemon_init_impl(dctx,rtdata->hsession))) {
at_locked_add_32(&ptyc_daemon_once,2);
return status;
}
at_locked_inc_32(&ptyc_daemon_once);
return 0;
case 1:
timeout.quad = -10;
for (; (at_locked_cas_32(&ptyc_daemon_once,0,1) == 1); )
ntapi->zw_delay_execution(
NT_SYNC_ALERTABLE,
&timeout);
return (ptyc_daemon_once == 2)
? 0 : -1;
case 2:
return 0;
case 3:
default:
return -1;
}
}
|