Windows驱动程序概述

Windows驱动概述

Windows驱动程序分为两种:

  • 不支持即插即用功能的NT驱动(包含NTDDK.h头文件)
  • 支持即插即用功能的WDM驱动(包含WDM.h头文件)

在Windows驱动程序开发中,所有程序的函数和变量要被指明加载到分页内存还是非分页内存

Windows操作驱动的基本概念

Windows API分为三类:

  1. USER函数:这类函数管理窗口,菜单,对话框和控件
  2. GDI函数:这类函数在物理设备上执行绘图操作
  3. KERNEL函数:这类函数管理非GUI资源

Native API

大部分Win32子系统的API都是通过Native API的函数实现的,所有Native API都是在Ntdll.dll中实现

内核

内核提供的功能

  • 对内核对象的支持
  • 对线程的调度
  • 对多处理器同步的支持
  • 中断处理函数的支持
  • 对错误陷阱的支持
  • 对其他硬件特殊功能的支持

加载NT式驱动

在HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services中添加新项目,项目名称为驱动名称
添加子键:
DisplayName:在设备管理器中显示
ImagePath:要以\??\开头,表示符号链接
Start
Type:为1表示在内核模式下下载

SCM服务组件和Windows服务

加载和卸载NT驱动分为四个步骤 :

  1. 为NT驱动创建新的服务
  2. 开启此项服务
  3. 关闭此项服务
  4. 删除NT驱动所创建的服务

以上四步都是通过调用SCM组件的服务来实现的

1
2
3
4
5
6
//打开SCM管理器函数,用于SCM初始化
SC_HANDLE OpenSCManager(
LPCTSTR lpMachineName, //计算机名称
LPCTSTR ipDatabaseName, //SCM数据库名称
DWORD dwDesiredAccess //使用权限
);

lpMachineName:指定计算机名称,如果未NULL,代表本机
ipDatabaseName:指定SCM数据的名称,如果为NULL代表使用缺省数据库
dwDesiredAccess:使用权限,一般设置为SC_MANAGER_ALL_ACCEDD

1
2
3
4
//关SCM管理器句柄,用于SCM的清除工作
BOOL CloseServiceHandle(
SC_HANDLE hSCObject //要关闭的SCM句柄
);

hSCObject:要关闭的SCM句柄

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//创建服务
SC_HANDLE CreateService(
SC_HANDLE hSCManager, //SCM管理器句柄
LPCTSTR lpServiceName, //服务名称,在设备管理器中看到的名称
LPCTSTR lpDispalyName, //服务显示出的名称
DWORD dwDesiredAccess, //打开权限
DWORD dwServiceType, //服务类型
DWORD dwStartType, //打开服务的时间
DWORD dwErrorControl, //错误处理代码
LPCTSTR lpBinaryPathName, //二进制文件的代码
LPCTSTR lpLoadOrderGroup, //开启服务的用户组
LPDWORD lpdwTagId, //输出验证标签
LPCTSTR lpDependencies, //所依赖的服务的名称
LPCTSTR lpServiceStartName, //用户账户名称
LPCTSTR lpPassword //用户口令
);

dwDesiredAccess:打开权限,一般设置为SERVICE_ALL_ACCESS
dwServiceType:服务类型,有以下两种选择

  • SERVICE_FILE_SYSTEM_DRIVER:文件系统的驱动
  • SERVICE_KERNEL_DRIVER:普通程序的驱动,一般用此项
    dwStartType:打开服务的时间,有以下选择
  • SERVICE_AUTO_START:驱动自动加载
  • SERVICE_BOOT_START:被system loader加载,即系统启动前就被启动
  • SERVICE_DEMAND_START:按照需要时启动,一般选择此项
    dwErrorControl:错误处理代码,有以下选择
  • SERVICE_ERROR_IGNORE:遇到错误全部忽略掉
  • SERVICE_ERROR_NORMAL:遇到错误按照缺省办法处理
  • SERVICE_ERROR_CRITICAL:增加对错误处理的校验,并提示出对话框,并且记录错误信息到log文件中
  • lpBinaryPathName:服务所用的二进制代码,即编译后的驱动程序
    1
    2
    3
    4
    5
    6
    //打开服务
    SC_HANDLE Openservice(
    SC_HANDLE hSCMananer, //SCM数据库句柄
    LPCTSTR lpServiceName, //服务名称
    DWORD dwDesiredAccess //访问权限
    );

hSCMananer:SCM管理器句柄,也就是OpenSCManager打开的句柄

1
2
3
4
5
6
//控制服务
BOOL ControlService(
SC_HANDLE hService, //服务的句柄
DWORD dwControl, //控制码
LPSERVICE_STATUS lpServiceStatus //返回状态
);

dwControl:对服务的控制码,常用控制码如下:

  • SERVICE_CONTROL_CONTINUE:针对暂停的服务发出继续运行的命令
  • SERVICE_CONTROL_PAUSE:针对正在运行的服务发出暂停的命令
  • SERVICE_CONTROL_STOP:针对运行的服务发出停止的命令

加载WDM式驱动

WDM式驱动增加了对即插即用的支持,安装时需要提供一个INF文件进行配合
WDM式驱动程序安装会改变注册表的三方面:

  1. 硬件子键:位于HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum
  2. 类子键:位于HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class
  3. 服务子键:位于HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services