Index: trunk/src/VBox/Main/HostDVDDriveImpl.cpp
===================================================================
--- trunk/src/VBox/Main/HostDVDDriveImpl.cpp	(revision 2853)
+++ trunk/src/VBox/Main/HostDVDDriveImpl.cpp	(revision 2917)
@@ -52,4 +52,23 @@
 }
 
+/**
+ * Initializes the host object.
+ *
+ * @returns COM result indicator
+ * @param driveName        name of the drive
+ * @param driveDescription human readable description of the drive
+ */
+HRESULT HostDVDDrive::init (INPTR BSTR driveName, INPTR BSTR driveDescription)
+{
+    ComAssertRet (driveName, E_INVALIDARG);
+    ComAssertRet (driveDescription, E_INVALIDARG);
+
+    AutoLock lock(this);
+    mDriveName = driveName;
+    mDriveDescription = driveDescription;
+    setReady(true);
+    return S_OK;
+}
+
 // IHostDVDDrive properties
 /////////////////////////////////////////////////////////////////////////////
@@ -70,2 +89,18 @@
     return S_OK;
 }
+
+/**
+ * Returns the description of the host drive
+ *
+ * @returns COM status code
+ * @param driveDescription address of result pointer
+ */
+STDMETHODIMP HostDVDDrive::COMGETTER(Description) (BSTR *driveDescription)
+{
+    if (!driveDescription)
+        return E_POINTER;
+    AutoLock lock(this);
+    CHECK_READY();
+    mDriveDescription.cloneTo(driveDescription);
+    return S_OK;
+}
Index: trunk/src/VBox/Main/HostImpl.cpp
===================================================================
--- trunk/src/VBox/Main/HostImpl.cpp	(revision 2853)
+++ trunk/src/VBox/Main/HostImpl.cpp	(revision 2917)
@@ -31,4 +31,10 @@
 #define _LINUX_BYTEORDER_GENERIC_H
 #include <linux/cdrom.h>
+#ifdef VBOX_USE_LIBHAL
+# include <libhal.h>
+/* These are defined by libhal.h and by VBox header files. */
+# undef TRUE
+# undef FALSE
+#endif
 #include <errno.h>
 #endif /* __LINUX __ */
@@ -190,45 +196,49 @@
     delete[] hostDrives;
 #elif defined(__LINUX__)
-    // On Linux, the situation is much more complex. There is no simple API so
-    // we will take a more creative approach. As there is only a heuristical
-    // approach on Linux, we'll allow the user to specify a list of host CDROMs
-    // using and an environment variable.
+#ifdef VBOX_USE_LIBHAL
+    if (!getDVDInfoFromHal(list)) /* Playing with #defines in this way is nasty, I know. */
+#endif /* USE_LIBHAL defined */
+    // On Linux without hal, the situation is much more complex. We will take a
+    // heuristical approach and also allow the user to specify a list of host
+    // CDROMs using an environment variable.
     // The general strategy is to try some known device names and see of they
     // exist. At last, we'll enumerate the /etc/fstab file (luckily there's an
     // API to parse it) for CDROM devices. Ok, let's start!
 
-    if (getenv("VBOX_CDROM"))
-    {
-        char *cdromEnv = strdupa(getenv("VBOX_CDROM"));
-        char *cdromDrive;
-        cdromDrive = strtok(cdromEnv, ":");
-        while (cdromDrive)
-        {
-            if (validateDevice(cdromDrive, true))
+    {
+        if (getenv("VBOX_CDROM"))
+        {
+            char *cdromEnv = strdupa(getenv("VBOX_CDROM"));
+            char *cdromDrive;
+            cdromDrive = strtok(cdromEnv, ":");
+            while (cdromDrive)
             {
-                ComObjPtr <HostDVDDrive> hostDVDDriveObj;
-                hostDVDDriveObj.createObject();
-                hostDVDDriveObj->init (Bstr (cdromDrive));
-                list.push_back (hostDVDDriveObj);
+                if (validateDevice(cdromDrive, true))
+                {
+                    ComObjPtr <HostDVDDrive> hostDVDDriveObj;
+                    hostDVDDriveObj.createObject();
+                    hostDVDDriveObj->init (Bstr (cdromDrive));
+                    list.push_back (hostDVDDriveObj);
+                }
+                cdromDrive = strtok(NULL, ":");
             }
-            cdromDrive = strtok(NULL, ":");
-        }
-    }
-    else
-    {
-        // this is a good guess usually
-        if (validateDevice("/dev/cdrom", true))
-        {
-                ComObjPtr <HostDVDDrive> hostDVDDriveObj;
-                hostDVDDriveObj.createObject();
-                hostDVDDriveObj->init (Bstr ("/dev/cdrom"));
-                list.push_back (hostDVDDriveObj);
-        }
-
-        // check the mounted drives
-        parseMountTable((char*)"/etc/mtab", list);
-
-        // check the drives that can be mounted
-        parseMountTable((char*)"/etc/fstab", list);
+        }
+        else
+        {
+            // this is a good guess usually
+            if (validateDevice("/dev/cdrom", true))
+            {
+                    ComObjPtr <HostDVDDrive> hostDVDDriveObj;
+                    hostDVDDriveObj.createObject();
+                    hostDVDDriveObj->init (Bstr ("/dev/cdrom"));
+                    list.push_back (hostDVDDriveObj);
+            }
+
+            // check the mounted drives
+            parseMountTable((char*)"/etc/mtab", list);
+
+            // check the drives that can be mounted
+            parseMountTable((char*)"/etc/fstab", list);
+        }
     }
 #elif defined(__DARWIN__)
@@ -1380,4 +1390,126 @@
 
 #ifdef __LINUX__
+# ifdef VBOX_USE_LIBHAL
+/**
+ * Helper function to query the hal subsystem for information about DVD drives attached to the
+ * system.
+ *
+ * @returns true if at least one drive was found, false otherwise
+ * @retval  list drives found will be attached to this list
+ */
+bool Host::getDVDInfoFromHal(std::list <ComObjPtr <HostDVDDrive> > &list)
+{
+    bool halSuccess = false;
+    DBusError dbusError;
+    dbus_error_init (&dbusError);
+    DBusConnection *dbusConnection = dbus_bus_get(DBUS_BUS_SYSTEM, &dbusError);
+    if (dbusConnection != 0)
+    {
+        LibHalContext *halContext = libhal_ctx_new();
+        if (halContext != 0)
+        {
+            if (libhal_ctx_set_dbus_connection (halContext, dbusConnection))
+            {
+                if (libhal_ctx_init(halContext, &dbusError))
+                {
+                    int numDevices;
+                    char **halDevices = libhal_find_device_by_capability(halContext,
+                                                "storage.cdrom", &numDevices, &dbusError);
+                    if (halDevices != 0)
+                    {
+                        for (int i = 0; i < numDevices; i++)
+                        {
+                            char *devNode = libhal_device_get_property_string(halContext,
+                                                    halDevices[i], "block.device", &dbusError);
+                            if (devNode != 0)
+                            {
+                                if (validateDevice(devNode, true))
+                                {
+                                    char description[256];
+                                    char *vendor, *product;
+                                    /* We have at least one hit, so operation successful :) */
+                                    halSuccess = true;
+                                    vendor = libhal_device_get_property_string(halContext,
+                                                    halDevices[i], "info.vendor", &dbusError);
+                                    product = libhal_device_get_property_string(halContext,
+                                                    halDevices[i], "info.product", &dbusError);
+                                    if ((product != 0))
+                                    {
+                                        if (vendor != 0 && vendor[0] != 0)
+                                        {
+                                            RTStrPrintf(description, sizeof(description),
+                                                        "%s %s (%s)", vendor, product, devNode);
+                                        }
+                                        else
+                                        {
+                                            RTStrPrintf(description, sizeof(description),
+                                                        "%s (%s)", product, devNode);
+                                        }
+                                        ComObjPtr <HostDVDDrive> hostDVDDriveObj;
+                                        hostDVDDriveObj.createObject();
+                                        hostDVDDriveObj->init (Bstr (devNode), Bstr (description));
+                                        list.push_back (hostDVDDriveObj);
+                                    }
+                                    else
+                                    {
+                                        ComObjPtr <HostDVDDrive> hostDVDDriveObj;
+                                        hostDVDDriveObj.createObject();
+                                        hostDVDDriveObj->init (Bstr (devNode));
+                                        list.push_back (hostDVDDriveObj);
+                                    }
+                                }
+                                else
+                                {
+                                    LogRel(("Host::COMGETTER(DVDDrives): failed to validate the block device %s as a DVD drive\n"));
+                                }
+                                libhal_free_string(devNode);
+                            }
+                            else
+                            {
+                                LogRel(("Host::COMGETTER(DVDDrives): failed to get property \"block.device\" for device %s.  dbus error: %s (%s)\n",
+                                        halDevices[i], dbusError.name, dbusError.message));
+                                dbus_error_free(&dbusError);
+                            }
+                        }
+                        libhal_free_string_array(halDevices);
+                    }
+                    else
+                    {
+                        LogRel(("Host::COMGETTER(DVDDrives): failed to get devices with capability \"storage.cdrom\".  dbus error: %s (%s)\n", dbusError.name, dbusError.message));
+                        dbus_error_free(&dbusError);
+                    }
+                    if (!libhal_ctx_shutdown(halContext, &dbusError))  /* what now? */
+                    {
+                        LogRel(("Host::COMGETTER(DVDDrives): failed to shutdown the libhal context.  dbus error: %s (%s)\n", dbusError.name, dbusError.message));
+                        dbus_error_free(&dbusError);
+                    }
+                }
+                else
+                {
+                    LogRel(("Host::COMGETTER(DVDDrives): failed to initialise libhal context.  dbus error: %s (%s)\n", dbusError.name, dbusError.message));
+                    dbus_error_free(&dbusError);
+                }
+                libhal_ctx_free(halContext);
+            }
+            else
+            {
+                LogRel(("Host::COMGETTER(DVDDrives): failed to set libhal connection to dbus.\n"));
+            }
+        }
+        else
+        {
+            LogRel(("Host::COMGETTER(DVDDrives): failed to get a libhal context - out of memory?\n"));
+        }
+        dbus_connection_unref(dbusConnection);
+    }
+    else
+    {
+        LogRel(("Host::COMGETTER(DVDDrives): failed to connect to dbus.  dbus error: %s (%s)\n", dbusError.name, dbusError.message));
+        dbus_error_free(&dbusError);
+    }
+    return halSuccess;
+}
+# endif  /* VBOX_USE_HAL defined */
+
 /**
  * Helper function to parse the given mount file and add found entries
Index: trunk/src/VBox/Main/Makefile.kmk
===================================================================
--- trunk/src/VBox/Main/Makefile.kmk	(revision 2853)
+++ trunk/src/VBox/Main/Makefile.kmk	(revision 2917)
@@ -153,4 +153,13 @@
 	$(PATH_LIB)/VBoxCOM$(VBOX_SUFF_LIB)
 endif
+ifdef VBOX_WITH_LIBHAL
+VBoxSVC_CXXFLAGS += \
+	$(LIB_HAL_CFLAGS)
+VBoxSVC_LIBS += \
+	$(LIB_HAL_LIBS)
+VBoxSVC_DEFS += \
+	VBOX_USE_LIBHAL
+endif
+
 VBoxSVC_SOURCES = \
 	Logging.cpp \
Index: trunk/src/VBox/Main/idl/VirtualBox.xidl
===================================================================
--- trunk/src/VBox/Main/idl/VirtualBox.xidl	(revision 2853)
+++ trunk/src/VBox/Main/idl/VirtualBox.xidl	(revision 2917)
@@ -3499,4 +3499,7 @@
             <desc>Returns the platform device identifier.</desc>
         </attribute>
+        <attribute name="description" type="wstring" readonly="yes">
+            <desc>Returns a human readable description for the drive.</desc>
+        </attribute>
 
     </interface>
Index: trunk/src/VBox/Main/include/HostDVDDriveImpl.h
===================================================================
--- trunk/src/VBox/Main/include/HostDVDDriveImpl.h	(revision 2853)
+++ trunk/src/VBox/Main/include/HostDVDDriveImpl.h	(revision 2917)
@@ -50,7 +50,9 @@
     // public initializer/uninitializer for internal purposes only
     HRESULT init (INPTR BSTR driveName);
+    HRESULT init (INPTR BSTR driveName, INPTR BSTR driveDescription);
 
     // IHostDVDDrive properties
     STDMETHOD(COMGETTER(Name)) (BSTR *driveName);
+    STDMETHOD(COMGETTER(Description)) (BSTR *driveDescription);
 
     // public methods for internal purposes only
@@ -64,4 +66,5 @@
 
     Bstr mDriveName;
+    Bstr mDriveDescription;
 };
 
Index: trunk/src/VBox/Main/include/HostImpl.h
===================================================================
--- trunk/src/VBox/Main/include/HostImpl.h	(revision 2853)
+++ trunk/src/VBox/Main/include/HostImpl.h	(revision 2917)
@@ -131,4 +131,7 @@
 
 #ifdef __LINUX__
+# ifdef VBOX_USE_LIBHAL
+    bool getDVDInfoFromHal(std::list <ComObjPtr <HostDVDDrive> > &list);
+# endif
     void parseMountTable(char *mountTable, std::list <ComObjPtr <HostDVDDrive> > &list);
     bool validateDevice(const char *deviceNode, bool isCDROM);
