#include #include #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; } }