前言
本文分享WINUSB枚举过程和描述符实例。
WINUSB枚举过程
描述符实例
设备描述符
static const uint8_t s_dev_desc[] =
{
0x12,
0x01,
0x00,
0x02,
0x00,
0x00,
0x00,
0x40,
0x95,
0x19,
0x01,
0x01,
0x00,
0x01,
0x01,
0x02,
0x00,
0x01,
};
索引EE的字符串描述符
12 03 4d 00 53 00 46 00 54 00 31 00 30 00 30 00 41 00
“MSFT100A”
配置描述符
static const uint8_t s_cfg_desc[] =
{
0x09, /* bLength */
0x02, /* bDescriptorType 0x02 */
0x20, 0x00, /* wTotalLength */
0x01, /* bNumInterfaces */
0x01, /* bConfigurationValue */
0x00, /* iConfiguration */
0x80, /* bmAttributes */
0x64, /* bMaxPower 200mA */
/* 接口0 */
0x09, /* bLength */
0x04, /* bDescriptorType 0x04*/
0x00, /* bInterfaceNumber */
0x00, /* bAlternateSetting */
0x02, /* bNumEndpoints */
0xff, /* bInterfaceClass */
0xff, /* bInterfaceSubClass */
0x00, /* bInterfaceProtocol */
0x00, /* iInterface */
/* 端点 */
0x07, /* bLength */
0x05, /* bDescriptorType 0x05*/
0x81, /* bEndpointAddress */
0x02, /* bmAttributes */
0x40, 0x00, /* wMaxPacketSize */
0x01, /* bInterval */
/* 端点 */
0x07, /* bLength */
0x05, /* bDescriptorType 0x05*/
0x02, /* bEndpointAddress */
0x02, /* bmAttributes */
0x40, 0x00, /* wMaxPacketSize */
0x01, /* bInterval */
};
兼容ID描述符
{
/* Header Sector 16字节头 */
0x28,0,0,0, /* dwLength: 40 */
0,1, /* bcdVersion: 1.0 */
4,0, /* wIndex: 0x04 */
1, /* bCount: 1 */
0,0,0,0,0,0,0, /* RESERVED: 7 bytes */
/* Function Section 24bytes */
0, /* bFirstInterfaceNumber: 0 */
1, /* RESERVED: 1bytes */
(uint8_t)'W',(uint8_t)'I',(uint8_t)'N',(uint8_t)'U',(uint8_t)'S',(uint8_t)'B',0,0, /* compatibleID */
0, 0, 0, 0, 0, 0, 0, 0, /* subCompatibleID */
0, 0, 0, 0, 0, 0 /* RESERVED 6 bytes */
};
扩展属性OS特征描述符
static const uint8_t s_extended_properties_os_feature_desc[] =
{
/* 头 10字节 */
0x8E, 0, 0, 0, /* 长度 length 142 = 132 + 10 byte */
0x00, 0x01, /* BCD version 1.0 */
0x05, 0x00, /* Extended Property Descriptor Index(5) */
0x01, 0x00, /* number of section (1) */
/* 0x84(132) = 50(property section) + 82(property data ) */
/* property section */
0x84, 0x00, 0x00, 0x00, /* size of property section */
0x1, 0, 0, 0, /* property data type (1) (REG_SZ) 多个接口0x01写0x07 (REG_MULTI_SZ) */
0x28, 0, /* property name length (40) */
'D', 0,
'e', 0,
'v', 0,
'i', 0,
'c', 0,
'e', 0,
'I', 0,
'n', 0,
't', 0,
'e', 0,
'r', 0,
'f', 0,
'a', 0,
'c', 0,
'e', 0,
'G', 0,
'U', 0,
'I', 0,
'D', 0,
0, 0,
/* 82 = 0x4E(78) + 4 */
0x4E, 0, 0, 0, /* property data length */
'{', 0,
'1', 0,
'3', 0,
'E', 0,
'B', 0,
'3', 0,
'6', 0,
'0', 0,
'B', 0,
'-', 0,
'B', 0,
'C', 0,
'1', 0,
'E', 0,
'-', 0,
'4', 0,
'6', 0,
'C', 0,
'B', 0,
'-', 0,
'A', 0,
'C', 0,
'8', 0,
'B', 0,
'-', 0,
'E', 0,
'F', 0,
'3', 0,
'D', 0,
'A', 0,
'4', 0,
'7', 0,
'B', 0,
'4', 0,
'0', 0,
'6', 0,
'2', 0,
'}', 0,
0, 0,
};
/* 以下是多个section示例 */
{
/* 头 10字节 */
0xE0, 0, 0, 0, /* length 214+10=224(0xE0) byte */
0x00, 0x01, /* BCD version 1.0 */
0x05, 0x00, /* Extended Property Descriptor Index(5) */
0x01, 0x00, /* number of section (1) */
/* 0xD6(214) = 50+2(property section) + 162(property data ) */
/*property section */
0xD6, 0x00, 0x00, 0x00, /* 214 size of property section */
0x7, 0, 0, 0, /* property data type (1) 多个接口0x01写0x07 (REG_MULTI_SZ) */
0x2a, 0, /* property name length (42) 注意:比单个接口多2字节 's', 0, */
'D', 0,
'e', 0,
'v', 0,
'i', 0,
'c', 0,
'e', 0,
'I', 0,
'n', 0,
't', 0,
'e', 0,
'r', 0,
'f', 0,
'a', 0,
'c', 0,
'e', 0,
'G', 0,
'U', 0,
'I', 0,
'D', 0,
's', 0, /* 比单个接口这里多了个s */
0, 0,
/* 0x9E(158) = 0x4E(78)x2+2
* 162= 0x9E(158)+4
*/
0x9E, 0, 0, 0, /* property data length */
'{', 0,
'1', 0,
'3', 0,
'E', 0,
'B', 0,
'3', 0,
'6', 0,
'0', 0,
'B', 0,
'-', 0,
'B', 0,
'C', 0,
'1', 0,
'E', 0,
'-', 0,
'4', 0,
'6', 0,
'C', 0,
'B', 0,
'-', 0,
'A', 0,
'C', 0,
'8', 0,
'B', 0,
'-', 0,
'E', 0,
'F', 0,
'3', 0,
'D', 0,
'A', 0,
'4', 0,
'7', 0,
'B', 0,
'4', 0,
'0', 0,
'6', 0,
'2', 0,
'}', 0,
0, 0, /* 一个结束符间隔 */
'{', 0,
'1', 0,
'3', 0,
'E', 0,
'B', 0,
'3', 0,
'6', 0,
'0', 0,
'B', 0,
'-', 0,
'B', 0,
'C', 0,
'1', 0,
'E', 0,
'-', 0,
'4', 0,
'6', 0,
'C', 0,
'B', 0,
'-', 0,
'A', 0,
'C', 0,
'8', 0,
'B', 0,
'-', 0,
'E', 0,
'F', 0,
'3', 0,
'D', 0,
'A', 0,
'4', 0,
'7', 0,
'B', 0,
'4', 0,
'0', 0,
'6', 0,
'3', 0,
'}', 0,
0, 0,
0, 0, /* 最后以两个结束符结束 */
};
枚举过程如下
(1)获取设备描述符
(2)设置地址
(3)获取设备描述符
(4)获取配置描述符
(5)获取索引0xEE的MS OS字符串描述符
(6)获取设备相关的扩展兼容ID OS特征描述符:先获取头确认总长
(7)获取设备相关的扩展兼容ID OS特征描述符:根据前面获取的总长获取全部内容
(8)获取索引0x00的字符串描述符
(9)获取索引2的字符串描述符
(10)获取接口相关的扩展属性OS特征描述符:先获取头确认总长
(11)获取接口相关的扩展属性OS特征描述符:根据前面获取的总长获取全部内容
(12)获取设备描述符
(13)获取配置描述符,先获取9字节的配置描述符头确认总长
(14)根据前面获取的总长,获取完整的配置描述符
(15)获取设备状态
(16)设置配置1
(17)获取索引0的字符串描述符
(18)获取索引1的字符串描述符
(19)获取索引2的字符串描述符
(20)获取索引0的字符串描述符
(21)获取索引1的字符串描述符
(22)获取索引2的字符串描述符
完整的抓包数据见附件
总结
枚举过程比较简单,注意三个WINUSB特有的请求,参考前一篇文章。