我正在开发RNDIS复合设备,其中包括RNDIS设备,usbnet设备,调制解调器设备和自定义CDC设备。

PC正在运行Win7 32位,并且我正在使用默认的RNDIS驱动程序。
当我仅使用RNDIS设备回答Windows枚举时,一切正常。
但是,当我将所有4个设备组合到描述符中作为复合设备时,Windows仍然可以正确枚举,而其他3个设备运行正常,但是RNDIS设备遇到“无法启动错误代码10”的问题。

我用USB分析仪跟踪了USB数据流,发现 Windows RNDIS驱动程序在“设置配置”之后没有发送RNDIS初始化消息

复合设备描述符如前所述:

         devDesc[0]  = 0x12; //  bLength             - Descriptor length
         devDesc[1]  = 0x01; //  bDescriptorType     - Descriptor  Type
         devDesc[2]  = bcdUSB_LSB; //  bcdUSB (LSB)        - Device Compliant to USB specification ..
         devDesc[3]  = bcdUSB_MSB; //  bcdUSB (MSB)
         devDesc[4]  = 0x00; //  bDeviceClass        - class of the device
         devDesc[5]  = 0x00; //  bDeviceSubClass     - subclass of the device
         devDesc[6]  = 0x00; //  bDeviceProtocol     - protocol of the device
         devDesc[7]  = bEp0MaxPacketSize; //  bMaxPacketSize0     - Max Packet Size for EP zero
         devDesc[8]  = 0x86; //  idVendor (LSB)      - Vendor ID
         devDesc[9]  = 0x12; //  idVendor (MSB)
         devDesc[10] = 0x0E; //  idProduct (LSB)     - Product ID
         devDesc[11] = 0x81; //  idProduct (MSB)
         devDesc[12] = 0x02; //  bcdDevice (LSB)     - The device release number
         devDesc[13] = 0x00; //  bcdDevice (MSB)
         devDesc[14] = 0x01; //  iManufacturer       - Index of string descriptor describing Manufacturer
         devDesc[15] = 0x03; //  iProduct            - Index of string descriptor describing Product
         devDesc[16] = 0x04; //  iSerialNumber       - Index of string descriptor describing Serial number
         devDesc[17] = 0x01; //  bNumConfigurations  - Number of configurations

         //Configuration Descriptor
         configDesc[0]  = 0x09; // bLength               - Descriptor length
         configDesc[1]  = 0x02; // bDescriptorType       - Descriptor Type
         configDesc[2]  = 177;   // wTotalLength (LSB)   - Total Data length for the configuration,
         configDesc[3]  = 0x00; // wTotalLength (MSB)    - includes all descriptors for this configuration
         configDesc[4]  = 0x05; // bNumInterfaces        - Number of interfaces this configuration supports
         configDesc[5]  = 0x01; // bConfigurationValue   - The Value that should be used to select this configuration
         configDesc[6]  = 0x00; // iConfiguration        - Index of string descriptor describing this configuration
         configDesc[7]  = 0xC0; // bmAttributes          - bit6: Self-Powered, bit5: RemoteWakeup
         configDesc[8]  = 0xfa; // MaxPower              - Maximum power consumption for this configuration (mA)


         //Interface Descriptor 0 usbnet
         configDesc[9]  = 0x09; // bLength               - Descriptor length
         configDesc[10] = 0x04; // bDescriptorType       - Descriptor Type
         configDesc[11] = 0x00; // bInterfaceNumber      - Index (Number) of this interfaces
         configDesc[12] = 0x00; // bAlternateSetting     - The value to select alternate setting of this interface
         configDesc[13] = 0x03; // bNumEndpoints         - Number endpoints  used by this interface
         configDesc[14] = 0xff; // bInterfaceClass       - Class of this Interface
         configDesc[15] = 0xff; // bInterfaceSubClass    - Sub class of this Interface
         configDesc[16] = 0x00; // bInterfaceProtocol    - Protocol of this Interface
         configDesc[17] = 0x05; // iInterface            - Index of string descriptor describing this Interface


         // usbnet Endpoint Descriptor
         configDesc[18] = 0x07; // bLength               - Descriptor length
         configDesc[19] = 0x05; // bDescriptorType       - Descriptor Type
         configDesc[20] = 0x85; // bEndpointAddress      - Endpoint Address & Direction
         configDesc[21] = 0x03; // bmAttributes          - BULK,ISO,Interrupt
         configDesc[22] = 0x0F; // wMaxPacketSize (LSB)  - Max packet size
         configDesc[23] = 0x00; // wMaxPacketSize (MSB)
         configDesc[24] = bInterval; // bInterval                - Polling Interval (ms)

         configDesc[25] = 0x07; // bLength               - Descriptor length
         configDesc[26] = 0x05; // bDescriptorType       - Descriptor Type
         configDesc[27] = 0x81; // bEndpointAddress      - Endpoint Address & Direction
         configDesc[28] = 0x02; // bmAttributes          - BULK,ISO,Interrupt
         configDesc[29] = bBulkMaxPacketSize_LSB; // wMaxPacketSize (LSB)  - Max packet size
         configDesc[30] = bBulkMaxPacketSize_MSB; // wMaxPacketSize (MSB)
         configDesc[31] = 0x00; // bInterval             - Polling Interval (ms)

         configDesc[32] = 0x07; // bLength               - Descriptor length
         configDesc[33] = 0x05; // bDescriptorType       - Descriptor Type
         configDesc[34] = 0x02; // bEndpointAddress      - Endpoint Address & Direction
         configDesc[35] = 0x02; // bmAttributes          - BULK,ISO,Interrupt
         configDesc[36] = bBulkMaxPacketSize_LSB; // wMaxPacketSize (LSB)  - Max packet size
         configDesc[37] = bBulkMaxPacketSize_MSB; // wMaxPacketSize (MSB)
         configDesc[38] = 0x00; // bInterval             - Polling Interval (ms)

         //Interface descriptor 1 ICAT
         configDesc[39] = 0x09; // bLength               - Descriptor length
         configDesc[40] = 0x04; // bDescriptorType       - Descriptor Type
         configDesc[41] = 0x01; // bInterfaceNumber      - Index (Number) of this interfaces
         configDesc[42] = 0x00; // bAlternateSetting     - The value to select alternate setting of this interface
         configDesc[43] = 0x02; // bNumEndpoints         - Number endpoints  used by this interface
         configDesc[44] = 0xFF; // bInterfaceClass       - Class of this Interface
         configDesc[45] = 0x00; // bInterfaceSubClass    - Sub class of this Interface
         configDesc[46] = 0x00; // bInterfaceProtocol    - Protocol of this Interface
         configDesc[47] = 0x00; // iInterface            - Index of string descriptor describing this Interface

         //ICAT endpoints
         configDesc[48] = 0x07; // bLength               - Descriptor length
         configDesc[49] = 0x05; // bDescriptorType       - Descriptor Type
         configDesc[50] = 0x87; // bEndpointAddress      - Endpoint Address & Direction
         configDesc[51] = 0x02; // bmAttributes          - BULK,ISO,Interrupt
         configDesc[52] = bBulkMaxPacketSize_LSB; // wMaxPacketSize (LSB)  - Max packet size
         configDesc[53] = bBulkMaxPacketSize_MSB; // wMaxPacketSize (MSB)
         configDesc[54] = 0x00; // bInterval             - Polling Interval (ms)

         configDesc[55] = 0x07; // bLength               - Descriptor length
         configDesc[56] = 0x05; // bDescriptorType       - Descriptor Type
         configDesc[57] = 0x08; // bEndpointAddress      - Endpoint Address & Direction
         configDesc[58] = 0x02; // bmAttributes          - BULK,ISO,Interrupt
         configDesc[59] = bBulkMaxPacketSize_LSB; // wMaxPacketSize (LSB)  - Max packet size
         configDesc[60] = bBulkMaxPacketSize_MSB; // wMaxPacketSize (MSB)
         configDesc[61] = 0x00; // bInterval             - Polling Interval (ms)

         //Modem class specific descriptors
         configDesc[62]  = 0x09; // bLength              - Descriptor length
         configDesc[63] = 0x04; // bDescriptorType       - Descriptor Type
         configDesc[64] = 0x02; // bInterfaceNumber      - Index (Number) of this interfaces
         configDesc[65] = 0x00; // bAlternateSetting     - The value to select alternate setting of this interface
         configDesc[66] = 0x03; // bNumEndpoints         - Number endpoints  used by this interface
         configDesc[67] = 0x02; // bInterfaceClass       - Class of this Interface
         configDesc[68] = 0x02; // bInterfaceSubClass    - Sub class of this Interface
         configDesc[69] = 0x01; // bInterfaceProtocol    - Protocol of this Interface
         configDesc[70] = 0x00; // iInterface            - Index of string descriptor describing this Interface

         configDesc[71] = 0x05; // descriptor length Comms Class CS_INTERFACE 'Functional Descriptors' Triplet
         configDesc[72] = 0x24; // descriptor type
         configDesc[73] = 0x00; // subtype = header
         configDesc[74] = 0x10; // BCD
         configDesc[75] = 0x01; //

         configDesc[76] = 0x05; // 2. descriptor length - Call Manangement Func Desc
         configDesc[77] = 0x24; // descriptor type
         configDesc[78] = 0x01; // subtype = Call management
         configDesc[79] = 0x00; //bmcapabilities; MS driver usbser.sys seems to ignore this bit and sends AT over the data,interface anyway
         configDesc[80] = 0x01; // Interface number of data class interface

         configDesc[81] = 0x04; // 3.descriptor length  Abstract Control Func Desc
         configDesc[82] = 0x24; // descriptor type
         configDesc[83] = 0x02; // subtype = Abstract CM
         configDesc[84] = 0x00; // bmcapabilities

         configDesc[85] = 0x05; // Size of descriptor. Number of interfaces plus 3 bytes of header
         configDesc[86] = 0x24; // 0x24 - CS_INTERFACE
         configDesc[87] = 0x06; // 0x06 - See table 25 of document "USB Class definitions for Comms Devices"
         configDesc[88] = 0x00;
         configDesc[89] = 0x01;

         //Endpoint Descriptors MODEM
         configDesc[90] = 0x07; // bLength               - Descriptor length
         configDesc[91] = 0x05; // bDescriptorType       - Descriptor Type
         configDesc[92] = 0x86; // bEndpointAddress      - Endpoint Address & Direction
         configDesc[93] = 0x03; // bmAttributes          - BULK,ISO,Interrupt
         configDesc[94] = 0x0F; // wMaxPacketSize (LSB)  - Max packet size
         configDesc[95] = 0x00; // wMaxPacketSize (MSB)
         configDesc[96] = bInterval; // bInterval                - Polling Interval (ms)

         configDesc[97] = 0x07; // bLength               - Descriptor length
         configDesc[98] = 0x05; // bDescriptorType       - Descriptor Type
         configDesc[99] = 0x83; // bEndpointAddress      - Endpoint Address & Direction
         configDesc[100] = 0x02; // bmAttributes          - BULK,ISO,Interrupt
         configDesc[101] = bBulkMaxPacketSize_LSB; // wMaxPacketSize (LSB)  - Max packet size
         configDesc[102] = bBulkMaxPacketSize_MSB; // wMaxPacketSize (MSB)
         configDesc[103] = 0x00; // bInterval                - Polling Interval (ms)

         configDesc[104] = 0x07; // bLength              - Descriptor length
         configDesc[105] = 0x05; // bDescriptorType      - Descriptor Type
         configDesc[106] = 0x04; // bEndpointAddress     - Endpoint Address & Direction
         configDesc[107] = 0x02; // bmAttributes          - BULK,ISO,Interrupt
         configDesc[108] = bBulkMaxPacketSize_LSB; // wMaxPacketSize (LSB)  - Max packet size
         configDesc[109] = bBulkMaxPacketSize_MSB; // wMaxPacketSize (MSB)
         configDesc[110] = 0x00; // bInterval                - Polling Interval (ms)


        //rndis IAD
        configDesc[111] = 0x08; // bLength
        configDesc[112] = 0x0b; // INTERFACE ASSOCIATION DESCRIPTOR bDescriptorType
        configDesc[113] = 0x03; // bFirstInterface
        configDesc[114] = 0x02; // bInterfaceCount
        configDesc[115] = 0x02; // bFunctionClass
        configDesc[116] = 0x02; // bFunctionSubClass
        configDesc[117] = 0xFF; // bFunctionProtocol
        configDesc[118] = 0x03; // Index of string descriptor describing this function

        //rndis comm interface
        configDesc[119] = 0x09; // bLength             - Descriptor length
        configDesc[120] = 0x04; // bDescriptorType     - Descriptor Type
        configDesc[121] = 0x03; //bInterfaceNumber     - for RNDIS
        configDesc[122] = 0x00; // bAlt
        configDesc[123] = 0x01; // bNumEnd
        configDesc[124] = 0x02; //bInterfaceClass
        configDesc[125] = 0x02; // bInterfaceSubclass
        configDesc[126] = 0xFF; // bInterfaceprotocol
        configDesc[127] = 0x00; // iInterface  +++++++++++++++++++++++++++++++++++++need modified


        // Class specified descriptor

        configDesc[128] = 0x05; //
        configDesc[129] = 0x24; // bDescriptorType
        configDesc[130] = 0x00; //bDescriptorSubtype
        configDesc[131] = 0x10; // BCD
        configDesc[132] = 0x01; //

        configDesc[133] = 0x05; //
        configDesc[134] = 0x24; // bDescriptorType
        configDesc[135] = 0x01; // bDescriptorSubtype
        configDesc[136] = 0x00; // bmCapabilities
        configDesc[137] = 0x04; //bDataInterface

        configDesc[138] = 0x04; //
        configDesc[139] = 0x24; // bDescriptorType
        configDesc[140] = 0x02; // bDescriptorSubtype
        configDesc[141] = 0x00; // bmCapabilities

        configDesc[142] = 0x05; //
        configDesc[143] = 0x24; // bDescriptorType
        configDesc[144] = 0x06; // bDescriptorSubtype
        configDesc[145] = 0x03; // bControlInterface
        configDesc[146] = 0x04; // bsubordinateInterface

        //Interrupt In endpoint
        configDesc[147] = 0x07; //
        configDesc[148] = 0x05; //
        configDesc[149] = 0x8C; //bendpointAddress
        configDesc[150] = 0x03; //bmAttributes
        configDesc[151] = 0x08; // wMaxPacketSize
        configDesc[152] = 0x00; //
        configDesc[153] = 0x01; // bInterval

        //rndis data interface
        configDesc[154] = 0x09; // bLength             - Descriptor length
        configDesc[155] = 0x04; // bDescriptorType     - Descriptor Type
        configDesc[156] = 0x04; //bInterfaceNumber     --- for RNDIS
        configDesc[157] = 0x00; // bAlt
        configDesc[158] = 0x02; // NumEndpoints
        configDesc[159] = 0x0a; //bInterfaceClass
        configDesc[160] = 0x00; // bInterfaceSubclass
        configDesc[161] = 0x00; // bInterfaceprotocol
        configDesc[162] = 0x00; // iInterface  +++++++++++++++++++++++++++++++++++++need modified

        //Bulk In endpoint
        configDesc[163] = 0x07; //
        configDesc[164] = 0x05; //
        configDesc[165] = 0x8E; //bendpointAddress
        configDesc[166] = 0x02; //bmAttributes
        configDesc[167] = 0x00; // wMaxPacketSize
        configDesc[168] = 0x02; //
        configDesc[169] = 0x00; // bInterval

        //Bulk Out endpoint
        configDesc[170] = 0x07; //
        configDesc[171] = 0x05; //
        configDesc[172] = 0x0D; //bendpointAddress
        configDesc[173] = 0x02; //bmAttributes
        configDesc[174] = 0x00; // wMaxPacketSize
        configDesc[175] = 0x02; //
        configDesc[176] = 0x00; // bInterva

最佳答案

让我回答我自己的问题,我已经弄清楚了这个问题:

RNDIS IAD接口(interface)必须是复合设备的第一个和第二个
尽管问题已解决,但仍然令我感到困惑。

希望本文能帮助其他遇到类似问题的人。

关于usb - RNDIS "Composite device"无法启动,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12154087/

10-13 03:20