/************************************************************ 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; }
VOID NDIS_API PacketRequestComplete(IN NDIS_HANDLE ProtocolBindingContext, IN PNDIS_REQUEST NdisRequest, IN NDIS_STATUS Status) { // perform a packet request complete POPEN_INSTANCE Open = (POPEN_INSTANCE)ProtocolBindingContext; PINTERNAL_REQUEST pRequest = CONTAINING_RECORD(NdisRequest, INTERNAL_REQUEST, Request); PPACKET_RESERVED pReserved = &pRequest->Reserved; OVERLAPPED * pOverlap = (OVERLAPPED *)pReserved->lpoOverlapped; EPACKET_OID * oidData = (EPACKET_OID*)pReserved->lpBuffer; if (Status == NDIS_STATUS_SUCCESS) { // set total bytes returned *pReserved->lpcbBytesReturned = oidData->Length + sizeof(EPACKET_OID) - sizeof(oidData->Data); pOverlap->O_InternalHigh = *(pReserved->lpcbBytesReturned); } else { *pReserved->lpcbBytesReturned = 0; // set total bytes returned pOverlap->O_InternalHigh = *pReserved->lpcbBytesReturned; oidData->Length = Status; // return status in oidData if there is an error } // 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)); // Return request element to list NdisAcquireSpinLock(&Open->RequestSpinLock); InsertTailList(&Open->RequestList, &pReserved->ListElement); NdisReleaseSpinLock(&Open->RequestSpinLock); }
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); }