【问题标题】:Prevent macOS generic keyboard driver from capturing usb-device阻止 macOS 通用键盘驱动程序捕获 USB 设备
【发布时间】:2017-06-26 15:33:59
【问题描述】:

我正在尝试用 C 语言为 USB 设备(带按钮的 Pentablet)编写 macOS 用户级驱动程序。

目前,此平板电脑被系统识别为通用鼠标和通用键盘。由于应用于 pentablet 按钮的快捷方式不可自定义,我想为此编写自己的驱动程序。

工作原理:

我可以使用 hidapi (http://www.signal11.us/oss/hidapi/) 从设备读取原始数据,如下所示:

A   B    C    D    E    F    G    H
10  192  228  50   157  43   0    0

我发现,当我使用笔时,B-H 列的值会根据笔的位置、压力和点击而变化。

我的问题:

但是,我不知道如何访问设备的按钮。每次我按下其中一个,它们的硬编码组合键就会被触发。由于A 列的值永远不会改变,我假设该设备仍被系统捕获为通用键盘,因此该列永远不会向我显示当前按下的按钮并触发它的组合键。

每次我按下其中一个按钮时,它们都会触发按住 ALT/Option + Shift,另外一些会触发一个字符,其中一个会触发音量增大。

因此,我的方法是使用无代码 kext 来防止系统捕获设备。但这也不起作用 - 该设备仍会被系统捕获为通用键盘。

我禁用了csrutil 并使用kextload,我的kext 位于/Library/Extensions,我收到一条成功的消息,表明kext 已加载:

Warnings:
    Personality CFBundleIdentifier differs from containing kext's (not necessarily a mistake, but rarely done):
        Tablet

Code Signing Failure: code signature is invalid
Warnings:
    Personality CFBundleIdentifier differs from containing kext's (not necessarily a mistake, but rarely done):
        Tablet

/Library/Extensions/foobartablet.kext appears to be loadable (not including linkage for on-disk libraries).
kext-dev-mode allowing invalid signature -67050 0xFFFFFFFFFFFEFA16 for kext "/Library/Extensions/foobartablet.kext"
kext signature failure override allowing invalid signature -67050 0xFFFFFFFFFFFEFA16 for kext "/Library/Extensions/foobartablet.kext"
Loading /Library/Extensions/foobartablet.kext.

这是我的 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>13C64</string>
    <key>CFBundleDevelopmentRegion</key>
    <string>English</string>
    <key>CFBundleGetInfoString</key>
    <string>1.0 Copyright © Adis Durakovic</string>
    <key>CFBundleIdentifier</key>
    <string>com.adisdurakovic.huitablet</string>
    <key>CFBundleInfoDictionaryVersion</key>
    <string>6.0</string>
    <key>CFBundlePackageType</key>
    <string>KEXT</string>
    <key>CFBundleShortVersionString</key>
    <string>Huion Tablet 1.0</string>
    <key>CFBundleSignature</key>
    <string>????</string>
    <key>CFBundleVersion</key>
    <string>1.0</string>
    <key>DTCompiler</key>
    <string>com.apple.compilers.llvm.clang.1_0</string>
    <key>DTPlatformBuild</key>
    <string>5A2053</string>
    <key>DTPlatformVersion</key>
    <string>GM</string>
    <key>DTSDKBuild</key>
    <string>13A595</string>
    <key>DTSDKName</key>
    <string>macosx10.9</string>
    <key>DTXcode</key>
    <string>0501</string>
    <key>DTXcodeBuild</key>
    <string>5A2053</string>
    <key>IOKitPersonalities</key>
    <dict>
        <key>Tablet</key>
        <dict>
            <key>CFBundleIdentifier</key>
            <string>com.apple.kpi.iokit</string>
            <key>IOClass</key>
            <string>IOService</string>
            <key>IOProviderClass</key>
            <string>IOUSBDevice</string>
            <key>idVendor</key>
            <string>9580</string>
            <key>idProduct</key>
            <string>110</string>
            <key>bcdDevice</key>
            <string>12288</string>
            <key>IOProbeScore</key>
            <integer>200000</integer>
        </dict>
        <key>TabletNew</key>
        <dict>
            <key>CFBundleIdentifier</key>
            <string>com.apple.kpi.iokit</string>
            <key>IOClass</key>
            <string>IOService</string>
            <key>IOProviderClass</key>
            <string>IOUSBHostDevice</string>
            <key>idVendor</key>
            <string>9580</string>
            <key>idProduct</key>
            <string>110</string>
            <key>bcdDevice</key>
            <string>12288</string>
            <key>IOProbeScore</key>
            <integer>300000</integer>
        </dict>
    </dict>
    <key>OSBundleLibraries</key>
    <dict/>
</dict>
</plist>

这也是我用于设备匹配的ioreg -i -w 0 -l -n "PenTablet" 输出: https://adisdurakovic.com/pentablet.txt

我在这里做错了什么?

【问题讨论】:

  • 设备是否可以模拟按钮的另一个界面,以便可以将它们作为单独的输入读取?
  • @Nick,有什么提示可以告诉我如何在这个方向上进一步调查?
  • 老实说,我在纯 Linux 环境设备方面的经验要丰富得多。我之所以发表评论,是因为我曾经遇到过类似的问题,该设备具有两个 USB 逻辑接口,因此它的按钮可以被视为通用键盘输入。在 Linux 中,我会将 USB 开发文件的内容与拔出的设备与插入的设备进行比较以查看设备。我不确定MacOS。抱歉,我不能提供更多帮助。
  • @Nick 这仍然是一个非常有用的输入。也许进一步的研究可以引导我接受你的建议。无论如何,谢谢你的帮助,我很感激;-)

标签: c macos usb kernel-extension


【解决方案1】:

既然您提到了 SIP,我假设您正在 10.11 或更高版本上进行测试。您的 IOProviderClass 设置为 IOUSBDevice - 这仅适用于 10.10 及更早版本。 10.11 引入了一个全新的 USB 堆栈,新的类名为 IOUSBHostDevice。我知道这不是 IORegistryExplorer/ioreg 所说的:某处正在进行翻译以保持旧用户空间应用程序的运行。在内核中,匹配IOUSBHostDevice 的驱动程序将优先于匹配IOUSBDevice 的驱动程序。如果你想同时支持两者,你可以为你的无代码 kext 添加一个额外的个性。对于带有 代码的 kexts,如果旧版支持不适用于您的情况,您将需要创建两个版本的 kext。

另一个可能影响它的因素是探测分数,虽然理论上你的 idVendor + idProduct + bcdDevice 规则应该已经有很高的分数了。

【讨论】:

  • 你说得对,目前我正在 macOS 10.12 上进行测试。我添加了另一个个性,将IOUSBDevice 更改为IOUSBHostDevice,但这也不起作用。设备仍会被系统完全捕获。
  • @ad_on_is 你能用 1 更新问题中的ioreg 输出吗?如果添加 -i 选项重新运行它会得到什么? 2. 成功匹配设备的服务,除了设备节点本身?这里还有更多的可能性,包括探测分数——你试过了吗?
  • 按要求更新了ioreg。此外,我使用修改后的IOProbeScore 更新了 info.plist。由于我对驱动程序开发还很陌生,而且这只是一个业余项目,所以我现在不完全了解您的 2. 点的确切含义。你有更多的提示给我吗?
  • 我问自己的一些问题是:我的方法是否正确?如果匹配并成功加载无代码 kext,是否应该阻止设备被识别为通用输入(鼠标和键盘)?然后我是否能够从该设备读取原始输入并在我的 C 代码中使用它来操作用户级别的鼠标和键盘输入?我还知道,完成的驱动程序必须在“安全和隐私”设置中具有访问权限才能完全运行。
  • 您还能显示您设备的客户端吗?我想查看当前与设备匹配的内容。尝试类似:ioreg -i -r -w 0 -l -n "PenTablet "(假设那是您所追求的设备。)对于您的第二个问题:如果我理解您要正确执行的操作,那么是的,您走在正确的轨道上。 (尽管您可能不想直接匹配 USB 设备,只匹配其中一个 HID 接口。)我不是 100% 清楚的是当您按下其中一个按钮时当前会发生什么想编程。有了这些信息 + ioreg 输出,我应该可以知道。
猜你喜欢
  • 2016-05-26
  • 2011-04-01
  • 1970-01-01
  • 2015-09-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多