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 */
 


Reply via email to