about TDI interfaces for UDP

Hi all,

I am facing problems using TDI interfaces for the UDP
communication. The problem is i am not getting the
event raised for the TdiBuildReceiveDatagram when
calling the driver even when i am sending the packet
to that datagram socket. The problem comes when i try
to create 2 UDP sockets and want to communicate with
that.With one its working fine.

The Code is attached here.

NTSTATUS
MSockRecvFrom
(
PFILE_OBJECT AddressFile,
PVOID Data,
PULONG32 DataSize
)
{
NTSTATUS Status;
PDEVICE_OBJECT ConnectionDevice;
PTDI_CONNECTION_INFORMATION pReceiveInfo;
PTDI_CONNECTION_INFORMATION pReturnInfo;
PTA_IP_ADDRESS pReturnAddress;
KEVENT Event;
IO_STATUS_BLOCK Iosb;
PIRP pIrp;
PMDL pMdl;
PVOID pMdlBuffer = NULL;
PTDI_ADDRESS_IP pIp;
LARGE_INTEGER TimeOut;

try
{
if ( pUdp->AddressFile )
{
ConnectionDevice = IoGetRelatedDeviceObject (
AddressFile );

pReceiveInfo =
(PTDI_CONNECTION_INFORMATION)ExAllocatePool ( //
allocate buffer
NonPagedPool,
sizeof ( TDI_CONNECTION_INFORMATION ) +
sizeof ( TDI_CONNECTION_INFORMATION ) +
sizeof ( TA_IP_ADDRESS ) );

pMdlBuffer = ExAllocatePool ( PagedPool, *DataSize );

if ( ConnectionDevice && pReceiveInfo && pMdlBuffer )
// validate pointer
{
RtlZeroMemory ( pReceiveInfo, // clear buffer
sizeof ( TDI_CONNECTION_INFORMATION ) +
sizeof ( TDI_CONNECTION_INFORMATION ) +
sizeof ( TA_IP_ADDRESS ) );

RtlCopyMemory ( pMdlBuffer, Data, *DataSize );

pReceiveInfo->RemoteAddressLength = 0;
// any address
pReceiveInfo->RemoteAddress = NULL;
// any address

pReturnInfo =
(PTDI_CONNECTION_INFORMATION)((PUCHAR)pReceiveInfo +
sizeof ( TDI_CONNECTION_INFORMATION ) );
pReturnInfo->RemoteAddressLength = sizeof (
TA_IP_ADDRESS );
pReturnInfo->RemoteAddress = (PUCHAR)pReturnInfo +
sizeof ( TDI_CONNECTION_INFORMATION );

pReturnAddress =
(PTA_IP_ADDRESS)(pReturnInfo->RemoteAddress);

pReturnAddress->TAAddressCount = 1;
pReturnAddress->Address[0].AddressLength = sizeof (
TDI_ADDRESS_IP );
pReturnAddress->Address[0].AddressType =
TDI_ADDRESS_TYPE_IP;
pIp =
(PTDI_ADDRESS_IP)(pReturnAddress->Address[0].Address);

pIp->sin_port = 0;
pIp->in_addr = 0L;

KeInitializeEvent( &Event, NotificationEvent, FALSE );
RtlZeroMemory( &Iosb, sizeof(IO_STATUS_BLOCK) );
pIrp = TdiBuildInternalDeviceControlIrp (

TDI_RECEIVE_DATAGRAM,// sub function
ConnectionDevice,// pointer to device object
AddressFile,// pointer to control object
&Event,// pointer to event
&Iosb );// pointer to return buffer

if ( pIrp == NULL )// validate pointer
Status = STATUS_INSUFFICIENT_RESOURCES;
else
{
pMdl = IoAllocateMdl (
pMdlBuffer,// buffer pointer - virtual address
*DataSize,// length
FALSE,// not secondary
FALSE,
NULL );// don’t use irp
if ( pMdl )// validate mdl pointer
{
try
{
MmProbeAndLockPages ( pMdl, KernelMode, IoModifyAccess
); // probe & lock
}
except ( EXCEPTION_EXECUTE_HANDLER )
{
DbgPrint ( “EXCEPTION: MmProbeAndLockPages\n” );
IoFreeMdl( pMdl );
pMdl = NULL;
}
}

if ( pMdl )
{
TdiBuildReceiveDatagram (
pIrp,// pointer to irp
ConnectionDevice,// pointer to device object
AddressFile,// pointer to file object
NULL,// completion routine
NULL,// completion context
pMdl,// pointer to data
*DataSize,// size of data
pReceiveInfo,// connection information
pReturnInfo,// connection information
TDI_RECEIVE_NORMAL ); // flags
// KeInitializeEvent( &Event, NotificationEvent,
FALSE );
RtlZeroMemory( &Iosb, sizeof(IO_STATUS_BLOCK) );
Status = IoCallDriver( ConnectionDevice, pIrp );
if ( Status == STATUS_PENDING )
{
KeWaitForSingleObject ((PVOID)&Event,
Executive,
KernelMode,
TRUE,
NULL
);
Status = Iosb.Status;
RtlCopyMemory ( Data, pMdlBuffer, Iosb.Information );
DbgPrint( “MSockRecvFrom Ip : %x\n”,
RtlUlongByteSwap(pIp->in_addr));
DbgPrint( “MSockRecvFrom Port : %d\n”,
RtlUshortByteSwap(pIp->sin_port));
}
else
{
IoFreeIrp ( pIrp );
DbgPrint ( “ERROR: IoAllocateMdl\n” );
}
}
}
}
}
finally
{
if ( pReceiveInfo )
// validate pointer
ExFreePool ( pReceiveInfo );// free buffer
if ( pMdlBuffer )
// validate pointer
ExFreePool ( pMdlBuffer );// free buffer
}

return ( Status );

}


Do You Yahoo!?
Yahoo! - Official partner of 2002 FIFA World Cup
http://fifaworldcup.yahoo.com

Your problem may be in your wait logic.

A return value of STATUS_PENDING does NOT mean that the event will be called
LATER. It just means that the system will call the event handler (callback)
SOMETIME. In fact, it ma have ALREADY called it. You should set a breakpoint
in your callback routine. You may see that being hit BEFORE the routine that
you are calling even returns to you.

There are several ways to deal with this. One way is to test the return
value and handle it in two steps:

1.) If the return value is NOT STATUS_PENDING (this means your event handler
will NOT be called by the system), set the event yourself.
2.) After step 1.) ALWAYS wait on the event. If logic of step 1.) was
entered your wait will return immediately. If status was STATUS_PENDING then
code will also work.

Good luck,

Thomas F. Divine

PCAUSA - Tools & Resources For Network Software Developers
NDIS Protocol/Intermediate/Hooking - TDI Client/Filter
http: - http:

“Murali S” wrote in message news:xxxxx@ntdev…
>
> Hi all,
>
> I am facing problems using TDI interfaces for the UDP
> communication. The problem is i am not getting the
> event raised for the TdiBuildReceiveDatagram when
> calling the driver even when i am sending the packet
> to that datagram socket. The problem comes when i try
> to create 2 UDP sockets and want to communicate with
> that.With one its working fine.
>
> The Code is attached here.</http:></http:>