#include #include #include #include "hook/iohook.h" #include "hooklib/uart.h" #include "util/dprintf.h" #include "util/dump.h" #include "hkbhook/led.h" static HRESULT hkb_led_handle_irp(struct irp *irp); static HRESULT hkb_led_handle_irp_locked(struct irp *irp); static CRITICAL_SECTION hkb_led_lock; static bool hkb_led_started; static struct uart hkb_led_uart; static uint8_t hkb_led_written_bytes[520]; static uint8_t hkb_led_readable_bytes[520]; HRESULT led_hook_init(const struct hkb_led_config *cfg, uint8_t port) { if (!cfg->enable) { return S_OK; } InitializeCriticalSection(&hkb_led_lock); uart_init(&hkb_led_uart, port); hkb_led_uart.written.bytes = hkb_led_written_bytes; hkb_led_uart.written.nbytes = sizeof(hkb_led_written_bytes); hkb_led_uart.readable.bytes = hkb_led_readable_bytes; hkb_led_uart.readable.nbytes = sizeof(hkb_led_readable_bytes); return iohook_push_handler(hkb_led_handle_irp); } static HRESULT hkb_led_handle_irp(struct irp *irp) { HRESULT hr; assert(irp != NULL); if (!uart_match_irp(&hkb_led_uart, irp)) { return iohook_invoke_next(irp); } EnterCriticalSection(&hkb_led_lock); hr = hkb_led_handle_irp_locked(irp); LeaveCriticalSection(&hkb_led_lock); return hr; } static HRESULT hkb_led_handle_irp_locked(struct irp *irp) { HRESULT hr; #if 1 if (irp->op == IRP_OP_WRITE) { dprintf("WRITE:\n"); dump_const_iobuf(&irp->write); } #endif #if 0 if (irp->op == IRP_OP_READ) { dprintf("READ:\n"); dump_iobuf(&hkb_led_uart.readable); } #endif if (irp->op == IRP_OP_OPEN) { /* Unfortunately the card reader UART gets opened and closed repeatedly */ if (!hkb_led_started) { dprintf("Led: Open\n"); hkb_led_started = true; } else { return S_OK; } } hr = uart_handle_irp(&hkb_led_uart, irp); if (FAILED(hr) || irp->op != IRP_OP_WRITE) { return hr; } hkb_led_uart.written.pos = 0; return hr; }