this repo has no description
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

IOKit initial work

+636
+1
CMakeLists.txt
··· 115 115 add_subdirectory(src/libncurses) 116 116 add_subdirectory(src/CoreSecurity) 117 117 add_subdirectory(src/CoreServices) 118 + add_subdirectory(src/IOKit) 118 119 add_subdirectory(src/thin) 119 120 120 121 add_dependencies(dyld${SUFFIX} mach-o)
+34
src/IOKit/CMakeLists.txt
··· 1 + project(IOKit) 2 + 3 + cmake_minimum_required(VERSION 2.4.0) 4 + if(COMMAND cmake_policy) 5 + cmake_policy(SET CMP0003 NEW) 6 + endif(COMMAND cmake_policy) 7 + 8 + #if (NOT "${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1}" MATCHES ".*clang") 9 + # message(FATAL_ERROR "Clang is the only supported compiler.") 10 + #endif (NOT "${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1}" MATCHES ".*clang") 11 + 12 + #configure_file(config.h.in config.h) 13 + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") 14 + #set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fblocks") 15 + 16 + include_directories(${CMAKE_CURRENT_SOURCE_DIR}) 17 + include_directories(${CMAKE_CURRENT_SOURCE_DIR}/..) 18 + include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../util) 19 + 20 + set(IOKit_SRCS 21 + bsd.cpp 22 + port.c 23 + service.mm 24 + io_object.cpp 25 + io_device_iterator.cpp 26 + io_device.cpp 27 + io_device_usb.cpp 28 + ) 29 + 30 + add_library(IOKit SHARED ${IOKit_SRCS}) 31 + target_link_libraries(IOKit -lgnustep-corebase util -ludev) 32 + 33 + install(TARGETS IOKit DESTINATION "lib${SUFFIX}/darling") 34 +
+54
src/IOKit/bsd.cpp
··· 1 + #include "bsd.h" 2 + #include "service.h" 3 + #include <cstring> 4 + #include <cstdio> 5 + #include <sys/types.h> 6 + #include <dirent.h> 7 + #include "constants.h" 8 + #include <CoreFoundation/CFString.h> 9 + 10 + std::string DarlingTranslateBSDName(const char* name); 11 + bool DarlingFindBSDName(const char* name, char* path); 12 + 13 + /* 14 + CFMutableDictionaryRef IOBSDNameMatching(void* iokitPort, unsigned int options, const char* bsdName) 15 + { 16 + // Search /sys/class/* for a device called bsdName 17 + bsdName = DarlingTranslateBSDName(bsdName); 18 + 19 + char path[PATH_MAX]; 20 + 21 + if (DarlingFindBSDName(bsdName, path)) 22 + return IOServiceSysPath(path); 23 + else 24 + return NULL; 25 + } 26 + */ 27 + 28 + 29 + std::string DarlingTranslateBSDName(const char* name) 30 + { 31 + int num; 32 + char linuxName[100]; 33 + 34 + // Macbooks have en0 = eth0, en1 = wlan0 35 + // We don't handle that yet 36 + if (sscanf(name, "en%d", &num) == 1) 37 + { 38 + sprintf(linuxName, "eth%d", num); 39 + return linuxName; 40 + } 41 + if (sscanf(name, "lo%d", &num) == 1) 42 + { 43 + return "lo"; 44 + } 45 + if (sscanf(name, "stf%d", &num) == 1) 46 + { 47 + sprintf(linuxName, "sit%d", num); 48 + return linuxName; 49 + } 50 + 51 + return name; 52 + } 53 + 54 +
+13
src/IOKit/bsd.h
··· 1 + #ifndef IOKIT_BSD_H 2 + #define IOKIT_BSD_H 3 + #include <CoreFoundation/CFDictionary.h> 4 + #include <string> 5 + 6 + extern "C" 7 + CFMutableDictionaryRef IOBSDNameMatching(void* iokitPort, unsigned int options, const char* bsdName); 8 + 9 + std::string DarlingTranslateBSDName(const char* name); 10 + bool DarlingFindBSDName(const char* name, char* path); 11 + 12 + #endif 13 +
+13
src/IOKit/cfutil.h
··· 1 + #ifndef IOKIT_CFUTIL_H 2 + #define IOKIT_CFUTIL_H 3 + 4 + #define strCFEqual(cfs, cstr) (CFStringCompare(cfs, CFSTR(cstr), CFStringCompareFlags(0)) == 0) 5 + 6 + inline CFStringRef strToCF(const char* val, CFAllocatorRef all = kCFAllocatorDefault) 7 + { 8 + if (!val) 9 + return nullptr; 10 + return CFStringCreateWithCString(kCFAllocatorDefault, val, kCFStringEncodingUTF8); 11 + } 12 + 13 + #endif
+41
src/IOKit/constants.h
··· 1 + #ifndef IOKIT_CONSTANTS_H 2 + #define IOKIT_CONSTANTS_H 3 + 4 + #define kIOMasterPortDefault NULL 5 + 6 + #define kIOProviderClassKey "IOProviderClass" 7 + #define kIOBSDNameKey "BSD Name" 8 + #define kIONameMatchKey "IONameMatch" 9 + #define kIOPropertyMatchKey "IOPropertyMatch" 10 + #define kIOPathMatchKey "IOPathMatch" 11 + #define kIOLocationMatchKey "IOLocationMatch" 12 + #define kIOParentMatchKey "IOParentMatch" 13 + #define kIOResourceMatchKey "IOResourceMatch" 14 + #define kIOMatchedServiceCountKey "IOMatchedServiceCountMatch" 15 + #define kIONameMatchedKey "IONameMatched" 16 + #define kIOMatchCategoryKey "IOMatchCategory" 17 + #define kIODefaultMatchCategoryKey "IODefaultMatchCategory" 18 + 19 + // ethernet 20 + #define kIOEthernetAddressSize 6 21 + #define kIOEthernetInterfaceClass "IOEthernetInterface" 22 + 23 + // serial 24 + #define kIOSerialBSDServiceValue "IOSerialBSDClient" 25 + #define kIOSerialBSDAllTypes "IOSerialStream" 26 + #define kIOSerialBSDModemType "IOModemSerialStream" 27 + #define kIOSerialBSDRS232Type "IORS232SerialStream" 28 + 29 + #define kIOTTYDeviceKey "IOTTYDevice" 30 + #define kIOTTYBaseNameKey "IOTTYBaseName" 31 + #define kIOTTYSuffixKey "IOTTYSuffix" 32 + #define kIOCalloutDeviceKey "IOCalloutDevice" 33 + #define kIODialinDeviceKey "IODialinDevice" 34 + 35 + // USB 36 + #define kIOUSBDeviceClassName "IOUSBDevice" 37 + #define kIOUSBInterfaceClassName "IOUSBInterface" 38 + #define kIOHIDDeviceKey "IOHIDDevice" 39 + 40 + #endif 41 +
+98
src/IOKit/io_device.cpp
··· 1 + #include "io_device.h" 2 + #include <cstdlib> 3 + #include "cfutil.h" 4 + 5 + io_device::io_device(struct udev_device* dev) 6 + : m_device(dev) 7 + { 8 + m_properties = udev_device_get_properties_list_entry(m_device); 9 + m_sysattrs = udev_device_get_sysattr_list_entry(m_device); 10 + } 11 + 12 + io_device::~io_device() 13 + { 14 + udev_device_unref(m_device); 15 + } 16 + 17 + const char* io_device::property(const char* name) 18 + { 19 + struct udev_list_entry* p = udev_list_entry_get_by_name(m_properties, name); 20 + if (p != nullptr) 21 + return udev_list_entry_get_value(p); 22 + else 23 + return nullptr; 24 + } 25 + 26 + const char* io_device::sysattr(const char* name) 27 + { 28 + struct udev_list_entry* p = udev_list_entry_get_by_name(m_sysattrs, name); 29 + if (p != nullptr) 30 + return udev_list_entry_get_value(p); 31 + else 32 + return nullptr; 33 + } 34 + 35 + CFStringRef io_device::sysattrStr(const char* name, CFAllocatorRef allocator) 36 + { 37 + return strToCF(sysattr(name), allocator); 38 + } 39 + 40 + CFNumberRef io_device::sysattrNum(const char* name, CFAllocatorRef allocator) 41 + { 42 + const char* value = sysattr(name); 43 + if (!value) 44 + return nullptr; 45 + 46 + char* end; 47 + long lvalue = strtol(value, &end, 16); 48 + 49 + if (end == value) 50 + return nullptr; 51 + 52 + return CFNumberCreate(allocator, kCFNumberLongType, &lvalue); 53 + } 54 + 55 + CFTypeRef io_device::retrieve(const property_mapping* mapping, CFAllocatorRef allocator) 56 + { 57 + const char* value = nullptr; 58 + if (mapping->linuxProperty) 59 + value = property(mapping->linuxProperty); 60 + else if (mapping->linuxSysAttr) 61 + value = sysattr(mapping->linuxSysAttr); 62 + if (!value) 63 + return nullptr; 64 + 65 + if (mapping->dataType == property_mapping::String) 66 + return strToCF(value, allocator); 67 + else 68 + { 69 + int base = (mapping->dataType == property_mapping::Number10) ? 10 : 16; 70 + char* end; 71 + long lvalue = strtol(value, &end, base); 72 + 73 + if (end == value) 74 + return nullptr; 75 + 76 + return CFNumberCreate(allocator, kCFNumberLongType, &lvalue); 77 + } 78 + } 79 + 80 + void io_device::properties(CFMutableDictionaryRef dict, CFAllocatorRef allocator) 81 + { 82 + } 83 + 84 + CFTypeRef io_device::property(CFStringRef name, CFAllocatorRef allocator) 85 + { 86 + return nullptr; 87 + } 88 + 89 + const property_mapping* property_mapping::find(const property_mapping* map, size_t count, CFStringRef what) 90 + { 91 + for (size_t i = 0; i < count; i++) 92 + { 93 + if (CFStringCompare(map[i].appleName, what, CFStringCompareFlags(0)) == 0) 94 + return map + i; 95 + } 96 + return nullptr; 97 + } 98 +
+41
src/IOKit/io_device.h
··· 1 + #ifndef IOKIT_IODEVICE_H 2 + #define IOKIT_IODEVICE_H 3 + #include <CoreFoundation/CFString.h> 4 + #include <CoreFoundation/CFNumber.h> 5 + #include <libudev.h> 6 + #include "io_object.h" 7 + 8 + struct property_mapping; 9 + 10 + class io_device : public io_object 11 + { 12 + public: 13 + io_device(struct udev_device* device); 14 + virtual ~io_device(); 15 + virtual void properties(CFMutableDictionaryRef dict, CFAllocatorRef allocator); 16 + virtual CFTypeRef property(CFStringRef name, CFAllocatorRef allocator); 17 + protected: 18 + const char* property(const char* name); 19 + const char* sysattr(const char* name); 20 + CFStringRef sysattrStr(const char* name, CFAllocatorRef allocator); 21 + CFNumberRef sysattrNum(const char* name, CFAllocatorRef allocator); 22 + CFTypeRef retrieve(const property_mapping* mapping, CFAllocatorRef allocator); 23 + protected: 24 + struct udev_device* m_device; 25 + struct udev_list_entry *m_properties, *m_sysattrs; 26 + }; 27 + 28 + struct property_mapping 29 + { 30 + CFStringRef appleName; 31 + const char* linuxProperty; 32 + const char* linuxSysAttr; 33 + 34 + enum DataType { String, Number10, Number16 }; 35 + DataType dataType; 36 + 37 + static const property_mapping* find(const property_mapping* map, size_t count, CFStringRef what); 38 + }; 39 + 40 + #endif 41 +
+28
src/IOKit/io_device_iterator.cpp
··· 1 + #include "io_device_iterator.h" 2 + #include "io_device.h" 3 + #include <libudev.h> 4 + 5 + io_device_iterator::io_device_iterator(udev_enumerate* uenum) 6 + : m_uenum(uenum) 7 + { 8 + m_udev = udev_new(); 9 + m_next = udev_enumerate_get_list_entry(uenum); 10 + } 11 + 12 + io_device_iterator::~io_device_iterator() 13 + { 14 + udev_enumerate_unref(m_uenum); 15 + udev_unref(m_udev); 16 + } 17 + 18 + io_object_t io_device_iterator::next() 19 + { 20 + if (!m_next) 21 + return nullptr; 22 + else 23 + { 24 + udev_device* dev = udev_device_new_from_syspath(m_udev, udev_list_entry_get_name(m_next)); 25 + m_next = udev_list_entry_get_next(m_next); 26 + return new io_device(dev); 27 + } 28 + }
+19
src/IOKit/io_device_iterator.h
··· 1 + #ifndef IOKIT_IODEVICEITERATOR_H 2 + #define IOKIT_IODEVICEITERATOR_H 3 + #include "io_iterator.h" 4 + 5 + class io_device_iterator : public io_iterator 6 + { 7 + public: 8 + io_device_iterator(struct udev_enumerate* uenum); 9 + virtual ~io_device_iterator(); 10 + virtual io_object_t next() override; 11 + private: 12 + struct udev* m_udev; 13 + struct udev_enumerate* m_uenum; 14 + struct udev_list_entry* m_next; 15 + }; 16 + 17 + typedef io_device_iterator* io_device_iterator_t; 18 + 19 + #endif
+29
src/IOKit/io_device_usb.cpp
··· 1 + #include "io_device_usb.h" 2 + 3 + // https://developer.apple.com/library/mac/#documentation/IOKit/Reference/USBSpec_header_reference/Reference/reference.html 4 + static const property_mapping usb_properties[] = { 5 + { CFSTR("Serial Number"), nullptr, "serial", property_mapping::String }, 6 + { CFSTR("USB Product Name"), nullptr, "product", property_mapping::String }, 7 + { CFSTR("USB Vendor Name"), nullptr, "manufacturer", property_mapping::String }, 8 + { CFSTR("VendorID"), nullptr, "idVendor", property_mapping::Number16 }, 9 + { CFSTR("ProductID"), nullptr, "idProduct", property_mapping::Number16 }, 10 + { CFSTR("bInterfaceClass"), nullptr, "bInterfaceClass", property_mapping::Number16 }, 11 + { CFSTR("bDeviceClass"), nullptr, "bDeviceClass", property_mapping::Number16 }, 12 + }; 13 + 14 + 15 + CFTypeRef io_device_usb::property(CFStringRef name, CFAllocatorRef allocator) 16 + { 17 + const property_mapping* prop = property_mapping::find(usb_properties, sizeof(usb_properties)/sizeof(usb_properties[0]), name); 18 + 19 + if (!prop) 20 + return nullptr; 21 + else 22 + return retrieve(prop, allocator); 23 + } 24 + 25 + void io_device_usb::properties(CFMutableDictionaryRef dict, CFAllocatorRef allocator) 26 + { 27 + // walk dict, call retrieve() 28 + 29 + }
+16
src/IOKit/io_device_usb.h
··· 1 + #ifndef IOKIT_IODEVICEUSB_H 2 + #define IOKIT_IODEVICEUSB_H 3 + #include "io_device.h" 4 + 5 + class io_device_usb : public io_device 6 + { 7 + public: 8 + // error: inheriting constructors are not supported 9 + // using io_device::io_device; 10 + 11 + io_device_usb(struct udev_device* device) : io_device(device) {} 12 + virtual CFTypeRef property(CFStringRef name, CFAllocatorRef allocator) override; 13 + virtual void properties(CFMutableDictionaryRef dict, CFAllocatorRef allocator) override; 14 + }; 15 + 16 + #endif
+13
src/IOKit/io_iterator.h
··· 1 + #ifndef IOKIT_IOITERATOR_H 2 + #define IOKIT_IOITERATOR_H 3 + #include "io_object.h" 4 + 5 + class io_iterator : public io_object 6 + { 7 + public: 8 + virtual io_object_t next() = 0; 9 + }; 10 + 11 + typedef io_iterator* io_iterator_t; 12 + 13 + #endif
+6
src/IOKit/io_object.cpp
··· 1 + #include "io_object.h" 2 + 3 + io_object::~io_object() 4 + { 5 + } 6 +
+15
src/IOKit/io_object.h
··· 1 + #ifndef IOKIT_IOOBJECT_H 2 + #define IOKIT_IOOBJECT_H 3 + 4 + class io_object 5 + { 6 + public: 7 + virtual ~io_object(); 8 + }; 9 + 10 + typedef io_object* io_object_t; 11 + 12 + extern "C" int IOObjectRelease(io_object_t obj); 13 + 14 + #endif 15 +
src/IOKit/port.c

This is a binary file and will not be displayed.

src/IOKit/port.h

This is a binary file and will not be displayed.

+25
src/IOKit/service.h
··· 1 + #ifndef IOKIT_SERVICE_H 2 + #define IOKIT_SERVICE_H 3 + #ifndef __STDC_LIMIT_MACROS 4 + # define __STDC_LIMIT_MACROS 5 + #endif 6 + 7 + #include "io_object.h" 8 + #include "io_iterator.h" 9 + #include <CoreFoundation/CFDictionary.h> 10 + 11 + // This seems to give all children (e.g. all USB devices) 12 + extern "C" CFMutableDictionaryRef IOServiceMatching(const char* service); 13 + // This seems to give the root device (e.g. the USB driver) 14 + extern "C" CFMutableDictionaryRef IOServiceNameMatching(const char* name); 15 + extern "C" CFMutableDictionaryRef IOBSDNameMatching(void* iokitPort, unsigned int options, const char* bsdName); 16 + 17 + extern "C" int IOServiceGetMatchingServices(void* port, CFDictionaryRef rules, io_iterator_t* iter); 18 + extern "C" int IOIteratorIsValid(io_iterator_t iter); 19 + extern "C" io_object_t IOIteratorNext(io_iterator_t iter); 20 + extern "C" int IOObjectRelease(io_object_t obj); 21 + 22 + extern "C" int IORegistryEntryCreateCFProperties(io_object_t obj, CFMutableDictionaryRef* props, CFAllocatorRef allocator, int opts); 23 + 24 + #endif 25 +
+190
src/IOKit/service.mm
··· 1 + #include "service.h" 2 + #include "constants.h" 3 + #include "bsd.h" 4 + #include <Foundation/NSString.h> 5 + #include <CoreFoundation/CFString.h> 6 + #include <libudev.h> 7 + #include <stdlib.h> 8 + #include <list> 9 + #include <string> 10 + #include <sys/types.h> 11 + #include <dirent.h> 12 + #include "../util/stlutils.h" 13 + #include "../util/log.h" 14 + #include "io_device.h" 15 + #include "io_device_iterator.h" 16 + #include "cfutil.h" 17 + 18 + static void filterByBSDName(struct udev_enumerate* uenum, CFStringRef str); 19 + static void filterByClass(struct udev_enumerate* uenum, CFStringRef str); 20 + static void filterByDriver(struct udev_enumerate* uenum, CFStringRef str); 21 + static void filterByProperties(struct udev_enumerate* uenum, CFDictionaryRef dict); 22 + 23 + io_object_t IOIteratorNext(io_iterator_t iter) 24 + { 25 + return iter->next(); 26 + } 27 + 28 + static CFMutableDictionaryRef createMatchingDictionary(CFStringRef key, CFStringRef value) 29 + { 30 + CFMutableDictionaryRef dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); 31 + CFDictionarySetValue(dict, key, value); 32 + return dict; 33 + } 34 + 35 + CFMutableDictionaryRef IOServiceMatching(const char* service) 36 + { 37 + static CFStringRef str = CFSTR(kIOProviderClassKey); 38 + return createMatchingDictionary(str, strToCF(service)); 39 + } 40 + 41 + CFMutableDictionaryRef IOServiceNameMatching(const char* name) 42 + { 43 + static CFStringRef str = CFSTR(kIONameMatchKey); 44 + return createMatchingDictionary(str, strToCF(name)); 45 + } 46 + 47 + CFMutableDictionaryRef IOBSDNameMatching(void* iokitPort, unsigned int options, const char* bsdName) 48 + { 49 + static CFStringRef str = CFSTR(kIOBSDNameKey); 50 + return createMatchingDictionary(str, strToCF(bsdName)); 51 + } 52 + 53 + int IOServiceGetMatchingServices(void* port, CFDictionaryRef rules, io_device_iterator_t* iter) 54 + { 55 + size_t size = CFDictionaryGetCount(rules); 56 + CFStringRef* keys = new CFStringRef[size]; 57 + CFDictionaryGetKeysAndValues(rules, (const void **) keys, nullptr); 58 + struct udev* udev; 59 + struct udev_enumerate* uenum; 60 + struct udev_list_entry* list; 61 + const void* value; 62 + 63 + udev = udev_new(); 64 + uenum = udev_enumerate_new(udev); 65 + 66 + if ((value = CFDictionaryGetValue(rules, CFSTR(kIOProviderClassKey)))) 67 + filterByClass(uenum, (CFStringRef) value); 68 + 69 + if ((value = CFDictionaryGetValue(rules, CFSTR(kIOBSDNameKey)))) 70 + filterByBSDName(uenum, (CFStringRef) value); 71 + 72 + if ((value = CFDictionaryGetValue(rules, CFSTR(kIOPropertyMatchKey)))) 73 + filterByProperties(uenum, (CFDictionaryRef) value); 74 + 75 + delete [] keys; 76 + udev_unref(udev); 77 + 78 + udev_enumerate_scan_devices(uenum); 79 + *iter = new io_device_iterator(uenum); 80 + 81 + return 0; 82 + } 83 + 84 + int IOIteratorIsValid(io_iterator_t iter) 85 + { 86 + return iter != nullptr; 87 + } 88 + 89 + int IOObjectRelease(io_object_t obj) 90 + { 91 + delete obj; 92 + return 0; 93 + } 94 + 95 + 96 + int IORegistryEntryCreateCFProperties(io_object_t obj, CFMutableDictionaryRef* props, CFAllocatorRef allocator, int opts) 97 + { 98 + io_device* dev = dynamic_cast<io_device*>(obj); 99 + 100 + if (!dev) 101 + { 102 + *props = nullptr; 103 + return -4; 104 + } 105 + else 106 + { 107 + *props = CFDictionaryCreateMutable(allocator, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); 108 + dev->properties(*props, allocator); 109 + return 0; 110 + } 111 + } 112 + 113 + void filterByClass(struct udev_enumerate* uenum, CFStringRef str) 114 + { 115 + if (strCFEqual(str, kIOEthernetInterfaceClass)) 116 + udev_enumerate_add_match_subsystem(uenum, "net"); 117 + else if (strCFEqual(str, kIOSerialBSDServiceValue)) 118 + udev_enumerate_add_match_subsystem(uenum, "tty"); 119 + else if (strCFEqual(str, kIOUSBDeviceClassName)) 120 + udev_enumerate_add_match_subsystem(uenum, "usb"); 121 + else if (strCFEqual(str, kIOHIDDeviceKey)) 122 + udev_enumerate_add_match_subsystem(uenum, "hidraw"); 123 + } 124 + 125 + void filterByBSDName(struct udev_enumerate* uenum, CFStringRef str) 126 + { 127 + std::string translated = DarlingTranslateBSDName([(NSString*) str UTF8String]); 128 + udev_enumerate_add_match_sysname(uenum, translated.c_str()); 129 + } 130 + 131 + void filterByDriver(struct udev_enumerate* uenum, CFStringRef str) 132 + { 133 + const char* driver = nullptr; 134 + 135 + if (strCFEqual(str, "AppleUSBEHCI")) 136 + driver = "ehci_hcd"; 137 + else if (strCFEqual(str, "AppleUSBOHCI")) 138 + driver = "ohci_hcd"; 139 + else if (strCFEqual(str, "AppleUSBUHCI")) 140 + driver = "uhci_hcd"; 141 + else if (strCFEqual(str, "AppleUSBCDC")) 142 + driver = "cdc_acm"; 143 + else if (strCFEqual(str, "processor")) 144 + driver = "processor"; 145 + else 146 + driver = [(NSString*) str UTF8String]; 147 + 148 + udev_enumerate_add_match_property(uenum, "driver", driver); 149 + } 150 + 151 + void filterByProperties(struct udev_enumerate* uenum, CFDictionaryRef dict) 152 + { 153 + size_t size = CFDictionaryGetCount(dict); 154 + CFStringRef* keys = new CFStringRef[size]; 155 + CFDictionaryGetKeysAndValues(dict, (const void **) keys, nullptr); 156 + 157 + for (size_t i = 0; i < size; i++) 158 + { 159 + const void* value = CFDictionaryGetValue(dict, keys[i]); 160 + const char* svalue = nullptr; 161 + const char* key = nullptr; 162 + CFStringRef str = keys[i]; 163 + 164 + if (strCFEqual(str, "VendorID")) 165 + { 166 + key = "ID_VENDOR_ID"; 167 + svalue = [(NSString*)value UTF8String]; 168 + } 169 + else if (strCFEqual(str, "ProductID")) 170 + { 171 + key = "ID_MODEL_ID"; 172 + svalue = [(NSString*)value UTF8String]; 173 + } 174 + else if (strCFEqual(str, "IOPrimaryInterface")) 175 + { 176 + key = "INTERFACE"; 177 + svalue = "eth0"; 178 + } 179 + 180 + if (key != nullptr) 181 + udev_enumerate_add_match_property(uenum, key, svalue); 182 + else 183 + LOG << "Ignoring property " << [(NSString*) str UTF8String] << " in IOKit filterByProperties\n"; 184 + } 185 + 186 + delete [] keys; 187 + } 188 + 189 + 190 +