2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS TCP/IP protocol driver
5 * PURPOSE: Miscellaneous operations on NDIS_BUFFERs and packets.
6 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
8 * CSH 01/08-2000 Created
13 __inline INT
SkipToOffset(
19 * FUNCTION: Skip Offset bytes into a buffer chain
21 * Buffer = Pointer to NDIS buffer
22 * Offset = Number of bytes to skip
23 * Data = Address of a pointer that on return will contain the
24 * address of the offset in the buffer
25 * Size = Address of a pointer that on return will contain the
26 * size of the destination buffer
28 * Offset into buffer, -1 if buffer chain was smaller than Offset bytes
38 NdisQueryBuffer(Buffer
, (PVOID
)Data
, Size
);
41 *Data
= (PCHAR
)((ULONG_PTR
) *Data
+ Offset
);
48 NdisGetNextBuffer(Buffer
, &Buffer
);
55 UINT
CopyBufferToBufferChain(
56 PNDIS_BUFFER DstBuffer
,
61 * FUNCTION: Copies data from a buffer to an NDIS buffer chain
63 * DstBuffer = Pointer to destination NDIS buffer
64 * DstOffset = Destination start offset
65 * SrcData = Pointer to source buffer
66 * Length = Number of bytes to copy
68 * Number of bytes copied to destination buffer
70 * The number of bytes copied may be limited by the destination
74 UINT BytesCopied
, BytesToCopy
, DstSize
;
77 TI_DbgPrint(DEBUG_PBUFFER
, ("DstBuffer (0x%X) DstOffset (0x%X) SrcData (0x%X) Length (%d)\n", DstBuffer
, DstOffset
, SrcData
, Length
));
79 /* Skip DstOffset bytes in the destination buffer chain */
80 if (SkipToOffset(DstBuffer
, DstOffset
, &DstData
, &DstSize
) == -1)
83 /* Start copying the data */
86 BytesToCopy
= MIN(DstSize
, Length
);
88 RtlCopyMemory((PVOID
)DstData
, (PVOID
)SrcData
, BytesToCopy
);
89 BytesCopied
+= BytesToCopy
;
90 SrcData
= (PCHAR
)((ULONG_PTR
)SrcData
+ BytesToCopy
);
92 Length
-= BytesToCopy
;
96 DstSize
-= BytesToCopy
;
98 /* No more bytes in desination buffer. Proceed to
99 the next buffer in the destination buffer chain */
100 NdisGetNextBuffer(DstBuffer
, &DstBuffer
);
104 NdisQueryBuffer(DstBuffer
, (PVOID
)&DstData
, &DstSize
);
112 UINT
CopyBufferChainToBuffer(
114 PNDIS_BUFFER SrcBuffer
,
118 * FUNCTION: Copies data from an NDIS buffer chain to a buffer
120 * DstData = Pointer to destination buffer
121 * SrcBuffer = Pointer to source NDIS buffer
122 * SrcOffset = Source start offset
123 * Length = Number of bytes to copy
125 * Number of bytes copied to destination buffer
127 * The number of bytes copied may be limited by the source
131 UINT BytesCopied
, BytesToCopy
, SrcSize
;
134 TI_DbgPrint(DEBUG_PBUFFER
, ("DstData 0x%X SrcBuffer 0x%X SrcOffset 0x%X Length %d\n",DstData
,SrcBuffer
, SrcOffset
, Length
));
136 /* Skip SrcOffset bytes in the source buffer chain */
137 if (SkipToOffset(SrcBuffer
, SrcOffset
, &SrcData
, &SrcSize
) == -1)
140 /* Start copying the data */
143 BytesToCopy
= MIN(SrcSize
, Length
);
145 TI_DbgPrint(DEBUG_PBUFFER
, ("Copying (%d) bytes from 0x%X to 0x%X\n", BytesToCopy
, SrcData
, DstData
));
147 RtlCopyMemory((PVOID
)DstData
, (PVOID
)SrcData
, BytesToCopy
);
148 BytesCopied
+= BytesToCopy
;
149 DstData
= (PCHAR
)((ULONG_PTR
)DstData
+ BytesToCopy
);
151 Length
-= BytesToCopy
;
155 SrcSize
-= BytesToCopy
;
157 /* No more bytes in source buffer. Proceed to
158 the next buffer in the source buffer chain */
159 NdisGetNextBuffer(SrcBuffer
, &SrcBuffer
);
163 NdisQueryBuffer(SrcBuffer
, (PVOID
)&SrcData
, &SrcSize
);
171 UINT
CopyPacketToBuffer(
173 PNDIS_PACKET SrcPacket
,
177 * FUNCTION: Copies data from an NDIS packet to a buffer
179 * DstData = Pointer to destination buffer
180 * SrcPacket = Pointer to source NDIS packet
181 * SrcOffset = Source start offset
182 * Length = Number of bytes to copy
184 * Number of bytes copied to destination buffer
186 * The number of bytes copied may be limited by the source
190 PNDIS_BUFFER FirstBuffer
;
195 TI_DbgPrint(DEBUG_PBUFFER
, ("DstData (0x%X) SrcPacket (0x%X) SrcOffset (0x%X) Length (%d)\n", DstData
, SrcPacket
, SrcOffset
, Length
));
197 NdisGetFirstBufferFromPacket(SrcPacket
,
203 return CopyBufferChainToBuffer(DstData
, FirstBuffer
, SrcOffset
, Length
);
207 UINT
CopyPacketToBufferChain(
208 PNDIS_BUFFER DstBuffer
,
210 PNDIS_PACKET SrcPacket
,
214 * FUNCTION: Copies data from an NDIS packet to an NDIS buffer chain
216 * DstBuffer = Pointer to destination NDIS buffer
217 * DstOffset = Destination start offset
218 * SrcPacket = Pointer to source NDIS packet
219 * SrcOffset = Source start offset
220 * Length = Number of bytes to copy
222 * Number of bytes copied to destination buffer
224 * The number of bytes copied may be limited by the source and
225 * destination buffer sizes
228 PNDIS_BUFFER SrcBuffer
;
229 PCHAR DstData
, SrcData
;
230 UINT DstSize
, SrcSize
;
233 TI_DbgPrint(DEBUG_PBUFFER
, ("DstBuffer (0x%X) DstOffset (0x%X) SrcPacket (0x%X) SrcOffset (0x%X) Length (%d)\n", DstBuffer
, DstOffset
, SrcPacket
, SrcOffset
, Length
));
235 /* Skip DstOffset bytes in the destination buffer chain */
236 NdisQueryBuffer(DstBuffer
, (PVOID
)&DstData
, &DstSize
);
237 if (SkipToOffset(DstBuffer
, DstOffset
, &DstData
, &DstSize
) == -1)
240 /* Skip SrcOffset bytes in the source packet */
241 NdisGetFirstBufferFromPacket(SrcPacket
, &SrcBuffer
, &SrcData
, &SrcSize
, &Total
);
242 if (SkipToOffset(SrcBuffer
, SrcOffset
, &SrcData
, &SrcSize
) == -1)
247 /* Find out how many bytes we can copy at one time */
248 if (Length
< SrcSize
)
255 RtlCopyMemory((PVOID
)DstData
, (PVOID
)SrcData
, Count
);
264 /* No more bytes in destination buffer. Proceed to
265 the next buffer in the destination buffer chain */
266 NdisGetNextBuffer(DstBuffer
, &DstBuffer
);
270 NdisQueryBuffer(DstBuffer
, (PVOID
)&DstData
, &DstSize
);
275 /* No more bytes in source buffer. Proceed to
276 the next buffer in the source buffer chain */
277 NdisGetNextBuffer(SrcBuffer
, &SrcBuffer
);
281 NdisQueryBuffer(SrcBuffer
, (PVOID
)&SrcData
, &SrcSize
);
293 * FUNCTION: Resizes an NDIS packet
295 * Packet = Pointer to packet
296 * Size = Number of bytes in first buffer
298 * Previous size of first buffer
301 PNDIS_BUFFER NdisBuffer
;
304 NdisQueryPacket(Packet
, NULL
, NULL
, &NdisBuffer
, NULL
);
306 OldSize
= NdisBuffer
->ByteCount
;
309 NdisBuffer
->ByteCount
= Size
;
314 NDIS_STATUS
PrependPacket( PNDIS_PACKET Packet
, PCHAR Data
, UINT Length
,
321 NewBuf
= ExAllocatePool( NonPagedPool
, Length
);
322 if( !NewBuf
) return STATUS_NO_MEMORY
;
323 RtlCopyMemory( NewBuf
, Data
, Length
);
324 } else NewBuf
= Data
;
326 NdisAllocateBuffer( &Status
, &Buffer
, GlobalBufferPool
, Data
, Length
);
327 if( Status
!= NDIS_STATUS_SUCCESS
) return Status
;
329 NdisChainBufferAtFront( Packet
, Buffer
);
331 return STATUS_SUCCESS
;
334 void GetDataPtr( PNDIS_PACKET Packet
,
340 NdisQueryPacket(Packet
, NULL
, NULL
, &Buffer
, NULL
);
341 if( !Buffer
) return;
342 SkipToOffset( Buffer
, Offset
, DataOut
, Size
);
345 NDIS_STATUS
AllocatePacketWithBufferX( PNDIS_PACKET
*NdisPacket
,
346 PCHAR Data
, UINT Len
,
347 PCHAR File
, UINT Line
) {
353 NewData
= ExAllocatePool( NonPagedPool
, Len
);
354 if( !NewData
) return NDIS_STATUS_NOT_ACCEPTED
; // XXX
355 TrackWithTag(EXALLOC_TAG
, NewData
, File
, Line
);
357 if( Data
) RtlCopyMemory(NewData
, Data
, Len
);
359 NdisAllocatePacket( &Status
, &Packet
, GlobalPacketPool
);
360 if( Status
!= NDIS_STATUS_SUCCESS
) {
361 UntrackFL( File
, Line
, NewData
);
362 ExFreePool( NewData
);
365 TrackWithTag(NDIS_PACKET_TAG
, Packet
, File
, Line
);
367 NdisAllocateBuffer( &Status
, &Buffer
, GlobalBufferPool
, NewData
, Len
);
368 if( Status
!= NDIS_STATUS_SUCCESS
) {
369 UntrackFL( File
, Line
, NewData
);
370 ExFreePool( NewData
);
371 UntrackFL( File
, Line
, Packet
);
372 FreeNdisPacket( Packet
);
375 TrackWithTag(NDIS_BUFFER_TAG
, Buffer
, File
, Line
);
377 NdisChainBufferAtFront( Packet
, Buffer
);
378 *NdisPacket
= Packet
;
380 return NDIS_STATUS_SUCCESS
;
385 ( PNDIS_PACKET Packet
,
389 * FUNCTION: Frees an NDIS packet
391 * Packet = Pointer to NDIS packet to be freed
394 PNDIS_BUFFER Buffer
, NextBuffer
;
396 TI_DbgPrint(DEBUG_PBUFFER
, ("Packet (0x%X)\n", Packet
));
398 /* Free all the buffers in the packet first */
399 NdisQueryPacket(Packet
, NULL
, NULL
, &Buffer
, NULL
);
400 for (; Buffer
!= NULL
; Buffer
= NextBuffer
) {
404 NdisGetNextBuffer(Buffer
, &NextBuffer
);
405 NdisQueryBuffer(Buffer
, &Data
, &Length
);
406 TI_DbgPrint(DEBUG_PBUFFER
, ("Freeing ndis buffer (0x%X)\n", Buffer
));
407 UntrackFL(File
,Line
,Buffer
);
408 NdisFreeBuffer(Buffer
);
409 TI_DbgPrint(DEBUG_PBUFFER
, ("Freeing exal buffer (0x%X)\n", Data
));
410 UntrackFL(File
,Line
,Data
);
414 /* Finally free the NDIS packet discriptor */
415 UntrackFL(File
,Line
,Packet
);
416 NdisFreePacket(Packet
);