/* * Check whether an IORegistryEntry refers to a valid * I/O device, and if so, collect the information. */ static int handle_drive(io_registry_entry_t drive, struct drivestats * dstat) { io_registry_entry_t parent; CFMutableDictionaryRef properties; CFStringRef name; CFNumberRef number; kern_return_t status; /* get drive's parent */ status = IORegistryEntryGetParentEntry(drive, kIOServicePlane, &parent); if (status != KERN_SUCCESS) { snmp_log(LOG_ERR, "diskio: device has no parent\n"); /* fprintf(stderr, "device has no parent\n"); */ return(1); } if (IOObjectConformsTo(parent, "IOBlockStorageDriver")) { /* get drive properties */ status = IORegistryEntryCreateCFProperties(drive, &properties, kCFAllocatorDefault, kNilOptions); if (status != KERN_SUCCESS) { snmp_log(LOG_ERR, "diskio: device has no properties\n"); /* fprintf(stderr, "device has no properties\n"); */ return(1); } /* get BSD name and unitnumber from properties */ name = (CFStringRef)CFDictionaryGetValue(properties, CFSTR(kIOBSDNameKey)); number = (CFNumberRef)CFDictionaryGetValue(properties, CFSTR(kIOBSDUnitKey)); /* Collect stats and if succesful store them with the name and unitnumber */ if (name && number && !collect_drive_stats(parent, dstat->stats)) { CFStringGetCString(name, dstat->name, MAXDRIVENAME, CFStringGetSystemEncoding()); CFNumberGetValue(number, kCFNumberSInt32Type, &dstat->bsd_unit_number); num_drives++; } /* clean up, return success */ CFRelease(properties); return(0); } /* failed, don't keep parent */ IOObjectRelease(parent); return(1); }
CFDictionaryRef myIORegistryEntryBSDNameMatchingCopyValue(const char * devname, Boolean parent) { kern_return_t status; CFMutableDictionaryRef properties = NULL; io_registry_entry_t service; service = IOServiceGetMatchingService(kIOMasterPortDefault, IOBSDNameMatching(kIOMasterPortDefault, 0, devname)); if (service == MACH_PORT_NULL) { return (NULL); } if (parent) { io_registry_entry_t parent_service; status = IORegistryEntryGetParentEntry(service, kIOServicePlane, &parent_service); if (status == KERN_SUCCESS) { status = IORegistryEntryCreateCFProperties(parent_service, &properties, kCFAllocatorDefault, kNilOptions); IOObjectRelease(parent_service); } } else { status = IORegistryEntryCreateCFProperties(service, &properties, kCFAllocatorDefault, kNilOptions); } if (status != KERN_SUCCESS) { properties = NULL; } IOObjectRelease(service); return (properties); }
int IdlePlatform::secondsIdle() { mach_port_t masterPort; io_iterator_t iter; io_registry_entry_t curObj; IOMasterPort(MACH_PORT_NULL, &masterPort); IOServiceGetMatchingServices(masterPort, IOServiceMatching("IOHIDSystem"), &iter); if (iter == 0) return -1; curObj = IOIteratorNext(iter); if (curObj == 0) return -1; CFMutableDictionaryRef properties = 0; CFTypeRef obj; int result = -1; if (IORegistryEntryCreateCFProperties(curObj, &properties, kCFAllocatorDefault, 0) == KERN_SUCCESS && properties != NULL) { obj = CFDictionaryGetValue(properties, CFSTR("HIDIdleTime")); CFRetain(obj); } else obj = NULL; if (obj) { uint64_t tHandle; CFTypeID type = CFGetTypeID(obj); if (type == CFDataGetTypeID()) CFDataGetBytes((CFDataRef) obj, CFRangeMake(0, sizeof(tHandle)), (UInt8*) &tHandle); else if (type == CFNumberGetTypeID()) CFNumberGetValue((CFNumberRef)obj, kCFNumberSInt64Type, &tHandle); else return -1; CFRelease(obj); // essentially divides by 10^9 tHandle >>= 30; result = tHandle; } /* Release our resources */ IOObjectRelease(curObj); IOObjectRelease(iter); CFRelease((CFTypeRef)properties); return result; }
// gets all properties from an entry into a QMap static QMap<QString, QVariant> getProperties(const io_registry_entry_t &entry) { CFMutableDictionaryRef propertyDict = 0; if (IORegistryEntryCreateCFProperties(entry, &propertyDict, kCFAllocatorDefault, kNilOptions) != KERN_SUCCESS) { return QMap<QString, QVariant>(); } QMap<QString, QVariant> result = q_toVariantMap(propertyDict); CFRelease(propertyDict); return result; }
void OSX_ReadCDTOC(io_object_t cdobject) { CFMutableDictionaryRef cd_props = 0; CFDataRef cdTOCdata = NULL; char* cdTOCrawdata = NULL; if (IORegistryEntryCreateCFProperties(cdobject, &cd_props, kCFAllocatorDefault, kNilOptions) != kIOReturnSuccess) return; cdTOCdata = (CFDataRef)CFDictionaryGetValue(cd_props, CFSTR (kIOCDMediaTOCKey)); if (cdTOCdata != NULL) { Extract_cdTOCrawdata(cdTOCdata, cdTOCrawdata); } CFRelease(cd_props); cd_props = NULL; return; }
IOReturn SATSMARTClient::Probe ( CFDictionaryRef propertyTable, io_service_t inService, SInt32 * order ) { CFMutableDictionaryRef dict = NULL; IOReturn status = kIOReturnBadArgument; PRINT ( ( "SATSMARTClient::Probe called\n" ) ); // Sanity check if ( inService == 0 ) { goto Exit; } status = IORegistryEntryCreateCFProperties ( inService, &dict, NULL, 0 ); if ( status != kIOReturnSuccess ) { goto Exit; } if ( !CFDictionaryContainsKey ( dict, CFSTR ( "IOCFPlugInTypes" ) ) ) { goto Exit; } status = kIOReturnSuccess; Exit: if ( dict != NULL ) { CFRelease ( dict ); dict = NULL; } PRINT ( ( "SATSMARTClient::Probe called %x\n",status ) ); return status; }
void genPCIDevice(const io_service_t& device, QueryData& results) { Row r; // Get the device details CFMutableDictionaryRef details; IORegistryEntryCreateCFProperties( device, &details, kCFAllocatorDefault, kNilOptions); r["pci_slot"] = getIOKitProperty(details, "pcidebug"); std::vector<std::string> properties; auto compatible = getIOKitProperty(details, "compatible"); boost::trim(compatible); boost::split(properties, compatible, boost::is_any_of(" ")); if (properties.size() < 2) { VLOG(1) << "Error parsing IOKit compatible properties"; return; } size_t prop_index = 0; if (properties[1].find("pci") == 0 && properties[1].find("pciclass") != 0) { // There are two sets of PCI definitions. prop_index = 1; } else if (properties[0].find("pci") != 0) { VLOG(1) << "No vendor/model found"; return; } std::vector<std::string> vendor; boost::split(vendor, properties[prop_index++], boost::is_any_of(",")); r["vendor_id"] = vendor[0].substr(3); r["model_id"] = (vendor[1].size() == 3) ? "0" + vendor[1] : vendor[1]; if (properties[prop_index].find("pciclass") == 0) { // There is a class definition. r["pci_class"] = properties[prop_index++].substr(9); } if (properties.size() > prop_index) { // There is a driver/ID. r["driver"] = properties[prop_index]; } results.push_back(r); CFRelease(details); }
/* * Determine whether an IORegistryEntry refers to a valid * I/O device, and if so, record it. */ static int record_device(io_registry_entry_t drive) { io_registry_entry_t parent; CFDictionaryRef properties; CFStringRef name; CFNumberRef number; kern_return_t status; /* get drive's parent */ status = IORegistryEntryGetParentEntry(drive, kIOServicePlane, &parent); if (status != KERN_SUCCESS) errx(1, "device has no parent"); if (IOObjectConformsTo(parent, "IOBlockStorageDriver")) { drivestat[num_devices].driver = parent; /* get drive properties */ status = IORegistryEntryCreateCFProperties(drive, (CFMutableDictionaryRef *)&properties, kCFAllocatorDefault, kNilOptions); if (status != KERN_SUCCESS) errx(1, "device has no properties"); /* get name from properties */ name = (CFStringRef)CFDictionaryGetValue(properties, CFSTR(kIOBSDNameKey)); CFStringGetCString(name, drivestat[num_devices].name, MAXDRIVENAME, CFStringGetSystemEncoding()); /* get blocksize from properties */ number = (CFNumberRef)CFDictionaryGetValue(properties, CFSTR(kIOMediaPreferredBlockSizeKey)); CFNumberGetValue(number, kCFNumberSInt64Type, &drivestat[num_devices].blocksize); /* clean up, return success */ CFRelease(properties); num_devices++; return(0); } /* failed, don't keep parent */ IOObjectRelease(parent); return(1); }
void genFDEStatusForBSDName(const std::string& bsd_name, const std::string& uuid, QueryData& results) { auto matching_dict = IOBSDNameMatching(kIOMasterPortDefault, kNilOptions, bsd_name.c_str()); if (matching_dict == nullptr) { return; } auto service = IOServiceGetMatchingService(kIOMasterPortDefault, matching_dict); if (!service) { return; } CFMutableDictionaryRef properties; if (IORegistryEntryCreateCFProperties( service, &properties, kCFAllocatorDefault, kNilOptions) != KERN_SUCCESS) { IOObjectRelease(service); return; } Row r; r["name"] = kDeviceNamePrefix + bsd_name; r["uuid"] = uuid; auto encrypted = getIOKitProperty(properties, kCoreStorageIsEncryptedKey_); if (encrypted.empty()) { r["encrypted"] = "0"; } else { r["encrypted"] = encrypted; id_t uid; uuid_string_t uuid_string = {0}; if (genUid(uid, uuid_string).ok()) { r["uid"] = BIGINT(uid); r["user_uuid"] = TEXT(uuid_string); } } r["type"] = (r.at("encrypted") == "1") ? kEncryptionType : std::string(); results.push_back(r); CFRelease(properties); IOObjectRelease(service); }
static PyObject *pyidle_get(PyIdle *self, PyObject *args, PyObject *kwargs) { CFMutableDictionaryRef props; CFTypeRef obj; uint64_t idleTime; CFTypeID type; int ret; if ((ret = IORegistryEntryCreateCFProperties(self->regEntry, &props, kCFAllocatorDefault, 0)) != kIOReturnSuccess) { PyErr_Format(PyExc_RuntimeError, "IORegistryEntryCreateCFProperties failed: %d", ret); return NULL; } obj = CFDictionaryGetValue(props, CFSTR("HIDIdleTime")); CFRetain(obj); type = CFGetTypeID(obj); if (type == CFDataGetTypeID()) { CFDataGetBytes((CFDataRef)obj, CFRangeMake(0, sizeof(idleTime)), (UInt8*)&idleTime); } else if (type == CFNumberGetTypeID()) { CFNumberGetValue((CFNumberRef)obj, kCFNumberSInt64Type, &idleTime); } else { PyErr_Format(PyExc_RuntimeError, "Unsupported type: %d", (int)type); CFRelease(obj); CFRelease((CFTypeRef)props); return NULL; } CFRelease(obj); CFRelease(props); return Py_BuildValue("L", idleTime >> 30); }
long idleTime() { long idlesecs; #ifdef LINUX bool _idleDetectionPossible; XScreenSaverInfo *_mit_info; int event_base, error_base; if(XScreenSaverQueryExtension(QX11Info::display(), &event_base, &error_base)) _idleDetectionPossible = true; else _idleDetectionPossible = false; _mit_info = XScreenSaverAllocInfo(); XScreenSaverQueryInfo(QX11Info::display(), QX11Info::appRootWindow(), _mit_info); idlesecs = (_mit_info->idle/1000); #endif #ifdef WINDOWS LASTINPUTINFO lif; lif.cbSize = sizeof(LASTINPUTINFO); GetLastInputInfo(&lif); DWORD tickCount = GetTickCount(); idlesecs = (tickCount - lif.dwTime) / 1000; #endif #ifdef MAC idlesecs = -1;//int64_t io_iterator_t iter = 0; if (IOServiceGetMatchingServices(kIOMasterPortDefault, IOServiceMatching("IOHIDSystem"), &iter) == KERN_SUCCESS) { io_registry_entry_t entry = IOIteratorNext(iter); if (entry) { CFMutableDictionaryRef dict = NULL; if (IORegistryEntryCreateCFProperties(entry, &dict, kCFAllocatorDefault, 0) == KERN_SUCCESS) { CFNumberRef obj = (CFNumberRef)CFDictionaryGetValue(dict, CFSTR("HIDIdleTime")); if (obj) { int64_t nanoseconds = 0; if (CFNumberGetValue(obj, kCFNumberSInt64Type, &nanoseconds)) { idlesecs = (nanoseconds >> 30); // Divide by 10^9 to convert from nanoseconds to seconds. } } CFRelease(dict); }
void genPCIDevice(const io_service_t& device, QueryData& results) { Row r; // Get the device details CFMutableDictionaryRef details; IORegistryEntryCreateCFProperties( device, &details, kCFAllocatorDefault, kNilOptions); r["pci_slot"] = getIOKitProperty(details, "pcidebug"); auto compatible = getIOKitProperty(details, "compatible"); auto properties = IOKitPCIProperties(compatible); r["vendor_id"] = properties.vendor_id; r["model_id"] = properties.model_id; r["pci_class"] = properties.pci_class; r["driver"] = properties.driver; results.push_back(r); CFRelease(details); }
CFDictionaryRef myIORegistryEntryCopyValue(const char * path) { io_registry_entry_t service; kern_return_t status; CFMutableDictionaryRef properties = NULL; service = IORegistryEntryFromPath(kIOMasterPortDefault, path); if (service == MACH_PORT_NULL) { return (NULL); } status = IORegistryEntryCreateCFProperties(service, &properties, kCFAllocatorDefault, kNilOptions); if (status != KERN_SUCCESS) { properties = NULL; } IOObjectRelease(service); return (properties); }
static IOReturn PrintSpeedForDisc ( io_object_t opticalMedia ) { IOReturn error = kIOReturnError; CFMutableDictionaryRef properties = NULL; CFStringRef bsdNode = NULL; const char * bsdName = NULL; error = IORegistryEntryCreateCFProperties ( opticalMedia, &properties, kCFAllocatorDefault, kNilOptions ); require ( ( error == kIOReturnSuccess ), ErrorExit ); bsdNode = ( CFStringRef ) CFDictionaryGetValue ( properties, CFSTR ( kIOBSDNameKey ) ); require ( ( bsdNode != NULL ), ReleaseProperties ); bsdName = CFStringGetCStringPtr ( bsdNode, CFStringGetSystemEncoding ( ) ); require ( ( bsdName != NULL ), ReleaseProperties ); error = PrintSpeedForBSDNode ( bsdName ); require ( ( error == kIOReturnSuccess ), ReleaseProperties ); ReleaseProperties: require_quiet ( ( properties != NULL ), ErrorExit ); CFRelease ( properties ); properties = NULL; ErrorExit: return error; }
void genUSBDevice(const io_service_t& device, QueryData& results) { Row r; // Get the device details CFMutableDictionaryRef details; IORegistryEntryCreateCFProperties( device, &details, kCFAllocatorDefault, kNilOptions); r["usb_address"] = getUSBProperty(details, "USB Address"); r["usb_port"] = getUSBProperty(details, "PortNum"); r["model"] = getUSBProperty(details, "USB Product Name"); r["model_id"] = getUSBProperty(details, "idProduct"); r["vendor"] = getUSBProperty(details, "USB Vendor Name"); r["vendor_id"] = getUSBProperty(details, "idVendor"); r["serial"] = getUSBProperty(details, "iSerialNumber"); auto non_removable = getUSBProperty(details, "non-removable"); r["removable"] = (non_removable == "yes") ? "0" : "1"; results.push_back(r); CFRelease(details); }
int main(int argc, char **argv) { mach_port_t masterPort; io_registry_entry_t root; CFDictionaryRef props; kern_return_t status; // Obtain the I/O Kit communication handle. status = IOMasterPort(bootstrap_port, &masterPort); assert(status == KERN_SUCCESS); // Obtain the registry root entry. root = IORegistryGetRootEntry(masterPort); assert(root); status = IORegistryEntryCreateCFProperties(root, (CFTypeRef *) &props, kCFAllocatorDefault, kNilOptions ); assert( KERN_SUCCESS == status ); assert( CFDictionaryGetTypeID() == CFGetTypeID(props)); props = (CFDictionaryRef) CFDictionaryGetValue( props, CFSTR(kIOKitDiagnosticsKey)); assert( props ); assert( CFDictionaryGetTypeID() == CFGetTypeID(props)); printNumber(props, CFSTR("Instance allocation")); printNumber(props, CFSTR("Container allocation")); printNumber(props, CFSTR("IOMalloc allocation")); CFRelease(props); IOObjectRelease(root); exit(0); }
Status genUnlockIdent(CFDataRef& uuid) { auto chosen = IORegistryEntryFromPath(kIOMasterPortDefault, kIODeviceTreeChosenPath_); if (chosen == MACH_PORT_NULL) { return Status(1, "Could not open IOKit DeviceTree"); } CFMutableDictionaryRef properties = nullptr; auto kr = IORegistryEntryCreateCFProperties( chosen, &properties, kCFAllocatorDefault, kNilOptions); IOObjectRelease(chosen); if (kr != KERN_SUCCESS) { return Status(1, "Could not get IOKit chosen properties"); } if (properties == nullptr) { return Status(1, "Could not load IOKit properties"); } CFTypeRef unlock_ident = nullptr; if (CFDictionaryGetValueIfPresent( properties, CFSTR("efilogin-unlock-ident"), &unlock_ident)) { if (CFGetTypeID(unlock_ident) != CFDataGetTypeID()) { return Status(1, "Unexpected data type for unlock ident"); } uuid = CFDataCreateCopy(kCFAllocatorDefault, (CFDataRef)unlock_ident); if (uuid == nullptr) { return Status(1, "Could not get UUID"); } CFRelease(properties); return Status(0, "ok"); } return Status(1, "Could not get unlock ident"); }
/** * \brief List of CD/DVD devices * * On Unix, this returns a list of /dev nodes which can be open()d. * Darwin doesn't have fixed devices for removables/pluggables, * so this method is actually useless as it stands. * In the long term, this method should return both a name, * and an opaque type? (for the IOKit io_object_t) */ QStringList MediaMonitorDarwin::GetCDROMBlockDevices() { kern_return_t kernResult; CFMutableDictionaryRef devices; io_iterator_t iter; QStringList list; QString msg = QString("GetCDRomBlockDevices() - "); devices = IOServiceMatching(kIOBlockStorageDeviceClass); if (!devices) { LOG(VB_GENERAL, LOG_ALERT, msg + "No Storage Devices? Unlikely!"); return list; } // Create an iterator across all parents of the service object passed in. kernResult = IOServiceGetMatchingServices(sMasterPort, devices, &iter); if (KERN_SUCCESS != kernResult) { LOG(VB_GENERAL, LOG_ALERT, msg + QString("IORegistryEntryCreateIterator returned %1") .arg(kernResult)); return list; } if (!iter) { LOG(VB_GENERAL, LOG_ALERT, msg + "IORegistryEntryCreateIterator returned a NULL iterator"); return list; } io_object_t drive; while ((drive = IOIteratorNext(iter))) { CFMutableDictionaryRef p = NULL; // properties of drive IORegistryEntryCreateCFProperties(drive, &p, kCFAllocatorDefault, 0); if (p) { const void *type = CFDictionaryGetValue(p, CFSTR("device-type")); if (CFEqual(type, CFSTR("DVD")) || CFEqual(type, CFSTR("CD"))) { QString desc = getModel(drive); list.append(desc); LOG(VB_MEDIA, LOG_INFO, desc.prepend("Found CD/DVD: ")); CFRelease(p); } } else LOG(VB_GENERAL, LOG_ALERT, msg + "Could not retrieve drive properties"); IOObjectRelease(drive); } IOObjectRelease(iter); return list; }
static void devstats(int perf_select, long double etime, int havelast) { CFNumberRef number; CFDictionaryRef properties; CFDictionaryRef statistics; long double transfers_per_second; long double kb_per_transfer, mb_per_second; u_int64_t value; u_int64_t total_bytes, total_transfers, total_blocks, total_time; u_int64_t interval_bytes, interval_transfers, interval_blocks; u_int64_t interval_time; long double interval_mb; long double blocks_per_second, ms_per_transaction; kern_return_t status; int i; for (i = 0; i < num_devices; i++) { /* * If the drive goes away, we may not get any properties * for it. So take some defaults. */ total_bytes = 0; total_transfers = 0; total_time = 0; /* get drive properties */ status = IORegistryEntryCreateCFProperties(drivestat[i].driver, (CFMutableDictionaryRef *)&properties, kCFAllocatorDefault, kNilOptions); if (status != KERN_SUCCESS) err(1, "device has no properties"); /* get statistics from properties */ statistics = (CFDictionaryRef)CFDictionaryGetValue(properties, CFSTR(kIOBlockStorageDriverStatisticsKey)); if (statistics) { /* * Get I/O volume. */ if ((number = (CFNumberRef)CFDictionaryGetValue(statistics, CFSTR(kIOBlockStorageDriverStatisticsBytesReadKey)))) { CFNumberGetValue(number, kCFNumberSInt64Type, &value); total_bytes += value; } if ((number = (CFNumberRef)CFDictionaryGetValue(statistics, CFSTR(kIOBlockStorageDriverStatisticsBytesWrittenKey)))) { CFNumberGetValue(number, kCFNumberSInt64Type, &value); total_bytes += value; } /* * Get I/O counts. */ if ((number = (CFNumberRef)CFDictionaryGetValue(statistics, CFSTR(kIOBlockStorageDriverStatisticsReadsKey)))) { CFNumberGetValue(number, kCFNumberSInt64Type, &value); total_transfers += value; } if ((number = (CFNumberRef)CFDictionaryGetValue(statistics, CFSTR(kIOBlockStorageDriverStatisticsWritesKey)))) { CFNumberGetValue(number, kCFNumberSInt64Type, &value); total_transfers += value; } /* * Get I/O time. */ if ((number = (CFNumberRef)CFDictionaryGetValue(statistics, CFSTR(kIOBlockStorageDriverStatisticsLatentReadTimeKey)))) { CFNumberGetValue(number, kCFNumberSInt64Type, &value); total_time += value; } if ((number = (CFNumberRef)CFDictionaryGetValue(statistics, CFSTR(kIOBlockStorageDriverStatisticsLatentWriteTimeKey)))) { CFNumberGetValue(number, kCFNumberSInt64Type, &value); total_time += value; } } CFRelease(properties); /* * Compute delta values and stats. */ interval_bytes = total_bytes - drivestat[i].total_bytes; interval_transfers = total_transfers - drivestat[i].total_transfers; interval_time = total_time - drivestat[i].total_time; /* update running totals, only once for -I */ if ((Iflag == 0) || (drivestat[i].total_bytes == 0)) { drivestat[i].total_bytes = total_bytes; drivestat[i].total_transfers = total_transfers; drivestat[i].total_time = total_time; } interval_blocks = interval_bytes / drivestat[i].blocksize; total_blocks = total_bytes / drivestat[i].blocksize; blocks_per_second = interval_blocks / etime; transfers_per_second = interval_transfers / etime; mb_per_second = (interval_bytes / etime) / (1024 * 1024); kb_per_transfer = (interval_transfers > 0) ? ((long double)interval_bytes / interval_transfers) / 1024 : 0; /* times are in nanoseconds, convert to milliseconds */ ms_per_transaction = (interval_transfers > 0) ? ((long double)interval_time / interval_transfers) / 1000 : 0; if (Kflag) total_blocks = total_blocks * drivestat[i].blocksize / 1024; if (oflag > 0) { int msdig = (ms_per_transaction < 100.0) ? 1 : 0; if (Iflag == 0) printf("%4.0Lf%4.0Lf%5.*Lf ", blocks_per_second, transfers_per_second, msdig, ms_per_transaction); else printf("%4.1qu%4.1qu%5.*Lf ", interval_blocks, interval_transfers, msdig, ms_per_transaction); } else { if (Iflag == 0) printf(" %5.2Lf %3.0Lf %5.2Lf ", kb_per_transfer, transfers_per_second, mb_per_second); else { interval_mb = interval_bytes; interval_mb /= 1024 * 1024; printf(" %5.2Lf %3.1qu %5.2Lf ", kb_per_transfer, interval_transfers, interval_mb); } } } }
static void get_via_generic_iokit (double *ret_charge, /* {{{ */ double *ret_current, double *ret_voltage) { kern_return_t status; io_iterator_t iterator; io_object_t io_obj; CFDictionaryRef bat_root_dict; CFArrayRef bat_info_arry; CFIndex bat_info_arry_len; CFIndex bat_info_arry_pos; CFDictionaryRef bat_info_dict; double temp_double; status = IOServiceGetMatchingServices (kIOMasterPortDefault, IOServiceNameMatching ("battery"), &iterator); if (status != kIOReturnSuccess) { DEBUG ("IOServiceGetMatchingServices failed."); return; } while ((io_obj = IOIteratorNext (iterator))) { status = IORegistryEntryCreateCFProperties (io_obj, (CFMutableDictionaryRef *) &bat_root_dict, kCFAllocatorDefault, kNilOptions); if (status != kIOReturnSuccess) { DEBUG ("IORegistryEntryCreateCFProperties failed."); continue; } bat_info_arry = (CFArrayRef) CFDictionaryGetValue (bat_root_dict, CFSTR ("IOBatteryInfo")); if (bat_info_arry == NULL) { CFRelease (bat_root_dict); continue; } bat_info_arry_len = CFArrayGetCount (bat_info_arry); for (bat_info_arry_pos = 0; bat_info_arry_pos < bat_info_arry_len; bat_info_arry_pos++) { bat_info_dict = (CFDictionaryRef) CFArrayGetValueAtIndex (bat_info_arry, bat_info_arry_pos); if (*ret_charge == INVALID_VALUE) { temp_double = dict_get_double (bat_info_dict, "Capacity"); if (temp_double != INVALID_VALUE) *ret_charge = temp_double / 1000.0; } if (*ret_current == INVALID_VALUE) { temp_double = dict_get_double (bat_info_dict, "Current"); if (temp_double != INVALID_VALUE) *ret_current = temp_double / 1000.0; } if (*ret_voltage == INVALID_VALUE) { temp_double = dict_get_double (bat_info_dict, "Voltage"); if (temp_double != INVALID_VALUE) *ret_voltage = temp_double / 1000.0; } } CFRelease (bat_root_dict); } IOObjectRelease (iterator); } /* }}} void get_via_generic_iokit */
/**************************************************************************** * darwin_getTOC: get the TOC ****************************************************************************/ static CDTOC *darwin_getTOC( vlc_object_t * p_this, const vcddev_t *p_vcddev ) { mach_port_t port; char *psz_devname; kern_return_t ret; CDTOC *pTOC = NULL; io_iterator_t iterator; io_registry_entry_t service; CFMutableDictionaryRef properties; CFDataRef data; /* get the device name */ if( ( psz_devname = strrchr( p_vcddev->psz_dev, '/') ) != NULL ) ++psz_devname; else psz_devname = p_vcddev->psz_dev; /* unraw the device name */ if( *psz_devname == 'r' ) ++psz_devname; /* get port for IOKit communication */ if( ( ret = IOMasterPort( MACH_PORT_NULL, &port ) ) != KERN_SUCCESS ) { msg_Err( p_this, "IOMasterPort: 0x%08x", ret ); return( NULL ); } /* get service iterator for the device */ if( ( ret = IOServiceGetMatchingServices( port, IOBSDNameMatching( port, 0, psz_devname ), &iterator ) ) != KERN_SUCCESS ) { msg_Err( p_this, "IOServiceGetMatchingServices: 0x%08x", ret ); return( NULL ); } /* first service */ service = IOIteratorNext( iterator ); IOObjectRelease( iterator ); /* search for kIOCDMediaClass */ while( service && !IOObjectConformsTo( service, kIOCDMediaClass ) ) { if( ( ret = IORegistryEntryGetParentIterator( service, kIOServicePlane, &iterator ) ) != KERN_SUCCESS ) { msg_Err( p_this, "IORegistryEntryGetParentIterator: 0x%08x", ret ); IOObjectRelease( service ); return( NULL ); } IOObjectRelease( service ); service = IOIteratorNext( iterator ); IOObjectRelease( iterator ); } if( !service ) { msg_Err( p_this, "search for kIOCDMediaClass came up empty" ); return( NULL ); } /* create a CF dictionary containing the TOC */ if( ( ret = IORegistryEntryCreateCFProperties( service, &properties, kCFAllocatorDefault, kNilOptions ) ) != KERN_SUCCESS ) { msg_Err( p_this, "IORegistryEntryCreateCFProperties: 0x%08x", ret ); IOObjectRelease( service ); return( NULL ); } /* get the TOC from the dictionary */ if( ( data = (CFDataRef) CFDictionaryGetValue( properties, CFSTR(kIOCDMediaTOCKey) ) ) != NULL ) { CFRange range; CFIndex buf_len; buf_len = CFDataGetLength( data ) + 1; range = CFRangeMake( 0, buf_len ); if( ( pTOC = malloc( buf_len ) ) != NULL ) { CFDataGetBytes( data, range, (u_char *)pTOC ); } } else { msg_Err( p_this, "CFDictionaryGetValue failed" ); } CFRelease( properties ); IOObjectRelease( service ); return( pTOC ); }
static int collect_drive_stats(io_registry_entry_t driver, long *stats) { CFNumberRef number; CFDictionaryRef properties; CFDictionaryRef statistics; long value; kern_return_t status; int i; /* * If the drive goes away, we may not get any properties * for it. So take some defaults. Nb: use memset ?? */ for (i = 0; i < kIDXLast; i++) { stats[i] = 0; } /* retrieve the properties */ status = IORegistryEntryCreateCFProperties(driver, (CFMutableDictionaryRef *)&properties, kCFAllocatorDefault, kNilOptions); if (status != KERN_SUCCESS) { snmp_log(LOG_ERR, "diskio: device has no properties\n"); /* fprintf(stderr, "device has no properties\n"); */ return (1); } /* retrieve statistics from properties */ statistics = (CFDictionaryRef)CFDictionaryGetValue(properties, CFSTR(kIOBlockStorageDriverStatisticsKey)); if (statistics) { /* Now hand me the crystals. */ if ((number = (CFNumberRef)CFDictionaryGetValue(statistics, CFSTR(kIOBlockStorageDriverStatisticsBytesReadKey)))) { CFNumberGetValue(number, kCFNumberSInt32Type, &value); stats[kIDXBytesRead] = value; } if ((number = (CFNumberRef)CFDictionaryGetValue(statistics, CFSTR(kIOBlockStorageDriverStatisticsBytesWrittenKey)))) { CFNumberGetValue(number, kCFNumberSInt32Type, &value); stats[kIDXBytesWritten] = value; } if ((number = (CFNumberRef)CFDictionaryGetValue(statistics, CFSTR(kIOBlockStorageDriverStatisticsReadsKey)))) { CFNumberGetValue(number, kCFNumberSInt32Type, &value); stats[kIDXNumReads] = value; } if ((number = (CFNumberRef)CFDictionaryGetValue(statistics, CFSTR(kIOBlockStorageDriverStatisticsWritesKey)))) { CFNumberGetValue(number, kCFNumberSInt32Type, &value); stats[kIDXNumWrites] = value; } } /* we're done with the properties, release them */ CFRelease(properties); return (0); }
/** * Creates a keyboard cache entry. * * @returns true if the entry was created successfully, otherwise false. * @param pKeyboardEntry Pointer to the entry. * @param KeyboardDevice The keyboard device to create the entry for. * */ static bool darwinHIDKeyboardCacheCreateEntry(struct KeyboardCacheData *pKeyboardEntry, io_object_t KeyboardDevice) { unsigned long cRefs = 0; memset(pKeyboardEntry, 0, sizeof(*pKeyboardEntry)); /* * Query the HIDDeviceInterface for this HID (keyboard) object. */ SInt32 Score = 0; IOCFPlugInInterface **ppPlugInInterface = NULL; IOReturn rc = IOCreatePlugInInterfaceForService(KeyboardDevice, kIOHIDDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &ppPlugInInterface, &Score); if (rc == kIOReturnSuccess) { IOHIDDeviceInterface **ppHidDeviceInterface = NULL; HRESULT hrc = (*ppPlugInInterface)->QueryInterface(ppPlugInInterface, CFUUIDGetUUIDBytes(kIOHIDDeviceInterfaceID), (LPVOID *)&ppHidDeviceInterface); cRefs = (*ppPlugInInterface)->Release(ppPlugInInterface); MY_CHECK_CREFS(cRefs); ppPlugInInterface = NULL; if (hrc == S_OK) { rc = (*ppHidDeviceInterface)->open(ppHidDeviceInterface, 0); if (rc == kIOReturnSuccess) { /* * create a removal callback. */ /** @todo */ /* * Create the queue so we can insert elements while searching the properties. */ IOHIDQueueInterface **ppHidQueueInterface = (*ppHidDeviceInterface)->allocQueue(ppHidDeviceInterface); if (ppHidQueueInterface) { rc = (*ppHidQueueInterface)->create(ppHidQueueInterface, 0, 32); if (rc != kIOReturnSuccess) { AssertMsgFailed(("rc=%d\n", rc)); cRefs = (*ppHidQueueInterface)->Release(ppHidQueueInterface); MY_CHECK_CREFS(cRefs); ppHidQueueInterface = NULL; } } else AssertFailed(); pKeyboardEntry->ppHidQueueInterface = ppHidQueueInterface; /* * Brute force getting of attributes. */ /** @todo read up on how to do this in a less resource intensive way! Suggestions are welcome! */ CFMutableDictionaryRef PropertiesRef = 0; kern_return_t krc = IORegistryEntryCreateCFProperties(KeyboardDevice, &PropertiesRef, kCFAllocatorDefault, kNilOptions); if (krc == KERN_SUCCESS) { darwinBruteForcePropertySearch(PropertiesRef, pKeyboardEntry); CFRelease(PropertiesRef); } else AssertMsgFailed(("krc=%#x\n", krc)); if (ppHidQueueInterface) { /* * Now install our queue callback. */ CFRunLoopSourceRef RunLoopSrcRef = NULL; rc = (*ppHidQueueInterface)->createAsyncEventSource(ppHidQueueInterface, &RunLoopSrcRef); if (rc == kIOReturnSuccess) { CFRunLoopRef RunLoopRef = (CFRunLoopRef)GetCFRunLoopFromEventLoop(GetMainEventLoop()); CFRunLoopAddSource(RunLoopRef, RunLoopSrcRef, kCFRunLoopDefaultMode); } /* * Now install our queue callback. */ rc = (*ppHidQueueInterface)->setEventCallout(ppHidQueueInterface, darwinQueueCallback, ppHidQueueInterface, pKeyboardEntry); if (rc != kIOReturnSuccess) AssertMsgFailed(("rc=%d\n", rc)); } /* * Complete the new keyboard cache entry. */ pKeyboardEntry->ppHidDeviceInterface = ppHidDeviceInterface; pKeyboardEntry->ppHidQueueInterface = ppHidQueueInterface; return true; } AssertMsgFailed(("rc=%d\n", rc)); cRefs = (*ppHidDeviceInterface)->Release(ppHidDeviceInterface); MY_CHECK_CREFS(cRefs); } else AssertMsgFailed(("hrc=%#x\n", hrc)); } else AssertMsgFailed(("rc=%d\n", rc)); return false; }
/* * Return a Python dict of tuples for disk I/O information */ static PyObject* get_disk_io_counters(PyObject* self, PyObject* args) { PyObject* py_retdict = PyDict_New(); PyObject* py_disk_info; CFDictionaryRef parent_dict; CFDictionaryRef props_dict; CFDictionaryRef stats_dict; io_registry_entry_t parent; io_registry_entry_t disk; io_iterator_t disk_list; /* Get list of disks */ if (IOServiceGetMatchingServices(kIOMasterPortDefault, IOServiceMatching(kIOMediaClass), &disk_list) != kIOReturnSuccess) { Py_DECREF(py_retdict); PyErr_SetString(PyExc_RuntimeError, "Unable to get the list of disks."); return NULL; } /* Iterate over disks */ while ((disk = IOIteratorNext(disk_list)) != 0) { parent_dict = NULL; props_dict = NULL; stats_dict = NULL; if (IORegistryEntryGetParentEntry(disk, kIOServicePlane, &parent) != kIOReturnSuccess) { PyErr_SetString(PyExc_RuntimeError, "Unable to get the disk's parent."); Py_DECREF(py_retdict); IOObjectRelease(disk); return NULL; } if (IOObjectConformsTo(parent, "IOBlockStorageDriver")) { if(IORegistryEntryCreateCFProperties( disk, (CFMutableDictionaryRef *) &parent_dict, kCFAllocatorDefault, kNilOptions) != kIOReturnSuccess) { PyErr_SetString(PyExc_RuntimeError, "Unable to get the parent's properties."); Py_DECREF(py_retdict); IOObjectRelease(disk); IOObjectRelease(parent); return NULL; } if (IORegistryEntryCreateCFProperties(parent, (CFMutableDictionaryRef *) &props_dict, kCFAllocatorDefault, kNilOptions) != kIOReturnSuccess) { PyErr_SetString(PyExc_RuntimeError, "Unable to get the disk properties."); Py_DECREF(py_retdict); IOObjectRelease(disk); return NULL; } const int kMaxDiskNameSize = 64; CFStringRef disk_name_ref = (CFStringRef)CFDictionaryGetValue( parent_dict, CFSTR(kIOBSDNameKey)); char disk_name[kMaxDiskNameSize]; CFStringGetCString(disk_name_ref, disk_name, kMaxDiskNameSize, CFStringGetSystemEncoding()); stats_dict = (CFDictionaryRef)CFDictionaryGetValue( props_dict, CFSTR(kIOBlockStorageDriverStatisticsKey)); if (stats_dict == NULL) { PyErr_SetString(PyExc_RuntimeError, "Unable to get disk stats."); Py_DECREF(py_retdict); CFRelease(props_dict); IOObjectRelease(disk); IOObjectRelease(parent); return NULL; } CFNumberRef number; int64_t reads, writes, read_bytes, write_bytes, read_time, write_time = 0; /* Get disk reads/writes */ if ((number = (CFNumberRef)CFDictionaryGetValue( stats_dict, CFSTR(kIOBlockStorageDriverStatisticsReadsKey)))) { CFNumberGetValue(number, kCFNumberSInt64Type, &reads); } if ((number = (CFNumberRef)CFDictionaryGetValue( stats_dict, CFSTR(kIOBlockStorageDriverStatisticsWritesKey)))) { CFNumberGetValue(number, kCFNumberSInt64Type, &writes); } /* Get disk bytes read/written */ if ((number = (CFNumberRef)CFDictionaryGetValue( stats_dict, CFSTR(kIOBlockStorageDriverStatisticsBytesReadKey)))) { CFNumberGetValue(number, kCFNumberSInt64Type, &read_bytes); } if ((number = (CFNumberRef)CFDictionaryGetValue( stats_dict, CFSTR(kIOBlockStorageDriverStatisticsBytesWrittenKey)))) { CFNumberGetValue(number, kCFNumberSInt64Type, &write_bytes); } /* Get disk time spent reading/writing (nanoseconds) */ if ((number = (CFNumberRef)CFDictionaryGetValue( stats_dict, CFSTR(kIOBlockStorageDriverStatisticsTotalReadTimeKey)))) { CFNumberGetValue(number, kCFNumberSInt64Type, &read_time); } if ((number = (CFNumberRef)CFDictionaryGetValue( stats_dict, CFSTR(kIOBlockStorageDriverStatisticsTotalWriteTimeKey)))) { CFNumberGetValue(number, kCFNumberSInt64Type, &write_time); } // Read/Write time on OS X comes back in nanoseconds and in psutil // we've standardized on milliseconds so do the conversion. py_disk_info = Py_BuildValue("(KKKKKK)", reads, writes, read_bytes, write_bytes, read_time / 1000, write_time / 1000); PyDict_SetItemString(py_retdict, disk_name, py_disk_info); Py_XDECREF(py_disk_info); CFRelease(parent_dict); IOObjectRelease(parent); CFRelease(props_dict); IOObjectRelease(disk); } } IOObjectRelease (disk_list); return py_retdict; }
QueryData genKernelInfo(QueryContext& context) { QueryData results; mach_port_t master_port; auto kr = IOMasterPort(bootstrap_port, &master_port); if (kr != KERN_SUCCESS) { VLOG(1) << "Could not get the IOMaster port"; return {}; } // NVRAM registry entry is :/options. auto chosen = IORegistryEntryFromPath(master_port, kIODTChosenPath_); if (chosen == 0) { VLOG(1) << "Could not get IOKit boot device"; return {}; } // Parse the boot arguments, usually none. CFMutableDictionaryRef properties; kr = IORegistryEntryCreateCFProperties( chosen, &properties, kCFAllocatorDefault, 0); IOObjectRelease(chosen); if (kr != KERN_SUCCESS) { VLOG(1) << "Could not get IOKit boot device properties"; return {}; } Row r; CFTypeRef property; if (CFDictionaryGetValueIfPresent( properties, CFSTR("boot-args"), &property)) { r["arguments"] = stringFromCFData((CFDataRef)property); } if (CFDictionaryGetValueIfPresent( properties, CFSTR("boot-device-path"), &property)) { r["device"] = getCanonicalEfiDevicePath((CFDataRef)property); } if (CFDictionaryGetValueIfPresent( properties, CFSTR("boot-file"), &property)) { r["path"] = stringFromCFData((CFDataRef)property); std::replace(r["path"].begin(), r["path"].end(), '\\', '/'); boost::trim(r["path"]); if (!r["path"].empty() && r["path"][0] != '/') { r["path"] = "/" + r["path"]; } } // No longer need chosen properties. CFRelease(properties); // The kernel version, signature, and build information is stored in Root. auto root = IORegistryGetRootEntry(master_port); if (root != 0) { property = (CFDataRef)IORegistryEntryCreateCFProperty( root, CFSTR(kIOKitBuildVersionKey), kCFAllocatorDefault, 0); if (property != nullptr) { // The version is in the form: // Darwin Kernel Version VERSION: DATE; root:BUILD/TAG auto signature = stringFromCFString((CFStringRef)property); CFRelease(property); r["version"] = signature.substr(22, signature.find(":") - 22); } } results.push_back(r); return results; }
static int as_read (void) { kern_return_t status; io_iterator_t iterator; io_object_t io_obj; CFMutableDictionaryRef prop_dict; CFTypeRef property; char type[128]; char inst[128]; int value_int; double value_double; int i; if (!io_master_port || (io_master_port == MACH_PORT_NULL)) return (-1); status = IOServiceGetMatchingServices (io_master_port, IOServiceNameMatching("IOHWSensor"), &iterator); if (status != kIOReturnSuccess) { ERROR ("IOServiceGetMatchingServices failed: %s", mach_error_string (status)); return (-1); } while ((io_obj = IOIteratorNext (iterator))) { prop_dict = NULL; status = IORegistryEntryCreateCFProperties (io_obj, &prop_dict, kCFAllocatorDefault, kNilOptions); if (status != kIOReturnSuccess) { DEBUG ("IORegistryEntryCreateCFProperties failed: %s", mach_error_string (status)); continue; } /* Copy the sensor type. */ property = NULL; if (!CFDictionaryGetValueIfPresent (prop_dict, CFSTR ("type"), &property)) continue; if (CFGetTypeID (property) != CFStringGetTypeID ()) continue; if (!CFStringGetCString (property, type, sizeof (type), kCFStringEncodingASCII)) continue; type[sizeof (type) - 1] = '\0'; /* Copy the sensor location. This will be used as `instance'. */ property = NULL; if (!CFDictionaryGetValueIfPresent (prop_dict, CFSTR ("location"), &property)) continue; if (CFGetTypeID (property) != CFStringGetTypeID ()) continue; if (!CFStringGetCString (property, inst, sizeof (inst), kCFStringEncodingASCII)) continue; inst[sizeof (inst) - 1] = '\0'; for (i = 0; i < 128; i++) { if (inst[i] == '\0') break; else if (isalnum (inst[i])) inst[i] = (char) tolower (inst[i]); else inst[i] = '_'; } /* Get the actual value. Some computation, based on the `type' * is neccessary. */ property = NULL; if (!CFDictionaryGetValueIfPresent (prop_dict, CFSTR ("current-value"), &property)) continue; if (CFGetTypeID (property) != CFNumberGetTypeID ()) continue; if (!CFNumberGetValue (property, kCFNumberIntType, &value_int)) continue; /* Found e.g. in the 1.5GHz PowerBooks */ if (strcmp (type, "temperature") == 0) { value_double = ((double) value_int) / 65536.0; sstrncpy (type, "temperature", sizeof (type)); } else if (strcmp (type, "temp") == 0) { value_double = ((double) value_int) / 10.0; sstrncpy (type, "temperature", sizeof (type)); } else if (strcmp (type, "fanspeed") == 0) { value_double = ((double) value_int) / 65536.0; sstrncpy (type, "fanspeed", sizeof (type)); } else if (strcmp (type, "voltage") == 0) { /* Leave this to the battery plugin. */ continue; } else if (strcmp (type, "adc") == 0) { value_double = ((double) value_int) / 10.0; sstrncpy (type, "fanspeed", sizeof (type)); } else { DEBUG ("apple_sensors: Read unknown sensor type: %s", type); value_double = (double) value_int; } as_submit (type, inst, value_double); CFRelease (prop_dict); IOObjectRelease (io_obj); } /* while (iterator) */ IOObjectRelease (iterator); return (0); } /* int as_read */
int MacHaptic_MaybeAddDevice( io_object_t device ) { IOReturn result; CFMutableDictionaryRef hidProperties; CFTypeRef refCF; SDL_hapticlist_item *item; if (numhaptics == -1) { return -1; /* not initialized. We'll pick these up on enumeration if we init later. */ } /* Check for force feedback. */ if (FFIsForceFeedback(device) != FF_OK) { return -1; } /* Make sure we don't already have it */ for (item = SDL_hapticlist; item ; item = item->next) { if (IOObjectIsEqualTo((io_object_t) item->dev, device)) { /* Already added */ return -1; } } item = (SDL_hapticlist_item *)SDL_calloc(1, sizeof(SDL_hapticlist_item)); if (item == NULL) { return SDL_SetError("Could not allocate haptic storage"); } /* retain it as we are going to keep it around a while */ IOObjectRetain(device); /* Set basic device data. */ HIDGetDeviceProduct(device, item->name); item->dev = device; /* Set usage pages. */ hidProperties = 0; refCF = 0; result = IORegistryEntryCreateCFProperties(device, &hidProperties, kCFAllocatorDefault, kNilOptions); if ((result == KERN_SUCCESS) && hidProperties) { refCF = CFDictionaryGetValue(hidProperties, CFSTR(kIOHIDPrimaryUsagePageKey)); if (refCF) { if (!CFNumberGetValue(refCF, kCFNumberLongType, &item->usagePage)) { SDL_SetError("Haptic: Receiving device's usage page."); } refCF = CFDictionaryGetValue(hidProperties, CFSTR(kIOHIDPrimaryUsageKey)); if (refCF) { if (!CFNumberGetValue(refCF, kCFNumberLongType, &item->usage)) { SDL_SetError("Haptic: Receiving device's usage."); } } } CFRelease(hidProperties); } if (SDL_hapticlist_tail == NULL) { SDL_hapticlist = SDL_hapticlist_tail = item; } else { SDL_hapticlist_tail->next = item; SDL_hapticlist_tail = item; } /* Device has been added. */ ++numhaptics; return numhaptics; }
// ---------------------------------------------------------------------------- // wxHIDDevice::Create // // nClass is the HID Page such as // kHIDPage_GenericDesktop // nType is the HID Usage such as // kHIDUsage_GD_Joystick,kHIDUsage_GD_Mouse,kHIDUsage_GD_Keyboard // nDev is the device number to use // // ---------------------------------------------------------------------------- bool wxHIDDevice::Create (int nClass, int nType, int nDev) { //Create the mach port if(IOMasterPort(bootstrap_port, &m_pPort) != kIOReturnSuccess) { wxLogSysError(wxT("Could not create mach port")); return false; } //Dictionary that will hold first //the matching dictionary for determining which kind of devices we want, //then later some registry properties from an iterator (see below) // //The call to IOServiceMatching filters down the //the services we want to hid services (and also eats the //dictionary up for us (consumes one reference)) CFMutableDictionaryRef pDictionary = IOServiceMatching(kIOHIDDeviceKey); if(pDictionary == NULL) { wxLogSysError( wxT("IOServiceMatching(kIOHIDDeviceKey) failed") ); return false; } //Here we'll filter down the services to what we want if (nType != -1) { CFNumberRef pType = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &nType); CFDictionarySetValue(pDictionary, CFSTR(kIOHIDPrimaryUsageKey), pType); CFRelease(pType); } if (nClass != -1) { CFNumberRef pClass = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &nClass); CFDictionarySetValue(pDictionary, CFSTR(kIOHIDPrimaryUsagePageKey), pClass); CFRelease(pClass); } //Now get the maching services io_iterator_t pIterator; if( IOServiceGetMatchingServices(m_pPort, pDictionary, &pIterator) != kIOReturnSuccess ) { wxLogSysError(wxT("No Matching HID Services")); return false; } //Were there any devices matched? if(pIterator == 0) return false; // No devices found //Now we iterate through them io_object_t pObject; while ( (pObject = IOIteratorNext(pIterator)) != 0) { if(--nDev != 0) { IOObjectRelease(pObject); continue; } if ( IORegistryEntryCreateCFProperties ( pObject, &pDictionary, kCFAllocatorDefault, kNilOptions ) != KERN_SUCCESS ) { wxLogDebug(wxT("IORegistryEntryCreateCFProperties failed")); } // // Now we get the attributes of each "product" in the iterator // //Get [product] name CFStringRef cfsProduct = (CFStringRef) CFDictionaryGetValue(pDictionary, CFSTR(kIOHIDProductKey)); m_szProductName = wxCFStringRef( wxCFRetain(cfsProduct) ).AsString(); //Get the Product ID Key CFNumberRef cfnProductId = (CFNumberRef) CFDictionaryGetValue(pDictionary, CFSTR(kIOHIDProductIDKey)); if (cfnProductId) { CFNumberGetValue(cfnProductId, kCFNumberIntType, &m_nProductId); } //Get the Vendor ID Key CFNumberRef cfnVendorId = (CFNumberRef) CFDictionaryGetValue(pDictionary, CFSTR(kIOHIDVendorIDKey)); if (cfnVendorId) { CFNumberGetValue(cfnVendorId, kCFNumberIntType, &m_nManufacturerId); } // // End attribute getting // //Create the interface (good grief - long function names!) SInt32 nScore; IOCFPlugInInterface** ppPlugin; if(IOCreatePlugInInterfaceForService(pObject, kIOHIDDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &ppPlugin, &nScore) != kIOReturnSuccess) { wxLogSysError(wxT("Could not create HID Interface for product")); return false; } //Now, the final thing we can check before we fall back to asserts //(because the dtor only checks if the device is ok, so if anything //fails from now on the dtor will delete the device anyway, so we can't break from this). //Get the HID interface from the plugin to the mach port if((*ppPlugin)->QueryInterface(ppPlugin, CFUUIDGetUUIDBytes(kIOHIDDeviceInterfaceID), (void**) &m_ppDevice) != S_OK) { wxLogSysError(wxT("Could not get device interface from HID interface")); return false; } //release the plugin (*ppPlugin)->Release(ppPlugin); //open the HID interface... if ( (*m_ppDevice)->open(m_ppDevice, 0) != S_OK ) { wxLogDebug(wxT("HID device: open failed")); } // //Now the hard part - in order to scan things we need "cookies" // CFArrayRef cfaCookies = (CFArrayRef)CFDictionaryGetValue(pDictionary, CFSTR(kIOHIDElementKey)); BuildCookies(cfaCookies); //cleanup CFRelease(pDictionary); IOObjectRelease(pObject); //iterator cleanup IOObjectRelease(pIterator); return true; } //iterator cleanup IOObjectRelease(pIterator); return false; //no device }//end Create()
/* * Gets the device's product name. */ static int HIDGetDeviceProduct(io_service_t dev, char *name) { CFMutableDictionaryRef hidProperties, usbProperties; io_registry_entry_t parent1, parent2; kern_return_t ret; hidProperties = usbProperties = 0; ret = IORegistryEntryCreateCFProperties(dev, &hidProperties, kCFAllocatorDefault, kNilOptions); if ((ret != KERN_SUCCESS) || !hidProperties) { return SDL_SetError("Haptic: Unable to create CFProperties."); } /* Mac OS X currently is not mirroring all USB properties to HID page so need to look at USB device page also * get dictionary for USB properties: step up two levels and get CF dictionary for USB properties */ if ((KERN_SUCCESS == IORegistryEntryGetParentEntry(dev, kIOServicePlane, &parent1)) && (KERN_SUCCESS == IORegistryEntryGetParentEntry(parent1, kIOServicePlane, &parent2)) && (KERN_SUCCESS == IORegistryEntryCreateCFProperties(parent2, &usbProperties, kCFAllocatorDefault, kNilOptions))) { if (usbProperties) { CFTypeRef refCF = 0; /* get device info * try hid dictionary first, if fail then go to USB dictionary */ /* Get product name */ refCF = CFDictionaryGetValue(hidProperties, CFSTR(kIOHIDProductKey)); if (!refCF) { refCF = CFDictionaryGetValue(usbProperties, CFSTR("USB Product Name")); } if (refCF) { if (!CFStringGetCString(refCF, name, 256, CFStringGetSystemEncoding())) { return SDL_SetError("Haptic: CFStringGetCString error retrieving pDevice->product."); } } CFRelease(usbProperties); } else { return SDL_SetError("Haptic: IORegistryEntryCreateCFProperties failed to create usbProperties."); } /* Release stuff. */ if (kIOReturnSuccess != IOObjectRelease(parent2)) { SDL_SetError("Haptic: IOObjectRelease error with parent2."); } if (kIOReturnSuccess != IOObjectRelease(parent1)) { SDL_SetError("Haptic: IOObjectRelease error with parent1."); } } else { return SDL_SetError("Haptic: Error getting registry entries."); } return 0; }
static void HIDGetDeviceInfo (io_object_t hidDevice, CFMutableDictionaryRef hidProperties, recDevice *pDevice) { CFMutableDictionaryRef usbProperties = 0; io_registry_entry_t parent1, parent2; /* Mac OS X currently is not mirroring all USB properties to HID page so need to look at USB device page also * get dictionary for usb properties: step up two levels and get CF dictionary for USB properties */ if ((KERN_SUCCESS == IORegistryEntryGetParentEntry (hidDevice, kIOServicePlane, &parent1)) && (KERN_SUCCESS == IORegistryEntryGetParentEntry (parent1, kIOServicePlane, &parent2)) && (KERN_SUCCESS == IORegistryEntryCreateCFProperties (parent2, &usbProperties, kCFAllocatorDefault, kNilOptions))) { if (usbProperties) { CFTypeRef refCF = 0; /* get device info * try hid dictionary first, if fail then go to usb dictionary */ /* get product name */ refCF = CFDictionaryGetValue (hidProperties, CFSTR(kIOHIDProductKey)); if (!refCF) refCF = CFDictionaryGetValue (usbProperties, CFSTR("USB Product Name")); if (refCF) { if (!CFStringGetCString (refCF, pDevice->product, 256, CFStringGetSystemEncoding ())) SDL_SetError ("CFStringGetCString error retrieving pDevice->product."); } /* get usage page and usage */ refCF = CFDictionaryGetValue (hidProperties, CFSTR(kIOHIDPrimaryUsagePageKey)); if (refCF) { if (!CFNumberGetValue (refCF, kCFNumberLongType, &pDevice->usagePage)) SDL_SetError ("CFNumberGetValue error retrieving pDevice->usagePage."); refCF = CFDictionaryGetValue (hidProperties, CFSTR(kIOHIDPrimaryUsageKey)); if (refCF) if (!CFNumberGetValue (refCF, kCFNumberLongType, &pDevice->usage)) SDL_SetError ("CFNumberGetValue error retrieving pDevice->usage."); } if (NULL == refCF) /* get top level element HID usage page or usage */ { /* use top level element instead */ CFTypeRef refCFTopElement = 0; refCFTopElement = CFDictionaryGetValue (hidProperties, CFSTR(kIOHIDElementKey)); { /* refCFTopElement points to an array of element dictionaries */ CFRange range = {0, CFArrayGetCount (refCFTopElement)}; CFArrayApplyFunction (refCFTopElement, range, HIDTopLevelElementHandler, pDevice); } } CFRelease (usbProperties); } else SDL_SetError ("IORegistryEntryCreateCFProperties failed to create usbProperties."); if (kIOReturnSuccess != IOObjectRelease (parent2)) SDL_SetError ("IOObjectRelease error with parent2."); if (kIOReturnSuccess != IOObjectRelease (parent1)) SDL_SetError ("IOObjectRelease error with parent1."); } }