|
|
9cf365 |
/*********************************************************/
|
|
|
9cf365 |
/* ptycon: a pty-console bridge */
|
|
|
9cf365 |
/* Copyright (C) 2016 Z. Gilboa */
|
|
|
9cf365 |
/* Released under GPLv2 and GPLv3; see COPYING.PTYCON. */
|
|
|
9cf365 |
/*********************************************************/
|
|
|
9cf365 |
|
|
|
9cf365 |
#include <psxtypes/psxtypes.h>
|
|
|
9cf365 |
#include <ntcon/ntcon.h>
|
|
|
9cf365 |
#include <ntapi/ntapi.h>
|
|
|
9cf365 |
|
|
|
9cf365 |
#include <ptycon/ptycon.h>
|
|
|
9cf365 |
#include "ptycon_driver_impl.h"
|
|
|
9cf365 |
|
|
|
9cf365 |
static int32_t ptyc_open(void ** hfile, void * hat, const char * arg)
|
|
|
9cf365 |
{
|
|
|
9cf365 |
int32_t status;
|
|
|
9cf365 |
nt_oa oa;
|
|
|
9cf365 |
nt_iosb iosb;
|
|
|
9cf365 |
nt_unicode_string path;
|
|
|
9cf365 |
nt_unicode_conversion_params_utf8_to_utf16 params = {0,0,0,0,0,0,0,0,0};
|
|
|
9cf365 |
wchar16_t buffer[4096];
|
|
|
9cf365 |
wchar16_t * wch;
|
|
|
9cf365 |
size_t nbytes;
|
|
|
9cf365 |
|
|
|
9cf365 |
/* utf-8 --> utf-16 */
|
|
|
9cf365 |
params.src = (const unsigned char *)arg;
|
|
|
9cf365 |
params.src_size_in_bytes= ntapi->tt_string_null_offset_multibyte(arg);
|
|
|
9cf365 |
params.dst = buffer;
|
|
|
9cf365 |
params.dst_size_in_bytes= sizeof(buffer);
|
|
|
9cf365 |
|
|
|
9cf365 |
if ((status = ntapi->uc_convert_unicode_stream_utf8_to_utf16(¶ms)))
|
|
|
9cf365 |
return status;
|
|
|
9cf365 |
|
|
|
9cf365 |
/* convenience */
|
|
|
9cf365 |
for (wch=buffer, nbytes=params.bytes_written; nbytes; ) {
|
|
|
9cf365 |
if (*wch == '/')
|
|
|
9cf365 |
*wch = '\\';
|
|
|
9cf365 |
|
|
|
9cf365 |
nbytes -= sizeof(wchar16_t);
|
|
|
9cf365 |
wch++;
|
|
|
9cf365 |
}
|
|
|
9cf365 |
|
|
|
9cf365 |
/* path */
|
|
|
9cf365 |
path.maxlen = 0;
|
|
|
9cf365 |
path.strlen = (uint16_t)params.bytes_written;
|
|
|
9cf365 |
path.buffer = buffer;
|
|
|
9cf365 |
|
|
|
9cf365 |
/* oa */
|
|
|
9cf365 |
oa.len = sizeof(nt_oa);
|
|
|
9cf365 |
oa.root_dir = hat;
|
|
|
9cf365 |
oa.obj_name = &pat;;
|
|
|
9cf365 |
oa.obj_attr = 0;
|
|
|
9cf365 |
oa.sec_desc = 0;
|
|
|
9cf365 |
oa.sec_qos = 0;
|
|
|
9cf365 |
|
|
|
9cf365 |
/* open */
|
|
|
9cf365 |
return ntapi->zw_open_file(
|
|
|
9cf365 |
hfile,
|
|
|
9cf365 |
NT_SEC_SYNCHRONIZE | NT_FILE_READ_ATTRIBUTES | NT_FILE_READ_DATA,
|
|
|
9cf365 |
&oa,&iosb,
|
|
|
9cf365 |
NT_FILE_SHARE_READ | NT_FILE_SHARE_WRITE | NT_FILE_SHARE_DELETE,
|
|
|
9cf365 |
NT_FILE_NON_DIRECTORY_FILE | NT_FILE_SYNCHRONOUS_IO_ALERT);
|
|
|
9cf365 |
}
|
|
|
9cf365 |
|
|
|
9cf365 |
static int32_t ptyc_cat(
|
|
|
9cf365 |
struct ptyc_driver_ctx* dctx,
|
|
|
9cf365 |
void * hat,
|
|
|
9cf365 |
const char * unit,
|
|
|
9cf365 |
void * hevent)
|
|
|
9cf365 |
{
|
|
|
9cf365 |
int32_t status;
|
|
|
9cf365 |
void * hfile;
|
|
|
9cf365 |
nt_iosb iosb;
|
|
|
9cf365 |
intptr_t nread;
|
|
|
9cf365 |
uintptr_t buffer[32768/sizeof(uintptr_t)];
|
|
|
9cf365 |
char * ch;
|
|
|
9cf365 |
|
|
|
9cf365 |
if ((status = ptyc_open(&hfile,hat,unit)))
|
|
|
9cf365 |
return status;
|
|
|
9cf365 |
|
|
|
9cf365 |
status = ntapi->zw_read_file(
|
|
|
9cf365 |
hfile,
|
|
|
9cf365 |
0,0,0,
|
|
|
9cf365 |
&iosb,
|
|
|
9cf365 |
buffer,sizeof(buffer),
|
|
|
9cf365 |
0,0);
|
|
|
9cf365 |
|
|
|
9cf365 |
while (status == NT_STATUS_SUCCESS) {
|
|
|
9cf365 |
ch = (char *)buffer;
|
|
|
9cf365 |
nread = iosb.info;
|
|
|
9cf365 |
|
|
|
9cf365 |
for ( ; nread; ) {
|
|
|
9cf365 |
status = ntapi->pty_write(
|
|
|
9cf365 |
dctx->cctx->hpts,
|
|
|
9cf365 |
hevent,0,0,
|
|
|
9cf365 |
&iosb,
|
|
|
9cf365 |
ch,nread,
|
|
|
9cf365 |
0,0);
|
|
|
9cf365 |
|
|
|
9cf365 |
if (status == NT_STATUS_PENDING)
|
|
|
9cf365 |
status = ntapi->zw_wait_for_single_object(
|
|
|
9cf365 |
hevent,NT_SYNC_ALERTABLE,0);
|
|
|
9cf365 |
|
|
|
9cf365 |
if (status || iosb.status) {
|
|
|
9cf365 |
ntapi->zw_close(hfile);
|
|
|
9cf365 |
return status ? status : iosb.status;
|
|
|
9cf365 |
}
|
|
|
9cf365 |
|
|
|
9cf365 |
ch += iosb.info;
|
|
|
9cf365 |
nread -= iosb.info;
|
|
|
9cf365 |
}
|
|
|
9cf365 |
|
|
|
9cf365 |
status = ntapi->zw_read_file(
|
|
|
9cf365 |
hfile,
|
|
|
9cf365 |
0,0,0,
|
|
|
9cf365 |
&iosb,
|
|
|
9cf365 |
buffer,sizeof(buffer),
|
|
|
9cf365 |
0,0);
|
|
|
9cf365 |
}
|
|
|
9cf365 |
|
|
|
9cf365 |
ntapi->zw_close(hfile);
|
|
|
9cf365 |
|
|
|
9cf365 |
return (status == NT_STATUS_END_OF_FILE)
|
|
|
9cf365 |
? NT_STATUS_SUCCESS
|
|
|
9cf365 |
: status;
|
|
|
9cf365 |
}
|
|
|
9cf365 |
|
|
|
9cf365 |
int ptyc_dbg_cat(struct ptyc_driver_ctx * dctx)
|
|
|
9cf365 |
{
|
|
|
9cf365 |
int32_t status;
|
|
|
9cf365 |
void * hevent;
|
|
|
9cf365 |
const char ** punit;
|
|
|
9cf365 |
nt_rtdata * rtdata;
|
|
|
9cf365 |
nt_peb * peb;
|
|
|
9cf365 |
void * hat;
|
|
|
9cf365 |
|
|
|
9cf365 |
if (!dctx->units[0])
|
|
|
9cf365 |
return 0;
|
|
|
9cf365 |
|
|
|
9cf365 |
if ((status = ntapi->tt_create_private_event(
|
|
|
9cf365 |
&hevent,
|
|
|
9cf365 |
NT_NOTIFICATION_EVENT,
|
|
|
9cf365 |
NT_EVENT_NOT_SIGNALED)))
|
|
|
9cf365 |
return status;
|
|
|
9cf365 |
|
|
|
9cf365 |
if ((status = ntapi->tt_get_runtime_data(&rtdata,0)))
|
|
|
9cf365 |
return status;
|
|
|
9cf365 |
|
|
|
9cf365 |
if (!(peb = (nt_peb *)pe_get_peb_address()))
|
|
|
9cf365 |
return NT_STATUS_INTERNAL_ERROR;
|
|
|
9cf365 |
|
|
|
9cf365 |
if (!peb->process_params)
|
|
|
9cf365 |
return NT_STATUS_INTERNAL_ERROR;
|
|
|
9cf365 |
|
|
|
9cf365 |
hat = rtdata->hcwd
|
|
|
9cf365 |
? rtdata->hcwd
|
|
|
9cf365 |
: peb->process_params->cwd_handle;
|
|
|
9cf365 |
|
|
|
9cf365 |
for (punit=dctx->units, status=0; *punit && !status; punit++)
|
|
|
9cf365 |
status = ptyc_cat(
|
|
|
9cf365 |
dctx,hat,
|
|
|
9cf365 |
*punit,
|
|
|
9cf365 |
hevent);
|
|
|
9cf365 |
|
|
|
9cf365 |
ntapi->zw_close(hevent);
|
|
|
9cf365 |
return status;
|
|
|
9cf365 |
}
|