3.7.1 Registering and Enabling an IoTimer Routine

Any NT driver can register an IoTimer routine after it creates one or more device objects by calling IoInitializeTimer when the driver initializes. After the driver has initialized, it can enable the timer by calling IoStartTimer. Figure 3.19 illustrates these calls.

Figure 3.19 Using a Timer Object for an IoTimer Routine

As Figure 3.19 shows, the driver calls IoInitializeTimer with the entry point of its IoTimer routine and pointers to a driver-created device object and TimerContext area in which the driver maintains whatever context its IoTimer routine uses. The I/O Manager associates the device object with a Kernel timer object, which the I/O Manager sets up to time out every second.

After the driver calls IoStartTimer, its IoTimer routine is called once per second until the driver calls IoStopTimer. An NT driver can re-enable calls to its IoTimer routine with IoStartTimer.

On entry, the IoTimer routine is given DeviceObject and Context pointers to the associated device object and TimerContext area that was set up when the driver called IoInitializeTimer.

Because an IoTimer routine is run at IRQL DISPATCH_LEVEL, its TimerContext area must be in resident, system-space memory. Most NT drivers that have IoTimer routines use the DeviceObject->DeviceExtension of the associated device object as such a Context-accessible area, but it can be in a controller extension if the driver uses a controller object (see Section 3.4) or in nonpaged pool allocated by the driver.

    Driver writers who implement an IoTimer routine should follow these guidelines concerning the TimerContext area:

For more information about the functionality required of an IoTimer routine, see Chapter 14.