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