diff options
Diffstat (limited to 'src/ipc/ntapi_ipc_connect.c')
-rw-r--r-- | src/ipc/ntapi_ipc_connect.c | 213 |
1 files changed, 199 insertions, 14 deletions
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); +} |