// This function is much inspired by record_device() and devstats() from // http://opensource.apple.com/source/system_cmds/system_cmds-230/iostat.tproj/iostat.c static void reportDrive(dynamic_accumulator_t *ioLoad, io_registry_entry_t drive) { io_registry_entry_t parent; CFStringRef name; kern_return_t status; // get drive's parent status = IORegistryEntryGetParentEntry(drive, kIOServicePlane, &parent); if (status != KERN_SUCCESS) { return; } if (!IOObjectConformsTo(parent, "IOBlockStorageDriver")) { IOObjectRelease(parent); return; } // get drive properties CFDictionaryRef driveProperties; status = IORegistryEntryCreateCFProperties(drive, (CFMutableDictionaryRef *)&driveProperties, kCFAllocatorDefault, kNilOptions); if (status != KERN_SUCCESS) { return; } // get name from properties name = (CFStringRef)CFDictionaryGetValue(driveProperties, CFSTR(kIOBSDNameKey)); char cname[100]; CFStringGetCString(name, cname, sizeof(cname), CFStringGetSystemEncoding()); CFRelease(driveProperties); // get parent properties CFDictionaryRef parentProperties; status = IORegistryEntryCreateCFProperties(parent, (CFMutableDictionaryRef *)&parentProperties, kCFAllocatorDefault, kNilOptions); IOObjectRelease(parent); if (status != KERN_SUCCESS) { CFRelease(driveProperties); return; } CFDictionaryRef statistics; statistics = (CFDictionaryRef)CFDictionaryGetValue(parentProperties, CFSTR(kIOBlockStorageDriverStatisticsKey)); if (!statistics) { CFRelease(parentProperties); return; } u_int64_t bytesRead = 0; u_int64_t bytesWritten = 0; CFNumberRef number; if ((number = (CFNumberRef)CFDictionaryGetValue(statistics, CFSTR(kIOBlockStorageDriverStatisticsBytesReadKey)))) { CFNumberGetValue(number, kCFNumberSInt64Type, &bytesRead); } if ((number = (CFNumberRef)CFDictionaryGetValue(statistics, CFSTR(kIOBlockStorageDriverStatisticsBytesWrittenKey)))) { CFNumberGetValue(number, kCFNumberSInt64Type, &bytesWritten); } CFRelease(parentProperties); dynamic_accumulator_report(ioLoad, cname, bytesRead, bytesWritten); }
/* * 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) { SDL_SetError("Haptic: Unable to create CFProperties."); return -1; } /* 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())) { SDL_SetError ("Haptic: CFStringGetCString error retrieving pDevice->product."); return -1; } } CFRelease(usbProperties); } else { SDL_SetError ("Haptic: IORegistryEntryCreateCFProperties failed to create usbProperties."); return -1; } /* 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 { SDL_SetError("Haptic: Error getting registry entries."); return -1; } 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."); } }
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."); } } } refCF = CFDictionaryGetValue(hidProperties, CFSTR(kIOHIDVendorIDKey)); if (refCF) { if (!CFNumberGetValue(refCF, kCFNumberLongType, &pDevice->guid.data[0])) { SDL_SetError("CFNumberGetValue error retrieving pDevice->guid[0]"); } } refCF = CFDictionaryGetValue(hidProperties, CFSTR(kIOHIDProductIDKey)); if (refCF) { if (!CFNumberGetValue(refCF, kCFNumberLongType, &pDevice->guid.data[8])) { SDL_SetError("CFNumberGetValue error retrieving pDevice->guid[8]"); } } /* Check to make sure we have a vendor and product ID If we don't, use the same algorithm as the Linux code for Bluetooth devices */ { Uint32 *guid32 = (Uint32*)pDevice->guid.data; if (!guid32[0] && !guid32[1]) { const Uint16 BUS_BLUETOOTH = 0x05; Uint16 *guid16 = (Uint16 *)guid32; *guid16++ = BUS_BLUETOOTH; *guid16++ = 0; SDL_strlcpy((char*)guid16, pDevice->product, sizeof(pDevice->guid.data) - 4); } } /* If we don't have a vendor and product ID this is probably a Bluetooth device */ 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"); } } }
RString ArchHooks_MacOSX::GetMachineId() const { RString ret; CFMutableDictionaryRef dict = IOServiceMatching( "IOPlatformExpertDevice" ); CFMutableDictionaryRef property; io_service_t service; if( dict ) { // This consumes the reference. service = IOServiceGetMatchingService( kIOMasterPortDefault, dict ); if( service ) { CFTypeRef serial; CFStringRef key = CFSTR( "IOPlatformSerialNumber" ); // kIOPlatformSerialNumberKey serial = IORegistryEntryCreateCFProperty( service, key, kCFAllocatorDefault, 0 ); if( serial ) { const char *str = CFStringGetCStringPtr( (CFStringRef)serial, CFStringGetSystemEncoding() ); ret = str? str:""; CFRelease( serial ); } IOObjectRelease( service ); } } dict = IOServiceMatching( kIOEthernetInterfaceClass ); if( !dict ) return ret; property = CFDictionaryCreateMutable( kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks ); if( !property ) { CFRelease( dict ); return ret; } CFDictionarySetValue( property, CFSTR(kIOPrimaryInterface), kCFBooleanTrue ); CFDictionarySetValue( dict, CFSTR(kIOPropertyMatchKey), property ); CFRelease( property ); io_iterator_t iter; if( IOServiceGetMatchingServices(kIOMasterPortDefault, dict, &iter) != KERN_SUCCESS ) return ret; while( (service = IOIteratorNext(iter)) ) { CFTypeRef data; io_object_t controller; if( IORegistryEntryGetParentEntry(service, kIOServicePlane, &controller) != KERN_SUCCESS ) { IOObjectRelease( service ); continue; } data = IORegistryEntryCreateCFProperty( controller, CFSTR(kIOMACAddress), kCFAllocatorDefault, 0 ); if( data ) { const uint8_t *p = CFDataGetBytePtr( (CFDataRef)data ); ret += ssprintf( "-%02x:%02x:%02x:%02x:%02x:%02x", p[0], p[1], p[2], p[3], p[4], p[5] ); CFRelease( data ); } IOObjectRelease( controller ); IOObjectRelease( service ); } IOObjectRelease( iter ); return ret; }
bool QextSerialEnumeratorPrivate::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; }
/** * Get the MAC address of the first logical IP-enabled network interface * * @param out the output character array * @return CPL_OK on success or an error code */ cpl_return_t cpl_platform_get_mac_address(cpl_mac_address_t* out) { #ifdef __unix__ // From: http://stackoverflow.com/questions/1779715/how-to-get-mac-address-of-your-machine-using-a-c-program ifreq ifr; ifconf ifc; char buf[1024]; int success = 0; int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP); if (sock == -1) return CPL_E_PLATFORM_ERROR; ifc.ifc_len = sizeof(buf); ifc.ifc_buf = buf; if (ioctl(sock, SIOCGIFCONF, &ifc) == -1) return CPL_E_PLATFORM_ERROR; ifreq* it = ifc.ifc_req; const ifreq* const end = it + (ifc.ifc_len / sizeof(ifreq)); for (; it != end; ++it) { strcpy(ifr.ifr_name, it->ifr_name); if (ioctl(sock, SIOCGIFFLAGS, &ifr) == 0) { if (! (ifr.ifr_flags & IFF_LOOPBACK)) { // don't count loopback if (ioctl(sock, SIOCGIFHWADDR, &ifr) == 0) { success = 1; break; } } } else { /* ignore error */ } } if (success && out) { memcpy(out, ifr.ifr_hwaddr.sa_data, 6); } if (!success) return CPL_E_NOT_FOUND; #elif defined(__APPLE__) /* * Adapted from GetMACAddress.c: * http://opensource.apple.com/source/DirectoryService * /DirectoryService-621/CoreFramework/Private/GetMACAddress.c * * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. */ kern_return_t kernResult = KERN_FAILURE; mach_port_t masterPort = MACH_PORT_NULL; CFMutableDictionaryRef classesToMatch = NULL; io_object_t intfService = MACH_PORT_NULL; io_object_t controllerService = MACH_PORT_NULL; io_iterator_t intfIterator = MACH_PORT_NULL; unsigned char macAddress[kIOEthernetAddressSize]; io_iterator_t *matchingServices = &intfIterator; UInt8 *MACAddress = macAddress; // Create an iterator with Primary Ethernet interface kernResult = IOMasterPort(MACH_PORT_NULL, &masterPort); if (kernResult != KERN_SUCCESS) return CPL_E_PLATFORM_ERROR; // Ethernet interfaces are instances of class kIOEthernetInterfaceClass classesToMatch = IOServiceMatching(kIOEthernetInterfaceClass); if (classesToMatch != NULL) { CFMutableDictionaryRef propertyMatch; propertyMatch = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFDictionarySetValue(propertyMatch, CFSTR(kIOPrimaryInterface), kCFBooleanTrue); CFDictionarySetValue(classesToMatch, CFSTR(kIOPropertyMatchKey), propertyMatch); CFRelease(propertyMatch); kernResult = IOServiceGetMatchingServices(masterPort, classesToMatch, matchingServices); } // Given an iterator across a set of Ethernet interfaces, return the // MAC address of the first one. intfService = IOIteratorNext(intfIterator); if (intfService == MACH_PORT_NULL) { IOObjectRelease(intfIterator); return CPL_E_PLATFORM_ERROR; } CFDataRef MACAddressAsCFData = NULL; kernResult = IORegistryEntryGetParentEntry(intfService, kIOServicePlane, &controllerService); if (kernResult != KERN_SUCCESS || controllerService == MACH_PORT_NULL) { IOObjectRelease(intfService); IOObjectRelease(intfIterator); return CPL_E_PLATFORM_ERROR; } MACAddressAsCFData = (CFDataRef) IORegistryEntryCreateCFProperty( controllerService, CFSTR(kIOMACAddress), kCFAllocatorDefault, 0); if (MACAddressAsCFData != NULL) { CFDataGetBytes(MACAddressAsCFData, CFRangeMake(0, kIOEthernetAddressSize), MACAddress); CFRelease(MACAddressAsCFData); } else { IOObjectRelease(controllerService); IOObjectRelease(intfService); IOObjectRelease(intfIterator); return CPL_E_NOT_FOUND; } IOObjectRelease(controllerService); IOObjectRelease(intfService); IOObjectRelease(intfIterator); if (out) memcpy(out, macAddress, 6); #elif defined(_WINDOWS) PIP_ADAPTER_ADDRESSES AdapterAddresses; ULONG family = AF_UNSPEC; ULONG flags = 0; ULONG outBufLen = 0; bool success = false; DWORD dwRetVal = GetAdaptersAddresses(family, flags, NULL, NULL, &outBufLen); if (dwRetVal == ERROR_NO_DATA) return CPL_E_NOT_FOUND; if (dwRetVal == 0 && outBufLen == 0) return CPL_E_NOT_FOUND; if (dwRetVal != ERROR_BUFFER_OVERFLOW) return CPL_E_PLATFORM_ERROR; AdapterAddresses = (IP_ADAPTER_ADDRESSES*) malloc(sizeof(IP_ADAPTER_ADDRESSES) * outBufLen); if (AdapterAddresses == NULL) return CPL_E_INSUFFICIENT_RESOURCES; dwRetVal = GetAdaptersAddresses(family, flags, NULL, AdapterAddresses, &outBufLen); if (dwRetVal != 0) { free(AdapterAddresses); return CPL_E_PLATFORM_ERROR; } for (PIP_ADAPTER_ADDRESSES p = AdapterAddresses; p != NULL; p = p->Next) { if (p->IfType == IF_TYPE_SOFTWARE_LOOPBACK) continue; if (p->PhysicalAddressLength != 6 /* Ethernet */) continue; success = true; if (out) memcpy(out, p->PhysicalAddress, 6); break; } free(AdapterAddresses); if (!success) return CPL_E_NOT_FOUND; #else #error "Not implemented for this platform" #endif return CPL_OK; }