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); } } }
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; }
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; }
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; }
int ipod_scsi_inquiry(struct ipod_t* ipod, int page_code, unsigned char* buf, int bufsize) { /* OS X doesn't allow to simply send out a SCSI inquiry request but * requires registering an interface handler first. * Currently this is done on each inquiry request which is somewhat * inefficient but the current ipodpatcher API doesn't really fit here. * Based on the documentation in Apple's document * "SCSI Architecture Model Device Interface Guide". * * WARNING: this code currently doesn't take the selected device into * account. It simply looks for an Ipod on the system and uses * the first match. */ (void)ipod; int result = 0; /* first, create a dictionary to match the device. This is needed to get the * service. */ CFMutableDictionaryRef match_dict; match_dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, NULL, NULL); if(match_dict == NULL) return -1; /* set value to match. In case of the Ipod this is "iPodUserClientDevice". */ CFMutableDictionaryRef sub_dict; sub_dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, NULL, NULL); CFDictionarySetValue(sub_dict, CFSTR(kIOPropertySCSITaskDeviceCategory), CFSTR("iPodUserClientDevice")); CFDictionarySetValue(match_dict, CFSTR(kIOPropertyMatchKey), sub_dict); if(sub_dict == NULL) return -1; /* get an iterator for searching for the service. */ kern_return_t kr; io_iterator_t iterator = IO_OBJECT_NULL; /* get matching services from IO registry. Consumes one reference to * the dictionary, so no need to release that. */ kr = IOServiceGetMatchingServices(kIOMasterPortDefault, match_dict, &iterator); if(!iterator | (kr != kIOReturnSuccess)) return -1; /* get interface and obtain exclusive access */ SInt32 score; HRESULT herr; kern_return_t err; IOCFPlugInInterface **plugin_interface = NULL; SCSITaskDeviceInterface **interface = NULL; io_service_t device = IO_OBJECT_NULL; device = IOIteratorNext(iterator); err = IOCreatePlugInInterfaceForService(device, kIOSCSITaskDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &plugin_interface, &score); if(err != noErr) { return -1; } /* query the plugin interface for task interface */ herr = (*plugin_interface)->QueryInterface(plugin_interface, CFUUIDGetUUIDBytes(kIOSCSITaskDeviceInterfaceID), (LPVOID*)&interface); if(herr != S_OK) { IODestroyPlugInInterface(plugin_interface); return -1; } err = (*interface)->ObtainExclusiveAccess(interface); if(err != noErr) { (*interface)->Release(interface); IODestroyPlugInInterface(plugin_interface); return -1; } /* do the inquiry */ SCSITaskInterface **task = NULL; task = (*interface)->CreateSCSITask(interface); if(task != NULL) { kern_return_t err; SCSITaskStatus task_status; IOVirtualRange* range; SCSI_Sense_Data sense_data; SCSICommandDescriptorBlock cdb; UInt64 transfer_count = 0; memset(buf, 0, bufsize); /* allocate virtual range for buffer. */ range = (IOVirtualRange*) malloc(sizeof(IOVirtualRange)); memset(&sense_data, 0, sizeof(sense_data)); memset(cdb, 0, sizeof(cdb)); /* set up range. address is buffer address, length is request size. */ range->address = (IOVirtualAddress)buf; range->length = bufsize; /* setup CDB */ cdb[0] = 0x12; /* inquiry */ cdb[1] = 1; cdb[2] = page_code; cdb[4] = bufsize; /* set cdb in task */ err = (*task)->SetCommandDescriptorBlock(task, cdb, kSCSICDBSize_6Byte); if(err != kIOReturnSuccess) { result = -1; goto cleanup; } err = (*task)->SetScatterGatherEntries(task, range, 1, bufsize, kSCSIDataTransfer_FromTargetToInitiator); if(err != kIOReturnSuccess) { result = -1; goto cleanup; } /* set timeout */ err = (*task)->SetTimeoutDuration(task, 10000); if(err != kIOReturnSuccess) { result = -1; goto cleanup; } /* request data */ err = (*task)->ExecuteTaskSync(task, &sense_data, &task_status, &transfer_count); if(err != kIOReturnSuccess) { result = -1; goto cleanup; } /* cleanup */ free(range); /* release task interface */ (*task)->Release(task); } else { result = -1; } cleanup: /* cleanup interface */ (*interface)->ReleaseExclusiveAccess(interface); (*interface)->Release(interface); IODestroyPlugInInterface(plugin_interface); return result; }
void BulkTestDeviceAdded(void *refCon, io_iterator_t iterator) { kern_return_t kr; io_service_t usbDevice; IOCFPlugInInterface **plugInInterface=NULL; IOUSBDeviceInterface245 **dev=NULL; HRESULT res; SInt32 score; UInt16 vendor; UInt16 product; UInt16 release; while ( (usbDevice = IOIteratorNext(iterator)) ) { printf("Bulk test device added.\n"); kr = IOCreatePlugInInterfaceForService(usbDevice, kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &plugInInterface, &score); kr = IOObjectRelease(usbDevice); // done with the device object now that I have the plugin if ((kIOReturnSuccess != kr) || !plugInInterface) { printf("unable to create a plugin (%08x)\n", kr); continue; } // I have the device plugin, I need the device interface res = (*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID245), (LPVOID)&dev); IODestroyPlugInInterface(plugInInterface); // done with this if (res || !dev) { printf("couldn't create a device interface (%08x)\n", (int) res); continue; } // technically should check these kr values kr = (*dev)->GetDeviceVendor(dev, &vendor); kr = (*dev)->GetDeviceProduct(dev, &product); kr = (*dev)->GetDeviceReleaseNumber(dev, &release); if ((vendor != kOurVendorID) || (product != kOurProductIDBulkTest) || (release != 1)) { // We should never get here because the matching criteria we specified above // will return just those devices with our vendor and product IDs printf("found device i didn't want (vendor = %d, product = %d)\n", vendor, product); (*dev)->Release(dev); continue; } // need to open the device in order to change its state kr = (*dev)->USBDeviceOpen(dev); if (kIOReturnSuccess != kr) { printf("unable to open device: %08x\n", kr); (*dev)->Release(dev); continue; } kr = ConfigureAnchorDevice(dev); if (kIOReturnSuccess != kr) { printf("unable to configure device: %08x\n", kr); (*dev)->USBDeviceClose(dev); (*dev)->Release(dev); continue; } kr = FindInterfaces(dev); if (kIOReturnSuccess != kr) { printf("unable to find interfaces on device: %08x\n", kr); (*dev)->USBDeviceClose(dev); (*dev)->Release(dev); continue; } #ifndef USE_ASYNC_IO kr = (*dev)->USBDeviceClose(dev); kr = (*dev)->Release(dev); #endif } }
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; }
/* 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; }
/** 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; }
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, ©RegionProc); 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); }
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; }
/* 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; }
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); }
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; }
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; }
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 ; }
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; }
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; }
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; } }