我的驱动学习笔记(一)

驱动的建立:

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

3. MAKEFILE文件

和SOURCES文件一样,MAKEFILE文件的名称也必须使用大写字母,同时也不能带任何扩展名,它的内容一般为:

!INCLUDE $(NTMAKEENV)/makefile.def
4. 构建过程
启动“Win XP Checked Build Environment ” ,进入工作目录,使用“build”命令构建。
 
5. 安装与启动驱动
使用I nstDrv驱动加载工具进行安装与启动。
 
深入:
 
   驱动程序的安装如同安装服务一样,唯一不同的是,创建服务时,类型是内核驱动,其他跟操作服务没什么区别。
  安装驱动程序流程:
  1,调用OpenSCManager()打开服务控制管理器
  2,调用CreateService()创建一个服务,服务类型为内核驱动
  3,调用OpenService()取得服务句柄
  启动服务
  4,调用StartService()启动服务
  停止服务
  4,调用ControlService()停止服务
  删除服务
  4,调用DeleteService()删除服务
  5,调用CloseServiceHandle()关闭服务句柄
  操作驱动程序流程:
  1,调用CreateFile()取得设备句柄
  2,调用DeviceIoControl()传递I/O控制代码
  3,调用CloseHandle()关闭设备句柄
 
InstDrv工具即实现了这个过程。
 

 

直接操作注册表加载驱动:

 

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"
第一项是要加的,后面那项是调用驱动后自动写进注册表的

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值