

码龄10年
暂无认证
34114访问
1
等级
8获赞
3
评论
热门文章
-
一.某岛之人物对象及其加密函数解析
2147
-
一.《传奇M》装备栏遍历的突破口
1789
-
二.某龙端游中LUA的分析和调用
1539
-
一.《轩辕传奇》周围遍历之二叉树
1385
-
一.《UE4奥丁》人物最大属性
1330
最新评论
-
20240228阿⑤
积分乍获得
-
20231124ziher
666
-
20230909八月老师
什麼時候發佈易語言支持庫呢
一.《驱动开发》缓冲区方式与IRP中的域的对应关系
admin
2023-08-19 11:09:10 发布
395
分类专栏: 文章标签:
缓冲区方式与IRP的关系如下:
1.在驱动层,依传输类型的不同,输入缓冲区的位置亦不同,见下表。
传输类型 位置
METHOD_IN_DIRECT irp->AssociatedIrp.SystemBuffer
METHOD_OUT_DIRECT irp->AssociatedIrp.SystemBuffer
METHOD_BUFFERED irp->AssociatedIrp.SystemBuffer
METHOD_NEITHER irpStack->Parameters.DeviceIoControl.Type3InputBuffer
2.在驱动层,依传输类型的不同,输出缓冲区的位置亦不同,见下表。
传输类型 位置
METHOD_IN_DIRECT irp->MdlAddress
METHOD_OUT_DIRECT irp->MdlAddress
METHOD_BUFFERED irp->AssociatedIrp.SystemBuffer
METHOD_NEITHER irp->UserBuffer
如何制定传输类型:
1.其实在我们定义传输代码的时候,定义宏的时候就在指定了
2.同学们注意这里,别忘记了
#define IOCTL_MOUSE \ CTL_CODE(FILE_DEVICE_UNKNOWN, 0x902, METHOD_IN_DIRECT, FILE_ANY_ACCESS) #define IOCTL_KB \ CTL_CODE(FILE_DEVICE_UNKNOWN, 0x903, METHOD_IN_DIRECT, FILE_ANY_ACCESS)
三种数据传输机制的区别:
Windows 操作系统家族支持三种数据传输机制:
1.缓存IO(Buffered I/O)在内核模式上操作对用户数据的拷贝
2.直接IO(Direct I/O)通过内存描述元列表(MDL, Memory Descriptor List)以及内核模式的指针直接访问用户数据
3.非上述方法IO(Method 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)或堆栈里一个安全的内核模式地址。
将数据拷贝到内核模式缓冲区确保了用户模式的调用者不会在驱动已经合法化数据之后再修改它。


评论列表