Chapter 4 NDIS Driver Lower-Edge Functions

This describes, in alphabetic order, the system-defined functions implemented in NDIS drivers layered immediately above any driver that exports a set of NDIS upper-edge (MiniportXxx) functions.

Two types of NDIS drivers have the functions described here:

  1. NDIS transport protocols that export a set of the ProtocolXxx functions described here and communicate with their clients through the TDI interface described later in Part 2.

  2. NDIS intermediate drivers that export the ProtocolXxx functions described here, along with a set of the MiniportXxx functions, described earlier in Chapter 1.

    Intermediate NDIS drivers appear to be NIC miniports to higher-level NDIS drivers that layered themselves above such an intermediate driver by establishing a binding. Intermediate NDIS drivers appear to be protocols to the NDIS drivers below them, including NIC drivers. To the NDIS library, such an intermediate driver appears to be both a protocol and a miniport driver.

Driver Function Names

All NDIS driver functions with the prefix Protocol have been given metanames describing their respective basic functionality in the references that follow.

Except for the DriverEntry function, NDIS-defined driver functions can have any name the driver writer chooses. For easy debugging, most system-supplied protocols simply substitute a driver-specific prefix for the Protocol prefix used in this documentation.

The initial entry point of any Windows NT kernel-mode driver has the explicit name DriverEntry in order to be loaded automatically by the system. For more information about the general requirements for and functionality of Windows NT DriverEntry routines, see also the Kernel-Mode Driver Design Guide.

Calling NdisXxx Functions at Appropriate IRQLs

NDIS lower-edge driver functions run, by default, at one of the following IRQLs, shown in order of increasing priority:

PASSIVE_LEVEL < DISPATCH_LEVEL.

Any driver function running at IRQL PASSIVE_LEVEL can be pre-empted by a thread of execution running at a higher priority IRQL. That is, every ProtocolXxx function can be pre-empted by device drivers’ ISRs that run at DIRQL when interrupts occur or by a system clock interrupt.

Each of the following DriverEntry and ProtocolXxx descriptions specifies the default IRQL at which that function runs. The default IRQLs of certain ProtocolXxx functions effectively restrict the set of NdisXxx functions that these ProtocolXxx can call. For example, a call to NdisCopyBuffer from a ProtocolXxx function that runs at IRQL DISPATCH_LEVEL or while the ProtocolXxx is holding a spin lock can cause a fatal page fault.

Initialization-Only and Pageable Driver Code

NDIS protocols mark their DriverEntry functions as initialization-only code, using the NDIS_INIT_FUNCTION macro.

Other driver functions can be marked as pageable code, using the NDIS_PAGABLE_FUNCTION macro. However, a driver function can be pageable code if and only if it never runs at IRQL >= DISPATCH_LEVEL. This restriction implies the following:

Most of the ProtocolXxx functions described here except ProtocolBindAdapter, ProtocolOpenAdapterComplete, ProtocolUnbindAdapter, and ProtocolCloseAdapterComplete run, by default, at IRQL DISPATCH_LEVEL.