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)在驱动程序加载时被调用,它接收两个参数:
DriverObject
:指向驱动对象的指针。驱动对象代表了驱动程序自身,并包含有关驱动程序的信息和功能。RegistryPath
:指向驱动程序在注册表中的路径的指针。这个路径可以用于在驱动程序中访问相关的配置信息。
在初始化函数中,可以执行以下任务:
- 注册驱动程序所提供的设备、文件系统、文件系统筛选器等。
- 初始化驱动程序特定的数据结构和全局变量。
- 设置驱动程序所支持的各种回调函数(如驱动程序的读取、写入、创建、关闭等操作的处理函数)。
- 进行任何其他必要的初始化操作。
需要注意的是,初始化函数应该返回一个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,则表示驱动程序对象创建成功。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?