| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| static int32_t toks_daemon_init_impl( |
| struct toks_daemon_ctx * dctx, |
| const nt_guid * svcguid, |
| void * htty) |
| { |
| int32_t status; |
| nt_daemon_params dparams; |
| wchar16_t * port_name; |
| nt_port_name_keys * port_name_keys; |
| void * hsvclink; |
| |
| |
| dctx->daemon_attr.type = NT_PORT_TYPE_DAEMON; |
| dctx->daemon_attr.subtype = NT_PORT_SUBTYPE_DEFAULT; |
| |
| |
| ntapi->tt_guid_copy( |
| &dctx->daemon_attr.guid, |
| svcguid); |
| |
| |
| if ((status = ntapi->tt_port_generate_keys(&dctx->daemon_attr.keys))) |
| return status; |
| |
| |
| ntapi->tt_port_name_from_attr( |
| &dctx->daemon_name, |
| &dctx->daemon_attr); |
| |
| |
| ntapi->tt_aligned_block_memset( |
| &dparams,0,sizeof(dparams)); |
| |
| port_name = (wchar16_t *)&dctx->daemon_name; |
| port_name_keys = (nt_port_name_keys *)&dctx->daemon_name.port_name_keys; |
| |
| dparams.port_keys = &dctx->daemon_keys; |
| dparams.port_name = port_name; |
| dparams.port_name_keys = port_name_keys; |
| |
| dparams.port_msg_size = sizeof(nt_tty_port_msg); |
| dparams.flags = NT_DSR_INIT_DEFAULT; |
| |
| dparams.daemon_once_routine = 0; |
| dparams.daemon_loop_routine = toks_daemon_loop; |
| dparams.daemon_loop_context = dctx; |
| |
| dparams.pport_daemon = &dctx->hport_daemon; |
| dparams.pport_internal_client = &dctx->hport_internal_client; |
| |
| dparams.pevent_daemon_ready = &dctx->hevent_daemon_ready; |
| dparams.pevent_internal_client_ready = &dctx->hevent_internal_client_ready; |
| |
| dparams.stack_size_commit = 8192; |
| dparams.stack_size_reserve = 8192; |
| |
| if ((status = ntapi->dsr_init(&dparams))) |
| return status; |
| |
| if ((status = ntapi->tt_create_dev_object_directory_entry( |
| &hsvclink, |
| NT_SYMBOLIC_LINK_ALL_ACCESS, |
| toks_get_driver_hsvcdir(dctx->driver_ctx), |
| dparams.hport_daemon,0, |
| svcguid))) |
| return status; |
| |
| toks_set_driver_hsvclink( |
| dctx->driver_ctx, |
| hsvclink); |
| |
| return ntapi->tty_request_peer( |
| htty, |
| TOKS_DAEMON_TTYSIGNAL, |
| 0,&(nt_guid)TTY_PTS_GUID, |
| &dctx->daemon_attr); |
| } |
| |
| static int32_t toks_daemon_once = 0; |
| |
| int32_t __stdcall toks_daemon_init(struct toks_daemon_ctx * dctx, const nt_guid * svcguid) |
| { |
| int32_t status; |
| nt_timeout timeout; |
| nt_runtime_data * rtdata; |
| nt_filetime pcnt; |
| nt_guid cliguid; |
| uint32_t * data; |
| |
| |
| if ((status = ntapi->tt_get_runtime_data(&rtdata,0))) |
| return status; |
| |
| |
| if (!svcguid) { |
| toks_query_performance_counters(dctx->driver_ctx,&pcnt); |
| |
| svcguid = &cliguid; |
| data = &cliguid.data1; |
| |
| data[0] = ntapi->tt_buffer_crc32( |
| (uint32_t)(uintptr_t)&cliguid, |
| &pcnt,sizeof(pcnt)); |
| |
| data[1] = ntapi->tt_buffer_crc32( |
| (uint32_t)(uintptr_t)rtdata, |
| rtdata,sizeof(*rtdata)); |
| |
| data[2] = ntapi->tt_buffer_crc32( |
| data[1],dctx,sizeof(*dctx)); |
| |
| data[3] = ntapi->tt_buffer_crc32( |
| data[2],dctx->driver_ctx, |
| sizeof(*dctx->driver_ctx)); |
| } |
| |
| |
| switch (at_locked_cas_32(&toks_daemon_once,0,1)) { |
| case 0: |
| if ((status = toks_daemon_init_impl(dctx,svcguid,rtdata->hsession))) { |
| at_locked_add_32(&toks_daemon_once,2); |
| return status; |
| } |
| |
| at_locked_inc_32(&toks_daemon_once); |
| return 0; |
| |
| case 1: |
| timeout.quad = -10; |
| |
| for (; (at_locked_cas_32(&toks_daemon_once,0,1) == 1); ) |
| ntapi->zw_delay_execution( |
| NT_SYNC_ALERTABLE, |
| &timeout); |
| |
| return (toks_daemon_once == 2) |
| ? 0 : -1; |
| |
| case 2: |
| return 0; |
| |
| case 3: |
| default: |
| return -1; |
| } |
| } |