2012年12月10日星期一
KeSetTimerEx.C
/*
时间很重要,在现实中如是,在计算机中亦是,如时钟中断。
时间怎能不会,特别是阴阳历转换。
此文展示几种用法,暂命名为KeSetTimerEx.C,
因为IoInitializeTimer需要一个设备对象。
KeSetTimerEx对dpc可有可无,使用更方便。
本文的不足之处,可能是定时器对象的删除等,
不然内存泄露,verifier.exe报错。
made by correy
made at 2012.12.10
QQ:112426112
Email:kouleguan at hotmail dot com
Homepage:http://correy.webs.com
*/
#include <ntddk.h>
PVOID g_pkThread;
DRIVER_UNLOAD Unload;
VOID Unload(__in PDRIVER_OBJECT DriverObject)
{
PDEVICE_OBJECT pdoNextDeviceObj;
KeWaitForSingleObject(g_pkThread, Executive, KernelMode, FALSE, NULL);
ObDereferenceObject(g_pkThread);
pdoNextDeviceObj = DriverObject->DeviceObject;//pdoGlobalDrvObj
//IoDeleteSymbolicLink(&usSymlinkName);//本程序没有创建符号链接。
while(pdoNextDeviceObj) // Delete all the device objects
{
PDEVICE_OBJECT pdoThisDeviceObj = pdoNextDeviceObj;
pdoNextDeviceObj = pdoThisDeviceObj->NextDevice;
IoDeleteDevice(pdoThisDeviceObj);
}
}
KSTART_ROUTINE ThreadStart;
VOID ThreadStart(__in PVOID StartContext)
{
KdPrint(("创建线程的完整规范示例用法,注意卸载的时候!\n"));
PsTerminateSystemThread(STATUS_SUCCESS);
}
IO_TIMER_ROUTINE IoTimer;
VOID IoTimer(__in PDEVICE_OBJECT DeviceObject, __in_opt PVOID Context)
{
DbgPrint("i am in IoTimer!\n");
KeSetEvent((PKEVENT)Context, 0, FALSE);
}
KDEFERRED_ROUTINE CustomDpc;
VOID CustomDpc(
__in struct _KDPC *Dpc,
__in_opt PVOID DeferredContext,
__in_opt PVOID SystemArgument1,
__in_opt PVOID SystemArgument2)
{
DbgPrint("i am in CustomDpc!\n");
KeSetEvent((PKEVENT)DeferredContext, IO_NO_INCREMENT, FALSE);//结束。
//还可以再调用KeSetTimer,但是要注意次数,和参数。 特别注意时间。
}
DRIVER_INITIALIZE DriverEntry;
NTSTATUS DriverEntry( __in struct _DRIVER_OBJECT * DriverObject, __in PUNICODE_STRING RegistryPath)
{
LARGE_INTEGER li;
HANDLE ThreadHandle;
UNICODE_STRING usDeviceName;
PDEVICE_OBJECT pdoDeviceObj = 0;
NTSTATUS status = STATUS_UNSUCCESSFUL;
KEVENT ke;
KTIMER kt;
BOOLEAN b;
KDPC dpc;
int i;
//KdBreakPoint();//#define KdBreakPoint() DbgBreakPoint()
DriverObject->DriverUnload = Unload;
//////////////////////////////////////////////////////////////////////////
KdPrint(("暂停5秒:KeStallExecutionProcessor\n"));
KeStallExecutionProcessor(5000000);//5秒钟。
//////////////////////////////////////////////////////////////////////////
KdPrint(("暂停5秒:KeDelayExecutionThread\n"));
li.QuadPart = (5 * (((-10) * 1000) * 1000)); //负数是暂停5秒钟。
status = KeDelayExecutionThread(KernelMode, FALSE, &li);
if (status != STATUS_SUCCESS)
{
KdPrint(("KeDelayExecutionThread return:%d\n", status));
//return r;
}
//////////////////////////////////////////////////////////////////////////
RtlInitUnicodeString(&usDeviceName, L"\\Device\\correy"); //必须创建设备。
status = IoCreateDevice(DriverObject, 0, &usDeviceName, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &pdoDeviceObj);
if(!NT_SUCCESS(status))
{
return status;
}
KeInitializeEvent(&ke, NotificationEvent, FALSE);
IoInitializeTimer(pdoDeviceObj, IoTimer, &ke);//感觉和WorkItem差不多,只不过把方法改名为开始和结束。
IoStartTimer(pdoDeviceObj);
KeWaitForSingleObject(&ke, Executive, KernelMode, FALSE, NULL);
IoStopTimer(pdoDeviceObj);
//////////////////////////////////////////////////////////////////////////
KeInitializeTimerEx(&kt, SynchronizationTimer);
li.QuadPart = (5 * (((-10) * 1000) * 1000));
//第三个参数,如果是负数,会失败,并且蓝屏。并且不能大于#define MAXLONG 0x7fffffff // winnt
b = KeSetTimerEx(&kt, li, 5000000, 0);//其实有5个参数。如kmdkit里面的用法,ida里面也是的。
if (b == 1)
{
KdPrint(("the timer object was already in the system timer queue\n"));
//继续前进,千万不要退出。注意,注意,再注意。
}
for (i = 0; i < 3; i++)
{
KeWaitForSingleObject(&kt, Executive, KernelMode, FALSE, NULL);
KdPrint(("KeSetTimer:5秒%d次\n", i+1));
KeSetTimerEx(&kt, li, 5000000, 0);
}
b = KeCancelTimer(&kt);
if (b == 0)
{
return b;
}
//////////////////////////////////////////////////////////////////////////
KeResetEvent(&ke);
KeInitializeTimerEx(&kt, SynchronizationTimer);
KeInitializeDpc(&dpc, CustomDpc, &ke);//最后一个参数是传递用的。
li.QuadPart = (5 * (((-10) * 1000) * 1000));
KdPrint(("5秒后调用CustomDpc函数\n", i));
//第三个参数,如果是负数,会失败,并且蓝屏。并且不能大于#define MAXLONG 0x7fffffff // winnt
b = KeSetTimerEx(&kt, li, 5000000, &dpc);//其实有5个参数。
if (b == 1)
{
KdPrint(("the timer object was already in the system timer queue\n"));
//继续前进,千万不要退出。注意,注意,再注意。
}
KeWaitForSingleObject(&ke, Executive, KernelMode, FALSE, NULL);
b = KeCancelTimer(&kt);
if (b == 0)
{
return b;
}
KeClearEvent(&ke);
KeCancelTimer(&kt);
//////////////////////////////////////////////////////////////////////////
status = PsCreateSystemThread(&ThreadHandle, THREAD_ALL_ACCESS, NULL, NULL, NULL, ThreadStart, NULL);
if (status != STATUS_SUCCESS)
{
KdPrint(("PsCreateSystemThread return:%d\n", status));
//return r;
}
else
{
ObReferenceObjectByHandle(ThreadHandle, THREAD_ALL_ACCESS, NULL, KernelMode, &g_pkThread, NULL);
ZwClose(ThreadHandle);
}
//////////////////////////////////////////////////////////////////////////
return 0;
}
订阅:
博文评论 (Atom)
没有评论:
发表评论