将对已弃用的 ExAllocatePool 调用更新为 ExAllocatePool2 和 ExAllocatePool3

从 Windows 10 版本 2004 开始,以下 DDI 已弃用,应按本主题中所述进行替换。

ExAllocatePool

ExAllocatePoolWithTag

ExAllocatePoolWithQuota

ExAllocatePoolWithQuotaTag

ExAllocatePoolWithTagPriority

Windows 10版本 2004 及更高版本的驱动程序更新

如果要生成面向 Windows 10 版本 2004 及更高版本的驱动程序,请改用替换 API ExAllocatePool2ExAllocatePool3

旧 API 新的 API
ExAllocatePool ExAllocatePool2
ExAllocatePoolWithTag ExAllocatePool2
ExAllocatePoolWithQuota ExAllocatePool2
ExAllocatePoolWithQuotaTag ExAllocatePool2
ExAllocatePoolWithTagPriority ExAllocatePool3

默认情况下,新 API 将零池分配,以帮助避免可能的内存泄漏 bug。

ExAllocatePool/ExAllocatePoolWithTag

// Old code
PVOID Allocation = ExAllocatePoolWithTag(PagedPool, 100, 'abcd');
RtlZeroMemory(Allocation, 100);

// New code
PVOID Allocation = ExAllocatePool2(POOL_FLAG_PAGED, 100, 'abcd');

旧的池分配 API 接受 POOL_TYPE 参数,但新的分配 API 接受 POOL_FLAGS 参数。 更新任何关联的代码以使用新的 POOL_FLAGS 参数。

ExAllocatePoolWithQuota/ExAllocatePoolWithQuotaTag

默认情况下,新函数将在分配失败时返回 NULL。 若要让分配器在失败时引发异常,必须按照 ExAllocatePool2 中所述传递POOL_FLAG_RAISE_ON_FAILURE标志。

// Old code
PVOID Allocation = ExAllocatePoolWithQuotaTag(PagedPool | POOL_QUOTA_FAIL_INSTEAD_OF_RAISE, 100, 'abcd');
RtlZeroMemory(Allocation, 100);

// New code
PVOID Allocation = ExAllocatePool2(POOL_FLAG_PAGED | POOL_FLAG_USE_QUOTA, 100, 'abcd');

ExAllocatePoolWithTagPriority

// Old code
PVOID Allocation = ExAllocatePoolWithTagPriority(PagedPool, 100, 'abcd', HighPoolPriority);
RtlZeroMemory(Allocation, 100);

// New code
POOL_EXTENDED_PARAMETER params = {0};
params.Type = PoolExtendedParameterPriority;
params.Priority = HighPoolPriority;
PVOID Allocation = ExAllocatePool3(POOL_FLAG_PAGED, 100, 'abcd', &params, 1);

适用于早于 Windows 10 版本 2004 的 Windows 版本的驱动程序更新

如果要生成面向 Windows 10 版本 2004 之前的 Windows 版本的驱动程序,则必须使用以下强制内联包装函数。

在调用池分配函数之前,还必须在驱动程序初始化期间 #define POOL_ZERO_DOWN_LEVEL_SUPPORT 并调用 ExInitializeDriverRuntime

本地定义的内联函数

PVOID
NTAPI
ExAllocatePoolZero (
    _In_ __drv_strictTypeMatch(__drv_typeExpr) POOL_TYPE PoolType,
    _In_ SIZE_T NumberOfBytes,
    _In_ ULONG Tag
    )

PVOID
NTAPI
ExAllocatePoolQuotaZero (
    _In_ __drv_strictTypeMatch(__drv_typeExpr) POOL_TYPE PoolType,
    _In_ SIZE_T NumberOfBytes,
    _In_ ULONG Tag
    )

PVOID
NTAPI
ExAllocatePoolPriorityZero (
    _In_ __drv_strictTypeMatch(__drv_typeExpr) POOL_TYPE PoolType,
    _In_ SIZE_T NumberOfBytes,
    _In_ ULONG Tag,
    _In_ EX_POOL_PRIORITY Priority
    )

有关这些代码包装器的实现代码,请参阅最新的 wdm.h 标头。 例如,这是 ExAllocatePoolPriorityZero 的实现,显示了 RtlZeroMemory 的用法。

{
    PVOID Allocation;

    Allocation = ExAllocatePoolWithTagPriority((POOL_TYPE) (PoolType | POOL_ZERO_ALLOCATION),
                                               NumberOfBytes,
                                               Tag,
                                               Priority);

#if defined(POOL_ZERO_DOWN_LEVEL_SUPPORT)

    if ((!ExPoolZeroingNativelySupported) && (Allocation != NULL)) {
        RtlZeroMemory(Allocation, NumberOfBytes);
    }

#endif

    return Allocation;
}

将旧 API 映射到新 API

旧 API 新的 API
ExAllocatePool ExAllocatePoolZero
ExAllocatePoolWithTag ExAllocatePoolZero
ExAllocatePoolWithQuota ExAllocatePoolQuotaZero
ExAllocatePoolWithQuotaTag ExAllocatePoolQuotaZero
ExAllocatePoolWithTagPriority ExAllocatePoolPriorityZero

示例

// Old code
PVOID Allocation = ExAllocatePoolWithTag(PagedPool, 100, 'abcd');
RtlZeroMemory(Allocation, 100);

// New code

// Before headers are pulled in (or compiler defined)
#define POOL_ZERO_DOWN_LEVEL_SUPPORT

// Once during driver initialization
// Argument can be any value
ExInitializeDriverRuntime(0);

// Replacement for each pool allocation
PVOID Allocation = ExAllocatePoolZero(PagedPool, 100, 'abcd');

驱动程序验证程序 UnSafeAllocatePool 规则

驱动程序验证程序 UnSafeAllocatePool 规则是一条重要的安全规则,用于检查驱动程序是否未使用已弃用的 DDI 来分配内存。 此规则在预览版 WDK 版本 20236 及更高版本中可用。

另请参阅

ExAllocatePool2

ExAllocatePool3

ExAllocatePool

ExAllocatePoolWithTag

ExAllocatePoolWithQuota

ExAllocatePoolWithQuotaTag

ExAllocatePoolWithTagPriority