(十七)、定时器

一、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
 
posted @ 2022-04-12 16:47  TLSN  阅读(94)  评论(0编辑  收藏  举报