[TCPIP]
[reactos.git] / reactos / drivers / network / tcpip / tcpip / dispatch.c
index f216ed5..65e0f96 100644 (file)
@@ -10,8 +10,6 @@
  */
 
 #include "precomp.h"
-#include <pseh/pseh2.h>
-
 
 NTSTATUS IRPFinish( PIRP Irp, NTSTATUS Status ) {
     KIRQL OldIrql;
@@ -122,6 +120,7 @@ VOID NTAPI DispCancelRequest(
     PTRANSPORT_CONTEXT TranContext;
     PFILE_OBJECT FileObject;
     UCHAR MinorFunction;
+    PCONNECTION_ENDPOINT Connection;
     BOOLEAN DequeuedIrp = TRUE;
 
     IoReleaseCancelSpinLock(Irp->CancelIrql);
@@ -171,6 +170,19 @@ VOID NTAPI DispCancelRequest(
     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));
@@ -259,7 +271,7 @@ NTSTATUS DispTdiAssociateAddress(
   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;
@@ -340,15 +352,22 @@ NTSTATUS DispTdiAssociateAddress(
 
   /* 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;
 }
 
 
@@ -428,7 +447,6 @@ NTSTATUS DispTdiDisassociateAddress(
   PCONNECTION_ENDPOINT Connection;
   PTRANSPORT_CONTEXT TranContext;
   PIO_STACK_LOCATION IrpSp;
-  KIRQL OldIrql;
 
   TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
 
@@ -448,27 +466,7 @@ NTSTATUS DispTdiDisassociateAddress(
     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;
 }
@@ -510,14 +508,22 @@ NTSTATUS DispTdiDisconnect(
     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) {
@@ -705,10 +711,16 @@ NTSTATUS DispTdiQueryInformation(
           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"));
@@ -718,51 +730,45 @@ NTSTATUS DispTdiQueryInformation(
 
     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;
      }
   }