kIOReturnNotPermitted 从 IOServiceOpen 连接到 SystemExtension IOService
kIOReturnNotPermitted from IOServiceOpen connecting to SystemExtension IOService
我正在尝试创建到 SystemExtension IOService 的客户端连接。我可以看到我的 IOUserClient
子类已创建(init()
和 Start(IOService*)
被调用),但是 IOServiceOpen
returns return 代码 kIOReturnNotPermitted
.
我正在从创建激活请求的同一个应用程序调用 IOServiceOpen
。
发出激活请求/调用 IOServiceOpen
的应用的权利:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.developer.driverkit.userclient-access</key>
<array>
<string>sc.example.MyUserUSBInterfaceDriver</string>
</array>
<key>com.apple.developer.system-extension.install</key>
<true/>
<key>com.apple.developer.system-extension.uninstall</key>
<true/>
</dict>
</plist>
dext 的权利:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.developer.driverkit.userclient-access</key>
<array>
<string>sc.example.USBApp</string>
</array>
<key>com.apple.developer.driverkit</key>
<true/>
<key>com.apple.developer.driverkit.transport.usb</key>
<true/>
</dict>
</plist>
我的用户客户端:
#ifndef MyUserClient_h
#define MyUserClient_h
#include <DriverKit/IOUserClient.iig>
class MyUserClient : public IOUserClient {
public:
bool init() override;
kern_return_t Start(IOService* provider) override;
kern_return_t Stop(IOService* provider) override;
void free() override;
};
#endif /* MyUserClient_h */
bool MyUserClient::init() {
LOG();
if (!super::init()) {
LOG("super::init() failed");
return false;
}
return true;
}
kern_return_t IMPL(MyUserClient, Start) {
LOG();
auto ret = Start(provider, SUPERDISPATCH);
if (ret != kIOReturnSuccess) {
LOG("SUPERDISPATCH Start failed, ret: %{public}d", ret);
}
return ret;
}
kern_return_t IMPL(MyUserClient, Stop) {
LOG();
auto ret = Stop(provider, SUPERDISPATCH);
if (ret != kIOReturnSuccess) {
LOG("SUPERDISPATCH Stop failed, ret: %{public}d", ret);
}
return ret;
}
void MyUserClient::free() {
super::free();
LOG();
}
LOG
只是一个执行 os_log(OS_LOG_DEFAULT, ...
的宏
NewUserClient
实施:
kern_return_t IMPL(MyUserUSBInterfaceDriver, NewUserClient) {
LOG("%{public}d:", type);
IOService* client;
auto ret = Create(this, "UserClientProperties", &client);
*userClient = OSDynamicCast(IOUserClient, client);
if (!(*userClient) || ret != kIOReturnSuccess) {
LOG("Failed to create IOUserClient, %{public}d", ret);
}
return ret;
}
连接到系统扩展的代码:
void connectToDext(io_service_t* serviceObject) {
io_connect_t dataPort;
kern_return_t kernResult =IOServiceOpen(*serviceObject, mach_task_self(), 123, &dataPort);
if (kernResult != KERN_SUCCESS) {
printf("IOServicceOpen failed: %d, %s\n", kernResult, kern_return_t_toCStr(kernResult));
}
kernResult = IOServiceClose(dataPort);
if (kernResult != KERN_SUCCESS) {
printf("IOServicceClosed failed: %d, %s\n", kernResult, kern_return_t_toCStr(kernResult));
}
}
int connectToFirstDext() {
CFMutableDictionaryRef matchingDict;
matchingDict = IOServiceMatching("IOService");
if (matchingDict == 0) {
return -1;
}
io_iterator_t iter;
if (IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDict, &iter) !=
KERN_SUCCESS) {
printf("IOServiceGetMatchingServices failed.\n");
return -1;
}
io_service_t device;
while ((device = IOIteratorNext(iter))) {
io_name_t deviceName;
if (IORegistryEntryGetName(device, deviceName) == KERN_SUCCESS) {
printf("name: %s\n", deviceName);
if (strcmp(deviceName, "MyUserUSBInterfaceDriver") == 0) {
printf("Calling connect\n");
connectToDext(&device);
}
}
IOObjectRelease(device);
}
IOObjectRelease(iter);
return 0;
}
编辑:
Info.plist 个应用
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>BuildMachineOSBuild</key>
<string>19E287</string>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>USBApp</string>
<key>CFBundleIdentifier</key>
<string>sc.example.USBApp</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>USBApp</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSupportedPlatforms</key>
<array>
<string>MacOSX</string>
</array>
<key>CFBundleVersion</key>
<string>1</string>
<key>DTCompiler</key>
<string>com.apple.compilers.llvm.clang.1_0</string>
<key>DTPlatformBuild</key>
<string>11E503a</string>
<key>DTPlatformVersion</key>
<string>GM</string>
<key>DTSDKBuild</key>
<string>19E258</string>
<key>DTSDKName</key>
<string>macosx10.15</string>
<key>DTXcode</key>
<string>1141</string>
<key>DTXcodeBuild</key>
<string>11E503a</string>
<key>LSMinimumSystemVersion</key>
<string>10.15</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2020 Example. All rights reserved.</string>
<key>NSMainNibFile</key>
<string>MainMenu</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
<key>NSSupportsAutomaticTermination</key>
<true/>
<key>NSSupportsSuddenTermination</key>
<true/>
</dict>
</plist>
Info.plist 的 dext:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>BuildMachineOSBuild</key>
<string>19E287</string>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>sc.example.MyUserUSBInterfaceDriver</string>
<key>CFBundleIdentifier</key>
<string>sc.example.MyUserUSBInterfaceDriver</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>sc.example.MyUserUSBInterfaceDriver</string>
<key>CFBundlePackageType</key>
<string>DEXT</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSupportedPlatforms</key>
<array>
<string>MacOSX</string>
</array>
<key>CFBundleVersion</key>
<string>1</string>
<key>DTCompiler</key>
<string>com.apple.compilers.llvm.clang.1_0</string>
<key>DTPlatformBuild</key>
<string>11E503a</string>
<key>DTPlatformVersion</key>
<string>GM</string>
<key>DTSDKBuild</key>
<string></string>
<key>DTSDKName</key>
<string>driverkit.macosx19.0</string>
<key>DTXcode</key>
<string>1141</string>
<key>DTXcodeBuild</key>
<string>11E503a</string>
<key>IOKitPersonalities</key>
<dict>
<key>example_device</key>
<dict>
<key>CFBundleIdentifier</key>
<string>sc.example.MyUserUSBInterfaceDriver</string>
<key>IOClass</key>
<string>IOUserService</string>
<key>IOProviderClass</key>
<string>IOUSBHostInterface</string>
<key>IOUserClass</key>
<string>MyUserUSBInterfaceDriver</string>
<key>IOUserServerName</key>
<string>sc.example.MyUserUSBInterfaceDriver</string>
<key>UserClientProperties</key>
<dict>
<key>IOClass</key>
<string>IOUserUserClient</string>
<key>IOServiceDEXTEntitlements</key>
<string></string>
<key>IOUserClass</key>
<string>MyUserClient</string>
</dict>
<key>bConfigurationValue</key>
<integer>1</integer>
<key>bInterfaceNumber</key>
<integer>0</integer>
<key>idProduct</key>
<integer>8</integer>
<key>idVendor</key>
<integer>1234</integer>
</dict>
</dict>
<key>OSBundleUsageDescription</key>
<string>Example user space USB driver</string>
<key>OSMinimumDriverKitVersion</key>
<string>19.4</string>
</dict>
</plist>
与您的问题无关 - 我将尝试单独回答您的实际问题 - 但我注意到您正在通过遍历所有 IOService
对象来定位您的服务。你可以通过直接使用 属性 匹配来匹配它,从而更优雅地找到它。我使用辅助函数来生成看起来像这样的匹配字典:
// Creates IOKit matching dictionary for locating driverkit-based service objects
// (Corresponds to kext services' IOServiceMatching())
static CFMutableDictionaryRef user_service_matching(CFStringRef driverkit_classname, CFStringRef driverkit_server_bundle_id) CF_RETURNS_RETAINED
{
CFMutableDictionaryRef match = IOServiceMatching("IOUserService");
CFTypeRef match_property_keys[] = { CFSTR("IOUserClass"), kIOBundleIdentifierKey };
CFTypeRef match_property_values[] = { driverkit_classname, driverkit_server_bundle_id };
CFDictionaryRef match_properties = CFDictionaryCreate(
kCFAllocatorDefault,
match_property_keys, match_property_values, 2,
&kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
CFDictionaryAddValue(match, CFSTR(kIOPropertyMatchKey), match_properties);
CFRelease(match_properties);
return match;
}
这匹配:
-
IOUserService
类型的对象(这是一个比 IOService
小得多的搜索 space 并且 dexts 中的所有直接 IOService
subclasses 实际上是IOUserService
"real"(内核)I/O 注册表中的对象。)
IOUserClass
属性 与提供的 driverkit_classname
匹配(在您的情况下为 CFSTR("MyUserUSBInterfaceDriver")
)
- 与
CFBundleIdentifier
匹配提供的。 (CFSTR("sc.example.MyUserUSBInterfaceDriver")
)
虽然相对不太可能,但在您发布的代码中通过 IORegistryEntryGetName
检索到的服务 name 理论上可能会与其他 kexts 或 dexts 发生冲突,而应该包标识符中没有歧义,当您的驱动程序实现多个 classes.
时,匹配用户 class 会很有帮助
更新的答案:
您的 IOKitPersonality Info.plist
的用户客户端 属性 字典中的 IOServiceDEXTEntitlements
属性 应该是以下之一:
- 完全缺失;这意味着:不要检查我原始答案中下面列出的基础以外的客户端权利。
- 我觉得,一个字符串数组的数组;客户端必须具有 all 内部数组 one 中列出的权利。 (注意:我没有对后一种情况进行任何测试。)
非数组或空数组 IOServiceDEXTEntitlements
属性 意味着客户端 无法匹配 one 中的权利内部数组,因为没有 any. 因此检查 总是失败 kIOReturnNotPermitted
。这就是您的(空)字符串值所发生的情况。
有关详细信息,请检查 IOUserServer::checkEntitlements()
中的代码以及从 xnu 源代码中 IOUserServer::serviceNewUserClient()
中 IOUserServer.cpp 中调用它的位置。
原回答:
(在 Info.plist
的内容发布之前给出。)
我没有发现您发布的内容有任何明显的错误,所以我怀疑您的问题可能是由您尚未发布的内容引起的。注意事项:
- 用户客户端应用程序的
com.apple.developer.driverkit.userclient-access
数组必须包含 dext 的包 ID。也许仔细检查这个 ID 真的等于 sc.example.MyUserUSBInterfaceDriver
? (我之前因为 kIOReturnNotPermitted
错误在这里拼写错误花了一个多小时。)
- 必须允许用户客户端应用程序与 IOKit 对话。默认情况下就是这种情况,除非您的应用程序是沙盒的。假设您发布的权利是完整,您的应用程序没有沙盒化,所以这应该不是问题。
- 如果用于创建新用户客户端的字典包含
IOServiceDEXTEntitlements
键,则用户 space 应用程序必须在此处列出所有权利。 (这本词典来自 dext 的 info.plist,您在撰写本文时尚未发布。)
- 我认为 dext 和应用程序必须使用相同的团队 ID 进行签名。 (我似乎记得你可以在 dext 上设置一个权利来解决这个要求。)也许使用
codesign -dv path/to/your.dext
和 codesign -dv path/to/your.app
仔细检查 TeamIdentifier
我正在尝试创建到 SystemExtension IOService 的客户端连接。我可以看到我的 IOUserClient
子类已创建(init()
和 Start(IOService*)
被调用),但是 IOServiceOpen
returns return 代码 kIOReturnNotPermitted
.
我正在从创建激活请求的同一个应用程序调用 IOServiceOpen
。
发出激活请求/调用 IOServiceOpen
的应用的权利:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.developer.driverkit.userclient-access</key>
<array>
<string>sc.example.MyUserUSBInterfaceDriver</string>
</array>
<key>com.apple.developer.system-extension.install</key>
<true/>
<key>com.apple.developer.system-extension.uninstall</key>
<true/>
</dict>
</plist>
dext 的权利:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.developer.driverkit.userclient-access</key>
<array>
<string>sc.example.USBApp</string>
</array>
<key>com.apple.developer.driverkit</key>
<true/>
<key>com.apple.developer.driverkit.transport.usb</key>
<true/>
</dict>
</plist>
我的用户客户端:
#ifndef MyUserClient_h
#define MyUserClient_h
#include <DriverKit/IOUserClient.iig>
class MyUserClient : public IOUserClient {
public:
bool init() override;
kern_return_t Start(IOService* provider) override;
kern_return_t Stop(IOService* provider) override;
void free() override;
};
#endif /* MyUserClient_h */
bool MyUserClient::init() {
LOG();
if (!super::init()) {
LOG("super::init() failed");
return false;
}
return true;
}
kern_return_t IMPL(MyUserClient, Start) {
LOG();
auto ret = Start(provider, SUPERDISPATCH);
if (ret != kIOReturnSuccess) {
LOG("SUPERDISPATCH Start failed, ret: %{public}d", ret);
}
return ret;
}
kern_return_t IMPL(MyUserClient, Stop) {
LOG();
auto ret = Stop(provider, SUPERDISPATCH);
if (ret != kIOReturnSuccess) {
LOG("SUPERDISPATCH Stop failed, ret: %{public}d", ret);
}
return ret;
}
void MyUserClient::free() {
super::free();
LOG();
}
LOG
只是一个执行 os_log(OS_LOG_DEFAULT, ...
NewUserClient
实施:
kern_return_t IMPL(MyUserUSBInterfaceDriver, NewUserClient) {
LOG("%{public}d:", type);
IOService* client;
auto ret = Create(this, "UserClientProperties", &client);
*userClient = OSDynamicCast(IOUserClient, client);
if (!(*userClient) || ret != kIOReturnSuccess) {
LOG("Failed to create IOUserClient, %{public}d", ret);
}
return ret;
}
连接到系统扩展的代码:
void connectToDext(io_service_t* serviceObject) {
io_connect_t dataPort;
kern_return_t kernResult =IOServiceOpen(*serviceObject, mach_task_self(), 123, &dataPort);
if (kernResult != KERN_SUCCESS) {
printf("IOServicceOpen failed: %d, %s\n", kernResult, kern_return_t_toCStr(kernResult));
}
kernResult = IOServiceClose(dataPort);
if (kernResult != KERN_SUCCESS) {
printf("IOServicceClosed failed: %d, %s\n", kernResult, kern_return_t_toCStr(kernResult));
}
}
int connectToFirstDext() {
CFMutableDictionaryRef matchingDict;
matchingDict = IOServiceMatching("IOService");
if (matchingDict == 0) {
return -1;
}
io_iterator_t iter;
if (IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDict, &iter) !=
KERN_SUCCESS) {
printf("IOServiceGetMatchingServices failed.\n");
return -1;
}
io_service_t device;
while ((device = IOIteratorNext(iter))) {
io_name_t deviceName;
if (IORegistryEntryGetName(device, deviceName) == KERN_SUCCESS) {
printf("name: %s\n", deviceName);
if (strcmp(deviceName, "MyUserUSBInterfaceDriver") == 0) {
printf("Calling connect\n");
connectToDext(&device);
}
}
IOObjectRelease(device);
}
IOObjectRelease(iter);
return 0;
}
编辑:
Info.plist 个应用
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>BuildMachineOSBuild</key>
<string>19E287</string>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>USBApp</string>
<key>CFBundleIdentifier</key>
<string>sc.example.USBApp</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>USBApp</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSupportedPlatforms</key>
<array>
<string>MacOSX</string>
</array>
<key>CFBundleVersion</key>
<string>1</string>
<key>DTCompiler</key>
<string>com.apple.compilers.llvm.clang.1_0</string>
<key>DTPlatformBuild</key>
<string>11E503a</string>
<key>DTPlatformVersion</key>
<string>GM</string>
<key>DTSDKBuild</key>
<string>19E258</string>
<key>DTSDKName</key>
<string>macosx10.15</string>
<key>DTXcode</key>
<string>1141</string>
<key>DTXcodeBuild</key>
<string>11E503a</string>
<key>LSMinimumSystemVersion</key>
<string>10.15</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2020 Example. All rights reserved.</string>
<key>NSMainNibFile</key>
<string>MainMenu</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
<key>NSSupportsAutomaticTermination</key>
<true/>
<key>NSSupportsSuddenTermination</key>
<true/>
</dict>
</plist>
Info.plist 的 dext:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>BuildMachineOSBuild</key>
<string>19E287</string>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>sc.example.MyUserUSBInterfaceDriver</string>
<key>CFBundleIdentifier</key>
<string>sc.example.MyUserUSBInterfaceDriver</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>sc.example.MyUserUSBInterfaceDriver</string>
<key>CFBundlePackageType</key>
<string>DEXT</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSupportedPlatforms</key>
<array>
<string>MacOSX</string>
</array>
<key>CFBundleVersion</key>
<string>1</string>
<key>DTCompiler</key>
<string>com.apple.compilers.llvm.clang.1_0</string>
<key>DTPlatformBuild</key>
<string>11E503a</string>
<key>DTPlatformVersion</key>
<string>GM</string>
<key>DTSDKBuild</key>
<string></string>
<key>DTSDKName</key>
<string>driverkit.macosx19.0</string>
<key>DTXcode</key>
<string>1141</string>
<key>DTXcodeBuild</key>
<string>11E503a</string>
<key>IOKitPersonalities</key>
<dict>
<key>example_device</key>
<dict>
<key>CFBundleIdentifier</key>
<string>sc.example.MyUserUSBInterfaceDriver</string>
<key>IOClass</key>
<string>IOUserService</string>
<key>IOProviderClass</key>
<string>IOUSBHostInterface</string>
<key>IOUserClass</key>
<string>MyUserUSBInterfaceDriver</string>
<key>IOUserServerName</key>
<string>sc.example.MyUserUSBInterfaceDriver</string>
<key>UserClientProperties</key>
<dict>
<key>IOClass</key>
<string>IOUserUserClient</string>
<key>IOServiceDEXTEntitlements</key>
<string></string>
<key>IOUserClass</key>
<string>MyUserClient</string>
</dict>
<key>bConfigurationValue</key>
<integer>1</integer>
<key>bInterfaceNumber</key>
<integer>0</integer>
<key>idProduct</key>
<integer>8</integer>
<key>idVendor</key>
<integer>1234</integer>
</dict>
</dict>
<key>OSBundleUsageDescription</key>
<string>Example user space USB driver</string>
<key>OSMinimumDriverKitVersion</key>
<string>19.4</string>
</dict>
</plist>
与您的问题无关 - 我将尝试单独回答您的实际问题 - 但我注意到您正在通过遍历所有 IOService
对象来定位您的服务。你可以通过直接使用 属性 匹配来匹配它,从而更优雅地找到它。我使用辅助函数来生成看起来像这样的匹配字典:
// Creates IOKit matching dictionary for locating driverkit-based service objects
// (Corresponds to kext services' IOServiceMatching())
static CFMutableDictionaryRef user_service_matching(CFStringRef driverkit_classname, CFStringRef driverkit_server_bundle_id) CF_RETURNS_RETAINED
{
CFMutableDictionaryRef match = IOServiceMatching("IOUserService");
CFTypeRef match_property_keys[] = { CFSTR("IOUserClass"), kIOBundleIdentifierKey };
CFTypeRef match_property_values[] = { driverkit_classname, driverkit_server_bundle_id };
CFDictionaryRef match_properties = CFDictionaryCreate(
kCFAllocatorDefault,
match_property_keys, match_property_values, 2,
&kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
CFDictionaryAddValue(match, CFSTR(kIOPropertyMatchKey), match_properties);
CFRelease(match_properties);
return match;
}
这匹配:
-
IOUserService
类型的对象(这是一个比IOService
小得多的搜索 space 并且 dexts 中的所有直接IOService
subclasses 实际上是IOUserService
"real"(内核)I/O 注册表中的对象。) IOUserClass
属性 与提供的driverkit_classname
匹配(在您的情况下为CFSTR("MyUserUSBInterfaceDriver")
)- 与
CFBundleIdentifier
匹配提供的。 (CFSTR("sc.example.MyUserUSBInterfaceDriver")
)
虽然相对不太可能,但在您发布的代码中通过 IORegistryEntryGetName
检索到的服务 name 理论上可能会与其他 kexts 或 dexts 发生冲突,而应该包标识符中没有歧义,当您的驱动程序实现多个 classes.
更新的答案:
您的 IOKitPersonality Info.plist
的用户客户端 属性 字典中的 IOServiceDEXTEntitlements
属性 应该是以下之一:
- 完全缺失;这意味着:不要检查我原始答案中下面列出的基础以外的客户端权利。
- 我觉得,一个字符串数组的数组;客户端必须具有 all 内部数组 one 中列出的权利。 (注意:我没有对后一种情况进行任何测试。)
非数组或空数组 IOServiceDEXTEntitlements
属性 意味着客户端 无法匹配 one 中的权利内部数组,因为没有 any. 因此检查 总是失败 kIOReturnNotPermitted
。这就是您的(空)字符串值所发生的情况。
有关详细信息,请检查 IOUserServer::checkEntitlements()
中的代码以及从 xnu 源代码中 IOUserServer::serviceNewUserClient()
中 IOUserServer.cpp 中调用它的位置。
原回答:
(在 Info.plist
的内容发布之前给出。)
我没有发现您发布的内容有任何明显的错误,所以我怀疑您的问题可能是由您尚未发布的内容引起的。注意事项:
- 用户客户端应用程序的
com.apple.developer.driverkit.userclient-access
数组必须包含 dext 的包 ID。也许仔细检查这个 ID 真的等于sc.example.MyUserUSBInterfaceDriver
? (我之前因为kIOReturnNotPermitted
错误在这里拼写错误花了一个多小时。) - 必须允许用户客户端应用程序与 IOKit 对话。默认情况下就是这种情况,除非您的应用程序是沙盒的。假设您发布的权利是完整,您的应用程序没有沙盒化,所以这应该不是问题。
- 如果用于创建新用户客户端的字典包含
IOServiceDEXTEntitlements
键,则用户 space 应用程序必须在此处列出所有权利。 (这本词典来自 dext 的 info.plist,您在撰写本文时尚未发布。) - 我认为 dext 和应用程序必须使用相同的团队 ID 进行签名。 (我似乎记得你可以在 dext 上设置一个权利来解决这个要求。)也许使用
codesign -dv path/to/your.dext
和codesign -dv path/to/your.app
仔细检查
TeamIdentifier