bool CEXIETHERNET::SendFrame(u8 *frame, u32 size) { DEBUG_LOG(SP1, "SendFrame %x\n%s", size, ArrayToString(frame, size, 0x10).c_str()); DWORD numBytesWrit; OVERLAPPED overlap; ZeroMemory(&overlap, sizeof(overlap)); if (!WriteFile(mHAdapter, frame, size, &numBytesWrit, &overlap)) { DWORD res = GetLastError(); ERROR_LOG(SP1, "Failed to send packet with error 0x%X", res); } if (numBytesWrit != size) { ERROR_LOG(SP1, "BBA SendFrame %i only got %i bytes sent!", size, numBytesWrit); } // Always report the packet as being sent successfully, even though it might be a lie SendComplete(); return true; }
bool CEXIETHERNET::SendFrame(const u8* frame, u32 size) { INFO_LOG(SP1, "SendFrame %x\n%s", size, ArrayToString(frame, size, 0x10).c_str()); int writtenBytes = write(fd, frame, size); if ((u32)writtenBytes != size) { ERROR_LOG(SP1, "SendFrame(): expected to write %d bytes, instead wrote %d", size, writtenBytes); return false; } else { SendComplete(); return true; } }
bool CEXIETHERNET::SendFrame(const u8* frame, u32 size) { #ifdef __linux__ DEBUG_LOG(SP1, "SendFrame %x\n%s", size, ArrayToString(frame, size, 0x10).c_str()); int writtenBytes = write(fd, frame, size); if ((u32)writtenBytes != size) { ERROR_LOG(SP1, "SendFrame(): expected to write %d bytes, instead wrote %d", size, writtenBytes); return false; } else { SendComplete(); return true; } #else NOTIMPLEMENTED("SendFrame"); return false; #endif }
bool CEXIETHERNET::SendFrame(u8 *frame, u32 size) { DEBUG_LOG(SP1, "SendFrame %x\n%s", size, ArrayToString(frame, size, 0x10).c_str()); OVERLAPPED overlap; ZeroMemory(&overlap, sizeof(overlap)); // WriteFile will always return false because the TAP handle is async WriteFile(mHAdapter, frame, size, nullptr, &overlap); DWORD res = GetLastError(); if (res != ERROR_IO_PENDING) { ERROR_LOG(SP1, "Failed to send packet with error 0x%X", res); } // Always report the packet as being sent successfully, even though it might be a lie SendComplete(); return true; }
bool CEXIETHERNET::SendFrame(const u8* frame, u32 size) { DEBUG_LOG(SP1, "SendFrame %u bytes:\n%s", size, ArrayToString(frame, size, 0x10).c_str()); // Check for a background write. We can't issue another one until this one has completed. DWORD transferred; if (mWritePending) { // Wait for previous write to complete. if (!GetOverlappedResult(mHAdapter, &mWriteOverlapped, &transferred, TRUE)) ERROR_LOG(SP1, "GetOverlappedResult failed (err=0x%X)", GetLastError()); } // Copy to write buffer. mWriteBuffer.assign(frame, frame + size); mWritePending = true; // Queue async write. if (WriteFile(mHAdapter, mWriteBuffer.data(), size, &transferred, &mWriteOverlapped)) { // Returning immediately is not likely to happen, but if so, reset the event state manually. ResetEvent(mWriteOverlapped.hEvent); } else { // IO should be pending. if (GetLastError() != ERROR_IO_PENDING) { ERROR_LOG(SP1, "WriteFile failed (err=0x%X)", GetLastError()); ResetEvent(mWriteOverlapped.hEvent); mWritePending = false; return false; } } // Always report the packet as being sent successfully, even though it might be a lie SendComplete(); return true; }
bool CParaNdisTX::SendMapped(bool IsInterrupt, PNET_BUFFER_LIST &NBLFailNow) { if(!ParaNdis_IsSendPossible(m_Context)) { NBLFailNow = RemoveAllNonWaitingNBLs(); if (NBLFailNow) { DPrintf(0, (__FUNCTION__ " Failing send")); } } else { bool SentOutSomeBuffers = false; auto HaveBuffers = true; while (HaveBuffers && HaveMappedNBLs()) { auto NBLHolder = PopMappedNBL(); if (NBLHolder->HaveMappedBuffers()) { auto NBHolder = NBLHolder->PopMappedNB(); auto result = m_VirtQueue.SubmitPacket(*NBHolder); switch (result) { case SUBMIT_NO_PLACE_IN_QUEUE: NBLHolder->PushMappedNB(NBHolder); PushMappedNBL(NBLHolder); HaveBuffers = false; // break the loop, allow to kick and free some buffers break; case SUBMIT_FAILURE: case SUBMIT_SUCCESS: case SUBMIT_PACKET_TOO_LARGE: // if this NBL finished? if (!NBLHolder->HaveMappedBuffers()) { m_WaitingList.Push(NBLHolder); } else { // no, insert it back to the queue PushMappedNBL(NBLHolder); } if (result == SUBMIT_SUCCESS) { SentOutSomeBuffers = true; } else { NBHolder->SendComplete(); CNB::Destroy(NBHolder, m_Context->MiniportHandle); } break; default: ASSERT(false); break; } } else { //TODO: Refactoring needed //This is a case when pause called, mapped list cleared but NBL is still in the send list m_WaitingList.Push(NBLHolder); } } if (SentOutSomeBuffers) { DPrintf(2, ("[%s] sent down\n", __FUNCTION__, SentOutSomeBuffers)); if (IsInterrupt) { return true; } else { m_VirtQueue.Kick(); } } } return false; }
// WorkerThread Method DWORD cIocpServer::WorkerThread( ) { DWORD bytesTransferred; ULONG_PTR completionKey; OVERLAPPED* overlapped; BOOL retValue; PerSocketContext* perSocketContext; PerIoContext* perIoContext; while ( true ) { retValue = GetQueuedCompletionStatus( mIocp, &bytesTransferred, &completionKey, &overlapped, INFINITE ); if ( overlapped == IOCP_SHUTDOWN ) return 0; perSocketContext = (PerSocketContext*)completionKey; perIoContext = (PerIoContext*)overlapped; if ( retValue == FALSE ) { #if defined(_DEBUG)/* && defined(SHOW_INFO)*/ int tmpErrorCode = WSAGetLastError(); printf("[%s:%d,errorcode:%d] has been error, the client will be closed.\n", __FUNCTION__, __LINE__, tmpErrorCode); #endif perIoContext->offset = max( perIoContext->offset, bytesTransferred ); Close( perSocketContext, perIoContext ); continue; } if ( bytesTransferred == 0 ) { #if defined(_DEBUG)/* && defined(SHOW_INFO)*/ printf("[%s] user has been closed socket, recv size is 0.\n", __FUNCTION__); #endif Close( perSocketContext, perIoContext ); continue; } switch ( perIoContext->requestType ) { case IOCP_REQUEST_READ: RecvComplete( perSocketContext, perIoContext, bytesTransferred ); break; case IOCP_REQUEST_WRITE: SendComplete( perSocketContext, perIoContext, bytesTransferred ); break; case IOCP_REQUEST_CALLBACK: assert(false); throw new std::exception("Please go back!!!"); break; default: { #if defined(_DEBUG)/* && defined(SHOW_INFO)*/ printf("[%s:%d] the receivced message error.\n", __FUNCTION__, __LINE__); #endif assert(false); Close(perSocketContext, perIoContext); break; } } } return 0; }