segatools/mai2hook/led.c

210 lines
5.1 KiB
C

#include <windows.h>
#include <stdbool.h>
#include "hooklib/reg.h"
#include "hooklib/uart.h"
#include "hooklib/fdshark.h"
#include "mai2hook/led.h"
#include "util/dprintf.h"
static HRESULT read_fake_com0(void *bytes, uint32_t *nbytes);
static HRESULT read_fake_com1(void *bytes, uint32_t *nbytes);
static HRESULT read_fake_com2(void *bytes, uint32_t *nbytes);
static HRESULT led_handle_irp(struct irp *irp);
static HRESULT led0_handle_irp_locked(struct irp *irp);
static HRESULT led1_handle_irp_locked(struct irp *irp);
static CRITICAL_SECTION led0_lock;
static struct uart led0_uart;
static uint8_t led0_written_bytes[520];
static uint8_t led0_readable_bytes[520];
static CRITICAL_SECTION led1_lock;
static struct uart led1_uart;
static uint8_t led1_written_bytes[520];
static uint8_t led1_readable_bytes[520];
static const struct reg_hook_val fake_com_keys[] = {
{
.name = L"\\Device\\RealTouchBoard0",
.read = read_fake_com0,
.type = REG_SZ,
},{
.name = L"\\Device\\RealTouchBoard1",
.read = read_fake_com1,
.type = REG_SZ,
},{
.name = L"\\Device\\RealLedBoard0",
.read = read_fake_com2,
.type = REG_SZ,
},
};
HRESULT led_hook_init(const struct led_config *cfg)
{
HRESULT hr;
if (!cfg->enable) {
return S_FALSE;
}
dprintf("Mai2 LED: Init\n");
InitializeCriticalSection(&led0_lock);
InitializeCriticalSection(&led1_lock);
hr = reg_hook_push_key(
HKEY_LOCAL_MACHINE,
L"HARDWARE\\DEVICEMAP\\SERIALCOMM",
fake_com_keys,
_countof(fake_com_keys));
if (FAILED(hr)) {
return hr;
}
uart_init(&led0_uart, 21);
led0_uart.written.bytes = led0_written_bytes;
led0_uart.written.nbytes = sizeof(led0_written_bytes);
led0_uart.readable.bytes = led0_readable_bytes;
led0_uart.readable.nbytes = sizeof(led0_readable_bytes);
uart_init(&led1_uart, 23);
led1_uart.written.bytes = led1_written_bytes;
led1_uart.written.nbytes = sizeof(led1_written_bytes);
led1_uart.readable.bytes = led1_readable_bytes;
led1_uart.readable.nbytes = sizeof(led1_readable_bytes);
return iohook_push_handler(led_handle_irp);
}
static HRESULT read_fake_com0(void *bytes, uint32_t *nbytes)
{
//dprintf("Mai2 Touch: Read COM3 reg val\n");
return reg_hook_read_wstr(bytes, nbytes, L"COM3");
}
static HRESULT read_fake_com1(void *bytes, uint32_t *nbytes)
{
//dprintf("Mai2 Touch: Read COM4 reg val\n");
return reg_hook_read_wstr(bytes, nbytes, L"COM4");
}
static HRESULT read_fake_com2(void *bytes, uint32_t *nbytes)
{
//dprintf("Mai2 LED: Read COM20 reg val\n");
return reg_hook_read_wstr(bytes, nbytes, L"COM20");
}
static HRESULT led_handle_irp(struct irp *irp)
{
HRESULT hr;
assert(irp != NULL);
if (uart_match_irp(&led0_uart, irp)) {
EnterCriticalSection(&led0_lock);
hr = led0_handle_irp_locked(irp);
LeaveCriticalSection(&led0_lock);
}
else if (uart_match_irp(&led1_uart, irp)) {
EnterCriticalSection(&led1_lock);
hr = led1_handle_irp_locked(irp);
LeaveCriticalSection(&led1_lock);
}
else {
return iohook_invoke_next(irp);
}
return hr;
}
static HRESULT led0_handle_irp_locked(struct irp *irp)
{
HRESULT hr = S_OK;
if (irp->op == IRP_OP_OPEN) {
dprintf("Mai2 led0: Starting backend\n");
//hr = mai2_dll.led_init();
if (FAILED(hr)) {
dprintf("Mai2 led: Backend error: %x\n", (int) hr);
return hr;
}
}
hr = uart_handle_irp(&led0_uart, irp);
if (FAILED(hr) || irp->op != IRP_OP_WRITE) {
return hr;
}
for (;;) {
#if 0
dprintf("TX0 Buffer:\n");
dump_iobuf(&led0_uart.written);
#endif
//hr = led_frame_decode(&req, &led0_uart.written, 0);
if (hr != S_OK) {
if (FAILED(hr)) {
dprintf("Mai2 led: Deframe error: %x\n", (int) hr);
}
return hr;
}
//hr = led_req_dispatch(&req);
if (FAILED(hr)) {
dprintf("Mai2 led: Processing error: %x\n", (int) hr);
}
return hr;
}
}
static HRESULT led1_handle_irp_locked(struct irp *irp)
{
HRESULT hr = S_OK;
if (irp->op == IRP_OP_OPEN) {
dprintf("Mai2 led1: Starting backend\n");
//hr = mai2_dll.led_init();
if (FAILED(hr)) {
dprintf("Mai2 led: Backend error: %x\n", (int) hr);
return hr;
}
}
hr = uart_handle_irp(&led0_uart, irp);
if (FAILED(hr) || irp->op != IRP_OP_WRITE) {
return hr;
}
for (;;) {
#if 0
dprintf("TX0 Buffer:\n");
dump_iobuf(&led0_uart.written);
#endif
//hr = led_frame_decode(&req, &led0_uart.written, 0);
if (hr != S_OK) {
if (FAILED(hr)) {
dprintf("Mai2 led: Deframe error: %x\n", (int) hr);
}
return hr;
}
//hr = led_req_dispatch(&req);
if (FAILED(hr)) {
dprintf("Mai2 led: Processing error: %x\n", (int) hr);
}
return hr;
}
}