摘要: 介绍了Windows NT4.0内核形式设备驱动程序开发中的一般性进程。经过供给一个最小化驱动程序的中心代码,解说各组成部分的结构功用和运用办法。在实践中,结合本身的开发需求,可编写出具有实用价值的驱动程序。
关键词:Win32子体系 设备驱动 体系注册表 I/O恳求包
Windows NT 以其安全、安稳及界面友爱等特性逐步成为工业操控范畴的前台操作体系。面临工业操控中很多选用的串/并行通讯及总线操控等技能,要求用户不断开宣布满意本身需求的硬件设备,一起又要求用户运用程序与这些硬件设备进行通讯,发送操控指令,读取状况信息等等。Windows NT出于安全性、安稳性等考虑,不允许用户运用程序对物理硬件进行直接拜访,这就需求运用设备驱动程序跨过操作体系鸿沟对物理硬件进行操作,并向上供给客户运用程序操控接口以供调用。
1 分层结构与设备驱动程序
Windows NT分层结构(如图1所示)包含运转于用户形式及内核形式的各种部件,设备驱动程序在图1的左下角,处于内核形式下I/O管理器之中。
2 驱动程序工作方式
内核形式驱动程序与运用程序之间的最大不同之一是驱动程序的操控结构。内核形式驱动程序没有main或WinMain,而是由I/O管理器根据需求调用一个驱动程序例程:
· 驱动程序被装入时;
· 驱动程序被卸出或体系封闭时;
· 用户程序宣布I/O体系服务调用时;
· 同享硬件资源对驱动程序可用时;
· 设备操作进程中的任何时候。
3 初始化进程
3.1 体系注册表中有关设备驱动程序的项目是体系加载设备驱动程序的进口点
体系注册表中用于体系加载设备驱动程序的项目如下:
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\DriverName]
″Type″ = dword00000001
″Start″ = dword00000002
″Group″ = ″Extended Base″
″ErrorControl″ = dword∶00000001
其间Start意义如下:
SERVICE_BOOT_START (0×0) 操作体系装入时
SERVICE_SYSTEM_START (0×01) 操作体系初始化时
SERVICE_AUTO_START (0×02) 服务操控管理器发动时
SERVICE_DEMAND_START (0×03) 服务操控管理器手艺发动
SERVICE_DISABLED (0×04) 不发动
Type意义如下:
SERVICE_KERNEL_DRIVER (0×1)
SERVICE_FILE_SYSTEM_DRIVER (0×2)
SERVICE_ADAPTER (0×4)
体系注册表中用于设备驱动程序加载后读取的项目如下:
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\DriverName\Parameters]
″Parameter1″ = dword∶00000001
″Parameter2″ = dword∶00000004
3.2 加载驱动程序的装入例程
I/O管理器调用驱动程序的DriverEntry例程,履行初始化。该例程完结:
· 初始化其它例程的进口;
· 创立命名设备目标;
· 读取体系注册表中相关项目并声明必要的资源;
· 设置内核驱动程序名与Win32子体系名的联接;
· 创立或初始化恣意驱动程序运用的目标、类型和资源;
· 回来状况值。
I/O管理器树立与设备相关的Driver目标,并将其传递给DriverEntry例程。实际上Driver目标基本上是一个目录,含有指向各个驱动程序服务例程函数的指针,其结构如表1所示。
表1 Driver目标域阐明
I/O管理器可以找到DriverEntry例程,是由于它有一个公认的姓名,而其他的例程则经过下列两种办法查找:
·在Driver目标中有清晰槽的函数如DirverObject->DriverUnload;
·在Driver目标的MajorFunction数组中——Driver目标的MajorFunction支撑两种类型的功用代码。一种为规范的功用代码,如IRP_MJ_CREATE。另一种是用户自定义的功用代码,如IRP_MJ_DEVICE_CONTROL。
一切驱动程序有必要支撑IRP_MJ_CREATE功用代码,这是由于Win32子体系下的用户程序调用CreateFile函数创立设备时,发生该功用代码。假如不处理这个功用代码,Win32程序就不能得到设备句柄。
用户自定义的功用代码IRP_MJ_DEVICE_CONTROL只要在用户形式下的客户程序履行自定义的功用时可用。
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath)
{
//声明设备目标
PDEVICE_OBJECT DeviceObject,
//生成函数接口指针
DriverObject->MajorFunction[IRP_MJ_CREATE]=XxSelfDispatch;
DriverObject->MajorFunction[IRP_MJ_CLOSE]=
XxSelfDispatch;
DriverObject->MajorFunction[IRP_MJ_READ]=
XxReadDispatch;
DriverObject->MajorFunction[IRP_MJ_WRITE]=
XxWriteDispatch
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]=XxSelfDispatch
DriverObject->DriverUnload=XxUnload
//生成Windows NT Executive知道的设备名
RtlInitUnicodeString(NtDeviceName, SelfDeviceName);
//生成自己的设备
Status=IoCreateDevice(
DriverObject, // Driver目标
sizeof(SELF_DEV%&&&&&%E_INFO), // Device目标
Extension结构巨细
NtDeviceName,
DeviceType,
0,
FALSE, // 不履行
DeviceObject //Device目标指针
);
//生成Win32子体系下的用户程序可辨认的设备名