/*********************************************************/
/* ptycon: a pty-console bridge */
/* Copyright (C) 2016 Z. Gilboa */
/* Released under GPLv2 and GPLv3; see COPYING.PTYCON. */
/*********************************************************/
#include <psxtypes/psxtypes.h>
#include <ntcon/ntcon.h>
#include <ntapi/ntapi.h>
#include <ptycon/ptycon.h>
#include "ptycon_driver_impl.h"
static int32_t ptyc_cat(
struct ptyc_driver_ctx* dctx,
void * hat,
const char * unit,
void * hevent)
{
int32_t status;
void * hfile;
nt_iosb iosb;
intptr_t nread;
uintptr_t buffer[32768/sizeof(uintptr_t)];
char * ch;
if ((status = ptyc_open_file(&hfile,hat,unit,true)))
return status;
status = ntapi->zw_read_file(
hfile,
0,0,0,
&iosb,
buffer,sizeof(buffer),
0,0);
while (status == NT_STATUS_SUCCESS) {
ch = (char *)buffer;
nread = iosb.info;
for ( ; nread; ) {
status = ntapi->pty_write(
dctx->cctx->hpts,
hevent,0,0,
&iosb,
ch,nread,
0,0);
if (status == NT_STATUS_PENDING)
status = ntapi->zw_wait_for_single_object(
hevent,NT_SYNC_ALERTABLE,0);
if (status || iosb.status) {
ntapi->zw_close(hfile);
return status ? status : iosb.status;
}
ch += iosb.info;
nread -= iosb.info;
}
status = ntapi->zw_read_file(
hfile,
0,0,0,
&iosb,
buffer,sizeof(buffer),
0,0);
}
ntapi->zw_close(hfile);
return (status == NT_STATUS_END_OF_FILE)
? NT_STATUS_SUCCESS
: status;
}
int __stdcall ptyc_dbg_cat(struct ptyc_driver_ctx * dctx)
{
int32_t status;
void * hevent;
const char ** punit;
nt_rtdata * rtdata;
nt_peb * peb;
void * hat;
if (!dctx->units[0])
return 0;
if ((status = ntapi->tt_create_private_event(
&hevent,
NT_NOTIFICATION_EVENT,
NT_EVENT_NOT_SIGNALED)))
return status;
if ((status = ntapi->tt_get_runtime_data(&rtdata,0)))
return status;
if (!(peb = (nt_peb *)pe_get_peb_address()))
return NT_STATUS_INTERNAL_ERROR;
if (!peb->process_params)
return NT_STATUS_INTERNAL_ERROR;
hat = rtdata->hcwd
? rtdata->hcwd
: peb->process_params->cwd_handle;
for (punit=dctx->units, status=0; *punit && !status; punit++)
status = ptyc_cat(
dctx,hat,
*punit,
hevent);
ntapi->zw_close(hevent);
return status;
}