Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

610 lines
12 KiB

/*++
Copyright (c) 1992 Microsoft Corporation
Module Name:
ltutils.c
Abstract:
This module contains utility routines.
Author:
Nikhil Kamkolkar ([email protected])
Stephen Hou ([email protected])
Revision History:
19 Jun 1992 Initial Version ([email protected])
Notes: Tab stop: 4
--*/
#include "ltmain.h"
#include "ltutils.h"
// Define file id for errorlogging
#define FILENUM LTUTILS
USHORT
LtUtilsPacketType(
IN PNDIS_PACKET Packet
)
/*++
Routine Description:
Calculates the packet type for this packet. It also determines
if this packet should go out on the wire.
Arguments:
Packet - Packet whose source and destination addresses are tested.
Return Value:
Returns FALSE if the source is equal to the destination.
--*/
{
// Holds the destination and source address from the packet.
UCHAR PacketAddresses[2];
// Junk variable to hold the length of the addresses
UINT AddressLength;
LtUtilsCopyFromPacketToBuffer(
Packet,
0,
2,
PacketAddresses,
&AddressLength);
return(LtUtilsUcharPacketType(PacketAddresses[0], PacketAddresses[1]));
}
USHORT
LtUtilsUcharPacketType(
IN UCHAR DestinationAddress,
IN UCHAR SourceAddress
)
/*++
Routine Description:
Calculates the packet type for this packet. It also determines
if this packet should go out on the wire.
Arguments:
Packet - Packet whose source and destination addresses are tested.
Return Value:
Returns FALSE if the source is equal to the destination.
--*/
{
int PacketType = LT_DIRECTED;
if (DestinationAddress == LT_BROADCAST_NODE_ID)
{
PacketType = LT_BROADCAST;
}
else
{
if (DestinationAddress == SourceAddress)
{
PacketType = LT_LOOPBACK;
}
}
return(PacketType);
}
VOID
LtUtilsCopyFromPacketToBuffer(
IN PNDIS_PACKET SrcPacket,
IN UINT SrcOffset,
IN UINT BytesToCopy,
OUT PUCHAR DestBuffer,
OUT PUINT BytesCopied
)
/*++
Routine Description:
Copy from an ndis packet into a buffer.
Arguments:
SrcPacket - The packet to copy from.
SrcOffset - The offset within the packet from which to start the copy.
BytesToCopy - The number of bytes to copy from the packet.
DestBuffer - 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
--*/
{
UINT SrcBufferCount; // number of buffers in the current buffer
PNDIS_BUFFER SrcCurrentBuffer; // current buffer
UINT SrcCurrentBufferLen; // length of the current buffer
PVOID SrcVirtualAddress; // virtual address of the current buffer
UINT AmountToCopy; // bytes to copy
UINT LocalBytesCopied = 0; // total bytes copied
*BytesCopied = 0;
// Take care of boundary condition of zero length copy.
if (!BytesToCopy)
{
return;
}
//
// Get the first buffer.
//
NdisQueryPacket(
SrcPacket,
NULL,
&SrcBufferCount,
&SrcCurrentBuffer,
NULL);
// Could have a null packet.
if (!SrcBufferCount)
{
return;
}
NdisQueryBuffer(
SrcCurrentBuffer,
&SrcVirtualAddress,
&SrcCurrentBufferLen);
// advance to the start point for the copy.
while (SrcOffset)
{
if (SrcOffset > SrcCurrentBufferLen)
{
//
// What we want isn't in this buffer.
//
SrcOffset -= SrcCurrentBufferLen;
SrcCurrentBufferLen = 0;
}
else
{
//
SrcVirtualAddress = (PCHAR)SrcVirtualAddress + SrcOffset;
SrcCurrentBufferLen -= SrcOffset;
SrcOffset = 0;
break;
}
NdisGetNextBuffer(
SrcCurrentBuffer,
&SrcCurrentBuffer);
// We hit the end of the packet
if (!SrcCurrentBuffer)
{
return;
}
NdisQueryBuffer(
SrcCurrentBuffer,
&SrcVirtualAddress,
&SrcCurrentBufferLen);
}
// Copy the data.
while (LocalBytesCopied < BytesToCopy)
{
AmountToCopy = ((SrcCurrentBufferLen <= (BytesToCopy - LocalBytesCopied))?
(SrcCurrentBufferLen):(BytesToCopy - LocalBytesCopied));
NdisMoveMemory(
DestBuffer,
SrcVirtualAddress,
AmountToCopy);
DestBuffer = (PCHAR)DestBuffer + AmountToCopy;
SrcVirtualAddress = (PCHAR)SrcVirtualAddress + AmountToCopy;
LocalBytesCopied += AmountToCopy;
SrcCurrentBufferLen -= AmountToCopy;
// read the entire buffer, read in the next one
if (!SrcCurrentBufferLen)
{
NdisGetNextBuffer(
SrcCurrentBuffer,
&SrcCurrentBuffer);
//
// We've reached the end of the packet. We return
// with what we've done so far. (Which must be shorter
// than requested.
//
if (!SrcCurrentBuffer)
break;
NdisQueryBuffer(
SrcCurrentBuffer,
&SrcVirtualAddress,
&SrcCurrentBufferLen);
}
}
*BytesCopied = LocalBytesCopied;
}
VOID
LtUtilsCopyFromBufferToPacket(
IN PUCHAR SrcBuffer,
IN UINT SrcOffset,
IN UINT BytesToCopy,
IN PNDIS_PACKET DestPacket,
OUT PUINT BytesCopied
)
/*++
Routine Description:
Copy from a buffer into an ndis packet.
Arguments:
SrcBuffer - The buffer to copy from.
SrcOffset - The offset within SrcBuffer from which to start the copy.
DestPacket - The destination of the copy.
BytesToCopy - The number of bytes to copy from the buffer.
BytesCopied - The number of bytes actually copied. Will be less
than BytesToCopy if the packet is not large enough.
Return Value:
None
--*/
{
UINT DestBufferCount; // number of buffers in the packet
PNDIS_BUFFER DestCurrentBuffer; // current buffer
UINT DestCurrentBufferLen; // length of the current buffer
PVOID DestVirtualAddress; // virtual addr of the current dest buffer
PUCHAR SrcCurrentAddress; // ptr to current location in src buffer
UINT AmountToCopy; // bytes to copy
UINT BytesRemaining; // bytes left to copy
UINT LocalBytesCopied = 0; // bytes copied
*BytesCopied = 0;
// Take care of boundary condition of zero length copy.
if (!BytesToCopy)
{
return;
}
// Get the first buffer of the destination.
NdisQueryPacket(
DestPacket,
NULL,
&DestBufferCount,
&DestCurrentBuffer,
NULL);
// Could have a null packet.
if (!DestBufferCount)
{
return;
}
NdisQueryBuffer(
DestCurrentBuffer,
&DestVirtualAddress,
&DestCurrentBufferLen);
// Set up the source address.
SrcCurrentAddress = SrcBuffer + SrcOffset;
while (LocalBytesCopied < BytesToCopy)
{
//
// Check to see whether we've exhausted the current destination
// buffer. If so, move onto the next one.
//
if (!DestCurrentBufferLen)
{
NdisGetNextBuffer(
DestCurrentBuffer,
&DestCurrentBuffer);
if (!DestCurrentBuffer)
{
//
// 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(
DestCurrentBuffer,
&DestVirtualAddress,
&DestCurrentBufferLen);
// go back to the start of the loop and repeat buffer size check
continue;
}
//
// Copy the data.
//
BytesRemaining = BytesToCopy - LocalBytesCopied;
AmountToCopy = ((BytesRemaining < DestCurrentBufferLen)?
(BytesRemaining):(DestCurrentBufferLen));
NdisMoveMemory(
DestVirtualAddress,
SrcCurrentAddress,
AmountToCopy);
SrcCurrentAddress += AmountToCopy;
LocalBytesCopied += AmountToCopy;
DestCurrentBufferLen -= AmountToCopy;
}
*BytesCopied = LocalBytesCopied;
}
VOID
LtRefAdapter(
IN OUT PLT_ADAPTER Adapter,
OUT PNDIS_STATUS Status
)
{
*Status = NDIS_STATUS_SUCCESS;
NdisAcquireSpinLock(&Adapter->Lock);
if ((Adapter->Flags & ADAPTER_CLOSING) == 0)
{
Adapter->RefCount++;
}
else
{
*Status = NDIS_STATUS_ADAPTER_REMOVED;
}
NdisReleaseSpinLock(&Adapter->Lock);
return;
}
VOID
LtRefAdapterNonInterlock(
IN OUT PLT_ADAPTER Adapter,
OUT PNDIS_STATUS Status
)
{
*Status = NDIS_STATUS_SUCCESS;
if ((Adapter->Flags & ADAPTER_CLOSING) == 0)
{
Adapter->RefCount++;
}
else
{
*Status = NDIS_STATUS_ADAPTER_REMOVED;
}
return;
}
VOID
LtDeRefAdapter(
IN OUT PLT_ADAPTER Adapter
)
{
BOOLEAN Close = FALSE;
NdisAcquireSpinLock(&Adapter->Lock);
if (--Adapter->RefCount == 0)
Close = TRUE;
NdisReleaseSpinLock(&Adapter->Lock);
if (Close)
{
// Last reference on adapter is gone.
ASSERTMSG("LtDeRefAdapter: Closing flag not set!\n",
(Adapter->Flags & ADAPTER_CLOSING));
ASSERTMSG("LtDeRefAdapter: Open count is not zero!\n",
(Adapter->OpenCount == 0));
// Release the adapter
NdisDeregisterAdapter(Adapter->NdisAdapterHandle);
NdisFreeSpinLock(&Adapter->Lock);
NdisFreeMemory(
Adapter,
sizeof(LT_ADAPTER),
(UINT)0);
}
return;
}
VOID
LtRefBinding(
IN OUT PLT_OPEN Binding,
OUT PNDIS_STATUS Status
)
{
*Status = NDIS_STATUS_SUCCESS;
NdisAcquireSpinLock(&Binding->LtAdapter->Lock);
if ((Binding->Flags & BINDING_CLOSING) == 0)
{
Binding->RefCount++;
}
else
{
*Status = NDIS_STATUS_CLOSING;
}
NdisReleaseSpinLock(&Binding->LtAdapter->Lock);
return;
}
VOID
LtRefBindingNextNcNonInterlock(
IN PLIST_ENTRY PList,
IN PLIST_ENTRY PEnd,
OUT PLT_OPEN * Binding,
OUT PNDIS_STATUS Status
)
{
PLT_OPEN ChkBinding;
*Status = NDIS_STATUS_FAILURE;
*Binding = NULL;
while (PList != PEnd)
{
ChkBinding = CONTAINING_RECORD(PList, LT_OPEN, Linkage);
DBGPRINT(DBG_COMP_UTILS, DBG_LEVEL_INFO,
("LtRefBindingNextNcNonInterlock: ChkBind %lx\n", ChkBinding));
LtRefBindingNonInterlock(ChkBinding, Status);
if (*Status == NDIS_STATUS_SUCCESS)
{
*Binding = ChkBinding;
break;
}
PList = PList->Flink;
}
return;
}
VOID
LtRefBindingNonInterlock(
IN OUT PLT_OPEN Binding,
OUT PNDIS_STATUS Status
)
{
*Status = NDIS_STATUS_SUCCESS;
if ((Binding->Flags & BINDING_CLOSING) == 0)
{
Binding->RefCount++;
}
else
{
*Status = NDIS_STATUS_CLOSING;
}
return;
}
VOID
LtDeRefBinding(
IN OUT PLT_OPEN Binding
)
{
BOOLEAN Close = FALSE;
NdisAcquireSpinLock(&Binding->LtAdapter->Lock);
if (--Binding->RefCount == 0)
{
Close = TRUE;
RemoveEntryList(&Binding->Linkage);
(Binding->LtAdapter->OpenCount)--;
}
NdisReleaseSpinLock(&Binding->LtAdapter->Lock);
if (Close)
{
NDIS_HANDLE OpenBindingContext = Binding->NdisBindingContext;
// Last reference on binding is gone.
ASSERTMSG("LtDeRefBinding: Closing flag not set!\n",
(Binding->Flags & BINDING_CLOSING));
// Release the binding and remove its reference on the
// adapter.
NdisCompleteCloseAdapter(OpenBindingContext, NDIS_STATUS_SUCCESS);
LtDeReferenceAdapter(Binding->LtAdapter);
// Free up the binding structure
NdisFreeMemory(Binding, sizeof(LT_OPEN), (UINT)0);
}
return;
}