speed very very slow?
Dera all,
I have modified the XP DDK passthru sample for my own
use.Instead of directly indicate receive packet
in PtReceivePacket or indicate receive buffer data in
PtReceive to upper layer driver, I always
use a fresh packet and copy all data from original
packet or buffer to my new packet and then indicate
it to upper driver.But when I use this driver under my
computer ,some strang thing happened.
I use a ADSL modem which connect to my realtek 10/100M
netcard to connect to internet.And when I install
oroginal xp passthru to my computer, everything is
ok.but after I install my driver (of cousely i have
uninstalled xp passthru before),my internet browsing
speed becomes very very slowly for some website,
and normal for a little other website.I don’t know why
and am tired of find the reasoning .Can anyone
give some advice.Following is some code snippet from
my driver source.
NDIS_STATUS
PtReceive(
IN NDIS_HANDLE ProtocolBindingContext,
IN NDIS_HANDLE MacReceiveContext,
IN PVOID HeaderBuffer,
IN UINT HeaderBufferSize,
IN PVOID LookAheadBuffer,
IN UINT LookAheadBufferSize,
IN UINT PacketSize
)
{
PADAPT pAdapt =(PADAPT)ProtocolBindingContext;
PNDIS_PACKET MyPacket, Packet;
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
NDIS_STATUS MyPacketStatus;
PSINGLE_LIST_ENTRY pPacketEntry;
PRECV_RSVD pPacketContext;
PSINGLE_LIST_ENTRY pRecvBufferEntry;
PNDIS_BUFFER pRecvNdisBuffer;
PNDIS_BUFFER pTempRecvNdisBuffer;
UINT uBytesTransferred;
if (!pAdapt->MiniportHandle)
{
Status = NDIS_STATUS_FAILURE;
}
else
{
// Now get a packet entry off our S List.
pPacketEntry = NdisInterlockedPopEntrySList
(&pAdapt->RecvPacketSList,
&pAdapt->RecvPacketSListLock);
if (pPacketEntry == NULL)
{
// Out of resources. indicate that we’re not
hanging onto the packet.
ImDbgOut (DBG_FAILURE, DBG_RECEIVE, (“PtReceive:
Out Of IM
Packets!!!\n” ));
Status = NDIS_STATUS_FAILURE;
goto RET_PATH;
}
// Get a NDIS_BUFFER from the single list.
pRecvBufferEntry = NdisInterlockedPopEntrySList
(&pAdapt->RecvBufferSList,
&pAdapt->RecvBufferSListLock);
if (pRecvBufferEntry == NULL)
{
// Out of resources. indicate that we’re not
hanging onto the packet.
ImDbgOut (DBG_FAILURE, DBG_RECEIVE, (“PtReceive:
Out Of IM
Buffers!!!\n” ));
// Push back previously popped packet.
NdisInterlockedPushEntrySList
(&pAdapt->RecvPacketSList, pPacketEntry,
&pAdapt->RecvPacketSListLock);
Status = NDIS_STATUS_FAILURE;
goto RET_PATH;
}
pRecvNdisBuffer = ((PIM_BUFFER_CONTEXT)
pRecvBufferEntry)->pNdisBuffer;
// Stats.
pAdapt->uNumFreePackets --;
pAdapt->uNumAllRecvPackets ++;
// Got a free packet. If it’s the last one, set the
packet status such
that
// NDIS will know we’re running short of resources.
MyPacket = CONTAINING_RECORD (pPacketEntry,
NDIS_PACKET,
MiniportReserved );
pPacketContext = (PRECV_RSVD)
MyPacket->MiniportReserved;
if (NdisQueryDepthSList (&pAdapt->RecvPacketSList)
== 0)
{
// Out of resources. indicate that we’re not
hanging onto the packet.
ImDbgOut (DBG_FAILURE, DBG_RECEIVE, (“PtReceive:
Almost Out Of IM
Packets!!!\n” ));
MyPacketStatus = NDIS_STATUS_RESOURCES;
}
else
{
MyPacketStatus = NDIS_STATUS_SUCCESS;
}
NDIS_SET_PACKET_STATUS (MyPacket, MyPacketStatus);
// Set pPacketContext->OriginalPkt to NULL since we
don’t get any
// packet from low-level miniport.
pPacketContext->OriginalPkt = NULL;
// Copy what we have into the lookahead buffer. Set
the lookahead buffer
size.
if (pAdapt->bCopyLookaheadData)
{
NdisMoveMemory (pRecvBufferEntry, HeaderBuffer,
HeaderBufferSize);
NdisMoveMemory ((CHAR *) pRecvBufferEntry +
HeaderBufferSize,
LookAheadBuffer,
LookAheadBufferSize);
}
else
{
TdiCopyLookaheadData (pRecvBufferEntry,
HeaderBuffer, HeaderBufferSize,
0 );
TdiCopyLookaheadData ((CHAR *) pRecvBufferEntry +
HeaderBufferSize,
LookAheadBuffer, LookAheadBufferSize, 0);
}
// Adjust some length.
NdisAdjustBufferLength (pRecvNdisBuffer,
HeaderBufferSize + PacketSize);
NdisChainBufferAtFront (MyPacket, pRecvNdisBuffer);
MyPacket->Private.TotalLength = HeaderBufferSize +
PacketSize;
NDIS_SET_PACKET_HEADER_SIZE (MyPacket,
HeaderBufferSize );
// Either indicate this packet directly or call
NdisTransferData.
if (LookAheadBufferSize == PacketSize)
{
// Stats.
pAdapt->uNumRecvPackets2 ++;
// Try to copy OOB data.
Packet = NdisGetReceivedPacket
(pAdapt->BindingHandle,
MacReceiveContext);
if (Packet != NULL)
{
// Get the original packet (it could be the same
packet as the
// one received or a different one based on the
number of layered
// miniports below) and set it on the indicated
packet so the OOB
// data is visible correctly at protocols above.
NDIS_SET_ORIGINAL_PACKET (MyPacket,
NDIS_GET_ORIGINAL_PACKET (Packet));
// Copy packet flags.
NdisGetPacketFlags (MyPacket) = NdisGetPacketFlags
(Packet);
}
// Force protocols above to make a copy if they
want to hang
// on to data in this packet. This is because we
are in our
// Receive handler (not ReceivePacket) and we can’t
return a
// ref count from here.
MyPacketStatus = NDIS_STATUS_RESOURCES;
NDIS_SET_PACKET_STATUS (MyPacket,
NDIS_STATUS_RESOURCES);
// We can indicate the packet now (or at least try
to) since we have all
of it.
MyNdisMIndicateReceivePacket
(pAdapt->MiniportHandle, &MyPacket, 1);
// !!! NO NO NO. Under Windows 2000, we are
deserialized IM driver,
// so we can not check Status on return of
NdisMIndicateReceivePacket
!!!
// We must check the already save packet
status.
if (MyPacketStatus == NDIS_STATUS_RESOURCES)
{
MPReturnPacket ((NDIS_HANDLE) pAdapt, MyPacket);
}
}
else
{
// Stats.
pAdapt->uNumRecvPackets1 ++;
// Stuff a pointer to the lookahead NDIS buffer in
the packet context
area
// and chain the residual buffer at the front. The
MP wants to copy data
to
// beginning of the first buffer, so we’ll chain
the lookahead buffer
when
// the transfer data stuff is complete.
NdisAllocateBuffer (&Status, &pTempRecvNdisBuffer,
pAdapt->TempRecvBufferPoolHandle,
(CHAR *) pRecvBufferEntry +
HeaderBufferSize +
LookAheadBufferSize, PacketSize -
LookAheadBufferSize);
if (!NT_SUCCESS (Status))
{
DBGPRINT ((“Allocate TempRecvNdisBuffer
Failed.\n”));
}
NdisChainBufferAtFront (MyPacket,
pTempRecvNdisBuffer);
NdisTransferData (&Status,
pAdapt->BindingHandle,
MacReceiveContext,
LookAheadBufferSize,
PacketSize -
LookAheadBufferSize,
MyPacket,
&uBytesTransferred);
if (Status != NDIS_STATUS_PENDING)
{
PtTransferDataComplete ((NDIS_HANDLE) pAdapt,
MyPacket, Status,
uBytesTransferred);
}
}
// Success.
Status = NDIS_STATUS_SUCCESS;
}
// Return.
RET_PATH:
return Status;
}
VOID
PtReceiveComplete(
IN NDIS_HANDLE ProtocolBindingContext
)
{
PADAPT pAdapt =(PADAPT)ProtocolBindingContext;
// if ((pAdapt->MiniportHandle != NULL) &&
pAdapt->IndicateRcvComplete)
if (pAdapt->MiniportHandle != NULL)
{
switch (pAdapt->Medium)
{
case NdisMedium802_3:
case NdisMediumWan:
NdisMEthIndicateReceiveComplete(pAdapt->MiniportHandle);
break;
case NdisMedium802_5:
NdisMTrIndicateReceiveComplete(pAdapt->MiniportHandle);
break;
case NdisMediumFddi:
NdisMFddiIndicateReceiveComplete(pAdapt->MiniportHandle);
break;
default:
ASSERT(FALSE);
break;
}
}
// pAdapt->IndicateRcvComplete = FALSE; // We don’t
use this variable.
}
INT
PtReceivePacket(
IN NDIS_HANDLE ProtocolBindingContext,
IN PNDIS_PACKET Packet
)
{
PADAPT pAdapt =(PADAPT)ProtocolBindingContext;
NDIS_STATUS Status;
PNDIS_PACKET MyPacket;
PSINGLE_LIST_ENTRY pPacketEntry;
PSINGLE_LIST_ENTRY pRecvBufferEntry;
NDIS_STATUS MyPacketStatus;
PRECV_RSVD pPacketContext;
PNDIS_BUFFER pRecvNdisBuffer;
UINT uPacketLength;
UINT uMyPacketLength;
UINT uBytesCopied;
// Drop the packet silently if the upper miniport
edge isn’t initialized
if (!pAdapt->MiniportHandle)
{
return 0;
}
// Now get a packet entry off our S List.
pPacketEntry = NdisInterlockedPopEntrySList
(&pAdapt->RecvPacketSList,
&pAdapt->RecvPacketSListLock);
if (pPacketEntry == NULL)
{
// Out of resources. indicate that we’re not hanging
onto the packet.
ImDbgOut (DBG_FAILURE, DBG_RECEIVE,
(“PtReceivePacket: Out Of IM
Packets!!!\n” ));
return 0;
}
// Get a NDIS_BUFFER from the single list.
pRecvBufferEntry = NdisInterlockedPopEntrySList
(&pAdapt->RecvBufferSList,
&pAdapt->RecvBufferSListLock);
if (pRecvBufferEntry == NULL)
{
// Out of resources. indicate that we’re not hanging
onto the packet.
ImDbgOut (DBG_FAILURE, DBG_RECEIVE,
(“PtReceivePacket: Out Of IM
Buffers!!!\n” ));
// Push back previously popped packet.
NdisInterlockedPushEntrySList
(&pAdapt->RecvPacketSList, pPacketEntry,
&pAdapt->RecvPacketSListLock);
return 0;
}
// Stats.
pAdapt->uNumFreePackets --;
pAdapt->uNumAllRecvPackets ++;
pAdapt->uNumRecvPackets3 ++;
// Got a free packet. If it’s the last one, set the
packet status such that
// NDIS will know we’re running short of
resources.
MyPacket = CONTAINING_RECORD (pPacketEntry,
NDIS_PACKET,
MiniportReserved );
pPacketContext = (PRECV_RSVD)
MyPacket->MiniportReserved;
if (NdisQueryDepthSList (&pAdapt->RecvPacketSList) ==
0)
{
// Out of resources. indicate that we’re not hanging
onto the packet.
ImDbgOut (DBG_FAILURE, DBG_RECEIVE,
(“PtReceivePacket: Almost Out Of IM
Packet!!!\n” ));
MyPacketStatus = NDIS_STATUS_RESOURCES;
}
else
{
MyPacketStatus = NDIS_STATUS_SUCCESS;
}
NDIS_SET_PACKET_STATUS (MyPacket, MyPacketStatus);
// Remember original packet.
pPacketContext->OriginalPkt = Packet;
// Copy original packet content to our packet
content.
pRecvNdisBuffer = ((PIM_BUFFER_CONTEXT)
pRecvBufferEntry)->pNdisBuffer;
NdisChainBufferAtFront (MyPacket, pRecvNdisBuffer);
NdisQueryPacket (Packet, NULL, NULL, NULL,
&uPacketLength);
NdisQueryPacket (MyPacket, NULL, NULL, NULL,
&uMyPacketLength);
NdisCopyFromPacketToPacket (MyPacket, 0,
uPacketLength,
Packet, 0, &uBytesCopied);
// Copy packet will not modify the following value,
// So adjust length: but we are large enough for
length scale.
NdisAdjustBufferLength (pRecvNdisBuffer,
uPacketLength);
MyPacket->Private.TotalLength = uPacketLength;
// Set packet flags.
NdisSetPacketFlags (MyPacket, NdisGetPacketFlags
(Packet));
// Get the original packet (it could be the same
packet as the one
// received or a different one based on the number of
layered miniports
// below) and set it on the indicated packet so the
OOB data is visible
// correctly to protocols above us.
NDIS_SET_ORIGINAL_PACKET (MyPacket,
NDIS_GET_ORIGINAL_PACKET (Packet));
NDIS_SET_PACKET_HEADER_SIZE (MyPacket,
NDIS_GET_PACKET_HEADER_SIZE
(Packet));
// Indicate this packet.
Status = NDIS_GET_PACKET_STATUS (Packet);
MyNdisMIndicateReceivePacket (pAdapt->MiniportHandle,
&MyPacket, 1);
// !!! NO NO NO. Under Windows 2000, we are
deserialized IM driver,
// so we can not check Status on return of
NdisMIndicateReceivePacket
!!!
// We must check the already save packet status.
if (MyPacketStatus == NDIS_STATUS_RESOURCES)
{
// NDIS won’t call MPReturnPacket, so we call it.
// Set pPacketContext->OriginalPkt to NULL to
prevent from returning this
// original packet since we needn’t return it.
pPacketContext->OriginalPkt = NULL;
MPReturnPacket ((NDIS_HANDLE) pAdapt, MyPacket);
return 0;
}
else
{
// We hold this original packet.
return 1;
}
}
VOID
PtTransferDataComplete(
IN NDIS_HANDLE ProtocolBindingContext,
IN PNDIS_PACKET Packet,
IN NDIS_STATUS Status,
IN UINT BytesTransferred
)
{
PADAPT pAdapt = (PADAPT)ProtocolBindingContext;
PRECV_RSVD pPacketContext;
PNDIS_BUFFER pResidualNdisBuffer = NULL;
NDIS_STATUS MyStatus;
if (pAdapt->MiniportHandle)
{
// Get the lookahead NDIS buffer pointer from the
context area and chain
it
// on the front.
pPacketContext = (PRECV_RSVD)
Packet->MiniportReserved;
if (BytesTransferred)
{
NdisUnchainBufferAtFront (Packet,
&pResidualNdisBuffer);
NdisFreeBuffer (pResidualNdisBuffer);
}
// We can indicate the packet now (or at least try
to) since we have all
of it.
MyStatus = NDIS_GET_PACKET_STATUS (Packet);
MyNdisMIndicateReceivePacket
(pAdapt->MiniportHandle, &Packet, 1);
// Now check the packet’s status to see if we can
return it.
if (MyStatus == NDIS_STATUS_RESOURCES)
{
MPReturnPacket ((NDIS_HANDLE) pAdapt,
Packet);
}
}
}
VOID
MPReturnPacket(
IN NDIS_HANDLE MiniportAdapterContext,
IN PNDIS_PACKET Packet
)
{
PADAPT pAdapt = (PADAPT)MiniportAdapterContext;
PNDIS_PACKET OriPacket;
PRECV_RSVD pPacketContext;
PNDIS_BUFFER pNdisBuffer;
PIM_BUFFER_CONTEXT pBufferContext;
UINT uLength;
// Get original packet.
pPacketContext =
(PRECV_RSVD)(Packet->MiniportReserved);
OriPacket = pPacketContext->OriginalPkt;
// Return ndis buffer.
NdisUnchainBufferAtFront (Packet, &pNdisBuffer);
NdisQueryBuffer (pNdisBuffer, &pBufferContext,
&uLength);
pBufferContext->pNdisBuffer = pNdisBuffer;
NdisInterlockedPushEntrySList
(&pAdapt->RecvBufferSList,
&pBufferContext->Linkage,
&pAdapt->RecvBufferSListLock);
// Return packet.
NdisReinitializePacket (Packet);
NdisInterlockedPushEntrySList
(&pAdapt->RecvPacketSList,
(PSINGLE_LIST_ENTRY)
&pPacketContext->Linkage,
&pAdapt->RecvPacketSListLock);
// Return original packet.
if (OriPacket)
{
NdisReturnPackets (&OriPacket, 1);
}
// Stats.
pAdapt->uNumFreePackets ++;
You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com