|
|
dd89bb |
/********************************************************/
|
|
|
dd89bb |
/* ntapi: Native API core library */
|
|
|
dd89bb |
/* Copyright (C) 2013,2014,2015 Z. Gilboa */
|
|
|
dd89bb |
/* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */
|
|
|
dd89bb |
/********************************************************/
|
|
|
dd89bb |
|
|
|
dd89bb |
#include <psxtypes/psxtypes.h>
|
|
|
dd89bb |
#include <ntapi/nt_status.h>
|
|
|
dd89bb |
#include <ntapi/nt_object.h>
|
|
|
dd89bb |
#include <ntapi/nt_memory.h>
|
|
|
dd89bb |
#include <ntapi/nt_thread.h>
|
|
|
dd89bb |
#include <ntapi/nt_process.h>
|
|
|
dd89bb |
#include <ntapi/nt_sync.h>
|
|
|
dd89bb |
#include <ntapi/nt_string.h>
|
|
|
dd89bb |
#include <ntapi/ntapi.h>
|
|
|
dd89bb |
#include "ntapi_impl.h"
|
|
|
dd89bb |
|
|
|
dd89bb |
static intptr_t __tt_fork_cancel(void * hprocess,int32_t status)
|
|
|
dd89bb |
{
|
|
|
dd89bb |
__ntapi->zw_terminate_process(hprocess, status);
|
|
|
dd89bb |
__ntapi->zw_close(hprocess);
|
|
|
dd89bb |
return (intptr_t)(-1);
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
intptr_t __fastcall __tt_fork_impl_v2(
|
|
|
dd89bb |
__out void ** hprocess,
|
|
|
dd89bb |
__out void ** hthread)
|
|
|
dd89bb |
{
|
|
|
dd89bb |
int32_t status;
|
|
|
dd89bb |
void ** hport_session;
|
|
|
dd89bb |
nt_object_attributes oa_process;
|
|
|
dd89bb |
nt_object_attributes oa_thread;
|
|
|
dd89bb |
nt_create_process_info process_info;
|
|
|
dd89bb |
nt_cid cid;
|
|
|
dd89bb |
nt_sec_img_inf sec_img_inf;
|
|
|
dd89bb |
nt_timeout timeout;
|
|
|
dd89bb |
ntapi_internals * __internals;
|
|
|
dd89bb |
|
|
|
dd89bb |
struct {
|
|
|
dd89bb |
size_t size_in_bytes;
|
|
|
dd89bb |
nt_create_process_ext_param process_info;
|
|
|
dd89bb |
nt_create_process_ext_param section_info;
|
|
|
dd89bb |
} ext_params;
|
|
|
dd89bb |
|
|
|
dd89bb |
|
|
|
dd89bb |
oa_process.len = sizeof(nt_object_attributes);
|
|
|
dd89bb |
oa_process.root_dir = 0;
|
|
|
dd89bb |
oa_process.obj_name = 0;
|
|
|
dd89bb |
oa_process.obj_attr = 0;
|
|
|
dd89bb |
oa_process.sec_desc = 0;
|
|
|
dd89bb |
oa_process.sec_qos = 0;
|
|
|
dd89bb |
|
|
|
dd89bb |
oa_thread.len = sizeof(nt_object_attributes);
|
|
|
dd89bb |
oa_thread.root_dir = 0;
|
|
|
dd89bb |
oa_thread.obj_name = 0;
|
|
|
dd89bb |
oa_thread.obj_attr = 0;
|
|
|
dd89bb |
oa_thread.sec_desc = 0;
|
|
|
dd89bb |
oa_thread.sec_qos = 0;
|
|
|
dd89bb |
|
|
|
dd89bb |
|
|
|
dd89bb |
__ntapi->tt_aligned_block_memset(
|
|
|
dd89bb |
&process_info,0,sizeof(process_info));
|
|
|
dd89bb |
|
|
|
dd89bb |
process_info.size = sizeof(process_info);
|
|
|
dd89bb |
process_info.state = NT_PROCESS_CREATE_INITIAL_STATE;
|
|
|
dd89bb |
process_info.init_state.init_flags = NT_PROCESS_CREATE_FLAGS_NO_OBJECT_SYNC;
|
|
|
dd89bb |
|
|
|
dd89bb |
__ntapi->tt_aligned_block_memset(&ext_params,0,sizeof(ext_params));
|
|
|
dd89bb |
__ntapi->tt_aligned_block_memset(&cid,0,sizeof(cid));
|
|
|
dd89bb |
__ntapi->tt_aligned_block_memset(&sec_img_inf,0,sizeof(sec_img_inf));
|
|
|
dd89bb |
ext_params.size_in_bytes = sizeof(ext_params);
|
|
|
dd89bb |
|
|
|
dd89bb |
ext_params.process_info.ext_param_type = NT_CREATE_PROCESS_EXT_PARAM_GET_CLIENT_ID;
|
|
|
dd89bb |
ext_params.process_info.ext_param_size = sizeof(cid);
|
|
|
dd89bb |
ext_params.process_info.ext_param_addr = &cid;
|
|
|
dd89bb |
|
|
|
dd89bb |
ext_params.section_info.ext_param_type = NT_CREATE_PROCESS_EXT_PARAM_GET_SECTION_IMAGE_INFO;
|
|
|
dd89bb |
ext_params.section_info.ext_param_size = sizeof(sec_img_inf);
|
|
|
dd89bb |
ext_params.section_info.ext_param_addr = &sec_img_inf;
|
|
|
dd89bb |
|
|
|
dd89bb |
|
|
|
dd89bb |
/* [thou shalt remember the single step paradox] */
|
|
|
dd89bb |
status = __ntapi->zw_create_user_process(
|
|
|
dd89bb |
hprocess,
|
|
|
dd89bb |
hthread,
|
|
|
dd89bb |
NT_PROCESS_ALL_ACCESS,
|
|
|
dd89bb |
NT_THREAD_ALL_ACCESS,
|
|
|
dd89bb |
&oa_process,
|
|
|
dd89bb |
&oa_thread,
|
|
|
dd89bb |
NT_PROCESS_CREATE_FLAGS_INHERIT_HANDLES,
|
|
|
dd89bb |
NT_PROCESS_CREATE_FLAGS_CREATE_THREAD_SUSPENDED,
|
|
|
dd89bb |
(nt_process_parameters *)0,
|
|
|
dd89bb |
&process_info,
|
|
|
dd89bb |
(nt_create_process_ext_params *)&ext_params);
|
|
|
dd89bb |
|
|
|
dd89bb |
if (status == NT_STATUS_PROCESS_CLONED)
|
|
|
dd89bb |
return 0;
|
|
|
dd89bb |
else if (status)
|
|
|
dd89bb |
return (intptr_t)(-1);
|
|
|
dd89bb |
|
|
|
dd89bb |
__internals = __ntapi_internals();
|
|
|
dd89bb |
hport_session = &__internals->hport_tty_session;
|
|
|
dd89bb |
timeout.quad = (-1) * 10 * 1000 * __NT_FORK_CHILD_WAIT_MILLISEC;
|
|
|
dd89bb |
|
|
|
dd89bb |
if (hport_session && *hport_session)
|
|
|
dd89bb |
if ((status = __ntapi->tty_client_process_register(
|
|
|
dd89bb |
*hport_session,
|
|
|
dd89bb |
cid.process_id,
|
|
|
dd89bb |
0,0,&timeout)))
|
|
|
dd89bb |
return __tt_fork_cancel(*hprocess,status);
|
|
|
dd89bb |
|
|
|
dd89bb |
/* [thou shalt remember the single step paradox] */
|
|
|
dd89bb |
if ((status = __ntapi->zw_resume_thread(
|
|
|
dd89bb |
*hthread,0)))
|
|
|
dd89bb |
return __tt_fork_cancel(*hprocess,status);
|
|
|
dd89bb |
|
|
|
dd89bb |
/* hoppla */
|
|
|
dd89bb |
return (int32_t)cid.process_id;
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
intptr_t __fastcall __ntapi_tt_fork_v2(
|
|
|
dd89bb |
__out void ** hprocess,
|
|
|
dd89bb |
__out void ** hthread)
|
|
|
dd89bb |
{
|
|
|
dd89bb |
int32_t status;
|
|
|
dd89bb |
intptr_t pid;
|
|
|
dd89bb |
nt_large_integer timeout;
|
|
|
dd89bb |
void ** hport_session;
|
|
|
dd89bb |
void * hevent_tty_connected;
|
|
|
dd89bb |
ntapi_internals * __internals;
|
|
|
dd89bb |
|
|
|
dd89bb |
__internals = __ntapi_internals();
|
|
|
dd89bb |
hport_session = &__internals->hport_tty_session;
|
|
|
dd89bb |
timeout.quad = (-1) * 10 * 1000 * __NT_FORK_CHILD_WAIT_MILLISEC;
|
|
|
dd89bb |
|
|
|
dd89bb |
if (hport_session && *hport_session)
|
|
|
dd89bb |
if (__ntapi_tt_create_inheritable_event(
|
|
|
dd89bb |
&hevent_tty_connected,
|
|
|
dd89bb |
NT_NOTIFICATION_EVENT,
|
|
|
dd89bb |
NT_EVENT_NOT_SIGNALED))
|
|
|
dd89bb |
return (intptr_t)(-1);
|
|
|
dd89bb |
|
|
|
dd89bb |
pid = __tt_fork_impl_v2(hprocess,hthread);
|
|
|
dd89bb |
|
|
|
dd89bb |
if (!hport_session || !*hport_session)
|
|
|
dd89bb |
return pid;
|
|
|
dd89bb |
else if (pid < 0)
|
|
|
dd89bb |
return pid;
|
|
|
dd89bb |
|
|
|
dd89bb |
if (pid == 0) {
|
|
|
dd89bb |
if ((status = __ntapi->tty_connect(
|
|
|
dd89bb |
hport_session,
|
|
|
dd89bb |
__internals->subsystem->base_named_objects,
|
|
|
dd89bb |
NT_SECURITY_IMPERSONATION)))
|
|
|
dd89bb |
return __tt_fork_cancel(NT_CURRENT_PROCESS_HANDLE,status);
|
|
|
dd89bb |
|
|
|
dd89bb |
__internals->hdev_mount_point_mgr = 0;
|
|
|
dd89bb |
|
|
|
dd89bb |
if (__internals->rtdata)
|
|
|
dd89bb |
__internals->rtdata->hsession = *hport_session;
|
|
|
dd89bb |
|
|
|
dd89bb |
__ntapi->zw_set_event(
|
|
|
dd89bb |
hevent_tty_connected,
|
|
|
dd89bb |
0);
|
|
|
dd89bb |
} else {
|
|
|
dd89bb |
status = __ntapi->zw_wait_for_single_object(
|
|
|
dd89bb |
hevent_tty_connected,
|
|
|
dd89bb |
NT_SYNC_NON_ALERTABLE,
|
|
|
dd89bb |
&timeout);
|
|
|
dd89bb |
|
|
|
dd89bb |
if (status && __PSX_DEBUG)
|
|
|
dd89bb |
if ((status = __ntapi->zw_wait_for_single_object(
|
|
|
dd89bb |
hevent_tty_connected,
|
|
|
dd89bb |
NT_SYNC_NON_ALERTABLE,
|
|
|
dd89bb |
0)))
|
|
|
dd89bb |
pid = __tt_fork_cancel(*hprocess,status);
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
|
|
|
dd89bb |
__ntapi->zw_close(hevent_tty_connected);
|
|
|
dd89bb |
|
|
|
dd89bb |
return pid;
|
|
|
dd89bb |
}
|