使用内存缓冲区

驱动程序通常使用内存缓冲区向/从框架和其他驱动程序传递数据,或在本地存储信息。 本主题介绍 框架内存对象旁观列表MDL本地缓冲区

使用框架内存对象

框架使用 内存对象 来描述驱动程序从中接收并传递给框架的内存缓冲区。 每个框架内存对象表示一个缓冲区。

若要创建内存对象,驱动程序会调用以下对象方法之一:

若要获取表示接收的 I/O 请求缓冲区的内存对象,驱动程序会调用 WdfRequestRetrieveInputMemoryWdfRequestRetrieveOutputMemory。 有关检索 I/O 请求缓冲区的详细信息,请参阅 在 Framework-Based 驱动程序中访问数据缓冲区

若要获取内存对象缓冲区的地址和大小,驱动程序会调用 WdfMemoryGetBuffer

若要将数据移入或移出内存对象的缓冲区,驱动程序会调用 WdfMemoryCopyFromBufferWdfMemoryCopyToBuffer。 这些对象方法检查源大小和目标大小,并防止缓冲区溢出错误。

如果驱动程序通过调用 WdfMemoryCreatePreallocated 创建内存对象,则它随后可以通过调用 WdfMemoryAssignBuffer 将不同的缓冲区分配给内存对象。

当驱动程序将 I/O 请求发送到 I/O 目标时,它通常会将输入或输出缓冲区传递给 框架 I/O 目标对象方法。 驱动程序通过传递描述缓冲区的 WDF_MEMORY_DESCRIPTOR 结构或通过传递内存对象句柄来指定缓冲区。 (同步发送 I/O 请求的 I/O 目标对象方法需要 WDF_MEMORY_DESCRIPTOR 结构,异步发送 I/O 请求的方法需要内存对象句柄。)

有关内存缓冲区何时有效的信息,请参阅 内存缓冲区生命周期

使用 Lookaside 列表

如果驱动程序需要许多大小大致相同的缓冲区,则应从 旁视列表中分配它们。 驱动程序通过调用 WdfLookasideListCreate 创建查看列表。 随后,驱动程序可以通过调用 WdfMemoryCreateFromLookaside 从 lookaside 列表中获取缓冲区。

每次驱动程序调用 WdfMemoryCreateFromLookaside 时,框架都会创建一个内存对象,从 lookaside 列表中获取缓冲区,并将缓冲区分配给对象。 当驱动程序使用完这些内存对象之一后,它将调用 WdfObjectDelete,这将删除内存对象并将缓冲区空间返回到旁观列表。

操作系统管理分配给旁视列表的内存资源。 如果驱动程序在无可用(例如驱动程序第一次调用 WdfMemoryCreateFromLookaside)时从旁视列表中请求缓冲区,系统会分配缓冲区并将其分配给列表。 当驱动程序 (调用 WdfObjectDelete 并将缓冲区空间返回到旁观列表) 时,系统会在列表中保留现在未分配的缓冲区,直到驱动程序再次需要它。 系统根据需要增加列表的大小;例如,更频繁地请求缓冲区的驱动程序会收到较大的旁观列表。 另一方面,如果驱动程序未全部使用缓冲区,系统可能会减少列表中的缓冲区数。

使用 MDL

某些驱动程序使用内存描述符列表 (MDL) 来描述缓冲区。 例如, (DMA) 设备的直接内存访问驱动程序必须将 MDL 传递给 WdfDmaTransactionInitialize 方法(如果它调用该方法)。

使用 MDL 的驱动程序可以通过调用 WdfRequestRetrieveInputWdmMdlWdfRequestRetrieveOutputWdmMdl 来获取表示已接收 I/O 请求缓冲区的 MDL。

大多数基于框架的驱动程序不使用 MDL。

分配本地缓冲区

需要不传递给框架的本地内部缓冲区空间的驱动程序不必创建内存对象来表示缓冲区。 驱动程序可以调用 ExAllocatePoolWithTag 来分配内部缓冲区。 驱动程序使用完缓冲区后,必须调用 ExFreePoolWithTag

但是,驱动程序还可以将内存对象用于本地缓冲区。 使用内存缓冲区(而不是调用 ExAllocatePoolWithTag)的一个优点是,在删除每个对象的父对象时,框架会自动删除内存对象及其缓冲区。

重要

本主题中讨论的 ExAllocatePool DDI 已在 Windows 10 版本 2004 中弃用,并已替换为 ExAllocatePool2ExAllocatePool3。 有关详细信息,请参阅 将已弃用的 ExAllocatePool 调用更新到 ExAllocatePool2 和 ExAllocatePool3

对齐缓冲区

驱动程序可以使用 WDF_ALIGN_SIZE_UPWDF_ALIGN_SIZE_DOWN 函数来计算与指定的对齐偏移量对齐的缓冲区大小。 如果驱动程序必须分配多个连续缓冲区,并且每个缓冲区必须从地址对齐边界开始,则此计算非常有用。