From: Detlef Riekenberg Subject: [PATCH 2/2] mountmgr: Support the dbus service udisks for dynamic devices :-) Message-Id: <1309436901-21216-2-git-send-email-wine.dev@web.de> Date: Thu, 30 Jun 2011 14:28:21 +0200 udisks is prefered, but libhal support is still present as fallback. This allow the libhal requirement on linux to die. Binary packages should be build with libhal support for a while. The logic to add/remove the devices/volumes is the same as present in our libhal support. autoheader/autoconf are needed before compilation -- By by ... Detlef --- configure.ac | 20 ++- dlls/mountmgr.sys/Makefile.in | 5 +- dlls/mountmgr.sys/hal.c | 15 ++ dlls/mountmgr.sys/mountmgr.c | 2 + dlls/mountmgr.sys/mountmgr.h | 3 + dlls/mountmgr.sys/udisks.c | 554 +++++++++++++++++++++++++++++++++++++++++ 6 files changed, 596 insertions(+), 3 deletions(-) create mode 100644 dlls/mountmgr.sys/udisks.c diff --git a/configure.ac b/configure.ac index b50d5ed..4d39606 100644 --- a/configure.ac +++ b/configure.ac @@ -42,6 +42,7 @@ AC_ARG_WITH(coreaudio, AS_HELP_STRING([--without-coreaudio],[do not use the Core AC_ARG_WITH(cups, AS_HELP_STRING([--without-cups],[do not use CUPS])) AC_ARG_WITH(curses, AS_HELP_STRING([--without-curses],[do not use (n)curses]), [if test "x$withval" = "xno"; then ac_cv_header_ncurses_h=no; ac_cv_header_curses_h=no; fi]) +AC_ARG_WITH(dbus, AS_HELP_STRING([--without-dbus],[do not use dbus (dynamic device support)])) AC_ARG_WITH(esd, AS_HELP_STRING([--without-esd],[do not use the EsounD sound support])) AC_ARG_WITH(fontconfig,AS_HELP_STRING([--without-fontconfig],[do not use fontconfig]), [if test "x$withval" = "xno"; then ac_cv_header_fontconfig_fontconfig_h=no; fi]) @@ -1214,6 +1215,23 @@ fi WINE_WARNING_WITH(xslt,[test "x$ac_cv_lib_soname_xslt" = "x"], [libxslt ${notice_platform}development files not found, xslt won't be supported.]) +dnl **** Check for libdbus **** +AC_SUBST(DBUSINCL,"") +if test "x$with_dbus" != "xno" +then + ac_save_CPPFLAGS="$CPPFLAGS" + if test "$PKG_CONFIG" != "false" + then + ac_dbus_libs="`$PKG_CONFIG --libs dbus-1 2>/dev/null`" + ac_dbus_cflags="`$PKG_CONFIG --cflags dbus-1 2>/dev/null`" + CPPFLAGS="$CPPFLAGS $ac_dbus_cflags" + fi + AC_CHECK_HEADER(dbus/dbus.h, + [WINE_CHECK_SONAME(dbus-1,dbus_bus_get,[DBUSINCL="$ac_dbus_cflags"],,[$ac_dbus_libs])]) + + CPPFLAGS="$ac_save_CPPFLAGS" +fi + dnl **** Check for libhal **** AC_SUBST(HALINCL,"") if test "x$with_hal" != "xno" @@ -1234,7 +1252,7 @@ then fi CPPFLAGS="$ac_save_CPPFLAGS" fi -WINE_NOTICE_WITH(hal,[test "x$ac_cv_lib_soname_hal" = "x" -a "x$ac_cv_header_DiskArbitration_DiskArbitration_h" != "xyes"], +WINE_NOTICE_WITH(hal,[test "x$ac_cv_lib_soname_hal" = "x" -a "x$ac_cv_lib_soname_dbus_1" = "x" -a "x$ac_cv_header_DiskArbitration_DiskArbitration_h" != "xyes"], [libhal/libdbus ${notice_platform}development files not found, no dynamic device support.]) dnl **** Check for libgnutls **** diff --git a/dlls/mountmgr.sys/Makefile.in b/dlls/mountmgr.sys/Makefile.in index 91203e1..d96628b 100644 --- a/dlls/mountmgr.sys/Makefile.in +++ b/dlls/mountmgr.sys/Makefile.in @@ -2,13 +2,14 @@ MODULE = mountmgr.sys IMPORTS = uuid advapi32 ntoskrnl.exe DELAYIMPORTS = user32 EXTRADLLFLAGS = -Wb,--subsystem,native -EXTRADEFS = @HALINCL@ +EXTRADEFS = @HALINCL@ @DBUSINCL@ EXTRALIBS = @DISKARBITRATIONLIB@ C_SRCS = \ device.c \ diskarb.c \ hal.c \ - mountmgr.c + mountmgr.c \ + udisks.c \ @MAKE_DLL_RULES@ diff --git a/dlls/mountmgr.sys/hal.c b/dlls/mountmgr.sys/hal.c index ff10a3e..8e31624 100644 --- a/dlls/mountmgr.sys/hal.c +++ b/dlls/mountmgr.sys/hal.c @@ -245,6 +245,21 @@ void initialize_hal(void) { HANDLE handle; + /* wait for udisks, when needed */ + if (dbus_present) + { + DWORD res; + + TRACE("waiting for udisks\n"); + res = WaitForSingleObject(dbus_present, 100); + + if (!res && *udisks_version) + { + TRACE("Skipping, found udisks\n"); + return; + } + } + if (!load_functions()) return; if (!(handle = CreateThread( NULL, 0, hal_thread, NULL, 0, NULL ))) return; CloseHandle( handle ); diff --git a/dlls/mountmgr.sys/mountmgr.c b/dlls/mountmgr.sys/mountmgr.c index 4e9900f..df0dbd3 100644 --- a/dlls/mountmgr.sys/mountmgr.c +++ b/dlls/mountmgr.sys/mountmgr.c @@ -443,6 +443,8 @@ NTSTATUS WINAPI DriverEntry( DRIVER_OBJECT *driver, UNICODE_STRING *path ) RtlInitUnicodeString( &nameW, harddiskW ); status = IoCreateDriver( &nameW, harddisk_driver_entry ); + /* start udisks before hal */ + initialize_udisks(); initialize_hal(); initialize_diskarbitration(); diff --git a/dlls/mountmgr.sys/mountmgr.h b/dlls/mountmgr.sys/mountmgr.h index a8e4389..3c3c564 100644 --- a/dlls/mountmgr.sys/mountmgr.h +++ b/dlls/mountmgr.sys/mountmgr.h @@ -35,8 +35,11 @@ #define WINE_MOUNTMGR_EXTENSIONS #include "ddk/mountmgr.h" +extern void initialize_udisks(void) DECLSPEC_HIDDEN; extern void initialize_hal(void) DECLSPEC_HIDDEN; extern void initialize_diskarbitration(void) DECLSPEC_HIDDEN; +extern HANDLE dbus_present; +extern char udisks_version[]; /* device functions */ diff --git a/dlls/mountmgr.sys/udisks.c b/dlls/mountmgr.sys/udisks.c new file mode 100644 index 0000000..3b02eb2 --- /dev/null +++ b/dlls/mountmgr.sys/udisks.c @@ -0,0 +1,554 @@ +/* + * udisks devices support + * + * Copyright 2006 Alexandre Julliard + * Copyright 2011 Detlef Riekenberg + * + * 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 +#include +#include +#include +#include + +#include "mountmgr.h" +#include "winnls.h" +#include "excpt.h" + +#include "wine/library.h" +#include "wine/exception.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(mountmgr); + +HANDLE dbus_present = NULL; +char udisks_version[32]; + +#ifdef SONAME_LIBDBUS_1 + +#include + +/* ########## */ + +typedef struct properties_s { + CHAR *device_file; + CHAR *id_usage; + CHAR *id_type; + CHAR *id_uuid; + BOOL device_is_mounted; + BOOL device_is_optical_disc; + BOOL device_is_removable; + CHAR *device_mount_paths; + CHAR *drive_media; + CHAR *drive_media_compatibility; + int depth; + const char * last_name; +}properties_t; + +static const char *my_match_rule = "interface=org.freedesktop.UDisks"; +static const char *dest_udisks_device = "org.freedesktop.UDisks.Device"; +static const char *dest_udisks = "org.freedesktop.UDisks"; +static const char *path_udisks = "/org/freedesktop/UDisks"; +static const char *iface_dbus_prop = "org.freedesktop.DBus.Properties"; +static const char *daemonversion = "DaemonVersion"; + +/* ########## */ + +#define DBUS_FUNCS \ + DO_FUNC(dbus_bus_add_match); \ + DO_FUNC(dbus_bus_get); \ + DO_FUNC(dbus_bus_remove_match); \ + DO_FUNC(dbus_connection_pop_message); \ + DO_FUNC(dbus_connection_read_write_dispatch); \ + DO_FUNC(dbus_connection_send_with_reply_and_block); \ + DO_FUNC(dbus_connection_unref); \ + DO_FUNC(dbus_error_free); \ + DO_FUNC(dbus_error_init); \ + DO_FUNC(dbus_error_is_set); \ + DO_FUNC(dbus_message_append_args); \ + DO_FUNC(dbus_message_get_member); \ + DO_FUNC(dbus_message_iter_get_arg_type); \ + DO_FUNC(dbus_message_iter_get_basic); \ + DO_FUNC(dbus_message_iter_init); \ + DO_FUNC(dbus_message_iter_next); \ + DO_FUNC(dbus_message_iter_recurse); \ + DO_FUNC(dbus_message_new_method_call); \ + DO_FUNC(dbus_message_type_to_string); \ + DO_FUNC(dbus_message_unref) + +#define DO_FUNC(f) static typeof(f) * p_##f +DBUS_FUNCS; +#undef DO_FUNC + + +static BOOL load_dbus_functions(void) +{ + void *dbus_handle; + char error[128]; + + if (!(dbus_handle = wine_dlopen(SONAME_LIBDBUS_1, RTLD_NOW|RTLD_GLOBAL, error, sizeof(error)))) + goto failed; + +#define DO_FUNC(f) if (!(p_##f = wine_dlsym(RTLD_DEFAULT, #f, error, sizeof(error)))) goto failed + DBUS_FUNCS; +#undef DO_FUNC + + return TRUE; + +failed: + WARN("failed to load udisks support: %s\n", error); + return FALSE; +} + +/* ########## */ + +static LONG WINAPI assert_fault(EXCEPTION_POINTERS *eptr) +{ + if (eptr->ExceptionRecord->ExceptionCode == EXCEPTION_WINE_ASSERTION) + return EXCEPTION_EXECUTE_HANDLER; + return EXCEPTION_CONTINUE_SEARCH; +} + +/* ######################################### + * get_properties_from_iter [internal] + * + * NOTES + * format of args in a reply from GetAll: + * an ARRAY of DICT_ENTRY + * each DICT_ENTRY has a STRING (property name) and a VARIANT (property value) + * each VARIANT has a BOOLEAN or a STRING or an ARRAY of STRING or an here unused value + */ +static BOOL get_properties_from_iter(properties_t * p, DBusMessageIter * iter) +{ + DBusMessageIter sub; + int arg_type = p_dbus_message_iter_get_arg_type(iter); + + p->depth++; + while (arg_type != DBUS_TYPE_INVALID) + { + if ((arg_type == DBUS_TYPE_ARRAY) || + (arg_type == DBUS_TYPE_DICT_ENTRY) || + (arg_type == DBUS_TYPE_VARIANT)) + { + p_dbus_message_iter_recurse(iter, &sub); + if (!get_properties_from_iter(p, &sub)) + { + p->depth--; + return FALSE; + } + } + else if (arg_type == DBUS_TYPE_STRING) + { + char * data; + p_dbus_message_iter_get_basic(iter, &data); + if (p->depth == 3) p->last_name = data; + else if (p->last_name) + { + if (!strcmp(p->last_name, "DeviceFile")) + p->device_file = data; + else if (!strcmp(p->last_name, "DeviceMountPaths")) + p->device_mount_paths = data; /* use only the first entry */ + else if (!strcmp(p->last_name, "DriveMedia")) + p->drive_media = data; + else if (!strcmp(p->last_name, "DriveMediaCompatibility")) + p->drive_media_compatibility = data; /* use only the first entry */ + else if (!strcmp(p->last_name, "IdType")) + p->id_type = data; + else if (!strcmp(p->last_name, "IdUsage")) + p->id_usage = data; + else if (!strcmp(p->last_name, "IdUuid")) + p->id_uuid = data; + + p->last_name = NULL; + } + } + else if (arg_type == DBUS_TYPE_BOOLEAN) + { + dbus_bool_t data; + if (p->last_name) + { + p_dbus_message_iter_get_basic(iter, &data); + if (!strcmp(p->last_name, "DeviceIsMounted")) + p->device_is_mounted = data; + else if (!strcmp(p->last_name, "DeviceIsOpticalDisc")) + p->device_is_optical_disc = data; + else if (!strcmp(p->last_name, "DeviceIsRemovable")) + p->device_is_removable = data; + + p->last_name = NULL; + } + } + + p_dbus_message_iter_next(iter); + arg_type = p_dbus_message_iter_get_arg_type(iter); + } + p->depth--; + return TRUE; +} + +/* ########### */ + +static DBusMessage * get_properties_from_path(properties_t * p, DBusConnection *ctx, const char * path) +{ + DBusMessage *request; + DBusMessage *reply = NULL; + DBusMessageIter iter; + DBusError error; + + TRACE("(%p, %p, %s)\n", p, ctx, path); + + memset(p, 0, sizeof(properties_t)); + request = p_dbus_message_new_method_call(dest_udisks, path, iface_dbus_prop, "GetAll"); + if (request) + { + if (p_dbus_message_append_args(request, DBUS_TYPE_STRING, &dest_udisks_device, DBUS_TYPE_INVALID)) + { + p_dbus_error_init(&error); + if ((reply = p_dbus_connection_send_with_reply_and_block(ctx, request, -1, &error))) + { + p_dbus_message_iter_init(reply, &iter); + get_properties_from_iter(p, &iter); + } + else + WARN("no reply for %s\n", path); + + p_dbus_error_free(&error); + } + else + WARN("dbus_message_append_args failed for 'GetAll'\n"); + + p_dbus_message_unref(request); + } + return reply; +} + +/* ########### */ + +static int get_drive_type(properties_t * p) +{ + /* examples: optical_cd, optical_cd_rw, optical_dvd_plus_r_dl */ + if (p->device_is_optical_disc && p->drive_media && !memcmp(p->drive_media, "optical_", 8)) + { + if (!memcmp(p->drive_media + 8, "cd", 2)) + return DEVICE_CDROM; + else + return DEVICE_DVD; + } + else if (p->drive_media_compatibility && !strcmp(p->drive_media_compatibility, "floppy")) + return DEVICE_FLOPPY; + else if (!p->device_is_removable && p->id_usage && !strcmp(p->id_usage, "filesystem")) + return DEVICE_HARDDISK_VOL; + + return DEVICE_UNKNOWN; +} + +/* ########### */ + +static void udisks_add_device(DBusConnection *ctx, const char *path) +{ + DBusMessage *reply; + properties_t p; + GUID guid; + GUID *guid_ptr = NULL; + + TRACE("%s\n", debugstr_a(path)); + + reply = get_properties_from_path(&p, ctx, path); + if (reply) + { + int drive_type = get_drive_type(&p); + + TRACE("DeviceFile: %s\n", p.device_file); + TRACE("IdUsage: %s\n", p.id_usage); + TRACE("IdType: %s\n", p.id_type); + TRACE("IdUuid: %s\n", p.id_uuid); + TRACE("DeviceIsMounted: %d (%s)\n", p.device_is_mounted, p.device_is_mounted ? "true" : "false"); + TRACE("DeviceIsOpticalDisc: %d (%s)\n", p.device_is_optical_disc, p.device_is_optical_disc ? "true" : "false"); + TRACE("DeviceIsRemovable: %d (%s)\n", p.device_is_removable, p.device_is_removable ? "true" : "false"); + TRACE("DeviceMountPaths: %s\n", p.device_mount_paths); + TRACE("DriveMedia: %s\n", p.drive_media); + TRACE("DriveMediaCompatibility: %s\n", p.drive_media_compatibility); + TRACE("using drive_type: %d\n", drive_type); + + if (p.device_is_mounted && p.device_mount_paths) + { + if (p.id_uuid) + guid_ptr = parse_uuid(&guid, p.id_uuid); + + if (p.device_is_removable) + add_dos_device(-1, path, p.device_file, p.device_mount_paths, drive_type, guid_ptr); + else if (guid_ptr) + add_volume(path, p.device_file, p.device_mount_paths, DEVICE_HARDDISK_VOL, guid_ptr); + + } + p_dbus_message_unref(reply); + } +} + +static void udisks_remove_device(DBusConnection *ctx, const char *path) +{ + TRACE("%s\n", debugstr_a(path)); + + if (remove_dos_device(-1, path)) + remove_volume(path); +} + +static void udisks_change_device(DBusConnection *ctx, const char *path) +{ + DBusMessage *reply; + properties_t p; + + TRACE("%s\n", debugstr_a(path)); + + reply = get_properties_from_path(&p, ctx, path); + if (reply) + { + int drive_type = get_drive_type(&p); + + if (p.device_is_mounted && p.device_mount_paths) + udisks_add_device(ctx, path); + else + { + TRACE("DeviceFile: %s\n", p.device_file); + TRACE("IdUsage: %s\n", p.id_usage); + TRACE("IdType: %s\n", p.id_type); + TRACE("IdUuid: %s\n", p.id_uuid); + TRACE("DeviceIsMounted: %d (%s)\n", p.device_is_mounted, p.device_is_mounted ? "true" : "false"); + TRACE("DeviceIsOpticalDisc: %d (%s)\n", p.device_is_optical_disc, p.device_is_optical_disc ? "true" : "false"); + TRACE("DeviceIsRemovable: %d (%s)\n", p.device_is_removable, p.device_is_removable ? "true" : "false"); + TRACE("DeviceMountPaths: %s\n", p.device_mount_paths); + TRACE("DriveMedia: %s\n", p.drive_media); + TRACE("DriveMediaCompatibility: %s\n", p.drive_media_compatibility); + TRACE("using drive_type: %d\n", drive_type); + + udisks_remove_device(ctx, path); + } + p_dbus_message_unref(reply); + } +} + +/* ########### */ + +static void udisks_get_all_devices(DBusConnection *ctx) +{ + DBusMessage *request; + DBusMessage *reply; + DBusMessageIter iter; + DBusMessageIter sub; + DBusError error; + int arg_type; + + request = p_dbus_message_new_method_call(dest_udisks, path_udisks, dest_udisks, "EnumerateDevices"); + if (request) + { + p_dbus_error_init(&error); + if ((reply = p_dbus_connection_send_with_reply_and_block(ctx, request, -1, &error))) + { + p_dbus_message_iter_init(reply, &iter); + arg_type = p_dbus_message_iter_get_arg_type(&iter); + if (arg_type == DBUS_TYPE_ARRAY) + { + p_dbus_message_iter_recurse(&iter, &sub); + while ((arg_type = p_dbus_message_iter_get_arg_type(&sub)) == DBUS_TYPE_OBJECT_PATH) + { + char * data; + p_dbus_message_iter_get_basic(&sub, &data); + udisks_add_device(ctx, data); + p_dbus_message_iter_next(&sub); + } + } + else + WARN("expected ARRAY, got %c\n", arg_type); + + p_dbus_message_unref(reply); + } + p_dbus_error_free(&error); + p_dbus_message_unref(request); + } +} + +/* ########## */ + +static void udisks_get_version(DBusConnection *ctx) +{ + DBusMessage *request; + DBusMessage *reply; + DBusMessageIter iter; + DBusMessageIter sub; + DBusError error; + int arg_type; + + request = p_dbus_message_new_method_call(dest_udisks, path_udisks, iface_dbus_prop, "Get"); + if (request) + { + if (p_dbus_message_append_args(request, DBUS_TYPE_STRING, &dest_udisks, + DBUS_TYPE_STRING, &daemonversion, + DBUS_TYPE_INVALID)) + { + p_dbus_error_init(&error); + if ((reply = p_dbus_connection_send_with_reply_and_block(ctx, request, -1, &error))) + { + p_dbus_message_iter_init(reply, &iter); + arg_type = p_dbus_message_iter_get_arg_type(&iter); + if (arg_type == DBUS_TYPE_VARIANT) + { + p_dbus_message_iter_recurse(&iter, &sub); + arg_type = p_dbus_message_iter_get_arg_type(&sub); + if (arg_type == DBUS_TYPE_STRING) + { + char * data; + p_dbus_message_iter_get_basic(&sub, &data); + lstrcpynA(udisks_version, data, sizeof(udisks_version) - 1); + TRACE("found udisks daemon %s\n", udisks_version); + } + else + WARN("expected STRING, got %c\n", arg_type); + + } + else + WARN("expected VARIANT, got %c\n", arg_type); + + p_dbus_message_unref(reply); + } + p_dbus_error_free(&error); + } + else + WARN("dbus_message_append_args failed\n"); + + p_dbus_message_unref(request); + } + return; + +} + +/* ##### */ + +static DWORD WINAPI udisks_thread( void *arg ) +{ + DBusConnection *ctx; + DBusMessage *msg; + DBusMessageIter iter; + DBusError error; + const char *member; + int arg_type; + char *data; + + p_dbus_error_init(&error); + ctx = p_dbus_bus_get(DBUS_BUS_SYSTEM, &error); + + if (!ctx) + { + SetEvent(dbus_present); /* wakeup hal support */ + WARN("failed to get system dbus connection: %s\n", error.message); + p_dbus_error_free(&error); + return 1; + } + + p_dbus_bus_add_match(ctx, my_match_rule, &error); + if (p_dbus_error_is_set(&error)) + { + SetEvent(dbus_present); /* wakeup hal support */ + WARN("add dbus filter failed: %s\n", error.message); + p_dbus_error_free(&error); + p_dbus_connection_unref(ctx); + return 1; + } + + udisks_get_version(ctx); + SetEvent(dbus_present); /* wakeup hal support */ + + if (!*udisks_version) + { + TRACE("udisks service not available\n"); + p_dbus_bus_remove_match(ctx, my_match_rule, NULL); + p_dbus_error_free(&error); + p_dbus_connection_unref(ctx); + return 1; + } + + __TRY + { + /* retrieve all existing devices */ + udisks_get_all_devices(ctx); + + while (p_dbus_connection_read_write_dispatch(ctx, -1 )) + { + while ((msg = p_dbus_connection_pop_message(ctx))) + { + member = p_dbus_message_get_member(msg); + p_dbus_message_iter_init(msg, &iter); + arg_type = p_dbus_message_iter_get_arg_type(&iter); + + if (arg_type == DBUS_TYPE_OBJECT_PATH) + p_dbus_message_iter_get_basic(&iter, &data); + + if (!lstrcmpA(member, "DeviceChanged")) + udisks_change_device(ctx, data); + else if (!lstrcmpA(member, "DeviceAdded")) + udisks_add_device(ctx, data); + else if (!lstrcmpA(member, "DeviceRemoved")) + udisks_remove_device(ctx, data); + else if (lstrcmpA(member, "DeviceJobChanged")) + WARN("got signal for %s\n", member); + + p_dbus_message_unref(msg); + } + } + } + __EXCEPT(assert_fault) + { + WARN("dbus assertion failure, disabling UDisks support\n"); + return 1; + } + __ENDTRY; + + p_dbus_bus_remove_match(ctx, my_match_rule, NULL); + p_dbus_error_free(&error); + p_dbus_connection_unref(ctx); + return 0; +} + +void initialize_udisks(void) +{ + HANDLE handle = NULL; + + dbus_present = NULL; + *udisks_version = 0; + if (!load_dbus_functions()) return; + + /* delay hal support, start udisks thread */ + if (!(dbus_present = CreateEventW(NULL, TRUE, FALSE, NULL)) || + !(handle = CreateThread(NULL, 0, udisks_thread, NULL, 0, NULL))) + { + /* something failed: wakeup hal now */ + if (dbus_present) SetEvent(dbus_present); + return; + } + CloseHandle(handle); +} + +#else /* SONAME_LIBDBUS_1 */ + +void initialize_udisks(void) +{ + TRACE("Skipping, DBUS support not compiled in\n"); +} + +#endif /* SONAME_LIBDBUS_1 */ -- 1.7.5.4