windows内核开发笔记十三:DeviceObject结构

 

windows内核开发笔记十三:DeviceObject结构

前一节学习了DriverObject结构,这一节开始学习设备结构设备对象(DEVICE_OBJECT)是在内核中唯一接收请求的实体.大部分消息都是以请求(IRP)方式传递的,而任何一个请求都是发送被某个设备对象的.设备对象是驱动对象结构的第三个参数对象.内核程序是以一个驱动对象表示的,所以一个设备对象总是属于一个驱动对象.

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;//使用StartIO例程,此域指向当前IRP对象
    PIO_TIMER Timer;
    ULONG Flags;                                // See above:  DO_...
    ULONG Characteristics;                      // See ntioapi:  FILE_...
    __volatile 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; 

 

  • Type: 

  操作系统用它来表明该对象是一个设备对象,对设备对象来说,该成员的值为3, 它是一个只读成员。

  • Size : 

  表明设备对象的size (字节为单位),该字节不包括设备扩展对象(如果有的话)。它是一个只读成员。

  • ReferenceCount: 

  I/O管理器用它来追踪与该设备对象相关联的设备被打开的句柄数量。这就使得I/O管理器可以避免当针对该驱动的设备的句柄在没有处理完的情况下卸载驱动的情况发生。它是一个只读成员。

  • DriverObject: 

  驱动对象指针,表示一个已经加载的驱动的镜像,驱动对象将作为DriverEntry和AddDevice的输入参数之一,在调用IoCreateDevice 或者IoCreateDeviceSecure成功后,该成员由I/O管理器设置。 它是一个只读成员。

  • NextDevice: 

  指向下一个由同一驱动程序创建的设备对象(如果有的话),在调用IoCreateDevice 或者 IoCreateDeviceSecure成功后,I/O管理器会自动更新设备列表。 
  对非即插即用(non –PnP)驱动来说,当驱动卸载时,必须层层穿越设备链表并删除设备,而对即插即用设备(PnP)来说则不需要如此,PnP驱动只需要在设备移除操作(IRP_MN_REMOVE_DEVICE)时进行相关的清理工作即可。 
  驱动重新创建设备对象时会自动用到该成员,它是一个可读可写的成员。

  • AttacheDevice: 

  挂载设备指针,如果该设备对象没有挂载设备,则该成员为NULL,通过AttachedDevice成员指定的设备对象通常是过滤驱动程序的设备对象,过滤程序用于拦截那些针对该设备对象所代表的设备发起的I/O请求,该成员对外不可见。

  • CurrentIrp: 

  当前IRP。

  • Timer: 

  计时器指针,这使得I/O管理器可以间隔一秒钟调用驱动提供的及时器例程,详细可参考IoInitializeTimer。该成员可读可写。

  • Flags: 值为如下:
flag值含义
DO_BUFFERED_IO读写操作使用缓冲方式(系统复制缓冲区)访问用户模式数据,指定缓冲类型,用于被IO管理器发送到设备栈的IO请求包。Higher-level驱动同设备栈中的下一个lower驱动程序在这个成员上具有相同的值,除了更高水平上的驱动程序。
DO_EXCLUSIVE一次只允许一个线程打开设备句柄,标识驱动程序服务于一个独占设备,例如视频、串行、并行或者声音设备。WDM驱动程序不能设置这个标志。了解更多信息,查看Specifying Exclusive Access to Device Objects。
DO_DIRECT_IO读写操作使用直接方式(内存描述符表)访问用户模式数据,指定缓冲类型,用于被IO管理器发送到设备栈的IO请求包。Higher-level驱动同设备栈中的下一个lower驱动程序在这个成员上具有相同的值,除了更高水平上的驱动程序。
DO_BUS_ENUMERATED_DEVICEBus drivers set this flag in the PDO of each device they enumerate. This flag pertains only to the PDO; it must not be set in an FDO or filter DO. Therefore, higher-level drivers layered over a bus driver must not propagate this value up the device stack.  OS在每个物理设备对象(PDO)上设置这个标志。驱动程序不能修改这个标志。
DO_DEVICE_INITIALIZING

设备对象正在初始化

当创建设备对象时,IO管理器设置这个标志。在以下操作之后,一个设备功能驱动或者过滤驱动在AddDevice例程中清除这个标志: 
(1) 附加设备对象到设备栈 
(2) 建立设备电源状态 
(3) 如果有必要,这个成员同电源标志执行按位与操作 

在AddDevice例程返回之后PNP管理器检查这个标志是否清除。

DO_POWER_INRUSHDrivers of devices that require inrush current when powering on must set this flag. A driver cannot set both this flag and DO_POWER_PAGABLE.设备上电期间需要大电流
DO_POWER_PAGABLE

Windows? 2000 and later drivers that are pageable, are not part of the paging path, and do not require inrush current must set this flag. The system calls such drivers at IRQL PASSIVE_LEVEL. Drivers cannot set both this flag and DO_POWER_INRUSH.
All WDM, Windows 98, and Windows Me drivers must set DO_POWER_PAGABLE.必须在PASSIVE_LEVEL级上处理IRP_MJ_PNP请求

同windows2000以及以后版本的windows兼容,可分页驱动不是调页路径的一部分,不要流入当前不需要设置这个标志。系统在IRQL=PASSIVE_LEVEL调用这类驱动。驱动程序不能将此标志与DO_POWER_INRUSH一起设置。所有的WDM驱动程序,windows98和windows Millennium 版本必须设置DO_POWER_PAGABLE。

DO_VERIFY_VOLUME

Removable-media drivers set this flag while processing transfer requests. Such drivers should also check for this flag in the target for a transfer request before transferring any data. See the Supporting Removable Media for details

当它们处理传递请求的时候可移动的媒介驱动程序设置这个标志。这样的驱动程序同样需要在它们传递任何数据之前为传递请求核对这个标志。了解更多信息,查看Supporting Removable Media主题。

DO_MAP_IO_BUFFER:

这个标志已不再使用。驱动程序不能设置这个标志。 
设备驱动程序需要流入当前必须设置这个标志当设备打开时。一个驱动程序不能同DO_POWER_PAGABLE一起设置这个标志。

DO_SHUTDOWN_REGISTERED:被IO管理器用于标识驱动程序已经为设备对象注册了关机回调函数,这个标志不能被驱动程序使用。

 

  • Characteristics: 

指定一个或者多个系统定义的常量,组合按位与操作,提供驱动程序设备的额外信息,这些常量包含以下内容:

Characteristics值含义
FILE_AUTOGENERATED_DEVICE_NAME直接由IO管理器为设备产生一个名字,取代由调用者调用这个例程时指定一个DeviceName。IO管理器必须保证这个名字是唯一的。这个characteristic通常由PNP总线驱动为物理设备对象在同一个总线上的子设备生成一个名字。这个characteristic伴随着windows 2000和windows98新开始.
FILE_CHARACTERISTIC_PNP_DEVICE标识设备对象是PNP栈的一部分,当总线驱动(或者总线过滤驱动)为没有收到IRP_START_MN_DEVICE请求的设备驱动注册WMI时,这个characteristics是必须的。如果一个功能或者过滤驱动在附上它的设备栈之前注册WMI,那么FILE_CHARACTERISTIC_PNP_DEVICE也是必须的。
FILE_CHARACTERISTIC_TS_DEVICE标识设备对象是终端服务设备栈,驱动程序不能设置这个特征。
FILE_CHARACTERISTIC_WEBDAV_DEVICE 表示基于Web的分布式创作和版本的文件系统已经在设备上挂载,驱动程序不能设置这个特征。
FILE_DEVICE_IS_MOUNTED表示文件系统已经在设备上挂载,驱动程序不能设置这个特征。
FILE_DEVICE_SECURE_OPEN IO管理器直接应用设备对象的安全描述符为打开相关设备和跟踪设备文件名的打开。了解更多信息,查看Controlling Device Namespace Access。
FILE_FLOPPY_DISKETTE 表示该设备是一个软盘驱动设备。
FILE_READ_ONLY_DEVICE 表示该设备不能被写入
FILE_REMOTE_DEVICE 表示该设备是一个远程的设备
FILE_REMOVABLE_MEDIA 表示存储设备支持可移动媒介。注意这个特征表示可移动媒介而不是可移动设备,例如,JAZ驱动程序的驱动设备应该指定这个特征,但是PCMCIA闪盘驱动程序不能指定这个特征。
FILE_VIRTUAL_VOLUME 表示卷是虚拟的,驱动程序不能设置这个特征。
FILE_WRITE_ONCE_MEDIA 表示设备支持写一次媒介。驱动程序不能直接设置这个成员。关于设置设备特征的更多信息,查看Specifying Device Characteristics。
  • Vpb: 
      与该设备对象相关的卷参数块指针(VPB)。对系统文件驱动来说,VPB提供了一个连接没有命名的逻辑设备对象的功能,该逻辑设备对象代表着一个已挂载的卷。该成员是不可见的。
  • DeviceExtension: 

  设备扩展结构指针,该结构体及其内容是由驱动定义的。大小也是由驱动决定的,该大小是在驱动调用IoCreateDevice或者IoCreatDeviceSecure函数是指定的。该成员是一个只读成员,但是,它指向的结构体式可以被驱动修改的。

  • DeviceType: 

  由IoCreateDevice或者IoCreatDeviceSecure函数是设定,具体设定的参数是由历程中DeviceType参数决定的,详细参见设备种类描述表。
StackSize: 
  指定发送给该驱动的IRP中stacklocation 的大小(最小值),IoCreateDevice和IoCreateDeviceSecure函数在新创建的设备对象中把该值设为1;最底层的驱动可以无视该成员。如果驱动调用IoAttachDevice 或者 
  IoAttachDeviceToDeviceStack函数时,I/O管理器在上层的驱动的设备对象中设置一个适当的值。

  • QueueAlignmentRequirement: 

  该成员针对数据的传输时指定设备的地址对齐请求,该值必须是定义在Wdm.h中的形如FILE_XXX_ALIGNMENT的值中的一个。

  • DeviceQueue: 

  设备对象的队列。驱动队列中包含了与驱动对象相应的等待驱动处理的IRP。

  • Dpc: 

  延迟处理调用。

  • ActiveThreadCount: 

  保留备用,该成员不可见。

  • SecurityDescriptor: 

  当设备对象创建时指定安全描述表(SECURITY_DISCRIPTOR),如果该成员为空,则该设备对象当做默认的安全设定。虽然该成员可以通过ZwSetSecurityObject函数修改,但它是只读的。

  • DeviceLock: 

  由I/O管理器创建的同步事件对象。

  • SectorSize: 

  如果设备对象不是表示一个卷,该成员设成0,如果是表示一个卷,该成员表示的是卷的分区的字节数。

  • Spare1: 

  保留供系统备用,该成员不可见。

  • DeviceObjectExtension: 

  设备对象扩展指针,I/O管理器和PnP管理器用该对象来存储设备的一些状态信息,该成员不可见。

  • Reserved: 

  保留供系统使用,该成员不可见。
 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jyl_sh

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值