在 Xcode 项目(macOS 应用程序)中,我使用 DriverKit(和 HIDDriverKit)框架。我在客户端应用程序和驱动程序之间的连接中遇到了问题,该问题是由“IOKit”框架实现的。通过调用函数“IOServiceGetMatchingServices”,“iterator”的值正确返回,然后完成与驱动程序的通信。然而,在TestFlight上发布版本后,在某些系统上,“迭代器”的值返回0,并且无法与驱动程序通信。我使用命令“systemextensionsctl list”检查了激活的驱动程序的状态,驱动程序端没有问题,并且“Enabled”和“Active”的值已加星号。
AppSandbox = True,SIP:启用
ret = IOServiceGetMatchingServices(kIOMainPortDefault, IOServiceNameMatching(dextIdentifier), &iterator);
if (ret != kIOReturnSuccess)
{
goto fail;
}
while ((service = IOIteratorNext(iterator)) != IO_OBJECT_NULL) {
ret = IOServiceOpen(service, mach_task_self(), 0, &connection);
if(ret == kIOReturnSuccess)
{
break;
}
else
{
syslog(LOG_WARNING, "Error");
}
IOObjectRelease(service);
}
“ret”的返回值始终为 0 (kIOReturnSuccess),但“iterator”为 null (0)。
编辑: 根据我添加到驱动程序的日志,我意识到从客户端应用程序调用IOServiceOpen后,驱动程序被初始化,然后创建了IOUserClient,但它立即取消初始化并且IOServiceOpen返回错误。
当没有匹配服务时,空迭代器(不幸的是?)是
IOServiceGetMatchingServices
的有效输出。当没有匹配时,不能保证它会为空,但你必须接受它作为可能的输出。
例如,以下小程序在我的系统上触发空迭代器:
#include <IOKit/IOKitLib.h>
#include <stdio.h>
int main()
{
io_iterator_t iterator = IO_OBJECT_NULL;
IOReturn ret = IOServiceGetMatchingServices(MACH_PORT_NULL,
IOServiceNameMatching("MadeUpNameThatDefinitelyDoesntExist"), &iterator);
printf("IOServiceGetMatchingServices -> 0x%x, iterator = 0x%x\n", ret, iterator);
if (iterator != IO_OBJECT_NULL)
IOObjectRelease(iterator);
}
运行时:
$ ./matching-services-null-iterator
IOServiceGetMatchingServices -> 0x0, iterator = 0x0
例如,当您的驱动程序未匹配任何设备时,您可能期望没有匹配的服务。因此,您应该能够通过在未插入设备的情况下运行代码来重现该问题。