Changeset 3764 in vbox
- Timestamp:
- Jul 22, 2007 1:19:02 PM (18 years ago)
- svn:sync-xref-src-repo-rev:
- 23092
- Location:
- trunk/src/VBox/Main
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/Makefile.kmk
r3758 r3764 219 219 endif 220 220 221 # #Alternative USB filtering.222 #ifeq ($(filter-out darwin,$(BUILD_TARGET)),)223 #VBoxSVC_DEFS += VBOX_WITH_USBFILTER224 #VBoxSVC_LIBS += $(PATH_LIB)/USBLib$(VBOX_SUFF_LIB)225 #endif221 # Alternative USB filtering. 222 ifeq ($(filter-out darwin,$(BUILD_TARGET)),) 223 VBoxSVC_DEFS += VBOX_WITH_USBFILTER 224 VBoxSVC_LIBS += $(PATH_LIB)/USBLib$(VBOX_SUFF_LIB) 225 endif 226 226 227 227 -
trunk/src/VBox/Main/USBProxyService.cpp
r3758 r3764 456 456 457 457 458 #ifdef VBOX_WITH_USBFILTER 459 /*static*/ void USBProxyService::initFilterFromDevice (PUSBFILTER aFilter, HostUSBDevice *aDevice) 460 { 461 PCUSBDEVICE pDev = aDevice->mUsb; 462 int vrc; 463 464 vrc = USBFilterSetNumExact (aFilter, USBFILTERIDX_VENDOR_ID, pDev->idVendor, true); AssertRC(vrc); 465 vrc = USBFilterSetNumExact (aFilter, USBFILTERIDX_PRODUCT_ID, pDev->idProduct, true); AssertRC(vrc); 466 vrc = USBFilterSetNumExact (aFilter, USBFILTERIDX_DEVICE_REV, pDev->bcdDevice, true); AssertRC(vrc); 467 vrc = USBFilterSetNumExact (aFilter, USBFILTERIDX_DEVICE_CLASS, pDev->bDeviceClass, true); AssertRC(vrc); 468 vrc = USBFilterSetNumExact (aFilter, USBFILTERIDX_DEVICE_SUB_CLASS, pDev->bDeviceSubClass, true); AssertRC(vrc); 469 vrc = USBFilterSetNumExact (aFilter, USBFILTERIDX_DEVICE_PROTOCOL, pDev->bDeviceProtocol, true); AssertRC(vrc); 470 vrc = USBFilterSetNumExact (aFilter, USBFILTERIDX_PORT, pDev->bPort, true); AssertRC(vrc); 471 vrc = USBFilterSetNumExact (aFilter, USBFILTERIDX_BUS, pDev->bBus, false); AssertRC(vrc); /* not available on darwin yet... */ 472 if (pDev->pszSerialNumber) 473 { 474 vrc = USBFilterSetStringExact (aFilter, USBFILTERIDX_SERIAL_NUMBER_STR, pDev->pszSerialNumber, true); 475 AssertRC (vrc); 476 } 477 if (pDev->pszProduct) 478 { 479 vrc = USBFilterSetStringExact (aFilter, USBFILTERIDX_PRODUCT_STR, pDev->pszProduct, true); 480 AssertRC (vrc); 481 } 482 if (pDev->pszManufacturer) 483 { 484 vrc = USBFilterSetStringExact (aFilter, USBFILTERIDX_MANUFACTURER_STR, pDev->pszManufacturer, true); 485 AssertRC (vrc); 486 } 487 } 488 #endif /* VBOX_WITH_USBFILTER */ 489 490 458 491 bool USBProxyService::updateDeviceStateFake (HostUSBDevice *aDevice, PUSBDEVICE aUSBDevice) 459 492 { … … 561 594 562 595 563 int USBProxyService::holdDevice (HostUSBDevice * /* aDevice */)564 {565 return VERR_NOT_IMPLEMENTED;566 }567 568 569 596 void USBProxyService::detachingDevice (HostUSBDevice * /* aDevice */) 570 597 { -
trunk/src/VBox/Main/darwin/iokit.cpp
r3665 r3764 42 42 43 43 #include <VBox/log.h> 44 #include <VBox/err.h> 44 45 #include <iprt/mem.h> 45 46 #include <iprt/string.h> 47 #include <iprt/process.h> 46 48 #include <iprt/assert.h> 49 #include <iprt/thread.h> 47 50 48 51 #include "iokit.h" … … 55 58 #define MY_CHECK_CREFS(cRefs) do { AssertMsg(cRefs < 25, ("%ld\n", cRefs)); NOREF(cRefs); } while (0) 56 59 60 /** Contains the pid of the current client. If 0, the kernel is the current client. */ 61 #define VBOXUSB_CLIENT_KEY "VBoxUSB-Client" 62 /** Contains the pid of the filter owner (i.e. the VBoxSVC pid). */ 63 #define VBOXUSB_OWNER_KEY "VBoxUSB-Owner" 64 /** The VBoxUSBDevice class name. */ 65 #define VBOXUSBDEVICE_CLASS_NAME "org_virtualbox_VBoxUSBDevice" 66 57 67 58 68 /******************************************************************************* … … 162 172 *pu64 = 0; 163 173 return false; 174 } 175 176 177 /** 178 * Gets a RTPROCESS value. 179 * 180 * @returns Success indicator (true/false). 181 * @param DictRef The dictionary. 182 * @param KeyStrRef The key name. 183 * @param pProcess Where to store the key value. 184 */ 185 static bool darwinDictGetProccess(CFMutableDictionaryRef DictRef, CFStringRef KeyStrRef, PRTPROCESS pProcess) 186 { 187 switch (sizeof(*pProcess)) 188 { 189 case sizeof(uint16_t): return darwinDictGetU16(DictRef, KeyStrRef, (uint16_t *)pProcess); 190 case sizeof(uint32_t): return darwinDictGetU32(DictRef, KeyStrRef, (uint32_t *)pProcess); 191 case sizeof(uint64_t): return darwinDictGetU64(DictRef, KeyStrRef, (uint64_t *)pProcess); 192 default: 193 AssertMsgFailedReturn(("%d\n", sizeof(*pProcess)), false); 194 } 164 195 } 165 196 … … 630 661 return; 631 662 663 RTPROCESS Owner = NIL_RTPROCESS; 664 RTPROCESS Client = NIL_RTPROCESS; 632 665 bool fUserClientOnly = true; 633 666 bool fConfigured = false; … … 686 719 } 687 720 } 721 /* 722 * Not an interface, could it be VBoxUSBDevice? 723 * If it is, get the owner and client properties. 724 */ 725 else if ( krc == KERN_SUCCESS 726 && !strcmp(szName, VBOXUSBDEVICE_CLASS_NAME)) 727 { 728 CFMutableDictionaryRef PropsRef = 0; 729 krc = IORegistryEntryCreateCFProperties(Interface, &PropsRef, kCFAllocatorDefault, kNilOptions); 730 if (krc == KERN_SUCCESS) 731 { 732 darwinDictGetProccess(PropsRef, CFSTR(VBOXUSB_OWNER_KEY), &Owner); 733 darwinDictGetProccess(PropsRef, CFSTR(VBOXUSB_CLIENT_KEY), &Client); 734 CFRelease(PropsRef); 735 } 736 } 737 688 738 IOObjectRelease(Interface); 689 739 } … … 693 743 * Calc the status. 694 744 */ 695 if (fUserClientOnly) 696 /** @todo how to detect other user client?!? */ 745 if ( Owner != NIL_RTPROCESS 746 && !Owner) 747 { 748 if (Owner == RTProcSelf()) 749 pCur->enmState = Client == NIL_RTPROCESS || !Client 750 ? USBDEVICESTATE_HELD_BY_PROXY 751 : USBDEVICESTATE_USED_BY_GUEST; 752 else 753 pCur->enmState = USBDEVICESTATE_USED_BY_HOST; 754 } 755 else if (fUserClientOnly) 756 /** @todo how to detect other user client?!? - Look for IOUSBUserClient! */ 697 757 pCur->enmState = !fConfigured 698 758 ? USBDEVICESTATE_UNUSED 699 759 : USBDEVICESTATE_USED_BY_HOST_CAPTURABLE; 700 701 760 else if (!fInUse) 702 761 pCur->enmState = USBDEVICESTATE_UNUSED; … … 909 968 } 910 969 970 971 /** 972 * Triggers re-enumeration of a device. 973 * 974 * @returns VBox status code. 975 * @param pCur The USBDEVICE structure for the device. 976 */ 977 int DarwinReEnumerateUSBDevice(PCUSBDEVICE pCur) 978 { 979 int vrc; 980 const char *pszAddress = pCur->pszAddress; 981 AssertPtrReturn(pszAddress, VERR_INVALID_POINTER); 982 AssertReturn(darwinOpenMasterPort(), VERR_GENERAL_FAILURE); 983 984 /* 985 * This code is a short version of the Open method in USBProxyDevice-darwin.cpp stuff. 986 * Fixes made to this code probably applies there too! 987 */ 988 989 CFMutableDictionaryRef RefMatchingDict = IOServiceMatching(kIOUSBDeviceClassName); 990 AssertReturn(RefMatchingDict, NULL); 991 992 uint64_t u64SessionId = 0; 993 uint32_t u32LocationId = 0; 994 const char *psz = pszAddress; 995 do 996 { 997 const char chValue = *psz; 998 AssertReleaseReturn(psz[1] == '=', VERR_INTERNAL_ERROR); 999 uint64_t u64Value; 1000 int rc = RTStrToUInt64Ex(psz + 2, (char **)&psz, 0, &u64Value); 1001 AssertReleaseRCReturn(rc, rc); 1002 AssertReleaseReturn(!*psz || *psz == ';', rc); 1003 switch (chValue) 1004 { 1005 case 'l': 1006 u32LocationId = (uint32_t)u64Value; 1007 break; 1008 case 's': 1009 u64SessionId = u64Value; 1010 break; 1011 case 'p': 1012 case 'v': 1013 { 1014 #if 0 /* Guess what, this doesn't 'ing work either! */ 1015 SInt32 i32 = (int16_t)u64Value; 1016 CFNumberRef Num = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &i32); 1017 AssertBreak(Num,); 1018 CFDictionarySetValue(RefMatchingDict, chValue == 'p' ? CFSTR(kUSBProductID) : CFSTR(kUSBVendorID), Num); 1019 CFRelease(Num); 1020 #endif 1021 break; 1022 } 1023 default: 1024 AssertReleaseMsgFailedReturn(("chValue=%#x\n", chValue), VERR_INTERNAL_ERROR); 1025 } 1026 if (*psz == ';') 1027 psz++; 1028 } while (*psz); 1029 1030 io_iterator_t USBDevices = NULL; 1031 IOReturn irc = IOServiceGetMatchingServices(g_MasterPort, RefMatchingDict, &USBDevices); 1032 AssertMsgReturn(irc == kIOReturnSuccess, ("irc=%#x\n", irc), NULL); 1033 RefMatchingDict = NULL; /* the reference is consumed by IOServiceGetMatchingServices. */ 1034 1035 unsigned cMatches = 0; 1036 io_object_t USBDevice; 1037 while ((USBDevice = IOIteratorNext(USBDevices))) 1038 { 1039 cMatches++; 1040 CFMutableDictionaryRef PropsRef = 0; 1041 kern_return_t krc = IORegistryEntryCreateCFProperties(USBDevice, &PropsRef, kCFAllocatorDefault, kNilOptions); 1042 if (krc == KERN_SUCCESS) 1043 { 1044 uint64_t u64CurSessionId; 1045 uint32_t u32CurLocationId; 1046 if ( ( !u64SessionId 1047 || ( darwinDictGetU64(PropsRef, CFSTR("sessionID"), &u64CurSessionId) 1048 && u64CurSessionId == u64SessionId)) 1049 && ( !u32LocationId 1050 || ( darwinDictGetU32(PropsRef, CFSTR(kUSBDevicePropertyLocationID), &u32CurLocationId) 1051 && u32CurLocationId == u32LocationId)) 1052 ) 1053 { 1054 CFRelease(PropsRef); 1055 break; 1056 } 1057 CFRelease(PropsRef); 1058 } 1059 IOObjectRelease(USBDevice); 1060 } 1061 IOObjectRelease(USBDevices); 1062 USBDevices = NULL; 1063 if (!USBDevice) 1064 { 1065 LogRel(("USB: Device '%s' not found (%d pid+vid matches)\n", pszAddress, cMatches)); 1066 IOObjectRelease(USBDevices); 1067 return VERR_VUSB_DEVICE_NAME_NOT_FOUND; 1068 } 1069 1070 /* 1071 * Create a plugin interface for the device and query its IOUSBDeviceInterface. 1072 */ 1073 SInt32 Score = 0; 1074 IOCFPlugInInterface **ppPlugInInterface = NULL; 1075 irc = IOCreatePlugInInterfaceForService(USBDevice, kIOUSBDeviceUserClientTypeID, 1076 kIOCFPlugInInterfaceID, &ppPlugInInterface, &Score); 1077 if (irc == kIOReturnSuccess) 1078 { 1079 IOUSBDeviceInterface245 **ppDevI = NULL; 1080 HRESULT hrc = (*ppPlugInInterface)->QueryInterface(ppPlugInInterface, 1081 CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID245), 1082 (LPVOID *)&ppDevI); 1083 irc = IODestroyPlugInInterface(ppPlugInInterface); Assert(irc == kIOReturnSuccess); 1084 ppPlugInInterface = NULL; 1085 if (hrc == S_OK) 1086 { 1087 /* 1088 * Try open the device for exclusive access. 1089 */ 1090 irc = (*ppDevI)->USBDeviceOpenSeize(ppDevI); 1091 if (irc == kIOReturnExclusiveAccess) 1092 { 1093 RTThreadSleep(20); 1094 irc = (*ppDevI)->USBDeviceOpenSeize(ppDevI); 1095 } 1096 if (irc == kIOReturnSuccess) 1097 { 1098 /* 1099 * Re-enumerate the device and bail out. 1100 */ 1101 irc = (*ppDevI)->USBDeviceReEnumerate(ppDevI, 0); 1102 if (irc != kIOReturnSuccess) 1103 { 1104 LogRel(("USB: Failed to open device '%s', plug-in creation failed with irc=%#x.\n", pszAddress, irc)); 1105 vrc = RTErrConvertFromDarwinIO(irc); 1106 } 1107 1108 (*ppDevI)->USBDeviceClose(ppDevI); 1109 } 1110 else if (irc == kIOReturnExclusiveAccess) 1111 { 1112 LogRel(("USB: Device '%s' is being used by another process\n", pszAddress)); 1113 vrc = VERR_SHARING_VIOLATION; 1114 } 1115 else 1116 { 1117 LogRel(("USB: Failed to open device '%s', irc=%#x.\n", pszAddress, irc)); 1118 vrc = VERR_OPEN_FAILED; 1119 } 1120 } 1121 else 1122 { 1123 LogRel(("USB: Failed to create plugin interface for device '%s', hrc=%#x.\n", pszAddress, hrc)); 1124 vrc = VERR_OPEN_FAILED; 1125 } 1126 1127 (*ppDevI)->Release(ppDevI); 1128 } 1129 else 1130 { 1131 LogRel(("USB: Failed to open device '%s', plug-in creation failed with irc=%#x.\n", pszAddress, irc)); 1132 vrc = RTErrConvertFromDarwinIO(irc); 1133 } 1134 1135 return vrc; 1136 } 1137 911 1138 #endif /* VBOX_WITH_USB */ 912 1139 -
trunk/src/VBox/Main/darwin/iokit.h
r3662 r3764 51 51 PUSBDEVICE DarwinGetUSBDevices(void); 52 52 void DarwinFreeUSBDeviceFromIOKit(PUSBDEVICE pCur); 53 int DarwinReEnumerateUSBDevice(PCUSBDEVICE pCur); 53 54 #endif 54 55 __END_DECLS -
trunk/src/VBox/Main/include/HostUSBDeviceImpl.h
r3668 r3764 84 84 85 85 /** Additional internal states. 86 * The async detach stuff for Darwin is a two stage journey with a variation 86 * The async detach stuff for Darwin is a two stage journey with a variation 87 87 * (filters) depending on who won the race to lock the Host object. 88 * 89 * @remark Trying out mac os x style enum naming convention here. nice or what? 88 * 89 * @remark Trying out mac os x style enum naming convention here. nice or what? 90 90 */ 91 91 typedef enum 92 { 92 { 93 93 /** Nothing is pending here, check mPendingState. */ 94 kNothingPending, 94 kNothingPending, 95 95 /** 1st stage of the detch, waiting for the logical detach notification. */ 96 kDetachingPendingDetach, 97 /** 1st stage of the detch, waiting for the logical detach notification - re-run filters. 96 kDetachingPendingDetach, 97 /** 1st stage of the detch, waiting for the logical detach notification - re-run filters. 98 98 * Prev: kDetachingPendingDetach */ 99 kDetachingPendingDetachFilters, 100 /** 2nd stage of the detach, waiting for the logical attach notification. 99 kDetachingPendingDetachFilters, 100 /** 2nd stage of the detach, waiting for the logical attach notification. 101 101 * Prev: kDetachingPendingDetach */ 102 102 kDetachingPendingAttach, 103 /** 2nd stage of the detach, waiting for the logical attach notification - re-run filters. 103 /** 2nd stage of the detach, waiting for the logical attach notification - re-run filters. 104 104 * Prev: kDetachingPendingDetachFilters */ 105 105 kDetachingPendingAttachFilters … … 163 163 /** Same as mPendingState but for the internal states. */ 164 164 InternalState mPendingStateEx; 165 /** RTTimeNanoTS() of when mIsStatePending was set or mDetaching changed 165 /** RTTimeNanoTS() of when mIsStatePending was set or mDetaching changed 166 166 * from kNotDetaching. For operations that cannot be cancelled it's 0. */ 167 167 uint64_t mPendingSince; … … 179 179 #ifdef RT_OS_LINUX 180 180 friend class USBProxyServiceLinux; 181 #endif 182 #ifdef RT_OS_DARWIN 183 /** One-shot filter id. */ 184 void *mOneShotId; 185 186 friend class USBProxyServiceDarwin; 181 187 #endif 182 188 }; -
trunk/src/VBox/Main/include/USBProxyService.h
r3758 r3764 64 64 65 65 /** 66 * The device is to be held so that the host OS will not start using it.67 *68 * @returns VBox status code.69 * @param aDevice The device in question.70 */71 virtual int holdDevice (HostUSBDevice *aDevice);72 73 /**74 66 * The device is going to be detached from a VM. 75 67 * … … 137 129 */ 138 130 static uint64_t calcSerialHash (const char *aSerial); 131 132 #ifdef VBOX_WITH_USBFILTER 133 /** 134 * Initializes a filter with the data from the specified device. 135 * 136 * @param aFilter The filter to fill. 137 * @param aDevice The device to fill it with. 138 */ 139 static void initFilterFromDevice (PUSBFILTER aFilter, HostUSBDevice *aDevice); 140 #endif 139 141 140 142 protected: … … 270 272 271 273 virtual int captureDevice (HostUSBDevice *aDevice); 272 virtual int holdDevice (HostUSBDevice *aDevice);273 274 virtual void detachingDevice (HostUSBDevice *aDevice); 274 275 virtual int releaseDevice (HostUSBDevice *aDevice); … … 291 292 * not including newly attached devices. */ 292 293 bool mWaitABitNextTime; 294 #ifndef VBOX_WITH_USBFILTER 293 295 /** Whether we've got a fake async event and should return without entering the runloop. */ 294 296 bool volatile mFakeAsync; 297 #endif 295 298 /** Whether we've successfully initialized the USBLib and should call USBLibTerm in the destructor. */ 296 299 bool mUSBLibInitialized; … … 312 315 313 316 virtual int captureDevice (HostUSBDevice *aDevice); 314 virtual int holdDevice (HostUSBDevice *aDevice);315 317 virtual int releaseDevice (HostUSBDevice *aDevice); 316 318 virtual bool updateDeviceState (HostUSBDevice *aDevice, PUSBDEVICE aUSBDevice); … … 354 356 355 357 virtual int captureDevice (HostUSBDevice *aDevice); 356 virtual int holdDevice (HostUSBDevice *aDevice);357 358 virtual int releaseDevice (HostUSBDevice *aDevice); 358 359 virtual bool updateDeviceState (HostUSBDevice *aDevice, PUSBDEVICE aUSBDevice);
Note:
See TracChangeset
for help on using the changeset viewer.