Macos DriverKit IOUSBHostInterface的CopyPipe失败,出现kIOReturnError(0xe00002bc)

Macos DriverKit IOUSBHostInterface的CopyPipe失败,出现kIOReturnError(0xe00002bc),macos,macos-catalina,driverkit,macos-system-extension,Macos,Macos Catalina,Driverkit,Macos System Extension,出于我自己的启发,我尝试使用DriverKit系统扩展从USB音频接口读取一些音频数据 我的IOProviderClass是ioubHostInterface。我可以成功地Open()接口,但是CopyPipe()返回kIOReturnError(0xe00002bc)。为什么我不能复制管道 为了能够打开这个界面,我必须比AppleUSBAudio更匹配,所以我的IOKitPersonalities明确匹配bConfigurationValue,bInterfaceNumber,idVendor

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

我的
IOProviderClass
ioubHostInterface
。我可以成功地
Open()
接口,但是
CopyPipe()
返回
kIOReturnError
0xe00002bc
)。为什么我不能复制管道

为了能够打开这个界面,我必须比AppleUSBAudio更匹配,所以我的
IOKitPersonalities
明确匹配
bConfigurationValue
bInterfaceNumber
idVendor
idProduct
bcdDevice
键。这个列表可能不是最小的


ioreg
中,我通常可以看到接口(有时只有匹配的接口在那里,尽管我认为这是一种退化的情况)。我在我的一些其他界面上看到一个
AppleUserUSBHostHIDDevice
子设备。这可能是问题所在吗?通常情况下,设备在USBAudio和HID两种情况下都没有问题。我试图将匹配的HID也排除在外,但未成功。

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

要查找端点地址,您需要通过
ioubConfiguration Descriptor
中的
ioubDescriptorHeader
s枚举,并检查
bDescriptorType
等于
kIOUSBDescriptorTypeEndpoint
的描述符

USBDriverKit/appleusbdescriptor parsing.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;
        }
    }
}