- Timestamp:
- Sep 6, 2010 11:24:02 PM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/linux/HostHardwareLinux.cpp
r32258 r32261 91 91 static int getDriveInfoFromSysfs(DriveInfoList *pList, bool isDVD, 92 92 bool *pfSuccess); 93 #ifdef VBOX_USB_WITH_SYSFS94 # ifdef VBOX_USB_WITH_INOTIFY95 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 pathHandler100 {101 /** Called on each element of the sysfs directory. Can e.g. store102 * 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 # endif118 #endif /* VBOX_USB_WITH_SYSFS */119 120 93 121 94 /** Find the length of a string, ignoring trailing non-ascii or control … … 1000 973 } 1001 974 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 (".", "..", ".*"). */ 978 static int maybeAddPathToVector(const char *pcszPath, const char *pcszEntry, 979 VECTOR_PTR(char *) *pvecpchDevs) 980 { 981 char *pszPath; 982 983 if (!pcszPath) 1019 984 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. */ 998 static 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 */ 1033 static 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); 1041 1050 } 1042 1051 … … 1064 1073 # ifdef VBOX_USB_WITH_INOTIFY 1065 1074 /** 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 */ 1068 1076 typedef struct inotifyWatch 1069 1077 { 1070 /** The pathHandler we inherit from - this must be the first structure1071 * member */1072 pathHandler mParent;1073 1078 /** Pointer to the inotify_add_watch() glibc function/Linux API */ 1074 1079 int (*inotify_add_watch)(int, const char *, uint32_t); … … 1081 1086 #define IN_FLAGS 0x306 1082 1087 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; 1088 static int iwAddWatch(inotifyWatch *pSelf, const char *pcszPath) 1089 { 1088 1090 errno = 0; 1089 1091 if ( pSelf->inotify_add_watch(pSelf->mhInotify, pcszPath, IN_FLAGS) >= 0 1090 1092 || (errno == EACCES)) 1091 return true;1093 return VINF_SUCCESS; 1092 1094 /* Other errors listed in the manpage can be treated as fatal */ 1093 return false;1095 return RTErrConvertFromErrno(errno); 1094 1096 } 1095 1097 … … 1102 1104 1103 1105 AssertPtr(pSelf); 1104 pSelf->mParent.handle = iwHandle;1105 1106 pSelf->mhInotify = -1; 1106 1107 errno = 0; … … 1259 1260 if (RT_FAILURE(rc = iwInit(&mWatches))) 1260 1261 break; 1261 phDoHandle(&mWatches.mParent, SYSFS_USB_DEVICE_PATH); 1262 if (RT_FAILURE(rc = iwAddWatch(&mWatches, SYSFS_USB_DEVICE_PATH))) 1263 break; 1262 1264 if (RT_FAILURE(rc = pipeCreateSimple(&mhWakeupPipeR, &mhWakeupPipeW))) 1263 1265 break; … … 1317 1319 { 1318 1320 int rc; 1321 char **ppszEntry; 1322 VECTOR_PTR(char *) vecpchDevs; 1319 1323 1320 1324 AssertRCReturn(mStatus, VERR_WRONG_ORDER); 1325 if (RT_FAILURE(rc = VEC_INIT_PTR(&vecpchDevs, char *, RTStrFree))) 1326 return rc; 1321 1327 bool fEntered = ASMAtomicCmpXchgU32(&mfWaiting, 1, 0); 1328 if (!fEntered) 1329 VEC_CLEANUP_PTR(&vecpchDevs); 1322 1330 AssertReturn(fEntered, VERR_WRONG_ORDER); 1323 1331 do { 1324 1332 struct pollfd pollFD[MAX_POLLID]; 1325 1333 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)) 1328 1340 break; 1329 1341 pollFD[RPIPE_ID].fd = mhWakeupPipeR; … … 1358 1370 } while (false); 1359 1371 mfWaiting = 0; 1372 VEC_CLEANUP_PTR(&vecpchDevs); 1360 1373 return rc; 1361 1374 } … … 1392 1405 } 1393 1406 1407 void 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 1415 int 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 1394 1429 #ifdef VBOX_USB_WITH_SYSFS 1395 1430 # ifdef VBOX_USB_WITH_INOTIFY 1396 /** Helper for readFilePathsFromDir(). Adds a path to the vector if it is not1397 * 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 directory1416 * @a pDir to the vector @a pvpchDevs using either the full path or the1417 * 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 else1435 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 a1445 * 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 up1450 * by the caller even on failure.1451 * @param withRealPath whether to canonicalise the filename with realpath1452 */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 function1475 * object on each.1476 *1477 * @returns zero on success or (positive) posix error value.1478 * @param pcszPath the path of the directory1479 * @param pvpchDevs vector of char strings containing the directory entry1480 * names1481 * @param pHandler Handler object which will be invoked on each file1482 */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't1499 * start with a dot.1500 * @returns iprt status code1501 * @param pcszPath Directory to walk. May not be '/'-terminated.1502 * @param pHandler Handler object which will be invoked on each1503 * directoryentry1504 * @param withRealPath Whether to apply realpath() to each entry before1505 * invoking the handler1506 */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 1525 1431 1526 1432 #define USBDEVICE_MAJOR 189 … … 1547 1453 1548 1454 /** 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 */ 1458 static int addIfDevice(const char *pcszNode, 1459 VECTOR_OBJ(USBDeviceInfo) *pvecDevInfo) 1460 { 1564 1461 const char *pcszFile = strrchr(pcszNode, '/'); 1565 1462 if (strchr(pcszFile, ':')) 1566 return true;1463 return VINF_SUCCESS; 1567 1464 dev_t devnum = RTLinuxSysFsReadDevNumFile("%s/dev", pcszNode); 1568 1465 /* Sanity test of our static helpers */ … … 1570 1467 Assert(usbDeviceFromDevNum(makedev(USBDEVICE_MAJOR, 517)) == 6); 1571 1468 if (!devnum) 1572 return true;1469 return VINF_SUCCESS; 1573 1470 char szDevPath[RTPATH_MAX]; 1574 1471 ssize_t cchDevPath; … … 1579 1476 usbDeviceFromDevNum(devnum)); 1580 1477 if (cchDevPath < 0) 1581 return true;1478 return VINF_SUCCESS; 1582 1479 1583 1480 USBDeviceInfo info; 1584 1481 if (USBDevInfoInit(&info, szDevPath, pcszNode)) 1585 if (RT_SUCCESS(VEC_PUSH_BACK_OBJ(p Self->mpvecDevInfo, USBDeviceInfo,1482 if (RT_SUCCESS(VEC_PUSH_BACK_OBJ(pvecDevInfo, USBDeviceInfo, 1586 1483 &info))) 1587 return true;1484 return VINF_SUCCESS; 1588 1485 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 } 1611 1488 1612 1489 /** The logic for testing whether a sysfs address corresponds to an … … 1639 1516 } 1640 1517 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. */ 1520 class testIsAnInterfaceOf 1521 { 1522 public: 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 }; 1533 static 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 */ 1540 static int addIfInterfaceOf(const char *pcszNode, USBDeviceInfo *pInfo) 1541 { 1542 if (!muiIsAnInterfaceOf(pcszNode, pInfo->mSysfsPath)) 1543 return VINF_SUCCESS; 1648 1544 char *pszDup = (char *)RTStrDup(pcszNode); 1649 1545 if (pszDup) 1650 if (RT_SUCCESS(VEC_PUSH_BACK_PTR(&p Self->mInfo->mvecpszInterfaces,1546 if (RT_SUCCESS(VEC_PUSH_BACK_PTR(&pInfo->mvecpszInterfaces, 1651 1547 char *, pszDup))) 1652 return true;1548 return VINF_SUCCESS; 1653 1549 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; 1671 1551 } 1672 1552 1673 1553 /** 1674 * Helper function to query the sysfs subsystem for information about USB1675 * devices attached to the system.1676 * @returns iprt status code1677 * @param pList where to add information about the drives detected1678 * @param pfSuccess Did we find anything?1679 * 1680 * @returns IPRT status code1681 */ 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 */ 1559 static int doUpdateUSBDevices(VECTOR_OBJ(USBDeviceInfo) *pvecDevInfo, 1560 VECTOR_PTR(char *) *pvecpchDevs) 1561 { 1562 char **ppszEntry; 1563 USBDeviceInfo *pInfo; 1564 int rc; 1565 1686 1566 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; 1711 1580 } 1712 1581 # endif /* VBOX_USB_WITH_INOTIFY */ 1713 1582 #endif /* VBOX_USB_WITH_SYSFS */ 1583 1584 int 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.