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