开发驱动程序的过程[3]34245
Windows 2000驱动程序支持的例程
I/O管理器和WIN2000其它的内核模式部分提供大量的供驱动程序调用的函数。DDK文文件描述了这些函数。现在,指出WIN2000支持的例程种类已经足够。如表5.1所示:
分类
支持
函数名
Executive
存储器分配,互锁队列区域,监控列表,系统工作者线程
ExXxx()
HAL
设备寄存器,总线访问
HalXxx()
I/O Manager
普通驱动程序支持
IoXxx()
Kernel
DPC,同步
KeXxx()
Memory Manager
虚拟存储器到物理存储器的映 射,存储器分配
MmXxx()
Object Manager
句柄管理
ObXxx()
Process Manager
系统线程管理
PsXxx()
Runtime library
字符串操作,大整数运算,寄存器访问,安全性函数,时间和日期函数,队列和列表支持
RtlXxx() (大部分的例程)
Security Monitor
特权检查,安全描述符函数
SeXxx()
(Miscellaneous)
内部系统服务
ZwXxx()
表5.1WIN2000支持的例程种类
ZwXxx函数需要更多的说明。它们实际上是为所有的NtXxx用户模式系统服务的内部调用接口。用户模式和内核模式接口时不同的,ZwXxx函数不执行任何参数校验。虽然这样的函数有很多,DDK文件仅仅描述很少一部分。使用无正式文件的函数是一个冒险,因为微软在未来可能改变或者删除这些函数。
I/O管理器提供几个方便的函数,它们包装了一个或者多个对其它内核模块的低级的调用,应该尽量使用它们。
丢弃初始化例程
一些编译器支持声明某些函数函数可以丢弃的选项。被选中的函数在驱动程序完成加载后被移出存储器,这样使驱动程序更小。最好使用这种开发环境。
可以丢弃的函数是DriverEntry和那些只是被DriverEntry调用的子程序。以下的代码片段描写怎样利用可以丢弃的代码(使用微软的C程序开发环境):
#ifdef ALLOC_PRAGMA
#pragma alloc_text( init, DriverEntry )
#pragma alloc_text( init, FuncCalledByDriverEntry )
#pragma alloc_text( init, OtherFuncCalledByDriverEntry )
:
#endif
alloc_text pragma必须出现在函数名声明之后,定义之前。在pragma声明中的函数必须在同一个编辑单元。
控制驱动程序分页
没分页的系统存储器是宝贵的资源。驱动程序可以定义适当的例程到分页的存储器来减少非分页存储器的负担,任何IRQL是PASSIVE_LEVEL的函数可以在分页的存储器中运行,包括Reinitialize例程,Unload例程,Shutdown例程,Dispatch例程,线程函数以及任何运行在PASSIVE_LEVEL IRQL的帮助函数。再一次,是alloc_text pragma执行这个声明,例子如下:
#ifdef ALLOC_PRAGMA
#pragma alloc_text( page, Unload )
#pragma alloc_text( page, Shutdown )
#pragma alloc_text( page, DispatchRead )
#pragma alloc_text( page, DispatchHelper )
:
#endif
最后,如果整个驱动程序很少使用,它可以被暂时的被翻出存储器。MmPageEntireDriver例程不管驱动程序声明的存储器管理属性,就将整个模块暂时的翻页。这个函数应该在DriverEntry例程的末尾调用和当不再打开任何它的设备句柄时从IRP_MJ_CLOSE的派遣例程,当使用这个驱动程序的时候,就在IRP_MJ_CREATE的派遣例程中调用MmResetDriverPaging来使驱动程序的页属性恢复正常。
当使用者个技术的时候,注意两件事:
1. 调用MmPageEntireDriver时,确定没有IRP被驱动程序的高级IRQL部分处理。
2. 当ISR被分页的时候,确定没有设备中断到达。

数据正在载入中..