Rebase against 3ba4412be60dafee310b5d3c71aa762aa8846564.

This commit is contained in:
Zebediah Figura
2021-05-03 23:39:26 -05:00
parent c814617e2c
commit 813bfa288e
13 changed files with 71 additions and 572 deletions

View File

@@ -1,4 +1,4 @@
From d394cc092108c710ad2cccbcec1919a084037910 Mon Sep 17 00:00:00 2001
From 9c6c0fb4a36ccf59313dbf0eff887c41c1749eb5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Tue, 23 Mar 2021 10:42:07 +0100
Subject: [PATCH] server: Implement WM_INPUT / RIM_TYPEHID message dispatch.
@@ -9,11 +9,11 @@ data after each RAWINPUT struct.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50506
---
dlls/user32/message.c | 1 +
dlls/user32/rawinput.c | 23 +++++++++++++++++++++--
dlls/user32/rawinput.c | 22 ++++++++++++++++++++--
server/protocol.def | 2 +-
server/queue.c | 25 ++++++++++++++++++-------
server/trace.c | 1 +
5 files changed, 42 insertions(+), 10 deletions(-)
5 files changed, 41 insertions(+), 10 deletions(-)
diff --git a/dlls/user32/message.c b/dlls/user32/message.c
index 54fcdc4588c..f986b71953a 100644
@@ -28,10 +28,10 @@ index 54fcdc4588c..f986b71953a 100644
req->input.hw.data.rawinput.type = rawinput->header.dwType;
switch (rawinput->header.dwType)
diff --git a/dlls/user32/rawinput.c b/dlls/user32/rawinput.c
index 99481ffae3d..c69393d9ed2 100644
index a43021ceac9..c40b685be50 100644
--- a/dlls/user32/rawinput.c
+++ b/dlls/user32/rawinput.c
@@ -326,6 +326,22 @@ BOOL rawinput_from_hardware_message(RAWINPUT *rawinput, const struct hardware_ms
@@ -373,6 +373,22 @@ BOOL rawinput_from_hardware_message(RAWINPUT *rawinput, const struct hardware_ms
rawinput->data.keyboard.Message = msg_data->rawinput.kbd.message;
rawinput->data.keyboard.ExtraInformation = msg_data->info;
}
@@ -54,7 +54,7 @@ index 99481ffae3d..c69393d9ed2 100644
else
{
FIXME("Unhandled rawinput type %#x.\n", msg_data->rawinput.type);
@@ -524,7 +540,7 @@ UINT WINAPI DECLSPEC_HOTPATCH GetRawInputBuffer(RAWINPUT *data, UINT *data_size,
@@ -566,7 +582,7 @@ UINT WINAPI DECLSPEC_HOTPATCH GetRawInputBuffer(RAWINPUT *data, UINT *data_size,
struct hardware_msg_data *msg_data;
struct rawinput_thread_data *thread_data;
RAWINPUT *rawinput;
@@ -63,7 +63,7 @@ index 99481ffae3d..c69393d9ed2 100644
BOOL is_wow64;
int i;
@@ -584,7 +600,9 @@ UINT WINAPI DECLSPEC_HOTPATCH GetRawInputBuffer(RAWINPUT *data, UINT *data_size,
@@ -626,7 +642,9 @@ UINT WINAPI DECLSPEC_HOTPATCH GetRawInputBuffer(RAWINPUT *data, UINT *data_size,
data->header.dwSize - sizeof(RAWINPUTHEADER));
data->header.dwSize += overhead;
data = NEXTRAWINPUTBLOCK(data);
@@ -74,19 +74,11 @@ index 99481ffae3d..c69393d9ed2 100644
}
if (count == 0 && next_size == 0) *data_size = 0;
@@ -657,6 +675,7 @@ UINT WINAPI GetRawInputDeviceInfoW(HANDLE handle, UINT command, void *data, UINT
handle, command, data, data_size);
if (!data_size) return ~0U;
+ if (!device) return ~0U;
/* each case below must set:
* *data_size: length (meaning defined by command) of data we want to copy
diff --git a/server/protocol.def b/server/protocol.def
index f97b966719c..829216b58c1 100644
index c9a0b53dfea..ce137caaea8 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -369,7 +369,7 @@ typedef union
@@ -358,7 +358,7 @@ typedef union
lparam_t lparam; /* message param */
union
{
@@ -169,10 +161,10 @@ index 248157ca7da..a411d0af8d2 100644
free_message( msg );
diff --git a/server/trace.c b/server/trace.c
index 3d24cec0133..f50a0367683 100644
index c6bdbb1139c..30aa979a20e 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -471,6 +471,7 @@ static void dump_hw_input( const char *prefix, const hw_input_t *input )
@@ -456,6 +456,7 @@ static void dump_hw_input( const char *prefix, const hw_input_t *input )
dump_uint64( ",lparam=", &input->hw.lparam );
switch (input->hw.msg)
{

View File

@@ -1,124 +0,0 @@
From 2e8dd5065ba659d6f5f5c5bedadbec4e06a98a6a Mon Sep 17 00:00:00 2001
From: Arkadiusz Hiler <ahiler@codeweavers.com>
Date: Tue, 23 Feb 2021 14:41:58 +0200
Subject: [PATCH] ntoskrnl: Implement IoSetDevicePropertyData().
---
dlls/ntoskrnl.exe/ntoskrnl.exe.spec | 1 +
dlls/ntoskrnl.exe/pnp.c | 51 +++++++++++++++++++++++++++++
include/ddk/wdm.h | 4 +++
3 files changed, 56 insertions(+)
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec
index 2e5e2e6e11b..4eb08faec2e 100644
--- a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec
+++ b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec
@@ -465,6 +465,7 @@
@ stdcall IoReuseIrp(ptr long)
@ stub IoSetCompletionRoutineEx
@ stdcall IoSetDeviceInterfaceState(ptr long)
+@ stdcall IoSetDevicePropertyData(ptr ptr long long long long ptr)
@ stub IoSetDeviceToVerify
@ stub IoSetFileOrigin
@ stub IoSetHardErrorOrVerifyDevice
diff --git a/dlls/ntoskrnl.exe/pnp.c b/dlls/ntoskrnl.exe/pnp.c
index 7994a8b85b9..0d5d0d721d4 100644
--- a/dlls/ntoskrnl.exe/pnp.c
+++ b/dlls/ntoskrnl.exe/pnp.c
@@ -38,6 +38,12 @@ DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
WINE_DEFAULT_DEBUG_CHANNEL(plugplay);
+static inline const char *debugstr_propkey( const DEVPROPKEY *id )
+{
+ if (!id) return "(null)";
+ return wine_dbg_sprintf( "{%s,%04x}", wine_dbgstr_guid( &id->fmtid ), id->pid );
+}
+
#define MAX_SERVICE_NAME 260
struct device_interface
@@ -770,6 +776,51 @@ NTSTATUS WINAPI IoSetDeviceInterfaceState( UNICODE_STRING *name, BOOLEAN enable
return ret;
}
+/***********************************************************************
+ * IoSetDevicePropertyData (NTOSKRNL.EXE.@)
+ */
+NTSTATUS WINAPI IoSetDevicePropertyData( DEVICE_OBJECT *device, const DEVPROPKEY *property_key, LCID lcid,
+ ULONG flags, DEVPROPTYPE type, ULONG size, void *data )
+{
+ SP_DEVINFO_DATA sp_device = {sizeof(sp_device)};
+ WCHAR device_instance_id[MAX_DEVICE_ID_LEN];
+ NTSTATUS status;
+ HDEVINFO set;
+
+ TRACE( "device %p, property_key %s, lcid %#x, flags %#x, type %#x, size %u, data %p.\n",
+ device, debugstr_propkey(property_key), lcid, flags, type, size, data );
+
+ /* flags is always treated as PLUGPLAY_PROPERTY_PERSISTENT starting with Win 8 / 2012 */
+
+ if (lcid != LOCALE_NEUTRAL) FIXME( "only LOCALE_NEUTRAL is supported\n" );
+
+ if ((status = get_device_instance_id( device, device_instance_id ))) return status;
+
+ if ((set = SetupDiCreateDeviceInfoList( &GUID_NULL, NULL )) == INVALID_HANDLE_VALUE)
+ {
+ ERR( "Failed to create device list, error %#x.\n", GetLastError() );
+ return GetLastError();
+ }
+
+ if (!SetupDiOpenDeviceInfoW( set, device_instance_id, NULL, 0, &sp_device ))
+ {
+ ERR( "Failed to open device, error %#x.\n", GetLastError() );
+ SetupDiDestroyDeviceInfoList( set );
+ return GetLastError();
+ }
+
+ if (!SetupDiSetDevicePropertyW( set, &sp_device, property_key, type, data, size, 0 ))
+ {
+ ERR( "Failed to set property, error %#x.\n", GetLastError() );
+ SetupDiDestroyDeviceInfoList( set );
+ return GetLastError();
+ }
+
+ SetupDiDestroyDeviceInfoList( set );
+
+ return STATUS_SUCCESS;
+}
+
/***********************************************************************
* IoRegisterDeviceInterface (NTOSKRNL.EXE.@)
*/
diff --git a/include/ddk/wdm.h b/include/ddk/wdm.h
index 3b9af7d52b2..3d0f810c2f0 100644
--- a/include/ddk/wdm.h
+++ b/include/ddk/wdm.h
@@ -21,6 +21,7 @@
#define _NTDDK_
#include <ntstatus.h>
+#include <devpropdef.h>
#ifdef _WIN64
#define POINTER_ALIGNMENT DECLSPEC_ALIGN(8)
@@ -1677,6 +1678,8 @@ void WINAPI ExReleaseResourceForThreadLite(ERESOURCE*,ERESOURCE_THREAD);
ULONG WINAPI ExSetTimerResolution(ULONG,BOOLEAN);
void WINAPI ExUnregisterCallback(void*);
+#define PLUGPLAY_PROPERTY_PERSISTENT 0x0001
+
void WINAPI IoAcquireCancelSpinLock(KIRQL*);
NTSTATUS WINAPI IoAcquireRemoveLockEx(IO_REMOVE_LOCK*,void*,const char*,ULONG, ULONG);
NTSTATUS WINAPI IoAllocateDriverObjectExtension(PDRIVER_OBJECT,PVOID,ULONG,PVOID*);
@@ -1724,6 +1727,7 @@ void WINAPI IoReleaseRemoveLockAndWaitEx(IO_REMOVE_LOCK*,void*,ULONG);
void WINAPI IoReleaseRemoveLockEx(IO_REMOVE_LOCK*,void*,ULONG);
void WINAPI IoReuseIrp(IRP*,NTSTATUS);
NTSTATUS WINAPI IoSetDeviceInterfaceState(UNICODE_STRING*,BOOLEAN);
+NTSTATUS WINAPI IoSetDevicePropertyData(DEVICE_OBJECT*,const DEVPROPKEY*,LCID,ULONG,DEVPROPTYPE,ULONG,void*);
NTSTATUS WINAPI IoWMIRegistrationControl(PDEVICE_OBJECT,ULONG);
void FASTCALL KeAcquireInStackQueuedSpinLockAtDpcLevel(KSPIN_LOCK*,KLOCK_QUEUE_HANDLE*);
--
2.30.2

View File

@@ -1,51 +0,0 @@
From cce25a3d567e6afcff3ccf97c46f08b9d2dda42f Mon Sep 17 00:00:00 2001
From: Arkadiusz Hiler <ahiler@codeweavers.com>
Date: Wed, 10 Feb 2021 13:23:33 +0100
Subject: [PATCH] hidclass.sys: Assign rawinput handles through device
properties.
---
dlls/hidclass.sys/pnp.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/dlls/hidclass.sys/pnp.c b/dlls/hidclass.sys/pnp.c
index 5e50ee90c60..15f4c12cba5 100644
--- a/dlls/hidclass.sys/pnp.c
+++ b/dlls/hidclass.sys/pnp.c
@@ -26,6 +26,8 @@
#include "ntddkbd.h"
#include "ddk/hidtypes.h"
#include "ddk/wdm.h"
+#include "initguid.h"
+#include "devpkey.h"
#include "regstr.h"
#include "winuser.h"
#include "wine/debug.h"
@@ -88,6 +90,8 @@ static NTSTATUS get_device_id(DEVICE_OBJECT *device, BUS_QUERY_ID_TYPE type, WCH
return irp_status.u.Status;
}
+DEFINE_DEVPROPKEY(DEVPROPKEY_HID_HANDLE, 0xbc62e415, 0xf4fe, 0x405c, 0x8e, 0xda, 0x63, 0x6f, 0xb5, 0x9f, 0x08, 0x98, 2);
+
/* user32 reserves 1 & 2 for winemouse and winekeyboard,
* keep this in sync with user_private.h */
#define WINE_MOUSE_HANDLE 1
@@ -248,6 +252,15 @@ static void create_child(minidriver *minidriver, DEVICE_OBJECT *fdo)
else
pdo_ext->u.pdo.rawinput_handle = alloc_rawinput_handle();
+ status = IoSetDevicePropertyData(child_pdo, &DEVPROPKEY_HID_HANDLE, LOCALE_NEUTRAL,
+ PLUGPLAY_PROPERTY_PERSISTENT, DEVPROP_TYPE_UINT32,
+ sizeof(pdo_ext->u.pdo.rawinput_handle), &pdo_ext->u.pdo.rawinput_handle);
+ if (status != STATUS_SUCCESS)
+ {
+ FIXME("failed to set device property %x\n", status);
+ return;
+ }
+
pdo_ext->u.pdo.poll_interval = DEFAULT_POLL_INTERVAL;
pdo_ext->u.pdo.ring_buffer = RingBuffer_Create(
--
2.30.2

View File

@@ -1,154 +0,0 @@
From 29aca5031e4237e55b1c3cfe591cd7f4af31fa9c Mon Sep 17 00:00:00 2001
From: Arkadiusz Hiler <ahiler@codeweavers.com>
Date: Mon, 22 Feb 2021 15:41:46 +0200
Subject: [PATCH] user32: Use device handles assigned by hidclass.sys.
This allows us to avoid racy handle mapping for messages from the WM_INPUT
family.
---
dlls/user32/rawinput.c | 61 +++++++++++++++++++++++++++++++++++-------
1 file changed, 51 insertions(+), 10 deletions(-)
diff --git a/dlls/user32/rawinput.c b/dlls/user32/rawinput.c
index 566a5844ad5..d42c2017e78 100644
--- a/dlls/user32/rawinput.c
+++ b/dlls/user32/rawinput.c
@@ -38,15 +38,19 @@
#include "user_private.h"
#include "initguid.h"
+#include "devpkey.h"
#include "ntddmou.h"
#include "ntddkbd.h"
WINE_DEFAULT_DEBUG_CHANNEL(rawinput);
+DEFINE_DEVPROPKEY(DEVPROPKEY_HID_HANDLE, 0xbc62e415, 0xf4fe, 0x405c, 0x8e, 0xda, 0x63, 0x6f, 0xb5, 0x9f, 0x08, 0x98, 2);
+
struct device
{
SP_DEVICE_INTERFACE_DETAIL_DATA_W *detail;
HANDLE file;
+ HANDLE handle;
RID_DEVICE_INFO info;
PHIDP_PREPARSED_DATA data;
};
@@ -92,10 +96,12 @@ static BOOL array_reserve(void **elements, unsigned int *capacity, unsigned int
static struct device *add_device(HDEVINFO set, SP_DEVICE_INTERFACE_DATA *iface)
{
+ SP_DEVINFO_DATA device_data = {sizeof(device_data)};
SP_DEVICE_INTERFACE_DETAIL_DATA_W *detail;
+ UINT32 handle;
struct device *device;
HANDLE file;
- DWORD size;
+ DWORD idx, size, type;
SetupDiGetDeviceInterfaceDetailW(set, iface, NULL, 0, &size, NULL);
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
@@ -109,7 +115,27 @@ static struct device *add_device(HDEVINFO set, SP_DEVICE_INTERFACE_DATA *iface)
return FALSE;
}
detail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W);
- SetupDiGetDeviceInterfaceDetailW(set, iface, detail, size, NULL, NULL);
+ SetupDiGetDeviceInterfaceDetailW(set, iface, detail, size, NULL, &device_data);
+
+ if (!SetupDiGetDevicePropertyW(set, &device_data, &DEVPROPKEY_HID_HANDLE, &type, (BYTE *)&handle, sizeof(handle), NULL, 0))
+ {
+ ERR("Failed to get handle for %s, skipping HID device.\n", debugstr_w(detail->DevicePath));
+ heap_free(detail);
+ return NULL;
+ }
+
+ if (type != DEVPROP_TYPE_UINT32)
+ ERR("Wrong prop type for HANDLE.\n");
+
+ for (idx = 0; idx < rawinput_devices_count; ++idx)
+ {
+ if (rawinput_devices[idx].handle == ULongToHandle(handle))
+ {
+ TRACE("Discarding %s as it's a duplicate of %s.\n", debugstr_w(detail->DevicePath), debugstr_w(rawinput_devices[idx].detail->DevicePath));
+ heap_free(detail);
+ return NULL;
+ }
+ }
TRACE("Found HID device %s.\n", debugstr_w(detail->DevicePath));
@@ -135,6 +161,7 @@ static struct device *add_device(HDEVINFO set, SP_DEVICE_INTERFACE_DATA *iface)
device->detail = detail;
device->file = file;
device->info.cbSize = sizeof(RID_DEVICE_INFO);
+ device->handle = ULongToHandle(handle);
device->data = NULL;
return device;
@@ -142,8 +169,6 @@ static struct device *add_device(HDEVINFO set, SP_DEVICE_INTERFACE_DATA *iface)
static void find_devices(void)
{
- static ULONGLONG last_check;
-
SP_DEVICE_INTERFACE_DATA iface = { sizeof(iface) };
struct device *device;
HIDD_ATTRIBUTES attr;
@@ -152,10 +177,6 @@ static void find_devices(void)
HDEVINFO set;
DWORD idx;
- if (GetTickCount64() - last_check < 2000)
- return;
- last_check = GetTickCount64();
-
HidD_GetHidGuid(&hid_guid);
EnterCriticalSection(&rawinput_devices_cs);
@@ -247,6 +268,26 @@ static void find_devices(void)
}
+static struct device *rawinput_device_from_handle(HANDLE handle)
+{
+ unsigned int i;
+
+ if (!handle) return NULL;
+
+ for (i = 0; i < rawinput_devices_count; ++i)
+ if (rawinput_devices[i].handle == handle)
+ return &rawinput_devices[i];
+
+ find_devices();
+
+ for (i = 0; i < rawinput_devices_count; ++i)
+ if (rawinput_devices[i].handle == handle)
+ return &rawinput_devices[i];
+
+ return NULL;
+}
+
+
struct rawinput_thread_data *rawinput_thread_data(void)
{
struct user_thread_info *thread_info = get_user_thread_info();
@@ -420,7 +461,7 @@ UINT WINAPI GetRawInputDeviceList(RAWINPUTDEVICELIST *devices, UINT *device_coun
for (i = 0; i < rawinput_devices_count; ++i)
{
- devices[2 + i].hDevice = &rawinput_devices[i];
+ devices[2 + i].hDevice = rawinput_devices[i].handle;
devices[2 + i].dwType = rawinput_devices[i].info.dwType;
}
@@ -692,7 +733,7 @@ UINT WINAPI GetRawInputDeviceInfoW(HANDLE handle, UINT command, void *data, UINT
static const RID_DEVICE_INFO_MOUSE mouse_info = {1, 5, 0, FALSE};
RID_DEVICE_INFO info;
- struct device *device = handle;
+ struct device *device = rawinput_device_from_handle(handle);
const void *to_copy;
UINT to_copy_bytes, avail_bytes;
--
2.30.2