KTIMER Timer;
DueTime.QuadPart=-10000*2000;//定时2秒
KeInitializeDpc(&deviceExtension->Dpc,CustomTimerDPC,deviceExtension);
KeInitializeTimer(&deviceExtension->Timer);
KeSetTimer(&deviceExtension->Timer,DueTime,&deviceExtension->Dpc);
IN PKDPC pDpc,
IN PVOID deferredContext,
IN PVOID systemArgument1,
IN PVOID systemArgument2
) {
KIRQL OldIrql;
if (sizeof(deferredContext) != sizeof(PDEVICE_EXTENSION))
return;
SKYDbgPrint (SKY_CHECK, ("Timeout"));
}
方法一:NdisMSleep
VOID
NdisMSleep(
IN ULONG MicrosecondsToSleep
);
直接调用NdisMSleep,它的参数是微秒数量级。不过这里一定要注意
调用环境:
KeGetCurrentIrql < DISPATCH_LEVEL
方法二:NdisStallExecution
VOID
NdisStallExecution(
IN UINT MicrosecondsToStall
);
这里也是直接调用,参数是微秒级,但是最好不要用它延时超过50个微秒。
调用环境:
Any IRQL
MicrosecondsToStall <= 50
方法三:KeDelayExecutionThread
NTSTATUS
KeDelayExecutionThread(
IN KPROCESSOR_MODE WaitMode,
IN BOOLEAN Alertable,
IN PLARGE_INTEGER Interval
);
该函数将当前执行线程置于等待状态,当时间过后被唤醒。
调用环境:
KeGetCurrentIrql <= APC_LEVEL
参考代码:
LARGE_INTEGER liTime;
/* Convert milliseconds to 100-nanosecond increments using:
*
* 1 ns = 10 ^ -9 sec
* 100 ns = 10 ^ -7 sec (1 timer interval)
* 1 ms = 10 ^ -3 sec
* 1 ms = (1 timer interval) * 10^4
*/
delay = delay * 10000;
// Negative value means relative time, not absolute
liTime =
RtlConvertLongToLargeInteger(
-(LONG)delay
);
//Callers of KeDelayExecutionThread must be running at IRQL <= APC_LEVEL.
DbgPrint("KeGetCurrentIrql = %d\n", KeGetCurrentIrql());
KeDelayExecutionThread(
KernelMode,
TRUE,
&liTime
);
方法四:KeWaitForSingleObject
NTSTATUS
KeWaitForSingleObject(
IN PVOID Object,
IN KWAIT_REASON WaitReason,
IN KPROCESSOR_MODE WaitMode,
IN BOOLEAN Alertable,
IN PLARGE_INTEGER Timeout OPTIONAL
);
该函数等待信号的到来,如果在所设时间之内没有信号,则返回TimeOut。
调用环境:
KeGetCurrentIrql <= PASSIVE_LEVEL
参考代码:
LARGE_INTEGER TimeoutTimer;
TimeoutTimer = RtlConvertLongToLargeInteger(
-(LONG)(delay * 10000)
);
//sleep,waiting (TimeoutWait) singaled
DbgPrint("KeGetCurrentIrql = %d\n", KeGetCurrentIrql());
status = KeWaitForSingleObject(
&TimeoutWait,
Executive,
KernelMode,
FALSE,
&TimeoutTimer
);
方法五:空循环
调用环境:
任何情况下都可使用。
参考代码:
LARGE_INTEGER liTime, startTime, currentTime;
/* Convert milliseconds to 100-nanosecond increments using:
*
* 1 ns = 10 ^ -9 sec
* 100 ns = 10 ^ -7 sec (1 timer interval)
* 1 ms = 10 ^ -3 sec
* 1 ms = (1 timer interval) * 10^4
*/
delay = delay * 10000;
KeQuerySystemTime(&startTime);
while(1){
KeQuerySystemTime(¤tTime);
liTime.QuadPart = currentTime.QuadPart - startTime.QuadPart;
if(liTime.QuadPart >= delay) break;
}
以上方法中前面四种不占用CPU时钟,第五种方法会占用CPU时钟,在迫不得已的情况下使用。