[PATCH v2 5/5] hidclass.sys: Use __wine_send_input to send device notifications.
Rémi Bernon
rbernon at codeweavers.com
Wed Apr 14 04:08:56 CDT 2021
On 4/9/21 1:11 PM, Rémi Bernon wrote:
> This currently does nothing, because winedevice.exe isn't associated
> with any desktop, and the INPUT_HARDWARE messages are dropped.
>
> In this specific case, 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 bytes, which are the HID device UsagePage
> and Usage bytes, 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).
>
> Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50506
> Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
> ---
> dlls/hidclass.sys/Makefile.in | 2 +-
> dlls/hidclass.sys/pnp.c | 36 +++++++++++++++++++++++++++++++++++
> 2 files changed, 37 insertions(+), 1 deletion(-)
>
> diff --git a/dlls/hidclass.sys/Makefile.in b/dlls/hidclass.sys/Makefile.in
> index be4af747853..2f9f30f8bef 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
> DELAYIMPORTS = setupapi hid
>
> EXTRADLLFLAGS = -mno-cygwin
> diff --git a/dlls/hidclass.sys/pnp.c b/dlls/hidclass.sys/pnp.c
> index a499aec93bb..8e539dfe6b7 100644
> --- a/dlls/hidclass.sys/pnp.c
> +++ b/dlls/hidclass.sys/pnp.c
> @@ -25,6 +25,7 @@
> #include "ddk/hidtypes.h"
> #include "ddk/wdm.h"
> #include "regstr.h"
> +#include "winuser.h"
> #include "wine/debug.h"
> #include "wine/list.h"
>
> @@ -69,6 +70,9 @@ static NTSTATUS get_device_id(DEVICE_OBJECT *device, BUS_QUERY_ID_TYPE type, WCH
> return status;
> }
>
> +/* make sure bRawData can hold two bytes without requiring additional allocation */
> +C_ASSERT(offsetof(RAWINPUT, data.hid.bRawData[2]) < sizeof(RAWINPUT));
> +
> NTSTATUS WINAPI PNP_AddDevice(DRIVER_OBJECT *driver, DEVICE_OBJECT *PDO)
> {
> WCHAR device_id[MAX_DEVICE_ID_LEN], instance_id[MAX_DEVICE_ID_LEN];
> @@ -79,6 +83,8 @@ NTSTATUS WINAPI PNP_AddDevice(DRIVER_OBJECT *driver, DEVICE_OBJECT *PDO)
> BASE_DEVICE_EXTENSION *ext = NULL;
> HID_DESCRIPTOR descriptor;
> BYTE *reportDescriptor;
> + RAWINPUT rawinput;
> + INPUT input;
> INT i;
>
> if ((status = get_device_id(PDO, BusQueryDeviceID, device_id)))
> @@ -187,6 +193,21 @@ NTSTATUS WINAPI PNP_AddDevice(DRIVER_OBJECT *driver, DEVICE_OBJECT *PDO)
>
> HID_StartDeviceThread(device);
>
> + rawinput.header.dwType = RIM_TYPEHID;
> + rawinput.header.dwSize = offsetof(RAWINPUT, data.hid.bRawData[2]);
> + rawinput.header.hDevice = ULongToHandle(ext->rawinput_handle);
> + rawinput.header.wParam = GIDC_ARRIVAL;
> + rawinput.data.hid.dwCount = 1;
> + rawinput.data.hid.dwSizeHid = 2;
> + rawinput.data.hid.bRawData[0] = ext->preparseData->caps.UsagePage;
> + rawinput.data.hid.bRawData[1] = ext->preparseData->caps.Usage;
> +
> + input.type = INPUT_HARDWARE;
> + input.u.hi.uMsg = WM_INPUT_DEVICE_CHANGE;
> + input.u.hi.wParamH = (WORD)(rawinput.header.dwSize >> 16);
> + input.u.hi.wParamL = (WORD)(rawinput.header.dwSize >> 0);
> + __wine_send_input(0, &input, &rawinput);
> +
> return STATUS_SUCCESS;
> }
>
> @@ -194,6 +215,21 @@ static NTSTATUS remove_device(minidriver *minidriver, DEVICE_OBJECT *device, IRP
> {
> BASE_DEVICE_EXTENSION *ext = device->DeviceExtension;
> NTSTATUS rc = STATUS_NOT_SUPPORTED;
> + RAWINPUT rawinput;
> + INPUT input;
> +
> + rawinput.header.dwType = RIM_TYPEHID;
> + rawinput.header.dwSize = offsetof(RAWINPUT, data.hid.bRawData[0]);
> + rawinput.header.hDevice = ULongToHandle(ext->rawinput_handle);
> + rawinput.header.wParam = GIDC_REMOVAL;
> + rawinput.data.hid.dwCount = 0;
> + rawinput.data.hid.dwSizeHid = 0;
> +
> + input.type = INPUT_HARDWARE;
> + input.u.hi.uMsg = WM_INPUT_DEVICE_CHANGE;
> + input.u.hi.wParamH = (WORD)(rawinput.header.dwSize >> 16);
> + input.u.hi.wParamL = (WORD)(rawinput.header.dwSize >> 0);
> + __wine_send_input(0, &input, &rawinput);
>
> rc = IoSetDeviceInterfaceState(&ext->link_name, FALSE);
> if (rc)
>
This last patch is wrong in the sense that UsagePage and Usage are
actually words.
However, if the first patches are fine I would rather avoid re-sending
the whole thing as PATCH 3 causes a very long Wine rebuild. Or is there
anything else to change there too?
--
Rémi Bernon <rbernon at codeweavers.com>
More information about the wine-devel
mailing list