windows驱动程序开发(普及)

1.用户态驱动驱动程序和核心态驱动程序   

下图描绘出了操作系统驱动程序的相关组成部分的概貌:


Windows驱动程序既可以运行在用户态也可以运行在核心模态。

l         用户态的驱动程序运行在非特权处理机模式(nonprivileged processor mode)上,其他一些被保护的子系统代码也运行在该模式上。用户态的驱动程序不能获得系统数据的存取权,除非调用Win32 API或者系统服务。

l         核心态驱动程序作为操作系统的一个组成部分被执行——支持一个或多个受保护的子系统的操作系统底层组件。

用户态和核心态驱动程序有不同的结构,不同的入口点和不同的系统接口。一个设备是需要一个用户态驱动程序还是需要一个核心态驱动程序依赖于该设备的类型和操作系统对它提供的支持。

一些设备驱动程序可以完全地或部分地运行在用户态。用户态驱动程序没有堆栈空间的限制,可以访问Win32 API,并且容易调试。

大多设备驱动程序运行在核心态。核心态驱动程序可以完成某些受保护的操作,并且可以访问用户态驱动程序不能访问的系统结构体(system sturcture)。然而,访问权限的提高当然也要付出相应的代价——调试的艰难,系统随时面临毁坏的危险。当代码运行在有特权的核心态环境中时,操作系统对代码所请求的数据的完整性和有效性的检查将大大减少。

为了方便,应该用高级语言(high-level language)来编写驱动程序,通常,C适合用来编写核心态驱动程序,CC++则适合用于编写用户态驱动程序。

驱动开发一般分为六步,在下面列出,每一步在DDK中都有相关部分进行阐述。

  • 第一步:理解驱动程序和操作系统基础
  • 第二步:确定特定设备驱动程序的需求
  • 第三步:做一个驱动程序设计方案
  • 第四步:构建、测试和调试驱动程序
  • 第五步:提供一个驱动程序包
  • 第六步:发布驱动程序

2.设备对象和设备栈

2.1介绍设备对象

操作系统用设备对象(device object)表示设备。每一个设备都有一个或多个设备对象与之相关联。设备对象提供了在设备上的所有操作。

核心态驱动程序中,每个设备必须至少创建一个设备对象,下面两种情况除外:

l         与类(class)或端口设备相关的微驱动程序不必创建它自己的设备对象。

l         特定类型子系统的设备驱动程序的设备对象由子系统创建。例如:NDIS小端口驱动。

一些设备对象并不表示物理设备。一个唯软件驱动程序(software-only driver,处理I/O请求,但是不把这些请求传递给硬件)也必须创建表示它的操作的设备对象。

设备常常由多个设备对象所表示,每一个设备对象在驱动程序栈(driver stack)中对应一个驱动程序来管理设备的I/O请求。一个设备的所有设备对象被组织成一个设备栈(device stack)。无论何时,一个操作都在一个设备上被完成,系统把IRPI/O request packet)数据结构体传递给设备栈中顶部设备的驱动程序。每一个驱动或者处理IRP,或者把它传递给设备栈中下一个设备对象的驱动程序。

设备对象由DEVICE_OBJECT结构体表示,它被对象管理器(Object Manager)所管理。对象管理器提供为设备对象提供与其他系统对象相同的功能。特别地,一个设备对象可以被命名,并且一个被命名的设备对象可以有一个句柄。


    系统为每一个设备对象提供专门的存储空间,被成作设备扩展(device extension),它可以用作特定设备的存储空间。设备扩展同设备对象一起被创建和释放。

下图描述了设备对象和I/O管理器之间的关系:

2.2Windows驱动模型(WDM)设备对象和设备栈

 

2.2.1. WDM设备对象的类型

有三种类型的WDM设备对象:

1)        物理设备对象(PDO)——表示一个总线驱动程序的总线设备。

2)        函数设备对象(FDO)——表示一个函数驱动程序的设备。

3)        过滤器设备对象(filter DO)——表示一个过滤器驱动程序的设备。

这三种设备对象都是DEVICE_OBJECT类型,但是用法不同并且有不同的设备扩展。

 

2.2.2. WDM设备对象的例子

 

2.2.3. WDM设备对象何时被创建

 

2.2.4. WDM设备栈的例子

 

2.3创建一个设备对象

    驱动程序调用IoCreateDeviceIoCreateDeviceSecure来创建它们的设备对象。当驱动程序创建一个设备对象时,要提供下列信息给IoCreateDeviceIoCreateDeviceSecure

l         设备的设备扩展(device extension)的大小。设备扩展是一块系统分配的存储区域,驱动程序可以使用这块区域作为特定设备的存储空间。

l         一个系统定义的常量,指明设备对象表示的设备类型(DeviceType)。

l         一个或多个ORed,系统定义的常量,它指明了设备的特征。

l         一个被叫做Exclusive的布尔值(Boolean value),它指明了设备对象的Flags中的一位是否应该被设置成DO_EXCLUSIVE——表明驱动服务于一个独立的设备,例如视频,串行,并行或声音设备。WDM驱动必须设置ExclusiveFALSE

l         一个指向驱动程序的驱动对象(driver object)的指针。一个WDM函数或过滤器驱动程序接收指向它的驱动对象的指针作为它的AddDevice函数的参数。所有的驱动程序在它们的DriverEntry函数中接收到一个只想驱动对象的指针。系统使用这个指针与相应的设备对象关联起来。

l         一个指向以0中止符结尾的Unicode字符串(DeviceName)的指针,该指针是可选的。除了总线驱动程序,WDM驱动程序不提供设备名称。

    如果调用IoCreateDeviceIoCreateDeviceSecure成功,I/O管理器将为设备对象本身和其它所有与设备对象相关的数据结构提供存储空间,包括设备扩展,它初始化的时候为0

 

2.3.1为WDM函数和过滤器驱动程序创建设备对象

    除了总线驱动程序以外的WDM驱动程序都调用IoCreateDevice来创建它们的设备对象。大多数的WDM驱动程序在它们的AddDevice函数里来创建设备对象。有些驱动程序,例如磁盘驱动程序,从分派函数(dispatch routine)调用IoCreateDevice

 

    除非是DDK说明文档里特别指定的设备类型,否则,你的驱动程序应该在它的AddDevice函数中创建设备对象。

 

2.3.2为WDM总线驱动程序创建设备对象

    当一个WDM总线驱动程序为响应IRP_MN_QUERY_DEVICE_RELATIONS而列出新设备时,如果类型是BusRelations,它将创建一个物理设备对象(PDO)。

下列规则决定了一个总线驱动程序是调用IoCreateDevice还是调用IoCreateDeviceSecure来创建一个设备对象:

l         如果设备可以在原始模式(raw mode)下使用,那么必须调用IoCreateDeviceSecure

l         如果设备不能在原是模式下使用,那么总线驱动程序既可以调用IoCreateDevice,也可以调用IoCreateDeviceSecure。当对于总线上的设备的默认系统安全性足够的时候可以调用IoCreateDevice;调用IoCreateDeviceSecure可以指定更严格的安全描述符。

2.3.3为非WDM驱动程序创建设备对象

    非WDM驱动程序通常使用IoCreateDevice来创建无名的设备对象,使用IoCreateDeviceSecure来创建有名的设备对象。

 

 

2.4初始化一个设备对象

          IoCreateDevice将返回一个指向设备对象(DeviceObject)的指针给调用者,这个设备对象包含一个指向设备扩展(device extension)的指针,驱动程序必须为它们的物理的、逻辑的、或虚拟的设备创建各自的区域。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值