Chris,
I agree that you do not have to “make allowances” for other driver’s
completion routines as you have your own stack area for this.
However technically you can’t do:
> > KeSetEvent(event, 0, FALSE) ;
> >
> > if (NT_SUCCESS(Irp->IoStatus.Status))
> > DbgPrint(“Transfer Success\n”) ;
> > else DbgPrint(“Transfer Error\n”) ;
in your completion handler as once you call KeSetEvent then the IRP can be
completed in your dispatch routine before you get to your “if” statement
that references the IRP.
Actually it just hit me what the problem is here. I was looking at the fact
that you comment out the IrpPending test, and I was thinking that this could
be a source of the problem. Then I re-examined the dispatch side and:
> > status = IoCallDriver(devExt->NextDevice, Irp) ;
> > KeWaitForSingleObject(&event, Executive,
KernelMode, FALSE, NULL) ;
> > DbgPrint(“Continue and Complete\n”) ;
> >
> > IoCompleteRequest(Irp, IO_NO_INCREMENT) ;
> >
> > return status ;
The problem is that you are returning the value produced by the call to
IoCallDriver. Bad news if IoCallDriver returned STATUS_PENDING! You should
instead be setting status to Irp->IoStatus.Status, ASSERTing that status
does not equal STATUS_PENDING and returning that value.
Mark Roddy
xxxxx@hollistech.com
www.hollistech.com
WindowsNT Windows 2000 Consulting Services