[Compuware Corporation] [Compuware NuMega home page]                [NuMega Lab]
[teal]

 [DriverStudio]    [Image][Image]
   Home
 [Driver Products]        Driver Technical Tips
   DriverStudio          How to Control Device Object Reentrancy
   DriverBundle
   Previews              Device Objects are central to the I/O architecture of Windows NT. They provide
   Compatibility         targets for I/O requests (IRPs) from applications and drivers. The driver routines
 [Downloads]             that the system calls to process an IRP are referred to as dispatch routines. A
                          driver may supply a dispatch routine for each type of IRP. In its DriverEntry
 Wizards                  routine, a typical driver initializes the driver objects with pointers to its
   Utilities             dispatch routines. In DriverWorks, member functions of class KDevice play the role
   NT source             of dispatch routines.
 examples
   VxD source            Most devices require some kind of serialization of I/O requests, simply because
 examples                 most devices can only do one thing at a time. If a driver started processing each
   WDM source            IRP as soon as it was received, it would risk interfering with other requests that
 examples                 were already in progress. The most common approach to handle this problem is to
 [Resources]             take advantage of the IRP queue built into each device object. The DDK provides
 Technical papers         services IoMarkPending, IoStartPacket, and IoStartNextPacket to facilitate
   Useful links          serializing of requests through a single entry point, generally named StartIo.
   Technical tips
 [Support]               The StartIo mechanism handles one kind of reentrancy problem, but there are other
                          levels of reentrancy that the driver may control. For example, it is not that
 Support                  unusual for a driver to require that there be only a single application with a
   Knowledge base        single handle open on a particular device object. In other words, a driver may
   Problem               want to restrict device access to one process at a time. A driver could implement
 submission               this by calling InterlockedIncrement to test and set a busy flag in the Create
   Product               handler, but the system will provide the same functionality if the DO_EXCLUSIVE
 registration             flag is set in the device object. If an application successfully opens a device
   Release notes         which has this flag set, then subsequent attempts to open the device will fail
 [Shop NuMega]           with ERROR_ACCESS_DENIED until the original handle is closed. The driver never
 Buy it!                  sees a Create call, because the exclusion is implemented by the system.
   Price list
   How to buy            If you are using DriverWorks, you can set the DO_EXCLUSIVE bit in the flags
   Sales offices         argument of the constructor of class KDevice. If you are using the raw DDK, set
                          parameter Exclusive to TRUE in the call to IoCreateDevice. The effect is that
                          there will never be more than one active file object for the device at any given
 [Y2K Compliance]         time.

                          One might think that if a device object has its DO_EXCLUSIVE bit set, then its
 [More information]       dispatch routines could not be reentered. That's not the case. The single handle
                          to the device could be shared by several threads, each of which is trying to
                          access the device. In this case, the question of whether the dispatch routines may
                          be reentered depends not on the device object, but on the attributes of the file
                          object. If the call to CreateFile that opened the device was made with flag
                          FILE_FLAG_OVERLAPPED, then the system will allow multiple threads to
                          simultaneously enter the device's dispatch routines. However, it the caller of
                          CreateFile does not set FILE_FLAG_OVERLAPPED, then calls to the device on that
                          handle are serialized. It's entirely possible (as long as DO_EXCLUSIVE is not set)
                          that there could be multiple handles open on a device, some of which allowed
                          asynchronous I/O while others did not. Serialization by the system will only occur
                          on handles for which FILE_FLAG_OVERLAPPED was not set. Note that it doesn't matter
                          if the call to ReadFile, WriteFile, or DeviceIoControl passes a non-NULL
                          OVERLAPPED structure or not; the behavior of the handle is determined when the
                          device is opened.

                          A driver that wants to prevent an application from using overlapped I/O can put a
                          check in the Create handler of a device, and fail the call if the overlapped I/O
                          is requested. The logic goes like this (assuming DriverWorks):

                            NTSTATUS MyDevice::Create(KIrp I)
                            {
                                  ULONG CreateOptions = I.CurrentStackLocation()->Parameters.Create.Options;

                                  if ( (CreateOptions & FILE_SYNCHRONOUS_IO_NONALERT) == 0 )
                                  {
                                          // overlapped I/O was requested
                                          return I.Complete(STATUS_INVALID_PARAMETER);
                                  }

                                  . . .

                          In summary, device object flag DO_EXCLUSIVE determines if only one file object for
                          a device may exist at a given time. This ensures that only a single process has
                          access to the device. Independent of the DO_EXCLUSIVE flag is the synchronous
                          attribute of the file object through which an application makes an I/O request.
                          This determines if the system waits for a dispatch routine to return before
                          calling into the device again. Correct usage of these features enables control of
                          the circumstances under which dispatch routines for a device object may be
                          reentered.

                          Back to technical tip start page.

  DriverCentral  DriverStudio  Free downloads  Resources  Support and
                          Services  Shop NuMega
     Compuware NuMega  Tel: +1 603 578-8400  Updated: 9 August 1999 
                      Problems? Contact our webmaster.
