From dd89bb8ad4fe184a34b5dbdda237e640fc82121b Mon Sep 17 00:00:00 2001 From: midipix Date: Mon, 27 Jul 2015 04:01:18 -0400 Subject: entered advanced internal development stage. --- src/pty/ntapi_pty_cancel.c | 46 +++++++++ src/pty/ntapi_pty_fd.c | 232 +++++++++++++++++++++++++++++++++++++++++++++ src/pty/ntapi_pty_io.c | 130 +++++++++++++++++++++++++ src/pty/ntapi_pty_ioctl.c | 92 ++++++++++++++++++ src/pty/ntapi_pty_query.c | 64 +++++++++++++ src/pty/ntapi_pty_set.c | 64 +++++++++++++ 6 files changed, 628 insertions(+) create mode 100644 src/pty/ntapi_pty_cancel.c create mode 100644 src/pty/ntapi_pty_fd.c create mode 100644 src/pty/ntapi_pty_io.c create mode 100644 src/pty/ntapi_pty_ioctl.c create mode 100644 src/pty/ntapi_pty_query.c create mode 100644 src/pty/ntapi_pty_set.c (limited to 'src/pty') diff --git a/src/pty/ntapi_pty_cancel.c b/src/pty/ntapi_pty_cancel.c new file mode 100644 index 0000000..4bfbb79 --- /dev/null +++ b/src/pty/ntapi_pty_cancel.c @@ -0,0 +1,46 @@ +/********************************************************/ +/* ntapi: Native API core library */ +/* Copyright (C) 2013,2014,2015 Z. Gilboa */ +/* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */ +/********************************************************/ + +#include +#include +#include +#include +#include "ntapi_impl.h" +#include "ntapi_pty.h" + +int32_t __stdcall __ntapi_pty_cancel( + nt_pty * pty, + nt_iosb * iosb) +{ + int32_t status; + nt_pty_io_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_PTY_CANCEL; + + msg.data.ioinfo.hpty = pty->hpty; + msg.data.ioinfo.luid.high = pty->luid.high; + msg.data.ioinfo.luid.low = pty->luid.low; + + __ntapi->tt_guid_copy( + &msg.data.ioinfo.guid, + &pty->guid); + + if ((status = __ntapi->zw_request_wait_reply_port(pty->hport,&msg,&msg))) + return status; + else if (msg.data.ttyinfo.status) + return msg.data.ttyinfo.status; + + iosb->info = msg.data.ioinfo.iosb.info; + iosb->status = msg.data.ioinfo.iosb.status; + + return NT_STATUS_SUCCESS; +} diff --git a/src/pty/ntapi_pty_fd.c b/src/pty/ntapi_pty_fd.c new file mode 100644 index 0000000..ee0b426 --- /dev/null +++ b/src/pty/ntapi_pty_fd.c @@ -0,0 +1,232 @@ +/********************************************************/ +/* ntapi: Native API core library */ +/* Copyright (C) 2013,2014,2015 Z. Gilboa */ +/* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */ +/********************************************************/ + +#include +#include +#include +#include +#include "ntapi_impl.h" +#include "ntapi_pty.h" + +static int32_t __stdcall __ntapi_pty_open_close( + nt_pty * pty, + nt_iosb * iosb, + int32_t opcode) +{ + int32_t status; + nt_pty_fd_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 = opcode; + + msg.data.fdinfo.hpty = pty->hpty; + msg.data.fdinfo.access = pty->access; + msg.data.fdinfo.flags = pty->flags; + msg.data.fdinfo.share = pty->share; + msg.data.fdinfo.options = pty->options; + + msg.data.fdinfo.luid.high = pty->luid.high; + msg.data.fdinfo.luid.low = pty->luid.low; + + __ntapi_tt_guid_copy( + &msg.data.fdinfo.guid, + &pty->guid); + + if ((status = __ntapi->zw_request_wait_reply_port(pty->hport,&msg,&msg))) + return status; + else if (msg.data.ttyinfo.status) + return msg.data.ttyinfo.status; + + pty->hpty = msg.data.fdinfo.hpty; + pty->section = msg.data.fdinfo.section; + pty->section_size = msg.data.fdinfo.section_size; + pty->luid.high = msg.data.fdinfo.luid.high; + pty->luid.low = msg.data.fdinfo.luid.low; + iosb->status = msg.data.ttyinfo.status; + iosb->info = 0; + + return NT_STATUS_SUCCESS; +} + + +static int32_t __fastcall __ntapi_pty_free(nt_pty * pty) +{ + void * addr; + size_t size; + + /* unmap section */ + if (pty->section_addr) + __ntapi->zw_unmap_view_of_section( + NT_CURRENT_PROCESS_HANDLE, + pty->section_addr); + + /* free control block */ + addr = pty->addr; + size = pty->size; + + return __ntapi->zw_free_virtual_memory( + NT_CURRENT_PROCESS_HANDLE, + &addr, + &size, + NT_MEM_RELEASE); +} + + +static int32_t __fastcall __ntapi_pty_fail(nt_pty * pty,int32_t status) +{ + __ntapi_pty_free(pty); + return status; +} + + +static int32_t __fastcall __ntapi_pty_alloc(nt_pty ** pty) +{ + int32_t status; + nt_pty * ctx; + size_t ctx_size; + + /* allocate control block */ + ctx = 0; + ctx_size = sizeof(nt_pty); + + if ((status = __ntapi->zw_allocate_virtual_memory( + NT_CURRENT_PROCESS_HANDLE, + (void **)&ctx, + 0,&ctx_size, + NT_MEM_COMMIT, + NT_PAGE_READWRITE))) + return status; + + /* init control block */ + __ntapi->tt_aligned_block_memset( + ctx,0,ctx_size); + + ctx->addr = ctx; + ctx->size = ctx_size; + + *pty = ctx; + return NT_STATUS_SUCCESS; +} + +static int32_t __ntapi_pty_connect( + void * hport, + nt_pty * ctx, + nt_iosb * iosb) +{ + int32_t status; + + ctx->hport = hport + ? hport + : __ntapi_internals()->hport_tty_session; + + /* request */ + iosb = iosb ? iosb : &ctx->iosb; + + if ((status = __ntapi_pty_open_close(ctx,iosb,NT_TTY_PTY_OPEN))) + return __ntapi_pty_fail(ctx,status); + + /* map section */ + if ((status = __ntapi->zw_map_view_of_section( + ctx->section, + NT_CURRENT_PROCESS_HANDLE, + &ctx->section_addr, + 0,ctx->section_size, + 0,&ctx->section_size, + NT_VIEW_UNMAP,0, + NT_PAGE_READWRITE))) + return __ntapi_pty_fail(ctx,status); + + /* assume conforming clients, config for single lock try */ + __ntapi->tt_sync_block_init(&ctx->sync[__PTY_READ],0,0,1,0,0); + __ntapi->tt_sync_block_init(&ctx->sync[__PTY_WRITE],0,0,1,0,0); + + return NT_STATUS_SUCCESS; +} + + +int32_t __stdcall __ntapi_pty_open( + void * hport, + nt_pty ** pty, + uint32_t desired_access, + nt_object_attributes* obj_attr, + nt_iosb * iosb, + uint32_t share_access, + uint32_t open_options) +{ + int32_t status; + uint32_t hash; + nt_guid guid; + nt_uuid_str_utf16 * guid_str; + nt_pty * ctx; + + if (!obj_attr || !obj_attr->obj_name || !obj_attr->obj_name->buffer) + return NT_STATUS_INVALID_PARAMETER; + + if (obj_attr->obj_name->strlen != __DEVICE_PATH_PREFIX_LEN + sizeof(nt_guid_str_utf16)) + return NT_STATUS_OBJECT_PATH_INVALID; + + hash = __ntapi->tt_buffer_crc32( + 0, + obj_attr->obj_name->buffer, + __DEVICE_PATH_PREFIX_LEN); + + if (hash != __DEVICE_PATH_PREFIX_HASH) + return NT_STATUS_OBJECT_PATH_INVALID; + + guid_str = (nt_uuid_str_utf16 *) + ((uintptr_t)obj_attr->obj_name->buffer + __DEVICE_PATH_PREFIX_LEN); + + if (__ntapi->tt_utf16_string_to_guid(guid_str,&guid)) + return NT_STATUS_OBJECT_NAME_INVALID; + + /* control block */ + if ((status = __ntapi_pty_alloc(&ctx))) + return status; + + __ntapi_tt_guid_copy( + &ctx->guid, + &guid); + + ctx->access = desired_access; + ctx->flags = obj_attr->obj_attr; + ctx->share = share_access; + ctx->options = open_options; + + /* pts */ + if (obj_attr->root_dir) { + ctx->luid.high = ((nt_pty *)obj_attr->root_dir)->luid.high; + ctx->luid.low = ((nt_pty *)obj_attr->root_dir)->luid.low; + } + + if ((status = __ntapi_pty_connect(hport,ctx,iosb))) + return status; + + *pty = ctx; + + return NT_STATUS_SUCCESS; +} + +int32_t __stdcall __ntapi_pty_reopen( + __in void * hport, + __in nt_pty * pty) +{ + return __ntapi_pty_connect(hport,pty,0); +} + +int32_t __stdcall __ntapi_pty_close(nt_pty * pty) +{ + if (!pty || (pty->addr != pty)) + return NT_STATUS_INVALID_PARAMETER; + + __ntapi_pty_open_close( + pty,&pty->iosb,NT_TTY_PTY_CLOSE); + + return __ntapi_pty_free(pty); +} diff --git a/src/pty/ntapi_pty_io.c b/src/pty/ntapi_pty_io.c new file mode 100644 index 0000000..f110371 --- /dev/null +++ b/src/pty/ntapi_pty_io.c @@ -0,0 +1,130 @@ +/********************************************************/ +/* ntapi: Native API core library */ +/* Copyright (C) 2013,2014,2015 Z. Gilboa */ +/* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */ +/********************************************************/ + +#include +#include +#include +#include +#include "ntapi_impl.h" +#include "ntapi_pty.h" + +static int32_t __stdcall __ntapi_pty_read_write( + nt_pty * pty, + void * hevent, + nt_io_apc_routine * apc_routine, + void * apc_context, + nt_iosb * iosb, + void * buffer, + size_t nbytes, + nt_large_integer * offset, + uint32_t * key, + int32_t opcode) +{ + int32_t status; + nt_pty_io_msg msg; + off_t soffset; + int mode; + + mode = opcode - NT_TTY_PTY_READ; + soffset = mode * pty->section_size / 2; + + if (offset && offset->quad) + return NT_STATUS_INVALID_PARAMETER; + + else if (__ntapi->tt_sync_block_lock(&pty->sync[mode],1,0,0)) + return NT_STATUS_RESOURCE_NOT_OWNED; + + nbytes = nbytes <= pty->section_size / 2 + ? nbytes + : pty->section_size / 2; + + __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.ioinfo.hpty = pty->hpty; + msg.data.ioinfo.hevent = hevent; + msg.data.ioinfo.apc_routine = apc_routine; + msg.data.ioinfo.apc_context = apc_context; + msg.data.ioinfo.key = key ? *key : 0; + + msg.data.ioinfo.luid.high = pty->luid.high; + msg.data.ioinfo.luid.low = pty->luid.low; + + msg.data.ioinfo.riosb = iosb; + msg.data.ioinfo.raddr = buffer; + + __ntapi->tt_guid_copy( + &msg.data.ioinfo.guid, + &pty->guid); + + msg.data.ioinfo.nbytes = nbytes; + msg.data.ioinfo.offset = soffset; + + if (mode == __PTY_WRITE) + __ntapi->tt_generic_memcpy( + (char *)pty->section_addr + soffset, + (char *)buffer, + nbytes); + + if ((status = __ntapi->zw_request_wait_reply_port(pty->hport,&msg,&msg))) + return status; + else if (msg.data.ttyinfo.status) + return msg.data.ttyinfo.status; + + if (mode == __PTY_READ) + __ntapi->tt_generic_memcpy( + (char *)buffer, + (char *)pty->section_addr + soffset, + msg.data.ioinfo.iosb.info); + + iosb->info = msg.data.ioinfo.iosb.info; + iosb->status = msg.data.ioinfo.iosb.status; + + return NT_STATUS_SUCCESS; +} + + +int32_t __stdcall __ntapi_pty_read( + __in nt_pty * pty, + __in void * hevent __optional, + __in nt_io_apc_routine * apc_routine __optional, + __in void * apc_context __optional, + __out nt_iosb * iosb, + __out void * buffer, + __in uint32_t nbytes, + __in nt_large_integer * offset __optional, + __in uint32_t * key __optional) +{ + return __ntapi_pty_read_write( + pty, + hevent,apc_routine,apc_context, + iosb,buffer,nbytes,offset,key, + NT_TTY_PTY_READ); +} + + +int32_t __stdcall __ntapi_pty_write( + __in nt_pty * pty, + __in void * hevent __optional, + __in nt_io_apc_routine * apc_routine __optional, + __in void * apc_context __optional, + __out nt_iosb * iosb, + __in void * buffer, + __in uint32_t nbytes, + __in nt_large_integer * offset __optional, + __in uint32_t * key __optional) +{ + return __ntapi_pty_read_write( + pty, + hevent,apc_routine,apc_context, + iosb,buffer,nbytes,offset,key, + NT_TTY_PTY_WRITE); +} diff --git a/src/pty/ntapi_pty_ioctl.c b/src/pty/ntapi_pty_ioctl.c new file mode 100644 index 0000000..f828753 --- /dev/null +++ b/src/pty/ntapi_pty_ioctl.c @@ -0,0 +1,92 @@ +/********************************************************/ +/* ntapi: Native API core library */ +/* Copyright (C) 2013,2014,2015 Z. Gilboa */ +/* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */ +/********************************************************/ + +#include +#include +#include +#include +#include +#include "ntapi_impl.h" +#include "ntapi_pty.h" + +int32_t __stdcall __ntapi_pty_ioctl( + nt_pty * pty, + void * hevent __optional, + nt_io_apc_routine * apc_routine __optional, + void * apc_context __optional, + nt_iosb * iosb, + uint32_t ctlcode, + void * input_buffer __optional, + uint32_t input_buffer_length, + void * output_buffer __optional, + uint32_t output_buffer_length) +{ + int32_t status; + nt_pty_sigctl_msg msg; + nt_tty_sigctl_info * input; + nt_tty_sigctl_info * output; + + if ((uintptr_t)input_buffer % sizeof(uintptr_t)) + return NT_STATUS_DATATYPE_MISALIGNMENT_ERROR; + else if (input_buffer_length != sizeof(nt_tty_sigctl_info)) + return NT_STATUS_INVALID_BUFFER_SIZE; + else if (!output_buffer) + return NT_STATUS_ACCESS_DENIED; + else if ((uintptr_t)output_buffer % sizeof(uintptr_t)) + return NT_STATUS_DATATYPE_MISALIGNMENT_ERROR; + else if (output_buffer_length < sizeof(nt_tty_sigctl_info)) + return NT_STATUS_BUFFER_TOO_SMALL; + + input = (nt_tty_sigctl_info *)input_buffer; + output = (nt_tty_sigctl_info *)output_buffer; + + __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_PTY_IOCTL; + + msg.data.ctlinfo.hpty = pty->hpty; + msg.data.ctlinfo.luid.high = pty->luid.high; + msg.data.ctlinfo.luid.low = pty->luid.low; + msg.data.ctlinfo.ctlcode = ctlcode; + + __ntapi->tt_guid_copy( + &msg.data.ctlinfo.guid, + &pty->guid); + + msg.data.ctlinfo.ctxarg[0] = input->ctxarg[0]; + msg.data.ctlinfo.ctxarg[1] = input->ctxarg[1]; + msg.data.ctlinfo.ctxarg[2] = input->ctxarg[2]; + msg.data.ctlinfo.ctxarg[3] = input->ctxarg[3]; + + __ntapi->tt_generic_memcpy( + (char *)&input->terminfo, + (char *)&msg.data.ctlinfo.terminfo, + sizeof(input->terminfo)); + + __ntapi->tt_generic_memcpy( + (char *)&input->winsize, + (char *)&msg.data.ctlinfo.winsize, + sizeof(input->winsize)); + + if ((status = __ntapi->zw_request_wait_reply_port(pty->hport,&msg,&msg))) + return status; + else if (msg.data.ttyinfo.status) + return msg.data.ttyinfo.status; + + __ntapi->tt_aligned_block_memcpy( + (uintptr_t *)output, + (uintptr_t *)&msg.data.ctlinfo, + sizeof(*output)); + + iosb->info = msg.data.ctlinfo.iosb.info; + iosb->status = msg.data.ctlinfo.iosb.status; + + return NT_STATUS_SUCCESS; +} diff --git a/src/pty/ntapi_pty_query.c b/src/pty/ntapi_pty_query.c new file mode 100644 index 0000000..57d31ee --- /dev/null +++ b/src/pty/ntapi_pty_query.c @@ -0,0 +1,64 @@ +/********************************************************/ +/* ntapi: Native API core library */ +/* Copyright (C) 2013,2014,2015 Z. Gilboa */ +/* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */ +/********************************************************/ + +#include +#include +#include +#include +#include "ntapi_impl.h" +#include "ntapi_pty.h" + +int32_t __stdcall __ntapi_pty_query( + nt_pty * pty, + nt_io_status_block * iosb, + void * pty_info, + uint32_t pty_info_length, + nt_pty_info_class pty_info_class) +{ + int32_t status; + nt_pty_sigctl_msg msg; + uintptr_t * info; + + if ((pty_info_class=NT_PTY_INFORMATION_CAP)) + return NT_STATUS_INVALID_INFO_CLASS; + else if (pty_info_class == NT_PTY_BASIC_INFORMATION) + return NT_STATUS_NOT_IMPLEMENTED; + else if ((pty_info_class == NT_PTY_CLIENT_INFORMATION) && (pty_info_length != sizeof(nt_pty_client_info))) + return NT_STATUS_INVALID_PARAMETER; + + __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_PTY_QUERY; + + msg.data.ctlinfo.hpty = pty->hpty; + msg.data.ctlinfo.luid.high = pty->luid.high; + msg.data.ctlinfo.luid.low = pty->luid.low; + msg.data.ctlinfo.ctlcode = pty_info_class; + + __ntapi->tt_guid_copy( + &msg.data.ctlinfo.guid, + &pty->guid); + + if ((status = __ntapi->zw_request_wait_reply_port(pty->hport,&msg,&msg))) + return status; + else if (msg.data.ttyinfo.status) + return msg.data.ttyinfo.status; + + iosb->info = msg.data.ctlinfo.iosb.info; + iosb->status = msg.data.ctlinfo.iosb.status; + + info = (uintptr_t *)pty_info; + info[0] = msg.data.ctlinfo.ctxarg[0]; + info[1] = msg.data.ctlinfo.ctxarg[1]; + info[2] = msg.data.ctlinfo.ctxarg[2]; + info[3] = msg.data.ctlinfo.ctxarg[3]; + + return NT_STATUS_SUCCESS; +} diff --git a/src/pty/ntapi_pty_set.c b/src/pty/ntapi_pty_set.c new file mode 100644 index 0000000..1543e7c --- /dev/null +++ b/src/pty/ntapi_pty_set.c @@ -0,0 +1,64 @@ +/********************************************************/ +/* ntapi: Native API core library */ +/* Copyright (C) 2013,2014,2015 Z. Gilboa */ +/* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */ +/********************************************************/ + +#include +#include +#include +#include +#include "ntapi_impl.h" +#include "ntapi_pty.h" + +int32_t __stdcall __ntapi_pty_set( + nt_pty * pty, + nt_io_status_block * iosb, + void * pty_info, + uint32_t pty_info_length, + nt_pty_info_class pty_info_class) +{ + int32_t status; + nt_pty_sigctl_msg msg; + uintptr_t * info; + + if ((pty_info_class=NT_PTY_INFORMATION_CAP)) + return NT_STATUS_INVALID_INFO_CLASS; + else if (pty_info_class == NT_PTY_BASIC_INFORMATION) + return NT_STATUS_NOT_IMPLEMENTED; + else if ((pty_info_class == NT_PTY_CLIENT_INFORMATION) && (pty_info_length != sizeof(nt_pty_client_info))) + return NT_STATUS_INVALID_PARAMETER; + + __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_PTY_SET; + + msg.data.ctlinfo.hpty = pty->hpty; + msg.data.ctlinfo.luid.high = pty->luid.high; + msg.data.ctlinfo.luid.low = pty->luid.low; + msg.data.ctlinfo.ctlcode = pty_info_class; + + __ntapi->tt_guid_copy( + &msg.data.ctlinfo.guid, + &pty->guid); + + info = (uintptr_t *)pty_info; + msg.data.ctlinfo.ctxarg[0] = info[0]; + msg.data.ctlinfo.ctxarg[1] = info[1]; + msg.data.ctlinfo.ctxarg[2] = info[2]; + msg.data.ctlinfo.ctxarg[3] = info[3]; + + if ((status = __ntapi->zw_request_wait_reply_port(pty->hport,&msg,&msg))) + return status; + else if (msg.data.ttyinfo.status) + return msg.data.ttyinfo.status; + + iosb->info = msg.data.ctlinfo.iosb.info; + iosb->status = msg.data.ctlinfo.iosb.status; + + return NT_STATUS_SUCCESS; +} -- cgit v1.2.3