Sending Network Data
The following figure illustrates a basic send operation, which involves a protocol driver, NDIS, and a miniport driver.
Protocol drivers call the NdisSendNetBufferLists function to send NET_BUFFER_LIST structures on a binding. NDIS calls the miniport driver's MiniportSendNetBufferLists function to forward the NET_BUFFER_LIST structures to an underlying miniport driver.
All NET_BUFFER-based send operations are asynchronous. The miniport driver calls the NdisMSendNetBufferListsComplete function with an appropriate status code when it is done. The sending of each NET_BUFFER_LIST structure can be completed individually. NDIS calls the protocol driver's ProtocolSendNetBufferListsComplete function each time the miniport driver calls NdisMSendNetBufferListsComplete.
Protocol drivers can reclaim the ownership of the NET_BUFFER_LIST structures and all associated structures and data as soon as the NDIS calls the protocol driver's ProtocolSendNetBufferListsComplete function.
The miniport driver or NDIS can return the NET_BUFFER_LIST structures in any order. Protocol drivers are guaranteed that the list of NET_BUFFER structures attached to each NET_BUFFER_LIST structure has not been modified.
Any NDIS driver can separate the NET_BUFFER structures in a NET_BUFFER_LIST structure. Any NDIS driver can also separate the MDLs in a NET_BUFFER structure. However, the driver must always return the NET_BUFFER_LIST structures with the NET_BUFFER structures and MDLs in the original form. For example, an intermediate driver might separate a NET_BUFFER_LIST into two new NET_BUFFER_LIST structures and pass on part of the original data to the next driver. However, when the intermediate driver completes the processing of the original NET_BUFFER_LIST it must return the complete NET_BUFFER_LIST with the original NET_BUFFER structures and MDLs.
Protocol drivers set the SourceHandle member in the NET_BUFFER_LIST structure to the NdisBindingHandle that NDIS provided in a call to the NdisOpenAdapterEx function. NDIS uses the SourceHandle member to return the NET_BUFFER_LIST structures to the protocol driver that sent the NET_BUFFER_LIST structures.
Intermediate drivers also set the SourceHandle member in the NET_BUFFER_LIST structure to the NdisBindingHandle value that NDIS provided in a call to NdisOpenAdapterEx. If an intermediate driver forwards a send request, the driver must save the SourceHandle value that the overlying driver provided before it writes to the SourceHandle member. When NDIS returns a forwarded NET_BUFFER_LIST structure to the intermediate driver, the intermediate driver must restore the SourceHandle that it saved.