阅读:1173回复:8
请教:双事件对象通知的问题!!
我在应用程序中和驱动中各创建一个事件对象。然后在应用程序中创建新线程并阻塞等待驱动置位事件,驱动置位事件后,则转入阻塞等待。具体代码如下:
应用程序中: unsigned ThreadId; DWORD BytesReturned; //获得设备句柄 hDevice=CreateFile(MY_DEVICE_NAME,GENERIC_READ | GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); //创建共享事件 hShareE = CreateEvent(NULL,TRUE,FALSE,NULL); //传递创建共享事件的I/O控制代码 DeviceIoControl(hDevice,SHARE_EVENT_CRT,&hShareE,4,NULL,0,&BytesReturned,NULL); //创建新线程 _beginthreadex(NULL,0,&ppppp,(void*)hShareE,0,&ThreadId); 新线程中: unsigned __stdcall ppppp(void*(hShareE)) { while(1) { //阻塞等待 WaitForSingleObject((HANDLE) hShareE,INFINITE); //通知用户 ::MessageBox(NULL,"Event Set!",NULL,MB_OK); ResetEvent((HANDLE) hShareE); } _endthreadex(0); return 0; } 驱动中: //共享事件 WCHAR wEventNameBuf[]=L"\\BaseNamedObjects\\SharedEvent"; UNICODE_STRING uEventName; PKEVENT pEventApp,pEventDrv; HANDLE hEventDrv,hEventApp; //互斥对象 KMUTEX H_FuncMutex; //共享事件创建 case SHARE_EVENT_CRT: RtlCopyMemory(&hEventApp,pIrp->AssociatedIrp.SystemBuffer,4); //从应用事件句柄获取事件指针 ObReferenceObjectByHandle(hEventApp,EVENT_MODIFY_STATE,*ExEventObjectType,pIrp->RequestorMode,(PVOID*) &pEventApp,NULL); //驱动事件创建 RtlInitUnicodeString(&uEventName,wEventNameBuf); pEventDrv = IoCreateNotificationEvent(&uEventName,&hEventDrv); if(pEventDrv != NULL) KeClearEvent(pEventDrv); break; 驱动中的hook函数: //互斥进入临界区 KeWaitForMutexObject(&H_FuncMutex,Executive,KernelMode,FALSE,NULL); //置位事件通知应用程序 KeSetEvent(pEventApp, IO_NO_INCREMENT, TRUE); //阻塞等待 KeWaitForSingleObject((PKEVENT)pEventDrv,Executive,UserMode,0,0); KeClearEvent(pEventDrv); //退出临界区 KeReleaseMutex(&H_FuncMutex,FALSE); 可是现在的问题是:在驱动中的hook函数里KeSetEvent成功了,但是在等待的新线程却没有反应,我强行置位,让hook函数继续执行下去,则如此经过3次之后,线程才被唤醒。如果把驱动中的hook函数里面的 //阻塞等待 KeWaitForSingleObject((PKEVENT)pEventDrv,Executive,UserMode,0,0); KeClearEvent(pEventDrv); 注释掉的话,则是完全没有问题的,线程可以正常唤醒。。。。 请大家帮帮忙,帮我看看出了什么问题吧,或者给我个思路也行,谢谢了!!! |
|
沙发#
发布于:2007-03-13 08:05
可能是deadlock,你hook的是什么函数?
另外,在user-mode thread中用MessageBox好像有问题,记得MSDN上曾经看到说只能在main thread中做GUI操作。 |
|
|
板凳#
发布于:2007-03-13 14:12
我hook了RegOpenKey来测试一下,因为RegOpenKey调用频繁,所以我用了KeWaitForMutexObject互斥进入。
对于你的第2个问题,如果把以下注释掉的话,其他一切都是正常的,MessageBox也弹出来了 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //阻塞等待 KeWaitForSingleObject((PKEVENT)pEventDrv,Executive,UserMode,0,0); KeClearEvent(pEventDrv); <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 所以,感觉好奇怪。不过也感谢你的回答,谢谢!! |
|
地板#
发布于:2007-03-14 06:43
曾经在开发中看到KeWaitxxx也会去操作registry,虽然不清楚是否一定是RegOpenKey。。。
|
|
|
地下室#
发布于:2007-03-14 14:07
谁来signal pEventDrv ???
|
|
5楼#
发布于:2007-03-14 15:07
经过测试,正如你说的,KeWaitxxx会调用到xxOpenKey函数,所以才有这样的情况,其他的函数却没有问题。非常感谢你的回答!!
|
|
6楼#
发布于:2007-03-14 15:15
噢,忘记写了,线程中会发一个IRP,让驱动自己去唤醒它。不过为了方便测试,我改为手工按钮执行。我本意是在线程中直接唤醒它的,但是好像驱动创建的事件,应用使用不了,但pjf以前说过是可以的,我用他的代码好像也实现不了,以下是他的代码的连接:
http://bbs.driverdevelop.com/read.php?tid-11043-fpage--toread--page-2.html |
|
7楼#
发布于:2007-03-15 06:24
引用第6楼troylees于2007-03-14 17:15发表的“”: 你那个简单的按钮操作,也有可能引起很多事情的,它不仅仅是画图像那么简单,很有可能产生新的RegOpenKey。。。 |
|
|
8楼#
发布于:2007-03-15 13:08
噢,明白了!!非常感谢你的提醒。现在驱动和应用的双事件通知问题应该算解决了。
不过,我还是搞不清楚在驱动创建的事件,应用程序怎么样才能使用。 感谢大家的关注。谢谢!! |
|