INFO: How Drivers Notify User-Mode Apps of Asynchronous Events |
The information in this article applies to:
-
Microsoft Win32 Device Driver Kit (DDK) for Windows NT, versions 3.1, 3.5, 3.51, 4.0
-
Microsoft Win32 Device Driver Kit (DDK) Windows 2000
This article discusses a Beta release of a Microsoft
product. The information in this article is provided as-is
and is subject to change without notice.
No formal product support is available from Microsoft for
this Beta product. For information about obtaining support
for a Beta release, please see the documentation included
with the Beta product files, or check the Web location
from which you downloaded the release.
SUMMARY
In Windows NT and Windows 2000, a kernel-mode driver cannot call back into
a user-mode application. This is by design. For a driver to notify the
application for an asynchronous event, the application needs to keep an I/O
request pending with the driver at all times so that the driver can
complete the request each time the event occurs. This article outlines a
typical scheme that an application and a driver can use to accomplish
asynchronous notification.
MORE INFORMATIONThe Application
The application can have a dedicated input thread. The thread goes into a
loop that sends an I/O request and waits for response. If the driver has
been opened and a handle, hDevice, is obtained, the loop can look like the
following:
while (!ApplicationExiting) {
returnval = DeviceIoControl (hDevice, dwIoControlCode,
lpvInBuffer, cbInBuffer, lpvOutBuffer,
cbOutBuffer, lpcbBytesReturned, lpoOverlapped);
if (!returnval && (GetLastError() == ERROR_IO_PENDING)) {
WaitForSingleObject (hEvent, INFINITE) // hEvent is located in
overlapped structure as well
... // Code to do action
ResetEvent (hEvent)
}
{ ... // Code to handle other situations }
}
The BOOL type, ApplicationExiting(), represents the condition for which the
loop should stop checking for events. The main thread of the application
can set this BOOL to TRUE when it is time to quit. The I/O control code,
dwIoControlCode(), is defined by the driver.
The above DeviceIoControl call must be made asynchronously in order for the
other application threads to be able to continue to send requests to the
driver while this request is pending. The event that was initialized and
placed in the overlapped structure of the DeviceIoControl call can be used
to make this thread synchronous with the completion of the request. Once
that event has been satisfied, this thread can notify the other application
threads that the event has signaled. If the overlapped structure is not
specified, all other threads will be blocked while this request is
processed in the driver. The other threads will not be released until the
synchronous DeviceIoControl has been completed.
The user-mode thread can also use ReadFile() or ReadFileEx() instead of
DeviceIoControl() if the driver uses a read request to send in an
asynchronous event notification.
The Driver
The driver should not complete the I/O request until an event has occurred.
When the driver receives the I/O request, if an event has occurred and is
waiting to be sent to the application, the driver can complete the request
in the dispatch routine. If no event is waiting to be reported, the driver
should perform the following steps:
- Mark the Irp pending, using IoMarkIrpPending().
- Set up a cancel routine for the Irp, using IoSetCancelRoutine().
- Put the Irp in a storing place (a queue for example).
- Return STATUS_PENDING from the dispatch routine.
Later, when an event has occurred, the driver can complete the pending
request from its deferred procedure call (DPC) routine. Before the Irp can
be completed, the driver should set the cancel routine address to NULL
using IoSetCancelRoutine.
Keywords : kbNTOS310 kbNTOS350 kbNTOS351 kbNTOS400 kbWinOS2000
Version :
Platform :
Issue type : kbinfo
Technology :
|
|
|
|