- 关于内核定时器,及DPC的使用,看来一些代码,这个估计是比较规范的用法了,很基础,希望对新手有帮助
- 注意,这里的定时器不太精确!
- #include <ntddk.h>
- typedef struct _DEVICE_EXTENSION {
-
- LIST_ENTRY list_head;
- KSPIN_LOCK list_lock;
- PVOID thread_pointer;
- BOOLEAN terminate_thread;
- KEVENT request_event;
- KTIMER my_timer;
- KDPC KiTimerExpireDpc;
- } DEVICE_EXTENSION, *PDEVICE_EXTENSION;
- #define dprintf if (DBG) DbgPrint
- #define nprintf DbgPrint
- #define DEVICE_NAME L"\\Device\\devhello" // Driver Name
- #define LINK_NAME L"\\DosDevices\\hello" // Link Name
-
-
-
- #define IOCTL_BASE 0x800
- #define MY_CTL_CODE(i) \
- CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_BASE+i, METHOD_BUFFERED, FILE_ANY_ACCESS)
- #define IOCTL_HELLO MY_CTL_CODE(0)
-
-
- NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pRegistryString);
- NTSTATUS DispatchCreate(PDEVICE_OBJECT pDevObj, PIRP pIrp);
- NTSTATUS DispatchClose(PDEVICE_OBJECT pDevObj, PIRP pIrp);
- VOID DriverUnload(PDRIVER_OBJECT pDriverObj);
- NTSTATUS DispatchIoctl(PDEVICE_OBJECT pDevObj, PIRP pIrp);
- VOID
- KiTimerExpirationFunction (
- IN struct _KDPC *Dpc,
- IN PVOID DeferredContext,
- IN PVOID SystemArgument1,
- IN PVOID SystemArgument2
- );
- NTSTATUS ThreadFunc ( IN PVOID Context);
-
-
- NTSTATUS
- DriverEntry(
- PDRIVER_OBJECT pDriverObj,
- PUNICODE_STRING pRegistryString
- )
- {
- NTSTATUS status = STATUS_SUCCESS;
- UNICODE_STRING ustrLinkName;
- UNICODE_STRING ustrDevName;
- PDEVICE_OBJECT device_object;
- PDEVICE_EXTENSION device_extension;
- HANDLE thread_handle;
-
-
-
-
-
-
- LARGE_INTEGER duetime = {0};
- #define POLLING_INTERVAL 3000
- dprintf("[hello] DriverEntry\n");
-
- pDriverObj->MajorFunction[IRP_MJ_CREATE] = DispatchCreate;
- pDriverObj->MajorFunction[IRP_MJ_CLOSE] = DispatchClose;
- pDriverObj->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchIoctl;
- pDriverObj->DriverUnload = DriverUnload;
-
- RtlInitUnicodeString(&ustrDevName, DEVICE_NAME);
- status = IoCreateDevice(pDriverObj,
- sizeof(DEVICE_EXTENSION),
- &ustrDevName,
- FILE_DEVICE_UNKNOWN,
- 0,
- FALSE,
- &device_object);
- if(!NT_SUCCESS(status)) {
- dprintf("[hello] IoCreateDevice = 0x%x\n", status);
- return status;
- }
- RtlInitUnicodeString(&ustrLinkName, LINK_NAME);
- status = IoCreateSymbolicLink(&ustrLinkName, &ustrDevName);
-
- if(!NT_SUCCESS(status)) {
- dprintf("[hello] IoCreateSymbolicLink = 0x%x\n", status);
- IoDeleteDevice(device_object);
- return status;
- }
- device_extension = (PDEVICE_EXTENSION) device_object->DeviceExtension;
- InitializeListHead(&device_extension->list_head);
- KeInitializeSpinLock(&device_extension->list_lock);
-
- KeInitializeEvent( &device_extension->request_event,
- NotificationEvent,
- FALSE);
-
- KeInitializeTimerEx(&device_extension->my_timer, NotificationTimer);
-
- KeInitializeDpc(&device_extension->KiTimerExpireDpc,
- (PKDEFERRED_ROUTINE)KiTimerExpirationFunction, (PVOID) device_object);
-
-
- KeSetTimerEx(&device_extension->my_timer, duetime, POLLING_INTERVAL, &device_extension->KiTimerExpireDpc);
-
-
-
- device_extension->terminate_thread = FALSE;
-
- status = PsCreateSystemThread(
- &thread_handle,
- (ACCESS_MASK) 0L,
- NULL,
- NULL,
- NULL,
- ThreadFunc,
- device_object
- );
- if (!NT_SUCCESS(status))
- {
- IoDeleteDevice(device_object);
- return status;
- }
-
- status = ObReferenceObjectByHandle(
- thread_handle,
- THREAD_ALL_ACCESS,
- NULL,
- KernelMode,
- &device_extension->thread_pointer,
- NULL
- );
-
- if (!NT_SUCCESS(status))
- {
- ZwClose(thread_handle);
- device_extension->terminate_thread = TRUE;
-
- KeSetEvent(
- &device_extension->request_event,
- (KPRIORITY) 0,
- FALSE
- );
- IoDeleteDevice(device_object);
- return status;
- }
-
- ZwClose(thread_handle);
- return STATUS_SUCCESS;
- }
- VOID
- KiTimerExpirationFunction (
- IN struct _KDPC *Dpc,
- IN PVOID DeferredContext,
- IN PVOID SystemArgument1,
- IN PVOID SystemArgument2
- )
- {
- PDEVICE_OBJECT pDevObj = (PDEVICE_OBJECT)DeferredContext;
- PDEVICE_EXTENSION device_extension = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;
-
-
-
- dprintf("haha dpc function work\n");
- KeSetEvent(&device_extension->request_event,
- (KPRIORITY) 0,
- FALSE);
- };
- NTSTATUS ThreadFunc ( IN PVOID Context)
- {
- PFILE_OBJECT ConnectionFileObject, AddressFileObject;
- HANDLE AddressHandle, ConnectionHandle;
- NTSTATUS Status;
- IO_STATUS_BLOCK IoStatus;
- KEVENT Event;
- PDEVICE_OBJECT device_object;
- PDEVICE_EXTENSION device_extension;
- device_object = (PDEVICE_OBJECT) Context;
- device_extension = (PDEVICE_EXTENSION) device_object->DeviceExtension;
-
- KeSetPriorityThread(KeGetCurrentThread(), LOW_REALTIME_PRIORITY);
-
-
-
- for (;;)
- {
- do
- {
- dprintf("thread work ok !!\n");
- goto failselabel;
- } while (TRUE);
- failselabel:
- KeWaitForSingleObject(
- &device_extension->request_event,
- Executive,
- KernelMode,
- FALSE,
- NULL
- );
-
-
-
-
-
- KeResetEvent(&device_extension->request_event);
- if ( device_extension->terminate_thread )
- {
- PsTerminateSystemThread(STATUS_SUCCESS);
- }
- }
- dprintf("never be here !\n");
- return Status;
- }
-
- VOID
- DriverUnload(
- PDRIVER_OBJECT pDriverObj
- )
- {
- PDEVICE_EXTENSION device_extension;
- UNICODE_STRING strLink;
- RtlInitUnicodeString(&strLink, LINK_NAME);
- device_extension = (PDEVICE_EXTENSION) pDriverObj->DeviceObject->DeviceExtension;
-
- if (KeCancelTimer(&device_extension->my_timer) == FALSE)
- {
-
- dprintf( " no timer active at terminate\n");
- }
- device_extension->terminate_thread = TRUE;
- KeSetEvent(
- &device_extension->request_event,
- (KPRIORITY) 0,
- FALSE
- );
- KeWaitForSingleObject(
- device_extension->thread_pointer,
- Executive,
- KernelMode,
- FALSE,
- NULL
- );
- ObDereferenceObject(device_extension->thread_pointer);
- IoDeleteSymbolicLink(&strLink);
- IoDeleteDevice(pDriverObj->DeviceObject);
- dprintf("[hello] Unloaded\n");
- }
-
- NTSTATUS
- DispatchCreate(
- PDEVICE_OBJECT pDevObj,
- PIRP pIrp
- )
- {
- pIrp->IoStatus.Status = STATUS_SUCCESS;
- pIrp->IoStatus.Information = 0;
- dprintf("[hello] IRP_MJ_CREATE\n");
- IoCompleteRequest(pIrp, IO_NO_INCREMENT);
- return STATUS_SUCCESS;
- }
-
- NTSTATUS
- DispatchClose(
- PDEVICE_OBJECT pDevObj,
- PIRP pIrp
- )
- {
- pIrp->IoStatus.Status = STATUS_SUCCESS;
- pIrp->IoStatus.Information = 0;
- dprintf("[hello] IRP_MJ_CLOSE\n");
- IoCompleteRequest(pIrp, IO_NO_INCREMENT);
- return STATUS_SUCCESS;
- }
-
- NTSTATUS
- DispatchIoctl(
- PDEVICE_OBJECT pDevObj,
- PIRP pIrp
- )
- {
- NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST;
- PIO_STACK_LOCATION pIrpStack;
- ULONG uIoControlCode;
- PVOID pIoBuffer;
- ULONG uInSize;
- ULONG uOutSize;
- pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
- uIoControlCode = pIrpStack->Parameters.DeviceIoControl.IoControlCode;
- pIoBuffer = pIrp->AssociatedIrp.SystemBuffer;
- uInSize = pIrpStack->Parameters.DeviceIoControl.InputBufferLength;
- uOutSize = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength;
- switch(uIoControlCode) {
- case IOCTL_HELLO: {
-
- dprintf("[hello] Hello\n");
- status = STATUS_SUCCESS;
- }
- break;
- }
- if(status == STATUS_SUCCESS)
- pIrp->IoStatus.Information = uOutSize;
- else
- pIrp->IoStatus.Information = 0;
-
-
- pIrp->IoStatus.Status = status;
- IoCompleteRequest(pIrp, IO_NO_INCREMENT);
- return status;
- }
|
|