kern_return_t IOHIDSetHIDParameterToEventSystem(io_connect_t handle, CFStringRef key, CFTypeRef parameter) { IOHIDEventSystemClientRef client = IOHIDEventSystemClientCreateWithType (kCFAllocatorDefault, kIOHIDEventSystemClientTypeMonitor, NULL); kern_return_t kr = kIOReturnNotReady; if (!client) { goto exit; } kr = kIOReturnUnsupported; io_service_t service = 0; if (IOConnectGetService (handle, &service) == kIOReturnSuccess) { if (IOObjectConformsTo (service, "IOHIDSystem")) { IOHIDEventSystemClientSetProperty(client, key, parameter); kr = kIOReturnSuccess; } else { uint64_t entryID = 0; if (IORegistryEntryGetRegistryEntryID (service, &entryID) == kIOReturnSuccess) { IOHIDServiceClientRef serviceClient = IOHIDEventSystemClientCopyServiceForRegistryID(client, entryID); if (serviceClient) { if (IOHIDServiceClientSetProperty(serviceClient, key, parameter)) { kr = kIOReturnSuccess; } else { kr = kIOReturnInternalError; } CFRelease(serviceClient); } } } IOObjectRelease(service); } exit: if (client) { CFRelease(client); } if (kr) { os_log_error(_IOHIDLog(), "Fail to set parameter with status 0x%x", kr); } return kr; }
kern_return_t IOHIDCopyHIDParameterFromEventSystem(io_connect_t handle, CFStringRef key, CFTypeRef *parameter) { CFTypeRef param = NULL; IOHIDEventSystemClientRef client = IOHIDEventSystemClientCreateWithType (kCFAllocatorDefault, kIOHIDEventSystemClientTypePassive, NULL); kern_return_t kr = kIOReturnNotReady; if (!client) { goto exit; } io_service_t service = 0; if (IOConnectGetService (handle, &service) == kIOReturnSuccess) { if (IOObjectConformsTo (service, "IOHIDSystem")) { param = IOHIDEventSystemClientCopyProperty(client, key); } else { uint64_t entryID = 0; if (IORegistryEntryGetRegistryEntryID (service, &entryID) == kIOReturnSuccess) { IOHIDServiceClientRef serviceClient = IOHIDEventSystemClientCopyServiceForRegistryID(client, entryID); if (serviceClient) { param = IOHIDServiceClientCopyProperty(serviceClient, key); CFRelease(serviceClient); } } } IOObjectRelease(service); } exit: if (param) { *parameter = param; kr = kIOReturnSuccess; } if (client) { CFRelease(client); } if (kr) { os_log_error(_IOHIDLog(), "Fail to get parameter with status 0x%x", kr); } return kr; }
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); }
static void dumpDevice(io_connect_t connect, uint32_t segment, uint32_t bus, uint32_t device, uint32_t fn, uint32_t * maxBus, uint32_t * maxFn) { io_registry_entry_t service; kern_return_t status; io_name_t name; uint64_t entryID; uint32_t off; uint32_t vendProd; uint32_t vend; uint32_t prod; uint32_t headerType; uint32_t priBusNum; uint32_t secBusNum; uint32_t subBusNum; uint32_t data[256/sizeof(uint32_t)]; uint8_t *bytes = (uint8_t *)&data[0]; for(off = 0; off < 256; off += 4) data[off >> 2] = configRead32(connect, segment, bus, device, fn, off); vendProd = data[0]; vend = vendProd & 0xffff; prod = vendProd >> 16; printf("[%d, %d, %d] 0x%04x, 0x%04x - ", bus, device, fn, vend, prod); service = lookService(segment, bus, device, fn); if (service) { status = IORegistryEntryGetName(service, name); assert(kIOReturnSuccess == status); status = IORegistryEntryGetRegistryEntryID(service, &entryID); assert(kIOReturnSuccess == status); printf("\"%s\", 0x%qx - ", name, entryID); IOObjectRelease(service); } headerType = bytes[kIOPCIConfigHeaderType]; if (maxFn && (0x80 & headerType)) *maxFn = 7; headerType &= 0x7f; if (!headerType) { // device dump printf("class: 0x%x, 0x%x, 0x%x\n", bytes[kIOPCIConfigRevisionID + 3], bytes[kIOPCIConfigRevisionID + 2], bytes[kIOPCIConfigRevisionID + 1]); } else { priBusNum = bytes[kPCI2PCIPrimaryBus]; secBusNum = bytes[kPCI2PCISecondaryBus]; subBusNum = bytes[kPCI2PCISubordinateBus]; printf("bridge: [%d, %d, %d]\n", priBusNum, secBusNum, subBusNum); if (maxBus && (subBusNum > *maxBus)) *maxBus = subBusNum; } dump(bytes, sizeof(data)); printf("\n"); }