USB DEXT Service registration and daemon communication

Dear Apple Developer Community,

I hope you're all doing well.

I'm running into an issue where a USB DEXT doesn’t seem to be fully registered in the IORegistry, which is preventing the user client (daemon) from connecting and communicating with it. The DEXT is supposed to authorize any USB device connections based on the daemon’s response.

Here’s a simplified example to illustrate the issue:

// MyUSBDEXT.h
class MyUSBDEXT : public IOService {
public:
    virtual kern_return_t Start(IOService *provider) override;
    virtual bool init() override;
    virtual kern_return_t Stop(IOService *provider) override;
    virtual kern_return_t NewUserClient(uint32_t type, IOUserClient **userClient) override;
};

// MyUSBDEXT.cpp
kern_return_t IMPL(MyUSBDEXT, Start) {
    // USB device handling

    kern_return_t result = RegisterService();
    if (result != kIOReturnSuccess) {
        os_log_error(OS_LOG_DEFAULT, "RegisterService() failed with error: %d", result);
        goto Exit; // Exit if registration fails
    }

    // Wait for NewUserClient creation and daemon response
    // Return: Allow or Deny the USB connection
}

kern_return_t IMPL(MyUSBDEXT, NewUserClient) {
    // Handle new client creation
}

In the example above, IMPL(MyUSBDEXT, Start) waits for a user client to establish communication after calling RegisterService(), and only then does it proceed to allow or deny the USB device connection.

Based on my observations, even after RegisterService() returns kIOReturnSuccess, the DEXT entry appears in the IORegistry but remains unregistered, preventing user clients from connecting.

MyUSBDEXT  <class IOUserService, id 0x100001185, !registered, !matched, active, busy 0, retain 7>

However, if IMPL(MyUSBDEXT, Start) does not wait after calling RegisterService(), the DEXT gets fully registered, allowing user clients to connect and communicate with it.

MyUSBDEXT  <class IOUserService, id 0x100001185, registered, matched, active, busy 0, retain 7>

This creates a challenge: IMPL(MyUSBDEXT, Start) needs to wait for a user client to establish communication to Allow or Deny USB connections, but the user client can only connect after MyUSBDEXT::Start() completes.

According to Apple’s documentation, RegisterService() initiates the registration process for the service, but it is unclear when the process actually completes. https://developer.apple.com/documentation/kernel/ioservice/3180701-registerservice

Is there a way to ensure that RegisterService() fully completes and properly registers the entry in IORegistry before returning from IMPL(MyUSBDEXT, Start)?

Alternatively, in a USB DEXT, is it possible to make the USB device authorization decision (allow/deny) after IMPL(MyUSBDEXT, Start) has completed?

Or is there another recommended approach to handle this scenario?

Any insights would be greatly appreciated!

USB DEXT Service registration and daemon communication
 
 
Q