From efc01e81a13322864775f13003a22c786dc357ed Mon Sep 17 00:00:00 2001 From: midipix Date: Fri, 14 Aug 2015 00:38:16 +0300 Subject: pty inheritance: client-side implementation. --- include/ntapi/nt_tty.h | 29 +++++++++++++++++++++- include/ntapi/ntapi.h | 1 + src/internal/ntapi.c | 1 + src/internal/ntapi_fnapi.h | 1 + src/pty/ntapi_pty_fd.c | 45 +++++++++++++++++++++++++++++++++ src/pty/ntapi_pty_query.c | 62 ++++++++++++++++++++++++++++++++++++---------- src/pty/ntapi_pty_set.c | 2 ++ 7 files changed, 127 insertions(+), 14 deletions(-) diff --git a/include/ntapi/nt_tty.h b/include/ntapi/nt_tty.h index 4783eb6..8f33bc7 100644 --- a/include/ntapi/nt_tty.h +++ b/include/ntapi/nt_tty.h @@ -68,10 +68,15 @@ typedef enum _nt_tty_info_class { typedef enum _nt_pty_info_class { NT_PTY_BASIC_INFORMATION, NT_PTY_CLIENT_INFORMATION, + NT_PTY_INHERIT_INFORMATION, NT_PTY_INFORMATION_CAP } nt_pty_info_class; +/* client process registration flags */ +#define NT_TTY_INHERIT_HANDLES 0x0001 + + typedef struct __attr_ptr_size_aligned__ _nt_tty_msg_info { uintptr_t msg_id; uint32_t opcode; @@ -166,6 +171,23 @@ typedef struct __attr_ptr_size_aligned__ _nt_pty_client_info { } nt_pty_client_info; +typedef struct __attr_ptr_size_aligned__ _nt_pty_inherit_info { + void * hpty; + nt_guid guid; + nt_luid luid; + + union { + struct { + uint32_t access; + uint32_t flags; + uint32_t share; + uint32_t options; + }; + + uintptr_t any[4]; + }; +} nt_pty_inherit_info; + typedef struct __attr_ptr_size_aligned__ _nt_tty_session_info { int32_t pid; int32_t pgid; @@ -173,7 +195,6 @@ typedef struct __attr_ptr_size_aligned__ _nt_tty_session_info { int32_t reserved; } nt_tty_session_info; - typedef struct __attr_ptr_size_aligned__ _nt_tty_register_msg { nt_port_message header; struct { @@ -341,6 +362,12 @@ typedef int32_t __stdcall ntapi_pty_reopen( __in nt_pty * pty); +typedef int32_t __stdcall ntapi_pty_inherit( + __in void * hport, + __out nt_pty ** pty, + __in nt_pty_client_info * client_info); + + typedef int32_t __stdcall ntapi_pty_close( __in nt_pty * pty); diff --git a/include/ntapi/ntapi.h b/include/ntapi/ntapi.h index 7978786..d6e5f65 100644 --- a/include/ntapi/ntapi.h +++ b/include/ntapi/ntapi.h @@ -524,6 +524,7 @@ typedef struct _ntapi_vtbl { ntapi_tty_vms_request * tty_vms_request; ntapi_pty_open * pty_open; ntapi_pty_reopen * pty_reopen; + ntapi_pty_inherit * pty_inherit; ntapi_pty_close * pty_close; ntapi_pty_read * pty_read; ntapi_pty_write * pty_write; diff --git a/src/internal/ntapi.c b/src/internal/ntapi.c index 2340c47..f554b62 100644 --- a/src/internal/ntapi.c +++ b/src/internal/ntapi.c @@ -288,6 +288,7 @@ static int32_t __fastcall __ntapi_init_once(ntapi_vtbl ** pvtbl) __ntapi->tty_vms_request = __ntapi_tty_vms_request; __ntapi->pty_open = __ntapi_pty_open; __ntapi->pty_reopen = __ntapi_pty_reopen; + __ntapi->pty_inherit = __ntapi_pty_inherit; __ntapi->pty_close = __ntapi_pty_close; __ntapi->pty_read = __ntapi_pty_read; __ntapi->pty_write = __ntapi_pty_write; diff --git a/src/internal/ntapi_fnapi.h b/src/internal/ntapi_fnapi.h index 4474334..2fb8b62 100644 --- a/src/internal/ntapi_fnapi.h +++ b/src/internal/ntapi_fnapi.h @@ -180,6 +180,7 @@ ntapi_tty_vms_query __ntapi_tty_vms_query; ntapi_tty_vms_request __ntapi_tty_vms_request; ntapi_pty_open __ntapi_pty_open; ntapi_pty_reopen __ntapi_pty_reopen; +ntapi_pty_inherit __ntapi_pty_inherit; ntapi_pty_close __ntapi_pty_close; ntapi_pty_read __ntapi_pty_read; ntapi_pty_write __ntapi_pty_write; diff --git a/src/pty/ntapi_pty_fd.c b/src/pty/ntapi_pty_fd.c index ee0b426..bb7e77e 100644 --- a/src/pty/ntapi_pty_fd.c +++ b/src/pty/ntapi_pty_fd.c @@ -213,6 +213,51 @@ int32_t __stdcall __ntapi_pty_open( return NT_STATUS_SUCCESS; } +int32_t __stdcall __ntapi_pty_inherit( + __in void * hport, + __out nt_pty ** pty, + __in nt_pty_client_info * client_info) +{ + int32_t status; + nt_iosb iosb; + nt_pty_inherit_info inherit; + nt_pty * ctx; + + inherit.any[0] = client_info->any[0]; + inherit.any[1] = client_info->any[1]; + inherit.any[2] = client_info->any[2]; + inherit.any[3] = client_info->any[3]; + + if ((status = __ntapi_pty_query( + hport,&iosb, + &inherit,sizeof(inherit), + NT_PTY_INHERIT_INFORMATION))) + return status; + + /* control block */ + if ((status = __ntapi_pty_alloc(&ctx))) + return status; + + __ntapi_tt_guid_copy( + &ctx->guid, + &inherit.guid); + + ctx->access = inherit.access; + ctx->flags = inherit.flags; + ctx->share = inherit.share; + ctx->options = inherit.options; + + ctx->luid.low = inherit.luid.low; + ctx->luid.high = inherit.luid.high; + + 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) diff --git a/src/pty/ntapi_pty_query.c b/src/pty/ntapi_pty_query.c index 57d31ee..06feace 100644 --- a/src/pty/ntapi_pty_query.c +++ b/src/pty/ntapi_pty_query.c @@ -19,8 +19,10 @@ int32_t __stdcall __ntapi_pty_query( nt_pty_info_class pty_info_class) { int32_t status; + void * hport; nt_pty_sigctl_msg msg; uintptr_t * info; + nt_pty_inherit_info * inherit; if ((pty_info_class=NT_PTY_INFORMATION_CAP)) return NT_STATUS_INVALID_INFO_CLASS; @@ -28,6 +30,8 @@ int32_t __stdcall __ntapi_pty_query( 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; + else if ((pty_info_class == NT_PTY_INHERIT_INFORMATION) && (pty_info_length != sizeof(nt_pty_inherit_info))) + return NT_STATUS_INVALID_PARAMETER; __ntapi->tt_aligned_block_memset( &msg,0,sizeof(msg)); @@ -37,16 +41,31 @@ int32_t __stdcall __ntapi_pty_query( 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; + if (pty_info_class == NT_PTY_CLIENT_INFORMATION) { + hport = pty->hport; + 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); + + } else if (pty_info_class == NT_PTY_INHERIT_INFORMATION) { + msg.data.ctlinfo.hpty = NT_INVALID_HANDLE_VALUE; + msg.data.ctlinfo.ctlcode = pty_info_class; + + inherit = (nt_pty_inherit_info *)pty_info; + msg.data.ctlinfo.ctxarg[0] = inherit->any[0]; + msg.data.ctlinfo.ctxarg[1] = inherit->any[1]; + msg.data.ctlinfo.ctxarg[2] = inherit->any[2]; + msg.data.ctlinfo.ctxarg[3] = inherit->any[3]; - __ntapi->tt_guid_copy( - &msg.data.ctlinfo.guid, - &pty->guid); + hport = pty ? pty : __ntapi_internals()->hport_tty_session; + } - if ((status = __ntapi->zw_request_wait_reply_port(pty->hport,&msg,&msg))) + if ((status = __ntapi->zw_request_wait_reply_port(hport,&msg,&msg))) return status; else if (msg.data.ttyinfo.status) return msg.data.ttyinfo.status; @@ -54,11 +73,28 @@ int32_t __stdcall __ntapi_pty_query( 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]; + if (pty_info_class == NT_PTY_CLIENT_INFORMATION) { + 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]; + + } else if (pty_info_class == NT_PTY_INHERIT_INFORMATION) { + inherit = (nt_pty_inherit_info *)pty_info; + inherit->hpty = msg.data.ctlinfo.hpty; + inherit->luid.low = msg.data.ctlinfo.luid.low; + inherit->luid.high = msg.data.ctlinfo.luid.high; + + inherit->access = msg.data.ctlinfo.ctxarg[0]; + inherit->flags = msg.data.ctlinfo.ctxarg[1]; + inherit->share = msg.data.ctlinfo.ctxarg[2]; + inherit->options = msg.data.ctlinfo.ctxarg[3]; + + __ntapi->tt_guid_copy( + &inherit->guid, + &msg.data.ctlinfo.guid); + } return NT_STATUS_SUCCESS; } diff --git a/src/pty/ntapi_pty_set.c b/src/pty/ntapi_pty_set.c index 1543e7c..fee34b8 100644 --- a/src/pty/ntapi_pty_set.c +++ b/src/pty/ntapi_pty_set.c @@ -26,6 +26,8 @@ int32_t __stdcall __ntapi_pty_set( 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_INHERIT_INFORMATION) + return NT_STATUS_INVALID_INFO_CLASS; else if ((pty_info_class == NT_PTY_CLIENT_INFORMATION) && (pty_info_length != sizeof(nt_pty_client_info))) return NT_STATUS_INVALID_PARAMETER; -- cgit v1.2.3