- Timestamp:
- Jul 17, 2007 4:22:06 AM (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/darwin/iokit.cpp
r3662 r3665 548 548 549 549 /** 550 * Decends recursivly into a IORegistry tree locating the first object of a given class. 551 * 552 * The search is performed depth first. 553 * 554 * @returns Object reference if found, NULL if not. 555 * @param Object The current tree root. 556 * @param pszClass The name of the class we're looking for. 557 * @param pszNameBuf A scratch buffer for query the class name in to avoid 558 * wasting 128 bytes on an io_name_t object for every recursion. 559 */ 560 static io_object_t darwinFindObjectByClass(io_object_t Object, const char *pszClass, io_name_t pszNameBuf) 561 { 562 io_iterator_t Children; 563 kern_return_t krc = IORegistryEntryGetChildIterator(Object, kIOServicePlane, &Children); 564 if (krc != KERN_SUCCESS) 565 return NULL; 566 io_object_t Child; 567 while ((Child = IOIteratorNext(Children))) 568 { 569 krc = IOObjectGetClass(Child, pszNameBuf); 570 if ( krc == KERN_SUCCESS 571 && !strcmp(pszNameBuf, pszClass)) 572 break; 573 574 io_object_t GrandChild = darwinFindObjectByClass(Child, pszClass, pszNameBuf); 575 IOObjectRelease(Child); 576 if (GrandChild) 577 { 578 Child = GrandChild; 579 break; 580 } 581 } 582 IOObjectRelease(Children); 583 return Child; 584 } 585 586 587 /** 588 * Decends recursivly into IOUSBMassStorageClass tree to check whether 589 * the MSD is mounted or not. 590 * 591 * The current heuristic is to look for the IOMedia class. 592 * 593 * @returns true if mounted, false if not. 594 * @param MSDObj The IOUSBMassStorageClass object. 595 * @param pszNameBuf A scratch buffer for query the class name in to avoid 596 * wasting 128 bytes on an io_name_t object for every recursion. 597 */ 598 static bool darwinIsMassStorageInterfaceInUse(io_object_t MSDObj, io_name_t pszNameBuf) 599 { 600 io_object_t MediaObj = darwinFindObjectByClass(MSDObj, "IOMedia", pszNameBuf); 601 if (MediaObj) 602 { 603 /* more checks? */ 604 IOObjectRelease(MediaObj); 605 return true; 606 } 607 return false; 608 } 609 610 611 /** 550 612 * Worker function for DarwinGetUSBDevices() that tries to figure out 551 613 * what state the device is in. … … 560 622 static void darwinDeterminUSBDeviceState(PUSBDEVICE pCur, io_object_t USBDevice, CFMutableDictionaryRef PropsRef) 561 623 { 562 ///@todo 624 /* 625 * Iterate the interfaces (among the children of the IOUSBDevice object). 626 */ 627 io_iterator_t Interfaces; 628 kern_return_t krc = IORegistryEntryGetChildIterator(USBDevice, kIOServicePlane, &Interfaces); 629 if (krc != KERN_SUCCESS) 630 return; 631 632 bool fUserClientOnly = true; 633 bool fConfigured = false; 634 bool fInUse = false; 635 bool fSeizable = true; 636 io_object_t Interface; 637 while ((Interface = IOIteratorNext(Interfaces))) 638 { 639 io_name_t szName; 640 krc = IOObjectGetClass(Interface, szName); 641 if ( krc == KERN_SUCCESS 642 && !strcmp(szName, "IOUSBInterface")) 643 { 644 fConfigured = true; 645 646 /* 647 * Iterate the interface children looking for stuff other than 648 * IOUSBUserClientInit objects. 649 */ 650 io_iterator_t Children1; 651 krc = IORegistryEntryGetChildIterator(Interface, kIOServicePlane, &Children1); 652 if (krc == KERN_SUCCESS) 653 { 654 io_object_t Child1; 655 while ((Child1 = IOIteratorNext(Children1))) 656 { 657 krc = IOObjectGetClass(Child1, szName); 658 if ( krc == KERN_SUCCESS 659 && strcmp(szName, "IOUSBUserClientInit")) 660 { 661 fUserClientOnly = false; 662 663 if (!strcmp(szName, "IOUSBMassStorageClass")) 664 { 665 /* Only permit capturing MSDs that aren't mounted, at least 666 until the GUI starts poping up warnings about data loss 667 and such when capturing a busy device. */ 668 fSeizable = false; 669 fInUse |= darwinIsMassStorageInterfaceInUse(Child1, szName); 670 } 671 else if (!strcmp(szName, "IOUSBHIDDriver") 672 || !strcmp(szName, "AppleHIDMouse") 673 /** @todo more? */) 674 { 675 /* For now, just assume that all HID devices are inaccessible 676 because of the greedy HID service. */ 677 fSeizable = false; 678 fInUse = true; 679 } 680 else 681 fInUse = true; 682 } 683 IOObjectRelease(Child1); 684 } 685 IOObjectRelease(Children1); 686 } 687 } 688 IOObjectRelease(Interface); 689 } 690 IOObjectRelease(Interfaces); 691 692 /* 693 * Calc the status. 694 */ 695 if (fUserClientOnly) 696 /** @todo how to detect other user client?!? */ 697 pCur->enmState = !fConfigured 698 ? USBDEVICESTATE_UNUSED 699 : USBDEVICESTATE_USED_BY_HOST_CAPTURABLE; 700 701 else if (!fInUse) 702 pCur->enmState = USBDEVICESTATE_UNUSED; 703 else 704 pCur->enmState = fSeizable 705 ? USBDEVICESTATE_USED_BY_HOST_CAPTURABLE 706 : USBDEVICESTATE_USED_BY_HOST; 563 707 } 564 708
Note:
See TracChangeset
for help on using the changeset viewer.