VirtualBox

Changeset 32261 in vbox for trunk/src


Ignore:
Timestamp:
Sep 6, 2010 11:24:02 PM (14 years ago)
Author:
vboxsync
Message:

Main/HostHardwareLinux: simplification

File:
1 edited

Legend:

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

    r32258 r32261  
    9191static int getDriveInfoFromSysfs(DriveInfoList *pList, bool isDVD,
    9292                                 bool *pfSuccess);
    93 #ifdef VBOX_USB_WITH_SYSFS
    94 # ifdef VBOX_USB_WITH_INOTIFY
    95 static int getUSBDeviceInfoFromSysfs(VECTOR_OBJ(USBDeviceInfo) *pvecDevInfo,
    96                                      bool *pfSuccess);
    97 
    98 /** Function object to be invoked on filenames from a directory. */
    99 typedef struct pathHandler
    100 {
    101     /** Called on each element of the sysfs directory.  Can e.g. store
    102      * interesting entries in a list. */
    103     bool (*handle)(pathHandler *pHandle, const char *pcszNode);
    104 } pathHandler;
    105 
    106 static bool phDoHandle(pathHandler *pHandler, const char *pcszNode)
    107 {
    108     AssertPtr(pHandler);
    109     AssertPtr(pHandler->handle);
    110     AssertPtr(pcszNode);
    111     Assert(pcszNode[0] == '/');
    112     return pHandler->handle(pHandler, pcszNode);
    113 }
    114 
    115 static int walkDirectory(const char *pcszPath, pathHandler *pHandler,
    116                          int withRealPath);
    117 # endif
    118 #endif /* VBOX_USB_WITH_SYSFS */
    119 
    12093
    12194/** Find the length of a string, ignoring trailing non-ascii or control
     
    1000973}
    1001974
    1002 void USBDevInfoCleanup(USBDeviceInfo *pSelf)
    1003 {
    1004     RTStrFree(pSelf->mDevice);
    1005     RTStrFree(pSelf->mSysfsPath);
    1006     pSelf->mDevice = pSelf->mSysfsPath = NULL;
    1007     VEC_CLEANUP_PTR(&pSelf->mvecpszInterfaces);
    1008 }
    1009 
    1010 int USBDevInfoInit(USBDeviceInfo *pSelf, const char *aDevice,
    1011                    const char *aSystemID)
    1012 {
    1013     pSelf->mDevice = aDevice ? RTStrDup(aDevice) : NULL;
    1014     pSelf->mSysfsPath = aSystemID ? RTStrDup(aSystemID) : NULL;
    1015     if (   RT_FAILURE(VEC_INIT_PTR(&pSelf->mvecpszInterfaces, char *, RTStrFree))
    1016         || (aDevice && !pSelf->mDevice) || (aSystemID && ! pSelf->mSysfsPath))
    1017     {
    1018         USBDevInfoCleanup(pSelf);
     975
     976/** Helper for readFilePathsFromDir().  Adds a path to the vector if it is not
     977 * NULL and not a dotfile (".", "..", ".*"). */
     978static int maybeAddPathToVector(const char *pcszPath, const char *pcszEntry,
     979                                VECTOR_PTR(char *) *pvecpchDevs)
     980{
     981    char *pszPath;
     982
     983    if (!pcszPath)
    1019984        return 0;
    1020     }
    1021     return 1;
    1022 }
    1023 
    1024 int USBDevInfoUpdateDevices (VBoxMainUSBDeviceInfo *pSelf)
    1025 {
    1026     LogFlowFunc(("entered\n"));
    1027     int rc = VINF_SUCCESS;
    1028     bool success = false;  /* Have we succeeded in finding anything yet? */
    1029     VEC_CLEAR_OBJ(&pSelf->mvecDevInfo);
    1030 #ifdef VBOX_USB_WITH_SYSFS
    1031 # ifdef VBOX_USB_WITH_INOTIFY
    1032     if (   RT_SUCCESS(rc)
    1033         && (!success || testing()))
    1034         rc = getUSBDeviceInfoFromSysfs(&pSelf->mvecDevInfo, &success);
    1035 # endif
    1036 #else /* !VBOX_USB_WITH_SYSFS */
    1037     NOREF(success);
    1038 #endif /* !VBOX_USB_WITH_SYSFS */
    1039     LogFlowFunc(("rc=%Rrc\n", rc));
    1040     return rc;
     985    if (pcszEntry[0] == '.')
     986        return 0;
     987    pszPath = RTStrDup(pcszPath);
     988    if (!pszPath)
     989        return ENOMEM;
     990    if (RT_FAILURE(VEC_PUSH_BACK_PTR(pvecpchDevs, char *, pszPath)))
     991        return ENOMEM;
     992    return 0;
     993}
     994
     995/** Helper for readFilePaths().  Adds the entries from the open directory
     996 * @a pDir to the vector @a pvecpchDevs using either the full path or the
     997 * realpath() and skipping hidden files and files on which realpath() fails. */
     998static int readFilePathsFromDir(const char *pcszPath, DIR *pDir,
     999                                VECTOR_PTR(char *) *pvecpchDevs, int withRealPath)
     1000{
     1001    struct dirent entry, *pResult;
     1002    int err;
     1003
     1004    for (err = readdir_r(pDir, &entry, &pResult); pResult;
     1005         err = readdir_r(pDir, &entry, &pResult))
     1006    {
     1007        /* We (implicitly) require that PATH_MAX be defined */
     1008        char szPath[PATH_MAX + 1], szRealPath[PATH_MAX + 1], *pszPath;
     1009        if (snprintf(szPath, sizeof(szPath), "%s/%s", pcszPath,
     1010                     entry.d_name) < 0)
     1011            return errno;
     1012        if (withRealPath)
     1013            pszPath = realpath(szPath, szRealPath);
     1014        else
     1015            pszPath = szPath;
     1016        if ((err = maybeAddPathToVector(pszPath, entry.d_name, pvecpchDevs)))
     1017            return err;
     1018    }
     1019    return err;
     1020}
     1021
     1022
     1023/**
     1024 * Helper for walkDirectory to dump the names of a directory's entries into a
     1025 * vector of char pointers.
     1026 *
     1027 * @returns zero on success or (positive) posix error value.
     1028 * @param   pcszPath      the path to dump. 
     1029 * @param   pvecpchDevs   an empty vector of char pointers - must be cleaned up
     1030 *                        by the caller even on failure.
     1031 * @param   withRealPath  whether to canonicalise the filename with realpath
     1032 */
     1033static int readFilePaths(const char *pcszPath, VECTOR_PTR(char *) *pvecpchDevs,
     1034                         int withRealPath)
     1035{
     1036    DIR *pDir;
     1037    int err;
     1038
     1039    AssertPtrReturn(pvecpchDevs, EINVAL);
     1040    AssertReturn(VEC_SIZE_PTR(pvecpchDevs) == 0, EINVAL);
     1041    AssertPtrReturn(pcszPath, EINVAL);
     1042
     1043    pDir = opendir(pcszPath);
     1044    if (!pDir)
     1045        return RTErrConvertFromErrno(errno);
     1046    err = readFilePathsFromDir(pcszPath, pDir, pvecpchDevs, withRealPath);
     1047    if (closedir(pDir) < 0 && !err)
     1048        err = errno;
     1049    return RTErrConvertFromErrno(err);
    10411050}
    10421051
     
    10641073# ifdef VBOX_USB_WITH_INOTIFY
    10651074/** Class wrapper around an inotify watch (or a group of them to be precise).
    1066  * Inherits from pathHandler so that it can be passed to walkDirectory() to
    1067  * easily add all files from a directory. */
     1075 */
    10681076typedef struct inotifyWatch
    10691077{
    1070     /** The pathHandler we inherit from - this must be the first structure
    1071      * member */
    1072     pathHandler mParent;
    10731078    /** Pointer to the inotify_add_watch() glibc function/Linux API */
    10741079    int (*inotify_add_watch)(int, const char *, uint32_t);
     
    10811086#define IN_FLAGS 0x306
    10821087
    1083 static bool iwHandle(pathHandler *pParent, const char *pcszPath)
    1084 {
    1085     AssertPtrReturn(pParent, false);
    1086     AssertReturn(pParent->handle == iwHandle, false);
    1087     inotifyWatch *pSelf = (inotifyWatch *)pParent;
     1088static int iwAddWatch(inotifyWatch *pSelf, const char *pcszPath)
     1089{
    10881090    errno = 0;
    10891091    if (  pSelf->inotify_add_watch(pSelf->mhInotify, pcszPath, IN_FLAGS) >= 0
    10901092        || (errno == EACCES))
    1091         return true;
     1093        return VINF_SUCCESS;
    10921094    /* Other errors listed in the manpage can be treated as fatal */
    1093     return false;
     1095    return RTErrConvertFromErrno(errno);
    10941096}
    10951097
     
    11021104
    11031105    AssertPtr(pSelf);
    1104     pSelf->mParent.handle = iwHandle;
    11051106    pSelf->mhInotify = -1;
    11061107    errno = 0;
     
    12591260        if (RT_FAILURE(rc = iwInit(&mWatches)))
    12601261            break;
    1261         phDoHandle(&mWatches.mParent, SYSFS_USB_DEVICE_PATH);
     1262        if (RT_FAILURE(rc = iwAddWatch(&mWatches, SYSFS_USB_DEVICE_PATH)))
     1263            break;
    12621264        if (RT_FAILURE(rc = pipeCreateSimple(&mhWakeupPipeR, &mhWakeupPipeW)))
    12631265            break;
     
    13171319{
    13181320    int rc;
     1321    char **ppszEntry;
     1322    VECTOR_PTR(char *) vecpchDevs;
    13191323
    13201324    AssertRCReturn(mStatus, VERR_WRONG_ORDER);
     1325    if (RT_FAILURE(rc = VEC_INIT_PTR(&vecpchDevs, char *, RTStrFree)))
     1326        return rc;
    13211327    bool fEntered = ASMAtomicCmpXchgU32(&mfWaiting, 1, 0);
     1328    if (!fEntered)
     1329        VEC_CLEANUP_PTR(&vecpchDevs);
    13221330    AssertReturn(fEntered, VERR_WRONG_ORDER);
    13231331    do {
    13241332        struct pollfd pollFD[MAX_POLLID];
    13251333
    1326         if (RT_FAILURE(rc = walkDirectory(SYSFS_USB_DEVICE_PATH, &mWatches.mParent,
    1327                                           false)))
     1334        rc = readFilePaths(SYSFS_USB_DEVICE_PATH, &vecpchDevs, false);
     1335        if (RT_SUCCESS(rc))
     1336            VEC_FOR_EACH(&vecpchDevs, char *, ppszEntry)
     1337                if (RT_FAILURE(rc = iwAddWatch(&mWatches, *ppszEntry)))
     1338                    break;
     1339        if (RT_FAILURE(rc))
    13281340            break;
    13291341        pollFD[RPIPE_ID].fd = mhWakeupPipeR;
     
    13581370    } while (false);
    13591371    mfWaiting = 0;
     1372    VEC_CLEANUP_PTR(&vecpchDevs);
    13601373    return rc;
    13611374}
     
    13921405}
    13931406
     1407void USBDevInfoCleanup(USBDeviceInfo *pSelf)
     1408{
     1409    RTStrFree(pSelf->mDevice);
     1410    RTStrFree(pSelf->mSysfsPath);
     1411    pSelf->mDevice = pSelf->mSysfsPath = NULL;
     1412    VEC_CLEANUP_PTR(&pSelf->mvecpszInterfaces);
     1413}
     1414
     1415int USBDevInfoInit(USBDeviceInfo *pSelf, const char *aDevice,
     1416                   const char *aSystemID)
     1417{
     1418    pSelf->mDevice = aDevice ? RTStrDup(aDevice) : NULL;
     1419    pSelf->mSysfsPath = aSystemID ? RTStrDup(aSystemID) : NULL;
     1420    if (   RT_FAILURE(VEC_INIT_PTR(&pSelf->mvecpszInterfaces, char *, RTStrFree))
     1421        || (aDevice && !pSelf->mDevice) || (aSystemID && ! pSelf->mSysfsPath))
     1422    {
     1423        USBDevInfoCleanup(pSelf);
     1424        return 0;
     1425    }
     1426    return 1;
     1427}
     1428
    13941429#ifdef VBOX_USB_WITH_SYSFS
    13951430# ifdef VBOX_USB_WITH_INOTIFY
    1396 /** Helper for readFilePathsFromDir().  Adds a path to the vector if it is not
    1397  * NULL and not a dotfile (".", "..", ".*"). */
    1398 static int maybeAddPathToVector(const char *pcszPath, const char *pcszEntry,
    1399                                 VECTOR_PTR(char *) *pvpchDevs)
    1400 {
    1401     char *pszPath;
    1402 
    1403     if (!pcszPath)
    1404         return 0;
    1405     if (pcszEntry[0] == '.')
    1406         return 0;
    1407     pszPath = RTStrDup(pcszPath);
    1408     if (!pszPath)
    1409         return ENOMEM;
    1410     if (RT_FAILURE(VEC_PUSH_BACK_PTR(pvpchDevs, char *, pszPath)))
    1411         return ENOMEM;
    1412     return 0;
    1413 }
    1414 
    1415 /** Helper for readFilePaths().  Adds the entries from the open directory
    1416  * @a pDir to the vector @a pvpchDevs using either the full path or the
    1417  * realpath() and skipping hidden files and files on which realpath() fails. */
    1418 static int readFilePathsFromDir(const char *pcszPath, DIR *pDir,
    1419                                 VECTOR_PTR(char *) *pvpchDevs, int withRealPath)
    1420 {
    1421     struct dirent entry, *pResult;
    1422     int err;
    1423 
    1424     for (err = readdir_r(pDir, &entry, &pResult); pResult;
    1425          err = readdir_r(pDir, &entry, &pResult))
    1426     {
    1427         /* We (implicitly) require that PATH_MAX be defined */
    1428         char szPath[PATH_MAX + 1], szRealPath[PATH_MAX + 1], *pszPath;
    1429         if (snprintf(szPath, sizeof(szPath), "%s/%s", pcszPath,
    1430                      entry.d_name) < 0)
    1431             return errno;
    1432         if (withRealPath)
    1433             pszPath = realpath(szPath, szRealPath);
    1434         else
    1435             pszPath = szPath;
    1436         if ((err = maybeAddPathToVector(pszPath, entry.d_name, pvpchDevs)))
    1437             return err;
    1438     }
    1439     return err;
    1440 }
    1441 
    1442 
    1443 /**
    1444  * Helper for walkDirectory to dump the names of a directory's entries into a
    1445  * vector of char pointers.
    1446  *
    1447  * @returns zero on success or (positive) posix error value.
    1448  * @param   pcszPath      the path to dump. 
    1449  * @param   pvpchDevs     an empty vector of char pointers - must be cleaned up
    1450  *                        by the caller even on failure.
    1451  * @param   withRealPath  whether to canonicalise the filename with realpath
    1452  */
    1453 static int readFilePaths(const char *pcszPath, VECTOR_PTR(char *) *pvpchDevs,
    1454                          int withRealPath)
    1455 {
    1456     DIR *pDir;
    1457     int err;
    1458 
    1459     AssertPtrReturn(pvpchDevs, EINVAL);
    1460     AssertReturn(VEC_SIZE_PTR(pvpchDevs) == 0, EINVAL);
    1461     AssertPtrReturn(pcszPath, EINVAL);
    1462 
    1463     pDir = opendir(pcszPath);
    1464     if (!pDir)
    1465         return errno;
    1466     err = readFilePathsFromDir(pcszPath, pDir, pvpchDevs, withRealPath);
    1467     if (closedir(pDir) < 0 && !err)
    1468         err = errno;
    1469     return err;
    1470 }
    1471 
    1472 
    1473 /**
    1474  * Helper for walkDirectory to walk a set of files, calling a function
    1475  * object on each.
    1476  *
    1477  * @returns zero on success or (positive) posix error value.
    1478  * @param   pcszPath     the path of the directory
    1479  * @param   pvpchDevs    vector of char strings containing the directory entry
    1480  *                       names
    1481  * @param   pHandler     Handler object which will be invoked on each file
    1482  */
    1483 static int walkFiles(VECTOR_PTR(char *) *pvpchDevs, pathHandler *pHandler)
    1484 {
    1485     char **ppszEntry;
    1486 
    1487     AssertPtrReturn(pvpchDevs, EINVAL);
    1488     AssertPtrReturn(pHandler, EINVAL);
    1489 
    1490     VEC_FOR_EACH(pvpchDevs, char *, ppszEntry)
    1491         if (!phDoHandle(pHandler, *ppszEntry))
    1492             break;
    1493     return 0;
    1494 }
    1495 
    1496 
    1497 /**
    1498  * Walk a directory and applying a function object to each entry which doesn't
    1499  * start with a dot.
    1500  * @returns iprt status code
    1501  * @param   pcszPath      Directory to walk.  May not be '/'-terminated.
    1502  * @param   pHandler      Handler object which will be invoked on each
    1503  *                        directoryentry
    1504  * @param   withRealPath  Whether to apply realpath() to each entry before
    1505  *                        invoking the handler
    1506  */
    1507 /* static */
    1508 int walkDirectory(const char *pcszPath, pathHandler *pHandler, int withRealPath)
    1509 {
    1510     VECTOR_PTR(char *) vpchDevs;
    1511     int rc;
    1512 
    1513     AssertPtrReturn(pcszPath, VERR_INVALID_POINTER);
    1514     AssertReturn(pcszPath[strlen(pcszPath)] != '/', VERR_INVALID_PARAMETER);
    1515 
    1516     if (RT_FAILURE((rc = VEC_INIT_PTR(&vpchDevs, char *, RTStrFree))))
    1517         return rc;
    1518     rc = readFilePaths(pcszPath, &vpchDevs, withRealPath);
    1519     if (!rc)
    1520         rc = walkFiles(&vpchDevs, pHandler);
    1521     VEC_CLEANUP_PTR(&vpchDevs);
    1522     return RTErrConvertFromErrno(rc);
    1523 }
    1524 
    15251431
    15261432#define USBDEVICE_MAJOR 189
     
    15471453
    15481454/**
    1549  * Tell whether a file in /sys/bus/usb/devices is a device rather than an
    1550  * interface.  To be used with getDeviceInfoFromSysfs().
    1551  */
    1552 typedef struct matchUSBDevice
    1553 {
    1554     /** The pathHandler object we inherit from - must come first */
    1555     pathHandler mParent;
    1556     VECTOR_OBJ(USBDeviceInfo) *mpvecDevInfo;
    1557 } matchUSBDevice;
    1558 
    1559 static bool mudHandle(pathHandler *pParent, const char *pcszNode)
    1560 {
    1561     AssertPtrReturn(pParent, false);
    1562     AssertReturn(pParent->handle = mudHandle, false);
    1563     matchUSBDevice *pSelf = (matchUSBDevice *)pParent;
     1455 * If a file @a pcszNode from /sys/bus/usb/devices is a device rather than an
     1456 * interface add an element for the device to @a pvecDevInfo.
     1457 */
     1458static int addIfDevice(const char *pcszNode,
     1459                       VECTOR_OBJ(USBDeviceInfo) *pvecDevInfo)
     1460{
    15641461    const char *pcszFile = strrchr(pcszNode, '/');
    15651462    if (strchr(pcszFile, ':'))
    1566         return true;
     1463        return VINF_SUCCESS;
    15671464    dev_t devnum = RTLinuxSysFsReadDevNumFile("%s/dev", pcszNode);
    15681465    /* Sanity test of our static helpers */
     
    15701467    Assert(usbDeviceFromDevNum(makedev(USBDEVICE_MAJOR, 517)) == 6);
    15711468    if (!devnum)
    1572         return true;
     1469        return VINF_SUCCESS;
    15731470    char szDevPath[RTPATH_MAX];
    15741471    ssize_t cchDevPath;
     
    15791476                                       usbDeviceFromDevNum(devnum));
    15801477    if (cchDevPath < 0)
    1581         return true;
     1478        return VINF_SUCCESS;
    15821479   
    15831480    USBDeviceInfo info;
    15841481    if (USBDevInfoInit(&info, szDevPath, pcszNode))
    1585         if (RT_SUCCESS(VEC_PUSH_BACK_OBJ(pSelf->mpvecDevInfo, USBDeviceInfo,
     1482        if (RT_SUCCESS(VEC_PUSH_BACK_OBJ(pvecDevInfo, USBDeviceInfo,
    15861483                                         &info)))
    1587             return true;
     1484            return VINF_SUCCESS;
    15881485    USBDevInfoCleanup(&info);
    1589     return false;
    1590 }
    1591 
    1592 static void mudInit(matchUSBDevice *pSelf,
    1593                     VECTOR_OBJ(USBDeviceInfo) *pvecDevInfo)
    1594 {
    1595     AssertPtrReturnVoid(pSelf);
    1596     pSelf->mParent.handle = mudHandle;
    1597     pSelf->mpvecDevInfo = pvecDevInfo;
    1598 }
    1599 
    1600 
    1601 /**
    1602  * Tell whether a file in /sys/bus/usb/devices is an interface rather than a
    1603  * device.  To be used with getDeviceInfoFromSysfs().
    1604  */
    1605 typedef struct matchUSBInterface
    1606 {
    1607     /** The pathHandler class we inherit from - must be the first member. */
    1608     pathHandler mParent;
    1609     USBDeviceInfo *mInfo;
    1610 } matchUSBInterface;
     1486    return VERR_NO_MEMORY;
     1487}
    16111488
    16121489/** The logic for testing whether a sysfs address corresponds to an
     
    16391516}
    16401517
    1641 static bool muiHandle(pathHandler *pParent, const char *pcszNode)
    1642 {
    1643     AssertPtrReturn(pParent, false);
    1644     AssertReturn(pParent->handle == muiHandle, false);
    1645     matchUSBInterface *pSelf = (matchUSBInterface *)pParent;
    1646     if (!muiIsAnInterfaceOf(pcszNode, pSelf->mInfo->mSysfsPath))
    1647         return true;
     1518#ifdef DEBUG
     1519/** Unit test the logic in muiIsAnInterfaceOf in debug builds. */
     1520class testIsAnInterfaceOf
     1521{
     1522public:
     1523    testIsAnInterfaceOf()
     1524    {
     1525        Assert(muiIsAnInterfaceOf("/sys/devices/pci0000:00/0000:00:1a.0/usb3/3-0:1.0",
     1526               "/sys/devices/pci0000:00/0000:00:1a.0/usb3"));
     1527        Assert(!muiIsAnInterfaceOf("/sys/devices/pci0000:00/0000:00:1a.0/usb3/3-1",
     1528               "/sys/devices/pci0000:00/0000:00:1a.0/usb3"));
     1529        Assert(!muiIsAnInterfaceOf("/sys/devices/pci0000:00/0000:00:1a.0/usb3/3-0:1.0/driver",
     1530               "/sys/devices/pci0000:00/0000:00:1a.0/usb3"));
     1531    }
     1532};
     1533static testIsAnInterfaceOf testIsAnInterfaceOfInst;
     1534#endif
     1535
     1536/**
     1537 * Tell whether a file in /sys/bus/usb/devices is an interface rather than a
     1538 * device.  To be used with getDeviceInfoFromSysfs().
     1539 */
     1540static int addIfInterfaceOf(const char *pcszNode, USBDeviceInfo *pInfo)
     1541{
     1542    if (!muiIsAnInterfaceOf(pcszNode, pInfo->mSysfsPath))
     1543        return VINF_SUCCESS;
    16481544    char *pszDup = (char *)RTStrDup(pcszNode);
    16491545    if (pszDup)
    1650         if (RT_SUCCESS(VEC_PUSH_BACK_PTR(&pSelf->mInfo->mvecpszInterfaces,
     1546        if (RT_SUCCESS(VEC_PUSH_BACK_PTR(&pInfo->mvecpszInterfaces,
    16511547                                         char *, pszDup)))
    1652             return true;
     1548            return VINF_SUCCESS;
    16531549    RTStrFree(pszDup);
    1654     return false;
    1655 }
    1656 
    1657 /** This constructor is currently used to unit test the class logic in
    1658  * debug builds.  Since no access is made to anything outside the class,
    1659  * this shouldn't cause any slowdown worth mentioning. */
    1660 static void muiInit(matchUSBInterface *pSelf, USBDeviceInfo *pInfo)
    1661 {
    1662     Assert(muiIsAnInterfaceOf("/sys/devices/pci0000:00/0000:00:1a.0/usb3/3-0:1.0",
    1663            "/sys/devices/pci0000:00/0000:00:1a.0/usb3"));
    1664     Assert(!muiIsAnInterfaceOf("/sys/devices/pci0000:00/0000:00:1a.0/usb3/3-1",
    1665            "/sys/devices/pci0000:00/0000:00:1a.0/usb3"));
    1666     Assert(!muiIsAnInterfaceOf("/sys/devices/pci0000:00/0000:00:1a.0/usb3/3-0:1.0/driver",
    1667            "/sys/devices/pci0000:00/0000:00:1a.0/usb3"));
    1668     AssertPtrReturnVoid(pSelf);
    1669     pSelf->mInfo = pInfo;
    1670     pSelf->mParent.handle = muiHandle;
     1550    return VERR_NO_MEMORY;
    16711551}
    16721552
    16731553/**
    1674  * Helper function to query the sysfs subsystem for information about USB
    1675  * devices attached to the system.
    1676  * @returns iprt status code
    1677  * @param   pList      where to add information about the drives detected
    1678  * @param   pfSuccess  Did we find anything?
    1679  *
    1680  * @returns IPRT status code
    1681  */
    1682 /* static */
    1683 int getUSBDeviceInfoFromSysfs(VECTOR_OBJ(USBDeviceInfo) *pvecDevInfo,
    1684                               bool *pfSuccess)
    1685 {
     1554 * Logic for USBDevInfoUpdateDevices.
     1555 * @param pvecDevInfo  vector of device information structures to add device
     1556 *                     information to
     1557 * @param pvecpchDevs  empty scratch vector which will be freed by the caller
     1558 */
     1559static int doUpdateUSBDevices(VECTOR_OBJ(USBDeviceInfo) *pvecDevInfo,
     1560                              VECTOR_PTR(char *) *pvecpchDevs)
     1561{
     1562    char **ppszEntry;
     1563    USBDeviceInfo *pInfo;
     1564    int rc;
     1565
    16861566    AssertPtrReturn(pvecDevInfo, VERR_INVALID_POINTER);
    1687     AssertPtrNullReturn(pfSuccess, VERR_INVALID_POINTER); /* Valid or Null */
    1688     LogFlowFunc (("pvecDevInfo=%p, pfSuccess=%p\n",
    1689                   pvecDevInfo, pfSuccess));
    1690     matchUSBDevice devHandler;
    1691     mudInit(&devHandler, pvecDevInfo);
    1692     int rc = walkDirectory("/sys/bus/usb/devices", &devHandler.mParent, true);
    1693     do {
    1694         if (RT_FAILURE(rc))
    1695             break;
    1696         USBDeviceInfo *pInfo;
    1697         VEC_FOR_EACH(pvecDevInfo, USBDeviceInfo, pInfo)
    1698         {
    1699             matchUSBInterface ifaceHandler;
    1700             muiInit(&ifaceHandler, pInfo);
    1701             rc = walkDirectory("/sys/bus/usb/devices", &ifaceHandler.mParent,
    1702                                true);
    1703             if (RT_FAILURE(rc))
    1704                 break;
    1705         }
    1706     } while(0);
    1707     if (pfSuccess)
    1708         *pfSuccess = RT_SUCCESS(rc);
    1709     LogFlow (("rc=%Rrc\n", rc));
    1710     return rc;
     1567    LogFlowFunc (("pvecDevInfo=%p\n", pvecDevInfo));
     1568
     1569    rc = readFilePaths("/sys/bus/usb/devices", pvecpchDevs, true);
     1570    if (RT_FAILURE(rc))
     1571        return rc;
     1572    VEC_FOR_EACH(pvecpchDevs, char *, ppszEntry)
     1573        if (RT_FAILURE(rc = addIfDevice(*ppszEntry, pvecDevInfo)))
     1574            return rc;
     1575    VEC_FOR_EACH(pvecDevInfo, USBDeviceInfo, pInfo)
     1576        VEC_FOR_EACH(pvecpchDevs, char *, ppszEntry)
     1577            if (RT_FAILURE(rc = addIfInterfaceOf(*ppszEntry, pInfo)))
     1578                return rc;
     1579    return VINF_SUCCESS;
    17111580}
    17121581# endif /* VBOX_USB_WITH_INOTIFY */
    17131582#endif /* VBOX_USB_WITH_SYSFS */
     1583
     1584int USBDevInfoUpdateDevices (VBoxMainUSBDeviceInfo *pSelf)
     1585{
     1586    LogFlowFunc(("entered\n"));
     1587    VECTOR_PTR(char *) vecpchDevs;
     1588    int rc = VEC_INIT_PTR(&vecpchDevs, char *, RTStrFree);
     1589    if (RT_FAILURE(rc))
     1590        return rc;
     1591    VEC_CLEAR_OBJ(&pSelf->mvecDevInfo);
     1592#ifdef VBOX_USB_WITH_SYSFS
     1593# ifdef VBOX_USB_WITH_INOTIFY
     1594    rc = doUpdateUSBDevices(&pSelf->mvecDevInfo, &vecpchDevs);
     1595# endif
     1596#endif /* !VBOX_USB_WITH_SYSFS */
     1597    VEC_CLEANUP_PTR(&vecpchDevs);
     1598    LogFlowFunc(("rc=%Rrc\n", rc));
     1599    return rc;
     1600}
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