fgo: working FTDI hook by @OLEG

from: 88a0026f0b
This commit is contained in:
2023-11-22 21:40:10 +01:00
parent b9fd59fd70
commit d86baab852
9 changed files with 341 additions and 20 deletions

View File

@ -32,6 +32,7 @@ void ftdi_config_load(struct ftdi_config *cfg, const wchar_t *filename)
assert(filename != NULL);
cfg->enable = GetPrivateProfileIntW(L"ftdi", L"enable", 1, filename);
cfg->port_no = GetPrivateProfileIntW(L"ftdi", L"port", 17, filename);
}
void led1509306_config_load(struct led1509306_config *cfg, const wchar_t *filename)
@ -45,7 +46,7 @@ void led1509306_config_load(struct led1509306_config *cfg, const wchar_t *filena
memset(cfg->chip_number, ' ', sizeof(cfg->chip_number));
cfg->enable = GetPrivateProfileIntW(L"ledstrip", L"enable", 1, filename);
cfg->port_no = GetPrivateProfileIntW(L"ledstrip", L"port", 21, filename);
cfg->port_no = GetPrivateProfileIntW(L"ledstrip", L"port", 17, filename);
cfg->fw_ver = GetPrivateProfileIntW(L"ledstrip", L"fw_ver", 0xA0, filename);
cfg->fw_sum = GetPrivateProfileIntW(L"ledstrip", L"fw_sum", 0xaa53, filename);

View File

@ -129,7 +129,7 @@ static struct card_collection* cards_ptr;
static uint8_t current_card_idx = 0;
static bool read_pending = false;
HRESULT deck_hook_init(const struct deck_config *cfg, int port)
HRESULT deck_hook_init(const struct deck_config *cfg, unsigned int port_no)
{
assert(cfg != NULL);
@ -139,7 +139,7 @@ HRESULT deck_hook_init(const struct deck_config *cfg, int port)
InitializeCriticalSection(&deck_lock);
uart_init(&deck_uart, port);
uart_init(&deck_uart, port_no);
deck_uart.written.bytes = deck_written_bytes;
deck_uart.written.nbytes = sizeof(deck_written_bytes);
deck_uart.readable.bytes = deck_readable_bytes;
@ -398,6 +398,8 @@ static HRESULT deck_frame_decode(struct iobuf *dest, struct iobuf *src) {
assert(src->bytes != NULL || src->nbytes == 0);
assert(src->pos <= src->nbytes);
deck_frame_sync(src);
dest->pos = 0;
escape = false;

View File

@ -8,4 +8,4 @@ struct deck_config {
bool enable;
};
HRESULT deck_hook_init(const struct deck_config *cfg, int port);
HRESULT deck_hook_init(const struct deck_config *cfg, unsigned int port_no);

View File

@ -90,13 +90,11 @@ static DWORD CALLBACK fgo_pre_startup(void)
goto fail;
}
/*
hr = ftdi_hook_init(&fgo_hook_cfg.ftdi);
if (FAILED(hr)) {
goto fail;
}
*/
hr = led1509306_hook_init(&fgo_hook_cfg.led1509306);

View File

@ -8,15 +8,22 @@
The game queries the presence of the FTDI board itself, followed by a
registry check to see which port number is assigned to the FTDI board.
If these fail, the "CABINET LED" check on startup will always return "NG".
Credits:
OLEG
*/
#include <windows.h>
#include <setupapi.h>
#include <stdint.h>
#include <assert.h>
#include <stdio.h>
#include "fgohook/ftdi.h"
#include "hook/iohook.h"
#include "hook/table.h"
#include "hooklib/setupapi.h"
@ -24,10 +31,97 @@
static struct ftdi_config ftdi_cfg;
static HANDLE ftdi_fd;
HRESULT ftdi_hook_init(const struct ftdi_config *cfg)
{
static BOOL WINAPI hook_SetupDiGetDeviceRegistryPropertyA(
HDEVINFO DeviceInfoSet,
PSP_DEVINFO_DATA DeviceInfoData,
uint32_t Property,
uint32_t *PropertyRegDataType,
void *PropertyBuffer,
uint32_t PropertyBufferSize,
uint32_t *RequiredSize
);
static HKEY WINAPI hook_SetupDiOpenDevRegKey(
HDEVINFO DeviceInfoSet,
PSP_DEVINFO_DATA DeviceInfoData,
uint32_t Scope,
uint32_t HwProfile,
uint32_t KeyType,
REGSAM samDesired
);
static LSTATUS WINAPI hook_RegQueryValueExA(
HKEY handle,
const char *name,
void *reserved,
uint32_t *type,
void *bytes,
uint32_t *nbytes);
static LSTATUS WINAPI hook_RegCloseKey(HKEY handle);
static BOOL (WINAPI *next_SetupDiGetDeviceRegistryPropertyA)(
HDEVINFO DeviceInfoSet,
PSP_DEVINFO_DATA DeviceInfoData,
uint32_t Property,
uint32_t *PropertyRegDataType,
void *PropertyBuffer,
uint32_t PropertyBufferSize,
uint32_t *RequiredSize
);
static HKEY (WINAPI *next_SetupDiOpenDevRegKey)(
HDEVINFO DeviceInfoSet,
PSP_DEVINFO_DATA DeviceInfoData,
uint32_t Scope,
uint32_t HwProfile,
uint32_t KeyType,
REGSAM samDesired
);
static LSTATUS (WINAPI *next_RegQueryValueExA)(
HKEY handle,
const char *name,
void *reserved,
uint32_t *type,
void *bytes,
uint32_t *nbytes);
static LSTATUS (WINAPI *next_RegCloseKey)(HKEY handle);
static const struct hook_symbol setupapi_syms[] = {
{
.name = "SetupDiGetDeviceRegistryPropertyA",
.patch = hook_SetupDiGetDeviceRegistryPropertyA,
.link = (void *) &next_SetupDiGetDeviceRegistryPropertyA,
}, {
.name = "SetupDiOpenDevRegKey",
.patch = hook_SetupDiOpenDevRegKey,
.link = (void *) &next_SetupDiOpenDevRegKey,
}
};
static const struct hook_symbol reg_syms[] = {
{
.name = "RegQueryValueExA",
.patch = hook_RegQueryValueExA,
.link = (void *) &next_RegQueryValueExA,
}, {
.name = "RegCloseKey",
.patch = hook_RegCloseKey,
.link = (void *) &next_RegCloseKey,
}
};
#define device_fake_key 0xDEADBEEF
static HANDLE ftdi_fd;
static char port_name[8];
HRESULT ftdi_hook_init(const struct ftdi_config *cfg) {
HRESULT hr;
assert(cfg != NULL);
@ -36,6 +130,18 @@ HRESULT ftdi_hook_init(const struct ftdi_config *cfg)
return S_FALSE;
}
hook_table_apply(
NULL,
"setupapi.dll",
setupapi_syms,
_countof(setupapi_syms));
hook_table_apply(
NULL,
"advapi32.dll",
reg_syms,
_countof(reg_syms));
memcpy(&ftdi_cfg, cfg, sizeof(*cfg));
hr = iohook_open_nul_fd(&ftdi_fd);
@ -50,6 +156,68 @@ HRESULT ftdi_hook_init(const struct ftdi_config *cfg)
return hr;
}
sprintf(port_name, "COM%d", cfg->port_no);
dprintf("FTDI: Hook enabled.\n");
return S_OK;
}
static BOOL WINAPI hook_SetupDiGetDeviceRegistryPropertyA(
HDEVINFO DeviceInfoSet,
PSP_DEVINFO_DATA DeviceInfoData,
uint32_t Property,
uint32_t *PropertyRegDataType,
void *PropertyBuffer,
uint32_t PropertyBufferSize,
uint32_t *RequiredSize
) {
if (!PropertyBuffer || PropertyBufferSize == 0) {
*RequiredSize = 16;
SetLastError(ERROR_INSUFFICIENT_BUFFER);
return FALSE;
}
*PropertyRegDataType = 1;
return TRUE;
}
static HKEY WINAPI hook_SetupDiOpenDevRegKey(
HDEVINFO DeviceInfoSet,
PSP_DEVINFO_DATA DeviceInfoData,
uint32_t Scope,
uint32_t HwProfile,
uint32_t KeyType,
REGSAM samDesired
) {
return (HKEY) device_fake_key;
}
static LSTATUS WINAPI hook_RegCloseKey(HKEY handle) {
if (handle == (HKEY) device_fake_key)
return ERROR_SUCCESS;
return next_RegCloseKey(handle);
}
static LSTATUS WINAPI hook_RegQueryValueExA(
HKEY handle,
const char *name,
void *reserved,
uint32_t *type,
void *bytes,
uint32_t *nbytes) {
if (handle == (HKEY) device_fake_key && !strcmp(name, "PortName")) {
strcpy(bytes, port_name);
*nbytes = 5;
*type = 1;
return ERROR_SUCCESS;
}
return next_RegQueryValueExA(
handle,
name,
reserved,
type,
bytes,
nbytes);
}

View File

@ -8,6 +8,7 @@
struct ftdi_config {
bool enable;
uint32_t port_no;
};
DEFINE_GUID(