YJX_Driver_027_应用程序与驱动交互访问(缓冲模式)

1、

应用程序与驱动交互访问(缓冲模式)


数据交换原理
  A、用户层传入数据
  B、驱动层接收数据
  C、驱动层回传数据级用户层

 

【250】A、用户层传入数据EXE WriteFile,ReadFile

  【350】

BOOL DeviceIoControl
(
  HANDLE hDevice, // 设备句柄 调用CreateFile获取
  DWORD dwIoControlCode, // 操作执行的 控制码,用来区分不同的操作 是一个CTL_CODE宏
  LPVOID lpInBuffer, // 输入参数 指针
  DWORD nInBufferSize, // 输入参数大小(单位 字节)
  LPVOID lpOutBuffer, // 输出参数 指针
  DWORD nOutBufferSize, // 输出参数大小指针(单位 字节)
  LPDWORD lpBytesReturned, // 实际输出参数大小指针(单位 字节)
  LPOVERLAPPED lpOverlapped
  //调用 CreateFile 时 FILE_FLAG_OVERLAPPED 标志打开时才有效,否则会被忽略,所以这里用NULL
);

  【530】MSDN查看DeviceIoControl

  【1315】

DeviceIoControl使用示例:  exe

hDevice=CreatFile
DWORD add(HANDLE hDevice,int a,int b)
{
  int bufret;
  int port[2];
  port[0]=a;
  port[1]=b;
  DeviceIoControl(hDevice, add_code , &port, 8, &bufret, 4, &dwWrite, NULL);
  return bufret;
}

【1960】函数DeviceIoControl 的参数 dwIoControlCode,它有一个缩写

  【2345】网页搜索 CTL_CODE

 

【2395】

CTL_CODE宏 (用户层需要包含 winioctl.h头文件,http://msdn.microsoft.com/en-us/library/ms902086.aspx 这个地址CTL_CODE宏的详解介绍)


CTL_CODE( DeviceType, Function, Method, Access );
  //DeviceType 在SYS中用IOCreateDevice 创建的设备类型
  //Function 驱动程序中定义的IOCTL码 取值范围 0x800-0xFFF 其它值为系统保留
  //Method 访问方式 有4种 缓冲,直接,其它
  //Access 访问权限,这个一般用:FILE_ANY_ACCESS 这个常量 表示有所有权限
示例:
#define add_code CTL_CODE(\
  FILE_DEVICE_UNKNOWN, \ //DeviceType
  0x800, \ // Function 0x800-0xfff 2048-4095
  METHOD_BUFFERED, \ //Method
  FILE_ANY_ACCESS) //Acess

  【2410】宏CTL_CODE的参数 DeviceType: 设备类型.【2430】必须是与我们创建的设备对应的 (ZC: IoCreateDevice函数的DeviceType参数)

    【2460】打开 第24课 的代码,看一下我们创建的设备。(ZC: 他没有找到 创建设备的地方...)

    【2798】MSDN中 查看 IoCreateDevice(...)

      【2980】一般我们使用的是这个设备"FILE_DEVICE_UNKNOWN",于是 宏CTL_CODE 的第一个参数 也是 "FILE_DEVICE_UNKNOWN"

  【3050】宏CTL_CODE的参数 Function: 【3080】值的范围为(十进制):2048~4095(十六进制为0x800~0xFFF)。这是一个自定义的值

  【3670】宏CTL_CODE的参数 Method: 访问的模式

    【3710】4种访问方式:

      METHOD_BUFFERED

      METHOD_IN_DIRECT  直接访问内存的方式

      METHOD_OUT_DIRECT  直接访问内存的方式

      METHOD_NEITHER  其他的方式(不是上面3种,不是直接也不是缓冲区)

  【3810】宏CTL_CODE的参数 Access: FILE_ANY_ACCESS(读和写 都包括了)

 

 

【3955】

B、驱动层接收数据
当用户层调用了DeviceIoControl时就会产生一个IRP_MJ_DEVICE_CONTROL 事件传送到相应的驱动设备
  // 所以在驱动部分 必须先注册一个 IRP_MJ_DEVICE_CONTROL IRP处理函数
pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = myDriver_DeviceIOControl;
  // 在这个回调函数里 可以通过 pIrp来获取 用户层EXE 传进来的参数

 

NTSTATUS myDriver_DeviceIOControl(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp)
{
  NTSTATUS status = STATUS_SUCCESS;
  //由pIrp得到输入缓冲区指针(首地址)
  //由pIrp得到输出缓冲区大小
  //得到IOCTL码
  //取得传入参数
  //处理相送数据
  //回传数据 SSDT hook
  // C、驱动层回传数据给用户层
  //完成IRP处理
  //结束IRP请求
  return status;
}

  【4280】ZC: 这里,是注册的 驱动对象的 IRP_MJ_DEVICE_CONTROL回调函数,然而 跟 设备对象 没有任何关系。OS是把 通过 该驱动对象的所有设备对象(符号链接) 的IRP请求 都发到 驱动对象的回调函数中了,并没有 区分 某IRP 到底是属于哪个 设备对象(符号链接) ??【4325】NO,回调函数 第1个参数就是 设备对象,OS帮我们区分了不同的设备对象

  【4575】用户层地址 转换成 相应的内核地址(ZC: METHOD_BUFFERED这个事情不用操心,DIRECT 和 NEITHER 模式是怎么处理地址转换这个问题的?忘掉了...)

 

【4830】回顾大致的流程

 

2、

 



 

posted @ 2016-04-07 14:30  DebugSkill  阅读(227)  评论(0编辑  收藏  举报