From 55c68c80941dc4e1b33661f0f6f03f986f260c1e Mon Sep 17 00:00:00 2001 From: Tau Date: Tue, 20 Nov 2018 20:29:40 -0500 Subject: [PATCH] cardhook: Wire up aimeReaderHost hook This is an external AiMe driver process that is only used by Chunithm AFAIK. The wiring can be easily re-used for other games. --- cardhook/_com12.c | 178 ++++++++++++++++++++++++++++++++++++++++++ cardhook/_com12.h | 3 + cardhook/cardhook.def | 4 + cardhook/dllmain.c | 42 ++++++++++ cardhook/meson.build | 20 +++++ meson.build | 1 + 6 files changed, 248 insertions(+) create mode 100644 cardhook/_com12.c create mode 100644 cardhook/_com12.h create mode 100644 cardhook/cardhook.def create mode 100644 cardhook/dllmain.c create mode 100644 cardhook/meson.build diff --git a/cardhook/_com12.c b/cardhook/_com12.c new file mode 100644 index 0000000..a87f14b --- /dev/null +++ b/cardhook/_com12.c @@ -0,0 +1,178 @@ +#include + +#include +#include +#include + +#include "board/sg-led.h" +#include "board/sg-nfc.h" + +#include "cardhook/_com12.h" + +#include "hook/iohook.h" + +#include "hooklib/uart.h" + +#include "util/dprintf.h" +#include "util/dump.h" + +static HRESULT com12_handle_irp(struct irp *irp); +static HRESULT com12_handle_irp_locked(struct irp *irp); + +static HRESULT com12_mifare_poll(void *ctx); +static HRESULT com12_mifare_read_luid(void *ctx, uint8_t *luid, size_t nbytes); +static HRESULT com12_led_set_color(void *ctx, uint8_t r, uint8_t g, uint8_t b); + +static const struct sg_nfc_ops com12_nfc_ops = { + .mifare_poll = com12_mifare_poll, + .mifare_read_luid = com12_mifare_read_luid, +}; + +static const struct sg_led_ops com12_led_ops = { + .set_color = com12_led_set_color, +}; + +static struct sg_nfc com12_nfc; +static struct sg_led com12_led; + +static const char com12_aime_path[] = "DEVICE\\aime.txt"; + +static CRITICAL_SECTION com12_lock; +static struct uart com12_uart; +static uint8_t com12_written_bytes[520]; +static uint8_t com12_readable_bytes[520]; +static uint8_t com12_aime_luid[10]; + +void com12_hook_init(void) +{ + sg_nfc_init(&com12_nfc, 0x00, &com12_nfc_ops, NULL); + sg_led_init(&com12_led, 0x08, &com12_led_ops, NULL); + + InitializeCriticalSection(&com12_lock); + + uart_init(&com12_uart, 12); + com12_uart.written.bytes = com12_written_bytes; + com12_uart.written.nbytes = sizeof(com12_written_bytes); + com12_uart.readable.bytes = com12_readable_bytes; + com12_uart.readable.nbytes = sizeof(com12_readable_bytes); + + iohook_push_handler(com12_handle_irp); +} + +static HRESULT com12_handle_irp(struct irp *irp) +{ + HRESULT hr; + + assert(irp != NULL); + + if (!uart_match_irp(&com12_uart, irp)) { + return iohook_invoke_next(irp); + } + + EnterCriticalSection(&com12_lock); + hr = com12_handle_irp_locked(irp); + LeaveCriticalSection(&com12_lock); + + return hr; +} + +static HRESULT com12_handle_irp_locked(struct irp *irp) +{ + HRESULT hr; + +#if 0 + 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(&com12_uart.readable); + } +#endif + + hr = uart_handle_irp(&com12_uart, irp); + + if (FAILED(hr) || irp->op != IRP_OP_WRITE) { + return hr; + } + + sg_nfc_transact( + &com12_nfc, + &com12_uart.readable, + com12_uart.written.bytes, + com12_uart.written.pos); + + sg_led_transact( + &com12_led, + &com12_uart.readable, + com12_uart.written.bytes, + com12_uart.written.pos); + + com12_uart.written.pos = 0; + + return hr; +} + +static HRESULT com12_mifare_poll(void *ctx) +{ + HRESULT hr; + FILE *f; + size_t i; + int byte; + int r; + + hr = S_FALSE; + f = NULL; + + if (!(GetAsyncKeyState(VK_RETURN) & 0x8000)) { + goto end; + } + + f = fopen(com12_aime_path, "r"); + + if (f == NULL) { + dprintf("Aime reader: Failed to open %s\n", com12_aime_path); + + goto end; + } + + for (i = 0 ; i < sizeof(com12_aime_luid) ; i++) { + r = fscanf(f, "%02x ", &byte); + + if (r != 1) { + dprintf("Aime reader: fscanf[%i] failed: %i\n", i, r); + + goto end; + } + + com12_aime_luid[i] = byte; + } + + hr = S_OK; + +end: + if (f != NULL) { + fclose(f); + } + + return hr; +} + +static HRESULT com12_mifare_read_luid(void *ctx, uint8_t *luid, size_t nbytes) +{ + assert(luid != NULL); + assert(nbytes == sizeof(com12_aime_luid)); + + memcpy(luid, com12_aime_luid, nbytes); + + return S_OK; +} + +static HRESULT com12_led_set_color(void *ctx, uint8_t r, uint8_t g, uint8_t b) +{ + return S_OK; +} diff --git a/cardhook/_com12.h b/cardhook/_com12.h new file mode 100644 index 0000000..119dd62 --- /dev/null +++ b/cardhook/_com12.h @@ -0,0 +1,3 @@ +#pragma once + +void com12_hook_init(void); diff --git a/cardhook/cardhook.def b/cardhook/cardhook.def new file mode 100644 index 0000000..af6a011 --- /dev/null +++ b/cardhook/cardhook.def @@ -0,0 +1,4 @@ +LIBRARY cardhook + +EXPORTS + DllMain@12 @1 NONAME diff --git a/cardhook/dllmain.c b/cardhook/dllmain.c new file mode 100644 index 0000000..b810ca1 --- /dev/null +++ b/cardhook/dllmain.c @@ -0,0 +1,42 @@ +#include + +#include "cardhook/_com12.h" + +#include "hook/process.h" + +#include "hooklib/serial.h" + +#include "util/dprintf.h" +#include "util/spike.h" + +static process_entry_t app_startup; + +static DWORD CALLBACK app_pre_startup(void) +{ + dprintf("--- Begin %s ---\n", __func__); + + serial_hook_init(); + spike_hook_init("cardspike.txt"); + com12_hook_init(); + + dprintf("--- End %s ---\n", __func__); + + return app_startup(); +} + +BOOL WINAPI DllMain(HMODULE mod, DWORD cause, void *ctx) +{ + HRESULT hr; + + if (cause != DLL_PROCESS_ATTACH) { + return TRUE; + } + + hr = process_hijack_startup(app_pre_startup, &app_startup); + + if (!SUCCEEDED(hr)) { + dprintf("Failed to hijack process startup: %x\n", (int) hr); + } + + return SUCCEEDED(hr); +} diff --git a/cardhook/meson.build b/cardhook/meson.build new file mode 100644 index 0000000..6714c98 --- /dev/null +++ b/cardhook/meson.build @@ -0,0 +1,20 @@ +shared_library( + 'cardhook', + name_prefix : '', + include_directories: inc, + implicit_include_directories : false, + vs_module_defs : 'cardhook.def', + c_pch : '../precompiled.h', + dependencies : [ + capnhook.get_variable('hook_dep'), + capnhook.get_variable('hooklib_dep'), + ], + link_with : [ + board_lib, + util_lib, + ], + sources : [ + '_com12.c', + 'dllmain.c', + ], +) diff --git a/meson.build b/meson.build index 345a761..d566102 100644 --- a/meson.build +++ b/meson.build @@ -22,5 +22,6 @@ subdir('jvs') subdir('nu') subdir('util') +subdir('cardhook') subdir('chunihook') subdir('minihook')