diff --git a/include/ntapi/nt_ipc.h b/include/ntapi/nt_ipc.h index 1dae3b3..7238146 100644 --- a/include/ntapi/nt_ipc.h +++ b/include/ntapi/nt_ipc.h @@ -52,4 +52,47 @@ typedef int32_t __stdcall ntapi_ipc_connect_by_port( __in void * hconn, __in nt_port_attr * attr); + +typedef int32_t __stdcall ntapi_ipc_connect_section_by_attr( + __out void ** hport, + __in nt_port_attr * attr, + __out void ** hsection, + __out void ** section_addr, + __out size_t * section_size); + + +typedef int32_t __stdcall ntapi_ipc_connect_section_by_name( + __out void ** hport, + __in nt_port_name * name, + __out void ** hsection, + __out void ** section_addr, + __out size_t * section_size); + + +typedef int32_t __stdcall ntapi_ipc_connect_section_by_symlink( + __out void ** hport, + __in void * hsymlink, + __out void ** hsection, + __out void ** section_addr, + __out size_t * section_size); + + +typedef int32_t __stdcall ntapi_ipc_connect_section_by_port( + __in void * hconn, + __in nt_port_attr * attr, + __out void ** hsection, + __out void ** section_addr, + __out size_t * section_size); + + +typedef int32_t __stdcall ntapi_ipc_init_section_by_port( + __in void * hconn, + __out void ** hsection, + __out void ** section_addr, + __out size_t * section_size); + + +typedef int32_t __stdcall ntapi_ipc_disconnect_unmap_section_by_port( + __in void * hconn); + #endif diff --git a/include/ntapi/nt_tty.h b/include/ntapi/nt_tty.h index fd41753..22c24a4 100644 --- a/include/ntapi/nt_tty.h +++ b/include/ntapi/nt_tty.h @@ -168,6 +168,14 @@ typedef struct __attr_ptr_size_aligned__ _nt_tty_service_info { } nt_tty_service_info; +typedef struct __attr_ptr_size_aligned__ _nt_tty_section_info { + nt_port_attr attr; + void * section; + void * section_addr; + size_t section_size; +} nt_tty_section_info; + + typedef struct __attr_ptr_size_aligned__ _nt_tty_vms_info { void * hroot; uint32_t hash; @@ -290,6 +298,15 @@ typedef struct __attr_ptr_size_aligned__ _nt_tty_service_msg { } nt_tty_service_msg; +typedef struct __attr_ptr_size_aligned__ _nt_tty_section_msg { + nt_port_message header; + struct { + nt_tty_msg_info ttyinfo; + nt_tty_section_info secinfo; + } data; +} nt_tty_section_msg; + + typedef struct __attr_ptr_size_aligned__ _nt_tty_vms_msg { nt_port_message header; struct { @@ -375,6 +392,7 @@ typedef struct __attr_ptr_size_aligned__ _nt_tty_port_msg { nt_pty_client_info clientinfo; nt_tty_session_info sessioninfo; nt_tty_service_info svcinfo; + nt_tty_section_info secinfo; nt_sem_info seminfo; }; } nt_tty_port_msg; @@ -438,6 +456,13 @@ typedef int32_t __stdcall ntapi_tty_client_process_register( __in nt_large_integer * reserved); +typedef int32_t __stdcall ntapi_tty_query_information_section( + __in void * hport, + __out nt_io_status_block * iosb, + __out nt_tty_section_info * secinfo, + __in const nt_guid * guid); + + typedef int32_t __stdcall ntapi_tty_query_information_server( __in void * hport, __out nt_io_status_block * iosb, diff --git a/include/ntapi/ntapi.h b/include/ntapi/ntapi.h index b3071c1..eff9c94 100644 --- a/include/ntapi/ntapi.h +++ b/include/ntapi/ntapi.h @@ -392,6 +392,12 @@ typedef struct _ntapi_vtbl { ntapi_ipc_connect_by_name * ipc_connect_by_name; ntapi_ipc_connect_by_symlink * ipc_connect_by_symlink; ntapi_ipc_connect_by_port * ipc_connect_by_port; + ntapi_ipc_connect_section_by_attr * ipc_connect_section_by_attr; + ntapi_ipc_connect_section_by_name * ipc_connect_section_by_name; + ntapi_ipc_connect_section_by_symlink * ipc_connect_section_by_symlink; + ntapi_ipc_connect_section_by_port * ipc_connect_section_by_port; + ntapi_ipc_init_section_by_port * ipc_init_section_by_port; + ntapi_ipc_disconnect_unmap_section_by_port * ipc_disconnect_unmap_section_by_port; ntapi_ipc_create_pipe * ipc_create_pipe; /* nt_ldr.h */ @@ -533,6 +539,7 @@ typedef struct _ntapi_vtbl { ntapi_tty_client_session_query * tty_client_session_query; ntapi_tty_client_session_set * tty_client_session_set; ntapi_tty_client_process_register * tty_client_process_register; + ntapi_tty_query_information_section * tty_query_information_section; ntapi_tty_query_information_server * tty_query_information_server; ntapi_tty_query_information_service * tty_query_information_service; ntapi_tty_request_peer * tty_request_peer; diff --git a/project/common.mk b/project/common.mk index 59d9317..65d6713 100644 --- a/project/common.mk +++ b/project/common.mk @@ -99,6 +99,7 @@ COMMON_SRCS = \ src/tty/ntapi_tty_connect.c \ src/tty/ntapi_tty_create_session.c \ src/tty/ntapi_tty_join_session.c \ + src/tty/ntapi_tty_query_information_section.c \ src/tty/ntapi_tty_query_information_server.c \ src/tty/ntapi_tty_query_information_service.c \ src/tty/ntapi_tty_request_peer.c \ diff --git a/src/internal/ntapi.c b/src/internal/ntapi.c index da91cfe..8e3c4b9 100644 --- a/src/internal/ntapi.c +++ b/src/internal/ntapi.c @@ -184,6 +184,12 @@ static int32_t __fastcall __ntapi_init_once(ntapi_vtbl ** pvtbl) __ntapi->ipc_connect_by_name = __ntapi_ipc_connect_by_name; __ntapi->ipc_connect_by_symlink = __ntapi_ipc_connect_by_symlink; __ntapi->ipc_connect_by_port = __ntapi_ipc_connect_by_port; + __ntapi->ipc_connect_section_by_attr = __ntapi_ipc_connect_section_by_attr; + __ntapi->ipc_connect_section_by_name = __ntapi_ipc_connect_section_by_name; + __ntapi->ipc_connect_section_by_symlink = __ntapi_ipc_connect_section_by_symlink; + __ntapi->ipc_connect_section_by_port = __ntapi_ipc_connect_section_by_port; + __ntapi->ipc_init_section_by_port = __ntapi_ipc_init_section_by_port; + __ntapi->ipc_disconnect_unmap_section_by_port = __ntapi_ipc_disconnect_unmap_section_by_port; /* nt_ldr.h */ __ntapi->ldr_load_system_dll = __ntapi_ldr_load_system_dll; @@ -324,6 +330,7 @@ static int32_t __fastcall __ntapi_init_once(ntapi_vtbl ** pvtbl) __ntapi->tty_client_session_query = __ntapi_tty_client_session_query; __ntapi->tty_client_session_set = __ntapi_tty_client_session_set; __ntapi->tty_client_process_register = __ntapi_tty_client_process_register; + __ntapi->tty_query_information_section = __ntapi_tty_query_information_section; __ntapi->tty_query_information_server = __ntapi_tty_query_information_server; __ntapi->tty_query_information_service = __ntapi_tty_query_information_service; __ntapi->tty_request_peer = __ntapi_tty_request_peer; diff --git a/src/internal/ntapi_fnapi.h b/src/internal/ntapi_fnapi.h index 8ff01f5..9fa215c 100644 --- a/src/internal/ntapi_fnapi.h +++ b/src/internal/ntapi_fnapi.h @@ -50,6 +50,12 @@ ntapi_ipc_connect_by_attr __ntapi_ipc_connect_by_attr; ntapi_ipc_connect_by_name __ntapi_ipc_connect_by_name; ntapi_ipc_connect_by_symlink __ntapi_ipc_connect_by_symlink; ntapi_ipc_connect_by_port __ntapi_ipc_connect_by_port; +ntapi_ipc_connect_section_by_attr __ntapi_ipc_connect_section_by_attr; +ntapi_ipc_connect_section_by_name __ntapi_ipc_connect_section_by_name; +ntapi_ipc_connect_section_by_symlink __ntapi_ipc_connect_section_by_symlink; +ntapi_ipc_connect_section_by_port __ntapi_ipc_connect_section_by_port; +ntapi_ipc_init_section_by_port __ntapi_ipc_init_section_by_port; +ntapi_ipc_disconnect_unmap_section_by_port __ntapi_ipc_disconnect_unmap_section_by_port; ntapi_ipc_create_pipe __ntapi_ipc_create_pipe_v1; ntapi_ipc_create_pipe __ntapi_ipc_create_pipe_v2; @@ -196,6 +202,7 @@ ntapi_tty_connect __ntapi_tty_connect; ntapi_tty_client_session_query __ntapi_tty_client_session_query; ntapi_tty_client_session_set __ntapi_tty_client_session_set; ntapi_tty_client_process_register __ntapi_tty_client_process_register; +ntapi_tty_query_information_section __ntapi_tty_query_information_section; ntapi_tty_query_information_server __ntapi_tty_query_information_server; ntapi_tty_query_information_service __ntapi_tty_query_information_service; ntapi_tty_request_peer __ntapi_tty_request_peer; diff --git a/src/ipc/ntapi_ipc_connect.c b/src/ipc/ntapi_ipc_connect.c index d61e869..fe3561a 100644 --- a/src/ipc/ntapi_ipc_connect.c +++ b/src/ipc/ntapi_ipc_connect.c @@ -127,9 +127,12 @@ static int32_t __ipc_connect_by_attr( } -int32_t __stdcall __ntapi_ipc_connect_by_attr( +int32_t __stdcall __ntapi_ipc_connect_section_by_attr( __out void ** hport, - __in nt_port_attr * attr) + __in nt_port_attr * attr, + __out void ** hsection, + __out void ** secaddr, + __out size_t * secsize) { nt_port_name name; nt_unicode_string str; @@ -143,15 +146,16 @@ int32_t __stdcall __ntapi_ipc_connect_by_attr( return __ipc_connect_by_attr( hport,attr,&str,0, - &(void *){0}, - &(void *){0}, - &(size_t){0}); + hsection,secaddr,secsize); } -int32_t __stdcall __ntapi_ipc_connect_by_name( +int32_t __stdcall __ntapi_ipc_connect_section_by_name( __out void ** hport, - __in nt_port_name * name) + __in nt_port_name * name, + __out void ** hsection, + __out void ** secaddr, + __out size_t * secsize) { int32_t status; nt_port_attr attr; @@ -166,15 +170,16 @@ int32_t __stdcall __ntapi_ipc_connect_by_name( return __ipc_connect_by_attr( hport,&attr,&str,0, - &(void *){0}, - &(void *){0}, - &(size_t){0}); + hsection,secaddr,secsize); } -int32_t __stdcall __ntapi_ipc_connect_by_symlink( +int32_t __stdcall __ntapi_ipc_connect_section_by_symlink( __out void ** hport, - __in void * hsymlink) + __in void * hsymlink, + __out void ** hsection, + __out void ** secaddr, + __out size_t * secsize) { int32_t status; nt_port_attr attr; @@ -202,6 +207,53 @@ int32_t __stdcall __ntapi_ipc_connect_by_symlink( return __ipc_connect_by_attr( hport,&attr,str,0, + hsection,secaddr,secsize); +} + + +int32_t __stdcall __ntapi_ipc_connect_section_by_port( + __in void * hconn, + __in nt_port_attr * attr, + __out void ** hsection, + __out void ** secaddr, + __out size_t * secsize) +{ + return __ipc_connect_by_attr( + &(void *){0},attr,0,hconn, + hsection,secaddr,secsize); +} + + +int32_t __stdcall __ntapi_ipc_connect_by_attr( + __out void ** hport, + __in nt_port_attr * attr) +{ + return __ntapi_ipc_connect_section_by_attr( + hport,attr, + &(void *){0}, + &(void *){0}, + &(size_t){0}); +} + + +int32_t __stdcall __ntapi_ipc_connect_by_name( + __out void ** hport, + __in nt_port_name * name) +{ + return __ntapi_ipc_connect_section_by_name( + hport,name, + &(void *){0}, + &(void *){0}, + &(size_t){0}); +} + + +int32_t __stdcall __ntapi_ipc_connect_by_symlink( + __out void ** hport, + __in void * hsymlink) +{ + return __ntapi_ipc_connect_section_by_symlink( + hport,hsymlink, &(void *){0}, &(void *){0}, &(size_t){0}); @@ -212,8 +264,8 @@ int32_t __stdcall __ntapi_ipc_connect_by_port( __in void * hconn, __in nt_port_attr * attr) { - return __ipc_connect_by_attr( - &(void *){0},attr,0,hconn, + return __ntapi_ipc_connect_section_by_port( + hconn,attr, &(void *){0}, &(void *){0}, &(size_t){0}); @@ -247,3 +299,136 @@ int __ntapi_ipc_page_alloc( return 0; } + + +int32_t __stdcall __ntapi_ipc_init_section_by_port( + __in void * hconn, + __out void ** hsection, + __out void ** secaddr, + __out size_t * secsize) +{ + int32_t status; + nt_tty_section_info secinfo; + nt_iosb iosb; + struct dalist_node_ex * node; + nt_ipc_conn * ipc; + void * addr; + size_t size; + ntapi_internals * __internals; + + /* init */ + __internals = __ntapi_internals(); + + /* lock */ + if (at_locked_cas(&__internals->hlock,0,1)) + return NT_STATUS_RESOURCE_NOT_OWNED; + + /* connection node */ + if ((status = dalist_get_node_by_key( + &__internals->ipc_conns, + &node,(uintptr_t)hconn, + DALIST_NODE_TYPE_EXISTING, + &(uintptr_t){0}))) + return __ipc_connect_return( + &__internals->hlock, + NT_STATUS_INTERNAL_ERROR); + + else if (!node) + return NT_STATUS_NOT_FOUND; + + else + ipc = (nt_ipc_conn *)&node->dblock; + + /* already mapped? */ + if (ipc->secaddr) + return __ipc_connect_return( + &__internals->hlock, + NT_STATUS_SUCCESS); + + /* section info */ + if ((status = __ntapi->tty_query_information_section( + hconn,&iosb,&secinfo,0))) + return __ipc_connect_return( + &__internals->hlock, + status); + + /* map section */ + addr = 0; + size = 0; + + if ((status = __ntapi->zw_map_view_of_section( + secinfo.section, + NT_CURRENT_PROCESS_HANDLE, + &addr,0, + secinfo.section_size,0,&size, + NT_VIEW_UNMAP,0, + NT_PAGE_READWRITE))) + return __ipc_connect_return( + &__internals->hlock, + status); + + /* update */ + *hsection = secinfo.section; + *secaddr = addr; + *secsize = size; + + /* all done */ + return __ipc_connect_return( + &__internals->hlock, + NT_STATUS_SUCCESS); +} + + +int32_t __stdcall __ntapi_ipc_disconnect_unmap_section_by_port( + __in void * hconn) +{ + int32_t status; + struct dalist_node_ex * node; + nt_ipc_conn * ipc; + ntapi_internals * __internals; + + /* init */ + __internals = __ntapi_internals(); + + /* lock */ + if (at_locked_cas(&__internals->hlock,0,1)) + return NT_STATUS_RESOURCE_NOT_OWNED; + + /* connection node */ + if ((status = dalist_get_node_by_key( + &__internals->ipc_conns, + &node,(uintptr_t)hconn, + DALIST_NODE_TYPE_EXISTING, + &(uintptr_t){0}))) + return __ipc_connect_return( + &__internals->hlock, + NT_STATUS_INTERNAL_ERROR); + + else if (!node) + return __ipc_connect_return( + &__internals->hlock, + NT_STATUS_NOT_FOUND); + + else + ipc = (nt_ipc_conn *)&node->dblock; + + /* unmap section */ + if (ipc->secaddr) + __ntapi->zw_unmap_view_of_section( + NT_CURRENT_PROCESS_HANDLE, + ipc->secaddr); + + /* close section */ + if (ipc->hsection) + __ntapi->zw_close(ipc->hsection); + + /* disconnect */ + __ntapi->zw_close(hconn); + + /* remove node */ + dalist_discard_node(&__internals->ipc_conns,node); + + return __ipc_connect_return( + &__internals->hlock, + NT_STATUS_SUCCESS); +} diff --git a/src/tty/ntapi_tty_query_information_section.c b/src/tty/ntapi_tty_query_information_section.c new file mode 100644 index 0000000..4cf26c6 --- /dev/null +++ b/src/tty/ntapi_tty_query_information_section.c @@ -0,0 +1,52 @@ +/********************************************************/ +/* 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" + +int32_t __stdcall __ntapi_tty_query_information_section( + __in void * hport, + __out nt_io_status_block * iosb, + __out nt_tty_section_info * secinfo, + __in const nt_guid * guid) +{ + int32_t status; + nt_tty_section_msg msg; + + __ntapi->tt_aligned_block_memset( + &msg,0,sizeof(msg)); + + msg.header.msg_type = NT_LPC_NEW_MESSAGE; + msg.header.data_size = sizeof(msg.data); + msg.header.msg_size = sizeof(msg); + msg.data.ttyinfo.opcode = NT_TTY_QUERY_INFORMATION_SECTION; + + if (guid) + __ntapi->tt_guid_copy( + &msg.data.secinfo.attr.guid, + guid); + + if (!hport) + hport = __ntapi_internals()->hport_tty_session; + + if ((status = __ntapi->zw_request_wait_reply_port(hport,&msg,&msg))) + return status; + else if (msg.data.ttyinfo.status) + return msg.data.ttyinfo.status; + + __ntapi->tt_generic_memcpy( + secinfo, + &msg.data.secinfo, + sizeof(*secinfo)); + + iosb->status = NT_STATUS_SUCCESS; + iosb->info = sizeof(*secinfo); + + return NT_STATUS_SUCCESS; +}