http://blog.csdn.net/zuishikonghuan/article/details/49717679
在驱动开发中,我们不应该使用C/C++运行时函数中的malloc或者calloc函数分配内存,更不应该使用new关键字,因为内核中的内存分配需要特殊处理。
在应用程序中,每个应用都有2G的虚拟内存,因此内存并不紧张,而所有的驱动程序共用内核模式的2G虚拟内存,因此内核中的资源非常宝贵,应该尽量节省。
更可怕的是内存泄露,应用程序即使发生了内存泄露,在其结束时操作系统可以通过进程上下文中的虚拟内存页面映射关系,释放这一部分虚拟内存对应的物理内存,但是驱动程序如果申请虚拟内存后不释放,结果就是在系统重新启动之前这一部分地址所在的内存页面一直处于“被申请未释放”的状态,想想那种情景吧。如果驱动程序申请的虚拟内存位于非页内存池,那么是不能交换到磁盘文件中的,因此这一部分虚拟内存对应的物理内存也一直无法空闲出来,后果更加严重。
内核中申请虚拟内存的函数一般有这么几个:ExAllocatePool(WithTag)、ExAllocatePoolWithQuota(Tag)、ExFreePool(WithTag),我们来看看这两个ExAllocatePool(申请内核虚拟内存)和ExFreePool(释放内核虚拟内存),其他的都差不多,具体可以看MSDN。
PVOID ExAllocatePool(
_In_ POOL_TYPE PoolType,
_In_ SIZE_T NumberOfBytes
);
PoolType:指定的池内存分配的类型。请参阅 POOL_TYPE。
常用的有:
NonPagedPool:从非分页内存池中分配虚拟内存
PagedPool:从分页内存池中分配虚拟内存
NumberOfBytes:指定要分配的字节数。
返回值:成功返回分配的内存指针,失败返回NULL。
VOID ExFreePool(
_In_ PVOID P
);
P:指定要释放的内存块的地址。
还有一点时间,说说内核中的错误码NTSTATUS吧
32位系统下,NTSTATUS是unsigned long类型,内核中的函数的返回值以及我们以后处理派遣函数等等都会用到。
其中,STATUS_SUCCESS表示成功 ,可以用NT_SUCCESS宏判断是否是STATUS_SUCCESS 。
自然还有很多其他的错误码,比如
STATUS_UNSUCCESS(不成功)
STATUS_ACCESS_DENIED(访问被拒绝)
STATUS_IN_PAGE_ERROR(页故障)
等等