|
|
30d28d |
/********************************************************/
|
|
|
30d28d |
/* ntapi: Native API core library */
|
|
|
30d28d |
/* Copyright (C) 2013--2017 Z. Gilboa */
|
|
|
30d28d |
/* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */
|
|
|
30d28d |
/********************************************************/
|
|
|
30d28d |
|
|
|
30d28d |
#include <psxtypes/psxtypes.h>
|
|
|
30d28d |
#include <ntapi/nt_file.h>
|
|
|
30d28d |
#include <ntapi/nt_string.h>
|
|
|
30d28d |
#include <ntapi/nt_atomic.h>
|
|
|
30d28d |
#include <ntapi/ntapi.h>
|
|
|
30d28d |
#include "ntapi_impl.h"
|
|
|
30d28d |
|
|
|
30d28d |
static int32_t __ipc_connect_return(
|
|
|
30d28d |
intptr_t * hlock,
|
|
|
30d28d |
int32_t status)
|
|
|
30d28d |
{
|
|
|
30d28d |
at_store(hlock,0);
|
|
|
30d28d |
return status;
|
|
|
30d28d |
}
|
|
|
30d28d |
|
|
|
30d28d |
|
|
|
edb085 |
static void __ipc_init_ctrl_msg_semctl(
|
|
|
edb085 |
const nt_port_attr * attr,
|
|
|
edb085 |
nt_tty_ipc_msg * msg)
|
|
|
edb085 |
{
|
|
|
edb085 |
__ntapi->tt_aligned_block_memset(
|
|
|
edb085 |
(uintptr_t *)msg,
|
|
|
edb085 |
0,sizeof(*msg));
|
|
|
edb085 |
|
|
|
edb085 |
msg->data.ipcinfo.ctrlsvc.type = attr->type;
|
|
|
edb085 |
msg->data.ipcinfo.ctrlsvc.subtype = attr->subtype;
|
|
|
edb085 |
|
|
|
edb085 |
msg->data.ipcinfo.ctrlsvc.keys.key[0] = attr->keys.key[0];
|
|
|
edb085 |
msg->data.ipcinfo.ctrlsvc.keys.key[1] = attr->keys.key[1];
|
|
|
edb085 |
msg->data.ipcinfo.ctrlsvc.keys.key[2] = attr->keys.key[2];
|
|
|
edb085 |
msg->data.ipcinfo.ctrlsvc.keys.key[3] = attr->keys.key[3];
|
|
|
edb085 |
msg->data.ipcinfo.ctrlsvc.keys.key[4] = attr->keys.key[4];
|
|
|
edb085 |
msg->data.ipcinfo.ctrlsvc.keys.key[5] = attr->keys.key[5];
|
|
|
edb085 |
|
|
|
edb085 |
__ntapi->tt_guid_copy(
|
|
|
edb085 |
&msg->data.ipcinfo.ctrlsvc.guid,
|
|
|
edb085 |
&attr->guid);
|
|
|
edb085 |
}
|
|
|
edb085 |
|
|
|
edb085 |
|
|
|
edb085 |
static void __ipc_init_ctrl_msg_semsvc(
|
|
|
edb085 |
nt_rtdata * rtdata,
|
|
|
edb085 |
nt_tty_ipc_msg * msg)
|
|
|
edb085 |
{
|
|
|
edb085 |
__ntapi->tt_aligned_block_memset(
|
|
|
edb085 |
(uintptr_t *)msg,
|
|
|
edb085 |
0,sizeof(*msg));
|
|
|
edb085 |
|
|
|
edb085 |
msg->data.ipcinfo.ctrlsvc.type = rtdata->semctl_type;
|
|
|
edb085 |
msg->data.ipcinfo.ctrlsvc.subtype = rtdata->semctl_subtype;
|
|
|
edb085 |
|
|
|
edb085 |
msg->data.ipcinfo.ctrlsvc.keys.key[0] = rtdata->semctl_keys[0];
|
|
|
edb085 |
msg->data.ipcinfo.ctrlsvc.keys.key[1] = rtdata->semctl_keys[1];
|
|
|
edb085 |
msg->data.ipcinfo.ctrlsvc.keys.key[2] = rtdata->semctl_keys[2];
|
|
|
edb085 |
msg->data.ipcinfo.ctrlsvc.keys.key[3] = rtdata->semctl_keys[3];
|
|
|
edb085 |
msg->data.ipcinfo.ctrlsvc.keys.key[4] = rtdata->semctl_keys[4];
|
|
|
edb085 |
msg->data.ipcinfo.ctrlsvc.keys.key[5] = rtdata->semctl_keys[5];
|
|
|
edb085 |
|
|
|
edb085 |
__ntapi->tt_guid_copy(
|
|
|
edb085 |
&msg->data.ipcinfo.ctrlsvc.guid,
|
|
|
edb085 |
&rtdata->semctl_guid);
|
|
|
edb085 |
}
|
|
|
edb085 |
|
|
|
edb085 |
|
|
|
47f21a |
static void __ipc_init_ctrl_msg_msqctl(
|
|
|
47f21a |
const nt_port_attr * attr,
|
|
|
47f21a |
nt_tty_ipc_msg * msg)
|
|
|
47f21a |
{
|
|
|
47f21a |
__ntapi->tt_aligned_block_memset(
|
|
|
47f21a |
(uintptr_t *)msg,
|
|
|
47f21a |
0,sizeof(*msg));
|
|
|
47f21a |
|
|
|
47f21a |
msg->data.ipcinfo.ctrlsvc.type = attr->type;
|
|
|
47f21a |
msg->data.ipcinfo.ctrlsvc.subtype = attr->subtype;
|
|
|
47f21a |
|
|
|
47f21a |
msg->data.ipcinfo.ctrlsvc.keys.key[0] = attr->keys.key[0];
|
|
|
47f21a |
msg->data.ipcinfo.ctrlsvc.keys.key[1] = attr->keys.key[1];
|
|
|
47f21a |
msg->data.ipcinfo.ctrlsvc.keys.key[2] = attr->keys.key[2];
|
|
|
47f21a |
msg->data.ipcinfo.ctrlsvc.keys.key[3] = attr->keys.key[3];
|
|
|
47f21a |
msg->data.ipcinfo.ctrlsvc.keys.key[4] = attr->keys.key[4];
|
|
|
47f21a |
msg->data.ipcinfo.ctrlsvc.keys.key[5] = attr->keys.key[5];
|
|
|
47f21a |
|
|
|
47f21a |
__ntapi->tt_guid_copy(
|
|
|
47f21a |
&msg->data.ipcinfo.ctrlsvc.guid,
|
|
|
47f21a |
&attr->guid);
|
|
|
47f21a |
}
|
|
|
47f21a |
|
|
|
47f21a |
|
|
|
47f21a |
static void __ipc_init_ctrl_msg_msqsvc(
|
|
|
47f21a |
nt_rtdata * rtdata,
|
|
|
47f21a |
nt_tty_ipc_msg * msg)
|
|
|
47f21a |
{
|
|
|
47f21a |
__ntapi->tt_aligned_block_memset(
|
|
|
47f21a |
(uintptr_t *)msg,
|
|
|
47f21a |
0,sizeof(*msg));
|
|
|
47f21a |
|
|
|
47f21a |
msg->data.ipcinfo.ctrlsvc.type = rtdata->msqctl_type;
|
|
|
47f21a |
msg->data.ipcinfo.ctrlsvc.subtype = rtdata->msqctl_subtype;
|
|
|
47f21a |
|
|
|
47f21a |
msg->data.ipcinfo.ctrlsvc.keys.key[0] = rtdata->msqctl_keys[0];
|
|
|
47f21a |
msg->data.ipcinfo.ctrlsvc.keys.key[1] = rtdata->msqctl_keys[1];
|
|
|
47f21a |
msg->data.ipcinfo.ctrlsvc.keys.key[2] = rtdata->msqctl_keys[2];
|
|
|
47f21a |
msg->data.ipcinfo.ctrlsvc.keys.key[3] = rtdata->msqctl_keys[3];
|
|
|
47f21a |
msg->data.ipcinfo.ctrlsvc.keys.key[4] = rtdata->msqctl_keys[4];
|
|
|
47f21a |
msg->data.ipcinfo.ctrlsvc.keys.key[5] = rtdata->msqctl_keys[5];
|
|
|
47f21a |
|
|
|
47f21a |
__ntapi->tt_guid_copy(
|
|
|
47f21a |
&msg->data.ipcinfo.ctrlsvc.guid,
|
|
|
47f21a |
&rtdata->msqctl_guid);
|
|
|
47f21a |
}
|
|
|
47f21a |
|
|
|
47f21a |
|
|
|
edb085 |
static void __ipc_init_ctrl_msg_ipcpeer(
|
|
|
edb085 |
nt_rtdata * rtdata,
|
|
|
edb085 |
nt_tty_ipc_msg * msg)
|
|
|
edb085 |
{
|
|
|
edb085 |
__ntapi->tt_aligned_block_memset(
|
|
|
edb085 |
(uintptr_t *)msg,
|
|
|
edb085 |
0,sizeof(*msg));
|
|
|
edb085 |
|
|
|
edb085 |
msg->data.ipcinfo.ctrlsvc.type = rtdata->srv_type;
|
|
|
edb085 |
msg->data.ipcinfo.ctrlsvc.subtype = rtdata->srv_subtype;
|
|
|
edb085 |
|
|
|
edb085 |
msg->data.ipcinfo.ctrlsvc.keys.key[0] = rtdata->srv_keys[0];
|
|
|
edb085 |
msg->data.ipcinfo.ctrlsvc.keys.key[1] = rtdata->srv_keys[1];
|
|
|
edb085 |
msg->data.ipcinfo.ctrlsvc.keys.key[2] = rtdata->srv_keys[2];
|
|
|
edb085 |
msg->data.ipcinfo.ctrlsvc.keys.key[3] = rtdata->srv_keys[3];
|
|
|
edb085 |
msg->data.ipcinfo.ctrlsvc.keys.key[4] = rtdata->srv_keys[4];
|
|
|
edb085 |
msg->data.ipcinfo.ctrlsvc.keys.key[5] = rtdata->srv_keys[5];
|
|
|
edb085 |
|
|
|
edb085 |
__ntapi->tt_guid_copy(
|
|
|
edb085 |
&msg->data.ipcinfo.ctrlsvc.guid,
|
|
|
edb085 |
&rtdata->srv_guid);
|
|
|
edb085 |
}
|
|
|
edb085 |
|
|
|
edb085 |
|
|
|
edb085 |
static int32_t __ipc_set_client_keys(
|
|
|
edb085 |
void * hport,
|
|
|
edb085 |
const nt_port_attr * attr,
|
|
|
edb085 |
nt_rtdata * rtdata)
|
|
|
edb085 |
{
|
|
|
edb085 |
int32_t status;
|
|
|
edb085 |
nt_tty_ipc_msg msg;
|
|
|
edb085 |
uint32_t opcode;
|
|
|
edb085 |
|
|
|
edb085 |
switch (attr->type) {
|
|
|
edb085 |
case NT_PORT_TYPE_SEMCTL:
|
|
|
edb085 |
if (rtdata->srv_type == NT_PORT_TYPE_SEMSVC)
|
|
|
edb085 |
__ipc_init_ctrl_msg_ipcpeer(
|
|
|
edb085 |
rtdata,&msg;;
|
|
|
edb085 |
else
|
|
|
edb085 |
__ipc_init_ctrl_msg_semctl(
|
|
|
edb085 |
attr,&msg;;
|
|
|
edb085 |
|
|
|
edb085 |
opcode = NT_TTY_SEM_FCNTL;
|
|
|
edb085 |
break;
|
|
|
edb085 |
|
|
|
edb085 |
case NT_PORT_TYPE_SEMSVC:
|
|
|
edb085 |
if (rtdata->srv_type == NT_PORT_TYPE_SEMCTL)
|
|
|
edb085 |
return NT_STATUS_SUCCESS;
|
|
|
edb085 |
|
|
|
edb085 |
__ipc_init_ctrl_msg_semsvc(
|
|
|
edb085 |
rtdata,&msg;;
|
|
|
edb085 |
|
|
|
edb085 |
opcode = NT_TTY_SEM_FCNTL;
|
|
|
edb085 |
break;
|
|
|
edb085 |
|
|
|
47f21a |
case NT_PORT_TYPE_MSQCTL:
|
|
|
47f21a |
if (rtdata->srv_type == NT_PORT_TYPE_MSQSVC)
|
|
|
47f21a |
__ipc_init_ctrl_msg_ipcpeer(
|
|
|
47f21a |
rtdata,&msg;;
|
|
|
47f21a |
else
|
|
|
47f21a |
__ipc_init_ctrl_msg_msqctl(
|
|
|
47f21a |
attr,&msg;;
|
|
|
47f21a |
|
|
|
47f21a |
opcode = NT_TTY_MSQ_FCNTL;
|
|
|
47f21a |
break;
|
|
|
47f21a |
|
|
|
47f21a |
case NT_PORT_TYPE_MSQSVC:
|
|
|
47f21a |
if (rtdata->srv_type == NT_PORT_TYPE_MSQCTL)
|
|
|
47f21a |
return NT_STATUS_SUCCESS;
|
|
|
47f21a |
|
|
|
47f21a |
__ipc_init_ctrl_msg_msqsvc(
|
|
|
47f21a |
rtdata,&msg;;
|
|
|
47f21a |
|
|
|
47f21a |
opcode = NT_TTY_MSQ_FCNTL;
|
|
|
47f21a |
break;
|
|
|
47f21a |
|
|
|
edb085 |
default:
|
|
|
edb085 |
return NT_STATUS_SUCCESS;
|
|
|
edb085 |
}
|
|
|
edb085 |
|
|
|
edb085 |
msg.header.msg_type = NT_LPC_NEW_MESSAGE;
|
|
|
edb085 |
msg.header.data_size = sizeof(msg.data);
|
|
|
edb085 |
msg.header.msg_size = sizeof(msg);
|
|
|
edb085 |
msg.data.ttyinfo.opcode = opcode;
|
|
|
edb085 |
|
|
|
edb085 |
msg.data.ipcinfo.ipckeys[0] = rtdata->ipc_keys[0];
|
|
|
edb085 |
msg.data.ipcinfo.ipckeys[1] = rtdata->ipc_keys[1];
|
|
|
edb085 |
msg.data.ipcinfo.ipckeys[2] = rtdata->ipc_keys[2];
|
|
|
edb085 |
msg.data.ipcinfo.ipckeys[3] = rtdata->ipc_keys[3];
|
|
|
edb085 |
msg.data.ipcinfo.ipckeys[4] = rtdata->ipc_keys[4];
|
|
|
edb085 |
msg.data.ipcinfo.ipckeys[5] = rtdata->ipc_keys[5];
|
|
|
edb085 |
|
|
|
edb085 |
if ((status = __ntapi->zw_request_wait_reply_port(hport,&msg,&msg)))
|
|
|
edb085 |
return status;
|
|
|
edb085 |
else if (msg.data.ttyinfo.status)
|
|
|
edb085 |
return msg.data.ttyinfo.status;
|
|
|
edb085 |
|
|
|
edb085 |
return NT_STATUS_SUCCESS;
|
|
|
edb085 |
}
|
|
|
edb085 |
|
|
|
30d28d |
static int32_t __ipc_connect_by_attr(
|
|
|
30d28d |
void ** hport,
|
|
|
30d28d |
const nt_port_attr * attr,
|
|
|
30d28d |
nt_unicode_string * str,
|
|
|
30d28d |
void * hconn,
|
|
|
edb085 |
void ** hsection,
|
|
|
edb085 |
void ** secaddr,
|
|
|
edb085 |
size_t * secsize,
|
|
|
edb085 |
int fexisting)
|
|
|
30d28d |
{
|
|
|
30d28d |
int32_t status;
|
|
|
30d28d |
struct dalist_node_ex * node;
|
|
|
30d28d |
const nt_port_attr * conn;
|
|
|
30d28d |
nt_port_attr * nconn;
|
|
|
30d28d |
nt_ipc_conn * ipc;
|
|
|
30d28d |
intptr_t * hlock;
|
|
|
edb085 |
nt_rtdata * rtdata;
|
|
|
30d28d |
ntapi_internals * __internals;
|
|
|
30d28d |
|
|
|
30d28d |
/* init */
|
|
|
30d28d |
__internals = __ntapi_internals();
|
|
|
edb085 |
rtdata = __internals->rtdata;
|
|
|
30d28d |
|
|
|
30d28d |
/* lock */
|
|
|
30d28d |
hlock = &(__internals->hlock);
|
|
|
30d28d |
|
|
|
30d28d |
if (at_locked_cas(hlock,0,1))
|
|
|
30d28d |
return NT_STATUS_RESOURCE_NOT_OWNED;
|
|
|
30d28d |
|
|
|
30d28d |
/* already connected? */
|
|
|
30d28d |
node = (struct dalist_node_ex *)__internals->ipc_conns.head;
|
|
|
30d28d |
|
|
|
30d28d |
for (; node; node=node->next) {
|
|
|
30d28d |
ipc = (nt_ipc_conn *)&node->dblock;
|
|
|
30d28d |
conn = &ipc->attr;
|
|
|
30d28d |
|
|
|
30d28d |
if ((attr->keys.key[0] == conn->keys.key[0])
|
|
|
30d28d |
&& (attr->keys.key[1] == conn->keys.key[1])
|
|
|
30d28d |
&& (attr->keys.key[2] == conn->keys.key[2])
|
|
|
30d28d |
&& (attr->keys.key[3] == conn->keys.key[3])
|
|
|
30d28d |
&& (attr->keys.key[4] == conn->keys.key[4])
|
|
|
30d28d |
&& (attr->keys.key[5] == conn->keys.key[5])
|
|
|
30d28d |
&& !__ntapi->tt_guid_compare(
|
|
|
30d28d |
&attr->guid,
|
|
|
30d28d |
&conn->guid)) {
|
|
|
30d28d |
/* already connected */
|
|
|
93e3aa |
if (hconn && ((uintptr_t)hconn != node->key))
|
|
|
30d28d |
return __ipc_connect_return(
|
|
|
93e3aa |
hlock,NT_STATUS_CONTEXT_MISMATCH);
|
|
|
30d28d |
|
|
|
30d28d |
*hport = (void *)node->key;
|
|
|
30d28d |
*hsection = ipc->hsection;
|
|
|
30d28d |
*secaddr = ipc->secaddr;
|
|
|
30d28d |
*secsize = ipc->secsize;
|
|
|
30d28d |
|
|
|
30d28d |
return __ipc_connect_return(hlock,NT_STATUS_SUCCESS);
|
|
|
30d28d |
}
|
|
|
30d28d |
}
|
|
|
30d28d |
|
|
|
edb085 |
/* __ipc_get_port? */
|
|
|
edb085 |
if (fexisting)
|
|
|
edb085 |
return __ipc_connect_return(hlock,NT_STATUS_NOT_FOUND);
|
|
|
edb085 |
|
|
|
30d28d |
/* allocate list node */
|
|
|
30d28d |
if ((status = dalist_get_free_node(
|
|
|
30d28d |
&__internals->ipc_conns,
|
|
|
30d28d |
(void **)&node)))
|
|
|
30d28d |
return __ipc_connect_return(hlock,status);
|
|
|
30d28d |
|
|
|
30d28d |
/* connect as needed */
|
|
|
30d28d |
if (!hconn) {
|
|
|
30d28d |
status = __ntapi->zw_connect_port(
|
|
|
30d28d |
&hconn,str,0,0,0,0,0,0);
|
|
|
30d28d |
|
|
|
30d28d |
if (status) {
|
|
|
30d28d |
dalist_deposit_free_node(
|
|
|
30d28d |
&__internals->ipc_conns,
|
|
|
30d28d |
node);
|
|
|
30d28d |
|
|
|
30d28d |
return __ipc_connect_return(hlock,status);
|
|
|
30d28d |
}
|
|
|
30d28d |
}
|
|
|
30d28d |
|
|
|
edb085 |
/* server-to-server synchronization */
|
|
|
edb085 |
if (!rtdata->ipc_keys[0]) {
|
|
|
edb085 |
rtdata->ipc_keys[0] = __ntapi->tt_buffer_crc32(
|
|
|
edb085 |
(uint32_t)(uintptr_t)&hport,
|
|
|
edb085 |
(char *)__internals,sizeof(*__internals));
|
|
|
edb085 |
|
|
|
edb085 |
rtdata->ipc_keys[1] = __ntapi->tt_buffer_crc32(
|
|
|
edb085 |
(uint32_t)(uintptr_t)&hconn,
|
|
|
edb085 |
(char *)rtdata,sizeof(*rtdata));
|
|
|
edb085 |
|
|
|
edb085 |
rtdata->ipc_keys[2] = __ntapi->tt_buffer_crc32(
|
|
|
edb085 |
(uint32_t)(uintptr_t)&attr,
|
|
|
edb085 |
(char *)attr,sizeof(*attr));
|
|
|
edb085 |
|
|
|
edb085 |
rtdata->ipc_keys[3] = __ntapi->tt_buffer_crc32(
|
|
|
edb085 |
(uint32_t)(uintptr_t)&node,
|
|
|
edb085 |
(char *)node,sizeof(*node));
|
|
|
edb085 |
|
|
|
edb085 |
rtdata->ipc_keys[4] = __ntapi->tt_buffer_crc32(
|
|
|
edb085 |
(uint32_t)(uintptr_t)&str,
|
|
|
edb085 |
(char *)pe_get_peb_address(),
|
|
|
edb085 |
sizeof(nt_peb));
|
|
|
edb085 |
|
|
|
edb085 |
rtdata->ipc_keys[5] = __ntapi->tt_buffer_crc32(
|
|
|
edb085 |
(uint32_t)(uintptr_t)&conn,
|
|
|
edb085 |
(char *)pe_get_teb_address(),
|
|
|
edb085 |
sizeof(nt_tib));
|
|
|
edb085 |
}
|
|
|
edb085 |
|
|
|
edb085 |
if ((status = __ipc_set_client_keys(hconn,attr,rtdata))) {
|
|
|
edb085 |
__ntapi->zw_close(hconn);
|
|
|
edb085 |
dalist_deposit_free_node(&__internals->ipc_conns,node);
|
|
|
edb085 |
return __ipc_connect_return(hlock,status);
|
|
|
edb085 |
}
|
|
|
edb085 |
|
|
|
30d28d |
/* add connection */
|
|
|
30d28d |
node->key = (uintptr_t)hconn;
|
|
|
30d28d |
ipc = (nt_ipc_conn *)&node->dblock;
|
|
|
30d28d |
nconn = &ipc->attr;
|
|
|
30d28d |
|
|
|
30d28d |
__ntapi->tt_aligned_block_memcpy(
|
|
|
30d28d |
(uintptr_t *)nconn,
|
|
|
30d28d |
(uintptr_t *)attr,
|
|
|
30d28d |
sizeof(nt_port_attr));
|
|
|
30d28d |
|
|
|
30d28d |
ipc->hsection = 0;
|
|
|
30d28d |
ipc->secaddr = 0;
|
|
|
30d28d |
ipc->secsize = 0;
|
|
|
30d28d |
|
|
|
30d28d |
dalist_insert_node_by_key(
|
|
|
30d28d |
&__internals->ipc_conns,
|
|
|
30d28d |
node);
|
|
|
30d28d |
|
|
|
30d28d |
/* all done */
|
|
|
30d28d |
*hport = hconn;
|
|
|
30d28d |
*hsection = 0;
|
|
|
30d28d |
*secaddr = 0;
|
|
|
30d28d |
*secsize = 0;
|
|
|
30d28d |
|
|
|
30d28d |
return __ipc_connect_return(hlock,NT_STATUS_SUCCESS);
|
|
|
30d28d |
}
|
|
|
30d28d |
|
|
|
30d28d |
|
|
|
1b6aec |
int32_t __stdcall __ntapi_ipc_connect_section_by_attr(
|
|
|
30d28d |
__out void ** hport,
|
|
|
1b6aec |
__in nt_port_attr * attr,
|
|
|
1b6aec |
__out void ** hsection,
|
|
|
1b6aec |
__out void ** secaddr,
|
|
|
1b6aec |
__out size_t * secsize)
|
|
|
30d28d |
{
|
|
|
30d28d |
nt_port_name name;
|
|
|
30d28d |
nt_unicode_string str;
|
|
|
30d28d |
|
|
|
30d28d |
__ntapi->tt_port_name_from_attr(
|
|
|
30d28d |
&name,attr);
|
|
|
30d28d |
|
|
|
30d28d |
str.strlen = ((size_t)&(((nt_port_name *)0)->null_termination));
|
|
|
30d28d |
str.maxlen = 0;
|
|
|
30d28d |
str.buffer = &name.base_named_objects[0];
|
|
|
30d28d |
|
|
|
30d28d |
return __ipc_connect_by_attr(
|
|
|
30d28d |
hport,attr,&str,0,
|
|
|
edb085 |
hsection,secaddr,secsize,0);
|
|
|
30d28d |
}
|
|
|
30d28d |
|
|
|
30d28d |
|
|
|
1b6aec |
int32_t __stdcall __ntapi_ipc_connect_section_by_name(
|
|
|
30d28d |
__out void ** hport,
|
|
|
1b6aec |
__in nt_port_name * name,
|
|
|
1b6aec |
__out void ** hsection,
|
|
|
1b6aec |
__out void ** secaddr,
|
|
|
1b6aec |
__out size_t * secsize)
|
|
|
30d28d |
{
|
|
|
30d28d |
int32_t status;
|
|
|
30d28d |
nt_port_attr attr;
|
|
|
30d28d |
nt_unicode_string str;
|
|
|
30d28d |
|
|
|
30d28d |
if ((status = __ntapi->tt_port_attr_from_name(&attr,name)))
|
|
|
30d28d |
return status;
|
|
|
30d28d |
|
|
|
30d28d |
str.strlen = ((size_t)&(((nt_port_name *)0)->null_termination));
|
|
|
30d28d |
str.maxlen = 0;
|
|
|
30d28d |
str.buffer = &name->base_named_objects[0];
|
|
|
30d28d |
|
|
|
30d28d |
return __ipc_connect_by_attr(
|
|
|
30d28d |
hport,&attr,&str,0,
|
|
|
edb085 |
hsection,secaddr,secsize,0);
|
|
|
30d28d |
}
|
|
|
30d28d |
|
|
|
30d28d |
|
|
|
1b6aec |
int32_t __stdcall __ntapi_ipc_connect_section_by_symlink(
|
|
|
30d28d |
__out void ** hport,
|
|
|
1b6aec |
__in void * hsymlink,
|
|
|
1b6aec |
__out void ** hsection,
|
|
|
1b6aec |
__out void ** secaddr,
|
|
|
1b6aec |
__out size_t * secsize)
|
|
|
30d28d |
{
|
|
|
30d28d |
int32_t status;
|
|
|
30d28d |
nt_port_attr attr;
|
|
|
30d28d |
nt_port_name * name;
|
|
|
30d28d |
size_t namelen;
|
|
|
30d28d |
uintptr_t buffer[512/sizeof(uintptr_t)];
|
|
|
30d28d |
nt_unicode_string * str;
|
|
|
30d28d |
|
|
|
30d28d |
str = (nt_unicode_string *)buffer;
|
|
|
30d28d |
str->strlen = 0;
|
|
|
30d28d |
str->maxlen = sizeof(buffer) - sizeof(nt_unicode_string);
|
|
|
30d28d |
str->buffer = (wchar16_t *)&str[1];
|
|
|
30d28d |
|
|
|
30d28d |
if ((status = __ntapi->zw_query_symbolic_link_object(
|
|
|
30d28d |
hsymlink,str,&namelen)))
|
|
|
30d28d |
return status;
|
|
|
30d28d |
|
|
|
30d28d |
if (str->strlen != ((size_t)&(((nt_port_name *)0)->null_termination)))
|
|
|
30d28d |
return NT_STATUS_INVALID_PORT_ATTRIBUTES;
|
|
|
30d28d |
|
|
|
30d28d |
name = (nt_port_name *)str->buffer;
|
|
|
30d28d |
|
|
|
30d28d |
if ((status = __ntapi->tt_port_attr_from_name(&attr,name)))
|
|
|
30d28d |
return status;
|
|
|
30d28d |
|
|
|
30d28d |
return __ipc_connect_by_attr(
|
|
|
30d28d |
hport,&attr,str,0,
|
|
|
edb085 |
hsection,secaddr,secsize,0);
|
|
|
1b6aec |
}
|
|
|
1b6aec |
|
|
|
1b6aec |
|
|
|
1b6aec |
int32_t __stdcall __ntapi_ipc_connect_section_by_port(
|
|
|
1b6aec |
__in void * hconn,
|
|
|
1b6aec |
__in nt_port_attr * attr,
|
|
|
1b6aec |
__out void ** hsection,
|
|
|
1b6aec |
__out void ** secaddr,
|
|
|
1b6aec |
__out size_t * secsize)
|
|
|
1b6aec |
{
|
|
|
1b6aec |
return __ipc_connect_by_attr(
|
|
|
1b6aec |
&(void *){0},attr,0,hconn,
|
|
|
edb085 |
hsection,secaddr,secsize,0);
|
|
|
1b6aec |
}
|
|
|
1b6aec |
|
|
|
1b6aec |
|
|
|
1b6aec |
int32_t __stdcall __ntapi_ipc_connect_by_attr(
|
|
|
1b6aec |
__out void ** hport,
|
|
|
1b6aec |
__in nt_port_attr * attr)
|
|
|
1b6aec |
{
|
|
|
1b6aec |
return __ntapi_ipc_connect_section_by_attr(
|
|
|
1b6aec |
hport,attr,
|
|
|
1b6aec |
&(void *){0},
|
|
|
1b6aec |
&(void *){0},
|
|
|
1b6aec |
&(size_t){0});
|
|
|
1b6aec |
}
|
|
|
1b6aec |
|
|
|
1b6aec |
|
|
|
1b6aec |
int32_t __stdcall __ntapi_ipc_connect_by_name(
|
|
|
1b6aec |
__out void ** hport,
|
|
|
1b6aec |
__in nt_port_name * name)
|
|
|
1b6aec |
{
|
|
|
1b6aec |
return __ntapi_ipc_connect_section_by_name(
|
|
|
1b6aec |
hport,name,
|
|
|
1b6aec |
&(void *){0},
|
|
|
1b6aec |
&(void *){0},
|
|
|
1b6aec |
&(size_t){0});
|
|
|
1b6aec |
}
|
|
|
1b6aec |
|
|
|
1b6aec |
|
|
|
1b6aec |
int32_t __stdcall __ntapi_ipc_connect_by_symlink(
|
|
|
1b6aec |
__out void ** hport,
|
|
|
1b6aec |
__in void * hsymlink)
|
|
|
1b6aec |
{
|
|
|
1b6aec |
return __ntapi_ipc_connect_section_by_symlink(
|
|
|
1b6aec |
hport,hsymlink,
|
|
|
30d28d |
&(void *){0},
|
|
|
30d28d |
&(void *){0},
|
|
|
30d28d |
&(size_t){0});
|
|
|
30d28d |
}
|
|
|
30d28d |
|
|
|
30d28d |
|
|
|
30d28d |
int32_t __stdcall __ntapi_ipc_connect_by_port(
|
|
|
30d28d |
__in void * hconn,
|
|
|
30d28d |
__in nt_port_attr * attr)
|
|
|
30d28d |
{
|
|
|
1b6aec |
return __ntapi_ipc_connect_section_by_port(
|
|
|
1b6aec |
hconn,attr,
|
|
|
30d28d |
&(void *){0},
|
|
|
30d28d |
&(void *){0},
|
|
|
30d28d |
&(size_t){0});
|
|
|
30d28d |
}
|
|
|
30d28d |
|
|
|
30d28d |
|
|
|
30d28d |
int __ntapi_ipc_page_alloc(
|
|
|
30d28d |
struct dalist_ex * dlist,
|
|
|
30d28d |
void ** addr,
|
|
|
30d28d |
size_t * alloc_size)
|
|
|
30d28d |
{
|
|
|
30d28d |
int32_t status;
|
|
|
30d28d |
ntapi_internals * __internals;
|
|
|
30d28d |
|
|
|
30d28d |
__internals = __ntapi_internals();
|
|
|
30d28d |
|
|
|
30d28d |
if (__internals->ipc_page == __NT_IPC_PAGES)
|
|
|
30d28d |
return NT_STATUS_QUOTA_EXCEEDED;
|
|
|
30d28d |
|
|
|
30d28d |
if ((status = __ntapi->zw_allocate_virtual_memory(
|
|
|
30d28d |
NT_CURRENT_PROCESS_HANDLE,
|
|
|
30d28d |
addr,0,alloc_size,
|
|
|
30d28d |
NT_MEM_COMMIT,
|
|
|
30d28d |
NT_PAGE_READWRITE)))
|
|
|
30d28d |
return status;
|
|
|
30d28d |
|
|
|
30d28d |
dalist_deposit_memory_block(
|
|
|
30d28d |
dlist,*addr,*alloc_size);
|
|
|
30d28d |
|
|
|
30d28d |
__internals->ipc_pages[__internals->ipc_page++] = *addr;
|
|
|
30d28d |
|
|
|
30d28d |
return 0;
|
|
|
30d28d |
}
|
|
|
1b6aec |
|
|
|
1b6aec |
|
|
|
edb085 |
int32_t __stdcall __ntapi_ipc_get_port_by_attr(
|
|
|
edb085 |
__out void ** hport,
|
|
|
edb085 |
__in nt_port_attr * attr)
|
|
|
edb085 |
{
|
|
|
edb085 |
return __ipc_connect_by_attr(
|
|
|
edb085 |
hport,attr,0,0,
|
|
|
edb085 |
&(void *){0},
|
|
|
edb085 |
&(void *){0},
|
|
|
edb085 |
&(size_t){0},
|
|
|
edb085 |
1);
|
|
|
edb085 |
}
|
|
|
edb085 |
|
|
|
edb085 |
|
|
|
edb085 |
int32_t __stdcall __ntapi_ipc_get_port_section_by_attr(
|
|
|
edb085 |
__out void ** hport,
|
|
|
edb085 |
__in nt_port_attr * attr,
|
|
|
edb085 |
__out void ** hsection,
|
|
|
edb085 |
__out void ** section_addr,
|
|
|
edb085 |
__out size_t * section_size)
|
|
|
edb085 |
{
|
|
|
edb085 |
return __ipc_connect_by_attr(
|
|
|
edb085 |
hport,attr,0,0,
|
|
|
edb085 |
hsection,
|
|
|
edb085 |
section_addr,
|
|
|
edb085 |
section_size,
|
|
|
edb085 |
1);
|
|
|
edb085 |
}
|
|
|
edb085 |
|
|
|
edb085 |
|
|
|
1b6aec |
int32_t __stdcall __ntapi_ipc_init_section_by_port(
|
|
|
1b6aec |
__in void * hconn,
|
|
|
1b6aec |
__out void ** hsection,
|
|
|
1b6aec |
__out void ** secaddr,
|
|
|
1b6aec |
__out size_t * secsize)
|
|
|
1b6aec |
{
|
|
|
1b6aec |
int32_t status;
|
|
|
1b6aec |
nt_tty_section_info secinfo;
|
|
|
1b6aec |
nt_iosb iosb;
|
|
|
1b6aec |
struct dalist_node_ex * node;
|
|
|
1b6aec |
nt_ipc_conn * ipc;
|
|
|
1b6aec |
void * addr;
|
|
|
1b6aec |
size_t size;
|
|
|
1b6aec |
ntapi_internals * __internals;
|
|
|
1b6aec |
|
|
|
1b6aec |
/* init */
|
|
|
1b6aec |
__internals = __ntapi_internals();
|
|
|
1b6aec |
|
|
|
1b6aec |
/* lock */
|
|
|
1b6aec |
if (at_locked_cas(&__internals->hlock,0,1))
|
|
|
1b6aec |
return NT_STATUS_RESOURCE_NOT_OWNED;
|
|
|
1b6aec |
|
|
|
1b6aec |
/* connection node */
|
|
|
1b6aec |
if ((status = dalist_get_node_by_key(
|
|
|
1b6aec |
&__internals->ipc_conns,
|
|
|
1b6aec |
&node,(uintptr_t)hconn,
|
|
|
1b6aec |
DALIST_NODE_TYPE_EXISTING,
|
|
|
1b6aec |
&(uintptr_t){0})))
|
|
|
1b6aec |
return __ipc_connect_return(
|
|
|
1b6aec |
&__internals->hlock,
|
|
|
1b6aec |
NT_STATUS_INTERNAL_ERROR);
|
|
|
1b6aec |
|
|
|
1b6aec |
else if (!node)
|
|
|
1b6aec |
return NT_STATUS_NOT_FOUND;
|
|
|
1b6aec |
|
|
|
1b6aec |
else
|
|
|
1b6aec |
ipc = (nt_ipc_conn *)&node->dblock;
|
|
|
1b6aec |
|
|
|
1b6aec |
/* already mapped? */
|
|
|
1b6aec |
if (ipc->secaddr)
|
|
|
1b6aec |
return __ipc_connect_return(
|
|
|
1b6aec |
&__internals->hlock,
|
|
|
1b6aec |
NT_STATUS_SUCCESS);
|
|
|
1b6aec |
|
|
|
1b6aec |
/* section info */
|
|
|
1b6aec |
if ((status = __ntapi->tty_query_information_section(
|
|
|
1b6aec |
hconn,&iosb,&secinfo,0)))
|
|
|
1b6aec |
return __ipc_connect_return(
|
|
|
1b6aec |
&__internals->hlock,
|
|
|
1b6aec |
status);
|
|
|
1b6aec |
|
|
|
1b6aec |
/* map section */
|
|
|
1b6aec |
addr = 0;
|
|
|
1b6aec |
size = 0;
|
|
|
1b6aec |
|
|
|
1b6aec |
if ((status = __ntapi->zw_map_view_of_section(
|
|
|
1b6aec |
secinfo.section,
|
|
|
1b6aec |
NT_CURRENT_PROCESS_HANDLE,
|
|
|
1b6aec |
&addr,0,
|
|
|
1b6aec |
secinfo.section_size,0,&size,
|
|
|
1b6aec |
NT_VIEW_UNMAP,0,
|
|
|
1b6aec |
NT_PAGE_READWRITE)))
|
|
|
1b6aec |
return __ipc_connect_return(
|
|
|
1b6aec |
&__internals->hlock,
|
|
|
1b6aec |
status);
|
|
|
1b6aec |
|
|
|
1b6aec |
/* update */
|
|
|
1b6aec |
*hsection = secinfo.section;
|
|
|
1b6aec |
*secaddr = addr;
|
|
|
1b6aec |
*secsize = size;
|
|
|
1b6aec |
|
|
|
1b6aec |
/* all done */
|
|
|
1b6aec |
return __ipc_connect_return(
|
|
|
1b6aec |
&__internals->hlock,
|
|
|
1b6aec |
NT_STATUS_SUCCESS);
|
|
|
1b6aec |
}
|
|
|
1b6aec |
|
|
|
1b6aec |
|
|
|
1b6aec |
int32_t __stdcall __ntapi_ipc_disconnect_unmap_section_by_port(
|
|
|
1b6aec |
__in void * hconn)
|
|
|
1b6aec |
{
|
|
|
1b6aec |
int32_t status;
|
|
|
1b6aec |
struct dalist_node_ex * node;
|
|
|
1b6aec |
nt_ipc_conn * ipc;
|
|
|
1b6aec |
ntapi_internals * __internals;
|
|
|
1b6aec |
|
|
|
1b6aec |
/* init */
|
|
|
1b6aec |
__internals = __ntapi_internals();
|
|
|
1b6aec |
|
|
|
1b6aec |
/* lock */
|
|
|
1b6aec |
if (at_locked_cas(&__internals->hlock,0,1))
|
|
|
1b6aec |
return NT_STATUS_RESOURCE_NOT_OWNED;
|
|
|
1b6aec |
|
|
|
1b6aec |
/* connection node */
|
|
|
1b6aec |
if ((status = dalist_get_node_by_key(
|
|
|
1b6aec |
&__internals->ipc_conns,
|
|
|
1b6aec |
&node,(uintptr_t)hconn,
|
|
|
1b6aec |
DALIST_NODE_TYPE_EXISTING,
|
|
|
1b6aec |
&(uintptr_t){0})))
|
|
|
1b6aec |
return __ipc_connect_return(
|
|
|
1b6aec |
&__internals->hlock,
|
|
|
1b6aec |
NT_STATUS_INTERNAL_ERROR);
|
|
|
1b6aec |
|
|
|
1b6aec |
else if (!node)
|
|
|
1b6aec |
return __ipc_connect_return(
|
|
|
1b6aec |
&__internals->hlock,
|
|
|
1b6aec |
NT_STATUS_NOT_FOUND);
|
|
|
1b6aec |
|
|
|
1b6aec |
else
|
|
|
1b6aec |
ipc = (nt_ipc_conn *)&node->dblock;
|
|
|
1b6aec |
|
|
|
1b6aec |
/* unmap section */
|
|
|
1b6aec |
if (ipc->secaddr)
|
|
|
1b6aec |
__ntapi->zw_unmap_view_of_section(
|
|
|
1b6aec |
NT_CURRENT_PROCESS_HANDLE,
|
|
|
1b6aec |
ipc->secaddr);
|
|
|
1b6aec |
|
|
|
1b6aec |
/* close section */
|
|
|
1b6aec |
if (ipc->hsection)
|
|
|
1b6aec |
__ntapi->zw_close(ipc->hsection);
|
|
|
1b6aec |
|
|
|
1b6aec |
/* disconnect */
|
|
|
1b6aec |
__ntapi->zw_close(hconn);
|
|
|
1b6aec |
|
|
|
1b6aec |
/* remove node */
|
|
|
1b6aec |
dalist_discard_node(&__internals->ipc_conns,node);
|
|
|
1b6aec |
|
|
|
1b6aec |
return __ipc_connect_return(
|
|
|
1b6aec |
&__internals->hlock,
|
|
|
1b6aec |
NT_STATUS_SUCCESS);
|
|
|
1b6aec |
}
|