驱动与应用程序的通信是非常有必要的,内核中执行代码后需要将其动态显示给应用层,但驱动程序与应用层毕竟不在一个地址空间内,为了实现内核与应用层数据交互则必须有通信的方法,微软为我们提供了三种通信方式,如下先来介绍通过ReadFile系列函数实现的通信模式 。
长话短说,不说没用的概念,首先系统中支持的通信模式可以总结为三种 。
- 缓冲区方式读写(DO_BUFFERED_IO)
- 直接方式读写(DO_DIRECT_IO)
- 其他方式读写
首先需要实现初始化各类派遣函数这么一个案例,如下代码则是通用的一种初始化派遣函数的基本框架,分别处理了IRP_MJ_CREATE创建派遣,以及IRP_MJ_CLOSE关闭的派遣,此外函数DriverDefaultHandle的作用时初始化其他派遣用的,也就是将除去CREATE/CLOSE这两个派遣之外,其他的全部赋值成初始值的意思,当然不增加此段代码也是无妨,并不影响代码的实际执行 。
#include <ntifs.h>// 卸载驱动执行VOID UnDriver(PDRIVER_OBJECT pDriver){ PDEVICE_OBJECT pDev; // 用来取得要删除设备对象 UNICODE_STRING SymLinkName; // 局部变量symLinkName pDev = pDriver->DeviceObject; IoDeleteDevice(pDev); // 调用IoDeleteDevice用于删除设备 RtlInitUnicodeString(&SymLinkName, L"\\??\\LySharkDriver"); // 初始化字符串将symLinkName定义成需要删除的符号链接名称 IoDeleteSymbolicLink(&SymLinkName); // 调用IoDeleteSymbolicLink删除符号链接 DbgPrint("驱动卸载完毕...");}// 创建设备连接// LyShark.comNTSTATUS CreateDriverObject(IN PDRIVER_OBJECT pDriver){ NTSTATUS Status; PDEVICE_OBJECT pDevObj; UNICODE_STRING DriverName; UNICODE_STRING SymLinkName; // 创建设备名称字符串 RtlInitUnicodeString(&DriverName, L"\\Device\\LySharkDriver"); Status = IoCreateDevice(pDriver, 0, &DriverName, FILE_DEVICE_UNKNOWN, 0, TRUE, &pDevObj); // 指定通信方式为缓冲区 pDevObj->Flags |= DO_BUFFERED_IO; // 创建符号链接 RtlInitUnicodeString(&SymLinkName, L"\\??\\LySharkDriver"); Status = IoCreateSymbolicLink(&SymLinkName, &DriverName); return STATUS_SUCCESS;}// 创建回调函数NTSTATUS DispatchCreate(PDEVICE_OBJECT pDevObj, PIRP pIrp){ pIrp->IoStatus.Status = STATUS_SUCCESS; // 返回成功 DbgPrint("派遣函数 IRP_MJ_CREATE 执行 \n"); IoCompleteRequest(pIrp, IO_NO_INCREMENT); // 指示完成此IRP return STATUS_SUCCESS; // 返回成功}// 关闭回调函数NTSTATUS DispatchClose(PDEVICE_OBJECT pDevObj, PIRP pIrp){ pIrp->IoStatus.Status = STATUS_SUCCESS; // 返回成功 DbgPrint("派遣函数 IRP_MJ_CLOSE 执行 \n"); IoCompleteRequest(pIrp, IO_NO_INCREMENT); // 指示完成此IRP return STATUS_SUCCESS; // 返回成功}// 默认派遣函数NTSTATUS DriverDefaultHandle(PDEVICE_OBJECT pDevObj, PIRP pIrp){ NTSTATUS status = STATUS_SUCCESS; pIrp->IoStatus.Status = status; pIrp->IoStatus.Information = 0; IoCompleteRequest(pIrp, IO_NO_INCREMENT); return status;}// 入口函数// By: LySharkNTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING RegistryPath){ DbgPrint("hello lyshark \n"); // 调用创建设备 CreateDriverObject(pDriver); pDriver->DriverUnload = UnDriver; // 卸载函数 pDriver->MajorFunction[IRP_MJ_CREATE] = DispatchCreate; // 创建派遣函数 pDriver->MajorFunction[IRP_MJ_CLOSE] = DispatchClose; // 关闭派遣函数 // 初始化其他派遣 for (ULONG i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++) {DbgPrint("初始化派遣: %d \n", i);pDriver->MajorFunction[i] = DriverDefaultHandle; } DbgPrint("驱动加载完成..."); return STATUS_SUCCESS;}
经验总结扩展阅读
- 用golang开发系统软件的一些细节
- 抖音团购套餐佣金抽成是多少
- 全国计算机等级考试通过率
- 狗狗靠什么辨认主人?
- 三十六 Java开发学习----SpringBoot三种配置文件解析
- aardio + Python 可视化快速开发桌面程序,一键生成独立 EXE
- 驱动精灵重装了驱动后无法开机
- 微粒贷在哪
- Windows esp-idf 安装
- 口袋妖怪火红版中如何走精灵塔