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(
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 ((ULONG_PTR
)*Data
) += Offset
;
49 NdisGetNextBuffer(Buffer
, &Buffer
);
56 UINT
CopyBufferToBufferChain(
57 PNDIS_BUFFER DstBuffer
,
62 * FUNCTION: Copies data from a buffer to an NDIS buffer chain
64 * DstBuffer = Pointer to destination NDIS buffer
65 * DstOffset = Destination start offset
66 * SrcData = Pointer to source buffer
67 * Length = Number of bytes to copy
69 * Number of bytes copied to destination buffer
71 * The number of bytes copied may be limited by the destination
75 UINT BytesCopied
, BytesToCopy
, DstSize
;
78 NDIS_DbgPrint(MAX_TRACE
, ("DstBuffer (0x%X) DstOffset (0x%X) SrcData (0x%X) Length (%d)\n", DstBuffer
, DstOffset
, SrcData
, Length
));
80 /* Skip DstOffset bytes in the destination buffer chain */
81 if (SkipToOffset(DstBuffer
, DstOffset
, &DstData
, &DstSize
) == -1)
84 /* Start copying the data */
87 BytesToCopy
= MIN(DstSize
, Length
);
89 RtlCopyMemory((PVOID
)DstData
, (PVOID
)SrcData
, BytesToCopy
);
90 BytesCopied
+= BytesToCopy
;
91 (ULONG_PTR
)SrcData
+= BytesToCopy
;
93 Length
-= BytesToCopy
;
97 DstSize
-= BytesToCopy
;
99 /* No more bytes in desination buffer. Proceed to
100 the next buffer in the destination buffer chain */
101 NdisGetNextBuffer(DstBuffer
, &DstBuffer
);
105 NdisQueryBuffer(DstBuffer
, (PVOID
)&DstData
, &DstSize
);
113 UINT
CopyBufferChainToBuffer(
115 PNDIS_BUFFER SrcBuffer
,
119 * FUNCTION: Copies data from an NDIS buffer chain to a buffer
121 * DstData = Pointer to destination buffer
122 * SrcBuffer = Pointer to source NDIS buffer
123 * SrcOffset = Source start offset
124 * Length = Number of bytes to copy
126 * Number of bytes copied to destination buffer
128 * The number of bytes copied may be limited by the source
132 UINT BytesCopied
, BytesToCopy
, SrcSize
;
135 NDIS_DbgPrint(MAX_TRACE
, ("DstData 0x%X SrcBuffer 0x%X SrcOffset 0x%X Length %d\n",DstData
,SrcBuffer
, SrcOffset
, Length
));
137 /* Skip SrcOffset bytes in the source buffer chain */
138 if (SkipToOffset(SrcBuffer
, SrcOffset
, &SrcData
, &SrcSize
) == -1)
141 /* Start copying the data */
144 BytesToCopy
= MIN(SrcSize
, Length
);
146 NDIS_DbgPrint(MAX_TRACE
, ("Copying (%d) bytes from 0x%X to 0x%X\n", BytesToCopy
, SrcData
, DstData
));
148 RtlCopyMemory((PVOID
)DstData
, (PVOID
)SrcData
, BytesToCopy
);
149 BytesCopied
+= BytesToCopy
;
150 (ULONG_PTR
)DstData
+= BytesToCopy
;
152 Length
-= BytesToCopy
;
156 SrcSize
-= BytesToCopy
;
158 /* No more bytes in source buffer. Proceed to
159 the next buffer in the source buffer chain */
160 NdisGetNextBuffer(SrcBuffer
, &SrcBuffer
);
164 NdisQueryBuffer(SrcBuffer
, (PVOID
)&SrcData
, &SrcSize
);
172 UINT
CopyPacketToBuffer(
174 PNDIS_PACKET SrcPacket
,
178 * FUNCTION: Copies data from an NDIS packet to a buffer
180 * DstData = Pointer to destination buffer
181 * SrcPacket = Pointer to source NDIS packet
182 * SrcOffset = Source start offset
183 * Length = Number of bytes to copy
185 * Number of bytes copied to destination buffer
187 * The number of bytes copied may be limited by the source
191 PNDIS_BUFFER FirstBuffer
;
196 NDIS_DbgPrint(MAX_TRACE
, ("DstData (0x%X) SrcPacket (0x%X) SrcOffset (0x%X) Length (%d)\n", DstData
, SrcPacket
, SrcOffset
, Length
));
198 NdisGetFirstBufferFromPacket(SrcPacket
,
204 return CopyBufferChainToBuffer(DstData
, FirstBuffer
, SrcOffset
, Length
);
208 UINT
CopyPacketToBufferChain(
209 PNDIS_BUFFER DstBuffer
,
211 PNDIS_PACKET SrcPacket
,
215 * FUNCTION: Copies data from an NDIS packet to an NDIS buffer chain
217 * DstBuffer = Pointer to destination NDIS buffer
218 * DstOffset = Destination start offset
219 * SrcPacket = Pointer to source NDIS packet
220 * SrcOffset = Source start offset
221 * Length = Number of bytes to copy
223 * Number of bytes copied to destination buffer
225 * The number of bytes copied may be limited by the source and
226 * destination buffer sizes
229 PNDIS_BUFFER SrcBuffer
;
230 PUCHAR DstData
, SrcData
;
231 UINT DstSize
, SrcSize
;
234 NDIS_DbgPrint(MAX_TRACE
, ("DstBuffer (0x%X) DstOffset (0x%X) SrcPacket (0x%X) SrcOffset (0x%X) Length (%d)\n", DstBuffer
, DstOffset
, SrcPacket
, SrcOffset
, Length
));
236 /* Skip DstOffset bytes in the destination buffer chain */
237 NdisQueryBuffer(DstBuffer
, (PVOID
)&DstData
, &DstSize
);
238 if (SkipToOffset(DstBuffer
, DstOffset
, &DstData
, &DstSize
) == -1)
240 /* Skip SrcOffset bytes in the source packet */
241 NdisGetFirstBufferFromPacket(SrcPacket
, &SrcBuffer
, (PVOID
)&SrcData
, &SrcSize
, &Total
);
242 if (SkipToOffset(SrcBuffer
, SrcOffset
, &SrcData
, &SrcSize
) == -1)
246 /* Find out how many bytes we can copy at one time */
247 if (Length
< SrcSize
)
254 RtlCopyMemory((PVOID
)DstData
, (PVOID
)SrcData
, Count
);
263 /* No more bytes in destination buffer. Proceed to
264 the next buffer in the destination buffer chain */
265 NdisGetNextBuffer(DstBuffer
, &DstBuffer
);
269 NdisQueryBuffer(DstBuffer
, (PVOID
)&DstData
, &DstSize
);
274 /* No more bytes in source buffer. Proceed to
275 the next buffer in the source buffer chain */
276 NdisGetNextBuffer(SrcBuffer
, &SrcBuffer
);
280 NdisQueryBuffer(SrcBuffer
, (PVOID
)&SrcData
, &SrcSize
);
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
;
312 NDIS_BUFFER_TO_SPAN_PAGES(
313 IN PNDIS_BUFFER Buffer
)
315 * FUNCTION: Determines how many physical pages a buffer is made of
317 * Buffer = Pointer to NDIS buffer descriptor
320 if (MmGetMdlByteCount(Buffer
) == 0)
323 return ADDRESS_AND_SIZE_TO_SPAN_PAGES(
324 MmGetMdlVirtualAddress(Buffer
),
325 MmGetMdlByteCount(Buffer
));
335 OUT PNDIS_STATUS Status
,
336 OUT PNDIS_BUFFER
* Buffer
,
337 IN NDIS_HANDLE PoolHandle
,
338 IN PVOID VirtualAddress
,
341 * FUNCTION: Allocates an NDIS buffer descriptor
343 * Status = Address of buffer for status
344 * Buffer = Address of buffer for NDIS buffer descriptor
345 * PoolHandle = Handle returned by NdisAllocateBufferPool
346 * VirtualAddress = Pointer to virtual address of data buffer
347 * Length = Number of bytes in data buffer
351 PNETWORK_HEADER Temp
;
352 PNDIS_BUFFER_POOL Pool
= (PNDIS_BUFFER_POOL
)PoolHandle
;
354 NDIS_DbgPrint(MAX_TRACE
, ("Status (0x%X) Buffer (0x%X) PoolHandle (0x%X) "
355 "VirtualAddress (0x%X) Length (%d)\n",
356 Status
, Buffer
, PoolHandle
, VirtualAddress
, Length
));
358 KeAcquireSpinLock(&Pool
->SpinLock
, &OldIrql
);
360 if (Pool
->FreeList
) {
361 Temp
= Pool
->FreeList
;
362 Pool
->FreeList
= Temp
->Next
;
364 KeReleaseSpinLock(&Pool
->SpinLock
, OldIrql
);
369 MmInitializeMdl(&Temp
->Mdl
, VirtualAddress
, Length
);
370 Temp
->Mdl
.MdlFlags
|= (MDL_SOURCE_IS_NONPAGED_POOL
| MDL_ALLOCATED_FIXED_SIZE
);
371 Temp
->Mdl
.MappedSystemVa
= VirtualAddress
;
373 Temp
->Mdl
.Next
= (PMDL
)NULL
;
374 Temp
->Mdl
.Size
= (CSHORT
)(sizeof(MDL
) +
375 (ADDRESS_AND_SIZE_TO_SPAN_PAGES(VirtualAddress
, Length
) * sizeof(ULONG
)));
376 Temp
->Mdl
.MdlFlags
= (MDL_SOURCE_IS_NONPAGED_POOL
| MDL_ALLOCATED_FIXED_SIZE
);
377 ; Temp
->Mdl
.StartVa
= (PVOID
)PAGE_ROUND_DOWN(VirtualAddress
);
378 Temp
->Mdl
.ByteOffset
= (ULONG_PTR
)(VirtualAddress
- PAGE_ROUND_DOWN(VirtualAddress
));
379 Temp
->Mdl
.ByteCount
= Length
;
380 Temp
->Mdl
.MappedSystemVa
= VirtualAddress
;
382 //Temp->Mdl.Process = PsGetCurrentProcess();
384 Temp
->Mdl
.Process
= NULL
;
388 Temp
->BufferPool
= Pool
;
390 *Buffer
= (PNDIS_BUFFER
)Temp
;
391 *Status
= NDIS_STATUS_SUCCESS
;
393 KeReleaseSpinLock(&Pool
->SpinLock
, OldIrql
);
394 *Status
= NDIS_STATUS_FAILURE
;
404 NdisAllocateBufferPool(
405 OUT PNDIS_STATUS Status
,
406 OUT PNDIS_HANDLE PoolHandle
,
407 IN UINT NumberOfDescriptors
)
409 * FUNCTION: Allocates storage for an NDIS buffer pool
411 * Status = Address of buffer for status
412 * PoolHandle = Address of buffer for pool handle
413 * NumberOfDescriptors = Size of buffer pool in number of descriptors
417 PNDIS_BUFFER_POOL Pool
;
418 PNETWORK_HEADER Buffer
;
420 NDIS_DbgPrint(MAX_TRACE
, ("Status (0x%X) PoolHandle (0x%X) NumberOfDescriptors (%d).\n",
421 Status
, PoolHandle
, NumberOfDescriptors
));
423 Pool
= ExAllocatePool(NonPagedPool
,
424 sizeof(NDIS_BUFFER_POOL
) +
425 sizeof(NETWORK_HEADER
) *
426 NumberOfDescriptors
);
428 KeInitializeSpinLock(&Pool
->SpinLock
);
430 if (NumberOfDescriptors
> 0) {
431 Buffer
= &Pool
->Buffers
[0];
432 Pool
->FreeList
= Buffer
;
433 for (i
= 1; i
< NumberOfDescriptors
; i
++) {
434 Buffer
->Next
= &Pool
->Buffers
[i
];
435 Buffer
= Buffer
->Next
;
439 Pool
->FreeList
= NULL
;
441 *Status
= NDIS_STATUS_SUCCESS
;
442 *PoolHandle
= (PNDIS_HANDLE
)Pool
;
444 *Status
= NDIS_STATUS_RESOURCES
;
454 OUT PNDIS_STATUS Status
,
455 OUT PNDIS_PACKET
* Packet
,
456 IN NDIS_HANDLE PoolHandle
)
458 * FUNCTION: Allocates an NDIS packet descriptor
460 * Status = Address of buffer for status
461 * Packet = Address of buffer for packet descriptor
462 * PoolHandle = Handle returned by NdisAllocatePacketPool
467 PNDIS_PACKET_POOL Pool
= (PNDIS_PACKET_POOL
)PoolHandle
;
469 NDIS_DbgPrint(MAX_TRACE
, ("Status (0x%X) Packet (0x%X) PoolHandle (0x%X).\n",
470 Status
, Packet
, PoolHandle
));
472 KeAcquireSpinLock(&Pool
->SpinLock
.SpinLock
, &OldIrql
);
474 if (Pool
->FreeList
) {
475 Temp
= Pool
->FreeList
;
476 Pool
->FreeList
= (PNDIS_PACKET
)Temp
->Private
.Head
;
478 KeReleaseSpinLock(&Pool
->SpinLock
.SpinLock
, OldIrql
);
480 RtlZeroMemory(&Temp
->Private
, sizeof(NDIS_PACKET_PRIVATE
));
481 Temp
->Private
.Pool
= Pool
;
484 *Status
= NDIS_STATUS_SUCCESS
;
486 *Status
= NDIS_STATUS_RESOURCES
;
487 KeReleaseSpinLock(&Pool
->SpinLock
.SpinLock
, OldIrql
);
497 NdisAllocatePacketPool(
498 OUT PNDIS_STATUS Status
,
499 OUT PNDIS_HANDLE PoolHandle
,
500 IN UINT NumberOfDescriptors
,
501 IN UINT ProtocolReservedLength
)
503 * FUNCTION: Allocates storage for an NDIS packet pool
505 * Status = Address of buffer for status
506 * PoolHandle = Address of buffer for pool handle
507 * NumberOfDescriptors = Size of packet pool in number of descriptors
508 * ProtocolReservedLength = Size of protocol reserved area in bytes
511 PNDIS_PACKET_POOL Pool
;
512 UINT Size
, Length
, i
;
513 PNDIS_PACKET Packet
, NextPacket
;
515 NDIS_DbgPrint(MAX_TRACE
, ("Status (0x%X) PoolHandle (0x%X) "
516 "NumberOfDescriptors (%d) ProtocolReservedLength (%d).\n",
517 Status
, PoolHandle
, NumberOfDescriptors
, ProtocolReservedLength
));
519 Length
= sizeof(NDIS_PACKET
) + ProtocolReservedLength
;
520 Size
= sizeof(NDIS_PACKET_POOL
) + Length
* NumberOfDescriptors
;
522 Pool
= ExAllocatePool(NonPagedPool
, Size
);
524 KeInitializeSpinLock(&Pool
->SpinLock
.SpinLock
);
525 Pool
->PacketLength
= Length
;
527 if (NumberOfDescriptors
> 0) {
528 Packet
= (PNDIS_PACKET
)&Pool
->Buffer
;
529 Pool
->FreeList
= Packet
;
531 NextPacket
= (PNDIS_PACKET
)((ULONG_PTR
)Packet
+ Length
);
532 for (i
= 1; i
< NumberOfDescriptors
; i
++) {
533 Packet
->Private
.Head
= (PNDIS_BUFFER
)NextPacket
;
535 NextPacket
= (PNDIS_PACKET
)((ULONG_PTR
)Packet
+ Length
);
537 Packet
->Private
.Head
= NULL
;
539 Pool
->FreeList
= NULL
;
541 *Status
= NDIS_STATUS_SUCCESS
;
542 *PoolHandle
= (PNDIS_HANDLE
)Pool
;
544 *Status
= NDIS_STATUS_RESOURCES
;
553 NdisAllocatePacketPoolEx(
554 OUT PNDIS_STATUS Status
,
555 OUT PNDIS_HANDLE PoolHandle
,
556 IN UINT NumberOfDescriptors
,
557 IN UINT NumberOfOverflowDescriptors
,
558 IN UINT ProtocolReservedLength
)
576 IN PNDIS_BUFFER Buffer
)
578 * FUNCTION: Modifies the length of an NDIS buffer
580 * Buffer = Pointer to NDIS buffer descriptor
581 * Length = New size of buffer
585 * Length of NDIS buffer
588 return Buffer
->ByteCount
;
597 NdisBufferVirtualAddress(
598 IN PNDIS_BUFFER Buffer
)
618 OUT PNDIS_STATUS Status
,
619 OUT PNDIS_BUFFER
*Buffer
,
620 IN NDIS_HANDLE PoolHandle
,
621 IN PVOID MemoryDescriptor
,
625 * FUNCTION: Returns a new buffer descriptor for a (partial) buffer
627 * Status = Address of a buffer to place status of operation
628 * Buffer = Address of a buffer to place new buffer descriptor
629 * PoolHandle = Handle returned by NdisAllocateBufferPool
630 * MemoryDescriptor = Pointer to a memory descriptor (possibly NDIS_BUFFER)
631 * Offset = Offset in buffer to start copying
632 * Length = Number of bytes to copy
635 *Status
= NDIS_STATUS_FAILURE
;
644 NdisCopyFromPacketToPacket(
645 IN PNDIS_PACKET Destination
,
646 IN UINT DestinationOffset
,
648 IN PNDIS_PACKET Source
,
649 IN UINT SourceOffset
,
650 OUT PUINT BytesCopied
)
652 * FUNCTION: Copies data from one packet to another
654 * Destination = Pointer to packet to copy data to
655 * DestinationOffset = Offset in destination packet to copy data to
656 * BytesToCopy = Number of bytes to copy
657 * Source = Pointer to packet descriptor to copy from
658 * SourceOffset = Offset in source packet to start copying from
659 * BytesCopied = Address of buffer to place number of bytes copied
662 PNDIS_BUFFER SrcBuffer
;
663 PNDIS_BUFFER DstBuffer
;
664 PUCHAR DstData
, SrcData
;
665 UINT DstSize
, SrcSize
;
670 /* Skip DestinationOffset bytes in the destination packet */
671 NdisGetFirstBufferFromPacket(Destination
, &DstBuffer
, (PVOID
)&DstData
, &DstSize
, &Total
);
672 if (SkipToOffset(DstBuffer
, DestinationOffset
, &DstData
, &DstSize
) == -1)
675 /* Skip SourceOffset bytes in the source packet */
676 NdisGetFirstBufferFromPacket(Source
, &SrcBuffer
, (PVOID
)&SrcData
, &SrcSize
, &Total
);
677 if (SkipToOffset(SrcBuffer
, SourceOffset
, &SrcData
, &SrcSize
) == -1)
682 /* Find out how many bytes we can copy at one time */
683 if (BytesToCopy
< SrcSize
)
690 RtlCopyMemory(DstData
, SrcData
, Count
);
693 BytesToCopy
-= Count
;
694 if (BytesToCopy
== 0)
699 /* No more bytes in destination buffer. Proceed to
700 the next buffer in the destination buffer chain */
701 NdisGetNextBuffer(DstBuffer
, &DstBuffer
);
705 NdisQueryBuffer(DstBuffer
, (PVOID
)&DstData
, &DstSize
);
710 /* No more bytes in source buffer. Proceed to
711 the next buffer in the source buffer chain */
712 NdisGetNextBuffer(SrcBuffer
, &SrcBuffer
);
716 NdisQueryBuffer(SrcBuffer
, (PVOID
)&SrcData
, &SrcSize
);
720 *BytesCopied
= Total
;
729 NdisDprAllocatePacket(
730 OUT PNDIS_STATUS Status
,
731 OUT PNDIS_PACKET
*Packet
,
732 IN NDIS_HANDLE PoolHandle
)
734 * FUNCTION: Allocates a packet at IRQL DISPATCH_LEVEL
736 * Status = Address of buffer to place status of operation
737 * Packet = Address of buffer to place a pointer to a packet descriptor
738 * PoolHandle = Handle returned by NdisAllocatePacketPool
749 NdisDprAllocatePacketNonInterlocked(
750 OUT PNDIS_STATUS Status
,
751 OUT PNDIS_PACKET
*Packet
,
752 IN NDIS_HANDLE PoolHandle
)
754 * FUNCTION: Allocates a packet at IRQL DISPATCH_LEVEL (w/o synchronization)
756 * Status = Address of buffer to place status of operation
757 * Packet = Address of buffer to place a pointer to a packet descriptor
758 * PoolHandle = Handle returned by NdisAllocatePacketPool
761 *Status
= NDIS_STATUS_FAILURE
;
771 IN PNDIS_PACKET Packet
)
773 * FUNCTION: Frees a packet at IRQL DISPATCH_LEVEL
775 * Packet = Pointer to packet to free
786 NdisDprFreePacketNonInterlocked(
787 IN PNDIS_PACKET Packet
)
789 * FUNCTION: Frees a packet at IRQL DISPATCH_LEVEL (w/o synchronization)
791 * Packet = Pointer to packet to free
803 IN NDIS_HANDLE PoolHandle
)
805 * FUNCTION: Frees storage allocated for an NDIS buffer pool
807 * PoolHandle = Handle returned by NdisAllocateBufferPool
810 ExFreePool((PVOID
)PoolHandle
);
820 IN NDIS_HANDLE PoolHandle
)
822 * FUNCTION: Frees storage allocated for an NDIS packet pool
824 * PoolHandle = Handle returned by NdisAllocatePacketPool
827 ExFreePool((PVOID
)PoolHandle
);
837 IN PNDIS_BUFFER Buffer
)
839 * FUNCTION: Puts an NDIS buffer descriptor back in it's pool
841 * Buffer = Pointer to buffer descriptor
845 PNDIS_BUFFER_POOL Pool
;
846 PNETWORK_HEADER Temp
= (PNETWORK_HEADER
)Buffer
;
848 NDIS_DbgPrint(MAX_TRACE
, ("Buffer (0x%X).\n", Buffer
));
850 Pool
= Temp
->BufferPool
;
852 KeAcquireSpinLock(&Pool
->SpinLock
, &OldIrql
);
853 Buffer
->Next
= (PMDL
)Pool
->FreeList
;
854 Pool
->FreeList
= (PNETWORK_HEADER
)Buffer
;
855 KeReleaseSpinLock(&Pool
->SpinLock
, OldIrql
);
865 IN PNDIS_PACKET Packet
)
867 * FUNCTION: Puts an NDIS packet descriptor back in it's pool
869 * Packet = Pointer to packet descriptor
874 NDIS_DbgPrint(MAX_TRACE
, ("Packet (0x%X).\n", Packet
));
876 KeAcquireSpinLock(&Packet
->Private
.Pool
->SpinLock
.SpinLock
, &OldIrql
);
877 Packet
->Private
.Head
= (PNDIS_BUFFER
)Packet
->Private
.Pool
->FreeList
;
878 Packet
->Private
.Pool
->FreeList
= Packet
;
879 KeReleaseSpinLock(&Packet
->Private
.Pool
->SpinLock
.SpinLock
, OldIrql
);
888 NdisGetBufferPhysicalArraySize(
889 IN PNDIS_BUFFER Buffer
,
892 * FUNCTION: Returns number of discontiguous physical blocks backing a buffer
894 * Buffer = Pointer to buffer descriptor
895 * ArraySize = Address of buffer to place number of physical blocks
898 ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL
);
899 ASSERT(Buffer
&& ArraySize
);
901 *ArraySize
= NDIS_BUFFER_TO_SPAN_PAGES(Buffer
);
910 NdisGetFirstBufferFromPacket(
911 IN PNDIS_PACKET _Packet
,
912 OUT PNDIS_BUFFER
*_FirstBuffer
,
913 OUT PVOID
*_FirstBufferVA
,
914 OUT PUINT _FirstBufferLength
,
915 OUT PUINT _TotalBufferLength
)
917 * FUNCTION: Retrieves information about an NDIS packet
919 * _Packet = Pointer to NDIS packet
920 * _FirstBuffer = Address of buffer for pointer to first NDIS buffer
921 * _FirstBufferVA = Address of buffer for address of first NDIS buffer
922 * _FirstBufferLength = Address of buffer for length of first buffer
923 * _TotalBufferLength = Address of buffer for total length of packet
928 Buffer
= _Packet
->Private
.Head
;
929 *_FirstBuffer
= Buffer
;
930 *_FirstBufferVA
= MmGetMdlVirtualAddress(Buffer
);
932 if (Buffer
!= NULL
) {
933 *_FirstBufferLength
= MmGetMdlByteCount(Buffer
);
934 Buffer
= Buffer
->Next
;
936 *_FirstBufferLength
= 0;
938 *_TotalBufferLength
= *_FirstBufferLength
;
940 while (Buffer
!= NULL
) {
941 *_TotalBufferLength
+= MmGetMdlByteCount(Buffer
);
942 Buffer
= Buffer
->Next
;
953 IN PNDIS_PACKET
*PacketsToReturn
,
954 IN UINT NumberOfPackets
)
956 * FUNCTION: Releases ownership of one or more packets
958 * PacketsToReturn = Pointer to an array of pointers to packet descriptors
959 * NumberOfPackets = Number of pointers in descriptor pointer array
972 IN NDIS_HANDLE PoolHandle
)
992 IN PNDIS_BUFFER Buffer
,
993 OUT PVOID
*VirtualAddress OPTIONAL
,
997 * Queries an NDIS buffer for information
999 * Buffer = Pointer to NDIS buffer to query
1000 * VirtualAddress = Address of buffer to place virtual address
1001 * Length = Address of buffer to place length of buffer
1004 if (VirtualAddress
!= NULL
)
1005 *(PVOID
*)VirtualAddress
= MmGetSystemAddressForMdl(Buffer
);
1007 *Length
= MmGetMdlByteCount(Buffer
);
1016 NdisQueryBufferOffset(
1017 IN PNDIS_BUFFER Buffer
,
1021 *((PUINT
)Offset
) = MmGetMdlByteOffset(Buffer
);
1022 *((PUINT
)Length
) = MmGetMdlByteCount(Buffer
);
1031 NdisUnchainBufferAtBack(
1032 IN OUT PNDIS_PACKET Packet
,
1033 OUT PNDIS_BUFFER
*Buffer
)
1036 * Removes the last buffer in a packet
1038 * Packet = Pointer to NDIS packet
1039 * Buffer = Address of buffer to place pointer to removed NDIS buffer
1042 PNDIS_BUFFER NdisBuffer
, Previous
;
1044 NdisQueryPacket(Packet
,
1055 while (NdisBuffer
->Next
) {
1056 Previous
= NdisBuffer
;
1057 NdisBuffer
= NdisBuffer
->Next
;
1061 Previous
->Next
= NULL
;
1062 Packet
->Private
.Tail
= Previous
;
1064 Packet
->Private
.Head
= NULL
;
1065 Packet
->Private
.Tail
= NULL
;
1068 Packet
->Private
.ValidCounts
= FALSE
;
1070 *Buffer
= NdisBuffer
;
1079 NdisUnchainBufferAtFront(
1080 IN OUT PNDIS_PACKET Packet
,
1081 OUT PNDIS_BUFFER
*Buffer
)
1084 * Removes the first buffer in a packet
1086 * Packet = Pointer to NDIS packet
1087 * Buffer = Address of buffer to place pointer to removed NDIS buffer
1090 PNDIS_BUFFER NdisBuffer
;
1092 NdisQueryPacket(Packet
,
1102 Packet
->Private
.Head
= NdisBuffer
->Next
;
1104 if (!NdisBuffer
->Next
)
1105 Packet
->Private
.Tail
= NULL
;
1107 NdisBuffer
->Next
= NULL
;
1109 Packet
->Private
.ValidCounts
= FALSE
;
1111 *Buffer
= NdisBuffer
;