user32: Return HID devices in GetRawInputDeviceList().
Signed-off-by: Zebediah Figura <zfigura@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
9e4e594972
commit
85d5fc23b4
|
@ -3,7 +3,7 @@ MODULE = user32.dll
|
||||||
IMPORTLIB = user32
|
IMPORTLIB = user32
|
||||||
IMPORTS = gdi32 version advapi32
|
IMPORTS = gdi32 version advapi32
|
||||||
EXTRAINCL = $(PNG_CFLAGS)
|
EXTRAINCL = $(PNG_CFLAGS)
|
||||||
DELAYIMPORTS = imm32 usp10
|
DELAYIMPORTS = hid imm32 setupapi usp10
|
||||||
|
|
||||||
C_SRCS = \
|
C_SRCS = \
|
||||||
button.c \
|
button.c \
|
||||||
|
|
|
@ -27,7 +27,10 @@
|
||||||
#include "winbase.h"
|
#include "winbase.h"
|
||||||
#include "wingdi.h"
|
#include "wingdi.h"
|
||||||
#include "winnls.h"
|
#include "winnls.h"
|
||||||
|
#include "winreg.h"
|
||||||
#include "winuser.h"
|
#include "winuser.h"
|
||||||
|
#include "setupapi.h"
|
||||||
|
#include "ddk/hidsdi.h"
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
#include "wine/server.h"
|
#include "wine/server.h"
|
||||||
|
|
||||||
|
@ -35,11 +38,130 @@
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(rawinput);
|
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.@)
|
* GetRawInputDeviceList (USER32.@)
|
||||||
*/
|
*/
|
||||||
UINT WINAPI GetRawInputDeviceList(RAWINPUTDEVICELIST *devices, UINT *device_count, UINT size)
|
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);
|
TRACE("devices %p, device_count %p, size %u.\n", devices, device_count, size);
|
||||||
|
|
||||||
if (size != sizeof(*devices))
|
if (size != sizeof(*devices))
|
||||||
|
@ -54,16 +176,18 @@ UINT WINAPI GetRawInputDeviceList(RAWINPUTDEVICELIST *devices, UINT *device_coun
|
||||||
return ~0U;
|
return ~0U;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
find_hid_devices();
|
||||||
|
|
||||||
if (!devices)
|
if (!devices)
|
||||||
{
|
{
|
||||||
*device_count = 2;
|
*device_count = 2 + hid_devices_count;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*device_count < 2)
|
if (*device_count < 2 + hid_devices_count)
|
||||||
{
|
{
|
||||||
SetLastError(ERROR_INSUFFICIENT_BUFFER);
|
SetLastError(ERROR_INSUFFICIENT_BUFFER);
|
||||||
*device_count = 2;
|
*device_count = 2 + hid_devices_count;
|
||||||
return ~0U;
|
return ~0U;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,7 +196,13 @@ UINT WINAPI GetRawInputDeviceList(RAWINPUTDEVICELIST *devices, UINT *device_coun
|
||||||
devices[1].hDevice = WINE_KEYBOARD_HANDLE;
|
devices[1].hDevice = WINE_KEYBOARD_HANDLE;
|
||||||
devices[1].dwType = RIM_TYPEKEYBOARD;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
|
|
@ -28,6 +28,8 @@
|
||||||
#include "winuser.h"
|
#include "winuser.h"
|
||||||
#include "winreg.h"
|
#include "winreg.h"
|
||||||
#include "winternl.h"
|
#include "winternl.h"
|
||||||
|
#include "wine/heap.h"
|
||||||
|
#include "wine/unicode.h"
|
||||||
|
|
||||||
#define GET_WORD(ptr) (*(const WORD *)(ptr))
|
#define GET_WORD(ptr) (*(const WORD *)(ptr))
|
||||||
#define GET_DWORD(ptr) (*(const DWORD *)(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)
|
#define assert(expr) ((void)0)
|
||||||
#endif
|
#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 */
|
#endif /* __WINE_USER_PRIVATE_H */
|
||||||
|
|
Loading…
Reference in New Issue