首页
社区
课程
招聘
[求助]AssociatedIrp.SystemBuffer为NULL
发表于: 2013-5-21 22:27 11020

[求助]AssociatedIrp.SystemBuffer为NULL

2013-5-21 22:27
11020
虚拟磁盘驱动程序,先创建设备,再设置Flags 为 DO_BUFFERED_IO方式,如下:

IoCreateDevice(DriverObject,0,&deviceName,FILE_DEVICE_DISK,FILE_DEVICE_SECURE_OPEN,FALSE,&pDevObj);
pDevObj->Flags |= DO_BUFFERED_IO;

这样设置出来的虚拟磁盘设备应该是BUFFERED_IO方式啊,可是接着进入IRP_MJ_READ的时候悲剧来了。
结果是系统MDL给设置了,不是为NULL,
而AssociatedIrp.SystemBuffer却为NULL,
按照道理我是使用的AssociatedIrp.SystemBuffer,结果为NULL,自然驱动出错了。
这是为什么啊,MDL不是我要的,系统却给设置了,而AssociatedIrp.SystemBuffer是对应DO_BUFFERED_IO方式的缓冲区啊,为什么却被设置NULL了?

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (8)
雪    币: 78
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
pDevObj->Flags |= DO_BUFFERED_IO;
|=是一个OR操作,要先清除初始值DO_DEVICE_INITIALIZING

改之为:
IoCreateDevice(DriverObject,0,&deviceName,FILE_DEVICE_DISK,FILE_DEVICE_SECURE_OPEN,FALSE,&pDevObj);
pDevObj->Flags &= ~DO_DEVICE_INITIALIZING;
pDevObj->Flags |= DO_BUFFERED_IO;
2013-5-23 01:38
0
雪    币: 468
活跃值: (52)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
我的是有pDevObj->Flags &= ~DO_DEVICE_INITIALIZING;这一句,不过是在pDevObj->Flags |= DO_BUFFERED_IO; 之后的。
我的是这样的:
IoCreateDevice(DriverObject,0,&deviceName,FILE_DEVICE_DISK,FILE_DEVICE_SECURE_OPEN,FALSE,&pDevObj);
pDevObj->Flags |= DO_BUFFERED_IO;
......
......
pDevObj->Flags &= ~DO_DEVICE_INITIALIZING;
这样的,这个操作的先后顺序不用,结果难道会不同吗?我觉得先后顺序不影响吧。
2013-5-25 10:39
0
雪    币: 468
活跃值: (52)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
而且我跟踪了进入我的驱动分发例程的irp_mj_read和irp_mj_write,发现有些irp是mdl有效,有些是AssociatedIrp.SystemBuffer有效,不知道怎么回事,结果我只好在分发例程中判断,mdl有效就用mdl,AssociatedIrp.SystemBuffer有效就用AssociatedIrp.SystemBuffer.很奇怪啊,buffered_io和direct_io居然是不确定的。
2013-5-25 11:10
0
雪    币: 78
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
这个如果是顶层驱动,是要特别处理的
2013-5-27 01:47
0
雪    币: 468
活跃值: (52)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
嗯,是顶层驱动,要如何处理呀?
2013-5-27 07:28
0
雪    币: 78
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
  
你的代码没贴完整,无法多说
   
用下边的代码跟一下,就能知道到底采用那种方式了

        // 下面得到 Device 与用户程序交换数据的 Buffer
        //
        if (DeviceObject->Flags & DO_BUFFERED_IO)
        {
                KdPrint(("[DeviceObject->Flags = DO_BUFFERED_IO]\n"));
               
                //
                // 当属于 BUFFERED_IO 类型时:
                // 使用 Irp->AssociatedIrp.SystemBuffer 作为传输数据的 buffer
                //
                Buffer = Irp->AssociatedIrp.SystemBuffer;
        }
        else if (DeviceObject->Flags & DO_DIRECT_IO)
        {
                KdPrint(("[DeviceObject->Flags = DO_DIRECT_IO]\n"));
               
                //
                // 当属于 DIRECT_IO 方法时:
                // 使用 Irp 提供的 MdlAddress 描述的内存作传输数据的 buffer
                //
                Buffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, LowPagePriority);
                if (Buffer == NULL)
                {
                        Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
                        Irp->IoStatus.Information = Len;
                        IoCompleteRequest(Irp, IO_NO_INCREMENT);
                        return Status;
                }
        }
        else
        {
                KdPrint(("[DeviceObject->Flags = Neither]\n"));

                //
                // 当属于 NEITHER_IO 方式(既非 BUFFERED_IO 也非 DIRECT_IO 方式)时:
                // 使用 Irp->UserBuffer 作为数据传送的 buffer
                //
                Buffer = Irp->UserBuffer;
               
                Neither = TRUE;
        }
2013-5-27 15:12
0
雪    币: 468
活跃值: (52)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
嗯,我的代码就是一个简单的测试虚拟磁盘的驱动,就是读d:\s.img映射成一个虚拟磁盘。你上面的代码我自己在测试程序里面写入了类似的,检测结果是通过dbgprint输出,输出结果是有些irp_read是mdl方式,有些是systembuffer方式。我听你说顶层驱动要特别处理,那么顶层应该怎样处理,才能使得系统发送过来的irp都统一为 mdl方式或者统一为buffer方式呢?不要系统一会儿发过来是mdl方式,一会儿是buffer方式,这究竟是怎么了啊?这个系统是按什么规则发过来的 irp啊?如果是顶层驱动需要处理,该如何通知系统发过来的irp固定为 mdl或者固定为buffer方式呢?
2013-5-27 17:26
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
9

确认下DeviceIoControl的第二个参数,发送的消息类型是否定义有误。应用层和驱动层是否定义一致。缓存IO的话是METHOD_BUFFERED,定义类似这样#define IOCTL_REQUEST                        CTL_CODE(FILE_DEVICE_UNKNOWN, 0x727, METHOD_BUFFERED, FILE_ANY_ACCESS)

最后于 2021-8-5 16:46 被_djc_编辑 ,原因:
2021-8-5 16:45
0
游客
登录 | 注册 方可回帖
返回
//