关于内核定时器,DPC,线程的使用

[cpp]  view plain  copy
  1. 关于内核定时器,及DPC的使用,看来一些代码,这个估计是比较规范的用法了,很基础,希望对新手有帮助  
  2. 注意,这里的定时器不太精确!  
[cpp]  view plain  copy
  1. #include <ntddk.h>  
  2. typedef struct _DEVICE_EXTENSION {  
  3.       
  4.     LIST_ENTRY      list_head;  
  5.     KSPIN_LOCK      list_lock;      
  6.     PVOID           thread_pointer;  
  7.     BOOLEAN            terminate_thread;      
  8.     KEVENT          request_event;  
  9.     KTIMER            my_timer;  
  10.     KDPC            KiTimerExpireDpc;      
  11. } DEVICE_EXTENSION, *PDEVICE_EXTENSION;  
  12. #define dprintf if (DBG) DbgPrint  
  13. #define nprintf DbgPrint  
  14. #define DEVICE_NAME L"\\Device\\devhello" // Driver Name  
  15. #define LINK_NAME L"\\DosDevices\\hello"  // Link Name  
  16. //  
  17. // The device driver IOCTLs  
  18. //  
  19. #define IOCTL_BASE    0x800  
  20. #define MY_CTL_CODE(i) \  
  21. CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_BASE+i, METHOD_BUFFERED, FILE_ANY_ACCESS)  
  22. #define IOCTL_HELLO    MY_CTL_CODE(0)  
  23. /  
  24. //函数声明  
  25. NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pRegistryString);  
  26. NTSTATUS DispatchCreate(PDEVICE_OBJECT pDevObj, PIRP pIrp);  
  27. NTSTATUS DispatchClose(PDEVICE_OBJECT pDevObj, PIRP pIrp);  
  28. VOID     DriverUnload(PDRIVER_OBJECT pDriverObj);  
  29. NTSTATUS DispatchIoctl(PDEVICE_OBJECT pDevObj, PIRP pIrp);  
  30. VOID  
  31. KiTimerExpirationFunction (  
  32.                            IN struct _KDPC  *Dpc,  
  33.                            IN PVOID  DeferredContext,  
  34.                            IN PVOID  SystemArgument1,  
  35.                            IN PVOID  SystemArgument2  
  36.                            );  
  37. NTSTATUS ThreadFunc ( IN PVOID Context);  
  38. /  
  39.   
  40. NTSTATUS   
  41. DriverEntry(  
  42.     PDRIVER_OBJECT pDriverObj,   
  43.     PUNICODE_STRING pRegistryString  
  44.     )  
  45. {  
  46.     NTSTATUS status = STATUS_SUCCESS;  
  47.     UNICODE_STRING ustrLinkName;  
  48.     UNICODE_STRING ustrDevName;      
  49.     PDEVICE_OBJECT device_object;  
  50.     PDEVICE_EXTENSION device_extension;  
  51.     HANDLE  thread_handle;  
  52. /* 
  53.     在驱动中是以100纳秒为单位的 
  54.     1000纳秒=1微秒 
  55.     1000微秒=1毫秒 
  56.     1000毫秒=1秒    10*1000*1000 
  57. */  
  58.     LARGE_INTEGER duetime = {0};  
  59.     #define POLLING_INTERVAL 3000  
  60.     dprintf("[hello] DriverEntry\n");  
  61.       
  62.     pDriverObj->MajorFunction[IRP_MJ_CREATE] = DispatchCreate;  
  63.     pDriverObj->MajorFunction[IRP_MJ_CLOSE] = DispatchClose;  
  64.     pDriverObj->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchIoctl;  
  65.     pDriverObj->DriverUnload = DriverUnload;  
  66.   
  67.     RtlInitUnicodeString(&ustrDevName, DEVICE_NAME);  
  68.     status = IoCreateDevice(pDriverObj,   
  69.                 sizeof(DEVICE_EXTENSION),  
  70.                 &ustrDevName,   
  71.                 FILE_DEVICE_UNKNOWN,  
  72.                 0,  
  73.                 FALSE,  
  74.                 &device_object);  
  75.     if(!NT_SUCCESS(status))    {  
  76.         dprintf("[hello] IoCreateDevice = 0x%x\n", status);  
  77.         return status;  
  78.     }  
  79.     RtlInitUnicodeString(&ustrLinkName, LINK_NAME);  
  80.     status = IoCreateSymbolicLink(&ustrLinkName, &ustrDevName);   
  81.       
  82.     if(!NT_SUCCESS(status)) {  
  83.         dprintf("[hello] IoCreateSymbolicLink = 0x%x\n", status);  
  84.         IoDeleteDevice(device_object);    
  85.         return status;  
  86.     }  
  87.     device_extension = (PDEVICE_EXTENSION) device_object->DeviceExtension;  
  88.     InitializeListHead(&device_extension->list_head);      
  89.     KeInitializeSpinLock(&device_extension->list_lock);  
  90.       
  91.     KeInitializeEvent(    &device_extension->request_event,  
  92.         NotificationEvent,  
  93.                          FALSE);  
  94. //    KeInitializeTimer(&my_timer);//这是个旧的函数  
  95.     KeInitializeTimerEx(&device_extension->my_timer, NotificationTimer);  
  96.     // 初始化定时器过期的DPC对象    
  97.     KeInitializeDpc(&device_extension->KiTimerExpireDpc,  
  98.     (PKDEFERRED_ROUTINE)KiTimerExpirationFunction, (PVOID) device_object);  
  99. //    KeSetTimer(&my_timer,timeout,&KiTimerExpireDpc); 仅仅只能设置一次  
  100. //    KeSetTimerEx(&my_timer, timeout, period, &KiTimerExpireDpc);这个可以循环设置  
  101.     KeSetTimerEx(&device_extension->my_timer, duetime, POLLING_INTERVAL, &device_extension->KiTimerExpireDpc);    
  102. //    KeSetTimerEx语句启动周期定时器。由于duetime参数是0,  
  103. //    所以定时器立即进入信号态。  
  104. //  然后每隔POLLING_INTERVAL=3秒触发一次。  
  105.     device_extension->terminate_thread = FALSE;  
  106.       
  107.     status = PsCreateSystemThread(  
  108.         &thread_handle,  
  109.         (ACCESS_MASK) 0L,  
  110.         NULL,  
  111.         NULL,  
  112.         NULL,  
  113.         ThreadFunc,  
  114.         device_object  
  115.         );  
  116.     if (!NT_SUCCESS(status))  
  117.     {  
  118.         IoDeleteDevice(device_object);  
  119.         return status;  
  120.     }  
  121.       
  122.     status = ObReferenceObjectByHandle(  
  123.         thread_handle,  
  124.         THREAD_ALL_ACCESS,  
  125.         NULL,  
  126.         KernelMode,  
  127.         &device_extension->thread_pointer,  
  128.         NULL  
  129.         );  
  130.       
  131.     if (!NT_SUCCESS(status))  
  132.     {  
  133.         ZwClose(thread_handle);  
  134.         device_extension->terminate_thread = TRUE;//如果出错就关闭创建的线程  
  135.           
  136.         KeSetEvent(  
  137.             &device_extension->request_event,  
  138.             (KPRIORITY) 0,  
  139.             FALSE  
  140.             );  
  141.         IoDeleteDevice(device_object);      
  142.         return status;  
  143.     }  
  144.       
  145.     ZwClose(thread_handle);  
  146.     return STATUS_SUCCESS;  
  147. }  
  148. VOID  
  149. KiTimerExpirationFunction (  
  150.            IN struct _KDPC  *Dpc,  
  151.            IN PVOID  DeferredContext,  
  152.            IN PVOID  SystemArgument1,  
  153.            IN PVOID  SystemArgument2  
  154.            )  
  155. {      
  156. PDEVICE_OBJECT pDevObj = (PDEVICE_OBJECT)DeferredContext;  
  157. PDEVICE_EXTENSION device_extension = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;  
  158. //kesetevent 必需在较低级别用  
  159. //ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);  
  160. //dprintf("level in timer function  is %x\n",KeGetCurrentIrql());  
  161. dprintf("haha dpc function work\n");  
  162. KeSetEvent(&device_extension->request_event,  
  163.             (KPRIORITY) 0,  
  164.             FALSE);  
  165. };  
  166. NTSTATUS ThreadFunc ( IN PVOID Context)  
  167. {   
  168.     PFILE_OBJECT ConnectionFileObject, AddressFileObject;   
  169.     HANDLE AddressHandle, ConnectionHandle;   
  170.     NTSTATUS Status;   
  171.     IO_STATUS_BLOCK IoStatus;  
  172.     KEVENT Event;  
  173.     PDEVICE_OBJECT      device_object;  
  174.     PDEVICE_EXTENSION   device_extension;  
  175.     device_object = (PDEVICE_OBJECT) Context;  
  176.     device_extension = (PDEVICE_EXTENSION) device_object->DeviceExtension;  
  177.       
  178.     KeSetPriorityThread(KeGetCurrentThread(), LOW_REALTIME_PRIORITY);  
  179. //****************************  
  180. //****************************  
  181. //开始工作   此处用2重循环,你可以添加实际的代码  
  182. for (;;)  
  183. {      
  184.     do   
  185.     {  
  186.        dprintf("thread work ok !!\n");  
  187.        goto failselabel;  
  188.       } while (TRUE);  
  189. failselabel:  
  190.    KeWaitForSingleObject(  
  191.        &device_extension->request_event,  
  192.        Executive,  
  193.        KernelMode,  
  194.        FALSE,  
  195.        NULL  
  196.        );//在这儿等  
  197.     //KeClearEvent(&Event);//清除一下试试  
  198.            //killvxk 2007-01-31 11:18   
  199.     //严重提醒不要使用KeClearEvent(&Event);   
  200.     //如果你还要用那个事件就不要用那个Clear,要其它手段~如果你不需要那个event了,  
  201.            //那你应该在thread里判断下~   
  202.    KeResetEvent(&device_extension->request_event);  
  203.    if (  device_extension->terminate_thread )  
  204.     {  
  205.       PsTerminateSystemThread(STATUS_SUCCESS);  
  206.     }  
  207. }  
  208. dprintf("never be here !\n");  
  209.     return Status;   
  210. }  
  211.   
  212. VOID   
  213. DriverUnload(  
  214.     PDRIVER_OBJECT pDriverObj  
  215.     )  
  216. {      
  217.     PDEVICE_EXTENSION   device_extension;  
  218.     UNICODE_STRING strLink;  
  219.     RtlInitUnicodeString(&strLink, LINK_NAME);  
  220.     device_extension = (PDEVICE_EXTENSION) pDriverObj->DeviceObject->DeviceExtension;  
  221. //停止创建的线程  
  222.     if (KeCancelTimer(&device_extension->my_timer) == FALSE)  
  223.     {  
  224.         //    KeCancelTimer(&device_extension->my_timer);//取消定时器  
  225.         dprintf( " no timer active at terminate\n");  
  226.     }  
  227.     device_extension->terminate_thread = TRUE;//停止线程  
  228.     KeSetEvent(  
  229.         &device_extension->request_event,  
  230.         (KPRIORITY) 0,  
  231.         FALSE  
  232.         );  
  233.     KeWaitForSingleObject(  
  234.         device_extension->thread_pointer,//等待线程对象结束,注意哦,是对象  
  235.         Executive,  
  236.         KernelMode,  
  237.         FALSE,  
  238.         NULL  
  239.         );  
  240.     ObDereferenceObject(device_extension->thread_pointer);  
  241.     IoDeleteSymbolicLink(&strLink);  
  242.     IoDeleteDevice(pDriverObj->DeviceObject);  
  243.     dprintf("[hello] Unloaded\n");  
  244. }  
  245.   
  246. NTSTATUS   
  247. DispatchCreate(  
  248.     PDEVICE_OBJECT pDevObj,   
  249.     PIRP pIrp  
  250.     )  
  251. {  
  252.     pIrp->IoStatus.Status = STATUS_SUCCESS;  
  253.     pIrp->IoStatus.Information = 0;  
  254.     dprintf("[hello] IRP_MJ_CREATE\n");  
  255.     IoCompleteRequest(pIrp, IO_NO_INCREMENT);  
  256.     return STATUS_SUCCESS;  
  257. }  
  258.   
  259. NTSTATUS   
  260. DispatchClose(  
  261.     PDEVICE_OBJECT pDevObj,   
  262.     PIRP pIrp  
  263.     )  
  264. {  
  265.     pIrp->IoStatus.Status = STATUS_SUCCESS;  
  266.     pIrp->IoStatus.Information = 0;  
  267.     dprintf("[hello] IRP_MJ_CLOSE\n");  
  268.     IoCompleteRequest(pIrp, IO_NO_INCREMENT);  
  269.     return STATUS_SUCCESS;  
  270. }  
  271.   
  272. NTSTATUS   
  273. DispatchIoctl(  
  274.     PDEVICE_OBJECT pDevObj,   
  275.     PIRP pIrp  
  276.     )  
  277. {  
  278.     NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST;  
  279.     PIO_STACK_LOCATION pIrpStack;  
  280.     ULONG uIoControlCode;  
  281.     PVOID pIoBuffer;  
  282.     ULONG uInSize;  
  283.     ULONG uOutSize;  
  284.     pIrpStack = IoGetCurrentIrpStackLocation(pIrp);  
  285.     uIoControlCode = pIrpStack->Parameters.DeviceIoControl.IoControlCode;  
  286.     pIoBuffer = pIrp->AssociatedIrp.SystemBuffer;  
  287.     uInSize = pIrpStack->Parameters.DeviceIoControl.InputBufferLength;  
  288.     uOutSize = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength;  
  289.     switch(uIoControlCode) {  
  290.         case IOCTL_HELLO: {  
  291.               
  292.             dprintf("[hello] Hello\n");  
  293.             status = STATUS_SUCCESS;  
  294.         }  
  295.         break;  
  296.     }  
  297.     if(status == STATUS_SUCCESS)  
  298.         pIrp->IoStatus.Information = uOutSize;  
  299.     else  
  300.         pIrp->IoStatus.Information = 0;  
  301.       
  302.     /  
  303.     pIrp->IoStatus.Status = status;  
  304.     IoCompleteRequest(pIrp, IO_NO_INCREMENT);  
  305.     return status;  
  306. }  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值