rookie_cn
驱动牛犊
驱动牛犊
  • 注册日期2002-11-28
  • 最后登录2004-02-08
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:935回复:0

我和lu0关于handle在内核态和用户态转化问题的讨论,我还有不明白的,请各位高人赐教

楼主#
更多 发布于:2003-05-19 19:07
rookie_cn:
我在programming wdm 2nd上看到
> **********************************************************
> case IOCTL_REGISTER_EVENT:
> 。。。。。
>
> HANDLE hevent = *(PHANDLE) Irp->AssociatedIrp.SystemBuffer;
> PKEVENT pevent;
> if (hevent)
> status = ObReferenceObjectByHandle(hevent, EVENT_MODIFY_STATE,
*ExEventObjectType,
> Irp->RequestorMode, (PVOID*) &pevent, NULL);
> else
> pevent = NULL;
> ******************************************************
> hevent是用户态程序传过来的句柄,要是进程切换了,ObReferenceObjectByHandle
怎么可以用它来做参数?????

****************************************************
lu0:
KERNEL需要的是与进程无关的OBJECT地址. ObReferenceObjectByHandle就是干这个
事情的.
> 获得的地址是KERNEL地址空间的地址. 这样, 在其他进程中也能访问.

***********************
rookie_cn:
我认为ObReferenceObjectByHandle无非是在handle table找到handle,输出相对应
的pointer。但是要是driver得到运行的时候,cpu的进程已经改变了(driver 工作在
任意线程上下文,这种情况可能发生),handle table已经变了,你在handle table里
面找到的handle就不是ap的那个handle了,我说的对吗?

lu0:
错. 2G以上的地址空间是所有进程共享的.
获得的POINTER是2G以上的.
KERNEL OBJECT, 当然是从KERNEL PAGED/NON-PAGED POOL中分配内存得来的对象.
至于HANDLE, 则是在PEPROCESS中HANDLETABLE找一空闲地方存放这个值. 返回给USER
HANDLE TABLE的INDEX(其中还有其他一些运算).
HANDLE是PROCESS SPECIFIC的, 但是通过HANDLE获得的OBJECT都是到处可以用的. 否则
OS怎么同步2个进程共享1个OBJECT的状况.

rookie_cn:
ok,我知道event是内核对象,要是获得他的指针的话,我们是可以到处用
但是我谈的是handle,我的意思是ap获得的handle,作为数据直接发给driver使用,
要是dirver得到运行的时候,cpu处于与ap不同的进程上下文中(driver运行在任意线
程,这种情况是可能的),
这时候driver会在当前进程的handle table中找handle,而这时找到的handle并不是ap
指向的event的handle,这时
用ObReferenceObjectByHandle当然也是找不到正确的pointer

lu0:
在接收到IOCTL的时刻, 一定是和CALLER处于同一CONTEXT的.
目前没有哪个FILTER把不属于自己的IOCTL POST到其他THREAD来处理的. 如果有, 那个
FILTER就有BUG. 无法正常工作.

rookie_cn:
我想只能说当deviceIocontrol触发的IRP很快就能得到处理的时候,这时driver的上下
文是app的
但是假如deviceIocontrol刚执行完,该线程的时间片用完,而有一个不同进程的线程
获得了时间片,这时不是会导致进程的切换吗
此时driver附着的进程就和app的不同了,不是吗

lu0:
DRIVER运行的THREAD如果时间片结束, DRIVER被运行被切断, 切换到其他线程. 等到下
一此运行, CONTEXT仍然被切换回来.
我想恐怕没有时间过多解释. 你的状况不是COMPETION ROUTINE调用的状况. 请仔细查
看一下文档. 并且确认你的UPPER FILTER的工作模式.

rookie_cn:
“在接收到IOCTL的时刻, 一定是和CALLER处于同一CONTEXT的”,要是这句话正确的
话,direct Io方式还有存在的必要?
因为在同一个context下,用户态的虚拟地址可以直接被driver使用(neither方式不就
是在你确定是在同一个context的情况下,直接使用用户态的虚拟地址吗)

lu0:
DIRECTIO当然有必要存在. 因为确实有些东西DEVICE IO CONTROL是通过其他线程来处
理的.
例如FAT需要完成某些DISK IO操作. 而STACK不够, 会POST IRP到SYSTEM THREAD. 此时
, 就需要MDL来处理内存问题.
但是你当时的例子一定是处于同一CONTEXT下的. 甚至可以用NEITHER接口,直接使用
USER ADDRESS来优化.
上层的FILTER如果处理错误, 就会导致你无法正常工作. 这是上层FILTER的问题, 不是
当前驱动的问题. 另外, 此问题可能会引申为很大的一个话题, 我不再回答此问题. 请
谅解.




这是我请教lu0的邮件记录,我还有一些地方不太明白
我在看programing wdm的时候,书上说driver是工作在任意线程上下文的
我原来的理解是driver不依赖某一个进程而存在,当driver被call的时候,driver新开一个线程,此线程附着在当前进程上,此进程不一定是caller进程
从lu0的解释来看,我的理解好像是不对的,
1.那么什么叫任意线程上下文呢???
2.filter指的是上层filter driver吗?好像不是,那又是什么呢?

另外,不知道为什么,我无法回复帖子!!!


[编辑 -  5/19/03 by  rookie_cn]
rookie_cn:相信我,我会让你成为世界上第2幸福的人 girl:那谁是第一幸福的人 rookie_cn:拥有了你,还有谁比我幸福
游客

返回顶部