/********************************************************/ /* ntapi: Native API core library */ /* Copyright (C) 2013--2017 Z. Gilboa */ /* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */ /********************************************************/ #include #include #include #include #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'}}, {{'b','r','i','d','g','e'}}, {{'n','t','p','r','o','c'}}, {{'s','e','m','c','t','l'}}, {{'s','e','m','s','v','c'}}, {{'m','s','q','c','t','l'}}, {{'m','s','q','s','v','c'}}, {{'a','f','l','c','t','l'}}, {{'a','f','l','s','v','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_BRIDGE}, {NT_PORT_GUID_NTPROC}, {NT_PORT_GUID_SEMCTL}, {NT_PORT_GUID_SEMSVC}, {NT_PORT_GUID_MSQCTL}, {NT_PORT_GUID_MSQSVC}, {NT_PORT_GUID_AFLCTL}, {NT_PORT_GUID_AFLSVC}}; 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 const nt_guid * guid) { int itype; int isubtype; for (itype=0; itypezw_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_attr( __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; } static int32_t __tt_port_attr_from_name( __out nt_port_attr * attr, __in const nt_port_name * name) { int i; int type; int32_t status; const wchar16_t bno[] = __NT_BASED_NAMED_OBJECTS; /* base named objects */ if (__ntapi->tt_strncmp_utf16( name->base_named_objects, bno,sizeof(bno))) return NT_STATUS_INVALID_PARAMETER; /* service prefix */ for (i=0, type=-1; itt_strncmp_utf16( name->svc_prefix, __port_service_prefixes[i][0], sizeof(__port_service_prefix)))) type = i; if (type < 0) return NT_STATUS_INVALID_PARAMETER; /* port guid */ if ((status = __ntapi->tt_string_to_guid_utf16( (nt_guid_str_utf16 *)&name->port_guid, &attr->guid))) return status; /* port keys */ if ((status = __ntapi->tt_hex_utf16_to_uint32( name->port_name_keys.key_1st, &attr->keys.key[0]))) return status; if ((status = __ntapi->tt_hex_utf16_to_uint32( name->port_name_keys.key_2nd, &attr->keys.key[1]))) return status; if ((status = __ntapi->tt_hex_utf16_to_uint32( name->port_name_keys.key_3rd, &attr->keys.key[2]))) return status; if ((status = __ntapi->tt_hex_utf16_to_uint32( name->port_name_keys.key_4th, &attr->keys.key[3]))) return status; if ((status = __ntapi->tt_hex_utf16_to_uint32( name->port_name_keys.key_5th, &attr->keys.key[4]))) return status; if ((status = __ntapi->tt_hex_utf16_to_uint32( name->port_name_keys.key_6th, &attr->keys.key[5]))) return status; /* backslash and underscores */ if (name->backslash != '\\') return NT_STATUS_INVALID_PARAMETER; if (name->port_name_keys.uscore_1st != '_') return NT_STATUS_INVALID_PARAMETER; if (name->port_name_keys.uscore_2nd != '_') return NT_STATUS_INVALID_PARAMETER; if (name->port_name_keys.uscore_3rd != '_') return NT_STATUS_INVALID_PARAMETER; if (name->port_name_keys.uscore_4th != '_') return NT_STATUS_INVALID_PARAMETER; if (name->port_name_keys.uscore_5th != '_') return NT_STATUS_INVALID_PARAMETER; /* type */ attr->type = type; attr->subtype = 0; /* unknown defaults */ attr->ver_major = 0; attr->ver_minor = 0; attr->options = 0; attr->flags = 0; /* all done */ return NT_STATUS_SUCCESS; } int32_t __stdcall __ntapi_tt_port_attr_from_name( __out nt_port_attr * attr, __in const nt_port_name * name) { /* null termination */ if (name->null_termination) return NT_STATUS_INVALID_PARAMETER; return __tt_port_attr_from_name( attr,name); } int32_t __stdcall __ntapi_tt_port_attr_from_string( __out nt_port_attr * attr, __in const nt_unicode_string * str) { if (str->strlen != ((size_t)&(((nt_port_name *)0)->null_termination))) return NT_STATUS_INVALID_PARAMETER; return __tt_port_attr_from_name( attr,(const nt_port_name *)str->buffer); } int32_t __stdcall __ntapi_tt_port_attr_from_symlink( __out nt_port_attr * attr, __in void * symlink) { int32_t status; size_t size; nt_unicode_string * target; uintptr_t buffer[512/sizeof(uintptr_t)]; target = (nt_unicode_string *)buffer; target->strlen = 0; target->maxlen = sizeof(buffer) - sizeof(nt_unicode_string); target->buffer = (wchar16_t *)&target[1]; if ((status = __ntapi->zw_query_symbolic_link_object( symlink,target,&size))) return status; if (target->strlen != ((size_t)&(((nt_port_name *)0)->null_termination))) return NT_STATUS_INVALID_PARAMETER; return __tt_port_attr_from_name( attr,(const nt_port_name *)target->buffer); }