3.1.2  Registering Miniport Functions

After DriverEntry has called NdisMInitializeWrapper to create an association with the NDIS library, it must register the miniport’s exported MiniportXxx functions. DriverEntry must allocate, zero-initialize and fill in the members of a structure of type NDIS_MINIPORT_CHARACTERISTICS. NDIS_MINIPORT_CHARACTERISTICS specifies the NDIS version with which the miniport is compatible and the addresses of the required and optional entry points of the upper-edge functions that the miniport provides. The NDIS 4.0 version can be specified with the compiler switch, -DNDIS40_MINIPORTS. Or the version can be set in source files as follows.

#define NDIS40_MINIPORT

This define statement must appear before the #include <ndis.h> statement.

NDIS retains the function addresses to subsequently call the appropriate miniport functions.

Any address member of NDIS_MINIPORT_CHARACTERISTICS must be initialized, that is, set to the address of a miniport-supplied function or to NULL. Valid version numbers are 4.0 or 3.0. The current version is 4.0, although the NDIS library continues to support legacy drivers written for version 3.0. The miniport must supply function addresses for the mandatory entry points or NDIS will unload the driver.

The entry points are passed to NDIS by supplying the symbolic name of the miniport’s functions. These functions are defined in ndis.h and described here as MiniportXxx. Because the miniport supplies the addresses, not the names, of its driver-specific entry points, driver developers are free to name these functions whatever they wish. In this documentation, these functions are given generic names, such as MiniportISR, suggestive of their purpose.

However, the developer can give these functions different names. A reasonable miniport-development strategy is to give these functions names that make debugging easier. For instance, the miniport NIC driver foo.sys could name the entry points FooISR, FooSend, etc.

Some MiniportXxx functions are optional. For instance, if a NIC does not generate interrupts, the miniport must poll the NIC. A miniport that polls does not need a MiniportISR function, a MiniportEnableInterrupt function or a MiniportDisableInterrupt function, but it must have a MiniportTimer function.

The possible entry points in NDIS_MINIPORT_CHARACTERISTICS are shown in the following table. For each entry, the table specifies whether the function is optional or mandatory and the reasons that a miniport might or might not supply a particular optional function.

Table 3.1   Filling in NDIS_MINIPORT_CHARACTERISTICS

Structure Member Required or Optional Reason
CheckForHangHandler Optional If not supplied, the miniport relies on NDIS to determine if the adapter is hung based on sends and requests that timeout.
DisableInterruptHandler Optional If the adapter does not generate an interrupt, this entry point is not required.
EnableInterruptHandler Optional If the adapter does not generate an interrupt, this entry point is not required.
HaltHandler Required
HandleInterruptHandler Optional A miniport will not supply this entry point if its device does not generate interrupts or if the miniport chooses to poll the adapter state with a miniport-supplied timer function.
InitializeHandler Required
ISRHandler Optional A miniport will not supply this entry point if its device  doesn’t interrupt or if it chooses to poll the adapter state with a miniport-supplied timer function.
QueryInformationHandler Required
ReconfigureHandler Not Used
ResetHandler Required
SendHandler Optional Not supplied if a LAN miniport provides a SendPackets handler. A LAN miniport must either provide a SendPacketsHandler or a SendHandler. A WAN miniport must have a WanSendHandler.
SendPacketsHandler Optional Not supplied if a LAN miniport supplies a SendHandler. A LAN miniport must either provide a SendPacketsHandler or a SendHandler. A WAN miniport must have a WanSendHandler.
SetInformationHandler Required
TransferDataHandler Optional Must be supplied if a miniport indicates the initial portions of received network packets in lookahead buffers from which received data is copied by interested upper layers. If a LAN miniport does not have a TransferDataHandler, it must have a ReturnPacketHandler. WAN miniports do not have a TransferDataHandler.
ReturnPacketHandler Optional Must be supplied if a miniport supports multipacket receive indications by calling NdisMIndicateReceivePacket and always indicates full network packets to higher level drivers. If a LAN miniport does not have a ReturnPacketHandler, it must have a TransferDataHandler. A WAN miniport does not have a ReturnPacketHandler.
AllocateCompleteHandler Optional Not supplied if the miniport does not control a busmaster DMA NIC and allocate memory at raised IRQL with NdisMAllocateSharedMemoryAsync.

DriverEntry calls NdisMRegisterMiniport, passing a pointer to its NDIS_MINIPORT_CHARACTERISTICS structure, the size of this structure and the handle returned by NdisMInitializeWrapper that identifies the miniport to NDIS.

NDIS will fail the call if the NDIS version specified in the structure is not a supported version of 4.0 or 3.0 or if the length of the structure does not match the length required for the specified version.

NDIS copies and retains the information passed in the characteristics structure. For instance, NDIS stores the function addresses passed by the miniport and uses these addresses to call the miniport when conditions requiring the attention of the miniport occur.

DriverEntry is the only miniport function that can be specified with the NDIS_INIT_FUNCTION macro. Code marked this way is no longer mapped after the system initialization phase has completed. DriverEntry is called when the miniport is first loaded and will never be called subsequently.

The miniport returns the status of its call to NdisMRegisterMiniport as the return status from DriverEntry.