时钟 IoTimer
2015-11-04 11:37
726 查看
/* 例程是在运行在DISPATCH_LEVEL的IRQL级别 例程中不能使用分页内存 另外在函数首部使用 #pragma LOCKEDCODE */ #include "Driver.h" #define DeviceName L"\\Device\\MyDDKDevice" #pragma INITCODE extern "C" NTSTATUS DriverEntry ( IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING pRegistryPath ) { NTSTATUS status; KdPrint(("Enter DriverEntry\n")); pDriverObject->DriverUnload = UnloadDriver; //设置派遣函数 /* ARRAY_SIZE 定义设备结构体的个数 #define ARRAY_SIZE(arr) (sizeof(arr)/sizeof((arr)[0]) + __must_be_array(arr)) */ for (int i = 0; i < arraysize(pDriverObject->MajorFunction); ++i) //ARRAY_SIZE 定义设备结构体的个数 pDriverObject->MajorFunction[i] = DispatchFunction; pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DeviceIoControl; //创建驱动设备对象 status = CreateDevice(pDriverObject); KdPrint(("Leave DriverEntry\n")); return status; } #pragma LOCKEDCODE VOID OnTimer( IN PDEVICE_OBJECT DeviceObject, IN PVOID Context) { PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; KdPrint(("Enter OnTimer!\n")); //将计数器自锁减一 InterlockedDecrement(&pDevExt->lTimerCount); /*如果计数器减到0,重新编程TIMER_OUT,整个过程是互锁运算 LONG __cdecl InterlockedCompareExchange( __inout LONG volatile *Destination, //当前值 __in LONG Exchange, //当比较值与当前值相同时 替换当前值 __in LONG Comparand //比较值 PVOID __cdecl InterlockedCompareExchangePointer( __inout PVOID volatile *Destination, __in PVOID Exchange, __in PVOID Comparand 这两个函数以原子方式执行一个测试和设置操作。对32位应用程序来说,这两个函数都对32位值进行操作; 在64位应用程序中,InterlockedCompareExchange对32位值进行操作而InterlockedCompareExchangePointer对64位值进行操作。 函数会将当前值(Destination指向的)与参数Comparand进行比较,如果两个值相同,那么函数会将*Destination修改为Exchange参数指定的值。 若不等,则*Destination保持不变。函数会返回*Destination原来的值。所有这些操作都是一个原子执行单元来完成的。 */ LONG previousCount = InterlockedCompareExchange(&pDevExt->lTimerCount,TIMER_OUT,0); //每隔三秒,计数器一个循环,输出以下log if (previousCount==0) { KdPrint(("%d seconds time out!\n",TIMER_OUT)); } //证明该线程运行在任意线程上下文的 /* PEPROCESS pEProcess = IoGetCurrentProcess(); PTSTR ProcessName = (PTSTR) ((ULONG)pEProcess + 0x174); */ PEPROCESS pEProcess = IoGetCurrentProcess(); PTSTR ProcessName = (PTSTR)((ULONG)pEProcess + 0x174);//即可得到用户进程 KdPrint(("The current process is %s\n",ProcessName)); } /************************************************************************ * 函数名称:CreateDevice * 功能描述:初始化设备对象 * 参数列表: pDriverObject:从I/O管理器中传进来的驱动对象 * 返回 值:返回初始化状态 *************************************************************************/ #pragma INITCODE NTSTATUS CreateDevice ( IN PDRIVER_OBJECT pDriverObject) { NTSTATUS status; PDEVICE_OBJECT pDevObj; PDEVICE_EXTENSION pDevExt; //创建设备名称 UNICODE_STRING devName; RtlInitUnicodeString(&devName,DeviceName); //创建设备 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); // 初始化IoTimer //创建符号链接 // 不进行Ring3层的交互 则不需要进行创建符号链接 NICODE_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 PAGEDCODE VOID UnloadDriver (IN PDRIVER_OBJECT pDriverObject) { PDEVICE_OBJECT pNextObj; 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 ); } } /************************************************************************ * 函数名称:HelloDDKDispatchRoutin * 功能描述:对读IRP进行处理 * 参数列表: pDevObj:功能设备对象 pIrp:从IO请求包 默认派遣例程 * 返回 值:返回状态 *************************************************************************/ #pragma PAGEDCODE NTSTATUS DispatchFunction(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)); else KdPrint(("\t%s\n", irpname[type])); NTSTATUS status = STATUS_SUCCESS; // 完成IRP pIrp->IoStatus.Status = status; pIrp->IoStatus.Information = 0; // bytes xfered IoCompleteRequest( pIrp, IO_NO_INCREMENT ); KdPrint(("Leave HelloDDKDispatchRoutin\n")); return status; } #pragma PAGEDCODE NTSTATUS DeviceIOControl(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp) { NTSTATUS status = STATUS_SUCCESS; KdPrint(("Enter HelloDDKDeviceIOControl\n")); //获得当前IRP堆栈 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 request case IOCTL_START_TIMER: { KdPrint(("IOCTL_START_TIMER\n")); pDevExt->lTimerCount = TIMER_OUT; IoStartTimer(pDevObj); //激活时钟 break; } case IOCTL_STOP: { KdPrint(("IOCTL_STOP\n")); IoStopTimer(pDevObj); // 停止时钟 break; } default: status = STATUS_INVALID_VARIANT; } // 完成IRP pIrp->IoStatus.Status = status; pIrp->IoStatus.Information = info; // bytes xfered IoCompleteRequest( pIrp, IO_NO_INCREMENT ); KdPrint(("Leave HelloDDKDeviceIOControl\n")); return status; }
代码
相关文章推荐
- 分析JVM的性能利器-iotop和jstack
- 浅谈工业级物联网项目架构设计及实施
- STM32 IO口双向问题
- 浅谈工业级物联网项目架构设计及实施
- Java 网络编程[Elliotte R.H.] 中对InputStream.markSupported()方法的误解
- 华为的新突破-物联网的敏捷性开发
- HDU 4609 3-idiots
- UVA - 10881-Piotr's Ants-思路题/模拟
- 物联网核心协议—消息推送技术演进
- jaudiotagger获取MP3文件信息及封面图片
- Riot工程师:三步让你的游戏更新更快更小
- 计划继续深化学习物联网系统的相关知识 目前的WiFi模块基于ESP8266
- 谁将改变移动?--来自移动开发者大会的4个心动故事
- 一个大三的物联网专业学生的想法法
- 物联网探秘:那些来自传感器的数据都是如何上传至云端的?
- hdu 4609 3-idiots(FFT)
- 看看,这就是微软的“万物互联”系统 window10 IOT
- 看看,这就是微软的“万物互联”系统 window10 IOT
- 【物联网】OpenWrt SCP工具的使用
- 【物联网】OpenWrt编译和修改基础--预科