|
|
dd89bb |
/********************************************************/
|
|
|
dd89bb |
/* ntapi: Native API core library */
|
|
|
4256e2 |
/* Copyright (C) 2013--2016 Z. Gilboa */
|
|
|
dd89bb |
/* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */
|
|
|
dd89bb |
/********************************************************/
|
|
|
dd89bb |
|
|
|
6c2ba1 |
#include <ntapi/nt_atomic.h>
|
|
|
dd89bb |
#include <ntapi/nt_status.h>
|
|
|
dd89bb |
#include <ntapi/nt_thread.h>
|
|
|
dd89bb |
#include <ntapi/nt_port.h>
|
|
|
dd89bb |
#include <ntapi/nt_daemon.h>
|
|
|
dd89bb |
#include <ntapi/ntapi.h>
|
|
|
dd89bb |
#include "ntapi_impl.h"
|
|
|
dd89bb |
|
|
|
6f3f3f |
static int32_t __stdcall __ntapi_dsr_once(nt_daemon_params * params);
|
|
|
dd89bb |
|
|
|
dd89bb |
int32_t __stdcall __ntapi_dsr_init(nt_daemon_params * params)
|
|
|
dd89bb |
{
|
|
|
dd89bb |
int32_t status;
|
|
|
dd89bb |
|
|
|
dd89bb |
nt_thread_params tparams;
|
|
|
dd89bb |
nt_large_integer timeout;
|
|
|
dd89bb |
|
|
|
6c2ba1 |
/* report status */
|
|
|
6c2ba1 |
at_store_32(
|
|
|
6c2ba1 |
¶ms->exit_code_daemon_loop,
|
|
|
6c2ba1 |
NT_STATUS_PENDING);
|
|
|
6c2ba1 |
|
|
|
6c2ba1 |
at_store_32(
|
|
|
6c2ba1 |
¶ms->exit_code_daemon_start,
|
|
|
6c2ba1 |
NT_STATUS_PENDING);
|
|
|
6c2ba1 |
|
|
|
6c2ba1 |
at_store_32(
|
|
|
6c2ba1 |
¶ms->exit_code_internal_client,
|
|
|
6c2ba1 |
NT_STATUS_PENDING);
|
|
|
6c2ba1 |
|
|
|
dd89bb |
/* port_keys */
|
|
|
dd89bb |
if (params->flags & NT_DSR_INIT_GENERATE_KEYS)
|
|
|
dd89bb |
if ((status = __ntapi->tt_port_generate_keys(params->port_keys)))
|
|
|
dd89bb |
return status;
|
|
|
dd89bb |
|
|
|
dd89bb |
/* port_name_keys */
|
|
|
dd89bb |
if (params->flags & NT_DSR_INIT_FORMAT_KEYS)
|
|
|
dd89bb |
__ntapi->tt_port_format_keys(
|
|
|
dd89bb |
params->port_keys,
|
|
|
dd89bb |
params->port_name_keys);
|
|
|
dd89bb |
|
|
|
dd89bb |
/* 'daemon-is-ready' event */
|
|
|
dd89bb |
if (!params->hevent_daemon_ready) {
|
|
|
dd89bb |
if ((status = __ntapi->tt_create_private_event(
|
|
|
dd89bb |
¶ms->hevent_daemon_ready,
|
|
|
dd89bb |
NT_NOTIFICATION_EVENT,
|
|
|
dd89bb |
NT_EVENT_NOT_SIGNALED)))
|
|
|
dd89bb |
return status;
|
|
|
dd89bb |
|
|
|
dd89bb |
if (params->pevent_daemon_ready)
|
|
|
dd89bb |
*(params->pevent_daemon_ready) = params->hevent_daemon_ready;
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
/* 'internal-client-is-ready' event */
|
|
|
dd89bb |
if (!params->hevent_internal_client_ready) {
|
|
|
dd89bb |
if ((status = __ntapi->tt_create_inheritable_event(
|
|
|
dd89bb |
¶ms->hevent_internal_client_ready,
|
|
|
dd89bb |
NT_NOTIFICATION_EVENT,
|
|
|
dd89bb |
NT_EVENT_NOT_SIGNALED)))
|
|
|
dd89bb |
return status;
|
|
|
dd89bb |
|
|
|
dd89bb |
if (params->pevent_internal_client_ready)
|
|
|
dd89bb |
*(params->pevent_internal_client_ready) = params->hevent_internal_client_ready;
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
/* daemon dedicated thread: general parameters */
|
|
|
dd89bb |
__ntapi->tt_aligned_block_memset(
|
|
|
dd89bb |
&tparams,0,sizeof(tparams));
|
|
|
dd89bb |
|
|
|
dd89bb |
tparams.start = (nt_thread_start_routine *)__ntapi_dsr_start;
|
|
|
dd89bb |
tparams.arg = params;
|
|
|
dd89bb |
|
|
|
dd89bb |
/* daemon dedicated thread: stack parameters (optional) */
|
|
|
dd89bb |
tparams.stack_size_commit = params->stack_size_commit;
|
|
|
dd89bb |
tparams.stack_size_reserve = params->stack_size_reserve;
|
|
|
dd89bb |
tparams.stack_info = params->stack_info;
|
|
|
dd89bb |
|
|
|
dd89bb |
/* daemon dedicated thread: create */
|
|
|
dd89bb |
status = __ntapi->tt_create_local_thread(&tparams);
|
|
|
dd89bb |
params->hthread_daemon_loop = tparams.hthread;
|
|
|
dd89bb |
if (status) return status;
|
|
|
dd89bb |
|
|
|
d34088 |
|
|
|
d34088 |
/* wait for the server to be ready */
|
|
|
d34088 |
timeout.quad = NT_DSR_INIT_MAX_WAIT;
|
|
|
d34088 |
|
|
|
d34088 |
if ((status = __ntapi->zw_wait_for_single_object(
|
|
|
d34088 |
params->hevent_daemon_ready,
|
|
|
d34088 |
0,&timeout))) {
|
|
|
d34088 |
__ntapi->zw_terminate_thread(
|
|
|
d34088 |
tparams.hthread,
|
|
|
d34088 |
status);
|
|
|
d34088 |
return status;
|
|
|
d34088 |
}
|
|
|
d34088 |
|
|
|
d34088 |
|
|
|
dd89bb |
/* daemon dedicated thread: actual stack size */
|
|
|
dd89bb |
params->stack_size_commit = tparams.stack_size_commit;
|
|
|
dd89bb |
params->stack_size_reserve = tparams.stack_size_reserve;
|
|
|
dd89bb |
|
|
|
dd89bb |
|
|
|
dd89bb |
/* establish internal connection */
|
|
|
dd89bb |
__ntapi->tt_aligned_block_memset(
|
|
|
dd89bb |
&tparams,0,sizeof(tparams));
|
|
|
dd89bb |
|
|
|
dd89bb |
tparams.start = (nt_thread_start_routine *)__ntapi_dsr_internal_client_connect;
|
|
|
dd89bb |
tparams.arg = params;
|
|
|
dd89bb |
|
|
|
dd89bb |
status = __ntapi->tt_create_local_thread(&tparams);
|
|
|
dd89bb |
params->hthread_internal_client = tparams.hthread;
|
|
|
dd89bb |
if (status) return status;
|
|
|
dd89bb |
|
|
|
dd89bb |
/* wait until the internal connection had been established */
|
|
|
dd89bb |
timeout.quad = NT_DSR_INIT_MAX_WAIT;
|
|
|
dd89bb |
|
|
|
dd89bb |
status = __ntapi->zw_wait_for_single_object(
|
|
|
dd89bb |
params->hevent_internal_client_ready,
|
|
|
dd89bb |
0,
|
|
|
dd89bb |
&timeout);
|
|
|
dd89bb |
|
|
|
dd89bb |
if (params->flags & NT_DSR_INIT_CLOSE_EVENTS) {
|
|
|
dd89bb |
__ntapi->zw_close(params->hevent_daemon_ready);
|
|
|
dd89bb |
__ntapi->zw_close(params->hevent_internal_client_ready);
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
return status;
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
|
|
|
dd89bb |
/* __ntapi_dsr_start executes in the daemon's dedicated thread */
|
|
|
6f3f3f |
int32_t __stdcall __ntapi_dsr_start_impl(nt_daemon_params * params)
|
|
|
dd89bb |
{
|
|
|
6f3f3f |
int32_t status;
|
|
|
6f3f3f |
|
|
|
6f3f3f |
if ((status = __ntapi_dsr_once(params)))
|
|
|
6f3f3f |
return status;
|
|
|
6f3f3f |
|
|
|
6f3f3f |
if ((status = __ntapi_dsr_create_port(params)))
|
|
|
6f3f3f |
return status;
|
|
|
6f3f3f |
|
|
|
6f3f3f |
if ((status = __ntapi_dsr_connect_internal_client(params)))
|
|
|
6f3f3f |
return status;
|
|
|
6f3f3f |
|
|
|
6f3f3f |
if ((status = params->daemon_loop_routine(params->daemon_loop_context)))
|
|
|
6f3f3f |
return status;
|
|
|
6f3f3f |
|
|
|
6f3f3f |
return NT_STATUS_SUCCESS;
|
|
|
6f3f3f |
}
|
|
|
dd89bb |
|
|
|
6f3f3f |
int32_t __stdcall __ntapi_dsr_start(nt_daemon_params * params)
|
|
|
6f3f3f |
{
|
|
|
6c2ba1 |
at_store_32(
|
|
|
6c2ba1 |
¶ms->exit_code_daemon_loop,
|
|
|
6c2ba1 |
NT_STATUS_MORE_PROCESSING_REQUIRED);
|
|
|
6c2ba1 |
|
|
|
6f3f3f |
return __ntapi->zw_terminate_thread(
|
|
|
6f3f3f |
NT_CURRENT_THREAD_HANDLE,
|
|
|
6f3f3f |
__ntapi_dsr_start_impl(params));
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
6f3f3f |
|
|
|
dd89bb |
/* __ntapi_dsr_once executes in the daemon's dedicated thread */
|
|
|
6f3f3f |
static int32_t __stdcall __ntapi_dsr_once(nt_daemon_params * params)
|
|
|
dd89bb |
{
|
|
|
dd89bb |
int32_t status;
|
|
|
dd89bb |
|
|
|
dd89bb |
if (!params->daemon_once_routine)
|
|
|
6f3f3f |
return NT_STATUS_SUCCESS;
|
|
|
dd89bb |
|
|
|
6f3f3f |
if ((status = params->daemon_once_routine(params->daemon_loop_context)))
|
|
|
6c2ba1 |
at_store_32(
|
|
|
6c2ba1 |
¶ms->exit_code_daemon_start,
|
|
|
6c2ba1 |
status);
|
|
|
6f3f3f |
|
|
|
6f3f3f |
return status;
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
/* __ntapi_dsr_create_port executes in the daemon's dedicated thread */
|
|
|
6c2ba1 |
static int32_t __stdcall __ntapi_dsr_create_port_exit(
|
|
|
6c2ba1 |
nt_daemon_params * params,
|
|
|
6c2ba1 |
int32_t status)
|
|
|
6c2ba1 |
{
|
|
|
6c2ba1 |
at_store_32(
|
|
|
6c2ba1 |
¶ms->exit_code_daemon_start,
|
|
|
6c2ba1 |
status);
|
|
|
6c2ba1 |
|
|
|
6c2ba1 |
return status;
|
|
|
6c2ba1 |
}
|
|
|
6c2ba1 |
|
|
|
dd89bb |
int32_t __stdcall __ntapi_dsr_create_port(nt_daemon_params * params)
|
|
|
dd89bb |
{
|
|
|
6c2ba1 |
int32_t status;
|
|
|
dd89bb |
nt_object_attributes oa;
|
|
|
dd89bb |
nt_security_quality_of_service sqos;
|
|
|
dd89bb |
nt_unicode_string server_name;
|
|
|
dd89bb |
|
|
|
dd89bb |
/* init server_name */
|
|
|
dd89bb |
server_name.strlen = (uint16_t)__ntapi->tt_string_null_offset_short((const int16_t *)params->port_name);
|
|
|
dd89bb |
server_name.maxlen = 0;
|
|
|
dd89bb |
server_name.buffer = (uint16_t *)params->port_name;
|
|
|
dd89bb |
|
|
|
dd89bb |
/* init security structure */
|
|
|
dd89bb |
sqos.length = sizeof(sqos);
|
|
|
dd89bb |
sqos.impersonation_level = NT_SECURITY_IMPERSONATION;
|
|
|
dd89bb |
sqos.context_tracking_mode = NT_SECURITY_TRACKING_DYNAMIC;
|
|
|
dd89bb |
sqos.effective_only = 1;
|
|
|
dd89bb |
|
|
|
dd89bb |
/* init the port's object attributes */
|
|
|
dd89bb |
oa.len = sizeof(oa);
|
|
|
dd89bb |
oa.root_dir = (void *)0;
|
|
|
dd89bb |
oa.obj_name = &server_name;
|
|
|
dd89bb |
oa.obj_attr = 0;
|
|
|
dd89bb |
oa.sec_desc = (nt_security_descriptor *)0;
|
|
|
dd89bb |
oa.sec_qos = &sqo;;
|
|
|
dd89bb |
|
|
|
dd89bb |
/* create the port */
|
|
|
6c2ba1 |
if ((status = __ntapi->zw_create_port(
|
|
|
6f3f3f |
¶ms->hport_daemon,
|
|
|
6f3f3f |
&oa,0,(uint32_t)params->port_msg_size,
|
|
|
6f3f3f |
0)))
|
|
|
6c2ba1 |
return __ntapi_dsr_create_port_exit(
|
|
|
6c2ba1 |
params,status);
|
|
|
dd89bb |
|
|
|
dd89bb |
/* return port info */
|
|
|
dd89bb |
if (params->pport_daemon)
|
|
|
6c2ba1 |
at_store(
|
|
|
6c2ba1 |
(intptr_t *)params->pport_daemon,
|
|
|
6c2ba1 |
(intptr_t)params->hport_daemon);
|
|
|
dd89bb |
|
|
|
dd89bb |
/* signal the daemon-is-ready event */
|
|
|
6c2ba1 |
status = __ntapi->zw_set_event(
|
|
|
dd89bb |
params->hevent_daemon_ready,
|
|
|
dd89bb |
(int32_t *)0);
|
|
|
dd89bb |
|
|
|
6c2ba1 |
return __ntapi_dsr_create_port_exit(
|
|
|
6c2ba1 |
params,status);
|
|
|
dd89bb |
}
|