|
|
dd89bb |
/********************************************************/
|
|
|
dd89bb |
/* ntapi: Native API core library */
|
|
|
4256e2 |
/* Copyright (C) 2013--2016 Z. Gilboa */
|
|
|
dd89bb |
/* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */
|
|
|
dd89bb |
/********************************************************/
|
|
|
dd89bb |
|
|
|
dd89bb |
#include <psxtypes/psxtypes.h>
|
|
|
dd89bb |
#include <ntapi/nt_port.h>
|
|
|
dd89bb |
#include <ntapi/nt_tty.h>
|
|
|
dd89bb |
#include <ntapi/ntapi.h>
|
|
|
dd89bb |
#include "ntapi_impl.h"
|
|
|
f62cf8 |
#include "ntapi_log.h"
|
|
|
dd89bb |
#include "ntapi_pty.h"
|
|
|
dd89bb |
|
|
|
dd89bb |
static int32_t __stdcall __ntapi_pty_open_close(
|
|
|
dd89bb |
nt_pty * pty,
|
|
|
dd89bb |
nt_iosb * iosb,
|
|
|
dd89bb |
int32_t opcode)
|
|
|
dd89bb |
{
|
|
|
dd89bb |
int32_t status;
|
|
|
dd89bb |
nt_pty_fd_msg msg;
|
|
|
dd89bb |
|
|
|
dd89bb |
__ntapi->tt_aligned_block_memset(&msg,0,sizeof(msg));
|
|
|
dd89bb |
|
|
|
dd89bb |
msg.header.msg_type = NT_LPC_NEW_MESSAGE;
|
|
|
dd89bb |
msg.header.data_size = sizeof(msg.data);
|
|
|
dd89bb |
msg.header.msg_size = sizeof(msg);
|
|
|
dd89bb |
msg.data.ttyinfo.opcode = opcode;
|
|
|
dd89bb |
|
|
|
dd89bb |
msg.data.fdinfo.hpty = pty->hpty;
|
|
|
dd89bb |
msg.data.fdinfo.access = pty->access;
|
|
|
dd89bb |
msg.data.fdinfo.flags = pty->flags;
|
|
|
dd89bb |
msg.data.fdinfo.share = pty->share;
|
|
|
dd89bb |
msg.data.fdinfo.options = pty->options;
|
|
|
dd89bb |
|
|
|
dd89bb |
msg.data.fdinfo.luid.high = pty->luid.high;
|
|
|
dd89bb |
msg.data.fdinfo.luid.low = pty->luid.low;
|
|
|
dd89bb |
|
|
|
dd89bb |
__ntapi_tt_guid_copy(
|
|
|
dd89bb |
&msg.data.fdinfo.guid,
|
|
|
dd89bb |
&pty->guid);
|
|
|
dd89bb |
|
|
|
dd89bb |
if ((status = __ntapi->zw_request_wait_reply_port(pty->hport,&msg,&msg)))
|
|
|
dd89bb |
return status;
|
|
|
dd89bb |
else if (msg.data.ttyinfo.status)
|
|
|
dd89bb |
return msg.data.ttyinfo.status;
|
|
|
dd89bb |
|
|
|
dd89bb |
pty->hpty = msg.data.fdinfo.hpty;
|
|
|
dd89bb |
pty->section = msg.data.fdinfo.section;
|
|
|
dd89bb |
pty->section_size = msg.data.fdinfo.section_size;
|
|
|
dd89bb |
pty->luid.high = msg.data.fdinfo.luid.high;
|
|
|
dd89bb |
pty->luid.low = msg.data.fdinfo.luid.low;
|
|
|
dd89bb |
iosb->status = msg.data.ttyinfo.status;
|
|
|
dd89bb |
iosb->info = 0;
|
|
|
dd89bb |
|
|
|
dd89bb |
return NT_STATUS_SUCCESS;
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
|
|
|
dd89bb |
static int32_t __fastcall __ntapi_pty_free(nt_pty * pty)
|
|
|
dd89bb |
{
|
|
|
dd89bb |
void * addr;
|
|
|
dd89bb |
size_t size;
|
|
|
dd89bb |
|
|
|
dd89bb |
/* unmap section */
|
|
|
dd89bb |
if (pty->section_addr)
|
|
|
dd89bb |
__ntapi->zw_unmap_view_of_section(
|
|
|
dd89bb |
NT_CURRENT_PROCESS_HANDLE,
|
|
|
dd89bb |
pty->section_addr);
|
|
|
dd89bb |
|
|
|
dd89bb |
/* free control block */
|
|
|
dd89bb |
addr = pty->addr;
|
|
|
dd89bb |
size = pty->size;
|
|
|
dd89bb |
|
|
|
dd89bb |
return __ntapi->zw_free_virtual_memory(
|
|
|
dd89bb |
NT_CURRENT_PROCESS_HANDLE,
|
|
|
dd89bb |
&addr,
|
|
|
dd89bb |
&size,
|
|
|
dd89bb |
NT_MEM_RELEASE);
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
|
|
|
dd89bb |
static int32_t __fastcall __ntapi_pty_fail(nt_pty * pty,int32_t status)
|
|
|
dd89bb |
{
|
|
|
dd89bb |
__ntapi_pty_free(pty);
|
|
|
dd89bb |
return status;
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
|
|
|
dd89bb |
static int32_t __fastcall __ntapi_pty_alloc(nt_pty ** pty)
|
|
|
dd89bb |
{
|
|
|
dd89bb |
int32_t status;
|
|
|
dd89bb |
nt_pty * ctx;
|
|
|
dd89bb |
size_t ctx_size;
|
|
|
dd89bb |
|
|
|
dd89bb |
/* allocate control block */
|
|
|
dd89bb |
ctx = 0;
|
|
|
dd89bb |
ctx_size = sizeof(nt_pty);
|
|
|
dd89bb |
|
|
|
dd89bb |
if ((status = __ntapi->zw_allocate_virtual_memory(
|
|
|
dd89bb |
NT_CURRENT_PROCESS_HANDLE,
|
|
|
dd89bb |
(void **)&ctx,
|
|
|
dd89bb |
0,&ctx_size,
|
|
|
dd89bb |
NT_MEM_COMMIT,
|
|
|
dd89bb |
NT_PAGE_READWRITE)))
|
|
|
dd89bb |
return status;
|
|
|
dd89bb |
|
|
|
dd89bb |
/* init control block */
|
|
|
dd89bb |
__ntapi->tt_aligned_block_memset(
|
|
|
dd89bb |
ctx,0,ctx_size);
|
|
|
dd89bb |
|
|
|
dd89bb |
ctx->addr = ctx;
|
|
|
dd89bb |
ctx->size = ctx_size;
|
|
|
dd89bb |
|
|
|
dd89bb |
*pty = ctx;
|
|
|
dd89bb |
return NT_STATUS_SUCCESS;
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
static int32_t __ntapi_pty_connect(
|
|
|
dd89bb |
void * hport,
|
|
|
dd89bb |
nt_pty * ctx,
|
|
|
dd89bb |
nt_iosb * iosb)
|
|
|
dd89bb |
{
|
|
|
dd89bb |
int32_t status;
|
|
|
dd89bb |
|
|
|
dd89bb |
ctx->hport = hport
|
|
|
dd89bb |
? hport
|
|
|
dd89bb |
: __ntapi_internals()->hport_tty_session;
|
|
|
dd89bb |
|
|
|
dd89bb |
/* request */
|
|
|
dd89bb |
iosb = iosb ? iosb : &ctx->iosb;
|
|
|
dd89bb |
|
|
|
dd89bb |
if ((status = __ntapi_pty_open_close(ctx,iosb,NT_TTY_PTY_OPEN)))
|
|
|
dd89bb |
return __ntapi_pty_fail(ctx,status);
|
|
|
dd89bb |
|
|
|
dd89bb |
/* map section */
|
|
|
dd89bb |
if ((status = __ntapi->zw_map_view_of_section(
|
|
|
dd89bb |
ctx->section,
|
|
|
dd89bb |
NT_CURRENT_PROCESS_HANDLE,
|
|
|
dd89bb |
&ctx->section_addr,
|
|
|
dd89bb |
0,ctx->section_size,
|
|
|
dd89bb |
0,&ctx->section_size,
|
|
|
dd89bb |
NT_VIEW_UNMAP,0,
|
|
|
dd89bb |
NT_PAGE_READWRITE)))
|
|
|
f62cf8 |
ctx->section_addr = 0;
|
|
|
f62cf8 |
|
|
|
f62cf8 |
/* resilience */
|
|
|
f62cf8 |
if (!ctx->section_addr) {
|
|
|
f62cf8 |
__ntapi_log_write("__ntapi_pty_connect:149\n",24);
|
|
|
f62cf8 |
if ((status = __ntapi->zw_map_view_of_section(
|
|
|
f62cf8 |
ctx->section,
|
|
|
f62cf8 |
NT_CURRENT_PROCESS_HANDLE,
|
|
|
f62cf8 |
&ctx->section_addr,
|
|
|
f62cf8 |
0,ctx->section_size,
|
|
|
f62cf8 |
0,&ctx->section_size,
|
|
|
f62cf8 |
NT_VIEW_UNMAP,0,
|
|
|
f62cf8 |
NT_PAGE_READWRITE)))
|
|
|
f62cf8 |
return __ntapi_pty_fail(ctx,status);
|
|
|
f62cf8 |
__ntapi_log_write("__ntapi_pty_connect:159\n",24);
|
|
|
f62cf8 |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
/* assume conforming clients, config for single lock try */
|
|
|
dd89bb |
__ntapi->tt_sync_block_init(&ctx->sync[__PTY_READ],0,0,1,0,0);
|
|
|
dd89bb |
__ntapi->tt_sync_block_init(&ctx->sync[__PTY_WRITE],0,0,1,0,0);
|
|
|
dd89bb |
|
|
|
dd89bb |
return NT_STATUS_SUCCESS;
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
|
|
|
dd89bb |
int32_t __stdcall __ntapi_pty_open(
|
|
|
dd89bb |
void * hport,
|
|
|
dd89bb |
nt_pty ** pty,
|
|
|
dd89bb |
uint32_t desired_access,
|
|
|
dd89bb |
nt_object_attributes* obj_attr,
|
|
|
dd89bb |
nt_iosb * iosb,
|
|
|
dd89bb |
uint32_t share_access,
|
|
|
dd89bb |
uint32_t open_options)
|
|
|
dd89bb |
{
|
|
|
dd89bb |
int32_t status;
|
|
|
dd89bb |
nt_guid guid;
|
|
|
dd89bb |
nt_uuid_str_utf16 * guid_str;
|
|
|
dd89bb |
nt_pty * ctx;
|
|
|
e9b18b |
wchar16_t * wch;
|
|
|
dd89bb |
|
|
|
e9b18b |
/* validate */
|
|
|
dd89bb |
if (!obj_attr || !obj_attr->obj_name || !obj_attr->obj_name->buffer)
|
|
|
dd89bb |
return NT_STATUS_INVALID_PARAMETER;
|
|
|
dd89bb |
|
|
|
dd89bb |
if (obj_attr->obj_name->strlen != __DEVICE_PATH_PREFIX_LEN + sizeof(nt_guid_str_utf16))
|
|
|
dd89bb |
return NT_STATUS_OBJECT_PATH_INVALID;
|
|
|
dd89bb |
|
|
|
e9b18b |
wch = obj_attr->obj_name->buffer;
|
|
|
dd89bb |
|
|
|
e9b18b |
if ((wch[0] != '\\')
|
|
|
e9b18b |
|| (wch[1] != 'D')
|
|
|
e9b18b |
|| (wch[2] != 'e')
|
|
|
e9b18b |
|| (wch[3] != 'v')
|
|
|
e9b18b |
|| (wch[4] != 'i')
|
|
|
e9b18b |
|| (wch[5] != 'c')
|
|
|
e9b18b |
|| (wch[6] != 'e')
|
|
|
e9b18b |
|| (wch[7] != '\\'))
|
|
|
dd89bb |
return NT_STATUS_OBJECT_PATH_INVALID;
|
|
|
dd89bb |
|
|
|
dd89bb |
guid_str = (nt_uuid_str_utf16 *)
|
|
|
dd89bb |
((uintptr_t)obj_attr->obj_name->buffer + __DEVICE_PATH_PREFIX_LEN);
|
|
|
dd89bb |
|
|
|
dd89bb |
if (__ntapi->tt_utf16_string_to_guid(guid_str,&guid))
|
|
|
dd89bb |
return NT_STATUS_OBJECT_NAME_INVALID;
|
|
|
dd89bb |
|
|
|
dd89bb |
/* control block */
|
|
|
dd89bb |
if ((status = __ntapi_pty_alloc(&ctx)))
|
|
|
dd89bb |
return status;
|
|
|
dd89bb |
|
|
|
dd89bb |
__ntapi_tt_guid_copy(
|
|
|
dd89bb |
&ctx->guid,
|
|
|
dd89bb |
&guid);
|
|
|
dd89bb |
|
|
|
dd89bb |
ctx->access = desired_access;
|
|
|
dd89bb |
ctx->flags = obj_attr->obj_attr;
|
|
|
dd89bb |
ctx->share = share_access;
|
|
|
dd89bb |
ctx->options = open_options;
|
|
|
dd89bb |
|
|
|
dd89bb |
/* pts */
|
|
|
dd89bb |
if (obj_attr->root_dir) {
|
|
|
54abed |
ctx->hpty = ((nt_pty *)obj_attr->root_dir)->hpty;
|
|
|
dd89bb |
ctx->luid.high = ((nt_pty *)obj_attr->root_dir)->luid.high;
|
|
|
dd89bb |
ctx->luid.low = ((nt_pty *)obj_attr->root_dir)->luid.low;
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
if ((status = __ntapi_pty_connect(hport,ctx,iosb)))
|
|
|
dd89bb |
return status;
|
|
|
dd89bb |
|
|
|
dd89bb |
*pty = ctx;
|
|
|
dd89bb |
|
|
|
dd89bb |
return NT_STATUS_SUCCESS;
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
efc01e |
int32_t __stdcall __ntapi_pty_inherit(
|
|
|
efc01e |
__in void * hport,
|
|
|
efc01e |
__out nt_pty ** pty,
|
|
|
efc01e |
__in nt_pty_client_info * client_info)
|
|
|
efc01e |
{
|
|
|
efc01e |
int32_t status;
|
|
|
efc01e |
nt_iosb iosb;
|
|
|
efc01e |
nt_pty_inherit_info inherit;
|
|
|
efc01e |
nt_pty * ctx;
|
|
|
efc01e |
|
|
|
efc01e |
inherit.any[0] = client_info->any[0];
|
|
|
efc01e |
inherit.any[1] = client_info->any[1];
|
|
|
efc01e |
inherit.any[2] = client_info->any[2];
|
|
|
efc01e |
inherit.any[3] = client_info->any[3];
|
|
|
efc01e |
|
|
|
efc01e |
if ((status = __ntapi_pty_query(
|
|
|
efc01e |
hport,&iosb,
|
|
|
efc01e |
&inherit,sizeof(inherit),
|
|
|
efc01e |
NT_PTY_INHERIT_INFORMATION)))
|
|
|
efc01e |
return status;
|
|
|
efc01e |
|
|
|
efc01e |
/* control block */
|
|
|
efc01e |
if ((status = __ntapi_pty_alloc(&ctx)))
|
|
|
efc01e |
return status;
|
|
|
efc01e |
|
|
|
efc01e |
__ntapi_tt_guid_copy(
|
|
|
efc01e |
&ctx->guid,
|
|
|
efc01e |
&inherit.guid);
|
|
|
efc01e |
|
|
|
f4367d |
ctx->hpty = inherit.hpty;
|
|
|
efc01e |
ctx->access = inherit.access;
|
|
|
efc01e |
ctx->flags = inherit.flags;
|
|
|
efc01e |
ctx->share = inherit.share;
|
|
|
efc01e |
ctx->options = inherit.options;
|
|
|
efc01e |
|
|
|
efc01e |
ctx->luid.low = inherit.luid.low;
|
|
|
efc01e |
ctx->luid.high = inherit.luid.high;
|
|
|
efc01e |
|
|
|
862d11 |
if ((status = __ntapi_pty_connect(hport,ctx,&iosb))) {
|
|
|
862d11 |
__ntapi_pty_free(ctx);
|
|
|
efc01e |
return status;
|
|
|
862d11 |
}
|
|
|
862d11 |
|
|
|
862d11 |
if ((status = __ntapi_pty_set(
|
|
|
862d11 |
ctx,&iosb,
|
|
|
862d11 |
client_info,
|
|
|
862d11 |
sizeof(*client_info),
|
|
|
862d11 |
NT_PTY_CLIENT_INFORMATION))) {
|
|
|
862d11 |
__ntapi_pty_free(ctx);
|
|
|
862d11 |
return status;
|
|
|
862d11 |
}
|
|
|
efc01e |
|
|
|
efc01e |
*pty = ctx;
|
|
|
efc01e |
|
|
|
efc01e |
return NT_STATUS_SUCCESS;
|
|
|
efc01e |
}
|
|
|
efc01e |
|
|
|
dd89bb |
int32_t __stdcall __ntapi_pty_reopen(
|
|
|
dd89bb |
__in void * hport,
|
|
|
dd89bb |
__in nt_pty * pty)
|
|
|
dd89bb |
{
|
|
|
dd89bb |
return __ntapi_pty_connect(hport,pty,0);
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
int32_t __stdcall __ntapi_pty_close(nt_pty * pty)
|
|
|
dd89bb |
{
|
|
|
dd89bb |
if (!pty || (pty->addr != pty))
|
|
|
dd89bb |
return NT_STATUS_INVALID_PARAMETER;
|
|
|
dd89bb |
|
|
|
dd89bb |
__ntapi_pty_open_close(
|
|
|
dd89bb |
pty,&pty->iosb,NT_TTY_PTY_CLOSE);
|
|
|
dd89bb |
|
|
|
dd89bb |
return __ntapi_pty_free(pty);
|
|
|
dd89bb |
}
|
|
|
5ea20e |
|
|
|
5ea20e |
int32_t __stdcall __ntapi_pty_inherit_runtime_ctty(
|
|
|
5ea20e |
__in void * hport,
|
|
|
5ea20e |
__in_out nt_runtime_data * rtdata)
|
|
|
5ea20e |
{
|
|
|
5ea20e |
int32_t status;
|
|
|
5ea20e |
nt_pty_client_info client_info;
|
|
|
5ea20e |
|
|
|
5ea20e |
if (rtdata->stdin_type == NT_FILE_TYPE_PTY) {
|
|
|
5ea20e |
client_info.any[0] = rtdata->ptyin[0];
|
|
|
5ea20e |
client_info.any[1] = rtdata->ptyin[1];
|
|
|
5ea20e |
client_info.any[2] = rtdata->ptyin[2];
|
|
|
5ea20e |
client_info.any[3] = rtdata->ptyin[3];
|
|
|
5ea20e |
|
|
|
5ea20e |
if ((status = __ntapi_pty_inherit(
|
|
|
5ea20e |
hport,
|
|
|
5ea20e |
(nt_pty **)&rtdata->hstdin,
|
|
|
5ea20e |
&client_info)))
|
|
|
5ea20e |
return status;
|
|
|
5ea20e |
}
|
|
|
5ea20e |
|
|
|
5ea20e |
if (rtdata->stdout_type == NT_FILE_TYPE_PTY) {
|
|
|
5ea20e |
if ((rtdata->stdin_type == NT_FILE_TYPE_PTY)
|
|
|
5ea20e |
&& (rtdata->ptyout[0] == rtdata->ptyin[0])
|
|
|
5ea20e |
&& (rtdata->ptyout[1] == rtdata->ptyin[1])
|
|
|
5ea20e |
&& (rtdata->ptyout[2] == rtdata->ptyin[2])
|
|
|
5ea20e |
&& (rtdata->ptyout[3] == rtdata->ptyin[3])) {
|
|
|
5ea20e |
rtdata->hstdout = rtdata->hstdin;
|
|
|
5ea20e |
|
|
|
5ea20e |
} else {
|
|
|
5ea20e |
client_info.any[0] = rtdata->ptyout[0];
|
|
|
5ea20e |
client_info.any[1] = rtdata->ptyout[1];
|
|
|
5ea20e |
client_info.any[2] = rtdata->ptyout[2];
|
|
|
5ea20e |
client_info.any[3] = rtdata->ptyout[3];
|
|
|
5ea20e |
|
|
|
5ea20e |
if ((status = __ntapi_pty_inherit(
|
|
|
5ea20e |
hport,
|
|
|
5ea20e |
(nt_pty **)&rtdata->hstdout,
|
|
|
5ea20e |
&client_info)))
|
|
|
5ea20e |
return status;
|
|
|
5ea20e |
}
|
|
|
5ea20e |
}
|
|
|
5ea20e |
|
|
|
5ea20e |
if (rtdata->stderr_type == NT_FILE_TYPE_PTY) {
|
|
|
5ea20e |
if ((rtdata->stdin_type == NT_FILE_TYPE_PTY)
|
|
|
5ea20e |
&& (rtdata->ptyerr[0] == rtdata->ptyin[0])
|
|
|
5ea20e |
&& (rtdata->ptyerr[1] == rtdata->ptyin[1])
|
|
|
5ea20e |
&& (rtdata->ptyerr[2] == rtdata->ptyin[2])
|
|
|
5ea20e |
&& (rtdata->ptyerr[3] == rtdata->ptyin[3])) {
|
|
|
5ea20e |
rtdata->hstderr = rtdata->hstdin;
|
|
|
5ea20e |
|
|
|
5ea20e |
} else if ((rtdata->stdout_type == NT_FILE_TYPE_PTY)
|
|
|
5ea20e |
&& (rtdata->ptyerr[0] == rtdata->ptyout[0])
|
|
|
5ea20e |
&& (rtdata->ptyerr[1] == rtdata->ptyout[1])
|
|
|
5ea20e |
&& (rtdata->ptyerr[2] == rtdata->ptyout[2])
|
|
|
5ea20e |
&& (rtdata->ptyerr[3] == rtdata->ptyout[3])) {
|
|
|
5ea20e |
rtdata->hstderr = rtdata->hstdout;
|
|
|
5ea20e |
|
|
|
5ea20e |
} else {
|
|
|
5ea20e |
client_info.any[0] = rtdata->ptyerr[0];
|
|
|
5ea20e |
client_info.any[1] = rtdata->ptyerr[1];
|
|
|
5ea20e |
client_info.any[2] = rtdata->ptyerr[2];
|
|
|
5ea20e |
client_info.any[3] = rtdata->ptyerr[3];
|
|
|
5ea20e |
|
|
|
5ea20e |
if ((status = __ntapi_pty_inherit(
|
|
|
5ea20e |
hport,
|
|
|
5ea20e |
(nt_pty **)&rtdata->hstderr,
|
|
|
5ea20e |
&client_info)))
|
|
|
5ea20e |
return status;
|
|
|
5ea20e |
}
|
|
|
5ea20e |
}
|
|
|
5ea20e |
|
|
|
5ea20e |
/* hctty */
|
|
|
5ea20e |
if ((rtdata->stdin_type == NT_FILE_TYPE_PTY)
|
|
|
5ea20e |
&& (rtdata->ptyctl[0] == rtdata->ptyin[0])
|
|
|
5ea20e |
&& (rtdata->ptyctl[1] == rtdata->ptyin[1])
|
|
|
5ea20e |
&& (rtdata->ptyctl[2] == rtdata->ptyin[2])
|
|
|
5ea20e |
&& (rtdata->ptyctl[3] == rtdata->ptyin[3])) {
|
|
|
5ea20e |
rtdata->hctty = rtdata->hstdin;
|
|
|
5ea20e |
|
|
|
5ea20e |
} else if ((rtdata->stdout_type == NT_FILE_TYPE_PTY)
|
|
|
5ea20e |
&& (rtdata->ptyctl[0] == rtdata->ptyout[0])
|
|
|
5ea20e |
&& (rtdata->ptyctl[1] == rtdata->ptyout[1])
|
|
|
5ea20e |
&& (rtdata->ptyctl[2] == rtdata->ptyout[2])
|
|
|
5ea20e |
&& (rtdata->ptyctl[3] == rtdata->ptyout[3])) {
|
|
|
5ea20e |
rtdata->hctty = rtdata->hstdout;
|
|
|
5ea20e |
|
|
|
5ea20e |
} else if ((rtdata->stderr_type == NT_FILE_TYPE_PTY)
|
|
|
5ea20e |
&& (rtdata->ptyctl[0] == rtdata->ptyerr[0])
|
|
|
5ea20e |
&& (rtdata->ptyctl[1] == rtdata->ptyerr[1])
|
|
|
5ea20e |
&& (rtdata->ptyctl[2] == rtdata->ptyerr[2])
|
|
|
5ea20e |
&& (rtdata->ptyctl[3] == rtdata->ptyerr[3])) {
|
|
|
5ea20e |
rtdata->hctty = rtdata->hstderr;
|
|
|
5ea20e |
|
|
|
5ea20e |
} else {
|
|
|
5ea20e |
client_info.any[0] = rtdata->ptyctl[0];
|
|
|
5ea20e |
client_info.any[1] = rtdata->ptyctl[1];
|
|
|
5ea20e |
client_info.any[2] = rtdata->ptyctl[2];
|
|
|
5ea20e |
client_info.any[3] = rtdata->ptyctl[3];
|
|
|
5ea20e |
|
|
|
5ea20e |
if ((status = __ntapi_pty_inherit(
|
|
|
5ea20e |
hport,
|
|
|
5ea20e |
(nt_pty **)&rtdata->hctty,
|
|
|
5ea20e |
&client_info)))
|
|
|
5ea20e |
rtdata->hctty = 0;
|
|
|
5ea20e |
}
|
|
|
5ea20e |
|
|
|
5ea20e |
return NT_STATUS_SUCCESS;
|
|
|
5ea20e |
}
|