diff --git a/ri/ri.c b/ri/ri.c index 3a1e48b..eb2dd96 100644 --- a/ri/ri.c +++ b/ri/ri.c @@ -3,7 +3,6 @@ #include #include #include -#include #include #include "hook/iohook.h" @@ -13,9 +12,17 @@ static HWND ri_hwnd; static WNDCLASSEX ri_wndclass; -static HANDLE selected_ri_dev = (HANDLE)-1; static uintptr_t ri_thread; +static struct RI_DEVICE selected_ri_dev = +{ + .hDevice = INVALID_HANDLE_VALUE, + .capeabilities = NULL, + .preparsed_data = NULL, + .prod_name = L"", + .dev_name = L"" +}; + static ri_mouse_cb_t mouse_cb = NULL; static ri_kb_cb_t kb_cb = NULL; static ri_hid_cb_t hid_cb = NULL; @@ -27,10 +34,15 @@ HRESULT ri_init(uint8_t dev_num, ri_mouse_cb_t in_mouse_cb, ri_kb_cb_t in_kb_cb, { wchar_t ri_dev_name[MAX_PATH] = L"\0"; wchar_t hid_prod_name[MAX_PATH] = L"\0"; + PHIDP_PREPARSED_DATA ppdata = NULL; + PHIDP_CAPS caps = NULL; UINT num_ri_devs = 0; UINT len_ri_dev_name = 0; + UINT len_ri_preparsed_data = 0; DWORD err = 0; PRAWINPUTDEVICELIST ri_devs = NULL; + uint32_t num_final_devs = 0; + PRI_DEVICE final_dev_list; mouse_cb = in_mouse_cb; kb_cb = in_kb_cb; @@ -55,6 +67,32 @@ HRESULT ri_init(uint8_t dev_num, ri_mouse_cb_t in_mouse_cb, ri_kb_cb_t in_kb_cb, dprintf("RawInput: Raw Input device list (%d devices):\n", num_ri_devs); for (int i = 0; i < num_ri_devs; i++) { len_ri_dev_name = 0; + len_ri_preparsed_data = 0; + if (GetRawInputDeviceInfo(ri_devs[i].hDevice, RIDI_PREPARSEDDATA, NULL, &len_ri_preparsed_data) != 0) { + dprintf("RawInput: GetRawInputDeviceInfo #%d failed to get preprocessed data size\n", i); + break; + } + + if (len_ri_preparsed_data <= 0) { + dprintf("RawInput: GetRawInputDeviceInfoW #%d len_ri_preparsed_data <= 0\n", i); + break; + } + + if (GetRawInputDeviceInfo(ri_devs[i].hDevice, RIDI_PREPARSEDDATA, ppdata, &len_ri_preparsed_data) != 0) { + dprintf("RawInput: GetRawInputDeviceInfo #%d failed to get preprocessed data\n", i); + break; + } + + if (HidP_GetCaps(ppdata, caps) != HIDP_STATUS_SUCCESS) { + dprintf("RawInput: HidP_GetCaps #%d failed to get capeabilities data size\n", i); + break; + } + + if ((caps->UsagePage >> 8) == 0xFF) { + dprintf("RawInput: Skipping vendor-specific device #%d\n", i); + continue; + } + if (GetRawInputDeviceInfoW(ri_devs[i].hDevice, RIDI_DEVICENAME, NULL, &len_ri_dev_name) != 0) { dprintf("RawInput: GetRawInputDeviceInfoW #%d failed to get name size\n", i); break; @@ -83,16 +121,37 @@ HRESULT ri_init(uint8_t dev_num, ri_mouse_cb_t in_mouse_cb, ri_kb_cb_t in_kb_cb, } if (!HidD_GetProductString(hiddev, hid_prod_name, MAX_PATH)) { - //dprintf("RawInput: HidD_GetProductString failed on dev #%d for device %ls\n", i, ri_dev_name); continue; } + + PRI_DEVICE new_dev; + PRI_DEVICE new_mem = realloc(final_dev_list, (num_final_devs + 1) * sizeof(struct RI_DEVICE)); - dprintf("\tDev #%d - %ls\n", i, hid_prod_name); + new_dev = &new_mem[num_final_devs]; + new_dev->hDevice = ri_devs[i].hDevice; + // does this need memcpy? + new_dev->capeabilities = caps; + new_dev->preparsed_data = ppdata; + new_dev->dev_name = ri_dev_name; + new_dev->prod_name = hid_prod_name; + + final_dev_list = new_mem; + num_final_devs++; + } + + if (dev_num >= num_final_devs) { + dprintf("RawInput: No RawInput device set, please select from the list below:\n"); + for (int i = 0; i < num_final_devs; i++) { + dprintf("\tDev #%d - %ls\n", i, hid_prod_name); + } + + free(ri_devs); + free(final_dev_list); + return S_FALSE; } - selected_ri_dev = ri_devs[dev_num].hDevice; - - free(ri_devs); + selected_ri_dev = final_dev_list[dev_num]; + dprintf("RawInput: Using device %ls\n", selected_ri_dev.prod_name); ri_wndclass.cbSize = sizeof(WNDCLASSEX); ri_wndclass.hInstance = GetModuleHandle(NULL); @@ -101,13 +160,10 @@ HRESULT ri_init(uint8_t dev_num, ri_mouse_cb_t in_mouse_cb, ri_kb_cb_t in_kb_cb, RegisterClassEx(&ri_wndclass); - ri_thread = _beginthreadex( - NULL, - 0, - ri_thread_proc, - NULL, - 0, - NULL); + ri_thread = _beginthreadex(NULL, 0, ri_thread_proc, NULL, 0, NULL); + + free(ri_devs); + free(final_dev_list); return S_OK; } @@ -120,6 +176,11 @@ void ri_exit() static unsigned int __stdcall ri_thread_proc(void *ctx) { + if (selected_ri_dev.hDevice == INVALID_HANDLE_VALUE) { + dprintf("RawInput: ri_thread_proc cannont begin, no device selected\n"); + return (LRESULT)0; + } + dprintf("RawInput: ri_thread_proc begin\n"); SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL); @@ -174,7 +235,7 @@ LRESULT CALLBACK ri_win_proc(HWND hWnd, UINT msg, WPARAM wparam, LPARAM lParam) PRAWINPUT ridata = (PRAWINPUT)malloc(pdata_size); GetRawInputData((HRAWINPUT)lParam, RID_INPUT, ridata, &pdata_size, sizeof(RAWINPUTHEADER)); - if (ridata->header.hDevice != selected_ri_dev) { + if (ridata->header.hDevice != selected_ri_dev.hDevice) { free(ridata); return (LRESULT)0; } @@ -182,17 +243,17 @@ LRESULT CALLBACK ri_win_proc(HWND hWnd, UINT msg, WPARAM wparam, LPARAM lParam) switch (ridata->header.dwType) { case RIM_TYPEMOUSE: if (mouse_cb != NULL) { - mouse_cb(&ridata->data.mouse); + mouse_cb(&selected_ri_dev, &ridata->data.mouse); } break; case RIM_TYPEKEYBOARD: if (kb_cb != NULL) { - kb_cb(&ridata->data.keyboard); + kb_cb(&selected_ri_dev, &ridata->data.keyboard); } break; case RIM_TYPEHID: if (hid_cb != NULL) { - hid_cb(&ridata->data.hid); + hid_cb(&selected_ri_dev, &ridata->data.hid); } break; } diff --git a/ri/ri.h b/ri/ri.h index d1e5fad..02edaec 100644 --- a/ri/ri.h +++ b/ri/ri.h @@ -1,10 +1,22 @@ #pragma once #include #include +#include -typedef void (*ri_mouse_cb_t)(PRAWMOUSE); -typedef void (*ri_kb_cb_t)(PRAWKEYBOARD); -typedef void (*ri_hid_cb_t)(PRAWHID); + +#pragma pack(push,1) +typedef struct RI_DEVICE { + HANDLE hDevice; + PHIDP_PREPARSED_DATA preparsed_data; + PHIDP_CAPS capeabilities; + wchar_t *dev_name; + wchar_t *prod_name; +} *PRI_DEVICE; +#pragma pack(pop) + +typedef void (*ri_mouse_cb_t)(PRI_DEVICE, PRAWMOUSE); +typedef void (*ri_kb_cb_t)(PRI_DEVICE, PRAWKEYBOARD); +typedef void (*ri_hid_cb_t)(PRI_DEVICE, PRAWHID); HRESULT ri_init(uint8_t dev_num, ri_mouse_cb_t in_mouse_cb, ri_kb_cb_t in_kb_cb, ri_hid_cb_t in_hid_cb); void ri_exit(); diff --git a/sivaio/config.c b/sivaio/config.c index c035ba4..7ac8a2f 100644 --- a/sivaio/config.c +++ b/sivaio/config.c @@ -15,7 +15,7 @@ void siva_io_config_load(struct siva_input_config *cfg, const wchar_t *filename) cfg->coin = GetPrivateProfileIntW(L"fastio", L"coin", VK_INSERT, filename); cfg->is_ri = GetPrivateProfileIntW(L"deck", L"input_type", 0, filename); // 0 for KB, 1 for RI - cfg->device_num = GetPrivateProfileIntW(L"deck", L"device_num", 1, filename); + cfg->device_num = GetPrivateProfileIntW(L"deck", L"device_num", UINT_MAX, filename); cfg->btn_l = GetPrivateProfileIntW(L"deck", L"left_button", 'C', filename); cfg->btn_r = GetPrivateProfileIntW(L"deck", L"right_button", 'N', filename); diff --git a/sivaio/sivaio.c b/sivaio/sivaio.c index 0dd8e62..7981330 100644 --- a/sivaio/sivaio.c +++ b/sivaio/sivaio.c @@ -18,9 +18,9 @@ static uint16_t siva_service_ct = 0; static struct siva_input_config cfg; static CRITICAL_SECTION ri_critsec; -void ri_mouse_input_cb(PRAWMOUSE mouse); -void ri_kb_input_cb(PRAWKEYBOARD kb); -void ri_hid_input_cb(PRAWHID hid); +void ri_mouse_input_cb(PRI_DEVICE dev, PRAWMOUSE mouse); +void ri_kb_input_cb(PRI_DEVICE dev, PRAWKEYBOARD kb); +void ri_hid_input_cb(PRI_DEVICE dev, PRAWHID hid); uint16_t siva_io_get_api_version(void) { @@ -29,24 +29,24 @@ uint16_t siva_io_get_api_version(void) HRESULT siva_io_init(void) { + HRESULT hr = S_OK; dprintf("Siva IO: Init\n"); siva_io_config_load(&cfg, L".\\taitools.ini"); if (cfg.is_ri) { InitializeCriticalSection(&ri_critsec); - return ri_init(cfg.device_num, ri_mouse_input_cb, ri_kb_input_cb, ri_hid_input_cb); + hr = ri_init(cfg.device_num, ri_mouse_input_cb, ri_kb_input_cb, ri_hid_input_cb); + + if (FAILED(hr) || hr == S_FALSE) { + DeleteCriticalSection(&ri_critsec); + cfg.is_ri = 0; + } } - return S_OK; + return hr; } void siva_io_get_btns(uint8_t *btn, uint8_t *stick) { - - // if (GetAsyncKeyState(VK_MENU) && GetAsyncKeyState(VK_F4)) { - // ri_exit(); - // return; - // } - if (cfg.is_ri) { } else { @@ -133,17 +133,17 @@ void siva_io_read_coin_counter(uint16_t *coins, uint16_t *services) *services = siva_service_ct; } -void ri_mouse_input_cb(PRAWMOUSE mouse) +void ri_mouse_input_cb(PRI_DEVICE dev, PRAWMOUSE mouse) { } -void ri_kb_input_cb(PRAWKEYBOARD kb) +void ri_kb_input_cb(PRI_DEVICE dev, PRAWKEYBOARD kb) { } -void ri_hid_input_cb(PRAWHID hid) +void ri_hid_input_cb(PRI_DEVICE dev, PRAWHID hid) { DWORD bfr_size = hid->dwCount * hid->dwSizeHid; dprintf("SivaIO: HID input - %d elements * %d bytes per element = %d\n", (int)hid->dwCount, (int)hid->dwSizeHid, (int)bfr_size);