Index: /trunk/src/VBox/Main/include/vbox-dbus-internal.h
===================================================================
--- /trunk/src/VBox/Main/include/vbox-dbus-internal.h	(revision 16178)
+++ /trunk/src/VBox/Main/include/vbox-dbus-internal.h	(revision 16178)
@@ -0,0 +1,101 @@
+/** @file
+ *
+ * Stubs for dynamically loading libdbus-1 and the symbols
+ * which are needed by VirtualBox.
+ */
+
+/*
+ * Copyright (C) 2008 Sun Microsystems, Inc.
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
+ * Clara, CA 95054 USA or visit http://www.sun.com if you need
+ * additional information or have any questions.
+ */
+
+#ifndef VBOX_PROXY_STUB
+#error This file is a private header, intended to be included in specific places only
+#endif
+
+/** The following are the symbols which we need from libdbus-1. */
+VBOX_PROXY_STUB(dbus_error_init, void, (DBusError *error),
+                (error))
+VBOX_PROXY_STUB(dbus_bus_get, DBusConnection *,
+                (DBusBusType type, DBusError *error), (type, error))
+VBOX_PROXY_STUB(dbus_bus_get_private, DBusConnection *,
+                (DBusBusType type, DBusError *error), (type, error))
+VBOX_PROXY_STUB(dbus_error_free, void, (DBusError *error),
+                (error))
+VBOX_PROXY_STUB(dbus_connection_unref, void, (DBusConnection *connection),
+                (connection))
+VBOX_PROXY_STUB(dbus_connection_close, void, (DBusConnection *connection),
+                (connection))
+VBOX_PROXY_STUB(dbus_connection_set_exit_on_disconnect, void,
+                (DBusConnection *connection, dbus_bool_t boolean),
+                (connection, boolean))
+VBOX_PROXY_STUB(dbus_bus_name_has_owner, dbus_bool_t,
+                (DBusConnection *connection, const char *string, DBusError *error),
+                (connection, string, error))
+VBOX_PROXY_STUB(dbus_bus_add_match, void,
+                (DBusConnection *connection, const char *string,
+                 DBusError *error),
+                (connection, string, error))
+VBOX_PROXY_STUB(dbus_bus_remove_match, void,
+                (DBusConnection *connection, const char *string,
+                 DBusError *error),
+                (connection, string, error))
+VBOX_PROXY_STUB(dbus_message_unref, void, (DBusMessage *message),
+                (message))
+VBOX_PROXY_STUB(dbus_message_new_method_call, DBusMessage*,
+                (const char *string1, const char *string2, const char *string3,
+                 const char *string4),
+                (string1, string2, string3, string4))
+VBOX_PROXY_STUB(dbus_message_iter_init_append, void,
+                (DBusMessage *message, DBusMessageIter *iter),
+                (message, iter))
+VBOX_PROXY_STUB(dbus_message_iter_append_basic, dbus_bool_t,
+                (DBusMessageIter *iter, int val, const void *string),
+                (iter, val, string))
+VBOX_PROXY_STUB(dbus_connection_send_with_reply_and_block, DBusMessage *,
+                (DBusConnection *connection, DBusMessage *message, int val,
+                 DBusError *error),
+                (connection, message, val, error))
+VBOX_PROXY_STUB(dbus_message_iter_init, dbus_bool_t,
+                (DBusMessage *message, DBusMessageIter *iter),
+                (message, iter))
+VBOX_PROXY_STUB(dbus_message_iter_get_arg_type, int, (DBusMessageIter *iter),
+                (iter))
+VBOX_PROXY_STUB(dbus_message_iter_get_element_type, int,
+                (DBusMessageIter *iter), (iter))
+VBOX_PROXY_STUB(dbus_message_iter_recurse, void,
+                (DBusMessageIter *iter1, DBusMessageIter *iter2),
+                (iter1, iter2))
+VBOX_PROXY_STUB(dbus_message_iter_get_basic, void,
+                (DBusMessageIter *iter, void *pvoid), (iter, pvoid))
+VBOX_PROXY_STUB(dbus_message_iter_next, dbus_bool_t, (DBusMessageIter *iter),
+                (iter))
+VBOX_PROXY_STUB(dbus_connection_add_filter, dbus_bool_t,
+                (DBusConnection *connection,
+                 DBusHandleMessageFunction function1, void *pvoid,
+                 DBusFreeFunction function2),
+                (connection, function1, pvoid, function2))
+VBOX_PROXY_STUB(dbus_connection_remove_filter, void,
+                (DBusConnection *connection,
+                 DBusHandleMessageFunction function, void *pvoid),
+                (connection, function, pvoid))
+VBOX_PROXY_STUB(dbus_connection_read_write_dispatch, dbus_bool_t,
+                (DBusConnection *connection, int val), (connection, val))
+VBOX_PROXY_STUB(dbus_message_is_signal, dbus_bool_t,
+                (DBusMessage *message, const char *string1,
+                 const char *string2),
+                (message, string1, string2))
+VBOX_PROXY_STUB(dbus_connection_pop_message, DBusMessage *,
+                (DBusConnection *connection), (connection))
+
Index: /trunk/src/VBox/Main/include/vbox-dbus.h
===================================================================
--- /trunk/src/VBox/Main/include/vbox-dbus.h	(revision 16177)
+++ /trunk/src/VBox/Main/include/vbox-dbus.h	(revision 16178)
@@ -26,6 +26,6 @@
 #include <stdint.h>
 
-#define LIB_DBUS_1_2 "libdbus-1.so.2"  /* This should be compatible */
-#define LIB_DBUS_1_3 "libdbus-1.so.3"
+#define VBOX_DBUS_1_2_LIB "libdbus-1.so.2"  /* This should be compatible */
+#define VBOX_DBUS_1_3_LIB "libdbus-1.so.3"
 
 /** Types and defines from the dbus header files which we need.  These are
@@ -85,112 +85,20 @@
 typedef void (*DBusFreeFunction) (void *);
 
-/** The following are the symbols which we need from libdbus-1. */
-extern void (*vbox_dbus_error_init)(DBusError *);
-inline void dbus_error_init(DBusError *error)
-{ vbox_dbus_error_init(error); }
-extern DBusConnection *(*vbox_dbus_bus_get)(DBusBusType, DBusError *);
-inline DBusConnection *dbus_bus_get(DBusBusType type, DBusError *error)
-{ return vbox_dbus_bus_get(type, error); }
-extern DBusConnection *(*vbox_dbus_bus_get_private)(DBusBusType, DBusError *);
-inline DBusConnection *dbus_bus_get_private(DBusBusType type, DBusError *error)
-{ return vbox_dbus_bus_get_private(type, error); }
-extern void (*vbox_dbus_error_free)(DBusError *);
-inline void dbus_error_free(DBusError *error)
-{ vbox_dbus_error_free(error); }
-extern void (*vbox_dbus_connection_unref)(DBusConnection *);
-inline void dbus_connection_unref(DBusConnection *connection)
-{ vbox_dbus_connection_unref(connection); }
-extern void (*vbox_dbus_connection_close)(DBusConnection *);
-inline void dbus_connection_close(DBusConnection *connection)
-{ vbox_dbus_connection_close(connection); }
-extern void (*vbox_dbus_connection_set_exit_on_disconnect)(DBusConnection *, dbus_bool_t);
-inline void dbus_connection_set_exit_on_disconnect(DBusConnection *connection, dbus_bool_t boolean)
-{ vbox_dbus_connection_set_exit_on_disconnect(connection, boolean); }
-extern dbus_bool_t (*vbox_dbus_bus_name_has_owner)(DBusConnection *, const char *,
-                                                   DBusError *);
-inline dbus_bool_t dbus_bus_name_has_owner(DBusConnection *connection, const char *string,
-                                                   DBusError *error)
-{ return vbox_dbus_bus_name_has_owner(connection, string, error); }
-extern void (*vbox_dbus_bus_add_match)(DBusConnection *, const char *, DBusError *);
-inline void dbus_bus_add_match(DBusConnection *connection, const char *string, DBusError *error)
-{ vbox_dbus_bus_add_match(connection, string, error); }
-extern void (*vbox_dbus_bus_remove_match)(DBusConnection *, const char *, DBusError *);
-inline void dbus_bus_remove_match(DBusConnection *connection, const char *string, DBusError *error)
-{ vbox_dbus_bus_remove_match(connection, string, error); }
-extern void (*vbox_dbus_message_unref)(DBusMessage *);
-inline void dbus_message_unref(DBusMessage *message)
-{ vbox_dbus_message_unref(message); }
-extern DBusMessage* (*vbox_dbus_message_new_method_call)(const char *, const char *,
-                                                         const char *, const char *);
-inline DBusMessage* dbus_message_new_method_call(const char *string1, const char *string2,
-                                                         const char *string3, const char *string4)
-{ return vbox_dbus_message_new_method_call(string1, string2, string3, string4); }
-extern void (*vbox_dbus_message_iter_init_append)(DBusMessage *, DBusMessageIter *);
-inline void dbus_message_iter_init_append(DBusMessage *message, DBusMessageIter *iter)
-{ vbox_dbus_message_iter_init_append(message, iter); }
-extern dbus_bool_t (*vbox_dbus_message_iter_append_basic)(DBusMessageIter *, int,
-                                                          const void *);
-inline dbus_bool_t dbus_message_iter_append_basic(DBusMessageIter *iter, int val,
-                                                          const void *string)
-{ return vbox_dbus_message_iter_append_basic(iter, val, string); }
-extern DBusMessage * (*vbox_dbus_connection_send_with_reply_and_block)(DBusConnection *,
-                                                                       DBusMessage *, int,
-                                                                       DBusError *error);
-inline DBusMessage * dbus_connection_send_with_reply_and_block(DBusConnection *connection,
-                                                               DBusMessage *message, int val,
-                                                               DBusError *error)
-{ return vbox_dbus_connection_send_with_reply_and_block(connection, message, val, error); }
-extern dbus_bool_t (*vbox_dbus_message_iter_init) (DBusMessage *, DBusMessageIter *);
-inline dbus_bool_t dbus_message_iter_init(DBusMessage *message, DBusMessageIter *iter)
-{ return vbox_dbus_message_iter_init(message, iter); }
-extern int (*vbox_dbus_message_iter_get_arg_type) (DBusMessageIter *);
-inline int dbus_message_iter_get_arg_type(DBusMessageIter *iter)
-{ return vbox_dbus_message_iter_get_arg_type(iter); }
-extern int (*vbox_dbus_message_iter_get_element_type) (DBusMessageIter *);
-inline int dbus_message_iter_get_element_type(DBusMessageIter *iter)
-{ return vbox_dbus_message_iter_get_element_type(iter); }
-extern void (*vbox_dbus_message_iter_recurse) (DBusMessageIter *, DBusMessageIter *);
-inline void dbus_message_iter_recurse(DBusMessageIter *iter1, DBusMessageIter *iter2)
-{ vbox_dbus_message_iter_recurse(iter1, iter2); }
-extern void (*vbox_dbus_message_iter_get_basic) (DBusMessageIter *, void *);
-inline void dbus_message_iter_get_basic(DBusMessageIter *iter, void *pvoid)
-{ vbox_dbus_message_iter_get_basic(iter, pvoid); }
-extern dbus_bool_t (*vbox_dbus_message_iter_next) (DBusMessageIter *);
-inline dbus_bool_t dbus_message_iter_next(DBusMessageIter *iter)
-{ return vbox_dbus_message_iter_next(iter); }
-extern dbus_bool_t (*vbox_dbus_connection_add_filter) (DBusConnection *, DBusHandleMessageFunction,
-                                                       void *, DBusFreeFunction);
-inline dbus_bool_t dbus_connection_add_filter(DBusConnection *connection,
-                                              DBusHandleMessageFunction function1,
-                                              void *pvoid, DBusFreeFunction function2)
-{ return vbox_dbus_connection_add_filter(connection, function1, pvoid, function2); }
-extern void (*vbox_dbus_connection_remove_filter) (DBusConnection *, DBusHandleMessageFunction,
-                                                   void *);
-inline void dbus_connection_remove_filter(DBusConnection *connection,
-                                          DBusHandleMessageFunction function, void *pvoid)
-{ vbox_dbus_connection_remove_filter(connection, function, pvoid); }
-extern dbus_bool_t (*vbox_dbus_connection_read_write_dispatch) (DBusConnection *, int);
-inline dbus_bool_t dbus_connection_read_write_dispatch(DBusConnection *connection, int val)
-{ return vbox_dbus_connection_read_write_dispatch(connection, val); }
-extern dbus_bool_t (*vbox_dbus_message_is_signal) (DBusMessage *, const char *, const char *);
-inline dbus_bool_t dbus_message_is_signal(DBusMessage *message, const char *string1, const char *string2)
-{ return vbox_dbus_message_is_signal(message, string1, string2); }
-extern DBusMessage *(*vbox_dbus_connection_pop_message)(DBusConnection *);
-inline DBusMessage *dbus_connection_pop_message(DBusConnection *connection)
-{ return vbox_dbus_connection_pop_message(connection); }
+/* Declarations of the functions that we need from libdbus-1 */
+#define VBOX_PROXY_STUB(function, rettype, signature, shortsig) \
+extern rettype ( function ) signature ;
+
+#include "vbox-dbus-internal.h"
+
+#undef VBOX_PROXY_STUB
 
 /**
- * Checks whether libdbus is present and if so loads all symbols we need.  This
- * should be called before making any calls to libdbus if that library is being
- * loaded at runtime.
- * @returns true if libdbus was found, false otherwise.
+ * Try to dynamically load the DBus library.  This function should be called
+ * before attempting to use any of the DBus functions.  It is safe to call this
+ * function multiple times.
+ *
+ * @returns iprt status code
  */
-extern bool VBoxDBusCheckPresence(void);
-/** Wrapper around dbus_connection_unref.  We need this to use it as a free
- * function in auto pointers, as a function pointer won't wash here. */
-extern void VBoxDBusConnectionUnref(DBusConnection *pConnection);
-/** Wrapper around dbus_message_unref.  We need this to use it as a free
- * function in auto pointers, as a function pointer won't wash here. */
-extern void VBoxDBusMessageUnref(DBusMessage *pMessage);
+extern int VBoxLoadDBusLib(void);
 
 #endif /* ____H_VBOX_DBUS not defined */
Index: /trunk/src/VBox/Main/linux/HostHardwareLinux.cpp
===================================================================
--- /trunk/src/VBox/Main/linux/HostHardwareLinux.cpp	(revision 16177)
+++ /trunk/src/VBox/Main/linux/HostHardwareLinux.cpp	(revision 16178)
@@ -79,4 +79,7 @@
 extern void VBoxHalShutdown (DBusConnection *pConnection);
 extern void VBoxHalShutdownPrivate (DBusConnection *pConnection);
+extern void VBoxDBusConnectionUnref(DBusConnection *pConnection);
+extern void VBoxDBusConnectionCloseAndUnref(DBusConnection *pConnection);
+extern void VBoxDBusMessageUnref(DBusMessage *pMessage);
 
 static int halInit(RTMemAutoPtr <DBusConnection, VBoxHalShutdown> *pConnection);
@@ -109,5 +112,5 @@
 #if defined(RT_OS_LINUX)
 #ifdef VBOX_WITH_DBUS
-        if (RT_SUCCESS (rc) && VBoxDBusCheckPresence() && (!success || testing()))
+        if (RT_SUCCESS (rc) && RT_SUCCESS(VBoxLoadDBusLib()) && (!success || testing()))
             rc = getDriveInfoFromHal(&mDVDList, true /* isDVD */, &success);
 #endif /* VBOX_WITH_DBUS defined */
@@ -154,5 +157,7 @@
 #if defined(RT_OS_LINUX)
 #ifdef VBOX_WITH_DBUS
-        if (RT_SUCCESS (rc) && VBoxDBusCheckPresence() && (!success || testing()))
+        if (   RT_SUCCESS (rc)
+            && RT_SUCCESS(VBoxLoadDBusLib())
+            && (!success || testing()))
             rc = getDriveInfoFromHal(&mFloppyList, false /* isDVD */, &success);
 #endif /* VBOX_WITH_DBUS defined */
@@ -197,5 +202,7 @@
 #if defined(RT_OS_LINUX)
 #ifdef VBOX_WITH_DBUS
-        if (RT_SUCCESS (rc) && VBoxDBusCheckPresence() && (!success || testing()))
+        if (   RT_SUCCESS (rc)
+            && RT_SUCCESS(VBoxLoadDBusLib())
+            && (!success || testing()))
             rc = getUSBDeviceInfoFromHal(&mDeviceList, &halSuccess);
         /* Try the old API if the new one *succeeded* as only one of them will
@@ -226,4 +233,6 @@
     /** A flag to say that we wish to interrupt the current wait. */
     bool mInterrupt;
+    /** Constructor */
+    Context() : mTriggered(false), mInterrupt(false) {}
 #endif  /* defined RT_OS_LINUX && defined VBOX_WITH_DBUS */
 };
@@ -238,7 +247,7 @@
     int rc = VINF_SUCCESS;
 
-    if (VBoxDBusCheckPresence())
-    {
-        mContext = new Context;
+    mContext = new Context;
+    if (RT_SUCCESS(VBoxLoadDBusLib()))
+    {
         for (unsigned i = 0; RT_SUCCESS(rc) && i < 5 && !mContext->mConnection; ++i)
         {
@@ -617,5 +626,5 @@
     autoDBusError dbusError;
 
-    RTMemAutoPtr <DBusConnection, VBoxDBusConnectionUnref> dbusConnection;
+    RTMemAutoPtr <DBusConnection, VBoxDBusConnectionCloseAndUnref> dbusConnection;
     dbusConnection = dbus_bus_get_private (DBUS_BUS_SYSTEM, &dbusError.get());
     if (!dbusConnection)
@@ -650,5 +659,5 @@
  * @param   pConnection  the connection handle
  */
-/* static */
+/* extern */
 void VBoxHalShutdown (DBusConnection *pConnection)
 {
@@ -672,5 +681,5 @@
  * @param   pConnection  the connection handle
  */
-/* static */
+/* extern */
 void VBoxHalShutdownPrivate (DBusConnection *pConnection)
 {
@@ -689,4 +698,31 @@
     LogFlowFunc(("returning\n"));
     dbusError.FlowLog();
+}
+
+/** Wrapper around dbus_connection_unref.  We need this to use it as a real
+ * function in auto pointers, as a function pointer won't wash here. */
+/* extern */
+void VBoxDBusConnectionUnref(DBusConnection *pConnection)
+{
+    dbus_connection_unref(pConnection);
+}
+
+/**
+ * This function closes and unrefs a private connection to dbus.  It should
+ * only be called once no-one else is referencing the connection.
+ */
+/* extern */
+void VBoxDBusConnectionCloseAndUnref(DBusConnection *pConnection)
+{
+    dbus_connection_close(pConnection);
+    dbus_connection_unref(pConnection);
+}
+
+/** Wrapper around dbus_message_unref.  We need this to use it as a real
+ * function in auto pointers, as a function pointer won't wash here. */
+/* extern */
+void VBoxDBusMessageUnref(DBusMessage *pMessage)
+{
+    dbus_message_unref(pMessage);
 }
 
Index: /trunk/src/VBox/Main/linux/vbox-dbus.cpp
===================================================================
--- /trunk/src/VBox/Main/linux/vbox-dbus.cpp	(revision 16177)
+++ /trunk/src/VBox/Main/linux/vbox-dbus.cpp	(revision 16178)
@@ -23,142 +23,68 @@
 #include "vbox-dbus.h"
 
-#include <iprt/err.h>
+#define LOG_GROUP LOG_GROUP_MAIN
+#include <VBox/log.h>
+#include <VBox/err.h>
+
 #include <iprt/ldr.h>
-
-/**
- * Whether we have tried to load libdbus-1 yet.  This flag should only be set
- * to "true" after we have either loaded the library and all symbols which we
- * need, or failed to load something and unloaded and set back to zero
- * pLibDBus.
- */
-static bool gCheckedForLibDBus = false;
-/**
- * Pointer to the libdbus-1 shared object.  This should only be set once all
- * needed libraries and symbols have been successfully loaded.
- */
-static RTLDRMOD ghLibDBus = NULL;
+#include <iprt/assert.h>
+#include <iprt/once.h>
 
 /** The following are the symbols which we need from libdbus. */
-void (*vbox_dbus_error_init)(DBusError *);
-DBusConnection *(*vbox_dbus_bus_get)(DBusBusType, DBusError *);
-DBusConnection *(*vbox_dbus_bus_get_private)(DBusBusType, DBusError *);
-void (*vbox_dbus_error_free)(DBusError *);
-void (*vbox_dbus_connection_unref)(DBusConnection *);
-void (*vbox_dbus_connection_close)(DBusConnection *);
-void (*vbox_dbus_connection_set_exit_on_disconnect)(DBusConnection *, dbus_bool_t);
-dbus_bool_t (*vbox_dbus_bus_name_has_owner)(DBusConnection *, const char *,
-                                            DBusError *);
-void (*vbox_dbus_bus_add_match)(DBusConnection *, const char *, DBusError *);
-void (*vbox_dbus_bus_remove_match)(DBusConnection *, const char *, DBusError *);
-void (*vbox_dbus_message_unref)(DBusMessage *);
-DBusMessage* (*vbox_dbus_message_new_method_call)(const char *, const char *,
-                                                  const char *, const char *);
-void (*vbox_dbus_message_iter_init_append)(DBusMessage *, DBusMessageIter *);
-dbus_bool_t (*vbox_dbus_message_iter_append_basic)(DBusMessageIter *, int,
-                                                   const void *);
-DBusMessage * (*vbox_dbus_connection_send_with_reply_and_block)(DBusConnection *,
-                                                                DBusMessage *, int,
-                                                                DBusError *error);
-dbus_bool_t (*vbox_dbus_message_iter_init) (DBusMessage *, DBusMessageIter *);
-int (*vbox_dbus_message_iter_get_arg_type) (DBusMessageIter *);
-int (*vbox_dbus_message_iter_get_element_type) (DBusMessageIter *);
-void (*vbox_dbus_message_iter_recurse) (DBusMessageIter *, DBusMessageIter *);
-void (*vbox_dbus_message_iter_get_basic) (DBusMessageIter *, void *);
-dbus_bool_t (*vbox_dbus_message_iter_next) (DBusMessageIter *);
-dbus_bool_t (*vbox_dbus_connection_add_filter) (DBusConnection *, DBusHandleMessageFunction,
-                                                void *, DBusFreeFunction);
-void (*vbox_dbus_connection_remove_filter) (DBusConnection *, DBusHandleMessageFunction,
-                                            void *);
-dbus_bool_t (*vbox_dbus_connection_read_write_dispatch) (DBusConnection *, int);
-dbus_bool_t (*vbox_dbus_message_is_signal) (DBusMessage *, const char *, const char *);
-DBusMessage *(*vbox_dbus_connection_pop_message)(DBusConnection *);
+#define VBOX_PROXY_STUB(function, rettype, signature, shortsig) \
+void (*function ## _fn)(void); \
+rettype function signature \
+{ return ( (rettype (*) signature) function ## _fn ) shortsig; }
 
-bool VBoxDBusCheckPresence(void)
+#include "vbox-dbus-internal.h"
+
+static int32_t loadDBusLibOnce(void *, void *);
+
+#undef VBOX_PROXY_STUB
+
+/* Now comes a table of functions to be loaded from libdbus-1 */
+typedef struct
 {
-    RTLDRMOD hLibDBus;
+    const char *name;
+    void (**fn)(void);
+} SHARED_FUNC;
 
-    if (ghLibDBus != 0 && gCheckedForLibDBus == true)
-        return true;
-    if (gCheckedForLibDBus == true)
-        return false;
-    if (   !RT_SUCCESS(RTLdrLoad(LIB_DBUS_1_3, &hLibDBus))
-        && !RT_SUCCESS(RTLdrLoad(LIB_DBUS_1_2, &hLibDBus)))
-    {
-        return false;
-    }
-    if (   RT_SUCCESS(RTLdrGetSymbol(hLibDBus, "dbus_error_init",
-                                     (void **) &vbox_dbus_error_init))
-        && RT_SUCCESS(RTLdrGetSymbol(hLibDBus, "dbus_bus_get",
-                                     (void **) &vbox_dbus_bus_get))
-        && RT_SUCCESS(RTLdrGetSymbol(hLibDBus, "dbus_bus_get_private",
-                                     (void **) &vbox_dbus_bus_get_private))
-        && RT_SUCCESS(RTLdrGetSymbol(hLibDBus, "dbus_error_free",
-                                     (void **) &vbox_dbus_error_free))
-        && RT_SUCCESS(RTLdrGetSymbol(hLibDBus, "dbus_connection_unref",
-                                     (void **) &vbox_dbus_connection_unref))
-        && RT_SUCCESS(RTLdrGetSymbol(hLibDBus, "dbus_connection_close",
-                                     (void **) &vbox_dbus_connection_close))
-        && RT_SUCCESS(RTLdrGetSymbol(hLibDBus, "dbus_connection_set_exit_on_disconnect",
-                                     (void **) &vbox_dbus_connection_set_exit_on_disconnect))
-        && RT_SUCCESS(RTLdrGetSymbol(hLibDBus, "dbus_bus_name_has_owner",
-                                     (void **) &vbox_dbus_bus_name_has_owner))
-        && RT_SUCCESS(RTLdrGetSymbol(hLibDBus, "dbus_bus_add_match",
-                                     (void **) &vbox_dbus_bus_add_match))
-        && RT_SUCCESS(RTLdrGetSymbol(hLibDBus, "dbus_bus_remove_match",
-                                     (void **) &vbox_dbus_bus_remove_match))
-        && RT_SUCCESS(RTLdrGetSymbol(hLibDBus, "dbus_message_unref",
-                                     (void **) &vbox_dbus_message_unref))
-        && RT_SUCCESS(RTLdrGetSymbol(hLibDBus, "dbus_message_new_method_call",
-                                     (void **) &vbox_dbus_message_new_method_call))
-        && RT_SUCCESS(RTLdrGetSymbol(hLibDBus, "dbus_message_iter_init_append",
-                                     (void **) &vbox_dbus_message_iter_init_append))
-        && RT_SUCCESS(RTLdrGetSymbol(hLibDBus, "dbus_message_iter_append_basic",
-                                     (void **) &vbox_dbus_message_iter_append_basic))
-        && RT_SUCCESS(RTLdrGetSymbol(hLibDBus, "dbus_connection_send_with_reply_and_block",
-                                     (void **) &vbox_dbus_connection_send_with_reply_and_block))
-        && RT_SUCCESS(RTLdrGetSymbol(hLibDBus, "dbus_message_iter_init",
-                                     (void **) &vbox_dbus_message_iter_init))
-        && RT_SUCCESS(RTLdrGetSymbol(hLibDBus, "dbus_message_iter_get_arg_type",
-                                     (void **) &vbox_dbus_message_iter_get_arg_type))
-        && RT_SUCCESS(RTLdrGetSymbol(hLibDBus, "dbus_message_iter_get_element_type",
-                                     (void **) &vbox_dbus_message_iter_get_element_type))
-        && RT_SUCCESS(RTLdrGetSymbol(hLibDBus, "dbus_message_iter_recurse",
-                                     (void **) &vbox_dbus_message_iter_recurse))
-        && RT_SUCCESS(RTLdrGetSymbol(hLibDBus, "dbus_message_iter_get_basic",
-                                     (void **) &vbox_dbus_message_iter_get_basic))
-        && RT_SUCCESS(RTLdrGetSymbol(hLibDBus, "dbus_message_iter_next",
-                                     (void **) &vbox_dbus_message_iter_next))
-        && RT_SUCCESS(RTLdrGetSymbol(hLibDBus, "dbus_connection_add_filter",
-                                     (void **) &vbox_dbus_connection_add_filter))
-        && RT_SUCCESS(RTLdrGetSymbol(hLibDBus, "dbus_connection_remove_filter",
-                                     (void **) &vbox_dbus_connection_remove_filter))
-        && RT_SUCCESS(RTLdrGetSymbol(hLibDBus, "dbus_connection_read_write_dispatch",
-                                     (void **) &vbox_dbus_connection_read_write_dispatch))
-        && RT_SUCCESS(RTLdrGetSymbol(hLibDBus, "dbus_message_is_signal",
-                                     (void **) &vbox_dbus_message_is_signal))
-        && RT_SUCCESS(RTLdrGetSymbol(hLibDBus, "dbus_connection_pop_message",
-                                     (void **) &vbox_dbus_connection_pop_message))
-       )
-    {
-        ghLibDBus = hLibDBus;
-        gCheckedForLibDBus = true;
-        return true;
-    }
-    else
-    {
-        RTLdrClose(hLibDBus);
-        gCheckedForLibDBus = true;
-        return false;
-    }
+#define VBOX_PROXY_STUB(s, dummy1, dummy2, dummy3 ) { #s , & s ## _fn } ,
+static SHARED_FUNC SharedFuncs[] =
+{
+#include "vbox-dbus-internal.h"
+    { NULL, NULL }
+};
+#undef VBOX_PROXY_STUB
+
+/* extern */
+int VBoxLoadDBusLib(void)
+{
+    static RTONCE sOnce = RTONCE_INITIALIZER;
+
+    LogFlowFunc(("\n"));
+    int rc = RTOnce (&sOnce, loadDBusLibOnce, NULL, NULL);
+    LogFlowFunc(("rc = %Rrc\n", rc));
+    return rc;
 }
 
-void VBoxDBusConnectionUnref(DBusConnection *pConnection)
+/* The function which does the actual work for VBoxLoadDBusLib, serialised for
+ * thread safety. */
+static int32_t loadDBusLibOnce(void *, void *)
 {
-    dbus_connection_unref(pConnection);
+    int rc = VINF_SUCCESS;
+    RTLDRMOD hLib;
+
+    LogFlowFunc(("\n"));
+    rc = RTLdrLoad(VBOX_DBUS_1_2_LIB, &hLib);
+    if (RT_FAILURE(rc))
+        rc = RTLdrLoad(VBOX_DBUS_1_3_LIB, &hLib);
+    if (RT_FAILURE(rc))
+        LogRelFunc(("Failed to load library %s or %s\n",
+                    VBOX_DBUS_1_2_LIB, VBOX_DBUS_1_3_LIB));
+    for (unsigned i = 0; RT_SUCCESS(rc) && SharedFuncs[i].name != NULL; ++i)
+        rc = RTLdrGetSymbol(hLib, SharedFuncs[i].name, (void**)SharedFuncs[i].fn);
+    LogFlowFunc(("rc = %Rrc\n", rc));
+    return rc;
 }
 
-void VBoxDBusMessageUnref(DBusMessage *pMessage)
-{
-    dbus_message_unref(pMessage);
-}
-
Index: /trunk/src/VBox/Main/testcase/tstHostHardwareLinux.cpp
===================================================================
--- /trunk/src/VBox/Main/testcase/tstHostHardwareLinux.cpp	(revision 16177)
+++ /trunk/src/VBox/Main/testcase/tstHostHardwareLinux.cpp	(revision 16178)
@@ -36,4 +36,5 @@
 #include <errno.h>
 #include <string.h>
+#include <stdlib.h>
 
 int main()
@@ -133,7 +134,15 @@
     RTPrintf ("Waiting for hotplug events.  Note that DBus often seems to deliver duplicate events in close succession.\n");
     RTPrintf ("Waiting for a hotplug event for five seconds...\n");
-    waiter.Wait (5000);
+    if (RT_FAILURE(waiter.Wait (5000)))
+    {
+        RTPrintf("Failed!\n");
+        exit(1);
+    }
     RTPrintf ("Waiting for a hotplug event, Ctrl-C to abort...\n");
-    waiter.Wait(RT_INDEFINITE_WAIT);
+    if (RT_FAILURE(waiter.Wait(RT_INDEFINITE_WAIT)))
+    {
+        RTPrintf("Failed!\n");
+        exit(1);
+    }    
 #endif  /* VBOX_USB_WITH_SYSFS */
     return 0;
