Blame src/daemon/toks_daemon_loop.c

5e5175
/*********************************************************/
5e5175
/*  toksvc: a framework-native token broker service      */
5e5175
/*  Copyright (C) 2020  Z. Gilboa                        */
5e5175
/*  Released under GPLv2 and GPLv3; see COPYING.TOKSVC.  */
5e5175
/*********************************************************/
5e5175
5e5175
#include <psxtypes/psxtypes.h>
5e5175
#include <ntapi/ntapi.h>
5e5175
5e5175
#include <toksvc/toksvc.h>
5e5175
#include "toksvc_daemon_impl.h"
5e5175
#include "toksvc_driver_impl.h"
f2a689
#include "toksvc_log_impl.h"
5e5175
d6a03d
#define  TOKS_VTBL_ELEMENTS   TOKS_DAEMON_OPCODE_CAP - TOKS_DAEMON_OPCODE_BASE
d6a03d
d6a03d
#define  TOKS_OPCODE_IDX(IDX) TOKS_DAEMON_ ## IDX - TOKS_DAEMON_OPCODE_BASE
d6a03d
#define  TOKS_HANDLER(IDX,fn) [TOKS_OPCODE_IDX(IDX)] = fn
d6a03d
5e5175
5e5175
static toks_daemon_routine * toks_daemon_vtbl[TOKS_VTBL_ELEMENTS] = {
d6a03d
	TOKS_HANDLER(CONNECT,       toks_daemon_connect),
d6a03d
	TOKS_HANDLER(TTYSIGNAL,     toks_daemon_signal),
44e933
	TOKS_HANDLER(ACQUIRE,       toks_daemon_acquire),
c78a06
	TOKS_HANDLER(RELEASE,       toks_daemon_release),
5e5175
};
5e5175
5e5175
int32_t __stdcall toks_daemon_loop(void * ctx)
5e5175
{
5e5175
	struct toks_daemon_ctx *	dctx;
5e5175
	nt_rtdata *			rtdata;
5e5175
5e5175
	nt_tty_port_msg *		request;
5e5175
	nt_tty_port_msg *		reply;
5e5175
5e5175
	intptr_t			port_id;
5e5175
	int32_t				opcode;
5e5175
5e5175
	if (ntapi->tt_get_runtime_data(&rtdata,0))
5e5175
		return NT_STATUS_INTERNAL_ERROR;
5e5175
5e5175
	dctx = (struct toks_daemon_ctx *)ctx;
5e5175
5e5175
	/* init */
9985a1
	request = &dctx->request;
9985a1
	reply   = &dctx->reply;
9985a1
5e5175
	ntapi->tt_aligned_block_memset(
5e5175
		request,0,sizeof(*request));
5e5175
5e5175
	/* get first message */
5e5175
	ntapi->zw_reply_wait_receive_port(
5e5175
		dctx->hport_daemon,
5e5175
		&port_id,
5e5175
		0,(nt_port_message *)request);
5e5175
5e5175
	/* message loop */
5e5175
	do {
f2a689
		toks_log_lpc_request(dctx->driver_ctx,request);
f2a689
5e5175
		switch (request->header.msg_type) {
5e5175
			case NT_LPC_REQUEST:
5e5175
			case NT_LPC_DATAGRAM:
5e5175
				opcode = request->ttyinfo.opcode;
5e5175
				break;
5e5175
5e5175
			case NT_LPC_CONNECTION_REQUEST:
5e5175
				opcode = TOKS_DAEMON_CONNECT;
5e5175
				break;
5e5175
5e5175
			default:
5e5175
				opcode = -1;
5e5175
				break;
5e5175
		}
5e5175
5e5175
		/* dispatch */
5e5175
		ntapi->tt_aligned_block_memcpy(
5e5175
			(uintptr_t *)reply,
5e5175
			(uintptr_t *)request,
5e5175
			sizeof(*reply));
5e5175
5e5175
		reply->header.msg_type = NT_LPC_REPLY;
5e5175
5e5175
		if ((opcode >= TOKS_DAEMON_OPCODE_BASE) && (opcode < TOKS_DAEMON_OPCODE_CAP)) {
5e5175
			reply->ttyinfo.exarg = (void *)request->header.client_id.process_id;
5e5175
			opcode -= TOKS_DAEMON_OPCODE_BASE;
5e5175
5e5175
			if (toks_daemon_vtbl[opcode])
9985a1
				reply->ttyinfo.status = toks_daemon_vtbl[opcode](dctx);
5e5175
			else
5e5175
				reply->ttyinfo.status = NT_STATUS_NOT_IMPLEMENTED;
5e5175
		} else {
5e5175
			reply->ttyinfo.exarg    = NT_INVALID_HANDLE_VALUE;
5e5175
			reply->ttyinfo.status   = NT_STATUS_LPC_INVALID_CONNECTION_USAGE;
5e5175
		}
5e5175
5e5175
		ntapi->tt_aligned_block_memset(
5e5175
			request,0,sizeof(*request));
5e5175
9985a1
		if (!reply->ttyinfo.exarg)
5e5175
			ntapi->zw_reply_wait_receive_port(
5e5175
				dctx->hport_daemon,
5e5175
				&port_id,
5e5175
				0,&request->header);
5e5175
		else if (reply->header.client_id.process_id == rtdata->cid_self.process_id)
5e5175
			ntapi->zw_reply_wait_receive_port(
5e5175
				dctx->hport_daemon,
5e5175
				&port_id,
5e5175
				&reply->header,
5e5175
				&request->header);
5e5175
		else {
5e5175
			ntapi->zw_reply_port(
5e5175
				dctx->hport_daemon,
5e5175
				&reply->header);
5e5175
5e5175
			ntapi->zw_reply_wait_receive_port(
5e5175
				dctx->hport_daemon,
5e5175
				&port_id,
5e5175
				0,&request->header);
5e5175
		}
5e5175
	} while (request->header.msg_id);
5e5175
5e5175
	return NT_STATUS_INTERNAL_ERROR;
5e5175
}