2-3-2 帮助中有的几类函数
在帮助中有很多的函数。作者本人没有数过,但是估计有上千个。幸运的是,大多数
是读者可能一辈子都不会使用的。比Win32API 好的是,大部分内核API 都有前缀。主要
的函数以Io-、Ex-、Rtl-、Ke-,Zw-和Nt-和Ps-开头。此外NDIS 网络驱动开发相关的函
数几乎都是以Ndis-开头的。
下面列出一些常用的内核API,但是并不详细介绍用法。在后面涉及实际开发的时候
再仔细说明。这里只是让读者获得初步印象,以便在后面见到相关代码的时候不会觉得太
困惑。
首先是常用的几个分配内存、获取互斥体等几个函数:
Ex-系列函数名 功能简述
ExAllocatePool 内存分配。相当于CRunTime 库里的
malloc。
下面是一组用于操作文件的Zw-系列的函数。Zw-和同名的Nt-函数有同样的功能。中
间实际上是从Zw-函数到Nt-函数的简单跳转关系。这些函数具有同名的Win32API 函数与
之对应。而哪些函数可以用于所谓的Native 程序,所以这个系列的函数被称为Native API。
请注意,对应的Nt-系列的函数在WDK 的帮助里是查不到的,头文件里也没有。但是确
实存在。自己声明后就可以使用。
Zw-系列函数名 对应的Nt-函数 功能简述
ZwCreateFile NtCreateFile 打开文件(实际上也可以用
于打开一个设备)。
ZwWriteFile NtWriteFile 写文件(实际上也可以用于
发写请求给设备)。
ZwReadFile NtReadFile 读,同上。
ZwQueryDirectoryFile NtQueryDirectoryFile 目录查询。
ZwDeviceIoControlFile NtDeviceIoControlFile 发出设备控制请求。
ZwCreateKey NtCreateKey 打开一个注册表键
ZwQueryValueKey NtQueryValueKey 读取一个注册表中的值。
表格 2 部分Zw-和Nt-系列的函数的代表
在进行字符串操作的时候,大量的使用到Rtl-函数。此外内存拷贝、比较、移动也是
比较常用的。还有一个经典的用法是或许当前操作系统的的版本判断。有时一些代码要根
据不同的操作系统版本(比如说是Windows 2000 还是Windows Vista)来处理。
Rtl-系列函数名 功能简述
RtlInitUnicodeString 初始化一个字符串。
RtlCopyUnicodeString 拷贝字符串。
RtlAppendUnicodeToString 一个字符串追加到另一个字符串后。
RtlStringCbPrintf 打印字符串到一个字符串中。相当于sprintf。
ExFreePool 内存释放。相当于CRunTime 库里的
free。
ExAcquireFastMutex 获取一个快速互斥体。互斥体用于多线
程环境下的同步。
ExReleaseFastMutex 释放一个快速互斥体。
ExRaiseStatus 抛出一个异常,带有一个错误的status
值。这个用于从代码很深的地方直接报
错。
表格 1 部分Ex-系列的函数的代表
RtlCopyMemory 内存数据块拷贝。
RtlMoveMemory 内存数据块移动。请问内存拷贝和内存移动有
什么区别?这是一个有名的面试题。请读者自
己思考下。
RtlZeroMemory 内存数据清零。
RtlCompareMemory 比较内存。
RtlGetVersion 获得当前Windows 的版本。
图表 XIII 部分Rtl-系列的函数
Io-开头的系列函数函数非常的重要。因为涉及到IO 管理器。IO 管理器就是将用户调
用的API 函数翻译成IRP 或者等价请求发送到内核各个不同的设备的关键组件。相关的函
数是我们几乎最常调用的。
Io-系列函数名 功能简述
IoCreateFile 打开文件。这个比ZwCreateFile 要更加底
层。
IoCreateDevice 生成一个设备对象。
IoCallDriver 发送请求。实际上这个函数可能是
IofCallDriver 的一个别名。WindowsIO 管理
器调用这个函数把不同的IRP 发到不同的
设备。
IoCompleteRequest 完成请求。这实际上是通知IO 管理器这个
IRP 已经完成了。
IoCopyCurrentIrpStackLocationToNext 拷贝当前IRP 栈空间到下一个栈空间。
IoSkipCurrentIrpStackLocationToNext 跳过当前IRP 的栈空间。
IoGetCurrentIrpStackLocation 获得IRP 的当前栈空间指针。
表格 3 部分Io-开头系列的函数
Ps-系列的函数大多是进程、线程信息相关的。Ndis-系列的函数有很多和其他前缀的
函数重复。功能是一样的,看似只是换了个前缀而已。貌似是MS 希望大家只使用Ndis-
系列的函数来开发NDIS 网络驱动。但是实际上没这个限制。这些函数在这里就不举例了。
请读者自己查看帮助吧。
如何学习API?作者本人的建议是对一个API 的详细了解,可以等到实际要用的时候
再去查帮助。但是平时没事的时候应该多看看,有哪些种类的API,大致提供哪些功能。
不必要详细了解,但是应该大致有所了解。这样当自己需要实现一个功能的时候,或许就
会想起某些API 提供哪些功能,通过哪几个步骤能达到自己的目的。否则在实际碰到问题
的时候,只能一筹莫展。但是不要企图以为,了解了所有的API,就无所不能了。这和背
完了四级的单词就能过四级完全是不同的两码事。