Changeset 2587 in vbox for trunk/src/VBox
- Timestamp:
- May 11, 2007 3:12:27 AM (18 years ago)
- Location:
- trunk/src/VBox/Main
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/HostImpl.cpp
r2434 r2587 113 113 mParent = parent; 114 114 115 #if defined (__LINUX__) && defined (VBOX_WITH_USB) 115 #if defined (__DARWIN__) && defined (VBOX_WITH_USB) 116 mUSBProxyService = new USBProxyServiceDarwin (this); 117 #elif defined (__LINUX__) && defined (VBOX_WITH_USB) 116 118 mUSBProxyService = new USBProxyServiceLinux (this); 117 119 #elif defined (__WIN__) && defined (VBOX_WITH_USB) -
trunk/src/VBox/Main/Makefile.kmk
r2486 r2587 202 202 203 203 ifdef VBOX_WITH_USB 204 VBoxSVC_SOURCES.darwin += darwin/USBProxyServiceDarwin.cpp 204 205 VBoxSVC_SOURCES.linux += linux/USBProxyServiceLinux.cpp 205 206 VBoxSVC_SOURCES.win += win32/USBProxyServiceWin32.cpp -
trunk/src/VBox/Main/USBProxyService.cpp
r1 r2587 288 288 USBProxyService *pThis = (USBProxyService *)pvUser; 289 289 LogFlow (("USBProxyService::serviceThread: pThis=%p\n", pThis)); 290 pThis->serviceThreadInit(); 290 291 291 292 /* … … 300 301 } 301 302 303 pThis->serviceThreadTerm(); 302 304 LogFlow (("USBProxyService::serviceThread: returns VINF_SUCCESS\n")); 303 305 return VINF_SUCCESS; … … 391 393 } 392 394 395 396 void USBProxyService::serviceThreadInit (void) 397 { 398 } 399 400 401 void USBProxyService::serviceThreadTerm (void) 402 { 403 } 404 405 393 406 /** 394 407 * The default implementation returns non-NULL to emulate successful insertions -
trunk/src/VBox/Main/darwin/iokit.cpp
r2342 r2587 34 34 #include <IOKit/scsi-commands/SCSITaskLib.h> 35 35 #include <mach/mach_error.h> 36 #ifdef VBOX_WITH_USB 37 # include <IOKit/usb/IOUSBLib.h> 38 #endif 36 39 37 40 #include <iprt/mem.h> … … 40 43 41 44 #include "iokit.h" 45 46 47 /******************************************************************************* 48 * Defined Constants And Macros * 49 *******************************************************************************/ 50 /** An attempt at catching reference leaks. */ 51 #define MY_CHECK_CREFS(cRefs) do { AssertMsg(cRefs < 25, ("%ld\n", cRefs)); NOREF(cRefs); } while (0) 42 52 43 53 … … 49 59 50 60 61 /** 62 * Lazily opens the master port. 63 * 64 * @returns true if the port is open, false on failure (very unlikely). 65 */ 66 static bool darwinOpenMasterPort(void) 67 { 68 if (!g_MasterPort) 69 { 70 kern_return_t krc = IOMasterPort(MACH_PORT_NULL, &g_MasterPort); 71 AssertReturn(krc == KERN_SUCCESS, false); 72 } 73 return true; 74 } 75 76 77 #ifdef VBOX_WITH_USB 78 79 /** 80 * Gets an unsigned 8-bit integer value. 81 * 82 * @returns Success indicator (true/false). 83 * @param DictRef The dictionary. 84 * @param KeyStrRef The key name. 85 * @param pu8 Where to store the key value. 86 */ 87 static bool darwinDictGetU8(CFMutableDictionaryRef DictRef, CFStringRef KeyStrRef, uint8_t *pu8) 88 { 89 CFTypeRef ValRef = CFDictionaryGetValue(DictRef, KeyStrRef); 90 if (ValRef) 91 { 92 if (CFNumberGetValue((CFNumberRef)ValRef, kCFNumberSInt8Type, pu8)) 93 return true; 94 } 95 *pu8 = 0; 96 return false; 97 } 98 99 100 /** 101 * Gets an unsigned 16-bit integer value. 102 * 103 * @returns Success indicator (true/false). 104 * @param DictRef The dictionary. 105 * @param KeyStrRef The key name. 106 * @param pu16 Where to store the key value. 107 */ 108 static bool darwinDictGetU16(CFMutableDictionaryRef DictRef, CFStringRef KeyStrRef, uint16_t *pu16) 109 { 110 CFTypeRef ValRef = CFDictionaryGetValue(DictRef, KeyStrRef); 111 if (ValRef) 112 { 113 if (CFNumberGetValue((CFNumberRef)ValRef, kCFNumberSInt16Type, pu16)) 114 return true; 115 } 116 *pu16 = 0; 117 return false; 118 } 119 120 121 /** 122 * Gets an unsigned 32-bit integer value. 123 * 124 * @returns Success indicator (true/false). 125 * @param DictRef The dictionary. 126 * @param KeyStrRef The key name. 127 * @param pu32 Where to store the key value. 128 */ 129 static bool darwinDictGetU32(CFMutableDictionaryRef DictRef, CFStringRef KeyStrRef, uint32_t *pu32) 130 { 131 CFTypeRef ValRef = CFDictionaryGetValue(DictRef, KeyStrRef); 132 if (ValRef) 133 { 134 if (CFNumberGetValue((CFNumberRef)ValRef, kCFNumberSInt32Type, pu32)) 135 return true; 136 } 137 *pu32 = 0; 138 return false; 139 } 140 141 142 /** 143 * Gets an unsigned 64-bit integer value. 144 * 145 * @returns Success indicator (true/false). 146 * @param DictRef The dictionary. 147 * @param KeyStrRef The key name. 148 * @param pu64 Where to store the key value. 149 */ 150 static bool darwinDictGetU64(CFMutableDictionaryRef DictRef, CFStringRef KeyStrRef, uint64_t *pu64) 151 { 152 CFTypeRef ValRef = CFDictionaryGetValue(DictRef, KeyStrRef); 153 if (ValRef) 154 { 155 if (CFNumberGetValue((CFNumberRef)ValRef, kCFNumberSInt64Type, pu64)) 156 return true; 157 } 158 *pu64 = 0; 159 return false; 160 } 161 162 163 /** 164 * Gets string value, converted to UTF-8 and put in a IPRT string buffer. 165 * 166 * @returns Success indicator (true/false). 167 * @param DictRef The dictionary. 168 * @param KeyStrRef The key name. 169 * @param ppsz Where to store the key value. Free with RTStrFree. Set to NULL on failure. 170 */ 171 static bool darwinDictGetString(CFMutableDictionaryRef DictRef, CFStringRef KeyStrRef, char **ppsz) 172 { 173 CFTypeRef ValRef = CFDictionaryGetValue(DictRef, KeyStrRef); 174 if (ValRef) 175 { 176 char szBuf[512]; 177 if (CFStringGetCString((CFStringRef)ValRef, szBuf, sizeof(szBuf), kCFStringEncodingUTF8)) 178 { 179 *ppsz = RTStrDup(RTStrStrip(szBuf)); 180 if (*ppsz) 181 return true; 182 } 183 } 184 *ppsz = NULL; 185 return false; 186 } 187 188 189 190 void DarwinSubscribeUSBNotifications(void) 191 { 192 193 } 194 195 void DarwinUnsubscribeUSBNotifications(void) 196 { 197 198 } 199 200 201 /** 202 * Enumerate the USB devices returning a FIFO of them. 203 * 204 * @returns Pointer to the head. 205 * USBProxyService::freeDevice is expected to free each of the list elements. 206 */ 207 PUSBDEVICE DarwinGetUSBDevices(void) 208 { 209 AssertReturn(darwinOpenMasterPort(), NULL); 210 211 /* 212 * Create a matching dictionary for searching for USB Devices in the IOKit. 213 */ 214 CFMutableDictionaryRef RefMatchingDict = IOServiceMatching(kIOUSBDeviceClassName); 215 AssertReturn(RefMatchingDict, NULL); 216 217 /* 218 * Perform the search and get a collection of USB Device back. 219 */ 220 io_iterator_t USBDevices = NULL; 221 IOReturn rc = IOServiceGetMatchingServices(g_MasterPort, RefMatchingDict, &USBDevices); 222 AssertMsgReturn(rc == kIOReturnSuccess, ("rc=%d\n", rc), NULL); 223 RefMatchingDict = NULL; /* the reference is consumed by IOServiceGetMatchingServices. */ 224 225 /* 226 * Enumerate the USB Devices. 227 */ 228 PUSBDEVICE pHead = NULL; 229 PUSBDEVICE pTail = NULL; 230 unsigned i = 0; 231 io_object_t USBDevice; 232 while ((USBDevice = IOIteratorNext(USBDevices)) != 0) 233 { 234 /* 235 * Query the device properties from the registry. 236 * 237 * We could alternatively use the device and such, but that will be 238 * slower and we would have to resort to the registry for the three 239 * string anyway. 240 */ 241 CFMutableDictionaryRef PropsRef = 0; 242 kern_return_t krc = IORegistryEntryCreateCFProperties(USBDevice, &PropsRef, kCFAllocatorDefault, kNilOptions); 243 if (krc == KERN_SUCCESS) 244 { 245 bool fOk = false; 246 PUSBDEVICE pCur = (PUSBDEVICE)RTMemAllocZ(sizeof(*pCur)); 247 do /* loop for breaking out of on failure. */ 248 { 249 AssertBreak(pCur,); 250 251 /* 252 * Mandatory 253 */ 254 pCur->bcdUSB = 0; /* we've no idea. */ 255 pCur->enmState = USBDEVICESTATE_USED_BY_HOST_CAPTURABLE; /* ditto. */ 256 257 AssertBreak(darwinDictGetU8(PropsRef, CFSTR(kUSBDeviceClass), &pCur->bDeviceClass),); 258 /* skip hubs */ 259 if (pCur->bDeviceClass == 0x09 /* hub, find a define! */) 260 break; 261 AssertBreak(darwinDictGetU8(PropsRef, CFSTR(kUSBDeviceSubClass), &pCur->bDeviceSubClass),); 262 AssertBreak(darwinDictGetU8(PropsRef, CFSTR(kUSBDeviceProtocol), &pCur->bDeviceProtocol),); 263 AssertBreak(darwinDictGetU16(PropsRef, CFSTR(kUSBVendorID), &pCur->idVendor),); 264 AssertBreak(darwinDictGetU16(PropsRef, CFSTR(kUSBProductID), &pCur->idProduct),); 265 AssertBreak(darwinDictGetU16(PropsRef, CFSTR(kUSBDeviceReleaseNumber), &pCur->bcdDevice),); 266 char szAddress[32]; 267 #if 0 268 uint32_t u32LocationID; 269 AssertBreak(darwinDictGetU32(PropsRef, CFSTR(kUSBDevicePropertyLocationID), &u32LocationID),); 270 RTStrPrintf(szAddress, sizeof(szAddress), "%08RX32", u32LocationID); 271 #else 272 uint64_t u64SessionID; 273 AssertBreak(darwinDictGetU64(PropsRef, CFSTR(kUSBDevicePropertyLocationID), &u64SessionID),); 274 RTStrPrintf(szAddress, sizeof(szAddress), "%016RX32", u64SessionID); 275 #endif 276 pCur->pszAddress = RTStrDup(szAddress); 277 AssertBreak(pCur->pszAddress,); 278 279 /* 280 * Optional. 281 * There are some nameless device in the iMac, apply names to them. 282 */ 283 darwinDictGetString(PropsRef, CFSTR("USB Vendor Name"), (char **)&pCur->pszManufacturer); 284 if ( !pCur->pszManufacturer 285 && pCur->idVendor == kIOUSBVendorIDAppleComputer) 286 pCur->pszManufacturer = RTStrDup("Apple Computer, Inc."); 287 darwinDictGetString(PropsRef, CFSTR("USB Product Name"), (char **)&pCur->pszProduct); 288 if ( !pCur->pszProduct 289 && pCur->bDeviceClass == 224 /* Wireless */ 290 && pCur->bDeviceSubClass == 1 /* Radio Frequency */ 291 && pCur->bDeviceProtocol == 1 /* Bluetooth */) 292 pCur->pszProduct = RTStrDup("Bluetooth"); 293 darwinDictGetString(PropsRef, CFSTR("USB Serial Number"), (char **)&pCur->pszSerialNumber); 294 295 #if 0 /* leave the remainder as zero for now. */ 296 /* 297 * Create a plugin interface for the service and query its USB Device interface. 298 */ 299 SInt32 Score = 0; 300 IOCFPlugInInterface **ppPlugInInterface = NULL; 301 rc = IOCreatePlugInInterfaceForService(USBDevice, kIOUSBDeviceUserClientTypeID, 302 kIOCFPlugInInterfaceID, &ppPlugInInterface, &Score); 303 if (rc == kIOReturnSuccess) 304 { 305 IOUSBDeviceInterface245 **ppUSBDevI = NULL; 306 HRESULT hrc = (*ppPlugInInterface)->QueryInterface(ppPlugInInterface, 307 CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID245), 308 (LPVOID *)&ppUSBDevI); 309 rc = IODestroyPlugInInterface(ppPlugInInterface); Assert(rc == kIOReturnSuccess); 310 ppPlugInInterface = NULL; 311 if (hrc == S_OK) 312 { 313 /** @todo enumerate configurations and interfaces if we actually need them. */ 314 //IOReturn (*GetNumberOfConfigurations)(void *self, UInt8 *numConfig); 315 //IOReturn (*GetConfigurationDescriptorPtr)(void *self, UInt8 configIndex, IOUSBConfigurationDescriptorPtr *desc); 316 //IOReturn (*CreateInterfaceIterator)(void *self, IOUSBFindInterfaceRequest *req, io_iterator_t *iter); 317 } 318 long cReft = (*ppUSBDeviceInterface)->Release(ppUSBDeviceInterface); MY_CHECK_CREFS(cRefs); 319 } 320 #endif 321 322 /* 323 * We're good. Link the device. 324 */ 325 pCur->pPrev = pTail; 326 if (pTail) 327 pTail = pTail->pNext = pCur; 328 else 329 pTail = pHead = pCur; 330 fOk = true; 331 } while (0); 332 333 /* cleanup on failure / skipped device. */ 334 if (!fOk && pCur) 335 { 336 /** @todo */ 337 } 338 339 CFRelease(PropsRef); 340 } 341 else 342 AssertMsgFailed(("krc=%#x\n", krc)); 343 344 IOObjectRelease(USBDevice); 345 i++; 346 } 347 348 IOObjectRelease(USBDevices); 349 350 /* 351 * Some post processing. There are a couple of things we have to 352 * make 100% sure about, and that is that the (Apple) keyboard 353 * and mouse most likely to be in use by the user aren't available 354 * for capturing. If there is no Apple mouse or keyboard we'll 355 * take the first one from another vendor. 356 */ 357 PUSBDEVICE pMouse = NULL; 358 PUSBDEVICE pKeyboard = NULL; 359 for (PUSBDEVICE pCur = pHead; pCur; pCur = pCur->pNext) 360 if (pCur->idVendor == kIOUSBVendorIDAppleComputer) 361 { 362 /* 363 * This test is a bit rough, should check device class/protocol but 364 * we don't have interface info yet so that might be a bit tricky. 365 */ 366 if ( ( !pKeyboard 367 || pKeyboard->idVendor != kIOUSBVendorIDAppleComputer) 368 && pCur->pszProduct 369 && strstr(pCur->pszProduct, " Keyboard")) 370 pKeyboard = pCur; 371 else if ( ( !pMouse 372 || pMouse->idVendor != kIOUSBVendorIDAppleComputer) 373 && pCur->pszProduct 374 && strstr(pCur->pszProduct, " Mouse") 375 ) 376 pMouse = pCur; 377 } 378 else if (!pKeyboard || !pMouse) 379 { 380 if ( pCur->bDeviceClass == 3 /* HID */ 381 && pCur->bDeviceProtocol == 1 /* Keyboard */) 382 pKeyboard = pCur; 383 else if ( pCur->bDeviceClass == 3 /* HID */ 384 && pCur->bDeviceProtocol == 2 /* Mouse */) 385 pMouse = pCur; 386 /** @todo examin interfaces */ 387 } 388 389 if (pKeyboard) 390 pKeyboard->enmState = USBDEVICESTATE_USED_BY_HOST; 391 if (pMouse) 392 pMouse->enmState = USBDEVICESTATE_USED_BY_HOST; 393 394 return pHead; 395 } 396 397 #endif /* VBOX_WITH_USB */ 398 51 399 52 400 /** … … 58 406 PDARWINDVD DarwinGetDVDDrives(void) 59 407 { 60 PDARWINDVD pHead = NULL; 61 PDARWINDVD pTail = NULL; 62 63 /* 64 * Open the master port on the first invocation. 65 */ 66 if (!g_MasterPort) 67 { 68 kern_return_t krc = IOMasterPort(MACH_PORT_NULL, &g_MasterPort); 69 AssertReturn(krc == KERN_SUCCESS, NULL); 70 } 408 AssertReturn(darwinOpenMasterPort(), NULL); 71 409 72 410 /* … … 83 421 84 422 /* 85 * do the search and get a collection of keyboards.423 * Perform the search and get a collection of DVD services. 86 424 */ 87 425 io_iterator_t DVDServices = NULL; … … 91 429 92 430 /* 93 * Enumerate the DVD drives (services).431 * Enumerate the DVD services. 94 432 * (This enumeration must be identical to the one performed in DrvHostBase.cpp.) 95 433 */ 434 PDARWINDVD pHead = NULL; 435 PDARWINDVD pTail = NULL; 96 436 unsigned i = 0; 97 437 io_object_t DVDService; … … 186 526 return pHead; 187 527 } 528 -
trunk/src/VBox/Main/darwin/iokit.h
r2342 r2587 25 25 #include <iprt/cdefs.h> 26 26 #include <iprt/types.h> 27 #ifdef VBOX_WITH_USB 28 # include <VBox/usb.h> 29 #endif 27 30 28 31 /** … … 37 40 } DARWINDVD, *PDARWINDVD; 38 41 42 /** The run loop mode string used by iokit.cpp when it registers 43 * notifications events. */ 44 #define VBOX_IOKIT_MODE_STRING "VBoxIOKitMode" 39 45 40 46 __BEGIN_DECLS 41 PDARWINDVD DarwinGetDVDDrives(void); 47 PDARWINDVD DarwinGetDVDDrives(void); 48 #ifdef VBOX_WITH_USB 49 void DarwinSubscribeUSBNotifications(void); 50 void DarwinUnsubscribeUSBNotifications(void); 51 PUSBDEVICE DarwinGetUSBDevices(void); 52 #endif 42 53 __END_DECLS 43 44 54 45 55 #endif -
trunk/src/VBox/Main/include/USBProxyService.h
r1 r2587 149 149 virtual PUSBDEVICE getDevices (void); 150 150 151 /** 152 * First call made on the service thread, use it to do 153 * thread initialization. 154 */ 155 virtual void serviceThreadInit (void); 156 157 /** 158 * First call made on the service thread, use it to do 159 * thread termination. 160 */ 161 virtual void serviceThreadTerm (void); 162 151 163 public: 152 164 /** … … 190 202 #ifdef VBOX_WITH_USB 191 203 204 # ifdef __DARWIN__ 205 # include <VBox/param.h> 206 # undef PAGE_SHIFT 207 # undef PAGE_SIZE 208 # define OSType Carbon_OSType 209 # include <Carbon/Carbon.h> 210 # undef OSType 211 212 /** 213 * The Darwin hosted USB Proxy Service. 214 */ 215 class USBProxyServiceDarwin : public USBProxyService 216 { 217 public: 218 USBProxyServiceDarwin (Host *aHost); 219 ~USBProxyServiceDarwin(); 220 221 virtual int captureDevice (HostUSBDevice *aDevice); 222 virtual int holdDevice (HostUSBDevice *aDevice); 223 virtual int releaseDevice (HostUSBDevice *aDevice); 224 virtual int resetDevice (HostUSBDevice *aDevice); 225 226 protected: 227 virtual int wait (unsigned aMillies); 228 virtual int interruptWait (void); 229 virtual PUSBDEVICE getDevices (void); 230 virtual void serviceThreadInit (void); 231 virtual void serviceThreadTerm (void); 232 233 private: 234 /** Reference to the runloop of the service thread. 235 * This is NULL if the service thread isn't running. */ 236 CFRunLoopRef mServiceRunLoopRef; 237 238 }; 239 # endif /* __DARWIN__ */ 240 241 192 242 # ifdef __LINUX__ 193 243 # include <stdio.h>
Note:
See TracChangeset
for help on using the changeset viewer.