Author: cgutman
Date: Thu Jul  7 20:44:47 2011
New Revision: 52561

URL: http://svn.reactos.org/svn/reactos?rev=52561&view=rev
Log:
[AFD]
- Implement IOCTL_AFD_RECV for connection-less sockets
- Fix a parameter check
- Fixes recv() on datagram sockets

Modified:
    trunk/reactos/drivers/network/afd/afd/read.c

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=52561&r1=52560&r2=52561&view=diff
==============================================================================
--- trunk/reactos/drivers/network/afd/afd/read.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/network/afd/afd/read.c [iso-8859-1] Thu Jul  7 
20:44:47 2011
@@ -44,6 +44,48 @@
        
     return !BytesAvailable &&
        (FCB->PollState & (AFD_EVENT_CLOSE | AFD_EVENT_ABORT));
+}
+
+static BOOLEAN CheckUnlockExtraBuffers(PAFD_FCB FCB, PIO_STACK_LOCATION IrpSp)
+{
+    if (FCB->Flags & AFD_ENDPOINT_CONNECTIONLESS)
+    {
+        if (IrpSp->MajorFunction == IRP_MJ_READ)
+        {
+            /* read() call - no extra buffers */
+            return FALSE;
+        }
+        else if (IrpSp->MajorFunction == IRP_MJ_DEVICE_CONTROL)
+        {
+            if (IrpSp->Parameters.DeviceIoControl.IoControlCode == 
IOCTL_AFD_RECV_DATAGRAM)
+            {
+                /* recvfrom() call - extra buffers */
+                return TRUE;
+            }
+            else if (IrpSp->Parameters.DeviceIoControl.IoControlCode == 
IOCTL_AFD_RECV)
+            {
+                /* recv() call - no extra buffers */
+                return FALSE;
+            }
+            else
+            {
+                /* Unknown IOCTL */
+                ASSERT(FALSE);
+                return FALSE;
+            }
+        }
+        else
+        {
+            /* Unknown IRP_MJ code */
+            ASSERT(FALSE);
+            return FALSE;
+        }
+    }
+    else
+    {
+        /* Connection-oriented never has extra buffers */
+        return FALSE;
+    }
 }
 
 static VOID RefillSocketBuffer( PAFD_FCB FCB ) {
@@ -292,6 +334,97 @@
     return STATUS_SUCCESS;
 }
 
+static NTSTATUS NTAPI
+SatisfyPacketRecvRequest( PAFD_FCB FCB, PIRP Irp,
+                         PAFD_STORED_DATAGRAM DatagramRecv,
+                         PUINT TotalBytesCopied ) {
+    NTSTATUS Status = STATUS_SUCCESS;
+    PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp );
+    PAFD_RECV_INFO RecvReq =
+    GetLockedData(Irp, IrpSp);
+    UINT BytesToCopy = 0, BytesAvailable = DatagramRecv->Len, AddrLen = 0;
+    PAFD_MAPBUF Map;
+    
+    Map = (PAFD_MAPBUF)(RecvReq->BufferArray +
+                                               RecvReq->BufferCount +
+                                               EXTRA_LOCK_BUFFERS);
+    
+    BytesToCopy =
+    MIN( RecvReq->BufferArray[0].len, BytesAvailable );
+    
+    AFD_DbgPrint(MID_TRACE,("BytesToCopy: %d len %d\n", BytesToCopy,
+                                                       
RecvReq->BufferArray[0].len));
+    
+    if( Map[0].Mdl ) {
+               /* Copy the address */
+               if( Map[1].Mdl && Map[2].Mdl ) {
+                       AFD_DbgPrint(MID_TRACE,("Checking TAAddressCount\n"));
+            
+                       if( DatagramRecv->Address->TAAddressCount != 1 ) {
+                               AFD_DbgPrint
+                (MID_TRACE,
+                 ("Wierd address count %d\n",
+                  DatagramRecv->Address->TAAddressCount));
+                       }
+            
+                       AFD_DbgPrint(MID_TRACE,("Computing addr len\n"));
+            
+                       AddrLen = 
MIN(DatagramRecv->Address->Address->AddressLength +
+                                                 sizeof(USHORT),
+                                                 RecvReq->BufferArray[1].len);
+            
+                       AFD_DbgPrint(MID_TRACE,("Copying %d bytes of 
address\n", AddrLen));
+            
+                       Map[1].BufferAddress = MmMapLockedPages( Map[1].Mdl, 
KernelMode );
+            
+                       AFD_DbgPrint(MID_TRACE,("Done mapping, copying 
address\n"));
+            
+                       RtlCopyMemory( Map[1].BufferAddress,
+                          &DatagramRecv->Address->Address->AddressType,
+                          AddrLen );
+            
+                       MmUnmapLockedPages( Map[1].BufferAddress, Map[1].Mdl );
+            
+                       AFD_DbgPrint(MID_TRACE,("Copying address len\n"));
+            
+                       Map[2].BufferAddress = MmMapLockedPages( Map[2].Mdl, 
KernelMode );
+                       *((PINT)Map[2].BufferAddress) = AddrLen;
+                       MmUnmapLockedPages( Map[2].BufferAddress, Map[2].Mdl );
+               }
+        
+               AFD_DbgPrint(MID_TRACE,("Mapping data buffer pages\n"));
+        
+               Map[0].BufferAddress = MmMapLockedPages( Map[0].Mdl, KernelMode 
);
+        
+               AFD_DbgPrint(MID_TRACE,("Buffer %d: %x:%d\n",
+                                                               0,
+                                                               
Map[0].BufferAddress,
+                                                               BytesToCopy));
+        
+               RtlCopyMemory( Map[0].BufferAddress,
+                      DatagramRecv->Buffer,
+                      BytesToCopy );
+        
+               MmUnmapLockedPages( Map[0].BufferAddress, Map[0].Mdl );
+        
+        *TotalBytesCopied = BytesToCopy;
+    }
+    
+    Status = Irp->IoStatus.Status = STATUS_SUCCESS;
+    Irp->IoStatus.Information = BytesToCopy;
+    
+    if (!(RecvReq->TdiFlags & TDI_RECEIVE_PEEK))
+    {
+        FCB->Recv.Content -= *TotalBytesCopied;
+        ExFreePool( DatagramRecv->Address );
+        ExFreePool( DatagramRecv );
+    }
+    
+    AFD_DbgPrint(MID_TRACE,("Done\n"));
+    
+    return Status;
+}
+
 NTSTATUS NTAPI
 AfdConnectedSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
                                                   PIO_STACK_LOCATION IrpSp, 
BOOLEAN Short) {
@@ -300,40 +433,95 @@
     PAFD_FCB FCB = FileObject->FsContext;
     PAFD_RECV_INFO RecvReq;
     UINT TotalBytesCopied = 0;
+    PAFD_STORED_DATAGRAM DatagramRecv;
+    PLIST_ENTRY ListEntry;
 
     AFD_DbgPrint(MID_TRACE,("Called on %x\n", FCB));
 
     if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );
 
-    if( FCB->State != SOCKET_STATE_CONNECTED &&
+    if( !(FCB->Flags & AFD_ENDPOINT_CONNECTIONLESS) &&
+        FCB->State != SOCKET_STATE_CONNECTED &&
         FCB->State != SOCKET_STATE_CONNECTING ) {
         AFD_DbgPrint(MID_TRACE,("Called recv on wrong kind of socket (s%x)\n",
                                 FCB->State));
         return UnlockAndMaybeComplete( FCB, STATUS_INVALID_PARAMETER,
                                                                           Irp, 
0 );
     }
+    
+    if( !(RecvReq = LockRequest( Irp, IrpSp )) )
+               return UnlockAndMaybeComplete( FCB, STATUS_NO_MEMORY,
+                                      Irp, 0 );
+    
+    AFD_DbgPrint(MID_TRACE,("Recv flags %x\n", RecvReq->AfdFlags));
+    
+    RecvReq->BufferArray = LockBuffers( RecvReq->BufferArray,
+                                       RecvReq->BufferCount,
+                                       NULL, NULL,
+                                       TRUE, FALSE );
+    
+    if( !RecvReq->BufferArray ) {
+        return UnlockAndMaybeComplete( FCB, STATUS_ACCESS_VIOLATION,
+                                      Irp, 0 );
+    }
 
     if( FCB->Flags & AFD_ENDPOINT_CONNECTIONLESS )
     {
-               AFD_DbgPrint(MID_TRACE,("Receive on connection-less sockets not 
implemented\n"));
-               return UnlockAndMaybeComplete( FCB, STATUS_NOT_IMPLEMENTED,
-                                                                          Irp, 
0 );
-    }
-
-    if( !(RecvReq = LockRequest( Irp, IrpSp )) )
-               return UnlockAndMaybeComplete( FCB, STATUS_NO_MEMORY,
-                                                                          Irp, 
0 );
-
-    AFD_DbgPrint(MID_TRACE,("Recv flags %x\n", RecvReq->AfdFlags));
-
-    RecvReq->BufferArray = LockBuffers( RecvReq->BufferArray,
-                                                                               
RecvReq->BufferCount,
-                                                                               
NULL, NULL,
-                                                                               
TRUE, FALSE );
-
-    if( !RecvReq->BufferArray ) {
-        return UnlockAndMaybeComplete( FCB, STATUS_ACCESS_VIOLATION,
-                                       Irp, 0 );
+               if( !IsListEmpty( &FCB->DatagramList ) ) {
+            ListEntry = RemoveHeadList( &FCB->DatagramList );
+            DatagramRecv = CONTAINING_RECORD
+                       ( ListEntry, AFD_STORED_DATAGRAM, ListEntry );
+            if( DatagramRecv->Len > RecvReq->BufferArray[0].len &&
+               !(RecvReq->TdiFlags & TDI_RECEIVE_PARTIAL) ) {
+                InsertHeadList( &FCB->DatagramList,
+                               &DatagramRecv->ListEntry );
+                Status = Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
+                Irp->IoStatus.Information = DatagramRecv->Len;
+                
+                if( !IsListEmpty( &FCB->DatagramList ) ) {
+                    FCB->PollState |= AFD_EVENT_RECEIVE;
+                    FCB->PollStatus[FD_READ_BIT] = STATUS_SUCCESS;
+                    PollReeval( FCB->DeviceExt, FCB->FileObject );
+                } else
+                    FCB->PollState &= ~AFD_EVENT_RECEIVE;
+                
+                UnlockBuffers( RecvReq->BufferArray, RecvReq->BufferCount, 
FALSE );
+                
+                return UnlockAndMaybeComplete
+                               ( FCB, Status, Irp, Irp->IoStatus.Information );
+            } else {
+                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;
+                    FCB->PollStatus[FD_READ_BIT] = STATUS_SUCCESS;
+                    PollReeval( FCB->DeviceExt, FCB->FileObject );
+                } else
+                    FCB->PollState &= ~AFD_EVENT_RECEIVE;
+                
+                UnlockBuffers( RecvReq->BufferArray, RecvReq->BufferCount, 
FALSE );
+                
+                return UnlockAndMaybeComplete
+                               ( FCB, Status, Irp, Irp->IoStatus.Information );
+            }
+        } else if( (RecvReq->AfdFlags & AFD_IMMEDIATE) || (FCB->NonBlocking) ) 
{
+            AFD_DbgPrint(MID_TRACE,("Nonblocking\n"));
+            Status = STATUS_CANT_WAIT;
+            FCB->PollState &= ~AFD_EVENT_RECEIVE;
+            UnlockBuffers( RecvReq->BufferArray, RecvReq->BufferCount, FALSE );
+            return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
+        } else {
+            FCB->PollState &= ~AFD_EVENT_RECEIVE;
+            return LeaveIrpUntilLater( FCB, Irp, FUNCTION_RECV );
+        }
     }
 
     Irp->IoStatus.Status = STATUS_PENDING;
@@ -367,98 +555,6 @@
     return Status;
 }
 
-
-static NTSTATUS NTAPI
-SatisfyPacketRecvRequest( PAFD_FCB FCB, PIRP Irp,
-                                                 PAFD_STORED_DATAGRAM 
DatagramRecv,
-                                                 PUINT TotalBytesCopied ) {
-    NTSTATUS Status = STATUS_SUCCESS;
-    PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp );
-    PAFD_RECV_INFO RecvReq =
-        GetLockedData(Irp, IrpSp);
-    UINT BytesToCopy = 0, BytesAvailable = DatagramRecv->Len, AddrLen = 0;
-    PAFD_MAPBUF Map;
-
-    Map = (PAFD_MAPBUF)(RecvReq->BufferArray +
-                                               RecvReq->BufferCount +
-                                               EXTRA_LOCK_BUFFERS);
-
-    BytesToCopy =
-               MIN( RecvReq->BufferArray[0].len, BytesAvailable );
-
-    AFD_DbgPrint(MID_TRACE,("BytesToCopy: %d len %d\n", BytesToCopy,
-                                                       
RecvReq->BufferArray[0].len));
-
-    if( Map[0].Mdl ) {
-               /* Copy the address */
-               if( Map[1].Mdl && Map[2].Mdl ) {
-                       AFD_DbgPrint(MID_TRACE,("Checking TAAddressCount\n"));
-
-                       if( DatagramRecv->Address->TAAddressCount != 1 ) {
-                               AFD_DbgPrint
-                                       (MID_TRACE,
-                                        ("Wierd address count %d\n",
-                                         
DatagramRecv->Address->TAAddressCount));
-                       }
-
-                       AFD_DbgPrint(MID_TRACE,("Computing addr len\n"));
-
-                       AddrLen = 
MIN(DatagramRecv->Address->Address->AddressLength +
-                                                 sizeof(USHORT),
-                                                 RecvReq->BufferArray[1].len);
-
-                       AFD_DbgPrint(MID_TRACE,("Copying %d bytes of 
address\n", AddrLen));
-
-                       Map[1].BufferAddress = MmMapLockedPages( Map[1].Mdl, 
KernelMode );
-
-                       AFD_DbgPrint(MID_TRACE,("Done mapping, copying 
address\n"));
-
-                       RtlCopyMemory( Map[1].BufferAddress,
-                                                  
&DatagramRecv->Address->Address->AddressType,
-                                                  AddrLen );
-
-                       MmUnmapLockedPages( Map[1].BufferAddress, Map[1].Mdl );
-
-                       AFD_DbgPrint(MID_TRACE,("Copying address len\n"));
-
-                       Map[2].BufferAddress = MmMapLockedPages( Map[2].Mdl, 
KernelMode );
-                       *((PINT)Map[2].BufferAddress) = AddrLen;
-                       MmUnmapLockedPages( Map[2].BufferAddress, Map[2].Mdl );
-               }
-
-               AFD_DbgPrint(MID_TRACE,("Mapping data buffer pages\n"));
-
-               Map[0].BufferAddress = MmMapLockedPages( Map[0].Mdl, KernelMode 
);
-
-               AFD_DbgPrint(MID_TRACE,("Buffer %d: %x:%d\n",
-                                                               0,
-                                                               
Map[0].BufferAddress,
-                                                               BytesToCopy));
-
-               RtlCopyMemory( Map[0].BufferAddress,
-                                          DatagramRecv->Buffer,
-                                          BytesToCopy );
-
-               MmUnmapLockedPages( Map[0].BufferAddress, Map[0].Mdl );
-
-        *TotalBytesCopied = BytesToCopy;
-    }
-
-    Status = Irp->IoStatus.Status = STATUS_SUCCESS;
-    Irp->IoStatus.Information = BytesToCopy;
-    
-    if (!(RecvReq->TdiFlags & TDI_RECEIVE_PEEK))
-    {
-        FCB->Recv.Content -= *TotalBytesCopied;
-        ExFreePool( DatagramRecv->Address );
-        ExFreePool( DatagramRecv );
-    }
-
-    AFD_DbgPrint(MID_TRACE,("Done\n"));
-
-    return Status;
-}
-
 NTSTATUS NTAPI
 PacketSocketRecvComplete(
        PDEVICE_OBJECT DeviceObject,
@@ -491,7 +587,7 @@
            RecvReq = GetLockedData(NextIrp, NextIrpSp);
               NextIrp->IoStatus.Status = STATUS_FILE_CLOSED;
               NextIrp->IoStatus.Information = 0;
-              UnlockBuffers(RecvReq->BufferArray, RecvReq->BufferCount, FALSE);
+              UnlockBuffers(RecvReq->BufferArray, RecvReq->BufferCount, 
CheckUnlockExtraBuffers(FCB, NextIrpSp));
               if( NextIrp->MdlAddress ) UnlockRequest( NextIrp, 
IoGetCurrentIrpStackLocation( NextIrp ) );
                (void)IoSetCancelRoutine(NextIrp, NULL);
               IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT );
@@ -561,7 +657,7 @@
                                                        
&DatagramRecv->ListEntry );
                        Status = NextIrp->IoStatus.Status = 
STATUS_BUFFER_TOO_SMALL;
                        NextIrp->IoStatus.Information = DatagramRecv->Len;
-                       UnlockBuffers( RecvReq->BufferArray, 
RecvReq->BufferCount, TRUE );
+                       UnlockBuffers( RecvReq->BufferArray, 
RecvReq->BufferCount, CheckUnlockExtraBuffers(FCB, NextIrpSp) );
             if ( NextIrp->MdlAddress ) UnlockRequest( NextIrp, 
IoGetCurrentIrpStackLocation( NextIrp ) );
                         (void)IoSetCancelRoutine(NextIrp, NULL);
                        IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT );
@@ -576,7 +672,7 @@
                                &DatagramRecv->ListEntry);
             }
                        AFD_DbgPrint(MID_TRACE,("Unlocking\n"));
-                       UnlockBuffers( RecvReq->BufferArray, 
RecvReq->BufferCount, TRUE );
+                       UnlockBuffers( RecvReq->BufferArray, 
RecvReq->BufferCount, CheckUnlockExtraBuffers(FCB, NextIrpSp) );
             if ( NextIrp->MdlAddress ) UnlockRequest( NextIrp, 
IoGetCurrentIrpStackLocation( NextIrp ) );
                        AFD_DbgPrint(MID_TRACE,("Completing\n"));
                         (void)IoSetCancelRoutine(NextIrp, NULL);


Reply via email to