📄 protocol.c
字号:
NdisDprFreePacket(MyPacket);
break;
}
}
else
{
if(PacketSize <= LookAheadBufferSize && //如果LookAheadBuffer包含了全部数据
HeaderBufferSize >= 14) //如果带有以太网桢头
{
DbgPrint("11: NoPacket But Complete");
NdisMoveMemory(pPacketContent, HeaderBuffer, HeaderBufferSize); //复制数据报头
NdisMoveMemory(pPacketContent + HeaderBufferSize, LookAheadBuffer, LookAheadBufferSize); //复制前视缓冲
if(CheckPacket(pAdapt, pPacketContent, 11, HeaderBufferSize)==FALSE)
{
Status=NDIS_STATUS_SUCCESS;
NdisFreeMemory(pPacketContent, 2000, 0); //释放内存
break;
}
NdisFreeMemory(pPacketContent, 2000, 0); //释放内存
}
else //LookAheadBuffer没有包括全部数据
{
DbgPrint("12: NoPacket & InComplete");
NdisTransferData(&Status,
pAdapt->BindingHandle,
MacReceiveContext,
0,
PacketSize,
Packet,
&BytesTransferred);
if(Status==NDIS_STATUS_SUCCESS)
{
DbgPrint("12: TransferData Complete!");
if(Packet!=NULL)
{
//这里处理NdisTransferData得到的封包
}
}
else if (Status==NDIS_STATUS_PENDING)
{
DbgPrint("12: TransferData Pending!");
}
else
{
DbgPrint("12: TransferData Fail!");
}
NdisFreeMemory(pPacketContent, 2000, 0); //释放内存
}
//
// The miniport below us uses the old-style (not packet)
// receive indication. Fall through.
//
}
//
// Fall through if the miniport below us has either not
// indicated a packet or we could not allocate one
//
if (Packet != NULL)
{
//
// We are here because we failed to allocate packet
//
PtFlushReceiveQueue(pAdapt);
}
//
// Here the driver checks if the miniport adapter is in lower power state, do not indicate the
// packets, but the check does not close the window, it only minimizes the window. To close
// the window completely, we need to add synchronization in the receive code path; because
// NDIS can handle the case that miniport drivers indicate packets in lower power state,
// we don't add the synchronization in the hot code path.
//
if ((pAdapt->MiniportHandle == NULL)
|| (pAdapt->MPDeviceState > NdisDeviceStateD0))
{
break;
}
pAdapt->IndicateRcvComplete = TRUE;
switch (pAdapt->Medium)
{
case NdisMedium802_3:
case NdisMediumWan:
NdisMEthIndicateReceive(pAdapt->MiniportHandle,
MacReceiveContext,
HeaderBuffer,
HeaderBufferSize,
LookAheadBuffer,
LookAheadBufferSize,
PacketSize);
break;
case NdisMedium802_5:
NdisMTrIndicateReceive(pAdapt->MiniportHandle,
MacReceiveContext,
HeaderBuffer,
HeaderBufferSize,
LookAheadBuffer,
LookAheadBufferSize,
PacketSize);
break;
case NdisMediumFddi:
NdisMFddiIndicateReceive(pAdapt->MiniportHandle,
MacReceiveContext,
HeaderBuffer,
HeaderBufferSize,
LookAheadBuffer,
LookAheadBufferSize,
PacketSize);
break;
default:
ASSERT(FALSE);
break;
}
} while(FALSE);
return Status;
}
VOID
PtReceiveComplete(
IN NDIS_HANDLE ProtocolBindingContext
)
/*++
Routine Description:
Called by the adapter below us when it is done indicating a batch of
received packets.
Arguments:
ProtocolBindingContext Pointer to our adapter structure.
Return Value:
None
--*/
{
PADAPT pAdapt =(PADAPT)ProtocolBindingContext;
PNDIS_PACKET PacketArray[MAX_RECEIVE_PACKET_ARRAY_SIZE];
ULONG NumberOfPackets = 0, i;
PtFlushReceiveQueue(pAdapt);
if ((pAdapt->MiniportHandle != NULL)
&& (pAdapt->MPDeviceState == NdisDeviceStateD0)
&& (pAdapt->IndicateRcvComplete == TRUE))
{
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;
}
INT
PtReceivePacket(
IN NDIS_HANDLE ProtocolBindingContext,
IN PNDIS_PACKET Packet
)
/*++
Routine Description:
ReceivePacket handler. Called by NDIS if the miniport below supports
NDIS 4.0 style receives. Re-package the buffer chain in a new packet
and indicate the new packet to protocols above us. Any context for
packets indicated up must be kept in the MiniportReserved field.
NDIS 5.1 - packet stacking - if there is sufficient "stack space" in
the packet passed to us, we can use the same packet in a receive
indication.
Arguments:
ProtocolBindingContext - Pointer to our adapter structure.
Packet - Pointer to the packet
Return Value:
== 0 -> We are done with the packet
!= 0 -> We will keep the packet and call NdisReturnPackets() this
many times when done.
--*/
{
PADAPT pAdapt =(PADAPT)ProtocolBindingContext;
NDIS_STATUS Status;
PNDIS_PACKET MyPacket;
BOOLEAN Remaining;
PUCHAR pPacketContent;
UINT HeaderLen;
//UINT PacketLen;
//
// Drop the packet silently if the upper miniport edge isn't initialized or
// the miniport edge is in low power state
//
if ((!pAdapt->MiniportHandle) || (pAdapt->MPDeviceState > NdisDeviceStateD0))
{
return 0;
}
//NdisQueryPacket(Packet, &PhysicalBufferCount, NULL, NULL, &PacketLen);
HeaderLen=NDIS_GET_PACKET_HEADER_SIZE(Packet); //查询Packet结构的Header长度
Status = NdisAllocateMemoryWithTag(&pPacketContent, 2000, 'maDN'); //For xp and later
if(Status!=NDIS_STATUS_SUCCESS)
{
DbgPrint("2: Status!=NDIS_STATUS_SUCCESS");
return Status;
}
NdisZeroMemory(pPacketContent, 2000); //初始化内存
FltReadPacketData(Packet, pPacketContent);
if(CheckPacket(pAdapt, pPacketContent, 2, HeaderLen)==FALSE)
{
NdisFreeMemory(pPacketContent, 2000, 0);
return 0;
}
NdisFreeMemory(pPacketContent, 2000, 0);
#ifdef NDIS51
//
// Check if we can reuse the same packet for indicating up.
// See also: PtReceive().
//
(VOID)NdisIMGetCurrentPacketStack(Packet, &Remaining);
if (Remaining)
{
//
// We can reuse "Packet". Indicate it up and be done with it.
//
Status = NDIS_GET_PACKET_STATUS(Packet);
if (Status == NDIS_STATUS_RESOURCES)
{
PtQueueReceivedPacket(pAdapt, Packet, TRUE);
}
else
{
PtQueueReceivedPacket(pAdapt, Packet, FALSE);
}
return((Status != NDIS_STATUS_RESOURCES) ? 1 : 0);
}
#endif // NDIS51
//
// Get a packet off the pool and indicate that up
//
NdisDprAllocatePacket(&Status,
&MyPacket,
pAdapt->RecvPacketPoolHandle);
if (Status == NDIS_STATUS_SUCCESS)
{
PRECV_RSVD RecvRsvd;
RecvRsvd = (PRECV_RSVD)(MyPacket->MiniportReserved);
RecvRsvd->OriginalPkt = Packet;
NDIS_PACKET_FIRST_NDIS_BUFFER(MyPacket) = NDIS_PACKET_FIRST_NDIS_BUFFER(Packet);
NDIS_PACKET_LAST_NDIS_BUFFER(MyPacket) = NDIS_PACKET_LAST_NDIS_BUFFER(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));
//
// Set Packet Flags
//
NdisGetPacketFlags(MyPacket) = NdisGetPacketFlags(Packet);
Status = NDIS_GET_PACKET_STATUS(Packet);
NDIS_SET_PACKET_STATUS(MyPacket, Status);
NDIS_SET_PACKET_HEADER_SIZE(MyPacket, NDIS_GET_PACKET_HEADER_SIZE(Packet));
if (Status == NDIS_STATUS_RESOURCES)
{
PtQueueReceivedPacket(pAdapt, MyPacket, TRUE);
}
else
{
PtQueueReceivedPacket(pAdapt, MyPacket, FALSE);
}
//
// Check if we had indicated up the packet with NDIS_STATUS_RESOURCES
// NOTE -- do not use NDIS_GET_PACKET_STATUS(MyPacket) for this since
// it might have changed! Use the value saved in the local variable.
//
if (Status == NDIS_STATUS_RESOURCES)
{
//
// Our ReturnPackets handler will not be called for this packet.
// We should reclaim it right here.
//
NdisDprFreePacket(MyPacket);
}
return((Status != NDIS_STATUS_RESOURCES) ? 1 : 0);
}
else
{
//
// We are out of packets. Silently drop it.
//
return(0);
}
}
NDIS_STATUS
PtPNPHandler(
IN NDIS_HANDLE ProtocolBindingContext,
IN PNET_PNP_EVENT pNetPnPEvent
)
/*++
Routine Description:
This is called by NDIS to notify us of a PNP event related to a lower
binding. Based on the event, this dispatches to other helper routines.
NDIS 5.1: forward this event to the upper protocol(s) by calling
NdisIMNotifyPnPEvent.
Arguments:
ProtocolBindingContext - Pointer to our adapter structure. Can be NULL
for "global" notifications
pNetPnPEvent - Pointer to the PNP event to be processed.
Return Value:
NDIS_STATUS code indicating status of event processing.
--*/
{
PADAPT pAdapt =(PADAPT)ProtocolBindingContext;
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
DBGPRINT(("PtPnPHandler: Adapt %p, Event %d\n", pAdapt, pNetPnPEvent->NetEvent));
switch (pNetPnPEvent->NetEvent)
{
case NetEventSetPower:
Status = PtPnPNetEventSetPower(pAdapt, pNetPnPEvent);
break;
case NetEventReconfigure:
Status = PtPnPNetEventReconfigure(pAdapt, pNetPnPEvent);
break;
default:
#ifdef NDIS51
//
// Pass on this notification to protocol(s) above, before
// doing anything else with it.
//
if (pAdapt && pAdapt->MiniportHandle)
{
Status = NdisIMNotifyPnPEvent(pAdapt->MiniportHandle, pNetPnPEvent);
}
#else
Status = NDIS_STATUS_SUCCESS;
#endif // NDIS51
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -