阅读:1718回复:8
避免重入问题
楚狂人的教程第2版14节讲到避免重入的问题:
------------------------- 但重入绝对不是问题本身.你可以自由的利用重入实现你的功能,但是你必须避免死递归.如果我能判断这个请求是我自己发出的,我则跳过,这时重入虽然发生,但是对我并没有影响: NTSTATUS SfCreate(…) { … if(这个IRP 不由我的驱动自己发出) { ZwCreateFile(…); // <- 这里会导致发出Irp, 并再次被我们过滤到, 等于这里再次调用SfCreate(…) } … } ------------------------- 最后讲到一个函数: ------------------------- 现在你可以在这个线程里做任何事情,包括生成文件,读写和其他操作等.得到IRP 的时候,可以通过线程id 来判断是否我们自己的线程,来跳过重入问题: BOOLEAN WITIsMyThread(IN PWIT_THREAD thread) { return (PsGetCurrentThreadId() == thread->tid); } ------------------------- 我的疑问是在调用这个函数时,PWIT_THREAD类型的实参从哪里获取,是将thread声明为全局变量还是从Irp中获取? 如果是将thread声明为全局变量,那么一来不用传递这个参数,二来(我的猜测)这个全局变量有可能会在其他Irp到来时被修改。 如果是从Irp中获取,那么具体是从Irp的哪个字段获取? 或者还有其他的处理办法?想了好长时间这个地方实在没想通,请大家指教,谢谢。 |
|
沙发#
发布于:2007-11-10 09:33
参考FILEDISK里的方法,把所有相关处理IRP排队到你的线程里处理,然后在你的DISPATCH里判断是否来自你线程的处理,然后。。。。。。
|
|
|
板凳#
发布于:2007-11-11 01:05
谢谢wowocock老牛,是的,我也是这么想的,但是你没理解我的意思,我现在的问题就是不知道怎样“在你的DISPATCH里判断是否来自你线程的处理”,也就是怎样调用WITIsMyThread这个函数来判断?具体的说就是在 return (PsGetCurrentThreadId() == thread->tid) 这个语句中,我可以调用PsGetCurrentThreadId()函数来获取当前线程的Id,这个没有问题;但是如何获取thread->tid呢,也就是如何得到创建这个重入Irp的线程(即PWIT_THREAD thread参数)呢?回到我楼顶提的问题,就是在创建我的线程的时候,将PWIT_THREAD线程的信息保存到将要重入的Irp中呢,还是将PWIT_THREAD线程变量声明为全局变量(当然是在创建线程之前声明),或者根本就不是我说的这两种办法,还有其他的途径??这样我才能在调用WITIsMyThread这个函数时得到我创建的PWIT_THREAD线程的Id,来跟PsGetCurrentThreadId()这个当前线程的Id进行比较啊。
说的很啰嗦了,希望表达清楚我的意思了。 |
|
地板#
发布于:2007-11-11 12:48
一般全局变量即可。
|
|
|
地下室#
发布于:2007-11-12 13:48
OK,都说是全局变量,那么2个疑问:
1。全局变量不用传递参数 BOOLEAN WITIsMyThread() { return (PsGetCurrentThreadId() == thread->tid); } 这样就行了,thread反正是全局变量 2。既然thread是全局变量,就有可能会在其他相同类型Irp到来时被修改。(这个只是我的猜测,不知道会不会出现前一个Irp被阻塞,而新来的Irp却能被顺利处理的情况?还是说Irp一定会严格按顺序执行?) 主要是第1点吧,不太清楚楚狂人的意图,有点困惑,不知道wowocock是什么想法。 |
|
5楼#
发布于:2007-11-13 10:33
wowocock老兄,我一直在等待你的答案呢,怎么不说话了?
|
|
6楼#
发布于:2007-11-13 22:14
这个线程是在DriverEntry中创建,然后不会销毁也不会发生改变,它就是等待事情来做。所以不用担心会被修改或改变!
|
|
|
7楼#
发布于:2007-11-14 16:08
哦,谢谢devia,我了解你的想法,按照你的意思,这个在DriverEntry中创建的线程thread是全局变量,对不对?
既然是全局变量,那么引用这个thread的函数无需传递这个参数,直接引用就可以了,对不对?也就是说 BOOLEAN WITIsMyThread(IN PWIT_THREAD thread) 和 NTSTATUS WITDoItInThread(IN PWIT_THREAD thread, IN OUT PVOID context, IN PWIT_DO do_somthing) 这2个函数其实不用传递 IN PWIT_THREAD thread 这个参数,写成: BOOLEAN WITIsMyThread() { return (PsGetCurrentThreadId() == thread->tid); } 和 NTSTATUS WITDoItInThread(IN OUT PVOID context, IN PWIT_DO do_somthing) { ………… } 就可以了,对不对?? |
|
8楼#
发布于:2007-11-16 13:35
devia版主,怎么说两句也不说话了?
|
|