Blame src/debug/ptyc_dbg_cat.c

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(&params)))
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
}