/*********************************************************/ /* ptycon: a pty-console bridge */ /* Copyright (C) 2016--2017 SysDeer Technologies, LLC */ /* Released under GPLv2 and GPLv3; see COPYING.PTYCON. */ /*********************************************************/ #include #include #include #include #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; } }