That's Just the Way It Is - How NT Describes I/O Requests

对文件进行加密 // 在对文件进行加密写的时候,虽然跟踪到了有加密操作,但是为什么没有写到硬盘上去呢? 处理IrpFlags :IRP_PAGING_IO ,IRP_NOCACHE,IRP_SYNCHRONOUS_PAGING_IO //================================================================================ //IRP_M... 阅读详情

That's Just the Way It Is - How NT Describes I/O Requests 
The NT Insider, Vol 5, Issue 1, Jan-Feb 1998 | Published: 15-Feb-98| Modified: 20-Aug-02 

声明:原文来自www.osr.com,所有权利归原作者所有,翻译并贴在这里的目的只为学习和交流,除了商用你可以随意地使用这篇译文。但请不要删除声明。

                                                     ——by jununfly

版本:20090124

NT驱动中的根本问题:IRPs和数据缓冲… 在此之前我们从未真正地进行详论的细节.

NT用一个基于包的架构描述I/O请求。即任何一个I/O请求都能用一个单一的I/O请求包也就是IRP来描述。当发出一个I/O系统服务时(比如创建文件或读文件的请求),I/O管理器服务通过构造一个描述此请求的IRP并把该IRP的一个指针传给设备驱动来开始对这个请求的处理。

一个IRP,包含要向I/O管理器和设备驱动完整地描述一个I/O请求的所有必需的信息。IRP是一个标准的NT结构,其定义在NTDDK.H中。结构如图1:

图1 – 一个IRP的结构

如图1所示,任何一个IRP都能被认为是由两部分组成:一个"固定的"部分和一个I/O栈。IRP的固定部分包含这个请求的相关信息,有可能不同驱动中的IRP的固定部分相同,也可能在不同驱动间传递IRP时不需要关注它。I/O栈包含被指定给任何一个要处理该请求的驱动的信息。 

虽然一个IRP被I/O管理器创建时它的大小是固定的,但是I/O管理器创建的任何一个IRP的大小都不一样。当I/O管理器分配一个IRP时,它为IRP分配的空间是:IRP的固定部分的空间,加上其数量至少等于驱动栈中将会处理这个请求的驱动的数量的I/O栈位置的空间。因此,如果对一个软盘上的文件发出一个写I/O请求,要处理这个请求的驱动栈如图2。I/O管理器将会创建一个IRP来描述这个请求,这个IRP中至少有两个I/O栈位置:一个位置是FSD的,第二个位置是软盘设备驱动的。

图2 – 驱动栈示例

注意我们说的例子中的IRP将至少有两个I/O栈位置。为避免每一个IRP都要从NT的非分页池中分配,I/O管理器维护一对保存有预分配的IRPs的旁观列表。NT V4.0中,其中一个旁观列表保存带有一个单一的I/O栈位置的IRP。 

另外一个旁观列表保存带有三个I/O栈位置的旁观列表。I/O管理器总是尽可能使用这些旁观列表中的IRP。因此,对一个被引导到带有两个驱动的驱动栈上的I/O请求来说,I/O管理器会试图从保存带有三个I/O栈位置的IRP的旁观列表中分配一个IRP。如果没有可用的IRP,或者要分配的IRP所需的I/O栈位置超过三个,I/O管理器就会从非分页池中分配IRP。

IRP的固定部分中需要特别关注或有用的域如下:

o MdlAddres, UserBuffer和AssociatedIrp.SystemBuffer – 如果有一个关联I/O操作请求者的数据缓冲,则这三个域被用来描述这个缓冲。后面会加以详述。

o Flags – 顾名思义,这个域包含描述I/O请求的标记。例如,如果在此域中设置了IRP_PAGING_IO标记,则表示IRP所描述的读或写操作是一个分页请求。以此类推,如果设置了IRP_NOCACHE则表示这个请求是在没有中间缓冲的情况下被处理的。一般只有文件系统才关心这个域。

o IoStatus – 当IRP被完成时,完成这个IRP的驱动把IoStatus.Status域设置为I/O操作的完成状态,而把IoStatus.Information域设置为一些要返回给调用者的额外信息。典型的,在一个传输请求(读或写等会引起数据传输的请求)中IoStatus.Information 将会包含实际上被读或被写的字节数。

o RequestorMode – 指示这个请求是从哪种模式(内核模式或用户模式)发动的。

o Cancel, CancelIrql, and CancelRoutine – 如果正在进行时需要取消这个IRP就会用到它们。Cancel是一个BOOLEAN类型值,当被I/O管理器设置为TRUE时表示这个IRP正被取消。CancelRoutine是一个指针,在把这个IRP保存到一个队列中时由一个驱动设置它指向一个函数,I/O管理器会调用这个函数来让该驱动取消此IRP。因为CancelRoutine是在IRQL DISPATCH_LEVEL被调用, 而CancelIRQL是驱动应该返回到的IRQL。(看The NT Insider的卷4第6期的Part I,有篇文章关于取消处理)

o Tail.Overlay.Thread – 指向请求线程的ETHREAD. 

o TailOverlay.ListEntry – 可能被驱动用来排队的位置,尽管它拥有这个IRP。

IRP中的任何一个I/O栈位置都包含一个指定的驱动与此I/O请求相关的信息。在NTDDK.H 中I/O栈位置的定义如结构IO_STACK_LOCATION.要在一个给定的IRP中定位当前的I/O栈位置,驱动得调用函数IoGetCurrentIrpStackLocation(…).其唯一的参数是一个指向IRP的指针。返回值是当前I/O栈位置的一个指针。

当I/O管理器开始分配IRP并初始化它的固定部分时,它也初始化IRP中的首个I/O栈位置。这个位置中的信息与被传到将会处理这个请求的驱动栈中的首个驱动的信息相一致。I/O栈位置中有以下域:

o MajorFunction – 关联这个请求的主I/O函数代码。它从总体上指示了要执行的I/O操作的类型。

o MinorFunction – 关联这个请求的辅助I/O函数代码。当被使用时,这会改变主函数代码。Minor function几乎是被网络传输驱动和文件系统独占地使用,大多数设备驱动会忽略它们。

o Flags – 指定给正被执行的I/O函数的处理标记。此域主要为FSD所关注。

o Control – 一组指示I/O管理器如何处理这个IRP的标记,由I/O管理器设置并参阅。例如, 若设置了SL_PENDING位(因驱动调用了IoMarkIrpPending(…))就指示给I/O管理器此IRP还需其他处理。类推之, SL_INVOKE_ON_CANCEL, SL_INVOKE_ON_ERROR和SL_INVOKE_ON_SUCCESS都指示了驱动的I/O完成例程什么时候应该被调用。

o Parameters – 这个域由几个子成员组成,任何一个都基于正被执行的I/O主函数被指定。

o DeviceObject – 这个I/O请求的目标设备对象的一个指针。

o FileObject – 关联这个请求的文件对象的一个指针。

在IRP的固定部分和首个I/O栈位置之后的部分都被适当地初始化,I/O管理器在它的与此请求的主函数代码对应的分发入口点中调用驱动栈中的顶部驱动。因此,如果I/O管理器刚好已经构造了一个IRP来描述一个读请求,那么它会在它的读分发入口点中调用首个驱动。在此分发入口点上,刚构造的IRP的指针,和驱动要在其上处理这个请求的设备所对应的设备对象的指针会被I/O管理器作为参数传给驱动。

描述数据缓冲

请求者的数据缓冲的描述符出现在IRP的固定部分中。为了让驱动程序员能描述关联一个I/O操作的请求者的数据缓冲,NT提供了三个不同的选项:

o 若缓冲被一个叫做内存描述符列表(MDL)的结构,以该缓冲在请求者的物理地址空间中的真实位置的方式描述了,那这就叫做Direct I/O. 

o 若缓冲中的数据会从请求者的地址空间中被复制到系统地址空间中的一个中间位置,且驱动被提供了这个数据副本的一个指针,那这就叫做Buffered I/O. 

o 若驱动被提供了请求者的缓冲的虚拟地址,那这就叫做Neither I/O. 

驱动必须为I/O管理器选择一种方式来描述所有被发送到一个特定设备上的读写请求。通过设置设备对象中的Flags域可以做出这个选择 (通常在设备对象被创建的初始化阶段) 。任何一个由驱动支持的设备I/O控制(IOCTL)代码,都会为读写请求选择不同的方式。

如果驱动选择Direct I/O,一切关联读或写I/O请求的数据缓冲都会被I/O管理器用MDL描述。MDL描述了这个数据缓冲在请求者的物理地址空间中的真实的位置。MDL的地址在被传给驱动的IRP的MdlAddress域中.

在IRP被传给驱动之前,I/O管理器会做检查来确保调用者对整个数据缓冲有适当的访问权。如果访问检查失败,I/O管理器会以一个错误状态来完成这个请求,而此请求也永远不会被传给驱动。

在访问检查完成之后,IRP被传给驱动之前,I/O管理器锁住内存中由数据缓冲组成的物理页。如果这个操作失败了(例如,在某一时间由于数据缓冲太大而不适合内存),此请求会被I/O管理器以一个错误状态来完成。如果锁定操作成功,页会在这个I/O操作的整个时间段内都保持被锁状态(直到IRP最终完成).

MDL能描述一个单一的逻辑连续的数据缓冲而不是物理连续的。它被设计为使获得物理地址和由数据缓冲组成的段的长度变得快捷。MDL结构的定义在NTDDK.H中.示意图如图3:

图3 – 一个MDL

即使大家都知道了MDL的结构,这也只是NT中真正不透明的数据结构的冰山一角。通过不透明,我们要表达的意思是驱动绝对不能假设MDL的结构。因此,驱动绝对不能直接引用MDL中的域。I/O和内存管理器为使用MDL的数据缓冲提供了获得相关信息的函数。这些函数包括:

·        MmGetSystemAddressForMdl(…) – 返回在一个任意线程上下文环境中的一个内核虚拟地址,它用于引用MDL描述的缓冲。由图4看出, MDL中的一个域(如果存在的话)会包含关联此MDL的被映射的系统虚拟地址.实际上这个函数就是NTDDK.H中的一个宏.这个函数被首次调用时,它调用MmMapLockedPages(…)来映射缓冲到内核虚拟地址空间中。然后返回的内核虚拟地址被存储到MDL的MappedSystemVa域中.在后来的MmGetSystemAddressForMdl(…)调用中,之前被存到MappedSystemVa中的值会被返回给调用者。当MDL被释放时(例如当I/O请求最终被完成了)一切映射都会被删除。

·        IoMapTransfer(…) – 这个函数主要是被DMA设备驱动用来获得物理地址和数据缓冲组成的段的长度。

·        MmGetMdlVirtualAddress(…) – 这个函数(实际上是NTDDK.H中的一个宏)返回被MDL描述的缓冲的请求者的虚拟地址。这个虚拟地址只能在调用进程的上下文中使用。这个函数也常常像请求者的虚拟地址一样被DMA设备驱动用作IoMapTransfer(…)的一个入参。

·        MmGetMdlByteCount(…) – NTDDK.H中的另外一个宏,此函数返回被MDL描述的缓冲的长度。

·        MmGetMdlByteOffset(…) – 这个函数也是NTDDK.H中的一个宏,它返回MDL的首页中的数据缓冲的起始偏移。

图4 – MDL的域

MDL中的一个值得关注的域是Next.这个域是用于构造一个”MDL”链,该链上的所有MDL共同描述一个单一的逻辑不连续的缓冲。链中的任何一个MDL都描述一个单一的逻辑连续的缓冲。MDL 链仅用于网络驱动,且不被I/O管理器的大多数标准函数支持。因此,在NT中MDL链不能被标准的设备驱动使用。

Direct I/O一般用于”基于包的”DMA设备驱动。但它也能被一切想在一个用户缓冲和一个外设之间直接传输数据,而没有重缓冲这个数据的消耗(Buffer I/O的情形)也无需在调用进程的上下文中执行传输(Neither I/O的情形)。

当IRP最终被完成(通过调用IoCompleteRequest(…))而MdlAddress域非零时,I/O管理器解映射和解锁那些被映射和被锁的页,然后释放关联这个IRP的MDL。

在Buffered I/O中系统空间中的一个中间缓冲被用作一个数据缓冲。I/O管理器负责在中间缓冲和请求者的原始数据缓冲之间移动数据。当IRP最终被完成时,系统缓冲被I/O管理器释放。

图5 -- Buffered I/O方式的写

为准备一个Buffered I/O请求,I/O管理器会做检查来确保调用者对整个数据缓冲有合适的访问权,这与Direct I/O一样.如果调用者没有合适的访问权,则这个请求被完成且不会被传给驱动。作为一个优化,如果请求是从内核模式发起的那么就不会执行这个检查。

然后I/O管理器从非分页内存池中分配一个与该数据缓冲等大的系统缓冲。如果这是一个写操作,那么I/O管理器会从请求者的缓冲中复制数据到中间缓冲中。不论请求是读还是写,中间缓冲的内核虚拟地址都会在被传给驱动的IRP的AssociatedIrp.SystemAddress域中.注意即使这个域时IRP中"AssociatedIrp"结构的一部分,这个域也与关联的IRP没有任何关系。因为中间缓冲的地址对应系统的非分页池中的位置,这个地址能被在任意线程上下文中的驱动使用。当然,这个系统缓冲是逻辑连续的。但它不一定是逻辑连续的。

当使用Buffered I/O时,在I/O操作期间,由原始数据缓冲组成的内存页没有被锁住。因此,它们能被分页的能力不受I/O操作的影响。

当一个使用Buffer I/O的读操作最终完成时,I/O管理器负责从中间缓冲中复制数据到请求者的数据缓冲。作为一个优化,在发出这个I/O请求的线程成为下一个要被执行的线程之前(通过"指定I/O完成的内核APC"),I/O管理器会延迟这个复制操作。当请求者线程是下一个要被执行的线程时,I/O管理器从中间系统缓冲中复制数据到请求者的缓冲,并释放系统缓冲。此优化不仅避免了可能会有的页负担,而且也为一个”缓存热身”函数提供了服务 – 用来自缓冲的数据预加载处理器缓存,从而使得处理器能在从这个I/O请求返回的时候进行快速访问。

Buffered I/O常常被用于控制设备I/O的数据传输量小的驱动。在此驱动中,用一个系统虚拟地址描述请求者的数据非常方便。

I/O管理器描述请求者的数据缓冲的最后一种方式叫做"Neither I/O".它如此命名仅仅是因为这类驱动请求既不是Buffered I/O也不是I/O.在此方式中,I/O管理器为驱动提供数据缓冲的请求者的虚拟地址。这个缓冲没有被锁到内存中;也没有中间的数据缓冲。这个地址在IRP的UserBuffer 域中.

很显然,请求者的虚拟地址仅在调用进程的上下文中有用.结果就是,只有用Neither I/O的驱动才能无需任何中间驱动就能从I/O管理器中被直接进入,并能在调用进程的上下文中执行(并完成)I/O操作。因此,传统的存储器设备的驱动不能使用Neither I/O,因为它们的分发例程是在任意线程上下文中被调用的。大多数常规的设备驱动也不能使用Neither I/O,因为这些驱动的I/O请求常常是从DPC例程中开始的,也就是说它们也在任意线程的上下文中。

如果使用得当且谨慎,Neither I/O可能会是一些设备驱动的最理想的方式。例如,如果一个在调用线程的上下文中的驱动同步地执行其大部分的工作,Neither I/O就能节省创建一个MDL或再次复制数据的消耗。即使这个驱动偶尔中间地缓冲下数据或创建一个描述符来允许从任意线程的上下文中引用数据缓冲,Neither I/O能节省的消耗也是相当可观的。

那在你的驱动中,你怎么判断要用Direct I/O,Buffered I/O或Neither I/O中的哪个? 有一个规则:如果你正在写一个中间的驱动,而它将会被分层到另一个驱动之上的话,那么你所使用的缓冲方式必须与在你之下的设备所使用的缓冲方式保持一致。

对设备驱动来说,这种的选择无疑是一个架构决策,它将影响驱动的复杂性和性能。如果你因客观因素而不得不用Neither I/O,而且你能应付要使用它的需求,你就应该选I/O.

然而,因其严格的限制,大多数驱动不会使用Neither I/O.一般,每次传输要操作至少一页的数据的驱动最好是使用Direct I/O.在传输期间,I/O管理器将锁住内存中的页,这就避免了数据的再次复制的消耗。用Direct I/O来进行大量数据的传输也避免了众多系统池的占用。大多数DMA驱动也会用Direct I/O.基于DMA设备的信息包的驱动会用它是因为这会允许它们轻易地获得物理基础地址和由数据缓冲组成的段的长度。”公有缓冲”DMA设备的驱动用它来避免一次额外的复制操作的消耗。

用程序的I/O相对缓慢地移动数据的驱动,存在长时间的未决操作的驱动和传输小块数据的驱动大多会用Buffered I/O.这包括传统的串口和并口的设备,也包括大多数简单的机器控制驱动。Buffered I/O是最容易实现的方式,因为在IRP中提供了在系统空间中一个包含数据的逻辑连续的缓冲的一个指针。

在非临界情形的大多数情况中,相对Direct I/O来说Buffered是很重要的。几乎所有NT驱动程序员刚开始的时候都会花费大量的时间来决定要用哪种方式。如果你不确定,而你正在写一个程序I/O类型的设备的驱动的话,从用Buffered I/O开始吧。一旦你写好了你的驱动,你就可以尝试来看看转到Direct I/O会不会给你更多性能增效。毕竟,从编程的观点来看,二者的仅有的区别是你从IRP的哪个地方找你的信息(Irp->AssociatedIrp.SystemBuffer还是Irp->DmaAddress)和一个函数调用(即调用MmGetSystemAddressForMdl(…)来获得映射被一个MDL描述的缓冲的一个系统虚拟地址). 这不是小菜一碟嘛!

【tensorrt】——深入解析TypeError: pybind11::init()报错:CUDA版本冲突与解决方案 本文深入解析了TensorRT中常见的TypeError: pybind11::init()报错问题,重点探讨了CUDA版本冲突的根源与解决方案。通过实际案例展示了PyTorch与TensorRT的版本兼容性问题诊断方法,并提供了conda环境管理、环境变量配置等实用修复技巧,帮助开发者有效解决CUDA初始化失败问题。 阅读详情

相关推荐

AI嵌入式系统测试:从确定性验证到概率性评估的体系构建

软件测试是保障系统质量的关键环节,其核心在于验证功能是否符合预期。传统嵌入式测试聚焦于确定性逻辑,通过代码覆盖、边界值分析等方法确保时序、内存等指标的精确性。随着人工智能技术的普及,深度学习模型以其概率性输出和复杂非线性映射的特性,为嵌入式系统带来了新的能力,也彻底改变了测试的范式。AI模型的‘黑盒’特性使得测试目标从‘绝对正确’转向‘置信度满足’,并催生了准确率、F1分数等新指标。在工程实践中,这种融合要求测试体系必须扩展维度,将数据质量、模型量化损失、资源约束下的精度与性能权衡纳入核心考量。尤其在嵌入式

weixin_26766559的博客 382

标志为IRP_PAGING_IO的IRP有什么特殊的性质?

从目前的认识来看IRP_PAGING_IO是发生Page fault时从Cache Manager管理器发出的. 它具有很多不一般的特性. 1.此时文件系统应该避免获得任何资源(用来进行同步) 2.在处理读/写请求时绝不应该发生Page fault 3.绝不应该延迟这个请求进行异步处理 4.绝不应该因为任何原因阻塞这个请求5.PaginIO不扩大文件6.Pag...

weixin_33979203的博客 857

从实验室到生活:构建一份全面的手机相机主观画质评测指南

本文详细介绍了如何从实验室数据转向实际体验,构建全面的手机相机主观画质评测指南。通过基础装备清单、室内外场景实战评测及数据之外的感知艺术,帮助用户发现手机相机在色彩还原、动态范围和夜景模式等方面的真实表现。特别关注主观体验与客观参数的差异,提供实用的评测技巧和报告撰写心法。

weixin_30940783的博客 308

IRP_PAGING_IO的一些说明

 http://laokaddk.blog.51cto.com/368606/73746

zj510的专栏 2547

描述符链表(Descriptor Chain)是什么?

描述符链表是硬件加速数据传输的核心数据结构,通过链式描述符(包含地址、长度、控制标志等)实现DMA自动批量处理,显著降低CPU负载。其工作原理为:CPU初始化链表后,硬件按序处理每个描述符,完成自动跳转与中断通知。在网卡收包、NVMe存储等场景中应用广泛,优势包括批处理、低延迟和灵活调度。需注意内存对齐、缓存一致性等实现细节,优化手段包括预分配描述符池、环形缓冲区等。该技术是网络/存储领域提升吞吐量的关键方案。

guigenyi的专栏 776

利用netns做自环Iperf测试

netns可以让一台机器上模拟多个网络设备,是网络虚拟化的重要组成,将不同类型的网络应用隔离。一个net namespace有自己独立的路由表,iptables策略,设备管理。本文利用netns模拟网络来实现单机上网卡自环上的iperf测试或其他网络测试。

weixin_42414349的博客 3370

pagefile vs mappedfile & mm vs cc & IRP_PAGING_IO vs IRP_NOCACHE

/* * pagefile vs mappedfile & mm vs cc & IRP_PAGING_IO vs IRP_NOCACHE * sunwangsunwangme@hotmail.com> * 2005-10-20 *///osr1IRP_PAGING_IO means that the IRP is paging i/o, for example if the IRP is IRP

明日帝国的专栏-技术改进生活 6372

OpenClaw 子代理配对失败问题分析与解决方案

OpenClaw子代理配对失败问题分析与解决方案 问题核心在于agent设备权限不足,仅有operator.approvals权限而缺少operator.admin权限,导致子代理启动时形成权限死锁。本文提供三种解决方案: 直接编辑设备配对文件(推荐):修改本地JSON文件,为agent设备添加完整operator.admin权限,操作简单快捷。 标准重新配对流程:删除现有agent设备后重新配对,通过正常审批流程获取完整权限,符合系统安全设计。 修改源码降低权限要求(仅限开发环境):调整子代理代码避免强制

多媒体编程、网络编程、系统编程、网络安全编程、驱动编程 149

IRP结构体之Flag成员

IRP_DEALLOCATE_BUFFER //在I/O管理器将在该IRP完成阶段释放缓冲区。IRP_SYNCHRONOUS_API //该操作是一个同步分页I/O操作。IRP_BUFFERED_IO //该操作是一个缓冲的I/O操作。IRP_OB_QUERY_NAME //该操作是异步的名称查询。IRP_DEFER_IO_COMPLETION //I/O操作完成被推迟。IRP_HOLD_DEVICE_QUEUE //保留。

weixin_44628381的博客 198

3.1 快速启动Flink集群

在本实战中,我们将快速启动Apache Flink 1.13.0集群,并在Hadoop集群环境中提交作业。首先,我们会在本地下载Flink安装包并上传至云主机,解压并配置环境变量。接着,我们将启动Flink集群,通过访问Web UI进行监控管理。然后,我们会配置集群,将Flink分发到从节点,并在集群上提交作业。最后,我们将通过命令行提交作业,并在Web UI上查看任务节点的输出结果。这个过程涵盖了Flink集群的部署、配置和作业提交,为大数据处理提供了一个完整的实战经验。

howard2005的专栏 727

出现 Error:Unable to access jarfile xxxx\target\nacos-server.jar 解决方法

Nacos中的 2.x执行步骤如上,如果需要安装下载1.x版本,执行该步骤之后 自动更新下载的是2.x版本 对此如果需要下载安装1.x的版本,可通过如下连接(windows版本)

码农研究僧的博客 5699

IRP IO_STACK_LOCATION 《寒江独钓》内核学习笔记(1)

在学习内核过滤驱动的过程中,遇到了大量的涉及IRP操作的代码,这里有必要对IRP的数据结构和与之相关的API函数做一下笔记。   1. 相关阅读资料 《深入解析 windows 操作系统(第4版,中文版)》 --- 9章 《windows driver kit 帮助文档》 http://support.microsoft.com/kb/115758/zh-cn  IRP 结构中各地址字段...

weixin_33739523的博客 2504

【零基础入门unity游戏开发——2D篇】大大简化了地形创建流程,减少Rule Tile的使用 —— AutoTile自动平铺瓦片的使用介绍

Unity 2D游戏开发中的AutoTile技术详解 摘要:本文详细介绍了Unity 2D游戏开发中的AutoTile技术,这是一种智能瓦片系统,能够自动处理地形和场景拼接。文章首先讲解了AutoTile的基本概念和优势,然后分步骤指导读者如何安装2D Tilemap Extras包、创建AutoTile、设置参数和绘制遮罩。通过实际案例演示了AutoTile的使用方法,并比较了AutoTile与Rule Tile的适用场景。最后指出AutoTile虽然使用方便,但对素材要求较高,开发者应根据项目需求选择合

向宇的博客,专注php/web全栈 unity游戏开发,欢迎大家评论纠错 729

IRP 的结构

。WDK 中的wdm.h 中,能找到IRP 的结构如下: typedef struct DECLSPEC_ALIGN(MEMORY_ALLOCATION_ALIGNMENT) _IRP { // 类型和大小 CSHORT Type; USHORT Size; // 内存描述符链表指针。实际上,这里用来描述一个缓冲区。可以想象, // 一个内核请求一般都需要一个缓冲区(如读硬盘需要有读出缓冲区)

autumn20080101的专栏 1016

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

Fast I/O和IRP_笔记

1. IRP and Fast I/O http://excel.fit.vutbr.cz/submissions/2019/019/19_poster.pdf 2.Minifilter 拦截FileMapping IO事件 https://blog.youkuaiyun.com/zj510/article/details/85059638#FileMapping_17 3 文件过滤 http...

有趣的人生 一半是山川湖海 一半是初心情怀 2337

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

文件系统minifilter新架构开发指南

微过滤器驱动开发指南   0.译者序 对我来说,中文永远是最美,最简洁,最精确和最高雅的文字。 本 文翻译仅仅用做交流学习。我不打算保留任何版权或者承担任何责任。不要引用到赢利出版物中给您带来版权官司。本文的翻译者是楚狂人,如果有任何问题,你可 以通过邮箱MFC_Tan_Wen@163.com,或者是QQ16191935,或者是MSN walled_river@ho

look01的专栏 7952

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

IRP结构

IRP结构 图5-1显示了IRP的数据结构,阴影部分代表不透明域。下面是该结构中重要域的简要描述。 MdlAddress(PMDL)域指向一个内存描述符表(MDL),该表描述了一个与该请求关联的用户模式缓冲区。如果顶级设备对象的Flags域为DO_DIRECT_IO,则I/O管理器为IRP_MJ_READ或 IRP_MJ_WRITE请求创建这个MDL。如果一个IRP_MJ_DEVICE

木易云清 810

内核级文件读写流程

在应用层读写文件等操作将通过 INT 2E 切换到内核层。这个不用说大家都很熟悉流程。那么到了内核层又是如何处理的?就先拿 ZwReadFile,ZwWriteFile 说事。首先将文件句柄转换成 FILE_OBJECT 指针。这时 I/OMGR 收到一个 FILE I/O 请求,它将首先选择用 FASTIO 接口来进行缓冲操作(注意:FASTIO 对于 FSD 来说不是必须...

weixin_34307464的博客 258

Windbg命令查看IRP IO_STACK_LOACTION结构体成员

dt命令查看结构体成员。加入 /r 递归列举每个成员(dt nt!_irp /r)。      这个是双机调试32位系统下查询的结果, 列举每个成员的偏移量,对于调试汇编代码或者逆向分析驱动是很有帮助的,汇编访问结果体成员的时候都是通过偏移值进行的。知道偏移值以及数据结构的类型,就可以知道访问的成员是那一个了。 kd> dt nt!_irp    +0x000 Type

faithzzf的专栏 2511

IRP结构与理解

Irp->AssociatedIrp.SystemBuffer //输入输出缓冲区 使用DO_BUFFER_IO Irp->IoStatus.Status //返回给用户层的状态,表示这次通信的结果 Irp->IoStatus.Information //返回给用户层的大小 Irp->UserBuffer //USER_BUFFER时的通信 Irp->MdlAddress //使用MDL映

zhuhuibeishadiao 2340

IRP数据结构(即 I/O请求包数据结构)

IRP结构   图5-1显示了IRP的数据结构,阴影部分代表不透明域。下面是该结构中重要域的简要描述。 MdlAddress(PMDL)域指向一个内存描述符表(MDL),该表描述了一个与该请求关联的用户模式缓冲区。如果顶级设备对象的Flags域为DO_DIRECT_IO,则I/O管理器为IRP_MJ_READ或IRP_MJ_WRITE请求创建这个MDL。如果一个IRP_MJ

haiross的专栏 2008

【数据结构-5】单链表的实现

单链表,具体来说是单向的、不带头的、不循环的链表。链表由一个一个节点组成,每个节点分为数据域和指针域,数据域存放数据,指针域存放下一节点的地址。这样,就可以根据指针域中的地址找到下一个节点,节点就串起来了构成了单链表。

weixin_44218929的博客 195

pandas 深度入门:从数据结构到一份真实销售报表

本文系统讲解Pandas核心应用,从三分钟安装到完整月度报表生成,涵盖数据读取、清洗、筛选、分组聚合、表连接、透视表与时间序列等13个关键环节。强调“先看数据再动手”,掌握Series/DataFrame/Index结构本质,熟练运用loc/iloc、merge校验、agg/transform区别,通过真实案例实现高效报表自动化,告别手动Excel操作。最后提供性能优化与高频报错解决方案,助力读者快速上手,真正实现“写二十行代码,跑三秒出结果”。

信息安全领域优质创作者|操作系统领域专家 291
上一篇: 文件系统Minifilter驱动(十)
下一篇: FSFD入门 - 启
jununfly
博客等级 码龄19年 41粉丝 2原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值