驱动的建立:
1. 可以在VC++下建立一个C源文件(*.c 文件),其中包括驱动入口函数DriverEntry(),当驱动程序第一次加载的时候I/O管理器调用这个例程, 实例:
#include "ntddk.h"
NTSTATUS DriverEntry ( IN PDRIVER_OBJECT theDriverObject,
IN PUNICODE_STRING theRegistryPath )
{
DbgPrint("I am a driver!");
return STATUS_SUCCESS;
}
它只是在内核运行时,利用调试语句给出一则消息:“I am a driver!”。 利用调试工具DbgViewer可观察。
DriverEntry例程
当驱动程序第一次加载的时候I/O管理器调用这个例程,可能在系统引导的时候,也可能在任何时候被动态加载。DriverEntry例程执行第一次的初始化任务,如宣布其它例程的地址,定位它所控制的硬件,分配或者确认硬件资源的用法(端口,中断,DMA),为发现的每个硬件设备提供一个名字,方便给操作系统使用。对于分享即插即用的WDM驱动程序,这个硬件分配的步骤被延迟到AddDevice例程之后。
注意:
上面驱动程序没有设置卸载例程。若不设置卸载例程,除非重新启动机器,否则无法将载入内存的驱动程序卸载掉,不方便进行调试。
启动驱动程序时,系统会将参数theDriverObject传递给该驱动程序的主函数,这个参数指向的数据结构含有许多函数指针,其中一个指针称为“unload routine”。如果我们设置该指针,就能从内存中卸载驱动程序;如果不设置该指针的话,除非重新启动机器,否则无法将载入内存的驱动程序卸载掉。同时,驱动程序在开发过程中,会不断添加或改变功能,所以要经常装载以及卸载它们。为了避免每次测试新版本的驱动程序时都必须重启系统,我们应当设置“unload routine”指针。事实上,设置该指针并不是什么难事:先建立一个卸载例程,就可以设置该卸载指针了。
即在DriverEntry()中添加语句:theDriverObject->DriverUnload = MyUnload; //MyUnload 为卸载驱动函数名
修改后代码为:
#include "ntddk.h"
// 这里是我们的卸载函数
VOID MyUnload( IN PDRIVER_OBJECT DriverObject )
{
DbgPrint("MyUnload called/n");
}
NTSTATUS DriverEntry(IN PDRIVER_OBJECT theDriverObject,
IN PUNICODE_STRING theRegistryPath)
{
DbgPrint("I am a driver and I loaded!");
// 初始化DriverObject对象中指向卸载函数的指针
theDriverObject->DriverUnload = MyUnload;
return STATUS_SUCCESS;
}
2. 2. SOURCES文件
要想构建设备驱动程序,仅有驱动程序源文件还是不够的,我们还需另外两个文件:SOURCES和MAKEFILE文件。
我们先来介绍SOURCES文件,此文件的名称必须使用大写字母,并且不带任何扩展名,它的内容应当包含:
TARGETNAME=MYDRIVER TARGETPATH=OBJ TARGETTYPE=DRIVER SOURCES=mydriver.c |
和SOURCES文件一样,MAKEFILE文件的名称也必须使用大写字母,同时也不能带任何扩展名,它的内容一般为:
!INCLUDE $(NTMAKEENV)/makefile.def |
安装驱动程序流程:
1,调用OpenSCManager()打开服务控制管理器
2,调用CreateService()创建一个服务,服务类型为内核驱动
3,调用OpenService()取得服务句柄
启动服务
4,调用StartService()启动服务
停止服务
4,调用ControlService()停止服务
删除服务
4,调用DeleteService()删除服务
5,调用CloseServiceHandle()关闭服务句柄
操作驱动程序流程:
1,调用CreateFile()取得设备句柄
2,调用DeviceIoControl()传递I/O控制代码
3,调用CloseHandle()关闭设备句柄
直接操作注册表加载驱动:
a.需要在注册表中写个服务来加载这个驱动,
HKEY_LOCAL_MACHINE/System/CurrentControlSet/Services
在上面的目录下新建一项 名字叫hello
在hello中添加如下键值:
ImagePath=systam32/drivers/hello.sys (类型是REG_EXPAND_SZ)
DisplayName=驱动名称(随便写) (类型是REG _SZ)
ErrorControl=1 (类型是REG_DWORD)
Start=3 (类型是REG_DWORD)
Type=1 (类型是REG_DWORD)
服务写好了以后,重启电脑!
b.现在开始启动服务了。
这是就需要一个工具来观察驱动运行的结果,工具叫:Dbgview.exe
首先打开Dbgview.exe,然后运行cmd进入命令行,运行 net start hello,这时在Dbgview.exe中可以看到helloWorld。
PS:感谢作者的文章,从CSDN COPY来的,不错
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/hello]
"ImagePath"=hex(2):73,00,79,00,73,00,74,00,65,00,6d,00,33,00,32,00,5c,00,64,00,/
72,00,69,00,76,00,65,00,72,00,73,00,5c,00,68,00,65,00,6c,00,6c,00,6f,00,2e,/
00,73,00,79,00,73,00,00,00
"DisplayName"="hello"
"ErrorControl"=dword:00000001
"Start"=dword:00000003
"Type"=dword:00000001
[HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/hello/Enum]
"Count"=dword:00000001
"NextInstance"=dword:00000001
"INITSTARTFAILED"=dword:00000001
"0"="Root//LEGACY_HELLO//0000"
第一项是要加的,后面那项是调用驱动后自动写进注册表的