3问题,麻烦高手路过时看看,拜托!

zhangyanli 2008-03-19 12:35:16
1.驱动程序可以使用下列三种不同的 I/O 方法之一:"缓冲"、"直接"或"两者都不"。
在“直接”方法中:
对于 IOCTL 请求,如果在 METHOD_IN_DIRECT 和 METHOD_OUT_DIRECT 中同时有一个输出缓冲区,则分配一个系统缓冲区(SystemBuffer 又有了地址)并将输入数据复制到其中。如果有一个输出缓冲区,且它被锁定,则会创建 MDL 并设置 MdlAddress。UserBuffer 字段没有任何含义。
在“缓冲”方法中:
对于读取请求,I/O 管理器分配一个与用户模式的缓冲区大小相同的系统缓冲区。IRP 中的 SystemBuffer 字段包含系统地址。UserBuffer 字段包含初始的用户缓冲区地址。当完成请求时,I/O 管理器将驱动程序已经提供的数据从系统缓冲区复制到用户缓冲区。对于写入请求,会分配一个系统缓冲区并将 SystemBuffer 设置为地址。用户缓冲区的内容会被复制到系统缓冲区,但是不设置 UserBuffer。对于 IOCTL 请求,会分配一个容量大小足以包含输入缓冲区或输出缓冲区的系统缓冲区,并将 SystemBuffer 设置为分配的缓冲区地址。输入缓冲区中的数据复制到系统缓冲区。UserBuffer 字段设置为用户模式输出缓冲区地址。内核模式驱动程序应当只使用系统缓冲区,且不应使用 UserBuffer 中存储的地址。

问题:其中的用户缓冲区,初始的用户缓冲区和系统缓冲区具体指什么,他们分别是谁操作的:I/O管理器还是驱动,很多资料上说他们之间的数据传递过程,但是说的我很晕?

2.UserBuffer(PVOID) 对于METHOD_NEITHER方式的IRP_MJ_DEVICE_CONTROL请求,该域包含输出缓冲区的用户模式虚拟地址。该域还用于保存读写请求缓冲区的用户模式虚拟地址,但指定了DO_BUFFERED_IO或DO_DIRECT_IO标志的驱动程序,其读写例程通常不需要访问这个域。当处理一个METHOD_NEITHER控制操作时,驱动程序能用这个地址创建自己的MDL
“但指定了DO_BUFFERED_IO或DO_DIRECT_IO标志的驱动程序,其读写例程通常不需要访问这个域。”和上面的“输入缓冲区中的数据复制到系统缓冲区。UserBuffer 字段设置为用户模式输出缓冲区地址。内核模式驱动程序应当只使用系统缓冲区,且不应使用 UserBuffer 中存储的地址。

问题:
这两句话都说驱动程序不需要访问他,为什么不需要,是不是因为这个域不由驱动程序控制,而是有I/O管理器来设置,比如读取时由I/O管理器来填充它。


3.UserBuffer :Contains the address of an output buffer if the major function code in the I/O stack location is IRP_MJ_DEVICE_CONTROL or IRP_MJ_INTERNAL_DEVICE_CONTROL and the I/O control code was defined with METHOD_NEITHER和这句话“当处理一个METHOD_NEITHER控制操作时,驱动程序能用这个地址(即UserBuffer)创建自己的MDL。

问题:
又怎么理解?又用这个地址创建自己的MDL?感觉很乱


...全文
105 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
cnzdgs 2008-03-20
  • 打赏
  • 举报
回复
驱动程序中的大部分东西需要自己编程摸索,DDK文档做得很差,基本都没有Example,See Also给的也很少,还有很多东西都不公开。有时候还需要去MS网站查MSDN,那里的资料相对全一些。
zhangyanli 2008-03-20
  • 打赏
  • 举报
回复
ddk里面讲的似乎很粗糙,看不出什么实质性的联系。

看来还是经验重要啊
cnzdgs 2008-03-20
  • 打赏
  • 举报
回复
理解基本正确。我不知道哪里有相关资料,我是依照DDK文档和编程经验按照自己的理解来解释的。
zhangyanli 2008-03-20
  • 打赏
  • 举报
回复
十年有些夸张,十天倒是极有可能
gming2003 2008-03-20
  • 打赏
  • 举报
回复
听君一席话,胜读十本书.
zhangyanli 2008-03-20
  • 打赏
  • 举报
回复
在别的资料上基本上只有一些基础知识,却没有关于这些东西的联系和过程的讲解,听您叙述,清晰了不少,您看看我的理解对吗?
1.MDL本质上用户缓冲区在系统地址空间中的映射,起个连接作用。
2.Direct I/0和METHOD_NEITHER的关于UserBuffer的区别,是D——I/O是有I/O管理器创建的MDL,而后者需驱动程序自己创建。
这样理解对吗?

对了,这些资料在哪里可以找到,给点指点啊
cnzdgs 2008-03-19
  • 打赏
  • 举报
回复
我按照我自己的理解说明一下。

首先要理解内存地址空间的概念,在32位Windows系统中,0x80000000之前是用户地址空间,之后是系统地址空间,应用程序只能使用用户地址空间的内存,驱动程序只能使用的系统地址空间的内存。x86的内存管理机制可以把一个物理内存页映射到任意虚拟地址(4KB边界)上,同一物理内存页可以映射到多个虚拟地址,内存映射由Windows系统的内存管理器来处理。

UserBuffer是由应用程序给出的用户地址空间内的地址,是小于0x80000000的,驱动程序不能直接使用,如要使用可以通过创建MDL把UserBuffer对应的物理内存页映射到系统地址空间,然后再使用。

SystemBuffer是I/O管理器提供给驱动程序的系统缓冲区,是大于0x80000000的,驱动程序可以直接使用。

当请求为Buffer I/O类型时,I/O管理器会先把UserBuffer中的数据复制到SystemBuffer,然后再调用驱动程序,驱动程序执行完后,I/O管理器再把SystemBuffer中的数据复制到UserBuffer。

当请求为Direct I/O类型时,I/O管理器会创建MDL来映射UserBuffer,驱动程序可以使用MdlAddress来获得UserBuffer对应的系统地址空间的虚拟地址。

当请求为METHOD_NEITHER的时候,I/O管理器没有对UserBuffer做任何处理,SystemBuffer和MdlAddress都是不可用的,驱动程序如要使用UserBuffer必须自己创建MDL。

2,640

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 硬件/系统
社区管理员
  • 硬件/系统社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧