驱动对象、设备对象、设备栈----驱动程序基础概念(一)


  刚开始接触驱动的时候,总是搞不清楚驱动对象、设备对象、设备栈等等基本概念,所以对驱动的开发也总是会出现一些奇怪的错误。但想要一下子说明白这些基本结构,也不是一件容易的事,最好的办法就是接触多了,了解多了,慢慢会清楚的。这里做一个总结,也希望能对初学者有所帮助。

      一、 为了后面的叙述方便,首先列出驱动对象和设备对象的结构。

      1.1 驱动对象结构 DRIVER_OBJECT ,结构图如下:

     

       1.2 DDK 中有对于一些域的说明

       [00] IRP_MJ_CREATE
       [01] IRP_MJ_CREATE_NAMED_PIPE
       [02] IRP_MJ_CLOSE
       [03] IRP_MJ_READ
       [04] IRP_MJ_WRITE
       [05] IRP_MJ_QUERY_INFORMATION
       [06] IRP_MJ_SET_INFORMATION
       [07] IRP_MJ_QUERY_EA
       [08] IRP_MJ_SET_EA
       [09] IRP_MJ_FLUSH_BUFFERS
       [0a] IRP_MJ_QUERY_VOLUME_INFORMATION
       [0b] IRP_MJ_SET_VOLUME_INFORMATION
       [0c] IRP_MJ_DIRECTORY_CONTROL
       [0d] IRP_MJ_FILE_SYSTEM_CONTROL
       [0e] IRP_MJ_DEVICE_CONTROL
       [0f] IRP_MJ_INTERNAL_DEVICE_CONTROL
       [10] IRP_MJ_SHUTDOWN
       [11] IRP_MJ_LOCK_CONTROL
       [12] IRP_MJ_CLEANUP
       [13] IRP_MJ_CREATE_MAILSLOT
       [14] IRP_MJ_QUERY_SECURITY
       [15] IRP_MJ_SET_SECURITY
       [16] IRP_MJ_POWER
       [17] IRP_MJ_SYSTEM_CONTROL
       [18] IRP_MJ_DEVICE_CHANGE
       [19] IRP_MJ_QUERY_QUOTA
       [1a] IRP_MJ_SET_QUOTA
       [1b] IRP_MJ_PNP

       1.3 驱动对象扩展 _DRIVER_EXTENSION (sizeof=24),结构图如下:

      

         2. 设备对象结构 DEVICE_OBJECT ,定义如下
         struct _DEVICE_OBJECT (sizeof=184)
         +00 int16 Type
         +02 uint16 Size
         +04 int32 ReferenceCount
         +08 struct _DRIVER_OBJECT *DriverObject
         +0c struct _DEVICE_OBJECT *NextDevice
         +10 struct _DEVICE_OBJECT *AttachedDevice
         +14 struct _IRP *CurrentIrp
         +18 struct _IO_TIMER *Timer
         +1c uint32 Flags
         +20 uint32 Characteristics
         +24 struct _VPB *Vpb
         +28 void *DeviceExtension
         +2c uint32 DeviceType
         +30 char StackSize
         +34 union __unnamed62 Queue
         +34 struct _LIST_ENTRY ListEntry
         +34 struct _LIST_ENTRY *Flink
         +38 struct _LIST_ENTRY *Blink
         +34 struct _WAIT_CONTEXT_BLOCK Wcb
         +34 struct _KDEVICE_QUEUE_ENTRY WaitQueueEntry
         +34 struct _LIST_ENTRY DeviceListEntry
         +34 struct _LIST_ENTRY *Flink
         +38 struct _LIST_ENTRY *Blink
         +3c uint32 SortKey
         +40 byte Inserted
         +44 function *DeviceRoutine
         +48 void *DeviceContext
         +4c uint32 NumberOfMapRegisters
         +50 void *DeviceObject
         +54 void *CurrentIrp
         +58 struct _KDPC *BufferChainingDpc
         +5c uint32 AlignmentRequirement
         +60 struct _KDEVICE_QUEUE DeviceQueue
         +60 int16 Type
         +62 int16 Size
         +64 struct _LIST_ENTRY DeviceListHead
         +64 struct _LIST_ENTRY *Flink
         +68 struct _LIST_ENTRY *Blink
         +6c uint32 Lock
         +70 byte Busy
         +74 struct _KDPC Dpc
         +74 int16 Type
         +76 byte Number
         +77 byte Importance
         +78 struct _LIST_ENTRY DpcListEntry
         +78 struct _LIST_ENTRY *Flink
         +7c struct _LIST_ENTRY *Blink
         +80 function *DeferredRoutine
         +84 void *DeferredContext
         +88 void *SystemArgument1
         +8c void *SystemArgument2
         +90 uint32 *Lock
         +94 uint32 ActiveThreadCount
         +98 void *SecurityDescriptor
         +9c struct _KEVENT DeviceLock
         +9c struct _DISPATCHER_HEADER Header
         +9c byte Type
         +9d byte Absolute
         +9e byte Size
         +9f byte Inserted
         +a0 int32 SignalState
         +a4 struct _LIST_ENTRY WaitListHead
         +a4 struct _LIST_ENTRY *Flink
         +a8 struct _LIST_ENTRY *Blink
         +ac uint16 SectorSize
         +ae uint16 Spare1
         +b0 struct _DEVOBJ_EXTENSION *DeviceObjectExtension
         +b4 void *Reserved

         2.1 设备对象扩展_DEVOBJ_EXTENSION

         struct _DEVOBJ_EXTENSION (sizeof=36)
         +00 int16 Type
         +02 uint16 Size
         +04 struct _DEVICE_OBJECT *DeviceObject
         +08 uint32 PowerFlags
         +0c *Dope
         +10 uint32 ExtensionFlags
         +14 void *DeviceNode
         +18 struct _DEVICE_OBJECT *AttachedTo
         +1c struct _LIST_ENTRY FileObjectList
         +1c struct _LIST_ENTRY *Flink
         +20 struct _LIST_ENTRY *Blink

        二、简要说明

        1. 向内存中载入一个驱动程序文件,就会有一个驱动对象(DRIVER_OBJECT)产生

        2. 以驱动 i8042prt 为例简要说明过程(在这里我先做个说明,对于同时插有 ps/2 键盘和 ps/2 鼠标的计算机上, i8042prt 会创建两个设备对象,一个用于键盘,一个用于鼠标。i8042prt 是完成 ps/2 键盘驱动主要功能的驱动程序。)

        2.1 驱动 i8042prt 是在系统初始化阶段,IO 管理器调用函数 nt!IopLoadDriver 读取注册表,获得驱动程序文件 i8042prt.SYS 的路径,将这个文件载入内存。

        2.2 之后会调用 nt!ObCreateObject 创建一个驱动对象,并初始化这个驱动对象。

        3.  设备对象的创建

        设备对象(DEVICE_OBJECT)由驱动创建。一个驱动可以创建多个设备对象(DEVICE_OBJECT)。通过驱动对象(DRIVER_OBJECT),可以找到由该驱动创建的所有设备对象(DEVICE_OBJECT)。一个驱动创建的所有设备对象(DEVICE_OBJECT)链成一条链,该驱动的驱动对象(DRIVER_OBJECT)可以找到这个链。一个设备对象(DEVICE_OBJECT)也可以找到创建它的驱动的驱动对象(DRIVER_OBJECT)。

       三、实际观察驱动 i8042prt

       工具: WinDbg

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值