等待4种

来源:互联网 发布:jsp项目绑定域名 编辑:程序博客网 时间:2024/05/21 06:38
#include <windows.h>#include <stdio.h>//使用CTL_CODE必须加入winioctl.h#include <winioctl.h>#include "..\等待4种_\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","MyDDKDevice", GetLastError() );return 1;}DWORD dwOutput;DWORD dwMicroSecond = 1000;DeviceIoControl(hDevice, IOCTL_WAIT_METHOD1, &dwMicroSecond, sizeof(DWORD), NULL, 0, &dwOutput, NULL);system("pause");DeviceIoControl(hDevice, IOCTL_WAIT_METHOD2, &dwMicroSecond, sizeof(DWORD), NULL, 0, &dwOutput, NULL);system("pause");DeviceIoControl(hDevice, IOCTL_WAIT_METHOD3, &dwMicroSecond, sizeof(DWORD), NULL, 0, &dwOutput, NULL);system("pause");DeviceIoControl(hDevice, IOCTL_WAIT_METHOD4, &dwMicroSecond, sizeof(DWORD), NULL, 0, &dwOutput, NULL);system("pause");CloseHandle(hDevice);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_WAIT_METHOD1 CTL_CODE(\FILE_DEVICE_UNKNOWN, \0x800, \METHOD_BUFFERED, \FILE_ANY_ACCESS)#define IOCTL_WAIT_METHOD2 CTL_CODE(\FILE_DEVICE_UNKNOWN, \0x801, \METHOD_BUFFERED, \FILE_ANY_ACCESS)#define IOCTL_WAIT_METHOD3 CTL_CODE(\FILE_DEVICE_UNKNOWN, \0x802, \METHOD_BUFFERED, \FILE_ANY_ACCESS)#define IOCTL_WAIT_METHOD4 CTL_CODE(\FILE_DEVICE_UNKNOWN, \0x803, \METHOD_BUFFERED, \FILE_ANY_ACCESS)#endif
#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_OUT3typedef struct _DEVICE_EXTENSION {PDEVICE_OBJECT pDevice;UNICODE_STRING ustrDeviceName;//设备名称UNICODE_STRING ustrSymLinkName;//符号链接名} 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);
#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);KdPrint(("Leave DriverEntry\n"));return status;}/************************************************************************* 函数名称: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;//创建符号链接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 PAGEDCODEVOID WaitMicroSecond1(ULONG ulMircoSecond){KEVENT kEvent;KdPrint(("Thread1 suspends %d MircoSeconds...",ulMircoSecond));//初始化一个未激发的内核事件KeInitializeEvent(&kEvent,SynchronizationEvent,FALSE);//等待时间的单位是100纳秒,将微秒转换成这个单位//负数代表是从此刻到未来的某个时刻LARGE_INTEGER timeout = RtlConvertLongToLargeInteger(-10*ulMircoSecond);//在经过timeout后,线程继续运行KeWaitForSingleObject(&kEvent,Executive,KernelMode,FALSE,&timeout);KdPrint(("Thread1 is running again!\n"));}#pragma PAGEDCODEVOID WaitMicroSecond2(ULONG ulMircoSecond){KdPrint(("Thread2 suspends %d MircoSeconds...",ulMircoSecond));//等待时间的单位是100纳秒,将微秒转换成这个单位//负数代表是从此刻到未来的某个时刻LARGE_INTEGER timeout = RtlConvertLongToLargeInteger(-10*ulMircoSecond);//此种方法类似于KeWaitForSingleObject//将当前线程进入睡眠状态,间隔时间到转入运行状态KeDelayExecutionThread(KernelMode,FALSE,&timeout);KdPrint(("Thread2 is running again!\n"));}#pragma PAGEDCODEVOID WaitMicroSecond3(ULONG ulMircoSecond){KdPrint(("Thread3 suspends %d MircoSeconds...",ulMircoSecond));//忙等待,此种方法属于忙等待,比较浪费CPU时间//因此使用该方法不宜超过50微秒KeStallExecutionProcessor(ulMircoSecond);KdPrint(("Thread3 is running again!\n"));}#pragma PAGEDCODEVOID WaitMicroSecond4(ULONG ulMircoSecond){//使用计时器KTIMER kTimer;//内核计时器//初始化计时器KeInitializeTimer(&kTimer);LARGE_INTEGER timeout = RtlConvertLongToLargeInteger( ulMircoSecond * -10 );//注意这个计时器没有和DPC对象关联KeSetTimer(&kTimer,timeout,NULL);KdPrint(("Thread4 suspends %d MircoSeconds...",ulMircoSecond));KeWaitForSingleObject(&kTimer,Executive,KernelMode,FALSE,NULL);KdPrint(("Thread4 is running again!\n"));}#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;//得到用户程序传进来的微秒数ULONG ulMircoSecond = *(PULONG)pIrp->AssociatedIrp.SystemBuffer;switch (code){// process requestcase IOCTL_WAIT_METHOD1:{KdPrint(("IOCTL_WAIT_METHOD1\n"));WaitMicroSecond1(ulMircoSecond);break;}case IOCTL_WAIT_METHOD2:{KdPrint(("IOCTL_WAIT_METHOD2\n"));WaitMicroSecond2(ulMircoSecond);break;}case IOCTL_WAIT_METHOD3:{KdPrint(("IOCTL_WAIT_METHOD3\n"));WaitMicroSecond3(ulMircoSecond);break;}case IOCTL_WAIT_METHOD4:{KdPrint(("IOCTL_WAIT_METHOD4\n"));WaitMicroSecond4(ulMircoSecond);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;}




原创粉丝点击