Re: Propagating the Pending Bit
- From: Anton Bassov <AntonBassov@xxxxxxxxxxxxxxxxxxxxxxxxx>
- Date: Fri, 9 Mar 2007 05:04:13 -0800
Calvin,
It's ok not to mark pending while
returning !STATUS_MORE_PROCESSING_REQUIRED.
Here is the quotation from IoMarkIrpPending documentation in WDK
[begin quote]
If a driver sets an IoCompletion routine for an IRP and then passes the IRP
down to a lower driver, the IoCompletion routine should check the
IRP->PendingReturned flag. If the flag is set, the IoCompletion routine must
call IoMarkIrpPending with the IRP.
[end quote]
As you can see, according to MSDN, unless you abort the call chain of
completion routines by returning STATUS_MORE_PROCESSING_REQUIRED,
IoMarkIrpPending() is an absolute must here. It seems to be a pointless call,
but it is not - you will see it shortly
NTSTATUS CompRoutine(irp)
{
//do whatever with the IRP
return STATUS_CONTINUE_COMPLETION;
}
As you will see below, the above code has quite insidious bug in it....
it doesn't make sense while setting a bit that nobody cares.
Well, this is quite bold statement. The problem is that, although the OS,
apparently, does not really care about it, some third-party drivers may do.
Consider the following scenario:
Someone decides to "optimize a performance" and avoid unnecessary calls to
KeSetEvent() in the completion routine. Therefore, his actions depend on
whether IRP has been completed synchronously or asynchronously. If IRP has
been completed asynchronously, he calls KeSetEvent() in the completion
routine, because he knows that his Dispatch routine waits on it . Otherwise,
he does not do anything - he knows that his Dispatch routine would not wait
on event if IRP has been completed synchronously, so that he deems a call to
KeSetEvent() unnecessary.....
What happens if you write your completion routine the way you have described,
and this "optimized" driver happens to be above you on the stack? The answer
is obvios - if you don't propagate PendingReturned flag, this driver will
always believe that IRP has been completed synchronously, and, hence, will
never call
KeSetEvent(). Therefore, if IoCallDriver() call that he makes from his
Dispatch routine returns STATUS_PENDING, his Dispatch routine is going to
deadlock......
This is just a classical example of how one may get into a conflict with the
third-party software because of avoiding some seemingly pointless call that,
according to MSDN, he should make....
Anton Bassov
"Calvin Guan" wrote:
Interesting. Haven't seen discussion on classic topic like this for a long.
time.
However, if the driver sets an IoCompletion routine, and the
next-lower driver returns STATUS_PENDING, the current driver must mark
its
own I/O stack location as pending.
I don't know where the OP get this from. I don't know the context of this
statement but if there is no higher driver, doing so is most likely
committing suicide unless the caller has allocated extra stack. but still it
doesn't make sense while setting a bit that nobody cares.
Not necessarily - it is required to do so only if its completion routine
does not return STATUS_MORE_PROCESSING_REQUIRED.
"Only" is a bit too strong here. It's ok not to mark pending while
returning !STATUS_MORE_PROCESSING_REQUIRED.
NTSTATUS CompRoutine(irp)
{
//do whatever with the IRP
return STATUS_CONTINUE_COMPLETION;
}
NTSTATUS
Xyz_call_drv_and_potentially_alter_the_return_status (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
)
{
IoMarkIrpPending(Irp);
IoSetCompletionRoutine(Irp,CompRoutine,....);
IoCallDriver(DeviceObject,Irp);
return STATUS_PENDING;
}
There are just too many calling and completion combinations. I think the
best way for people outside of MSFT to understand how things work is disasm
the IoSyncxxxServiceTail and IofCompleteRequest. It hasn't changed a lot
since NT3.x. In the end, why would people have to care about IRP nowadays? I
thought MSFT wants us use WDF which would solve all of the mess.
--
Calvin Guan (expiring DDK MVP)
Sr. Staff Engineer
NetXtreme NTX Miniport
Broadcom Corporation
Connecting Everything(r)
- Follow-Ups:
- Re: Propagating the Pending Bit
- From: Calvin Guan
- Re: Propagating the Pending Bit
- From: Eliyas Yakub [MSFT]
- Re: Propagating the Pending Bit
- References:
- Propagating the Pending Bit
- From: treecontrol
- Re: Propagating the Pending Bit
- From: Calvin Guan
- Propagating the Pending Bit
- Prev by Date: Re: Virtual comport with usbser.sys
- Next by Date: Re: Difxapp error list
- Previous by thread: Re: Propagating the Pending Bit
- Next by thread: Re: Propagating the Pending Bit
- Index(es):
Relevant Pages
|