• 时钟 IoTimer


      1 /*
      2     例程是在运行在DISPATCH_LEVEL的IRQL级别
      3     例程中不能使用分页内存 
      4     另外在函数首部使用 #pragma LOCKEDCODE
      5 */
      6 
      7 #include "Driver.h"
      8 
      9 #define DeviceName L"\Device\MyDDKDevice"
     10 
     11 #pragma INITCODE
     12 extern "C" NTSTATUS DriverEntry (
     13             IN PDRIVER_OBJECT pDriverObject,
     14             IN PUNICODE_STRING pRegistryPath    ) 
     15 {
     16     NTSTATUS status;
     17     KdPrint(("Enter DriverEntry
    "));
     18 
     19     pDriverObject->DriverUnload = UnloadDriver;
     20 
     21     //设置派遣函数
     22 
     23     /*
     24         ARRAY_SIZE 定义设备结构体的个数
     25         #define ARRAY_SIZE(arr) (sizeof(arr)/sizeof((arr)[0]) + __must_be_array(arr))
     26 
     27     */
     28 
     29     for (int i = 0; i < arraysize(pDriverObject->MajorFunction); ++i)    //ARRAY_SIZE 定义设备结构体的个数
     30         pDriverObject->MajorFunction[i] = DispatchFunction;
     31 
     32 
     33 
     34     pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DeviceIoControl;
     35     
     36     //创建驱动设备对象
     37     status = CreateDevice(pDriverObject);
     38 
     39     KdPrint(("Leave DriverEntry
    "));
     40     return status;
     41 }
     42 
     43 #pragma LOCKEDCODE
     44 VOID OnTimer(
     45     IN PDEVICE_OBJECT DeviceObject,
     46     IN PVOID Context)
     47 {
     48     PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)
     49         DeviceObject->DeviceExtension;
     50     KdPrint(("Enter OnTimer!
    "));
     51 
     52     //将计数器自锁减一
     53     InterlockedDecrement(&pDevExt->lTimerCount);
     54     
     55     /*如果计数器减到0,重新编程TIMER_OUT,整个过程是互锁运算
     56     LONG __cdecl InterlockedCompareExchange(
     57 
     58       __inout  LONG volatile *Destination, //当前值
     59 
     60       __in     LONG Exchange, //当比较值与当前值相同时 替换当前值
     61 
     62       __in     LONG Comparand //比较值
     63 
     64     PVOID __cdecl InterlockedCompareExchangePointer(
     65 
     66       __inout  PVOID volatile *Destination,
     67 
     68       __in     PVOID Exchange,
     69 
     70       __in     PVOID Comparand
     71 
     72     这两个函数以原子方式执行一个测试和设置操作。对32位应用程序来说,这两个函数都对32位值进行操作;
     73     在64位应用程序中,InterlockedCompareExchange对32位值进行操作而InterlockedCompareExchangePointer对64位值进行操作。
     74     函数会将当前值(Destination指向的)与参数Comparand进行比较,如果两个值相同,那么函数会将*Destination修改为Exchange参数指定的值。
     75     若不等,则*Destination保持不变。函数会返回*Destination原来的值。所有这些操作都是一个原子执行单元来完成的。
     76 
     77     */
     78     LONG previousCount = InterlockedCompareExchange(&pDevExt->lTimerCount,TIMER_OUT,0);
     79 
     80     //每隔三秒,计数器一个循环,输出以下log
     81     if (previousCount==0)
     82     {
     83         KdPrint(("%d seconds time out!
    ",TIMER_OUT));
     84     }
     85 
     86     //证明该线程运行在任意线程上下文的
     87     /*
     88     PEPROCESS pEProcess = IoGetCurrentProcess();
     89     PTSTR ProcessName = (PTSTR) ((ULONG)pEProcess + 0x174);
     90     */
     91     PEPROCESS pEProcess = IoGetCurrentProcess();
     92    
     93     PTSTR ProcessName = (PTSTR)((ULONG)pEProcess + 0x174);//即可得到用户进程
     94 
     95     KdPrint(("The current process is %s
    ",ProcessName));
     96 }
     97 
     98 
     99 /************************************************************************
    100 * 函数名称:CreateDevice
    101 * 功能描述:初始化设备对象
    102 * 参数列表:
    103       pDriverObject:从I/O管理器中传进来的驱动对象
    104 * 返回 值:返回初始化状态
    105 *************************************************************************/
    106 #pragma INITCODE
    107 NTSTATUS CreateDevice (
    108         IN PDRIVER_OBJECT    pDriverObject) 
    109 {
    110     NTSTATUS status;
    111     PDEVICE_OBJECT pDevObj;
    112     PDEVICE_EXTENSION pDevExt;
    113     
    114     //创建设备名称
    115     UNICODE_STRING devName;
    116     RtlInitUnicodeString(&devName,DeviceName);
    117     
    118     //创建设备
    119     status = IoCreateDevice( pDriverObject,
    120                         sizeof(DEVICE_EXTENSION),
    121                         &(UNICODE_STRING)devName,
    122                         FILE_DEVICE_UNKNOWN,
    123                         0, TRUE,
    124                         &pDevObj );
    125     if (!NT_SUCCESS(status))
    126         return status;
    127 
    128     pDevObj->Flags |= DO_DIRECT_IO;
    129     pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;
    130     pDevExt->pDevice = pDevObj;
    131     pDevExt->ustrDeviceName = devName;
    132 
    133     IoInitializeTimer(pDevObj,OnTimer,NULL);    // 初始化IoTimer
    134 
    135     //创建符号链接
    136     // 不进行Ring3层的交互  则不需要进行创建符号链接
    137     NICODE_STRING symLinkName;
    138     RtlInitUnicodeString(&symLinkName,L"\??\HelloDDK");
    139     pDevExt->ustrSymLinkName = symLinkName;
    140     status = IoCreateSymbolicLink( &symLinkName,&devName );
    141     if (!NT_SUCCESS(status)) 
    142     {
    143         IoDeleteDevice( pDevObj );
    144         return status;
    145     }
    146     return STATUS_SUCCESS;
    147 }
    148 
    149 /************************************************************************
    150 * 函数名称:HelloDDKUnload
    151 * 功能描述:负责驱动程序的卸载操作
    152 * 参数列表:
    153       pDriverObject:驱动对象
    154 * 返回 值:返回状态
    155 *************************************************************************/
    156 #pragma PAGEDCODE
    157 VOID UnloadDriver (IN PDRIVER_OBJECT pDriverObject) 
    158 {
    159     PDEVICE_OBJECT    pNextObj;
    160     KdPrint(("Enter DriverUnload
    "));
    161     pNextObj = pDriverObject->DeviceObject;
    162     while (pNextObj != NULL) 
    163     {
    164         PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)
    165             pNextObj->DeviceExtension;
    166         //删除符号链接
    167         UNICODE_STRING pLinkName = pDevExt->ustrSymLinkName;
    168         IoDeleteSymbolicLink(&pLinkName);
    169         pNextObj = pNextObj->NextDevice;
    170         IoDeleteDevice( pDevExt->pDevice );
    171     }
    172 }
    173 
    174 /************************************************************************
    175 * 函数名称:HelloDDKDispatchRoutin
    176 * 功能描述:对读IRP进行处理
    177 * 参数列表:
    178       pDevObj:功能设备对象
    179       pIrp:从IO请求包
    180 
    181 
    182       默认派遣例程
    183 * 返回 值:返回状态
    184 *************************************************************************/
    185 #pragma PAGEDCODE
    186 NTSTATUS DispatchFunction(IN PDEVICE_OBJECT pDevObj,
    187                                  IN PIRP pIrp) 
    188 {
    189 
    190 
    191     KdPrint(("Enter HelloDDKDispatchRoutin
    "));
    192 
    193     PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrp);
    194     //建立一个字符串数组与IRP类型对应起来
    195     static char* irpname[] = 
    196     {
    197         "IRP_MJ_CREATE",
    198         "IRP_MJ_CREATE_NAMED_PIPE",
    199         "IRP_MJ_CLOSE",
    200         "IRP_MJ_READ",
    201         "IRP_MJ_WRITE",
    202         "IRP_MJ_QUERY_INFORMATION",
    203         "IRP_MJ_SET_INFORMATION",
    204         "IRP_MJ_QUERY_EA",
    205         "IRP_MJ_SET_EA",
    206         "IRP_MJ_FLUSH_BUFFERS",
    207         "IRP_MJ_QUERY_VOLUME_INFORMATION",
    208         "IRP_MJ_SET_VOLUME_INFORMATION",
    209         "IRP_MJ_DIRECTORY_CONTROL",
    210         "IRP_MJ_FILE_SYSTEM_CONTROL",
    211         "IRP_MJ_DEVICE_CONTROL",
    212         "IRP_MJ_INTERNAL_DEVICE_CONTROL",
    213         "IRP_MJ_SHUTDOWN",
    214         "IRP_MJ_LOCK_CONTROL",
    215         "IRP_MJ_CLEANUP",
    216         "IRP_MJ_CREATE_MAILSLOT",
    217         "IRP_MJ_QUERY_SECURITY",
    218         "IRP_MJ_SET_SECURITY",
    219         "IRP_MJ_POWER",
    220         "IRP_MJ_SYSTEM_CONTROL",
    221         "IRP_MJ_DEVICE_CHANGE",
    222         "IRP_MJ_QUERY_QUOTA",
    223         "IRP_MJ_SET_QUOTA",
    224         "IRP_MJ_PNP",
    225     };
    226 
    227     UCHAR type = stack->MajorFunction;
    228     if (type >= arraysize(irpname))
    229         KdPrint((" - Unknown IRP, major type %X
    ", type));
    230     else
    231         KdPrint(("	%s
    ", irpname[type]));
    232 
    233     NTSTATUS status = STATUS_SUCCESS;
    234     // 完成IRP
    235     pIrp->IoStatus.Status = status;
    236     pIrp->IoStatus.Information = 0;    // bytes xfered
    237     IoCompleteRequest( pIrp, IO_NO_INCREMENT );
    238 
    239     KdPrint(("Leave HelloDDKDispatchRoutin
    "));
    240 
    241     return status;
    242 }
    243 
    244 #pragma PAGEDCODE
    245 NTSTATUS DeviceIOControl(IN PDEVICE_OBJECT pDevObj,
    246                                  IN PIRP pIrp)
    247 {
    248     NTSTATUS status = STATUS_SUCCESS;
    249     KdPrint(("Enter HelloDDKDeviceIOControl
    "));
    250 
    251     //获得当前IRP堆栈
    252     PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrp);
    253     //得到输入缓冲区大小
    254     ULONG cbin = stack->Parameters.DeviceIoControl.InputBufferLength;
    255     //得到输出缓冲区大小
    256     ULONG cbout = stack->Parameters.DeviceIoControl.OutputBufferLength;
    257     //得到IOCTL码
    258     ULONG code = stack->Parameters.DeviceIoControl.IoControlCode;
    259 
    260     PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)
    261         pDevObj->DeviceExtension;
    262 
    263     ULONG info = 0;
    264 
    265     switch (code)
    266     {                        // process request
    267         case IOCTL_START_TIMER:
    268         {
    269             KdPrint(("IOCTL_START_TIMER
    "));
    270             pDevExt->lTimerCount = TIMER_OUT;
    271             IoStartTimer(pDevObj);        //激活时钟
    272             break;
    273         }
    274         case IOCTL_STOP:
    275         {
    276             KdPrint(("IOCTL_STOP
    "));
    277             IoStopTimer(pDevObj);        // 停止时钟
    278             break;
    279         }
    280         default:
    281             status = STATUS_INVALID_VARIANT;
    282     }
    283 
    284     // 完成IRP
    285     pIrp->IoStatus.Status = status;
    286     pIrp->IoStatus.Information = info;    // bytes xfered
    287     IoCompleteRequest( pIrp, IO_NO_INCREMENT );
    288 
    289     KdPrint(("Leave HelloDDKDeviceIOControl
    "));
    290 
    291     return status;
    292 }
    代码
    爱程序 不爱bug 爱生活 不爱黑眼圈 我和你们一样 我和你们不一样 我不是凡客 我要做geek
  • 相关阅读:
    在ASP.NET 2.0中使用WebParts
    Asp.net生成静态页面原理
    提高ASP.Net应用程序性能的十大方法
    Web2.0之Tag标签原理实现浅析
    ASP.NET 2.0中的URL映射
    动态加载控件UserControl到页面上:视图状态问题
    C#自动登录网页浏览页面 抓取数据
    .NET Framework 类库提供的命名空间
    一个用于热部署的框架设想
    重构如何进行?
  • 原文地址:https://www.cnblogs.com/yifi/p/4935463.html
Copyright © 2020-2023  润新知