DriverKit IOUSBHostInterface 的 CopyPipe 因 kIOReturnError (0xe00002bc) 而失败

CopyPipe of DriverKit IOUSBHostInterface fails with kIOReturnError (0xe00002bc)

为了我自己的启发,我正在尝试使用 DriverKit 系统扩展从 USB 音频接口读取一些音频数据。

我的 IOProviderClassIOUSBHostInterface。我可以成功Open()界面,但是CopyPipe()returnskIOReturnError0xe00002bc)。为什么我不能复制管道?

为了能够完全打开界面,我必须胜过 AppleUSBAudio 所以我的 IOKitPersonalities 明确匹配 bConfigurationValuebInterfaceNumberidVendoridProductbcdDevice 键。此列表可能不是最少的。

ioreg中我可以正常看到接口(有时只有我匹配的那个在那里,虽然我认为这是一种退化的情况)。我在其他一些界面上看到 AppleUserUSBHostHIDDevice child。这可能是问题所在吗?通常该设备既是 USBAudio 又是 HID 没有问题。我也在尝试匹配 HID,但没有成功。

我将错误的端点地址传递给 CopyPipe()

要查找端点地址,您需要枚举 IOUSBConfigurationDescriptor 中的 IOUSBDescriptorHeader 并检查 bDescriptorType 等于 kIOUSBDescriptorTypeEndpoint 的描述符。

USBDriverKit/AppleUSBDescriptorParsing.h 中的

IOUSBGetNextDescriptor() 就是为此而设计的,可以让您免于考虑指针操作。

如果端点处于不同的备用设置中,那么您需要使用 SelectAlternateSetting() 将接口切换到那个接口。

void
enumerate_configs(const IOUSBConfigurationDescriptor *configDesc) {
    const IOUSBDescriptorHeader *curHeader = NULL;
    
    while ((curHeader = IOUSBGetNextDescriptor(configDesc, curHeader))) {
        switch (curHeader->bDescriptorType) {
            case kIOUSBDescriptorTypeEndpoint: {
                auto endpoint = (const IOUSBEndpointDescriptor *)curHeader;
                os_log(OS_LOG_DEFAULT, "Endpoint bLength: %{public}i, bDescriptorType: %i, bEndpointAddress: %i, bmAttributes: 0x%x, wMaxPacketSize: %i, bInterval: %i",
                       endpoint->bLength,
                       endpoint->bDescriptorType,
                       endpoint->bEndpointAddress,  // pass this to CopyPipe()
                       endpoint->bmAttributes,
                       endpoint->wMaxPacketSize,
                       endpoint->bInterval);
            }
                break;
            default:
                os_log(OS_LOG_DEFAULT, "some other type: %{public}i", curHeader->bDescriptorType);
                break;
        }
    }
}