From ad58de287d1c25c8bc143803b978c4bc5b0955f2 Mon Sep 17 00:00:00 2001 From: midipix Date: Sun, 13 May 2018 12:13:30 +0000 Subject: daemon initialization: revised for optimized thread synchronization. --- include/ntapi/nt_daemon.h | 6 +- include/ntapi/ntapi.h | 3 - src/daemon/ntapi_dsr_init.c | 95 ++++++++++++++++-------- src/daemon/ntapi_dsr_internal_connection.c | 115 +++++++++++------------------ src/internal/ntapi.c | 3 - src/internal/ntapi_fnapi.h | 3 - src/internal/ntapi_impl.h | 5 ++ 7 files changed, 115 insertions(+), 115 deletions(-) diff --git a/include/ntapi/nt_daemon.h b/include/ntapi/nt_daemon.h index 0b44e86..04688d4 100644 --- a/include/ntapi/nt_daemon.h +++ b/include/ntapi/nt_daemon.h @@ -63,11 +63,12 @@ typedef struct _nt_daemon_params { void ** pport_daemon; void * hport_internal_client; void ** pport_internal_client; + void * hevent_daemon_port; + void ** pevent_daemon_port; void * hevent_daemon_ready; void ** pevent_daemon_ready; void * hevent_internal_client_ready; void ** pevent_internal_client_ready; - void * hthread_daemon_start; void * hthread_daemon_loop; void * hthread_internal_client; int32_t exit_code_daemon_start; @@ -81,10 +82,7 @@ typedef struct _nt_daemon_params { typedef int32_t __stdcall ntapi_dsr_init(nt_daemon_params *); -typedef int32_t __stdcall ntapi_dsr_start(nt_daemon_params *); typedef int32_t __stdcall ntapi_dsr_create_port(nt_daemon_params *); -typedef int32_t __stdcall ntapi_dsr_connect_internal_client(nt_daemon_params *); -typedef int32_t __stdcall ntapi_dsr_internal_client_connect(nt_daemon_params *); typedef int32_t __stdcall ntapi_dsr_loop(void *); #endif diff --git a/include/ntapi/ntapi.h b/include/ntapi/ntapi.h index a045a9f..c04d10a 100644 --- a/include/ntapi/ntapi.h +++ b/include/ntapi/ntapi.h @@ -567,10 +567,7 @@ typedef struct _ntapi_vtbl { /* nt_daemon.h */ ntapi_dsr_init * dsr_init; - ntapi_dsr_start * dsr_start; ntapi_dsr_create_port * dsr_create_port; - ntapi_dsr_connect_internal_client * dsr_connect_internal_client; - ntapi_dsr_internal_client_connect * dsr_internal_client_connect; /* nt_acl.h */ ntapi_acl_init_common_descriptor * acl_init_common_descriptor; diff --git a/src/daemon/ntapi_dsr_init.c b/src/daemon/ntapi_dsr_init.c index 8f29eec..afade50 100644 --- a/src/daemon/ntapi_dsr_init.c +++ b/src/daemon/ntapi_dsr_init.c @@ -19,9 +19,7 @@ static int32_t __stdcall __ntapi_dsr_once(nt_daemon_params * params); int32_t __stdcall __ntapi_dsr_init(nt_daemon_params * params) { int32_t status; - nt_thread_params tparams; - nt_large_integer timeout; /* report status */ at_store_32( @@ -36,6 +34,9 @@ int32_t __stdcall __ntapi_dsr_init(nt_daemon_params * params) ¶ms->exit_code_internal_client, NT_STATUS_PENDING); + at_locked_or((intptr_t *)params->port_name,0); + at_locked_or((intptr_t *)¶ms->port_name,0); + /* port_keys */ if (params->flags & NT_DSR_INIT_GENERATE_KEYS) if ((status = __ntapi->tt_port_generate_keys(params->port_keys))) @@ -47,6 +48,20 @@ int32_t __stdcall __ntapi_dsr_init(nt_daemon_params * params) params->port_keys, params->port_name_keys); + /* 'port-created' event */ + if (!params->hevent_daemon_port) { + if ((status = __ntapi->tt_create_private_event( + ¶ms->hevent_daemon_port, + NT_NOTIFICATION_EVENT, + NT_EVENT_NOT_SIGNALED))) + return status; + + if (params->pevent_daemon_port) + at_store( + (intptr_t *)params->pevent_daemon_port, + (intptr_t)params->hevent_daemon_port); + } + /* 'daemon-is-ready' event */ if (!params->hevent_daemon_ready) { if ((status = __ntapi->tt_create_private_event( @@ -91,27 +106,25 @@ int32_t __stdcall __ntapi_dsr_init(nt_daemon_params * params) if ((status = __ntapi->tt_create_local_thread(&tparams))) return status; - params->hthread_daemon_loop = tparams.hthread; - - /* wait for the server to be ready */ - timeout.quad = NT_DSR_INIT_MAX_WAIT; - - if ((status = __ntapi->zw_wait_for_single_object( - params->hevent_daemon_ready, - NT_SYNC_NON_ALERTABLE,&timeout))) { - __ntapi->zw_terminate_thread( - tparams.hthread, - status); - return status; - } - + at_store( + (intptr_t *)¶ms->hthread_daemon_loop, + (intptr_t)tparams.hthread); /* daemon dedicated thread: actual stack size */ params->stack_size_commit = tparams.stack_size_commit; params->stack_size_reserve = tparams.stack_size_reserve; + /* wait for the port to be created */ + if ((status = __ntapi->zw_wait_for_single_object( + params->hevent_daemon_port, + NT_SYNC_NON_ALERTABLE,0))) + return status; + + /* verify the port's successful creation */ + if (params->exit_code_daemon_start) + return NT_STATUS_PORT_NOT_SET; - /* establish internal connection */ + /* internal connection task-specific thread */ __ntapi->tt_aligned_block_memset( &tparams,0,sizeof(tparams)); @@ -121,17 +134,27 @@ int32_t __stdcall __ntapi_dsr_init(nt_daemon_params * params) if ((status = __ntapi->tt_create_local_thread(&tparams))) return status; - params->hthread_internal_client = tparams.hthread; - - /* wait until the internal connection had been established */ - timeout.quad = NT_DSR_INIT_MAX_WAIT; + at_store( + (intptr_t *)¶ms->hthread_internal_client, + (intptr_t)tparams.hthread); + /* wait for the task-specific thread to exit */ if ((status = __ntapi->zw_wait_for_single_object( - params->hevent_internal_client_ready, - NT_SYNC_NON_ALERTABLE,&timeout))) + params->hthread_internal_client, + NT_SYNC_NON_ALERTABLE,0))) return status; + /* verify a successful internal connection */ + if (params->exit_code_internal_client) + return params->exit_code_internal_client; + + /* all_done */ + __ntapi->zw_set_event( + params->hevent_daemon_ready, + 0); + if (params->flags & NT_DSR_INIT_CLOSE_EVENTS) { + __ntapi->zw_close(params->hevent_daemon_port); __ntapi->zw_close(params->hevent_daemon_ready); __ntapi->zw_close(params->hevent_internal_client_ready); } @@ -208,6 +231,10 @@ static int32_t __stdcall __ntapi_dsr_create_port_exit( ¶ms->exit_code_daemon_start, status); + __ntapi->zw_set_event( + params->hevent_daemon_port, + 0); + return status; } @@ -219,9 +246,9 @@ int32_t __stdcall __ntapi_dsr_create_port(nt_daemon_params * params) nt_unicode_string server_name; /* init server_name */ - server_name.strlen = (uint16_t)__ntapi->tt_string_null_offset_short((const int16_t *)params->port_name); + server_name.strlen = (uint16_t)__ntapi->tt_string_null_offset_short((int16_t *)params->port_name); server_name.maxlen = 0; - server_name.buffer = (uint16_t *)params->port_name; + server_name.buffer = params->port_name; /* init security structure */ sqos.length = sizeof(sqos); @@ -231,7 +258,7 @@ int32_t __stdcall __ntapi_dsr_create_port(nt_daemon_params * params) /* init the port's object attributes */ oa.len = sizeof(oa); - oa.root_dir = (void *)0; + oa.root_dir = 0; oa.obj_name = &server_name; oa.obj_attr = 0; oa.sec_desc = params->port_sd; @@ -251,11 +278,15 @@ int32_t __stdcall __ntapi_dsr_create_port(nt_daemon_params * params) (intptr_t *)params->pport_daemon, (intptr_t)params->hport_daemon); - /* signal the daemon-is-ready event */ - status = __ntapi->zw_set_event( - params->hevent_daemon_ready, - (int32_t *)0); + /* set status */ + at_store_32( + ¶ms->exit_code_daemon_start, + NT_STATUS_SUCCESS); + + /* signal the port-created event */ + __ntapi->zw_set_event( + params->hevent_daemon_port, + 0); - return __ntapi_dsr_create_port_exit( - params,status); + return NT_STATUS_SUCCESS; } diff --git a/src/daemon/ntapi_dsr_internal_connection.c b/src/daemon/ntapi_dsr_internal_connection.c index fecc027..6e77d00 100644 --- a/src/daemon/ntapi_dsr_internal_connection.c +++ b/src/daemon/ntapi_dsr_internal_connection.c @@ -14,7 +14,7 @@ int32_t __ntapi_tt_seh_frame(void *, void *, void *, int32_t (*)(nt_daemon_params *)); -static int32_t __stdcall __ntapi_dsr_internal_client_connect_fail( +static int32_t __ntapi_dsr_internal_client_connect_exit( nt_daemon_params * params, int32_t status) { @@ -27,56 +27,6 @@ static int32_t __stdcall __ntapi_dsr_internal_client_connect_fail( status); } -/* __ntapi_dsr_connect_internal_client executes in the daemon's dedicated thread */ -int32_t __stdcall __ntapi_dsr_connect_internal_client(nt_daemon_params * params) -{ - int32_t status; - intptr_t port_id; - nt_port_message port_msg; - void * hport; - void * hready; - - /* avoid out-of-scope use */ - hready = params->hthread_internal_client; - - /* report state */ - at_store_32( - ¶ms->exit_code_daemon_start, - NT_STATUS_MORE_PROCESSING_REQUIRED); - - /* first connection */ - if ((status = __ntapi->zw_reply_wait_receive_port( - params->hport_daemon, - &port_id,0,&port_msg))) - return status; - - /* the internal client must be first */ - if (port_msg.client_id.process_id != pe_get_current_process_id()) - return NT_STATUS_PORT_CONNECTION_REFUSED; - - /* accept connection request */ - if ((status = __ntapi->zw_accept_connect_port( - &hport, - port_msg.client_id.process_id, - (nt_port_message *)&port_msg, - NT_LPC_ACCEPT_CONNECTION, - (nt_port_section_write *)0, - (nt_port_section_read *)0))) - return status; - - /* finalize connection */ - if ((status = __ntapi->zw_complete_connect_port(hport))) - return status; - - /* await client thread task completion */ - __ntapi->zw_wait_for_single_object( - hready,NT_SYNC_NON_ALERTABLE,0); - - /* all done */ - return NT_STATUS_SUCCESS; -} - - /* __ntapi_dsr_internal_client_connect executes in its own temporary thread */ static int32_t __ntapi_dsr_internal_client_connect_impl(nt_daemon_params * params) { @@ -85,15 +35,10 @@ static int32_t __ntapi_dsr_internal_client_connect_impl(nt_daemon_params * param nt_object_attributes oa; nt_security_quality_of_service sqos; - /* report status */ - at_store_32( - ¶ms->exit_code_internal_client, - NT_STATUS_MORE_PROCESSING_REQUIRED); - /* init server_name */ - server_name.strlen = (uint16_t)__ntapi->tt_string_null_offset_short((const int16_t *)params->port_name); + server_name.strlen = (uint16_t)__ntapi->tt_string_null_offset_short((int16_t *)params->port_name); server_name.maxlen = 0; - server_name.buffer = (uint16_t *)params->port_name; + server_name.buffer = params->port_name; /* init security structure */ sqos.length = sizeof(sqos); @@ -103,10 +48,10 @@ static int32_t __ntapi_dsr_internal_client_connect_impl(nt_daemon_params * param /* init the port's object attributes */ oa.len = sizeof(oa); - oa.root_dir = (void *)0; + oa.root_dir = 0; oa.obj_name = &server_name; oa.obj_attr = 0; - oa.sec_desc = (nt_security_descriptor *)0; + oa.sec_desc = params->port_sd; oa.sec_qos = &sqos; /* establish internal connection */ @@ -115,7 +60,7 @@ static int32_t __ntapi_dsr_internal_client_connect_impl(nt_daemon_params * param &server_name, &sqos, 0,0,0,0,0))) - return __ntapi_dsr_internal_client_connect_fail( + return __ntapi_dsr_internal_client_connect_exit( params,status); /* update port info */ @@ -124,25 +69,55 @@ static int32_t __ntapi_dsr_internal_client_connect_impl(nt_daemon_params * param (intptr_t *)params->pport_internal_client, (intptr_t)params->hport_internal_client); - /* report status */ - at_store_32( - ¶ms->exit_code_internal_client, - status); - /* signal the 'internal-client-is-ready' event */ status = __ntapi->zw_set_event( params->hevent_internal_client_ready, 0); /* exit the task-specific thread */ - return __ntapi->zw_terminate_thread( - NT_CURRENT_THREAD_HANDLE, - status); + return __ntapi_dsr_internal_client_connect_exit( + params,status); } -int32_t __stdcall __ntapi_dsr_internal_client_connect(nt_daemon_params * params) +int32_t __ntapi_dsr_internal_client_connect(nt_daemon_params * params) { return __ntapi_tt_seh_frame( params,0,0, __ntapi_dsr_internal_client_connect_impl); } + +/* __ntapi_dsr_connect_internal_client executes in the daemon's dedicated thread */ +int32_t __ntapi_dsr_connect_internal_client(nt_daemon_params * params) +{ + int32_t status; + intptr_t port_id; + nt_port_message port_msg; + void * hport; + + /* first connection */ + if ((status = __ntapi->zw_reply_wait_receive_port( + params->hport_daemon, + &port_id,0,&port_msg))) + return status; + + /* the internal client must be first */ + if (port_msg.client_id.process_id != pe_get_current_process_id()) + return NT_STATUS_PORT_CONNECTION_REFUSED; + + /* accept connection request */ + if ((status = __ntapi->zw_accept_connect_port( + &hport, + port_msg.client_id.process_id, + (nt_port_message *)&port_msg, + NT_LPC_ACCEPT_CONNECTION, + (nt_port_section_write *)0, + (nt_port_section_read *)0))) + return status; + + /* finalize connection */ + if ((status = __ntapi->zw_complete_connect_port(hport))) + return status; + + /* all done */ + return NT_STATUS_SUCCESS; +} diff --git a/src/internal/ntapi.c b/src/internal/ntapi.c index c493087..9361338 100644 --- a/src/internal/ntapi.c +++ b/src/internal/ntapi.c @@ -362,10 +362,7 @@ static int32_t __fastcall __ntapi_init_once(ntapi_vtbl ** pvtbl) /* nt_daemon.h */ __ntapi->dsr_init = __ntapi_dsr_init; - __ntapi->dsr_start = __ntapi_dsr_start; __ntapi->dsr_create_port = __ntapi_dsr_create_port; - __ntapi->dsr_connect_internal_client = __ntapi_dsr_connect_internal_client; - __ntapi->dsr_internal_client_connect = __ntapi_dsr_internal_client_connect; /* nt_acl.h */ __ntapi->acl_init_common_descriptor = __ntapi_acl_init_common_descriptor; diff --git a/src/internal/ntapi_fnapi.h b/src/internal/ntapi_fnapi.h index da71a81..7c744c9 100644 --- a/src/internal/ntapi_fnapi.h +++ b/src/internal/ntapi_fnapi.h @@ -228,10 +228,7 @@ ntapi_uc_convert_unicode_stream_utf16_to_utf32 __ntapi_uc_convert_unicode_stream /* nt_daemon.h */ ntapi_dsr_init __ntapi_dsr_init; -ntapi_dsr_start __ntapi_dsr_start; ntapi_dsr_create_port __ntapi_dsr_create_port; -ntapi_dsr_connect_internal_client __ntapi_dsr_connect_internal_client; -ntapi_dsr_internal_client_connect __ntapi_dsr_internal_client_connect; /* nt_acl.h */ ntapi_acl_init_common_descriptor __ntapi_acl_init_common_descriptor; diff --git a/src/internal/ntapi_impl.h b/src/internal/ntapi_impl.h index d020386..18845a5 100644 --- a/src/internal/ntapi_impl.h +++ b/src/internal/ntapi_impl.h @@ -144,6 +144,11 @@ ntapi_internals * __cdecl __ntapi_internals(void); int32_t __ntapi_tt_open_file_utf8(void ** hfile, void * hat, const char * arg, int fprivate, wchar16_t *, uint32_t); int32_t __ntapi_tt_open_dir_utf8(void ** hfile, void * hat, const char * arg, int fprivate, wchar16_t *, uint32_t); +/* daemon internals */ +int32_t __ntapi_dsr_start(nt_daemon_params *); +int32_t __ntapi_dsr_connect_internal_client(nt_daemon_params *); +int32_t __ntapi_dsr_internal_client_connect(nt_daemon_params *); + /* ipc internals */ int __ntapi_ipc_page_alloc(struct dalist_ex * dlist, void ** addr, size_t * alloc_size); -- cgit v1.2.3