Prevent macOS generic keyboard driver from hijacking a USB device

I am trying to write a macOS custom level driver in C for a USB device (pentablet with buttons).

This tablet is currently recognized as a shared mouse and a shared keyboard from the system. Since the labels applied to the pentablet buttons are not customizable, I would like to write my own driver for this.

What works:

I can read raw data from hidapi ( http://www.signal11.us/oss/hidapi/ ) from a device that looks something like this:

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

      

I realized that when using the pen, the column values B-H

change according to position, pressure and click.

My problem:

However, I cannot figure out how to access the buttons of the device. Every time I press one of them their hardcoded key combination is triggered. Since the column values A

never change, I am assuming that the device is still captured as a shared keyboard by the system, and so this column never shows me the currently pressed button and triggers its key combination.

Every time I press one of these buttons, they trigger holding ALT / Option + Shift , in addition, some of them trigger a symbol, and one of them causes the volume to increase.

So my approach was to use a no-coded kext to prevent the system from seizing the device. But that doesn't work either - the device is still captured by the system as a generic keyboard.

I disabled csrutil

and kextload

, having my kext located in /Library/Extensions

, I get a successful message being loaded by the kext:

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

Code Signing Failure: code signature is invalid
Warnings:
    Personality CFBundleIdentifier differs from containing kext (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 my output as well ioreg -i -w 0 -l -n "PenTablet"

, which I used to map devices: https://adisdurakovic.com/pentablet.txt

What am I doing wrong here?

+3


source to share


1 answer


Since you mention SIP, I am assuming you are testing this on 10.11 or newer. Yours is IOProviderClass

set to IOUSBDevice

- this will only work 10.10 and older. 10.11 introduced a completely new USB stack, a new class name IOUSBHostDevice

. I know that's not what the IORegistryExplorer / says ioreg

: there the translation happens where old apps need to be stored in user space. In the kernel, matching drivers IOUSBHostDevice

will take precedence over matching drivers IOUSBDevice

. If you want to support both, you can simply add an extra personality to your kext. For kexts with code, you need to create two versions of your kext if deprecated support doesn't work in your case.



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

+1


source







All Articles