Blame src/daemon/ntapi_dsr_internal_connection.c

dd89bb
/********************************************************/
dd89bb
/*  ntapi: Native API core library                      */
dd89bb
/*  Copyright (C) 2013,2014,2015  Z. Gilboa             */
dd89bb
/*  Released under GPLv2 and GPLv3; see COPYING.NTAPI.  */
dd89bb
/********************************************************/
dd89bb
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
dd89bb
/* __ntapi_dsr_connect_internal_client executes in the daemon's dedicated thread */
dd89bb
int32_t __stdcall __ntapi_dsr_connect_internal_client(nt_daemon_params * params)
dd89bb
{
dd89bb
	int32_t *		pstatus;
dd89bb
dd89bb
	intptr_t		port_id;
dd89bb
	nt_port_message		port_msg;
dd89bb
	nt_large_integer	timeout;
dd89bb
	void *			_hport_client;
dd89bb
dd89bb
	pstatus = &params->exit_code_daemon_start;
dd89bb
dd89bb
	/* timeout-enabled first connection */
dd89bb
	timeout.quad = NT_DSR_INIT_MAX_WAIT;
dd89bb
dd89bb
	*pstatus = __ntapi->zw_reply_wait_receive_port_ex(
dd89bb
		params->hport_daemon,
dd89bb
		&port_id,
dd89bb
		(nt_port_message *)0,
dd89bb
		(nt_port_message *)&port_msg,
dd89bb
		&timeout);
dd89bb
dd89bb
	if (*pstatus != NT_STATUS_SUCCESS)
dd89bb
		__ntapi->zw_terminate_thread(
dd89bb
			NT_CURRENT_THREAD_HANDLE,
dd89bb
			*pstatus);
dd89bb
dd89bb
	/* the internal client must be first */
dd89bb
	if (port_msg.client_id.process_id != pe_get_current_process_id())
dd89bb
		__ntapi->zw_terminate_thread(
dd89bb
			NT_CURRENT_THREAD_HANDLE,
dd89bb
			NT_STATUS_PORT_CONNECTION_REFUSED);
dd89bb
dd89bb
	/* accept connection request */
dd89bb
	*pstatus = __ntapi->zw_accept_connect_port(
dd89bb
		&_hport_client,
dd89bb
		port_msg.client_id.process_id,
dd89bb
		(nt_port_message *)&port_msg,
dd89bb
		NT_LPC_ACCEPT_CONNECTION,
dd89bb
		(nt_port_section_write *)0,
dd89bb
		(nt_port_section_read *)0);
dd89bb
dd89bb
	if (*pstatus != NT_STATUS_SUCCESS)
dd89bb
		__ntapi->zw_terminate_thread(
dd89bb
			NT_CURRENT_THREAD_HANDLE,
dd89bb
			*pstatus);
dd89bb
dd89bb
	/* finalize connection */
dd89bb
	*pstatus = __ntapi->zw_complete_connect_port(_hport_client);
dd89bb
dd89bb
	if (*pstatus != NT_STATUS_SUCCESS)
dd89bb
		__ntapi->zw_terminate_thread(
dd89bb
			NT_CURRENT_THREAD_HANDLE,
dd89bb
			*pstatus);
dd89bb
dd89bb
	return *pstatus;
dd89bb
}
dd89bb
dd89bb
dd89bb
/* __ntapi_dsr_internal_client_connect executes in its own temporary thread */
dd89bb
int32_t __stdcall __ntapi_dsr_internal_client_connect(nt_daemon_params * params)
dd89bb
{
dd89bb
	int32_t *			pstatus;
dd89bb
dd89bb
	nt_unicode_string		server_name;
dd89bb
	nt_object_attributes		oa;
dd89bb
	nt_security_quality_of_service	sqos;
dd89bb
	nt_large_integer		timeout;
dd89bb
dd89bb
	pstatus = &params->exit_code_internal_client;
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
	/* wait for the server to be ready */
dd89bb
	timeout.quad = NT_DSR_INIT_MAX_WAIT;
dd89bb
dd89bb
	if ((*pstatus = __ntapi->zw_wait_for_single_object(
dd89bb
			params->hevent_daemon_ready,
dd89bb
			0,&timeout)))
dd89bb
		__ntapi->zw_terminate_thread(
dd89bb
			NT_CURRENT_THREAD_HANDLE,
dd89bb
			*pstatus);
dd89bb
dd89bb
	/* establish internal connection */
dd89bb
	*pstatus = __ntapi->zw_connect_port(
dd89bb
		&params->hport_internal_client,
dd89bb
		&server_name,
dd89bb
		&sqos,
dd89bb
		0,0,0,0,0);
dd89bb
dd89bb
	if (*pstatus != NT_STATUS_SUCCESS)
dd89bb
		__ntapi->zw_terminate_thread(
dd89bb
			NT_CURRENT_THREAD_HANDLE,
dd89bb
			*pstatus);
dd89bb
dd89bb
	/* return port info */
dd89bb
	if (params->pport_internal_client)
dd89bb
		*(params->pport_internal_client) = params->hport_internal_client;
dd89bb
dd89bb
	/* signal the 'internal-client-is-ready' event */
dd89bb
	*pstatus = __ntapi->zw_set_event(
dd89bb
		params->hevent_internal_client_ready,
dd89bb
		0);
dd89bb
dd89bb
	/* exit the task-specific thread */
dd89bb
	__ntapi->zw_terminate_thread(
dd89bb
		NT_CURRENT_THREAD_HANDLE,
dd89bb
		*pstatus);
dd89bb
dd89bb
	/* (no return) */
dd89bb
	return NT_STATUS_INTERNAL_ERROR;
dd89bb
}