Rémi Bernon : hidclass.sys: Use __wine_send_input to send device notifications.

Alexandre Julliard julliard at winehq.org
Mon May 10 15:44:06 CDT 2021


Module: wine
Branch: master
Commit: c0fc89991b641d9927af3c0cc29ce16ee8ad1b4a
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=c0fc89991b641d9927af3c0cc29ce16ee8ad1b4a

Author: Rémi Bernon <rbernon at codeweavers.com>
Date:   Thu May  6 12:57:30 2021 +0200

hidclass.sys: Use __wine_send_input to send device notifications.

When INPUT type is INPUT_HARDWARE and hi.uMsg is WM_INPUT_DEVICE_CHANGE,
the RAWINPUT structure usage is a non-standard extension for Wine
internal usage:

* header.wParam contains the message GIDC_ARRIVAL / GIDC_REMOVAL wparam,

* hid.bRawData contains two words, which are the HID device UsagePage
  and Usage words, instead of a real HID report.

This will let us use the same entry point and structures to send device
notifications as for the HID reports in the future (which will be sent
with INPUT_HARDWARE type / WM_INPUT uMsg instead).

This currently does nothing, because the INPUT_HARDWARE messages are
currently dropped, and because winedevice.exe desktop is different from
the default desktop.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50506
Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/hidclass.sys/Makefile.in |  2 +-
 dlls/hidclass.sys/pnp.c       | 29 +++++++++++++++++++++++++++++
 2 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/dlls/hidclass.sys/Makefile.in b/dlls/hidclass.sys/Makefile.in
index 4b1e9338eb4..09281c118b4 100644
--- a/dlls/hidclass.sys/Makefile.in
+++ b/dlls/hidclass.sys/Makefile.in
@@ -1,6 +1,6 @@
 MODULE    = hidclass.sys
 IMPORTLIB = hidclass
-IMPORTS   = hal ntoskrnl
+IMPORTS   = hal ntoskrnl user32
 
 EXTRADLLFLAGS = -mno-cygwin
 
diff --git a/dlls/hidclass.sys/pnp.c b/dlls/hidclass.sys/pnp.c
index 4490f1eba23..b5862a01593 100644
--- a/dlls/hidclass.sys/pnp.c
+++ b/dlls/hidclass.sys/pnp.c
@@ -30,6 +30,7 @@
 #include "ddk/hidtypes.h"
 #include "ddk/wdm.h"
 #include "regstr.h"
+#include "winuser.h"
 #include "wine/debug.h"
 #include "wine/asm.h"
 #include "wine/list.h"
@@ -103,6 +104,30 @@ static UINT32 alloc_rawinput_handle(void)
     return InterlockedIncrement(&counter);
 }
 
+/* make sure bRawData can hold UsagePage and Usage without requiring additional allocation */
+C_ASSERT(offsetof(RAWINPUT, data.hid.bRawData[2 * sizeof(USAGE)]) < sizeof(RAWINPUT));
+
+static void send_wm_input_device_change(BASE_DEVICE_EXTENSION *ext, LPARAM param)
+{
+    RAWINPUT rawinput;
+    INPUT input;
+
+    rawinput.header.dwType = RIM_TYPEHID;
+    rawinput.header.dwSize = offsetof(RAWINPUT, data.hid.bRawData[2 * sizeof(USAGE)]);
+    rawinput.header.hDevice = ULongToHandle(ext->u.pdo.rawinput_handle);
+    rawinput.header.wParam = param;
+    rawinput.data.hid.dwCount = 0;
+    rawinput.data.hid.dwSizeHid = 0;
+    ((USAGE *)rawinput.data.hid.bRawData)[0] = ext->u.pdo.preparsed_data->caps.UsagePage;
+    ((USAGE *)rawinput.data.hid.bRawData)[1] = ext->u.pdo.preparsed_data->caps.Usage;
+
+    input.type = INPUT_HARDWARE;
+    input.u.hi.uMsg = WM_INPUT_DEVICE_CHANGE;
+    input.u.hi.wParamH = 0;
+    input.u.hi.wParamL = 0;
+    __wine_send_input(0, &input, &rawinput);
+}
+
 static NTSTATUS WINAPI driver_add_device(DRIVER_OBJECT *driver, DEVICE_OBJECT *bus_pdo)
 {
     WCHAR device_id[MAX_DEVICE_ID_LEN], instance_id[MAX_DEVICE_ID_LEN];
@@ -262,6 +287,8 @@ static void create_child(minidriver *minidriver, DEVICE_OBJECT *fdo)
             sizeof(HID_XFER_PACKET) + pdo_ext->u.pdo.preparsed_data->caps.InputReportByteLength);
 
     HID_StartDeviceThread(child_pdo);
+
+    send_wm_input_device_change(pdo_ext, GIDC_ARRIVAL);
 }
 
 static NTSTATUS fdo_pnp(DEVICE_OBJECT *device, IRP *irp)
@@ -433,6 +460,8 @@ static NTSTATUS pdo_pnp(DEVICE_OBJECT *device, IRP *irp)
         {
             IRP *queued_irp;
 
+            send_wm_input_device_change(ext, GIDC_REMOVAL);
+
             IoSetDeviceInterfaceState(&ext->u.pdo.link_name, FALSE);
             if (ext->u.pdo.is_mouse)
                 IoSetDeviceInterfaceState(&ext->u.pdo.mouse_link_name, FALSE);




More information about the wine-cvs mailing list