Blame src/daemon/ptyc_daemon_loop.c

778de5
/*********************************************************/
778de5
/*  ptycon: a pty-console bridge                         */
f25e99
/*  Copyright (C) 2016--2017  SysDeer Technologies, LLC  */
778de5
/*  Released under GPLv2 and GPLv3; see COPYING.PTYCON.  */
778de5
/*********************************************************/
778de5
778de5
#include <psxtypes/psxtypes.h>
778de5
#include <ntapi/ntapi.h>
778de5
778de5
#include <ptycon/ptycon.h>
778de5
#include "ptycon_daemon_impl.h"
778de5
#include "ptycon_driver_impl.h"
778de5
08072c
#define PTYC_VTBL_ELEMENTS   PTYC_DAEMON_OPCODE_CAP - PTYC_DAEMON_OPCODE_BASE
08072c
08072c
static ptyc_daemon_routine * ptyc_daemon_vtbl[PTYC_VTBL_ELEMENTS] = {
08072c
	ptyc_daemon_connect,
08072c
	0,
87ae0a
	ptyc_daemon_signal,
08072c
	0,
08072c
	0,
08072c
	0
08072c
};
08072c
447147
static int ptyc_init_pidmap_target_symlink(struct ptyc_daemon_ctx * dctx)
447147
{
447147
	int     status;
447147
	void *  hkeydir;
447147
447147
	struct ptyc_driver_ctx_impl * ictx = ptyc_get_driver_ictx(dctx->driver_ctx);
447147
447147
	if ((status = ntapi->tt_create_keyed_object_directory(
447147
			&hkeydir,
447147
			NT_SYMBOLIC_LINK_ALL_ACCESS,
447147
			ictx->rtdata->hpidmapdir,
447147
			pe_get_current_process_id())))
447147
		return status;
447147
447147
	if ((status = ntapi->zw_set_information_object(
447147
			hkeydir,
447147
			NT_OBJECT_HANDLE_INFORMATION,
447147
			&(nt_object_handle_information){0,0},
447147
			sizeof(nt_object_handle_information))))
447147
		return status;
447147
447147
	return ntapi->tt_create_keyed_object_directory_entry(
447147
		&ictx->hntpipc,
447147
		NT_SYMBOLIC_LINK_ALL_ACCESS,
447147
		hkeydir,
447147
		dctx->hport_daemon,0,
447147
		pe_get_current_process_id());
447147
}
447147
447147
static int ptyc_init_ntpipc_target_symlink(struct ptyc_daemon_ctx * dctx)
447147
{
447147
	struct ptyc_driver_ctx_impl * ictx = ptyc_get_driver_ictx(dctx->driver_ctx);
447147
447147
	return ntapi->tt_create_keyed_object_directory_entry(
447147
		&ictx->hntpipc,
447147
		NT_SYMBOLIC_LINK_ALL_ACCESS,
447147
		ictx->rtdata->hntpipcdir,
447147
		dctx->hport_daemon,0,
447147
		pe_get_current_process_id());
447147
}
447147
778de5
int32_t __stdcall ptyc_daemon_loop(void * ctx)
778de5
{
447147
	int                             status;
447147
08072c
	struct ptyc_daemon_ctx *	dctx;
08072c
	nt_rtdata *			rtdata;
08072c
08072c
	nt_tty_port_msg			inbuf;
08072c
	nt_tty_port_msg			outbuf;
08072c
08072c
	nt_tty_port_msg *		request;
08072c
	nt_tty_port_msg *		reply;
08072c
08072c
	intptr_t			port_id;
08072c
	int32_t				opcode;
08072c
08072c
	if (ntapi->tt_get_runtime_data(&rtdata,0))
08072c
		return NT_STATUS_INTERNAL_ERROR;
08072c
08072c
	dctx = (struct ptyc_daemon_ctx *)ctx;
08072c
447147
	/* pidmap daemon symlink */
447147
	if ((status = ptyc_init_pidmap_target_symlink(dctx)))
447147
		return status;
447147
447147
	/* ntpipc daemon symlink */
447147
	if ((status = ptyc_init_ntpipc_target_symlink(dctx)))
447147
		return status;
447147
08072c
	/* init */
08072c
	request = &inbuf;
08072c
	ntapi->tt_aligned_block_memset(
08072c
		request,0,sizeof(*request));
08072c
08072c
	/* get first message */
08072c
	ntapi->zw_reply_wait_receive_port(
08072c
		dctx->hport_daemon,
08072c
		&port_id,
08072c
		0,(nt_port_message *)request);
08072c
08072c
	/* message loop */
08072c
	do {
08072c
		switch (request->header.msg_type) {
08072c
			case NT_LPC_REQUEST:
08072c
			case NT_LPC_DATAGRAM:
08072c
				opcode = request->ttyinfo.opcode;
08072c
				break;
08072c
08072c
			case NT_LPC_CONNECTION_REQUEST:
08072c
				opcode = PTYC_DAEMON_CONNECT;
08072c
				break;
08072c
08072c
			default:
08072c
				opcode = -1;
08072c
				break;
08072c
		}
08072c
08072c
		/* dispatch */
08072c
		reply = &outbuf;
08072c
08072c
		ntapi->tt_aligned_block_memcpy(
08072c
			(uintptr_t *)reply,
08072c
			(uintptr_t *)request,
08072c
			sizeof(*reply));
08072c
08072c
		reply->header.msg_type = NT_LPC_REPLY;
08072c
08072c
		if ((opcode >= PTYC_DAEMON_OPCODE_BASE) && (opcode < PTYC_DAEMON_OPCODE_CAP)) {
ab99f6
			reply->ttyinfo.exarg = (void *)request->header.client_id.process_id;
08072c
			opcode -= PTYC_DAEMON_OPCODE_BASE;
08072c
08072c
			if (ptyc_daemon_vtbl[opcode])
08072c
				reply->ttyinfo.status = ptyc_daemon_vtbl[opcode](reply);
08072c
			else
08072c
				reply->ttyinfo.status = NT_STATUS_NOT_IMPLEMENTED;
08072c
		} else {
ab99f6
			reply->ttyinfo.exarg    = NT_INVALID_HANDLE_VALUE;
08072c
			reply->ttyinfo.status   = NT_STATUS_LPC_INVALID_CONNECTION_USAGE;
08072c
		}
08072c
08072c
		ntapi->tt_aligned_block_memset(
08072c
			request,0,sizeof(*request));
08072c
ab99f6
		reply = reply->ttyinfo.exarg
08072c
			? &outbuf : 0;
08072c
08072c
		if (!reply)
08072c
			ntapi->zw_reply_wait_receive_port(
08072c
				dctx->hport_daemon,
08072c
				&port_id,
08072c
				0,&request->header);
08072c
		else if (reply->header.client_id.process_id == rtdata->cid_self.process_id)
08072c
			ntapi->zw_reply_wait_receive_port(
08072c
				dctx->hport_daemon,
08072c
				&port_id,
08072c
				&reply->header,
08072c
				&request->header);
08072c
		else {
08072c
			ntapi->zw_reply_port(
08072c
				dctx->hport_daemon,
08072c
				&reply->header);
08072c
08072c
			ntapi->zw_reply_wait_receive_port(
08072c
				dctx->hport_daemon,
08072c
				&port_id,
08072c
				0,&request->header);
08072c
		}
08072c
	} while (request->header.msg_id);
08072c
08072c
	return NT_STATUS_INTERNAL_ERROR;
778de5
}