windows加载即插即用PNP设备的过程
无论是应用通知总线创建子设备或者是真实的物理设备被总线发现,PNP设备均是通过其总线驱动来枚举的。
总线驱动监听其总线上设备的变化(包括设备的新建或移除),当有设备发生变化时,使用函数IoInvalidateDeviceRelations来通知PNP管理器其总线设备上有子设备的变化。
当PNP管理器收到通知后,会通过IRP_MN_QUERY_DEVICE_RELATIONS IRP来获取总线设备上的子设备。总线驱动返回其总线上的所有子设备集。
pnp 管理器根据该IRP_MN_QUERY_DEVICE_RELATIONS返回的信息来更新自己的设备树,创建新设备的节点。然后PNP管理器通过以下IRP收集设备的信息。
- IRP_MN_QUERY_ID:
- 通过BusQueryInstanceID标志收集设备的实例ID,
- 通过BusQueryHardwareIDs标志收集设备的硬件ID
- 通过BusQueryDeviceID标志收集设备ID
- 通过BusQueryCompatibleIDs收集设备的兼容ID
- 通过BusQueryContainerID收集设备的容器ID
PDOHandleQueryDeviceText:
- DeviceTextDescription:设备的描述信息
- DeviceTextLocationInformation
IRP_MN_QUERY_CAPABILITIES:获取设备的CAPABILITIES。可直接返回总线驱动查询到的DEVICE_CAPABILITIES。
- IRP_MN_QUERY_BUS_INFORMATION:获取与总线相关的信息。使用PNP_BUS_INFORMATION标识总线类型,总线号等。
- IRP_MN_QUERY_RESOURCES:获取分配给该子设备的硬件资源,包括中断,IO,内存。
- IRP_MN_QUERY_RESOURCE_REQUIREMENTS:获取分配给该子设备的请求硬件资源,包括中断,IO,内存。
以下成功后,在注册表中创建相关项:
HKLM\System\CurrentControlSet\Enum\<enumerator>\<deviceID>
HKLM\System\CurrentControlSet\Enum\<enumerator>\<deviceID>\<instanceID>
最后根据设备ID安装相应的驱动程序。
关于各IRP详细的使用参见:即插即用简介 https://docs.microsoft.com/zh-cn/windows-hardware/drivers/kernel/introduction-to-plug-and-play
主要过程如下:
1) IoInvalidateDeviceRelations通知PNP管理器有设备变化。
2) 对IRP_MN_QUERY_DEVICE_RELATIONS 返回该总线上的设备集合(总线驱动创建的PDOs)。
3) 对IRP_MN_QUERY_ID返回设备的相关ID信息。
- BusQueryDeviceID
- BusQueryInstanceID
- BusQueryHardwareIDs
- BusQueryCompatibleIDs
4.返回IRP_MN_QUERY_CAPABILITIES
5.IRP_MN_QUERY_DEVICE_TEXT返回设备的字符描述信息
- DeviceTextDescription
- DeviceTextLocationInformation
6.IRP_MN_QUERY_BUS_INFORMATION 总线信息。
7.资源信息IRP_MN_QUERY_RESOURCES,IRP_MN_QUERY_RESOURCE_REQUIREMENTS