阅读:6203回复:27
驱动在棺材里睡死了.KeWaitForSingleObject后再也起不来.
这是一个Sfilter文件过滤驱动.我在驱动创建时启动了一个线程,该线程不停的激活全局事件EvEnt
在SfCreate函数中等待全局事件被激活,然后处理某些事,处理完后清除信号量KeClearEvent 结果是创建的线程GetPESignContext 激活不了,SfCreate永远的等待,趴棺材里不起来了 在IRP_MJ_CREATE的处理中的代码: sfCreate (...) { .....省略部分,其实上面没代码 //上面加判断线城ID KeWaitForSingleObject(&Event,Executive,KernelMode,FALSE,(PLARGE_INTEGER)NULL); IoSkipCurrentIrpStackLocation(Irp); //清除信号量 KeClearEvent(&Event); return IoCallDriver(devExt->NLExtHeader.AttachedToDeviceObject, Irp); } 驱动入口部分代码: KeInitializeEvent( &Event, SynchronizationEvent , FALSE ); status = PsCreateSystemThread( &threadHandle, PROCESS_ALL_ACCESS, NULL, NULL, //My system thread,why is system?haha,因为,系统线程只有系统关闭时才结束, NULL, GetPESignContext, NULL ); 线程函数: VOID GetPESignContext (PVOID pContext) { pContext = NULL; KeSetPriorityThread (KeGetCurrentThread() ,LOW_REALTIME_PRIORITY); while(TRUE) { KeSetEvent(&Event ,0 ,FALSE); } } |
|
沙发#
发布于:2008-03-12 15:53
虽然是老帖了,可楼上的说的实在太精彩了
|
|
板凳#
发布于:2007-02-02 11:10
哈哈,让我来告诉你们吧!
1. VOID KeInitializeEvent(IN PRKEVENT Event, IN EVENT_TYPE Type, IN BOOLEAN State); Type : 事件类型,可以是 NotificationEvent 和 而SynchronizationEvent. NotificationEvent 等待一个IO操作完成.当一个NotificationEvent事件用KeSetEvent设置成信号状态时, 所有等待在该事件上的线程都会开始执行,这是因为此类型事件不会自动清除信号,它 保留信号状态直到你手工用KeResetEvent 或 KeClearEvent 清除这个事件的信号状态. SynchronizationEvent 等待一个IO操作完成.当一个NotificationEvent事件用KeSetEvent设置成信号状态时, 则只能让等待在该事件上的单个线程开始执行,其它会继续等待,这是因为此类型在执 行 KeWaitForMultipleObjects 或 KeWaitForSingleObject 之后会自动清除这个事件 的信号状态, 而不必手工用 KeResetEvent 或 KeClearEvent 清除这个事件的信号状 态. State : 指明事件的信号初始化状态. 当是TRUE 时初始化事件是有信号状态. 当是FALSE时初始化事件是没信号状态. 2. LONG KeSetEvent ( IN PRKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait ); 设置事件为有信号状态. 3. NTSTATUS KeWaitForMultipleObjects ( IN ULONG Count, IN PVOID Object[], IN WAIT_TYPE WaitType, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL, IN PKWAIT_BLOCK WaitBlockArray OPTIONAL ); 或 NTSTATUS KeWaitForSingleObject ( IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL ); 等待事件信号状态的发生. 4. LONG KeResetEvent ( IN PRKEVENT Event ); 复位一个指定事件到没有信号状态并返回以前这个事件的信号状态. 返回非零说明以前是有信号状态; 返回 零说明以前是无信号状态; 5. VOID KeClearEvent ( IN PRKEVENT Event ); 设置一个指定事件到没有信号状态. 说明: KeResetEvent 和 KeClearEvent 都是设置一个指定事件到没有信号状态, 如果不想得到以前这个事件的信号状态的话用 KeClearEvent 更好. 6. LONG KeReadStateEvent( IN PRKEVENT Event ); 得到一个给定事件当前的信号状态. 返回非零说明是有信号状态; 返回 零说明是无信号状态; |
|
地板#
发布于:2007-02-01 14:49
不知道是不是Irp->Tail.Overlay.Thread。哈哈
|
|
地下室#
发布于:2007-02-01 14:20
感谢几位大大,
AllenZh killvxk 当然还有wow。感谢你们 我接下来做的是根据截获的IRP取产生这个IRP的线程ID,不知道哪位大大能提示下该怎么做吗? |
|
5楼#
发布于:2007-02-01 13:26
因为Sy那个玩意产生过问题,所以使用Notifi了~
不过只是习惯和风格而已~ 哈哈~ |
|
|
6楼#
发布于:2007-02-01 13:19
以前使用SynchronizationEvent 出现过问题,使用NotificationEvent 就好了,所以现在就一直偏爱NotificationEvent 了,纯粹是个人喜好,
![]() |
|
|
7楼#
发布于:2007-02-01 13:09
while(1)
{ //等待事件. KeResetEvent(&Event); while(KeWaitForSingleObject(&Event,Executive,KernelMode,FALSE,&Time)==STATUS_TIMEOUT);// //KeWaitForSingleObject(&Event,Executive,KernelMode,FALSE,(PLARGE_INTEGER)NULL); DbgPrint("Thread is active..."); ThreadReturn = TRUE; KeSetEvent(&irpEvent ,0 ,FALSE); } 修改为 KeResetEvent(&Event); while(1) { //等待事件. while(KeWaitForSingleObject(&Event,Executive,KernelMode,FALSE,&Time)==STATUS_TIMEOUT);// KeResetEvent(&Event); //KeWaitForSingleObject(&Event,Executive,KernelMode,FALSE,(PLARGE_INTEGER)NULL); DbgPrint("Thread is active..."); ThreadReturn = TRUE; KeSetEvent(&irpEvent ,0 ,FALSE); } KeResetEvent(&irpEvent); KeSetEvent(&Event ,0 ,FALSE); while(KeWaitForSingleObject(&irpEvent,Executive,KernelMode,FALSE,&Time)==STATUS_TIMEOUT);// 修改为 KeSetEvent(&Event ,0 ,FALSE); while(KeWaitForSingleObject(&irpEvent,Executive,KernelMode,FALSE,&Time)==STATUS_TIMEOUT);// KeResetEvent(&irpEvent); |
|
|
8楼#
发布于:2007-02-01 13:03
killvxk,老大.不好意思.代码顺序错了。
我把错误的地方写上:希望能对以后的人有帮助 KeResetEvent(&irpEvent); 放在KeWaitForSingleObject(&irpEvent,Executive,KernelMode,FALSE,&Time)之后 对于A老大的改法。我之前有试过。好象还是不行。 对于NotificationEvent ,我看DDK上的说明是: NotificationEvent 会让所有等待该事件的线程休眠。 而SynchronizationEvent 则是单一线程吧 SynchronizationEvent 会自动清楚信号等。而NotificationEvent 则不会 为什么A老大和老V都用NotificationEvent 呢。可以让后生我知道吗? 对于内存轮询。总觉得不太好。While(1)循环好象不是效率的好办法 现在同步成功了。谢谢你,谢谢大大门。 感激。 不想发贴。顺便问问。在一个IRP_MJ_CREATE消息中。怎么才能得到发送这个消息的线程的ID 希望大大们给点提示。谢谢。 我努力学习中。 |
|
9楼#
发布于:2007-02-01 12:46
![]() |
|
|
10楼#
发布于:2007-02-01 12:32
使用
KeInitializeEvent( &Event, NotificationEvent , FALSE ); KeInitializeEvent( &irpEvent, NotificationEvent , FALSE ); 失败了。依然 使用老V老大短信说的。也依然失败了。。唤醒不了。 |
|
|
11楼#
发布于:2007-02-01 10:37
哈,AllenZh一语道破~我今天也短消息给LZ说了~
|
|
|
12楼#
发布于:2007-02-01 10:27
KeInitializeEvent( &Event, SynchronizationEvent , FALSE );
修改为KeInitializeEvent( &Event, NotificationEvent , FALSE ); |
|
|
13楼#
发布于:2007-02-01 09:41
别用什么EVENT了,自己设置块内存,轮巡访问吧,自己的东西好控制,那些同步什么的最麻烦,大不了自己用什么CMPXCHG系列的指令自己来处理.
![]() |
|
|
14楼#
发布于:2007-02-01 00:29
我在后面的代码使用了
KeResetEvent(&irpEvent);后工作线程是正常的,但是主线程的等待唤醒不了。 请楼上的大大和老V大大帮忙!!! |
|
15楼#
发布于:2007-01-31 22:39
引用第4楼killvxk于2007-01-31 11:17发表的“”: 同意。。。 打强心针就能起来了。。。 |
|
|
16楼#
发布于:2007-01-31 17:48
有没有人来救救我啊?
|
|
17楼#
发布于:2007-01-31 14:25
killvxk
可以告诉我你的方法吗?我知道这种行为不好.但是我真的是束手无策了. 现在工作线程是正常睡眠正常唤醒.而主线程则是不正常的. |
|
18楼#
发布于:2007-01-31 14:11
我等待的方法和你不一样~
|
|
|
19楼#
发布于:2007-01-31 14:10
我觉得问题是不是在这?
//清除信号量 KeResetEvent(&irpEvent); return IoCallDriver(devExt->NLExtHeader.AttachedToDeviceObject, Irp); 这句会导致return前主线程休眠了? 那我是否可以放到完成例程里去? |
|
上一页
下一页