ERROR_GEN_FAILURE

We have a custom USB device which supports 2 pairs of IN/OUT endpoints.
The first pair is used for bulk I/O via calls to ReadFile and WriteFile.
The second pair is used for messaging via custom IOCTL calls. The handle
used for both purposes is opened using a device name returned by the
SetupDi API.

hDevice = CreateFile( pDevName, GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL );

On WXP this mostly works, but every once in a long while, a call to ReadFile or
WriteFile fails and GetLastError returns 0x1F which, according to winerror.h,
is ERROR_GEN_FAILURE.

BOOL success = ReadFile(hDevice, pData, length, &transferred, NULL);
if (!success)
LastError = GetLastError(); // ERROR_GEN_FAILURE!!!

Searches for this error by name suggest that the device has been disconnected or
needs a manual reset, neither of which is true: If the application waits 20-30 msec
and then retries, that’s generally good enough. But not always. Microsoft says,

“Block device drivers should return ERROR_GEN_FAILURE for any unknown or unexpected errors”

so it might as well be ERROR_BLACK_SWAN.

On the PC side, we have a custom KMDF driver which gets loaded whenever the
device is plugged in. We wrote the driver, so we know that it does not raise
this error. The question I have for you folks is this: Under what conditions
would WDF, the USB stack, and/or the O/S throw up their hands and declare
ERROR_GEN_FAILURE? I would welcome concrete examples of “unknown or unexpected
errors” that you have encountered in similar circumstances.

Of course you did not return ERROR_GEN_FAILURE in your driver since that
is a Win32 error, what you might look for are places you return
STATUS_UNSUCCESSFUL which is the most common kernel status code to
translate to ERROR_GEN_FAILURE.

Don Burn (MVP, Windows DKD)
Windows Filesystem and Driver Consulting
Website: http://www.windrvr.com
Blog: http://msmvps.com/blogs/WinDrvr

xxxxx@juno.com” wrote in message
news:xxxxx@ntdev:

> We have a custom USB device which supports 2 pairs of IN/OUT endpoints.
> The first pair is used for bulk I/O via calls to ReadFile and WriteFile.
> The second pair is used for messaging via custom IOCTL calls. The handle
> used for both purposes is opened using a device name returned by the
> SetupDi API.
>
> hDevice = CreateFile( pDevName, GENERIC_READ | GENERIC_WRITE,
> FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
> FILE_ATTRIBUTE_NORMAL, NULL );
>
> On WXP this mostly works, but every once in a long while, a call to ReadFile or
> WriteFile fails and GetLastError returns 0x1F which, according to winerror.h,
> is ERROR_GEN_FAILURE.
>
> BOOL success = ReadFile(hDevice, pData, length, &transferred, NULL);
> if (!success)
> LastError = GetLastError(); // ERROR_GEN_FAILURE!!!
>
> Searches for this error by name suggest that the device has been disconnected or
> needs a manual reset, neither of which is true: If the application waits 20-30 msec
> and then retries, that’s generally good enough. But not always. Microsoft says,
>
> “Block device drivers should return ERROR_GEN_FAILURE for any unknown or unexpected errors”
>
> so it might as well be ERROR_BLACK_SWAN.
>
> On the PC side, we have a custom KMDF driver which gets loaded whenever the
> device is plugged in. We wrote the driver, so we know that it does not raise
> this error. The question I have for you folks is this: Under what conditions
> would WDF, the USB stack, and/or the O/S throw up their hands and declare
> ERROR_GEN_FAILURE? I would welcome concrete examples of “unknown or unexpected
> errors” that you have encountered in similar circumstances.

The driver never explicitly returns STATUS_UNSUCCESSFUL. In the bulk I/O
routines we pass the IoStatus.Status field from a WDF_REQUEST_COMPLETION_PARAMS
record as the 2nd argument in a call to WdfRequestCompleteWithInformation just
before returning. This could perhaps be STATUS_UNSUCCESSFUL. Is that all it
would take to get ERROR_GEN_FAILURE? It seems that whatever USB specific
information was stored in the Parameters.Usb.Completion->UsbdStatus field of
that record gets lost. Is there something better we could do?

Randall Barron wrote:

This could perhaps be STATUS_UNSUCCESSFUL. Is that all
it would take to get ERROR_GEN_FAILURE? It seems that
whatever USB specific information was stored in the
Parameters.Usb.Completion->UsbdStatus field of that record
gets lost. Is there something better we could do?

Sure, you could log that field to the event log or DebugView. Or, you could try to map all those return codes into NTSTATUS’s. Or both.