Exemplo n.º 1
0
NDIS_STATUS AllocatePacketWithBufferX( PNDIS_PACKET *NdisPacket,
				       PCHAR Data, UINT Len,
				       PCHAR File, UINT Line ) {
    PNDIS_PACKET Packet;
    PNDIS_BUFFER Buffer;
    NDIS_STATUS Status;
    PCHAR NewData;

    NewData = exAllocatePool( NonPagedPool, Len );
    if( !NewData ) return NDIS_STATUS_NOT_ACCEPTED; // XXX

    if( Data )
	RtlCopyMemory(NewData, Data, Len);

    NdisAllocatePacket( &Status, &Packet, GlobalPacketPool );
    if( Status != NDIS_STATUS_SUCCESS ) {
	exFreePool( NewData );
	return Status;
    }
    TrackWithTag(NDIS_PACKET_TAG, Packet, File, Line);

    NdisAllocateBuffer( &Status, &Buffer, GlobalBufferPool, NewData, Len );
    if( Status != NDIS_STATUS_SUCCESS ) {
	exFreePool( NewData );
	FreeNdisPacket( Packet );
    }
    TrackWithTag(NDIS_BUFFER_TAG, Buffer, File, Line);

    NdisChainBufferAtFront( Packet, Buffer );
    *NdisPacket = Packet;

    return NDIS_STATUS_SUCCESS;
}
Exemplo n.º 2
0
NDIS_STATUS AllocatePacketWithBuffer( PNDIS_PACKET *NdisPacket,
				      PCHAR Data, UINT Len ) {
    PNDIS_PACKET Packet;
    PNDIS_BUFFER Buffer;
    NDIS_STATUS Status;
    PCHAR NewData;

    NewData = ExAllocatePoolWithTag( NonPagedPool, Len, PACKET_BUFFER_TAG );
    if( !NewData ) return NDIS_STATUS_RESOURCES;

    if( Data ) RtlCopyMemory(NewData, Data, Len);

    NdisAllocatePacket( &Status, &Packet, GlobalPacketPool );
    if( Status != NDIS_STATUS_SUCCESS ) {
	ExFreePoolWithTag( NewData, PACKET_BUFFER_TAG );
	return Status;
    }

    NdisAllocateBuffer( &Status, &Buffer, GlobalBufferPool, NewData, Len );
    if( Status != NDIS_STATUS_SUCCESS ) {
	ExFreePoolWithTag( NewData, PACKET_BUFFER_TAG );
	FreeNdisPacket( Packet );
	return Status;
    }

    NdisChainBufferAtFront( Packet, Buffer );
    *NdisPacket = Packet;

    return NDIS_STATUS_SUCCESS;
}
Exemplo n.º 3
0
void
CAR6KMini::car6k_sendEapolKeyMsg (A_UINT8 descType,
                            A_BOOL secure, A_BOOL mic, A_BOOL ack, A_BOOL tx,
                            A_UINT32 index, A_UINT8 isPW,
                            A_BOOL doEncrypt,
                            A_UINT64 keyRSC,
                            const A_UINT8 nonce[],
                            const A_UINT32 keyLength,
                            A_UINT32 keyDataLen,
                            const A_UINT8 *keyData,
                            const A_UINT32 keyBufferLength,
                            A_UINT8  *bssid)
{
    STATION *station;
    station = GetStation(bssid,0);
    NDIS_STATUS Status;
    PNDIS_PACKET pPacket;
    PNDIS_BUFFER pBuffer;
    A_UINT32 *magic;
    A_UINT16 length;

    memset (m_wpa_buffer, 0 , sizeof (m_wpa_buffer));
    crypto_sendEapolKeyMsg ( descType,secure, mic, ack,  tx,
                             index, isPW,doEncrypt,keyRSC,
                             nonce,keyLength,keyDataLen,
                             keyData, keyBufferLength,
                             bssid,m_CurrentAddress,m_keyCounter,&replayCtr,
                             station,m_wpa_buffer,&length);

    NdisAllocatePacket (&Status, &pPacket, m_TxPacketPool);
    magic = (UINT32 *) pPacket->ProtocolReserved;
    if (NDIS_STATUS_SUCCESS != Status)
    {
        NDIS_DEBUG_PRINTF (ATH_LOG_ERR, "AR6K: ERROR - NdisAllocatePacket failed\n");
        return;
    }

    NdisAllocateBuffer (&Status, &pBuffer, m_TxBufferPool, m_wpa_buffer, length);

    if (NDIS_STATUS_SUCCESS != Status)
    {
        NdisFreePacket (pPacket);
        NDIS_DEBUG_PRINTF (ATH_LOG_ERR, "AR6K: ERROR - NdisAllocateBuffer failed\n");
        return;
    }

    pBuffer->Next = NULL;
    NdisChainBufferAtFront (pPacket,pBuffer);
    *(magic) = TAG_WPA_SEND_PCK;
    SendPackets (&pPacket,1);
    return;
}
/*----------------------------------------------------------------------------*/
WLAN_STATUS
kalProcessRxPacket(IN P_GLUE_INFO_T prGlueInfo,
		   IN PVOID pvPacket,
		   IN PUINT_8 pucPacketStart,
		   IN UINT_32 u4PacketLen, IN BOOL fgIsRetain, IN ENUM_CSUM_RESULT_T aerCSUM[]
    )
{
	PNDIS_PACKET prNdisPacket;
	PNDIS_BUFFER prNdisBuf;
	NDIS_STATUS rStatus;


	ASSERT(prGlueInfo);
	ASSERT(pvPacket);
	ASSERT(pucPacketStart);

	prNdisPacket = (PNDIS_PACKET) pvPacket;

	NdisAllocateBuffer(&rStatus,
			   &prNdisBuf,
			   prGlueInfo->hBufPool, (PVOID) pucPacketStart, (UINT_32) u4PacketLen);

	if (rStatus != NDIS_STATUS_SUCCESS) {
		ASSERT(0);
		return WLAN_STATUS_FAILURE;
	}

	NdisChainBufferAtBack(prNdisPacket, prNdisBuf);

	if (fgIsRetain) {
		/* We don't have enough receive buffers, so set the status
		   on the packet to NDIS_STATUS_RESOURCES to force the
		   protocol driver(s) to copy this packet and return this
		   buffer immediately after returning from the
		   NdisMIndicateReceivePacket function. */
		NDIS_SET_PACKET_STATUS(prNdisPacket, NDIS_STATUS_RESOURCES);
	} else {

		/* We have enough receive buffers, so set the status on the
		   packet to NDIS_STATUS_SUCCESS. */
		NDIS_SET_PACKET_STATUS(prNdisPacket, NDIS_STATUS_SUCCESS);
	}

#if CFG_TCP_IP_CHKSUM_OFFLOAD
	kalUpdateRxCSUMOffloadParam(pvPacket, aerCSUM);
#endif

	return WLAN_STATUS_SUCCESS;
}
Exemplo n.º 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;
}
Exemplo n.º 6
0
NDIS_STATUS PrependPacket( PNDIS_PACKET Packet, PCHAR Data, UINT Length,
			   BOOLEAN Copy ) {
    PNDIS_BUFFER Buffer;
    NDIS_STATUS Status;
    PCHAR NewBuf;

    if( Copy ) {
	NewBuf = PoolAllocateBuffer( Length );
	if( !NewBuf ) return STATUS_NO_MEMORY;
	RtlCopyMemory( NewBuf, Data, Length );
    } else NewBuf = Data;

    NdisAllocateBuffer( &Status, &Buffer, GlobalBufferPool, Data, Length );
    if( Status != NDIS_STATUS_SUCCESS ) return Status;

    NdisChainBufferAtFront( Packet, Buffer );

    return STATUS_SUCCESS;
}
Exemplo n.º 7
0
NDIS_STATUS PrependPacket( PNDIS_PACKET Packet, PCHAR Data, UINT Length,
			   BOOLEAN Copy ) {
    PNDIS_BUFFER Buffer;
    NDIS_STATUS Status;
    PCHAR NewBuf;

    if( Copy ) {
	NewBuf = ExAllocatePoolWithTag( NonPagedPool, Length, PACKET_BUFFER_TAG );
	if( !NewBuf ) return NDIS_STATUS_RESOURCES;
	RtlCopyMemory( NewBuf, Data, Length );
    } else NewBuf = Data;

    NdisAllocateBuffer( &Status, &Buffer, GlobalBufferPool, NewBuf, Length );
    if( Status != NDIS_STATUS_SUCCESS ) {
        if (Copy) ExFreePoolWithTag(NewBuf, PACKET_BUFFER_TAG);
        return Status;
    }

    NdisChainBufferAtFront( Packet, Buffer );

    return STATUS_SUCCESS;
}
Exemplo n.º 8
0
// Create a packet buffer
PACKET_BUFFER *NeoNewPacketBuffer()
{
	PACKET_BUFFER *p;
	NDIS_STATUS ret;

	// Memory allocation
	p = NeoZeroMalloc(sizeof(PACKET_BUFFER));
	// Memory allocation for packet
	p->Buf = NeoMalloc(NEO_MAX_PACKET_SIZE);
	// Allocate the buffer pool
	NdisAllocateBufferPool(&ret, &p->BufferPool, 1);
	// Allocate the buffer
	NdisAllocateBuffer(&ret, &p->NdisBuffer, p->BufferPool, p->Buf, NEO_MAX_PACKET_SIZE);
	// Secure the packet pool
	NdisAllocatePacketPool(&ret, &p->PacketPool, 1, PROTOCOL_RESERVED_SIZE_IN_PACKET);
	// Secure the packet
	NdisAllocatePacket(&ret, &p->NdisPacket, p->PacketPool);
	NDIS_SET_PACKET_HEADER_SIZE(p->NdisPacket, NEO_PACKET_HEADER_SIZE);
	// Attach the buffer to the packet
	NdisChainBufferAtFront(p->NdisPacket, p->NdisBuffer);

	return p;
}
Exemplo n.º 9
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;
}
Exemplo n.º 10
0
INT
	natpReceivePacketPassThrough(
		IN NDIS_HANDLE ProtocolBindingContext,
		IN PNDIS_PACKET Packet,
		IN FLT_PKT* pFltPkt
		)
{
	PFILTER_ADAPTER pAdapt =(PFILTER_ADAPTER)ProtocolBindingContext;
	NDIS_STATUS Status;
	PNDIS_PACKET MyPacket;
	BOOLEAN Remaining;
	PNDIS_BUFFER		pNewBuffer;

	if (NULL == pAdapt->MiniportHandle || pAdapt->natmDeviceState > NdisDeviceStateD0)
		return 0;
	NdisIMGetCurrentPacketStack(Packet, &Remaining);
	if (NULL == pFltPkt && Remaining){
		Status = NDIS_GET_PACKET_STATUS(Packet);
		NdisMIndicateReceivePacket(pAdapt->MiniportHandle, &Packet, 1);

		return Status != NDIS_STATUS_RESOURCES ? 1 : 0;
    	}

	if(NULL == pFltPkt){

		NdisDprAllocatePacket(
			&Status,
			&MyPacket,
			pAdapt->RcvPP1
			);

		if (Status != NDIS_STATUS_SUCCESS){
			return 0;
		}

		*((PVOID*)&MyPacket->MiniportReserved) = Packet;

		MyPacket->Private.Head = Packet->Private.Head;
		MyPacket->Private.Tail = Packet->Private.Tail;

	}else{

		NdisDprAllocatePacket(
			&Status,
			&MyPacket,
			pAdapt->RcvPP2
			);

		if (Status != NDIS_STATUS_SUCCESS)
			return NDIS_STATUS_NOT_ACCEPTED;

		*((PVOID*)&MyPacket->MiniportReserved) = pFltPkt;

		NdisAllocateBuffer(
			&Status,
			&pNewBuffer,
			pAdapt->RcvBP,
			pFltPkt->pBuf,
			pFltPkt->uLen
			);

		if ( Status != NDIS_STATUS_SUCCESS ){

			NdisReinitializePacket (MyPacket);
			NdisFreePacket (MyPacket);

			return 0;
		}

		NdisChainBufferAtFront(MyPacket, pNewBuffer );
	}
	NDIS_SET_ORIGINAL_PACKET(MyPacket, NDIS_GET_ORIGINAL_PACKET(Packet));
	NdisGetPacketFlags(MyPacket) = NdisGetPacketFlags(Packet);

	Status = NDIS_GET_PACKET_STATUS(Packet);

	NDIS_SET_PACKET_STATUS(MyPacket, Status);
	NDIS_SET_PACKET_HEADER_SIZE(MyPacket, NDIS_GET_PACKET_HEADER_SIZE(Packet));

	if (Status == NDIS_STATUS_RESOURCES){

		natpQueueReceivedPacket(pAdapt, MyPacket, TRUE);
	}else{

		natpQueueReceivedPacket(pAdapt, MyPacket, FALSE);
	}
	
	if (Status == NDIS_STATUS_RESOURCES)
	        NdisDprFreePacket(MyPacket);

	return Status != NDIS_STATUS_RESOURCES ? 1 : 0;
}
Exemplo n.º 11
0
PNDIS_PACKET
SecLabAllocateReceivePacket(
    PADAPT			                pAdapt,
    IN UINT                         DataLength,
    OUT PUCHAR *                    ppDataBuffer
    )
/*++

Routine Description:

    分配用于拷贝和排队接收包的资源.

Arguments:

    DataLength - 封包的总长度,包括包头和数据
    ppDataBuffer - 返回的缓冲区地址

Return Value:

    如果成功则返回包的指针,否则为空.

--*/
{
    PNDIS_PACKET            pNdisPacket;
    PNDIS_BUFFER            pNdisBuffer;
    PUCHAR                  pDataBuffer;
    NDIS_STATUS             Status;

    pNdisPacket = NULL;
    pNdisBuffer = NULL;
    pDataBuffer = NULL;

    do
    {
		NdisAllocateMemoryWithTag((PVOID *)(&pDataBuffer), DataLength,'lceS');

        if (pDataBuffer == NULL)
        {
            DbgPrint("Can not Allocate resoures for packet");
            break;
        }

        //
        //  将其转化为NDIS_BUFFER.
        //
        NdisAllocateBuffer(
            &Status,
            &pNdisBuffer,
            RecvBufferPool,
            pDataBuffer,
            DataLength);
        
        if (Status != NDIS_STATUS_SUCCESS)
        {
            DbgPrint("failed to allocate Ndis Buffer");
            break;
        }

        NdisAllocatePacket(&Status, &pNdisPacket, pAdapt->RecvPacketPoolHandle);

        if (Status != NDIS_STATUS_SUCCESS)
        {
            DbgPrint("failed to alloc NDIS packet");
            break;
        }

        NDIS_SET_PACKET_STATUS(pNdisPacket, 0);
        SECLAB_RCV_PKT_TO_ORIGINAL_BUFFER(pNdisPacket) = NULL;

        NdisChainBufferAtFront(pNdisPacket, pNdisBuffer);

        *ppDataBuffer = pDataBuffer;

        break;
    }
    while (FALSE);

    if (pNdisPacket == NULL)
    {
        //
        //  Clean up
        //
        if (pNdisBuffer != NULL)
        {
            NdisFreeBuffer(pNdisBuffer);
        }

        if (pDataBuffer != NULL)
        {
            NdisFreeMemory(pDataBuffer, 0, 0);
        }
    }

    return (pNdisPacket);
}
Exemplo n.º 12
0
BOOLEAN
ArcConvertToNdisPacket(
    IN PARC_FILTER Filter,
    IN PARC_PACKET Packet,
    IN BOOLEAN ConvertWholePacket
    )
/*++

Routine description:

    This routine builds a corresponding NDIS_PACKET in TmpNdisPacket,
    that corresponds to the arcnet packet.  The flag ConvertWholePacket
    is used to convert only part of the arcnet packet, or the whole
    stream.  If the flag is FALSE, then only the buffers that have
    free space (starting with buffer LastBuffer on up) are converted.

    NOTE: It assumes TmpNdisPacket is an initialized ndis_packet structure.

Arguments:

    Filter - Filter to allocate from.

    Packet - The packet to convert.

    ConvertWholePacket - Convert the whole stream, or only part?

Return values:

    TRUE - If successful, else FALSE

--*/
{
    PNDIS_BUFFER NdisBuffer;
    PARC_BUFFER_LIST Buffer;
    NDIS_STATUS NdisStatus;

    Buffer = Packet->FirstBuffer;

    while (Buffer != NULL) {

        NdisAllocateBuffer(
            &NdisStatus,
            &NdisBuffer,
            Filter->ReceiveBufferPool,
            Buffer->Buffer,
            Buffer->Size - Buffer->BytesLeft
            );

        if (NdisStatus != NDIS_STATUS_SUCCESS) {

            return(FALSE);

        }

        NdisChainBufferAtBack(
            &(Packet->TmpNdisPacket),
            NdisBuffer
            );

        Buffer = Buffer->Next;

    }

    return(TRUE);
}
Exemplo n.º 13
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
}
Exemplo n.º 14
0
/*+
 *
 * AllocateAdapterMemory
 *
 * Routine Description:
 *
 *     This routine allocates memory for:
 *
 *     - Transmit descriptor ring
 *     - Receive descriptor ring
 *     - Receive buffers
 *     - Transmit buffer
 *     - Setup buffer
 *
 * Arguments:
 *
 *     Adapter - The adapter to allocate memory for.
 *
 * Functional description
 *
 *     For each allocated zone, we maintain a set of pointers:
 *        - virtual & physical addresses of the allocated block
 *        - virtual & physical addresses of the aligned structure (descriptor ring, buffer,...)
 *          whithin  the block
 *
 * Return Value:
 *
 *     Returns FALSE if an allocation fails.
 *
-*/
extern
BOOLEAN
AllocateAdapterMemory(
        IN PDC21X4_ADAPTER Adapter
        )
{
   PDC21X4_TRANSMIT_DESCRIPTOR TransmitDescriptor;
   PDC21X4_RECEIVE_DESCRIPTOR ReceiveDescriptor;

   NDIS_STATUS Status;

   PRCV_HEADER RcvHeader;
   PNDIS_PACKET Packet;

   ULONG AllocSize;
   PULONG AllocVa;
   NDIS_PHYSICAL_ADDRESS AllocPa;
   ULONG Va;

   ULONG Pa;

   UINT i;
   ULONG Offset;

   INT TransmitDescriptorRingSize;
   INT ReceiveDescriptorRingSize;

   Adapter->RcvHeaderSize =
           ((RCV_HEADER_SIZE + Adapter->CacheLineSize - 1) / Adapter->CacheLineSize)
         * Adapter->CacheLineSize;


#if _DBG
   DbgPrint("Alloc Rcv_ring[%d desc.], Txm_ring[%d desc.], setup_buf[%d]...\n",
      Adapter->ReceiveRingSize,
      TRANSMIT_RING_SIZE,
      DC21X4_SETUP_BUFFER_SIZE
      );
#endif

   // Allocate space for transmit descriptor ring,
   // the receive descriptor ring and the setup buffer

   TransmitDescriptorRingSize =
      Adapter->DescriptorSize * TRANSMIT_RING_SIZE;
   ReceiveDescriptorRingSize =
      Adapter->DescriptorSize * Adapter->ReceiveRingSize;

   Adapter->DescriptorRing.AllocSize =
      TransmitDescriptorRingSize
      + ReceiveDescriptorRingSize
      + DC21X4_SETUP_BUFFER_SIZE
      + Adapter->CacheLineSize;

   NdisMAllocateSharedMemory(
      Adapter->MiniportAdapterHandle,
      Adapter->DescriptorRing.AllocSize,
      FALSE,                                           // NON-CACHED
      (PVOID *)&Adapter->DescriptorRing.AllocVa,       // virtual ...
      &Adapter->DescriptorRing.AllocPa                 // and physical address of the allocation
      );

   // Check the allocation success

   if ((PVOID)Adapter->DescriptorRing.AllocVa == (PVOID)NULL) {
      return FALSE;
   }
   if (NdisGetPhysicalAddressHigh(Adapter->DescriptorRing.AllocPa) != 0) {
      return FALSE;
   }

   NdisZeroMemory (
      (PVOID)(Adapter->DescriptorRing.AllocVa),
      (ULONG)(Adapter->DescriptorRing.AllocSize)
      );

   // Align to the next cache line boundary

   AlignStructure (
      &Adapter->DescriptorRing,
      Adapter->CacheLineSize
      );

   Adapter->TransmitDescriptorRingVa = Adapter->DescriptorRing.Va;
   Adapter->TransmitDescriptorRingPa = Adapter->DescriptorRing.Pa;
   Offset = TransmitDescriptorRingSize;

   Adapter->ReceiveDescriptorRingVa =  Adapter->DescriptorRing.Va + Offset;
   Adapter->ReceiveDescriptorRingPa =  Adapter->DescriptorRing.Pa + Offset;
   Offset += ReceiveDescriptorRingSize;

   Adapter->SetupBufferVa = Adapter->DescriptorRing.Va + Offset;
   Adapter->SetupBufferPa = Adapter->DescriptorRing.Pa + Offset;

   //Initialize the setup buffer

   NdisZeroMemory (
      (PVOID)(Adapter->SetupBufferVa),
      DC21X4_SETUP_BUFFER_SIZE
      );


   // Allocate a pool of NDIS buffers

   NdisAllocateBufferPool(
        &Status,
        &Adapter->FlushBufferPoolHandle,
        ( Adapter->ReceiveRingSize
        + Adapter->ExtraReceiveBuffers
        + DC21X4_NUMBER_OF_MAX_TRANSMIT_BUFFERS
        + DC21X4_NUMBER_OF_MIN_TRANSMIT_BUFFERS )
        );

   if (Status != NDIS_STATUS_SUCCESS) {
      return FALSE;
   }


   //  Allocate a pool of packets.
#if _DBG
   DbgPrint("Allocate PacketPool [%d packets]\n",
      Adapter->ExtraReceivePackets);
#endif
   NdisAllocatePacketPool(
      &Status,
      &Adapter->ReceivePacketPool,
      Adapter->ExtraReceivePackets,
      0
      );

   if (Status != NDIS_STATUS_SUCCESS) {
      return FALSE;
   }

   // Allocate all of the packets out of the packet pool
   // and place them on a queue.

   for (i = 0; i < Adapter->ExtraReceivePackets; i++) {

      // Allocate a packet from the pool.
      NdisAllocatePacket(
         &Status,
         &Packet,
         Adapter->ReceivePacketPool
         );
      if (Status != NDIS_STATUS_SUCCESS) {
         return(FALSE);
      }

      // Set the header size in the packet's Out-Of-Band information.
      // All other fields in the Out-Of-Band information have been
      // initialized to 0 by NdisAllocatePacket().

      NDIS_SET_PACKET_HEADER_SIZE(Packet, ETH_HEADER_SIZE);

      // Place it on the receive packet free list.

      RCV_RESERVED(Packet)->Next = Adapter->FreePacketList;
      Adapter->FreePacketList = Packet;
   }

   //  Clear out the free receive list of buffers.
   Adapter->FreeRcvList = NULL;


   //  We allocate the receive buffers.  We allocate both
   //  the buffers for the descriptor ring and the extra
   //  buffers and place them all on the free queue.

#if _DBG
   DbgPrint("Allocate Receive Buffers [%d]\n",
      Adapter->ExtraReceiveBuffers+Adapter->ReceiveRingSize);
#endif

   // Attempt to allocate all the receive buffer space
   // in one block
   // If it fails,allocate each buffer individually

   //  Allocation size
   Adapter->RcvBufferSpace.AllocSize =
      ((Adapter->ExtraReceiveBuffers + Adapter->ReceiveRingSize)
      * (DC21X4_RECEIVE_BUFFER_SIZE + Adapter->RcvHeaderSize))
      + Adapter->CacheLineSize;


   NdisMAllocateSharedMemory(
      Adapter->MiniportAdapterHandle,
      Adapter->RcvBufferSpace.AllocSize,
      TRUE,
      (PVOID *)&Adapter->RcvBufferSpace.AllocVa,
      &Adapter->RcvBufferSpace.AllocPa
      );

   // Check the allocation success
   if (((PVOID)Adapter->RcvBufferSpace.AllocVa != (PVOID)NULL)
      && (NdisGetPhysicalAddressHigh(Adapter->RcvBufferSpace.AllocPa) == 0)) {

        NdisZeroMemory (
          (PVOID)(Adapter->RcvBufferSpace.AllocVa),
          (ULONG)(Adapter->RcvBufferSpace.AllocSize)
          );

       // Align to the next cache line boundary

       AlignStructure (
          &Adapter->RcvBufferSpace,
          Adapter->CacheLineSize
          );

       //  Allocation size needed for the receive buffer
       AllocSize = DC21X4_RECEIVE_BUFFER_SIZE
                 + Adapter->RcvHeaderSize;
       Offset=0;
   }
   else
   {
       //  Allocation size needed for the receive buffer
       AllocSize = DC21X4_RECEIVE_BUFFER_SIZE
                 + Adapter->RcvHeaderSize
                 + Adapter->CacheLineSize;


       Adapter->RcvBufferSpace.Va=0;
   }

   for (i = 0;
      i < (Adapter->ExtraReceiveBuffers + Adapter->ReceiveRingSize);
      i++
      ) {

      if (Adapter->RcvBufferSpace.Va != 0) {

          Va = Adapter->RcvBufferSpace.Va + Offset;
          Pa = Adapter->RcvBufferSpace.Pa + Offset;
          Offset += AllocSize;

      }
      else
      {
          //  Allocate a receive buffer.

          NdisMAllocateSharedMemory(
             Adapter->MiniportAdapterHandle,
             AllocSize,
             TRUE,
             (PVOID *)&AllocVa,
             &AllocPa
             );
          if (((PVOID)AllocVa == (PVOID)NULL)
             || (NdisGetPhysicalAddressHigh(AllocPa) != 0)) {
             return FALSE;
          }

          NdisZeroMemory(AllocVa, AllocSize);

          //  Align on the cache line boundary

          Offset = Adapter->CacheLineSize - ((ULONG)AllocVa % Adapter->CacheLineSize);
          Va = (ULONG)(AllocVa) + Offset;
          Pa = NdisGetPhysicalAddressLow(AllocPa) + Offset;

      }

      //The receive header points to the aligned va.

      RcvHeader = (PRCV_HEADER)Va;

      RcvHeader->AllocVa = (ULONG)AllocVa;
      RcvHeader->AllocPa = AllocPa;
      RcvHeader->AllocSize = (USHORT)AllocSize;

      // These addresses point to the data buffer

      RcvHeader->Va = (ULONG)(Va + Adapter->RcvHeaderSize);
      RcvHeader->Pa = Pa + Adapter->RcvHeaderSize;
      RcvHeader->Size = DC21X4_RECEIVE_BUFFER_SIZE;

#if DBG
      RcvHeader->Signature = 'dHxR';
#if _DBG
      DbgPrint(
         "%-3d RcvHeader: %lx, RcvBuffer: %lx/%lx, HeaderSize: %lx\n",
         i,RcvHeader,
         RcvHeader->Va,
         RcvHeader->Pa,
         Adapter->RcvHeaderSize
         );
#endif
#endif
      //  Allocate an NDIS flush buffer for each receive buffer.

      NdisAllocateBuffer(
         &Status,
         &RcvHeader->FlushBuffer,
         Adapter->FlushBufferPoolHandle,
         (PVOID)RcvHeader->Va,
         DC21X4_RECEIVE_BUFFER_SIZE
         );
      if (Status != NDIS_STATUS_SUCCESS) {
         return FALSE;
      }

      // Grab a packet off of the free packet list and
      // associate it with the buffer.

      Packet = Adapter->FreePacketList;
      Adapter->FreePacketList = RCV_RESERVED(Packet)->Next;

      // Chain the buffer on the packet.

      NdisChainBufferAtFront(Packet, RcvHeader->FlushBuffer);

      // Save a pointer to the receive header with the packet.

      RCV_RESERVED(Packet)->RcvHeader = RcvHeader;

      // Save the packet with the receive header.

      RcvHeader->Packet = Packet;

      // Place the descriptor on the free queue.

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

      Adapter->CurrentReceiveBufferCount++;
   }


#if _DBG
   DbgPrint("Init Rcv ring..\n");
#endif

   //  Assign the receive buffers to the descriptors.

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

      // Grab a receive buffer from the free list.

      ASSERT(Adapter->FreeRcvList != NULL);
      RcvHeader = Adapter->FreeRcvList;
      Adapter->FreeRcvList = RcvHeader->Next;

      Adapter->CurrentReceiveBufferCount--;

      // Associate the buffer with the descriptor.

      ReceiveDescriptor->RcvHeader = RcvHeader;
      ReceiveDescriptor->FirstBufferAddress = RcvHeader->Pa;


      ReceiveDescriptor->Status = DESC_OWNED_BY_DC21X4;
      ReceiveDescriptor->Control = DC21X4_RECEIVE_BUFFER_SIZE;

      ReceiveDescriptor->Next =
         (PDC21X4_RECEIVE_DESCRIPTOR)((PCHAR)ReceiveDescriptor + Adapter->DescriptorSize);

   }

   //last descriptor of the ring

   (PCHAR)ReceiveDescriptor -= Adapter->DescriptorSize;
   ReceiveDescriptor->Control |= DC21X4_RDES_SECOND_ADDR_CHAINED;
   ReceiveDescriptor->SecondBufferAddress = Adapter->ReceiveDescriptorRingPa;
   ReceiveDescriptor->Next =
      (PDC21X4_RECEIVE_DESCRIPTOR)Adapter->ReceiveDescriptorRingVa;

#if _DBG
   DbgPrint("Init Txm ring..\n");
#endif

   // Initialize the Transmit Descriptor ring

   for (i=0,
      TransmitDescriptor = (PDC21X4_TRANSMIT_DESCRIPTOR)Adapter->TransmitDescriptorRingVa,
      Pa = Adapter->TransmitDescriptorRingPa;
      i < TRANSMIT_RING_SIZE;
      i++,
      (PCHAR)TransmitDescriptor += Adapter->DescriptorSize,
      Pa += Adapter->DescriptorSize
      ) {

      TransmitDescriptor->MapTableIndex = i * NUMBER_OF_SEGMENT_PER_DESC;
      TransmitDescriptor->DescriptorPa = Pa;
      TransmitDescriptor->Next =
         (PDC21X4_TRANSMIT_DESCRIPTOR)((PCHAR)TransmitDescriptor + Adapter->DescriptorSize);

   }

   //last descriptor of the ring
   (PCHAR)TransmitDescriptor -= Adapter->DescriptorSize;
   TransmitDescriptor->Control = DC21X4_TDES_SECOND_ADDR_CHAINED;
   TransmitDescriptor->SecondBufferAddress = Adapter->TransmitDescriptorRingPa;
   TransmitDescriptor->Next =
      (PDC21X4_TRANSMIT_DESCRIPTOR)Adapter->TransmitDescriptorRingVa;


   // Txm buffers

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

      Adapter->MaxTransmitBuffer[i].AllocSize =
         DC21X4_MAX_TRANSMIT_BUFFER_SIZE + Adapter->CacheLineSize;

      NdisMAllocateSharedMemory(
         Adapter->MiniportAdapterHandle,
         Adapter->MaxTransmitBuffer[i].AllocSize,
         TRUE,                                           // CACHED
         (PVOID *)&Adapter->MaxTransmitBuffer[i].AllocVa,   // virtual ...
         &Adapter->MaxTransmitBuffer[i].AllocPa             // and physical address of the buffer allocation
         );

      // Check the allocation success

      if (((PVOID)Adapter->MaxTransmitBuffer[i].AllocVa == (PVOID)NULL)
         || (NdisGetPhysicalAddressHigh(Adapter->MaxTransmitBuffer[i].AllocPa) != 0)) {
         return FALSE;
      }

      // Align the buffer on the cache line boundary

      AlignStructure (
         &Adapter->MaxTransmitBuffer[i],
         Adapter->CacheLineSize
         );


      // Allocate an NDIS flush buffer for each transmit buffer

      NdisAllocateBuffer(
         &Status,
         &Adapter->MaxTransmitBuffer[i].FlushBuffer,
         Adapter->FlushBufferPoolHandle,
         (PVOID)Adapter->MaxTransmitBuffer[i].Va,
         DC21X4_MAX_TRANSMIT_BUFFER_SIZE
         );

      if (Status != NDIS_STATUS_SUCCESS) {
         return FALSE;
      }
   }

   // Allocate the minimal packet buffers

   Adapter->MinTransmitBuffer[0].AllocSize =
       (DC21X4_NUMBER_OF_MIN_TRANSMIT_BUFFERS * DC21X4_MIN_TRANSMIT_BUFFER_SIZE)
     + Adapter->CacheLineSize;

   NdisMAllocateSharedMemory(
     Adapter->MiniportAdapterHandle,
     Adapter->MinTransmitBuffer[0].AllocSize,
     TRUE,                                              // CACHED
     (PVOID *)&Adapter->MinTransmitBuffer[0].AllocVa,   // virtual ...
     &Adapter->MinTransmitBuffer[0].AllocPa             // and physical address of the buffer allocation
     );

   // Check the allocation success

   if (((PVOID)Adapter->MinTransmitBuffer[0].AllocVa == (PVOID)NULL)
       || (NdisGetPhysicalAddressHigh(Adapter->MinTransmitBuffer[0].AllocPa) != 0)) {

	  Adapter->DontUseMinTransmitBuffer = TRUE;
      return TRUE;
   }

   // Align the buffer on the cache line boundary

   AlignStructure (
      &Adapter->MinTransmitBuffer[0],
      Adapter->CacheLineSize
      );

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

      Offset = i * DC21X4_MIN_TRANSMIT_BUFFER_SIZE;

      Adapter->MinTransmitBuffer[i].Va =
          Adapter->MinTransmitBuffer[0].Va + Offset;

      Adapter->MinTransmitBuffer[i].Pa =
          Adapter->MinTransmitBuffer[0].Pa + Offset;

      // Allocate an NDIS flush buffer for each transmit buffer

      NdisAllocateBuffer(
         &Status,
         &Adapter->MinTransmitBuffer[i].FlushBuffer,
         Adapter->FlushBufferPoolHandle,
         (PVOID)Adapter->MinTransmitBuffer[i].Va,
         DC21X4_MIN_TRANSMIT_BUFFER_SIZE
         );

      if (Status != NDIS_STATUS_SUCCESS) {
         return FALSE;
      }
   }

   // Allocation has completed successfully

   return TRUE;
}
Exemplo n.º 15
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;
}
Exemplo n.º 16
0
NTSTATUS
PacketAllocate(
    IN	PSERVICE_POINT		ServicePoint,
    IN	ULONG				PacketLength,
    IN	PDEVICE_CONTEXT		DeviceContext,
    IN	UCHAR				Type,
    IN	PUCHAR				CopyData,
    IN	ULONG				CopyDataLength,
    IN	PIO_STACK_LOCATION	IrpSp,
    OUT	PNDIS_PACKET		*Packet
)
{
    NTSTATUS		status;
    PUCHAR			packetData;
    PNDIS_BUFFER	pNdisBuffer;
    PNDIS_BUFFER	pNdisBufferData;
    PNDIS_PACKET	packet;
    USHORT			port;

    DebugPrint(3, ("PacketAllocate, PacketLength = %d, Numberofpackets = %d\n", PacketLength, NumberOfPackets));

    //	if(ServicePoint && ServicePoint->SmpState == SMP_SYN_RECV)
    //		return STATUS_INSUFFICIENT_RESOURCES;

    if(DeviceContext == NULL) {
        DebugPrint(1, ("[LPX]PacketAllocate: DeviceContext is NULL!!!\n"));
        return STATUS_INVALID_PARAMETER;
    }

    if(DeviceContext->LpxPacketPool == NULL) {
        DebugPrint(1, ("[LPX]PacketAllocate: DeviceContext->LpxPacketPool is NULL!!!\n"));
        return STATUS_INVALID_PARAMETER;
    }

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

    if(status != NDIS_STATUS_SUCCESS) {
        DebugPrint(1, ("[LPX]PacketAllocate: NdisAllocatePacket Failed!!!\n"));
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    status = NdisAllocateMemory(
                 &packetData,
                 PacketLength
             );
    if(status != NDIS_STATUS_SUCCESS) {
        DebugPrint(1, ("[LpxSmp]PacketAllocate: Can't Allocate Memory packet.\n"));

        NdisFreePacket(packet);
        *Packet = NULL;

        return status;
    }

    NdisAllocateBuffer(
        &status,
        &pNdisBuffer,
        DeviceContext->LpxBufferPool,
        packetData,
        PacketLength
    );
    if(!NT_SUCCESS(status)) {
        NdisFreePacket(packet);
        *Packet = NULL;
        NdisFreeMemory(packetData);
        DebugPrint(1, ("[LPX]PacketAllocate: Can't Allocate Buffer!!!\n"));

        return status;
    }

    switch(Type) {

    case SEND_TYPE:

        if(ServicePoint && &ServicePoint->SmpContext) {
            RtlCopyMemory(&packetData[0],
                          ServicePoint->DestinationAddress.Node,
                          ETHERNET_ADDRESS_LENGTH
                         );
            RtlCopyMemory(&packetData[ETHERNET_ADDRESS_LENGTH],
                          ServicePoint->SourceAddress.Node,
                          ETHERNET_ADDRESS_LENGTH
                         );
            port = HTONS(ETH_P_LPX);
            RtlCopyMemory(&packetData[ETHERNET_ADDRESS_LENGTH*2],
                          &port, //&ServicePoint->DestinationAddress.Port,
                          2
                         );
        }

        if(CopyDataLength) {

            NdisAllocateBuffer(
                &status,
                &pNdisBufferData,
                DeviceContext->LpxBufferPool,
                CopyData,
                CopyDataLength
            );
            if(!NT_SUCCESS(status)) {
                NdisFreePacket(packet);
                *Packet = NULL;
                NdisFreeMemory(packetData);
                DebugPrint(1, ("[LPX]PacketAllocate: Can't Allocate Buffer For CopyData!!!\n"));

                return status;
            }

            NdisChainBufferAtFront(packet, pNdisBufferData);
        }
        break;

    case RECEIVE_TYPE:

        NdisMoveMappedMemory(
            packetData,
            CopyData,
            CopyDataLength
        );

        break;
    }

    //	RESERVED(packet)->ServicePoint = ServicePoint;
    RESERVED(packet)->Cloned = 0;
    RESERVED(packet)->IrpSp = IrpSp;
    RESERVED(packet)->Type = Type;
    RESERVED(packet)->LpxSmpHeader = NULL;

    if(IrpSp == NULL) {
        DebugPrint(2, ("[LPX] PacketAllocate: No IrpSp\n")) ;
    }

    NdisChainBufferAtFront(packet, pNdisBuffer);

    InterlockedIncrement(&NumberOfPackets);

    *Packet = packet;
    return STATUS_SUCCESS;
}
Exemplo n.º 17
0
//***********************************************************************************
// 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;
}
Exemplo n.º 18
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;
}
Exemplo n.º 19
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;
}
Exemplo n.º 20
0
VOID PacketAllocatePacketBuffer(PNDIS_STATUS    pStatus,
                                POPEN_INSTANCE  pOpen,
                                PNDIS_PACKET    *ppPacket,
                                PDIOCPARAMETERS pDiocParms,
                                DWORD           FunctionCode )
{
  // allocate a buffer for reading/writing

  PNDIS_BUFFER pNdisBuffer;
  PNDIS_PACKET pPacket;
  

  //  Try to get a packet from our list of free ones
  NdisAllocatePacket(pStatus, ppPacket, pOpen->PacketPool);
  
  if (*pStatus != NDIS_STATUS_SUCCESS) {
    *(DWORD *)(pDiocParms->lpcbBytesReturned) = 0;
    return;
  }
  
  pPacket = *ppPacket;
  
  // Buffers used asynchronously must be page locked
  switch (FunctionCode) {
    case IOCTL_EPACKET_READ:
      RESERVED(pPacket)->lpBuffer = (PVOID)PacketPageLock(pDiocParms->lpvOutBuffer, pDiocParms->cbOutBuffer);
      RESERVED(pPacket)->cbBuffer = pDiocParms->cbOutBuffer;
      break;
    
    case IOCTL_EPACKET_WRITE:
      RESERVED(pPacket)->lpBuffer = (PVOID)PacketPageLock(pDiocParms->lpvInBuffer, pDiocParms->cbInBuffer);
      RESERVED(pPacket)->cbBuffer = pDiocParms->cbInBuffer;
      break;
    
    default:
      // recycle the packet
      NdisReinitializePacket(pPacket);
    
      // Put the packet on the free queue
      NdisFreePacket(pPacket);
    
      *(DWORD *)(pDiocParms->lpcbBytesReturned) = 0;
      *pStatus = NDIS_STATUS_NOT_ACCEPTED;
      return;
  }
  
  RESERVED(pPacket)->lpcbBytesReturned = (PVOID)PacketPageLock(pDiocParms->lpcbBytesReturned, sizeof(DWORD));
  RESERVED(pPacket)->lpoOverlapped     = (PVOID)PacketPageLock(pDiocParms->lpoOverlapped, sizeof(OVERLAPPED));
  RESERVED(pPacket)->hDevice           = pDiocParms->hDevice;
  RESERVED(pPacket)->tagProcess        = pDiocParms->tagProcess;
  
  switch (FunctionCode) {
    case IOCTL_EPACKET_READ:
      NdisAllocateBuffer(pStatus,
                         &pNdisBuffer,
                         pOpen->BufferPool,
                         (PVOID)(RESERVED(pPacket)->lpBuffer + ETHERNET_HEADER_LENGTH),
                         pDiocParms->cbOutBuffer);
      break;
    
    case IOCTL_EPACKET_WRITE:
      NdisAllocateBuffer(pStatus,
                         &pNdisBuffer,
                         pOpen->BufferPool,
                         (PVOID)RESERVED(pPacket)->lpBuffer,
                         pDiocParms->cbInBuffer);
      break;
  }
  
  if (*pStatus == NDIS_STATUS_SUCCESS)
    NdisChainBufferAtFront(pPacket, pNdisBuffer); // Attach buffer to Packet
  else {
    NdisReinitializePacket(pPacket);  // recycle the packet
    NdisFreePacket(pPacket);          // Put the packet on the free queue
    *(DWORD *)(pDiocParms->lpcbBytesReturned) = 0;
  }
}
Exemplo n.º 21
0
NTSTATUS netgSendToMiniport(PDEVICE_OBJECT pDeviceObject, PIRP pIrp) {
	PIO_STACK_LOCATION  pIrpSp;
	NTSTATUS            NtStatus = STATUS_SUCCESS;
	NDIS_STATUS         Status;
	ULONG               BytesReturned = 0;
	PUCHAR              ioBuffer = NULL;
	ULONG               inputBufferLength;
	ULONG               outputBufferLength, Remaining;
	POPEN_CONTEXT       pOpenContext;
	PNDIS_PACKET        pNdisPacket;
    PNDIS_BUFFER        pNdisBuffer;

	DBGPRINT(("      netgSendToMiniport Called \n"));

	UNREFERENCED_PARAMETER(pDeviceObject);

	pIrpSp = IoGetCurrentIrpStackLocation(pIrp);

	pOpenContext = pIrpSp->FileObject->FsContext;
	ioBuffer = pIrp->AssociatedIrp.SystemBuffer;
	inputBufferLength  = pIrpSp->Parameters.DeviceIoControl.InputBufferLength;
	outputBufferLength = pIrpSp->Parameters.DeviceIoControl.OutputBufferLength;
	Remaining = outputBufferLength;

	DBGPRINT(("==> netgSendToMiniport: FileObject %p\n", pIrpSp->FileObject ));

	if( !pOpenContext ) {
		DBGPRINT(( "      Invalid Handle\n" ));
		NtStatus = STATUS_INVALID_HANDLE;
		goto CompleteTheIRP;
	}

	DBGPRINT(("     Len: %d Data: %x%x...\n", pIrpSp->Parameters.DeviceIoControl.InputBufferLength, ioBuffer[0], ioBuffer[1]));

	// Allocate a send packet.
	pNdisPacket = NULL;
	NdisAllocatePacket(&Status, &pNdisPacket, pOpenContext->SendPacketPool);
	if (Status != NDIS_STATUS_SUCCESS) {
		DBGPRINT(("     netgSendToMiniport: open %p, failed to alloc send pkt\n", pOpenContext));
        NtStatus = STATUS_INSUFFICIENT_RESOURCES;
        goto CompleteTheIRP;
    }

	// Allocate a send buffer.
	NdisAllocateBuffer(&Status, &pNdisBuffer, pOpenContext->SendBufferPool, ioBuffer, inputBufferLength);
    if (Status != NDIS_STATUS_SUCCESS) {
        NdisFreePacket(pNdisPacket);
        DBGPRINT(("     netgSendToMiniport: open %p, failed to alloc send buf\n", pOpenContext));
        NtStatus = STATUS_INSUFFICIENT_RESOURCES;
		goto CompleteTheIRP;
	}

	IoMarkIrpPending(pIrp);
	((PNPROT_SEND_PACKET_RSVD)&((pNdisPacket)->ProtocolReserved[0]))->RefCount = 1;
	(((PNPROT_SEND_PACKET_RSVD)&((pNdisPacket)->ProtocolReserved[0]))->pIrp) = pIrp;
	NtStatus = STATUS_PENDING;

	pNdisBuffer->Next = NULL;
	NdisChainBufferAtFront(pNdisPacket, pNdisBuffer);
	NdisSendPackets(pOpenContext->pAdapt->BindingHandle, &pNdisPacket, 1);

CompleteTheIRP:
	if (NtStatus != STATUS_PENDING) {
		pIrp->IoStatus.Information = BytesReturned;
		pIrp->IoStatus.Status = NtStatus;
		IoCompleteRequest(pIrp, IO_NO_INCREMENT);
	}

	DBGPRINT(("<== netgSendToMiniport\n"));
	return NtStatus;
}
Exemplo n.º 22
0
NDIS_STATUS
NdisuioReceive(
    IN NDIS_HANDLE                  ProtocolBindingContext,
    IN NDIS_HANDLE                  MacReceiveContext,
    IN PVOID                        pHeaderBuffer,
    IN UINT                         HeaderBufferSize,
    IN PVOID                        pLookaheadBuffer,
    IN UINT                         LookaheadBufferSize,
    IN UINT                         PacketSize
    )
/*++

Routine Description:

    Our protocol receive handler called by NDIS, typically if we have
    a miniport below that doesn't indicate packets.

    We make a local packet/buffer copy of this data, queue it up, and
    kick off the read service routine.

Arguments:

    ProtocolBindingContext - pointer to open context
    MacReceiveContext - for use in NdisTransferData
    pHeaderBuffer - pointer to data header
    HeaderBufferSize - size of the above
    pLookaheadBuffer - pointer to buffer containing lookahead data
    LookaheadBufferSize - size of the above
    PacketSize - size of the entire packet, minus header size.

Return Value:

    NDIS_STATUS_NOT_ACCEPTED - if this packet is uninteresting
    NDIS_STATUS_SUCCESS - if we processed this successfully

--*/
{
    PNDISUIO_OPEN_CONTEXT   pOpenContext;
    NDIS_STATUS             Status;
    PNDISUIO_ETH_HEADER     pEthHeader;
    PNDIS_PACKET            pRcvPacket;
    PUCHAR                  pRcvData;
    UINT                    BytesTransferred;
    PNDIS_BUFFER            pOriginalNdisBuffer, pPartialNdisBuffer;
    PIRP					pIrp;
    PLIST_ENTRY				pIrpEntry;
    ULONG					BytesRemaining; // at pDst
	PPACKET_GROUP			pGroup;

	//ULONG                   pDst;
	
    pOpenContext = (PNDISUIO_OPEN_CONTEXT)ProtocolBindingContext;
    NUIO_STRUCT_ASSERT(pOpenContext, oc);
    pRcvPacket = NULL;
    pRcvData = NULL;
    Status = NDIS_STATUS_SUCCESS;

    DEBUGP(DL_LOUD, ("Receive: Open %p, LookaheadBufferSize %d, PacketSize %d\n",
		pOpenContext, LookaheadBufferSize, PacketSize));
    
	NdisInterlockedAddLargeStatistic((PLARGE_INTEGER)&pOpenContext->ReceivedPackets, 1);

	do
    {
        if (HeaderBufferSize != sizeof(NDISUIO_ETH_HEADER))
        {
            Status = NDIS_STATUS_NOT_ACCEPTED;
            break;
        }

        pEthHeader = (PNDISUIO_ETH_HEADER)pHeaderBuffer;

		NUIO_ACQUIRE_LOCK(&pOpenContext->Lock);

		//
		// Someone is reading, and this is the first packet.
		//
		if (!NUIO_IS_LIST_EMPTY(&pOpenContext->PendedReads) &&
			NUIO_IS_LIST_EMPTY(&pOpenContext->RecvPktQueue))
		{
			//
			//  Get the first pended Read IRP
			//
			pIrpEntry = pOpenContext->PendedReads.Flink;
			pIrp = CONTAINING_RECORD(pIrpEntry, IRP, Tail.Overlay.ListEntry);
			
			//
			// We don't have to worry about the situation where the IRP is cancelled
			// after we remove it from the queue and before we reset the cancel
			// routine because the cancel routine has been coded to cancel an IRP
			// only if it's in the queue.
			//
			IoSetCancelRoutine(pIrp, NULL);

			NUIO_REMOVE_ENTRY_LIST(pIrpEntry);
			
			pOpenContext->PendedReadCount--;

			NUIO_RELEASE_LOCK(&pOpenContext->Lock);

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

			//
			//  Copy as much data as possible from the receive packet to
			//  the IRP MDL.
			//
#ifndef WIN9X
			pGroup = MmGetSystemAddressForMdlSafe(pIrp->MdlAddress, NormalPagePriority);
			//NUIO_ASSERT(pDst != NULL);  // since it was already mapped
#else
			pGroup = MmGetSystemAddressForMdl(pIrp->MdlAddress);  // Win9x
#endif
			BytesRemaining = MmGetMdlByteCount(pIrp->MdlAddress);
			
			BytesRemaining -= sizeof(PACKET_GROUP);

			//
			//  copy the ethernet header into the actual readbuffer
			//
			NdisMoveMappedMemory(pGroup->Data, pHeaderBuffer, HeaderBufferSize);
			
			if (PacketSize == LookaheadBufferSize)
			{
				BytesTransferred = MIN(LookaheadBufferSize, BytesRemaining);

				NdisCopyLookaheadData(pGroup->Data + HeaderBufferSize,
					pLookaheadBuffer,
					BytesTransferred,
					pOpenContext->MacOptions);

				pGroup->Length = BytesTransferred + HeaderBufferSize;
				
				pIrp->IoStatus.Information = pGroup->Length + sizeof(PACKET_GROUP);
				pIrp->IoStatus.Status = STATUS_SUCCESS;				
		
				DEBUGP(DL_LOUD, ("Receive: %d bytes\n", pIrp->IoStatus.Information));
		
				IoCompleteRequest(pIrp, IO_NO_INCREMENT);
			}
			else
			{
				BytesTransferred = 0;

				NdisAllocatePacket(
					&Status,
					&pRcvPacket,
					pOpenContext->RecvBufferPool
					);
				
				if (Status != NDIS_STATUS_SUCCESS)
					goto ERROR;
				
				//
				//  Allocate an MDL to map the portion of the buffer following the
				//  header
				//
				pPartialNdisBuffer = IoAllocateMdl(pGroup->Data, BytesRemaining, FALSE, FALSE, NULL);
				
				if (pPartialNdisBuffer == NULL)
				{
					NdisFreePacket(pRcvPacket);
					Status = NDIS_STATUS_RESOURCES;
					goto ERROR;
				}
				
				//
				//  Build the mdl to point to the the portion of the buffer following
				//  the header
				//
				IoBuildPartialMdl(
					pIrp->MdlAddress,
					pPartialNdisBuffer,
					pGroup->Data + HeaderBufferSize,
					0);
				
				//
				//  Clear the next link in the new MDL
				//
				
				pPartialNdisBuffer->Next = NULL;
				
				//
				//  Get a pointer to the packet itself.
				//
				
				NUIO_IRP_FROM_RCV_PKT(pRcvPacket) = pIrp;
				NUIO_RCV_PKT_TO_ORIGINAL_BUFFER(pRcvPacket) = pPartialNdisBuffer;
				
				//
				//  Attach our partial MDL to the packet
				//
				
				NdisChainBufferAtFront(pRcvPacket, pPartialNdisBuffer);
				
				//
				//  Call the Mac to transfer the packet
				//
				
				NdisTransferData(
					&Status,
					pOpenContext->BindingHandle,
					MacReceiveContext,
					0,  // ByteOffset
					PacketSize,
					pRcvPacket,
					&BytesTransferred);

ERROR:					
				//
				//  If it didn't pend, call the completeion routine now
				//
				if (Status != NDIS_STATUS_PENDING)
				{
					NdisuioTransferDataComplete(
						(NDIS_HANDLE)pOpenContext,
						pRcvPacket,
						Status,
						BytesTransferred);
				}
			}

			break;
		}

		NUIO_RELEASE_LOCK(&pOpenContext->Lock);

		//
        //  Allocate resources for queueing this up.
        //
        pRcvPacket = ndisuioAllocateReceivePacket(
			pOpenContext,
			PacketSize + HeaderBufferSize,
			&pRcvData
			);

        if (pRcvPacket == NULL)
        {
            Status = NDIS_STATUS_NOT_ACCEPTED;
            break;
        }

        NdisMoveMappedMemory(pRcvData, pHeaderBuffer, HeaderBufferSize);

        //
        //  Check if the entire packet is within the lookahead.
        //
        if (PacketSize == LookaheadBufferSize)
        {
            NdisCopyLookaheadData(pRcvData + HeaderBufferSize,
                                  pLookaheadBuffer,
                                  LookaheadBufferSize,
                                  pOpenContext->MacOptions);
            //
            //  Queue this up for receive processing, and
            //  try to complete some read IRPs.
            //
            ndisuioQueueReceivePacket(pOpenContext, pRcvPacket);
        }
        else
        {
            //
            //  Allocate an NDIS buffer to map the receive area
            //  at an offset "HeaderBufferSize" from the current
            //  start. This is so that NdisTransferData can copy
            //  in at the right point in the destination buffer.
            //

            NdisAllocateBuffer(
                &Status,
                &pPartialNdisBuffer,
                pOpenContext->RecvBufferPool,
                pRcvData + HeaderBufferSize,
                PacketSize);
            
            if (Status == NDIS_STATUS_SUCCESS)
            {
                //
                //  Unlink and save away the original NDIS Buffer
                //  that maps the full receive buffer.
                //
                NdisUnchainBufferAtFront(pRcvPacket, &pOriginalNdisBuffer);
                NUIO_RCV_PKT_TO_ORIGINAL_BUFFER(pRcvPacket) = pOriginalNdisBuffer;
				NUIO_IRP_FROM_RCV_PKT(pRcvPacket) = NULL;

                //
                //  Link in the partial buffer for NdisTransferData to
                //  operate on.
                //
                NdisChainBufferAtBack(pRcvPacket, pPartialNdisBuffer);

                DEBUGP(DL_LOUD, ("Receive: setting up for TransferData:"
                        " Pkt %p, OriginalBuf %p, PartialBuf %p\n",
                        pRcvPacket, pOriginalNdisBuffer, pPartialNdisBuffer));

                NdisTransferData(
                    &Status,
                    pOpenContext->BindingHandle,
                    MacReceiveContext,
                    0,  // ByteOffset
                    PacketSize,
                    pRcvPacket,
                    &BytesTransferred);
            }
            else
            {
                //
                //  Failure handled below in TransferDataComplete.
                //
                BytesTransferred = 0;
            }
    
            if (Status != NDIS_STATUS_PENDING)
            {
                NdisuioTransferDataComplete(
                    (NDIS_HANDLE)pOpenContext,
                    pRcvPacket,
                    Status,
                    BytesTransferred);
            }
        }
    } while (FALSE);

	if (Status != NDIS_STATUS_SUCCESS && Status != NDIS_STATUS_PENDING)
		NdisInterlockedAddLargeStatistic((PLARGE_INTEGER)&pOpenContext->DroppedPackets, 1);

    return Status;
}
Exemplo n.º 23
0
NTSTATUS
NdisProtWrite(
    IN PDEVICE_OBJECT       pDeviceObject,
    IN PIRP                 pIrp
)
/*++

Routine Description:

    Dispatch routine to handle IRP_MJ_WRITE.

Arguments:

    pDeviceObject - pointer to our device object
    pIrp - Pointer to request packet

Return Value:

    NT status code.

--*/
{
    PIO_STACK_LOCATION      pIrpSp;
    ULONG                   DataLength;
    NTSTATUS                NtStatus;
    NDIS_STATUS             Status;
    PNDISPROT_OPEN_CONTEXT   pOpenContext;
    PNDIS_PACKET            pNdisPacket;
    PNDIS_BUFFER            pNdisBuffer;
    NDISPROT_ETH_HEADER UNALIGNED *pEthHeader;
#ifdef NDIS51
    PVOID                   CancelId;
#endif

    UNREFERENCED_PARAMETER(pDeviceObject);

    pIrpSp = IoGetCurrentIrpStackLocation(pIrp);
    pOpenContext = pIrpSp->FileObject->FsContext;

    pNdisPacket = NULL;

    do
    {
        if (pOpenContext == NULL)
        {
            DEBUGP(DL_WARN, ("Write: FileObject %p not yet associated with a device\n",
                             pIrpSp->FileObject));
            NtStatus = STATUS_INVALID_HANDLE;
            break;
        }

        NPROT_STRUCT_ASSERT(pOpenContext, oc);

        if (pIrp->MdlAddress == NULL)
        {
            DEBUGP(DL_FATAL, ("Write: NULL MDL address on IRP %p\n", pIrp));
            NtStatus = STATUS_INVALID_PARAMETER;
            break;
        }
        //
        // Try to get a virtual address for the MDL.
        //

        pEthHeader = MmGetSystemAddressForMdlSafe(pIrp->MdlAddress, NormalPagePriority);

        if (pEthHeader == NULL)
        {
            DEBUGP(DL_FATAL, ("Write: MmGetSystemAddr failed for"
                              " IRP %p, MDL %p\n",
                              pIrp, pIrp->MdlAddress));
            NtStatus = STATUS_INSUFFICIENT_RESOURCES;
            break;
        }

        //
        // Sanity-check the length.
        //
        DataLength = MmGetMdlByteCount(pIrp->MdlAddress);
        if (DataLength < sizeof(NDISPROT_ETH_HEADER))
        {
            DEBUGP(DL_WARN, ("Write: too small to be a valid packet (%d bytes)\n",
                             DataLength));
            NtStatus = STATUS_BUFFER_TOO_SMALL;
            break;
        }

        if (DataLength > (pOpenContext->MaxFrameSize + sizeof(NDISPROT_ETH_HEADER)))
        {
            DEBUGP(DL_WARN, ("Write: Open %p: data length (%d)"
                             " larger than max frame size (%d)\n",
                             pOpenContext, DataLength, pOpenContext->MaxFrameSize));

            NtStatus = STATUS_INVALID_BUFFER_SIZE;
            break;
        }

        //
        // To prevent applications from sending packets with spoofed
        // mac address, we will do the following check to make sure the source
        // address in the packet is same as the current MAC address of the NIC.
        //
        if ((pIrp->RequestorMode == UserMode) &&
                !NPROT_MEM_CMP(pEthHeader->SrcAddr, pOpenContext->CurrentAddress, NPROT_MAC_ADDR_LEN))
        {
            DEBUGP(DL_WARN, ("Write: Failing with invalid Source address"));
            NtStatus = STATUS_INVALID_PARAMETER;
            break;
        }

        NPROT_ACQUIRE_LOCK(&pOpenContext->Lock);

        if (!NPROT_TEST_FLAGS(pOpenContext->Flags, NUIOO_BIND_FLAGS, NUIOO_BIND_ACTIVE))
        {
            NPROT_RELEASE_LOCK(&pOpenContext->Lock);

            DEBUGP(DL_FATAL, ("Write: Open %p is not bound"
                              " or in low power state\n", pOpenContext));

            NtStatus = STATUS_INVALID_HANDLE;
            break;
        }

        //
        //  Allocate a send packet.
        //
        NPROT_ASSERT(pOpenContext->SendPacketPool != NULL);
        NdisAllocatePacket(
            &Status,
            &pNdisPacket,
            pOpenContext->SendPacketPool);

        if (Status != NDIS_STATUS_SUCCESS)
        {
            NPROT_RELEASE_LOCK(&pOpenContext->Lock);

            DEBUGP(DL_FATAL, ("Write: open %p, failed to alloc send pkt\n",
                              pOpenContext));
            NtStatus = STATUS_INSUFFICIENT_RESOURCES;
            break;
        }

        //
        //  Allocate a send buffer if necessary.
        //
        if (pOpenContext->bRunningOnWin9x)
        {
            NdisAllocateBuffer(
                &Status,
                &pNdisBuffer,
                pOpenContext->SendBufferPool,
                pEthHeader,
                DataLength);

            if (Status != NDIS_STATUS_SUCCESS)
            {
                NPROT_RELEASE_LOCK(&pOpenContext->Lock);

                NdisFreePacket(pNdisPacket);

                DEBUGP(DL_FATAL, ("Write: open %p, failed to alloc send buf\n",
                                  pOpenContext));
                NtStatus = STATUS_INSUFFICIENT_RESOURCES;
                break;
            }
        }
        else
        {
            pNdisBuffer = pIrp->MdlAddress;
        }

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

        NPROT_REF_OPEN(pOpenContext);  // pended send

        IoMarkIrpPending(pIrp);

        //
        //  Initialize the packet ref count. This packet will be freed
        //  when this count goes to zero.
        //
        NPROT_SEND_PKT_RSVD(pNdisPacket)->RefCount = 1;

#ifdef NDIS51

        //
        //  NDIS 5.1 supports cancelling sends. We set up a cancel ID on
        //  each send packet (which maps to a Write IRP), and save the
        //  packet pointer in the IRP. If the IRP gets cancelled, we use
        //  NdisCancelSendPackets() to cancel the packet.
        //

        CancelId = NPROT_GET_NEXT_CANCEL_ID();
        NDIS_SET_PACKET_CANCEL_ID(pNdisPacket, CancelId);
        pIrp->Tail.Overlay.DriverContext[0] = (PVOID)pOpenContext;
        pIrp->Tail.Overlay.DriverContext[1] = (PVOID)pNdisPacket;

        NPROT_INSERT_TAIL_LIST(&pOpenContext->PendedWrites, &pIrp->Tail.Overlay.ListEntry);

        IoSetCancelRoutine(pIrp, NdisProtCancelWrite);

#endif // NDIS51

        NPROT_RELEASE_LOCK(&pOpenContext->Lock);

        //
        //  Set a back pointer from the packet to the IRP.
        //
        NPROT_IRP_FROM_SEND_PKT(pNdisPacket) = pIrp;

        NtStatus = STATUS_PENDING;

        pNdisBuffer->Next = NULL;
        NdisChainBufferAtFront(pNdisPacket, pNdisBuffer);

#if SEND_DBG
        {
            PUCHAR      pData;

            pData = MmGetSystemAddressForMdlSafe(pNdisBuffer, NormalPagePriority);
            NPROT_ASSERT(pEthHeader == pData);

            DEBUGP(DL_VERY_LOUD,
                   ("Write: MDL %p, MdlFlags %x, SystemAddr %p, %d bytes\n",
                    pIrp->MdlAddress, pIrp->MdlAddress->MdlFlags, pData, DataLength));

            DEBUGPDUMP(DL_VERY_LOUD, pData, MIN(DataLength, 48));
        }
#endif // SEND_DBG

        NdisSendPackets(pOpenContext->BindingHandle, &pNdisPacket, 1);

    }
    while (FALSE);

    if (NtStatus != STATUS_PENDING)
    {
        pIrp->IoStatus.Status = NtStatus;
        IoCompleteRequest(pIrp, IO_NO_INCREMENT);
    }

    return (NtStatus);
}
Exemplo n.º 24
0
/******************************************************************************
 *
 *  Name: AllocateRxQ()
 *
 *  Description: Allocate Rx Buffer
 *
 *  Arguments:  PMRVDRV_ADAPTER Adapter
 *    
 *  Return Value: NDIS_STATUS_SUCCESS or NDIS_STATUS_FAILURE
 * 
 *  Notes:        
 *
 *****************************************************************************/
NDIS_STATUS AllocateRxQ(
  IN PMRVDRV_ADAPTER Adapter
  )
{

  ULONG i;
    NDIS_STATUS tStatus;
    BOOLEAN                 bSuccess = TRUE;
    PACKET_QUEUE_NODE       **pNode;
    PNDIS_PACKET_OOB_DATA   pOOB; 

    /// Initialize rx-related variables 
    Adapter->RxBufferPoolHandle = 
    Adapter->RxPacketPoolHandle = NULL;
    //
    InitializeQKeeper(&Adapter->RxPacketFreeQueue);
    // 
    for ( i=0; i < MRVDRV_NUM_RX_PKT_IN_QUEUE; i++ )
    {
        Adapter->pRxBufVM[i] = NULL;
        Adapter->pRxBuffer[i] = NULL;
        Adapter->pRxPacket[i] = NULL;
    }

    /// Allocate all needed memory space 
    do
    {
     // packet pool 
     NdisAllocatePacketPoolEx(
                                &tStatus, 
                                &Adapter->RxPacketPoolHandle,
                                MRVDRV_NUM_RX_PKT_IN_QUEUE,
                                MRVDRV_NUM_RX_PKT_IN_QUEUE, 
                                PROTOCOL_RESERVED_SIZE_IN_PACKET);

        if ( tStatus != NDIS_STATUS_SUCCESS )
        {
            DBGPRINT(DBG_LOAD | DBG_ERROR,
                    (L"Unable to allocate packet pool!\n"));
            return tStatus;
        }

        // buffer pool 
        NdisAllocateBufferPool(
                               &tStatus,
                               &Adapter->RxBufferPoolHandle,
                               MRVDRV_NUM_RX_PKT_IN_QUEUE);
        
        if ( tStatus != NDIS_STATUS_SUCCESS )
        {
            DBGPRINT(DBG_LOAD | DBG_ERROR,
                    (L"Unable to allocate buffer pool!\n"));
            bSuccess = FALSE;
            break;
        }

    // assign space to used three array 
        for ( i=0; i < MRVDRV_NUM_RX_PKT_IN_QUEUE; i++ )
        {                          
          // data payload space array 
           tStatus = NdisAllocateMemoryWithTag(
                         &Adapter->pRxBufVM[i], 
                         MRVDRV_ETH_RX_PACKET_BUFFER_SIZE,
                         MRVDRV_MEMORY_TAG);
           //to hide unused packet header ahead of pointer.   
           //(ULONG)Adapter->pRxBufVM[i] += (sizeof(RxPD)+sizeof(pkt.Len)+sizeof(pkt.Type));
           (ULONG)Adapter->pRxBufVM[i] += MRVDRV_ETH_RX_HIDDEN_HEADER_SIZE;

            if ( tStatus != NDIS_STATUS_SUCCESS )
            {
                bSuccess = FALSE;
                break;
            }
                      
            // buffer array 
            NdisAllocateBuffer(
                                &tStatus,
                                &Adapter->pRxBuffer[i],
                                Adapter->RxBufferPoolHandle,
                                Adapter->pRxBufVM[i],
                                (MRVDRV_ETH_RX_PACKET_BUFFER_SIZE-MRVDRV_ETH_RX_HIDDEN_HEADER_SIZE));

            if ( tStatus != NDIS_STATUS_SUCCESS )
            {
                bSuccess = FALSE;
                break;
            }

      // packet array   
            NdisAllocatePacket(
                               &tStatus, 
                               &Adapter->pRxPacket[i],
                               Adapter->RxPacketPoolHandle);

            if ( tStatus != NDIS_STATUS_SUCCESS )
            {
                bSuccess = FALSE;
                break;
            }

            // init OBB space
            pOOB = NDIS_OOB_DATA_FROM_PACKET(Adapter->pRxPacket[i]);
            NdisZeroMemory(pOOB, sizeof(NDIS_PACKET_OOB_DATA));
            NDIS_SET_PACKET_HEADER_SIZE(Adapter->pRxPacket[i], MRVDRV_ETH_HEADER_SIZE);

            // chain the packet and buffer 
            NdisChainBufferAtFront(Adapter->pRxPacket[i],
                                   Adapter->pRxBuffer[i]);

            // fill packet node 
            Adapter->RxPacketQueueNode[i].pPacket = Adapter->pRxPacket[i];
    
            pNode = (PACKET_QUEUE_NODE **)Adapter->pRxPacket[i]->MiniportReserved;
            *pNode = &Adapter->RxPacketQueueNode[i];
            
            // insert to free queue
            InsertQNodeAtTail(&Adapter->RxPacketFreeQueue, &Adapter->RxPacketQueueNode[i]);

        }   // end of for(;;)

    } while (0);

    if ( ! bSuccess )
    {
        // clean up all
        FreeRxQ(Adapter);
        return NDIS_STATUS_FAILURE;
    }

    Adapter->sNumOutstandingRxPacket = 0;

    return NDIS_STATUS_SUCCESS;
}
Exemplo n.º 25
0
NDIS_STATUS NICAllocAdapter(
    PMP_ADAPTER *pAdapter)
{
    PMP_ADAPTER Adapter = NULL;
    PNDIS_PACKET Packet;
    PNDIS_BUFFER Buffer;
    PUCHAR pTCBMem;
    PTCB  pTCB;
    NDIS_STATUS Status;

    LONG index;

    DEBUGP(MP_TRACE, ("--> NICAllocAdapter\n"));

    PAGED_CODE();

    *pAdapter = NULL;

    do
    {
        //
        // Allocate memory for adapter context
        //
        Status = NdisAllocateMemoryWithTag(
            &Adapter, 
            sizeof(MP_ADAPTER), 
            NIC_TAG);
        if(Status != NDIS_STATUS_SUCCESS)
        {
            DEBUGP(MP_ERROR, ("Failed to allocate memory for adapter context\n"));
            break;
        }
        //
        // Zero the memory block
        //
        NdisZeroMemory(Adapter, sizeof(MP_ADAPTER));
        NdisInitializeListHead(&Adapter->List);

        //
        // Initialize Send & Recv listheads and corresponding 
        // spinlocks.
        //
        //NdisInitializeListHead(&Adapter->RecvWaitList);
        //NdisInitializeListHead(&Adapter->SendWaitList);
        //NdisInitializeListHead(&Adapter->SendFreeList);
        NdisAllocateSpinLock(&Adapter->SendLock);                                                  

        //NdisInitializeListHead(&Adapter->RecvFreeList);
        NdisAllocateSpinLock(&Adapter->RecvLock);  


				//allocate a packet pool
				NdisAllocatePacketPool(
            &Status,
            &Adapter->LdnRecvPacketPoolHandle,
            1,
            PROTOCOL_RESERVED_SIZE_IN_PACKET);
        
        if(Status != NDIS_STATUS_SUCCESS)
        {
            DEBUGP(MP_ERROR, ("NdisAllocatePacketPool failed\n"));
            break;
        }
				
				//allocate a single packet in the pool
				NdisAllocatePacket(
                &Status,
                &Adapter->LdnRecvPacket,
                Adapter->LdnRecvPacketPoolHandle);
        if(Status != NDIS_STATUS_SUCCESS)
        {
                DEBUGP(MP_ERROR, ("NdisAllocatePacket failed\n"));
                break;
        }
				
				
				//allocate a buffer pool
				NdisAllocateBufferPool(
            &Status,
            &Adapter->LdnRecvBufferPoolHandle,
            1);
        if(Status != NDIS_STATUS_SUCCESS)
        {
            DEBUGP(MP_ERROR, ("NdisAllocateBufferPool for recv buffer failed\n"));
            break;
        }
				
				//allocate a single buffer in the buffer pool
				NdisAllocateBuffer(
                &Status,
                &Adapter->LdnRecvPacketBuffer,
                Adapter->LdnRecvBufferPoolHandle,
                (PVOID)&Adapter->LdnRecvPacketBufferData[0],
                NIC_BUFFER_SIZE);
        if(Status != NDIS_STATUS_SUCCESS)
        {
                DEBUGP(MP_ERROR, ("NdisAllocateBuffer failed\n"));
                break;
        }
				
				//chain the buffer to the packet
				NdisChainBufferAtBack(Adapter->LdnRecvPacket,
						Adapter->LdnRecvPacketBuffer);
				
	      NDIS_SET_PACKET_STATUS(Adapter->LdnRecvPacket, NDIS_STATUS_RESOURCES);
				NDIS_SET_PACKET_HEADER_SIZE(Adapter->LdnRecvPacket, ETH_HEADER_SIZE);
  


        /*//
        // Allocate lookside list for Receive Control blocks.
        //
        NdisInitializeNPagedLookasideList(
                    &Adapter->RecvLookaside,
                    NULL, // No Allocate function
                    NULL, // No Free function
                    0,    // Reserved for system use
                    sizeof(RCB),
                    NIC_TAG, 
                    0); // Reserved for system use
                    
        MP_SET_FLAG(Adapter, fMP_ADAPTER_RECV_LOOKASIDE); 
        
        //
        // Allocate packet pool for receive indications
        //
        NdisAllocatePacketPool(
            &Status,
            &Adapter->RecvPacketPoolHandle,
            NIC_MAX_BUSY_RECVS,
            PROTOCOL_RESERVED_SIZE_IN_PACKET);
        
        if(Status != NDIS_STATUS_SUCCESS)
        {
            DEBUGP(MP_ERROR, ("NdisAllocatePacketPool failed\n"));
            break;
        }
        //
        // Initialize receive packets
        //
        for(index=0; index < NIC_MAX_BUSY_RECVS; index++)
        {
            //
            // Allocate a packet descriptor for receive packets
            // from a preallocated pool.
            //
            NdisAllocatePacket(
                &Status,
                &Packet,
                Adapter->RecvPacketPoolHandle);
            if(Status != NDIS_STATUS_SUCCESS)
            {
                DEBUGP(MP_ERROR, ("NdisAllocatePacket failed\n"));
                break;
            }
            
            NDIS_SET_PACKET_HEADER_SIZE(Packet, ETH_HEADER_SIZE);

            //
            // Insert it into the list of free receive packets.
            //
            NdisInterlockedInsertTailList(
                &Adapter->RecvFreeList, 
                (PLIST_ENTRY)&Packet->MiniportReserved[0], 
                &Adapter->RecvLock);
        }
        
        //
        // Allocate a huge block of memory for all TCB's
        //
        Status = NdisAllocateMemoryWithTag(
            &pTCBMem, 
            sizeof(TCB) * NIC_MAX_BUSY_SENDS, 
            NIC_TAG);
        
        if(Status != NDIS_STATUS_SUCCESS)
        {
            DEBUGP(MP_ERROR, ("Failed to allocate memory for TCB's\n"));
            break;
        }
        NdisZeroMemory(pTCBMem, sizeof(TCB) * NIC_MAX_BUSY_SENDS);
        Adapter->TCBMem = pTCBMem;

        //
        // Allocate a buffer pool for send buffers.
        //

        NdisAllocateBufferPool(
            &Status,
            &Adapter->SendBufferPoolHandle,
            NIC_MAX_BUSY_SENDS);
        if(Status != NDIS_STATUS_SUCCESS)
        {
            DEBUGP(MP_ERROR, ("NdisAllocateBufferPool for send buffer failed\n"));
            break;
        }

        //
        // Divide the TCBMem blob into TCBs and create a buffer
        // descriptor for the Data portion of the TCBs.
        //
        for(index=0; index < NIC_MAX_BUSY_SENDS; index++)
        {
            pTCB = (PTCB) pTCBMem;
            //
            // Create a buffer descriptor for the Data portion of the TCBs.
            // Buffer descriptors are nothing but MDLs on NT systems.
            //
            NdisAllocateBuffer(
                &Status,
                &Buffer,
                Adapter->SendBufferPoolHandle,
                (PVOID)&pTCB->Data[0],
                NIC_BUFFER_SIZE);
            if(Status != NDIS_STATUS_SUCCESS)
            {
                DEBUGP(MP_ERROR, ("NdisAllocateBuffer failed\n"));
                break;
            }

            //
            // Initialize the TCB structure.
            // 
            pTCB->Buffer = Buffer;
            pTCB->pData = (PUCHAR) &pTCB->Data[0];       
            pTCB->Adapter = Adapter;

            NdisInterlockedInsertTailList(
                &Adapter->SendFreeList, 
                &pTCB->List, 
                &Adapter->SendLock);

            pTCBMem = pTCBMem + sizeof(TCB);
        }*/

    } while(FALSE);


    *pAdapter = Adapter;

    //
    // In the failure case, the caller of this routine will end up
    // calling NICFreeAdapter to free all the successfully allocated
    // resources.
    //
    DEBUGP(MP_TRACE, ("<-- NICAllocAdapter\n"));

    return(Status);

}
Exemplo n.º 26
0
NDIS_STATUS
	natpReceive(
		IN  NDIS_HANDLE	ProtocolBindingContext,
		IN  NDIS_HANDLE	MacReceiveContext,
		IN  PVOID		HeaderBuffer,
		IN  UINT		HeaderBufferSize,
		IN  PVOID		LookAheadBuffer,
		IN  UINT		LookAheadBufferSize,
		IN  UINT		PacketSize
		)
{
	PFILTER_ADAPTER	pAdapt;
	PNDIS_PACKET Packet;
	NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
	NDIS_STATUS PacketStatus;
	PNDIS_PACKET pNewPacket;
	ULONG nDataSize;
	FLT_PKT *pFltPkt;
	PNDIS_BUFFER pNewBuffer;

	pAdapt = (PFILTER_ADAPTER)ProtocolBindingContext;

	if ((!pAdapt->MiniportHandle) || (pAdapt->natmDeviceState > NdisDeviceStateD0)){
		return NDIS_STATUS_FAILURE;
	}

	nDataSize = HeaderBufferSize + PacketSize;
	if ( nDataSize > MAX_ETHER_SIZE ){
		return NDIS_STATUS_FAILURE;
	}

	Packet = NdisGetReceivedPacket(pAdapt->BindingHandle, MacReceiveContext);
	if (NULL == Packet)
		return NDIS_STATUS_NOT_ACCEPTED;

	pFltPkt = AllocateFltPacket();
	if(NULL == pFltPkt)
		return NDIS_STATUS_NOT_ACCEPTED;

	if(!natbParsePacket(Packet, pFltPkt)){

		if(g_LogPktDrop) PrintFtlPkt("DROP ", pFltPkt, 0, FALSE);
		FreeFltPkt(pFltPkt);
		return NDIS_STATUS_NOT_ACCEPTED;
	}

	//
	// Translate
	//
	TranslatePktIncoming(&pAdapt->ctrl, pFltPkt);

	//
	// Filter
	//
	if(!FilterPkt(&pAdapt->ctrl, pFltPkt, FALSE)){

		if(g_LogPktDrop) PrintFtlPkt("DROP ", pFltPkt, 0, FALSE);
		FreeFltPkt(pFltPkt);
		return NDIS_STATUS_NOT_ACCEPTED;
	}

	if(g_LogPktPass) PrintFtlPkt("PASS ", pFltPkt, 0, FALSE);

	if(NULL == pFltPkt->pBuf){

		FreeFltPkt(pFltPkt);
		pFltPkt = NULL;

		NdisDprAllocatePacket(
			&Status,
			&pNewPacket,
			pAdapt->RcvPP1
			);

		if (Status != NDIS_STATUS_SUCCESS)
		{
			return NDIS_STATUS_NOT_ACCEPTED;
		}

		*((PVOID*)&pNewPacket->MiniportReserved) = NULL;

		pNewPacket->Private.Head = Packet->Private.Head;
		pNewPacket->Private.Tail = Packet->Private.Tail;

	}else{

		NdisDprAllocatePacket(
			&Status,
			&pNewPacket,
			pAdapt->RcvPP2
			);

		if (Status != NDIS_STATUS_SUCCESS)
			return NDIS_STATUS_NOT_ACCEPTED;

		*((PVOID*)&pNewPacket->MiniportReserved) = pFltPkt;

		NdisAllocateBuffer(
			&Status,
			&pNewBuffer,
			pAdapt->RcvBP,
			pFltPkt->pBuf,
			pFltPkt->uLen
			);

		if ( Status != NDIS_STATUS_SUCCESS ){

			NdisReinitializePacket (pNewPacket);
			NdisFreePacket (pNewPacket);

			return NDIS_STATUS_NOT_ACCEPTED;
		}

		NdisChainBufferAtFront(pNewPacket, pNewBuffer );
	}

	NdisGetPacketFlags(pNewPacket) = NdisGetPacketFlags(Packet);

	NDIS_SET_PACKET_STATUS(pNewPacket, NDIS_STATUS_RESOURCES);

	NDIS_SET_ORIGINAL_PACKET(pNewPacket, NDIS_GET_ORIGINAL_PACKET(Packet));
	NDIS_SET_PACKET_HEADER_SIZE(pNewPacket, HeaderBufferSize);

	natpQueueReceivedPacket(pAdapt, pNewPacket, TRUE);

	natmReturnPacket(
		ProtocolBindingContext,
		pNewPacket
		);

	return Status;
}
Exemplo n.º 27
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"));

}
Exemplo n.º 28
0
//
//发送相关函数的实现、
//
NTSTATUS
SecLabSendPacket(
                 PADAPT			         pAdapt,
				 IN PDEVICE_OBJECT       DeviceObject,
				 IN PIRP                 pIrp
				 )
{
	PIO_STACK_LOCATION      pIrpSp;
    ULONG                   FunctionCode;
    ULONG                   DataLength;
    NTSTATUS                NtStatus=STATUS_INVALID_HANDLE;
    NDIS_STATUS             Status;
    
    PNDIS_PACKET                pNdisPacket;
    PNDIS_BUFFER                pNdisBuffer;
//  SECLAB_ETH_HEADER UNALIGNED *pEthHeader;

	PUCHAR      pData;
	ULONG        i;

#ifdef NDIS51
    PVOID                   CancelId;
#endif

    pIrpSp = IoGetCurrentIrpStackLocation(pIrp);

    pNdisPacket = NULL;
	pNdisBuffer = NULL;

    do
    {
        if (pAdapt == NULL)
        {
            DbgPrint("Write: FileObject not yet associated with a device\n");
            NtStatus = STATUS_INVALID_HANDLE;
            break;
        }

        //
        // 检查发送数据包的长度
        //

		DataLength=pIrpSp->Parameters.DeviceIoControl.InputBufferLength;
		
        if (DataLength > MAX_SEND_PACKETLEN )
        {
            DbgPrint("Write: Open data length larger than max frame size\n");

            NtStatus = STATUS_UNSUCCESSFUL;
            break;
        }

        //
        //  构造一个发送封包
        //

		if(pAdapt->SendPacketPoolHandle==NULL)
		{
			DbgPrint("The Packet Pool should not be NULL");
			DbgBreakPoint();
			break;
		}

	    do
		{
			 //其实怎么样分配内存是无关紧要的,忘记资源的释放也不是很严重的
			 //最多导致内存支出过多。关键是不能让程序引用不存在的内存,这样会
			 //造成崩溃,比如重复释放内存。崩溃的另一大可能是在Dispatch>=passive
			 //级别上调用非分页内存。
		     //pData=(PUCHAR)ExAllocatePool(NonPagedPool,DataLength);
			 NdisAllocateMemoryWithTag((PVOID *)(&pData), DataLength,'lceS');

		     if(pData==NULL)
			 {
			      DbgPrint("Can not allocate pool for send");
			      break;
			 }
		     //RtlCopyMemory(pData,pIrp->AssociatedIrp.SystemBuffer,DataLength);
             NdisMoveMemory(pData,pIrp->AssociatedIrp.SystemBuffer,DataLength);

             //
             //  将其转化为NDIS_BUFFER.
             //
             NdisAllocateBuffer(
                 &Status,
                 &pNdisBuffer,
                 SendBufferPool,
                 pData,
                 DataLength);
        
              if (Status != NDIS_STATUS_SUCCESS)
			  {
                   DbgPrint("failed to allocate Ndis Buffer");
                   break;
			  }		

              NdisAllocatePacket(&Status, &pNdisPacket, pAdapt->SendPacketPoolHandle);

              if (Status != NDIS_STATUS_SUCCESS)
			  {
                   DbgPrint("failed to alloc NDIS packet");
                   break;
			  }

              NDIS_SET_PACKET_STATUS(pNdisPacket, 0);
              pNdisBuffer->Next = NULL;
              NdisChainBufferAtFront(pNdisPacket, pNdisBuffer);
			  
		      pNdisPacket->Private.Head->Next=NULL;
		      pNdisPacket->Private.Tail=NULL;

              break;
		}
        while (FALSE);

        if (pNdisPacket == NULL || pNdisBuffer==NULL)
		{
            //
            //  Clean up
            //
            if (pNdisBuffer != NULL)
			{
                NdisFreeBuffer(pNdisBuffer);
			}

            if (pData != NULL)
			{
                NdisFreeMemory(pData, 0, 0);
			}
		}

        IoMarkIrpPending(pIrp);
		NtStatus = STATUS_PENDING;
        pIrp->IoStatus.Status = STATUS_PENDING;
        //
        //  初始化封包中的标志符。当标志符值为0时此包被释放
        //
        SECLAB_SEND_PKT_RSVD(pNdisPacket)->RefCount = 1;

#ifdef NDIS51

        //
        //  NDIS 5.1 supports cancelling sends. We set up a cancel ID on
        //  each send packet (which maps to a Write IRP), and save the
        //  packet pointer in the IRP. If the IRP gets cancelled, we use
        //  NdisCancelSendPackets() to cancel the packet.
        //

        CancelId = SECLAB_GET_NEXT_CANCEL_ID();
        NDIS_SET_PACKET_CANCEL_ID(pNdisPacket, CancelId);
        pIrp->Tail.Overlay.DriverContext[0] = (PVOID)pAdapt;
        pIrp->Tail.Overlay.DriverContext[1] = (PVOID)pNdisPacket;

		NdisInterlockedIncrement(&PendedSendCount);

		NdisAcquireSpinLock(&WriteIrpLock);
        InsertTailList(&PendedWritesList, &pIrp->Tail.Overlay.ListEntry);
        IoSetCancelRoutine(pIrp, SecLabCancelWrite);
		NdisReleaseSpinLock(&WriteIrpLock);

#endif // NDIS51
               
        //
        //  创建一个指针从packet回指向IRP
        //
        SECLAB_IRP_FROM_SEND_PKT(pNdisPacket) = pIrp;

		//
		//创建三个信号,以便在发送完成例程中指示此包
		//
		SECLAB_SIGNAL1_FROM_SEND_PKT(pNdisPacket)=SIGNAL1;
        SECLAB_SIGNAL2_FROM_SEND_PKT(pNdisPacket)=SIGNAL2;
		SECLAB_SIGNAL3_FROM_SEND_PKT(pNdisPacket)=SIGNAL3;

		//
		//发包
		//
        NdisSendPackets(pAdapt->BindingHandle, &pNdisPacket, 1); 
    }

    while (FALSE);

    if (NtStatus != STATUS_PENDING)
    {
        pIrp->IoStatus.Status = NtStatus;
        IoCompleteRequest(pIrp, IO_NO_INCREMENT);	
    }

    return (NtStatus);
}