|
|
dd89bb |
/********************************************************/
|
|
|
dd89bb |
/* ntapi: Native API core library */
|
|
|
64e606 |
/* Copyright (C) 2013--2021 SysDeer Technologies, LLC */
|
|
|
dd89bb |
/* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */
|
|
|
dd89bb |
/********************************************************/
|
|
|
dd89bb |
|
|
|
dd89bb |
#include <psxtypes/psxtypes.h>
|
|
|
dd89bb |
#include <ntapi/ntapi.h>
|
|
|
dd89bb |
#include "ntapi_impl.h"
|
|
|
dd89bb |
|
|
|
dd89bb |
static int32_t __fastcall __tty_create_session_return(
|
|
|
0d309b |
void * hready,
|
|
|
dd89bb |
nt_create_process_params * params,
|
|
|
dd89bb |
int32_t status)
|
|
|
dd89bb |
{
|
|
|
0d309b |
if (params->hprocess && status)
|
|
|
dd89bb |
__ntapi->zw_terminate_process(
|
|
|
dd89bb |
params->hprocess,
|
|
|
dd89bb |
NT_STATUS_UNEXPECTED_IO_ERROR);
|
|
|
dd89bb |
|
|
|
0d309b |
__ntapi->zw_close(hready);
|
|
|
dd89bb |
__ntapi->zw_close(params->hprocess);
|
|
|
dd89bb |
__ntapi->zw_close(params->hthread);
|
|
|
dd89bb |
|
|
|
dd89bb |
return status;
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
int32_t __stdcall __ntapi_tty_create_session(
|
|
|
dd89bb |
__out void ** hport,
|
|
|
dd89bb |
__out nt_port_name * port_name,
|
|
|
dd89bb |
__in nt_tty_session_type type,
|
|
|
e3e5a2 |
__in nt_tty_session_subtype subtype,
|
|
|
dd89bb |
__in const nt_guid * guid __optional,
|
|
|
1f883a |
__in wchar16_t * image_name,
|
|
|
f61917 |
__in void * htty __optional)
|
|
|
dd89bb |
{
|
|
|
dd89bb |
nt_status status;
|
|
|
dd89bb |
ntapi_internals * __internals;
|
|
|
f61917 |
void * shport;
|
|
|
f61917 |
nt_port_name sport_name;
|
|
|
f61917 |
nt_tty_server_basic_info ttyinfo;
|
|
|
f61917 |
nt_iosb iosb;
|
|
|
dd89bb |
|
|
|
dd89bb |
nt_port_attr port_attr;
|
|
|
df0e42 |
nt_runtime_data * rtdata;
|
|
|
dd89bb |
nt_runtime_data ssattr;
|
|
|
dd89bb |
nt_runtime_data_block rtblock;
|
|
|
dd89bb |
nt_create_process_params params;
|
|
|
abc6f7 |
nt_event_basic_information eready;
|
|
|
dd89bb |
|
|
|
b58b75 |
/* abi/api */
|
|
|
b58b75 |
(void)subtype;
|
|
|
b58b75 |
|
|
|
1f883a |
/* validate */
|
|
|
1f883a |
if (!image_name)
|
|
|
1f883a |
return NT_STATUS_INVALID_PARAMETER;
|
|
|
dd89bb |
|
|
|
dd89bb |
/* init */
|
|
|
dd89bb |
__internals = __ntapi_internals();
|
|
|
df0e42 |
rtdata = __internals->rtdata;
|
|
|
dd89bb |
|
|
|
dd89bb |
__ntapi->tt_aligned_block_memset(
|
|
|
dd89bb |
&port_attr,0,sizeof(port_attr));
|
|
|
dd89bb |
|
|
|
f61917 |
__ntapi->tt_aligned_block_memset(
|
|
|
f61917 |
&ssattr,0,sizeof(ssattr));
|
|
|
f61917 |
|
|
|
171c2d |
/* port type */
|
|
|
171c2d |
if (guid) {
|
|
|
171c2d |
if ((status = __ntapi->tt_port_type_from_guid(
|
|
|
171c2d |
&port_attr.type,
|
|
|
171c2d |
&port_attr.subtype,
|
|
|
171c2d |
guid)))
|
|
|
171c2d |
return status;
|
|
|
171c2d |
} else {
|
|
|
171c2d |
port_attr.type = NT_PORT_TYPE_SUBSYSTEM;
|
|
|
171c2d |
}
|
|
|
171c2d |
|
|
|
171c2d |
/* port subtype */
|
|
|
dd89bb |
switch (type) {
|
|
|
dd89bb |
case NT_TTY_SESSION_PRIMARY:
|
|
|
dd89bb |
port_attr.subtype = NT_PORT_SUBTYPE_DEFAULT;
|
|
|
dd89bb |
|
|
|
dd89bb |
if (!hport)
|
|
|
dd89bb |
hport = &__internals->hport_tty_session;
|
|
|
dd89bb |
|
|
|
dd89bb |
if (!port_name)
|
|
|
dd89bb |
port_name = __internals->subsystem;
|
|
|
dd89bb |
|
|
|
dd89bb |
break;
|
|
|
dd89bb |
|
|
|
f61917 |
case NT_TTY_SESSION_SECONDARY:
|
|
|
f61917 |
port_attr.subtype = NT_PORT_SUBTYPE_DEFAULT;
|
|
|
f61917 |
|
|
|
f61917 |
if (!hport)
|
|
|
f61917 |
hport = &shport;
|
|
|
f61917 |
|
|
|
f61917 |
if (!port_name)
|
|
|
f61917 |
port_name = &sport_name;
|
|
|
f61917 |
|
|
|
f61917 |
break;
|
|
|
f61917 |
|
|
|
dd89bb |
case NT_TTY_SESSION_PRIVATE:
|
|
|
dd89bb |
port_attr.subtype = NT_PORT_SUBTYPE_PRIVATE;
|
|
|
dd89bb |
break;
|
|
|
dd89bb |
|
|
|
dd89bb |
default:
|
|
|
dd89bb |
return NT_STATUS_INVALID_PARAMETER;
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
/* port guid */
|
|
|
dd89bb |
if (guid)
|
|
|
dd89bb |
__ntapi->tt_guid_copy(
|
|
|
dd89bb |
&port_attr.guid,
|
|
|
dd89bb |
guid);
|
|
|
dd89bb |
else
|
|
|
dd89bb |
__ntapi->tt_port_guid_from_type(
|
|
|
dd89bb |
&port_attr.guid,
|
|
|
dd89bb |
port_attr.type,
|
|
|
dd89bb |
port_attr.subtype);
|
|
|
dd89bb |
|
|
|
dd89bb |
/* port keys */
|
|
|
dd89bb |
if ((status = __ntapi->tt_port_generate_keys(&port_attr.keys)))
|
|
|
dd89bb |
return status;
|
|
|
dd89bb |
|
|
|
dd89bb |
/* port name */
|
|
|
6d5726 |
__ntapi->tt_port_name_from_attr(
|
|
|
dd89bb |
port_name,
|
|
|
dd89bb |
&port_attr);
|
|
|
dd89bb |
|
|
|
f61917 |
/* parent session) */
|
|
|
f61917 |
if (htty && (htty != NT_INVALID_HANDLE_VALUE)) {
|
|
|
f61917 |
if ((status = __ntapi->tty_query_information_server(
|
|
|
f61917 |
htty,&iosb,
|
|
|
f61917 |
&ttyinfo,sizeof(ttyinfo),
|
|
|
f61917 |
NT_TTY_SERVER_BASIC_INFORMATION)))
|
|
|
f61917 |
return status;
|
|
|
dd89bb |
|
|
|
f61917 |
ssattr.tty_type = ttyinfo.attr.type;
|
|
|
f61917 |
ssattr.tty_subtype = ttyinfo.attr.subtype;
|
|
|
f61917 |
|
|
|
f61917 |
ssattr.tty_keys[0] = ttyinfo.attr.keys.key[0];
|
|
|
f61917 |
ssattr.tty_keys[1] = ttyinfo.attr.keys.key[1];
|
|
|
f61917 |
ssattr.tty_keys[2] = ttyinfo.attr.keys.key[2];
|
|
|
f61917 |
ssattr.tty_keys[3] = ttyinfo.attr.keys.key[3];
|
|
|
f61917 |
ssattr.tty_keys[4] = ttyinfo.attr.keys.key[4];
|
|
|
f61917 |
ssattr.tty_keys[5] = ttyinfo.attr.keys.key[5];
|
|
|
f61917 |
|
|
|
f61917 |
__ntapi->tt_guid_copy(
|
|
|
f61917 |
&ssattr.tty_guid,
|
|
|
f61917 |
&ttyinfo.attr.guid);
|
|
|
f61917 |
}
|
|
|
f61917 |
|
|
|
f61917 |
/* subsystem attributes */
|
|
|
e3a284 |
__ntapi->tt_guid_copy(
|
|
|
e3a284 |
&ssattr.abi,
|
|
|
e3a284 |
&(nt_guid)NT_PROCESS_GUID_RTDATA);
|
|
|
e3a284 |
|
|
|
b58b75 |
ssattr.srv_type = port_attr.type;
|
|
|
b58b75 |
ssattr.srv_subtype = port_attr.subtype;
|
|
|
e3e5a2 |
|
|
|
dd89bb |
ssattr.srv_keys[0] = port_attr.keys.key[0];
|
|
|
dd89bb |
ssattr.srv_keys[1] = port_attr.keys.key[1];
|
|
|
dd89bb |
ssattr.srv_keys[2] = port_attr.keys.key[2];
|
|
|
dd89bb |
ssattr.srv_keys[3] = port_attr.keys.key[3];
|
|
|
dd89bb |
ssattr.srv_keys[4] = port_attr.keys.key[4];
|
|
|
dd89bb |
ssattr.srv_keys[5] = port_attr.keys.key[5];
|
|
|
dd89bb |
|
|
|
dd89bb |
__ntapi->tt_guid_copy(
|
|
|
dd89bb |
&ssattr.srv_guid,
|
|
|
dd89bb |
&port_attr.guid);
|
|
|
dd89bb |
|
|
|
dd89bb |
if ((status = __ntapi->tt_create_private_event(
|
|
|
6336c4 |
&ssattr.hserver,
|
|
|
6c2850 |
NT_NOTIFICATION_EVENT,
|
|
|
dd89bb |
NT_EVENT_NOT_SIGNALED)))
|
|
|
dd89bb |
return status;
|
|
|
dd89bb |
|
|
|
df0e42 |
/* server chain */
|
|
|
df0e42 |
if (rtdata->srv_type) {
|
|
|
df0e42 |
ssattr.ppid_type = rtdata->srv_type;
|
|
|
df0e42 |
ssattr.ppid_subtype = rtdata->srv_subtype;
|
|
|
df0e42 |
|
|
|
df0e42 |
ssattr.ppid_keys[0] = rtdata->srv_keys[0];
|
|
|
df0e42 |
ssattr.ppid_keys[1] = rtdata->srv_keys[1];
|
|
|
df0e42 |
ssattr.ppid_keys[2] = rtdata->srv_keys[2];
|
|
|
df0e42 |
ssattr.ppid_keys[3] = rtdata->srv_keys[3];
|
|
|
df0e42 |
ssattr.ppid_keys[4] = rtdata->srv_keys[4];
|
|
|
df0e42 |
ssattr.ppid_keys[5] = rtdata->srv_keys[5];
|
|
|
df0e42 |
|
|
|
df0e42 |
__ntapi->tt_guid_copy(
|
|
|
df0e42 |
&ssattr.ppid_guid,
|
|
|
df0e42 |
&rtdata->srv_guid);
|
|
|
df0e42 |
}
|
|
|
df0e42 |
|
|
|
dd89bb |
/* create subsystem process */
|
|
|
dd89bb |
rtblock.addr = &ssattr;
|
|
|
dd89bb |
rtblock.size = sizeof(ssattr);
|
|
|
dd89bb |
rtblock.remote_addr = 0;
|
|
|
dd89bb |
rtblock.remote_size = 0;
|
|
|
dd89bb |
rtblock.flags = NT_RUNTIME_DATA_DUPLICATE_SESSION_HANDLES;
|
|
|
dd89bb |
|
|
|
dd89bb |
__ntapi->tt_aligned_block_memset(
|
|
|
dd89bb |
¶ms,0,sizeof(params));
|
|
|
dd89bb |
|
|
|
dd89bb |
params.image_name = image_name;
|
|
|
dd89bb |
params.rtblock = &rtblock;
|
|
|
f61917 |
params.hsession = htty;
|
|
|
dd89bb |
|
|
|
dd89bb |
if ((status = __ntapi->tt_create_native_process(¶ms)))
|
|
|
6336c4 |
return __tty_create_session_return(ssattr.hserver,¶ms,status);
|
|
|
dd89bb |
|
|
|
abc6f7 |
__ntapi->zw_wait_for_multiple_objects(
|
|
|
abc6f7 |
2,
|
|
|
6336c4 |
(void *[]){ssattr.hserver,params.hprocess},
|
|
|
abc6f7 |
NT_WAIT_ANY,
|
|
|
abc6f7 |
NT_SYNC_NON_ALERTABLE,
|
|
|
abc6f7 |
0);
|
|
|
abc6f7 |
|
|
|
abc6f7 |
if ((status = __ntapi->zw_query_event(
|
|
|
6336c4 |
ssattr.hserver,
|
|
|
abc6f7 |
NT_EVENT_BASIC_INFORMATION,
|
|
|
abc6f7 |
&eready,
|
|
|
abc6f7 |
sizeof(eready),
|
|
|
abc6f7 |
&(size_t){0})))
|
|
|
6336c4 |
return __tty_create_session_return(ssattr.hserver,¶ms,status);
|
|
|
dd89bb |
|
|
|
abc6f7 |
if (!eready.signal_state)
|
|
|
6336c4 |
return __tty_create_session_return(ssattr.hserver,¶ms,NT_STATUS_SYSTEM_PROCESS_TERMINATED);
|
|
|
abc6f7 |
|
|
|
dd89bb |
/* connect to subsystem */
|
|
|
dd89bb |
if ((status = __ntapi->tty_connect(
|
|
|
dd89bb |
hport,
|
|
|
dd89bb |
&port_name->base_named_objects[0],
|
|
|
dd89bb |
NT_SECURITY_IMPERSONATION)))
|
|
|
6336c4 |
return __tty_create_session_return(ssattr.hserver,¶ms,status);
|
|
|
dd89bb |
|
|
|
dd89bb |
/* finalize primary session */
|
|
|
dd89bb |
if (type == NT_TTY_SESSION_PRIMARY) {
|
|
|
dd89bb |
if (hport != &__internals->hport_tty_session)
|
|
|
dd89bb |
__internals->hport_tty_session = *hport;
|
|
|
dd89bb |
|
|
|
dd89bb |
if (port_name != __internals->subsystem)
|
|
|
dd89bb |
__ntapi->tt_memcpy_utf16(
|
|
|
dd89bb |
__internals->subsystem->base_named_objects,
|
|
|
dd89bb |
port_name->base_named_objects,
|
|
|
dd89bb |
sizeof(*port_name));
|
|
|
dd89bb |
};
|
|
|
dd89bb |
|
|
|
6336c4 |
return __tty_create_session_return(ssattr.hserver,¶ms,NT_STATUS_SUCCESS);
|
|
|
dd89bb |
}
|