Holy cow, I wrote a book!
When an I/O completes (whether synchronously or asynchronously),
the event is signaled and completion status notifications are queued.
The GetOverlappedResult/Ex function can be used
to wait on an I/O that has already completed;
it will merely return immediately.
If you ask
HasOverlappedIoCompleted whether the I/O
has completed, and the I/O completed synchronously,
it will correctly report,
"Yeah, of course it completed. Heck, it completed a long time ago!"
In other words, you can logically treat the case of an asynchronous
I/O request completing synchronously as if it had completed asynchronously.
It just completes asynchronously before you even blinked.