user32: Also scan for mouse devices in GetRawInputDeviceList().
Halo: Spartan Strike attempts to discover input devices using rawinput. It expects to be able to open at least one device file with a zero access mask. It does not perform any other operations on the file. Signed-off-by: Zebediah Figura <zfigura@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
da87589ee2
commit
19c6524e48
|
@ -37,13 +37,16 @@
|
||||||
|
|
||||||
#include "user_private.h"
|
#include "user_private.h"
|
||||||
|
|
||||||
|
#include "initguid.h"
|
||||||
|
#include "ntddmou.h"
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(rawinput);
|
WINE_DEFAULT_DEBUG_CHANNEL(rawinput);
|
||||||
|
|
||||||
struct device
|
struct device
|
||||||
{
|
{
|
||||||
WCHAR *path;
|
WCHAR *path;
|
||||||
HANDLE file;
|
HANDLE file;
|
||||||
RID_DEVICE_INFO_HID info;
|
RID_DEVICE_INFO info;
|
||||||
PHIDP_PREPARSED_DATA data;
|
PHIDP_PREPARSED_DATA data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -139,6 +142,7 @@ static struct device *add_device(HDEVINFO set, SP_DEVICE_INTERFACE_DATA *iface)
|
||||||
device = &rawinput_devices[rawinput_devices_count++];
|
device = &rawinput_devices[rawinput_devices_count++];
|
||||||
device->path = path;
|
device->path = path;
|
||||||
device->file = file;
|
device->file = file;
|
||||||
|
device->info.cbSize = sizeof(RID_DEVICE_INFO);
|
||||||
|
|
||||||
return device;
|
return device;
|
||||||
}
|
}
|
||||||
|
@ -161,8 +165,6 @@ static void find_devices(void)
|
||||||
|
|
||||||
HidD_GetHidGuid(&hid_guid);
|
HidD_GetHidGuid(&hid_guid);
|
||||||
|
|
||||||
set = SetupDiGetClassDevsW(&hid_guid, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT);
|
|
||||||
|
|
||||||
EnterCriticalSection(&rawinput_devices_cs);
|
EnterCriticalSection(&rawinput_devices_cs);
|
||||||
|
|
||||||
/* destroy previous list */
|
/* destroy previous list */
|
||||||
|
@ -171,8 +173,10 @@ static void find_devices(void)
|
||||||
CloseHandle(rawinput_devices[idx].file);
|
CloseHandle(rawinput_devices[idx].file);
|
||||||
heap_free(rawinput_devices[idx].path);
|
heap_free(rawinput_devices[idx].path);
|
||||||
}
|
}
|
||||||
|
|
||||||
rawinput_devices_count = 0;
|
rawinput_devices_count = 0;
|
||||||
|
|
||||||
|
set = SetupDiGetClassDevsW(&hid_guid, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT);
|
||||||
|
|
||||||
for (idx = 0; SetupDiEnumDeviceInterfaces(set, NULL, &hid_guid, idx, &iface); ++idx)
|
for (idx = 0; SetupDiEnumDeviceInterfaces(set, NULL, &hid_guid, idx, &iface); ++idx)
|
||||||
{
|
{
|
||||||
if (!(device = add_device(set, &iface)))
|
if (!(device = add_device(set, &iface)))
|
||||||
|
@ -181,9 +185,11 @@ static void find_devices(void)
|
||||||
attr.Size = sizeof(HIDD_ATTRIBUTES);
|
attr.Size = sizeof(HIDD_ATTRIBUTES);
|
||||||
if (!HidD_GetAttributes(device->file, &attr))
|
if (!HidD_GetAttributes(device->file, &attr))
|
||||||
WARN("Failed to get attributes.\n");
|
WARN("Failed to get attributes.\n");
|
||||||
device->info.dwVendorId = attr.VendorID;
|
|
||||||
device->info.dwProductId = attr.ProductID;
|
device->info.dwType = RIM_TYPEHID;
|
||||||
device->info.dwVersionNumber = attr.VersionNumber;
|
device->info.u.hid.dwVendorId = attr.VendorID;
|
||||||
|
device->info.u.hid.dwProductId = attr.ProductID;
|
||||||
|
device->info.u.hid.dwVersionNumber = attr.VersionNumber;
|
||||||
|
|
||||||
if (!HidD_GetPreparsedData(device->file, &device->data))
|
if (!HidD_GetPreparsedData(device->file, &device->data))
|
||||||
WARN("Failed to get preparsed data.\n");
|
WARN("Failed to get preparsed data.\n");
|
||||||
|
@ -191,12 +197,28 @@ static void find_devices(void)
|
||||||
if (!HidP_GetCaps(device->data, &caps))
|
if (!HidP_GetCaps(device->data, &caps))
|
||||||
WARN("Failed to get caps.\n");
|
WARN("Failed to get caps.\n");
|
||||||
|
|
||||||
device->info.usUsagePage = caps.UsagePage;
|
device->info.u.hid.usUsagePage = caps.UsagePage;
|
||||||
device->info.usUsage = caps.Usage;
|
device->info.u.hid.usUsage = caps.Usage;
|
||||||
}
|
}
|
||||||
|
|
||||||
LeaveCriticalSection(&rawinput_devices_cs);
|
|
||||||
SetupDiDestroyDeviceInfoList(set);
|
SetupDiDestroyDeviceInfoList(set);
|
||||||
|
|
||||||
|
set = SetupDiGetClassDevsW(&GUID_DEVINTERFACE_MOUSE, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT);
|
||||||
|
|
||||||
|
for (idx = 0; SetupDiEnumDeviceInterfaces(set, NULL, &GUID_DEVINTERFACE_MOUSE, idx, &iface); ++idx)
|
||||||
|
{
|
||||||
|
static const RID_DEVICE_INFO_MOUSE mouse_info = {1, 5, 0, FALSE};
|
||||||
|
|
||||||
|
if (!(device = add_device(set, &iface)))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
device->info.dwType = RIM_TYPEMOUSE;
|
||||||
|
device->info.u.mouse = mouse_info;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetupDiDestroyDeviceInfoList(set);
|
||||||
|
|
||||||
|
LeaveCriticalSection(&rawinput_devices_cs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
@ -243,7 +265,7 @@ UINT WINAPI GetRawInputDeviceList(RAWINPUTDEVICELIST *devices, UINT *device_coun
|
||||||
for (i = 0; i < rawinput_devices_count; ++i)
|
for (i = 0; i < rawinput_devices_count; ++i)
|
||||||
{
|
{
|
||||||
devices[2 + i].hDevice = &rawinput_devices[i];
|
devices[2 + i].hDevice = &rawinput_devices[i];
|
||||||
devices[2 + i].dwType = RIM_TYPEHID;
|
devices[2 + i].dwType = rawinput_devices[i].info.dwType;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 2 + rawinput_devices_count;
|
return 2 + rawinput_devices_count;
|
||||||
|
@ -461,8 +483,7 @@ UINT WINAPI GetRawInputDeviceInfoW(HANDLE handle, UINT command, void *data, UINT
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
info.dwType = RIM_TYPEHID;
|
info = device->info;
|
||||||
info.u.hid = device->info;
|
|
||||||
}
|
}
|
||||||
to_copy_bytes = sizeof(info);
|
to_copy_bytes = sizeof(info);
|
||||||
*data_size = to_copy_bytes;
|
*data_size = to_copy_bytes;
|
||||||
|
|
|
@ -1686,7 +1686,7 @@ static void test_GetRawInputDeviceList(void)
|
||||||
* understand that; so use the \\?\ prefix instead */
|
* understand that; so use the \\?\ prefix instead */
|
||||||
name[1] = '\\';
|
name[1] = '\\';
|
||||||
file = CreateFileW(name, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
|
file = CreateFileW(name, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
|
||||||
todo_wine_if(info.dwType != RIM_TYPEHID)
|
todo_wine_if(i == 0 || i == 1)
|
||||||
ok(file != INVALID_HANDLE_VALUE, "Failed to open %s, error %u\n", wine_dbgstr_w(name), GetLastError());
|
ok(file != INVALID_HANDLE_VALUE, "Failed to open %s, error %u\n", wine_dbgstr_w(name), GetLastError());
|
||||||
|
|
||||||
sz = 0;
|
sz = 0;
|
||||||
|
@ -1716,8 +1716,7 @@ static void test_GetRawInputDeviceList(void)
|
||||||
{
|
{
|
||||||
/* succeeds on hardware, fails in some VMs */
|
/* succeeds on hardware, fails in some VMs */
|
||||||
br = HidD_GetPreparsedData(file, &preparsed);
|
br = HidD_GetPreparsedData(file, &preparsed);
|
||||||
todo_wine
|
ok(br == TRUE || broken(br == FALSE), "HidD_GetPreparsedData failed\n");
|
||||||
ok(br == TRUE || broken(br == FALSE), "HidD_GetPreparsedData failed\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (br)
|
if (br)
|
||||||
|
|
Loading…
Reference in New Issue