防止经典驱动程序在 OS X 上打开 USB 设备

Prevent classic drivers from opening usb device on OS X

我正在为 OS X 上的 USB 设备开发 kext 驱动程序。在这个驱动程序中,我有一个指向对象 IOUSBDevice *device 的指针(它可以在 start() 和 probe( ) 函数),我有一个问题:可以在 probe() 函数中打开设备 (device->open(this, kIOServiceSeize)),但在其他函数中 open()return false,因为它看起来像经典驱动程序控制设备。

我找到文章 User-Mode USB Device Arbitration 并尝试创建 "skeleton" kext 以将 "ClassicMustNotSeize" 属性 设置为 true,但似乎它不起作用,我仍然可以'打开设备。

<?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>English</string>
    <key>CFBundleIconFile</key>
    <string></string>
    <key>CFBundleIdentifier</key>
    <string>com.sample.iokit.ClassicNotSeizeDriver</string>
    <key>CFBundleInfoDictionaryVersion</key>
    <string>6.0</string>
    <key>CFBundlePackageType</key>
    <string>KEXT</string>
    <key>CFBundleShortVersionString</key>
    <string>1.0.0</string>
    <key>CFBundleSignature</key>
    <string>????</string>
    <key>CFBundleVersion</key>
    <string>1.0.0</string>
    <key>IOKitPersonalities</key>
    <dict>
        <key>MyUSBDevice</key>
        <dict>
            <key>CFBundleIdentifier</key>
            <string>com.apple.driver.AppleUSBMergeNub</string>
            <key>IOClass</key>
            <string>AppleUSBMergeNub</string>
            <key>IOProviderClass</key>
            <string>IOUSBDevice</string>
            <key>IOProviderMergeProperties</key>
            <dict>
                <key>ClassicMustNotSeize</key>
                <true/>
            </dict>
            <key>idProduct</key>
            <integer>1</integer>
            <key>idVendor</key>
            <integer>10978</integer>
        </dict>
    </dict>
    <key>OSBundleLibraries</key>
    <dict>
        <key>com.apple.driver.AppleUSBMergeNub</key>
        <string>1.8.3b1</string>
        <key>com.apple.iokit.IOUSBFamily</key>
        <string>1.8</string>
    </dict>
</dict>
</plist>

是否可以通过编程方式设置 "ClassicMustNotSeize" 属性,例如在我的驱动程序的 probe() 函数中?

我试过了:

device->setProperty("ClassicMustNotSeize", true);

而且好像也不行。

如果您的成功匹配并且 probe()d,其他 kexts 将不会要求服务。如果你没有成功 start(),它可能会在稍后重新启动匹配时被另一个 kext 匹配。所以有些事情是不对的,并且不可能仅仅从你的问题中判断它是什么,因为你没有提供相关的代码,info.plist 和 ioreg 摘录,更不用说你的代码的调试输出了......

所以我只能猜测:

  1. 为什么您认为需要使用 kIOServiceSeize?如果您的 kext 与该设备匹配,具有最高的探测分数并且 probe() 中的 return 非空,则没有其他驱动程序会获取该设备(目前)。如果要确保对 USB 设备的独占访问,请使用 kUSBOptionBitOpenExclusivelyMask 选项 open()
  2. 如果您在 probe() 期间 open(),请确保在 return 之前 close(),无论您 return 的值是多少。在start()中重新open()。 (通常不需要覆盖 probe(),默认情况下会 return this。)
  3. 您是否在 I/O 套件个性中设置匹配类别?除非你有很好的理由,否则不要。
  4. 您是否在实际驱动程序个性中匹配 IOUSBInterface 而不是 IOUSBDevice,然后遍历服务图?或者以其他方式试图通过 I/O 套件匹配以外的方式声明设备?
  5. 您的 kext 是否在 /Library/Extensions 中(或 /System/Library/Extensions 如果有充分的理由不能在 /LE 中)?否则不参与匹配
  6. 我非常怀疑这与 "Classic" 有什么关系,据我所知这是 运行 Mac OS 8 & 9 的一种方式OS X 早期版本中的应用程序。因此,除非您的目标是 10.1 左右,否则 ClassicMustNotSeize 什么都不做。