You are currently offline, waiting for your internet to reconnect

INFO: How Drivers Notify User-Mode Apps of Asynchronous Events

This article was previously published under Q117308
In Windows NT and Windows 2000, a kernel-mode driver cannot call back intoa user-mode application. This is by design. For a driver to notify theapplication for an asynchronous event, the application needs to keep an I/Orequest pending with the driver at all times so that the driver cancomplete the request each time the event occurs. This article outlines atypical scheme that an application and a driver can use to accomplishasynchronous notification.

The Application

The application can have a dedicated input thread. The thread goes into aloop that sends an I/O request and waits for response. If the driver hasbeen opened and a handle, hDevice, is obtained, the loop can look like thefollowing:
   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 theloop should stop checking for events. The main thread of the applicationcan 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 theother application threads to be able to continue to send requests to thedriver while this request is pending. The event that was initialized andplaced in the overlapped structure of the DeviceIoControl call can be usedto make this thread synchronous with the completion of the request. Oncethat event has been satisfied, this thread can notify the other applicationthreads that the event has signaled. If the overlapped structure is notspecified, all other threads will be blocked while this request isprocessed in the driver. The other threads will not be released until thesynchronous DeviceIoControl has been completed.

The user-mode thread can also use ReadFile() or ReadFileEx() instead ofDeviceIoControl() if the driver uses a read request to send in anasynchronous 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 iswaiting to be sent to the application, the driver can complete the requestin the dispatch routine. If no event is waiting to be reported, the drivershould perform the following steps:

  1. Mark the Irp pending, using IoMarkIrpPending().
  2. Set up a cancel routine for the Irp, using IoSetCancelRoutine().
  3. Put the Irp in a storing place (a queue for example).
  4. Return STATUS_PENDING from the dispatch routine.
Later, when an event has occurred, the driver can complete the pendingrequest from its deferred procedure call (DPC) routine. Before the Irp canbe completed, the driver should set the cancel routine address to NULLusing IoSetCancelRoutine.

Article ID: 117308 - Last Review: 05/24/2004 16:52:00 - Revision: 3.1

  • Microsoft Win32 Device Driver Kit for Windows NT 3.5
  • Microsoft Win32 Device Driver Kit for Windows NT 3.5
  • Microsoft Win32 Device Driver Kit for Windows NT 3.51
  • Microsoft Win32 Device Driver Kit for Windows NT 4.0
  • Microsoft Win32 Device Driver Kit for Windows 2000
  • kbinfo KB117308