Marcus Meissner
7fbe6c1757
- Support for multisampling in Direct3D. - New version of the Gecko engine. - Improvements to the network proxy handling. - Better write support in MSXML. - Side-by-side manifests for built-in libraries. - Various bug fixes. OBS-URL: https://build.opensuse.org/package/show/Emulators/wine?expand=0&rev=101
654 lines
22 KiB
Diff
654 lines
22 KiB
Diff
diff --git a/configure.ac b/configure.ac
|
|
index ae89108..3085136 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 */
|