将 NDIS 微型端口驱动程序移植到 NetAdapterCx

本页介绍如何将 NDIS 6.x 微型端口驱动程序转换为 NetAdapterCx 客户端驱动程序。

有关 WDF 的一般信息,请查看 WDF 驱动程序开发指南

编译设置

在 Visual Studio 中打开现有的 NDIS 微型端口驱动程序项目,并使用以下步骤将其转换为 KMDF 项目。

  1. 首先,导航到 “配置属性->驱动程序设置->驱动程序模型 ”,并验证 驱动程序类型 是否设置为 KMDF,以及 KMDF 版本主要 版本和 KMDF 版本次要版本 均为空。

  2. 在项目属性中,打开 “驱动程序设置->网络适配器驱动程序” ,并将 “链接到网络适配器类扩展” 设置为 “是”。

    • 如果转换后的驱动程序仍会调用 NDIS API,请继续链接到 。ndis.lib
  3. 删除 NDIS 预处理器宏,如 NDIS650_MINIPORT=1

  4. 将以下标头添加到每个源文件 (或常见/预编译标头) :

    #include <ntddk.h>
    #include <wdf.h>
    #include <netadaptercx.h>
    
  5. 标准 WDF 修饰 添加到 INF:

    [Yourdriver.Wdf]
    KmdfService = Yourdriverservice, Yourdriver.wdfsect
    
    [Yourdriver.wdfsect]
    KmdfLibraryVersion = <insert here>
    
  6. 将新的所需网络关键字添加到 INF 的 NT 部分:

驱动程序初始化

DriverEntry 中删除对 NdisMRegisterMiniportDriver 的调用,并添加以下内容:

WDF_DRIVER_CONFIG_INIT(&config, EvtDriverDeviceAdd);
status = WdfDriverCreate(. . . );
if (!NT_SUCCESS(status)) {
  return status;
}

如果已设置,请从调用 WdfDriverCreate 中删除 WdfDriverInitNoDispatchOverride 标志。

DriverUnload 是 WDF 网络客户端驱动程序的可选例程,因此可以根据需要将其删除。 不要从 DriverUnload 调用 NdisMDeregisterMiniportDriver

设备初始化

接下来,你将将 MiniportInitializeEx 中的代码分发到相应的 WDF 事件回调处理程序中,其中一些是可选的。 有关回调序列的详细信息,请参阅 网络适配器 WDF 客户端驱动程序的电源启动序列

在启动 net 适配器时,但在调用 NetAdapterStart 之前,你将调用等效于 NdisMSetMiniportAttributes 的方法。 但是,客户端驱动程序调用不同的函数来设置不同类型的功能,而不是使用泛 型NDIS_MINIPORT_ADAPTER_ATTRIBUTES 结构调用一个例程。

有关需要提供的回调以及何时启动 Net 适配器的信息,请参阅 设备和适配器初始化

从注册表读取配置

接下来,将对 NdisOpenConfigurationEx 和相关函数的调用替换为 NetConfiguration* 方法。 方法 NetConfiguration* 类似于 Ndis*Configuration* 函数,无需重新构造代码。

有关详细信息,请参阅 访问配置信息

从用户模式) 接收 I/O 控制代码 (IOCTL

如果 NDIS 驱动程序调用 NdisRegisterDeviceEx(一个用于创建控制设备对象的例程), (CDO) 从用户模式接收 IOCTL,请阅读本部分。

下面是在 WDF 网络客户端驱动程序中执行此操作的两种方法。

最简单的端口是通过从客户端EVT_WDF_DRIVER_DEVICE_ADD回调调用WdfControlDeviceInitAllocate 来创建控制设备对象。 有关详细信息,请参阅 使用控制设备对象

但是,建议的解决方案是创建设备接口,如 使用设备接口中所述。

完成设备初始化

此时 ,在 EVT_WDF_DRIVER_DEVICE_ADD 中,你可以执行任何要初始化设备的其他操作,例如分配中断。

处理电源状态更改通知

WDF 客户端驱动程序不会收到电源状态更改 OID_PNP_SET_POWER

相反,WDF 客户端会注册可选的回调函数来接收电源状态更改通知。 有关概述,请参阅 在函数驱动程序中支持 PnP 和电源管理

通常, OID_PNP_SET_POWER 处理程序中的代码将移动到 EVT_WDF_DEVICE_D0_EXITEVT_WDF_DEVICE_D0_ENTRY

由于 WDF 电源状态机略有不同,因此可能需要对代码进行细微修改。

具体而言,在其 MiniportInitializeEx 回调函数中,NDIS 微型端口驱动程序执行一次性初始化任务以及使设备进入 D0 状态的工作。 然后,它会重复工作以转到其 OID_PNP_SET_POWER 处理程序中的 D0。

相比之下,WDF 客户端在 EVT_WDF_DEVICE_D0_ENTRY之前在事件回调中执行一次性初始化任务,在此期间设备处于低功耗状态。 然后,它会在 EVT_WDF_DEVICE_D0_ENTRY 中执行转到 D0 的工作。

总之,在 WDF 中,将“转到 D0”代码放在一个位置,而不是两个位置。

有关回调序列的详细信息,请参阅 NetAdapterCx 客户端驱动程序的 Power-Up 序列

查询和设置电源管理功能

同样,WDF 客户端驱动程序不会收到查询或设置网络适配器的电源管理硬件功能的 OID_PM_PARAMETERS

相反,驱动程序会从 NETPOWERSETTINGS 对象查询必要的 LAN 唤醒 (WoL) 配置。 有关详细信息,请参阅 配置电源管理

返回的实际标志具有与 NDIS 6 微型端口相同的语义,因此无需对逻辑进行深入更改。 main区别在于,现在可以在关机序列期间查询这些标志。 请参阅 NetAdapterCx 客户端驱动程序的关机序列

移动此代码后,可以删除 OID_PNP_SET_POWEROID_PM_PARAMETERS的 OID 处理程序。

由于 NetAdapter 框架在主机使用网络接口时将设备保持在 D0,因此客户端通常不实现电源逻辑;默认 NetAdapter 电源行为已足够。

数据路径

数据路径编程模型已发生重大更改。 下面是一些主要区别:

删除设备

WDF NIC 驱动程序的设备删除操作与任何其他 WDF 设备驱动程序相同,无需网络特定处理。 网络数据路径首先关闭,然后关闭 WDF 设备。 有关 WDF 关闭的信息,请参阅 用户拔出设备

MiniportHaltEx 处理程序可能分布在 EVT_WDF_DEVICE_D0_EXITEVT_WDF_DEVICE_RELEASE_HARDWARE 之间。

WDF 客户端不需要删除 NetAdapter 或其创建的任何数据路径队列。 WDF 会自动删除这些对象。

可以删除 MiniportShutdownExMiniportResetExMiniportCheckForHangEx。 不再支持这些回调。

NDIS-WDF 函数等效项

大多数 NdisXxx 函数都可以替换为 WDF 等效项。 一般情况下,应发现需要从 NDIS.SYS导入的很少功能。

有关函数等效项的列表,请参阅 NDIS-WDF 函数等效项

调试

请参阅 调试 NetAdapterCx 客户端驱动程序

!ndiskd.netadapter 调试器扩展显示的结果与 NDIS 6 驱动程序的 !ndiskd.miniport 显示的结果类似。

结论

使用本主题中的步骤,你应该有一个启动和停止设备的工作驱动程序。

注意:NetAdapterCx 当前不支持 iSCSI 启动。