summaryrefslogtreecommitdiffhomepage
path: root/src/debug/ptyc_dbg_oven.c
blob: 49ddb82861b3f7112603059d96c5cc4008c1bead (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
/*********************************************************/
/*  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 <gdi/gdi.h>

#include <ptycon/ptycon.h>
#include "ptycon_driver_impl.h"

int __stdcall ptyc_dbg_oven(struct ptyc_driver_ctx_impl * ictx)
{
	int32_t		status;
	void *		hwait;
	char *		ch;
	nt_iosb		iosb;
	size_t		nread;
	uintptr_t	buffer[4196/sizeof(uintptr_t)];

	if ((status = ntapi->tt_create_private_event(
			&hwait,
			NT_NOTIFICATION_EVENT,
			NT_EVENT_NOT_SIGNALED)))
		return status;

	do {
		status = ntapi->pty_read(
			ictx->cctx.hpts,
			hwait,0,0,
			&iosb,
			buffer,sizeof(buffer),
			0,0);

		if (status == NT_STATUS_PENDING)
			status = ntapi->zw_wait_for_single_object(
				hwait,NT_SYNC_ALERTABLE,0);

		if (status || iosb.status) {
			ntapi->zw_close(hwait);
			return status ? status : iosb.status;
		}

		ch    = (char *)buffer;
		nread = iosb.info;

		for ( ; nread; ) {
			status = ntapi->pty_write(
				ictx->cctx.hpts,
				hwait,0,0,&iosb,
				ch,(uint32_t)nread,
				0,0);

			if (status == NT_STATUS_PENDING)
				status = ntapi->zw_wait_for_single_object(
					hwait,NT_SYNC_ALERTABLE,0);

			if (status || iosb.status) {
				ntapi->zw_close(hwait);
				return status ? status : iosb.status;
			}

			ch    += iosb.info;
			nread -= iosb.info;
		}
	} while (1);
}