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

📄 recv.c

📁 ndis windows网络驱动程序的范例
💻 C
📖 第 1 页 / 共 2 页
字号:
    NDIS_STATUS OurPacketStatus;
    UINT BytesTransferred;
    LONGLONG TimeSent;
    LONGLONG TimeReceived;
    PUCHAR MediaArea;
    UINT MediaSizeNeeded;
    PULONG ErrorCounter;

    IMStructAssert( Adapter );

    //
    // return this packet now if we're unable to deal with it right now
    //

    NdisAcquireSpinLock( &Adapter->Lock );

    if ( Adapter->IMMPState & ADAPTER_STATE_RUNNING ) {

        Status = NDIS_STATUS_SUCCESS;
        ++Adapter->RefCount;
        ImDbgOut( DBG_TRACE, DBG_REFCNTS, ("ClReceiveIndication (%08X) +Adapter:h %2d\n", Adapter, Adapter->RefCount));
    } else {

        Status = NDIS_STATUS_NOT_ACCEPTED;
       ImDbgOut( DBG_TRACE, DBG_REFCNTS, ("ClReceiveIndication: (%08X) +Adapter: Packet not accepted\n", Adapter));

    }

    NdisReleaseSpinLock( &Adapter->Lock );

    if ( !NT_SUCCESS( Status )) {
        return Status;
    }

    //
    // get a packet
    //

    PacketEntry = NdisInterlockedPopEntrySList( &Adapter->PacketSList, &Adapter->PacketSListLock );

    if ( PacketEntry == NULL ) {

        //
        // out of resources. indicate that we're not hanging onto the packet
        //

        ImDbgOut(DBG_FAILURE, DBG_RECEIVE, ("CLReceiveIndication: Out Of MP Packets!!!\n" ));

        InterlockedIncrement( &Adapter->Stats.OutOfPackets );
        DerefAdapter( Adapter );

        return NDIS_STATUS_NOT_ACCEPTED;
    }

    OurPacket = CONTAINING_RECORD( PacketEntry, NDIS_PACKET, ProtocolReserved );

    IMAssert( OurPacket->Private.Head == NULL );

    //
    // if this was the last packet on the list, then let NDIS know this so we'll get
    // this one back pretty quick
    //

    if ( NdisQueryDepthSList( &Adapter->PacketSList ) == 0 ) {

        OurPacketStatus = NDIS_STATUS_RESOURCES;
    } else {
        OurPacketStatus = NDIS_STATUS_SUCCESS;
    }

    NDIS_SET_PACKET_STATUS( OurPacket, OurPacketStatus );

    //
    // MPs might indicate more data in their lookahead buffers than what they
    // reported in OID_GEN_MAXIMUM_LOOKAHEAD. If that is the case, then use
    // a residual buffer which is the full frame size.
    //

    if (( HeaderBufferSize + LookaheadBufferSize ) > Adapter->LookaheadBufferSize ) {

        SList = &Adapter->ResidualSList;
        SListLock = &Adapter->ResidualSListLock;
        ErrorCounter = &Adapter->Stats.OutOfResidualBuffers;
    } else {
        SList = &Adapter->LookaheadSList;
        SListLock = &Adapter->LookaheadSListLock;
        ErrorCounter = &Adapter->Stats.OutOfLookaheadBuffers;
    }

    LookaheadEntry = NdisInterlockedPopEntrySList( SList, SListLock );

    if ( LookaheadEntry == NULL ) {

        ImDbgOut(DBG_FAILURE, DBG_RECEIVE,
                 ("CLReceiveIndication: Out Of Lookahead Buffers!!!\n" ));

        NdisInterlockedPushEntrySList(&Adapter->PacketSList,
                                      (PSINGLE_LIST_ENTRY)OurPacket->ProtocolReserved,
                                      &Adapter->PacketSListLock);

   
        InterlockedIncrement( ErrorCounter );
        DerefAdapter( Adapter );

        return NDIS_STATUS_NOT_ACCEPTED;
    }

    LookaheadNdisBuffer = ((PIM_BUFFER_CONTEXT)LookaheadEntry)->NdisBuffer;

    //
    // get a (or another) residual buffer if all the data is not available
    //

    if ( PacketSize != LookaheadBufferSize ) {

        ResidualEntry = NdisInterlockedPopEntrySList(&Adapter->ResidualSList,
                                                     &Adapter->ResidualSListLock);

        if ( ResidualEntry == NULL ) {

            ImDbgOut(DBG_FAILURE, DBG_RECEIVE,
                     ("CLReceiveIndication: Out Of Residual Buffers!!!\n" ));

            NdisInterlockedPushEntrySList(SList,
                                          &((PIM_BUFFER_CONTEXT)LookaheadEntry)->SListEntry,
                                          SListLock);

            NdisInterlockedPushEntrySList(&Adapter->PacketSList,
                                          (PSINGLE_LIST_ENTRY)OurPacket->ProtocolReserved,
                                          &Adapter->PacketSListLock);


            InterlockedIncrement( &Adapter->Stats.OutOfResidualBuffers );
            DerefAdapter( Adapter );

            return NDIS_STATUS_NOT_ACCEPTED;
        }

        ResidualNdisBuffer = ((PIM_BUFFER_CONTEXT)ResidualEntry)->NdisBuffer;
    }

    //
    // get a pointer to the start of the packet and our context area. Clear the
    // original packet area. We'll key off of this when the packet is returned
    // so we don't try and return it to the miniport
    //

    PktContext = IM_PACKET_CONTEXT_FROM_PACKET( Adapter, OurPacket );
    IMStructAssert1( PktContext, PacketContext );

    ImDbgOut(DBG_INFO, DBG_RECEIVE,
             ("(%08X) CLReceiveIndication: Packet %08X Packetsize %d %s\n",
              Adapter, OurPacket, PacketSize,
              (PacketSize != LookaheadBufferSize ? "(RD)" : "")));

    PktContext->OriginalPacket = NULL;

    //
    // copy what we have into the lookahead buffer. set the lookahead buffer size
    //

#if BINARY_COMPATIBLE

    //
    // TDI functions are not allowed
    //

    NdisMoveMemory( LookaheadEntry, HeaderBuffer, HeaderBufferSize );

    NdisMoveMemory((CHAR *)LookaheadEntry + HeaderBufferSize, LookaheadBuffer, LookaheadBufferSize);
#else // BINARY_COMPATIBLE

    //
    // for NT, we honor the copy lookahead flag
    //

    if ( Adapter->CopyLookaheadData ) {

        NdisMoveMemory( LookaheadEntry, HeaderBuffer, HeaderBufferSize );

        NdisMoveMemory((CHAR *)LookaheadEntry + HeaderBufferSize,
                       LookaheadBuffer,
                       LookaheadBufferSize);
    } else {

        TdiCopyLookaheadData( LookaheadEntry, HeaderBuffer, HeaderBufferSize, 0 );

        TdiCopyLookaheadData((CHAR *)LookaheadEntry + HeaderBufferSize,
                             LookaheadBuffer,
                             LookaheadBufferSize,
                             0);
    }

#endif // BINARY_COMPATIBLE

    NdisAdjustBufferLength( LookaheadNdisBuffer, HeaderBufferSize + LookaheadBufferSize );
	NDIS_SET_PACKET_HEADER_SIZE( OurPacket, HeaderBufferSize );

    if ( ResidualEntry == NULL ) {

        //
        // we can indicate the packet now (or at least try to) since we have all of it.
        // adjust the NDIS buffer to indicate the correct amount of data and chain the
        // lookahead buffer onto the packet
        //

        NdisChainBufferAtFront( OurPacket, LookaheadNdisBuffer );

        NdisMIndicateReceivePacket( Adapter->IMNdisHandle, &OurPacket, 1 );

        //
        // now check the packet's status to see if we can return it
        //

        if ( NDIS_GET_PACKET_STATUS( OurPacket ) != NDIS_STATUS_PENDING ) {

            MPReturnPacket( (NDIS_HANDLE)Adapter, OurPacket );
        }

    } else {

        //
        // stuff a pointer to the lookahead NDIS buffer in the packet context area
        // and chain the residual buffer at the front. The MP wants to copy data to 
        // beginning of the first buffer, so we'll chain the lookahead buffer when
        // the transfer data stuff is complete.
        //

        NdisAdjustBufferLength( ResidualNdisBuffer, PacketSize - LookaheadBufferSize );
        NdisChainBufferAtFront( OurPacket, ResidualNdisBuffer );
        PktContext->LookaheadBuffer = LookaheadNdisBuffer;

        NdisTransferData(&Status,
                         Adapter->LowerMPHandle,
                         MacReceiveContext,
                         LookaheadBufferSize,
                         PacketSize - LookaheadBufferSize,
                         OurPacket,
                         &BytesTransferred);

        if ( Status != NDIS_STATUS_PENDING ) {

            CLTransferDataComplete( (NDIS_HANDLE)Adapter, OurPacket, Status, BytesTransferred );
        }
    }

    return NDIS_STATUS_SUCCESS;

} // CLReceiveIndication


VOID
CLReceiveComplete(
	IN	NDIS_HANDLE				ProtocolBindingContext
	)

/*++

Routine Description:

    Called by NIC via NdisIndicateReceiveComplete. Continue this indication
    up to the higher layer

Arguments:

    See the DDK...

Return Values:

    None

--*/

{
    PADAPTER Adapter = (PADAPTER)ProtocolBindingContext;

    IMStructAssert( Adapter );

    ImDbgOut(DBG_INFO, DBG_RECEIVE, ("(%08X) CLReceiveComplete:\n", Adapter));

    if ( Adapter->IMMPState & ADAPTER_STATE_RUNNING ) {

        switch( Adapter->MediaType ) {
        case NdisMedium802_3:
            NdisMEthIndicateReceiveComplete( Adapter->IMNdisHandle );
            break;

        case NdisMedium802_5:
            NdisMTrIndicateReceiveComplete( Adapter->IMNdisHandle );
            break;

        case NdisMediumFddi:
            NdisMFddiIndicateReceiveComplete( Adapter->IMNdisHandle );
            break;

        default:
            IMAssert( FALSE );
        }
    }

}  // CLReceiveComplete


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:



Arguments:

    See the DDK...

Return Values:

    None

--*/

{
    PADAPTER Adapter = (PADAPTER)MiniportAdapterContext;

    IMStructAssert( Adapter );

    ImDbgOut(DBG_INFO, DBG_RECEIVE, ("(%08X) MPTransferData:\n", Adapter));

    return NDIS_STATUS_FAILURE;

} // MPTransferData


VOID
CLTransferDataComplete(
    IN  NDIS_HANDLE     ProtocolBindingContext,
    IN  PNDIS_PACKET    Packet,
    IN  NDIS_STATUS     Status,
    IN  UINT            BytesTransferred
    )

/*++

Routine Description:

    Completion routine for NdisTransferData

Arguments:

    See the DDK...

Return Values:

    None

--*/

{
    PADAPTER Adapter = (PADAPTER)ProtocolBindingContext;
    PIM_PACKET_CONTEXT PktContext;

    IMStructAssert( Adapter );

    ImDbgOut(DBG_INFO, DBG_RECEIVE,
             ("(%08X) CLTransferDataComplete: Packet %08X Status %08X Bytes xfer'ed %d\n",
              Adapter, Packet, Status, BytesTransferred));

    //
    // get the lookahead NDIS buffer pointer from the context area and chain it
    // on the front
    //

    PktContext = IM_PACKET_CONTEXT_FROM_PACKET( Adapter, Packet );
    IMStructAssert1( PktContext, PacketContext );

    NdisChainBufferAtFront( Packet, PktContext->LookaheadBuffer );

    //
    // we can indicate the packet now (or at least try to) since we have all of it
    //

    NdisMIndicateReceivePacket( Adapter->IMNdisHandle, &Packet, 1 );

    //
    // now check the packet's status to see if we can return it
    //

    if ( NDIS_GET_PACKET_STATUS( Packet ) != NDIS_STATUS_PENDING ) {

        MPReturnPacket( (NDIS_HANDLE)Adapter, Packet );
    }

} // CLTransferDataComplete

/* end recv.c */

⌨️ 快捷键说明

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