[PATCH] mountmgr: Support the dbus service udisks for dynamic devices :-) [try 5]

Detlef Riekenberg wine.dev at web.de
Mon Aug 15 18:36:50 CDT 2011


This Patch allow the libhal requirement on linux to die.

Recent distributions depend on udisks, so the libhal development package
should be uninstalled or disabled when building Wine (--without-hal).

libhal support is still present for old OS without udisks support.

The logic to add/remove the devices/volumes is the same as present in
our libhal support.

autoheader/autoconf are needed before compilation

try 5
As requested by julliard, not moving around the parse_uuid helper and
no sync between hal support and udisks support.

try 4
sync to current git (wineesd was removed)

try 3:
changes for configure.ac where missing in try 2

try 2:
remove a trailing space in the code an a trailing " \" in Makefile.in

--
By by ... Detlef
---
 configure.ac                  |   20 ++-
 dlls/mountmgr.sys/Makefile.in |    5 +-
 dlls/mountmgr.sys/mountmgr.c  |    2 +
 dlls/mountmgr.sys/mountmgr.h  |    1 +
 dlls/mountmgr.sys/udisks.c    |  556 +++++++++++++++++++++++++++++++++++++++++
 5 files changed, 581 insertions(+), 3 deletions(-)
 create mode 100644 dlls/mountmgr.sys/udisks.c

diff --git a/configure.ac b/configure.ac
index e6bbb2a..09eb1c6 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(fontconfig,AS_HELP_STRING([--without-fontconfig],[do not use fontconfig]),
             [if test "x$withval" = "xno"; then ac_cv_header_fontconfig_fontconfig_h=no; fi])
 AC_ARG_WITH(freetype,  AS_HELP_STRING([--without-freetype],[do not use the FreeType library]))
@@ -1201,6 +1202,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"
@@ -1221,7 +1239,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..f3355e0 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/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 a47a3e3..7d07b45 100644
--- a/dlls/mountmgr.sys/mountmgr.h
+++ b/dlls/mountmgr.sys/mountmgr.h
@@ -35,6 +35,7 @@
 #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;
 
diff --git a/dlls/mountmgr.sys/udisks.c b/dlls/mountmgr.sys/udisks.c
new file mode 100644
index 0000000..6b7fe13
--- /dev/null
+++ b/dlls/mountmgr.sys/udisks.c
@@ -0,0 +1,556 @@
+/*
+ * 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 <assert.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/time.h>
+
+#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);
+
+
+static char udisks_version[32];
+
+#ifdef SONAME_LIBDBUS_1
+
+#include <dbus/dbus.h>
+
+/* ########## */
+
+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 GUID *parse_uuid( GUID *guid, const char *str )
+{
+    /* standard uuid format */
+    if (strlen(str) == 36)
+    {
+        UNICODE_STRING strW;
+        WCHAR buffer[39];
+
+        if (MultiByteToWideChar( CP_UNIXCP, 0, str, 36, buffer + 1, 36 ))
+        {
+            buffer[0] = '{';
+            buffer[37] = '}';
+            buffer[38] = 0;
+            RtlInitUnicodeString( &strW, buffer );
+            if (!RtlGUIDFromString( &strW, guid )) return guid;
+        }
+    }
+
+    /* check for xxxx-xxxx format (FAT serial number) */
+    if (strlen(str) == 9 && str[4] == '-')
+    {
+        memset( guid, 0, sizeof(*guid) );
+        if (sscanf( str, "%hx-%hx", &guid->Data2, &guid->Data3 ) == 2) return guid;
+    }
+    return NULL;
+}
+
+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)
+    {
+        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))
+    {
+        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);
+
+    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;
+
+    if (!load_dbus_functions()) return;
+    if (!(handle = CreateThread(NULL, 0, udisks_thread, NULL, 0, NULL))) 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




More information about the wine-patches mailing list