From e495bfb8f1b3927f612aa0da910127150d199cb7 Mon Sep 17 00:00:00 2001 From: Will Xyen Date: Sat, 12 Oct 2019 04:17:06 -0400 Subject: [PATCH] bio2emu: Refactor out the BIO2 emulation code so that it can be reused Also make it support multiple BIO2 devices if needed (DRS) --- Module.mk | 1 + src/main/bio2emu/Module.mk | 8 + src/main/bio2emu/emu.c | 107 +++++++++++ src/main/bio2emu/emu.h | 28 +++ src/main/bio2emu/setupapi.c | 327 ++++++++++++++++++++++++++++++++++ src/main/bio2emu/setupapi.h | 8 + src/main/iidxhook8/Module.mk | 3 +- src/main/iidxhook8/bi2a.c | 52 +++--- src/main/iidxhook8/bi2a.h | 7 +- src/main/iidxhook8/bio2.c | 84 --------- src/main/iidxhook8/bio2.h | 14 -- src/main/iidxhook8/dllmain.c | 25 ++- src/main/iidxhook8/setupapi.c | 287 ----------------------------- src/main/iidxhook8/setupapi.h | 6 - 14 files changed, 530 insertions(+), 427 deletions(-) create mode 100644 src/main/bio2emu/Module.mk create mode 100644 src/main/bio2emu/emu.c create mode 100644 src/main/bio2emu/emu.h create mode 100644 src/main/bio2emu/setupapi.c create mode 100644 src/main/bio2emu/setupapi.h delete mode 100644 src/main/iidxhook8/bio2.c delete mode 100644 src/main/iidxhook8/bio2.h delete mode 100644 src/main/iidxhook8/setupapi.c delete mode 100644 src/main/iidxhook8/setupapi.h diff --git a/Module.mk b/Module.mk index 849a425..9e09936 100644 --- a/Module.mk +++ b/Module.mk @@ -74,6 +74,7 @@ imps += avs avs-ea3 include src/main/aciodrv/Module.mk include src/main/acioemu/Module.mk include src/main/aciotest/Module.mk +include src/main/bio2emu/Module.mk include src/main/bsthook/Module.mk include src/main/bstio/Module.mk include src/main/cconfig/Module.mk diff --git a/src/main/bio2emu/Module.mk b/src/main/bio2emu/Module.mk new file mode 100644 index 0000000..208b3e4 --- /dev/null +++ b/src/main/bio2emu/Module.mk @@ -0,0 +1,8 @@ +libs += bio2emu + +libs_bio2emu := \ + acioemu \ + +src_bio2emu := \ + emu.c \ + setupapi.c \ diff --git a/src/main/bio2emu/emu.c b/src/main/bio2emu/emu.c new file mode 100644 index 0000000..abca733 --- /dev/null +++ b/src/main/bio2emu/emu.c @@ -0,0 +1,107 @@ +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include "acioemu/addr.h" +#include "acioemu/emu.h" + +#include "hook/iohook.h" +#include "hooklib/rs232.h" + +#include "bio2emu/emu.h" +#include "bio2emu/setupapi.h" + +#include "imports/avs.h" + +#include "util/defs.h" +#include "util/iobuf.h" +#include "util/log.h" +#include "util/str.h" +#include "util/array.h" + +static struct array bio2_active_ports; + +void bio2emu_init_start() +{ + array_init(&bio2_active_ports); +} + +void bio2emu_init_end() +{ + bio2emu_setupapi_hook_init(&bio2_active_ports); +} + +void bio2emu_port_init(struct bio2emu_port* bio2_emu) +{ + // BIO2 seems like ACIO with just 1 device + ac_io_emu_init(&bio2_emu->acio, bio2_emu->wport); + rs232_hook_add_fd(bio2_emu->acio.fd); + + *array_append(struct bio2emu_port*, &bio2_active_ports) = bio2_emu; +} + +void bio2emu_port_fini(struct bio2emu_port* bio2_emu) +{ + ac_io_emu_fini(&bio2_emu->acio); +} + +HRESULT bio2emu_port_dispatch_irp(struct irp *irp) +{ + const struct ac_io_message *msg; + HRESULT hr; + + log_assert(irp != NULL); + + struct bio2emu_port* check = NULL; + struct bio2emu_port* selected_emu = NULL; + + for (size_t i = 0 ; i < bio2_active_ports.nitems ; i++) { + check = *array_item(struct bio2emu_port*, &bio2_active_ports, i); + if (ac_io_emu_match_irp(&check->acio, irp)) { + selected_emu = check; + } + } + + if (!selected_emu) { + return irp_invoke_next(irp); + } + + struct ac_io_emu* emu = &selected_emu->acio; + + for (;;) { + hr = ac_io_emu_dispatch_irp(emu, irp); + + if (hr != S_OK) { + return hr; + } + + msg = ac_io_emu_request_peek(emu); + + switch (msg->addr) { + case 0: + ac_io_emu_cmd_assign_addrs(emu, msg, 1); + break; + + case 1: + selected_emu->dispatcher(selected_emu, msg); + break; + + case AC_IO_BROADCAST: + log_warning("Broadcast(?) message on BIO2 bus?"); + break; + + default: + log_warning("BIO2 message on unhandled bus address: %d", msg->addr); + break; + } + + ac_io_emu_request_pop(emu); + } +} diff --git a/src/main/bio2emu/emu.h b/src/main/bio2emu/emu.h new file mode 100644 index 0000000..fc37ed9 --- /dev/null +++ b/src/main/bio2emu/emu.h @@ -0,0 +1,28 @@ +#ifndef BIO2EMU_H +#define BIO2EMU_BIO2EMU_H + +#include "hook/iohook.h" +#include "acioemu/emu.h" + +struct bio2emu_port; +struct ac_io_message; + +typedef void (*bio2_bi2a_dispatcher)(struct bio2emu_port *emu, const struct ac_io_message *req); + +struct bio2emu_port { + struct ac_io_emu acio; + const char* port; + const wchar_t* wport; + bio2_bi2a_dispatcher dispatcher; +}; + + +void bio2emu_init_start(); +void bio2emu_init_end(); + +void bio2emu_port_init(struct bio2emu_port* bio2emu_emu); +void bio2emu_port_fini(struct bio2emu_port* bio2emu_emu); + +HRESULT bio2emu_port_dispatch_irp(struct irp *irp); + +#endif diff --git a/src/main/bio2emu/setupapi.c b/src/main/bio2emu/setupapi.c new file mode 100644 index 0000000..3acf78d --- /dev/null +++ b/src/main/bio2emu/setupapi.c @@ -0,0 +1,327 @@ +#define LOG_MODULE "setupapi-hook" + +#include +#include +#include + +#include "hook/table.h" + +#include "bio2emu/setupapi.h" +#include "bio2emu/emu.h" + +#include "util/defs.h" +#include "util/log.h" +#include "util/str.h" +#include "util/time.h" + +#define MAX_INSTANCES_HOOKED 8 + +static struct array* bio2_assigned_ports = NULL; + +static BOOL my_SetupDiDestroyDeviceInfoList( + HDEVINFO DeviceInfoSet +); + +static BOOL (*real_SetupDiDestroyDeviceInfoList)( + HDEVINFO DeviceInfoSet +); + +static BOOL my_SetupDiEnumDeviceInfo( + HDEVINFO DeviceInfoSet, + DWORD MemberIndex, + PSP_DEVINFO_DATA DeviceInfoData +); + +static BOOL (*real_SetupDiEnumDeviceInfo)( + HDEVINFO DeviceInfoSet, + DWORD MemberIndex, + PSP_DEVINFO_DATA DeviceInfoData +); + +static HKEY my_SetupDiOpenDevRegKey( + HDEVINFO DeviceInfoSet, + PSP_DEVINFO_DATA DeviceInfoData, + DWORD Scope, + DWORD HwProfile, + DWORD KeyType, + REGSAM samDesired +); + +static HKEY (*real_SetupDiOpenDevRegKey)( + HDEVINFO DeviceInfoSet, + PSP_DEVINFO_DATA DeviceInfoData, + DWORD Scope, + DWORD HwProfile, + DWORD KeyType, + REGSAM samDesired +); + +static BOOL my_SetupDiGetDeviceRegistryPropertyA( + HDEVINFO DeviceInfoSet, + PSP_DEVINFO_DATA DeviceInfoData, + DWORD Property, + PDWORD PropertyRegDataType, + PBYTE PropertyBuffer, + DWORD PropertyBufferSize, + PDWORD RequiredSize +); + +static BOOL (*real_SetupDiGetDeviceRegistryPropertyA)( + HDEVINFO DeviceInfoSet, + PSP_DEVINFO_DATA DeviceInfoData, + DWORD Property, + PDWORD PropertyRegDataType, + PBYTE PropertyBuffer, + DWORD PropertyBufferSize, + PDWORD RequiredSize +); + +static BOOL my_SetupDiGetDeviceInfoListDetailA( + HDEVINFO DeviceInfoSet, + PSP_DEVINFO_LIST_DETAIL_DATA_A DeviceInfoSetDetailData +); + +static BOOL (*real_SetupDiGetDeviceInfoListDetailA)( + HDEVINFO DeviceInfoSet, + PSP_DEVINFO_LIST_DETAIL_DATA_A DeviceInfoSetDetailData +); + +static HDEVINFO my_SetupDiGetClassDevsA( + CONST GUID *ClassGuid, + PCSTR Enumerator, + HWND hwndParent, + DWORD Flags +); + +static HDEVINFO(*real_SetupDiGetClassDevsA)( + CONST GUID *ClassGuid, + PCSTR Enumerator, + HWND hwndParent, + DWORD Flags +); + +static const struct hook_symbol bio2emu_setupapi_syms[] = { + { + .name = "SetupDiDestroyDeviceInfoList", + .patch = my_SetupDiDestroyDeviceInfoList, + .link = (void **) &real_SetupDiDestroyDeviceInfoList + }, + { + .name = "SetupDiEnumDeviceInfo", + .patch = my_SetupDiEnumDeviceInfo, + .link = (void **) &real_SetupDiEnumDeviceInfo + }, + { + .name = "SetupDiOpenDevRegKey", + .patch = my_SetupDiOpenDevRegKey, + .link = (void **) &real_SetupDiOpenDevRegKey + }, + { + .name = "SetupDiGetDeviceRegistryPropertyA", + .patch = my_SetupDiGetDeviceRegistryPropertyA, + .link = (void **) &real_SetupDiGetDeviceRegistryPropertyA + }, + { + .name = "SetupDiGetDeviceInfoListDetailA", + .patch = my_SetupDiGetDeviceInfoListDetailA, + .link = (void **) &real_SetupDiGetDeviceInfoListDetailA + }, + { + .name = "SetupDiGetClassDevsA", + .patch = my_SetupDiGetClassDevsA, + .link = (void **) &real_SetupDiGetClassDevsA + }, +}; + +static LSTATUS my_RegQueryValueExA( + HKEY hKey, + LPCSTR lpValueName, + LPDWORD lpReserved, + LPDWORD lpType, + LPBYTE lpData, + LPDWORD lpcbData +); +static LSTATUS (*real_RegQueryValueExA)( + HKEY hKey, + LPCSTR lpValueName, + LPDWORD lpReserved, + LPDWORD lpType, + LPBYTE lpData, + LPDWORD lpcbData +); + +static const struct hook_symbol bio2emu_Advapi32_syms[] = { + { + .name = "RegQueryValueExA", + .patch = my_RegQueryValueExA, + .link = (void **) &real_RegQueryValueExA + }, +}; + +static void* CUSTOM_DEVICE_HANDLE; +static struct HKEY__ CUSTOM_REGISTRY_HANDLE[MAX_INSTANCES_HOOKED]; + +static BOOL check_if_match(HKEY ptr, HKEY base) { + return (ptr >= &base[0]) && (ptr <= &base[MAX_INSTANCES_HOOKED - 1]); +} + +static size_t get_match_index(HKEY ptr, HKEY base) { + for (size_t i = 0; i < MAX_INSTANCES_HOOKED; ++i) { + if (ptr == &base[i]) { + return i; + } + } + return -1; +} + +static BOOL my_SetupDiDestroyDeviceInfoList( + HDEVINFO DeviceInfoSet +){ + if (DeviceInfoSet == &CUSTOM_DEVICE_HANDLE){ + log_info("Inside: %s", __FUNCTION__); + return true; + } + return real_SetupDiDestroyDeviceInfoList(DeviceInfoSet); +} + +static BOOL my_SetupDiEnumDeviceInfo( + HDEVINFO DeviceInfoSet, + DWORD MemberIndex, + PSP_DEVINFO_DATA DeviceInfoData +){ + if (DeviceInfoSet == &CUSTOM_DEVICE_HANDLE){ + log_info("%s: Loaded idx %ld", __FUNCTION__, MemberIndex); + if (MemberIndex < MAX_INSTANCES_HOOKED) { + DeviceInfoData->DevInst = MemberIndex; + return true; + } + return false; + } + return real_SetupDiEnumDeviceInfo(DeviceInfoSet, MemberIndex, DeviceInfoData); +} + +static HKEY my_SetupDiOpenDevRegKey( + HDEVINFO DeviceInfoSet, + PSP_DEVINFO_DATA DeviceInfoData, + DWORD Scope, + DWORD HwProfile, + DWORD KeyType, + REGSAM samDesired +){ + if (DeviceInfoSet == &CUSTOM_DEVICE_HANDLE){ + if (DeviceInfoData->DevInst < MAX_INSTANCES_HOOKED){ + log_info("%s: matched instance", __FUNCTION__); + return &CUSTOM_REGISTRY_HANDLE[DeviceInfoData->DevInst]; + } + } + return real_SetupDiOpenDevRegKey(DeviceInfoSet, DeviceInfoData, Scope, HwProfile, KeyType, samDesired); +} + +static const char DEVICE_PROPERTY_VALUE[] = "BIO2(VIDEO)("; +static const size_t DEVICE_PROPERTY_LENGTH = 12; + +static BOOL my_SetupDiGetDeviceRegistryPropertyA( + HDEVINFO DeviceInfoSet, + PSP_DEVINFO_DATA DeviceInfoData, + DWORD Property, + PDWORD PropertyRegDataType, + PBYTE PropertyBuffer, + DWORD PropertyBufferSize, + PDWORD RequiredSize +){ + if (DeviceInfoSet == &CUSTOM_DEVICE_HANDLE){ + if (DeviceInfoData->DevInst< MAX_INSTANCES_HOOKED){ + struct bio2emu_port* selected_port = *array_item(struct bio2emu_port*, bio2_assigned_ports, DeviceInfoData->DevInst); + size_t portname_len = strlen(selected_port->port); + size_t required_size = (DEVICE_PROPERTY_LENGTH + portname_len + 1 + 1); // + 1 for ')', + 1 for NULL + + if (PropertyBuffer && (PropertyBufferSize >= required_size)){ + char* PropBuffStr = (char*)PropertyBuffer; + + strcpy(PropBuffStr, DEVICE_PROPERTY_VALUE); + strcpy(PropBuffStr + DEVICE_PROPERTY_LENGTH, selected_port->port); + strcpy(PropBuffStr + DEVICE_PROPERTY_LENGTH + portname_len, ")"); + + log_info("%s: Done copying property name [%s]", __FUNCTION__, PropBuffStr); + } else { + log_info("%s: Returning size", __FUNCTION__); + *RequiredSize = required_size; + } + } + log_info("%s: STUB RETURN", __FUNCTION__); + return true; + } + return real_SetupDiGetDeviceRegistryPropertyA(DeviceInfoSet, DeviceInfoData, Property, PropertyRegDataType, PropertyBuffer, PropertyBufferSize, RequiredSize); +} + +static BOOL my_SetupDiGetDeviceInfoListDetailA( + HDEVINFO DeviceInfoSet, + PSP_DEVINFO_LIST_DETAIL_DATA_A DeviceInfoSetDetailData +){ + if (DeviceInfoSet == &CUSTOM_DEVICE_HANDLE){ + log_info("Inside: %s", __FUNCTION__); + return true; + } + return real_SetupDiGetDeviceInfoListDetailA(DeviceInfoSet, DeviceInfoSetDetailData); +} + +DEFINE_GUID(GUID_COM_BUS_ENUMERATOR, + 0x4D36E978, 0xE325, 0x11CE, 0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18); + +static HDEVINFO my_SetupDiGetClassDevsA( + CONST GUID *ClassGuid, + PCSTR Enumerator, + HWND hwndParent, + DWORD Flags +){ + if (ClassGuid) { + if (IsEqualGUID(ClassGuid, &GUID_COM_BUS_ENUMERATOR)){ + log_info("Inside: %s", __FUNCTION__); + return &CUSTOM_DEVICE_HANDLE; + } + } + return real_SetupDiGetClassDevsA(ClassGuid, Enumerator, hwndParent, Flags); +} + +static LSTATUS my_RegQueryValueExA( + HKEY hKey, + LPCSTR lpValueName, + LPDWORD lpReserved, + LPDWORD lpType, + LPBYTE lpData, + LPDWORD lpcbData +){ + if (check_if_match(hKey, CUSTOM_REGISTRY_HANDLE)){ + if (strcmp(lpValueName, "PortName") == 0) { + if (lpData){ + size_t portidx = get_match_index(hKey, CUSTOM_REGISTRY_HANDLE); + struct bio2emu_port* selected_port = *array_item(struct bio2emu_port*, bio2_assigned_ports, portidx); + strncpy((char*)lpData, selected_port->port, *lpcbData); + + log_info("%s: Queried %s", __FUNCTION__, selected_port->port); + return ERROR_SUCCESS; + } + return ERROR_MORE_DATA; + } + } + return real_RegQueryValueExA(hKey, lpValueName, lpReserved, lpType, lpData, lpcbData); +} + +void bio2emu_setupapi_hook_init(struct array* bio2_ports) +{ + bio2_assigned_ports = bio2_ports; + + hook_table_apply( + NULL, + "setupapi.dll", + bio2emu_setupapi_syms, + lengthof(bio2emu_setupapi_syms)); + + hook_table_apply( + NULL, + "Advapi32.dll", + bio2emu_Advapi32_syms, + lengthof(bio2emu_Advapi32_syms)); + + log_info("Inserted setupapi hooks"); +} diff --git a/src/main/bio2emu/setupapi.h b/src/main/bio2emu/setupapi.h new file mode 100644 index 0000000..ac72c7d --- /dev/null +++ b/src/main/bio2emu/setupapi.h @@ -0,0 +1,8 @@ +#ifndef BIO2EMU_SETUPAPI_H +#define BIO2EMU_SETUPAPI_H + +#include "util/array.h" + +void bio2emu_setupapi_hook_init(struct array* bio2_ports); + +#endif diff --git a/src/main/iidxhook8/Module.mk b/src/main/iidxhook8/Module.mk index 1f0b269..7a5f344 100644 --- a/src/main/iidxhook8/Module.mk +++ b/src/main/iidxhook8/Module.mk @@ -14,6 +14,7 @@ deplibs_iidxhook8 := \ libs_iidxhook8 := \ iidxhook-util \ acioemu \ + bio2emu \ iidxio \ hook \ hooklib \ @@ -23,9 +24,7 @@ libs_iidxhook8 := \ src_iidxhook8 := \ bi2a.c \ - bio2.c \ cam.c \ config-cam.c \ config-io.c \ dllmain.c \ - setupapi.c \ diff --git a/src/main/iidxhook8/bi2a.c b/src/main/iidxhook8/bi2a.c index 7caca87..eea5082 100644 --- a/src/main/iidxhook8/bi2a.c +++ b/src/main/iidxhook8/bi2a.c @@ -1,6 +1,7 @@ #define LOG_MODULE "bio2emu-bi2a" #include "iidxhook8/bi2a.h" +#include "bio2emu/emu.h" #include /* for _BitScanForward */ @@ -13,12 +14,11 @@ #include "bemanitools/iidxio.h" static int get_default_slider_valid(size_t idx); -static void bio2_emu_bi2a_cmd_send_version(const struct ac_io_message *req); -static void bio2_emu_bi2a_send_state(const struct ac_io_message *req); -static void bio2_emu_bi2a_send_empty(const struct ac_io_message *req); -static void bio2_emu_bi2a_send_status(const struct ac_io_message *req, uint8_t status); +static void bio2_emu_bi2a_cmd_send_version(struct ac_io_emu *emu, const struct ac_io_message *req); +static void bio2_emu_bi2a_send_state(struct ac_io_emu *emu, const struct ac_io_message *req); +static void bio2_emu_bi2a_send_empty(struct ac_io_emu *emu, const struct ac_io_message *req); +static void bio2_emu_bi2a_send_status(struct ac_io_emu *emu, const struct ac_io_message *req, uint8_t status); -static struct ac_io_emu *bi2a_bio2; static int default_sliders[5]; static bool poll_delay; @@ -30,10 +30,10 @@ int get_default_slider_valid(size_t idx) { } } -void bio2_emu_bi2a_init(struct ac_io_emu *bio2_emu, bool disable_poll_limiter) +void bio2_emu_bi2a_init(struct bio2emu_port *bio2_emu, bool disable_poll_limiter) { - FILE* f; - bi2a_bio2 = bio2_emu; + bio2emu_port_init(bio2_emu); + poll_delay = !disable_poll_limiter; if (!poll_delay) { log_warning("bio2_emu_bi2a_init: poll_delay has been disabled"); @@ -43,7 +43,7 @@ void bio2_emu_bi2a_init(struct ac_io_emu *bio2_emu, bool disable_poll_limiter) default_sliders[i] = -1; } - f = fopen("vefx.txt", "r"); + FILE* f = fopen("vefx.txt", "r"); if (f) { fscanf(f, "%d %d %d %d %d", &default_sliders[0], &default_sliders[1], &default_sliders[2], &default_sliders[3], &default_sliders[4]); fclose(f); @@ -51,7 +51,7 @@ void bio2_emu_bi2a_init(struct ac_io_emu *bio2_emu, bool disable_poll_limiter) } -void bio2_emu_bi2a_dispatch_request(const struct ac_io_message *req) +void bio2_emu_bi2a_dispatch_request(struct bio2emu_port *bio2port, const struct ac_io_message *req) { uint16_t cmd_code; @@ -61,27 +61,27 @@ void bio2_emu_bi2a_dispatch_request(const struct ac_io_message *req) case BIO2_BI2A_CMD_UNK_0100: case BIO2_BI2A_CMD_UNK_0120: log_misc("BIO2_BI2A_CMD_UNK_%04X(%d)", cmd_code, req->addr); - bio2_emu_bi2a_send_status(req, 0x00); + bio2_emu_bi2a_send_status(&bio2port->acio, req, 0x00); break; case BIO2_BI2A_CMD_POLL: // log_misc("BIO2_BI2A_CMD_POLL"); - bio2_emu_bi2a_send_state(req); + bio2_emu_bi2a_send_state(&bio2port->acio, req); break; case AC_IO_CMD_GET_VERSION: log_misc("BIO2_CMD_GET_VERSION(%d)", req->addr); - bio2_emu_bi2a_cmd_send_version(req); + bio2_emu_bi2a_cmd_send_version(&bio2port->acio, req); break; case AC_IO_CMD_START_UP: log_misc("BIO2_CMD_START_UP(%d)", req->addr); - bio2_emu_bi2a_send_status(req, 0x00); + bio2_emu_bi2a_send_status(&bio2port->acio, req, 0x00); break; case AC_IO_CMD_KEEPALIVE: log_misc("BIO2_CMD_KEEPALIVE(%d)", req->addr); - bio2_emu_bi2a_send_empty(req); + bio2_emu_bi2a_send_empty(&bio2port->acio, req); break; default: @@ -90,7 +90,7 @@ void bio2_emu_bi2a_dispatch_request(const struct ac_io_message *req) } } -static void bio2_emu_bi2a_cmd_send_version(const struct ac_io_message *req) +static void bio2_emu_bi2a_cmd_send_version(struct ac_io_emu *emu, const struct ac_io_message *req) { struct ac_io_message resp; @@ -108,10 +108,10 @@ static void bio2_emu_bi2a_cmd_send_version(const struct ac_io_message *req) strncpy(resp.cmd.version.date, __DATE__, sizeof(resp.cmd.version.date)); strncpy(resp.cmd.version.time, __TIME__, sizeof(resp.cmd.version.time)); - ac_io_emu_response_push(bi2a_bio2, &resp, 0); + ac_io_emu_response_push(emu, &resp, 0); } -static void bio2_emu_bi2a_send_empty(const struct ac_io_message *req) +static void bio2_emu_bi2a_send_empty(struct ac_io_emu *emu, const struct ac_io_message *req) { struct ac_io_message resp; @@ -120,10 +120,10 @@ static void bio2_emu_bi2a_send_empty(const struct ac_io_message *req) resp.cmd.seq_no = req->cmd.seq_no; resp.cmd.nbytes = 0; - ac_io_emu_response_push(bi2a_bio2, &resp, 0); + ac_io_emu_response_push(emu, &resp, 0); } -static void bio2_emu_bi2a_send_status(const struct ac_io_message *req, uint8_t status) +static void bio2_emu_bi2a_send_status(struct ac_io_emu *emu, const struct ac_io_message *req, uint8_t status) { struct ac_io_message resp; @@ -133,11 +133,11 @@ static void bio2_emu_bi2a_send_status(const struct ac_io_message *req, uint8_t s resp.cmd.nbytes = sizeof(resp.cmd.status); resp.cmd.status = status; - ac_io_emu_response_push(bi2a_bio2, &resp, 0); + ac_io_emu_response_push(emu, &resp, 0); } -static void bio2_emu_bi2a_send_state(const struct ac_io_message *req) +static void bio2_emu_bi2a_send_state(struct ac_io_emu *emu, const struct ac_io_message *req) { struct ac_io_message resp; struct bio2_bi2a_state *body; @@ -190,12 +190,12 @@ static void bio2_emu_bi2a_send_state(const struct ac_io_message *req) if (!iidx_io_ep1_send()) { log_warning("BIO2: iidx_io_ep1_send error"); - return bio2_emu_bi2a_send_status(req, 0); + return bio2_emu_bi2a_send_status(emu, req, 0); } if (!iidx_io_ep3_write_16seg((const char*) req_bi2a->SEG16)) { log_warning("BIO2: iidx_io_ep3_write_16seg error"); - return bio2_emu_bi2a_send_status(req, 0); + return bio2_emu_bi2a_send_status(emu, req, 0); } body = (struct bio2_bi2a_state *)&resp.cmd.raw; @@ -208,7 +208,7 @@ static void bio2_emu_bi2a_send_state(const struct ac_io_message *req) if (!iidx_io_ep2_recv()) { log_warning("BIO2: iidx_io_ep2_recv error"); - return bio2_emu_bi2a_send_status(req, 0); + return bio2_emu_bi2a_send_status(emu, req, 0); } body->TURNTABLE1 = iidx_io_ep2_get_turntable(0); @@ -247,5 +247,5 @@ static void bio2_emu_bi2a_send_state(const struct ac_io_message *req) body->SYSTEM.v_service = (input_sys >> IIDX_IO_SYS_SERVICE) & 1; body->SYSTEM.v_coin = (input_sys >> IIDX_IO_SYS_COIN) & 1; - ac_io_emu_response_push(bi2a_bio2, &resp, 0); + ac_io_emu_response_push(emu, &resp, 0); } diff --git a/src/main/iidxhook8/bi2a.h b/src/main/iidxhook8/bi2a.h index 3654ed3..b34110a 100644 --- a/src/main/iidxhook8/bi2a.h +++ b/src/main/iidxhook8/bi2a.h @@ -107,9 +107,12 @@ struct bio2_bi2a_state_in { uint8_t UNK3[7]; }; _Static_assert(sizeof(struct bio2_bi2a_state_in) == 48, "bio2_bi2a_state_in is the wrong size"); +_Static_assert(sizeof(struct bio2_bi2a_state) == 46, "bio2_bi2a_state_out is the wrong size"); #pragma pack(pop) -void bio2_emu_bi2a_init(struct ac_io_emu *in, bool disable_poll_limiter); -void bio2_emu_bi2a_dispatch_request(const struct ac_io_message *req); +struct bio2emu_port; + +void bio2_emu_bi2a_init(struct bio2emu_port *in, bool disable_poll_limiter); +void bio2_emu_bi2a_dispatch_request(struct bio2emu_port *bio2port, const struct ac_io_message *req); #endif diff --git a/src/main/iidxhook8/bio2.c b/src/main/iidxhook8/bio2.c deleted file mode 100644 index 29a3a10..0000000 --- a/src/main/iidxhook8/bio2.c +++ /dev/null @@ -1,84 +0,0 @@ -#include - -#include -#include -#include - -#include -#include -#include -#include - -#include "acioemu/addr.h" -#include "acioemu/emu.h" - -#include "hook/iohook.h" -#include "hooklib/rs232.h" - -#include "iidxhook8/bi2a.h" - -#include "imports/avs.h" - -#include "util/defs.h" -#include "util/iobuf.h" -#include "util/log.h" -#include "util/str.h" - -static struct ac_io_emu bio2_emu; - -void bio2_port_init(bool disable_poll_limiter) -{ - // yes I'm using acio - // they use the same framing - ac_io_emu_init(&bio2_emu, L"COM4"); - bio2_emu_bi2a_init(&bio2_emu, disable_poll_limiter); - - rs232_hook_add_fd(bio2_emu.fd); -} - -void bio2_port_fini(void) -{ - ac_io_emu_fini(&bio2_emu); -} - -HRESULT bio2_port_dispatch_irp(struct irp *irp) -{ - const struct ac_io_message *msg; - HRESULT hr; - - log_assert(irp != NULL); - - if (!ac_io_emu_match_irp(&bio2_emu, irp)) { - return irp_invoke_next(irp); - } - - for (;;) { - hr = ac_io_emu_dispatch_irp(&bio2_emu, irp); - - if (hr != S_OK) { - return hr; - } - - msg = ac_io_emu_request_peek(&bio2_emu); - - switch (msg->addr) { - case 0: - ac_io_emu_cmd_assign_addrs(&bio2_emu, msg, 1); - break; - - case 1: - bio2_emu_bi2a_dispatch_request(msg); - break; - - case AC_IO_BROADCAST: - log_warning("Broadcast(?) message on IIDX BIO2 bus?"); - break; - - default: - log_warning("BIO2 message on unhandled bus address: %d", msg->addr); - break; - } - - ac_io_emu_request_pop(&bio2_emu); - } -} diff --git a/src/main/iidxhook8/bio2.h b/src/main/iidxhook8/bio2.h deleted file mode 100644 index 1894fac..0000000 --- a/src/main/iidxhook8/bio2.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef IIDXHOOK_BIO2_H -#define IIDXHOOK_BIO2_H - -#include - -#include - -#include "hook/iohook.h" - -void bio2_port_init(bool disable_poll_limiter); -void bio2_port_fini(void); -HRESULT bio2_port_dispatch_irp(struct irp *irp); - -#endif diff --git a/src/main/iidxhook8/dllmain.c b/src/main/iidxhook8/dllmain.c index 7a7511c..900ae19 100644 --- a/src/main/iidxhook8/dllmain.c +++ b/src/main/iidxhook8/dllmain.c @@ -23,11 +23,12 @@ #include "iidxhook-util/d3d9.h" #include "iidxhook-util/log-server.h" -#include "iidxhook8/bio2.h" +#include "bio2emu/emu.h" +#include "iidxhook8/bi2a.h" + #include "iidxhook8/cam.h" #include "iidxhook8/config-cam.h" #include "iidxhook8/config-io.h" -#include "iidxhook8/setupapi.h" #include "iidxhook8/cam.h" #include "imports/avs.h" @@ -44,7 +45,7 @@ static const irp_handler_t iidxhook_handlers[] = { iidxhook_util_acio_dispatch_irp, - bio2_port_dispatch_irp, + bio2emu_port_dispatch_irp, }; static const hook_d3d9_irp_handler_t iidxhook_d3d9_handlers[] = { @@ -75,6 +76,12 @@ static void iidxhook8_setup_d3d9_hooks(const struct iidxhook_config_gfx* config_ struct iidxhook8_config_io iidxhook8_config_io; +static struct bio2emu_port bio2_emu = { + .port = "COM4", + .wport = L"COM4", + .dispatcher = bio2_emu_bi2a_dispatch_request, +}; + static bool my_dll_entry_init(char *sidcode, struct property_node *param) { struct cconfig* config; @@ -82,7 +89,8 @@ static bool my_dll_entry_init(char *sidcode, struct property_node *param) struct iidxhook_config_gfx config_gfx; struct iidxhook8_config_cam config_cam; - // log_server_init is not required anymore + // log_server_init is required due to IO occuring in a non avs_thread + log_server_init(); log_info("-------------------------------------------------------------"); log_info("--------------- Begin iidxhook dll_entry_init ---------------"); @@ -141,8 +149,11 @@ static bool my_dll_entry_init(char *sidcode, struct property_node *param) rs232_hook_limit_hooks(); if (!iidxhook8_config_io.disable_bio2_emu) { - bio2_port_init(iidxhook8_config_io.disable_poll_limiter); - setupapi_hook_init(); + bio2emu_init_start(); + + bio2_emu_bi2a_init(&bio2_emu, iidxhook8_config_io.disable_poll_limiter); + + bio2emu_init_end(); } if (!iidxhook8_config_io.disable_card_reader_emu) { @@ -177,6 +188,8 @@ static bool my_dll_entry_main(void) iidx_io_fini(); } + log_server_fini(); + return result; } diff --git a/src/main/iidxhook8/setupapi.c b/src/main/iidxhook8/setupapi.c deleted file mode 100644 index e790b3e..0000000 --- a/src/main/iidxhook8/setupapi.c +++ /dev/null @@ -1,287 +0,0 @@ -#define LOG_MODULE "setupapi-hook" - -#include -#include -#include - -#include "hook/table.h" - -#include "iidxhook8/setupapi.h" - -#include "util/defs.h" -#include "util/log.h" -#include "util/str.h" -#include "util/time.h" - -static BOOL my_SetupDiDestroyDeviceInfoList( - HDEVINFO DeviceInfoSet -); - -static BOOL (*real_SetupDiDestroyDeviceInfoList)( - HDEVINFO DeviceInfoSet -); - -static BOOL my_SetupDiEnumDeviceInfo( - HDEVINFO DeviceInfoSet, - DWORD MemberIndex, - PSP_DEVINFO_DATA DeviceInfoData -); - -static BOOL (*real_SetupDiEnumDeviceInfo)( - HDEVINFO DeviceInfoSet, - DWORD MemberIndex, - PSP_DEVINFO_DATA DeviceInfoData -); - -static HKEY my_SetupDiOpenDevRegKey( - HDEVINFO DeviceInfoSet, - PSP_DEVINFO_DATA DeviceInfoData, - DWORD Scope, - DWORD HwProfile, - DWORD KeyType, - REGSAM samDesired -); - -static HKEY (*real_SetupDiOpenDevRegKey)( - HDEVINFO DeviceInfoSet, - PSP_DEVINFO_DATA DeviceInfoData, - DWORD Scope, - DWORD HwProfile, - DWORD KeyType, - REGSAM samDesired -); - -static BOOL my_SetupDiGetDeviceRegistryPropertyA( - HDEVINFO DeviceInfoSet, - PSP_DEVINFO_DATA DeviceInfoData, - DWORD Property, - PDWORD PropertyRegDataType, - PBYTE PropertyBuffer, - DWORD PropertyBufferSize, - PDWORD RequiredSize -); - -static BOOL (*real_SetupDiGetDeviceRegistryPropertyA)( - HDEVINFO DeviceInfoSet, - PSP_DEVINFO_DATA DeviceInfoData, - DWORD Property, - PDWORD PropertyRegDataType, - PBYTE PropertyBuffer, - DWORD PropertyBufferSize, - PDWORD RequiredSize -); - -static BOOL my_SetupDiGetDeviceInfoListDetailA( - HDEVINFO DeviceInfoSet, - PSP_DEVINFO_LIST_DETAIL_DATA_A DeviceInfoSetDetailData -); - -static BOOL (*real_SetupDiGetDeviceInfoListDetailA)( - HDEVINFO DeviceInfoSet, - PSP_DEVINFO_LIST_DETAIL_DATA_A DeviceInfoSetDetailData -); - -static HDEVINFO my_SetupDiGetClassDevsA( - CONST GUID *ClassGuid, - PCSTR Enumerator, - HWND hwndParent, - DWORD Flags -); - -static HDEVINFO(*real_SetupDiGetClassDevsA)( - CONST GUID *ClassGuid, - PCSTR Enumerator, - HWND hwndParent, - DWORD Flags -); - -static const struct hook_symbol iidxhook5_setupapi_syms[] = { - { - .name = "SetupDiDestroyDeviceInfoList", - .patch = my_SetupDiDestroyDeviceInfoList, - .link = (void **) &real_SetupDiDestroyDeviceInfoList - }, - { - .name = "SetupDiEnumDeviceInfo", - .patch = my_SetupDiEnumDeviceInfo, - .link = (void **) &real_SetupDiEnumDeviceInfo - }, - { - .name = "SetupDiOpenDevRegKey", - .patch = my_SetupDiOpenDevRegKey, - .link = (void **) &real_SetupDiOpenDevRegKey - }, - { - .name = "SetupDiGetDeviceRegistryPropertyA", - .patch = my_SetupDiGetDeviceRegistryPropertyA, - .link = (void **) &real_SetupDiGetDeviceRegistryPropertyA - }, - { - .name = "SetupDiGetDeviceInfoListDetailA", - .patch = my_SetupDiGetDeviceInfoListDetailA, - .link = (void **) &real_SetupDiGetDeviceInfoListDetailA - }, - { - .name = "SetupDiGetClassDevsA", - .patch = my_SetupDiGetClassDevsA, - .link = (void **) &real_SetupDiGetClassDevsA - }, -}; - -static LSTATUS my_RegQueryValueExA( - HKEY hKey, - LPCSTR lpValueName, - LPDWORD lpReserved, - LPDWORD lpType, - LPBYTE lpData, - LPDWORD lpcbData -); -static LSTATUS (*real_RegQueryValueExA)( - HKEY hKey, - LPCSTR lpValueName, - LPDWORD lpReserved, - LPDWORD lpType, - LPBYTE lpData, - LPDWORD lpcbData -); - -static const struct hook_symbol iidxhook5_Advapi32_syms[] = { - { - .name = "RegQueryValueExA", - .patch = my_RegQueryValueExA, - .link = (void **) &real_RegQueryValueExA - }, -}; - -#define CUSTOM_DEVICE_HANDLE (void*)0x12341230 -#define CUSTOM_REGISTRY_HANDLE (void*)0x4242ccc0 - -static BOOL my_SetupDiDestroyDeviceInfoList( - HDEVINFO DeviceInfoSet -){ - if (DeviceInfoSet == CUSTOM_DEVICE_HANDLE){ - log_info("Inside: %s", __FUNCTION__); - return true; - } - return real_SetupDiDestroyDeviceInfoList(DeviceInfoSet); -} - -static BOOL my_SetupDiEnumDeviceInfo( - HDEVINFO DeviceInfoSet, - DWORD MemberIndex, - PSP_DEVINFO_DATA DeviceInfoData -){ - if (DeviceInfoSet == CUSTOM_DEVICE_HANDLE){ - log_info("Inside: %s", __FUNCTION__); - return true; - } - return real_SetupDiEnumDeviceInfo(DeviceInfoSet, MemberIndex, DeviceInfoData); -} - -static HKEY my_SetupDiOpenDevRegKey( - HDEVINFO DeviceInfoSet, - PSP_DEVINFO_DATA DeviceInfoData, - DWORD Scope, - DWORD HwProfile, - DWORD KeyType, - REGSAM samDesired -){ - if (DeviceInfoSet == CUSTOM_DEVICE_HANDLE){ - log_info("Inside: %s", __FUNCTION__); - return CUSTOM_REGISTRY_HANDLE; - } - return real_SetupDiOpenDevRegKey(DeviceInfoSet, DeviceInfoData, Scope, HwProfile, KeyType, samDesired); -} - -static BOOL my_SetupDiGetDeviceRegistryPropertyA( - HDEVINFO DeviceInfoSet, - PSP_DEVINFO_DATA DeviceInfoData, - DWORD Property, - PDWORD PropertyRegDataType, - PBYTE PropertyBuffer, - DWORD PropertyBufferSize, - PDWORD RequiredSize -){ - if (DeviceInfoSet == CUSTOM_DEVICE_HANDLE){ - log_info("Inside: %s", __FUNCTION__); - log_info("%s: Found CUSTOM HANDLE", __FUNCTION__); - if (PropertyBuffer && (PropertyBufferSize >= 12)){ - log_info("%s: Copying property name (%ld)", __FUNCTION__, PropertyBufferSize); - strncpy((char*)PropertyBuffer, "BIO2(VIDEO)", PropertyBufferSize); - log_info("%s: Done copying property name", __FUNCTION__); - // Sleep(500); - } else { - log_info("%s: Returning size", __FUNCTION__); - *RequiredSize = 12; - } - log_info("%s: STUB RETURN", __FUNCTION__); - return true; - } - return real_SetupDiGetDeviceRegistryPropertyA(DeviceInfoSet, DeviceInfoData, Property, PropertyRegDataType, PropertyBuffer, PropertyBufferSize, RequiredSize); -} - -static BOOL my_SetupDiGetDeviceInfoListDetailA( - HDEVINFO DeviceInfoSet, - PSP_DEVINFO_LIST_DETAIL_DATA_A DeviceInfoSetDetailData -){ - if (DeviceInfoSet == CUSTOM_DEVICE_HANDLE){ - log_info("Inside: %s", __FUNCTION__); - return true; - } - return real_SetupDiGetDeviceInfoListDetailA(DeviceInfoSet, DeviceInfoSetDetailData); -} - -DEFINE_GUID(GUID_COM_BUS_ENUMERATOR, - 0x4D36E978, 0xE325, 0x11CE, 0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18); - -static HDEVINFO my_SetupDiGetClassDevsA( - CONST GUID *ClassGuid, - PCSTR Enumerator, - HWND hwndParent, - DWORD Flags -){ - if (ClassGuid) { - if (IsEqualGUID(ClassGuid, &GUID_COM_BUS_ENUMERATOR)){ - log_info("Inside: %s", __FUNCTION__); - return CUSTOM_DEVICE_HANDLE; - } - } - return real_SetupDiGetClassDevsA(ClassGuid, Enumerator, hwndParent, Flags); -} - -static LSTATUS my_RegQueryValueExA( - HKEY hKey, - LPCSTR lpValueName, - LPDWORD lpReserved, - LPDWORD lpType, - LPBYTE lpData, - LPDWORD lpcbData -){ - if (hKey == CUSTOM_REGISTRY_HANDLE){ - if (strcmp(lpValueName, "PortName") == 0) { - log_info("Inside: %s", __FUNCTION__); - if (lpData){ - strncpy((char*)lpData, "COM4", *lpcbData); - return ERROR_SUCCESS; - } - return ERROR_MORE_DATA; - } - } - return real_RegQueryValueExA(hKey, lpValueName, lpReserved, lpType, lpData, lpcbData); -} - -void setupapi_hook_init(void) -{ - hook_table_apply( - NULL, - "setupapi.dll", - iidxhook5_setupapi_syms, - lengthof(iidxhook5_setupapi_syms)); - hook_table_apply( - NULL, - "Advapi32.dll", - iidxhook5_Advapi32_syms, - lengthof(iidxhook5_Advapi32_syms)); - - log_info("Inserted setupapi hooks"); -} diff --git a/src/main/iidxhook8/setupapi.h b/src/main/iidxhook8/setupapi.h deleted file mode 100644 index 97a6381..0000000 --- a/src/main/iidxhook8/setupapi.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef IIDXHOOK_SETUPAPI_H -#define IIDXHOOK_SETUPAPI_H - -void setupapi_hook_init(void); - -#endif