CPU与IRP的一些相关函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | VOID KiAdjustIrpCredits ( VOID )其中 Number = KeNumberProcessors;Prcb = KiProcessorBlock[Index]; 多核情况下调整每个CPU的IRP对象配额。在 while (Index < Number);轮询调整1-n的CPU的配额InterlockedExchangeAdd(&Prcb->LookasideIrpFloat, Adjust),不过最后一个CPU为什么是 InterlockedExchangeAdd(&Prcb->LookasideIrpFloat, -TotalAdjust)?? PIRP IopAllocateIrpPrivate( IN CCHAR StackSize, IN BOOLEAN ChargeQuota )分配IRP首先根据IRP需要的栈单元决定是否从两个快查表中的一个分配。一个栈单元为1则为LookasideSmallIrpList ,一个栈单元小于8大于1则为LookasideLargeIrpList.然后从指定的快查表中摘除一个作为IRP的空间。如果超过8 则自行分配。没什么说的了。 里面的IopInitializeIrp倒是个需要注意的 StackSize 是IRP要分配的堆栈数目PacketSize是IRP的长度加上 StackSize *stack的长度#define IopInitializeIrp( Irp, PacketSize, StackSize ) { \ RtlZeroMemory( (Irp), (PacketSize) ); \ (Irp)->Type = (CSHORT) IO_TYPE_IRP; \ (Irp)->Size = (USHORT) ((PacketSize)); \ (Irp)->StackCount = (CCHAR) ((StackSize)); \ (Irp)->CurrentLocation = (CCHAR) ((StackSize) + 1); \ (Irp)->ApcEnvironment = KeGetCurrentApcEnvironment(); \ InitializeListHead (&(Irp)->ThreadListEntry); \ (Irp)->Tail.Overlay.CurrentStackLocation = \ ((PIO_STACK_LOCATION) ((UCHAR *) (Irp) + \ sizeof ( IRP ) + \ ( (StackSize) * sizeof ( IO_STACK_LOCATION )))); } IopFreeIrp情况类似:首先检验IRP是否是IO_TYPE_IRP,&(Irp)->ThreadListEntry为空。当前IRP的CurrentLocation大于IRP的STACKCOUNT。获取当前CPU的PKPRCB , prcb = KeGetCurrentPrcb();然后根据IRP之前是从快查表分配还是使用自行分配进行处理。 另:这里是 gussing是个错别字 的博客 http: //www.cnblogs.com/gussing/archive/2011/01/18/1938140.html因为他不允许转载 所以在这里谈谈内容 也推荐大家对驱动内核有兴趣的去看下他的wdk tips IRP的创建可以为自写驱动创建和IO管理器创建,在释放上有自己释放或者由IO管理器释放两种IoAllocateIrp IoBuildAsynchronousFsdRequest属于需要自行释放,WDK帮助也有提到。( IoBuildSynchronousFsdRequest IoBuildDeviceIoControlRequest TdiBuildInternalDeviceControlIrp 属于交与IO管理器释放。 PIRP IoBuildAsynchronousFsdRequest( IN ULONG MajorFunction, IN PDEVICE_OBJECT DeviceObject, IN OUT PVOID Buffer OPTIONAL, IN ULONG Length OPTIONAL, IN PLARGE_INTEGER StartingOffset OPTIONAL, IN PIO_STATUS_BLOCK IoStatusBlock OPTIONAL ) { PIRP irp; PIO_STACK_LOCATION irpSp; // 分配IRP 第一个是IRP的stack数目 ,第二个参数是不改变IRP配额 irp = IoAllocateIrp( DeviceObject->StackSize, FALSE ); if (!irp) { return irp; } // 按推荐的博客的那个作者的意思 这里应该不设置THREAD 因为他将创建的IRP分类至NON THREAD IRP。 irp->Tail.Overlay.Thread = PsGetCurrentThread(); irpSp = IoGetNextIrpStackLocation( irp ); irpSp->MajorFunction = (UCHAR) MajorFunction; if (MajorFunction != IRP_MJ_FLUSH_BUFFERS && MajorFunction != IRP_MJ_SHUTDOWN && MajorFunction != IRP_MJ_PNP && MajorFunction != IRP_MJ_POWER) { // ......根据设备对象的类型来决定 BUFFER的种类是SYSBUF 还是MDL 或者原函数输入BUF...... // 代码比较简单 分配IRP并设置读写参数 if (MajorFunction == IRP_MJ_WRITE) { irpSp->Parameters.Write.Length = Length; irpSp->Parameters.Write.ByteOffset = *StartingOffset; } else { irpSp->Parameters.Read.Length = Length; irpSp->Parameters.Read.ByteOffset = *StartingOffset; } } irp->UserIosb = IoStatusBlock; return irp; } IoBuildsynchronousFsdRequest还是调用IoBuildAsynchronousFsdRequest只不过多了一行 irp->UserEvent = Event,用于同步时候的等待。 |
作 者: itdef
欢迎转帖 请保持文本完整并注明出处
技术博客 http://www.cnblogs.com/itdef/
B站算法视频题解
https://space.bilibili.com/18508846
qq 151435887
gitee https://gitee.com/def/
欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
如果觉得不错,欢迎点赞,你的鼓励就是我的动力
欢迎转帖 请保持文本完整并注明出处
技术博客 http://www.cnblogs.com/itdef/
B站算法视频题解
https://space.bilibili.com/18508846
qq 151435887
gitee https://gitee.com/def/
欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
如果觉得不错,欢迎点赞,你的鼓励就是我的动力


分类:
windows 内核
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话