ReactOS 0.4.15-dev-7924-g5949c20
buffer.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS TCP/IP protocol driver
4 * FILE: tcpip/buffer.c
5 * PURPOSE: Miscellaneous operations on NDIS_BUFFERs and packets.
6 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
7 * REVISIONS:
8 * CSH 01/08-2000 Created
9 */
10
11#include "precomp.h"
12
13static inline
17 PCHAR *Data,
18 PUINT Size)
19/*
20 * FUNCTION: Skip Offset bytes into a buffer chain
21 * ARGUMENTS:
22 * Buffer = Pointer to NDIS buffer
23 * Offset = Number of bytes to skip
24 * Data = Address of a pointer that on return will contain the
25 * address of the offset in the buffer
26 * Size = Address of a pointer that on return will contain the
27 * size of the destination buffer
28 * RETURNS:
29 * Offset into buffer, -1 if buffer chain was smaller than Offset bytes
30 * NOTES:
31 * Buffer may be NULL
32 */
33{
34 for (;;) {
35
36 if (!Buffer)
37 return -1;
38
40
41 if (Offset < *Size) {
42 *Data = (PCHAR)((ULONG_PTR) *Data + Offset);
43 *Size -= Offset;
44 break;
45 }
46
47 Offset -= *Size;
48
50 }
51
52 return Offset;
53}
54
55
57 PNDIS_BUFFER DstBuffer,
58 UINT DstOffset,
59 PCHAR SrcData,
61/*
62 * FUNCTION: Copies data from a buffer to an NDIS buffer chain
63 * ARGUMENTS:
64 * DstBuffer = Pointer to destination NDIS buffer
65 * DstOffset = Destination start offset
66 * SrcData = Pointer to source buffer
67 * Length = Number of bytes to copy
68 * RETURNS:
69 * Number of bytes copied to destination buffer
70 * NOTES:
71 * The number of bytes copied may be limited by the destination
72 * buffer size
73 */
74{
76 PCHAR DstData;
77
78 TI_DbgPrint(DEBUG_PBUFFER, ("DstBuffer (0x%X) DstOffset (0x%X) SrcData (0x%X) Length (%d)\n", DstBuffer, DstOffset, SrcData, Length));
79
80 /* Skip DstOffset bytes in the destination buffer chain */
81 if (SkipToOffset(DstBuffer, DstOffset, &DstData, &DstSize) == -1)
82 return 0;
83
84 /* Start copying the data */
85 BytesCopied = 0;
86 for (;;) {
87 BytesToCopy = MIN(DstSize, Length);
88
89 RtlCopyMemory((PVOID)DstData, (PVOID)SrcData, BytesToCopy);
91 SrcData = (PCHAR)((ULONG_PTR)SrcData + BytesToCopy);
92
94 if (Length == 0)
95 break;
96
97 DstSize -= BytesToCopy;
98 if (DstSize == 0) {
99 /* No more bytes in destination buffer. Proceed to
100 the next buffer in the destination buffer chain */
101 NdisGetNextBuffer(DstBuffer, &DstBuffer);
102 if (!DstBuffer)
103 break;
104
105 NdisQueryBuffer(DstBuffer, (PVOID)&DstData, &DstSize);
106 }
107 }
108
109 return BytesCopied;
110}
111
112
114 PCHAR DstData,
115 PNDIS_BUFFER SrcBuffer,
116 UINT SrcOffset,
117 UINT Length)
118/*
119 * FUNCTION: Copies data from an NDIS buffer chain to a buffer
120 * ARGUMENTS:
121 * DstData = Pointer to destination buffer
122 * SrcBuffer = Pointer to source NDIS buffer
123 * SrcOffset = Source start offset
124 * Length = Number of bytes to copy
125 * RETURNS:
126 * Number of bytes copied to destination buffer
127 * NOTES:
128 * The number of bytes copied may be limited by the source
129 * buffer size
130 */
131{
132 UINT BytesCopied, BytesToCopy, SrcSize;
133 PCHAR SrcData;
134
135 TI_DbgPrint(DEBUG_PBUFFER, ("DstData 0x%X SrcBuffer 0x%X SrcOffset 0x%X Length %d\n",DstData,SrcBuffer, SrcOffset, Length));
136
137 /* Skip SrcOffset bytes in the source buffer chain */
138 if (SkipToOffset(SrcBuffer, SrcOffset, &SrcData, &SrcSize) == -1)
139 return 0;
140
141 /* Start copying the data */
142 BytesCopied = 0;
143 for (;;) {
144 BytesToCopy = MIN(SrcSize, Length);
145
146 TI_DbgPrint(DEBUG_PBUFFER, ("Copying (%d) bytes from 0x%X to 0x%X\n", BytesToCopy, SrcData, DstData));
147
148 RtlCopyMemory((PVOID)DstData, (PVOID)SrcData, BytesToCopy);
150 DstData = (PCHAR)((ULONG_PTR)DstData + BytesToCopy);
151
153 if (Length == 0)
154 break;
155
156 SrcSize -= BytesToCopy;
157 if (SrcSize == 0) {
158 /* No more bytes in source buffer. Proceed to
159 the next buffer in the source buffer chain */
160 NdisGetNextBuffer(SrcBuffer, &SrcBuffer);
161 if (!SrcBuffer)
162 break;
163
164 NdisQueryBuffer(SrcBuffer, (PVOID)&SrcData, &SrcSize);
165 }
166 }
167
168 return BytesCopied;
169}
170
171
173 PCHAR DstData,
174 PNDIS_PACKET SrcPacket,
175 UINT SrcOffset,
176 UINT Length)
177/*
178 * FUNCTION: Copies data from an NDIS packet to a buffer
179 * ARGUMENTS:
180 * DstData = Pointer to destination buffer
181 * SrcPacket = Pointer to source NDIS packet
182 * SrcOffset = Source start offset
183 * Length = Number of bytes to copy
184 * RETURNS:
185 * Number of bytes copied to destination buffer
186 * NOTES:
187 * The number of bytes copied may be limited by the source
188 * buffer size
189 */
190{
191 PNDIS_BUFFER FirstBuffer;
193 UINT FirstLength;
195
196 TI_DbgPrint(DEBUG_PBUFFER, ("DstData (0x%X) SrcPacket (0x%X) SrcOffset (0x%X) Length (%d)\n", DstData, SrcPacket, SrcOffset, Length));
197
199 &FirstBuffer,
200 &Address,
201 &FirstLength,
202 &TotalLength);
203
204 return CopyBufferChainToBuffer(DstData, FirstBuffer, SrcOffset, Length);
205}
206
207
209 PNDIS_BUFFER DstBuffer,
210 UINT DstOffset,
211 PNDIS_PACKET SrcPacket,
212 UINT SrcOffset,
213 UINT Length)
214/*
215 * FUNCTION: Copies data from an NDIS packet to an NDIS buffer chain
216 * ARGUMENTS:
217 * DstBuffer = Pointer to destination NDIS buffer
218 * DstOffset = Destination start offset
219 * SrcPacket = Pointer to source NDIS packet
220 * SrcOffset = Source start offset
221 * Length = Number of bytes to copy
222 * RETURNS:
223 * Number of bytes copied to destination buffer
224 * NOTES:
225 * The number of bytes copied may be limited by the source and
226 * destination buffer sizes
227 */
228{
229 PNDIS_BUFFER SrcBuffer;
230 PCHAR DstData, SrcData;
231 UINT DstSize, SrcSize;
232 UINT Count, Total;
233
234 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
236 /* Skip DstOffset bytes in the destination buffer chain */
237 NdisQueryBuffer(DstBuffer, (PVOID)&DstData, &DstSize);
238 if (SkipToOffset(DstBuffer, DstOffset, &DstData, &DstSize) == -1)
239 return 0;
240
241 /* Skip SrcOffset bytes in the source packet */
242 NdisGetFirstBufferFromPacket(SrcPacket, &SrcBuffer, (PVOID)&SrcData, &SrcSize, &Total);
243 if (SkipToOffset(SrcBuffer, SrcOffset, &SrcData, &SrcSize) == -1)
244 return 0;
245
246 /* Copy the data */
247 for (Total = 0;;) {
248 /* Find out how many bytes we can copy at one time */
249 if (Length < SrcSize)
250 Count = Length;
251 else
252 Count = SrcSize;
253 if (DstSize < Count)
254 Count = DstSize;
255
256 RtlCopyMemory((PVOID)DstData, (PVOID)SrcData, Count);
257
258 Total += Count;
259 Length -= Count;
260 if (Length == 0)
261 break;
262
263 DstSize -= Count;
264 if (DstSize == 0) {
265 /* No more bytes in destination buffer. Proceed to
266 the next buffer in the destination buffer chain */
267 NdisGetNextBuffer(DstBuffer, &DstBuffer);
268 if (!DstBuffer)
269 break;
270
271 NdisQueryBuffer(DstBuffer, (PVOID)&DstData, &DstSize);
272 }
273
274 SrcSize -= Count;
275 if (SrcSize == 0) {
276 /* No more bytes in source buffer. Proceed to
277 the next buffer in the source buffer chain */
278 NdisGetNextBuffer(SrcBuffer, &SrcBuffer);
279 if (!SrcBuffer)
280 break;
281
282 NdisQueryBuffer(SrcBuffer, (PVOID)&SrcData, &SrcSize);
283 }
284 }
285
286 return Total;
287}
288
289
292 UINT Size)
293/*
294 * FUNCTION: Resizes an NDIS packet
295 * ARGUMENTS:
296 * Packet = Pointer to packet
297 * Size = Number of bytes in first buffer
298 * RETURNS:
299 * Previous size of first buffer
300 */
301{
302 PNDIS_BUFFER NdisBuffer;
303 UINT OldSize;
304
305 NdisQueryPacket(Packet, NULL, NULL, &NdisBuffer, NULL);
306
307 OldSize = NdisBuffer->ByteCount;
308
309 if (Size != OldSize)
310 NdisBuffer->ByteCount = Size;
311
312 return OldSize;
313}
314
316 UINT Offset,
317 PCHAR *DataOut,
318 PUINT Size ) {
320
322 if( !Buffer ) return;
323 SkipToOffset( Buffer, Offset, DataOut, Size );
324}
325
327 PCHAR Data, UINT Len ) {
331 PCHAR NewData;
332
334 if( !NewData ) return NDIS_STATUS_RESOURCES;
335
336 if( Data ) RtlCopyMemory(NewData, Data, Len);
337
339 if( Status != NDIS_STATUS_SUCCESS ) {
341 return Status;
342 }
343
345 if( Status != NDIS_STATUS_SUCCESS ) {
348 return Status;
349 }
350
352 *NdisPacket = Packet;
353
354 return NDIS_STATUS_SUCCESS;
355}
356
357
360/*
361 * FUNCTION: Frees an NDIS packet
362 * ARGUMENTS:
363 * Packet = Pointer to NDIS packet to be freed
364 */
365{
366 PNDIS_BUFFER Buffer, NextBuffer;
367
368 TI_DbgPrint(DEBUG_PBUFFER, ("Packet (0x%X)\n", Packet));
369
370 /* Free all the buffers in the packet first */
372 for (; Buffer != NULL; Buffer = NextBuffer) {
373 PVOID Data;
374 UINT Length;
375
376 NdisGetNextBuffer(Buffer, &NextBuffer);
378 TI_DbgPrint(DEBUG_PBUFFER, ("Freeing ndis buffer (0x%X)\n", Buffer));
380 TI_DbgPrint(DEBUG_PBUFFER, ("Freeing exal buffer (0x%X)\n", Data));
382 }
383
384 /* Finally free the NDIS packet descriptor */
386}
#define MIN(x, y)
Definition: rdesktop.h:171
Definition: bufpool.h:45
#define Len
Definition: deflate.h:82
#define NULL
Definition: types.h:112
#define DEBUG_PBUFFER
Definition: debug.h:20
VOID EXPORT NdisAllocateBuffer(OUT PNDIS_STATUS Status, OUT PNDIS_BUFFER *Buffer, IN NDIS_HANDLE PoolHandle, IN PVOID VirtualAddress, IN UINT Length)
Definition: buffer.c:336
UINT CopyBufferToBufferChain(PNDIS_BUFFER DstBuffer, UINT DstOffset, PUCHAR SrcData, UINT Length)
Definition: buffer.c:56
FORCEINLINE ULONG SkipToOffset(IN PNDIS_BUFFER Buffer, IN UINT Offset, IN OUT PUCHAR *Data, IN OUT PUINT Size)
Definition: buffer.c:15
UINT CopyBufferChainToBuffer(PUCHAR DstData, PNDIS_BUFFER SrcBuffer, UINT SrcOffset, UINT Length)
Definition: buffer.c:113
VOID EXPORT NdisFreePacket(IN PNDIS_PACKET Packet)
Definition: buffer.c:828
UINT CopyPacketToBufferChain(PNDIS_BUFFER DstBuffer, UINT DstOffset, PNDIS_PACKET SrcPacket, UINT SrcOffset, UINT Length)
Definition: buffer.c:208
VOID EXPORT NdisAllocatePacket(OUT PNDIS_STATUS Status, OUT PNDIS_PACKET *Packet, IN NDIS_HANDLE PoolHandle)
Definition: buffer.c:394
UINT CopyPacketToBuffer(PUCHAR DstData, PNDIS_PACKET SrcPacket, UINT SrcOffset, UINT Length)
Definition: buffer.c:172
VOID EXPORT NdisGetFirstBufferFromPacket(IN PNDIS_PACKET _Packet, OUT PNDIS_BUFFER *_FirstBuffer, OUT PVOID *_FirstBufferVA, OUT PUINT _FirstBufferLength, OUT PUINT _TotalBufferLength)
Definition: buffer.c:873
#define TI_DbgPrint(_t_, _x_)
Definition: debug.h:45
#define PACKET_BUFFER_TAG
Definition: tags.h:27
void GetDataPtr(PNDIS_PACKET Packet, UINT Offset, PCHAR *DataOut, PUINT Size)
Definition: buffer.c:315
UINT ResizePacket(PNDIS_PACKET Packet, UINT Size)
Definition: buffer.c:290
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define NonPagedPool
Definition: env_spec_w32.h:307
Status
Definition: gdiplustypes.h:25
NDIS_HANDLE GlobalBufferPool
Definition: routines.c:4
NDIS_HANDLE GlobalPacketPool
Definition: routines.c:3
#define AllocatePacketWithBuffer(x, y, z)
Definition: memtrack.h:7
#define FreeNdisPacket(x)
Definition: memtrack.h:8
#define PCHAR
Definition: match.c:90
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
#define NdisGetNextBuffer(CurrentBuffer, NextBuffer)
Definition: ndis.h:3386
_In_ NDIS_HANDLE _In_ PNDIS_PACKET Packet
Definition: ndis.h:1549
unsigned int * PUINT
Definition: ndis.h:50
unsigned int UINT
Definition: ndis.h:50
static __inline VOID NdisQueryPacket(IN PNDIS_PACKET Packet, OUT PUINT PhysicalBufferCount OPTIONAL, OUT PUINT BufferCount OPTIONAL, OUT PNDIS_BUFFER *FirstBuffer OPTIONAL, OUT PUINT TotalPacketLength OPTIONAL)
Definition: ndis.h:3593
_In_ UINT _In_ UINT _In_ PNDIS_PACKET _In_ UINT _Out_ PUINT BytesCopied
Definition: ndis.h:3171
_In_ UINT _In_ UINT BytesToCopy
Definition: ndis.h:3168
#define NDIS_STATUS_SUCCESS
Definition: ndis.h:346
MDL * PNDIS_BUFFER
Definition: ndis.h:343
#define NdisFreeBuffer
Definition: ndis.h:2895
#define NdisQueryBuffer(_Buffer, _VirtualAddress, _Length)
Definition: ndis.h:3029
#define NdisChainBufferAtFront(Packet, Buffer)
Definition: ndis.h:3106
#define NDIS_STATUS_RESOURCES
Definition: ndis.h:466
int Count
Definition: noreturn.cpp:7
int NDIS_STATUS
Definition: ntddndis.h:475
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
static WCHAR Address[46]
Definition: ping.c:68
int32_t INT
Definition: typedefs.h:58
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
uint32_t ULONG_PTR
Definition: typedefs.h:65
char * PCHAR
Definition: typedefs.h:51
_In_ ULONG TotalLength
Definition: usbdlib.h:158
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533