mirror of
https://github.com/reactos/reactos.git
synced 2024-09-30 22:47:28 +00:00
[NDIS]
- Implement NdisReturnPackets and do proper reference tracking of packets sent to ProtocolReceivePacket - Plug a massive memory leak that resulted in leaking every packet descriptor that any deserialized miniport indicated to TCP/IP svn path=/trunk/; revision=54559
This commit is contained in:
parent
f5fda30d65
commit
77ed514f64
|
@ -487,25 +487,6 @@ NdisIMInitializeDeviceInstanceEx(
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
VOID
|
||||
EXPORT
|
||||
NdisReturnPackets(
|
||||
IN PNDIS_PACKET *PacketsToReturn,
|
||||
IN UINT NumberOfPackets)
|
||||
/*
|
||||
* FUNCTION: Releases ownership of one or more packets
|
||||
* ARGUMENTS:
|
||||
* PacketsToReturn = Pointer to an array of pointers to packet descriptors
|
||||
* NumberOfPackets = Number of pointers in descriptor pointer array
|
||||
*/
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
|
|
|
@ -245,7 +245,41 @@ MiniIndicateData(
|
|||
NDIS_DbgPrint(MAX_TRACE, ("Leaving.\n"));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
VOID
|
||||
EXPORT
|
||||
NdisReturnPackets(
|
||||
IN PNDIS_PACKET *PacketsToReturn,
|
||||
IN UINT NumberOfPackets)
|
||||
/*
|
||||
* FUNCTION: Releases ownership of one or more packets
|
||||
* ARGUMENTS:
|
||||
* PacketsToReturn = Pointer to an array of pointers to packet descriptors
|
||||
* NumberOfPackets = Number of pointers in descriptor pointer array
|
||||
*/
|
||||
{
|
||||
UINT i;
|
||||
PLOGICAL_ADAPTER Adapter;
|
||||
|
||||
NDIS_DbgPrint(MID_TRACE, ("Returning %d packets\n", NumberOfPackets));
|
||||
|
||||
for (i = 0; i < NumberOfPackets; i++)
|
||||
{
|
||||
PacketsToReturn[i]->WrapperReserved[0]--;
|
||||
if (PacketsToReturn[i]->WrapperReserved[0] == 0)
|
||||
{
|
||||
Adapter = (PVOID)(ULONG_PTR)PacketsToReturn[i]->Reserved[1];
|
||||
|
||||
NDIS_DbgPrint(MAX_TRACE, ("Freeing packet %d (adapter = 0x%p)\n", i, Adapter));
|
||||
|
||||
Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.ReturnPacketHandler(
|
||||
Adapter->NdisMiniportBlock.MiniportAdapterContext,
|
||||
PacketsToReturn[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
VOID NTAPI
|
||||
MiniIndicateReceivePacket(
|
||||
IN NDIS_HANDLE MiniportAdapterHandle,
|
||||
|
@ -276,20 +310,23 @@ MiniIndicateReceivePacket(
|
|||
|
||||
for (i = 0; i < NumberOfPackets; i++)
|
||||
{
|
||||
/* Store the indicating miniport in the packet */
|
||||
PacketArray[i]->Reserved[1] = (ULONG_PTR)Adapter;
|
||||
|
||||
if (AdapterBinding->ProtocolBinding->Chars.ReceivePacketHandler &&
|
||||
NDIS_GET_PACKET_STATUS(PacketArray[i]) != NDIS_STATUS_RESOURCES)
|
||||
{
|
||||
(*AdapterBinding->ProtocolBinding->Chars.ReceivePacketHandler)(
|
||||
NDIS_DbgPrint(MID_TRACE, ("Indicating packet to protocol's ReceivePacket handler\n"));
|
||||
PacketArray[i]->WrapperReserved[0] += (*AdapterBinding->ProtocolBinding->Chars.ReceivePacketHandler)(
|
||||
AdapterBinding->NdisOpenBlock.ProtocolBindingContext,
|
||||
PacketArray[i]);
|
||||
NDIS_DbgPrint(MID_TRACE, ("Protocol is holding %d references to the packet\n", PacketArray[i]->WrapperReserved[0]));
|
||||
}
|
||||
else
|
||||
{
|
||||
UINT FirstBufferLength, TotalBufferLength, LookAheadSize, HeaderSize;
|
||||
PNDIS_BUFFER NdisBuffer;
|
||||
PVOID NdisBufferVA, LookAheadBuffer;
|
||||
NDIS_STATUS NdisStatus;
|
||||
|
||||
|
||||
NdisGetFirstBufferFromPacket(PacketArray[i],
|
||||
&NdisBuffer,
|
||||
|
@ -308,7 +345,6 @@ MiniIndicateReceivePacket(
|
|||
LookAheadSize = TotalBufferLength - HeaderSize;
|
||||
}
|
||||
|
||||
|
||||
LookAheadBuffer = ExAllocatePool(NonPagedPool, LookAheadSize);
|
||||
if (!LookAheadBuffer)
|
||||
{
|
||||
|
@ -322,7 +358,8 @@ MiniIndicateReceivePacket(
|
|||
HeaderSize,
|
||||
LookAheadSize);
|
||||
|
||||
NdisStatus = (*AdapterBinding->ProtocolBinding->Chars.ReceiveHandler)(
|
||||
NDIS_DbgPrint(MID_TRACE, ("Indicating packet to protocol's legacy Receive handler\n"));
|
||||
(*AdapterBinding->ProtocolBinding->Chars.ReceiveHandler)(
|
||||
AdapterBinding->NdisOpenBlock.ProtocolBindingContext,
|
||||
AdapterBinding->NdisOpenBlock.MacHandle,
|
||||
NdisBufferVA,
|
||||
|
@ -331,8 +368,6 @@ MiniIndicateReceivePacket(
|
|||
LookAheadSize,
|
||||
TotalBufferLength - HeaderSize);
|
||||
|
||||
NDIS_SET_PACKET_STATUS(PacketArray[i], NdisStatus);
|
||||
|
||||
ExFreePool(LookAheadBuffer);
|
||||
}
|
||||
}
|
||||
|
@ -340,6 +375,57 @@ MiniIndicateReceivePacket(
|
|||
CurrentEntry = CurrentEntry->Flink;
|
||||
}
|
||||
|
||||
/* Loop the packet array to get everything
|
||||
* set up for return the packets to the miniport */
|
||||
for (i = 0; i < NumberOfPackets; i++)
|
||||
{
|
||||
/* First, check the initial packet status */
|
||||
if (NDIS_GET_PACKET_STATUS(PacketArray[i]) == NDIS_STATUS_RESOURCES)
|
||||
{
|
||||
/* The miniport driver gets it back immediately so nothing to do here */
|
||||
NDIS_DbgPrint(MID_TRACE, ("Miniport needs the packet back immediately\n"));
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Different behavior depending on whether it's serialized or not */
|
||||
if (Adapter->NdisMiniportBlock.Flags & NDIS_ATTRIBUTE_DESERIALIZE)
|
||||
{
|
||||
/* We need to check the reference count */
|
||||
if (PacketArray[i]->WrapperReserved[0] == 0)
|
||||
{
|
||||
/* NOTE: Unlike serialized miniports, this is REQUIRED to be called for each
|
||||
* packet received that can be reused immediately, it is not implied! */
|
||||
Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.ReturnPacketHandler(
|
||||
Adapter->NdisMiniportBlock.MiniportAdapterContext,
|
||||
PacketArray[i]);
|
||||
NDIS_DbgPrint(MID_TRACE, ("Packet has been returned to miniport (Deserialized)\n"));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Packet will be returned by the protocol's call to NdisReturnPackets */
|
||||
NDIS_DbgPrint(MID_TRACE, ("Packet will be returned to miniport later (Deserialized)\n"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check the reference count */
|
||||
if (PacketArray[i]->WrapperReserved[0] == 0)
|
||||
{
|
||||
/* NDIS_STATUS_SUCCESS means the miniport can have the packet back immediately */
|
||||
NDIS_SET_PACKET_STATUS(PacketArray[i], NDIS_STATUS_SUCCESS);
|
||||
|
||||
NDIS_DbgPrint(MID_TRACE, ("Packet has been returned to miniport (Serialized)\n"));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* NDIS_STATUS_PENDING means the miniport needs to wait for MiniportReturnPacket */
|
||||
NDIS_SET_PACKET_STATUS(PacketArray[i], NDIS_STATUS_PENDING);
|
||||
|
||||
NDIS_DbgPrint(MID_TRACE, ("Packet will be returned to miniport later (Serialized)\n"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, OldIrql);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue