现在的位置: 首页 > 综合 > 正文

DRIVER_OBJECT & DEVICE_OBJECT

2013年01月20日 ⁄ 综合 ⁄ 共 15389字 ⁄ 字号 评论关闭

驱动对象结构 DRIVER_OBJECT ,定义如下:(左侧为相对于结构体起始地址的偏移量)
  struct _DRIVER_OBJECT (sizeof=168)
  +00 int16 Type
  +02 int16 Size
  +04 struct _DEVICE_OBJECT *DeviceObject
  +08 uint32 Flags
  +0c void *DriverStart
  +10 uint32 DriverSize
  +14 void *DriverSection(即为PsLoadedModuleList的地址,利用它可以枚举系统中所有驱动模块)
  +18 struct _DRIVER_EXTENSION *DriverExtension
  +1c struct _UNICODE_STRING DriverName
  +1c uint16 Length
  +1e uint16 MaximumLength
  +20 uint16 *Buffer
  +24 struct _UNICODE_STRING *HardwareDatabase
  +28 struct _FAST_IO_DISPATCH *FastIoDispatch
  +2c function *DriverInit
  +30 function *DriverStartIo
  +34 function *DriverUnload
  +38 function *MajorFunction[28]
  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
  struct _DRIVER_EXTENSION (sizeof=24)
  +00 struct _DRIVER_OBJECT *DriverObject
  +04 function *AddDevice
  +08 uint32 Count
  +0c struct _UNICODE_STRING ServiceKeyName
  +0c uint16 Length
  +0e uint16 MaximumLength
  +10 uint16 *Buffer
  +14 struct _IO_CLIENT_EXTENSION *ClientDriverExtension
  设备对象结构 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

-----------------------------------------------------------------------------------------------------------------

//Defined in ntddk.h

// STRUCT PDEVICE_OBJECT

typedef struct DECLSPEC_ALIGN(MEMORY_ALLOCATION_ALIGNMENT) _DEVICE_OBJECT {
CSHORT Type;
USHORT Size;
LONG ReferenceCount;
struct _DRIVER_OBJECT *DriverObject;
struct _DEVICE_OBJECT *NextDevice;
struct _DEVICE_OBJECT *AttachedDevice;
struct _IRP *CurrentIrp;
PIO_TIMER Timer;
ULONG Flags; // See above: DO_...
ULONG Characteristics; // See ntioapi: FILE_...
PVPB Vpb;
PVOID DeviceExtension;
DEVICE_TYPE DeviceType;
CCHAR StackSize;
union {
LIST_ENTRY ListEntry;
WAIT_CONTEXT_BLOCK Wcb;
} Queue;
ULONG AlignmentRequirement;
KDEVICE_QUEUE DeviceQueue;
KDPC Dpc;

//
// The following field is for exclusive use by the filesystem to keep
// track of the number of Fsp threads currently using the device
//

ULONG ActiveThreadCount;
PSECURITY_DESCRIPTOR SecurityDescriptor;
KEVENT DeviceLock;

USHORT SectorSize;
USHORT Spare1;

struct _DEVOBJ_EXTENSION *DeviceObjectExtension;
PVOID Reserved;
} DEVICE_OBJECT;

typedef struct _DEVICE_OBJECT *PDEVICE_OBJECT; // ntndis

//Defined in ntddk.h

// STRUCT PDRIVER_OBJECT

typedef struct _DRIVER_OBJECT {
CSHORT Type;
CSHORT Size;

//
// The following links all of the devices created by a single driver
// together on a list, and the Flags word provides an extensible flag
// location for driver objects.
//

PDEVICE_OBJECT DeviceObject;
ULONG Flags;

//
// The following section describes where the driver is loaded. The count
// field is used to count the number of times the driver has had its
// registered reinitialization routine invoked.
//

PVOID DriverStart;
ULONG DriverSize;
PVOID DriverSection;
PDRIVER_EXTENSION DriverExtension;

//
// The driver name field is used by the error log thread
// determine the name of the driver that an I/O request is/was bound.
//

UNICODE_STRING DriverName;

//
// The following section is for registry support. Thise is a pointer
// to the path to the hardware information in the registry
//

PUNICODE_STRING HardwareDatabase;

//
// The following section contains the optional pointer to an array of
// alternate entry points to a driver for "fast I/O" support. Fast I/O
// is performed by invoking the driver routine directly with separate
// parameters, rather than using the standard IRP call mechanism. Note
// that these functions may only be used for synchronous I/O, and when
// the file is cached.
//

PFAST_IO_DISPATCH FastIoDispatch;

//
// The following section describes the entry points to this particular
// driver. Note that the major function dispatch table must be the last
// field in the object so that it remains extensible.
//

PDRIVER_INITIALIZE DriverInit;
PDRIVER_STARTIO DriverStartIo;
PDRIVER_UNLOAD DriverUnload;
PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION + 1];

} DRIVER_OBJECT;
typedef struct _DRIVER_OBJECT *PDRIVER_OBJECT; // ntndis

  DDK 中有对于一些域的说明
  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
  有一个载入内存的驱动程序文件,就会有一个驱动对象(DRIVER_OBJECT)。
  比如,驱动 i8042prt 是在系统初始化阶段,IO 管理器调用函数 nt!IopLoadDriver 载入的。nt!IopLoadDriver 读取注册表,获得驱动程序文件 i8042prt.SYS 的路径,将这个文件载入内存。之后会调用 nt!ObCreateObject 创建一个驱动对象,并初始化这个驱动对象。
  设备对象(DEVICE_OBJECT)由驱动创建。一个驱动可以创建多个设备对象(DEVICE_OBJECT)。通过驱动对象(DRIVER_OBJECT),可以找到由该驱动创建的所有设备对象(DEVICE_OBJECT)。一个驱动创建的所有设备对象(DEVICE_OBJECT)链成一条链,该驱动的驱动对象(DRIVER_OBJECT)可以找到这个链。一个设备对象(DEVICE_OBJECT)也可以找到创建它的驱动的驱动对象(DRIVER_OBJECT)。下面我们使用 WinDbg
实际观察驱动 i8042prt 的情况,i8042prt 是完成 ps/2 键盘驱动主要功能的驱动程序。
  在这里我们先做个说明,对于同时插有 ps/2 键盘和 ps/2 鼠标的计算机上, i8042prt 会创建两个设备对象,一个用于键盘,一个用于鼠标。
  首先我们从命名对象地址空间,找到 i8042prt 的 DRIVER_OBJECT 的地址
  kd> !object \driver\i8042prt
  Object: fe4f69f0 Type: (fe4ec3e0) Driver
  ObjectHeader: fe4f69d8
  HandleCount: 0 PointerCount: 5
  Directory Object: fe51bf30 Name: i8042prt
  下面我们看 i8042prt 的 DRIVER_OBJECT 中的内容
  kd> !strct driver_object fe4f69f0
  struct _DRIVER_OBJECT (sizeof=168)
  +00 int16 Type = 0004
  +02 int16 Size = 00a8
  +04 struct _DEVICE_OBJECT *DeviceObject = FE4D3BA0
  // 注意 DeviceObject 链上的第一个设备对象
  +08 uint32 Flags = 00000012
  +0c void *DriverStart = FE1BD000
  +10 uint32 DriverSize = 00021000
  +14 void *DriverSection = FE4F6CC8
  +18 struct _DRIVER_EXTENSION *DriverExtension = FE4F6A98
  +1c struct _UNICODE_STRING DriverName
  +1c uint16 Length = 0020
  +1e uint16 MaximumLength = 0020
  +20 uint16 *Buffer = E127FE88
  +24 struct _UNICODE_STRING *HardwareDatabase = 80541FC0
  +28 struct _FAST_IO_DISPATCH *FastIoDispatch = 00000000
  +2c function *DriverInit = FE1D8000
  +30 function *DriverStartIo = FE1BF444
  +34 function *DriverUnload = FE1CB920
  +38 function *MajorFunction[28] = FE1CB000
  80425354
  FE1CB14E
  80425354
  80425354
  80425354
  80425354
  80425354
  80425354
  FE1BE558
  80425354
  80425354
  80425354
  80425354
  FE1CB243
  FE1BE667
  80425354
  80425354
  80425354
  80425354
  80425354
  80425354
  FE1D2C63
  FE1D3633
  80425354
  80425354
  80425354
  FE1D1BFB
  我们看到了 DeviceObject 上的第一个设备对象的地址 FE4D3BA0 ,我们使用 WinDbg 的 !devobj 命令,来获得一些信息
  kd> !devobj FE4D3BA0
  Device object (fe4d3ba0) is for:
  \Driver\i8042prt DriverObject fe4f69f0
  Current Irp 00000000 RefCount 0 Type 00000027 Flags 00002004
  DevExt fe4d3c58 DevObjExt fe4d3ed8
  ExtensionFlags (0xc0000000)
  Unknown flags 0xc0000000
  AttachedDevice (Upper) fe4d3a60 \Driver\vmmouse
  AttachedTo (Lower) fe4dd610 \Driver\ACPI
  Device queue is not busy.
  从获得的信息来看,这是用于鼠标的那个设备对象,下面我们看这个设备对象 DEVICE_OBJECT 中的具体内容
  kd> !strct device_object FE4D3BA0
  struct _DEVICE_OBJECT (sizeof=184)
  +00 int16 Type = 0003
  +02 uint16 Size = 0338
  +04 int32 ReferenceCount = 00000000
  +08 struct _DRIVER_OBJECT *DriverObject = FE4F69F0
  // 正是 \Driver\i8042prt 的驱动对象的地址
  +0c struct _DEVICE_OBJECT *NextDevice = FE4F5020
  // DeviceObject 链的下一个
  +10 struct _DEVICE_OBJECT *AttachedDevice = FE4D3A60
  +14 struct _IRP *CurrentIrp = 00000000
  ...
  我们看到了设备对象 +0c struct _DEVICE_OBJECT *NextDevice 处是 DeviceObject 链上的下一个设备对象的地址,值为 FE4F5020 ,我们使用 WinDbg 的 !devobj 命令,来获得一些信息
  kd> !devobj FE4F5020
  Device object (fe4f5020) is for:
  \Driver\i8042prt DriverObject fe4f69f0
  Current Irp 00000000 RefCount 0 Type 00000027 Flags 00002004
  DevExt fe4f50d8 DevObjExt fe4f5358
  ExtensionFlags (0xc0000000)
  Unknown flags 0xc0000000
  AttachedDevice (Upper) fe4f5df0 \Driver\Kbdclass
  AttachedTo (Lower) fe4dd730 \Driver\ACPI
  Device queue is not busy.
  从获得的信息来看,这是用于键盘的那个设备对象,下面我们看这个设备对象 DEVICE_OBJECT 中的具体内容
  kd> !strct device_object FE4F5020
  struct _DEVICE_OBJECT (sizeof=184)
  +00 int16 Type = 0003
  +02 uint16 Size = 0338
  +04 int32 ReferenceCount = 00000000
  +08 struct _DRIVER_OBJECT *DriverObject = FE4F69F0
  // 正是 \Driver\i8042prt 的驱动对象的地址
  +0c struct _DEVICE_OBJECT *NextDevice = 00000000
  // 为空,表明链结束了。
  +10 struct _DEVICE_OBJECT *AttachedDevice = FE4F5DF0
  +14 struct _IRP *CurrentIrp = 00000000
  ...
  我们观察初始化时,看到 i8042prt 调用 IoCreateDevice 创建设备对象,并且 IoCreateDevice 会把新创建的这个设备对象,链入驱动的设备链中。
  现在我们对驱动对象和设备对象之间的联系,做一个总结
  驱动调用 IoCreateDevice 创建设备对象,一个驱动创建的所有设备对象链成一个链,这个链以空表示结束。驱动对象通过 +04 struct _DEVICE_OBJECT *DeviceObject 可以找到这个链。设备对象通过 +0c struct _DEVICE_OBJECT *NextDevice 链在一起。设备对象通过 +08 struct _DRIVER_OBJECT *DriverObject 可以找到创建它的驱动的驱动对象。
  下面我们来讲讲设备栈。一个物理设备的驱动任务,通常由几个驱动程序一层一层的共同完成。每层一个设备对象,他们联系在一起,组成一个设备栈。一个设备栈上的设备对象,从上自下,联系在一起。从下自上,也联系在一起。我们以 ps/2 键盘驱动为例,使用 WinDbg 来观察它的设备栈,以及他们如何联系在一起。
  ps/2 键盘驱动的设备栈,大概就是这个样子
  kd> !devstack fe4f5020
  !DevObj !DrvObj !DevExt ObjectName
  fe4f5df0 \Driver\Kbdclass fe4f5ea8 KeyboardClass0
  > fe4f5020 \Driver\i8042prt fe4f50d8
  fe4dd730 \Driver\ACPI fe507468 0000000e
  !DevNode fe4fed68 :
  DeviceInst is "ACPI\PNP0303\4&5289e18&0"
  ServiceName is "i8042prt"
  最上面的 DEVICE_OBJECT 地址为 fe4f5df0,属于驱动 \Driver\Kbdclass
  中间的 DEVICE_OBJECT 地址为 fe4f5020,属于驱动 \Driver\i8042prt
  最下面的 DEVICE_OBJECT 地址为 fe4dd730,属于驱动 \Driver\ACPI

  下面我们看这3个设备对象,如何联系在一起。

  最上面一层的 DEVICE_OBJECT
  kd> !devobj fe4f5df0
  Device object (fe4f5df0) is for:
  KeyboardClass0 \Driver\Kbdclass DriverObject fe4f6330
  Current Irp fe43a1c8 RefCount 0 Type 0000000b Flags 00002044
  DevExt fe4f5ea8 DevObjExt fe4f5fd8
  ExtensionFlags (0000000000)
  AttachedTo (Lower) fe4f5020 \Driver\i8042prt
  Device queue is busy -- Queue empty.
  看到这个设备对象有名字,叫 KeyboardClass0 ,属于驱动 Kbdclass
  kd> !strct device_object fe4f5df0
  struct _DEVICE_OBJECT (sizeof=184)
  +00 int16 Type = 0003
  +02 uint16 Size = 01e8
  +04 int32 ReferenceCount = 00000000
  +08 struct _DRIVER_OBJECT *DriverObject = FE4F6330// 正是 kbdclass 的 DRIVER_OBJECT 的地址
  +0c struct _DEVICE_OBJECT *NextDevice = 00000000
  +10 struct _DEVICE_OBJECT *AttachedDevice = 00000000// 为空结束,表示上面没有其它设备对象了
  +14 struct _IRP *CurrentIrp = FE43A1C8
  ...
  +ae uint16 Spare1 = 0000
  +b0 struct _DEVOBJ_EXTENSION *DeviceObjectExtension = FE4F5FD8
  // 它的 DEVOBJ_EXTENSION 在 FE4F5FD8
  +b4 void *Reserved = 00000000

  kd> !strct DEVOBJ_EXTENSION FE4F5FD8

       struct _DEVOBJ_EXTENSION (sizeof=36)
  +00 int16 Type = 000d
  +02 uint16 Size = 0000
  +04 struct _DEVICE_OBJECT *DeviceObject = FE4F5DF0
  +08 uint32 PowerFlags = 00000010
  +0c *Dope = 00000000
  +10 uint32 ExtensionFlags = 00000000
  +14 void *DeviceNode = 00000000
  +18 struct _DEVICE_OBJECT *AttachedTo = FE4F5020 // 下面一层的设备对象为 FE4F5020
  +1c struct _LIST_ENTRY FileObjectList
  +1c struct _LIST_ENTRY *Flink = 00000000
  +20 struct _LIST_ENTRY *Blink = 00000000

  中间层的 DEVICE_OBJECT
  kd> !devobj fe4f5020

  Device object (fe4f5020) is for:
  \Driver\i8042prt DriverObject fe4f69f0
  Current Irp 00000000 RefCount 0 Type 00000027 Flags 00002004
  DevExt fe4f50d8 DevObjExt fe4f5358
  ExtensionFlags (0xc0000000)
  Unknown flags 0xc0000000
  AttachedDevice (Upper) fe4f5df0 \Driver\Kbdclass
  AttachedTo (Lower) fe4dd730 \Driver\ACPI
  Device queue is not busy.
  看到这个设备对象没有名字,属于驱动 i8042prt
  kd> !strct device_object fe4f5020
  struct _DEVICE_OBJECT (sizeof=184)
  +00 int16 Type = 0003
  +02 uint16 Size = 0338
  +04 int32 ReferenceCount = 00000000
  +08 struct _DRIVER_OBJECT *DriverObject = FE4F69F0
  // 正是 i8042prt 的 DRIVER_OBJECT 的地址
  +0c struct _DEVICE_OBJECT *NextDevice = 00000000
  +10 struct _DEVICE_OBJECT *AttachedDevice = FE4F5DF0  // 上面一层的设备对象
  +14 struct _IRP *CurrentIrp = 00000000
  ...
  +ae uint16 Spare1 = 0001
  +b0 struct _DEVOBJ_EXTENSION *DeviceObjectExtension = FE4F5358 // 它的 DEVOBJ_EXTENSION 在 FE4F5358
  +b4 void *Reserved = 00000000
  kd> !strct DEVOBJ_EXTENSION FE4F5358
  struct _DEVOBJ_EXTENSION (sizeof=36)
  +00 int16 Type = 000d
  +02 uint16 Size = 0000
  +04 struct _DEVICE_OBJECT *DeviceObject = FE4F5020
  +08 uint32 PowerFlags = 00000000
  +0c *Dope = 00000000
  +10 uint32 ExtensionFlags = c0000000
  +14 void *DeviceNode = 00000000
  +18 struct _DEVICE_OBJECT *AttachedTo = FE4DD730
  // 下面一层的设备对象
  +1c struct _LIST_ENTRY FileObjectList
  +1c struct _LIST_ENTRY *Flink = 00000000
  +20 struct _LIST_ENTRY *Blink = 00000000
  最下面一层的 DEVICE_OBJECT
  kd> !devobj fe4dd730
  Device object (fe4dd730) is for:
  0000000e \Driver\ACPI DriverObject fe4e8ad0
  Current Irp 00000000 RefCount 1 Type 00000032 Flags 00001040
  DevExt fe507468 DevObjExt fe4dd7e8 DevNode fe4fed68
  ExtensionFlags (0000000000)
  AttachedDevice (Upper) fe4f5020 \Driver\i8042prt
  Device queue is not busy.
  看到这个设备对象有名字,叫 0000000e ,属于驱动 acpi
  kd> !strct device_object fe4dd730
  struct _DEVICE_OBJECT (sizeof=184)
  +00 int16 Type = 0003
  +02 uint16 Size = 00b8
  +04 int32 ReferenceCount = 00000001
  +08 struct _DRIVER_OBJECT *DriverObject = FE4E8AD0
  // 正是 acpi 的 DRIVER_OBJECT 的地址
  +0c struct _DEVICE_OBJECT *NextDevice = FE4DD850
  +10 struct _DEVICE_OBJECT *AttachedDevice = FE4F5020
  // 上面一层的设备对象
  +14 struct _IRP *CurrentIrp = 00000000
  ...
  +ae uint16 Spare1 = 0001
  +b0 struct _DEVOBJ_EXTENSION *DeviceObjectExtension = FE4DD7E8
  // 它的 DEVOBJ_EXTENSION 在 FE4DD7E8
  +b4 void *Reserved = 00000000
  kd> !strct DEVOBJ_EXTENSION FE4DD7E8
  struct _DEVOBJ_EXTENSION (sizeof=36)
  +00 int16 Type = 000d
  +02 uint16 Size = 0000
  +04 struct _DEVICE_OBJECT *DeviceObject = FE4DD730
  +08 uint32 PowerFlags = 00000010
  +0c *Dope = 00000000
  +10 uint32 ExtensionFlags = 00000000
  +14 void *DeviceNode = FE4FED68
  +18 struct _DEVICE_OBJECT *AttachedTo = 00000000
  // 为空结束,表示下面没有其它设备对象了
  +1c struct _LIST_ENTRY FileObjectList
  +1c struct _LIST_ENTRY *Flink = 00000000
  +20 struct _LIST_ENTRY *Blink = 00000000
  从上自下。\Device\KeyboardClass0(DRIVER_OBJECT 是 kbdclass)可以找到 没有名字地址为fe4f5020的DEVICE_OBJECT(DRIVER_OBJECT 是 i8042prt)。没有名字地址为fe4f5020的DEVICE_OBJECT(DRIVER_OBJECT 是 i8042prt)可以找到 \Device\0000000e(DRIVER_OBJECT 是 ACPI)。
  从下自上。\Device\0000000e(DRIVER_OBJECT 是 ACPI) 可以找到 没有名字地址为fe4f5020的DEVICE_OBJECT(DRIVER_OBJECT 是 i8042prt)。没有名字地址为fe4f5020的DEVICE_OBJECT(DRIVER_OBJECT 是 i8042prt)可以找到 \Device\KeyboardClass0(DRIVER_OBJECT 是 ACPI)。

  现在我们对设备栈上的设备对象之间的联系,做一个总结,

  设备栈上的设备对象,从上自下,通过 DEVICE_OBJECT 的 DEVOBJ_EXTENSION 的 +18 struct _DEVICE_OBJECT *AttachedTo 联系在一起。
  设备栈上的设备对象,从下自上,通过 DEVICE_OBJECT 的 +10 struct _DEVICE_OBJECT *AttachedDevice 联系在一起。
  在观察键盘驱动的初始化过程中,我们看到了设备栈是如何建立起来的。
  驱动 i8042prt ,驱动 kbdclass 分别调用 IoAttachDeviceToDeviceStack ,把自己相应的设备对象加入到键盘设备栈中。IoAttachDeviceToDeviceStack 会设置 DEVICE_OBJECT 的 DEVOBJ_EXTENSION 的 +18 struct _DEVICE_OBJECT *AttachedTo 和 DEVICE_OBJECT 的 +10 struct _DEVICE_OBJECT *AttachedDevice ,把两个对象联系在一起。并设置新加入的设备对象的
+30 char StackSize。

抱歉!评论已关闭.