Great set of questions. I will try to answer them one by one.
This brings up one of the things I have always wondered about win32. Why on earth can't you do an overlapped CreateFile? It doesn't sound like this is going to be changing in Vista either.
There are many reasons CreateFile is synchronous. Here is one. All Windows APIs are based on object handles. Windows OS has an underlying object manager which parses names and creates objects. These objects have Create<OBJ> apis that return a handle. For
example, CreateEvent takes an event name, finds the object and returns a handle to that object. CreateFile parses the file name, creates a file object and returns a handle to it. Other APIs then operate on the handles. These APIs (read/write/ioctl) assume
that the Create API has done name parsing, security access control etc. This makes the APIs that operate on the handles fast and efficient. If CreateFile was made asynchronous, we would now have to update all the other APIs that take a file handle and synchronize
that with CreateFile processing. This will complicate and hurt the performance of handle based APIs like ReadFile and WriteFile. After all, program calls Read/Write much more often than Create.
I've *wanted* to use overlapped IO on many occasions, but I've always been very turned off by this omission. Also, why is it that some overlapped IO calls block for hundreds of milliseconds? Shouldn't asynchronous really mean asynchronous?
I agree. When an I/O goes into a driver, the driver can immediately queue the request and return. But if there is a deep driver stack, there is a lot of computation that happens, the code waits for locks etc. These slow things down even if you do asynch
I also have one question about user-mode drivers. You talked a little about how we don't want user-mode drivers to host a GUI, etc. But I wasn't sure if you mean that it is impossible for them to do that. Do user-mode drivers run in win32, or are they
in a separate subsystem?
On Vista, User mode drivers run in a win32 process. They run in the context of session 0. So we don't want them throwing UI etc. For one thing they won't be in the right context.
OK, one more question and I'm done. In general you can only cancel an operation that is sufficiently started, and not sufficiently finished. Those two restrictions lead directly to the two main classes of bugs associated with "cancel" type API calls.
Namely, that you can't be sure you aren't trying to cancel it too early, and that you can't be sure you aren't trying to cancel it too late. The case of trying to cancel it too early can be handled carefully by the application with retries and synchronization,
to avoid turning it into a problem. But I can't see how you can, in general, solve the second class of problem, trying to cancel an operation that has just finished, and accidentally cancelling a different operation. Is this something that you have looked
Both these issues can be handled with sufficient synchronization (albeit tricky). In the driver space, if someone cancels an I/O that's already completed, the cancelation is just ignored. If an application wants to make sure that its canceling only the
I/O it really wants to cancel, it has to track its overlapped I/O blocks and use the correct synchronization. I agree that providing libraries to help with this task would be useful.
There are many scenarios and some of them are given in the "Inside Windows" book. For example, many critical system threads run at real time priorities. Using these priorities require "increase scheduling priority" privilege.
For further details I would recommend the "Inside Windows" book.