aurain
技术文摘
posts - 137,  comments - 268,  trackbacks - 0

Windows 操作系统家族支持三种数据传输机制:

l         缓存IOBuffered I/O)在内核模式上操作对用户数据的拷贝

l         直接IODirect I/O)通过内存描述元列表(MDL, Memory Descriptor List)以及内核模式的指针直接访问用户数据

l         非上述方法IOMethod neither I/O,既非缓存,也非直接IO)通过用户模式的指针访问用户数据

对于标准的IO 请求,例如IRP_MJ_READ IRP_MJ_WRITE,由驱动在设备刚创建后,马上通过修改DeviceObject->Flags 域的值来指定支持那一种传输机制。

缓存IO

为了以缓存IO 的方式接收读、写的请求,驱动会在初始化时在DeviceObject->Flags 域上设置DO_BUFFERED_IO标志。当驱动收到了一个缓存IO 的请求,在特定的Irp->AssociatedIrp.SystemBuffer域中会放有驱动应该操作的内核模式缓冲区的地址。IO管理
器在进行读请求时将数据由内核模式缓冲区拷贝到用户模式缓冲区,或者在进行写请求时从用户模式缓冲区向内核模式缓冲区拷贝数据。
直接IO

为了以直接IO的方式接收读、写请求,驱动会在初始化时在DeviceObject->Flags 域上设置DO_DIRECT_IO标志。当驱动接收到一个直接IO请求,特定的Irp->MdlAddress域中会放有一个用来描述请求缓冲区的MDL 的地址。这个MDL 列出了缓冲区的虚拟地址和尺寸,连同相应缓冲区中的物理页表(physical pages)。IO 管理器会在将请求发送给驱动之前锁定这些物理页,并在(请求)完成的过程中解锁。驱动千万不能使用MDL 中列举的用户模式缓冲区地址,而必须通过调用MmGetSystemAddressForMdlSafe 宏来得到一个内核模式的地址。

非缓存非直接IO
为了接收非缓存非直接IO 的方式的请求,驱动初始化时在DeviceObject->Flags 域上既不设置DO_BUFFERED_IO 标志,也不设置DO_DIRECT_IO 标志。当驱动接收到这样的请求,相应的Irp->UserBuffer 域会放有附属于这个请求的数据地址。因为这个缓冲区在用户地址空间上,驱动程序必须在用之前使相应的地址合法化。驱动程序在try/except 块里调用ProbeForRead 或者ProbeForWrite 函数来合法化特定的指针。驱动还必须完全在try/except块里处理所有对这一缓冲区的访问。

另外,驱动还必须在应用(manipulating)数据之前将它拷贝到池(the pool)或堆栈里一个安全的内核模式地址。将数据拷贝到内核模式缓冲区确保了用户模式的调用者不会在驱动已经合法化数据之后再修改它。

posted on 2009-09-27 13:50 阅读(1474) 评论(0)  编辑 收藏 引用 所属分类: windows驱动

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理



<2009年4月>
2930311234
567891011
12131415161718
19202122232425
262728293012
3456789

常用链接

留言簿(17)

随笔分类(138)

随笔档案(137)

网络开发

最新随笔

搜索

  •  

积分与排名

  • 积分 - 488886
  • 排名 - 36

最新随笔

最新评论

阅读排行榜

评论排行榜