[ros-diffs] [arty] 39687: - Our code was a bit confused about close vs cleanup irps in tcpip. We now interpret and implement them both properly, preparing for close in cleanup then actually deallocating in close. - AFD should have been keeping extra references to TCP resources, because the handles will be closed by the handle sweeper at process shutdown. - Fix failure cases for pendable TCP requests and add SEL_FIN when a socket is closed at oskit, but closing up at tcpip.sys. - Fix some breakage from my previous commit re: bind the zero address. We now ask the connection for the right address if we are one, and plumb the request all the way to tcp, which is deciding what adapter to send to anyway. - Fix one error code in udp, properly reporting network unreachable.

arty at svn.reactos.org arty at svn.reactos.org
Thu Feb 19 21:14:39 CET 2009


Author: arty
Date: Thu Feb 19 14:14:39 2009
New Revision: 39687

URL: http://svn.reactos.org/svn/reactos?rev=39687&view=rev
Log:
 - Our code was a bit confused about close vs cleanup irps in tcpip.  We now
   interpret and implement them both properly, preparing for close in cleanup
   then actually deallocating in close.
 - AFD should have been keeping extra references to TCP resources, because 
   the handles will be closed by the handle sweeper at process shutdown.
 - Fix failure cases for pendable TCP requests and add SEL_FIN when a socket
   is closed at oskit, but closing up at tcpip.sys.
 - Fix some breakage from my previous commit re: bind the zero address.  We 
   now ask the connection for the right address if we are one, and plumb 
   the request all the way to tcp, which is deciding what adapter to send to
   anyway.
 - Fix one error code in udp, properly reporting network unreachable.

Modified:
    trunk/reactos/dll/win32/msafd/misc/dllmain.c
    trunk/reactos/drivers/network/afd/afd/bind.c
    trunk/reactos/drivers/network/afd/afd/connect.c
    trunk/reactos/drivers/network/afd/afd/info.c
    trunk/reactos/drivers/network/afd/afd/main.c
    trunk/reactos/drivers/network/afd/afd/read.c
    trunk/reactos/drivers/network/tcpip/include/fileobjs.h
    trunk/reactos/drivers/network/tcpip/include/tcp.h
    trunk/reactos/drivers/network/tcpip/tcpip/dispatch.c
    trunk/reactos/drivers/network/tcpip/tcpip/fileobjs.c
    trunk/reactos/drivers/network/tcpip/tcpip/main.c
    trunk/reactos/lib/drivers/ip/transport/tcp/tcp.c
    trunk/reactos/lib/drivers/ip/transport/udp/udp.c

Modified: trunk/reactos/dll/win32/msafd/misc/dllmain.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msafd/misc/dllmain.c?rev=39687&r1=39686&r2=39687&view=diff
==============================================================================
--- trunk/reactos/dll/win32/msafd/misc/dllmain.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/msafd/misc/dllmain.c [iso-8859-1] Thu Feb 19 14:14:39 2009
@@ -351,6 +351,10 @@
             DbgPrint("MSAFD: STATUS_INVALID_PARAMETER\n");
             *Errno = WSAEINVAL;
             break;
+		case STATUS_CANCELLED:
+			DbgPrint("MSAFD: STATUS_CANCELLED\n");
+			*Errno = WSAENOTSOCK;
+			break;
         default:
             DbgPrint("MSAFD: Error %x is unknown\n", Status);
             *Errno = WSAEINVAL;

Modified: trunk/reactos/drivers/network/afd/afd/bind.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/afd/afd/bind.c?rev=39687&r1=39686&r2=39687&view=diff
==============================================================================
--- trunk/reactos/drivers/network/afd/afd/bind.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/network/afd/afd/bind.c [iso-8859-1] Thu Feb 19 14:14:39 2009
@@ -32,6 +32,11 @@
                                 FCB->LocalAddress,
                                 &FCB->AddressFile.Handle,
                                 &FCB->AddressFile.Object );
+
+	if (NT_SUCCESS(Status)) 
+	{
+		ObReferenceObject(FCB->AddressFile.Object);
+	}
 
     AFD_DbgPrint(MID_TRACE,("Returning %x\n", Status));
 

Modified: trunk/reactos/drivers/network/afd/afd/connect.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/afd/afd/connect.c?rev=39687&r1=39686&r2=39687&view=diff
==============================================================================
--- trunk/reactos/drivers/network/afd/afd/connect.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/network/afd/afd/connect.c [iso-8859-1] Thu Feb 19 14:14:39 2009
@@ -29,6 +29,11 @@
                                           FCB->Connection.Object );
     }
 
+	if (NT_SUCCESS(Status)) 
+	{
+		ObReferenceObject(FCB->Connection.Object);
+	}
+
     return Status;
 }
 

Modified: trunk/reactos/drivers/network/afd/afd/info.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/afd/afd/info.c?rev=39687&r1=39686&r2=39687&view=diff
==============================================================================
--- trunk/reactos/drivers/network/afd/afd/info.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/network/afd/afd/info.c [iso-8859-1] Thu Feb 19 14:14:39 2009
@@ -110,7 +110,8 @@
                 }
 
                 Status = TdiQueryInformation
-                    ( FCB->AddressFile.Object,
+                    ( FCB->Connection.Object ? 
+					  FCB->Connection.Object : FCB->AddressFile.Object,
                       TDI_QUERY_ADDRESS_INFO,
                       Mdl );
             } else {

Modified: trunk/reactos/drivers/network/afd/afd/main.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/afd/afd/main.c?rev=39687&r1=39686&r2=39687&view=diff
==============================================================================
--- trunk/reactos/drivers/network/afd/afd/main.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/network/afd/afd/main.c [iso-8859-1] Thu Feb 19 14:14:39 2009
@@ -224,11 +224,16 @@
     if( FCB->TdiDeviceName.Buffer )
 	ExFreePool(FCB->TdiDeviceName.Buffer);
 
-    /* HACK HACK HACK */
-    TdiCloseDevice( FCB->Connection.Handle,
-		    FCB->Connection.Object );
-    TdiCloseDevice( FCB->AddressFile.Handle,
-		    FCB->AddressFile.Object );
+	if (FCB->Connection.Object)
+	{
+		NtClose(FCB->Connection.Handle);
+		ObDereferenceObject(FCB->Connection.Object);
+	}
+	if (FCB->AddressFile.Object)
+	{
+		NtClose(FCB->AddressFile.Handle);
+		ObDereferenceObject(FCB->AddressFile.Object);
+	}
 
     ExFreePool(FCB);
     AFD_DbgPrint(MIN_TRACE,("Deleted (%x)\n", FCB));

Modified: trunk/reactos/drivers/network/afd/afd/read.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/afd/afd/read.c?rev=39687&r1=39686&r2=39687&view=diff
==============================================================================
--- trunk/reactos/drivers/network/afd/afd/read.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/network/afd/afd/read.c [iso-8859-1] Thu Feb 19 14:14:39 2009
@@ -34,7 +34,8 @@
 }
 
 static VOID HandleEOFOnIrp( PAFD_FCB FCB, NTSTATUS Status, UINT Information ) {
-    if( Status == STATUS_SUCCESS && Information == 0 ) {
+    if( !NT_SUCCESS(Status) || 
+		(Status == STATUS_SUCCESS && Information == 0) ) {
         AFD_DbgPrint(MID_TRACE,("Looks like an EOF\n"));
         FCB->PollState |= AFD_EVENT_DISCONNECT;
         PollReeval( FCB->DeviceExt, FCB->FileObject );
@@ -259,10 +260,10 @@
 
     HandleEOFOnIrp( FCB, Irp->IoStatus.Status, Irp->IoStatus.Information );
 
-    ReceiveActivity( FCB, NULL );
-
-    PollReeval( FCB->DeviceExt, FCB->FileObject );
-
+	ReceiveActivity( FCB, NULL );
+
+	PollReeval( FCB->DeviceExt, FCB->FileObject );
+		
     SocketStateUnlock( FCB );
 
     AFD_DbgPrint(MID_TRACE,("Returned %x\n", Status));

Modified: trunk/reactos/drivers/network/tcpip/include/fileobjs.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/tcpip/include/fileobjs.h?rev=39687&r1=39686&r2=39687&view=diff
==============================================================================
--- trunk/reactos/drivers/network/tcpip/include/fileobjs.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/network/tcpip/include/fileobjs.h [iso-8859-1] Thu Feb 19 14:14:39 2009
@@ -23,6 +23,9 @@
 NTSTATUS FileCloseAddress(
   PTDI_REQUEST Request);
 
+NTSTATUS FileFreeAddress(
+  PTDI_REQUEST Request);
+
 NTSTATUS FileOpenConnection(
   PTDI_REQUEST Request,
   PVOID ClientContext);
@@ -32,10 +35,13 @@
 NTSTATUS FileCloseConnection(
   PTDI_REQUEST Request);
 
+NTSTATUS FileFreeConnection(
+  PTDI_REQUEST Request);
+
 NTSTATUS FileOpenControlChannel(
   PTDI_REQUEST Request);
 
-NTSTATUS FileCloseControlChannel(
+NTSTATUS FileFreeControlChannel(
   PTDI_REQUEST Request);
 
 #endif /* __FILEOBJS_H */

Modified: trunk/reactos/drivers/network/tcpip/include/tcp.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/tcpip/include/tcp.h?rev=39687&r1=39686&r2=39687&view=diff
==============================================================================
--- trunk/reactos/drivers/network/tcpip/include/tcp.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/network/tcpip/include/tcp.h [iso-8859-1] Thu Feb 19 14:14:39 2009
@@ -170,9 +170,10 @@
 
 VOID TCPFreePort( UINT Port );
 
-NTSTATUS TCPGetPeerAddress
+NTSTATUS TCPGetSockAddress
 ( PCONNECTION_ENDPOINT Connection,
-  PTRANSPORT_ADDRESS TransportAddress );
+  PTRANSPORT_ADDRESS TransportAddress,
+  BOOLEAN RemoteAddress );
 
 NTSTATUS TCPStartup(
   VOID);

Modified: trunk/reactos/drivers/network/tcpip/tcpip/dispatch.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/tcpip/tcpip/dispatch.c?rev=39687&r1=39686&r2=39687&view=diff
==============================================================================
--- trunk/reactos/drivers/network/tcpip/tcpip/dispatch.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/network/tcpip/tcpip/dispatch.c [iso-8859-1] Thu Feb 19 14:14:39 2009
@@ -671,19 +671,34 @@
         PTDI_ADDRESS_INFO AddressInfo;
         PADDRESS_FILE AddrFile;
         PTA_IP_ADDRESS Address;
+        PCONNECTION_ENDPOINT Endpoint = NULL;
 
         AddressInfo = (PTDI_ADDRESS_INFO)MmGetSystemAddressForMdl(Irp->MdlAddress);
+		Address = (PTA_IP_ADDRESS)&AddressInfo->Address;
 
         switch ((ULONG)IrpSp->FileObject->FsContext2) {
           case TDI_TRANSPORT_ADDRESS_FILE:
             AddrFile = (PADDRESS_FILE)TranContext->Handle.AddressHandle;
-            break;
+
+			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 = AddrFile->Port;
+			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));
+			return STATUS_SUCCESS;
 
           case TDI_CONNECTION_FILE:
-            AddrFile =
-              ((PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext)->
-              AddressFile;
-            break;
+            Endpoint =
+				(PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext;
+			TCPGetSockAddress( Endpoint, (PTRANSPORT_ADDRESS)Address, FALSE );
+			DbgPrint("Returning socket address %x\n", Address->Address[0].Address[0].in_addr);
+			RtlZeroMemory(
+				&Address->Address[0].Address[0].sin_zero,
+				sizeof(Address->Address[0].Address[0].sin_zero));
+			return STATUS_SUCCESS;
 
           default:
             TI_DbgPrint(MIN_TRACE, ("Invalid transport context\n"));
@@ -702,17 +717,6 @@
           return STATUS_BUFFER_OVERFLOW;
         }
 
-        Address = (PTA_IP_ADDRESS)&AddressInfo->Address;
-        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 = AddrFile->Port;
-        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));
-
         return STATUS_SUCCESS;
       }
 
@@ -752,7 +756,7 @@
           return STATUS_BUFFER_OVERFLOW;
         }
 
-        return TCPGetPeerAddress( Endpoint, AddressInfo->RemoteAddress );
+        return TCPGetSockAddress( Endpoint, AddressInfo->RemoteAddress, TRUE );
       }
   }
 

Modified: trunk/reactos/drivers/network/tcpip/tcpip/fileobjs.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/tcpip/tcpip/fileobjs.c?rev=39687&r1=39686&r2=39687&view=diff
==============================================================================
--- trunk/reactos/drivers/network/tcpip/tcpip/fileobjs.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/network/tcpip/tcpip/fileobjs.c [iso-8859-1] Thu Feb 19 14:14:39 2009
@@ -204,28 +204,6 @@
 
 
 /*
- * FUNCTION: Deletes a connection endpoint file object
- * ARGUMENTS:
- *     Connection = Pointer to connection endpoint to delete
- */
-VOID DeleteConnectionEndpoint(
-  PCONNECTION_ENDPOINT Connection)
-{
-  KIRQL OldIrql;
-
-  TI_DbgPrint(MID_TRACE, ("Called.\n"));
-
-  /* Remove connection endpoint from the global list */
-  TcpipAcquireSpinLock(&ConnectionEndpointListLock, &OldIrql);
-  RemoveEntryList(&Connection->ListEntry);
-  TcpipReleaseSpinLock(&ConnectionEndpointListLock, OldIrql);
-
-  TCPFreeConnectionEndpoint(Connection);
-
-  TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
-}
-
-/*
  * FUNCTION: Open an address file object
  * ARGUMENTS:
  *     Request  = Pointer to TDI request structure for this request
@@ -395,6 +373,29 @@
     break;
   }
 
+  TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
+
+  return Status;
+}
+
+
+/*
+ * FUNCTION: Closes an address file object
+ * ARGUMENTS:
+ *     Request = Pointer to TDI request structure for this request
+ * RETURNS:
+ *     Status of operation
+ */
+NTSTATUS FileFreeAddress(
+  PTDI_REQUEST Request)
+{
+  PADDRESS_FILE AddrFile;
+  NTSTATUS Status = STATUS_SUCCESS;
+
+  AddrFile = Request->Handle.AddressHandle;
+
+  TI_DbgPrint(MID_TRACE, ("Called.\n"));
+
   DeleteAddress(AddrFile);
 
   TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
@@ -493,8 +494,37 @@
   Connection = Request->Handle.ConnectionContext;
 
   TcpipRecursiveMutexEnter( &TCPLock, TRUE );
-  DeleteConnectionEndpoint(Connection);
+  TCPClose( Connection );
   TcpipRecursiveMutexLeave( &TCPLock );
+
+  TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
+
+  return STATUS_SUCCESS;
+}
+
+
+/*
+ * FUNCTION: Frees an connection file object
+ * ARGUMENTS:
+ *     Request = Pointer to TDI request structure for this request
+ * RETURNS:
+ *     Status of operation
+ */
+NTSTATUS FileFreeConnection(
+  PTDI_REQUEST Request)
+{
+  KIRQL OldIrql;
+  PCONNECTION_ENDPOINT Connection;
+
+  TI_DbgPrint(MID_TRACE, ("Called.\n"));
+
+  Connection = Request->Handle.ConnectionContext;
+
+  TcpipAcquireSpinLock(&ConnectionEndpointListLock, &OldIrql);
+  RemoveEntryList(&Connection->ListEntry);
+  TcpipReleaseSpinLock(&ConnectionEndpointListLock, OldIrql);
+
+  TCPFreeConnectionEndpoint(Connection);
 
   TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
 
@@ -549,7 +579,7 @@
  * RETURNS:
  *     Status of operation
  */
-NTSTATUS FileCloseControlChannel(
+NTSTATUS FileFreeControlChannel(
   PTDI_REQUEST Request)
 {
   PCONTROL_CHANNEL ControlChannel = Request->Handle.ControlChannel;

Modified: trunk/reactos/drivers/network/tcpip/tcpip/main.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/tcpip/tcpip/main.c?rev=39687&r1=39686&r2=39687&view=diff
==============================================================================
--- trunk/reactos/drivers/network/tcpip/tcpip/main.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/network/tcpip/tcpip/main.c [iso-8859-1] Thu Feb 19 14:14:39 2009
@@ -253,7 +253,7 @@
 }
 
 /*
- * FUNCTION: Releases resources used by a file object
+ * FUNCTION: Prepares a file object for close
  * ARGUMENTS:
  *     DeviceObject = Pointer to a device object for this driver
  *     Irp          = Pointer to a I/O request packet
@@ -298,7 +298,76 @@
 
   case TDI_CONTROL_CHANNEL_FILE:
     Request.Handle.ControlChannel = Context->Handle.ControlChannel;
-    Status = FileCloseControlChannel(&Request);
+	/* Nothing to do to close */
+	Status = STATUS_SUCCESS;
+    break;
+
+  default:
+    /* This should never happen */
+
+    TI_DbgPrint(MIN_TRACE, ("Unknown transport context.\n"));
+
+    IoAcquireCancelSpinLock(&OldIrql);
+    Context->CancelIrps = FALSE;
+    IoReleaseCancelSpinLock(OldIrql);
+
+    Status = STATUS_INVALID_PARAMETER;
+
+  }
+
+  Irp->IoStatus.Status = Status;
+
+  return Irp->IoStatus.Status;
+}
+
+
+/*
+ * FUNCTION: Releases resources used by a file object
+ * ARGUMENTS:
+ *     DeviceObject = Pointer to a device object for this driver
+ *     Irp          = Pointer to a I/O request packet
+ * RETURNS:
+ *     Status of the operation
+ * NOTES:
+ *     This function does not pend
+ */
+NTSTATUS TiCloseFileObject(
+  PDEVICE_OBJECT DeviceObject,
+  PIRP Irp)
+{
+  PIO_STACK_LOCATION IrpSp;
+  PTRANSPORT_CONTEXT Context;
+  TDI_REQUEST Request;
+  NTSTATUS Status;
+  KIRQL OldIrql;
+
+  IrpSp   = IoGetCurrentIrpStackLocation(Irp);
+  Context = IrpSp->FileObject->FsContext;
+  if (!Context) {
+    TI_DbgPrint(MIN_TRACE, ("Parameters are invalid.\n"));
+    return STATUS_INVALID_PARAMETER;
+  }
+
+  IoAcquireCancelSpinLock(&OldIrql);
+
+  Context->CancelIrps = TRUE;
+
+  IoReleaseCancelSpinLock(OldIrql);
+
+  switch ((ULONG_PTR)IrpSp->FileObject->FsContext2) {
+  case TDI_TRANSPORT_ADDRESS_FILE:
+    Request.Handle.AddressHandle = Context->Handle.AddressHandle;
+    Status = FileFreeAddress(&Request);
+    break;
+
+  case TDI_CONNECTION_FILE:
+    Request.Handle.ConnectionContext = Context->Handle.ConnectionContext;
+    Status = FileFreeConnection(&Request);
+    break;
+
+  case TDI_CONTROL_CHANNEL_FILE:
+    Request.Handle.ControlChannel = Context->Handle.ControlChannel;
+    Status = FileFreeControlChannel(&Request);
     break;
 
   default:
@@ -352,9 +421,7 @@
   /* Close an address file, connection endpoint, or control connection */
   case IRP_MJ_CLOSE:
     Context = (PTRANSPORT_CONTEXT)IrpSp->FileObject->FsContext;
-    if (Context)
-        exFreePool(Context);
-    Status = STATUS_SUCCESS;
+	Status = TiCloseFileObject(DeviceObject, Irp);
     break;
 
   /* Release resources bound to an address file, connection endpoint,

Modified: trunk/reactos/lib/drivers/ip/transport/tcp/tcp.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/ip/transport/tcp/tcp.c?rev=39687&r1=39686&r2=39687&view=diff
==============================================================================
--- trunk/reactos/lib/drivers/ip/transport/tcp/tcp.c [iso-8859-1] (original)
+++ trunk/reactos/lib/drivers/ip/transport/tcp/tcp.c [iso-8859-1] Thu Feb 19 14:14:39 2009
@@ -42,7 +42,7 @@
             Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
             Complete = Bucket->Request.RequestNotifyObject;
             TI_DbgPrint(DEBUG_TCP,
-                        ("Completing Request %x\n", Bucket->Request));
+                        ("Completing Request %x\n", Bucket->Request.RequestContext));
 
             if( (NewState & (SEL_CONNECT | SEL_FIN)) ==
                 (SEL_CONNECT | SEL_FIN) )
@@ -158,7 +158,7 @@
     }
     if( NewState & SEL_WRITE ) {
 		TI_DbgPrint(DEBUG_TCP,("Writeable: irp list %s\n",
-							   IsListEmpty(&Connection->ReceiveRequest) ?
+							   IsListEmpty(&Connection->SendRequest) ?
 							   "empty" : "nonempty"));
 
 		while( !IsListEmpty( &Connection->SendRequest ) ) {
@@ -282,7 +282,7 @@
 }
 
 VOID TCPFreeConnectionEndpoint( PCONNECTION_ENDPOINT Connection ) {
-    TCPClose( Connection );
+	TI_DbgPrint(DEBUG_TCP, ("Freeing TCP Endpoint\n"));
     exFreePool( Connection );
 }
 
@@ -542,25 +542,29 @@
     IP_ADDRESS RemoteAddress;
     USHORT RemotePort;
     PTDI_BUCKET Bucket;
+	PNEIGHBOR_CACHE_ENTRY NCE;
 
     TI_DbgPrint(DEBUG_TCP,("TCPConnect: Called\n"));
-
-    Bucket = exAllocatePool( NonPagedPool, sizeof(*Bucket) );
-    if( !Bucket ) return STATUS_NO_MEMORY;
-
-    TcpipRecursiveMutexEnter( &TCPLock, TRUE );
-
-    /* Freed in TCPSocketState */
-    Bucket->Request.RequestNotifyObject = (PVOID)Complete;
-    Bucket->Request.RequestContext = Context;
-
-    InsertHeadList( &Connection->ConnectRequest, &Bucket->Entry );
 
     Status = AddrBuildAddress
 		((PTRANSPORT_ADDRESS)ConnInfo->RemoteAddress,
 		 &RemoteAddress,
 		 &RemotePort);
 
+	if (!(NCE = RouteGetRouteToDestination(&RemoteAddress)))
+	{
+		return STATUS_NETWORK_UNREACHABLE;
+	}
+
+    TcpipRecursiveMutexEnter( &TCPLock, TRUE );
+
+	if (Connection->State & SEL_FIN)
+	{
+		TcpipRecursiveMutexLeave( &TCPLock );
+		return STATUS_REMOTE_DISCONNECT;
+	}
+
+    /* Freed in TCPSocketState */
     TI_DbgPrint(DEBUG_TCP,
                 ("Connecting to address %x:%x\n",
                  RemoteAddress.Address.IPv4Address,
@@ -574,6 +578,7 @@
 
     AddressToConnect.sin_family = AF_INET;
     AddressToBind = AddressToConnect;
+	AddressToBind.sin_addr.s_addr = NCE->Interface->Unicast.Address.IPv4Address;
 
     Status = TCPTranslateError
         ( OskitTCPBind( Connection->SocketContext,
@@ -592,6 +597,17 @@
 							   Connection,
 							   &AddressToConnect,
 							   sizeof(AddressToConnect) ) );
+
+		if (Status == STATUS_PENDING)
+		{
+			Bucket = exAllocatePool( NonPagedPool, sizeof(*Bucket) );
+			if( !Bucket ) return STATUS_NO_MEMORY;
+			
+			Bucket->Request.RequestNotifyObject = (PVOID)Complete;
+			Bucket->Request.RequestContext = Context;
+			
+			InsertHeadList( &Connection->ConnectRequest, &Bucket->Entry );
+		}
     }
 
     TcpipRecursiveMutexLeave( &TCPLock );
@@ -678,6 +694,14 @@
 
     TcpipRecursiveMutexEnter( &TCPLock, TRUE );
 
+	/* Closing */
+	if (Connection->State & SEL_FIN)
+	{
+		TcpipRecursiveMutexLeave( &TCPLock );
+		*BytesReceived = 0;
+		return STATUS_REMOTE_DISCONNECT;
+	}
+
     NdisQueryBuffer( Buffer, &DataBuffer, &DataLen );
 
     TI_DbgPrint(DEBUG_TCP,("TCP>|< Got an MDL %x (%x:%d)\n", Buffer, DataBuffer, DataLen));
@@ -706,7 +730,7 @@
 		Bucket->Request.RequestContext = Context;
 		*BytesReceived = 0;
 
-		InsertHeadList( &Connection->ReceiveRequest, &Bucket->Entry );
+		InsertTailList( &Connection->ReceiveRequest, &Bucket->Entry );
 		Status = STATUS_PENDING;
 		TI_DbgPrint(DEBUG_TCP,("Queued read irp\n"));
     } else {
@@ -744,6 +768,14 @@
     TI_DbgPrint(DEBUG_TCP,("Connection->SocketContext = %x\n",
 						   Connection->SocketContext));
 
+	/* Closing */
+	if (Connection->State & SEL_FIN)
+	{
+		TcpipRecursiveMutexLeave( &TCPLock );
+		*BytesSent = 0;
+		return STATUS_REMOTE_DISCONNECT;
+	}
+
     Status = TCPTranslateError
 		( OskitTCPSend( Connection->SocketContext,
 						(OSK_PCHAR)BufferData, SendLength,
@@ -760,20 +792,20 @@
 			TcpipRecursiveMutexLeave( &TCPLock );
 			return STATUS_NO_MEMORY;
 		}
-
+		
 		Bucket->Request.RequestNotifyObject = Complete;
 		Bucket->Request.RequestContext = Context;
 		*BytesSent = 0;
-
-		InsertHeadList( &Connection->SendRequest, &Bucket->Entry );
+		
+		InsertTailList( &Connection->SendRequest, &Bucket->Entry );
 		TI_DbgPrint(DEBUG_TCP,("Queued write irp\n"));
     } else {
 		TI_DbgPrint(DEBUG_TCP,("Got status %x, bytes %d\n", Status, Sent));
 		*BytesSent = Sent;
     }
-
+	
     TcpipRecursiveMutexLeave( &TCPLock );
-
+	
     TI_DbgPrint(DEBUG_TCP,("Status %x\n", Status));
 
     return Status;
@@ -798,9 +830,10 @@
     DeallocatePort( &TCPPorts, Port );
 }
 
-NTSTATUS TCPGetPeerAddress
+NTSTATUS TCPGetSockAddress
 ( PCONNECTION_ENDPOINT Connection,
-  PTRANSPORT_ADDRESS Address ) {
+  PTRANSPORT_ADDRESS Address,
+  BOOLEAN GetRemote ) {
     OSK_UINT LocalAddress, RemoteAddress;
     OSK_UI16 LocalPort, RemotePort;
     PTA_IP_ADDRESS AddressIP = (PTA_IP_ADDRESS)Address;
@@ -815,8 +848,9 @@
     AddressIP->TAAddressCount = 1;
     AddressIP->Address[0].AddressLength = TDI_ADDRESS_LENGTH_IP;
     AddressIP->Address[0].AddressType = TDI_ADDRESS_TYPE_IP;
-    AddressIP->Address[0].Address[0].sin_port = RemotePort;
-    AddressIP->Address[0].Address[0].in_addr = RemoteAddress;
+    AddressIP->Address[0].Address[0].sin_port = GetRemote ? RemotePort : LocalPort;
+    AddressIP->Address[0].Address[0].in_addr = GetRemote ? RemoteAddress : LocalAddress;
+	AddressIP->Address[1].AddressLength = TDI_ADDRESS_LENGTH_IP;
 
     TcpipRecursiveMutexLeave( &TCPLock );
 
@@ -837,13 +871,15 @@
 
     TcpipAcquireSpinLock( &Endpoint->Lock, &OldIrql );
 
-    for( i = 0; i < 4; i++ ) {
+    for( i = 0; i < 4; i++ )
+	{
 		for( Entry = ListHead[i]->Flink;
 			 Entry != ListHead[i];
-			 Entry = Entry->Flink ) {
+			 Entry = Entry->Flink )
+		{
 			Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
-
-			if( Bucket->Request.RequestContext == Irp ) {
+			if( Bucket->Request.RequestContext == Irp )
+			{
 				RemoveEntryList( &Bucket->Entry );
 				exFreePool( Bucket );
 				break;

Modified: trunk/reactos/lib/drivers/ip/transport/udp/udp.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/ip/transport/udp/udp.c?rev=39687&r1=39686&r2=39687&view=diff
==============================================================================
--- trunk/reactos/lib/drivers/ip/transport/udp/udp.c [iso-8859-1] (original)
+++ trunk/reactos/lib/drivers/ip/transport/udp/udp.c [iso-8859-1] Thu Feb 19 14:14:39 2009
@@ -185,7 +185,7 @@
     }
 
     if(!(NCE = RouteGetRouteToDestination( &RemoteAddress ))) {
-		return STATUS_UNSUCCESSFUL;
+		return STATUS_NETWORK_UNREACHABLE;
     }
 
 	LocalAddress = AddrFile->Address;



More information about the Ros-diffs mailing list