W_SEND_HANDLER callback function

Note   NDIS 5. x has been deprecated and is superseded by NDIS 6. x. For new NDIS driver development, see Network Drivers Starting with Windows Vista. For information about porting NDIS 5. x drivers to NDIS 6. x, see Porting NDIS 5.x Drivers to NDIS 6.0.

The MiniportSend function is required for drivers that do not have a MiniportSendPackets, MiniportWanSend, or MiniportCoSendPackets function. MiniportSend transfers a protocol-supplied packet over the network.


W_SEND_HANDLER MiniportSend;

NDIS_STATUS MiniportSend(
  _In_ NDIS_HANDLE  MiniportAdapterContext,
  _In_ PNDIS_PACKET Packet,
  _In_ UINT         Flags
{ ... }


  • MiniportAdapterContext [in]
    Specifies the handle to a miniport driver-allocated context area in which the driver maintains per-NIC state, set up by MiniportInitialize.

  • Packet [in]
    Pointer to a packet descriptor specifying the data to be transmitted.

  • Flags [in]
    Specifies the packet flags, if any, set by the protocol.

Return value

MiniportSend can return any of the following:

Return code Description

The driver (or its NIC) has accepted the packet data for transmission, so MiniportSend is returning the packet, which NDIS will return to the protocol.


The driver will complete the packet asynchronously with a call to NdisMSendComplete.


The driver (or NIC) currently has insufficient resources available to process the given packet so NDIS should queue the send packet for a resubmission when the driver next calls NdisMSendResourcesAvailable or NdisMSendComplete.

If a deserialized miniport driver returns NDIS_STATUS_RESOURCES from its MiniportSend function, NDIS returns the given packet back to the protocol with an error status.


The NIC has failed the send operation because the network cable is disconnected from the NIC.


The NIC has failed the send operation because the NIC is resetting.


The given packet was invalid or unacceptable to the NIC. MiniportSend should return NDIS_STATUS_FAILURE only if there is no NDIS_STATUS_XXX value that adequately describes the failure. Preferably, MiniportSend should return an NDIS_STATUS_XXX value that indicates the specific cause of the failure.



If a driver registers both MiniportSend and MiniportSendPackets functions when it initializes, its MiniportSend function is never called by NDIS.

MiniportSend can safely access the packet and all buffer descriptors chained to the packet until the given packet is complete. If MiniportSend returns a status other than NDIS_STATUS_PENDING or, from a serialized driver NDIS_STATUS_RESOURCES, the request is considered complete and ownership of the packet descriptor and all memory associated with the packet reverts to the allocating protocol.

If the MiniportSend function of a deserialized driver returns NDIS_STATUS_RESOURCES, the request is also considered complete. Such a deserialized driver's MiniportSend function should queue the given packet internally if the driver currently has insufficient resources to transmit it and the packet is valid. In these circumstances, MiniportSend should return NDIS_STATUS_PENDING for the packet it queued and call NdisMSendComplete subsequently when it has transmitted the packet. A deserialized miniport driver cannot call NdisMSendResourcesAvailable.

If MiniportSend returns NDIS_STATUS_PENDING, the driver subsequently must signal completion of the request by calling NdisMSendComplete. When MiniportSend returns NDIS_STATUS_RESOURCES, the NDIS library reflects this status to the protocol as NDIS_STATUS_PENDING if the driver is serialized.

When a serialized driver returns a packet with NDIS_STATUS_RESOURCES, the next packet submitted to its MiniportSend function is the same packet it just returned to NDIS. Consequently, MiniportSend can optimize by retaining information about such a returned packet if the driver currently has sufficient resources to store the information. NDIS assumes MiniportSend is ready to accept that packet as soon as the serialized driver calls NdisMSendResourcesAvailable or NdisMSendComplete, whichever occurs first.

Each protocol driver must pass packet descriptors to NdisSend that are fully set up to be passed by the underlying driver's MiniportSend function to its NIC. That is, the protocol is responsible for determining what is required, based on the medium type selected by the miniport driver to which the protocol bound itself. However, a protocol can supply net packets mapped by the chained buffer descriptors that are shorter than the minimum for the selected medium, which MiniportSend must pad if its medium imposes a minimum-length requirement on transmits.

Any NDIS intermediate driver that layers itself between a higher-level protocol and an underlying NIC driver has the same responsibility as any protocol driver to set up packets according to the requirements of the underlying miniport driver and its selected medium. Such an intermediate driver must repackage each incoming send packet in a fresh packet descriptor that was allocated by the intermediate driver.

MiniportSend can use only the eight-byte area at MiniportReserved within the NDIS_PACKET structure for its own purposes. Consequently, an NDIS intermediate driver that forwards send requests to an underlying NIC driver must repackage the packets input to its MiniportSend function in fresh packet descriptors, which the intermediate driver allocates from packet pool, so that the underlying miniport driver has a MiniportReserved area it can use.

MiniportSend can call NdisQueryPacket to extract information, such as the number of buffer descriptors chained to the packet and the total size in bytes of the requested transfer. It can call NdisGetFirstBufferFromPacketSafe, NdisGetFirstBufferFromPacket, NdisQueryBuffer, NdisQueryBufferSafe, or NdisQueryBufferOffset to extract information about individual buffers containing the data to be transmitted.

The Flags parameter can provide information about a send that is not contained in the packet data itself. Currently, there are no system-defined flags, but a pair of closely coupled protocol and miniport drivers can pass information in this parameter, which MiniportSend can retrieve with NdisGetPacketFlags. However, such a pair of drivers can communicate more information, such as timestamps and packet priority, in the NDIS_PACKET_OOB_DATA block associated with each packet descriptor.

If the underlying driver's MiniportQueryInformation function set the NDIS_MAC_OPTION_NO_LOOPBACK flag when the NDIS library queried the OID_GEN_MAC_OPTIONS, the miniport driver must not attempt to loop back any packets. The NDIS library provides software loopback support for such a driver.

MiniportSend can be preempted by an interrupt.

The MiniportSend function of a deserialized miniport driver can be called at any IRQL <= DISPATCH_LEVEL. The MiniportSend function of a deserialized driver is responsible for synchronizing access to its internal queues of packet descriptors with the driver's other MiniportXxx functions that also access the same queues.

The MiniportSend function of a serialized miniport driver runs at IRQL = DISPATCH_LEVEL.


Target platform



Not supported for NDIS 6.0 drivers in Windows Vista. Use MiniportSendNetBufferLists instead. Supported for NDIS 5.1 drivers in Windows Vista and Microsoft Windows XP. Use MiniportSendPackets instead.


Ndis.h (include Ndis.h)


<= DISPATCH_LEVEL (see Remarks section)

See also






























Send comments about this topic to Microsoft