VirtualBox

Changeset 34716 in vbox


Ignore:
Timestamp:
Dec 3, 2010 11:33:04 PM (14 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
68519
Message:

Main/linux/USB: more thorough checks for the different USB probing methods

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/linux/USBGetDevices.cpp

    r34456 r34716  
    4848
    4949#include <dirent.h>
     50#include <dlfcn.h>
    5051#include <errno.h>
    5152#include <fcntl.h>
     
    473474
    474475/** Just a worker for USBProxyServiceLinux::getDevices that avoids some code duplication. */
    475 static int addDeviceToChain(PUSBDEVICE pDev, PUSBDEVICE *ppFirst, PUSBDEVICE **pppNext, const char *pcszUsbfsRoot, int rc)
     476static int addDeviceToChain(PUSBDEVICE pDev, PUSBDEVICE *ppFirst, PUSBDEVICE **pppNext, const char *pcszUsbfsRoot, bool testfs, int rc)
    476477{
    477478    /* usbDeterminState requires the address. */
     
    483484        {
    484485            pDevNew->enmState = usbDeterminState(pDevNew);
    485             if (pDevNew->enmState != USBDEVICESTATE_UNSUPPORTED)
     486            if (pDevNew->enmState != USBDEVICESTATE_UNSUPPORTED || testfs)
    486487            {
    487488                if (*pppNext)
     
    526527
    527528/**
    528  * USBProxyService::getDevices() implementation for usbfs.
    529  */
    530 static PUSBDEVICE getDevicesFromUsbfs(const char *pcszUsbfsRoot)
     529 * USBProxyService::getDevices() implementation for usbfs.  The @a testfs flag
     530 * tells the function to return information about unsupported devices as well.
     531 * This is used as a sanity test to check that a devices file is really what
     532 * we expect.
     533 */
     534static PUSBDEVICE getDevicesFromUsbfs(const char *pcszUsbfsRoot, bool testfs)
    531535{
    532536    PUSBDEVICE pFirst = NULL;
     
    593597                    AssertMsg(cHits >= 3 || cHits == 0, ("cHits=%d\n", cHits));
    594598                    if (cHits >= 3)
    595                         rc = addDeviceToChain(&Dev, &pFirst, &ppNext, pcszUsbfsRoot, rc);
     599                        rc = addDeviceToChain(&Dev, &pFirst, &ppNext, pcszUsbfsRoot, testfs, rc);
    596600                    else
    597601                        deviceFreeMembers(&Dev);
     
    786790        AssertMsg(cHits >= 3 || cHits == 0, ("cHits=%d\n", cHits));
    787791        if (cHits >= 3)
    788             rc = addDeviceToChain(&Dev, &pFirst, &ppNext, pcszUsbfsRoot, rc);
     792            rc = addDeviceToChain(&Dev, &pFirst, &ppNext, pcszUsbfsRoot, testfs, rc);
    789793
    790794        /*
     
    13431347 * USBProxyService::getDevices() implementation for sysfs.
    13441348 */
    1345 static PUSBDEVICE getDevicesFromSysfs(const char *pcszDevicesRoot)
     1349static PUSBDEVICE getDevicesFromSysfs(const char *pcszDevicesRoot, bool testfs)
    13461350{
    13471351#ifdef VBOX_USB_WITH_SYSFS
     
    13671371        }
    13681372        if (   RT_SUCCESS(rc)
    1369             && Dev->enmState != USBDEVICESTATE_UNSUPPORTED
     1373            && (   Dev->enmState != USBDEVICESTATE_UNSUPPORTED
     1374                || testfs)
    13701375            && Dev->pszAddress != NULL
    13711376           )
     
    13941399}
    13951400
     1401/** Is inotify available and working on this system?  This is a requirement
     1402 * for using USB with sysfs */
     1403/** @todo test the "inotify in glibc but not in the kernel" case. */
     1404static bool inotifyAvailable(void)
     1405{
     1406    int (*inotify_init)(void);
     1407
     1408    *(void **)(&inotify_init) = dlsym(RTLD_DEFAULT, "inotify_init");
     1409    if (!inotify_init)
     1410        return false;
     1411    int fd = inotify_init();
     1412    if (fd == -1)
     1413        return false;
     1414    close(fd);
     1415    return true;
     1416}
     1417
    13961418PCUSBDEVTREELOCATION USBProxyLinuxGetDeviceRoot(bool fPreferSysfs)
    13971419{
     
    13991421    PCUSBDEVTREELOCATION pcBestSysfs = NULL;
    14001422
     1423    bool fHaveInotify = inotifyAvailable();
    14011424    for (unsigned i = 0; i < RT_ELEMENTS(s_aTreeLocations); ++i)
    14021425        if (!s_aTreeLocations[i].fUseSysfs)
     
    14061429                PUSBDEVICE pDevices;
    14071430
    1408                 pDevices = getDevicesFromUsbfs(s_aTreeLocations[i].szDevicesRoot);
     1431                pDevices = getDevicesFromUsbfs(s_aTreeLocations[i].szDevicesRoot,
     1432                                               true);
    14091433                if (pDevices)
    14101434                {
     
    14161440        else
    14171441        {
    1418             if (   !pcBestSysfs
     1442            if (   fHaveInotify
     1443                && !pcBestSysfs
    14191444                && RTPathExists(s_aTreeLocations[i].szDevicesRoot))
    1420                 pcBestSysfs = &s_aTreeLocations[i];
     1445            {
     1446                PUSBDEVICE pDevices;
     1447
     1448                pDevices = getDevicesFromSysfs(s_aTreeLocations[i].szDevicesRoot,
     1449                                               true);
     1450                if (pDevices)
     1451                {
     1452                    pcBestSysfs = &s_aTreeLocations[i];
     1453                    deviceListFree(&pDevices);
     1454                }
     1455            }
    14211456        }
    14221457    if (pcBestUsbfs && !fPreferSysfs)
     
    14301465{
    14311466    if (!fUseSysfs)
    1432         return getDevicesFromUsbfs(pcszDevicesRoot);
     1467        return getDevicesFromUsbfs(pcszDevicesRoot, false);
    14331468    else
    1434         return getDevicesFromSysfs(pcszDevicesRoot);
    1435 }
     1469        return getDevicesFromSysfs(pcszDevicesRoot, false);
     1470}
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette