From 12f323214ef390f810bdc03e9713f83e7558ad2f Mon Sep 17 00:00:00 2001 From: Alexander Morozov Date: Tue, 15 May 2012 15:49:15 +0400 Subject: [eter-2.0.0 4/8] mountmgr: Add dynamic USB devices support using udev (eterbug #4301). --- configure | 71 ++++++++++++++++++++++++++++++++++ configure.ac | 13 +++++++ dlls/mountmgr.sys/Makefile.in | 2 +- dlls/mountmgr.sys/dbus.c | 8 ++++ dlls/mountmgr.sys/usbhub.c | 84 +++++++++++++++++++++++++++++++++++++++++ include/config.h.in | 3 ++ 6 files changed, 180 insertions(+), 1 deletion(-) diff --git a/configure b/configure index 94eb36a..c5f263d 100755 --- a/configure +++ b/configure @@ -644,6 +644,7 @@ gphoto2port_devel gphoto2_devel USBINCL USBLIBS +LIBUDEV IEEE1284LIBS SANEINCL sane_devel @@ -811,6 +812,7 @@ with_oss with_png with_pthread with_sane +with_udev with_usb with_tiff with_v4l @@ -1504,6 +1506,7 @@ Optional Packages: --without-png do not use PNG --without-pthread do not use the pthread library --without-sane do not use SANE (scanner support) + --without-udev do not use libudev --without-usb do not use USB --without-tiff do not use TIFF --without-v4l do not use v4l1 (v4l support) @@ -2730,6 +2733,12 @@ if test "${with_sane+set}" = set; then : fi +# Check whether --with-udev was given. +if test "${with_udev+set}" = set; then : + withval=$with_udev; +fi + + # Check whether --with-usb was given. if test "${with_usb+set}" = set; then : withval=$with_usb; @@ -10163,6 +10172,68 @@ This is an error since --with-ieee1284 was requested." "$LINENO" 5 ;; esac fi +LIBUDEV="" + +if test "x$with_udev" != "xno" +then + 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 : + { $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 $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_LIBUDEV 1" >>confdefs.h + + LIBUDEV="-ludev" +fi + +fi + + +fi +if test "x$ac_cv_lib_udev_udev_new" = "x"; then : + case "x$with_udev" in + x) as_fn_append wine_notices "|libudev ${notice_platform}development files not found, no dynamic USB device support." ;; + xno) ;; + *) as_fn_error $? "libudev ${notice_platform}development files not found, no dynamic USB device support. +This is an error since --with-udev was requested." "$LINENO" 5 ;; +esac +fi + USBLIBS="" USBINCL="" diff --git a/configure.ac b/configure.ac index 84ea9e6..37fba8d 100644 --- a/configure.ac +++ b/configure.ac @@ -78,6 +78,7 @@ AC_ARG_WITH(png, AS_HELP_STRING([--without-png],[do not use PNG]), AC_ARG_WITH(pthread, AS_HELP_STRING([--without-pthread],[do not use the pthread library]), [if test "x$withval" = "xno"; then ac_cv_header_pthread_h=no; fi]) AC_ARG_WITH(sane, AS_HELP_STRING([--without-sane],[do not use SANE (scanner support)])) +AC_ARG_WITH(udev, AS_HELP_STRING([--without-udev],[do not use libudev])) AC_ARG_WITH(usb, AS_HELP_STRING([--without-usb],[do not use USB])) AC_ARG_WITH(tiff, AS_HELP_STRING([--without-tiff],[do not use TIFF]), [if test "x$withval" = "xno"; then ac_cv_header_tiffio_h=no; fi]) @@ -1327,6 +1328,18 @@ fi WINE_NOTICE_WITH(ieee1284,[test "x$ac_cv_lib_ieee1284_ieee1284_find_ports" = "x"], [libieee1284 ${notice_platform}development files not found, no LPT device drivers support.]) +dnl **** Check for libudev **** +AC_SUBST(LIBUDEV,"") +if test "x$with_udev" != "xno" +then + AC_CHECK_HEADER(libudev.h, + AC_CHECK_LIB(udev, udev_new, + [AC_DEFINE(HAVE_LIBUDEV, 1, [Define if you have the libudev library and header]) + LIBUDEV="-ludev"])) +fi +WINE_NOTICE_WITH(udev,[test "x$ac_cv_lib_udev_udev_new" = "x"], + [libudev ${notice_platform}development files not found, no dynamic USB device support.]) + dnl **** Check for LIBUSB **** AC_SUBST(USBLIBS,"") AC_SUBST(USBINCL,"") diff --git a/dlls/mountmgr.sys/Makefile.in b/dlls/mountmgr.sys/Makefile.in index 756a36c..82f6a6a 100644 --- a/dlls/mountmgr.sys/Makefile.in +++ b/dlls/mountmgr.sys/Makefile.in @@ -4,7 +4,7 @@ DELAYIMPORTS = user32 EXTRADLLFLAGS = -Wb,--subsystem,native EXTRADEFS = @DBUSINCL@ @HALINCL@ EXTRAINCL = @USBINCL@ -EXTRALIBS = @DISKARBITRATIONLIB@ @USBLIBS@ @IEEE1284LIBS@ +EXTRALIBS = @DISKARBITRATIONLIB@ @USBLIBS@ @IEEE1284LIBS@ @LIBUDEV@ C_SRCS = \ dbus.c \ diff --git a/dlls/mountmgr.sys/dbus.c b/dlls/mountmgr.sys/dbus.c index 533d0e4..785eb3f 100644 --- a/dlls/mountmgr.sys/dbus.c +++ b/dlls/mountmgr.sys/dbus.c @@ -431,7 +431,9 @@ static int get_num_from_file( const char *path, const char *filename ) static void hal_new_device( LibHalContext *ctx, const char *udi ) { DBusError error; +#ifndef HAVE_LIBUDEV char *subsys = NULL; +#endif char *parent = NULL; char *mount_point = NULL; char *device = NULL; @@ -452,9 +454,11 @@ static void hal_new_device( LibHalContext *ctx, const char *udi ) p_dbus_error_init( &error ); +#ifndef HAVE_LIBUDEV if ((subsys = p_libhal_device_get_property_string( ctx, udi, "info.subsystem", NULL )) && !strcmp( subsys, "usb_device" )) add_usb_devices(); +#endif if (automount_disabled()) goto done; @@ -520,7 +524,9 @@ static void hal_new_device( LibHalContext *ctx, const char *udi ) else if (guid_ptr) add_volume( udi, device, mount_point, DEVICE_HARDDISK_VOL, guid_ptr ); done: +#ifndef HAVE_LIBUDEV if (subsys) p_libhal_free_string( subsys ); +#endif if (type) p_libhal_free_string( type ); if (parent) p_libhal_free_string( parent ); if (device) p_libhal_free_string( device ); @@ -542,7 +548,9 @@ static void hal_removed_device( LibHalContext *ctx, const char *udi ) TRACE( "removed %s\n", wine_dbgstr_a(udi) ); +#ifndef HAVE_LIBUDEV remove_usb_devices(); +#endif if (!remove_dos_device( -1, udi )) { p_dbus_error_init( &error ); diff --git a/dlls/mountmgr.sys/usbhub.c b/dlls/mountmgr.sys/usbhub.c index 9a25e91..71f5da3 100644 --- a/dlls/mountmgr.sys/usbhub.c +++ b/dlls/mountmgr.sys/usbhub.c @@ -21,6 +21,12 @@ #include #include +#ifdef HAVE_POLL_H +#include +#endif +#ifdef HAVE_SYS_POLL_H +#include +#endif #ifdef HAVE_LIBUSB_1 #include @@ -32,6 +38,9 @@ #undef USB_ENDPOINT_TYPE_BULK #undef USB_ENDPOINT_TYPE_INTERRUPT #endif +#ifdef HAVE_LIBUDEV +#include +#endif #define NONAMELESSUNION #define NONAMELESSSTRUCT @@ -2197,6 +2206,77 @@ void remove_usb_devices(void) #if defined(HAVE_LIBUSB) || defined(HAVE_LIBUSB_1) +#ifdef HAVE_LIBUDEV + +static void *start_udev(void) +{ + struct udev *udev; + struct udev_monitor *mon; + int ret; + + udev = udev_new(); + if (!udev) + return NULL; + + mon = udev_monitor_new_from_netlink( udev, "udev" ); + if (!mon) goto end; + ret = udev_monitor_filter_add_match_subsystem_devtype( mon, "usb", "usb_device" ); + if (ret < 0) goto end; + ret = udev_monitor_enable_receiving( mon ); + if (ret < 0) goto end; + return mon; +end: + udev_monitor_unref( mon ); + udev_unref( udev ); + return NULL; +} + +static void loop_udev( void *mon ) +{ + struct pollfd fds; + int ret, fd = udev_monitor_get_fd( mon ); + + fds.fd = fd; + fds.events = POLLIN; + + for(;;) + { + fds.revents = 0; + ret = poll( &fds, 1, -1 ); + if (ret == 1 && (fds.revents & POLLIN)) + { + struct udev_device *dev = udev_monitor_receive_device( mon ); + + if (dev) + { + const char *action = udev_device_get_action( dev ); + + if (action) + { + if (!strcmp( action, "add" )) + add_usb_devices(); + else if (!strcmp( action, "remove" )) + remove_usb_devices(); + } + udev_device_unref( dev ); + } + } + } +} + +#else /* HAVE_LIBUDEV */ + +static void *start_udev(void) +{ + return NULL; +} + +static void loop_udev( void *mon ) +{ +} + +#endif /* HAVE_LIBUDEV */ + static DWORD CALLBACK initialize_usbhub( void *arg ) { static const WCHAR usbhub_started_eventW[] = {'_','_','w','i','n','e', @@ -2204,6 +2284,7 @@ static DWORD CALLBACK initialize_usbhub( void *arg ) 'S','t','a','r','t','e','d',0}; HANDLE event; + void *monitor; start_root_devices( usbhub_driver ); EnterCriticalSection( &usbhub_cs ); @@ -2214,10 +2295,13 @@ static DWORD CALLBACK initialize_usbhub( void *arg ) else libusb_initialized = TRUE; LeaveCriticalSection( &usbhub_cs ); + monitor = start_udev(); add_usb_devices(); event = CreateEventW( NULL, TRUE, FALSE, usbhub_started_eventW ); SetEvent( event ); CloseHandle( event ); + if (monitor) + loop_udev( monitor ); return 0; } diff --git a/include/config.h.in b/include/config.h.in index c599f1e..b87d5c0 100644 --- a/include/config.h.in +++ b/include/config.h.in @@ -356,6 +356,9 @@ /* Define to 1 if you have the `ossaudio' library (-lossaudio). */ #undef HAVE_LIBOSSAUDIO +/* Define if you have the libudev library and header */ +#undef HAVE_LIBUDEV + /* Define if you have the libusb library and header */ #undef HAVE_LIBUSB -- 1.7.9.7