📄 protocol.c
字号:
}
VOID
PtPostProcessPnPCapabilities(
IN PVELAN pVElan,
IN PVOID InformationBuffer,
IN ULONG InformationBufferLength
)
/*++
Routine Description:
Postprocess a successfully completed query for OID_PNP_CAPABILITIES.
We modify the returned information slightly before completing
it to the VELAN above.
Arguments:
pVElan - Pointer to VELAN
InformationBuffer - points to buffer for the OID
InformationBufferLength - byte length of the above.
Return Value:
None
--*/
{
PNDIS_PNP_CAPABILITIES pPNPCapabilities;
PNDIS_PM_WAKE_UP_CAPABILITIES pPMstruct;
UNREFERENCED_PARAMETER(pVElan);
if (InformationBufferLength >= sizeof(NDIS_PNP_CAPABILITIES))
{
pPNPCapabilities = (PNDIS_PNP_CAPABILITIES)InformationBuffer;
//
// The following fields must be overwritten by an IM driver.
//
pPMstruct= &pPNPCapabilities->WakeUpCapabilities;
pPMstruct->MinMagicPacketWakeUp = NdisDeviceStateUnspecified;
pPMstruct->MinPatternWakeUp = NdisDeviceStateUnspecified;
pPMstruct->MinLinkChangeWakeUp = NdisDeviceStateUnspecified;
}
}
VOID
PtCompleteBlockingRequest(
IN PADAPT pAdapt,
IN PMUX_NDIS_REQUEST pMuxNdisRequest,
IN NDIS_STATUS Status
)
/*++
Routine Description:
Handle completion of an NDIS request that was originated
by this driver and the calling thread is blocked waiting
for completion.
Arguments:
pAdapt - Adapter on which the request was forwarded
pMuxNdisRequest - super-struct for request
Status - request completion status
Return Value:
None
--*/
{
UNREFERENCED_PARAMETER(pAdapt);
pMuxNdisRequest->Status = Status;
//
// The request was originated from this driver. Wake up the
// thread blocked for its completion.
//
pMuxNdisRequest->Status = Status;
NdisSetEvent(&pMuxNdisRequest->Event);
}
VOID
PtDiscardCompletedRequest(
IN PADAPT pAdapt,
IN PMUX_NDIS_REQUEST pMuxNdisRequest,
IN NDIS_STATUS Status
)
/*++
Routine Description:
Handle completion of an NDIS request that was originated
by this driver - the request is to be discarded.
Arguments:
pAdapt - Adapter on which the request was forwarded
pMuxNdisRequest - super-struct for request
Status - request completion status
Return Value:
None
--*/
{
UNREFERENCED_PARAMETER(pAdapt);
UNREFERENCED_PARAMETER(Status);
NdisFreeMemory(pMuxNdisRequest, sizeof(MUX_NDIS_REQUEST), 0);
}
VOID
PtStatus(
IN NDIS_HANDLE ProtocolBindingContext,
IN NDIS_STATUS GeneralStatus,
IN PVOID StatusBuffer,
IN UINT StatusBufferSize
)
/*++
Routine Description:
Handle a status indication on the lower binding (ADAPT).
If this is a media status indication, we also pass this
on to all associated VELANs.
Arguments:
ProtocolBindingContext Pointer to the adapter structure
GeneralStatus Status code
StatusBuffer Status buffer
StatusBufferSize Size of the status buffer
Return Value:
None
--*/
{
PADAPT pAdapt = (PADAPT)ProtocolBindingContext;
PLIST_ENTRY p;
PVELAN pVElan;
LOCK_STATE LockState;
DBGPRINT(MUX_LOUD, ("PtStatus: Adapt %p, Status %x\n", pAdapt, GeneralStatus));
do
{
//
// Ignore status indications that we aren't going
// to pass up.
//
if ((GeneralStatus != NDIS_STATUS_MEDIA_CONNECT) &&
(GeneralStatus != NDIS_STATUS_MEDIA_DISCONNECT))
{
break;
}
MUX_ACQUIRE_ADAPT_READ_LOCK(pAdapt, &LockState);
for (p = pAdapt->VElanList.Flink;
p != &pAdapt->VElanList;
p = p->Flink)
{
pVElan = CONTAINING_RECORD(p, VELAN, Link);
MUX_INCR_PENDING_RECEIVES(pVElan);
//
// Should the indication be sent on this VELAN?
//
if ((pVElan->MiniportInitPending) ||
(pVElan->MiniportHalting) ||
(pVElan->MiniportAdapterHandle == NULL) ||
MUX_IS_LOW_POWER_STATE(pVElan->MPDevicePowerState))
{
MUX_DECR_PENDING_RECEIVES(pVElan);
if (MUX_IS_LOW_POWER_STATE(pVElan->MPDevicePowerState))
{
//
// Keep track of the lastest status to indicated when VELAN power is on
//
ASSERT((GeneralStatus == NDIS_STATUS_MEDIA_CONNECT) || (GeneralStatus == NDIS_STATUS_MEDIA_DISCONNECT));
pVElan->LatestUnIndicateStatus = GeneralStatus;
}
continue;
}
//
// Save the last indicated status when
pVElan->LastIndicatedStatus = GeneralStatus;
NdisMIndicateStatus(pVElan->MiniportAdapterHandle,
GeneralStatus,
StatusBuffer,
StatusBufferSize);
//
// Mark this so that we forward a status complete
// indication as well.
//
pVElan->IndicateStatusComplete = TRUE;
MUX_DECR_PENDING_RECEIVES(pVElan);
}
MUX_RELEASE_ADAPT_READ_LOCK(pAdapt, &LockState);
}
while (FALSE);
}
VOID
PtStatusComplete(
IN NDIS_HANDLE ProtocolBindingContext
)
/*++
Routine Description:
Marks the end of a status indication. Pass it on to
associated VELANs if necessary.
Arguments:
ProtocolBindingContext - pointer to ADAPT
Return Value:
None.
--*/
{
PADAPT pAdapt = (PADAPT)ProtocolBindingContext;
PLIST_ENTRY p;
PVELAN pVElan;
LOCK_STATE LockState;
MUX_ACQUIRE_ADAPT_READ_LOCK(pAdapt, &LockState);
for (p = pAdapt->VElanList.Flink;
p != &pAdapt->VElanList;
p = p->Flink)
{
pVElan = CONTAINING_RECORD(p, VELAN, Link);
MUX_INCR_PENDING_RECEIVES(pVElan);
//
// Should this indication be sent on this VELAN?
//
if ((pVElan->MiniportInitPending) ||
(pVElan->MiniportHalting) ||
(pVElan->MiniportAdapterHandle == NULL) ||
(!pVElan->IndicateStatusComplete) ||
(MUX_IS_LOW_POWER_STATE(pVElan->MPDevicePowerState)))
{
MUX_DECR_PENDING_RECEIVES(pVElan);
continue;
}
pVElan->IndicateStatusComplete = FALSE;
NdisMIndicateStatusComplete(pVElan->MiniportAdapterHandle);
MUX_DECR_PENDING_RECEIVES(pVElan);
}
MUX_RELEASE_ADAPT_READ_LOCK(pAdapt, &LockState);
}
VOID
PtSendComplete(
IN NDIS_HANDLE ProtocolBindingContext,
IN PNDIS_PACKET Packet,
IN NDIS_STATUS Status
)
/*++
Routine Description:
Called by NDIS when the miniport below had completed a send.
We complete the corresponding upper-edge send this represents.
The packet being completed belongs to our send packet pool,
however we store a pointer to the original packet this represents,
in the packet's reserved field.
Arguments:
ProtocolBindingContext - Points to ADAPT structure
Packet - Packet being completed by the lower miniport
Status - status of send
Return Value:
None
--*/
{
PVELAN pVElan;
PMUX_SEND_RSVD pSendReserved;
PNDIS_PACKET OriginalPacket;
#if IEEE_VLAN_SUPPORT
NDIS_PACKET_8021Q_INFO NdisPacket8021qInfo;
BOOLEAN IsTagInsert;
PNDIS_BUFFER pNdisBuffer;
PVOID pVa;
ULONG BufferLength;
#endif
UNREFERENCED_PARAMETER(ProtocolBindingContext);
pSendReserved = MUX_RSVD_FROM_SEND_PACKET(Packet);
OriginalPacket = pSendReserved->pOriginalPacket;
pVElan = pSendReserved->pVElan;
#if IEEE_VLAN_SUPPORT
//
// Check if we had inserted a tag header
//
IsTagInsert = TRUE;
NdisPacket8021qInfo.Value = NDIS_PER_PACKET_INFO_FROM_PACKET(
OriginalPacket,
Ieee8021QInfo);
// A tag is inserted IFF VLAN ID of the virtual miniport is -not- 0,
// thus the miniport should act like it doesn't support VELAN tag processing
if (pVElan->VlanId == 0)
{
IsTagInsert = FALSE;
}
#endif
#ifndef WIN9X
NdisIMCopySendCompletePerPacketInfo(OriginalPacket, Packet);
#endif
//
// Update statistics.
//
if (Status == NDIS_STATUS_SUCCESS)
{
MUX_INCR_STATISTICS64(&pVElan->GoodTransmits);
}
else
{
MUX_INCR_STATISTICS(&pVElan->TransmitFailuresOther);
}
//
// Complete the original send.
//
NdisMSendComplete(pVElan->MiniportAdapterHandle,
OriginalPacket,
Status);
#if IEEE_VLAN_SUPPORT
//
// If we had inserted a tag header, then remove the header
// buffer and free it. We would also have created a new
// NDIS buffer to map part of the original packet's header;
// free that, too.
//
if (IsTagInsert)
{
pNdisBuffer = NDIS_PACKET_FIRST_NDIS_BUFFER(Packet);
#ifdef NDIS51_MINIPORT
NdisQueryBufferSafe(pNdisBuffer, &pVa, (PUINT)&BufferLength, NormalPagePriority);
#else
NdisQueryBuffer(pNdisBuffer, &pVa, &BufferLength);
#endif
if (pVa != NULL)
{
NdisFreeToNPagedLookasideList(&pVElan->TagLookaside, pVa);
}
NdisFreeBuffer(NDIS_BUFFER_LINKAGE(pNdisBuffer));
NdisFreeBuffer (pNdisBuffer);
}
#endif
//
// Free our packet.
//
NdisFreePacket(Packet);
//
// Note down send-completion.
//
MUX_DECR_PENDING_SENDS(pVElan);
}
VOID
PtTransferDataComplete(
IN NDIS_HANDLE ProtocolBindingContext,
IN PNDIS_PACKET Packet,
IN NDIS_STATUS Status,
IN UINT BytesTransferred
)
/*++
Routine Description:
Entry point called by NDIS to indicate completion of a call by us
to NdisTransferData. We locate the original packet and VELAN on
which our TransferData function (see MPTransferData) was called,
and complete the original request.
Arguments:
ProtocolBindingContext - lower binding context, pointer to ADAPT
Packet - Packet allocated by us
Status - Completion status
BytesTransferred - Number of bytes copied in
Return Value:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -