Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- include/winuser.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/winuser.h b/include/winuser.h index 8489d05..d09f8cd 100644 --- a/include/winuser.h +++ b/include/winuser.h @@ -486,7 +486,7 @@ typedef struct tagRAWINPUTDEVICELIST typedef struct tagRAWHID { DWORD dwSizeHid; DWORD dwCount; - BYTE bRawData; + BYTE bRawData[1]; } RAWHID, *LPRAWHID;
typedef struct tagRAWKEYBOARD {
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/user32/Makefile.in | 1 + dlls/user32/input.c | 251 ------------------------------------------ dlls/user32/rawinput.c | 282 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 283 insertions(+), 251 deletions(-) create mode 100644 dlls/user32/rawinput.c
diff --git a/dlls/user32/Makefile.in b/dlls/user32/Makefile.in index 931a715..81cde06 100644 --- a/dlls/user32/Makefile.in +++ b/dlls/user32/Makefile.in @@ -36,6 +36,7 @@ C_SRCS = \ nonclient.c \ painting.c \ property.c \ + rawinput.c \ resource.c \ scroll.c \ spy.c \ diff --git a/dlls/user32/input.c b/dlls/user32/input.c index 1925998..ab9b70f 100644 --- a/dlls/user32/input.c +++ b/dlls/user32/input.c @@ -498,257 +498,6 @@ BOOL WINAPI GetLastInputInfo(PLASTINPUTINFO plii) }
-/****************************************************************** -* GetRawInputDeviceList (USER32.@) -*/ -UINT WINAPI GetRawInputDeviceList(RAWINPUTDEVICELIST *devices, UINT *device_count, UINT size) -{ - TRACE("devices %p, device_count %p, size %u.\n", devices, device_count, size); - - if (size != sizeof(*devices)) - { - SetLastError(ERROR_INVALID_PARAMETER); - return ~0U; - } - - if (!device_count) - { - SetLastError(ERROR_NOACCESS); - return ~0U; - } - - if (!devices) - { - *device_count = 2; - return 0; - } - - if (*device_count < 2) - { - SetLastError(ERROR_INSUFFICIENT_BUFFER); - *device_count = 2; - return ~0U; - } - - devices[0].hDevice = WINE_MOUSE_HANDLE; - devices[0].dwType = RIM_TYPEMOUSE; - devices[1].hDevice = WINE_KEYBOARD_HANDLE; - devices[1].dwType = RIM_TYPEKEYBOARD; - - return 2; -} - - -/****************************************************************** -* RegisterRawInputDevices (USER32.@) -*/ -BOOL WINAPI DECLSPEC_HOTPATCH RegisterRawInputDevices(RAWINPUTDEVICE *devices, UINT device_count, UINT size) -{ - struct rawinput_device *d; - BOOL ret; - UINT i; - - TRACE("devices %p, device_count %u, size %u.\n", devices, device_count, size); - - if (size != sizeof(*devices)) - { - WARN("Invalid structure size %u.\n", size); - return FALSE; - } - - if (!(d = HeapAlloc( GetProcessHeap(), 0, device_count * sizeof(*d) ))) return FALSE; - - for (i = 0; i < device_count; ++i) - { - TRACE("device %u: page %#x, usage %#x, flags %#x, target %p.\n", - i, devices[i].usUsagePage, devices[i].usUsage, - devices[i].dwFlags, devices[i].hwndTarget); - if (devices[i].dwFlags & ~RIDEV_REMOVE) - FIXME("Unhandled flags %#x for device %u.\n", devices[i].dwFlags, i); - - d[i].usage_page = devices[i].usUsagePage; - d[i].usage = devices[i].usUsage; - d[i].flags = devices[i].dwFlags; - d[i].target = wine_server_user_handle( devices[i].hwndTarget ); - } - - SERVER_START_REQ( update_rawinput_devices ) - { - wine_server_add_data( req, d, device_count * sizeof(*d) ); - ret = !wine_server_call( req ); - } - SERVER_END_REQ; - - HeapFree( GetProcessHeap(), 0, d ); - - return ret; -} - - -/****************************************************************** -* GetRawInputData (USER32.@) -*/ -UINT WINAPI GetRawInputData(HRAWINPUT rawinput, UINT command, void *data, UINT *data_size, UINT header_size) -{ - RAWINPUT *ri = (RAWINPUT *)rawinput; - UINT s; - - TRACE("rawinput %p, command %#x, data %p, data_size %p, header_size %u.\n", - rawinput, command, data, data_size, header_size); - - if (header_size != sizeof(RAWINPUTHEADER)) - { - WARN("Invalid structure size %u.\n", header_size); - return ~0U; - } - - switch (command) - { - case RID_INPUT: - s = ri->header.dwSize; - break; - case RID_HEADER: - s = sizeof(RAWINPUTHEADER); - break; - default: - return ~0U; - } - - if (!data) - { - *data_size = s; - return 0; - } - - if (*data_size < s) return ~0U; - memcpy(data, ri, s); - return s; -} - - -/****************************************************************** -* GetRawInputBuffer (USER32.@) -*/ -UINT WINAPI DECLSPEC_HOTPATCH GetRawInputBuffer(PRAWINPUT pData, PUINT pcbSize, UINT cbSizeHeader) -{ - FIXME("(pData=%p, pcbSize=%p, cbSizeHeader=%d) stub!\n", pData, pcbSize, cbSizeHeader); - - return 0; -} - - -/****************************************************************** -* GetRawInputDeviceInfoA (USER32.@) -*/ -UINT WINAPI GetRawInputDeviceInfoA(HANDLE device, UINT command, void *data, UINT *data_size) -{ - UINT ret; - - TRACE("device %p, command %u, data %p, data_size %p.\n", device, command, data, data_size); - - ret = GetRawInputDeviceInfoW(device, command, data, data_size); - if (command == RIDI_DEVICENAME && ret && ret != ~0U) - ret = WideCharToMultiByte(CP_ACP, 0, data, -1, data, *data_size, NULL, NULL); - - return ret; -} - - -/****************************************************************** -* GetRawInputDeviceInfoW (USER32.@) -*/ -UINT WINAPI GetRawInputDeviceInfoW(HANDLE device, UINT command, void *data, UINT *data_size) -{ - /* FIXME: Most of this is made up. */ - static const WCHAR keyboard_name[] = {'\','\','?','\','W','I','N','E','_','K','E','Y','B','O','A','R','D',0}; - static const WCHAR mouse_name[] = {'\','\','?','\','W','I','N','E','_','M','O','U','S','E',0}; - static const RID_DEVICE_INFO_KEYBOARD keyboard_info = {0, 0, 1, 12, 3, 101}; - static const RID_DEVICE_INFO_MOUSE mouse_info = {1, 5, 0, FALSE}; - const WCHAR *name = NULL; - RID_DEVICE_INFO *info; - UINT s; - - TRACE("device %p, command %u, data %p, data_size %p.\n", device, command, data, data_size); - - if (!data_size || (device != WINE_MOUSE_HANDLE && device != WINE_KEYBOARD_HANDLE)) return ~0U; - - switch (command) - { - case RIDI_DEVICENAME: - if (device == WINE_MOUSE_HANDLE) - { - s = sizeof(mouse_name); - name = mouse_name; - } - else - { - s = sizeof(keyboard_name); - name = keyboard_name; - } - break; - case RIDI_DEVICEINFO: - s = sizeof(*info); - break; - default: - return ~0U; - } - - if (!data) - { - *data_size = s; - return 0; - } - - if (*data_size < s) - { - *data_size = s; - return ~0U; - } - - if (command == RIDI_DEVICENAME) - { - memcpy(data, name, s); - return s; - } - - info = data; - info->cbSize = sizeof(*info); - if (device == WINE_MOUSE_HANDLE) - { - info->dwType = RIM_TYPEMOUSE; - info->u.mouse = mouse_info; - } - else - { - info->dwType = RIM_TYPEKEYBOARD; - info->u.keyboard = keyboard_info; - } - return s; -} - - -/****************************************************************** -* GetRegisteredRawInputDevices (USER32.@) -*/ -UINT WINAPI DECLSPEC_HOTPATCH GetRegisteredRawInputDevices(PRAWINPUTDEVICE pRawInputDevices, PUINT puiNumDevices, UINT cbSize) -{ - FIXME("(pRawInputDevices=%p, puiNumDevices=%p, cbSize=%d) stub!\n", pRawInputDevices, puiNumDevices, cbSize); - - return 0; -} - - -/****************************************************************** -* DefRawInputProc (USER32.@) -*/ -LRESULT WINAPI DefRawInputProc(PRAWINPUT *paRawInput, INT nInput, UINT cbSizeHeader) -{ - FIXME("(paRawInput=%p, nInput=%d, cbSizeHeader=%d) stub!\n", *paRawInput, nInput, cbSizeHeader); - - return 0; -} - - /********************************************************************** * AttachThreadInput (USER32.@) * diff --git a/dlls/user32/rawinput.c b/dlls/user32/rawinput.c new file mode 100644 index 0000000..5ce42f6 --- /dev/null +++ b/dlls/user32/rawinput.c @@ -0,0 +1,282 @@ +/* + * Raw Input + * + * Copyright 2012 Henri Verbeet + * Copyright 2018 Zebediah Figura for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" +#include <stdarg.h> + +#define NONAMELESSUNION +#include "windef.h" +#include "winbase.h" +#include "wingdi.h" +#include "winnls.h" +#include "winuser.h" +#include "wine/debug.h" +#include "wine/server.h" + +#include "user_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(rawinput); + +/*********************************************************************** + * GetRawInputDeviceList (USER32.@) + */ +UINT WINAPI GetRawInputDeviceList(RAWINPUTDEVICELIST *devices, UINT *device_count, UINT size) +{ + TRACE("devices %p, device_count %p, size %u.\n", devices, device_count, size); + + if (size != sizeof(*devices)) + { + SetLastError(ERROR_INVALID_PARAMETER); + return ~0U; + } + + if (!device_count) + { + SetLastError(ERROR_NOACCESS); + return ~0U; + } + + if (!devices) + { + *device_count = 2; + return 0; + } + + if (*device_count < 2) + { + SetLastError(ERROR_INSUFFICIENT_BUFFER); + *device_count = 2; + return ~0U; + } + + devices[0].hDevice = WINE_MOUSE_HANDLE; + devices[0].dwType = RIM_TYPEMOUSE; + devices[1].hDevice = WINE_KEYBOARD_HANDLE; + devices[1].dwType = RIM_TYPEKEYBOARD; + + return 2; +} + +/*********************************************************************** + * RegisterRawInputDevices (USER32.@) + */ +BOOL WINAPI DECLSPEC_HOTPATCH RegisterRawInputDevices(RAWINPUTDEVICE *devices, UINT device_count, UINT size) +{ + struct rawinput_device *d; + BOOL ret; + UINT i; + + TRACE("devices %p, device_count %u, size %u.\n", devices, device_count, size); + + if (size != sizeof(*devices)) + { + WARN("Invalid structure size %u.\n", size); + return FALSE; + } + + if (!(d = HeapAlloc( GetProcessHeap(), 0, device_count * sizeof(*d) ))) return FALSE; + + for (i = 0; i < device_count; ++i) + { + TRACE("device %u: page %#x, usage %#x, flags %#x, target %p.\n", + i, devices[i].usUsagePage, devices[i].usUsage, + devices[i].dwFlags, devices[i].hwndTarget); + if (devices[i].dwFlags & ~RIDEV_REMOVE) + FIXME("Unhandled flags %#x for device %u.\n", devices[i].dwFlags, i); + + d[i].usage_page = devices[i].usUsagePage; + d[i].usage = devices[i].usUsage; + d[i].flags = devices[i].dwFlags; + d[i].target = wine_server_user_handle( devices[i].hwndTarget ); + } + + SERVER_START_REQ( update_rawinput_devices ) + { + wine_server_add_data( req, d, device_count * sizeof(*d) ); + ret = !wine_server_call( req ); + } + SERVER_END_REQ; + + HeapFree( GetProcessHeap(), 0, d ); + + return ret; +} + +/*********************************************************************** + * GetRawInputData (USER32.@) + */ +UINT WINAPI GetRawInputData(HRAWINPUT rawinput, UINT command, void *data, UINT *data_size, UINT header_size) +{ + RAWINPUT *ri = (RAWINPUT *)rawinput; + UINT s; + + TRACE("rawinput %p, command %#x, data %p, data_size %p, header_size %u.\n", + rawinput, command, data, data_size, header_size); + + if (header_size != sizeof(RAWINPUTHEADER)) + { + WARN("Invalid structure size %u.\n", header_size); + return ~0U; + } + + switch (command) + { + case RID_INPUT: + s = ri->header.dwSize; + break; + case RID_HEADER: + s = sizeof(RAWINPUTHEADER); + break; + default: + return ~0U; + } + + if (!data) + { + *data_size = s; + return 0; + } + + if (*data_size < s) return ~0U; + memcpy(data, ri, s); + return s; +} + +/*********************************************************************** + * GetRawInputBuffer (USER32.@) + */ +UINT WINAPI DECLSPEC_HOTPATCH GetRawInputBuffer(RAWINPUT *data, UINT *data_size, UINT header_size) +{ + FIXME("data %p, data_size %p, header_size %u stub!\n", data, data_size, header_size); + + return 0; +} + +/*********************************************************************** + * GetRawInputDeviceInfoA (USER32.@) + */ +UINT WINAPI GetRawInputDeviceInfoA(HANDLE device, UINT command, void *data, UINT *data_size) +{ + UINT ret; + + TRACE("device %p, command %u, data %p, data_size %p.\n", + device, command, data, data_size); + + ret = GetRawInputDeviceInfoW(device, command, data, data_size); + if (command == RIDI_DEVICENAME && ret && ret != ~0U) + ret = WideCharToMultiByte(CP_ACP, 0, data, -1, data, *data_size, NULL, NULL); + + return ret; +} + +/*********************************************************************** + * GetRawInputDeviceInfoW (USER32.@) + */ +UINT WINAPI GetRawInputDeviceInfoW(HANDLE device, UINT command, void *data, UINT *data_size) +{ + /* FIXME: Most of this is made up. */ + static const WCHAR keyboard_name[] = {'\','\','?','\','W','I','N','E','_','K','E','Y','B','O','A','R','D',0}; + static const WCHAR mouse_name[] = {'\','\','?','\','W','I','N','E','_','M','O','U','S','E',0}; + static const RID_DEVICE_INFO_KEYBOARD keyboard_info = {0, 0, 1, 12, 3, 101}; + static const RID_DEVICE_INFO_MOUSE mouse_info = {1, 5, 0, FALSE}; + const WCHAR *name = NULL; + RID_DEVICE_INFO *info; + UINT s; + + TRACE("device %p, command %u, data %p, data_size %p.\n", + device, command, data, data_size); + + if (!data_size || (device != WINE_MOUSE_HANDLE && device != WINE_KEYBOARD_HANDLE)) return ~0U; + + switch (command) + { + case RIDI_DEVICENAME: + if (device == WINE_MOUSE_HANDLE) + { + s = sizeof(mouse_name); + name = mouse_name; + } + else + { + s = sizeof(keyboard_name); + name = keyboard_name; + } + break; + case RIDI_DEVICEINFO: + s = sizeof(*info); + break; + default: + return ~0U; + } + + if (!data) + { + *data_size = s; + return 0; + } + + if (*data_size < s) + { + *data_size = s; + return ~0U; + } + + if (command == RIDI_DEVICENAME) + { + memcpy(data, name, s); + return s; + } + + info = data; + info->cbSize = sizeof(*info); + if (device == WINE_MOUSE_HANDLE) + { + info->dwType = RIM_TYPEMOUSE; + info->u.mouse = mouse_info; + } + else + { + info->dwType = RIM_TYPEKEYBOARD; + info->u.keyboard = keyboard_info; + } + return s; +} + +/*********************************************************************** + * GetRegisteredRawInputDevices (USER32.@) + */ +UINT WINAPI DECLSPEC_HOTPATCH GetRegisteredRawInputDevices(RAWINPUTDEVICE *devices, UINT *device_count, UINT size) +{ + FIXME("devices %p, device_count %p, size %u stub!\n", devices, device_count, size); + + return 0; +} + + +/*********************************************************************** + * DefRawInputProc (USER32.@) + */ +LRESULT WINAPI DefRawInputProc(RAWINPUT **data, INT data_count, UINT header_size) +{ + FIXME("data %p, data_count %d, header_size %u stub!\n", data, data_count, header_size); + + return 0; +}
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/user32/rawinput.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/user32/rawinput.c b/dlls/user32/rawinput.c index 5ce42f6..bd5fbf4 100644 --- a/dlls/user32/rawinput.c +++ b/dlls/user32/rawinput.c @@ -177,7 +177,7 @@ UINT WINAPI GetRawInputDeviceInfoA(HANDLE device, UINT command, void *data, UINT { UINT ret;
- TRACE("device %p, command %u, data %p, data_size %p.\n", + TRACE("device %p, command %#x, data %p, data_size %p.\n", device, command, data, data_size);
ret = GetRawInputDeviceInfoW(device, command, data, data_size); @@ -201,7 +201,7 @@ UINT WINAPI GetRawInputDeviceInfoW(HANDLE device, UINT command, void *data, UINT RID_DEVICE_INFO *info; UINT s;
- TRACE("device %p, command %u, data %p, data_size %p.\n", + TRACE("device %p, command %#x, data %p, data_size %p.\n", device, command, data, data_size);
if (!data_size || (device != WINE_MOUSE_HANDLE && device != WINE_KEYBOARD_HANDLE)) return ~0U;
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/user32/Makefile.in | 2 +- dlls/user32/rawinput.c | 138 +++++++++++++++++++++++++++++++++++++++++++-- dlls/user32/user_private.h | 12 ++++ 3 files changed, 147 insertions(+), 5 deletions(-)
diff --git a/dlls/user32/Makefile.in b/dlls/user32/Makefile.in index 81cde06..d420dcb 100644 --- a/dlls/user32/Makefile.in +++ b/dlls/user32/Makefile.in @@ -3,7 +3,7 @@ MODULE = user32.dll IMPORTLIB = user32 IMPORTS = gdi32 version advapi32 EXTRAINCL = $(PNG_CFLAGS) -DELAYIMPORTS = imm32 usp10 +DELAYIMPORTS = hid imm32 setupapi usp10
C_SRCS = \ button.c \ diff --git a/dlls/user32/rawinput.c b/dlls/user32/rawinput.c index bd5fbf4..91dcff4 100644 --- a/dlls/user32/rawinput.c +++ b/dlls/user32/rawinput.c @@ -27,7 +27,10 @@ #include "winbase.h" #include "wingdi.h" #include "winnls.h" +#include "winreg.h" #include "winuser.h" +#include "setupapi.h" +#include "ddk/hidsdi.h" #include "wine/debug.h" #include "wine/server.h"
@@ -35,11 +38,130 @@
WINE_DEFAULT_DEBUG_CHANNEL(rawinput);
+struct hid_device +{ + WCHAR *path; + HANDLE file; +}; + +static struct hid_device *hid_devices; +static unsigned int hid_devices_count, hid_devices_max; + +static CRITICAL_SECTION hid_devices_cs; +static CRITICAL_SECTION_DEBUG hid_devices_cs_debug = +{ + 0, 0, &hid_devices_cs, + { &hid_devices_cs_debug.ProcessLocksList, &hid_devices_cs_debug.ProcessLocksList }, + 0, 0, { (DWORD_PTR)(__FILE__ ": hid_devices_cs") } +}; +static CRITICAL_SECTION hid_devices_cs = { &hid_devices_cs_debug, -1, 0, 0, 0, 0 }; + +static void find_hid_devices(void) +{ + static ULONGLONG last_check; + + SP_DEVICE_INTERFACE_DATA iface = { sizeof(iface) }; + SP_DEVICE_INTERFACE_DETAIL_DATA_W *detail; + DWORD detail_size, needed; + DWORD idx, didx; + GUID hid_guid; + HDEVINFO set; + HANDLE file; + WCHAR *path; + + if (GetTickCount64() - last_check < 2000) + return; + last_check = GetTickCount64(); + + HidD_GetHidGuid(&hid_guid); + + set = SetupDiGetClassDevsW(&hid_guid, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT); + + detail_size = sizeof(*detail) + (MAX_PATH * sizeof(WCHAR)); + if (!(detail = heap_alloc(detail_size))) + return; + detail->cbSize = sizeof(*detail); + + EnterCriticalSection(&hid_devices_cs); + + /* destroy previous list */ + for (didx = 0; didx < hid_devices_count; ++didx) + { + CloseHandle(hid_devices[didx].file); + heap_free(hid_devices[didx].path); + } + + didx = 0; + for (idx = 0; SetupDiEnumDeviceInterfaces(set, NULL, &hid_guid, idx, &iface); ++idx) + { + if (!SetupDiGetDeviceInterfaceDetailW(set, &iface, detail, detail_size, &needed, NULL)) + { + if (!(detail = heap_realloc(detail, needed))) + { + ERR("Failed to allocate memory.\n"); + goto done; + } + detail_size = needed; + + SetupDiGetDeviceInterfaceDetailW(set, &iface, detail, detail_size, NULL, NULL); + } + + if (!(path = heap_strdupW(detail->DevicePath))) + { + ERR("Failed to allocate memory.\n"); + goto done; + } + + file = CreateFileW(path, GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0); + if (file == INVALID_HANDLE_VALUE) + { + ERR("Failed to open device file %s, error %u.\n", debugstr_w(path), GetLastError()); + heap_free(path); + continue; + } + + if (didx >= hid_devices_max) + { + if (hid_devices) + { + hid_devices_max *= 2; + hid_devices = heap_realloc(hid_devices, + hid_devices_max * sizeof(hid_devices[0])); + } + else + { + hid_devices_max = 8; + hid_devices = heap_alloc(hid_devices_max * sizeof(hid_devices[0])); + } + if (!hid_devices) + { + ERR("Failed to allocate memory.\n"); + goto done; + } + } + + TRACE("Found HID device %s.\n", debugstr_w(path)); + + hid_devices[didx].path = path; + hid_devices[didx].file = file; + + didx++; + } + hid_devices_count = didx; + +done: + LeaveCriticalSection(&hid_devices_cs); + heap_free(detail); +} + /*********************************************************************** * GetRawInputDeviceList (USER32.@) */ UINT WINAPI GetRawInputDeviceList(RAWINPUTDEVICELIST *devices, UINT *device_count, UINT size) { + UINT i; + TRACE("devices %p, device_count %p, size %u.\n", devices, device_count, size);
if (size != sizeof(*devices)) @@ -54,16 +176,18 @@ UINT WINAPI GetRawInputDeviceList(RAWINPUTDEVICELIST *devices, UINT *device_coun return ~0U; }
+ find_hid_devices(); + if (!devices) { - *device_count = 2; + *device_count = 2 + hid_devices_count; return 0; }
- if (*device_count < 2) + if (*device_count < 2 + hid_devices_count) { SetLastError(ERROR_INSUFFICIENT_BUFFER); - *device_count = 2; + *device_count = 2 + hid_devices_count; return ~0U; }
@@ -72,7 +196,13 @@ UINT WINAPI GetRawInputDeviceList(RAWINPUTDEVICELIST *devices, UINT *device_coun devices[1].hDevice = WINE_KEYBOARD_HANDLE; devices[1].dwType = RIM_TYPEKEYBOARD;
- return 2; + for (i = 0; i < hid_devices_count; ++i) + { + devices[2 + i].hDevice = &hid_devices[i]; + devices[2 + i].dwType = RIM_TYPEHID; + } + + return 2 + hid_devices_count; }
/*********************************************************************** diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h index 7a70ae9..73a2bad 100644 --- a/dlls/user32/user_private.h +++ b/dlls/user32/user_private.h @@ -28,6 +28,8 @@ #include "winuser.h" #include "winreg.h" #include "winternl.h" +#include "wine/heap.h" +#include "wine/unicode.h"
#define GET_WORD(ptr) (*(const WORD *)(ptr)) #define GET_DWORD(ptr) (*(const DWORD *)(ptr)) @@ -354,4 +356,14 @@ extern BOOL get_icon_size( HICON handle, SIZE *size ) DECLSPEC_HIDDEN; #define assert(expr) ((void)0) #endif
+static inline WCHAR *heap_strdupW(const WCHAR *src) +{ + WCHAR *dst; + unsigned len; + if (!src) return NULL; + len = (strlenW(src) + 1) * sizeof(WCHAR); + if ((dst = heap_alloc(len))) memcpy(dst, src, len); + return dst; +} + #endif /* __WINE_USER_PRIVATE_H */
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/user32/rawinput.c | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-)
diff --git a/dlls/user32/rawinput.c b/dlls/user32/rawinput.c index 91dcff4..12a0e15 100644 --- a/dlls/user32/rawinput.c +++ b/dlls/user32/rawinput.c @@ -42,6 +42,8 @@ struct hid_device { WCHAR *path; HANDLE file; + RID_DEVICE_INFO_HID info; + PHIDP_PREPARSED_DATA data; };
static struct hid_device *hid_devices; @@ -63,7 +65,9 @@ static void find_hid_devices(void) SP_DEVICE_INTERFACE_DATA iface = { sizeof(iface) }; SP_DEVICE_INTERFACE_DETAIL_DATA_W *detail; DWORD detail_size, needed; + HIDD_ATTRIBUTES attr; DWORD idx, didx; + HIDP_CAPS caps; GUID hid_guid; HDEVINFO set; HANDLE file; @@ -146,6 +150,22 @@ static void find_hid_devices(void) hid_devices[didx].path = path; hid_devices[didx].file = file;
+ attr.Size = sizeof(HIDD_ATTRIBUTES); + if (!HidD_GetAttributes(file, &attr)) + WARN_(rawinput)("Failed to get attributes.\n"); + hid_devices[didx].info.dwVendorId = attr.VendorID; + hid_devices[didx].info.dwProductId = attr.ProductID; + hid_devices[didx].info.dwVersionNumber = attr.VersionNumber; + + if (!HidD_GetPreparsedData(file, &hid_devices[didx].data)) + WARN_(rawinput)("Failed to get preparsed data.\n"); + + if (!HidP_GetCaps(hid_devices[didx].data, &caps)) + WARN_(rawinput)("Failed to get caps.\n"); + + hid_devices[didx].info.usUsagePage = caps.UsagePage; + hid_devices[didx].info.usUsage = caps.Usage; + didx++; } hid_devices_count = didx; @@ -327,6 +347,7 @@ UINT WINAPI GetRawInputDeviceInfoW(HANDLE device, UINT command, void *data, UINT static const WCHAR mouse_name[] = {'\','\','?','\','W','I','N','E','_','M','O','U','S','E',0}; static const RID_DEVICE_INFO_KEYBOARD keyboard_info = {0, 0, 1, 12, 3, 101}; static const RID_DEVICE_INFO_MOUSE mouse_info = {1, 5, 0, FALSE}; + struct hid_device *hid_device; const WCHAR *name = NULL; RID_DEVICE_INFO *info; UINT s; @@ -334,7 +355,7 @@ UINT WINAPI GetRawInputDeviceInfoW(HANDLE device, UINT command, void *data, UINT TRACE("device %p, command %#x, data %p, data_size %p.\n", device, command, data, data_size);
- if (!data_size || (device != WINE_MOUSE_HANDLE && device != WINE_KEYBOARD_HANDLE)) return ~0U; + if (!data_size) return ~0U;
switch (command) { @@ -382,11 +403,17 @@ UINT WINAPI GetRawInputDeviceInfoW(HANDLE device, UINT command, void *data, UINT info->dwType = RIM_TYPEMOUSE; info->u.mouse = mouse_info; } - else + else if (device == WINE_KEYBOARD_HANDLE) { info->dwType = RIM_TYPEKEYBOARD; info->u.keyboard = keyboard_info; } + else + { + hid_device = device; + info->dwType = RIM_TYPEHID; + info->u.hid = hid_device->info; + } return s; }
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/user32/rawinput.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/dlls/user32/rawinput.c b/dlls/user32/rawinput.c index 12a0e15..cf3028a 100644 --- a/dlls/user32/rawinput.c +++ b/dlls/user32/rawinput.c @@ -365,11 +365,17 @@ UINT WINAPI GetRawInputDeviceInfoW(HANDLE device, UINT command, void *data, UINT s = sizeof(mouse_name); name = mouse_name; } - else + else if (device == WINE_KEYBOARD_HANDLE) { s = sizeof(keyboard_name); name = keyboard_name; } + else + { + hid_device = device; + s = (strlenW(hid_device->path) + 1) * sizeof(WCHAR); + name = hid_device->path; + } break; case RIDI_DEVICEINFO: s = sizeof(*info);