dongle: add vid and pid arguments

This commit is contained in:
Hay1tsme 2023-01-25 21:09:38 -05:00
parent 914ddc3e93
commit fd99f8956a
6 changed files with 211 additions and 28 deletions

View File

@ -34,7 +34,11 @@ static DWORD CALLBACK ferrum_pre_startup(void)
serial_hook_init();
hr = platform_hook_init(&ferrum_hook_cfg.platform, PLATFORM_ES3, ferrum_jvs_init, ferrum_hook_mod);
struct dongle_info dinfo;
dinfo.vid = 2970;
dinfo.pid = 3088;
hr = platform_hook_init(&ferrum_hook_cfg.platform, PLATFORM_ES3, ferrum_jvs_init, ferrum_hook_mod, dinfo);
if (FAILED(hr)) {
ExitProcess(EXIT_FAILURE);

View File

@ -10,15 +10,20 @@
#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 const wchar_t DEVNAME_HUB[] = L"$hub";
static const wchar_t DEVNAME_HUB_[] = L"\\\\.\\$hub";
static const wchar_t DEVNAME_DONGLE[] = L"$dongle";
static const wchar_t HUB_DRIVER_KEY[] = L"{36fc9e60-c465-11cf-8056-444553540000}\\0001";
static const wchar_t root_hub_name[] = L"Fake Root Hub";
static const DEVINST HUB_DEVINST = 573;
static const DEVINST DONGLE_DEVINST = 5730;
static struct es3sec_config config;
static HANDLE dongle_fd;
static HANDLE hub_fd;
static IID hubs_iid;
DEVINST root_dev_inst;
static DEVINST root_dev_inst;
static USHORT dongle_vid;
static USHORT dongle_pid;
static HRESULT es3sec_handle_hub_irp(struct irp *irp);
static HRESULT es3sec_handle_hub_open(struct irp *irp);
@ -30,6 +35,10 @@ 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 HRESULT es3sec_hub_handle_roothub(struct irp *irp);
static HRESULT es3sec_hub_handle_nodeinfo(struct irp *irp);
static HRESULT es3sec_hub_connection_info_ex(struct irp *irp);
static HRESULT es3sec_hub_descriptor_from_node(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);
@ -64,7 +73,7 @@ static const struct hook_symbol cm_syms[] = {
},
};
HRESULT es3sec_hook_init(const struct es3sec_config *cfg, char *vid, char *pid)
HRESULT es3sec_hook_init(const struct es3sec_config *cfg, USHORT vid, USHORT pid)
{
HRESULT hr;
assert(cfg != NULL);
@ -94,7 +103,9 @@ HRESULT es3sec_hook_init(const struct es3sec_config *cfg, char *vid, char *pid)
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);
dprintf("ES3 Dongle: init with VID %d PID %d\n", vid, pid);
dongle_vid = vid;
dongle_pid = pid;
memcpy(&config, cfg, sizeof(*cfg));
return S_OK;
@ -117,7 +128,7 @@ static HRESULT es3sec_handle_hub_irp(struct irp *irp)
static HRESULT es3sec_handle_hub_open(struct irp *irp)
{
if (!wstr_ieq(irp->open_filename, DEVNAME_HUB)) {
if (!wstr_ieq(irp->open_filename, DEVNAME_HUB) && !wstr_ieq(irp->open_filename, DEVNAME_HUB_)) {
return iohook_invoke_next(irp);
}
@ -136,18 +147,48 @@ static HRESULT es3sec_handle_hub_ioctl(struct irp *irp)
{
switch (irp->ioctl) {
case 0x220424: return es3sec_hub_handle_driverkey(irp);
case 0x220448: return es3sec_hub_connection_info_ex(irp);
case 0x220410: return es3sec_hub_descriptor_from_node(irp);
case 0x220408:
if (irp->read.nbytes == sizeof(USB_NODE_INFORMATION))
return es3sec_hub_handle_nodeinfo(irp);
else if (irp->read.nbytes >= sizeof(USB_ROOT_HUB_NAME))
return es3sec_hub_handle_roothub(irp);
else {
dprintf("ES3 Dongle: Bad size for IOCTL %X\n", irp->ioctl);
return HRESULT_FROM_WIN32(ERROR_INVALID_FUNCTION);
}
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);
{
size_t size_of_driver_key = sizeof(HUB_DRIVER_KEY);
ULONG actual_length = size_of_driver_key + sizeof(USB_ROOT_HUB_NAME);
HRESULT hr;
if (irp->write.nbytes == sizeof(USB_HCD_DRIVERKEY_NAME)) {
dprintf("ES3 Dongle: Get Hub Driver Key size\n");
USB_HCD_DRIVERKEY_NAME usb_hcd_driver_key_name;
usb_hcd_driver_key_name.ActualLength = actual_length;
hr = iobuf_write(&irp->read, &usb_hcd_driver_key_name, sizeof(usb_hcd_driver_key_name));
if (FAILED(hr)) {
dprintf("ES3 Dongle: iobuf_write failed! %lx\n", hr);
}
return hr;
}
dprintf("ES3 Dongle: Get Hub Driver Key\n");
PUSB_HCD_DRIVERKEY_NAME usb_hcd_driver_key_name = (PUSB_HCD_DRIVERKEY_NAME)malloc(sizeof(USB_HCD_DRIVERKEY_NAME) + 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),
@ -159,10 +200,130 @@ static HRESULT es3sec_hub_handle_driverkey(struct irp *irp)
return E_FAIL;
}
iobuf_write(&irp->read, usb_hcd_driver_key_name, sizeof(usb_hcd_driver_key_name));
hr = iobuf_write(&irp->read, usb_hcd_driver_key_name, actual_length);
dprintf("ES3 Dongle: Get Hub Driver Key\n");
return S_OK;
if (FAILED(hr)) {
dprintf("ES3 Dongle: iobuf_write failed! %lx\n", hr);
}
return hr;
}
static HRESULT es3sec_hub_handle_roothub(struct irp *irp)
{
size_t size_of_hub_name = sizeof(DEVNAME_HUB);
ULONG actual_length = size_of_hub_name + sizeof(USB_ROOT_HUB_NAME);
HRESULT hr;
if (irp->read.nbytes == sizeof(USB_ROOT_HUB_NAME)) {
dprintf("ES3 Dongle: Get Hub Root Hub Name size\n");
USB_ROOT_HUB_NAME rhub;
rhub.ActualLength = actual_length;
hr = iobuf_write(&irp->read, &rhub, sizeof(rhub));
if (FAILED(hr)) {
dprintf("ES3 Dongle: iobuf_write failed! %lx\n", hr);
}
return hr;
}
dprintf("ES3 Dongle: Get Hub Root Hub Name\n");
PUSB_ROOT_HUB_NAME rhub = (PUSB_ROOT_HUB_NAME)malloc(actual_length);
rhub->ActualLength = actual_length;
errno_t err = wcscpy_s(
rhub->RootHubName,
_countof(DEVNAME_HUB),
DEVNAME_HUB
);
if (err) {
dprintf("ES3 Dongle: es3sec_hub_handle_roothub wcscpy_s failed with %X", err);
return E_FAIL;
}
hr = iobuf_write(&irp->read, rhub, sizeof(USB_ROOT_HUB_NAME) + size_of_hub_name);
if (FAILED(hr)) {
dprintf("ES3 Dongle: iobuf_write failed! %lx\n", hr);
}
return hr;
}
static HRESULT es3sec_hub_handle_nodeinfo(struct irp *irp)
{
dprintf("ES3 Dongle: Get Hub Node Information\n");
USB_NODE_INFORMATION node_info;
node_info.NodeType = UsbHub;
node_info.u.HubInformation.HubDescriptor.bNumberOfPorts = 1;
HRESULT hr = iobuf_write(&irp->read, &node_info, sizeof(node_info));
if (FAILED(hr)) {
dprintf("ES3 Dongle: es3sec_hub_handle_nodeinfo iobuf_write failed! 0x%lX\n", hr);
}
return hr;
}
static HRESULT es3sec_hub_connection_info_ex(struct irp *irp)
{
HRESULT hr;
PUSB_NODE_CONNECTION_INFORMATION_EX conn_info = (PUSB_NODE_CONNECTION_INFORMATION_EX) malloc(irp->write.nbytes);
hr = iobuf_read(&irp->write, conn_info, irp->write.nbytes);
if (FAILED(hr)) {
dprintf("ES3 Dongle: es3sec_hub_connection_info_ex Failed to read IRP %lx\n", hr);
return hr;
}
dprintf("ES3 Dongle: Get Hub Connection Info EX\tConnectionIndex %ld\n", conn_info->ConnectionIndex);
conn_info->ConnectionStatus = DeviceConnected;
conn_info->DeviceIsHub = false;
conn_info->DeviceDescriptor.idVendor = dongle_vid;
conn_info->DeviceDescriptor.idProduct = dongle_pid;
conn_info->DeviceDescriptor.bLength = sizeof(conn_info->DeviceDescriptor);
hr = iobuf_write(&irp->read, conn_info, irp->read.nbytes);
if (FAILED(hr)) {
dprintf("ES3 Dongle: es3sec_hub_connection_info_ex Failed to write IRP %lx\n", hr);
}
return hr;
}
static HRESULT es3sec_hub_descriptor_from_node(struct irp *irp)
{
HRESULT hr;
UCHAR req_type;
UCHAR req_data_requested;
PUSB_DESCRIPTOR_REQUEST req = (PUSB_DESCRIPTOR_REQUEST) malloc(irp->write.nbytes);
hr = iobuf_read(&irp->write, req, irp->write.nbytes);
if (FAILED(hr)) {
dprintf("ES3 Dongle: es3sec_hub_descriptor_from_node Failed to read IRP %lx\n", hr);
return hr;
}
req_type = req->SetupPacket.wValue >> 8;
req_data_requested = req->SetupPacket.wValue & 0xFF;
dprintf("ES3 Dongle: Get Hub Descriptor from Node Connection\treq_type %02X req_data_requested %02X\n", req_type, req_data_requested);
switch (req_type) {
case USB_CONFIGURATION_DESCRIPTOR_TYPE: req->Data[2] = irp->write.nbytes - 12; break;
case USB_STRING_DESCRIPTOR_TYPE: break;
default:
dprintf("ES3 Dongle: es3sec_hub_descriptor_from_node Unknown request type %x\n", req_type);
return HRESULT_FROM_WIN32(ERROR_INVALID_FUNCTION);
}
hr = iobuf_write(&irp->read, req, irp->read.nbytes);
if (FAILED(hr)) {
dprintf("ES3 Dongle: es3sec_hub_descriptor_from_node Failed to write IRP %lx\n", hr);
}
return hr;
}
static HRESULT es3sec_handle_dongle_irp(struct irp *irp)
@ -199,8 +360,9 @@ static HRESULT es3sec_handle_dongle_close(struct irp *irp)
static HRESULT es3sec_handle_dongle_ioctl(struct irp *irp)
{
dprintf("ES3 Dongle: IOCTL %X\n", irp->ioctl);
return iohook_invoke_next(irp);
switch (irp->ioctl) {
default: dprintf("ES3 Dongle: Unknown dongle IOCTL %X\n", irp->ioctl); return HRESULT_FROM_WIN32(ERROR_INVALID_FUNCTION);
}
}
static CONFIGRET my_CM_Get_DevNode_Registry_PropertyW(
@ -218,16 +380,22 @@ static CONFIGRET my_CM_Get_DevNode_Registry_PropertyW(
}
switch (ulProperty) {
case CM_DRP_DEVICEDESC: wcscpy_s(Buffer, _countof(L"Disk drive"), L"Disk drive"); break;
case CM_DRP_DEVICEDESC:
dprintf("ES3 Dongle: Get hub device description\n");
// wcscpy_s(Buffer, _countof(L"Disk drive"), L"Disk drive");
wcscpy_s(Buffer, _countof(L"Fake USB Hub"), L"Fake USB Hub");
break;
case CM_DRP_DRIVER: wcscpy_s(Buffer, _countof(HUB_DRIVER_KEY), HUB_DRIVER_KEY); break;
case CM_DRP_DRIVER:
dprintf("ES3 Dongle: Get hub driver\n");
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);
dprintf("ES3 Dongle: my_CM_Get_DevNode_Registry_PropertyW Unhandled property 0x%lX\n", ulProperty);
return CR_FAILURE;
}
dprintf("ES3 Dongle: my_CM_Get_DevNode_Registry_PropertyW %lX\n", ulProperty);
return CR_SUCCESS;
}

View File

@ -9,4 +9,4 @@ struct es3sec_config {
wchar_t pid[5];
};
HRESULT es3sec_hook_init(const struct es3sec_config *cfg, char *vid, char *pid);
HRESULT es3sec_hook_init(const struct es3sec_config *cfg, USHORT vid, USHORT pid);

View File

@ -4,7 +4,8 @@ HRESULT platform_hook_init(
const struct platform_config *cfg,
enum platform_type type,
jvs_provider_t jvs,
HMODULE redir_mod
HMODULE redir_mod,
struct dongle_info d_info
)
{
HRESULT hr;
@ -56,7 +57,7 @@ HRESULT platform_hook_init(
return hr;
}
hr = es3sec_hook_init(&cfg->dongle, "", "");
hr = es3sec_hook_init(&cfg->dongle, d_info.vid, d_info.pid);
if (FAILED(hr)) {
return hr;

View File

@ -9,6 +9,11 @@
#include "platform/vfs.h"
#include "platform/es3sec.h"
struct dongle_info {
USHORT pid;
USHORT vid;
};
struct platform_config {
struct clock_config clock;
struct netenv_config netenv;
@ -30,5 +35,6 @@ HRESULT platform_hook_init(
const struct platform_config *cfg,
enum platform_type type,
jvs_provider_t jvs,
HMODULE redir_mod
HMODULE redir_mod,
struct dongle_info d_info
);

View File

@ -35,7 +35,11 @@ static DWORD CALLBACK taiko_pre_startup(void)
serial_hook_init();
hr = platform_hook_init(&taiko_hook_cfg.platform, PLATFORM_BNA1, NULL, taiko_hook_mod);
struct dongle_info dinfo;
dinfo.pid = 0;
dinfo.vid = 0;
hr = platform_hook_init(&taiko_hook_cfg.platform, PLATFORM_BNA1, NULL, taiko_hook_mod, dinfo);
if (FAILED(hr)) {
ExitProcess(EXIT_FAILURE);