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 + +#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 +#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 header file. */ #undef HAVE_LIBPROC_H +/* Define to 1 if you have the header file. */ +#undef HAVE_LIBUDEV_H + /* Define to 1 if you have the 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 header file. */ #undef HAVE_UNISTD_H