驱动中,IO定时器 / DPC定时器 里不能调用KeWaitForSingleObject吗??

时间:2022-07-08 00:16:54
RT

如下面一段 使用 DPC定时器 的代码:

#pragma LOCKEDCODE
VOID PollingTimerDpc( IN PKDPC pDpc,
  IN PVOID pContext,
  IN PVOID SysArg1,
  IN PVOID SysArg2 ) 
{
PDEVICE_OBJECT pDevObj = (PDEVICE_OBJECT)pContext;
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;

// ***
KIRQL zcIrql=KeGetCurrentIrql ();
KdPrint(("zcIrql :: %d\n",zcIrql));//显示是 2 ,即 DISPATCH_LEVEL 
// ***
//*
KEVENT event;
KdPrint(("1\n"));
KeInitializeEvent(&event,NotificationEvent,FALSE);
KdPrint(("2\n"));
LARGE_INTEGER timeout;
KdPrint(("3\n"));
timeout.QuadPart = -1*1000*1000*10;
KdPrint(("4 - %d\n",timeout.QuadPart));
KeWaitForSingleObject(&event,Executive,KernelMode,FALSE,&timeout); // 到这句就 蓝屏
KdPrint(("5\n"));
*/
// ***

KeSetTimer(
&pdx->pollingTimer,
pdx->pollingInterval,
&pdx->pollingDPC );
KdPrint(("PollingTimerDpc\n"));

//检验是运行在任意线程上下文
    PEPROCESS pEProcess = IoGetCurrentProcess();
   
    PTSTR ProcessName = (PTSTR)((ULONG)pEProcess + 0x174);

    KdPrint(("%s\n",ProcessName));
}


PollingTimerDpc 里获得 IRQL 是 DISPATCH_LEVEL。
msdn中看到
“Callers of KeWaitForSingleObject must be running at IRQL <= DISPATCH_LEVEL. However, if Timeout = NULL or *Timeout != 0, the caller must be running at IRQL <= APC_LEVEL and in a nonarbitrary thread context. (If Timeout != NULL and *Timeout = 0, the caller must be running at IRQL <= DISPATCH_LEVEL.)

中断请求级别 没问题啊??

请问为何会 蓝屏??是哪边的问题??

ps:注释掉 "KeWaitForSingleObject" ,代码是运行OK的。

2 个解决方案

#1


不要在DPC Routine里面做这种Wait Object动作:

http://msdn.microsoft.com/en-us/library/ff546551(v=VS.85).aspx
DpcForIsr and CustomDpc routines run at IRQL DISPATCH_LEVEL, which restricts the set of support routines they can call.

For example, DpcForIsr and CustomDpc routines can neither access nor allocate pageable memory, and they cannot wait for kernel dispatcher objects to be set to the signaled state. On the other hand, they can acquire and release a driver's executive spin lock with KeAcquireSpinLockAtDpcLevel and KeReleaseSpinLockFromDpcLevel, which run faster than KeAcquireSpinLock and KeReleaseSpinLock.


http://www.osronline.com/ddkx/kmarch/k105_40c2.htm
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.

#2


Thanks

#1


不要在DPC Routine里面做这种Wait Object动作:

http://msdn.microsoft.com/en-us/library/ff546551(v=VS.85).aspx
DpcForIsr and CustomDpc routines run at IRQL DISPATCH_LEVEL, which restricts the set of support routines they can call.

For example, DpcForIsr and CustomDpc routines can neither access nor allocate pageable memory, and they cannot wait for kernel dispatcher objects to be set to the signaled state. On the other hand, they can acquire and release a driver's executive spin lock with KeAcquireSpinLockAtDpcLevel and KeReleaseSpinLockFromDpcLevel, which run faster than KeAcquireSpinLock and KeReleaseSpinLock.


http://www.osronline.com/ddkx/kmarch/k105_40c2.htm
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.

#2


Thanks