[ros-diffs] [cgutman] 52186: [AFD] - Rewrite user-mode request locking to fix several bugs - IRP_MJ_READ and IRP_MJ_WRITE doesn't crash - Revert the IoModifyAccess change (the Write parameter was relevant to t...

cgutman at svn.reactos.org cgutman at svn.reactos.org
Sat Jun 11 12:46:05 UTC 2011


Author: cgutman
Date: Sat Jun 11 12:46:04 2011
New Revision: 52186

URL: http://svn.reactos.org/svn/reactos?rev=52186&view=rev
Log:
[AFD]
- Rewrite user-mode request locking to fix several bugs
- IRP_MJ_READ and IRP_MJ_WRITE doesn't crash
- Revert the IoModifyAccess change (the Write parameter was relevant to the buffer not the request)
- Use GetLockedData to retrieve a locked buffer instead of accessing it manually
- Lock several requests which were not locked and could cause a crash
- ASSERT that the in flight request is the IRP being completed
- Fix a socket closure bug so shutdown(SO_SEND) will not prevent packets being received
- Don't count bytes used in the receive content
- Don't free the datagram buffer if it is a peek request
- Requeue the datagram buffer at the head of the list if it is a peek request
- Fix a bug which could cause corrupted data to be received if multiple datagrams come in before the app receives them 
- Make sure that we're not overwriting an existing in flight request when creating a new one
- Perform an implicit bind in AfdPacketSocketWriteData if it is not already bound
- Implement batching several user-mode send IRPs into one TDI request (if there is already one pending)
- Fix a potential crash if a connectionless send IRP is cancelled

Modified:
    trunk/reactos/drivers/network/afd/afd/connect.c
    trunk/reactos/drivers/network/afd/afd/context.c
    trunk/reactos/drivers/network/afd/afd/info.c
    trunk/reactos/drivers/network/afd/afd/listen.c
    trunk/reactos/drivers/network/afd/afd/lock.c
    trunk/reactos/drivers/network/afd/afd/main.c
    trunk/reactos/drivers/network/afd/afd/read.c
    trunk/reactos/drivers/network/afd/afd/tdi.c
    trunk/reactos/drivers/network/afd/afd/write.c
    trunk/reactos/drivers/network/afd/include/afd.h

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=52186&r1=52185&r2=52186&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] Sat Jun 11 12:46:04 2011
@@ -43,10 +43,13 @@
 {
     PFILE_OBJECT FileObject = IrpSp->FileObject;
     PAFD_FCB FCB = FileObject->FsContext;
-    PVOID ConnectOptions = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
+    PVOID ConnectOptions = LockRequest(Irp, IrpSp);
     UINT ConnectOptionsSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
 
     if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
+    
+    if (!ConnectOptions)
+        return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
 
     if (FCB->ConnectOptions)
     {
@@ -75,10 +78,13 @@
 {
     PFILE_OBJECT FileObject = IrpSp->FileObject;
     PAFD_FCB FCB = FileObject->FsContext;
-    PUINT ConnectOptionsSize = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
+    PUINT ConnectOptionsSize = LockRequest(Irp, IrpSp);
     UINT BufferSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
 
     if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
+    
+    if (!ConnectOptionsSize)
+        return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
 
     if (BufferSize < sizeof(UINT))
         return UnlockAndMaybeComplete(FCB, STATUS_BUFFER_TOO_SMALL, Irp, 0);
@@ -129,10 +135,13 @@
 {
     PFILE_OBJECT FileObject = IrpSp->FileObject;
     PAFD_FCB FCB = FileObject->FsContext;
-    PVOID ConnectData = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
+    PVOID ConnectData = LockRequest(Irp, IrpSp);
     UINT ConnectDataSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
 
     if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
+    
+    if (!ConnectData)
+        return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
 
     if (FCB->ConnectData)
     {
@@ -161,11 +170,14 @@
 {
     PFILE_OBJECT FileObject = IrpSp->FileObject;
     PAFD_FCB FCB = FileObject->FsContext;
-    PUINT ConnectDataSize = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
+    PUINT ConnectDataSize = LockRequest(Irp, IrpSp);
     UINT BufferSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
 
     if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
 
+    if (!ConnectDataSize)
+        return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
+    
     if (BufferSize < sizeof(UINT))
         return UnlockAndMaybeComplete(FCB, STATUS_BUFFER_TOO_SMALL, Irp, 0);
 
@@ -274,6 +286,7 @@
     AFD_DbgPrint(MID_TRACE,("Irp->IoStatus.Status = %x\n",
 			    Irp->IoStatus.Status));
 
+    ASSERT(FCB->ConnectIrp.InFlightRequest == Irp);
     FCB->ConnectIrp.InFlightRequest = NULL;
 
     if( FCB->State == SOCKET_STATE_CLOSED ) {

Modified: trunk/reactos/drivers/network/afd/afd/context.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/afd/afd/context.c?rev=52186&r1=52185&r2=52186&view=diff
==============================================================================
--- trunk/reactos/drivers/network/afd/afd/context.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/network/afd/afd/context.c [iso-8859-1] Sat Jun 11 12:46:04 2011
@@ -54,14 +54,18 @@
 
     return UnlockAndMaybeComplete(FCB, STATUS_SUCCESS, Irp, sizeof(ULONG));
 }
-        
+
 NTSTATUS NTAPI
 AfdSetContext( PDEVICE_OBJECT DeviceObject, PIRP Irp,
 	       PIO_STACK_LOCATION IrpSp ) {
     PFILE_OBJECT FileObject = IrpSp->FileObject;
     PAFD_FCB FCB = FileObject->FsContext;
+    PVOID Context = LockRequest(Irp, IrpSp);
 
     if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );
+    
+    if (!Context)
+        return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
 
     if( FCB->Context ) {
 	ExFreePool( FCB->Context );
@@ -76,7 +80,7 @@
     FCB->ContextSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
 
     RtlCopyMemory( FCB->Context,
-		   IrpSp->Parameters.DeviceIoControl.Type3InputBuffer,
+		   Context,
 		   FCB->ContextSize );
 
     return UnlockAndMaybeComplete( FCB, STATUS_SUCCESS, Irp, 0 );

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=52186&r1=52185&r2=52186&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] Sat Jun 11 12:46:04 2011
@@ -17,7 +17,7 @@
 AfdGetInfo( PDEVICE_OBJECT DeviceObject, PIRP Irp,
 	    PIO_STACK_LOCATION IrpSp ) {
     NTSTATUS Status = STATUS_SUCCESS;
-    PAFD_INFO InfoReq = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
+    PAFD_INFO InfoReq = LockRequest(Irp, IrpSp);
     PFILE_OBJECT FileObject = IrpSp->FileObject;
     PAFD_FCB FCB = FileObject->FsContext;
     PLIST_ENTRY CurrentEntry;
@@ -26,6 +26,9 @@
 			    InfoReq ? InfoReq->InformationClass : 0));
 
     if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );
+    
+    if (!InfoReq)
+        return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
 
     _SEH2_TRY {
 	switch( InfoReq->InformationClass ) {
@@ -67,10 +70,6 @@
 	         CurrentEntry = CurrentEntry->Flink;
 	    }
 
-	    /* Count the send in progress */
-	    if (FCB->SendIrp.InFlightRequest)
-	        InfoReq->Information.Ulong++;
-
             break;
 
 	default:
@@ -93,11 +92,14 @@
 AfdSetInfo( PDEVICE_OBJECT DeviceObject, PIRP Irp,
             PIO_STACK_LOCATION IrpSp ) {
     NTSTATUS Status = STATUS_SUCCESS;
-    PAFD_INFO InfoReq = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
+    PAFD_INFO InfoReq = LockRequest(Irp, IrpSp);
     PFILE_OBJECT FileObject = IrpSp->FileObject;
     PAFD_FCB FCB = FileObject->FsContext;
 
     if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
+    
+    if (!InfoReq)
+        return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
 
     _SEH2_TRY {
       switch (InfoReq->InformationClass) {

Modified: trunk/reactos/drivers/network/afd/afd/listen.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/afd/afd/listen.c?rev=52186&r1=52185&r2=52186&view=diff
==============================================================================
--- trunk/reactos/drivers/network/afd/afd/listen.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/network/afd/afd/listen.c [iso-8859-1] Sat Jun 11 12:46:04 2011
@@ -101,6 +101,7 @@
     if( !SocketAcquireStateLock( FCB ) )
         return STATUS_FILE_CLOSED;
 
+    ASSERT(FCB->ListenIrp.InFlightRequest == Irp);
     FCB->ListenIrp.InFlightRequest = NULL;
 
     if( FCB->State == SOCKET_STATE_CLOSED ) {

Modified: trunk/reactos/drivers/network/afd/afd/lock.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/afd/afd/lock.c?rev=52186&r1=52185&r2=52186&view=diff
==============================================================================
--- trunk/reactos/drivers/network/afd/afd/lock.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/network/afd/afd/lock.c [iso-8859-1] Sat Jun 11 12:46:04 2011
@@ -13,49 +13,85 @@
 #include "debug.h"
 #include "pseh/pseh2.h"
 
+PVOID GetLockedData(PIRP Irp, PIO_STACK_LOCATION IrpSp)
+{
+    ASSERT(Irp->MdlAddress);
+    
+    return MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
+}
+
 /* Lock a method_neither request so it'll be available from DISPATCH_LEVEL */
 PVOID LockRequest( PIRP Irp, PIO_STACK_LOCATION IrpSp ) {
     BOOLEAN LockFailed = FALSE;
-
-    ASSERT(IrpSp->Parameters.DeviceIoControl.Type3InputBuffer);
-    ASSERT(IrpSp->Parameters.DeviceIoControl.InputBufferLength);
+    
     ASSERT(!Irp->MdlAddress);
-
-    Irp->MdlAddress =
-	IoAllocateMdl( IrpSp->Parameters.DeviceIoControl.Type3InputBuffer,
-		       IrpSp->Parameters.DeviceIoControl.InputBufferLength,
-		       FALSE,
-		       FALSE,
-		       NULL );
-    if( Irp->MdlAddress ) {
-	_SEH2_TRY {
-	    MmProbeAndLockPages( Irp->MdlAddress, Irp->RequestorMode, IoModifyAccess );
-	} _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
-	    LockFailed = TRUE;
-	} _SEH2_END;
-
-	if( LockFailed ) {
-	    IoFreeMdl( Irp->MdlAddress );
-	    Irp->MdlAddress = NULL;
-	    return NULL;
-	}
-
-	IrpSp->Parameters.DeviceIoControl.Type3InputBuffer =
-	    MmGetSystemAddressForMdlSafe( Irp->MdlAddress, NormalPagePriority );
-
-	if( !IrpSp->Parameters.DeviceIoControl.Type3InputBuffer ) {
-            MmUnlockPages( Irp->MdlAddress );
-	    IoFreeMdl( Irp->MdlAddress );
-	    Irp->MdlAddress = NULL;
-	    return NULL;
-	}
-
-	return IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
-    } else return NULL;
+    
+    switch (IrpSp->MajorFunction)
+    {
+        case IRP_MJ_DEVICE_CONTROL:
+        case IRP_MJ_INTERNAL_DEVICE_CONTROL:
+            ASSERT(IrpSp->Parameters.DeviceIoControl.Type3InputBuffer);
+            ASSERT(IrpSp->Parameters.DeviceIoControl.InputBufferLength);
+
+            
+            Irp->MdlAddress =
+            IoAllocateMdl( IrpSp->Parameters.DeviceIoControl.Type3InputBuffer,
+                          IrpSp->Parameters.DeviceIoControl.InputBufferLength,
+                          FALSE,
+                          FALSE,
+                          NULL );
+            if( Irp->MdlAddress ) {
+                _SEH2_TRY {
+                    MmProbeAndLockPages( Irp->MdlAddress, Irp->RequestorMode, IoModifyAccess );
+                } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
+                    LockFailed = TRUE;
+                } _SEH2_END;
+                
+                if( LockFailed ) {
+                    IoFreeMdl( Irp->MdlAddress );
+                    Irp->MdlAddress = NULL;
+                    return NULL;
+                }
+            } else return NULL;
+            break;
+            
+        case IRP_MJ_READ:
+        case IRP_MJ_WRITE:
+            ASSERT(Irp->UserBuffer);
+            
+            Irp->MdlAddress =
+            IoAllocateMdl(Irp->UserBuffer,
+                          (IrpSp->MajorFunction == IRP_MJ_READ) ?
+                                IrpSp->Parameters.Read.Length : IrpSp->Parameters.Write.Length,
+                          FALSE,
+                          FALSE,
+                          NULL );
+            if( Irp->MdlAddress ) {
+                _SEH2_TRY {
+                    MmProbeAndLockPages( Irp->MdlAddress, Irp->RequestorMode, IoModifyAccess );
+                } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
+                    LockFailed = TRUE;
+                } _SEH2_END;
+                
+                if( LockFailed ) {
+                    IoFreeMdl( Irp->MdlAddress );
+                    Irp->MdlAddress = NULL;
+                    return NULL;
+                }
+            } else return NULL;
+            break;
+            
+        default:
+            ASSERT(FALSE);
+            return NULL;
+    }
+    
+    return GetLockedData(Irp, IrpSp);
 }
 
 VOID UnlockRequest( PIRP Irp, PIO_STACK_LOCATION IrpSp )
 {
+    ASSERT(Irp->MdlAddress);
     MmUnlockPages( Irp->MdlAddress );
     IoFreeMdl( Irp->MdlAddress );
     Irp->MdlAddress = NULL;
@@ -123,7 +159,7 @@
 		AFD_DbgPrint(MID_TRACE,("Probe and lock pages\n"));
 		_SEH2_TRY {
 		    MmProbeAndLockPages( MapBuf[i].Mdl, KernelMode,
-				         Write ? IoReadAccess : IoModifyAccess );
+				         Write ? IoModifyAccess : IoReadAccess );
 		} _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
 		    LockFailed = TRUE;
 		} _SEH2_END;

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=52186&r1=52185&r2=52186&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] Sat Jun 11 12:46:04 2011
@@ -72,10 +72,13 @@
 {
     PFILE_OBJECT FileObject = IrpSp->FileObject;
     PAFD_FCB FCB = FileObject->FsContext;
-    PVOID DisconnectOptions = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
+    PVOID DisconnectOptions = LockRequest(Irp, IrpSp);
     UINT DisconnectOptionsSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
 
     if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
+    
+    if (!DisconnectOptions)
+        return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
 
     if (FCB->DisconnectOptions)
     {
@@ -104,10 +107,13 @@
 {
     PFILE_OBJECT FileObject = IrpSp->FileObject;
     PAFD_FCB FCB = FileObject->FsContext;
-    PUINT DisconnectOptionsSize = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
+    PUINT DisconnectOptionsSize = LockRequest(Irp, IrpSp);
     UINT BufferSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
 
     if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
+    
+    if (!DisconnectOptionsSize)
+        return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
 
     if (BufferSize < sizeof(UINT))
         return UnlockAndMaybeComplete(FCB, STATUS_BUFFER_TOO_SMALL, Irp, 0);
@@ -158,10 +164,13 @@
 {
     PFILE_OBJECT FileObject = IrpSp->FileObject;
     PAFD_FCB FCB = FileObject->FsContext;
-    PVOID DisconnectData = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
+    PVOID DisconnectData = LockRequest(Irp, IrpSp);
     UINT DisconnectDataSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
 
     if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
+    
+    if (!DisconnectData)
+        return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
 
     if (FCB->DisconnectData)
     {
@@ -190,10 +199,13 @@
 {
     PFILE_OBJECT FileObject = IrpSp->FileObject;
     PAFD_FCB FCB = FileObject->FsContext;
-    PUINT DisconnectDataSize = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
+    PUINT DisconnectDataSize = LockRequest(Irp, IrpSp);
     UINT BufferSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
 
     if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
+    
+    if (!DisconnectDataSize)
+        return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
 
     if (BufferSize < sizeof(UINT))
         return UnlockAndMaybeComplete(FCB, STATUS_BUFFER_TOO_SMALL, Irp, 0);
@@ -219,10 +231,13 @@
 {
     PFILE_OBJECT FileObject = IrpSp->FileObject;
     PAFD_FCB FCB = FileObject->FsContext;
-    PULONG HandleFlags = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
+    PULONG HandleFlags = LockRequest(Irp, IrpSp);
     PAFD_TDI_HANDLE_DATA HandleData = Irp->UserBuffer;
 
     if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
+    
+    if (!HandleFlags)
+        return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
 
     if (IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(ULONG) ||
         IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(*HandleData))
@@ -535,6 +550,12 @@
     if( !(DisReq = LockRequest( Irp, IrpSp )) )
 	return UnlockAndMaybeComplete( FCB, STATUS_NO_MEMORY,
 				       Irp, 0 );
+    
+    if( DisReq->DisconnectType & AFD_DISCONNECT_SEND )
+	    Flags |= TDI_DISCONNECT_RELEASE;
+    if( DisReq->DisconnectType & AFD_DISCONNECT_RECV ||
+       DisReq->DisconnectType & AFD_DISCONNECT_ABORT )
+	    Flags |= TDI_DISCONNECT_ABORT;
 
     if (!(FCB->Flags & AFD_ENDPOINT_CONNECTIONLESS))
     {
@@ -550,12 +571,6 @@
         if( !NT_SUCCESS(Status) )
 	    return UnlockAndMaybeComplete( FCB, Status,
 				           Irp, 0 );
-
-        if( DisReq->DisconnectType & AFD_DISCONNECT_SEND )
-	    Flags |= TDI_DISCONNECT_RELEASE;
-        if( DisReq->DisconnectType & AFD_DISCONNECT_RECV ||
-	    DisReq->DisconnectType & AFD_DISCONNECT_ABORT )
-	    Flags |= TDI_DISCONNECT_ABORT;
 
         FCB->ConnectInfo->UserData = FCB->DisconnectData;
         FCB->ConnectInfo->UserDataLength = FCB->DisconnectDataSize;
@@ -591,11 +606,25 @@
 
         ExFreePool( ConnectionReturnInfo );
 
-        FCB->PollState |= AFD_EVENT_DISCONNECT;
+        if (Flags & TDI_DISCONNECT_RELEASE)
+            FCB->PollState |= AFD_EVENT_DISCONNECT;
+        else
+            FCB->PollState |= AFD_EVENT_ABORT;
         FCB->PollStatus[FD_CLOSE_BIT] = STATUS_SUCCESS;
         PollReeval( FCB->DeviceExt, FCB->FileObject );
-    } else
-        Status = STATUS_INVALID_PARAMETER;
+    }
+    else
+    {
+        if (!(Flags & TDI_DISCONNECT_RELEASE))
+        {
+            if (!FCB->RemoteAddress)
+                return UnlockAndMaybeComplete(FCB, STATUS_INVALID_PARAMETER, Irp, 0);
+        
+            ExFreePool(FCB->RemoteAddress);
+        
+            FCB->RemoteAddress = NULL;
+        }
+    }
 
     return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
 }
@@ -784,7 +813,7 @@
 }
 
 VOID
-CleanupPendingIrp(PIRP Irp, PIO_STACK_LOCATION IrpSp, PAFD_ACTIVE_POLL Poll)
+CleanupPendingIrp(PAFD_FCB FCB, PIRP Irp, PIO_STACK_LOCATION IrpSp, PAFD_ACTIVE_POLL Poll)
 {
     PAFD_RECV_INFO RecvReq;
     PAFD_SEND_INFO SendReq;
@@ -793,13 +822,14 @@
     if (IrpSp->Parameters.DeviceIoControl.IoControlCode == IOCTL_AFD_RECV ||
         IrpSp->MajorFunction == IRP_MJ_READ)
     {
-        RecvReq = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
+        RecvReq = GetLockedData(Irp, IrpSp);
         UnlockBuffers(RecvReq->BufferArray, RecvReq->BufferCount, FALSE);
     }
-    else if (IrpSp->Parameters.DeviceIoControl.IoControlCode == IOCTL_AFD_SEND ||
-             IrpSp->MajorFunction == IRP_MJ_WRITE)
-    {
-        SendReq = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
+    else if ((IrpSp->Parameters.DeviceIoControl.IoControlCode == IOCTL_AFD_SEND ||
+              IrpSp->MajorFunction == IRP_MJ_WRITE) &&
+             !(FCB->Flags & AFD_ENDPOINT_CONNECTIONLESS))
+    {
+        SendReq = GetLockedData(Irp, IrpSp);
         UnlockBuffers(SendReq->BufferArray, SendReq->BufferCount, FALSE);
     }
     else if (IrpSp->Parameters.DeviceIoControl.IoControlCode == IOCTL_AFD_SELECT)
@@ -879,7 +909,7 @@
 
             if (Irp == Poll->Irp)
             {
-                CleanupPendingIrp(Irp, IrpSp, Poll);
+                CleanupPendingIrp(FCB, Irp, IrpSp, Poll);
                 KeReleaseSpinLock(&DeviceExt->Lock, OldIrql);
                 SocketStateUnlock(FCB);
                 return;
@@ -911,7 +941,7 @@
         if (CurrentIrp == Irp)
         {
             RemoveEntryList(CurrentEntry);
-            CleanupPendingIrp(Irp, IrpSp, NULL);
+            CleanupPendingIrp(FCB, Irp, IrpSp, NULL);
             UnlockAndMaybeComplete(FCB, STATUS_CANCELLED, Irp, 0);
             return;
         }

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=52186&r1=52185&r2=52186&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] Sat Jun 11 12:46:04 2011
@@ -32,7 +32,7 @@
 	   ( !NT_SUCCESS( Status ) ) )
 	{
 		/* The socket has been closed */
-		FCB->PollState |= AFD_EVENT_DISCONNECT;
+		FCB->PollState |= AFD_EVENT_CLOSE;
 		FCB->PollStatus[FD_CLOSE_BIT] = Status;
 		
 		PollReeval( FCB->DeviceExt, FCB->FileObject );
@@ -43,7 +43,7 @@
     UINT BytesAvailable = FCB->Recv.Content - FCB->Recv.BytesUsed;
 	
     return !BytesAvailable &&
-	(FCB->PollState & (AFD_EVENT_CLOSE | AFD_EVENT_DISCONNECT));
+	(FCB->PollState & (AFD_EVENT_CLOSE | AFD_EVENT_ABORT));
 }
 
 static VOID RefillSocketBuffer( PAFD_FCB FCB ) {
@@ -60,20 +60,10 @@
 							 &FCB->ReceiveIrp.Iosb,
 							 ReceiveComplete,
 							 FCB );
-
-        if( Status == STATUS_SUCCESS && FCB->ReceiveIrp.Iosb.Information )
+        if (Status != STATUS_PENDING)
         {
-            FCB->Recv.Content = FCB->ReceiveIrp.Iosb.Information;
-            FCB->PollState |= AFD_EVENT_RECEIVE;
-            FCB->PollStatus[FD_READ_BIT] = STATUS_SUCCESS;
-			
-			PollReeval( FCB->DeviceExt, FCB->FileObject );
+            HandleEOFOnIrp(FCB, Status, FCB->ReceiveIrp.Iosb.Information);
         }
-		else
-		{
-			/* Check for EOF */
-			HandleEOFOnIrp(FCB, Status, FCB->ReceiveIrp.Iosb.Information);
-		}
 	}
 }
 
@@ -166,7 +156,7 @@
             NextIrp =
 			CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
             NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp );
-            RecvReq = NextIrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
+            RecvReq = GetLockedData(NextIrp, NextIrpSp);
 			
             AFD_DbgPrint(MID_TRACE,("Completing recv %x (%d)\n", NextIrp,
                                     TotalBytesCopied));
@@ -196,7 +186,7 @@
 			NextIrp =
 			CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
 			NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp );
-			RecvReq = NextIrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
+			RecvReq = GetLockedData(NextIrp, NextIrpSp);
 			
 			AFD_DbgPrint(MID_TRACE,("RecvReq @ %x\n", RecvReq));
 			
@@ -226,7 +216,7 @@
 		}
     }
 
-    if( FCB->Recv.Content ) {
+    if( FCB->Recv.Content - FCB->Recv.BytesUsed ) {
 		FCB->PollState |= AFD_EVENT_RECEIVE;
         FCB->PollStatus[FD_READ_BIT] = STATUS_SUCCESS;
         PollReeval( FCB->DeviceExt, FCB->FileObject );
@@ -259,6 +249,7 @@
     if( !SocketAcquireStateLock( FCB ) )
         return STATUS_FILE_CLOSED;
 
+    ASSERT(FCB->ReceiveIrp.InFlightRequest == Irp);
     FCB->ReceiveIrp.InFlightRequest = NULL;
 
     FCB->Recv.Content = Irp->IoStatus.Information;
@@ -271,7 +262,7 @@
 	       NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_RECV]);
 	       NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
                NextIrpSp = IoGetCurrentIrpStackLocation(NextIrp);
-               RecvReq = NextIrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
+               RecvReq = GetLockedData(NextIrp, NextIrpSp);
 	       NextIrp->IoStatus.Status = STATUS_FILE_CLOSED;
 	       NextIrp->IoStatus.Information = 0;
 	       UnlockBuffers(RecvReq->BufferArray, RecvReq->BufferCount, FALSE);
@@ -378,7 +369,7 @@
     NTSTATUS Status = STATUS_SUCCESS;
     PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp );
     PAFD_RECV_INFO RecvReq =
-		IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
+        GetLockedData(Irp, IrpSp);
     UINT BytesToCopy = 0, BytesAvailable = DatagramRecv->Len, AddrLen = 0;
     PAFD_MAPBUF Map;
 
@@ -438,26 +429,23 @@
 								Map[0].BufferAddress,
 								BytesToCopy));
 
-		/* OskitDumpBuffer
-		   ( FCB->Recv.Window + FCB->Recv.BytesUsed, BytesToCopy ); */
-
 		RtlCopyMemory( Map[0].BufferAddress,
-					   FCB->Recv.Window + FCB->Recv.BytesUsed,
+					   DatagramRecv->Buffer,
 					   BytesToCopy );
 
 		MmUnmapLockedPages( Map[0].BufferAddress, Map[0].Mdl );
 
         *TotalBytesCopied = BytesToCopy;
-
-        if (!(RecvReq->TdiFlags & TDI_RECEIVE_PEEK)) {
-            FCB->Recv.BytesUsed = 0;
-        }
     }
 
     Status = Irp->IoStatus.Status = STATUS_SUCCESS;
     Irp->IoStatus.Information = BytesToCopy;
-    ExFreePool( DatagramRecv->Address );
-    ExFreePool( DatagramRecv );
+    
+    if (!(RecvReq->TdiFlags & TDI_RECEIVE_PEEK))
+    {
+        ExFreePool( DatagramRecv->Address );
+        ExFreePool( DatagramRecv );
+    }
 
     AFD_DbgPrint(MID_TRACE,("Done\n"));
 
@@ -484,6 +472,7 @@
     if( !SocketAcquireStateLock( FCB ) )
         return STATUS_FILE_CLOSED;
 
+    ASSERT(FCB->ReceiveIrp.InFlightRequest == Irp);
     FCB->ReceiveIrp.InFlightRequest = NULL;
 
     if( FCB->State == SOCKET_STATE_CLOSED ) {
@@ -492,7 +481,7 @@
 	       NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_RECV]);
 	       NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
 	       NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp );
-	       RecvReq = NextIrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
+           RecvReq = GetLockedData(NextIrp, NextIrpSp);
 	       NextIrp->IoStatus.Status = STATUS_FILE_CLOSED;
 	       NextIrp->IoStatus.Information = 0;
 	       UnlockBuffers(RecvReq->BufferArray, RecvReq->BufferCount, FALSE);
@@ -511,6 +500,12 @@
 
 	SocketStateUnlock( FCB );
 	return STATUS_FILE_CLOSED;
+    }
+    
+    if (Irp->IoStatus.Status != STATUS_SUCCESS)
+    {
+        SocketStateUnlock(FCB);
+        return Irp->IoStatus.Status;
     }
 
     DatagramRecv = ExAllocatePool( NonPagedPool, DGSize );
@@ -547,7 +542,7 @@
 		ListEntry = RemoveHeadList( &FCB->PendingIrpList[FUNCTION_RECV] );
 		NextIrp = CONTAINING_RECORD( ListEntry, IRP, Tail.Overlay.ListEntry );
 		NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp );
-		RecvReq = NextIrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
+		RecvReq = GetLockedData(NextIrp, NextIrpSp);
 
 		AFD_DbgPrint(MID_TRACE,("RecvReq: %x, DatagramRecv: %x\n",
 								RecvReq, DatagramRecv));
@@ -567,6 +562,11 @@
 			Status = SatisfyPacketRecvRequest
 				( FCB, NextIrp, DatagramRecv,
 				  (PUINT)&NextIrp->IoStatus.Information );
+            if (RecvReq->TdiFlags & TDI_RECEIVE_PEEK)
+            {
+                InsertHeadList(&FCB->DatagramList,
+                               &DatagramRecv->ListEntry);
+            }
 			AFD_DbgPrint(MID_TRACE,("Unlocking\n"));
 			UnlockBuffers( RecvReq->BufferArray, RecvReq->BufferCount, TRUE );
             if ( NextIrp->MdlAddress ) UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) );
@@ -664,6 +664,12 @@
 			Status = SatisfyPacketRecvRequest
 				( FCB, Irp, DatagramRecv,
 				  (PUINT)&Irp->IoStatus.Information );
+            
+            if (RecvReq->TdiFlags & TDI_RECEIVE_PEEK)
+            {
+                InsertHeadList(&FCB->DatagramList,
+                               &DatagramRecv->ListEntry);
+            }
 
 			if( !IsListEmpty( &FCB->DatagramList ) ) {
 				FCB->PollState |= AFD_EVENT_RECEIVE;

Modified: trunk/reactos/drivers/network/afd/afd/tdi.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/afd/afd/tdi.c?rev=52186&r1=52185&r2=52186&view=diff
==============================================================================
--- trunk/reactos/drivers/network/afd/afd/tdi.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/network/afd/afd/tdi.c [iso-8859-1] Sat Jun 11 12:46:04 2011
@@ -328,17 +328,17 @@
 	NTSTATUS Status;
 
 	AFD_DbgPrint(MAX_TRACE, ("Called\n"));
+    
+    ASSERT(*Irp == NULL);
 
 	if (!ConnectionObject) {
 		AFD_DbgPrint(MIN_TRACE, ("Bad connection object.\n"));
-		*Irp = NULL;
 		return STATUS_INVALID_PARAMETER;
 	}
 
 	DeviceObject = IoGetRelatedDeviceObject(ConnectionObject);
 	if (!DeviceObject) {
         AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n"));
-        *Irp = NULL;
         return STATUS_INVALID_PARAMETER;
 	}
 
@@ -492,17 +492,17 @@
 	NTSTATUS Status;
 
 	AFD_DbgPrint(MAX_TRACE, ("Called\n"));
+    
+    ASSERT(*Irp == NULL);
 
 	if (!ConnectionObject) {
 		AFD_DbgPrint(MIN_TRACE, ("Bad connection object.\n"));
-		*Irp = NULL;
 		return STATUS_INVALID_PARAMETER;
 	}
 
 	DeviceObject = IoGetRelatedDeviceObject(ConnectionObject);
 	if (!DeviceObject) {
         AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n"));
-        *Irp = NULL;
         return STATUS_INVALID_PARAMETER;
 	}
 
@@ -899,17 +899,17 @@
     PDEVICE_OBJECT DeviceObject;
     NTSTATUS Status = STATUS_SUCCESS;
     PMDL Mdl;
+    
+    ASSERT(*Irp == NULL);
 
     if (!TransportObject) {
 		AFD_DbgPrint(MIN_TRACE, ("Bad transport object.\n"));
-		*Irp = NULL;
 		return STATUS_INVALID_PARAMETER;
     }
 
     DeviceObject = IoGetRelatedDeviceObject(TransportObject);
     if (!DeviceObject) {
         AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n"));
-        *Irp = NULL;
         return STATUS_INVALID_PARAMETER;
     }
 
@@ -980,17 +980,17 @@
     NTSTATUS Status = STATUS_SUCCESS;
     PDEVICE_OBJECT DeviceObject;
     PMDL Mdl;
+    
+    ASSERT(*Irp == NULL);
 
     if (!TransportObject) {
 		AFD_DbgPrint(MIN_TRACE, ("Bad transport object.\n"));
-		*Irp = NULL;
 		return STATUS_INVALID_PARAMETER;
     }
 
     DeviceObject = IoGetRelatedDeviceObject(TransportObject);
     if (!DeviceObject) {
         AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n"));
-        *Irp = NULL;
         return STATUS_INVALID_PARAMETER;
     }
 
@@ -1080,17 +1080,17 @@
     PDEVICE_OBJECT DeviceObject;
     NTSTATUS Status;
     PMDL Mdl;
+    
+    ASSERT(*Irp == NULL);
 
     if (!TransportObject) {
 		AFD_DbgPrint(MIN_TRACE, ("Bad tranport object.\n"));
-		*Irp = NULL;
 		return STATUS_INVALID_PARAMETER;
     }
 
     DeviceObject = IoGetRelatedDeviceObject(TransportObject);
     if (!DeviceObject) {
         AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n"));
-        *Irp = NULL;
         return STATUS_INVALID_PARAMETER;
     }
 
@@ -1176,10 +1176,11 @@
     PDEVICE_OBJECT DeviceObject;
     NTSTATUS Status;
     PMDL Mdl;
+    
+    ASSERT(*Irp == NULL);
 
     if (!TransportObject) {
 		AFD_DbgPrint(MIN_TRACE, ("Bad transport object.\n"));
-		*Irp = NULL;
 		return STATUS_INVALID_PARAMETER;
     }
 
@@ -1188,7 +1189,6 @@
     DeviceObject = IoGetRelatedDeviceObject(TransportObject);
     if (!DeviceObject) {
         AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n"));
-        *Irp = NULL;
         return STATUS_INVALID_PARAMETER;
     }
 

Modified: trunk/reactos/drivers/network/afd/afd/write.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/afd/afd/write.c?rev=52186&r1=52185&r2=52186&view=diff
==============================================================================
--- trunk/reactos/drivers/network/afd/afd/write.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/network/afd/afd/write.c [iso-8859-1] Sat Jun 11 12:46:04 2011
@@ -23,7 +23,7 @@
     PIO_STACK_LOCATION NextIrpSp;
     PAFD_SEND_INFO SendReq = NULL;
     PAFD_MAPBUF Map;
-    UINT TotalBytesCopied = 0, SpaceAvail, i, CopySize = 0;
+    UINT TotalBytesCopied = 0, SpaceAvail, i;
 
     /*
      * The Irp parameter passed in is the IRP of the stream between AFD and
@@ -41,6 +41,7 @@
     if( !SocketAcquireStateLock( FCB ) )
         return STATUS_FILE_CLOSED;
 
+    ASSERT(FCB->SendIrp.InFlightRequest == Irp);
     FCB->SendIrp.InFlightRequest = NULL;
     /* Request is not in flight any longer */
 
@@ -50,7 +51,7 @@
 	       NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_SEND]);
 	       NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
 	       NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp );
-	       SendReq = NextIrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
+           SendReq = GetLockedData(NextIrp, NextIrpSp);
 	       NextIrp->IoStatus.Status = STATUS_FILE_CLOSED;
 	       NextIrp->IoStatus.Information = 0;
 	       UnlockBuffers(SendReq->BufferArray, SendReq->BufferCount, FALSE);
@@ -71,7 +72,7 @@
 			NextIrp =
 				CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
 			NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp );
-			SendReq = NextIrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
+			SendReq = GetLockedData(NextIrp, NextIrpSp);
 
 			UnlockBuffers( SendReq->BufferArray,
 						   SendReq->BufferCount,
@@ -95,37 +96,60 @@
 				   FCB->Send.BytesUsed - Irp->IoStatus.Information );
     FCB->Send.BytesUsed -= Irp->IoStatus.Information;
 
-    if( !FCB->Send.BytesUsed &&
-		!IsListEmpty( &FCB->PendingIrpList[FUNCTION_SEND] ) ) {
+    while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_SEND] ) ) {
 		NextIrpEntry =
 			RemoveHeadList(&FCB->PendingIrpList[FUNCTION_SEND]);
 		NextIrp =
 			CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
 		NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp );
-		SendReq = NextIrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
+		SendReq = GetLockedData(NextIrp, NextIrpSp);
 		Map = (PAFD_MAPBUF)(SendReq->BufferArray + SendReq->BufferCount);
 
 		AFD_DbgPrint(MID_TRACE,("SendReq @ %x\n", SendReq));
 
 		SpaceAvail = FCB->Send.Size - FCB->Send.BytesUsed;
+        TotalBytesCopied = 0;
 
 		for( i = 0; i < SendReq->BufferCount; i++ ) {
+            if (SpaceAvail < SendReq->BufferArray[i].len)
+            {
+                InsertHeadList(&FCB->PendingIrpList[FUNCTION_SEND],
+                               &NextIrp->Tail.Overlay.ListEntry);
+                NextIrp = NULL;
+                break;
+            }
 			Map[i].BufferAddress =
 				MmMapLockedPages( Map[i].Mdl, KernelMode );
 
-			CopySize = MIN( SpaceAvail,
-							SendReq->BufferArray[i].len );
-
 			RtlCopyMemory( FCB->Send.Window + FCB->Send.BytesUsed,
 						   Map[i].BufferAddress,
-						   CopySize );
+						   SendReq->BufferArray[i].len );
 
 			MmUnmapLockedPages( Map[i].BufferAddress, Map[i].Mdl );
 
-			FCB->Send.BytesUsed += CopySize;
-			TotalBytesCopied += CopySize;
-			SpaceAvail -= CopySize;
+			TotalBytesCopied += SendReq->BufferArray[i].len;
+			SpaceAvail -= SendReq->BufferArray[i].len;
 		}
+
+        if (NextIrp != NULL)
+        {
+            FCB->Send.BytesUsed += TotalBytesCopied;
+
+            NextIrp->IoStatus.Status = STATUS_SUCCESS;
+            NextIrp->IoStatus.Information = TotalBytesCopied;
+
+            (void)IoSetCancelRoutine(NextIrp, NULL);
+
+            UnlockBuffers( SendReq->BufferArray,
+                           SendReq->BufferCount,
+                           FALSE );
+
+            if (NextIrp->MdlAddress) UnlockRequest(NextIrp, NextIrpSp);
+
+            IoCompleteRequest(NextIrp, IO_NETWORK_INCREMENT);
+        }
+        else
+            break;
     }
 
     /* Some data is still waiting */
@@ -146,22 +170,6 @@
 		PollReeval( FCB->DeviceExt, FCB->FileObject );
     }
 
-    if( TotalBytesCopied > 0 ) {
-		UnlockBuffers( SendReq->BufferArray, SendReq->BufferCount, FALSE );
-
-		if( Status == STATUS_PENDING )
-			Status = STATUS_SUCCESS;
-
-		AFD_DbgPrint(MID_TRACE,("Dismissing request: %x\n", Status));
-
-		return UnlockAndMaybeComplete( FCB, Status, NextIrp, TotalBytesCopied );
-    } else if( NextIrp ) {
-		AFD_DbgPrint(MID_TRACE,("Could not do any more with Irp %x\n",
-								NextIrp));
-		InsertHeadList( &FCB->PendingIrpList[FUNCTION_SEND],
-						&NextIrp->Tail.Overlay.ListEntry );
-    }
-
     SocketStateUnlock( FCB );
 
     return STATUS_SUCCESS;
@@ -182,6 +190,7 @@
     if( !SocketAcquireStateLock( FCB ) )
         return STATUS_FILE_CLOSED;
 
+    ASSERT(FCB->SendIrp.InFlightRequest == Irp);
     FCB->SendIrp.InFlightRequest = NULL;
     /* Request is not in flight any longer */
 
@@ -220,8 +229,8 @@
     PAFD_FCB FCB = FileObject->FsContext;
     PAFD_SEND_INFO SendReq;
 	ULONG Information;
-    UINT TotalBytesCopied = 0, i, CopySize = 0,
-		SpaceAvail = 0, TotalBytesEncountered = 0;
+    UINT TotalBytesCopied = 0, i, SpaceAvail = 0;
+    BOOLEAN NoSpace = FALSE;
 
     AFD_DbgPrint(MID_TRACE,("Called on %x\n", FCB));
 
@@ -309,76 +318,87 @@
     AFD_DbgPrint(MID_TRACE,("FCB->Send.BytesUsed = %d\n",
 							FCB->Send.BytesUsed));
 
-    if( !FCB->Send.BytesUsed ) {
-		SpaceAvail = FCB->Send.Size - FCB->Send.BytesUsed;
-
-		AFD_DbgPrint(MID_TRACE,("We can accept %d bytes\n",
-								SpaceAvail));
-
-		for( i = 0; FCB->Send.BytesUsed < FCB->Send.Size &&
-				 i < SendReq->BufferCount; i++ ) {
-			CopySize = MIN( SpaceAvail,
-							SendReq->BufferArray[i].len );
-
-			TotalBytesEncountered += SendReq->BufferArray[i].len;
-
-			AFD_DbgPrint(MID_TRACE,("Copying Buffer %d, %x:%d to %x\n",
-									i,
-									SendReq->BufferArray[i].buf,
-									CopySize,
-									FCB->Send.Window + FCB->Send.BytesUsed));
-
-			RtlCopyMemory( FCB->Send.Window + FCB->Send.BytesUsed,
-						   SendReq->BufferArray[i].buf,
-						   CopySize );
-
-			FCB->Send.BytesUsed += CopySize;
-			TotalBytesCopied += CopySize;
-			SpaceAvail -= CopySize;
-		}
-
-		if( TotalBytesEncountered == 0 ) {
-			UnlockBuffers( SendReq->BufferArray, SendReq->BufferCount, FALSE );
-
-			AFD_DbgPrint(MID_TRACE,("Empty send\n"));
-			return UnlockAndMaybeComplete
-				( FCB, Status, Irp, TotalBytesCopied );
-		}
-
-		AFD_DbgPrint(MID_TRACE,("Completed %d bytes\n", TotalBytesCopied));
-
-		if( TotalBytesCopied > 0 ) {
-			UnlockBuffers( SendReq->BufferArray, SendReq->BufferCount, FALSE );
-
-			Status = TdiSend( &FCB->SendIrp.InFlightRequest,
-							  FCB->Connection.Object,
-							  0,
-							  FCB->Send.Window,
-							  FCB->Send.BytesUsed,
-							  &FCB->SendIrp.Iosb,
-							  SendComplete,
-							  FCB );
-
-			if( Status == STATUS_PENDING )
-				Status = STATUS_SUCCESS;
-
-			AFD_DbgPrint(MID_TRACE,("Dismissing request: %x (%d)\n",
-									Status, TotalBytesCopied));
-
-			return UnlockAndMaybeComplete
-				( FCB, Status, Irp, TotalBytesCopied );
-		}
-    }
-
-    if( SendReq->AfdFlags & AFD_IMMEDIATE ) {
-		AFD_DbgPrint(MID_TRACE,("Nonblocking\n"));
-		UnlockBuffers( SendReq->BufferArray, SendReq->BufferCount, FALSE );
-		return UnlockAndMaybeComplete
+    SpaceAvail = FCB->Send.Size - FCB->Send.BytesUsed;
+        
+    AFD_DbgPrint(MID_TRACE,("We can accept %d bytes\n",
+                            SpaceAvail));
+    
+    for( i = 0; FCB->Send.BytesUsed < FCB->Send.Size &&
+        i < SendReq->BufferCount; i++ ) {
+        
+        if (SpaceAvail < SendReq->BufferArray[i].len)
+        {
+            if (FCB->Send.BytesUsed + TotalBytesCopied + 
+                SendReq->BufferArray[i].len > FCB->Send.Size)
+            {
+                UnlockBuffers( SendReq->BufferArray, SendReq->BufferCount, FALSE );
+                
+                return UnlockAndMaybeComplete(FCB, STATUS_BUFFER_OVERFLOW, Irp, 0);
+            }
+            NoSpace = TRUE;
+            break;
+        }
+        
+        AFD_DbgPrint(MID_TRACE,("Copying Buffer %d, %x:%d to %x\n",
+                                i,
+                                SendReq->BufferArray[i].buf,
+                                SendReq->BufferArray[i].len,
+                                FCB->Send.Window + FCB->Send.BytesUsed));
+        
+        RtlCopyMemory( FCB->Send.Window + FCB->Send.BytesUsed,
+                      SendReq->BufferArray[i].buf,
+                      SendReq->BufferArray[i].len );
+        
+        TotalBytesCopied += SendReq->BufferArray[i].len;
+        SpaceAvail -= SendReq->BufferArray[i].len;
+    }
+    
+    if( TotalBytesCopied == 0 ) {
+        AFD_DbgPrint(MID_TRACE,("Empty send\n"));
+        UnlockBuffers( SendReq->BufferArray, SendReq->BufferCount, FALSE );
+        return UnlockAndMaybeComplete
+        ( FCB, STATUS_SUCCESS, Irp, TotalBytesCopied );
+    }
+    
+    if (!NoSpace)
+    {
+        UnlockBuffers( SendReq->BufferArray, SendReq->BufferCount, FALSE );
+        FCB->Send.BytesUsed += TotalBytesCopied;
+        AFD_DbgPrint(MID_TRACE,("Completed %d bytes\n", TotalBytesCopied));
+    }
+    else
+    {
+        if( SendReq->AfdFlags & AFD_IMMEDIATE ) {
+            AFD_DbgPrint(MID_TRACE,("Nonblocking\n"));
+            UnlockBuffers( SendReq->BufferArray, SendReq->BufferCount, FALSE );
+            return UnlockAndMaybeComplete
 			( FCB, STATUS_CANT_WAIT, Irp, 0 );
-    } else {
-		AFD_DbgPrint(MID_TRACE,("Queuing request\n"));
-		return LeaveIrpUntilLater( FCB, Irp, FUNCTION_SEND );
-    }
+        } else {
+            AFD_DbgPrint(MID_TRACE,("Queuing request\n"));
+            return LeaveIrpUntilLater( FCB, Irp, FUNCTION_SEND );
+        }
+    }
+        
+    if (!FCB->SendIrp.InFlightRequest)
+    {
+        Status = TdiSend( &FCB->SendIrp.InFlightRequest,
+                         FCB->Connection.Object,
+                         0,
+                         FCB->Send.Window,
+                         FCB->Send.BytesUsed,
+                         &FCB->SendIrp.Iosb,
+                         SendComplete,
+                         FCB );
+        
+        if( Status == STATUS_PENDING )
+            Status = STATUS_SUCCESS;
+        
+        AFD_DbgPrint(MID_TRACE,("Dismissing request: %x (%d)\n",
+                                Status, TotalBytesCopied));
+    }
+    
+    return UnlockAndMaybeComplete
+    ( FCB, Status, Irp, TotalBytesCopied );
 }
 
 NTSTATUS NTAPI
@@ -396,12 +416,32 @@
     if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );
 
     /* Check that the socket is bound */
-    if( FCB->State != SOCKET_STATE_BOUND )
+    if( FCB->State != SOCKET_STATE_BOUND &&
+        FCB->State != SOCKET_STATE_CREATED)
 		return UnlockAndMaybeComplete
 			( FCB, STATUS_INVALID_PARAMETER, Irp, 0 );
     if( !(SendReq = LockRequest( Irp, IrpSp )) )
 		return UnlockAndMaybeComplete
 			( FCB, STATUS_NO_MEMORY, Irp, 0 );
+    
+    if (FCB->State == SOCKET_STATE_CREATED)
+    {
+        if( FCB->LocalAddress ) ExFreePool( FCB->LocalAddress );
+        FCB->LocalAddress =
+        TaBuildNullTransportAddress( ((PTRANSPORT_ADDRESS)SendReq->TdiConnection.RemoteAddress)->
+                                      Address[0].AddressType );
+        
+        if( FCB->LocalAddress ) {
+            Status = WarmSocketForBind( FCB );
+            
+            if( NT_SUCCESS(Status) )
+                FCB->State = SOCKET_STATE_BOUND;
+            else
+                return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
+        } else
+            return UnlockAndMaybeComplete
+            ( FCB, STATUS_NO_MEMORY, Irp, 0 );
+    }
 
     SendReq->BufferArray = LockBuffers( SendReq->BufferArray,
                                         SendReq->BufferCount,

Modified: trunk/reactos/drivers/network/afd/include/afd.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/afd/include/afd.h?rev=52186&r1=52185&r2=52186&view=diff
==============================================================================
--- trunk/reactos/drivers/network/afd/include/afd.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/network/afd/include/afd.h [iso-8859-1] Sat Jun 11 12:46:04 2011
@@ -300,6 +300,7 @@
 VOID UnlockHandles( PAFD_HANDLE HandleArray, UINT HandleCount );
 PVOID LockRequest( PIRP Irp, PIO_STACK_LOCATION IrpSp );
 VOID UnlockRequest( PIRP Irp, PIO_STACK_LOCATION IrpSp );
+PVOID GetLockedData( PIRP Irp, PIO_STACK_LOCATION IrpSp );
 
 /* main.c */
 




More information about the Ros-diffs mailing list