2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Ancillary Function Driver
5 * PURPOSE: Support routines
6 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
8 * CSH 01/02-2001 Created
23 for (i = 0; i < BufferCount; i++) {
28 AFD_DbgPrint(MAX_TRACE, ("Buffer is %d bytes.\n", Count));
34 NTSTATUS MergeWSABuffers(
48 return STATUS_SUCCESS;
52 AFD_DbgPrint(MAX_TRACE, ("Destination is 0x%X\n", Destination));
53 AFD_DbgPrint(MAX_TRACE, ("p is 0x%X\n", p));
55 for (i = 0; i < BufferCount; i++) {
57 if (Length > MaxLength)
58 /* Don't copy out of bounds */
61 RtlCopyMemory(Destination, p->buf, Length);
62 Destination += Length;
63 AFD_DbgPrint(MAX_TRACE, ("Destination is 0x%X\n", Destination));
65 AFD_DbgPrint(MAX_TRACE, ("p is 0x%X\n", p));
67 *BytesCopied += Length;
71 /* Destination buffer is full */
75 return STATUS_SUCCESS;
79 * NOTES: ReceiveQueueLock must be acquired for the FCB when called
81 NTSTATUS FillWSABuffers(
88 PUCHAR DstData, SrcData;
89 UINT DstSize, SrcSize;
91 PAFD_BUFFER SrcBuffer;
97 return STATUS_SUCCESS;
99 if (IsListEmpty(&FCB->ReceiveQueue))
100 return STATUS_SUCCESS;
102 Entry = RemoveHeadList(&FCB->ReceiveQueue);
103 SrcBuffer = CONTAINING_RECORD(Entry, AFD_BUFFER, ListEntry);
104 SrcData = SrcBuffer->Buffer.buf;
105 SrcSize = SrcBuffer->Buffer.len;
107 DstData = Buffers->buf;
108 DstSize = Buffers->len;
112 /* Find out how many bytes we can copy at one time */
113 if (DstSize < SrcSize)
118 AFD_DbgPrint(MAX_TRACE, ("DstData (0x%X) SrcData (0x%X) Count (0x%X).\n",
119 DstData, SrcData, Count));
121 RtlCopyMemory((PVOID)DstData, (PVOID)SrcData, Count);
127 ExFreePool(SrcBuffer->Buffer.buf);
128 ExFreePool(SrcBuffer);
130 /* No more bytes in source buffer. Proceed to the next buffer
131 in the source buffer chain if there is one */
132 if (IsListEmpty(&FCB->ReceiveQueue)) {
139 Entry = RemoveHeadList(&FCB->ReceiveQueue);
140 SrcBuffer = CONTAINING_RECORD(Entry, AFD_BUFFER, ListEntry);
141 SrcData = SrcBuffer->Buffer.buf;
142 SrcSize = SrcBuffer->Buffer.len;
147 /* No more bytes in destination buffer. Proceed to
148 the next buffer in the destination buffer chain */
153 DstData = Buffers->buf;
154 DstSize = Buffers->len;
159 InsertHeadList(&FCB->ReceiveQueue, Entry);
160 } else if (SrcBuffer != NULL) {
161 ExFreePool(SrcBuffer->Buffer.buf);
162 ExFreePool(SrcBuffer);
165 *BytesCopied = Total;
167 return STATUS_SUCCESS;
170 ULONG ChecksumCompute(
175 * FUNCTION: Calculate checksum of a buffer
177 * Data = Pointer to buffer with data
178 * Count = Number of bytes in buffer
179 * Seed = Previously calculated checksum (if any)
184 /* FIXME: This should be done in assembler */
186 register ULONG Sum = Seed;
189 Sum += *(PUSHORT)Data;
191 (ULONG_PTR)Data += 2;
194 /* Add left-over byte, if any */
196 Sum += *(PUCHAR)Data;
198 /* Fold 32-bit sum to 16 bits */
200 Sum = (Sum & 0xFFFF) + (Sum >> 16);
205 VOID BuildIPv4Header(
206 PIPv4_HEADER IPHeader,
209 PSOCKADDR SourceAddress,
210 PSOCKADDR DestinationAddress)
212 PSOCKADDR_IN SrcNameIn = (PSOCKADDR_IN)SourceAddress;
213 PSOCKADDR_IN DstNameIn = (PSOCKADDR_IN)DestinationAddress;
215 /* Version = 4, Length = 5 DWORDs */
216 IPHeader->VerIHL = 0x45;
217 /* Normal Type-of-Service */
219 /* Length of header and data */
220 IPHeader->TotalLength = WH2N((USHORT)TotalSize);
223 /* One fragment at offset 0 */
224 IPHeader->FlagsFragOfs = 0;
225 /* Time-to-Live is 128 */
227 /* Protocol number */
228 IPHeader->Protocol = Protocol;
229 /* Checksum is 0 (calculated later) */
230 IPHeader->Checksum = 0;
232 IPHeader->SrcAddr = SrcNameIn->sin_addr.S_un.S_addr;
233 /* Destination address */
234 IPHeader->DstAddr = DstNameIn->sin_addr.S_un.S_addr;
236 /* Calculate checksum of IP header */
237 IPHeader->Checksum = (USHORT)
238 ChecksumCompute(IPHeader, sizeof(IPv4_HEADER), 0);