forked from Hay1tsme/segatools
210 lines
5.1 KiB
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;
|
||
|
}
|
||
|
}
|