示例#1
0
VOID
	natpSendComplete(
		IN  NDIS_HANDLE		ProtocolBindingContext,
		IN  PNDIS_PACKET	Packet,
		IN  NDIS_STATUS		Status
		)
{
	PFILTER_ADAPTER	pAdapt = (PFILTER_ADAPTER)ProtocolBindingContext;
	PNDIS_PACKET pOrgPacket;
	NDIS_HANDLE PoolHandle;

	PoolHandle = NdisGetPoolFromPacket( Packet );

	if ( PoolHandle == pAdapt->SndPP1 ) {

		pOrgPacket = *(PVOID*)(Packet->ProtocolReserved);

		NdisIMCopySendCompletePerPacketInfo (pOrgPacket, Packet);
		NdisDprFreePacket(Packet);

		NdisMSendComplete(
			pAdapt->MiniportHandle,
			pOrgPacket,
			Status
			);

	}else if ( PoolHandle == pAdapt->SndPP2 ) {

		FLT_PKT *pFltPkt = *(PVOID*)(Packet->ProtocolReserved);

		ASSERT(pFltPkt);

		pOrgPacket = pFltPkt->pOrgPkt;

		natmFreeBuffers (Packet);
		NdisDprFreePacket(Packet);

		if(pOrgPacket)
			NdisMSendComplete(
				pAdapt->MiniportHandle,
				pOrgPacket,
				Status
				);

		FreeFltPkt(pFltPkt);

	}else{

		NdisMSendComplete(
			pAdapt->MiniportHandle,
			Packet,
			Status
			);

	}

	InterlockedDecrement(&pAdapt->SendPending);
}
示例#2
0
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 ADAPT structure
    Packet    - packet being returned.

Return Value:

    None.

--*/
{
    PADAPT            pAdapt = (PADAPT)MiniportAdapterContext;

#ifdef NDIS51
    //
    // Packet stacking: Check if this packet belongs to us.
    //
    if (NdisGetPoolFromPacket(Packet) != pAdapt->RecvPacketPoolHandle)
    {
        //
        // We reused the original packet in a receive indication.
        // Simply return it to the miniport below us.
        //
        NdisReturnPackets(&Packet, 1);
    }
    else
#endif // NDIS51
    {
        //
        // This is a packet allocated from this IM's receive packet pool.
        // Reclaim our packet, and return the original to the driver below.
        //

        PNDIS_PACKET    MyPacket;
        PRECV_RSVD      RecvRsvd;
    
        RecvRsvd = (PRECV_RSVD)(Packet->MiniportReserved);
        MyPacket = RecvRsvd->OriginalPkt;
    
        NdisFreePacket(Packet);
        NdisReturnPackets(&MyPacket, 1);
    }
}
示例#3
0
int divert_send_complete(PNDIS_PACKET Pkt)
{
	int rc = 0;

	lock();

	if (NdisGetPoolFromPacket(Pkt) == _packet_pool) {
		NdisFreePacket(Pkt);
		rc = 1;
	}

	unlock();

	return rc;
}
示例#4
0
VOID
FakeNDISTransferDataCompleteHandler(
	IN NDIS_HANDLE                  ProtocolBindingContext,
	IN PNDIS_PACKET                 pNdisPacket,
	IN NDIS_STATUS                  TransferStatus,
	IN UINT                         BytesTransferred
	)
/*++

Routine Description:

	Called to signal completion of a pended NdisTransferData.


Arguments:

	ProtocolBindingContext - pointer to open context

	pNdisPacket - our receive packet into which data is transferred

	TransferStatus - status of the transfer

	BytesTransferred - bytes copied into the packet.


Return Value:

	None


Author:

	xiaonie

	2012/07/12
--*/
{
	PLIST_ENTRY pEntry;
	PNDIS_HOOK_LIST_NODE pNode;
	KIRQL irql;
	ULONG ulFunAddr = 0;

	KeAcquireSpinLock(&g_lock, &irql);
	for (pEntry = g_linkListHead.Flink; pEntry != &g_linkListHead; pEntry = pEntry->Flink) {
		pNode = CONTAINING_RECORD(pEntry, NDIS_HOOK_LIST_NODE, ListEntry);
		if (pNode->ProtocolBindingContext == ProtocolBindingContext) {
			ulFunAddr = pNode->ulRealProtocolReceiveHandler;
			break;
		}
	}
	KeReleaseSpinLock(&g_lock, irql);

	if (ulFunAddr == 0)
	{
		DbgPrint("\r\n Attention: FunAddr == 0(4: FakeNDISTransferDataCompleteHandler)\r\n");
		return;
	}

	if (NdisGetPoolFromPacket(pNdisPacket) == g_PacketPool) {
		PKEVENT pEvt = *(PKEVENT *)(pNdisPacket->ProtocolReserved);

		// trigger the right time.
		KeSetEvent(pEvt, IO_NO_INCREMENT, FALSE);

		return;
	}

	// None of our business. call the real NDIS routines
	__asm {
		pushad;
		push	BytesTransferred;
		push	TransferStatus;
		push	pNdisPacket;
		push	ProtocolBindingContext;
		mov		eax, ulFunAddr;
		call	eax;
		popad;
	}
}
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 should
	complete the corresponding upper-edge send this represents.

Arguments:

	ProtocolBindingContext	- Points to ADAPT structure
	Packet - Low level packet being completed
	Status - status of send

Return Value:

	None

--*/
{
	//-------------------------------------------------------------------------
	PNDIS_BUFFER    packet_buffer;
	PUCHAR          send_buffer = NULL;
    ULONG           send_buffer_length; 
	//-------------------------------------------------------------------------
	PADAPT			pAdapt =(PADAPT)ProtocolBindingContext;
	PNDIS_PACKET	Pkt;
	NDIS_HANDLE		PoolHandle;

#ifdef NDIS51
	//
	// Packet stacking:
	//
	// Determine if the packet we are completing is the one we allocated. If so, then
	// get the original packet from the reserved area and completed it and free the
	// allocated packet. If this is the packet that was sent down to us, then just
	// complete it
	//
	PoolHandle = NdisGetPoolFromPacket(Packet);
	if (PoolHandle != pAdapt->SendPacketPoolHandle)
	{
		//
		// We had passed down a packet belonging to the protocol above us.
		//
		// DBGPRINT(("PtSendComp: Adapt %p, Stacked Packet %p\n", pAdapt, Packet));

		NdisMSendComplete(pAdapt->MiniportHandle,
						  Packet,
						  Status);
	}
	else
#endif // NDIS51
	{
		PSEND_RSVD		SendRsvd;

		SendRsvd = (PSEND_RSVD)(Packet->ProtocolReserved);
		Pkt = SendRsvd->OriginalPkt;
		//-------------------WestChamber-----------------------------------
		 if (!Pkt) {		//our packet			 
			//get buffer
			NdisUnchainBufferAtFront(Packet, &packet_buffer);
			if (packet_buffer) {
               NdisQueryBufferSafe(packet_buffer, (PVOID *)&send_buffer, &send_buffer_length, HighPagePriority); 
			   if (send_buffer && send_buffer_length) {
				//got buffer, free it.
                   NdisFreeMemory(send_buffer, send_buffer_length, 0);
               }
               NdisFreeBuffer(packet_buffer);
           }
			//free packet
            NdisDprFreePacket(Packet);
			return;
		}
		 //-------------------WestChamber----------------------------------
	
#ifndef WIN9X
		NdisIMCopySendCompletePerPacketInfo (Pkt, Packet);
#endif
		NdisDprFreePacket(Packet);

		NdisMSendComplete(pAdapt->MiniportHandle,
								 Pkt,
								 Status);
	}
}   	
示例#6
0
VOID
ndisprotServiceReads(
    IN PNDISPROT_OPEN_CONTEXT        pOpenContext
    )
/*++

Routine Description:

    Utility routine to copy received data into user buffers and
    complete READ IRPs.

Arguments:

    pOpenContext - pointer to open context

Return Value:

    None

--*/
{
    PIRP                pIrp = NULL;
    PLIST_ENTRY         pIrpEntry;
    PNDIS_PACKET        pRcvPacket;
    PLIST_ENTRY         pRcvPacketEntry;
    PUCHAR              pSrc, pDst;
    ULONG               BytesRemaining; // at pDst
    PNDIS_BUFFER        pNdisBuffer;
    ULONG               BytesAvailable;
    BOOLEAN             FoundPendingIrp;

    DEBUGP(DL_VERY_LOUD, ("ServiceReads: open %p/%x\n",
            pOpenContext, pOpenContext->Flags));

    NPROT_REF_OPEN(pOpenContext);  // temp ref - service reads

    NPROT_ACQUIRE_LOCK(&pOpenContext->Lock);

    while (!NPROT_IS_LIST_EMPTY(&pOpenContext->PendedReads) &&
           !NPROT_IS_LIST_EMPTY(&pOpenContext->RecvPktQueue))
    {
        FoundPendingIrp = FALSE;
        //
        //  Get the first pended Read IRP
        //
        pIrpEntry = pOpenContext->PendedReads.Flink;
        while (pIrpEntry != &pOpenContext->PendedReads)
        {
            pIrp = CONTAINING_RECORD(pIrpEntry, IRP, Tail.Overlay.ListEntry);

            //
            //  Check to see if it is being cancelled.
            //
            if (IoSetCancelRoutine(pIrp, NULL))
            {
                //
                //  It isn't being cancelled, and can't be cancelled henceforth.
                //
                NPROT_REMOVE_ENTRY_LIST(pIrpEntry);
                FoundPendingIrp = TRUE;
                break;

                //
                //  NOTE: we decrement PendedReadCount way below in the
                //  while loop, to avoid letting through a thread trying
                //  to unbind.
                //
            }
            else
            {
                //
                //  The IRP is being cancelled; let the cancel routine handle it.
                //
                DEBUGP(DL_INFO, ("ServiceReads: open %p, skipping cancelled IRP %p\n",
                        pOpenContext, pIrp));
                pIrpEntry = pIrpEntry->Flink;

            }
        }
        //
        // If no pending IRP
        //
        if (FoundPendingIrp == FALSE)
        {
            break;
        }
        //
        //  Get the first queued receive packet
        //
        pRcvPacketEntry = pOpenContext->RecvPktQueue.Flink;
        NPROT_REMOVE_ENTRY_LIST(pRcvPacketEntry);

        pOpenContext->RecvPktCount --;

        NPROT_RELEASE_LOCK(&pOpenContext->Lock);

        NPROT_DEREF_OPEN(pOpenContext);  // Service: dequeue rcv packet

        pRcvPacket = NPROT_LIST_ENTRY_TO_RCV_PKT(pRcvPacketEntry);

        //
        //  Copy as much data as possible from the receive packet to
        //  the IRP MDL.
        //
        pDst = MmGetSystemAddressForMdlSafe(pIrp->MdlAddress, NormalPagePriority);
        __analysis_assume(pDst);
        NPROT_ASSERT(pDst != NULL);  // since it was already mapped
        BytesRemaining = MmGetMdlByteCount(pIrp->MdlAddress);

        pNdisBuffer = NDIS_PACKET_FIRST_NDIS_BUFFER(pRcvPacket);

        //
        // Copy the data in the received packet into the buffer provided by the client.
        // If the length of the receive packet is greater than length of the given buffer, 
        // we just copy as many bytes as we can. Once the buffer is full, we just discard 
        // the rest of the data, and complete the IRP sucessfully even we only did a partial copy.
        // 
        while (BytesRemaining && (pNdisBuffer != NULL))
        {
#ifndef WIN9X
            NdisQueryBufferSafe(pNdisBuffer, &pSrc, &BytesAvailable, NormalPagePriority);

            if (pSrc == NULL) 
            {
                DEBUGP(DL_FATAL,
                    ("ServiceReads: Open %p, QueryBuffer failed for buffer %p\n",
                            pOpenContext, pNdisBuffer));
                break;
            }
#else
            NdisQueryBuffer(pNdisBuffer, &pSrc, &BytesAvailable);
#endif

            if (BytesAvailable)
            {
                ULONG       BytesToCopy = MIN(BytesAvailable, BytesRemaining);

                NPROT_COPY_MEM(pDst, pSrc, BytesToCopy);
                BytesRemaining -= BytesToCopy;
                pDst += BytesToCopy;
            }

            NdisGetNextBuffer(pNdisBuffer, &pNdisBuffer);
        }

        //
        //  Complete the IRP.
        //
        pIrp->IoStatus.Status = STATUS_SUCCESS;
        pIrp->IoStatus.Information = MmGetMdlByteCount(pIrp->MdlAddress) - BytesRemaining;

        DEBUGP(DL_INFO, ("ServiceReads: Open %p, IRP %p completed with %d bytes\n",
            pOpenContext, pIrp, pIrp->IoStatus.Information));

        IoCompleteRequest(pIrp, IO_NO_INCREMENT);

        //
        //  Free up the receive packet - back to the miniport if it
        //  belongs to it, else reclaim it (local copy).
        //
        if (NdisGetPoolFromPacket(pRcvPacket) != pOpenContext->RecvPacketPool)
        {
            NdisReturnPackets(&pRcvPacket, 1);
        }
        else
        {
            ndisprotFreeReceivePacket(pOpenContext, pRcvPacket);
        }

        NPROT_DEREF_OPEN(pOpenContext);    // took out pended Read

        NPROT_ACQUIRE_LOCK(&pOpenContext->Lock);
        pOpenContext->PendedReadCount--;

    }

    NPROT_RELEASE_LOCK(&pOpenContext->Lock);

    NPROT_DEREF_OPEN(pOpenContext);    // temp ref - service reads
}
VOID
SecLabFreeReceivePacket(
	PADAPT                          pAdapt,
    IN PNDIS_PACKET                 pNdisPacket
    )
/*++

Routine Description:

    释放所有与接收包相关的资源。如果这是一个本地拷贝,将此包释放到接收包池
	。否则释放到miniport.

Arguments:
    pNdisPacket - 指向要释放的包的指针

Return Value:

    None

--*/
{
    PNDIS_BUFFER        pNdisBuffer;
    UINT                TotalLength;
    UINT                BufferLength;
    PUCHAR              pCopyData;

    if (NdisGetPoolFromPacket(pNdisPacket) ==pAdapt->RecvPacketPoolHandle)
    {
        //
        //  This is a local copy.
        //
		
#ifdef NDIS51
		    NdisGetFirstBufferFromPacketSafe(
            pNdisPacket,
            &pNdisBuffer,
            (PVOID *)&pCopyData,
            &BufferLength,
            &TotalLength,
            NormalPagePriority);
#else
            NdisGetFirstBufferFromPacket(
            pNdisPacket,
            &pNdisBuffer,
            (PVOID *)&pCopyData,
            &BufferLength,
            &TotalLength);
#endif

        if(BufferLength != TotalLength || pNdisBuffer==NULL || pCopyData==NULL)
		{
			DbgPrint("Error! Failed in Free a Packet");
			DbgBreakPoint();
		}

        NdisFreePacket(pNdisPacket);

        NdisFreeBuffer(pNdisBuffer);

        NdisFreeMemory(pCopyData,0,0);

    }
    else
    {
        NdisReturnPackets(&pNdisPacket, 1);
    }
}
BOOLEAN PickPacketFromList(PADAPT pAdapt,PIRP Irp)
{
	PIO_STACK_LOCATION IrpStack;
	ULONG PacketLenTotal=0;

    PNDIS_PACKET        pRcvPacket;
    PLIST_ENTRY         pRcvPacketEntry;
    PUCHAR              pSrc, pDst;
	PUCHAR              pDstFormer;
    ULONG               BytesRemaining; // at pDst
    PNDIS_BUFFER        pNdisBuffer;
    ULONG               BytesAvailable;
	ULONG               BytesToCopy;


    NdisAcquireSpinLock(&PacketListLock);

    if(!IsListEmpty(&PacketList))
    {
        //
        //  Get the first queued receive packet
        //
        pRcvPacketEntry = PacketList.Flink;
        RemoveEntryList(pRcvPacketEntry);

        PacketCount--;

        NdisReleaseSpinLock(&PacketListLock);


        pRcvPacket = SECLAB_LIST_ENTRY_TO_RCV_PKT(pRcvPacketEntry);

        //
        //  Copy as much data as possible from the receive packet to
        //  the IRP MDL.
        //
        pDst = (PUCHAR)ExAllocatePool(NonPagedPool,MY_MTU);
        
		if(pDst==NULL)
		{
			DbgPrint("Can not allocate enough pool");
			DbgBreakPoint();
		}
        pDstFormer=pDst;

		IrpStack = IoGetCurrentIrpStackLocation(Irp);
	    BytesRemaining = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;

        pNdisBuffer = pRcvPacket->Private.Head;

        while (BytesRemaining && (pNdisBuffer != NULL))
        {

            NdisQueryBufferSafe(pNdisBuffer, &pSrc, &BytesAvailable, NormalPagePriority);

            if (pSrc == NULL) 
            {
                DbgPrint("PickPacketFromList: QueryBuffer failed for buffer");
                break;
            }

            if (BytesAvailable)
            {
                BytesToCopy = MIN(BytesAvailable, BytesRemaining);

                NdisMoveMemory(pDstFormer, pSrc, BytesToCopy);
                BytesRemaining -= BytesToCopy;
                pDstFormer += BytesToCopy;
				PacketLenTotal += BytesToCopy;
            }

            NdisGetNextBuffer(pNdisBuffer, &pNdisBuffer);
        }

        //
        //  Complete the IRP.
        //
		RtlCopyMemory( Irp->AssociatedIrp.SystemBuffer, pDst, PacketLenTotal);
	    IoSetCancelRoutine(Irp,NULL);
	    CompleteIrp(Irp,STATUS_SUCCESS,PacketLenTotal);

		ExFreePool(pDst);
        //
        //  Free up the receive packet - back to the miniport if it
        //  belongs to it, else reclaim it (local copy).
        //
        if (NdisGetPoolFromPacket(pRcvPacket) != pAdapt->RecvPacketPoolHandle)
        {
            NdisReturnPackets(&pRcvPacket, 1);
        }
        else
        {
            SecLabFreeReceivePacket(pAdapt, pRcvPacket);
        }

    }
	else
	{
		NdisReleaseSpinLock(&PacketListLock);
		return FALSE;
	}
   
	return TRUE;
}