xref: /reactos/drivers/network/ndis/ndis/buffer.c (revision c2c66aff)
1*c2c66affSColin Finck /*
2*c2c66affSColin Finck  * COPYRIGHT:   See COPYING in the top level directory
3*c2c66affSColin Finck  * PROJECT:     ReactOS NDIS library
4*c2c66affSColin Finck  * FILE:        ndis/buffer.c
5*c2c66affSColin Finck  * PURPOSE:     Buffer management routines
6*c2c66affSColin Finck  * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
7*c2c66affSColin Finck  * REVISIONS:
8*c2c66affSColin Finck  *   CSH 01/08-2000 Created
9*c2c66affSColin Finck  */
10*c2c66affSColin Finck 
11*c2c66affSColin Finck #include <ndissys.h>
12*c2c66affSColin Finck 
13*c2c66affSColin Finck __inline ULONG SkipToOffset(
14*c2c66affSColin Finck     IN PNDIS_BUFFER Buffer,
15*c2c66affSColin Finck     IN UINT Offset,
16*c2c66affSColin Finck     IN OUT PUCHAR *Data,
17*c2c66affSColin Finck     IN OUT PUINT Size)
18*c2c66affSColin Finck /*
19*c2c66affSColin Finck  * FUNCTION: Skips Offset bytes into a buffer chain
20*c2c66affSColin Finck  * ARGUMENTS:
21*c2c66affSColin Finck  *     Buffer = Pointer to NDIS buffer
22*c2c66affSColin Finck  *     Offset = Number of bytes to skip
23*c2c66affSColin Finck  *     Data   = Address of a pointer that on return will contain the
24*c2c66affSColin Finck  *              address of the offset in the buffer
25*c2c66affSColin Finck  *     Size   = Address of a pointer that on return will contain the
26*c2c66affSColin Finck  *              size of the destination buffer
27*c2c66affSColin Finck  * RETURNS:
28*c2c66affSColin Finck  *     Offset into buffer, -1 if buffer chain was smaller than Offset bytes
29*c2c66affSColin Finck  * NOTES:
30*c2c66affSColin Finck  *     Buffer may be NULL
31*c2c66affSColin Finck  */
32*c2c66affSColin Finck {
33*c2c66affSColin Finck     for (;;) {
34*c2c66affSColin Finck 
35*c2c66affSColin Finck         if (!Buffer)
36*c2c66affSColin Finck             return 0xFFFFFFFF;
37*c2c66affSColin Finck 
38*c2c66affSColin Finck         NdisQueryBuffer(Buffer, (PVOID)Data, Size);
39*c2c66affSColin Finck 
40*c2c66affSColin Finck         if (Offset < *Size) {
41*c2c66affSColin Finck             *Data  = (PUCHAR) ((ULONG_PTR) *Data + Offset);
42*c2c66affSColin Finck             *Size -= Offset;
43*c2c66affSColin Finck             break;
44*c2c66affSColin Finck         }
45*c2c66affSColin Finck 
46*c2c66affSColin Finck         Offset -= *Size;
47*c2c66affSColin Finck 
48*c2c66affSColin Finck         NdisGetNextBuffer(Buffer, &Buffer);
49*c2c66affSColin Finck     }
50*c2c66affSColin Finck 
51*c2c66affSColin Finck     return Offset;
52*c2c66affSColin Finck }
53*c2c66affSColin Finck 
54*c2c66affSColin Finck UINT CopyBufferToBufferChain(
55*c2c66affSColin Finck     PNDIS_BUFFER DstBuffer,
56*c2c66affSColin Finck     UINT DstOffset,
57*c2c66affSColin Finck     PUCHAR SrcData,
58*c2c66affSColin Finck     UINT Length)
59*c2c66affSColin Finck /*
60*c2c66affSColin Finck  * FUNCTION: Copies data from a buffer to an NDIS buffer chain
61*c2c66affSColin Finck  * ARGUMENTS:
62*c2c66affSColin Finck  *     DstBuffer = Pointer to destination NDIS buffer
63*c2c66affSColin Finck  *     DstOffset = Destination start offset
64*c2c66affSColin Finck  *     SrcData   = Pointer to source buffer
65*c2c66affSColin Finck  *     Length    = Number of bytes to copy
66*c2c66affSColin Finck  * RETURNS:
67*c2c66affSColin Finck  *     Number of bytes copied to destination buffer
68*c2c66affSColin Finck  * NOTES:
69*c2c66affSColin Finck  *     The number of bytes copied may be limited by the destination
70*c2c66affSColin Finck  *     buffer size
71*c2c66affSColin Finck  */
72*c2c66affSColin Finck {
73*c2c66affSColin Finck     UINT BytesCopied, BytesToCopy, DstSize;
74*c2c66affSColin Finck     PUCHAR DstData;
75*c2c66affSColin Finck 
76*c2c66affSColin Finck     NDIS_DbgPrint(MAX_TRACE, ("DstBuffer (0x%X)  DstOffset (0x%X)  SrcData (0x%X)  Length (%d)\n", DstBuffer, DstOffset, SrcData, Length));
77*c2c66affSColin Finck 
78*c2c66affSColin Finck     /* Skip DstOffset bytes in the destination buffer chain */
79*c2c66affSColin Finck     if (SkipToOffset(DstBuffer, DstOffset, &DstData, &DstSize) == 0xFFFFFFFF)
80*c2c66affSColin Finck         return 0;
81*c2c66affSColin Finck 
82*c2c66affSColin Finck     /* Start copying the data */
83*c2c66affSColin Finck     BytesCopied = 0;
84*c2c66affSColin Finck     for (;;) {
85*c2c66affSColin Finck         BytesToCopy = MIN(DstSize, Length);
86*c2c66affSColin Finck 
87*c2c66affSColin Finck         RtlCopyMemory((PVOID)DstData, (PVOID)SrcData, BytesToCopy);
88*c2c66affSColin Finck         BytesCopied += BytesToCopy;
89*c2c66affSColin Finck         SrcData      = (PUCHAR) ((ULONG_PTR) SrcData + BytesToCopy);
90*c2c66affSColin Finck 
91*c2c66affSColin Finck         Length -= BytesToCopy;
92*c2c66affSColin Finck         if (Length == 0)
93*c2c66affSColin Finck             break;
94*c2c66affSColin Finck 
95*c2c66affSColin Finck         DstSize -= BytesToCopy;
96*c2c66affSColin Finck         if (DstSize == 0) {
97*c2c66affSColin Finck             /* No more bytes in destination buffer. Proceed to
98*c2c66affSColin Finck                the next buffer in the destination buffer chain */
99*c2c66affSColin Finck             NdisGetNextBuffer(DstBuffer, &DstBuffer);
100*c2c66affSColin Finck             if (!DstBuffer)
101*c2c66affSColin Finck                 break;
102*c2c66affSColin Finck 
103*c2c66affSColin Finck             NdisQueryBuffer(DstBuffer, (PVOID)&DstData, &DstSize);
104*c2c66affSColin Finck         }
105*c2c66affSColin Finck     }
106*c2c66affSColin Finck 
107*c2c66affSColin Finck     return BytesCopied;
108*c2c66affSColin Finck }
109*c2c66affSColin Finck 
110*c2c66affSColin Finck 
111*c2c66affSColin Finck UINT CopyBufferChainToBuffer(
112*c2c66affSColin Finck     PUCHAR DstData,
113*c2c66affSColin Finck     PNDIS_BUFFER SrcBuffer,
114*c2c66affSColin Finck     UINT SrcOffset,
115*c2c66affSColin Finck     UINT Length)
116*c2c66affSColin Finck /*
117*c2c66affSColin Finck  * FUNCTION: Copies data from an NDIS buffer chain to a buffer
118*c2c66affSColin Finck  * ARGUMENTS:
119*c2c66affSColin Finck  *     DstData   = Pointer to destination buffer
120*c2c66affSColin Finck  *     SrcBuffer = Pointer to source NDIS buffer
121*c2c66affSColin Finck  *     SrcOffset = Source start offset
122*c2c66affSColin Finck  *     Length    = Number of bytes to copy
123*c2c66affSColin Finck  * RETURNS:
124*c2c66affSColin Finck  *     Number of bytes copied to destination buffer
125*c2c66affSColin Finck  * NOTES:
126*c2c66affSColin Finck  *     The number of bytes copied may be limited by the source
127*c2c66affSColin Finck  *     buffer size
128*c2c66affSColin Finck  */
129*c2c66affSColin Finck {
130*c2c66affSColin Finck     UINT BytesCopied, BytesToCopy, SrcSize;
131*c2c66affSColin Finck     PUCHAR SrcData;
132*c2c66affSColin Finck 
133*c2c66affSColin Finck     NDIS_DbgPrint(MAX_TRACE, ("DstData 0x%X  SrcBuffer 0x%X  SrcOffset 0x%X  Length %d\n",DstData,SrcBuffer, SrcOffset, Length));
134*c2c66affSColin Finck 
135*c2c66affSColin Finck     /* Skip SrcOffset bytes in the source buffer chain */
136*c2c66affSColin Finck     if (SkipToOffset(SrcBuffer, SrcOffset, &SrcData, &SrcSize) == 0xFFFFFFFF)
137*c2c66affSColin Finck         return 0;
138*c2c66affSColin Finck 
139*c2c66affSColin Finck     /* Start copying the data */
140*c2c66affSColin Finck     BytesCopied = 0;
141*c2c66affSColin Finck     for (;;) {
142*c2c66affSColin Finck         BytesToCopy = MIN(SrcSize, Length);
143*c2c66affSColin Finck 
144*c2c66affSColin Finck         NDIS_DbgPrint(MAX_TRACE, ("Copying (%d) bytes from 0x%X to 0x%X\n", BytesToCopy, SrcData, DstData));
145*c2c66affSColin Finck 
146*c2c66affSColin Finck         RtlCopyMemory((PVOID)DstData, (PVOID)SrcData, BytesToCopy);
147*c2c66affSColin Finck         BytesCopied += BytesToCopy;
148*c2c66affSColin Finck         DstData      = (PUCHAR)((ULONG_PTR) DstData + BytesToCopy);
149*c2c66affSColin Finck 
150*c2c66affSColin Finck         Length -= BytesToCopy;
151*c2c66affSColin Finck         if (Length == 0)
152*c2c66affSColin Finck             break;
153*c2c66affSColin Finck 
154*c2c66affSColin Finck         SrcSize -= BytesToCopy;
155*c2c66affSColin Finck         if (SrcSize == 0) {
156*c2c66affSColin Finck             /* No more bytes in source buffer. Proceed to
157*c2c66affSColin Finck                the next buffer in the source buffer chain */
158*c2c66affSColin Finck             NdisGetNextBuffer(SrcBuffer, &SrcBuffer);
159*c2c66affSColin Finck             if (!SrcBuffer)
160*c2c66affSColin Finck                 break;
161*c2c66affSColin Finck 
162*c2c66affSColin Finck             NdisQueryBuffer(SrcBuffer, (PVOID)&SrcData, &SrcSize);
163*c2c66affSColin Finck         }
164*c2c66affSColin Finck     }
165*c2c66affSColin Finck 
166*c2c66affSColin Finck     return BytesCopied;
167*c2c66affSColin Finck }
168*c2c66affSColin Finck 
169*c2c66affSColin Finck 
170*c2c66affSColin Finck UINT CopyPacketToBuffer(
171*c2c66affSColin Finck     PUCHAR DstData,
172*c2c66affSColin Finck     PNDIS_PACKET SrcPacket,
173*c2c66affSColin Finck     UINT SrcOffset,
174*c2c66affSColin Finck     UINT Length)
175*c2c66affSColin Finck /*
176*c2c66affSColin Finck  * FUNCTION: Copies data from an NDIS packet to a buffer
177*c2c66affSColin Finck  * ARGUMENTS:
178*c2c66affSColin Finck  *     DstData   = Pointer to destination buffer
179*c2c66affSColin Finck  *     SrcPacket = Pointer to source NDIS packet
180*c2c66affSColin Finck  *     SrcOffset = Source start offset
181*c2c66affSColin Finck  *     Length    = Number of bytes to copy
182*c2c66affSColin Finck  * RETURNS:
183*c2c66affSColin Finck  *     Number of bytes copied to destination buffer
184*c2c66affSColin Finck  * NOTES:
185*c2c66affSColin Finck  *     The number of bytes copied may be limited by the source
186*c2c66affSColin Finck  *     buffer size
187*c2c66affSColin Finck  */
188*c2c66affSColin Finck {
189*c2c66affSColin Finck     PNDIS_BUFFER FirstBuffer;
190*c2c66affSColin Finck     PVOID Address;
191*c2c66affSColin Finck     UINT FirstLength;
192*c2c66affSColin Finck     UINT TotalLength;
193*c2c66affSColin Finck 
194*c2c66affSColin Finck     NDIS_DbgPrint(MAX_TRACE, ("DstData (0x%X)  SrcPacket (0x%X)  SrcOffset (0x%X)  Length (%d)\n", DstData, SrcPacket, SrcOffset, Length));
195*c2c66affSColin Finck 
196*c2c66affSColin Finck     NdisGetFirstBufferFromPacket(SrcPacket,
197*c2c66affSColin Finck                                  &FirstBuffer,
198*c2c66affSColin Finck                                  &Address,
199*c2c66affSColin Finck                                  &FirstLength,
200*c2c66affSColin Finck                                  &TotalLength);
201*c2c66affSColin Finck 
202*c2c66affSColin Finck     return CopyBufferChainToBuffer(DstData, FirstBuffer, SrcOffset, Length);
203*c2c66affSColin Finck }
204*c2c66affSColin Finck 
205*c2c66affSColin Finck 
206*c2c66affSColin Finck UINT CopyPacketToBufferChain(
207*c2c66affSColin Finck     PNDIS_BUFFER DstBuffer,
208*c2c66affSColin Finck     UINT DstOffset,
209*c2c66affSColin Finck     PNDIS_PACKET SrcPacket,
210*c2c66affSColin Finck     UINT SrcOffset,
211*c2c66affSColin Finck     UINT Length)
212*c2c66affSColin Finck /*
213*c2c66affSColin Finck  * FUNCTION: Copies data from an NDIS packet to an NDIS buffer chain
214*c2c66affSColin Finck  * ARGUMENTS:
215*c2c66affSColin Finck  *     DstBuffer = Pointer to destination NDIS buffer
216*c2c66affSColin Finck  *     DstOffset = Destination start offset
217*c2c66affSColin Finck  *     SrcPacket = Pointer to source NDIS packet
218*c2c66affSColin Finck  *     SrcOffset = Source start offset
219*c2c66affSColin Finck  *     Length    = Number of bytes to copy
220*c2c66affSColin Finck  * RETURNS:
221*c2c66affSColin Finck  *     Number of bytes copied to destination buffer
222*c2c66affSColin Finck  * NOTES:
223*c2c66affSColin Finck  *     The number of bytes copied may be limited by the source and
224*c2c66affSColin Finck  *     destination buffer sizes
225*c2c66affSColin Finck  */
226*c2c66affSColin Finck {
227*c2c66affSColin Finck     PNDIS_BUFFER SrcBuffer;
228*c2c66affSColin Finck     PUCHAR DstData, SrcData;
229*c2c66affSColin Finck     UINT DstSize, SrcSize;
230*c2c66affSColin Finck     UINT Count, Total;
231*c2c66affSColin Finck 
232*c2c66affSColin Finck     NDIS_DbgPrint(MAX_TRACE, ("DstBuffer (0x%X)  DstOffset (0x%X)  SrcPacket (0x%X)  SrcOffset (0x%X)  Length (%d)\n", DstBuffer, DstOffset, SrcPacket, SrcOffset, Length));
233*c2c66affSColin Finck 
234*c2c66affSColin Finck     /* Skip DstOffset bytes in the destination buffer chain */
235*c2c66affSColin Finck     NdisQueryBuffer(DstBuffer, (PVOID)&DstData, &DstSize);
236*c2c66affSColin Finck     if (SkipToOffset(DstBuffer, DstOffset, &DstData, &DstSize) == 0xFFFFFFFF)
237*c2c66affSColin Finck         return 0;
238*c2c66affSColin Finck     /* Skip SrcOffset bytes in the source packet */
239*c2c66affSColin Finck     NdisGetFirstBufferFromPacket(SrcPacket, &SrcBuffer, (PVOID*)&SrcData, &SrcSize, &Total);
240*c2c66affSColin Finck     if (SkipToOffset(SrcBuffer, SrcOffset, &SrcData, &SrcSize) == 0xFFFFFFFF)
241*c2c66affSColin Finck         return 0;
242*c2c66affSColin Finck     /* Copy the data */
243*c2c66affSColin Finck     for (Total = 0;;) {
244*c2c66affSColin Finck         /* Find out how many bytes we can copy at one time */
245*c2c66affSColin Finck         if (Length < SrcSize)
246*c2c66affSColin Finck             Count = Length;
247*c2c66affSColin Finck         else
248*c2c66affSColin Finck             Count = SrcSize;
249*c2c66affSColin Finck         if (DstSize < Count)
250*c2c66affSColin Finck             Count = DstSize;
251*c2c66affSColin Finck 
252*c2c66affSColin Finck         RtlCopyMemory((PVOID)DstData, (PVOID)SrcData, Count);
253*c2c66affSColin Finck 
254*c2c66affSColin Finck         Total  += Count;
255*c2c66affSColin Finck         Length -= Count;
256*c2c66affSColin Finck         if (Length == 0)
257*c2c66affSColin Finck             break;
258*c2c66affSColin Finck 
259*c2c66affSColin Finck         DstSize -= Count;
260*c2c66affSColin Finck         if (DstSize == 0) {
261*c2c66affSColin Finck             /* No more bytes in destination buffer. Proceed to
262*c2c66affSColin Finck                the next buffer in the destination buffer chain */
263*c2c66affSColin Finck             NdisGetNextBuffer(DstBuffer, &DstBuffer);
264*c2c66affSColin Finck             if (!DstBuffer)
265*c2c66affSColin Finck                 break;
266*c2c66affSColin Finck 
267*c2c66affSColin Finck             NdisQueryBuffer(DstBuffer, (PVOID)&DstData, &DstSize);
268*c2c66affSColin Finck         }
269*c2c66affSColin Finck 
270*c2c66affSColin Finck         SrcSize -= Count;
271*c2c66affSColin Finck         if (SrcSize == 0) {
272*c2c66affSColin Finck             /* No more bytes in source buffer. Proceed to
273*c2c66affSColin Finck                the next buffer in the source buffer chain */
274*c2c66affSColin Finck             NdisGetNextBuffer(SrcBuffer, &SrcBuffer);
275*c2c66affSColin Finck             if (!SrcBuffer)
276*c2c66affSColin Finck                 break;
277*c2c66affSColin Finck 
278*c2c66affSColin Finck             NdisQueryBuffer(SrcBuffer, (PVOID)&SrcData, &SrcSize);
279*c2c66affSColin Finck         }
280*c2c66affSColin Finck     }
281*c2c66affSColin Finck 
282*c2c66affSColin Finck     return Total;
283*c2c66affSColin Finck }
284*c2c66affSColin Finck 
285*c2c66affSColin Finck 
286*c2c66affSColin Finck /*
287*c2c66affSColin Finck  * @implemented
288*c2c66affSColin Finck  */
289*c2c66affSColin Finck #undef NdisAdjustBufferLength
290*c2c66affSColin Finck VOID
291*c2c66affSColin Finck EXPORT
292*c2c66affSColin Finck NdisAdjustBufferLength(
293*c2c66affSColin Finck     IN PNDIS_BUFFER Buffer,
294*c2c66affSColin Finck     IN UINT         Length)
295*c2c66affSColin Finck /*
296*c2c66affSColin Finck  * FUNCTION: Modifies the length of an NDIS buffer
297*c2c66affSColin Finck  * ARGUMENTS:
298*c2c66affSColin Finck  *     Buffer = Pointer to NDIS buffer descriptor
299*c2c66affSColin Finck  *     Length = New size of buffer
300*c2c66affSColin Finck  */
301*c2c66affSColin Finck {
302*c2c66affSColin Finck     Buffer->ByteCount = Length;
303*c2c66affSColin Finck }
304*c2c66affSColin Finck 
305*c2c66affSColin Finck 
306*c2c66affSColin Finck /*
307*c2c66affSColin Finck  * @implemented
308*c2c66affSColin Finck  */
309*c2c66affSColin Finck #undef NDIS_BUFFER_TO_SPAN_PAGES
310*c2c66affSColin Finck ULONG
311*c2c66affSColin Finck EXPORT
312*c2c66affSColin Finck NDIS_BUFFER_TO_SPAN_PAGES(
313*c2c66affSColin Finck     IN  PNDIS_BUFFER    Buffer)
314*c2c66affSColin Finck /*
315*c2c66affSColin Finck  * FUNCTION: Determines how many physical pages a buffer is made of
316*c2c66affSColin Finck  * ARGUMENTS:
317*c2c66affSColin Finck  *     Buffer = Pointer to NDIS buffer descriptor
318*c2c66affSColin Finck  */
319*c2c66affSColin Finck {
320*c2c66affSColin Finck     if (MmGetMdlByteCount(Buffer) == 0)
321*c2c66affSColin Finck         return 1;
322*c2c66affSColin Finck 
323*c2c66affSColin Finck     return ADDRESS_AND_SIZE_TO_SPAN_PAGES(
324*c2c66affSColin Finck             MmGetMdlVirtualAddress(Buffer),
325*c2c66affSColin Finck             MmGetMdlByteCount(Buffer));
326*c2c66affSColin Finck }
327*c2c66affSColin Finck 
328*c2c66affSColin Finck 
329*c2c66affSColin Finck /*
330*c2c66affSColin Finck  * @implemented
331*c2c66affSColin Finck  */
332*c2c66affSColin Finck VOID
333*c2c66affSColin Finck EXPORT
334*c2c66affSColin Finck NdisAllocateBuffer(
335*c2c66affSColin Finck     OUT PNDIS_STATUS    Status,
336*c2c66affSColin Finck     OUT PNDIS_BUFFER    * Buffer,
337*c2c66affSColin Finck     IN  NDIS_HANDLE     PoolHandle,
338*c2c66affSColin Finck     IN  PVOID           VirtualAddress,
339*c2c66affSColin Finck     IN  UINT            Length)
340*c2c66affSColin Finck /*
341*c2c66affSColin Finck  * FUNCTION: Allocates an NDIS buffer descriptor
342*c2c66affSColin Finck  * ARGUMENTS:
343*c2c66affSColin Finck  *     Status         = Address of buffer for status
344*c2c66affSColin Finck  *     Buffer         = Address of buffer for NDIS buffer descriptor
345*c2c66affSColin Finck  *     PoolHandle     = Handle returned by NdisAllocateBufferPool
346*c2c66affSColin Finck  *     VirtualAddress = Pointer to virtual address of data buffer
347*c2c66affSColin Finck  *     Length         = Number of bytes in data buffer
348*c2c66affSColin Finck  */
349*c2c66affSColin Finck {
350*c2c66affSColin Finck     ASSERT(VirtualAddress != NULL);
351*c2c66affSColin Finck     ASSERT(Length > 0);
352*c2c66affSColin Finck 
353*c2c66affSColin Finck     *Buffer = IoAllocateMdl(VirtualAddress, Length, FALSE, FALSE, NULL);
354*c2c66affSColin Finck     if (*Buffer != NULL) {
355*c2c66affSColin Finck         MmBuildMdlForNonPagedPool(*Buffer);
356*c2c66affSColin Finck         (*Buffer)->Next = NULL;
357*c2c66affSColin Finck         *Status = NDIS_STATUS_SUCCESS;
358*c2c66affSColin Finck     } else {
359*c2c66affSColin Finck         NDIS_DbgPrint(MIN_TRACE, ("IoAllocateMdl failed (%x, %lx)\n", VirtualAddress, Length));
360*c2c66affSColin Finck         *Status = NDIS_STATUS_FAILURE;
361*c2c66affSColin Finck     }
362*c2c66affSColin Finck }
363*c2c66affSColin Finck 
364*c2c66affSColin Finck 
365*c2c66affSColin Finck /*
366*c2c66affSColin Finck  * @implemented
367*c2c66affSColin Finck  */
368*c2c66affSColin Finck VOID
369*c2c66affSColin Finck EXPORT
370*c2c66affSColin Finck NdisAllocateBufferPool(
371*c2c66affSColin Finck     OUT PNDIS_STATUS    Status,
372*c2c66affSColin Finck     OUT PNDIS_HANDLE    PoolHandle,
373*c2c66affSColin Finck     IN  UINT            NumberOfDescriptors)
374*c2c66affSColin Finck /*
375*c2c66affSColin Finck  * FUNCTION: Allocates storage for an NDIS buffer pool
376*c2c66affSColin Finck  * ARGUMENTS:
377*c2c66affSColin Finck  *     Status              = Address of buffer for status
378*c2c66affSColin Finck  *     PoolHandle          = Address of buffer for pool handle
379*c2c66affSColin Finck  *     NumberOfDescriptors = Size of buffer pool in number of descriptors
380*c2c66affSColin Finck  */
381*c2c66affSColin Finck {
382*c2c66affSColin Finck     *Status = NDIS_STATUS_SUCCESS;
383*c2c66affSColin Finck     *PoolHandle = 0;
384*c2c66affSColin Finck }
385*c2c66affSColin Finck 
386*c2c66affSColin Finck 
387*c2c66affSColin Finck /*
388*c2c66affSColin Finck  * @implemented
389*c2c66affSColin Finck  */
390*c2c66affSColin Finck VOID
391*c2c66affSColin Finck EXPORT
392*c2c66affSColin Finck NdisAllocatePacket(
393*c2c66affSColin Finck     OUT PNDIS_STATUS    Status,
394*c2c66affSColin Finck     OUT PNDIS_PACKET    * Packet,
395*c2c66affSColin Finck     IN  NDIS_HANDLE     PoolHandle)
396*c2c66affSColin Finck /*
397*c2c66affSColin Finck  * FUNCTION: Allocates an NDIS packet descriptor
398*c2c66affSColin Finck  * ARGUMENTS:
399*c2c66affSColin Finck  *     Status     = Address of buffer for status
400*c2c66affSColin Finck  *     Packet     = Address of buffer for packet descriptor
401*c2c66affSColin Finck  *     PoolHandle = Handle returned by NdisAllocatePacketPool
402*c2c66affSColin Finck  */
403*c2c66affSColin Finck {
404*c2c66affSColin Finck     PNDISI_PACKET_POOL Pool = (PNDISI_PACKET_POOL)PoolHandle;
405*c2c66affSColin Finck 
406*c2c66affSColin Finck     KeAcquireSpinLock(&Pool->SpinLock.SpinLock, &Pool->SpinLock.OldIrql);
407*c2c66affSColin Finck     NdisDprAllocatePacketNonInterlocked(Status,
408*c2c66affSColin Finck                                         Packet,
409*c2c66affSColin Finck                                         PoolHandle);
410*c2c66affSColin Finck     KeReleaseSpinLock(&Pool->SpinLock.SpinLock, Pool->SpinLock.OldIrql);
411*c2c66affSColin Finck }
412*c2c66affSColin Finck 
413*c2c66affSColin Finck 
414*c2c66affSColin Finck /*
415*c2c66affSColin Finck  * @implemented
416*c2c66affSColin Finck  */
417*c2c66affSColin Finck VOID
418*c2c66affSColin Finck EXPORT
419*c2c66affSColin Finck NdisAllocatePacketPool(
420*c2c66affSColin Finck     OUT PNDIS_STATUS    Status,
421*c2c66affSColin Finck     OUT PNDIS_HANDLE    PoolHandle,
422*c2c66affSColin Finck     IN  UINT            NumberOfDescriptors,
423*c2c66affSColin Finck     IN  UINT            ProtocolReservedLength)
424*c2c66affSColin Finck /*
425*c2c66affSColin Finck  * FUNCTION: Allocates storage for an NDIS packet pool
426*c2c66affSColin Finck  * ARGUMENTS:
427*c2c66affSColin Finck  *     Status                 = Address of buffer for status
428*c2c66affSColin Finck  *     PoolHandle             = Address of buffer for pool handle
429*c2c66affSColin Finck  *     NumberOfDescriptors    = Size of packet pool in number of descriptors
430*c2c66affSColin Finck  *     ProtocolReservedLength = Size of protocol reserved area in bytes
431*c2c66affSColin Finck  */
432*c2c66affSColin Finck {
433*c2c66affSColin Finck     NdisAllocatePacketPoolEx(
434*c2c66affSColin Finck         Status,
435*c2c66affSColin Finck         PoolHandle,
436*c2c66affSColin Finck         NumberOfDescriptors,
437*c2c66affSColin Finck         0,
438*c2c66affSColin Finck         ProtocolReservedLength);
439*c2c66affSColin Finck }
440*c2c66affSColin Finck 
441*c2c66affSColin Finck 
442*c2c66affSColin Finck /*
443*c2c66affSColin Finck  * @implemented
444*c2c66affSColin Finck  */
445*c2c66affSColin Finck VOID
446*c2c66affSColin Finck EXPORT
447*c2c66affSColin Finck NdisAllocatePacketPoolEx(
448*c2c66affSColin Finck     OUT PNDIS_STATUS    Status,
449*c2c66affSColin Finck     OUT PNDIS_HANDLE    PoolHandle,
450*c2c66affSColin Finck     IN  UINT            NumberOfDescriptors,
451*c2c66affSColin Finck     IN  UINT            NumberOfOverflowDescriptors,
452*c2c66affSColin Finck     IN  UINT            ProtocolReservedLength)
453*c2c66affSColin Finck /*
454*c2c66affSColin Finck  * FUNCTION:
455*c2c66affSColin Finck  * ARGUMENTS:
456*c2c66affSColin Finck  * NOTES:
457*c2c66affSColin Finck  *    NDIS 5.0
458*c2c66affSColin Finck  */
459*c2c66affSColin Finck {
460*c2c66affSColin Finck     PNDISI_PACKET_POOL Pool;
461*c2c66affSColin Finck     UINT Size, Length, i;
462*c2c66affSColin Finck     PNDIS_PACKET Packet, NextPacket;
463*c2c66affSColin Finck 
464*c2c66affSColin Finck     NDIS_DbgPrint(MAX_TRACE, ("Status (0x%X)  PoolHandle (0x%X)  "
465*c2c66affSColin Finck         "NumberOfDescriptors (%d)  ProtocolReservedLength (%d).\n",
466*c2c66affSColin Finck         Status, PoolHandle, NumberOfDescriptors, ProtocolReservedLength));
467*c2c66affSColin Finck 
468*c2c66affSColin Finck     *PoolHandle = NULL;
469*c2c66affSColin Finck 
470*c2c66affSColin Finck     if (NumberOfDescriptors > 0xffff)
471*c2c66affSColin Finck     {
472*c2c66affSColin Finck         NDIS_DbgPrint(MIN_TRACE, ("Invalid number of descriptors (%lx)\n", NumberOfDescriptors))
473*c2c66affSColin Finck         *Status = NDIS_STATUS_RESOURCES;
474*c2c66affSColin Finck     }
475*c2c66affSColin Finck     else
476*c2c66affSColin Finck     {
477*c2c66affSColin Finck         NumberOfDescriptors += NumberOfOverflowDescriptors;
478*c2c66affSColin Finck         if (NumberOfDescriptors > 0xffff)
479*c2c66affSColin Finck         {
480*c2c66affSColin Finck             NDIS_DbgPrint(MIN_TRACE, ("Total number of descriptors > 0xffff (%lx)\n", NumberOfDescriptors));
481*c2c66affSColin Finck             NumberOfDescriptors = 0xffff;
482*c2c66affSColin Finck         }
483*c2c66affSColin Finck 
484*c2c66affSColin Finck         Length = sizeof(NDIS_PACKET) + sizeof(NDIS_PACKET_OOB_DATA) +
485*c2c66affSColin Finck                  sizeof(NDIS_PACKET_EXTENSION) + ProtocolReservedLength;
486*c2c66affSColin Finck         Size   = sizeof(NDISI_PACKET_POOL) + Length * NumberOfDescriptors;
487*c2c66affSColin Finck 
488*c2c66affSColin Finck         Pool   = ExAllocatePool(NonPagedPool, Size);
489*c2c66affSColin Finck         if (Pool)
490*c2c66affSColin Finck         {
491*c2c66affSColin Finck             KeInitializeSpinLock(&Pool->SpinLock.SpinLock);
492*c2c66affSColin Finck             Pool->PacketLength = Length;
493*c2c66affSColin Finck 
494*c2c66affSColin Finck             if (NumberOfDescriptors > 0)
495*c2c66affSColin Finck             {
496*c2c66affSColin Finck                 Packet         = (PNDIS_PACKET)&Pool->Buffer;
497*c2c66affSColin Finck                 Pool->FreeList = Packet;
498*c2c66affSColin Finck 
499*c2c66affSColin Finck                 NextPacket = (PNDIS_PACKET)((ULONG_PTR)Packet + Length);
500*c2c66affSColin Finck                 for (i = 1; i < NumberOfDescriptors; i++)
501*c2c66affSColin Finck                 {
502*c2c66affSColin Finck                     Packet->Reserved[0]  = (ULONG_PTR)NextPacket;
503*c2c66affSColin Finck                     Packet               = NextPacket;
504*c2c66affSColin Finck                     NextPacket           = (PNDIS_PACKET)((ULONG_PTR)Packet + Length);
505*c2c66affSColin Finck                 }
506*c2c66affSColin Finck                 Packet->Reserved[0] = 0;
507*c2c66affSColin Finck             }
508*c2c66affSColin Finck             else {
509*c2c66affSColin Finck                 NDIS_DbgPrint(MIN_TRACE, ("Attempted to allocate a packet pool with 0 descriptors\n"));
510*c2c66affSColin Finck                 Pool->FreeList = NULL;
511*c2c66affSColin Finck             }
512*c2c66affSColin Finck 
513*c2c66affSColin Finck             *Status     = NDIS_STATUS_SUCCESS;
514*c2c66affSColin Finck             *PoolHandle = (PNDIS_HANDLE)Pool;
515*c2c66affSColin Finck         } else {
516*c2c66affSColin Finck             *Status = NDIS_STATUS_RESOURCES;
517*c2c66affSColin Finck         }
518*c2c66affSColin Finck     }
519*c2c66affSColin Finck }
520*c2c66affSColin Finck 
521*c2c66affSColin Finck 
522*c2c66affSColin Finck /*
523*c2c66affSColin Finck  * @implemented
524*c2c66affSColin Finck  */
525*c2c66affSColin Finck #undef NdisBufferLength
526*c2c66affSColin Finck ULONG
527*c2c66affSColin Finck EXPORT
528*c2c66affSColin Finck NdisBufferLength(
529*c2c66affSColin Finck     IN  PNDIS_BUFFER    Buffer)
530*c2c66affSColin Finck /*
531*c2c66affSColin Finck  * FUNCTION: Modifies the length of an NDIS buffer
532*c2c66affSColin Finck  * ARGUMENTS:
533*c2c66affSColin Finck  *     Buffer = Pointer to NDIS buffer descriptor
534*c2c66affSColin Finck  *     Length = New size of buffer
535*c2c66affSColin Finck  * NOTES:
536*c2c66affSColin Finck  *    NDIS 5.0
537*c2c66affSColin Finck  * RETURNS:
538*c2c66affSColin Finck  *     Length of NDIS buffer
539*c2c66affSColin Finck  */
540*c2c66affSColin Finck {
541*c2c66affSColin Finck     return MmGetMdlByteCount(Buffer);
542*c2c66affSColin Finck }
543*c2c66affSColin Finck 
544*c2c66affSColin Finck 
545*c2c66affSColin Finck /*
546*c2c66affSColin Finck  * @implemented
547*c2c66affSColin Finck  */
548*c2c66affSColin Finck #undef NdisBufferVirtualAddress
549*c2c66affSColin Finck PVOID
550*c2c66affSColin Finck EXPORT
551*c2c66affSColin Finck NdisBufferVirtualAddress(
552*c2c66affSColin Finck     IN  PNDIS_BUFFER    Buffer)
553*c2c66affSColin Finck /*
554*c2c66affSColin Finck  * FUNCTION:
555*c2c66affSColin Finck  * ARGUMENTS:
556*c2c66affSColin Finck  * NOTES:
557*c2c66affSColin Finck  *    NDIS 5.0
558*c2c66affSColin Finck  */
559*c2c66affSColin Finck {
560*c2c66affSColin Finck     return MmGetSystemAddressForMdl(Buffer);
561*c2c66affSColin Finck }
562*c2c66affSColin Finck 
563*c2c66affSColin Finck 
564*c2c66affSColin Finck /*
565*c2c66affSColin Finck  * @implemented
566*c2c66affSColin Finck  */
567*c2c66affSColin Finck VOID
568*c2c66affSColin Finck EXPORT
569*c2c66affSColin Finck NdisCopyFromPacketToPacket(
570*c2c66affSColin Finck     IN  PNDIS_PACKET    Destination,
571*c2c66affSColin Finck     IN  UINT            DestinationOffset,
572*c2c66affSColin Finck     IN  UINT            BytesToCopy,
573*c2c66affSColin Finck     IN  PNDIS_PACKET    Source,
574*c2c66affSColin Finck     IN  UINT            SourceOffset,
575*c2c66affSColin Finck     OUT PUINT           BytesCopied)
576*c2c66affSColin Finck /*
577*c2c66affSColin Finck  * FUNCTION: Copies data from one packet to another
578*c2c66affSColin Finck  * ARGUMENTS:
579*c2c66affSColin Finck  *     Destination       = Pointer to packet to copy data to
580*c2c66affSColin Finck  *     DestinationOffset = Offset in destination packet to copy data to
581*c2c66affSColin Finck  *     BytesToCopy       = Number of bytes to copy
582*c2c66affSColin Finck  *     Source            = Pointer to packet descriptor to copy from
583*c2c66affSColin Finck  *     SourceOffset      = Offset in source packet to start copying from
584*c2c66affSColin Finck  *     BytesCopied       = Address of buffer to place number of bytes copied
585*c2c66affSColin Finck  */
586*c2c66affSColin Finck {
587*c2c66affSColin Finck     PNDIS_BUFFER SrcBuffer;
588*c2c66affSColin Finck     PNDIS_BUFFER DstBuffer;
589*c2c66affSColin Finck     PUCHAR DstData, SrcData;
590*c2c66affSColin Finck     UINT DstSize, SrcSize;
591*c2c66affSColin Finck     UINT Count, Total;
592*c2c66affSColin Finck 
593*c2c66affSColin Finck     *BytesCopied = 0;
594*c2c66affSColin Finck 
595*c2c66affSColin Finck     /* Skip DestinationOffset bytes in the destination packet */
596*c2c66affSColin Finck     NdisGetFirstBufferFromPacket(Destination, &DstBuffer, (PVOID*)&DstData, &DstSize, &Total);
597*c2c66affSColin Finck     if (SkipToOffset(DstBuffer, DestinationOffset, &DstData, &DstSize) == 0xFFFFFFFF)
598*c2c66affSColin Finck         return;
599*c2c66affSColin Finck 
600*c2c66affSColin Finck     /* Skip SourceOffset bytes in the source packet */
601*c2c66affSColin Finck     NdisGetFirstBufferFromPacket(Source, &SrcBuffer, (PVOID*)&SrcData, &SrcSize, &Total);
602*c2c66affSColin Finck     if (SkipToOffset(SrcBuffer, SourceOffset, &SrcData, &SrcSize) == 0xFFFFFFFF)
603*c2c66affSColin Finck         return;
604*c2c66affSColin Finck 
605*c2c66affSColin Finck     /* Copy the data */
606*c2c66affSColin Finck     for (Total = 0;;) {
607*c2c66affSColin Finck         /* Find out how many bytes we can copy at one time */
608*c2c66affSColin Finck         if (BytesToCopy < SrcSize)
609*c2c66affSColin Finck             Count = BytesToCopy;
610*c2c66affSColin Finck         else
611*c2c66affSColin Finck             Count = SrcSize;
612*c2c66affSColin Finck         if (DstSize < Count)
613*c2c66affSColin Finck             Count = DstSize;
614*c2c66affSColin Finck 
615*c2c66affSColin Finck         RtlCopyMemory(DstData, SrcData, Count);
616*c2c66affSColin Finck 
617*c2c66affSColin Finck         Total       += Count;
618*c2c66affSColin Finck         BytesToCopy -= Count;
619*c2c66affSColin Finck         if (BytesToCopy == 0)
620*c2c66affSColin Finck             break;
621*c2c66affSColin Finck 
622*c2c66affSColin Finck         DstSize -= Count;
623*c2c66affSColin Finck         if (DstSize == 0) {
624*c2c66affSColin Finck             /* No more bytes in destination buffer. Proceed to
625*c2c66affSColin Finck                the next buffer in the destination buffer chain */
626*c2c66affSColin Finck             NdisGetNextBuffer(DstBuffer, &DstBuffer);
627*c2c66affSColin Finck             if (!DstBuffer)
628*c2c66affSColin Finck                 break;
629*c2c66affSColin Finck 
630*c2c66affSColin Finck             NdisQueryBuffer(DstBuffer, (PVOID)&DstData, &DstSize);
631*c2c66affSColin Finck         }
632*c2c66affSColin Finck 
633*c2c66affSColin Finck         SrcSize -= Count;
634*c2c66affSColin Finck         if (SrcSize == 0) {
635*c2c66affSColin Finck             /* No more bytes in source buffer. Proceed to
636*c2c66affSColin Finck                the next buffer in the source buffer chain */
637*c2c66affSColin Finck             NdisGetNextBuffer(SrcBuffer, &SrcBuffer);
638*c2c66affSColin Finck             if (!SrcBuffer)
639*c2c66affSColin Finck                 break;
640*c2c66affSColin Finck 
641*c2c66affSColin Finck             NdisQueryBuffer(SrcBuffer, (PVOID)&SrcData, &SrcSize);
642*c2c66affSColin Finck         }
643*c2c66affSColin Finck     }
644*c2c66affSColin Finck 
645*c2c66affSColin Finck     *BytesCopied = Total;
646*c2c66affSColin Finck }
647*c2c66affSColin Finck 
648*c2c66affSColin Finck 
649*c2c66affSColin Finck /*
650*c2c66affSColin Finck  * @implemented
651*c2c66affSColin Finck  */
652*c2c66affSColin Finck VOID
653*c2c66affSColin Finck EXPORT
654*c2c66affSColin Finck NdisDprAllocatePacket(
655*c2c66affSColin Finck     OUT PNDIS_STATUS    Status,
656*c2c66affSColin Finck     OUT PNDIS_PACKET    *Packet,
657*c2c66affSColin Finck     IN  NDIS_HANDLE     PoolHandle)
658*c2c66affSColin Finck /*
659*c2c66affSColin Finck  * FUNCTION: Allocates a packet at IRQL DISPATCH_LEVEL
660*c2c66affSColin Finck  * ARGUMENTS:
661*c2c66affSColin Finck  *     Status     = Address of buffer to place status of operation
662*c2c66affSColin Finck  *     Packet     = Address of buffer to place a pointer to a packet descriptor
663*c2c66affSColin Finck  *     PoolHandle = Handle returned by NdisAllocatePacketPool
664*c2c66affSColin Finck  */
665*c2c66affSColin Finck {
666*c2c66affSColin Finck     PNDISI_PACKET_POOL Pool = (PNDISI_PACKET_POOL)PoolHandle;
667*c2c66affSColin Finck 
668*c2c66affSColin Finck     KeAcquireSpinLockAtDpcLevel(&Pool->SpinLock.SpinLock);
669*c2c66affSColin Finck     NdisDprAllocatePacketNonInterlocked(Status,
670*c2c66affSColin Finck                                         Packet,
671*c2c66affSColin Finck                                         PoolHandle);
672*c2c66affSColin Finck     KeReleaseSpinLockFromDpcLevel(&Pool->SpinLock.SpinLock);
673*c2c66affSColin Finck }
674*c2c66affSColin Finck 
675*c2c66affSColin Finck 
676*c2c66affSColin Finck /*
677*c2c66affSColin Finck  * @implemented
678*c2c66affSColin Finck  */
679*c2c66affSColin Finck VOID
680*c2c66affSColin Finck EXPORT
681*c2c66affSColin Finck NdisDprAllocatePacketNonInterlocked(
682*c2c66affSColin Finck     OUT PNDIS_STATUS    Status,
683*c2c66affSColin Finck     OUT PNDIS_PACKET    *Packet,
684*c2c66affSColin Finck     IN NDIS_HANDLE      PoolHandle)
685*c2c66affSColin Finck /*
686*c2c66affSColin Finck  * FUNCTION: Allocates a packet at IRQL DISPATCH_LEVEL (w/o synchronization)
687*c2c66affSColin Finck  * ARGUMENTS:
688*c2c66affSColin Finck  *     Status     = Address of buffer to place status of operation
689*c2c66affSColin Finck  *     Packet     = Address of buffer to place a pointer to a packet descriptor
690*c2c66affSColin Finck  *     PoolHandle = Handle returned by NdisAllocatePacketPool
691*c2c66affSColin Finck  */
692*c2c66affSColin Finck {
693*c2c66affSColin Finck     PNDIS_PACKET Temp;
694*c2c66affSColin Finck     PNDISI_PACKET_POOL Pool = (PNDISI_PACKET_POOL)PoolHandle;
695*c2c66affSColin Finck 
696*c2c66affSColin Finck     NDIS_DbgPrint(MAX_TRACE, ("Status (0x%X)  Packet (0x%X)  PoolHandle (0x%X).\n",
697*c2c66affSColin Finck         Status, Packet, PoolHandle));
698*c2c66affSColin Finck 
699*c2c66affSColin Finck     *Packet = NULL;
700*c2c66affSColin Finck 
701*c2c66affSColin Finck     if (Pool == NULL)
702*c2c66affSColin Finck     {
703*c2c66affSColin Finck         *Status = NDIS_STATUS_FAILURE;
704*c2c66affSColin Finck         NDIS_DbgPrint(MIN_TRACE, ("Called passed a bad pool handle\n"));
705*c2c66affSColin Finck         return;
706*c2c66affSColin Finck     }
707*c2c66affSColin Finck 
708*c2c66affSColin Finck     if (Pool->FreeList) {
709*c2c66affSColin Finck         Temp           = Pool->FreeList;
710*c2c66affSColin Finck         Pool->FreeList = (PNDIS_PACKET)Temp->Reserved[0];
711*c2c66affSColin Finck 
712*c2c66affSColin Finck         RtlZeroMemory(Temp, Pool->PacketLength);
713*c2c66affSColin Finck         Temp->Private.Pool = Pool;
714*c2c66affSColin Finck         Temp->Private.ValidCounts = TRUE;
715*c2c66affSColin Finck         Temp->Private.NdisPacketFlags = fPACKET_ALLOCATED_BY_NDIS;
716*c2c66affSColin Finck         Temp->Private.NdisPacketOobOffset = Pool->PacketLength -
717*c2c66affSColin Finck                                             (sizeof(NDIS_PACKET_OOB_DATA) +
718*c2c66affSColin Finck                                              sizeof(NDIS_PACKET_EXTENSION));
719*c2c66affSColin Finck 
720*c2c66affSColin Finck         *Packet = Temp;
721*c2c66affSColin Finck         *Status = NDIS_STATUS_SUCCESS;
722*c2c66affSColin Finck     } else {
723*c2c66affSColin Finck         NDIS_DbgPrint(MIN_TRACE, ("No more free descriptors\n"));
724*c2c66affSColin Finck         *Status = NDIS_STATUS_RESOURCES;
725*c2c66affSColin Finck     }
726*c2c66affSColin Finck }
727*c2c66affSColin Finck 
728*c2c66affSColin Finck 
729*c2c66affSColin Finck /*
730*c2c66affSColin Finck  * @implemented
731*c2c66affSColin Finck  */
732*c2c66affSColin Finck VOID
733*c2c66affSColin Finck EXPORT
734*c2c66affSColin Finck NdisDprFreePacket(
735*c2c66affSColin Finck     IN  PNDIS_PACKET    Packet)
736*c2c66affSColin Finck /*
737*c2c66affSColin Finck  * FUNCTION: Frees a packet at IRQL DISPATCH_LEVEL
738*c2c66affSColin Finck  * ARGUMENTS:
739*c2c66affSColin Finck  *     Packet = Pointer to packet to free
740*c2c66affSColin Finck  */
741*c2c66affSColin Finck {
742*c2c66affSColin Finck     PNDISI_PACKET_POOL Pool = (PNDISI_PACKET_POOL)Packet->Private.Pool;
743*c2c66affSColin Finck 
744*c2c66affSColin Finck     KeAcquireSpinLockAtDpcLevel(&Pool->SpinLock.SpinLock);
745*c2c66affSColin Finck     NdisDprFreePacketNonInterlocked(Packet);
746*c2c66affSColin Finck     KeReleaseSpinLockFromDpcLevel(&Pool->SpinLock.SpinLock);
747*c2c66affSColin Finck }
748*c2c66affSColin Finck 
749*c2c66affSColin Finck 
750*c2c66affSColin Finck /*
751*c2c66affSColin Finck  * @implemented
752*c2c66affSColin Finck  */
753*c2c66affSColin Finck VOID
754*c2c66affSColin Finck EXPORT
755*c2c66affSColin Finck NdisDprFreePacketNonInterlocked(
756*c2c66affSColin Finck     IN  PNDIS_PACKET    Packet)
757*c2c66affSColin Finck /*
758*c2c66affSColin Finck  * FUNCTION: Frees a packet at IRQL DISPATCH_LEVEL (w/o synchronization)
759*c2c66affSColin Finck  * ARGUMENTS:
760*c2c66affSColin Finck  *     Packet = Pointer to packet to free
761*c2c66affSColin Finck  */
762*c2c66affSColin Finck {
763*c2c66affSColin Finck     NDIS_DbgPrint(MAX_TRACE, ("Packet (0x%X).\n", Packet));
764*c2c66affSColin Finck 
765*c2c66affSColin Finck     Packet->Reserved[0]          = (ULONG_PTR)((NDISI_PACKET_POOL*)Packet->Private.Pool)->FreeList;
766*c2c66affSColin Finck     ((NDISI_PACKET_POOL*)Packet->Private.Pool)->FreeList = Packet;
767*c2c66affSColin Finck }
768*c2c66affSColin Finck 
769*c2c66affSColin Finck 
770*c2c66affSColin Finck /*
771*c2c66affSColin Finck  * @implemented
772*c2c66affSColin Finck  */
773*c2c66affSColin Finck VOID
774*c2c66affSColin Finck EXPORT
775*c2c66affSColin Finck NdisFreeBufferPool(
776*c2c66affSColin Finck     IN  NDIS_HANDLE PoolHandle)
777*c2c66affSColin Finck /*
778*c2c66affSColin Finck  * FUNCTION: Frees storage allocated for an NDIS buffer pool
779*c2c66affSColin Finck  * ARGUMENTS:
780*c2c66affSColin Finck  *     PoolHandle = Handle returned by NdisAllocateBufferPool
781*c2c66affSColin Finck  */
782*c2c66affSColin Finck {
783*c2c66affSColin Finck }
784*c2c66affSColin Finck 
785*c2c66affSColin Finck 
786*c2c66affSColin Finck /*
787*c2c66affSColin Finck  * @implemented
788*c2c66affSColin Finck  */
789*c2c66affSColin Finck VOID
790*c2c66affSColin Finck EXPORT
791*c2c66affSColin Finck NdisFreePacketPool(
792*c2c66affSColin Finck     IN  NDIS_HANDLE PoolHandle)
793*c2c66affSColin Finck /*
794*c2c66affSColin Finck  * FUNCTION: Frees storage allocated for an NDIS packet pool
795*c2c66affSColin Finck  * ARGUMENTS:
796*c2c66affSColin Finck  *     PoolHandle = Handle returned by NdisAllocatePacketPool
797*c2c66affSColin Finck  */
798*c2c66affSColin Finck {
799*c2c66affSColin Finck     ExFreePool((PVOID)PoolHandle);
800*c2c66affSColin Finck }
801*c2c66affSColin Finck 
802*c2c66affSColin Finck 
803*c2c66affSColin Finck /*
804*c2c66affSColin Finck  * @implemented
805*c2c66affSColin Finck  */
806*c2c66affSColin Finck #undef NdisFreeBuffer
807*c2c66affSColin Finck VOID
808*c2c66affSColin Finck EXPORT
809*c2c66affSColin Finck NdisFreeBuffer(
810*c2c66affSColin Finck     IN   PNDIS_BUFFER   Buffer)
811*c2c66affSColin Finck /*
812*c2c66affSColin Finck  * FUNCTION: Puts an NDIS buffer descriptor back in it's pool
813*c2c66affSColin Finck  * ARGUMENTS:
814*c2c66affSColin Finck  *     Buffer = Pointer to buffer descriptor
815*c2c66affSColin Finck  */
816*c2c66affSColin Finck {
817*c2c66affSColin Finck     IoFreeMdl(Buffer);
818*c2c66affSColin Finck }
819*c2c66affSColin Finck 
820*c2c66affSColin Finck 
821*c2c66affSColin Finck /*
822*c2c66affSColin Finck  * @implemented
823*c2c66affSColin Finck  */
824*c2c66affSColin Finck VOID
825*c2c66affSColin Finck EXPORT
826*c2c66affSColin Finck NdisFreePacket(
827*c2c66affSColin Finck     IN   PNDIS_PACKET   Packet)
828*c2c66affSColin Finck /*
829*c2c66affSColin Finck  * FUNCTION: Puts an NDIS packet descriptor back in it's pool
830*c2c66affSColin Finck  * ARGUMENTS:
831*c2c66affSColin Finck  *     Packet = Pointer to packet descriptor
832*c2c66affSColin Finck  */
833*c2c66affSColin Finck {
834*c2c66affSColin Finck     PNDISI_PACKET_POOL Pool = (PNDISI_PACKET_POOL)Packet->Private.Pool;
835*c2c66affSColin Finck 
836*c2c66affSColin Finck     KeAcquireSpinLock(&Pool->SpinLock.SpinLock, &Pool->SpinLock.OldIrql);
837*c2c66affSColin Finck     NdisDprFreePacketNonInterlocked(Packet);
838*c2c66affSColin Finck     KeReleaseSpinLock(&Pool->SpinLock.SpinLock, Pool->SpinLock.OldIrql);
839*c2c66affSColin Finck }
840*c2c66affSColin Finck 
841*c2c66affSColin Finck 
842*c2c66affSColin Finck /*
843*c2c66affSColin Finck  * @implemented
844*c2c66affSColin Finck  */
845*c2c66affSColin Finck #undef NdisGetBufferPhysicalArraySize
846*c2c66affSColin Finck VOID
847*c2c66affSColin Finck EXPORT
848*c2c66affSColin Finck NdisGetBufferPhysicalArraySize(
849*c2c66affSColin Finck     IN  PNDIS_BUFFER    Buffer,
850*c2c66affSColin Finck     OUT PUINT           ArraySize)
851*c2c66affSColin Finck /*
852*c2c66affSColin Finck  * FUNCTION: Returns number of discontiguous physical blocks backing a buffer
853*c2c66affSColin Finck  * ARGUMENTS:
854*c2c66affSColin Finck  *     Buffer    = Pointer to buffer descriptor
855*c2c66affSColin Finck  *     ArraySize = Address of buffer to place number of physical blocks
856*c2c66affSColin Finck  */
857*c2c66affSColin Finck {
858*c2c66affSColin Finck   ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
859*c2c66affSColin Finck   ASSERT(Buffer && ArraySize);
860*c2c66affSColin Finck 
861*c2c66affSColin Finck   *ArraySize = NDIS_BUFFER_TO_SPAN_PAGES(Buffer);
862*c2c66affSColin Finck }
863*c2c66affSColin Finck 
864*c2c66affSColin Finck 
865*c2c66affSColin Finck /*
866*c2c66affSColin Finck  * @implemented
867*c2c66affSColin Finck  */
868*c2c66affSColin Finck #undef NdisGetFirstBufferFromPacket
869*c2c66affSColin Finck VOID
870*c2c66affSColin Finck EXPORT
871*c2c66affSColin Finck NdisGetFirstBufferFromPacket(
872*c2c66affSColin Finck     IN  PNDIS_PACKET    _Packet,
873*c2c66affSColin Finck     OUT PNDIS_BUFFER    *_FirstBuffer,
874*c2c66affSColin Finck     OUT PVOID           *_FirstBufferVA,
875*c2c66affSColin Finck     OUT PUINT           _FirstBufferLength,
876*c2c66affSColin Finck     OUT PUINT           _TotalBufferLength)
877*c2c66affSColin Finck /*
878*c2c66affSColin Finck  * FUNCTION: Retrieves information about an NDIS packet
879*c2c66affSColin Finck  * ARGUMENTS:
880*c2c66affSColin Finck  *     _Packet            = Pointer to NDIS packet
881*c2c66affSColin Finck  *     _FirstBuffer       = Address of buffer for pointer to first NDIS buffer
882*c2c66affSColin Finck  *     _FirstBufferVA     = Address of buffer for address of first NDIS buffer
883*c2c66affSColin Finck  *     _FirstBufferLength = Address of buffer for length of first buffer
884*c2c66affSColin Finck  *     _TotalBufferLength = Address of buffer for total length of packet
885*c2c66affSColin Finck  */
886*c2c66affSColin Finck {
887*c2c66affSColin Finck     PNDIS_BUFFER Buffer;
888*c2c66affSColin Finck 
889*c2c66affSColin Finck     Buffer          = _Packet->Private.Head;
890*c2c66affSColin Finck     *_FirstBuffer   = Buffer;
891*c2c66affSColin Finck 
892*c2c66affSColin Finck     if (Buffer != NULL) {
893*c2c66affSColin Finck         *_FirstBufferLength = MmGetMdlByteCount(Buffer);
894*c2c66affSColin Finck         *_FirstBufferVA = MmGetSystemAddressForMdl(Buffer);
895*c2c66affSColin Finck         Buffer = Buffer->Next;
896*c2c66affSColin Finck     } else {
897*c2c66affSColin Finck         NDIS_DbgPrint(MID_TRACE, ("No buffers linked to this packet\n"));
898*c2c66affSColin Finck         *_FirstBufferLength = 0;
899*c2c66affSColin Finck         *_FirstBufferVA = NULL;
900*c2c66affSColin Finck     }
901*c2c66affSColin Finck 
902*c2c66affSColin Finck     *_TotalBufferLength = *_FirstBufferLength;
903*c2c66affSColin Finck 
904*c2c66affSColin Finck     while (Buffer != NULL) {
905*c2c66affSColin Finck         *_TotalBufferLength += MmGetMdlByteCount(Buffer);
906*c2c66affSColin Finck         Buffer = Buffer->Next;
907*c2c66affSColin Finck     }
908*c2c66affSColin Finck }
909*c2c66affSColin Finck 
910*c2c66affSColin Finck #undef NdisGetFirstBufferFromPacketSafe
911*c2c66affSColin Finck /*
912*c2c66affSColin Finck  * @implemented
913*c2c66affSColin Finck  */
914*c2c66affSColin Finck VOID
915*c2c66affSColin Finck EXPORT
916*c2c66affSColin Finck NdisGetFirstBufferFromPacketSafe(
917*c2c66affSColin Finck     IN  PNDIS_PACKET     _Packet,
918*c2c66affSColin Finck     OUT PNDIS_BUFFER     *_FirstBuffer,
919*c2c66affSColin Finck     OUT PVOID            *_FirstBufferVA,
920*c2c66affSColin Finck     OUT PUINT            _FirstBufferLength,
921*c2c66affSColin Finck     OUT PUINT            _TotalBufferLength,
922*c2c66affSColin Finck     IN  MM_PAGE_PRIORITY Priority)
923*c2c66affSColin Finck {
924*c2c66affSColin Finck     PNDIS_BUFFER Buffer;
925*c2c66affSColin Finck 
926*c2c66affSColin Finck     Buffer          = _Packet->Private.Head;
927*c2c66affSColin Finck     *_FirstBuffer   = Buffer;
928*c2c66affSColin Finck 
929*c2c66affSColin Finck     if (Buffer != NULL) {
930*c2c66affSColin Finck         *_FirstBufferLength = MmGetMdlByteCount(Buffer);
931*c2c66affSColin Finck         *_FirstBufferVA = MmGetSystemAddressForMdlSafe(Buffer, Priority);
932*c2c66affSColin Finck         Buffer = Buffer->Next;
933*c2c66affSColin Finck     } else {
934*c2c66affSColin Finck         NDIS_DbgPrint(MID_TRACE, ("No buffers linked to this packet\n"));
935*c2c66affSColin Finck         *_FirstBufferLength = 0;
936*c2c66affSColin Finck         *_FirstBufferVA = NULL;
937*c2c66affSColin Finck     }
938*c2c66affSColin Finck 
939*c2c66affSColin Finck     *_TotalBufferLength = *_FirstBufferLength;
940*c2c66affSColin Finck 
941*c2c66affSColin Finck     while (Buffer != NULL) {
942*c2c66affSColin Finck         *_TotalBufferLength += MmGetMdlByteCount(Buffer);
943*c2c66affSColin Finck         Buffer = Buffer->Next;
944*c2c66affSColin Finck     }
945*c2c66affSColin Finck }
946*c2c66affSColin Finck 
947*c2c66affSColin Finck /*
948*c2c66affSColin Finck  * @implemented
949*c2c66affSColin Finck  */
950*c2c66affSColin Finck #undef NdisQueryBuffer
951*c2c66affSColin Finck VOID
952*c2c66affSColin Finck EXPORT
953*c2c66affSColin Finck NdisQueryBuffer(
954*c2c66affSColin Finck     IN  PNDIS_BUFFER    Buffer,
955*c2c66affSColin Finck     OUT PVOID           *VirtualAddress OPTIONAL,
956*c2c66affSColin Finck     OUT PUINT           Length)
957*c2c66affSColin Finck /*
958*c2c66affSColin Finck  * FUNCTION:
959*c2c66affSColin Finck  *     Queries an NDIS buffer for information
960*c2c66affSColin Finck  * ARGUMENTS:
961*c2c66affSColin Finck  *     Buffer         = Pointer to NDIS buffer to query
962*c2c66affSColin Finck  *     VirtualAddress = Address of buffer to place virtual address
963*c2c66affSColin Finck  *     Length         = Address of buffer to place length of buffer
964*c2c66affSColin Finck  */
965*c2c66affSColin Finck {
966*c2c66affSColin Finck 	if (VirtualAddress != NULL)
967*c2c66affSColin Finck 		*(PVOID*)VirtualAddress = MmGetSystemAddressForMdl(Buffer);
968*c2c66affSColin Finck 
969*c2c66affSColin Finck 	*Length = MmGetMdlByteCount(Buffer);
970*c2c66affSColin Finck }
971*c2c66affSColin Finck 
972*c2c66affSColin Finck 
973*c2c66affSColin Finck /*
974*c2c66affSColin Finck  * @implemented
975*c2c66affSColin Finck  */
976*c2c66affSColin Finck #undef NdisQueryBufferSafe
977*c2c66affSColin Finck VOID
978*c2c66affSColin Finck EXPORT
979*c2c66affSColin Finck NdisQueryBufferSafe(
980*c2c66affSColin Finck     IN  PNDIS_BUFFER    Buffer,
981*c2c66affSColin Finck     OUT PVOID           *VirtualAddress OPTIONAL,
982*c2c66affSColin Finck     OUT PUINT           Length,
983*c2c66affSColin Finck     IN  UINT            Priority)
984*c2c66affSColin Finck /*
985*c2c66affSColin Finck  * FUNCTION:
986*c2c66affSColin Finck  * ARGUMENTS:
987*c2c66affSColin Finck  * NOTES:
988*c2c66affSColin Finck  *    NDIS 5.0
989*c2c66affSColin Finck  */
990*c2c66affSColin Finck {
991*c2c66affSColin Finck     if (VirtualAddress != NULL)
992*c2c66affSColin Finck         *VirtualAddress = MmGetSystemAddressForMdlSafe(Buffer, Priority);
993*c2c66affSColin Finck     *Length = MmGetMdlByteCount(Buffer);
994*c2c66affSColin Finck }
995*c2c66affSColin Finck 
996*c2c66affSColin Finck 
997*c2c66affSColin Finck /*
998*c2c66affSColin Finck  * @implemented
999*c2c66affSColin Finck  */
1000*c2c66affSColin Finck #undef NdisQueryBufferOffset
1001*c2c66affSColin Finck VOID
1002*c2c66affSColin Finck EXPORT
1003*c2c66affSColin Finck NdisQueryBufferOffset(
1004*c2c66affSColin Finck     IN  PNDIS_BUFFER    Buffer,
1005*c2c66affSColin Finck     OUT PUINT           Offset,
1006*c2c66affSColin Finck     OUT PUINT           Length)
1007*c2c66affSColin Finck {
1008*c2c66affSColin Finck     *((PUINT)Offset) = MmGetMdlByteOffset(Buffer);
1009*c2c66affSColin Finck     *((PUINT)Length) = MmGetMdlByteCount(Buffer);
1010*c2c66affSColin Finck }
1011*c2c66affSColin Finck 
1012*c2c66affSColin Finck 
1013*c2c66affSColin Finck /*
1014*c2c66affSColin Finck  * @implemented
1015*c2c66affSColin Finck  */
1016*c2c66affSColin Finck VOID
1017*c2c66affSColin Finck EXPORT
1018*c2c66affSColin Finck NdisUnchainBufferAtBack(
1019*c2c66affSColin Finck     IN OUT  PNDIS_PACKET    Packet,
1020*c2c66affSColin Finck     OUT     PNDIS_BUFFER    *Buffer)
1021*c2c66affSColin Finck /*
1022*c2c66affSColin Finck  * FUNCTION:
1023*c2c66affSColin Finck  *     Removes the last buffer in a packet
1024*c2c66affSColin Finck  * ARGUMENTS:
1025*c2c66affSColin Finck  *     Packet = Pointer to NDIS packet
1026*c2c66affSColin Finck  *     Buffer = Address of buffer to place pointer to removed NDIS buffer
1027*c2c66affSColin Finck  */
1028*c2c66affSColin Finck {
1029*c2c66affSColin Finck 	PNDIS_BUFFER NdisBuffer, Previous;
1030*c2c66affSColin Finck 
1031*c2c66affSColin Finck     NdisQueryPacket(Packet,
1032*c2c66affSColin Finck                     NULL,
1033*c2c66affSColin Finck                     NULL,
1034*c2c66affSColin Finck                     &NdisBuffer,
1035*c2c66affSColin Finck                     NULL);
1036*c2c66affSColin Finck     if (!NdisBuffer) {
1037*c2c66affSColin Finck         NDIS_DbgPrint(MID_TRACE, ("No buffer to unchain\n"));
1038*c2c66affSColin Finck         *Buffer = NULL;
1039*c2c66affSColin Finck         return;
1040*c2c66affSColin Finck     }
1041*c2c66affSColin Finck 
1042*c2c66affSColin Finck     Previous = NULL;
1043*c2c66affSColin Finck     while (NdisBuffer->Next) {
1044*c2c66affSColin Finck         Previous   = NdisBuffer;
1045*c2c66affSColin Finck         NdisBuffer = NdisBuffer->Next;
1046*c2c66affSColin Finck     }
1047*c2c66affSColin Finck 
1048*c2c66affSColin Finck     if (Previous) {
1049*c2c66affSColin Finck         Previous->Next       = NULL;
1050*c2c66affSColin Finck         Packet->Private.Tail = Previous;
1051*c2c66affSColin Finck     } else {
1052*c2c66affSColin Finck         Packet->Private.Head = NULL;
1053*c2c66affSColin Finck         Packet->Private.Tail = NULL;
1054*c2c66affSColin Finck     }
1055*c2c66affSColin Finck 
1056*c2c66affSColin Finck     Packet->Private.ValidCounts = FALSE;
1057*c2c66affSColin Finck 
1058*c2c66affSColin Finck     *Buffer = NdisBuffer;
1059*c2c66affSColin Finck }
1060*c2c66affSColin Finck 
1061*c2c66affSColin Finck 
1062*c2c66affSColin Finck /*
1063*c2c66affSColin Finck  * @implemented
1064*c2c66affSColin Finck  */
1065*c2c66affSColin Finck VOID
1066*c2c66affSColin Finck EXPORT
1067*c2c66affSColin Finck NdisUnchainBufferAtFront(
1068*c2c66affSColin Finck     IN OUT  PNDIS_PACKET    Packet,
1069*c2c66affSColin Finck     OUT     PNDIS_BUFFER    *Buffer)
1070*c2c66affSColin Finck /*
1071*c2c66affSColin Finck  * FUNCTION:
1072*c2c66affSColin Finck  *     Removes the first buffer in a packet
1073*c2c66affSColin Finck  * ARGUMENTS:
1074*c2c66affSColin Finck  *     Packet = Pointer to NDIS packet
1075*c2c66affSColin Finck  *     Buffer = Address of buffer to place pointer to removed NDIS buffer
1076*c2c66affSColin Finck  */
1077*c2c66affSColin Finck {
1078*c2c66affSColin Finck 	PNDIS_BUFFER NdisBuffer;
1079*c2c66affSColin Finck 
1080*c2c66affSColin Finck     NdisQueryPacket(Packet,
1081*c2c66affSColin Finck                     NULL,
1082*c2c66affSColin Finck                     NULL,
1083*c2c66affSColin Finck                     &NdisBuffer,
1084*c2c66affSColin Finck                     NULL);
1085*c2c66affSColin Finck     if (!NdisBuffer) {
1086*c2c66affSColin Finck         NDIS_DbgPrint(MID_TRACE, ("No buffer to unchain\n"));
1087*c2c66affSColin Finck         *Buffer = NULL;
1088*c2c66affSColin Finck         return;
1089*c2c66affSColin Finck     }
1090*c2c66affSColin Finck 
1091*c2c66affSColin Finck     Packet->Private.Head = NdisBuffer->Next;
1092*c2c66affSColin Finck 
1093*c2c66affSColin Finck     if (!NdisBuffer->Next)
1094*c2c66affSColin Finck         Packet->Private.Tail = NULL;
1095*c2c66affSColin Finck 
1096*c2c66affSColin Finck     NdisBuffer->Next = NULL;
1097*c2c66affSColin Finck 
1098*c2c66affSColin Finck     Packet->Private.ValidCounts = FALSE;
1099*c2c66affSColin Finck 
1100*c2c66affSColin Finck     *Buffer = NdisBuffer;
1101*c2c66affSColin Finck }
1102*c2c66affSColin Finck 
1103*c2c66affSColin Finck /*
1104*c2c66affSColin Finck  * @implemented
1105*c2c66affSColin Finck  */
1106*c2c66affSColin Finck VOID
1107*c2c66affSColin Finck EXPORT
1108*c2c66affSColin Finck NdisCopyBuffer(
1109*c2c66affSColin Finck     OUT PNDIS_STATUS    Status,
1110*c2c66affSColin Finck     OUT PNDIS_BUFFER    *Buffer,
1111*c2c66affSColin Finck     IN  NDIS_HANDLE     PoolHandle,
1112*c2c66affSColin Finck     IN  PVOID           MemoryDescriptor,
1113*c2c66affSColin Finck     IN  UINT            Offset,
1114*c2c66affSColin Finck     IN  UINT            Length)
1115*c2c66affSColin Finck /*
1116*c2c66affSColin Finck  * FUNCTION: Returns a new buffer descriptor for a (partial) buffer
1117*c2c66affSColin Finck  * ARGUMENTS:
1118*c2c66affSColin Finck  *     Status           = Address of a buffer to place status of operation
1119*c2c66affSColin Finck  *     Buffer           = Address of a buffer to place new buffer descriptor
1120*c2c66affSColin Finck  *     PoolHandle       = Handle returned by NdisAllocateBufferPool
1121*c2c66affSColin Finck  *     MemoryDescriptor = Pointer to a memory descriptor (possibly NDIS_BUFFER)
1122*c2c66affSColin Finck  *     Offset           = Offset in buffer to start copying
1123*c2c66affSColin Finck  *     Length           = Number of bytes to copy
1124*c2c66affSColin Finck  */
1125*c2c66affSColin Finck {
1126*c2c66affSColin Finck     PVOID CurrentVa = (PUCHAR)(MmGetMdlVirtualAddress((PNDIS_BUFFER)MemoryDescriptor)) + Offset;
1127*c2c66affSColin Finck 
1128*c2c66affSColin Finck     NDIS_DbgPrint(MAX_TRACE, ("Called\n"));
1129*c2c66affSColin Finck 
1130*c2c66affSColin Finck     *Buffer = IoAllocateMdl(CurrentVa, Length, FALSE, FALSE, NULL);
1131*c2c66affSColin Finck     if (!*Buffer)
1132*c2c66affSColin Finck     {
1133*c2c66affSColin Finck         NDIS_DbgPrint(MIN_TRACE, ("IoAllocateMdl failed (%x, %lx)\n", CurrentVa, Length));
1134*c2c66affSColin Finck         *Status = NDIS_STATUS_FAILURE;
1135*c2c66affSColin Finck         return;
1136*c2c66affSColin Finck     }
1137*c2c66affSColin Finck 
1138*c2c66affSColin Finck     IoBuildPartialMdl((PNDIS_BUFFER)MemoryDescriptor,
1139*c2c66affSColin Finck                       *Buffer,
1140*c2c66affSColin Finck                       CurrentVa,
1141*c2c66affSColin Finck                       Length);
1142*c2c66affSColin Finck 
1143*c2c66affSColin Finck     (*Buffer)->Next = NULL;
1144*c2c66affSColin Finck     *Status = NDIS_STATUS_SUCCESS;
1145*c2c66affSColin Finck }
1146*c2c66affSColin Finck 
1147*c2c66affSColin Finck /*
1148*c2c66affSColin Finck  * @implemented
1149*c2c66affSColin Finck  */
1150*c2c66affSColin Finck NDIS_HANDLE
1151*c2c66affSColin Finck EXPORT
1152*c2c66affSColin Finck NdisGetPoolFromPacket(
1153*c2c66affSColin Finck     IN PNDIS_PACKET  Packet)
1154*c2c66affSColin Finck {
1155*c2c66affSColin Finck     return Packet->Private.Pool;
1156*c2c66affSColin Finck }
1157*c2c66affSColin Finck 
1158*c2c66affSColin Finck /*
1159*c2c66affSColin Finck  * @implemented
1160*c2c66affSColin Finck  */
1161*c2c66affSColin Finck UINT
1162*c2c66affSColin Finck EXPORT
1163*c2c66affSColin Finck NdisPacketSize(
1164*c2c66affSColin Finck     IN UINT  ProtocolReservedSize)
1165*c2c66affSColin Finck {
1166*c2c66affSColin Finck     return sizeof(NDIS_PACKET) + sizeof(NDIS_PACKET_OOB_DATA) +
1167*c2c66affSColin Finck                  sizeof(NDIS_PACKET_EXTENSION) + ProtocolReservedSize;
1168*c2c66affSColin Finck }
1169*c2c66affSColin Finck 
1170*c2c66affSColin Finck /*
1171*c2c66affSColin Finck  * @implemented
1172*c2c66affSColin Finck  */
1173*c2c66affSColin Finck #undef NdisGetPacketCancelId
1174*c2c66affSColin Finck PVOID
1175*c2c66affSColin Finck EXPORT
1176*c2c66affSColin Finck NdisGetPacketCancelId(
1177*c2c66affSColin Finck     IN PNDIS_PACKET  Packet)
1178*c2c66affSColin Finck {
1179*c2c66affSColin Finck     return NDIS_GET_PACKET_CANCEL_ID(Packet);
1180*c2c66affSColin Finck }
1181*c2c66affSColin Finck 
1182*c2c66affSColin Finck /*
1183*c2c66affSColin Finck  * @implemented
1184*c2c66affSColin Finck  */
1185*c2c66affSColin Finck #undef NdisSetPacketCancelId
1186*c2c66affSColin Finck VOID
1187*c2c66affSColin Finck EXPORT
1188*c2c66affSColin Finck NdisSetPacketCancelId(
1189*c2c66affSColin Finck     IN PNDIS_PACKET  Packet,
1190*c2c66affSColin Finck     IN PVOID  CancelId)
1191*c2c66affSColin Finck {
1192*c2c66affSColin Finck     NDIS_SET_PACKET_CANCEL_ID(Packet, CancelId);
1193*c2c66affSColin Finck }
1194*c2c66affSColin Finck 
1195*c2c66affSColin Finck /*
1196*c2c66affSColin Finck  * @implemented
1197*c2c66affSColin Finck  */
1198*c2c66affSColin Finck VOID
1199*c2c66affSColin Finck EXPORT
1200*c2c66affSColin Finck NdisCopyFromPacketToPacketSafe(
1201*c2c66affSColin Finck     IN  PNDIS_PACKET     Destination,
1202*c2c66affSColin Finck     IN  UINT             DestinationOffset,
1203*c2c66affSColin Finck     IN  UINT             BytesToCopy,
1204*c2c66affSColin Finck     IN  PNDIS_PACKET     Source,
1205*c2c66affSColin Finck     IN  UINT             SourceOffset,
1206*c2c66affSColin Finck     OUT PUINT            BytesCopied,
1207*c2c66affSColin Finck     IN  MM_PAGE_PRIORITY Priority)
1208*c2c66affSColin Finck {
1209*c2c66affSColin Finck     PNDIS_BUFFER SrcBuffer;
1210*c2c66affSColin Finck     PNDIS_BUFFER DstBuffer;
1211*c2c66affSColin Finck     PUCHAR DstData, SrcData;
1212*c2c66affSColin Finck     UINT DstSize, SrcSize;
1213*c2c66affSColin Finck     UINT Count, Total;
1214*c2c66affSColin Finck 
1215*c2c66affSColin Finck     *BytesCopied = 0;
1216*c2c66affSColin Finck 
1217*c2c66affSColin Finck     /* Skip DestinationOffset bytes in the destination packet */
1218*c2c66affSColin Finck     NdisGetFirstBufferFromPacketSafe(Destination, &DstBuffer, (PVOID*)&DstData, &DstSize, &Total, Priority);
1219*c2c66affSColin Finck     if (!DstData || SkipToOffset(DstBuffer, DestinationOffset, &DstData, &DstSize) == 0xFFFFFFFF)
1220*c2c66affSColin Finck         return;
1221*c2c66affSColin Finck 
1222*c2c66affSColin Finck     /* Skip SourceOffset bytes in the source packet */
1223*c2c66affSColin Finck     NdisGetFirstBufferFromPacketSafe(Source, &SrcBuffer, (PVOID*)&SrcData, &SrcSize, &Total, Priority);
1224*c2c66affSColin Finck     if (!SrcData || SkipToOffset(SrcBuffer, SourceOffset, &SrcData, &SrcSize) == 0xFFFFFFFF)
1225*c2c66affSColin Finck         return;
1226*c2c66affSColin Finck 
1227*c2c66affSColin Finck     /* Copy the data */
1228*c2c66affSColin Finck     for (Total = 0;;) {
1229*c2c66affSColin Finck         /* Find out how many bytes we can copy at one time */
1230*c2c66affSColin Finck         if (BytesToCopy < SrcSize)
1231*c2c66affSColin Finck             Count = BytesToCopy;
1232*c2c66affSColin Finck         else
1233*c2c66affSColin Finck             Count = SrcSize;
1234*c2c66affSColin Finck         if (DstSize < Count)
1235*c2c66affSColin Finck             Count = DstSize;
1236*c2c66affSColin Finck 
1237*c2c66affSColin Finck         RtlCopyMemory(DstData, SrcData, Count);
1238*c2c66affSColin Finck 
1239*c2c66affSColin Finck         Total       += Count;
1240*c2c66affSColin Finck         BytesToCopy -= Count;
1241*c2c66affSColin Finck         if (BytesToCopy == 0)
1242*c2c66affSColin Finck             break;
1243*c2c66affSColin Finck 
1244*c2c66affSColin Finck         DstSize -= Count;
1245*c2c66affSColin Finck         if (DstSize == 0) {
1246*c2c66affSColin Finck             /* No more bytes in destination buffer. Proceed to
1247*c2c66affSColin Finck                the next buffer in the destination buffer chain */
1248*c2c66affSColin Finck             NdisGetNextBuffer(DstBuffer, &DstBuffer);
1249*c2c66affSColin Finck             if (!DstBuffer)
1250*c2c66affSColin Finck                 break;
1251*c2c66affSColin Finck 
1252*c2c66affSColin Finck             NdisQueryBufferSafe(DstBuffer, (PVOID)&DstData, &DstSize, Priority);
1253*c2c66affSColin Finck             if (!DstData)
1254*c2c66affSColin Finck                 break;
1255*c2c66affSColin Finck         }
1256*c2c66affSColin Finck 
1257*c2c66affSColin Finck         SrcSize -= Count;
1258*c2c66affSColin Finck         if (SrcSize == 0) {
1259*c2c66affSColin Finck             /* No more bytes in source buffer. Proceed to
1260*c2c66affSColin Finck                the next buffer in the source buffer chain */
1261*c2c66affSColin Finck             NdisGetNextBuffer(SrcBuffer, &SrcBuffer);
1262*c2c66affSColin Finck             if (!SrcBuffer)
1263*c2c66affSColin Finck                 break;
1264*c2c66affSColin Finck 
1265*c2c66affSColin Finck             NdisQueryBufferSafe(SrcBuffer, (PVOID)&SrcData, &SrcSize, Priority);
1266*c2c66affSColin Finck             if (!SrcData)
1267*c2c66affSColin Finck                 break;
1268*c2c66affSColin Finck         }
1269*c2c66affSColin Finck     }
1270*c2c66affSColin Finck 
1271*c2c66affSColin Finck     *BytesCopied = Total;
1272*c2c66affSColin Finck }
1273*c2c66affSColin Finck 
1274*c2c66affSColin Finck /*
1275*c2c66affSColin Finck  * @implemented
1276*c2c66affSColin Finck  */
1277*c2c66affSColin Finck VOID
1278*c2c66affSColin Finck EXPORT
1279*c2c66affSColin Finck NdisIMCopySendCompletePerPacketInfo(
1280*c2c66affSColin Finck     IN  PNDIS_PACKET    DstPacket,
1281*c2c66affSColin Finck     IN  PNDIS_PACKET    SrcPacket)
1282*c2c66affSColin Finck /*
1283*c2c66affSColin Finck  * FUNCTION:
1284*c2c66affSColin Finck  * ARGUMENTS:
1285*c2c66affSColin Finck  * NOTES:
1286*c2c66affSColin Finck  *    NDIS 5.0
1287*c2c66affSColin Finck  */
1288*c2c66affSColin Finck {
1289*c2c66affSColin Finck     /* FIXME: What is the difference between NdisIMCopySendPerPacketInfo and
1290*c2c66affSColin Finck      * NdisIMCopySendCompletePerPacketInfo?
1291*c2c66affSColin Finck      */
1292*c2c66affSColin Finck 
1293*c2c66affSColin Finck     NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
1294*c2c66affSColin Finck 
1295*c2c66affSColin Finck     RtlCopyMemory(NDIS_PACKET_EXTENSION_FROM_PACKET(DstPacket),
1296*c2c66affSColin Finck                   NDIS_PACKET_EXTENSION_FROM_PACKET(SrcPacket),
1297*c2c66affSColin Finck                   sizeof(NDIS_PACKET_EXTENSION));
1298*c2c66affSColin Finck }
1299*c2c66affSColin Finck 
1300*c2c66affSColin Finck 
1301*c2c66affSColin Finck /*
1302*c2c66affSColin Finck  * @implemented
1303*c2c66affSColin Finck  */
1304*c2c66affSColin Finck VOID
1305*c2c66affSColin Finck EXPORT
1306*c2c66affSColin Finck NdisIMCopySendPerPacketInfo(
1307*c2c66affSColin Finck     IN  PNDIS_PACKET    DstPacket,
1308*c2c66affSColin Finck     IN  PNDIS_PACKET    SrcPacket)
1309*c2c66affSColin Finck /*
1310*c2c66affSColin Finck  * FUNCTION:
1311*c2c66affSColin Finck  * ARGUMENTS:
1312*c2c66affSColin Finck  * NOTES:
1313*c2c66affSColin Finck  *    NDIS 5.0
1314*c2c66affSColin Finck  */
1315*c2c66affSColin Finck {
1316*c2c66affSColin Finck     /* FIXME: What is the difference between NdisIMCopySendPerPacketInfo and
1317*c2c66affSColin Finck      * NdisIMCopySendCompletePerPacketInfo?
1318*c2c66affSColin Finck      */
1319*c2c66affSColin Finck 
1320*c2c66affSColin Finck     NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
1321*c2c66affSColin Finck 
1322*c2c66affSColin Finck     RtlCopyMemory(NDIS_PACKET_EXTENSION_FROM_PACKET(DstPacket),
1323*c2c66affSColin Finck                   NDIS_PACKET_EXTENSION_FROM_PACKET(SrcPacket),
1324*c2c66affSColin Finck                   sizeof(NDIS_PACKET_EXTENSION));
1325*c2c66affSColin Finck }
1326*c2c66affSColin Finck 
1327*c2c66affSColin Finck /* EOF */
1328