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、



 

posted @ 2016-04-08 10:53  DebugSkill  阅读(317)  评论(0编辑  收藏  举报