IRP 处理浅析
来源:互联网 发布:长沙理工大学教务网络 编辑:程序博客网 时间:2024/05/21 17:10
1. IRP 的总体结构(IoAllocateIrp)
#define IoSizeOfIrp(_StackSize) \ ((USHORT) (sizeof(IRP) + ((_StackSize) * (sizeof(IO_STACK_LOCATION)))))PIRPIoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota){ PIRP Irp = NULL; USHORT Size = IoSizeOfIrp(StackSize); Irp = ExAllocatePoolWithTag(NonPagedPool, Size, TAG_IRP); IoInitializeIrp(Irp, Size, StackSize); return Irp;}
2. IRP 如何使用 - 1(IoBuildDeviceIoControlRequest)
(1)分配 IRP
(2)设置下一层 IO_STACK_LOCARION (IRP_MJ_Xxx / Parameters)
(3)设置 IRP 内容 (读写缓冲区)
(4)把 IRP 与线程相关联 (即把 IRP 设置成同步 IRP)
3. IRP 如何使用 - 2(转发并忘记)
(1)IoSkipCurrentIrpStackLocation
(2)return IoCallDriver ( pLowerDevice , pIrp );
NTSTATUSIofCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp){ DriverObject = DeviceObject->DriverObject; Irp->CurrentLocation--; StackPtr = IoGetNextIrpStackLocation(Irp); Irp->Tail.Overlay.CurrentStackLocation = StackPtr; /* Get the Device Object */ StackPtr->DeviceObject = DeviceObject; /* Call it */ return DriverObject->MajorFunction[StackPtr->MajorFunction](DeviceObject, Irp);}
4. IRP 如何使用 - 3(前进并等待)
(1)IoSetCompletionRoutine
(2)IoCallDriver
(3)KeWaitForSingleObject
#define IoSetCompletionRoutine(_Irp, \ _CompletionRoutine, \ _Context, \ _InvokeOnSuccess, \ _InvokeOnError, \ _InvokeOnCancel) \{ \ PIO_STACK_LOCATION _IrpSp; \ _IrpSp = IoGetNextIrpStackLocation(_Irp); \ _IrpSp->CompletionRoutine = (PIO_COMPLETION_ROUTINE)(_CompletionRoutine); \ _IrpSp->Context = (_Context); \ _IrpSp->Control = 0; \ if (_InvokeOnSuccess) _IrpSp->Control = SL_INVOKE_ON_SUCCESS; \ if (_InvokeOnError) _IrpSp->Control |= SL_INVOKE_ON_ERROR; \ if (_InvokeOnCancel) _IrpSp->Control |= SL_INVOKE_ON_CANCEL; \}
5. IRP 的完成与返回(IoCompleteRequest)
(1)设置 pIrp->IoStatus
(2)IoCompleteRequest
(3)return STATUS_Xxx
VOIDIofCompleteRequest(IN PIRP Irp, IN CCHAR PriorityBoost){ /* * Start the loop with the current stack and point the IRP to the next stack * and then keep incrementing the stack as we loop through. The IRP should * always point to the next stack location w.r.t the one currently being * analyzed, so completion routine code will see the appropriate value. * Because of this, we must loop until the current stack location is +1 of * the stack count, because when StackPtr is at the end, CurrentLocation is +1. */ for (StackPtr = IoGetCurrentIrpStackLocation(Irp), Irp->CurrentLocation++, Irp->Tail.Overlay.CurrentStackLocation++; Irp->CurrentLocation <= (Irp->StackCount + 1); StackPtr++, Irp->CurrentLocation++, Irp->Tail.Overlay.CurrentStackLocation++) { /* Set Pending Returned */ Irp->PendingReturned = StackPtr->Control & SL_PENDING_RETURNED; /* Check if we failed */ if (!NT_SUCCESS(Irp->IoStatus.Status)) { /* Check if it was changed by a completion routine */ if (Irp->IoStatus.Status != ErrorCode) { /* Update the error for the current stack */ ErrorCode = Irp->IoStatus.Status; StackPtr->Control |= SL_ERROR_RETURNED; LastStackPtr->Parameters.Others.Argument4 = UlongToPtr(ErrorCode); LastStackPtr->Control |= SL_ERROR_RETURNED; } } /* Check if there is a Completion Routine to Call */ if ((NT_SUCCESS(Irp->IoStatus.Status) && (StackPtr->Control & SL_INVOKE_ON_SUCCESS)) || (!NT_SUCCESS(Irp->IoStatus.Status) && (StackPtr->Control & SL_INVOKE_ON_ERROR)) || (Irp->Cancel && (StackPtr->Control & SL_INVOKE_ON_CANCEL))) { /* Clear the stack location */ IopClearStackLocation(StackPtr); /* Check for highest-level device completion routines */ if (Irp->CurrentLocation == (Irp->StackCount + 1)) { /* Clear the DO, since the current stack location is invalid */ DeviceObject = NULL; } else { /* Otherwise, return the real one */ DeviceObject = IoGetCurrentIrpStackLocation(Irp)->DeviceObject; } /* Call the completion routine */ Status = StackPtr->CompletionRoutine(DeviceObject, Irp, StackPtr->Context); /* Don't touch the Packet in this case, since it might be gone! */ if (Status == STATUS_MORE_PROCESSING_REQUIRED) return; } else { /* Otherwise, check if this is a completed IRP */ if ((Irp->CurrentLocation <= Irp->StackCount) && (Irp->PendingReturned)) { /* Mark it as pending */ IoMarkIrpPending(Irp); } /* Clear the stack location */ IopClearStackLocation(StackPtr); } } ......}
(1)当完成函数的返回值为 STATUS_CONTINUE_COMPLETION 时,IoCompleteRequest 继续向上遍历 IO_STACK_LOCATION
(2)当完成函数的返回值为 STATUS_MORE_PROCESSING_REQUIRED 时,IoCompleteRequest 不再继续向上遍历 IO_STACK_LOCATION
7. 同步IRP 与 异步 IRP
参加文献:
ReactOS 0.3.15 Src
Different ways of handling IRPs - cheat sheet
- IRP 处理浅析
- WDM驱动之IRP处理:取消IRP
- WDM驱动之IRP处理:取消IRP
- 处理取消IRP
- IRP处理模型
- IRP 处理流程
- 3.4 IRP处理
- IRP的超时处理
- IRP 处理流程
- IRP 处理流程
- 同步,异步IRP的处理
- 同步,异步IRP的处理
- IRP
- irp
- IRP
- IRP
- IRP
- IRP
- Spring国际化--从数据库读取messageSource
- 微软Xperf Windows Software Development Kit (SDK) for Windows 8.1
- 几对对比(title\alt,join\split)
- 随诊医生3---应用介绍页面
- Windows下python安装问题解决方案
- IRP 处理浅析
- MySQL主从复制技术与读写分离技术amoeba应用
- 协同过滤算法的几篇文章PFM/svd/ svd++
- HDU 2066 一个人的旅行 (SPFA + 链式前向星)
- 掌握JS中的“this” (一)
- Testbench 阻塞赋值与非阻塞赋值
- 图解JSP与Servlet的关系
- 分页居中实现
- mybatis-generator自动生成DAO文件