我正在尝试与应用程序中的 ext 进行交互。我可以找到使用的服务,IOServiceOpen并且可以调用NewUserClient我的 dext(我可以看到type传递的参数在日志中输出)。在此之后我有点失落。阅读此处有关NewUserClient的内容 ,我可以看到应该使用它Create来创建一个新的 Service 对象。
这里的讨论部分说字典中的键propertiesKey描述了新服务。
是否应该将此字典作为顶级条目放置在系统扩展的 plist 文件中,还是应该将字典放在 key 中IOKitPersonalities?
我可以将IOServiceDEXTEntitlements密钥保留为空值,以便不对连接到系统扩展的应用程序施加任何权利限制吗?
我的 plist 看起来像这样(键MyUserClientProperties/字典在两个地方)。
<?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>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>MyUserClientProperties</key>
<dict>
<key>IOClass</key>
<string>MyUserClient</string>
<key>IOUserClass</key>
<string>MyUserUSBInterfaceDriver</string>
<key>IOServiceDEXTEntitlements</key>
<string></string>
</dict>
<key>IOKitPersonalities</key>
<dict>
<key>example_device</key>
<dict>
<key>MyUserClientProperties</key> …Run Code Online (Sandbox Code Playgroud) 我已在应用程序中分配内存并将其指针和大小传递给 IOConnectCallStructMethod. 然后,IOMemoryDescriptor::CreateMapping我已将此内存映射到 DriverKit 系统扩展进程,并且可以写入此映射的内存位置并从我的应用程序读取数据。
我现在想对系统扩展中分配的内存执行类似的操作,然后将其映射到使用系统扩展的应用程序。我想在系统扩展中创建一组内存缓冲区,然后从应用程序写入它,然后向系统扩展发出信号,告知给IOConnectCallScalarMethod定的缓冲区应发送到 USB 设备,使用IOUSBHostPipe::AsyncIO. 当CompleteAsyncIO发送完成后出现回调时,我会通知应用程序现在可以将数据复制到发送的第一个缓冲区。此机制可能可以使用IOConnectCallAsyncStructMethod和OSAction在系统扩展中创建的对象来完成。我不明白的是如何将系统扩展中分配的内存映射到应用程序。
我们正在为 USB 麦克风开发自定义音频驱动程序,以便对输入音频流进行简单处理 (EQ)(与 Windows 的 APO 相当)。经过一些帮助,我们设法将我们的驱动程序(基于 SimpleAudioDriver )分配给正确的音频设备。但现在我们显示了两个设备:一个分配给我们的驱动程序,另一个分配给默认驱动程序。我们如何用我们的设备覆盖原来的设备,只显示一台设备?
我们已经尝试添加更多 IOKitPersonalities 以获得更好的探测分数,但结果是一样的。我们还读取了日志,原始驱动程序和我们的探测分数均处于最大值(100000)。
这是 info.plist 文件的当前状态:
<plist version="1.0">
<dict>
<key>IOKitPersonalities</key>
<dict>
<key>SimpleAudioDriver</key>
<dict>
<key>idProduct</key>
<integer>49456</integer>
<key>idVendor</key>
<integer>1130</integer>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>IOClass</key>
<string>IOUserService</string>
<key>IOMatchCategory</key>
<string>SimpleAudioDriver</string>
<key>IOProviderClass</key>
<string>IOUSBDevice</string>
<key>IOResourceMatch</key>
<string>IOKit</string>
<key>IOUserAudioDriverUserClientProperties</key>
<dict>
<key>IOClass</key>
<string>IOUserUserClient</string>
<key>IOUserClass</key>
<string>IOUserAudioDriverUserClient</string>
</dict>
<key>IOUserClass</key>
<string>SimpleAudioDriver</string>
<key>IOUserServerName</key>
<string>com.example.apple-samplecode.SimpleAudio.Driver</string>
<key>SimpleAudioDriverUserClientProperties</key>
<dict>
<key>IOClass</key>
<string>IOUserUserClient</string>
<key>IOUserClass</key>
<string>SimpleAudioDriverUserClient</string>
</dict>
</dict>
</dict>
</dict>
</plist>
Run Code Online (Sandbox Code Playgroud)
如果您有任何提示,请回复我们。
谢谢。
我正在尝试了解有关 DriverKit 和内存管理的更多信息,并且我读到了这个问题:
如何在 DriverKit 系统扩展中分配内存并将其映射到另一个进程?
我想了解如何使用IOMemoryDescriptor::CreateMapping.
我写了一个小应用程序来测试我所做的(非常简化的代码):
uint8_t * buffer = new uint8_t[256];
for (int i = 0 ; i < 256 ; i++)
buffer[i] = 0xC6;
clientData in, out;
in.nbytes = 256;
in.pbuffer = buffer;
size_t sout = sizeof(out);
IOConnectCallStructMethod(connection, selector,&in,sizeof(in),&out,&sout);
// out.pbuffer now has new values in it
Run Code Online (Sandbox Code Playgroud)
在我的 Kext 用户客户端类中,我正在做(我正在简化):
IOReturn UserClient::MyExtFunction(clientData * in, clientData * out, IOByteCount inSize, IOByteCount * outSize)
{
MyFunction(in->nBytes, in->pbuffer);//this will change the content of pbuffer
*out = *in; …Run Code Online (Sandbox Code Playgroud) 我们正在 macOS 上试验 DriverKit,而在 iPadOS 上 DriverKit 仍处于测试阶段。我们想要构建一个 iPad 驱动程序,允许我们的 iPad 应用程序与 USB 设备进行通信。
\n我们做了什么:
\nUSBDriverKit::IOUSBHostInterface。当我们将设备插入 USB 端口时,macOS 会自动匹配/启动该驱动程序。接下来我们利用USBDriverKit::IOUSBHostPipe从我们的设备发送/接收数据。我们现在在日志中打印来自设备的数据。IOUserClientmacOS 应用程序并允许使用 API 打开通信通道的驱动程序IOServiceOpen。驱动程序有回调将数据传递到 macOS 客户端应用程序。目前,我们希望组合 2 个驱动程序,并使用回调将从 USB 设备接收到的数据传递到我们的客户端应用程序。不幸的是,我们陷入了困境,因为现在我们有 2 个驱动程序实例:
\nvirtual kern_return_t NewUserClient(uint32_t type, IOUserClient** userClient)当我们从客户端应用程序连接并调用方法时创建第二个实例。因此,我们不能使用第二个实例进行 USB 设备通信,因为它有错误的提供程序(IOUserClient),kern_return_t Start(IOService * provider)但我们需要IOUSBHostInterface启动:
\xc2\xa0 \xc2\xa0 ivars->interface = …Run Code Online (Sandbox Code Playgroud)