Windows驱动开发之测试案例(二)

一、源码示例

根据官方教程,我们在VS2019中创建空的 KMDF 项目,并在其中创建 Driver.c 文件,编写代码如下:

复制代码
#include <ntddk.h>
#include <wdf.h>

DRIVER_INITIALIZE DriverEntry;
EVT_WDF_DRIVER_DEVICE_ADD KmdfHelloWorldEvtDeviceAdd;

NTSTATUS DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING  RegistryPath)
{
    NTSTATUS status = STATUS_SUCCESS;
    WDF_DRIVER_CONFIG config;

    KdPrintEx((DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "KMDFHelloWorld: DriverEntry\n"));
    WDF_DRIVER_CONFIG_INIT(&config, KmdfHelloWorldEvtDeviceAdd);

    status = WdfDriverCreate(DriverObject, RegistryPath, WDF_NO_OBJECT_ATTRIBUTES, &config, WDF_NO_HANDLE);

    return status;
}

NTSTATUS KmdfHelloWorldEvtDeviceAdd(_In_ WDFDRIVER Driver, _Inout_ PWDFDEVICE_INIT DeviceInit)
{
    UNREFERENCED_PARAMETER(Driver);
    NTSTATUS status;
    WDFDEVICE hDevice;

    KdPrintEx((DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "KMDFHelloWorld: KmdfHelloWorldEvtDeviceAdd\n"));

    status = WdfDeviceCreate(&DeviceInit, WDF_NO_OBJECT_ATTRIBUTES, &hDevice);

    return status;
}
复制代码

二、DRIVER_INITIALIZE

DRIVER_INITIALIZE 是一个Windows内核模式驱动程序的函数,它的作用是初始化驱动程序。当驱动程序被加载时,操作系统会调用驱动程序的入口点函数,这个入口点函数通常被命名为DriverEntry。在驱动程序的DriverEntry函数中,会调用 DRIVER_INITIALIZE 宏来定义初始化函数的原型。

DRIVER_INITIALIZE 宏定义的初始化函数原型如下:

NTSTATUS DriverEntry(
    _In_ PDRIVER_OBJECT  DriverObject,
    _In_ PUNICODE_STRING RegistryPath
);

初始化函数(DriverEntry)在驱动程序加载时被调用,它接收两个参数:

  1. DriverObject:指向驱动对象的指针。驱动对象代表了驱动程序自身,并包含有关驱动程序的信息和功能。
  2. RegistryPath:指向驱动程序在注册表中的路径的指针。这个路径可以用于在驱动程序中访问相关的配置信息。

在初始化函数中,可以执行以下任务:

  1. 注册驱动程序所提供的设备、文件系统、文件系统筛选器等。
  2. 初始化驱动程序特定的数据结构和全局变量。
  3. 设置驱动程序所支持的各种回调函数(如驱动程序的读取、写入、创建、关闭等操作的处理函数)。
  4. 进行任何其他必要的初始化操作。

需要注意的是,初始化函数应该返回一个NTSTATUS类型的值,用于指示初始化是否成功。通常情况下,可以返回STATUS_SUCCESS表示初始化成功,或者返回适当的错误代码来指示初始化失败。

总之,DRIVER_INITIALIZE 宏用于定义驱动程序的初始化函数,它在驱动程序加载时被调用,用于完成驱动程序的初始化和配置工作。

三、EVT_WDF_DRIVER_DEVICE_ADD

EVT_WDF_DRIVER_DEVICE_ADD是一个Windows驱动程序框架(WDF)中的回调函数类型,用于在驱动程序加载和初始化设备时执行特定的操作。下面是有关EVT_WDF_DRIVER_DEVICE_ADD的介绍和使用方法:
  1.介绍:
   a.EVT_WDF_DRIVER_DEVICE_ADD是WDF驱动程序对象的一个回调函数类型,用于在设备对象被添加到驱动程序时执行相关操作。
   b.通常,在设备对象被添加到驱动程序时,该回调函数会被调用,并提供一个WDFDEVICE句柄,可以用于操作和管理设备。
   c.EVT_WDF_DRIVER_DEVICE_ADD回调函数是驱动程序的一部分,在驱动程序入口函数(DriverEntry)中通过调用WdfDriverCreate函数注册。
  2.使用方法:
   a.在驱动程序的DriverEntry函数中,通过调用WdfDriverCreate函数注册EVT_WDF_DRIVER_DEVICE_ADD回调函数,以便在设备对象添加时调用。
   b.在EVT_WDF_DRIVER_DEVICE_ADD回调函数中,可以执行与设备初始化和配置相关的操作,例如创建设备接口、设置设备属性、注册中断处理程序等。
   c.通过使用WDFDEVICE句柄,可以访问设备对象并与其进行交互,例如配置设备资源、注册回调函数、创建并管理设备的I/O队列等。
   d.在EVT_WDF_DRIVER_DEVICE_ADD回调函数中,可以使用WDF提供的各种函数和方法来执行与设备相关的操作,如WdfDeviceCreate、WdfDeviceSetAlignmentRequirement、WdfDeviceConfigureRequestDispatching等。

  3.WDF_DRIVER_CONFIG

示例代码片段如下所示:

复制代码
NTSTATUS DriverEntry(
    _In_ PDRIVER_OBJECT DriverObject,
    _In_ PUNICODE_STRING RegistryPath
)
{
    // ...
    WDF_DRIVER_CONFIG config;
    WDF_DRIVER_CONFIG_INIT(&config, WDF_NO_EVENT_CALLBACK);

    config.EvtDriverDeviceAdd = MyDriverDeviceAdd; // 注册EVT_WDF_DRIVER_DEVICE_ADD回调函数

    return WdfDriverCreate(DriverObject, RegistryPath, WDF_NO_OBJECT_ATTRIBUTES, &config, WDF_NO_HANDLE);
}

NTSTATUS MyDriverDeviceAdd(
    _In_ WDFDRIVER Driver,
    _Inout_ PWDFDEVICE_INIT DeviceInit
)
{
    // 在设备添加时执行的操作

    WDFDEVICE device;
    NTSTATUS status;

    // 创建设备对象
    status = WdfDeviceCreate(&DeviceInit, WDF_NO_OBJECT_ATTRIBUTES, &device);
    if (!NT_SUCCESS(status)) {
        // 处理错误
        return status;
    }

    // 对设备进行初始化和配置

    return status;
}
复制代码

四、WDF_DRIVER_CONFIG

WDF_DRIVER_CONFIG是Windows驱动程序框架(WDF)中的结构体,用于配置和初始化驱动程序对象。下面是关于WDF_DRIVER_CONFIG的介绍和使用方法:

  1.介绍:
   a.WDF_DRIVER_CONFIG结构体用于指定驱动程序对象的配置信息,包括回调函数、驱动程序类型和其他选项。
   b.在驱动程序的DriverEntry函数中,通过填充WDF_DRIVER_CONFIG结构体并传递给WdfDriverCreate函数,来配置和创建驱动程序对象。
  2.使用方法:
   a.在驱动程序的DriverEntry函数中,创建一个WDF_DRIVER_CONFIG结构体实例,并使用WDF_DRIVER_CONFIG_INIT宏进行初始化。
   b.使用结构体实例的成员变量进行配置,例如设置回调函数、驱动程序类型和其他选项。
   c.调用WdfDriverCreate函数,传递驱动程序对象的DriverObject和RegistryPath,以及WDF_DRIVER_CONFIG结构体实例,来创建驱动程序对象。

示例代码片段如下所示:

复制代码
NTSTATUS DriverEntry(
    _In_ PDRIVER_OBJECT DriverObject,
    _In_ PUNICODE_STRING RegistryPath
)
{
    // ...
    WDF_DRIVER_CONFIG config;
    WDF_DRIVER_CONFIG_INIT(&config, WDF_NO_EVENT_CALLBACK);

    config.DriverInitFlags |= WdfDriverInitNonPnpDriver; // 设置驱动程序类型

    config.EvtDriverDeviceAdd = MyDriverDeviceAdd; // 设置设备添加回调函数

    return WdfDriverCreate(DriverObject, RegistryPath, WDF_NO_OBJECT_ATTRIBUTES, &config, WDF_NO_HANDLE);
}
复制代码

五、WDF_DRIVER_CONFIG_INIT

WDF_DRIVER_CONFIG_INIT是一个宏,用于初始化WDF_DRIVER_CONFIG结构体。它的作用是为WDF_DRIVER_CONFIG结构体的成员变量设置默认值,以便方便地进行进一步的配置和使用。

WDF_DRIVER_CONFIG是Windows驱动程序框架(WDF)中的一个结构体,用于指定驱动程序对象的配置信息。它包含了各种成员变量,例如回调函数指针、驱动程序类型、内存池标签等。在创建驱动程序对象之前,我们需要对WDF_DRIVER_CONFIG结构体进行适当的配置。

WDF_DRIVER_CONFIG_INIT宏的定义类似于以下形式:

#define WDF_DRIVER_CONFIG_INIT(_config, _evtDriverUnload) \
    { \
        (_config)->Size = sizeof(WDF_DRIVER_CONFIG); \
        (_config)->EvtDriverUnload = _evtDriverUnload; \
    }

宏接受两个参数:

  • _config:指向WDF_DRIVER_CONFIG结构体的指针,表示要初始化的结构体实例。
  • _evtDriverUnload:表示驱动程序卸载时调用的回调函数指针。

WDF_DRIVER_CONFIG_INIT宏会将传递的_config指针所指向的WDF_DRIVER_CONFIG结构体的Size成员设置为sizeof(WDF_DRIVER_CONFIG),以确保正确的结构体大小。同时,它会将EvtDriverUnload成员设置为传递的_evtDriverUnload参数,以指定驱动程序卸载时要调用的回调函数。通过使用WDF_DRIVER_CONFIG_INIT宏,可以简化对WDF_DRIVER_CONFIG结构体的初始化过程,并设置一些常用的默认值。在初始化之后,可以进一步配置WDF_DRIVER_CONFIG结构体的其他成员变量,以满足具体的驱动程序需求。

示例代码片段:

WDF_DRIVER_CONFIG config;
WDF_DRIVER_CONFIG_INIT(&config, EvtDriverUnloadCallback);

// 对config进行进一步的配置和设置

六、WdfDriverCreate函数

WdfDriverCreate函数是Windows驱动程序框架(WDF)中用于创建驱动程序对象的函数。

在驱动程序的头文件中声明WdfDriverCreate函数的原型,如下所示:

NTSTATUS WdfDriverCreate(
    _In_     PDRIVER_OBJECT            DriverObject,
    _In_     PCUNICODE_STRING          RegistryPath,
    _In_opt_ PWDF_OBJECT_ATTRIBUTES    DriverAttributes,
    _In_     PWDF_DRIVER_CONFIG        DriverConfig,
    _Out_opt_ WDFDRIVER*                Driver
);

dfDriverCreate函数的参数的详细说明:

  1.DriverObject:
    类型:PDRIVER_OBJECT
    描述:驱动程序的驱动对象指针。它通常是驱动程序的DriverEntry函数的第一个参数。
    使用:将驱动对象传递给WdfDriverCreate函数,使驱动程序对象与驱动对象关联。
  2.RegistryPath:
    类型:PCUNICODE_STRING
    描述:指向驱动程序的注册表路径的Unicode字符串指针。
    使用:将注册表路径传递给WdfDriverCreate函数,使驱动程序对象与注册表路径关联。
  3.DriverAttributes:
    类型:PWDF_OBJECT_ATTRIBUTES(可选)
    描述:指向WDF_OBJECT_ATTRIBUTES结构体的指针,用于指定驱动程序对象的属性。
    使用:可以使用WDF_OBJECT_ATTRIBUTES结构体来配置驱动程序对象的属性,例如内存池标签、上下文类型等。如果不需要设置属性,可以传递NULL或WDF_NO_OBJECT_ATTRIBUTES。
  4.DriverConfig:
    类型:PWDF_DRIVER_CONFIG
    描述:指向WDF_DRIVER_CONFIG结构体的指针,包含了驱动程序对象的配置信息。
    使用:在调用WdfDriverCreate之前,必须对WDF_DRIVER_CONFIG结构体进行适当的配置。可以使用WDF_DRIVER_CONFIG_INIT宏初始化结构体,并对其成员进行进一步的配置,例如设置回调函数、驱动程序类型等。
  5.Driver:
    类型:WDFDRIVER*(可选)
    描述:指向WDFDRIVER类型的指针,用于接收创建的驱动程序对象的句柄。
  使用:如果需要获取驱动程序对象的句柄,可以提供一个WDFDRIVER类型的指针变量的地址作为参数。如果不需要获取句柄,可以传递NULL或WDF_NO_HANDLE。

  返回值:
  类型:NTSTATUS
  描述:表示驱动程序对象的创建结果。如果返回值是NT_SUCCESS,则表示驱动程序对象创建成功。

posted @   TechNomad  阅读(1028)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示