91 lines
1.9 KiB
C
91 lines
1.9 KiB
C
|
#include <windows.h>
|
||
|
#include <stdbool.h>
|
||
|
#include <stdint.h>
|
||
|
|
||
|
#include "board/qr.h"
|
||
|
|
||
|
#include "hook/table.h"
|
||
|
#include "hook/iobuf.h"
|
||
|
#include "hook/iohook.h"
|
||
|
|
||
|
#include "hooklib/uart.h"
|
||
|
#include "hooklib/fdshark.h"
|
||
|
|
||
|
#include "util/dprintf.h"
|
||
|
#include "util/dump.h"
|
||
|
|
||
|
/*
|
||
|
* Scans QR Codes that the Taiko twitter sometimes
|
||
|
* puts out to unlock songs and other things. Pretty
|
||
|
* sure that it's COM1...
|
||
|
*/
|
||
|
static HRESULT qr_handle_irp_locked(struct irp *irp);
|
||
|
static HRESULT qr_handle_irp(struct irp *irp);
|
||
|
|
||
|
static struct uart qr_uart;
|
||
|
static CRITICAL_SECTION qr_lock;
|
||
|
static uint8_t qr_written_bytes[520];
|
||
|
static uint8_t qr_readable_bytes[520];
|
||
|
|
||
|
HRESULT qr_hook_init(const struct qr_config *cfg, unsigned int port)
|
||
|
{
|
||
|
assert(cfg != NULL);
|
||
|
|
||
|
if (!cfg->enable) {
|
||
|
return S_FALSE;
|
||
|
}
|
||
|
if (cfg->port > 0) {
|
||
|
port = cfg->port;
|
||
|
}
|
||
|
|
||
|
dprintf("QR: Init\n");
|
||
|
|
||
|
uart_init(&qr_uart, port);
|
||
|
qr_uart.written.bytes = qr_written_bytes;
|
||
|
qr_uart.written.nbytes = sizeof(qr_written_bytes);
|
||
|
qr_uart.readable.bytes = qr_readable_bytes;
|
||
|
qr_uart.readable.nbytes = sizeof(qr_readable_bytes);
|
||
|
InitializeCriticalSection(&qr_lock);
|
||
|
|
||
|
return iohook_push_handler(qr_handle_irp);
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
|
||
|
static HRESULT qr_handle_irp(struct irp *irp)
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
|
||
|
assert(irp != NULL);
|
||
|
|
||
|
if (uart_match_irp(&qr_uart, irp)) {
|
||
|
EnterCriticalSection(&qr_lock);
|
||
|
hr = qr_handle_irp_locked(irp);
|
||
|
LeaveCriticalSection(&qr_lock);
|
||
|
}
|
||
|
else {
|
||
|
return iohook_invoke_next(irp);
|
||
|
}
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
static HRESULT qr_handle_irp_locked(struct irp *irp)
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
if (irp->op == IRP_OP_OPEN) {
|
||
|
dprintf("QR: Starting backend\n");
|
||
|
}
|
||
|
|
||
|
hr = uart_handle_irp(&qr_uart, irp);
|
||
|
if (FAILED(hr)) {
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
#if 1
|
||
|
dprintf("QR: IRP_OP %d Written\n", irp->op);
|
||
|
dump_iobuf(&qr_uart.written);
|
||
|
#endif
|
||
|
return S_OK;
|
||
|
}
|