summaryrefslogtreecommitdiffhomepage
path: root/src/ipc/ntapi_ipc_connect.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ipc/ntapi_ipc_connect.c')
-rw-r--r--src/ipc/ntapi_ipc_connect.c213
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);
+}