|
|
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 |
|
|
|
335494 |
/* type */
|
|
|
335494 |
attr->type = type;
|
|
|
335494 |
attr->subtype = 0;
|
|
|
335494 |
|
|
|
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 |
}
|