用于创建适配器的事件回调
客户端驱动程序使用相同的事件回调创建工作站适配器和 WfdRole 适配器: EvtWifiDeviceCreateAdapter。
- 调用 WifiAdapterGetType 来确定适配器类型。
- 如果在创建适配器之前驱动程序需要从 NETADAPTER_INIT 对象查询适配器类型,请调用 WifiAdapterInitGetType。
- 调用 WifiAdapterGetPortId 确定端口 ID(用于消息命令)。
NTSTATUS EvtWifiDeviceCreateAdapter( WDFDEVICE Device, NETADAPTER_INIT* AdapterInit ) { NET_ADAPTER_DATAPATH_CALLBACKS datapathCallbacks; NET_ADAPTER_DATAPATH_CALLBACKS_INIT(&datapathCallbacks, EvtAdapterCreateTxQueue, EvtAdapterCreateRxQueue); NetAdapterInitSetDatapathCallbacks(AdapterInit, &datapathCallbacks); WDF_OBJECT_ATTRIBUTES adapterAttributes; WDF_OBJECT_ATTRIBUTES_INIT(&adapterAttributes); WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&adapterAttributes, WIFI_NETADAPTER_CONTEXT); adapterAttributes.EvtCleanupCallback = EvtAdapterContextCleanup; NETADAPTER netAdapter; NTSTATUS ntStatus = NetAdapterCreate(AdapterInit, &adapterAttributes, &netAdapter); if (!NT_SUCCESS(ntStatus)) { TraceEvents(TRACE_LEVEL_ERROR, DBG_DEVICE, "%!FUNC!: NetAdapterCreate failed, status=0x%x\n", ntStatus); return ntStatus; } ntStatus = WifiAdapterInitialize(netAdapter); if (!NT_SUCCESS(ntStatus)) { TraceEvents(TRACE_LEVEL_ERROR, DBG_DEVICE, "%!FUNC!: WifiAdapterInitialize failed with %!STATUS!\n", ntStatus); return ntStatus; } ntStatus = ClientDriverInitDataAdapterContext( Device, netAdapter, WifiAdapterGetType(netAdapter) == WIFI_ADAPTER_EXTENSIBLE_STATION ? EXTSTA_PORT : EXT_P2P_ROLE_PORT, WifiAdapterGetPortId(netAdapter)); if (!NT_SUCCESS(ntStatus)) { TraceEvents(TRACE_LEVEL_ERROR, DBG_DEVICE, "%!FUNC!: ClientDriverInitDataAdapterContext failed with %!STATUS!\n", ntStatus); return ntStatus; } ntStatus = ClientDriverNetAdapterStart(netAdapter); if (!NT_SUCCESS(ntStatus)) { TraceEvents(TRACE_LEVEL_ERROR, DBG_DEVICE, "%!FUNC!: ClientDriverNetAdapterStart failed with %!STATUS!\n", ntStatus); return ntStatus; } return ntStatus; }该函数是 WiFiCx 客户端驱动程序中用于创建默认网络适配器(通常对应基础站模式)的核心回调,由 WiFiCx 框架在硬件准备完成后调用。其执行流程可概括为六个步骤,依次完成数据路径配置、适配器对象创建、WiFiCx 上下文初始化、客户端自定义设置以及适配器启动。
- 函数初始化一个用于注册数据路径回调的结构体,并指定发送队列和接收队列的创建函数,然后将其设置到适配器初始化对象中。这一步的作用是告诉 NetAdapterCx 框架,当需要为网络数据收发创建队列时,应调用哪些驱动提供的回调。
- 函数准备适配器对象的属性,为适配器关联一个自定义的上下文结构(用于存储驱动私有数据),并注册一个清理回调以便在适配器销毁时释放资源。随后调用 NetAdapterCx 的创建函数,生成底层的 NETADAPTER 对象,该对象代表一个网络接口。
- 创建成功后,函数调用 WiFiCx 提供的初始化函数,将新生成的 NETADAPTER 对象与 WiFiCx 框架绑定,完成 Wi-Fi 专用的上下文初始化,使得该适配器能够支持 WDI 命令处理。
- 函数进入客户端自定义阶段。它会根据适配器的类型(是基础站还是 Wi-Fi Direct 角色)以及端口 ID,调用驱动程序自定义的初始化上下文函数。在此过程中,它使用 WiFiCx 的辅助函数来获取适配器类型和端口号,以便正确配置驱动内部的端口数据结构。
- 函数调用驱动程序自定义的启动函数。该函数通常会执行必要的硬件准备或状态同步,并最终调用 NetAdapterCx 的标准启动例程,使适配器进入活动状态。
- 一旦启动成功,WiFiCx 框架便会向设备下发初始配置和无线电状态设置等命令。
整个函数将 WDF 的对象管理、NetAdapterCx 的数据路径创建,以及 WiFiCx 的 Wi-Fi 控制功能有机地结合在一起,是驱动从初始化阶段过渡到正常运行阶段的关键桥梁。每一步都有明确的失败处理,如果任何调用失败,函数会记录错误并立即返回,避免继续执行无效操作。