From 8f7a0c92c370cb4bf1ee6e6d7c51a3d90fe4cd48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Bernon?= Date: Wed, 18 Sep 2019 21:04:25 +0200 Subject: [PATCH] hidclass.sys: Send input message to server when HID report is received. --- dlls/hidclass.sys/device.c | 30 ++++++++++++++++++++++++++++++ dlls/hidclass.sys/hid.h | 1 + dlls/hidclass.sys/pnp.c | 16 ++++++++++++++++ 3 files changed, 47 insertions(+) diff --git a/dlls/hidclass.sys/device.c b/dlls/hidclass.sys/device.c index 0e905c8322f..369d847e3c1 100644 --- a/dlls/hidclass.sys/device.c +++ b/dlls/hidclass.sys/device.c @@ -26,9 +26,11 @@ #include "winuser.h" #include "setupapi.h" +#include "wine/server.h" #include "wine/debug.h" #include "ddk/hidsdi.h" #include "ddk/hidtypes.h" +#include "ddk/ntifs.h" #include "ddk/wdm.h" #include "initguid.h" @@ -123,6 +125,8 @@ NTSTATUS HID_LinkDevice(DEVICE_OBJECT *device) return status; } + ext->link_handle = INVALID_HANDLE_VALUE; + /* FIXME: This should probably be done in mouhid.sys. */ if (ext->preparseData->caps.UsagePage == HID_USAGE_PAGE_GENERIC && ext->preparseData->caps.Usage == HID_USAGE_GENERIC_MOUSE) @@ -207,6 +211,8 @@ void HID_DeleteDevice(DEVICE_OBJECT *device) IoCompleteRequest(irp, IO_NO_INCREMENT); } + CloseHandle(ext->link_handle); + TRACE("Delete device(%p) %s\n", device, debugstr_w(ext->device_name)); HeapFree(GetProcessHeap(), 0, ext->device_name); RtlFreeUnicodeString(&ext->link_name); @@ -241,6 +247,28 @@ static NTSTATUS copy_packet_into_buffer(HID_XFER_PACKET *packet, BYTE* buffer, U return STATUS_BUFFER_OVERFLOW; } +static void HID_Device_sendRawInput(DEVICE_OBJECT *device, HID_XFER_PACKET *packet) +{ + BASE_DEVICE_EXTENSION *ext = device->DeviceExtension; + + if (ext->link_handle == INVALID_HANDLE_VALUE) + return; + + SERVER_START_REQ(send_hardware_message) + { + req->win = 0; + req->flags = SEND_HWMSG_RAWINPUT; + req->input.type = HW_INPUT_HID; + req->input.hid.device = wine_server_obj_handle(ext->link_handle); + req->input.hid.usage_page = ext->preparseData->caps.UsagePage; + req->input.hid.usage = ext->preparseData->caps.Usage; + req->input.hid.length = packet->reportBufferLen; + wine_server_add_data(req, packet->reportBuffer, packet->reportBufferLen); + wine_server_call(req); + } + SERVER_END_REQ; +} + static void HID_Device_processQueue(DEVICE_OBJECT *device) { IRP *irp; @@ -324,6 +352,7 @@ static DWORD CALLBACK hid_device_thread(void *args) if (irp->IoStatus.u.Status == STATUS_SUCCESS) { RingBuffer_Write(ext->ring_buffer, packet); + HID_Device_sendRawInput(device, packet); HID_Device_processQueue(device); } @@ -370,6 +399,7 @@ static DWORD CALLBACK hid_device_thread(void *args) else packet->reportId = 0; RingBuffer_Write(ext->ring_buffer, packet); + HID_Device_sendRawInput(device, packet); HID_Device_processQueue(device); } diff --git a/dlls/hidclass.sys/hid.h b/dlls/hidclass.sys/hid.h index 36d13c009d7..f12e04d7898 100644 --- a/dlls/hidclass.sys/hid.h +++ b/dlls/hidclass.sys/hid.h @@ -46,6 +46,7 @@ typedef struct _BASE_DEVICE_EXTENSION { ULONG poll_interval; WCHAR *device_name; UNICODE_STRING link_name; + HANDLE link_handle; WCHAR device_id[MAX_DEVICE_ID_LEN]; WCHAR instance_id[MAX_DEVICE_ID_LEN]; struct ReportRingBuffer *ring_buffer; diff --git a/dlls/hidclass.sys/pnp.c b/dlls/hidclass.sys/pnp.c index 1c130e8dd80..b84a358dba4 100644 --- a/dlls/hidclass.sys/pnp.c +++ b/dlls/hidclass.sys/pnp.c @@ -299,12 +299,28 @@ NTSTATUS WINAPI HID_PNP_Dispatch(DEVICE_OBJECT *device, IRP *irp) case IRP_MN_START_DEVICE: { BASE_DEVICE_EXTENSION *ext = device->DeviceExtension; + OBJECT_ATTRIBUTES attr; rc = minidriver->PNPDispatch(device, irp); IoSetDeviceInterfaceState(&ext->link_name, TRUE); if (ext->is_mouse) IoSetDeviceInterfaceState(&ext->mouse_link_name, TRUE); + + attr.Length = sizeof(attr); + attr.RootDirectory = 0; + attr.Attributes = OBJ_CASE_INSENSITIVE; + attr.ObjectName = &ext->link_name; + attr.SecurityDescriptor = NULL; + attr.SecurityQualityOfService = NULL; + NtOpenSymbolicLinkObject(&ext->link_handle, SYMBOLIC_LINK_QUERY, &attr); + ext->link_handle = ConvertToGlobalHandle(ext->link_handle); + + if (ext->link_handle == INVALID_HANDLE_VALUE) + ERR("Failed to open link %s, error %u.\n", debugstr_w(ext->link_name.Buffer), GetLastError()); + else + TRACE("Opened link handle: %p for %s\n", ext->link_handle, debugstr_w(ext->link_name.Buffer)); + return rc; } case IRP_MN_REMOVE_DEVICE: -- 2.27.0