标签:
I/O定时器是DDK提供的一种定时器。它每个1s钟系统会调用一次I/O定时器例程。I/O定时器例程运行在DISPATCH_LEVEL级别,因此在这个例程中不能使用分页内存,否则会引起页故障从而导致系统崩溃。另外I/O定时器是运行在任一线程的,不一定是IRP发起的线程中,因此不能直接使用应用程序的内存地址。
初始化I/O定时器后,可以开启和停止I/O定时器。开启定时器后,每个1s系统调用一次定时器例程。在听指定是气候,系统就不会进入定时器例程。开启定时器的内核函数是IoStartTimer,停止I/O定时器的内核函数是IoStopTimer。
示例代码:
现在DriverEntry中初始化计时器:
再写相应的派遣函数:
1 NTSTATUS HelloDDKDeviceIoControl_Timer(PDEVICE_OBJECT pDevObj, PIRP pIrp){ 2 DbgPrint("Enter HelloDDKDeviceIoControl_Timer!\n"); 3 NTSTATUS status = STATUS_SUCCESS; 4 PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrp); 5 //ULONG cbin = stack->Parameters.DeviceIoControl.InputBufferLength; 6 //ULONG cbout = stack->Parameters.DeviceIoControl.OutputBufferLength; 7 ULONG code = stack->Parameters.DeviceIoControl.IoControlCode; 8 PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION) 9 pDevObj->DeviceExtension; 10 ULONG info = 0; 11 switch (code) 12 { 13 case IOCTL_START_TIMER: 14 { 15 DbgPrint("IOCTL_START_TIMER\n"); 16 pDevExt->lTimerCount = TIMER_OUT; 17 IoStartTimer(pDevObj); 18 break; 19 } 20 case IOCTL_STOP: 21 { 22 DbgPrint("IOCTL_STOP\n"); 23 IoStopTimer(pDevObj); 24 break; 25 } 26 default: 27 status = STATUS_INVALID_VARIANT; 28 } 29 pIrp->IoStatus.Status = status; 30 pIrp->IoStatus.Status = info; 31 IoCompleteRequest(pIrp, IO_NO_INCREMENT); 32 DbgPrint("Leave HelloDDKDeviceIoControl_Timer!\n"); 33 return status; 34 }
再写入Timer例程:
应用层代码如下:
发送相应控制码到底层,每三秒输出一个“Time Out”:
驱动程序中第二种使用定时器的方法是使用DPC定时器,这种定时器更加灵活,可以对任意间隔时间进行定时。DPC定时器内部使用定时器对象KTIMER,当对定时器设定一个时间间隔后,每隔这段时间操作系统就会将一个DPC例程插入DPC队列。当操作系统读取DPC队列时,对应的DPC例程会被执行。DPC定时器例程相当于定时器的回调函数。
标签:
原文地址:http://www.cnblogs.com/predator-wang/p/5580002.html