diff options
Diffstat (limited to '')
-rw-r--r-- | private/ntos/ndis/elnkmc/packet.c | 437 |
1 files changed, 437 insertions, 0 deletions
diff --git a/private/ntos/ndis/elnkmc/packet.c b/private/ntos/ndis/elnkmc/packet.c new file mode 100644 index 000000000..8a2836e38 --- /dev/null +++ b/private/ntos/ndis/elnkmc/packet.c @@ -0,0 +1,437 @@ +/*++ + +Copyright (c) 1992 Microsoft Corporation + +Module Name: + + packet.c + +Abstract: + + This module contains code to copy from ndis packets to ndis packets, + and also to copy from ndis packets to a buffer. + +Author: + + Johnson R. Apacible (JohnsonA) 9-June-1991 + +Environment: + + Works in kernal mode, but is not important that it does. + +Revision History: + + +--*/ + +#include <ndis.h> + +// +// So we can trace things... +// +#define STATIC + +#include <efilter.h> +#include <elnkhw.h> +#include <elnksw.h> + + +VOID +ElnkCopyFromPacketToBuffer( + IN PNDIS_PACKET Packet, + IN UINT Offset, + IN UINT BytesToCopy, + OUT PCHAR Buffer, + OUT PUINT BytesCopied + ) + +/*++ + +Routine Description: + + Copy from an ndis packet into a buffer. + +Arguments: + + Packet - The packet to copy from. + + Offset - The offset from which to start the copy. + + BytesToCopy - The number of bytes to copy from the packet. + + Buffer - The destination of the copy. + + BytesCopied - The number of bytes actually copied. Can be less then + BytesToCopy if the packet is shorter than BytesToCopy. + +Return Value: + + None + +--*/ + +{ + + // + // Holds the number of ndis buffers comprising the packet. + // + UINT NdisBufferCount; + + // + // Points to the buffer from which we are extracting data. + // + PNDIS_BUFFER CurrentBuffer; + + // + // Holds the virtual address of the current buffer. + // + PVOID VirtualAddress; + + // + // Holds the length of the current buffer of the packet. + // + UINT CurrentLength; + + // + // Keep a local variable of BytesCopied so we aren't referencing + // through a pointer. + // + UINT LocalBytesCopied = 0; + + // + // Take care of boundary condition of zero length copy. + // + + *BytesCopied = 0; + if (!BytesToCopy) return; + + // + // Get the first buffer. + // + + NdisQueryPacket( + Packet, + NULL, + &NdisBufferCount, + &CurrentBuffer, + NULL + ); + + // + // Could have a null packet. + // + + if (!NdisBufferCount) { + return; + } + + NdisQueryBuffer( + CurrentBuffer, + &VirtualAddress, + &CurrentLength + ); + + while (LocalBytesCopied < BytesToCopy) { + + if (!CurrentLength) { + + NdisGetNextBuffer( + CurrentBuffer, + &CurrentBuffer + ); + + // + // We've reached the end of the packet. We return + // with what we've done so far. (Which must be shorter + // than requested. + // + + if (!CurrentBuffer) { + break; + } + + NdisQueryBuffer( + CurrentBuffer, + &VirtualAddress, + &CurrentLength + ); + + continue; + + } + + // + // Try to get us up to the point to start the copy. + + + if (Offset) { + + if (Offset > CurrentLength) { + + // + // What we want isn't in this buffer. + // + + Offset -= CurrentLength; + CurrentLength = 0; + continue; + + } else { + + VirtualAddress = (PCHAR)VirtualAddress + Offset; + CurrentLength -= Offset; + Offset = 0; + + } + + } + + // + // Copy the data. + // + + + { + + // + // Holds the amount of data to move. + // + UINT AmountToMove; + + AmountToMove = + ((CurrentLength <= (BytesToCopy - LocalBytesCopied))? + (CurrentLength):(BytesToCopy - LocalBytesCopied)); + + ELNK_MOVE_MEMORY_TO_SHARED_RAM( + Buffer, + VirtualAddress, + AmountToMove + ); + + Buffer = (PCHAR)Buffer + AmountToMove; + VirtualAddress = (PCHAR)VirtualAddress + AmountToMove; + + LocalBytesCopied += AmountToMove; + CurrentLength -= AmountToMove; + + } + + } + + *BytesCopied = LocalBytesCopied; + +} + +VOID +ElnkCopyFromBufferToPacket( + IN PCHAR Buffer, + IN UINT BytesToCopy, + IN PNDIS_PACKET Packet, + IN UINT Offset, + OUT PUINT BytesCopied + ) + +/*++ + +Routine Description: + + Copy from a buffer into an ndis packet. + +Arguments: + + Buffer - The packet to copy from. + + Offset - The offset from which to start the copy. + + BytesToCopy - The number of bytes to copy from the buffer. + + Packet - The destination of the copy. + + BytesCopied - The number of bytes actually copied. Will be less + than BytesToCopy if the packet is not large enough. + +Return Value: + + None + +--*/ + +{ + // + // Holds the count of the number of ndis buffers comprising the + // destination packet. + // + UINT DestinationBufferCount; + + // + // Points to the buffer into which we are putting data. + // + PNDIS_BUFFER DestinationCurrentBuffer; + + // + // Points to the location in Buffer from which we are extracting data. + // + PUCHAR SourceCurrentAddress; + + // + // Holds the virtual address of the current destination buffer. + // + PVOID DestinationVirtualAddress; + + // + // Holds the length of the current destination buffer. + // + UINT DestinationCurrentLength; + + // + // Keep a local variable of BytesCopied so we aren't referencing + // through a pointer. + // + UINT LocalBytesCopied = 0; + + + // + // Take care of boundary condition of zero length copy. + // + + *BytesCopied = 0; + if (!BytesToCopy) { + return; + } + + // + // Get the first buffer of the destination. + // + + NdisQueryPacket( + Packet, + NULL, + &DestinationBufferCount, + &DestinationCurrentBuffer, + NULL + ); + + // + // Could have a null packet. + // + + if (!DestinationBufferCount) { + return; + } + + NdisQueryBuffer( + DestinationCurrentBuffer, + &DestinationVirtualAddress, + &DestinationCurrentLength + ); + + // + // Set up the source address. + // + + SourceCurrentAddress = Buffer; + + + while (LocalBytesCopied < BytesToCopy) { + + // + // Check to see whether we've exhausted the current destination + // buffer. If so, move onto the next one. + // + + if (!DestinationCurrentLength) { + + NdisGetNextBuffer( + DestinationCurrentBuffer, + &DestinationCurrentBuffer + ); + + if (!DestinationCurrentBuffer) { + + // + // We've reached the end of the packet. We return + // with what we've done so far. (Which must be shorter + // than requested.) + // + + break; + + } + + NdisQueryBuffer( + DestinationCurrentBuffer, + &DestinationVirtualAddress, + &DestinationCurrentLength + ); + + continue; + + } + + // + // Try to get us up to the point to start the copy. + // + + if (Offset) { + + if (Offset > DestinationCurrentLength) { + + // + // What we want isn't in this buffer. + // + + Offset -= DestinationCurrentLength; + DestinationCurrentLength = 0; + continue; + + } else { + + DestinationVirtualAddress = (PCHAR)DestinationVirtualAddress + + Offset; + DestinationCurrentLength -= Offset; + Offset = 0; + + } + + } + + + // + // Copy the data. + // + + { + + // + // Holds the amount of data to move. + // + UINT AmountToMove; + + // + // Holds the amount desired remaining. + // + UINT Remaining = BytesToCopy - LocalBytesCopied; + + + AmountToMove = DestinationCurrentLength; + + AmountToMove = ((Remaining < AmountToMove)? + (Remaining):(AmountToMove)); + + ELNK_MOVE_SHARED_RAM_TO_MEMORY( + DestinationVirtualAddress, + SourceCurrentAddress, + AmountToMove + ); + + SourceCurrentAddress += AmountToMove; + LocalBytesCopied += AmountToMove; + DestinationCurrentLength -= AmountToMove; + + } + + } + + *BytesCopied = LocalBytesCopied; +} + |