Hello,
I have a strange behaviour with connection acceptance after the driver
returns from ClientEventConnect() function.
For ConnectionContext parameter, the NT4 DDK says:
“Points to a caller-supplied variable in which ClientEventConnect returns
a pointer to the client’s context area in which it maintains
client-determined state for this connection endpoint. Usually, the
specified address is identical to the value that the client set for the
value at EaBuffer when it originally called ZwCreateFile to open the local
connection endpoint.”
I created the connection endpoint with EAValue set to my own context.
However when I set *ConnectionContext=“pointer to my context”, the
completion routine is called with STATUS_INVALID_CONNECTION though if I
set *ConnectionContext with a pointer to the driver object (the same as
in DriverEntry), the connection is accepted with STATUS_SUCCESS.
Could someone help me to understand this behaviour ? Is the DDK
documentation inaccurate or is it me who have not understood the text ?
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; // return value
PTA_ADDRESS Address; // transport address
PTDI_ADDRESS_IP Ip; // host IP address
PDEVICE_EXTENSION Extension; // my device context
PDEVICE_OBJECT TargetDevice; // target device (tcpip.sys)
PIRP Irp; // Accept IRP
Extension=(PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
// Check source address
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==Extension->AdresseIp && Extension->Connected==FALSE)
{
// Connection approved: IRP building
TargetDevice=IoGetRelatedDeviceObject(Extension->Connection.Object);
Irp=IoAllocateIrp(TargetDevice->StackSize,FALSE);
if(Irp!=NULL)
{
Extension->ConnectIrp.IoStatus.Status=STATUS_SUCCESS;
Extension->ConnectIrp.IoStatus.Information=0;
Irp->UserIosb=&Extension->ConnectIrp.IoStatus;
Irp->UserEvent=&Extension->ConnectIrp.Event;
TdiBuildAccept(Irp,
TargetDevice,
Extension->Connection.Object,
ConnectEventComplete,// completion routine is
below
Extension,
Extension->ConnectIrp.PtrInfo,
NULL);
IoSetNextIrpStackLocation(Irp);
*ConnectionContext=Extension->DriverObject;
// *ConnectionContext=Extension; I get STATUS_INVALID_CONNECTION
*AcceptIrp=Irp;
Status=STATUS_MORE_PROCESSING_REQUIRED;
}
else
{
// not enough memory
*AcceptIrp=NULL;
*ConnectionContext=NULL;
Status=STATUS_INSUFFICIENT_RESOURCES;
}
}
else
{
// filtered address
*AcceptIrp=NULL;
*ConnectionContext=NULL;
Status=STATUS_CONNECTION_REFUSED;
}
}
else
{
// Invalid source address
*AcceptIrp=NULL;
*ConnectionContext=NULL;
Status=STATUS_CONNECTION_REFUSED;
}
return Status;
}
NTSTATUS ConnectEventComplete(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,IN PVOID Context)
{
PDEVICE_EXTENSION Extension=(PDEVICE_EXTENSION)Context;
if(Irp->IoStatus.Status==STATUS_SUCCESS)
{
Extension->Connected=TRUE;
Extension->DataReceived=FALSE;
}
IoFreeIrp(Irp);
return STATUS_MORE_PROCESSING_REQUIRED;
}