示例#1
0
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);
        }
    }
}
示例#2
0
文件: usb_mac.c 项目: akosipc/ckb
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);
        }
    }
}
示例#3
0
文件: main.cpp 项目: arnelh/Examples
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;
}
示例#5
0
////////////////////////////////////////////////////////////
/// 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;
}
示例#6
0
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;
}
示例#7
0
文件: fwext.c 项目: iZsh/rubyfw
// 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));
  }
示例#8
0
// 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;
}
示例#9
0
文件: xcache.c 项目: aosm/Heimdal
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;
}
示例#10
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;
}
示例#12
0
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;
}
示例#13
0
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);
}
示例#14
0
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);
    }
}
示例#15
0
/** 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;
}
示例#16
0
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);
        }
    }
}
示例#17
0
//================================================================================================
//
//  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);
	}
}
示例#18
0
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);
	
}
示例#19
0
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;
}
示例#20
0
文件: main.c 项目: aosm/IOUSBFamily
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
    }
}
示例#21
0
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;
}
示例#23
0
/**
 * 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;
}
示例#24
0
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
}
示例#25
0
// 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;
}
示例#26
0
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;
}
示例#27
0
/** 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;
}
示例#28
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;

}
示例#30
0
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;
}