diff --git a/src/client/toks_client_acquire.c b/src/client/toks_client_acquire.c index 97e998b..8dfd205 100644 --- a/src/client/toks_client_acquire.c +++ b/src/client/toks_client_acquire.c @@ -30,12 +30,25 @@ int32_t toks_client_acquire(struct toks_driver_ctx * dctx) msg.data.ttyinfo.opcode = TOKS_DAEMON_ACQUIRE; msg.data.ipcinfo.ctrlsvc.keys.key[0] = toks_get_driver_tokpid(dctx); + msg.data.ipcinfo.hevent = toks_get_driver_hevent(dctx); if ((status = ntapi->zw_request_wait_reply_port(hport,&msg,&msg))) return status; - else if (msg.data.ttyinfo.status) - return msg.data.ttyinfo.status; + switch (msg.data.ttyinfo.status) { + case NT_STATUS_SUCCESS: + break; + + case NT_STATUS_PENDING: + status = ntapi->zw_wait_for_single_object( + msg.data.ipcinfo.hevent, + NT_SYNC_NON_ALERTABLE, + 0); + break; + + default: + return msg.data.ttyinfo.status; + } keys->key[0] = msg.data.ipcinfo.ipckeys[0]; keys->key[1] = msg.data.ipcinfo.ipckeys[1]; @@ -44,5 +57,5 @@ int32_t toks_client_acquire(struct toks_driver_ctx * dctx) keys->key[4] = msg.data.ipcinfo.ipckeys[4]; keys->key[5] = msg.data.ipcinfo.ipckeys[5]; - return NT_STATUS_SUCCESS; + return status; } diff --git a/src/daemon/toks_daemon_acquire.c b/src/daemon/toks_daemon_acquire.c index af262ac..587b04f 100644 --- a/src/daemon/toks_daemon_acquire.c +++ b/src/daemon/toks_daemon_acquire.c @@ -148,11 +148,13 @@ static int32_t toks_daemon_token_instance( return NT_STATUS_SUCCESS; } -static int32_t toks_daemon_queue(struct toks_daemon_ctx * dctx) +static int32_t toks_daemon_queue(struct toks_daemon_ctx * dctx, void * hcaller, void * hprocess) { int nwaiters; struct toks_waiter * waiter; nt_tty_port_msg * msg; + void * hevent; + int32_t status; msg = &dctx->reply; nwaiters = toks_get_driver_nwaiters(dctx->driver_ctx); @@ -160,8 +162,34 @@ static int32_t toks_daemon_queue(struct toks_daemon_ctx * dctx) if (nwaiters == TOKS_MAX_WAITERS) return NT_STATUS_TIMEOUT; + + status = ntapi->zw_duplicate_object( + hcaller, + msg->ipcinfo.hevent, + NT_CURRENT_PROCESS_HANDLE, + &hevent, + NT_EVENT_QUERY_STATE|NT_EVENT_MODIFY_STATE, + 0,0); + + ntapi->zw_close(hcaller); + + if (status) { + ntapi->zw_close(hprocess); + return status; + } + + if ((status = ntapi->zw_reset_event(hevent,&(int){0}))) { + ntapi->zw_close(hprocess); + ntapi->zw_close(hevent); + return status; + } + + waiter = dctx->waiter_next; + waiter->client.hprocess = hprocess; + waiter->client.hevent = hevent; + toks_set_driver_nwaiters( dctx->driver_ctx, ++nwaiters); @@ -175,24 +203,21 @@ static int32_t toks_daemon_queue(struct toks_daemon_ctx * dctx) &waiter->msg,msg, sizeof(*msg)); - msg->ttyinfo.exarg = 0; - - return NT_STATUS_SUCCESS; + return NT_STATUS_PENDING; } int32_t __stdcall toks_daemon_acquire(struct toks_daemon_ctx * dctx) { int32_t status; nt_tty_port_msg * msg; + void * hcaller; struct toks_client_ctx client; nt_oa oa; struct toks_token * token; struct toks_token * tocap; - nt_timeout timeout; nt_filetime pcnt; msg = &dctx->reply; - timeout.quad = (int64_t)msg->ttyinfo.exarg; client.hport = 0; client.hprocess = 0; @@ -208,71 +233,123 @@ int32_t __stdcall toks_daemon_acquire(struct toks_daemon_ctx * dctx) oa.sec_desc = 0; oa.sec_qos = 0; - (void)timeout; + if (dctx->opcode == TOKS_DAEMON_ACQUIRE) { + if (msg->ipcinfo.ctrlsvc.keys.key[0]) { + if ((status = toks_daemon_pidopen(dctx))) + return status; - if (msg->ipcinfo.ctrlsvc.keys.key[0]) { - if ((status = toks_daemon_pidopen(dctx))) - return status; + client.cid.process_id = msg->ipcinfo.ctrlsvc.keys.key[1]; + } - client.cid.process_id = msg->ipcinfo.ctrlsvc.keys.key[1]; + if ((status = ntapi->zw_open_process( + &client.hprocess, + NT_PROCESS_SYNCHRONIZE + | NT_PROCESS_DUP_HANDLE + | NT_PROCESS_QUERY_INFORMATION, + &oa,&client.cid))) + return status; } - if ((status = ntapi->zw_open_process( - &client.hprocess, - NT_PROCESS_SYNCHRONIZE | NT_PROCESS_QUERY_INFORMATION, - &oa,&client.cid))) - return status; - token = toks_get_driver_tokens(dctx->driver_ctx); tocap = &token[toks_get_driver_ntokens(dctx->driver_ctx)]; for (; token->self && (tokenipcinfo.hevent) { + if ((token == tocap) && !msg->ipcinfo.hevent) { ntapi->zw_close(client.hprocess); return NT_STATUS_TIMEOUT; } + toks_query_performance_counters(dctx->driver_ctx,&pcnt); + if (token == tocap) { - ntapi->zw_close(client.hprocess); - return toks_daemon_queue(dctx); - } + status = ntapi->zw_open_process( + &hcaller, + NT_PROCESS_SYNCHRONIZE + | NT_PROCESS_DUP_HANDLE + | NT_PROCESS_QUERY_INFORMATION, + &oa,&msg->header.client_id); + + if (status) { + ntapi->zw_close(client.hprocess); + return status; + } - toks_query_performance_counters(dctx->driver_ctx,&pcnt); + msg->ipcinfo.ipckeys[0] = ntapi->tt_buffer_crc32( + msg->header.msg_id, + &pcnt,sizeof(pcnt)); - token->keys.key[0] = ntapi->tt_buffer_crc32( - msg->header.msg_id, - &pcnt,sizeof(pcnt)); - - token->keys.key[1] = ntapi->tt_buffer_crc32( - msg->header.msg_id, - &msg->header,sizeof(msg->header)); - - token->keys.key[2] = ntapi->tt_buffer_crc32( - msg->header.msg_id, - &msg->ipcinfo,sizeof(msg->ipcinfo)); - - token->keys.key[3] = ntapi->tt_buffer_crc32( - msg->header.msg_id, - &client,sizeof(client)); - - token->keys.key[4] = ntapi->tt_buffer_crc32( - msg->header.msg_id, - toks_get_driver_tokens(dctx->driver_ctx), - toks_get_driver_ntokens(dctx->driver_ctx) - * sizeof(struct toks_token)); - - token->keys.key[5] = ntapi->tt_buffer_crc32( - msg->header.msg_id, - &token->keys,sizeof(token->keys)); - - msg->ipcinfo.ipckeys[0] = token->keys.key[0]; - msg->ipcinfo.ipckeys[1] = token->keys.key[1]; - msg->ipcinfo.ipckeys[2] = token->keys.key[2]; - msg->ipcinfo.ipckeys[3] = token->keys.key[3]; - msg->ipcinfo.ipckeys[4] = token->keys.key[4]; - msg->ipcinfo.ipckeys[5] = token->keys.key[5]; + msg->ipcinfo.ipckeys[1] = ntapi->tt_buffer_crc32( + msg->header.msg_id, + &msg->header,sizeof(msg->header)); + + msg->ipcinfo.ipckeys[2] = ntapi->tt_buffer_crc32( + msg->header.msg_id, + &msg->ipcinfo,sizeof(msg->ipcinfo)); + + msg->ipcinfo.ipckeys[3] = ntapi->tt_buffer_crc32( + msg->header.msg_id, + &client,sizeof(client)); + + msg->ipcinfo.ipckeys[4] = ntapi->tt_buffer_crc32( + msg->header.msg_id, + toks_get_driver_tokens(dctx->driver_ctx), + toks_get_driver_ntokens(dctx->driver_ctx) + * sizeof(struct toks_token)); + + msg->ipcinfo.ipckeys[5] = ntapi->tt_buffer_crc32( + msg->header.msg_id, + &token->keys,sizeof(token->keys)); + + return toks_daemon_queue( + dctx,hcaller, + client.hprocess); + } + + if (dctx->opcode == TOKS_DAEMON_RELEASE) { + client.hprocess = msg->ttyinfo.exarg; + + token->keys.key[0] = msg->ipcinfo.ipckeys[0]; + token->keys.key[1] = msg->ipcinfo.ipckeys[1]; + token->keys.key[2] = msg->ipcinfo.ipckeys[2]; + token->keys.key[3] = msg->ipcinfo.ipckeys[3]; + token->keys.key[4] = msg->ipcinfo.ipckeys[4]; + token->keys.key[5] = msg->ipcinfo.ipckeys[5]; + } else { + token->keys.key[0] = ntapi->tt_buffer_crc32( + msg->header.msg_id, + &pcnt,sizeof(pcnt)); + + token->keys.key[1] = ntapi->tt_buffer_crc32( + msg->header.msg_id, + &msg->header,sizeof(msg->header)); + + token->keys.key[2] = ntapi->tt_buffer_crc32( + msg->header.msg_id, + &msg->ipcinfo,sizeof(msg->ipcinfo)); + + token->keys.key[3] = ntapi->tt_buffer_crc32( + msg->header.msg_id, + &client,sizeof(client)); + + token->keys.key[4] = ntapi->tt_buffer_crc32( + msg->header.msg_id, + toks_get_driver_tokens(dctx->driver_ctx), + toks_get_driver_ntokens(dctx->driver_ctx) + * sizeof(struct toks_token)); + + token->keys.key[5] = ntapi->tt_buffer_crc32( + msg->header.msg_id, + &token->keys,sizeof(token->keys)); + + msg->ipcinfo.ipckeys[0] = token->keys.key[0]; + msg->ipcinfo.ipckeys[1] = token->keys.key[1]; + msg->ipcinfo.ipckeys[2] = token->keys.key[2]; + msg->ipcinfo.ipckeys[3] = token->keys.key[3]; + msg->ipcinfo.ipckeys[4] = token->keys.key[4]; + msg->ipcinfo.ipckeys[5] = token->keys.key[5]; + } if ((status = toks_daemon_token_instance(token,&client))) { toks_daemon_token_reset(token); diff --git a/src/daemon/toks_daemon_release.c b/src/daemon/toks_daemon_release.c index fbaffe1..2889620 100644 --- a/src/daemon/toks_daemon_release.c +++ b/src/daemon/toks_daemon_release.c @@ -59,13 +59,12 @@ static int32_t toks_daemon_unqueue(struct toks_daemon_ctx * dctx) msg,&waiter->msg, sizeof(*msg)); - status = toks_daemon_acquire(dctx); - msg->ttyinfo.status = status; - msg->ttyinfo.exarg = waiter; + msg->ttyinfo.exarg = waiter->client.hprocess; + msg->ttyinfo.status = toks_daemon_acquire(dctx); + status = msg->ttyinfo.status; - ntapi->zw_reply_port( - dctx->hport_daemon, - &msg->header); + ntapi->zw_set_event(waiter->client.hevent,0); + ntapi->zw_close(waiter->client.hevent); ntapi->tt_generic_memcpy( msg,&cmsg, diff --git a/src/internal/toksvc_daemon_impl.h b/src/internal/toksvc_daemon_impl.h index 4c397d0..4a21a0f 100644 --- a/src/internal/toksvc_daemon_impl.h +++ b/src/internal/toksvc_daemon_impl.h @@ -26,6 +26,7 @@ struct toks_client_ctx { void * hport; void * hswap; void * halert; + void * hevent; void * hdaemon; nt_cid cid; };