Command Error Handling
When an error is returned for a command the device enters an IO-ERROR state. To clear this state the server must issue a ClearError command. The client must complete outstanding commands using the CompleteCommand function and then acknowledge the ClearError command.
At the server interface, when a virtual device is in the IO-ERROR state, further commands are immediately rejected with a code of ERROR_IO_DEVICE. This is done by calling the callback function immediately from the thread issuing the SendCommand. The server is not able to send any command other than a ClearError command. This command is not delivered from the GetCommand interface until the client has delivered command completions for commands that were outstanding at the time the device entered the IO-ERROR state. When the client receives the ClearError command, it can take any necessary actions, and then can respond with a successful completion code. Commands queued but not yet delivered to the client are automatically completed with ERROR_IO_DEVICE. The client never sees these commands.
After the server receives the completion on the ClearError command, the state of the device becomes Active again and any command can be issued.
This diagram describes the device states.
The reason for this error handling protocol is to ensure that the server is able to reliably recover from errors while asynchronous I/O is pending.
Instead of issuing a ClearError command, the server is free to CloseDevice or SignalAbort. In either case, the client sees an appropriate response from a subsequent GetCommand call.