windows驱动程序使用的内存资源非常珍贵,分配内存时要尽量节约。
和应用程序一样,局部变量是放在栈(Stack)空间中的,但栈空间不会像应用程序那么大
所以驱动程序部适合递归调用或者局部变量是大型结构体。
若果需要大型结构体,要在堆(Heap)中申请
堆中申请内存的函数由以下几个,原型如下:
PVOID ExAllocatePool(IN POOL_TYPE PoolType, IN SIZE_T BumberOfBytes);
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,分别可以指定如下几种。
NonPagedPool 指定要求分配非分页内存
PagedPool 指定要求分配分页内存
NonPagedPoolMustSucceed 指定分配非分页内存,必须成功
DontUseThisType 未指定
NonPagedPoolCacheAligned 指定要求分配非分页内存,而且必须内存对齐
PagedPoolCacheAligned 指定分配分页内存,而且必须内存对齐
NonPagedPoolCacheAlignedMustS 指定分配非分页内存,而且必须内存对齐,必须成功。
将分配的内存,进行回收的函数是ExFreePool和ExFreePoolWithTag
VOID ExFreePool(IN PVOID P);
NTKERNELAPI VOID ExFreePoolWithTag(IN PVOID P, IN ULONG Tag);
参数P就是要释放的地址