- Windows内核编程
- (美)帕维尔·约西福维奇
- 562字
- 2021-07-09 20:28:54
3.6 动态内存分配
驱动程序经常需要进行动态内存分配。我们曾在第1章中提到,内核的栈相当小,因此任何大块的内存都必须动态分配。
内核为驱动程序提供了两个通用的内存池(内核本身也使用它们)。
- 分页池—在需要时能够将页面换出的内存池。
- 非分页池—永远不会换出页面,保证驻留在RAM里的内存池。
很显然,非分页池是一个“更好”的内存池,因为它不会导致页面错误。在本书的后面我们会看到一些需要从非分页池分配的例子。驱动程序要尽可能少地使用非分页池,除非必需。其他任何情况驱动程序都应该使用分页池。POOL_TYPE
这个枚举类型表示内存池的类型。这个枚举类型包括很多内存池的“类型”,但是只有三种可以被驱动程序使用:PagedPool
、NonPagedPool
和NonPagePoolNx
(没有执行权限的非分页池)。
表3-4总结了最常用的内核内存池函数。
表3-4 内核内存池分配函数
有些函数中的tag参数允许用一个4字节的值为分配的内存做标记。通常这个值由4个ASCII字符组成,用来在逻辑上指明该驱动程序或者它的一部分。这些标记可以用来指内存泄漏—如果发现在驱动程序卸载之后,仍然有带有该驱动程序标记的内存块遗留。从这些内存池分配的内存块(以及各块的标记)可以用WDK的PoolMon
工具来查看。也能用我写的PoolMonX
工具(可以从http://www.github.com/zodiacon/AllTools下载)。图3-1显示了PoolMonX
(v2)的截屏。
图3-1 PoolMonX(v2)
下面的代码显示了内存分配和字符串复制过程,用来将传递给DriverEntry
的注册表路径保存下来,并在Unload例程中释放。