void dumpIter( io_iterator_t iter, mach_port_t recvPort ) { kern_return_t kr; io_object_t obj; io_name_t name; io_string_t path; mach_port_t iter3; while( (obj = IOIteratorNext( iter))) { assert( KERN_SUCCESS == ( kr = IORegistryEntryGetName( obj, name ) )); printf("name:%s(%d)\n", name, obj); kr = IORegistryEntryGetPath( obj, kIOServicePlane, path ); if( KERN_SUCCESS == kr) { // if the object is detached, getPath will fail printf("path:%s\n", path); // as will IOServiceAddInterestNotification if( KERN_SUCCESS != ( kr = IOServiceAddInterestNotificationMsg( obj, kIOGeneralInterest, recvPort, (unsigned int) obj, &iter3) )) printf("IOServiceAddInterestNotification(%lx)\n", kr); // can compare two kernel objects with IOObjectIsEqualTo() if we keep the object, // otherwise, release IOObjectRelease( obj ); } } }
// makes a list of ATA or SCSI devices for the DEVICESCAN directive of // smartd. Returns number N of devices, or -1 if out of // memory. Allocates N+1 arrays: one of N pointers (devlist); the // other N arrays each contain null-terminated character strings. In // the case N==0, no arrays are allocated because the array of 0 // pointers has zero length, equivalent to calling malloc(0). int make_device_names (char*** devlist, const char* name) { IOReturn err; io_iterator_t i; io_object_t device = MACH_PORT_NULL; int result; int index; // We treat all devices as ATA so long as they support SMARTLib. if (strcmp (name, "ATA") != 0) return 0; err = IOServiceGetMatchingServices (kIOMasterPortDefault, IOServiceMatching (kIOBlockStorageDeviceClass), &i); if (err != kIOReturnSuccess) return -1; // Count the devices. result = 0; while ((device = IOIteratorNext (i)) != MACH_PORT_NULL) { if (is_smart_capable (device)) result++; IOObjectRelease (device); } // Create an array of service names. IOIteratorReset (i); *devlist = (char**)Calloc (result, sizeof (char *)); if (! *devlist) goto error; index = 0; while ((device = IOIteratorNext (i)) != MACH_PORT_NULL) { if (is_smart_capable (device)) { io_string_t devName; IORegistryEntryGetPath(device, kIOServicePlane, devName); (*devlist)[index] = CustomStrDup (devName, true, __LINE__, __FILE__); if (! (*devlist)[index]) goto error; index++; } IOObjectRelease (device); } IOObjectRelease (i); return result; error: if (device != MACH_PORT_NULL) IOObjectRelease (device); IOObjectRelease (i); if (*devlist) { for (index = 0; index < result; index++) if ((*devlist)[index]) FreeNonZero ((*devlist)[index], 0, __LINE__, __FILE__); FreeNonZero (*devlist, result * sizeof (char *), __LINE__, __FILE__); } return -1; }
struct usb_device_info *find_usb_devices(int (*match)(const struct usb_device_info*)) { struct usb_device_info *devlist = 0; struct usb_device_info devinfo; /*static const int vendor_id = 1133;*/ /* 3dconnexion */ static char dev_path[512]; io_object_t dev; io_iterator_t iter; CFMutableDictionaryRef match_dict; CFNumberRef number_ref; match_dict = IOServiceMatching(kIOHIDDeviceKey); /* add filter rule: vendor-id should be 3dconnexion's */ /*number_ref = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &vendor_id); CFDictionarySetValue(match_dict, CFSTR(kIOHIDVendorIDKey), number_ref); CFRelease(number_ref); */ /* fetch... */ if(IOServiceGetMatchingServices(kIOMasterPortDefault, match_dict, &iter) != kIOReturnSuccess) { fprintf(stderr, "failed to retrieve USB HID devices\n"); return 0; } while((dev = IOIteratorNext(iter))) { memset(&devinfo, 0, sizeof devinfo); IORegistryEntryGetPath(dev, kIOServicePlane, dev_path); if(!(devinfo.devfiles[0] = strdup(dev_path))) { perror("failed to allocate device file path buffer"); continue; } devinfo.num_devfiles = 1; /* TODO retrieve vendor id and product id */ if(!match || match(&devinfo)) { struct usb_device_info *node = malloc(sizeof *node); if(node) { if(verbose) { printf("found usb device: "); print_usb_device_info(&devinfo); } *node = devinfo; node->next = devlist; devlist = node; } else { free(devinfo.devfiles[0]); perror("failed to allocate usb device info node"); } } } IOObjectRelease(dev); IOObjectRelease(iter); return devlist; }
int main(int argc, char *argv[]) { char *path; kern_return_t ret; io_registry_entry_t entry = 0; io_string_t iopath; if(argc != 2) { fprintf(stderr, "Usage: %s disk1s1\n", getprogname()); exit(1); } path = argv[1]; // entry = IORegistryEntryFromPath(kIOMasterPortDefault, path); entry = IOServiceGetMatchingService(kIOMasterPortDefault, IOBSDNameMatching(kIOMasterPortDefault, 0, path)); printf("entry is %p\n", entry); if(entry == 0) exit(1); ret = IORegistryEntryGetPath(entry, kIOServicePlane, iopath); if(ret) { fprintf(stderr, "Could not get entry path\n"); exit(1); } printf("%s path: %s\n", kIOServicePlane, iopath); ret = IORegistryEntryGetPath(entry, kIODeviceTreePlane, iopath); if(ret) { fprintf(stderr, "Could not get entry path\n"); exit(1); } printf("%s path: %s\n", kIODeviceTreePlane, iopath); IOObjectRelease(entry); return 0; }
int main( int argc, char * argv[] ) { kern_return_t kr; io_service_t framebuffer, interface; IOOptionBits bus; IOItemCount busCount; framebuffer = CGDisplayIOServicePort(CGMainDisplayID()); { io_string_t path; kr = IORegistryEntryGetPath(framebuffer, kIOServicePlane, path); assert( KERN_SUCCESS == kr ); printf("\nUsing device: %s\n", path); kr = IOFBGetI2CInterfaceCount( framebuffer, &busCount ); assert( kIOReturnSuccess == kr ); for( bus = 0; bus < busCount; bus++ ) { IOI2CConnectRef connect; kr = IOFBCopyI2CInterfaceForBus(framebuffer, bus, &interface); if( kIOReturnSuccess != kr) continue; kr = IOI2CInterfaceOpen( interface, kNilOptions, &connect ); IOObjectRelease(interface); assert( kIOReturnSuccess == kr ); if( kIOReturnSuccess != kr) continue; printf("\nEDID using bus %ld:\n", bus); EDIDTest( connect ); printf("\niTV using bus %ld:\n", bus); iTVTest( connect ); IOI2CInterfaceClose( connect, kNilOptions ); } } exit(0); return(0); }
bool find_service(const char *target_name, io_connect_t *ptarget_port) { io_iterator_t iter; kern_return_t r = IOServiceGetMatchingServices(kIOMasterPortDefault, IOServiceMatching("IOService"), &iter); if (r != KERN_SUCCESS) { fprintf(stderr, " [!] IOServiceGetMatchingServices() failed\n"); return -1; } io_object_t service; while ((service = IOIteratorNext(iter)) != IO_OBJECT_NULL) { /* Get service name */ io_name_t name; r = IORegistryEntryGetName(service, name); if (r != KERN_SUCCESS) { fprintf(stderr, " [!] IORegistryEntryGetName() failed\n"); IOObjectRelease(service); continue; } io_string_t path; r = IORegistryEntryGetPath(service, "IOService", path); /* Try to open service */ io_connect_t port = (io_connect_t) 0; r = IOServiceOpen(service, mach_task_self(), 0, &port); IOObjectRelease(service); if (r != kIOReturnSuccess) { continue; } if (strstr(name, target_name)) { printf(" [+] Found service %s\n", name); *ptarget_port = port; return true; } IOServiceClose(port); } return false; }
// gets the parent's Udi from an entry static QString getParentDeviceUdi(const io_registry_entry_t &entry) { io_registry_entry_t parent = 0; kern_return_t ret = IORegistryEntryGetParentEntry(entry, kIOServicePlane, &parent); if (ret != KERN_SUCCESS) { // don't release parent here - docs say only on success return QString(); } QString result; io_string_t pathName; ret = IORegistryEntryGetPath(parent, kIOServicePlane, pathName); if (ret == KERN_SUCCESS) result = QString::fromUtf8(pathName); // now we can release the parent IOObjectRelease(parent); return result; }
int main() { mach_port_t masterPort; io_iterator_t iter = 0; io_service_t service = 0; kern_return_t ret; io_string_t path; ret = IOMasterPort(MACH_PORT_NULL, &masterPort); if (ret != KERN_SUCCESS) { printf("error: IOMasterPort returned 0x%08x\n", ret); goto failure; } ret = IOServiceGetMatchingServices(masterPort, IOServiceMatching(kVoodooHDAClassName), &iter); if (ret != KERN_SUCCESS) { printf("error: IOServiceGetMatchingServices returned 0x%08x\n", ret); goto failure; } while ((service = IOIteratorNext(iter)) != 0) { ret = IORegistryEntryGetPath(service, kIOServicePlane, path); if (ret != KERN_SUCCESS) { printf("error: IORegistryEntryGetPath returned 0x%08x\n", ret); goto failure; } printf("Found a device of class "kVoodooHDAClassName": %s\n\n", path); printMsgBuffer(service); IOObjectRelease(service); } failure: if (service) IOObjectRelease(service); if (iter) IOObjectRelease(iter); return 0; }
bool QextSerialEnumerator::getServiceDetailsOSX( io_object_t service, QextPortInfo* portInfo ) { bool retval = true; CFTypeRef bsdPathAsCFString = NULL; CFTypeRef productNameAsCFString = NULL; CFTypeRef vendorIdAsCFNumber = NULL; CFTypeRef productIdAsCFNumber = NULL; // check the name of the modem's callout device bsdPathAsCFString = IORegistryEntryCreateCFProperty(service, CFSTR(kIOCalloutDeviceKey), kCFAllocatorDefault, 0); // wander up the hierarchy until we find the level that can give us the // vendor/product IDs and the product name, if available io_registry_entry_t parent; kern_return_t kernResult = IORegistryEntryGetParentEntry(service, kIOServicePlane, &parent); while( kernResult == KERN_SUCCESS && !vendorIdAsCFNumber && !productIdAsCFNumber ) { if(!productNameAsCFString) productNameAsCFString = IORegistryEntrySearchCFProperty(parent, kIOServicePlane, CFSTR("Product Name"), kCFAllocatorDefault, 0); vendorIdAsCFNumber = IORegistryEntrySearchCFProperty(parent, kIOServicePlane, CFSTR(kUSBVendorID), kCFAllocatorDefault, 0); productIdAsCFNumber = IORegistryEntrySearchCFProperty(parent, kIOServicePlane, CFSTR(kUSBProductID), kCFAllocatorDefault, 0); io_registry_entry_t oldparent = parent; kernResult = IORegistryEntryGetParentEntry(parent, kIOServicePlane, &parent); IOObjectRelease(oldparent); } io_string_t ioPathName; IORegistryEntryGetPath( service, kIOServicePlane, ioPathName ); portInfo->physName = ioPathName; if( bsdPathAsCFString ) { char path[MAXPATHLEN]; if( CFStringGetCString((CFStringRef)bsdPathAsCFString, path, PATH_MAX, kCFStringEncodingUTF8) ) portInfo->portName = path; CFRelease(bsdPathAsCFString); } if(productNameAsCFString) { char productName[MAXPATHLEN]; if( CFStringGetCString((CFStringRef)productNameAsCFString, productName, PATH_MAX, kCFStringEncodingUTF8) ) portInfo->friendName = productName; CFRelease(productNameAsCFString); } if(vendorIdAsCFNumber) { SInt32 vID; if(CFNumberGetValue((CFNumberRef)vendorIdAsCFNumber, kCFNumberSInt32Type, &vID)) portInfo->vendorID = vID; CFRelease(vendorIdAsCFNumber); } if(productIdAsCFNumber) { SInt32 pID; if(CFNumberGetValue((CFNumberRef)productIdAsCFNumber, kCFNumberSInt32Type, &pID)) portInfo->productID = pID; CFRelease(productIdAsCFNumber); } IOObjectRelease(service); return retval; }
struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, unsigned short product_id) { struct hid_device_info *root = NULL; /* return object */ struct hid_device_info *cur_dev = NULL; CFIndex num_devices; int i; /* Set up the HID Manager if it hasn't been done */ if (hid_init() < 0) return NULL; /* give the IOHIDManager a chance to update itself */ process_pending_events(); /* Get a list of the Devices */ IOHIDManagerSetDeviceMatching(hid_mgr, NULL); CFSetRef device_set = IOHIDManagerCopyDevices(hid_mgr); /* Convert the list into a C array so we can iterate easily. */ num_devices = CFSetGetCount(device_set); IOHIDDeviceRef *device_array = calloc(num_devices, sizeof(IOHIDDeviceRef)); CFSetGetValues(device_set, (const void **) device_array); /* Iterate over each device, making an entry for it. */ for (i = 0; i < num_devices; i++) { unsigned short dev_vid; unsigned short dev_pid; #define BUF_LEN 256 wchar_t buf[BUF_LEN]; IOHIDDeviceRef dev = device_array[i]; if (!dev) { continue; } dev_vid = get_vendor_id(dev); dev_pid = get_product_id(dev); /* Check the VID/PID against the arguments */ if ((vendor_id == 0x0 || vendor_id == dev_vid) && (product_id == 0x0 || product_id == dev_pid)) { struct hid_device_info *tmp; io_object_t iokit_dev; kern_return_t res; io_string_t path; /* VID/PID match. Create the record. */ tmp = malloc(sizeof(struct hid_device_info)); if (cur_dev) { cur_dev->next = tmp; } else { root = tmp; } cur_dev = tmp; /* Get the Usage Page and Usage for this device. */ cur_dev->usage_page = get_int_property(dev, CFSTR(kIOHIDPrimaryUsagePageKey)); cur_dev->usage = get_int_property(dev, CFSTR(kIOHIDPrimaryUsageKey)); /* Fill out the record */ cur_dev->next = NULL; /* Fill in the path (IOService plane) */ iokit_dev = hidapi_IOHIDDeviceGetService(dev); res = IORegistryEntryGetPath(iokit_dev, kIOServicePlane, path); if (res == KERN_SUCCESS) cur_dev->path = strdup(path); else cur_dev->path = strdup(""); /* Serial Number */ get_serial_number(dev, buf, BUF_LEN); cur_dev->serial_number = dup_wcs(buf); /* Manufacturer and Product strings */ get_manufacturer_string(dev, buf, BUF_LEN); cur_dev->manufacturer_string = dup_wcs(buf); get_product_string(dev, buf, BUF_LEN); cur_dev->product_string = dup_wcs(buf); /* VID/PID */ cur_dev->vendor_id = dev_vid; cur_dev->product_id = dev_pid; /* Release Number */ cur_dev->release_number = get_int_property(dev, CFSTR(kIOHIDVersionNumberKey)); /* Interface Number (Unsupported on Mac)*/ cur_dev->interface_number = -1; } } free(device_array); CFRelease(device_set); return root; }
//================================================================================================ // // DeviceAdded // // This routine is the callback for our IOServiceAddMatchingNotification. When we get called // we will look at all the devices that were added and we will: // // 1. Create some private data to relate to each device (in this case we use the service's name // and the location ID of the device // 2. Submit an IOServiceAddInterestNotification of type kIOGeneralInterest for this device, // using the refCon field to store a pointer to our private data. When we get called with // this interest notification, we can grab the refCon and access our private data. // //================================================================================================ static void DeviceAdded(void *refCon, io_iterator_t iterator) { kern_return_t kr; io_service_t usbDevice; IOCFPlugInInterface **plugInInterface = NULL; SInt32 score; HRESULT res; while((usbDevice = IOIteratorNext(iterator))) { io_name_t deviceName; CFStringRef deviceNameAsCFString; UInt32 locationID; UInt16 vendorId; UInt16 productId; UInt16 addr; DeviceItem_t* deviceItem = new DeviceItem_t(); // Get the USB device's name. kr = IORegistryEntryGetName(usbDevice, deviceName); if(KERN_SUCCESS != kr) { deviceName[0] = '\0'; } deviceNameAsCFString = CFStringCreateWithCString(kCFAllocatorDefault, deviceName, kCFStringEncodingASCII); if(deviceNameAsCFString) { Boolean result; char deviceName[MAXPATHLEN]; // Convert from a CFString to a C (NUL-terminated) result = CFStringGetCString(deviceNameAsCFString, deviceName, sizeof(deviceName), kCFStringEncodingUTF8); if(result) { deviceItem->deviceParams.deviceName = deviceName; } CFRelease(deviceNameAsCFString); } CFStringRef manufacturerAsCFString = (CFStringRef)IORegistryEntrySearchCFProperty( usbDevice, kIOServicePlane, CFSTR(kUSBVendorString), kCFAllocatorDefault, kIORegistryIterateRecursively ); if(manufacturerAsCFString) { Boolean result; char manufacturer[MAXPATHLEN]; // Convert from a CFString to a C (NUL-terminated) result = CFStringGetCString( manufacturerAsCFString, manufacturer, sizeof(manufacturer), kCFStringEncodingUTF8 ); if(result) { deviceItem->deviceParams.manufacturer = manufacturer; } CFRelease(manufacturerAsCFString); } CFStringRef serialNumberAsCFString = (CFStringRef) IORegistryEntrySearchCFProperty( usbDevice, kIOServicePlane, CFSTR(kUSBSerialNumberString), kCFAllocatorDefault, kIORegistryIterateRecursively ); if(serialNumberAsCFString) { Boolean result; char serialNumber[MAXPATHLEN]; // Convert from a CFString to a C (NUL-terminated) result = CFStringGetCString( serialNumberAsCFString, serialNumber, sizeof(serialNumber), kCFStringEncodingUTF8 ); if(result) { deviceItem->deviceParams.serialNumber = serialNumber; } CFRelease(serialNumberAsCFString); } // Now, get the locationID of this device. In order to do this, we need to create an IOUSBDeviceInterface // for our device. This will create the necessary connections between our userland application and the // kernel object for the USB Device. kr = IOCreatePlugInInterfaceForService(usbDevice, kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &plugInInterface, &score); if((kIOReturnSuccess != kr) || !plugInInterface) { fprintf(stderr, "IOCreatePlugInInterfaceForService returned 0x%08x.\n", kr); continue; } stDeviceListItem *deviceListItem = new stDeviceListItem(); // Use the plugin interface to retrieve the device interface. res = (*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID), (LPVOID*) &deviceListItem->deviceInterface); // Now done with the plugin interface. (*plugInInterface)->Release(plugInInterface); if(res || deviceListItem->deviceInterface == NULL) { fprintf(stderr, "QueryInterface returned %d.\n", (int) res); continue; } // Now that we have the IOUSBDeviceInterface, we can call the routines in IOUSBLib.h. // In this case, fetch the locationID. The locationID uniquely identifies the device // and will remain the same, even across reboots, so long as the bus topology doesn't change. kr = (*deviceListItem->deviceInterface)->GetLocationID(deviceListItem->deviceInterface, &locationID); if(KERN_SUCCESS != kr) { fprintf(stderr, "GetLocationID returned 0x%08x.\n", kr); continue; } std::stringstream sstream; sstream << std::hex << locationID; deviceItem->deviceParams.locationId = sstream.str(); kr = (*deviceListItem->deviceInterface)->GetDeviceAddress(deviceListItem->deviceInterface, &addr); if(KERN_SUCCESS != kr) { fprintf(stderr, "GetDeviceAddress returned 0x%08x.\n", kr); continue; } deviceItem->deviceParams.deviceAddress = addr; kr = (*deviceListItem->deviceInterface)->GetDeviceVendor(deviceListItem->deviceInterface, &vendorId); if(KERN_SUCCESS != kr) { fprintf(stderr, "GetDeviceVendor returned 0x%08x.\n", kr); continue; } deviceItem->deviceParams.vendorId = vendorId; kr = (*deviceListItem->deviceInterface)->GetDeviceProduct(deviceListItem->deviceInterface, &productId); if(KERN_SUCCESS != kr) { fprintf(stderr, "GetDeviceProduct returned 0x%08x.\n", kr); continue; } deviceItem->deviceParams.productId = productId; // Extract path name as unique key io_string_t pathName; IORegistryEntryGetPath(usbDevice, kIOServicePlane, pathName); deviceNameAsCFString = CFStringCreateWithCString(kCFAllocatorDefault, pathName, kCFStringEncodingASCII); char cPathName[MAXPATHLEN]; if(deviceNameAsCFString) { Boolean result; // Convert from a CFString to a C (NUL-terminated) result = CFStringGetCString( deviceNameAsCFString, cPathName, sizeof(cPathName), kCFStringEncodingUTF8 ); CFRelease(deviceNameAsCFString); } AddItemToList(cPathName, deviceItem); deviceListItem->deviceItem = deviceItem; if(initialDeviceImport == false) { WaitForDeviceHandled(); currentItem = &deviceItem->deviceParams; isAdded = true; uv_async_send(&async_handler); } // Register for an interest notification of this device being removed. Use a reference to our // private data as the refCon which will be passed to the notification callback. kr = IOServiceAddInterestNotification( gNotifyPort, // notifyPort usbDevice, // service kIOGeneralInterest, // interestType DeviceRemoved, // callback deviceListItem, // refCon &(deviceListItem->notification) // notification ); if(KERN_SUCCESS != kr) { printf("IOServiceAddInterestNotification returned 0x%08x.\n", kr); } // Done with this USB device; release the reference added by IOIteratorNext kr = IOObjectRelease(usbDevice); } }
void genIOKitDevice(const io_service_t& device, const io_service_t& parent, const io_name_t plane, int depth, QueryData& results) { Row r; io_name_t name, device_class; auto kr = IORegistryEntryGetName(device, name); if (kr == KERN_SUCCESS) { r["name"] = std::string(name); } // Get the device class. kr = IOObjectGetClass(device, device_class); if (kr == KERN_SUCCESS) { r["class"] = std::string(device_class); } // The entry into the registry is the ID, and is used for children as parent. uint64_t device_id, parent_id; kr = IORegistryEntryGetRegistryEntryID(device, &device_id); if (kr == KERN_SUCCESS) { r["id"] = BIGINT(device_id); } else { r["id"] = "-1"; } kr = IORegistryEntryGetRegistryEntryID(parent, &parent_id); if (kr == KERN_SUCCESS) { r["parent"] = BIGINT(parent_id); } else { r["parent"] = "-1"; } r["depth"] = INTEGER(depth); if (IORegistryEntryInPlane(device, kIODeviceTreePlane)) { io_string_t device_path; kr = IORegistryEntryGetPath(device, kIODeviceTreePlane, device_path); if (kr == KERN_SUCCESS) { // Remove the "IODeviceTree:" from the device tree path. r["device_path"] = std::string(device_path).substr(13); } } // Fill in service bits and busy/latency time. if (IOObjectConformsTo(device, "IOService")) { r["service"] = "1"; } else { r["service"] = "0"; } uint32_t busy_state; kr = IOServiceGetBusyState(device, &busy_state); if (kr == KERN_SUCCESS) { r["busy_state"] = INTEGER(busy_state); } else { r["busy_state"] = "0"; } auto retain_count = IOObjectGetKernelRetainCount(device); r["retain_count"] = INTEGER(retain_count); results.push_back(r); }
int main(int argc, char * argv[]) { kern_return_t kr; io_iterator_t iter; io_service_t framebuffer; io_string_t path; uint32_t index, maxIndex; io_connect_t connect; mach_timebase_info_data_t timebase; StdFBShmem_t * shmem[16]; vm_size_t shmemSize; CFNumberRef clk, count; vm_address_t mapAddr; kr = IOServiceGetMatchingServices(kIOMasterPortDefault, IOServiceMatching( IOFRAMEBUFFER_CONFORMSTO), &iter); assert( KERN_SUCCESS == kr ); for ( index = 0; index++, (framebuffer = IOIteratorNext(iter)); IOObjectRelease(framebuffer)) { kr = IORegistryEntryGetPath(framebuffer, kIOServicePlane, path); assert( KERN_SUCCESS == kr ); printf("\n/* [%d] Using device: %s */\n", index, path); clk = IORegistryEntryCreateCFProperty(framebuffer, CFSTR(kIOFBCurrentPixelClockKey), kCFAllocatorDefault, kNilOptions); count = IORegistryEntryCreateCFProperty(framebuffer, CFSTR(kIOFBCurrentPixelCountKey), kCFAllocatorDefault, kNilOptions); if (clk && count) { float num, div; CFNumberGetValue(clk, kCFNumberFloatType, &num); CFNumberGetValue(count, kCFNumberFloatType, &div); printf("clock %.0f, count %.0f, rate %f Hz, period %f us\n", num, div, num / div, div * 1000 / num); } if (clk) CFRelease(clk); if (count) CFRelease(count); kr = mach_timebase_info(&timebase); assert(kIOReturnSuccess == kr); kr = IOServiceOpen(framebuffer, mach_task_self(), kIOFBSharedConnectType, &connect); if (kIOReturnSuccess != kr) { printf("IOServiceOpen(%x)\n", kr); continue; } kr = IOConnectMapMemory(connect, kIOFBCursorMemory, mach_task_self(), &mapAddr, &shmemSize, kIOMapAnywhere); if (kIOReturnSuccess != kr) { printf("IOConnectMapMemory(%x)\n", kr); continue; } shmem[index] = (StdFBShmem_t *) mapAddr; // bzero( shmem, shmemSize); // make sure its read only! printf("screenBounds (%d, %d), (%d, %d)\n", shmem[index]->screenBounds.minx, shmem[index]->screenBounds.miny, shmem[index]->screenBounds.maxx, shmem[index]->screenBounds.maxy); } maxIndex = index; while (true) { printf("\n"); for (index = 0; index < maxIndex; index++) { if (!shmem[index]) continue; uint64_t time = (((uint64_t) shmem[index]->vblTime.hi) << 32 | shmem[index]->vblTime.lo); uint64_t delta = (((uint64_t) shmem[index]->vblDelta.hi) << 32 | shmem[index]->vblDelta.lo); double usecs = delta * timebase.numer / timebase.denom / 1e6; if (!delta) continue; printf("[%d] time of last VBL 0x%qx, delta %qd (%f us), count %qd, measured delta %qd(%f%%), drift %qd(%qd%%)\n", index, time, delta, usecs, shmem[index]->vblCount, shmem[index]->vblDeltaMeasured, ((shmem[index]->vblDeltaMeasured * 100.0) / delta), shmem[index]->vblDrift, ((shmem[index]->vblDrift * 100) / delta)); } for (index = 0; index < maxIndex; index++) { if (!shmem[index]) continue; if ((shmem[index]->screenBounds.maxx - shmem[index]->screenBounds.minx) < 128) continue; printf("[%d] cursorShow %d, hw %d, frame %d, loc (%d, %d), hs (%d, %d), cursorRect (%d, %d), (%d, %d), saveRect (%d, %d), (%d, %d)\n", index, shmem[index]->cursorShow, shmem[index]->hardwareCursorActive, shmem[index]->frame, shmem[index]->cursorLoc.x, shmem[index]->cursorLoc.y, shmem[index]->hotSpot[0].x, shmem[index]->hotSpot[0].y, shmem[index]->cursorRect.minx, shmem[index]->cursorRect.miny, shmem[index]->cursorRect.maxx, shmem[index]->cursorRect.maxy, shmem[index]->saveRect.minx, shmem[index]->saveRect.miny, shmem[index]->saveRect.maxx, shmem[index]->saveRect.maxy); } sleep(1); } exit(0); return(0); }
// first look up the media object, then create a // custom matching dictionary that should be persistent // from boot to boot int addMatchingInfoForBSDName(BLContextPtr context, mach_port_t masterPort, CFMutableDictionaryRef dict, const char *bsdName, bool shortForm) { io_service_t media = IO_OBJECT_NULL, checkMedia = IO_OBJECT_NULL; CFStringRef uuid = NULL; CFMutableDictionaryRef propDict = NULL; kern_return_t kret; CFStringRef lastBSDName = NULL; lastBSDName = CFStringCreateWithCString(kCFAllocatorDefault, bsdName, kCFStringEncodingUTF8); propDict = IOBSDNameMatching(masterPort, 0, bsdName); CFDictionarySetValue(propDict, CFSTR(kIOProviderClassKey), CFSTR(kIOMediaClass)); media = IOServiceGetMatchingService(masterPort, propDict); propDict = NULL; if(media == IO_OBJECT_NULL) { contextprintf(context, kBLLogLevelError, "Could not find object for %s\n", bsdName); CFRelease(lastBSDName); return 1; } uuid = IORegistryEntryCreateCFProperty(media, CFSTR(kIOMediaUUIDKey), kCFAllocatorDefault, 0); if(uuid == NULL) { CFUUIDRef fsuuid = NULL; CFStringRef fsuuidstr = NULL; io_string_t path; #if USE_DISKARBITRATION DASessionRef session = NULL; DADiskRef dadisk = NULL; contextprintf(context, kBLLogLevelVerbose, "IOMedia %s does not have a partition %s\n", bsdName, kIOMediaUUIDKey); session = DASessionCreate(kCFAllocatorDefault); if(session) { dadisk = DADiskCreateFromIOMedia(kCFAllocatorDefault, session, media); if(dadisk) { CFDictionaryRef descrip = DADiskCopyDescription(dadisk); if(descrip) { fsuuid = CFDictionaryGetValue(descrip, kDADiskDescriptionVolumeUUIDKey); if(fsuuid) CFRetain(fsuuid); CFRelease(descrip); } CFRelease(dadisk); } CFRelease(session); } #endif // USE_DISKARBITRATION if(fsuuid) { char fsuuidCString[64]; fsuuidstr = CFUUIDCreateString(kCFAllocatorDefault, fsuuid); CFStringGetCString(fsuuidstr,fsuuidCString,sizeof(fsuuidCString),kCFStringEncodingUTF8); contextprintf(context, kBLLogLevelVerbose, "DADiskRef %s has Volume UUID %s\n", bsdName, fsuuidCString); CFRelease(fsuuid); } else { contextprintf(context, kBLLogLevelVerbose, "IOMedia %s does not have a Volume UUID\n", bsdName); } // we have a volume UUID, but our primary matching mechanism will be the device path kret = IORegistryEntryGetPath(media, kIODeviceTreePlane,path); if(kret) { contextprintf(context, kBLLogLevelVerbose, "IOMedia %s does not have device tree path\n", bsdName); propDict = IOServiceMatching(kIOMediaClass); CFDictionaryAddValue(propDict, CFSTR(kIOBSDNameKey), lastBSDName); // add UUID as hint if(fsuuidstr) CFDictionaryAddValue(dict, CFSTR("BLVolumeUUID"), fsuuidstr); } else { CFStringRef blpath = CFStringCreateWithCString(kCFAllocatorDefault, path, kCFStringEncodingUTF8); contextprintf(context, kBLLogLevelVerbose, "IOMedia %s has path %s\n", bsdName, path); propDict = IOServiceMatching(kIOMediaClass); CFDictionaryAddValue(propDict, CFSTR(kIOPathMatchKey), blpath); CFRelease(blpath); // add UUID as hint if(fsuuidstr) CFDictionaryAddValue(dict, CFSTR("BLVolumeUUID"), fsuuidstr); CFDictionaryAddValue(dict, CFSTR("BLLastBSDName"), lastBSDName); } if(fsuuidstr) { CFRelease(fsuuidstr); } } else { CFMutableDictionaryRef propMatch; contextprintf(context, kBLLogLevelVerbose, "IOMedia %s has UUID %s\n", bsdName, BLGetCStringDescription(uuid)); propMatch = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFDictionaryAddValue(propMatch, CFSTR(kIOMediaUUIDKey), uuid); propDict = IOServiceMatching(kIOMediaClass); CFDictionaryAddValue(propDict, CFSTR(kIOPropertyMatchKey), propMatch); CFRelease(propMatch); // add a hint to the top-level dict CFDictionaryAddValue(dict, CFSTR("BLLastBSDName"), lastBSDName); CFRelease(uuid); } // verify the dictionary matches CFRetain(propDict); // consumed below checkMedia = IOServiceGetMatchingService(masterPort, propDict); if(IO_OBJECT_NULL == checkMedia || !IOObjectIsEqualTo(media, checkMedia)) { contextprintf(context, kBLLogLevelVerbose, "Inconsistent registry entries for %s\n", bsdName); if(IO_OBJECT_NULL != checkMedia) IOObjectRelease(checkMedia); IOObjectRelease(media); CFRelease(lastBSDName); CFRelease(propDict); return 2; } IOObjectRelease(checkMedia); IOObjectRelease(media); CFDictionaryAddValue(dict, CFSTR("IOMatch"), propDict); CFRelease(lastBSDName); CFRelease(propDict); if(shortForm) { CFDictionaryAddValue(dict, CFSTR("IOEFIShortForm"), kCFBooleanTrue); } return 0; }
int main(int argc, char * argv[]) { kern_return_t kr; io_iterator_t iter; io_service_t framebuffer; io_string_t path; uint32_t index; CFIndex idx; IODisplayModeInformation * modeInfo; IODetailedTimingInformationV2 *timingInfo; CFDictionaryRef dict; CFArrayRef modes; CFIndex count; CFDictionaryRef mode; CFDataRef data; CFNumberRef num; kr = IOServiceGetMatchingServices(kIOMasterPortDefault, IOServiceMatching( IOFRAMEBUFFER_CONFORMSTO), &iter); assert( KERN_SUCCESS == kr ); for ( index = 0; index++, (framebuffer = IOIteratorNext(iter)); IOObjectRelease(framebuffer)) { kr = IORegistryEntryGetPath(framebuffer, kIOServicePlane, path); assert( KERN_SUCCESS == kr ); fprintf(stderr, "\n%s\n", path); dict = IORegistryEntryCreateCFProperty(framebuffer, CFSTR(kIOFBConfigKey), kCFAllocatorDefault, kNilOptions); if (!dict) continue; modes = CFDictionaryGetValue(dict, CFSTR(kIOFBModesKey)); assert(modes); count = CFArrayGetCount(modes); for (idx = 0; idx < count; idx++) { mode = CFArrayGetValueAtIndex(modes, idx); data = CFDictionaryGetValue(mode, CFSTR(kIOFBModeDMKey)); if (!data) continue; modeInfo = (IODisplayModeInformation *) CFDataGetBytePtr(data); data = CFDictionaryGetValue(mode, CFSTR(kIOFBModeTMKey)); if (!data) continue; timingInfo = (IODetailedTimingInformationV2 *) CFDataGetBytePtr(data); IODisplayModeID modeID = 0; num = CFDictionaryGetValue(mode, CFSTR(kIOFBModeIDKey)); if (num) CFNumberGetValue(num, kCFNumberSInt32Type, &modeID ); printf("0x%x: %d x %d %d Hz - %d x %d - flags 0x%x\n", modeID, modeInfo->nominalWidth, modeInfo->nominalHeight, ((modeInfo->refreshRate + 0x8000) >> 16), modeInfo->imageWidth, modeInfo->imageHeight, modeInfo->flags); if (argc > 1) { printf(" horizontalScaledInset %d\n", timingInfo->horizontalScaledInset); printf(" verticalScaledInset %d\n", timingInfo->verticalScaledInset); printf(" scalerFlags 0x%x\n", timingInfo->scalerFlags); printf(" horizontalScaled %d\n", timingInfo->horizontalScaled); printf(" verticalScaled %d\n", timingInfo->verticalScaled); printf(" pixelClock %lld\n", timingInfo->pixelClock); printf(" minPixelClock %lld\n", timingInfo->minPixelClock); printf(" maxPixelClock %lld\n", timingInfo->maxPixelClock); printf(" horizontalActive %d\n", timingInfo->horizontalActive); printf(" horizontalBlanking %d\n", timingInfo->horizontalBlanking); printf(" horizontalSyncOffset %d\n", timingInfo->horizontalSyncOffset); printf(" horizontalSyncPulseWidth %d\n", timingInfo->horizontalSyncPulseWidth); printf(" verticalActive %d\n", timingInfo->verticalActive); printf(" verticalBlanking %d\n", timingInfo->verticalBlanking); printf(" verticalSyncOffset %d\n", timingInfo->verticalSyncOffset); printf(" verticalSyncPulseWidth %d\n", timingInfo->verticalSyncPulseWidth); printf(" horizontalBorderLeft %d\n", timingInfo->horizontalBorderLeft); printf(" horizontalBorderRight %d\n", timingInfo->horizontalBorderRight); printf(" verticalBorderTop %d\n", timingInfo->verticalBorderTop); printf(" verticalBorderBottom %d\n", timingInfo->verticalBorderBottom); printf(" horizontalSyncConfig %d\n", timingInfo->horizontalSyncConfig); printf(" horizontalSyncLevel %d\n", timingInfo->horizontalSyncLevel); printf(" verticalSyncConfig 0x%x\n", timingInfo->verticalSyncConfig); printf(" verticalSyncLevel %d\n", timingInfo->verticalSyncLevel); printf(" signalConfig 0x%x\n", timingInfo->signalConfig); printf(" signalLevels %d\n", timingInfo->signalLevels); printf(" numLinks %d\n", timingInfo->numLinks); } } CFRelease(dict); } IOObjectRelease(iter); exit(0); return(0); }
int main( int argc, char * argv[] ) { mach_port_t masterPort; io_iterator_t iter; io_service_t service; kern_return_t kr; CFMutableDictionaryRef properties; CFStringRef cfStr; kr = IOMasterPort( MACH_PORT_NULL, &masterPort); assert( KERN_SUCCESS == kr ); // Look up the object we wish to open. This example uses simple class // matching (IOServiceMatching()) to look up the object that is the // AppleSamplePCI driver class instantiated by the kext. kr = IOServiceGetMatchingServices( masterPort, IOServiceMatching( kAppleSamplePCIClassName ), &iter); assert( KERN_SUCCESS == kr ); for( ; (service = IOIteratorNext(iter)); IOObjectRelease(service)) { io_string_t path; kr = IORegistryEntryGetPath(service, kIOServicePlane, path); assert( KERN_SUCCESS == kr ); printf("Found a device of class "kAppleSamplePCIClassName": %s\n", path); // print the value of kIONameMatchedKey property, as an example of // getting properties from the registry. Property based access // doesn't require a user client connection. // grab a copy of the properties kr = IORegistryEntryCreateCFProperties( service, &properties, kCFAllocatorDefault, kNilOptions ); assert( KERN_SUCCESS == kr ); cfStr = CFDictionaryGetValue( properties, CFSTR(kIONameMatchedKey) ); if( cfStr) { const char * c = NULL; char * buffer = NULL; c = CFStringGetCStringPtr(cfStr, kCFStringEncodingMacRoman); if(!c) { CFIndex bufferSize = CFStringGetLength(cfStr) + 1; buffer = malloc(bufferSize); if(buffer) { if(CFStringGetCString(cfStr, buffer, bufferSize, kCFStringEncodingMacRoman)) c = buffer; } } if(c) printf("it matched on name \"%s\"\n", c); if(buffer) free(buffer); } CFRelease( properties ); // test out the user client Test( masterPort, service ); } IOObjectRelease(iter); exit(0); return(0); }