⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 protocol.c

📁 网络驱动开发
💻 C
📖 第 1 页 / 共 5 页
字号:

}



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 + -