I/O定时器_3秒执行一次_1秒执行一次

来源:互联网 发布:中云文化大数据靠谱吗 编辑:程序博客网 时间:2024/05/16 10:58
#include <windows.h>#include <stdio.h>//使用CTL_CODE必须加入winioctl.h#include <winioctl.h>#include "..\IO定时器\Ioctls.h"int main(){HANDLE hDevice = CreateFile(L"\\\\.\\HelloDDK",GENERIC_READ | GENERIC_WRITE,0,// share mode noneNULL,// no securityOPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL );// no templateif (hDevice == INVALID_HANDLE_VALUE){printf("Failed to obtain file handle to device: ""%s with Win32 error code: %d\n","MyWDMDevice", GetLastError() );return 1;}DWORD dwOutput;DeviceIoControl(hDevice, IOCTL_START_TIMER, NULL, 0, NULL, 0, &dwOutput, NULL);//将控制代码直接发送给指定的设备驱动程序,使相应的设备执行相应的操作。system("pause"); DeviceIoControl(hDevice, IOCTL_STOP, NULL, 0, NULL, 0, &dwOutput, NULL);CloseHandle(hDevice);system("pause");return 0;}
// IOCTLS.H -- IOCTL code definitions for fileio driver// Copyright (C) 1999 by Walter Oney// All rights reserved#ifndef IOCTLS_H#define IOCTLS_H#ifndef CTL_CODE#pragma message("CTL_CODE undefined. Include winioctl.h or wdm.h")#endif#define IOCTL_START_TIMER CTL_CODE(\FILE_DEVICE_UNKNOWN, \0x800, \METHOD_BUFFERED, \FILE_ANY_ACCESS)#define IOCTL_STOP CTL_CODE(\FILE_DEVICE_UNKNOWN, \0x801, \METHOD_IN_DIRECT, \FILE_ANY_ACCESS)#endif
/************************************************************************* 文件名称:Driver.h                                                 * 作    者:张帆* 完成日期:2007-11-1*************************************************************************/#pragma once#ifdef __cplusplusextern "C"{#endif#include <NTDDK.h>#ifdef __cplusplus}#endif #include "ioctls.h"#define PAGEDCODE code_seg("PAGE")#define LOCKEDCODE code_seg()#define INITCODE code_seg("INIT")#define PAGEDDATA data_seg("PAGE")#define LOCKEDDATA data_seg()#define INITDATA data_seg("INIT")#define arraysize(p) (sizeof(p)/sizeof((p)[0]))//设定3秒间隔时间#define TIMER_OUT4typedef struct _DEVICE_EXTENSION {PDEVICE_OBJECT pDevice;UNICODE_STRING ustrDeviceName;//设备名称UNICODE_STRING ustrSymLinkName;//符号链接名LONG lTimerCount;} DEVICE_EXTENSION, *PDEVICE_EXTENSION;// 函数声明NTSTATUS CreateDevice (IN PDRIVER_OBJECT pDriverObject);VOID HelloDDKUnload (IN PDRIVER_OBJECT pDriverObject);NTSTATUS HelloDDKDispatchRoutin(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp);NTSTATUS HelloDDKDeviceIOControl(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp);
/************************************************************************* 文件名称:Driver.cpp                                                 * 作    者:张帆* 完成日期:2007-11-1*************************************************************************/#include "Driver.h"/************************************************************************* 函数名称:DriverEntry* 功能描述:初始化驱动程序,定位和申请硬件资源,创建内核对象* 参数列表:      pDriverObject:从I/O管理器中传进来的驱动对象      pRegistryPath:驱动程序在注册表的中的路径* 返回 值:返回初始化驱动状态*************************************************************************/#pragma INITCODEextern "C" NTSTATUS DriverEntry (IN PDRIVER_OBJECT pDriverObject,IN PUNICODE_STRING pRegistryPath) {NTSTATUS status;KdPrint(("Enter DriverEntry\n"));//设置卸载函数pDriverObject->DriverUnload = HelloDDKUnload;//设置派遣函数for (int i = 0; i < arraysize(pDriverObject->MajorFunction); ++i)pDriverObject->MajorFunction[i] = HelloDDKDispatchRoutin;pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = HelloDDKDeviceIOControl;//创建驱动设备对象status = CreateDevice(pDriverObject);//IoStartTimer(pDriverObject->DeviceObject);KdPrint(("Leave DriverEntry\n"));return status;}#pragma LOCKEDCODEVOID OnTimer(IN PDEVICE_OBJECT DeviceObject,IN PVOID Context)//定时器回调函数{PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;KdPrint(("Enter OnTimer!\n"));//将计数器自锁减一InterlockedDecrement(&pDevExt->lTimerCount);//3秒计算机语言函数,该函数减小指定的变量,并检查值,可以保证同一时刻只有一个线程访问该变量,即保证增加操作的原子性。LONG previousCount = InterlockedCompareExchange(&pDevExt->lTimerCount,TIMER_OUT,0);//如果计数器减到0,重新编程TIMER_OUT,整个过程是互锁运算  扩展减到0 再弄成3//是把目标操作数(第1参数所指向的内存中的数)与一个值(第3参数)比较,如果相等,则用另一个值(第2参数)与目标操作数(第1参数所指向的内存中的数)交换;InterlockedExchange是不比较直接交换。//每隔三秒,计数器一个循环,输出以下logif (previousCount == 0)//返回值是 Destination(第一个参数) 指针的初始值{//KdPrint(("%d seconds time out!\n",TIMER_OUT));KdPrint(("这里是3秒执行一次"));}//证明该线程运行在任意线程上下文的    PEPROCESS pEProcess = IoGetCurrentProcess();    PTSTR ProcessName = (PTSTR)((ULONG)pEProcess + 0x174);//即可得到用户进程    KdPrint(("当前进程名%s\n",ProcessName));}/************************************************************************* 函数名称:CreateDevice* 功能描述:初始化设备对象* 参数列表:      pDriverObject:从I/O管理器中传进来的驱动对象* 返回 值:返回初始化状态*************************************************************************/#pragma INITCODENTSTATUS CreateDevice (IN PDRIVER_OBJECTpDriverObject) {NTSTATUS status;PDEVICE_OBJECT pDevObj;PDEVICE_EXTENSION pDevExt;//创建设备名称UNICODE_STRING devName;RtlInitUnicodeString(&devName,L"\\Device\\MyDDKDevice");//创建设备status = IoCreateDevice( pDriverObject,sizeof(DEVICE_EXTENSION),&(UNICODE_STRING)devName,FILE_DEVICE_UNKNOWN,0, TRUE,&pDevObj );if (!NT_SUCCESS(status))return status;pDevObj->Flags |= DO_DIRECT_IO;pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;pDevExt->pDevice = pDevObj;pDevExt->ustrDeviceName = devName;IoInitializeTimer(pDevObj,OnTimer,NULL);//io定时器初始化//创建符号链接UNICODE_STRING symLinkName;RtlInitUnicodeString(&symLinkName,L"\\??\\HelloDDK");pDevExt->ustrSymLinkName = symLinkName;status = IoCreateSymbolicLink( &symLinkName,&devName );if (!NT_SUCCESS(status)) {IoDeleteDevice( pDevObj );return status;}return STATUS_SUCCESS;}/************************************************************************* 函数名称:HelloDDKUnload* 功能描述:负责驱动程序的卸载操作* 参数列表:      pDriverObject:驱动对象* 返回 值:返回状态*************************************************************************/#pragma PAGEDCODEVOID HelloDDKUnload (IN PDRIVER_OBJECT pDriverObject) {PDEVICE_OBJECTpNextObj;KdPrint(("Enter DriverUnload\n"));pNextObj = pDriverObject->DeviceObject;//while (pNextObj != NULL) //{//PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)//pNextObj->DeviceExtension;////删除符号链接//UNICODE_STRING pLinkName = pDevExt->ustrSymLinkName;//IoDeleteSymbolicLink(&pLinkName);//pNextObj = pNextObj->NextDevice;//IoDeleteDevice( pDevExt->pDevice );//}UNICODE_STRING symLinkName;RtlInitUnicodeString(&symLinkName, L"\\??\\HelloDDK");pNextObj = pDriverObject->DeviceObject;//我的第一个设备          IoDeleteSymbolicLink(&symLinkName);//删除符号连接          IoDeleteDevice(pDriverObject->DeviceObject);//删除设备  }/************************************************************************* 函数名称:HelloDDKDispatchRoutin* 功能描述:对读IRP进行处理* 参数列表:      pDevObj:功能设备对象      pIrp:从IO请求包* 返回 值:返回状态*************************************************************************/#pragma PAGEDCODENTSTATUS HelloDDKDispatchRoutin(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrp) {KdPrint(("Enter HelloDDKDispatchRoutin\n"));PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrp);//建立一个字符串数组与IRP类型对应起来static char* irpname[] = {"IRP_MJ_CREATE","IRP_MJ_CREATE_NAMED_PIPE","IRP_MJ_CLOSE","IRP_MJ_READ","IRP_MJ_WRITE","IRP_MJ_QUERY_INFORMATION","IRP_MJ_SET_INFORMATION","IRP_MJ_QUERY_EA","IRP_MJ_SET_EA","IRP_MJ_FLUSH_BUFFERS","IRP_MJ_QUERY_VOLUME_INFORMATION","IRP_MJ_SET_VOLUME_INFORMATION","IRP_MJ_DIRECTORY_CONTROL","IRP_MJ_FILE_SYSTEM_CONTROL","IRP_MJ_DEVICE_CONTROL","IRP_MJ_INTERNAL_DEVICE_CONTROL","IRP_MJ_SHUTDOWN","IRP_MJ_LOCK_CONTROL","IRP_MJ_CLEANUP","IRP_MJ_CREATE_MAILSLOT","IRP_MJ_QUERY_SECURITY","IRP_MJ_SET_SECURITY","IRP_MJ_POWER","IRP_MJ_SYSTEM_CONTROL","IRP_MJ_DEVICE_CHANGE","IRP_MJ_QUERY_QUOTA","IRP_MJ_SET_QUOTA","IRP_MJ_PNP",};UCHAR type = stack->MajorFunction;if (type >= arraysize(irpname))KdPrint((" - Unknown IRP, major type %X\n", type));elseKdPrint(("\t%s\n", irpname[type]));NTSTATUS status = STATUS_SUCCESS;// 完成IRPpIrp->IoStatus.Status = status;pIrp->IoStatus.Information = 0;// bytes xferedIoCompleteRequest( pIrp, IO_NO_INCREMENT );KdPrint(("Leave HelloDDKDispatchRoutin\n"));return status;}#pragma PAGEDCODENTSTATUS HelloDDKDeviceIOControl(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrp){NTSTATUS status = STATUS_SUCCESS;KdPrint(("Enter HelloDDKDeviceIOControl\n"));//得到当前堆栈PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrp);//得到输入缓冲区大小ULONG cbin = stack->Parameters.DeviceIoControl.InputBufferLength;//得到输出缓冲区大小ULONG cbout = stack->Parameters.DeviceIoControl.OutputBufferLength;//得到IOCTL码ULONG code = stack->Parameters.DeviceIoControl.IoControlCode;PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;ULONG info = 0;switch (code){// process requestcase IOCTL_START_TIMER:{KdPrint(("IOCTL_START_TIMER\n"));pDevExt->lTimerCount = TIMER_OUT;//时间间隔3秒IoStartTimer(pDevObj);break;}case IOCTL_STOP:{KdPrint(("IOCTL_STOP\n"));IoStopTimer(pDevObj);break;}default:status = STATUS_INVALID_VARIANT;}// 完成IRPpIrp->IoStatus.Status = status;pIrp->IoStatus.Information = info;// bytes xferedIoCompleteRequest( pIrp, IO_NO_INCREMENT );KdPrint(("Leave HelloDDKDeviceIOControl\n"));return status;}