/*********************************************************/
/* toksvc: a framework-native token broker service */
/* Copyright (C) 2020 Z. Gilboa */
/* Released under GPLv2 and GPLv3; see COPYING.TOKSVC. */
/*********************************************************/
#include <psxtypes/psxtypes.h>
#include <ntapi/ntapi.h>
#include <toksvc/toksvc.h>
#include "toksvc_daemon_impl.h"
#include "toksvc_driver_impl.h"
static int32_t toks_daemon_client_wait(void * rapunzel)
{
struct toks_client_ctx * client;
client = (struct toks_client_ctx *)rapunzel;
ntapi->zw_set_event(client->hswap,0);
ntapi->zw_close(client->hswap);
ntapi->zw_wait_for_single_object(
client->hprocess,
NT_SYNC_NON_ALERTABLE,
0);
ntapi->zw_close(client->hprocess);
ntapi->zw_close(client->hport);
return ntapi->zw_terminate_thread(
NT_CURRENT_THREAD_HANDLE,
NT_STATUS_SUCCESS);
}
static int32_t toks_daemon_client_instance(struct toks_client_ctx * client)
{
int32_t status;
nt_thread_params params;
if ((status = ntapi->tt_create_private_event(
&client->hswap,
NT_NOTIFICATION_EVENT,
NT_EVENT_NOT_SIGNALED)))
return status;
ntapi->tt_aligned_block_memset(
¶ms,0,sizeof(params));
params.hprocess = NT_CURRENT_PROCESS_HANDLE;
params.start = toks_daemon_client_wait;
params.ext_ctx = client;
params.ext_ctx_size = sizeof(*client);
params.stack_size_commit = 4 * 1024;
params.stack_size_reserve = 4 * 1024;
params.creation_flags = NT_CREATE_LOCAL_THREAD;
if ((status = ntapi->tt_create_thread(¶ms)))
return status;
if ((status = ntapi->zw_wait_for_single_object(
client->hswap,
NT_SYNC_NON_ALERTABLE,
0)))
return status;
return ntapi->zw_close(params.hthread);
}
int32_t __stdcall toks_daemon_connect(struct toks_daemon_ctx * dctx)
{
int32_t status;
nt_tty_port_msg * msg;
struct toks_client_ctx client;
nt_oa oa;
msg = &dctx->reply;
msg->ttyinfo.exarg = 0;
client.hport = 0;
client.hprocess = 0;
client.hswap = 0;
client.cid.process_id = msg->header.client_id.process_id;
client.cid.thread_id = 0;
oa.len = sizeof(oa);
oa.root_dir = 0;
oa.obj_name = 0;
oa.obj_attr = 0;
oa.sec_desc = 0;
oa.sec_qos = 0;
status = ntapi->zw_open_process(
&client.hprocess,
NT_PROCESS_SYNCHRONIZE | NT_PROCESS_QUERY_INFORMATION,
&oa,&client.cid);
status = ntapi->zw_accept_connect_port(
&client.hport,
client.cid.process_id,
&msg->header,
NT_LPC_ACCEPT_CONNECTION,0,0);
if (status) {
ntapi->zw_close(client.hprocess);
return status;
}
ntapi->zw_complete_connect_port(client.hport);
return toks_daemon_client_instance(&client);
}