我是第一次在这里发帖,我希望这将是清晰可读的。
我目前正在尝试使用C ++和Visual Studio 2008以编程方式使用特定的HCD和端口路径测试嵌入式系统上usb设备的存在。
这个想法是传入端口号和hcd值作为函数的参数,函数将返回true或false,表示连接状态。
我编写了一些代码来填充根集线器并证明连接到根集线器端口1的设备是使用来自bool DeviceIsHub
的{{1}}的集线器。
但是,当我尝试枚举连接到root端口1的usb集线器时,我可以测试下游端口的连接状态是否存在设备(此usb集线器的端口1和2)。它似乎不知道usb集线器有多少个下游端口。
我检查了USBVIEW / TreeView,两个应用程序都告诉我设备在那里 但我不确定使用什么ioctl命令代码,以便我可以枚举下游端口,以便检查连接状态。
基于USB视图和USB树的设备结构提供以下内容。
根集线器 - 它有7个端口,只使用第一个端口。
USB集线器(它有四个可用端口)连接到根集线器的第一个端口。
两个USB设备(USB鼠标和USB键盘)连接到USB集线器的端口1和端口2.
我已尝试usbioctl.h
,IOCTL_USB_GET_CONNECTION_INFORMATION
,IOCTL_USB_GET_CONNECTION_NAME
,
IOCTL_USB_GET_CONNECTION_INFORMATION_EX
(不支持,它只能在Windows 8中使用,这是他们用来枚举端口的确切ioctl调用)。
请忽略MessageBoxes,这些是我检查控制路径状态并确定它遵循的路由。
请在我尝试枚举/填充USB集线器时找到我编写的代码。我没有包含Root hub代码,因为它会使这个代码段太大。
我的问题主要在于我认为的辅助USB集线器的枚举过程。
我刚检查了设备的注册表项。 USB集线器似乎已枚举并出现在设备上,因为信息显示在regedit IOCTL_USB_PORT_CONNECTOR_PROPERTIES
下。我相信我在测试应用程序中没有正确枚举它。
非常感谢任何帮助。
更新
我最关心的部分是DeviceIoControl Calls,它试图获取该USB集线器的大小和实际名称。
目前只接受USB_GET_NODE_INFORMATION。用于检索集线器名称的任何其他ioctl调用将在第一个DeviceIoControl失败,它会尝试获取集线器名称的大小,以便知道要分配多少内存 为了它。
更新第2部分
从观察usbview开源代码开始,我相信在检查设备是否存在之前,我需要首先枚举主机控制器和所有设备。我得出一个结论,即如果不进行控制器的枚举,它只会在树下走得太远(最好是第二层,在我的情况下是外部集线器连接的地方)。
我目前正在尝试枚举其他设备和控制器,希望我能够进入第三层设备。我将继续更新这个帖子,直到我自己找出问题或有人能够回答我的问题。
HKLM->System->CurrentControlSet->Enum->USB
答案 0 :(得分:0)
如果启用了UAC且应用程序没有足够的权限,则在Windows 7上枚举USB将失败。 Windows Embedded 7也可能在类似任务上失败。
还有可能通过注册表进行枚举。
答案 1 :(得分:0)
你无法枚举任何可能的东西。通常,USB设备是总线设备或总线设备的子设备。感觉总线设备不可移动,它在启动过程中由acpi.sys自动枚举根设备,或者如果某个其他设备的总线设备连接到根节点,那么该设备必须经历一些事件,这意味着它检测到设备然后枚举它,即插即用将自动查找它的设备类型的驱动程序,如果安装将加载它。如果usb说有4个实际的usb连接器,它们是由中央设备控制的,那么可能有一个usb驱动器/迷你驱动器对。在这种情况下,微型端口驱动程序是usb驱动程序的子代,并由它枚举并附加到它。微型端口的工作是了解实际的硬件,irp和其他所有io都来自它的父母。如果有多个物理连接,则可能有其他子驱动程序。他们都操作硬件,并有一个热插拔。当固件检测到USB设备的安装时,它会将其传送给微型端口驱动程序,并在堆栈中向总线传送,最终通过即插即用进行处理。然后,即插即用将使微型端口驱动程序枚举它的设备,但它需要获得硬件ID。然后它可以找到它的驱动程序并加载它,然后安装该设备并准备好运行。
在不知道设备堆栈的情况下,不清楚它指的是什么设备。请记住,驱动程序堆栈可能无法反映实际的硬件拓扑。还有一些称为逻辑设备的东西,它们不代表任何硬件。必须考虑这些中的任何一个,并且您需要知道哪个设备对应于节点的末尾。
还有一点细节。我不熟悉用户模式api和驱动程序,因为我是内核,但似乎wsprintf第二个参数控制输入缓冲区输出缓冲区的格式。它应该是%[]%[]
[]
是表示格式的符号。它将根据第一个符号格式化第一个字符,然后使用第二个符号格式化第二个字符。似乎你在做一些与众不同的事情。
最后一点,现在似乎已弃用wsprintf()
,而不是其他api。