Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
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;
  }
}
Exemplo n.º 3
0
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
}
Exemplo n.º 4
0
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;
}
Exemplo n.º 5
0
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;
}
Exemplo n.º 7
0
// 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;
}