阅读:2136回复:9
怎样执行需在较低IRQL级下才能执行的函数?
我想执行一个函数(如:KeWaitForSingleObject),但它需在PASSIVE_LEVEL级下执行,而我目前的IRQL级为DISPATCH_LEVEL,我该作怎样的处理才能将其成功执行且无错误。
我曾试过先用KeLowerIrql()降低其IRQL再执行,然后用KeRaiseIrql()还原其IRQL,但最终失败了,执行的效果是,先是执行成功了,不过不一会就非法操作了,大概是降低后被其它线程抢先而导致的,。。。。。。 我该怎么办? |
|
|
沙发#
发布于:2003-09-25 11:41
你又没做中断或者DMA,找找为啥级别会这样高,一定程序中有问题的。
|
|
|
板凳#
发布于:2003-09-25 13:25
Callers of KeWaitForSingleObject must be running at IRQL <= DISPATCH_LEVEL. Usually, the caller must be running at IRQL = PASSIVE_LEVEL and in a nonarbitrary thread context. A call while running at IRQL = DISPATCH_LEVEL is valid if and only if the caller specifies a Timeout of zero. That is, a driver must not wait for a nonzero interval at IRQL = DISPATCH_LEVEL.
|
|
地板#
发布于:2003-09-29 09:05
据我测试,好像只有另建的线程、DriverEntry、AddDevice、DeviceIoControl等例程中才是PASSIVE_LEVEL级,其它很多都是DISPATCH_LEVEL级,比如我在DispatchScsi中需要执行KeWaitForSingleObject,那么此时的IRQL就是DISPATCH_LEVEL,但KeWaitForSingleObject本身的要求是要在PASSIVE_LEVEL级中执行(除非0超时),我的解决方案是另建一个线程,但这样不能实现我在DispatchScsi中所需要的真正同步,
请问有没有什么其它解决方案???????? |
|
|
地下室#
发布于:2003-09-29 19:51
换方案。。。
让你在Dispatch_Level上wait了,那别人还干不干活了? :D DriverObject->MajorFunction[]的都是在passive的 |
|
5楼#
发布于:2003-09-29 22:47
You can use IoAllocateWorkItem() to create a work item. Then use IoQueueWorkItem() to queue your request. I implemented this in my driver. It worked fine.
Hope this can help you. |
|
6楼#
发布于:2003-10-10 15:14
换方案。。。 但我试过了,DriverObject->MajorFunction[IRP_MJ_SCSI]等一些分派例程中好像都是DISPATCH_LEVEL级,不能调用那些需在PASSIVE_LEVEL级才能运行的函数, piggy说的应该能行(虽然我没试),因为据DDK中介绍,他实际上是将它插入队列然后放在另一个线程里面执行。因为我现在的解决方案就是将其转入另一个工作者线程中执行的(成功),因为工作者线程的IRQL级是PASSIV_LEVEL。 |
|
|
7楼#
发布于:2003-10-12 19:59
DISPATH_LEVEL上当然不可能执行KeWaitForSingleObject操作了,因为KeWaitForSingleObject很可能导致当前线程挂起,但DISPATCH_LEVEL是不能进行线程调度的。
IRP分派例程大多数情况下都是在PASSIVE_LEVEL下执行的,可能是你在释放同步对象的时候将Wait置为TRUE了,这样IRQL会维持在DISPATCH_LEVEL。 |
|
8楼#
发布于:2003-10-13 01:38
The IoQueueWorkItem routine inserts a work item into a work queue. A system worker thread will subsequently remove the item from the queue and call the specified callback routine.
我翻译 一个工作队列中插入一个工作项.一个系统工作线程随后将从这个队列里移除这个项然后调用指定的回调函数. |
|
|
9楼#
发布于:2003-10-13 12:52
对呀,意思是说它最终还是是在一个系统工作者线程中执行的,因为系统工作者线程的IRQL为PASSIVE_LEVEL,所以当然没问题了。
|
|
|