Blame src/port/ntapi_port_name_helper.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
dd89bb
#include <psxtypes/psxtypes.h>
dd89bb
#include <ntapi/nt_guid.h>
dd89bb
#include <ntapi/nt_port.h>
dd89bb
#include <ntapi/nt_string.h>
dd89bb
#include "ntapi_impl.h"
dd89bb
dd89bb
typedef wchar16_t __port_service_prefix[6];
dd89bb
dd89bb
static const __port_service_prefix	__port_service_null = {0};
e3982b
static const __port_service_prefix	__port_service_prefixes[NT_PORT_TYPE_CAP][NT_PORT_SUBTYPE_CAP] = {
e3982b
					{{'s','v','c','a','n','y'}},
e3982b
					{{'n','t','c','t','t','y'}},
e3982b
					{{'v','m','o','u','n','t'}},
e3982b
					{{'d','a','e','m','o','n'}},
e3982b
					{{'s','y','m','l','n','k'}},
4a2e49
					{{'n','t','p','r','o','c'}},
4a2e49
					{{'s','e','m','c','t','l'}},
4a2e49
					{{'s','e','m','s','v','c'}}};
dd89bb
dd89bb
static const nt_guid		__port_guids[NT_PORT_TYPE_CAP][NT_PORT_SUBTYPE_CAP] = {
dd89bb
					{NT_PORT_GUID_DEFAULT},
dd89bb
					{NT_PORT_GUID_SUBSYSTEM},
dd89bb
					{NT_PORT_GUID_VMOUNT},
41d417
					{NT_PORT_GUID_DAEMON},
41d417
					{NT_PORT_GUID_SYMLNK},
4a2e49
					{NT_PORT_GUID_NTPROC},
4a2e49
					{NT_PORT_GUID_SEMCTL},
4a2e49
					{NT_PORT_GUID_SEMSVC}};
dd89bb
dd89bb
int32_t __stdcall __ntapi_tt_port_guid_from_type(
dd89bb
	__out	nt_guid *		guid,
dd89bb
	__in	nt_port_type		type,
dd89bb
	__in	nt_port_subtype		subtype)
dd89bb
{
dd89bb
	const nt_guid *	src_guid;
dd89bb
dd89bb
	if ((type >= NT_PORT_TYPE_CAP) || (subtype >= NT_PORT_SUBTYPE_CAP))
dd89bb
		return NT_STATUS_INVALID_PARAMETER;
dd89bb
dd89bb
	src_guid = &(__port_guids[type][subtype]);
dd89bb
dd89bb
	__ntapi->tt_aligned_block_memcpy(
dd89bb
		(uintptr_t *)guid,
dd89bb
		(uintptr_t *)src_guid,
dd89bb
		sizeof(nt_guid));
dd89bb
dd89bb
	return NT_STATUS_SUCCESS;
dd89bb
}
dd89bb
dd89bb
dd89bb
int32_t __stdcall __ntapi_tt_port_type_from_guid(
dd89bb
	__out	nt_port_type *		type,
dd89bb
	__out	nt_port_subtype *	subtype,
ae515f
	__in	const nt_guid *		guid)
dd89bb
{
dd89bb
	int		itype;
dd89bb
	int		isubtype;
dd89bb
dd89bb
	for (itype=0; itype
dd89bb
		for (isubtype=0; isubtype
cb3f2e
			if (!(__ntapi_tt_guid_compare(
cb3f2e
					&__port_guids[itype][isubtype],
cb3f2e
					guid))) {
dd89bb
				*type	 = (nt_port_type)itype;
dd89bb
				*subtype = (nt_port_subtype)isubtype;
dd89bb
dd89bb
				return NT_STATUS_SUCCESS;
dd89bb
			}
dd89bb
		}
dd89bb
	}
dd89bb
cb3f2e
	return NT_STATUS_NOT_FOUND;
dd89bb
}
dd89bb
dd89bb
dd89bb
int32_t __stdcall __ntapi_tt_port_generate_keys(
dd89bb
	__out	nt_port_keys *		keys)
dd89bb
{
dd89bb
	int32_t			status;
5b9ff6
	nt_large_integer	ticks;
5b9ff6
	nt_large_integer	pcfreq;
dd89bb
	nt_luid			luid;
dd89bb
5b9ff6
	if ((status = __ntapi->zw_query_performance_counter(&ticks,&pcfreq)))
273d64
		return status;
dd89bb
273d64
	if ((status = __ntapi->zw_allocate_locally_unique_id(&luid)))
273d64
		return status;
dd89bb
dd89bb
	keys->key[0] = pe_get_current_process_id();
dd89bb
	keys->key[1] = pe_get_current_thread_id();
5b9ff6
	keys->key[2] = ticks.ihigh;
5b9ff6
	keys->key[3] = ticks.ulow;
dd89bb
	keys->key[4] = luid.high;
dd89bb
	keys->key[5] = luid.low;
dd89bb
dd89bb
	return NT_STATUS_SUCCESS;
dd89bb
}
dd89bb
dd89bb
dd89bb
void __stdcall	__ntapi_tt_port_format_keys(
dd89bb
	__in	nt_port_keys *		keys,
dd89bb
	__out	nt_port_name_keys *	name_keys)
dd89bb
{
dd89bb
	__ntapi->tt_uint32_to_hex_utf16(keys->key[0],name_keys->key_1st);
dd89bb
	__ntapi->tt_uint32_to_hex_utf16(keys->key[1],name_keys->key_2nd);
dd89bb
	__ntapi->tt_uint32_to_hex_utf16(keys->key[2],name_keys->key_3rd);
dd89bb
	__ntapi->tt_uint32_to_hex_utf16(keys->key[3],name_keys->key_4th);
dd89bb
	__ntapi->tt_uint32_to_hex_utf16(keys->key[4],name_keys->key_5th);
dd89bb
	__ntapi->tt_uint32_to_hex_utf16(keys->key[5],name_keys->key_6th);
dd89bb
dd89bb
	return;
dd89bb
}
dd89bb
dd89bb
6d5726
void __stdcall __ntapi_tt_port_name_from_attr(
dd89bb
	__out	nt_port_name *		name,
dd89bb
	__in	nt_port_attr *		attr)
dd89bb
{
dd89bb
	wchar16_t bno[] = __NT_BASED_NAMED_OBJECTS;
dd89bb
dd89bb
	/* base named objects */
dd89bb
	__ntapi->tt_memcpy_utf16(
dd89bb
		name->base_named_objects,
dd89bb
		bno,sizeof(bno));
dd89bb
dd89bb
	/* service prefix */
dd89bb
	if (attr && (attr->type < NT_PORT_TYPE_CAP) && (attr->subtype < NT_PORT_SUBTYPE_CAP))
dd89bb
		__ntapi->tt_memcpy_utf16(
dd89bb
			name->svc_prefix,
e3982b
			__port_service_prefixes[attr->type][attr->subtype],
dd89bb
			sizeof(name->svc_prefix));
dd89bb
	else
dd89bb
		__ntapi->tt_memcpy_utf16(
dd89bb
			name->svc_prefix,
dd89bb
			__port_service_null,
dd89bb
			sizeof(name->svc_prefix));
dd89bb
dd89bb
	/* port guid */
701eb2
	__ntapi->tt_guid_to_string_utf16(
dd89bb
		&attr->guid,
dd89bb
		(nt_guid_str_utf16 *)&name->port_guid);
dd89bb
dd89bb
	/* port name keys */
dd89bb
	__ntapi_tt_port_format_keys(
dd89bb
		&attr->keys,
dd89bb
		&name->port_name_keys);
dd89bb
dd89bb
	/* backslash and underscores */
dd89bb
	name->backslash = '\\';
dd89bb
	name->port_guid.uscore_guid = '_';
dd89bb
	name->port_guid.uscore_keys = '_';
dd89bb
	name->port_name_keys.uscore_1st  = '_';
dd89bb
	name->port_name_keys.uscore_2nd  = '_';
dd89bb
	name->port_name_keys.uscore_3rd  = '_';
dd89bb
	name->port_name_keys.uscore_4th  = '_';
dd89bb
	name->port_name_keys.uscore_5th  = '_';
dd89bb
dd89bb
	/* null termination */
dd89bb
	name->null_termination = 0;
dd89bb
dd89bb
	return;
dd89bb
}
d9d178
d9d178
d9d178
static int32_t __tt_port_attr_from_name(
d9d178
	__out	nt_port_attr *		attr,
d9d178
	__in	const nt_port_name *	name)
d9d178
{
d9d178
	int		i;
d9d178
	int		type;
d9d178
	int32_t		status;
d9d178
	const wchar16_t bno[] = __NT_BASED_NAMED_OBJECTS;
d9d178
d9d178
	/* base named objects */
d9d178
	if (__ntapi->tt_strncmp_utf16(
d9d178
			name->base_named_objects,
d9d178
			bno,sizeof(bno)))
d9d178
		return NT_STATUS_INVALID_PARAMETER;
d9d178
d9d178
	/* service prefix */
d9d178
	for (i=0, type=-1; i
d9d178
		if (!(__ntapi->tt_strncmp_utf16(
d9d178
				name->svc_prefix,
d9d178
				__port_service_prefixes[i][0],
d9d178
				sizeof(__port_service_prefix))))
d9d178
			type = i;
d9d178
d9d178
	if (type < 0)
d9d178
		return NT_STATUS_INVALID_PARAMETER;
d9d178
d9d178
	/* port guid */
d9d178
	if ((status = __ntapi->tt_string_to_guid_utf16(
d9d178
			(nt_guid_str_utf16 *)&name->port_guid,
d9d178
			&attr->guid)))
d9d178
		return status;
d9d178
d9d178
	/* port keys */
d9d178
	if ((status = __ntapi->tt_hex_utf16_to_uint32(
d9d178
			name->port_name_keys.key_1st,
d9d178
			&attr->keys.key[0])))
d9d178
		return status;
d9d178
d9d178
	if ((status = __ntapi->tt_hex_utf16_to_uint32(
d9d178
			name->port_name_keys.key_2nd,
d9d178
			&attr->keys.key[1])))
d9d178
		return status;
d9d178
d9d178
	if ((status = __ntapi->tt_hex_utf16_to_uint32(
d9d178
			name->port_name_keys.key_3rd,
d9d178
			&attr->keys.key[2])))
d9d178
		return status;
d9d178
d9d178
	if ((status = __ntapi->tt_hex_utf16_to_uint32(
d9d178
			name->port_name_keys.key_4th,
d9d178
			&attr->keys.key[3])))
d9d178
		return status;
d9d178
d9d178
	if ((status = __ntapi->tt_hex_utf16_to_uint32(
d9d178
			name->port_name_keys.key_5th,
d9d178
			&attr->keys.key[4])))
d9d178
		return status;
d9d178
d9d178
	if ((status = __ntapi->tt_hex_utf16_to_uint32(
d9d178
			name->port_name_keys.key_6th,
d9d178
			&attr->keys.key[5])))
d9d178
		return status;
d9d178
d9d178
	/* backslash and underscores */
d9d178
	if (name->backslash != '\\')
d9d178
		return NT_STATUS_INVALID_PARAMETER;
d9d178
d9d178
	if (name->port_name_keys.uscore_1st != '_')
d9d178
		return NT_STATUS_INVALID_PARAMETER;
d9d178
d9d178
	if (name->port_name_keys.uscore_2nd != '_')
d9d178
		return NT_STATUS_INVALID_PARAMETER;
d9d178
d9d178
	if (name->port_name_keys.uscore_3rd != '_')
d9d178
		return NT_STATUS_INVALID_PARAMETER;
d9d178
d9d178
	if (name->port_name_keys.uscore_4th != '_')
d9d178
		return NT_STATUS_INVALID_PARAMETER;
d9d178
d9d178
	if (name->port_name_keys.uscore_5th != '_')
d9d178
		return NT_STATUS_INVALID_PARAMETER;
d9d178
d9d178
	/* unknown defaults */
d9d178
	attr->ver_major = 0;
d9d178
	attr->ver_minor = 0;
d9d178
	attr->options   = 0;
d9d178
	attr->flags     = 0;
d9d178
d9d178
	/* all done */
d9d178
	return NT_STATUS_SUCCESS;
d9d178
}
d9d178
d9d178
d9d178
int32_t __stdcall __ntapi_tt_port_attr_from_name(
d9d178
	__out	nt_port_attr *		attr,
d9d178
	__in	const nt_port_name *	name)
d9d178
{
d9d178
	/* null termination */
d9d178
	if (name->null_termination)
d9d178
		return NT_STATUS_INVALID_PARAMETER;
d9d178
d9d178
	return __tt_port_attr_from_name(
d9d178
		attr,name);
d9d178
}
d9d178
d9d178
d9d178
int32_t __stdcall __ntapi_tt_port_attr_from_string(
d9d178
	__out	nt_port_attr *			attr,
d9d178
	__in	const nt_unicode_string *	str)
d9d178
{
d9d178
	if (str->strlen != ((size_t)&(((nt_port_name *)0)->null_termination)))
d9d178
		return NT_STATUS_INVALID_PARAMETER;
d9d178
d9d178
	return __tt_port_attr_from_name(
d9d178
		attr,(const nt_port_name *)str->buffer);
d9d178
}
d9d178
d9d178
d9d178
int32_t __stdcall __ntapi_tt_port_attr_from_symlink(
d9d178
	__out	nt_port_attr *	attr,
d9d178
	__in	void *		symlink)
d9d178
{
d9d178
	int32_t			status;
d9d178
	size_t			size;
d9d178
	nt_unicode_string *	target;
d9d178
	uintptr_t		buffer[512/sizeof(uintptr_t)];
d9d178
d9d178
	target         = (nt_unicode_string *)buffer;
d9d178
	target->strlen = 0;
d9d178
	target->maxlen = sizeof(buffer) - sizeof(nt_unicode_string);
d9d178
	target->buffer = (wchar16_t *)&target[1];
d9d178
d9d178
	if ((status = __ntapi->zw_query_symbolic_link_object(
d9d178
			symlink,target,&size)))
d9d178
		return status;
d9d178
d9d178
	if (target->strlen != ((size_t)&(((nt_port_name *)0)->null_termination)))
d9d178
		return NT_STATUS_INVALID_PARAMETER;
d9d178
d9d178
	return __tt_port_attr_from_name(
d9d178
		attr,(const nt_port_name *)target->buffer);
d9d178
}