示例#1
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);
        }
    }
}
示例#2
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;
}
示例#3
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;
}
示例#4
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;
}
示例#5
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;
}
示例#6
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
    }
}
示例#7
0
文件: main.c 项目: aosm/IOUSBFamily
IOReturn FindInterfaces(IOUSBDeviceInterface245 **dev)
{
    IOReturn			kr;
    IOUSBFindInterfaceRequest	request;
    io_iterator_t		iterator;
    io_service_t		usbInterface;
    IOCFPlugInInterface 	**plugInInterface = NULL;
    IOUSBInterfaceInterface245 	**intf = NULL;
    HRESULT 			res;
    SInt32 			score;
    UInt8			intfClass;
    UInt8			intfSubClass;
    UInt8			intfNumEndpoints;
    int				pipeRef;
#ifndef USE_ASYNC_IO
    UInt32			numBytesRead;
    UInt32			i;
#else
    CFRunLoopSourceRef		runLoopSource;
#endif
    
    request.bInterfaceClass = kIOUSBFindInterfaceDontCare;
    request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare;
    request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare;
    request.bAlternateSetting = kIOUSBFindInterfaceDontCare;
   
    kr = (*dev)->CreateInterfaceIterator(dev, &request, &iterator);
    
    while ( (usbInterface = IOIteratorNext(iterator)) )
    {
        printf("Interface found.\n");
       
        kr = IOCreatePlugInInterfaceForService(usbInterface, kIOUSBInterfaceUserClientTypeID, kIOCFPlugInInterfaceID, &plugInInterface, &score);
        kr = IOObjectRelease(usbInterface);				// done with the usbInterface object now that I have the plugin
        if ((kIOReturnSuccess != kr) || !plugInInterface)
        {
            printf("unable to create a plugin (%08x)\n", kr);
            break;
        }
            
        // I have the interface plugin. I need the interface interface
        res = (*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(kIOUSBInterfaceInterfaceID245), (LPVOID) &intf);
        IODestroyPlugInInterface(plugInInterface);			// done with this

        if (res || !intf)
        {
            printf("couldn't create an IOUSBInterfaceInterface245 (%08x)\n", (int) res);
            break;
        }
        
        kr = (*intf)->GetInterfaceClass(intf, &intfClass);
        kr = (*intf)->GetInterfaceSubClass(intf, &intfSubClass);
        
        printf("Interface class %d, subclass %d\n", intfClass, intfSubClass);
        
        // Now open the interface. This will cause the pipes to be instantiated that are 
        // associated with the endpoints defined in the interface descriptor.
        kr = (*intf)->USBInterfaceOpen(intf);
        if (kIOReturnSuccess != kr)
        {
            printf("unable to open interface (%08x)\n", kr);
            (void) (*intf)->Release(intf);
            break;
        }
        
    	kr = (*intf)->GetNumEndpoints(intf, &intfNumEndpoints);
        if (kIOReturnSuccess != kr)
        {
            printf("unable to get number of endpoints (%08x)\n", kr);
            (void) (*intf)->USBInterfaceClose(intf);
            (void) (*intf)->Release(intf);
            break;
        }
        
        printf("Interface has %d endpoints.\n", intfNumEndpoints);

        for (pipeRef = 1; pipeRef <= intfNumEndpoints; pipeRef++)
        {
            IOReturn	kr2;
            UInt8	direction;
            UInt8	number;
            UInt8	transferType;
            UInt16	maxPacketSize;
            UInt8	interval;
            char	*message;
            
            kr2 = (*intf)->GetPipeProperties(intf, pipeRef, &direction, &number, &transferType, &maxPacketSize, &interval);
            if (kIOReturnSuccess != kr)
                printf("unable to get properties of pipe %d (%08x)\n", pipeRef, kr2);
            else {
                printf("pipeRef %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 = "???";
                }
                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 = "???";
                }
                printf("transfer type %s, maxPacketSize %d\n", message, maxPacketSize);
            }
        }
        
        // We can now address endpoints 1 through intfNumEndpoints. Or, we can also address endpoint 0,
        // the default control endpoint. But it's usually better to use (*usbDevice)->DeviceRequest() instead.
#ifndef USE_ASYNC_IO
        kr = (*intf)->WritePipe(intf, 2, kTestMessage, strlen(kTestMessage));
        if (kIOReturnSuccess != kr)
        {
            printf("unable to do bulk write (%08x)\n", kr);
            (void) (*intf)->USBInterfaceClose(intf);
            (void) (*intf)->Release(intf);
            break;
        }
        
        printf("Wrote \"%s\" (%ld bytes) to bulk endpoint\n", kTestMessage, (UInt32) strlen(kTestMessage));
        
        numBytesRead = sizeof(gBuffer) - 1; // leave one byte at the end for NUL termination
        kr = (*intf)->ReadPipe(intf, 9, gBuffer, &numBytesRead);
        if (kIOReturnSuccess != kr)
        {
            printf("unable to do bulk read (%08x)\n", kr);
            (void) (*intf)->USBInterfaceClose(intf);
            (void) (*intf)->Release(intf);
            break;
        }
        // The firmware we downloaded echoes the 1's complement of what we wrote, so
        // complement the buffer contents to see if we get the original data
        for (i = 0; i < numBytesRead; i++)
            gBuffer[i] = ~gBuffer[i];
    
        printf("Read \"%s\" (%ld bytes) from bulk endpoint\n", gBuffer, numBytesRead);
#else
        // Just like with service matching notifications, we need to create an event source and add it 
        //  to our run loop in order to receive async completion notifications.
        kr = (*intf)->CreateInterfaceAsyncEventSource(intf, &runLoopSource);
        if (kIOReturnSuccess != kr)
        {
            printf("unable to create async event source (%08x)\n", kr);
            (void) (*intf)->USBInterfaceClose(intf);
            (void) (*intf)->Release(intf);
            break;
        }
        CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopDefaultMode);
        
        printf("Async event source added to run loop.\n");
        
        bzero(gBuffer, sizeof(gBuffer));
        strcpy(gBuffer, kTestMessage);
        kr = (*intf)->WritePipeAsync(intf, 2, gBuffer, strlen(gBuffer), WriteCompletion, (void *) intf);
        if (kIOReturnSuccess != kr)
        {
            printf("unable to do async bulk write (%08x)\n", kr);
            (void) (*intf)->USBInterfaceClose(intf);
            (void) (*intf)->Release(intf);
            break;
        }
#endif
        
        // For this test we just want to use the first interface, so exit the loop.
        break;
    }
    
    return kr;
}
示例#8
0
/* Main method. */
int main (int argc, const char * argv[])
{
	kern_return_t err;
	
	mach_port_t masterPort = 0;
	bool suspend;
	SInt32 productId, vendorId;	
	SInt32 count;
	CFMutableDictionaryRef matcher;
	CFNumberRef numberRef;
	io_iterator_t iterator;
	io_service_t usbService;
    IOCFPlugInInterface **pluginInterface;
	IOUSBDeviceInterface245 **deviceInterface;
	SInt32 score;

	// Display usage info
	if(argc != 4)
	{
		printf("Usage:\n"
			"  usbpower suspend <product id> <vendor id>\n"
			"  usbpower resume <product id> <vendor id>\n"
			"\n"
			"Vendor and product IDs can be obtained by running the command:\n"
			"  system_profiler SPUSBDataType\n"
			"\n"
			"They must be given as four-digit hexadecimal numbers beginning with 0x\n"
			"(as shown by the above command).\n"
			"\n"
			"Example:\n"
			"  usbpower suspend 0x0040 0x045e\n"
			"\n"
			"Copyright 2009 Samuel Marshall - http://www.leafdigital.com/software/\n"
			"Released under Gnu Public License v3.\n");
		return 0;
	}
	
	// Check first parameter
	if(strcmp(argv[1], "suspend") == 0)
	{
		suspend = true;
	}
	else if(strcmp(argv[1], "resume") == 0)
	{
		suspend = false;
	}
	else
	{
		fprintf(stderr, "Invalid argument '%s': expecting suspend, resume\n", argv[1]);
		return -1;
	}
	
	// Check other two parameters
	productId = convertHexId(argv[2]);
	if(productId == -1)
	{
		fprintf(stderr, "Invalid product id '%s': expecting four-digit hexadecimal e.g. 0x0040\n", argv[2]);
		return -1;
	}
	vendorId = convertHexId(argv[3]);
	if(vendorId == -1)
	{
		fprintf(stderr, "Invalid vendor id '%s': expecting four-digit hexadecimal e.g. 0x045e\n", argv[3]);
		return -1;
	}
	
	// Allocate master IO port
	err = IOMasterPort(MACH_PORT_NULL, &masterPort);
	CHECKRETURN(err, "Failed to open master port");
	
	// Create matching dictionary
    matcher = IOServiceMatching(kIOUSBDeviceClassName);
    if(!matcher)
    {
		fprintf(stderr, "Failed to create matching dictionary\n");
		return -1;
    }
	
	// Create number references and add to dictionary
    numberRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &productId);
    if(!numberRef)
    {
        fprintf(stderr, "Failed to create number reference for product ID\n");
        return -1;
    }
    CFDictionaryAddValue(matcher, CFSTR(kUSBProductID), numberRef);
    CFRelease(numberRef);
    numberRef = 0;
    numberRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &vendorId);
    if(!numberRef)
    {
        fprintf(stderr, "Failed to create number reference for vendor ID\n");
        return -1;
    }
    CFDictionaryAddValue(matcher, CFSTR(kUSBVendorID), numberRef);
    CFRelease(numberRef);
    numberRef = 0;
	
	// Get matches from dictionary (this eats the dictionary)
    err = IOServiceGetMatchingServices(masterPort, matcher, &iterator);
	CHECKRETURN(err, "Failed to get matching servivces");
    matcher = 0;
    
	count = 0;
    while((usbService = IOIteratorNext(iterator)))
    {
		// Get plugin interface
		err = IOCreatePlugInInterfaceForService(
			usbService, kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &pluginInterface, &score);
		CHECKRETURN(err, "Failed to create plugin interface for service");
		if(!pluginInterface)
		{
			fprintf(stderr, "Service did not return plugin interface\n");
			return -1;
		}
		
		// Now query for suitable USB device interface
		err = (*pluginInterface)->QueryInterface(pluginInterface, 
			CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID245), (LPVOID)&deviceInterface);
		IODestroyPlugInInterface(pluginInterface);

		// Open device
		err = (*deviceInterface)->USBDeviceOpen(deviceInterface);
		CHECKRETURN(err, "Error opening device");
		
		// Suspend or resume device
		err = (*deviceInterface)->USBDeviceSuspend(deviceInterface, suspend);
		CHECKRETURN(err, "Error suspending or resuming device");
		
		// Close device
		err = (*deviceInterface)->USBDeviceClose(deviceInterface);
		CHECKRETURN(err, "Error closing device");
		err = (*deviceInterface)->Release(deviceInterface);
		CHECKRETURN(err, "Error releading device interface");
		
		// Release service
		IOObjectRelease(usbService);
		count++;
    }
	
	// Release iterator
    IOObjectRelease(iterator);
    iterator = 0;
	
	// Free master IO port
    mach_port_deallocate(mach_task_self(), masterPort);
	
	// Check count
	if(!count)
	{
		fprintf(stderr, "Device with product ID 0x%04x and vendor ID 0x%04x not found\n", productId, vendorId);
		return -1;
	}
	
    return 0;	
}
示例#9
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;
}
示例#10
0
IOReturn
IOAccelReadFramebuffer(io_service_t framebuffer, uint32_t width, uint32_t height, size_t rowBytes,
                        vm_address_t * result, vm_size_t * bytecount)
{
    IOReturn     err;
    io_service_t accelerator;
    UInt32       framebufferIndex;
    size_t       size = 0;
    UInt32       surfaceID = 155;
    vm_address_t buffer = 0;
    IOAccelConnect                      connect = MACH_PORT_NULL;
    IOAccelDeviceRegion *               region = NULL;
    IOAccelSurfaceInformation           surfaceInfo;
    IOGraphicsAcceleratorInterface **   interface = 0;
    IOBlitterPtr                        copyRegionProc;
    IOBlitCopyRegion                    op;
    IOBlitSurface                       dest;
    SInt32                              quality = 0;

    *result    = 0;
    *bytecount = 0;
    dest.interfaceRef = NULL;

    do
    {
        err = IOAccelFindAccelerator(framebuffer, &accelerator, &framebufferIndex);
        if (kIOReturnSuccess != err) continue;
        err = IOAccelCreateSurface(accelerator, surfaceID, 
                                   kIOAccelSurfaceModeWindowedBit | kIOAccelSurfaceModeColorDepth8888,
                                   &connect);
        IOObjectRelease(accelerator);
        if (kIOReturnSuccess != err) continue;
    
        size = rowBytes * height;
    
        region = calloc(1, sizeof (IOAccelDeviceRegion) + sizeof(IOAccelBounds));
        if (!region) continue;
    
        region->num_rects = 1;
        region->bounds.x = region->rect[0].x = 0;
        region->bounds.y = region->rect[0].y = 0;
        region->bounds.h = region->rect[0].h = height;
        region->bounds.w = region->rect[0].w = width;
        
        err = vm_allocate(mach_task_self(), &buffer, size, 
                          VM_FLAGS_ANYWHERE | VM_MAKE_TAG(VM_MEMORY_COREGRAPHICS_FRAMEBUFFERS));
        if (kIOReturnSuccess != err) continue;
    
        err = IOAccelSetSurfaceFramebufferShapeWithBackingAndLength(connect, region,
                    kIOAccelSurfaceShapeIdentityScaleBit| 
                    kIOAccelSurfaceShapeNonBlockingBit| 
                    //kIOAccelSurfaceShapeStaleBackingBit |
                    kIOAccelSurfaceShapeNonSimpleBit,
                    0,
                    (IOVirtualAddress) buffer,
                    (UInt32) rowBytes,
                    (UInt32) size);
        if (kIOReturnSuccess != err) continue;
        err = IOCreatePlugInInterfaceForService(framebuffer,
                            kIOGraphicsAcceleratorTypeID,
                            kIOGraphicsAcceleratorInterfaceID,
                            (IOCFPlugInInterface ***)&interface, &quality );
        if (kIOReturnSuccess != err) continue;
        err = (*interface)->GetBlitter(interface,
                                    kIOBlitAllOptions,
                                    (kIOBlitTypeCopyRegion | kIOBlitTypeOperationType0),
                                    kIOBlitSourceFramebuffer,
                                    &copyRegionProc);
        if (kIOReturnSuccess != err) continue;
        err = (*interface)->AllocateSurface(interface, kIOBlitHasCGSSurface, &dest, (void *) surfaceID);
        if (kIOReturnSuccess != err) continue;
        err = (*interface)->SetDestination(interface, kIOBlitSurfaceDestination, &dest);
        if (kIOReturnSuccess != err) continue;
        op.region = region;
        op.deltaX = 0;
        op.deltaY = 0;
        err = (*copyRegionProc)(interface,
                        kNilOptions,
                        (kIOBlitTypeCopyRegion | kIOBlitTypeOperationType0),
                        kIOBlitSourceFramebuffer,
                        &op.operation,
                        (void *) 0);
        if (kIOReturnSuccess != err) continue;
        (*interface)->Flush(interface, kNilOptions);
        err = IOAccelWriteLockSurfaceWithOptions(connect,
                kIOAccelSurfaceLockInBacking, &surfaceInfo, sizeof(surfaceInfo));
        if (kIOReturnSuccess != err) continue;
    
        (void ) IOAccelWriteUnlockSurfaceWithOptions(connect, kIOAccelSurfaceLockInBacking);
    }
    while (false);

    if (dest.interfaceRef) (*interface)->FreeSurface(interface, kIOBlitHasCGSSurface, &dest);

    // destroy the surface
    if (connect) (void) IOAccelDestroySurface(connect);

    if (region) free(region);

    if (interface) IODestroyPlugInInterface((IOCFPlugInInterface **)interface);

    if (kIOReturnSuccess == err) 
    {
        *result    = buffer;
        *bytecount = size;
    }

    return (err);
}
示例#11
0
TorcUSBDevice TorcUSBPrivOSX::GetDevice(io_service_t Device)
{
    TorcUSBDevice usbdevice;

    if (Device)
    {
        io_name_t buffer;
        IOReturn ok = IORegistryEntryGetName(Device, buffer);

        QString name = kIOReturnSuccess == ok ?  QString(buffer) : "Unknown";

        IOCFPlugInInterface **plugin;
        qint32 score;

        ok = IOCreatePlugInInterfaceForService(Device, kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &plugin, &score);
        if (kIOReturnSuccess == ok)
        {
            IOUSBDeviceInterface **interface;

            ok = (*plugin)->QueryInterface(plugin, CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID), (void**)&interface);
            if (kIOReturnSuccess == ok)
            {
                quint16  vendor;
                quint16  product;
                quint32  location;
                quint8   classtype;

                IOReturn vendorok    = (*interface)->GetDeviceVendor(interface, &vendor);
                IOReturn productok   = (*interface)->GetDeviceProduct(interface, &product);
                IOReturn locationok  = (*interface)->GetLocationID(interface, &location);
                IOReturn classtypeok = (*interface)->GetDeviceClass(interface, &classtype);

                if ((classtypeok == kIOReturnSuccess) && !TorcUSBDevice::IgnoreClass(ToTorcClass(classtype)))
                {
                    TorcUSBDevice::Classes torcclass = ToTorcClass(classtype);

                    io_service_t usbinterface;
                    io_iterator_t iterator;
                    IOUSBFindInterfaceRequest request;
                    request.bInterfaceClass    = kIOUSBFindInterfaceDontCare;
                    request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare;
                    request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare;
                    request.bAlternateSetting  = kIOUSBFindInterfaceDontCare;

                    ok = (*interface)->CreateInterfaceIterator(interface, &request, &iterator);

                    while ((ok == kIOReturnSuccess) && (usbinterface = IOIteratorNext(iterator)))
                    {
                        IOCFPlugInInterface **interfaceplugin;
                        if (kIOReturnSuccess == IOCreatePlugInInterfaceForService(usbinterface, kIOUSBInterfaceUserClientTypeID,
                                                                                  kIOCFPlugInInterfaceID, &interfaceplugin, &score))
                        {
                            IOUSBInterfaceInterface** interfaceinterface;
                            if (kIOReturnSuccess == (*interfaceplugin)->QueryInterface(interfaceplugin, CFUUIDGetUUIDBytes(kIOUSBInterfaceInterfaceID),
                                                                        (void**)&interfaceinterface))
                            {
                                QString path = locationok == kIOReturnSuccess ? QString::number(location) : "Error";

                                quint8 interfaceclass;
                                IOReturn result = (*interfaceinterface)->GetInterfaceClass(interfaceinterface, &interfaceclass);

                                if (result == kIOReturnSuccess)
                                {
                                    io_registry_entry_t parent;
                                    kern_return_t kernresult;
                                    kernresult = IORegistryEntryGetParentEntry(usbinterface, kIOServicePlane, &parent);
                                    if (kernresult == KERN_SUCCESS)
                                    {
                                        CFStringRef pathstring = (CFStringRef)IORegistryEntrySearchCFProperty(parent,
                                                kIOServicePlane, CFSTR(kIOCalloutDeviceKey), kCFAllocatorDefault, kIORegistryIterateRecursively);
                                        if (pathstring)
                                            path = CFStringReftoQString(pathstring);
                                        IOObjectRelease(parent);
                                    }
                                }

                                usbdevice = TorcUSBDevice(path, vendorok == kIOReturnSuccess ? vendor : 0,
                                                          productok == kIOReturnSuccess ? product : 0, torcclass);
                                usbdevice.m_product = name;
                            }

                            IODestroyPlugInInterface(interfaceplugin);
                        }

                        IOObjectRelease(usbinterface);
                    }
                }
            }

            IODestroyPlugInInterface(plugin);
        }
    }

    return usbdevice;
}
示例#12
0
/* this is where most of the getting magic happens.. */
static int get_cam_list(io_iterator_t devIter,
						uvccCam ***list)
{
	io_iterator_t ifIter;
	kern_return_t kr;
	int i, nDevs = 0, nCams = 0;
	uvccCam **tmp;
	io_service_t devSrv, ifSrv;			/* unsigned int */
	IOCFPlugInInterface **pIf;			/* needed to find the device interface */
	HRESULT qiRes;						/* int32_t */
	int32_t score;
	IOUSBDeviceInterface197 **devIf;	/* interface to communicate with the device */

	if(!uvcc_port)
	{
		fprintf(stderr, UVCC_INIT_ERROR_MSG);
		return -1;
	}
	/* get number of devices */
	while((IOIteratorNext(devIter)) != 0) nDevs++;
	if(!nDevs) return 0;
	IOIteratorReset(devIter);
	tmp = malloc(nDevs*sizeof(uvccCam *));
	while((devSrv = IOIteratorNext(devIter)))
	{
		kr = IOCreatePlugInInterfaceForService(devSrv, kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &pIf, &score);
		/* we're done with the devSrv */
		IOObjectRelease(devSrv);
		if(kr != kIOReturnSuccess)
		{
			uvcc_err("get_cam_list: IOCreatePlugInInterfaceForService", kr);
			IOObjectRelease(devSrv);
			continue;
		}
		qiRes = (*pIf)->QueryInterface(pIf, CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID197), (LPVOID)&devIf);
		/* we're done with the plugin */
		(*pIf)->Stop(pIf);
		IODestroyPlugInInterface(pIf);
		/* kIOReturnSuccess is actually just 0 but since QI strictly talking
		 returns HRESULT (int32_t) and not kern_return_t (int) i figured i'll
		 just do this here */
		if(!qiRes && devIf)
		{
			kr = (*devIf)->CreateInterfaceIterator(devIf, &vid_ctrl_if_req, &ifIter);
			if(kr != kIOReturnSuccess || !IOIteratorIsValid(ifIter))
			{
				uvcc_err("get_cam_list: CreateInterfaceIterator", kr);
				IOObjectRelease(devSrv);
				continue;
			}
			if((ifSrv = IOIteratorNext(ifIter)))
			{	/* we'll just use the first vid ctrl if we get */
				if((tmp[nCams] = malloc(sizeof(uvccCam))) == NULL)
				{
					if(!logger) perror("uvcc error! get_cam_list: Could not allocate memory for list entry");
                    else asl_log(logger, NULL, ASL_LEVEL_ERR, "get_cam_list: Could not allocate memory for list entry: %s", strerror(errno));
					IOObjectRelease(ifIter);
					(*devIf)->Release(devIf);
					IOObjectRelease(devSrv);
					break;
				}
				/* set the data.. */
				if((fill_cam_struct(devIf, tmp[nCams])) != 0)
				{
					(*devIf)->Release(devIf);
					IOObjectRelease(devSrv);
					continue;
				}
				/* get the registry name */
				set_cam_reg_name(devSrv, tmp[nCams]);
				nCams++;
				IOObjectRelease(ifSrv);
			}
			/* else: no vid_ctrl_iface, i.e. not cam */
			IOObjectRelease(ifIter);
		}
		else
		{
			if(!logger) perror("uvcc warning! get_cam_list: QueryInterface failed");
            else asl_log(logger, NULL, ASL_LEVEL_WARNING, "get_cam_list: QueryInterface failed: %s", strerror(errno));
		}
		IOObjectRelease(devSrv);
	}
	if(nCams > 0)
	{	/* only make the allocation if we got cams */
		(*list) = malloc(nCams*sizeof(uvccCam *));
		for(i = 0; i < nCams; i++) (*list)[i] = tmp[i];
	}
	free(tmp);
	return nCams;
}
示例#13
0
void init_usb ( ) 
{ 
   
   IOCFPlugInInterface **iface; io_service_t service;
   SInt32 score;
   void *thing;
   int i;
   IOUSBDeviceDescriptionRef desc   = IOUSBDeviceDescriptionCreateFromDefaults(kCFAllocatorDefault);
   IOUSBDeviceDescriptionSetSerialString(desc, CFSTR("MaliciousHackerService"));
   CFArrayRef usb_interfaces   = (CFArrayRef) IOUSBDeviceDescriptionCopyInterfaces(desc); 
   
   for(i=0; i < CFArrayGetCount(usb_interfaces); i++)
   {
      CFArrayRef arr1 = CFArrayGetValueAtIndex(usb_interfaces, i);
      if (CFArrayContainsValue(arr1, CFRangeMake(0,CFArrayGetCount(arr1)), CFSTR("PTP")))
      {
         printf("Found PTP interface\n");
         break; 
      }
   }
   
   IOUSBDeviceControllerRef controller;
   while (IOUSBDeviceControllerCreate(kCFAllocatorDefault, &controller))
   {
      printf("Unable to get USB device controller\n");
      sleep(3); 
   }
   
   IOUSBDeviceControllerSetDescription(controller, desc);
   CFMutableDictionaryRef match = IOServiceMatching("IOUSBDeviceInterface");
   CFMutableDictionaryRef dict = CFDictionaryCreateMutable(
     NULL,
     0,
     &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
   
   CFDictionarySetValue(dict, CFSTR("USBDeviceFunction"), CFSTR("PTP")); 
   CFDictionarySetValue(match, CFSTR("IOPropertyMatch"), dict);
   
   while(1) 
   {
      service = IOServiceGetMatchingService(kIOMasterPortDefault, match); 
      if (!service) 
      {
         printf("Didn't find, trying again\n"); sleep(1);
      }
      else
      {
         break; 
      }
   }
   assert(!IOCreatePlugInInterfaceForService( service,
                                             kIOSomethingPluginID, kIOCFPlugInInterfaceID, &iface,
                                             &score
                                             60 | Chapter 3: Stealing the Filesystem
                                             ));
   assert(!IOCreatePlugInInterfaceForService( service,
                                             kIOSomethingPluginID, kIOCFPlugInInterfaceID, &iface,
                                             &score
                                             ));
   assert(!((*iface)->QueryInterface)(iface,
                                      CFUUIDGetUUIDBytes(kIOSomeID), &thing));
   IOReturn (**table)(void *, ...) = *((void **) thing); /* printf("%p\n", table[0x10/4]); */
   /* open IOUSBDeviceInterfaceInterface                 */ (!table[0x10/4](thing, 0));
   /* set IOUSBDeviceInterfaceInterface class            */ (!table[0x2c/4](thing, 0xff, 0));
   /* set IOUSBDeviceInterfaceInterface sub-class        */ (!table[0x30/4](thing, 0x50, 0));
   /* set IOUSBDeviceInterfaceInterface protocol         */ (!table[0x34/4](thing, 0x43, 0));
   /* commit IOUSBDeviceInterfaceInterface configuration */ (!table[0x44/4](thing, 0));
   IODestroyPlugInInterface(iface); 
}
示例#14
0
int do_intf(io_service_t usbInterfaceRef)
{
    IOReturn err;
    IOCFPlugInInterface **iodev;
    SInt32 score;
    UInt8 numPipes;
    int i;
    UInt8 direction, number, transferType, interval;
    UInt16 maxPacketSize;
    
    err = IOCreatePlugInInterfaceForService(usbInterfaceRef, 
					    kIOUSBInterfaceUserClientTypeID, 
					    kIOCFPlugInInterfaceID, 
					    &iodev, &score);
    if( err || !iodev ) {
      fprintf( stderr, "unable to create plugin. ret = %08x, iodev = %p\n", err, iodev);
      return -1;
    }
    
    err = (*iodev)->QueryInterface(iodev, 
				   CFUUIDGetUUIDBytes(kIOUSBInterfaceInterfaceID),
				   (LPVOID)&intf);
    IODestroyPlugInInterface(iodev);
	
    if (err || !intf) {
      fprintf( stderr, "unable to create a device interface. ret = %08x, intf = %p\n", 
	     err, intf);
      return -1;
    }

    err = (*intf)->USBInterfaceOpen(intf);
    if (err) {
      fprintf( stderr, "unable to open interface. ret = %08x\n", err);
      return -1;
    }
    
    err = (*intf)->GetNumEndpoints(intf, &numPipes);
    if (err) {
      fprintf( stderr, "unable to get number of endpoints. ret = %08x\n", err);
      return -1;
    }

    if (numPipes) {
      for (i=1; i <= numPipes; i++) {
	
	err = (*intf)->GetPipeProperties(intf, i, &direction, 
					 &number, &transferType,
					 &maxPacketSize, &interval);
	if (err) {
	    fprintf( stderr, "unable to get pipe properties for pipe %d, err = %08x\n",
		   i, err);
	    continue;
	}

	if (transferType != kUSBBulk) {
	    continue;
	}
	
	if ((direction == kUSBIn) && !inPipeRef) {
	    inPipeRef = i;
	}
	if ((direction == kUSBOut) && !outPipeRef) {
	    outPipeRef = i;
	}
      }
    }

    if( !inPipeRef || !outPipeRef ) {
      (*intf)->USBInterfaceClose(intf);
      (*intf)->Release(intf);
      intf = NULL;
      return -1;
    }

    return 0;
}
示例#15
0
static int do_dev( io_service_t usbDeviceRef )
{   
  IOReturn err;
  IOCFPlugInInterface **iodev;		// requires <IOKit/IOCFPlugIn.h>
  SInt32 score;
  UInt8 numConf;
  IOUSBConfigurationDescriptorPtr confDesc;
  IOUSBFindInterfaceRequest interfaceRequest;
  io_iterator_t	iterator;
  io_service_t usbInterfaceRef;
  
  err = IOCreatePlugInInterfaceForService(usbDeviceRef, 
					  kIOUSBDeviceUserClientTypeID,
					  kIOCFPlugInInterfaceID, &iodev, &score);
  if (err || !iodev) {
    fprintf( stderr, "unable to create plugin. ret = %08x, iodev = %p\n",
	   err, iodev);
		return -1;
    }
  
  err = (*iodev)->QueryInterface(iodev, 
				 CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID),
				 (LPVOID)&usbDev);
  IODestroyPlugInInterface(iodev);				// done with this
  
  if (err || !usbDev) {
    fprintf( stderr, "unable to create a device interface. ret = %08x, dev = %p\n",
	   err, usbDev);
    return -1;
  }
  
  err = (*usbDev)->USBDeviceOpen(usbDev);
  if (err) {
    fprintf( stderr, "unable to open device. ret = %08x\n", err);
    return -1;
  }
  err = (*usbDev)->GetNumberOfConfigurations(usbDev, &numConf);
  if (err || !numConf) {
    fprintf( stderr, "unable to obtain the number of configurations. ret = %08x\n", err);
    return -1;
  }

  err = (*usbDev)->GetConfigurationDescriptorPtr(usbDev, 0, &confDesc);			// get the first config desc (index 0)
  if (err) {
      fprintf( stderr, "unable to get config descriptor for index 0\n");
      return -1;
  }
  

  err = (*usbDev)->SetConfiguration(usbDev, confDesc->bConfigurationValue);
  if (err) {
    fprintf( stderr, "unable to set the configuration\n");
    return -1;
  }

  // requested class
  interfaceRequest.bInterfaceClass = kIOUSBFindInterfaceDontCare;
  // requested subclass
  interfaceRequest.bInterfaceSubClass = kIOUSBFindInterfaceDontCare;		
  // requested protocol
  interfaceRequest.bInterfaceProtocol = kIOUSBFindInterfaceDontCare;		
  // requested alt setting
  interfaceRequest.bAlternateSetting = kIOUSBFindInterfaceDontCare;		
  
  err = (*usbDev)->CreateInterfaceIterator(usbDev, &interfaceRequest, &iterator);
  if (err) {
    fprintf( stderr, "unable to create interface iterator\n");
    return -1;
  }
    
  while( (usbInterfaceRef = IOIteratorNext(iterator)) ) {
    if( do_intf( usbInterfaceRef ) == 0 ) {
      IOObjectRelease(iterator);
      iterator = 0;
      return 0;
    }
  } 

    
  IOObjectRelease(iterator);
  iterator = 0;
  return -1;


}
示例#16
0
文件: main.cpp 项目: arnelh/Examples
int
main ( int argc, const char * argv[] ) 
{

	//
	// allocate our DMA buffers using vm_allocate
	//
	
	vm_address_t	buffer = nil ;
	::vm_allocate( mach_task_self(), & buffer, kBufferSize, true ) ;
	
	assert( buffer ) ;

	//
	// split up vm_allocated buffer into buffers we will use
	// in our DMA program
	//
	
	UInt8*	buffers[3] = { (UInt8*)buffer, (UInt8*)buffer + 1024, (UInt8*)buffer + 4096 } ;

	//
	// put test data into our DMA program buffers
	//
	
	snprintf( reinterpret_cast<char*>(buffers[0]), 1024, "sample text in a buffer" ) ;
	snprintf( reinterpret_cast<char*>(buffers[1]), 3048, "<this space intentionally left blank>" ) ;
	snprintf( reinterpret_cast<char*>(buffers[2]), 1024, "next sample text is here" ) ;

	//
	// run test
	//
	
	IOReturn	error 			= kIOReturnSuccess ;
	
	cout << i++ << "\n### SETTING UP\n" ;
	
	for( int index=0; index < 3; ++index )
		cout << i << "buffers[" << index << "] " << (char*)(buffers[index]) << endl ;
	
	cout << i++ << "Getting device interface...\n" ;

	IOFireWireLibNubRef				localNode		= 0 ;
	IOCFPlugInInterfaceRef			cfPlugInInterface ;

	error = GetDeviceInterface( & cfPlugInInterface, & localNode ) ;
	cout << i-- << "..." << _success << endl ;
			
	if ( !error )
	{
		cout << i << "Opening...\n" ;
		error = (**localNode).Open( localNode ) ;
	}
	
//	if (!error)
//	{
//		error = (**localNode).AddCallbackDispatcherToRunLoop( localNode, ::CFRunLoopGetCurrent() ) ;
//		if (!error)
//			(**localNode).TurnOnNotification( localNode ) ;
//	}

	if ( !error )
	{
		cout << i++ << "Adding isoch dispatcher to run loop...\n" ;

		error = (**localNode).AddIsochCallbackDispatcherToRunLoop( localNode, CFRunLoopGetCurrent() ) ;
	}
	
	
	IOFireWireLibDCLCommandPoolRef		commandPool 	= 0 ;
	IOFireWireLibRemoteIsochPortRef		remoteIsochPort	= 0 ;
	IOFireWireLibLocalIsochPortRef		localIsochPort	= 0 ;
	IOFireWireLibIsochChannelRef		isochChannel	= 0 ;
	
	if ( !error )
	{
		cout << i++ << "Creating DCL command pool...\n" ;
		error = CreateDCLCommandPool( localNode, & commandPool ) ;
	}
	
	if ( !error )
	{
		cout << i++ << "Creating remote isochronous port...\n" ;
		error = CreateRemoteIsochPort( localNode, & remoteIsochPort ) ;
		cout << i-- << "..." << _success << endl ;
	}
	
	if ( !error )
	{
		cout << i << "Creating local isoch port...\n" ;
		error = CreateLocalIsochPort( localNode, buffers, commandPool, & localIsochPort ) ;
		cout << i-- << "..." << _success << endl ;
	}

	if ( !error )
	{
		cout << i++ << "Creating isoch channel...\n" ;
		error = CreateIsochChannel( localNode, & isochChannel ) ;
		cout << i-- << "..." << _success << endl ;
	}
	
		// remote is listener
	if ( !error )
	{
		cout << i++ << "Adding listener to isoch channel...\n" ;
		error = (**isochChannel).AddListener( isochChannel, (IOFireWireLibIsochPortRef) remoteIsochPort ) ;
		cout << i-- << "..." << _success << endl ;
	}
	
		// local is talker
	if ( !error )
	{
		cout << i++ << "Setting talker on isoch channel...\n" ;
		error = (**isochChannel).SetTalker( isochChannel, (IOFireWireLibIsochPortRef) localIsochPort ) ;
		cout << i-- << "..." << _success << endl ;
	}
	
	if ( !error )
	{
		cout << i++ << "Allocating channel...\n" ;
		error = (**isochChannel).AllocateChannel( isochChannel ) ;
		cout << i-- << "..." << _success << endl ;
	}

	i-- ;	// unindent
	
	// run for approx. 15 seconds
	cout << i++ << "\n### RUNNING\n" ;

	if ( !error )
	{
		if ( !error )
		{
			cout << i++ << "Starting channel...\n" ;
			error = (**isochChannel).Start( isochChannel ) ;
			cout << i-- << "..." << _success << endl ;
		}
		
		cout << i << "\nRunning...\n" ;

		SInt16	runLoopResult ;
		while (  kCFRunLoopRunHandledSource == ( runLoopResult = CFRunLoopRunInMode( kCFRunLoopDefaultMode, 30, false ) ) ) 
		{
		}
		
		error = (**isochChannel).Stop( isochChannel ) ;
		
		cout << i-- << "done!\n" ;
				
		// clean up
		cout << i++ << "\n### CLEAN UP ###\n\n" ;
	
		// release all interfaces
		if ( isochChannel )
		{
			cout << i++ << "releasing isoch channel.\n" ;
	
			if ( error != kIOReturnSuccess )
				cout << i << _file << "error " << error << " stopping channel.\n" ;
			
			error = (**isochChannel).ReleaseChannel( isochChannel ) ;
			if ( error != kIOReturnSuccess )
				cout << i << _file << "error " << error << " from ReleaseChannel().\n" ;
	
			(**isochChannel).Release( isochChannel ) ;
			
			i-- ;
		}
			
		if ( localIsochPort )
		{
			cout << i << "releasing local port.\n" ;

			(**localIsochPort).Release( localIsochPort ) ;
		}
		
		if ( remoteIsochPort )
		{
			cout << i << "releasing remote port.\n" ;
			(**remoteIsochPort).Release( remoteIsochPort ) ;
		}
	}
	
	if ( localNode )
	{
		cout << i << "releasing local node interface.\n" ;
		(**localNode).Close( localNode ) ;
		(**localNode).Release( localNode ) ;
	}
	
	//
	// release the original CFPlugInInterface
	//
	
	if ( cfPlugInInterface )
	{
		cout << i << "releasing CFPlugInInterface.\n" ;
		IODestroyPlugInInterface( cfPlugInInterface ) ;
	}
	
	//
	// deallocate our DMA buffers
	//
	
	if (buffer)
	{
		::vm_deallocate( mach_task_self(), buffer, kBufferSize ) ;
	}
	
	cout << i << "### DONE\n" ;
	return (error == kIOReturnSuccess) ? EXIT_SUCCESS : EXIT_FAILURE ;
}
示例#17
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;
}
示例#18
0
文件: main.c 项目: a-page/IOUSBFamily
void dealWithInterface(io_service_t usbInterfaceRef)
{
    IOReturn					err;
    IOCFPlugInInterface 		**iodev;		// requires <IOKit/IOCFPlugIn.h>
    IOUSBInterfaceInterface245 	**intf;
    SInt32						score;
    UInt8						numPipes;


    err = IOCreatePlugInInterfaceForService(usbInterfaceRef, kIOUSBInterfaceUserClientTypeID, kIOCFPlugInInterfaceID, &iodev, &score);
    if (err || !iodev)
    {
		printf("dealWithInterface: unable to create plugin. ret = %08x, iodev = %p\n", err, iodev);
		return;
    }
    err = (*iodev)->QueryInterface(iodev, CFUUIDGetUUIDBytes(kIOUSBInterfaceInterfaceID245), (LPVOID)&intf);
	IODestroyPlugInInterface(iodev);				// done with this
	
    if (err || !intf)
    {
		printf("dealWithInterface: unable to create a device interface. ret = %08x, intf = %p\n", err, intf);
		return;
    }
    err = (*intf)->USBInterfaceOpen(intf);
    if (err)
    {
		printf("dealWithInterface: unable to open interface. ret = %08x\n", err);
		return;
    }
    err = (*intf)->GetNumEndpoints(intf, &numPipes);
    if (err)
    {
		printf("dealWithInterface: unable to get number of endpoints. ret = %08x\n", err);
		(*intf)->USBInterfaceClose(intf);
		(*intf)->Release(intf);
		return;
    }
    
    printf("dealWithInterface: found %d pipes\n", numPipes);
    if (numPipes == 0)
    {
		// try alternate setting 1
		err = (*intf)->SetAlternateInterface(intf, 1);
		if (err)
		{
			printf("dealWithInterface: unable to set alternate interface 1. ret = %08x\n", err);
			(*intf)->USBInterfaceClose(intf);
			(*intf)->Release(intf);
			return;
		}
		err = (*intf)->GetNumEndpoints(intf, &numPipes);
		if (err)
		{
			printf("dealWithInterface: unable to get number of endpoints - alt setting 1. ret = %08x\n", err);
			(*intf)->USBInterfaceClose(intf);
			(*intf)->Release(intf);
			return;
		}
		numPipes = 13;  		// workaround. GetNumEndpoints does not work after SetAlternateInterface
    }
    
    if (numPipes)
	dealWithPipes(intf, numPipes);
	
    err = (*intf)->USBInterfaceClose(intf);
    if (err)
    {
		printf("dealWithInterface: unable to close interface. ret = %08x\n", err);
		return;
    }
    err = (*intf)->Release(intf);
    if (err)
    {
		printf("dealWithInterface: unable to release interface. ret = %08x\n", err);
		return;
    }
}
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;

}
示例#20
0
文件: main.c 项目: a-page/IOUSBFamily
void dealWithDevice(io_service_t usbDeviceRef)
{
    IOReturn						err;
    IOCFPlugInInterface				**iodev;		// requires <IOKit/IOCFPlugIn.h>
    IOUSBDeviceInterface245			**dev;
    SInt32							score;
    UInt8							numConf;
    IOUSBConfigurationDescriptorPtr	confDesc;
    IOUSBFindInterfaceRequest		interfaceRequest;
    io_iterator_t					iterator;
    io_service_t					usbInterfaceRef;
    
    err = IOCreatePlugInInterfaceForService(usbDeviceRef, kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &iodev, &score);
    if (err || !iodev)
    {
		printf("dealWithDevice: unable to create plugin. ret = %08x, iodev = %p\n", err, iodev);
		return;
    }
    err = (*iodev)->QueryInterface(iodev, CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID245), (LPVOID)&dev);
	IODestroyPlugInInterface(iodev);				// done with this

    if (err || !dev)
    {
		printf("dealWithDevice: unable to create a device interface. ret = %08x, dev = %p\n", err, dev);
		return;
    }
    err = (*dev)->USBDeviceOpen(dev);
    if (err)
    {
		printf("dealWithDevice: unable to open device. ret = %08x\n", err);
		return;
    }
    err = (*dev)->GetNumberOfConfigurations(dev, &numConf);
    if (err || !numConf)
    {
		printf("dealWithDevice: unable to obtain the number of configurations. ret = %08x\n", err);
        (*dev)->USBDeviceClose(dev);
        (*dev)->Release(dev);
		return;
    }
    printf("dealWithDevice: found %d configurations\n", numConf);
    err = (*dev)->GetConfigurationDescriptorPtr(dev, 0, &confDesc);			// get the first config desc (index 0)
    if (err)
    {
		printf("dealWithDevice:unable to get config descriptor for index 0\n");
        (*dev)->USBDeviceClose(dev);
        (*dev)->Release(dev);
		return;
    }
    err = (*dev)->SetConfiguration(dev, confDesc->bConfigurationValue);
    if (err)
    {
		printf("dealWithDevice: unable to set the configuration\n");
        (*dev)->USBDeviceClose(dev);
        (*dev)->Release(dev);
		return;
    }
    
    interfaceRequest.bInterfaceClass = kIOUSBFindInterfaceDontCare;		// requested class
    interfaceRequest.bInterfaceSubClass = kIOUSBFindInterfaceDontCare;		// requested subclass
    interfaceRequest.bInterfaceProtocol = kIOUSBFindInterfaceDontCare;		// requested protocol
    interfaceRequest.bAlternateSetting = kIOUSBFindInterfaceDontCare;		// requested alt setting
    
    err = (*dev)->CreateInterfaceIterator(dev, &interfaceRequest, &iterator);
    if (err)
    {
		printf("dealWithDevice: unable to create interface iterator\n");
        (*dev)->USBDeviceClose(dev);
        (*dev)->Release(dev);
		return;
    }
    
    while ( (usbInterfaceRef = IOIteratorNext(iterator)) )
    {
		printf("found interface: %p\n", (void*)usbInterfaceRef);
		dealWithInterface(usbInterfaceRef);
		IOObjectRelease(usbInterfaceRef);				// no longer need this reference
    }
    
    IOObjectRelease(iterator);
    iterator = 0;

    err = (*dev)->USBDeviceClose(dev);
    if (err)
    {
		printf("dealWithDevice: error closing device - %08x\n", err);
		(*dev)->Release(dev);
		return;
    }
    err = (*dev)->Release(dev);
    if (err)
    {
		printf("dealWithDevice: error releasing device - %08x\n", err);
		return;
    }
}