/********************************************************/
/* ntapi: Native API core library */
/* Copyright (C) 2013--2016 Z. Gilboa */
/* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */
/********************************************************/
#include <psxtypes/psxtypes.h>
#include <ntapi/nt_guid.h>
#include <ntapi/nt_port.h>
#include <ntapi/nt_string.h>
#include "ntapi_impl.h"
typedef wchar16_t __port_service_prefix[6];
static const __port_service_prefix __port_service_null = {0};
static const __port_service_prefix __port_service_prefixes[NT_PORT_TYPE_CAP][NT_PORT_SUBTYPE_CAP] = {
{{'s','v','c','a','n','y'}},
{{'n','t','c','t','t','y'}},
{{'v','m','o','u','n','t'}},
{{'d','a','e','m','o','n'}},
{{'s','y','m','l','n','k'}},
{{'n','t','p','r','o','c'}}};
static const nt_guid __port_guids[NT_PORT_TYPE_CAP][NT_PORT_SUBTYPE_CAP] = {
{NT_PORT_GUID_DEFAULT},
{NT_PORT_GUID_SUBSYSTEM},
{NT_PORT_GUID_VMOUNT},
{NT_PORT_GUID_DAEMON},
{NT_PORT_GUID_SYMLNK},
{NT_PORT_GUID_NTPROC}};
int32_t __stdcall __ntapi_tt_port_guid_from_type(
__out nt_guid * guid,
__in nt_port_type type,
__in nt_port_subtype subtype)
{
const nt_guid * src_guid;
if ((type >= NT_PORT_TYPE_CAP) || (subtype >= NT_PORT_SUBTYPE_CAP))
return NT_STATUS_INVALID_PARAMETER;
src_guid = &(__port_guids[type][subtype]);
__ntapi->tt_aligned_block_memcpy(
(uintptr_t *)guid,
(uintptr_t *)src_guid,
sizeof(nt_guid));
return NT_STATUS_SUCCESS;
}
int32_t __stdcall __ntapi_tt_port_type_from_guid(
__out nt_port_type * type,
__out nt_port_subtype * subtype,
__in nt_guid * guid)
{
int itype;
int isubtype;
for (itype=0; itype<NT_PORT_TYPE_CAP; itype++) {
for (isubtype=0; isubtype<NT_PORT_SUBTYPE_CAP; isubtype++) {
if (!(__ntapi_tt_guid_compare(
&__port_guids[itype][isubtype],
guid))) {
*type = (nt_port_type)itype;
*subtype = (nt_port_subtype)isubtype;
return NT_STATUS_SUCCESS;
}
}
}
return NT_STATUS_NOT_FOUND;
}
int32_t __stdcall __ntapi_tt_port_generate_keys(
__out nt_port_keys * keys)
{
int32_t status;
nt_large_integer ticks;
nt_large_integer pcfreq;
nt_luid luid;
if ((status = __ntapi->zw_query_performance_counter(&ticks,&pcfreq)))
return status;
if ((status = __ntapi->zw_allocate_locally_unique_id(&luid)))
return status;
keys->key[0] = pe_get_current_process_id();
keys->key[1] = pe_get_current_thread_id();
keys->key[2] = ticks.ihigh;
keys->key[3] = ticks.ulow;
keys->key[4] = luid.high;
keys->key[5] = luid.low;
return NT_STATUS_SUCCESS;
}
void __stdcall __ntapi_tt_port_format_keys(
__in nt_port_keys * keys,
__out nt_port_name_keys * name_keys)
{
__ntapi->tt_uint32_to_hex_utf16(keys->key[0],name_keys->key_1st);
__ntapi->tt_uint32_to_hex_utf16(keys->key[1],name_keys->key_2nd);
__ntapi->tt_uint32_to_hex_utf16(keys->key[2],name_keys->key_3rd);
__ntapi->tt_uint32_to_hex_utf16(keys->key[3],name_keys->key_4th);
__ntapi->tt_uint32_to_hex_utf16(keys->key[4],name_keys->key_5th);
__ntapi->tt_uint32_to_hex_utf16(keys->key[5],name_keys->key_6th);
return;
}
void __stdcall __ntapi_tt_port_name_from_attributes(
__out nt_port_name * name,
__in nt_port_attr * attr)
{
wchar16_t bno[] = __NT_BASED_NAMED_OBJECTS;
/* base named objects */
__ntapi->tt_memcpy_utf16(
name->base_named_objects,
bno,sizeof(bno));
/* service prefix */
if (attr && (attr->type < NT_PORT_TYPE_CAP) && (attr->subtype < NT_PORT_SUBTYPE_CAP))
__ntapi->tt_memcpy_utf16(
name->svc_prefix,
__port_service_prefixes[attr->type][attr->subtype],
sizeof(name->svc_prefix));
else
__ntapi->tt_memcpy_utf16(
name->svc_prefix,
__port_service_null,
sizeof(name->svc_prefix));
/* port guid */
__ntapi->tt_guid_to_string_utf16(
&attr->guid,
(nt_guid_str_utf16 *)&name->port_guid);
/* port name keys */
__ntapi_tt_port_format_keys(
&attr->keys,
&name->port_name_keys);
/* backslash and underscores */
name->backslash = '\\';
name->port_guid.uscore_guid = '_';
name->port_guid.uscore_keys = '_';
name->port_name_keys.uscore_1st = '_';
name->port_name_keys.uscore_2nd = '_';
name->port_name_keys.uscore_3rd = '_';
name->port_name_keys.uscore_4th = '_';
name->port_name_keys.uscore_5th = '_';
/* null termination */
name->null_termination = 0;
return;
}