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

📄 miniport.c

📁 网络驱动开发
💻 C
📖 第 1 页 / 共 5 页
字号:
        //
        // Let the miniport below handle these OIDs:
        //
        case OID_PNP_ADD_WAKE_UP_PATTERN:
        case OID_PNP_REMOVE_WAKE_UP_PATTERN:
        case OID_PNP_ENABLE_WAKE_UP:
            bForwardRequest = TRUE;
            break;

        case OID_PNP_SET_POWER:
            //
            // Store new power state and succeed the request.
            //
            *BytesNeeded = sizeof(NDIS_DEVICE_POWER_STATE);
            if (InformationBufferLength < *BytesNeeded)
            {
                Status = NDIS_STATUS_INVALID_LENGTH;
                break;
            }
           
            NewDeviceState = (*(PNDIS_DEVICE_POWER_STATE)InformationBuffer);
            
            //
            // Check if the VELAN adapter goes from lower power state to D0
            // 
            if ((MUX_IS_LOW_POWER_STATE(pVElan->MPDevicePowerState)) 
                    && (!MUX_IS_LOW_POWER_STATE(NewDeviceState)))
            {
                //
                // Indicate the media status is necessary
                // 
                if (pVElan->LastIndicatedStatus != pVElan->LatestUnIndicateStatus)
                {
                    NdisMIndicateStatus(pVElan->MiniportAdapterHandle,
                                        pVElan->LatestUnIndicateStatus,
                                        (PVOID)NULL,
                                        0);
                    NdisMIndicateStatusComplete(pVElan->MiniportAdapterHandle);
                    pVElan->LastIndicatedStatus = pVElan->LatestUnIndicateStatus;
                }
            }
            //
            // Check if the VELAN adapter goes from D0 to lower power state
            // 
            if ((!MUX_IS_LOW_POWER_STATE(pVElan->MPDevicePowerState)) 
                    && (MUX_IS_LOW_POWER_STATE(NewDeviceState)))
            {
                //
                //  Initialize LastUnIndicateStatus 
                // 
                pVElan->LatestUnIndicateStatus = pVElan->LastIndicatedStatus;
            }
            
            NdisMoveMemory(&pVElan->MPDevicePowerState,
                           InformationBuffer,
                           *BytesNeeded);

            DBGPRINT(MUX_INFO, ("SetInfo: VElan %p, new miniport power state --- %d\n",
                    pVElan, pVElan->MPDevicePowerState));

            break;

        case OID_802_3_MULTICAST_LIST:
            Status = MPSetMulticastList(pVElan,
                                        InformationBuffer,
                                        InformationBufferLength,
                                        BytesRead,
                                        BytesNeeded);
            break;

        case OID_GEN_CURRENT_PACKET_FILTER:
            if (InformationBufferLength != sizeof(ULONG))
            {
                Status = NDIS_STATUS_INVALID_LENGTH;
                *BytesNeeded = sizeof(ULONG);
                break;
            }

            NdisMoveMemory(&PacketFilter, InformationBuffer, sizeof(ULONG));
            *BytesRead = sizeof(ULONG);

            Status = MPSetPacketFilter(pVElan,
                                       PacketFilter);
            break;

        case OID_GEN_CURRENT_LOOKAHEAD:
#if IEEE_VLAN_SUPPORT
            //
            // In order to simplify parsing and to avoid excessive
            // copying, we need the tag header also to be present in the
            // lookahead buffer. Make sure that the driver below
            // includes that.
            //
            *(UNALIGNED PULONG)InformationBuffer += VLAN_TAG_HEADER_SIZE;
#endif            
            bForwardRequest = TRUE;
            break;
            
#if IEEE_VLAN_SUPPORT
        case OID_GEN_VLAN_ID:
            if (InformationBufferLength != sizeof(ULONG))
            {
                Status = NDIS_STATUS_INVALID_LENGTH;
                *BytesNeeded = sizeof(ULONG);
                break;
            }
            NdisMoveMemory(&(pVElan->VlanId), InformationBuffer, sizeof(ULONG));
            break;
#endif
            
        default:
            Status = NDIS_STATUS_INVALID_OID;
            break;

    }
    
    if (bForwardRequest == FALSE)
    {
        if (Status == NDIS_STATUS_SUCCESS)
        {
            *BytesRead = InformationBufferLength;
        }
    }
    else
    {
        //
        // Send this request to the binding below.
        //
        Status = MPForwardRequest(pVElan,
                                  NdisRequestSetInformation,
                                  Oid,
                                  InformationBuffer,
                                  InformationBufferLength,
                                  BytesRead,
                                  BytesNeeded);
    }

    return(Status);
}

VOID
MPReturnPacket(
    IN    NDIS_HANDLE             MiniportAdapterContext,
    IN    PNDIS_PACKET            Packet
    )
/*++

Routine Description:

    NDIS Miniport entry point called whenever protocols are done with
    a packet that we had indicated up and they had queued up for returning
    later.

Arguments:

    MiniportAdapterContext    - pointer to VELAN structure
    Packet    - packet being returned.

Return Value:

    None.

--*/
{
    PVELAN              pVElan = (PVELAN)MiniportAdapterContext;
    PNDIS_PACKET        pOriginalPacket;
    PMUX_RECV_RSVD      pRecvRsvd;
    
    pRecvRsvd = MUX_RSVD_FROM_RECV_PACKET(Packet);
    pOriginalPacket = pRecvRsvd->pOriginalPacket;

    //
    // Reclaim our packet.
    //
#if IEEE_VLAN_SUPPORT
    //
    // If we did remove the tag header from the received packet,
    // we would have allocated a buffer to describe the "untagged"
    // header (see PtHandleRcvTagging); free it.
    // 
    if (pRecvRsvd->AllocatedNdisBuffer != NULL)
    {
        ASSERT(pRecvRsvd->AllocatedNdisBuffer == NDIS_PACKET_FIRST_NDIS_BUFFER(Packet));
        NdisFreeBuffer(NDIS_PACKET_FIRST_NDIS_BUFFER(Packet));
    }

#endif
    
    NdisFreePacket(Packet);

    //
    // Return the original packet received at our protocol
    // edge, if any.
    //
    // NOTE that we might end up calling NdisReturnPackets
    // multiple times with the same "lower" packet, based on
    // the number of VELANs to which we had indicated that
    // packet. The number of times we do so should match
    // the return value from our PtReceivePacket handler.
    //
    if (pOriginalPacket != NULL)
    {
        NdisReturnPackets(&pOriginalPacket, 1);
    }
    else
    {
        //
        // If no original packet, then we have been called
        // here to reclaim a packet used to forward up
        // a non-packet receive (see PtReceive). There
        // is nothing more to be done.
        //
    }


    MUX_DECR_PENDING_RECEIVES(pVElan);
}


NDIS_STATUS
MPTransferData(
    OUT PNDIS_PACKET                Packet,
    OUT PUINT                       BytesTransferred,
    IN  NDIS_HANDLE                 MiniportAdapterContext,
    IN  NDIS_HANDLE                 MiniportReceiveContext,
    IN  UINT                        ByteOffset,
    IN  UINT                        BytesToTransfer
    )
/*++

Routine Description:

    Miniport's transfer data handler.  This is called if we had
    indicated receive data using a non-packet API, for e.g. if
    the lookahead buffer did not contain the entire data.

    We need to forward this to the miniport below to that it can
    copy in the rest of the data. We call NdisTransferData to do so.
    However, when that completes (see PtTransferDataComplete), we
    have to get back at the VELAN from which this packet came so that
    we can complete this request with the right MiniportAdapterHandle.
    We therefore allocate a new packet, pointing to the same buffer
    as the packet just passed in, and use reserved space in the packet
    to hold a backpointer to the VELAN from which this came.

Arguments:

    Packet                    Destination packet
    BytesTransferred          Place to return how much data was copied
    MiniportAdapterContext    Pointer to the VELAN structure
    MiniportReceiveContext    Context
    ByteOffset                Offset into the packet for copying data
    BytesToTransfer           How much to copy.

Return Value:

    Status of transfer

--*/
{
    PVELAN          pVElan = (PVELAN)MiniportAdapterContext;
    NDIS_STATUS     Status;
    PNDIS_PACKET    MyPacket;
    PMUX_TD_RSVD    pTDReserved;
#if IEEE_VLAN_SUPPORT
    PMUX_RCV_CONTEXT        pMuxRcvContext;
#endif    
    

    do
    {
        NdisAllocatePacket(&Status,
                           &MyPacket,
                           pVElan->SendPacketPoolHandle);

        if (Status != NDIS_STATUS_SUCCESS)
        {
            break;
        }

        pTDReserved = MUX_RSVD_FROM_TD_PACKET(MyPacket);
        pTDReserved->pOriginalPacket = Packet;
        pTDReserved->pVElan = pVElan;

        NdisGetPacketFlags(MyPacket) = NdisGetPacketFlags(Packet) |
                                        MUX_SEND_PACKET_FLAGS;

        NDIS_PACKET_FIRST_NDIS_BUFFER(MyPacket) = NDIS_PACKET_FIRST_NDIS_BUFFER(Packet);
        NDIS_PACKET_LAST_NDIS_BUFFER(MyPacket) = NDIS_PACKET_LAST_NDIS_BUFFER(Packet);
#ifdef WIN9X
        //
        // Work around the fact that NDIS does not initialize this
        // field on Win9x.
        //
        NDIS_PACKET_VALID_COUNTS(MyPacket) = FALSE;
#endif // WIN9X

#if IEEE_VLAN_SUPPORT
        //
        // Check if the original received packet did contain a
        // VLAN tag header. If so, make sure we get the upcoming
        // call to NdisTransferData to skip the tag header.
        //
        pMuxRcvContext = (PMUX_RCV_CONTEXT)MiniportReceiveContext;
        if (pMuxRcvContext->TagHeaderLen == VLAN_TAG_HEADER_SIZE)
        {
            //
            // There was a tag header in the received packet.
            //
            ByteOffset += VLAN_TAG_HEADER_SIZE;

            //
            // Copy the 8021Q info into the packet
            //
            NDIS_PER_PACKET_INFO_FROM_PACKET(Packet, Ieee8021QInfo) =
                                        pMuxRcvContext->NdisPacket8021QInfo.Value;
        }

        //
        // Get back the lower driver's receive context for this indication.
        //
        MiniportReceiveContext = pMuxRcvContext->MacRcvContext;
#endif
        
        NdisTransferData(&Status,
                         pVElan->pAdapt->BindingHandle,
                         MiniportReceiveContext,
                         ByteOffset,
                         BytesToTransfer,
                         MyPacket,
                         BytesTransferred);
    
        if (Status != NDIS_STATUS_PENDING)
        {
            PtTransferDataComplete(pVElan->pAdapt,
                                   MyPacket,
                                   Status,
                                   *BytesTransferred);

            Status = NDIS_STATUS_PENDING;
        }
    }
    while (FALSE);

    return(Status);
}
    
    

VOID
MPHalt(
    IN    NDIS_HANDLE                MiniportAdapterContext
    )
/*++

Routine Description:

    Halt handler. Add any further clean-up for the VELAN to this
    function.

    We wait for all pending I/O on the VELAN to complete and then
    unlink the VELAN from the adapter.

Arguments:

    MiniportAdapterContext    Pointer to the pVElan

Return Value:

    None.

--*/
{
    PVELAN            pVElan = (PVELAN)MiniportAdapterContext;
    

    DBGPRINT(MUX_LOUD, ("==>MiniportHalt: VELAN %p\n", pVElan));

    //
    // Mark the VELAN so that we don't send down any new requests or
    // sends to the adapter below, or new receives/indications to
    // protocols above.
    //
    pVElan->MiniportHalting = TRUE;

    //
    // Update the packet filter on the underlying adapter if needed.
    //
    if (pVElan->PacketFilter != 0)
    {
        MPSetPacketFilter(pVElan, 0);
    }

    //
    // Wait for any outstanding sends or requests to complete.
    //
    while (pVElan->OutstandingSends)
    {
        DBGPRINT(MUX_INFO, ("MiniportHalt: VELAN %p has %d outstanding sends\n",
                            pVElan, pVElan->OutstandingSends));
        NdisMSleep(20000);
    }

    //
    // Wait for all outstanding indications to be completed and
    // any pended receive packets to be returned to us.
    //
    while (pVElan->OutstandingReceives)
    {
        DBGPRINT(MUX_INFO, ("MiniportHalt: VELAN %p has %d outstanding receives\n",
                            pVElan, pVElan->OutstandingReceives));
        NdisMSleep(20000);
    }

    //
    // Delete the ioctl interface that was created when the miniport
    // was created.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -