VirtualBox

Changeset 32299 in vbox for trunk/src


Ignore:
Timestamp:
Sep 7, 2010 9:25:05 PM (14 years ago)
Author:
vboxsync
Message:

Main/USBProxyServiceLinux: move the implementation of the device enumeration code out of the class and into static C-like functions

Location:
trunk/src/VBox/Main
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/include/HostHardwareLinux.h

    r32262 r32299  
    131131
    132132/**
    133  * Class for probing and returning information about host USB devices.
    134  * To use this class, create an instance, call the update methods to do the
    135  * actual probing and use the iterator methods to get the result of the probe.
    136  */
    137 typedef struct VBoxMainUSBDeviceInfo
    138 {
    139     /** The list of currently available USB devices */
    140     VECTOR_OBJ(USBDeviceInfo) mvecDevInfo;
    141 } VBoxMainUSBDeviceInfo;
    142 
    143 /** Constructor */
    144 static inline void VBoxMainUSBDevInfoInit(VBoxMainUSBDeviceInfo *pSelf)
    145 {
    146     VEC_INIT_OBJ(&pSelf->mvecDevInfo, USBDeviceInfo, USBDevInfoCleanup);
    147 }
    148 
    149 /** Destructor */
    150 static inline void VBoxMainUSBDevInfoCleanup(VBoxMainUSBDeviceInfo *pSelf)
    151 {
    152     VEC_CLEANUP_OBJ(&pSelf->mvecDevInfo);
    153 }
    154 
    155 /**
    156  * Search for host USB devices and rebuild the list, which remains empty
    157  * until the first time this method is called.
     133 * Enumerate USB devices attached to the host using sysfs and return them as a
     134 * vector
    158135 * @returns iprt status code
    159  */
    160 int USBDevInfoUpdateDevices(VBoxMainUSBDeviceInfo *pSelf);
     136 * @param pvecDevInfo  vector to add the devices onto the end of.  Should be
     137 *                     initialised and empty.
     138 */
     139int USBSysfsEnumerateHostDevices(VECTOR_OBJ(USBDeviceInfo) *pvecDevInfo);
    161140
    162141
  • trunk/src/VBox/Main/include/USBProxyService.h

    r31892 r32299  
    219219    virtual int interruptWait(void);
    220220    virtual PUSBDEVICE getDevices(void);
    221     PUSBDEVICE getDevicesFromUsbfs(void);
    222     PUSBDEVICE getDevicesFromSysfs(void);
    223     int addDeviceToChain(PUSBDEVICE pDev, PUSBDEVICE *ppFirst, PUSBDEVICE **pppNext, int rc);
    224221    virtual void deviceAdded(ComObjPtr<HostUSBDevice> &aDevice, SessionMachinesList &llOpenedMachines, PUSBDEVICE aUSBDevice);
    225222    virtual bool updateDeviceState(HostUSBDevice *aDevice, PUSBDEVICE aUSBDevice, bool *aRunFilters, SessionMachine **aIgnoreMachine);
     
    245242    unsigned mUdevPolls;
    246243#  ifdef VBOX_USB_WITH_SYSFS
    247     /** Object used for querying device information from hal. */
    248     VBoxMainUSBDeviceInfo mDeviceList;
    249244    /** Object used for polling for hotplug events from hal. */
    250245    VBoxMainHotplugWaiter mWaiter;
  • trunk/src/VBox/Main/linux/HostHardwareLinux.cpp

    r32262 r32299  
    15491549
    15501550/**
    1551  * Logic for USBDevInfoUpdateDevices.
     1551 * Logic for USBSysfsEnumerateHostDevices.
    15521552 * @param pvecDevInfo  vector of device information structures to add device
    15531553 *                     information to
    15541554 * @param pvecpchDevs  empty scratch vector which will be freed by the caller
    15551555 */
    1556 static int doUpdateUSBDevices(VECTOR_OBJ(USBDeviceInfo) *pvecDevInfo,
     1556static int doSysfsEnumerateHostDevices(VECTOR_OBJ(USBDeviceInfo) *pvecDevInfo,
    15571557                              VECTOR_PTR(char *) *pvecpchDevs)
    15581558{
     
    15791579#endif /* VBOX_USB_WITH_SYSFS */
    15801580
    1581 int USBDevInfoUpdateDevices (VBoxMainUSBDeviceInfo *pSelf)
    1582 {
    1583     int rc = VINF_SUCCESS;
    1584 
     1581int USBSysfsEnumerateHostDevices(VECTOR_OBJ(USBDeviceInfo) *pvecDevInfo)
     1582{
     1583    VECTOR_PTR(char *) vecpchDevs;
     1584    int rc = VERR_NOT_IMPLEMENTED;
     1585
     1586    AssertReturn(VEC_SIZE_OBJ(pvecDevInfo) == 0, VERR_INVALID_PARAMETER);
    15851587    LogFlowFunc(("entered\n"));
    1586     VECTOR_PTR(char *) vecpchDevs;
    15871588    VEC_INIT_PTR(&vecpchDevs, char *, RTStrFree);
    1588     VEC_CLEAR_OBJ(&pSelf->mvecDevInfo);
    15891589#ifdef VBOX_USB_WITH_SYSFS
    15901590# ifdef VBOX_USB_WITH_INOTIFY
    1591     rc = doUpdateUSBDevices(&pSelf->mvecDevInfo, &vecpchDevs);
     1591    rc = doSysfsEnumerateHostDevices(pvecDevInfo, &vecpchDevs);
    15921592# endif
    15931593#endif /* !VBOX_USB_WITH_SYSFS */
  • trunk/src/VBox/Main/linux/USBProxyServiceLinux.cpp

    r32262 r32299  
    263263
    264264#ifdef VBOX_USB_WITH_SYSFS
    265     VBoxMainUSBDevInfoInit(&mDeviceList);
    266265    int rc = mWaiter.getStatus();
    267266    if (RT_SUCCESS(rc) || rc == VERR_TIMEOUT || rc == VERR_TRY_AGAIN)
     
    475474}
    476475
     476/**
     477 * Free all the members of a USB device created by the Linux enumeration code.
     478 * @note this duplicates a USBProxyService method which we needed access too
     479 *       without pulling in the rest of the proxy service code.
     480 *
     481 * @param   pDevice     Pointer to the device.
     482 */
     483static void deviceFreeMembers(PUSBDEVICE pDevice)
     484{
     485    RTStrFree((char *)pDevice->pszManufacturer);
     486    pDevice->pszManufacturer = NULL;
     487    RTStrFree((char *)pDevice->pszProduct);
     488    pDevice->pszProduct = NULL;
     489    RTStrFree((char *)pDevice->pszSerialNumber);
     490    pDevice->pszSerialNumber = NULL;
     491
     492    RTStrFree((char *)pDevice->pszAddress);
     493    pDevice->pszAddress = NULL;
     494}
     495
     496/**
     497 * Free one USB device created by the Linux enumeration code.
     498 * @note this duplicates a USBProxyService method which we needed access too
     499 *       without pulling in the rest of the proxy service code.
     500 *
     501 * @param   pDevice     Pointer to the device.
     502 */
     503static void deviceFree(PUSBDEVICE pDevice)
     504{
     505    deviceFreeMembers(pDevice);
     506    RTMemFree(pDevice);
     507}
    477508
    478509/**
     
    836867
    837868/** Just a worker for USBProxyServiceLinux::getDevices that avoids some code duplication. */
    838 int USBProxyServiceLinux::addDeviceToChain(PUSBDEVICE pDev, PUSBDEVICE *ppFirst, PUSBDEVICE **pppNext, int rc)
     869static int addDeviceToChain(PUSBDEVICE pDev, PUSBDEVICE *ppFirst, PUSBDEVICE **pppNext, const char *pcszUsbfsRoot, int rc)
    839870{
    840871    /* usbDeterminState requires the address. */
     
    842873    if (pDevNew)
    843874    {
    844         RTStrAPrintf((char **)&pDevNew->pszAddress, "%s/%03d/%03d", mUsbfsRoot.c_str(), pDevNew->bBus, pDevNew->bDevNum);
     875        RTStrAPrintf((char **)&pDevNew->pszAddress, "%s/%03d/%03d", pcszUsbfsRoot, pDevNew->bBus, pDevNew->bDevNum);
    845876        if (pDevNew->pszAddress)
    846877        {
     
    855886            }
    856887            else
    857                 freeDevice(pDevNew);
     888                deviceFree(pDevNew);
    858889        }
    859890        else
    860891        {
    861             freeDevice(pDevNew);
     892            deviceFree(pDevNew);
    862893            rc = VERR_NO_MEMORY;
    863894        }
     
    866897    {
    867898        rc = VERR_NO_MEMORY;
    868         freeDeviceMembers(pDev);
     899        deviceFreeMembers(pDev);
    869900    }
    870901
     
    873904
    874905
     906static int openDevicesFile(const char *pcszUsbfsRoot, FILE **ppFile)
     907{
     908    char *pszPath;
     909    FILE *pFile;
     910    RTStrAPrintf(&pszPath, "%s/devices", pcszUsbfsRoot);
     911    if (!pszPath)
     912        return VERR_NO_MEMORY;
     913    pFile = fopen(pszPath, "r");
     914    RTStrFree(pszPath);
     915    if (!pFile)
     916        return RTErrConvertFromErrno(errno);
     917    *ppFile = pFile;
     918    return VINF_SUCCESS;
     919}
     920
    875921/**
    876922 * USBProxyService::getDevices() implementation for usbfs.
    877923 */
    878 PUSBDEVICE USBProxyServiceLinux::getDevicesFromUsbfs(void)
     924static PUSBDEVICE getDevicesFromUsbfs(const char *pcszUsbfsRoot)
    879925{
    880926    PUSBDEVICE pFirst = NULL;
    881     if (mStream)
     927    FILE *pFile;
     928    int rc;
     929    rc = openDevicesFile(pcszUsbfsRoot, &pFile);
     930    if (RT_SUCCESS(rc))
    882931    {
    883932        PUSBDEVICE     *ppNext = NULL;
     
    888937        Dev.enmState = USBDEVICESTATE_UNUSED;
    889938
    890         /*
    891          * Rewind the stream and make 100% sure we flush the buffer.
    892          *
    893          * We've had trouble with rewind() messing up on buffered streams when attaching
    894          * device clusters such as the Bloomberg keyboard. Therefor the stream is now
    895          * without a permanent buffer (see the constructor) and we'll employ a temporary
    896          * stack buffer while parsing the file (speed).
    897          */
    898         rewind(mStream);
    899         char szBuf[1024];
    900         setvbuf(mStream, szBuf, _IOFBF, sizeof(szBuf));
    901 
    902         int rc = VINF_SUCCESS;
     939        rc = VINF_SUCCESS;
    903940        while (     RT_SUCCESS(rc)
    904                &&   fgets(szLine, sizeof(szLine), mStream))
     941               &&   fgets(szLine, sizeof(szLine), pFile))
    905942        {
    906943            char   *psz;
     
    909946            /* validate and remove the trailing newline. */
    910947            psz = strchr(szLine, '\0');
    911             if (psz[-1] != '\n' && !feof(mStream))
     948            if (psz[-1] != '\n' && !feof(pFile))
    912949            {
    913950                AssertMsgFailed(("Line too long. (cch=%d)\n", strlen(szLine)));
     
    947984                    AssertMsg(cHits >= 3 || cHits == 0, ("cHits=%d\n", cHits));
    948985                    if (cHits >= 3)
    949                         rc = addDeviceToChain(&Dev, &pFirst, &ppNext, rc);
     986                        rc = addDeviceToChain(&Dev, &pFirst, &ppNext, pcszUsbfsRoot, rc);
    950987                    else
    951                         freeDeviceMembers(&Dev);
     988                        deviceFreeMembers(&Dev);
    952989
    953990                    /* Reset device state */
     
    11391176        AssertMsg(cHits >= 3 || cHits == 0, ("cHits=%d\n", cHits));
    11401177        if (cHits >= 3)
    1141             rc = addDeviceToChain(&Dev, &pFirst, &ppNext, rc);
     1178            rc = addDeviceToChain(&Dev, &pFirst, &ppNext, pcszUsbfsRoot, rc);
    11421179
    11431180        /*
     
    11461183        if (RT_FAILURE(rc))
    11471184        {
    1148             LogFlow(("USBProxyServiceLinux::getDevices: rc=%Rrc\n", rc));
    11491185            while (pFirst)
    11501186            {
    11511187                PUSBDEVICE pFree = pFirst;
    11521188                pFirst = pFirst->pNext;
    1153                 freeDevice(pFree);
     1189                deviceFree(pFree);
    11541190            }
    11551191        }
    1156 
    1157         /*
    1158          * Turn buffering off to detach it from the local buffer and to
    1159          * make subsequent rewind() calls work correctly.
    1160          */
    1161         setvbuf(mStream, NULL, _IONBF, 0);
    1162     }
     1192    }
     1193    if (RT_FAILURE(rc))
     1194        LogFlow(("USBProxyServiceLinux::getDevices: rc=%Rrc\n", rc));
    11631195    return pFirst;
    11641196}
     
    13331365#endif  /* VBOX_USB_WITH_SYSFS */
    13341366
     1367static void fillInDeviceFromSysfs(USBDEVICE *Dev, USBDeviceInfo *pInfo)
     1368{
     1369    int rc;
     1370    const char *pszSysfsPath = pInfo->mSysfsPath;
     1371
     1372    /* Fill in the simple fields */
     1373    Dev->enmState           = USBDEVICESTATE_UNUSED;
     1374    Dev->bBus               = RTLinuxSysFsReadIntFile(10, "%s/busnum", pszSysfsPath);
     1375    Dev->bDeviceClass       = RTLinuxSysFsReadIntFile(16, "%s/bDeviceClass", pszSysfsPath);
     1376    Dev->bDeviceSubClass    = RTLinuxSysFsReadIntFile(16, "%s/bDeviceSubClass", pszSysfsPath);
     1377    Dev->bDeviceProtocol    = RTLinuxSysFsReadIntFile(16, "%s/bDeviceProtocol", pszSysfsPath);
     1378    Dev->bNumConfigurations = RTLinuxSysFsReadIntFile(10, "%s/bNumConfigurations", pszSysfsPath);
     1379    Dev->idVendor           = RTLinuxSysFsReadIntFile(16, "%s/idVendor", pszSysfsPath);
     1380    Dev->idProduct          = RTLinuxSysFsReadIntFile(16, "%s/idProduct", pszSysfsPath);
     1381    Dev->bDevNum            = RTLinuxSysFsReadIntFile(10, "%s/devnum", pszSysfsPath);
     1382
     1383    /* Now deal with the non-numeric bits. */
     1384    char szBuf[1024];  /* Should be larger than anything a sane device
     1385                        * will need, and insane devices can be unsupported
     1386                        * until further notice. */
     1387    ssize_t cchRead;
     1388
     1389    /* For simplicity, we just do strcmps on the next one. */
     1390    cchRead = RTLinuxSysFsReadStrFile(szBuf, sizeof(szBuf), "%s/speed",
     1391                                      pszSysfsPath);
     1392    if (cchRead <= 0 || (size_t) cchRead == sizeof(szBuf))
     1393        Dev->enmState = USBDEVICESTATE_UNSUPPORTED;
     1394    else
     1395        Dev->enmSpeed =   !strcmp(szBuf, "1.5") ? USBDEVICESPEED_LOW
     1396                        : !strcmp(szBuf, "12")  ? USBDEVICESPEED_FULL
     1397                        : !strcmp(szBuf, "480") ? USBDEVICESPEED_HIGH
     1398                        : USBDEVICESPEED_UNKNOWN;
     1399
     1400    cchRead = RTLinuxSysFsReadStrFile(szBuf, sizeof(szBuf), "%s/version",
     1401                                      pszSysfsPath);
     1402    if (cchRead <= 0 || (size_t) cchRead == sizeof(szBuf))
     1403        Dev->enmState = USBDEVICESTATE_UNSUPPORTED;
     1404    else
     1405    {
     1406        rc = convertSysfsStrToBCD(szBuf, &Dev->bcdUSB);
     1407        if (RT_FAILURE(rc))
     1408        {
     1409            Dev->enmState = USBDEVICESTATE_UNSUPPORTED;
     1410            Dev->bcdUSB = (uint16_t)-1;
     1411        }
     1412    }
     1413
     1414    cchRead = RTLinuxSysFsReadStrFile(szBuf, sizeof(szBuf), "%s/bcdDevice",
     1415                                      pszSysfsPath);
     1416    if (cchRead <= 0 || (size_t) cchRead == sizeof(szBuf))
     1417        Dev->bcdDevice = (uint16_t)-1;
     1418    else
     1419    {
     1420        rc = convertSysfsStrToBCD(szBuf, &Dev->bcdDevice);
     1421        if (RT_FAILURE(rc))
     1422            Dev->bcdDevice = (uint16_t)-1;
     1423    }
     1424
     1425    /* Now do things that need string duplication */
     1426    cchRead = RTLinuxSysFsReadStrFile(szBuf, sizeof(szBuf), "%s/product",
     1427                                      pszSysfsPath);
     1428    if (cchRead > 0 && (size_t) cchRead < sizeof(szBuf))
     1429    {
     1430        RTStrPurgeEncoding(szBuf);
     1431        Dev->pszProduct = RTStrDup(szBuf);
     1432    }
     1433
     1434    cchRead = RTLinuxSysFsReadStrFile(szBuf, sizeof(szBuf), "%s/serial",
     1435                                      pszSysfsPath);
     1436    if (cchRead > 0 && (size_t) cchRead < sizeof(szBuf))
     1437    {
     1438        RTStrPurgeEncoding(szBuf);
     1439        Dev->pszSerialNumber = RTStrDup(szBuf);
     1440        Dev->u64SerialHash = USBLibHashSerial(szBuf);
     1441    }
     1442
     1443    cchRead = RTLinuxSysFsReadStrFile(szBuf, sizeof(szBuf), "%s/manufacturer",
     1444                                      pszSysfsPath);
     1445    if (cchRead > 0 && (size_t) cchRead < sizeof(szBuf))
     1446    {
     1447        RTStrPurgeEncoding(szBuf);
     1448        Dev->pszManufacturer = RTStrDup(szBuf);
     1449    }
     1450
     1451    /* Work out the port number */
     1452    if (RT_FAILURE(usbGetPortFromSysfsPath(pszSysfsPath, &Dev->bPort)))
     1453        Dev->enmState = USBDEVICESTATE_UNSUPPORTED;
     1454
     1455    /* Check the interfaces to see if we can support the device. */
     1456    char **ppszIf;
     1457    VEC_FOR_EACH(&pInfo->mvecpszInterfaces, char *, ppszIf)
     1458    {
     1459        ssize_t cb = RTLinuxSysFsGetLinkDest(szBuf, sizeof(szBuf), "%s/driver",
     1460                                             *ppszIf);
     1461        if (cb > 0 && Dev->enmState != USBDEVICESTATE_UNSUPPORTED)
     1462            Dev->enmState = (strcmp(szBuf, "hub") == 0)
     1463                          ? USBDEVICESTATE_UNSUPPORTED
     1464                          : USBDEVICESTATE_USED_BY_HOST_CAPTURABLE;
     1465        if (RTLinuxSysFsReadIntFile(16, "%s/bInterfaceClass",
     1466                                    *ppszIf) == 9 /* hub */)
     1467            Dev->enmState = USBDEVICESTATE_UNSUPPORTED;
     1468    }
     1469
     1470    /* We want a copy of the device node and sysfs paths guaranteed not to
     1471     * contain double slashes, since we use a double slash as a separator in
     1472     * the pszAddress field. */
     1473    char szDeviceClean[RTPATH_MAX];
     1474    char szSysfsClean[RTPATH_MAX];
     1475    char *pszAddress = NULL;
     1476    if (   RT_SUCCESS(RTPathReal(pInfo->mDevice, szDeviceClean,
     1477                                 sizeof(szDeviceClean)))
     1478        && RT_SUCCESS(RTPathReal(pszSysfsPath, szSysfsClean,
     1479                                 sizeof(szSysfsClean)))
     1480       )
     1481        RTStrAPrintf(&pszAddress, "sysfs:%s//device:%s", szSysfsClean,
     1482                     szDeviceClean);
     1483    Dev->pszAddress = pszAddress;
     1484
     1485    /* Work out from the data collected whether we can support this device. */
     1486    Dev->enmState = usbDeterminState(Dev);
     1487    usbLogDevice(Dev);
     1488}
     1489
    13351490/**
    13361491 * USBProxyService::getDevices() implementation for sysfs.
    13371492 */
    1338 PUSBDEVICE USBProxyServiceLinux::getDevicesFromSysfs(void)
     1493static PUSBDEVICE getDevicesFromSysfs(void)
    13391494{
    13401495#ifdef VBOX_USB_WITH_SYSFS
     
    13421497    PUSBDEVICE pFirst = NULL;
    13431498    PUSBDEVICE pLast  = NULL;
    1344     int        rc     = USBDevInfoUpdateDevices(&mDeviceList);
     1499    VECTOR_OBJ(USBDeviceInfo) vecDevInfo;
    13451500    USBDeviceInfo *pInfo;
    1346     VEC_FOR_EACH(&mDeviceList.mvecDevInfo, USBDeviceInfo, pInfo)
     1501    int rc;
     1502
     1503    VEC_INIT_OBJ(&vecDevInfo, USBDeviceInfo, USBDevInfoCleanup);
     1504    rc = USBSysfsEnumerateHostDevices(&vecDevInfo);
     1505    if (RT_FAILURE(rc))
     1506        return NULL;
     1507    VEC_FOR_EACH(&vecDevInfo, USBDeviceInfo, pInfo)
    13471508    {
    13481509        USBDEVICE *Dev = (USBDEVICE *)RTMemAllocZ(sizeof(USBDEVICE));
     
    13511512        if (RT_SUCCESS(rc))
    13521513        {
    1353             const char *pszSysfsPath = pInfo->mSysfsPath;
    1354 
    1355             /* Fill in the simple fields */
    1356             Dev->enmState = USBDEVICESTATE_UNUSED;
    1357             Dev->bBus               = RTLinuxSysFsReadIntFile(10, "%s/busnum", pszSysfsPath);
    1358             Dev->bDeviceClass       = RTLinuxSysFsReadIntFile(16, "%s/bDeviceClass", pszSysfsPath);
    1359             Dev->bDeviceSubClass    = RTLinuxSysFsReadIntFile(16, "%s/bDeviceSubClass", pszSysfsPath);
    1360             Dev->bDeviceProtocol    = RTLinuxSysFsReadIntFile(16, "%s/bDeviceProtocol", pszSysfsPath);
    1361             Dev->bNumConfigurations = RTLinuxSysFsReadIntFile(10, "%s/bNumConfigurations", pszSysfsPath);
    1362             Dev->idVendor           = RTLinuxSysFsReadIntFile(16, "%s/idVendor", pszSysfsPath);
    1363             Dev->idProduct          = RTLinuxSysFsReadIntFile(16, "%s/idProduct", pszSysfsPath);
    1364             Dev->bDevNum            = RTLinuxSysFsReadIntFile(10, "%s/devnum", pszSysfsPath);
    1365 
    1366             /* Now deal with the non-numeric bits. */
    1367             char szBuf[1024];  /* Should be larger than anything a sane device
    1368                                 * will need, and insane devices can be unsupported
    1369                                 * until further notice. */
    1370             ssize_t cchRead;
    1371 
    1372             /* For simplicity, we just do strcmps on the next one. */
    1373             cchRead = RTLinuxSysFsReadStrFile(szBuf, sizeof(szBuf), "%s/speed",
    1374                                               pszSysfsPath);
    1375             if (cchRead <= 0 || (size_t) cchRead == sizeof(szBuf))
    1376                 Dev->enmState = USBDEVICESTATE_UNSUPPORTED;
    1377             else
    1378                 Dev->enmSpeed =   !strcmp(szBuf, "1.5") ? USBDEVICESPEED_LOW
    1379                                 : !strcmp(szBuf, "12")  ? USBDEVICESPEED_FULL
    1380                                 : !strcmp(szBuf, "480") ? USBDEVICESPEED_HIGH
    1381                                 : USBDEVICESPEED_UNKNOWN;
    1382 
    1383             cchRead = RTLinuxSysFsReadStrFile(szBuf, sizeof(szBuf), "%s/version",
    1384                                               pszSysfsPath);
    1385             if (cchRead <= 0 || (size_t) cchRead == sizeof(szBuf))
    1386                 Dev->enmState = USBDEVICESTATE_UNSUPPORTED;
    1387             else
    1388             {
    1389                 rc = convertSysfsStrToBCD(szBuf, &Dev->bcdUSB);
    1390                 if (RT_FAILURE(rc))
    1391                 {
    1392                     Dev->enmState = USBDEVICESTATE_UNSUPPORTED;
    1393                     Dev->bcdUSB = (uint16_t)-1;
    1394                 }
    1395             }
    1396 
    1397             cchRead = RTLinuxSysFsReadStrFile(szBuf, sizeof(szBuf), "%s/bcdDevice",
    1398                                               pszSysfsPath);
    1399             if (cchRead <= 0 || (size_t) cchRead == sizeof(szBuf))
    1400                 Dev->bcdDevice = (uint16_t)-1;
    1401             else
    1402             {
    1403                 rc = convertSysfsStrToBCD(szBuf, &Dev->bcdDevice);
    1404                 if (RT_FAILURE(rc))
    1405                     Dev->bcdDevice = (uint16_t)-1;
    1406             }
    1407 
    1408             /* Now do things that need string duplication */
    1409             cchRead = RTLinuxSysFsReadStrFile(szBuf, sizeof(szBuf), "%s/product",
    1410                                               pszSysfsPath);
    1411             if (cchRead > 0 && (size_t) cchRead < sizeof(szBuf))
    1412             {
    1413                 RTStrPurgeEncoding(szBuf);
    1414                 Dev->pszProduct = RTStrDup(szBuf);
    1415             }
    1416 
    1417             cchRead = RTLinuxSysFsReadStrFile(szBuf, sizeof(szBuf), "%s/serial",
    1418                                               pszSysfsPath);
    1419             if (cchRead > 0 && (size_t) cchRead < sizeof(szBuf))
    1420             {
    1421                 RTStrPurgeEncoding(szBuf);
    1422                 Dev->pszSerialNumber = RTStrDup(szBuf);
    1423                 Dev->u64SerialHash = USBLibHashSerial(szBuf);
    1424             }
    1425 
    1426             cchRead = RTLinuxSysFsReadStrFile(szBuf, sizeof(szBuf), "%s/manufacturer",
    1427                                               pszSysfsPath);
    1428             if (cchRead > 0 && (size_t) cchRead < sizeof(szBuf))
    1429             {
    1430                 RTStrPurgeEncoding(szBuf);
    1431                 Dev->pszManufacturer = RTStrDup(szBuf);
    1432             }
    1433 
    1434             /* Work out the port number */
    1435             if (RT_FAILURE(usbGetPortFromSysfsPath(pszSysfsPath, &Dev->bPort)))
    1436                 Dev->enmState = USBDEVICESTATE_UNSUPPORTED;
    1437 
    1438             /* Check the interfaces to see if we can support the device. */
    1439             char **ppszIf;
    1440             VEC_FOR_EACH(&pInfo->mvecpszInterfaces, char *, ppszIf)
    1441             {
    1442                 ssize_t cb = RTLinuxSysFsGetLinkDest(szBuf, sizeof(szBuf), "%s/driver",
    1443                                                      *ppszIf);
    1444                 if (cb > 0 && Dev->enmState != USBDEVICESTATE_UNSUPPORTED)
    1445                     Dev->enmState = (strcmp(szBuf, "hub") == 0)
    1446                                   ? USBDEVICESTATE_UNSUPPORTED
    1447                                   : USBDEVICESTATE_USED_BY_HOST_CAPTURABLE;
    1448                 if (RTLinuxSysFsReadIntFile(16, "%s/bInterfaceClass",
    1449                                             *ppszIf) == 9 /* hub */)
    1450                     Dev->enmState = USBDEVICESTATE_UNSUPPORTED;
    1451             }
    1452 
    1453             /* We want a copy of the device node and sysfs paths guaranteed not to
    1454              * contain double slashes, since we use a double slash as a separator in
    1455              * the pszAddress field. */
    1456             char szDeviceClean[RTPATH_MAX];
    1457             char szSysfsClean[RTPATH_MAX];
    1458             char *pszAddress = NULL;
    1459             if (   RT_SUCCESS(RTPathReal(pInfo->mDevice, szDeviceClean,
    1460                                          sizeof(szDeviceClean)))
    1461                 && RT_SUCCESS(RTPathReal(pszSysfsPath, szSysfsClean,
    1462                                          sizeof(szSysfsClean)))
    1463                )
    1464                 RTStrAPrintf(&pszAddress, "sysfs:%s//device:%s", szSysfsClean,
    1465                              szDeviceClean);
    1466             Dev->pszAddress = pszAddress;
    1467 
    1468             /* Work out from the data collected whether we can support this device. */
    1469             Dev->enmState = usbDeterminState(Dev);
    1470             usbLogDevice(Dev);
     1514            fillInDeviceFromSysfs(Dev, pInfo);
    14711515        }
    14721516        if (   RT_SUCCESS(rc)
     
    14841528        }
    14851529        else
    1486             freeDevice(Dev);
     1530            deviceFree(Dev);
    14871531        if (RT_FAILURE(rc))
    14881532            break;
     
    14921536        {
    14931537            PUSBDEVICE pNext = pFirst->pNext;
    1494             freeDevice(pFirst);
     1538            deviceFree(pFirst);
    14951539            pFirst = pNext;
    14961540        }
    14971541
    1498     /* Eliminate any duplicates.  This was originally a sanity check, but it
    1499      * turned out that hal can get confused and return devices twice. */
    1500     for (PUSBDEVICE pDev = pFirst; pDev != NULL; pDev = pDev->pNext)
    1501         for (PUSBDEVICE pDev2 = pDev; pDev2 != NULL && pDev2->pNext != NULL;
    1502              pDev2 = pDev2->pNext)
    1503             while (   pDev2->pNext != NULL
    1504                    && RTStrCmp(pDev->pszAddress, pDev2->pNext->pszAddress) == 0)
    1505             {
    1506                 PUSBDEVICE pDup = pDev2->pNext;
    1507                 pDev2->pNext = pDup->pNext;
    1508                 freeDevice(pDup);
    1509             }
     1542    VEC_CLEANUP_OBJ(&vecDevInfo);
    15101543    return pFirst;
    15111544#else  /* !VBOX_USB_WITH_SYSFS */
     
    15141547}
    15151548
     1549static PUSBDEVICE USBProxyLinuxGetDevices(const char *pcszUsbfsRoot)
     1550{
     1551    if (pcszUsbfsRoot)
     1552        return getDevicesFromUsbfs(pcszUsbfsRoot);
     1553    else
     1554        return getDevicesFromSysfs();
     1555}
    15161556
    15171557PUSBDEVICE USBProxyServiceLinux::getDevices(void)
    15181558{
    1519     PUSBDEVICE pDevices;
    15201559    if (mUsingUsbfsDevices)
    1521         pDevices = getDevicesFromUsbfs();
     1560        return USBProxyLinuxGetDevices(mUsbfsRoot.c_str());
    15221561    else
    1523         pDevices = getDevicesFromSysfs();
    1524     return pDevices;
    1525 }
    1526 
     1562        return USBProxyLinuxGetDevices(NULL);
     1563}
     1564
  • trunk/src/VBox/Main/testcase/tstHostHardwareLinux.cpp

    r32262 r32299  
    9191    }
    9292#ifdef VBOX_USB_WITH_SYSFS
    93     VBoxMainUSBDeviceInfo deviceInfo;
    94     VBoxMainUSBDevInfoInit(&deviceInfo);
    95     rc = USBDevInfoUpdateDevices(&deviceInfo);
     93    VECTOR_OBJ(USBDeviceInfo) vecDevInfo;
     94    VEC_INIT_OBJ(&vecDevInfo, USBDeviceInfo, USBDevInfoCleanup);
     95    rc = USBSysfsEnumerateHostDevices(&vecDevInfo);
    9696    if (RT_FAILURE(rc))
    9797    {
     
    102102    RTPrintf ("Listing USB devices detected:\n");
    103103    USBDeviceInfo *pInfo;
    104     VEC_FOR_EACH(&deviceInfo.mvecDevInfo, USBDeviceInfo, pInfo)
     104    VEC_FOR_EACH(&vecDevInfo, USBDeviceInfo, pInfo)
    105105    {
    106106        char szProduct[1024];
     
    146146        }
    147147    }
     148    VEC_CLEANUP_OBJ(&vecDevInfo);
    148149    VBoxMainHotplugWaiter waiter;
    149150    RTPrintf ("Waiting for a hotplug event for five seconds...\n");
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