void CreateDeviceInterfaceUsingOldMethod(io_object_t scsiDevice, IOSCSIDeviceInterface ***interface) { io_name_t className; IOCFPlugInInterface **plugInInterface = NULL; HRESULT plugInResult = S_OK; kern_return_t kr = kIOReturnSuccess; SInt32 score = 0; // Get the object's class name just to display it kr = IOObjectGetClass(scsiDevice, className); if (kr != kIOReturnSuccess) { fprintf(stderr, "Failed to get class name. (0x%08x)\n", kr); } else { fprintf(stderr, "Found device class \"%s\" using old method.\n", className); // Create the base interface of type IOCFPlugInInterface. // This object will be used to create the SCSI device interface object. kr = IOCreatePlugInInterfaceForService( scsiDevice, kIOSCSIUserClientTypeID, kIOCFPlugInInterfaceID, &plugInInterface, &score); if (kr != kIOReturnSuccess) { fprintf(stderr, "Couldn't create a plugin interface for the io_service_t. (0x%08x)\n", kr); } else { // Query the base plugin interface for an instance of the specific SCSI device interface // object. plugInResult = (*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(kIOSCSIDeviceInterfaceID), (LPVOID *) interface); if (plugInResult != S_OK) { fprintf(stderr, "Couldn't create SCSI device interface. (%ld)\n", plugInResult); } // We're now finished with the instance of IOCFPlugInInterface. IODestroyPlugInInterface(plugInInterface); } } }
static void iterate_devices(void* context, io_iterator_t iterator){ io_service_t device; while((device = IOIteratorNext(iterator)) != 0){ // Get the plugin interface for the device IOCFPlugInInterface** plugin; SInt32 score; kern_return_t err = IOCreatePlugInInterfaceForService(device, kIOHIDDeviceTypeID, kIOCFPlugInInterfaceID, &plugin, &score); if(err != kIOReturnSuccess){ ckb_err("Failed to create device plugin: %x\n", err); continue; } // Get the device interface hid_dev_t handle; err = (*plugin)->QueryInterface(plugin, CFUUIDGetUUIDBytes(kIOHIDDeviceDeviceInterfaceID), (LPVOID*)&handle); if(err != kIOReturnSuccess){ ckb_err("QueryInterface failed: %x\n", err); continue; } // Plugin is no longer needed IODestroyPlugInInterface(plugin); // Seize the device handle euid_guard_start; err = (*handle)->open(handle, kIOHIDOptionsTypeSeizeDevice); euid_guard_stop; if(err != kIOReturnSuccess){ ckb_err("Failed to seize device: %x\n", err); continue; } // Connect it io_object_t* rm_notify = 0; usbdevice* kb = usbadd(handle, &rm_notify); if(kb) // If successful, register for removal notification IOServiceAddInterestNotification(notify, device, kIOGeneralInterest, remove_device, kb, rm_notify); else { // Otherwise, release it now (*handle)->close(handle, kIOHIDOptionsTypeNone); remove_device(0, device, kIOMessageServiceIsTerminated, 0); } } }
IOReturn CreateRemoteIsochPort( IOFireWireLibNubRef nub, IOFireWireLibRemoteIsochPortRef* outPort ) { cout << i << "+CreateRemoteIsochPort\n" ; IOFireWireLibRemoteIsochPortRef port ; port = (**nub).CreateRemoteIsochPort( nub, false, CFUUIDGetUUIDBytes( kIOFireWireRemoteIsochPortInterfaceID ) ) ; if (!port) return kIOReturnError ; (**port).SetGetSupportedHandler( port, & RemotePort_GetSupported ) ; (**port).SetAllocatePortHandler( port, & RemotePort_AllocatePort ) ; (**port).SetReleasePortHandler( port, & RemotePort_ReleasePort ) ; (**port).SetStartHandler( port, & RemotePort_Start ) ; (**port).SetStopHandler( port, & RemotePort_Stop ) ; *outPort = port ; return kIOReturnSuccess ; }
HRESULT STDMETHODCALLTYPE DeckLinkDeviceInstance::QueryInterface(REFIID iid, LPVOID *ppv) { HRESULT result = E_NOINTERFACE; *ppv = nullptr; CFUUIDBytes unknown = CFUUIDGetUUIDBytes(IUnknownUUID); if (memcmp(&iid, &unknown, sizeof(REFIID)) == 0) { *ppv = this; AddRef(); result = S_OK; } else if (memcmp(&iid, &IID_IDeckLinkNotificationCallback, sizeof(REFIID)) == 0) { *ppv = (IDeckLinkNotificationCallback *)this; AddRef(); result = S_OK; } return result; }
//////////////////////////////////////////////////////////// /// Store the interface to the joystick/gamepad for future usage //////////////////////////////////////////////////////////// int JoystickSupport::GetDeviceInterface(io_object_t *hidDevice, JoystickDevice &joystick) { IOCFPlugInInterface **plugInInterface; HRESULT plugInResult; SInt32 score = 0; IOReturn ioRes; if (IOCreatePlugInInterfaceForService(*hidDevice, kIOHIDDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &plugInInterface, &score) == kIOReturnSuccess) { plugInResult = (*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(kIOHIDDeviceInterfaceID), (LPVOID*)&(joystick.hidDeviceInterface)); if( plugInResult == S_OK ) { (*plugInInterface)->Release(plugInInterface); ioRes = (*(joystick.hidDeviceInterface))->open(joystick.hidDeviceInterface, 0); } } return ioRes; }
unsigned long openDeviceInterface(UInt32 hidDevice, struct deviceRecord *deviceRec) { IOReturn result = 0; HRESULT plugInResult = 0; SInt32 score = 0; IOCFPlugInInterface **plugInInterface = NULL; if (!deviceRec->interface) { result = IOCreatePlugInInterfaceForService(hidDevice, kIOHIDDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &plugInInterface, &score); if (kIOReturnSuccess == result) { // Call a method of the intermediate plug-in to create the device interface plugInResult = (*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(kIOHIDDeviceInterfaceID), (void **) &(deviceRec->interface)); if (verbose && plugInResult) printf("Can't get HID device info.\n"); IODestroyPlugInInterface(plugInInterface); } else if (verbose) printf("Failed to create USB interface.\n"); } if (deviceRec->interface) { result = (*(IOHIDDeviceInterface**) deviceRec->interface)->open(deviceRec->interface, 0); if (verbose && result) printf("Failed to open USB device interface.\n"); } return result; }
// Read a 32bit value static VALUE FWDevice_readQuadlet(VALUE Self, VALUE StartAddr) { FWDevice *device; Data_Get_Struct(Self, FWDevice, device); IOCFPlugInInterface **cfPlugInInterface = NULL; SInt32 theScore; IOFireWireLibDeviceRef fwIntf; IOReturn result = IOCreatePlugInInterfaceForService(device->Device, kIOFireWireLibTypeID, kIOCFPlugInInterfaceID, &cfPlugInInterface, &theScore); (*cfPlugInInterface)->QueryInterface(cfPlugInInterface, CFUUIDGetUUIDBytes(kIOFireWireDeviceInterfaceID), (void **) &fwIntf); assert((*fwIntf)->InterfaceIsInited(fwIntf)); VALUE ret; if((*fwIntf)->Open(fwIntf) == 0) { // Set destination adress. Note that the upper 48 bits identify // the device on the bus and the address set by the operating system. uint64_t startaddr = rb_num2ull(StartAddr); FWAddress fwaddr; fwaddr.nodeID = 0; fwaddr.addressHi = startaddr >> 32; fwaddr.addressLo = startaddr & 0xffffffffL; // do the actual read UInt32 val = 0; result = (*fwIntf)->ReadQuadlet(fwIntf, device->Device, &fwaddr, &val, false, 0); ret = rb_hash_new(); rb_hash_aset(ret, ID2SYM(rb_intern("value")), INT2FIX(val)); rb_hash_aset(ret, ID2SYM(rb_intern("resultcode")), INT2FIX(result)); }
// Generate a unique user ID. We're using a GUID form, // but not jumping through hoops to make it cryptographically // secure. We just want it to distinguish unique users. static nsresult InitUserID(nsACString& aUserID) { nsID id; // copied shamelessly from nsUUIDGenerator.cpp #if defined(XP_WIN) HRESULT hr = CoCreateGuid((GUID*)&id); if (NS_FAILED(hr)) return NS_ERROR_FAILURE; #elif defined(XP_MACOSX) CFUUIDRef uuid = CFUUIDCreate(kCFAllocatorDefault); if (!uuid) return NS_ERROR_FAILURE; CFUUIDBytes bytes = CFUUIDGetUUIDBytes(uuid); memcpy(&id, &bytes, sizeof(nsID)); CFRelease(uuid); #else // UNIX or some such thing id.m0 = random(); id.m1 = random(); id.m2 = random(); *reinterpret_cast<PRUint32*>(&id.m3[0]) = random(); *reinterpret_cast<PRUint32*>(&id.m3[4]) = random(); #endif char* id_cstr = id.ToString(); NS_ENSURE_TRUE(id_cstr, NS_ERROR_OUT_OF_MEMORY); nsDependentCString id_str(id_cstr); aUserID = Substring(id_str, 1, id_str.Length()-2); PR_Free(id_cstr); return NS_OK; }
static krb5_error_code KRB5_CALLCONV get_default_name(krb5_context context, const krb5_cc_ops *ops, const char *cachename, char **str) { CFUUIDRef uuid = NULL; CFUUIDBytes bytes; uuid = HeimCredCopyDefaultCredential(kHEIMTypeKerberos, NULL); if (uuid == NULL) { return _krb5_expand_default_cc_name(context, cachename, str); } bytes = CFUUIDGetUUIDBytes(uuid); char uuidstr[37]; uuid_unparse((void *)&bytes, uuidstr); CFRELEASE_NULL(uuid); asprintf(str, "%s:%s", ops->prefix, uuidstr); return 0; }
// ---------------------------------------------------------------------------- // wxHIDDevice::Create // // nClass is the HID Page such as // kHIDPage_GenericDesktop // nType is the HID Usage such as // kHIDUsage_GD_Joystick,kHIDUsage_GD_Mouse,kHIDUsage_GD_Keyboard // nDev is the device number to use // // ---------------------------------------------------------------------------- bool wxHIDDevice::Create (int nClass, int nType, int nDev) { //Create the mach port if(IOMasterPort(bootstrap_port, &m_pPort) != kIOReturnSuccess) { wxLogSysError(wxT("Could not create mach port")); return false; } //Dictionary that will hold first //the matching dictionary for determining which kind of devices we want, //then later some registry properties from an iterator (see below) // //The call to IOServiceMatching filters down the //the services we want to hid services (and also eats the //dictionary up for us (consumes one reference)) CFMutableDictionaryRef pDictionary = IOServiceMatching(kIOHIDDeviceKey); if(pDictionary == NULL) { wxLogSysError( wxT("IOServiceMatching(kIOHIDDeviceKey) failed") ); return false; } //Here we'll filter down the services to what we want if (nType != -1) { CFNumberRef pType = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &nType); CFDictionarySetValue(pDictionary, CFSTR(kIOHIDPrimaryUsageKey), pType); CFRelease(pType); } if (nClass != -1) { CFNumberRef pClass = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &nClass); CFDictionarySetValue(pDictionary, CFSTR(kIOHIDPrimaryUsagePageKey), pClass); CFRelease(pClass); } //Now get the maching services io_iterator_t pIterator; if( IOServiceGetMatchingServices(m_pPort, pDictionary, &pIterator) != kIOReturnSuccess ) { wxLogSysError(wxT("No Matching HID Services")); return false; } //Were there any devices matched? if(pIterator == 0) return false; // No devices found //Now we iterate through them io_object_t pObject; while ( (pObject = IOIteratorNext(pIterator)) != 0) { if(--nDev != 0) { IOObjectRelease(pObject); continue; } if ( IORegistryEntryCreateCFProperties ( pObject, &pDictionary, kCFAllocatorDefault, kNilOptions ) != KERN_SUCCESS ) { wxLogDebug(wxT("IORegistryEntryCreateCFProperties failed")); } // // Now we get the attributes of each "product" in the iterator // //Get [product] name CFStringRef cfsProduct = (CFStringRef) CFDictionaryGetValue(pDictionary, CFSTR(kIOHIDProductKey)); m_szProductName = wxCFStringRef( wxCFRetain(cfsProduct) ).AsString(); //Get the Product ID Key CFNumberRef cfnProductId = (CFNumberRef) CFDictionaryGetValue(pDictionary, CFSTR(kIOHIDProductIDKey)); if (cfnProductId) { CFNumberGetValue(cfnProductId, kCFNumberIntType, &m_nProductId); } //Get the Vendor ID Key CFNumberRef cfnVendorId = (CFNumberRef) CFDictionaryGetValue(pDictionary, CFSTR(kIOHIDVendorIDKey)); if (cfnVendorId) { CFNumberGetValue(cfnVendorId, kCFNumberIntType, &m_nManufacturerId); } // // End attribute getting // //Create the interface (good grief - long function names!) SInt32 nScore; IOCFPlugInInterface** ppPlugin; if(IOCreatePlugInInterfaceForService(pObject, kIOHIDDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &ppPlugin, &nScore) != kIOReturnSuccess) { wxLogSysError(wxT("Could not create HID Interface for product")); return false; } //Now, the final thing we can check before we fall back to asserts //(because the dtor only checks if the device is ok, so if anything //fails from now on the dtor will delete the device anyway, so we can't break from this). //Get the HID interface from the plugin to the mach port if((*ppPlugin)->QueryInterface(ppPlugin, CFUUIDGetUUIDBytes(kIOHIDDeviceInterfaceID), (void**) &m_ppDevice) != S_OK) { wxLogSysError(wxT("Could not get device interface from HID interface")); return false; } //release the plugin (*ppPlugin)->Release(ppPlugin); //open the HID interface... if ( (*m_ppDevice)->open(m_ppDevice, 0) != S_OK ) { wxLogDebug(wxT("HID device: open failed")); } // //Now the hard part - in order to scan things we need "cookies" // CFArrayRef cfaCookies = (CFArrayRef)CFDictionaryGetValue(pDictionary, CFSTR(kIOHIDElementKey)); BuildCookies(cfaCookies); //cleanup CFRelease(pDictionary); IOObjectRelease(pObject); //iterator cleanup IOObjectRelease(pIterator); return true; } //iterator cleanup IOObjectRelease(pIterator); return false; //no device }//end Create()
/** * Creates a keyboard cache entry. * * @returns true if the entry was created successfully, otherwise false. * @param pKeyboardEntry Pointer to the entry. * @param KeyboardDevice The keyboard device to create the entry for. * */ static bool darwinHIDKeyboardCacheCreateEntry(struct KeyboardCacheData *pKeyboardEntry, io_object_t KeyboardDevice) { unsigned long cRefs = 0; memset(pKeyboardEntry, 0, sizeof(*pKeyboardEntry)); /* * Query the HIDDeviceInterface for this HID (keyboard) object. */ SInt32 Score = 0; IOCFPlugInInterface **ppPlugInInterface = NULL; IOReturn rc = IOCreatePlugInInterfaceForService(KeyboardDevice, kIOHIDDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &ppPlugInInterface, &Score); if (rc == kIOReturnSuccess) { IOHIDDeviceInterface **ppHidDeviceInterface = NULL; HRESULT hrc = (*ppPlugInInterface)->QueryInterface(ppPlugInInterface, CFUUIDGetUUIDBytes(kIOHIDDeviceInterfaceID), (LPVOID *)&ppHidDeviceInterface); cRefs = (*ppPlugInInterface)->Release(ppPlugInInterface); MY_CHECK_CREFS(cRefs); ppPlugInInterface = NULL; if (hrc == S_OK) { rc = (*ppHidDeviceInterface)->open(ppHidDeviceInterface, 0); if (rc == kIOReturnSuccess) { /* * create a removal callback. */ /** @todo */ /* * Create the queue so we can insert elements while searching the properties. */ IOHIDQueueInterface **ppHidQueueInterface = (*ppHidDeviceInterface)->allocQueue(ppHidDeviceInterface); if (ppHidQueueInterface) { rc = (*ppHidQueueInterface)->create(ppHidQueueInterface, 0, 32); if (rc != kIOReturnSuccess) { AssertMsgFailed(("rc=%d\n", rc)); cRefs = (*ppHidQueueInterface)->Release(ppHidQueueInterface); MY_CHECK_CREFS(cRefs); ppHidQueueInterface = NULL; } } else AssertFailed(); pKeyboardEntry->ppHidQueueInterface = ppHidQueueInterface; /* * Brute force getting of attributes. */ /** @todo read up on how to do this in a less resource intensive way! Suggestions are welcome! */ CFMutableDictionaryRef PropertiesRef = 0; kern_return_t krc = IORegistryEntryCreateCFProperties(KeyboardDevice, &PropertiesRef, kCFAllocatorDefault, kNilOptions); if (krc == KERN_SUCCESS) { darwinBruteForcePropertySearch(PropertiesRef, pKeyboardEntry); CFRelease(PropertiesRef); } else AssertMsgFailed(("krc=%#x\n", krc)); if (ppHidQueueInterface) { /* * Now install our queue callback. */ CFRunLoopSourceRef RunLoopSrcRef = NULL; rc = (*ppHidQueueInterface)->createAsyncEventSource(ppHidQueueInterface, &RunLoopSrcRef); if (rc == kIOReturnSuccess) { CFRunLoopRef RunLoopRef = (CFRunLoopRef)GetCFRunLoopFromEventLoop(GetMainEventLoop()); CFRunLoopAddSource(RunLoopRef, RunLoopSrcRef, kCFRunLoopDefaultMode); } /* * Now install our queue callback. */ rc = (*ppHidQueueInterface)->setEventCallout(ppHidQueueInterface, darwinQueueCallback, ppHidQueueInterface, pKeyboardEntry); if (rc != kIOReturnSuccess) AssertMsgFailed(("rc=%d\n", rc)); } /* * Complete the new keyboard cache entry. */ pKeyboardEntry->ppHidDeviceInterface = ppHidDeviceInterface; pKeyboardEntry->ppHidQueueInterface = ppHidQueueInterface; return true; } AssertMsgFailed(("rc=%d\n", rc)); cRefs = (*ppHidDeviceInterface)->Release(ppHidDeviceInterface); MY_CHECK_CREFS(cRefs); } else AssertMsgFailed(("hrc=%#x\n", hrc)); } else AssertMsgFailed(("rc=%d\n", rc)); return false; }
forensic1394_result platform_update_device_list(forensic1394_bus *bus) { CFMutableDictionaryRef matchingDict; io_iterator_t iterator; io_object_t currdev; IOReturn iret; forensic1394_result fret = FORENSIC1394_RESULT_SUCCESS; // We need to get the systems local device node to update the CSR matchingDict = IOServiceMatching("IOFireWireDevice"); iret = IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDict, &iterator); require_assertion(iret == kIOReturnSuccess, cleanupMatchingServices, fret, FORENSIC1394_RESULT_OTHER_ERROR); while ((currdev = IOIteratorNext(iterator))) { IOCFPlugInInterface **plugIn; SInt32 theScore; UInt32 generation; UInt16 nodeid; // Allocate memory for a forensic1394 device forensic1394_dev *fdev = malloc(sizeof(forensic1394_dev)); // And for the platform specific structure fdev->pdev = malloc(sizeof(platform_dev)); // Copy over the device IO object to the structure fdev->pdev->dev = currdev; // Get an plug-in interface to the device IOCreatePlugInInterfaceForService(currdev, kIOFireWireLibTypeID, kIOCFPlugInInterfaceID, &plugIn, &theScore); // Ensure we got an interface require_assertion(plugIn, cleanupPlugIn, fret, FORENSIC1394_RESULT_OTHER_ERROR); // Use this to get an interface to the firewire device (*plugIn)->QueryInterface(plugIn, CFUUIDGetUUIDBytes(kIOFireWireDeviceInterfaceID_v9), (void **) &fdev->pdev->devIntrf); // Ensure the interface is inited require_assertion((*fdev->pdev->devIntrf)->InterfaceIsInited(fdev->pdev->devIntrf), cleanupDevIntrf, fret, FORENSIC1394_RESULT_OTHER_ERROR); // Save the bus the device is attached to fdev->bus = bus; // The device is not open fdev->is_open = 0; // Copy the ROM copy_device_csr(currdev, fdev->rom); // Parse the ROM to extract useful fragments common_parse_csr(fdev); // Get the bus generation (*fdev->pdev->devIntrf)->GetBusGeneration(fdev->pdev->devIntrf, &generation); // Get the node ID (*fdev->pdev->devIntrf)->GetRemoteNodeID(fdev->pdev->devIntrf, generation, &nodeid); fdev->generation = generation; fdev->node_id = nodeid; // Add this new device to the device list fdev->next = bus->dev_link; bus->dev_link = fdev; bus->ndev++; // Continue; everything from here on in is damage control continue; cleanupDevIntrf: // Release the device interface (*fdev->pdev->devIntrf)->Release(fdev->pdev->devIntrf); cleanupPlugIn: // Release the plug-in interface IODestroyPlugInInterface(plugIn); // Release the IO object IOObjectRelease(fdev->pdev->dev); // Release the partially allocated device free(fdev->pdev); free(fdev); } // Release the iterator IOObjectRelease(iterator); cleanupMatchingServices: return fret; }
kern_return_t IOCreatePlugInInterfaceForService(io_service_t service, CFUUIDRef pluginType, CFUUIDRef interfaceType, IOCFPlugInInterface *** theInterface, SInt32 * theScore) { CFDictionaryRef plist = 0; CFArrayRef plists; CFArrayRef factories; CFMutableArrayRef candidates; CFMutableArrayRef scores; CFIndex index; CFIndex insert; CFUUIDRef factoryID; kern_return_t kr; SInt32 score; IOCFPlugInInterface ** interface; Boolean haveOne; kr = IOFindPlugIns( service, pluginType, &factories, &plists ); if( KERN_SUCCESS != kr) { if (factories) CFRelease(factories); if (plists) CFRelease(plists); return( kr ); } if ((KERN_SUCCESS != kr) || (factories == NULL) || (0 == CFArrayGetCount(factories))) { // printf("No factories for type\n"); if (factories) CFRelease(factories); if (plists) CFRelease(plists); return( kIOReturnUnsupported ); } candidates = CFArrayCreateMutable(kCFAllocatorDefault, 0, NULL); scores = CFArrayCreateMutable(kCFAllocatorDefault, 0, NULL); // allocate and Probe all if (candidates && scores) { CFIndex numfactories = CFArrayGetCount(factories); for ( index = 0; index < numfactories; index++ ) { IUnknownVTbl ** iunknown; factoryID = (CFUUIDRef) CFArrayGetValueAtIndex(factories, index); iunknown = (IUnknownVTbl **) CFPlugInInstanceCreate(NULL, factoryID, pluginType); if (!iunknown) { // printf("Failed to create instance (link error?)\n"); continue; } (*iunknown)->QueryInterface(iunknown, CFUUIDGetUUIDBytes(interfaceType), (LPVOID *)&interface); // Now we are done with IUnknown interface (*iunknown)->Release(iunknown); if (!interface) { // printf("Failed to get interface.\n"); continue; } if (plists) plist = (CFDictionaryRef) CFArrayGetValueAtIndex( plists, index ); score = 0; // from property table kr = (*interface)->Probe(interface, plist, service, &score); if (kIOReturnSuccess == kr) { CFIndex numscores = CFArrayGetCount(scores); for (insert = 0; insert < numscores; insert++) { if (score > (SInt32) ((intptr_t) CFArrayGetValueAtIndex(scores, insert))) break; } CFArrayInsertValueAtIndex(candidates, insert, (void *) interface); CFArrayInsertValueAtIndex(scores, insert, (void *) (intptr_t) score); } else (*interface)->Release(interface); } } // Start in score order CFIndex candidatecount = CFArrayGetCount(candidates); for (haveOne = false, index = 0; index < candidatecount; index++) { Boolean freeIt; if (plists) plist = (CFDictionaryRef) CFArrayGetValueAtIndex(plists, index ); interface = (IOCFPlugInInterface **) CFArrayGetValueAtIndex(candidates, index ); if (!haveOne) { haveOne = (kIOReturnSuccess == (*interface)->Start(interface, plist, service)); freeIt = !haveOne; if (haveOne) { *theInterface = interface; *theScore = (SInt32) (intptr_t) CFArrayGetValueAtIndex(scores, index ); } } else freeIt = true; if (freeIt) (*interface)->Release(interface); } if (factories) CFRelease(factories); if (plists) CFRelease(plists); if (candidates) CFRelease(candidates); if (scores) CFRelease(scores); // CFRelease(plugin); return (haveOne ? kIOReturnSuccess : kIOReturnNoResources); }
void UPSDeviceAdded(void *refCon, io_iterator_t iterator) { io_object_t upsDevice = MACH_PORT_NULL; UPSDataRef upsDataRef = NULL; CFDictionaryRef upsProperties = NULL; CFDictionaryRef upsEvent = NULL; CFSetRef upsCapabilites = NULL; CFRunLoopSourceRef upsEventSource = NULL; CFRunLoopTimerRef upsEventTimer = NULL; CFTypeRef typeRef = NULL; IOCFPlugInInterface ** plugInInterface = NULL; IOUPSPlugInInterface_v140 ** upsPlugInInterface = NULL; HRESULT result = S_FALSE; IOReturn kr; SInt32 score; while ( (upsDevice = IOIteratorNext(iterator)) ) { // Create the CF plugin for this device kr = IOCreatePlugInInterfaceForService(upsDevice, kIOUPSPlugInTypeID, kIOCFPlugInInterfaceID, &plugInInterface, &score); if ( kr != kIOReturnSuccess ) goto UPSDEVICEADDED_NONPLUGIN_CLEANUP; // Grab the new v140 interface result = (*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(kIOUPSPlugInInterfaceID_v140), (LPVOID)&upsPlugInInterface); if ( ( result == S_OK ) && upsPlugInInterface ) { kr = (*upsPlugInInterface)->createAsyncEventSource(upsPlugInInterface, &typeRef); if ((kr != kIOReturnSuccess) || !typeRef) goto UPSDEVICEADDED_FAIL; if ( CFGetTypeID(typeRef) == CFRunLoopTimerGetTypeID() ) { upsEventTimer = (CFRunLoopTimerRef)typeRef; CFRunLoopAddTimer(CFRunLoopGetCurrent(), upsEventTimer, kCFRunLoopDefaultMode); } else if ( CFGetTypeID(typeRef) == CFRunLoopSourceGetTypeID() ) { upsEventSource = (CFRunLoopSourceRef)typeRef; CFRunLoopAddSource(CFRunLoopGetCurrent(), upsEventSource, kCFRunLoopDefaultMode); } } // Couldn't grab the new interface. Fallback on the old. else { result = (*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(kIOUPSPlugInInterfaceID), (LPVOID)&upsPlugInInterface); } // Got the interface if ( ( result == S_OK ) && upsPlugInInterface ) { kr = (*upsPlugInInterface)->getProperties(upsPlugInInterface, &upsProperties); if (kr != kIOReturnSuccess) goto UPSDEVICEADDED_FAIL; upsDataRef = GetPrivateData(upsProperties); if ( !upsDataRef ) goto UPSDEVICEADDED_FAIL; upsDataRef->upsPlugInInterface = (IOUPSPlugInInterface **)upsPlugInInterface; upsDataRef->upsEventSource = upsEventSource; upsDataRef->upsEventTimer = upsEventTimer; upsDataRef->isPresent = true; kr = (*upsPlugInInterface)->getCapabilities(upsPlugInInterface, &upsCapabilites); if (kr != kIOReturnSuccess) goto UPSDEVICEADDED_FAIL; kr = CreatePowerManagerUPSEntry(upsDataRef, upsProperties, upsCapabilites); if (kr != kIOReturnSuccess) goto UPSDEVICEADDED_FAIL; kr = (*upsPlugInInterface)->getEvent(upsPlugInInterface, &upsEvent); if (kr != kIOReturnSuccess) goto UPSDEVICEADDED_FAIL; ProcessUPSEvent(upsDataRef, upsEvent); (*upsPlugInInterface)->setEventCallback(upsPlugInInterface, UPSEventCallback, NULL, upsDataRef); IOServiceAddInterestNotification( gNotifyPort, // notifyPort upsDevice, // service kIOGeneralInterest, // interestType DeviceNotification, // callback upsDataRef, // refCon &(upsDataRef->notification) // notification ); goto UPSDEVICEADDED_CLEANUP; } UPSDEVICEADDED_FAIL: // Failed to allocated a UPS interface. Do some cleanup if ( upsPlugInInterface ) { (*upsPlugInInterface)->Release(upsPlugInInterface); upsPlugInInterface = NULL; } if ( upsEventSource ) { CFRunLoopRemoveSource(CFRunLoopGetCurrent(), upsEventSource, kCFRunLoopDefaultMode); upsEventSource = NULL; } if ( upsEventTimer ) { CFRunLoopRemoveTimer(CFRunLoopGetCurrent(), upsEventTimer, kCFRunLoopDefaultMode); upsEventSource = NULL; } UPSDEVICEADDED_CLEANUP: // Clean up (*plugInInterface)->Release(plugInInterface); UPSDEVICEADDED_NONPLUGIN_CLEANUP: IOObjectRelease(upsDevice); } }
/** Try out the given device and see if there's a match. Returns 0 on * success, -1 on failure. */ static int try_device(io_service_t device, usb_handle *handle) { kern_return_t kr; IOCFPlugInInterface **plugin = NULL; IOUSBDeviceInterface500** dev = NULL; SInt32 score; HRESULT result; UInt8 serialIndex; UInt32 locationId; // Create an intermediate plugin. kr = IOCreatePlugInInterfaceForService(device, kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &plugin, &score); if ((kr != 0) || (plugin == NULL)) { goto error; } // Now create the device interface. result = (*plugin)->QueryInterface(plugin, CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID500), (LPVOID*)&dev); if ((result != 0) || (dev == NULL)) { ERR("Couldn't create a device interface (%08x)\n", (int) result); goto error; } /* * We don't need the intermediate interface after the device interface * is created. */ IODestroyPlugInInterface(plugin); // So, we have a device, finally. Grab its vitals. kr = (*dev)->GetDeviceVendor(dev, &handle->info.dev_vendor); if (kr != 0) { ERR("GetDeviceVendor"); goto error; } kr = (*dev)->GetDeviceProduct(dev, &handle->info.dev_product); if (kr != 0) { ERR("GetDeviceProduct"); goto error; } kr = (*dev)->GetDeviceClass(dev, &handle->info.dev_class); if (kr != 0) { ERR("GetDeviceClass"); goto error; } kr = (*dev)->GetDeviceSubClass(dev, &handle->info.dev_subclass); if (kr != 0) { ERR("GetDeviceSubClass"); goto error; } kr = (*dev)->GetDeviceProtocol(dev, &handle->info.dev_protocol); if (kr != 0) { ERR("GetDeviceProtocol"); goto error; } kr = (*dev)->GetLocationID(dev, &locationId); if (kr != 0) { ERR("GetLocationId"); goto error; } snprintf(handle->info.device_path, sizeof(handle->info.device_path), "usb:%" PRIu32 "X", (unsigned int)locationId); kr = (*dev)->USBGetSerialNumberStringIndex(dev, &serialIndex); if (serialIndex > 0) { IOUSBDevRequest req; UInt16 buffer[256]; req.bmRequestType = USBmakebmRequestType(kUSBIn, kUSBStandard, kUSBDevice); req.bRequest = kUSBRqGetDescriptor; req.wValue = (kUSBStringDesc << 8) | serialIndex; //language ID (en-us) for serial number string req.wIndex = 0x0409; req.pData = buffer; req.wLength = sizeof(buffer); kr = (*dev)->DeviceRequest(dev, &req); if (kr == kIOReturnSuccess && req.wLenDone > 0) { int i, count; // skip first word, and copy the rest to the serial string, changing shorts to bytes. count = (req.wLenDone - 1) / 2; for (i = 0; i < count; i++) handle->info.serial_number[i] = buffer[i + 1]; handle->info.serial_number[i] = 0; } } else { // device has no serial number handle->info.serial_number[0] = 0; } handle->info.writable = 1; if (try_interfaces(dev, handle)) { goto error; } (*dev)->Release(dev); return 0; error: if (dev != NULL) { (*dev)->Release(dev); } return -1; }
static void AndroidInterfaceAdded(void *refCon, io_iterator_t iterator) { kern_return_t kr; io_service_t usbDevice; io_service_t usbInterface; IOCFPlugInInterface **plugInInterface = NULL; IOUSBInterfaceInterface220 **iface = NULL; IOUSBDeviceInterface197 **dev = NULL; HRESULT result; SInt32 score; UInt32 locationId; UInt16 vendor; UInt16 product; UInt8 serialIndex; char serial[256]; char devpathBuf[64]; char *devpath = NULL; while ((usbInterface = IOIteratorNext(iterator))) { //* Create an intermediate interface plugin kr = IOCreatePlugInInterfaceForService(usbInterface, kIOUSBInterfaceUserClientTypeID, kIOCFPlugInInterfaceID, &plugInInterface, &score); IOObjectRelease(usbInterface); if ((kIOReturnSuccess != kr) || (!plugInInterface)) { DBG("ERR: Unable to create an interface plug-in (%08x)\n", kr); continue; } //* This gets us the interface object result = (*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(kIOUSBInterfaceInterfaceID), (LPVOID*) &iface); //* We only needed the plugin to get the interface, so discard it (*plugInInterface)->Release(plugInInterface); if (result || !iface) { DBG("ERR: Couldn't query the interface (%08x)\n", (int) result); continue; } //* this gets us an ioservice, with which we will find the actual //* device; after getting a plugin, and querying the interface, of //* course. //* Gotta love OS X kr = (*iface)->GetDevice(iface, &usbDevice); if (kIOReturnSuccess != kr || !usbDevice) { DBG("ERR: Couldn't grab device from interface (%08x)\n", kr); continue; } plugInInterface = NULL; score = 0; //* create an intermediate device plugin kr = IOCreatePlugInInterfaceForService(usbDevice, kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &plugInInterface, &score); //* only needed this to find the plugin (void)IOObjectRelease(usbDevice); if ((kIOReturnSuccess != kr) || (!plugInInterface)) { DBG("ERR: Unable to create a device plug-in (%08x)\n", kr); continue; } result = (*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID), (LPVOID*) &dev); //* only needed this to query the plugin (*plugInInterface)->Release(plugInInterface); if (result || !dev) { DBG("ERR: Couldn't create a device interface (%08x)\n", (int) result); continue; } //* Now after all that, we actually have a ref to the device and //* the interface that matched our criteria kr = (*dev)->GetDeviceVendor(dev, &vendor); kr = (*dev)->GetDeviceProduct(dev, &product); kr = (*dev)->GetLocationID(dev, &locationId); if (kr == 0) { snprintf(devpathBuf, sizeof(devpathBuf), "usb:%lX", locationId); devpath = devpathBuf; } kr = (*dev)->USBGetSerialNumberStringIndex(dev, &serialIndex); if (serialIndex > 0) { IOUSBDevRequest req; UInt16 buffer[256]; UInt16 languages[128]; memset(languages, 0, sizeof(languages)); req.bmRequestType = USBmakebmRequestType(kUSBIn, kUSBStandard, kUSBDevice); req.bRequest = kUSBRqGetDescriptor; req.wValue = (kUSBStringDesc << 8) | 0; req.wIndex = 0; req.pData = languages; req.wLength = sizeof(languages); kr = (*dev)->DeviceRequest(dev, &req); if (kr == kIOReturnSuccess && req.wLenDone > 0) { int langCount = (req.wLenDone - 2) / 2, lang; for (lang = 1; lang <= langCount; lang++) { memset(buffer, 0, sizeof(buffer)); memset(&req, 0, sizeof(req)); req.bmRequestType = USBmakebmRequestType(kUSBIn, kUSBStandard, kUSBDevice); req.bRequest = kUSBRqGetDescriptor; req.wValue = (kUSBStringDesc << 8) | serialIndex; req.wIndex = languages[lang]; req.pData = buffer; req.wLength = sizeof(buffer); kr = (*dev)->DeviceRequest(dev, &req); if (kr == kIOReturnSuccess && req.wLenDone > 0) { int i, count; // skip first word, and copy the rest to the serial string, // changing shorts to bytes. count = (req.wLenDone - 1) / 2; for (i = 0; i < count; i++) serial[i] = buffer[i + 1]; serial[i] = 0; break; } } } } (*dev)->Release(dev); DBG("INFO: Found vid=%04x pid=%04x serial=%s\n", vendor, product, serial); usb_handle* handle = CheckInterface((IOUSBInterfaceInterface**)iface, vendor, product); if (handle == NULL) { DBG("ERR: Could not find device interface: %08x\n", kr); (*iface)->Release(iface); continue; } DBG("AndroidDeviceAdded calling register_usb_transport\n"); register_usb_transport(handle, (serial[0] ? serial : NULL), devpath, 1); // Register for an interest notification of this device being removed. // Pass the reference to our private data as the refCon for the // notification. kr = IOServiceAddInterestNotification(notificationPort, usbInterface, kIOGeneralInterest, AndroidInterfaceNotify, handle, &handle->usbNotification); if (kIOReturnSuccess != kr) { DBG("ERR: Unable to create interest notification (%08x)\n", kr); } } }
//================================================================================================ // // DeviceAdded // // This routine is the callback for our IOServiceAddMatchingNotification. When we get called // we will look at all the devices that were added and we will: // // 1. Create some private data to relate to each device (in this case we use the service's name // and the location ID of the device // 2. Submit an IOServiceAddInterestNotification of type kIOGeneralInterest for this device, // using the refCon field to store a pointer to our private data. When we get called with // this interest notification, we can grab the refCon and access our private data. // //================================================================================================ static void DeviceAdded(void *refCon, io_iterator_t iterator) { kern_return_t kr; io_service_t usbDevice; IOCFPlugInInterface **plugInInterface = NULL; SInt32 score; HRESULT res; while((usbDevice = IOIteratorNext(iterator))) { io_name_t deviceName; CFStringRef deviceNameAsCFString; UInt32 locationID; UInt16 vendorId; UInt16 productId; UInt16 addr; DeviceItem_t* deviceItem = new DeviceItem_t(); // Get the USB device's name. kr = IORegistryEntryGetName(usbDevice, deviceName); if(KERN_SUCCESS != kr) { deviceName[0] = '\0'; } deviceNameAsCFString = CFStringCreateWithCString(kCFAllocatorDefault, deviceName, kCFStringEncodingASCII); if(deviceNameAsCFString) { Boolean result; char deviceName[MAXPATHLEN]; // Convert from a CFString to a C (NUL-terminated) result = CFStringGetCString(deviceNameAsCFString, deviceName, sizeof(deviceName), kCFStringEncodingUTF8); if(result) { deviceItem->deviceParams.deviceName = deviceName; } CFRelease(deviceNameAsCFString); } CFStringRef manufacturerAsCFString = (CFStringRef)IORegistryEntrySearchCFProperty( usbDevice, kIOServicePlane, CFSTR(kUSBVendorString), kCFAllocatorDefault, kIORegistryIterateRecursively ); if(manufacturerAsCFString) { Boolean result; char manufacturer[MAXPATHLEN]; // Convert from a CFString to a C (NUL-terminated) result = CFStringGetCString( manufacturerAsCFString, manufacturer, sizeof(manufacturer), kCFStringEncodingUTF8 ); if(result) { deviceItem->deviceParams.manufacturer = manufacturer; } CFRelease(manufacturerAsCFString); } CFStringRef serialNumberAsCFString = (CFStringRef) IORegistryEntrySearchCFProperty( usbDevice, kIOServicePlane, CFSTR(kUSBSerialNumberString), kCFAllocatorDefault, kIORegistryIterateRecursively ); if(serialNumberAsCFString) { Boolean result; char serialNumber[MAXPATHLEN]; // Convert from a CFString to a C (NUL-terminated) result = CFStringGetCString( serialNumberAsCFString, serialNumber, sizeof(serialNumber), kCFStringEncodingUTF8 ); if(result) { deviceItem->deviceParams.serialNumber = serialNumber; } CFRelease(serialNumberAsCFString); } // Now, get the locationID of this device. In order to do this, we need to create an IOUSBDeviceInterface // for our device. This will create the necessary connections between our userland application and the // kernel object for the USB Device. kr = IOCreatePlugInInterfaceForService(usbDevice, kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &plugInInterface, &score); if((kIOReturnSuccess != kr) || !plugInInterface) { fprintf(stderr, "IOCreatePlugInInterfaceForService returned 0x%08x.\n", kr); continue; } stDeviceListItem *deviceListItem = new stDeviceListItem(); // Use the plugin interface to retrieve the device interface. res = (*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID), (LPVOID*) &deviceListItem->deviceInterface); // Now done with the plugin interface. (*plugInInterface)->Release(plugInInterface); if(res || deviceListItem->deviceInterface == NULL) { fprintf(stderr, "QueryInterface returned %d.\n", (int) res); continue; } // Now that we have the IOUSBDeviceInterface, we can call the routines in IOUSBLib.h. // In this case, fetch the locationID. The locationID uniquely identifies the device // and will remain the same, even across reboots, so long as the bus topology doesn't change. kr = (*deviceListItem->deviceInterface)->GetLocationID(deviceListItem->deviceInterface, &locationID); if(KERN_SUCCESS != kr) { fprintf(stderr, "GetLocationID returned 0x%08x.\n", kr); continue; } std::stringstream sstream; sstream << std::hex << locationID; deviceItem->deviceParams.locationId = sstream.str(); kr = (*deviceListItem->deviceInterface)->GetDeviceAddress(deviceListItem->deviceInterface, &addr); if(KERN_SUCCESS != kr) { fprintf(stderr, "GetDeviceAddress returned 0x%08x.\n", kr); continue; } deviceItem->deviceParams.deviceAddress = addr; kr = (*deviceListItem->deviceInterface)->GetDeviceVendor(deviceListItem->deviceInterface, &vendorId); if(KERN_SUCCESS != kr) { fprintf(stderr, "GetDeviceVendor returned 0x%08x.\n", kr); continue; } deviceItem->deviceParams.vendorId = vendorId; kr = (*deviceListItem->deviceInterface)->GetDeviceProduct(deviceListItem->deviceInterface, &productId); if(KERN_SUCCESS != kr) { fprintf(stderr, "GetDeviceProduct returned 0x%08x.\n", kr); continue; } deviceItem->deviceParams.productId = productId; // Extract path name as unique key io_string_t pathName; IORegistryEntryGetPath(usbDevice, kIOServicePlane, pathName); deviceNameAsCFString = CFStringCreateWithCString(kCFAllocatorDefault, pathName, kCFStringEncodingASCII); char cPathName[MAXPATHLEN]; if(deviceNameAsCFString) { Boolean result; // Convert from a CFString to a C (NUL-terminated) result = CFStringGetCString( deviceNameAsCFString, cPathName, sizeof(cPathName), kCFStringEncodingUTF8 ); CFRelease(deviceNameAsCFString); } AddItemToList(cPathName, deviceItem); deviceListItem->deviceItem = deviceItem; if(initialDeviceImport == false) { WaitForDeviceHandled(); currentItem = &deviceItem->deviceParams; isAdded = true; uv_async_send(&async_handler); } // Register for an interest notification of this device being removed. Use a reference to our // private data as the refCon which will be passed to the notification callback. kr = IOServiceAddInterestNotification( gNotifyPort, // notifyPort usbDevice, // service kIOGeneralInterest, // interestType DeviceRemoved, // callback deviceListItem, // refCon &(deviceListItem->notification) // notification ); if(KERN_SUCCESS != kr) { printf("IOServiceAddInterestNotification returned 0x%08x.\n", kr); } // Done with this USB device; release the reference added by IOIteratorNext kr = IOObjectRelease(usbDevice); } }
void interfaceInteraction(IOUSBInterfaceInterface300*** intfPtr, io_service_t Ref) { IOCFPlugInInterface **iodev; SInt32 score; IOReturn err; UInt8 interfaceClass, direction, number, transfertype, interval; UInt8 interfaceSubClass, interfaceNumEndpoints, interfaceNumber; UInt16 maxPacketSize; int pipeRef = 1; char *message; err = IOCreatePlugInInterfaceForService(Ref, kIOUSBInterfaceUserClientTypeID, kIOCFPlugInInterfaceID, &iodev, &score); IO_ERR(3, "openInterface: Create Plugin Interface for usbInterface", err); //query plugin for device interface err = (*iodev)->QueryInterface(iodev, CFUUIDGetUUIDBytes(kIOUSBInterfaceInterfaceID300), (LPVOID)intfPtr); IO_ERR(3, "openInterface: Query Plugin for Device Interface", err); err = (**intfPtr)->GetInterfaceNumber(*intfPtr, &interfaceNumber); IO_ERR(3, "openInterface: Get Interface Number", err); //NSLog(@"Interface Number: %d", interfaceNumber); //err = (**intfPtr)->GetPipeStatus(*intfPtr); //ERR(self.usbDebug, "openInterface: Pipe Status", err); err = (**intfPtr)->USBInterfaceOpen(*intfPtr); IO_ERR(3, "openInterface: Open Interface port", err); err = (**intfPtr)->GetInterfaceClass(*intfPtr, &interfaceClass); err = (**intfPtr)->GetInterfaceSubClass(*intfPtr, &interfaceSubClass); //NSLog(@"OpenInterface: interface Class:%d Interface Sub Class:%d", interfaceClass, interfaceSubClass); err = (**intfPtr)->GetNumEndpoints(*intfPtr, &interfaceNumEndpoints); //NSLog(@"OpenInterface: Number of Endpoints is:%d", interfaceNumEndpoints); for(pipeRef = 1; pipeRef <= interfaceNumEndpoints; pipeRef++) { err = (**intfPtr)->GetPipeProperties(*intfPtr, pipeRef, &direction, &number, &transfertype, &maxPacketSize, &interval); IO_ERR(3, "openInterface: Get Pipe Properties",err); printf("Pipe Reference number:%d, ", pipeRef); switch (direction) { case kUSBOut: message = "out"; break; case kUSBIn: message = "in"; break; case kUSBNone: message = "none"; break; case kUSBAnyDirn: message = "any"; break; default: message = "???"; break; } printf("direction:%s, ", message); switch (transfertype) { case kUSBControl: message = "control"; break; case kUSBIsoc: message = "isoc"; break; case kUSBBulk: message = "bulk"; break; case kUSBInterrupt: message = "interrupt"; break; case kUSBAnyType: message = "any"; break; default: message = "???"; break; } printf("transfer type:%s, Pipe Number:%d maxPacketSize:%d, Intervals:%d\n", message, number, maxPacketSize,interval); if (transfertype == kUSBBulk && direction == kUSBIn) { //alarmInPipeRef = number; }else if (transfertype == kUSBBulk && direction == kUSBOut) { //alarmOutPipeRef = number; } } (*iodev)->Release(iodev); }
int ipod_scsi_inquiry(struct ipod_t* ipod, int page_code, unsigned char* buf, int bufsize) { /* OS X doesn't allow to simply send out a SCSI inquiry request but * requires registering an interface handler first. * Currently this is done on each inquiry request which is somewhat * inefficient but the current ipodpatcher API doesn't really fit here. * Based on the documentation in Apple's document * "SCSI Architecture Model Device Interface Guide". * * WARNING: this code currently doesn't take the selected device into * account. It simply looks for an Ipod on the system and uses * the first match. */ (void)ipod; int result = 0; /* first, create a dictionary to match the device. This is needed to get the * service. */ CFMutableDictionaryRef match_dict; match_dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, NULL, NULL); if(match_dict == NULL) return -1; /* set value to match. In case of the Ipod this is "iPodUserClientDevice". */ CFMutableDictionaryRef sub_dict; sub_dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, NULL, NULL); CFDictionarySetValue(sub_dict, CFSTR(kIOPropertySCSITaskDeviceCategory), CFSTR("iPodUserClientDevice")); CFDictionarySetValue(match_dict, CFSTR(kIOPropertyMatchKey), sub_dict); if(sub_dict == NULL) return -1; /* get an iterator for searching for the service. */ kern_return_t kr; io_iterator_t iterator = IO_OBJECT_NULL; /* get matching services from IO registry. Consumes one reference to * the dictionary, so no need to release that. */ kr = IOServiceGetMatchingServices(kIOMasterPortDefault, match_dict, &iterator); if(!iterator | (kr != kIOReturnSuccess)) return -1; /* get interface and obtain exclusive access */ SInt32 score; HRESULT herr; kern_return_t err; IOCFPlugInInterface **plugin_interface = NULL; SCSITaskDeviceInterface **interface = NULL; io_service_t device = IO_OBJECT_NULL; device = IOIteratorNext(iterator); err = IOCreatePlugInInterfaceForService(device, kIOSCSITaskDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &plugin_interface, &score); if(err != noErr) { return -1; } /* query the plugin interface for task interface */ herr = (*plugin_interface)->QueryInterface(plugin_interface, CFUUIDGetUUIDBytes(kIOSCSITaskDeviceInterfaceID), (LPVOID*)&interface); if(herr != S_OK) { IODestroyPlugInInterface(plugin_interface); return -1; } err = (*interface)->ObtainExclusiveAccess(interface); if(err != noErr) { (*interface)->Release(interface); IODestroyPlugInInterface(plugin_interface); return -1; } /* do the inquiry */ SCSITaskInterface **task = NULL; task = (*interface)->CreateSCSITask(interface); if(task != NULL) { kern_return_t err; SCSITaskStatus task_status; IOVirtualRange* range; SCSI_Sense_Data sense_data; SCSICommandDescriptorBlock cdb; UInt64 transfer_count = 0; memset(buf, 0, bufsize); /* allocate virtual range for buffer. */ range = (IOVirtualRange*) malloc(sizeof(IOVirtualRange)); memset(&sense_data, 0, sizeof(sense_data)); memset(cdb, 0, sizeof(cdb)); /* set up range. address is buffer address, length is request size. */ range->address = (IOVirtualAddress)buf; range->length = bufsize; /* setup CDB */ cdb[0] = 0x12; /* inquiry */ cdb[1] = 1; cdb[2] = page_code; cdb[4] = bufsize; /* set cdb in task */ err = (*task)->SetCommandDescriptorBlock(task, cdb, kSCSICDBSize_6Byte); if(err != kIOReturnSuccess) { result = -1; goto cleanup; } err = (*task)->SetScatterGatherEntries(task, range, 1, bufsize, kSCSIDataTransfer_FromTargetToInitiator); if(err != kIOReturnSuccess) { result = -1; goto cleanup; } /* set timeout */ err = (*task)->SetTimeoutDuration(task, 10000); if(err != kIOReturnSuccess) { result = -1; goto cleanup; } /* request data */ err = (*task)->ExecuteTaskSync(task, &sense_data, &task_status, &transfer_count); if(err != kIOReturnSuccess) { result = -1; goto cleanup; } /* cleanup */ free(range); /* release task interface */ (*task)->Release(task); } else { result = -1; } cleanup: /* cleanup interface */ (*interface)->ReleaseExclusiveAccess(interface); (*interface)->Release(interface); IODestroyPlugInInterface(plugin_interface); return result; }
void BulkTestDeviceAdded(void *refCon, io_iterator_t iterator) { kern_return_t kr; io_service_t usbDevice; IOCFPlugInInterface **plugInInterface=NULL; IOUSBDeviceInterface245 **dev=NULL; HRESULT res; SInt32 score; UInt16 vendor; UInt16 product; UInt16 release; while ( (usbDevice = IOIteratorNext(iterator)) ) { printf("Bulk test device added.\n"); kr = IOCreatePlugInInterfaceForService(usbDevice, kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &plugInInterface, &score); kr = IOObjectRelease(usbDevice); // done with the device object now that I have the plugin if ((kIOReturnSuccess != kr) || !plugInInterface) { printf("unable to create a plugin (%08x)\n", kr); continue; } // I have the device plugin, I need the device interface res = (*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID245), (LPVOID)&dev); IODestroyPlugInInterface(plugInInterface); // done with this if (res || !dev) { printf("couldn't create a device interface (%08x)\n", (int) res); continue; } // technically should check these kr values kr = (*dev)->GetDeviceVendor(dev, &vendor); kr = (*dev)->GetDeviceProduct(dev, &product); kr = (*dev)->GetDeviceReleaseNumber(dev, &release); if ((vendor != kOurVendorID) || (product != kOurProductIDBulkTest) || (release != 1)) { // We should never get here because the matching criteria we specified above // will return just those devices with our vendor and product IDs printf("found device i didn't want (vendor = %d, product = %d)\n", vendor, product); (*dev)->Release(dev); continue; } // need to open the device in order to change its state kr = (*dev)->USBDeviceOpen(dev); if (kIOReturnSuccess != kr) { printf("unable to open device: %08x\n", kr); (*dev)->Release(dev); continue; } kr = ConfigureAnchorDevice(dev); if (kIOReturnSuccess != kr) { printf("unable to configure device: %08x\n", kr); (*dev)->USBDeviceClose(dev); (*dev)->Release(dev); continue; } kr = FindInterfaces(dev); if (kIOReturnSuccess != kr) { printf("unable to find interfaces on device: %08x\n", kr); (*dev)->USBDeviceClose(dev); (*dev)->Release(dev); continue; } #ifndef USE_ASYNC_IO kr = (*dev)->USBDeviceClose(dev); kr = (*dev)->Release(dev); #endif } }
drives_s* drives_available(){ CFMutableDictionaryRef main_dict = NULL; CFMutableDictionaryRef sec_dict = NULL; io_iterator_t itt = IO_OBJECT_NULL; io_name_t cls_name; io_service_t sd = IO_OBJECT_NULL; IOCFPlugInInterface **plg_in_intf = NULL; SCSITaskDeviceInterface **dev_intf = NULL; MMCDeviceInterface **mmc_intf = NULL; SInt32 score = 0; int count; int ret = 1; drive_s* d = 0; drives_s* dd = 0; if((main_dict = CFDictionaryCreateMutable(kCFAllocatorDefault,0,&kCFTypeDictionaryKeyCallBacks,&kCFTypeDictionaryValueCallBacks)) != NULL){ if((sec_dict = CFDictionaryCreateMutable(kCFAllocatorDefault,0,&kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)) != NULL){ CFDictionarySetValue(sec_dict,CFSTR(kIOPropertySCSITaskDeviceCategory),CFSTR(kIOPropertySCSITaskAuthoringDevice)); CFDictionarySetValue(main_dict,CFSTR(kIOPropertyMatchKey),sec_dict); CFRelease(sec_dict); } } if(IOServiceGetMatchingServices(kIOMasterPortDefault,main_dict,&itt)){ printf("no matching services\n"); return 0; } count = 0; while((sd = IOIteratorNext(itt))) { if(!IOObjectGetClass(sd,cls_name)){ if(!IOCreatePlugInInterfaceForService(sd,kIOMMCDeviceUserClientTypeID,kIOCFPlugInInterfaceID,&plg_in_intf,&score) && !(*plg_in_intf)->QueryInterface(plg_in_intf,CFUUIDGetUUIDBytes(kIOMMCDeviceInterfaceID),(LPVOID*)&mmc_intf)) { dev_intf = (*mmc_intf)->GetSCSITaskDeviceInterface(mmc_intf); if(dev_intf){ drive_data_s dd; dd.mmc_intf = mmc_intf; dd.plg_in_intf = plg_in_intf; dd.itt = itt; dd.dev_intf = dev_intf; if(drive_type((int)&dd) == T_CDROM){ inquiry_s* inq; count++; d = (drive_s*)realloc(d,count*sizeof(drive_s)); inq = drive_inquiry((int)&dd); memcpy(&d[count-1].name,inq->p_id,sizeof(inq->p_id)); d[count-1].id = count; free(inq); } } } if(IOObjectRelease(sd)) ret = 0; } if(mmc_intf != NULL)(*mmc_intf)->Release(mmc_intf); if(plg_in_intf != NULL)IODestroyPlugInInterface(plg_in_intf); } IOObjectRelease(itt); dd = (drives_s*)malloc(sizeof(drives_s)); if(dd){ dd->drives = d; dd->number = count; }else{ free(d); return 0; } if(ret) return dd; else return 0; }
static stDeviceListItem* GetSerialDevices() { char bsdPath[MAXPATHLEN]; io_iterator_t serialPortIterator; FindModems(&serialPortIterator); kern_return_t kernResult = KERN_FAILURE; Boolean modemFound = false; // Initialize the returned path *bsdPath = '\0'; stDeviceListItem* devices = NULL; stDeviceListItem* lastDevice = NULL; int length = 0; io_service_t modemService; while ((modemService = IOIteratorNext(serialPortIterator))) { CFTypeRef bsdPathAsCFString; bsdPathAsCFString = IORegistryEntrySearchCFProperty( modemService, kIOServicePlane, CFSTR(kIODialinDeviceKey), kCFAllocatorDefault, kIORegistryIterateRecursively); if (bsdPathAsCFString) { Boolean result; // Convert the path from a CFString to a C (NUL-terminated) result = CFStringGetCString((CFStringRef) bsdPathAsCFString, bsdPath, sizeof(bsdPath), kCFStringEncodingUTF8); CFRelease(bsdPathAsCFString); if (result) { stDeviceListItem *deviceListItem = reinterpret_cast<stDeviceListItem*>( malloc(sizeof(stDeviceListItem))); stSerialDevice *serialDevice = &(deviceListItem->value); snprintf(serialDevice->port, sizeof(serialDevice->port), "%s", bsdPath); memset(serialDevice->locationId, 0, sizeof(serialDevice->locationId)); memset(serialDevice->vendorId, 0, sizeof(serialDevice->vendorId)); memset(serialDevice->productId, 0, sizeof(serialDevice->productId)); serialDevice->manufacturer[0] = '\0'; serialDevice->serialNumber[0] = '\0'; deviceListItem->next = NULL; deviceListItem->length = &length; if (devices == NULL) { devices = deviceListItem; } else { lastDevice->next = deviceListItem; } lastDevice = deviceListItem; length++; modemFound = true; kernResult = KERN_SUCCESS; uv_mutex_lock(&list_mutex); io_service_t device = GetUsbDevice(modemService); if (device) { CFStringRef manufacturerAsCFString = (CFStringRef) IORegistryEntryCreateCFProperty(device, CFSTR(kUSBVendorString), kCFAllocatorDefault, 0); if (manufacturerAsCFString) { Boolean result; char manufacturer[MAXPATHLEN]; // Convert from a CFString to a C (NUL-terminated) result = CFStringGetCString(manufacturerAsCFString, manufacturer, sizeof(manufacturer), kCFStringEncodingUTF8); if (result) { snprintf(serialDevice->manufacturer, sizeof(serialDevice->manufacturer), "%s", manufacturer); } CFRelease(manufacturerAsCFString); } CFStringRef serialNumberAsCFString = (CFStringRef) IORegistryEntrySearchCFProperty(device, kIOServicePlane, CFSTR(kUSBSerialNumberString), kCFAllocatorDefault, kIORegistryIterateRecursively); if (serialNumberAsCFString) { Boolean result; char serialNumber[MAXPATHLEN]; // Convert from a CFString to a C (NUL-terminated) result = CFStringGetCString(serialNumberAsCFString, serialNumber, sizeof(serialNumber), kCFStringEncodingUTF8); if (result) { snprintf(serialDevice->serialNumber, sizeof(serialDevice->serialNumber), "%s", serialNumber); } CFRelease(serialNumberAsCFString); } IOCFPlugInInterface **plugInInterface = NULL; SInt32 score; HRESULT res; IOUSBDeviceInterface **deviceInterface = NULL; kernResult = IOCreatePlugInInterfaceForService(device, kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &plugInInterface, &score); if ((kIOReturnSuccess != kernResult) || !plugInInterface) { continue; } // Use the plugin interface to retrieve the device interface. res = (*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID), reinterpret_cast<LPVOID*> (&deviceInterface)); // Now done with the plugin interface. (*plugInInterface)->Release(plugInInterface); if (res || deviceInterface == NULL) { continue; } // Extract the desired Information ExtractUsbInformation(serialDevice, deviceInterface); // Release the Interface (*deviceInterface)->Release(deviceInterface); // Release the device (void) IOObjectRelease(device); } uv_mutex_unlock(&list_mutex); } } // Release the io_service_t now that we are done with it. (void) IOObjectRelease(modemService); } IOObjectRelease(serialPortIterator); // Release the iterator. return devices; }
/** * USB オープン * @param[in] vid VID * @param[in] pid PID * @retval true 成功 * @retval false 失敗 */ bool CUsbDev::Open(unsigned int vid, unsigned int pid) { // 探すデバイス const SInt32 usbVendor = vid; const SInt32 usbProduct = pid; // Set up matching dictionary for class IOUSBDevice and its subclasses CFMutableDictionaryRef matchingDict = IOServiceMatching(kIOUSBDeviceClassName); if (matchingDict == NULL) { printf("Couldn't create a USB matching dictionary\n"); return false; } // Add the vendor and product IDs to the matching dictionary. // This is the second key in the table of device-matching keys of the // USB Common Class Specification CFDictionarySetValue(matchingDict, CFSTR(kUSBVendorName), CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &usbVendor)); CFDictionarySetValue(matchingDict, CFSTR(kUSBProductName), CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &usbProduct)); // インタフェイスを得る io_iterator_t iterator = 0; IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDict, &iterator); io_service_t usbDevice = IOIteratorNext(iterator); if (usbDevice == 0) { printf("Device not found\n"); return false; } IOObjectRelease(iterator); // Create an intermediate plug-in IOCFPlugInInterface** plugInInterface = NULL; SInt32 score = 0; IOReturn kr = IOCreatePlugInInterfaceForService(usbDevice, kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &plugInInterface, &score); kr = IOObjectRelease(usbDevice); if ((kr != kIOReturnSuccess) || (plugInInterface == NULL)) { printf("Unable to create a plug-in (%08x)\n", kr); return false; } // Now create the device interface IOUSBDeviceInterface** dev = NULL; HRESULT result = (*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID), (LPVOID*)&dev); (*plugInInterface)->Release(plugInInterface); if ((result != S_OK) || (dev == NULL)) { printf("Couldn't create a device interface (%08x)\n", (int)result); return false; } // Open the device to change its state kr = (*dev)->USBDeviceOpen(dev); if (kr != kIOReturnSuccess) { printf("Unable to open device: %08x\n", kr); (*dev)->Release(dev); return false; } // Configure device kr = ConfigureDevice(dev); if (kr != kIOReturnSuccess) { printf("Unable to configure device: %08x\n", kr); (*dev)->USBDeviceClose(dev); (*dev)->Release(dev); return false; } // Placing the constant kIOUSBFindInterfaceDontCare into the following // fields of the IOUSBFindInterfaceRequest structure will allow you // to find all the interfaces IOUSBFindInterfaceRequest request; request.bInterfaceClass = kIOUSBFindInterfaceDontCare; request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare; request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare; request.bAlternateSetting = kIOUSBFindInterfaceDontCare; // Get an iterator for the interfaces on the device io_iterator_t iterator2; kr = (*dev)->CreateInterfaceIterator(dev, &request, &iterator2); while (1 /*EVER*/) { io_service_t usbInterface = IOIteratorNext(iterator2); if (usbInterface == 0) { break; } // Create an intermediate plug-in IOCFPlugInInterface** plugInInterface = NULL; SInt32 score; kr = IOCreatePlugInInterfaceForService(usbInterface, kIOUSBInterfaceUserClientTypeID, kIOCFPlugInInterfaceID, &plugInInterface, &score); kr = IOObjectRelease(usbInterface); if ((kr != kIOReturnSuccess) || (plugInInterface == NULL)) { printf("Unable to create a plug-in (%08x)\n", kr); continue; } // Now create the device interface for the interface IOUSBInterfaceInterface** interface = NULL; HRESULT result = (*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(kIOUSBInterfaceInterfaceID), (LPVOID*)&interface); (*plugInInterface)->Release(plugInInterface); if ((result != S_OK) || (interface == NULL)) { printf("Couldn't create a device interface for the interface(%08x)\n", (int) result); continue; } // Get interface class and subclass UInt8 interfaceClass; kr = (*interface)->GetInterfaceClass(interface, &interfaceClass); UInt8 interfaceSubClass; kr = (*interface)->GetInterfaceSubClass(interface, &interfaceSubClass); printf("Interface class: %d, subclass: %d\n", interfaceClass, interfaceSubClass); // Now open the interface. This will cause the pipes associated with // the endpoints in the interface descriptor to be instantiated kr = (*interface)->USBInterfaceOpen(interface); if (kr != kIOReturnSuccess) { printf("Unable to open interface (%08x)\n", kr); (*interface)->Release(interface); continue; } // Get the number of endpoints associated with this interface UInt8 interfaceNumEndpoints; kr = (*interface)->GetNumEndpoints(interface, &interfaceNumEndpoints); if (kr != kIOReturnSuccess) { printf("Unable to get number of endpoints (%08x)\n", kr); (*interface)->USBInterfaceClose(interface); (*interface)->Release(interface); continue; } printf("Interface has %d endpoints\n", interfaceNumEndpoints); // Access each pipe in turn, starting with the pipe at index 1 // The pipe at index 0 is the default control pipe and should be // accessed using (*usbDevice)->DeviceRequest() instead for (int pipeRef = 1; pipeRef <= interfaceNumEndpoints; pipeRef++) { printf(" PipeRef %d: ", pipeRef); UInt8 direction; UInt8 number; UInt8 transferType; UInt16 maxPacketSize; UInt8 interval; kr = (*interface)->GetPipeProperties(interface, pipeRef, &direction, &number, &transferType, &maxPacketSize, &interval); if (kr != kIOReturnSuccess) { printf("Unable to get properties of pipe(%08x)\n", kr); continue; } const char* message; switch (direction) { case kUSBOut: message = "out"; break; case kUSBIn: message = "in"; break; case kUSBNone: message = "none"; break; case kUSBAnyDirn: message = "any"; break; default: message = "???"; break; } printf("direction %s, ", message); switch (transferType) { case kUSBControl: message = "control"; break; case kUSBIsoc: message = "isoc"; break; case kUSBBulk: message = "bulk"; break; case kUSBInterrupt: message = "interrupt"; break; case kUSBAnyType: message = "any"; break; default: message = "???"; break; } printf("transfer type %s, maxPacketSize %d\n", message, maxPacketSize); } // Query G.I.M.I.C module info. m_device = dev; m_interface = interface; return true; } (*dev)->USBDeviceClose(dev); (*dev)->Release(dev); return false; }
int musb_open(MUSB_INTERFACE **musb_interface, int vendor, int product, int instance, int configuration, int usbinterface) { #if defined(HAVE_LIBUSB) struct usb_bus *bus; struct usb_device *dev; int count = 0; usb_init(); usb_find_busses(); usb_find_devices(); usb_set_debug(3); for (bus = usb_get_busses(); bus; bus = bus->next) for (dev = bus->devices; dev; dev = dev->next) if (dev->descriptor.idVendor == vendor && dev->descriptor.idProduct == product) { if (count == instance) { int status; usb_dev_handle *udev; udev = usb_open(dev); if (!udev) { fprintf(stderr, "musb_open: usb_open() error\n"); return MUSB_ACCESS_ERROR; } status = usb_set_configuration(udev, configuration); if (status < 0) { fprintf(stderr, "musb_open: usb_set_configuration() error %d (%s)\n", status, strerror(-status)); fprintf(stderr, "musb_open: Found USB device 0x%04x:0x%04x instance %d, but cannot initialize it: please check permissions on \"/proc/bus/usb/%s/%s\" and \"/dev/bus/usb/%s/%s\"\n", vendor, product, instance, bus->dirname, dev->filename, bus->dirname, dev->filename); return MUSB_ACCESS_ERROR; } /* see if we have write access */ status = usb_claim_interface(udev, usbinterface); if (status < 0) { fprintf(stderr, "musb_open: usb_claim_interface() error %d (%s)\n", status, strerror(-status)); #ifdef _MSC_VER fprintf(stderr, "musb_open: Found USB device 0x%04x:0x%04x instance %d, but cannot initialize it:\nDevice is probably used by another program\n", vendor, product, instance); #else fprintf(stderr, "musb_open: Found USB device 0x%04x:0x%04x instance %d, but cannot initialize it: please check permissions on \"/proc/bus/usb/%s/%s\"\n", vendor, product, instance, bus->dirname, dev->filename); #endif return MUSB_ACCESS_ERROR; } *musb_interface = (MUSB_INTERFACE*)calloc(1, sizeof(MUSB_INTERFACE)); (*musb_interface)->dev = udev; (*musb_interface)->usb_configuration = configuration; (*musb_interface)->usb_interface = usbinterface; return MUSB_SUCCESS; } count++; } return MUSB_NOT_FOUND; #elif defined(HAVE_LIBUSB10) static int first_call = 1; libusb_device **dev_list; libusb_device_handle *dev; struct libusb_device_descriptor desc; int status, i, n; int count = 0; if (first_call) { first_call = 0; libusb_init(NULL); // libusb_set_debug(NULL, 3); } n = libusb_get_device_list(NULL, &dev_list); for (i=0 ; i<n ; i++) { status = libusb_get_device_descriptor(dev_list[i], &desc); if (desc.idVendor == vendor && desc.idProduct == product) { if (count == instance) { status = libusb_open(dev_list[i], &dev); if (status < 0) { fprintf(stderr, "musb_open: libusb_open() error %d\n", status); return MUSB_ACCESS_ERROR; } status = libusb_set_configuration(dev, configuration); if (status < 0) { fprintf(stderr, "musb_open: usb_set_configuration() error %d\n", status); fprintf(stderr, "musb_open: Found USB device 0x%04x:0x%04x instance %d, but cannot initialize it: please check permissions on \"/proc/bus/usb/%d/%d\" and \"/dev/bus/usb/%d/%d\"\n", vendor, product, instance, libusb_get_bus_number(dev_list[i]), libusb_get_device_address(dev_list[i]), libusb_get_bus_number(dev_list[i]), libusb_get_device_address(dev_list[i])); return MUSB_ACCESS_ERROR; } /* see if we have write access */ status = libusb_claim_interface(dev, usbinterface); if (status < 0) { fprintf(stderr, "musb_open: libusb_claim_interface() error %d\n", status); #ifdef _MSC_VER fprintf(stderr, "musb_open: Found USB device 0x%04x:0x%04x instance %d, but cannot initialize it:\nDevice is probably used by another program\n", vendor, product, instance); #else fprintf(stderr, "musb_open: Found USB device 0x%04x:0x%04x instance %d, but cannot initialize it: please check permissions on \"/proc/bus/usb/%d/%d\"\n", vendor, product, instance, libusb_get_bus_number(dev_list[i]), libusb_get_device_address(dev_list[i])); #endif return MUSB_ACCESS_ERROR; } *musb_interface = (MUSB_INTERFACE*)calloc(1, sizeof(MUSB_INTERFACE)); (*musb_interface)->dev = dev; (*musb_interface)->usb_configuration = configuration; (*musb_interface)->usb_interface = usbinterface; return MUSB_SUCCESS; } count++; } } libusb_free_device_list(dev_list, 1); return MUSB_NOT_FOUND; #elif defined(OS_DARWIN) kern_return_t status; io_iterator_t iter; io_service_t service; IOCFPlugInInterface **plugin; SInt32 score; IOUSBDeviceInterface **device; UInt16 xvendor, xproduct; int count = 0; *musb_interface = calloc(1, sizeof(MUSB_INTERFACE)); status = IORegistryCreateIterator(kIOMasterPortDefault, kIOUSBPlane, kIORegistryIterateRecursively, &iter); assert(status == kIOReturnSuccess); while ((service = IOIteratorNext(iter))) { status = IOCreatePlugInInterfaceForService(service, kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &plugin, &score); assert(status == kIOReturnSuccess); status = IOObjectRelease(service); assert(status == kIOReturnSuccess); status = (*plugin)->QueryInterface(plugin, CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID), (void *) &device); assert(status == kIOReturnSuccess); status = (*plugin)->Release(plugin); status = (*device)->GetDeviceVendor(device, &xvendor); assert(status == kIOReturnSuccess); status = (*device)->GetDeviceProduct(device, &xproduct); assert(status == kIOReturnSuccess); //fprintf(stderr, "musb_open: Found USB device: vendor 0x%04x, product 0x%04x\n", xvendor, xproduct); if (xvendor == vendor && xproduct == product) { if (count == instance) { fprintf(stderr, "musb_open: Found USB device: vendor 0x%04x, product 0x%04x, instance %d\n", xvendor, xproduct, instance); status = (*device)->USBDeviceOpen(device); fprintf(stderr, "musb_open: USBDeviceOpen status 0x%x\n", status); assert(status == kIOReturnSuccess); (*musb_interface)->usb_configuration = configuration; (*musb_interface)->usb_interface = usbinterface; (*musb_interface)->device = (void*)device; (*musb_interface)->interface = NULL; status = darwin_configure_device(*musb_interface); if (status == kIOReturnSuccess) return MUSB_SUCCESS; fprintf(stderr, "musb_open: USB device exists, but configuration fails!"); return MUSB_NOT_FOUND; } count++; } (*device)->Release(device); } return MUSB_NOT_FOUND; #elif defined(_MSC_VER) GUID guid; HDEVINFO hDevInfoList; SP_DEVICE_INTERFACE_DATA deviceInfoData; PSP_DEVICE_INTERFACE_DETAIL_DATA functionClassDeviceData; ULONG predictedLength, requiredLength; int status; char device_name[256], str[256]; *musb_interface = (MUSB_INTERFACE *)calloc(1, sizeof(MUSB_INTERFACE)); guid = GUID_CLASS_MSCB_BULK; // Retrieve device list for GUID that has been specified. hDevInfoList = SetupDiGetClassDevs(&guid, NULL, NULL, (DIGCF_PRESENT | DIGCF_DEVICEINTERFACE)); status = FALSE; if (hDevInfoList != NULL) { // Clear data structure memset(&deviceInfoData, 0, sizeof(deviceInfoData)); deviceInfoData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); // retrieves a context structure for a device interface of a device information set. if (SetupDiEnumDeviceInterfaces(hDevInfoList, 0, &guid, instance, &deviceInfoData)) { // Must get the detailed information in two steps // First get the length of the detailed information and allocate the buffer // retrieves detailed information about a specified device interface. functionClassDeviceData = NULL; predictedLength = requiredLength = 0; SetupDiGetDeviceInterfaceDetail(hDevInfoList, &deviceInfoData, NULL, // Not yet allocated 0, // Set output buffer length to zero &requiredLength, // Find out memory requirement NULL); predictedLength = requiredLength; functionClassDeviceData = (PSP_DEVICE_INTERFACE_DETAIL_DATA) malloc(predictedLength); functionClassDeviceData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); // Second, get the detailed information if (SetupDiGetDeviceInterfaceDetail(hDevInfoList, &deviceInfoData, functionClassDeviceData, predictedLength, &requiredLength, NULL)) { // Save the device name for subsequent pipe open calls strcpy(device_name, functionClassDeviceData->DevicePath); free(functionClassDeviceData); // Signal device found status = TRUE; } else free(functionClassDeviceData); } } // SetupDiDestroyDeviceInfoList() destroys a device information set // and frees all associated memory. SetupDiDestroyDeviceInfoList(hDevInfoList); if (status) { // Get the read handle sprintf(str, "%s\\PIPE00", device_name); (*musb_interface)->rhandle = CreateFile(str, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); if ((*musb_interface)->rhandle == INVALID_HANDLE_VALUE) return MUSB_ACCESS_ERROR; // Get the write handle sprintf(str, "%s\\PIPE01", device_name); (*musb_interface)->whandle = CreateFile(str, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); if ((*musb_interface)->whandle == INVALID_HANDLE_VALUE) return MUSB_ACCESS_ERROR; return MUSB_SUCCESS; } return MUSB_NOT_FOUND; #endif }
// Like open(). Return non-negative integer handle, only used by the // functions below. type=="ATA" or "SCSI". The return value is // an index into the devices[] array. If the device can't be opened, // sets errno and returns -1. // Acceptable device names are: // /dev/disk* // /dev/rdisk* // disk* // IOService:* // IODeviceTree:* int deviceopen(const char *pathname, char *type){ size_t devnum; const char *devname; io_object_t disk; if (strcmp (type, "ATA") != 0) { errno = EINVAL; return -1; } // Find a free device number. for (devnum = 0; devnum < sizeof (devices) / sizeof (devices[0]); devnum++) if (! devices[devnum].ioob) break; if (devnum == sizeof (devices) / sizeof (devices[0])) { errno = EMFILE; return -1; } devname = NULL; if (strncmp (pathname, "/dev/rdisk", 10) == 0) devname = pathname + 6; else if (strncmp (pathname, "/dev/disk", 9) == 0) devname = pathname + 5; else if (strncmp (pathname, "disk", 4) == 0) // allow user to just say 'disk0' devname = pathname; // Find the device. if (devname) { CFMutableDictionaryRef matcher; matcher = IOBSDNameMatching (kIOMasterPortDefault, 0, devname); disk = IOServiceGetMatchingService (kIOMasterPortDefault, matcher); } else { disk = IORegistryEntryFromPath (kIOMasterPortDefault, pathname); } if (! disk) { errno = ENOENT; return -1; } // Find a SMART-capable driver which is a parent of this device. while (! is_smart_capable (disk)) { IOReturn err; io_object_t prevdisk = disk; // Find this device's parent and try again. err = IORegistryEntryGetParentEntry (disk, kIOServicePlane, &disk); if (err != kIOReturnSuccess || ! disk) { errno = ENODEV; IOObjectRelease (prevdisk); return -1; } } devices[devnum].ioob = disk; { SInt32 dummy; devices[devnum].plugin = NULL; devices[devnum].smartIf = NULL; // Create an interface to the ATA SMART library. if (IOCreatePlugInInterfaceForService (disk, kIOATASMARTUserClientTypeID, kIOCFPlugInInterfaceID, &devices[devnum].plugin, &dummy) == kIOReturnSuccess) (*devices[devnum].plugin)->QueryInterface (devices[devnum].plugin, CFUUIDGetUUIDBytes ( kIOATASMARTInterfaceID), (void **)&devices[devnum].smartIf); } return devnum; }
IOReturn darwin_configure_device(MUSB_INTERFACE* musb) { IOReturn status; io_iterator_t iter; io_service_t service; IOCFPlugInInterface **plugin; SInt32 score; IOUSBInterfaceInterface **uinterface; UInt8 numend; IOUSBDeviceInterface **device = (IOUSBDeviceInterface **)musb->device; status = (*device)->SetConfiguration(device, musb->usb_configuration); assert(status == kIOReturnSuccess); IOUSBFindInterfaceRequest request; request.bInterfaceClass = kIOUSBFindInterfaceDontCare; request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare; request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare; request.bAlternateSetting = kIOUSBFindInterfaceDontCare; status = (*device)->CreateInterfaceIterator(device, &request, &iter); assert(status == kIOReturnSuccess); while ((service = IOIteratorNext(iter))) { int i; status = IOCreatePlugInInterfaceForService(service, kIOUSBInterfaceUserClientTypeID, kIOCFPlugInInterfaceID, &plugin, &score); assert(status == kIOReturnSuccess); status = (*plugin)->QueryInterface(plugin, CFUUIDGetUUIDBytes(kIOUSBInterfaceInterfaceID), (void *) &uinterface); assert(status == kIOReturnSuccess); status = (*uinterface)->USBInterfaceOpen(uinterface); fprintf(stderr, "musb_open: USBInterfaceOpen status 0x%x\n", status); assert(status == kIOReturnSuccess); status = (*uinterface)->GetNumEndpoints(uinterface, &numend); assert(status == kIOReturnSuccess); fprintf(stderr, "musb_open: endpoints: %d\n", numend); for (i=1; i<=numend; i++) { status = (*uinterface)->GetPipeStatus(uinterface, i); fprintf(stderr, "musb_open: pipe %d status: 0x%x\n", i, status); #if 0 status = (*uinterface)->ClearPipeStall(uinterface, i); fprintf(stderr, "musb_open: pipe %d ClearPipeStall() status: 0x%x\n", i, status); status = (*uinterface)->ResetPipe(uinterface, i); fprintf(stderr, "musb_open: pipe %d ResetPipe() status: 0x%x\n", i, status); status = (*uinterface)->AbortPipe(uinterface, i); fprintf(stderr, "musb_open: pipe %d AbortPipe() status: 0x%x\n", i, status); #endif } musb->interface = uinterface; return kIOReturnSuccess; } assert(!"Should never be reached!"); return -1; }
/** Try out all the interfaces and see if there's a match. Returns 0 on * success, -1 on failure. */ static int try_interfaces(IOUSBDeviceInterface500** dev, usb_handle* handle) { IOReturn kr; IOUSBFindInterfaceRequest request; io_iterator_t iterator; io_service_t usbInterface; IOCFPlugInInterface **plugInInterface; IOUSBInterfaceInterface500** interface = NULL; HRESULT result; SInt32 score; UInt8 interfaceNumEndpoints; request.bInterfaceClass = 0xff; request.bInterfaceSubClass = 0x42; request.bInterfaceProtocol = 0x03; request.bAlternateSetting = kIOUSBFindInterfaceDontCare; // Get an iterator for the interfaces on the device kr = (*dev)->CreateInterfaceIterator(dev, &request, &iterator); if (kr != 0) { ERR("Couldn't create a device interface iterator: (%08x)\n", kr); return -1; } while ((usbInterface = IOIteratorNext(iterator))) { // Create an intermediate plugin kr = IOCreatePlugInInterfaceForService( usbInterface, kIOUSBInterfaceUserClientTypeID, kIOCFPlugInInterfaceID, &plugInInterface, &score); // No longer need the usbInterface object now that we have the plugin (void) IOObjectRelease(usbInterface); if ((kr != 0) || (!plugInInterface)) { WARN("Unable to create plugin (%08x)\n", kr); continue; } // Now create the interface interface for the interface result = (*plugInInterface) ->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(kIOUSBInterfaceInterfaceID500), (LPVOID*)&interface); // No longer need the intermediate plugin (*plugInInterface)->Release(plugInInterface); if (result || !interface) { ERR("Couldn't create interface interface: (%08x)\n", (unsigned int) result); // continue so we can try the next interface continue; } /* * Now open the interface. This will cause the pipes * associated with the endpoints in the interface descriptor * to be instantiated. */ /* * TODO: Earlier comments here indicated that it was a bad * idea to just open any interface, because opening "mass * storage endpoints" is bad. However, the only way to find * out if an interface does bulk in or out is to open it, and * the framework in this application wants to be told about * bulk in / out before deciding whether it actually wants to * use the interface. Maybe something needs to be done about * this situation. */ kr = (*interface)->USBInterfaceOpen(interface); if (kr != 0) { WARN("Could not open interface: (%08x)\n", kr); (void) (*interface)->Release(interface); // continue so we can try the next interface continue; } // Get the number of endpoints associated with this interface. kr = (*interface)->GetNumEndpoints(interface, &interfaceNumEndpoints); if (kr != 0) { ERR("Unable to get number of endpoints: (%08x)\n", kr); goto next_interface; } // Get interface class, subclass and protocol if ((*interface)->GetInterfaceClass(interface, &handle->info.ifc_class) != 0 || (*interface)->GetInterfaceSubClass(interface, &handle->info.ifc_subclass) != 0 || (*interface)->GetInterfaceProtocol(interface, &handle->info.ifc_protocol) != 0) { ERR("Unable to get interface class, subclass and protocol\n"); goto next_interface; } handle->info.has_bulk_in = 0; handle->info.has_bulk_out = 0; // Iterate over the endpoints for this interface and see if there // are any that do bulk in/out. for (UInt8 endpoint = 1; endpoint <= interfaceNumEndpoints; endpoint++) { UInt8 transferType; UInt16 maxPacketSize; UInt8 interval; UInt8 number; UInt8 direction; kr = (*interface)->GetPipeProperties(interface, endpoint, &direction, &number, &transferType, &maxPacketSize, &interval); if (kr == 0) { if (transferType != kUSBBulk) { continue; } if (direction == kUSBIn) { handle->info.has_bulk_in = 1; handle->bulkIn = endpoint; } else if (direction == kUSBOut) { handle->info.has_bulk_out = 1; handle->bulkOut = endpoint; } if (handle->info.ifc_protocol == 0x01) { handle->zero_mask = maxPacketSize - 1; } } else { ERR("could not get pipe properties for endpoint %u (%08x)\n", endpoint, kr); } if (handle->info.has_bulk_in && handle->info.has_bulk_out) { break; } } if (handle->callback(&handle->info) == 0) { handle->interface = interface; handle->success = 1; /* * Clear both the endpoints, because it has been observed * that the Mac may otherwise (incorrectly) start out with * them in bad state. */ if (handle->info.has_bulk_in) { kr = (*interface)->ClearPipeStallBothEnds(interface, handle->bulkIn); if (kr != 0) { ERR("could not clear input pipe; result %x, ignoring...\n", kr); } } if (handle->info.has_bulk_out) { kr = (*interface)->ClearPipeStallBothEnds(interface, handle->bulkOut); if (kr != 0) { ERR("could not clear output pipe; result %x, ignoring....\n", kr); } } return 0; } next_interface: (*interface)->USBInterfaceClose(interface); (*interface)->Release(interface); } return 0; }
brick_t *find_usb_devices ( void *usb, int32_t vendor, int32_t product, int32_t configuration, int32_t interface, brick_type_t type) { usb_handle_t *h = (usb_handle_t *) usb; CFMutableDictionaryRef matching; kern_return_t kr; io_iterator_t devices; io_service_t device; brick_t *bricks = NULL; int count; if (configuration) { matching = IOServiceMatching (kIOUSBInterfaceClassName); } else { matching = IOServiceMatching (kIOUSBDeviceClassName); } if (!matching) { return NULL; } CFDictionarySetValue (matching, CFSTR (kUSBVendorID), CFNumberCreate (kCFAllocatorDefault, kCFNumberSInt32Type, &vendor)); CFDictionarySetValue (matching, CFSTR (kUSBProductID), CFNumberCreate (kCFAllocatorDefault, kCFNumberSInt32Type, &product)); if (configuration) { CFDictionarySetValue (matching, CFSTR (kUSBConfigurationValue), CFNumberCreate (kCFAllocatorDefault, kCFNumberSInt32Type, &configuration)); CFDictionarySetValue (matching, CFSTR (kUSBInterfaceNumber), CFNumberCreate (kCFAllocatorDefault, kCFNumberSInt32Type, &interface)); } kr = IOServiceGetMatchingServices (h->port, matching, &devices); if (kr) { fprintf (stderr, "IOService matching error = %08x\n", kr); return NULL; } count = 0; while ((device = IOIteratorNext (devices))) count++; if (count > 0) { int i = 0; IOIteratorReset (devices); bricks = malloc ((sizeof (brick_t)) * (count + 1)); memset ((void *) bricks, 0, (sizeof (brick_t )) * (count + 1)); while ((device = IOIteratorNext (devices))) { IOUSBInterfaceInterface182 **intf = NULL; IOUSBDeviceInterface **dev = NULL; IOCFPlugInInterface **plugInInterface = NULL; brick_t *b = &(bricks[i]); HRESULT result; SInt32 score; if (configuration) { kr = IOCreatePlugInInterfaceForService ( device, kIOUSBInterfaceUserClientTypeID, kIOCFPlugInInterfaceID, &plugInInterface, &score ); } else { kr = IOCreatePlugInInterfaceForService ( device, kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &plugInInterface, &score ); } if (kr || !plugInInterface) { continue; } if (configuration) { result = (*plugInInterface)->QueryInterface ( plugInInterface, CFUUIDGetUUIDBytes (kIOUSBInterfaceInterfaceID182), (LPVOID *) &intf ); } else { result = (*plugInInterface)->QueryInterface ( plugInInterface, CFUUIDGetUUIDBytes (kIOUSBDeviceInterfaceID), (LPVOID *) &dev ); } (*plugInInterface)->Release (plugInInterface); if (result || !(dev || intf)) { continue; } b->type = type; if (configuration) { b->handle = intf; b->open = open_intf; b->close = close_intf; b->control = control_msg; b->read = read_intf; b->write = write_intf; b->release = release_intf; (*intf)->GetLocationID (intf, &(b->id)); } else { b->handle = dev; b->get_config = get_dev_config; b->set_config = set_dev_config; b->release = release_dev; (*dev)->GetLocationID (dev, &(b->id)); } i = i + 1; } bricks[i].type = NULL_BRICK; } return bricks; }
IOReturn PrintSMARTData ( io_service_t service ) { IOCFPlugInInterface ** cfPlugInInterface = NULL; IOATASMARTInterface ** smartInterface = NULL; HRESULT herr = S_OK; IOReturn err = kIOReturnSuccess; SInt32 score = 0; Boolean conditionExceeded = false; CFStringRef description = NULL; UInt8 buffer[512]; UInt32 bytesRead; ATASMARTLogDirectory logData; err = IOCreatePlugInInterfaceForService ( service, kIOATASMARTUserClientTypeID, kIOCFPlugInInterfaceID, &cfPlugInInterface, &score ); require_string ( ( err == kIOReturnSuccess ), ErrorExit, "IOCreatePlugInInterfaceForService" ); herr = ( *cfPlugInInterface )->QueryInterface ( cfPlugInInterface, CFUUIDGetUUIDBytes ( kIOATASMARTInterfaceID ), ( LPVOID ) &smartInterface ); require_string ( ( herr == S_OK ), ReleasePlugIn, "QueryInterface" ); require_string ( ( smartInterface != NULL ), ReleasePlugIn, "smartInterface" ); description = GetDriveDescription ( service ); printf ( "SAT Drive: " ); fflush ( stdout ); CFShow ( description ); CFRelease ( description ); err = ( *smartInterface )->SMARTEnableDisableOperations ( smartInterface, true ); require_string ( ( err == kIOReturnSuccess ), ReleaseInterface, "SMARTEnableDisableOperations" ); err = ( *smartInterface )->SMARTEnableDisableAutosave ( smartInterface, true ); require ( ( err == kIOReturnSuccess ), ReleaseInterface ); err = ( *smartInterface )->SMARTReturnStatus ( smartInterface, &conditionExceeded ); require ( ( err == kIOReturnSuccess ), ReleaseInterface ); if ( conditionExceeded ) { printf ( "SMART condition exceeded, drive will fail soon\n" ); } else { printf ( "SMART condition not exceeded, drive OK\n" ); } err = ( *smartInterface )->GetATAIdentifyData (smartInterface, &buffer, sizeof buffer, &bytesRead ); require ( ( err == kIOReturnSuccess ), ReleaseInterface ); require ( ( bytesRead == sizeof buffer ), ReleaseInterface ); printf ( "Model: %s\n", buffer + 2 * kATAIdentifyModelNumber ); // FIXME not null terminated err = ( *smartInterface )->SMARTReadLogDirectory (smartInterface, &logData ); require ( ( err == kIOReturnSuccess ), ReleaseInterface ); for (int i = 0; i < 255; i++) { if (logData.entries[i].numberOfSectors > 0) printf ( "entry[%d]: %d\n", i, logData.entries[i].numberOfSectors); } err = ( *smartInterface )->SMARTReadLogAtAddress ( smartInterface, 224, buffer, sizeof buffer); require ( ( err == kIOReturnSuccess ), ReleaseInterface ); for (int i = 0; i < 512; i++) { if (buffer[i]) printf ( "buffer[%d]: %d\n", i, buffer[i]); } #if 0 err = ( *smartInterface )->SMARTWriteLogAtAddress ( smartInterface, 224, buffer, sizeof buffer); require ( ( err == kIOReturnSuccess ), ReleaseInterface ); #endif ReleaseInterface: printf ("status %s\n", getStatus(err)); ( *smartInterface )->Release ( smartInterface ); smartInterface = NULL; ReleasePlugIn: err = IODestroyPlugInInterface ( cfPlugInInterface ); require ( ( err == kIOReturnSuccess ), ErrorExit ); ErrorExit: return err; }
forensic1394_result platform_enable_sbp2(forensic1394_bus *bus, const uint32_t *sbp2dir, size_t len) { int i; CFMutableDictionaryRef matchingDict; io_iterator_t iterator; io_object_t currdev; IOCFPlugInInterface **plugIn; SInt32 theScore; // Unused IOFireWireLibDeviceRef localDev; IOFireWireLibLocalUnitDirectoryRef localUnitDir; IOReturn iret; forensic1394_result fret = FORENSIC1394_RESULT_SUCCESS; // We need to get the systems local device node to update the CSR matchingDict = IOServiceMatching("IOFireWireLocalNode"); iret = IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDict, &iterator); // If the call fails then we do not need to release the iterator require_success(iret, cleanupNull, fret); // There should only be one of these; so grab the first currdev = IOIteratorNext(iterator); // Get a plug-in interface to the device IOCreatePlugInInterfaceForService(currdev, kIOFireWireLibTypeID, kIOCFPlugInInterfaceID, &plugIn, &theScore); // Ensure plugIn is != NULL; otherwise this is a general error require_assertion(plugIn, cleanupCurrdev, fret, FORENSIC1394_RESULT_OTHER_ERROR); // Use this plug-in to get a firewire device interface iret = (*plugIn)->QueryInterface(plugIn, CFUUIDGetUUIDBytes(kIOFireWireDeviceInterfaceID_v9), (void **) &localDev); require_success(iret, cleanupPlugIn, fret); // Use this device interface to open up the device (*localDev)->Open(localDev); // And grab a unit local directory interface localUnitDir = (*localDev)->CreateLocalUnitDirectory(localDev, CFUUIDGetUUIDBytes(kIOFireWireLocalUnitDirectoryInterfaceID)); // Add the unit directory, ignoring the first entry for (i = 1; i < len; i++) { // The entries are passed as <8-bit key><24-bit value> UInt32 key = CSR_KEY(sbp2dir[i]); UInt32 value = CSR_VALUE(sbp2dir[i]); // Add the key-value pair to the local unit directory (*localUnitDir)->AddEntry_UInt32(localUnitDir, key, value, NULL); } // Publish this unit directory (*localUnitDir)->Publish(localUnitDir); // Save the interface references for later bus->pbus->localDev = localDev; bus->pbus->localUnitDir = localUnitDir; cleanupPlugIn: // Release the plug-in interface IODestroyPlugInInterface(plugIn); cleanupCurrdev: // Release the current device io_object IOObjectRelease(currdev); // Release the iterator used to find the device IOObjectRelease(iterator); cleanupNull: // Should be FORENSIC1394_RESULT_SUCCESS unless changed by an error macro return fret; }