The relationship between NdisSend() and NdisMSendComplete()

Discussion in 'Windows Vista Drivers' started by Liang Chen, Aug 17, 2005.

  1. Liang Chen

    Liang Chen Guest

    Hi all,

    I learnd from the passthru sample than it is required in NDIS to acknowledge
    the successful sending operations by NdisMSendComplete(). However, I need
    the futhurmore expertise to cover my trick modified from the original
    passthru sample.

    It is supposed that there are 2 adapters binding to the passthru, NIC1 and
    NIC2. In my design, I expecte every downlink packet, either from the NIC1 or
    NIC2, will be forwarded to the NIC2's miniport.

    For example, if a packet is sent from the NIC1 to passthru via
    MPSendPackets(), the passthru transfers the packet to NIC2 by calling
    NdisSend(). When the packet is sent successfully, NDIS will call the
    PtSendComplete() to indicate the success to the upper layer.

    In my scenario, which adapter shall I acknowledge in PtSendComplete(), NIC1
    or NIC2?

    Does NDIS return the packet with the same address to PtSendComplete() as the
    packet sending by NdisSend()?


    Liang Chen, Aug 17, 2005
    1. Advertisements

  2. Simply follow this rule: Each NDIS_PACKET has a current owner. An owner
    (aka "module"/"driver") can temporarily pass ownership of an
    NDIS_PACKET to some other driver. Finally, a temporary owner must pass
    ownership back to the originator of the NDIS_PACKET.

    In your case, there is some protocol like TCP/IP that allocates and
    thus owns an NDIS_PACKET. The protocol sets up the NDIS_PACKET with one
    or more NDIS_BUFFERs and passes ownership to the miniport of an
    underlying NIC by calling NdisSend().

    Since you are a Filter intermediate driver, the NIC miniport does not
    get the NDIS_PACKET but instead your IM's MiniportSend() routine gets
    it. Thus your IM now temporarily owns the NDIS_PACKET. The IM is
    responsible for passing ownership back to the protocol by *later*
    calling NdisMSendComplete().

    Since you want to actually send the packet, you allocate a new
    NDIS_PACKET and attach to it the same NDIS_BUFFER(s) from the original
    NDIS_PACKET (unless you use packet stacking). Then you pass this new
    NDIS_PACKET to NdisSend() with the miniport handle of e.g. NIC1.

    The NIC1 miniport now temporarily owns your NDIS_PACKET until it calls
    NdisMSendComplete(). This is when the NDIS_PACKET gets passed back to
    your ProtocolSendComplete() routine. You are now again the owner of the
    NDIS_PACKET that you allocated. (You can free this NDIS_PACKET.)

    But you still own the original NDIS_PACKET from the protocol. Thus you
    now pass the original NDIS_PACKET back to the protocol by also calling
    NdisMSendComplete() with the same miniport handle that was passed to
    MiniportSend() earlier.

    Note that an NDIS_PACKET is uniquely identified by its address (i.e.
    the pointer to it). All routines that handle the same NDIS_PACKET thus
    use the same pointer value.

    Also note that what you are doing is not actually what a Filter IM is
    supposed to do. You are rather implementing a MUX IM. See the MUX
    sample in the DDK.

    Stephan Wolf [MVP], Aug 17, 2005
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.