Hi,
I try to receive a datagram size > 10000 bytes with tdi driver in Nt4. I
create TDI_EVENT_RECEIVE_DATAGRAM event but it not return the complete
size of my datagram. I try TDI_EVENT_CHAINED_RECEIVE_DATAGRAM event
but, it doesn’t work but.
Please help me to understand why.
The event handlers will provide data as it becomes available. This is the
normal behavior of the TDI receive event handler.
Good luck,
Thomas F. Divine
PCAUSA - Tools & Resources For Network Software Developers
NDIS Protocol/Intermediate/Hooking - TDI Client/Filter
http: - http:
"sampo" wrote in message news:xxxxx@ntdev...
>
> Hi,
> I try to receive a datagram size > 10000 bytes with tdi driver in Nt4. I
> create TDI_EVENT_RECEIVE_DATAGRAM event but it not return the complete
> size of my datagram. I try TDI_EVENT_CHAINED_RECEIVE_DATAGRAM event
> but, it doesn't work but.
> Please help me to understand why.
>
></http:></http:>
> I try to receive a datagram size > 10000 bytes with tdi driver in Nt4. I
create TDI_EVENT_RECEIVE_DATAGRAM event but it not return the complete
size of my datagram.
Strange. Is the size indicated to your TDI event correct?
I try TDI_EVENT_CHAINED_RECEIVE_DATAGRAM event
but, it doesn’t work but.
It requires the NIC miniport to support NdisMIndicateReceivePacket and use it instead of NdisMXxxIndicateReceive.
Also IIRC TDI chained receives are not supported for UDP on NT4 and w2k.
Max
BytesIndicated(aproximatly 1500 bytes) < BytesAvailable.
In BytesAvailable i have the exacte size of my datagram.
In Tsdu i have only BytesIndicated.
How can i get my full datagram?
thanks for your help
> BytesIndicated(aproximatly 1500 bytes) < BytesAvailable.
In BytesAvailable i have the exacte size of my datagram.
In Tsdu i have only BytesIndicated.
How can i get my full datagram?
Allocate a RECEIVE_DATAGRAM IRP inside your receive event and return it to TDI.
The full datagram will arrive to the IRP’s completion routine.
Max
I try this but windows crash.
Have you an example ?
Thanks for your help.
This is my code :
///////////
/// Install Event Handler (Work Fine)
pIrp=TdiBuildInternalDeviceControlIrp(TDI_RECEIVE_DATAGRAM,pDeviceObject,pTdiTransportObject,NULL,NULL);
if(pIrp==NULL)
dStatus=STATUS_INSUFFICIENT_RESOURCES;
else
{
TdiBuildSetEventHandler(pIrp,pDeviceObject,pTdiTransportObject,NULL,NULL,TDI_EVENT_RECEIVE_DATAGRAM,RcvDatagram,NULL);
dStatus=TdiCall(pIrp,pDeviceObject,&IoStatusBlock);
}
///////////////////
// Event Handler (crash)
NTSTATUS RcvDatagram(IN PVOID TdiEventContext,IN LONG SourceAddressLength,IN PVOID SourceAddress,IN LONG OptionsLength,
IN PVOID Options,IN ULONG ReceiveDatagramFlags,IN ULONG BytesIndicated,IN ULONG BytesAvailable,
OUT ULONG *BytesTaken,IN PVOID Tsdu,OUT PIRP *IoRequestPacket)
{
static int BytesRcv=0;
BytesRcv+=BytesIndicated;
DbgPrint(“BytesIndicated=%lu\n\r”,BytesIndicated);
DbgPrint(“BytesAvailable=%lu\n\r”,BytesAvailable);
if(BytesRcv<10000)
{
//PIRP Test (global)
Test=TdiBuildInternalDeviceControlIrp(TDI_RECEIVE_DATAGRAM,IoGetRelatedDeviceObject(pTdiTransportObject),
pTdiTransportObject,NULL,NULL);
if(Test==NULL)
{
DbgPrint(“ERROR IoRequestPacket\n\r”);
return STATUS_DATA_NOT_ACCEPTED;
}
else
{
IoRequestPacket=&Test;
*BytesTaken=BytesIndicated;
return STATUS_MORE_PROCESSING_REQUIRED;
}
}
else
return STATUS_SUCCESS;
Your code is missing a couple of things. One is a call to
TdiBuildReceiveDatagram the other is a call to SetNextIrpStackLocation.
- set *BytesTaken = 0
- Allocate an IRP
- Pass the IRP to the TdiBuildReceiveDatagram() macro
- Call SetNextIrpStackLocation() on the IRP.
- Assign the IRP to *IoRequestPacket
- return STATUS_MORE_PROCESSING_REQUIRED
Some pseudo code would look like:
PIRP irp;
irp=IoAllocateIrp(…,False);
TdiBuildReceiveDatagram(…); // Set the completion routine for the
IRP here.
SetNextIrpStackLocation(irp); // Necessary to advance the stack
pointer.
*IoRequestPacket=irp;
*BytesTaken=0;
return STATUS_MORE_PROCESSING_REQUIRED;
Below is a sample completion routine for the above pseudo code.
NTSTATUS
IoCompletionAsync(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
{
IoFreeIrp(Irp);
return STATUS_MORE_PROCESSING_REQUIRED;
}
Now the only thing missing would be a buffer to receive the data into.
If your TDI Client allocates the buffer then it will be responsible for
either freeing the buffer or reusing the buffer. This would be done in
the completion routine before calling IoFreeIrp().
For the case where BytesIndicated == BytesAvailable you can still do
steps 1-6 above or you can do the following steps:
- Copy the data at Tsdu for the BytesIndicated
- Set *BytesTaken = BytesAvailable
- return STATUS_SUCCESS
- Eric
This posting is provided “AS IS” with no warranties, and confers no
rights.
-----Original Message-----
From: sampo [mailto:xxxxx@voila.fr]
Sent: Tuesday, March 19, 2002 9:15 AM
To: NT Developers Interest List
Subject: [ntdev] Re: tdi SetEventHandler
I try this but windows crash.
Have you an example ?
Thanks for your help.
This is my code :
///////////
/// Install Event Handler (Work Fine)
pIrp=TdiBuildInternalDeviceControlIrp(TDI_RECEIVE_DATAGRAM,pDeviceObject
,pTdiTransportObject,NULL,NULL);
if(pIrp==NULL)
dStatus=STATUS_INSUFFICIENT_RESOURCES;
else
{
TdiBuildSetEventHandler(pIrp,pDeviceObject,pTdiTransportObject,NULL,NULL
,TDI_EVENT_RECEIVE_DATAGRAM,RcvDatagram,NULL);
dStatus=TdiCall(pIrp,pDeviceObject,&IoStatusBlock);
}
///////////////////
// Event Handler (crash)
NTSTATUS RcvDatagram(IN PVOID TdiEventContext,IN LONG
SourceAddressLength,IN PVOID SourceAddress,IN LONG OptionsLength,
IN PVOID Options,IN ULONG
ReceiveDatagramFlags,IN ULONG BytesIndicated,IN ULONG BytesAvailable,
OUT ULONG *BytesTaken,IN PVOID
Tsdu,OUT PIRP *IoRequestPacket) {
static int BytesRcv=0;
BytesRcv+=BytesIndicated;
DbgPrint(“BytesIndicated=%lu\n\r”,BytesIndicated);
DbgPrint(“BytesAvailable=%lu\n\r”,BytesAvailable);
if(BytesRcv<10000)
{
//PIRP Test (global)
Test=TdiBuildInternalDeviceControlIrp(TDI_RECEIVE_DATAGRAM,IoGetRelatedD
eviceObject(pTdiTransportObject),
pTdiTransportObject,NULL,NULL);
if(Test==NULL)
{
DbgPrint(“ERROR IoRequestPacket\n\r”);
return STATUS_DATA_NOT_ACCEPTED;
}
else
{
IoRequestPacket=&Test;
*BytesTaken=BytesIndicated;
return STATUS_MORE_PROCESSING_REQUIRED;
}
}
else
return STATUS_SUCCESS;
You are currently subscribed to ntdev as: xxxxx@microsoft.com To
unsubscribe send a blank email to %%email.unsub%%
That would be IoSetNextIrpStackLocation…
-----Original Message-----
From: Eric W Hanson [mailto:xxxxx@microsoft.com]
Sent: Tuesday, March 19, 2002 11:50 AM
To: NT Developers Interest List
Subject: [ntdev] Re: tdi SetEventHandler
Your code is missing a couple of things. One is a call to
TdiBuildReceiveDatagram the other is a call to SetNextIrpStackLocation.
- set *BytesTaken = 0
- Allocate an IRP
- Pass the IRP to the TdiBuildReceiveDatagram() macro
- Call SetNextIrpStackLocation() on the IRP.
- Assign the IRP to *IoRequestPacket
- return STATUS_MORE_PROCESSING_REQUIRED
Some pseudo code would look like:
PIRP irp;
irp=IoAllocateIrp(…,False);
TdiBuildReceiveDatagram(…); // Set the completion routine for the
IRP here. SetNextIrpStackLocation(irp); // Necessary to advance the
stack pointer. *IoRequestPacket=irp; *BytesTaken=0; return
STATUS_MORE_PROCESSING_REQUIRED;
Below is a sample completion routine for the above pseudo code.
NTSTATUS
IoCompletionAsync(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
{
IoFreeIrp(Irp);
return STATUS_MORE_PROCESSING_REQUIRED;
}
Now the only thing missing would be a buffer to receive the data into.
If your TDI Client allocates the buffer then it will be responsible for
either freeing the buffer or reusing the buffer. This would be done in
the completion routine before calling IoFreeIrp().
For the case where BytesIndicated == BytesAvailable you can still do
steps 1-6 above or you can do the following steps:
- Copy the data at Tsdu for the BytesIndicated
- Set *BytesTaken = BytesAvailable
- return STATUS_SUCCESS
- Eric
This posting is provided “AS IS” with no warranties, and confers no
rights.
-----Original Message-----
From: sampo [mailto:xxxxx@voila.fr]
Sent: Tuesday, March 19, 2002 9:15 AM
To: NT Developers Interest List
Subject: [ntdev] Re: tdi SetEventHandler
I try this but windows crash.
Have you an example ?
Thanks for your help.
This is my code :
///////////
/// Install Event Handler (Work Fine)
pIrp=TdiBuildInternalDeviceControlIrp(TDI_RECEIVE_DATAGRAM,pDeviceObject
,pTdiTransportObject,NULL,NULL);
if(pIrp==NULL)
dStatus=STATUS_INSUFFICIENT_RESOURCES;
else
{
TdiBuildSetEventHandler(pIrp,pDeviceObject,pTdiTransportObject,NULL,NULL
,TDI_EVENT_RECEIVE_DATAGRAM,RcvDatagram,NULL);
dStatus=TdiCall(pIrp,pDeviceObject,&IoStatusBlock);
}
///////////////////
// Event Handler (crash)
NTSTATUS RcvDatagram(IN PVOID TdiEventContext,IN LONG
SourceAddressLength,IN PVOID SourceAddress,IN LONG OptionsLength,
IN PVOID Options,IN ULONG
ReceiveDatagramFlags,IN ULONG BytesIndicated,IN ULONG BytesAvailable,
OUT ULONG *BytesTaken,IN PVOID
Tsdu,OUT PIRP *IoRequestPacket) {
static int BytesRcv=0;
BytesRcv+=BytesIndicated;
DbgPrint(“BytesIndicated=%lu\n\r”,BytesIndicated);
DbgPrint(“BytesAvailable=%lu\n\r”,BytesAvailable);
if(BytesRcv<10000)
{
//PIRP Test (global)
Test=TdiBuildInternalDeviceControlIrp(TDI_RECEIVE_DATAGRAM,IoGetRelatedD
eviceObject(pTdiTransportObject),
pTdiTransportObject,NULL,NULL);
if(Test==NULL)
{
DbgPrint(“ERROR IoRequestPacket\n\r”);
return STATUS_DATA_NOT_ACCEPTED;
}
else
{
IoRequestPacket=&Test;
*BytesTaken=BytesIndicated;
return STATUS_MORE_PROCESSING_REQUIRED;
}
}
else
return STATUS_SUCCESS;
You are currently subscribed to ntdev as: xxxxx@microsoft.com To
unsubscribe send a blank email to %%email.unsub%%
You are currently subscribed to ntdev as: xxxxx@microsoft.com To
unsubscribe send a blank email to %%email.unsub%%
> IoRequestPacket=&Test;
*BytesTaken=BytesIndicated;
Call IoSetNextIrpStackLocation before returning the IRP to TDI.
Max
Thank you very much. It work fine.