- Forgot to commit these for MSVC build...
[reactos.git] / reactos / drivers / net / tcpip / tcpip / dispatch.c
index 0f25e9e..ced62e2 100644 (file)
@@ -10,7 +10,7 @@
  */
 
 #include "precomp.h"
-#include <pseh.h>
+#include <pseh/pseh.h>
 
 NTSTATUS DispPrepareIrpForCancel(
     PTRANSPORT_CONTEXT Context,
@@ -43,7 +43,7 @@ NTSTATUS DispPrepareIrpForCancel(
     }
 
     /* IRP has already been cancelled */
+
     IoReleaseCancelSpinLock(OldIrql);
 
     Irp->IoStatus.Status      = STATUS_CANCELLED;
@@ -66,7 +66,7 @@ VOID DispCancelComplete(
     /*KIRQL OldIrql;*/
     PFILE_OBJECT FileObject;
     PTRANSPORT_CONTEXT TranContext;
-    
+
     TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
 
     FileObject  = (PFILE_OBJECT)Context;
@@ -99,7 +99,7 @@ VOID DispDataRequestComplete(
     PTRANSPORT_CONTEXT TranContext;
     KIRQL OldIrql;
 
-    TI_DbgPrint(DEBUG_IRP, ("Called for irp %x (%x, %d).\n", 
+    TI_DbgPrint(DEBUG_IRP, ("Called for irp %x (%x, %d).\n",
                            Context, Status, Count));
 
     Irp         = Context;
@@ -135,8 +135,32 @@ VOID DispDataRequestComplete(
     TI_DbgPrint(DEBUG_IRP, ("Done Completing IRP\n"));
 }
 
+typedef struct _DISCONNECT_TYPE {
+    UINT Type;
+    PVOID Context;
+    PIRP Irp;
+    PFILE_OBJECT FileObject;
+} DISCONNECT_TYPE, *PDISCONNECT_TYPE;
+
+VOID DispDoDisconnect( PVOID Data ) {
+    PDISCONNECT_TYPE DisType = (PDISCONNECT_TYPE)Data;
+
+    TI_DbgPrint(DEBUG_IRP, ("PostCancel: DoDisconnect\n"));
+    TCPDisconnect
+       ( DisType->Context,
+         DisType->Type,
+         NULL,
+         NULL,
+         DispDataRequestComplete,
+         DisType->Irp );
+    TI_DbgPrint(DEBUG_IRP, ("PostCancel: DoDisconnect done\n"));
+
+    DispDataRequestComplete(DisType->Irp, STATUS_CANCELLED, 0);
+
+    DispCancelComplete(DisType->FileObject);
+}
 
-VOID DDKAPI DispCancelRequest(
+VOID NTAPI DispCancelRequest(
     PDEVICE_OBJECT Device,
     PIRP Irp)
 /*
@@ -150,6 +174,8 @@ VOID DDKAPI DispCancelRequest(
     PTRANSPORT_CONTEXT TranContext;
     PFILE_OBJECT FileObject;
     UCHAR MinorFunction;
+    DISCONNECT_TYPE DisType;
+    PVOID WorkItem;
     /*NTSTATUS Status = STATUS_SUCCESS;*/
 
     TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
@@ -161,6 +187,8 @@ VOID DDKAPI DispCancelRequest(
 
     TI_DbgPrint(DEBUG_IRP, ("IRP at (0x%X)  MinorFunction (0x%X)  IrpSp (0x%X).\n", Irp, MinorFunction, IrpSp));
 
+    Irp->IoStatus.Status = STATUS_PENDING;
+
 #ifdef DBG
     if (!Irp->Cancel)
         TI_DbgPrint(MIN_TRACE, ("Irp->Cancel is FALSE, should be TRUE.\n"));
@@ -169,26 +197,22 @@ VOID DDKAPI DispCancelRequest(
     /* Try canceling the request */
     switch(MinorFunction) {
     case TDI_SEND:
-        TCPDisconnect
-            ( TranContext->Handle.ConnectionContext,
-              TDI_DISCONNECT_RELEASE,
-              NULL,
-              NULL,
-              DispDataRequestComplete,
-              Irp );
-        break;
-
     case TDI_RECEIVE:
-        TCPDisconnect
-            ( TranContext->Handle.ConnectionContext,
-              TDI_DISCONNECT_ABORT | TDI_DISCONNECT_RELEASE,
-              NULL,
-              NULL,
-              DispDataRequestComplete,
-              Irp );
+       DisType.Type = TDI_DISCONNECT_RELEASE | 
+           ((MinorFunction == TDI_RECEIVE) ? TDI_DISCONNECT_ABORT : 0);
+       DisType.Context = TranContext->Handle.ConnectionContext;
+       DisType.Irp = Irp;
+       DisType.FileObject = FileObject;
+       
+       TCPRemoveIRP( TranContext->Handle.ConnectionContext, Irp );
+
+       if( !ChewCreate( &WorkItem, sizeof(DISCONNECT_TYPE), 
+                        DispDoDisconnect, &DisType ) )
+           ASSERT(0);
         break;
 
     case TDI_SEND_DATAGRAM:
+       Irp->IoStatus.Status = STATUS_CANCELLED;
         if (FileObject->FsContext2 != (PVOID)TDI_TRANSPORT_ADDRESS_FILE) {
             TI_DbgPrint(MIN_TRACE, ("TDI_SEND_DATAGRAM, but no address file.\n"));
             break;
@@ -198,6 +222,7 @@ VOID DDKAPI DispCancelRequest(
         break;
 
     case TDI_RECEIVE_DATAGRAM:
+       Irp->IoStatus.Status = STATUS_CANCELLED;
         if (FileObject->FsContext2 != (PVOID)TDI_TRANSPORT_ADDRESS_FILE) {
             TI_DbgPrint(MIN_TRACE, ("TDI_RECEIVE_DATAGRAM, but no address file.\n"));
             break;
@@ -211,15 +236,16 @@ VOID DDKAPI DispCancelRequest(
         break;
     }
 
+    if( Irp->IoStatus.Status == STATUS_PENDING )
+       IoMarkIrpPending(Irp);
+
     IoReleaseCancelSpinLock(Irp->CancelIrql);
-    
-    DispCancelComplete(FileObject);
 
     TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
 }
 
 
-VOID DDKAPI DispCancelListenRequest(
+VOID NTAPI DispCancelListenRequest(
     PDEVICE_OBJECT Device,
     PIRP Irp)
 /*
@@ -258,7 +284,7 @@ VOID DDKAPI DispCancelListenRequest(
     IoReleaseCancelSpinLock(Irp->CancelIrql);
 
     DispDataRequestComplete(Irp, STATUS_CANCELLED, 0);
-    
+
     DispCancelComplete(FileObject);
 
     TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
@@ -414,7 +440,7 @@ NTSTATUS DispTdiConnect(
       Parameters->ReturnConnectionInformation,
       DispDataRequestComplete,
       Irp );
-  
+
   TI_DbgPrint(MAX_TRACE, ("TCP Connect returned %08x\n", Status));
 
   return Status;
@@ -504,7 +530,7 @@ NTSTATUS DispTdiDisconnect(
       DisReq->ReturnConnectionInformation,
       DispDataRequestComplete,
       Irp );
-  
+
   TI_DbgPrint(MAX_TRACE, ("TCP Connect returned %08x\n", Status));
 
   return Status;
@@ -549,7 +575,7 @@ NTSTATUS DispTdiListen(
 
   Parameters = (PTDI_REQUEST_KERNEL)&IrpSp->Parameters;
 
-  TI_DbgPrint(MIN_TRACE, ("Connection->AddressFile: %x\n", 
+  TI_DbgPrint(MIN_TRACE, ("Connection->AddressFile: %x\n",
                          Connection->AddressFile ));
   if( Connection->AddressFile ) {
       TI_DbgPrint(MIN_TRACE, ("Connection->AddressFile->Listener: %x\n",
@@ -562,16 +588,16 @@ NTSTATUS DispTdiListen(
   /* The important thing to note here is that the irp we'll complete belongs
    * to the socket to be accepted onto, not the listener */
   if( !Connection->AddressFile->Listener ) {
-      Connection->AddressFile->Listener = 
+      Connection->AddressFile->Listener =
          TCPAllocateConnectionEndpoint( NULL );
 
-      if( !Connection->AddressFile->Listener ) 
+      if( !Connection->AddressFile->Listener )
          Status = STATUS_NO_MEMORY;
 
       if( NT_SUCCESS(Status) ) {
-         Connection->AddressFile->Listener->AddressFile = 
+         Connection->AddressFile->Listener->AddressFile =
              Connection->AddressFile;
-         
+
          Status = TCPSocket( Connection->AddressFile->Listener,
                              Connection->AddressFile->Family,
                              SOCK_STREAM,
@@ -579,19 +605,19 @@ NTSTATUS DispTdiListen(
       }
 
       if( NT_SUCCESS(Status) )
-         Status = TCPListen( Connection->AddressFile->Listener, 1024 ); 
+         Status = TCPListen( Connection->AddressFile->Listener, 1024 );
          /* BACKLOG */
   }
   if( NT_SUCCESS(Status) ) {
       Status = DispPrepareIrpForCancel
-          (TranContext->Handle.ConnectionContext, 
-           Irp, 
+          (TranContext->Handle.ConnectionContext,
+           Irp,
            (PDRIVER_CANCEL)DispCancelListenRequest);
   }
 
   if( NT_SUCCESS(Status) ) {
       Status = TCPAccept
-         ( (PTDI_REQUEST)Parameters, 
+         ( (PTDI_REQUEST)Parameters,
            Connection->AddressFile->Listener,
            Connection,
            DispDataRequestComplete,
@@ -647,7 +673,7 @@ NTSTATUS DispTdiQueryInformation(
             break;
 
           case TDI_CONNECTION_FILE:
-            AddrFile = 
+            AddrFile =
               ((PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext)->
               AddressFile;
             break;
@@ -674,8 +700,8 @@ NTSTATUS DispTdiQueryInformation(
         Address->Address[0].AddressLength = TDI_ADDRESS_LENGTH_IP;
         Address->Address[0].AddressType = TDI_ADDRESS_TYPE_IP;
         Address->Address[0].Address[0].sin_port = AddrFile->Port;
-        Address->Address[0].Address[0].in_addr = 
-          AddrFile->Address.Address.IPv4Address;        
+        Address->Address[0].Address[0].in_addr =
+          AddrFile->Address.Address.IPv4Address;
         RtlZeroMemory(
           &Address->Address[0].Address[0].sin_zero,
           sizeof(Address->Address[0].Address[0].sin_zero));
@@ -698,7 +724,7 @@ NTSTATUS DispTdiQueryInformation(
             break;
 
           case TDI_CONNECTION_FILE:
-            Endpoint = 
+            Endpoint =
               (PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext;
             break;
 
@@ -763,8 +789,8 @@ NTSTATUS DispTdiReceive(
 
   /* Initialize a receive request */
   Status = DispPrepareIrpForCancel
-      (TranContext->Handle.ConnectionContext, 
-       Irp, 
+      (TranContext->Handle.ConnectionContext,
+       Irp,
        (PDRIVER_CANCEL)DispCancelRequest);
 
   TI_DbgPrint(MID_TRACE,("TCPIP<<< Got an MDL: %x\n", Irp->MdlAddress));
@@ -872,15 +898,15 @@ NTSTATUS DispTdiSend(
  */
 {
   PIO_STACK_LOCATION IrpSp;
-  PTDI_REQUEST_KERNEL_RECEIVE ReceiveInfo;
+  PTDI_REQUEST_KERNEL_SEND SendInfo;
   PTRANSPORT_CONTEXT TranContext;
   NTSTATUS Status;
-  ULONG BytesReceived;
+  ULONG BytesSent;
 
   TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
 
   IrpSp = IoGetCurrentIrpStackLocation(Irp);
-  ReceiveInfo = (PTDI_REQUEST_KERNEL_RECEIVE)&(IrpSp->Parameters);
+  SendInfo = (PTDI_REQUEST_KERNEL_SEND)&(IrpSp->Parameters);
 
   TranContext = IrpSp->FileObject->FsContext;
   if (TranContext == NULL)
@@ -907,18 +933,20 @@ NTSTATUS DispTdiSend(
        UINT Len;
 
        NdisQueryBuffer( Irp->MdlAddress, &Data, &Len );
-       
+
        TI_DbgPrint(MID_TRACE,("About to TCPSendData\n"));
        Status = TCPSendData(
            TranContext->Handle.ConnectionContext,
            Data,
-           ReceiveInfo->ReceiveLength,
-           &BytesReceived,
-           ReceiveInfo->ReceiveFlags);
+           SendInfo->SendLength,
+           &BytesSent,
+           SendInfo->SendFlags,
+           DispDataRequestComplete,
+           Irp);
        if (Status != STATUS_PENDING)
        {
-           DispDataRequestComplete(Irp, Status, BytesReceived);
-       } else 
+           DispDataRequestComplete(Irp, Status, BytesSent);
+       } else
            IoMarkIrpPending( Irp );
     }
 
@@ -963,22 +991,22 @@ NTSTATUS DispTdiSendDatagram(
     if (NT_SUCCESS(Status)) {
        PCHAR DataBuffer;
        UINT BufferSize;
-       
+
        TI_DbgPrint(MID_TRACE,("About to query buffer %x\n", Irp->MdlAddress));
 
        NdisQueryBuffer( (PNDIS_BUFFER)Irp->MdlAddress,
                         &DataBuffer,
                         &BufferSize );
-       
-        /* FIXME: DgramInfo->SendDatagramInformation->RemoteAddress 
+
+        /* FIXME: DgramInfo->SendDatagramInformation->RemoteAddress
            must be of type PTDI_ADDRESS_IP */
        TI_DbgPrint(MID_TRACE,
-                   ("About to call send routine %x\n", 
+                   ("About to call send routine %x\n",
                     (*((PADDRESS_FILE)Request.Handle.AddressHandle)->Send)));
-       
-        if( (*((PADDRESS_FILE)Request.Handle.AddressHandle)->Send) ) 
+
+        if( (*((PADDRESS_FILE)Request.Handle.AddressHandle)->Send) )
             Status = (*((PADDRESS_FILE)Request.Handle.AddressHandle)->Send)(
-                Request.Handle.AddressHandle, 
+                Request.Handle.AddressHandle,
                 DgramInfo->SendDatagramInformation,
                 DataBuffer,
                 BufferSize,
@@ -1037,7 +1065,7 @@ NTSTATUS DispTdiSetEventHandler(PIRP Irp)
 
   Parameters = (PTDI_REQUEST_KERNEL_SET_EVENT)&IrpSp->Parameters;
   Status     = STATUS_SUCCESS;
-  
+
   TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql);
 
   /* Set the event handler. if an event handler is associated with
@@ -1344,7 +1372,7 @@ NTSTATUS DispTdiQueryInformationEx(
             ExFreePool(QueryContext);
         } else
             Status = STATUS_INSUFFICIENT_RESOURCES;
-    } else if( InputBufferLength == 
+    } else if( InputBufferLength ==
               sizeof(TCP_REQUEST_QUERY_INFORMATION_EX) ) {
        /* Handle the case where the user is probing the buffer for length */
        TI_DbgPrint(MAX_TRACE, ("InputBufferLength %d OutputBufferLength %d\n",
@@ -1364,7 +1392,7 @@ NTSTATUS DispTdiQueryInformationEx(
 
            MmProbeAndLockPages(InputMdl, Irp->RequestorMode,
                                IoModifyAccess);
-           
+
            InputMdlLocked = TRUE;
            Status = STATUS_SUCCESS;
        } _SEH_HANDLE {
@@ -1388,9 +1416,9 @@ NTSTATUS DispTdiQueryInformationEx(
        Request.RequestNotifyObject = DispTdiQueryInformationExComplete;
        Request.RequestContext      = QueryContext;
        Status = InfoTdiQueryInformationEx(&Request,
-                                          &QueryContext->QueryInfo.ID, 
+                                          &QueryContext->QueryInfo.ID,
                                           NULL,
-                                          &Size, 
+                                          &Size,
                                           &QueryContext->QueryInfo.Context);
        DispTdiQueryInformationExComplete(QueryContext, Status, Size);
        TI_DbgPrint(MAX_TRACE, ("Leaving. Status = (0x%X)\n", Status));
@@ -1473,7 +1501,7 @@ NTSTATUS DispTdiSetInformationEx(
 
 NTSTATUS DispTdiSetIPAddress( PIRP Irp, PIO_STACK_LOCATION IrpSp ) {
     NTSTATUS Status = STATUS_DEVICE_DOES_NOT_EXIST;
-    PIP_SET_ADDRESS IpAddrChange = 
+    PIP_SET_ADDRESS IpAddrChange =
         (PIP_SET_ADDRESS)Irp->AssociatedIrp.SystemBuffer;
     IF_LIST_ITER(IF);
 
@@ -1483,10 +1511,20 @@ NTSTATUS DispTdiSetIPAddress( PIRP Irp, PIO_STACK_LOCATION IrpSp ) {
             break;
         }
         if( IF->Index == IpAddrChange->NteIndex ) {
+            IPRemoveInterfaceRoute( IF );
+
             IF->Unicast.Type = IP_ADDRESS_V4;
             IF->Unicast.Address.IPv4Address = IpAddrChange->Address;
             IF->Netmask.Type = IP_ADDRESS_V4;
             IF->Netmask.Address.IPv4Address = IpAddrChange->Netmask;
+
+            TI_DbgPrint(MID_TRACE,("New Unicast Address: %x\n",
+                                   IF->Unicast.Address.IPv4Address));
+            TI_DbgPrint(MID_TRACE,("New Netmask        : %x\n",
+                                   IF->Netmask.Address.IPv4Address));
+
+            IPAddInterfaceRoute( IF );
+
             IpAddrChange->Address = IF->Index;
             Status = STATUS_SUCCESS;
             Irp->IoStatus.Information = IF->Index;