irp的异步完成_irp等待插入队列_删除队列_结束irp

来源:互联网 发布:iso软件如何卸载 编辑:程序博客网 时间:2024/06/07 18:02
#include <windows.h>#include <stdio.h>int main(){HANDLE hDevice = CreateFile(L"\\\\.\\HelloDDK",GENERIC_READ | GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,//此处设置FILE_FLAG_OVERLAPPEDNULL );if (hDevice == INVALID_HANDLE_VALUE){printf("Open Device failed!");return 1;}OVERLAPPED overlap1={0};OVERLAPPED overlap2={0};UCHAR buffer[10];ULONG ulRead;BOOL bRead = ReadFile(hDevice,buffer,10,&ulRead,&overlap1);if (!bRead && GetLastError()==ERROR_IO_PENDING){printf("操作等待中1...The operation is pending\n");}bRead = ReadFile(hDevice,buffer,10,&ulRead,&overlap2);if (!bRead && GetLastError()==ERROR_IO_PENDING){printf("操作等待中1...The operation is pending\n");}//迫使程序中止2秒Sleep(2000);//创建IRP_MJ_CLEANUP IRPsystem("pause");printf("按回车就关闭等待 irp异步传送完毕\n");CloseHandle(hDevice);return 0;}
#pragma once#ifdef __cplusplusextern "C"{#endif#include <NTDDK.h>#ifdef __cplusplus}#endif #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]))typedef struct _DEVICE_EXTENSION {PDEVICE_OBJECT pDevice;UNICODE_STRING ustrDeviceName;//设备名称UNICODE_STRING ustrSymLinkName;//符号链接名PLIST_ENTRY pIRPLinkListHead;} DEVICE_EXTENSION, *PDEVICE_EXTENSION;typedef struct _MY_IRP_ENTRY//irp队列{PIRP pIRP;LIST_ENTRY ListEntry;} MY_IRP_ENTRY, *PMY_IRP_ENTRY;// 函数声明NTSTATUS CreateDevice (IN PDRIVER_OBJECT pDriverObject);VOID HelloDDKUnload (IN PDRIVER_OBJECT pDriverObject);NTSTATUS HelloDDKDispatchRoutin(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrp);NTSTATUS HelloDDKRead(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrp);NTSTATUS HelloDDKCleanUp(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;//设置派遣函数pDriverObject->MajorFunction[IRP_MJ_CREATE] = HelloDDKDispatchRoutin;pDriverObject->MajorFunction[IRP_MJ_CLOSE] = HelloDDKDispatchRoutin;pDriverObject->MajorFunction[IRP_MJ_WRITE] = HelloDDKDispatchRoutin;pDriverObject->MajorFunction[IRP_MJ_READ] = HelloDDKRead;pDriverObject->MajorFunction[IRP_MJ_CLEANUP] = HelloDDKCleanUp;pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = HelloDDKDispatchRoutin;pDriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = HelloDDKDispatchRoutin;pDriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = HelloDDKDispatchRoutin;pDriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = HelloDDKDispatchRoutin;//创建驱动设备对象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_BUFFERED_IO;pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;pDevExt->pDevice = pDevObj;pDevExt->ustrDeviceName = devName;pDevExt->pIRPLinkListHead = (PLIST_ENTRY)ExAllocatePool(PagedPool,sizeof(LIST_ENTRY));//分配一个链表的大小  链表指针InitializeListHead(pDevExt->pIRPLinkListHead);//初始化链表//创建符号链接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);//ExFreePool(pDevExt->pIRPLinkListHead);//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]));//对一般IRP的简单操作,后面会介绍对IRP更复杂的操作NTSTATUS status = STATUS_SUCCESS;// 完成IRPpIrp->IoStatus.Status = status;pIrp->IoStatus.Information = 0;// bytes xferedIoCompleteRequest( pIrp, IO_NO_INCREMENT );KdPrint(("Leave HelloDDKDispatchRoutin\n"));return status;}NTSTATUS HelloDDKRead(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrp)//irp装入队列里{KdPrint(("Enter HelloDDKRead\n"));PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;//设备扩展PMY_IRP_ENTRY pIrp_entry = (PMY_IRP_ENTRY)ExAllocatePool(PagedPool, sizeof(MY_IRP_ENTRY));//irp队列指针pIrp_entry->pIRP = pIrp;//插入队列InsertHeadList(pDevExt->pIRPLinkListHead,&pIrp_entry->ListEntry);//将IRP设置为挂起IoMarkIrpPending(pIrp);KdPrint(("读历程中来了 Leave HelloDDKRead\n"));//返回pending状态return STATUS_PENDING;}NTSTATUS HelloDDKCleanUp(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrp) {KdPrint(("Enter HelloDDKCleanUp\n"));PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;//(1)将存在队列中的IRP逐个出队列,并处理PMY_IRP_ENTRY my_irp_entry;while(!IsListEmpty(pDevExt->pIRPLinkListHead))//链表有数据  {PLIST_ENTRY pEntry = RemoveHeadList(pDevExt->pIRPLinkListHead);//删除一个结点 链表  返回删除的节点的指针my_irp_entry = CONTAINING_RECORD(pEntry,MY_IRP_ENTRY,ListEntry);//删除的节点的元素的指针 my_irp_entry->pIRP->IoStatus.Status = STATUS_SUCCESS;//队列 my_irp_entry->pIRP->IoStatus.Information = 0;//  IoCompleteRequest( my_irp_entry->pIRP, IO_NO_INCREMENT );//io完成请求ExFreePool(my_irp_entry);//释放删除 节点的元素的指针}//(2)处理IRP_MJ_CLEANUP的IRPNTSTATUS status = STATUS_SUCCESS;// 完成IRPpIrp->IoStatus.Status = status;pIrp->IoStatus.Information = 0;// bytes xferedIoCompleteRequest( pIrp, IO_NO_INCREMENT );KdPrint(("关闭历程中来了 Leave HelloDDKCleanUp\n"));return STATUS_SUCCESS;}