Example #1
0
VOID FreeNdisPacket
( PNDIS_PACKET Packet )
/*
 * FUNCTION: Frees an NDIS packet
 * ARGUMENTS:
 *     Packet = Pointer to NDIS packet to be freed
 */
{
    PNDIS_BUFFER Buffer, NextBuffer;

    TI_DbgPrint(DEBUG_PBUFFER, ("Packet (0x%X)\n", Packet));

    /* Free all the buffers in the packet first */
    NdisQueryPacket(Packet, NULL, NULL, &Buffer, NULL);
    for (; Buffer != NULL; Buffer = NextBuffer) {
        PVOID Data;
        UINT Length;

        NdisGetNextBuffer(Buffer, &NextBuffer);
        NdisQueryBuffer(Buffer, &Data, &Length);
	TI_DbgPrint(DEBUG_PBUFFER, ("Freeing ndis buffer (0x%X)\n", Buffer));
        NdisFreeBuffer(Buffer);
	TI_DbgPrint(DEBUG_PBUFFER, ("Freeing exal buffer (0x%X)\n", Data));
        ExFreePoolWithTag(Data, PACKET_BUFFER_TAG);
    }

    /* Finally free the NDIS packet discriptor */
    NdisFreePacket(Packet);
}
Example #2
0
VOID FreeNdisPacketX
( PNDIS_PACKET Packet,
  PCHAR File,
  UINT Line )
/*
 * FUNCTION: Frees an NDIS packet
 * ARGUMENTS:
 *     Packet = Pointer to NDIS packet to be freed
 */
{
    PNDIS_BUFFER Buffer, NextBuffer;

    TI_DbgPrint(DEBUG_PBUFFER, ("Packet (0x%X)\n", Packet));

    /* Free all the buffers in the packet first */
    NdisQueryPacket(Packet, NULL, NULL, &Buffer, NULL);
    for (; Buffer != NULL; Buffer = NextBuffer) {
        PVOID Data;
        UINT Length;

        NdisGetNextBuffer(Buffer, &NextBuffer);
        XNdisQueryBuffer(Buffer, &Data, &Length);
	UntrackFL(File,Line,Buffer);
        NdisFreeBuffer(Buffer);
        exFreePool(Data);
    }

    /* Finally free the NDIS packet descriptor */
    UntrackFL(File,Line,Packet);
    NdisFreePacket(Packet);
}
Example #3
0
/************************************************************
Function called by NDIS to indicate that the data transfer
is finished
************************************************************/
VOID NDIS_API
PacketSendComplete(	IN NDIS_HANDLE	ProtocolBindingContext,
					IN PNDIS_PACKET	pPacket,
					IN NDIS_STATUS	Status
   )
{
	PNDIS_BUFFER 		pNdisBuffer;
	PPACKET_RESERVED	Reserved = (PPACKET_RESERVED) pPacket->ProtocolReserved;

	TRACE_ENTER( "SendComplete" );
	
	NdisUnchainBufferAtFront( pPacket, &pNdisBuffer );
	if ( pNdisBuffer )
		NdisFreeBuffer( pNdisBuffer );
		
	VWIN32_DIOCCompletionRoutine( Reserved->lpoOverlapped->O_Internal );
		
	PacketPageUnlock( Reserved->lpBuffer, Reserved->cbBuffer );
	PacketPageUnlock( Reserved->lpcbBytesReturned, sizeof(DWORD) );
	PacketPageUnlock( Reserved->lpoOverlapped, sizeof(OVERLAPPED) );
	
	NdisReinitializePacket(pPacket);
		
	NdisFreePacket(pPacket);

	TRACE_LEAVE( "SendComplete" );
	return;
}
Example #4
0
/*
 *************************************************************************
 *  ReturnPacketHandler
 *************************************************************************
 *
 *  When NdisMIndicateReceivePacket returns asynchronously, 
 *  the protocol returns ownership of the packet to the miniport via this function.
 *
 */
VOID ReturnPacketHandler(NDIS_HANDLE MiniportAdapterContext, PNDIS_PACKET Packet)
{
	IrDevice *thisDev = CONTEXT_TO_DEV(MiniportAdapterContext);
	UINT rcvBufIndex;

	DBGOUT(("ReturnPacketHandler(0x%x)", (UINT)MiniportAdapterContext));

	/*
	 *  The rcv buffer index is cached in the MiniportReserved field of the packet.
	 */
	rcvBufIndex = *(UINT *)Packet->MiniportReserved;

	if (rcvBufIndex < NUM_RCV_BUFS){
		if (thisDev->rcvBufs[rcvBufIndex].state == STATE_PENDING){
			PNDIS_BUFFER ndisBuf;

			DBGPKT(("Reclaimed rcv packet 0x%x.", (UINT)Packet));

			NdisUnchainBufferAtFront(Packet, &ndisBuf);
			if (ndisBuf){
				NdisFreeBuffer(ndisBuf);
			}

			thisDev->rcvBufs[rcvBufIndex].state = STATE_FREE;
		}
		else {
			DBGERR(("Packet in ReturnPacketHandler was not PENDING."));
		}
	}
	else {
		DBGERR(("Bad rcvBufIndex (from corrupted MiniportReserved) in ReturnPacketHandler."));
	}

	
}
Example #5
0
NTSTATUS
MPIndicatePacket(PHWT_ADAPTER Adapter, PVOID Input, ULONG InputSize, PDEV_RET Output, ULONG OutputSize, PIRP Irp) {

	PVOID data = NULL;
	NDIS_STATUS ndis_status = NDIS_STATUS_FAILURE;
	PNDIS_BUFFER ndis_buffer = NULL;
	PNDIS_PACKET ndis_packet = NULL;	
	do {
		data = ExAllocatePoolWithTag(NonPagedPool, InputSize, 'tkpi');

		RtlCopyMemory(data, Input, InputSize);
				
		NdisAllocateBuffer(&ndis_status, 
                           &ndis_buffer, 
                           Adapter->AllocateBufferPool,
                           data,
                           InputSize);
		if (ndis_status != NDIS_STATUS_SUCCESS)
			break;

		NdisAllocatePacket(&ndis_status,
                           &ndis_packet,
                           Adapter->AllocatePacketPool);
		if (ndis_status != NDIS_STATUS_SUCCESS)
			break;

		NdisReinitializePacket(ndis_packet);
		*(PVOID*)ndis_packet->MiniportReserved = data;
		NdisChainBufferAtBack(ndis_packet, ndis_buffer);
		NDIS_SET_PACKET_HEADER_SIZE(ndis_packet, sizeof(ETHERNET_HEADER));
		NDIS_SET_PACKET_STATUS(ndis_packet, NDIS_STATUS_SUCCESS);
		NdisMIndicateReceivePacket(Adapter->AdapterHandle, &ndis_packet, 1);

		Output->hResult = S_OK;

		ndis_status = NDIS_STATUS_SUCCESS;
	} while(FALSE);
	
	if (ndis_status != NDIS_STATUS_SUCCESS &&
		ndis_status != STATUS_PENDING) {
		if (ndis_packet)
			NdisFreePacket(ndis_packet);
		if (ndis_buffer) 
			NdisFreeBuffer(ndis_buffer);		
		if (data)
			ExFreePoolWithTag(data, 'tkpi');
	}
	return ndis_status;
}
Example #6
0
VOID
ArcFreeNdisPacket(
    IN PARC_PACKET Packet
    )
/*++

Routine description:

    This routine takes an arcnet packet and frees up the corresponding
    Ndis packet built for it.

Arguments:

    Packet - The packet to free up.

Return values:

    None

--*/
{
    PNDIS_BUFFER NdisBuffer, NextNdisBuffer;

    NdisQueryPacket(
        &(Packet->TmpNdisPacket),
        NULL,
        NULL,
        &NdisBuffer,
        NULL
        );

    while (NdisBuffer != NULL) {

        NdisGetNextBuffer(
            NdisBuffer,
            &NextNdisBuffer
            );

        NdisFreeBuffer(
            NdisBuffer
            );

        NdisBuffer = NextNdisBuffer;
    }

    NdisReinitializePacket(&(Packet->TmpNdisPacket));

}
Example #7
0
/******************************************************************************
 *
 *  Name: FreeRxQ()
 *
 *  Description: Free Rx buffer
 *
 *  Arguments:  PMRVDRV_ADAPTER Adapter
 *    
 *  Return Value: NDIS_STATUS_SUCCESS or NDIS_STATUS_FAILURE
 * 
 *  Notes:        
 *
 *****************************************************************************/
NDIS_STATUS FreeRxQ(
  IN PMRVDRV_ADAPTER Adapter
  )
{
    ULONG i;    

    DBGPRINT(DBG_BUF|DBG_RX|DBG_HELP,(L"Free Rx Q\r\n"));
   
    for ( i=0; i < MRVDRV_NUM_RX_PKT_IN_QUEUE; i++ )
    {
        if ( Adapter->pRxBufVM[i] != NULL )
        {                       
            (ULONG)Adapter->pRxBufVM[i] -= MRVDRV_ETH_RX_HIDDEN_HEADER_SIZE; 

            NdisFreeMemory(Adapter->pRxBufVM[i],
                           MRVDRV_ETH_RX_PACKET_BUFFER_SIZE,
                           0);            
            Adapter->pRxBufVM[i] = NULL;
        }

        if ( Adapter->pRxBuffer[i] != NULL )
        {
            NdisFreeBuffer(Adapter->pRxBuffer[i]);
            Adapter->pRxBuffer[i] = NULL;
        }

        if ( Adapter->pRxPacket[i] != NULL )
        {
            NdisFreePacket(Adapter->pRxPacket[i]);
            Adapter->pRxPacket[i] = NULL;
        }
    } 
    
    if ( Adapter->RxBufferPoolHandle != NULL )
    {
        NdisFreeBufferPool(Adapter->RxBufferPoolHandle);
        Adapter->RxBufferPoolHandle = NULL;
    }

    if ( Adapter->RxPacketPoolHandle != NULL )
    {
        NdisFreePacketPool(Adapter->RxPacketPoolHandle);
        Adapter->RxPacketPoolHandle = NULL;
    }
    return NDIS_STATUS_SUCCESS;
}
Example #8
0
VOID NDIS_API PacketTransferDataComplete(IN NDIS_HANDLE  ProtocolBindingContext,
                                         IN PNDIS_PACKET pPacket,
                                         IN NDIS_STATUS  Status,
                                         IN UINT         BytesTransfered)
{
  // upcall when no more data available

  POPEN_INSTANCE Open = (POPEN_INSTANCE)ProtocolBindingContext;
  PPACKET_RESERVED pReserved = (PPACKET_RESERVED)(pPacket->ProtocolReserved);
  OVERLAPPED * pOverlap = (OVERLAPPED *)(pReserved->lpoOverlapped);
  PNDIS_BUFFER pNdisBuffer;


  // free buffer descriptor
  NdisUnchainBufferAtFront(pPacket, &pNdisBuffer);
  if (pNdisBuffer)
    NdisFreeBuffer(pNdisBuffer);

  // set total bytes returned
  BytesTransfered += ETHERNET_HEADER_LENGTH;
  *pReserved->lpcbBytesReturned += BytesTransfered;

  pOverlap->O_InternalHigh = *(pReserved->lpcbBytesReturned);

  // The internal member of overlapped structure contains
  // a pointer to the event structure that will be signalled,
  // resuming the execution of the waitng GetOverlappedResult
  // call.
  VWIN32_DIOCCompletionRoutine(pOverlap->O_Internal);

  // Unlock buffers   
  PacketPageUnlock(pReserved->lpBuffer, pReserved->cbBuffer);
  PacketPageUnlock(pReserved->lpcbBytesReturned, sizeof(DWORD));
  PacketPageUnlock(pReserved->lpoOverlapped, sizeof(OVERLAPPED));

  // recycle the packet
  NdisReinitializePacket(pPacket);

  // Put the packet on the free queue
  NdisFreePacket(pPacket);
}
Example #9
0
VOID 
MPReturnPacket(
    IN NDIS_HANDLE  MiniportAdapterContext,
    IN PNDIS_PACKET Packet)
{
	if (Packet) {
		PVOID data = NULL;
		PNDIS_BUFFER ndis_buffer = NULL;
		data = *(PVOID*)Packet->MiniportReserved;
		if (data)
			ExFreePoolWithTag(data, 'tkpi');
		while(1) {
			NdisUnchainBufferAtBack(Packet, &ndis_buffer);
			if (ndis_buffer)
				NdisFreeBuffer(ndis_buffer);
			else
				break;
		}		
		NdisFreePacket(Packet);
	}
}
Example #10
0
static void
shared_free_pkt(ND_PKT* p)
{
#ifndef NDIS60
	PNDIS_BUFFER b;

	NdisQueryPacket(p, NULL, NULL, &b, NULL);
	ASSERT(b);
	NdisFreeBuffer(b);
	NdisFreePacket(p);
#else /* NDIS60 */
	PNET_BUFFER nb;
	PMDL b;

	nb = NET_BUFFER_LIST_FIRST_NB(p);
	b = NET_BUFFER_FIRST_MDL(nb);
	ASSERT(b);
	NdisFreeMdl(b);
	NdisFreeNetBufferList(p);
#endif /* NDIS60 */
}
Example #11
0
void netgSendToMiniportComplete(IN NDIS_HANDLE ProtocolBindingContext, IN PNDIS_PACKET pNdisPacket, IN NDIS_STATUS Status) {
	PIRP                        pIrp;
    PIO_STACK_LOCATION          pIrpSp;
	PADAPT						pAdapt;
    POPEN_CONTEXT				pOpenContext;
	PNDIS_BUFFER                pNdisBuffer;
	PVOID                       VirtualAddr;
	UINT                        BufferLength;
	UINT                        TotalLength;

	DBGPRINT(("==> netgSendToMiniportComplete\n"));

	pAdapt = (PADAPT)ProtocolBindingContext;
	pOpenContext = pAdapt->pOpenContext;
	pIrp = (((PNPROT_SEND_PACKET_RSVD)&((pNdisPacket)->ProtocolReserved[0]))->pIrp);

	// Free buffer
	NdisGetFirstBufferFromPacket(pNdisPacket, &pNdisBuffer, &VirtualAddr, &BufferLength, &TotalLength);
	NdisFreeBuffer(pNdisBuffer);

	// Free packet
	if (NdisInterlockedDecrement((PLONG)&((PNPROT_SEND_PACKET_RSVD)&((pNdisPacket)->ProtocolReserved[0]))->RefCount) == 0) {                                                                           \
		NdisFreePacket(pNdisPacket);
	}   

CompleteTheIRP:
	// Complete the Write IRP with the right status.
	pIrpSp = IoGetCurrentIrpStackLocation(pIrp);
    if (Status == NDIS_STATUS_SUCCESS) {
		pIrp->IoStatus.Information = pIrpSp->Parameters.Write.Length;
        pIrp->IoStatus.Status = STATUS_SUCCESS;
    } else {
        pIrp->IoStatus.Information = 0;
        pIrp->IoStatus.Status = STATUS_UNSUCCESSFUL;
    }
	IoCompleteRequest(pIrp, IO_NO_INCREMENT);

	DBGPRINT(("<== netgSendToMiniportComplete\n"));
}
Example #12
0
// Release the packet buffer
void NeoFreePacketBuffer(PACKET_BUFFER *p)
{
	// Validate arguments
	if (p == NULL)
	{
		return;
	}

	// Detach the buffer from the packet
	NdisUnchainBufferAtFront(p->NdisPacket, &p->NdisBuffer);
	// Release the packet
	NdisFreePacket(p->NdisPacket);
	// Release the packet pool
	NdisFreePacketPool(p->PacketPool);
	// Release the buffer
	NdisFreeBuffer(p->NdisBuffer);
	// Release the memory
	NeoFree(p->Buf);
	// Release the buffer pool
	NdisFreeBufferPool(p->BufferPool);
	// Release the memory
	NeoFree(p);
}
//***********************************************************************************
// Name: MpFreeSGList 
//
// Description: 
//		frees sgdma list
//
// Return value: 
//		None
//
// Parameters: 
//
// NOTE: None
// **********************************************************************************
VOID
	MpFreeSGList(
		IN  PKIP_NDIS_ADAPTER		pAdapter,
		IN	PNDIS_PACKET			Packet
		)
{
	PSCATTER_GATHER_LIST pSGL;
	PDMA_ADAPTER	SystemAdapterObject = NDIS_GetSystemAdapterObject( pAdapter->NdisMiniportHandle );

	pSGL = NDIS_PER_PACKET_INFO_FROM_PACKET(Packet, ScatterGatherListPacketInfo);
	if ( SystemAdapterObject ){
		SystemAdapterObject->DmaOperations->PutScatterGatherList( SystemAdapterObject, pSGL, TRUE );
	}

	if ( (Packet->Private.Flags & NDIS_FLAGS_USES_SG_BUFFER_LIST ) ==  NDIS_FLAGS_USES_SG_BUFFER_LIST ){
		PNPAGED_LOOKASIDE_LIST SGListLookasideList = NDIS_GetSGListLookasideList( pAdapter->NdisMiniportHandle );
		Packet->Private.Flags &= ~NDIS_FLAGS_USES_SG_BUFFER_LIST;
		pSGL = NDIS_PER_PACKET_INFO_FROM_PACKET(Packet, NdisReserved);
		if ( pSGL && SGListLookasideList ){
			ExFreeToNPagedLookasideList( SGListLookasideList, pSGL );
		}
		NDIS_PER_PACKET_INFO_FROM_PACKET(Packet, NdisReserved) = NULL;
	} 
	else if ( ( Packet->Private.Flags & NDIS_FLAGS_DOUBLE_BUFFERED ) == NDIS_FLAGS_DOUBLE_BUFFERED ){
		PNDIS_BUFFER NdisBuffer;
		PVOID NdisBufferVA;
		Packet->Private.Flags &= ~NDIS_FLAGS_DOUBLE_BUFFERED;
		NdisBuffer = NDIS_PER_PACKET_INFO_FROM_PACKET(Packet, NdisReserved);
		if ( NdisBuffer ){
			NdisBufferVA = MmGetMdlVirtualAddress(NdisBuffer);
			NdisFreeBuffer( NdisBuffer );
			if ( NdisBufferVA ){
				ExFreePoolWithTag(NdisBufferVA,MODULE_TAG);
			}
		}
	}
}
/*----------------------------------------------------------------------------*/
VOID kalPacketFree(IN P_GLUE_INFO_T prGlueInfo, IN PVOID pvPacket)
{
	PNDIS_PACKET prNdisPacket;
	PNDIS_BUFFER prNdisBuf;


	ASSERT(prGlueInfo);
	ASSERT(pvPacket);

	prNdisPacket = (PNDIS_PACKET) pvPacket;

	do {
		NdisUnchainBufferAtBack(prNdisPacket, &prNdisBuf);

		if (prNdisBuf) {
			NdisFreeBuffer(prNdisBuf);
		} else {
			break;
		}

	} while (TRUE);

	/* Reinitialize the packet descriptor for reuse. */
	NdisReinitializePacket(prNdisPacket);

#if CETK_NDIS_PERFORMANCE_WORKAROUND
	{
		PUINT_32 ptr;
		ptr = (PUINT_32) prNdisPacket->ProtocolReserved;
		*ptr = 0;
	}
#endif

	putPoolPacket(prGlueInfo, prNdisPacket, NULL);

}				/* kalPacketFree */
Example #15
0
VOID NDIS_API PacketSendComplete(IN NDIS_HANDLE  ProtocolBindingContext,
                                 IN PNDIS_PACKET pPacket,
                                 IN NDIS_STATUS  Status)
{
  // upcall on completion of send

  PNDIS_BUFFER     pNdisBuffer;
  PPACKET_RESERVED Reserved = (PPACKET_RESERVED)pPacket->ProtocolReserved;

  
  // free buffer descriptor
  NdisUnchainBufferAtFront(pPacket, &pNdisBuffer);
  
  if (pNdisBuffer)
    NdisFreeBuffer(pNdisBuffer);
  
  // return status
  Reserved->lpoOverlapped->O_InternalHigh = Status;
  
  // The internal member of overlapped structure contains
  // a pointer to the event structure that will be signalled,
  // resuming the execution of the waiting GetOverlappedResult
  // call.
  VWIN32_DIOCCompletionRoutine(Reserved->lpoOverlapped->O_Internal);
  
  // Unlock buffers	
  PacketPageUnlock(Reserved->lpBuffer, Reserved->cbBuffer);
  PacketPageUnlock(Reserved->lpcbBytesReturned, sizeof(DWORD));
  PacketPageUnlock(Reserved->lpoOverlapped, sizeof(OVERLAPPED));
  
  // recycle the packet
  NdisReinitializePacket(pPacket);
  
  // Put the packet back on the free list
  NdisFreePacket(pPacket);
}
Example #16
0
int divert_filter(
   IN PADAPT         pAdapt,
   IN NDIS_HANDLE    MacReceiveContext,
   IN PVOID          HeaderBuffer,
   IN UINT           HeaderBufferSize,
   IN PVOID          LookAheadBuffer,
   IN UINT           LookAheadBufferSize,
   IN UINT           PacketSize
   )
{
#define MAC_SIZE 14
	USHORT               EtherType;
	ULONG                NumberOfBytesRead;
	struct ether_header  *pEthHdr;      // See ../B2Winet/ethernet.h
	struct ip            *pIPHeader;
	struct tcphdr	     *tcp;
	int rc = 0;
	struct divert_packet *dp, *cur;
	NDISPROT_ETH_HEADER UNALIGNED *pEthHeader;

	NdisDprAcquireSpinLock(&pAdapt->Lock);

	pEthHdr = (struct ether_header * )HeaderBuffer;
	pEthHeader = pEthHdr;

	if (ntohs( pEthHdr->ether_type ) != ETHERTYPE_IP)
		goto Out;

	if (get_pa(pEthHeader->SrcAddr))
		goto Out;

	pIPHeader = (struct ip * )LookAheadBuffer;

	if (LookAheadBufferSize < 40)
		goto Out;

	if (pIPHeader->ip_p != IPPROTO_TCP)
		goto Out;

	tcp = (struct tcphr*) (pIPHeader + 1);

#if 0
	if (ntohs(tcp->th_dport) == 666)
		rc = 1;
#endif

	lock();

	if (!_open)
		goto Outl;

	dp = get_packet();
	if (!dp) {
		DbgPrint("Out of queue - shit\n");
		goto Outl;
	}

	if (LookAheadBufferSize != PacketSize) {
		NDIS_STATUS status;
		PNDIS_PACKET pkt;
		PNDIS_BUFFER buf;
		int len;

		if ((PacketSize + MAC_SIZE) > sizeof(dp->dp_packet)) {
			DbgPrint("cAZZOOOOOOOOOOOOOOOOOOOOOOOOOOo\n");
			goto Fanculo;
		}

		NdisAllocatePacket(&status, &pkt, _packet_pool);
		NdisAllocateBuffer(&status, &buf, _buf_pool,
				   dp->dp_packet + MAC_SIZE,
				   sizeof(dp->dp_packet) - MAC_SIZE);
		NdisChainBufferAtFront(pkt, buf);
		NdisTransferData(&status, pAdapt->BindingHandle,
				 MacReceiveContext, 0,
				 PacketSize, pkt, &len);
		NdisFreeBuffer(buf);
		NdisFreePacket(pkt);
	} else {
		NdisCopyLookaheadData(dp->dp_packet + MAC_SIZE,
				      LookAheadBuffer,
				      LookAheadBufferSize,
				      0);
	}

Fanculo:
	rc = 1;

	memcpy(dp->dp_packet, pEthHdr, MAC_SIZE);

	dp->dp_len   = PacketSize + MAC_SIZE;
	dp->dp_flags = 1;

	kick_pending();

Outl:
	unlock();
Out:
	NdisDprReleaseSpinLock(&pAdapt->Lock);

	return rc;
#undef MAC_SIZE
}
Example #17
0
VOID
NdisProtSendComplete(
    IN NDIS_HANDLE                  ProtocolBindingContext,
    IN PNDIS_PACKET                 pNdisPacket,
    IN NDIS_STATUS                  Status
)
/*++

Routine Description:

    NDIS entry point called to signify completion of a packet send.
    We pick up and complete the Write IRP corresponding to this packet.

    NDIS 5.1:

Arguments:

    ProtocolBindingContext - pointer to open context
    pNdisPacket - packet that completed send
    Status - status of send

Return Value:

    None

--*/
{
    PIRP                        pIrp;
    PIO_STACK_LOCATION          pIrpSp;
    PNDISPROT_OPEN_CONTEXT       pOpenContext;

    pOpenContext = (PNDISPROT_OPEN_CONTEXT)ProtocolBindingContext;
    NPROT_STRUCT_ASSERT(pOpenContext, oc);

    pIrp = NPROT_IRP_FROM_SEND_PKT(pNdisPacket);

    if (pOpenContext->bRunningOnWin9x)
    {
        //
        //  We would have attached our own NDIS_BUFFER. Take it out
        //  and free it.
        //
#ifndef NDIS51
        PNDIS_BUFFER                pNdisBuffer;
        PVOID                       VirtualAddr;
        UINT                        BufferLength;
        UINT                        TotalLength;
#endif

#ifdef NDIS51
        NPROT_ASSERT(FALSE); // NDIS 5.1 not on Win9X!
#else
        NdisGetFirstBufferFromPacket(
            pNdisPacket,
            &pNdisBuffer,
            &VirtualAddr,
            &BufferLength,
            &TotalLength);

        NPROT_ASSERT(pNdisBuffer != NULL);
        NdisFreeBuffer(pNdisBuffer);
#endif
    }


#ifdef NDIS51
    IoSetCancelRoutine(pIrp, NULL);

    NPROT_ACQUIRE_LOCK(&pOpenContext->Lock);

    NPROT_REMOVE_ENTRY_LIST(&pIrp->Tail.Overlay.ListEntry);

    NPROT_RELEASE_LOCK(&pOpenContext->Lock);
#endif

    //
    //  We are done with the NDIS_PACKET:
    //
    NPROT_DEREF_SEND_PKT(pNdisPacket);

    //
    //  Complete the Write IRP with the right status.
    //
    pIrpSp = IoGetCurrentIrpStackLocation(pIrp);
    if (Status == NDIS_STATUS_SUCCESS)
    {
        pIrp->IoStatus.Information = pIrpSp->Parameters.Write.Length;
        pIrp->IoStatus.Status = STATUS_SUCCESS;
    }
    else
    {
        pIrp->IoStatus.Information = 0;
        pIrp->IoStatus.Status = STATUS_UNSUCCESSFUL;
    }

    DEBUGP(DL_INFO, ("SendComplete: packet %p/IRP %p/Length %d "
                     "completed with status %x\n",
                     pNdisPacket, pIrp, pIrp->IoStatus.Information, pIrp->IoStatus.Status));

    IoCompleteRequest(pIrp, IO_NO_INCREMENT);

    NdisInterlockedDecrement((PLONG)&pOpenContext->PendedSendCount);

    NPROT_DEREF_OPEN(pOpenContext); // send complete - dequeued send IRP
}
Example #18
0
/*+
 *
 * FreeAdapterMemory
 *
 * Routine Description:
 *
 *    Frees the memory previously allocated by
 *    AllocateAdapterMemory
 *
 * Arguments:
 *
 *    Adapter - The adapter to deallocate memory for.
 *
 * Return Value:
 *
 *    None.
 *
-*/
extern
VOID
FreeAdapterMemory(
    IN PDC21X4_ADAPTER Adapter
    )
{

   PDC21X4_RECEIVE_DESCRIPTOR ReceiveDescriptor;
   PRCV_HEADER RcvHeader;
   PNDIS_PACKET Packet;
   UINT i;

   if ((PVOID)Adapter->DescriptorRing.AllocVa == (PVOID)NULL) {
      // AllocateAdapterMemory failed on the first allocation:
      // no ressources were allocated
      return;
   }

   for (i = 0,
      ReceiveDescriptor = (PDC21X4_RECEIVE_DESCRIPTOR)Adapter->ReceiveDescriptorRingVa;
      i < Adapter->ReceiveRingSize;
      i++,
      (PCHAR)ReceiveDescriptor += Adapter->DescriptorSize
      ) {

      if (ReceiveDescriptor->RcvHeader) {

         RcvHeader = ReceiveDescriptor->RcvHeader;

         if (RcvHeader->FlushBuffer) {
             NdisFreeBuffer(RcvHeader->FlushBuffer);
         }
         if (RcvHeader->Packet) {
             NdisFreePacket(RcvHeader->Packet);
         }

         if (!Adapter->RcvBufferSpace.Va)

         {
            NdisMFreeSharedMemory(
               Adapter->MiniportAdapterHandle,
               RcvHeader->AllocSize,
               TRUE,
               (PVOID)RcvHeader->AllocVa,
               RcvHeader->AllocPa
               );
         }

      }
   }

   while (Adapter->FreeRcvList != NULL) {

      RcvHeader = Adapter->FreeRcvList;
      Adapter->FreeRcvList = RcvHeader->Next;

      if (RcvHeader->FlushBuffer) {
          NdisFreeBuffer(RcvHeader->FlushBuffer);
      }
      if (  !Adapter->RcvBufferSpace.Va
         && RcvHeader->AllocVa)
      {
         NdisMFreeSharedMemory(
            Adapter->MiniportAdapterHandle,
            RcvHeader->AllocSize,
            TRUE,
            (PVOID)RcvHeader->AllocVa,
            RcvHeader->AllocPa
            );
      }
   }

	while (Adapter->FreePacketList != NULL)
	{
		Packet = Adapter->FreePacketList;
		Adapter->FreePacketList = RCV_RESERVED(Packet)->Next;
		
		if (NULL != Packet)
		{
			NdisFreePacket(Packet);
		}
	}

   if (Adapter->RcvBufferSpace.Va) {

       NdisMFreeSharedMemory(
           Adapter->MiniportAdapterHandle,
           Adapter->RcvBufferSpace.AllocSize,
           TRUE,
           (PVOID)Adapter->RcvBufferSpace.AllocVa,
           Adapter->RcvBufferSpace.AllocPa
           );
   }

   if (Adapter->ReceivePacketPool) {
      NdisFreePacketPool((PVOID)Adapter->ReceivePacketPool);
   }


   for (i = 0; i < DC21X4_NUMBER_OF_MAX_TRANSMIT_BUFFERS;i ++ ) {

      if (Adapter->MaxTransmitBuffer[i].AllocVa) {

         NdisMFreeSharedMemory(
            Adapter->MiniportAdapterHandle,
            Adapter->MaxTransmitBuffer[i].AllocSize,
            TRUE,
            (PVOID)Adapter->MaxTransmitBuffer[i].AllocVa,
            Adapter->MaxTransmitBuffer[i].AllocPa
            );

      }

      if (Adapter->MaxTransmitBuffer[i].FlushBuffer) {
         NdisFreeBuffer(Adapter->MaxTransmitBuffer[i].FlushBuffer);
      }
   }

   if (Adapter->MinTransmitBuffer[0].AllocVa &&
	   !Adapter->DontUseMinTransmitBuffer) {

      NdisMFreeSharedMemory(
         Adapter->MiniportAdapterHandle,
         Adapter->MinTransmitBuffer[0].AllocSize,
         TRUE,
         (PVOID)Adapter->MinTransmitBuffer[0].AllocVa,
         Adapter->MinTransmitBuffer[0].AllocPa
         );

   }

   for (i = 0; i < DC21X4_NUMBER_OF_MIN_TRANSMIT_BUFFERS;i ++ ) {

      if (Adapter->MinTransmitBuffer[i].FlushBuffer) {
         NdisFreeBuffer(Adapter->MinTransmitBuffer[i].FlushBuffer);
      }
   }


   if (Adapter->FlushBufferPoolHandle) {
      NdisFreeBufferPool(Adapter->FlushBufferPoolHandle);
   }


   if (Adapter->DescriptorRing.AllocVa) {

      NdisMFreeSharedMemory(
         Adapter->MiniportAdapterHandle,
         Adapter->DescriptorRing.AllocSize,
         FALSE,
         (PVOID)Adapter->DescriptorRing.AllocVa,
         Adapter->DescriptorRing.AllocPa
         );

   }

}
Example #19
0
VOID
PacketFree2 (
	IN PNDIS_PACKET		Packet
	)
{
	PLPX_RESERVED	reserved = RESERVED(Packet);
	PUCHAR			packetData;
	PNDIS_BUFFER	pNdisBuffer;
	UINT			uiLength;
	LONG			clone;
	LONG			BufferSeq;
	BOOLEAN			allocMiniport = FALSE;
	PLPX_RESERVED	externalReserved;


	DebugPrint( 3, ("PacketFree reserved->type = %d\n", reserved->Type) );
	ASSERT( Packet->Private.NdisPacketFlags & fPACKET_ALLOCATED_BY_NDIS );

	
	switch (reserved->Type) {

	case LPX_PACKET_TYPE_SEND:

		clone = InterlockedDecrement( &reserved->Cloned );
		
		if(clone >= 0) {
		
			return;
		}
	
		pNdisBuffer = NULL;
		BufferSeq = 0;
		NdisUnchainBufferAtFront( Packet, &pNdisBuffer );

		while (pNdisBuffer) {

			//
			//	Assuming the first data buffer comes from user application
			//			the others are created in LPX for padding, etc.
			//	Free the memory of the others.
			//
			
			if (BufferSeq == 0) {

#if DBG
				NdisQueryBufferSafe( pNdisBuffer, &packetData, &uiLength, HighPagePriority );
				ASSERT( packetData == (PCHAR)&RESERVED(Packet)->EthernetHeader );
#endif

			} else if (BufferSeq == 1) {

				// UserBuffer

			} else if (BufferSeq == 2) {

				// Padding
					
				NdisQueryBufferSafe( pNdisBuffer, &packetData, &uiLength, HighPagePriority );
				LpxFreeMemoryWithLpxTag( packetData );
			
			} else {

				ASSERT( FALSE );
			}

			NdisFreeBuffer( pNdisBuffer );

			pNdisBuffer = NULL;
			NdisUnchainBufferAtFront( Packet, &pNdisBuffer );
			BufferSeq ++;
		}
		
		if (reserved->IrpSp != NULL) {
			
			PIRP _Irp = IRP_SEND_IRP( reserved->IrpSp );

			ASSERT( reserved->NdisStatus == NDIS_STATUS_SUCCESS || reserved->NdisStatus == NDIS_STATUS_NOT_ACCEPTED || !NT_SUCCESS(reserved->NdisStatus) );

			if (!NT_SUCCESS(reserved->NdisStatus)) {

				_Irp->IoStatus.Status = reserved->NdisStatus;
			}

			//INC_IRP_RETRANSMITS( _Irp, reserved->Retransmits );

			LpxDereferenceSendIrp( "Destroy packet", reserved->IrpSp, RREF_PACKET );
		
		} else {
		
			DebugPrint( 3, ("[LPX] PacketFree: No IrpSp\n") ) ;
		}

		break;

	case LPX_PACKET_TYPE_RECEIVE:

		//
		// If the packet allocated by NIC miniport, break here.
		//
		if(RESERVED(Packet)->RecvFlags & LPX_RESERVED_RECVFLAG_ALLOC_MINIPORT) {
			allocMiniport = TRUE;
			break;
		}

		pNdisBuffer = NULL;	

		NdisUnchainBufferAtFront( Packet, &pNdisBuffer );

#if __LPX_STATISTICS__
		{
			LARGE_INTEGER systemTime;

			KeQuerySystemTime( &systemTime );

			RESERVED(Packet)->DeviceContext->NumberOfRecvPackets ++;
			RESERVED(Packet)->DeviceContext->FreeTimeOfRecvPackets.QuadPart += systemTime.QuadPart - RESERVED(Packet)->RecvTime2.QuadPart;
			RESERVED(Packet)->DeviceContext->BytesOfRecvPackets.QuadPart += sizeof(LPX_HEADER) + RESERVED(Packet)->PacketRawDataLength;

			if (RESERVED(Packet)->PacketRawDataLength) {

				RESERVED(Packet)->DeviceContext->NumberOfLargeRecvPackets ++;
				RESERVED(Packet)->DeviceContext->FreeTimeOfLargeRecvPackets.QuadPart += systemTime.QuadPart - RESERVED(Packet)->RecvTime2.QuadPart;
				RESERVED(Packet)->DeviceContext->BytesOfLargeRecvPackets.QuadPart += sizeof(LPX_HEADER) + RESERVED(Packet)->PacketRawDataLength;
			
			} else {

				RESERVED(Packet)->DeviceContext->NumberOfSmallRecvPackets ++;
				RESERVED(Packet)->DeviceContext->FreeTimeOfSmallRecvPackets.QuadPart += systemTime.QuadPart - RESERVED(Packet)->RecvTime2.QuadPart;
				RESERVED(Packet)->DeviceContext->BytesOfSmallRecvPackets.QuadPart += sizeof(LPX_HEADER);
			}
		}
#endif

		if (pNdisBuffer) {

			NdisQueryBufferSafe( pNdisBuffer, &packetData, &uiLength, HighPagePriority );
			
			LpxFreeMemoryWithLpxTag( packetData );
			NdisFreeBuffer( pNdisBuffer );
		}

		break;
	default:
		ASSERT(FALSE);
		return;
	}

	//
	// Free external protocol reserved context.
	//

	externalReserved = ((PLPX_RESERVED)(Packet->ProtocolReserved))->ExternalReserved;
	if(externalReserved) {
		NdisFreeMemory(externalReserved, sizeof(LPX_RESERVED), 0);
	}

	ASSERT( Packet->Private.NdisPacketFlags & fPACKET_ALLOCATED_BY_NDIS );
	if(allocMiniport) {
		//
		// Return the packet allocated by NIC miniport
		//
		NdisReturnPackets(&Packet, 1);
	} else {

		NdisFreePacket( Packet );

		InterlockedDecrement( &NumberOfAllockPackets );
		DebugPrint( 3, ("Packet REALLY Freed NumberOfAllockPackets = %d\n", NumberOfAllockPackets) );

	}

}
Example #20
0
NTSTATUS
RcvPacketAlloc (
	IN  PDEVICE_CONTEXT		DeviceContext,
	IN	ULONG				PacketDataLength,
	OUT	PNDIS_PACKET		*Packet
	)
{
	NTSTATUS		status;
	PUCHAR			packetData = NULL;
	PNDIS_BUFFER	packetDataBuffer = NULL;
	PNDIS_PACKET	packet = NULL;


	DebugPrint( 3, ("RcvPacketAlloc, PacketLength = %d, NumberOfAllockPackets = %d\n", PacketDataLength, NumberOfAllockPackets) );
	
	ASSERT( DeviceContext );
	ASSERT( DeviceContext->LpxPacketPool != NULL );

	ASSERT( PacketDataLength <= DeviceContext->MaxUserData );

	do {
	
		NdisAllocatePacket( &status, &packet, DeviceContext->LpxPacketPool );

		if (status != NDIS_STATUS_SUCCESS) {
 	
			ASSERT( status == NDIS_STATUS_RESOURCES );
			ASSERT( FALSE );

			return status;
		}

		RtlZeroMemory( RESERVED(packet), sizeof(LPX_RESERVED) );

		ASSERT( packet->Private.NdisPacketFlags & fPACKET_ALLOCATED_BY_NDIS );

		if (PacketDataLength) {
		
			status = LpxAllocateMemoryWithLpxTag( &packetData,
												  PacketDataLength );

			if (status != NDIS_STATUS_SUCCESS) {

				ASSERT( status == NDIS_STATUS_FAILURE ); 
				ASSERT( FALSE );
			
				break;
			}

			NdisAllocateBuffer( &status,
								&packetDataBuffer,
								DeviceContext->LpxBufferPool,
								packetData,
								PacketDataLength );

			if (!NT_SUCCESS(status)) {

				ASSERT( status == NDIS_STATUS_FAILURE ); 
				ASSERT( FALSE );
				break;
			}

			NdisChainBufferAtFront( packet, packetDataBuffer );
		}
	
	} while(0);

	if (status == STATUS_SUCCESS) {
	
		RESERVED(packet)->Cloned = 0;
		RESERVED(packet)->Type = LPX_PACKET_TYPE_RECEIVE;
		RESERVED(packet)->Packet = packet;
	
		InterlockedIncrement( &NumberOfAllockPackets );
	
		*Packet = packet;
	
#if __LPX_STATISTICS__
		
		KeQuerySystemTime( &RESERVED(packet)->RecvTime2 );
		RESERVED(packet)->DeviceContext = DeviceContext;

#endif

	} else {

		if (packetDataBuffer)
			NdisFreeBuffer( packetDataBuffer );
		
		if (packetData)
			LpxFreeMemoryWithLpxTag( packetData );

		if (packet)
			NdisFreePacket( packet );

		*Packet = NULL;
		
		DebugPrint( 1, ("[LPX]RcvPacketAlloc: Can't Allocate Buffer For CopyData!!!\n") );
	}

	return status;
}
/*----------------------------------------------------------------------------*/
WLAN_STATUS kalRxIndicatePkts(IN P_GLUE_INFO_T prGlueInfo, IN PVOID apvPkts[], IN UINT_32 ucPktNum)
{
	NDIS_STATUS arStatus[CFG_RX_MAX_PKT_NUM];
	UINT_32 u4Idx;

	for (u4Idx = 0; u4Idx < ucPktNum; u4Idx++) {
		UINT_32 i, pivot;
		PVOID pvTmp;

		if (NDIS_GET_PACKET_STATUS((PNDIS_PACKET) apvPkts[u4Idx]) == NDIS_STATUS_RESOURCES) {
			pivot = u4Idx;
			for (i = u4Idx + 1; i < ucPktNum; i++) {
				if (NDIS_GET_PACKET_STATUS((PNDIS_PACKET) apvPkts[i]) !=
				    NDIS_STATUS_RESOURCES) {
					pvTmp = apvPkts[pivot];
					apvPkts[pivot] = apvPkts[i];
					apvPkts[i] = pvTmp;
					pivot++;
				}
			}
			break;
		}
	}

	for (u4Idx = 0; u4Idx < ucPktNum; u4Idx++) {
		arStatus[u4Idx] = NDIS_GET_PACKET_STATUS((PNDIS_PACKET) apvPkts[u4Idx]);
		if (arStatus[u4Idx] == NDIS_STATUS_SUCCESS) {
			/* 4 Increase the Pending Count before calling NdisMIndicateReceivePacket(). */
			InterlockedIncrement(&prGlueInfo->i4RxPendingFrameNum);
		}
	}

	NdisMIndicateReceivePacket(prGlueInfo->rMiniportAdapterHandle,
				   (PPNDIS_PACKET) apvPkts, (UINT) ucPktNum);

	for (u4Idx = 0; u4Idx < ucPktNum; u4Idx++) {

		/* 4 <1> Packets be retained. */
		if (arStatus[u4Idx] != NDIS_STATUS_SUCCESS) {
			PNDIS_PACKET prNdisPacket = (PNDIS_PACKET) apvPkts[u4Idx];
			PNDIS_BUFFER prNdisBuf = (PNDIS_BUFFER) NULL;

			ASSERT(prNdisPacket);

			NdisUnchainBufferAtBack(prNdisPacket, &prNdisBuf);

			if (prNdisBuf) {
				NdisFreeBuffer(prNdisBuf);
			}
#if DBG
			else {
				ASSERT(0);
			}
#endif				/* DBG */

			/* Reinitialize the packet descriptor for reuse. */
			NdisReinitializePacket(prNdisPacket);

#if CETK_NDIS_PERFORMANCE_WORKAROUND
			{
				PUINT_32 pu4Dummy;
				pu4Dummy = (PUINT_32) prNdisPacket->ProtocolReserved;
				*pu4Dummy = 0;
			}
#endif				/* CETK_NDIS_PERFORMANCE_WORKAROUND */

		}
	}

	return WLAN_STATUS_SUCCESS;
}				/* kalIndicatePackets */
Example #22
0
NDIS_STATUS
FakeNDISReceiveHandler (
	NDIS_HANDLE ProtocolBindingContext,
	NDIS_HANDLE MacReceiveContext,
	PUCHAR pHeaderBuffer,
	UINT HeaderBufferSize,
	PUCHAR pLookaheadBuffer,
	UINT LookaheadBufferSize,
	UINT PacketSize
	)
/*++

Routine Description:

	Filters network packets received.


Arguments:

	ProtocolBindingContext - ...

	MacReceiveContext - ...

	pHeaderBuffer - packet header

	HeaderBufferSize - packet header length

	pLookaheadBuffer - look ahead buffer after packet header

	LookaheadBufferSize - length of look ahead buffer

	PacketSize - length of packet, exclude packet header


Return Value:

	...


Author:

	xiaonie

	2012/07/12


--*/
{
	PLIST_ENTRY pEntry;
	PNDIS_HOOK_LIST_NODE pNode;
	KIRQL irql;
	ULONG ulFunAddr = 0;
	// PVOID MacHandle = NULL;
	NDIS_STATUS status = NDIS_STATUS_SUCCESS;
	PNDIS_PACKET pNdisPacket = NULL;
	PNDIS_BUFFER pNdisBuffer = NULL;
	PUCHAR pBuffer = NULL;
	ULONG ulLen;
	KEVENT evt;

	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->ulRealReceiveHandler;
			// MacHandle = pNode->MacHandle;
			break;
		}
	}
	KeReleaseSpinLock(&g_lock, irql);

	if (ulFunAddr == 0) {
		DbgPrint("\r\n Attention: FunAddr == 0(0: FakeNDISReceiveHandler)\r\n");
		// return NDIS_STATUS_SUCCESS;
		return NDIS_STATUS_NOT_ACCEPTED;
	}


	////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	if (PacketSize + HeaderBufferSize < PacketSize || PacketSize < LookaheadBufferSize) {	// PacketSize not valid
		DbgPrint("\r\n Attention: PacketSize not valid!(0: FakeNDISReceiveHandler)\r\n");
		return NDIS_STATUS_NOT_ACCEPTED;
	}

	// allocate buffer to hold network packet
	status = NdisAllocateMemoryWithTag(&pBuffer, HeaderBufferSize + PacketSize, '!nmN');
	if (status != NDIS_STATUS_SUCCESS/* || pBuffer == NULL*/)
		return NDIS_STATUS_NOT_ACCEPTED;

	// copy packet header to buffer
	NdisMoveMemory(pBuffer, pHeaderBuffer, HeaderBufferSize);

	if (PacketSize == LookaheadBufferSize)		// Lookahead buffer contains a complete packet
	{
		//
		//	path 1 of 3, tested ok!
		//
		NdisMoveMemory(pBuffer + HeaderBufferSize, pLookaheadBuffer, PacketSize);

		// do the filtering work
		if (TRUE == RabbitHole(pBuffer, HeaderBufferSize + PacketSize)) {
			NdisFreeMemory(pBuffer, 0, 0);
			return NDIS_STATUS_NOT_ACCEPTED;
		}

		NdisFreeMemory(pBuffer, 0, 0);

	}
	else										// Lookahead buffer contains an incomplete packet
	{
		//
		// get the full packet
		//
		// DbgPrint("Get Full Packet!\r\n");

		//if (MacHandle == NULL) {
		//	DbgPrint("MacHandle == NULL!(0: FakeNDISReceiveHandler)\r\n");
		//	NdisFreeMemory(pBuffer, 0, 0);
		//	return NDIS_STATUS_NOT_ACCEPTED;
		//}

		// make pBuffer a NDIS buffer to hold data
		NdisAllocateBuffer(&status, &pNdisBuffer, g_BufferPool, pBuffer + HeaderBufferSize, PacketSize);
		if (status != NDIS_STATUS_SUCCESS/* || pNdisBuffer == NULL*/) {
			DbgPrint("allocate pNdisBuffer(size = %d) failed in FakeNDISReceiveHandler!\r\n", PacketSize);
			NdisFreeMemory(pBuffer, 0, 0);
			return NDIS_STATUS_NOT_ACCEPTED;
		}

		// allocate a NIDS packet to chain buffer in.
		NdisAllocatePacket(&status, &pNdisPacket, g_PacketPool);
		if (status != NDIS_STATUS_SUCCESS/* || pNdisPacket == NULL*/) {
			DbgPrint("allocate pNdisPacket failed in FakeNDISReceiveHandler!\r\n");
			NdisFreeBuffer(pNdisBuffer);
			NdisFreeMemory(pBuffer, 0, 0);
			return NDIS_STATUS_NOT_ACCEPTED;
		}

		NDIS_SET_PACKET_STATUS(pNdisPacket, STATUS_SUCCESS);

		// Bring explosives.
		KeInitializeEvent(&evt, NotificationEvent, FALSE);
		*(PKEVENT *)(pNdisPacket->ProtocolReserved) = &evt;

		NdisChainBufferAtFront(pNdisPacket, pNdisBuffer);

		// try to get complete packet
		NdisTransferData(&status, pNode->pOpenBlock, MacReceiveContext, 0, PacketSize, pNdisPacket, &ulLen);

		if (status == NDIS_STATUS_PENDING) {			// wait for the right time
			//
			// Path 2 of 3, not tested yet! Warning: An Error may occur!
			//
			DbgPrint("NdisTransferData is pending in FakeNDISReceiveHandler!\r\n", status);
			KeWaitForSingleObject(&evt, Executive, KernelMode, FALSE, NULL);
		} else if (status != NDIS_STATUS_SUCCESS) {
			DbgPrint("NdisTransferData failed(status == 0x%08x) in FakeNDISReceiveHandler!\r\n", status);
			NdisFreePacket(pNdisPacket);
			NdisFreeBuffer(pNdisBuffer);
			NdisFreeMemory(pBuffer, 0, 0);
			return NDIS_STATUS_NOT_ACCEPTED;
		}

		//
		// Path 3 of 3, Filtering doesn't seem to work properly.
		//
		// do the filtering work
		if (TRUE == FilterPacket_ReceiveHandler(pBuffer, HeaderBufferSize, pNdisPacket)) {
			NdisFreePacket(pNdisPacket);
			NdisFreeBuffer(pNdisBuffer);
			NdisFreeMemory(pBuffer, 0, 0);
			return NDIS_STATUS_NOT_ACCEPTED;
		}

		NdisFreePacket(pNdisPacket);
		NdisFreeBuffer(pNdisBuffer);
		NdisFreeMemory(pBuffer, 0, 0);
	}

	// call the original NDIS routine.
	__asm {
		pushad;
		push	PacketSize;
		push	LookaheadBufferSize;
		push	pLookaheadBuffer;
		push	HeaderBufferSize;
		push	pHeaderBuffer;
		push	MacReceiveContext;
		push	ProtocolBindingContext;
		mov		eax, ulFunAddr;
		call	eax;
		mov		status, eax;
		popad;
	}

	return status;
}
Example #23
0
VOID
NdisuioTransferDataComplete(
    IN NDIS_HANDLE                  ProtocolBindingContext,
    IN PNDIS_PACKET                 pNdisPacket,
    IN NDIS_STATUS                  TransferStatus,
    IN UINT                         BytesTransferred
    )
/*++

Routine Description:

    NDIS entry point called to signal completion of a call to
    NdisTransferData that had pended.

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

--*/
{
    PNDISUIO_OPEN_CONTEXT   pOpenContext;
    PNDIS_BUFFER            pOriginalBuffer, pPartialBuffer;
	PIRP					pIrp;
	PPACKET_GROUP			pGroup;
	//ULONG                   pDst;

    pOpenContext = (PNDISUIO_OPEN_CONTEXT)ProtocolBindingContext;
    NUIO_STRUCT_ASSERT(pOpenContext, oc);

	pIrp = NUIO_IRP_FROM_RCV_PKT(pNdisPacket);
	if (pIrp)
	{
		PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(pIrp);

		pOriginalBuffer = NUIO_RCV_PKT_TO_ORIGINAL_BUFFER(pNdisPacket);
		
		//
		//  Free the partial MDL that we allocated
		//
		if (pOriginalBuffer)
			IoFreeMdl(pOriginalBuffer);
		
		//
		//  Put the packet on the free queue
		//
		NdisFreePacket(pNdisPacket);
		
#ifndef WIN9X
		pGroup = MmGetSystemAddressForMdlSafe(pIrp->MdlAddress, NormalPagePriority);
		//NUIO_ASSERT(pDst != NULL);  // since it was already mapped
#else
		pGroup = MmGetSystemAddressForMdl(pIrp->MdlAddress);  // Win9x
#endif
		pGroup->Length = BytesTransferred + sizeof(NDISUIO_ETH_HEADER);
		if (TransferStatus == NDIS_STATUS_SUCCESS)
		{
			pIrp->IoStatus.Status = STATUS_SUCCESS;
			pIrp->IoStatus.Information = pGroup->Length + sizeof(PACKET_GROUP);
		}
		else
		{
			pIrp->IoStatus.Status = STATUS_UNSUCCESSFUL;
			pIrp->IoStatus.Information = 0;
		}
		
		DEBUGP(DL_LOUD, ("TransferComp: Pkt %p, OrigBuf %p, BytesTransferred %d\n",
			pNdisPacket, pOriginalBuffer, BytesTransferred));
		
		IoCompleteRequest(pIrp, IO_NO_INCREMENT);
	}
	else
	{
		//
		//  Check if an NDIS_BUFFER was created to map part of the receive buffer;
		//  if so, free it and link back the original NDIS_BUFFER that maps
		//  the full receive buffer to the packet.
		//
		pOriginalBuffer = NUIO_RCV_PKT_TO_ORIGINAL_BUFFER(pNdisPacket);
		if (pOriginalBuffer != NULL)
		{
			//
			//  We had stashed off the NDIS_BUFFER for the full receive
			//  buffer in the packet reserved area. Unlink the partial
			//  buffer and link in the full buffer.
			//
			NdisUnchainBufferAtFront(pNdisPacket, &pPartialBuffer);
			NdisChainBufferAtBack(pNdisPacket, pOriginalBuffer);
			
			DEBUGP(DL_LOUD, ("TransferComp: Pkt %p, OrigBuf %p, PartialBuf %p\n",
                pNdisPacket, pOriginalBuffer, pPartialBuffer));
			
			//
			//  Free up the partial buffer.
			//
			NdisFreeBuffer(pPartialBuffer);
		}
	}

    if (TransferStatus == NDIS_STATUS_SUCCESS)
    {
        //
        //  Queue this up for receive processing, and
        //  try to complete some read IRPs.
        //
        ndisuioQueueReceivePacket(pOpenContext, pNdisPacket);
    }
    else
    {
        ndisuioFreeReceivePacket(pOpenContext, pNdisPacket);

		NdisInterlockedAddLargeStatistic((PLARGE_INTEGER)&pOpenContext->DroppedPackets, 1);
    }
}
Example #24
0
NDIS_STATUS
shared_flush(
	IN shared_info_t *shared,
	IN uchar *va,
	IN ULONG pa,
	IN ULONG len,
	IN BOOLEAN writetodevice
)
{
#ifndef NDIS60
	PNDIS_BUFFER b;
	NDIS_STATUS status;
	NDIS_PHYSICAL_ADDRESS npa;

	/* if receive, buffer must begin and end on a cacheline boundary */
	if (!writetodevice) {
		ASSERT(ISALIGNED((uintptr)va, shared->cacheline));
		len = ROUNDUP(len, shared->cacheline);
	}

	/* alloc a temp buffer descriptor */
	NdisAllocateBuffer(&status, &b, shared->rxbufferpool, va, len);
	if (status != NDIS_STATUS_SUCCESS) {
		ND_ERROR(("%s%d: shared_flush: NdisAllocateBuffer error 0x%x\n",
			shared->id, shared->unit, status));
		return status;
	}

	/* flush processor cache */
	NdisAdjustBufferLength(b, len);
	NdisFlushBuffer(b, writetodevice);

	npa.HighPart = 0;
	npa.LowPart = pa;

#ifndef USEWDK


	if (!writetodevice)
		NdisMUpdateSharedMemory(shared->adapterhandle, len, va, npa);

#endif /* USEWDK */

	/* free the temp buffer descriptor */
	NdisFreeBuffer(b);
#else /* NDIS60 */
	PMDL b;

	/* if receive, buffer must begin and end on a cacheline boundary */
	if (!writetodevice) {
		ASSERT(ISALIGNED((uintptr)va, shared->cacheline));
		len = ROUNDUP(len, shared->cacheline);
	}

	/* alloc a temp MDL */
	b = NdisAllocateMdl(shared->adapterhandle, va, len);
	if (b == NULL) {
		ND_ERROR(("%s%d: shared_flush: NdisAllocateMdl error\n", shared->id, shared->unit));
		return NDIS_STATUS_FAILURE;
	}

	/* flush processor cache */
	NdisAdjustMdlLength(b, len);
	NdisFlushBuffer(b, writetodevice);

	/* free the temp MDL */
	NdisFreeMdl(b);
#endif /* NDIS60 */
	return NDIS_STATUS_SUCCESS;
}
Example #25
0
/*
 *************************************************************************
 *  DeliverFullBuffers
 *************************************************************************
 *
 *  Deliver received packets to the protocol.
 *
 */
VOID DeliverFullBuffers(IrDevice *thisDev)
{
	int rcvBufIndex = thisDev->firstRcvBufIndex;

	DBGOUT(("==> DeliverFullBuffers"));



	/*
	 *  Deliver all full rcv buffers
	 */
	while (rcvBufIndex != NO_BUF_INDEX){
		rcvBuffer *rcvBuf = &thisDev->rcvBufs[rcvBufIndex];
		NDIS_STATUS stat;
		PNDIS_BUFFER packetBuf;
		SLOW_IR_FCS_TYPE fcs;

		switch (rcvBuf->state){

			case STATE_FREE:
			case STATE_PENDING:
				/*
				 *  This frame was already delivered.  Just go to the next one.
				 */
				break;
		
			case STATE_FULL:

				/*
				 *  The packet we have already has had BOFs, EOF, and
				 *  escape-sequences removed.  
				 *  It contains an FCS code at the end,
				 *  which we need to verify and then remove before
				 *  delivering the frame.
				 *  We compute the FCS on the packet with the packet FCS
				 *  attached; this should produce the constant value GOOD_FCS.
				 */
				fcs = ComputeFCS(rcvBuf->dataBuf, rcvBuf->dataLen);

				if (fcs != GOOD_FCS){
					/*
					 *  FCS Error.  Drop this frame.
					 */
					DBGERR(("Bad FCS in DeliverFullBuffers 0x%x!=0x%x.", (UINT)fcs, (UINT)GOOD_FCS));
					rcvBuf->state = STATE_FREE;

					DBGSTAT(("Dropped %d/%d packets; packet with BAD FCS (%xh!=%xh):", 
							++thisDev->packetsDropped, thisDev->packetsDropped + thisDev->packetsRcvd, fcs, GOOD_FCS));
					DBGPRINTBUF(rcvBuf->dataBuf, rcvBuf->dataLen);
					break;
				}


				/*
				 *  Remove the FCS from the end of the packet.
				 */
				rcvBuf->dataLen -= SLOW_IR_FCS_SIZE;


				#ifdef DBG_ADD_PKT_ID
					if (addPktIdOn){
						/*
						 *  Remove dbg packet id.
						 */
						rcvBuf->dataLen -= sizeof(USHORT);
						DBGOUT((" RCVing packet %xh **", (UINT)*(USHORT *)(rcvBuf->dataBuf+rcvBuf->dataLen)));
					}
				#endif

				/*
				 *  The packet array is set up with its NDIS_PACKET.
				 *  Now we need to allocate a single NDIS_BUFFER for the
				 *  NDIS_PACKET and set the NDIS_BUFFER  to the part of dataBuf
				 *  that we want to deliver.
				 */
				NdisAllocateBuffer(	&stat, 
									&packetBuf, 
									thisDev->bufferPoolHandle,
									(PVOID)rcvBuf->dataBuf,
									rcvBuf->dataLen); 
				if (stat != NDIS_STATUS_SUCCESS){
					DBGERR(("NdisAllocateBuffer failed"));
					break;
				}
				NdisChainBufferAtFront(rcvBuf->packet, packetBuf);

				/*
				 *  Fix up some other packet fields.
				 */
				NDIS_SET_PACKET_HEADER_SIZE(rcvBuf->packet, SLOW_IR_ADDR_SIZE + SLOW_IR_CONTROL_SIZE);

				DBGPKT(("Indicating rcv packet 0x%x.", (UINT)rcvBuf->packet));
				DBGPRINTBUF(rcvBuf->dataBuf, rcvBuf->dataLen);

				/*  
				 *  Indicate to the protocol that another packet is ready.  
				 *  Set the rcv buffer's state to PENDING first to avoid
				 *  a race condition with NDIS's call to the return packet
				 *  handler.
				 */
				rcvBuf->state = STATE_PENDING;
				NdisMIndicateReceivePacket(thisDev->ndisAdapterHandle, &rcvBuf->packet, 1);
				stat = NDIS_GET_PACKET_STATUS(rcvBuf->packet);			
				if (stat == NDIS_STATUS_PENDING){
					/*
					 *  The packet is being delivered asynchronously.
					 *  Leave the rcv buffer's state as PENDING; we'll
					 *  get a callback when the transfer is complete.
					 *	
					 *  Do NOT step firstRcvBufIndex.
					 *  We don't really need to break out here, 
					 *  but we will anyways just to make things simple.
					 *  This is ok since we get this deferred interrupt callback
					 *  for each packet anyway.  It'll give the protocol a chance
					 *  to catch up.
					 */
					DBGSTAT(("Rcv Pending.  Rcvd %d packets", ++thisDev->packetsRcvd));
				}
				else {
					/*
					 *  If there was an error, we are dropping this packet;
					 *  otherwise, this packet was delivered synchronously. 
					 *  We can free the packet buffer and make this rcv frame
					 *  available.
					 */
					NdisUnchainBufferAtFront(rcvBuf->packet, &packetBuf);
					if (packetBuf){
						NdisFreeBuffer(packetBuf);	
					}	
					rcvBuf->state = STATE_FREE;

					if (stat == NDIS_STATUS_SUCCESS){
						DBGSTAT(("Rcvd %d packets", ++thisDev->packetsRcvd));
					}
					else {
						DBGSTAT(("Dropped %d/%d rcv packets. ", thisDev->packetsDropped++, thisDev->packetsDropped+thisDev->packetsRcvd));
					}
				}

				break;


			default:
				/*
				 *  This should never happen.
				 */
				DBGERR(("Bad rcv buffer state in DPC"));
				break;
		}
		
		/*
		 *  Step the buffer index
		 */
		if (rcvBufIndex == thisDev->lastRcvBufIndex){
			rcvBufIndex = NO_BUF_INDEX;
		}
		else {
			rcvBufIndex = NEXT_RCV_BUF_INDEX(rcvBufIndex);
		}
	}

	DBGOUT(("<== DeliverFullBuffers"));

}
Example #26
0
VOID
PacketFree(
    IN PNDIS_PACKET	Packet
)
{
    PLPX_RESERVED	reserved = RESERVED(Packet);
    PUCHAR			packetData;
    PNDIS_BUFFER	pNdisBuffer;
    UINT			uiLength;
    LONG			clone ;

    DebugPrint(3, ("PacketFree reserved->type = %d\n", reserved->Type));

    switch(reserved->Type) {

    case SEND_TYPE:

        clone = InterlockedDecrement(&reserved->Cloned);
        if(clone >= 0) {
            return;
        }

        pNdisBuffer = NULL;
        NdisUnchainBufferAtFront(Packet, &pNdisBuffer);
        if(pNdisBuffer) {

            NdisQueryBufferSafe(
                pNdisBuffer,
                &packetData,
                &uiLength,
                HighPagePriority
            );

            NdisFreeMemory(packetData);
            NdisFreeBuffer(pNdisBuffer);
        }
        pNdisBuffer = NULL;
        NdisUnchainBufferAtFront(Packet, &pNdisBuffer);
        while(pNdisBuffer) {
            NdisFreeBuffer(pNdisBuffer);
            pNdisBuffer = NULL;
            NdisUnchainBufferAtFront(Packet, &pNdisBuffer);
        }
        if(reserved->IrpSp != NULL) {
            LpxDereferenceSendIrp(reserved->IrpSp);
        } else {
            DebugPrint(2, ("[LPX] PacketFree: No IrpSp\n")) ;
        }
        break;

    case RECEIVE_TYPE:

        if(reserved->LpxSmpHeader)
            //ExFreePool(reserved->LpxSmpHeader);
            NdisFreeMemory(reserved->LpxSmpHeader);

        pNdisBuffer = NULL;
        NdisUnchainBufferAtFront(Packet, &pNdisBuffer);
        if(pNdisBuffer) {
            NdisQueryBufferSafe(
                pNdisBuffer,
                &packetData,
                &uiLength,
                HighPagePriority
            );

            NdisFreeMemory(packetData);
            NdisFreeBuffer(pNdisBuffer);
        }
        reserved->PacketDataOffset = 0;

        break;

    }

    NdisFreePacket(Packet);

    InterlockedDecrement(&NumberOfPackets);

    DebugPrint(2, ("Packet REALLY Freed Numberofpackets = %d\n", NumberOfPackets));
}
//***********************************************************************************
// Name: MpAllocSGList
//
// Description: 
//		sends packet via DMA
//
// Return value: 
//		None
//
// Parameters: 
//
// NOTE: None
// **********************************************************************************
NDIS_STATUS
	MpAllocSGList(
		IN  PKIP_NDIS_ADAPTER		pAdapter,
		IN  PNDIS_PACKET            Packet
		)
{
	NDIS_STATUS		nStatus = NDIS_STATUS_FAILURE; 
	PNDIS_BUFFER	Buffer;
	PVOID			pBufferVa;
	ULONG			PacketLength;
	PDMA_ADAPTER	SystemAdapterObject;
	PDEVICE_OBJECT	DeviceObject;
	PNPAGED_LOOKASIDE_LIST SGListLookasideList = NULL;
	ULONG ScatterGatherListSize = 0;
	PVOID pSGList = NULL;
	KIRQL OldIrql;
	PVOID SendBuffer = NULL;
	PNDIS_BUFFER	SendNdisBuffer;
	ULONG nBytesRead = 0;
	BOOLEAN fbResult;
	BOOLEAN fbDMAV2;

	do 
	{
		SystemAdapterObject = NDIS_GetSystemAdapterObject( pAdapter->NdisMiniportHandle );
		if ( SystemAdapterObject == NULL ){
			DBGLOG(( LError, "SystemAdapterObject is NULL\n" ));
			nStatus = NDIS_STATUS_RESOURCES;
			break;
		}

		fbDMAV2 = (SystemAdapterObject->DmaOperations->Size >= sizeof(DMA_OPERATIONS_V2) );

		DeviceObject = NDIS_GetMiniportDeviceObject( pAdapter->NdisMiniportHandle );
		if ( DeviceObject == NULL ){
			DBGLOG(( LError, "DeviceObject is NULL\n" ));
			nStatus = NDIS_STATUS_RESOURCES;
			break;
		}

		if ( fbDMAV2 ){
			SGListLookasideList = NDIS_GetSGListLookasideList( pAdapter->NdisMiniportHandle );
			if ( SGListLookasideList == NULL ){
				DBGLOG(( LError, "SGListLookasideList is NULL\n" ));
				nStatus = NDIS_STATUS_RESOURCES;
				break;
			}

			ScatterGatherListSize = NDIS_GetScatterGatherListSize( pAdapter->NdisMiniportHandle );
			if ( ScatterGatherListSize == 0 ){
				DBGLOG(( LError, "SGListLookasideList is NULL\n" ));
				nStatus = NDIS_STATUS_RESOURCES;
				break;
			}
		}

		NdisQueryPacket(Packet, NULL, NULL, &Buffer, &PacketLength);
		if ( Buffer == NULL ){
			DBGLOG(( LError, "Buffer is NULL\n" ));
			nStatus = NDIS_STATUS_FAILURE;
			break;
		}

		// try to use build sg list interface
		if ( fbDMAV2 ){
			// allocate SG list
			pSGList = 
				ExAllocateFromNPagedLookasideList(
					SGListLookasideList
					);
			if ( pSGList != NULL ){

				Packet->Private.Flags |= NDIS_FLAGS_USES_SG_BUFFER_LIST; // sg list
				NDIS_PER_PACKET_INFO_FROM_PACKET(Packet, NdisReserved) = pSGList;
				// raise irql to dispatch
				KeRaiseIrql(DISPATCH_LEVEL,&OldIrql);
				nStatus = 
					SystemAdapterObject->DmaOperations->BuildScatterGatherList(
						SystemAdapterObject,
						DeviceObject,
						Buffer,
						MmGetMdlVirtualAddress(Buffer),
						PacketLength,
						MpProcessSGList,
						Packet,
						TRUE,
						pSGList,
						ScatterGatherListSize
						);
				KeLowerIrql( OldIrql );

				if ( !NT_SUCCESS ( nStatus )){
					DBGLOG(( LDebug, "%08X=BuildMdlFromScatterGatherList failed\n",nStatus ));
					Packet->Private.Flags &= ~NDIS_FLAGS_RESERVED2; // sg list
					NDIS_PER_PACKET_INFO_FROM_PACKET(Packet, ScatterGatherListPacketInfo) = NULL;
					ExFreeToNPagedLookasideList( SGListLookasideList, pSGList );
				}
			}else{
				DBGLOG(( LDebug, "ExAllocateFromNPagedLookasideList failed\n" ));
				nStatus = NDIS_STATUS_RESOURCES;
			}
		}

		// if ( !fbDMAV2 ) then nStatus = NDIS_STATUS_FAILURE; 
		if ( !NT_SUCCESS ( nStatus ))
		{
			// raise irql to dispatch
			KeRaiseIrql(DISPATCH_LEVEL,&OldIrql);

			// call DMA
			nStatus = 
				SystemAdapterObject->DmaOperations->GetScatterGatherList(
					SystemAdapterObject,
					DeviceObject,
					Buffer,
					MmGetMdlVirtualAddress(Buffer),
					PacketLength,
					MpProcessSGList,
					Packet,
					TRUE
					);
			KeLowerIrql( OldIrql );

			if ( !NT_SUCCESS ( nStatus )){
				DBGLOG(( LError, "%08X=GetScatterGatherList failed\n",nStatus ));
			}
		}

		if ( fbDMAV2 && !NT_SUCCESS ( nStatus ) ) {
			
			SendBuffer = 
				ExAllocatePoolWithTag(
					NonPagedPool,
					PacketLength,
					MODULE_TAG
					);
			if ( SendBuffer == NULL ){
				DBGLOG(( LError, "ExAllocatePoolWithTag failed\n" ));
				nStatus = NDIS_STATUS_RESOURCES;
				break;
			}
			NdisAllocateBuffer(
				&nStatus,
				&SendNdisBuffer,
				NULL,
				SendBuffer,
				PacketLength
				);

			if ( nStatus != NDIS_STATUS_SUCCESS ){
				DBGLOG(( LError, "%08X=NdisAllocateBuffer failed\n",nStatus ));
				break;
			}
			//copy data to intermediate buffer
			fbResult =
				NDIS_CopyPacketData(
					Packet,
					SendBuffer,
					PacketLength,0,
					&nBytesRead
					);
			if ( !fbResult || nBytesRead != PacketLength ){
				DBGLOG(( LError, "NDIS_CopyPacketData failed\n" ));
				nStatus = NDIS_STATUS_RESOURCES;
				break;
			}

			Packet->Private.Flags |= NDIS_FLAGS_DOUBLE_BUFFERED; // sg list
			NDIS_PER_PACKET_INFO_FROM_PACKET(Packet, NdisReserved) = SendBuffer;

			// raise irql to dispatch
			KeRaiseIrql(DISPATCH_LEVEL,&OldIrql);
			// call DMA
			nStatus = 
				SystemAdapterObject->DmaOperations->GetScatterGatherList(
					SystemAdapterObject,
					DeviceObject,
					SendNdisBuffer,
					MmGetMdlVirtualAddress(SendNdisBuffer),
					PacketLength,
					MpProcessSGList,
					Packet,
					TRUE
					);
			KeLowerIrql( OldIrql );			
		}

		if ( !NT_SUCCESS ( nStatus ) ){

			if ( SendNdisBuffer ){
				NdisFreeBuffer( SendNdisBuffer );
			}
			if ( SendBuffer ){
				ExFreePoolWithTag( SendBuffer, MODULE_TAG );
			}

			NDIS_PER_PACKET_INFO_FROM_PACKET(Packet, NdisReserved) = NULL;
			if (KIP_MINIPORT_TEST_FLAG(pAdapter, fADAPTER_IS_CO))
			{
				ASSERT(FALSE); // TODO:
				//NdisMCoSendComplete(NDIS_STATUS_FAILURE, GET_VCPTR_FROM_PACKET(Packet), Packet);
			}
			else
			{
				//MpSendPacketCompleteHandler( pAdapter, Packet, NDIS_STATUS_FAILURE );
				// we complete it in caller
			}
		}

	} while ( FALSE );

	return nStatus;
}
Example #28
0
NTSTATUS
SendPacketAlloc (
	IN  PDEVICE_CONTEXT		DeviceContext,
	IN  PTP_ADDRESS			Address,
	IN  UCHAR				DestinationAddressNode[],
	IN	PUCHAR				UserData,
	IN	ULONG				UserDataLength,
	IN	PIO_STACK_LOCATION	IrpSp,
	IN  UCHAR				Option,
	OUT	PNDIS_PACKET		*Packet
	)
{
	NTSTATUS		status;
	PUCHAR			packetHeader = NULL;
	PNDIS_BUFFER	packetHeaderBuffer = NULL;
	ULONG			packetHeaderLength;

	PNDIS_BUFFER	userDataBuffer = NULL;
	PUCHAR			paddingData = NULL;
	PNDIS_BUFFER	paddingDataBuffer = NULL;
	PNDIS_PACKET	packet = NULL;
	USHORT			etherType;


	packetHeaderLength = ETHERNET_HEADER_LENGTH + sizeof(LPX_HEADER);

#if __LPX_OPTION_ADDRESSS__

	if (FlagOn(Option, LPX_OPTION_SOURCE_ADDRESS)) {

		packetHeaderLength += ETHERNET_ADDRESS_LENGTH;
	}
	if (FlagOn(Option, LPX_OPTION_DESTINATION_ADDRESS)) {

		packetHeaderLength += ETHERNET_ADDRESS_LENGTH;
	}

#endif

	ASSERT( packetHeaderLength + UserDataLength <= ETHERNET_HEADER_LENGTH + DeviceContext->MaxUserData );
	
	DebugPrint( 3, ("SendPacketAlloc, packetHeaderLength = %d, NumberOfAllockPackets = %d\n", packetHeaderLength, NumberOfAllockPackets) );
	
	ASSERT( DeviceContext );
	ASSERT( DeviceContext->LpxPacketPool != NULL );

	do {
	
		NdisAllocatePacket( &status, &packet, DeviceContext->LpxPacketPool );

		if (status != NDIS_STATUS_SUCCESS) {
 	
			ASSERT( FALSE );
			LPX_ASSERT( status == NDIS_STATUS_RESOURCES );

			return status;
		}

		RtlZeroMemory( RESERVED(packet), sizeof(LPX_RESERVED) );

		ASSERT( packet->Private.NdisPacketFlags & fPACKET_ALLOCATED_BY_NDIS );

		packetHeader = (PCHAR)&RESERVED(packet)->EthernetHeader;

		NdisAllocateBuffer( &status,
							&packetHeaderBuffer,
							DeviceContext->LpxBufferPool,
							packetHeader,
							packetHeaderLength );

		if (!NT_SUCCESS(status)) {

			ASSERT( status == NDIS_STATUS_FAILURE ); 
			ASSERT( FALSE );
			break;
		}

		if (UserData && UserDataLength) {
			
			NdisAllocateBuffer( &status,
								&userDataBuffer,
								DeviceContext->LpxBufferPool,
								UserData,
								UserDataLength );

			if(!NT_SUCCESS(status)) {

				ASSERT( status == NDIS_STATUS_FAILURE ); 
				ASSERT( FALSE );
				break;
			}
		}

//////////////////////////////////////////////////////////////////////////
//
//	Add padding to fix Under-60byte bug of NDAS chip 2.0.
//

		if (packetHeaderLength == ETHERNET_HEADER_LENGTH + sizeof(LPX_HEADER)) {

			UINT		    totalPacketLength;

			totalPacketLength = packetHeaderLength + UserDataLength;

			if (totalPacketLength >= ETHERNET_HEADER_LENGTH + sizeof(LPX_HEADER) + 4 && totalPacketLength <= 56) {

			    LONG			paddingLen = 60 - totalPacketLength;
			
				DebugPrint( 4, ("[LpxSmp]TransmitDataPacket: Adding padding to support NDAS chip 2.0\n") );

				status = LpxAllocateMemoryWithLpxTag( &paddingData, paddingLen );

				if (status != NDIS_STATUS_SUCCESS) {

					ASSERT( status == NDIS_STATUS_FAILURE ); 
					ASSERT( FALSE );
			
					break;
				}

				NdisAllocateBuffer( &status,
									&paddingDataBuffer,
									DeviceContext->LpxBufferPool,
									paddingData,
									paddingLen );

				if (status != NDIS_STATUS_SUCCESS) {

					ASSERT( status == NDIS_STATUS_FAILURE ); 
					ASSERT( FALSE );
			
					break;
				}

				RtlZeroMemory( paddingData, paddingLen );

				RtlCopyMemory( paddingData + paddingLen - 4, UserData + UserDataLength - 4, 4 );
			}
		}

//
//	End of padding routine.
//
//////////////////////////////////////////////////////////////////////////

	} while(0);

	if (status == STATUS_SUCCESS) {
	
		RtlCopyMemory( &packetHeader[0],
					   DestinationAddressNode,
					   ETHERNET_ADDRESS_LENGTH );

		RtlCopyMemory( &packetHeader[ETHERNET_ADDRESS_LENGTH],
					   Address->NetworkName->Node,
					   ETHERNET_ADDRESS_LENGTH );

		etherType = HTONS( ETH_P_LPX );

		RtlCopyMemory( &packetHeader[ETHERNET_ADDRESS_LENGTH*2],
					   &etherType,
					   2 );

#if __LPX_OPTION_ADDRESSS__

		if (FlagOn(Option, LPX_OPTION_DESTINATION_ADDRESS)) {

			RtlCopyMemory( RESERVED(packet)->OptionDestinationAddress,
						   DestinationAddressNode,
						   ETHERNET_ADDRESS_LENGTH );	
		}

		if (FlagOn(Option, LPX_OPTION_SOURCE_ADDRESS)) {

			if (FlagOn(Option, LPX_OPTION_DESTINATION_ADDRESS)) {
		
				RtlCopyMemory( RESERVED(packet)->OptionSourceAddress,
							   Address->NetworkName->Node,
							   ETHERNET_ADDRESS_LENGTH );	
			
			} else {
			
				RtlCopyMemory( RESERVED(packet)->OptionDestinationAddress,
							   Address->NetworkName->Node,
							   ETHERNET_ADDRESS_LENGTH );	
			}
		}

#endif

		RESERVED(packet)->LpxHeader.PacketSize = HTONS( (USHORT)(packetHeaderLength - ETHERNET_HEADER_LENGTH + UserDataLength) );
		RESERVED(packet)->LpxHeader.Option = Option;

		RESERVED(packet)->Cloned = 0;
		RESERVED(packet)->IrpSp  = IrpSp;
		RESERVED(packet)->Type   = LPX_PACKET_TYPE_SEND;
		RESERVED(packet)->Packet = packet;
		
		if (IrpSp == NULL) {

			DebugPrint( 3, ("[LPX] PacketAllocate: No IrpSp\n") ) ;
		}
	
		if (paddingDataBuffer)
			NdisChainBufferAtFront( packet, paddingDataBuffer );
		
		if (userDataBuffer)
			NdisChainBufferAtFront( packet, userDataBuffer );
		
		NdisChainBufferAtFront( packet, packetHeaderBuffer );

		InterlockedIncrement( &NumberOfAllockPackets );
	
		*Packet = packet;
	
	} else {

		if (paddingDataBuffer)
			NdisFreeBuffer( paddingDataBuffer );

		if( paddingData)
			LpxFreeMemoryWithLpxTag( paddingData );

		if (userDataBuffer)
			NdisFreeBuffer( userDataBuffer );

		if (packetHeaderBuffer)
			NdisFreeBuffer( packetHeaderBuffer );
		
		if (packet)
			NdisFreePacket( packet );

		*Packet = NULL;
		
		DebugPrint( 1, ("[LPX]PacketAllocate: Can't Allocate Buffer For CopyData!!!\n") );
	}

	return status;
}
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);
	}
}   	
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);
    }
}