diff --git a/src/daemon/toks_daemon_loop.c b/src/daemon/toks_daemon_loop.c index 862f615..be54404 100644 --- a/src/daemon/toks_daemon_loop.c +++ b/src/daemon/toks_daemon_loop.c @@ -34,6 +34,120 @@ static toks_daemon_routine * toks_client_vtbl[TOKS_VTBL_ELEMENTS] = { TOKS_HANDLER(TTYSIGNAL, toks_daemon_signal), }; +static void toks_daemon_ctrlpid_abort(struct toks_daemon_ctx * dctx) +{ + void * hport; + struct _nt_tty_sync_msg msg; + + hport = dctx->hport_internal_client; + + ntapi->tt_aligned_block_memset( + &msg,0,sizeof(msg)); + + msg.header.msg_type = NT_LPC_NEW_MESSAGE; + msg.header.data_size = sizeof(msg.data); + msg.header.msg_size = sizeof(msg); + msg.data.ttyinfo.opcode = TOKS_DAEMON_ABORT; + + ntapi->zw_request_wait_reply_port( + hport,&msg,&msg); +} + +static int32_t toks_daemon_ctrlpid_wait(void * rapunzel) +{ + struct toks_daemon_ctx * dctx; + + dctx = (struct toks_daemon_ctx *)rapunzel; + + ntapi->zw_set_event( + dctx->hswap,0); + + ntapi->zw_wait_for_single_object( + dctx->hctrl, + NT_SYNC_NON_ALERTABLE, + 0); + + toks_daemon_ctrlpid_abort(dctx); + + return ntapi->zw_terminate_thread( + NT_CURRENT_THREAD_HANDLE, + NT_STATUS_REMOTE_DISCONNECT); + +} + +static int32_t toks_daemon_ctrlpid_instance(struct toks_daemon_ctx * dctx) +{ + int32_t status; + nt_thread_params params; + nt_cid cid; + nt_oa oa; + + if ((dctx->ctrlpid == 0) && (dctx->csyspid == 0)) + return NT_STATUS_SUCCESS; + + if (dctx->ctrlpid) { + dctx->reqtokpid = dctx->ctrlpid; + + if ((status = toks_daemon_pidopen(dctx))) + return status; + + dctx->csyspid = dctx->reqsyspid; + } + + oa.len = sizeof(oa); + oa.root_dir = 0; + oa.obj_name = 0; + oa.obj_attr = 0; + oa.sec_desc = 0; + oa.sec_qos = 0; + + cid.process_id = dctx->csyspid; + cid.thread_id = 0; + + if ((status = ntapi->zw_open_process( + &dctx->hctrl, + NT_PROCESS_SYNCHRONIZE, + &oa,&cid))) + return status; + + if ((status = ntapi->tt_create_private_event( + &dctx->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_ctrlpid_wait; + params.arg = dctx; + 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))) { + ntapi->zw_close(dctx->hctrl); + ntapi->zw_close(dctx->hswap); + return status; + } + + status = ntapi->zw_wait_for_single_object( + dctx->hswap, + NT_SYNC_NON_ALERTABLE, + 0); + + ntapi->zw_close(dctx->hswap); + ntapi->zw_close(params.hthread); + + if (status) { + ntapi->zw_close(dctx->hctrl); + return status; + } + + return NT_STATUS_SUCCESS; +} + int32_t __stdcall toks_daemon_loop(void * ctx) { struct toks_daemon_ctx * dctx; @@ -45,16 +159,26 @@ int32_t __stdcall toks_daemon_loop(void * ctx) intptr_t port_id; int32_t opcode; + int32_t status; if (ntapi->tt_get_runtime_data(&rtdata,0)) return NT_STATUS_INTERNAL_ERROR; dctx = (struct toks_daemon_ctx *)ctx; + dctx->ctrlpid = toks_get_driver_ctrlpid(dctx->driver_ctx); + dctx->csyspid = toks_get_driver_csyspid(dctx->driver_ctx); + svcvtbl = (dctx->driver_ctx->cctx->drvflags & TOKS_DRIVER_MODE_SERVER) ? toks_daemon_vtbl : toks_client_vtbl; + if (svcvtbl == toks_daemon_vtbl) + if ((status = toks_daemon_ctrlpid_instance(dctx))) + ntapi->zw_terminate_process( + NT_CURRENT_PROCESS_HANDLE, + status); + /* init */ request = &dctx->request; reply = &dctx->reply; diff --git a/src/driver/toks_driver_ctx.c b/src/driver/toks_driver_ctx.c index c88d67a..293264a 100644 --- a/src/driver/toks_driver_ctx.c +++ b/src/driver/toks_driver_ctx.c @@ -276,6 +276,8 @@ int toks_get_driver_ctx( struct argv_entry * uuid; struct argv_entry * pid; struct argv_entry * syspid; + struct argv_entry * cfpid; + struct argv_entry * cspid; struct argv_entry * msecs; struct toks_token_string key; size_t keylen; @@ -285,6 +287,8 @@ int toks_get_driver_ctx( int ntokens; int32_t tokpid; int32_t tsyspid; + int32_t ctrlpid; + int32_t csyspid; int64_t timeout; void * hkernel32; char * targv[TOKS_SARGV_ELEMENTS]; @@ -314,6 +318,8 @@ int toks_get_driver_ctx( uuid = 0; tokpid = 0; tsyspid = 0; + ctrlpid = 0; + csyspid = 0; keylen = 0; ntokens = 0; timeout = (-1); @@ -366,6 +372,14 @@ int toks_get_driver_ctx( tsyspid = toks_arg_to_int32((syspid=entry)); break; + case TAG_CTRLPID: + ctrlpid = toks_arg_to_int32((cfpid=entry)); + break; + + case TAG_CSYSPID: + csyspid = toks_arg_to_int32((cspid=entry)); + break; + case TAG_TIMEOUT: timeout = toks_arg_to_int64((msecs=entry)); timeout = (timeout < 0) ? (-2) : timeout; @@ -430,6 +444,24 @@ int toks_get_driver_ctx( return toks_get_driver_ctx_fail(meta); } + if ((cctx.drvflags & TOKS_DRIVER_MODE_SERVER) && (ctrlpid < 0)) { + if (flags & TOKS_DRIVER_VERBOSITY_ERRORS) + toks_dprintf(STDERR_FILENO, + "%s: error: %s is not a valid controlling " + "framework process id.", + program,cfpid->arg); + return toks_get_driver_ctx_fail(meta); + } + + if ((cctx.drvflags & TOKS_DRIVER_MODE_SERVER) && (csyspid < 0)) { + if (flags & TOKS_DRIVER_VERBOSITY_ERRORS) + toks_dprintf(STDERR_FILENO, + "%s: error: %s is not a valid controlling " + "system process id.", + program,cspid->arg); + return toks_get_driver_ctx_fail(meta); + } + if ((cctx.drvflags & TOKS_DRIVER_MODE_CLIENT) && (timeout < (-1))) { if (flags & TOKS_DRIVER_VERBOSITY_ERRORS) toks_dprintf(STDERR_FILENO, @@ -506,6 +538,8 @@ int toks_get_driver_ctx( ctx->tokpid = tokpid; ctx->tsyspid = tsyspid; + ctx->ctrlpid = ctrlpid; + ctx->csyspid = csyspid; ctx->ntokens = ntokens; ctx->timeout = timeout; ctx->ctx.program = program; diff --git a/src/internal/toksvc_daemon_impl.h b/src/internal/toksvc_daemon_impl.h index fea6f4d..7df3a99 100644 --- a/src/internal/toksvc_daemon_impl.h +++ b/src/internal/toksvc_daemon_impl.h @@ -60,6 +60,12 @@ struct toks_daemon_ctx { nt_port_attr daemon_attr; nt_port_name daemon_name; + intptr_t ctrlpid; + intptr_t csyspid; + + void * hctrl; + void * hswap; + void * hport_daemon; void * hevent_daemon_ready; diff --git a/src/internal/toksvc_driver_impl.h b/src/internal/toksvc_driver_impl.h index 6ef8a6c..83c3216 100644 --- a/src/internal/toksvc_driver_impl.h +++ b/src/internal/toksvc_driver_impl.h @@ -39,6 +39,8 @@ enum app_tags { TAG_REFSTR, TAG_PID, TAG_SYSPID, + TAG_CTRLPID, + TAG_CSYSPID, }; struct toks_ticks { @@ -66,6 +68,8 @@ struct toks_driver_ctx_impl { int ntokens; int tokpid; int tsyspid; + int ctrlpid; + int csyspid; nt_guid uuid; }; @@ -235,6 +239,20 @@ static inline int toks_get_driver_tsyspid(const struct toks_driver_ctx * dctx) return ictx->tsyspid; } +static inline int toks_get_driver_ctrlpid(const struct toks_driver_ctx * dctx) +{ + struct toks_driver_ctx_impl * ictx; + ictx = toks_get_driver_ictx(dctx); + return ictx->ctrlpid; +} + +static inline int toks_get_driver_csyspid(const struct toks_driver_ctx * dctx) +{ + struct toks_driver_ctx_impl * ictx; + ictx = toks_get_driver_ictx(dctx); + return ictx->csyspid; +} + static inline char * toks_get_driver_refstr(const struct toks_driver_ctx * dctx) { struct toks_driver_ctx_impl * ictx; diff --git a/src/skin/toks_skin_default.c b/src/skin/toks_skin_default.c index 6012a97..a57ef22 100644 --- a/src/skin/toks_skin_default.c +++ b/src/skin/toks_skin_default.c @@ -56,5 +56,13 @@ const struct argv_option toks_default_options[] = { "a timeout of zero milliseconds implies no wait at all; " "not setting a timeout implies an indefinite wait."}, + {"ctrl-pid", 'l',TAG_CTRLPID,ARGV_OPTARG_REQUIRED,0,0,"", + "set the service's controlling process to the " + "framework process identified by %s"}, + + {"ctrl-syspid", 'L',TAG_CSYSPID,ARGV_OPTARG_REQUIRED,0,0,"", + "set the service's controlling process to the " + "system process identified by %s"}, + {0,0,0,0,0,0,0,0} };