|
|
2420c2 |
/*********************************************************/
|
|
|
2420c2 |
/* toksvc: a framework-native token broker service */
|
|
|
2420c2 |
/* Copyright (C) 2020 Z. Gilboa */
|
|
|
2420c2 |
/* Released under GPLv2 and GPLv3; see COPYING.TOKSVC. */
|
|
|
2420c2 |
/*********************************************************/
|
|
|
2420c2 |
|
|
|
2420c2 |
#include <ntapi/ntapi.h>
|
|
|
2420c2 |
#include <ntapi/nt_atomic.h>
|
|
|
236509 |
#include <ntapi/nt_fsctl.h>
|
|
|
2420c2 |
|
|
|
2420c2 |
#include <stdint.h>
|
|
|
2420c2 |
|
|
|
2420c2 |
#include <toksvc/toksvc.h>
|
|
|
2420c2 |
#include "toksvc_init_impl.h"
|
|
|
2420c2 |
#include "toksvc_nolibc_impl.h"
|
|
|
2420c2 |
|
|
|
2420c2 |
#define ARGV_DRIVER
|
|
|
2420c2 |
|
|
|
2420c2 |
#include "toksvc_version.h"
|
|
|
2420c2 |
#include "toksvc_daemon_impl.h"
|
|
|
2420c2 |
#include "toksvc_dprintf_impl.h"
|
|
|
2420c2 |
#include "toksvc_driver_impl.h"
|
|
|
2420c2 |
#include "argv/argv.h"
|
|
|
2420c2 |
|
|
|
3fc30f |
#undef strlen
|
|
|
3fc30f |
|
|
|
2420c2 |
/* pty integration */
|
|
|
2420c2 |
#include <psxtypes/section/freestd.h>
|
|
|
2420c2 |
|
|
|
2420c2 |
__attr_section_decl__(".freestd")
|
|
|
2420c2 |
static const nt_tty_affiliation tty_affiliation
|
|
|
2420c2 |
__attr_section__(".freestd")
|
|
|
2420c2 |
= NT_TTY_AFFILIATION_DEFAULT;
|
|
|
2420c2 |
|
|
|
2420c2 |
/* ntapi accessor table */
|
|
|
2420c2 |
const ntapi_vtbl * toks_ntapi;
|
|
|
2420c2 |
|
|
|
2420c2 |
/* daemon */
|
|
|
2420c2 |
static struct toks_daemon_ctx toks_daemon_ctx;
|
|
|
618937 |
static const nt_guid toks_daemon_default_guid = TOKS_PORT_GUID_DAEMON;
|
|
|
00069c |
static const wchar16_t toks_service_name[6] = TOKS_PORT_NAME_PREFIX;
|
|
|
2420c2 |
|
|
|
2420c2 |
/* package info */
|
|
|
2420c2 |
static const struct toks_source_version toks_src_version = {
|
|
|
2420c2 |
TOKS_TAG_VER_MAJOR,
|
|
|
2420c2 |
TOKS_TAG_VER_MINOR,
|
|
|
2420c2 |
TOKS_TAG_VER_PATCH,
|
|
|
2420c2 |
TOKSVC_GIT_VERSION
|
|
|
2420c2 |
};
|
|
|
2420c2 |
|
|
|
2420c2 |
struct toks_driver_ctx_alloc {
|
|
|
2420c2 |
struct argv_meta * meta;
|
|
|
2420c2 |
struct toks_driver_ctx_impl ctx;
|
|
|
2420c2 |
uint64_t guard;
|
|
|
2420c2 |
};
|
|
|
2420c2 |
|
|
|
2420c2 |
struct toks_split_vector {
|
|
|
2420c2 |
char ** targv;
|
|
|
2420c2 |
char ** eargv;
|
|
|
2420c2 |
};
|
|
|
2420c2 |
|
|
|
2420c2 |
static uint32_t toks_argv_flags(uint32_t flags)
|
|
|
2420c2 |
{
|
|
|
2420c2 |
uint32_t ret = ARGV_CLONE_VECTOR;
|
|
|
2420c2 |
|
|
|
2420c2 |
if (flags & TOKS_DRIVER_VERBOSITY_NONE)
|
|
|
2420c2 |
ret |= ARGV_VERBOSITY_NONE;
|
|
|
2420c2 |
|
|
|
2420c2 |
if (flags & TOKS_DRIVER_VERBOSITY_ERRORS)
|
|
|
2420c2 |
ret |= ARGV_VERBOSITY_ERRORS;
|
|
|
2420c2 |
|
|
|
2420c2 |
if (flags & TOKS_DRIVER_VERBOSITY_STATUS)
|
|
|
2420c2 |
ret |= ARGV_VERBOSITY_STATUS;
|
|
|
2420c2 |
|
|
|
2420c2 |
return ret;
|
|
|
2420c2 |
}
|
|
|
2420c2 |
|
|
|
2420c2 |
static int toks_driver_usage(
|
|
|
2420c2 |
const char * program,
|
|
|
2420c2 |
const char * arg,
|
|
|
2420c2 |
const struct argv_option ** optv,
|
|
|
2420c2 |
struct argv_meta * meta)
|
|
|
2420c2 |
{
|
|
|
2420c2 |
char header[512];
|
|
|
2420c2 |
|
|
|
2420c2 |
snprintf(header,sizeof(header),
|
|
|
2420c2 |
"Usage: %s [options] <file>...\n" "Options:\n",
|
|
|
2420c2 |
program);
|
|
|
2420c2 |
|
|
|
2420c2 |
argv_usage(STDOUT_FILENO,header,optv,arg);
|
|
|
2420c2 |
argv_free(meta);
|
|
|
2420c2 |
|
|
|
2420c2 |
return TOKS_USAGE;
|
|
|
2420c2 |
}
|
|
|
2420c2 |
|
|
|
ff65f1 |
static int64_t toks_arg_to_int64(struct argv_entry * entry)
|
|
|
ff65f1 |
{
|
|
|
ff65f1 |
int64_t ret;
|
|
|
ff65f1 |
const char * ch;
|
|
|
ff65f1 |
|
|
|
ff65f1 |
for (ret=0, ch=entry->arg; *ch && (ret>=0); ch++) {
|
|
|
ff65f1 |
if ((*ch < '0') || (*ch >'9'))
|
|
|
ff65f1 |
return (-1);
|
|
|
ff65f1 |
|
|
|
ff65f1 |
ret *= 10;
|
|
|
ff65f1 |
ret += (*ch - '0');
|
|
|
ff65f1 |
}
|
|
|
ff65f1 |
|
|
|
ff65f1 |
return ret;
|
|
|
ff65f1 |
}
|
|
|
ff65f1 |
|
|
|
ff65f1 |
static int32_t toks_arg_to_int32(struct argv_entry * entry)
|
|
|
ff65f1 |
{
|
|
|
ff65f1 |
int64_t ret = toks_arg_to_int64(entry);
|
|
|
ff65f1 |
return (ret >= 0) && (ret <= 0x7fffffff)
|
|
|
ff65f1 |
? ret : (-1);
|
|
|
ff65f1 |
}
|
|
|
ff65f1 |
|
|
|
2f270e |
static int32_t toks_query_performance_counters_failover(nt_filetime * ticks)
|
|
|
2f270e |
{
|
|
|
2f270e |
(void)ticks;
|
|
|
2f270e |
return 0;
|
|
|
2f270e |
}
|
|
|
2f270e |
|
|
|
23494d |
static int32_t toks_daemon_library_once;
|
|
|
23494d |
|
|
|
23494d |
static int32_t toks_daemon_library_init(void)
|
|
|
23494d |
{
|
|
|
23494d |
int32_t status;
|
|
|
23494d |
int argc;
|
|
|
23494d |
char ** argv;
|
|
|
23494d |
char ** envp;
|
|
|
23494d |
nt_rtdata * rtdata;
|
|
|
23494d |
nt_timeout timeout;
|
|
|
23494d |
|
|
|
23494d |
switch (at_locked_cas_32(&toks_daemon_library_once,0,1)) {
|
|
|
23494d |
case 0:
|
|
|
23494d |
status = ntapi->tt_get_argv_envp_utf8(
|
|
|
23494d |
&argc,&argv,&envp,
|
|
|
23494d |
0,0,0);
|
|
|
23494d |
|
|
|
23494d |
if (status) {
|
|
|
23494d |
at_store_32(&toks_daemon_library_once,3);
|
|
|
23494d |
return status;
|
|
|
23494d |
}
|
|
|
23494d |
|
|
|
23494d |
if ((status = ntapi->tt_get_runtime_data(&rtdata,0))) {
|
|
|
23494d |
at_store_32(&toks_daemon_library_once,3);
|
|
|
23494d |
return status;
|
|
|
23494d |
}
|
|
|
23494d |
|
|
|
15a6ec |
if (!rtdata->argv) {
|
|
|
15a6ec |
rtdata->argc = argc;
|
|
|
15a6ec |
rtdata->argv = argv;
|
|
|
15a6ec |
rtdata->envp = envp;
|
|
|
15a6ec |
}
|
|
|
15a6ec |
|
|
|
23494d |
ntapi->tt_guid_copy(
|
|
|
23494d |
&rtdata->srv_guid,
|
|
|
23494d |
&toks_daemon_default_guid);
|
|
|
23494d |
|
|
|
23494d |
at_locked_inc_32(&toks_daemon_library_once);
|
|
|
23494d |
return 0;
|
|
|
23494d |
|
|
|
23494d |
case 1:
|
|
|
23494d |
timeout.quad = -10;
|
|
|
23494d |
|
|
|
23494d |
for (; (at_locked_cas_32(&toks_daemon_library_once,0,1) == 1); )
|
|
|
23494d |
ntapi->zw_delay_execution(
|
|
|
23494d |
NT_SYNC_ALERTABLE,
|
|
|
23494d |
&timeout);
|
|
|
23494d |
|
|
|
23494d |
return (toks_daemon_library_once == 2)
|
|
|
23494d |
? 0 : -1;
|
|
|
23494d |
|
|
|
23494d |
case 2:
|
|
|
23494d |
return 0;
|
|
|
23494d |
|
|
|
23494d |
case 3:
|
|
|
23494d |
default:
|
|
|
23494d |
return -1;
|
|
|
23494d |
}
|
|
|
23494d |
|
|
|
23494d |
return NT_STATUS_INTERNAL_ERROR;
|
|
|
23494d |
}
|
|
|
23494d |
|
|
|
2420c2 |
static struct toks_driver_ctx_impl * toks_driver_ctx_alloc(
|
|
|
2420c2 |
struct argv_meta * meta,
|
|
|
2420c2 |
const struct toks_common_ctx * cctx)
|
|
|
2420c2 |
{
|
|
|
2420c2 |
struct toks_driver_ctx_alloc * ictx;
|
|
|
2420c2 |
size_t size;
|
|
|
2420c2 |
nt_runtime_data * rtdata;
|
|
|
2420c2 |
|
|
|
23494d |
switch (ntapi->tt_get_runtime_data(&rtdata,0)) {
|
|
|
23494d |
case NT_STATUS_SUCCESS:
|
|
|
23494d |
break;
|
|
|
23494d |
|
|
|
23494d |
case NT_STATUS_MORE_PROCESSING_REQUIRED:
|
|
|
23494d |
toks_daemon_library_init();
|
|
|
23494d |
|
|
|
23494d |
if (ntapi->tt_get_runtime_data(&rtdata,0))
|
|
|
23494d |
return 0;
|
|
|
23494d |
|
|
|
75adfe |
break;
|
|
|
75adfe |
|
|
|
23494d |
default:
|
|
|
23494d |
return 0;
|
|
|
23494d |
}
|
|
|
2420c2 |
|
|
|
2420c2 |
size = sizeof(struct toks_driver_ctx_alloc);
|
|
|
2420c2 |
|
|
|
2420c2 |
if (!(ictx = calloc(1,size)))
|
|
|
2420c2 |
return 0;
|
|
|
2420c2 |
|
|
|
2420c2 |
if (cctx)
|
|
|
2420c2 |
memcpy(&ictx->ctx.cctx,cctx,sizeof(*cctx));
|
|
|
2420c2 |
|
|
|
2f270e |
ictx->ctx.ticks.qpc = toks_query_performance_counters_failover;
|
|
|
2f270e |
ictx->ctx.ticks.pcfreq.quad = 0;
|
|
|
2f270e |
|
|
|
2420c2 |
ictx->meta = meta;
|
|
|
2420c2 |
ictx->ctx.rtdata = rtdata;
|
|
|
2420c2 |
return &ictx->ctx;
|
|
|
2420c2 |
}
|
|
|
2420c2 |
|
|
|
2420c2 |
static int toks_get_driver_ctx_fail(struct argv_meta * meta)
|
|
|
2420c2 |
{
|
|
|
2420c2 |
argv_free(meta);
|
|
|
2420c2 |
return -1;
|
|
|
2420c2 |
}
|
|
|
2420c2 |
|
|
|
2420c2 |
#define TOKS_SARGV_ELEMENTS 1024
|
|
|
2420c2 |
|
|
|
2420c2 |
static int toks_split_argv(
|
|
|
2420c2 |
char ** argv,
|
|
|
2420c2 |
struct toks_split_vector * sargv)
|
|
|
2420c2 |
{
|
|
|
2420c2 |
ptrdiff_t argc;
|
|
|
2420c2 |
char ** parg;
|
|
|
2420c2 |
|
|
|
2420c2 |
/* argc */
|
|
|
2420c2 |
for (parg=argv; *parg; )
|
|
|
2420c2 |
parg++;
|
|
|
2420c2 |
|
|
|
2420c2 |
if ((argc = parg - argv) >= TOKS_SARGV_ELEMENTS)
|
|
|
2420c2 |
return -1;
|
|
|
2420c2 |
|
|
|
2420c2 |
/* clone argv into targv */
|
|
|
2420c2 |
ntapi->tt_aligned_block_memset(
|
|
|
2420c2 |
(uintptr_t *)sargv->targv,
|
|
|
2420c2 |
0,TOKS_SARGV_ELEMENTS*sizeof(char *));
|
|
|
2420c2 |
|
|
|
2420c2 |
ntapi->tt_aligned_block_memcpy(
|
|
|
2420c2 |
(uintptr_t *)sargv->targv,
|
|
|
2420c2 |
(uintptr_t *)argv,
|
|
|
2420c2 |
argc*sizeof(char *));
|
|
|
2420c2 |
|
|
|
2420c2 |
/* eargv */
|
|
|
2420c2 |
for (parg=sargv->targv; *parg; parg++) {
|
|
|
2420c2 |
if (!(strcmp(*parg,"-e")) || !(strcmp(*parg,"--exec"))) {
|
|
|
2420c2 |
sargv->eargv = &argv[parg-sargv->targv];
|
|
|
2420c2 |
sargv->eargv++;
|
|
|
2420c2 |
*parg = 0;
|
|
|
2420c2 |
return 0;
|
|
|
2420c2 |
}
|
|
|
2420c2 |
}
|
|
|
2420c2 |
|
|
|
2420c2 |
return 0;
|
|
|
2420c2 |
}
|
|
|
2420c2 |
|
|
|
3fc30f |
static int32_t toks_set_tmpfs_from_uuid(struct toks_driver_ctx_impl * ctx)
|
|
|
3fc30f |
{
|
|
|
3fc30f |
int32_t status;
|
|
|
3fc30f |
void * htmproot;
|
|
|
3fc30f |
void * hsvcroot;
|
|
|
3fc30f |
nt_oa oa;
|
|
|
3fc30f |
nt_iosb iosb;
|
|
|
3fc30f |
nt_unicode_string path;
|
|
|
3fc30f |
uint32_t access;
|
|
|
3fc30f |
nt_sd_common_buffer sd;
|
|
|
3fc30f |
nt_large_integer alloc_size;
|
|
|
3fc30f |
nt_guid_str_utf16 guidstr;
|
|
|
3fc30f |
uint32_t access_owner;
|
|
|
3fc30f |
uint32_t access_group;
|
|
|
3fc30f |
uint32_t access_other;
|
|
|
3fc30f |
uint32_t access_admin;
|
|
|
3fc30f |
wchar16_t tmproot[3] = {'t','m','p'};
|
|
|
3fc30f |
wchar16_t toksvc[6] = {'t','o','k','s','v','c'};
|
|
|
3fc30f |
|
|
|
3fc30f |
/* sd */
|
|
|
3fc30f |
access_owner = NT_GENERIC_ALL|NT_SEC_SPECIFIC_RIGHTS_ALL;
|
|
|
3fc30f |
access_admin = access_owner;
|
|
|
3fc30f |
|
|
|
3fc30f |
access_group = NT_GENERIC_READ | NT_GENERIC_WRITE | NT_GENERIC_EXECUTE;
|
|
|
3fc30f |
access_group |= NT_SEC_READ_CONTROL | NT_FILE_READ_ATTRIBUTES;
|
|
|
3fc30f |
|
|
|
3fc30f |
access_other = NT_GENERIC_READ | NT_GENERIC_EXECUTE;
|
|
|
3fc30f |
access_other |= NT_SEC_READ_CONTROL | NT_FILE_READ_ATTRIBUTES;
|
|
|
3fc30f |
|
|
|
3fc30f |
ntapi->acl_init_common_descriptor(
|
|
|
3fc30f |
&sd,0,0,0,0,
|
|
|
3fc30f |
access_owner,access_group,access_other,
|
|
|
3fc30f |
access_admin,access_owner,
|
|
|
3fc30f |
0);
|
|
|
3fc30f |
|
|
|
3fc30f |
/* oa */
|
|
|
3fc30f |
oa.len = sizeof(nt_oa);
|
|
|
3fc30f |
oa.root_dir = 0;
|
|
|
3fc30f |
oa.obj_name = &pat;;
|
|
|
3fc30f |
oa.obj_attr = 0;
|
|
|
3fc30f |
oa.sec_desc = &sd.sd;
|
|
|
3fc30f |
oa.sec_qos = 0;
|
|
|
3fc30f |
|
|
|
3fc30f |
/* alloc_size (always zero) */
|
|
|
3fc30f |
alloc_size.quad = 0;
|
|
|
3fc30f |
|
|
|
3fc30f |
/* access */
|
|
|
3fc30f |
access = NT_SEC_SYNCHRONIZE | NT_SEC_READ_CONTROL | NT_FILE_READ_ATTRIBUTES;
|
|
|
3fc30f |
access |= NT_FILE_LIST_DIRECTORY | NT_FILE_ADD_FILE | NT_FILE_ADD_SUBDIRECTORY;
|
|
|
3fc30f |
access |= NT_FILE_TRAVERSE | NT_FILE_DELETE_CHILD;
|
|
|
3fc30f |
|
|
|
3fc30f |
/* /tmp or alternative */
|
|
|
3fc30f |
if (ctx->rtdata->htmpfslroot) {
|
|
|
3fc30f |
if ((status = ntapi->zw_duplicate_object(
|
|
|
3fc30f |
ctx->rtdata->hself,
|
|
|
3fc30f |
ctx->rtdata->htmpfslroot,
|
|
|
3fc30f |
ctx->rtdata->hself,
|
|
|
3fc30f |
&htmproot,
|
|
|
3fc30f |
0,0,
|
|
|
3fc30f |
NT_DUPLICATE_SAME_ATTRIBUTES|NT_DUPLICATE_SAME_ACCESS)))
|
|
|
3fc30f |
return status;
|
|
|
3fc30f |
} else {
|
|
|
3fc30f |
path.maxlen = 0;
|
|
|
3fc30f |
path.strlen = sizeof(tmproot);
|
|
|
3fc30f |
path.buffer = tmproot;
|
|
|
3fc30f |
|
|
|
3fc30f |
oa.root_dir = ctx->rtdata->hroot;
|
|
|
3fc30f |
|
|
|
3fc30f |
if ((status = ntapi->zw_create_file(
|
|
|
3fc30f |
&htmproot,
|
|
|
3fc30f |
access,&oa,&iosb,
|
|
|
3fc30f |
&alloc_size,
|
|
|
3fc30f |
NT_FILE_ATTRIBUTE_DIRECTORY,
|
|
|
3fc30f |
NT_FILE_SHARE_READ | NT_FILE_SHARE_WRITE | NT_FILE_SHARE_DELETE,
|
|
|
3fc30f |
NT_FILE_OPEN_IF,
|
|
|
3fc30f |
NT_FILE_DIRECTORY_FILE | NT_FILE_SYNCHRONOUS_IO_ALERT,
|
|
|
3fc30f |
0,0)))
|
|
|
3fc30f |
return status;
|
|
|
3fc30f |
}
|
|
|
3fc30f |
|
|
|
3fc30f |
/* service tmpfs root */
|
|
|
3fc30f |
path.maxlen = 0;
|
|
|
3fc30f |
path.strlen = sizeof(toksvc);
|
|
|
3fc30f |
path.buffer = toksvc;
|
|
|
3fc30f |
|
|
|
3fc30f |
oa.root_dir = htmproot;
|
|
|
3fc30f |
|
|
|
3fc30f |
status = ntapi->zw_create_file(
|
|
|
3fc30f |
&hsvcroot,
|
|
|
3fc30f |
access,&oa,&iosb,
|
|
|
3fc30f |
&alloc_size,
|
|
|
3fc30f |
NT_FILE_ATTRIBUTE_DIRECTORY,
|
|
|
3fc30f |
NT_FILE_SHARE_READ | NT_FILE_SHARE_WRITE | NT_FILE_SHARE_DELETE,
|
|
|
3fc30f |
NT_FILE_OPEN_IF,
|
|
|
3fc30f |
NT_FILE_DIRECTORY_FILE | NT_FILE_SYNCHRONOUS_IO_ALERT,
|
|
|
3fc30f |
0,0);
|
|
|
3fc30f |
|
|
|
3fc30f |
if (status) {
|
|
|
3fc30f |
ntapi->zw_close(htmproot);
|
|
|
3fc30f |
return status;
|
|
|
3fc30f |
}
|
|
|
3fc30f |
|
|
|
3fc30f |
/* instance-specific tmpfs root */
|
|
|
3fc30f |
ntapi->tt_guid_to_string_utf16(
|
|
|
0021e3 |
&ctx->guid,
|
|
|
3fc30f |
&guidstr);
|
|
|
3fc30f |
|
|
|
3fc30f |
path.maxlen = 0;
|
|
|
3fc30f |
path.strlen = sizeof(guidstr);
|
|
|
3fc30f |
path.buffer = &guidstr.lbrace;
|
|
|
3fc30f |
|
|
|
3fc30f |
oa.root_dir = hsvcroot;
|
|
|
3fc30f |
|
|
|
3fc30f |
status = ntapi->zw_create_file(
|
|
|
3fc30f |
&ctx->htmpfs,
|
|
|
3fc30f |
access,&oa,&iosb,
|
|
|
3fc30f |
&alloc_size,
|
|
|
3fc30f |
NT_FILE_ATTRIBUTE_DIRECTORY,
|
|
|
3fc30f |
NT_FILE_SHARE_READ | NT_FILE_SHARE_WRITE | NT_FILE_SHARE_DELETE,
|
|
|
3fc30f |
NT_FILE_OPEN_IF,
|
|
|
3fc30f |
NT_FILE_DIRECTORY_FILE | NT_FILE_SYNCHRONOUS_IO_ALERT,
|
|
|
3fc30f |
0,0);
|
|
|
3fc30f |
|
|
|
3fc30f |
ntapi->zw_close(hsvcroot);
|
|
|
3fc30f |
ntapi->zw_close(htmproot);
|
|
|
3fc30f |
|
|
|
3fc30f |
return status;
|
|
|
3fc30f |
}
|
|
|
3fc30f |
|
|
|
236509 |
static int32_t toks_set_uuid_from_root(
|
|
|
236509 |
struct toks_driver_ctx_impl * ctx,
|
|
|
236509 |
struct _nt_guid * svcguid)
|
|
|
236509 |
{
|
|
|
236509 |
int32_t status;
|
|
|
236509 |
nt_iosb iosb;
|
|
|
236509 |
nt_file_object_id_buffer objid;
|
|
|
236509 |
|
|
|
236509 |
if (!ctx->rtdata->hroot)
|
|
|
236509 |
return NT_STATUS_INVALID_PARAMETER;
|
|
|
236509 |
|
|
|
236509 |
iosb.status = NT_STATUS_PENDING;
|
|
|
236509 |
|
|
|
236509 |
status = ntapi->zw_fs_control_file(
|
|
|
236509 |
ctx->rtdata->hroot,
|
|
|
236509 |
ctx->hevent,0,0,
|
|
|
236509 |
&iosb,
|
|
|
236509 |
NT_FSCTL_CREATE_OR_GET_OBJECT_ID,
|
|
|
236509 |
0,0,&objid,sizeof(objid));
|
|
|
236509 |
|
|
|
236509 |
if (status == NT_STATUS_PENDING)
|
|
|
236509 |
ntapi->zw_wait_for_single_object(
|
|
|
236509 |
ctx->hevent,
|
|
|
236509 |
NT_SYNC_NON_ALERTABLE,
|
|
|
236509 |
0);
|
|
|
236509 |
|
|
|
236509 |
if (iosb.status)
|
|
|
236509 |
return iosb.status;
|
|
|
236509 |
|
|
|
236509 |
svcguid->data1 = (objid.obj_id[0]);
|
|
|
236509 |
svcguid->data1 |= (objid.obj_id[1] << 8);
|
|
|
236509 |
svcguid->data1 |= (objid.obj_id[2] << 16);
|
|
|
236509 |
svcguid->data1 |= (objid.obj_id[3] << 24);
|
|
|
236509 |
|
|
|
236509 |
svcguid->data2 = (objid.obj_id[4]);
|
|
|
236509 |
svcguid->data2 |= (objid.obj_id[5] << 8);
|
|
|
236509 |
|
|
|
236509 |
svcguid->data3 = (objid.obj_id[6]);
|
|
|
236509 |
svcguid->data3 |= (objid.obj_id[7] << 8);
|
|
|
236509 |
|
|
|
236509 |
svcguid->data4[0] = (objid.obj_id[8]);
|
|
|
236509 |
svcguid->data4[1] = (objid.obj_id[9]);
|
|
|
236509 |
svcguid->data4[2] = (objid.obj_id[10]);
|
|
|
236509 |
svcguid->data4[3] = (objid.obj_id[11]);
|
|
|
236509 |
svcguid->data4[4] = (objid.obj_id[12]);
|
|
|
236509 |
svcguid->data4[5] = (objid.obj_id[13]);
|
|
|
236509 |
svcguid->data4[6] = (objid.obj_id[14]);
|
|
|
236509 |
svcguid->data4[7] = (objid.obj_id[15]);
|
|
|
236509 |
|
|
|
236509 |
return NT_STATUS_SUCCESS;
|
|
|
236509 |
}
|
|
|
236509 |
|
|
|
2420c2 |
int toks_get_driver_ctx(
|
|
|
2420c2 |
char ** argv,
|
|
|
2420c2 |
char ** envp,
|
|
|
2420c2 |
uint32_t flags,
|
|
|
2420c2 |
struct toks_driver_ctx ** pctx)
|
|
|
2420c2 |
{
|
|
|
2c9219 |
int32_t status;
|
|
|
2420c2 |
struct toks_driver_ctx_impl * ctx;
|
|
|
2420c2 |
struct toks_common_ctx cctx;
|
|
|
2420c2 |
struct toks_split_vector sargv;
|
|
|
2420c2 |
const struct argv_option * optv[TOKS_OPTV_ELEMENTS];
|
|
|
2420c2 |
struct argv_meta * meta;
|
|
|
2420c2 |
struct argv_entry * entry;
|
|
|
618937 |
struct argv_entry * uuid;
|
|
|
e3e583 |
struct argv_entry * pid;
|
|
|
201fd7 |
struct argv_entry * syspid;
|
|
|
35e873 |
struct argv_entry * cfpid;
|
|
|
35e873 |
struct argv_entry * cspid;
|
|
|
b27e56 |
struct argv_entry * msecs;
|
|
|
867b30 |
struct toks_token_string key;
|
|
|
867b30 |
size_t keylen;
|
|
|
bd4f0c |
uintptr_t opdata;
|
|
|
618937 |
nt_guid svcguid;
|
|
|
2420c2 |
const char * program;
|
|
|
79252f |
const char * refstr;
|
|
|
c847e3 |
int ntokens;
|
|
|
8f6a66 |
int atokens;
|
|
|
ee5c9c |
int loglevel;
|
|
|
e3e583 |
int32_t tokpid;
|
|
|
201fd7 |
int32_t tsyspid;
|
|
|
35e873 |
int32_t ctrlpid;
|
|
|
35e873 |
int32_t csyspid;
|
|
|
b27e56 |
int64_t timeout;
|
|
|
ed52e5 |
void * hlog;
|
|
|
2f270e |
void * hkernel32;
|
|
|
2420c2 |
char * targv[TOKS_SARGV_ELEMENTS];
|
|
|
2420c2 |
|
|
|
2420c2 |
(void)envp;
|
|
|
2420c2 |
|
|
|
2420c2 |
if (toks_init())
|
|
|
2420c2 |
return -1;
|
|
|
2420c2 |
|
|
|
2420c2 |
argv_optv_init(toks_default_options,optv);
|
|
|
2420c2 |
|
|
|
2420c2 |
sargv.targv = targv;
|
|
|
2420c2 |
sargv.eargv = 0;
|
|
|
2420c2 |
|
|
|
2420c2 |
if (toks_split_argv(argv,&sargv))
|
|
|
2420c2 |
return -1;
|
|
|
2420c2 |
|
|
|
2420c2 |
if (!(meta = argv_get(
|
|
|
2420c2 |
sargv.targv,optv,
|
|
|
2420c2 |
toks_argv_flags(flags),
|
|
|
2420c2 |
STDERR_FILENO)))
|
|
|
2420c2 |
return -1;
|
|
|
2420c2 |
|
|
|
618937 |
if (!(flags & TOKS_DRIVER_MODE_CLIENT))
|
|
|
618937 |
flags |= TOKS_DRIVER_MODE_SERVER;
|
|
|
618937 |
|
|
|
ed52e5 |
hlog = 0;
|
|
|
6832b9 |
uuid = 0;
|
|
|
6832b9 |
tokpid = 0;
|
|
|
6832b9 |
tsyspid = 0;
|
|
|
35e873 |
ctrlpid = 0;
|
|
|
35e873 |
csyspid = 0;
|
|
|
6832b9 |
keylen = 0;
|
|
|
35c599 |
refstr = 0;
|
|
|
6832b9 |
ntokens = 0;
|
|
|
ee5c9c |
loglevel = 0;
|
|
|
6832b9 |
timeout = (-1);
|
|
|
6832b9 |
program = argv_program_name(argv[0]);
|
|
|
618937 |
|
|
|
2420c2 |
memset(&cctx,0,sizeof(cctx));
|
|
|
2420c2 |
cctx.drvflags = flags;
|
|
|
2420c2 |
cctx.eargv = sargv.eargv;
|
|
|
2420c2 |
|
|
|
2420c2 |
if (!argv[1] && (flags & TOKS_DRIVER_VERBOSITY_USAGE))
|
|
|
2420c2 |
return toks_driver_usage(program,0,optv,meta);
|
|
|
2420c2 |
|
|
|
2420c2 |
for (entry=meta->entries; entry->fopt || entry->arg; entry++) {
|
|
|
2420c2 |
if (entry->fopt) {
|
|
|
2420c2 |
switch (entry->tag) {
|
|
|
2420c2 |
case TAG_HELP:
|
|
|
2420c2 |
if (flags & TOKS_DRIVER_VERBOSITY_USAGE)
|
|
|
2420c2 |
return toks_driver_usage(program,entry->arg,optv,meta);
|
|
|
2420c2 |
|
|
|
2420c2 |
case TAG_VERSION:
|
|
|
2420c2 |
cctx.drvflags |= TOKS_DRIVER_VERSION;
|
|
|
2420c2 |
break;
|
|
|
2420c2 |
|
|
|
2420c2 |
case TAG_DAEMON:
|
|
|
2420c2 |
if (!strcmp("always",entry->arg))
|
|
|
2420c2 |
cctx.drvflags |= TOKS_DRIVER_DAEMON_ALWAYS;
|
|
|
2420c2 |
|
|
|
2420c2 |
else if (!strcmp("never",entry->arg))
|
|
|
2420c2 |
cctx.drvflags |= TOKS_DRIVER_DAEMON_NEVER;
|
|
|
2420c2 |
|
|
|
2420c2 |
break;
|
|
|
2420c2 |
|
|
|
2420c2 |
case TAG_SYSROOT:
|
|
|
2420c2 |
cctx.sysroot = entry->arg;
|
|
|
2420c2 |
break;
|
|
|
618937 |
|
|
|
618937 |
case TAG_UUID:
|
|
|
618937 |
uuid = entry;
|
|
|
618937 |
break;
|
|
|
486fcd |
|
|
|
236509 |
case TAG_ROOTUUID:
|
|
|
236509 |
cctx.drvflags |= TOKS_DRIVER_ROOT_UUID;
|
|
|
236509 |
break;
|
|
|
236509 |
|
|
|
79252f |
case TAG_REFSTR:
|
|
|
79252f |
refstr = entry->arg;
|
|
|
79252f |
break;
|
|
|
79252f |
|
|
|
e3e583 |
case TAG_PID:
|
|
|
ff65f1 |
tokpid = toks_arg_to_int32((pid=entry));
|
|
|
e3e583 |
break;
|
|
|
e3e583 |
|
|
|
201fd7 |
case TAG_SYSPID:
|
|
|
ff65f1 |
tsyspid = toks_arg_to_int32((syspid=entry));
|
|
|
201fd7 |
break;
|
|
|
201fd7 |
|
|
|
35e873 |
case TAG_CTRLPID:
|
|
|
35e873 |
ctrlpid = toks_arg_to_int32((cfpid=entry));
|
|
|
35e873 |
break;
|
|
|
35e873 |
|
|
|
35e873 |
case TAG_CSYSPID:
|
|
|
35e873 |
csyspid = toks_arg_to_int32((cspid=entry));
|
|
|
35e873 |
break;
|
|
|
35e873 |
|
|
|
ee5c9c |
case TAG_LOGLEVEL:
|
|
|
ee5c9c |
loglevel = toks_arg_to_int32(entry);
|
|
|
ee5c9c |
loglevel = (loglevel > 9) ? (-1) : loglevel;
|
|
|
ee5c9c |
cctx.loglevel = loglevel;
|
|
|
ee5c9c |
break;
|
|
|
ee5c9c |
|
|
|
b27e56 |
case TAG_TIMEOUT:
|
|
|
ff65f1 |
timeout = toks_arg_to_int64((msecs=entry));
|
|
|
ff65f1 |
timeout = (timeout < 0) ? (-2) : timeout;
|
|
|
b27e56 |
break;
|
|
|
b27e56 |
|
|
|
c847e3 |
case TAG_TOKENS:
|
|
|
ff65f1 |
ntokens = toks_arg_to_int32(entry);
|
|
|
ff65f1 |
ntokens = (ntokens > 9999) ? (-1) : ntokens;
|
|
|
c847e3 |
break;
|
|
|
c847e3 |
|
|
|
486fcd |
case TAG_CONNECT:
|
|
|
486fcd |
cctx.drvflags &= ~(uint64_t)TOKS_DRIVER_MODE_SERVER;
|
|
|
486fcd |
cctx.drvflags |= TOKS_DRIVER_MODE_CLIENT;
|
|
|
486fcd |
break;
|
|
|
02451d |
|
|
|
520f51 |
case TAG_ABORT:
|
|
|
520f51 |
cctx.drvflags &= ~(uint64_t)TOKS_DRIVER_MODE_SERVER;
|
|
|
520f51 |
cctx.drvflags |= TOKS_DRIVER_MODE_CLIENT;
|
|
|
520f51 |
cctx.drvflags |= TOKS_DRIVER_ACTION_ABORT;
|
|
|
520f51 |
break;
|
|
|
520f51 |
|
|
|
02451d |
case TAG_ACQUIRE:
|
|
|
02451d |
cctx.drvflags &= ~(uint64_t)TOKS_DRIVER_MODE_SERVER;
|
|
|
02451d |
cctx.drvflags |= TOKS_DRIVER_MODE_CLIENT;
|
|
|
02451d |
cctx.drvflags |= TOKS_DRIVER_ACTION_ACQUIRE;
|
|
|
02451d |
break;
|
|
|
867b30 |
|
|
|
867b30 |
case TAG_RELEASE:
|
|
|
867b30 |
cctx.drvflags &= ~(uint64_t)TOKS_DRIVER_MODE_SERVER;
|
|
|
867b30 |
cctx.drvflags |= TOKS_DRIVER_MODE_CLIENT;
|
|
|
867b30 |
cctx.drvflags |= TOKS_DRIVER_ACTION_RELEASE;
|
|
|
867b30 |
|
|
|
867b30 |
keylen = toks_strlen(entry->arg);
|
|
|
867b30 |
|
|
|
867b30 |
ntapi->tt_generic_memset(
|
|
|
867b30 |
&key,0,sizeof(key));
|
|
|
867b30 |
|
|
|
867b30 |
if (keylen < sizeof(key.token))
|
|
|
867b30 |
ntapi->tt_generic_memcpy(
|
|
|
867b30 |
&key.token,entry->arg,
|
|
|
867b30 |
keylen);
|
|
|
867b30 |
break;
|
|
|
ed52e5 |
|
|
|
ed52e5 |
case TAG_LOGFILE:
|
|
|
ed52e5 |
cctx.logfile = entry->arg;
|
|
|
ed52e5 |
break;
|
|
|
bd4f0c |
|
|
|
bd4f0c |
case TAG_NTOKENSGET:
|
|
|
bd4f0c |
cctx.drvflags &= ~(uint64_t)TOKS_DRIVER_MODE_SERVER;
|
|
|
bd4f0c |
cctx.drvflags |= TOKS_DRIVER_MODE_CLIENT;
|
|
|
bd4f0c |
cctx.drvflags |= TOKS_DRIVER_ACTION_NTOKENS_GET;
|
|
|
bd4f0c |
break;
|
|
|
0f44d8 |
|
|
|
0f44d8 |
case TAG_NTOKENSSET:
|
|
|
0f44d8 |
cctx.drvflags &= ~(uint64_t)TOKS_DRIVER_MODE_SERVER;
|
|
|
0f44d8 |
cctx.drvflags |= TOKS_DRIVER_MODE_CLIENT;
|
|
|
0f44d8 |
cctx.drvflags |= TOKS_DRIVER_ACTION_NTOKENS_SET;
|
|
|
0f44d8 |
ntokens = toks_arg_to_int32(entry);
|
|
|
0f44d8 |
break;
|
|
|
0b7161 |
|
|
|
0b7161 |
case TAG_GETSVCINFO:
|
|
|
0b7161 |
cctx.drvflags &= ~(uint64_t)TOKS_DRIVER_MODE_SERVER;
|
|
|
0b7161 |
cctx.drvflags |= TOKS_DRIVER_MODE_CLIENT;
|
|
|
0b7161 |
cctx.drvflags |= TOKS_DRIVER_ACTION_SVCINFO_GET;
|
|
|
0b7161 |
break;
|
|
|
0b7161 |
|
|
|
0b7161 |
case TAG_LOGSVCINFO:
|
|
|
0b7161 |
cctx.drvflags &= ~(uint64_t)TOKS_DRIVER_MODE_SERVER;
|
|
|
0b7161 |
cctx.drvflags |= TOKS_DRIVER_MODE_CLIENT;
|
|
|
0b7161 |
cctx.drvflags |= TOKS_DRIVER_ACTION_SVCINFO_LOG;
|
|
|
0b7161 |
break;
|
|
|
7f4116 |
|
|
|
eb3ecd |
case TAG_GETTOKINFO:
|
|
|
eb3ecd |
cctx.drvflags &= ~(uint64_t)TOKS_DRIVER_MODE_SERVER;
|
|
|
eb3ecd |
cctx.drvflags |= TOKS_DRIVER_MODE_CLIENT;
|
|
|
eb3ecd |
cctx.drvflags |= TOKS_DRIVER_ACTION_TOKINFO_GET;
|
|
|
eb3ecd |
break;
|
|
|
eb3ecd |
|
|
|
5e0b43 |
case TAG_LOGTOKINFO:
|
|
|
5e0b43 |
cctx.drvflags &= ~(uint64_t)TOKS_DRIVER_MODE_SERVER;
|
|
|
5e0b43 |
cctx.drvflags |= TOKS_DRIVER_MODE_CLIENT;
|
|
|
5e0b43 |
cctx.drvflags |= TOKS_DRIVER_ACTION_TOKINFO_LOG;
|
|
|
5e0b43 |
break;
|
|
|
5e0b43 |
|
|
|
7f4116 |
case TAG_LOGLEVELGET:
|
|
|
7f4116 |
cctx.drvflags &= ~(uint64_t)TOKS_DRIVER_MODE_SERVER;
|
|
|
7f4116 |
cctx.drvflags |= TOKS_DRIVER_MODE_CLIENT;
|
|
|
7f4116 |
cctx.drvflags |= TOKS_DRIVER_ACTION_LOGLEVEL_GET;
|
|
|
7f4116 |
break;
|
|
|
7f4116 |
|
|
|
7f4116 |
case TAG_LOGLEVELSET:
|
|
|
7f4116 |
cctx.drvflags &= ~(uint64_t)TOKS_DRIVER_MODE_SERVER;
|
|
|
7f4116 |
cctx.drvflags |= TOKS_DRIVER_MODE_CLIENT;
|
|
|
7f4116 |
cctx.drvflags |= TOKS_DRIVER_ACTION_LOGLEVEL_SET;
|
|
|
7f4116 |
|
|
|
7f4116 |
loglevel = toks_arg_to_int32(entry);
|
|
|
7f4116 |
loglevel = (loglevel > 9) ? (-1) : loglevel;
|
|
|
7f4116 |
cctx.loglevel = loglevel;
|
|
|
7f4116 |
|
|
|
7f4116 |
break;
|
|
|
2420c2 |
}
|
|
|
2420c2 |
} else
|
|
|
2420c2 |
/* strict */
|
|
|
2420c2 |
return toks_driver_usage(program,0,optv,meta);
|
|
|
2420c2 |
}
|
|
|
2420c2 |
|
|
|
e3e583 |
if ((cctx.drvflags & TOKS_DRIVER_MODE_CLIENT) && (tokpid < 0)) {
|
|
|
e3e583 |
if (flags & TOKS_DRIVER_VERBOSITY_ERRORS)
|
|
|
e3e583 |
toks_dprintf(STDERR_FILENO,
|
|
|
201fd7 |
"%s: error: %s is not a valid framework process id.",
|
|
|
e3e583 |
program,pid->arg);
|
|
|
e3e583 |
return toks_get_driver_ctx_fail(meta);
|
|
|
e3e583 |
}
|
|
|
e3e583 |
|
|
|
201fd7 |
if ((cctx.drvflags & TOKS_DRIVER_MODE_CLIENT) && (tsyspid < 0)) {
|
|
|
201fd7 |
if (flags & TOKS_DRIVER_VERBOSITY_ERRORS)
|
|
|
201fd7 |
toks_dprintf(STDERR_FILENO,
|
|
|
201fd7 |
"%s: error: %s is not a valid system process id.",
|
|
|
201fd7 |
program,syspid->arg);
|
|
|
201fd7 |
return toks_get_driver_ctx_fail(meta);
|
|
|
201fd7 |
}
|
|
|
201fd7 |
|
|
|
35e873 |
if ((cctx.drvflags & TOKS_DRIVER_MODE_SERVER) && (ctrlpid < 0)) {
|
|
|
35e873 |
if (flags & TOKS_DRIVER_VERBOSITY_ERRORS)
|
|
|
35e873 |
toks_dprintf(STDERR_FILENO,
|
|
|
35e873 |
"%s: error: %s is not a valid controlling "
|
|
|
35e873 |
"framework process id.",
|
|
|
35e873 |
program,cfpid->arg);
|
|
|
35e873 |
return toks_get_driver_ctx_fail(meta);
|
|
|
35e873 |
}
|
|
|
35e873 |
|
|
|
35e873 |
if ((cctx.drvflags & TOKS_DRIVER_MODE_SERVER) && (csyspid < 0)) {
|
|
|
35e873 |
if (flags & TOKS_DRIVER_VERBOSITY_ERRORS)
|
|
|
35e873 |
toks_dprintf(STDERR_FILENO,
|
|
|
35e873 |
"%s: error: %s is not a valid controlling "
|
|
|
35e873 |
"system process id.",
|
|
|
35e873 |
program,cspid->arg);
|
|
|
35e873 |
return toks_get_driver_ctx_fail(meta);
|
|
|
35e873 |
}
|
|
|
35e873 |
|
|
|
b27e56 |
if ((cctx.drvflags & TOKS_DRIVER_MODE_CLIENT) && (timeout < (-1))) {
|
|
|
b27e56 |
if (flags & TOKS_DRIVER_VERBOSITY_ERRORS)
|
|
|
b27e56 |
toks_dprintf(STDERR_FILENO,
|
|
|
b27e56 |
"%s: error: %s is not a valid timeout in milliseconds.",
|
|
|
b27e56 |
program,msecs->arg);
|
|
|
b27e56 |
return toks_get_driver_ctx_fail(meta);
|
|
|
b27e56 |
}
|
|
|
b27e56 |
|
|
|
d5c778 |
if ((ntokens == 0) && !(cctx.drvflags & TOKS_DRIVER_VERSION)) {
|
|
|
d5c778 |
ntokens = (-1);
|
|
|
d5c778 |
}
|
|
|
d5c778 |
|
|
|
d5c778 |
if (ntokens == 0) {
|
|
|
d5c778 |
cctx.drvflags &= ~(uint64_t)TOKS_DRIVER_MODE_SERVER;
|
|
|
d5c778 |
}
|
|
|
d5c778 |
|
|
|
d5c778 |
if ((cctx.drvflags & TOKS_DRIVER_MODE_SERVER) && (ntokens < 0)) {
|
|
|
c847e3 |
if (flags & TOKS_DRIVER_VERBOSITY_ERRORS)
|
|
|
c847e3 |
toks_dprintf(STDERR_FILENO,
|
|
|
c847e3 |
"%s: error: number of tokens not set or is invalid.",
|
|
|
c847e3 |
program);
|
|
|
c847e3 |
return toks_get_driver_ctx_fail(meta);
|
|
|
c847e3 |
}
|
|
|
c847e3 |
|
|
|
ee5c9c |
if ((cctx.drvflags & TOKS_DRIVER_MODE_SERVER) && (loglevel < 0)) {
|
|
|
ee5c9c |
if (flags & TOKS_DRIVER_VERBOSITY_ERRORS)
|
|
|
ee5c9c |
toks_dprintf(STDERR_FILENO,
|
|
|
ee5c9c |
"%s: error: loglevel must be in the range of 0..9.",
|
|
|
ee5c9c |
program);
|
|
|
ee5c9c |
return toks_get_driver_ctx_fail(meta);
|
|
|
ee5c9c |
}
|
|
|
ee5c9c |
|
|
|
618937 |
if (uuid && ntapi->tt_string_to_guid_utf8(uuid->arg,&svcguid)) {
|
|
|
618937 |
if (flags & TOKS_DRIVER_VERBOSITY_ERRORS)
|
|
|
618937 |
toks_dprintf(STDERR_FILENO,
|
|
|
618937 |
"%s: error: '%s' is not a valid service guid (did you forget the braces?)",
|
|
|
618937 |
program,uuid->arg);
|
|
|
618937 |
return toks_get_driver_ctx_fail(meta);
|
|
|
618937 |
|
|
|
618937 |
}
|
|
|
618937 |
|
|
|
2420c2 |
if (cctx.sysroot && toks_open_dir(&cctx.hroot,0,cctx.sysroot,false)) {
|
|
|
2420c2 |
if (flags & TOKS_DRIVER_VERBOSITY_ERRORS)
|
|
|
2420c2 |
toks_dprintf(STDERR_FILENO,
|
|
|
2420c2 |
"%s: error: could not open sysroot directory '%s'",
|
|
|
2420c2 |
program,cctx.sysroot);
|
|
|
2420c2 |
return toks_get_driver_ctx_fail(meta);
|
|
|
2420c2 |
}
|
|
|
2420c2 |
|
|
|
2420c2 |
if (!(ctx = toks_driver_ctx_alloc(meta,&cctx)))
|
|
|
2420c2 |
return toks_get_driver_ctx_fail(meta);
|
|
|
2420c2 |
|
|
|
a830d3 |
if (ctx->rtdata->hroot && cctx.sysroot) {
|
|
|
ed52e5 |
ntapi->zw_close(ctx->rtdata->hroot);
|
|
|
ed52e5 |
ctx->rtdata->hroot = cctx.hroot;
|
|
|
866f59 |
} else if (cctx.sysroot) {
|
|
|
866f59 |
ctx->rtdata->hroot = cctx.hroot;
|
|
|
a830d3 |
} else {
|
|
|
a830d3 |
cctx.hroot = ctx->rtdata->hroot;
|
|
|
ed52e5 |
}
|
|
|
ed52e5 |
|
|
|
ed52e5 |
if (cctx.logfile && toks_open_log_file(&hlog,ctx->rtdata->hroot,cctx.logfile,false)) {
|
|
|
ed52e5 |
if (flags & TOKS_DRIVER_VERBOSITY_ERRORS)
|
|
|
ed52e5 |
toks_dprintf(STDERR_FILENO,
|
|
|
ed52e5 |
"%s: error: could not create logfile '%s'",
|
|
|
ed52e5 |
program,cctx.logfile);
|
|
|
ed52e5 |
return toks_get_driver_ctx_fail(meta);
|
|
|
ed52e5 |
}
|
|
|
ed52e5 |
|
|
|
ed52e5 |
if (ctx->rtdata->hlog && cctx.logfile) {
|
|
|
ed52e5 |
ntapi->zw_close(ctx->rtdata->hlog);
|
|
|
ed52e5 |
ctx->rtdata->hlog = hlog;
|
|
|
ed52e5 |
}
|
|
|
ed52e5 |
|
|
|
867b30 |
if ((cctx.drvflags & TOKS_DRIVER_ACTION_RELEASE)) {
|
|
|
867b30 |
if (toks_client_str_to_token(&ctx->ctx,&key)) {
|
|
|
867b30 |
if (flags & TOKS_DRIVER_VERBOSITY_ERRORS)
|
|
|
867b30 |
toks_dprintf(STDERR_FILENO,
|
|
|
867b30 |
"%s: error: [%s] is not a valid token.",
|
|
|
867b30 |
program,key.token);
|
|
|
867b30 |
return toks_get_driver_ctx_fail(meta);
|
|
|
867b30 |
}
|
|
|
867b30 |
}
|
|
|
867b30 |
|
|
|
618937 |
|
|
|
2f270e |
if ((toks_ntapi->tt_create_private_event(
|
|
|
2f270e |
&ctx->hevent,
|
|
|
2f270e |
NT_NOTIFICATION_EVENT,
|
|
|
2f270e |
NT_EVENT_NOT_SIGNALED)))
|
|
|
2f270e |
return toks_get_driver_ctx_fail(meta);
|
|
|
2f270e |
|
|
|
236509 |
|
|
|
236509 |
if (uuid) {
|
|
|
236509 |
ntapi->tt_guid_copy(
|
|
|
0021e3 |
&ctx->guid,
|
|
|
236509 |
&svcguid);
|
|
|
236509 |
|
|
|
236509 |
} else if (cctx.drvflags & TOKS_DRIVER_ROOT_UUID) {
|
|
|
236509 |
if ((status = toks_set_uuid_from_root(ctx,&svcguid))) {
|
|
|
236509 |
if (flags & TOKS_DRIVER_VERBOSITY_ERRORS)
|
|
|
236509 |
toks_dprintf(STDERR_FILENO,
|
|
|
236509 |
"%s: error: could not set the uuid "
|
|
|
236509 |
"based on the sysroot directory [0x%08x].",
|
|
|
236509 |
program,status);
|
|
|
236509 |
return toks_get_driver_ctx_fail(meta);
|
|
|
236509 |
}
|
|
|
236509 |
|
|
|
236509 |
ntapi->tt_guid_copy(
|
|
|
0021e3 |
&ctx->guid,
|
|
|
236509 |
&svcguid);
|
|
|
236509 |
} else {
|
|
|
236509 |
ntapi->tt_guid_copy(
|
|
|
0021e3 |
&ctx->guid,
|
|
|
236509 |
&ctx->rtdata->srv_guid);
|
|
|
236509 |
}
|
|
|
236509 |
|
|
|
236509 |
|
|
|
00069c |
if ((ntapi->tt_open_dev_object_directory(
|
|
|
00069c |
&ctx->hsvcdir,
|
|
|
2c26a1 |
NT_SEC_READ_CONTROL
|
|
|
2c26a1 |
| NT_DIRECTORY_QUERY
|
|
|
2c26a1 |
| NT_DIRECTORY_TRAVERSE
|
|
|
2c26a1 |
| NT_DIRECTORY_CREATE_OBJECT
|
|
|
2c26a1 |
| NT_DIRECTORY_CREATE_SUBDIRECTORY,
|
|
|
00069c |
toks_service_name,
|
|
|
00069c |
&toks_daemon_default_guid)))
|
|
|
00069c |
return toks_get_driver_ctx_fail(meta);
|
|
|
00069c |
|
|
|
2f270e |
if ((hkernel32 = pe_get_kernel32_module_handle()))
|
|
|
2f270e |
if ((ctx->ticks.qpc = pe_get_procedure_address(
|
|
|
2f270e |
hkernel32,"QueryPerformanceCounter")))
|
|
|
2f270e |
ntapi->zw_query_performance_counter(
|
|
|
2f270e |
&(nt_filetime){{0,0}},
|
|
|
2f270e |
&ctx->ticks.pcfreq);
|
|
|
2f270e |
|
|
|
ed52e5 |
|
|
|
8f6a66 |
atokens = ntokens;
|
|
|
8f6a66 |
atokens += 0x1fff;
|
|
|
8f6a66 |
atokens |= 0xfff;
|
|
|
8f6a66 |
atokens ^= 0xfff;
|
|
|
8f6a66 |
|
|
|
ed52e5 |
ctx->hlog = hlog;
|
|
|
e3e583 |
ctx->tokpid = tokpid;
|
|
|
201fd7 |
ctx->tsyspid = tsyspid;
|
|
|
35e873 |
ctx->ctrlpid = ctrlpid;
|
|
|
35e873 |
ctx->csyspid = csyspid;
|
|
|
c847e3 |
ctx->ntokens = ntokens;
|
|
|
8f6a66 |
ctx->atokens = atokens;
|
|
|
b27e56 |
ctx->timeout = timeout;
|
|
|
2420c2 |
ctx->ctx.program = program;
|
|
|
2420c2 |
ctx->ctx.cctx = &ctx->cctx;
|
|
|
618937 |
ctx->cctx.uuid = &ctx->uuid;
|
|
|
7fcdf2 |
ctx->rtdata->hlog = hlog ? hlog : ctx->rtdata->hlog;
|
|
|
ed52e5 |
|
|
|
79252f |
toks_set_driver_refstr(&ctx->ctx,refstr);
|
|
|
0021e3 |
toks_guid_to_uuid(&ctx->guid,&ctx->uuid);
|
|
|
79252f |
|
|
|
c847e3 |
if (cctx.drvflags & TOKS_DRIVER_MODE_SERVER) {
|
|
|
3fc30f |
if ((status = toks_set_tmpfs_from_uuid(ctx))) {
|
|
|
3fc30f |
if (flags & TOKS_DRIVER_VERBOSITY_ERRORS)
|
|
|
3fc30f |
toks_dprintf(STDERR_FILENO,
|
|
|
3fc30f |
"%s: error: could not create or open "
|
|
|
3fc30f |
"the instance-specific tmpfs directory [0x%08x].",
|
|
|
3fc30f |
program,status);
|
|
|
3fc30f |
return toks_get_driver_ctx_fail(meta);
|
|
|
3fc30f |
}
|
|
|
3fc30f |
|
|
|
681a45 |
if (!(ctx->waiters = toks_calloc(
|
|
|
681a45 |
TOKS_MAX_WAITERS,
|
|
|
681a45 |
sizeof(struct toks_waiter))))
|
|
|
d73408 |
return toks_get_driver_ctx_fail(meta);
|
|
|
d73408 |
|
|
|
681a45 |
toks_daemon_ctx.driver_ctx = &ctx->ctx;
|
|
|
681a45 |
toks_daemon_ctx.waiter_base = ctx->waiters;
|
|
|
681a45 |
toks_daemon_ctx.waiter_first = ctx->waiters;
|
|
|
681a45 |
toks_daemon_ctx.waiter_next = ctx->waiters;
|
|
|
681a45 |
toks_daemon_ctx.waiter_cap = &ctx->waiters[TOKS_MAX_WAITERS];
|
|
|
681a45 |
|
|
|
681a45 |
|
|
|
8f6a66 |
if (!(ctx->tokens = toks_calloc(atokens,sizeof(*ctx->tokens))))
|
|
|
c847e3 |
return toks_get_driver_ctx_fail(meta);
|
|
|
c847e3 |
|
|
|
0021e3 |
if (toks_daemon_init(&toks_daemon_ctx,&ctx->guid))
|
|
|
f2a689 |
return toks_get_driver_ctx_fail(meta);
|
|
|
c847e3 |
}
|
|
|
f2a689 |
|
|
|
2c9219 |
if (cctx.drvflags & TOKS_DRIVER_MODE_CLIENT) {
|
|
|
3e9813 |
if (cctx.drvflags & TOKS_DRIVER_DAEMON_ALWAYS) {
|
|
|
3e9813 |
toks_daemon_ctx.driver_ctx = &ctx->ctx;
|
|
|
3e9813 |
|
|
|
3e9813 |
switch ((status = toks_daemon_init(&toks_daemon_ctx,0))) {
|
|
|
3e9813 |
case NT_STATUS_SUCCESS:
|
|
|
3e9813 |
break;
|
|
|
3e9813 |
|
|
|
3e9813 |
default:
|
|
|
3e9813 |
if (flags & TOKS_DRIVER_VERBOSITY_ERRORS)
|
|
|
3e9813 |
toks_dprintf(STDERR_FILENO,
|
|
|
3e9813 |
"%s: error: failed to initialize signal handling "
|
|
|
3e9813 |
"(check the system's documentation) [0x%x].",
|
|
|
3e9813 |
program,status);
|
|
|
3e9813 |
|
|
|
3e9813 |
return toks_get_driver_ctx_fail(meta);
|
|
|
3e9813 |
}
|
|
|
3e9813 |
}
|
|
|
3e9813 |
|
|
|
2c9219 |
switch ((status = toks_client_connect(&ctx->ctx))) {
|
|
|
2c9219 |
case NT_STATUS_SUCCESS:
|
|
|
2c9219 |
break;
|
|
|
2c9219 |
|
|
|
2c9219 |
case NT_STATUS_OBJECT_NAME_NOT_FOUND:
|
|
|
2c9219 |
if (flags & TOKS_DRIVER_VERBOSITY_ERRORS)
|
|
|
2c9219 |
toks_dprintf(STDERR_FILENO,
|
|
|
2c9219 |
"%s: error: could not connect "
|
|
|
2c9219 |
"(server not running) [0x%x].",
|
|
|
2c9219 |
program,status);
|
|
|
2c9219 |
|
|
|
2c9219 |
return toks_get_driver_ctx_fail(meta);
|
|
|
2c9219 |
|
|
|
2c9219 |
case NT_STATUS_CONNECTION_REFUSED:
|
|
|
2c9219 |
case NT_STATUS_PORT_CONNECTION_REFUSED:
|
|
|
2c9219 |
if (flags & TOKS_DRIVER_VERBOSITY_ERRORS)
|
|
|
2c9219 |
toks_dprintf(STDERR_FILENO,
|
|
|
2c9219 |
"%s: error: could not connect "
|
|
|
2c9219 |
"(connection refused) [0x%x].",
|
|
|
2c9219 |
program,status);
|
|
|
2c9219 |
|
|
|
2c9219 |
return toks_get_driver_ctx_fail(meta);
|
|
|
2c9219 |
|
|
|
2c9219 |
case NT_STATUS_ACCESS_DENIED:
|
|
|
2c9219 |
if (flags & TOKS_DRIVER_VERBOSITY_ERRORS)
|
|
|
2c9219 |
toks_dprintf(STDERR_FILENO,
|
|
|
2c9219 |
"%s: error: could not connect "
|
|
|
2c9219 |
"(access denied) [0x%x].",
|
|
|
2c9219 |
program,status);
|
|
|
2c9219 |
|
|
|
2c9219 |
return toks_get_driver_ctx_fail(meta);
|
|
|
2c9219 |
|
|
|
2c9219 |
default:
|
|
|
2c9219 |
if (flags & TOKS_DRIVER_VERBOSITY_ERRORS)
|
|
|
2c9219 |
toks_dprintf(STDERR_FILENO,
|
|
|
2c9219 |
"%s: error: could not connect "
|
|
|
2c9219 |
"(check the system's documentation) [0x%x].",
|
|
|
2c9219 |
program,status);
|
|
|
2c9219 |
|
|
|
2c9219 |
return toks_get_driver_ctx_fail(meta);
|
|
|
2c9219 |
}
|
|
|
bd4f0c |
|
|
|
bd4f0c |
if (cctx.drvflags & TOKS_DRIVER_ACTION_NTOKENS_GET) {
|
|
|
bd4f0c |
status = toks_service_ioctl(
|
|
|
bd4f0c |
&ctx->ctx,TOKS_IOCTL_GET_TOKEN_COUNT,
|
|
|
bd4f0c |
&opdata,0);
|
|
|
bd4f0c |
|
|
|
bd4f0c |
switch (status) {
|
|
|
bd4f0c |
case NT_STATUS_SUCCESS:
|
|
|
bd4f0c |
ctx->ntokens = opdata;
|
|
|
bd4f0c |
break;
|
|
|
bd4f0c |
|
|
|
bd4f0c |
default:
|
|
|
bd4f0c |
if (flags & TOKS_DRIVER_VERBOSITY_ERRORS)
|
|
|
bd4f0c |
toks_dprintf(STDERR_FILENO,
|
|
|
bd4f0c |
"%s: error: could not obtain the current "
|
|
|
bd4f0c |
"overall number of tokens "
|
|
|
bd4f0c |
"(check the system's documentation) [0x%x].",
|
|
|
bd4f0c |
program,status);
|
|
|
bd4f0c |
|
|
|
bd4f0c |
return toks_get_driver_ctx_fail(meta);
|
|
|
bd4f0c |
}
|
|
|
bd4f0c |
}
|
|
|
7f4116 |
|
|
|
7f4116 |
if (cctx.drvflags & TOKS_DRIVER_ACTION_LOGLEVEL_GET) {
|
|
|
7f4116 |
status = toks_service_ioctl(
|
|
|
7f4116 |
&ctx->ctx,TOKS_IOCTL_GET_LOG_LEVEL,
|
|
|
7f4116 |
&opdata,0);
|
|
|
7f4116 |
|
|
|
7f4116 |
switch (status) {
|
|
|
7f4116 |
case NT_STATUS_SUCCESS:
|
|
|
7f4116 |
ctx->cctx.loglevel = opdata;
|
|
|
7f4116 |
break;
|
|
|
7f4116 |
|
|
|
7f4116 |
default:
|
|
|
7f4116 |
if (flags & TOKS_DRIVER_VERBOSITY_ERRORS)
|
|
|
7f4116 |
toks_dprintf(STDERR_FILENO,
|
|
|
7f4116 |
"%s: error: could not obtain the server's "
|
|
|
7f4116 |
"current log-level parameter "
|
|
|
7f4116 |
"(check the system's documentation) [0x%x].",
|
|
|
7f4116 |
program,status);
|
|
|
7f4116 |
|
|
|
7f4116 |
return toks_get_driver_ctx_fail(meta);
|
|
|
7f4116 |
}
|
|
|
7f4116 |
}
|
|
|
2c9219 |
}
|
|
|
486fcd |
|
|
|
2420c2 |
*pctx = &ctx->ctx;
|
|
|
2420c2 |
return TOKS_OK;
|
|
|
2420c2 |
}
|
|
|
2420c2 |
|
|
|
2420c2 |
static void toks_free_driver_ctx_impl(struct toks_driver_ctx_alloc * ictx)
|
|
|
2420c2 |
{
|
|
|
3fc30f |
if (ictx->ctx.htmpfs)
|
|
|
3fc30f |
ntapi->zw_close(ictx->ctx.htmpfs);
|
|
|
3fc30f |
|
|
|
2f270e |
if (ictx->ctx.hevent)
|
|
|
2f270e |
ntapi->zw_close(ictx->ctx.hevent);
|
|
|
2f270e |
|
|
|
00069c |
if (ictx->ctx.hsvcdir)
|
|
|
00069c |
ntapi->zw_close(ictx->ctx.hsvcdir);
|
|
|
00069c |
|
|
|
00069c |
if (ictx->ctx.hsvclink)
|
|
|
00069c |
ntapi->zw_close(ictx->ctx.hsvclink);
|
|
|
00069c |
|
|
|
aba5a2 |
if (ictx->ctx.hservice)
|
|
|
aba5a2 |
ntapi->zw_close(ictx->ctx.hservice);
|
|
|
aba5a2 |
|
|
|
83e502 |
if (ictx->ctx.hserver)
|
|
|
83e502 |
ntapi->zw_close(ictx->ctx.hserver);
|
|
|
83e502 |
|
|
|
ed52e5 |
if (ictx->ctx.hlog)
|
|
|
ed52e5 |
ntapi->zw_close(ictx->ctx.hlog);
|
|
|
ed52e5 |
|
|
|
c847e3 |
if (ictx->ctx.tokens)
|
|
|
c847e3 |
toks_free(ictx->ctx.tokens);
|
|
|
c847e3 |
|
|
|
d73408 |
if (ictx->ctx.waiters)
|
|
|
d73408 |
toks_free(ictx->ctx.waiters);
|
|
|
d73408 |
|
|
|
2420c2 |
argv_free(ictx->meta);
|
|
|
2420c2 |
free(ictx);
|
|
|
2420c2 |
}
|
|
|
2420c2 |
|
|
|
2420c2 |
void toks_free_driver_ctx(struct toks_driver_ctx * ctx)
|
|
|
2420c2 |
{
|
|
|
2420c2 |
struct toks_driver_ctx_alloc * ictx;
|
|
|
2420c2 |
uintptr_t addr;
|
|
|
2420c2 |
|
|
|
2420c2 |
if (ctx) {
|
|
|
2420c2 |
addr = (uintptr_t)ctx - offsetof(struct toks_driver_ctx_impl,ctx);
|
|
|
2420c2 |
addr = addr - offsetof(struct toks_driver_ctx_alloc,ctx);
|
|
|
2420c2 |
ictx = (struct toks_driver_ctx_alloc *)addr;
|
|
|
2420c2 |
toks_free_driver_ctx_impl(ictx);
|
|
|
2420c2 |
}
|
|
|
2420c2 |
}
|
|
|
2420c2 |
|
|
|
b27e56 |
void toks_driver_set_timeout(struct toks_driver_ctx * dctx, int64_t millisecs)
|
|
|
b27e56 |
{
|
|
|
b27e56 |
toks_set_driver_timeout(dctx,millisecs);
|
|
|
b27e56 |
}
|
|
|
b27e56 |
|
|
|
b27e56 |
void toks_driver_unset_timeout(struct toks_driver_ctx * dctx)
|
|
|
b27e56 |
{
|
|
|
b27e56 |
toks_set_driver_timeout(dctx,(-1));
|
|
|
b27e56 |
}
|
|
|
b27e56 |
|
|
|
f4d6f1 |
void toks_driver_set_refstr(struct toks_driver_ctx * dctx, const char * refstr)
|
|
|
f4d6f1 |
{
|
|
|
f4d6f1 |
toks_set_driver_refstr(dctx,refstr);
|
|
|
f4d6f1 |
}
|
|
|
f4d6f1 |
|
|
|
f4d6f1 |
void toks_driver_unset_refstr(struct toks_driver_ctx * dctx)
|
|
|
f4d6f1 |
{
|
|
|
f4d6f1 |
toks_set_driver_refstr(dctx,0);
|
|
|
f4d6f1 |
}
|
|
|
f4d6f1 |
|
|
|
2420c2 |
const struct toks_source_version * toks_source_version(void)
|
|
|
2420c2 |
{
|
|
|
2420c2 |
return &toks_src_version;
|
|
|
2420c2 |
}
|