move QR and USIO to board folder, try to actually emulate the USIO properly
This commit is contained in:
parent
16b1678bdb
commit
69d7b74d95
119
board/bpreader.c
119
board/bpreader.c
@ -26,7 +26,10 @@ static size_t build_bpreader_response(
|
||||
uint8_t *response,
|
||||
const size_t resp_size);
|
||||
|
||||
static HRESULT bpreader_poll_card();
|
||||
static HRESULT bpreader_generic_cmd(uint32_t resp_code);
|
||||
static HRESULT bpreader_poll_card_cmd();
|
||||
static HRESULT bpreader_init_cmd();
|
||||
static HRESULT bpreader_set_output_cmd();
|
||||
|
||||
static struct bpreader_config *config;
|
||||
static struct uart bp_uart;
|
||||
@ -42,7 +45,7 @@ HRESULT bpreader_init(struct bpreader_config *cfg, uint16_t port)
|
||||
if (!config->enable) {
|
||||
return S_OK;
|
||||
}
|
||||
if (cfg->port < 0) {
|
||||
if (cfg->port > 0) {
|
||||
port = cfg->port;
|
||||
}
|
||||
|
||||
@ -57,39 +60,6 @@ HRESULT bpreader_init(struct bpreader_config *cfg, uint16_t port)
|
||||
return iohook_push_handler(bp_handle_irp);
|
||||
}
|
||||
|
||||
void bpreader_congif_load(struct bpreader_config *cfg, const wchar_t *filename)
|
||||
{
|
||||
assert(cfg != NULL);
|
||||
assert(filename != NULL);
|
||||
|
||||
cfg->enable = GetPrivateProfileIntW(L"reader", L"enable", 1, filename);
|
||||
cfg->port = GetPrivateProfileIntW(L"reader", L"port", 0, filename);
|
||||
GetPrivateProfileStringW(
|
||||
L"reader",
|
||||
L"access_code",
|
||||
L"00000000000000000000",
|
||||
cfg->access_code,
|
||||
_countof(cfg->access_code),
|
||||
filename);
|
||||
GetPrivateProfileStringW(
|
||||
L"reader",
|
||||
L"chip_id",
|
||||
L"00000000000000000000000000000000",
|
||||
cfg->chip_id,
|
||||
_countof(cfg->chip_id),
|
||||
filename);
|
||||
|
||||
HRESULT hr = wstr_to_bytes(cfg->access_code, 20, cfg->access_code_bytes, sizeof(cfg->access_code_bytes));
|
||||
if (FAILED(hr)) {
|
||||
dprintf("Reader: wstr_to_bytes 1 failed! 0x%lX", hr);
|
||||
}
|
||||
|
||||
hr = wstr_to_bytes(cfg->chip_id, 32, cfg->chip_id_bytes, sizeof(cfg->chip_id_bytes));
|
||||
if (FAILED(hr)) {
|
||||
dprintf("Reader: wstr_to_bytes 2 failed! 0x%lX", hr);
|
||||
}
|
||||
}
|
||||
|
||||
static HRESULT bp_handle_irp(struct irp *irp)
|
||||
{
|
||||
HRESULT hr;
|
||||
@ -143,6 +113,10 @@ static HRESULT bp_handle_irp_locked(struct irp *irp)
|
||||
if (!read_ct) {
|
||||
//dump_iobuf(&bp_uart.written);
|
||||
hr = crack_bpreader_request();
|
||||
if (!FAILED(hr)) {
|
||||
bp_uart.written.pos = 0;
|
||||
return hr;
|
||||
}
|
||||
}
|
||||
switch (bp_uart.written.bytes[3]) {
|
||||
case 0x02:
|
||||
@ -296,6 +270,7 @@ static HRESULT crack_bpreader_request() {
|
||||
|
||||
case 0x18:
|
||||
dprintf("Reader: Initialize\n");
|
||||
// return bpreader_init_cmd(); FIXME
|
||||
break;
|
||||
|
||||
case 0x0C:
|
||||
@ -304,10 +279,12 @@ static HRESULT crack_bpreader_request() {
|
||||
|
||||
case 0x0E:
|
||||
dprintf("Reader: Set Output\n");
|
||||
return bpreader_generic_cmd(0x0F);
|
||||
break;
|
||||
|
||||
case 0x32:
|
||||
dprintf("Reader: Cmd 0x32\n");
|
||||
//return bpreader_generic_cmd(0x33);
|
||||
break;
|
||||
|
||||
case 0x40:
|
||||
@ -316,7 +293,7 @@ static HRESULT crack_bpreader_request() {
|
||||
|
||||
case 0x4A:
|
||||
dprintf("Reader: Poll Card\n");
|
||||
return bpreader_poll_card();
|
||||
return bpreader_poll_card_cmd();
|
||||
|
||||
case 0xA0:
|
||||
dprintf("Reader: Read Felica\n");
|
||||
@ -326,7 +303,7 @@ static HRESULT crack_bpreader_request() {
|
||||
dprintf("Reader: Unknown command 0x%02x\n", header.cmd);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
return (HRESULT)-1;
|
||||
}
|
||||
|
||||
static size_t build_bpreader_response(
|
||||
@ -349,7 +326,9 @@ static size_t build_bpreader_response(
|
||||
resp_header->header_checksum = 0xFF - ((0xFF + len_data + 2) & 0xFF);
|
||||
|
||||
memcpy_s(response, resp_size, resp_header, sizeof(*resp_header)); // Copy header
|
||||
memcpy_s(&response[7], resp_size - 7, data, len_data); // copy data
|
||||
if (len_data > 0) {
|
||||
memcpy_s(&response[7], resp_size - 7, data, len_data); // copy data if there's any
|
||||
}
|
||||
|
||||
for (int i = 0; i < full_resp_len; i++) {
|
||||
final_checksum = (final_checksum + response[i]) & 0xFF; // Calculate checksum
|
||||
@ -359,7 +338,67 @@ static size_t build_bpreader_response(
|
||||
return full_resp_len;
|
||||
}
|
||||
|
||||
static HRESULT bpreader_poll_card()
|
||||
static HRESULT bpreader_generic_cmd(uint32_t resp_code)
|
||||
{
|
||||
//uint8_t buff[] = { 0x00, 0x00, 0xFF, 0x02, 0xFE, 0xD5, 0x19, 0x12, 0x00 };
|
||||
uint8_t buff[9] = { 0x00 };
|
||||
struct bpreader_cmd_header header = { 0x00, 0x00, 0xFF, 0x02, 0xFE, 0xD5, resp_code };
|
||||
size_t resp_len = 0;
|
||||
|
||||
resp_len = build_bpreader_response((uint8_t *){0}, 0, &header, buff, sizeof(buff));
|
||||
|
||||
if (resp_len > 0) {
|
||||
HRESULT hr = iobuf_write(&bp_uart.readable, buff, resp_len);
|
||||
//dump_iobuf(&bp_uart.readable);
|
||||
return hr;
|
||||
|
||||
} else {
|
||||
dprintf("Reader: No data to return in bpreader_generic_cmd (0x%2X response code)!\n", resp_code);
|
||||
return E_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
static HRESULT bpreader_init_cmd()
|
||||
{
|
||||
//uint8_t buff[] = { 0x00, 0x00, 0xFF, 0x02, 0xFE, 0xD5, 0x19, 0x12, 0x00 };
|
||||
uint8_t buff[9] = { 0x00 };
|
||||
struct bpreader_cmd_header header = { 0x00, 0x00, 0xFF, 0x02, 0xFE, 0xD5, 0x19 };
|
||||
size_t resp_len = 0;
|
||||
|
||||
resp_len = build_bpreader_response((uint8_t *){0}, 0, &header, buff, sizeof(buff));
|
||||
|
||||
if (resp_len > 0) {
|
||||
HRESULT hr = iobuf_write(&bp_uart.readable, buff, resp_len);
|
||||
dump_iobuf(&bp_uart.readable);
|
||||
return hr;
|
||||
|
||||
} else {
|
||||
dprintf("Reader: No data to return in bpreader_init_cmd!\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
static HRESULT bpreader_set_output_cmd()
|
||||
{
|
||||
//uint8_t buff[] = { 0x00, 0x00, 0xFF, 0x02, 0xFE, 0xD5, 0x0F, 0x1C, 0x00 };
|
||||
uint8_t buff[9] = { 0x00 };
|
||||
struct bpreader_cmd_header header = { 0x00, 0x00, 0xFF, 0x02, 0xFE, 0xD5, 0x0F };
|
||||
size_t resp_len = 0;
|
||||
|
||||
resp_len = build_bpreader_response((uint8_t *){0}, 0, &header, buff, sizeof(buff));
|
||||
|
||||
if (resp_len > 0) {
|
||||
HRESULT hr = iobuf_write(&bp_uart.readable, buff, resp_len);
|
||||
dump_iobuf(&bp_uart.readable);
|
||||
return hr;
|
||||
|
||||
} else {
|
||||
dprintf("Reader: No data to return in bpreader_set_output_cmd!\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
static HRESULT bpreader_poll_card_cmd()
|
||||
{
|
||||
struct bpreader_cmd_header header = { 0x00, 0x00, 0xFF, 0x03, 0xFD, 0xD5, 0x4B };
|
||||
struct bpreader_poll_banapass_data data = { 0x00 };
|
||||
@ -388,7 +427,7 @@ static HRESULT bpreader_poll_card()
|
||||
return hr;
|
||||
|
||||
} else {
|
||||
dprintf("Reader: No data to return in bpreader_poll_card!\n");
|
||||
dprintf("Reader: No data to return in bpreader_poll_card_cmd!\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
}
|
@ -13,7 +13,6 @@ struct bpreader_config {
|
||||
};
|
||||
|
||||
HRESULT bpreader_init(struct bpreader_config *cfg, uint16_t port);
|
||||
void bpreader_congif_load(struct bpreader_config *cfg, const wchar_t *filename);
|
||||
|
||||
/*
|
||||
bpreader packet format WIP
|
||||
|
61
board/config.c
Normal file
61
board/config.c
Normal file
@ -0,0 +1,61 @@
|
||||
#include <windows.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "board/config.h"
|
||||
#include "board/bpreader.h"
|
||||
#include "util/dprintf.h"
|
||||
#include "util/hexstr.h"
|
||||
|
||||
void bpreader_config_load(struct bpreader_config *cfg, const wchar_t *filename)
|
||||
{
|
||||
assert(cfg != NULL);
|
||||
assert(filename != NULL);
|
||||
|
||||
cfg->enable = GetPrivateProfileIntW(L"reader", L"enable", 1, filename);
|
||||
cfg->port = GetPrivateProfileIntW(L"reader", L"port", 0, filename);
|
||||
GetPrivateProfileStringW(
|
||||
L"reader",
|
||||
L"access_code",
|
||||
L"00000000000000000000",
|
||||
cfg->access_code,
|
||||
_countof(cfg->access_code),
|
||||
filename);
|
||||
GetPrivateProfileStringW(
|
||||
L"reader",
|
||||
L"chip_id",
|
||||
L"00000000000000000000000000000000",
|
||||
cfg->chip_id,
|
||||
_countof(cfg->chip_id),
|
||||
filename);
|
||||
|
||||
HRESULT hr = wstr_to_bytes(cfg->access_code, 20, cfg->access_code_bytes, sizeof(cfg->access_code_bytes));
|
||||
if (FAILED(hr)) {
|
||||
dprintf("Reader: wstr_to_bytes 1 failed! 0x%lX", hr);
|
||||
}
|
||||
|
||||
hr = wstr_to_bytes(cfg->chip_id, 32, cfg->chip_id_bytes, sizeof(cfg->chip_id_bytes));
|
||||
if (FAILED(hr)) {
|
||||
dprintf("Reader: wstr_to_bytes 2 failed! 0x%lX", hr);
|
||||
}
|
||||
}
|
||||
|
||||
void usio_config_load(struct usio_config *cfg, const wchar_t *filename)
|
||||
{
|
||||
assert(cfg != NULL);
|
||||
assert(filename != NULL);
|
||||
|
||||
cfg->enable = GetPrivateProfileIntW(L"usio", L"enable", 1, filename);
|
||||
}
|
||||
|
||||
void qr_config_load(struct qr_config *cfg, const wchar_t *filename)
|
||||
{
|
||||
assert(cfg != NULL);
|
||||
assert(filename != NULL);
|
||||
|
||||
cfg->enable = GetPrivateProfileIntW(L"qr", L"enable", 1, filename);
|
||||
cfg->port = GetPrivateProfileIntW(L"qr", L"port", 0, filename);
|
||||
}
|
12
board/config.h
Normal file
12
board/config.h
Normal file
@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "board/usio.h"
|
||||
#include "board/bpreader.h"
|
||||
#include "board/qr.h"
|
||||
|
||||
void bpreader_config_load(struct bpreader_config *cfg, const wchar_t *filename);
|
||||
void usio_config_load(struct usio_config *cfg, const wchar_t *filename);
|
||||
void qr_config_load(struct qr_config *cfg, const wchar_t *filename);
|
3
board/guid.c
Normal file
3
board/guid.c
Normal file
@ -0,0 +1,3 @@
|
||||
#include <initguid.h>
|
||||
|
||||
#include "board/guid.h"
|
10
board/guid.h
Normal file
10
board/guid.h
Normal file
@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
DEFINE_GUID(
|
||||
usio_guid,
|
||||
0xE54BF304L,
|
||||
0x66A3,
|
||||
0x476F,
|
||||
0xA4, 0x56, 0xC6, 0xDD, 0xAB, 0x8C, 0x70, 0x78);
|
@ -1,5 +1,5 @@
|
||||
board_lib = static_library(
|
||||
'gfxhook',
|
||||
'board',
|
||||
include_directories : inc,
|
||||
implicit_include_directories : false,
|
||||
c_pch : '../precompiled.h',
|
||||
@ -15,6 +15,14 @@ board_lib = static_library(
|
||||
'bpreader.c',
|
||||
'bpreader.h',
|
||||
'najv4.c',
|
||||
'najv4.h'
|
||||
'najv4.h',
|
||||
'config.c',
|
||||
'config.h',
|
||||
'guid.c',
|
||||
'guid.h',
|
||||
'usio.c',
|
||||
'usio.h',
|
||||
'qr.c',
|
||||
'qr.h',
|
||||
],
|
||||
)
|
||||
|
@ -72,6 +72,11 @@ static HRESULT najv4_cmd_read_analogs(
|
||||
struct const_iobuf *req_buf,
|
||||
struct iobuf *resp_buf);
|
||||
|
||||
static HRESULT najv4_cmd_analog_out(
|
||||
struct najv4 *najv4,
|
||||
struct const_iobuf *req_buf,
|
||||
struct iobuf *resp_buf);
|
||||
|
||||
static HRESULT najv4_cmd_write_gpio(
|
||||
struct najv4 *najv4,
|
||||
struct const_iobuf *req_buf,
|
||||
@ -264,6 +269,9 @@ static HRESULT najv4_cmd(
|
||||
case JVS_CMD_READ_ANALOGS:
|
||||
return najv4_cmd_read_analogs(najv4, req, resp);
|
||||
|
||||
case JVS_CMD_ANALOG_OUT:
|
||||
return najv4_cmd_analog_out(najv4, req, resp);
|
||||
|
||||
case JVS_CMD_WRITE_GPIO:
|
||||
return najv4_cmd_write_gpio(najv4, req, resp);
|
||||
|
||||
@ -589,6 +597,37 @@ static HRESULT najv4_cmd_read_analogs(
|
||||
|
||||
}
|
||||
|
||||
static HRESULT najv4_cmd_analog_out(
|
||||
struct najv4 *najv4,
|
||||
struct const_iobuf *req_buf,
|
||||
struct iobuf *resp_buf)
|
||||
{
|
||||
uint8_t cmd;
|
||||
uint8_t channel_ct;
|
||||
uint16_t bytes[MAX_PATH];
|
||||
HRESULT hr;
|
||||
|
||||
hr = iobuf_read_8(req_buf, &cmd);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
hr = iobuf_read_8(req_buf, &channel_ct);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
for (int i = 0; i < channel_ct; i++) {
|
||||
iobuf_read_be16(req_buf, &bytes[i]);
|
||||
}
|
||||
|
||||
//dprintf("JVS I/O: Write Analog Out to %d channels\n", channel_ct);
|
||||
|
||||
return iobuf_write_8(resp_buf, 0x01);
|
||||
}
|
||||
|
||||
static HRESULT najv4_cmd_write_gpio(
|
||||
struct najv4 *najv4,
|
||||
struct const_iobuf *req_buf,
|
||||
@ -748,6 +787,7 @@ static HRESULT najv4_cmd_namco_extend_noop_cmd(
|
||||
|
||||
return iobuf_write_8(resp_buf, 1);
|
||||
|
||||
case 0x14B4:
|
||||
case 0x143c: // Run it back??
|
||||
hr = iobuf_read_8(req_buf, &cmd); // cmd (0x70)
|
||||
hr = iobuf_read_8(req_buf, &subcmd); // subcmd (0x18)
|
||||
@ -759,7 +799,7 @@ static HRESULT najv4_cmd_namco_extend_noop_cmd(
|
||||
return iobuf_write_8(resp_buf, 1);
|
||||
|
||||
default:
|
||||
dprintf("\nJVS I/O: Namco Extended Command 0x18 param unknown!\n");
|
||||
dprintf("\nJVS I/O: Namco Extended Command 0x18 param unknown! %04X\n", param);
|
||||
dump_const_iobuf(req_buf);
|
||||
|
||||
return iobuf_write_8(resp_buf, 1);
|
||||
|
91
board/qr.c
Normal file
91
board/qr.c
Normal file
@ -0,0 +1,91 @@
|
||||
#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;
|
||||
}
|
@ -5,7 +5,7 @@
|
||||
|
||||
struct qr_config {
|
||||
bool enable;
|
||||
unsigned int port;
|
||||
};
|
||||
|
||||
HRESULT qr_hook_init(const struct qr_config *cfg);
|
||||
void qr_insert_hooks(HMODULE target);
|
||||
HRESULT qr_hook_init(const struct qr_config *cfg, unsigned int port);
|
176
board/usio.c
Normal file
176
board/usio.c
Normal file
@ -0,0 +1,176 @@
|
||||
#include <windows.h>
|
||||
|
||||
#include <devioctl.h>
|
||||
#include <hidclass.h>
|
||||
#include <winusb.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "board/config.h"
|
||||
#include "board/guid.h"
|
||||
#include "board/usio.h"
|
||||
|
||||
#include "hook/iobuf.h"
|
||||
#include "hook/iohook.h"
|
||||
|
||||
#include "hooklib/setupapi.h"
|
||||
|
||||
#include "util/dprintf.h"
|
||||
#include "util/dump.h"
|
||||
|
||||
#pragma pack(push, 1)
|
||||
enum {
|
||||
USIO_CMD_SET_COMM_TIMEOUT = 0x01,
|
||||
USIO_CMD_SET_SAMPLING_COUNT = 0x02,
|
||||
USIO_CMD_CLEAR_BOARD_STATUS = 0x03,
|
||||
USIO_CMD_SET_GENERAL_OUTPUT = 0x04,
|
||||
USIO_CMD_SET_PWM_OUTPUT = 0x05,
|
||||
USIO_CMD_UNIMPLEMENTED = 0x41,
|
||||
USIO_CMD_UPDATE_FIRMWARE = 0x85,
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
static HRESULT usio_handle_irp(struct irp *irp);
|
||||
static HRESULT usio_handle_open(struct irp *irp);
|
||||
static HRESULT usio_handle_close(struct irp *irp);
|
||||
static HRESULT usio_handle_read(struct irp *irp);
|
||||
static HRESULT usio_handle_write(struct irp *irp);
|
||||
static HRESULT usio_handle_ioctl(struct irp *irp);
|
||||
|
||||
static HRESULT usio_ioctl_get_manufacturer_string(struct irp *irp);
|
||||
static HRESULT usio_ioctl_get_product_string(struct irp *irp);
|
||||
|
||||
static const wchar_t usio_path[] = L"$usio";
|
||||
//static const wchar_t usio_path[] = L"USBIO_Device0";
|
||||
|
||||
static HANDLE usio_fd;
|
||||
static const struct usio_ops *usio_ops;
|
||||
static void *usio_ops_ctx;
|
||||
|
||||
HRESULT usio_hook_init(
|
||||
const struct usio_config *cfg,
|
||||
const struct usio_ops *ops,
|
||||
void *ctx)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
assert(cfg != NULL);
|
||||
assert(ops != NULL);
|
||||
|
||||
if (!cfg->enable) {
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
hr = iohook_open_nul_fd(&usio_fd);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
usio_ops = ops;
|
||||
usio_ops_ctx = ctx;
|
||||
iohook_push_handler(usio_handle_irp);
|
||||
|
||||
hr = setupapi_add_phantom_dev(&usio_guid, usio_path);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
dprintf("USIO: Init\n");
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT usio_handle_irp(struct irp *irp)
|
||||
{
|
||||
assert(irp != NULL);
|
||||
|
||||
if (irp->op != IRP_OP_OPEN && irp->fd != usio_fd) {
|
||||
return iohook_invoke_next(irp);
|
||||
}
|
||||
|
||||
switch (irp->op) {
|
||||
case IRP_OP_OPEN: return usio_handle_open(irp);
|
||||
case IRP_OP_CLOSE: return usio_handle_close(irp);
|
||||
case IRP_OP_READ: return usio_handle_read(irp);
|
||||
case IRP_OP_WRITE: return usio_handle_write(irp);
|
||||
case IRP_OP_IOCTL: return usio_handle_ioctl(irp);
|
||||
default: return HRESULT_FROM_WIN32(ERROR_INVALID_FUNCTION);
|
||||
}
|
||||
}
|
||||
|
||||
static HRESULT usio_handle_open(struct irp *irp)
|
||||
{
|
||||
if (wcscmp(irp->open_filename, usio_path) != 0) {
|
||||
return iohook_invoke_next(irp);
|
||||
}
|
||||
|
||||
dprintf("USIO: Device opened\n");
|
||||
irp->fd = usio_fd;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT usio_handle_close(struct irp *irp)
|
||||
{
|
||||
dprintf("USIO: Device closed\n");
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT usio_handle_read(struct irp *irp)
|
||||
{
|
||||
dprintf("USIO: Read\n");
|
||||
dump_iobuf(&irp->read);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT usio_handle_write(struct irp *irp)
|
||||
{
|
||||
dprintf("USIO: Write\n");
|
||||
dump_const_iobuf(&irp->write);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT usio_handle_ioctl(struct irp *irp)
|
||||
{
|
||||
switch (irp->ioctl) {
|
||||
case IOCTL_HID_GET_MANUFACTURER_STRING:
|
||||
dprintf("USIO: Get Manufacturer String\n");
|
||||
//return usio_ioctl_get_manufacturer_string(irp);
|
||||
|
||||
case IOCTL_HID_GET_PRODUCT_STRING:
|
||||
dprintf("USIO: Get Product String\n");
|
||||
//return usio_ioctl_get_product_string(irp);
|
||||
|
||||
case IOCTL_HID_GET_INPUT_REPORT:
|
||||
dprintf("USIO: Control IN (untested!!)\n");
|
||||
|
||||
//return usio_handle_read(irp);
|
||||
|
||||
case IOCTL_HID_SET_OUTPUT_REPORT:
|
||||
dprintf("USIO: Control OUT (untested!!)\n");
|
||||
|
||||
//return usio_handle_write(irp);
|
||||
|
||||
default:
|
||||
dprintf("USIO: Unknown ioctl %#08x, write %i read %i\n",
|
||||
irp->ioctl,
|
||||
(int) irp->write.nbytes,
|
||||
(int) irp->read.nbytes);
|
||||
#if 1
|
||||
dprintf("USIO: Written\n");
|
||||
dump_const_iobuf(&irp->write);
|
||||
dprintf("USIO: Read\n");
|
||||
dump_iobuf(&irp->read);
|
||||
#endif
|
||||
|
||||
return HRESULT_FROM_WIN32(ERROR_INVALID_FUNCTION);
|
||||
}
|
||||
}
|
32
board/usio.h
Normal file
32
board/usio.h
Normal file
@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
enum {
|
||||
/* System buttons in button[0] */
|
||||
|
||||
USIO_BUTTON_TEST = 1 << 9,
|
||||
USIO_BUTTON_SERVICE = 1 << 6,
|
||||
};
|
||||
|
||||
struct usio_config {
|
||||
bool enable;
|
||||
};
|
||||
|
||||
struct usio_state {
|
||||
uint16_t adcs[8];
|
||||
uint16_t spinners[4];
|
||||
uint16_t chutes[2];
|
||||
uint16_t buttons[2];
|
||||
};
|
||||
|
||||
struct usio_ops {
|
||||
HRESULT (*poll)(void *ctx, struct usio_state *state);
|
||||
};
|
||||
|
||||
HRESULT usio_hook_init(
|
||||
const struct usio_config *cfg,
|
||||
const struct usio_ops *ops,
|
||||
void *ctx);
|
@ -43,5 +43,5 @@ void ferrum_hook_config_load(
|
||||
ferrum_dll_config_load(&cfg->dll, filename);
|
||||
ferrum_xinput_config_load(&cfg->xinput, filename);
|
||||
gfx_config_load(&cfg->gfx, filename);
|
||||
bpreader_congif_load(&cfg->reader, filename);
|
||||
bpreader_config_load(&cfg->reader, filename);
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
#include "ferrumhook/ferrum-dll.h"
|
||||
#include "ferrumhook/xinput.h"
|
||||
#include "ferrumhook/jvs.h"
|
||||
#include "board/bpreader.h"
|
||||
#include "board/config.h"
|
||||
|
||||
#include "platform/config.h"
|
||||
#include "gfxhook/config.h"
|
||||
|
@ -23,6 +23,12 @@ static void setupapi_hook_init(void);
|
||||
|
||||
/* API hooks */
|
||||
|
||||
static HDEVINFO WINAPI my_SetupDiGetClassDevsA(
|
||||
const GUID *ClassGuid,
|
||||
char *Enumerator,
|
||||
HWND hwndParent,
|
||||
DWORD Flags);
|
||||
|
||||
static HDEVINFO WINAPI my_SetupDiGetClassDevsW(
|
||||
const GUID *ClassGuid,
|
||||
wchar_t *Enumerator,
|
||||
@ -44,10 +50,24 @@ static BOOL WINAPI my_SetupDiGetDeviceInterfaceDetailW(
|
||||
DWORD *RequiredSize,
|
||||
SP_DEVINFO_DATA *DeviceInfoData);
|
||||
|
||||
static BOOL WINAPI my_SetupDiGetDeviceInterfaceDetailA(
|
||||
HDEVINFO DeviceInfoSet,
|
||||
SP_DEVICE_INTERFACE_DATA *DeviceInterfaceData,
|
||||
SP_DEVICE_INTERFACE_DETAIL_DATA_A *DeviceInterfaceDetailData,
|
||||
DWORD DeviceInterfaceDetailDataSize,
|
||||
DWORD *RequiredSize,
|
||||
SP_DEVINFO_DATA *DeviceInfoData);
|
||||
|
||||
static BOOL WINAPI my_SetupDiDestroyDeviceInfoList(HDEVINFO DeviceInfoSet);
|
||||
|
||||
/* Links */
|
||||
|
||||
static HDEVINFO (WINAPI *next_SetupDiGetClassDevsA)(
|
||||
const GUID *ClassGuid,
|
||||
char *Enumerator,
|
||||
HWND hwndParent,
|
||||
DWORD Flags);
|
||||
|
||||
static HDEVINFO (WINAPI *next_SetupDiGetClassDevsW)(
|
||||
const GUID *ClassGuid,
|
||||
wchar_t *Enumerator,
|
||||
@ -69,12 +89,24 @@ static BOOL (WINAPI *next_SetupDiGetDeviceInterfaceDetailW)(
|
||||
DWORD *RequiredSize,
|
||||
SP_DEVINFO_DATA *DeviceInfoData);
|
||||
|
||||
static BOOL (WINAPI *next_SetupDiGetDeviceInterfaceDetailA)(
|
||||
HDEVINFO DeviceInfoSet,
|
||||
SP_DEVICE_INTERFACE_DATA *DeviceInterfaceData,
|
||||
SP_DEVICE_INTERFACE_DETAIL_DATA_A *DeviceInterfaceDetailData,
|
||||
DWORD DeviceInterfaceDetailDataSize,
|
||||
DWORD *RequiredSize,
|
||||
SP_DEVINFO_DATA *DeviceInfoData);
|
||||
|
||||
static BOOL (WINAPI *next_SetupDiDestroyDeviceInfoList)(HDEVINFO DeviceInfoSet);
|
||||
|
||||
/* Hook tbl */
|
||||
|
||||
static const struct hook_symbol setupapi_syms[] = {
|
||||
{
|
||||
.name = "SetupDiGetClassDevsA",
|
||||
.patch = my_SetupDiGetClassDevsA,
|
||||
.link = (void *) &next_SetupDiGetClassDevsA,
|
||||
}, {
|
||||
.name = "SetupDiGetClassDevsW",
|
||||
.patch = my_SetupDiGetClassDevsW,
|
||||
.link = (void *) &next_SetupDiGetClassDevsW,
|
||||
@ -86,6 +118,10 @@ static const struct hook_symbol setupapi_syms[] = {
|
||||
.name = "SetupDiGetDeviceInterfaceDetailW",
|
||||
.patch = my_SetupDiGetDeviceInterfaceDetailW,
|
||||
.link = (void *) &next_SetupDiGetDeviceInterfaceDetailW,
|
||||
}, {
|
||||
.name = "SetupDiGetDeviceInterfaceDetailA",
|
||||
.patch = my_SetupDiGetDeviceInterfaceDetailA,
|
||||
.link = (void *) &next_SetupDiGetDeviceInterfaceDetailA,
|
||||
}, {
|
||||
.name = "SetupDiDestroyDeviceInfoList",
|
||||
.patch = my_SetupDiDestroyDeviceInfoList,
|
||||
@ -155,6 +191,40 @@ void setupapi_hook_insert_hooks(HMODULE target)
|
||||
_countof(setupapi_syms));
|
||||
}
|
||||
|
||||
static HDEVINFO WINAPI my_SetupDiGetClassDevsA(
|
||||
const GUID *ClassGuid,
|
||||
char *Enumerator,
|
||||
HWND hwndParent,
|
||||
DWORD Flags)
|
||||
{
|
||||
struct setupapi_class *class_;
|
||||
HDEVINFO result;
|
||||
size_t i;
|
||||
|
||||
result = next_SetupDiGetClassDevsA(
|
||||
ClassGuid,
|
||||
Enumerator,
|
||||
hwndParent,
|
||||
Flags);
|
||||
|
||||
if (result == INVALID_HANDLE_VALUE || ClassGuid == NULL) {
|
||||
return result;
|
||||
}
|
||||
|
||||
EnterCriticalSection(&setupapi_lock);
|
||||
|
||||
for (i = 0 ; i < setupapi_nclasses ; i++) {
|
||||
class_ = &setupapi_classes[i];
|
||||
if (memcmp(ClassGuid, class_->guid, sizeof(*ClassGuid)) == 0) {
|
||||
class_->cur_handle = result;
|
||||
}
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&setupapi_lock);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static HDEVINFO WINAPI my_SetupDiGetClassDevsW(
|
||||
const GUID *ClassGuid,
|
||||
wchar_t *Enumerator,
|
||||
@ -322,6 +392,83 @@ pass:
|
||||
DeviceInfoData);
|
||||
}
|
||||
|
||||
static BOOL WINAPI my_SetupDiGetDeviceInterfaceDetailA(
|
||||
HDEVINFO DeviceInfoSet,
|
||||
SP_DEVICE_INTERFACE_DATA *DeviceInterfaceData,
|
||||
SP_DEVICE_INTERFACE_DETAIL_DATA_A *DeviceInterfaceDetailData,
|
||||
DWORD DeviceInterfaceDetailDataSize,
|
||||
DWORD *RequiredSize,
|
||||
SP_DEVINFO_DATA *DeviceInfoData)
|
||||
{
|
||||
const wchar_t *wstr;
|
||||
char path_ch[MAX_PATH];
|
||||
size_t nbytes_wstr;
|
||||
size_t nbytes_str;
|
||||
size_t nbytes_total;
|
||||
size_t i;
|
||||
bool match;
|
||||
|
||||
if (DeviceInfoSet == INVALID_HANDLE_VALUE || DeviceInterfaceData == NULL) {
|
||||
goto pass;
|
||||
}
|
||||
|
||||
EnterCriticalSection(&setupapi_lock);
|
||||
|
||||
for ( i = 0, match = false ;
|
||||
i < setupapi_nclasses && !match ;
|
||||
i++) {
|
||||
if ( DeviceInfoSet == setupapi_classes[i].cur_handle &&
|
||||
DeviceInterfaceData->Reserved == (ULONG_PTR) setupapi_classes[i].path) {
|
||||
match = true;
|
||||
}
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&setupapi_lock);
|
||||
|
||||
if (!match) {
|
||||
goto pass;
|
||||
}
|
||||
|
||||
wstr = (const wchar_t *) DeviceInterfaceData->Reserved;
|
||||
nbytes_wstr = (wcslen(wstr) + 1) * sizeof(wchar_t);
|
||||
|
||||
wcstombs(path_ch, (wchar_t *) DeviceInterfaceData->Reserved, MAX_PATH);
|
||||
nbytes_str = strlen(path_ch) * sizeof(char);
|
||||
nbytes_total = offsetof(SP_DEVICE_INTERFACE_DETAIL_DATA_A, DevicePath);
|
||||
nbytes_total += nbytes_str;
|
||||
|
||||
if (RequiredSize != NULL) {
|
||||
*RequiredSize = (DWORD) nbytes_total;
|
||||
}
|
||||
|
||||
if ( DeviceInterfaceDetailData == NULL &&
|
||||
DeviceInterfaceDetailDataSize < nbytes_total) {
|
||||
SetLastError(ERROR_INSUFFICIENT_BUFFER);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (DeviceInterfaceDetailData->cbSize!=sizeof(*DeviceInterfaceDetailData)) {
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
memcpy(DeviceInterfaceDetailData->DevicePath, path_ch, nbytes_str);
|
||||
SetLastError(ERROR_SUCCESS);
|
||||
|
||||
return TRUE;
|
||||
|
||||
pass:
|
||||
return next_SetupDiGetDeviceInterfaceDetailA(
|
||||
DeviceInfoSet,
|
||||
DeviceInterfaceData,
|
||||
DeviceInterfaceDetailData,
|
||||
DeviceInterfaceDetailDataSize,
|
||||
RequiredSize,
|
||||
DeviceInfoData);
|
||||
}
|
||||
|
||||
static BOOL WINAPI my_SetupDiDestroyDeviceInfoList(HDEVINFO DeviceInfoSet)
|
||||
{
|
||||
size_t i;
|
||||
|
@ -11,6 +11,7 @@ enum {
|
||||
JVS_CMD_READ_COIN = 0x21,
|
||||
JVS_CMD_READ_ANALOGS = 0x22,
|
||||
JVS_CMD_WRITE_GPIO = 0x32,
|
||||
JVS_CMD_ANALOG_OUT = 0x33,
|
||||
JVS_CMD_RESET = 0xF0,
|
||||
JVS_CMD_ASSIGN_ADDR = 0xF1,
|
||||
JVS_CMD_NAMCO_EXTEND = 0x70,
|
||||
|
@ -1,7 +1,4 @@
|
||||
#include <windows.h>
|
||||
|
||||
#include "taikohook/bnusio.h"
|
||||
#include "taikohook/qr.h"
|
||||
#include "taikohook/config.h"
|
||||
|
||||
#include "hook/table.h"
|
||||
@ -17,28 +14,6 @@
|
||||
* to reinvent the wheel for the most part, we can just hook the functions
|
||||
* that AMFW uses and let it talk to the game for us.
|
||||
*/
|
||||
void amfw_dongle_insert_hooks(HMODULE target);
|
||||
|
||||
static int my_nbamUsbFinderInitialize();
|
||||
static int my_nbamUsbFinderGetSerialNumber(int a1, char serial[32]);
|
||||
static int my_nbamUsbFinder_GetInformation(int a1, int a2, uint64_t a3, uint16_t a4, void *a5);
|
||||
|
||||
static const struct hook_symbol dongle_hooks[] = {
|
||||
{
|
||||
.name = "nbamUsbFinderInitialize",
|
||||
.patch = my_nbamUsbFinderInitialize
|
||||
},
|
||||
{
|
||||
.name = "nbamUsbFinderGetSerialNumber",
|
||||
.patch = my_nbamUsbFinderGetSerialNumber
|
||||
},
|
||||
{
|
||||
.name = "nbamUsbFinder_GetInformation",
|
||||
.patch = my_nbamUsbFinder_GetInformation
|
||||
},
|
||||
};
|
||||
|
||||
char g_serial[13] = {0};
|
||||
|
||||
HRESULT amfw_hook_init(wchar_t serial[13])
|
||||
{
|
||||
@ -55,40 +30,7 @@ HRESULT amfw_hook_init(wchar_t serial[13])
|
||||
|
||||
dprintf("AMFW: Found AMFrameWork Handle\n");
|
||||
|
||||
bnusio_insert_hooks(hMod);
|
||||
amfw_dongle_insert_hooks(hMod);
|
||||
path_hook_insert_hooks(hMod);
|
||||
qr_insert_hooks(hMod);
|
||||
wcstombs_s(NULL, g_serial, sizeof(g_serial), serial, 26);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void amfw_dongle_insert_hooks(HMODULE target) {
|
||||
hook_table_apply(
|
||||
target,
|
||||
"nbamUsbFinder.dll",
|
||||
dongle_hooks,
|
||||
_countof(dongle_hooks));
|
||||
}
|
||||
|
||||
static int my_nbamUsbFinderInitialize()
|
||||
{
|
||||
dprintf("AMFW: nbamUsbFinderInitialize\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int my_nbamUsbFinderGetSerialNumber(int a1, char serial[32])
|
||||
{
|
||||
dprintf("AMFW: nbamUsbFinderGetSerialNumber %d serial %s\n", a1, g_serial);
|
||||
strcpy_s(serial, 32, g_serial);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int my_nbamUsbFinder_GetInformation(int a1, int a2, uint64_t a3, uint16_t a4, void *a5)
|
||||
{
|
||||
dprintf("AMFW: nbamUsbFinder_GetInformation %d\n", a1);
|
||||
memset(a5, 0x00, 0x628);
|
||||
//memcpy(a5 + 0x428, L"123456789012\0", 26);
|
||||
return 0;
|
||||
}
|
||||
|
@ -21,28 +21,8 @@ void taiko_dll_config_load(
|
||||
filename);
|
||||
}
|
||||
|
||||
void bnusio_config_load(
|
||||
struct bnusio_config *cfg,
|
||||
const wchar_t *filename)
|
||||
{
|
||||
assert(cfg != NULL);
|
||||
assert(filename != NULL);
|
||||
|
||||
cfg->enable = GetPrivateProfileIntW(L"bnusio", L"enable", 1, filename);
|
||||
}
|
||||
|
||||
void qr_config_load(
|
||||
struct qr_config *cfg,
|
||||
const wchar_t *filename)
|
||||
{
|
||||
assert(cfg != NULL);
|
||||
assert(filename != NULL);
|
||||
|
||||
cfg->enable = GetPrivateProfileIntW(L"qr", L"enable", 1, filename);
|
||||
}
|
||||
|
||||
void network_config_load(
|
||||
struct ferrum_network_config *cfg,
|
||||
struct taiko_network_config *cfg,
|
||||
const wchar_t *filename)
|
||||
{
|
||||
assert(cfg != NULL);
|
||||
@ -60,9 +40,10 @@ void taiko_hook_config_load(
|
||||
|
||||
platform_config_load(&cfg->platform, filename);
|
||||
taiko_dll_config_load(&cfg->dll, filename);
|
||||
bnusio_config_load(&cfg->bnusio, filename);
|
||||
gfx_config_load(&cfg->gfx, filename);
|
||||
qr_config_load(&cfg->qr, filename);
|
||||
network_config_load(&cfg->network, filename);
|
||||
bpreader_congif_load(&cfg->reader, filename);
|
||||
bpreader_config_load(&cfg->reader, filename);
|
||||
usio_config_load(&cfg->usio, filename);
|
||||
|
||||
}
|
||||
|
@ -3,40 +3,34 @@
|
||||
#include <stddef.h>
|
||||
|
||||
#include "taikohook/taiko-dll.h"
|
||||
#include "taikohook/bnusio.h"
|
||||
#include "taikohook/qr.h"
|
||||
#include "taikohook/network.h"
|
||||
|
||||
#include "platform/config.h"
|
||||
#include "gfxhook/config.h"
|
||||
#include "amcus/config.h"
|
||||
#include "board/bpreader.h"
|
||||
#include "board/config.h"
|
||||
|
||||
struct taiko_hook_config {
|
||||
struct platform_config platform;
|
||||
struct taiko_dll_config dll;
|
||||
struct bnusio_config bnusio;
|
||||
struct gfx_config gfx;
|
||||
struct amcus_config amcus;
|
||||
struct qr_config qr;
|
||||
struct ferrum_network_config network;
|
||||
struct taiko_network_config network;
|
||||
struct bpreader_config reader;
|
||||
struct usio_config usio;
|
||||
};
|
||||
|
||||
void taiko_dll_config_load(
|
||||
struct taiko_dll_config *cfg,
|
||||
const wchar_t *filename);
|
||||
|
||||
void bnusio_config_load(
|
||||
struct bnusio_config *cfg,
|
||||
const wchar_t *filename);
|
||||
|
||||
void qr_config_load(
|
||||
struct qr_config *cfg,
|
||||
const wchar_t *filename);
|
||||
|
||||
void network_config_load(
|
||||
struct ferrum_network_config *cfg,
|
||||
struct taiko_network_config *cfg,
|
||||
const wchar_t *filename);
|
||||
|
||||
void taiko_hook_config_load(
|
||||
|
@ -3,10 +3,12 @@
|
||||
|
||||
#include "taikohook/config.h"
|
||||
#include "taikohook/taiko-dll.h"
|
||||
#include "taikohook/bnusio.h"
|
||||
#include "taikohook/amfw.h"
|
||||
#include "taikohook/network.h"
|
||||
#include "taikohook/qr.h"
|
||||
#include "taikohook/usio.h"
|
||||
|
||||
#include "board/bpreader.h"
|
||||
#include "board/qr.h"
|
||||
|
||||
#include "amcus/amcus.h"
|
||||
|
||||
@ -36,8 +38,8 @@ static DWORD CALLBACK taiko_pre_startup(void)
|
||||
serial_hook_init();
|
||||
|
||||
struct dongle_info dinfo;
|
||||
dinfo.pid = 0;
|
||||
dinfo.vid = 0;
|
||||
dinfo.pid = 0x0C00;
|
||||
dinfo.vid = 0x0B9A;
|
||||
|
||||
hr = platform_hook_init(&taiko_hook_cfg.platform, PLATFORM_BNA1, NULL, taiko_hook_mod, dinfo);
|
||||
|
||||
@ -51,13 +53,19 @@ static DWORD CALLBACK taiko_pre_startup(void)
|
||||
ExitProcess(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
hr = bnusio_hook_init(&taiko_hook_cfg.bnusio);
|
||||
hr = taiko_usio_hook_init(&taiko_hook_cfg.usio);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
ExitProcess(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
hr = qr_hook_init(&taiko_hook_cfg.qr);
|
||||
hr = qr_hook_init(&taiko_hook_cfg.qr, 1);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
ExitProcess(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
hr = bpreader_init(&taiko_hook_cfg.reader, 3);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
ExitProcess(EXIT_FAILURE);
|
||||
|
@ -26,15 +26,11 @@ shared_library(
|
||||
'config.h',
|
||||
'taiko-dll.c',
|
||||
'taiko-dll.h',
|
||||
'bnusio.c',
|
||||
'bnusio.h',
|
||||
'amfw.c',
|
||||
'amfw.h',
|
||||
'qr.c',
|
||||
'qr.h',
|
||||
'network.c',
|
||||
'network.h',
|
||||
'bngrw.c',
|
||||
'bngrw.h',
|
||||
'usio.c',
|
||||
'usio.h',
|
||||
],
|
||||
)
|
||||
|
@ -6,6 +6,13 @@
|
||||
|
||||
#include "util/dprintf.h"
|
||||
|
||||
/*
|
||||
* Forces Taiko to use TLS v1.2 instead of 1.0
|
||||
* This was made to solve a niche issue with
|
||||
* the server stack I was using. Recomend
|
||||
* leaving it disabled.
|
||||
*/
|
||||
|
||||
void network_insert_hooks(HMODULE target);
|
||||
|
||||
static uint64_t my_TLSv1_method(uint64_t a1, uint64_t flag);
|
||||
@ -24,7 +31,7 @@ static const struct hook_symbol nethook_syms[] = {
|
||||
},
|
||||
};
|
||||
|
||||
HRESULT network_hook_init(const struct ferrum_network_config *cfg)
|
||||
HRESULT network_hook_init(const struct taiko_network_config *cfg)
|
||||
{
|
||||
if (!cfg->enable) {
|
||||
return S_FALSE;
|
||||
|
@ -3,8 +3,8 @@
|
||||
#include <windows.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
struct ferrum_network_config {
|
||||
struct taiko_network_config {
|
||||
bool enable;
|
||||
};
|
||||
|
||||
HRESULT network_hook_init(const struct ferrum_network_config *cfg);
|
||||
HRESULT network_hook_init(const struct taiko_network_config *cfg);
|
@ -1,80 +0,0 @@
|
||||
#include <windows.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "taikohook/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"
|
||||
|
||||
static int my_nbamQrInitialize(void *qr);
|
||||
static int my_nbamQrEncode(void *qr, void *info);
|
||||
static int my_nbamQrGetQrImageSize(void *qr, void *info);
|
||||
|
||||
static const struct hook_symbol qr_hooks[] = {
|
||||
{
|
||||
.name = "nbamQrInitialize(void * *)",
|
||||
.patch = my_nbamQrInitialize,
|
||||
.ordinal = 6
|
||||
},
|
||||
{
|
||||
.name = "nbamQrEncode(void *,nbamQr_encode_info_t *)",
|
||||
.patch = my_nbamQrInitialize,
|
||||
.ordinal = 3
|
||||
},
|
||||
{
|
||||
.name = "nbamQrGetQrImageSize(void *,nbamQr_encode_info_t *)",
|
||||
.patch = my_nbamQrInitialize,
|
||||
.ordinal = 5
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
HRESULT qr_hook_init(const struct qr_config *cfg)
|
||||
{
|
||||
assert(cfg != NULL);
|
||||
|
||||
if (!cfg->enable) {
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
dprintf("QR: Init\n");
|
||||
// Hook the DLL the game loads
|
||||
qr_insert_hooks(NULL);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void qr_insert_hooks(HMODULE target)
|
||||
{
|
||||
hook_table_apply(
|
||||
target,
|
||||
"Nbam_QR_Code.dll",
|
||||
qr_hooks,
|
||||
_countof(qr_hooks));
|
||||
}
|
||||
|
||||
static int my_nbamQrInitialize(void *qr)
|
||||
{
|
||||
dprintf("QR: nbamQrInitialize\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int my_nbamQrEncode(void *qr, void *info)
|
||||
{
|
||||
dprintf("QR: nbamQrEncode\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int my_nbamQrGetQrImageSize(void *qr, void *info)
|
||||
{
|
||||
dprintf("QR: nbamQrGetQrImageSize\n");
|
||||
return 0;
|
||||
}
|
43
taikohook/usio.c
Normal file
43
taikohook/usio.c
Normal file
@ -0,0 +1,43 @@
|
||||
#include <windows.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "board/usio.h"
|
||||
|
||||
#include "taikohook/taiko-dll.h"
|
||||
|
||||
#include "util/dprintf.h"
|
||||
|
||||
bool taiko_io_coin = false;
|
||||
uint16_t taiko_io_coins = 0;
|
||||
|
||||
static HRESULT taiko_usio_poll(void *ctx, struct usio_state *state);
|
||||
|
||||
static const struct usio_ops taiko_usio_ops = {
|
||||
.poll = taiko_usio_poll,
|
||||
};
|
||||
|
||||
HRESULT taiko_usio_hook_init(const struct usio_config *cfg)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
assert(taiko_dll.init != NULL);
|
||||
|
||||
hr = usio_hook_init(cfg, &taiko_usio_ops, NULL);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
dprintf("Taiko USIO: Init\n");
|
||||
|
||||
return taiko_dll.init();
|
||||
}
|
||||
|
||||
static HRESULT taiko_usio_poll(void *ctx, struct usio_state *state)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
7
taikohook/usio.h
Normal file
7
taikohook/usio.h
Normal file
@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "board/usio.h"
|
||||
|
||||
HRESULT taiko_usio_hook_init(const struct usio_config *cfg);
|
@ -6,12 +6,22 @@
|
||||
|
||||
#include "taikoio/config.h"
|
||||
|
||||
void taiko_io_config_load(struct taiko_input_config *cfg, const char *filename)
|
||||
void taiko_io_config_load(struct taiko_input_config *cfg, const wchar_t *filename)
|
||||
{
|
||||
cfg->test = GetPrivateProfileIntW(L"input", L"test", VK_HOME, filename);
|
||||
cfg->service = GetPrivateProfileIntW(L"input", L"service", VK_DELETE, filename);
|
||||
cfg->coin = GetPrivateProfileIntW(L"input", L"coin", VK_INSERT, filename);
|
||||
cfg->up = GetPrivateProfileIntW(L"input", L"up", VK_UP, filename);
|
||||
cfg->down = GetPrivateProfileIntW(L"input", L"down", VK_DOWN, filename);
|
||||
cfg->enter = GetPrivateProfileIntW(L"input", L"enter", VK_RETURN, filename);
|
||||
cfg->test = GetPrivateProfileIntW(L"usio", L"test", VK_HOME, filename);
|
||||
cfg->service = GetPrivateProfileIntW(L"usio", L"service", VK_DELETE, filename);
|
||||
cfg->coin = GetPrivateProfileIntW(L"usio", L"coin", VK_INSERT, filename);
|
||||
cfg->up = GetPrivateProfileIntW(L"usio", L"up", VK_UP, filename);
|
||||
cfg->down = GetPrivateProfileIntW(L"usio", L"down", VK_DOWN, filename);
|
||||
cfg->enter = GetPrivateProfileIntW(L"usio", L"enter", VK_RETURN, filename);
|
||||
|
||||
cfg->p1_rim_l = GetPrivateProfileIntW(L"drum", L"p1_rim_l", 'Z', filename);
|
||||
cfg->p1_center_l = GetPrivateProfileIntW(L"usio", L"p1_center_l", 'X', filename);
|
||||
cfg->p1_center_r = GetPrivateProfileIntW(L"usio", L"p1_center_r", 'C', filename);
|
||||
cfg->p1_rim_r = GetPrivateProfileIntW(L"usio", L"p1_rim_r", 'V', filename);
|
||||
|
||||
cfg->p2_rim_l = GetPrivateProfileIntW(L"drum", L"p2_rim_l", 'U', filename);
|
||||
cfg->p2_center_l = GetPrivateProfileIntW(L"usio", L"p2_center_l", 'I', filename);
|
||||
cfg->p2_center_r = GetPrivateProfileIntW(L"usio", L"p2_center_r", 'O', filename);
|
||||
cfg->p2_rim_r = GetPrivateProfileIntW(L"usio", L"p2_rim_r", 'P', filename);
|
||||
}
|
@ -3,6 +3,7 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct taiko_input_config {
|
||||
uint8_t test;
|
||||
uint8_t service;
|
||||
@ -10,4 +11,16 @@ struct taiko_input_config {
|
||||
uint8_t down;
|
||||
uint8_t enter;
|
||||
uint8_t coin;
|
||||
|
||||
uint8_t p1_rim_l;
|
||||
uint8_t p1_center_l;
|
||||
uint8_t p1_center_r;
|
||||
uint8_t p1_rim_r;
|
||||
uint8_t p2_rim_l;
|
||||
uint8_t p2_center_l;
|
||||
uint8_t p2_center_r;
|
||||
uint8_t p2_rim_r;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
void taiko_io_config_load(struct taiko_input_config *cfg, const wchar_t *filename);
|
@ -10,5 +10,7 @@ taikoio_lib = static_library(
|
||||
sources : [
|
||||
'taikoio.c',
|
||||
'taikoio.h',
|
||||
'config.c',
|
||||
'config.h',
|
||||
],
|
||||
)
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "taikoio/taikoio.h"
|
||||
#include "taikoio/config.h"
|
||||
|
||||
#include "util/dprintf.h"
|
||||
|
||||
@ -16,6 +17,7 @@ static uint8_t taiko_opbtn = 0;
|
||||
static uint16_t taiko_gamebtn = 0;
|
||||
static uint16_t taiko_coin_ct = 0;
|
||||
static uint16_t taiko_service_ct = 0;
|
||||
static struct taiko_input_config cfg;
|
||||
|
||||
uint16_t taiko_io_get_api_version(void)
|
||||
{
|
||||
@ -25,6 +27,7 @@ uint16_t taiko_io_get_api_version(void)
|
||||
HRESULT taiko_io_init(void)
|
||||
{
|
||||
dprintf("Taiko IO: Init\n");
|
||||
taiko_io_config_load(&cfg, L".\\bananatools.ini");
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@ -33,55 +36,55 @@ HRESULT taiko_io_poll(void)
|
||||
taiko_opbtn = 0;
|
||||
taiko_gamebtn = 0;
|
||||
|
||||
if ((GetAsyncKeyState(VK_HOME) & 0x8000)) {
|
||||
if ((GetAsyncKeyState(cfg.test) & 0x8000)) {
|
||||
taiko_opbtn |= TAIKO_IO_OPBTN_TEST;
|
||||
}
|
||||
|
||||
if (GetAsyncKeyState(VK_DELETE) & 0x8000) {
|
||||
if (GetAsyncKeyState(cfg.service) & 0x8000) {
|
||||
taiko_opbtn |= TAIKO_IO_OPBTN_SERVICE;
|
||||
}
|
||||
|
||||
if (GetAsyncKeyState(VK_UP) & 0x8000) {
|
||||
if (GetAsyncKeyState(cfg.up) & 0x8000) {
|
||||
taiko_opbtn |= TAIKO_IO_OPBTN_UP;
|
||||
}
|
||||
|
||||
if (GetAsyncKeyState(VK_DOWN) & 0x8000) {
|
||||
if (GetAsyncKeyState(cfg.down) & 0x8000) {
|
||||
taiko_opbtn |= TAIKO_IO_OPBTN_DOWN;
|
||||
}
|
||||
|
||||
if (GetAsyncKeyState(VK_RETURN) & 0x8000) {
|
||||
if (GetAsyncKeyState(cfg.enter) & 0x8000) {
|
||||
taiko_opbtn |= TAIKO_IO_OPBTN_ENTER;
|
||||
}
|
||||
|
||||
if (GetAsyncKeyState('Z') & 0x8000) {
|
||||
if (GetAsyncKeyState(cfg.p1_rim_l) & 0x8000) {
|
||||
taiko_gamebtn |= TAIKO_IO_P1_RIM_L;
|
||||
}
|
||||
|
||||
if (GetAsyncKeyState('X') & 0x8000) {
|
||||
if (GetAsyncKeyState(cfg.p1_center_l) & 0x8000) {
|
||||
taiko_gamebtn |= TAIKO_IO_P1_CENTER_L;
|
||||
}
|
||||
|
||||
if (GetAsyncKeyState('C') & 0x8000) {
|
||||
if (GetAsyncKeyState(cfg.p1_center_r) & 0x8000) {
|
||||
taiko_gamebtn |= TAIKO_IO_P1_CENTER_R;
|
||||
}
|
||||
|
||||
if (GetAsyncKeyState('V') & 0x8000) {
|
||||
if (GetAsyncKeyState(cfg.p1_rim_r) & 0x8000) {
|
||||
taiko_gamebtn |= TAIKO_IO_P1_RIM_R;
|
||||
}
|
||||
|
||||
if (GetAsyncKeyState('U') & 0x8000) {
|
||||
if (GetAsyncKeyState(cfg.p2_rim_l) & 0x8000) {
|
||||
taiko_gamebtn |= TAIKO_IO_P2_RIM_L;
|
||||
}
|
||||
|
||||
if (GetAsyncKeyState('I') & 0x8000) {
|
||||
if (GetAsyncKeyState(cfg.p2_center_l) & 0x8000) {
|
||||
taiko_gamebtn |= TAIKO_IO_P2_CENTER_L;
|
||||
}
|
||||
|
||||
if (GetAsyncKeyState('O') & 0x8000) {
|
||||
if (GetAsyncKeyState(cfg.p2_center_r) & 0x8000) {
|
||||
taiko_gamebtn |= TAIKO_IO_P2_CENTER_R;
|
||||
}
|
||||
|
||||
if (GetAsyncKeyState('P') & 0x8000) {
|
||||
if (GetAsyncKeyState(cfg.p2_rim_r) & 0x8000) {
|
||||
taiko_gamebtn |= TAIKO_IO_P2_RIM_R;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user