Programming the Microsoft Windows Driver Model中描述:<br />多功能设备 <br />如果你的设备有一个配置和多个接口,Microsoft的总线驱动程序将自动把这种设备当作一个组合的,或多功能设备。你必须为每个接口提供一个功能驱动程序,通过在INF中用接口类和子类替换厂商标识和产品标识。总线驱动程序为每个接口创建一个物理设备对象(PDO),这样,PnP管理器就可以装载独立的驱动程序。当任何一个功能驱动程序读取配置描述符时,总线驱动程序就提供一个修改后的仅描述一个接口的描述符。关于INF文件中的设备标识的各种可能形式请参考第十二章。<br /><br />以上是书上的一段话,我做了些试验说明事情不是那么回事<br />例如我的设备有两个INTERFACE第一个INTERFACE中只有一个中断端点EP1<br />第二个INTERFACE 中有两个批端点,分别为EP2和EP3,按上面的意思,端点EP2,和EP3是不可用的,而我在配置的过程中获取这些端点的句柄,之后向这些端点读/写数据完全可以,是不是说上面书上的描述有问题?<br /><br />我的配置代码如下:<br /><br />/////////////////////////////////////////////////////////////////////////////<br />//UsbSelectConfiguration: 选择配置<br />NTSTATUS UsbSelectConfiguration( IN PUSER_DEVICE_EXTENSION dx)<br />{<br /> // 获取所有描述符<br /> PUSB_CONFIGURATION_DESCRIPTOR Descriptors = NULL;<br /> ULONG size;<br /> ULONG i;<br /> NTSTATUS status = UsbGetConfigurationDescriptors( dx, Descriptors, 0, size);<br /> if( !NT_SUCCESS(status))<br /> {<br /> FreeIfAllocated(Descriptors);<br /> return status;<br /> }<br /><br /> USBD_INTERFACE_LIST_ENTRY ilist[3];<br /><br /> //从复合的配置描述符中寻找第一个接口描述符<br /> PUSB_INTERFACE_DESCRIPTOR id = USBD_ParseConfigurationDescriptorEx(<br /> Descriptors, Descriptors,<br /> 0, -1, -1, -1, -1); //均为搜索条件 -1表示无<br /> if( id==NULL)<br /> {<br /> FreeIfAllocated(Descriptors);<br /> return STATUS_NO_SUCH_DEVICE;<br /> }<br /><br /> //用第一个接口描述符填充接口数组<br /> ilist[0].InterfaceDescriptor = id;<br /> ilist[0].Interface = NULL; //这将指向urb->UrbSelectConfiguration.Interface<br /><br /> //找到第二个接口<br /> id = USBD_ParseConfigurationDescriptorEx(<br /> Descriptors, Descriptors,<br /> 1, -1, -1, -1, -1); //均为搜索条件 -1表示无<br /> if( id==NULL)<br /> {<br /> FreeIfAllocated(Descriptors);<br /> return STATUS_NO_SUCH_DEVICE;<br /> }<br /> ilist[1].InterfaceDescriptor = id;<br /> ilist[1].Interface=NULL;<br /><br /> //表示结束<br /> ilist[2].InterfaceDescriptor= NULL;<br /> ilist[2].Interface=NULL;<br /><br /> // 创建 select configuration URB <br /> PURB urb = USBD_CreateConfigurationRequestEx( Descriptors, ilist);<br /><br /> if(urb==NULL)<br /> DebugPrint("urb is null");<br /><br /> status = CallUSBDI( dx->NextStackDevice, urb);<br /> if( !NT_SUCCESS(status) || !USBD_SUCCESS( urb->UrbHeader.Status))<br /> {<br /> DebugPrint("Error Status:%x urb Status:%x",status,urb->UrbHeader.Status);<br /> status = STATUS_UNSUCCESSFUL;<br /> }<br /> else<br /> {<br /> dx->UsbConfigurationHandle = urb->UrbSelectConfiguration.ConfigurationHandle;<br /> PUSBD_INTERFACE_INFORMATION InterfaceInfo = &urb->UrbSelectConfiguration.Interface;<br /> DebugPrint("EndPoint Number:%d",InterfaceInfo->NumberOfPipes);<br /><br /> PUSBD_PIPE_INFORMATION pi = &InterfaceInfo->Pipes[0];<br /><br /> pi=&(ilist[1].Interface->Pipes[0]);<br /> dx->hEpBulkWrite = pi->PipeHandle;//这是我获取第二个接口中EP2的方法<br /> pi=&(ilist[1].Interface->Pipes[1]);<br /> dx->hEpBulkRead=pi->PipeHandle;//这是获取EP3的方法<br /> }<br /><br /> FreeIfAllocated(urb);<br /> FreeIfAllocated(Descriptors);<br /> return status;<br />}<br /> |
|