|
|
c78a06 |
/*********************************************************/
|
|
|
c78a06 |
/* toksvc: a framework-native token broker service */
|
|
|
c78a06 |
/* Copyright (C) 2020 Z. Gilboa */
|
|
|
c78a06 |
/* Released under GPLv2 and GPLv3; see COPYING.TOKSVC. */
|
|
|
c78a06 |
/*********************************************************/
|
|
|
c78a06 |
|
|
|
c78a06 |
#include <psxtypes/psxtypes.h>
|
|
|
c78a06 |
#include <ntapi/ntapi.h>
|
|
|
c78a06 |
|
|
|
c78a06 |
#include <toksvc/toksvc.h>
|
|
|
c78a06 |
#include "toksvc_daemon_impl.h"
|
|
|
c78a06 |
#include "toksvc_driver_impl.h"
|
|
|
c78a06 |
|
|
|
c78a06 |
static void toks_daemon_token_reset(struct toks_token * token)
|
|
|
c78a06 |
{
|
|
|
c78a06 |
token->self = 0;
|
|
|
c78a06 |
token->keys.key[0] = 0;
|
|
|
c78a06 |
token->keys.key[1] = 0;
|
|
|
c78a06 |
token->keys.key[2] = 0;
|
|
|
c78a06 |
token->keys.key[3] = 0;
|
|
|
c78a06 |
token->keys.key[4] = 0;
|
|
|
c78a06 |
token->keys.key[5] = 0;
|
|
|
c78a06 |
}
|
|
|
c78a06 |
|
|
|
d73408 |
static int32_t toks_daemon_unqueue(struct toks_daemon_ctx * dctx)
|
|
|
d73408 |
{
|
|
|
681a45 |
int status;
|
|
|
d73408 |
int nwaiters;
|
|
|
d73408 |
struct toks_waiter * waiter;
|
|
|
d73408 |
nt_tty_port_msg * msg;
|
|
|
d73408 |
nt_tty_port_msg cmsg;
|
|
|
719840 |
void * hcaller;
|
|
|
d73408 |
|
|
|
d73408 |
msg = &dctx->reply;
|
|
|
d73408 |
nwaiters = toks_get_driver_nwaiters(dctx->driver_ctx);
|
|
|
d73408 |
|
|
|
eb8750 |
if ((nwaiters == 0) || (dctx->ftokens == 0))
|
|
|
d73408 |
return NT_STATUS_SUCCESS;
|
|
|
d73408 |
|
|
|
681a45 |
|
|
|
681a45 |
|
|
|
681a45 |
waiter = dctx->waiter_first;
|
|
|
681a45 |
|
|
|
681a45 |
toks_set_driver_nwaiters(
|
|
|
681a45 |
dctx->driver_ctx,
|
|
|
681a45 |
--nwaiters);
|
|
|
681a45 |
|
|
|
681a45 |
dctx->waiter_first++;
|
|
|
681a45 |
|
|
|
681a45 |
if (dctx->waiter_first == dctx->waiter_cap)
|
|
|
681a45 |
dctx->waiter_first = dctx->waiter_base;
|
|
|
681a45 |
|
|
|
681a45 |
|
|
|
d73408 |
|
|
|
3034d1 |
if (!waiter->msg.header.msg_id)
|
|
|
3034d1 |
return NT_STATUS_CANCELLED;
|
|
|
3034d1 |
|
|
|
719840 |
|
|
|
719840 |
if ((hcaller = waiter->client.hcaller)) {
|
|
|
719840 |
status = ntapi->zw_wait_for_single_object(
|
|
|
719840 |
hcaller,
|
|
|
719840 |
NT_SYNC_NON_ALERTABLE,
|
|
|
719840 |
&(nt_timeout){.quad=0});
|
|
|
719840 |
|
|
|
719840 |
ntapi->zw_close(hcaller);
|
|
|
719840 |
|
|
|
719840 |
switch (status) {
|
|
|
719840 |
case NT_STATUS_TIMEOUT:
|
|
|
719840 |
break;
|
|
|
719840 |
|
|
|
719840 |
default:
|
|
|
719840 |
waiter->msg.header.msg_id = 0;
|
|
|
719840 |
return NT_STATUS_REQUEST_ABORTED;
|
|
|
719840 |
}
|
|
|
719840 |
}
|
|
|
719840 |
|
|
|
719840 |
|
|
|
d73408 |
ntapi->tt_generic_memcpy(
|
|
|
d73408 |
&cmsg,msg,
|
|
|
d73408 |
sizeof(*msg));
|
|
|
d73408 |
|
|
|
d73408 |
ntapi->tt_generic_memcpy(
|
|
|
d73408 |
msg,&waiter->msg,
|
|
|
d73408 |
sizeof(*msg));
|
|
|
d73408 |
|
|
|
658181 |
msg->ttyinfo.exarg = waiter->client.hprocess;
|
|
|
658181 |
msg->ttyinfo.status = toks_daemon_acquire(dctx);
|
|
|
658181 |
status = msg->ttyinfo.status;
|
|
|
d73408 |
|
|
|
658181 |
ntapi->zw_set_event(waiter->client.hevent,0);
|
|
|
658181 |
ntapi->zw_close(waiter->client.hevent);
|
|
|
d73408 |
|
|
|
d73408 |
ntapi->tt_generic_memcpy(
|
|
|
d73408 |
msg,&cmsg,
|
|
|
d73408 |
sizeof(*msg));
|
|
|
d73408 |
|
|
|
681a45 |
return status;
|
|
|
d73408 |
}
|
|
|
d73408 |
|
|
|
8f6a66 |
static int toks_daemon_unqueue_ioctl(struct toks_daemon_ctx * dctx)
|
|
|
8f6a66 |
{
|
|
|
8f6a66 |
int ntokens = toks_get_driver_ntokens(dctx->driver_ctx);
|
|
|
8f6a66 |
|
|
|
8f6a66 |
dctx->opcode = TOKS_DAEMON_RELEASE;
|
|
|
8f6a66 |
|
|
|
8f6a66 |
while (dctx->utokens < ntokens) {
|
|
|
bb0371 |
if (toks_get_driver_nwaiters(dctx->driver_ctx) == 0) {
|
|
|
bb0371 |
dctx->opcode = TOKS_DAEMON_IOCTL;
|
|
|
8f6a66 |
return NT_STATUS_SUCCESS;
|
|
|
bb0371 |
}
|
|
|
8f6a66 |
|
|
|
8f6a66 |
toks_daemon_unqueue(dctx);
|
|
|
8f6a66 |
}
|
|
|
8f6a66 |
|
|
|
8f6a66 |
dctx->opcode = TOKS_DAEMON_IOCTL;
|
|
|
8f6a66 |
|
|
|
8f6a66 |
return NT_STATUS_SUCCESS;
|
|
|
8f6a66 |
}
|
|
|
8f6a66 |
|
|
|
c78a06 |
int32_t __stdcall toks_daemon_release(struct toks_daemon_ctx * dctx)
|
|
|
c78a06 |
{
|
|
|
c78a06 |
nt_tty_port_msg * msg;
|
|
|
c78a06 |
struct toks_token * token;
|
|
|
c78a06 |
struct toks_token * toptr;
|
|
|
c78a06 |
struct toks_token * tocap;
|
|
|
c78a06 |
uint32_t * keys;
|
|
|
c78a06 |
|
|
|
8f6a66 |
if (dctx->opcode == TOKS_DAEMON_IOCTL)
|
|
|
8f6a66 |
return toks_daemon_unqueue_ioctl(dctx);
|
|
|
8f6a66 |
|
|
|
c78a06 |
msg = &dctx->reply;
|
|
|
8b933d |
keys = msg->syncinfo.ipckeys;
|
|
|
c78a06 |
|
|
|
c78a06 |
toptr = toks_get_driver_tokens(dctx->driver_ctx);
|
|
|
8f6a66 |
tocap = &toptr[toks_get_driver_atokens(dctx->driver_ctx)];
|
|
|
c78a06 |
|
|
|
c78a06 |
for (token=0; !token && (toptr
|
|
|
c78a06 |
if ((toptr->self)
|
|
|
c78a06 |
&& (toptr->keys.key[0] == keys[0])
|
|
|
c78a06 |
&& (toptr->keys.key[1] == keys[1])
|
|
|
c78a06 |
&& (toptr->keys.key[2] == keys[2])
|
|
|
c78a06 |
&& (toptr->keys.key[3] == keys[3])
|
|
|
c78a06 |
&& (toptr->keys.key[4] == keys[4])
|
|
|
c78a06 |
&& (toptr->keys.key[5] == keys[5]))
|
|
|
c78a06 |
token = toptr;
|
|
|
c78a06 |
|
|
|
c78a06 |
if (!token)
|
|
|
c78a06 |
return NT_STATUS_INVALID_PARAMETER;
|
|
|
c78a06 |
|
|
|
971724 |
if (--dctx->utokens < toks_get_driver_ntokens(dctx->driver_ctx))
|
|
|
971724 |
dctx->ftokens++;
|
|
|
8f6a66 |
|
|
|
c78a06 |
toks_daemon_token_reset(token);
|
|
|
c78a06 |
|
|
|
c78a06 |
ntapi->zw_alert_thread(token->client.hinstance);
|
|
|
c78a06 |
ntapi->zw_close(token->client.hinstance);
|
|
|
c78a06 |
|
|
|
d73408 |
do {
|
|
|
d73408 |
(void)0;
|
|
|
d73408 |
} while (toks_daemon_unqueue(dctx));
|
|
|
d73408 |
|
|
|
c78a06 |
return NT_STATUS_SUCCESS;
|
|
|
c78a06 |
}
|