| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| static int32_t __fastcall __tty_create_session_return( |
| void * hready, |
| nt_create_process_params * params, |
| int32_t status) |
| { |
| if (params->hprocess && status) |
| __ntapi->zw_terminate_process( |
| params->hprocess, |
| NT_STATUS_UNEXPECTED_IO_ERROR); |
| |
| __ntapi->zw_close(hready); |
| __ntapi->zw_close(params->hprocess); |
| __ntapi->zw_close(params->hthread); |
| |
| return status; |
| } |
| |
| int32_t __stdcall __ntapi_tty_create_session( |
| __out void ** hport, |
| __out nt_port_name * port_name, |
| __in nt_tty_session_type type, |
| __in nt_tty_session_subtype subtype, |
| __in const nt_guid * guid __optional, |
| __in wchar16_t * image_name, |
| __in void * htty __optional) |
| { |
| nt_status status; |
| ntapi_internals * __internals; |
| void * shport; |
| nt_port_name sport_name; |
| nt_tty_server_basic_info ttyinfo; |
| nt_iosb iosb; |
| |
| nt_port_attr port_attr; |
| nt_runtime_data * rtdata; |
| nt_runtime_data ssattr; |
| nt_runtime_data_block rtblock; |
| nt_create_process_params params; |
| nt_event_basic_information eready; |
| |
| |
| (void)subtype; |
| |
| |
| if (!image_name) |
| return NT_STATUS_INVALID_PARAMETER; |
| |
| |
| __internals = __ntapi_internals(); |
| rtdata = __internals->rtdata; |
| |
| __ntapi->tt_aligned_block_memset( |
| &port_attr,0,sizeof(port_attr)); |
| |
| __ntapi->tt_aligned_block_memset( |
| &ssattr,0,sizeof(ssattr)); |
| |
| |
| if (guid) { |
| if ((status = __ntapi->tt_port_type_from_guid( |
| &port_attr.type, |
| &port_attr.subtype, |
| guid))) |
| return status; |
| } else { |
| port_attr.type = NT_PORT_TYPE_SUBSYSTEM; |
| } |
| |
| |
| switch (type) { |
| case NT_TTY_SESSION_PRIMARY: |
| port_attr.subtype = NT_PORT_SUBTYPE_DEFAULT; |
| |
| if (!hport) |
| hport = &__internals->hport_tty_session; |
| |
| if (!port_name) |
| port_name = __internals->subsystem; |
| |
| break; |
| |
| case NT_TTY_SESSION_SECONDARY: |
| port_attr.subtype = NT_PORT_SUBTYPE_DEFAULT; |
| |
| if (!hport) |
| hport = &shport; |
| |
| if (!port_name) |
| port_name = &sport_name; |
| |
| break; |
| |
| case NT_TTY_SESSION_PRIVATE: |
| port_attr.subtype = NT_PORT_SUBTYPE_PRIVATE; |
| break; |
| |
| default: |
| return NT_STATUS_INVALID_PARAMETER; |
| } |
| |
| |
| if (guid) |
| __ntapi->tt_guid_copy( |
| &port_attr.guid, |
| guid); |
| else |
| __ntapi->tt_port_guid_from_type( |
| &port_attr.guid, |
| port_attr.type, |
| port_attr.subtype); |
| |
| |
| if ((status = __ntapi->tt_port_generate_keys(&port_attr.keys))) |
| return status; |
| |
| |
| __ntapi->tt_port_name_from_attr( |
| port_name, |
| &port_attr); |
| |
| |
| if (htty && (htty != NT_INVALID_HANDLE_VALUE)) { |
| if ((status = __ntapi->tty_query_information_server( |
| htty,&iosb, |
| &ttyinfo,sizeof(ttyinfo), |
| NT_TTY_SERVER_BASIC_INFORMATION))) |
| return status; |
| |
| ssattr.tty_type = ttyinfo.attr.type; |
| ssattr.tty_subtype = ttyinfo.attr.subtype; |
| |
| ssattr.tty_keys[0] = ttyinfo.attr.keys.key[0]; |
| ssattr.tty_keys[1] = ttyinfo.attr.keys.key[1]; |
| ssattr.tty_keys[2] = ttyinfo.attr.keys.key[2]; |
| ssattr.tty_keys[3] = ttyinfo.attr.keys.key[3]; |
| ssattr.tty_keys[4] = ttyinfo.attr.keys.key[4]; |
| ssattr.tty_keys[5] = ttyinfo.attr.keys.key[5]; |
| |
| __ntapi->tt_guid_copy( |
| &ssattr.tty_guid, |
| &ttyinfo.attr.guid); |
| } |
| |
| |
| __ntapi->tt_guid_copy( |
| &ssattr.abi, |
| &(nt_guid)NT_PROCESS_GUID_RTDATA); |
| |
| ssattr.srv_type = port_attr.type; |
| ssattr.srv_subtype = port_attr.subtype; |
| |
| ssattr.srv_keys[0] = port_attr.keys.key[0]; |
| ssattr.srv_keys[1] = port_attr.keys.key[1]; |
| ssattr.srv_keys[2] = port_attr.keys.key[2]; |
| ssattr.srv_keys[3] = port_attr.keys.key[3]; |
| ssattr.srv_keys[4] = port_attr.keys.key[4]; |
| ssattr.srv_keys[5] = port_attr.keys.key[5]; |
| |
| __ntapi->tt_guid_copy( |
| &ssattr.srv_guid, |
| &port_attr.guid); |
| |
| if ((status = __ntapi->tt_create_private_event( |
| &ssattr.hserver, |
| NT_NOTIFICATION_EVENT, |
| NT_EVENT_NOT_SIGNALED))) |
| return status; |
| |
| |
| if (rtdata->srv_type) { |
| ssattr.ppid_type = rtdata->srv_type; |
| ssattr.ppid_subtype = rtdata->srv_subtype; |
| |
| ssattr.ppid_keys[0] = rtdata->srv_keys[0]; |
| ssattr.ppid_keys[1] = rtdata->srv_keys[1]; |
| ssattr.ppid_keys[2] = rtdata->srv_keys[2]; |
| ssattr.ppid_keys[3] = rtdata->srv_keys[3]; |
| ssattr.ppid_keys[4] = rtdata->srv_keys[4]; |
| ssattr.ppid_keys[5] = rtdata->srv_keys[5]; |
| |
| __ntapi->tt_guid_copy( |
| &ssattr.ppid_guid, |
| &rtdata->srv_guid); |
| } |
| |
| |
| rtblock.addr = &ssattr; |
| rtblock.size = sizeof(ssattr); |
| rtblock.remote_addr = 0; |
| rtblock.remote_size = 0; |
| rtblock.flags = NT_RUNTIME_DATA_DUPLICATE_SESSION_HANDLES; |
| |
| __ntapi->tt_aligned_block_memset( |
| ¶ms,0,sizeof(params)); |
| |
| params.image_name = image_name; |
| params.rtblock = &rtblock; |
| params.hsession = htty; |
| |
| if ((status = __ntapi->tt_create_native_process(¶ms))) |
| return __tty_create_session_return(ssattr.hserver,¶ms,status); |
| |
| __ntapi->zw_wait_for_multiple_objects( |
| 2, |
| (void *[]){ssattr.hserver,params.hprocess}, |
| NT_WAIT_ANY, |
| NT_SYNC_NON_ALERTABLE, |
| 0); |
| |
| if ((status = __ntapi->zw_query_event( |
| ssattr.hserver, |
| NT_EVENT_BASIC_INFORMATION, |
| &eready, |
| sizeof(eready), |
| &(size_t){0}))) |
| return __tty_create_session_return(ssattr.hserver,¶ms,status); |
| |
| if (!eready.signal_state) |
| return __tty_create_session_return(ssattr.hserver,¶ms,NT_STATUS_SYSTEM_PROCESS_TERMINATED); |
| |
| |
| if ((status = __ntapi->tty_connect( |
| hport, |
| &port_name->base_named_objects[0], |
| NT_SECURITY_IMPERSONATION))) |
| return __tty_create_session_return(ssattr.hserver,¶ms,status); |
| |
| |
| if (type == NT_TTY_SESSION_PRIMARY) { |
| if (hport != &__internals->hport_tty_session) |
| __internals->hport_tty_session = *hport; |
| |
| if (port_name != __internals->subsystem) |
| __ntapi->tt_memcpy_utf16( |
| __internals->subsystem->base_named_objects, |
| port_name->base_named_objects, |
| sizeof(*port_name)); |
| }; |
| |
| return __tty_create_session_return(ssattr.hserver,¶ms,NT_STATUS_SUCCESS); |
| } |