as the Dpc parameter. This fact could be used in DPC processing, if necessary. For example, for IRP cancelling and time-outs, there is no need to provide a priority boost for the IRP.
Listing 17.5 WdmIo time-out routines
VOID Timeout1s(IN PDEVICE_OBJECT fdo, IN PWDMIO_DEVICE_EXTENSION dx) {
if (dx->Timeout==-1) return;
DebugPrint('Timeout1s: Timeout is %d' ,dx->Timeout);
PIRP Irp = fdo->CurrentIrp;
if (Irp->Cancel ||
KeSynchronizeExecution(dx->InterruptObject, (PKSYNCHRONIZE_ROUTINE)Timeout1sSynch, dx))
WdmIoDpcForIsr(NULL, fdo, fdo->CurrentIrp, dx);
}
static BOOLEAN Timeout1sSync(IN PWDMIO_DEVICE_EXTENSION dx) {
if (dx->Timeout==-1 || –dx->Timeout>0) return FALSE;
dx->Timeout = –2;
dx->TxStatus = STATUS_NO_MEDIA_IN_DEVICE; // Win32: ERROR_NOT_READY
return TRUE;
}
Custom timers may be used if you want timer resolutions other than one second. You can detect when the timer goes off in two ways. Either use a Custom DPC callback, or wait for the timer object to become signalled.
NT 3.51 timers are one-shot only. NT 4, W2000, and WDM drivers can use periodic timers. Declare a KTIMER field in nonpaged memory (e.g., in your device extension), and initialize it with
Use
You can cancel a timer using
A custom DPC routine may used as the timer callback. Initialize a custom DPC as described previously. Pass the KDPC pointer to KeSetTimer or KeSetTimerEx.
System threads can wait for a timer to go off using the
Conclusion
This chapter has looked at how to write interrupt service routines. Any nonessential processing is best done in a Deferred Procedure Call (DPC) routine at a lower IRQL. A basic one-second interval timer can be used to detect device time-outs. Custom timers can be used with Custom DPCs to receive notification of other time-out periods.
Chapter 18
NT Hardware
This chapter looks at how to find, allocate, and use hardware resources in non-WDM drivers that do not support Plug and Play. I call these 'NT style' drivers because they run in NT 3.51, NT 4, and Windows 2000. These drivers sometimes also work in Windows 98, slightly to my surprise.
I have already shown how to use the translated hardware resource assignments in the last two chapters. The WdmIo and PHDIo drivers use
An NT style driver has three jobs to do to obtain its translated hardware resources.
1. Find its device's raw resource requirements.
2. Allocate these raw resources: check for conflicts with existing devices and reserve the resources so that other new devices cannot use them.
3. Translate the raw resource information.
The PHDIo driver receives its resource requirements from the Win32 application. The filename passed in the Create IRP specifies the I/O port details and optionally the Interrupt IRQ number. PHDIo can currently only accept ISA resource details.
This chapter shows how PHDIo allocates its raw resources and translates them. At the end of the chapter, I look at how NT and W2000 find various devices and make the resource information available to drivers.
First, I look at how to build and structure an NT style driver.
NT Style Driver Construction
An NT style driver is built in a slightly different way from a WDM driver. It also has none of the Plug and Play infrastructure to support.
You must build an NT style driver in Windows 2000 or NT 4. The Windows 2000 DDK or NT 4 DDK must be installed as appropriate. If you alter an NT style driver, you must reboot Windows 98 to use the changed driver.
It is possible that crucial kernel structures have been changed between NT 4 and W2000, so it is safest to have one NT 4/NT 3.51 version of your driver and one W2000 version. In practice, it seems as though a driver compiled in W2000 using the W2000 DDK works in the NT platforms and Windows 98. I compared the free build driver made by the Windows 2000 Beta DDK with the same build using the NT 4 DDK. Although the files were both the same size, they were not identical.
An NT style driver can support Power Management and Windows Management Instrumentation (WMI), as long as it is only run on Windows 2000 or Windows 98. The major function code for the Power Management IRP, IRP_MJ_POWER, is defined as 0x16 in the W2000 DDK NTDDK.H. IRP_MJ_POWER is not defined in the NT 4 DDK. Instead, the IRP major function code 0x16 is defined as IRP_MJ_QUERY_POWER in NT 4. I am not sure whether this IRP is issued in NT 4. However, it is best if you do not handle IRP_MJ_POWER or IRP_MJ_SYSTEM_CONTROL in a driver installed in NT 4.
An NT style driver must use NTDDK.H as its main header file, rather than WDM.H. In general, this gives the driver access to more facilities than would be available to a WDM device driver. In the SOURCES build file, remove the line that says DRIVERTYPE=WDM.
An NT style driver like PHDIo creates devices in a different way from WDM device drivers. A WDM device driver has an
As a consequence of not using Plug and Play, PHDIo does not deal with PnP device stacks. The device extension does not need to have fields for the Physical Device Object (PDO) or
Instead, PHDIo creates one device in its
Most NT style drivers that need resources find and allocate them in the DriverEntry call. However, PHDIo only receives its resource requirements when a handle is opened to its device. Later in the chapter, I will look at various techniques for finding a driver's resource requirements.
The one PHDIo device is deleted using
Device Creation and Deletion
The PHDIo
Listing 18.1 shows how PHDIo creates its device in