Microsoft 为复合设备提供的名为 USB 通用父驱动程序 (Usbccgp.sys) 的独立驱动程序。
许多 USB 设备公开多个 USB 接口。 在 USB 术语中,这些设备称为 复合设备。 Windows 操作系统在 USB 总线驱动程序 (Usbhub.sys) 中包含一个通用父设备,该设备将复合设备的每个接口公开为单独的设备。 通过将此功能传输到名为 USB 通用父 驱动程序 (Usbccgp.sys) 的独立驱动程序,可以简化和改进此功能。 设备供应商可以使用通用父驱动程序的功能选择性地对某些接口使用 Microsoft 提供的驱动程序支持。
某些复合设备的接口独立运行。 例如,具有电源按钮的复合 USB 键盘可能有一个接口用于键盘,另一个接口用于电源按钮。 USB 泛型父驱动程序将其中每个接口枚举为单独的设备。 操作系统加载 Microsoft 提供的键盘驱动程序来管理键盘界面,并加载 Microsoft 提供的电源键驱动程序来管理电源键接口。
如果本机 Windows 驱动程序不支持设备的接口,则设备的供应商应提供接口的驱动程序和 INF 文件。 INF 文件应具有与接口的设备 ID 匹配的 INF DDInstall 部分。 INF 文件不能与复合设备本身的设备 ID 匹配,因为它会阻止通用父驱动程序加载。
某些设备将接口分组到接口集合中,这些接口集合协同工作以执行特定功能。 当接口分组到接口集合中时,泛型父驱动程序会将每个集合而不是每个单独的接口视为一个设备。
在 Windows 为复合设备的接口加载客户端驱动程序后,通用父驱动程序将多路复用来自客户端驱动程序的数据流,将这些单独的交互合并为复合设备的单个数据流。 泛型父级是整个复合设备及其所有接口的电源策略所有者。 它还管理同步和即插即用请求。
如果 Microsoft 提供的驱动程序支持某些接口,但不支持其他接口,则通用父驱动程序可以简化复合硬件供应商的任务。 此类设备的供应商只需要为不支持的接口提供驱动程序,因为通用父驱动程序有助于将 Microsoft 提供的驱动程序用于支持的接口。
以下部分介绍泛型父驱动程序的特性和功能:
USB 复合设备的枚举
当新的 USB 设备连接到主机时,USB 总线驱动程序将为设备创建物理设备对象(PDO),并生成 PnP 事件来报告新的 PDO。 然后,操作系统查询与 PDO 关联的硬件 ID 的总线驱动程序。
对于所有 USB 设备,USB 总线驱动程序报告采用 以下格式的设备 ID :
USB\VID_xxxx&PID_yyyy
xxxx 和 yyy 值分别取自设备描述符的 idVendor 和 idProduct 字段。
如果设备满足以下要求,则总线驱动程序还会报告兼容的标识符(ID USB\COMPOSITE):
- 设备描述符(bDeviceClass)的设备类字段必须包含一个值为零,或者设备描述符的类(bDeviceClass)、子类(bDeviceSubClass)和协议(bDeviceProtocol)字段必须分别具有值0xEF、0x02和0x01,如 USB 接口关联描述符中所述。
- 设备必须具有多个接口。
- 设备必须具有单个配置。
总线驱动程序还会检查设备描述符的设备类(bDeviceClass)、子类(bDeviceSubClass)和协议(bDeviceProtocol)字段。 如果这些字段为零,则设备是复合设备,总线驱动程序报告 PDO 的 USB\COMPOSITE 的额外兼容标识符(ID)。
在总线驱动程序检索新 PDO 的硬件和兼容 ID 后,操作系统将搜索 INF 文件。 如果其中一个 INF 文件包含设备 ID 的匹配项,Windows 将加载该驱动程序和通用父驱动程序不会发挥作用。 如果没有 INF 文件包含设备 ID,并且 PDO 具有兼容的 ID,Windows 将搜索兼容的 ID。 此搜索在 Usb.inf 中生成匹配项,并导致操作系统加载 USB 通用父驱动程序(Usbccgp.sys)。
如果设备没有生成 USB\COMPOSITE 兼容 ID 的特征,则必须提供加载通用父驱动程序的 INF 文件。 INF 文件应包含引用 Usb.inf 的需要/包含部分。
如果复合设备具有多个配置,则提供的 INF 文件必须指定通用父级应在注册表中使用的配置。 配置Usbccgp.sys以选择非默认 USB 配置中介绍了必要的注册表项。
USB 复合设备上的描述符
如 USB 规范所述,每个 USB 设备都提供一组用于定义其功能的分层描述符。 在顶级,每个设备都有一个或多个 USB 配置描述符,其中每个都有一个或多个接口描述符。
在 Windows Vista 之前,Microsoft 提供的驱动程序仅选择配置 1。 在 Windows Vista 和更高版本的 Windows 中,可以设置注册表值以指定 USB 通用父驱动程序 (Usbccgp.sys) 将使用的配置。
在配置中,接口和接口集合是独立管理的。 每个接口在描述符级别由其USB_INTERFACE_DESCRIPTOR结构的 bInterfaceNumber 成员中的唯一值表示。
接口的功能由同一结构的 bInterfaceClass、 bInterfaceSubClass 和 bInterfaceProtocol 成员以及可能跟随它的类特定描述符指示。
枚举 USB 复合设备上的接口
复合 USB 设备上的接口可以分组到集合中,也可以单独表示一个 USB 函数。 当接口未分组到集合中时,泛型父驱动程序会为每个接口创建一个 PDO,并为每个 PDO 生成一组硬件 ID。
接口 PDO 的设备 ID 采用以下形式:
USB\VID_v(4)&PID_p(4)&MI_z(2)
在这些 ID 中:
- v (4) 是 USB 标准委员会分配给供应商的四位数供应商代码。
- p (4) 是供应商分配给设备的四位数产品代码。
- z (2) 是从接口描述符的 bInterfaceNumber 字段中提取的接口号。
泛型父驱动程序还通过使用接口描述符 (USB_INTERFACE_DESCRIPTOR) 中 的信息生成以下兼容 ID:
USB\CLASS_d(2)&SUBCLASS_s(2)&PROT_p(2)
USB\CLASS_d(2)&SUBCLASS_s(2)
USB\CLASS_d(2)
在这些 ID 中:
- d (2) 是 bInterfaceClass) (类代码
- s (2) 是 bInterfaceSubClass) (子类代码
- p (2) 是 bInterfaceProtocol) (协议代码
其中每个代码都是一个四位数的数字。
USB 复合设备上的接口集合枚举概述
复合 USB 设备上的接口可以分组到集合中。 USB 泛型父驱动程序 (Usbccgp.sys) 可以通过四种方式枚举接口集合。
这四种接口集合枚举方法按以下方式分层排列:
- 供应商提供的回调例程
如果供应商已向 USB 泛型父驱动程序 (Usbccgp.sys) 注册回调例程,则泛型父驱动程序优先于回调例程,并允许回调例程对接口进行分组,而不是使用其他方法; - 联合功能描述符
如果供应商已在 USB 泛型父驱动程序中启用了 CDC 和 WMCDC 枚举,则泛型父驱动程序使用 联合功能描述符 (UFD) 将接口分组到集合中。 启用后,此方法优先于所有其他方法,供应商提供的回调例程除外; - 接口关联描述符
如果 存在接口关联描述符 (IAD) ,USB 泛型父驱动程序始终使用 IAD(而不是旧方法)对接口进行分组。 Microsoft 建议供应商使用 IAD 来定义接口集合; - 旧版音频方法
USB 泛型父驱动程序能够使用为音频功能保留的旧技术枚举接口集合。 如果设备上有任何 IAD,则泛型父驱动程序不使用此方法;
为复合设备自定义接口集合的枚举
某些 USB 设备具有 USB 接口关联描述符 (IAD) 无法描述的接口集合。 在 Windows Vista 和更高版本的操作系统中,供应商可以自定义 USB 通用父驱动程序 (Usbccgp.sys) 定义和枚举设备接口集合的方式。 这是通过筛选器驱动程序中的 枚举回调例程 完成的。 回调例程可帮助泛型父驱动程序为设备定义自定义接口集合。
若要使泛型父驱动程序定义自定义接口集合,复合设备的供应商必须:
- USBC_START_DEVICE_CALLBACK实现枚举回调例程;
- 提供指向 USB 设备配置接口中的回调例程的指针, (USBC_DEVICE_CONFIGURATION_INTERFACE_V1) 的 StartDeviceCallback 成员;
- 提供与复合设备的设备 ID 匹配的 INF 文件,并显式加载 USB 泛型父驱动程序和筛选器驱动程序;
实现注意事项
包含枚举回调例程的筛选器驱动程序可以是上限筛选器驱动程序,也可以是低级筛选器驱动程序。 当 USB 泛型父驱动程序收到启动复合设备的 IRP_MN_START_DEVICE 请求时,它会通过向驱动程序堆栈顶部发送 IRP_MN_QUERY_INTERFACE 请求来查询 USB 设备配置接口。
收到IRP_MN_QUERY_INTERFACE请求时,筛选器驱动程序必须在请求的 InterfaceType 成员中检查 GUID 类型,以验证请求的接口的类型USB_BUS_INTERFACE_USBC_CONFIGURATION_GUID。 如果是,则筛选器驱动程序返回指向 IRP 的 Interface 成员中的 接口 的指针。
枚举回调例程必须返回指向 函数描述符 数组的指针,描述接口集合 USBC_FUNCTION_DESCRIPTOR。 每个函数描述符都包含一个接口描述符数组,描述接口集合USB_INTERFACE_DESCRIPTOR。 回调例程必须从非分页池中分配函数描述符和接口描述符。 泛型父驱动程序释放此内存。 回调例程必须确保每个USB_INTERFACE_DESCRIPTOR的 NumberOfInterfaces 成员准确报告接口集合中的接口数。
泛型父驱动程序为每个函数描述符 (PDO) 创建物理设备对象。通用父驱动程序例程中汇总了 USB 设备配置接口和枚举回调例程。
USB 通用父驱动程序加载机制
当复合设备满足 枚举 USB 复合设备中所述的要求时,操作系统会生成 兼容的 ID USB\COMPOSITE ,以指示该设备是复合设备。 兼容 ID 在 Usb.inf 中生成匹配项,操作系统无需供应商提供的 INF 文件帮助即可自动加载 USB 通用父驱动程序。
但是,此默认机制不适用于需要接口集合自定义枚举的复合设备,因为在默认机制中,系统不会加载供应商提供的筛选器驱动程序。 若要使枚举回调例程机制正常工作,当 USB 泛型父级枚举复合设备的接口集合时,必须已加载公开 USB 设备配置接口的筛选器驱动程序。 这要求复合设备的供应商安装与复合设备的设备 ID 匹配的 INF 文件,并显式加载 USB 通用父驱动程序和筛选器驱动程序。