progress on ES3 dongle
This commit is contained in:
parent
1a507f77e7
commit
f0511e0f67
@ -12,7 +12,7 @@ void amcus_config_load(struct amcus_config *cfg, const wchar_t *filename)
|
||||
GetPrivateProfileStringW(L"amcus", L"cacfg_game_ver", L"00.01", cfg->cacfg_game_ver, _countof(cfg->cacfg_game_ver), filename);
|
||||
GetPrivateProfileStringW(L"amcus", L"server_uri", L"localhost", cfg->server_uri, _countof(cfg->server_uri), filename);
|
||||
GetPrivateProfileStringW(L"amcus", L"server_host", L"localhost", cfg->server_host, _countof(cfg->server_host), filename);
|
||||
GetPrivateProfileStringW(L"amcus", L"am_serial", L"ABLN6789012", cfg->am_serial, _countof(cfg->am_serial), filename);
|
||||
GetPrivateProfileStringW(L"amcus", L"am_serial", L"ABGN6789012", cfg->am_serial, _countof(cfg->am_serial), filename);
|
||||
|
||||
es3sec_config_load(&cfg->dongle, filename);
|
||||
}
|
@ -38,6 +38,7 @@ shlwapi_lib = cc.find_library('shlwapi')
|
||||
dinput8_lib = cc.find_library('dinput8')
|
||||
dxguid_lib = cc.find_library('dxguid')
|
||||
xinput_lib = cc.find_library('xinput')
|
||||
cfgmgr32_lib = cc.find_library('cfgmgr32')
|
||||
|
||||
inc = include_directories('.')
|
||||
capnhook = subproject('capnhook')
|
||||
|
@ -1,4 +1,243 @@
|
||||
#include <windows.h>
|
||||
#include <cfgmgr32.h>
|
||||
#include <usbioctl.h>
|
||||
|
||||
#include "hook/table.h"
|
||||
#include "hook/iohook.h"
|
||||
#include "hooklib/setupapi.h"
|
||||
|
||||
#include "util/dprintf.h"
|
||||
#include "util/str.h"
|
||||
#include "es3sec.h"
|
||||
|
||||
const wchar_t *DEVNAME_HUB = L"$hub";
|
||||
const wchar_t *DEVNAME_DONGLE = L"$dongle";
|
||||
const wchar_t HUB_DRIVER_KEY[] = L"{36fc9e60-c465-11cf-8056-444553540000}\\0001";
|
||||
const DEVINST HUB_DEVINST = 573;
|
||||
static struct es3sec_config config;
|
||||
static HANDLE dongle_fd;
|
||||
static HANDLE hub_fd;
|
||||
static IID hubs_iid;
|
||||
DEVINST root_dev_inst;
|
||||
|
||||
static HRESULT es3sec_handle_hub_irp(struct irp *irp);
|
||||
static HRESULT es3sec_handle_hub_open(struct irp *irp);
|
||||
static HRESULT es3sec_handle_hub_close(struct irp *irp);
|
||||
static HRESULT es3sec_handle_hub_ioctl(struct irp *irp);
|
||||
static HRESULT es3sec_handle_dongle_irp(struct irp *irp);
|
||||
static HRESULT es3sec_handle_dongle_open(struct irp *irp);
|
||||
static HRESULT es3sec_handle_dongle_close(struct irp *irp);
|
||||
static HRESULT es3sec_handle_dongle_ioctl(struct irp *irp);
|
||||
|
||||
static HRESULT es3sec_hub_handle_driverkey(struct irp *irp);
|
||||
|
||||
static CONFIGRET my_CM_Get_Child(PDEVINST pdnDevInst, DEVINST dnDevInst, ULONG ulFlags);
|
||||
static CONFIGRET (*next_CM_Get_Child)(PDEVINST pdnDevInst, DEVINST dnDevInst, ULONG ulFlags);
|
||||
|
||||
static CONFIGRET my_CM_Get_DevNode_Registry_PropertyW(
|
||||
DEVINST dnDevInst,
|
||||
ULONG ulProperty,
|
||||
PULONG pulRegDataType,
|
||||
PVOID Buffer,
|
||||
PULONG pulLength,
|
||||
ULONG ulFlags
|
||||
);
|
||||
static CONFIGRET (*next_CM_Get_DevNode_Registry_PropertyW)(
|
||||
DEVINST dnDevInst,
|
||||
ULONG ulProperty,
|
||||
PULONG pulRegDataType,
|
||||
PVOID Buffer,
|
||||
PULONG pulLength,
|
||||
ULONG ulFlags
|
||||
);
|
||||
|
||||
static const struct hook_symbol cm_syms[] = {
|
||||
{
|
||||
.name = "CM_Get_DevNode_Registry_PropertyW",
|
||||
.patch = my_CM_Get_DevNode_Registry_PropertyW,
|
||||
.link = (void **) &next_CM_Get_DevNode_Registry_PropertyW
|
||||
},
|
||||
{
|
||||
.name = "CM_Get_Child",
|
||||
.patch = my_CM_Get_Child,
|
||||
.link = (void **) &next_CM_Get_Child
|
||||
},
|
||||
};
|
||||
|
||||
HRESULT es3sec_hook_init(const struct es3sec_config *cfg, char *vid, char *pid)
|
||||
{
|
||||
HRESULT hr;
|
||||
assert(cfg != NULL);
|
||||
|
||||
if (!cfg->enable) {
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
IIDFromString(L"{3ABF6F2D-71C4-462a-8A92-1E6861E6AF27}", &hubs_iid);
|
||||
setupapi_add_phantom_dev(&hubs_iid, DEVNAME_HUB);
|
||||
|
||||
hr = iohook_open_nul_fd(&dongle_fd);
|
||||
hr = iohook_open_nul_fd(&hub_fd);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
hr = iohook_push_handler(es3sec_handle_hub_irp);
|
||||
hr = iohook_push_handler(es3sec_handle_dongle_irp);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
hook_table_apply(NULL, "setupapi.dll", cm_syms, _countof(cm_syms));
|
||||
|
||||
CM_Locate_DevNodeW(&root_dev_inst, NULL, CM_LOCATE_DEVNODE_NORMAL);
|
||||
|
||||
dprintf("ES3 Dongle: init with VID %s PID %s (root node DEVINST %lx)\n", vid, pid, root_dev_inst);
|
||||
|
||||
memcpy(&config, cfg, sizeof(*cfg));
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT es3sec_handle_hub_irp(struct irp *irp)
|
||||
{
|
||||
assert(irp != NULL);
|
||||
if (irp->op != IRP_OP_OPEN && irp->fd != hub_fd) {
|
||||
return iohook_invoke_next(irp);
|
||||
}
|
||||
|
||||
switch (irp->op) {
|
||||
case IRP_OP_OPEN: return es3sec_handle_hub_open(irp);
|
||||
case IRP_OP_CLOSE: return es3sec_handle_hub_close(irp);
|
||||
case IRP_OP_IOCTL: return es3sec_handle_hub_ioctl(irp);
|
||||
default: return HRESULT_FROM_WIN32(ERROR_INVALID_FUNCTION);
|
||||
}
|
||||
}
|
||||
|
||||
static HRESULT es3sec_handle_hub_open(struct irp *irp)
|
||||
{
|
||||
if (!wstr_ieq(irp->open_filename, DEVNAME_HUB)) {
|
||||
return iohook_invoke_next(irp);
|
||||
}
|
||||
|
||||
dprintf("ES3 Dongle: Open USB Hub\n");
|
||||
irp->fd = hub_fd;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT es3sec_handle_hub_close(struct irp *irp)
|
||||
{
|
||||
dprintf("ES3 Dongle: Close Hub\n");
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT es3sec_handle_hub_ioctl(struct irp *irp)
|
||||
{
|
||||
switch (irp->ioctl) {
|
||||
case 0x220424: return es3sec_hub_handle_driverkey(irp);
|
||||
default: dprintf("ES3 Dongle: Unknown hub IOCTL %X\n", irp->ioctl); return HRESULT_FROM_WIN32(ERROR_INVALID_FUNCTION);
|
||||
}
|
||||
|
||||
return iohook_invoke_next(irp);
|
||||
}
|
||||
|
||||
static HRESULT es3sec_hub_handle_driverkey(struct irp *irp)
|
||||
{
|
||||
int actual_length = sizeof(HUB_DRIVER_KEY);
|
||||
PUSB_HCD_DRIVERKEY_NAME usb_hcd_driver_key_name = (PUSB_HCD_DRIVERKEY_NAME) malloc(sizeof(USB_HCD_DRIVERKEY_NAME) + 2 * actual_length);
|
||||
|
||||
usb_hcd_driver_key_name->ActualLength = actual_length;
|
||||
errno_t err = wcscpy_s(
|
||||
usb_hcd_driver_key_name->DriverKeyName,
|
||||
_countof(HUB_DRIVER_KEY),
|
||||
HUB_DRIVER_KEY
|
||||
);
|
||||
|
||||
if (err) {
|
||||
dprintf("ES3 Dongle: es3sec_hub_handle_driverkey wcscpy_s failed with %X", err);
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
iobuf_write(&irp->read, usb_hcd_driver_key_name, sizeof(usb_hcd_driver_key_name));
|
||||
|
||||
dprintf("ES3 Dongle: Get Hub Driver Key\n");
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT es3sec_handle_dongle_irp(struct irp *irp)
|
||||
{
|
||||
assert(irp != NULL);
|
||||
if (irp->op != IRP_OP_OPEN && irp->fd != dongle_fd) {
|
||||
return iohook_invoke_next(irp);
|
||||
}
|
||||
|
||||
switch (irp->op) {
|
||||
case IRP_OP_OPEN: return es3sec_handle_dongle_open(irp);
|
||||
case IRP_OP_CLOSE: return es3sec_handle_dongle_close(irp);
|
||||
case IRP_OP_IOCTL: return es3sec_handle_dongle_ioctl(irp);
|
||||
default: return HRESULT_FROM_WIN32(ERROR_INVALID_FUNCTION);
|
||||
}
|
||||
}
|
||||
|
||||
static HRESULT es3sec_handle_dongle_open(struct irp *irp)
|
||||
{
|
||||
if (!wstr_ieq(irp->open_filename, DEVNAME_DONGLE)) {
|
||||
return iohook_invoke_next(irp);
|
||||
}
|
||||
|
||||
dprintf("ES3 Dongle: Open dongle\n");
|
||||
irp->fd = dongle_fd;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT es3sec_handle_dongle_close(struct irp *irp)
|
||||
{
|
||||
dprintf("ES3 Dongle: Close dongle\n");
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT es3sec_handle_dongle_ioctl(struct irp *irp)
|
||||
{
|
||||
dprintf("ES3 Dongle: IOCTL %X\n", irp->ioctl);
|
||||
return iohook_invoke_next(irp);
|
||||
}
|
||||
|
||||
static CONFIGRET my_CM_Get_DevNode_Registry_PropertyW(
|
||||
DEVINST dnDevInst,
|
||||
ULONG ulProperty,
|
||||
PULONG pulRegDataType,
|
||||
PVOID Buffer,
|
||||
PULONG pulLength,
|
||||
ULONG ulFlags
|
||||
)
|
||||
{
|
||||
CONFIGRET cr = next_CM_Get_DevNode_Registry_PropertyW(dnDevInst, ulProperty, pulRegDataType, Buffer, pulLength, ulFlags);
|
||||
if (dnDevInst != HUB_DEVINST) {
|
||||
return cr;
|
||||
}
|
||||
|
||||
switch (ulProperty) {
|
||||
case CM_DRP_DEVICEDESC: wcscpy_s(Buffer, _countof(L"Disk drive"), L"Disk drive"); break;
|
||||
|
||||
case CM_DRP_DRIVER: wcscpy_s(Buffer, _countof(HUB_DRIVER_KEY), HUB_DRIVER_KEY); break;
|
||||
|
||||
default:
|
||||
dprintf("ES3 Dongle: my_CM_Get_DevNode_Registry_PropertyW Unhandled property %lX\n", ulProperty);
|
||||
return CR_FAILURE;
|
||||
}
|
||||
|
||||
dprintf("ES3 Dongle: my_CM_Get_DevNode_Registry_PropertyW %lX\n", ulProperty);
|
||||
return CR_SUCCESS;
|
||||
}
|
||||
|
||||
static CONFIGRET my_CM_Get_Child(PDEVINST pdnDevInst, DEVINST dnDevInst, ULONG ulFlags)
|
||||
{
|
||||
if (dnDevInst != root_dev_inst) {
|
||||
return next_CM_Get_Child(pdnDevInst, dnDevInst, ulFlags);
|
||||
}
|
||||
|
||||
dprintf("ES3 Dongle: Adding fake hub to root node\n");
|
||||
*pdnDevInst = HUB_DEVINST;
|
||||
return CR_SUCCESS;
|
||||
}
|
||||
|
@ -5,4 +5,8 @@
|
||||
struct es3sec_config {
|
||||
bool enable;
|
||||
wchar_t serial[13];
|
||||
wchar_t vid[5];
|
||||
wchar_t pid[5];
|
||||
};
|
||||
|
||||
HRESULT es3sec_hook_init(const struct es3sec_config *cfg, char *vid, char *pid);
|
||||
|
@ -6,6 +6,7 @@ platform_lib = static_library(
|
||||
dependencies : [
|
||||
capnhook.get_variable('hook_dep'),
|
||||
shlwapi_lib,
|
||||
cfgmgr32_lib,
|
||||
],
|
||||
link_with : [
|
||||
board_lib
|
||||
@ -29,6 +30,7 @@ platform_lib = static_library(
|
||||
'misc.h',
|
||||
'vfs.c',
|
||||
'vfs.h',
|
||||
'es3sec.c',
|
||||
'es3sec.h',
|
||||
],
|
||||
)
|
||||
|
@ -56,5 +56,11 @@ HRESULT platform_hook_init(
|
||||
return hr;
|
||||
}
|
||||
|
||||
hr = es3sec_hook_init(&cfg->dongle, "", "");
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
Loading…
Reference in New Issue
Block a user