爆款云主机2核4G限时秒杀,88元/年起!
查看详情

活动

天翼云最新优惠活动,涵盖免费试用,产品折扣等,助您降本增效!
热门活动
  • 618智算钜惠季 爆款云主机2核4G限时秒杀,88元/年起!
  • 免费体验DeepSeek,上天翼云息壤 NEW 新老用户均可免费体验2500万Tokens,限时两周
  • 云上钜惠 HOT 爆款云主机全场特惠,更有万元锦鲤券等你来领!
  • 算力套餐 HOT 让算力触手可及
  • 天翼云脑AOne NEW 连接、保护、办公,All-in-One!
  • 中小企业应用上云专场 产品组合下单即享折上9折起,助力企业快速上云
  • 息壤高校钜惠活动 NEW 天翼云息壤杯高校AI大赛,数款产品享受线上订购超值特惠
  • 天翼云电脑专场 HOT 移动办公新选择,爆款4核8G畅享1年3.5折起,快来抢购!
  • 天翼云奖励推广计划 加入成为云推官,推荐新用户注册下单得现金奖励
免费活动
  • 免费试用中心 HOT 多款云产品免费试用,快来开启云上之旅
  • 天翼云用户体验官 NEW 您的洞察,重塑科技边界

智算服务

打造统一的产品能力,实现算网调度、训练推理、技术架构、资源管理一体化智算服务
智算云(DeepSeek专区)
科研助手
  • 算力商城
  • 应用商城
  • 开发机
  • 并行计算
算力互联调度平台
  • 应用市场
  • 算力市场
  • 算力调度推荐
一站式智算服务平台
  • 模型广场
  • 体验中心
  • 服务接入
智算一体机
  • 智算一体机
大模型
  • DeepSeek-R1-昇腾版(671B)
  • DeepSeek-R1-英伟达版(671B)
  • DeepSeek-V3-昇腾版(671B)
  • DeepSeek-R1-Distill-Llama-70B
  • DeepSeek-R1-Distill-Qwen-32B
  • Qwen2-72B-Instruct
  • StableDiffusion-V2.1
  • TeleChat-12B

应用商城

天翼云精选行业优秀合作伙伴及千余款商品,提供一站式云上应用服务
进入甄选商城进入云市场创新解决方案
办公协同
  • WPS云文档
  • 安全邮箱
  • EMM手机管家
  • 智能商业平台
财务管理
  • 工资条
  • 税务风控云
企业应用
  • 翼信息化运维服务
  • 翼视频云归档解决方案
工业能源
  • 智慧工厂_生产流程管理解决方案
  • 智慧工地
建站工具
  • SSL证书
  • 新域名服务
网络工具
  • 翼云加速
灾备迁移
  • 云管家2.0
  • 翼备份
资源管理
  • 全栈混合云敏捷版(软件)
  • 全栈混合云敏捷版(一体机)
行业应用
  • 翼电子教室
  • 翼智慧显示一体化解决方案

合作伙伴

天翼云携手合作伙伴,共创云上生态,合作共赢
天翼云生态合作中心
  • 天翼云生态合作中心
天翼云渠道合作伙伴
  • 天翼云代理渠道合作伙伴
天翼云服务合作伙伴
  • 天翼云集成商交付能力认证
天翼云应用合作伙伴
  • 天翼云云市场合作伙伴
  • 天翼云甄选商城合作伙伴
天翼云技术合作伙伴
  • 天翼云OpenAPI中心
  • 天翼云EasyCoding平台
天翼云培训认证
  • 天翼云学堂
  • 天翼云市场商学院
天翼云合作计划
  • 云汇计划
天翼云东升计划
  • 适配中心
  • 东升计划
  • 适配互认证

开发者

开发者相关功能入口汇聚
技术社区
  • 专栏文章
  • 互动问答
  • 技术视频
资源与工具
  • OpenAPI中心
开放能力
  • EasyCoding敏捷开发平台
培训与认证
  • 天翼云学堂
  • 天翼云认证
魔乐社区
  • 魔乐社区

支持与服务

为您提供全方位支持与服务,全流程技术保障,助您轻松上云,安全无忧
文档与工具
  • 文档中心
  • 新手上云
  • 自助服务
  • OpenAPI中心
定价
  • 价格计算器
  • 定价策略
基础服务
  • 售前咨询
  • 在线支持
  • 在线支持
  • 工单服务
  • 建议与反馈
  • 用户体验官
  • 服务保障
  • 客户公告
  • 会员中心
增值服务
  • 红心服务
  • 首保服务
  • 客户支持计划
  • 专家技术服务
  • 备案管家

了解天翼云

天翼云秉承央企使命,致力于成为数字经济主力军,投身科技强国伟大事业,为用户提供安全、普惠云服务
品牌介绍
  • 关于天翼云
  • 智算云
  • 天翼云4.0
  • 新闻资讯
  • 天翼云APP
基础设施
  • 全球基础设施
  • 信任中心
最佳实践
  • 精选案例
  • 超级探访
  • 云杂志
  • 分析师和白皮书
  • 天翼云·创新直播间
市场活动
  • 2025智能云生态大会
  • 2024智算云生态大会
  • 2023云生态大会
  • 2022云生态大会
  • 天翼云中国行
天翼云
  • 活动
  • 智算服务
  • 产品
  • 解决方案
  • 应用商城
  • 合作伙伴
  • 开发者
  • 支持与服务
  • 了解天翼云
      • 文档
      • 控制中心
      • 备案
      • 管理中心

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

      首页 知识中心 软件开发 文章详情页

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

      2024-09-10 08:20:45 阅读次数:55

      硬件,连接器,驱动开发

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

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

      UdeCx: (udecx.sys) 函数驱动程序使用的 WDF 扩展。 此扩展包含在 Windows 中。
      链接到存根库 (Udecxstub.lib) 。 存根库位于 WDK 中。包括 WDK 中提供的 Udecx.h。

      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:可选。 重置主机控制器和/或连接的设备;
      EVT_WDF_DRIVER_DEVICE_ADD                 Controller_WdfEvtDeviceAdd;
      
      #define BASE_DEVICE_NAME                  L"\\Device\\USBFDO-"
      #define BASE_SYMBOLIC_LINK_NAME           L"\\DosDevices\\HCD"
      
      #define DeviceNameSize                    sizeof(BASE_DEVICE_NAME)+MAX_SUFFIX_SIZE
      #define SymLinkNameSize                   sizeof(BASE_SYMBOLIC_LINK_NAME)+MAX_SUFFIX_SIZE
      
      NTSTATUS
      Controller_WdfEvtDeviceAdd(
          _In_
              WDFDRIVER Driver,
          _Inout_
              PWDFDEVICE_INIT WdfDeviceInit
          )
      {
          NTSTATUS                            status;
          WDFDEVICE                           wdfDevice;
          WDF_PNPPOWER_EVENT_CALLBACKS        wdfPnpPowerCallbacks;
          WDF_OBJECT_ATTRIBUTES               wdfDeviceAttributes;
          WDF_OBJECT_ATTRIBUTES               wdfRequestAttributes;
          UDECX_WDF_DEVICE_CONFIG             controllerConfig;
          WDF_FILEOBJECT_CONFIG               fileConfig;
          PWDFDEVICE_CONTEXT                  pControllerContext;
          WDF_IO_QUEUE_CONFIG                 defaultQueueConfig;
          WDF_DEVICE_POWER_POLICY_IDLE_SETTINGS
                                              idleSettings;
          UNICODE_STRING                      refString;
          ULONG instanceNumber;
          BOOLEAN isCreated;
      
          DECLARE_UNICODE_STRING_SIZE(uniDeviceName, DeviceNameSize);
          DECLARE_UNICODE_STRING_SIZE(uniSymLinkName, SymLinkNameSize);
      
          UNREFERENCED_PARAMETER(Driver);
      
          ...
      
          WdfDeviceInitSetPnpPowerEventCallbacks(WdfDeviceInit, &wdfPnpPowerCallbacks);
      
          WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&wdfRequestAttributes, REQUEST_CONTEXT);
          WdfDeviceInitSetRequestAttributes(WdfDeviceInit, &wdfRequestAttributes);
      
      // To distinguish I/O sent to GUID_DEVINTERFACE_USB_HOST_CONTROLLER, we will enable
      // enable interface reference strings by calling WdfDeviceInitSetFileObjectConfig
      // with FileObjectClass WdfFileObjectWdfXxx.
      
      WDF_FILEOBJECT_CONFIG_INIT(&fileConfig,
                                  WDF_NO_EVENT_CALLBACK,
                                  WDF_NO_EVENT_CALLBACK,
                                  WDF_NO_EVENT_CALLBACK // No cleanup callback function
                                  );
      
      ...
      
      WdfDeviceInitSetFileObjectConfig(WdfDeviceInit,
                                          &fileConfig,
                                          WDF_NO_OBJECT_ATTRIBUTES);
      
      ...
      
      // Do additional setup required for USB controllers.
      
      status = UdecxInitializeWdfDeviceInit(WdfDeviceInit);
      
      ...
      
      WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&wdfDeviceAttributes, WDFDEVICE_CONTEXT);
      wdfDeviceAttributes.EvtCleanupCallback = _ControllerWdfEvtCleanupCallback;
      
      // Call WdfDeviceCreate with a few extra compatibility steps to ensure this device looks
      // exactly like other USB host controllers.
      
      isCreated = FALSE;
      
      for (instanceNumber = 0; instanceNumber < ULONG_MAX; instanceNumber++) {
      
          status = RtlUnicodeStringPrintf(&uniDeviceName,
                                          L"%ws%d",
                                          BASE_DEVICE_NAME,
                                          instanceNumber);
      
          ...
      
          status = WdfDeviceInitAssignName(*WdfDeviceInit, &uniDeviceName);
      
          ...
      
          status = WdfDeviceCreate(WdfDeviceInit, WdfDeviceAttributes, WdfDevice);
      
          if (status == STATUS_OBJECT_NAME_COLLISION) {
      
              // This is expected to happen at least once when another USB host controller
              // already exists on the system.
      
          ...
      
          } else if (!NT_SUCCESS(status)) {
      
          ...
      
          } else {
      
              isCreated = TRUE;
              break;
          }
      }
      
      if (!isCreated) {
      
          ...
      }
      
      // Create the symbolic link (also for compatibility).
      status = RtlUnicodeStringPrintf(&uniSymLinkName,
                                      L"%ws%d",
                                      BASE_SYMBOLIC_LINK_NAME,
                                      instanceNumber);
      ...
      
      status = WdfDeviceCreateSymbolicLink(*WdfDevice, &uniSymLinkName);
      
      ...
      
      // Create the device interface.
      
      RtlInitUnicodeString(&refString,
                           USB_HOST_DEVINTERFACE_REF_STRING);
      
      status = WdfDeviceCreateDeviceInterface(wdfDevice,
                                              (LPGUID)&GUID_DEVINTERFACE_USB_HOST_CONTROLLER,
                                              &refString);
      
      ...
      
      UDECX_WDF_DEVICE_CONFIG_INIT(&controllerConfig, Controller_EvtUdecxWdfDeviceQueryUsbCapability);
      
      status = UdecxWdfDeviceAddUsbDeviceEmulation(wdfDevice,
                                                 &controllerConfig);
      
      // Create default queue. It only supports USB controller IOCTLs. (USB I/O will come through
      // in separate USB device queues.)
      // Shown later in this topic.
      
      WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&defaultQueueConfig, WdfIoQueueDispatchSequential);
      defaultQueueConfig.EvtIoDeviceControl = ControllerEvtIoDeviceControl;
      defaultQueueConfig.PowerManaged = WdfFalse;
      
      status = WdfIoQueueCreate(wdfDevice,
                                &defaultQueueConfig,
                                WDF_NO_OBJECT_ATTRIBUTES,
                                &pControllerContext->DefaultQueue);
      
      ...
      
      // Initialize virtual USB device software objects.
      // Shown later in this topic.
      
      status = Usb_Initialize(wdfDevice);
      
      ...
      
      exit:
      
          return status;
      }
      ```1.
      处理发送到主机控制器的用户模式 IOCTL 请求

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

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

      EVT_WDF_IO_QUEUE_IO_DEVICE_CONTROL        Controller_EvtIoDeviceControl;
      
      VOID
      Controller_EvtIoDeviceControl(
          _In_
              WDFQUEUE Queue,
          _In_
              WDFREQUEST Request,
          _In_
              size_t OutputBufferLength,
          _In_
              size_t InputBufferLength,
          _In_
              ULONG IoControlCode
      )
      {
          BOOLEAN handled;
          NTSTATUS status;
          UNREFERENCED_PARAMETER(OutputBufferLength);
          UNREFERENCED_PARAMETER(InputBufferLength);
      
          handled = UdecxWdfDeviceTryHandleUserIoctl(WdfIoQueueGetDevice(Queue),
                                                      Request);
      
          if (handled) {
      
              goto exit;
          }
      
          // Unexpected control code.
          // Fail the request.
      
          status = STATUS_INVALID_DEVICE_REQUEST;
      
          WdfRequestComplete(Request, status);
      
      exit:
      
          return;
      }
      报告主机控制器的功能

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

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

      NTSTATUS
      Controller_EvtControllerQueryUsbCapability(
          WDFDEVICE     UdeWdfDevice,
          PGUID         CapabilityType,
          ULONG         OutputBufferLength,
          PVOID         OutputBuffer,
          PULONG        ResultLength
      )
      
      {
          NTSTATUS status;
      
          UNREFERENCED_PARAMETER(UdeWdfDevice);
          UNREFERENCED_PARAMETER(OutputBufferLength);
          UNREFERENCED_PARAMETER(OutputBuffer);
      
          *ResultLength = 0;
      
          if (RtlCompareMemory(CapabilityType,
                               &GUID_USB_CAPABILITY_CHAINED_MDLS,
                               sizeof(GUID)) == sizeof(GUID)) {
      
              //
              // TODO: Is GUID_USB_CAPABILITY_CHAINED_MDLS supported?
              // If supported, status = STATUS_SUCCESS
              // Otherwise, status = STATUS_NOT_SUPPORTED
          }
      
          else {
      
              status = STATUS_NOT_IMPLEMENTED;
          }
      
          return status;
      }
      创建虚拟 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 设备为例进行声明:

      const UCHAR g_UsbDeviceDescriptor[] = {
          // Device Descriptor
          0x12, // Descriptor Size
          0x01, // Device Descriptor Type
          0x00, 0x03, // USB 3.0
          0x00, // Device class
          0x00, // Device sub-class
          0x00, // Device protocol
          0x09, // Maxpacket size for EP0 : 2^9
          0x5E, 0x04, // Vendor ID
          0x39, 0x00, // Product ID
          0x00, // LSB of firmware version
          0x03, // MSB of firmware version
          0x01, // Manufacture string index
          0x03, // Product string index
          0x00, // Serial number string index
          0x01 // Number of configurations
      };

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

      NTSTATUS
      Usb_Initialize(
          _In_
              WDFDEVICE WdfDevice
          )
      {
          NTSTATUS                                status;
          PUSB_CONTEXT                            usbContext;    //Client driver declared context for the host controller object
          PUDECX_USBDEVICE_CONTEXT                deviceContext; //Client driver declared context for the UDE device object
          UDECX_USB_DEVICE_STATE_CHANGE_CALLBACKS callbacks;
          WDF_OBJECT_ATTRIBUTES                   attributes;
      
          UDECX_USB_DEVICE_PLUG_IN_OPTIONS        pluginOptions;
      
          usbContext = WdfDeviceGetUsbContext(WdfDevice);
      
          usbContext->UdecxUsbDeviceInit = UdecxUsbDeviceInitAllocate(WdfDevice);
      
          if (usbContext->UdecxUsbDeviceInit == NULL) {
      
              ...
              goto exit;
          }
      
          // State changed callbacks
      
          UDECX_USB_DEVICE_CALLBACKS_INIT(&callbacks);
      #ifndef SIMPLEENDPOINTS
          callbacks.EvtUsbDeviceDefaultEndpointAdd = UsbDevice_EvtUsbDeviceDefaultEndpointAdd;
          callbacks.EvtUsbDeviceEndpointAdd = UsbDevice_EvtUsbDeviceEndpointAdd;
          callbacks.EvtUsbDeviceEndpointsConfigure = UsbDevice_EvtUsbDeviceEndpointsConfigure;
      #endif
          callbacks.EvtUsbDeviceLinkPowerEntry = UsbDevice_EvtUsbDeviceLinkPowerEntry;
          callbacks.EvtUsbDeviceLinkPowerExit = UsbDevice_EvtUsbDeviceLinkPowerExit;
          callbacks.EvtUsbDeviceSetFunctionSuspendAndWake = UsbDevice_EvtUsbDeviceSetFunctionSuspendAndWake;
      
          UdecxUsbDeviceInitSetStateChangeCallbacks(usbContext->UdecxUsbDeviceInit, &callbacks);
      
          // Set required attributes.
      
          UdecxUsbDeviceInitSetSpeed(usbContext->UdecxUsbDeviceInit, UdecxUsbLowSpeed);
      
      #ifdef SIMPLEENDPOINTS
          UdecxUsbDeviceInitSetEndpointsType(usbContext->UdecxUsbDeviceInit, UdecxEndpointTypeSimple);
      #else
          UdecxUsbDeviceInitSetEndpointsType(usbContext->UdecxUsbDeviceInit, UdecxEndpointTypeDynamic);
      #endif
      
          // Add device descriptor
          //
          status = UdecxUsbDeviceInitAddDescriptor(usbContext->UdecxUsbDeviceInit,
                                                 (PUCHAR)g_UsbDeviceDescriptor,
                                                 sizeof(g_UsbDeviceDescriptor));
      
          if (!NT_SUCCESS(status)) {
      
              goto exit;
          }
      
      #ifdef USB30
      
          // Add BOS descriptor for a SuperSpeed device
      
          status = UdecxUsbDeviceInitAddDescriptor(pUsbContext->UdecxUsbDeviceInit,
                                                 (PUCHAR)g_UsbBOSDescriptor,
                                                 sizeof(g_UsbBOSDescriptor));
      
          if (!NT_SUCCESS(status)) {
      
              goto exit;
          }
      #endif
      
          // String descriptors
      
          status = UdecxUsbDeviceInitAddDescriptorWithIndex(usbContext->UdecxUsbDeviceInit,
                                                          (PUCHAR)g_LanguageDescriptor,
                                                          sizeof(g_LanguageDescriptor),
                                                          0);
      
          if (!NT_SUCCESS(status)) {
      
              goto exit;
          }
      
          status = UdecxUsbDeviceInitAddStringDescriptor(usbContext->UdecxUsbDeviceInit,
                                                       &g_ManufacturerStringEnUs,
                                                       g_ManufacturerIndex,
                                                       US_ENGLISH);
      
          if (!NT_SUCCESS(status)) {
      
              goto exit;
          }
      
          WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, UDECX_USBDEVICE_CONTEXT);
      
          status = UdecxUsbDeviceCreate(&usbContext->UdecxUsbDeviceInit,
                                      &attributes,
                                      &usbContext->UdecxUsbDevice);
      
          if (!NT_SUCCESS(status)) {
      
              goto exit;
          }
      
      #ifdef SIMPLEENDPOINTS
         // Create the default control endpoint
         // Shown later in this topic.
      
          status = UsbCreateControlEndpoint(WdfDevice);
      
          if (!NT_SUCCESS(status)) {
      
              goto exit;
          }
      
      #endif
      
          UDECX_USB_DEVICE_PLUG_IN_OPTIONS_INIT(&pluginOptions);
      #ifdef USB30
          pluginOptions.Usb30PortNumber = 2;
      #else
          pluginOptions.Usb20PortNumber = 1;
      #endif
          status = UdecxUsbDevicePlugIn(usbContext->UdecxUsbDevice, &pluginOptions);
      
      exit:
      
          if (!NT_SUCCESS(status)) {
      
              UdecxUsbDeviceInitFree(usbContext->UdecxUsbDeviceInit);
              usbContext->UdecxUsbDeviceInit = NULL;
      
          }
      
          return status;
      }
      版权声明:本文内容来自第三方投稿或授权转载,原文地址:https://blog.csdn.net/m0_72813396/article/details/140095993,作者:sului,版权归原作者所有。本网站转在其作品的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如因作品内容、版权等问题需要同本网站联系,请发邮件至ctyunbbs@chinatelecom.cn沟通。

      上一篇:windows USB 设备驱动开发-开发Type C接口的驱动程序(一)

      下一篇:windows USB 设备驱动开发- 不同模型下的控制传输

      相关文章

      2025-03-17 07:50:46

      【源码分析】chunjun实现flink sql连接器的顶层思想:通过实现InputFormatSourceFunction来串起flink sql 连接器的生命周期

      【源码分析】chunjun实现flink sql连接器的顶层思想:通过实现InputFormatSourceFunction来串起flink sql 连接器的生命周期

      2025-03-17 07:50:46
      实现 , 数据 , 数据源 , 连接器
      2025-03-11 09:34:32

      【Trino权威指南(第二版)】Trino的架构、trino架构组件、 trino连接器架构的细节、trino的查询执行模型

      【Trino权威指南(第二版)】Trino的架构、trino架构组件、 trino连接器架构的细节、trino的查询执行模型

      2025-03-11 09:34:32
      数据源 , 查询 , 节点 , 连接器
      2025-03-04 09:11:34

      C++中的锁是如何实现的?底层原理揭秘

      在多线程编程中,锁是确保线程同步的重要工具。C++提供了多种锁的实现方式,如互斥锁、自旋锁和读写锁。

      2025-03-04 09:11:34
      C++ , 实现 , 硬件 , 线程
      2025-02-21 08:56:43

      【Linux】Linux内核学习--- 学习中

      【Linux】Linux内核学习--- 学习中

      2025-02-21 08:56:43
      Linux , 内核 , 文件系统 , 模块 , 硬件 , 调度 , 进程
      2024-12-24 10:17:17

      【操作系统】详细介绍操作系统的基本概念

      【操作系统】详细介绍操作系统的基本概念

      2024-12-24 10:17:17
      接口 , 操作系统 , 用户 , 硬件 , 管理 , 计算机 , 软件
      2024-12-19 08:42:50

      HarmonyOS第11天学习笔记-HarmonyOS简介与定位

      HarmonyOS是华为开发的一款面向未来的全场景分布式智慧操作系统,旨在覆盖1+8+N全场景总端设备。该系统提出了基于同一套系统能力、适配多种终端形态的分布式理念,能够支持手机、平板、智能穿戴、智慧屏、车机等多种终端设备。在万物互联的时代背景下,HarmonyOS不仅整合了不同终端硬件能力,形成虚拟的超级终端,更通过跨设备信息流转,提升了设备的利用率和用户体验。

      2024-12-19 08:42:50
      HarmonyOS , 分布式 , 硬件 , 终端 , 设备
      2024-12-11 06:20:18

      浅谈Linux中的软锁定(soft lockup)和硬件监视器(watchdog)

      浅谈Linux中的软锁定(soft lockup)和硬件监视器(watchdog)

      2024-12-11 06:20:18
      内核 , 硬件 , 系统 , 锁定
      2024-11-04 09:33:34

      嵌入式优势到底在哪里?

      嵌入式优势到底在哪里?

      2024-11-04 09:33:34
      单片机 , 嵌入式 , 硬件
      2024-10-23 08:58:48

      嵌入式技术

      嵌入式技术

      2024-10-23 08:58:48
      嵌入式 , 操作系统 , 硬件
      2024-09-10 08:20:57

      WDF驱动开发-特定于KMDF的技术(一)

      这部分的技术是一些零散的记录知识点,它们主要是在WDF框架中特定于KMDF的部分。

      2024-09-10 08:20:57
      硬件 , 连接器 , 驱动开发
      查看更多
      推荐标签

      作者介绍

      天翼云小翼
      天翼云用户

      文章

      33561

      阅读量

      5221898

      查看更多

      最新文章

      【源码分析】chunjun实现flink sql连接器的顶层思想:通过实现InputFormatSourceFunction来串起flink sql 连接器的生命周期

      2025-03-17 07:50:46

      C++中的锁是如何实现的?底层原理揭秘

      2025-03-04 09:11:34

      WDF驱动开发-特定于KMDF的技术(一)

      2024-09-10 08:20:57

      windows USB 设备驱动开发- 驱动操作USB配置

      2024-09-10 08:20:57

      windows USB设备驱动开发-双角色驱动

      2024-09-10 08:20:57

      windows USB 设备驱动开发-USB描述符

      2024-09-10 08:20:57

      查看更多

      热门文章

      C/C++ 获取系统IP地址/硬件信息等

      2023-07-20 06:05:57

      驱动开发:内核CR3切换读写内存

      2023-05-04 09:00:09

      驱动开发:内核读取SSDT表基址

      2023-05-04 09:00:09

      用MicroPython进行硬件编程

      2024-04-17 08:51:50

      windows USB 设备驱动开发-USB 功能控制器驱动开发(一)

      2024-09-10 08:20:45

      windows USB设备驱动开发-双角色驱动

      2024-09-10 08:20:57

      查看更多

      热门标签

      java Java python 编程开发 代码 开发语言 算法 线程 Python html 数组 C++ 元素 javascript c++
      查看更多

      相关产品

      弹性云主机

      随时自助获取、弹性伸缩的云服务器资源

      天翼云电脑(公众版)

      便捷、安全、高效的云电脑服务

      对象存储

      高品质、低成本的云上存储服务

      云硬盘

      为云上计算资源提供持久性块存储

      查看更多

      随机文章

      windows USB 设备驱动开发- 排查未知 USB 设备的问题

      windows USB设备驱动开发通用技术

      用MicroPython进行硬件编程

      windows USB 设备驱动开发-USB复合设备的注册

      windows USB 设备驱动开发- 不同模型下的控制传输

      windows USB 设备驱动开发-USB电源管理(一)

      • 7*24小时售后
      • 无忧退款
      • 免费备案
      • 专家服务
      售前咨询热线
      400-810-9889转1
      关注天翼云
      • 旗舰店
      • 天翼云APP
      • 天翼云微信公众号
      服务与支持
      • 备案中心
      • 售前咨询
      • 智能客服
      • 自助服务
      • 工单管理
      • 客户公告
      • 涉诈举报
      账户管理
      • 管理中心
      • 订单管理
      • 余额管理
      • 发票管理
      • 充值汇款
      • 续费管理
      快速入口
      • 天翼云旗舰店
      • 文档中心
      • 最新活动
      • 免费试用
      • 信任中心
      • 天翼云学堂
      云网生态
      • 甄选商城
      • 渠道合作
      • 云市场合作
      了解天翼云
      • 关于天翼云
      • 天翼云APP
      • 服务案例
      • 新闻资讯
      • 联系我们
      热门产品
      • 云电脑
      • 弹性云主机
      • 云电脑政企版
      • 天翼云手机
      • 云数据库
      • 对象存储
      • 云硬盘
      • Web应用防火墙
      • 服务器安全卫士
      • CDN加速
      热门推荐
      • 云服务备份
      • 边缘安全加速平台
      • 全站加速
      • 安全加速
      • 云服务器
      • 云主机
      • 智能边缘云
      • 应用编排服务
      • 微服务引擎
      • 共享流量包
      更多推荐
      • web应用防火墙
      • 密钥管理
      • 等保咨询
      • 安全专区
      • 应用运维管理
      • 云日志服务
      • 文档数据库服务
      • 云搜索服务
      • 数据湖探索
      • 数据仓库服务
      友情链接
      • 中国电信集团
      • 189邮箱
      • 天翼企业云盘
      • 天翼云盘
      ©2025 天翼云科技有限公司版权所有 增值电信业务经营许可证A2.B1.B2-20090001
      公司地址:北京市东城区青龙胡同甲1号、3号2幢2层205-32室
      • 用户协议
      • 隐私政策
      • 个人信息保护
      • 法律声明
      备案 京公网安备11010802043424号 京ICP备 2021034386号