ad_on_is
ad_on_is

Reputation: 1550

Prevent macOS generic keyboard driver from capturing usb-device

I'm trying to write a macOS user-level driver in C for a usb-device (a pentablet with buttons).

Currently this tablet gets recognized as generic mouse and generic keyboard from the system. Since the shortcuts applied to the buttons of the pentablet are not customizeable, I'd like to write my own driver for that.

What's working:

I am able to read the raw-data with hidapi (http://www.signal11.us/oss/hidapi/) from the device, which looks something like this:

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

I figured out, that when I use the pen the values of the columns B-H change according to the pens position, pressure and click.

My problem:

However, I cannot figure out how to access the buttons of the device. Each time I press one of them, their hardcoded key-combination gets triggered. Since the values of column A never change, I assume that the device is still captured as a generic keyboard by the system, and so this column never shows me the currently pressed button and triggers it's key-combination.

Each time I press one of these buttons they all trigger a holding ALT/Option + Shift, additionally some of them trigger a character, and one of them triggers the volume up.

So, my approach was to use a codeless kext for preventing the system from capturing the device. But this doesn't work either - the device still gets captured by the system as a generic keyboard.

I disabled csrutil and with kextload, having my kext located in /Library/Extensions, I get a successfull message, that the kext is loaded:

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.

Here's my 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>

And here's also my ioreg -i -w 0 -l -n "PenTablet" output which I used for device matching: https://adisdurakovic.com/pentablet.txt

What am I doing wrong here?

Upvotes: 4

Views: 435

Answers (1)

pmdj
pmdj

Reputation: 23438

Since you mention SIP, I assume you're testing this on 10.11 or newer. Your IOProviderClass is set to IOUSBDevice - this will only work for 10.10 and older. 10.11 introduced a completely new USB stack, the new class name is IOUSBHostDevice. I know that's not what IORegistryExplorer/ioreg say: there's a translation going on somewhere to keep old userspace apps ticking over. In the kernel, drivers matching IOUSBHostDevice will take precedence over those matching IOUSBDevice. If you want to support both, you can just add an extra personality to your codeless kext. For kexts with code, you'll need to create two versions of your kext if the legacy support doesn't work in your case.

Another thing that could affect it is probe score, although in theory your idVendor + idProduct + bcdDevice rule should already have a very high score.

Upvotes: 1

Related Questions