From 6d3e5f8441136d359274af7791c787eb5d205cb2 Mon Sep 17 00:00:00 2001
From: Aric Stewart <aric@codeweavers.com>
Date: Thu, 8 Sep 2016 10:12:50 +0200
Subject: [PATCH] winebus.sys: Add initial udev stub driver.

Signed-off-by: Aric Stewart <aric@codeweavers.com>
Signed-off-by: Sebastian Lackner <sebastian@fds-team.de>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
---
 configure                    | 107 +++++++++++++++++++++++++++++++++++
 configure.ac                 |  14 +++++
 dlls/winebus.sys/Makefile.in |   2 +
 dlls/winebus.sys/bus.h       |  23 ++++++++
 dlls/winebus.sys/bus_udev.c  |  60 ++++++++++++++++++++
 dlls/winebus.sys/main.c      |  34 +++++++++++
 include/config.h.in          |   6 ++
 7 files changed, 246 insertions(+)
 create mode 100644 dlls/winebus.sys/bus.h
 create mode 100644 dlls/winebus.sys/bus_udev.c

diff --git a/configure b/configure
index ce6b8143cd0..2cc532b2fc8 100755
--- a/configure
+++ b/configure
@@ -652,6 +652,8 @@ FONTCONFIG_CFLAGS
 CUPS_CFLAGS
 CAPI20_LIBS
 CAPI20_CFLAGS
+UDEV_LIBS
+UDEV_CFLAGS
 OSS4_CFLAGS
 ALSA_LIBS
 GSTREAMER_LIBS
@@ -846,6 +848,7 @@ with_pthread
 with_pulse
 with_sane
 with_tiff
+with_udev
 with_v4l
 with_xcomposite
 with_xcursor
@@ -1590,6 +1593,8 @@ PULSE_CFLAGS
 PULSE_LIBS
 GSTREAMER_CFLAGS
 GSTREAMER_LIBS
+UDEV_CFLAGS
+UDEV_LIBS
 CAPI20_CFLAGS
 CAPI20_LIBS
 FONTCONFIG_CFLAGS
@@ -2275,6 +2280,7 @@ Optional Packages:
   --without-pulse         do not use PulseAudio sound support
   --without-sane          do not use SANE (scanner support)
   --without-tiff          do not use TIFF
+  --without-udev          do not use udev (play and play support)
   --without-v4l           do not use v4l1 (v4l support)
   --without-xcomposite    do not use the Xcomposite extension
   --without-xcursor       do not use the Xcursor extension
@@ -2342,6 +2348,8 @@ Some influential environment variables:
   GSTREAMER_LIBS
               Linker flags for gstreamer-1.0 gstreamer-video-1.0
               gstreamer-audio-1.0, overriding pkg-config
+  UDEV_CFLAGS C compiler flags for libudev, overriding pkg-config
+  UDEV_LIBS   Linker flags for libudev, overriding pkg-config
   CAPI20_CFLAGS
               C compiler flags for capi20, overriding pkg-config
   CAPI20_LIBS Linker flags for capi20, overriding pkg-config
@@ -3546,6 +3554,12 @@ if test "${with_tiff+set}" = set; then :
 fi
 
 
+# Check whether --with-udev was given.
+if test "${with_udev+set}" = set; then :
+  withval=$with_udev;
+fi
+
+
 # Check whether --with-v4l was given.
 if test "${with_v4l+set}" = set; then :
   withval=$with_v4l;
@@ -12902,6 +12916,97 @@ esac
 enable_wineoss_drv=${enable_wineoss_drv:-no}
 fi
 
+if test "x$with_udev" != "xno"
+then
+    if ${UDEV_CFLAGS:+false} :; then :
+  if ${PKG_CONFIG+:} false; then :
+  UDEV_CFLAGS=`$PKG_CONFIG --cflags libudev 2>/dev/null`
+fi
+fi
+
+if ${UDEV_LIBS:+false} :; then :
+  if ${PKG_CONFIG+:} false; then :
+  UDEV_LIBS=`$PKG_CONFIG --libs libudev 2>/dev/null`
+fi
+fi
+
+
+$as_echo "$as_me:${as_lineno-$LINENO}: libudev cflags: $UDEV_CFLAGS" >&5
+$as_echo "$as_me:${as_lineno-$LINENO}: libudev libs: $UDEV_LIBS" >&5
+ac_save_CPPFLAGS=$CPPFLAGS
+CPPFLAGS="$CPPFLAGS $UDEV_CFLAGS"
+for ac_header in libudev.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "libudev.h" "ac_cv_header_libudev_h" "$ac_includes_default"
+if test "x$ac_cv_header_libudev_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBUDEV_H 1
+_ACEOF
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for udev_new in -ludev" >&5
+$as_echo_n "checking for udev_new in -ludev... " >&6; }
+if ${ac_cv_lib_udev_udev_new+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ludev $UDEV_LIBS $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char udev_new ();
+int
+main ()
+{
+return udev_new ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_udev_udev_new=yes
+else
+  ac_cv_lib_udev_udev_new=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_udev_udev_new" >&5
+$as_echo "$ac_cv_lib_udev_udev_new" >&6; }
+if test "x$ac_cv_lib_udev_udev_new" = xyes; then :
+
+$as_echo "#define HAVE_UDEV 1" >>confdefs.h
+
+else
+  UDEV_LIBS=""
+fi
+
+else
+  UDEV_LIBS=""
+fi
+
+done
+
+CPPFLAGS=$ac_save_CPPFLAGS
+test -z "$UDEV_CFLAGS" || UDEV_CFLAGS=`echo " $UDEV_CFLAGS" | sed 's/ -I\([^/]\)/ -I\$(top_builddir)\/\1/g'`
+test -z "$UDEV_LIBS" || UDEV_LIBS=`echo " $UDEV_LIBS" | sed 's/ -L\([^/]\)/ -L\$(top_builddir)\/\1/g'`
+
+fi
+if test "x$UDEV_LIBS" = "x"; then :
+  case "x$with_udev" in
+  x)   as_fn_append wine_notices "|libudev ${notice_platform}development files not found, plug and play won't be supported." ;;
+  xno) ;;
+  *)   as_fn_error $? "libudev ${notice_platform}development files not found, plug and play won't be supported.
+This is an error since --with-udev was requested." "$LINENO" 5 ;;
+esac
+
+fi
+
 if test "x$with_capi" != "xno"
 then
     if ${CAPI20_CFLAGS:+false} :; then :
@@ -17350,6 +17455,8 @@ GSTREAMER_CFLAGS = $GSTREAMER_CFLAGS
 GSTREAMER_LIBS = $GSTREAMER_LIBS
 ALSA_LIBS = $ALSA_LIBS
 OSS4_CFLAGS = $OSS4_CFLAGS
+UDEV_CFLAGS = $UDEV_CFLAGS
+UDEV_LIBS = $UDEV_LIBS
 CAPI20_CFLAGS = $CAPI20_CFLAGS
 CAPI20_LIBS = $CAPI20_LIBS
 CUPS_CFLAGS = $CUPS_CFLAGS
diff --git a/configure.ac b/configure.ac
index 8ce789ffb9c..680955873dc 100644
--- a/configure.ac
+++ b/configure.ac
@@ -75,6 +75,7 @@ AC_ARG_WITH(pthread,   AS_HELP_STRING([--without-pthread],[do not use the pthrea
 AC_ARG_WITH(pulse,     AS_HELP_STRING([--without-pulse],[do not use PulseAudio sound support]))
 AC_ARG_WITH(sane,      AS_HELP_STRING([--without-sane],[do not use SANE (scanner support)]))
 AC_ARG_WITH(tiff,      AS_HELP_STRING([--without-tiff],[do not use TIFF]))
+AC_ARG_WITH(udev,      AS_HELP_STRING([--without-udev],[do not use udev (play and play support)]))
 AC_ARG_WITH(v4l,       AS_HELP_STRING([--without-v4l],[do not use v4l1 (v4l support)]))
 AC_ARG_WITH(xcomposite,AS_HELP_STRING([--without-xcomposite],[do not use the Xcomposite extension]),
             [if test "x$withval" = "xno"; then ac_cv_header_X11_extensions_Xcomposite_h=no; fi])
@@ -1519,6 +1520,19 @@ WINE_NOTICE_WITH(oss,[test "x$ac_cv_member_oss_sysinfo_numaudioengines" != xyes]
                  [OSS sound system found but too old (OSSv4 needed), OSS won't be supported.],
                  [enable_wineoss_drv])
 
+dnl **** Check for libudev ****
+if test "x$with_udev" != "xno"
+then
+    WINE_PACKAGE_FLAGS(UDEV,[libudev],,,,
+        [AC_CHECK_HEADERS(libudev.h,
+            [AC_CHECK_LIB(udev,udev_new,
+                AC_DEFINE(HAVE_UDEV,1,[Define to 1 if you have the `udev' library (-ludev).]),
+                [UDEV_LIBS=""],[$UDEV_LIBS])],
+            [UDEV_LIBS=""])])
+fi
+WINE_NOTICE_WITH(udev,[test "x$UDEV_LIBS" = "x"],
+                 [libudev ${notice_platform}development files not found, plug and play won't be supported.])
+
 dnl **** Check for capi4linux ****
 if test "x$with_capi" != "xno"
 then
diff --git a/dlls/winebus.sys/Makefile.in b/dlls/winebus.sys/Makefile.in
index d646dc3397a..99ff4d22749 100644
--- a/dlls/winebus.sys/Makefile.in
+++ b/dlls/winebus.sys/Makefile.in
@@ -1,5 +1,7 @@
 MODULE    = winebus.sys
+IMPORTS   = ntoskrnl
 EXTRADLLFLAGS = -Wb,--subsystem,native
 
 C_SRCS = \
+	bus_udev.c \
 	main.c
diff --git a/dlls/winebus.sys/bus.h b/dlls/winebus.sys/bus.h
new file mode 100644
index 00000000000..3d53a462fb7
--- /dev/null
+++ b/dlls/winebus.sys/bus.h
@@ -0,0 +1,23 @@
+/*
+ * 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
+ */
+
+/* Busses */
+NTSTATUS WINAPI udev_driver_init(DRIVER_OBJECT *driver, UNICODE_STRING *registry_path) DECLSPEC_HIDDEN;
+
+/* HID Plug and Play Bus */
+NTSTATUS WINAPI common_pnp_dispatch(DEVICE_OBJECT *device, IRP *irp) DECLSPEC_HIDDEN;
diff --git a/dlls/winebus.sys/bus_udev.c b/dlls/winebus.sys/bus_udev.c
new file mode 100644
index 00000000000..f040e60e3e1
--- /dev/null
+++ b/dlls/winebus.sys/bus_udev.c
@@ -0,0 +1,60 @@
+/*
+ * Plug and Play support for hid devices found through udev
+ *
+ * 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 <stdarg.h>
+
+#define NONAMELESSUNION
+
+#include "ntstatus.h"
+#define WIN32_NO_STATUS
+#include "windef.h"
+#include "winbase.h"
+#include "winternl.h"
+#include "ddk/wdm.h"
+#include "wine/debug.h"
+
+#include "bus.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(plugplay);
+
+#ifdef HAVE_UDEV
+
+static DRIVER_OBJECT *udev_driver_obj = NULL;
+
+NTSTATUS WINAPI udev_driver_init(DRIVER_OBJECT *driver, UNICODE_STRING *registry_path)
+{
+    TRACE("(%p, %s)\n", driver, debugstr_w(registry_path->Buffer));
+
+    udev_driver_obj = driver;
+    driver->MajorFunction[IRP_MJ_PNP] = common_pnp_dispatch;
+
+    return STATUS_SUCCESS;
+}
+
+#else
+
+NTSTATUS WINAPI udev_driver_init(DRIVER_OBJECT *driver, UNICODE_STRING *registry_path)
+{
+    WARN("Wine was compiled without UDEV support\n");
+    return STATUS_NOT_IMPLEMENTED;
+}
+
+#endif /* HAVE_UDEV */
diff --git a/dlls/winebus.sys/main.c b/dlls/winebus.sys/main.c
index d495cd98757..43de25ad3fc 100644
--- a/dlls/winebus.sys/main.c
+++ b/dlls/winebus.sys/main.c
@@ -20,6 +20,8 @@
 
 #include <stdarg.h>
 
+#define NONAMELESSUNION
+
 #include "ntstatus.h"
 #define WIN32_NO_STATUS
 #include "windef.h"
@@ -28,11 +30,43 @@
 #include "ddk/wdm.h"
 #include "wine/debug.h"
 
+#include "bus.h"
+
 WINE_DEFAULT_DEBUG_CHANNEL(plugplay);
 
+NTSTATUS WINAPI common_pnp_dispatch(DEVICE_OBJECT *device, IRP *irp)
+{
+    NTSTATUS status = irp->IoStatus.u.Status;
+    IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation(irp);
+
+    switch (irpsp->MinorFunction)
+    {
+        case IRP_MN_QUERY_DEVICE_RELATIONS:
+            TRACE("IRP_MN_QUERY_DEVICE_RELATIONS\n");
+            break;
+        case IRP_MN_QUERY_ID:
+            TRACE("IRP_MN_QUERY_ID\n");
+            break;
+        case IRP_MN_QUERY_CAPABILITIES:
+            TRACE("IRP_MN_QUERY_CAPABILITIES\n");
+            break;
+        default:
+            FIXME("Unhandled function %08x\n", irpsp->MinorFunction);
+            break;
+    }
+
+    IoCompleteRequest(irp, IO_NO_INCREMENT);
+    return status;
+}
+
 NTSTATUS WINAPI DriverEntry( DRIVER_OBJECT *driver, UNICODE_STRING *path )
 {
+    static const WCHAR udevW[] = {'\\','D','r','i','v','e','r','\\','U','D','E','V',0};
+    static UNICODE_STRING udev = {sizeof(udevW) - sizeof(WCHAR), sizeof(udevW), (WCHAR *)udevW};
+
     TRACE( "(%p, %s)\n", driver, debugstr_w(path->Buffer) );
 
+    IoCreateDriver(&udev, udev_driver_init);
+
     return STATUS_SUCCESS;
 }
diff --git a/include/config.h.in b/include/config.h.in
index 382beb66d54..bcee452ac94 100644
--- a/include/config.h.in
+++ b/include/config.h.in
@@ -378,6 +378,9 @@
 /* Define to 1 if you have the <libproc.h> header file. */
 #undef HAVE_LIBPROC_H
 
+/* Define to 1 if you have the <libudev.h> header file. */
+#undef HAVE_LIBUDEV_H
+
 /* Define to 1 if you have the <libunwind.h> header file. */
 #undef HAVE_LIBUNWIND_H
 
@@ -1200,6 +1203,9 @@
 /* Define to 1 if you have the `truncf' function. */
 #undef HAVE_TRUNCF
 
+/* Define to 1 if you have the `udev' library (-ludev). */
+#undef HAVE_UDEV
+
 /* Define to 1 if you have the <unistd.h> header file. */
 #undef HAVE_UNISTD_H
 
-- 
GitLab