This problem is a classic problem for most people who learn the intermediate NDIS layer.
When asked on the Forum, others will only tell you the approximate method and steps. Here we post the specific code, hoping to help the buddies who study the NDIS middle layer:
Ndis_status
Mysendpacket (
Ndis_handle ndisbindinghandle,
Ndis_handle ndissendpacketpool,
Pvoid pbuffer,
Ulong dwbufferlength
)
{
Ndis_status status;
Pndis_packet psendpacket = NULL;
Pndis_buffer psendpacketbuffer = NULL;
Puchar psendbuffer = NULL;
Ulong dwsendbufferlength;
Ndis_physical_address highestacceptableaddress;
Psend_rsvd sendrsvd = NULL;
If (! Ndisbindinghandle)
Return ndis_status_failure;
If (! Pbuffer)
Return ndis_status_failure;
If (dwbufferlength> eth_max_packet_size)
Return ndis_status_failure;
Highestacceptableaddress. quadpart =-1;
Dwsendbufferlength = max (dwbufferlength, eth_min_packet_size );
Status = ndisallocatememory (& psendbuffer, dwsendbufferlength, 0, highestacceptableaddress );
If (status! = Ndis_status_success)
{
Return status;
}
Rtlzeromemory (psendbuffer, dwsendbufferlength );
Rtlmovememory (psendbuffer, pbuffer, dwsendbufferlength );
Ndisallocatepacket (& status, & psendpacket, ndissendpacketpool );
If (status! = Ndis_status_success)
{
Ndisfreememory (psendbuffer, dwsendbufferlength, 0 );
Return status;
}
Ndisallocatebuffer (& status,
& Psendpacketbuffer,
Ndissendpacketpool,
Psendbuffer,
Dwsendbufferlength );
If (status! = Ndis_status_success)
{
Ndisfreememory (psendbuffer, dwsendbufferlength, 0 );
Ndisdprfreepacket (psendpacket );
Return status;
}
Ndischainbufferatfront (psendpacket, psendpacketbuffer );
Sendrsvd = (psend_rsvd) (psendpacket-> protocolreserved );
Sendrsvd-> originalpkt = NULL; // note the following:
Psendpacket-> private. Head-> next = NULL;
Psendpacket-> private. Tail = NULL;
// Ndis_set_packet_header_size (psendpacket, 14 );
Ndissetpacketflags (psendpacket, ndis_flags_dont_loopback );
Ndissend (& status, ndisbindinghandle, psendpacket );
If (status! = Status_pending)
{
Ndisunchainbufferatfront (psendpacket, & psendpacketbuffer );
Ndisquerybuffersafe (psendpacketbuffer,
(Pvoid *) & psendbuffer,
& Dwsendbufferlength,
Highpagepriority );
Ndisfreebuffer (psendpacketbuffer );
Ndisfreememory (psendbuffer, dwsendbufferlength, 0 );
Ndisdprfreepacket (psendpacket );
}
Return status;
}
NOTE: If ndissend is completed immediately without pending, you need to release the allocated resources after ndissend returns. Otherwise, if it is pending, we need to release the allocated resources in the complete routine after the package event is actually completed.
In the ptsendcomplete function:
Psend_rsvd sendrsvd;
Sendrsvd = (psend_rsvd) (packet-> protocolreserved );
Pkt = sendrsvd-> originalpkt;
// Protocolreserved is a place where you can store your own data. passthru uses this address to store the original package, while we set sendrsvd> originalpkt to null when constructing our own package, therefore, it is easy to determine which of the packages that have been sent is passtru.
If (! Pkt)
{
Ndisunchainbufferatfront (packet, & pmysendpacketbuffer );
If (pmysendpacketbuffer)
{
Ndisquerybuffersafe (pmysendpacketbuffer,
(Pvoid *) & pmysendbuffer,
& Dwmysendbufferlength,
Highpagepriority );
If (pmysendbuffer & dwmysendbufferlength)
{
Ndisfreememory (pmysendbuffer, dwmysendbufferlength, 0 );
}
Ndisfreebuffer (pmysendpacketbuffer );
}
Ndisdprfreepacket (packet );
This article from the csdn blog, reproduced please indicate the source: http://blog.csdn.net/floweronwarmbed/archive/2008/11/01/3202065.aspx