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

📄 miniport.c

📁 网络驱动开发
💻 C
📖 第 1 页 / 共 5 页
字号:
        0x02 | (((UCHAR)pVElan->VElanNumber & 0x3f) << 3);

    ETH_COPY_NETWORK_ADDRESS(
            pVElan->CurrentAddress,
            pVElan->PermanentAddress);
    
    DBGPRINT(MUX_LOUD, ("%d CurrentAddress %s\n",
        pVElan->VElanNumber, MacAddrToString(&pVElan->CurrentAddress)));
    DBGPRINT(MUX_LOUD, ("%d PermanentAddress  %s\n",
        pVElan->VElanNumber, MacAddrToString(&pVElan->PermanentAddress)));

}


#ifdef NDIS51_MINIPORT

VOID
MPCancelSendPackets(
    IN NDIS_HANDLE              MiniportAdapterContext,
    IN PVOID                    CancelId
    )
/*++

Routine Description:

    The miniport entry point to handle cancellation of all send packets
    that match the given CancelId. If we have queued any packets that match
    this, then we should dequeue them and call NdisMSendComplete for all
    such packets, with a status of NDIS_STATUS_REQUEST_ABORTED.

    We should also call NdisCancelSendPackets in turn, on each lower binding
    that this adapter corresponds to. This is to let miniports below cancel
    any matching packets.

Arguments:

    MiniportAdapterContext    - pointer to VELAN structure
    CancelId    - ID of packets to be cancelled.

Return Value:

    None

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

    //
    // If we queue packets on our VELAN/adapter structure, this would be 
    // the place to acquire a spinlock to it, unlink any packets whose
    // Id matches CancelId, release the spinlock and call NdisMSendComplete
    // with NDIS_STATUS_REQUEST_ABORTED for all unlinked packets.
    //

    //
    // Next, pass this down so that we let the miniport(s) below cancel
    // any packets that they might have queued.
    //
    NdisCancelSendPackets(pVElan->pAdapt->BindingHandle, CancelId);

    return;
}

VOID
MPDevicePnPEvent(
    IN NDIS_HANDLE              MiniportAdapterContext,
    IN NDIS_DEVICE_PNP_EVENT    DevicePnPEvent,
    IN PVOID                    InformationBuffer,
    IN ULONG                    InformationBufferLength
    )
/*++

Routine Description:

    This handler is called to notify us of PnP events directed to
    our miniport device object.

Arguments:

    MiniportAdapterContext - pointer to VELAN structure
    DevicePnPEvent - the event
    InformationBuffer - Points to additional event-specific information
    InformationBufferLength - length of above

Return Value:

    None
--*/
{
    // TBD - add code/comments about processing this.

	UNREFERENCED_PARAMETER(MiniportAdapterContext);
    UNREFERENCED_PARAMETER(DevicePnPEvent);
    UNREFERENCED_PARAMETER(InformationBuffer);
    UNREFERENCED_PARAMETER(InformationBufferLength);
    
    return;
}


VOID
MPAdapterShutdown(
    IN NDIS_HANDLE              MiniportAdapterContext
    )
/*++

Routine Description:

    This handler is called to notify us of an impending system shutdown.
    Since this is not a hardware driver, there isn't anything specific
    we need to do about this.

Arguments:

    MiniportAdapterContext  - pointer to VELAN structure

Return Value:

    None
--*/
{
	UNREFERENCED_PARAMETER(MiniportAdapterContext);
	
    return;
}


#endif // NDIS51_MINIPORT

VOID
MPUnload(
    IN    PDRIVER_OBJECT        DriverObject
    )
{
    NDIS_STATUS Status;
    
#if !DBG
    UNREFERENCED_PARAMETER(DriverObject);
#endif
    
    DBGPRINT(MUX_LOUD, ("==> MPUnload: DriverObj %p\n", DriverObject));  
    NdisDeregisterProtocol(&Status, ProtHandle);
    DBGPRINT(MUX_LOUD, ("<== MPUnload \n"));    
}

#if IEEE_VLAN_SUPPORT
NDIS_STATUS
MPHandleSendTagging(
    IN  PVELAN              pVElan,
    IN  PNDIS_PACKET        Packet,
    IN  OUT PNDIS_PACKET    MyPacket
    )
/*++

Routine Description:

    This function is called when the driver supports IEEE802Q tagging.
    It checks the packet to be sent on a VELAN and inserts a tag header
    if necessary.

Arguments:

    PVELAN  - pointer to VELAN structure
    Packet - pointer to original packet
    MyPacket - pointer to the new allocated packet
    
Return Value:

    NDIS_STATUS_SUCCESS if the packet was successfully parsed
    and hence should be passed down to the lower driver. NDIS_STATUS_XXX
    otherwise.
    
--*/
{
    NDIS_PACKET_8021Q_INFO      NdisPacket8021qInfo;
    PVOID                       pEthTagBuffer;
    PNDIS_BUFFER                pNdisBuffer;
    PVOID                       pVa;
    ULONG                       BufferLength;
    PNDIS_BUFFER                pFirstBuffer;
    PNDIS_BUFFER                pSecondBuffer;
    NDIS_STATUS                 Status;
    NDIS_STATUS                 Status2;
    PVOID                       pStartVa = NULL;
    BOOLEAN                     IsFirstVa;
    PVLAN_TAG_HEADER            pTagHeader;
    PUSHORT                     pTpid;
    ULONG                       BytesToSkip;
    PUSHORT                     pTypeLength;
    //
    // Add tag header here
    //
    Status = NDIS_STATUS_SUCCESS;
    
    NdisPacket8021qInfo.Value =  NDIS_PER_PACKET_INFO_FROM_PACKET(
                                                            MyPacket,         
                                                            Ieee8021QInfo);
            
    do
    {
        //
        // If the vlan ID of the virtual miniport is 0, the miniport should act like it doesn't
        // support VELAN tag processing
        // 
        if (pVElan->VlanId == 0)
        {
            break;
        }
        //
        // Insert a tag only if we have a configured VLAN ID
        //
            
        //
        // We don't support E-RIF
        // 
        if (NdisPacket8021qInfo.TagHeader.CanonicalFormatId)
        {
            //
            // skip the packet, return NDIS_STATUS_FAILURE
            //
            Status = NDIS_STATUS_INVALID_PACKET;
            break;
        }

        //
        // The Vlan Id must be the same as the configured VLAN ID if it is non-zero
        // 
        if ((NdisPacket8021qInfo.TagHeader.VlanId)
                && (NdisPacket8021qInfo.TagHeader.VlanId != pVElan->VlanId))
        {
            Status = NDIS_STATUS_INVALID_PACKET;
            break;
        }
                
        //
        // Find the virtual address after the Ethernet Header
        //
        BytesToSkip = ETH_HEADER_SIZE;
        pNdisBuffer = NDIS_PACKET_FIRST_NDIS_BUFFER(Packet);
        IsFirstVa = TRUE;
            
        //
        // Assume the Ethernet Header is in the first buffer of the packet.
        // The following loop is to find the start address of the data after
        // the ethernet header. This may be either in the first NDIS buffer
        // or in the second.
        // 
        while (TRUE)
        {
#ifdef NDIS51_MINIPORT
            NdisQueryBufferSafe(pNdisBuffer, &pVa, (PUINT)&BufferLength, NormalPagePriority);
#else
            NdisQueryBuffer(pNdisBuffer, &pVa, &BufferLength);
#endif
            //
            // The query can fail if the system is low on resources.
            // 
            if (pVa == NULL)
            {
                break;
            }

            //
            // Remember the start of the ethernet header for later.
            // 
            if (IsFirstVa)
            {
                pStartVa = pVa;
                IsFirstVa = FALSE;
            }

            //
            // Have we gone far enough into the packet?
            // 
            if (BytesToSkip == 0)
            {
                break;
            }

            //
            // Does the current buffer contain bytes past the Ethernet
            // header? If so, stop.
            // 
            if (BufferLength > BytesToSkip)
            {
                pVa = (PVOID)((PUCHAR)pVa + BytesToSkip);
                BufferLength -= BytesToSkip;
                break;
            }

            //
            // We haven't gone past the Ethernet header yet, so go
            // to the next buffer.
            //
            BytesToSkip -= BufferLength;
            pNdisBuffer = NDIS_BUFFER_LINKAGE(pNdisBuffer);
        }

        if (pVa == NULL)
        {
            Status = NDIS_STATUS_RESOURCES;
            break;
        }

        //
        // Allocate space for the Ethernet + VLAN tag header.
        // 
        pEthTagBuffer = NdisAllocateFromNPagedLookasideList(&pVElan->TagLookaside);
            
        //
        // Memory allocation failed, can't send out the packet
        // 
        if (pEthTagBuffer == NULL)
        {
            Status = NDIS_STATUS_RESOURCES;
            break;
        }

        //
        // Allocate NDIS buffers for the Ethernet + VLAN tag header and
        // the data that follows these.
        //
        NdisAllocateBuffer(&Status,
                            &pSecondBuffer,
                            pVElan->BufferPoolHandle,
                            pVa,    // byte following the Eth+tag headers
                            BufferLength);
        
        NdisAllocateBuffer(&Status2,
                            &pFirstBuffer,
                            pVElan->BufferPoolHandle,
                            pEthTagBuffer,
                            ETH_HEADER_SIZE + VLAN_TAG_HEADER_SIZE);

        if (Status != NDIS_STATUS_SUCCESS || Status2 != NDIS_STATUS_SUCCESS)
        {
            //
            // One of the buffer allocations failed.
            //
            if (Status == NDIS_STATUS_SUCCESS)
            {
                NdisFreeBuffer(pSecondBuffer);
            }   
        
            if (Status2 == NDIS_STATUS_SUCCESS)
            {
                NdisFreeBuffer(pFirstBuffer);
            }

            NdisFreeToNPagedLookasideList(&pVElan->TagLookaside, pEthTagBuffer);
        
            Status = NDIS_STATUS_RESOURCES;
            break;
        }

        //
        // All allocations were successful, now prepare the packet
        // to be sent down to the lower driver.
        //
        NDIS_PACKET_FIRST_NDIS_BUFFER(MyPacket) = NDIS_BUFFER_LINKAGE(pNdisBuffer);
        NdisChainBufferAtFront(MyPacket, pSecondBuffer)
        NdisChainBufferAtFront(MyPacket, pFirstBuffer)
        
        //
        // Prepare the Ethernet and tag headers.
        //
        NdisMoveMemory(pEthTagBuffer, pStartVa, 2 * ETH_LENGTH_OF_ADDRESS);
        pTpid = (PUSHORT)((PUCHAR)pEthTagBuffer + 2 * ETH_LENGTH_OF_ADDRESS);
        *pTpid = TPID;
        pTagHeader = (PVLAN_TAG_HEADER)(pTpid + 1);
    
        //
        // Write Ieee 802Q info to packet frame
        // 
        INITIALIZE_TAG_HEADER_TO_ZERO(pTagHeader);
        if (NdisPacket8021qInfo.Value)
        {
            SET_USER_PRIORITY_TO_TAG(pTagHeader, NdisPacket8021qInfo.TagHeader.UserPriority);
        }
        else
        {
            SET_USER_PRIORITY_TO_TAG(pTagHeader, 0);
        }

        SET_CANONICAL_FORMAT_ID_TO_TAG (pTagHeader, 0);
            
        if (NdisPacket8021qInfo.TagHeader.VlanId)
        {
            SET_VLAN_ID_TO_TAG (pTagHeader, NdisPacket8021qInfo.TagHeader.VlanId);
        }
        else
        {
            SET_VLAN_ID_TO_TAG (pTagHeader, pVElan->VlanId);
        }   

        pTypeLength = (PUSHORT)((PUCHAR)pTagHeader + sizeof(pTagHeader->TagInfo));
        *pTypeLength = *((PUSHORT)((PUCHAR)pStartVa + 2 * ETH_LENGTH_OF_ADDRESS));

        //
        // Clear the Ieee8021QInfo field in packet being sent down
        // to prevent double tag insertion!
        // 
        NDIS_PER_PACKET_INFO_FROM_PACKET(MyPacket, Ieee8021QInfo) = 0;
      
    }
    while (FALSE);
    
    return Status;
}
    
#endif // IEEE_VLAN_SUPPORT 
                

⌨️ 快捷键说明

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