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);