VOID FreeNdisPacket ( PNDIS_PACKET Packet ) /* * FUNCTION: Frees an NDIS packet * ARGUMENTS: * Packet = Pointer to NDIS packet to be freed */ { PNDIS_BUFFER Buffer, NextBuffer; TI_DbgPrint(DEBUG_PBUFFER, ("Packet (0x%X)\n", Packet)); /* Free all the buffers in the packet first */ NdisQueryPacket(Packet, NULL, NULL, &Buffer, NULL); for (; Buffer != NULL; Buffer = NextBuffer) { PVOID Data; UINT Length; NdisGetNextBuffer(Buffer, &NextBuffer); NdisQueryBuffer(Buffer, &Data, &Length); TI_DbgPrint(DEBUG_PBUFFER, ("Freeing ndis buffer (0x%X)\n", Buffer)); NdisFreeBuffer(Buffer); TI_DbgPrint(DEBUG_PBUFFER, ("Freeing exal buffer (0x%X)\n", Data)); ExFreePoolWithTag(Data, PACKET_BUFFER_TAG); } /* Finally free the NDIS packet discriptor */ NdisFreePacket(Packet); }
VOID FreeNdisPacketX ( PNDIS_PACKET Packet, PCHAR File, UINT Line ) /* * FUNCTION: Frees an NDIS packet * ARGUMENTS: * Packet = Pointer to NDIS packet to be freed */ { PNDIS_BUFFER Buffer, NextBuffer; TI_DbgPrint(DEBUG_PBUFFER, ("Packet (0x%X)\n", Packet)); /* Free all the buffers in the packet first */ NdisQueryPacket(Packet, NULL, NULL, &Buffer, NULL); for (; Buffer != NULL; Buffer = NextBuffer) { PVOID Data; UINT Length; NdisGetNextBuffer(Buffer, &NextBuffer); XNdisQueryBuffer(Buffer, &Data, &Length); UntrackFL(File,Line,Buffer); NdisFreeBuffer(Buffer); exFreePool(Data); } /* Finally free the NDIS packet descriptor */ UntrackFL(File,Line,Packet); NdisFreePacket(Packet); }
/************************************************************ Function called by NDIS to indicate that the data transfer is finished ************************************************************/ VOID NDIS_API PacketSendComplete( IN NDIS_HANDLE ProtocolBindingContext, IN PNDIS_PACKET pPacket, IN NDIS_STATUS Status ) { PNDIS_BUFFER pNdisBuffer; PPACKET_RESERVED Reserved = (PPACKET_RESERVED) pPacket->ProtocolReserved; TRACE_ENTER( "SendComplete" ); NdisUnchainBufferAtFront( pPacket, &pNdisBuffer ); if ( pNdisBuffer ) NdisFreeBuffer( pNdisBuffer ); VWIN32_DIOCCompletionRoutine( Reserved->lpoOverlapped->O_Internal ); PacketPageUnlock( Reserved->lpBuffer, Reserved->cbBuffer ); PacketPageUnlock( Reserved->lpcbBytesReturned, sizeof(DWORD) ); PacketPageUnlock( Reserved->lpoOverlapped, sizeof(OVERLAPPED) ); NdisReinitializePacket(pPacket); NdisFreePacket(pPacket); TRACE_LEAVE( "SendComplete" ); return; }
/* ************************************************************************* * ReturnPacketHandler ************************************************************************* * * When NdisMIndicateReceivePacket returns asynchronously, * the protocol returns ownership of the packet to the miniport via this function. * */ VOID ReturnPacketHandler(NDIS_HANDLE MiniportAdapterContext, PNDIS_PACKET Packet) { IrDevice *thisDev = CONTEXT_TO_DEV(MiniportAdapterContext); UINT rcvBufIndex; DBGOUT(("ReturnPacketHandler(0x%x)", (UINT)MiniportAdapterContext)); /* * The rcv buffer index is cached in the MiniportReserved field of the packet. */ rcvBufIndex = *(UINT *)Packet->MiniportReserved; if (rcvBufIndex < NUM_RCV_BUFS){ if (thisDev->rcvBufs[rcvBufIndex].state == STATE_PENDING){ PNDIS_BUFFER ndisBuf; DBGPKT(("Reclaimed rcv packet 0x%x.", (UINT)Packet)); NdisUnchainBufferAtFront(Packet, &ndisBuf); if (ndisBuf){ NdisFreeBuffer(ndisBuf); } thisDev->rcvBufs[rcvBufIndex].state = STATE_FREE; } else { DBGERR(("Packet in ReturnPacketHandler was not PENDING.")); } } else { DBGERR(("Bad rcvBufIndex (from corrupted MiniportReserved) in ReturnPacketHandler.")); } }
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; }
VOID ArcFreeNdisPacket( IN PARC_PACKET Packet ) /*++ Routine description: This routine takes an arcnet packet and frees up the corresponding Ndis packet built for it. Arguments: Packet - The packet to free up. Return values: None --*/ { PNDIS_BUFFER NdisBuffer, NextNdisBuffer; NdisQueryPacket( &(Packet->TmpNdisPacket), NULL, NULL, &NdisBuffer, NULL ); while (NdisBuffer != NULL) { NdisGetNextBuffer( NdisBuffer, &NextNdisBuffer ); NdisFreeBuffer( NdisBuffer ); NdisBuffer = NextNdisBuffer; } NdisReinitializePacket(&(Packet->TmpNdisPacket)); }
/****************************************************************************** * * Name: FreeRxQ() * * Description: Free Rx buffer * * Arguments: PMRVDRV_ADAPTER Adapter * * Return Value: NDIS_STATUS_SUCCESS or NDIS_STATUS_FAILURE * * Notes: * *****************************************************************************/ NDIS_STATUS FreeRxQ( IN PMRVDRV_ADAPTER Adapter ) { ULONG i; DBGPRINT(DBG_BUF|DBG_RX|DBG_HELP,(L"Free Rx Q\r\n")); for ( i=0; i < MRVDRV_NUM_RX_PKT_IN_QUEUE; i++ ) { if ( Adapter->pRxBufVM[i] != NULL ) { (ULONG)Adapter->pRxBufVM[i] -= MRVDRV_ETH_RX_HIDDEN_HEADER_SIZE; NdisFreeMemory(Adapter->pRxBufVM[i], MRVDRV_ETH_RX_PACKET_BUFFER_SIZE, 0); Adapter->pRxBufVM[i] = NULL; } if ( Adapter->pRxBuffer[i] != NULL ) { NdisFreeBuffer(Adapter->pRxBuffer[i]); Adapter->pRxBuffer[i] = NULL; } if ( Adapter->pRxPacket[i] != NULL ) { NdisFreePacket(Adapter->pRxPacket[i]); Adapter->pRxPacket[i] = NULL; } } if ( Adapter->RxBufferPoolHandle != NULL ) { NdisFreeBufferPool(Adapter->RxBufferPoolHandle); Adapter->RxBufferPoolHandle = NULL; } if ( Adapter->RxPacketPoolHandle != NULL ) { NdisFreePacketPool(Adapter->RxPacketPoolHandle); Adapter->RxPacketPoolHandle = NULL; } return NDIS_STATUS_SUCCESS; }
VOID NDIS_API PacketTransferDataComplete(IN NDIS_HANDLE ProtocolBindingContext, IN PNDIS_PACKET pPacket, IN NDIS_STATUS Status, IN UINT BytesTransfered) { // upcall when no more data available POPEN_INSTANCE Open = (POPEN_INSTANCE)ProtocolBindingContext; PPACKET_RESERVED pReserved = (PPACKET_RESERVED)(pPacket->ProtocolReserved); OVERLAPPED * pOverlap = (OVERLAPPED *)(pReserved->lpoOverlapped); PNDIS_BUFFER pNdisBuffer; // free buffer descriptor NdisUnchainBufferAtFront(pPacket, &pNdisBuffer); if (pNdisBuffer) NdisFreeBuffer(pNdisBuffer); // set total bytes returned BytesTransfered += ETHERNET_HEADER_LENGTH; *pReserved->lpcbBytesReturned += BytesTransfered; pOverlap->O_InternalHigh = *(pReserved->lpcbBytesReturned); // The internal member of overlapped structure contains // a pointer to the event structure that will be signalled, // resuming the execution of the waitng GetOverlappedResult // call. VWIN32_DIOCCompletionRoutine(pOverlap->O_Internal); // Unlock buffers PacketPageUnlock(pReserved->lpBuffer, pReserved->cbBuffer); PacketPageUnlock(pReserved->lpcbBytesReturned, sizeof(DWORD)); PacketPageUnlock(pReserved->lpoOverlapped, sizeof(OVERLAPPED)); // recycle the packet NdisReinitializePacket(pPacket); // Put the packet on the free queue NdisFreePacket(pPacket); }
VOID MPReturnPacket( IN NDIS_HANDLE MiniportAdapterContext, IN PNDIS_PACKET Packet) { if (Packet) { PVOID data = NULL; PNDIS_BUFFER ndis_buffer = NULL; data = *(PVOID*)Packet->MiniportReserved; if (data) ExFreePoolWithTag(data, 'tkpi'); while(1) { NdisUnchainBufferAtBack(Packet, &ndis_buffer); if (ndis_buffer) NdisFreeBuffer(ndis_buffer); else break; } NdisFreePacket(Packet); } }
static void shared_free_pkt(ND_PKT* p) { #ifndef NDIS60 PNDIS_BUFFER b; NdisQueryPacket(p, NULL, NULL, &b, NULL); ASSERT(b); NdisFreeBuffer(b); NdisFreePacket(p); #else /* NDIS60 */ PNET_BUFFER nb; PMDL b; nb = NET_BUFFER_LIST_FIRST_NB(p); b = NET_BUFFER_FIRST_MDL(nb); ASSERT(b); NdisFreeMdl(b); NdisFreeNetBufferList(p); #endif /* NDIS60 */ }
void netgSendToMiniportComplete(IN NDIS_HANDLE ProtocolBindingContext, IN PNDIS_PACKET pNdisPacket, IN NDIS_STATUS Status) { PIRP pIrp; PIO_STACK_LOCATION pIrpSp; PADAPT pAdapt; POPEN_CONTEXT pOpenContext; PNDIS_BUFFER pNdisBuffer; PVOID VirtualAddr; UINT BufferLength; UINT TotalLength; DBGPRINT(("==> netgSendToMiniportComplete\n")); pAdapt = (PADAPT)ProtocolBindingContext; pOpenContext = pAdapt->pOpenContext; pIrp = (((PNPROT_SEND_PACKET_RSVD)&((pNdisPacket)->ProtocolReserved[0]))->pIrp); // Free buffer NdisGetFirstBufferFromPacket(pNdisPacket, &pNdisBuffer, &VirtualAddr, &BufferLength, &TotalLength); NdisFreeBuffer(pNdisBuffer); // Free packet if (NdisInterlockedDecrement((PLONG)&((PNPROT_SEND_PACKET_RSVD)&((pNdisPacket)->ProtocolReserved[0]))->RefCount) == 0) { \ NdisFreePacket(pNdisPacket); } CompleteTheIRP: // Complete the Write IRP with the right status. pIrpSp = IoGetCurrentIrpStackLocation(pIrp); if (Status == NDIS_STATUS_SUCCESS) { pIrp->IoStatus.Information = pIrpSp->Parameters.Write.Length; pIrp->IoStatus.Status = STATUS_SUCCESS; } else { pIrp->IoStatus.Information = 0; pIrp->IoStatus.Status = STATUS_UNSUCCESSFUL; } IoCompleteRequest(pIrp, IO_NO_INCREMENT); DBGPRINT(("<== netgSendToMiniportComplete\n")); }
// Release the packet buffer void NeoFreePacketBuffer(PACKET_BUFFER *p) { // Validate arguments if (p == NULL) { return; } // Detach the buffer from the packet NdisUnchainBufferAtFront(p->NdisPacket, &p->NdisBuffer); // Release the packet NdisFreePacket(p->NdisPacket); // Release the packet pool NdisFreePacketPool(p->PacketPool); // Release the buffer NdisFreeBuffer(p->NdisBuffer); // Release the memory NeoFree(p->Buf); // Release the buffer pool NdisFreeBufferPool(p->BufferPool); // Release the memory NeoFree(p); }
//*********************************************************************************** // Name: MpFreeSGList // // Description: // frees sgdma list // // Return value: // None // // Parameters: // // NOTE: None // ********************************************************************************** VOID MpFreeSGList( IN PKIP_NDIS_ADAPTER pAdapter, IN PNDIS_PACKET Packet ) { PSCATTER_GATHER_LIST pSGL; PDMA_ADAPTER SystemAdapterObject = NDIS_GetSystemAdapterObject( pAdapter->NdisMiniportHandle ); pSGL = NDIS_PER_PACKET_INFO_FROM_PACKET(Packet, ScatterGatherListPacketInfo); if ( SystemAdapterObject ){ SystemAdapterObject->DmaOperations->PutScatterGatherList( SystemAdapterObject, pSGL, TRUE ); } if ( (Packet->Private.Flags & NDIS_FLAGS_USES_SG_BUFFER_LIST ) == NDIS_FLAGS_USES_SG_BUFFER_LIST ){ PNPAGED_LOOKASIDE_LIST SGListLookasideList = NDIS_GetSGListLookasideList( pAdapter->NdisMiniportHandle ); Packet->Private.Flags &= ~NDIS_FLAGS_USES_SG_BUFFER_LIST; pSGL = NDIS_PER_PACKET_INFO_FROM_PACKET(Packet, NdisReserved); if ( pSGL && SGListLookasideList ){ ExFreeToNPagedLookasideList( SGListLookasideList, pSGL ); } NDIS_PER_PACKET_INFO_FROM_PACKET(Packet, NdisReserved) = NULL; } else if ( ( Packet->Private.Flags & NDIS_FLAGS_DOUBLE_BUFFERED ) == NDIS_FLAGS_DOUBLE_BUFFERED ){ PNDIS_BUFFER NdisBuffer; PVOID NdisBufferVA; Packet->Private.Flags &= ~NDIS_FLAGS_DOUBLE_BUFFERED; NdisBuffer = NDIS_PER_PACKET_INFO_FROM_PACKET(Packet, NdisReserved); if ( NdisBuffer ){ NdisBufferVA = MmGetMdlVirtualAddress(NdisBuffer); NdisFreeBuffer( NdisBuffer ); if ( NdisBufferVA ){ ExFreePoolWithTag(NdisBufferVA,MODULE_TAG); } } } }
/*----------------------------------------------------------------------------*/ VOID kalPacketFree(IN P_GLUE_INFO_T prGlueInfo, IN PVOID pvPacket) { PNDIS_PACKET prNdisPacket; PNDIS_BUFFER prNdisBuf; ASSERT(prGlueInfo); ASSERT(pvPacket); prNdisPacket = (PNDIS_PACKET) pvPacket; do { NdisUnchainBufferAtBack(prNdisPacket, &prNdisBuf); if (prNdisBuf) { NdisFreeBuffer(prNdisBuf); } else { break; } } while (TRUE); /* Reinitialize the packet descriptor for reuse. */ NdisReinitializePacket(prNdisPacket); #if CETK_NDIS_PERFORMANCE_WORKAROUND { PUINT_32 ptr; ptr = (PUINT_32) prNdisPacket->ProtocolReserved; *ptr = 0; } #endif putPoolPacket(prGlueInfo, prNdisPacket, NULL); } /* kalPacketFree */
VOID NDIS_API PacketSendComplete(IN NDIS_HANDLE ProtocolBindingContext, IN PNDIS_PACKET pPacket, IN NDIS_STATUS Status) { // upcall on completion of send PNDIS_BUFFER pNdisBuffer; PPACKET_RESERVED Reserved = (PPACKET_RESERVED)pPacket->ProtocolReserved; // free buffer descriptor NdisUnchainBufferAtFront(pPacket, &pNdisBuffer); if (pNdisBuffer) NdisFreeBuffer(pNdisBuffer); // return status Reserved->lpoOverlapped->O_InternalHigh = Status; // The internal member of overlapped structure contains // a pointer to the event structure that will be signalled, // resuming the execution of the waiting GetOverlappedResult // call. VWIN32_DIOCCompletionRoutine(Reserved->lpoOverlapped->O_Internal); // Unlock buffers PacketPageUnlock(Reserved->lpBuffer, Reserved->cbBuffer); PacketPageUnlock(Reserved->lpcbBytesReturned, sizeof(DWORD)); PacketPageUnlock(Reserved->lpoOverlapped, sizeof(OVERLAPPED)); // recycle the packet NdisReinitializePacket(pPacket); // Put the packet back on the free list NdisFreePacket(pPacket); }
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 }
VOID NdisProtSendComplete( IN NDIS_HANDLE ProtocolBindingContext, IN PNDIS_PACKET pNdisPacket, IN NDIS_STATUS Status ) /*++ Routine Description: NDIS entry point called to signify completion of a packet send. We pick up and complete the Write IRP corresponding to this packet. NDIS 5.1: Arguments: ProtocolBindingContext - pointer to open context pNdisPacket - packet that completed send Status - status of send Return Value: None --*/ { PIRP pIrp; PIO_STACK_LOCATION pIrpSp; PNDISPROT_OPEN_CONTEXT pOpenContext; pOpenContext = (PNDISPROT_OPEN_CONTEXT)ProtocolBindingContext; NPROT_STRUCT_ASSERT(pOpenContext, oc); pIrp = NPROT_IRP_FROM_SEND_PKT(pNdisPacket); if (pOpenContext->bRunningOnWin9x) { // // We would have attached our own NDIS_BUFFER. Take it out // and free it. // #ifndef NDIS51 PNDIS_BUFFER pNdisBuffer; PVOID VirtualAddr; UINT BufferLength; UINT TotalLength; #endif #ifdef NDIS51 NPROT_ASSERT(FALSE); // NDIS 5.1 not on Win9X! #else NdisGetFirstBufferFromPacket( pNdisPacket, &pNdisBuffer, &VirtualAddr, &BufferLength, &TotalLength); NPROT_ASSERT(pNdisBuffer != NULL); NdisFreeBuffer(pNdisBuffer); #endif } #ifdef NDIS51 IoSetCancelRoutine(pIrp, NULL); NPROT_ACQUIRE_LOCK(&pOpenContext->Lock); NPROT_REMOVE_ENTRY_LIST(&pIrp->Tail.Overlay.ListEntry); NPROT_RELEASE_LOCK(&pOpenContext->Lock); #endif // // We are done with the NDIS_PACKET: // NPROT_DEREF_SEND_PKT(pNdisPacket); // // Complete the Write IRP with the right status. // pIrpSp = IoGetCurrentIrpStackLocation(pIrp); if (Status == NDIS_STATUS_SUCCESS) { pIrp->IoStatus.Information = pIrpSp->Parameters.Write.Length; pIrp->IoStatus.Status = STATUS_SUCCESS; } else { pIrp->IoStatus.Information = 0; pIrp->IoStatus.Status = STATUS_UNSUCCESSFUL; } DEBUGP(DL_INFO, ("SendComplete: packet %p/IRP %p/Length %d " "completed with status %x\n", pNdisPacket, pIrp, pIrp->IoStatus.Information, pIrp->IoStatus.Status)); IoCompleteRequest(pIrp, IO_NO_INCREMENT); NdisInterlockedDecrement((PLONG)&pOpenContext->PendedSendCount); NPROT_DEREF_OPEN(pOpenContext); // send complete - dequeued send IRP }
/*+ * * FreeAdapterMemory * * Routine Description: * * Frees the memory previously allocated by * AllocateAdapterMemory * * Arguments: * * Adapter - The adapter to deallocate memory for. * * Return Value: * * None. * -*/ extern VOID FreeAdapterMemory( IN PDC21X4_ADAPTER Adapter ) { PDC21X4_RECEIVE_DESCRIPTOR ReceiveDescriptor; PRCV_HEADER RcvHeader; PNDIS_PACKET Packet; UINT i; if ((PVOID)Adapter->DescriptorRing.AllocVa == (PVOID)NULL) { // AllocateAdapterMemory failed on the first allocation: // no ressources were allocated return; } for (i = 0, ReceiveDescriptor = (PDC21X4_RECEIVE_DESCRIPTOR)Adapter->ReceiveDescriptorRingVa; i < Adapter->ReceiveRingSize; i++, (PCHAR)ReceiveDescriptor += Adapter->DescriptorSize ) { if (ReceiveDescriptor->RcvHeader) { RcvHeader = ReceiveDescriptor->RcvHeader; if (RcvHeader->FlushBuffer) { NdisFreeBuffer(RcvHeader->FlushBuffer); } if (RcvHeader->Packet) { NdisFreePacket(RcvHeader->Packet); } if (!Adapter->RcvBufferSpace.Va) { NdisMFreeSharedMemory( Adapter->MiniportAdapterHandle, RcvHeader->AllocSize, TRUE, (PVOID)RcvHeader->AllocVa, RcvHeader->AllocPa ); } } } while (Adapter->FreeRcvList != NULL) { RcvHeader = Adapter->FreeRcvList; Adapter->FreeRcvList = RcvHeader->Next; if (RcvHeader->FlushBuffer) { NdisFreeBuffer(RcvHeader->FlushBuffer); } if ( !Adapter->RcvBufferSpace.Va && RcvHeader->AllocVa) { NdisMFreeSharedMemory( Adapter->MiniportAdapterHandle, RcvHeader->AllocSize, TRUE, (PVOID)RcvHeader->AllocVa, RcvHeader->AllocPa ); } } while (Adapter->FreePacketList != NULL) { Packet = Adapter->FreePacketList; Adapter->FreePacketList = RCV_RESERVED(Packet)->Next; if (NULL != Packet) { NdisFreePacket(Packet); } } if (Adapter->RcvBufferSpace.Va) { NdisMFreeSharedMemory( Adapter->MiniportAdapterHandle, Adapter->RcvBufferSpace.AllocSize, TRUE, (PVOID)Adapter->RcvBufferSpace.AllocVa, Adapter->RcvBufferSpace.AllocPa ); } if (Adapter->ReceivePacketPool) { NdisFreePacketPool((PVOID)Adapter->ReceivePacketPool); } for (i = 0; i < DC21X4_NUMBER_OF_MAX_TRANSMIT_BUFFERS;i ++ ) { if (Adapter->MaxTransmitBuffer[i].AllocVa) { NdisMFreeSharedMemory( Adapter->MiniportAdapterHandle, Adapter->MaxTransmitBuffer[i].AllocSize, TRUE, (PVOID)Adapter->MaxTransmitBuffer[i].AllocVa, Adapter->MaxTransmitBuffer[i].AllocPa ); } if (Adapter->MaxTransmitBuffer[i].FlushBuffer) { NdisFreeBuffer(Adapter->MaxTransmitBuffer[i].FlushBuffer); } } if (Adapter->MinTransmitBuffer[0].AllocVa && !Adapter->DontUseMinTransmitBuffer) { NdisMFreeSharedMemory( Adapter->MiniportAdapterHandle, Adapter->MinTransmitBuffer[0].AllocSize, TRUE, (PVOID)Adapter->MinTransmitBuffer[0].AllocVa, Adapter->MinTransmitBuffer[0].AllocPa ); } for (i = 0; i < DC21X4_NUMBER_OF_MIN_TRANSMIT_BUFFERS;i ++ ) { if (Adapter->MinTransmitBuffer[i].FlushBuffer) { NdisFreeBuffer(Adapter->MinTransmitBuffer[i].FlushBuffer); } } if (Adapter->FlushBufferPoolHandle) { NdisFreeBufferPool(Adapter->FlushBufferPoolHandle); } if (Adapter->DescriptorRing.AllocVa) { NdisMFreeSharedMemory( Adapter->MiniportAdapterHandle, Adapter->DescriptorRing.AllocSize, FALSE, (PVOID)Adapter->DescriptorRing.AllocVa, Adapter->DescriptorRing.AllocPa ); } }
VOID PacketFree2 ( IN PNDIS_PACKET Packet ) { PLPX_RESERVED reserved = RESERVED(Packet); PUCHAR packetData; PNDIS_BUFFER pNdisBuffer; UINT uiLength; LONG clone; LONG BufferSeq; BOOLEAN allocMiniport = FALSE; PLPX_RESERVED externalReserved; DebugPrint( 3, ("PacketFree reserved->type = %d\n", reserved->Type) ); ASSERT( Packet->Private.NdisPacketFlags & fPACKET_ALLOCATED_BY_NDIS ); switch (reserved->Type) { case LPX_PACKET_TYPE_SEND: clone = InterlockedDecrement( &reserved->Cloned ); if(clone >= 0) { return; } pNdisBuffer = NULL; BufferSeq = 0; NdisUnchainBufferAtFront( Packet, &pNdisBuffer ); while (pNdisBuffer) { // // Assuming the first data buffer comes from user application // the others are created in LPX for padding, etc. // Free the memory of the others. // if (BufferSeq == 0) { #if DBG NdisQueryBufferSafe( pNdisBuffer, &packetData, &uiLength, HighPagePriority ); ASSERT( packetData == (PCHAR)&RESERVED(Packet)->EthernetHeader ); #endif } else if (BufferSeq == 1) { // UserBuffer } else if (BufferSeq == 2) { // Padding NdisQueryBufferSafe( pNdisBuffer, &packetData, &uiLength, HighPagePriority ); LpxFreeMemoryWithLpxTag( packetData ); } else { ASSERT( FALSE ); } NdisFreeBuffer( pNdisBuffer ); pNdisBuffer = NULL; NdisUnchainBufferAtFront( Packet, &pNdisBuffer ); BufferSeq ++; } if (reserved->IrpSp != NULL) { PIRP _Irp = IRP_SEND_IRP( reserved->IrpSp ); ASSERT( reserved->NdisStatus == NDIS_STATUS_SUCCESS || reserved->NdisStatus == NDIS_STATUS_NOT_ACCEPTED || !NT_SUCCESS(reserved->NdisStatus) ); if (!NT_SUCCESS(reserved->NdisStatus)) { _Irp->IoStatus.Status = reserved->NdisStatus; } //INC_IRP_RETRANSMITS( _Irp, reserved->Retransmits ); LpxDereferenceSendIrp( "Destroy packet", reserved->IrpSp, RREF_PACKET ); } else { DebugPrint( 3, ("[LPX] PacketFree: No IrpSp\n") ) ; } break; case LPX_PACKET_TYPE_RECEIVE: // // If the packet allocated by NIC miniport, break here. // if(RESERVED(Packet)->RecvFlags & LPX_RESERVED_RECVFLAG_ALLOC_MINIPORT) { allocMiniport = TRUE; break; } pNdisBuffer = NULL; NdisUnchainBufferAtFront( Packet, &pNdisBuffer ); #if __LPX_STATISTICS__ { LARGE_INTEGER systemTime; KeQuerySystemTime( &systemTime ); RESERVED(Packet)->DeviceContext->NumberOfRecvPackets ++; RESERVED(Packet)->DeviceContext->FreeTimeOfRecvPackets.QuadPart += systemTime.QuadPart - RESERVED(Packet)->RecvTime2.QuadPart; RESERVED(Packet)->DeviceContext->BytesOfRecvPackets.QuadPart += sizeof(LPX_HEADER) + RESERVED(Packet)->PacketRawDataLength; if (RESERVED(Packet)->PacketRawDataLength) { RESERVED(Packet)->DeviceContext->NumberOfLargeRecvPackets ++; RESERVED(Packet)->DeviceContext->FreeTimeOfLargeRecvPackets.QuadPart += systemTime.QuadPart - RESERVED(Packet)->RecvTime2.QuadPart; RESERVED(Packet)->DeviceContext->BytesOfLargeRecvPackets.QuadPart += sizeof(LPX_HEADER) + RESERVED(Packet)->PacketRawDataLength; } else { RESERVED(Packet)->DeviceContext->NumberOfSmallRecvPackets ++; RESERVED(Packet)->DeviceContext->FreeTimeOfSmallRecvPackets.QuadPart += systemTime.QuadPart - RESERVED(Packet)->RecvTime2.QuadPart; RESERVED(Packet)->DeviceContext->BytesOfSmallRecvPackets.QuadPart += sizeof(LPX_HEADER); } } #endif if (pNdisBuffer) { NdisQueryBufferSafe( pNdisBuffer, &packetData, &uiLength, HighPagePriority ); LpxFreeMemoryWithLpxTag( packetData ); NdisFreeBuffer( pNdisBuffer ); } break; default: ASSERT(FALSE); return; } // // Free external protocol reserved context. // externalReserved = ((PLPX_RESERVED)(Packet->ProtocolReserved))->ExternalReserved; if(externalReserved) { NdisFreeMemory(externalReserved, sizeof(LPX_RESERVED), 0); } ASSERT( Packet->Private.NdisPacketFlags & fPACKET_ALLOCATED_BY_NDIS ); if(allocMiniport) { // // Return the packet allocated by NIC miniport // NdisReturnPackets(&Packet, 1); } else { NdisFreePacket( Packet ); InterlockedDecrement( &NumberOfAllockPackets ); DebugPrint( 3, ("Packet REALLY Freed NumberOfAllockPackets = %d\n", NumberOfAllockPackets) ); } }
NTSTATUS RcvPacketAlloc ( IN PDEVICE_CONTEXT DeviceContext, IN ULONG PacketDataLength, OUT PNDIS_PACKET *Packet ) { NTSTATUS status; PUCHAR packetData = NULL; PNDIS_BUFFER packetDataBuffer = NULL; PNDIS_PACKET packet = NULL; DebugPrint( 3, ("RcvPacketAlloc, PacketLength = %d, NumberOfAllockPackets = %d\n", PacketDataLength, NumberOfAllockPackets) ); ASSERT( DeviceContext ); ASSERT( DeviceContext->LpxPacketPool != NULL ); ASSERT( PacketDataLength <= DeviceContext->MaxUserData ); do { NdisAllocatePacket( &status, &packet, DeviceContext->LpxPacketPool ); if (status != NDIS_STATUS_SUCCESS) { ASSERT( status == NDIS_STATUS_RESOURCES ); ASSERT( FALSE ); return status; } RtlZeroMemory( RESERVED(packet), sizeof(LPX_RESERVED) ); ASSERT( packet->Private.NdisPacketFlags & fPACKET_ALLOCATED_BY_NDIS ); if (PacketDataLength) { status = LpxAllocateMemoryWithLpxTag( &packetData, PacketDataLength ); if (status != NDIS_STATUS_SUCCESS) { ASSERT( status == NDIS_STATUS_FAILURE ); ASSERT( FALSE ); break; } NdisAllocateBuffer( &status, &packetDataBuffer, DeviceContext->LpxBufferPool, packetData, PacketDataLength ); if (!NT_SUCCESS(status)) { ASSERT( status == NDIS_STATUS_FAILURE ); ASSERT( FALSE ); break; } NdisChainBufferAtFront( packet, packetDataBuffer ); } } while(0); if (status == STATUS_SUCCESS) { RESERVED(packet)->Cloned = 0; RESERVED(packet)->Type = LPX_PACKET_TYPE_RECEIVE; RESERVED(packet)->Packet = packet; InterlockedIncrement( &NumberOfAllockPackets ); *Packet = packet; #if __LPX_STATISTICS__ KeQuerySystemTime( &RESERVED(packet)->RecvTime2 ); RESERVED(packet)->DeviceContext = DeviceContext; #endif } else { if (packetDataBuffer) NdisFreeBuffer( packetDataBuffer ); if (packetData) LpxFreeMemoryWithLpxTag( packetData ); if (packet) NdisFreePacket( packet ); *Packet = NULL; DebugPrint( 1, ("[LPX]RcvPacketAlloc: Can't Allocate Buffer For CopyData!!!\n") ); } return status; }
/*----------------------------------------------------------------------------*/ WLAN_STATUS kalRxIndicatePkts(IN P_GLUE_INFO_T prGlueInfo, IN PVOID apvPkts[], IN UINT_32 ucPktNum) { NDIS_STATUS arStatus[CFG_RX_MAX_PKT_NUM]; UINT_32 u4Idx; for (u4Idx = 0; u4Idx < ucPktNum; u4Idx++) { UINT_32 i, pivot; PVOID pvTmp; if (NDIS_GET_PACKET_STATUS((PNDIS_PACKET) apvPkts[u4Idx]) == NDIS_STATUS_RESOURCES) { pivot = u4Idx; for (i = u4Idx + 1; i < ucPktNum; i++) { if (NDIS_GET_PACKET_STATUS((PNDIS_PACKET) apvPkts[i]) != NDIS_STATUS_RESOURCES) { pvTmp = apvPkts[pivot]; apvPkts[pivot] = apvPkts[i]; apvPkts[i] = pvTmp; pivot++; } } break; } } for (u4Idx = 0; u4Idx < ucPktNum; u4Idx++) { arStatus[u4Idx] = NDIS_GET_PACKET_STATUS((PNDIS_PACKET) apvPkts[u4Idx]); if (arStatus[u4Idx] == NDIS_STATUS_SUCCESS) { /* 4 Increase the Pending Count before calling NdisMIndicateReceivePacket(). */ InterlockedIncrement(&prGlueInfo->i4RxPendingFrameNum); } } NdisMIndicateReceivePacket(prGlueInfo->rMiniportAdapterHandle, (PPNDIS_PACKET) apvPkts, (UINT) ucPktNum); for (u4Idx = 0; u4Idx < ucPktNum; u4Idx++) { /* 4 <1> Packets be retained. */ if (arStatus[u4Idx] != NDIS_STATUS_SUCCESS) { PNDIS_PACKET prNdisPacket = (PNDIS_PACKET) apvPkts[u4Idx]; PNDIS_BUFFER prNdisBuf = (PNDIS_BUFFER) NULL; ASSERT(prNdisPacket); NdisUnchainBufferAtBack(prNdisPacket, &prNdisBuf); if (prNdisBuf) { NdisFreeBuffer(prNdisBuf); } #if DBG else { ASSERT(0); } #endif /* DBG */ /* Reinitialize the packet descriptor for reuse. */ NdisReinitializePacket(prNdisPacket); #if CETK_NDIS_PERFORMANCE_WORKAROUND { PUINT_32 pu4Dummy; pu4Dummy = (PUINT_32) prNdisPacket->ProtocolReserved; *pu4Dummy = 0; } #endif /* CETK_NDIS_PERFORMANCE_WORKAROUND */ } } return WLAN_STATUS_SUCCESS; } /* kalIndicatePackets */
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; }
VOID NdisuioTransferDataComplete( IN NDIS_HANDLE ProtocolBindingContext, IN PNDIS_PACKET pNdisPacket, IN NDIS_STATUS TransferStatus, IN UINT BytesTransferred ) /*++ Routine Description: NDIS entry point called to signal completion of a call to NdisTransferData that had pended. Arguments: ProtocolBindingContext - pointer to open context pNdisPacket - our receive packet into which data is transferred TransferStatus - status of the transfer BytesTransferred - bytes copied into the packet. Return Value: None --*/ { PNDISUIO_OPEN_CONTEXT pOpenContext; PNDIS_BUFFER pOriginalBuffer, pPartialBuffer; PIRP pIrp; PPACKET_GROUP pGroup; //ULONG pDst; pOpenContext = (PNDISUIO_OPEN_CONTEXT)ProtocolBindingContext; NUIO_STRUCT_ASSERT(pOpenContext, oc); pIrp = NUIO_IRP_FROM_RCV_PKT(pNdisPacket); if (pIrp) { PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(pIrp); pOriginalBuffer = NUIO_RCV_PKT_TO_ORIGINAL_BUFFER(pNdisPacket); // // Free the partial MDL that we allocated // if (pOriginalBuffer) IoFreeMdl(pOriginalBuffer); // // Put the packet on the free queue // NdisFreePacket(pNdisPacket); #ifndef WIN9X pGroup = MmGetSystemAddressForMdlSafe(pIrp->MdlAddress, NormalPagePriority); //NUIO_ASSERT(pDst != NULL); // since it was already mapped #else pGroup = MmGetSystemAddressForMdl(pIrp->MdlAddress); // Win9x #endif pGroup->Length = BytesTransferred + sizeof(NDISUIO_ETH_HEADER); if (TransferStatus == NDIS_STATUS_SUCCESS) { pIrp->IoStatus.Status = STATUS_SUCCESS; pIrp->IoStatus.Information = pGroup->Length + sizeof(PACKET_GROUP); } else { pIrp->IoStatus.Status = STATUS_UNSUCCESSFUL; pIrp->IoStatus.Information = 0; } DEBUGP(DL_LOUD, ("TransferComp: Pkt %p, OrigBuf %p, BytesTransferred %d\n", pNdisPacket, pOriginalBuffer, BytesTransferred)); IoCompleteRequest(pIrp, IO_NO_INCREMENT); } else { // // Check if an NDIS_BUFFER was created to map part of the receive buffer; // if so, free it and link back the original NDIS_BUFFER that maps // the full receive buffer to the packet. // pOriginalBuffer = NUIO_RCV_PKT_TO_ORIGINAL_BUFFER(pNdisPacket); if (pOriginalBuffer != NULL) { // // We had stashed off the NDIS_BUFFER for the full receive // buffer in the packet reserved area. Unlink the partial // buffer and link in the full buffer. // NdisUnchainBufferAtFront(pNdisPacket, &pPartialBuffer); NdisChainBufferAtBack(pNdisPacket, pOriginalBuffer); DEBUGP(DL_LOUD, ("TransferComp: Pkt %p, OrigBuf %p, PartialBuf %p\n", pNdisPacket, pOriginalBuffer, pPartialBuffer)); // // Free up the partial buffer. // NdisFreeBuffer(pPartialBuffer); } } if (TransferStatus == NDIS_STATUS_SUCCESS) { // // Queue this up for receive processing, and // try to complete some read IRPs. // ndisuioQueueReceivePacket(pOpenContext, pNdisPacket); } else { ndisuioFreeReceivePacket(pOpenContext, pNdisPacket); NdisInterlockedAddLargeStatistic((PLARGE_INTEGER)&pOpenContext->DroppedPackets, 1); } }
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; }
/* ************************************************************************* * 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")); }
VOID PacketFree( IN PNDIS_PACKET Packet ) { PLPX_RESERVED reserved = RESERVED(Packet); PUCHAR packetData; PNDIS_BUFFER pNdisBuffer; UINT uiLength; LONG clone ; DebugPrint(3, ("PacketFree reserved->type = %d\n", reserved->Type)); switch(reserved->Type) { case SEND_TYPE: clone = InterlockedDecrement(&reserved->Cloned); if(clone >= 0) { return; } pNdisBuffer = NULL; NdisUnchainBufferAtFront(Packet, &pNdisBuffer); if(pNdisBuffer) { NdisQueryBufferSafe( pNdisBuffer, &packetData, &uiLength, HighPagePriority ); NdisFreeMemory(packetData); NdisFreeBuffer(pNdisBuffer); } pNdisBuffer = NULL; NdisUnchainBufferAtFront(Packet, &pNdisBuffer); while(pNdisBuffer) { NdisFreeBuffer(pNdisBuffer); pNdisBuffer = NULL; NdisUnchainBufferAtFront(Packet, &pNdisBuffer); } if(reserved->IrpSp != NULL) { LpxDereferenceSendIrp(reserved->IrpSp); } else { DebugPrint(2, ("[LPX] PacketFree: No IrpSp\n")) ; } break; case RECEIVE_TYPE: if(reserved->LpxSmpHeader) //ExFreePool(reserved->LpxSmpHeader); NdisFreeMemory(reserved->LpxSmpHeader); pNdisBuffer = NULL; NdisUnchainBufferAtFront(Packet, &pNdisBuffer); if(pNdisBuffer) { NdisQueryBufferSafe( pNdisBuffer, &packetData, &uiLength, HighPagePriority ); NdisFreeMemory(packetData); NdisFreeBuffer(pNdisBuffer); } reserved->PacketDataOffset = 0; break; } NdisFreePacket(Packet); InterlockedDecrement(&NumberOfPackets); DebugPrint(2, ("Packet REALLY Freed Numberofpackets = %d\n", NumberOfPackets)); }
//*********************************************************************************** // Name: MpAllocSGList // // Description: // sends packet via DMA // // Return value: // None // // Parameters: // // NOTE: None // ********************************************************************************** NDIS_STATUS MpAllocSGList( IN PKIP_NDIS_ADAPTER pAdapter, IN PNDIS_PACKET Packet ) { NDIS_STATUS nStatus = NDIS_STATUS_FAILURE; PNDIS_BUFFER Buffer; PVOID pBufferVa; ULONG PacketLength; PDMA_ADAPTER SystemAdapterObject; PDEVICE_OBJECT DeviceObject; PNPAGED_LOOKASIDE_LIST SGListLookasideList = NULL; ULONG ScatterGatherListSize = 0; PVOID pSGList = NULL; KIRQL OldIrql; PVOID SendBuffer = NULL; PNDIS_BUFFER SendNdisBuffer; ULONG nBytesRead = 0; BOOLEAN fbResult; BOOLEAN fbDMAV2; do { SystemAdapterObject = NDIS_GetSystemAdapterObject( pAdapter->NdisMiniportHandle ); if ( SystemAdapterObject == NULL ){ DBGLOG(( LError, "SystemAdapterObject is NULL\n" )); nStatus = NDIS_STATUS_RESOURCES; break; } fbDMAV2 = (SystemAdapterObject->DmaOperations->Size >= sizeof(DMA_OPERATIONS_V2) ); DeviceObject = NDIS_GetMiniportDeviceObject( pAdapter->NdisMiniportHandle ); if ( DeviceObject == NULL ){ DBGLOG(( LError, "DeviceObject is NULL\n" )); nStatus = NDIS_STATUS_RESOURCES; break; } if ( fbDMAV2 ){ SGListLookasideList = NDIS_GetSGListLookasideList( pAdapter->NdisMiniportHandle ); if ( SGListLookasideList == NULL ){ DBGLOG(( LError, "SGListLookasideList is NULL\n" )); nStatus = NDIS_STATUS_RESOURCES; break; } ScatterGatherListSize = NDIS_GetScatterGatherListSize( pAdapter->NdisMiniportHandle ); if ( ScatterGatherListSize == 0 ){ DBGLOG(( LError, "SGListLookasideList is NULL\n" )); nStatus = NDIS_STATUS_RESOURCES; break; } } NdisQueryPacket(Packet, NULL, NULL, &Buffer, &PacketLength); if ( Buffer == NULL ){ DBGLOG(( LError, "Buffer is NULL\n" )); nStatus = NDIS_STATUS_FAILURE; break; } // try to use build sg list interface if ( fbDMAV2 ){ // allocate SG list pSGList = ExAllocateFromNPagedLookasideList( SGListLookasideList ); if ( pSGList != NULL ){ Packet->Private.Flags |= NDIS_FLAGS_USES_SG_BUFFER_LIST; // sg list NDIS_PER_PACKET_INFO_FROM_PACKET(Packet, NdisReserved) = pSGList; // raise irql to dispatch KeRaiseIrql(DISPATCH_LEVEL,&OldIrql); nStatus = SystemAdapterObject->DmaOperations->BuildScatterGatherList( SystemAdapterObject, DeviceObject, Buffer, MmGetMdlVirtualAddress(Buffer), PacketLength, MpProcessSGList, Packet, TRUE, pSGList, ScatterGatherListSize ); KeLowerIrql( OldIrql ); if ( !NT_SUCCESS ( nStatus )){ DBGLOG(( LDebug, "%08X=BuildMdlFromScatterGatherList failed\n",nStatus )); Packet->Private.Flags &= ~NDIS_FLAGS_RESERVED2; // sg list NDIS_PER_PACKET_INFO_FROM_PACKET(Packet, ScatterGatherListPacketInfo) = NULL; ExFreeToNPagedLookasideList( SGListLookasideList, pSGList ); } }else{ DBGLOG(( LDebug, "ExAllocateFromNPagedLookasideList failed\n" )); nStatus = NDIS_STATUS_RESOURCES; } } // if ( !fbDMAV2 ) then nStatus = NDIS_STATUS_FAILURE; if ( !NT_SUCCESS ( nStatus )) { // raise irql to dispatch KeRaiseIrql(DISPATCH_LEVEL,&OldIrql); // call DMA nStatus = SystemAdapterObject->DmaOperations->GetScatterGatherList( SystemAdapterObject, DeviceObject, Buffer, MmGetMdlVirtualAddress(Buffer), PacketLength, MpProcessSGList, Packet, TRUE ); KeLowerIrql( OldIrql ); if ( !NT_SUCCESS ( nStatus )){ DBGLOG(( LError, "%08X=GetScatterGatherList failed\n",nStatus )); } } if ( fbDMAV2 && !NT_SUCCESS ( nStatus ) ) { SendBuffer = ExAllocatePoolWithTag( NonPagedPool, PacketLength, MODULE_TAG ); if ( SendBuffer == NULL ){ DBGLOG(( LError, "ExAllocatePoolWithTag failed\n" )); nStatus = NDIS_STATUS_RESOURCES; break; } NdisAllocateBuffer( &nStatus, &SendNdisBuffer, NULL, SendBuffer, PacketLength ); if ( nStatus != NDIS_STATUS_SUCCESS ){ DBGLOG(( LError, "%08X=NdisAllocateBuffer failed\n",nStatus )); break; } //copy data to intermediate buffer fbResult = NDIS_CopyPacketData( Packet, SendBuffer, PacketLength,0, &nBytesRead ); if ( !fbResult || nBytesRead != PacketLength ){ DBGLOG(( LError, "NDIS_CopyPacketData failed\n" )); nStatus = NDIS_STATUS_RESOURCES; break; } Packet->Private.Flags |= NDIS_FLAGS_DOUBLE_BUFFERED; // sg list NDIS_PER_PACKET_INFO_FROM_PACKET(Packet, NdisReserved) = SendBuffer; // raise irql to dispatch KeRaiseIrql(DISPATCH_LEVEL,&OldIrql); // call DMA nStatus = SystemAdapterObject->DmaOperations->GetScatterGatherList( SystemAdapterObject, DeviceObject, SendNdisBuffer, MmGetMdlVirtualAddress(SendNdisBuffer), PacketLength, MpProcessSGList, Packet, TRUE ); KeLowerIrql( OldIrql ); } if ( !NT_SUCCESS ( nStatus ) ){ if ( SendNdisBuffer ){ NdisFreeBuffer( SendNdisBuffer ); } if ( SendBuffer ){ ExFreePoolWithTag( SendBuffer, MODULE_TAG ); } NDIS_PER_PACKET_INFO_FROM_PACKET(Packet, NdisReserved) = NULL; if (KIP_MINIPORT_TEST_FLAG(pAdapter, fADAPTER_IS_CO)) { ASSERT(FALSE); // TODO: //NdisMCoSendComplete(NDIS_STATUS_FAILURE, GET_VCPTR_FROM_PACKET(Packet), Packet); } else { //MpSendPacketCompleteHandler( pAdapter, Packet, NDIS_STATUS_FAILURE ); // we complete it in caller } } } while ( FALSE ); return nStatus; }
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], ðerType, 2 ); #if __LPX_OPTION_ADDRESSS__ if (FlagOn(Option, LPX_OPTION_DESTINATION_ADDRESS)) { RtlCopyMemory( RESERVED(packet)->OptionDestinationAddress, DestinationAddressNode, ETHERNET_ADDRESS_LENGTH ); } if (FlagOn(Option, LPX_OPTION_SOURCE_ADDRESS)) { if (FlagOn(Option, LPX_OPTION_DESTINATION_ADDRESS)) { RtlCopyMemory( RESERVED(packet)->OptionSourceAddress, Address->NetworkName->Node, ETHERNET_ADDRESS_LENGTH ); } else { RtlCopyMemory( RESERVED(packet)->OptionDestinationAddress, Address->NetworkName->Node, ETHERNET_ADDRESS_LENGTH ); } } #endif RESERVED(packet)->LpxHeader.PacketSize = HTONS( (USHORT)(packetHeaderLength - ETHERNET_HEADER_LENGTH + UserDataLength) ); RESERVED(packet)->LpxHeader.Option = Option; RESERVED(packet)->Cloned = 0; RESERVED(packet)->IrpSp = IrpSp; RESERVED(packet)->Type = LPX_PACKET_TYPE_SEND; RESERVED(packet)->Packet = packet; if (IrpSp == NULL) { DebugPrint( 3, ("[LPX] PacketAllocate: No IrpSp\n") ) ; } if (paddingDataBuffer) NdisChainBufferAtFront( packet, paddingDataBuffer ); if (userDataBuffer) NdisChainBufferAtFront( packet, userDataBuffer ); NdisChainBufferAtFront( packet, packetHeaderBuffer ); InterlockedIncrement( &NumberOfAllockPackets ); *Packet = packet; } else { if (paddingDataBuffer) NdisFreeBuffer( paddingDataBuffer ); if( paddingData) LpxFreeMemoryWithLpxTag( paddingData ); if (userDataBuffer) NdisFreeBuffer( userDataBuffer ); if (packetHeaderBuffer) NdisFreeBuffer( packetHeaderBuffer ); if (packet) NdisFreePacket( packet ); *Packet = NULL; DebugPrint( 1, ("[LPX]PacketAllocate: Can't Allocate Buffer For CopyData!!!\n") ); } return status; }
VOID PtSendComplete( IN NDIS_HANDLE ProtocolBindingContext, IN PNDIS_PACKET Packet, IN NDIS_STATUS Status ) /*++ Routine Description: Called by NDIS when the miniport below had completed a send. We should complete the corresponding upper-edge send this represents. Arguments: ProtocolBindingContext - Points to ADAPT structure Packet - Low level packet being completed Status - status of send Return Value: None --*/ { //------------------------------------------------------------------------- PNDIS_BUFFER packet_buffer; PUCHAR send_buffer = NULL; ULONG send_buffer_length; //------------------------------------------------------------------------- PADAPT pAdapt =(PADAPT)ProtocolBindingContext; PNDIS_PACKET Pkt; NDIS_HANDLE PoolHandle; #ifdef NDIS51 // // Packet stacking: // // Determine if the packet we are completing is the one we allocated. If so, then // get the original packet from the reserved area and completed it and free the // allocated packet. If this is the packet that was sent down to us, then just // complete it // PoolHandle = NdisGetPoolFromPacket(Packet); if (PoolHandle != pAdapt->SendPacketPoolHandle) { // // We had passed down a packet belonging to the protocol above us. // // DBGPRINT(("PtSendComp: Adapt %p, Stacked Packet %p\n", pAdapt, Packet)); NdisMSendComplete(pAdapt->MiniportHandle, Packet, Status); } else #endif // NDIS51 { PSEND_RSVD SendRsvd; SendRsvd = (PSEND_RSVD)(Packet->ProtocolReserved); Pkt = SendRsvd->OriginalPkt; //-------------------WestChamber----------------------------------- if (!Pkt) { //our packet //get buffer NdisUnchainBufferAtFront(Packet, &packet_buffer); if (packet_buffer) { NdisQueryBufferSafe(packet_buffer, (PVOID *)&send_buffer, &send_buffer_length, HighPagePriority); if (send_buffer && send_buffer_length) { //got buffer, free it. NdisFreeMemory(send_buffer, send_buffer_length, 0); } NdisFreeBuffer(packet_buffer); } //free packet NdisDprFreePacket(Packet); return; } //-------------------WestChamber---------------------------------- #ifndef WIN9X NdisIMCopySendCompletePerPacketInfo (Pkt, Packet); #endif NdisDprFreePacket(Packet); NdisMSendComplete(pAdapt->MiniportHandle, Pkt, Status); } }
VOID SecLabFreeReceivePacket( PADAPT pAdapt, IN PNDIS_PACKET pNdisPacket ) /*++ Routine Description: 释放所有与接收包相关的资源。如果这是一个本地拷贝,将此包释放到接收包池 。否则释放到miniport. Arguments: pNdisPacket - 指向要释放的包的指针 Return Value: None --*/ { PNDIS_BUFFER pNdisBuffer; UINT TotalLength; UINT BufferLength; PUCHAR pCopyData; if (NdisGetPoolFromPacket(pNdisPacket) ==pAdapt->RecvPacketPoolHandle) { // // This is a local copy. // #ifdef NDIS51 NdisGetFirstBufferFromPacketSafe( pNdisPacket, &pNdisBuffer, (PVOID *)&pCopyData, &BufferLength, &TotalLength, NormalPagePriority); #else NdisGetFirstBufferFromPacket( pNdisPacket, &pNdisBuffer, (PVOID *)&pCopyData, &BufferLength, &TotalLength); #endif if(BufferLength != TotalLength || pNdisBuffer==NULL || pCopyData==NULL) { DbgPrint("Error! Failed in Free a Packet"); DbgBreakPoint(); } NdisFreePacket(pNdisPacket); NdisFreeBuffer(pNdisBuffer); NdisFreeMemory(pCopyData,0,0); } else { NdisReturnPackets(&pNdisPacket, 1); } }