mjq_nju
驱动牛犊
驱动牛犊
  • 注册日期2004-07-06
  • 最后登录2004-12-13
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1049回复:4

请教一个关于AddDevice例程的问题(程序理解上的)

楼主#
更多 发布于:2004-07-14 15:58
NTSTATUS AddDevice(IN PDRIVER_OBJECT DriverObject,IN PDEVICE_OBJECT PhysicalDeviceObject)
{
    //定义一个NTSTATUS类型的返回值:
    NTSTATUS status;
    //定义一个功能设备对象(Functional Device Object):
    PDEVICE_OBJECT fdo;

    //创建我们的功能设备对象,并储存到fdo中:
    status = IoCreateDevice(
        DriverObject,                //驱动程序对象
       sizeof(DEVICE_EXTENSION),    //要求的设备扩展的大小
        NULL,                        //设备名称,这里为NULL
        FILE_DEVICE_UNKNOWN,        //设备的类型,在标准头文件WDM.H或NTDDK.H中列出的FILE_DEVICE_xxx值之一
        0,                            //各种常量用OR组合在一起,指示可删除介质、只读等。
        FALSE,                        //如果一次只有一个线程可以访问该设备,为TRUE,否则为FALSE
        &fdo);                        //返回的设备对象
  //NT_SUCCESS宏用于测试IoCreateDevice内核是否成功完成。不要忘记检查对内核的所有调用是否成功。
  //NT_ERROR宏不等同于!NT_SUCCESS,最好使用!NT_SUCCESS,因为除了错误外,它还截获警告信息。
    if( !NT_SUCCESS(status))
        return status;

    //创建一个设备扩展对象dx,用于存储指向fdo的指针:
  
PDEVICE_EXTENSION dx = (PDEVICE_EXTENSION)fdo>DeviceExtension;
    dx->fdo = fdo;

    //用IoAttachDeviceToDeviceStack函数把HelloWDM设备挂接到设备栈:
    dx->NextStackDevice = IoAttachDeviceToDeviceStack(fdo, PhysicalDeviceObject);

    //设置fdo的flags。有两个"位"是必须改变的,一个是必须清除DO_DEVICE_INITIA
    //LIZING标志,如果在DriverEntry例程中调用IoCreateDevice(),就不需要清除这个标志位
   //。还有一个是必须设置DO_BUFFER_IO标志位:
    fdo->Flags |= DO_BUFFERED_IO | DO_POWER_PAGABLE;
    fdo->Flags &= ~DO_DEVICE_INITIALIZING;

    //返回值:
    return STATUS_SUCCESS;
}




请问PDEVICE_EXTENSION dx=(PDEVICE_EXTENSION)fdo->DEVICEEXTENSION;
dx->fdo=fdo;
以及fdo->Flags|=D0_Buffered_IO|DO_Power_Pagable;
  fdo->Flags &= ~DO_DEVICE_INITIALIZING;
该怎么来理解,小弟已经看了整整一天了,实在不明白它的含义
hljwangjb
驱动牛犊
驱动牛犊
  • 注册日期2002-12-10
  • 最后登录2006-09-04
  • 粉丝0
  • 关注0
  • 积分21分
  • 威望3点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2004-07-14 17:36
就是简单的赋值,和标志位的设置了
snowStart
驱动老牛
驱动老牛
  • 注册日期2004-04-06
  • 最后登录2011-06-02
  • 粉丝0
  • 关注0
  • 积分95分
  • 威望19点
  • 贡献值177点
  • 好评度1点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2004-07-14 17:50
PDEVICE_EXTENSION dx=(PDEVICE_EXTENSION)fdo->DEVICEEXTENSION;
dx->fdo=fdo;


主要是对结构指针的备份
学习,关注,交流中... [email=fengyu@163.com]Email:snowstarth@163.com[/email] [url]http://bbs.zndev.com/?a=snowStart[/url]
mjq_nju
驱动牛犊
驱动牛犊
  • 注册日期2004-07-06
  • 最后登录2004-12-13
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2004-07-14 19:57
头文件中其中有一部分是这样的:
typedef struct _DEVICE_EXTENSION
{
  PDEVICE_OBJECT  fdo;
  PDEVICE_OBJECT  NextStackDevice;
  UNICODE_STRING  ifSymLinkName;

} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
我的理解是指从c语言角度本身,我是这样想的:dx 是指向一个结构体(形式同DEVICE_EXTENSION)的指针,fdo指向另一个结构体(形式同DEVICE_OBJECT)的指针,那么 语句:PDEVICE_EXTENSION dx = (PDEVICE_EXTENSION)fdo->DeviceExtension;时不是指将DeviceExtension这个元素用强制类型转换后赋给dx?


而语句 dx->fdo = fdo;中两个fdo应该是不同的含义把?前一个fdo是
DEVICE_EXTENSION结构体中的一个元素,而后一个则是前面已定义的指向功能设备对象的指针。但把这两个等起来带表了什么 呢?
lovedrvdev
驱动牛犊
驱动牛犊
  • 注册日期2004-07-11
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分4分
  • 威望42点
  • 贡献值0点
  • 好评度9点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2004-07-14 20:22
DeviceExtension(PVOID)指向一个由用户定义的数据结构,该结构可用于保存每个设备实例的信息。I/O管理器为该结构分配空间,但该结构的名字和内容完全由用户决定。一个常见的做法是把该结构命名为DEVICE_EXTENSION。使用给定的设备对象指针fdo可访问这个用户结构,代码如下:
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
简单说DeviceExtension就是一块系统提供给你的非分页内存,用来备份一些系统的数据和存放用户的数据,dx->fdo=fdo备份FDO指针在
设备对象中有两个标志位需要在AddDevice中初始化,并且它们在以后也不会改变,它们是DO_BUFFERED_IO和DO_DIRECT_IO标志。你只能设置并使用其中一个标志,它将决定你以何种方式处理来自用户模式的内存缓冲区。
设备对象中有两个标志位属于电源管理范畴。与前两个缓冲区标志不同,这两个标志在任何时间都可以被改变。DO_POWER_PAGABLE意味着电源管理器将在PASSIVE_LEVEL级上向你发送IRP_MJ_POWER请求。DO_POWER_INRUSH意味着你的设备在上电时将汲取大量电流,因此,电源管理器将确保没有其它INRUSH设备同时上电。
AddDevice中最后一件需要做的事是清除设备对象中的DO_DEVICE_INITIALIZING标志:
fdo->Flags &= ~DO_DEVICE_INITIALIZING;
当这个标志设置时,I/O管理器将拒绝任何打开该设备句柄的请求或向该设备对象上附着其它设备对象的请求。在驱动程序完成初始化后,必须清除这个标志。在以前版本的Windows NT中,大部分驱动程序在DriverEntry中创建所有需要的设备对象。当DriverEntry返回时,I/O管理器自动遍历设备对象列表并清除该标志。但在WDM驱动程序中,设备对象在DriverEntry返回后才创建,所以I/O管理器不会自动清除这个标志,驱动程序必须自己清除它。
如果觉得满意请给分

游客

返回顶部