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);