From: Aric Stewart Subject: [PATCH v3 08/20] winehid.sys: add linux hidraw minidriver Message-Id: Date: Fri, 2 Sep 2016 07:16:59 -0500 Signed-off-by: Aric Stewart --- configure | 1 + configure.ac | 1 + dlls/winehid.sys/Makefile.in | 4 +- dlls/winehid.sys/hid.h | 22 +++++++ dlls/winehid.sys/main.c | 12 +++- dlls/winehid.sys/minidriver_hidraw.c | 124 +++++++++++++++++++++++++++++++++++ include/config.h.in | 3 + loader/wine.inf.in | 6 ++ 8 files changed, 171 insertions(+), 2 deletions(-) create mode 100644 dlls/winehid.sys/hid.h create mode 100644 dlls/winehid.sys/minidriver_hidraw.c diff --git a/configure b/configure index 3904a8b..888b5df 100755 --- a/configure +++ b/configure @@ -6768,6 +6768,7 @@ for ac_header in \ linux/compiler.h \ linux/filter.h \ linux/hdreg.h \ + linux/hidraw.h \ linux/input.h \ linux/ioctl.h \ linux/joystick.h \ diff --git a/configure.ac b/configure.ac index 524777d..58cf4d7 100644 --- a/configure.ac +++ b/configure.ac @@ -426,6 +426,7 @@ AC_CHECK_HEADERS(\ linux/compiler.h \ linux/filter.h \ linux/hdreg.h \ + linux/hidraw.h \ linux/input.h \ linux/ioctl.h \ linux/joystick.h \ diff --git a/dlls/winehid.sys/Makefile.in b/dlls/winehid.sys/Makefile.in index d9414d3..519fc2e 100644 --- a/dlls/winehid.sys/Makefile.in +++ b/dlls/winehid.sys/Makefile.in @@ -1,6 +1,8 @@ MODULE = winehid.sys IMPORTS = ntoskrnl hidclass EXTRADLLFLAGS = -Wb,--subsystem,native +EXTRALIBS = $(UDEV_LIBS) C_SRCS = \ - main.c + main.c \ + minidriver_hidraw.c \ diff --git a/dlls/winehid.sys/hid.h b/dlls/winehid.sys/hid.h new file mode 100644 index 0000000..3af3ba2 --- /dev/null +++ b/dlls/winehid.sys/hid.h @@ -0,0 +1,22 @@ +/* + * Copyright 2016 Aric Stewart + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/* Minidrivers */ +extern DRIVER_OBJECT *hr_driver_obj; + +NTSTATUS WINAPI hidraw_driver_init(DRIVER_OBJECT *driver, UNICODE_STRING *path) DECLSPEC_HIDDEN; diff --git a/dlls/winehid.sys/main.c b/dlls/winehid.sys/main.c index 91d94d9..60992f0 100644 --- a/dlls/winehid.sys/main.c +++ b/dlls/winehid.sys/main.c @@ -29,12 +29,14 @@ #include "ddk/wdm.h" #include "wine/unicode.h" #include "wine/debug.h" +#include "hid.h" WINE_DEFAULT_DEBUG_CHANNEL(hid_minidriver); /* Entry point for new devices iterated by the PNP manager */ static NTSTATUS WINAPI add_device(DRIVER_OBJECT *driver, DEVICE_OBJECT *device) { + static const WCHAR hidrawW[] = {'H','I','D','R','A','W',0}; WCHAR enumerator[10]; DWORD size; NTSTATUS status; @@ -48,7 +50,10 @@ static NTSTATUS WINAPI add_device(DRIVER_OBJECT *driver, DEVICE_OBJECT *device) return status; } - ERR("Unhandled bus %s\n",debugstr_w(enumerator)); + if (hr_driver_obj && strcmpW(enumerator, hidrawW) == 0) + hr_driver_obj->DriverExtension->AddDevice(hr_driver_obj, device); + else + ERR("Unhandled bus %s\n",debugstr_w(enumerator)); return STATUS_SUCCESS; } @@ -56,9 +61,14 @@ static NTSTATUS WINAPI add_device(DRIVER_OBJECT *driver, DEVICE_OBJECT *device) /* main entry point for the driver */ NTSTATUS WINAPI DriverEntry( DRIVER_OBJECT *driver, UNICODE_STRING *path ) { + static const WCHAR hidrawW[] = {'\\','D','r','i','v','e','r','\\','H','I','D','R','A','W','H','i','d',0}; + static UNICODE_STRING hidraw = {sizeof(hidrawW) - sizeof(WCHAR), sizeof(hidrawW), (WCHAR*)hidrawW}; + TRACE("%s\n", debugstr_w(path->Buffer) ); driver->DriverExtension->AddDevice = add_device; + IoCreateDriver(&hidraw, hidraw_driver_init); + return STATUS_SUCCESS; } diff --git a/dlls/winehid.sys/minidriver_hidraw.c b/dlls/winehid.sys/minidriver_hidraw.c new file mode 100644 index 0000000..6431ee4 --- /dev/null +++ b/dlls/winehid.sys/minidriver_hidraw.c @@ -0,0 +1,124 @@ +/* HID pseudo-mindriver connections for Linux Hidraw + * + * Copyright 2016 CodeWeavers, Aric Stewart + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" +#include "wine/port.h" +#include + +#ifdef HAVE_LINUX_HIDRAW_H +# include +#endif + +#ifdef HAVE_SYS_IOCTL_H +# include +#endif + +#ifdef HAVE_LIBUDEV_H +# include +#endif + +#include + +#define NONAMELESSUNION + +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "windef.h" +#include "winbase.h" +#include "winternl.h" +#include "winioctl.h" +#include "ddk/wdm.h" +#include "hidusage.h" +#include "ddk/hidtypes.h" +#include "ddk/hidclass.h" +#include "ddk/hidport.h" +#include "wine/debug.h" +#include "wine/unicode.h" +#include "wine/list.h" +#include "hid.h" + +WINE_DEFAULT_DEBUG_CHANNEL(hid_minidriver); + +DRIVER_OBJECT *hr_driver_obj = NULL; + +#if defined(SONAME_LIBUDEV) && defined(HAVE_LINUX_HIDRAW_H) + +typedef struct _HR_DEVICE_EXTENSTION { + int joyfd; + struct udev_device *udev; +} HR_DEVICE_EXTENSION; + +static HID_MINIDRIVER_REGISTRATION registration; + +VOID WINAPI unload(DRIVER_OBJECT *driver) +{ + TRACE("Linux Hidraw Driver Unload\n"); +} + +NTSTATUS WINAPI add_device(DRIVER_OBJECT *driver, DEVICE_OBJECT *device) +{ + HR_DEVICE_EXTENSION *ext; + HID_DEVICE_EXTENSION *bext; + const char *devnode; + + TRACE("Linux Hidraw Driver AddDevice\n"); + + bext = (HID_DEVICE_EXTENSION*)device->DeviceExtension; + ext = (HR_DEVICE_EXTENSION*)(((HID_DEVICE_EXTENSION*)device->DeviceExtension)->MiniDeviceExtension); + + ext->udev = *(struct udev_device**)bext->NextDeviceObject->DeviceExtension; + + devnode = udev_device_get_devnode(ext->udev); + ext->joyfd = open(devnode, O_RDWR); + + return STATUS_SUCCESS; +} + +NTSTATUS WINAPI hidraw_driver_init(DRIVER_OBJECT *driver, UNICODE_STRING *path) +{ + HANDLE event; + + TRACE("Linux Hidraw Minidriver Init\n"); + + event = CreateEventW(NULL, FALSE, FALSE, NULL); + + hr_driver_obj = driver; + + driver->DriverUnload = unload; + driver->DriverExtension->AddDevice = add_device; + + registration.DriverObject = driver; + registration.RegistryPath = path; + registration.DeviceExtensionSize = sizeof(HR_DEVICE_EXTENSION) + sizeof(HID_DEVICE_EXTENSION); + registration.DevicesArePolled = FALSE; + HidRegisterMinidriver(®istration); + + SetEvent(event); + return STATUS_SUCCESS; +} + +#else + +NTSTATUS WINAPI hidraw_driver_init(DRIVER_OBJECT *driver, UNICODE_STRING *path) +{ + TRACE("Dummy Linux Hidraw Minidriver Init\n"); + return STATUS_SUCCESS; +} + +#endif /* SONAME_LIBUDEV && HAVE_LINUX_HIDRAW_H */ diff --git a/include/config.h.in b/include/config.h.in index b9f9f19..f33ae49 100644 --- a/include/config.h.in +++ b/include/config.h.in @@ -435,6 +435,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_LINUX_HDREG_H +/* Define to 1 if you have the header file. */ +#undef HAVE_LINUX_HIDRAW_H + /* Define to 1 if you have the header file. */ #undef HAVE_LINUX_INPUT_H diff --git a/loader/wine.inf.in b/loader/wine.inf.in index b595693..92f4134 100644 --- a/loader/wine.inf.in +++ b/loader/wine.inf.in @@ -35,6 +35,7 @@ AddReg=\ Classes,\ ContentIndex,\ ControlClass,\ + CriticalDevice,\ CurrentVersion,\ Debugger,\ DirectX,\ @@ -60,6 +61,7 @@ AddReg=\ Classes,\ ContentIndex,\ ControlClass,\ + CriticalDevice,\ CurrentVersion,\ Debugger,\ DirectX,\ @@ -87,6 +89,7 @@ AddReg=\ Classes,\ ContentIndex,\ ControlClass,\ + CriticalDevice,\ CurrentVersion,\ CurrentVersionWow64,\ Debugger,\ @@ -463,6 +466,9 @@ HKLM,System\CurrentControlSet\Control\Class\{6bdd1fc6-810f-11d0-bec7-08002be2092 HKLM,System\CurrentControlSet\Control\Class\{745a17a0-74d3-11d0-b6fe-00a0c90f57da},,,"Human Interface Devices" HKLM,System\CurrentControlSet\Control\Class\{745a17a0-74d3-11d0-b6fe-00a0c90f57da},"Class",,"HIDClass" +[CriticalDevice] +HKLM,System\CurrentControlSet\Control\CriticalDeviceDatabase\HIDRAW,"Service",,"WineHIDMinidriver" + [CurrentVersion] HKCU,%CurrentVersion%\Run,,16 HKLM,%CurrentVersion%,"CommonFilesDir",,"%16427%"