HostHardwareLinux.cpp revision 18456bfb9f30d08e5347aa108a2fef0c49c0ab0b
5b281ba489ca18f0380d7efc7a5108b606cce449vboxsync * Classes for handling hardware detection under Linux. Please feel free to
67c26773eca4a576449ffa8f289fa344fc7b8176vboxsync * expand these to work for other systems (Solaris!) or to add new ones for
67c26773eca4a576449ffa8f289fa344fc7b8176vboxsync * other systems.
67c26773eca4a576449ffa8f289fa344fc7b8176vboxsync * Copyright (C) 2008 Sun Microsystems, Inc.
67c26773eca4a576449ffa8f289fa344fc7b8176vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * available from http://www.virtualbox.org. This file is free software;
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * you can redistribute it and/or modify it under the terms of the GNU
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * General Public License (GPL) as published by the Free Software
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * additional information or have any questions.
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync/*******************************************************************************
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync* Header Files *
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync*******************************************************************************/
67c26773eca4a576449ffa8f289fa344fc7b8176vboxsync/* bird: This is a hack to work around conflicts between these linux kernel headers
67c26773eca4a576449ffa8f289fa344fc7b8176vboxsync * and the GLIBC tcpip headers. They have different declarations of the 4
67c26773eca4a576449ffa8f289fa344fc7b8176vboxsync * standard byte order functions. */
67c26773eca4a576449ffa8f289fa344fc7b8176vboxsync// # define _LINUX_BYTEORDER_GENERIC_H
67c26773eca4a576449ffa8f289fa344fc7b8176vboxsync#endif /* RT_OS_LINUX */
67c26773eca4a576449ffa8f289fa344fc7b8176vboxsync/*******************************************************************************
67c26773eca4a576449ffa8f289fa344fc7b8176vboxsync* Global Variables *
67c26773eca4a576449ffa8f289fa344fc7b8176vboxsync*******************************************************************************/
67c26773eca4a576449ffa8f289fa344fc7b8176vboxsyncstatic bool testing () { return g_testHostHardwareLinux; }
67c26773eca4a576449ffa8f289fa344fc7b8176vboxsync/*******************************************************************************
67c26773eca4a576449ffa8f289fa344fc7b8176vboxsync* Typedefs and Defines *
67c26773eca4a576449ffa8f289fa344fc7b8176vboxsync*******************************************************************************/
67c26773eca4a576449ffa8f289fa344fc7b8176vboxsyncstatic bool validateDevice(const char *deviceNode, bool isDVD);
67c26773eca4a576449ffa8f289fa344fc7b8176vboxsyncstatic int getDriveInfoFromEnv(const char *pszVar, DriveInfoList *pList,
67c26773eca4a576449ffa8f289fa344fc7b8176vboxsyncstatic int getDVDInfoFromMTab(char *mountTable, DriveInfoList *pList);
67c26773eca4a576449ffa8f289fa344fc7b8176vboxsync/* These must be extern to be used in the RTMemAutoPtr template */
67c26773eca4a576449ffa8f289fa344fc7b8176vboxsyncextern void halShutdown (DBusConnection *pConnection);
67c26773eca4a576449ffa8f289fa344fc7b8176vboxsyncextern void halShutdownPrivate (DBusConnection *pConnection);
67c26773eca4a576449ffa8f289fa344fc7b8176vboxsyncstatic int halInit(RTMemAutoPtr <DBusConnection, halShutdown> *pConnection);
67c26773eca4a576449ffa8f289fa344fc7b8176vboxsyncstatic int halInitPrivate(RTMemAutoPtr <DBusConnection, halShutdownPrivate> *pConnection);
67c26773eca4a576449ffa8f289fa344fc7b8176vboxsyncstatic int halFindDeviceStringMatch (DBusConnection *pConnection,
67c26773eca4a576449ffa8f289fa344fc7b8176vboxsync RTMemAutoPtr <DBusMessage, VBoxDBusMessageUnref> *pMessage);
67c26773eca4a576449ffa8f289fa344fc7b8176vboxsyncstatic int halGetPropertyStrings (DBusConnection *pConnection,
67c26773eca4a576449ffa8f289fa344fc7b8176vboxsync RTMemAutoPtr <DBusMessage, VBoxDBusMessageUnref> *pMessage);
67c26773eca4a576449ffa8f289fa344fc7b8176vboxsyncstatic int getDriveInfoFromHal(DriveInfoList *pList, bool isDVD,
67c26773eca4a576449ffa8f289fa344fc7b8176vboxsyncstatic int getUSBDeviceInfoFromHal(USBDeviceInfoList *pList, bool *pfSuccess);
67c26773eca4a576449ffa8f289fa344fc7b8176vboxsyncstatic int getUSBInterfacesFromHal(std::vector <std::string> *pList,
67c26773eca4a576449ffa8f289fa344fc7b8176vboxsyncstatic DBusHandlerResult dbusFilterFunction (DBusConnection *pConnection,
67c26773eca4a576449ffa8f289fa344fc7b8176vboxsync#endif /* VBOX_WITH_DBUS */
67c26773eca4a576449ffa8f289fa344fc7b8176vboxsync * Updates the list of host DVD drives.
67c26773eca4a576449ffa8f289fa344fc7b8176vboxsync * @returns iprt status code
67c26773eca4a576449ffa8f289fa344fc7b8176vboxsync bool success = false; /* Have we succeeded in finding anything yet? */
67c26773eca4a576449ffa8f289fa344fc7b8176vboxsync if (RT_SUCCESS (rc) && VBoxDBusCheckPresence() && (!success || testing()))
67c26773eca4a576449ffa8f289fa344fc7b8176vboxsync rc = getDriveInfoFromHal(&mDVDList, true /* isDVD */, &success);
67c26773eca4a576449ffa8f289fa344fc7b8176vboxsync#endif /* VBOX_WITH_DBUS defined */
67c26773eca4a576449ffa8f289fa344fc7b8176vboxsync // On Linux without hal, the situation is much more complex. We will take a
67c26773eca4a576449ffa8f289fa344fc7b8176vboxsync // heuristical approach and also allow the user to specify a list of host
67c26773eca4a576449ffa8f289fa344fc7b8176vboxsync // CDROMs using an environment variable.
67c26773eca4a576449ffa8f289fa344fc7b8176vboxsync // The general strategy is to try some known device names and see of they
67c26773eca4a576449ffa8f289fa344fc7b8176vboxsync // exist. At last, we'll enumerate the /etc/fstab file (luckily there's an
67c26773eca4a576449ffa8f289fa344fc7b8176vboxsync // API to parse it) for CDROM devices. Ok, let's start!
67c26773eca4a576449ffa8f289fa344fc7b8176vboxsync rc = getDriveInfoFromEnv ("VBOX_CDROM", &mDVDList, true /* isDVD */,
67c26773eca4a576449ffa8f289fa344fc7b8176vboxsync // this is a good guess usually
67c26773eca4a576449ffa8f289fa344fc7b8176vboxsync // check the mounted drives
67c26773eca4a576449ffa8f289fa344fc7b8176vboxsync rc = getDVDInfoFromMTab((char*)"/etc/mtab", &mDVDList);
67c26773eca4a576449ffa8f289fa344fc7b8176vboxsync // check the drives that can be mounted
67c26773eca4a576449ffa8f289fa344fc7b8176vboxsync rc = getDVDInfoFromMTab((char*)"/etc/fstab", &mDVDList);
return rc;
#if defined(RT_OS_LINUX)
#ifdef VBOX_WITH_DBUS
&success);
return rc;
#if defined(RT_OS_LINUX)
#ifdef VBOX_WITH_DBUS
return rc;
bool mTriggered;
bool mInterrupt;
if (VBoxDBusCheckPresence())
delete mContext;
bool connected = true;
unsigned cRealMillies;
if (!connected)
return rc;
#ifdef RT_OS_LINUX
bool retValue = false;
if (!deviceNode)
if (isDVD)
int fileHandle;
if (fileHandle >= 0)
#ifdef RT_OS_LINUX
retValue = true;
retValue = true;
return retValue;
bool success = false;
if (!drive)
success = true;
return rc;
#ifdef RT_OS_LINUX
#ifdef RT_OS_LINUX
if (mtab)
char *tmp;
if (tmp)
if (!mnt_type)
if (tmp)
if (tmp)
if (!mnt_dev)
if (tmp)
bool insert = true;
insert = false;
insert = false;
if (insert)
return rc;
class autoDBusError
~autoDBusError ()
if (IsSet())
bool IsSet ()
void FlowLog ()
if (IsSet ())
bool halSuccess = true;
if (!dbusConnection)
halSuccess = false;
if (halSuccess)
if (halSuccess)
"path='/org/freedesktop/Hal/Manager'",
if (halSuccess)
return rc;
bool halSuccess = true;
if (!dbusConnection)
halSuccess = false;
if (halSuccess)
if (halSuccess)
"path='/org/freedesktop/Hal/Manager'",
if (halSuccess)
return rc;
"path='/org/freedesktop/Hal/Manager'",
"path='/org/freedesktop/Hal/Manager'",
const char *pszValue,
"/org/freedesktop/Hal/Manager",
if (!message)
if (!reply)
halSuccess = false;
return rc;
char **papszValues,
LogFlowFunc (("pConnection=%p, pszUdi=%s, cProps=%llu, papszKeys=%p, papszValues=%p, pMessage=%p\n",
if (!message)
if (!reply)
halSuccess = false;
halSuccess = false;
const char *pszKey;
return rc;
if (!dbusConnection)
halSuccess = false;
if (!replyFind)
halSuccess = false;
halSuccess = false;
const char *pszUdi;
static const char *papszKeys[] =
halSuccess = false;
return rc;
if (!dbusConnection)
halSuccess = false;
if (!replyFind)
halSuccess = false;
halSuccess = false;
const char *pszUdi;
return rc;
pfSuccess));
if (!dbusConnection)
halSuccess = false;
if (!replyFind)
halSuccess = false;
halSuccess = false;
const char *pszUdi;
if (!replyGet)
halSuccess = false;
halSuccess = false;
return rc;
*pTriggered = true;