时钟 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
原文地址:https://www.cnblogs.com/yifi/p/4935463.html