Originating packets in an IM driver, success!

For those following the thread, the procedure I am using is this:

  1. Allocate a new packet descriptor with NdisDprAllocatePacket or NdisAllocatePacket
    from your receivepacketpool
  2. Use NdisAllocateMemory or NdisAllocateMemoryWithTag to create a
    memory are for use as a buffer.
  3. Allocate a buffer from the receive pool and point it to the
    freshly allocated memory using NdisAllocateBuffer.
  4. Check the returned status to ensure that the buffer is allocated
    from the pool.
  5. Using NdisMoveMemory, or structure pointers, to assist in loading
    the packet data into the buffer.
  6. Calculate the packet checksums, in my case I had to calc an IP and a
    UDP checksum
  7. Set the Packet.private.head and .tail to NULL
  8. NdisChainBufferAtFront puts the packet buffer onto the packet
    descriptor
  9. NDIS_SET_PACKET_HEADER_SIZE sets the transport header size, I
    am simulating an ethernet packet so I use sizeof(ETH_HEADER)
  10. NDIS_SET_PACKET_STATUS is set to NDIS_STATUS_RESOURCES forcing
    the protocol driver to make a copy of the packet.
  11. NdisMIndicateReceivePacket pushes the packet up the stack.
  12. Use NDIS_GET_PACKET_STATUS on return. If equal to NDIS_STATUS_RESOURCES
    then the protocol successfully copied the packet.
  13. Call NdisFreeBuffer to release the buffer back to the buffer pool
  14. Call NdisFreeMemory to release the allocated memory for the packet data
  15. Call NdisDprFreePacket or NdisFreePacket to release the packet descriptor
  16. return NDIS_STATUS_SUCCESS

Mistakes I made included trying to deal with TCP_TASK_OFFLOAD, Checksumming,
and attempting to deal with other OOB data. In a nutshell, you have none
of that with the new packet. Just send it up clean. All the other fancy
blinking lights in NDIS are there to intimidate and confuse mere mortals (like me).

After stumbling through the maze called NDIS, I can only look at the above
and thinkā€¦ DUH!!!