summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/pty/ptyc_spawn.c271
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(
- &params,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(&params)))
- 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;
}