If a driver returns immediately with an error status, it isn't necessary to signal any event. The caller does only wait on the event, if the driver returns STATUS_PENDING (Some user mode functions may only check for an error). If the driver returns STATUS_PENDING, the driver has called IoMarkIrpPending , which sets Irp->PendingReturned. The error path without STATUS_PENDING must not do anything.
I'm not sure how it relates to this discussion (if at all) but I'm pretty sure that under windows, that if I have a file handle associated with a completion port, that the completion notification is delivered to the port regardless of whether it pended or not.
(I depend on this behavior in my apps... it means I only have one place where I process I/O results.)
I also believe that I can wait on the OVERLAPPED's event to detect completion (regardless of whether the I/O pended or not.)
Thanks,
Joseph