(十七)、定时器

一、IO定时器

IoInitializeTimer
 
0
 
0
 
 
IoStartTimer
 
0
 
代码
#include <ntddk.h> VOID Unload(PDRIVER_OBJECT driver) { IoStopTimer(driver->DeviceObject); DbgPrint("Driver Unload\n"); } VOID IoTimer( PDEVICE_OBJECT pDeviceObject, PVOID pContext ) { DbgPrint("iO定时器\n"); } NTSTATUS DriverEntry(PDRIVER_OBJECT driver) { DbgPrint("Driver Load\n"); PDEVICE_OBJECT DeviceObject; NTSTATUS status; status = IoCreateDevice(driver, 0, NULL, FILE_DEVICE_UNKNOWN, FILE_AUTOGENERATED_DEVICE_NAME, FALSE, &DeviceObject); if (!NT_SUCCESS(status)) { DbgPrint("设备创建失败\n"); return status; } IoInitializeTimer(DeviceObject, IoTimer, NULL); IoStartTimer(DeviceObject);//启动定时器,默认1s一次// driver->DriverUnload = Unload; return STATUS_SUCCESS; }
 
0
1s 1次,直至驱动卸载
 
 

二、DPC定时器

DPC计时器精度比较高,精确到微秒
KeSetTimer
0
 
KeInitializeDpc
0
 
代码
#include <ntddk.h> KDPC dpc; KTIMER timer; LARGE_INTEGER timeout; VOID Unload(PDRIVER_OBJECT driver) { //IoStopTimer(driver->DeviceObject); KeCancelTimer(&timer); DbgPrint("Driver Unload\n"); IoDeleteDevice(driver->DeviceObject); } VOID IoTimer( PDEVICE_OBJECT pDeviceObject, PVOID pContext ) { DbgPrint("iO定时器\n"); } void DpcRoutine( struct _KDPC* Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2 ) { DbgPrint("Dpc Timer\n"); KeSetTimer(&timer, timeout, &dpc); } NTSTATUS DriverEntry(PDRIVER_OBJECT driver) { DbgPrint("Driver Load\n"); PDEVICE_OBJECT DeviceObject; NTSTATUS status; status = IoCreateDevice(driver, 0, NULL, FILE_DEVICE_UNKNOWN, FILE_AUTOGENERATED_DEVICE_NAME, FALSE, &DeviceObject); if (!NT_SUCCESS(status)) { DbgPrint("设备创建失败\n"); return status; } //IoInitializeTimer(DeviceObject, IoTimer, NULL); //IoStartTimer(DeviceObject);//启动定时器,默认1s一次// timeout = RtlConvertLongToLargeInteger(-10 * 100 * 1000);//100 ms 一次// KeInitializeTimer(&timer); KeInitializeDpc(&dpc, DpcRoutine, NULL); driver->DriverUnload = Unload; KeSetTimer(&timer, timeout, &dpc); return STATUS_SUCCESS; }
 
0
每100ms触发一次
 

三、等待

 
0
KeWaitForSingleObject :等待事件或对象
KeStallExecutionProcessor:CPU空转
 
代码
#include <ntddk.h> VOID Unload(PDRIVER_OBJECT driver) { DbgPrint("Driver Unload\n"); } void WaitTest1() { KEVENT Event; LARGE_INTEGER timeout = RtlConvertLongToLargeInteger(-10 * 1000 * 1000); KeInitializeEvent(&Event, SynchronizationEvent,FALSE); KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, &timeout); DbgPrint("等待结束\n"); } void WaitTest2() { KTIMER timer; LARGE_INTEGER timeout = RtlConvertLongToLargeInteger(-10 * 1000 * 1000); KeInitializeTimer(&timer); KeSetTimer(&timer, timeout, NULL); KeWaitForSingleObject(&timer, Executive, KernelMode, FALSE, &timeout); DbgPrint("等待结束2"); } void WaitTest3() { LARGE_INTEGER timeout = RtlConvertLongToLargeInteger(-10 * 1000 * 1000); KeDelayExecutionThread(KernelMode, FALSE, &timeout); DbgPrint("等待结束3\n"); } void WaitTest4() { KeStallExecutionProcessor(1000 * 1000); DbgPrint("等待结束4\n"); } NTSTATUS DriverEntry(PDRIVER_OBJECT driver) { DbgPrint("Driver Load\n"); WaitTest1(); WaitTest2(); WaitTest3(); WaitTest4(); driver->DriverUnload = Unload; return STATUS_SUCCESS; }
 
0
 
 

四、时间函数与Irp超时处理

KeQuerySystemTime
查询系统时间
 
 
ExSystemTimeToLocalTime
0
RtlTimeToTimeFields
0
 
#include <ntddk.h> VOID Unload(PDRIVER_OBJECT driver) { DbgPrint("Driver Unload\n"); } void WaitTest1() { KEVENT Event; LARGE_INTEGER timeout = RtlConvertLongToLargeInteger(-10 * 1000 * 1000); KeInitializeEvent(&Event, SynchronizationEvent,FALSE); KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, &timeout); DbgPrint("等待结束\n"); } void WaitTest2() { KTIMER timer; LARGE_INTEGER timeout = RtlConvertLongToLargeInteger(-10 * 1000 * 1000); KeInitializeTimer(&timer); KeSetTimer(&timer, timeout, NULL); KeWaitForSingleObject(&timer, Executive, KernelMode, FALSE, &timeout); DbgPrint("等待结束2"); } void WaitTest3() { LARGE_INTEGER timeout = RtlConvertLongToLargeInteger(-10 * 1000 * 1000); KeDelayExecutionThread(KernelMode, FALSE, &timeout); DbgPrint("等待结束3\n"); } void WaitTest4() { KeStallExecutionProcessor(1000 * 1000); DbgPrint("等待结束4\n"); } VOID FunTime() { LARGE_INTEGER systemtime; LARGE_INTEGER localtime; TIME_FIELDS timefields; KeQuerySystemTime(&systemtime);//查询系统时间// ExSystemTimeToLocalTime(&systemtime, &localtime); RtlTimeToTimeFields(&localtime, &timefields); DbgPrint("%d年%d月%d日 %d:%d:%d %.3d\n", timefields.Year, timefields.Month, timefields.Day, timefields.Hour, timefields.Minute, timefields.Second, timefields.Milliseconds); } NTSTATUS DriverEntry(PDRIVER_OBJECT driver) { DbgPrint("Driver Load\n"); /*WaitTest1(); WaitTest2(); WaitTest3(); WaitTest4();*/ FunTime(); driver->DriverUnload = Unload; return STATUS_SUCCESS; }

 

 
0

五、Irp超时处理

 
0环代码
#include <ntddk.h> KDPC dpc; KTIMER timer; LARGE_INTEGER timeout; VOID Unload(PDRIVER_OBJECT driver) { //IoStopTimer(driver->DeviceObject); UNICODE_STRING SymbolicName = RTL_CONSTANT_STRING(L"\\??\\MyDDKLink"); KeCancelTimer(&timer); DbgPrint("Driver Unload\n"); IoDeleteSymbolicLink(&SymbolicName); IoDeleteDevice(driver->DeviceObject); DbgPrint("driver unload\n"); } VOID IoTimer( PDEVICE_OBJECT pDeviceObject, PVOID pContext ) { DbgPrint("iO定时器\n"); } void DpcRoutine( struct _KDPC* Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2 ) { PIRP Irp = (PIRP)DeferredContext; Irp->IoStatus.Status = STATUS_CANCELLED; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); DbgPrint("Dpc Timer\n"); } NTSTATUS DispatchRoutine(PDEVICE_OBJECT DeviceObject, PIRP Irp) { Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_SUCCESS; } NTSTATUS DispatchRead(PDEVICE_OBJECT DeviceObject, PIRP Irp) { IoMarkIrpPending(Irp); timeout = RtlConvertLongToLargeInteger(-10 * 2000 * 1000);// 2s 一次// KeInitializeTimer(&timer); KeInitializeDpc(&dpc, DpcRoutine, Irp); KeSetTimer(&timer, timeout, &dpc); return STATUS_PENDING; } NTSTATUS DriverEntry(PDRIVER_OBJECT driver) { DbgPrint("Driver Load\n"); UNICODE_STRING SymbolicLinkName = RTL_CONSTANT_STRING(L"\\??\\MyDDKLink"); UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\MyDDKName"); PDEVICE_OBJECT DeviceObject; NTSTATUS status; status = IoCreateDevice(driver, 0, &DeviceName, FILE_DEVICE_UNKNOWN, 0, FALSE, &DeviceObject); if (!NT_SUCCESS(status)) { DbgPrint("设备创建失败\n"); return status; } status = IoCreateSymbolicLink(&SymbolicLinkName, &DeviceName); if (!NT_SUCCESS(status)) { DbgPrint("符号链接创建失败\n"); IoDeleteDevice(DeviceObject); return status; } //IoInitializeTimer(DeviceObject, IoTimer, NULL); //IoStartTimer(DeviceObject);//启动定时器,默认1s一次// //timeout = RtlConvertLongToLargeInteger(-10 * 2000 * 1000);// 2s 一次// //KeInitializeTimer(&timer); //KeInitializeDpc(&dpc, DpcRoutine, NULL); //KeSetTimer(&timer, timeout, &dpc); driver->DriverUnload = Unload; driver->MajorFunction[IRP_MJ_CREATE] = DispatchRoutine; driver->MajorFunction[IRP_MJ_CLOSE] = DispatchRoutine; driver->MajorFunction[IRP_MJ_READ] = DispatchRead; DeviceObject->Flags |= DO_BUFFERED_IO; DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; //KeSetTimer(&timer, timeout, &dpc); return STATUS_SUCCESS; }
三环代码
// dpc定时器三环代码.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 // #include <iostream> #include <stdio.h> #include <Windows.h> using namespace std; int main() { DWORD dwRet; HANDLE hDevice = CreateFile(TEXT("\\\\.\\MyDDKLink"), GENERIC_ALL, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL ); if (hDevice == INVALID_HANDLE_VALUE) { printf("设备打开失败 %d \n",GetLastError()); getchar(); return -1; } OVERLAPPED ol = { NULL }; ReadFile(hDevice, NULL, 0, &dwRet, &ol); WaitForSingleObject(ol.hEvent, INFINITE); CloseHandle(hDevice); getchar(); return 0; }
运行两秒后显示 Dpc Timer
0
 

__EOF__

本文作者_TLSN
本文链接https://www.cnblogs.com/lordtianqiyi/articles/16135894.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   TLSN  阅读(107)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示