1.1.1.1 Registering an Intermediate Driver as a Miniport

An intermediate driver calls one of the two registration routines to export its MiniportXxx functions.

NdisIMRegisterLayeredMiniport is declared as follows:

NDIS_STATUS
    NdisIMRegisterLayeredMiniport(
        IN NDIS_HANDLE
    NdisWrapperHandle,
        IN PNDIS_MINIPORT_CHARACTERISTICS
MiniportCharacteristics,
        IN UINT
    CharacteristicsLength,
        OUT PNDIS_HANDLE
    DriverHandle
        );

The DriverHandle returned by NdisIMRegisterLayeredMiniport must be retained by the intermediate driver and input to NDIS when the driver calls NdisIMInitializeDeviceInstance to request a call to the intermediate driver’s MiniportInitialize function, which then initializes a virtual NIC. An intermediate driver calls NdisIMInitializeDeviceInstance after it either has successfully bound to one or more underlying NIC drivers or has layered itself above the driver of a nonNIC device so the intermediate driver is ready to initialize its miniport component to accept I/O requests on its virtual NIC.

The call to NdisMRegisterMiniport is almost identical except for the DriverHandle parameter, which is specific to NdisIMRegisterLayeredMiniport.

NDIS_STATUS
    NdisMRegisterMiniport(
        IN NDIS_HANDLE
    NdisWrapperHandle,
        IN PNDIS_MINIPORT_CHARACTERISTICS
MiniportCharacteristics,
        IN UINT
    CharacteristicsLength
        );

NdisWrapperHandle was returned by a previous call to NdisMInitializeWrapper.

The intermediate driver must:

  1. Zero-initialize a structure of type NDIS_MINIPORT_CHARACTERISTICS with NdisZeroMemory.

  2. Store the addresses of the mandatory MiniportXxx functions as well as any optional MiniportXxx functions the driver exports. Any other MiniportXxx entry points must be set to NULL.

While valid major versions are 0x03 or 0x04 for other types of NDIS drivers, an intermediate driver must provide a major version of 4.0 and provide a version 4.0 MiniportCharacteristics structure no matter whether it calls NdisIMRegisterLayeredMiniport or NdisMRegisterMiniport and whether it exports any new-for-V4.0 MiniportXxx functions.

The following entries in MiniportCharacteristics must be set to a valid MiniportXxx function address or NULL:

HaltHandler
This function is called by NDIS, for instance, if the underlying NIC has timed out and NDIS has halted the NIC driver or perhaps because the operating system is performing a controlled shutdown of the system.
InitializeHandler
This function is called as a result of the intermediate driver calling NdisIMInitializeDeviceInstance to initialize its miniport operations for the virtual NIC being initialized, or in the context of the call to NdisMRegisterMiniport.
QueryInformationHandler
This function receives OID_XXX requests originating from or passed through by an overlying driver that has called NdisRequest with a request type of NdisRequestQueryInformation.
ResetHandler
NDIS can call an intermediate driver’s MiniportReset function at the behest of a higher-level protocol driver that has called NdisReset. Typically, however, a protocol driver does not initiate resets. Generally, NDIS initiates a reset of an underlying NIC driver and calls an intermediate driver’s ProtocolStatus and ProtocolStatusComplete function to inform such an intermediate driver that the underlying miniport is resetting its NIC.
SetInformationHandler
This function processes OID_XXX requests made by or passed through an overlying driver that has called NdisRequest with a request type of NdisRequestSetInformation.
SendHandler
NDIS calls this function to transmit a single packet to the underlying NIC (or device) driver. A MiniportSend function (or a MiniportWanSend function) is required if the intermediate driver does not supply a MiniportSendPackets function. A MiniportSendPackets function should always be provided at SendPacketsHandler, rather than this handler, unless the intermediate driver will always be layered between drivers that transmit a single packet at a time or will bind itself to underlying WAN NIC driver(s). See Section 1.6 for more discussion of this topic.
SendPacketsHandler
This function receives an array of one or more pointers to packet descriptors specifying packets for transmission over the network. Every intermediate driver should supply a MiniportSendPackets function, rather than supplying a MiniportSend function, unless the intermediate driver will bind itself to underlying WAN NIC driver(s) and must supply a MiniportWanSend function. Otherwise, a MiniportSendPackets function provides the best performance whether the intermediate driver is layered over a NIC driver that can transmit several packets at a time or only one packet at a time and whether it is layered under a protocol driver that sends one packet at a time or several packets at a time. See Section 1.6 for a more complete discussion.
TransferDataHandler
This function is called to transfer the remaining part of a received packet that was not previously indicated up in the lookahead buffer passed by the intermediate driver to NdisMXxxIndicateReceive. This indicated packet can be a converted packet previously received at the intermediate driver’s ProtocolReceive function or ProtocolReceivePacket handler. This handler is required if the intermediate driver indicates received packets to its overlying driver by calling any medium-specific NdisMXxxIndicateReceive function except for NdisMWanIndicateReceive. If the intermediate driver always indicates packets to the overlying driver by calling NdisMIndicateReceivePacket it need not provide a MiniportTransferData function.
ReturnPacketHandler
This function receives a returned packet descriptor that was previously indicated to a higher level driver by calling NdisMIndicateReceivePacket, thereby relinquishing control of the resources indicated to the higher level driver. After each such indication is consumed by the higher level driver, the intermediate-allocated packet descriptor and the resources it describes will be returned to the MiniportReturnPacket function. A MiniportReturnPacket function is not supplied if the intermediate driver always indicates packets up by calling a medium-specific NdisMXxxIndicateReceive function or if it always sets the status in the OOB data block associated with each packet descriptor to NDIS_STATUS_RESOURCES before calling NdisMIndicateReceivePacket.
CheckForHangHandler
This function is called at an NDIS-determined or, alternatively, at an intermediate-driver-determined interval. If supplied, the MiniportCheckForHang function is called every 2 (or at a driver-requested interval) seconds. See the Network Driver Reference for more information about the MiniportCheckForHang function or Part 2 of this manual. Generally, an NDIS intermediate driver does not provide a MiniportCheckForHang function because such a driver has no way to determine if an underlying NIC is hung. An intermediate driver probably would provide this handler if it was layered over a non-NDIS driver whose state is inaccessible to NDIS.

The following miniport handler functions are never supplied by an intermediate driver, because such drivers do not manage interrupting devices, do not allocate buffers at raised IRQL, or in the case of the ReconfigureHandler, because NDIS currently does not call a MiniportReconfigure function: