*/
#include "precomp.h"
-#include <pseh/pseh2.h>
-
NTSTATUS IRPFinish( PIRP Irp, NTSTATUS Status ) {
KIRQL OldIrql;
PTRANSPORT_CONTEXT TranContext;
PFILE_OBJECT FileObject;
UCHAR MinorFunction;
+ PCONNECTION_ENDPOINT Connection;
BOOLEAN DequeuedIrp = TRUE;
IoReleaseCancelSpinLock(Irp->CancelIrql);
case TDI_CONNECT:
DequeuedIrp = TCPRemoveIRP(TranContext->Handle.ConnectionContext, Irp);
break;
+
+ case TDI_DISCONNECT:
+ Connection = (PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext;
+
+ DequeuedIrp = TCPRemoveIRP(TranContext->Handle.ConnectionContext, Irp);
+ if (DequeuedIrp)
+ {
+ if (KeCancelTimer(&Connection->DisconnectTimer))
+ {
+ DereferenceObject(Connection);
+ }
+ }
+ break;
default:
TI_DbgPrint(MIN_TRACE, ("Unknown IRP. MinorFunction (0x%X).\n", MinorFunction));
PTDI_REQUEST_KERNEL_ASSOCIATE Parameters;
PTRANSPORT_CONTEXT TranContext;
PIO_STACK_LOCATION IrpSp;
- PCONNECTION_ENDPOINT Connection;
+ PCONNECTION_ENDPOINT Connection, LastConnection;
PFILE_OBJECT FileObject;
PADDRESS_FILE AddrFile = NULL;
NTSTATUS Status;
/* Add connection endpoint to the address file */
ReferenceObject(Connection);
- AddrFile->Connection = Connection;
+ if (AddrFile->Connection == NULL)
+ AddrFile->Connection = Connection;
+ else
+ {
+ LastConnection = AddrFile->Connection;
+ while (LastConnection->Next != NULL)
+ LastConnection = LastConnection->Next;
+ LastConnection->Next = Connection;
+ }
- /* FIXME: Maybe do this in DispTdiDisassociateAddress() instead? */
ObDereferenceObject(FileObject);
UnlockObjectFromDpcLevel(AddrFile);
UnlockObject(Connection, OldIrql);
- return Status;
+ return STATUS_SUCCESS;
}
PCONNECTION_ENDPOINT Connection;
PTRANSPORT_CONTEXT TranContext;
PIO_STACK_LOCATION IrpSp;
- KIRQL OldIrql;
TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
return STATUS_INVALID_PARAMETER;
}
- LockObject(Connection, &OldIrql);
-
- if (!Connection->AddressFile) {
- UnlockObject(Connection, OldIrql);
- TI_DbgPrint(MID_TRACE, ("No address file is asscociated.\n"));
- return STATUS_INVALID_PARAMETER;
- }
-
- LockObjectAtDpcLevel(Connection->AddressFile);
-
- /* Remove this connection from the address file */
- DereferenceObject(Connection->AddressFile->Connection);
- Connection->AddressFile->Connection = NULL;
-
- UnlockObjectFromDpcLevel(Connection->AddressFile);
-
- /* Remove the address file from this connection */
- DereferenceObject(Connection->AddressFile);
- Connection->AddressFile = NULL;
-
- UnlockObject(Connection, OldIrql);
+ /* NO-OP because we need the address to deallocate the port when the connection closes */
return STATUS_SUCCESS;
}
Status = STATUS_INVALID_PARAMETER;
goto done;
}
+
+ Status = DispPrepareIrpForCancel
+ (TranContext->Handle.ConnectionContext,
+ Irp,
+ (PDRIVER_CANCEL)DispCancelRequest);
- Status = TCPDisconnect(
- TranContext->Handle.ConnectionContext,
- DisReq->RequestFlags,
- DisReq->RequestConnectionInformation,
- DisReq->ReturnConnectionInformation,
- DispDataRequestComplete,
- Irp );
+ if (NT_SUCCESS(Status))
+ {
+ Status = TCPDisconnect(TranContext->Handle.ConnectionContext,
+ DisReq->RequestFlags,
+ DisReq->RequestSpecific,
+ DisReq->RequestConnectionInformation,
+ DisReq->ReturnConnectionInformation,
+ DispDataRequestComplete,
+ Irp);
+ }
done:
if (Status != STATUS_PENDING) {
case TDI_CONNECTION_FILE:
Endpoint =
(PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext;
+
+ Address->TAAddressCount = 1;
+ Address->Address[0].AddressLength = TDI_ADDRESS_LENGTH_IP;
+ Address->Address[0].AddressType = TDI_ADDRESS_TYPE_IP;
+ Address->Address[0].Address[0].sin_port = Endpoint->AddressFile->Port;
+ Address->Address[0].Address[0].in_addr = Endpoint->AddressFile->Address.Address.IPv4Address;
RtlZeroMemory(
&Address->Address[0].Address[0].sin_zero,
sizeof(Address->Address[0].Address[0].sin_zero));
- return TCPGetSockAddress( Endpoint, (PTRANSPORT_ADDRESS)Address, FALSE );
+ return STATUS_SUCCESS;
default:
TI_DbgPrint(MIN_TRACE, ("Invalid transport context\n"));
case TDI_QUERY_CONNECTION_INFO:
{
- PTDI_CONNECTION_INFORMATION AddressInfo;
- PADDRESS_FILE AddrFile;
- PCONNECTION_ENDPOINT Endpoint = NULL;
+ PTDI_CONNECTION_INFO ConnectionInfo;
+ PCONNECTION_ENDPOINT Endpoint;
- if (MmGetMdlByteCount(Irp->MdlAddress) <
- (FIELD_OFFSET(TDI_CONNECTION_INFORMATION, RemoteAddress) +
- sizeof(PVOID))) {
- TI_DbgPrint(MID_TRACE, ("MDL buffer too small (ptr).\n"));
+ if (MmGetMdlByteCount(Irp->MdlAddress) < sizeof(*ConnectionInfo)) {
+ TI_DbgPrint(MID_TRACE, ("MDL buffer too small.\n"));
return STATUS_BUFFER_TOO_SMALL;
}
- AddressInfo = (PTDI_CONNECTION_INFORMATION)
+ ConnectionInfo = (PTDI_CONNECTION_INFO)
MmGetSystemAddressForMdl(Irp->MdlAddress);
switch ((ULONG_PTR)IrpSp->FileObject->FsContext2) {
- case TDI_TRANSPORT_ADDRESS_FILE:
- AddrFile = (PADDRESS_FILE)TranContext->Handle.AddressHandle;
- Endpoint = AddrFile ? AddrFile->Connection : NULL;
- break;
-
case TDI_CONNECTION_FILE:
Endpoint =
(PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext;
- break;
+ RtlZeroMemory(ConnectionInfo, sizeof(*ConnectionInfo));
+ return STATUS_SUCCESS;
default:
TI_DbgPrint(MIN_TRACE, ("Invalid transport context\n"));
return STATUS_INVALID_PARAMETER;
}
-
- if (!Endpoint) {
- TI_DbgPrint(MID_TRACE, ("No connection object.\n"));
- return STATUS_INVALID_PARAMETER;
- }
-
- return TCPGetSockAddress( Endpoint, AddressInfo->RemoteAddress, TRUE );
}
case TDI_QUERY_MAX_DATAGRAM_INFO:
{
- PTDI_MAX_DATAGRAM_INFO MaxDatagramInfo = MmGetSystemAddressForMdl(Irp->MdlAddress);
-
- MaxDatagramInfo->MaxDatagramSize = 0xFFFF;
-
- return STATUS_SUCCESS;
+ PTDI_MAX_DATAGRAM_INFO MaxDatagramInfo;
+
+ if (MmGetMdlByteCount(Irp->MdlAddress) < sizeof(*MaxDatagramInfo)) {
+ TI_DbgPrint(MID_TRACE, ("MDL buffer too small.\n"));
+ return STATUS_BUFFER_TOO_SMALL;
+ }
+
+ MaxDatagramInfo = (PTDI_MAX_DATAGRAM_INFO)
+ MmGetSystemAddressForMdl(Irp->MdlAddress);
+
+ MaxDatagramInfo->MaxDatagramSize = 0xFFFF;
+
+ return STATUS_SUCCESS;
}
}