mirror of
https://github.com/djhackersdev/bemanitools.git
synced 2024-11-28 00:10:51 +01:00
bio2emu: Refactor out the BIO2 emulation code so that it can be reused
Also make it support multiple BIO2 devices if needed (DRS)
This commit is contained in:
parent
073392407a
commit
e495bfb8f1
@ -74,6 +74,7 @@ imps += avs avs-ea3
|
|||||||
include src/main/aciodrv/Module.mk
|
include src/main/aciodrv/Module.mk
|
||||||
include src/main/acioemu/Module.mk
|
include src/main/acioemu/Module.mk
|
||||||
include src/main/aciotest/Module.mk
|
include src/main/aciotest/Module.mk
|
||||||
|
include src/main/bio2emu/Module.mk
|
||||||
include src/main/bsthook/Module.mk
|
include src/main/bsthook/Module.mk
|
||||||
include src/main/bstio/Module.mk
|
include src/main/bstio/Module.mk
|
||||||
include src/main/cconfig/Module.mk
|
include src/main/cconfig/Module.mk
|
||||||
|
8
src/main/bio2emu/Module.mk
Normal file
8
src/main/bio2emu/Module.mk
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
libs += bio2emu
|
||||||
|
|
||||||
|
libs_bio2emu := \
|
||||||
|
acioemu \
|
||||||
|
|
||||||
|
src_bio2emu := \
|
||||||
|
emu.c \
|
||||||
|
setupapi.c \
|
107
src/main/bio2emu/emu.c
Normal file
107
src/main/bio2emu/emu.c
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#include <ntdef.h>
|
||||||
|
#include <devioctl.h>
|
||||||
|
#include <ntddser.h>
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <wchar.h>
|
||||||
|
|
||||||
|
#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);
|
||||||
|
}
|
||||||
|
}
|
28
src/main/bio2emu/emu.h
Normal file
28
src/main/bio2emu/emu.h
Normal file
@ -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
|
327
src/main/bio2emu/setupapi.c
Normal file
327
src/main/bio2emu/setupapi.c
Normal file
@ -0,0 +1,327 @@
|
|||||||
|
#define LOG_MODULE "setupapi-hook"
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <setupapi.h>
|
||||||
|
#include <initguid.h>
|
||||||
|
|
||||||
|
#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");
|
||||||
|
}
|
8
src/main/bio2emu/setupapi.h
Normal file
8
src/main/bio2emu/setupapi.h
Normal file
@ -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
|
@ -14,6 +14,7 @@ deplibs_iidxhook8 := \
|
|||||||
libs_iidxhook8 := \
|
libs_iidxhook8 := \
|
||||||
iidxhook-util \
|
iidxhook-util \
|
||||||
acioemu \
|
acioemu \
|
||||||
|
bio2emu \
|
||||||
iidxio \
|
iidxio \
|
||||||
hook \
|
hook \
|
||||||
hooklib \
|
hooklib \
|
||||||
@ -23,9 +24,7 @@ libs_iidxhook8 := \
|
|||||||
|
|
||||||
src_iidxhook8 := \
|
src_iidxhook8 := \
|
||||||
bi2a.c \
|
bi2a.c \
|
||||||
bio2.c \
|
|
||||||
cam.c \
|
cam.c \
|
||||||
config-cam.c \
|
config-cam.c \
|
||||||
config-io.c \
|
config-io.c \
|
||||||
dllmain.c \
|
dllmain.c \
|
||||||
setupapi.c \
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#define LOG_MODULE "bio2emu-bi2a"
|
#define LOG_MODULE "bio2emu-bi2a"
|
||||||
|
|
||||||
#include "iidxhook8/bi2a.h"
|
#include "iidxhook8/bi2a.h"
|
||||||
|
#include "bio2emu/emu.h"
|
||||||
|
|
||||||
#include <windows.h> /* for _BitScanForward */
|
#include <windows.h> /* for _BitScanForward */
|
||||||
|
|
||||||
@ -13,12 +14,11 @@
|
|||||||
#include "bemanitools/iidxio.h"
|
#include "bemanitools/iidxio.h"
|
||||||
|
|
||||||
static int get_default_slider_valid(size_t idx);
|
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_cmd_send_version(struct ac_io_emu *emu, 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_state(struct ac_io_emu *emu, 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_empty(struct ac_io_emu *emu, 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_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 int default_sliders[5];
|
||||||
static bool poll_delay;
|
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;
|
bio2emu_port_init(bio2_emu);
|
||||||
bi2a_bio2 = bio2_emu;
|
|
||||||
poll_delay = !disable_poll_limiter;
|
poll_delay = !disable_poll_limiter;
|
||||||
if (!poll_delay) {
|
if (!poll_delay) {
|
||||||
log_warning("bio2_emu_bi2a_init: poll_delay has been disabled");
|
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;
|
default_sliders[i] = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
f = fopen("vefx.txt", "r");
|
FILE* f = fopen("vefx.txt", "r");
|
||||||
if (f) {
|
if (f) {
|
||||||
fscanf(f, "%d %d %d %d %d", &default_sliders[0], &default_sliders[1], &default_sliders[2], &default_sliders[3], &default_sliders[4]);
|
fscanf(f, "%d %d %d %d %d", &default_sliders[0], &default_sliders[1], &default_sliders[2], &default_sliders[3], &default_sliders[4]);
|
||||||
fclose(f);
|
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;
|
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_0100:
|
||||||
case BIO2_BI2A_CMD_UNK_0120:
|
case BIO2_BI2A_CMD_UNK_0120:
|
||||||
log_misc("BIO2_BI2A_CMD_UNK_%04X(%d)", cmd_code, req->addr);
|
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;
|
break;
|
||||||
|
|
||||||
case BIO2_BI2A_CMD_POLL:
|
case BIO2_BI2A_CMD_POLL:
|
||||||
// log_misc("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;
|
break;
|
||||||
|
|
||||||
case AC_IO_CMD_GET_VERSION:
|
case AC_IO_CMD_GET_VERSION:
|
||||||
log_misc("BIO2_CMD_GET_VERSION(%d)", req->addr);
|
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;
|
break;
|
||||||
|
|
||||||
case AC_IO_CMD_START_UP:
|
case AC_IO_CMD_START_UP:
|
||||||
log_misc("BIO2_CMD_START_UP(%d)", req->addr);
|
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;
|
break;
|
||||||
|
|
||||||
case AC_IO_CMD_KEEPALIVE:
|
case AC_IO_CMD_KEEPALIVE:
|
||||||
log_misc("BIO2_CMD_KEEPALIVE(%d)", req->addr);
|
log_misc("BIO2_CMD_KEEPALIVE(%d)", req->addr);
|
||||||
bio2_emu_bi2a_send_empty(req);
|
bio2_emu_bi2a_send_empty(&bio2port->acio, req);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
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;
|
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.date, __DATE__, sizeof(resp.cmd.version.date));
|
||||||
strncpy(resp.cmd.version.time, __TIME__, sizeof(resp.cmd.version.time));
|
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;
|
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.seq_no = req->cmd.seq_no;
|
||||||
resp.cmd.nbytes = 0;
|
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;
|
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.nbytes = sizeof(resp.cmd.status);
|
||||||
resp.cmd.status = 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 ac_io_message resp;
|
||||||
struct bio2_bi2a_state *body;
|
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()) {
|
if (!iidx_io_ep1_send()) {
|
||||||
log_warning("BIO2: iidx_io_ep1_send error");
|
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)) {
|
if (!iidx_io_ep3_write_16seg((const char*) req_bi2a->SEG16)) {
|
||||||
log_warning("BIO2: iidx_io_ep3_write_16seg error");
|
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;
|
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()) {
|
if (!iidx_io_ep2_recv()) {
|
||||||
log_warning("BIO2: iidx_io_ep2_recv error");
|
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);
|
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_service = (input_sys >> IIDX_IO_SYS_SERVICE) & 1;
|
||||||
body->SYSTEM.v_coin = (input_sys >> IIDX_IO_SYS_COIN) & 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);
|
||||||
}
|
}
|
||||||
|
@ -107,9 +107,12 @@ struct bio2_bi2a_state_in {
|
|||||||
uint8_t UNK3[7];
|
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_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)
|
#pragma pack(pop)
|
||||||
|
|
||||||
void bio2_emu_bi2a_init(struct ac_io_emu *in, bool disable_poll_limiter);
|
struct bio2emu_port;
|
||||||
void bio2_emu_bi2a_dispatch_request(const struct ac_io_message *req);
|
|
||||||
|
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
|
#endif
|
||||||
|
@ -1,84 +0,0 @@
|
|||||||
#include <windows.h>
|
|
||||||
|
|
||||||
#include <ntdef.h>
|
|
||||||
#include <devioctl.h>
|
|
||||||
#include <ntddser.h>
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <wchar.h>
|
|
||||||
|
|
||||||
#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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,14 +0,0 @@
|
|||||||
#ifndef IIDXHOOK_BIO2_H
|
|
||||||
#define IIDXHOOK_BIO2_H
|
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
#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
|
|
@ -23,11 +23,12 @@
|
|||||||
#include "iidxhook-util/d3d9.h"
|
#include "iidxhook-util/d3d9.h"
|
||||||
#include "iidxhook-util/log-server.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/cam.h"
|
||||||
#include "iidxhook8/config-cam.h"
|
#include "iidxhook8/config-cam.h"
|
||||||
#include "iidxhook8/config-io.h"
|
#include "iidxhook8/config-io.h"
|
||||||
#include "iidxhook8/setupapi.h"
|
|
||||||
#include "iidxhook8/cam.h"
|
#include "iidxhook8/cam.h"
|
||||||
|
|
||||||
#include "imports/avs.h"
|
#include "imports/avs.h"
|
||||||
@ -44,7 +45,7 @@
|
|||||||
|
|
||||||
static const irp_handler_t iidxhook_handlers[] = {
|
static const irp_handler_t iidxhook_handlers[] = {
|
||||||
iidxhook_util_acio_dispatch_irp,
|
iidxhook_util_acio_dispatch_irp,
|
||||||
bio2_port_dispatch_irp,
|
bio2emu_port_dispatch_irp,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const hook_d3d9_irp_handler_t iidxhook_d3d9_handlers[] = {
|
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;
|
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)
|
static bool my_dll_entry_init(char *sidcode, struct property_node *param)
|
||||||
{
|
{
|
||||||
struct cconfig* config;
|
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 iidxhook_config_gfx config_gfx;
|
||||||
struct iidxhook8_config_cam config_cam;
|
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("-------------------------------------------------------------");
|
||||||
log_info("--------------- Begin iidxhook dll_entry_init ---------------");
|
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();
|
rs232_hook_limit_hooks();
|
||||||
|
|
||||||
if (!iidxhook8_config_io.disable_bio2_emu) {
|
if (!iidxhook8_config_io.disable_bio2_emu) {
|
||||||
bio2_port_init(iidxhook8_config_io.disable_poll_limiter);
|
bio2emu_init_start();
|
||||||
setupapi_hook_init();
|
|
||||||
|
bio2_emu_bi2a_init(&bio2_emu, iidxhook8_config_io.disable_poll_limiter);
|
||||||
|
|
||||||
|
bio2emu_init_end();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!iidxhook8_config_io.disable_card_reader_emu) {
|
if (!iidxhook8_config_io.disable_card_reader_emu) {
|
||||||
@ -177,6 +188,8 @@ static bool my_dll_entry_main(void)
|
|||||||
iidx_io_fini();
|
iidx_io_fini();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log_server_fini();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,287 +0,0 @@
|
|||||||
#define LOG_MODULE "setupapi-hook"
|
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
#include <setupapi.h>
|
|
||||||
#include <initguid.h>
|
|
||||||
|
|
||||||
#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");
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
#ifndef IIDXHOOK_SETUPAPI_H
|
|
||||||
#define IIDXHOOK_SETUPAPI_H
|
|
||||||
|
|
||||||
void setupapi_hook_init(void);
|
|
||||||
|
|
||||||
#endif
|
|
Loading…
Reference in New Issue
Block a user