当前位置:网站首页 > 容器化与Kubernetes > 正文

虚拟usb软件(usb虚拟化解决方案)



Windows 操作系统中 (UDE) 支持 USB 模拟设备,用于开发模拟通用串行总线 (USB) 主机控制器驱动程序和连接的虚拟 USB 设备。 这两个组件组合成单个 KMDF 驱动程序,该驱动程序可以与 Microsoft 提供的 USB 设备模拟类扩展 (UdeCx) 通信。

Windows 驱动程序工具包 (WDK) 包含开发驱动程序所需的资源,如头文件、库、工具和示例。若要编写功能控制器驱动程序,需要:

UDE 的体系结构

UDE 驱动程序的结构如下:windows USB 设备驱动程序开发-USB 设备模拟 (一)

在上图中,

  • USB 集线器驱动程序 (Usbhub3.sys) 是 KMDF 驱动程序。 集线器驱动程序负责管理 USB 集线器及其端口、枚举和创建物理设备对象, (PDO) USB 设备和可能连接到其下游端口的其他集线器;
  • USB 主机控制器扩展 (Ucx01000.sys) 是堆栈中上述集线器驱动程序的抽象层,提供一种通用机制,用于将请求排队到基础主机控制器驱动程序;
  • UdeCx) (UDE 类扩展通过客户端实现的回调函数调用到 UDE 客户端驱动程序。 类扩展为客户端驱动程序提供例程,用于创建和管理 UDE 对象;
  • UDE 客户端驱动程序 管理硬件,与 WDF 和 UDE API 交互。 上边缘使用 USB 构造与 WDF 和 UDE 类扩展通信。 其下边缘使用硬件的接口与硬件通信;
  • 自定义硬件:例如,可以模拟 PCI 硬件以用作 USB 设备;
UDE 设备节点

下面是为 UDE 客户端驱动程序加载的设备堆栈:

windows USB 设备驱动程序开发-USB 设备模拟 (一)

编写 UDE 客户端驱动程序
本文介绍 USB 设备仿真 (UDE) 类扩展的行为,以及客户机驱动程序必须为仿真主机控制器及其连接的设备执行的任务。 它提供有关类驱动程序和类扩展如何通过一组例程和回调函数与每个函数进行通信的信息。 它还介绍了客户端驱动程序应实现的功能。

UDE对象和句柄

UDE 类扩展和客户端驱动程序使用表示模拟主机控制器和虚拟设备的特定 WDF 对象,包括用于在设备和主机之间传输数据的端点和 URB。 客户端驱动程序请求创建对象,并且对象的生存期由类扩展管理。

  • 模拟主机控制器对象 (WDFDEVICE): 表示模拟的主机控制器,是 UDE 类扩展和客户端驱动程序之间的主句柄;
  • UDE 设备对象 (UDECXUSBDEVICE): 表示连接到模拟主机控制器上的端口的虚拟 USB 设备;
  • UDE 端点对象 (UDECXUSBENDPOINT: 表示 USB 设备的顺序数据管道。 用于接收端点发送或接收数据的软件请求;
初始化模拟主机控制器

下面是客户端驱动程序检索模拟主机控制器的 WDFDEVICE 句柄的顺序的摘要。 我们建议驱动程序在其 EvtDriverDeviceAdd 回调函数中执行这些任务:

1.通过传递对框架传递 WDFDEVICE_INIT 的引用来调用 UdecxInitializeWdfDeviceInit;

2.使用设置信息初始化 WDFDEVICE_INIT 结构,以便此设备与其他 USB 主机控制器类似。 例如,分配 FDO 名称和符号链接,将设备接口注册到 Microsoft 提供的 GUID_DEVINTERFACE_USB_HOST_CONTROLLER GUID 作为设备接口 GUID,以便应用程序可以打开设备的句柄;

3.调用 WdfDeviceCreate 以创建框架设备对象;

4.调用 UdecxWdfDeviceAddUsbDeviceEmulation 并注册客户端驱动程序的回调函数;

下面是与主机控制器对象关联的回调函数,这些函数由 UDE 类扩展调用。 这些函数必须由客户端驱动程序实现。

  • EVT_UDECX_WDF_DEVICE_QUERY_USB_CAPABILITY:确定客户端驱动程序必须向类扩展报告的主控制器支持的功能;
  • EVT_UDECX_WDF_DEVICE_RESET:可选。 重置主机控制器和/或连接的设备;
 
  
处理发送到主机控制器的用户模式 IOCTL 请求

初始化期间,UDE 客户端驱动程序公开 GUID_DEVINTERFACE_USB_HOST_CONTROLLER 设备接口 GUID。 这使驱动程序能够接收来自使用该 GUID 打开设备句柄的应用程序的 IOCTL 请求。

为了处理这些请求,客户端驱动程序注册 EvtIoDeviceControl 事件回调。 在实现中,驱动程序可以选择将请求转发到 UDE 类扩展进行处理,而不是处理请求。 若要转发请求,驱动程序必须调用 UdecxWdfDeviceTryHandleUserIoctl。 如果收到的 IOCTL 控制代码对应于标准请求,例如检索设备描述符,则类扩展将处理并成功完成请求。 在这种情况下,UdecxWdfDeviceTryHandleUserIoctl 以 TRUE 作为返回值完成。 否则,调用返回 FALSE,驱动程序必须确定如何完成请求。 在最简单的实现中,驱动程序可以通过调用 WdfRequestComplete 以完成请求,并给出相应的失败代码。

 
  
报告主机控制器的功能

在上层驱动程序可以使用 USB 主机控制器的功能之前,驱动程序必须确定控制器是否支持这些功能。 驱动程序通过调用 WdfUsbTargetDeviceQueryUsbCapability 和 USBD_QueryUsbCapability 进行此类查询。 这些调用将转接到 USB 设备仿真 (UDE) 类扩展。 获取请求后,类扩展将调用客户端驱动程序的 EVT_UDECX_WDF_DEVICE_QUERY_USB_CAPABILITY 实现。 此调用仅在 EvtDriverDeviceAdd 完成之后进行,通常在 EvtDevicePrepareHardware 中,而不是在 EvtDeviceReleaseHardware 之后进行。 这是需要回调函数。

在实现中,客户端驱动程序必须报告它是否支持请求的功能。 UDE 不支持某些功能,例如静态流。

 
  
创建虚拟 USB 服务

虚拟 USB 设备的行为类似于 USB 设备。 它支持具有多个接口的配置,每个接口都支持备用设置。 每个设置可以有一个用于数据传输的端点。 所有描述符(设备、配置、接口、端点)都由 UDE 客户端驱动程序设置,以便设备可以报告与真实 USB 设备非常类似的信息。

注意: UDE 客户端驱动程序不支持外部集线器

下面是客户端驱动程序为 UDE 设备对象创建 UDECXUSBDEVICE 句柄的顺序的摘要。 驱动程序在检索模拟主机控制器的 WDFDEVICE 句柄后必须执行这些步骤。 我们建议驱动程序在其 EvtDriverDeviceAdd 回调函数中执行这些任务。

1.调用 UdecxUsbDeviceInitAllocate 以获取指向创建设备所需的初始化参数的指针。 此结构由 UDE 类扩展分配;

2.通过设置 UDECX_USB_DEVICE_STATE_CHANGE_CALLBACKS 的成员并调用 UdecxUsbDeviceInitSetStateChangeCallbacks 来注册事件回调函数。 下面是与 UDE 设备对象关联的回调函数,这些函数由 UDE 类扩展调用;

这些函数由客户端驱动程序实现以创建或配置端点。

  • EVT_UDECX_USB_DEVICE_DEFAULT_ENDPOINT_ADD
  • EVT_UDECX_USB_DEVICE_ENDPOINT_ADD
  • EVT_UDECX_USB_DEVICE_ENDPOINTS_CONFIGURE
  • EVT_UDECX_USB_DEVICE_D0_ENTRY
  • EVT_UDECX_USB_DEVICE_D0_EXIT
  • EVT_UDECX_USB_DEVICE_SET_FUNCTION_SUSPEND_AND_WAKE

3.调用 UdecxUsbDeviceInitSetSpeed 以设置 USB 设备速度以及设备类型、USB 2.0 或 SuperSpeed 设备。

4.调用 UdecxUsbDeviceInitSetEndpointsType 以指定设备支持的端点类型:简单或动态。 如果客户端驱动程序选择创建简单端点,驱动程序必须在插入设备之前创建所有端点对象。 设备必须只有一个配置,每个接口只能有一个接口设置。 对于动态端点,驱动程序可以在设备收到 EVT_UDECX_USB_DEVICE_ENDPOINTS_CONFIGURE 事件回调后随时创建端点。

5.调用上述任一方法,将必要的描述符添加到设备。

  • UdecxUsbDeviceInitAddDescriptor
  • UdecxUsbDeviceInitAddDescriptorWithIndex
  • UdecxUsbDeviceInitAddStringDescriptor
  • UdecxUsbDeviceInitAddStringDescriptorRaw

如果 UDE 类扩展使用上述方法之一收到客户端驱动程序在初始化期间提供的标准描述符的请求,则类扩展会自动完成请求。 类扩展不会将该请求转发到客户端驱动程序。 此设计减少了驱动程序需要处理控制请求的请求数。 此外,它还不需要驱动程序实现描述符逻辑,这些逻辑需要对设置数据包进行广泛的分析,并正确处理 wLength 和 TransferBufferLength。 此列表包括标准请求。 客户端驱动程序不需要为这些请求检查(仅当调用上述方法以添加描述符时):

  • USB_REQUEST_GET_DESCRIPTOR
  • USB_REQUEST_SET_CONFIGURATION
  • USB_REQUEST_SET_INTERFACE
  • USB_REQUEST_SET_ADDRESS
  • USB_REQUEST_SET_FEATURE
  • USB_FEATURE_FUNCTION_SUSPEND
  • USB_FEATURE_REMOTE_WAKEUP
  • USB_REQUEST_CLEAR_FEATURE
  • USB_FEATURE_ENDPOINT_STALL
  • USB_REQUEST_SET_SEL
  • USB_REQUEST_ISOCH_DELAY

但是,对于接口、特定于类或供应商定义的描述符的请求,UDE 类扩展会将它们转发到客户端驱动程序。 驱动程序必须处理这些 GET_DESCRIPTOR 请求。

6.调用 UdecxUsbDeviceCreate 以创建 UDE 设备对象并检索 UDECXUSBDEVICE 句柄。

7.通过调用 UdecxUsbEndpointCreate 创建静态端点。

8.调用 UdecxUsbDevicePlugIn 以指示设备已附加的 UDE 类扩展,并且可以在端点上接收 I/O 请求。 此调用后,类扩展还可以在端点和 USB 设备上调用回调函数。 请注意如果需要在运行时删除 USB 设备,客户端驱动程序可以调用 UdecxUsbDevicePlugOutAndDelete。 如果驱动程序想要使用设备,则必须通过调用 UdecxUsbDeviceCreate 来创建它。

在此示例中,描述符声明假定为全局变量,此处以 HID 设备为例进行声明:

 
  

下面是客户端驱动程序通过注册回调函数、设置设备速度、指示端点类型以及最后设置某些设备描述符来指定初始化参数的示例。

到此这篇虚拟usb软件(usb虚拟化 
  解决方案)的文章就介绍到这了,更多相关内容请继续浏览下面的相关推荐文章,希望大家都能在编程的领域有一番成就! 
  

                            

版权声明


相关文章:

  • awvs下载(awvs汉化版)2025-11-09 20:45:10
  • 启动docker镜像命令(docker启动镜像容器命令)2025-11-09 20:45:10
  • labview调用dll动态库出现内存泄露(labview动态链接库dll初始化失败怎么弄)2025-11-09 20:45:10
  • kvm虚拟化的特点是什么?(kvm虚拟化是什么意思)2025-11-09 20:45:10
  • list转为字符串并换行(将list转化为字符串并以逗号隔开)2025-11-09 20:45:10
  • qt中字符串转int(qt将字符串转化为二进制)2025-11-09 20:45:10
  • nsenter 进入容器(nsenter进入容器ping)2025-11-09 20:45:10
  • lda主题模型分析树图可视化(lda主题模型结果分析)2025-11-09 20:45:10
  • ue将dos转换为unix(ue dos转化为unix)2025-11-09 20:45:10
  • docker如何启动容器(docker启动容器后ps不存在)2025-11-09 20:45:10
  • 全屏图片