Guarantee OVERLAPPED structure from user's DeviceIoControl

> To explain further what I’m doing, I am using KMDF, and in my

EvtDeviceCreateFile callback I am checking the file object flags with
WdfFileObjectGetFlags. If I find FO_SYNCHRONOUS_IO in the flags, I fail the
creation. This is intended to prevent the device file from being opened
without
FILE_FLAG_OVERLAPPED. (Is this a good way to check?)

In MJ_CREATE path, it is better to check for FILE_SYNCHRONOUS_IO_(NON)ALERT
flags somewhere in ->Parameters.Create.Options or such.

Outside the MJ_CREATE path, you can check FO_SYNCHRONOUS_IO, but it is better
to use a wrapper function for this called IoIsOperationSynchronous.


Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

The unanswered question is still “why do you care how the user opens the
device?”

Bill Wandel

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com]
On Behalf Of xxxxx@rtd.com
Sent: Friday, November 16, 2007 9:30 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Guarantee OVERLAPPED structure from user’s
DeviceIoControl

Thanks for everyone’s comments. (I didn’t mean to start a fight BTW.) It
seems I have some misconceptions about how things work.

To explain further what I’m doing, I am using KMDF, and in my
EvtDeviceCreateFile callback I am checking the file object flags with
WdfFileObjectGetFlags. If I find FO_SYNCHRONOUS_IO in the flags, I fail the
creation. This is intended to prevent the device file from being opened
without FILE_FLAG_OVERLAPPED. (Is this a good way to check?) Since my device
file must be opened with FILE_FLAG_OVERLAPPED, all DeviceIoControl calls to
it must use an OVERLAPPED structure (as stated in the DeviceIoControl docs,
mentioned earlier by Gianluca Varenni). I was hoping to catch a NULL
lpOverlapped value in the IOCTL handler in an attempt to prevent misuse of
the driver.

What still confuses me is this: Peter said earlier, “If they try to call
DeviceIoControl with no OVERLAPPED structure and they’ve opened the handle
for overlapped I/O then the I/O manager will take care of that for you.”
Some others have said the same thing. However the DeviceIoControl docs seem
to contradict this (unless failing in unpredictable ways is ok :-p ). Any
ideas?

Thanks,
Josh


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

Chris,

I tell people they can do the delete for testing. You suggested some
one hook for a priduction driver when there was no reason to do anything.
Sorry, your comments are beyond stupid.


Don Burn (MVP, Windows DDK)
Windows 2k/XP/2k3 Filesystem and Driver Consulting
Website: http://www.windrvr.com
Blog: http://msmvps.com/blogs/WinDrvr
Remove StopSpam to reply

wrote in message news:xxxxx@ntdev…
> Don Burn wrote:
>
>> This is one of the stupidest suggestions I have ever seen on this
>> forum.
>
> Hey, thanks. Coming from someone who tells people to manually delete keys
> from CCS\Enum, that means a lot.
>

> Hey, thanks. Coming from someone who tells people to manually delete keys

from CCS\Enum, that means a lot.

Hooking is by far worse then manual deletion of CCS\Enum, which is - note
this - recommended for use on test machines only.


Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

Bill: I’m requiring the file be opened with FILE_FLAG_OVERLAPPED because I want some of the device functionality (notifiying user-mode of interrupts and DMA completion) to be accessed asynchronously. This requires FILE_FLAG_OVERLAPPED in the CreateFile call which therefore requires a non-NULL lpOverlapped value to be passed into DeviceIoControl every time. So, I want to fail the IOCTL if the user passes in a NULL to lpOverlapped. This is because DeviceIoControl will allow the NULL, even though its documentation says it “fails in unpredictable ways” (a.k.a. its an invalid thing to do).

Thanks,
Josh

> Bill: I’m requiring the file be opened with FILE_FLAG_OVERLAPPED because I

want some of the device functionality (notifiying user-mode of interrupts and
DMA
completion) to be accessed asynchronously. This requires
FILE_FLAG_OVERLAPPED in the CreateFile

This also allows the use of a separate thread in the app, without
FILE_FLAG_OVERLAPPED.


Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

Maxim: Just to be clear, if a DeviceIoControl was blocked in a thread waiting to be completed, could a DeviceIoControl be called and completed in another thread in the meantime? If so, then I shouldn’t need FILE_FLAG_OVERLAPPED. Unfortunately, I would need to make a special IOCTL to cancel the waiting IOCTLs before closing the device file, which feels kludgy to me. I’ll have to think about it.

Thanks,
Josh

Josh,

If someone tries to close the file, you will get notified of the
IOCTL’s being canceled. You are trying to reinvent the OS here, don’t worry
about it. As was stated early in this discussion, if you are really
concerned make a user mode DLL that provides the interface and don’t have
anyone call the driver directly except that.


Don Burn (MVP, Windows DDK)
Windows 2k/XP/2k3 Filesystem and Driver Consulting
Website: http://www.windrvr.com
Blog: http://msmvps.com/blogs/WinDrvr
Remove StopSpam to reply

wrote in message news:xxxxx@ntdev…
> Maxim: Just to be clear, if a DeviceIoControl was blocked in a thread
> waiting to be completed, could a DeviceIoControl be called and completed
> in another thread in the meantime? If so, then I shouldn’t need
> FILE_FLAG_OVERLAPPED. Unfortunately, I would need to make a special IOCTL
> to cancel the waiting IOCTLs before closing the device file, which feels
> kludgy to me. I’ll have to think about it.
>
> Thanks,
> Josh
>

Don: Since the IOCTLs can be canceled safely as the file closes, just using multiple threads and synchronous calls should work fine for me.

BTW, sorry if I seem ‘slow’, but I’m a relatively new driver developer and I’m still learning. I’m also trying to be careful so that I can get things ‘right’ the first time.

Unfortunately, something is still bugging me. DeviceIoControl allows you to pass in NULL to lpOverlapped when the device file was opened with FILE_FLAG_OVERLAPPED and people have said this is okay (as I quoted from Peter earlier). However, the docs for DeviceIoControl say this fails unpredictably. So, is it ok or might it fail?

Thanks,
Josh

You keep making statements like “Since my device file must be opened with
FILE_FLAG_OVERLAPPED” and those statements indicate that you still do not
understand that this is not a driver issue. Why do you think that your
device must be opened with FILE_FLAG_OVERLAPPED?

What you appear to continue to not understand is that there is no reason for
your driver to do this checking at all. A thread that opens your device in
synchronous mode is not going to force your driver to behave synchronously,
nor is it going to prevent some other thread from opening your device in
asynchronous mode. If your driver processes some IOCTLs by returning
STATUS_PENDING in its dispatch routine and completing the IOCTL at a later
time, that behavior is unchanged regardless of the setting of
FILE_FLAG_OVERLAPPED by the thread that opened the device. Likewise, if your
driver completes some IOCTLs immediately in its dispatch routine, that
processing is synchronous regardless of how the application opened the
device.

The application’s use of FILE_FLAG_OVERLAPPED does not affect your driver’s
processing of IOCTL operations at all.
I don’t think I can beat this dead horse any deader.

On Nov 16, 2007 9:29 AM, wrote:

> Thanks for everyone’s comments. (I didn’t mean to start a fight BTW.) It
> seems I have some misconceptions about how things work.
>
> To explain further what I’m doing, I am using KMDF, and in my
> EvtDeviceCreateFile callback I am checking the file object flags with
> WdfFileObjectGetFlags. If I find FO_SYNCHRONOUS_IO in the flags, I fail the
> creation. This is intended to prevent the device file from being opened
> without FILE_FLAG_OVERLAPPED. (Is this a good way to check?) Since my device
> file must be opened with FILE_FLAG_OVERLAPPED, all DeviceIoControl calls to
> it must use an OVERLAPPED structure (as stated in the DeviceIoControl docs,
> mentioned earlier by Gianluca Varenni). I was hoping to catch a NULL
> lpOverlapped value in the IOCTL handler in an attempt to prevent misuse of
> the driver.
>
> What still confuses me is this: Peter said earlier, “If they try to call
> DeviceIoControl with no OVERLAPPED structure and they’ve opened the handle
> for overlapped I/O then the I/O manager will take care of that for you.”
> Some others have said the same thing. However the DeviceIoControl docs seem
> to contradict this (unless failing in unpredictable ways is ok :-p ). Any
> ideas?
>
> Thanks,
> Josh
>
> —
> 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
>


Mark Roddy

Mark: I’m sorry I haven’t been able to explain things clearly. I completely understand that it doesn’t matter how the IOCTL was called, as far as my driver is concerned. My intention was for the driver to help prevent user errors. The particular error I was trying to prevent was the case of a user calling DeviceIoControl with lpOverlapped set to NULL on a file that was opened with FILE_FLAG_OVERLAPPED. The documentation for DeviceIoControl says that this fails unpredictably. Others have said this is ok. I’m trying to find out which one is true.

Thanks for your patience,
Josh

> Maxim: Just to be clear, if a DeviceIoControl was blocked in a thread waiting
to

be completed, could a DeviceIoControl be called and completed in another
thread
in the meantime?

Blocked DeviceIoControl means (if the driver is written properly) -
non-overlapped file object.

Open another file object - and call the second DeviceIoControl.


Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

> Unfortunately, something is still bugging me. DeviceIoControl allows you to
pass

in NULL to lpOverlapped when the device file was opened with
FILE_FLAG_OVERLAPPED

Try this. I have major doubts this is possible, and the docs are on my side.


Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

> your driver to do this checking at all. A thread that opens your device in

synchronous mode is not going to force your driver to behave synchronously,
nor is it going to prevent some other thread from opening your device in
asynchronous mode.

Yes, but the file object created without _OVERLAPPED serializes all threads
trying to do IO on it using a mutex-like lock. So, you cannot have more then 1
outstanding IRP a time on such a sync file object.

Once I had a task to write a multithreaded service which will read some file
from many threads. Regardless of the fact I do not need any async IO at all, I
was forced by the above thing to use an overlapped file object, with the
nuisance of GetOverlappedResult. The only other solution was to create a file
object per thread.


Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

xxxxx@rtd.com wrote:

Unfortunately, I would need to make a special IOCTL to cancel the waiting IOCTLs before closing the device file, which feels kludgy to me. I’ll have to think about it.

The OS has an I/O cancellation mechanism which works (provided you
implement cancellation correctly in your driver). I believe that later
versions of the Win32 API export some functions to cancel some/all I/O
on a handle.

Regardless, When a thread quits, all asynchronous I/O that it might have
been doing is cancelled. If that thread is blocked on I/O synchronously,
then preferable solutions to implementing a “Wakeup IoCtl” are:

  1. Using the Win32 API to cancel I/O on the handle before closing - this
    is nice, because it means that the driver uses exactly the same cleanup
    mechanisms between unblocking the app and handling (for example) a
    thread or application crash or unusual termination.
  2. Writing a user mode wrapper which does the blocking, but in an
    alertable fashion.

MH.

Thanks for the comments.

Maxim: I have tried it and I was using it for weeks without seeing any problems. (On W2K, btw.) That’s partly why I’m so confused. :-p

Thanks,
Josh

xxxxx@rtd.com wrote:

Bill: I’m requiring the file be opened with FILE_FLAG_OVERLAPPED because I want some of the device functionality (notifiying user-mode of interrupts and DMA completion) to be accessed asynchronously.

This is not a decision that you should be making. Your driver should
not establish policy. There are several ways to implement simultaneous
I/O without using an OVERLAPPED. For example, in some cases it can be
easier to write an application to open multiple instances of a driver
and issue I/O requests on multiple handles.

You’ve heard the same thing many times in the past couple of days. What
you are doing is NOT RIGHT. Stop it. Offer your services as you need
to, and let the applications decide the policy.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

It is not the driver’s role to make sure the app is implemented correctly. What you are doing is violating a couple of layers of abstraction and trying to enforce policy at too low a level. In the end, it will become brittle and buggy and the next poor soul who takes over the driver will probably yank all of this out in the name of simplicity and sanitfy.

OTOH, it is the driver’s role to be resilient to a misbehaving/non responsive UM application. How the application sends i/o wrt to async or sync is not a part of this resiliency. Think of it this way, if it were something drivers should do, you would see other drivers doing it, there would be a WDK sample showing you how and KMDF would have probably wrapped it in a layer of abstraction.

d

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@rtd.com
Sent: Friday, November 16, 2007 8:55 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Guarantee OVERLAPPED structure from user’s DeviceIoControl

Mark: I’m sorry I haven’t been able to explain things clearly. I completely understand that it doesn’t matter how the IOCTL was called, as far as my driver is concerned. My intention was for the driver to help prevent user errors. The particular error I was trying to prevent was the case of a user calling DeviceIoControl with lpOverlapped set to NULL on a file that was opened with FILE_FLAG_OVERLAPPED. The documentation for DeviceIoControl says that this fails unpredictably. Others have said this is ok. I’m trying to find out which one is true.

Thanks for your patience,
Josh


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

xxxxx@rtd.com wrote:

Unfortunately, something is still bugging me. DeviceIoControl allows you to pass in NULL to lpOverlapped when the device file was opened with FILE_FLAG_OVERLAPPED and people have said this is okay (as I quoted from Peter earlier). However, the docs for DeviceIoControl say this fails unpredictably. So, is it ok or might it fail?

Yes, your last sentence is exactly right.

The behavior is not defined. It might fail unpredictably. It might
work. Many people say it does work. That just means they haven’t yet
encountered the circumstance where it might fail.

You have to judge your own comfort level with that. For me, I would
never rely on such a thing.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Do you know where the unpredictable fails coming from, in your scenario?
What if the failure occurs before even your driver’s IOCTL even get a chance
to handle it ?

-pro
----- Original Message -----
From:
To: “Windows System Software Devs Interest List”
Sent: Friday, November 16, 2007 8:54 AM
Subject: RE:[ntdev] Guarantee OVERLAPPED structure from user’s
DeviceIoControl

> Mark: I’m sorry I haven’t been able to explain things clearly. I
> completely understand that it doesn’t matter how the IOCTL was called, as
> far as my driver is concerned. My intention was for the driver to help
> prevent user errors. The particular error I was trying to prevent was the
> case of a user calling DeviceIoControl with lpOverlapped set to NULL on a
> file that was opened with FILE_FLAG_OVERLAPPED. The documentation for
> DeviceIoControl says that this fails unpredictably. Others have said this
> is ok. I’m trying to find out which one is true.
>
> Thanks for your patience,
> Josh
>
> —
> 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