Blame src/daemon/ntapi_dsr_internal_connection.c

dd89bb
/********************************************************/
dd89bb
/*  ntapi: Native API core library                      */
dde53a
/*  Copyright (C) 2013--2017  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
cd4191
int32_t __ntapi_tt_seh_frame(void *, void *, void *, int32_t (*)(nt_daemon_params *));
cd4191
ad58de
static int32_t __ntapi_dsr_internal_client_connect_exit(
6c2ba1
	nt_daemon_params *	params,
6c2ba1
	int32_t			status)
6c2ba1
{
6c2ba1
	at_store_32(
6c2ba1
		&params->exit_code_internal_client,
6c2ba1
		status);
6c2ba1
6c2ba1
	return __ntapi->zw_terminate_thread(
6c2ba1
		NT_CURRENT_THREAD_HANDLE,
6c2ba1
		status);
6c2ba1
}
6c2ba1
dd89bb
/* __ntapi_dsr_internal_client_connect executes in its own temporary thread */
cd4191
static int32_t __ntapi_dsr_internal_client_connect_impl(nt_daemon_params * params)
dd89bb
{
6c2ba1
	int32_t				status;
dd89bb
	nt_unicode_string		server_name;
dd89bb
	nt_object_attributes		oa;
dd89bb
	nt_security_quality_of_service	sqos;
dd89bb
dd89bb
	/* init server_name */
ad58de
	server_name.strlen = (uint16_t)__ntapi->tt_string_null_offset_short((int16_t *)params->port_name);
dd89bb
	server_name.maxlen = 0;
ad58de
	server_name.buffer = 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);
ad58de
	oa.root_dir	= 0;
dd89bb
	oa.obj_name	= &server_name;
dd89bb
	oa.obj_attr	= 0;
ad58de
	oa.sec_desc	= params->port_sd;
dd89bb
	oa.sec_qos	= &sqo;;
dd89bb
dd89bb
	/* establish internal connection */
6c2ba1
	if ((status = __ntapi->zw_connect_port(
6c2ba1
			&params->hport_internal_client,
6c2ba1
			&server_name,
6c2ba1
			&sqos,
6c2ba1
			0,0,0,0,0)))
ad58de
		return __ntapi_dsr_internal_client_connect_exit(
6c2ba1
			params,status);
dd89bb
a5dc9f
	/* update port info */
dd89bb
	if (params->pport_internal_client)
a5dc9f
		at_store(
a5dc9f
			(intptr_t *)params->pport_internal_client,
a5dc9f
			(intptr_t)params->hport_internal_client);
a5dc9f
dd89bb
	/* signal the 'internal-client-is-ready' event */
6c2ba1
	status = __ntapi->zw_set_event(
dd89bb
		params->hevent_internal_client_ready,
dd89bb
		0);
dd89bb
dd89bb
	/* exit the task-specific thread */
ad58de
	return __ntapi_dsr_internal_client_connect_exit(
ad58de
		params,status);
dd89bb
}
cd4191
ad58de
int32_t __ntapi_dsr_internal_client_connect(nt_daemon_params * params)
cd4191
{
cd4191
	return __ntapi_tt_seh_frame(
cd4191
		params,0,0,
cd4191
		__ntapi_dsr_internal_client_connect_impl);
392ff9
}
ad58de
ad58de
/* __ntapi_dsr_connect_internal_client executes in the daemon's dedicated thread */
ad58de
int32_t __ntapi_dsr_connect_internal_client(nt_daemon_params * params)
ad58de
{
ad58de
	int32_t			status;
ad58de
	intptr_t		port_id;
ad58de
	nt_port_message		port_msg;
ad58de
	void *			hport;
ad58de
ad58de
	/* first connection */
ad58de
	if ((status = __ntapi->zw_reply_wait_receive_port(
ad58de
			params->hport_daemon,
ad58de
			&port_id,0,&port_msg)))
ad58de
		return status;
ad58de
ad58de
	/* the internal client must be first */
ad58de
	if (port_msg.client_id.process_id != pe_get_current_process_id())
ad58de
		return NT_STATUS_PORT_CONNECTION_REFUSED;
ad58de
ad58de
	/* accept connection request */
ad58de
	if ((status = __ntapi->zw_accept_connect_port(
ad58de
			&hport,
ad58de
			port_msg.client_id.process_id,
ad58de
			(nt_port_message *)&port_msg,
ad58de
			NT_LPC_ACCEPT_CONNECTION,
ad58de
			(nt_port_section_write *)0,
ad58de
			(nt_port_section_read *)0)))
ad58de
		return status;
ad58de
ad58de
	/* finalize connection */
ad58de
	if ((status = __ntapi->zw_complete_connect_port(hport)))
ad58de
		return status;
ad58de
ad58de
	/* all done */
ad58de
	return NT_STATUS_SUCCESS;
ad58de
}