segatools/hkbhook/led.c

99 lines
2.1 KiB
C

#include <windows.h>
#include <stdbool.h>
#include <stdint.h>
#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;
}