YJX_Driver_029_实战EXE和SYS通信(直接访问模式)
1、
应用程序与驱动交互访问(直接模式)
A、用户层传入数据EXE部分代码
B、驱动层接收数据并处理SYS部分代码
C、驱动层返回数据至用户层
D、用户层获得处理结果
E、预编译指令#pragma #ifndef #endif
ZC: 上节课 最后说 蓝屏的问题,这节课【3725】处
【190】都是在 第28课 的代码的基础上进行修改,复制过来
【260】缓冲区方式 和 直接方式 的区别
【305】区别1:
#define add_code CTL_CODE(
FILE_DEVICE_UNKNOWN,
0x800,
METHOD_IN_DIRECT,
FILE_ANY_ACCESS)
“
在讲直接内存访问模式时,我们不得不再次讲到CTL_CODE宏的Method项
CTL_CODE(DeviceType,Function,Method,Acess);
Method是指定数据传递的模式 有这几个值:
METHOD_BUFFERED //使用缓冲区方式操作 0
METHOD_IN_DIRECT //直接写方式 1
METHOD_OUT_DIRECT //直接读方式 2
METHOD_NEITHER //其它方式 3
直接内存操作方式METHOD_IN_DIRECT和METHOD_OUT_DIRECT模式都以相同方式处理。仅有的不同 是它们访问用户模式缓冲区时所需的访问权限;
METHOD_IN_DIRECT 需要读权限;
METHOD_OUT_DIRECT 既需要读权限又需要写权限。
使用这两种模式时,I/O管理器会
为 输入数据 提供一个内核模式拷贝缓冲区(AssociatedIrp.SystemBuffer),
为 输出数据缓冲区 提供一个MDL。
MdlAddress(PMDL)域指向一个内存描述符表(MDL),该表描述了一个与该请求关联的用户模式缓冲区。
当IRP_MJ_DEVICE_CONTROL请求的控制代码指定METHOD_IN_DIRECT或METHOD_OUT_DIRECT操作方式,则I/O管理器为该请求使用的输出缓冲区创建一个MDL。
MDL本身用于描述用户模式虚拟缓冲区,但它同时也含有该缓冲区锁定内存页的物理地址。
//获取 PIrp->MdlAddres 然后通过MmGetSystemAddressForMdlSafe将这段内存映身到内核模式下 供直接访问
int* OutBuffer =(int *)MmGetSystemAddressForMdlSafe(PIrp->MdlAddres, NormalPagePriority );
”
【1095】MSDN中 查看 MmGetSystemAddressForMdlSafe(...)
【1335】MmGetSystemAddressForMdlSafe 的第2个参数 MM_PAGE_PRIORITY
访问的优先权,可用的参数:LowPagePriority、NormalPagePriority、HighPagePriority,一般用 NormalPagePriority
【1640】修改代码
修改EXE部分
修改SYS部分
【1715】优化头文件,预编译指令,使之具有通用性
“
#ifndef CTL_CODE
#pragma message("\n\n------EXE模式 . Include winioctl.h")
#include<winioctl.h>
#else
#pragma message("\n\n------SYS模式 . No include winioctl.h")
#endif
”
【2030】驱动中 宏CTL_CODE 应该是在 ntddk.h或wmd.h 中定义的
【2130】“#pragma message(???)”可以打印编译时候的一个提示信息
【2370】VC6编译exe
【2380】看到信息“------EXE模式 . Include winioctl.h”在VC6的控制台被打印出来了
【2405】把头文件ctl_code.h复制到驱动项目里
【2455】vs2003编译sys
【2495】看到信息“------SYS模式 . No include winioctl.h”在vs2003的"输出"中被打印出来了
【2615】将 缓冲区访问模式 改为 直接访问模式
METHOD_BUFFERED 改为 METHOD_IN_DIRECT,同步sys、exe两边的ctl_code.h
ZC: 为何不用 METHOD_OUT_DIRECT?不需要输出缓冲?还是这样就可以使用输出信息?
【2770】驱动部分 改的地方只有一个地方
【2840】“int* OutputBuffer = (int*) pIrp->AssociatedIrp.SystemBuffer;”改为
“int* OutputBuffer =(int *)MmGetSystemAddressForMdlSafe(pIrp->MdlAddres, NormalPagePriority);”
【3220】将 exe和sys 复制到 虚拟机,测试一下
【3255】在虚拟机启动的时候,我们修改一下 打印的信息
【3720】测试OK。
ZC: 使用 METHOD_IN_DIRECT 照样可以返回信息,那相关的权限指的是什么?难道是指CreateFile时指定的权限吗?查资料 & 自己测试,待验证。
【3725】上一节课出现的蓝屏,其实是另外一个错误:
mini_ddk.sys 在运行中,它的一个备份“2mini_ddk.sys” 又被加载了,然后在 “2mini_ddk.sys”停止的时候,虚拟机蓝屏了。两个驱动有冲突,设备之间 符号链接名/设备名 之类 是相同的,所以说 会报一个错 蓝屏
ZC: 那这个蓝屏怎么避免呢?我想到的方式:判断 设备名/符号链接名 是否存在,若存在 则不再创建。“设备名/符号链接名 是否存在”这个怎么判断呢?(相关知识: 驱动间通信 应该用的就是 设备名/符号链接,用这个方式应该能判断 设备名/符号链接 是否存在)
【3860】留一个作业给大家
把减法 做出来
2、