Help, WriteFileEx() behaves differently under Windows 98 vs. 2000/NT

Hello,

As you probably all know, WriteFileEx() is documented as returning TRUE if
“the calling thread has an asynchronous I/O (input/output) operation
pending”, FALSE otherwise.

I use WriteFileEx() to issue asynchronous writes to my WDM driver under
Windows 9x and 2000/NT. This seems to (mostly) function identically on both
Windows platforms. When WriteFileEx() returns TRUE, I enter an alertable
wait status (via SleepEx(), etc.) and eventually my
OVERLAPPED_COMLETION_ROUTINE is called.

However, a problem occurs when my driver *synchronously fails* the
IRP_MJ_WRITE request corresponding to a WriteFileEx() call. That is, when
it returns some failure status immediately from the dispatch routine instead
of starting the operation and returning STATUS_PENDING.

Under Windows 2000/NT, this causes WriteFileEx() to return FALSE, as would
seem logical. My user-mode thread thus knows *not* to enter a wait state.
Also, calling GetLastError() results in the expected “winerror.h”
translation of the status returned by the driver.

Under Windows 98 though, synchronously failing IRP_MJ_WRITE causes
WriteFileEx() to return TRUE, just as it does when the driver returns
STATUS_PENDING or STATUS_SUCCESS. Under Windows 9x, my user-mode thread is
thus “tricked” into waiting for the OVERLAPPED_COMPLETION_ROUTINE
callback – which never occurs.

Has anyone else noticed this behavior? Is it a bug in Windows 98’s
WriteFileEx() implementation?

Is there a workaround? I been thinking that perhaps that I can use
SetLastError(ERROR_SUCCESS) to clear any error before calling WriteFileEx()
and then always check GetLastError() afterwards (instead of relying on the
return value of WriteFileEx()), and enter a wait only on ERROR_IO_PENDING.

Thanks,

  • Matt

From: “Matt Arnold”
Sent: Thursday, August 17, 2000 2:38 PM

[snip]

> Under Windows 98 though, synchronously failing IRP_MJ_WRITE causes
> WriteFileEx() to return TRUE, just as it does when the driver returns
> STATUS_PENDING or STATUS_SUCCESS. Under Windows 9x, my user-mode thread
is
> thus “tricked” into waiting for the OVERLAPPED_COMPLETION_ROUTINE
> callback – which never occurs.
>
> Has anyone else noticed this behavior? Is it a bug in Windows 98’s
> WriteFileEx() implementation?
>
> Is there a workaround? I been thinking that perhaps that I can use
> SetLastError(ERROR_SUCCESS) to clear any error before calling
WriteFileEx()
> and then always check GetLastError() afterwards (instead of relying on the
> return value of WriteFileEx()), and enter a wait only on ERROR_IO_PENDING.

Apparently, the following seems to work around 9x’s weird behavior…

bool StartAsynchWrite( … )
{
SetLastError(ERROR_SUCCESS);

bool pending = WriteFileEx( … );

if (pending && (GetLastError() != ERROR_SUCCESS))
pending = false;

return pending;
}

This “works” (properly detects synchronous failures) under 9x in the
situation I described in my last post, but I don’t know if it will always
work, or will work properly under NT (where the workaround isn’t needed
anyway).

- Matt