Windows驱动程序使用的内存资源非常珍贵,分配内存时要尽量节约。和应用程序一样,局部变量是存放在栈(Stack)空间中的。但栈空间不会像应用程序那么大,所以驱动程序不适合递归调用或者局部变量是大型结构体。如果需要大型结构体,请在堆(Heap)中申请。
堆中申请内存的函数有以下几个,原型如下:
PVOID ExAllocatePool(
IN POOL_TYPE PoolType,
IN SIZE_T NumberOfBytes
);
PVOID ExAllocatePoolWithTag(
IN POOL_TYPE PoolType,
IN SIZE_T NumberOfBytes,
IN ULONG Tag
);
PVOID ExAllocatePoolWithQuota(
IN POOL_TYPE PoolType,
IN SIZE_T NumberOfBytes
);
PVOID ExAllocatePoolWithQuotaTag(
IN POOL_TYPE PoolType,
IN SIZE_T NumberOfBytes,
IN ULONG Tag
);
* PoolType:是个枚举变量,如果此值为NonPagedPool,则分配非分页内存。如果此值为PagedPool,则分配内存为分页内存。
* NumberOfBytes:是分配内存的大小,注释最好是4的倍数。
* 返回值,返回分配的内存地址,一定是内核模式地址。如果返回0,则代表分配失败。
以上四个函数功能类似。
函数以WithQuota结尾的代表分配的时候按配额分配。
函数以WithTag结尾的函数,和ExAllocatePool功能类似,唯一不同的是多了一个Tag参数,系统在要求的内存外又额外地多分配了4个字节的标签。在调试的时候,可以找出是否有标有这个标签的内存没有被释放。 以上四个函数都需要指定PoolType,分别可以指定如下几种:
typedef enum _POOL_TYPE {
NonPagedPool, // 非分页内存
PagedPool, // 指定要求分配分页内存
NonPagedPoolMustSucceed, // 指定分配非分页内存,必须成功
DontUseThisType, // 未指定
NonPagedPoolCacheAligned, // 指定要求分配非分页内存,而且必须内存对齐
PagedPoolCacheAligned, // 指定分配分页内存,而且必须内存对齐
NonPagedPoolCacheAlignedMustS, // 指定分配非分页内存,而且必须内存对齐,且必须成功
MaxPoolType,
NonPagedPoolSession = 32,
PagedPoolSession = NonPagedPoolSession + 1,
NonPagedPoolMustSucceedSession = PagedPoolSession + 1,
DontUseThisTypeSession = NonPagedPoolMustSucceedSession + 1,
NonPagedPoolCacheAlignedSession = DontUseThisTypeSession + 1,
PagedPoolCacheAlignedSession = NonPagedPoolCacheAlignedSession + 1,
NonPagedPoolCacheAlignedMustSSession = PagedPoolCacheAlignedSession + 1,
} POOL_TYPE;
分配的内存,进行回收的函数是ExFreePool和ExFreePoolWithTag,他们的原型是:
VOID ExFreePool(
IN PVOID P
);
VOID ExFreePoolWithTag(
IN PVOID P,
IN ULONG Tag
);
* P就是要释放的地址