More work on winsock stack (ping is now working)
[reactos.git] / reactos / drivers / net / afd / afd / routines.c
index 987bef8..2947304 100644 (file)
@@ -8,72 +8,76 @@
  *   CSH 01/02-2001 Created
  */
 #include <afd.h>
+#include <debug.h>
 
 
 ULONG WSABufferSize(
-    LPWSABUF Buffers,
-    DWORD BufferCount)
+  LPWSABUF Buffers,
+  DWORD BufferCount)
 {
-    ULONG i;
-    LPWSABUF p;
-    ULONG Count = 0;
-
-    p = Buffers;
-    for (i = 0; i < BufferCount; i++) {
-        Count += p->len;
-        p++;
-    }
+  ULONG i;
+  LPWSABUF p;
+  ULONG Count = 0;
+
+  p = Buffers;
+  for (i = 0; i < BufferCount; i++) {
+    Count += p->len;
+    p++;
+  }
 
-    AFD_DbgPrint(MAX_TRACE, ("Buffer is %d bytes.\n", Count));
+  AFD_DbgPrint(MAX_TRACE, ("Buffer is %d bytes.\n", Count));
 
-    return Count;
+  return Count;
 }
 
 
 NTSTATUS MergeWSABuffers(
-    LPWSABUF Buffers,
-    DWORD BufferCount,
-    PVOID Destination,
-    ULONG MaxLength,
-    PULONG BytesCopied)
+  LPWSABUF Buffers,
+  DWORD BufferCount,
+  PVOID Destination,
+  ULONG MaxLength,
+  PULONG BytesCopied)
 {
-    NTSTATUS Status;
-    ULONG Length;
-    LPWSABUF p;
-    ULONG i;
+  NTSTATUS Status;
+  ULONG Length;
+  LPWSABUF p;
+  ULONG i;
+
+  *BytesCopied = 0;
+  if (BufferCount == 0)
+    return STATUS_SUCCESS;
+
+  p = Buffers;
 
-    *BytesCopied = 0;
-    if (BufferCount == 0)
-        return STATUS_SUCCESS;
+  AFD_DbgPrint(MAX_TRACE, ("Destination is 0x%X\n", Destination));
+  AFD_DbgPrint(MAX_TRACE, ("p is 0x%X\n", p));
 
-    p = Buffers;
+  for (i = 0; i < BufferCount; i++) {
+    Length = p->len;
+    if (Length > MaxLength)
+      /* Don't copy out of bounds */
+      Length = MaxLength;
 
+    RtlCopyMemory(Destination, p->buf, Length);
+    Destination += Length;
     AFD_DbgPrint(MAX_TRACE, ("Destination is 0x%X\n", Destination));
+    p++;
     AFD_DbgPrint(MAX_TRACE, ("p is 0x%X\n", p));
 
-    for (i = 0; i < BufferCount; i++) {
-        Length = p->len;
-        if (Length > MaxLength)
-            /* Don't copy out of bounds */
-            Length = MaxLength;
+    *BytesCopied += Length;
 
-        RtlCopyMemory(Destination, p->buf, Length);
-        Destination += Length;
-        AFD_DbgPrint(MAX_TRACE, ("Destination is 0x%X\n", Destination));
-        p++;
-        AFD_DbgPrint(MAX_TRACE, ("p is 0x%X\n", p));
-
-        *BytesCopied += Length;
-
-        MaxLength -= Length;
-        if (MaxLength == 0)
-            /* Destination buffer is full */
-            break;
-    }
+    MaxLength -= Length;
+    if (MaxLength == 0)
+      /* Destination buffer is full */
+      break;
+  }
 
-    return STATUS_SUCCESS;
+  return STATUS_SUCCESS;
 }
 
+/*
+ * NOTES: ReceiveQueueLock must be acquired for the FCB when called
+ */
 NTSTATUS FillWSABuffers(
     PAFDFCB FCB,
     LPWSABUF Buffers,
@@ -83,7 +87,7 @@ NTSTATUS FillWSABuffers(
   NTSTATUS Status;
   PUCHAR DstData, SrcData;
   UINT DstSize, SrcSize;
-  UINT Count, Total, Length;
+  UINT Count, Total;
   PAFD_BUFFER SrcBuffer;
   PLIST_ENTRY Entry;
   ULONG Size;
@@ -92,6 +96,11 @@ NTSTATUS FillWSABuffers(
   if (BufferCount == 0)
     return STATUS_SUCCESS;
 
+  if (IsListEmpty(&FCB->ReceiveQueue))
+    return STATUS_SUCCESS;
+
+  Entry = RemoveHeadList(&FCB->ReceiveQueue);
+  SrcBuffer = CONTAINING_RECORD(Entry, AFD_BUFFER, ListEntry);
   SrcData = SrcBuffer->Buffer.buf;
   SrcSize = SrcBuffer->Buffer.len;
 
@@ -101,25 +110,32 @@ NTSTATUS FillWSABuffers(
   /* Copy the data */
   for (Total = 0;;) {
     /* Find out how many bytes we can copy at one time */
-    if (Length < SrcSize)
-      Count = Length;
+    if (DstSize < SrcSize)
+      Count = DstSize;
     else
       Count = SrcSize;
-    if (DstSize < Count)
-      Count = DstSize;
+
+    AFD_DbgPrint(MAX_TRACE, ("DstData (0x%X) SrcData (0x%X) Count (0x%X).\n",
+      DstData, SrcData, Count));
 
     RtlCopyMemory((PVOID)DstData, (PVOID)SrcData, Count);
 
-    Total  += Count;
-    Length -= Count;
+    Total += Count;
 
     SrcSize -= Count;
     if (SrcSize == 0) {
       ExFreePool(SrcBuffer->Buffer.buf);
       ExFreePool(SrcBuffer);
 
-      /* No more bytes in source buffer. Proceed to
-         the next buffer in the source buffer chain */
+      /* No more bytes in source buffer. Proceed to the next buffer
+         in the source buffer chain if there is one */
+      if (IsListEmpty(&FCB->ReceiveQueue)) {
+        SrcBuffer = NULL;
+        SrcData = 0;
+        SrcSize = 0;
+        break;
+      }
+
       Entry = RemoveHeadList(&FCB->ReceiveQueue);
       SrcBuffer = CONTAINING_RECORD(Entry, AFD_BUFFER, ListEntry);
       SrcData = SrcBuffer->Buffer.buf;
@@ -137,13 +153,13 @@ NTSTATUS FillWSABuffers(
       DstData = Buffers->buf;
       DstSize = Buffers->len;
     }
-
-    if (Length == 0)
-      break;
   }
 
   if (SrcSize > 0) {
     InsertHeadList(&FCB->ReceiveQueue, Entry);
+  } else if (SrcBuffer != NULL) {
+    ExFreePool(SrcBuffer->Buffer.buf);
+    ExFreePool(SrcBuffer);
   }
 
   *BytesCopied = Total;
@@ -165,61 +181,61 @@ ULONG ChecksumCompute(
  *     Checksum of buffer
  */
 {
-    /* FIXME: This should be done in assembler */
+  /* FIXME: This should be done in assembler */
 
-    register ULONG Sum = Seed;
+  register ULONG Sum = Seed;
 
-    while (Count > 1) {
-        Sum             += *(PUSHORT)Data;
-        Count           -= 2;
-        (ULONG_PTR)Data += 2;
-    }
+  while (Count > 1) {
+    Sum             += *(PUSHORT)Data;
+    Count           -= 2;
+    (ULONG_PTR)Data += 2;
+  }
 
-    /* Add left-over byte, if any */
-    if (Count > 0)
-        Sum += *(PUCHAR)Data;
+  /* Add left-over byte, if any */
+  if (Count > 0)
+    Sum += *(PUCHAR)Data;
 
-    /* Fold 32-bit sum to 16 bits */
-    while (Sum >> 16)
-        Sum = (Sum & 0xFFFF) + (Sum >> 16);
+  /* Fold 32-bit sum to 16 bits */
+  while (Sum >> 16)
+    Sum = (Sum & 0xFFFF) + (Sum >> 16);
 
-    return ~Sum;
+  return ~Sum;
 }
 
 VOID BuildIPv4Header(
-    PIPv4_HEADER IPHeader,
-    ULONG TotalSize,
-    ULONG Protocol,
-    PSOCKADDR SourceAddress,
-    PSOCKADDR DestinationAddress)
+  PIPv4_HEADER IPHeader,
+  ULONG TotalSize,
+  ULONG Protocol,
+  PSOCKADDR SourceAddress,
+  PSOCKADDR DestinationAddress)
 {
-    PSOCKADDR_IN SrcNameIn = (PSOCKADDR_IN)SourceAddress;
-    PSOCKADDR_IN DstNameIn = (PSOCKADDR_IN)DestinationAddress;
-
-    /* Version = 4, Length = 5 DWORDs */
-    IPHeader->VerIHL = 0x45;
-    /* Normal Type-of-Service */
-    IPHeader->Tos = 0;
-    /* Length of header and data */
-    IPHeader->TotalLength = WH2N((USHORT)TotalSize);
-    /* Identification */
-    IPHeader->Id = 0;
-    /* One fragment at offset 0 */
-    IPHeader->FlagsFragOfs = 0;
-    /* Time-to-Live is 128 */
-    IPHeader->Ttl = 128;
-    /* Protocol number */
-    IPHeader->Protocol = Protocol;
-    /* Checksum is 0 (calculated later) */
-    IPHeader->Checksum = 0;
-    /* Source address */
-    IPHeader->SrcAddr = SrcNameIn->sin_addr.S_un.S_addr;
-    /* Destination address */
-    IPHeader->DstAddr = DstNameIn->sin_addr.S_un.S_addr;
-
-    /* Calculate checksum of IP header */
-    IPHeader->Checksum = (USHORT)
-        ChecksumCompute(IPHeader, sizeof(IPv4_HEADER), 0);
+  PSOCKADDR_IN SrcNameIn = (PSOCKADDR_IN)SourceAddress;
+  PSOCKADDR_IN DstNameIn = (PSOCKADDR_IN)DestinationAddress;
+
+  /* Version = 4, Length = 5 DWORDs */
+  IPHeader->VerIHL = 0x45;
+  /* Normal Type-of-Service */
+  IPHeader->Tos = 0;
+  /* Length of header and data */
+  IPHeader->TotalLength = WH2N((USHORT)TotalSize);
+  /* Identification */
+  IPHeader->Id = 0;
+  /* One fragment at offset 0 */
+  IPHeader->FlagsFragOfs = 0;
+  /* Time-to-Live is 128 */
+  IPHeader->Ttl = 128;
+  /* Protocol number */
+  IPHeader->Protocol = Protocol;
+  /* Checksum is 0 (calculated later) */
+  IPHeader->Checksum = 0;
+  /* Source address */
+  IPHeader->SrcAddr = SrcNameIn->sin_addr.S_un.S_addr;
+  /* Destination address */
+  IPHeader->DstAddr = DstNameIn->sin_addr.S_un.S_addr;
+
+  /* Calculate checksum of IP header */
+  IPHeader->Checksum = (USHORT)
+    ChecksumCompute(IPHeader, sizeof(IPv4_HEADER), 0);
 }
 
 /* EOF */