WdfMemoryCreate 函数 (wdfmemory.h)
[适用于 KMDF 和 UMDF]
WdfMemoryCreate 方法创建框架内存对象并分配指定大小的内存缓冲区。
语法
NTSTATUS WdfMemoryCreate(
[in, optional] PWDF_OBJECT_ATTRIBUTES Attributes,
[in] POOL_TYPE PoolType,
[in, optional] ULONG PoolTag,
[in] size_t BufferSize,
[out] WDFMEMORY *Memory,
[out, optional] PVOID *Buffer
);
参数
[in, optional] Attributes
指向包含新内存对象的对象属性 的 WDF_OBJECT_ATTRIBUTES 结构的指针。 此参数是可选的,可以WDF_NO_OBJECT_ATTRIBUTES。
[in] PoolType
一个POOL_TYPE类型的值,用于指定要分配的内存类型。
[in, optional] PoolTag
已分配内存的驱动程序定义的池标记。 调试器显示此标记。 驱动程序通常指定最多四个字符的字符串,由单引号分隔, (例如“dcba”) 。 标记中每个字符的 ASCII 值必须介于 0 和 127 之间。 如果每个池标记是唯一的,则调试驱动程序会更容易。
如果 PoolTag 为零,框架会提供默认池标记,该标记使用驱动程序内核模式服务名称的前四个字符。 如果服务名称以“WDF”开头 (名称不区分大小写且不包含引号) ,则使用接下来的四个字符。 如果可用字符少于 4 个字符,则使用“FxDr”。
对于 KMDF 1.5 及更高版本,驱动程序可以使用 WDF_DRIVER_CONFIG 结构的 DriverPoolTag 成员来指定默认池标记。
[in] BufferSize
缓冲区的非零指定大小(以字节为单位)。
[out] Memory
指向接收新内存对象的句柄的位置的指针。
[out, optional] Buffer
指向位置的指针,该位置接收指向与新内存对象关联的缓冲区的指针。 此参数是可选的,可以为 NULL。
返回值
如果操作成功,WdfMemoryCreate 将返回STATUS_SUCCESS。 否则,此方法可能会返回以下值之一:
返回代码 | 说明 |
---|---|
|
检测到无效的参数。 |
|
内存不足。 |
有关 WdfMemoryCreate 方法可能返回的其他返回值的列表,请参阅 框架对象创建错误。
此方法还可能返回其他 NTSTATUS 值。
注解
WdfMemoryCreate 方法分配 BufferSize 参数指定大小的缓冲区,并创建表示缓冲区的框架内存对象。
若要获取缓冲区的地址,驱动程序可以为 WdfMemoryCreate 函数的 Buffer 参数提供非 NULL 值,或者驱动程序可以调用 WdfMemoryGetBuffer。
最好将内存分配为零内存,尤其是对于将通过网络等 (用户模式复制到不受信任的位置 ) 的分配,以避免泄露敏感信息。 默认情况下,WdfMemoryCreate 不对分配的内存进行零次初始化。
根据已分配内存的驱动程序使用模式,驱动程序编写者的建议是考虑:
- 调用 WdfMemoryCreate 后立即 RtlZeroMemory
- 或者,将零分配 API (ExAllocatePool2、 ExAllocatePoolZero 用于内核模式; HeapAlloc 具有用户模式 ) HEAP_ZERO_MEMORY 标志,后跟 WdfMemoryCreatePreallocated。 由于预先分配的缓冲区不会作为 WDFMEMORY 或其父删除的一部分自动删除,因此这不是最佳方法。
每个内存对象的默认父对象是表示调用 WdfMemoryCreate 的驱动程序的框架驱动程序对象。 如果驱动程序创建的内存对象与特定的设备对象、请求对象或其他框架对象一起使用,则应相应地设置内存对象的父对象。 删除父对象时,将删除内存对象及其缓冲区。 如果不更改默认父对象,内存对象及其缓冲区将一直保留,直到 I/O 管理器卸载驱动程序。
驱动程序还可以通过调用 WdfObjectDelete 来删除内存对象及其缓冲区。
如果 BufferSize 小于 PAGE_SIZE,则操作系统会向调用方提供所请求的内存字节数。 缓冲区不一定按页对齐,但它由 ntdef.h 中MEMORY_ALLOCATION_ALIGNMENT常量指定的字节数对齐。
如果 BufferSize PAGE_SIZE 或更高版本,则对于 KMDF,系统仅分配页对齐缓冲区。 如果 PoolType 参数为 NonPagedPool,系统会分配保存所有字节所需的页数。 上次分配的页面上任何未使用的字节基本上都是浪费的。
有关框架内存对象的详细信息,请参阅 使用内存缓冲区。
如果驱动程序为 PoolType 指定 PagedPool,则必须在 IRQL <= APC_LEVEL调用 WdfMemoryCreate 方法。 否则,可以在 IRQL <= DISPATCH_LEVEL 调用 方法。
示例
下面的代码示例创建一个框架内存对象,并分配一个大小为WRITE_BUFFER_SIZE的缓冲区。 内存对象的父对象是请求对象。
NTSTATUS status;
WDF_OBJECT_ATTRIBUTES attributes;
WDFMEMORY writeBufferMemHandle;
PVOID writeBufferPointer;
WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
attributes.ParentObject = requestHandle;
status = WdfMemoryCreate(
&attributes,
NonPagedPool,
0,
WRITE_BUFFER_SIZE,
&writeBufferMemHandle,
&writeBufferPointer
);
要求
要求 | 值 |
---|---|
目标平台 | 通用 |
最低 KMDF 版本 | 1.0 |
最低 UMDF 版本 | 2.0 |
标头 | wdfmemory.h (包括 Wdf.h) |
Library | Wdf01000.sys (KMDF) ;WUDFx02000.dll (UMDF) |
IRQL | 请参见“备注”部分。 |
DDI 符合性规则 | DriverCreate (kmdf) 、 KmdfIrql (kmdf) 、 KmdfIrql2 (kmdf) 、KmdfIrqlExplicit (kmdf) 、 ParentObjectCheck (kmdf) |