Changeset 60153 in vbox for trunk/src/VBox
- Timestamp:
- Mar 23, 2016 11:19:02 AM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/src-server/linux/USBGetDevices.cpp
r60150 r60153 20 20 * Header Files * 21 21 *********************************************************************************************************************************/ 22 22 #define VBOX_USB_WITH_USBFS 23 23 #include "USBGetDevices.h" 24 24 … … 116 116 } 117 117 return offSrc - 1; 118 }119 120 121 /**122 * "reads" the number suffix.123 *124 * It's more like validating it and skipping the necessary number of chars.125 */126 static int usbfsReadSkipSuffix(char **ppszNext)127 {128 char *pszNext = *ppszNext;129 if (!RT_C_IS_SPACE(*pszNext) && *pszNext)130 {131 /* skip unit */132 if (pszNext[0] == 'm' && pszNext[1] == 's')133 pszNext += 2;134 else if (pszNext[0] == 'm' && pszNext[1] == 'A')135 pszNext += 2;136 137 /* skip parenthesis */138 if (*pszNext == '(')139 {140 pszNext = strchr(pszNext, ')');141 if (!pszNext++)142 {143 AssertMsgFailed(("*ppszNext=%s\n", *ppszNext));144 return VERR_PARSE_ERROR;145 }146 }147 148 /* blank or end of the line. */149 if (!RT_C_IS_SPACE(*pszNext) && *pszNext)150 {151 AssertMsgFailed(("pszNext=%s\n", pszNext));152 return VERR_PARSE_ERROR;153 }154 155 /* it's ok. */156 *ppszNext = pszNext;157 }158 159 return VINF_SUCCESS;160 }161 162 163 /**164 * Reads a USB number returning the number and the position of the next character to parse.165 */166 static int usbfsReadNum(const char *pszValue, unsigned uBase, uint32_t u32Mask, void *pvNum, char **ppszNext)167 {168 /*169 * Initialize return value to zero and strip leading spaces.170 */171 switch (u32Mask)172 {173 case 0xff: *(uint8_t *)pvNum = 0; break;174 case 0xffff: *(uint16_t *)pvNum = 0; break;175 case 0xffffffff: *(uint32_t *)pvNum = 0; break;176 }177 pszValue = RTStrStripL(pszValue);178 if (*pszValue)179 {180 /*181 * Try convert the number.182 */183 char *pszNext;184 uint32_t u32 = 0;185 RTStrToUInt32Ex(pszValue, &pszNext, uBase, &u32);186 if (pszNext == pszValue)187 {188 AssertMsgFailed(("pszValue=%d\n", pszValue));189 return VERR_NO_DATA;190 }191 192 /*193 * Check the range.194 */195 if (u32 & ~u32Mask)196 {197 AssertMsgFailed(("pszValue=%d u32=%#x lMask=%#x\n", pszValue, u32, u32Mask));198 return VERR_OUT_OF_RANGE;199 }200 201 int rc = usbfsReadSkipSuffix(&pszNext);202 if (RT_FAILURE(rc))203 return rc;204 205 *ppszNext = pszNext;206 207 /*208 * Set the value.209 */210 switch (u32Mask)211 {212 case 0xff: *(uint8_t *)pvNum = (uint8_t)u32; break;213 case 0xffff: *(uint16_t *)pvNum = (uint16_t)u32; break;214 case 0xffffffff: *(uint32_t *)pvNum = (uint32_t)u32; break;215 }216 }217 return VINF_SUCCESS;218 }219 220 221 static int usbfsRead8(const char *pszValue, unsigned uBase, uint8_t *pu8, char **ppszNext)222 {223 return usbfsReadNum(pszValue, uBase, 0xff, pu8, ppszNext);224 }225 226 227 static int usbfsRead16(const char *pszValue, unsigned uBase, uint16_t *pu16, char **ppszNext)228 {229 return usbfsReadNum(pszValue, uBase, 0xffff, pu16, ppszNext);230 }231 232 233 /**234 * Reads a USB BCD number returning the number and the position of the next character to parse.235 * The returned number contains the integer part in the high byte and the decimal part in the low byte.236 */237 static int usbfsReadBCD(const char *pszValue, unsigned uBase, uint16_t *pu16, char **ppszNext)238 {239 /*240 * Initialize return value to zero and strip leading spaces.241 */242 *pu16 = 0;243 pszValue = RTStrStripL(pszValue);244 if (*pszValue)245 {246 /*247 * Try convert the number.248 */249 /* integer part */250 char *pszNext;251 uint32_t u32Int = 0;252 RTStrToUInt32Ex(pszValue, &pszNext, uBase, &u32Int);253 if (pszNext == pszValue)254 {255 AssertMsgFailed(("pszValue=%s\n", pszValue));256 return VERR_NO_DATA;257 }258 if (u32Int & ~0xff)259 {260 AssertMsgFailed(("pszValue=%s u32Int=%#x (int)\n", pszValue, u32Int));261 return VERR_OUT_OF_RANGE;262 }263 264 /* skip dot and read decimal part */265 if (*pszNext != '.')266 {267 AssertMsgFailed(("pszValue=%s pszNext=%s (int)\n", pszValue, pszNext));268 return VERR_PARSE_ERROR;269 }270 char *pszValue2 = RTStrStripL(pszNext + 1);271 uint32_t u32Dec = 0;272 RTStrToUInt32Ex(pszValue2, &pszNext, uBase, &u32Dec);273 if (pszNext == pszValue)274 {275 AssertMsgFailed(("pszValue=%s\n", pszValue));276 return VERR_NO_DATA;277 }278 if (u32Dec & ~0xff)279 {280 AssertMsgFailed(("pszValue=%s u32Dec=%#x\n", pszValue, u32Dec));281 return VERR_OUT_OF_RANGE;282 }283 284 /*285 * Validate and skip stuff following the number.286 */287 int rc = usbfsReadSkipSuffix(&pszNext);288 if (RT_FAILURE(rc))289 return rc;290 *ppszNext = pszNext;291 292 /*293 * Set the value.294 */295 *pu16 = (uint16_t)u32Int << 8 | (uint16_t)u32Dec;296 }297 return VINF_SUCCESS;298 }299 300 301 /**302 * Reads a string, i.e. allocates memory and copies it.303 *304 * We assume that a string is Utf8 and if that's not the case305 * (pre-2.6.32-kernels used Latin-1, but so few devices return non-ASCII that306 * this usually goes unnoticed) then we mercilessly force it to be so.307 */308 static int usbfsReadStr(const char *pszValue, const char **ppsz)309 {310 char *psz;311 312 if (*ppsz)313 RTStrFree((char *)*ppsz);314 psz = RTStrDup(pszValue);315 if (psz)316 {317 usbPurgeEncoding(psz);318 *ppsz = psz;319 return VINF_SUCCESS;320 }321 return VERR_NO_MEMORY;322 }323 324 325 /**326 * Skips the current property.327 */328 static char *usbfsReadSkip(char *pszValue)329 {330 char *psz = strchr(pszValue, '=');331 if (psz)332 psz = strchr(psz + 1, '=');333 if (!psz)334 return strchr(pszValue, '\0');335 while (psz > pszValue && !RT_C_IS_SPACE(psz[-1]))336 psz--;337 Assert(psz > pszValue);338 return psz;339 }340 341 342 /**343 * Determine the USB speed.344 */345 static int usbfsReadSpeed(const char *pszValue, USBDEVICESPEED *pSpd, char **ppszNext)346 {347 pszValue = RTStrStripL(pszValue);348 /* verified with Linux 2.4.0 ... Linux 2.6.25 */349 if (!strncmp(pszValue, RT_STR_TUPLE("1.5")))350 *pSpd = USBDEVICESPEED_LOW;351 else if (!strncmp(pszValue, RT_STR_TUPLE("12 ")))352 *pSpd = USBDEVICESPEED_FULL;353 else if (!strncmp(pszValue, RT_STR_TUPLE("480")))354 *pSpd = USBDEVICESPEED_HIGH;355 else if (!strncmp(pszValue, RT_STR_TUPLE("5000")))356 *pSpd = USBDEVICESPEED_SUPER;357 else358 *pSpd = USBDEVICESPEED_UNKNOWN;359 while (pszValue[0] != '\0' && !RT_C_IS_SPACE(pszValue[0]))360 pszValue++;361 *ppszNext = (char *)pszValue;362 return VINF_SUCCESS;363 }364 365 366 /**367 * Compare a prefix and returns pointer to the char following it if it matches.368 */369 static char *usbfsPrefix(char *psz, const char *pszPref, size_t cchPref)370 {371 if (strncmp(psz, pszPref, cchPref))372 return NULL;373 return psz + cchPref;374 118 } 375 119 … … 453 197 454 198 return enmState; 199 } 200 201 202 /** 203 * Dumps a USBDEVICE structure to the log using LogLevel 3. 204 * @param pDev The structure to log. 205 * @todo This is really common code. 206 */ 207 static void usbLogDevice(PUSBDEVICE pDev) 208 { 209 NOREF(pDev); 210 if (LogIs3Enabled()) 211 { 212 Log3(("USB device:\n")); 213 Log3(("Product: %s (%x)\n", pDev->pszProduct, pDev->idProduct)); 214 Log3(("Manufacturer: %s (Vendor ID %x)\n", pDev->pszManufacturer, pDev->idVendor)); 215 Log3(("Serial number: %s (%llx)\n", pDev->pszSerialNumber, pDev->u64SerialHash)); 216 Log3(("Device revision: %d\n", pDev->bcdDevice)); 217 Log3(("Device class: %x\n", pDev->bDeviceClass)); 218 Log3(("Device subclass: %x\n", pDev->bDeviceSubClass)); 219 Log3(("Device protocol: %x\n", pDev->bDeviceProtocol)); 220 Log3(("USB version number: %d\n", pDev->bcdUSB)); 221 Log3(("Device speed: %s\n", 222 pDev->enmSpeed == USBDEVICESPEED_UNKNOWN ? "unknown" 223 : pDev->enmSpeed == USBDEVICESPEED_LOW ? "1.5 MBit/s" 224 : pDev->enmSpeed == USBDEVICESPEED_FULL ? "12 MBit/s" 225 : pDev->enmSpeed == USBDEVICESPEED_HIGH ? "480 MBit/s" 226 : pDev->enmSpeed == USBDEVICESPEED_SUPER ? "5.0 GBit/s" 227 : pDev->enmSpeed == USBDEVICESPEED_VARIABLE ? "variable" 228 : "invalid")); 229 Log3(("Number of configurations: %d\n", pDev->bNumConfigurations)); 230 Log3(("Bus number: %d\n", pDev->bBus)); 231 Log3(("Port number: %d\n", pDev->bPort)); 232 Log3(("Device number: %d\n", pDev->bDevNum)); 233 Log3(("Device state: %s\n", 234 pDev->enmState == USBDEVICESTATE_UNSUPPORTED ? "unsupported" 235 : pDev->enmState == USBDEVICESTATE_USED_BY_HOST ? "in use by host" 236 : pDev->enmState == USBDEVICESTATE_USED_BY_HOST_CAPTURABLE ? "in use by host, possibly capturable" 237 : pDev->enmState == USBDEVICESTATE_UNUSED ? "not in use" 238 : pDev->enmState == USBDEVICESTATE_HELD_BY_PROXY ? "held by proxy" 239 : pDev->enmState == USBDEVICESTATE_USED_BY_GUEST ? "used by guest" 240 : "invalid")); 241 Log3(("OS device address: %s\n", pDev->pszAddress)); 242 } 243 } 244 245 246 #ifdef VBOX_USB_WITH_USBFS 247 248 /** 249 * "reads" the number suffix. 250 * 251 * It's more like validating it and skipping the necessary number of chars. 252 */ 253 static int usbfsReadSkipSuffix(char **ppszNext) 254 { 255 char *pszNext = *ppszNext; 256 if (!RT_C_IS_SPACE(*pszNext) && *pszNext) 257 { 258 /* skip unit */ 259 if (pszNext[0] == 'm' && pszNext[1] == 's') 260 pszNext += 2; 261 else if (pszNext[0] == 'm' && pszNext[1] == 'A') 262 pszNext += 2; 263 264 /* skip parenthesis */ 265 if (*pszNext == '(') 266 { 267 pszNext = strchr(pszNext, ')'); 268 if (!pszNext++) 269 { 270 AssertMsgFailed(("*ppszNext=%s\n", *ppszNext)); 271 return VERR_PARSE_ERROR; 272 } 273 } 274 275 /* blank or end of the line. */ 276 if (!RT_C_IS_SPACE(*pszNext) && *pszNext) 277 { 278 AssertMsgFailed(("pszNext=%s\n", pszNext)); 279 return VERR_PARSE_ERROR; 280 } 281 282 /* it's ok. */ 283 *ppszNext = pszNext; 284 } 285 286 return VINF_SUCCESS; 287 } 288 289 290 /** 291 * Reads a USB number returning the number and the position of the next character to parse. 292 */ 293 static int usbfsReadNum(const char *pszValue, unsigned uBase, uint32_t u32Mask, void *pvNum, char **ppszNext) 294 { 295 /* 296 * Initialize return value to zero and strip leading spaces. 297 */ 298 switch (u32Mask) 299 { 300 case 0xff: *(uint8_t *)pvNum = 0; break; 301 case 0xffff: *(uint16_t *)pvNum = 0; break; 302 case 0xffffffff: *(uint32_t *)pvNum = 0; break; 303 } 304 pszValue = RTStrStripL(pszValue); 305 if (*pszValue) 306 { 307 /* 308 * Try convert the number. 309 */ 310 char *pszNext; 311 uint32_t u32 = 0; 312 RTStrToUInt32Ex(pszValue, &pszNext, uBase, &u32); 313 if (pszNext == pszValue) 314 { 315 AssertMsgFailed(("pszValue=%d\n", pszValue)); 316 return VERR_NO_DATA; 317 } 318 319 /* 320 * Check the range. 321 */ 322 if (u32 & ~u32Mask) 323 { 324 AssertMsgFailed(("pszValue=%d u32=%#x lMask=%#x\n", pszValue, u32, u32Mask)); 325 return VERR_OUT_OF_RANGE; 326 } 327 328 int rc = usbfsReadSkipSuffix(&pszNext); 329 if (RT_FAILURE(rc)) 330 return rc; 331 332 *ppszNext = pszNext; 333 334 /* 335 * Set the value. 336 */ 337 switch (u32Mask) 338 { 339 case 0xff: *(uint8_t *)pvNum = (uint8_t)u32; break; 340 case 0xffff: *(uint16_t *)pvNum = (uint16_t)u32; break; 341 case 0xffffffff: *(uint32_t *)pvNum = (uint32_t)u32; break; 342 } 343 } 344 return VINF_SUCCESS; 345 } 346 347 348 static int usbfsRead8(const char *pszValue, unsigned uBase, uint8_t *pu8, char **ppszNext) 349 { 350 return usbfsReadNum(pszValue, uBase, 0xff, pu8, ppszNext); 351 } 352 353 354 static int usbfsRead16(const char *pszValue, unsigned uBase, uint16_t *pu16, char **ppszNext) 355 { 356 return usbfsReadNum(pszValue, uBase, 0xffff, pu16, ppszNext); 357 } 358 359 360 /** 361 * Reads a USB BCD number returning the number and the position of the next character to parse. 362 * The returned number contains the integer part in the high byte and the decimal part in the low byte. 363 */ 364 static int usbfsReadBCD(const char *pszValue, unsigned uBase, uint16_t *pu16, char **ppszNext) 365 { 366 /* 367 * Initialize return value to zero and strip leading spaces. 368 */ 369 *pu16 = 0; 370 pszValue = RTStrStripL(pszValue); 371 if (*pszValue) 372 { 373 /* 374 * Try convert the number. 375 */ 376 /* integer part */ 377 char *pszNext; 378 uint32_t u32Int = 0; 379 RTStrToUInt32Ex(pszValue, &pszNext, uBase, &u32Int); 380 if (pszNext == pszValue) 381 { 382 AssertMsgFailed(("pszValue=%s\n", pszValue)); 383 return VERR_NO_DATA; 384 } 385 if (u32Int & ~0xff) 386 { 387 AssertMsgFailed(("pszValue=%s u32Int=%#x (int)\n", pszValue, u32Int)); 388 return VERR_OUT_OF_RANGE; 389 } 390 391 /* skip dot and read decimal part */ 392 if (*pszNext != '.') 393 { 394 AssertMsgFailed(("pszValue=%s pszNext=%s (int)\n", pszValue, pszNext)); 395 return VERR_PARSE_ERROR; 396 } 397 char *pszValue2 = RTStrStripL(pszNext + 1); 398 uint32_t u32Dec = 0; 399 RTStrToUInt32Ex(pszValue2, &pszNext, uBase, &u32Dec); 400 if (pszNext == pszValue) 401 { 402 AssertMsgFailed(("pszValue=%s\n", pszValue)); 403 return VERR_NO_DATA; 404 } 405 if (u32Dec & ~0xff) 406 { 407 AssertMsgFailed(("pszValue=%s u32Dec=%#x\n", pszValue, u32Dec)); 408 return VERR_OUT_OF_RANGE; 409 } 410 411 /* 412 * Validate and skip stuff following the number. 413 */ 414 int rc = usbfsReadSkipSuffix(&pszNext); 415 if (RT_FAILURE(rc)) 416 return rc; 417 *ppszNext = pszNext; 418 419 /* 420 * Set the value. 421 */ 422 *pu16 = (uint16_t)u32Int << 8 | (uint16_t)u32Dec; 423 } 424 return VINF_SUCCESS; 425 } 426 427 428 /** 429 * Reads a string, i.e. allocates memory and copies it. 430 * 431 * We assume that a string is Utf8 and if that's not the case 432 * (pre-2.6.32-kernels used Latin-1, but so few devices return non-ASCII that 433 * this usually goes unnoticed) then we mercilessly force it to be so. 434 */ 435 static int usbfsReadStr(const char *pszValue, const char **ppsz) 436 { 437 char *psz; 438 439 if (*ppsz) 440 RTStrFree((char *)*ppsz); 441 psz = RTStrDup(pszValue); 442 if (psz) 443 { 444 usbPurgeEncoding(psz); 445 *ppsz = psz; 446 return VINF_SUCCESS; 447 } 448 return VERR_NO_MEMORY; 449 } 450 451 452 /** 453 * Skips the current property. 454 */ 455 static char *usbfsReadSkip(char *pszValue) 456 { 457 char *psz = strchr(pszValue, '='); 458 if (psz) 459 psz = strchr(psz + 1, '='); 460 if (!psz) 461 return strchr(pszValue, '\0'); 462 while (psz > pszValue && !RT_C_IS_SPACE(psz[-1])) 463 psz--; 464 Assert(psz > pszValue); 465 return psz; 466 } 467 468 469 /** 470 * Determine the USB speed. 471 */ 472 static int usbfsReadSpeed(const char *pszValue, USBDEVICESPEED *pSpd, char **ppszNext) 473 { 474 pszValue = RTStrStripL(pszValue); 475 /* verified with Linux 2.4.0 ... Linux 2.6.25 */ 476 if (!strncmp(pszValue, RT_STR_TUPLE("1.5"))) 477 *pSpd = USBDEVICESPEED_LOW; 478 else if (!strncmp(pszValue, RT_STR_TUPLE("12 "))) 479 *pSpd = USBDEVICESPEED_FULL; 480 else if (!strncmp(pszValue, RT_STR_TUPLE("480"))) 481 *pSpd = USBDEVICESPEED_HIGH; 482 else if (!strncmp(pszValue, RT_STR_TUPLE("5000"))) 483 *pSpd = USBDEVICESPEED_SUPER; 484 else 485 *pSpd = USBDEVICESPEED_UNKNOWN; 486 while (pszValue[0] != '\0' && !RT_C_IS_SPACE(pszValue[0])) 487 pszValue++; 488 *ppszNext = (char *)pszValue; 489 return VINF_SUCCESS; 490 } 491 492 493 /** 494 * Compare a prefix and returns pointer to the char following it if it matches. 495 */ 496 static char *usbfsPrefix(char *psz, const char *pszPref, size_t cchPref) 497 { 498 if (strncmp(psz, pszPref, cchPref)) 499 return NULL; 500 return psz + cchPref; 455 501 } 456 502 … … 795 841 } 796 842 843 #endif /* VBOX_USB_WITH_USBFS */ 797 844 #ifdef VBOX_USB_WITH_SYSFS 798 845 … … 819 866 } 820 867 821 # define USBDEVICE_MAJOR 189868 # define USBDEVICE_MAJOR 189 822 869 823 870 /** … … 943 990 944 991 945 # ifdef DEBUG946 # ifdef __cplusplus992 # ifdef DEBUG 993 # ifdef __cplusplus 947 994 /** Unit test the logic in muiIsAnInterfaceOf in debug builds. */ 948 995 class testIsAnInterfaceOf … … 960 1007 }; 961 1008 static testIsAnInterfaceOf testIsAnInterfaceOfInst; 962 # endif /* __cplusplus */963 # endif /* DEBUG */1009 # endif /* __cplusplus */ 1010 # endif /* DEBUG */ 964 1011 965 1012 … … 1182 1229 1183 1230 /** 1184 * Dumps a USBDEVICE structure to the log using LogLevel 3.1185 * @param pDev The structure to log.1186 * @todo This is really common code.1187 */1188 static void usbLogDevice(PUSBDEVICE pDev)1189 {1190 NOREF(pDev);1191 if (LogIs3Enabled())1192 {1193 Log3(("USB device:\n"));1194 Log3(("Product: %s (%x)\n", pDev->pszProduct, pDev->idProduct));1195 Log3(("Manufacturer: %s (Vendor ID %x)\n", pDev->pszManufacturer, pDev->idVendor));1196 Log3(("Serial number: %s (%llx)\n", pDev->pszSerialNumber, pDev->u64SerialHash));1197 Log3(("Device revision: %d\n", pDev->bcdDevice));1198 Log3(("Device class: %x\n", pDev->bDeviceClass));1199 Log3(("Device subclass: %x\n", pDev->bDeviceSubClass));1200 Log3(("Device protocol: %x\n", pDev->bDeviceProtocol));1201 Log3(("USB version number: %d\n", pDev->bcdUSB));1202 Log3(("Device speed: %s\n",1203 pDev->enmSpeed == USBDEVICESPEED_UNKNOWN ? "unknown"1204 : pDev->enmSpeed == USBDEVICESPEED_LOW ? "1.5 MBit/s"1205 : pDev->enmSpeed == USBDEVICESPEED_FULL ? "12 MBit/s"1206 : pDev->enmSpeed == USBDEVICESPEED_HIGH ? "480 MBit/s"1207 : pDev->enmSpeed == USBDEVICESPEED_SUPER ? "5.0 GBit/s"1208 : pDev->enmSpeed == USBDEVICESPEED_VARIABLE ? "variable"1209 : "invalid"));1210 Log3(("Number of configurations: %d\n", pDev->bNumConfigurations));1211 Log3(("Bus number: %d\n", pDev->bBus));1212 Log3(("Port number: %d\n", pDev->bPort));1213 Log3(("Device number: %d\n", pDev->bDevNum));1214 Log3(("Device state: %s\n",1215 pDev->enmState == USBDEVICESTATE_UNSUPPORTED ? "unsupported"1216 : pDev->enmState == USBDEVICESTATE_USED_BY_HOST ? "in use by host"1217 : pDev->enmState == USBDEVICESTATE_USED_BY_HOST_CAPTURABLE ? "in use by host, possibly capturable"1218 : pDev->enmState == USBDEVICESTATE_UNUSED ? "not in use"1219 : pDev->enmState == USBDEVICESTATE_HELD_BY_PROXY ? "held by proxy"1220 : pDev->enmState == USBDEVICESTATE_USED_BY_GUEST ? "used by guest"1221 : "invalid"));1222 Log3(("OS device address: %s\n", pDev->pszAddress));1223 }1224 }1225 1226 1227 /**1228 1231 * Converts a sysfs BCD value into a uint16_t. 1229 1232 * … … 1267 1270 } 1268 1271 1269 #endif /* VBOX_USB_WITH_SYSFS */1270 1272 1271 1273 static void usbsysfsFillInDevice(USBDEVICE *pDev, USBDeviceInfo *pInfo) … … 1384 1386 static PUSBDEVICE usbsysfsGetDevices(const char *pcszDevicesRoot, bool testfs) 1385 1387 { 1386 #ifdef VBOX_USB_WITH_SYSFS1387 1388 /* Add each of the devices found to the chain. */ 1388 1389 PUSBDEVICE pFirst = NULL; … … 1427 1428 VEC_CLEANUP_OBJ(&vecDevInfo); 1428 1429 return pFirst; 1429 #else /* !VBOX_USB_WITH_SYSFS */ 1430 return NULL; 1431 #endif /* !VBOX_USB_WITH_SYSFS */ 1432 } 1433 1430 } 1431 1432 #endif /* VBOX_USB_WITH_SYSFS */ 1434 1433 #ifdef UNIT_TEST 1435 1434 … … 1553 1552 1554 1553 1555 # ifdef UNIT_TEST 1556 /** The path we pretend the usbfs root is located at, or NULL. */ 1557 const char *s_pcszTestUsbfsRoot; 1558 /** Should usbfs be accessible to the current user? */ 1559 bool s_fTestUsbfsAccessible; 1560 /** The path we pretend the device node tree root is located at, or NULL. */ 1561 const char *s_pcszTestDevicesRoot; 1562 /** Should the device node tree be accessible to the current user? */ 1563 bool s_fTestDevicesAccessible; 1564 /** The result of the usbfs/inotify-specific init */ 1565 int s_rcTestMethodInitResult; 1566 /** The value of the VBOX_USB environment variable. */ 1567 const char *s_pcszTestEnvUsb; 1568 /** The value of the VBOX_USB_ROOT environment variable. */ 1569 const char *s_pcszTestEnvUsbRoot; 1570 # endif 1554 /** The path we pretend the usbfs root is located at, or NULL. */ 1555 const char *s_pcszTestUsbfsRoot; 1556 /** Should usbfs be accessible to the current user? */ 1557 bool s_fTestUsbfsAccessible; 1558 /** The path we pretend the device node tree root is located at, or NULL. */ 1559 const char *s_pcszTestDevicesRoot; 1560 /** Should the device node tree be accessible to the current user? */ 1561 bool s_fTestDevicesAccessible; 1562 /** The result of the usbfs/inotify-specific init */ 1563 int s_rcTestMethodInitResult; 1564 /** The value of the VBOX_USB environment variable. */ 1565 const char *s_pcszTestEnvUsb; 1566 /** The value of the VBOX_USB_ROOT environment variable. */ 1567 const char *s_pcszTestEnvUsbRoot; 1571 1568 1572 1569 … … 1602 1599 # define USBProxyLinuxCheckDeviceRoot(pcszPath, fUseNodes) \ 1603 1600 ( ((fUseNodes) && s_fTestDevicesAccessible \ 1604 1601 && !RTStrCmp(pcszPath, s_pcszTestDevicesRoot)) \ 1605 1602 || (!(fUseNodes) && s_fTestUsbfsAccessible \ 1606 1603 && !RTStrCmp(pcszPath, s_pcszTestUsbfsRoot))) 1607 1604 # define RTDirExists(pcszDir) \ 1608 1605 ( (pcszDir) \ … … 1663 1660 else 1664 1661 { 1665 LogRel(("Invalid VBOX_USB environment variable setting \"%s\"\n", 1666 pcszUsbFromEnv)); 1662 LogRel(("Invalid VBOX_USB environment variable setting \"%s\"\n", pcszUsbFromEnv)); 1667 1663 fValidVBoxUSB = false; 1668 1664 pcszUsbFromEnv = NULL; … … 1709 1705 1710 1706 /** 1711 * Check whether a USB device tree root is usable 1707 * Check whether a USB device tree root is usable. 1712 1708 * 1713 1709 * @param pcszRoot the path to the root of the device tree … … 1720 1716 if (!fIsDeviceNodes) /* usbfs */ 1721 1717 { 1722 PUSBDEVICE pDevices; 1723 1718 #ifdef VBOX_USB_WITH_USBFS 1724 1719 if (!access(pcszRoot, R_OK | X_OK)) 1725 1720 { 1726 1721 fOK = true; 1727 pDevices = usbfsGetDevices(pcszRoot, true);1722 PUSBDEVICE pDevices = usbfsGetDevices(pcszRoot, true); 1728 1723 if (pDevices) 1729 1724 { 1730 1725 PUSBDEVICE pDevice; 1731 1732 1726 for (pDevice = pDevices; pDevice && fOK; pDevice = pDevice->pNext) 1733 1727 if (access(pDevice->pszAddress, R_OK | W_OK)) … … 1736 1730 } 1737 1731 } 1738 } 1732 #endif 1733 } 1734 #ifdef VBOX_USB_WITH_SYSFS 1739 1735 /* device nodes */ 1740 1736 else if (usbsysfsInotifyAvailable() && !access(pcszRoot, R_OK | X_OK)) 1741 1737 fOK = true; 1738 #endif 1742 1739 return fOK; 1743 1740 } … … 1759 1756 { 1760 1757 if (!fUseSysfs) 1758 { 1759 #ifdef VBOX_USB_WITH_USBFS 1761 1760 return usbfsGetDevices(pcszDevicesRoot, false); 1761 #else 1762 return NULL; 1763 #endif 1764 } 1765 1766 #ifdef VBOX_USB_WITH_SYSFS 1762 1767 return usbsysfsGetDevices(pcszDevicesRoot, false); 1763 } 1768 #else 1769 return NULL; 1770 #endif 1771 } 1772
Note:
See TracChangeset
for help on using the changeset viewer.