Blame src/daemon/toks_daemon_init.c

5e5175
/*********************************************************/
5e5175
/*  toksvc: a framework-native token broker service      */
d91fa0
/*  Copyright (C) 2020  SysDeer Technologies, LLC        */
5e5175
/*  Released under GPLv2 and GPLv3; see COPYING.TOKSVC.  */
5e5175
/*********************************************************/
5e5175
5e5175
#include <psxtypes/psxtypes.h>
5e5175
#include <ntapi/ntapi.h>
5e5175
#include <ntapi/nt_atomic.h>
5e5175
5e5175
#include <toksvc/toksvc.h>
5e5175
#include "toksvc_daemon_impl.h"
5e5175
#include "toksvc_driver_impl.h"
5e5175
618937
static int32_t toks_daemon_init_impl(
618937
	struct toks_daemon_ctx *    dctx,
618937
	const nt_guid *             svcguid,
618937
	void *                      htty)
5e5175
{
5e5175
	int32_t				status;
5e5175
	nt_daemon_params		dparams;
5e5175
	wchar16_t *			port_name;
5e5175
	nt_port_name_keys *		port_name_keys;
00069c
	void *				hsvclink;
7015e6
	nt_sd_common_buffer		sd;
5e5175
5e5175
	/* daemon attributes */
5e5175
	dctx->daemon_attr.type    = NT_PORT_TYPE_DAEMON;
5e5175
	dctx->daemon_attr.subtype = NT_PORT_SUBTYPE_DEFAULT;
5e5175
5e5175
	/* port guid */
5e5175
	ntapi->tt_guid_copy(
5e5175
		&dctx->daemon_attr.guid,
618937
		svcguid);
5e5175
5e5175
	/* port keys */
5e5175
	if ((status = ntapi->tt_port_generate_keys(&dctx->daemon_attr.keys)))
5e5175
		return status;
5e5175
5e5175
	/* port name */
5e5175
	ntapi->tt_port_name_from_attr(
5e5175
		&dctx->daemon_name,
5e5175
		&dctx->daemon_attr);
5e5175
7015e6
	/* daemon sd */
7015e6
	ntapi->acl_init_common_descriptor(
7015e6
		&sd,0,0,0,0,
7015e6
		NT_PORT_ALL_ACCESS | NT_SEC_STANDARD_RIGHTS_ALL,
7015e6
		NT_PORT_CONNECT | NT_SEC_READ_CONTROL,
7015e6
		NT_PORT_CONNECT | NT_SEC_READ_CONTROL,
7015e6
		NT_PORT_ALL_ACCESS | NT_SEC_STANDARD_RIGHTS_ALL,
7015e6
		NT_PORT_ALL_ACCESS | NT_SEC_STANDARD_RIGHTS_ALL,
7015e6
		0);
7015e6
7015e6
	ntapi->tt_aligned_block_memlock(
7015e6
		&sd,sizeof(sd));
7015e6
5e5175
	/* dparams */
5e5175
	ntapi->tt_aligned_block_memset(
5e5175
		&dparams,0,sizeof(dparams));
5e5175
5e5175
	port_name      = (wchar16_t *)&dctx->daemon_name;
5e5175
	port_name_keys = (nt_port_name_keys *)&dctx->daemon_name.port_name_keys;
5e5175
5e5175
	dparams.port_keys	= &dctx->daemon_keys;
5e5175
	dparams.port_name	= port_name;
5e5175
	dparams.port_name_keys	= port_name_keys;
7015e6
	dparams.port_sd		= &sd.sd;
5e5175
5e5175
	dparams.port_msg_size	= sizeof(nt_tty_port_msg);
5e5175
	dparams.flags		= NT_DSR_INIT_DEFAULT;
5e5175
5e5175
	dparams.daemon_once_routine	= 0;
5e5175
	dparams.daemon_loop_routine	= toks_daemon_loop;
5e5175
	dparams.daemon_loop_context	= dctx;
5e5175
5e5175
	dparams.pport_daemon		= &dctx->hport_daemon;
5e5175
	dparams.pport_internal_client	= &dctx->hport_internal_client;
5e5175
5e5175
	dparams.pevent_daemon_ready		= &dctx->hevent_daemon_ready;
5e5175
	dparams.pevent_internal_client_ready	= &dctx->hevent_internal_client_ready;
5e5175
4a1e54
	dparams.stack_size_commit		= 64 * 1024;
4a1e54
	dparams.stack_size_reserve		= 64 * 1024;
5e5175
5e5175
	if ((status = ntapi->dsr_init(&dparams)))
5e5175
		return status;
00069c
00069c
	if ((status = ntapi->tt_create_dev_object_directory_entry(
00069c
			&hsvclink,
00069c
			NT_SYMBOLIC_LINK_ALL_ACCESS,
00069c
			toks_get_driver_hsvcdir(dctx->driver_ctx),
00069c
			dparams.hport_daemon,0,
00069c
			svcguid)))
00069c
		return status;
00069c
00069c
	toks_set_driver_hsvclink(
00069c
		dctx->driver_ctx,
00069c
		hsvclink);
5e5175
9fcd5a
	return (htty == 0)
9fcd5a
		? NT_STATUS_SUCCESS
9fcd5a
		: ntapi->tty_request_peer(
9fcd5a
			htty,
9fcd5a
			TOKS_DAEMON_TTYSIGNAL,
9fcd5a
			0,&(nt_guid)TTY_PTS_GUID,
9fcd5a
			&dctx->daemon_attr);
5e5175
}
5e5175
5e5175
static int32_t toks_daemon_once = 0;
5e5175
618937
int32_t __stdcall toks_daemon_init(struct toks_daemon_ctx * dctx, const nt_guid * svcguid)
5e5175
{
5e5175
	int32_t			status;
5e5175
	nt_timeout		timeout;
5e5175
	nt_runtime_data *	rtdata;
3e9813
	nt_filetime		pcnt;
3e9813
	nt_guid			cliguid;
3e9813
	uint32_t *		data;
5e5175
5e5175
	/* rtdata */
5e5175
	if ((status = ntapi->tt_get_runtime_data(&rtdata,0)))
5e5175
		return status;
5e5175
3e9813
	/* arbitrary client uuid */
3e9813
	if (!svcguid) {
3e9813
		toks_query_performance_counters(dctx->driver_ctx,&pcnt);
3e9813
3e9813
		svcguid = &cliguid;
3e9813
		data    = &cliguid.data1;
3e9813
3e9813
		data[0] = ntapi->tt_buffer_crc32(
3e9813
			(uint32_t)(uintptr_t)&cliguid,
3e9813
			&pcnt,sizeof(pcnt));
3e9813
3e9813
		data[1] = ntapi->tt_buffer_crc32(
3e9813
			(uint32_t)(uintptr_t)rtdata,
3e9813
			rtdata,sizeof(*rtdata));
3e9813
3e9813
		data[2] = ntapi->tt_buffer_crc32(
3e9813
			data[1],dctx,sizeof(*dctx));
3e9813
3e9813
		data[3] = ntapi->tt_buffer_crc32(
3e9813
			data[2],dctx->driver_ctx,
3e9813
			sizeof(*dctx->driver_ctx));
3e9813
	}
3e9813
5e5175
	/* once */
5e5175
	switch (at_locked_cas_32(&toks_daemon_once,0,1)) {
5e5175
		case 0:
618937
			if ((status = toks_daemon_init_impl(dctx,svcguid,rtdata->hsession))) {
5e5175
				at_locked_add_32(&toks_daemon_once,2);
5e5175
				return status;
5e5175
			}
5e5175
5e5175
			at_locked_inc_32(&toks_daemon_once);
5e5175
			return 0;
5e5175
5e5175
		case 1:
5e5175
			timeout.quad = -10;
5e5175
5e5175
			for (; (at_locked_cas_32(&toks_daemon_once,0,1) == 1); )
5e5175
				ntapi->zw_delay_execution(
5e5175
					NT_SYNC_ALERTABLE,
5e5175
					&timeout);
5e5175
5e5175
			return (toks_daemon_once == 2)
5e5175
				? 0 : -1;
5e5175
5e5175
		case 2:
5e5175
			return 0;
5e5175
5e5175
		case 3:
5e5175
		default:
5e5175
			return -1;
5e5175
	}
5e5175
}