"Any time a driver handling an I/O request returns the response of the
next-lower driver, the value of the pending bit in its I/O stack location
(SL_PENDING_RETURNED in the Control field of the IO_STACK_LOCATION
structure) must be the same as that of the next-lower driver. "

...of course they are the same!

"If the driver does not set an IoCompletion routine, the I/O Manager
automatically propagates the value of the bit, freeing the driver of this
responsibility. 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. "

if the driver sets an IoCompletion routine, means it has sth need to cleanup
before the irp is released, it is reasonalbe bcz device stack is a nesting
arch.

pls correct me.

RE: Propagating the Pending Bit by AntonBassov

AntonBassov
Thu Mar 08 21:41:11 CST 2007

> pls correct me.

OK, I will try my best.....

> if the driver sets an IoCompletion routine, means it has sth need to cleanup
> before the irp is released,

If a driver sets an IoCompletion routine, the only thing it means that, for
this or that reason, it wants to get access to this IRP when it gets
completed by lower-level drivers. If it does not set IoCompletion routine in
IRP, it has no chance to see this IRP again after having passed it down the
stack


> "If the driver does not set an IoCompletion routine, the I/O Manager
> automatically propagates the value of the bit, freeing the driver of this
> responsibility

Basically, PENDING_RETURNED means that lower-level driver had not completed
IRP immediately, but, instead, marked it as pending. If you haven't set
IOCompletion routine in IRP, it does not really matter for you - once you
have passed this IRP to the lower-level you are not going to ever see it
again. Therefore, your driver just cannot have any responsibility for IRP's
subsequent processing if it has not set IO Completion routine in it....

> 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.

Not necessarily - it is required to do so only if its completion routine
does not return STATUS_MORE_PROCESSING_REQUIRED. If it returns
STATUS_MORE_PROCESSING_REQUIRED, IOCompleteRequest() returns immediately, so
that completion routines that have been registed by higher-level drivers are
not going to get called. In this case, your driver will have to call
IoCompleteRequest() to complete IRP at some later stage, so that completion
routines that have been registed by higher-level drivers are going to get
called when your driver calls IoCompleteRequest() .

Anton Bassov

"treecontrol" wrote:

> "Any time a driver handling an I/O request returns the response of the
> next-lower driver, the value of the pending bit in its I/O stack location
> (SL_PENDING_RETURNED in the Control field of the IO_STACK_LOCATION
> structure) must be the same as that of the next-lower driver. "
>
> ....of course they are the same!
>
> "If the driver does not set an IoCompletion routine, the I/O Manager
> automatically propagates the value of the bit, freeing the driver of this
> responsibility. 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. "
>
> if the driver sets an IoCompletion routine, means it has sth need to cleanup
> before the irp is released, it is reasonalbe bcz device stack is a nesting
> arch.
>
> pls correct me.
>
>
>
>
>

Re: Propagating the Pending Bit by Tim

Tim
Thu Mar 08 22:59:31 CST 2007

"treecontrol" <treecontrol@hotmail.com> wrote:
>
>"Any time a driver handling an I/O request returns the response of the
>next-lower driver, the value of the pending bit in its I/O stack location
>(SL_PENDING_RETURNED in the Control field of the IO_STACK_LOCATION
>structure) must be the same as that of the next-lower driver. "
>
>...of course they are the same!

Why do you say that? Every driver in a driver stack has its own
IO_STACK_LOCATION in the IRP, separate from all of the others. Someone has
to copy the bit to the next stack location. Without an IoCompletion
routine, I/O manager will do it. If you do have an IoCompletion routine,
then no one will do it, so your driver must.

>"If the driver does not set an IoCompletion routine, the I/O Manager
>automatically propagates the value of the bit, freeing the driver of this
>responsibility. 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. "
>
>if the driver sets an IoCompletion routine, means it has sth need to cleanup
>before the irp is released, it is reasonalbe bcz device stack is a nesting
>arch.
>
>pls correct me.

Please correct what? I don't understand what you're trying to say. It's
true that an IO completion routine is used when a driver needs to take some
action when the IRP is completed, but also remember that STATUS_PENDING
means you can't really "clean up" yet. The IRP isn't finished.
--
Tim Roberts, timr@probo.com
Providenza & Boekelheide, Inc.

Re: Propagating the Pending Bit by Calvin

Calvin
Fri Mar 09 01:43:13 CST 2007

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)



Re: Propagating the Pending Bit by AntonBassov

AntonBassov
Fri Mar 09 07:04:13 CST 2007

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)
>
>
>

Re: Propagating the Pending Bit by Eliyas

Eliyas
Fri Mar 09 11:12:41 CST 2007

1) Documentation is not completely accurate. It just describes a typical
scenario but there so many different ways you can handle the IRP.

2) Calvin logic is correct. He doesn't need to mark the pending again in the
completionRoutine because he has already marked his stack location pending
in his dispatch routine. So when the IRP reaches the completion routine of
the driver above, it will have right information (ie Irp->PendingReturned
will be set). Look at the IoCompleteRequest code at the end of this message
to understand how that happens.

Here is the simple rule I follow to figure out whether the completion
routine should mark the IRP pending or not:

RULE:

If your dispatch routine returns the status of IoCallDriver as is then you
should do the following in your completion routine before you return.

if (Irp->PendingReturned) {
IoMarkIrpPending( Irp );
}

Let us examine this rule in little bit more detail:

NTSTATUS
DispathRoutine(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
IoCopyCurrentIrpStackLocationToNext(Irp);

IoSetCompletionRoutine();

return IoCallDriver(TopOfDeviceStack, Irp);
}

The above dispatch routine returns the status of the IoCallDriver as is.
When you do that, you cannot defer the completion of the IRP. In other
words, when the IRP comes back to your completionRoutine, you must let it
complete. In yet another words, you cannot return
STATUS_MORE_PROCESSING_REQUIRED and decide to complete the IRP later. If you
think hard, you will understand the reason. So let us look at how the
completionRoutine for this IRP is going to look:

NTSTATUS
CompletionRoutine_1 (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
)
{
if (Irp->PendingReturned) {
IoMarkIrpPending( Irp );
}

return STATUS_CONTINUE_COMPLETION ;
}

NTSTATUS
CompletionRoutine_2 (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
)
{
if (Irp->PendingReturned) {
IoMarkIrpPending( Irp );
}

IoCompleteRequest( Irp, IO_NO_INCREMENT);

return STATUS_MORE_PROCESSING_REQUIRED;
}


RULE 2:

If you mark the IRP pending, you must return STATUS_PENDING from your
dispatch routine. In the completion routine, you don't need to mark the IRP
pending again. You can either return STATUS_CONTINUE_COMPLETION or defer the
completion by returning STATUS_MORE_PROCESSING_REQUIRED.

NTSTATUS
DispathRoutine
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
IoMarkIrpPending( Irp );
IoCopyCurrentIrpStackLocationToNext(Irp);
IoSetCompletionRoutine();
IoCallDriver(TopOfDeviceStack, Irp);
return STATUS_PENDING ;
}CompletionRoutine_1(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
)
{
return STATUS_CONTINUE_COMPLETION ;
}

NTSTATUS
CompletionRoutine_2 (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
)
{
//
// Because you are stopping the completion of the IRP by returning the
// following status, you must complete the IRP later.
//
return STATUS_MORE_PROCESSING_REQUIRED ;
}

This article (http://support.microsoft.com/kb/320275 - it's split in to two
articles) I wrote about five few years ago describes all the possible ways
(AFAIK) of handling the IRP.It contains mostly code snippet. You have to
compare and contrast the cases to figure out the differences.

I have pasted here only the relevant code of IoCompletionRequest to help you
in understanding the insanity around marking the pending.

1) You will see how the pending flag is copied from the stack location to
the Irp->PendingReturned.
2) You willl see why the deviceobject is NULL in the completion routine.
Another often discussed issue.

IoCompleteRequest()
{
stackPointer = IoGetCurrentIrpStackLocation(Irp);


for (Irp->CurrentLocation++,

Irp->Tail.Overlay.CurrentStackLocation++;

Irp->CurrentLocation <= (CCHAR) (Irp->StackCount + 1);

stackPointer++,

Irp->CurrentLocation++,

Irp->Tail.Overlay.CurrentStackLocation++) {



Irp->PendingReturned = stackPointer->Control & SL_PENDING_RETURNED;



if ( (NT_SUCCESS( Irp->IoStatus.Status ) &&

stackPointer->Control & SL_INVOKE_ON_SUCCESS) ||

(!NT_SUCCESS( Irp->IoStatus.Status ) &&

stackPointer->Control & SL_INVOKE_ON_ERROR) ||

(Irp->Cancel &&

stackPointer->Control & SL_INVOKE_ON_CANCEL)

) {



minorFunction = stackPointer->MinorFunction;



//

// This driver has specified a completion routine. Invoke the

// routine passing it a pointer to its device object and the

// IRP that is being completed.

//



ZeroIrpStackLocation( stackPointer );



if (Irp->CurrentLocation == (CCHAR) (Irp->StackCount + 1)) {

deviceObject = NULL;

}

else {

deviceObject = IoGetCurrentIrpStackLocation(
Irp )->DeviceObject;

}



status = stackPointer->CompletionRoutine( deviceObject,

Irp,

stackPointer->Context
);



if (status == STATUS_MORE_PROCESSING_REQUIRED) {



//

// Note: Notice that if the driver has returned the above

// status value, it may have already DEALLOCATED the

// packet! Therefore, do NOT touch any part of the

// IRP in the following code.

//



return;

}



} else {

if (Irp->PendingReturned && Irp->CurrentLocation <=
Irp->StackCount) {

IoMarkIrpPending( Irp );

}

ZeroIrpStackLocation( stackPointer );

}

} // End of for loop



}



Re: Propagating the Pending Bit by Calvin

Calvin
Fri Mar 09 12:59:36 CST 2007

"Anton Bassov" <AntonBassov@discussions.microsoft.com> wrote in message
news:C7D1E53D-8C62-4F4F-BE43-BC9BD8056BE2@microsoft.com...
> 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....
>

LOL...You are taking the doc too too literately.... See Eliyas's excellent
explanations and demo code.

>
>> 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:
>

I obviously didn't make it clear for some people to understand what I was
trying to say. Let me expand a bit.

VOID func_a()
{
IoGetDeviceObjectPointer(...,&pDevObject);
irp = IoAllocateIrp(); // with no extra stack;
/// setup IRP stack.
IoSetCompetionRoutine(irp,CompRoutine,...);
IoCallDriver();
return;
}

NTSTATUS
CompRoutine(irp)
{
if (Irp->PendingReturned)
{
/// do NOT mark pending regardless what code you return,
/// it's fatal error - a logical one.
}
ObDereferenceObject(devobj);
IoFreeIrp(Irp);
return SMPR;
}

> 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 obvious - 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....
>

I've been writing almost all kind of IRP completion combinations. My drivers
are running on millions of NT systems for years. They are not in the habit
of croaking.

> according to MSDN

If someone can not understand what the document really wants to say, he just
can't write a solid driver, period. Maybe I should have shown you the list
of DDK doc bugs I've submitted over the years.

--
Calvin Guan (expiring DDK MVP)
Sr. Staff Engineer
NetXtreme NTX Miniport
Broadcom Corporation
Connecting Everything(r)



Re: Propagating the Pending Bit by Maxim

Maxim
Fri Mar 09 13:11:42 CST 2007

> 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.

Exactly so. Such a disasm saves kilobytes of explanation texts.

--
Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
maxim@storagecraft.com
http://www.storagecraft.com


Re: Propagating the Pending Bit by AntonBassov

AntonBassov
Fri Mar 09 20:23:13 CST 2007

> LOL...You are taking the doc too too literately....
> See Eliyas's excellent explanations and demo code.

Unfortunately, his explanation is just "insider info", rather than
documented behaviour of IoCompleteRequest(). Indeed, as it turns out,
IoMarkIrpPending()
call by the driver is unnecessary, simply because, unless the completion
routine returns STATUS_MORE_PROCESSING_REQUIRED, IoCompleteRequest() calls
IoMarkIrpPending() anyway if Irp->PendingReturned is set. In other words,
IoCompleteRequest() does something that, according to the doc I quoted,
should be done by the completion routine, so that doing the same thing in the
completion routine is simply unnecessary.

However, officially all the above is undocumented behaviour, so that MSFT
can change it at whenever it wants - after all, if some problem arises, they
can always say that you just haven't followed their guidelines.....

> Maybe I should have shown you the list
> of DDK doc bugs I've submitted over the years.

This is not really a bug - if you do it the way this doc says, you are not
going to get into any trouble. Therefore, this is just a "harmless"
discrepancy between DDK documentation and *CURRENTLY EXISTING* implementation
of IoCompleteRequest() that can be changed without breaking drivers that do
things the way the doc says.
Unfortunately, from time to time you can come across much more serious
"omissions" in the official documentation ( for example, WFP documentation
that came with RTM WDK is virtually unusable)....

Anton Bassov


"Calvin Guan" wrote:

> "Anton Bassov" <AntonBassov@discussions.microsoft.com> wrote in message
> news:C7D1E53D-8C62-4F4F-BE43-BC9BD8056BE2@microsoft.com...
> > 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....
> >
>
> LOL...You are taking the doc too too literately.... See Eliyas's excellent
> explanations and demo code.
>
> >
> >> 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:
> >
>
> I obviously didn't make it clear for some people to understand what I was
> trying to say. Let me expand a bit.
>
> VOID func_a()
> {
> IoGetDeviceObjectPointer(...,&pDevObject);
> irp = IoAllocateIrp(); // with no extra stack;
> /// setup IRP stack.
> IoSetCompetionRoutine(irp,CompRoutine,...);
> IoCallDriver();
> return;
> }
>
> NTSTATUS
> CompRoutine(irp)
> {
> if (Irp->PendingReturned)
> {
> /// do NOT mark pending regardless what code you return,
> /// it's fatal error - a logical one.
> }
> ObDereferenceObject(devobj);
> IoFreeIrp(Irp);
> return SMPR;
> }
>
> > 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 obvious - 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....
> >
>
> I've been writing almost all kind of IRP completion combinations. My drivers
> are running on millions of NT systems for years. They are not in the habit
> of croaking.
>
> > according to MSDN
>
> If someone can not understand what the document really wants to say, he just
> can't write a solid driver, period. Maybe I should have shown you the list
> of DDK doc bugs I've submitted over the years.
>
> --
> Calvin Guan (expiring DDK MVP)
> Sr. Staff Engineer
> NetXtreme NTX Miniport
> Broadcom Corporation
> Connecting Everything(r)
>
>
>

Re: Propagating the Pending Bit by AntonBassov

AntonBassov
Fri Mar 09 20:32:03 CST 2007

> > 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.
>
> Exactly so. Such a disasm saves kilobytes of explanation texts.

.... but gives you the additional headache if you rely it in a commercial
product - even minor system upgrade theoretically may shatter your product
into pieces......

Anton Bassov



"Maxim S. Shatskih" wrote:

> > 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.
>
> Exactly so. Such a disasm saves kilobytes of explanation texts.
>
> --
> Maxim Shatskih, Windows DDK MVP
> StorageCraft Corporation
> maxim@storagecraft.com
> http://www.storagecraft.com
>
>