static unsigned int WINAPI ether_thread_write_packets(void *arg) { LPPACKET Packet; thread_active_1 = true; D(bug("ether_thread_write_packets start\n")); while(thread_active) { // must be alertable, otherwise write completion is never called WaitForSingleObjectEx(int_send_now,INFINITE,TRUE); while( thread_active && (Packet = get_send_head()) != 0 ) { switch (net_if_type) { case NET_IF_ROUTER: if(router_write_packet((uint8 *)Packet->Buffer, Packet->Length)) { Packet->bIoComplete = TRUE; recycle_write_packet(Packet); } break; case NET_IF_FAKE: Packet->bIoComplete = TRUE; recycle_write_packet(Packet); break; case NET_IF_B2ETHER: if(!PacketSendPacket( fd, Packet, FALSE, TRUE )) { // already recycled if async } break; case NET_IF_TAP: if (!tap_send_packet(fd, Packet, FALSE, TRUE)) { // already recycled if async } break; case NET_IF_SLIRP: slirp_input((uint8 *)Packet->Buffer, Packet->Length); Packet->bIoComplete = TRUE; recycle_write_packet(Packet); break; } } } D(bug("ether_thread_write_packets exit\n")); thread_active_1 = false; return(0); }
BOOLEAN PacketSendPacket( LPADAPTER AdapterObject, LPPACKET lpPacket, BOOLEAN Sync, BOOLEAN RecyclingAllowed ) { BOOLEAN Result; #if DEBUG_PACKETS D(bug("Packet32: PacketSendPacket bytes=%d, sync=%d\n",lpPacket->Length,Sync)); #endif lpPacket->OverLapped.Offset = 0; lpPacket->OverLapped.OffsetHigh = 0; lpPacket->bIoComplete = FALSE; if(Sync) { Result = WriteFile( AdapterObject->hFile, lpPacket->Buffer, lpPacket->Length, &lpPacket->BytesReceived, &lpPacket->OverLapped ); if(Result) { Result = GetOverlappedResult( AdapterObject->hFile, &lpPacket->OverLapped, &lpPacket->BytesReceived, TRUE ); } else { D(bug("Packet32: PacketSendPacket WriteFile failed, err=%d\n",(int)GetLastError())); } lpPacket->bIoComplete = TRUE; if(RecyclingAllowed) PacketFreePacket(lpPacket); #if DEBUG_PACKETS D(bug("Packet32: PacketSendPacket result=%d, bytes=%d\n",(int)Result,(int)lpPacket->BytesReceived)); #endif } else { // don't care about the result Result = WriteFileEx( AdapterObject->hFile, lpPacket->Buffer, lpPacket->Length, &lpPacket->OverLapped, PacketSendCompletionRoutine ); #if DEBUG_PACKETS D(bug("Packet32: PacketSendPacket result=%d\n",(int)Result)); #endif if(!Result && RecyclingAllowed) { recycle_write_packet(lpPacket); } } return Result; }
static VOID CALLBACK tap_write_completion( DWORD dwErrorCode, DWORD dwNumberOfBytesTransfered, LPOVERLAPPED lpOverLapped ) { LPPACKET lpPacket = CONTAINING_RECORD(lpOverLapped, PACKET, OverLapped); lpPacket->bIoComplete = TRUE; recycle_write_packet(lpPacket); }
VOID CALLBACK PacketSendCompletionRoutine( DWORD dwErrorCode, DWORD dwNumberOfBytesTransfered, LPOVERLAPPED lpOverlapped ) { LPPACKET lpPacket = CONTAINING_RECORD(lpOverlapped,PACKET,OverLapped); #if DEBUG_PACKETS D(bug("PacketSendCompletionRoutine %d\n",dwNumberOfBytesTransfered)); #endif lpPacket->bIoComplete = TRUE; // lpPacket->free = TRUE; // PacketFreePacket(lpPacket); recycle_write_packet(lpPacket); }
static bool tap_send_packet( LPADAPTER fd, LPPACKET lpPacket, BOOLEAN Sync, BOOLEAN RecyclingAllowed) { BOOLEAN Result; lpPacket->OverLapped.Offset = 0; lpPacket->OverLapped.OffsetHigh = 0; lpPacket->bIoComplete = FALSE; if (Sync) { Result = WriteFile(fd->hFile, lpPacket->Buffer, lpPacket->Length, &lpPacket->BytesReceived, &lpPacket->OverLapped); if (Result) { GetOverlappedResult(fd->hFile, &lpPacket->OverLapped, &lpPacket->BytesReceived, TRUE); } lpPacket->bIoComplete = TRUE; if (RecyclingAllowed) PacketFreePacket(lpPacket); } else { Result = WriteFileEx(fd->hFile, lpPacket->Buffer, lpPacket->Length, &lpPacket->OverLapped, tap_write_completion); if (!Result && RecyclingAllowed) recycle_write_packet(lpPacket); } return Result; }