about hold TDI recieve packet.

Hi,
I am writing a TDI filter. Something like this:

  1. at TdiSetEvent, registe TDI_RECEIVE_EVENT handler, and set TDI_CHAINED_RECEIVE_EVENT handler is NULL, so, I can receive all tcp packet with TDI_RECIEVE_EVENT handler;
    The code:

case TDI_EVENT_RECEIVE:
if( pSrc->EventHandler )
{
pAddrObj->ao_rcv = pSrc->EventHandler;
pAddrObj->ao_rcvcontext = pSrc->EventContext;

pDest->EventHandler = (PVOID )DSTDI_TdiReceiveEventHandler;
pDest->EventContext = (PVOID )pAddrObj; // context is our Address Object Record
}
else
{
pAddrObj->ao_rcv = NULL;
pAddrObj->ao_rcvcontext = NULL;

pDest->EventHandler = NULL;
pDest->EventContext = NULL;
}
break;

case TDI_EVENT_CHAINED_RECEIVE:
pAddrObj->ao_chainedrcv = NULL;
pAddrObj->ao_chainedrcvcontext = NULL;

pDest->EventHandler = NULL;
pDest->EventContext = NULL;

break;

now, I have 2 TDI_RECEIVE_EVENT handler,
one is the original handler(pAddrObj->ao_rcv), other is DSTDI_TdiReceiveEventHandler.

  1. at TDI_RECEIVE_EVENT handler routine, insert the receive packet(TSDU) to alinkage, and return;
    at this point, if the BytesIndicated != BytesAvailable, I will build a Irp to get the ENTIRE tsdu.
    the code:

if ( BytesIndicated != BytesAvailable)
{
IoAllocateIrp…
ExAllocatePool(pBuf, …
IoAllocateMdl(pBuf, …
MmBuildMdlForNonPagedPool(pMdl);
TdiBuildReceive(pTDIReceiveIrp,
pDeviceObject,
pTCPConn->tc_FileObject,
TdiBuildReceiveComplete,
pReceiveContxt,
pMdl,
TDI_RECEIVE_NORMAL|TDI_RECEIVE_EXPEDITED,
BytesAvailable
);

IoSetNextIrpStackLocation(pTDIReceiveIrp);

*IoRequestPacket = pTDIReceiveIrp;
*BytesTaken = 0;

return STATUS_MORE_PROCESSING_REQUIRED;
}
else
{
*BytesTaken = BytesIndicated;
Insert the tsdu to linkage;
return STATUS_success
}

  1. at the TdiBuildReceiveComplete, I can get the ENTIRE tsdu. so I insert the tsdu and it’s context to linkage, and return STATUS_MORE_PROCESSING_REQUIRED;

  2. When the TDI filter is load, I start a system thread.It will indicate all the packet in the linkage, use the original handler(pAddrObj->ao_rcv).

so, my problem is: how can I notify the under, I’ve indicate the receive packet, and the under can release all the resource.

In the DSTDI_TdiReceiveEventHandler, I return STATUS_MORE_PROCESSING_REQUIRED;
in the TdiBuildReceiveComplete, I return STATUS_MORE_PROCESSING_REQUIRED too.

The under seems do not know I have indicate the packet. how can I notify the under.

I try to use TdiChainedReturnReceive, but the system crashed.
TdiReturnChainedReceives(&pTCPRecvq->Tsdu, 1);

I think I understand your question to be simply:

Q: If a TDI filter queues the ‘data’ copied from a RX event indication (not
a RX chained event indication) what must it do to ensure that the transport
releases resources associated with this RX indication?

If that is your question, the answer is *nothing* because the transport does
not maintain any resources associated with a RX event indication. It is the
handlers (your filter in this case) responsibility to copy the data and/or
provide an IRP with a buffer mapped by an MDL to copy the data into, which
it seems as though you have said your filter does.

At this point, the ‘under’ transport is done. It indicated the RX and
something accepted it (your filter). When you indicate the data to the
(next) client handler, the only resource cleanup required is stuff allocated
by your filter to hold onto the received data until such time as the (next)
client accepts, rejects, or pends the receive event processing.

My answer completely ignores the myriad of issues associated with *actually*
doing this; in particular syncronization between the multiple ways that a
TDI client can ‘receive’ data as well as the possiblity of changes to the
event handler, closing the endpoint, etc. etc.

I am not sure why you want to ‘stall’ the data but if stalling is all you
are doing then often it is better to stall the data in the original
transport (in other words, don?t accept any of the data) and restart the
receive processing at some later time when it is appropriate. If your
filter takes the responsibility of buffering abitrary amounts of receive
data while your system thread figures out what to do with it, you could
easily find yourself managing quite a bit of data. Unless you actually need
to read and process that data to figure out what to do with it, allowing the
transport flow control mechanism keep the data from overrunning the receiver
is not a bad idea.

Good Luck,
Dave Cattley
Consulting Engineer
Systems Software Development

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@hotmail.com
Sent: Sunday, July 16, 2006 1:36 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] about hold TDI recieve packet.

so, my problem is: how can I notify the under, I’ve indicate the receive
packet, and the under can release all the resource.

In the DSTDI_TdiReceiveEventHandler, I return
STATUS_MORE_PROCESSING_REQUIRED; in the TdiBuildReceiveComplete, I return
STATUS_MORE_PROCESSING_REQUIRED too.

The under seems do not know I have indicate the packet. how can I notify the
under.

I try to use TdiChainedReturnReceive, but the system crashed.
TdiReturnChainedReceives(&pTCPRecvq->Tsdu, 1);


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer