diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/internal/ntapi.c | 12 | ||||
-rw-r--r-- | src/internal/ntapi_fnapi.h | 12 | ||||
-rw-r--r-- | src/ipc/ntapi_ipc_connect.c | 69 | ||||
-rw-r--r-- | src/msq/ntapi_msq_connect.c | 353 | ||||
-rw-r--r-- | src/msq/ntapi_msq_fcntl.c | 42 | ||||
-rw-r--r-- | src/msq/ntapi_msq_fdio.c | 64 | ||||
-rw-r--r-- | src/msq/ntapi_msq_ioctl.c | 42 | ||||
-rw-r--r-- | src/msq/ntapi_msq_query.c | 70 | ||||
-rw-r--r-- | src/msq/ntapi_msq_recv.c | 109 | ||||
-rw-r--r-- | src/msq/ntapi_msq_send.c | 103 | ||||
-rw-r--r-- | src/msq/ntapi_msq_set.c | 68 | ||||
-rw-r--r-- | src/process/ntapi_tt_fork.c | 3 |
12 files changed, 947 insertions, 0 deletions
diff --git a/src/internal/ntapi.c b/src/internal/ntapi.c index a5d6113..0e9e6e0 100644 --- a/src/internal/ntapi.c +++ b/src/internal/ntapi.c @@ -203,6 +203,18 @@ static int32_t __fastcall __ntapi_init_once(ntapi_vtbl ** pvtbl) __ntapi->sem_cancel = __ntapi_sem_cancel; __ntapi->sem_free = __ntapi_sem_free; + /* nt_msq.h */ + __ntapi->msq_create = __ntapi_msq_create; + __ntapi->msq_open = __ntapi_msq_open; + __ntapi->msq_send = __ntapi_msq_send; + __ntapi->msq_recv = __ntapi_msq_recv; + __ntapi->msq_fcntl = __ntapi_msq_fcntl; + __ntapi->msq_ioctl = __ntapi_msq_ioctl; + __ntapi->msq_query = __ntapi_msq_query; + __ntapi->msq_set = __ntapi_msq_set; + __ntapi->msq_cancel = __ntapi_msq_cancel; + __ntapi->msq_free = __ntapi_msq_free; + /* nt_ldr.h */ __ntapi->ldr_load_system_dll = __ntapi_ldr_load_system_dll; __ntapi->ldr_create_state_snapshot = __ntapi_ldr_create_state_snapshot; diff --git a/src/internal/ntapi_fnapi.h b/src/internal/ntapi_fnapi.h index 1e770ce..8bafdbc 100644 --- a/src/internal/ntapi_fnapi.h +++ b/src/internal/ntapi_fnapi.h @@ -71,6 +71,18 @@ ntapi_sem_set __ntapi_sem_set; ntapi_sem_cancel __ntapi_sem_cancel; ntapi_sem_free __ntapi_sem_free; +/* nt_msq.h */ +ntapi_msq_create __ntapi_msq_create; +ntapi_msq_open __ntapi_msq_open; +ntapi_msq_send __ntapi_msq_send; +ntapi_msq_recv __ntapi_msq_recv; +ntapi_msq_fcntl __ntapi_msq_fcntl; +ntapi_msq_ioctl __ntapi_msq_ioctl; +ntapi_msq_query __ntapi_msq_query; +ntapi_msq_set __ntapi_msq_set; +ntapi_msq_cancel __ntapi_msq_cancel; +ntapi_msq_free __ntapi_msq_free; + /* nt_ldr */ ntapi_ldr_load_system_dll __ntapi_ldr_load_system_dll; ntapi_ldr_create_state_snapshot __ntapi_ldr_create_state_snapshot; diff --git a/src/ipc/ntapi_ipc_connect.c b/src/ipc/ntapi_ipc_connect.c index 6584f49..fc05efb 100644 --- a/src/ipc/ntapi_ipc_connect.c +++ b/src/ipc/ntapi_ipc_connect.c @@ -68,6 +68,54 @@ static void __ipc_init_ctrl_msg_semsvc( } +static void __ipc_init_ctrl_msg_msqctl( + const nt_port_attr * attr, + nt_tty_ipc_msg * msg) +{ + __ntapi->tt_aligned_block_memset( + (uintptr_t *)msg, + 0,sizeof(*msg)); + + msg->data.ipcinfo.ctrlsvc.type = attr->type; + msg->data.ipcinfo.ctrlsvc.subtype = attr->subtype; + + msg->data.ipcinfo.ctrlsvc.keys.key[0] = attr->keys.key[0]; + msg->data.ipcinfo.ctrlsvc.keys.key[1] = attr->keys.key[1]; + msg->data.ipcinfo.ctrlsvc.keys.key[2] = attr->keys.key[2]; + msg->data.ipcinfo.ctrlsvc.keys.key[3] = attr->keys.key[3]; + msg->data.ipcinfo.ctrlsvc.keys.key[4] = attr->keys.key[4]; + msg->data.ipcinfo.ctrlsvc.keys.key[5] = attr->keys.key[5]; + + __ntapi->tt_guid_copy( + &msg->data.ipcinfo.ctrlsvc.guid, + &attr->guid); +} + + +static void __ipc_init_ctrl_msg_msqsvc( + nt_rtdata * rtdata, + nt_tty_ipc_msg * msg) +{ + __ntapi->tt_aligned_block_memset( + (uintptr_t *)msg, + 0,sizeof(*msg)); + + msg->data.ipcinfo.ctrlsvc.type = rtdata->msqctl_type; + msg->data.ipcinfo.ctrlsvc.subtype = rtdata->msqctl_subtype; + + msg->data.ipcinfo.ctrlsvc.keys.key[0] = rtdata->msqctl_keys[0]; + msg->data.ipcinfo.ctrlsvc.keys.key[1] = rtdata->msqctl_keys[1]; + msg->data.ipcinfo.ctrlsvc.keys.key[2] = rtdata->msqctl_keys[2]; + msg->data.ipcinfo.ctrlsvc.keys.key[3] = rtdata->msqctl_keys[3]; + msg->data.ipcinfo.ctrlsvc.keys.key[4] = rtdata->msqctl_keys[4]; + msg->data.ipcinfo.ctrlsvc.keys.key[5] = rtdata->msqctl_keys[5]; + + __ntapi->tt_guid_copy( + &msg->data.ipcinfo.ctrlsvc.guid, + &rtdata->msqctl_guid); +} + + static void __ipc_init_ctrl_msg_ipcpeer( nt_rtdata * rtdata, nt_tty_ipc_msg * msg) @@ -123,6 +171,27 @@ static int32_t __ipc_set_client_keys( opcode = NT_TTY_SEM_FCNTL; break; + case NT_PORT_TYPE_MSQCTL: + if (rtdata->srv_type == NT_PORT_TYPE_MSQSVC) + __ipc_init_ctrl_msg_ipcpeer( + rtdata,&msg); + else + __ipc_init_ctrl_msg_msqctl( + attr,&msg); + + opcode = NT_TTY_MSQ_FCNTL; + break; + + case NT_PORT_TYPE_MSQSVC: + if (rtdata->srv_type == NT_PORT_TYPE_MSQCTL) + return NT_STATUS_SUCCESS; + + __ipc_init_ctrl_msg_msqsvc( + rtdata,&msg); + + opcode = NT_TTY_MSQ_FCNTL; + break; + default: return NT_STATUS_SUCCESS; } diff --git a/src/msq/ntapi_msq_connect.c b/src/msq/ntapi_msq_connect.c new file mode 100644 index 0000000..c4a0f98 --- /dev/null +++ b/src/msq/ntapi_msq_connect.c @@ -0,0 +1,353 @@ +/********************************************************/ +/* ntapi: Native API core library */ +/* Copyright (C) 2013--2017 Z. Gilboa */ +/* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */ +/********************************************************/ + +#include <psxtypes/psxtypes.h> +#include <ntapi/nt_file.h> +#include <ntapi/nt_string.h> +#include <ntapi/nt_atomic.h> +#include <ntapi/nt_port.h> +#include <ntapi/nt_ipc.h> +#include <ntapi/nt_msq.h> +#include <ntapi/ntapi.h> +#include "ntapi_impl.h" + +static const nt_guid g_msqpid = NT_IPC_GUID_MSQPID; +static const wchar16_t p_msqpid[6] = NT_IPC_OBJDIR_PREFIX_MSQPID; + +static int32_t __msqctl_get_service_attr( + nt_rtdata * rtdata, + nt_tty_service_info * msqctl) +{ + nt_iosb iosb; + + /* inherited runtime data? */ + if (rtdata->msqctl_keys[0]) { + msqctl->attr.ver_major = 0; + msqctl->attr.ver_minor = 0; + msqctl->attr.options = 0; + msqctl->attr.flags = 0; + + msqctl->attr.type = rtdata->msqctl_type; + msqctl->attr.subtype = rtdata->msqctl_subtype; + + msqctl->attr.keys.key[0] = rtdata->msqctl_keys[0]; + msqctl->attr.keys.key[1] = rtdata->msqctl_keys[1]; + msqctl->attr.keys.key[2] = rtdata->msqctl_keys[2]; + msqctl->attr.keys.key[3] = rtdata->msqctl_keys[3]; + msqctl->attr.keys.key[4] = rtdata->msqctl_keys[4]; + msqctl->attr.keys.key[5] = rtdata->msqctl_keys[5]; + + __ntapi->tt_guid_copy( + &msqctl->attr.guid, + &rtdata->msqctl_guid); + + return NT_STATUS_SUCCESS; + } + + /* obtain service info */ + return __ntapi->tty_query_information_service( + 0,&iosb,msqctl, + &(nt_guid)NT_PORT_GUID_MSQCTL, + 0,0); +} + +static int32_t __msqctl_server_connect( + nt_rtdata * rtdata, + nt_tty_service_info * msqctl) +{ + int32_t status; + + /* already cononected? */ + if (rtdata->hmsqctl) + return NT_STATUS_SUCCESS; + + /* connect */ + if ((status = __ntapi->ipc_connect_by_attr( + &rtdata->hmsqctl, + &msqctl->attr))) + return status; + + /* update */ + rtdata->msqctl_type = msqctl->attr.type; + rtdata->msqctl_subtype = msqctl->attr.subtype; + + rtdata->msqctl_keys[0] = msqctl->attr.keys.key[0]; + rtdata->msqctl_keys[1] = msqctl->attr.keys.key[1]; + rtdata->msqctl_keys[2] = msqctl->attr.keys.key[2]; + rtdata->msqctl_keys[3] = msqctl->attr.keys.key[3]; + rtdata->msqctl_keys[4] = msqctl->attr.keys.key[4]; + rtdata->msqctl_keys[5] = msqctl->attr.keys.key[5]; + + __ntapi->tt_guid_copy( + &rtdata->msqctl_guid, + &msqctl->attr.guid); + + return NT_STATUS_SUCCESS; +} + +static int32_t __msqpid_symlink_set( + nt_rtdata * rtdata, + nt_tty_service_info * msqctl) +{ + int32_t status; + void * hpiddir; + nt_port_name svcname; + nt_unicode_string str; + + if (rtdata->hmsqpid) + return NT_STATUS_SUCCESS; + + if (!rtdata->hmsqpiddir) { + if ((status = __ntapi->tt_open_ipc_object_directory( + &hpiddir, + NT_DIRECTORY_ALL_ACCESS, + p_msqpid,&g_msqpid))) + return status; + + if (at_locked_cas((intptr_t *)&rtdata->hmsqpiddir,0,(intptr_t)hpiddir)) + __ntapi->zw_close(hpiddir); + } + + __ntapi->tt_port_name_from_attr( + &svcname,&msqctl->attr); + + str.strlen = (uint16_t)(size_t)(&(((nt_port_name *)0)->null_termination)); + str.maxlen = sizeof(nt_port_name); + str.buffer = svcname.base_named_objects; + + return __ntapi->tt_create_ipc_object_directory_entry( + &rtdata->hmsqpid, + NT_SEC_STANDARD_RIGHTS_ALL, + rtdata->hmsqpiddir, + 0,&str, + pe_get_current_process_id()); + +} + +static int32_t __stdcall __msq_open( + void * hipc, + nt_msq_info * msq, + uint32_t access, + nt_object_attributes * oa, + nt_iosb * iosb, + uint32_t share, + uint32_t msqslots, + uint32_t key, + uint32_t id, + uint32_t opcode) +{ + int32_t status; + nt_tty_port_msg msg; + nt_iosb siosb; + nt_tty_service_info msqctl; + nt_runtime_data * rtdata; + + /* init */ + rtdata = (__ntapi_internals())->rtdata; + + /* msqctl service attributes */ + if (!rtdata->hmsqpid) + if ((status = __msqctl_get_service_attr(rtdata,&msqctl))) + return status; + + /* msqctl server */ + if ((status = __msqctl_server_connect(rtdata,&msqctl))) + return status; + + /* msqpid symlink */ + if ((status = __msqpid_symlink_set(rtdata,&msqctl))) + return status; + + /* hipc */ + if (!hipc && (opcode == NT_TTY_MSQ_ALLOC)) + hipc = (__ntapi_internals())->rtdata->hmsqctl; + + /* obtain msq info */ + __ntapi->tt_aligned_block_memset( + &msg,0,sizeof(msg)); + + if (!iosb) + iosb = &siosb; + + msg.header.msg_type = NT_LPC_NEW_MESSAGE; + msg.header.data_size = sizeof(nt_msq_info_msg) - sizeof(msg.header); + msg.header.msg_size = sizeof(msg); + msg.ttyinfo.opcode = opcode; + + msg.msqinfo.msqkey = (int32_t)key; + msg.msqinfo.msqid = (int32_t)id; + msg.msqinfo.msqslots = msqslots; + + msg.msqinfo.ntattr = oa->obj_attr; + msg.msqinfo.ntaccess = access; + msg.msqinfo.ntshare = share; + + if ((status = __ntapi->zw_request_wait_reply_port(hipc,&msg,&msg))) + return status; + else if (msg.ttyinfo.status) + return msg.ttyinfo.status; + + iosb->info = sizeof(msg.svcinfo); + iosb->status = NT_STATUS_SUCCESS; + + /* new msqueue? */ + if (opcode == NT_TTY_MSQ_ALLOC) + if ((status = __ntapi->ipc_connect_by_attr( + &hipc,&msg.svcinfo.attr))) + return status; + + /* all done */ + __ntapi->tt_aligned_block_memset( + (uintptr_t *)msq, + 0,sizeof(*msq)); + + msq->msqkey = msg.svcinfo.key; + msq->msqid = msg.svcinfo.id; + + msq->hport = hipc; + + return NT_STATUS_SUCCESS; +} + + +int32_t __ntapi_msq_create( + __in void * hport, + __out nt_msq_info * msq, + __in uint32_t access, + __in nt_object_attributes * oa, + __out nt_iosb * iosb, + __in uint32_t share, + __in uint32_t nslots) +{ + uint32_t key; + + /* validate */ + if (!oa->root_dir) + return NT_STATUS_DIRECTORY_SERVICE_REQUIRED; + + if (oa->obj_name && !oa->obj_name->strlen) { + key = 0; + + } else if (oa->obj_name) { + if (oa->obj_name->strlen != 8 * sizeof(wchar16_t)) + return NT_STATUS_OBJECT_NAME_INVALID; + + if (__ntapi->tt_hex_utf16_to_uint32(oa->obj_name->buffer,&key)) + return NT_STATUS_OBJECT_NAME_INVALID; + + } else { + key = 0; + } + + /* open msqueue */ + return __msq_open( + hport,msq,access, + oa,iosb,share,nslots, + key,0,NT_TTY_MSQ_ALLOC); +} + + +int32_t __stdcall __ntapi_msq_open( + __in void * hport, + __out nt_msq_info * msq, + __in uint32_t access, + __in nt_object_attributes * oa, + __out nt_iosb * iosb, + __in uint32_t share, + __in uint32_t nslots) +{ + int32_t status; + uint32_t key; + uint32_t id; + void * hsymlink; + nt_oa ipcoa; + void * hipc; + nt_rtdata * rtdata; + nt_tty_service_info msqctl; + + /* init */ + rtdata = (__ntapi_internals())->rtdata; + + /* validate */ + if (!oa->root_dir) + return NT_STATUS_DIRECTORY_SERVICE_REQUIRED; + + if (!oa->obj_name) + return NT_STATUS_INVALID_PARAMETER; + + if (oa->obj_name->strlen != 8 * sizeof(wchar16_t)) + return NT_STATUS_OBJECT_NAME_INVALID; + + if (__ntapi->tt_hex_utf16_to_uint32(oa->obj_name->buffer,&key)) + return NT_STATUS_OBJECT_NAME_INVALID; + + /* open symlink */ + ipcoa.len = sizeof(ipcoa); + ipcoa.root_dir = oa->root_dir; + ipcoa.obj_name = oa->obj_name; + ipcoa.obj_attr = 0; + ipcoa.sec_desc = oa->sec_desc; + ipcoa.sec_qos = oa->sec_qos; + + status = __ntapi->zw_open_symbolic_link_object( + &hsymlink, + NT_SEC_STANDARD_RIGHTS_READ | NT_GENERIC_READ, + &ipcoa); + + switch (status) { + case NT_STATUS_SUCCESS: + break; + + case NT_STATUS_OBJECT_NAME_NOT_FOUND: + case NT_STATUS_OBJECT_PATH_NOT_FOUND: + if (oa->obj_attr & NT_OBJ_OPENIF) + return __msq_open( + hport,msq,access, + oa,iosb,share,nslots, + key,0,NT_TTY_MSQ_ALLOC); + else + return status; + + default: + return status; + } + + /* msqctl service attributes */ + if (!rtdata->hmsqpid) + if ((status = __msqctl_get_service_attr(rtdata,&msqctl))) + return status; + + /* msqctl server */ + if ((status = __msqctl_server_connect(rtdata,&msqctl))) + return status; + + /* msqpid symlink */ + if ((status = __msqpid_symlink_set(rtdata,&msqctl))) + return status; + + /* ipc connect */ + status = __ntapi->ipc_connect_by_symlink( + &hipc,hsymlink); + + __ntapi->zw_close( + hsymlink); + + if (status) + return status; + + /* open by id? */ + if (oa->obj_attr & NT_OBJ_OPENLINK) { + id = key; + key = 0; + } else { + id = 0; + } + + return __msq_open( + hipc,msq,access, + oa,iosb,share,nslots, + key,id,NT_TTY_MSQ_OPEN); +} diff --git a/src/msq/ntapi_msq_fcntl.c b/src/msq/ntapi_msq_fcntl.c new file mode 100644 index 0000000..91efed2 --- /dev/null +++ b/src/msq/ntapi_msq_fcntl.c @@ -0,0 +1,42 @@ +/********************************************************/ +/* ntapi: Native API core library */ +/* Copyright (C) 2013--2017 Z. Gilboa */ +/* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */ +/********************************************************/ + +#include <psxtypes/psxtypes.h> +#include <ntapi/nt_file.h> +#include <ntapi/nt_string.h> +#include <ntapi/nt_atomic.h> +#include <ntapi/nt_port.h> +#include <ntapi/nt_ipc.h> +#include <ntapi/nt_msq.h> +#include <ntapi/ntapi.h> +#include "ntapi_impl.h" + +int32_t __stdcall __ntapi_msq_fcntl( + __in nt_msq_info * msq, + __in void * hevent __optional, + __in nt_io_apc_routine * apc_routine __optional, + __in void * apc_context __optional, + __out nt_iosb * iosb, + __in uint32_t fs_control_code, + __in void * input_buffer __optional, + __in uint32_t input_buffer_length, + __out void * output_buffer __optional, + __in uint32_t output_buffer_length) +{ + (void)msq; + (void)hevent; + (void)apc_routine; + (void)apc_context; + (void)iosb; + (void)fs_control_code; + (void)input_buffer; + (void)input_buffer_length; + (void)output_buffer; + (void)output_buffer_length; + + /* internal only */ + return NT_STATUS_NOT_IMPLEMENTED; +} diff --git a/src/msq/ntapi_msq_fdio.c b/src/msq/ntapi_msq_fdio.c new file mode 100644 index 0000000..d186bb6 --- /dev/null +++ b/src/msq/ntapi_msq_fdio.c @@ -0,0 +1,64 @@ +/********************************************************/ +/* ntapi: Native API core library */ +/* Copyright (C) 2013--2017 Z. Gilboa */ +/* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */ +/********************************************************/ + +#include <psxtypes/psxtypes.h> +#include <ntapi/nt_file.h> +#include <ntapi/nt_string.h> +#include <ntapi/nt_atomic.h> +#include <ntapi/nt_port.h> +#include <ntapi/nt_ipc.h> +#include <ntapi/nt_msq.h> +#include <ntapi/ntapi.h> +#include "ntapi_impl.h" + +static int32_t __msq_fdio( + nt_msq_info * msq, + nt_iosb * iosb, + uint32_t opcode) +{ + int32_t status; + nt_msq_info_msg msg; + + /* validate */ + if (!iosb) + return NT_STATUS_INVALID_PARAMETER; + + /* 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 = opcode; + + msg.data.msqinfo.msqkey = msq->msqkey; + msg.data.msqinfo.msqid = msq->msqid; + + if ((status = __ntapi->zw_request_wait_reply_port(msq->hport,&msg,&msg))) + return status; + else if (msg.data.ttyinfo.status) + return msg.data.ttyinfo.status; + + iosb->status = NT_STATUS_SUCCESS; + iosb->info = 0; + + return NT_STATUS_SUCCESS; +} + +int32_t __stdcall __ntapi_msq_cancel( + __in nt_msq_info * msq, + __out nt_iosb * iosb) +{ + return __msq_fdio(msq,iosb,NT_TTY_MSQ_CANCEL); +} + +int32_t __stdcall __ntapi_msq_free( + __in nt_msq_info * msq, + __out nt_iosb * iosb) +{ + return __msq_fdio(msq,iosb,NT_TTY_MSQ_FREE); +} diff --git a/src/msq/ntapi_msq_ioctl.c b/src/msq/ntapi_msq_ioctl.c new file mode 100644 index 0000000..6cdc49f --- /dev/null +++ b/src/msq/ntapi_msq_ioctl.c @@ -0,0 +1,42 @@ +/********************************************************/ +/* ntapi: Native API core library */ +/* Copyright (C) 2013--2017 Z. Gilboa */ +/* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */ +/********************************************************/ + +#include <psxtypes/psxtypes.h> +#include <ntapi/nt_file.h> +#include <ntapi/nt_string.h> +#include <ntapi/nt_atomic.h> +#include <ntapi/nt_port.h> +#include <ntapi/nt_ipc.h> +#include <ntapi/nt_msq.h> +#include <ntapi/ntapi.h> +#include "ntapi_impl.h" + +int32_t __stdcall __ntapi_msq_ioctl( + __in nt_msq_info * msq, + __in void * hevent __optional, + __in nt_io_apc_routine * apc_routine __optional, + __in void * apc_context __optional, + __out nt_iosb * iosb, + __in uint32_t io_control_code, + __in void * input_buffer __optional, + __in uint32_t input_buffer_length, + __out void * output_buffer __optional, + __in uint32_t output_buffer_length) +{ + (void)msq; + (void)hevent; + (void)apc_routine; + (void)apc_context; + (void)iosb; + (void)io_control_code; + (void)input_buffer; + (void)input_buffer_length; + (void)output_buffer; + (void)output_buffer_length; + + /* internal only */ + return NT_STATUS_NOT_IMPLEMENTED; +} diff --git a/src/msq/ntapi_msq_query.c b/src/msq/ntapi_msq_query.c new file mode 100644 index 0000000..28922ef --- /dev/null +++ b/src/msq/ntapi_msq_query.c @@ -0,0 +1,70 @@ +/********************************************************/ +/* ntapi: Native API core library */ +/* Copyright (C) 2013--2017 Z. Gilboa */ +/* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */ +/********************************************************/ + +#include <psxtypes/psxtypes.h> +#include <ntapi/nt_file.h> +#include <ntapi/nt_string.h> +#include <ntapi/nt_atomic.h> +#include <ntapi/nt_port.h> +#include <ntapi/nt_ipc.h> +#include <ntapi/nt_msq.h> +#include <ntapi/ntapi.h> +#include "ntapi_impl.h" + +int32_t __stdcall __ntapi_msq_query( + __in nt_msq_info * msq, + __out nt_io_status_block * iosb, + __out void * msq_info, + __in uint32_t msq_info_length, + __in int32_t msq_info_class) +{ + int32_t status; + nt_msq_info_msg msg; + + /* validate */ + if (!iosb) + return NT_STATUS_INVALID_PARAMETER; + + else if (!msq_info) + return NT_STATUS_INVALID_PARAMETER; + + else if (msq_info_length < sizeof(msg.data.msqinfo)) + return NT_STATUS_BUFFER_TOO_SMALL; + + else if (msq_info_class) + return NT_STATUS_INVALID_INFO_CLASS; + + /* 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_MSQ_QUERY; + + msg.data.msqinfo.msqkey = msq->msqkey; + msg.data.msqinfo.msqid = msq->msqid; + + if ((status = __ntapi->zw_request_wait_reply_port(msq->hport,&msg,&msg))) + return status; + else if (msg.data.ttyinfo.status) + return msg.data.ttyinfo.status; + + /* reply */ + if (msg.header.data_size != sizeof(msg.data)) + return NT_STATUS_UNEXPECTED_IO_ERROR; + + __ntapi->tt_generic_memcpy( + msq_info, + &msg.data.msqinfo, + sizeof(msg.data.msqinfo)); + + iosb->status = NT_STATUS_SUCCESS; + iosb->info = sizeof(msg.data.msqinfo); + + return NT_STATUS_SUCCESS; +} diff --git a/src/msq/ntapi_msq_recv.c b/src/msq/ntapi_msq_recv.c new file mode 100644 index 0000000..4da7cbe --- /dev/null +++ b/src/msq/ntapi_msq_recv.c @@ -0,0 +1,109 @@ +/********************************************************/ +/* ntapi: Native API core library */ +/* Copyright (C) 2013--2017 Z. Gilboa */ +/* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */ +/********************************************************/ + +#include <psxtypes/psxtypes.h> +#include <ntapi/nt_file.h> +#include <ntapi/nt_string.h> +#include <ntapi/nt_atomic.h> +#include <ntapi/nt_port.h> +#include <ntapi/nt_ipc.h> +#include <ntapi/nt_msq.h> +#include <ntapi/ntapi.h> +#include "ntapi_impl.h" + +static int32_t __msq_recv_return( + intptr_t * hlock, + int32_t status) +{ + at_store(hlock,0); + return status; +} + + +int32_t __stdcall __ntapi_msq_recv( + __in nt_msq_info * msq, + __in void * hevent __optional, + __in nt_io_apc_routine * apc_routine __optional, + __in void * apc_context __optional, + __out void * buffer, + __in size_t len, + __in intptr_t rank, + __in uint32_t options, + __out nt_io_status_block * iosb) +{ + int32_t status; + void * hsection; + void * secaddr; + size_t secsize; + nt_msq_info_msg msg; + intptr_t * hlock; + + /* validate */ + if (!iosb) + return NT_STATUS_INVALID_PARAMETER; + + else if (!len) + return NT_STATUS_INVALID_PARAMETER; + + /* section */ + if (msq->section_addr) { + hsection = msq->section; + secaddr = msq->section_addr; + secsize = msq->section_size; + + } else if ((status = __ntapi->ipc_init_section_by_port( + msq->hport,&hsection, + &secaddr,&secsize))) + return status; + + /* len */ + if (len > secsize) + len = secsize; + + /* lock */ + hlock = &(__ntapi_internals()->hlock); + + if (at_locked_cas(hlock,0,1)) + return NT_STATUS_RESOURCE_NOT_OWNED; + + /* 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_MSQ_RECV; + + msg.data.msqinfo.msqkey = msq->msqkey; + msg.data.msqinfo.msqid = msq->msqid; + msg.data.msqinfo.msqrpid = msq->msqrpid; + msg.data.msqinfo.msqrank = rank; + msg.data.msqinfo.section_addr = secaddr; + msg.data.msqinfo.section_size = len; + msg.data.msqinfo.ntoptions = options; + + msg.data.msqinfo.hevent = hevent; + msg.data.msqinfo.apc_routine = apc_routine; + msg.data.msqinfo.apc_context = apc_context; + msg.data.msqinfo.riosb = iosb; + + if ((status = __ntapi->zw_request_wait_reply_port(msq->hport,&msg,&msg))) + return __msq_recv_return(hlock,status); + else if (msg.data.ttyinfo.status) + return __msq_recv_return(hlock,msg.data.ttyinfo.status); + + /* msq data section to buffer */ + __ntapi->tt_generic_memcpy( + buffer,secaddr, + msg.data.msqinfo.ntiosb.info); + + /* all done */ + iosb->status = msg.data.msqinfo.ntiosb.status; + iosb->info = msg.data.msqinfo.ntiosb.info; + + return __msq_recv_return(hlock,NT_STATUS_SUCCESS); +} diff --git a/src/msq/ntapi_msq_send.c b/src/msq/ntapi_msq_send.c new file mode 100644 index 0000000..65443ea --- /dev/null +++ b/src/msq/ntapi_msq_send.c @@ -0,0 +1,103 @@ +/********************************************************/ +/* ntapi: Native API core library */ +/* Copyright (C) 2013--2017 Z. Gilboa */ +/* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */ +/********************************************************/ + +#include <psxtypes/psxtypes.h> +#include <ntapi/nt_file.h> +#include <ntapi/nt_string.h> +#include <ntapi/nt_atomic.h> +#include <ntapi/nt_port.h> +#include <ntapi/nt_ipc.h> +#include <ntapi/nt_msq.h> +#include <ntapi/ntapi.h> +#include "ntapi_impl.h" + +static int32_t __msq_send_return( + intptr_t * hlock, + int32_t status) +{ + at_store(hlock,0); + return status; +} + + +int32_t __stdcall __ntapi_msq_send( + __in nt_msq_info * msq, + __in void * hevent __optional, + __in nt_io_apc_routine * apc_routine __optional, + __in void * apc_context __optional, + __in const void * buffer, + __in size_t len, + __in intptr_t rank, + __in uint32_t options, + __out nt_io_status_block * iosb) +{ + int32_t status; + void * hsection; + void * secaddr; + size_t secsize; + nt_msq_info_msg msg; + intptr_t * hlock; + + /* validate */ + if (!iosb) + return NT_STATUS_INVALID_PARAMETER; + + /* section */ + if (msq->section_addr) { + hsection = msq->section; + secaddr = msq->section_addr; + secsize = msq->section_size; + + } else if ((status = __ntapi->ipc_init_section_by_port( + msq->hport,&hsection, + &secaddr,&secsize))) + return status; + + if (len > secsize) + return NT_STATUS_INFO_LENGTH_MISMATCH; + + /* lock */ + hlock = &(__ntapi_internals()->hlock); + + if (at_locked_cas(hlock,0,1)) + return NT_STATUS_RESOURCE_NOT_OWNED; + + /* msq data to section */ + __ntapi->tt_generic_memcpy( + secaddr,buffer,len); + + /* 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_MSQ_SEND; + + msg.data.msqinfo.msqkey = msq->msqkey; + msg.data.msqinfo.msqid = msq->msqid; + msg.data.msqinfo.msqspid = msq->msqspid; + msg.data.msqinfo.msqrank = rank; + msg.data.msqinfo.section_addr = secaddr; + msg.data.msqinfo.section_size = len; + msg.data.msqinfo.ntoptions = options; + + msg.data.msqinfo.hevent = hevent; + msg.data.msqinfo.apc_routine = apc_routine; + msg.data.msqinfo.apc_context = apc_context; + msg.data.msqinfo.riosb = iosb; + + if ((status = __ntapi->zw_request_wait_reply_port(msq->hport,&msg,&msg))) + return __msq_send_return(hlock,status); + else if (msg.data.ttyinfo.status) + return __msq_send_return(hlock,msg.data.ttyinfo.status); + + iosb->status = msg.data.msqinfo.ntiosb.status; + iosb->info = msg.data.msqinfo.ntiosb.info; + + return __msq_send_return(hlock,NT_STATUS_SUCCESS); +} diff --git a/src/msq/ntapi_msq_set.c b/src/msq/ntapi_msq_set.c new file mode 100644 index 0000000..2def716 --- /dev/null +++ b/src/msq/ntapi_msq_set.c @@ -0,0 +1,68 @@ +/********************************************************/ +/* ntapi: Native API core library */ +/* Copyright (C) 2013--2017 Z. Gilboa */ +/* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */ +/********************************************************/ + +#include <psxtypes/psxtypes.h> +#include <ntapi/nt_file.h> +#include <ntapi/nt_string.h> +#include <ntapi/nt_atomic.h> +#include <ntapi/nt_port.h> +#include <ntapi/nt_ipc.h> +#include <ntapi/nt_msq.h> +#include <ntapi/ntapi.h> +#include "ntapi_impl.h" + +int32_t __stdcall __ntapi_msq_set( + __in nt_msq_info * msq, + __out nt_io_status_block * iosb, + __in void * msq_info, + __in uint32_t msq_info_length, + __in int32_t msq_info_class) +{ + int32_t status; + nt_msq_info_msg msg; + + /* validate */ + if (!iosb) + return NT_STATUS_INVALID_PARAMETER; + + else if (!msq_info) + return NT_STATUS_INVALID_PARAMETER; + + else if (msq_info_length != sizeof(msg.data.msqinfo)) + return NT_STATUS_INFO_LENGTH_MISMATCH; + + else if (msq_info_class) + return NT_STATUS_INVALID_INFO_CLASS; + + /* 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_MSQ_SET; + + __ntapi->tt_generic_memcpy( + &msg.data.msqinfo, + msq_info, + sizeof(msg.data.msqinfo)); + + msg.data.msqinfo.msqkey = msq->msqkey; + msg.data.msqinfo.msqid = msq->msqid; + msg.data.msqinfo.section_size = msq_info_length; + + if ((status = __ntapi->zw_request_wait_reply_port(msq->hport,&msg,&msg))) + return status; + else if (msg.data.ttyinfo.status) + return msg.data.ttyinfo.status; + + /* reply */ + iosb->status = NT_STATUS_SUCCESS; + iosb->info = 0; + + return NT_STATUS_SUCCESS; +} diff --git a/src/process/ntapi_tt_fork.c b/src/process/ntapi_tt_fork.c index 68ae84b..485d98b 100644 --- a/src/process/ntapi_tt_fork.c +++ b/src/process/ntapi_tt_fork.c @@ -78,6 +78,9 @@ static intptr_t __fastcall __ntapi_tt_fork_finalize( rtdata->hsemctl = 0; rtdata->hsempid = 0; + rtdata->hmsqctl = 0; + rtdata->hmsqpid = 0; + rtdata->ipc_keys[0] = 0; rtdata->ipc_keys[1] = 0; rtdata->ipc_keys[2] = 0; |