2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS NDIS library
5 * PURPOSE: Buffer management routines
6 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
8 * CSH 01/08-2000 Created
14 __inline ULONG
SkipToOffset(
15 IN PNDIS_BUFFER Buffer
,
20 * FUNCTION: Skips Offset bytes into a buffer chain
22 * Buffer = Pointer to NDIS buffer
23 * Offset = Number of bytes to skip
24 * Data = Address of a pointer that on return will contain the
25 * address of the offset in the buffer
26 * Size = Address of a pointer that on return will contain the
27 * size of the destination buffer
29 * Offset into buffer, -1 if buffer chain was smaller than Offset bytes
39 NdisQueryBuffer(Buffer
, (PVOID
)Data
, Size
);
42 *Data
= (PUCHAR
) ((ULONG_PTR
) *Data
+ Offset
);
49 NdisGetNextBuffer(Buffer
, &Buffer
);
55 UINT
CopyBufferToBufferChain(
56 PNDIS_BUFFER DstBuffer
,
61 * FUNCTION: Copies data from a buffer to an NDIS buffer chain
63 * DstBuffer = Pointer to destination NDIS buffer
64 * DstOffset = Destination start offset
65 * SrcData = Pointer to source buffer
66 * Length = Number of bytes to copy
68 * Number of bytes copied to destination buffer
70 * The number of bytes copied may be limited by the destination
74 UINT BytesCopied
, BytesToCopy
, DstSize
;
77 NDIS_DbgPrint(MAX_TRACE
, ("DstBuffer (0x%X) DstOffset (0x%X) SrcData (0x%X) Length (%d)\n", DstBuffer
, DstOffset
, SrcData
, Length
));
79 /* Skip DstOffset bytes in the destination buffer chain */
80 if (SkipToOffset(DstBuffer
, DstOffset
, &DstData
, &DstSize
) == 0xFFFFFFFF)
83 /* Start copying the data */
86 BytesToCopy
= MIN(DstSize
, Length
);
88 RtlCopyMemory((PVOID
)DstData
, (PVOID
)SrcData
, BytesToCopy
);
89 BytesCopied
+= BytesToCopy
;
90 SrcData
= (PUCHAR
) ((ULONG_PTR
) SrcData
+ BytesToCopy
);
92 Length
-= BytesToCopy
;
96 DstSize
-= BytesToCopy
;
98 /* No more bytes in desination buffer. Proceed to
99 the next buffer in the destination buffer chain */
100 NdisGetNextBuffer(DstBuffer
, &DstBuffer
);
104 NdisQueryBuffer(DstBuffer
, (PVOID
)&DstData
, &DstSize
);
112 UINT
CopyBufferChainToBuffer(
114 PNDIS_BUFFER SrcBuffer
,
118 * FUNCTION: Copies data from an NDIS buffer chain to a buffer
120 * DstData = Pointer to destination buffer
121 * SrcBuffer = Pointer to source NDIS buffer
122 * SrcOffset = Source start offset
123 * Length = Number of bytes to copy
125 * Number of bytes copied to destination buffer
127 * The number of bytes copied may be limited by the source
131 UINT BytesCopied
, BytesToCopy
, SrcSize
;
134 NDIS_DbgPrint(MAX_TRACE
, ("DstData 0x%X SrcBuffer 0x%X SrcOffset 0x%X Length %d\n",DstData
,SrcBuffer
, SrcOffset
, Length
));
136 /* Skip SrcOffset bytes in the source buffer chain */
137 if (SkipToOffset(SrcBuffer
, SrcOffset
, &SrcData
, &SrcSize
) == 0xFFFFFFFF)
140 /* Start copying the data */
143 BytesToCopy
= MIN(SrcSize
, Length
);
145 NDIS_DbgPrint(MAX_TRACE
, ("Copying (%d) bytes from 0x%X to 0x%X\n", BytesToCopy
, SrcData
, DstData
));
147 RtlCopyMemory((PVOID
)DstData
, (PVOID
)SrcData
, BytesToCopy
);
148 BytesCopied
+= BytesToCopy
;
149 DstData
= (PUCHAR
)((ULONG_PTR
) DstData
+ BytesToCopy
);
151 Length
-= BytesToCopy
;
155 SrcSize
-= BytesToCopy
;
157 /* No more bytes in source buffer. Proceed to
158 the next buffer in the source buffer chain */
159 NdisGetNextBuffer(SrcBuffer
, &SrcBuffer
);
163 NdisQueryBuffer(SrcBuffer
, (PVOID
)&SrcData
, &SrcSize
);
171 UINT
CopyPacketToBuffer(
173 PNDIS_PACKET SrcPacket
,
177 * FUNCTION: Copies data from an NDIS packet to a buffer
179 * DstData = Pointer to destination buffer
180 * SrcPacket = Pointer to source NDIS packet
181 * SrcOffset = Source start offset
182 * Length = Number of bytes to copy
184 * Number of bytes copied to destination buffer
186 * The number of bytes copied may be limited by the source
190 PNDIS_BUFFER FirstBuffer
;
195 NDIS_DbgPrint(MAX_TRACE
, ("DstData (0x%X) SrcPacket (0x%X) SrcOffset (0x%X) Length (%d)\n", DstData
, SrcPacket
, SrcOffset
, Length
));
197 NdisGetFirstBufferFromPacket(SrcPacket
,
203 return CopyBufferChainToBuffer(DstData
, FirstBuffer
, SrcOffset
, Length
);
207 UINT
CopyPacketToBufferChain(
208 PNDIS_BUFFER DstBuffer
,
210 PNDIS_PACKET SrcPacket
,
214 * FUNCTION: Copies data from an NDIS packet to an NDIS buffer chain
216 * DstBuffer = Pointer to destination NDIS buffer
217 * DstOffset = Destination start offset
218 * SrcPacket = Pointer to source NDIS packet
219 * SrcOffset = Source start offset
220 * Length = Number of bytes to copy
222 * Number of bytes copied to destination buffer
224 * The number of bytes copied may be limited by the source and
225 * destination buffer sizes
228 PNDIS_BUFFER SrcBuffer
;
229 PUCHAR DstData
, SrcData
;
230 UINT DstSize
, SrcSize
;
233 NDIS_DbgPrint(MAX_TRACE
, ("DstBuffer (0x%X) DstOffset (0x%X) SrcPacket (0x%X) SrcOffset (0x%X) Length (%d)\n", DstBuffer
, DstOffset
, SrcPacket
, SrcOffset
, Length
));
235 /* Skip DstOffset bytes in the destination buffer chain */
236 NdisQueryBuffer(DstBuffer
, (PVOID
)&DstData
, &DstSize
);
237 if (SkipToOffset(DstBuffer
, DstOffset
, &DstData
, &DstSize
) == 0xFFFFFFFF)
239 /* Skip SrcOffset bytes in the source packet */
240 NdisGetFirstBufferFromPacket(SrcPacket
, &SrcBuffer
, (PVOID
*)&SrcData
, &SrcSize
, &Total
);
241 if (SkipToOffset(SrcBuffer
, SrcOffset
, &SrcData
, &SrcSize
) == 0xFFFFFFFF)
245 /* Find out how many bytes we can copy at one time */
246 if (Length
< SrcSize
)
253 RtlCopyMemory((PVOID
)DstData
, (PVOID
)SrcData
, Count
);
262 /* No more bytes in destination buffer. Proceed to
263 the next buffer in the destination buffer chain */
264 NdisGetNextBuffer(DstBuffer
, &DstBuffer
);
268 NdisQueryBuffer(DstBuffer
, (PVOID
)&DstData
, &DstSize
);
273 /* No more bytes in source buffer. Proceed to
274 the next buffer in the source buffer chain */
275 NdisGetNextBuffer(SrcBuffer
, &SrcBuffer
);
279 NdisQueryBuffer(SrcBuffer
, (PVOID
)&SrcData
, &SrcSize
);
290 #undef NdisAdjustBufferLength
293 NdisAdjustBufferLength(
294 IN PNDIS_BUFFER Buffer
,
297 * FUNCTION: Modifies the length of an NDIS buffer
299 * Buffer = Pointer to NDIS buffer descriptor
300 * Length = New size of buffer
303 Buffer
->ByteCount
= Length
;
310 #undef NDIS_BUFFER_TO_SPAN_PAGES
313 NDIS_BUFFER_TO_SPAN_PAGES(
314 IN PNDIS_BUFFER Buffer
)
316 * FUNCTION: Determines how many physical pages a buffer is made of
318 * Buffer = Pointer to NDIS buffer descriptor
321 if (MmGetMdlByteCount(Buffer
) == 0)
324 return ADDRESS_AND_SIZE_TO_SPAN_PAGES(
325 MmGetMdlVirtualAddress(Buffer
),
326 MmGetMdlByteCount(Buffer
));
336 OUT PNDIS_STATUS Status
,
337 OUT PNDIS_BUFFER
* Buffer
,
338 IN NDIS_HANDLE PoolHandle
,
339 IN PVOID VirtualAddress
,
342 * FUNCTION: Allocates an NDIS buffer descriptor
344 * Status = Address of buffer for status
345 * Buffer = Address of buffer for NDIS buffer descriptor
346 * PoolHandle = Handle returned by NdisAllocateBufferPool
347 * VirtualAddress = Pointer to virtual address of data buffer
348 * Length = Number of bytes in data buffer
351 ASSERT(VirtualAddress
!= NULL
);
354 *Buffer
= IoAllocateMdl(VirtualAddress
, Length
, FALSE
, FALSE
, NULL
);
355 if (*Buffer
!= NULL
) {
356 MmBuildMdlForNonPagedPool(*Buffer
);
357 (*Buffer
)->Next
= NULL
;
358 *Status
= NDIS_STATUS_SUCCESS
;
360 *Status
= NDIS_STATUS_FAILURE
;
370 NdisAllocateBufferPool(
371 OUT PNDIS_STATUS Status
,
372 OUT PNDIS_HANDLE PoolHandle
,
373 IN UINT NumberOfDescriptors
)
375 * FUNCTION: Allocates storage for an NDIS buffer pool
377 * Status = Address of buffer for status
378 * PoolHandle = Address of buffer for pool handle
379 * NumberOfDescriptors = Size of buffer pool in number of descriptors
382 *Status
= NDIS_STATUS_SUCCESS
;
393 OUT PNDIS_STATUS Status
,
394 OUT PNDIS_PACKET
* Packet
,
395 IN NDIS_HANDLE PoolHandle
)
397 * FUNCTION: Allocates an NDIS packet descriptor
399 * Status = Address of buffer for status
400 * Packet = Address of buffer for packet descriptor
401 * PoolHandle = Handle returned by NdisAllocatePacketPool
406 PNDISI_PACKET_POOL Pool
= (PNDISI_PACKET_POOL
)PoolHandle
;
408 NDIS_DbgPrint(MAX_TRACE
, ("Status (0x%X) Packet (0x%X) PoolHandle (0x%X).\n",
409 Status
, Packet
, PoolHandle
));
415 *Status
= NDIS_STATUS_FAILURE
;
419 KeAcquireSpinLock(&Pool
->SpinLock
.SpinLock
, &OldIrql
);
421 if (Pool
->FreeList
) {
422 Temp
= Pool
->FreeList
;
423 Pool
->FreeList
= (PNDIS_PACKET
)Temp
->Private
.Head
;
425 KeReleaseSpinLock(&Pool
->SpinLock
.SpinLock
, OldIrql
);
427 RtlZeroMemory(&Temp
->Private
, sizeof(NDIS_PACKET_PRIVATE
));
428 Temp
->Private
.Pool
= Pool
;
431 *Status
= NDIS_STATUS_SUCCESS
;
433 *Status
= NDIS_STATUS_RESOURCES
;
434 KeReleaseSpinLock(&Pool
->SpinLock
.SpinLock
, OldIrql
);
444 NdisAllocatePacketPool(
445 OUT PNDIS_STATUS Status
,
446 OUT PNDIS_HANDLE PoolHandle
,
447 IN UINT NumberOfDescriptors
,
448 IN UINT ProtocolReservedLength
)
450 * FUNCTION: Allocates storage for an NDIS packet pool
452 * Status = Address of buffer for status
453 * PoolHandle = Address of buffer for pool handle
454 * NumberOfDescriptors = Size of packet pool in number of descriptors
455 * ProtocolReservedLength = Size of protocol reserved area in bytes
458 NdisAllocatePacketPoolEx(
463 ProtocolReservedLength
);
472 NdisAllocatePacketPoolEx(
473 OUT PNDIS_STATUS Status
,
474 OUT PNDIS_HANDLE PoolHandle
,
475 IN UINT NumberOfDescriptors
,
476 IN UINT NumberOfOverflowDescriptors
,
477 IN UINT ProtocolReservedLength
)
485 PNDISI_PACKET_POOL Pool
;
486 UINT Size
, Length
, i
;
487 PNDIS_PACKET Packet
, NextPacket
;
489 NDIS_DbgPrint(MAX_TRACE
, ("Status (0x%X) PoolHandle (0x%X) "
490 "NumberOfDescriptors (%d) ProtocolReservedLength (%d).\n",
491 Status
, PoolHandle
, NumberOfDescriptors
, ProtocolReservedLength
));
495 if (NumberOfDescriptors
> 0xffff)
497 *Status
= NDIS_STATUS_RESOURCES
;
501 NumberOfDescriptors
+= NumberOfOverflowDescriptors
;
502 if (NumberOfDescriptors
> 0xffff)
504 NumberOfDescriptors
= 0xffff;
507 Length
= sizeof(NDIS_PACKET
) + ProtocolReservedLength
;
508 Size
= sizeof(NDISI_PACKET_POOL
) + Length
* NumberOfDescriptors
;
510 Pool
= ExAllocatePool(NonPagedPool
, Size
);
513 KeInitializeSpinLock(&Pool
->SpinLock
.SpinLock
);
514 Pool
->PacketLength
= Length
;
516 if (NumberOfDescriptors
> 0)
518 Packet
= (PNDIS_PACKET
)&Pool
->Buffer
;
519 Pool
->FreeList
= Packet
;
521 NextPacket
= (PNDIS_PACKET
)((ULONG_PTR
)Packet
+ Length
);
522 for (i
= 1; i
< NumberOfDescriptors
; i
++)
524 Packet
->Private
.Head
= (PNDIS_BUFFER
)NextPacket
;
526 NextPacket
= (PNDIS_PACKET
)((ULONG_PTR
)Packet
+ Length
);
528 Packet
->Private
.Head
= NULL
;
531 Pool
->FreeList
= NULL
;
533 *Status
= NDIS_STATUS_SUCCESS
;
534 *PoolHandle
= (PNDIS_HANDLE
)Pool
;
536 *Status
= NDIS_STATUS_RESOURCES
;
545 #undef NdisBufferLength
549 IN PNDIS_BUFFER Buffer
)
551 * FUNCTION: Modifies the length of an NDIS buffer
553 * Buffer = Pointer to NDIS buffer descriptor
554 * Length = New size of buffer
558 * Length of NDIS buffer
561 return MmGetMdlByteCount(Buffer
);
568 #undef NdisBufferVirtualAddress
571 NdisBufferVirtualAddress(
572 IN PNDIS_BUFFER Buffer
)
580 return MmGetSystemAddressForMdl(Buffer
);
590 OUT PNDIS_STATUS Status
,
591 OUT PNDIS_BUFFER
*Buffer
,
592 IN NDIS_HANDLE PoolHandle
,
593 IN PVOID MemoryDescriptor
,
597 * FUNCTION: Returns a new buffer descriptor for a (partial) buffer
599 * Status = Address of a buffer to place status of operation
600 * Buffer = Address of a buffer to place new buffer descriptor
601 * PoolHandle = Handle returned by NdisAllocateBufferPool
602 * MemoryDescriptor = Pointer to a memory descriptor (possibly NDIS_BUFFER)
603 * Offset = Offset in buffer to start copying
604 * Length = Number of bytes to copy
607 *Status
= NDIS_STATUS_FAILURE
;
616 NdisCopyFromPacketToPacket(
617 IN PNDIS_PACKET Destination
,
618 IN UINT DestinationOffset
,
620 IN PNDIS_PACKET Source
,
621 IN UINT SourceOffset
,
622 OUT PUINT BytesCopied
)
624 * FUNCTION: Copies data from one packet to another
626 * Destination = Pointer to packet to copy data to
627 * DestinationOffset = Offset in destination packet to copy data to
628 * BytesToCopy = Number of bytes to copy
629 * Source = Pointer to packet descriptor to copy from
630 * SourceOffset = Offset in source packet to start copying from
631 * BytesCopied = Address of buffer to place number of bytes copied
634 PNDIS_BUFFER SrcBuffer
;
635 PNDIS_BUFFER DstBuffer
;
636 PUCHAR DstData
, SrcData
;
637 UINT DstSize
, SrcSize
;
642 /* Skip DestinationOffset bytes in the destination packet */
643 NdisGetFirstBufferFromPacket(Destination
, &DstBuffer
, (PVOID
*)&DstData
, &DstSize
, &Total
);
644 if (SkipToOffset(DstBuffer
, DestinationOffset
, &DstData
, &DstSize
) == 0xFFFFFFFF)
647 /* Skip SourceOffset bytes in the source packet */
648 NdisGetFirstBufferFromPacket(Source
, &SrcBuffer
, (PVOID
*)&SrcData
, &SrcSize
, &Total
);
649 if (SkipToOffset(SrcBuffer
, SourceOffset
, &SrcData
, &SrcSize
) == 0xFFFFFFFF)
654 /* Find out how many bytes we can copy at one time */
655 if (BytesToCopy
< SrcSize
)
662 RtlCopyMemory(DstData
, SrcData
, Count
);
665 BytesToCopy
-= Count
;
666 if (BytesToCopy
== 0)
671 /* No more bytes in destination buffer. Proceed to
672 the next buffer in the destination buffer chain */
673 NdisGetNextBuffer(DstBuffer
, &DstBuffer
);
677 NdisQueryBuffer(DstBuffer
, (PVOID
)&DstData
, &DstSize
);
682 /* No more bytes in source buffer. Proceed to
683 the next buffer in the source buffer chain */
684 NdisGetNextBuffer(SrcBuffer
, &SrcBuffer
);
688 NdisQueryBuffer(SrcBuffer
, (PVOID
)&SrcData
, &SrcSize
);
692 *BytesCopied
= Total
;
701 NdisDprAllocatePacket(
702 OUT PNDIS_STATUS Status
,
703 OUT PNDIS_PACKET
*Packet
,
704 IN NDIS_HANDLE PoolHandle
)
706 * FUNCTION: Allocates a packet at IRQL DISPATCH_LEVEL
708 * Status = Address of buffer to place status of operation
709 * Packet = Address of buffer to place a pointer to a packet descriptor
710 * PoolHandle = Handle returned by NdisAllocatePacketPool
714 PNDISI_PACKET_POOL Pool
= (PNDISI_PACKET_POOL
)PoolHandle
;
716 NDIS_DbgPrint(MAX_TRACE
, ("Status (0x%X) Packet (0x%X) PoolHandle (0x%X).\n",
717 Status
, Packet
, PoolHandle
));
723 *Status
= NDIS_STATUS_FAILURE
;
727 KeAcquireSpinLockAtDpcLevel(&Pool
->SpinLock
.SpinLock
);
729 if (Pool
->FreeList
) {
730 Temp
= Pool
->FreeList
;
731 Pool
->FreeList
= (PNDIS_PACKET
)Temp
->Private
.Head
;
733 KeReleaseSpinLockFromDpcLevel(&Pool
->SpinLock
.SpinLock
);
735 RtlZeroMemory(&Temp
->Private
, sizeof(NDIS_PACKET_PRIVATE
));
736 Temp
->Private
.Pool
= Pool
;
739 *Status
= NDIS_STATUS_SUCCESS
;
741 *Status
= NDIS_STATUS_RESOURCES
;
742 KeReleaseSpinLockFromDpcLevel(&Pool
->SpinLock
.SpinLock
);
752 NdisDprAllocatePacketNonInterlocked(
753 OUT PNDIS_STATUS Status
,
754 OUT PNDIS_PACKET
*Packet
,
755 IN NDIS_HANDLE PoolHandle
)
757 * FUNCTION: Allocates a packet at IRQL DISPATCH_LEVEL (w/o synchronization)
759 * Status = Address of buffer to place status of operation
760 * Packet = Address of buffer to place a pointer to a packet descriptor
761 * PoolHandle = Handle returned by NdisAllocatePacketPool
765 PNDISI_PACKET_POOL Pool
= (PNDISI_PACKET_POOL
)PoolHandle
;
767 NDIS_DbgPrint(MAX_TRACE
, ("Status (0x%X) Packet (0x%X) PoolHandle (0x%X).\n",
768 Status
, Packet
, PoolHandle
));
774 *Status
= NDIS_STATUS_FAILURE
;
778 if (Pool
->FreeList
) {
779 Temp
= Pool
->FreeList
;
780 Pool
->FreeList
= (PNDIS_PACKET
)Temp
->Private
.Head
;
782 RtlZeroMemory(&Temp
->Private
, sizeof(NDIS_PACKET_PRIVATE
));
783 Temp
->Private
.Pool
= Pool
;
786 *Status
= NDIS_STATUS_SUCCESS
;
788 *Status
= NDIS_STATUS_RESOURCES
;
799 IN PNDIS_PACKET Packet
)
801 * FUNCTION: Frees a packet at IRQL DISPATCH_LEVEL
803 * Packet = Pointer to packet to free
806 NDIS_DbgPrint(MAX_TRACE
, ("Packet (0x%X).\n", Packet
));
808 KeAcquireSpinLockAtDpcLevel(&((NDISI_PACKET_POOL
*)Packet
->Private
.Pool
)->SpinLock
.SpinLock
);
809 Packet
->Private
.Head
= (PNDIS_BUFFER
)((NDISI_PACKET_POOL
*)Packet
->Private
.Pool
)->FreeList
;
810 ((NDISI_PACKET_POOL
*)Packet
->Private
.Pool
)->FreeList
= Packet
;
811 KeReleaseSpinLockFromDpcLevel(&((NDISI_PACKET_POOL
*)Packet
->Private
.Pool
)->SpinLock
.SpinLock
);
820 NdisDprFreePacketNonInterlocked(
821 IN PNDIS_PACKET Packet
)
823 * FUNCTION: Frees a packet at IRQL DISPATCH_LEVEL (w/o synchronization)
825 * Packet = Pointer to packet to free
828 NDIS_DbgPrint(MAX_TRACE
, ("Packet (0x%X).\n", Packet
));
830 Packet
->Private
.Head
= (PNDIS_BUFFER
)((NDISI_PACKET_POOL
*)Packet
->Private
.Pool
)->FreeList
;
831 ((NDISI_PACKET_POOL
*)Packet
->Private
.Pool
)->FreeList
= Packet
;
841 IN NDIS_HANDLE PoolHandle
)
843 * FUNCTION: Frees storage allocated for an NDIS buffer pool
845 * PoolHandle = Handle returned by NdisAllocateBufferPool
857 IN NDIS_HANDLE PoolHandle
)
859 * FUNCTION: Frees storage allocated for an NDIS packet pool
861 * PoolHandle = Handle returned by NdisAllocatePacketPool
864 ExFreePool((PVOID
)PoolHandle
);
871 #undef NdisFreeBuffer
875 IN PNDIS_BUFFER Buffer
)
877 * FUNCTION: Puts an NDIS buffer descriptor back in it's pool
879 * Buffer = Pointer to buffer descriptor
892 IN PNDIS_PACKET Packet
)
894 * FUNCTION: Puts an NDIS packet descriptor back in it's pool
896 * Packet = Pointer to packet descriptor
901 NDIS_DbgPrint(MAX_TRACE
, ("Packet (0x%X).\n", Packet
));
903 KeAcquireSpinLock(&((NDISI_PACKET_POOL
*)Packet
->Private
.Pool
)->SpinLock
.SpinLock
, &OldIrql
);
904 Packet
->Private
.Head
= (PNDIS_BUFFER
)((NDISI_PACKET_POOL
*)Packet
->Private
.Pool
)->FreeList
;
905 ((NDISI_PACKET_POOL
*)Packet
->Private
.Pool
)->FreeList
= Packet
;
906 KeReleaseSpinLock(&((NDISI_PACKET_POOL
*)Packet
->Private
.Pool
)->SpinLock
.SpinLock
, OldIrql
);
913 #undef NdisGetBufferPhysicalArraySize
916 NdisGetBufferPhysicalArraySize(
917 IN PNDIS_BUFFER Buffer
,
920 * FUNCTION: Returns number of discontiguous physical blocks backing a buffer
922 * Buffer = Pointer to buffer descriptor
923 * ArraySize = Address of buffer to place number of physical blocks
926 ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL
);
927 ASSERT(Buffer
&& ArraySize
);
929 *ArraySize
= NDIS_BUFFER_TO_SPAN_PAGES(Buffer
);
936 #undef NdisGetFirstBufferFromPacket
939 NdisGetFirstBufferFromPacket(
940 IN PNDIS_PACKET _Packet
,
941 OUT PNDIS_BUFFER
*_FirstBuffer
,
942 OUT PVOID
*_FirstBufferVA
,
943 OUT PUINT _FirstBufferLength
,
944 OUT PUINT _TotalBufferLength
)
946 * FUNCTION: Retrieves information about an NDIS packet
948 * _Packet = Pointer to NDIS packet
949 * _FirstBuffer = Address of buffer for pointer to first NDIS buffer
950 * _FirstBufferVA = Address of buffer for address of first NDIS buffer
951 * _FirstBufferLength = Address of buffer for length of first buffer
952 * _TotalBufferLength = Address of buffer for total length of packet
957 Buffer
= _Packet
->Private
.Head
;
958 *_FirstBuffer
= Buffer
;
960 if (Buffer
!= NULL
) {
961 *_FirstBufferLength
= MmGetMdlByteCount(Buffer
);
962 *_FirstBufferVA
= MmGetSystemAddressForMdl(Buffer
);
963 Buffer
= Buffer
->Next
;
965 *_FirstBufferLength
= 0;
966 *_FirstBufferVA
= NULL
;
969 *_TotalBufferLength
= *_FirstBufferLength
;
971 while (Buffer
!= NULL
) {
972 *_TotalBufferLength
+= MmGetMdlByteCount(Buffer
);
973 Buffer
= Buffer
->Next
;
984 IN PNDIS_PACKET
*PacketsToReturn
,
985 IN UINT NumberOfPackets
)
987 * FUNCTION: Releases ownership of one or more packets
989 * PacketsToReturn = Pointer to an array of pointers to packet descriptors
990 * NumberOfPackets = Number of pointers in descriptor pointer array
1002 NdisPacketPoolUsage(
1003 IN NDIS_HANDLE PoolHandle
)
1020 #undef NdisQueryBuffer
1024 IN PNDIS_BUFFER Buffer
,
1025 OUT PVOID
*VirtualAddress OPTIONAL
,
1029 * Queries an NDIS buffer for information
1031 * Buffer = Pointer to NDIS buffer to query
1032 * VirtualAddress = Address of buffer to place virtual address
1033 * Length = Address of buffer to place length of buffer
1036 if (VirtualAddress
!= NULL
)
1037 *(PVOID
*)VirtualAddress
= MmGetSystemAddressForMdl(Buffer
);
1039 *Length
= MmGetMdlByteCount(Buffer
);
1046 #undef NdisQueryBufferSafe
1049 NdisQueryBufferSafe(
1050 IN PNDIS_BUFFER Buffer
,
1051 OUT PVOID
*VirtualAddress OPTIONAL
,
1061 if (VirtualAddress
!= NULL
)
1062 *VirtualAddress
= MmGetSystemAddressForMdlSafe(Buffer
, Priority
);
1063 *Length
= MmGetMdlByteCount(Buffer
);
1070 #undef NdisQueryBufferOffset
1073 NdisQueryBufferOffset(
1074 IN PNDIS_BUFFER Buffer
,
1078 *((PUINT
)Offset
) = MmGetMdlByteOffset(Buffer
);
1079 *((PUINT
)Length
) = MmGetMdlByteCount(Buffer
);
1088 NdisUnchainBufferAtBack(
1089 IN OUT PNDIS_PACKET Packet
,
1090 OUT PNDIS_BUFFER
*Buffer
)
1093 * Removes the last buffer in a packet
1095 * Packet = Pointer to NDIS packet
1096 * Buffer = Address of buffer to place pointer to removed NDIS buffer
1099 PNDIS_BUFFER NdisBuffer
, Previous
;
1101 NdisQueryPacket(Packet
,
1112 while (NdisBuffer
->Next
) {
1113 Previous
= NdisBuffer
;
1114 NdisBuffer
= NdisBuffer
->Next
;
1118 Previous
->Next
= NULL
;
1119 Packet
->Private
.Tail
= Previous
;
1121 Packet
->Private
.Head
= NULL
;
1122 Packet
->Private
.Tail
= NULL
;
1125 Packet
->Private
.ValidCounts
= FALSE
;
1127 *Buffer
= NdisBuffer
;
1136 NdisUnchainBufferAtFront(
1137 IN OUT PNDIS_PACKET Packet
,
1138 OUT PNDIS_BUFFER
*Buffer
)
1141 * Removes the first buffer in a packet
1143 * Packet = Pointer to NDIS packet
1144 * Buffer = Address of buffer to place pointer to removed NDIS buffer
1147 PNDIS_BUFFER NdisBuffer
;
1149 NdisQueryPacket(Packet
,
1159 Packet
->Private
.Head
= NdisBuffer
->Next
;
1161 if (!NdisBuffer
->Next
)
1162 Packet
->Private
.Tail
= NULL
;
1164 NdisBuffer
->Next
= NULL
;
1166 Packet
->Private
.ValidCounts
= FALSE
;
1168 *Buffer
= NdisBuffer
;