阅读:1130回复:3
怎么理解啊???
看了《Windows驱动开发模型》一书的源码后有几个问题真是想不通,谁能够说说该怎么理解:
1、 关于StartIo、DpcForIsr、StartNextPacket三个例程的模糊点: 看了三个函数的关系后我不理解的是在StartIo例程中当 if (!stack->Parameters.Read.Length) { // nothing to do StartNextPacket(&pdx->dqReadWrite, fdo);//启动下一个IRP的处理工作 CompleteRequest(Irp, STATUS_SUCCESS, 0);//完成当前的IRP IoReleaseRemoveLock(&pdx->RemoveLock, Irp); return; } 条件不满足时就调用StartNextPacket函数,现在假设在队列中刚好有3个这样的IRP使得条件都不满足,这样当3个IRP在StartNextPacket和StartIo之间完成函数调用后这时StartIo函数就开始进行“出栈” 完成IRP的处理,也就是说开始调用 CompleteRequest(Irp, STATUS_SUCCESS, 0);//完成当前的IRP IoReleaseRemoveLock(&pdx->RemoveLock, Irp); return; 这3条语句,这样队列中排在最后的就先被处理,而派在最前的反而最后处理,这不符合IRP的串行化处理规则,因为它导致了先进入队列的应先处理。 2、 在StartNextPacket例程中有 pdq->CurrentIrp = Irp; 我们可以看到这个CurrentIrp相当于一个全局性的变量,在StartIo和StartNextPacket相互调用不断地被重新赋值,现在假设前几个IRP在StartIo中都是属于if (!stack->Parameters.Read.Length)类型的IRP而第4个则不满足该条件同时也成功地获得了删除锁,这时候StartIo开始了“回滚出栈”,如果在这个时候又刚好来了一个HandleQueryStop调用,它会判断WaitForCurrentIrp,问题在于当前的CurrentIrp被处理后WaitForCurrentIrp成功返回,也就是说可以停止设备了,实际上是StartIo还在继续回滚出栈,根本不能停下,CurrentIrp在StartNextPacket中被赋值正确吗? 3、 在DpcForIsr例程中我们可以看到: PIRP Irp = GetCurrentIrp(&pdx->dqReadWrite); StartNextPacket(&pdx->dqReadWrite, fdo); IoCompleteRequest(Irp, IO_NO_INCREMENT); IoReleaseRemoveLock(&pdx->RemoveLock, Irp); 我看到关于Dpc例程的描述是该例程先完成当前的IRP然后进行下一个IRP处理也就是把下一个IRP送到Start I/O中,但是我们这里却是进入了StartNextPacket中把下一个IRP送到StartIo然后在完成当前的IRP,这样处理正确吗,同样这里是不是也存在一个CurrentIrp的问题? |
|
沙发#
发布于:2005-04-20 14:16
1.我认为应该是\"出对\"而不是\"出栈\",怎么一会是栈一会是队列的
说的不一定对,请见谅 [编辑 - 4/20/05 by worldcup] |
|
板凳#
发布于:2005-04-20 16:56
是这样的,在《Windows Driver Model》的源码中作者用了一个队列来排队收到的IRP并在条件许可的情况下发送到StartIo例程中处理。在StartNextPacket函数中调用了StartIo例程,而在StartIo例程中又调用了StartNextPacket例程,这种两个例程的相互调用在结束彼此调用之前,这是一种堆栈操作方式。你可以想一下如果不是堆栈操作方式,函数怎么回退呢?
我想问一下你看过那本书的源代码吗,如果看过那么我们刚好可以讨论一下,因为我也是刚学驱动开发,对那本书的源码有些地方不是理解,但是我觉得他的设计思想是非常好的。 |
|
地板#
发布于:2005-04-26 14:25
求ds3.2 啊,除了本坛,那里有得下啊。是不是2.5版本得,不能在xpddk下面编译通过啊?
|
|