mirror of
https://gitea.tendokyu.moe/TeamTofuShop/taitools.git
synced 2026-10-02 11:47:59 +03:00
add winusb hook and usbio board skeletons
This commit is contained in:
@@ -4,6 +4,7 @@ hooklib_lib = static_library(
|
||||
implicit_include_directories : false,
|
||||
dependencies : [
|
||||
capnhook.get_variable('hook_dep'),
|
||||
winusb_lib,
|
||||
],
|
||||
sources : [
|
||||
'cursor.c',
|
||||
@@ -28,5 +29,7 @@ hooklib_lib = static_library(
|
||||
'setupapi.h',
|
||||
'spike.c',
|
||||
'spike.h',
|
||||
'winusb.c',
|
||||
'winusb.h',
|
||||
],
|
||||
)
|
||||
|
||||
@@ -23,6 +23,12 @@ static void setupapi_hook_init(void);
|
||||
|
||||
/* API hooks */
|
||||
|
||||
static HDEVINFO WINAPI my_SetupDiGetClassDevsA(
|
||||
const GUID *ClassGuid,
|
||||
char *Enumerator,
|
||||
HWND hwndParent,
|
||||
DWORD Flags);
|
||||
|
||||
static HDEVINFO WINAPI my_SetupDiGetClassDevsW(
|
||||
const GUID *ClassGuid,
|
||||
wchar_t *Enumerator,
|
||||
@@ -44,10 +50,24 @@ static BOOL WINAPI my_SetupDiGetDeviceInterfaceDetailW(
|
||||
DWORD *RequiredSize,
|
||||
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);
|
||||
|
||||
/* Links */
|
||||
|
||||
static HDEVINFO (WINAPI *next_SetupDiGetClassDevsA)(
|
||||
const GUID *ClassGuid,
|
||||
char *Enumerator,
|
||||
HWND hwndParent,
|
||||
DWORD Flags);
|
||||
|
||||
static HDEVINFO (WINAPI *next_SetupDiGetClassDevsW)(
|
||||
const GUID *ClassGuid,
|
||||
wchar_t *Enumerator,
|
||||
@@ -69,12 +89,24 @@ static BOOL (WINAPI *next_SetupDiGetDeviceInterfaceDetailW)(
|
||||
DWORD *RequiredSize,
|
||||
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);
|
||||
|
||||
/* Hook tbl */
|
||||
|
||||
static const struct hook_symbol setupapi_syms[] = {
|
||||
{
|
||||
.name = "SetupDiGetClassDevsA",
|
||||
.patch = my_SetupDiGetClassDevsA,
|
||||
.link = (void *) &next_SetupDiGetClassDevsA,
|
||||
}, {
|
||||
.name = "SetupDiGetClassDevsW",
|
||||
.patch = my_SetupDiGetClassDevsW,
|
||||
.link = (void *) &next_SetupDiGetClassDevsW,
|
||||
@@ -86,6 +118,10 @@ static const struct hook_symbol setupapi_syms[] = {
|
||||
.name = "SetupDiGetDeviceInterfaceDetailW",
|
||||
.patch = my_SetupDiGetDeviceInterfaceDetailW,
|
||||
.link = (void *) &next_SetupDiGetDeviceInterfaceDetailW,
|
||||
}, {
|
||||
.name = "SetupDiGetDeviceInterfaceDetailA",
|
||||
.patch = my_SetupDiGetDeviceInterfaceDetailA,
|
||||
.link = (void *) &next_SetupDiGetDeviceInterfaceDetailA,
|
||||
}, {
|
||||
.name = "SetupDiDestroyDeviceInfoList",
|
||||
.patch = my_SetupDiDestroyDeviceInfoList,
|
||||
@@ -155,6 +191,40 @@ void setupapi_hook_insert_hooks(HMODULE target)
|
||||
_countof(setupapi_syms));
|
||||
}
|
||||
|
||||
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 HDEVINFO WINAPI my_SetupDiGetClassDevsW(
|
||||
const GUID *ClassGuid,
|
||||
wchar_t *Enumerator,
|
||||
@@ -322,6 +392,82 @@ pass:
|
||||
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 wchar_t *wstr;
|
||||
char path_ch[MAX_PATH];
|
||||
size_t nbytes_wstr;
|
||||
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) {
|
||||
match = true;
|
||||
}
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&setupapi_lock);
|
||||
|
||||
if (!match) {
|
||||
goto pass;
|
||||
}
|
||||
|
||||
wstr = (const wchar_t *) DeviceInterfaceData->Reserved;
|
||||
nbytes_wstr = (wcslen(wstr) + 1) * sizeof(wchar_t);
|
||||
|
||||
wcstombs_s(&nbytes_str, path_ch, MAX_PATH, (wchar_t *) DeviceInterfaceData->Reserved, MAX_PATH);
|
||||
nbytes_total = offsetof(SP_DEVICE_INTERFACE_DETAIL_DATA_A, 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, path_ch, nbytes_str);
|
||||
SetLastError(ERROR_SUCCESS);
|
||||
|
||||
return TRUE;
|
||||
|
||||
pass:
|
||||
return next_SetupDiGetDeviceInterfaceDetailA(
|
||||
DeviceInfoSet,
|
||||
DeviceInterfaceData,
|
||||
DeviceInterfaceDetailData,
|
||||
DeviceInterfaceDetailDataSize,
|
||||
RequiredSize,
|
||||
DeviceInfoData);
|
||||
}
|
||||
|
||||
static BOOL WINAPI my_SetupDiDestroyDeviceInfoList(HDEVINFO DeviceInfoSet)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
@@ -0,0 +1,223 @@
|
||||
#include <windows.h>
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "hook/table.h"
|
||||
|
||||
#include "hooklib/winusb.h"
|
||||
|
||||
#include "util/dprintf.h"
|
||||
|
||||
static bool winusb_initted;
|
||||
static CRITICAL_SECTION winusb_lock;
|
||||
static struct winusb_dev *winusb_classes;
|
||||
static size_t winusb_nclasses;
|
||||
|
||||
static void winusb_hook_init();
|
||||
|
||||
BOOL my_WinUsb_QueryPipe(
|
||||
WINUSB_INTERFACE_HANDLE InterfaceHandle,
|
||||
UCHAR AlternateInterfaceNumber,
|
||||
UCHAR PipeIndex,
|
||||
PWINUSB_PIPE_INFORMATION PipeInformation
|
||||
);
|
||||
|
||||
BOOL my_WinUsb_QueryInterfaceSettings(
|
||||
WINUSB_INTERFACE_HANDLE InterfaceHandle,
|
||||
UCHAR AlternateInterfaceNumber,
|
||||
PUSB_INTERFACE_DESCRIPTOR UsbAltInterfaceDescriptor
|
||||
);
|
||||
|
||||
BOOL my_WinUsb_GetDescriptor(
|
||||
WINUSB_INTERFACE_HANDLE InterfaceHandle,
|
||||
UCHAR DescriptorType,
|
||||
UCHAR Index,
|
||||
USHORT LanguageID,
|
||||
PUCHAR Buffer,
|
||||
ULONG BufferLength,
|
||||
PULONG LengthTransferred
|
||||
);
|
||||
|
||||
BOOL my_WinUsb_WritePipe(
|
||||
WINUSB_INTERFACE_HANDLE InterfaceHandle,
|
||||
UCHAR PipeID,
|
||||
PUCHAR Buffer,
|
||||
ULONG BufferLength,
|
||||
PULONG LengthTransferred,
|
||||
LPOVERLAPPED Overlapped
|
||||
);
|
||||
|
||||
BOOL my_WinUsb_QueryDeviceInformation(
|
||||
WINUSB_INTERFACE_HANDLE InterfaceHandle,
|
||||
ULONG InformationType,
|
||||
PULONG BufferLength,
|
||||
PVOID Buffer
|
||||
);
|
||||
|
||||
BOOL my_WinUsb_ReadPipe(
|
||||
WINUSB_INTERFACE_HANDLE InterfaceHandle,
|
||||
UCHAR PipeID,
|
||||
PUCHAR Buffer,
|
||||
ULONG BufferLength,
|
||||
PULONG LengthTransferred,
|
||||
LPOVERLAPPED Overlapped
|
||||
);
|
||||
|
||||
BOOL my_WinUsb_Initialize(
|
||||
HANDLE DeviceHandle,
|
||||
PWINUSB_INTERFACE_HANDLE InterfaceHandle
|
||||
);
|
||||
|
||||
BOOL my_WinUsb_Free(
|
||||
WINUSB_INTERFACE_HANDLE InterfaceHandle
|
||||
);
|
||||
|
||||
BOOL (*next_WinUsb_QueryPipe)(
|
||||
WINUSB_INTERFACE_HANDLE InterfaceHandle,
|
||||
UCHAR AlternateInterfaceNumber,
|
||||
UCHAR PipeIndex,
|
||||
PWINUSB_PIPE_INFORMATION PipeInformation
|
||||
);
|
||||
|
||||
BOOL (*next_WinUsb_QueryInterfaceSettings)(
|
||||
WINUSB_INTERFACE_HANDLE InterfaceHandle,
|
||||
UCHAR AlternateInterfaceNumber,
|
||||
PUSB_INTERFACE_DESCRIPTOR UsbAltInterfaceDescriptor
|
||||
);
|
||||
|
||||
BOOL (*next_WinUsb_GetDescriptor)(
|
||||
WINUSB_INTERFACE_HANDLE InterfaceHandle,
|
||||
UCHAR DescriptorType,
|
||||
UCHAR Index,
|
||||
USHORT LanguageID,
|
||||
PUCHAR Buffer,
|
||||
ULONG BufferLength,
|
||||
PULONG LengthTransferred
|
||||
);
|
||||
|
||||
BOOL (*next_WinUsb_WritePipe)(
|
||||
WINUSB_INTERFACE_HANDLE InterfaceHandle,
|
||||
UCHAR PipeID,
|
||||
PUCHAR Buffer,
|
||||
ULONG BufferLength,
|
||||
PULONG LengthTransferred,
|
||||
LPOVERLAPPED Overlapped
|
||||
);
|
||||
|
||||
BOOL (*next_WinUsb_QueryDeviceInformation)(
|
||||
WINUSB_INTERFACE_HANDLE InterfaceHandle,
|
||||
ULONG InformationType,
|
||||
PULONG BufferLength,
|
||||
PVOID Buffer
|
||||
);
|
||||
|
||||
BOOL (*next_WinUsb_ReadPipe)(
|
||||
WINUSB_INTERFACE_HANDLE InterfaceHandle,
|
||||
UCHAR PipeID,
|
||||
PUCHAR Buffer,
|
||||
ULONG BufferLength,
|
||||
PULONG LengthTransferred,
|
||||
LPOVERLAPPED Overlapped
|
||||
);
|
||||
|
||||
BOOL (*next_WinUsb_Initialize)(
|
||||
HANDLE DeviceHandle,
|
||||
PWINUSB_INTERFACE_HANDLE InterfaceHandle
|
||||
);
|
||||
|
||||
BOOL (*next_WinUsb_Free)(
|
||||
WINUSB_INTERFACE_HANDLE InterfaceHandle
|
||||
);
|
||||
|
||||
static const struct hook_symbol winusb_syms[] = {
|
||||
{
|
||||
.name = "WinUsb_QueryPipe",
|
||||
.patch = my_WinUsb_QueryPipe,
|
||||
.link = (void *) &next_WinUsb_QueryPipe,
|
||||
}, {
|
||||
.name = "WinUsb_QueryInterfaceSettings",
|
||||
.patch = my_WinUsb_QueryInterfaceSettings,
|
||||
.link = (void *) &next_WinUsb_QueryInterfaceSettings,
|
||||
}, {
|
||||
.name = "WinUsb_GetDescriptor",
|
||||
.patch = my_WinUsb_GetDescriptor,
|
||||
.link = (void *) &next_WinUsb_GetDescriptor,
|
||||
}, {
|
||||
.name = "WinUsb_WritePipe",
|
||||
.patch = my_WinUsb_WritePipe,
|
||||
.link = (void *) &next_WinUsb_WritePipe,
|
||||
}, {
|
||||
.name = "WinUsb_QueryDeviceInformation",
|
||||
.patch = my_WinUsb_QueryDeviceInformation,
|
||||
.link = (void *) &next_WinUsb_QueryDeviceInformation,
|
||||
}, {
|
||||
.name = "WinUsb_ReadPipe",
|
||||
.patch = my_WinUsb_ReadPipe,
|
||||
.link = (void *) &next_WinUsb_ReadPipe,
|
||||
}, {
|
||||
.name = "WinUsb_Initialize",
|
||||
.patch = my_WinUsb_Initialize,
|
||||
.link = (void *) &next_WinUsb_Initialize,
|
||||
}, {
|
||||
.name = "WinUsb_Free",
|
||||
.patch = my_WinUsb_Free,
|
||||
.link = (void *) &next_WinUsb_Free,
|
||||
}
|
||||
};
|
||||
|
||||
HRESULT winusb_add_phantom_dev(const struct winusb_dev *dev)
|
||||
{
|
||||
struct winusb_dev *class_;
|
||||
struct winusb_dev *new_array;
|
||||
HRESULT hr;
|
||||
|
||||
assert(dev != NULL);
|
||||
|
||||
winusb_hook_init();
|
||||
|
||||
EnterCriticalSection(&winusb_lock);
|
||||
|
||||
new_array = realloc(
|
||||
winusb_classes,
|
||||
(winusb_nclasses + 1) * sizeof(struct winusb_dev));
|
||||
|
||||
if (new_array == NULL) {
|
||||
hr = E_OUTOFMEMORY;
|
||||
|
||||
goto end;
|
||||
}
|
||||
|
||||
winusb_classes = new_array;
|
||||
|
||||
// TODO: Copy the dev class to the new slot in the array
|
||||
class_ = &winusb_classes[winusb_nclasses++];
|
||||
hr = S_OK;
|
||||
|
||||
end:
|
||||
LeaveCriticalSection(&winusb_lock);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static void winusb_hook_init()
|
||||
{
|
||||
if (winusb_initted) {
|
||||
return;
|
||||
}
|
||||
|
||||
winusb_hook_insert_hooks(NULL);
|
||||
|
||||
InitializeCriticalSection(&winusb_lock);
|
||||
winusb_initted = true;
|
||||
}
|
||||
|
||||
void winusb_hook_insert_hooks(HMODULE target)
|
||||
{
|
||||
hook_table_apply(
|
||||
target,
|
||||
"winusb.dll",
|
||||
winusb_syms,
|
||||
_countof(winusb_syms));
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
#include <windows.h>
|
||||
#include <stdint.h>
|
||||
#include <winusb.h>
|
||||
|
||||
#pragma pack(push,1)
|
||||
|
||||
// winusb - hooks for winusb ident, read and write passed to device
|
||||
// usio - providor for winusb, passes along read/write
|
||||
// ll3io - gives usio the data to write
|
||||
|
||||
struct winusb_dev {
|
||||
HANDLE fd;
|
||||
GUID class_guid;
|
||||
const wchar_t *path;
|
||||
//uint8_t read_pipe_id; // duno if this ever needs to change?
|
||||
//uint8_t write_pipe_id;
|
||||
struct _USB_DEVICE_DESCRIPTOR descriptor;
|
||||
void (*read_pipe)(void *ctx, uint8_t pipe_id, uint8_t *bfr, uint32_t bfr_len);
|
||||
void (*write_pipe)(void *ctx, uint8_t pipe_id, uint8_t *bfr, uint32_t bfr_len);
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
HRESULT winusb_add_phantom_dev(const struct winusb_dev *dev);
|
||||
void winusb_hook_insert_hooks(HMODULE target);
|
||||
Reference in New Issue
Block a user