设备驱动程序的动态加载主要是由服务控制管理程序(Service Control Manager,SCM)系统组件完成的,让系统加载驱动程序,主要是操作SCM组件.
步骤如下:
首先打开SCM管理器,得到SCM管理器句柄,openSCManager
其次打开了SCM管理器以后,就可以创建一个服务,CreateService
然后打开创建的服务,OpenServicer
最后打开创建的服务后,启动服务,StartService
简单的4个步骤,就可以把驱动加载到系统中.我们来解释下加载的理解,其中最重要的是这个函数CreateService.来看看这个函数的调用,我帖代码
除开0参数和一些常量权限参数外,还有4个需要自己填写的参数,1.局_SCM管理器句柄(用openSCManager打开返回的句柄),2和3.都是pszDriverName(这里是一个服务的名称,一般把驱动文件名作为服务的名称),4. pszDriverPath(驱动文件的全路径).看到这4个参数,我们就应该想到了,这个函数就是为驱动文件创建一个服务.然后打开创建的服务,启动服务,驱动就自动加载到系统中去了(如果把SYS驱动想象成一个DLL的话,SCM管理器就相当于一个LoadDLLexe,我们要做的工作就是先为SYS驱动创建一个服务,然后让服务控制管理器SCM来启动服务,这样就把驱动装载到系统中了)
既然知道了用服务控制管理程序SCM是以启动服务来让系统装载驱动,那么停止驱动和卸载驱动就很好理解了,只要停止服务,和删除服务,那么自然就可以停止驱动和卸载驱动了.
下面,我直接贴代码
我把加载驱动,和卸载驱动封装成4个子程序,分别是注册驱动,运行驱动,停止驱动,和卸载驱动.
注册驱动就是为驱动文件创建一个服务,而运行驱动就是把这个为驱动文件创建的服务进行启动,启动服务后,SCM服务管理器就会为系统加载这个服务的驱动文件.经历注册驱动和运行驱动后,驱动文件就会被加载进系统(驱动加载后会自动执行DriverEntry这个入口函数,好比DLL被加载后DLL会自动执行DLLMAIN一样,把SYS想象成系统的一个DLL,一切都很简单了)
上面的加载驱动和卸载驱动,我们来说下和驱动怎么通讯,这里讲一个最简单的,用DeviceloControl与驱动交流,正常的nt驱动,会在入口函数也就是DriverEntry函数里创建一个设备对象,这个设置对象有个内核名和一个应用层名(应用层名也叫符号链接),我们用CreateFile函数打开这个设备,然后就可以用DeviceloControl给这个设备对象发送自定义的IO控制码,这个IO控制码就可以被驱动接收到,在驱动的派遣函数中进行处理(这个控制码简单说就象是消息,而驱动派遣函数函数就象处理消息的回调函数) 下面是贴代码
总结下,驱动的加载和卸载就是利用服务控制管理程序(SCM)系统组件,为驱动文件创建一个服务,然后启动这个服务,让服务控制管理器把驱动装载到系统中
加载后就没SCM什么事了
和驱动的通讯主要是通过设备对象的操作.由于驱动自己在入口函数处虚拟了一个设备,并创造了一个设备名称(供给应用层程序识别的设备名叫符号链接),打开这个设备,然后用DeviceloControl发送Io控制码.所以与驱动进行交互,一定要知道驱动设备所创造的符号链接.
也就是我们可以加载驱动的时候指定任意服务名加载驱动,而与驱动进行交互的时候,一定要知道驱动所创造的符号链接(也就是驱动在入口函数所创造的设备对象的名字)*笔者就亲测过,在驱动入口函数创造的设备对象是MyDriver的名字,而加载驱动的时候就用自己随便填的服务名"2"就加载成功了,而与驱动交互是用CreateFile打开名字为MyDriver的设备对象,再调用DeviceloControl发送Io控制码进行交互的*
源码下载 http://files.cnblogs.com/qq32175822/SYSControl.rar
参考资料
<<windows驱动开发技术详解>> 张帆 史采成
看雪论坛http://bbs.pediy.com ID:非安全 地址:http://bbs.pediy.com/showthread.php?t=176945&highlight=%E9%9D%9E%E5%AE%89+%E5%AE%89%E5%85%A8+%E5%85%A8