How to sending capability requests.

I want to create a DriverKit driver and send vendor-specific commands to the storage device. Since UserClient is required to access the DriverKit driver from the app, I am attempting to implement it by referring to the following sample code. [Communicating between a DriverKit extension and a client app]

I want to add com.apple.developer.driverkit.allow-any-userclient-access to the driver's Entitlements, submit a Capability Request on the developer site, and create a Provisioning Profile. However, I don't know how to enable com.apple.developer.driverkit.allow-any-userclient-access.

I am entering the following information in the “Request a System Extension or DriverKit Entitlement” form.

Which entitlement are you applying for? : DriverKit Entitlement Which DriverKit entitlements do you need? : UserClient Access UserClient Bundle IDs : [Bundle ID of MyDriver] Describe your apps and how they’ll use these entitlements. : testing sample code

However, even if this request is accepted, I believe only MyDriver will be permitted. How can I grant access to all UserClients?

Answered by DTS Engineer in 865219022

I have a new question: I include Capabilities in the Provisioning Profile that might not be used, just in case. If I don't list all these Capabilities in the driver's Entitlements, will it cause the driver to behave abnormally?

No, this doesn't affect anything.

I then created a UserClient inheriting from the IOUserClient class to access it from the app, but IOServiceOpen fails with code 0xe00002d7 and cannot open.

Huh. So, "0xe00002d7" is kIOReturnOffline, but I'm not sure how you'd get it from IOServiceOpen. It's returned in a few places in DriverKit and xnu, but none of them look like "places" you'd reach from IOServiceOpen. My best guess is that you're either trying to open the wrong object or your subclass is in an odd/unexpected state which is making it "non-connectable". If you haven't already, make sure you check the system log as it's possible we logged additional info about what actually happened.

Actually... real-time correction of myself:

And in the driver's Info.plist, the following definitions are specified.

This is wrong:

<key>IOClass</key>
<string>IOSCSIPeripheralDeviceType00</string>

DriverKit (most of it) works by having your DEXT work with an corresponding in-kernel "support" KEXT that handles the interaction between the kernel and your DEXT. The naming convention for those classes is to:

  1. Add "User" to the name suffix of the existing "standard" support driver.

  2. Use the same name for the class your DEXT actually inherits from.

...which, in this case, would be "IOUserSCSIPeripheralDeviceType00". By specifying "IOSCSIPeripheralDeviceType00", the kernel has done exactly what you told it and loaded "IOSCSIPeripheralDeviceType00"... and that class is basically now "ignoring" your driver, since it has no idea what a DEXT is.

I don't know if switching to "IOUserSCSIPeripheralDeviceType00" will fully resolve your issue, but as is, your DEXT is basically non-functional.

Small follow-up here:

The driver's entitlements are as follows.

Your DEXT should NOT include "com.apple.developer.driverkit.communicates-with-drivers". That's an app-level entitlement specific to iPadOS, not a DEXT entitlement. Including it doesn't create any problem (the system will just ignore it), but it doesn't belong on any DEXT.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

Environment:

  •  macOS 15.6
  •  Xcode 26.0.1

Minimum Deployments

  • macOS 12
  • DriverKit 20.0

I want to create a DriverKit driver and send vendor-specific commands to the storage device. Since UserClient is required to access the DriverKit driver from the app, I am attempting to implement it by referring to the following sample code. [Communicating between a DriverKit extension and a client app]

So, as it happens, I have a post here that's specifically about getting this sample to work.

Try what that post suggests and let me know if you're still having issues.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

I understand that it is not necessary to include this com.apple.developer.driverkit.allow-any-userclient-access in the driver's Entitlements.

I have a new question: I include Capabilities in the Provisioning Profile that might not be used, just in case. If I don't list all these Capabilities in the driver's Entitlements, will it cause the driver to behave abnormally?

To issue vendor-specific commands, I created a driver class inheriting from the IOUserSCSIPeripheralDeviceType00 class in the SCSIPeripheralDriverKit Framework.

I then created a UserClient inheriting from the IOUserClient class to access it from the app, but IOServiceOpen fails with code 0xe00002d7 and cannot open.

The driver's entitlements are as follows.

<key>com.apple.developer.driverkit.transport.usb</key>
<true/>
<key>com.apple.developer.driverkit.family.scsicontroller</key>
<true/>
<key>com.apple.developer.driverkit.communicates-with-drivers</key>
<true/>
<key>com.apple.developer.driverkit.allow-third-party-userclients</key>
<true/>
<key>com.apple.developer.driverkit</key>
<true/>

And in the driver's Info.plist, the following definitions are specified.

<key>IOKitPersonalities</key>
<dict>
    <key>SampleDriverKitDriver</key>
    <dict>
        <key>CFBundleIdentifier</key>
        <string>${PRODUCT_BUNDLE_IDENTIFIER}</string>
        <key>CFBundleIdentifierKernel</key>
        <string>com.apple.kpi.iokit</string>
        <key>IOClass</key>
        <string>IOSCSIPeripheralDeviceType00</string>
        <key>IOProbeScore</key>
        <integer>20000</integer>
        <key>IOProviderClass</key>
           <string>IOSCSIPeripheralDeviceNub</string>
        <key>IOResourceMatch</key>
        <string>IOKit</string>
        <key>IOUserClass</key>
        <string>SampleDriverKitDriver</string>
        <key>IOUserClientClass</key>
        <string>SampleDriverKitUserClient</string>
        <key>IOUserServerName</key>
        <string>${PRODUCT_BUNDLE_IDENTIFIER}</string>
        <key>Peripheral Device Type</key>
        <integer>0</integer>
        <key>Vendor Identifier</key>

        <string>[write Device Vendor Name]</string>
        <key>Product Identifier</key>
        <string>[write Device Product Name]</string>
        <key>UserClientProperties</key>
        <dict>
            <key>IOClass</key>
            <string>IOUserUserClient</string>
            <key>IOUserClass</key>
            <string>SampleDriverKitUserClient</string>        
        </dict>
    </dict>
</dict>

I suspect the code isn't written correctly to generate the UserClient. Is there anything wrong with the code?

I have a new question: I include Capabilities in the Provisioning Profile that might not be used, just in case. If I don't list all these Capabilities in the driver's Entitlements, will it cause the driver to behave abnormally?

No, this doesn't affect anything.

I then created a UserClient inheriting from the IOUserClient class to access it from the app, but IOServiceOpen fails with code 0xe00002d7 and cannot open.

Huh. So, "0xe00002d7" is kIOReturnOffline, but I'm not sure how you'd get it from IOServiceOpen. It's returned in a few places in DriverKit and xnu, but none of them look like "places" you'd reach from IOServiceOpen. My best guess is that you're either trying to open the wrong object or your subclass is in an odd/unexpected state which is making it "non-connectable". If you haven't already, make sure you check the system log as it's possible we logged additional info about what actually happened.

Actually... real-time correction of myself:

And in the driver's Info.plist, the following definitions are specified.

This is wrong:

<key>IOClass</key>
<string>IOSCSIPeripheralDeviceType00</string>

DriverKit (most of it) works by having your DEXT work with an corresponding in-kernel "support" KEXT that handles the interaction between the kernel and your DEXT. The naming convention for those classes is to:

  1. Add "User" to the name suffix of the existing "standard" support driver.

  2. Use the same name for the class your DEXT actually inherits from.

...which, in this case, would be "IOUserSCSIPeripheralDeviceType00". By specifying "IOSCSIPeripheralDeviceType00", the kernel has done exactly what you told it and loaded "IOSCSIPeripheralDeviceType00"... and that class is basically now "ignoring" your driver, since it has no idea what a DEXT is.

I don't know if switching to "IOUserSCSIPeripheralDeviceType00" will fully resolve your issue, but as is, your DEXT is basically non-functional.

Small follow-up here:

The driver's entitlements are as follows.

Your DEXT should NOT include "com.apple.developer.driverkit.communicates-with-drivers". That's an app-level entitlement specific to iPadOS, not a DEXT entitlement. Including it doesn't create any problem (the system will just ignore it), but it doesn't belong on any DEXT.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

How to sending capability requests.
 
 
Q