DeviceIoControl, FILE_FLAG_OVERLAPPED and NULL lpOverlapped Question (I have the stupids today...)

The MSDN documentation for DeviceIoControl says:

“If hDevice was opened with the FILE_FLAG_OVERLAPPED flag, the operation is performed as an overlapped (asynchronous) operation. In this case, lpOverlapped must point to a valid OVERLAPPED structure that contains a handle to an event object. Otherwise, the function fails in unpredictable ways.”

In reviewing a lot of WDK sample code I see quite a few examples where a device handle is opened with FILE_FLAG_OVERLAPPED for asynchronous I/O, but DeviceIoControl calls are made with lpOverlapped being NULL.

Is the MSDN admonition still correct? Or, was it an issue that was specific to 9X/ME?

Thomas F. Divine

Thomas Divine wrote:

In reviewing a lot of WDK sample code I see quite a few examples
where a device handle is opened with FILE_FLAG_OVERLAPPED for
asynchronous I/O, but DeviceIoControl calls are made with
lpOverlapped being NULL.

This came up awhile ago and actually spawned a huge flamewar when a noob posted that he wanted to “protect against people doing non-overlapped I/O to his driver” or something like that.

If you’re calling into a driver, and the IRP is completed synchronously in the dispatch routine, I think you’ll see the success/failure value of the IRP as the return value of DeviceIoControl() even if lpOverlapped is NULL. Otherwise I don’t know what happens.

Thanks for the info.

Actually, I’m hoping someone who really knows will pipe up and answer.

IIRC, DeviceIoControl on 9X/ME would behave badly in the case I am interested in, but I don’t think it is a problem on NT.

Any Microsoft guys want to comment on this?

Just want to know…

Thomas F. Divine

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:bounce-329773-
xxxxx@lists.osr.com] On Behalf Of xxxxx@gmail.com
Sent: Tuesday, July 08, 2008 9:44 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] DeviceIoControl, FILE_FLAG_OVERLAPPED and NULL
lpOverlapped Question (I have the stupids today…)

Thomas Divine wrote:

> In reviewing a lot of WDK sample code I see quite a few examples
> where a device handle is opened with FILE_FLAG_OVERLAPPED for
> asynchronous I/O, but DeviceIoControl calls are made with
> lpOverlapped being NULL.

This came up awhile ago and actually spawned a huge flamewar when a
noob posted that he wanted to “protect against people doing non-
overlapped I/O to his driver” or something like that.

If you’re calling into a driver, and the IRP is completed synchronously
in the dispatch routine, I think you’ll see the success/failure value
of the IRP as the return value of DeviceIoControl() even if
lpOverlapped is NULL. Otherwise I don’t know what happens.


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

I can say from personal experience that this can hose you…It’s been a
while since I’ve been bitten by this, but this is the reasoning to the best
of my recollection (and someone will fill in the holes if I miss something,
this list is usually pretty good at that :))

When you open non-overlapped, you (duh) get synchronous I/O. This causes the
I/O manager to do all kinds of extra things, two of which are interesting:

  1. He takes out a per-file object lock before dispatching operations against
    your handle

  2. More importantly, he signals the completion of the I/O operation via an
    event in the file object. There’s only ever going to be one I/O operation at
    a time against the handle, so he can leverage the file object to signal
    completion.

Now, compare this to the overlapped case. In the overlapped case, the file
object is not locked across the dispatch *and* it is assumed that your
application is supplying the event for the I/O operation, so the I/O manager
will signal the completion of the operation via that event…

The hosing then happens because by doing what you suggest you confuse the
I/O manager in KM and the Win32 subsystem in UM when you mix and match.

You open the file overlapped, so you have an asynchronous file object in KM.
Then you do your DeviceIoControl. Win32 determines if you’ve opened the file
for overlapped or not by the presense of the overlapped structure (why
bother tracking all handles in your process and how you opened them?). If
the overlapped structure is present, this is an overlapped handle and he
hucks the device control and returns.

If the structure is *not* present, then this means to Win32 that you’ve
opened a synchronous handle and completion is going to be signaled via the
file object. So, Win32 hucks the I/O and, if pending is returned, it then
*waits on the file handle*, 'cause that’s what is signalled for synchronous
I/O. Now you have the kernel and user parts of the O/S out of phase and bad
things can happen (in a multithreaded scenario I’ve managed to have the O/S
tell me that my I/O was complete even though it really wasn’t finished yet,
oops).

There are other details in there that will make it seem like it works most
of the time, like I said it’s been a while. But, this isn’t just a Win9x
issue, it’s an actual bug.

-scott


Scott Noone
Software Engineer
OSR Open Systems Resources, Inc.
http://www.osronline.com

“Thomas F. Divine” wrote in message
news:xxxxx@ntdev…
Thanks for the info.

Actually, I’m hoping someone who really knows will pipe up and answer.

IIRC, DeviceIoControl on 9X/ME would behave badly in the case I am
interested in, but I don’t think it is a problem on NT.

Any Microsoft guys want to comment on this?

Just want to know…

Thomas F. Divine

> -----Original Message-----
> From: xxxxx@lists.osr.com [mailto:bounce-329773-
> xxxxx@lists.osr.com] On Behalf Of xxxxx@gmail.com
> Sent: Tuesday, July 08, 2008 9:44 PM
> To: Windows System Software Devs Interest List
> Subject: RE:[ntdev] DeviceIoControl, FILE_FLAG_OVERLAPPED and NULL
> lpOverlapped Question (I have the stupids today…)
>
> Thomas Divine wrote:
>
> > In reviewing a lot of WDK sample code I see quite a few examples
> > where a device handle is opened with FILE_FLAG_OVERLAPPED for
> > asynchronous I/O, but DeviceIoControl calls are made with
> > lpOverlapped being NULL.
>
> This came up awhile ago and actually spawned a huge flamewar when a
> noob posted that he wanted to “protect against people doing non-
> overlapped I/O to his driver” or something like that.
>
> If you’re calling into a driver, and the IRP is completed synchronously
> in the dispatch routine, I think you’ll see the success/failure value
> of the IRP as the return value of DeviceIoControl() even if
> lpOverlapped is NULL. Otherwise I don’t know what happens.
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer

Thanks, Scott. I appreciate you taking the time to provide a reasonable
explaination.

In the WDK samples where I see this bug (CreateFile with
FILE_FLAG_OVERLAPPED and DeviceIoControl with lpOverlapped NULL) the sample
driver generally waits on an event in Dispatch and does not return from
Dispatch until the I/O is complete.

However, in these samples there is other asynchronous I/O (Read completion
in particular) that could happen…

I guess that this points out a flaw in providing “samples”…

Warm regards,

Thomas F. Divine

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:bounce-329804-
xxxxx@lists.osr.com] On Behalf Of Scott Noone
Sent: Wednesday, July 09, 2008 10:18 AM
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] DeviceIoControl, FILE_FLAG_OVERLAPPED and NULL
lpOverlapped Question (I have the stupids today…)

I can say from personal experience that this can hose you…It’s been a
while since I’ve been bitten by this, but this is the reasoning to the
best
of my recollection (and someone will fill in the holes if I miss
something,
this list is usually pretty good at that :))

When you open non-overlapped, you (duh) get synchronous I/O. This
causes the
I/O manager to do all kinds of extra things, two of which are
interesting:

  1. He takes out a per-file object lock before dispatching operations
    against
    your handle

  2. More importantly, he signals the completion of the I/O operation via
    an
    event in the file object. There’s only ever going to be one I/O
    operation at
    a time against the handle, so he can leverage the file object to signal
    completion.

Now, compare this to the overlapped case. In the overlapped case, the
file
object is not locked across the dispatch *and* it is assumed that your
application is supplying the event for the I/O operation, so the I/O
manager
will signal the completion of the operation via that event…

The hosing then happens because by doing what you suggest you confuse
the
I/O manager in KM and the Win32 subsystem in UM when you mix and match.

You open the file overlapped, so you have an asynchronous file object
in KM.
Then you do your DeviceIoControl. Win32 determines if you’ve opened the
file
for overlapped or not by the presense of the overlapped structure (why
bother tracking all handles in your process and how you opened them?).
If
the overlapped structure is present, this is an overlapped handle and
he
hucks the device control and returns.

If the structure is *not* present, then this means to Win32 that you’ve
opened a synchronous handle and completion is going to be signaled via
the
file object. So, Win32 hucks the I/O and, if pending is returned, it
then
*waits on the file handle*, 'cause that’s what is signalled for
synchronous
I/O. Now you have the kernel and user parts of the O/S out of phase and
bad
things can happen (in a multithreaded scenario I’ve managed to have the
O/S
tell me that my I/O was complete even though it really wasn’t finished
yet,
oops).

There are other details in there that will make it seem like it works
most
of the time, like I said it’s been a while. But, this isn’t just a
Win9x
issue, it’s an actual bug.

-scott


Scott Noone
Software Engineer
OSR Open Systems Resources, Inc.
http://www.osronline.com

“Thomas F. Divine” wrote in message
> news:xxxxx@ntdev…
> Thanks for the info.
>
> Actually, I’m hoping someone who really knows will pipe up and answer.
>
> IIRC, DeviceIoControl on 9X/ME would behave badly in the case I am
> interested in, but I don’t think it is a problem on NT.
>
> Any Microsoft guys want to comment on this?
>
> Just want to know…
>
> Thomas F. Divine
>
>
> > -----Original Message-----
> > From: xxxxx@lists.osr.com [mailto:bounce-329773-
> > xxxxx@lists.osr.com] On Behalf Of xxxxx@gmail.com
> > Sent: Tuesday, July 08, 2008 9:44 PM
> > To: Windows System Software Devs Interest List
> > Subject: RE:[ntdev] DeviceIoControl, FILE_FLAG_OVERLAPPED and NULL
> > lpOverlapped Question (I have the stupids today…)
> >
> > Thomas Divine wrote:
> >
> > > In reviewing a lot of WDK sample code I see quite a few examples
> > > where a device handle is opened with FILE_FLAG_OVERLAPPED for
> > > asynchronous I/O, but DeviceIoControl calls are made with
> > > lpOverlapped being NULL.
> >
> > This came up awhile ago and actually spawned a huge flamewar when a
> > noob posted that he wanted to “protect against people doing non-
> > overlapped I/O to his driver” or something like that.
> >
> > If you’re calling into a driver, and the IRP is completed
> synchronously
> > in the dispatch routine, I think you’ll see the success/failure value
> > of the IRP as the return value of DeviceIoControl() even if
> > lpOverlapped is NULL. Otherwise I don’t know what happens.
> >
> > —
> > NTDEV is sponsored by OSR
> >
> > For our schedule of WDF, WDM, debugging and other seminars visit:
> > http://www.osr.com/seminars
> >
> > To unsubscribe, visit the List Server section of OSR Online at
> > http://www.osronline.com/page.cfm?name=ListServer
>
>
>
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer

Thomas Divine wrote:

In the WDK samples where I see this bug (CreateFile with
FILE_FLAG_OVERLAPPED and DeviceIoControl with lpOverlapped
NULL) the sample driver generally waits on an event in Dispatch
and does not return from Dispatch until the I/O is complete.

Really, which ones? I thought this, too, was a no-no (waiting in the dispatch routine)…

Chris hit the nail on the head.

The biggest concern is if you issue multiple outstanding I/Os on the same async handle without an overlapped structure. The Win32 APIs will try to wait on the device/file handle, and the completion of one I/O can cause the wrong call to unwind (leading to bogus data and a corrupt stack when the I/O does actually complete since the IOSB is no longer valid but we still try to write to it).

We’ll take care of cleaning up our samples for the next release. Thanks guys!

-Paul

I was cruising through the WDK 6001.18001 NDISPROT samples (5X and 60) to see if there was anything new and noticed this behavior there. It’s been there forever - just peaked my interest.

I think all the samples should be reviewed for this specific behavior. It wouldn’t hurt systematically reviewing all the samples to cull out bugs. Understand that many samples are used as “templates” for deriving “commercial” products. A bug in a sample will likely appear in the wild.

Thomas

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:bounce-329834-
xxxxx@lists.osr.com] On Behalf Of xxxxx@gmail.com
Sent: Wednesday, July 09, 2008 12:18 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] DeviceIoControl, FILE_FLAG_OVERLAPPED and NULL
lpOverlapped Question (I have the stupids today…)

Thomas Divine wrote:

> In the WDK samples where I see this bug (CreateFile with
> FILE_FLAG_OVERLAPPED and DeviceIoControl with lpOverlapped
> NULL) the sample driver generally waits on an event in Dispatch
> and does not return from Dispatch until the I/O is complete.

Really, which ones? I thought this, too, was a no-no (waiting in the
dispatch routine)…


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer