驱动和应用层的三种通信方式

 作 者: sislcb
时 间: 2008-01-04,11:57
链 接: http://bbs.pediy.com/showthread.php?t=57666

驱动程序和客户应用程序经常需要进行数据交换,但我们知道驱动程序和客户应用程序可能不在同一个地址空间,因此操作系统必须解决两者之间的数据交换。
驱动层和应用层通信,主要是靠DeviceIoControl函数,下面是该函数的原型:
BOOL DeviceIoControl ( 
HANDLE hDevice, // 设备句柄 
DWORD dwIoControlCode, // IOCTL请求操作代码 
LPVOID lpInBuffer, // 输入缓冲区地址 
DWORD nInBufferSize, // 输入缓冲区大小 
LPVOID lpOutBuffer, // 输出缓冲区地址 
DWORD nOutBufferSize, // 输出缓冲区大小 
LPDWORD lpBytesReturned, // 存放返回字节数的指针 
LPOVERLAPPED lpOverlapped // 用于同步操作的Overlapped结构体指针 
);

dwIoControlCode
要进行操作的控制码。驱动程序可以通过CTL_CODE宏来组合定义一个控制码,并在IRP_MJ_DEVICE_CONTROL的实现中进行控制码的操作。在驱动层,irpStack->Parameters.DeviceIoControl.IoControlCode表示了这个控制码。

IOCTL请求有四种缓冲策略,下面一一介绍。 
1、 输入输出缓冲I/O(METHOD_BUFFERED)
2、 直接输入缓冲输出I/O(METHOD_IN_DIRECT)
3、 缓冲输入直接输出I/O(METHOD_OUT_DIRECT)
4、 上面三种方法都不是(METHOD_NEITHER)

为了对这些类型更详细的描述,请看msdn上的解释,我抄录如下:

"缓冲"方法(METHOD_BUFFERED)
备注:在下面的讨论中,"输入"表示数据从用户模式的应用程序到驱动程序,"输出"表示数据从驱动程序到应用程序。

对于读取请求,I/O 管理器分配一个与用户模式的缓冲区大小相同的系统缓冲区。IRP 中的 SystemBuffer 字段包含系统地址。UserBuffer 字段包含初始的用户缓冲区地址。当完成请求时,I/O 管理器将驱动程序已经提供的数据从系统缓冲区复制到用户缓冲区。对于写入请求,会分配一个系统缓冲区并将 SystemBuffer 设置为地址。用户缓冲区的内容会被复制到系统缓冲区,但是不设置 UserBuffer。对于 IOCTL 请求,会分配一个容量大小足以包含输入缓冲区或输出缓冲区的系统缓冲区,并将 SystemBuffer 设置为分配的缓冲区地址。输入缓冲区中的数据复制到系统缓冲区。UserBuffer 字段设置为用户模式输出缓冲区地址。内核模式驱动程序应当只使用系统缓冲区,且不应使用 UserBuffer 中存储的地址。

对于 IOCTL,驱动程序应当从系统缓冲区获取输入并将输出写入到系统缓冲区。当完成请求时,I/O 系统将输出数据从系统缓冲区复制到用户缓冲区。

"直接"方法(METHOD_IN/OUT_DIRECT)
对于读取和写入请求,用户模式缓冲区会被锁定,并且会创建一个内存描述符列
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值