forked from Dniel97/segatools
parent
b9fd59fd70
commit
d86baab852
17
README.md
17
README.md
@ -1,6 +1,6 @@
|
|||||||
# Segatools
|
# Segatools
|
||||||
|
|
||||||
Version: `2023-07-14`
|
Version: `2023-11-22`
|
||||||
|
|
||||||
Loaders and hardware emulators for SEGA games that run on the Nu and ALLS platforms.
|
Loaders and hardware emulators for SEGA games that run on the Nu and ALLS platforms.
|
||||||
|
|
||||||
@ -12,19 +12,22 @@ Loaders and hardware emulators for SEGA games that run on the Nu and ALLS platfo
|
|||||||
* [Chunithm Star (Plus)](doc/chunihook.md)
|
* [Chunithm Star (Plus)](doc/chunihook.md)
|
||||||
* [Chunithm Amazon (Plus)](doc/chunihook.md)
|
* [Chunithm Amazon (Plus)](doc/chunihook.md)
|
||||||
* [Chunithm Crystal (Plus)](doc/chunihook.md)
|
* [Chunithm Crystal (Plus)](doc/chunihook.md)
|
||||||
|
* Chunithm SUN
|
||||||
* Initial D
|
* Initial D
|
||||||
* [Initial D Arcade Stage Zero](doc/idzhook.md)
|
* [Initial D Arcade Stage Zero](doc/idzhook.md)
|
||||||
* Initial D The Arcade
|
* Initial D THE ARCADE
|
||||||
* SEGA World Drivers Championship
|
* SEGA World Drivers Championship
|
||||||
* SEGA World Drivers Championship 2019
|
* up to SEGA World Drivers Championship 2019
|
||||||
|
* Fate/Grand Order
|
||||||
|
* Fate/Grand Order Arcade
|
||||||
* ONGEKI
|
* ONGEKI
|
||||||
* bright MEMORY
|
* up to bright MEMORY
|
||||||
* maimai DX
|
* maimai DX
|
||||||
* maimai DX FESTiVAL
|
* up to maimai DX FESTiVAL PLUS
|
||||||
* Card Maker
|
* Card Maker
|
||||||
* Card Maker 1.35
|
* up to Card Maker 1.35
|
||||||
* Wacca
|
* Wacca
|
||||||
* Wacca Lilly R (WIP)
|
* up to WACCA Reverse
|
||||||
|
|
||||||
## End-users
|
## End-users
|
||||||
|
|
||||||
|
7
dist/fgo/segatools.ini
vendored
7
dist/fgo/segatools.ini
vendored
@ -55,12 +55,13 @@ rotate180=1
|
|||||||
; 837-15345 RFID deck reader emulation setting.
|
; 837-15345 RFID deck reader emulation setting.
|
||||||
enable=1
|
enable=1
|
||||||
|
|
||||||
|
[ftdi]
|
||||||
|
; FTDI serial to usb adapter emulation for CABINET LED.
|
||||||
|
enable=1
|
||||||
|
|
||||||
[ledstrip]
|
[ledstrip]
|
||||||
; 837-15093-06 LED strip emulation setting.
|
; 837-15093-06 LED strip emulation setting.
|
||||||
enable=1
|
enable=1
|
||||||
; FTDI board currently not working properly. Use com0com (Create a virtual pair
|
|
||||||
; for 21 and 51) or use any USB to Serial Adapter.
|
|
||||||
port=21
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
; -----------------------------------------------------------------------------
|
||||||
; Input settings
|
; Input settings
|
||||||
|
@ -32,6 +32,7 @@ void ftdi_config_load(struct ftdi_config *cfg, const wchar_t *filename)
|
|||||||
assert(filename != NULL);
|
assert(filename != NULL);
|
||||||
|
|
||||||
cfg->enable = GetPrivateProfileIntW(L"ftdi", L"enable", 1, filename);
|
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)
|
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));
|
memset(cfg->chip_number, ' ', sizeof(cfg->chip_number));
|
||||||
|
|
||||||
cfg->enable = GetPrivateProfileIntW(L"ledstrip", L"enable", 1, filename);
|
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_ver = GetPrivateProfileIntW(L"ledstrip", L"fw_ver", 0xA0, filename);
|
||||||
cfg->fw_sum = GetPrivateProfileIntW(L"ledstrip", L"fw_sum", 0xaa53, filename);
|
cfg->fw_sum = GetPrivateProfileIntW(L"ledstrip", L"fw_sum", 0xaa53, filename);
|
||||||
|
|
||||||
|
@ -129,7 +129,7 @@ static struct card_collection* cards_ptr;
|
|||||||
static uint8_t current_card_idx = 0;
|
static uint8_t current_card_idx = 0;
|
||||||
static bool read_pending = false;
|
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);
|
assert(cfg != NULL);
|
||||||
|
|
||||||
@ -139,7 +139,7 @@ HRESULT deck_hook_init(const struct deck_config *cfg, int port)
|
|||||||
|
|
||||||
InitializeCriticalSection(&deck_lock);
|
InitializeCriticalSection(&deck_lock);
|
||||||
|
|
||||||
uart_init(&deck_uart, port);
|
uart_init(&deck_uart, port_no);
|
||||||
deck_uart.written.bytes = deck_written_bytes;
|
deck_uart.written.bytes = deck_written_bytes;
|
||||||
deck_uart.written.nbytes = sizeof(deck_written_bytes);
|
deck_uart.written.nbytes = sizeof(deck_written_bytes);
|
||||||
deck_uart.readable.bytes = deck_readable_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->bytes != NULL || src->nbytes == 0);
|
||||||
assert(src->pos <= src->nbytes);
|
assert(src->pos <= src->nbytes);
|
||||||
|
|
||||||
|
deck_frame_sync(src);
|
||||||
|
|
||||||
dest->pos = 0;
|
dest->pos = 0;
|
||||||
escape = false;
|
escape = false;
|
||||||
|
|
||||||
|
@ -8,4 +8,4 @@ struct deck_config {
|
|||||||
bool enable;
|
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);
|
||||||
|
@ -90,13 +90,11 @@ static DWORD CALLBACK fgo_pre_startup(void)
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
hr = ftdi_hook_init(&fgo_hook_cfg.ftdi);
|
hr = ftdi_hook_init(&fgo_hook_cfg.ftdi);
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
hr = led1509306_hook_init(&fgo_hook_cfg.led1509306);
|
hr = led1509306_hook_init(&fgo_hook_cfg.led1509306);
|
||||||
|
|
||||||
|
174
fgohook/ftdi.c
174
fgohook/ftdi.c
@ -8,15 +8,22 @@
|
|||||||
The game queries the presence of the FTDI board itself, followed by a
|
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.
|
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".
|
If these fail, the "CABINET LED" check on startup will always return "NG".
|
||||||
|
|
||||||
|
Credits:
|
||||||
|
|
||||||
|
OLEG
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
#include <setupapi.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "fgohook/ftdi.h"
|
#include "fgohook/ftdi.h"
|
||||||
|
|
||||||
#include "hook/iohook.h"
|
#include "hook/iohook.h"
|
||||||
|
#include "hook/table.h"
|
||||||
|
|
||||||
#include "hooklib/setupapi.h"
|
#include "hooklib/setupapi.h"
|
||||||
|
|
||||||
@ -24,10 +31,97 @@
|
|||||||
|
|
||||||
static struct ftdi_config ftdi_cfg;
|
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;
|
HRESULT hr;
|
||||||
|
|
||||||
assert(cfg != NULL);
|
assert(cfg != NULL);
|
||||||
@ -36,6 +130,18 @@ HRESULT ftdi_hook_init(const struct ftdi_config *cfg)
|
|||||||
return S_FALSE;
|
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));
|
memcpy(&ftdi_cfg, cfg, sizeof(*cfg));
|
||||||
|
|
||||||
hr = iohook_open_nul_fd(&ftdi_fd);
|
hr = iohook_open_nul_fd(&ftdi_fd);
|
||||||
@ -50,6 +156,68 @@ HRESULT ftdi_hook_init(const struct ftdi_config *cfg)
|
|||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sprintf(port_name, "COM%d", cfg->port_no);
|
||||||
|
|
||||||
dprintf("FTDI: Hook enabled.\n");
|
dprintf("FTDI: Hook enabled.\n");
|
||||||
return S_OK;
|
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);
|
||||||
|
}
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
struct ftdi_config {
|
struct ftdi_config {
|
||||||
bool enable;
|
bool enable;
|
||||||
|
uint32_t port_no;
|
||||||
};
|
};
|
||||||
|
|
||||||
DEFINE_GUID(
|
DEFINE_GUID(
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
struct setupapi_class {
|
struct setupapi_class {
|
||||||
const GUID *guid;
|
const GUID *guid;
|
||||||
const wchar_t *path;
|
const wchar_t *path;
|
||||||
|
char *a_path;
|
||||||
HDEVINFO cur_handle;
|
HDEVINFO cur_handle;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -29,6 +30,12 @@ static HDEVINFO WINAPI my_SetupDiGetClassDevsW(
|
|||||||
HWND hwndParent,
|
HWND hwndParent,
|
||||||
DWORD Flags);
|
DWORD Flags);
|
||||||
|
|
||||||
|
static HDEVINFO WINAPI my_SetupDiGetClassDevsA(
|
||||||
|
const GUID *ClassGuid,
|
||||||
|
char *Enumerator,
|
||||||
|
HWND hwndParent,
|
||||||
|
DWORD Flags);
|
||||||
|
|
||||||
static BOOL WINAPI my_SetupDiEnumDeviceInterfaces(
|
static BOOL WINAPI my_SetupDiEnumDeviceInterfaces(
|
||||||
HDEVINFO DeviceInfoSet,
|
HDEVINFO DeviceInfoSet,
|
||||||
SP_DEVINFO_DATA *DeviceInfoData,
|
SP_DEVINFO_DATA *DeviceInfoData,
|
||||||
@ -44,6 +51,14 @@ static BOOL WINAPI my_SetupDiGetDeviceInterfaceDetailW(
|
|||||||
DWORD *RequiredSize,
|
DWORD *RequiredSize,
|
||||||
SP_DEVINFO_DATA *DeviceInfoData);
|
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);
|
static BOOL WINAPI my_SetupDiDestroyDeviceInfoList(HDEVINFO DeviceInfoSet);
|
||||||
|
|
||||||
/* Links */
|
/* Links */
|
||||||
@ -54,6 +69,12 @@ static HDEVINFO (WINAPI *next_SetupDiGetClassDevsW)(
|
|||||||
HWND hwndParent,
|
HWND hwndParent,
|
||||||
DWORD Flags);
|
DWORD Flags);
|
||||||
|
|
||||||
|
static HDEVINFO (WINAPI *next_SetupDiGetClassDevsA)(
|
||||||
|
const GUID *ClassGuid,
|
||||||
|
char *Enumerator,
|
||||||
|
HWND hwndParent,
|
||||||
|
DWORD Flags);
|
||||||
|
|
||||||
static BOOL (WINAPI *next_SetupDiEnumDeviceInterfaces)(
|
static BOOL (WINAPI *next_SetupDiEnumDeviceInterfaces)(
|
||||||
HDEVINFO DeviceInfoSet,
|
HDEVINFO DeviceInfoSet,
|
||||||
SP_DEVINFO_DATA *DeviceInfoData,
|
SP_DEVINFO_DATA *DeviceInfoData,
|
||||||
@ -69,6 +90,14 @@ static BOOL (WINAPI *next_SetupDiGetDeviceInterfaceDetailW)(
|
|||||||
DWORD *RequiredSize,
|
DWORD *RequiredSize,
|
||||||
SP_DEVINFO_DATA *DeviceInfoData);
|
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);
|
static BOOL (WINAPI *next_SetupDiDestroyDeviceInfoList)(HDEVINFO DeviceInfoSet);
|
||||||
|
|
||||||
/* Hook tbl */
|
/* Hook tbl */
|
||||||
@ -78,6 +107,10 @@ static const struct hook_symbol setupapi_syms[] = {
|
|||||||
.name = "SetupDiGetClassDevsW",
|
.name = "SetupDiGetClassDevsW",
|
||||||
.patch = my_SetupDiGetClassDevsW,
|
.patch = my_SetupDiGetClassDevsW,
|
||||||
.link = (void *) &next_SetupDiGetClassDevsW,
|
.link = (void *) &next_SetupDiGetClassDevsW,
|
||||||
|
}, {
|
||||||
|
.name = "SetupDiGetClassDevsA",
|
||||||
|
.patch = my_SetupDiGetClassDevsA,
|
||||||
|
.link = (void *) &next_SetupDiGetClassDevsA,
|
||||||
}, {
|
}, {
|
||||||
.name = "SetupDiEnumDeviceInterfaces",
|
.name = "SetupDiEnumDeviceInterfaces",
|
||||||
.patch = my_SetupDiEnumDeviceInterfaces,
|
.patch = my_SetupDiEnumDeviceInterfaces,
|
||||||
@ -86,6 +119,10 @@ static const struct hook_symbol setupapi_syms[] = {
|
|||||||
.name = "SetupDiGetDeviceInterfaceDetailW",
|
.name = "SetupDiGetDeviceInterfaceDetailW",
|
||||||
.patch = my_SetupDiGetDeviceInterfaceDetailW,
|
.patch = my_SetupDiGetDeviceInterfaceDetailW,
|
||||||
.link = (void *) &next_SetupDiGetDeviceInterfaceDetailW,
|
.link = (void *) &next_SetupDiGetDeviceInterfaceDetailW,
|
||||||
|
}, {
|
||||||
|
.name = "SetupDiGetDeviceInterfaceDetailA",
|
||||||
|
.patch = my_SetupDiGetDeviceInterfaceDetailA,
|
||||||
|
.link = (void *) &next_SetupDiGetDeviceInterfaceDetailA,
|
||||||
}, {
|
}, {
|
||||||
.name = "SetupDiDestroyDeviceInfoList",
|
.name = "SetupDiDestroyDeviceInfoList",
|
||||||
.patch = my_SetupDiDestroyDeviceInfoList,
|
.patch = my_SetupDiDestroyDeviceInfoList,
|
||||||
@ -102,6 +139,7 @@ HRESULT setupapi_add_phantom_dev(const GUID *iface_class, const wchar_t *path)
|
|||||||
{
|
{
|
||||||
struct setupapi_class *class_;
|
struct setupapi_class *class_;
|
||||||
struct setupapi_class *new_array;
|
struct setupapi_class *new_array;
|
||||||
|
size_t a_path_len;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
assert(iface_class != NULL);
|
assert(iface_class != NULL);
|
||||||
@ -126,6 +164,11 @@ HRESULT setupapi_add_phantom_dev(const GUID *iface_class, const wchar_t *path)
|
|||||||
class_ = &setupapi_classes[setupapi_nclasses++];
|
class_ = &setupapi_classes[setupapi_nclasses++];
|
||||||
class_->guid = iface_class;
|
class_->guid = iface_class;
|
||||||
class_->path = path;
|
class_->path = path;
|
||||||
|
|
||||||
|
a_path_len = wcslen(path) * sizeof(wchar_t) + 1;
|
||||||
|
class_->a_path = (char*)malloc(a_path_len);
|
||||||
|
wcstombs(class_->a_path, path, a_path_len);
|
||||||
|
|
||||||
hr = S_OK;
|
hr = S_OK;
|
||||||
|
|
||||||
end:
|
end:
|
||||||
@ -189,6 +232,40 @@ static HDEVINFO WINAPI my_SetupDiGetClassDevsW(
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 BOOL WINAPI my_SetupDiEnumDeviceInterfaces(
|
static BOOL WINAPI my_SetupDiEnumDeviceInterfaces(
|
||||||
HDEVINFO DeviceInfoSet,
|
HDEVINFO DeviceInfoSet,
|
||||||
SP_DEVINFO_DATA *DeviceInfoData,
|
SP_DEVINFO_DATA *DeviceInfoData,
|
||||||
@ -322,6 +399,76 @@ pass:
|
|||||||
DeviceInfoData);
|
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 char *str;
|
||||||
|
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) {
|
||||||
|
str = setupapi_classes[i].a_path;
|
||||||
|
match = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LeaveCriticalSection(&setupapi_lock);
|
||||||
|
|
||||||
|
if (!match) {
|
||||||
|
goto pass;
|
||||||
|
}
|
||||||
|
|
||||||
|
nbytes_str = strlen(str) + 1;
|
||||||
|
nbytes_total = offsetof(SP_DEVICE_INTERFACE_DETAIL_DATA_W, 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, str, nbytes_str);
|
||||||
|
SetLastError(ERROR_SUCCESS);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
pass:
|
||||||
|
return next_SetupDiGetDeviceInterfaceDetailA(
|
||||||
|
DeviceInfoSet,
|
||||||
|
DeviceInterfaceData,
|
||||||
|
DeviceInterfaceDetailData,
|
||||||
|
DeviceInterfaceDetailDataSize,
|
||||||
|
RequiredSize,
|
||||||
|
DeviceInfoData);
|
||||||
|
}
|
||||||
|
|
||||||
static BOOL WINAPI my_SetupDiDestroyDeviceInfoList(HDEVINFO DeviceInfoSet)
|
static BOOL WINAPI my_SetupDiDestroyDeviceInfoList(HDEVINFO DeviceInfoSet)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
|
Loading…
Reference in New Issue
Block a user