[适用于 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 方法可能返回的其他返回值的列表,请参阅 Framework 对象创建错误。
此方法还可以 返回其他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,则作系统将确切地为调用方提供请求的内存字节数。 缓冲区不一定是页面对齐的,但它是由MEMORY_ALLOCATION_ALIGNMENT常量在 ntdef.h 中指定字节数对齐的。
如果 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) |
图书馆 | Wdf01000.sys(KMDF):WUDFx02000.dll (UMDF) |
IRQL | 请参阅“备注”部分。 |
DDI 符合性规则 | DriverCreate(kmdf),KmdfIrql(kmdf),KmdfIrql2(kmdf),KmdfIrqlExplicit(kmdf),ParentObjectCheck(kmdf) |