Commit in reactos/drivers/net/afd on arty_afd_20040709
afd/bind.c+22-11.1.2.1 -> 1.1.2.2
   /main.c+34-251.1.2.1 -> 1.1.2.2
   /read.c+140-41.1.2.1 -> 1.1.2.2
   /select.c+2-11.1.2.1 -> 1.1.2.2
   /tdi.c+105-1371.13.4.1 -> 1.13.4.2
   /write.c+30-41.1.2.2 -> 1.1.2.3
include/afd.h+51-101.18.10.1 -> 1.18.10.2
+384-182
7 modified files
Code for sendto and recvfrom in.  Needs testing.

reactos/drivers/net/afd/afd
bind.c 1.1.2.1 -> 1.1.2.2
diff -u -r1.1.2.1 -r1.1.2.2
--- bind.c	9 Jul 2004 04:41:18 -0000	1.1.2.1
+++ bind.c	14 Jul 2004 16:54:14 -0000	1.1.2.2
@@ -1,4 +1,4 @@
-/* $Id: bind.c,v 1.1.2.1 2004/07/09 04:41:18 arty Exp $
+/* $Id: bind.c,v 1.1.2.2 2004/07/14 16:54:14 arty Exp $
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
  * FILE:             drivers/net/afd/afd/bind.c
@@ -58,6 +58,27 @@
     if( NT_SUCCESS(Status) ) 
 	FCB->State = SOCKET_STATE_BOUND;
 
+    if( FCB->Flags & SGID_CONNECTIONLESS ) {
+	/* This will be the from address for subsequent recvfrom calls */
+	TdiBuildConnectionInfo( &FCB->AddressFrom,
+				&FCB->LocalAddress->Address[0] );
+	/* Allocate our backup buffer */
+	FCB->Recv.Window = ExAllocatePool( NonPagedPool, FCB->Recv.Size );
+	FCB->PollState |= AFD_EVENT_SEND; 
+	/* A datagram socket is always sendable */
+	
+	Status = TdiReceiveDatagram
+	    ( &FCB->ReceiveIrp.InFlightRequest,
+	      FCB->AddressFile.Object,
+	      0,
+	      FCB->Recv.Window,
+	      FCB->Recv.Size,
+	      FCB->AddressFrom,
+	      &FCB->ReceiveIrp.Iosb,
+	      PacketSocketRecvComplete,
+	      FCB );
+    }
+
     return UnlockAndMaybeComplete( FCB, Status, Irp, 0, NULL );
 }
 

reactos/drivers/net/afd/afd
main.c 1.1.2.1 -> 1.1.2.2
diff -u -r1.1.2.1 -r1.1.2.2
--- main.c	9 Jul 2004 04:41:18 -0000	1.1.2.1
+++ main.c	14 Jul 2004 16:54:14 -0000	1.1.2.2
@@ -1,4 +1,4 @@
-/* $Id: main.c,v 1.1.2.1 2004/07/09 04:41:18 arty Exp $
+/* $Id: main.c,v 1.1.2.2 2004/07/14 16:54:14 arty Exp $
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
  * FILE:             drivers/net/afd/afd/main.c
@@ -89,28 +89,14 @@
 
     AFD_DbgPrint(MID_TRACE,("Initializing the new FCB @ %x (FileObject %x)\n", FCB, FileObject));
 
-    FCB->Locked = FALSE;
-    FCB->PollState = 0;
+    RtlZeroMemory( FCB, sizeof( *FCB ) );
+
+    FCB->Flags = ConnectInfo->Flags;
     FCB->State = SOCKET_STATE_CREATED;
     FCB->FileObject = FileObject;
     FCB->DeviceExt = DeviceExt;
-    FCB->CurrentThread = NULL;
-    FCB->LockCount = 0;
-    FCB->DelayedAccept = FALSE;
-    FCB->LocalAddress = FCB->RemoteAddress = NULL;
     FCB->Recv.Size = DEFAULT_RECEIVE_WINDOW_SIZE;
-    FCB->Recv.BytesUsed = 0;
-    FCB->Recv.Content = 0;
-    FCB->Recv.Window = NULL;
     FCB->Send.Size = DEFAULT_SEND_WINDOW_SIZE;
-    FCB->Send.BytesUsed = 0;
-    FCB->Send.Content = 0;
-    FCB->Send.Window = NULL;
-    FCB->Context = 0;
-    FCB->ContextSize = 0;
-
-    RtlZeroMemory( &FCB->Connection, sizeof(FCB->Connection) );
-    RtlZeroMemory( &FCB->AddressFile, sizeof(FCB->AddressFile) );
 
     KeInitializeSpinLock( &FCB->SpinLock );
     ExInitializeFastMutex( &FCB->Mutex );
@@ -153,22 +139,45 @@
 {
     PFILE_OBJECT FileObject = IrpSp->FileObject;
     PAFD_FCB FCB = FileObject->FsContext;
-    
+    UINT i;
+    PAFD_IN_FLIGHT_REQUEST InFlightRequest[IN_FLIGHT_REQUESTS];
+
     if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );    
 
+    InFlightRequest[0] = &FCB->ListenIrp;
+    InFlightRequest[1] = &FCB->ReceiveIrp;
+    InFlightRequest[2] = &FCB->SendIrp;
+
     AFD_DbgPrint(MID_TRACE,
 		 ("AfdClose(DeviceObject %p Irp %p)\n", DeviceObject, Irp));
     
     AFD_DbgPrint(MID_TRACE,("FCB %x\n", FCB));
 
+    FileObject->FsContext = NULL;
     FCB->PollState |= AFD_EVENT_CLOSE;
-    FCB->State = SOCKET_STATE_CLOSED;
-    PollReeval( FCB->DeviceExt, FCB->FileObject );
+    PollReeval( FCB->DeviceExt, FCB->FileObject ); 
+    /* After PoolReeval, this FCB should not be involved in any outstanding
+     * poll requests */
+
+    /* Cancel our pending requests */
+    for( i = 0; i < IN_FLIGHT_REQUESTS; i++ ) {
+	NTSTATUS Status = STATUS_NO_SUCH_FILE;
+	InFlightRequest[i]->InFlightRequest->IoStatus.Status = Status;
+	InFlightRequest[i]->InFlightRequest->IoStatus.Information = 0;
+	IoCancelIrp( InFlightRequest[i]->InFlightRequest );
+    }
 
-    FileObject->FsContext = NULL;
-    
     SocketStateUnlock( FCB );
     
+    if( FCB->Recv.Window ) 
+	ExFreePool( FCB->Recv.Window );
+    if( FCB->Send.Window )
+	ExFreePool( FCB->Send.Window );
+    if( FCB->AddressFrom ) 
+	ExFreePool( FCB->AddressFrom );
+    if( FCB->LocalAddress )
+	ExFreePool( FCB->LocalAddress );
+
     ExFreePool(FCB->TdiDeviceName.Buffer);
     ExFreePool(FCB);
     
@@ -234,14 +243,14 @@
 	    return AfdSelect( DeviceObject, Irp, IrpSp );
 
 	case IOCTL_AFD_RECVFROM:
-	    return AfdPacketSocketReadData( DeviceObject, Irp );
+	    return AfdPacketSocketReadData( DeviceObject, Irp, IrpSp );
 
 	case IOCTL_AFD_SEND:
 	    return AfdConnectedSocketWriteData( DeviceObject, Irp, IrpSp, 
 						FALSE );
 
 	case IOCTL_AFD_SENDTO:
-	    return AfdPacketSocketWriteData( DeviceObject, Irp );
+	    return AfdPacketSocketWriteData( DeviceObject, Irp, IrpSp );
 
 	case IOCTL_AFD_GET_INFO:
 	    return AfdGetInfo( DeviceObject, Irp, IrpSp );

reactos/drivers/net/afd/afd
read.c 1.1.2.1 -> 1.1.2.2
diff -u -r1.1.2.1 -r1.1.2.2
--- read.c	9 Jul 2004 04:41:18 -0000	1.1.2.1
+++ read.c	14 Jul 2004 16:54:14 -0000	1.1.2.2
@@ -1,4 +1,4 @@
-/* $Id: read.c,v 1.1.2.1 2004/07/09 04:41:18 arty Exp $
+/* $Id: read.c,v 1.1.2.2 2004/07/14 16:54:14 arty Exp $
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
  * FILE:             drivers/net/afd/afd/read.c
@@ -6,6 +6,8 @@
  * PROGRAMMER:       Art Yerkes (ayerkes@speakeasy.net)
  * UPDATE HISTORY:
  * 20040708 Created
+ *
+ * Improve buffering code
  */
 #include "afd.h"
 #include "tdi_proto.h"
@@ -118,6 +120,7 @@
 	if( FCB->Recv.Window && !FCB->Recv.Content ) {
 	    AFD_DbgPrint(MID_TRACE,
 			 ("Exhausted our buffer.  Requesting new: %x\n", FCB));
+
 	    Status = TdiReceive( &FCB->ReceiveIrp.InFlightRequest,
 				 IrpSp->FileObject,
 				 TDI_RECEIVE_NORMAL,
@@ -184,9 +187,142 @@
     }
 }
 
+
 NTSTATUS STDCALL
-AfdPacketSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp ) {
-    Irp->IoStatus.Information = 0;
-    return STATUS_END_OF_FILE;
+SatisfyPacketRecvRequest( PAFD_FCB FCB, PIRP Irp, 
+			  PAFD_STORED_DATAGRAM DatagramRecv ) {
+    NTSTATUS Status = STATUS_SUCCESS;
+    PAFD_RECV_REQ RecvReq = Irp->AssociatedIrp.SystemBuffer;
+    UINT CopyLen = 0;
+
+    CopyLen = MIN(DatagramRecv->Len, RecvReq->BufferArray[0].len);
+    RtlCopyMemory( RecvReq->BufferArray[0].buf, DatagramRecv->Buffer,
+		   CopyLen );
+    
+    Status = Irp->IoStatus.Status = STATUS_SUCCESS;
+    Irp->IoStatus.Information = CopyLen;
+    ExFreePool( DatagramRecv );
+    
+    return Status;
 }
 
+NTSTATUS DDKAPI
+PacketSocketRecvComplete(
+  PDEVICE_OBJECT DeviceObject,
+  PIRP Irp,
+  PVOID Context ) {
+    NTSTATUS Status = STATUS_SUCCESS;
+    PAFD_FCB FCB = Context;
+    PIRP NextIrp;
+    PLIST_ENTRY ListEntry;
+    PAFD_RECV_REQ RecvReq;
+    PAFD_STORED_DATAGRAM DatagramRecv;
+    UINT DGSize = Irp->IoStatus.Information + sizeof( AFD_STORED_DATAGRAM );
+
+    AFD_DbgPrint(MID_TRACE,("Called on %x\n", FCB));
+
+    if( !SocketAcquireStateLock( FCB ) ) {
+	SocketStateUnlock( FCB );
+	return STATUS_UNSUCCESSFUL;
+    }
+    
+    DatagramRecv = ExAllocatePool( NonPagedPool, DGSize );
+
+    if( DatagramRecv ) {
+	DatagramRecv->Len = Irp->IoStatus.Information;
+	RtlCopyMemory( DatagramRecv->Buffer, FCB->Recv.Window,
+		       DatagramRecv->Len );
+	InsertTailList( &FCB->DatagramList, &DatagramRecv->ListEntry );
+    } else Status = STATUS_NO_MEMORY;
+
+    /* Satisfy as many requests as we can */
+
+    while( NT_SUCCESS(Status) && 
+	   !IsListEmpty( &FCB->DatagramList ) && 
+	   !IsListEmpty( &FCB->PendingIrpList[FUNCTION_RECV_DATAGRAM] ) ) {
+	ListEntry = RemoveHeadList( &FCB->DatagramList );
+	DatagramRecv = CONTAINING_RECORD( ListEntry, AFD_STORED_DATAGRAM,
+					  ListEntry );
+	ListEntry = RemoveHeadList
+	    ( &FCB->PendingIrpList[FUNCTION_RECV_DATAGRAM] );
+	NextIrp = CONTAINING_RECORD( ListEntry, IRP, Tail.Overlay.ListEntry );
+	RecvReq = NextIrp->AssociatedIrp.SystemBuffer;
+
+	if( DatagramRecv->Len > RecvReq->BufferArray[0].len && 
+	    !(RecvReq->TdiFlags & TDI_RECEIVE_PARTIAL) ) {
+	    InsertHeadList( &FCB->DatagramList,
+			    &DatagramRecv->ListEntry );
+	    Status = NextIrp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
+	    NextIrp->IoStatus.Information = DatagramRecv->Len;
+	    UnlockBuffers( RecvReq->BufferArray, RecvReq->BufferCount );
+	    IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT );
+	} else {
+	    Status = SatisfyPacketRecvRequest( FCB, NextIrp, DatagramRecv );
+	    UnlockBuffers( RecvReq->BufferArray, RecvReq->BufferCount );
+	    IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT );
+	}
+    }
+
+    if( !IsListEmpty( &FCB->DatagramList ) ) { 
+	FCB->PollState |= AFD_EVENT_RECEIVE;
+	PollReeval( FCB->DeviceExt, FCB->FileObject );
+    }
+
+    /* Now relaunch the datagram request */
+    Status = TdiReceiveDatagram
+	( &FCB->ReceiveIrp.InFlightRequest,
+	  FCB->AddressFile.Object,
+	  0,
+	  FCB->Recv.Window,
+	  FCB->Recv.Size,
+	  FCB->AddressFrom,
+	  &FCB->ReceiveIrp.Iosb,
+	  PacketSocketRecvComplete,
+	  FCB );
+
+    SocketStateUnlock( FCB );
+
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS STDCALL
+AfdPacketSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp, 
+			PIO_STACK_LOCATION IrpSp ) {
+    NTSTATUS Status = STATUS_SUCCESS;
+    PFILE_OBJECT FileObject = IrpSp->FileObject;
+    PAFD_FCB FCB = FileObject->FsContext;
+    PAFD_RECV_REQ RecvReq = Irp->AssociatedIrp.SystemBuffer;
+    PLIST_ENTRY ListEntry;
+    PAFD_STORED_DATAGRAM DatagramRecv;
+
+    AFD_DbgPrint(MID_TRACE,("Called on %x\n", FCB));
+
+    if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );
+    
+    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;
+	    return UnlockAndMaybeComplete
+		( FCB, Status, Irp, RecvReq->BufferArray[0].len, NULL );
+	} else {
+	    if( IsListEmpty( &FCB->DatagramList ) ) 
+		FCB->PollState &= ~AFD_EVENT_RECEIVE;
+
+	    Status = SatisfyPacketRecvRequest( FCB, Irp, DatagramRecv );
+	    return UnlockAndMaybeComplete
+		( FCB, Status, Irp, Irp->IoStatus.Information, NULL );
+	}
+    } else {
+	RecvReq->BufferArray = LockBuffers( RecvReq->BufferArray, 
+					    RecvReq->BufferCount,
+					    TRUE );
+	return LeaveIrpUntilLater( FCB, Irp, FUNCTION_RECV_DATAGRAM );
+    }
+}

reactos/drivers/net/afd/afd
select.c 1.1.2.1 -> 1.1.2.2
diff -u -r1.1.2.1 -r1.1.2.2
--- select.c	9 Jul 2004 04:41:18 -0000	1.1.2.1
+++ select.c	14 Jul 2004 16:54:14 -0000	1.1.2.2
@@ -1,4 +1,4 @@
-/* $Id: select.c,v 1.1.2.1 2004/07/09 04:41:18 arty Exp $
+/* $Id: select.c,v 1.1.2.2 2004/07/14 16:54:14 arty Exp $
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
  * FILE:             drivers/net/afd/afd/select.c
@@ -52,6 +52,7 @@
 	      KernelMode,
 	      (PVOID*)&FileObject,
 	      NULL );
+
 	if( NT_SUCCESS(Status) ) {
 	    FCB = FileObject->FsContext;
 	    /* Check select bits */

reactos/drivers/net/afd/afd
tdi.c 1.13.4.1 -> 1.13.4.2
diff -u -r1.13.4.1 -r1.13.4.2
--- tdi.c	9 Jul 2004 04:41:18 -0000	1.13.4.1
+++ tdi.c	14 Jul 2004 16:54:14 -0000	1.13.4.2
@@ -847,31 +847,19 @@
     return Status;
 }
 
-
-NTSTATUS TdiSendDatagram(
+NTSTATUS TdiReceive(
+    PIRP *Irp,
     PFILE_OBJECT TransportObject,
-    PTA_ADDRESS Address,
-    PMDL Mdl,
-    ULONG BufferSize)
-/*
- * FUNCTION: Sends a datagram
- * ARGUMENTS:
- *     TransportObject = Pointer to transport object
- *     Address         = Remote address to send data to
- *     Mdl             = MDL of buffer to send
- *     BufferSize      = Length of buffer
- * RETURNS:
- *     Status of operation
- */
+    USHORT Flags,
+    PCHAR Buffer,
+    UINT BufferLength,
+    PIO_STATUS_BLOCK Iosb,
+    PIO_COMPLETION_ROUTINE CompletionRoutine,
+    PVOID CompletionContext)
 {
-    PTDI_CONNECTION_INFORMATION ConnectInfo;
     PDEVICE_OBJECT DeviceObject;
-    IO_STATUS_BLOCK Iosb;
     NTSTATUS Status;
-    KEVENT Event;
-    PIRP Irp;
-
-    AFD_DbgPrint(MAX_TRACE, ("Called.\n"));
+    PMDL Mdl;
 
     DeviceObject = IoGetRelatedDeviceObject(TransportObject);
     if (!DeviceObject) {
@@ -879,92 +867,84 @@
         return STATUS_INVALID_PARAMETER;
     }
 
-    AFD_DbgPrint(MAX_TRACE, 
-		 ("TdiSendDatagram: TansportObject = %08x\n", TransportObject));
-
-    TdiBuildConnectionInfo( &ConnectInfo, Address );
-
-    AFD_DbgPrint(MAX_TRACE, ("Point B\n"));
-
-    KeInitializeEvent(&Event, NotificationEvent, FALSE);
-
-    AFD_DbgPrint(MAX_TRACE, ("Point 0\n"));
+    *Irp = TdiBuildInternalDeviceControlIrp
+	( TDI_RECEIVE,             /* Sub function */
+	  DeviceObject,            /* Device object */
+	  TransportObject,         /* File object */
+	  NULL,                    /* Event */
+	  Iosb );                  /* Status */
 
-    Irp = TdiBuildInternalDeviceControlIrp(TDI_SEND_DATAGRAM,   /* Sub function */
-                                           DeviceObject,        /* Device object */
-                                           TransportObject,     /* File object */
-                                           &Event,              /* Event */
-                                           &Iosb);              /* Status */
-    if (!Irp) {
-        AFD_DbgPrint(MIN_TRACE, ("TdiBuildInternalDeviceControlIrp() failed.\n"));
-        ExFreePool(ConnectInfo);
+    if (!*Irp) {
+        AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
         return STATUS_INSUFFICIENT_RESOURCES;
     }
 
-    AFD_DbgPrint(MAX_TRACE, ("Point 1\n"));
+    AFD_DbgPrint(MID_TRACE, ("Allocating irp for %x:%d\n", Buffer,BufferLength));
 
-#if 0
-    Mdl = IoAllocateMdl(Buffer,     /* Virtual address of buffer */
-                        BufferSize, /* Length of buffer */
-                        FALSE,      /* Not secondary */
-                        FALSE,      /* Don't charge quota */
-                        NULL);      /* Don't use IRP */
+    Mdl = IoAllocateMdl(Buffer,         /* Virtual address */
+                        BufferLength,   /* Length of buffer */
+                        FALSE,          /* Not secondary */
+                        FALSE,          /* Don't charge quota */
+                        *Irp);          /* Don't use IRP */
     if (!Mdl) {
-        AFD_DbgPrint(MIN_TRACE, ("IoAllocateMdl() failed.\n"));
-        IoFreeIrp(Irp);
-        ExFreePool(ConnectInfo);
+        AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
+        IoFreeIrp(*Irp);
         return STATUS_INSUFFICIENT_RESOURCES;
     }
+
 #ifdef _MSC_VER
     try {
 #endif
         MmProbeAndLockPages(Mdl, KernelMode, IoModifyAccess);
 #ifdef _MSC_VER
-    } except(EXCEPTION_EXECUTE_HANDLER) {
+    } except (EXCEPTION_EXECUTE_HANDLER) {
         AFD_DbgPrint(MIN_TRACE, ("MmProbeAndLockPages() failed.\n"));
-        IoFreeIrp(Irp);
-        ExFreePool(ConnectInfo);
-        return STATUS_UNSUCCESSFUL;
+        IoFreeMdl(Mdl);
+        IoFreeIrp(*Irp);
+        return STATUS_INSUFFICIENT_RESOURCES;
     }
 #endif
-#endif
-
-    AFD_DbgPrint(MAX_TRACE, ("TdiBuildSendDatagram()\n"));
-    TdiBuildSendDatagram(Irp,               /* I/O Request Packet */
-                         DeviceObject,      /* Device object */
-                         TransportObject,   /* File object */
-                         NULL,              /* Completion routine */
-                         NULL,              /* Completion context */
-                         Mdl,               /* Descriptor for data buffer */
-                         BufferSize,        /* Size of data to send */
-                         ConnectInfo);      /* Connection information */
-    AFD_DbgPrint(MAX_TRACE, ("Returned from TdiBuildSendDatagram\n"));
-
-    Status = TdiCall(Irp, DeviceObject, &Event, &Iosb);
-    AFD_DbgPrint(MAX_TRACE, ("Returned from TdiCall\n"));
 
-#if 0
-    MmUnlockPages(Mdl);
+    AFD_DbgPrint(MID_TRACE,("AFD>>> Got an MDL: %x\n", Mdl));
 
-    IoFreeMdl(Mdl);
-#endif
+    TdiBuildReceive(*Irp,                   /* I/O Request Packet */
+		    DeviceObject,           /* Device object */
+		    TransportObject,        /* File object */
+		    CompletionRoutine,      /* Completion routine */
+		    CompletionContext,      /* Completion context */
+		    Mdl,                    /* Data buffer */
+		    Flags,                  /* Flags */
+		    BufferLength);          /* Length of data */
 
-    ExFreePool(ConnectInfo);
-    AFD_DbgPrint(MAX_TRACE, ("Leaving %08x.\n", Status));
+    Status = TdiCall(*Irp, DeviceObject, NULL, Iosb);
+    /* Does not block...  The MDL is deleted in the receive completion
+       routine. */
 
     return Status;
 }
 
 
-NTSTATUS TdiReceive(
+NTSTATUS TdiReceiveDatagram(
     PIRP *Irp,
     PFILE_OBJECT TransportObject,
     USHORT Flags,
     PCHAR Buffer,
     UINT BufferLength,
+    PTDI_CONNECTION_INFORMATION Addr,
     PIO_STATUS_BLOCK Iosb,
     PIO_COMPLETION_ROUTINE CompletionRoutine,
     PVOID CompletionContext)
+/*
+ * FUNCTION: Receives a datagram
+ * ARGUMENTS:
+ *     TransportObject = Pointer to transport object
+ *     From            = Receive filter (NULL if none)
+ *     Address         = Address of buffer to place remote address
+ *     Buffer          = Address of buffer to place received data
+ *     BufferSize      = Address of buffer with length of Buffer (updated)
+ * RETURNS:
+ *     Status of operation
+ */
 {
     PDEVICE_OBJECT DeviceObject;
     NTSTATUS Status;
@@ -977,7 +957,7 @@
     }
 
     *Irp = TdiBuildInternalDeviceControlIrp
-	( TDI_RECEIVE,             /* Sub function */
+	( TDI_RECEIVE_DATAGRAM,    /* Sub function */
 	  DeviceObject,            /* Device object */
 	  TransportObject,         /* File object */
 	  NULL,                    /* Event */
@@ -1016,14 +996,17 @@
 
     AFD_DbgPrint(MID_TRACE,("AFD>>> Got an MDL: %x\n", Mdl));
 
-    TdiBuildReceive(*Irp,                   /* I/O Request Packet */
-		    DeviceObject,           /* Device object */
-		    TransportObject,        /* File object */
-		    CompletionRoutine,      /* Completion routine */
-		    CompletionContext,      /* Completion context */
-		    Mdl,                    /* Data buffer */
-		    Flags,                  /* Flags */
-		    BufferLength);          /* Length of data */
+    TdiBuildReceiveDatagram
+	(*Irp,                   /* I/O Request Packet */
+	 DeviceObject,           /* Device object */
+	 TransportObject,        /* File object */
+	 CompletionRoutine,      /* Completion routine */
+	 CompletionContext,      /* Completion context */
+	 Mdl,                    /* Data buffer */
+	 BufferLength,
+	 Addr,
+	 Addr,
+	 Flags);                 /* Length of data */
 
     Status = TdiCall(*Irp, DeviceObject, NULL, Iosb);
     /* Does not block...  The MDL is deleted in the receive completion
@@ -1033,67 +1016,59 @@
 }
 
 
-NTSTATUS TdiReceiveDatagram(
+NTSTATUS TdiSendDatagram(
+    PIRP *Irp,
     PFILE_OBJECT TransportObject,
-    PTA_ADDRESS From,
-    PTA_ADDRESS Address,
-    PUCHAR Buffer,
-    PULONG BufferSize)
+    PCHAR Buffer,
+    UINT BufferLength,
+    PTDI_CONNECTION_INFORMATION Addr,
+    PIO_STATUS_BLOCK Iosb,
+    PIO_COMPLETION_ROUTINE CompletionRoutine,
+    PVOID CompletionContext)
 /*
- * FUNCTION: Receives a datagram
+ * FUNCTION: Sends a datagram
  * ARGUMENTS:
  *     TransportObject = Pointer to transport object
- *     From            = Receive filter (NULL if none)
+ *     From            = Send filter (NULL if none)
  *     Address         = Address of buffer to place remote address
- *     Buffer          = Address of buffer to place received data
+ *     Buffer          = Address of buffer to place sendd data
  *     BufferSize      = Address of buffer with length of Buffer (updated)
  * RETURNS:
  *     Status of operation
  */
 {
-    PTDI_CONNECTION_INFORMATION ReceiveInfo;
-    PTDI_CONNECTION_INFORMATION ReturnInfo = NULL;
     PDEVICE_OBJECT DeviceObject;
-    IO_STATUS_BLOCK Iosb;
     NTSTATUS Status;
-    KEVENT Event;
-    PIRP Irp;
     PMDL Mdl;
 
-    if (From != NULL) {
-        /* FIXME: Check that the socket type match the socket */
-    }
-
     DeviceObject = IoGetRelatedDeviceObject(TransportObject);
     if (!DeviceObject) {
         AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n"));
         return STATUS_INVALID_PARAMETER;
     }
 
-    TdiBuildConnectionInfoPair( &ReceiveInfo, From, Address );
-    
-    KeInitializeEvent(&Event, NotificationEvent, FALSE);
-
-    Irp = TdiBuildInternalDeviceControlIrp(TDI_RECEIVE_DATAGRAM,    /* Sub function */
-                                           DeviceObject,            /* Device object */
-                                           TransportObject,         /* File object */
-                                           &Event,                  /* Event */
-                                           &Iosb);                  /* Status */
-    if (!Irp) {
+    *Irp = TdiBuildInternalDeviceControlIrp
+	( TDI_SEND_DATAGRAM,       /* Sub function */
+	  DeviceObject,            /* Device object */
+	  TransportObject,         /* File object */
+	  NULL,                    /* Event */
+	  Iosb );                  /* Status */
+
+    if (!*Irp) {
         AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
-        ExFreePool(ReceiveInfo);
         return STATUS_INSUFFICIENT_RESOURCES;
     }
 
+    AFD_DbgPrint(MID_TRACE, ("Allocating irp for %x:%d\n", Buffer,BufferLength));
+
     Mdl = IoAllocateMdl(Buffer,         /* Virtual address */
-                        *BufferSize,    /* Length of buffer */
+                        BufferLength,   /* Length of buffer */
                         FALSE,          /* Not secondary */
                         FALSE,          /* Don't charge quota */
-                        NULL);          /* Don't use IRP */
+                        *Irp);          /* Don't use IRP */
     if (!Mdl) {
         AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
-        IoFreeIrp(Irp);
-        ExFreePool(ReceiveInfo);
+        IoFreeIrp(*Irp);
         return STATUS_INSUFFICIENT_RESOURCES;
     }
 
@@ -1105,33 +1080,26 @@
     } except (EXCEPTION_EXECUTE_HANDLER) {
         AFD_DbgPrint(MIN_TRACE, ("MmProbeAndLockPages() failed.\n"));
         IoFreeMdl(Mdl);
-        IoFreeIrp(Irp);
-        ExFreePool(ReceiveInfo);
+        IoFreeIrp(*Irp);
         return STATUS_INSUFFICIENT_RESOURCES;
     }
 #endif
 
-    TdiBuildReceiveDatagram(Irp,                    /* I/O Request Packet */
-                            DeviceObject,           /* Device object */
-                            TransportObject,        /* File object */
-                            NULL,                   /* Completion routine */
-                            NULL,                   /* Completion context */
-                            Mdl,                    /* Data buffer */
-                            *BufferSize,            /* Size of data buffer */
-                            ReceiveInfo,            /* Connection information */
-                            ReturnInfo,             /* Connection information */
-                            TDI_RECEIVE_NORMAL);    /* Flags */
-    Status = TdiCall(Irp, DeviceObject, &Event, &Iosb);
-    if (NT_SUCCESS(Status)) {
-        *BufferSize = Iosb.Information;
-	TaCopyAddressInPlace( Address, TdiGetRemoteAddress(ReturnInfo) );
-    }
-
-    MmUnlockPages(Mdl);
+    AFD_DbgPrint(MID_TRACE,("AFD>>> Got an MDL: %x\n", Mdl));
 
-    IoFreeMdl(Mdl);
+    TdiBuildSendDatagram
+	(*Irp,                   /* I/O Request Packet */
+	 DeviceObject,           /* Device object */
+	 TransportObject,        /* File object */
+	 CompletionRoutine,      /* Completion routine */
+	 CompletionContext,      /* Completion context */
+	 Mdl,                    /* Data buffer */
+	 BufferLength,           /* Bytes to send */
+	 Addr);                  /* Address */
 
-    ExFreePool(ReceiveInfo);
+    Status = TdiCall(*Irp, DeviceObject, NULL, Iosb);
+    /* Does not block...  The MDL is deleted in the send completion
+       routine. */
 
     return Status;
 }

reactos/drivers/net/afd/afd
write.c 1.1.2.2 -> 1.1.2.3
diff -u -r1.1.2.2 -r1.1.2.3
--- write.c	11 Jul 2004 23:04:35 -0000	1.1.2.2
+++ write.c	14 Jul 2004 16:54:14 -0000	1.1.2.3
@@ -1,4 +1,4 @@
-/* $Id: write.c,v 1.1.2.2 2004/07/11 23:04:35 arty Exp $
+/* $Id: write.c,v 1.1.2.3 2004/07/14 16:54:14 arty Exp $
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
  * FILE:             drivers/net/afd/afd/write.c
@@ -224,8 +224,34 @@
 }
 
 NTSTATUS STDCALL
-AfdPacketSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp) {
-    Irp->IoStatus.Information = 0;
-    return STATUS_SUCCESS;
+AfdPacketSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp, 
+			 PIO_STACK_LOCATION IrpSp) {
+    NTSTATUS Status = STATUS_SUCCESS;
+    PFILE_OBJECT FileObject = IrpSp->FileObject;
+    PAFD_FCB FCB = FileObject->FsContext;
+    PAFD_SEND_REQ SendReq = Irp->AssociatedIrp.SystemBuffer;
+   
+    AFD_DbgPrint(MID_TRACE,("Called on %x\n", FCB));
+
+    if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );
+    
+    /* Check the size of the Address given ... */
+
+    Status = TdiSendDatagram
+	( &FCB->SendIrp.InFlightRequest,
+	  FCB->AddressFile.Object,
+	  SendReq->BufferArray[0].buf,
+	  SendReq->BufferArray[0].len,
+	  &SendReq->Address,
+	  &FCB->SendIrp.Iosb,
+	  NULL,
+	  NULL );
+
+    if( Status == STATUS_PENDING ) Status = STATUS_SUCCESS;
+    
+    AFD_DbgPrint(MID_TRACE,("Dismissing request: %x\n", Status));
+    
+    return UnlockAndMaybeComplete
+	( FCB, Status, Irp, SendReq->BufferArray[0].len, NULL );
 }
 

reactos/drivers/net/afd/include
afd.h 1.18.10.1 -> 1.18.10.2
diff -u -r1.18.10.1 -r1.18.10.2
--- afd.h	9 Jul 2004 04:41:18 -0000	1.18.10.1
+++ afd.h	14 Jul 2004 16:54:14 -0000	1.18.10.2
@@ -1,4 +1,4 @@
-/* $Id: afd.h,v 1.18.10.1 2004/07/09 04:41:18 arty Exp $
+/* $Id: afd.h,v 1.18.10.2 2004/07/14 16:54:14 arty Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
@@ -49,13 +49,18 @@
 
 #define FUNCTION_CONNECT                0
 #define FUNCTION_RECV                   1
-#define FUNCTION_SEND                   2
-#define FUNCTION_CLOSE                  3
-#define MAX_FUNCTIONS                   4
+#define FUNCTION_RECV_DATAGRAM          2
+#define FUNCTION_SEND                   3
+#define FUNCTION_CLOSE                  4
+#define MAX_FUNCTIONS                   5
+
+#define IN_FLIGHT_REQUESTS              3
 
 #define DEFAULT_SEND_WINDOW_SIZE        16384
 #define DEFAULT_RECEIVE_WINDOW_SIZE     16384
 
+#define SGID_CONNECTIONLESS             1 /* XXX Find this flag */
+
 typedef struct _AFD_MAPBUF {
     PVOID BufferAddress;
     PMDL  Mdl;
@@ -96,9 +101,16 @@
     UINT BytesUsed, Size, Content;
 } AFD_DATA_WINDOW, *PAFD_DATA_WINDOW;
 
+typedef struct _AFD_STORED_DATAGRAM {
+    LIST_ENTRY ListEntry;
+    UINT Len;
+    PTA_ADDRESS Address;
+    CHAR Buffer[1];
+} AFD_STORED_DATAGRAM, *PAFD_STORED_DATAGRAM;
+
 typedef struct _AFD_FCB {
     BOOLEAN Locked;
-    UINT State;
+    UINT State, Flags;
     KIRQL OldIrql;
     UINT LockCount;
     PVOID CurrentThread;
@@ -106,9 +118,8 @@
     PFILE_OBJECT FileObject;
     PAFD_DEVICE_EXTENSION DeviceExt;
     BOOLEAN DelayedAccept;
-    PTRANSPORT_ADDRESS LocalAddress;
-    PTRANSPORT_ADDRESS RemoteAddress;
-    IO_STATUS_BLOCK ReceiveIosb;
+    PTRANSPORT_ADDRESS LocalAddress, RemoteAddress;
+    PTDI_CONNECTION_INFORMATION AddressFrom;
     AFD_TDI_OBJECT AddressFile, Connection;
     AFD_IN_FLIGHT_REQUEST ListenIrp, ReceiveIrp, SendIrp;
     AFD_DATA_WINDOW Send, Recv;
@@ -120,6 +131,7 @@
     UINT ContextSize;
     PIRP PendingTdiIrp;
     LIST_ENTRY PendingIrpList[MAX_FUNCTIONS];
+    LIST_ENTRY DatagramList;
 } AFD_FCB, *PAFD_FCB;
 
 /* bind.c */
@@ -179,11 +191,18 @@
 ( PDEVICE_OBJECT DeviceObject,
   PIRP Irp,
   PVOID Context );
+
+NTSTATUS DDKAPI PacketSocketRecvComplete
+( PDEVICE_OBJECT DeviceObject,
+  PIRP Irp,
+  PVOID Context );
+
 NTSTATUS STDCALL
 AfdConnectedSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp, 
 			   PIO_STACK_LOCATION IrpSp, BOOLEAN Short);
 NTSTATUS STDCALL
-AfdPacketSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp );
+AfdPacketSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp
+			PIO_STACK_LOCATION IrpSp );
 
 /* select.c */
 
@@ -232,12 +251,34 @@
   PIO_COMPLETION_ROUTINE  CompletionRoutine,
   PVOID CompletionContext);
 
+NTSTATUS TdiReceiveDatagram(
+    PIRP *Irp,
+    PFILE_OBJECT TransportObject,
+    USHORT Flags,
+    PCHAR Buffer,
+    UINT BufferLength,
+    PTDI_CONNECTION_INFORMATION From,
+    PIO_STATUS_BLOCK Iosb,
+    PIO_COMPLETION_ROUTINE CompletionRoutine,
+    PVOID CompletionContext);
+
+NTSTATUS TdiSendDatagram(
+    PIRP *Irp,
+    PFILE_OBJECT TransportObject,
+    PCHAR Buffer,
+    UINT BufferLength,
+    PTDI_CONNECTION_INFORMATION To,
+    PIO_STATUS_BLOCK Iosb,
+    PIO_COMPLETION_ROUTINE CompletionRoutine,
+    PVOID CompletionContext);
+
 /* write.c */
 
 NTSTATUS STDCALL
 AfdConnectedSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp, 
 			    PIO_STACK_LOCATION IrpSp, BOOLEAN Short);
 NTSTATUS STDCALL
-AfdPacketSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp);
+AfdPacketSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp
+			 PIO_STACK_LOCATION IrpSp);
 
 #endif/*_AFD_H*/
CVSspam 0.2.8