📄 2005-03-21_protocol.c
字号:
MyPacket->Private.Head->Next=NULL;
MyPacket->Private.Tail=NULL;
OffsetSize = HeaderBufferSize + LookAheadBufferSize;
// 分配包描述符 MyPacket1。
NdisDprAllocatePacket(&Status, &MyPacket1, pAdapt->RecvPacketPoolHandle);
// 分配缓冲描述符 pBakBuffer,与 pBakContent 指向的内存关联。
NdisAllocateBuffer(&Status, &pBakBuffer, pAdapt->RecvBufferPoolHandle, pBakContent, OffsetSize);
// 关联包描述符 MyPacket1 与缓冲描述符 pBakBuffer。
NdisChainBufferAtFront(MyPacket1, pBakBuffer);
Rsvd = (PRSVD)(MyPacket->MiniportReserved);
Rsvd->OriginalPkt = (PNDIS_PACKET)MyPacket1;
NDIS_SET_PACKET_HEADER_SIZE(MyPacket, HeaderBufferSize);
// 取得 LookAheadBuffer 之后的数据
NdisTransferData(&Status,
pAdapt->BindingHandle,
MacReceiveContext,
LookAheadBufferSize, // 数据起始地址
PacketSize-LookAheadBufferSize, // 字节数
MyPacket,
&BytesTransferred);
if(Status != NDIS_STATUS_PENDING)
{
PtTransferDataComplete((NDIS_HANDLE)pAdapt, MyPacket, Status, BytesTransferred);
}
break;
}
pAdapt->IndicateRcvComplete = TRUE;
} 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 buffers.
Arguments:
ProtocolBindingContext Pointer to our adapter structure.
Return Value:
None
--*/
{
PADAPT pAdapt =(PADAPT)ProtocolBindingContext;
//
// We should not be getting Receives on a Secondary, this is just specific to our LBFO driver
//
if(pAdapt->isSecondary)
{
DBGPRINT("PASSTHRU GETTING RECEIVES ON SECONDARY\n");
ASSERT(0);
}
if((pAdapt->MiniportHandle != NULL) && pAdapt->IndicateRcvComplete)
{
switch(pAdapt->Medium)
{
case NdisMedium802_3:
NdisMEthIndicateReceiveComplete(pAdapt->MiniportHandle);
break;
case NdisMedium802_5:
NdisMTrIndicateReceiveComplete(pAdapt->MiniportHandle);
break;
case NdisMediumFddi:
NdisMFddiIndicateReceiveComplete(pAdapt->MiniportHandle);
break;
default:
ASSERT(0);
break;
}
}
pAdapt->IndicateRcvComplete = FALSE;
}
INT
PtReceivePacket(
IN NDIS_HANDLE ProtocolBindingContext,
IN PNDIS_PACKET Packet
)
/*++
Routine Description:
ReceivePacket handler. Called up by the miniport below when it supports NDIS 4.0 style receives.
Re-package the packet and hand it back to NDIS for protocols above us. The re-package part is
important since NDIS uses the WrapperReserved part of the packet for its own book-keeping. Also
the re-packaging works differently when packets flow-up or down. In the up-path(here) the protocol
reserved is owned by the protocol above. We need to use the miniport reserved here.
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;
PRSVD Resvd;
if(!pAdapt->MiniportHandle)
{
return 0;
}
//
// We should not be getting Receives on a Secondary, this is just specific to our LBFO driver
//
if(pAdapt->isSecondary)
{
DBGPRINT("PASSTHRU GETTING RECEIVES ON SECONDARY\n");
ASSERT(0);
}
//
// Get a packet off the pool and indicate that up
//
NdisDprAllocatePacket(&Status,
&MyPacket,
pAdapt->RecvPacketPoolHandle);
if(Status == NDIS_STATUS_SUCCESS)
{
Resvd =(PRSVD)(MyPacket->MiniportReserved);
Resvd->OriginalPkt = Packet;
MyPacket->Private.Head = Packet->Private.Head;
MyPacket->Private.Tail = Packet->Private.Tail;
//
// Get the original packet(it could be the same packet as one received or a different one
// based on # of layered MPs) and set it on the indicated packet so the OOB stuff is visible
// correctly at the top.
//
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));
NdisMIndicateReceivePacket(pAdapt->MiniportHandle, &MyPacket, 1);
if(Status == NDIS_STATUS_RESOURCES)
{
NdisDprFreePacket(MyPacket);
}
return((Status != NDIS_STATUS_RESOURCES) ? 1 : 0);
}
else
{
//
// We are out of packets. Silently drop it. Alternatively we can deal with it:
// - By keeping separate send and receive pools
// - Dynamically allocate more pools as needed and free them when not needed
//
return(0);
}
}
NDIS_STATUS
PtPNPHandler(
IN NDIS_HANDLE ProtocolBindingContext,
IN PNET_PNP_EVENT pNetPnPEvent
)
/*++
Routine Description:
This is the Protocol PNP handlers. All PNP Related OIDS(requests) are routed to this function
If the Power of the SetPower PNP Event is received, then the new power state is copied to
the internal state of the Passthru driver. Need to complete all sends and requests before
returning from this function.
Arguments:
ProtocolBindingContext Pointer to our adapter structure.
pNetPnPEvent Pointer to a Net_PnP_Event
Return Value:
NDIS_STATUS_SUCCESS: as we do not do much here
--*/
{
PADAPT pAdapt =(PADAPT)ProtocolBindingContext;
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
DBGPRINT ("PtPnPHandler");
//
// This will happen when all entities in the system need to be notified
//
switch(pNetPnPEvent->NetEvent)
{
case NetEventSetPower :
Status = PtPnPNetEventSetPower(pAdapt, pNetPnPEvent);
break;
case NetEventReconfigure :
Status = PtPnPNetEventReconfigure(pAdapt, (PCWSTR)pNetPnPEvent->Buffer);
break;
default :
Status = NDIS_STATUS_SUCCESS;
break;
}
return Status;
}
NDIS_STATUS
PtPnPNetEventReconfigure(
IN PADAPT pAdapt,
IN PCWSTR pBundleString
)
/*++
Routine Description:
This is the function that will be called by the PNP handler whenever a PNPNetEventReconfigure happens
Protocol will read the Bundle from the registry.
if pAdapt is NULL, then a global reconfig event has been issued. We should use this to ensure that our protocol
is bound to its underlying miniports
Simple Algorithm for Bundles:
If bundleId was not changed then exit.
if pAdapt is the secondary of a bundle, promote pAdapt.
If pAdapt is the primary of a bundle, promote the secondary miniport
Now check to see if the new bundleId causes us to be a part of another bundle
Walk through the list attach pAdapt to a miniport that has the same bundleId.
If there is a Device Instantiated with the same bundle ID then we will become the secondary of that miniport
Arguments:
ProtocolBindingContext Pointer to our adapter structure.
Return Value:
NDIS_STATUS_SUCCESS: as we do not do much here
--*/
{
NDIS_STATUS BundleStatus = NDIS_STATUS_SUCCESS;
NDIS_STRING NewBundleUniString;
if(pAdapt == NULL)
{
NdisReEnumerateProtocolBindings (ProtHandle);
return BundleStatus;
}
if (pBundleString == NULL)
{
return BundleStatus;
}
NdisInitUnicodeString( &NewBundleUniString, pBundleString);
do
{
//
// If the bundle Identifier was not changed, do not do anything
//
if(NdisEqualUnicodeString(&NewBundleUniString, &pAdapt->BundleUniString, TRUE))
{
break;
}
//
// We have a new bundle id , copy it and do the necessary bundling work
//
RtlCopyUnicodeString(&pAdapt->BundleUniString , &NewBundleUniString);
//
// If we are part of a bundle and our bundle id was changed, either the primary or the secondary
// will get promoted
// If we are the secondary of a bundle promote ourselves
//
if(pAdapt->isSecondary)
{
PADAPT pPrimaryAdapt = pAdapt->pPrimaryAdapt;
BundleStatus = MPPromoteSecondary(pAdapt);
if(BundleStatus != NDIS_STATUS_SUCCESS)
{
ASSERT(0);
break;
}
//
// resetting all the internal variables of the primary Adapter structure
//
pPrimaryAdapt->pPrimaryAdapt = pPrimaryAdapt;
pPrimaryAdapt->pSecondaryAdapt = pPrimaryAdapt;
pPrimaryAdapt->isSecondary = FALSE;
}
else
{
//
// The BundleId has changed. If we are the primary of a bundle,
// then we need to promote the secondary
//
if(pAdapt->pSecondaryAdapt != pAdapt)
{
BundleStatus = MPPromoteSecondary(pAdapt->pSecondaryAdapt);
if(BundleStatus != NDIS_STATUS_SUCCESS)
{
ASSERT(0);
break;
}
//
// resetting all our internal variables
//
pAdapt->pSecondaryAdapt = pAdapt;
pAdapt->pPrimaryAdapt = pAdapt;
pAdapt->isSecondary = FALSE ;
}
}
//
// Now we need to see if the new bundle ID makes the Passthru part of another bundle
// If so. then set the current pAdapt as the secondary
//
BundleStatus = MPBundleSearchAndSetSecondary(pAdapt);
} while(FALSE) ;
DBGPRINT("<==PtPNPNetEventReconfigure\n");
return BundleStatus;
}
NDIS_STATUS
PtPnPNetEventSetPower(
IN PADAPT pAdapt,
IN PNET_PNP_EVENT pNetPnPEvent
)
/*++
Routine Description:
Sets the PowerState to the required level. Waits for all outstanding Sends and requests to complete
Arguments:
pAdapt - Pointer to the adpater structure
pNetPnpEvent - The Net Pnp Event. this contains the new device state
Return Value:
NDIS_STATUS_SUCCESS: If the device successfully changed its power state
--*/
{
PNDIS_DEVICE_POWER_STATE pDeviceState =(PNDIS_DEVICE_POWER_STATE)(pNetPnPEvent->Buffer);
NDIS_DEVICE_POWER_STATE PrevDeviceState = pAdapt->PTDeviceState;
NDIS_STATUS Status ;
//
// Set the Internal Device State, this blocks all new sends or receives
//
pAdapt->PTDeviceState = *pDeviceState;
//
// if we are being sent to standby, block for outstanding requests and sends
//
if(*pDeviceState > NdisDeviceStateD0)
{
//
// If the physical miniport is going to standby, fail all incoming requests
//
if (PrevDeviceState == NdisDeviceStateD0)
{
pAdapt->StandingBy = TRUE;
}
while(NdisPacketPoolUsage(pAdapt->SendPacketPoolHandle) != 0)
{
//
// sleep till outstanding sends complete
//
NdisMSleep(10);
}
while(pAdapt->OutstandingRequests == TRUE)
{
//
// sleep till outstanding requests complete
//
NdisMSleep(10);
}
ASSERT(NdisPacketPoolUsage(pAdapt->SendPacketPoolHandle) == 0);
ASSERT(pAdapt->OutstandingRequests == FALSE);
}
else
{
//
// The protocol is being turned on. A pending request must be completed
//
if (pAdapt->QueuedRequest == TRUE)
{
pAdapt->QueuedRequest = FALSE;
NdisRequest(&Status,
pAdapt->BindingHandle,
&pAdapt->Request);
//
// The underlying miniport completed the request synchronously, the IM
// needs to complete the request which it had pended earlier
//
if (Status != NDIS_STATUS_PENDING)
{
PtRequestComplete(pAdapt,
&pAdapt->Request,
Status);
}
}
//
// If the physical miniport is powering up (from Low power state to D0),
// clear the flag
//
if (PrevDeviceState > NdisDeviceStateD0)
{
pAdapt->StandingBy = FALSE;
}
}
Status = NDIS_STATUS_SUCCESS;
return Status;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -