设备和适配器初始化
本主题介绍 NetAdapterCx 客户端驱动程序初始化和启动 WDFDEVICE 和 NETADAPTER 对象的步骤。 有关这些对象及其关系的详细信息,请参阅 NetAdapterCx 对象的摘要。
EVT_WDF_DRIVER_DEVICE_ADD
NetAdapterCx 客户端驱动程序在从其 DriverEntry 例程调用 WdfDriverCreate 时注册其EVT_WDF_DRIVER_DEVICE_ADD回调函数。
在 EVT_WDF_DRIVER_DEVICE_ADD 中,NetAdapterCx 客户端驱动程序应按顺序执行以下操作:
-
status = NetDeviceInitConfig(DeviceInit); if (!NT_SUCCESS(status)) { return status; }
调用 WdfDeviceCreate。
提示
如果设备支持多个 NETADAPTER,我们建议在设备上下文中存储指向每个适配器的指针。
创建 NETADAPTER 对象。 为此,客户端调用 NetAdapterInitAllocate,然后调用可选的 NetAdapterInitSetXxx 方法,以初始化适配器的属性。 最后,客户端调用 NetAdapterCreate。
以下示例演示客户端驱动程序如何初始化 NETADAPTER 对象。 请注意,此示例中简化了错误处理。
WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attribs, MY_ADAPTER_CONTEXT); // // Allocate the initialization structure // PNETADAPTER_INIT adapterInit = NetAdapterInitAllocate(device); if(adapterInit == NULL) { return status; } // // Optional: set additional attributes // // Datapath callbacks for creating packet queues NET_ADAPTER_DATAPATH_CALLBACKS datapathCallbacks; NET_ADAPTER_DATAPATH_CALLBACKS_INIT(&datapathCallbacks, MyEvtAdapterCreateTxQueue, MyEvtAdapterCreateRxQueue); NetAdapterInitSetDatapathCallbacks(adapterInit, datapathCallbacks); // // Required: create the adapter // NETADAPTER* netAdapter; status = NetAdapterCreate(adapterInit, &attribs, netAdapter); if(!NT_SUCCESS(status)) { NetAdapterInitFree(adapterInit); adapterInit = NULL; return status; } // // Required: free the adapter initialization object even // if adapter creation succeeds // NetAdapterInitFree(adapterInit); adapterInit = NULL; // // Optional: initialize the adapter's context // PMY_ADAPTER_CONTEXT adapterContext = GetMyAdapterContext(&netAdapter); ...
(可选)可以将上下文空间添加到 NETADAPTER 对象。 由于可以在任何 WDF 对象上设置上下文,因此可以为 WDFDEVICE 和 NETADAPTER 对象添加单独的上下文空间。 在步骤 3 的示例中,客户端将添加到 MY_ADAPTER_CONTEXT
NETADAPTER 对象。 有关详细信息,请参阅 框架对象上下文空间。
建议将设备相关的数据放入 WDFDEVICE 的上下文中,并将与网络相关的数据(如链接层地址)放入 NETADAPTER 上下文中。 如果要移植现有的 NDIS 6.x 驱动程序,则可能有一个 MiniportAdapterContext,它将与网络相关和设备相关的数据合并到单个数据结构中。 若要简化移植过程,只需将该整个结构转换为 WDFDEVICE 上下文,并使 NETADAPTER 的上下文成为指向 WDFDEVICE 上下文的小型结构。
可以选择为 NET_ADAPTER_DATAPATH_CALLBACKS_INIT 方法提供 2 个回调:
有关这些回调的实现中要提供的内容的详细信息,请参阅各个参考页。
EVT_WDF_DEVICE_PREPARE_HARDWARE
许多 NetAdapterCx 客户端驱动程序从其 EVT_WDF_DEVICE_PREPARE_HARDWARE 回调函数中启动其适配器, 移动宽带类扩展客户端驱动程序除外。 若要注册 EVT_WDF_DEVICE_PREPARE_HARDWARE 回调函数,NetAdapterCx 客户端驱动程序必须调用 WdfDeviceInitSetPnpPowerEventCallbacks。
在 EVT_WDF_DEVICE_PREPARE_HARDWARE 中,除了其他硬件准备任务外,客户端驱动程序还设置适配器的必需和可选功能。
NetAdapterCx 要求客户端驱动程序设置以下功能:
数据路径功能。 驱动程序调用 NetAdapterSetDataPathCapabilities 来设置这些功能。 有关详细信息,请参阅 网络数据缓冲区管理。
链接层功能。 驱动程序调用 NetAdapterSetLinkLayerCapabilities 来设置这些功能。
链接层最大传输单位 (MTU) 大小。 驱动程序调用 NetAdapterSetLinkLayerMtuSize 来设置 MTU 大小。
然后,驱动程序必须调用 NetAdapterStart 才能启动其适配器。
以下示例演示客户端驱动程序如何启动 NETADAPTER 对象。 请注意,为简洁明了起见,设置每个适配器功能方法所需的代码被遗漏,错误处理也得到了简化。
PMY_DEVICE_CONTEXT deviceContext = GetMyDeviceContext(device);
NETADAPTER netAdapter = deviceContext->NetAdapter;
PMY_ADAPTER_CONTEXT adapterContext = GetMyAdapterContext(netAdapter);
//
// Set required adapter capabilities
//
// Link layer capabilities
...
NetAdapterSetDatapathCapabilities(netAdapter,
&txCapabilities,
&rxCapabilities);
...
NetAdapterSetLinkLayerCapabilities(netAdapter,
&linkLayerCapabilities);
...
NetAdapterSetLinkLayerMtuSize(netAdapter,
MY_MAX_PACKET_SIZE - ETHERNET_HEADER_LENGTH);
//
// Set optional adapter capabilities
//
// Link layer capabilities
...
NetAdapterSetPermanentLinkLayerAddress(netAdapter,
&adapterContext->PermanentAddress);
...
NetAdapterSetCurrentLinkLayerAddress(netAdapter,
&adapterContext->CurrentAddress);
// Datapath capabilities
...
NetAdapterSetDatapathCapabilities(netAdapter,
&txCapabilities,
&rxCapabilities);
// Receive scaling capabilities
...
NetAdapterSetReceiveScalingCapabilities(netAdapter,
&receiveScalingCapabilities);
// Hardware offload capabilities
...
NetAdapterOffloadSetChecksumCapabilities(netAdapter,
&checksumCapabilities);
...
NetAdapterOffloadSetLsoCapabilities(netAdapter,
&lsoCapabilities);
...
NetAdapterOffloadSetRscCapabilities(netAdapter,
&rscCapabilities);
//
// Required: start the adapter
//
status = NetAdapterStart(netAdapter);
if(!NT_SUCCESS(status))
{
return status;
}
反馈
https://aka.ms/ContentUserFeedback。
即将发布:在整个 2024 年,我们将逐步淘汰作为内容反馈机制的“GitHub 问题”,并将其取代为新的反馈系统。 有关详细信息,请参阅:提交和查看相关反馈