正文开始:
前面我们学到了一个简单的驱动程序“beeper.sys”,今天我们来学习怎么自己编程来加载它,我们前面介绍过,NT式驱动的加载与卸载是基于服务的, 我们先来简单介绍下Windows服务吧,在这方面罗云彬翻译的KmdTut中文版里介绍的不错,我对原文进行了适当的补充完善后摘抄入此,内容如下: 5.1 Windows服务
Windows NT使用某种机制来启动进程,并让它们不和某个具体的交互式的用户界面相关联,这些进程就被称为服务(service),服务的一个很好的例子就是Web 服务器,这些Web服务都没有用户界面,服务是唯一以这种方式运行的应用程序(注:指没有用户界面,当然,严格地说病毒、木马以及所有不想见光的程序也是 这样的~~),服务可以在系统启动的时候自动启动,也可以被手工启动,从这一点来看,设备驱动程序和服务是类似的。
Windows NT还支持驱动程序服务,只要使用的时候遵循设备驱动程序协议就可以了,这和用户模式的服务类似,所以,"服务"一词既可以指用户模式的服务进程或者内核 模式的设备驱动程序,微软不知何故没有明确地区分两者的概念,所以下面的叙述可能看起来有点让人疑惑。可能有的地方我会说到"driver"一词,但在其 他的文章中可能说到"service"一词,但既然这篇教程讲的是如何编写内核设备驱动程序,那么我们就约定无论说到"service"还 是"driver",我们的意思都是指"驱动程序",当的确需要提及"服务"的时候,我会明确地指出来的。
另外,请读者时刻记得,文档中关于服务管理的函数其实是叙述得相当含糊的,因为这些函数既能用于驱动程序也能用于服务,在下面的文章中,我们只强调它们在驱动方面的用途和忽略服务方面的用途。
Windows NT中有主要有两个组件和服务管理相关:
◎ 服务控制管理器(Service Control Manager/SCM)--用于启动服务以及和它通讯
◎ 服务控制程序(Service Control Program/SCP)--用于和SCM进行通讯,告诉它何时启动或者停止服务
仔细观察图5.1后,你对beeper.sys有什么要说的吗?好的,我们看到beeper这个内核模式驱动程序位于”D:\RadASM\Masm\Projects\beeper"目录下,它的名称为"beeper",由用户控制启动,出错信息不被记录。
Path前面的"\??"前缀的含义你下面就会知道!
如果我们要启动SCM数据库中不存在的驱动程序,那么可以在任何时刻在SCP的帮助下动态装入(也许称为DCP/device control program更为贴切,但是微软的术语库中并没有这个词)。
5.3 服务控制程序(SCP)
从名称理解,服务控制程序(service control program/SCP)可以控制服务或者设备驱动程序,这些功能是在SCM的管理下,通过调用适当的函数来完成的,这些函数位 于\%SystemRoot%\System32\advapi.dll (Advanced API)中。
这里是一段关于使用SCP来控制beeper.sys驱动的代码例子
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; Service Control Program for beeper driver
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
.386
.model flat, stdcall
option casemap:none
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; I N C L U D E F I L E S
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
include windows.inc
include kernel32.inc
include user32.inc
include advapi32.inc
includelib kernel32.lib
includelib user32.lib
includelib advapi32.lib
include \RadASM\masm32\Macros\Strings.mac
includelib debug.lib
include debug.inc
; ----------------------debug-------------------------------
; PrintError
; PrintText<"debug message!">
; PrintString<driver>
; PrintStringByAddr<offset driver>
; PrintDword<hSCManager,driver>
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; C O D E
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
.code
start proc
local hSCManager:HANDLE
local hService:HANDLE
local acDriverPath[MAX_PATH]:CHAR
LOCAL bRet:BOOL
LOCAL SvrSta
invoke OpenSCManager, NULL, NULL, SC_MANAGER_CREATE_SERVICE
mov hSCManager, eax
PrintDec hSCManager
.if hSCManager != NULL
invoke GetFullPathName, $CTA0("beeper.sys"),sizeof acDriverPath,addr acDriverPath,NULL
PrintString acDriverPath
invoke CreateService, hSCManager, $CTA0("beeper"), $CTA0("Beeper"), \
SERVICE_START + DELETE, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, \
SERVICE_ERROR_IGNORE, addr acDriverPath, NULL, NULL, NULL, NULL, NULL
mov hService, eax
PrintDec hService
.if hService==NULL
PrintError
invoke GetLastError
; 服务创建失败,是由于服务已经创立过
.if eax==ERROR_IO_PENDING || eax==ERROR_SERVICE_EXISTS || eax==ERROR_SERVICE_MARKED_FOR_DELETE
invoke OpenService ,hSCManager,$CTA0("beeper"), SERVICE_ALL_ACCESS
mov hService, eax
push eax
;如果打开服务也失败,则意味错误
.if eax==NULL
pop eax
PrintError
jmp exit
.endif
pop eax
;服务创建失败,是由于服务已经标记删除
.if eax==ERROR_SERVICE_MARKED_FOR_DELETE
invoke ControlService,hService,SERVICE_CONTROL_STOP, addr SvrSta
invoke CloseServiceHandle,hService
;再次创建
invoke CreateService, hSCManager, $CTA0("beeper"), $CTA0("beeper"), \
SERVICE_START + DELETE, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, \
SERVICE_ERROR_IGNORE, addr acDriverPath, NULL, NULL, NULL, NULL, NULL
;如果再次创建再失败,则意味着错误
.if eax==NULL
PrintError
mov bRet,FALSE
jmp exit
.endif
.endif
;由于其他原因创建服务失败
.else
PrintText "注册驱动时出错,出错信息如下:"
PrintError
mov bRet,FALSE
jmp exit
.endif
.endif
invoke StartService, hService, 0, NULL
invoke DeleteService, hService
.else
invoke MessageBox, NULL, $CTA0("打开服务管理器出错."), \
NULL, MB_ICONSTOP
PrintText "打开服务管理器出错"
PrintError
.endif
exit:
.if hService
invoke CloseServiceHandle ,hService ; 服务句柄
.endif
.if hSCManager
invoke CloseServiceHandle ,hSCManager; SCM句柄
.endif
invoke ExitProcess, 0
start endp
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
end start