/************************************************************ 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; }
NDIS_STATUS ArcAllocatePackets( IN PARC_FILTER Filter ) /*++ Routine Description: This routine allocates Receive packets for the filter database. Arguments: Filter - The filter db to allocate for. Returns: NDIS_STATUS_SUCCESS if any packet was allocated. --*/ { ULONG i; PARC_PACKET Packet; for (i = ARC_PACKET_ALLOCATION_UNIT; i != 0 ; i--) { NdisAllocateMemory((PVOID)&Packet, sizeof(ARC_PACKET), 0, HighestAcceptableMax ); if (Packet == NULL) { if (i == ARC_BUFFER_ALLOCATION_UNIT) { return(NDIS_STATUS_FAILURE); } return(NDIS_STATUS_SUCCESS); } NdisZeroMemory(Packet, sizeof(ARC_PACKET)); NdisReinitializePacket(&(Packet->TmpNdisPacket)); Packet->Next = Filter->FreePackets; Filter->FreePackets = Packet; } return(NDIS_STATUS_SUCCESS); }
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)); }
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 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); }
/*----------------------------------------------------------------------------*/ 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 StSendDatagramCompletion( IN PTP_ADDRESS Address, IN PNDIS_PACKET NdisPacket, IN NDIS_STATUS NdisStatus ) /*++ Routine Description: This routine is called as an I/O completion handler at the time a StSendUIMdlFrame send request is completed. Because this handler is only associated with StSendUIMdlFrame, and because StSendUIMdlFrame is only used with datagrams and broadcast datagrams, we know that the I/O being completed is a datagram. Here we complete the in-progress datagram, and start-up the next one if there is one. Arguments: Address - Pointer to a transport address on which the datagram is queued. NdisPacket - pointer to the NDIS packet describing this request. Return Value: none. --*/ { PTP_REQUEST Request; PLIST_ENTRY p; KIRQL oldirql; PNDIS_BUFFER HeaderBuffer; UNREFERENCED_PARAMETER(NdisPacket); StReferenceAddress ("Complete datagram", Address); // // Dequeue the current request and return it to the client. Release // our hold on the send datagram queue. // // *** There may be no current request, if the one that was queued // was aborted or timed out. // ACQUIRE_SPIN_LOCK (&Address->SpinLock, &oldirql); p = RemoveHeadList (&Address->SendDatagramQueue); if (p != &Address->SendDatagramQueue) { RELEASE_SPIN_LOCK (&Address->SpinLock, oldirql); Request = CONTAINING_RECORD (p, TP_REQUEST, Linkage); // // Strip off and unmap the buffers describing data and header. // NdisUnchainBufferAtFront (Address->Packet->NdisPacket, &HeaderBuffer); // drop the rest of the packet NdisReinitializePacket (Address->Packet->NdisPacket); NDIS_BUFFER_LINKAGE(HeaderBuffer) = (PNDIS_BUFFER)NULL; NdisChainBufferAtFront (Address->Packet->NdisPacket, HeaderBuffer); // // Ignore NdisStatus; datagrams always "succeed". // StCompleteRequest (Request, STATUS_SUCCESS, Request->Buffer2Length); ACQUIRE_SPIN_LOCK (&Address->SpinLock, &oldirql); Address->Flags &= ~ADDRESS_FLAGS_SEND_IN_PROGRESS; RELEASE_SPIN_LOCK (&Address->SpinLock, oldirql); // // Send more datagrams on the Address if possible. // StSendDatagramsOnAddress (Address); // do more datagrams. } else { Address->Flags &= ~ADDRESS_FLAGS_SEND_IN_PROGRESS; RELEASE_SPIN_LOCK (&Address->SpinLock, oldirql); } StDereferenceAddress ("Complete datagram", Address); } /* StSendDatagramCompletion */
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; }
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; }
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; } }
/*----------------------------------------------------------------------------*/ 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 */
VOID NICIndicateReceivedPacket( IN PRCB pRCB, IN ULONG dataoffset, IN ULONG BytesToIndicate, IN ULONG PacketNum ) /*++ Routine Description: Initialize the packet to describe the received data and indicate to NDIS. Arguments: pRCB - pointer to the RCB block BytesToIndicate - number of bytes to indicate Return value: VOID --*/ { ULONG PacketLength; PNDIS_BUFFER CurrentBuffer = NULL; PETH_HEADER pEthHeader = NULL; PMP_ADAPTER Adapter = pRCB->Adapter; KIRQL oldIrql; PVOID VirtualAddress=NULL; ASSERT( PacketNum < RCB_BUFFERARRAY_SIZE); ASSERT((dataoffset+BytesToIndicate) < pRCB->ulBufferSize); //NdisAdjustBufferLength(pRCB->Buffer, BytesToIndicate); //MmInitializeMdl(pRCB->BufferArray[PacketNum],pRCB->pDataForNTB+dataoffset,BytesToIndicate); VirtualAddress=MmGetMdlVirtualAddress(pRCB->BufferArray[PacketNum]); ASSERT(VirtualAddress!=NULL); NdisMoveMemory(VirtualAddress,pRCB->pDataForNTB+dataoffset,BytesToIndicate); NdisAdjustBufferLength(pRCB->BufferArray[PacketNum], BytesToIndicate); //NdisMoveMemory(pRCB->pDataForNet+NIC_BUFFER_SIZE*PacketNum,pRCB->pDataForNTB+dataoffset,BytesToIndicate); // // Prepare the recv packet // NdisReinitializePacket(pRCB->PacketArray[PacketNum]); *((PRCB *)pRCB->PacketArray[PacketNum]->MiniportReserved) = pRCB; // // Chain the TCB buffers to the packet // NdisChainBufferAtBack(pRCB->PacketArray[PacketNum], pRCB->BufferArray[PacketNum]); NdisQueryPacket(pRCB->PacketArray[PacketNum], NULL, NULL, &CurrentBuffer, (PUINT) &PacketLength); ASSERT(CurrentBuffer == pRCB->BufferArray[PacketNum]); pEthHeader = (PETH_HEADER)(pRCB->pDataForNTB+dataoffset); if(PacketLength >= sizeof(ETH_HEADER) && Adapter->PacketFilter && NICIsPacketAcceptable(Adapter, pEthHeader->DstAddr)){ DEBUGP(MP_LOUD, ("Src Address = %02x-%02x-%02x-%02x-%02x-%02x", pEthHeader->SrcAddr[0], pEthHeader->SrcAddr[1], pEthHeader->SrcAddr[2], pEthHeader->SrcAddr[3], pEthHeader->SrcAddr[4], pEthHeader->SrcAddr[5])); DEBUGP(MP_LOUD, (" Dest Address = %02x-%02x-%02x-%02x-%02x-%02x\n", pEthHeader->DstAddr[0], pEthHeader->DstAddr[1], pEthHeader->DstAddr[2], pEthHeader->DstAddr[3], pEthHeader->DstAddr[4], pEthHeader->DstAddr[5])); DEBUGP(MP_LOUD, ("Indicating packet = %p, Packet Length = %d\n", pRCB->PacketArray[PacketNum], PacketLength)); NdisInterlockedIncrement(&pRCB->Ref); NDIS_SET_PACKET_STATUS(pRCB->PacketArray[PacketNum], NDIS_STATUS_SUCCESS); Adapter->nPacketsIndicated++; // // NDIS expects the indication to happen at DISPATCH_LEVEL if the // device is assinged any I/O resources in the IRP_MN_START_DEVICE_IRP. // Since this sample is flexible enough to be used as a standalone // virtual miniport talking to another device or part of a WDM stack for // devices consuming hw resources such as ISA, PCI, PCMCIA. I have to // do the following check. You should avoid raising the IRQL, if you // know for sure that your device wouldn't have any I/O resources. This // would be the case if your driver is talking to USB, 1394, etc. // if(Adapter->IsHardwareDevice){ KeRaiseIrql(DISPATCH_LEVEL, &oldIrql); NdisMIndicateReceivePacket(Adapter->AdapterHandle, &pRCB->PacketArray[PacketNum], 1); KeLowerIrql(oldIrql); }else{ NdisMIndicateReceivePacket(Adapter->AdapterHandle, &pRCB->PacketArray[PacketNum], 1); } }else { DEBUGP(MP_VERY_LOUD, ("Invalid packet or filter is not set packet = %p,Packet Length = %d\n", pRCB->PacketArray, PacketLength)); } }