首页
社区
课程
招聘
[旧帖] 关于寒江独钓一书中串口过滤的一段代码的疑问? 0.00雪花
发表于: 2014-4-25 20:53 3942

[旧帖] 关于寒江独钓一书中串口过滤的一段代码的疑问? 0.00雪花

2014-4-25 20:53
3942
//以下是过滤设备所属驱动对象的分发函数,用于写串口时得到要写入串口的数据
NTSTATUS ccpDispatch(PDEVICE_OBJECT device,PIRP irp)
{
    PIO_STACK_LOCATION irpsp = IoGetCurrentIrpStackLocation(irp);
    NTSTATUS status;
    ULONG i,j;

    // 首先得知道发送给了哪个过滤设备。设备一共最多CCP_MAX_COM_ID
    // 个,是前面的代码保存好的,都在s_fltobj中。
    for(i=0;i<CCP_MAX_COM_ID;i++)
    {
        if(s_fltobj[i] == device)
        {   
            // 所有电源操作,全部直接放过。
            if(irpsp->MajorFunction == IRP_MJ_POWER)
            {
                // 直接发送,然后返回说已经被处理了。
                PoStartNextPowerIrp(irp);
                IoSkipCurrentIrpStackLocation(irp);
                return PoCallDriver(s_nextobj[i],irp);
            }
            // 此外我们只过滤写请求。写请求的话,获得缓冲区以及其长度。
            // 然后打印一下。
            if(irpsp->MajorFunction == IRP_MJ_WRITE)
            {
                // 如果是写,先获得长度
                ULONG len = irpsp->Parameters.Write.Length;
                // 然后获得缓冲区
                PUCHAR buf = NULL;
                if(irp->MdlAddress != NULL)
                    buf = (PUCHAR)MmGetSystemAddressForMdlSafe(irp->MdlAddress,NormalPagePriority);
                else
                    buf = (PUCHAR)irp->UserBuffer;
                if(buf == NULL)
                    buf = (PUCHAR)irp->AssociatedIrp.SystemBuffer;

                // 打印内容
                for(j=0;j<len;++j)
                {
                    DbgPrint("comcap: Send Data: %2x\r\n",
                        buf[j]);
                }
            }

            // 这些请求直接下发执行即可。我们并不禁止或者改变它。
            IoSkipCurrentIrpStackLocation(irp);
            //IoCallDriver把请求发送给真实的设备。
            return IoCallDriver(s_nextobj[i],irp);
        }
    }

    // 如果根本就不在被绑定的设备中,那是有问题的,直接返回参数错误。
    irp->IoStatus.Information = 0;
    irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
    IoCompleteRequest(irp,IO_NO_INCREMENT);
    return STATUS_SUCCESS;
}

//////////////////////////////////////////我的疑问是最后这一点代码,如下:
   // 如果根本就不在被绑定的设备中,那是有问题的,直接返回参数错误。
    irp->IoStatus.Information = 0;
    irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
    IoCompleteRequest(irp,IO_NO_INCREMENT);
    return STATUS_SUCCESS;
书中所说的“如果根本就不在被绑定的设备中,那是有问题的,直接返回参数错误。”是啥意思呢?
什么根本不在被绑定的设备中?没看出这一段代码的作用是什么。请高手不吝赐教,谢谢啦!

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (7)
雪    币: 5
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
应该有很多朋友写个这个程序吗,怎么没有人回答呢?
2014-4-26 09:03
0
雪    币: 5
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
我把下面着两行代码注释后,运行程序也没有感觉有什么异常。
//irp->IoStatus.Information = 0;
//irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
2014-4-26 10:04
0
雪    币: 277
活跃值: (31)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
这句话的意思是说,没有设备存在,那么for循环里面的代码不会被执行。而且这个irp会直接给一个完成操作直接返回成功!就相当于没有进行任何操作!
2014-6-4 10:10
0
雪    币: 581
活跃值: (215)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
5
他只是对你上面循环之外的情况去考虑。那是有问题的不是说设备有问题,是指其他的设备。理解歧义了。
2014-6-5 22:52
0
雪    币: 5
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
可以把for循环和后面几行理解为 if else关系,如果没有要的写请求,我们认为这是不对的,向下传递的IRP的status设置为参数错误
2014-6-11 17:08
0
雪    币: 2
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
1.这个irp是发给dvice的,数组s_fltobj[0]保存的是你关注的过滤设备
2.比较两个设备是否一样,如果一样,就获取buf,病打印出来
3.如果不一样,就将该irp置为完成

可以明确的说该ir不是发给你的设备的,所以就忽略它(直接置为完成状态)
更清晰的逻辑是:在进入该分发函数之后就判断是不是发给s_fltobj[]的,如果不是的话,直接置为完成返回即可,是的话再执行后面操作。
2014-6-25 23:04
0
雪    币: 293
活跃值: (239)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
2014-12-5 23:18
0
游客
登录 | 注册 方可回帖
返回
//