diff options
-rw-r--r-- | src/pty/ptyc_spawn.c | 271 |
1 files changed, 55 insertions, 216 deletions
diff --git a/src/pty/ptyc_spawn.c b/src/pty/ptyc_spawn.c index 3655d19..94e56b3 100644 --- a/src/pty/ptyc_spawn.c +++ b/src/pty/ptyc_spawn.c @@ -5,55 +5,25 @@ /*********************************************************/ #include <psxtypes/psxtypes.h> -#include <ntcon/ntcon.h> +#include <pemagine/pemagine.h> +#include <ntapi/nt_status.h> +#include <ntapi/nt_object.h> +#include <ntapi/nt_thread.h> +#include <ntapi/nt_process.h> +#include <ntapi/nt_string.h> #include <ntapi/ntapi.h> #include <ptycon/ptycon.h> #include "ptycon_driver_impl.h" -static int32_t __stdcall ptyc_spawn_return( - nt_runtime_data_block * rtblock, - int32_t status) -{ - nt_runtime_data * rtdata; - - rtdata = (nt_runtime_data *)rtblock; - - if (rtdata->hready) - ntapi->zw_close( - rtdata->hready); - - ntapi->zw_free_virtual_memory( - NT_CURRENT_PROCESS_HANDLE, - &rtblock->addr, - &rtblock->size, - NT_MEM_RELEASE); - - return status; -} - int __stdcall ptyc_spawn(struct ptyc_driver_ctx * dctx) { int32_t status; - char * patharg; - void * hchild[2]; - nt_create_process_params params; + nt_spawn_process_params sparams; + nt_runtime_data rtctx; struct ptyc_driver_ctx_impl * ictx; struct ptyc_client_ctx * clctx; - nt_tty_session_info session; - nt_runtime_data_block rtblock; - nt_runtime_data * rdata; nt_rtdata * self; - nt_peb * peb; - void * hat; - void * hfile; - char ** rargv; - char ** renvp; - wchar16_t ** pwarg; - wchar16_t * wch; - nt_unicode_string * imgname; - uint32_t written; - uintptr_t imgbuf[8192/sizeof(uintptr_t)]; /* init */ if (!(ictx = ptyc_get_driver_ictx(dctx))) @@ -65,198 +35,67 @@ int __stdcall ptyc_spawn(struct ptyc_driver_ctx * dctx) self = ictx->rtdata; clctx = &ictx->clctx; - /* hat */ - if (!(peb = (nt_peb *)pe_get_peb_address())) - return NT_STATUS_INTERNAL_ERROR; - - if (!peb->process_params) - return NT_STATUS_INTERNAL_ERROR; - - hat = (dctx->cctx->hroot && (dctx->cctx->eargv[0][0] == '/')) - ? dctx->cctx->hroot - : self->hcwd - ? self->hcwd - : peb->process_params->cwd_handle; - - patharg = (dctx->cctx->eargv[0][0] == '/') - ? (dctx->cctx->eargv[0][1] == '?') - ? &dctx->cctx->eargv[0][0] - : &dctx->cctx->eargv[0][1] - : &dctx->cctx->eargv[0][0]; - - /* hfile */ - if ((status = ptyc_open_file(&hfile,hat,patharg,true))) - return status; - - /* rtblock */ - rtblock.addr = 0; - rtblock.size = 0x10000; - rtblock.remote_addr = 0; - rtblock.remote_size = 0; - rtblock.flags = 0; - - if ((status = ntapi->zw_allocate_virtual_memory( - self->hprocess_self, - &rtblock.addr,0, - &rtblock.size, - NT_MEM_COMMIT, - NT_PAGE_READWRITE))) - return status; - + /* sparams */ ntapi->tt_aligned_block_memset( - rtblock.addr,0,rtblock.size); - - if ((status = ntapi->zw_query_object( - hfile, - NT_OBJECT_NAME_INFORMATION, - imgbuf,sizeof(imgbuf), - &written))) - return ptyc_spawn_return( - &rtblock,status); - - imgname = (nt_unicode_string *)imgbuf; - rdata = (nt_runtime_data *)rtblock.addr; - - /* argv, envp */ - if ((status = ntapi->tt_array_copy_utf8( - &rdata->argc, - (const char **)dctx->cctx->eargv, - (const char **)self->envp, - 0,0,0, - rtblock.addr, - rdata->buffer, - rtblock.size - sizeof(*rdata), - &rtblock.remote_size))) - return ptyc_spawn_return( - &rtblock,status); + &sparams,0,sizeof(sparams)); - rdata->argv = (char **)&((nt_runtime_data *)0)->buffer; - rdata->envp = rdata->argv + rdata->argc + 1; + sparams.rtctx = &rtctx; + sparams.patharg = dctx->cctx->eargv[0]; + sparams.argv = dctx->cctx->eargv; + sparams.envp = self->envp; + sparams.hsession = self->hsession; - rdata->wargv = (wchar16_t **)(rdata->buffer + (rtblock.remote_size / sizeof(uintptr_t)) + 1); - rdata->wenvp = rdata->wargv + rdata->argc + 1; - - rargv = rdata->argv + ((uintptr_t)rtblock.addr / sizeof(char *)); - renvp = rdata->envp + ((uintptr_t)rtblock.addr / sizeof(char *)); - - pwarg = rdata->wenvp + self->envc + 1; - wch = (wchar16_t *)pwarg; - - if ((status = ntapi->tt_array_convert_utf8_to_utf16( - rargv, - rdata->wargv, - rdata, - wch, - rtblock.size - sizeof(wchar16_t)*(wch-(wchar16_t *)rdata->buffer), - &rtblock.remote_size))) - return ptyc_spawn_return( - &rtblock,status); - - wch += rtblock.remote_size/sizeof(wchar16_t); - - if ((status = ntapi->tt_array_convert_utf8_to_utf16( - renvp, - rdata->wenvp, - rdata, - wch, - rtblock.size - sizeof(wchar16_t)*(wch-(wchar16_t *)rdata->buffer), - &rtblock.remote_size))) - return ptyc_spawn_return( - &rtblock,status); - - rdata->wargv -= (uintptr_t)rtblock.addr / sizeof(wchar16_t *); - rdata->wenvp -= (uintptr_t)rtblock.addr / sizeof(wchar16_t *); - - /* session */ - if ((status = ntapi->tt_create_inheritable_event( - &rdata->hready, - NT_NOTIFICATION_EVENT, - NT_EVENT_NOT_SIGNALED))) - return ptyc_spawn_return( - &rtblock,status); + /* rtctx */ + ntapi->tt_aligned_block_memset( + &rtctx,0,sizeof(rtctx)); ntapi->tt_aligned_block_memcpy( - (uintptr_t *)&rdata->cid_parent, + (uintptr_t *)&rtctx.cid_parent, (uintptr_t *)&self->cid_self, sizeof(nt_cid)); - rdata->hroot = dctx->cctx->hroot; - rdata->hcwd = self->hcwd - ? self->hcwd - : peb->process_params->cwd_handle; + rtctx.hroot = dctx->cctx->hroot; + rtctx.hcwd = self->hcwd; - rdata->srv_keys[0] = self->srv_keys[0]; - rdata->srv_keys[1] = self->srv_keys[1]; - rdata->srv_keys[2] = self->srv_keys[2]; - rdata->srv_keys[3] = self->srv_keys[3]; - rdata->srv_keys[4] = self->srv_keys[4]; - rdata->srv_keys[5] = self->srv_keys[5]; + rtctx.srv_keys[0] = self->srv_keys[0]; + rtctx.srv_keys[1] = self->srv_keys[1]; + rtctx.srv_keys[2] = self->srv_keys[2]; + rtctx.srv_keys[3] = self->srv_keys[3]; + rtctx.srv_keys[4] = self->srv_keys[4]; + rtctx.srv_keys[5] = self->srv_keys[5]; - rdata->hstdin = NT_INVALID_HANDLE_VALUE; - rdata->hstdout = NT_INVALID_HANDLE_VALUE; - rdata->hstderr = NT_INVALID_HANDLE_VALUE; + rtctx.hstdin = NT_INVALID_HANDLE_VALUE; + rtctx.hstdout = NT_INVALID_HANDLE_VALUE; + rtctx.hstderr = NT_INVALID_HANDLE_VALUE; - rdata->stdin_type = NT_FILE_TYPE_PTY; - rdata->stdout_type = NT_FILE_TYPE_PTY; - rdata->stderr_type = NT_FILE_TYPE_PTY; + rtctx.stdin_type = NT_FILE_TYPE_PTY; + rtctx.stdout_type = NT_FILE_TYPE_PTY; + rtctx.stderr_type = NT_FILE_TYPE_PTY; - rdata->ptyany[0] = clctx->clinfo.any[0]; - rdata->ptyany[1] = clctx->clinfo.any[1]; - rdata->ptyany[2] = clctx->clinfo.any[2]; - rdata->ptyany[3] = clctx->clinfo.any[3]; - - /* params */ - ntapi->tt_aligned_block_memset( - ¶ms,0,sizeof(params)); - - params.image_name = imgname->buffer; - params.rtblock = &rtblock; - params.creation_flags_process = NT_PROCESS_CREATE_FLAGS_INHERIT_HANDLES; - params.creation_flags_thread = NT_PROCESS_CREATE_FLAGS_CREATE_THREAD_SUSPENDED; + rtctx.ptyany[0] = clctx->clinfo.any[0]; + rtctx.ptyany[1] = clctx->clinfo.any[1]; + rtctx.ptyany[2] = clctx->clinfo.any[2]; + rtctx.ptyany[3] = clctx->clinfo.any[3]; /* hoppla */ - if ((status = ntapi->tt_create_native_process(¶ms))) - return ptyc_spawn_return( - &rtblock,status); + if ((status = ntapi->tt_spawn_native_process(&sparams))) + return status; /* clctx */ - clctx->hprocess = params.hprocess; - clctx->hthread = params.hthread; - clctx->cid.process_id = params.cid.process_id; - clctx->cid.thread_id = params.cid.thread_id; - - if ((status = ntapi->tty_client_process_register( - self->hsession, - params.pbi.unique_process_id, - 0,NT_TTY_INHERIT_HANDLES,0))) - ntapi->zw_terminate_process( - params.hprocess, - status); - - session.pid = 0; - session.pgid = 0; - session.sid = 0; - session.syspid = params.pbi.unique_process_id; - - if ((status = ntapi->tty_client_session_set(0,&session))) - ntapi->zw_terminate_process( - params.hprocess, - status); - - if ((status = ntapi->zw_resume_thread(params.hthread,0))) - ntapi->zw_terminate_process( - params.hprocess, - status); - - hchild[1] = params.hprocess; - hchild[0] = rdata->hready; - - ntapi->zw_wait_for_multiple_objects( - 2,hchild, - NT_WAIT_ANY, - NT_SYNC_NON_ALERTABLE, - 0); - - return ptyc_spawn_return( - &rtblock,status); + clctx->hprocess = sparams.hprocess; + clctx->hthread = sparams.hthread; + clctx->cid.process_id = sparams.cid.process_id; + clctx->cid.thread_id = sparams.cid.thread_id; + + /* child ready? */ + if (!(sparams.eready.signal_state)) + return NT_STATUS_GENERIC_COMMAND_FAILED; + + /* finalize */ + if (!(dctx->cctx->drvflags & (PTYC_DRIVER_DBG_RAW|PTYC_DRIVER_DBG_OVEN))) + if ((status = ntapi->pty_close(ictx->cctx.hpts))) + return status; + + /* all done */ + return NT_STATUS_SUCCESS; } |