TDI client help

From: xxxxx@cesa.fr

Hi,

I have a TDI client which is waiting for connections. I have set up an
event handler which is calling a ClientEventConnect when a remote host ask
for a connection.
The driver works and the event function is called when there is a
connection request. However, when in ClientEventConnect the function
returns STATUS_MORE_PROCESSING_REQUIRED, I get a BSOD and I cannot find
where is the bug.
Below are two functions: ClientEventConnect and BuildIrpForEventCalled
(the last being called at driver loading). Thanks for your help !

nunch

NTSTATUS ClientEventConnect(IN PDEVICE_OBJECT DeviceObject,IN LONG
RemoteAddressLength,
IN PVOID RemoteAddress,IN LONG
UserDataLength,IN PVOID UserData,
IN LONG OptionsLength,IN PVOID Options,
OUT CONNECTION_CONTEXT *ConnectionContext,OUT
PIRP *AcceptIrp)
{
NTSTATUS Status; // Status value
PTA_ADDRESS Address; // Transport address descriptor
PTDI_ADDRESS_IP Ip; // IP Address descriptor
PTA_IP_ADDRESS AdresseIP; // IP Transport Address descriptor
PDEVICE_OBJECT TargetDevice; // Target device
PDEVICE_EXTENSION DeviceExtension; // Pointer to internal structure:
device extension
PTDI_CONNECTION_INFORMATION RequestInformation; // Remote connection
information

DeviceExtension=(PDEVICE_EXTENSION)DeviceObject->DeviceExtension;

// Source address format checking
Address=((PTRANSPORT_ADDRESS)RemoteAddress)->Address;
if(Address->AddressLength==TDI_ADDRESS_LENGTH_IP &&
Address->AddressType==TDI_ADDRESS_TYPE_IP)
{
// IP address filtering
Ip=(PTDI_ADDRESS_IP)Address->Address;
if(Ip->in_addr==DeviceExtension->AdresseIp)
{
// Connection is accepted
RequestInformation=DeviceExtension->ConnectIrp.PtrInfo;
if(RequestInformation!=NULL)
{
// Build remote connection information
RequestInformation->UserDataLength=0;
RequestInformation->UserData=NULL;
RequestInformation->OptionsLength=0;
RequestInformation->Options=NULL;
RequestInformation->RemoteAddressLength=sizeof(TA_IP_ADDRESS);

RequestInformation->RemoteAddress=(PUCHAR)RequestInformation+sizeof(TDI_CONNECTION_INFORMATION);

AdresseIP=(PTA_IP_ADDRESS)RequestInformation->RemoteAddress;
AdresseIP->TAAddressCount=1;
AdresseIP->Address[0].AddressLength=TDI_ADDRESS_LENGTH_IP;
AdresseIP->Address[0].AddressType=TDI_ADDRESS_TYPE_IP;
AdresseIP->Address[0].Address[0].sin_port=Ip->sin_port;
AdresseIP->Address[0].Address[0].in_addr=Ip->in_addr;

// IRP building

TargetDevice=IoGetRelatedDeviceObject(DeviceExtension->Connection.Object);
*AcceptIrp=DeviceExtension->ConnectIrp.PtrIrp;
if(*AcceptIrp!=NULL)
{

TdiBuildAccept(*AcceptIrp,TargetDevice,DeviceExtension->Connection.Object,NULL,NULL,

RequestInformation,NULL);
*ConnectionContext=DeviceExtension;
Status=STATUS_MORE_PROCESSING_REQUIRED;
}
else
{
*AcceptIrp=NULL;
*ConnectionContext=NULL;
Status=STATUS_INSUFFICIENT_RESOURCES;
}
}
else
{
*AcceptIrp=NULL;
*ConnectionContext=NULL;
Status=STATUS_INSUFFICIENT_RESOURCES;
}
}
else
{
// IP Address filtered
*AcceptIrp=NULL;
*ConnectionContext=NULL;
Status=STATUS_CONNECTION_REFUSED;
}
}
else
{
// Invalid source address format
*AcceptIrp=NULL;
*ConnectionContext=NULL;
Status=STATUS_CONNECTION_REFUSED;
}
return Status;
}

NTSTATUS BuildIrpForEventConnect(IN PDEVICE_EXTENSION DevExt)
{
PDEVICE_OBJECT DeviceObject; // Target device
NTSTATUS Status; // Status value

Status=STATUS_SUCCESS;
if(DevExt->ConnectIrp.PtrInfo==NULL)
{
// Buffer allocation
DevExt->ConnectIrp.PtrInfo=(PTDI_CONNECTION_INFORMATION)

ExAllocatePool(NonPagedPool,sizeof(TDI_CONNECTION_INFORMATION)+

sizeof(TA_IP_ADDRESS));
}
else

RtlZeroMemory(DevExt->ConnectIrp.PtrInfo,sizeof(TDI_CONNECTION_INFORMATION)+

sizeof(TA_IP_ADDRESS));
if(DevExt->ConnectIrp.PtrInfo!=NULL)
{
// IRP Building
DeviceObject=IoGetRelatedDeviceObject(DevExt->Connection.Object);

DevExt->ConnectIrp.PtrIrp=TdiBuildInternalDeviceControlIrp(TDI_ACCEPT,DeviceObject,

DevExt->Connection.Object,NULL,

&DevExt->ConnectIrp.IoStatus);
if(DevExt->ConnectIrp.PtrIrp==NULL)
Status=STATUS_INSUFFICIENT_RESOURCES;
}
else
Status=STATUS_INSUFFICIENT_RESOURCES;

return Status;
}

hi Nicolas !
Are u not handling any errors in Completion routine, when u call the lower
driver with IoCallDriver()
Only when u get an Irp Pending, should u call the completion routine and
return STATUS_MORE_PROCESSING_REQUIRED.
Is your client listening for any connections to accept ?
I have implemented a very simple TDI driver( accepting connections
successfuly) …and it works fine.
U can build your Irp with correct TDIBuildxxx, and then call the lower
driver, handling the error in Completion routine…

Regards
Anurag

On Friday 25 October 2002 04:06 pm, you wrote:

From: xxxxx@cesa.fr

Hi,

I have a TDI client which is waiting for connections. I have set up an
event handler which is calling a ClientEventConnect when a remote host ask
for a connection.
The driver works and the event function is called when there is a
connection request. However, when in ClientEventConnect the function
returns STATUS_MORE_PROCESSING_REQUIRED, I get a BSOD and I cannot find
where is the bug.
Below are two functions: ClientEventConnect and BuildIrpForEventCalled
(the last being called at driver loading). Thanks for your help !

nunch

NTSTATUS ClientEventConnect(IN PDEVICE_OBJECT DeviceObject,IN LONG
RemoteAddressLength,
IN PVOID RemoteAddress,IN LONG
UserDataLength,IN PVOID UserData,
IN LONG OptionsLength,IN PVOID Options,
OUT CONNECTION_CONTEXT *ConnectionContext,OUT
PIRP *AcceptIrp)
{
NTSTATUS Status; // Status value
PTA_ADDRESS Address; // Transport address descriptor
PTDI_ADDRESS_IP Ip; // IP Address descriptor
PTA_IP_ADDRESS AdresseIP; // IP Transport Address descriptor
PDEVICE_OBJECT TargetDevice; // Target device
PDEVICE_EXTENSION DeviceExtension; // Pointer to internal structure:
device extension
PTDI_CONNECTION_INFORMATION RequestInformation; // Remote connection
information

DeviceExtension=(PDEVICE_EXTENSION)DeviceObject->DeviceExtension;

// Source address format checking
Address=((PTRANSPORT_ADDRESS)RemoteAddress)->Address;
if(Address->AddressLength==TDI_ADDRESS_LENGTH_IP &&
Address->AddressType==TDI_ADDRESS_TYPE_IP)
{
// IP address filtering
Ip=(PTDI_ADDRESS_IP)Address->Address;
if(Ip->in_addr==DeviceExtension->AdresseIp)
{
// Connection is accepted
RequestInformation=DeviceExtension->ConnectIrp.PtrInfo;
if(RequestInformation!=NULL)
{
// Build remote connection information
RequestInformation->UserDataLength=0;
RequestInformation->UserData=NULL;
RequestInformation->OptionsLength=0;
RequestInformation->Options=NULL;
RequestInformation->RemoteAddressLength=sizeof(TA_IP_ADDRESS);

RequestInformation->RemoteAddress=(PUCHAR)RequestInformation+sizeof(TDI_CON
NECTION_INFORMATION);

AdresseIP=(PTA_IP_ADDRESS)RequestInformation->RemoteAddress;
AdresseIP->TAAddressCount=1;
AdresseIP->Address[0].AddressLength=TDI_ADDRESS_LENGTH_IP;
AdresseIP->Address[0].AddressType=TDI_ADDRESS_TYPE_IP;
AdresseIP->Address[0].Address[0].sin_port=Ip->sin_port;
AdresseIP->Address[0].Address[0].in_addr=Ip->in_addr;

// IRP building

TargetDevice=IoGetRelatedDeviceObject(DeviceExtension->Connection.Object);
*AcceptIrp=DeviceExtension->ConnectIrp.PtrIrp;
if(*AcceptIrp!=NULL)
{

TdiBuildAccept(*AcceptIrp,TargetDevice,DeviceExtension->Connection.Object,N
ULL,NULL,

RequestInformation,NULL);
*ConnectionContext=DeviceExtension;
Status=STATUS_MORE_PROCESSING_REQUIRED;
}
else
{
*AcceptIrp=NULL;
*ConnectionContext=NULL;
Status=STATUS_INSUFFICIENT_RESOURCES;
}
}
else
{
*AcceptIrp=NULL;
*ConnectionContext=NULL;
Status=STATUS_INSUFFICIENT_RESOURCES;
}
}
else
{
// IP Address filtered
*AcceptIrp=NULL;
*ConnectionContext=NULL;
Status=STATUS_CONNECTION_REFUSED;
}
}
else
{
// Invalid source address format
*AcceptIrp=NULL;
*ConnectionContext=NULL;
Status=STATUS_CONNECTION_REFUSED;
}
return Status;
}

NTSTATUS BuildIrpForEventConnect(IN PDEVICE_EXTENSION DevExt)
{
PDEVICE_OBJECT DeviceObject; // Target device
NTSTATUS Status; // Status value

Status=STATUS_SUCCESS;
if(DevExt->ConnectIrp.PtrInfo==NULL)
{
// Buffer allocation
DevExt->ConnectIrp.PtrInfo=(PTDI_CONNECTION_INFORMATION)

ExAllocatePool(NonPagedPool,sizeof(TDI_CONNECTION_INFORMATION)+

sizeof(TA_IP_ADDRESS));
}
else

RtlZeroMemory(DevExt->ConnectIrp.PtrInfo,sizeof(TDI_CONNECTION_INFORMATION)
+

sizeof(TA_IP_ADDRESS));
if(DevExt->ConnectIrp.PtrInfo!=NULL)
{
// IRP Building
DeviceObject=IoGetRelatedDeviceObject(DevExt->Connection.Object);

DevExt->ConnectIrp.PtrIrp=TdiBuildInternalDeviceControlIrp(TDI_ACCEPT,Devic
eObject,

DevExt->Connection.Object,NULL,

&DevExt->ConnectIrp.IoStatus);
if(DevExt->ConnectIrp.PtrIrp==NULL)
Status=STATUS_INSUFFICIENT_RESOURCES;
}
else
Status=STATUS_INSUFFICIENT_RESOURCES;

return Status;
}


You are currently subscribed to ntdev as: xxxxx@dcmtech.co.in
To unsubscribe send a blank email to %%email.unsub%%

Yes Anurag, I use the TDIBuildxxx functions. Did you saw the C code at the
end of my message ? Does your TDI driver is event based ?
I did’nt make any completion routine because the NT DDK documentation
concerning the ClientEventConnect callback function says:

AcceptIrp:
“Points to a caller-supplied variable in which ClientEventConnect returns
a pointer to an IRP, set up by ClientEventConnect with TdiBuildAccept. The
transport completes this IRP if it is supplied as it does any normal
accept request. If ClientEventConnect rejects the connection offer, this
parameter is NULL.”

and later:
“To accept an offered endpoint-to-endpoint connection, ClientEventConnect
must set up the buffer at ConnectionContext, together with a TDI_ACCEPT
request, and, then, return STATUS_MORE_PROCESSING_REQUIRED. The local-node
transport notifies the remote node of the acceptance, transmitting any
connect data that its client supplied in the accept IRP, and completes the
TDI_ACCEPT request normally.”

So I just used TdiBuildInternalDeviceControlIrp() and TdiBuildAccept()
macros and set the PIRP pointer with the resulting value.